/**********************************************************************/ /* $Date: 91/11/14 16:51:47 $ /* $Revision: 1.20.33.2 $ /**********************************************************************/ /****************************************************************************** NAME: uimxMF.c 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 -----------------------------------------------------------------------------*/ /******* Included so that the WidgetClass pointers can be used. *******/ #include #include #include #include #include #include #ifdef vms #include #else #include #endif #include static void InstallMwmCloseCallback(); #ifdef decstation static void UpdateShadowThickness (); #endif /* decstation */ /****************************************************************************** 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 (oM,name,class) INPUT: swidget oM - swidget char *name - widget name WidgetClass widget_class - class of widget RETURN: Widget DESCRIPTION: Create implicit shell CREATION: July 1990 (see bug710) REVISIONS: 28 July/90 -- added setting of width and height (see bug836) 18 Oct/91 fix3059 -- deal with shell title and iconName -----------------------------------------------------------------------------*/ static Widget CreateImplicitShell(oM,name,shell_class,parent) swidget oM; char *name; WidgetClass shell_class; Widget parent; { char shellname[256]; Arg pa[10]; Widget rtn; int i=0; strncpy(shellname,name,256); strncat(shellname,"_shell",256); if(UxObjectIsPropDefined(oM, XmNunitType)) { /* *** Don't set XmShellUnitType if a mainWindow is parented *** on a dialogShell. */ if (!(shell_class == xmDialogShellWidgetClass && UxGetClass(oM) == xmMainWindowWidgetClass)) { int unitType = (int)UxGetUnitType(oM); if (unitType != XmPIXELS) { XtSetArg(pa[i], XmNshellUnitType, unitType); i++; } } } if(x_used(oM)) { XtSetArg(pa[i], XtNx, (Position) UxGetX(oM)); i++; } if(y_used(oM)) { XtSetArg(pa[i], XtNy, (Position) UxGetY(oM)); i++; } if(height_used(oM)) { XtSetArg(pa[i], XtNheight, (Dimension) UxGetHeight(oM)); i++; } if(width_used(oM)) { XtSetArg(pa[i], XtNwidth, (Dimension) UxGetWidth(oM)); i++; } if(allowShellResize_used(oM)) { XtSetArg(pa[i], XtNallowShellResize, UxGetAllowShellResize(oM)); 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 (oM)); return rtn; } /******************************************************************************* NAME: static WidgetClass DetermineImplicitShellClass (oM) INPUT: swidget oM - swidget RETURN: WidgetClass DESCRIPTION: Determine implicit shell class CREATION: July 1990 (see bug710) REVISIONS: -- -----------------------------------------------------------------------------*/ static WidgetClass DetermineImplicitShellClass(oM) swidget oM; { WidgetClass shell_class; if(midget_is_dialog(oM)) return xmDialogShellWidgetClass; else if (shell_class = (WidgetClass)UxGetDefaultShell(oM)) 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,class,list,sz) char *name; Widget pwidget; WidgetClass 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, class)) { if(pwidget == NULL) pwidget= UxTopLevel; } else if((XtParent(pwidget) !=NULL)&& (XmIsMenuShell(XtParent(pwidget)))) pwidget = XtParent (pwidget); return XtCreatePopupShell(shellname,xmMenuShellWidgetClass,pwidget,pa,i); } /****************************************************************************** ==== GLOBAL ================================================================= ******************************************************************************* NAME: Widget UxrCreateWidget(oM) INPUT: swidget oM - swidget whose xwidget to create RETURN: Widget * - xwidget created from the swidget DESCRIPTION: Creates the xwidget using the values from the swidget (Midget). 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 REVISIONS: Jul 27/1989 -- Motif-specific functionality july 11/1990 -- major overhaul (see bug710) Aug 01/1990 - install callback for close button on shell. record implicit shell's widget. -----------------------------------------------------------------------------*/ Widget UxrCreateWidget(oM) swidget oM; { String name,cn; WidgetClass class, shell_class; swidget parent; Widget w = (Widget) 0, pwidget; ArgList list; int sz, real_shell = 0,is_menu = 0; int is_parent_dialog=0,needs_implicit_shell=0; void UxrDestroyCallback(); char *tr; if(w = UxGetWidget(oM)) return w; if(UxrIsValidSwidget(oM)) { /* get Widget data from the Midget */ sz = UxGetArgListSize(oM); list = (ArgList)UxGetArgList(oM); parent = UxGetParent(oM); pwidget = UxGetWidget(parent); class = UxGetClass(oM); name = UxGetName(oM); real_shell= UxrIsShellClass(class); if (real_shell) { w = XtCreatePopupShell(name,class, (pwidget ? pwidget : UxTopLevel), list,sz); InstallMwmCloseCallback(w); } else { needs_implicit_shell = midget_is_dialog(oM) || (!pwidget); if ( needs_implicit_shell ) { shell_class = DetermineImplicitShellClass(oM); pwidget = CreateImplicitShell(oM,name,shell_class, (pwidget ? pwidget : UxTopLevel)); InstallMwmCloseCallback(pwidget); RecordWidget(pwidget, oM); } /* menu rowColumn widgets need a menuShell */ is_menu = NeedsMenuShell (list, sz, class); if (is_menu) pwidget = CreateMenuShell(name,pwidget,class,list,sz); is_parent_dialog=XtIsSubclass(pwidget,xmDialogShellWidgetClass); if ( is_menu || is_parent_dialog || (strcmp(UxMidgetGetCreateManaged (oM), "false") == 0) ) { w = XtCreateWidget (name, class, pwidget, list, sz); } else { w = XtCreateManagedWidget (name, class, pwidget, list, sz); } } UxPutWidget(oM,w); RecordWidget(w,oM); #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 (oM, list, sz); #endif if (tr = UxGetTranslations(oM)) UxrAddTranslations(oM,tr); if(tr = UxMidgetAccelerators(oM)) UxrAddAccelerators(oM,tr); UxMidgetFreeArgList(oM); } return w; } /****************************************************************************** NAME: void PostPopupMenu (w, popup, event) INPUT: Widget w - widget where event occured popup - popup menu widget as closure XButtonEvent *event - pointer X Event structure DESCRIPTION: Post a popup menu by first positioning it, then managing it. CREATION: Aug 1/1989 -----------------------------------------------------------------------------*/ static void PostPopupMenu (w, popup, event) Widget w, popup; XButtonEvent *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(event->button != which_button) { return; } } else { if(event->button != Button3) { return; } } XmMenuPosition (popup, event); XtManageChild (popup); } /****************************************************************************** NAME: void UxrRegisterPopupMenuHandler (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 UxrRegisterPopupMenuHandler (wid, popup_wid) swidget wid, popup_wid; { XtAddEventHandler (UxGetWidget (wid), ButtonPressMask, False, PostPopupMenu, UxGetWidget (popup_wid)); } /*-------------------------------------------------------------------------- NAME: UxrPostMenu(widget,event, pars, npars) INPUT: Widget widget, XEvent *event, String *pars, Crdinal npars RETURN: DESCRIPTION: Post a popup menu CREATION: Sept . 15, 89 REVISIONS: -- --------------------------------------------------------------------------*/ static void nothing() { } static XtActionsRec action_list[]={{"nothing",nothing}, {"UxPostMenu",UxrPostMenu}}; static Widget post_widget; void UxrPostMenu(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 = UxrFindSwidget(pars[0]); if ((UxrIsValidSwidget(mmgr)) && (menu_manager = UxGetWidget(mmgr)) ) { XmMenuPosition (menu_manager, 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 UxrScrolledWindowSetAreas (sw, hsb, vsb, ww) swidget sw, hsb, vsb, ww; { Widget wsw, whsb, wvsb, www; if (UxrIsValidSwidget(sw)) wsw = UxGetWidget(sw); else /* Can't set areas on a null widget */ return; if (UxrIsValidSwidget(hsb)) whsb = UxGetWidget(hsb); else whsb = (Widget)NULL; if (UxrIsValidSwidget(vsb)) wvsb = UxGetWidget(vsb); else wvsb = (Widget)NULL; if (UxrIsValidSwidget(ww)) www = UxGetWidget(ww); else www = (Widget)NULL; XmScrolledWindowSetAreas(wsw, whsb, wvsb, www); } /*-------------------------------------------------------------------------- NAME: UxMainWindowSetMessageWindow(mwe, msgw) INPUT: swidget mwe,msgw; mwe - 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 UxrMainWindowSetMessageWindow(mwe, msgw) swidget mwe, msgw; { Widget wmwe, msgww; if (UxrIsValidSwidget(mwe)) wmwe = UxGetWidget(mwe); else wmwe = (Widget)NULL; if (UxrIsValidSwidget(msgw)) msgww = UxGetWidget(msgw); else msgww = (Widget)NULL; XtVaSetValues(wmwe, XmNmessageWindow, msgww, NULL); } /*-------------------------------------------------------------------------- NAME: UxMainWindowSetAreas(mwe, pdm, c, hsb, vsb, ww) INPUT: swidget mwe, pdm, c, hsp, vsb, ww RETURN: DESCRIPTION: Call the XtMainWindowSetAreas function. CREATION: Sept 26, 89 REVISIONS: --------------------------------------------------------------------------*/ void UxrMainWindowSetAreas(mwe, pdm, c, hsb, vsb, ww) swidget mwe, pdm, c, hsb, vsb, ww; { Widget wmwe, wpdm, wc, whsb, wvsb, www; if (UxrIsValidSwidget(mwe)) wmwe = UxGetWidget(mwe); else wmwe = (Widget)NULL; if (UxrIsValidSwidget(pdm)) wpdm = UxGetWidget(pdm); else wpdm = (Widget)NULL; if (UxrIsValidSwidget(c)) wc = UxGetWidget(c); else wc = (Widget)NULL; if (UxrIsValidSwidget(hsb)) whsb = UxGetWidget(hsb); else whsb = (Widget)NULL; if (UxrIsValidSwidget(vsb)) wvsb = UxGetWidget(vsb); else wvsb = (Widget)NULL; if (UxrIsValidSwidget(ww)) www = UxGetWidget(ww); else www = (Widget)NULL; XmMainWindowSetAreas(wmwe, wpdm, wc, whsb, wvsb, www); } /*-------------------------------------------------------------------------- NAME: void UxrAddAccelerators(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 UxrAddAccelerators(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 UxrAddTabGroup(oM) INPUT: swidget oM - 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 UxrAddTabGroup(oM) swidget oM; { Widget w; if (w = UxGetWidget(oM)) XmAddTabGroup(w); return; } /****************************************************************************** NAME: Widget UxrRemoveTabGroup(oM) INPUT: swidget oM - 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 UxrRemoveTabGroup(oM) swidget oM; { Widget w; if (w = UxGetWidget(oM)) XmRemoveTabGroup(w); return; } /****************************************************************************** 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 delete; static int init= 0; if(!init) { delete= XmInternAtom(UxDisplay, "WM_DELETE_WINDOW",FALSE); init= 1; } return(delete); } /****************************************************************************** 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; caddr_t client_data; XmAnyCallbackStruct *call_data; { Atom dwa; Widget shell; dwa= GetProtocolsAtom(); shell = (Widget) client_data; if(call_data->event->xclient.message_type == dwa) { unsigned char dr; swidget sw; if (!XmIsVendorShell(shell)) return; XtVaGetValues(shell, XmNdeleteResponse, &dr, NULL); 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, shell); } } /*----------------------------------------------------------------------------- NAME: char *UxrGetText (sw) INPUT: Widget sw | swidget to get resource from DESCRIPTION: Get the char string of the value resource associated with the specified widget. CREATION: Dec 14, 1990 -----------------------------------------------------------------------------*/ char *UxrGetText (sw) swidget sw; { Widget w; char *s = NULL; if ((w = UxGetWidget (sw)) != NULL) { Arg arg[1]; XtSetArg (arg[0], XmNvalue, &s); XtGetValues (w, arg, 1); #ifdef _IBMR2 s = strdup(s); #endif } return (s); } #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