/* * @OPENGROUP_COPYRIGHT@ * COPYRIGHT NOTICE * Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc. * Copyright (c) 1996, 1997, 1998, 1999, 2000 The Open Group * ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for * the full copyright text. * * This software is subject to an open license. It may only be * used on, with or for operating systems which are themselves open * source systems. You must contact The Open Group for a license * allowing distribution and sublicensing of this software on, with, * or for operating systems which are not Open Source programs. * * See http://www.opengroup.org/openmotif/license for full * details of the license agreement. Any use, reproduction, or * distribution of the program constitutes recipient's acceptance of * this agreement. * * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS * PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY * WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY * OR FITNESS FOR A PARTICULAR PURPOSE * * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT * NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE * EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. */ /* * HISTORY */ #ifdef REV_INFO #ifndef lint static char rcsid[] = "$TOG: SharedTearM1.c /main/7 1999/05/19 11:21:49 jff $" #endif #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* for _XmAllowAcceleratedInsensitiveUnmanatedMenuItems() */ #include #define NPOP 16 Widget popup[NPOP]; Widget mw; Widget mb; Widget mb_cb1, mb_cb2, mb_cb3; Widget pd1, pd2, pd3, pd4, pd5; Widget pd1_lbl, pd1_sep, pd1_pb1, pd1_pb2, pd1_tb1, pd1_tb2, pd1_cb1, pd1_cb2; Widget pd2_pb1, pd2_pb2; Widget pd3_tb1, pd3_tb2; Widget pd4_pb1, pd4_pb2; Widget pd5_tb1, pd5_tb2; Widget wa; Widget wa_om; Widget action_wa; Widget action_reset, action_test; Widget wa_pb1, wa_pb2, wa_pb3, wa_pb4, wa_pb5, wa_pb6, wa_pb7, wa_pb8, wa_pb9, wa_pb10, wa_pb11, wa_pb12, wa_pb13, wa_pb14, wa_pb15, wa_pb16, wa_pb17, wa_pb18; Widget pop = NULL; Widget pop_lbl, pop_pb1, pop_pb2, pop_cb1, pop_cb2; typedef struct _ButtonDataRec { Widget context; Widget button; Widget menu_item; Boolean sensitive; } ButtonDataRec, *ButtonData; ButtonDataRec * ButtonDataList = NULL; short nButtonData; typedef struct _ToggleStateRec { Widget context; Widget menu_item; Boolean state; } ToggleStateRec, *ToggleState; ToggleStateRec * ToggleStateList = NULL; short nToggleState; #define TEST_MAP_CB 0 #define TEST_CASCADE_CB 1 static int num_popups = 3; static int handle_warnings = FALSE; static int ignore_warnings = FALSE; static int test_type = TEST_MAP_CB; static int quiet = FALSE; #define TEST_MAP_CB 0 #define TEST_CASCADE_CB 1 #define LAST_TEST_TYPE 1 /* * Some Utility routines */ /* number of toplevels */ #define NFLAG "-nt" /* use our my warning handler */ #define WFLAG "-mw" /* ignore (supress) warnings */ #define IFLAG "-ig" /* test type -tt<#> to specify cascading or rowcolumn-map callback, default 0 */ #define TFLAG "-tt" /* Don't print info */ #define QFLAG "-qt" void get_options(unsigned int argc, char **argv) { int i; for(i=0; i NPOP) num_popups = NPOP; } else if(!strncmp(TFLAG,argv[i], strlen(TFLAG))) { test_type = atoi(&(argv[i][strlen(TFLAG)])); if ((test_type < 0) || (test_type > LAST_TEST_TYPE)) test_type = 0; } else if(!strncmp(WFLAG,argv[i], strlen(WFLAG))) { handle_warnings = TRUE; } else if(!strncmp(IFLAG,argv[i], strlen(IFLAG))) { ignore_warnings = TRUE; handle_warnings = TRUE; } else if(!strncmp(QFLAG,argv[i], strlen(QFLAG))) { quiet = TRUE; } } } } void MyWarningHandler(char *message) { if (!ignore_warnings && !quiet) printf("MyWarningHandler: %s\n", message); } char *ButtonLabel(Widget button) { static char ret_str[128]; unsigned char label_type; XmString label_xmstr; XmStringContext strContext; char *text; XmStringCharSet c; XmStringDirection d; Boolean s; Arg args[2]; XtSetArg(args[0], XmNlabelType, &label_type); XtSetArg(args[1], XmNlabelString, &label_xmstr); XtGetValues(button, args, 2); ret_str[0] = '\0'; if (label_type == XmSTRING) { XmStringInitContext(&strContext, label_xmstr); while (XmStringGetNextSegment(strContext, &text, &c, &d, &s)) strcat(ret_str, text); } return(ret_str); } /* * This is by no means an example that should be used to track *real* * application menu_item sensitivity. For this test, it's a simplisitic * approach that's quick and dirty. */ void update_submenu_state(Widget context, XmRowColumnWidget rc) { Arg args[15]; int n; unsigned char rc_type; Widget menu_item; int i, j; if (XmIsRowColumn(rc)) { n = 0; XtSetArg(args[n], XmNrowColumnType, &rc_type); n++; XtGetValues((Widget)rc, args, n); if (context && (rc_type == XmMENU_PULLDOWN) || (rc_type == XmMENU_POPUP)) { for(i=0; icomposite.num_children; i++) { menu_item = rc->composite.children[i]; for(j=0; jcore.xrm_name)); for(i=0; iZ"); XtSetValues(pd1_pb1, args, 1); } void TestOpaqueCB(Widget w, caddr_t clientData, caddr_t callData) { Arg args[8]; int n; Widget xmscreen; Boolean opaque; xmscreen = (Widget) XmGetXmScreen(screen); n = 0; XtSetArg(args[n], XmNmoveOpaque, &opaque); n++; XtGetValues(xmscreen, args, n); opaque = !opaque; if (!quiet) if (opaque) printf("Setting MoveOpaque to True\n"); else printf("Setting MoveOpaque to False\n"); n = 0; XtSetArg(args[n], XmNmoveOpaque, opaque); n++; XtSetValues(xmscreen, args, n); } void CascadingCB (Widget w, caddr_t clientData, caddr_t callData) { Arg args[15]; int n; char *s; Widget postedFromWidget, toplevel; Widget subMenuId; s = ButtonLabel(w); postedFromWidget = XmGetPostedFromWidget(XtParent(w)); toplevel = FindTopMostShell(postedFromWidget); PrintInfo( XrmQuarkToString(w->core.xrm_name), s, "CASCADING", "", XrmQuarkToString(postedFromWidget->core.xrm_name), XrmQuarkToString(toplevel->core.xrm_name)); if (test_type == TEST_CASCADE_CB) { XtSetArg(args[0], XmNsubMenuId, &subMenuId); XtGetValues(w, args, 1); update_submenu_state(toplevel, (XmRowColumnWidget)subMenuId); } } void ArmCB(Widget w, caddr_t clientData, caddr_t callData) { char *s; Widget postedFromWidget, toplevel; char cr_value[32]; Boolean is_sensitive_managed; s = ButtonLabel(w); postedFromWidget = XmGetPostedFromWidget(XtParent(w)); toplevel = FindTopMostShell(postedFromWidget); #ifndef TEST_TORN_ACCEL_CONTEXT_SHARED if (!(is_sensitive_managed = SensitiveManagedVerified(toplevel, w))) strcpy(cr_value, "ignore arm"); else #endif strcpy(cr_value, "ARM"); PrintInfo( XrmQuarkToString(w->core.xrm_name), s, cr_value, "", XrmQuarkToString(postedFromWidget->core.xrm_name), XrmQuarkToString(toplevel->core.xrm_name)); } void DisarmCB (Widget w, caddr_t clientData, caddr_t callData) { char *s; Widget postedFromWidget, toplevel; char cr_value[32]; Boolean is_sensitive_managed; s = ButtonLabel(w); postedFromWidget = XmGetPostedFromWidget(XtParent(w)); toplevel = FindTopMostShell(postedFromWidget); #ifndef TEST_TORN_ACCEL_CONTEXT_SHARED if (!(is_sensitive_managed = SensitiveManagedVerified(toplevel, w))) strcpy(cr_value, "ignore disarm"); else #endif strcpy(cr_value, "DISARM"); PrintInfo( XrmQuarkToString(w->core.xrm_name), s, cr_value, "", XrmQuarkToString(postedFromWidget->core.xrm_name), XrmQuarkToString(toplevel->core.xrm_name)); } void ActivateCB (Widget w, caddr_t clientData, XmPushButtonCallbackStruct pb_cbs) { char *s; Widget postedFromWidget, toplevel; char cr_value[32]; Boolean is_sensitive_managed; s = ButtonLabel(w); postedFromWidget = XmGetPostedFromWidget(XtParent(w)); toplevel = FindTopMostShell(postedFromWidget); #ifndef TEST_TORN_ACCEL_CONTEXT_SHARED if (!(is_sensitive_managed = SensitiveManagedVerified(toplevel, w))) strcpy(cr_value, "ignore activate"); else #endif strcpy(cr_value, "ACTIVATE"); PrintInfo( XrmQuarkToString(w->core.xrm_name), s, cr_value, "", XrmQuarkToString(postedFromWidget->core.xrm_name), XrmQuarkToString(toplevel->core.xrm_name)); } void ValueChangedCB (Widget w, caddr_t clientData, XmToggleButtonCallbackStruct *tb_cbs) { char *s; Widget toplevel, postedFromWidget; int j; char svalue[8]; char cr_value[32]; Boolean is_sensitive_managed; s = ButtonLabel(w); postedFromWidget = XmGetPostedFromWidget(XtParent(w)); toplevel = FindTopMostShell(postedFromWidget); #ifndef TEST_TORN_ACCEL_CONTEXT_SHARED if (!(is_sensitive_managed = SensitiveManagedVerified(toplevel, w))) strcpy(cr_value, "ignore value_changed"); else #endif strcpy(cr_value, "VALUE_CHANGED"); sprintf(svalue, "%d", tb_cbs->set); PrintInfo( XrmQuarkToString(w->core.xrm_name), s, cr_value, svalue, XrmQuarkToString(postedFromWidget->core.xrm_name), XrmQuarkToString(toplevel->core.xrm_name)); if (is_sensitive_managed) { for(j=0; jevent->type == KeyPress) || (tb_cbs->event->type == KeyRelease)) { ToggleStateList[j].state = !ToggleStateList[j].state; if (!quiet) printf("ToggleB REAL internal tracked value: %d\n", ToggleStateList[j].state); } else ToggleStateList[j].state = XmToggleButtonGetState(w); break; } } } } void PopupCB (Widget w, caddr_t clientData, caddr_t callData) { Arg args[15]; int n; unsigned char rc_type; XmMenuShellWidget ms = (XmMenuShellWidget)w; XmRowColumnWidget rc; Widget toplevel, postedFromWidget; if (ms && ms->composite.num_children) rc = (XmRowColumnWidget) ms->composite.children[0]; else return; postedFromWidget = XmGetPostedFromWidget((Widget)rc); toplevel = FindTopMostShell(postedFromWidget); PrintInfo( XrmQuarkToString(w->core.xrm_name), "", "POPUP", "", XrmQuarkToString(postedFromWidget->core.xrm_name), XrmQuarkToString(toplevel->core.xrm_name)); if (test_type == TEST_CASCADE_CB) { n = 0; XtSetArg(args[n], XmNrowColumnType, &rc_type); n++; XtGetValues((Widget)rc, args, n); if (rc_type == XmMENU_POPUP) update_submenu_state(toplevel, rc); } } void MapCB(Widget w, caddr_t clientData, caddr_t callData) { XmRowColumnWidget rc = (XmRowColumnWidget)w; Widget toplevel, postedFromWidget; postedFromWidget = XmGetPostedFromWidget((Widget)rc); toplevel = FindTopMostShell(postedFromWidget); PrintInfo( XrmQuarkToString(w->core.xrm_name), "", "MAP", "", XrmQuarkToString(postedFromWidget->core.xrm_name), XrmQuarkToString(toplevel->core.xrm_name)); if (test_type == TEST_MAP_CB) update_submenu_state(toplevel, rc); } void UnmapCB(Widget w, caddr_t clientData, caddr_t callData) { Widget toplevel, postedFromWidget; postedFromWidget = XmGetPostedFromWidget(w); toplevel = FindTopMostShell(postedFromWidget); PrintInfo( XrmQuarkToString(w->core.xrm_name), "", "UNMAP", "", XrmQuarkToString(postedFromWidget->core.xrm_name), XrmQuarkToString(toplevel->core.xrm_name)); } void TearOffActivateCB (Widget w,caddr_t clientData, XmRowColumnCallbackStruct *callData) { Widget toplevel, postedFromWidget; char svalue[8]; postedFromWidget = XmGetPostedFromWidget(w); toplevel = FindTopMostShell(postedFromWidget); sprintf(svalue, "%d", (unsigned short)callData->data); PrintInfo( XrmQuarkToString(w->core.xrm_name), "", "TEAR_OFF_ACTIVATE", svalue, XrmQuarkToString(postedFromWidget->core.xrm_name), XrmQuarkToString(toplevel->core.xrm_name)); if (test_type == TEST_CASCADE_CB) update_submenu_state(toplevel, (XmRowColumnWidget)w); } void TearOffDeactivateCB (Widget w, caddr_t clientData, XmRowColumnCallbackStruct *callData) { Widget toplevel, postedFromWidget; char svalue[8]; postedFromWidget = XmGetPostedFromWidget(w); toplevel = FindTopMostShell(postedFromWidget); sprintf(svalue, "%d", (unsigned short)callData->data); PrintInfo( XrmQuarkToString(w->core.xrm_name), "", "TEAR_OFF_DEACTIVATE", svalue, XrmQuarkToString(postedFromWidget->core.xrm_name), XrmQuarkToString(toplevel->core.xrm_name)); } void ChangeSensitivity (Widget w, caddr_t clientData, caddr_t callData) { Widget toplevel, menu_item; int i; char *s; char svalue[8]; s = ButtonLabel(w); /* ChangeSensitivity() was called from a button in a workarea - NOT a menu. * so toplevel is simply the topmost shell in the parent heirarchy. */ toplevel = FindTopMostShell(w); for(i=0; icore.xrm_name), s, "Change Sensitivity", svalue, "", XrmQuarkToString(toplevel->core.xrm_name)); /* If the parent pane is torn, only change the sensitivity * immeditately if the toplevels match. Otherwise, the next * post/map will update sensitivity appropriately. */ if (!XmIsMenuShell(XtParent(XtParent(menu_item)))) { Widget tearoff_toplevel = FindTopMostShell(XmGetPostedFromWidget(XtParent(menu_item))); if (tearoff_toplevel == ButtonDataList[i].context) XtSetSensitive(menu_item, ButtonDataList[i].sensitive); } break; } } } /* * BEGIN the BEGIN */ /* * This is by no means an example that should be used to track *real* * application menu_item sensitivity. For this test, it's a simplisitic * approach that's quick and dirty. */ void RegisterButtonData(Widget wid, Widget data) { /* inefficient, but quick and dirty */ if (!ButtonDataList) { ButtonDataList = (ButtonDataRec *)XtMalloc((Cardinal)sizeof(ButtonDataRec)); nButtonData = 0; } else { ButtonDataList = (ButtonDataRec *)XtRealloc((char *)ButtonDataList, (Cardinal)((nButtonData + 1) * sizeof(ButtonDataRec))); } ButtonDataList[nButtonData].context = FindTopMostShell(wid); ButtonDataList[nButtonData].button = wid; ButtonDataList[nButtonData].menu_item = data; ButtonDataList[nButtonData].sensitive = XtIsSensitive(data); nButtonData++; } void RegisterToggleState(Widget wid, Widget tb) { if (!ToggleStateList) { ToggleStateList = (ToggleStateRec *)XtMalloc((Cardinal)sizeof(ToggleStateRec)); nToggleState = 0; } else { ToggleStateList = (ToggleStateRec *)XtRealloc((char *)ToggleStateList, (Cardinal)((nToggleState + 1) * sizeof(ToggleStateRec))); } ToggleStateList[nToggleState].context = FindTopMostShell(wid); ToggleStateList[nToggleState].menu_item = tb; ToggleStateList[nToggleState].state = XmToggleButtonGetState(tb); nToggleState++; } /* * Meat and Potatoes */ Widget CreateSelectionButton(Widget parent, char * name, caddr_t data) { Arg args[15]; int n; Widget wid; n = 0; wid = XmCreatePushButton(parent, name, args, n); XtManageChild(wid); XtAddCallback(wid, XmNactivateCallback, (XtCallbackProc) ChangeSensitivity, (XtPointer)data); RegisterButtonData(wid, (Widget)data); if(XmIsToggleButton((Widget)data) || XmIsToggleButtonGadget((Widget)data)) { RegisterToggleState(wid, (Widget)data); } return(wid); } void AddMenuCallbacks(Widget w) { XtAddCallback(w, XmNmapCallback, (XtCallbackProc) MapCB, (XtPointer)NULL); XtAddCallback(w, XmNunmapCallback, (XtCallbackProc) UnmapCB, (XtPointer)NULL); XtAddCallback(w, XmNtearOffMenuActivateCallback, (XtCallbackProc) TearOffActivateCB, (XtPointer) NULL); XtAddCallback(w, XmNtearOffMenuDeactivateCallback, (XtCallbackProc) TearOffDeactivateCB, (XtPointer) NULL); } void AddMenuPushButtonCallbacks(Widget w) { XtAddCallback(w, XmNarmCallback, (XtCallbackProc) ArmCB, (XtPointer) NULL); XtAddCallback(w, XmNactivateCallback, (XtCallbackProc) ActivateCB, (XtPointer) NULL); XtAddCallback(w, XmNdisarmCallback, (XtCallbackProc) DisarmCB, (XtPointer) NULL); } void AddMenuToggleButtonCallbacks(Widget w) { XtAddCallback(w, XmNarmCallback, (XtCallbackProc) ArmCB, (XtPointer) NULL); XtAddCallback(w, XmNvalueChangedCallback, (XtCallbackProc) ValueChangedCB, (XtPointer) NULL); XtAddCallback(w, XmNdisarmCallback, (XtCallbackProc) DisarmCB, (XtPointer) NULL); } void CreatePopup(Widget attach_widget) { Arg args[15]; int n; Widget child[16]; int nchild; if (pop) { XmAddToPostFromList(pop, attach_widget); XtAddEventHandler(attach_widget, ButtonPressMask, False, (XtEventHandler)PostIt, (XtPointer) pop); return; } /* The create time parent MUST be the attach_widget. This provides * the popup with the attach_widget to insert into its internal * postFromList. */ n = 0; pop = XmCreatePopupMenu(attach_widget, "pop", args, n); AddMenuCallbacks(pop); XtAddCallback(XtParent(pop), XmNpopupCallback, (XtCallbackProc) PopupCB, (XtPointer) NULL); XtAddEventHandler(attach_widget, ButtonPressMask, False, (XtEventHandler)PostIt, (XtPointer) pop); nchild = 0; n = 0; child[nchild++] = pop_lbl = XmCreateLabel(pop, "pop_lbl", args, n); n = 0; child[nchild++] = XmCreateSeparator(pop, "pop_sep", args, n); n = 0; child[nchild++] = pop_pb1 = XmCreatePushButton(pop, "pop_pb1", args, n); AddMenuPushButtonCallbacks(pop_pb1); n = 0; child[nchild++] = pop_pb2 = XmCreatePushButtonGadget(pop, "pop_pb2", args, n); AddMenuPushButtonCallbacks(pop_pb2); n = 0; XtSetArg(args[n], XmNsubMenuId, pd1); n++; child[nchild++] = pop_cb1 = XmCreateCascadeButton(pop, "pop_cb1", args, n); XtAddCallback(pop_cb1, XmNcascadingCallback, (XtCallbackProc) CascadingCB, (XtPointer) NULL); n = 0; XtSetArg(args[n], XmNsubMenuId, pd4); n++; child[nchild++] = pop_cb2 = XmCreateCascadeButtonGadget(pop, "pop_cb2", args, n); XtAddCallback(pop_cb2, XmNcascadingCallback,(XtCallbackProc) CascadingCB, (XtPointer) NULL); XtManageChildren(child, nchild); /* Share the popup with the other main window */ } void SetupMainWindow(Widget toplevel) { Arg args[15]; int n; Widget child[16]; int nchild; static Boolean one_time_only = TRUE; n = 0; mw = XmCreateMainWindow(toplevel, "mw", (ArgList) args, n); XtManageChild(mw); CreatePopup(mw); /** ** Create menubar and it's immediate cascade buttons **/ n = 0; mb = XmCreateMenuBar(mw, "mb", args, n); XtManageChild(mb); nchild = 0; n = 0; child[nchild++] = mb_cb1 = XmCreateCascadeButton(mb, "mb_cb1", args, n); XtAddCallback(mb_cb1, XmNcascadingCallback, (XtCallbackProc) CascadingCB, (XtPointer) NULL); n = 0; child[nchild++] = mb_cb2 = XmCreateCascadeButtonGadget(mb, "mb_cb2", args, n); XtAddCallback(mb_cb2, XmNcascadingCallback, (XtCallbackProc) CascadingCB, (XtPointer) NULL); n = 0; child[nchild++] = mb_cb3 = XmCreateCascadeButtonGadget(mb, "mb_cb3", args, n); XtAddCallback(mb_cb3, XmNcascadingCallback, (XtCallbackProc) CascadingCB, (XtPointer) NULL); XtManageChildren(child, nchild); /** ** Now set up the toplevel menu to cascading pulldown connections ** In the technical sense, these are shared because they have more ** than one attach-widget (cascade button). **/ n = 0; XtSetArg(args[n], XmNsubMenuId, pd1); n++; XtSetValues(mb_cb1, args, n); n = 0; XtSetArg(args[n], XmNsubMenuId, pd4); n++; XtSetValues(mb_cb2, args, n); n = 0; XtSetArg(args[n], XmNsubMenuId, pd5); n++; XtSetValues(mb_cb3, args, n); /** ** Create Workarea for selection pushbuttons **/ n = 0; wa = XmCreateRowColumn(mw, "wa", args, n); XtManageChild(wa); n = 0; XtSetArg(args[n], XmNsubMenuId, pd4); n++; wa_om = XmCreateOptionMenu(wa, "wa_om", args, n); XtManageChild(wa_om); child[0] = XmCreateSeparator(wa, "separator", args, 0); child[1] = XmCreateSeparator(wa, "separator", args, 0); XtManageChildren(child, 2); /***/ n = 0; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; action_wa = XmCreateRowColumn(wa, "action_wa", args, n); XtManageChild(action_wa); n = 0; action_reset = XmCreatePushButton(action_wa, "action_reset", args, n); XtManageChild(action_reset); XtAddCallback(action_reset, XmNactivateCallback, (XtCallbackProc)ResetMenuCB, (XtPointer)NULL); if (one_time_only) { n = 0; action_test = XmCreatePushButton(action_wa, "action_test_acc", args, n); XtManageChild(action_test); XtAddCallback(action_test, XmNactivateCallback, (XtCallbackProc)TestAccCB, (XtPointer) NULL); n = 0; action_test = XmCreatePushButton(action_wa, "action_test_opaque", args, n); XtManageChild(action_test); XtAddCallback(action_test, XmNactivateCallback, (XtCallbackProc) TestOpaqueCB, (XtPointer) NULL); one_time_only = FALSE; } /***/ child[0] = XmCreateSeparator(wa, "separator", args, 0); XtManageChild(child[0]); wa_pb1 = CreateSelectionButton(wa, "wa_pb1", (caddr_t) pd1_pb1); wa_pb2 = CreateSelectionButton(wa, "wa_pb2", (caddr_t) pd1_pb2); wa_pb3 = CreateSelectionButton(wa, "wa_pb3", (caddr_t) pd1_tb1); wa_pb4 = CreateSelectionButton(wa, "wa_pb4", (caddr_t) pd1_tb2); wa_pb5 = CreateSelectionButton(wa, "wa_pb5", (caddr_t) pd1_cb1); wa_pb6 = CreateSelectionButton(wa, "wa_pb6", (caddr_t) pd1_cb2); child[0] = XmCreateSeparator(wa, "separator", args, 0); XtManageChild(child[0]); wa_pb7 = CreateSelectionButton(wa, "wa_pb7", (caddr_t) pd2_pb1); wa_pb8 = CreateSelectionButton(wa, "wa_pb8", (caddr_t) pd2_pb2); child[0] = XmCreateSeparator(wa, "separator", args, 0); XtManageChild(child[0]); wa_pb9 = CreateSelectionButton(wa, "wa_pb9", (caddr_t) pd3_tb1); wa_pb10 = CreateSelectionButton(wa, "wa_pb10", (caddr_t) pd3_tb2); child[0] = XmCreateSeparator(wa, "separator", args, 0); XtManageChild(child[0]); wa_pb11 = CreateSelectionButton(wa, "wa_pb11", (caddr_t) pd4_pb1); wa_pb12 = CreateSelectionButton(wa, "wa_pb12", (caddr_t) pd4_pb2); child[0] = XmCreateSeparator(wa, "separator", args, 0); XtManageChild(child[0]); wa_pb17 = CreateSelectionButton(wa, "wa_pb17", (caddr_t) pd5_tb1); wa_pb18 = CreateSelectionButton(wa, "wa_pb18", (caddr_t) pd5_tb2); child[0] = XmCreateSeparator(wa, "separator", args, 0); XtManageChild(child[0]); wa_pb13 = CreateSelectionButton(wa, "wa_pb13", (caddr_t) pop_pb1); wa_pb14 = CreateSelectionButton(wa, "wa_pb14", (caddr_t) pop_pb2); wa_pb15 = CreateSelectionButton(wa, "wa_pb15", (caddr_t) pop_cb1); wa_pb16 = CreateSelectionButton(wa, "wa_pb16", (caddr_t) pop_cb2); /** ** Assign the main window areas **/ XmMainWindowSetAreas(mw, mb, NULL, NULL, NULL, wa); } void CreateCascadingMenuHierarchy(Widget toplevel) { Arg args[15]; int n; Widget child[16]; int nchild; /** ** Create a pulldown hierarchy for the menubars ** Note that this will only work for >= Motif1.2 because we are using ** a mixed shared menushell model. I.e. pd1 is not MenuShell shared ** and pd2, pd3, and pd4 are sharing. I think a bug prevents this ** model from working in 1.1. **/ /** pulldown 1 **/ /* use toplevel as the parent because mb is not yet created */ n = 0; pd1 = XmCreatePulldownMenu(toplevel, "pd1", args, n); AddMenuCallbacks(pd1); child[0] = XmGetTearOffControl(pd1); if (!quiet) { if (child[0]) { printf("pd1's tear off control 0x%p (%s)\n", child[0], child[0]->core.name); if(XtParent(child[0]) == pd1) printf("Tear off control's parent verified\n"); else printf("ERROR: Tear off control's parent is incorrect\n"); } else printf("ERROR: Tear off control is NULL\n"); } nchild = 0; n = 0; child[nchild++] = pd1_lbl = XmCreateLabel(pd1, "pd1_lbl", args, n); n = 0; child[nchild++] = pd1_sep = XmCreateSeparator(pd1, "pd1_sep", args, n); n = 0; child[nchild++] = pd1_pb1 = XmCreatePushButton(pd1, "pd1_pb1", args, n); AddMenuPushButtonCallbacks(pd1_pb1); n = 0; child[nchild++] = pd1_pb2 = XmCreatePushButtonGadget(pd1, "pd1_pb2", args, n); AddMenuPushButtonCallbacks(pd1_pb2); n = 0; child[nchild++] = pd1_tb1 = XmCreateToggleButton(pd1, "pd1_tb1", args, n); AddMenuToggleButtonCallbacks(pd1_tb1); n = 0; child[nchild++] = pd1_tb2 = XmCreateToggleButtonGadget(pd1, "pd1_tb2", args, n); AddMenuToggleButtonCallbacks(pd1_tb2); n = 0; child[nchild++] = pd1_cb1 = XmCreateCascadeButton(pd1, "pd1_cb1", args, n); XtAddCallback(pd1_cb1, XmNcascadingCallback, (XtCallbackProc) CascadingCB, (XtPointer) NULL); n = 0; child[nchild++] = pd1_cb2 = XmCreateCascadeButtonGadget(pd1, "pd1_cb2", args, n); XtAddCallback(pd1_cb2, XmNcascadingCallback, (XtCallbackProc) CascadingCB, (XtPointer) NULL); XtManageChildren(child, nchild); /** pulldown 2 **/ n = 0; pd2 = XmCreatePulldownMenu(pd1, "pd2", args, n); AddMenuCallbacks(pd2); nchild = 0; n = 0; child[nchild++] = pd2_pb1 = XmCreatePushButton(pd2, "pd2_pb1", args, n); AddMenuPushButtonCallbacks(pd2_pb1); n = 0; child[nchild++] = pd2_pb2 = XmCreatePushButtonGadget(pd2, "pd2_pb2", args, n); AddMenuPushButtonCallbacks(pd2_pb2); XtManageChildren(child, nchild); /** pulldown 3 **/ n = 0; pd3 = XmCreatePulldownMenu(pd1, "pd3", args, n); AddMenuCallbacks(pd3); nchild = 0; n = 0; child[nchild++] = pd3_tb1 = XmCreateToggleButton(pd3, "pd3_tb1", args, n); AddMenuToggleButtonCallbacks(pd3_tb1); n = 0; child[nchild++] = pd3_tb2 = XmCreateToggleButtonGadget(pd3, "pd3_tb2", args, n); AddMenuToggleButtonCallbacks(pd3_tb2); XtManageChildren(child, nchild); /** pulldown 4 **/ /* Use pd1 as the parent widget so that menushells are shared - Note * that typically this would be mb (except that mb is not yet created). */ n = 0; pd4 = XmCreatePulldownMenu(pd1, "pd4", args, n); AddMenuCallbacks(pd4); nchild = 0; n = 0; child[nchild++] = pd4_pb1 = XmCreatePushButton(pd4, "pd4_pb1", args, n); AddMenuPushButtonCallbacks(pd4_pb1); n = 0; child[nchild++] = pd4_pb2 = XmCreatePushButton(pd4, "pd4_pb2", args, n); AddMenuPushButtonCallbacks(pd4_pb2); XtManageChildren(child, nchild); /** pulldown 5 **/ n = 0; pd5 = XmCreatePulldownMenu(pd1, "pd5", args, n); AddMenuCallbacks(pd5); nchild = 0; n = 0; child[nchild++] = pd5_tb1 = XmCreatePushButton(pd5, "pd5_tb1", args, n); AddMenuPushButtonCallbacks(pd5_tb1); n = 0; child[nchild++] = pd5_tb2 = XmCreatePushButton(pd5, "pd5_tb2", args, n); AddMenuPushButtonCallbacks(pd5_tb2); XtManageChildren(child, nchild); /** ** Now set up the cascading pulldown to cascading pulldown connections ** In the technical sense, these are not shared because they only have ** one attach-widget (cascade button). However, in reality, they are ** and still require state tracking. **/ n = 0; XtSetArg(args[n], XmNsubMenuId, pd2); n++; XtSetValues(pd1_cb1, args, n); n = 0; XtSetArg(args[n], XmNsubMenuId, pd3); n++; XtSetValues(pd1_cb2, args, n); #ifndef TEST_TORN_ACCEL_CONTEXT_SHARED _XmAllowAcceleratedInsensitiveUnmanagedMenuItems(toplevel, TRUE); #endif } void main (argc, argv) unsigned int argc; char **argv; { Arg args[15]; int n; int i; char name[32]; XrmDatabase save_db, new_db; XmRepTypeInstallTearOffModelConverter(); CommonTestInit(argc, argv); XrmInitialize(); save_db = XtDatabase(display); sprintf(name, "%s.db", argv[0]); new_db = XrmGetFileDatabase(name); XrmCombineDatabase(new_db, &save_db, TRUE); get_options(argc, argv); if (!quiet) printf("Test type: %d\n", test_type); if (handle_warnings) XtSetWarningHandler((XtErrorHandler)MyWarningHandler); CreateCascadingMenuHierarchy(Shell1); SetupMainWindow(Shell1); XtRealizeWidget(Shell1); n = 0; for(i=0; i