Blame clients/mwm/WmEvent.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
 * Motif Release 1.2.4
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[] = "$XConsortium: WmEvent.c /main/7 1996/11/20 15:27:47 rswiston $"
Packit b099d7
#endif
Packit b099d7
#endif
Packit b099d7
/*
Packit b099d7
 * (c) Copyright 1987, 1988, 1989, 1990, 1993, 1994 HEWLETT-PACKARD COMPANY 
Packit b099d7
 * (c) Copyright 1993, 1994 International Business Machines Corp.
Packit b099d7
 * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
Packit b099d7
 * (c) Copyright 1993, 1994 Novell, Inc.
Packit b099d7
 */
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Included Files:
Packit b099d7
 */
Packit b099d7
Packit b099d7
#include "WmGlobal.h"
Packit b099d7
/*
Packit b099d7
 * include extern functions
Packit b099d7
 */
Packit b099d7
#include "WmEvent.h"
Packit b099d7
#ifdef WSM
Packit b099d7
#include "WmBackdrop.h"
Packit b099d7
#endif /* WSM */
Packit b099d7
#include "WmCDInfo.h"
Packit b099d7
#include "WmCDecor.h"
Packit b099d7
#include "WmCEvent.h"
Packit b099d7
#include "WmColormap.h"
Packit b099d7
#include "WmFunction.h"
Packit b099d7
#include "WmKeyFocus.h"
Packit b099d7
#ifdef PANELIST
Packit b099d7
#include "WmPanelP.h"  /* for typedef in WmManage.h */
Packit b099d7
#endif /* PANELIST */
Packit b099d7
#include "WmManage.h"
Packit b099d7
#include "WmMenu.h"
Packit b099d7
#ifdef WSM
Packit b099d7
#include "WmICCC.h"
Packit b099d7
#include "WmProperty.h"
Packit b099d7
#endif /* WSM */
Packit b099d7
#include "WmWinInfo.h"
Packit b099d7
#include "WmWinState.h"
Packit b099d7
#ifdef PANELIST
Packit b099d7
#include "WmResNames.h"
Packit b099d7
#include "WmResParse.h"
Packit b099d7
#include "WmParse.h"
Packit b099d7
#include "WmParseP.h"
Packit b099d7
#endif /* PANELIST */
Packit b099d7
Packit b099d7
#include <Xm/RowColumnP.h> /* for MS_LastManagedMenuTime */
Packit b099d7
extern XmMenuState _XmGetMenuState();
Packit b099d7
Packit b099d7
#ifdef WSM
Packit b099d7
/*
Packit b099d7
 * FUNCTION PARSER TABLE
Packit b099d7
 */
Packit b099d7
Packit b099d7
typedef struct {
Packit b099d7
   char         * funcName;
Packit b099d7
   Context        greyedContext;
Packit b099d7
   unsigned int   resource;
Packit b099d7
   long           mgtMask;
Packit b099d7
   WmFunction     wmFunction;
Packit b099d7
   Boolean       (*parseProc)();
Packit b099d7
} FunctionTableEntry;
Packit b099d7
Packit b099d7
#endif /* WSM */
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Global Variables:
Packit b099d7
 */
Packit b099d7
Packit b099d7
extern unsigned int buttonModifierMasks[];
Packit b099d7
#ifdef WSM
Packit b099d7
int smAckState = SM_UNITIALIZED;
Packit b099d7
extern FunctionTableEntry functionTable[];
Packit b099d7
extern int F_NOP_INDEX;
Packit b099d7
#endif /* WSM */
Packit b099d7
Packit b099d7
#ifndef MOTIF_ONE_DOT_ONE
Packit b099d7
#include <Xm/MenuShellP.h>
Packit b099d7
#endif
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  InitEventHandling ()
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function initializes window manager event handling in preparation
Packit b099d7
 *  for managing client windows.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  wmGD = (keySpecs)
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void InitEventHandling (void)
Packit b099d7
{
Packit b099d7
    WmScreenData *pSD;
Packit b099d7
    XSetWindowAttributes setAttributes;
Packit b099d7
    unsigned long base_mask;
Packit b099d7
    unsigned int n, scr;
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Prepare to get root (workspace) window events that are used to
Packit b099d7
     * manage client windows.  Setup accelerator event processing.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    base_mask = SubstructureRedirectMask | FocusChangeMask;
Packit b099d7
Packit b099d7
    /* handle entry of root window */
Packit b099d7
    base_mask |= EnterWindowMask | LeaveWindowMask;
Packit b099d7
Packit b099d7
    for (scr=0; scr
Packit b099d7
    {
Packit b099d7
	pSD = &(wmGD.Screens[scr]);
Packit b099d7
Packit b099d7
        if (pSD->managed) 
Packit b099d7
        {
Packit b099d7
	    setAttributes.event_mask = base_mask;
Packit b099d7
Packit b099d7
	    if (pSD->buttonBindings)
Packit b099d7
	    {
Packit b099d7
		/*
Packit b099d7
		 * The desktop menu and button bindings for window 
Packit b099d7
		 * manager functions use button press and button 
Packit b099d7
		 * release events.
Packit b099d7
		 */
Packit b099d7
		setAttributes.event_mask |= 
Packit b099d7
		    (ButtonPressMask | ButtonReleaseMask);
Packit b099d7
	    }
Packit b099d7
Packit b099d7
            XChangeWindowAttributes (DISPLAY, pSD->rootWindow, 
Packit b099d7
                CWEventMask, &setAttributes);
Packit b099d7
Packit b099d7
Packit b099d7
	    /*
Packit b099d7
	     * Setup event handling for "accelerated" window management 
Packit b099d7
	     * functions done with key bindings.
Packit b099d7
	     */
Packit b099d7
Packit b099d7
            if (pSD->keySpecs)
Packit b099d7
            {
Packit b099d7
        	SetupKeyBindings (pSD->keySpecs, pSD->rootWindow, 
Packit b099d7
		    GrabModeSync, F_CONTEXT_ALL);
Packit b099d7
            }
Packit b099d7
        
Packit b099d7
	    if (pSD->acceleratorMenuCount)
Packit b099d7
	    {
Packit b099d7
		for (n = 0; n < pSD->acceleratorMenuCount; n++)
Packit b099d7
		{
Packit b099d7
		SetupKeyBindings (
Packit b099d7
		    pSD->acceleratorMenuSpecs[n]->accelKeySpecs,
Packit b099d7
		    pSD->rootWindow, GrabModeSync, F_CONTEXT_ALL);
Packit b099d7
		}
Packit b099d7
	    }
Packit b099d7
	} /* end if (managed) */
Packit b099d7
    }  /* end for (all screens) */
Packit b099d7
} /* END OF FUNCTION InitEventHandling */
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  _WmGrabMasks (modifiers, pnum_masks)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function returns a set of grab masks to use that effectively
Packit b099d7
 *  filters out the effects of locking modifiers. Redundant masks
Packit b099d7
 *  are removed.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  modifiers		- keymask of modifiers
Packit b099d7
 *
Packit b099d7
 *  Outputs:
Packit b099d7
 *  ------
Packit b099d7
 *  *pnum_masks		- number of masks returned
Packit b099d7
 *
Packit b099d7
 *  Return:
Packit b099d7
 *  -------
Packit b099d7
 *  pointer to a NULL-terminated list of modifier masks. This memory is
Packit b099d7
 *  statically allocated and reused. Do no free or modify. Make a copy
Packit b099d7
 *  if you need to keep it. 
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
static unsigned int *
Packit b099d7
_WmGrabMasks ( unsigned int modifiers, int *pnum_masks )
Packit b099d7
{
Packit b099d7
    static unsigned int	*pRetMasks = NULL;
Packit b099d7
    static int len_ret_masks = 0;
Packit b099d7
    int num_masks;
Packit b099d7
    int num_ret_masks;
Packit b099d7
    int i,j;
Packit b099d7
    unsigned int mask;
Packit b099d7
Packit b099d7
    /* count the number of masks in the lock sequence */
Packit b099d7
    for (num_masks=0; wmGD.pLockMaskSequence[num_masks] != 0; num_masks++);
Packit b099d7
Packit b099d7
    /* insure we have enough space for our returned masks */
Packit b099d7
    if ((pRetMasks == NULL) || (len_ret_masks < num_masks+2))
Packit b099d7
    {
Packit b099d7
	if (pRetMasks != NULL) 
Packit b099d7
			XtFree ((char *)pRetMasks);
Packit b099d7
Packit b099d7
	len_ret_masks = num_masks+2;
Packit b099d7
	pRetMasks = (unsigned int *) 
Packit b099d7
			XtCalloc (len_ret_masks, sizeof(unsigned int));
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* fill up the array of masks we return */
Packit b099d7
    num_ret_masks = 0;
Packit b099d7
    for (i=0; i
Packit b099d7
    {
Packit b099d7
	/* combine with this set of locking mods */
Packit b099d7
	mask = (modifiers | wmGD.pLockMaskSequence[i]);
Packit b099d7
Packit b099d7
	/* skip if exact match */
Packit b099d7
	if (mask == modifiers) continue;
Packit b099d7
Packit b099d7
	/* add this mask to the list if not already there */
Packit b099d7
        for (j=0; j
Packit b099d7
	{
Packit b099d7
	    if (mask == pRetMasks[j])
Packit b099d7
		break;
Packit b099d7
	}
Packit b099d7
	if (j >= num_ret_masks)
Packit b099d7
	{
Packit b099d7
	    /* we don't have this mask yet, add it */
Packit b099d7
	    pRetMasks[num_ret_masks] = mask;
Packit b099d7
	    num_ret_masks++;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Add the original mask to the list at the end
Packit b099d7
     */
Packit b099d7
    pRetMasks[num_ret_masks++] = modifiers;
Packit b099d7
    pRetMasks[num_ret_masks] = 0;		/* terminator */
Packit b099d7
Packit b099d7
    *pnum_masks = num_ret_masks;
Packit b099d7
Packit b099d7
    return (pRetMasks);
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  WmGrabKey (display, keycode, modifiers, grab_window, owner_events,
Packit b099d7
 *		pointer_mode, keyboard_mode)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function does several grabs on a key to make sure the
Packit b099d7
 *  key is grabbed irrespective of the state of locking modifiers
Packit b099d7
 *  It is a wrapper for XGrabKey, so the parameters are all the
Packit b099d7
 *  same.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  display		- X server connection
Packit b099d7
 *  keycode		- keycode to grab
Packit b099d7
 *  modifiers		- keymask of modifiers
Packit b099d7
 *  grab_window		- window to do grab on
Packit b099d7
 *  owner_events	- does app receive events normally?
Packit b099d7
 *  pointer_mode	- pointer event processing during grab
Packit b099d7
 *  keyboard_mode	- keyboard event processing during grab
Packit b099d7
 *  wmGD.pLockMaskSequence	- extra modifier masks to grab with
Packit b099d7
 *
Packit b099d7
 *  Return:
Packit b099d7
 *  -------
Packit b099d7
 *  The function is asynchronous.
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void
Packit b099d7
WmGrabKey (
Packit b099d7
	Display		*display,
Packit b099d7
	int		keycode,
Packit b099d7
	unsigned int	modifiers,
Packit b099d7
	Window		grab_window,
Packit b099d7
	Bool		owner_events,
Packit b099d7
	int		pointer_mode,
Packit b099d7
	int		keyboard_mode 
Packit b099d7
	  )
Packit b099d7
{
Packit b099d7
    unsigned int	*pGrabMasks;
Packit b099d7
    int			i, num_masks;
Packit b099d7
Packit b099d7
    pGrabMasks = _WmGrabMasks (modifiers, &num_masks);
Packit b099d7
Packit b099d7
    for (i=0; i
Packit b099d7
    {
Packit b099d7
	XGrabKey (display, keycode, *pGrabMasks, grab_window,
Packit b099d7
	        owner_events, pointer_mode, keyboard_mode);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  WmGrabButton (display, button, modifiers, grab_window, owner_events,
Packit b099d7
 *		event_mask, pointer_mode, keyboard_mode, confine_to, cursor)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function does several grabs on a button to make sure the
Packit b099d7
 *  button is grabbed irrespective of the state of locking modifiers
Packit b099d7
 *  It is a wrapper for XGrabButton, so the parameters are all the
Packit b099d7
 *  same.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  display		- X server connection 
Packit b099d7
 *  button		- button to grab
Packit b099d7
 *  modifiers		- keymask of modifiers
Packit b099d7
 *  grab_window		- window to do grab on
Packit b099d7
 *  event_mask		- event mask in effect during grab
Packit b099d7
 *  owner_events	- does app receive events normally?
Packit b099d7
 *  pointer_mode	- pointer event processing during grab
Packit b099d7
 *  keyboard_mode	- keyboard event processing during grab
Packit b099d7
 *  confine_to		- window to confine the pointer to
Packit b099d7
 *  cursor		- cursor to be displayed during grab
Packit b099d7
 *  wmGD.pLockMaskSequence	- extra modifier masks to grab with
Packit b099d7
 *
Packit b099d7
 *  Return:
Packit b099d7
 *  -------
Packit b099d7
 *  The function is asynchronous.
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void
Packit b099d7
WmGrabButton (
Packit b099d7
	Display		*display,
Packit b099d7
	unsigned int	button,
Packit b099d7
	unsigned int	modifiers,
Packit b099d7
	Window		grab_window,
Packit b099d7
	unsigned int	event_mask,
Packit b099d7
	Bool		owner_events,
Packit b099d7
	int		pointer_mode,
Packit b099d7
	int		keyboard_mode,
Packit b099d7
	Window		confine_to,
Packit b099d7
	Cursor		cursor
Packit b099d7
	  )
Packit b099d7
{
Packit b099d7
    unsigned int	*pGrabMasks;
Packit b099d7
    int			i, num_masks;
Packit b099d7
Packit b099d7
    pGrabMasks = _WmGrabMasks (modifiers, &num_masks);
Packit b099d7
Packit b099d7
    for (i=0; i
Packit b099d7
    {
Packit b099d7
	XGrabButton (display, button, *pGrabMasks, grab_window, event_mask,
Packit b099d7
	        owner_events, pointer_mode, keyboard_mode, confine_to,
Packit b099d7
		cursor);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  WmUngrabButton (display, button, modifiers, grab_window)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function is the complement of WmGrabButton. It does several 
Packit b099d7
 *  ungrabs on a button to undo the set of grabs done to ignore
Packit b099d7
 *  the state of locking modifiers.
Packit b099d7
 *
Packit b099d7
 *  It is a wrapper for XUngrabButton, so the parameters are all the
Packit b099d7
 *  same.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  display		- X server connection 
Packit b099d7
 *  button		- button to grab
Packit b099d7
 *  modifiers		- keymask of modifiers
Packit b099d7
 *  grab_window		- window to do grab on
Packit b099d7
 *  wmGD.pLockMaskSequence	- extra modifier masks to grab with
Packit b099d7
 *
Packit b099d7
 *  Return:
Packit b099d7
 *  -------
Packit b099d7
 *  The function is asynchronous.
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void
Packit b099d7
WmUngrabButton (
Packit b099d7
	Display		*display,
Packit b099d7
	unsigned int	button,
Packit b099d7
	unsigned int	modifiers,
Packit b099d7
	Window		grab_window 
Packit b099d7
	  )
Packit b099d7
{
Packit b099d7
    unsigned int	*pGrabMasks;
Packit b099d7
    int			i, num_masks;
Packit b099d7
Packit b099d7
    pGrabMasks = _WmGrabMasks (modifiers, &num_masks);
Packit b099d7
Packit b099d7
    for (i=0; i
Packit b099d7
    {
Packit b099d7
	XUngrabButton (display, button, *pGrabMasks, grab_window);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  SetupKeyBindings (keySpecs, grabWindow, keyboardMode, context)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function sets up the event handling necessary to support user
Packit b099d7
 *  specified key bindings for window manager functions.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  keySpecs = list of key bindings for window manager functions.
Packit b099d7
 *
Packit b099d7
 *  grabWindow = window that is to be associated with the passive key grab.
Packit b099d7
 *
Packit b099d7
 *  keyboardMode = indicates keyboard mode for grab.
Packit b099d7
 *
Packit b099d7
 *  context = context of key binding to set
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *  RETURN = number of key bindings set
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
int SetupKeyBindings (KeySpec *keySpecs, Window grabWindow, int keyboardMode, long context)
Packit b099d7
{
Packit b099d7
    KeySpec *keySpec;
Packit b099d7
    int setCount = 0;
Packit b099d7
    Boolean iconContext;
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Use key grabs to get the keys that invoke window manger functions.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    iconContext = (context == F_CONTEXT_ICON);
Packit b099d7
    keySpec = keySpecs;
Packit b099d7
    while (keySpec)
Packit b099d7
    {
Packit b099d7
#ifdef OLD_CODE
Packit b099d7
	if (((keySpec->context == F_CONTEXT_ICON) && iconContext) ||
Packit b099d7
	    ((keySpec->context != F_CONTEXT_ICON) && !iconContext))
Packit b099d7
#endif
Packit b099d7
	if (((F_CONTEXT_ICON == (keySpec->context ^
Packit b099d7
				 (F_CONTEXT_ICONBOX     |
Packit b099d7
				  F_SUBCONTEXT_IB_IICON |
Packit b099d7
				  F_SUBCONTEXT_IB_WICON))) &&
Packit b099d7
             iconContext) ||
Packit b099d7
            ((F_CONTEXT_ICON != (keySpec->context ^
Packit b099d7
				 (F_CONTEXT_ICONBOX     |
Packit b099d7
				  F_SUBCONTEXT_IB_IICON |
Packit b099d7
				  F_SUBCONTEXT_IB_WICON))) &&
Packit b099d7
             !iconContext))
Packit b099d7
	{
Packit b099d7
Packit b099d7
	    WmGrabKey (DISPLAY, keySpec->keycode, keySpec->state, grabWindow,
Packit b099d7
	        False, GrabModeAsync, keyboardMode);
Packit b099d7
Packit b099d7
	    setCount++;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	keySpec = keySpec->nextKeySpec;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    return (setCount);
Packit b099d7
Packit b099d7
} /* END OF FUNCTION SetupKeyBindings */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  WmDispatchMenuEvent (event)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function detects and processes events that affect menu behavior that
Packit b099d7
 *  are NOT dispatched (processed) by the toolkit.  The events may cause the 
Packit b099d7
 *  menu to be unposted, may trigger hotspot processing, or may represent 
Packit b099d7
 *  menu accelerators.  This processing is generally done when the system 
Packit b099d7
 *  menu is posted in "sticky" mode.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  event = This is an X event that has been retrieved by XtNextEvent.
Packit b099d7
 *  wmGD.menuActive == nonNULL
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *  RETURN = If True the event should be dispatched by the toolkit,
Packit b099d7
 *      otherwise the event should not be dispatched.
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
Boolean WmDispatchMenuEvent (XButtonEvent *event)
Packit b099d7
{
Packit b099d7
    ClientData *pCD = wmGD.menuClient;
Packit b099d7
    Boolean     doXtDispatchEvent = True;
Packit b099d7
    Boolean     checkContext;
Packit b099d7
    Context     context = 0;
Packit b099d7
     /* For fixing the bug CR 5227 */
Packit b099d7
     XKeyEvent *keyEvent;
Packit b099d7
     KeySpec   *keySpecs;
Packit b099d7
     MenuButton   *menuBtnPtr;
Packit b099d7
Packit b099d7
Packit b099d7
    if (event->type == KeyPress)
Packit b099d7
    {
Packit b099d7
        if (wmGD.menuActive->accelKeySpecs)
Packit b099d7
        {
Packit b099d7
	   /*
Packit b099d7
	    * Check to see if the KeyPress is a menu accelerator
Packit b099d7
	    * (don't require context match for system menu accelerators).
Packit b099d7
	    * If so, the active menu will be unposted and the KeyPress event 
Packit b099d7
	    * will not be sent on to the toolkit.
Packit b099d7
	    */
Packit b099d7
Packit b099d7
  	    checkContext = (!pCD || (pCD->systemMenuSpec != wmGD.menuActive));
Packit b099d7
	    if (checkContext)
Packit b099d7
	    {
Packit b099d7
                if (pCD)
Packit b099d7
                {
Packit b099d7
            	    if (pCD->clientState == MINIMIZED_STATE)
Packit b099d7
            	    {
Packit b099d7
            	        context = F_CONTEXT_ICON;
Packit b099d7
            	    }
Packit b099d7
            	    else if (pCD->clientState == NORMAL_STATE)
Packit b099d7
            	    {
Packit b099d7
            	        context = F_CONTEXT_NORMAL;
Packit b099d7
            	    }
Packit b099d7
            	    else
Packit b099d7
            	    {
Packit b099d7
            	        context = F_CONTEXT_MAXIMIZE;
Packit b099d7
            	    }
Packit b099d7
                }
Packit b099d7
                else
Packit b099d7
                {
Packit b099d7
            	    context = F_CONTEXT_ROOT;
Packit b099d7
                }
Packit b099d7
	    }
Packit b099d7
	    /* Begin fixing CR 5227 */
Packit b099d7
	    keySpecs = wmGD.menuActive->accelKeySpecs;
Packit b099d7
	    keyEvent = (XKeyEvent *)event;
Packit b099d7
	    menuBtnPtr = wmGD.menuActive->menuButtons + 
Packit b099d7
	                 (wmGD.menuActive->menuButtonSize - 1);
Packit b099d7
  
Packit b099d7
	    while (keySpecs)
Packit b099d7
	      {
Packit b099d7
                if ((keyEvent->keycode == keySpecs->keycode) &&
Packit b099d7
		    ((keyEvent->state == keySpecs->state) ||
Packit b099d7
		    (NOLOCKMOD(keyEvent->state) == keySpecs->state))
Packit b099d7
                   && ((!checkContext) || (context & keySpecs->context)))
Packit b099d7
                 {
Packit b099d7
                    doXtDispatchEvent =  
Packit b099d7
                            XtIsSensitive(menuBtnPtr->buttonWidget);
Packit b099d7
                    break;
Packit b099d7
                 } 
Packit b099d7
                 keySpecs = keySpecs->nextKeySpec;
Packit b099d7
                 menuBtnPtr--;
Packit b099d7
                } 
Packit b099d7
     
Packit b099d7
	    doXtDispatchEvent = doXtDispatchEvent &&
Packit b099d7
		HandleKeyPress ((XKeyEvent *)event, 
Packit b099d7
				wmGD.menuActive->accelKeySpecs,
Packit b099d7
				checkContext, context, 
Packit b099d7
				TRUE, (ClientData *)NULL);
Packit b099d7
        }
Packit b099d7
Packit b099d7
        if (wmGD.menuActive && wmGD.menuUnpostKeySpec)
Packit b099d7
        {
Packit b099d7
	    if ((wmGD.menuUnpostKeySpec->keycode == event->button) &&
Packit b099d7
		((wmGD.menuUnpostKeySpec->state == event->state) ||
Packit b099d7
		 (wmGD.menuUnpostKeySpec->state == NOLOCKMOD(event->state))))
Packit b099d7
	    {
Packit b099d7
	        /*
Packit b099d7
	         * This is an alternate key for unposting a menu from the
Packit b099d7
	         * keyboard (in addition to [ESC]).
Packit b099d7
	         */
Packit b099d7
Packit b099d7
	        UnpostMenu (wmGD.menuActive);
Packit b099d7
	        doXtDispatchEvent = False;
Packit b099d7
	    }
Packit b099d7
        }
Packit b099d7
#ifdef ROOT_ICON_MENU
Packit b099d7
        if (wmGD.menuActive && wmGD.F_NextKeySpec)
Packit b099d7
        {
Packit b099d7
            if (((wmGD.F_NextKeySpec->state == event->state) ||
Packit b099d7
                 (wmGD.F_NextKeySpec->state == NOLOCKMOD(event->state))) &&
Packit b099d7
                (wmGD.F_NextKeySpec->keycode == event->button))
Packit b099d7
            {
Packit b099d7
                /*
Packit b099d7
                 * This is a key spec to traverse to the next window
Packit b099d7
                 * via the keyboard.
Packit b099d7
                 */
Packit b099d7
		
Packit b099d7
                UnpostMenu (wmGD.menuActive);
Packit b099d7
                doXtDispatchEvent = False;
Packit b099d7
            }
Packit b099d7
        }
Packit b099d7
        if (wmGD.menuActive && wmGD.F_PrevKeySpec)
Packit b099d7
        {
Packit b099d7
            if (((wmGD.F_PrevKeySpec->state == event->state) ||
Packit b099d7
                 (wmGD.F_PrevKeySpec->state == NOLOCKMOD(event->state))) &&
Packit b099d7
                (wmGD.F_PrevKeySpec->keycode == event->button))
Packit b099d7
            {
Packit b099d7
                /*
Packit b099d7
                 * This is a key spec to traverse to the previous window
Packit b099d7
                 * via the keyboard.
Packit b099d7
                 */
Packit b099d7
		
Packit b099d7
                UnpostMenu (wmGD.menuActive);
Packit b099d7
                doXtDispatchEvent = False;
Packit b099d7
            }
Packit b099d7
        }
Packit b099d7
#endif /*  ROOT_ICON_MENU */
Packit b099d7
    }
Packit b099d7
Packit b099d7
    else if (wmGD.checkHotspot &&
Packit b099d7
	     ((event->type == ButtonPress) || 
Packit b099d7
	      (event->type == ButtonRelease)) &&
Packit b099d7
	     (event->x_root >= wmGD.hotspotRectangle.x) &&
Packit b099d7
	     (event->y_root >= wmGD.hotspotRectangle.y) &&
Packit b099d7
	     (event->x_root < (wmGD.hotspotRectangle.x + 
Packit b099d7
	                       (short) wmGD.hotspotRectangle.width)) &&
Packit b099d7
	     (event->y_root < (wmGD.hotspotRectangle.y + 
Packit b099d7
	                       (short) wmGD.hotspotRectangle.height))&&
Packit b099d7
#ifdef WSM
Packit b099d7
	     (pCD || 
Packit b099d7
	      (wmGD.rootButtonClick && wmGD.clickData.clickPending)))
Packit b099d7
#else /* WSM */
Packit b099d7
	     pCD)
Packit b099d7
#endif /* WSM */
Packit b099d7
    {
Packit b099d7
	/*   ^^^
Packit b099d7
	 * Added check for NULL pCD in the above condition.
Packit b099d7
	 * We should never get here with a NULL pCD, but, 
Packit b099d7
	 * sometimes our UnmapCallback for a menu does not
Packit b099d7
	 * get called, so..., we get to this point because
Packit b099d7
	 * wmGD.menuActive is not cleared, but, wmGD.menuClient 
Packit b099d7
	 * is set to NULL when we unmanage the client window.
Packit b099d7
	 */
Packit b099d7
	
Packit b099d7
	/*
Packit b099d7
	 * The event triggers hotspot processing for the system menu button
Packit b099d7
	 * or an icon.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
	if (event->type == ButtonRelease)
Packit b099d7
	{
Packit b099d7
#ifdef WSM
Packit b099d7
          if (pCD)
Packit b099d7
	  {
Packit b099d7
#endif /* WSM */
Packit b099d7
	    /*
Packit b099d7
	     * The system menu is posted from a system menu button or an
Packit b099d7
	     * icon.  By doing a button release over the system menu button
Packit b099d7
	     * or icon the system menu that is posted is put into keyboard
Packit b099d7
	     * traversal mode.
Packit b099d7
	     */
Packit b099d7
Packit b099d7
	    ProcessClickBRelease (event, pCD, wmGD.clickData.context,
Packit b099d7
		wmGD.clickData.subContext);
Packit b099d7
Packit b099d7
	    if (wmGD.clickData.context == F_SUBCONTEXT_W_SYSTEM)
Packit b099d7
	    {
Packit b099d7
		PopGadgetOut (pCD, FRAME_SYSTEM);
Packit b099d7
	    }
Packit b099d7
#ifdef MOTIF_ONE_DOT_ONE
Packit b099d7
	    TraversalOn (pCD->systemMenuSpec);
Packit b099d7
	    doXtDispatchEvent = False;
Packit b099d7
#else
Packit b099d7
 	    _XmGetMenuState(XtParent(pCD->systemMenuSpec->menuWidget))
Packit b099d7
		->MS_LastManagedMenuTime = ((XButtonEvent *)event)->time;
Packit b099d7
	    doXtDispatchEvent = True;
Packit b099d7
#endif
Packit b099d7
#ifdef WSM
Packit b099d7
          }
Packit b099d7
	  else if ((!wmGD.clickData.pCD) && 
Packit b099d7
	      (((XButtonEvent *)event)->button == wmGD.clickData.button) &&
Packit b099d7
	      ((((XButtonEvent *)event)->state == 
Packit b099d7
				wmGD.clickData.releaseState) ||
Packit b099d7
	       (NOLOCKMOD(((XButtonEvent *)event)->state) == 
Packit b099d7
				wmGD.clickData.releaseState)))
Packit b099d7
	  {
Packit b099d7
	      /*
Packit b099d7
	       * This is a button release over the root. Check for
Packit b099d7
	       * root menu click and keep the menu up in a sticky
Packit b099d7
	       * fashion.
Packit b099d7
	       */
Packit b099d7
		Time timeDiff;
Packit b099d7
Packit b099d7
		/* 
Packit b099d7
		 * Check click time 
Packit b099d7
		 */
Packit b099d7
		 if (((XButtonEvent *)event)->time > wmGD.clickData.time)
Packit b099d7
		 {
Packit b099d7
		   timeDiff = 
Packit b099d7
		     ((XButtonEvent *)event)->time - wmGD.clickData.time;
Packit b099d7
		 }
Packit b099d7
		 else
Packit b099d7
		 {
Packit b099d7
		   timeDiff = 
Packit b099d7
		     ~wmGD.clickData.time + ((XButtonEvent *)event)->time + 1;
Packit b099d7
		 }
Packit b099d7
Packit b099d7
		 if (timeDiff < wmGD.doubleClickTime)
Packit b099d7
		 {
Packit b099d7
#ifdef MOTIF_ONE_DOT_ONE
Packit b099d7
		   TraversalOn (wmGD.menuActive);
Packit b099d7
		   doXtDispatchEvent = False;
Packit b099d7
#else
Packit b099d7
		   _XmGetMenuState (XtParent(wmGD.menuActive->menuWidget))
Packit b099d7
		       ->MS_LastManagedMenuTime =
Packit b099d7
			   ((XButtonEvent *)event)->time;
Packit b099d7
		   doXtDispatchEvent = True;
Packit b099d7
#endif
Packit b099d7
		 }
Packit b099d7
	    wmGD.clickData.clickPending = False;
Packit b099d7
	    }
Packit b099d7
#endif /* WSM */
Packit b099d7
	}
Packit b099d7
	else
Packit b099d7
	{
Packit b099d7
	    /*
Packit b099d7
	     * A button press over a system menu button or an icon when the
Packit b099d7
	     * system menu is posted indicates that a double-click action is
Packit b099d7
	     * to be done if appropriate and the menu is to be taken
Packit b099d7
	     * out of traversal mode (done by the menu widget).
Packit b099d7
	     */
Packit b099d7
Packit b099d7
	    ProcessClickBPress (event, pCD, wmGD.clickData.context,
Packit b099d7
				wmGD.clickData.subContext);
Packit b099d7
Packit b099d7
	    if (wmGD.clickData.subContext == F_SUBCONTEXT_W_SYSTEM)
Packit b099d7
	    {
Packit b099d7
		PushGadgetIn (pCD, FRAME_SYSTEM);
Packit b099d7
	    }
Packit b099d7
Packit b099d7
	    if (wmGD.clickData.doubleClickContext == F_SUBCONTEXT_W_SYSTEM)
Packit b099d7
	    {
Packit b099d7
		if (wmGD.systemButtonClick2 &&
Packit b099d7
		    (pCD->clientFunctions & MWM_FUNC_CLOSE))
Packit b099d7
		{
Packit b099d7
		    /*
Packit b099d7
		     * Close the client window.  Cancel other system menu
Packit b099d7
		     * button actions.
Packit b099d7
		     */
Packit b099d7
Packit b099d7
		    UnpostMenu (pCD->systemMenuSpec);
Packit b099d7
		    F_Kill (NULL, pCD, (XEvent *) event);
Packit b099d7
		    doXtDispatchEvent = False;
Packit b099d7
		}
Packit b099d7
	    }
Packit b099d7
	    else
Packit b099d7
	    if (wmGD.clickData.doubleClickContext == F_SUBCONTEXT_I_ALL)
Packit b099d7
	    {
Packit b099d7
		/*
Packit b099d7
		 * Normalize the icon.
Packit b099d7
		 */
Packit b099d7
		int newState;
Packit b099d7
Packit b099d7
		UnpostMenu (pCD->systemMenuSpec);
Packit b099d7
		if (pCD->maxConfig)
Packit b099d7
		{
Packit b099d7
		    newState = MAXIMIZED_STATE;
Packit b099d7
		}
Packit b099d7
		else
Packit b099d7
		{
Packit b099d7
		    newState = NORMAL_STATE;
Packit b099d7
		}
Packit b099d7
Packit b099d7
		SetClientState (pCD, newState, event->time);
Packit b099d7
		wmGD.clickData.clickPending = False;
Packit b099d7
		wmGD.clickData.doubleClickPending = False;
Packit b099d7
		doXtDispatchEvent = False;
Packit b099d7
	    }
Packit b099d7
	    else
Packit b099d7
	    if ((wmGD.clickData.doubleClickContext == F_SUBCONTEXT_IB_IICON)||
Packit b099d7
		(wmGD.clickData.doubleClickContext == F_SUBCONTEXT_IB_WICON))
Packit b099d7
            {
Packit b099d7
                /*
Packit b099d7
                 * Raise the Window and Normalize
Packit b099d7
                 */
Packit b099d7
		
Packit b099d7
                UnpostMenu (pCD->systemMenuSpec);
Packit b099d7
		F_Restore_And_Raise ((String)NULL, pCD, (XEvent *)NULL);
Packit b099d7
/*		F_Normalize_And_Raise ((String)NULL, pCD, (XEvent *)NULL);
Packit b099d7
*/                doXtDispatchEvent = False;
Packit b099d7
            }
Packit b099d7
Packit b099d7
	    /*
Packit b099d7
	     * Else no special button press processing; have the toolkit
Packit b099d7
	     * dispatch the event to the menu widgets.
Packit b099d7
	     */
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    return (doXtDispatchEvent);
Packit b099d7
Packit b099d7
Packit b099d7
} /* END OF FUNCTION WmDispatchMenuEvent */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  WmDispatchWsEvent (event)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function detects and dispatches events that are reported to the root
Packit b099d7
 *  (workspace) window and that are not widget-related (i.e. they would not be
Packit b099d7
 *  dispatched by the Xtk intrinsics).
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  event = This is an X event that has been retrieved by XtNextEvent.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *  RETURN = If True the event should be dispatched by the toolkit,
Packit b099d7
 *      otherwise the event should not be dispatched.
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
Boolean WmDispatchWsEvent (XEvent *event)
Packit b099d7
{
Packit b099d7
    ClientData *pCD;
Packit b099d7
    Boolean dispatchEvent = False;
Packit b099d7
    WmScreenData *pSD;
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Detect and dispatch non-widget events that have been reported to
Packit b099d7
     * the root window.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    switch (event->type)
Packit b099d7
    {
Packit b099d7
	case KeyPress:
Packit b099d7
	{
Packit b099d7
	    /*
Packit b099d7
	     * The key press is to initiate some window management
Packit b099d7
	     * function (e.g., shuffle the client windows).
Packit b099d7
	     */
Packit b099d7
Packit b099d7
	    dispatchEvent = HandleWsKeyPress ((XKeyEvent *)event);
Packit b099d7
	    break;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	case ButtonPress:
Packit b099d7
	{
Packit b099d7
	    /*
Packit b099d7
	     * The button press is to initiate some window management
Packit b099d7
	     * function (e.g., pop up the desktop menu).
Packit b099d7
	     */
Packit b099d7
Packit b099d7
	    if (wmGD.menuActive)
Packit b099d7
	    {
Packit b099d7
		dispatchEvent = True; /* have the toolkit dispatch the event */
Packit b099d7
	    }
Packit b099d7
	    else
Packit b099d7
	    {
Packit b099d7
		HandleWsButtonPress ((XButtonEvent *)event);
Packit b099d7
	    }
Packit b099d7
	    break;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	case ButtonRelease:
Packit b099d7
	{
Packit b099d7
	    /*
Packit b099d7
	     * The button release may do some window management
Packit b099d7
	     * function.
Packit b099d7
	     */
Packit b099d7
Packit b099d7
	    if (wmGD.menuActive)
Packit b099d7
	    {
Packit b099d7
		dispatchEvent = True; /* have the toolkit dispatch the event */
Packit b099d7
	    }
Packit b099d7
	    else
Packit b099d7
	    {
Packit b099d7
		HandleWsButtonRelease ((XButtonEvent *)event);
Packit b099d7
	    }
Packit b099d7
	    break;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	case UnmapNotify:
Packit b099d7
	{
Packit b099d7
	  /* BEGIN CR 5183 */
Packit b099d7
	  if ( (!XFindContext (DISPLAY, event->xunmap.window,
Packit b099d7
			       wmGD.windowContextType,
Packit b099d7
			       (XPointer *)&pCD)
Packit b099d7
		)
Packit b099d7
	      && (((XUnmapEvent *)event)->window == pCD->client)
Packit b099d7
	      )
Packit b099d7
	  /* END CR 5183 */
Packit b099d7
	    {
Packit b099d7
		/*
Packit b099d7
		 * This is a synthetic UnmapNotity used to withdraw a client
Packit b099d7
		 * window form window manager control.
Packit b099d7
		 */
Packit b099d7
Packit b099d7
		UnManageWindow (pCD);
Packit b099d7
	    }
Packit b099d7
	    break;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	case EnterNotify:
Packit b099d7
	{
Packit b099d7
	    HandleWsEnterNotify ((XEnterWindowEvent *)event);
Packit b099d7
	    break;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	case LeaveNotify:
Packit b099d7
	{
Packit b099d7
	    HandleWsLeaveNotify ((XLeaveWindowEvent *)event);
Packit b099d7
	    break;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	case ConfigureRequest:
Packit b099d7
	{
Packit b099d7
	    HandleWsConfigureRequest ((XConfigureRequestEvent *)event);
Packit b099d7
	    break;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	case MapRequest:
Packit b099d7
	{
Packit b099d7
	    /*
Packit b099d7
	     * Determine if the window is already being managed:
Packit b099d7
	     */
Packit b099d7
Packit b099d7
	    if ((XFindContext (DISPLAY, event->xmaprequest.window,
Packit b099d7
		    wmGD.windowContextType, (caddr_t *)&pCD)) &&
Packit b099d7
		(pSD = GetScreenForWindow (event->xmaprequest.window)))
Packit b099d7
	    {
Packit b099d7
	        /*
Packit b099d7
                 * The window is not yet managed and it's parented to a 
Packit b099d7
		 * screen/root window that we manage. Start to manage the
Packit b099d7
		 * new window.  Management details are dependent on the
Packit b099d7
		 * type of the window.  For a typical top-level application
Packit b099d7
		 * window reparent the window to a window frame, add it to
Packit b099d7
		 * the wm saveset, ...
Packit b099d7
                 */
Packit b099d7
Packit b099d7
                ManageWindow (pSD, event->xmaprequest.window, MANAGEW_NORMAL);
Packit b099d7
	    }
Packit b099d7
	    /* else ...
Packit b099d7
	     * The context information on the window WAS found.
Packit b099d7
	     * The window is already managed by the window manager
Packit b099d7
	     * so this is redundant request to have the client
Packit b099d7
	     * window managed.
Packit b099d7
	     */
Packit b099d7
Packit b099d7
	    break;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	case FocusIn:
Packit b099d7
	{
Packit b099d7
	    HandleWsFocusIn ((XFocusInEvent *)event);
Packit b099d7
	    break;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	case FocusOut:
Packit b099d7
	{
Packit b099d7
	    break;
Packit b099d7
	}
Packit b099d7
Packit b099d7
    } /* end of event.type switch */
Packit b099d7
Packit b099d7
Packit b099d7
    return (dispatchEvent);
Packit b099d7
Packit b099d7
} /* END OF FUNCTION WmDispatchWsEvent */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  HandleWsKeyPress (keyEvent)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function processes KeyPress events that are reported to the root
Packit b099d7
 *  window.  These events are generally associated with accelerators.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  keyEvent = pointer to a key press event on the root window.
Packit b099d7
 *
Packit b099d7
 *  Output:
Packit b099d7
 *  ------
Packit b099d7
 *  RETURN = True is the event is to be dispatched by XtDispatch.
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
Boolean HandleWsKeyPress (XKeyEvent *keyEvent)
Packit b099d7
{
Packit b099d7
    Boolean      dispatchEvent = False;
Packit b099d7
    Boolean      checkKeyEvent = True;
Packit b099d7
    unsigned int n;
Packit b099d7
    Context      context;
Packit b099d7
Packit b099d7
    if (wmGD.menuActive)
Packit b099d7
    {
Packit b099d7
	/*
Packit b099d7
	 *  The active menu accelerators have been checked and keyEvent was
Packit b099d7
	 *  not one of them.  We will check for pass keys mode and then 
Packit b099d7
	 *  have the toolkit dispatch the event, without searching any other 
Packit b099d7
	 *  key or accelerator specification list.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
	dispatchEvent = True;
Packit b099d7
	checkKeyEvent = False;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * If pass keys is active then only check for getting out of the
Packit b099d7
     * pass keys mode.  Unfreeze the keyboard and replay the key if
Packit b099d7
     * pass keys is active.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (wmGD.passKeysActive)
Packit b099d7
    {
Packit b099d7
	if (wmGD.passKeysKeySpec &&
Packit b099d7
	    ((wmGD.passKeysKeySpec->state == keyEvent->state) ||
Packit b099d7
	     (wmGD.passKeysKeySpec->state == NOLOCKMOD(keyEvent->state))) &&
Packit b099d7
	    (wmGD.passKeysKeySpec->keycode == keyEvent->keycode))
Packit b099d7
	{
Packit b099d7
	    /*
Packit b099d7
	     * Get out of the pass keys mode.
Packit b099d7
	     */
Packit b099d7
Packit b099d7
	    F_Pass_Key (NULL, (ClientData *) NULL, (XEvent *) NULL);
Packit b099d7
	    XAllowEvents (DISPLAY, AsyncKeyboard, CurrentTime);
Packit b099d7
	}
Packit b099d7
	else
Packit b099d7
	{
Packit b099d7
	    XAllowEvents (DISPLAY, ReplayKeyboard, CurrentTime);
Packit b099d7
	}
Packit b099d7
	checkKeyEvent = False;
Packit b099d7
    }
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Search through the key specification list and the menu 
Packit b099d7
     * accelerator lists until these lists are exhausted or
Packit b099d7
     * the event is handled.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (checkKeyEvent)
Packit b099d7
    {
Packit b099d7
        if (wmGD.keyboardFocus)
Packit b099d7
        {
Packit b099d7
	    if (wmGD.keyboardFocus->clientState == MINIMIZED_STATE)
Packit b099d7
	    {
Packit b099d7
	        context = F_CONTEXT_ICON;
Packit b099d7
	    }
Packit b099d7
	    else if (wmGD.keyboardFocus->clientState == NORMAL_STATE)
Packit b099d7
	    {
Packit b099d7
	        context = F_CONTEXT_NORMAL;
Packit b099d7
	    }
Packit b099d7
	    else
Packit b099d7
	    {
Packit b099d7
	        context = F_CONTEXT_MAXIMIZE;
Packit b099d7
	    }
Packit b099d7
        }
Packit b099d7
        else
Packit b099d7
        {
Packit b099d7
	    context = F_CONTEXT_ROOT;
Packit b099d7
        }
Packit b099d7
Packit b099d7
        if (HandleKeyPress (keyEvent, ACTIVE_PSD->keySpecs, 
Packit b099d7
	                    TRUE, context, FALSE, (ClientData *)NULL) &&
Packit b099d7
	    ACTIVE_PSD->acceleratorMenuCount)
Packit b099d7
	{
Packit b099d7
	    for (n = 0; ((keyEvent->keycode != 0) &&
Packit b099d7
			 (n < ACTIVE_PSD->acceleratorMenuCount)); n++)
Packit b099d7
	    {
Packit b099d7
	        if (!HandleKeyPress (keyEvent,
Packit b099d7
		     ACTIVE_PSD->acceleratorMenuSpecs[n]->accelKeySpecs, 
Packit b099d7
				 TRUE, context, TRUE,(ClientData *)NULL))
Packit b099d7
	        {
Packit b099d7
		    break;
Packit b099d7
		}
Packit b099d7
	    }
Packit b099d7
        }
Packit b099d7
Packit b099d7
	/*
Packit b099d7
	 * Fix for CR 3117 - Do the XAllowEvents after calling HandleKeyPress so that
Packit b099d7
	 *                   keys meant for an application can be sent to it.
Packit b099d7
	 */
Packit b099d7
	XAllowEvents (DISPLAY, AsyncKeyboard, CurrentTime);
Packit b099d7
	/*
Packit b099d7
	 * End Fix for CR 3117
Packit b099d7
	 */
Packit b099d7
    }
Packit b099d7
Packit b099d7
    return (dispatchEvent);
Packit b099d7
Packit b099d7
} /* END OF FUNCTION HandleWsKeyPress */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  HandleKeyPress (keyEvent, keySpecs, checkContext, context, onlyFirst, pCD)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function identifies window manager functions that are triggered by
Packit b099d7
 *  a KeyPress event.  The window manager functions are done if appropriate.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  keyEvent = pointer to a key press event on the root window
Packit b099d7
 *  keySpecs = pointer to a key specification list to search
Packit b099d7
 *  checkContext = TRUE iff the context must match the keySpec context.
Packit b099d7
 *  context = context to match keySpec context.
Packit b099d7
 *  onlyFirst = TRUE iff key processing should stop with the first match.
Packit b099d7
 *
Packit b099d7
 *  Output:
Packit b099d7
 *  ------
Packit b099d7
 *  RETURN = False if key binding processing should be terminated; True if
Packit b099d7
 *	key binding processing can continue
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
Boolean HandleKeyPress (XKeyEvent *keyEvent, 
Packit b099d7
			KeySpec *keySpecs, 
Packit b099d7
			Boolean checkContext, 
Packit b099d7
			Context context, 
Packit b099d7
			Boolean onlyFirst, 
Packit b099d7
			ClientData *pCD)
Packit b099d7
{
Packit b099d7
  Boolean     processKey = True;
Packit b099d7
  ClientData *functionClient;
Packit b099d7
  Boolean   haveRootBinding = False;
Packit b099d7
  Boolean   haveWindowBinding = False;
Packit b099d7
Packit b099d7
  /*
Packit b099d7
   * Search for matching key specification.
Packit b099d7
   */
Packit b099d7
Packit b099d7
  while (processKey && keySpecs)
Packit b099d7
    {
Packit b099d7
      if (((keyEvent->state == keySpecs->state) ||
Packit b099d7
           (NOLOCKMOD(keyEvent->state) == keySpecs->state)) &&
Packit b099d7
	  (keyEvent->keycode == keySpecs->keycode))
Packit b099d7
	{
Packit b099d7
	  if ((!checkContext) || (context & keySpecs->context))
Packit b099d7
	    {
Packit b099d7
	      /*
Packit b099d7
	       * A matching key binding has been found.
Packit b099d7
	       * Determine the client to which the key binding function is to
Packit b099d7
	       *   apply.
Packit b099d7
	       * Unpost any active menu and specify that no futher key binding 
Packit b099d7
	       *   processing should be done.
Packit b099d7
	       * Do the function associated with the matching key binding.
Packit b099d7
	       * Stop if onlyFirst == TRUE
Packit b099d7
	       */
Packit b099d7
Packit b099d7
	      if (pCD)
Packit b099d7
		{
Packit b099d7
		  functionClient = pCD;
Packit b099d7
		}
Packit b099d7
	      else
Packit b099d7
		{
Packit b099d7
		  functionClient = wmGD.keyboardFocus;
Packit b099d7
		}
Packit b099d7
Packit b099d7
	      if (wmGD.menuActive)
Packit b099d7
		{
Packit b099d7
		  functionClient = wmGD.menuClient;  /* might not have focus! */
Packit b099d7
		  UnpostMenu (wmGD.menuActive);
Packit b099d7
		  processKey = False;
Packit b099d7
		}
Packit b099d7
	      else if (onlyFirst)
Packit b099d7
		{
Packit b099d7
		  processKey = False;
Packit b099d7
		}
Packit b099d7
Packit b099d7
	      if ((keySpecs->wmFunction == F_Menu) ||
Packit b099d7
#if ((!defined(WSM)) || defined(MWM_QATS_PROTOCOL))
Packit b099d7
		  (keySpecs->wmFunction == F_Post_RMenu) ||
Packit b099d7
#endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */
Packit b099d7
		  (keySpecs->wmFunction == F_Post_SMenu))
Packit b099d7
		{
Packit b099d7
		  wmGD.menuUnpostKeySpec = keySpecs;  /* menu unpost key spec */
Packit b099d7
		}
Packit b099d7
	      else if (keySpecs->wmFunction == F_Pass_Key)
Packit b099d7
		{
Packit b099d7
		  wmGD.passKeysKeySpec = keySpecs;
Packit b099d7
		}
Packit b099d7
#ifdef ROOT_ICON_MENU
Packit b099d7
              else if (keySpecs->wmFunction == F_Next_Key)
Packit b099d7
		{
Packit b099d7
                  wmGD.F_NextKeySpec = keySpecs;
Packit b099d7
		}
Packit b099d7
              else if (keySpecs->wmFunction == F_Prev_Key)
Packit b099d7
		{
Packit b099d7
                  wmGD.F_PrevKeySpec = keySpecs;
Packit b099d7
		}
Packit b099d7
#endif /* ROOT_ICON_MENU */
Packit b099d7
	      if (!(keySpecs->wmFunction (keySpecs->wmFuncArgs,
Packit b099d7
					  functionClient, keyEvent)))
Packit b099d7
		{
Packit b099d7
		  /*
Packit b099d7
		   * The window manager function return indicates that further
Packit b099d7
		   * key binding processing should not be done.
Packit b099d7
		   */
Packit b099d7
Packit b099d7
		  processKey = False;
Packit b099d7
		}
Packit b099d7
	      /*
Packit b099d7
	       * Note that for key bindings, frame, title, border, and app contexts
Packit b099d7
	       * are equivalent to the window context. This is NOT the same as for
Packit b099d7
	       * button bindings.
Packit b099d7
	       */
Packit b099d7
	      if ((context & (F_CONTEXT_WINDOW)))
Packit b099d7
		haveWindowBinding = True;
Packit b099d7
	    }
Packit b099d7
	  /* Fix for 3117 -- If the keypress looks as if it had been intended
Packit b099d7
	   *                 for the application, send it back.
Packit b099d7
	   */
Packit b099d7
	  
Packit b099d7
	  else if ((context & (F_CONTEXT_WINDOW)) &&
Packit b099d7
		   (keySpecs->context & F_CONTEXT_ROOT))
Packit b099d7
	    {
Packit b099d7
	      haveRootBinding = True;
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
	keySpecs = keySpecs->nextKeySpec;
Packit b099d7
Packit b099d7
      }
Packit b099d7
Packit b099d7
    if (haveRootBinding && (!haveWindowBinding) )
Packit b099d7
      {
Packit b099d7
	XAllowEvents (DISPLAY, ReplayKeyboard, CurrentTime);
Packit b099d7
      }
Packit b099d7
Packit b099d7
    return (processKey);
Packit b099d7
Packit b099d7
Packit b099d7
} /* END OF FUNCTION HandleKeyPress */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  HandleWsButtonPress (buttonEvent)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function identifies button events that are associated with window
Packit b099d7
 *  manager functions.  Window manager functions are done if appropriate.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  buttonEvent = pointer to a button press event on the root window
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void HandleWsButtonPress (XButtonEvent *buttonEvent)
Packit b099d7
{
Packit b099d7
    ClientData *pCD;
Packit b099d7
    Context context;
Packit b099d7
    int partContext;
Packit b099d7
    Context subContext;
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Determine if the top-level window that contains the pointer is a
Packit b099d7
     * client managed by the window manager (there may be no window under
Packit b099d7
     * the pointer or it may be an "override-redirect" window).
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if ((buttonEvent->subwindow == None) ||
Packit b099d7
	(XFindContext (DISPLAY, buttonEvent->subwindow, wmGD.windowContextType,
Packit b099d7
	     (caddr_t *)&pCD)))
Packit b099d7
    {
Packit b099d7
	/* no managed window under the pointer */
Packit b099d7
	pCD = NULL;
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Look through the window manager function button binding list for
Packit b099d7
     * matches with the event:
Packit b099d7
     */
Packit b099d7
Packit b099d7
    IdentifyEventContext (buttonEvent, pCD, &context, &partContext);
Packit b099d7
    subContext = (1L << partContext);
Packit b099d7
Packit b099d7
    ProcessClickBPress (buttonEvent, pCD, context, subContext);
Packit b099d7
Packit b099d7
    if (CheckForButtonAction (buttonEvent, context, subContext, pCD) && pCD)
Packit b099d7
    {
Packit b099d7
	/*
Packit b099d7
	 * Button bindings have been processed, now check for bindings that
Packit b099d7
	 * are associated with the built-in semantics of the window frame
Packit b099d7
	 * decorations.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
	CheckButtonPressBuiltin (buttonEvent, context, subContext, partContext,
Packit b099d7
	    pCD);
Packit b099d7
    }
Packit b099d7
    /*
Packit b099d7
     * Else skip built-in processing due to execution of a function that
Packit b099d7
     * does on-going event processing or that has changed the client state
Packit b099d7
     * (e.g., f.move or f.minimize).
Packit b099d7
     */
Packit b099d7
Packit b099d7
Packit b099d7
} /* END OF FUNCTION HandleWsButtonPress */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  HandleWsButtonRelease (buttonEvent)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function identifies button release events that are associated with
Packit b099d7
 *  window manager functions.  Window manager functions are done if
Packit b099d7
 *  appropriate.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  buttonEvent = pointer to a button release event
Packit b099d7
 * 
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void HandleWsButtonRelease (XButtonEvent *buttonEvent)
Packit b099d7
{
Packit b099d7
    ClientData *pCD;
Packit b099d7
    Context context;
Packit b099d7
    int  partContext;
Packit b099d7
    Context subContext;
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Determine if the top-level window that contains the pointer is a
Packit b099d7
     * client managed by the window manager (there may be no window under
Packit b099d7
     * the pointer or it may be an "override-redirect" window).
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if ((buttonEvent->subwindow == None) ||
Packit b099d7
	(XFindContext (DISPLAY, buttonEvent->subwindow, wmGD.windowContextType,
Packit b099d7
	     (caddr_t *)&pCD)))
Packit b099d7
    {
Packit b099d7
	/* no managed window under the pointer */
Packit b099d7
	pCD = NULL;
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Look for a builtin function that may be done by this event.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    IdentifyEventContext (buttonEvent, pCD, &context, &partContext);
Packit b099d7
    subContext = (1L << partContext);
Packit b099d7
Packit b099d7
    ProcessClickBRelease (buttonEvent, pCD, context, subContext);
Packit b099d7
Packit b099d7
    if (CheckForButtonAction (buttonEvent, context, subContext, pCD) && pCD)
Packit b099d7
    {
Packit b099d7
	/*
Packit b099d7
	 * Button bindings have been processed, now check for bindings that
Packit b099d7
	 * are associated with the built-in semantics of the window frame
Packit b099d7
	 * decorations.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
	CheckButtonReleaseBuiltin (buttonEvent, context, subContext, pCD);
Packit b099d7
    }
Packit b099d7
    /*
Packit b099d7
     * Else skip built-in processing due to execution of a function that
Packit b099d7
     * does on-going event processing or that has changed the client state
Packit b099d7
     * (e.g., f.move or f.minimize).
Packit b099d7
     */
Packit b099d7
Packit b099d7
Packit b099d7
} /* END OF FUNCTION HandleWsButtonRelease */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  CheckForButtonAction (buttonEvent, context, subContext, pCD)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function checks to see if a button event is to do a button binding
Packit b099d7
 *  action.  The action is done if specified.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  buttonEvent = a button event handled by the window manager
Packit b099d7
 *
Packit b099d7
 *  context = button event context (root, icon, window)
Packit b099d7
 *
Packit b099d7
 *  subContext = button event subContext (title, system button, etc.)
Packit b099d7
 *
Packit b099d7
 *  pCD = a pointer to client data that is associated with the button event
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *  RETURN = If True then further button binding processing can be done;
Packit b099d7
 *      if false then a state change function, menu function, or
Packit b099d7
 *      configuration function is ongoing and further button binding
Packit b099d7
 *      processing should not be done.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
Boolean CheckForButtonAction (XButtonEvent *buttonEvent, Context context, Context subContext, ClientData *pCD)
Packit b099d7
{
Packit b099d7
    ButtonSpec *buttonSpec;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Look through the window manager function button binding list for
Packit b099d7
     * matches with the event:
Packit b099d7
     */
Packit b099d7
Packit b099d7
    buttonSpec = ACTIVE_PSD->buttonSpecs;
Packit b099d7
    while (buttonSpec)
Packit b099d7
    {
Packit b099d7
	if ((buttonEvent->button == buttonSpec->button) &&
Packit b099d7
	    ((buttonEvent->state == buttonSpec->state) ||
Packit b099d7
	     (NOLOCKMOD(buttonEvent->state) == buttonSpec->state)))
Packit b099d7
	{
Packit b099d7
	    /*
Packit b099d7
	     * See if the event context matches the binding context.
Packit b099d7
	     */
Packit b099d7
Packit b099d7
	    if ((buttonEvent->type == buttonSpec->eventType) &&
Packit b099d7
	        (context & buttonSpec->context) &&
Packit b099d7
		(subContext & buttonSpec->subContext))
Packit b099d7
	    {
Packit b099d7
Packit b099d7
		/*
Packit b099d7
		 * For click type bindings check for a match between the
Packit b099d7
		 * event context and the click / double-click context.
Packit b099d7
		 */
Packit b099d7
Packit b099d7
	        if (buttonEvent->type == ButtonRelease)
Packit b099d7
	        {
Packit b099d7
		    /*
Packit b099d7
		     * Clicks occur on button releases.  A button release
Packit b099d7
		     * binding is always treated as a click binding.
Packit b099d7
		     */
Packit b099d7
Packit b099d7
		    if ((buttonSpec->subContext | wmGD.clickData.clickContext)
Packit b099d7
			 != buttonSpec->subContext)
Packit b099d7
		    {
Packit b099d7
		        /* click binding and event contexts do not match */
Packit b099d7
			buttonSpec = buttonSpec->nextButtonSpec;
Packit b099d7
		        continue;
Packit b099d7
		    }
Packit b099d7
		    /* else there is a click match */
Packit b099d7
	        }
Packit b099d7
		else if (buttonSpec->click && (buttonEvent->type==ButtonPress))
Packit b099d7
		{
Packit b099d7
		    /*
Packit b099d7
		     * Double-clicks occur on button presses.
Packit b099d7
		     */
Packit b099d7
Packit b099d7
		    if ((buttonSpec->subContext |
Packit b099d7
					wmGD.clickData.doubleClickContext)
Packit b099d7
			!= buttonSpec->subContext)
Packit b099d7
		    {
Packit b099d7
			/* click binding and event contexts do not match */
Packit b099d7
			buttonSpec = buttonSpec->nextButtonSpec;
Packit b099d7
			continue;
Packit b099d7
		    }
Packit b099d7
		    else
Packit b099d7
		    {
Packit b099d7
		        /*
Packit b099d7
			 * The is a double-click match.  Don't do any click
Packit b099d7
			 * or double-click matches for the following button
Packit b099d7
			 * press and release.
Packit b099d7
			 */
Packit b099d7
Packit b099d7
			wmGD.clickData.clickPending = False;
Packit b099d7
			wmGD.clickData.doubleClickPending = False;
Packit b099d7
		    }
Packit b099d7
		}
Packit b099d7
Packit b099d7
	        if (!(buttonSpec->wmFunction (buttonSpec->wmFuncArgs, pCD,
Packit b099d7
					      buttonEvent)))
Packit b099d7
		{
Packit b099d7
		    /*
Packit b099d7
		     * The window manager function return indicates that
Packit b099d7
		     * further button binding processing should not be done.
Packit b099d7
		     */
Packit b099d7
Packit b099d7
		    return (False);
Packit b099d7
		}
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
	buttonSpec = buttonSpec->nextButtonSpec;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    return (True);
Packit b099d7
Packit b099d7
Packit b099d7
} /* END OF FUNCTION CheckForButtonAction */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  IdentifyEventContext (event, pCD, pContext, pPartContext)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function identifies the context in which an event occured.  The 
Packit b099d7
 *  pointer position is used to identify the context if the event is a
Packit b099d7
 *  button event.  If the context and the window state are incompatible
Packit b099d7
 *  (e.g., the context is window and the window is minimized) then the
Packit b099d7
 *  context is reset to 0 (none).
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  event = find the context of this X event
Packit b099d7
 *
Packit b099d7
 *  pCD = client data (maybe NULL) that the event is associated with
Packit b099d7
 *
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *  pContext = event context
Packit b099d7
 *
Packit b099d7
 *  pPartContext = part (e.g, frame) context associated with the event
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void IdentifyEventContext (XButtonEvent *event, ClientData *pCD, Context *pContext, int *pPartContext)
Packit b099d7
{
Packit b099d7
    Boolean eventOnRoot;
Packit b099d7
    Window actionWindow;
Packit b099d7
    int clientX;
Packit b099d7
    int clientY;
Packit b099d7
    int framePart;
Packit b099d7
Packit b099d7
Packit b099d7
    eventOnRoot = (event->window == ACTIVE_ROOT) ? 
Packit b099d7
				True : False;
Packit b099d7
Packit b099d7
    if (pCD)
Packit b099d7
    {
Packit b099d7
	actionWindow = (eventOnRoot) ? event->subwindow : event->window;
Packit b099d7
	if (actionWindow == pCD->clientFrameWin)
Packit b099d7
	{
Packit b099d7
	    *pContext = F_CONTEXT_WINDOW;
Packit b099d7
Packit b099d7
	    if (eventOnRoot)
Packit b099d7
	    {
Packit b099d7
	        clientX = event->x -
Packit b099d7
			  (pCD->maxConfig ? pCD->maxX : pCD->clientX) +
Packit b099d7
			  pCD->clientOffset.x;
Packit b099d7
	        clientY = event->y -
Packit b099d7
			  (pCD->maxConfig ? pCD->maxY : pCD->clientY) +
Packit b099d7
			  pCD->clientOffset.y;
Packit b099d7
	    }
Packit b099d7
	    else
Packit b099d7
	    {
Packit b099d7
		clientX = event->x;
Packit b099d7
		clientY = event->y;
Packit b099d7
	    }
Packit b099d7
	    framePart = IdentifyFramePart (pCD, clientX, clientY);
Packit b099d7
	    *pPartContext = framePart;
Packit b099d7
	}
Packit b099d7
	else if (actionWindow == pCD->clientBaseWin)
Packit b099d7
	{
Packit b099d7
	    *pContext = F_CONTEXT_WINDOW;
Packit b099d7
	    *pPartContext = FRAME_CLIENT;
Packit b099d7
	}
Packit b099d7
	else if ((actionWindow == ICON_FRAME_WIN(pCD)) ||
Packit b099d7
		 (actionWindow == ACTIVE_PSD->activeIconTextWin))
Packit b099d7
	{
Packit b099d7
	    if (P_ICON_BOX(pCD))
Packit b099d7
	    {
Packit b099d7
	        *pContext = F_CONTEXT_ICONBOX;
Packit b099d7
		if (pCD->clientState == MINIMIZED_STATE)
Packit b099d7
		{
Packit b099d7
		    *pPartContext = ICONBOX_PART_IICON;
Packit b099d7
		}
Packit b099d7
		else
Packit b099d7
		{
Packit b099d7
		    *pPartContext = ICONBOX_PART_WICON;
Packit b099d7
		}
Packit b099d7
	    }
Packit b099d7
	    else
Packit b099d7
	    {
Packit b099d7
	        *pContext = F_CONTEXT_ICON;
Packit b099d7
	        *pPartContext = ICON_PART_ALL;
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
	else
Packit b099d7
	{
Packit b099d7
	    *pContext = F_CONTEXT_ROOT;
Packit b099d7
	    *pPartContext = ROOT_PART_ALL;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	/*
Packit b099d7
	 * Check for an incompatible context and window state.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
	if (((*pContext & F_CONTEXT_WINDOW) &&
Packit b099d7
	     (pCD->clientState != NORMAL_STATE) &&
Packit b099d7
	     (pCD->clientState != MAXIMIZED_STATE)) ||
Packit b099d7
	    ((*pContext & F_CONTEXT_ICON) &&
Packit b099d7
	     (pCD->clientState != MINIMIZED_STATE)))
Packit b099d7
	{
Packit b099d7
	    *pContext = F_CONTEXT_NONE;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
    else
Packit b099d7
    {
Packit b099d7
	*pContext = F_CONTEXT_ROOT;
Packit b099d7
	*pPartContext = ROOT_PART_ALL;
Packit b099d7
    }
Packit b099d7
Packit b099d7
Packit b099d7
} /* END OF FUNCTION IdentifyEventContext */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  ProcessClickBPress (buttonEvent, pCD, context, subContext)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function checks for a double-click match and saves state information
Packit b099d7
 *  to do click and double-click processing.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  buttonEvent = pointer to a button press event
Packit b099d7
 *
Packit b099d7
 *  pCD = pointer to client data (identifies client window)
Packit b099d7
 *
Packit b099d7
 *  context = root/window/icon context for the event
Packit b099d7
 *
Packit b099d7
 *  subContext = subcontext for the event (title, system button, etc.)
Packit b099d7
 *
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *  (wmGD.clickData) = click processing information
Packit b099d7
 *
Packit b099d7
 *  (wmGD.clickData.doubleClickContext) = set if double click occured
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void ProcessClickBPress (XButtonEvent *buttonEvent, ClientData *pCD, Context context, Context subContext)
Packit b099d7
{
Packit b099d7
    Time timeDiff;
Packit b099d7
    Boolean passButton;
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Check for a double-click.  If a double click has occurred then
Packit b099d7
     * save the double-click context.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    wmGD.clickData.doubleClickContext = F_SUBCONTEXT_NONE;
Packit b099d7
    if (wmGD.clickData.doubleClickPending &&
Packit b099d7
	(buttonEvent->button == wmGD.clickData.button) &&
Packit b099d7
        ((buttonEvent->state == wmGD.clickData.state) ||
Packit b099d7
         (NOLOCKMOD(buttonEvent->state) == wmGD.clickData.state)) &&
Packit b099d7
	(pCD == wmGD.clickData.pCD) &&
Packit b099d7
	(context == wmGD.clickData.context))
Packit b099d7
    {
Packit b099d7
	/*
Packit b099d7
	 * Check the time between button release events.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
	if (buttonEvent->time > wmGD.clickData.time)
Packit b099d7
	{
Packit b099d7
	    timeDiff = buttonEvent->time - wmGD.clickData.time;
Packit b099d7
	}
Packit b099d7
	else
Packit b099d7
	{
Packit b099d7
	    timeDiff = ~wmGD.clickData.time + buttonEvent->time + 1;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	if (timeDiff < wmGD.doubleClickTime)
Packit b099d7
	{
Packit b099d7
	    /*
Packit b099d7
	     * A double-click has been done; save the context.
Packit b099d7
	     */
Packit b099d7
Packit b099d7
	    wmGD.clickData.doubleClickContext = subContext |
Packit b099d7
						wmGD.clickData.subContext;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Save state data for click checking.  If a button binding match
Packit b099d7
     * occurs for a double-click then clear out the clickData (don't
Packit b099d7
     * do any click/double-click matches for the following button press
Packit b099d7
     * and release).  If the button press is done on the client area and
Packit b099d7
     * is used to set the focus to the window then don't use it in
Packit b099d7
     * setting up clickData.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if ((buttonEvent->button == SELECT_BUTTON) && 
Packit b099d7
	((buttonEvent->state == 0) ||
Packit b099d7
	 (NOLOCKMOD(buttonEvent->state) == 0)))
Packit b099d7
    {
Packit b099d7
	passButton = wmGD.passSelectButton;
Packit b099d7
    }
Packit b099d7
    else
Packit b099d7
    {
Packit b099d7
	passButton = wmGD.passButtons;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (!(pCD && (buttonEvent->window == pCD->clientBaseWin) && passButton))
Packit b099d7
    {
Packit b099d7
        wmGD.clickData.button = buttonEvent->button;
Packit b099d7
        wmGD.clickData.state = buttonEvent->state;
Packit b099d7
        /* add in event button mask (this will show up in the button release */
Packit b099d7
        wmGD.clickData.releaseState = buttonEvent->state |
Packit b099d7
				    buttonModifierMasks[buttonEvent->button];
Packit b099d7
        wmGD.clickData.pCD = pCD;
Packit b099d7
        wmGD.clickData.context = context;
Packit b099d7
        wmGD.clickData.subContext = subContext;
Packit b099d7
        wmGD.clickData.time = buttonEvent->time;
Packit b099d7
        wmGD.clickData.clickPending = True;
Packit b099d7
        wmGD.clickData.doubleClickPending = True;
Packit b099d7
#ifdef WSM
Packit b099d7
        wmGD.clickData.bReplayed = wmGD.bReplayedButton;
Packit b099d7
#endif /* WSM */
Packit b099d7
    }
Packit b099d7
Packit b099d7
Packit b099d7
} /* END OF FUNCTION ProcessClickBPress */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  ProcessClickBRelease (buttonEvent, pCD, context, subContext)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function checks to see if a "click" was done.  The button release
Packit b099d7
 *  completes a click if there is a click pending and the button release
Packit b099d7
 *  context is the same as the button press context.  Configuration or
Packit b099d7
 *  menu activity cancels a pending click.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  buttonEvent = pointer to a button press event
Packit b099d7
 *
Packit b099d7
 *  pCD = pointer to client data (identifies client window)
Packit b099d7
 *
Packit b099d7
 *  context = root/window/icon context for the event
Packit b099d7
 *
Packit b099d7
 *  subContext = window subcontext for the event (title, system button, etc.)
Packit b099d7
 *
Packit b099d7
 *  (wmGD.clickData) = click processing information
Packit b099d7
 *
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *  (wmGD.clickData) = click processing information
Packit b099d7
 *
Packit b099d7
 *  (wmGD.clickData.clickContext) = set if click occured
Packit b099d7
 * 
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void ProcessClickBRelease (XButtonEvent *buttonEvent, ClientData *pCD, Context context, Context subContext)
Packit b099d7
{
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Restore the state of the last "depressed" frame gadget
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (pCD && (wmGD.gadgetClient == pCD) && (pCD->decorFlags))
Packit b099d7
    {
Packit b099d7
	PopGadgetOut(pCD, wmGD.gadgetDepressed);
Packit b099d7
    }
Packit b099d7
	
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Check to see if a click has been done.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    wmGD.clickData.clickContext = F_SUBCONTEXT_NONE;
Packit b099d7
    if (wmGD.clickData.clickPending &&
Packit b099d7
	(buttonEvent->button == wmGD.clickData.button) &&
Packit b099d7
	(buttonEvent->state == wmGD.clickData.releaseState) &&
Packit b099d7
	(pCD == wmGD.clickData.pCD) &&
Packit b099d7
	(context == wmGD.clickData.context))
Packit b099d7
    {
Packit b099d7
	wmGD.clickData.clickContext = subContext | wmGD.clickData.subContext;
Packit b099d7
	/* !!! check for double click time? !!! */
Packit b099d7
    }
Packit b099d7
    else
Packit b099d7
    {
Packit b099d7
	wmGD.clickData.doubleClickPending = False;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    wmGD.clickData.clickPending = False;
Packit b099d7
Packit b099d7
Packit b099d7
} /* END OF FUNCTION ProcessClickBRelease */
Packit b099d7
Packit b099d7
Packit b099d7
#ifdef WSM
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  HandleDtWmClientMessage (clientEvent)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function handles client message events that are sent to the 
Packit b099d7
 *  wm window.  The window manager action that is taken depends on the
Packit b099d7
 *  message_type of the event.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  clientEvent = pointer to a client message event on the wm window
Packit b099d7
 * 
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void HandleDtWmClientMessage (XClientMessageEvent *clientEvent)
Packit b099d7
{
Packit b099d7
    int scr;
Packit b099d7
    /*
Packit b099d7
     * Process the client message event based on the message_type.
Packit b099d7
     */
Packit b099d7
    
Packit b099d7
    if (clientEvent->message_type == wmGD.xa_DT_SM_WM_PROTOCOL)
Packit b099d7
    {
Packit b099d7
	if (clientEvent->data.l[0] == wmGD.xa_DT_SM_START_ACK_WINDOWS)
Packit b099d7
	{
Packit b099d7
	    smAckState = SM_START_ACK;
Packit b099d7
	}
Packit b099d7
	else if (clientEvent->data.l[0] == wmGD.xa_DT_SM_STOP_ACK_WINDOWS)
Packit b099d7
	{
Packit b099d7
	    smAckState = SM_STOP_ACK;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (clientEvent->message_type == wmGD.xa_WM_PROTOCOLS)
Packit b099d7
    {
Packit b099d7
	if (clientEvent->data.l[0] == wmGD.xa_WM_SAVE_YOURSELF)
Packit b099d7
	{
Packit b099d7
	    for (scr = 0; scr < wmGD.numScreens; scr++)
Packit b099d7
	    {
Packit b099d7
		if (wmGD.Screens[scr].managed)
Packit b099d7
		{
Packit b099d7
		    /*
Packit b099d7
		     * Write out current workspace, frontpanel 
Packit b099d7
		     * position and iconbox position and size.
Packit b099d7
		     */
Packit b099d7
		    SaveResources(&wmGD.Screens[scr]);
Packit b099d7
		}
Packit b099d7
	    } /*  for loop */
Packit b099d7
	    XSetCommand(DISPLAY, wmGD.commandWindow, 0, 0);
Packit b099d7
Packit b099d7
	} /* WM_SAVE_YOURSELF */     
Packit b099d7
    } /* WM_PROTOCOLS */
Packit b099d7
} /* END OF FUNCTION HandleDtWmClientMessage */
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  HandleDtWmRequest (pSD, pev)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function processes _DT_WM_REQUESTs that come in from 
Packit b099d7
 *  other clients
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  pSD - pointer to screen data
Packit b099d7
 *  pev - pointer to the triggering event (PropertyNotify)
Packit b099d7
 *
Packit b099d7
 *  Comments:
Packit b099d7
 *  ---------
Packit b099d7
 *  This reuses the global parse buffer. It assumes that no parsing 
Packit b099d7
 *  is in progress. All parsing of the config file must be completed 
Packit b099d7
 *  before we call this routine. 
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void 
Packit b099d7
HandleDtWmRequest (WmScreenData *pSD, XEvent *pev)
Packit b099d7
{
Packit b099d7
    Boolean more = True;
Packit b099d7
    char *pchReq = NULL;
Packit b099d7
    String sRequest = NULL;
Packit b099d7
    unsigned char *lineP;
Packit b099d7
    int iFuncIndex;
Packit b099d7
    WmFunction   wmFunction;
Packit b099d7
    String       wmFuncArgs;
Packit b099d7
    ClientData	 *pCD;
Packit b099d7
    Context	 ctxDisallowed;
Packit b099d7
    DtWmpParseBuf wmPB;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Save state of global parse buffer
Packit b099d7
     */
Packit b099d7
    memcpy (&wmPB, wmGD.pWmPB, sizeof(DtWmpParseBuf));
Packit b099d7
Packit b099d7
    while (more)
Packit b099d7
    {
Packit b099d7
	GetDtWmRequest (pSD, &pchReq, &more);
Packit b099d7
Packit b099d7
	if (pchReq)
Packit b099d7
	{
Packit b099d7
	    pCD = NULL;
Packit b099d7
	    ctxDisallowed = F_CONTEXT_ROOT;
Packit b099d7
	    if (wmGD.requestContextWin != (Window) 0L)
Packit b099d7
	    {
Packit b099d7
		if (!XFindContext (DISPLAY, wmGD.requestContextWin, 
Packit b099d7
					wmGD.windowContextType,
Packit b099d7
					(caddr_t *)&pCD))
Packit b099d7
		{
Packit b099d7
		    /* 
Packit b099d7
		     * A valid client window was specified
Packit b099d7
		     * in a previous F_Set_Context request.
Packit b099d7
		     * Remove the restriction to root-only context.
Packit b099d7
		     */
Packit b099d7
		    ctxDisallowed = F_CONTEXT_NONE;
Packit b099d7
		}
Packit b099d7
	    }
Packit b099d7
	    sRequest = XtNewString (pchReq);
Packit b099d7
	    _DtWmParseSetLine (wmGD.pWmPB, (unsigned char *)sRequest);
Packit b099d7
	    lineP = wmGD.pWmPB->pchLine;
Packit b099d7
            iFuncIndex = ParseWmFunction (&lineP, CRS_BUTTON|CRS_KEY, 
Packit b099d7
		&wmFunction);
Packit b099d7
Packit b099d7
	    if (iFuncIndex != F_NOP_INDEX)
Packit b099d7
	    {
Packit b099d7
		if (functionTable[iFuncIndex].greyedContext & ctxDisallowed)
Packit b099d7
		{
Packit b099d7
		    /* 
Packit b099d7
		     * Sorry, we have to disallow this function request
Packit b099d7
		     * based on context problems.
Packit b099d7
		     */
Packit b099d7
		    XtFree ((char *)sRequest);
Packit b099d7
		    sRequest = NULL;
Packit b099d7
		    break;
Packit b099d7
		}
Packit b099d7
Packit b099d7
		/*
Packit b099d7
		 * Apply the function argument parser.
Packit b099d7
		 */
Packit b099d7
		if ((*(functionTable [iFuncIndex].parseProc))
Packit b099d7
			   (&lineP, wmFunction, &wmFuncArgs))
Packit b099d7
		{
Packit b099d7
		    /* 
Packit b099d7
		     * Found it in the function table! 
Packit b099d7
		     * Apply the function.
Packit b099d7
		     */
Packit b099d7
		    wmFunction (wmFuncArgs, pCD, NULL);
Packit b099d7
Packit b099d7
		    /*
Packit b099d7
		     * Free up allocated args, if any
Packit b099d7
		     */
Packit b099d7
		    if (wmFuncArgs)
Packit b099d7
		    {
Packit b099d7
			if ((functionTable[iFuncIndex].parseProc ==
Packit b099d7
			    		ParseWmFuncStrArg) ||
Packit b099d7
			    (functionTable[iFuncIndex].parseProc ==
Packit b099d7
					ParseWmFuncMaybeStrArg))
Packit b099d7
			{
Packit b099d7
			    XtFree ((char *)wmFuncArgs);
Packit b099d7
			}
Packit b099d7
			else if ((functionTable[iFuncIndex].parseProc ==
Packit b099d7
			    		ParseWmFuncActionArg))
Packit b099d7
			{
Packit b099d7
			    WmActionArg *pAP = (WmActionArg *) wmFuncArgs;
Packit b099d7
Packit b099d7
			    if (pAP->actionName)
Packit b099d7
				XtFree ((char *) pAP->actionName);
Packit b099d7
			    if (pAP->szExecParms)
Packit b099d7
				XtFree ((char *) pAP->szExecParms);
Packit b099d7
			    while (pAP->numArgs > 0)
Packit b099d7
			    {
Packit b099d7
				XtFree ((char *)
Packit b099d7
				    pAP->aap[--(pAP->numArgs)].u.file.name);
Packit b099d7
			    }
Packit b099d7
			    XtFree ((char *) pAP);
Packit b099d7
			}
Packit b099d7
		    }
Packit b099d7
		}
Packit b099d7
	    }
Packit b099d7
	    else if (!strncmp (pchReq, DTWM_REQ_CHANGE_BACKDROP,
Packit b099d7
			strlen(DTWM_REQ_CHANGE_BACKDROP)))
Packit b099d7
	    {
Packit b099d7
		Pixmap pixmap = None;
Packit b099d7
		char *pch;
Packit b099d7
		char *pchFile = NULL;
Packit b099d7
Packit b099d7
		/* skip function name */
Packit b099d7
		pch = pchReq;
Packit b099d7
		(void) strtok (pch, " ");
Packit b099d7
Packit b099d7
		/* get path name */
Packit b099d7
		pch = strtok (NULL, " ");
Packit b099d7
		if (pch)
Packit b099d7
		{
Packit b099d7
		    pchFile = (char *) XtMalloc (1+strlen(pch));
Packit b099d7
		}
Packit b099d7
		else
Packit b099d7
		{
Packit b099d7
		    Warning (((char *)GETMESSAGE(32, 3, "Missing path name for backdrop change request.")));
Packit b099d7
Packit b099d7
		}
Packit b099d7
		if (pchFile)
Packit b099d7
		{
Packit b099d7
		    strcpy (pchFile, pch);
Packit b099d7
Packit b099d7
		    /* get pixmap id */
Packit b099d7
		    pch = strtok (NULL, " ");
Packit b099d7
		    if (pch) 
Packit b099d7
		    {
Packit b099d7
			sscanf (pch, "%lx", &pixmap);  
Packit b099d7
			SetNewBackdrop (ACTIVE_WS, pixmap, (String)pchFile);
Packit b099d7
		    }
Packit b099d7
		    else 
Packit b099d7
		    {
Packit b099d7
			Warning (((char *)GETMESSAGE(32, 4, "Missing pixmap id for backdrop change request.")));
Packit b099d7
		    }
Packit b099d7
		    XtFree (pchFile);
Packit b099d7
		}
Packit b099d7
		else
Packit b099d7
		{
Packit b099d7
		    Warning (((char *)GETMESSAGE(32, 2, "Insufficient memory to handle backdrop change.")));
Packit b099d7
		}
Packit b099d7
	    }
Packit b099d7
	    if (sRequest)
Packit b099d7
	    {
Packit b099d7
		XtFree ((char *) sRequest);
Packit b099d7
	    }
Packit b099d7
	    XtFree (pchReq);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Restore state of global parse buffer
Packit b099d7
     */
Packit b099d7
    memcpy (wmGD.pWmPB, &wmPB, sizeof(DtWmpParseBuf));
Packit b099d7
Packit b099d7
} /* END OF FUNCTION HandleDtWmRequest */
Packit b099d7
Packit b099d7
Packit b099d7
#endif /* WSM */
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  HandleWsEnterNotify (enterEvent)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function processes EnterNotify events that are reported to
Packit b099d7
 *  the root window.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  enterEvent = pointer to an enter notify event on the root window.
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void HandleWsEnterNotify (XEnterWindowEvent *enterEvent)
Packit b099d7
{
Packit b099d7
    WmScreenData *pSD;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * If the pointer entered a screen that we manage, then set the
Packit b099d7
     * new active screen.
Packit b099d7
     */
Packit b099d7
    if (wmGD.queryScreen &&
Packit b099d7
	(!XFindContext (DISPLAY, enterEvent->window, wmGD.screenContextType,
Packit b099d7
	    (caddr_t *)&pSD)))
Packit b099d7
    {
Packit b099d7
	SetActiveScreen (pSD);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * The root window was entered; do focus processing
Packit b099d7
     * if necessary:
Packit b099d7
     */
Packit b099d7
    
Packit b099d7
Packit b099d7
    if (!wmGD.menuActive &&
Packit b099d7
	((enterEvent->mode == NotifyNormal) ||
Packit b099d7
	 (enterEvent->mode == NotifyUngrab) ||
Packit b099d7
	 (enterEvent->mode == NotifyWhileGrabbed)))
Packit b099d7
    {
Packit b099d7
        if (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_POINTER)
Packit b099d7
	{
Packit b099d7
	    Do_Focus_Key ((ClientData *) NULL, enterEvent->time, 
Packit b099d7
			ALWAYS_SET_FOCUS);
Packit b099d7
	}
Packit b099d7
	else if ((wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT) &&
Packit b099d7
	         ((enterEvent->detail == NotifyNonlinearVirtual) ||
Packit b099d7
	          (enterEvent->detail == NotifyNonlinear)) &&
Packit b099d7
		 (wmGD.keyboardFocus == NULL) &&
Packit b099d7
		 enterEvent->focus)
Packit b099d7
	{
Packit b099d7
	    /*
Packit b099d7
	     * Reset the explicit selection focus to the workspace
Packit b099d7
	     * window.
Packit b099d7
	     */
Packit b099d7
Packit b099d7
	    Do_Focus_Key ((ClientData *) NULL, enterEvent->time, 
Packit b099d7
	    		ALWAYS_SET_FOCUS);
Packit b099d7
	}
Packit b099d7
Packit b099d7
        if (wmGD.colormapFocusPolicy == CMAP_FOCUS_POINTER)
Packit b099d7
	{
Packit b099d7
	    SetColormapFocus (ACTIVE_PSD, (ClientData *) NULL);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
} /* END OF FUNCTION HandleWsEnterNotify */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  HandleWsLeaveNotify (leaveEvent)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function processes LeaveNotify events that are reported to
Packit b099d7
 *  the root window.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  enterEvent = pointer to an leave notify event on the root window.
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void HandleWsLeaveNotify (XLeaveWindowEvent *leaveEvent)
Packit b099d7
{
Packit b099d7
    WmScreenData *pSD;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * The root window was exited; do focus processing
Packit b099d7
     * if necessary:
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (!wmGD.menuActive &&
Packit b099d7
	((leaveEvent->detail == NotifyNonlinear) ||
Packit b099d7
	(leaveEvent->detail == NotifyNonlinearVirtual)))
Packit b099d7
    {
Packit b099d7
	/*
Packit b099d7
	 * The pointer has moved to another screen.  Fix the
Packit b099d7
	 * focus on the screen controlled by the window manager.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
        if ((wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_POINTER) ||
Packit b099d7
            (wmGD.colormapFocusPolicy == CMAP_FOCUS_POINTER))
Packit b099d7
	{
Packit b099d7
	    if (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_POINTER)
Packit b099d7
	    {
Packit b099d7
	        Do_Focus_Key ((ClientData *) NULL, leaveEvent->time,
Packit b099d7
		    (SCREEN_SWITCH_FOCUS | ALWAYS_SET_FOCUS));
Packit b099d7
	    }
Packit b099d7
	    if (wmGD.colormapFocusPolicy == CMAP_FOCUS_POINTER)
Packit b099d7
	    {
Packit b099d7
	        SetColormapFocus (ACTIVE_PSD, (ClientData *) NULL);
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
Packit b099d7
	/*  Set new active screen */
Packit b099d7
Packit b099d7
	if (!XFindContext (DISPLAY, leaveEvent->root, wmGD.screenContextType,
Packit b099d7
	    (caddr_t *)&pSD))
Packit b099d7
	{
Packit b099d7
	    /* moved to another screen we manage! */
Packit b099d7
	    SetActiveScreen (pSD);
Packit b099d7
	}
Packit b099d7
	else
Packit b099d7
	{
Packit b099d7
	    /* off onto an unmanaged screen */
Packit b099d7
	    wmGD.queryScreen = True;
Packit b099d7
Packit b099d7
	    /* set input focus to pointer root */
Packit b099d7
	    XSetInputFocus (DISPLAY, PointerRoot, 
Packit b099d7
		RevertToPointerRoot, leaveEvent->time);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
} /* END OF FUNCTION HandleWsLeaveNotify */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  HandleWsConfigureRequest (focusEvent)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function processes ConfigureRequest events that are reported to
Packit b099d7
 *  the root window.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  focusEvent = pointer to a configure request event on the root window.
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void HandleWsConfigureRequest (XConfigureRequestEvent *configureEvent)
Packit b099d7
{
Packit b099d7
    ClientData *pCD;
Packit b099d7
    XConfigureEvent notifyEvent;
Packit b099d7
    Boolean configChanged;
Packit b099d7
    XWindowChanges values;
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * A window that is a child of the root window is being
Packit b099d7
     * configured.  Either it is an un-managed window or it is a
Packit b099d7
     * managed window that did the configuration before it was
Packit b099d7
     * reparented.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (XFindContext (DISPLAY, configureEvent->window, wmGD.windowContextType,
Packit b099d7
	    (caddr_t *)&pCD))
Packit b099d7
    {
Packit b099d7
	/*
Packit b099d7
	 * Get window attribute information; this is used later on
Packit b099d7
	 * to decide if a synthetic ConfigureNotify event should
Packit b099d7
	 * be send to the client.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
	if (WmGetWindowAttributes (configureEvent->window))
Packit b099d7
	{
Packit b099d7
	    configChanged =
Packit b099d7
		(wmGD.windowAttributes.x != configureEvent->x) ||
Packit b099d7
		(wmGD.windowAttributes.y != configureEvent->y) ||
Packit b099d7
		(wmGD.windowAttributes.width != configureEvent->width) ||
Packit b099d7
		(wmGD.windowAttributes.height != configureEvent->height) ||
Packit b099d7
		(wmGD.windowAttributes.border_width !=
Packit b099d7
				       configureEvent->border_width) ||
Packit b099d7
		(configureEvent->value_mask & (CWSibling|CWStackMode));
Packit b099d7
Packit b099d7
            /*
Packit b099d7
             * The window is not (yet) managed.  Do the window
Packit b099d7
	     * configuration.
Packit b099d7
             */
Packit b099d7
Packit b099d7
	    if (configChanged)
Packit b099d7
	    {
Packit b099d7
	        values.x = configureEvent->x;
Packit b099d7
	        values.y = configureEvent->y;
Packit b099d7
	        values.width = configureEvent->width;
Packit b099d7
	        values.height = configureEvent->height;
Packit b099d7
	        values.border_width = configureEvent->border_width;
Packit b099d7
	        values.sibling = configureEvent->above;
Packit b099d7
	        values.stack_mode = configureEvent->detail;
Packit b099d7
	        XConfigureWindow (DISPLAY, configureEvent->window,
Packit b099d7
	            (unsigned int) (configureEvent->value_mask), &values);
Packit b099d7
	    }
Packit b099d7
Packit b099d7
	    /*
Packit b099d7
	     * Some clients expect a ConfigureNotify event even if the
Packit b099d7
	     * XConfigureWindow call has NO effect.  Send a synthetic
Packit b099d7
	     * ConfigureNotify event just to be sure.
Packit b099d7
	     */
Packit b099d7
Packit b099d7
	    if (!configChanged)
Packit b099d7
	    {
Packit b099d7
	        notifyEvent.type = ConfigureNotify;
Packit b099d7
	        notifyEvent.display = DISPLAY;
Packit b099d7
	        notifyEvent.event = configureEvent->window;
Packit b099d7
	        notifyEvent.window = configureEvent->window;
Packit b099d7
	        notifyEvent.x = configureEvent->x;
Packit b099d7
	        notifyEvent.y = configureEvent->y;
Packit b099d7
	        notifyEvent.width = configureEvent->width;
Packit b099d7
	        notifyEvent.height = configureEvent->height;
Packit b099d7
	        notifyEvent.border_width = configureEvent->border_width;
Packit b099d7
	        notifyEvent.above = None;
Packit b099d7
	        notifyEvent.override_redirect = False;
Packit b099d7
Packit b099d7
	        XSendEvent (DISPLAY, configureEvent->window, False,
Packit b099d7
	            StructureNotifyMask, (XEvent *)&notifyEvent);
Packit b099d7
            }
Packit b099d7
        }
Packit b099d7
    }
Packit b099d7
    else
Packit b099d7
    {
Packit b099d7
        /*
Packit b099d7
         * The context information on the window WAS found.
Packit b099d7
         * The window is already managed by the window manager
Packit b099d7
         * so this is a configuration request that was made before
Packit b099d7
         * the window was reparented.
Packit b099d7
         */
Packit b099d7
Packit b099d7
	HandleCConfigureRequest (pCD, configureEvent);
Packit b099d7
    }
Packit b099d7
Packit b099d7
} /* END OF FUNCTION HandleWsConfigureRequest */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  HandleWsFocusIn (focusEvent)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function processes FocusIn events that are reported to the root
Packit b099d7
 *  window.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  focusEvent = pointer to a focus in event on the root window.
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void HandleWsFocusIn (XFocusInEvent *focusEvent)
Packit b099d7
{
Packit b099d7
    ClientData *pCD;
Packit b099d7
    Boolean sameScreen;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * This code is used to handle the case of the focus being
Packit b099d7
     * set to pointer root (either explicitly by some client, by the window
Packit b099d7
     * manager or as a result of a "revert to" action).
Packit b099d7
     * It also handles the case where the focus is manipulated by a window
Packit b099d7
     * manager on another screen (in this case let the other window manager
Packit b099d7
     * control the focus). Reset the focus to a client window if appropriate.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (((focusEvent->mode == NotifyNormal) ||
Packit b099d7
	 (focusEvent->mode == NotifyUngrab)) &&
Packit b099d7
	((focusEvent->detail == NotifyPointerRoot) ||
Packit b099d7
	 (focusEvent->detail == NotifyDetailNone) ||
Packit b099d7
	 (focusEvent->detail == NotifyInferior)))
Packit b099d7
    {
Packit b099d7
	/*
Packit b099d7
	 * Fix the keyboard focus if it should be set to a particular client.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
        pCD = GetClientUnderPointer (&sameScreen);
Packit b099d7
	if (wmGD.keyboardFocus && (focusEvent->detail != NotifyInferior))
Packit b099d7
	{
Packit b099d7
	    if (sameScreen)
Packit b099d7
	    {
Packit b099d7
		/*
Packit b099d7
		 * Assume that the focus still belongs to the screen
Packit b099d7
		 * controlled by mwm.  Repair the focus if the client
Packit b099d7
		 * is still active.
Packit b099d7
		 */
Packit b099d7
Packit b099d7
		if (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT)
Packit b099d7
		{
Packit b099d7
		    Do_Focus_Key (wmGD.keyboardFocus, GetTimestamp (),
Packit b099d7
			ALWAYS_SET_FOCUS);
Packit b099d7
		}
Packit b099d7
		else
Packit b099d7
		{
Packit b099d7
		    if (pCD || (focusEvent->detail == NotifyDetailNone))
Packit b099d7
		    {
Packit b099d7
			/* !!! check for redundant focus setting !!! */
Packit b099d7
	        	Do_Focus_Key (pCD, GetTimestamp (), ALWAYS_SET_FOCUS);
Packit b099d7
		    }
Packit b099d7
		}
Packit b099d7
		SetKeyboardFocus ((ClientData *) NULL, REFRESH_LAST_FOCUS);
Packit b099d7
	    }
Packit b099d7
	    else
Packit b099d7
	    {
Packit b099d7
	        /*
Packit b099d7
		 * Assume that the focus is now controlled by a
Packit b099d7
		 * window manager on another screen.  Clear the
Packit b099d7
		 * focus locally.
Packit b099d7
	         */
Packit b099d7
Packit b099d7
		SetKeyboardFocus ((ClientData *) NULL, REFRESH_LAST_FOCUS);
Packit b099d7
	    }
Packit b099d7
        }
Packit b099d7
        else
Packit b099d7
        {
Packit b099d7
	    /*
Packit b099d7
	     * No client window currently has the focus.  If the pointer
Packit b099d7
	     * is on the mwm-controlled screen set the focus to
Packit b099d7
	     * the window management window if the focus is explicit.
Packit b099d7
	     */
Packit b099d7
Packit b099d7
	    if (sameScreen)
Packit b099d7
	    {
Packit b099d7
		if (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT)
Packit b099d7
		{
Packit b099d7
		    if (((focusEvent->detail == NotifyInferior) ||
Packit b099d7
			 (focusEvent->detail == NotifyPointerRoot)) &&
Packit b099d7
			(wmGD.keyboardFocus != wmGD.nextKeyboardFocus))
Packit b099d7
		    {
Packit b099d7
			/*
Packit b099d7
			 * Window that had the focus went away.  Try to
Packit b099d7
			 * reset the window to the next keyboard focus
Packit b099d7
			 * client window if there is one.
Packit b099d7
			 */
Packit b099d7
Packit b099d7
		        Do_Focus_Key (wmGD.nextKeyboardFocus, GetTimestamp (),
Packit b099d7
			    ALWAYS_SET_FOCUS);
Packit b099d7
		    }
Packit b099d7
		    else
Packit b099d7
		    {
Packit b099d7
		        /* Re: CR 4896                                          */
Packit b099d7
                        /* The previous version would pass NULL widget to this  */
Packit b099d7
                        /* this routine.  This doesn't seem to make sense. NULL */
Packit b099d7
                        /* has been replaced by pCD which seems to fix the icon */
Packit b099d7
                        /* focus problem.                                       */
Packit b099d7
                        /* Another related patch is made in WmCEvent.c.         */
Packit b099d7
		        Do_Focus_Key ((ClientData *) pCD, GetTimestamp(), 
Packit b099d7
					ALWAYS_SET_FOCUS);
Packit b099d7
		    }
Packit b099d7
		}
Packit b099d7
		else /*KEYBOARD_FOCUS_POINTER*/
Packit b099d7
		{
Packit b099d7
		    if (pCD || focusEvent->detail != NotifyPointerRoot)
Packit b099d7
		    {
Packit b099d7
		        Do_Focus_Key (pCD, GetTimestamp (), ALWAYS_SET_FOCUS);
Packit b099d7
		    }
Packit b099d7
		}
Packit b099d7
	    }
Packit b099d7
        }
Packit b099d7
    }
Packit b099d7
Packit b099d7
} /* END OF FUNCTION HandleWsFocusIn */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  GetTimestamp ()
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function is used to provide a timestamp for use with X calls that
Packit b099d7
 *  require a timestamp (and a timestamp is not available from a prior
Packit b099d7
 *  X event).
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *  Return = a timestamp value
Packit b099d7
 *
Packit b099d7
 *  Comment: 
Packit b099d7
 *  --------
Packit b099d7
 *  This costs a server round-trip
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
Time GetTimestamp (void)
Packit b099d7
{
Packit b099d7
    Time timestamp;
Packit b099d7
    WmScreenData *pSD = ACTIVE_PSD;
Packit b099d7
    XEvent event;
Packit b099d7
    long property;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Do zero-length append to our own WM_STATE
Packit b099d7
     */
Packit b099d7
    XChangeProperty (DISPLAY, pSD->wmWorkspaceWin, wmGD.xa_WM_STATE, 
Packit b099d7
	wmGD.xa_WM_STATE, 32, PropModeAppend, 
Packit b099d7
	(unsigned char *)&property, 0);
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Pick up the property notify event
Packit b099d7
     */
Packit b099d7
    XSync (DISPLAY, False);
Packit b099d7
    if (XCheckWindowEvent (DISPLAY, pSD->wmWorkspaceWin, 
Packit b099d7
			    PropertyChangeMask, &event))
Packit b099d7
    {
Packit b099d7
	if (event.type == PropertyNotify)
Packit b099d7
	{
Packit b099d7
	    timestamp = event.xproperty.time;
Packit b099d7
	}
Packit b099d7
	else
Packit b099d7
	{
Packit b099d7
	    /* not sure what happened here ... use CurrentTime */
Packit b099d7
	    timestamp = CurrentTime; 
Packit b099d7
	}
Packit b099d7
	if ((event.type != PropertyNotify) ||
Packit b099d7
	    (event.xproperty.atom != wmGD.xa_WM_STATE))
Packit b099d7
	{
Packit b099d7
	    /* 
Packit b099d7
	     * This wasn't the event we caused, put it back for
Packit b099d7
	     * later processing. We'll keep the timestamp, though.
Packit b099d7
	     */
Packit b099d7
	    XPutBackEvent (DISPLAY, &event);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
    else
Packit b099d7
    {
Packit b099d7
	/* Hmm... didn't get the prop notify, fall back to current time */
Packit b099d7
	timestamp = CurrentTime; 
Packit b099d7
    }
Packit b099d7
Packit b099d7
    return (timestamp);
Packit b099d7
Packit b099d7
} /* END OF FUNCTION GetTimestamp */
Packit b099d7
Packit b099d7
#if ((!defined(WSM)) || defined(MWM_QATS_PROTOCOL))
Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  LastTime ()
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function is used to provide a timestamp for use with X calls that
Packit b099d7
 *  require a timestamp. It returns the last timestamp processed if one
Packit b099d7
 *  exists or it generates a new one.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  none
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *  Return = a timestamp value - NOT CurrentTime
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
Time LastTime ()
Packit b099d7
{
Packit b099d7
  Time evTime;
Packit b099d7
Packit b099d7
  if (! (evTime = XtLastTimestampProcessed(DISPLAY)) )
Packit b099d7
    evTime = GetTimestamp();
Packit b099d7
Packit b099d7
  return (evTime);
Packit b099d7
}
Packit b099d7
#endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  PullExposureEvents ()
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  Pull in and process all outstanding exposure events 
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *
Packit b099d7
 *  Comments:
Packit b099d7
 *  --------
Packit b099d7
 *  Useful for cleaning up display after menu popdown
Packit b099d7
 * 
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
void PullExposureEvents (void)
Packit b099d7
{
Packit b099d7
    XEvent	event;
Packit b099d7
    Boolean	dispatchEvent;
Packit b099d7
Packit b099d7
    /* 
Packit b099d7
     * Force the exposure events into the queue
Packit b099d7
     */
Packit b099d7
    XSync (DISPLAY, False);
Packit b099d7
#ifdef WSM
Packit b099d7
    XSync (DISPLAY1, False);
Packit b099d7
#endif /* WSM */
Packit b099d7
    /*
Packit b099d7
     * Selectively extract the exposure events
Packit b099d7
     */
Packit b099d7
#ifdef WSM
Packit b099d7
    while (XCheckMaskEvent (DISPLAY, 
Packit b099d7
	       ExposureMask|VisibilityChangeMask, &event) ||
Packit b099d7
	   XCheckMaskEvent (DISPLAY1, 
Packit b099d7
	       ExposureMask|VisibilityChangeMask, &event))
Packit b099d7
#else /* WSM */
Packit b099d7
    while (XCheckMaskEvent (DISPLAY, ExposureMask, &event))
Packit b099d7
#endif /* WSM */
Packit b099d7
    {
Packit b099d7
        /*
Packit b099d7
	 * Check for, and process non-widget events.  The events may be
Packit b099d7
	 * reported to the root window, to some client frame window,
Packit b099d7
	 * to an icon window, or to a "special" window management window.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
#ifdef WSM
Packit b099d7
      switch (event.type)
Packit b099d7
      {
Packit b099d7
       case Expose:
Packit b099d7
#endif /* WSM */
Packit b099d7
	if (event.xany.window == ACTIVE_ROOT)
Packit b099d7
	{
Packit b099d7
	    dispatchEvent = WmDispatchWsEvent (&event);
Packit b099d7
	}
Packit b099d7
	else
Packit b099d7
	{
Packit b099d7
	    dispatchEvent = WmDispatchClientEvent (&event);
Packit b099d7
	}
Packit b099d7
#ifdef WSM
Packit b099d7
       default:
Packit b099d7
	dispatchEvent = True;
Packit b099d7
      }
Packit b099d7
#endif /* WSM */
Packit b099d7
Packit b099d7
	if (dispatchEvent)
Packit b099d7
	{
Packit b099d7
	    /*
Packit b099d7
	     * Dispatch widget related event:
Packit b099d7
	     */
Packit b099d7
Packit b099d7
	    XtDispatchEvent (&event);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
} /* END OF FUNCTION PullExposureEvents */
Packit b099d7
Packit b099d7
#ifdef WSM
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  ReplayedButtonEvent ()
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  Compare to button events to see if it's one event that's been
Packit b099d7
 *  replayed.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *  return	= True if event is replayed.
Packit b099d7
 *
Packit b099d7
 *  Comments:
Packit b099d7
 *  --------
Packit b099d7
 * 
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Boolean
Packit b099d7
ReplayedButtonEvent (
Packit b099d7
    XButtonEvent *pevB1,
Packit b099d7
    XButtonEvent *pevB2)
Packit b099d7
{
Packit b099d7
    Boolean rval = False;
Packit b099d7
Packit b099d7
    if ( (pevB1->type  		== pevB2->type) &&
Packit b099d7
	 (pevB1->send_event 	== pevB2->send_event) &&
Packit b099d7
	 (pevB1->display 	== pevB2->display) &&
Packit b099d7
	 (pevB1->window 	== pevB2->window) &&
Packit b099d7
	 (pevB1->root 		== pevB2->root) &&
Packit b099d7
	 (pevB1->subwindow 	== pevB2->subwindow) &&
Packit b099d7
	 (pevB1->time 		== pevB2->time) &&
Packit b099d7
	 (pevB1->x 		== pevB2->x) &&
Packit b099d7
	 (pevB1->y 		== pevB2->y) &&
Packit b099d7
	 (pevB1->x_root 	== pevB2->x_root) &&
Packit b099d7
	 (pevB1->y_root 	== pevB2->y_root) &&
Packit b099d7
	 (pevB1->state 		== pevB2->state) &&
Packit b099d7
	 (pevB1->button		== pevB2->button) &&
Packit b099d7
	 (pevB1->same_screen	== pevB2->same_screen) 
Packit b099d7
       )
Packit b099d7
    {
Packit b099d7
	rval = True;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    return (rval);
Packit b099d7
}
Packit b099d7
#endif /* WSM */