Blame lib/Xm/MenuUtil.c

Packit b099d7
/* 
Packit b099d7
 * Motif
Packit b099d7
 *
Packit b099d7
 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are free software; you can
Packit b099d7
 * redistribute them and/or modify them under the terms of the GNU
Packit b099d7
 * Lesser General Public License as published by the Free Software
Packit b099d7
 * Foundation; either version 2 of the License, or (at your option)
Packit b099d7
 * any later version.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are distributed in the hope that
Packit b099d7
 * they will be useful, but WITHOUT ANY WARRANTY; without even the
Packit b099d7
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
Packit b099d7
 * PURPOSE. See the GNU Lesser General Public License for more
Packit b099d7
 * details.
Packit b099d7
 *
Packit b099d7
 * You should have received a copy of the GNU Lesser General Public
Packit b099d7
 * License along with these librararies and programs; if not, write
Packit b099d7
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
Packit b099d7
 * Floor, Boston, MA 02110-1301 USA
Packit b099d7
*/ 
Packit b099d7
/* 
Packit b099d7
 * HISTORY
Packit b099d7
*/ 
Packit b099d7
#ifdef HAVE_CONFIG_H
Packit b099d7
#include <config.h>
Packit b099d7
#endif
Packit b099d7
Packit b099d7
Packit b099d7
#ifdef REV_INFO
Packit b099d7
#ifndef lint
Packit b099d7
static char rcsid[] = "$TOG: MenuUtil.c /main/16 1999/05/13 15:57:21 mgreess $"
Packit b099d7
#endif
Packit b099d7
#endif
Packit b099d7
/* (c) Copyright 1989, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
Packit b099d7
/* (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 HEWLETT-PACKARD COMPANY */
Packit b099d7
Packit b099d7
#include <stdio.h>
Packit b099d7
#include <ctype.h>
Packit b099d7
#include <X11/IntrinsicP.h>
Packit b099d7
#include <X11/ShellP.h>
Packit b099d7
#include <Xm/CascadeBGP.h>
Packit b099d7
#include <Xm/CascadeBP.h>
Packit b099d7
#include <Xm/MenuShellP.h>
Packit b099d7
#include <Xm/RowColumnP.h>
Packit b099d7
#include <Xm/ScreenP.h>
Packit b099d7
#include <Xm/XmosP.h>
Packit b099d7
#include "GadgetUtiI.h"
Packit b099d7
#include "MenuStateI.h"
Packit b099d7
#include "MenuUtilI.h"
Packit b099d7
#include "MessagesI.h"
Packit b099d7
#include "RCMenuI.h"
Packit b099d7
#include "TravActI.h"
Packit b099d7
#include "TraversalI.h"
Packit b099d7
#include "UniqueEvnI.h"
Packit b099d7
#include "XmI.h"
Packit b099d7
Packit b099d7
#define GRABPTRERROR    _XmMMsgCascadeB_0003
Packit b099d7
#define GRABKBDERROR    _XmMMsgRowColText_0024
Packit b099d7
Packit b099d7
#define EVENTS              ((unsigned int) (ButtonPressMask | \
Packit b099d7
                              ButtonReleaseMask | EnterWindowMask | \
Packit b099d7
                              LeaveWindowMask))
Packit b099d7
Packit b099d7
/********    Static Function Declarations    ********/
Packit b099d7
Packit b099d7
static void MenuTraverse( 
Packit b099d7
                        Widget w,
Packit b099d7
                        XEvent *event,
Packit b099d7
                        XmTraversalDirection direction) ;
Packit b099d7
static void GadgetCleanup( 
Packit b099d7
                        XmRowColumnWidget rc,
Packit b099d7
                        XmGadget oldActiveChild) ;
Packit b099d7
static Boolean WrapRight( 
Packit b099d7
                        XmRowColumnWidget rc) ;
Packit b099d7
static Boolean WrapLeft( 
Packit b099d7
                        XmRowColumnWidget rc) ;
Packit b099d7
static void LocateChild( 
Packit b099d7
                        XmRowColumnWidget rc,
Packit b099d7
                        Widget wid,
Packit b099d7
                        XmTraversalDirection direction) ;
Packit b099d7
static void MoveDownInMenuBar( 
Packit b099d7
                        XmRowColumnWidget rc,
Packit b099d7
                        Widget pw) ;
Packit b099d7
static void MoveLeftInMenuBar( 
Packit b099d7
                        XmRowColumnWidget rc,
Packit b099d7
                        Widget pw) ;
Packit b099d7
static void MoveRightInMenuBar( 
Packit b099d7
                        XmRowColumnWidget rc,
Packit b099d7
                        Widget pw) ;
Packit b099d7
static void FindNextMenuBarItem( 
Packit b099d7
                        XmRowColumnWidget menubar) ;
Packit b099d7
static void FindPrevMenuBarItem( 
Packit b099d7
                        XmRowColumnWidget menubar) ;
Packit b099d7
static Boolean ValidateMenuBarItem( 
Packit b099d7
                        Widget oldActiveChild,
Packit b099d7
                        Widget newActiveChild) ;
Packit b099d7
static Boolean FindNextMenuBarCascade( 
Packit b099d7
                        XmRowColumnWidget menubar) ;
Packit b099d7
static Boolean FindPrevMenuBarCascade( 
Packit b099d7
                        XmRowColumnWidget menubar) ;
Packit b099d7
static Boolean ValidateMenuBarCascade( 
Packit b099d7
                        Widget oldActiveChild,
Packit b099d7
                        Widget newMenuChild) ;
Packit b099d7
Packit b099d7
/********    End Static Function Declarations    ********/
Packit b099d7
Packit b099d7
Packit b099d7
Boolean
Packit b099d7
_XmIsActiveTearOff (
Packit b099d7
       Widget widget)
Packit b099d7
{
Packit b099d7
    XmRowColumnWidget menu = (XmRowColumnWidget) widget;
Packit b099d7
Packit b099d7
    if (RC_TearOffActive(menu))
Packit b099d7
        return (True);
Packit b099d7
    else
Packit b099d7
        return (False);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Call XtGrabPointer with retry
Packit b099d7
 */
Packit b099d7
int 
Packit b099d7
_XmGrabPointer(
Packit b099d7
	Widget widget,
Packit b099d7
	Bool owner_events, 
Packit b099d7
	unsigned int event_mask, 
Packit b099d7
	int pointer_mode, 
Packit b099d7
	int keyboard_mode, 
Packit b099d7
	Window confine_to, 
Packit b099d7
	Cursor cursor, 
Packit b099d7
	Time time )
Packit b099d7
{
Packit b099d7
   register int status = 0, retry;
Packit b099d7
Packit b099d7
   for (retry=0; retry < 5; retry++)
Packit b099d7
   {
Packit b099d7
      if ((status = XtGrabPointer(widget, owner_events, event_mask, 
Packit b099d7
         			  pointer_mode, keyboard_mode, confine_to, 
Packit b099d7
				  cursor, time)) == GrabSuccess)
Packit b099d7
	 break;
Packit b099d7
Packit b099d7
      XmeMicroSleep(1000);
Packit b099d7
   }
Packit b099d7
   if (status != GrabSuccess)
Packit b099d7
      XmeWarning((Widget) widget, GRABPTRERROR);
Packit b099d7
Packit b099d7
   return(status);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Call XtGrabKeyboard with retry
Packit b099d7
 */
Packit b099d7
int 
Packit b099d7
_XmGrabKeyboard(
Packit b099d7
	Widget widget,
Packit b099d7
	Bool owner_events, 
Packit b099d7
	int pointer_mode,
Packit b099d7
	int keyboard_mode, 
Packit b099d7
	Time time )
Packit b099d7
{
Packit b099d7
   register int status = 0, retry;
Packit b099d7
Packit b099d7
   for (retry=0; retry < 5; retry++)
Packit b099d7
   {
Packit b099d7
      if ((status = XtGrabKeyboard(widget, owner_events, 
Packit b099d7
         pointer_mode, keyboard_mode, time)) == GrabSuccess)
Packit b099d7
	 break;
Packit b099d7
      XmeMicroSleep(1000);
Packit b099d7
   }
Packit b099d7
   if (status != GrabSuccess)
Packit b099d7
      XmeWarning(widget, GRABKBDERROR);
Packit b099d7
Packit b099d7
   return(status);
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
void 
Packit b099d7
_XmMenuSetInPMMode (
Packit b099d7
	Widget wid,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
	int flag )
Packit b099d7
#else
Packit b099d7
	Boolean flag )
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
   _XmGetMenuState((Widget)wid)->MU_InPMMode = flag;
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * This menuprocs procedure allows an external object to turn on and off menu
Packit b099d7
 * traversal.
Packit b099d7
 */
Packit b099d7
void
Packit b099d7
_XmSetMenuTraversal(
Packit b099d7
        Widget wid,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int traversalOn )
Packit b099d7
#else
Packit b099d7
        Boolean traversalOn )
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
   if (traversalOn)
Packit b099d7
   {
Packit b099d7
      _XmSetInDragMode(wid, False);
Packit b099d7
      if (!XmProcessTraversal(wid , XmTRAVERSE_CURRENT))
Packit b099d7
         XtSetKeyboardFocus(XtParent(wid), wid);
Packit b099d7
   }
Packit b099d7
   else
Packit b099d7
   {
Packit b099d7
     _XmSetInDragMode(wid, True);
Packit b099d7
     if(    XmIsMenuShell( XtParent( wid))    )
Packit b099d7
       {
Packit b099d7
	 /* Must be careful not to trash the traversal environment
Packit b099d7
	  * for RowColumns which are not using menu-specific traversal.
Packit b099d7
	  */
Packit b099d7
	 _XmLeafPaneFocusOut(wid);
Packit b099d7
       }
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
void
Packit b099d7
_XmLeafPaneFocusOut( 
Packit b099d7
	Widget wid )
Packit b099d7
{
Packit b099d7
   XEvent fo_event;
Packit b099d7
   Widget widget;
Packit b099d7
   XmRowColumnWidget rc = (XmRowColumnWidget)wid;
Packit b099d7
Packit b099d7
   /* find the leaf pane */
Packit b099d7
   while (RC_PopupPosted(rc))
Packit b099d7
     rc = (XmRowColumnWidget) 
Packit b099d7
       ((XmMenuShellWidget)RC_PopupPosted(rc))->composite.children[0];
Packit b099d7
Packit b099d7
   fo_event.type = FocusOut;
Packit b099d7
   fo_event.xfocus.send_event = True;
Packit b099d7
   if ((widget = rc->manager.active_child) && XmIsCascadeButtonGadget(widget))
Packit b099d7
   {
Packit b099d7
      /* clear the internal focus path; also active_child = NULL which happens
Packit b099d7
       * to make cascadebutton focus out work correctly.
Packit b099d7
       */
Packit b099d7
      _XmClearFocusPath((Widget)rc);
Packit b099d7
      _XmDispatchGadgetInput(widget, NULL, XmFOCUS_OUT_EVENT);
Packit b099d7
      ((XmGadget)widget)->gadget.have_traversal = False;
Packit b099d7
   }
Packit b099d7
   else
Packit b099d7
   {
Packit b099d7
      if (widget && XmIsPrimitive(widget) &&
Packit b099d7
          (((XmPrimitiveWidgetClass)(widget->core.widget_class))->
Packit b099d7
            primitive_class.border_unhighlight != (XtWidgetProc)NULL))
Packit b099d7
         (*(((XmPrimitiveWidgetClass)(widget->core.widget_class))->
Packit b099d7
            primitive_class.border_unhighlight))((Widget) widget);
Packit b099d7
      else
Packit b099d7
	 _XmManagerFocusOut( (Widget) rc, &fo_event, NULL, NULL);
Packit b099d7
Packit b099d7
      /* clears the focus_item so that next TraverseToChild() will work */
Packit b099d7
      _XmClearFocusPath((Widget)rc);
Packit b099d7
   }
Packit b099d7
}
Packit b099d7

Packit b099d7
/*ARGSUSED*/
Packit b099d7
void
Packit b099d7
_XmMenuHelp(
Packit b099d7
        Widget wid,
Packit b099d7
        XEvent *event,
Packit b099d7
        String *params,		/* unused */
Packit b099d7
        Cardinal *num_params )	/* unused */
Packit b099d7
{
Packit b099d7
   XmRowColumnWidget rc = (XmRowColumnWidget) wid;
Packit b099d7
   XmGadget gadget;
Packit b099d7
Packit b099d7
   if (!_XmIsEventUnique(event) ||
Packit b099d7
       (!RC_IsArmed(rc) && !((RC_Type(rc) == XmMENU_OPTION) ||
Packit b099d7
			     (RC_Type(rc) == XmMENU_PULLDOWN)))) 
Packit b099d7
     return;
Packit b099d7
Packit b099d7
   if (!_XmGetInDragMode ((Widget)rc))
Packit b099d7
   {
Packit b099d7
     if ((gadget = (XmGadget) rc->manager.active_child) != NULL)
Packit b099d7
	_XmDispatchGadgetInput( (Widget) gadget, event, XmHELP_EVENT);
Packit b099d7
     else
Packit b099d7
     {
Packit b099d7
	_XmSocorro( (Widget) rc, event, NULL, NULL);
Packit b099d7
	_XmMenuPopDown((Widget)rc, event, NULL);
Packit b099d7
     }
Packit b099d7
   }
Packit b099d7
   else
Packit b099d7
   {
Packit b099d7
     if ((gadget = (XmGadget) 
Packit b099d7
	  XmObjectAtPoint((Widget) rc, event->xkey.x, event->xkey.y)) != NULL)
Packit b099d7
        _XmDispatchGadgetInput( (Widget) gadget, event, XmHELP_EVENT);
Packit b099d7
     else
Packit b099d7
     {
Packit b099d7
	_XmSocorro( (Widget) rc, event, NULL, NULL);
Packit b099d7
	_XmMenuPopDown((Widget)rc, event, NULL);
Packit b099d7
     }
Packit b099d7
   }
Packit b099d7
   _XmRecordEvent(event);
Packit b099d7
}
Packit b099d7

Packit b099d7
static void 
Packit b099d7
MenuTraverse(
Packit b099d7
        Widget w,
Packit b099d7
        XEvent *event,
Packit b099d7
        XmTraversalDirection direction )
Packit b099d7
{
Packit b099d7
   Widget parent;
Packit b099d7
Packit b099d7
   /*
Packit b099d7
    * The case may occur where the reporting widget is in fact the
Packit b099d7
    * RowColumn widget, and not a child.  This will occur if the
Packit b099d7
    * RowColumn has not traversable children.
Packit b099d7
    */
Packit b099d7
   if (XmIsRowColumn(w))
Packit b099d7
      parent = w;
Packit b099d7
   else if (XmIsRowColumn(XtParent(w)))
Packit b099d7
      parent = XtParent(w);
Packit b099d7
   else
Packit b099d7
      return;
Packit b099d7
Packit b099d7
   if ((RC_Type(parent) == XmMENU_POPUP) || 
Packit b099d7
       (RC_Type(parent) == XmMENU_PULLDOWN) ||
Packit b099d7
       (RC_Type(parent) == XmMENU_BAR))
Packit b099d7
   {
Packit b099d7
      _XmRecordEvent(event);
Packit b099d7
      (*(((XmRowColumnWidgetClass)XtClass(parent))->row_column_class.
Packit b099d7
          traversalHandler))( (Widget) parent, (Widget) w, direction);
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
void 
Packit b099d7
_XmMenuTraverseLeft(
Packit b099d7
        Widget wid,
Packit b099d7
        XEvent *event,
Packit b099d7
        String *param,
Packit b099d7
        Cardinal *num_param )
Packit b099d7
{
Packit b099d7
    if (_XmIsEventUnique(event))
Packit b099d7
   {
Packit b099d7
	 MenuTraverse(wid, event, XmTRAVERSE_LEFT);
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
void 
Packit b099d7
_XmMenuTraverseRight(
Packit b099d7
        Widget wid,
Packit b099d7
        XEvent *event,
Packit b099d7
        String *param,
Packit b099d7
        Cardinal *num_param )
Packit b099d7
{
Packit b099d7
   if (_XmIsEventUnique(event))
Packit b099d7
   {
Packit b099d7
	 MenuTraverse(wid, event, XmTRAVERSE_RIGHT);
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
void 
Packit b099d7
_XmMenuTraverseUp(
Packit b099d7
        Widget wid,
Packit b099d7
        XEvent *event,
Packit b099d7
        String *param,
Packit b099d7
        Cardinal *num_param )
Packit b099d7
{
Packit b099d7
   if (_XmIsEventUnique(event))
Packit b099d7
   {
Packit b099d7
	 MenuTraverse(wid, event, XmTRAVERSE_UP);
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
void 
Packit b099d7
_XmMenuTraverseDown(
Packit b099d7
        Widget wid,
Packit b099d7
        XEvent *event,
Packit b099d7
        String *param,
Packit b099d7
        Cardinal *num_param )
Packit b099d7
{
Packit b099d7
   if (_XmIsEventUnique(event))
Packit b099d7
   {
Packit b099d7
	 MenuTraverse(wid, event, XmTRAVERSE_DOWN);
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
void 
Packit b099d7
_XmMenuEscape(
Packit b099d7
        Widget w,
Packit b099d7
        XEvent *event,
Packit b099d7
        String *params,
Packit b099d7
        Cardinal *num_params )
Packit b099d7
{
Packit b099d7
   Widget parent = XtParent(w);
Packit b099d7
Packit b099d7
   /* Process the event only if not already processed */
Packit b099d7
   if (!_XmIsEventUnique(event))
Packit b099d7
      return;
Packit b099d7
Packit b099d7
   /*
Packit b099d7
    * Catch case where its a menubar w/ no submenus up - can't call
Packit b099d7
    *   menushell's popdown, call rowcolumn's instead.
Packit b099d7
    */
Packit b099d7
   if ((XmIsCascadeButton(w) || XmIsCascadeButtonGadget(w)) &&
Packit b099d7
	XmIsRowColumn(parent) && (RC_Type(parent) == XmMENU_BAR) &&
Packit b099d7
	!RC_PopupPosted(parent))
Packit b099d7
   {
Packit b099d7
      (*(((XmRowColumnClassRec *)XtClass(parent))->row_column_class.
Packit b099d7
	 menuProcedures)) (XmMENU_POPDOWN, parent, NULL, event, NULL);
Packit b099d7
   }
Packit b099d7
   else
Packit b099d7
       /* Let the menushell widget clean things up */
Packit b099d7
       (*(((XmMenuShellClassRec *)xmMenuShellWidgetClass)->
Packit b099d7
	  menu_shell_class.popdownOne))(w, event, NULL, NULL);
Packit b099d7
}
Packit b099d7
Packit b099d7
void 
Packit b099d7
_XmRC_GadgetTraverseDown(
Packit b099d7
        Widget wid,
Packit b099d7
        XEvent *event,
Packit b099d7
        String *param,
Packit b099d7
        Cardinal *num_param )
Packit b099d7
{
Packit b099d7
        XmRowColumnWidget rc = (XmRowColumnWidget) wid ;
Packit b099d7
   XmGadget gadget = (XmGadget)rc->manager.active_child;
Packit b099d7
Packit b099d7
   if (gadget && XmIsGadget(gadget))
Packit b099d7
      _XmMenuTraverseDown((Widget) gadget, event, param, num_param);
Packit b099d7
}
Packit b099d7
Packit b099d7
void 
Packit b099d7
_XmRC_GadgetTraverseUp(
Packit b099d7
        Widget wid,
Packit b099d7
        XEvent *event,
Packit b099d7
        String *param,
Packit b099d7
        Cardinal *num_param )
Packit b099d7
{
Packit b099d7
        XmRowColumnWidget rc = (XmRowColumnWidget) wid ;
Packit b099d7
   XmGadget gadget = (XmGadget)rc->manager.active_child;
Packit b099d7
Packit b099d7
   if (gadget && XmIsGadget(gadget))
Packit b099d7
      _XmMenuTraverseUp((Widget) gadget, event, param, num_param);
Packit b099d7
}
Packit b099d7
Packit b099d7
void 
Packit b099d7
_XmRC_GadgetTraverseLeft(
Packit b099d7
        Widget wid,
Packit b099d7
        XEvent *event,
Packit b099d7
        String *param,
Packit b099d7
        Cardinal *num_param )
Packit b099d7
{
Packit b099d7
        XmRowColumnWidget rc = (XmRowColumnWidget) wid ;
Packit b099d7
   XmGadget gadget = (XmGadget)rc->manager.active_child;
Packit b099d7
Packit b099d7
   /*
Packit b099d7
    * If there is not active child, then this RowColumn has
Packit b099d7
    * no traversable children, so it's fielding traversal
Packit b099d7
    * requests itself.
Packit b099d7
    */
Packit b099d7
   if (gadget)
Packit b099d7
      _XmMenuTraverseLeft((Widget) gadget, event, param, num_param);
Packit b099d7
   else 
Packit b099d7
      _XmMenuTraverseLeft((Widget) rc, event, param, num_param);
Packit b099d7
}
Packit b099d7
Packit b099d7
void 
Packit b099d7
_XmRC_GadgetTraverseRight(
Packit b099d7
        Widget wid,
Packit b099d7
        XEvent *event,
Packit b099d7
        String *param,
Packit b099d7
        Cardinal *num_param )
Packit b099d7
{
Packit b099d7
        XmRowColumnWidget rc = (XmRowColumnWidget) wid ;
Packit b099d7
   XmGadget gadget = (XmGadget)rc->manager.active_child;
Packit b099d7
Packit b099d7
   /*
Packit b099d7
    * If there is not active child, then this RowColumn has
Packit b099d7
    * no traversable children, so it's fielding traversal
Packit b099d7
    * requests itself.
Packit b099d7
    */
Packit b099d7
   if (gadget)
Packit b099d7
      _XmMenuTraverseRight((Widget) gadget, event, param, num_param);
Packit b099d7
   else 
Packit b099d7
      _XmMenuTraverseRight((Widget) rc, event, param, num_param);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * In case we've moved into our out of a gadget, we need to take care
Packit b099d7
 * of the highlighting ourselves, since the gadget will not get a focus
Packit b099d7
 * event.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
GadgetCleanup(
Packit b099d7
        XmRowColumnWidget rc,
Packit b099d7
        XmGadget oldActiveChild )
Packit b099d7
{
Packit b099d7
    XmGadget newActiveChild = (XmGadget)rc->manager.active_child;
Packit b099d7
Packit b099d7
    if (oldActiveChild != newActiveChild)
Packit b099d7
    {
Packit b099d7
        if (oldActiveChild && XmIsGadget(oldActiveChild))
Packit b099d7
        {
Packit b099d7
            _XmDispatchGadgetInput( (Widget) oldActiveChild, NULL,
Packit b099d7
                                                            XmFOCUS_OUT_EVENT);
Packit b099d7
            oldActiveChild->gadget.have_traversal = False;
Packit b099d7
        }
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * At the edge of the menu, decide what to do in this case
Packit b099d7
 */
Packit b099d7
static Boolean
Packit b099d7
WrapRight (
Packit b099d7
        XmRowColumnWidget rc )
Packit b099d7
{
Packit b099d7
   Widget topLevel;
Packit b099d7
   Widget oldActiveChild = rc->manager.active_child;
Packit b099d7
   Boolean done = False;
Packit b099d7
Packit b099d7
   _XmGetActiveTopLevelMenu ((Widget) rc, (Widget *) &topLevel);
Packit b099d7
Packit b099d7
   /* if in a menubar system, try to move to next menubar item cascade */
Packit b099d7
   if (XmIsMenuShell(XtParent(rc)) && (RC_Type(topLevel) == XmMENU_BAR) &&
Packit b099d7
       (FindNextMenuBarCascade((XmRowColumnWidget) topLevel)))
Packit b099d7
   {
Packit b099d7
      GadgetCleanup(rc, (XmGadget) oldActiveChild);
Packit b099d7
      done = True;
Packit b099d7
   }
Packit b099d7
Packit b099d7
   return (done);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * At the edge of the menu, decide what to do in this case
Packit b099d7
 */
Packit b099d7
static Boolean
Packit b099d7
WrapLeft (
Packit b099d7
        XmRowColumnWidget rc )
Packit b099d7
{
Packit b099d7
   Widget oldActiveChild = rc->manager.active_child;
Packit b099d7
   Boolean done = False;
Packit b099d7
Packit b099d7
   /* 
Packit b099d7
    * If we're the topmost pulldown menupane from a menubar, then unpost 
Packit b099d7
    * and move to the next available item in the menubar, and post its 
Packit b099d7
    * submenu.
Packit b099d7
    */
Packit b099d7
   if (XmIsMenuShell(XtParent(rc)) &&
Packit b099d7
       (RC_Type (rc) != XmMENU_POPUP) && RC_CascadeBtn(rc) && 
Packit b099d7
       (RC_Type (XtParent(RC_CascadeBtn(rc))) == XmMENU_BAR) &&
Packit b099d7
       (FindPrevMenuBarCascade((XmRowColumnWidget) 
Packit b099d7
                                      XtParent(RC_CascadeBtn(rc)))))
Packit b099d7
   {
Packit b099d7
      GadgetCleanup(rc, (XmGadget) oldActiveChild);
Packit b099d7
      done = True;
Packit b099d7
   }
Packit b099d7
Packit b099d7
   /*
Packit b099d7
    * if we are in a pulldown from another posted menupane, unpost this one
Packit b099d7
    */
Packit b099d7
   else if ((RC_Type(rc) == XmMENU_PULLDOWN) && RC_CascadeBtn(rc) &&
Packit b099d7
            (RC_Type(XtParent(RC_CascadeBtn(rc))) != XmMENU_OPTION) &&
Packit b099d7
            XmIsMenuShell(XtParent(rc)))
Packit b099d7
   {
Packit b099d7
      (*(((XmMenuShellClassRec *)xmMenuShellWidgetClass)->
Packit b099d7
                  menu_shell_class.popdownOne)) (XtParent(rc), NULL, NULL, 
Packit b099d7
                                                 NULL);
Packit b099d7
      done = True;
Packit b099d7
   }
Packit b099d7
Packit b099d7
   return (done);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Search for the next menu item according to the direction
Packit b099d7
 */
Packit b099d7
static void
Packit b099d7
LocateChild (
Packit b099d7
        XmRowColumnWidget rc,
Packit b099d7
        Widget wid,
Packit b099d7
        XmTraversalDirection direction )
Packit b099d7
{
Packit b099d7
   Boolean done = False;
Packit b099d7
   Widget nextWidget;
Packit b099d7
Packit b099d7
   /* special case a popped up submenu with no traversable items */
Packit b099d7
   if (XmIsRowColumn(wid) && 
Packit b099d7
       ((XmManagerWidget) wid)->manager.active_child == 0)
Packit b099d7
   {
Packit b099d7
     if (direction == XmTRAVERSE_LEFT)
Packit b099d7
       WrapLeft (rc);
Packit b099d7
     else if (direction == XmTRAVERSE_RIGHT)
Packit b099d7
       WrapRight (rc);
Packit b099d7
   }
Packit b099d7
   else
Packit b099d7
   {
Packit b099d7
     nextWidget = _XmNavigate(wid, direction);
Packit b099d7
Packit b099d7
     if (direction == XmTRAVERSE_LEFT)
Packit b099d7
     {
Packit b099d7
       /* watch for left wrap */
Packit b099d7
       if ((wid->core.x <= nextWidget->core.x) ||
Packit b099d7
	   (nextWidget->core.y + nextWidget->core.height <= wid->core.y) ||
Packit b099d7
	   (nextWidget->core.y >= wid->core.y + wid->core.height))
Packit b099d7
	 done = WrapLeft(rc);
Packit b099d7
     }
Packit b099d7
     else if (direction == XmTRAVERSE_RIGHT)
Packit b099d7
     {
Packit b099d7
       /* watch for right wrap */
Packit b099d7
       if ((wid->core.x >= nextWidget->core.x) ||
Packit b099d7
	   (wid->core.y + wid->core.height <= nextWidget->core.y) ||
Packit b099d7
	   (wid->core.y >= nextWidget->core.y + nextWidget->core.height))
Packit b099d7
	 done = WrapRight(rc);
Packit b099d7
     }
Packit b099d7
     
Packit b099d7
     if (!done)
Packit b099d7
       _XmMgrTraversal (nextWidget, XmTRAVERSE_CURRENT);
Packit b099d7
   }
Packit b099d7
Packit b099d7
}
Packit b099d7
Packit b099d7
 void 
Packit b099d7
_XmMenuTraversalHandler(
Packit b099d7
        Widget w,
Packit b099d7
        Widget pw,
Packit b099d7
        XmTraversalDirection direction )
Packit b099d7
{
Packit b099d7
   XmRowColumnWidget rc = (XmRowColumnWidget) w;
Packit b099d7
Packit b099d7
   if (_XmGetInDragMode((Widget) rc))
Packit b099d7
      return;
Packit b099d7
Packit b099d7
   if ( LayoutIsRtoLM(rc) ) {
Packit b099d7
     if (direction == XmTRAVERSE_RIGHT)
Packit b099d7
       direction = XmTRAVERSE_LEFT;
Packit b099d7
     else if (direction == XmTRAVERSE_LEFT)
Packit b099d7
       direction = XmTRAVERSE_RIGHT;
Packit b099d7
   }
Packit b099d7
   if (RC_Type(rc) != XmMENU_BAR)
Packit b099d7
   {
Packit b099d7
      /* check for cascading into a submenu */
Packit b099d7
      if (direction == XmTRAVERSE_RIGHT && 
Packit b099d7
          XmIsCascadeButtonGadget(pw) && CBG_Submenu(pw)) 
Packit b099d7
      {
Packit b099d7
         (*(((XmGadgetClassRec *)XtClass(pw))->gadget_class.
Packit b099d7
            arm_and_activate))( (Widget) pw, NULL, NULL, NULL);
Packit b099d7
      }
Packit b099d7
      else if (direction == XmTRAVERSE_RIGHT && 
Packit b099d7
               XmIsCascadeButton(pw) && CB_Submenu(pw))
Packit b099d7
      {
Packit b099d7
         (*(((XmPrimitiveClassRec *)XtClass(pw))->primitive_class.
Packit b099d7
             arm_and_activate)) ((Widget) pw, NULL, NULL, NULL);
Packit b099d7
      }
Packit b099d7
      
Packit b099d7
      else
Packit b099d7
         LocateChild (rc, pw, direction);
Packit b099d7
   }
Packit b099d7
Packit b099d7
   else
Packit b099d7
   {
Packit b099d7
       switch (direction)
Packit b099d7
       {
Packit b099d7
          case XmTRAVERSE_DOWN:
Packit b099d7
          {
Packit b099d7
             MoveDownInMenuBar (rc, pw);
Packit b099d7
             break;
Packit b099d7
          }
Packit b099d7
Packit b099d7
          case XmTRAVERSE_LEFT:
Packit b099d7
          {	
Packit b099d7
	    MoveLeftInMenuBar(rc, pw);
Packit b099d7
	    break;
Packit b099d7
          }
Packit b099d7
Packit b099d7
          case XmTRAVERSE_RIGHT:
Packit b099d7
          {
Packit b099d7
	    MoveRightInMenuBar(rc, pw);
Packit b099d7
	    break;
Packit b099d7
          }
Packit b099d7
	  
Packit b099d7
          case XmTRAVERSE_UP:
Packit b099d7
	  default:
Packit b099d7
	     break;
Packit b099d7
       }
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * When the PM menubar mode is active, down arrow will
Packit b099d7
 * cause us to post the menupane associated with the active cascade button
Packit b099d7
 * in the menubar.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
MoveDownInMenuBar(
Packit b099d7
        XmRowColumnWidget rc,
Packit b099d7
        Widget pw )
Packit b099d7
{
Packit b099d7
    if (rc->manager.active_child == NULL)
Packit b099d7
        return;
Packit b099d7
Packit b099d7
    if (XmIsPrimitive(pw))
Packit b099d7
    {
Packit b099d7
        XmPrimitiveClassRec * prim;
Packit b099d7
Packit b099d7
	CB_SetTraverse (pw, TRUE);
Packit b099d7
        prim = (XmPrimitiveClassRec *)XtClass(pw);
Packit b099d7
        (*(prim->primitive_class.arm_and_activate)) ((Widget) pw, NULL,
Packit b099d7
						     NULL, NULL);
Packit b099d7
	CB_SetTraverse (pw, FALSE);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    else if (XmIsGadget(pw))
Packit b099d7
    {
Packit b099d7
        XmGadgetClassRec * gad;
Packit b099d7
      
Packit b099d7
	CBG_SetTraverse (pw, TRUE);
Packit b099d7
        gad = (XmGadgetClassRec *)XtClass(pw);
Packit b099d7
        (*(gad->gadget_class.arm_and_activate)) ((Widget) pw, NULL,
Packit b099d7
						 NULL, NULL);
Packit b099d7
	CBG_SetTraverse (pw, FALSE);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void 
Packit b099d7
MoveLeftInMenuBar(
Packit b099d7
        XmRowColumnWidget rc,
Packit b099d7
        Widget pw )
Packit b099d7
{
Packit b099d7
   XmMenuState mst = _XmGetMenuState((Widget)rc);
Packit b099d7
Packit b099d7
   if ((mst->MU_CurrentMenuChild != NULL) &&
Packit b099d7
       (RC_PopupPosted(rc) != NULL) &&
Packit b099d7
       ((XmIsCascadeButtonGadget(pw) && !CBG_Submenu(pw)) ||
Packit b099d7
       (XmIsCascadeButton(pw) && !CB_Submenu(pw))))
Packit b099d7
   {
Packit b099d7
      /* Move to the previous item in the menubar */
Packit b099d7
      FindPrevMenuBarItem(rc);
Packit b099d7
   }
Packit b099d7
   else 
Packit b099d7
   {
Packit b099d7
      /* Move to the previous item in the menubar */
Packit b099d7
      mst->MU_CurrentMenuChild = NULL;
Packit b099d7
      FindPrevMenuBarItem(rc);
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
static void 
Packit b099d7
MoveRightInMenuBar(
Packit b099d7
        XmRowColumnWidget rc,
Packit b099d7
        Widget pw )
Packit b099d7
{
Packit b099d7
   XmMenuState mst = _XmGetMenuState((Widget)rc);
Packit b099d7
   
Packit b099d7
   if ((rc->manager.active_child == NULL) &&
Packit b099d7
        ((XmIsCascadeButtonGadget(pw) && !CBG_Submenu(pw)) ||
Packit b099d7
        (XmIsCascadeButton(pw) && !CB_Submenu(pw))))
Packit b099d7
   {
Packit b099d7
      FindNextMenuBarCascade(rc);
Packit b099d7
   }
Packit b099d7
   else
Packit b099d7
   {
Packit b099d7
      /* Move to the next item in the menubar */
Packit b099d7
      mst->MU_CurrentMenuChild = NULL;
Packit b099d7
      FindNextMenuBarItem(rc);
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Find the next cascade button in the menubar which can be traversed to.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
FindNextMenuBarItem(
Packit b099d7
        XmRowColumnWidget menubar )
Packit b099d7
{
Packit b099d7
   register int i, j;
Packit b099d7
   int upper_limit;
Packit b099d7
   Widget active_child;
Packit b099d7
Packit b099d7
   /*
Packit b099d7
    * We're not in the PM menubar mode if we don't have an active child.
Packit b099d7
    */
Packit b099d7
   if (menubar->manager.active_child == NULL)
Packit b099d7
       return;
Packit b099d7
Packit b099d7
   upper_limit = menubar->composite.num_children;
Packit b099d7
   active_child = menubar->manager.active_child;
Packit b099d7
Packit b099d7
   /* Find the index of the currently active item */
Packit b099d7
   for (i = 0; i < upper_limit; i++)
Packit b099d7
   {
Packit b099d7
      if (menubar->composite.children[i] == active_child)
Packit b099d7
	 break;
Packit b099d7
   }
Packit b099d7
Packit b099d7
   /* Start looking at the next child */
Packit b099d7
   for (j = 0, i++; j < upper_limit - 1; j++, i++)
Packit b099d7
   {
Packit b099d7
       /* Wrap, if necessary */
Packit b099d7
       if (i >= upper_limit)
Packit b099d7
	  i = 0;
Packit b099d7
Packit b099d7
	if (ValidateMenuBarItem(active_child, menubar->composite.children[i]))
Packit b099d7
	  return;
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Find the previous cascade button in the menubar which can be traversed to.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
FindPrevMenuBarItem(
Packit b099d7
        XmRowColumnWidget menubar )
Packit b099d7
{
Packit b099d7
   register int i, j;
Packit b099d7
   int upper_limit;
Packit b099d7
   Widget active_child;
Packit b099d7
Packit b099d7
   /* We're not in the PM menubar mode if we don't have an active child */
Packit b099d7
   if (menubar->manager.active_child == NULL)
Packit b099d7
       return;
Packit b099d7
Packit b099d7
   upper_limit = menubar->composite.num_children;
Packit b099d7
   active_child = menubar->manager.active_child;
Packit b099d7
Packit b099d7
   /* Find the index of the currently active item */
Packit b099d7
   for (i = 0; i < upper_limit; i++)
Packit b099d7
   {
Packit b099d7
       if (menubar->composite.children[i] == active_child)
Packit b099d7
	   break;
Packit b099d7
   }
Packit b099d7
Packit b099d7
   /* Start looking at the previous child */
Packit b099d7
   for (j = 0, --i; j < upper_limit - 1; j++, --i)
Packit b099d7
   {
Packit b099d7
       /* Wrap, if necessary */
Packit b099d7
       if (i < 0)
Packit b099d7
	  i = upper_limit - 1;
Packit b099d7
Packit b099d7
       if (ValidateMenuBarItem(active_child, menubar->composite.children[i]))
Packit b099d7
	  return;
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
static Boolean 
Packit b099d7
ValidateMenuBarItem (
Packit b099d7
	Widget oldActiveChild,
Packit b099d7
        Widget newActiveChild)
Packit b099d7
{
Packit b099d7
   XmMenuState mst = _XmGetMenuState((Widget)oldActiveChild);
Packit b099d7
Packit b099d7
   if (XmIsTraversable(newActiveChild))
Packit b099d7
   {
Packit b099d7
      (void) XmProcessTraversal (newActiveChild, XmTRAVERSE_CURRENT);
Packit b099d7
Packit b099d7
      if (XmIsPrimitive(newActiveChild))
Packit b099d7
      {
Packit b099d7
         XmPrimitiveClassRec * prim;
Packit b099d7
Packit b099d7
         prim = (XmPrimitiveClassRec *)XtClass(newActiveChild);
Packit b099d7
Packit b099d7
         if (!mst->MU_InPMMode && CB_Submenu(newActiveChild))
Packit b099d7
            (*(prim->primitive_class.arm_and_activate)) (newActiveChild, NULL,
Packit b099d7
                                                                   NULL, NULL);
Packit b099d7
     }
Packit b099d7
      else if (XmIsGadget(newActiveChild))
Packit b099d7
      {
Packit b099d7
         XmGadgetClassRec * gadget;
Packit b099d7
Packit b099d7
         gadget = (XmGadgetClassRec *)XtClass(newActiveChild);
Packit b099d7
Packit b099d7
         if (!mst->MU_InPMMode && CBG_Submenu(newActiveChild))
Packit b099d7
            (*(gadget->gadget_class.arm_and_activate)) (newActiveChild, NULL,
Packit b099d7
                                                                   NULL, NULL);
Packit b099d7
      }
Packit b099d7
      return True;
Packit b099d7
   }
Packit b099d7
   else
Packit b099d7
      return False;
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Find the next hierarchy in the menubar which can be traversed to.
Packit b099d7
 */
Packit b099d7
static Boolean 
Packit b099d7
FindNextMenuBarCascade(
Packit b099d7
        XmRowColumnWidget menubar )
Packit b099d7
{
Packit b099d7
   Widget active_child = NULL;
Packit b099d7
   register int i, j;
Packit b099d7
   int upper_limit;
Packit b099d7
   ShellWidget shell;
Packit b099d7
   XmMenuState mst = _XmGetMenuState((Widget)menubar);
Packit b099d7
Packit b099d7
   upper_limit = menubar->composite.num_children;
Packit b099d7
Packit b099d7
   /*
Packit b099d7
    * Determine which child is popped up.
Packit b099d7
    */
Packit b099d7
   shell = (ShellWidget) RC_PopupPosted(menubar);
Packit b099d7
   if (shell != NULL)
Packit b099d7
      active_child = mst->MU_CurrentMenuChild =
Packit b099d7
         RC_CascadeBtn(shell->composite.children[0]);
Packit b099d7
Packit b099d7
   /* Find the index of the currently active item */
Packit b099d7
   for (i = 0; i < upper_limit; i++)
Packit b099d7
   {
Packit b099d7
      if (menubar->composite.children[i] == mst->MU_CurrentMenuChild)
Packit b099d7
          break;
Packit b099d7
   }
Packit b099d7
Packit b099d7
   /* Start looking at the next child */
Packit b099d7
   for (j = 0, i++; j < upper_limit - 1; j++, i++)
Packit b099d7
   {
Packit b099d7
      /* Wrap, if necessary */
Packit b099d7
      if (i >= upper_limit)
Packit b099d7
          i = 0;
Packit b099d7
Packit b099d7
      mst->MU_CurrentMenuChild = menubar->composite.children[i];
Packit b099d7
      if (ValidateMenuBarCascade(active_child, mst->MU_CurrentMenuChild))
Packit b099d7
         return True;
Packit b099d7
   }
Packit b099d7
   return False;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Find the previous hierarchy in the menubar which can be traversed to.
Packit b099d7
 */
Packit b099d7
static Boolean 
Packit b099d7
FindPrevMenuBarCascade(
Packit b099d7
        XmRowColumnWidget menubar )
Packit b099d7
{
Packit b099d7
    Widget active_child = NULL;
Packit b099d7
    register int i, j;
Packit b099d7
    int upper_limit;
Packit b099d7
    ShellWidget shell;
Packit b099d7
    XmMenuState mst = _XmGetMenuState((Widget)menubar);
Packit b099d7
Packit b099d7
    upper_limit = menubar->composite.num_children;
Packit b099d7
Packit b099d7
    /* Determine which child is popped up */
Packit b099d7
    shell = (ShellWidget) RC_PopupPosted(menubar);
Packit b099d7
    if (shell != NULL)
Packit b099d7
       active_child = mst->MU_CurrentMenuChild =
Packit b099d7
          RC_CascadeBtn(shell->composite.children[0]);
Packit b099d7
Packit b099d7
    /* Find the index of the currently active item */
Packit b099d7
    for (i = 0; i < upper_limit; i++)
Packit b099d7
    {
Packit b099d7
        if (menubar->composite.children[i] == mst->MU_CurrentMenuChild)
Packit b099d7
           break;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* Start looking at the previous child */
Packit b099d7
    for (j = 0, --i; j < upper_limit - 1; j++, --i)
Packit b099d7
    {
Packit b099d7
        /* Wrap, if necessary */
Packit b099d7
        if (i < 0)
Packit b099d7
           i = upper_limit - 1;
Packit b099d7
Packit b099d7
        mst->MU_CurrentMenuChild = menubar->composite.children[i];
Packit b099d7
        if (ValidateMenuBarCascade(active_child, mst->MU_CurrentMenuChild))
Packit b099d7
           return True;
Packit b099d7
    }
Packit b099d7
    return False;
Packit b099d7
}
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static Boolean 
Packit b099d7
ValidateMenuBarCascade (Widget oldActiveChild, /* unused */
Packit b099d7
			Widget newMenuChild)
Packit b099d7
{
Packit b099d7
   XmRowColumnWidget menubar = (XmRowColumnWidget)XtParent(newMenuChild);
Packit b099d7
   Time _time = XtLastTimestampProcessed(XtDisplay(menubar));
Packit b099d7
Packit b099d7
   if (XmIsTraversable(newMenuChild))
Packit b099d7
   {
Packit b099d7
      if (XmIsCascadeButtonGadget(newMenuChild))
Packit b099d7
      {
Packit b099d7
         XmGadgetClassRec * gadget;
Packit b099d7
Packit b099d7
         gadget = (XmGadgetClassRec *)XtClass(newMenuChild);
Packit b099d7
Packit b099d7
         if (RC_PopupPosted(menubar) && !CBG_Submenu(newMenuChild))
Packit b099d7
         {
Packit b099d7
	     (*(((XmMenuShellClassRec *)xmMenuShellWidgetClass)->
Packit b099d7
		menu_shell_class.popdownEveryone))
Packit b099d7
		 (RC_PopupPosted(menubar),NULL, NULL, NULL);
Packit b099d7
Packit b099d7
            /* Return the X focus to the Menubar hierarchy from the menushell.
Packit b099d7
             * Set the Xt focus to the cascade
Packit b099d7
             */
Packit b099d7
            _XmMenuFocus((Widget) menubar, XmMENU_MIDDLE, _time);
Packit b099d7
            (void)XmProcessTraversal(newMenuChild, XmTRAVERSE_CURRENT);
Packit b099d7
         }
Packit b099d7
         else
Packit b099d7
         {
Packit b099d7
            (*(gadget->gadget_class.arm_and_activate)) (newMenuChild, NULL,
Packit b099d7
                                                                   NULL, NULL);
Packit b099d7
         }
Packit b099d7
         return True;
Packit b099d7
      }
Packit b099d7
      else if (XmIsCascadeButton (newMenuChild))
Packit b099d7
      {
Packit b099d7
         XmPrimitiveClassRec * prim;
Packit b099d7
Packit b099d7
         prim = (XmPrimitiveClassRec *)XtClass(newMenuChild);
Packit b099d7
Packit b099d7
         /* No submenu means PM mode */
Packit b099d7
         if (RC_PopupPosted(menubar) && !CB_Submenu(newMenuChild))
Packit b099d7
         {
Packit b099d7
	     (*(((XmMenuShellClassRec *)xmMenuShellWidgetClass)->
Packit b099d7
		menu_shell_class.popdownEveryone))
Packit b099d7
		 (RC_PopupPosted(menubar),NULL, NULL, NULL);
Packit b099d7
Packit b099d7
            /* Update X and Xt focus */
Packit b099d7
            _XmMenuFocus((Widget) menubar, XmMENU_MIDDLE, _time);
Packit b099d7
            (void)XmProcessTraversal(newMenuChild, XmTRAVERSE_CURRENT);
Packit b099d7
         }
Packit b099d7
         else
Packit b099d7
         {
Packit b099d7
            (*(prim->primitive_class.arm_and_activate)) (newMenuChild, NULL,
Packit b099d7
                                                                   NULL, NULL);
Packit b099d7
         }
Packit b099d7
         return True;
Packit b099d7
      }
Packit b099d7
   }
Packit b099d7
   return False;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/* (New) Grab strategy for menus requires grab before posting. If not possible
Packit b099d7
  * don't post the menu! This will ensure grabs active during a posted menu.
Packit b099d7
  * This will help consistency by preventing simultaneously posted menus.
Packit b099d7
  */
Packit b099d7
int 
Packit b099d7
_XmMenuGrabKeyboardAndPointer(
Packit b099d7
      Widget widget,
Packit b099d7
      Time time )
Packit b099d7
{
Packit b099d7
Packit b099d7
   register int status =
Packit b099d7
           (_XmGrabKeyboard(widget,
Packit b099d7
#ifdef FIX_1565
Packit b099d7
                            False,
Packit b099d7
#else
Packit b099d7
                            True,
Packit b099d7
#endif
Packit b099d7
                            GrabModeSync,
Packit b099d7
                            GrabModeAsync,
Packit b099d7
                            time) != GrabSuccess);
Packit b099d7
   if (status)
Packit b099d7
      return(status);
Packit b099d7
Packit b099d7
   status = _XmGrabPointer(widget, True, EVENTS, GrabModeSync,
Packit b099d7
       GrabModeAsync, None, XmGetMenuCursor(XtDisplay(widget)), time) !=
Packit b099d7
         GrabSuccess;
Packit b099d7
Packit b099d7
   if (status)
Packit b099d7
      XtUngrabKeyboard(widget, CurrentTime);
Packit b099d7
Packit b099d7
   return(status);
Packit b099d7
}