Search code examples
unixx11xlibmotif

How do I create two toplevel windows in Xt/Motif?


To create a sample toplevel window the following code can be done. This is shown in documentation and Motif books (specifically this example is based on "Motif Essentials, Programming and More by Marshall Brain).

#include <Xm/Xm.h>
#include <Xm/PushB.h>
#include <Xm/RowColumn.h>

XtAppContext    context;
XmStringCharSet char_set=XmSTRING_DEFAULT_CHARSET;

Widget          toplevel;
Widget          pulldownMenu, optionMenu;
Widget          optionMenuItem1;
Widget          optionMenuItem2;

Widget addMenuItem(char *itemName, XtPointer clientData, Widget menuWidget) {

        int ac;
        Arg al[10];
        Widget item;

        ac=0;
        XtSetArg(al[ac],XmNlabelString, XmStringCreateLtoR(itemName, char_set)); ac++;
        item=XmCreatePushButton(menuWidget,itemName,al,ac);
        XtManageChild(item);
        /*XtAddCallback(item,XmNactivateCallback,menuCB,clientData);*/
        XtSetSensitive(item,True);
        return(item);

}

int main(int argc, char *argv[]){

        Arg             al[10];
        int             ac;

        /* CREATE TOP LEVEL */
        toplevel = XtAppInitialize(&context, "test1", NULL, 0, &argc, argv, NULL, NULL, 0);

        /* RESIZE TOP LEVEL */
        ac=0;
        XtSetArg(al[ac], XmNheight, 300); ac++;
        XtSetArg(al[ac], XmNwidth, 300); ac++;
        XtSetValues(toplevel, al, ac);


        /* CREATE OPTIONS MENU */
        pulldownMenu=XmCreatePulldownMenu(toplevel, "pulldownMenu",NULL,0);
        optionMenuItem1 = addMenuItem("item1", "Item 1", pulldownMenu);
        optionMenuItem2 = addMenuItem("item2", "Item 2", pulldownMenu);
        ac=0;
        XtSetArg(al[ac], XmNsubMenuId, pulldownMenu); ac++;
        XtSetArg(al[ac], XmNlabelString, XmStringCreateLtoR("Sample",char_set)); ac++;
        optionMenu = XmCreateOptionMenu(toplevel, "optionMenu", al, ac);
        XtManageChild(optionMenu);


        /* DISPLAY TOP LEVEL */
        XtRealizeWidget(toplevel);
        XtAppMainLoop(context);
}

However, I can not find how to realize two windows, if my application wants to open 'n' independent windows at the toplvel, what shall be done?

Is it even possible in X11? (I think the question might be related to Xt library than to Motif).

If so, can someone point me to an example or a piece of documentation to understand how to do it?


Solution

  • Sure you can create two top-level windows. The sample below creates two windows, one with a "first" label and other with a "sec" label.

    #include <Xm/Label.h>
    
    int main(int argc, char **argv) {
      XtAppContext app;
      Widget       t1, t2, l1, l2;
    
      t1 = XtVaOpenApplication(&app, "w1", NULL, 0, &argc, argv, NULL,
                                     sessionShellWidgetClass, NULL);
      
      l1 = XtVaCreateManagedWidget("first", xmLabelWidgetClass, t1, NULL);
    
      /* Or applicationShellWidgetClass, topLevelShellWidgetClass, ... */
      t2 = XtVaCreatePopupShell("w2", sessionShellWidgetClass, t1, NULL);
    
      l2 = XtVaCreateManagedWidget("sec", xmLabelWidgetClass, t2, NULL);
    
      XtRealizeWidget(t1);
      XtPopup(t2, XtGrabNone);
      XtAppMainLoop(app);
      return(0);
    }
    

    I used varargs functions (XtVa) because I find filling Args and keeping track of counters with XtSetArg(al[ac], XmNheight, 300); ac++; very boring and potentially error-prone, but that doesn't really matter here.

    In general, you may benefit from inspecting real-life examples of (now mostly legacy) Athena or Motif programs, e.g. Xmgrace and Nedit, Xmessage and Xedit.