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