Blame lib/Xm/TravAct.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: TravAct.c /main/14 1999/05/27 13:58:09 mgreess $"
Packit b099d7
#endif
Packit b099d7
#endif
Packit b099d7

Packit b099d7
/* (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 HEWLETT-PACKARD COMPANY */
Packit b099d7
Packit b099d7
#include "TraversalI.h"
Packit b099d7
#include "TravActI.h"
Packit b099d7
#include <Xm/GadgetP.h>
Packit b099d7
#include <Xm/PrimitiveP.h>
Packit b099d7
#include <Xm/ManagerP.h>
Packit b099d7
#include <Xm/VendorSEP.h>
Packit b099d7
#include <Xm/MenuShellP.h>
Packit b099d7
#include "RepTypeI.h"
Packit b099d7
#include <Xm/VirtKeysP.h>
Packit b099d7
#include <Xm/DisplayP.h>
Packit b099d7
#include <Xm/ScrolledWP.h>
Packit b099d7
Packit b099d7
#include "ToolTipI.h"
Packit b099d7
Packit b099d7
Packit b099d7
#define EVENTS_EQ(ev1, ev2) \
Packit b099d7
  ((((ev1)->type == (ev2)->type) &&\
Packit b099d7
    ((ev1)->serial == (ev2)->serial) &&\
Packit b099d7
    ((ev1)->time == (ev2)->time) &&\
Packit b099d7
    ((ev1)->x == (ev2)->x) &&\
Packit b099d7
    ((ev1)->y == (ev2)->y)) ? TRUE : FALSE)
Packit b099d7
Packit b099d7
Packit b099d7
/********    Static Function Declarations    ********/
Packit b099d7
Packit b099d7
static Boolean UpdatePointerData(Widget w, XEvent *event);
Packit b099d7
static void FlushPointerData(Widget w, XEvent *event);
Packit b099d7
static void DispatchGadgetInput(XmGadget g, XEvent *event, Mask mask);
Packit b099d7
Packit b099d7
/********    End Static Function Declarations    ********/
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * The following functions are used by the widgets to query or modify one
Packit b099d7
 * of the display dependent global variabled used by traversal mechanism.
Packit b099d7
 */
Packit b099d7
Packit b099d7
unsigned short
Packit b099d7
_XmGetFocusFlag(Widget w, 
Packit b099d7
		unsigned int mask)
Packit b099d7
{
Packit b099d7
  XmDisplay dd = (XmDisplay)XmGetXmDisplay(XtDisplay(w));
Packit b099d7
Packit b099d7
  return ((unsigned short)((XmDisplayInfo *)
Packit b099d7
	   (dd->display.displayInfo))->resetFocusFlag & mask);
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
void 
Packit b099d7
_XmSetFocusFlag(Widget w,
Packit b099d7
		unsigned int mask,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
		int value)
Packit b099d7
#else
Packit b099d7
     		Boolean value)
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
  XmDisplay dd = (XmDisplay)XmGetXmDisplay(XtDisplay(w));
Packit b099d7
Packit b099d7
  if (value)
Packit b099d7
     ((XmDisplayInfo *)
Packit b099d7
	 (dd->display.displayInfo))->resetFocusFlag |= mask;
Packit b099d7
  else
Packit b099d7
     ((XmDisplayInfo *)
Packit b099d7
	 (dd->display.displayInfo))->resetFocusFlag &= ~mask;
Packit b099d7
}
Packit b099d7
     
Packit b099d7

Packit b099d7
static Boolean 
Packit b099d7
UpdatePointerData(Widget w,
Packit b099d7
		  XEvent *event)
Packit b099d7
{
Packit b099d7
  XmFocusData focusData;
Packit b099d7
  
Packit b099d7
  if ((focusData = _XmGetFocusData(w)) != NULL)
Packit b099d7
    {
Packit b099d7
      XCrossingEvent *lastEvent = &(focusData->lastCrossingEvent);
Packit b099d7
      
Packit b099d7
      focusData->needToFlush = TRUE;
Packit b099d7
      
Packit b099d7
      if (!EVENTS_EQ(lastEvent, (XCrossingEvent *)event))
Packit b099d7
	{
Packit b099d7
	  focusData->old_pointer_item = focusData->pointer_item;
Packit b099d7
	  focusData->pointer_item = w;
Packit b099d7
	  focusData->lastCrossingEvent = *(XCrossingEvent *) event;
Packit b099d7
	  return TRUE;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
  return FALSE;
Packit b099d7
}
Packit b099d7

Packit b099d7
static void 
Packit b099d7
FlushPointerData(Widget w,
Packit b099d7
		 XEvent *event)
Packit b099d7
{
Packit b099d7
  XmFocusData focusData = _XmGetFocusData(w);
Packit b099d7
  
Packit b099d7
  if (focusData && focusData->needToFlush)
Packit b099d7
    {
Packit b099d7
      XCrossingEvent	lastEvent;
Packit b099d7
      
Packit b099d7
      lastEvent = focusData->lastCrossingEvent;
Packit b099d7
      
Packit b099d7
      focusData->needToFlush = FALSE;
Packit b099d7
      /* 
Packit b099d7
       * We are munging data into the event to fake out the focus
Packit b099d7
       * code when Mwm is trying to catch up with the pointer.
Packit b099d7
       * This event that we are munging might already have been
Packit b099d7
       * munged by XmDispatchGadgetInput from a motion event to a
Packit b099d7
       * crossing event !!!!!
Packit b099d7
       */
Packit b099d7
      
Packit b099d7
      lastEvent.serial = event->xany.serial;
Packit b099d7
      if ( (LeaveNotify == event->type) || (EnterNotify == event->type) )
Packit b099d7
	      lastEvent.time = event->xcrossing.time;
Packit b099d7
      else
Packit b099d7
		/* Approximation; the code appears to need even Focus events,
Packit b099d7
		** so make up a time and try to continue, rather than limit
Packit b099d7
		** lastEvent to XCrossingEvents. (It is a flaw in the X
Packit b099d7
		** Protocol that Focus events do not have timestamps.)
Packit b099d7
		*/
Packit b099d7
		lastEvent.time = XtLastTimestampProcessed(XtDisplay(w));
Packit b099d7
      lastEvent.focus = True;
Packit b099d7
      XtDispatchEvent((XEvent *) &lastEvent);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7

Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  _XmTrackShellFocus
Packit b099d7
 *
Packit b099d7
 *  This handler is added by ShellExt initialize to the front of the
Packit b099d7
 * queue
Packit b099d7
 *     
Packit b099d7
 ************************************************************************/
Packit b099d7
Packit b099d7
void 
Packit b099d7
_XmTrackShellFocus(Widget widget,
Packit b099d7
		   XtPointer client_data,
Packit b099d7
		   XEvent *event,
Packit b099d7
		   Boolean *dontSwallow)
Packit b099d7
{
Packit b099d7
  XmVendorShellExtObject ve = (XmVendorShellExtObject) client_data;
Packit b099d7
  XmFocusData		 focusData;
Packit b099d7
  XmGeneology		 oldFocalPoint;
Packit b099d7
  XmGeneology		 newFocalPoint;
Packit b099d7
  
Packit b099d7
  if (widget->core.being_destroyed)
Packit b099d7
    {
Packit b099d7
      *dontSwallow = False;
Packit b099d7
      return;
Packit b099d7
    }
Packit b099d7
Packit b099d7
  if ((focusData = ve->vendor.focus_data) == NULL)
Packit b099d7
    return;
Packit b099d7
Packit b099d7
  oldFocalPoint = newFocalPoint = focusData->focalPoint;
Packit b099d7
  
Packit b099d7
  switch(event->type)
Packit b099d7
    {
Packit b099d7
    case EnterNotify:
Packit b099d7
    case LeaveNotify:
Packit b099d7
      /*
Packit b099d7
       * If operating in a focus driven model, then enter and
Packit b099d7
       * leave events do not affect the keyboard focus.
Packit b099d7
       */
Packit b099d7
      if ((event->xcrossing.detail != NotifyInferior) &&
Packit b099d7
	  (event->xcrossing.focus))
Packit b099d7
	{	      
Packit b099d7
	  switch (oldFocalPoint)
Packit b099d7
	    {
Packit b099d7
	    case XmUnrelated:
Packit b099d7
	      if (event->type == EnterNotify)
Packit b099d7
		newFocalPoint = XmMyAncestor;
Packit b099d7
	      break;
Packit b099d7
	    case XmMyAncestor:
Packit b099d7
	      if (event->type == LeaveNotify)
Packit b099d7
		newFocalPoint = XmUnrelated;
Packit b099d7
	      break;
Packit b099d7
	    case XmMyDescendant:
Packit b099d7
	    case XmMyCousin:
Packit b099d7
	    case XmMySelf:
Packit b099d7
	    default:
Packit b099d7
	      break;
Packit b099d7
	    }	
Packit b099d7
	}
Packit b099d7
      break;
Packit b099d7
Packit b099d7
    case FocusIn:
Packit b099d7
      switch (event->xfocus.detail)
Packit b099d7
	{
Packit b099d7
	case NotifyNonlinear:
Packit b099d7
	case NotifyAncestor:
Packit b099d7
	case NotifyInferior:
Packit b099d7
	  newFocalPoint = XmMySelf;
Packit b099d7
	  break;
Packit b099d7
	case NotifyNonlinearVirtual:
Packit b099d7
	case NotifyVirtual:
Packit b099d7
	  newFocalPoint = XmMyDescendant;
Packit b099d7
	  break;
Packit b099d7
	case NotifyPointer:
Packit b099d7
	  newFocalPoint = XmMyAncestor;
Packit b099d7
	  break;
Packit b099d7
	}
Packit b099d7
      break;
Packit b099d7
Packit b099d7
    case FocusOut:
Packit b099d7
      switch (event->xfocus.detail)
Packit b099d7
	{
Packit b099d7
	case NotifyPointer:
Packit b099d7
	case NotifyNonlinear:
Packit b099d7
	case NotifyAncestor:
Packit b099d7
	case NotifyNonlinearVirtual:
Packit b099d7
	case NotifyVirtual:
Packit b099d7
	  newFocalPoint = XmUnrelated;
Packit b099d7
	  break;
Packit b099d7
	case NotifyInferior:
Packit b099d7
	  return;
Packit b099d7
	}
Packit b099d7
      break;
Packit b099d7
    }
Packit b099d7
Packit b099d7
  if (newFocalPoint == XmUnrelated)
Packit b099d7
    {
Packit b099d7
      focusData->old_focus_item = NULL;
Packit b099d7
      
Packit b099d7
      if (focusData->trav_graph.num_alloc)
Packit b099d7
	{
Packit b099d7
	  /* Free traversal graph, since focus is leaving hierarchy. */
Packit b099d7
	  _XmFreeTravGraph(&(focusData->trav_graph));
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
  if ((focusData->focus_policy == XmEXPLICIT) &&
Packit b099d7
      (oldFocalPoint != newFocalPoint) &&
Packit b099d7
      focusData->focus_item)
Packit b099d7
    {
Packit b099d7
      if (oldFocalPoint == XmUnrelated)
Packit b099d7
	_XmCallFocusMoved(NULL, focusData->focus_item, event);
Packit b099d7
      else if (newFocalPoint == XmUnrelated)
Packit b099d7
	_XmCallFocusMoved(focusData->focus_item, NULL, event);
Packit b099d7
    }
Packit b099d7
Packit b099d7
  focusData->focalPoint = newFocalPoint;
Packit b099d7
}
Packit b099d7

Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  Enter & Leave
Packit b099d7
 *      Enter and leave event processing routines.
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
void 
Packit b099d7
_XmPrimitiveEnter(Widget wid,
Packit b099d7
		  XEvent *event,
Packit b099d7
		  String *params,	/* unused */
Packit b099d7
		  Cardinal *num_params)	/* unused */
Packit b099d7
{   
Packit b099d7
  _XmToolTipEnter(wid, event, params, num_params);
Packit b099d7
  if (_XmGetFocusPolicy(wid) == XmPOINTER)
Packit b099d7
    {   
Packit b099d7
      if (event->xcrossing.focus)
Packit b099d7
        {   
Packit b099d7
	  _XmCallFocusMoved(XtParent(wid), wid, event);
Packit b099d7
	  _XmWidgetFocusChange(wid, XmENTER);
Packit b099d7
	}
Packit b099d7
Packit b099d7
      UpdatePointerData(wid, event);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7

Packit b099d7
/*ARGSUSED*/
Packit b099d7
void 
Packit b099d7
_XmPrimitiveLeave(Widget wid,
Packit b099d7
		  XEvent *event,
Packit b099d7
		  String *params,	/* unused */
Packit b099d7
		  Cardinal *num_params)	/* unused */
Packit b099d7
{   
Packit b099d7
  _XmToolTipLeave(wid, event, params, num_params);
Packit b099d7
  if (_XmGetFocusPolicy(wid) == XmPOINTER)
Packit b099d7
    {   
Packit b099d7
      if (event->xcrossing.focus)
Packit b099d7
        {   
Packit b099d7
	  _XmCallFocusMoved(wid, XtParent(wid), event);
Packit b099d7
	  _XmWidgetFocusChange(wid, XmLEAVE);
Packit b099d7
	}
Packit b099d7
    }	
Packit b099d7
}
Packit b099d7

Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  Focus In & Out
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
void 
Packit b099d7
_XmPrimitiveFocusInInternal(Widget wid,
Packit b099d7
			    XEvent *event,
Packit b099d7
			    String *params,		/* unused */
Packit b099d7
			    Cardinal *num_params)	/* unused */
Packit b099d7
{   
Packit b099d7
  if (!(event->xfocus.send_event) ||
Packit b099d7
      _XmGetFocusFlag(wid, XmFOCUS_IGNORE))
Packit b099d7
    return;
Packit b099d7
Packit b099d7
  if (_XmGetFocusPolicy(wid) == XmPOINTER)
Packit b099d7
    {   
Packit b099d7
      /* Maybe Mwm trying to catch up with us. */
Packit b099d7
      if (XtIsShell(XtParent(wid)))
Packit b099d7
	FlushPointerData(wid, event);
Packit b099d7
    }
Packit b099d7
  else 
Packit b099d7
    {   
Packit b099d7
      /* We should only be recieving the focus from a traversal request. */
Packit b099d7
      if (!_XmGetActiveTabGroup(wid))
Packit b099d7
	_XmMgrTraversal(_XmFindTopMostShell(wid), XmTRAVERSE_NEXT_TAB_GROUP);
Packit b099d7
      else
Packit b099d7
	_XmWidgetFocusChange(wid, XmFOCUS_IN);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7

Packit b099d7
/*ARGSUSED*/
Packit b099d7
void 
Packit b099d7
_XmPrimitiveFocusOut(Widget wid,
Packit b099d7
		     XEvent *event,
Packit b099d7
		     String *params,		/* unused */
Packit b099d7
		     Cardinal *num_params)	/* unused */
Packit b099d7
{   
Packit b099d7
  if (event->xfocus.send_event &&
Packit b099d7
      !(wid->core.being_destroyed) &&
Packit b099d7
      (_XmGetFocusPolicy(wid) == XmEXPLICIT))
Packit b099d7
    {   
Packit b099d7
      _XmWidgetFocusChange(wid, XmFOCUS_OUT);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7

Packit b099d7
void 
Packit b099d7
_XmPrimitiveFocusIn(Widget pw,
Packit b099d7
		    XEvent *event,
Packit b099d7
		    String *params,
Packit b099d7
		    Cardinal *num_params)
Packit b099d7
{
Packit b099d7
  _XmPrimitiveFocusInInternal(pw, event, params, num_params);
Packit b099d7
}
Packit b099d7

Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  _XmEnterGadget
Packit b099d7
 *     This function processes enter window conditions occuring in a gadget
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
void 
Packit b099d7
_XmEnterGadget(Widget wid,
Packit b099d7
	       XEvent *event,
Packit b099d7
	       String *params,		/* unused */
Packit b099d7
	       Cardinal *num_params)	/* unused */
Packit b099d7
{   
Packit b099d7
  if (XmIsGadget(wid) && ((XmGadget)wid)->gadget.traversal_on)
Packit b099d7
  {
Packit b099d7
      _XmToolTipEnter(wid, event, params, num_params);
Packit b099d7
  }
Packit b099d7
  if (_XmGetFocusPolicy(wid) == XmPOINTER)
Packit b099d7
    {   
Packit b099d7
      XmFocusData focusData = _XmGetFocusData(wid);
Packit b099d7
      
Packit b099d7
      /* We may be getting called as a result of Mwm catching up
Packit b099d7
       * with the pointer and setting input focus to the shell
Packit b099d7
       * which then gets forwarded to us.
Packit b099d7
       */
Packit b099d7
      if (focusData && (focusData->focalPoint != XmUnrelated))
Packit b099d7
        {   
Packit b099d7
	  _XmCallFocusMoved(XtParent(wid), wid, event);
Packit b099d7
	  _XmWidgetFocusChange(wid, XmENTER);
Packit b099d7
        }
Packit b099d7
    }
Packit b099d7
}
Packit b099d7

Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  DispatchGadgetInput
Packit b099d7
 *	This routine is used instead of _XmDispatchGadgetInput due to
Packit b099d7
 *	the fact that it needs to dispatch to unmanaged gadgets
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
static void 
Packit b099d7
DispatchGadgetInput(XmGadget g,
Packit b099d7
		    XEvent *event,
Packit b099d7
		    Mask mask)
Packit b099d7
{
Packit b099d7
   if ((g->gadget.event_mask & mask) && XtIsSensitive((Widget)g))
Packit b099d7
     {
Packit b099d7
       (*(((XmGadgetClass) (g->object.widget_class))->
Packit b099d7
	  gadget_class.input_dispatch)) ((Widget) g, event, mask);
Packit b099d7
     }
Packit b099d7
}
Packit b099d7

Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  _XmLeaveGadget
Packit b099d7
 *     This function processes leave window conditions occuring in a gadget
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
void 
Packit b099d7
_XmLeaveGadget(Widget wid,
Packit b099d7
	       XEvent *event,
Packit b099d7
	       String *params,		/* unused */
Packit b099d7
	       Cardinal *num_params)	/* unused */
Packit b099d7
{   
Packit b099d7
  if (XmIsGadget(wid) && ((XmGadget)wid)->gadget.traversal_on)
Packit b099d7
  {
Packit b099d7
      _XmToolTipLeave(wid, event, params, num_params);
Packit b099d7
  }
Packit b099d7
Packit b099d7
  if (_XmGetFocusPolicy(wid) == XmPOINTER)
Packit b099d7
    {   
Packit b099d7
      _XmCallFocusMoved(wid, XtParent(wid), event);
Packit b099d7
      _XmWidgetFocusChange(wid, XmLEAVE);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7

Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  _XmFocusInGadget
Packit b099d7
 *     This function processes focusIn conditions occuring in a gadget
Packit b099d7
 *
Packit b099d7
Packit b099d7
 ************************************************************************/
Packit b099d7
/*ARGSUSED*/
Packit b099d7
void 
Packit b099d7
_XmFocusInGadget(Widget wid,
Packit b099d7
		 XEvent *event,		/* unused */
Packit b099d7
		 String *params,	/* unused */
Packit b099d7
		 Cardinal *num_params)	/* unused */
Packit b099d7
{
Packit b099d7
  if (_XmGetFocusPolicy(wid) == XmEXPLICIT)
Packit b099d7
    _XmWidgetFocusChange(wid, XmFOCUS_IN);
Packit b099d7
}
Packit b099d7

Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  _XmFocusOutGadget
Packit b099d7
 *     This function processes FocusOut conditions occuring in a gadget
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
void 
Packit b099d7
_XmFocusOutGadget(Widget wid,
Packit b099d7
		  XEvent *event,	/* unused */
Packit b099d7
		  String *params,	/* unused */
Packit b099d7
		  Cardinal *num_params)	/* unused */
Packit b099d7
{
Packit b099d7
  if (_XmGetFocusPolicy(wid) == XmEXPLICIT)
Packit b099d7
    _XmWidgetFocusChange(wid, XmFOCUS_OUT);
Packit b099d7
}
Packit b099d7

Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  Enter, FocusIn and Leave Window procs
Packit b099d7
 *
Packit b099d7
 *     These two procedures handle traversal activation and deactivation
Packit b099d7
 *     for manager widgets. They are invoked directly throught the
Packit b099d7
 *     the action table of a widget.
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  _XmManagerEnter
Packit b099d7
 *     This function handles both focusIn and Enter. Don't ask me why
Packit b099d7
 *     :-(
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
void 
Packit b099d7
_XmManagerEnter(Widget wid,
Packit b099d7
		XEvent *event_in,
Packit b099d7
		String *params,		/* unused */
Packit b099d7
		Cardinal *num_params)	/* unused */
Packit b099d7
{
Packit b099d7
  XmManagerWidget mw = (XmManagerWidget) wid;
Packit b099d7
  XCrossingEvent *event = (XCrossingEvent *) event_in;
Packit b099d7
  
Packit b099d7
  if (_XmGetFocusPolicy((Widget) mw) == XmPOINTER)
Packit b099d7
    {
Packit b099d7
      if (UpdatePointerData((Widget) mw, event_in) && event->focus)
Packit b099d7
	{
Packit b099d7
	  Widget old;
Packit b099d7
	  
Packit b099d7
	  if (event->detail == NotifyInferior)
Packit b099d7
	    old = XtWindowToWidget(event->display, event->subwindow);
Packit b099d7
	  else
Packit b099d7
	    old = XtParent(mw);
Packit b099d7
Packit b099d7
	  _XmCallFocusMoved(old, (Widget) mw, (XEvent *) event);
Packit b099d7
	  _XmWidgetFocusChange((Widget) mw, XmENTER);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
}
Packit b099d7

Packit b099d7
/*ARGSUSED*/
Packit b099d7
void 
Packit b099d7
_XmManagerLeave(Widget wid,
Packit b099d7
		XEvent *event,
Packit b099d7
		String *params,		/* unused */
Packit b099d7
		Cardinal *num_params)	/* unused */
Packit b099d7
{
Packit b099d7
  /*
Packit b099d7
   * This code is inefficient since it is called twice for each
Packit b099d7
   * internal move in the hierarchy |||
Packit b099d7
   */
Packit b099d7
  if (event->type == LeaveNotify)
Packit b099d7
    {
Packit b099d7
      if (_XmGetFocusPolicy(wid) == XmPOINTER)
Packit b099d7
	{
Packit b099d7
	  Widget new_wid;
Packit b099d7
	  
Packit b099d7
	  if (event->xcrossing.detail == NotifyInferior)
Packit b099d7
	    new_wid = XtWindowToWidget(event->xcrossing.display, 
Packit b099d7
				       event->xcrossing.subwindow);
Packit b099d7
	  else 
Packit b099d7
	    new_wid = XtParent(wid);
Packit b099d7
Packit b099d7
	  if (UpdatePointerData(wid, event) && event->xcrossing.focus)
Packit b099d7
	    {
Packit b099d7
	      _XmCallFocusMoved(wid, new_wid, event);
Packit b099d7
	      _XmWidgetFocusChange(wid, XmLEAVE);
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
}
Packit b099d7

Packit b099d7
/*ARGSUSED*/
Packit b099d7
void 
Packit b099d7
_XmManagerFocusInInternal(Widget wid,
Packit b099d7
			  XEvent *event,
Packit b099d7
			  String *params,	/* unused */
Packit b099d7
			  Cardinal *num_params)	/* unused */
Packit b099d7
{   
Packit b099d7
  Widget child;
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Managers ignore all focus events which have been generated by the
Packit b099d7
   * window system; only those sent to us by a window manager or the
Packit b099d7
   * Xtk focus code is accepted.
Packit b099d7
   * Bail out if the focus policy is not set to explicit
Packit b099d7
   */
Packit b099d7
  if (!(event->xfocus.send_event) ||
Packit b099d7
      _XmGetFocusFlag(wid, XmFOCUS_RESET | XmFOCUS_IGNORE))
Packit b099d7
    return;
Packit b099d7
Packit b099d7
  if (_XmGetFocusPolicy(wid) == XmPOINTER)
Packit b099d7
    {   
Packit b099d7
      FlushPointerData(wid, event);
Packit b099d7
    } 
Packit b099d7
  else if (!_XmGetActiveTabGroup(wid))
Packit b099d7
    {   
Packit b099d7
      /* If the heirarchy doesn't have an active tab group give it one. */
Packit b099d7
      _XmMgrTraversal(_XmFindTopMostShell(wid), XmTRAVERSE_NEXT_TAB_GROUP);
Packit b099d7
    } 
Packit b099d7
  else if ((child = ((XmManagerWidget) wid)->manager.active_child) && 
Packit b099d7
	   XmIsGadget(child))
Packit b099d7
    {   
Packit b099d7
      /* If focus went to a gadget, then force it to highlight */
Packit b099d7
      DispatchGadgetInput((XmGadget) child, event, XmFOCUS_IN_EVENT);
Packit b099d7
    }
Packit b099d7
  else
Packit b099d7
    {
Packit b099d7
      _XmWidgetFocusChange(wid, XmFOCUS_IN);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * Non-menu widgets use this entry point, so that they will ignore focus
Packit b099d7
 * events during menu activities.
Packit b099d7
 */
Packit b099d7
void 
Packit b099d7
_XmManagerFocusIn(Widget mw,
Packit b099d7
		  XEvent *event,
Packit b099d7
		  String *params,
Packit b099d7
		  Cardinal *num_params)
Packit b099d7
{
Packit b099d7
  _XmManagerFocusInInternal(mw, event, params, num_params);
Packit b099d7
}
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * If the manager widget received a FocusOut while it is processing its
Packit b099d7
 * FocusIn event, then it knows that the focus has been successfully moved
Packit b099d7
 * to one of its children.  However, if no FocusOut is received, then the
Packit b099d7
 * manager widget must manually force the child to take the focus.
Packit b099d7
 */
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
void 
Packit b099d7
_XmManagerFocusOut(Widget wid,
Packit b099d7
		   XEvent *event,
Packit b099d7
		   String *params,		/* unused */
Packit b099d7
		   Cardinal *num_params)	/* unused */
Packit b099d7
{   
Packit b099d7
  Widget child;
Packit b099d7
  
Packit b099d7
  if (!event->xfocus.send_event)
Packit b099d7
    return;
Packit b099d7
Packit b099d7
  if (_XmGetFocusPolicy(wid) == XmEXPLICIT)
Packit b099d7
    {   
Packit b099d7
      /* If focus is in a gadget, then force it to unhighlight. */
Packit b099d7
      if ((child = ((XmManagerWidget) wid)->manager.active_child) &&
Packit b099d7
	  XmIsGadget(child))
Packit b099d7
        {   
Packit b099d7
	  DispatchGadgetInput((XmGadget) child, event, XmFOCUS_OUT_EVENT);
Packit b099d7
	}
Packit b099d7
      else
Packit b099d7
	{
Packit b099d7
	  _XmWidgetFocusChange(wid, XmFOCUS_OUT);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
}
Packit b099d7

Packit b099d7
/*ARGSUSED*/
Packit b099d7
void 
Packit b099d7
_XmManagerUnmap(Widget mw,
Packit b099d7
		XEvent *event,		/* unused */
Packit b099d7
		String *params,		/* unused */
Packit b099d7
		Cardinal *num_params)	/* unused */
Packit b099d7
{
Packit b099d7
  /* This functionality is bogus, since a good implementation
Packit b099d7
   * requires more code (hooks for mapping of widgets) than it's
Packit b099d7
   * worth.  To move focus away from a widget when it is unmapped
Packit b099d7
   * implies the ability to recover from the case when the last
Packit b099d7
   * traversable widget in a hierarchy is unmapped and then re-mapped.
Packit b099d7
   * Since we don't have the hooks in place for the mapping of these
Packit b099d7
   * widgets, and since the old code only worked some of the time,
Packit b099d7
   * and since it is arguable that the focus should never be
Packit b099d7
   * changed in response to a widget being unmapped, we should choose
Packit b099d7
   * to do NO traversal in response to the unmapping of a widget.
Packit b099d7
   * However, historical precedent again defeats good design.
Packit b099d7
   */
Packit b099d7
  _XmValidateFocus(mw);
Packit b099d7
}
Packit b099d7

Packit b099d7
/*ARGSUSED*/
Packit b099d7
void 
Packit b099d7
_XmPrimitiveUnmap(Widget pw,
Packit b099d7
		  XEvent *event,	/* unused */
Packit b099d7
		  String *params,	/* unused */
Packit b099d7
		  Cardinal *num_params)	/* unused */
Packit b099d7
{
Packit b099d7
  _XmValidateFocus(pw);
Packit b099d7
}