From: dwallach@loch.nas.nasa.gov (Dan Wallach)
Subject: XmNsubMenuId and other menu contortions in Motif
Organization: NAS, NASA Ames Research Center, Moffett Field, CA
Date: Thu, 23 Jul 92 01:55:19 GMT

Right now, I'm busy trying to emulate an old user interface library called
Panel in Motif.  Unfortunately, the way the two libraries do menus differ
in some annoying ways.

Basically, under Panel, first you create an "Icon", then you attach a
"Menu" to the Icon, then you attach buttons to the Menu.  You can mostly
do the same thing in Motif, in theory, with CascadeButtons, but I'm
getting caught up on a really weird snag.  Here's a demo program that
breaks things:

================================== snippity, snip =========================
#include <stdio.h>

#include <Xm/Xm.h>
#include <Xm/Label.h>
#include <Xm/PushB.h>
#include <Xm/PushBG.h>
#include <Xm/Form.h>
#include <Xm/MenuShell.h>
#include <Xm/CascadeB.h>
#include <Xm/CascadeBG.h>
#include <Xm/RowColumn.h>

#define NFISH 4
char *fish[] = {"one fish", "two fish", "red fish", "blue fish" };

Widget top, form, cascade, menu, fish_but[NFISH];

void buttonCB(Widget w, int id, XmAnyCallbackStruct *data) {
    int i;

    printf("Chose %s!\n", fish[id]);
}

void main(int argc, char **argv) {
    XtAppContext context;
    int i;


    XmString zeek;

    top = XtVaAppInitialize(&context, "Fishie", NULL, 0,
                                 &argc, argv, NULL, NULL);

    form = XtVaCreateManagedWidget("form", xmFormWidgetClass,
				   top,
				   XmNfractionBase, 10,
				   NULL);
    
    cascade = XtVaCreateManagedWidget("cascade", xmCascadeButtonWidgetClass,
				      form,
				      XmNleftPosition, 2,
				      XmNrightPosition, 8,
				      XmNtopPosition, 2,
				      XmNbottomPosition, 8,
				      XmNleftAttachment, XmATTACH_POSITION,
				      XmNrightAttachment, XmATTACH_POSITION,
				      XmNtopAttachment, XmATTACH_POSITION,
				      XmNbottomAttachment, XmATTACH_POSITION,
				      XmNlabelString,
					zeek = XmStringCreateSimple("Fishies"),
				      NULL);
    
    XmStringFree(zeek);

    menu = XmCreatePulldownMenu(cascade, "menu", NULL, 0);

    /*  
     *  my code blows up here
     */
    XtVaSetValues(cascade, XmNsubMenuId, menu, NULL);

    for(i=0;i<NFISH;i++) {
	fish_but[i] = XtVaCreateManagedWidget(fish[i], xmPushButtonGadgetClass,
					 menu,
					 XmNlabelString, zeek = XmStringCreateSimple(fish[i]),
					 NULL);
	
	XmStringFree(zeek);
	XtAddCallback(fish_but[i], XmNactivateCallback, buttonCB, i);
    }

    XtRealizeWidget(top);
    XtAppMainLoop(context);
}
============================= snippity, snip ============================

Now, then, it looks like something inside Motif is trying to dereference
a null pointer, because gdb is belching "Cannot access memory at address
0xfffffffc", a usual hint of that problem.

Now, the menu is really a RowColumn, under a MenuShell, so I tried changing
    XtVaSetValues(cascade, XmNsubMenuId, menu, NULL);
to
    XtVaSetValues(cascade, XmNsubMenuId, XtParent(menu), NULL);

And got instead:

Warning: 
    Name: cascade
    Class: XmCascadeButton
    Only XmMENU_PULLDOWN XmRowColumnWidgets can be submenus.

So, I'm guessing that Motif's happy with the types.  Any hints, or alternate
ideas on how to do an "Icon," which, when you click on it, pops something
else up on the screen?

Thanks much,

Dan

P.S.  If it matters, I'm on a Silicon Graphics, running Irix 4.0.1, with
      what I believe is Motif 1.1.1, although it might be higher. (How can
      I find out?)
--
Dan Wallach                XtVaGetValues(motifSystem, XmNarcaneDocumentation,
dwallach@nas.nasa.gov          &hoplesslyClutteredDesk, NULL);
Newsgroups: comp.windows.x.intrinsics