/* @(#)uimxMF.c 17.1.1.1 (ESO-IPG) 01/25/02 17:26:44 */ /*--------------------------------------------------------------------- * $Date: 93/07/12 18:31:26 $ $Revision: 2.6.6.1 $ *--------------------------------------------------------------------- * * * Copyright (c) 1992, Visual Edge Software Ltd. * * ALL RIGHTS RESERVED. Permission to use, copy, modify, and * distribute this software and its documentation for any purpose * and without fee is hereby granted, provided that the above * copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Visual Edge Software not be * used in advertising or publicity pertaining to distribution of * the software without specific, written prior permission. The year * included in the notice is the year of the creation of the work. *-------------------------------------------------------------------*/ /*--------------------------------------------------------------------- DESCRIPTION: Motif-specific widget creation support functions. This file is included by during compilation. Special checks are performed during widget creation to determine if dialog or menu shells must be created instead of the normal shells. CREATION: 27 July 1989 *--------------------------------------------------------------------*/ /*--- include files ---*/ #include "version.h" /******* Included so that the WidgetClass pointers can be used. *******/ #include #include #include #include #include #include #include /*--- macro symbolic constants ---*/ /*--- macro functions ---*/ /*--- types ---*/ /*--- external functions ---*/ /*--- external variables ---*/ /*--- global variables ---*/ /*--- file global variables ---*/ M_FILE_VERSION("$Header") /*--- forward declaration of static functions ---*/ static void InstallMwmCloseCallback(); #ifdef decstation static void UpdateShadowThickness (); #endif /* decstation */ /*------------------------------------------------------------ * COMMENT_BOX *-----------------------------------------------------------*/ /****************************************************************************** NAME: int NeedsMenuShell (arg_list, size) INPUT: ArgList arg_list - widget argument list int size - size of argument list WidgetClass widget_class - class of widget RETURN: Boolean DESCRIPTION: Checks if the widget is a rowColumn and if its type is set to be a popup or pulldown menu; if these conditions are met, then the rowColumn widget is being used as a menu and needs a menuShell. CREATION: Jul 27/1989 REVISIONS: -- -----------------------------------------------------------------------------*/ static int NeedsMenuShell (arg_list, size, widget_class) ArgList arg_list; int size; WidgetClass widget_class; { int i; /* first compare the class of the widget */ if (widget_class != xmRowColumnWidgetClass) return 0; /* loop through the argument list and search for the rowColumnType property; if it is set to be a popup or pulldown menu, then a menuShell is needed */ for (i = 0; i < size; i++) { if (strcmp (arg_list[i].name, XmNrowColumnType) == 0 && (arg_list[i].value == XmMENU_POPUP || arg_list[i].value == XmMENU_PULLDOWN)) return 1; } /* no match was found */ return 0; } /****************************************************************************** NAME: int IsPopupMenu (arg_list, size, widget_class) INPUT: ArgList arg_list - widget argument list int size - size of argument list WidgetClass widget_class - class of widget RETURN: Boolean DESCRIPTION: Checks if the widget is a rowColumn and if its type is set to be a popup menu. CREATION: Aug 16/1989 REVISIONS: -- -----------------------------------------------------------------------------*/ static int IsPopupMenu (arg_list, size, widget_class) ArgList arg_list; int size; WidgetClass widget_class; { int i; /* first compare the class of the widget */ if (widget_class != xmRowColumnWidgetClass) return 0; /* loop through the argument list and search for the rowColumnType property; if it is set to be a popup menu, then return 'true' */ for (i = 0; i < size; i++) { if (strcmp (arg_list[i].name, XmNrowColumnType) == 0 && arg_list[i].value == XmMENU_POPUP) return 1; } /* no match was found */ return 0; } /*---------------------------------------------------------------------------- NAME: void UxDealWithShellTitleAndIconName (shl, name) INPUT: Widget shl the shell widget. char *name the name to set. RETURN: void DESCRIPTION: Set the title and iconName of an implicit shell. CREATION: Oct/16/91 fix3059 ------------------------------------------------------------------------------*/ void UxDealWithShellTitleAndIconName (shl, name) Widget shl; char *name; { Arg args[5]; int i = 0; /* * For all shells subclass of wmShellWidgetClass * (this excludes overrideShellWidgetClass) * set the title of implicit shell to be * the name of its child by default. For shells * subclass of topLevel shells, also set the * iconName. */ if (XtIsSubclass (shl, wmShellWidgetClass)) { XtSetArg (args[i], XtNtitle, name); i++; } if (XtIsSubclass (shl, topLevelShellWidgetClass)) { XtSetArg (args[i], XtNiconName, name); i++; } if (i > 0) XtSetValues (shl, args, i); } /******************************************************************************* NAME: static swidget CreateImplicitShell (sw, name, class) INPUT: swidget sw - swidget char *name - widget name WidgetClass widget_class - class of widget RETURN: Widget DESCRIPTION: Create implicit shell CREATION: July 1990 (see bug710) LAST REV: May 92 fix3571 -- rewrite for pointer swidget type. -----------------------------------------------------------------------------*/ static Widget CreateImplicitShell(sw, name, shell_class, parent) swidget sw; char *name; WidgetClass shell_class; Widget parent; { char shellname[256]; Arg pa[10]; Widget rtn; int i=0; XtArgVal value; strncpy(shellname, name, 256); strncat(shellname, "_shell", 256); /* * Don't set XmShellUnitType if a mainWindow is parented * on a dialogShell. */ if (!(shell_class == xmDialogShellWidgetClass && UxGetClass(sw) == xmMainWindowWidgetClass)) { if (UxFindValue (sw, XmNunitType, &value)){ if (value != XmPIXELS) { XtSetArg(pa[i], XmNshellUnitType, value); i++; } } } if(UxFindValue (sw, XtNx, &value)) { XtSetArg(pa[i], XtNx, value); i++; } if(UxFindValue (sw, XtNy, &value)) { XtSetArg(pa[i], XtNy, value); i++; } if(UxFindValue (sw, XtNheight, &value)) { XtSetArg(pa[i], XtNheight, value); i++; } if(UxFindValue (sw, XtNwidth, &value)) { XtSetArg(pa[i], XtNwidth, value); i++; } if (UxFindValue (sw, XtNallowShellResize, &value)) { XtSetArg(pa[i], XtNallowShellResize, value); i++ ; } rtn = XtCreatePopupShell(shellname, shell_class, parent, pa, i); /* * set the shell title and iconName after creation so * that these values can be set to the appropriate shell * classes. */ if (rtn) UxDealWithShellTitleAndIconName (rtn, UxGetName (sw)); return rtn; } /******************************************************************************* NAME: static WidgetClass DetermineImplicitShellClass (sw) INPUT: swidget sw - swidget RETURN: WidgetClass DESCRIPTION: Determine implicit shell class CREATION: July 1990 (see bug710) LAST REV: May 92 fix3571 -- rewrite for pointer swidget type. -----------------------------------------------------------------------------*/ static WidgetClass DetermineImplicitShellClass(sw) swidget sw; { WidgetClass shell_class; if (UxSwidgetGetFlag(sw, UXDIALOG_FLAG)) return xmDialogShellWidgetClass; else if (shell_class = (WidgetClass)UxGetDefaultShell(sw)) return shell_class; else return (WidgetClass)UxUserShell; } /******************************************************************************* NAME: static swidget CreateMenuShell (name, pwidget, class, list, sz) INPUT: char *name - widget name WidgetClass class - class of widget Widget pwidget - parent ArgList list - argument list int sz - size of argument list RETURN: Widget DESCRIPTION: create a menu shell CREATION: July 1990 (see bug710) REVISIONS: -- -----------------------------------------------------------------------------*/ static Widget CreateMenuShell(name, pwidget, w_class, list, sz) char *name; Widget pwidget; WidgetClass w_class; ArgList list; int sz; { Arg pa[5]; int i=0; char shellname[256]; strncpy(shellname, name, 256); strncat(shellname, "_shell", 256); XtSetArg (pa[i], XmNwidth, (Dimension) 1); i++; XtSetArg (pa[i], XmNheight, (Dimension) 1); i++; XtSetArg (pa[i], XmNallowShellResize, TRUE); i++; XtSetArg (pa[i], XmNoverrideRedirect, TRUE); i++; if (IsPopupMenu (list, sz, w_class)) { if (! pwidget) pwidget= UxTopLevel; } else if((XtParent(pwidget)) && (XmIsMenuShell(XtParent(pwidget)))) pwidget = XtParent (pwidget); return XtCreatePopupShell(shellname, xmMenuShellWidgetClass, pwidget, pa, i); } /****************************************************************************** NAME: Widget UxCreateWidget(sw) INPUT: swidget sw - swidget whose xwidget to create RETURN: Widget * - xwidget created from the swidget DESCRIPTION: Creates the xwidget using the values from the swidget. Dialogs are given dialog shells, and a check is made for the dialog convenience classes so that the 'dialogType' resource can be set properly. CREATION: Mar 14/1989 LAST REV: March 93 fix3963 UxIsSwidget now called. -----------------------------------------------------------------------------*/ Widget UxCreateWidget(sw) swidget sw; { String name; WidgetClass w_class, shell_class; swidget parent; ArgList list; int sz, real_shell = 0, is_menu = 0; int is_parent_dialog=0, needs_implicit_shell=0; char *tr; Widget pwidget; Widget w = UxGetWidget(sw); if (w) return w; if (UxIsSwidget(sw)) { parent = UxGetParent(sw); pwidget = UxGetWidget(parent); w_class = UxGetClass(sw); name = UxGetName(sw); real_shell = UxIsShellClass(w_class); sz = sw->NumValues; list = sw->Values; if (real_shell) { w = XtCreatePopupShell(name, w_class, (pwidget ? pwidget : UxTopLevel), list, sz); InstallMwmCloseCallback(w); } else { needs_implicit_shell = UxSwidgetGetFlag(sw, UXDIALOG_FLAG) || (!pwidget); if ( needs_implicit_shell ) { shell_class = DetermineImplicitShellClass(sw); pwidget = CreateImplicitShell(sw, name, shell_class, (pwidget ? pwidget : UxTopLevel)); InstallMwmCloseCallback(pwidget); RecordWidget(pwidget, sw); } /* menu rowColumn widgets need a menuShell */ is_menu = NeedsMenuShell (list, sz, w_class); if (is_menu) pwidget = CreateMenuShell(name, pwidget, w_class, list, sz); is_parent_dialog=XtIsSubclass(pwidget, xmDialogShellWidgetClass); if ( is_menu || is_parent_dialog || (strcmp(UxGetCreateManaged(sw), "false") == 0) ) { w = XtCreateWidget (name, w_class, pwidget, list, sz); } else { w = XtCreateManagedWidget (name, w_class, pwidget, list, sz); } } sw->ItsWidget = w; RecordWidget(w, sw); #ifdef decstation /* Fixes a Motif bug on the decstation where menu buttons are * fat since the default value of the shadowThickness resource is * way too large for unitType other than pixels. */ UpdateShadowThickness (sw, list, sz); #endif if (tr = UxGetTranslations(sw)) UxAddTranslations(sw, tr); if(tr = UxGetAccelerators(sw)) UxAddAccelerators(sw, tr); UxSwidgetFreeArgs(sw); } return w; } /****************************************************************************** NAME: void PostPopupMenu (w, client_data, event, cont) INPUT: Widget w - widget where event occured XtPointer client_data - popup menu widget as closure XEvent *event - pointer X Event structure Boolean *cont - not used DESCRIPTION: Post a popup menu by first positioning it, then managing it. CREATION: Aug 1/1989 -----------------------------------------------------------------------------*/ static void PostPopupMenu (w, client_data, event, cont) Widget w; XtPointer client_data; XEvent *event; Boolean *cont; { Widget popup = (Widget) client_data; XButtonPressedEvent *button_event = (XButtonPressedEvent *) event; extern WidgetClass xmRowColumnWidgetClass; if (popup && (XtClass(popup) == xmRowColumnWidgetClass)) { Arg a[1]; int which_button; XtSetArg(a[0], XmNwhichButton, &which_button); XtGetValues(popup, a, 1); if(button_event->button != which_button) { return; } } else { if(button_event->button != Button3) { return; } } XmMenuPosition (popup, button_event); XtManageChild (popup); } /****************************************************************************** NAME: void UxRegisterPopupMenuHandler (wid, popup_wid) INPUT: Widget wid - menu parent widget popup_wid - popup menu widget DESCRIPTION: Adds the popup menu event handler to position and popup the menu on the parent widget. CREATION: Aug 1/1989 REVISIONS: -- -----------------------------------------------------------------------------*/ void UxRegisterPopupMenuHandler (wid, popup_wid) swidget wid, popup_wid; { XtAddEventHandler (UxGetWidget(wid), ButtonPressMask, False, PostPopupMenu, (XtPointer)UxGetWidget(popup_wid)); } /*-------------------------------------------------------------------------- NAME: UxPostMenu(widget, event, pars, npars) INPUT: Widget widget, XEvent *event, String *pars, Cardinal *npars RETURN: DESCRIPTION: Post a popup menu CREATION: Sept . 15, 89 REVISIONS: March 93 fix3963 UxIsSwidget now called. --------------------------------------------------------------------------*/ static void nothing(widget, event, pars, npars) Widget widget; XEvent *event; String *pars; Cardinal *npars; { } static XtActionsRec action_list[]={{"nothing", nothing}, {"UxPostMenu", UxPostMenu}}; static Widget post_widget; void UxPostMenu(widget, event, pars, npars) Widget widget; XEvent *event; String *pars; Cardinal *npars; { swidget mmgr; /*menu manager*/ Widget menu_manager; /*X menu manager*/ post_widget = widget; mmgr = UxFindSwidget(pars[0]); if ((UxIsSwidget(mmgr)) && (menu_manager = UxGetWidget(mmgr)) ) { XmMenuPosition (menu_manager, (XButtonPressedEvent *) event); XtManageChild (menu_manager); } } /*-------------------------------------------------------------------------- NAME: UxScrolledWindowSetAreas(mwe, hsb, vsb, ww) INPUT: swidget mwe, hsb, vsb, ww; RETURN: DESCRIPTION: Call the XmScrolledWindowSetAreas function. CREATION: Sept 22, 90 REVISIONS: -- --------------------------------------------------------------------------*/ void UxScrolledWindowSetAreas (sw, hsb, vsb, ww) swidget sw, hsb, vsb, ww; { Widget wsw = UxGetWidget(sw); if (! wsw) return; XmScrolledWindowSetAreas(wsw, UxGetWidget(hsb), UxGetWidget(vsb), UxGetWidget(ww)); } /*-------------------------------------------------------------------------- NAME: UxMainWindowSetMessageWindow(mw, msgw) INPUT: swidget mw, msgw; mw - The Main Window Widget. msgw - The Message Window Widget. RETURN: DESCRIPTION: This function is added to complement UxMainWindowSetAreas Which does not contain a mechanism to add a Message Window to a Main Window. We did not change the UxMainWindowSetAreas to stay compatible with already released UIM/X. CREATION: 4 Fevrier 1991 (bug2045) REVISIONS: --------------------------------------------------------------------------*/ void UxMainWindowSetMessageWindow(mw, msgw) swidget mw, msgw; { Widget wmw = UxGetWidget(mw); if (! wmw) return; XtVaSetValues(wmw, XmNmessageWindow, UxGetWidget(msgw), 0); } /*-------------------------------------------------------------------------- NAME: UxMainWindowSetAreas(mw, pdm, c, hsb, vsb, ww) INPUT: swidget mw, pdm, cmd, hsp, vsb, ww RETURN: DESCRIPTION: Call the XtMainWindowSetAreas function. CREATION: Sept 26, 89 REVISIONS: --------------------------------------------------------------------------*/ void UxMainWindowSetAreas(mw, pdm, cmd, hsb, vsb, ww) swidget mw, pdm, cmd, hsb, vsb, ww; { Widget wmw = UxGetWidget(mw); if (! wmw) return; XmMainWindowSetAreas(wmw, UxGetWidget(pdm), UxGetWidget(cmd), UxGetWidget(hsb), UxGetWidget(vsb), UxGetWidget(ww)); } /*-------------------------------------------------------------------------- NAME: void UxAddAccelerators(s, t) INPUT: swidget s, t; RETURN: DESCRIPTION: given swidget s add accelerator property CREATION: 23, Nov. 1989 REVISIONS: September 06 1990 -- Call XtParseAcceleratorTable() instead of XtParseTranslationTable(). --------------------------------------------------------------------------*/ void UxAddAccelerators(s, t) swidget s; String t; { Widget w; XtAccelerators acc; Arg arg[2]; if((w = UxGetWidget(s)) && t){ acc = XtParseAcceleratorTable(t); XtSetArg(arg[0], XmNaccelerators, acc); XtSetValues(w, arg, 1); } } /****************************************************************************** NAME: Widget UxAddTabGroup(sw) INPUT: swidget sw - swidget whose xwidget gets XmAddTabGroup'ed RETURN: void DESCRIPTION: Performs a XmAddTabGroup on the widget associated with the swidget. CREATION: Jul 20/1990 (see bug804) REVISIONS: -----------------------------------------------------------------------------*/ void UxAddTabGroup(sw) swidget sw; { Widget w = UxGetWidget(sw); if (w) XmAddTabGroup(w); } /****************************************************************************** NAME: Widget UxRemoveTabGroup(sw) INPUT: swidget sw - swidget whose xwidget gets XmRemoveTabGroup'ed RETURN: void DESCRIPTION: Performs a XmRemoveTabGroup on the widget associated with the swidget. CREATION: Jul 20/1990 (see bug804) REVISIONS: -----------------------------------------------------------------------------*/ void UxRemoveTabGroup(sw) swidget sw; { Widget w = UxGetWidget(sw); if (w) XmRemoveTabGroup(w); } /****************************************************************************** NAME: Atom GetProtocolsAtom() RETURN: atom DESCRIPTION: Return the WM_PROTOCOLS atom to the caller. CREATION: Aug 01/1990 REVISIONS: -- -----------------------------------------------------------------------------*/ static Atom GetProtocolsAtom() { static Atom prot; static int init= 0; if(!init) { prot= XmInternAtom(UxDisplay, "WM_PROTOCOLS", FALSE); init= 1; } return(prot); } /****************************************************************************** NAME: Atom GetDeleteWindowAtom() RETURN: delete atom DESCRIPTION: Return the WM_DELETE_WINDOW atom to the caller. CREATION: Aug 01/1990 REVISIONS: -- -----------------------------------------------------------------------------*/ static Atom GetDeleteWindowAtom() { static Atom del_atom; static int init= 0; if(!init) { del_atom= XmInternAtom(UxDisplay, "WM_DELETE_WINDOW", FALSE); init= 1; } return(del_atom); } /****************************************************************************** NAME: void CloseButtonCallback(wid, unused, call_data) INPUT: Widget wid - widget caddr_t unused - unused info XmAnyCallbackStruct*call_data - callback data DESCRIPTION: Mwm close button callback function. CREATION: Aug 01/1990 REVISIONS: November 21 1990 [bug1159] -- Get the shell widget from the client data. Some window managers do not pass back the right wid. -----------------------------------------------------------------------------*/ static void CloseButtonCallback(wid, client_data, call_data) Widget wid; XtPointer client_data; XtPointer call_data; { Atom dwa; Widget shell; XmAnyCallbackStruct *cbstruct = (XmAnyCallbackStruct *) call_data; dwa= GetProtocolsAtom(); shell = (Widget) client_data; if(cbstruct->event->xclient.message_type == dwa) { unsigned char dr; swidget sw; if (!XmIsVendorShell(shell)) return; XtVaGetValues(shell, XmNdeleteResponse, &dr, 0); sw= UxWidgetToSwidget(shell); if (dr == XmDESTROY) { if(XtIsSubclass(shell, applicationShellWidgetClass)) exit(0); else UxDestroyInterface(sw); } else if (dr == XmUNMAP) UxPopdownInterface(sw); } } /****************************************************************************** NAME: void InstallMwmCloseCallback(shell) INPUT: Widget shell - shell to add callback to. DESCRIPTION: Add a callback for the close button on subclasses of vendor shell. CREATION: Aug 01/1990 REVISIONS: November 21 1990 [bug1159] -- Pass the shell widget as the client data. -----------------------------------------------------------------------------*/ static void InstallMwmCloseCallback(shell) Widget shell; { if(XmIsVendorShell(shell)) { Atom dwa; dwa= GetDeleteWindowAtom(); XmAddWMProtocols(shell, &dwa, 1); XmAddWMProtocolCallback(shell, dwa, CloseButtonCallback, (XtPointer) shell); } } /*---------------------------------------------------------------------- * NAME: * DESCRIPTION: A rotating buffer will contain the strings. For the first pass, the buffer is filled up to its size and for the subsequent strings to be stored, the location is first reallocated before the new string takes its place. Every time the buffer index reaches the size of the buffer, it is reset to 0 to create the rotating buffer. This way, we avoid system crashes because the pointer will always point to valid memory addresses but the memory content may not be the right one if the user waited too long (more than calls to this converter) before using the value returned. * PARAMETERS: Widget sw - swidget to get resource from * RETURN: char * - value resource * EXT REFS: globals_used * EXT EFFECTS: globals or other things altered * ASSUMPTIONS: * REVISIONS: 14/12/90 creation * dd/mm/yy fix# fix_description *--------------------------------------------------------------------*/ char *UxGetText (sw) swidget sw; { Widget w = UxGetWidget(sw); char *s = 0; static char **RotatingBuffer; static int BufferIndex = -1; if (w) { Arg arg[1]; XtSetArg (arg[0], XmNvalue, &s); XtGetValues (w, arg, 1); #ifdef _IBMR2 s = strdup(s); #endif UxUpdateRotatingBuffer(&BufferIndex, &RotatingBuffer, s, XtFree); return(RotatingBuffer[BufferIndex]); } else return (NULL); } #ifdef decstation /****************************************************************************** NAME: Boolean CheckForPresenceInArgumentList( arg, a, cnt ) INPUT: char *Argument; The argument we are looking for Arg *a; The argument list int cnt; How many arguments in the list DESCRIPTION: Finds out if the arguments (XmNshadowThickness for example) is in the list of values being passed for the creation of this Widget. CREATION: 8 Oct 1991 (fix2993) -----------------------------------------------------------------------------*/ static Boolean CheckForPresenceInArgumentList (Argument, a, cnt) char *Argument; Arg *a; int cnt; { int i=0; for (i=0;i