1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436 |
- /************************************************************
- Copyright 1987, 1998 The Open Group
- Permission to use, copy, modify, distribute, and sell this software and its
- documentation for any purpose is hereby granted without fee, provided that
- the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation.
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- Except as contained in this notice, the name of The Open Group shall not be
- used in advertising or otherwise to promote the sale, use or other dealings
- in this Software without prior written authorization from The Open Group.
- Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
- All Rights Reserved
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted,
- provided that the above copyright notice appear in all copies and that
- both that copyright notice and this permission notice appear in
- supporting documentation, and that the name of Digital not be
- used in advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
- DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- SOFTWARE.
- ********************************************************/
- /* The panoramix components contained the following notice */
- /*****************************************************************
- Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software.
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
- BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
- IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- Except as contained in this notice, the name of Digital Equipment Corporation
- shall not be used in advertising or otherwise to promote the sale, use or other
- dealings in this Software without prior written authorization from Digital
- Equipment Corporation.
- ******************************************************************/
- /*****************************************************************
- Copyright 2003-2005 Sun Microsystems, Inc.
- All rights reserved.
- Permission is hereby granted, free of charge, to any person obtaining a
- copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, and/or sell copies of the Software, and to permit persons
- to whom the Software is furnished to do so, provided that the above
- copyright notice(s) and this permission notice appear in all copies of
- the Software and that both the above copyright notice(s) and this
- permission notice appear in supporting documentation.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
- OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
- INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
- FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- Except as contained in this notice, the name of a copyright holder
- shall not be used in advertising or otherwise to promote the sale, use
- or other dealings in this Software without prior written authorization
- of the copyright holder.
- ******************************************************************/
- #ifdef HAVE_DIX_CONFIG_H
- #include <dix-config.h>
- #endif
- #include <X11/X.h>
- #include "misc.h"
- #include "resource.h"
- #include <X11/Xproto.h>
- #include "windowstr.h"
- #include "inputstr.h"
- #include "scrnintstr.h"
- #include "cursorstr.h"
- #include "dixstruct.h"
- #include "globals.h"
- #include <X11/extensions/XIproto.h>
- #include "exevents.h"
- #include "extnsionst.h"
- #include "dixevents.h"
- #include "dixgrabs.h"
- #include "dispatch.h"
- #define EXTENSION_EVENT_BASE 64
- #define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */
- #define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask )
- #define AllButtonsMask ( \
- Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
- #define MotionMask ( \
- PointerMotionMask | Button1MotionMask | \
- Button2MotionMask | Button3MotionMask | Button4MotionMask | \
- Button5MotionMask | ButtonMotionMask )
- #define PropagateMask ( \
- KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \
- MotionMask )
- #define PointerGrabMask ( \
- ButtonPressMask | ButtonReleaseMask | \
- EnterWindowMask | LeaveWindowMask | \
- PointerMotionHintMask | KeymapStateMask | \
- MotionMask )
- #define AllModifiersMask ( \
- ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
- Mod3Mask | Mod4Mask | Mod5Mask )
- #define AllEventMasks (lastEventMask|(lastEventMask-1))
- /*
- * The following relies on the fact that the Button<n>MotionMasks are equal
- * to the corresponding Button<n>Masks from the current modifier/button state.
- */
- #define Motion_Filter(class) (PointerMotionMask | \
- (class)->state | (class)->motionMask)
- #define WID(w) ((w) ? ((w)->drawable.id) : 0)
- #define XE_KBPTR (xE->u.keyButtonPointer)
- #define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
- _X_EXPORT CallbackListPtr EventCallback;
- _X_EXPORT CallbackListPtr DeviceEventCallback;
- #define DNPMCOUNT 8
- Mask DontPropagateMasks[DNPMCOUNT];
- static int DontPropagateRefCnts[DNPMCOUNT];
- #ifdef DEBUG
- static debug_events = 0;
- #endif
- _X_EXPORT InputInfo inputInfo;
- static struct {
- QdEventPtr pending, *pendtail;
- DeviceIntPtr replayDev; /* kludgy rock to put flag for */
- WindowPtr replayWin; /* ComputeFreezes */
- Bool playingEvents;
- TimeStamp time;
- } syncEvents;
- /*
- * The window trace information is used to avoid having to compute all the
- * windows between the root and the current pointer window each time a button
- * or key goes down. The grabs on each of those windows must be checked.
- */
- static WindowPtr *spriteTrace = (WindowPtr *) NULL;
- #define ROOT spriteTrace[0]
- static int spriteTraceSize = 0;
- static int spriteTraceGood;
- static struct {
- CursorPtr current;
- BoxRec hotLimits; /* logical constraints of hot spot */
- Bool confined; /* confined to screen */
- RegionPtr hotShape; /* additional logical shape constraint */
- BoxRec physLimits; /* physical constraints of hot spot */
- WindowPtr win; /* window of logical position */
- HotSpot hot; /* logical pointer position */
- HotSpot hotPhys; /* physical pointer position */
- } sprite; /* info about the cursor sprite */
- static void DoEnterLeaveEvents(WindowPtr fromWin, WindowPtr toWin, int mode);
- static WindowPtr XYToWindow(int x, int y);
- extern int lastEvent;
- static Mask lastEventMask;
- #define CantBeFiltered NoEventMask
- static Mask filters[128];
- static const Mask initialFilters[128] = {
- NoSuchEvent, /* 0 */
- NoSuchEvent, /* 1 */
- KeyPressMask, /* KeyPress */
- KeyReleaseMask, /* KeyRelease */
- ButtonPressMask, /* ButtonPress */
- ButtonReleaseMask, /* ButtonRelease */
- PointerMotionMask, /* MotionNotify (initial state) */
- EnterWindowMask, /* EnterNotify */
- LeaveWindowMask, /* LeaveNotify */
- FocusChangeMask, /* FocusIn */
- FocusChangeMask, /* FocusOut */
- KeymapStateMask, /* KeymapNotify */
- ExposureMask, /* Expose */
- CantBeFiltered, /* GraphicsExpose */
- CantBeFiltered, /* NoExpose */
- VisibilityChangeMask, /* VisibilityNotify */
- SubstructureNotifyMask, /* CreateNotify */
- StructureAndSubMask, /* DestroyNotify */
- StructureAndSubMask, /* UnmapNotify */
- StructureAndSubMask, /* MapNotify */
- SubstructureRedirectMask, /* MapRequest */
- StructureAndSubMask, /* ReparentNotify */
- StructureAndSubMask, /* ConfigureNotify */
- SubstructureRedirectMask, /* ConfigureRequest */
- StructureAndSubMask, /* GravityNotify */
- ResizeRedirectMask, /* ResizeRequest */
- StructureAndSubMask, /* CirculateNotify */
- SubstructureRedirectMask, /* CirculateRequest */
- PropertyChangeMask, /* PropertyNotify */
- CantBeFiltered, /* SelectionClear */
- CantBeFiltered, /* SelectionRequest */
- CantBeFiltered, /* SelectionNotify */
- ColormapChangeMask, /* ColormapNotify */
- CantBeFiltered, /* ClientMessage */
- CantBeFiltered /* MappingNotify */
- };
- static CARD8 criticalEvents[32] = {
- 0x7c /* key and button events */
- };
- void
- SetMaskForEvent(Mask mask, int event)
- {
- if ((event < LASTEvent) || (event >= 128))
- FatalError("SetMaskForEvent: bogus event number");
- filters[event] = mask;
- }
- _X_EXPORT void
- SetCriticalEvent(int event)
- {
- if (event >= 128)
- FatalError("SetCriticalEvent: bogus event number");
- criticalEvents[event >> 3] |= 1 << (event & 7);
- }
- static void
- SyntheticMotion(int x, int y)
- {
- xEvent xE;
- xE.u.keyButtonPointer.rootX = x;
- xE.u.keyButtonPointer.rootY = y;
- if (syncEvents.playingEvents)
- xE.u.keyButtonPointer.time = syncEvents.time.milliseconds;
- else
- xE.u.keyButtonPointer.time = currentTime.milliseconds;
- xE.u.u.type = MotionNotify;
- (*inputInfo.pointer->public.processInputProc) (&xE, inputInfo.pointer, 1);
- }
- static void
- ConfineToShape(RegionPtr shape, int *px, int *py)
- {
- BoxRec box;
- int x = *px, y = *py;
- int incx = 1, incy = 1;
- if (POINT_IN_REGION(shape, x, y, &box))
- return;
- box = *REGION_EXTENTS(shape);
- /* this is rather crude */
- do {
- x += incx;
- if (x >= box.x2) {
- incx = -1;
- x = *px - 1;
- }
- else if (x < box.x1) {
- incx = 1;
- x = *px;
- y += incy;
- if (y >= box.y2) {
- incy = -1;
- y = *py - 1;
- }
- else if (y < box.y1)
- return; /* should never get here! */
- }
- } while (!POINT_IN_REGION(shape, x, y, &box));
- *px = x;
- *py = y;
- }
- static void
- CheckPhysLimits(CursorPtr cursor,
- Bool generateEvents, Bool confineToScreen, ScreenPtr pScreen)
- {
- HotSpot new;
- if (!cursor)
- return;
- new = sprite.hotPhys;
- if (pScreen)
- new.pScreen = pScreen;
- else
- pScreen = new.pScreen;
- (*pScreen->CursorLimits) (pScreen, cursor, &sprite.hotLimits,
- &sprite.physLimits);
- sprite.confined = confineToScreen;
- (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits);
- if (new.x < sprite.physLimits.x1)
- new.x = sprite.physLimits.x1;
- else if (new.x >= sprite.physLimits.x2)
- new.x = sprite.physLimits.x2 - 1;
- if (new.y < sprite.physLimits.y1)
- new.y = sprite.physLimits.y1;
- else if (new.y >= sprite.physLimits.y2)
- new.y = sprite.physLimits.y2 - 1;
- if (sprite.hotShape)
- ConfineToShape(sprite.hotShape, &new.x, &new.y);
- if ((pScreen != sprite.hotPhys.pScreen) ||
- (new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y)) {
- if (pScreen != sprite.hotPhys.pScreen)
- sprite.hotPhys = new;
- (*pScreen->SetCursorPosition) (pScreen, new.x, new.y, generateEvents);
- if (!generateEvents)
- SyntheticMotion(new.x, new.y);
- }
- }
- static void
- CheckVirtualMotion(register QdEventPtr qe, register WindowPtr pWin)
- {
- if (qe) {
- sprite.hot.pScreen = qe->pScreen;
- sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
- sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
- pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
- NullWindow;
- }
- if (pWin) {
- BoxRec lims;
- if (sprite.hot.pScreen != pWin->drawable.pScreen) {
- sprite.hot.pScreen = pWin->drawable.pScreen;
- sprite.hot.x = sprite.hot.y = 0;
- }
- lims = *REGION_EXTENTS(&pWin->borderSize);
- if (sprite.hot.x < lims.x1)
- sprite.hot.x = lims.x1;
- else if (sprite.hot.x >= lims.x2)
- sprite.hot.x = lims.x2 - 1;
- if (sprite.hot.y < lims.y1)
- sprite.hot.y = lims.y1;
- else if (sprite.hot.y >= lims.y2)
- sprite.hot.y = lims.y2 - 1;
- if (wBoundingShape(pWin))
- ConfineToShape(&pWin->borderSize, &sprite.hot.x, &sprite.hot.y);
- if (qe) {
- qe->pScreen = sprite.hot.pScreen;
- qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
- qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
- }
- }
- ROOT = WindowTable[sprite.hot.pScreen->myNum];
- }
- static void
- ConfineCursorToWindow(WindowPtr pWin, Bool generateEvents, Bool confineToScreen)
- {
- ScreenPtr pScreen = pWin->drawable.pScreen;
- if (syncEvents.playingEvents) {
- CheckVirtualMotion((QdEventPtr) NULL, pWin);
- SyntheticMotion(sprite.hot.x, sprite.hot.y);
- }
- else {
- sprite.hotLimits = *REGION_EXTENTS(&pWin->borderSize);
- sprite.hotShape = wBoundingShape(pWin) ? &pWin->borderSize : NullRegion;
- CheckPhysLimits(sprite.current, generateEvents, confineToScreen,
- pScreen);
- }
- }
- _X_EXPORT Bool
- PointerConfinedToScreen()
- {
- return sprite.confined;
- }
- static void
- ChangeToCursor(CursorPtr cursor)
- {
- if (cursor != sprite.current) {
- if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
- (sprite.current->bits->yhot != cursor->bits->yhot))
- CheckPhysLimits(cursor, FALSE, sprite.confined, (ScreenPtr) NULL);
- (*sprite.hotPhys.pScreen->DisplayCursor) (sprite.hotPhys.pScreen,
- cursor);
- FreeCursor(sprite.current, (Cursor) 0);
- sprite.current = cursor;
- sprite.current->refcnt++;
- }
- }
- /* returns true if b is a descendent of a */
- Bool
- IsParent(register WindowPtr a, register WindowPtr b)
- {
- for (b = b->parent; b; b = b->parent)
- if (b == a)
- return TRUE;
- return FALSE;
- }
- static void
- PostNewCursor(void)
- {
- WindowPtr win;
- GrabPtr grab = inputInfo.pointer->grab;
- if (syncEvents.playingEvents)
- return;
- if (grab) {
- if (grab->cursor) {
- ChangeToCursor(grab->cursor);
- return;
- }
- if (IsParent(grab->window, sprite.win))
- win = sprite.win;
- else
- win = grab->window;
- }
- else
- win = sprite.win;
- for (; win; win = win->parent)
- if (win->optional && win->optional->cursor != NullCursor) {
- ChangeToCursor(win->optional->cursor);
- return;
- }
- }
- _X_EXPORT WindowPtr
- GetCurrentRootWindow()
- {
- return ROOT;
- }
- _X_EXPORT WindowPtr
- GetSpriteWindow()
- {
- return sprite.win;
- }
- _X_EXPORT CursorPtr
- GetSpriteCursor()
- {
- return sprite.current;
- }
- _X_EXPORT void
- GetSpritePosition(int *px, int *py)
- {
- *px = sprite.hotPhys.x;
- *py = sprite.hotPhys.y;
- }
- #define TIMESLOP (5 * 60 * 1000) /* 5 minutes */
- static void
- MonthChangedOrBadTime(register xEvent *xE)
- {
- /* If the ddx/OS is careless about not processing timestamped events from
- * different sources in sorted order, then it's possible for time to go
- * backwards when it should not. Here we ensure a decent time.
- */
- if ((currentTime.milliseconds - XE_KBPTR.time) > TIMESLOP)
- currentTime.months++;
- else
- XE_KBPTR.time = currentTime.milliseconds;
- }
- #define NoticeTime(xE) { \
- if ((xE)->u.keyButtonPointer.time < currentTime.milliseconds) \
- MonthChangedOrBadTime(xE); \
- currentTime.milliseconds = (xE)->u.keyButtonPointer.time; \
- lastDeviceEventTime = currentTime; }
- void
- NoticeEventTime(register xEvent *xE)
- {
- if (!syncEvents.playingEvents)
- NoticeTime(xE);
- }
- /**************************************************************************
- * The following procedures deal with synchronous events *
- **************************************************************************/
- void
- EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
- {
- QdEventPtr tail = *syncEvents.pendtail;
- QdEventPtr qe;
- xEvent *qxE;
- NoticeTime(xE);
- if (DeviceEventCallback) {
- DeviceEventInfoRec eventinfo;
- /* The RECORD spec says that the root window field of motion events
- * must be valid. At this point, it hasn't been filled in yet, so
- * we do it here. The long expression below is necessary to get
- * the current root window; the apparently reasonable alternative
- * GetCurrentRootWindow()->drawable.id doesn't give you the right
- * answer on the first motion event after a screen change because
- * the data that GetCurrentRootWindow relies on hasn't been
- * updated yet.
- */
- if (xE->u.u.type == MotionNotify)
- XE_KBPTR.root =
- WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
- eventinfo.events = xE;
- eventinfo.count = count;
- CallCallbacks(&DeviceEventCallback, (pointer) &eventinfo);
- }
- if (xE->u.u.type == MotionNotify) {
- sprite.hotPhys.x = XE_KBPTR.rootX;
- sprite.hotPhys.y = XE_KBPTR.rootY;
- /* do motion compression */
- if (tail &&
- (tail->event->u.u.type == MotionNotify) &&
- (tail->pScreen == sprite.hotPhys.pScreen)) {
- tail->event->u.keyButtonPointer.rootX = sprite.hotPhys.x;
- tail->event->u.keyButtonPointer.rootY = sprite.hotPhys.y;
- tail->event->u.keyButtonPointer.time = XE_KBPTR.time;
- tail->months = currentTime.months;
- return;
- }
- }
- qe = malloc(sizeof(QdEventRec) + (count * sizeof(xEvent)));
- if (!qe)
- return;
- qe->next = (QdEventPtr) NULL;
- qe->device = device;
- qe->pScreen = sprite.hotPhys.pScreen;
- qe->months = currentTime.months;
- qe->event = (xEvent *) (qe + 1);
- qe->evcount = count;
- for (qxE = qe->event; --count >= 0; qxE++, xE++)
- *qxE = *xE;
- if (tail)
- syncEvents.pendtail = &tail->next;
- *syncEvents.pendtail = qe;
- }
- static void
- PlayReleasedEvents(void)
- {
- QdEventPtr *prev, qe;
- DeviceIntPtr dev;
- prev = &syncEvents.pending;
- while ((qe = *prev)) {
- if (!qe->device->sync.frozen) {
- *prev = qe->next;
- if (*syncEvents.pendtail == *prev)
- syncEvents.pendtail = prev;
- if (qe->event->u.u.type == MotionNotify)
- CheckVirtualMotion(qe, NullWindow);
- syncEvents.time.months = qe->months;
- syncEvents.time.milliseconds = qe->event->u.keyButtonPointer.time;
- (*qe->device->public.processInputProc) (qe->event, qe->device,
- qe->evcount);
- free(qe);
- for (dev = inputInfo.devices; dev && dev->sync.frozen;
- dev = dev->next);
- if (!dev)
- break;
- /* Playing the event may have unfrozen another device. */
- /* So to play it safe, restart at the head of the queue */
- prev = &syncEvents.pending;
- }
- else
- prev = &qe->next;
- }
- }
- static void
- FreezeThaw(register DeviceIntPtr dev, Bool frozen)
- {
- dev->sync.frozen = frozen;
- if (frozen)
- dev->public.processInputProc = dev->public.enqueueInputProc;
- else
- dev->public.processInputProc = dev->public.realInputProc;
- }
- void
- ComputeFreezes()
- {
- DeviceIntPtr replayDev = syncEvents.replayDev;
- int i;
- WindowPtr w;
- xEvent *xE;
- int count;
- GrabPtr grab;
- DeviceIntPtr dev;
- for (dev = inputInfo.devices; dev; dev = dev->next)
- FreezeThaw(dev, dev->sync.other || (dev->sync.state >= FROZEN));
- if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending))
- return;
- syncEvents.playingEvents = TRUE;
- if (replayDev) {
- xE = replayDev->sync.event;
- count = replayDev->sync.evcount;
- syncEvents.replayDev = (DeviceIntPtr) NULL;
- w = XYToWindow(XE_KBPTR.rootX, XE_KBPTR.rootY);
- for (i = 0; i < spriteTraceGood; i++) {
- if (syncEvents.replayWin == spriteTrace[i]) {
- if (!CheckDeviceGrabs(replayDev, xE, i + 1, count)) {
- if (replayDev->focus)
- DeliverFocusedEvent(replayDev, xE, w, count);
- else
- DeliverDeviceEvents(w, xE, NullGrab, NullWindow,
- replayDev, count);
- }
- goto playmore;
- }
- }
- /* must not still be in the same stack */
- if (replayDev->focus)
- DeliverFocusedEvent(replayDev, xE, w, count);
- else
- DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count);
- }
- playmore:
- for (dev = inputInfo.devices; dev; dev = dev->next) {
- if (!dev->sync.frozen) {
- PlayReleasedEvents();
- break;
- }
- }
- syncEvents.playingEvents = FALSE;
- /* the following may have been skipped during replay, so do it now */
- if ((grab = inputInfo.pointer->grab) &&grab->confineTo) {
- if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
- sprite.hotPhys.x = sprite.hotPhys.y = 0;
- ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
- }
- else
- ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
- TRUE, FALSE);
- PostNewCursor();
- }
- void
- ScreenRestructured(ScreenPtr pScreen)
- {
- GrabPtr grab;
- if ((grab = inputInfo.pointer->grab) &&grab->confineTo) {
- if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
- sprite.hotPhys.x = sprite.hotPhys.y = 0;
- ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
- }
- else
- ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
- TRUE, FALSE);
- }
- void
- CheckGrabForSyncs(register DeviceIntPtr thisDev, Bool thisMode, Bool otherMode)
- {
- GrabPtr grab = thisDev->grab;
- DeviceIntPtr dev;
- if (thisMode == GrabModeSync)
- thisDev->sync.state = FROZEN_NO_EVENT;
- else { /* free both if same client owns both */
- thisDev->sync.state = THAWED;
- if (thisDev->sync.other &&
- (CLIENT_BITS(thisDev->sync.other->resource) ==
- CLIENT_BITS(grab->resource)))
- thisDev->sync.other = NullGrab;
- }
- for (dev = inputInfo.devices; dev; dev = dev->next) {
- if (dev != thisDev) {
- if (otherMode == GrabModeSync)
- dev->sync.other = grab;
- else { /* free both if same client owns both */
- if (dev->sync.other &&
- (CLIENT_BITS(dev->sync.other->resource) ==
- CLIENT_BITS(grab->resource)))
- dev->sync.other = NullGrab;
- }
- }
- }
- ComputeFreezes();
- }
- void
- ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab,
- TimeStamp time, Bool autoGrab)
- {
- WindowPtr oldWin = (mouse->grab) ? mouse->grab->window : sprite.win;
- if (grab->confineTo) {
- if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
- sprite.hotPhys.x = sprite.hotPhys.y = 0;
- ConfineCursorToWindow(grab->confineTo, FALSE, TRUE);
- }
- DoEnterLeaveEvents(oldWin, grab->window, NotifyGrab);
- mouse->valuator->motionHintWindow = NullWindow;
- if (syncEvents.playingEvents)
- mouse->grabTime = syncEvents.time;
- else
- mouse->grabTime = time;
- if (grab->cursor)
- grab->cursor->refcnt++;
- mouse->activeGrab = *grab;
- mouse->grab = &mouse->activeGrab;
- mouse->fromPassiveGrab = autoGrab;
- PostNewCursor();
- CheckGrabForSyncs(mouse, (Bool) grab->pointerMode,
- (Bool) grab->keyboardMode);
- }
- void
- DeactivatePointerGrab(register DeviceIntPtr mouse)
- {
- GrabPtr grab = mouse->grab;
- DeviceIntPtr dev;
- mouse->valuator->motionHintWindow = NullWindow;
- mouse->grab = NullGrab;
- mouse->sync.state = NOT_GRABBED;
- mouse->fromPassiveGrab = FALSE;
- for (dev = inputInfo.devices; dev; dev = dev->next) {
- if (dev->sync.other == grab)
- dev->sync.other = NullGrab;
- }
- DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab);
- if (grab->confineTo)
- ConfineCursorToWindow(ROOT, FALSE, FALSE);
- PostNewCursor();
- if (grab->cursor)
- FreeCursor(grab->cursor, (Cursor) 0);
- ComputeFreezes();
- }
- void
- ActivateKeyboardGrab(register DeviceIntPtr keybd, GrabPtr grab, TimeStamp time,
- Bool passive)
- {
- WindowPtr oldWin;
- if (keybd->grab)
- oldWin = keybd->grab->window;
- else if (keybd->focus)
- oldWin = keybd->focus->win;
- else
- oldWin = sprite.win;
- if (oldWin == FollowKeyboardWin)
- oldWin = inputInfo.keyboard->focus->win;
- if (keybd->valuator)
- keybd->valuator->motionHintWindow = NullWindow;
- DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab);
- if (syncEvents.playingEvents)
- keybd->grabTime = syncEvents.time;
- else
- keybd->grabTime = time;
- keybd->activeGrab = *grab;
- keybd->grab = &keybd->activeGrab;
- keybd->fromPassiveGrab = passive;
- CheckGrabForSyncs(keybd, (Bool) grab->keyboardMode,
- (Bool) grab->pointerMode);
- }
- void
- DeactivateKeyboardGrab(register DeviceIntPtr keybd)
- {
- GrabPtr grab = keybd->grab;
- DeviceIntPtr dev;
- WindowPtr focusWin = keybd->focus ? keybd->focus->win : sprite.win;
- if (focusWin == FollowKeyboardWin)
- focusWin = inputInfo.keyboard->focus->win;
- if (keybd->valuator)
- keybd->valuator->motionHintWindow = NullWindow;
- keybd->grab = NullGrab;
- keybd->sync.state = NOT_GRABBED;
- keybd->fromPassiveGrab = FALSE;
- for (dev = inputInfo.devices; dev; dev = dev->next) {
- if (dev->sync.other == grab)
- dev->sync.other = NullGrab;
- }
- DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
- ComputeFreezes();
- }
- void
- AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState)
- {
- Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced;
- TimeStamp grabTime;
- DeviceIntPtr dev;
- thisGrabbed = thisDev->grab && SameClient(thisDev->grab, client);
- thisSynced = FALSE;
- otherGrabbed = FALSE;
- othersFrozen = TRUE;
- grabTime = thisDev->grabTime;
- for (dev = inputInfo.devices; dev; dev = dev->next) {
- if (dev == thisDev)
- continue;
- if (dev->grab && SameClient(dev->grab, client)) {
- if (!(thisGrabbed || otherGrabbed) ||
- (CompareTimeStamps(dev->grabTime, grabTime) == LATER))
- grabTime = dev->grabTime;
- otherGrabbed = TRUE;
- if (thisDev->sync.other == dev->grab)
- thisSynced = TRUE;
- if (dev->sync.state < FROZEN)
- othersFrozen = FALSE;
- }
- else if (!dev->sync.other || !SameClient(dev->sync.other, client))
- othersFrozen = FALSE;
- }
- if (!((thisGrabbed && thisDev->sync.state >= FROZEN) || thisSynced))
- return;
- if ((CompareTimeStamps(time, currentTime) == LATER) ||
- (CompareTimeStamps(time, grabTime) == EARLIER))
- return;
- switch (newState) {
- case THAWED: /* Async */
- if (thisGrabbed)
- thisDev->sync.state = THAWED;
- if (thisSynced)
- thisDev->sync.other = NullGrab;
- ComputeFreezes();
- break;
- case FREEZE_NEXT_EVENT: /* Sync */
- if (thisGrabbed) {
- thisDev->sync.state = FREEZE_NEXT_EVENT;
- if (thisSynced)
- thisDev->sync.other = NullGrab;
- ComputeFreezes();
- }
- break;
- case THAWED_BOTH: /* AsyncBoth */
- if (othersFrozen) {
- for (dev = inputInfo.devices; dev; dev = dev->next) {
- if (dev->grab && SameClient(dev->grab, client))
- dev->sync.state = THAWED;
- if (dev->sync.other && SameClient(dev->sync.other, client))
- dev->sync.other = NullGrab;
- }
- ComputeFreezes();
- }
- break;
- case FREEZE_BOTH_NEXT_EVENT: /* SyncBoth */
- if (othersFrozen) {
- for (dev = inputInfo.devices; dev; dev = dev->next) {
- if (dev->grab && SameClient(dev->grab, client))
- dev->sync.state = FREEZE_BOTH_NEXT_EVENT;
- if (dev->sync.other && SameClient(dev->sync.other, client))
- dev->sync.other = NullGrab;
- }
- ComputeFreezes();
- }
- break;
- case NOT_GRABBED: /* Replay */
- if (thisGrabbed && thisDev->sync.state == FROZEN_WITH_EVENT) {
- if (thisSynced)
- thisDev->sync.other = NullGrab;
- syncEvents.replayDev = thisDev;
- syncEvents.replayWin = thisDev->grab->window;
- (*thisDev->DeactivateGrab) (thisDev);
- syncEvents.replayDev = (DeviceIntPtr) NULL;
- }
- break;
- case THAW_OTHERS: /* AsyncOthers */
- if (othersFrozen) {
- for (dev = inputInfo.devices; dev; dev = dev->next) {
- if (dev == thisDev)
- continue;
- if (dev->grab && SameClient(dev->grab, client))
- dev->sync.state = THAWED;
- if (dev->sync.other && SameClient(dev->sync.other, client))
- dev->sync.other = NullGrab;
- }
- ComputeFreezes();
- }
- break;
- }
- }
- int
- ProcAllowEvents(register ClientPtr client)
- {
- TimeStamp time;
- DeviceIntPtr mouse = inputInfo.pointer;
- DeviceIntPtr keybd = inputInfo.keyboard;
- REQUEST(xAllowEventsReq);
- REQUEST_SIZE_MATCH(xAllowEventsReq);
- time = ClientTimeToServerTime(stuff->time);
- switch (stuff->mode) {
- case ReplayPointer:
- AllowSome(client, time, mouse, NOT_GRABBED);
- break;
- case SyncPointer:
- AllowSome(client, time, mouse, FREEZE_NEXT_EVENT);
- break;
- case AsyncPointer:
- AllowSome(client, time, mouse, THAWED);
- break;
- case ReplayKeyboard:
- AllowSome(client, time, keybd, NOT_GRABBED);
- break;
- case SyncKeyboard:
- AllowSome(client, time, keybd, FREEZE_NEXT_EVENT);
- break;
- case AsyncKeyboard:
- AllowSome(client, time, keybd, THAWED);
- break;
- case SyncBoth:
- AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT);
- break;
- case AsyncBoth:
- AllowSome(client, time, keybd, THAWED_BOTH);
- break;
- default:
- client->errorValue = stuff->mode;
- return BadValue;
- }
- return Success;
- }
- void
- ReleaseActiveGrabs(ClientPtr client)
- {
- DeviceIntPtr dev;
- Bool done;
- /* XXX CloseDownClient should remove passive grabs before
- * releasing active grabs.
- */
- do {
- done = TRUE;
- for (dev = inputInfo.devices; dev; dev = dev->next) {
- if (dev->grab && SameClient(dev->grab, client)) {
- (*dev->DeactivateGrab) (dev);
- done = FALSE;
- }
- }
- } while (!done);
- }
- /**************************************************************************
- * The following procedures deal with delivering events *
- **************************************************************************/
- _X_EXPORT int
- TryClientEvents(ClientPtr client, xEvent *pEvents, int count, Mask mask,
- Mask filter, GrabPtr grab)
- {
- int type;
- #ifdef DEBUG
- if (debug_events)
- ErrorF("Event([%d, %d], mask=0x%x), client=%d",
- pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
- #endif
- if ((client) && (client != serverClient) && (!client->clientGone) &&
- ((filter == CantBeFiltered) || (mask & filter))) {
- if (grab && !SameClient(grab, client))
- return -1; /* don't send, but notify caller */
- type = pEvents->u.u.type;
- if (type == MotionNotify) {
- if (mask & PointerMotionHintMask) {
- if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
- pEvents->u.keyButtonPointer.event) {
- #ifdef DEBUG
- if (debug_events)
- ErrorF("\n");
- fprintf(stderr,
- "motionHintWindow == keyButtonPointer.event\n");
- #endif
- return 1; /* don't send, but pretend we did */
- }
- pEvents->u.u.detail = NotifyHint;
- }
- else {
- pEvents->u.u.detail = NotifyNormal;
- }
- }
- if (BitIsOn(criticalEvents, type)) {
- #ifdef SMART_SCHEDULE
- if (client->smart_priority < SMART_MAX_PRIORITY)
- client->smart_priority++;
- #endif
- SetCriticalOutputPending();
- }
- WriteEventsToClient(client, count, pEvents);
- #ifdef DEBUG
- if (debug_events)
- ErrorF(" delivered\n");
- #endif
- return 1;
- }
- else {
- #ifdef DEBUG
- if (debug_events)
- ErrorF("\n");
- #endif
- return 0;
- }
- }
- int
- DeliverEventsToWindow(register WindowPtr pWin, xEvent *pEvents, int count,
- Mask filter, GrabPtr grab, int mskidx)
- {
- int deliveries = 0, nondeliveries = 0;
- int attempt;
- InputClients *other;
- ClientPtr client = NullClient;
- Mask deliveryMask = 0; /* If a grab occurs due to a button press, then
- this mask is the mask of the grab. */
- int type = pEvents->u.u.type;
- /* CantBeFiltered means only window owner gets the event */
- if ((filter == CantBeFiltered) || !(type & EXTENSION_EVENT_BASE)) {
- /* if nobody ever wants to see this event, skip some work */
- if (filter != CantBeFiltered &&
- !((wOtherEventMasks(pWin) | pWin->eventMask) & filter))
- return 0;
- if ((attempt = TryClientEvents(wClient(pWin), pEvents, count,
- pWin->eventMask, filter, grab))) {
- if (attempt > 0) {
- deliveries++;
- client = wClient(pWin);
- deliveryMask = pWin->eventMask;
- }
- else
- nondeliveries--;
- }
- }
- if (filter != CantBeFiltered) {
- if (type & EXTENSION_EVENT_BASE) {
- OtherInputMasks *inputMasks;
- inputMasks = wOtherInputMasks(pWin);
- if (!inputMasks || !(inputMasks->inputEvents[mskidx] & filter))
- return 0;
- other = inputMasks->inputClients;
- }
- else
- other = (InputClients *) wOtherClients(pWin);
- for (; other; other = other->next) {
- if ((attempt = TryClientEvents(rClient(other), pEvents, count,
- other->mask[mskidx], filter, grab)))
- {
- if (attempt > 0) {
- deliveries++;
- client = rClient(other);
- deliveryMask = other->mask[mskidx];
- }
- else
- nondeliveries--;
- }
- }
- }
- if ((type == ButtonPress) && deliveries && (!grab)) {
- GrabRec tempGrab;
- tempGrab.device = inputInfo.pointer;
- tempGrab.resource = client->clientAsMask;
- tempGrab.window = pWin;
- tempGrab.ownerEvents =
- (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
- tempGrab.eventMask = deliveryMask;
- tempGrab.keyboardMode = GrabModeAsync;
- tempGrab.pointerMode = GrabModeAsync;
- tempGrab.confineTo = NullWindow;
- tempGrab.cursor = NullCursor;
- (*inputInfo.pointer->ActivateGrab) (inputInfo.pointer, &tempGrab,
- currentTime, TRUE);
- }
- else if ((type == MotionNotify) && deliveries)
- inputInfo.pointer->valuator->motionHintWindow = pWin;
- if (deliveries)
- return deliveries;
- return nondeliveries;
- }
- /* If the event goes to dontClient, don't send it and return 0. if
- send works, return 1 or if send didn't work, return 2.
- Only works for core events.
- */
- int
- MaybeDeliverEventsToClient(register WindowPtr pWin, xEvent *pEvents,
- int count, Mask filter, ClientPtr dontClient)
- {
- OtherClients *other;
- if (pWin->eventMask & filter) {
- if (wClient(pWin) == dontClient)
- return 0;
- return TryClientEvents(wClient(pWin), pEvents, count,
- pWin->eventMask, filter, NullGrab);
- }
- for (other = wOtherClients(pWin); other; other = other->next) {
- if (other->mask & filter) {
- if (SameClient(other, dontClient))
- return 0;
- return TryClientEvents(rClient(other), pEvents, count,
- other->mask, filter, NullGrab);
- }
- }
- return 2;
- }
- static void
- FixUpEventFromWindow(xEvent *xE, WindowPtr pWin, Window child, Bool calcChild)
- {
- if (calcChild) {
- WindowPtr w = spriteTrace[spriteTraceGood - 1];
- /* If the search ends up past the root should the child field be
- set to none or should the value in the argument be passed
- through. It probably doesn't matter since everyone calls
- this function with child == None anyway. */
- while (w) {
- /* If the source window is same as event window, child should be
- none. Don't bother going all all the way back to the root. */
- if (w == pWin) {
- child = None;
- break;
- }
- if (w->parent == pWin) {
- child = w->drawable.id;
- break;
- }
- w = w->parent;
- }
- }
- XE_KBPTR.root = ROOT->drawable.id;
- XE_KBPTR.event = pWin->drawable.id;
- if (sprite.hot.pScreen == pWin->drawable.pScreen) {
- XE_KBPTR.sameScreen = xTrue;
- XE_KBPTR.child = child;
- XE_KBPTR.eventX = XE_KBPTR.rootX - pWin->drawable.x;
- XE_KBPTR.eventY = XE_KBPTR.rootY - pWin->drawable.y;
- }
- else {
- XE_KBPTR.sameScreen = xFalse;
- XE_KBPTR.child = None;
- XE_KBPTR.eventX = 0;
- XE_KBPTR.eventY = 0;
- }
- }
- int
- DeliverDeviceEvents(register WindowPtr pWin, register xEvent *xE, GrabPtr grab,
- register WindowPtr stopAt, DeviceIntPtr dev, int count)
- {
- Window child = None;
- int type = xE->u.u.type;
- Mask filter = filters[type];
- int deliveries = 0;
- if (type & EXTENSION_EVENT_BASE) {
- OtherInputMasks *inputMasks;
- int mskidx = dev->id;
- inputMasks = wOtherInputMasks(pWin);
- if (inputMasks && !(filter & inputMasks->deliverableEvents[mskidx]))
- return 0;
- while (pWin) {
- if (inputMasks && (inputMasks->inputEvents[mskidx] & filter)) {
- FixUpEventFromWindow(xE, pWin, child, FALSE);
- deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
- grab, mskidx);
- if (deliveries > 0)
- return deliveries;
- }
- if ((deliveries < 0) ||
- (pWin == stopAt) ||
- (inputMasks &&
- (filter & inputMasks->dontPropagateMask[mskidx])))
- return 0;
- child = pWin->drawable.id;
- pWin = pWin->parent;
- if (pWin)
- inputMasks = wOtherInputMasks(pWin);
- }
- }
- else {
- if (!(filter & pWin->deliverableEvents))
- return 0;
- while (pWin) {
- if ((wOtherEventMasks(pWin) | pWin->eventMask) & filter) {
- FixUpEventFromWindow(xE, pWin, child, FALSE);
- deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
- grab, 0);
- if (deliveries > 0)
- return deliveries;
- }
- if ((deliveries < 0) ||
- (pWin == stopAt) || (filter & wDontPropagateMask(pWin)))
- return 0;
- child = pWin->drawable.id;
- pWin = pWin->parent;
- }
- }
- return 0;
- }
- /* not useful for events that propagate up the tree or extension events */
- _X_EXPORT int
- DeliverEvents(register WindowPtr pWin, register xEvent *xE, int count,
- register WindowPtr otherParent)
- {
- Mask filter;
- int deliveries;
- if (!count)
- return 0;
- filter = filters[xE->u.u.type];
- if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
- xE->u.destroyNotify.event = pWin->drawable.id;
- if (filter != StructureAndSubMask)
- return DeliverEventsToWindow(pWin, xE, count, filter, NullGrab, 0);
- deliveries = DeliverEventsToWindow(pWin, xE, count, StructureNotifyMask,
- NullGrab, 0);
- if (pWin->parent) {
- xE->u.destroyNotify.event = pWin->parent->drawable.id;
- deliveries += DeliverEventsToWindow(pWin->parent, xE, count,
- SubstructureNotifyMask, NullGrab,
- 0);
- if (xE->u.u.type == ReparentNotify) {
- xE->u.destroyNotify.event = otherParent->drawable.id;
- deliveries += DeliverEventsToWindow(otherParent, xE, count,
- SubstructureNotifyMask,
- NullGrab, 0);
- }
- }
- return deliveries;
- }
- static Bool
- PointInBorderSize(WindowPtr pWin, int x, int y)
- {
- BoxRec box;
- if (POINT_IN_REGION(&pWin->borderSize, x, y, &box))
- return TRUE;
- return FALSE;
- }
- static WindowPtr
- XYToWindow(int x, int y)
- {
- WindowPtr pWin;
- BoxRec box;
- spriteTraceGood = 1; /* root window still there */
- pWin = ROOT->firstChild;
- while (pWin) {
- if ((pWin->mapped) &&
- (x >= pWin->drawable.x - wBorderWidth(pWin)) &&
- (x < pWin->drawable.x + (int) pWin->drawable.width +
- wBorderWidth(pWin)) &&
- (y >= pWin->drawable.y - wBorderWidth(pWin)) &&
- (y < pWin->drawable.y + (int) pWin->drawable.height +
- wBorderWidth(pWin))
- /* When a window is shaped, a further check
- * is made to see if the point is inside
- * borderSize
- */
- && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
- && (!wInputShape(pWin) ||
- POINT_IN_REGION(
- wInputShape(pWin),
- x - pWin->drawable.x,
- y - pWin->drawable.y, &box))
- ) {
- if (spriteTraceGood >= spriteTraceSize) {
- spriteTraceSize += 10;
- Must_have_memory = TRUE; /* XXX */
- spriteTrace =
- (WindowPtr *) realloc(spriteTrace,
- spriteTraceSize * sizeof(WindowPtr));
- Must_have_memory = FALSE; /* XXX */
- }
- spriteTrace[spriteTraceGood++] = pWin;
- pWin = pWin->firstChild;
- }
- else
- pWin = pWin->nextSib;
- }
- return spriteTrace[spriteTraceGood - 1];
- }
- static Bool
- CheckMotion(xEvent *xE)
- {
- WindowPtr prevSpriteWin = sprite.win;
- if (xE && !syncEvents.playingEvents) {
- if (sprite.hot.pScreen != sprite.hotPhys.pScreen) {
- sprite.hot.pScreen = sprite.hotPhys.pScreen;
- ROOT = WindowTable[sprite.hot.pScreen->myNum];
- }
- sprite.hot.x = XE_KBPTR.rootX;
- sprite.hot.y = XE_KBPTR.rootY;
- if (sprite.hot.x < sprite.physLimits.x1)
- sprite.hot.x = sprite.physLimits.x1;
- else if (sprite.hot.x >= sprite.physLimits.x2)
- sprite.hot.x = sprite.physLimits.x2 - 1;
- if (sprite.hot.y < sprite.physLimits.y1)
- sprite.hot.y = sprite.physLimits.y1;
- else if (sprite.hot.y >= sprite.physLimits.y2)
- sprite.hot.y = sprite.physLimits.y2 - 1;
- if (sprite.hotShape)
- ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
- sprite.hotPhys = sprite.hot;
- if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
- (sprite.hotPhys.y != XE_KBPTR.rootY)) {
- (*sprite.hotPhys.pScreen->SetCursorPosition) (sprite.hotPhys.
- pScreen,
- sprite.hotPhys.x,
- sprite.hotPhys.y,
- FALSE);
- }
- XE_KBPTR.rootX = sprite.hot.x;
- XE_KBPTR.rootY = sprite.hot.y;
- }
- sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
- #ifdef notyet
- if (!(sprite.win->deliverableEvents &
- Motion_Filter(inputInfo.pointer->button))
- ! syncEvents.playingEvents) {
- /* XXX Do PointerNonInterestBox here */
- }
- #endif
- if (sprite.win != prevSpriteWin) {
- if (prevSpriteWin != NullWindow) {
- if (!xE)
- UpdateCurrentTimeIf();
- DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
- }
- PostNewCursor();
- return FALSE;
- }
- return TRUE;
- }
- _X_EXPORT void
- WindowsRestructured()
- {
- (void) CheckMotion((xEvent *) NULL);
- }
- void
- DefineInitialRootWindow(register WindowPtr win)
- {
- ScreenPtr pScreen = win->drawable.pScreen;
- sprite.hotPhys.pScreen = pScreen;
- sprite.hotPhys.x = pScreen->width / 2;
- sprite.hotPhys.y = pScreen->height / 2;
- sprite.hot = sprite.hotPhys;
- sprite.hotLimits.x2 = pScreen->width;
- sprite.hotLimits.y2 = pScreen->height;
- sprite.win = win;
- sprite.current = wCursor(win);
- sprite.current->refcnt++;
- spriteTraceGood = 1;
- ROOT = win;
- (*pScreen->CursorLimits) (pScreen, sprite.current, &sprite.hotLimits,
- &sprite.physLimits);
- sprite.confined = FALSE;
- (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits);
- (*pScreen->SetCursorPosition) (pScreen, sprite.hot.x, sprite.hot.y, FALSE);
- (*pScreen->DisplayCursor) (pScreen, sprite.current);
- }
- /*
- * This does not take any shortcuts, and even ignores its argument, since
- * it does not happen very often, and one has to walk up the tree since
- * this might be a newly instantiated cursor for an intermediate window
- * between the one the pointer is in and the one that the last cursor was
- * instantiated from.
- */
- void
- WindowHasNewCursor(WindowPtr pWin)
- {
- PostNewCursor();
- }
- _X_EXPORT void
- NewCurrentScreen(ScreenPtr newScreen, int x, int y)
- {
- sprite.hotPhys.x = x;
- sprite.hotPhys.y = y;
- if (newScreen != sprite.hotPhys.pScreen)
- ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE, FALSE);
- }
- int
- ProcWarpPointer(ClientPtr client)
- {
- WindowPtr dest = NULL;
- int x, y;
- ScreenPtr newScreen;
- REQUEST(xWarpPointerReq);
- REQUEST_SIZE_MATCH(xWarpPointerReq);
- if (stuff->dstWid != None) {
- dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
- if (!dest)
- return BadWindow;
- }
- x = sprite.hotPhys.x;
- y = sprite.hotPhys.y;
- if (stuff->srcWid != None) {
- int winX, winY;
- XID winID = stuff->srcWid;
- WindowPtr source;
- source = SecurityLookupWindow(winID, client, SecurityReadAccess);
- if (!source)
- return BadWindow;
- winX = source->drawable.x;
- winY = source->drawable.y;
- if (source->drawable.pScreen != sprite.hotPhys.pScreen ||
- x < winX + stuff->srcX ||
- y < winY + stuff->srcY ||
- (stuff->srcWidth != 0 &&
- winX + stuff->srcX + (int) stuff->srcWidth < x) ||
- (stuff->srcHeight != 0 &&
- winY + stuff->srcY + (int) stuff->srcHeight < y) ||
- !PointInWindowIsVisible(source, x, y))
- return Success;
- }
- if (dest) {
- x = dest->drawable.x;
- y = dest->drawable.y;
- newScreen = dest->drawable.pScreen;
- }
- else
- newScreen = sprite.hotPhys.pScreen;
- x += stuff->dstX;
- y += stuff->dstY;
- if (x < 0)
- x = 0;
- else if (x >= newScreen->width)
- x = newScreen->width - 1;
- if (y < 0)
- y = 0;
- else if (y >= newScreen->height)
- y = newScreen->height - 1;
- if (newScreen == sprite.hotPhys.pScreen) {
- if (x < sprite.physLimits.x1)
- x = sprite.physLimits.x1;
- else if (x >= sprite.physLimits.x2)
- x = sprite.physLimits.x2 - 1;
- if (y < sprite.physLimits.y1)
- y = sprite.physLimits.y1;
- else if (y >= sprite.physLimits.y2)
- y = sprite.physLimits.y2 - 1;
- if (sprite.hotShape)
- ConfineToShape(sprite.hotShape, &x, &y);
- (*newScreen->SetCursorPosition) (newScreen, x, y, TRUE);
- }
- else if (!PointerConfinedToScreen()) {
- NewCurrentScreen(newScreen, x, y);
- }
- return Success;
- }
- static Bool
- BorderSizeNotEmpty(WindowPtr pWin)
- {
- if (REGION_NOTEMPTY(&pWin->borderSize))
- return TRUE;
- return FALSE;
- }
- /* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
- passive grab set on the window to be activated. */
- static Bool
- CheckPassiveGrabsOnWindow(WindowPtr pWin,
- register DeviceIntPtr device,
- register xEvent *xE, int count)
- {
- GrabPtr grab = wPassiveGrabs(pWin);
- GrabRec tempGrab;
- xEvent *dxE;
- if (!grab)
- return FALSE;
- tempGrab.window = pWin;
- tempGrab.device = device;
- tempGrab.type = xE->u.u.type;
- tempGrab.detail.exact = xE->u.u.detail;
- tempGrab.detail.pMask = NULL;
- tempGrab.modifiersDetail.pMask = NULL;
- for (; grab; grab = grab->next) {
- tempGrab.modifierDevice = grab->modifierDevice;
- if ((device == grab->modifierDevice) && ((xE->u.u.type == KeyPress)
- ))
- tempGrab.modifiersDetail.exact =
- grab->modifierDevice->key->prev_state;
- else
- tempGrab.modifiersDetail.exact =
- grab->modifierDevice->key->state;
- if (GrabMatchesSecond(&tempGrab, grab) &&
- (!grab->confineTo ||
- (grab->confineTo->realized &&
- BorderSizeNotEmpty(grab->confineTo)))) {
- (*device->ActivateGrab) (device, grab, currentTime, TRUE);
- FixUpEventFromWindow(xE, grab->window, None, TRUE);
- (void) TryClientEvents(rClient(grab), xE, count,
- filters[xE->u.u.type],
- filters[xE->u.u.type], grab);
- if (device->sync.state == FROZEN_NO_EVENT) {
- if (device->sync.evcount < count) {
- Must_have_memory = TRUE; /* XXX */
- device->sync.event = (xEvent *) realloc(device->sync.event,
- count *
- sizeof(xEvent));
- Must_have_memory = FALSE; /* XXX */
- }
- device->sync.evcount = count;
- for (dxE = device->sync.event; --count >= 0; dxE++, xE++)
- *dxE = *xE;
- device->sync.state = FROZEN_WITH_EVENT;
- }
- return TRUE;
- }
- }
- return FALSE;
- }
- /**
- "CheckDeviceGrabs" handles both keyboard and pointer events that may cause
- a passive grab to be activated. If the event is a keyboard event, the
- ancestors of the focus window are traced down and tried to see if they have
- any passive grabs to be activated. If the focus window itself is reached and
- it's descendants contain they pointer, the ancestors of the window that the
- pointer is in are then traced down starting at the focus window, otherwise no
- grabs are activated. If the event is a pointer event, the ancestors of the
- window that the pointer is in are traced down starting at the root until
- CheckPassiveGrabs causes a passive grab to activate or all the windows are
- tried. PRH
- */
- Bool
- CheckDeviceGrabs(register DeviceIntPtr device, register xEvent *xE,
- int checkFirst, int count)
- {
- int i;
- WindowPtr pWin = NULL;
- FocusClassPtr focus = device->focus;
- if (((xE->u.u.type == ButtonPress)
- ) && (device->button->buttonsDown != 1))
- return FALSE;
- i = checkFirst;
- if (focus) {
- for (; i < focus->traceGood; i++) {
- pWin = focus->trace[i];
- if (pWin->optional &&
- CheckPassiveGrabsOnWindow(pWin, device, xE, count))
- return TRUE;
- }
- if ((focus->win == NoneWin) ||
- (i >= spriteTraceGood) ||
- ((i > checkFirst) && (pWin != spriteTrace[i - 1])))
- return FALSE;
- }
- for (; i < spriteTraceGood; i++) {
- pWin = spriteTrace[i];
- if (pWin->optional &&
- CheckPassiveGrabsOnWindow(pWin, device, xE, count))
- return TRUE;
- }
- return FALSE;
- }
- void
- DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
- {
- WindowPtr focus = keybd->focus->win;
- int mskidx = 0;
- if (focus == FollowKeyboardWin)
- focus = inputInfo.keyboard->focus->win;
- if (!focus)
- return;
- if (focus == PointerRootWin) {
- DeliverDeviceEvents(window, xE, NullGrab, NullWindow, keybd, count);
- return;
- }
- if ((focus == window) || IsParent(focus, window)) {
- if (DeliverDeviceEvents(window, xE, NullGrab, focus, keybd, count))
- return;
- }
- /* just deliver it to the focus window */
- FixUpEventFromWindow(xE, focus, None, FALSE);
- if (xE->u.u.type & EXTENSION_EVENT_BASE)
- mskidx = keybd->id;
- (void) DeliverEventsToWindow(focus, xE, count, filters[xE->u.u.type],
- NullGrab, mskidx);
- }
- void
- DeliverGrabbedEvent(register xEvent *xE, register DeviceIntPtr thisDev,
- Bool deactivateGrab, int count)
- {
- GrabPtr grab = thisDev->grab;
- int deliveries = 0;
- DeviceIntPtr dev;
- xEvent *dxE;
- if (grab->ownerEvents) {
- WindowPtr focus;
- if (thisDev->focus) {
- focus = thisDev->focus->win;
- if (focus == FollowKeyboardWin)
- focus = inputInfo.keyboard->focus->win;
- }
- else
- focus = PointerRootWin;
- if (focus == PointerRootWin)
- deliveries = DeliverDeviceEvents(sprite.win, xE, grab, NullWindow,
- thisDev, count);
- else if (focus && (focus == sprite.win || IsParent(focus, sprite.win)))
- deliveries = DeliverDeviceEvents(sprite.win, xE, grab, focus,
- thisDev, count);
- else if (focus)
- deliveries = DeliverDeviceEvents(focus, xE, grab, focus,
- thisDev, count);
- }
- if (!deliveries) {
- FixUpEventFromWindow(xE, grab->window, None, TRUE);
- deliveries = TryClientEvents(rClient(grab), xE, count,
- (Mask) grab->eventMask,
- filters[xE->u.u.type], grab);
- if (deliveries && (xE->u.u.type == MotionNotify
- ))
- thisDev->valuator->motionHintWindow = grab->window;
- }
- if (deliveries && !deactivateGrab && (xE->u.u.type != MotionNotify
- ))
- switch (thisDev->sync.state) {
- case FREEZE_BOTH_NEXT_EVENT:
- for (dev = inputInfo.devices; dev; dev = dev->next) {
- if (dev == thisDev)
- continue;
- FreezeThaw(dev, TRUE);
- if ((dev->sync.state == FREEZE_BOTH_NEXT_EVENT) &&
- (CLIENT_BITS(dev->grab->resource) ==
- CLIENT_BITS(thisDev->grab->resource)))
- dev->sync.state = FROZEN_NO_EVENT;
- else
- dev->sync.other = thisDev->grab;
- }
- /* fall through */
- case FREEZE_NEXT_EVENT:
- thisDev->sync.state = FROZEN_WITH_EVENT;
- FreezeThaw(thisDev, TRUE);
- if (thisDev->sync.evcount < count) {
- Must_have_memory = TRUE; /* XXX */
- thisDev->sync.event = (xEvent *) realloc(thisDev->sync.event,
- count *
- sizeof(xEvent));
- Must_have_memory = FALSE; /* XXX */
- }
- thisDev->sync.evcount = count;
- for (dxE = thisDev->sync.event; --count >= 0; dxE++, xE++)
- *dxE = *xE;
- break;
- }
- }
- void
- ProcessKeyboardEvent(register xEvent *xE, register DeviceIntPtr keybd,
- int count)
- {
- int key, bit;
- BYTE *kptr;
- int i;
- CARD8 modifiers;
- CARD16 mask;
- GrabPtr grab = keybd->grab;
- Bool deactivateGrab = FALSE;
- KeyClassPtr keyc = keybd->key;
- if (!syncEvents.playingEvents) {
- NoticeTime(xE);
- if (DeviceEventCallback) {
- DeviceEventInfoRec eventinfo;
- eventinfo.events = xE;
- eventinfo.count = count;
- CallCallbacks(&DeviceEventCallback, (pointer) &eventinfo);
- }
- }
- XE_KBPTR.state = (keyc->state | inputInfo.pointer->button->state);
- XE_KBPTR.rootX = sprite.hot.x;
- XE_KBPTR.rootY = sprite.hot.y;
- key = xE->u.u.detail;
- kptr = &keyc->down[key >> 3];
- bit = 1 << (key & 7);
- modifiers = keyc->modifierMap[key];
- #ifdef DEBUG
- if ((xkbDebugFlags & 0x4) &&
- ((xE->u.u.type == KeyPress) || (xE->u.u.type == KeyRelease))) {
- ErrorF("CoreProcessKbdEvent: Key %d %s\n", key,
- (xE->u.u.type == KeyPress ? "down" : "up"));
- }
- #endif
- switch (xE->u.u.type) {
- case KeyPress:
- if (*kptr & bit) { /* allow ddx to generate multiple downs */
- if (!modifiers) {
- xE->u.u.type = KeyRelease;
- (*keybd->public.processInputProc) (xE, keybd, count);
- xE->u.u.type = KeyPress;
- /* release can have side effects, don't fall through */
- (*keybd->public.processInputProc) (xE, keybd, count);
- }
- return;
- }
- inputInfo.pointer->valuator->motionHintWindow = NullWindow;
- *kptr |= bit;
- keyc->prev_state = keyc->state;
- for (i = 0, mask = 1; modifiers; i++, mask <<= 1) {
- if (mask & modifiers) {
- /* This key affects modifier "i" */
- keyc->modifierKeyCount[i]++;
- keyc->state |= mask;
- modifiers &= ~mask;
- }
- }
- if (!grab && CheckDeviceGrabs(keybd, xE, 0, count)) {
- keybd->activatingKey = key;
- return;
- }
- break;
- case KeyRelease:
- if (!(*kptr & bit)) /* guard against duplicates */
- return;
- inputInfo.pointer->valuator->motionHintWindow = NullWindow;
- *kptr &= ~bit;
- keyc->prev_state = keyc->state;
- for (i = 0, mask = 1; modifiers; i++, mask <<= 1) {
- if (mask & modifiers) {
- /* This key affects modifier "i" */
- if (--keyc->modifierKeyCount[i] <= 0) {
- keyc->state &= ~mask;
- keyc->modifierKeyCount[i] = 0;
- }
- modifiers &= ~mask;
- }
- }
- if (keybd->fromPassiveGrab && (key == keybd->activatingKey))
- deactivateGrab = TRUE;
- break;
- default:
- FatalError("Impossible keyboard event");
- }
- if (grab)
- DeliverGrabbedEvent(xE, keybd, deactivateGrab, count);
- else
- DeliverFocusedEvent(keybd, xE, sprite.win, count);
- if (deactivateGrab)
- (*keybd->DeactivateGrab) (keybd);
- }
- void
- ProcessPointerEvent(register xEvent *xE, register DeviceIntPtr mouse, int count)
- {
- GrabPtr grab = mouse->grab;
- Bool deactivateGrab = FALSE;
- ButtonClassPtr butc = mouse->button;
- if (!syncEvents.playingEvents)
- NoticeTime(xE)
- XE_KBPTR.state = (butc->state | (
- inputInfo.keyboard->key->state
- ));
- {
- NoticeTime(xE);
- if (DeviceEventCallback) {
- DeviceEventInfoRec eventinfo;
- /* see comment in EnqueueEvents regarding the next three lines */
- if (xE->u.u.type == MotionNotify)
- XE_KBPTR.root =
- WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
- eventinfo.events = xE;
- eventinfo.count = count;
- CallCallbacks(&DeviceEventCallback, (pointer) &eventinfo);
- }
- }
- if (xE->u.u.type != MotionNotify) {
- int key;
- BYTE *kptr;
- int bit;
- XE_KBPTR.rootX = sprite.hot.x;
- XE_KBPTR.rootY = sprite.hot.y;
- key = xE->u.u.detail;
- kptr = &butc->down[key >> 3];
- bit = 1 << (key & 7);
- switch (xE->u.u.type) {
- case ButtonPress:
- mouse->valuator->motionHintWindow = NullWindow;
- if (!(*kptr & bit))
- butc->buttonsDown++;
- butc->motionMask = ButtonMotionMask;
- *kptr |= bit;
- if (xE->u.u.detail == 0)
- return;
- if (xE->u.u.detail <= 5)
- butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
- filters[MotionNotify] = Motion_Filter(butc);
- if (!grab)
- if (CheckDeviceGrabs(mouse, xE, 0, count))
- return;
- break;
- case ButtonRelease:
- mouse->valuator->motionHintWindow = NullWindow;
- if (*kptr & bit)
- --butc->buttonsDown;
- if (!butc->buttonsDown)
- butc->motionMask = 0;
- *kptr &= ~bit;
- if (xE->u.u.detail == 0)
- return;
- if (xE->u.u.detail <= 5)
- butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
- filters[MotionNotify] = Motion_Filter(butc);
- if (!butc->state && mouse->fromPassiveGrab)
- deactivateGrab = TRUE;
- break;
- default:
- FatalError("bogus pointer event from ddx");
- }
- }
- else if (!CheckMotion(xE))
- return;
- if (grab)
- DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
- else
- DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow, mouse, count);
- if (deactivateGrab)
- (*mouse->DeactivateGrab) (mouse);
- }
- #define AtMostOneClient \
- (SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask)
- void
- RecalculateDeliverableEvents(pWin)
- WindowPtr pWin;
- {
- OtherClients *others;
- WindowPtr pChild;
- pChild = pWin;
- while (1) {
- if (pChild->optional) {
- pChild->optional->otherEventMasks = 0;
- for (others = wOtherClients(pChild); others; others = others->next) {
- pChild->optional->otherEventMasks |= others->mask;
- }
- }
- pChild->deliverableEvents = pChild->eventMask |
- wOtherEventMasks(pChild);
- if (pChild->parent)
- pChild->deliverableEvents |=
- (pChild->parent->deliverableEvents &
- ~wDontPropagateMask(pChild) & PropagateMask);
- if (pChild->firstChild) {
- pChild = pChild->firstChild;
- continue;
- }
- while (!pChild->nextSib && (pChild != pWin))
- pChild = pChild->parent;
- if (pChild == pWin)
- break;
- pChild = pChild->nextSib;
- }
- }
- /**
- *
- * \param value must conform to DeleteType
- */
- int
- OtherClientGone(pointer value, XID id)
- {
- OtherClientsPtr other, prev;
- WindowPtr pWin = (WindowPtr) value;
- prev = 0;
- for (other = wOtherClients(pWin); other; other = other->next) {
- if (other->resource == id) {
- if (prev)
- prev->next = other->next;
- else {
- if (!(pWin->optional->otherClients = other->next))
- CheckWindowOptionalNeed(pWin);
- }
- free(other);
- RecalculateDeliverableEvents(pWin);
- return (Success);
- }
- prev = other;
- }
- FatalError("client not on event list");
- /*NOTREACHED*/ return -1; /* make compiler happy */
- }
- int
- EventSelectForWindow(register WindowPtr pWin, register ClientPtr client,
- Mask mask)
- {
- Mask check;
- OtherClients *others;
- if (mask & ~AllEventMasks) {
- client->errorValue = mask;
- return BadValue;
- }
- check = (mask & AtMostOneClient);
- if (check & (pWin->eventMask | wOtherEventMasks(pWin))) { /* It is illegal for two different
- clients to select on any of the
- events for AtMostOneClient. However,
- it is OK, for some client to
- continue selecting on one of those
- events. */
- if ((wClient(pWin) != client) && (check & pWin->eventMask))
- return BadAccess;
- for (others = wOtherClients(pWin); others; others = others->next) {
- if (!SameClient(others, client) && (check & others->mask))
- return BadAccess;
- }
- }
- if (wClient(pWin) == client) {
- check = pWin->eventMask;
- pWin->eventMask = mask;
- }
- else {
- for (others = wOtherClients(pWin); others; others = others->next) {
- if (SameClient(others, client)) {
- check = others->mask;
- if (mask == 0) {
- FreeResource(others->resource, RT_NONE);
- return Success;
- }
- else
- others->mask = mask;
- goto maskSet;
- }
- }
- check = 0;
- if (!pWin->optional && !MakeWindowOptional(pWin))
- return BadAlloc;
- others = malloc(sizeof(OtherClients));
- if (!others)
- return BadAlloc;
- others->mask = mask;
- others->resource = FakeClientID(client->index);
- others->next = pWin->optional->otherClients;
- pWin->optional->otherClients = others;
- if (!AddResource(others->resource, RT_OTHERCLIENT, (pointer) pWin))
- return BadAlloc;
- }
- maskSet:
- if ((inputInfo.pointer->valuator->motionHintWindow == pWin) &&
- (mask & PointerMotionHintMask) &&
- !(check & PointerMotionHintMask) && !inputInfo.pointer->grab)
- inputInfo.pointer->valuator->motionHintWindow = NullWindow;
- RecalculateDeliverableEvents(pWin);
- return Success;
- }
- int
- EventSuppressForWindow(register WindowPtr pWin, register ClientPtr client,
- Mask mask, Bool *checkOptional)
- {
- int i, free;
- if (mask & ~PropagateMask) {
- client->errorValue = mask;
- return BadValue;
- }
- if (pWin->dontPropagate)
- DontPropagateRefCnts[pWin->dontPropagate]--;
- if (!mask)
- i = 0;
- else {
- for (i = DNPMCOUNT, free = 0; --i > 0;) {
- if (!DontPropagateRefCnts[i])
- free = i;
- else if (mask == DontPropagateMasks[i])
- break;
- }
- if (!i && free) {
- i = free;
- DontPropagateMasks[i] = mask;
- }
- }
- if (i || !mask) {
- pWin->dontPropagate = i;
- if (i)
- DontPropagateRefCnts[i]++;
- if (pWin->optional) {
- pWin->optional->dontPropagateMask = mask;
- *checkOptional = TRUE;
- }
- }
- else {
- if (!pWin->optional && !MakeWindowOptional(pWin)) {
- if (pWin->dontPropagate)
- DontPropagateRefCnts[pWin->dontPropagate]++;
- return BadAlloc;
- }
- pWin->dontPropagate = 0;
- pWin->optional->dontPropagateMask = mask;
- }
- RecalculateDeliverableEvents(pWin);
- return Success;
- }
- static WindowPtr
- CommonAncestor(register WindowPtr a, register WindowPtr b)
- {
- for (b = b->parent; b; b = b->parent)
- if (IsParent(b, a))
- return b;
- return NullWindow;
- }
- static void
- EnterLeaveEvent(int type,
- int mode, int detail, register WindowPtr pWin, Window child)
- {
- xEvent event;
- DeviceIntPtr keybd = inputInfo.keyboard;
- WindowPtr focus;
- DeviceIntPtr mouse = inputInfo.pointer;
- GrabPtr grab = mouse->grab;
- Mask mask;
- if ((pWin == mouse->valuator->motionHintWindow) &&
- (detail != NotifyInferior))
- mouse->valuator->motionHintWindow = NullWindow;
- if (grab) {
- mask = (pWin == grab->window) ? grab->eventMask : 0;
- if (grab->ownerEvents)
- mask |= EventMaskForClient(pWin, rClient(grab));
- }
- else {
- mask = pWin->eventMask | wOtherEventMasks(pWin);
- }
- if (mask & filters[type]) {
- event.u.u.type = type;
- event.u.u.detail = detail;
- event.u.enterLeave.time = currentTime.milliseconds;
- event.u.enterLeave.rootX = sprite.hot.x;
- event.u.enterLeave.rootY = sprite.hot.y;
- /* Counts on the same initial structure of crossing & button events! */
- FixUpEventFromWindow(&event, pWin, None, FALSE);
- /* Enter/Leave events always set child */
- event.u.enterLeave.child = child;
- event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ?
- ELFlagSameScreen : 0;
- event.u.enterLeave.state = keybd->key->state | mouse->button->state;
- event.u.enterLeave.mode = mode;
- focus = keybd->focus->win;
- if ((focus != NoneWin) &&
- ((pWin == focus) || (focus == PointerRootWin) ||
- IsParent(focus, pWin)))
- event.u.enterLeave.flags |= ELFlagFocus;
- if (grab)
- (void) TryClientEvents(rClient(grab), &event, 1, mask,
- filters[type], grab);
- else
- (void) DeliverEventsToWindow(pWin, &event, 1, filters[type],
- NullGrab, 0);
- }
- if ((type == EnterNotify) && (mask & KeymapStateMask)) {
- xKeymapEvent ke;
- memmove((char *) &ke.map[0], (char *) &keybd->key->down[1], 31);
- ke.type = KeymapNotify;
- if (grab)
- (void) TryClientEvents(rClient(grab), (xEvent *) &ke, 1, mask,
- KeymapStateMask, grab);
- else
- (void) DeliverEventsToWindow(pWin, (xEvent *) &ke, 1,
- KeymapStateMask, NullGrab, 0);
- }
- }
- static void
- EnterNotifies(WindowPtr ancestor, WindowPtr child, int mode, int detail)
- {
- WindowPtr parent = child->parent;
- if (ancestor == parent)
- return;
- EnterNotifies(ancestor, parent, mode, detail);
- EnterLeaveEvent(EnterNotify, mode, detail, parent, child->drawable.id);
- }
- static void
- LeaveNotifies(WindowPtr child, WindowPtr ancestor, int mode, int detail)
- {
- WindowPtr pWin;
- if (ancestor == child)
- return;
- for (pWin = child->parent; pWin != ancestor; pWin = pWin->parent) {
- EnterLeaveEvent(LeaveNotify, mode, detail, pWin, child->drawable.id);
- child = pWin;
- }
- }
- static void
- DoEnterLeaveEvents(WindowPtr fromWin, WindowPtr toWin, int mode)
- {
- if (fromWin == toWin)
- return;
- if (IsParent(fromWin, toWin)) {
- EnterLeaveEvent(LeaveNotify, mode, NotifyInferior, fromWin, None);
- EnterNotifies(fromWin, toWin, mode, NotifyVirtual);
- EnterLeaveEvent(EnterNotify, mode, NotifyAncestor, toWin, None);
- }
- else if (IsParent(toWin, fromWin)) {
- EnterLeaveEvent(LeaveNotify, mode, NotifyAncestor, fromWin, None);
- LeaveNotifies(fromWin, toWin, mode, NotifyVirtual);
- EnterLeaveEvent(EnterNotify, mode, NotifyInferior, toWin, None);
- }
- else { /* neither fromWin nor toWin is descendent of the other */
- WindowPtr common = CommonAncestor(toWin, fromWin);
- /* common == NullWindow ==> different screens */
- EnterLeaveEvent(LeaveNotify, mode, NotifyNonlinear, fromWin, None);
- LeaveNotifies(fromWin, common, mode, NotifyNonlinearVirtual);
- EnterNotifies(common, toWin, mode, NotifyNonlinearVirtual);
- EnterLeaveEvent(EnterNotify, mode, NotifyNonlinear, toWin, None);
- }
- }
- static void
- FocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
- register WindowPtr pWin)
- {
- xEvent event;
- event.u.focus.mode = mode;
- event.u.u.type = type;
- event.u.u.detail = detail;
- event.u.focus.window = pWin->drawable.id;
- (void) DeliverEventsToWindow(pWin, &event, 1, filters[type], NullGrab, 0);
- if ((type == FocusIn) &&
- ((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask)) {
- xKeymapEvent ke;
- memmove((char *) &ke.map[0], (char *) &dev->key->down[1], 31);
- ke.type = KeymapNotify;
- (void) DeliverEventsToWindow(pWin, (xEvent *) &ke, 1,
- KeymapStateMask, NullGrab, 0);
- }
- }
- /*
- * recursive because it is easier
- * no-op if child not descended from ancestor
- */
- static Bool
- FocusInEvents(DeviceIntPtr dev,
- WindowPtr ancestor, WindowPtr child, WindowPtr skipChild,
- int mode, int detail, Bool doAncestor)
- {
- if (child == NullWindow)
- return ancestor == NullWindow;
- if (ancestor == child) {
- if (doAncestor)
- FocusEvent(dev, FocusIn, mode, detail, child);
- return TRUE;
- }
- if (FocusInEvents(dev, ancestor, child->parent, skipChild, mode, detail,
- doAncestor)) {
- if (child != skipChild)
- FocusEvent(dev, FocusIn, mode, detail, child);
- return TRUE;
- }
- return FALSE;
- }
- /* dies horribly if ancestor is not an ancestor of child */
- static void
- FocusOutEvents(DeviceIntPtr dev,
- WindowPtr child, WindowPtr ancestor,
- int mode, int detail, Bool doAncestor)
- {
- WindowPtr pWin;
- for (pWin = child; pWin != ancestor; pWin = pWin->parent)
- FocusEvent(dev, FocusOut, mode, detail, pWin);
- if (doAncestor)
- FocusEvent(dev, FocusOut, mode, detail, ancestor);
- }
- void
- DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode)
- {
- int out, in; /* for holding details for to/from
- PointerRoot/None */
- int i;
- if (fromWin == toWin)
- return;
- out = (fromWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
- in = (toWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
- /* wrong values if neither, but then not referenced */
- if ((toWin == NullWindow) || (toWin == PointerRootWin)) {
- if ((fromWin == NullWindow) || (fromWin == PointerRootWin)) {
- if (fromWin == PointerRootWin)
- FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
- TRUE);
- /* Notify all the roots */
- for (i = 0; i < screenInfo.numScreens; i++)
- FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
- }
- else {
- if (IsParent(fromWin, sprite.win))
- FocusOutEvents(dev, sprite.win, fromWin, mode, NotifyPointer,
- FALSE);
- FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
- /* next call catches the root too, if the screen changed */
- FocusOutEvents(dev, fromWin->parent, NullWindow, mode,
- NotifyNonlinearVirtual, FALSE);
- }
- /* Notify all the roots */
- for (i = 0; i < screenInfo.numScreens; i++)
- FocusEvent(dev, FocusIn, mode, in, WindowTable[i]);
- if (toWin == PointerRootWin)
- (void) FocusInEvents(dev, ROOT, sprite.win, NullWindow, mode,
- NotifyPointer, TRUE);
- }
- else {
- if ((fromWin == NullWindow) || (fromWin == PointerRootWin)) {
- if (fromWin == PointerRootWin)
- FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
- TRUE);
- for (i = 0; i < screenInfo.numScreens; i++)
- FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
- if (toWin->parent != NullWindow)
- (void) FocusInEvents(dev, ROOT, toWin, toWin, mode,
- NotifyNonlinearVirtual, TRUE);
- FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
- if (IsParent(toWin, sprite.win))
- (void) FocusInEvents(dev, toWin, sprite.win, NullWindow, mode,
- NotifyPointer, FALSE);
- }
- else {
- if (IsParent(toWin, fromWin)) {
- FocusEvent(dev, FocusOut, mode, NotifyAncestor, fromWin);
- FocusOutEvents(dev, fromWin->parent, toWin, mode,
- NotifyVirtual, FALSE);
- FocusEvent(dev, FocusIn, mode, NotifyInferior, toWin);
- if ((IsParent(toWin, sprite.win)) &&
- (sprite.win != fromWin) &&
- (!IsParent(fromWin, sprite.win)) &&
- (!IsParent(sprite.win, fromWin)))
- (void) FocusInEvents(dev, toWin, sprite.win, NullWindow,
- mode, NotifyPointer, FALSE);
- }
- else if (IsParent(fromWin, toWin)) {
- if ((IsParent(fromWin, sprite.win)) &&
- (sprite.win != fromWin) &&
- (!IsParent(toWin, sprite.win)) &&
- (!IsParent(sprite.win, toWin)))
- FocusOutEvents(dev, sprite.win, fromWin, mode,
- NotifyPointer, FALSE);
- FocusEvent(dev, FocusOut, mode, NotifyInferior, fromWin);
- (void) FocusInEvents(dev, fromWin, toWin, toWin, mode,
- NotifyVirtual, FALSE);
- FocusEvent(dev, FocusIn, mode, NotifyAncestor, toWin);
- }
- else {
- /* neither fromWin or toWin is child of other */
- WindowPtr common = CommonAncestor(toWin, fromWin);
- /* common == NullWindow ==> different screens */
- if (IsParent(fromWin, sprite.win))
- FocusOutEvents(dev, sprite.win, fromWin, mode,
- NotifyPointer, FALSE);
- FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
- if (fromWin->parent != NullWindow)
- FocusOutEvents(dev, fromWin->parent, common, mode,
- NotifyNonlinearVirtual, FALSE);
- if (toWin->parent != NullWindow)
- (void) FocusInEvents(dev, common, toWin, toWin, mode,
- NotifyNonlinearVirtual, FALSE);
- FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
- if (IsParent(toWin, sprite.win))
- (void) FocusInEvents(dev, toWin, sprite.win, NullWindow,
- mode, NotifyPointer, FALSE);
- }
- }
- }
- }
- int
- SetInputFocus(ClientPtr client,
- DeviceIntPtr dev,
- Window focusID, CARD8 revertTo, Time ctime, Bool followOK)
- {
- FocusClassPtr focus;
- WindowPtr focusWin;
- int mode;
- TimeStamp time;
- UpdateCurrentTime();
- if ((revertTo != RevertToParent) &&
- (revertTo != RevertToPointerRoot) &&
- (revertTo != RevertToNone) &&
- ((revertTo != RevertToFollowKeyboard) || !followOK)) {
- client->errorValue = revertTo;
- return BadValue;
- }
- time = ClientTimeToServerTime(ctime);
- if ((focusID == None) || (focusID == PointerRoot))
- focusWin = (WindowPtr) (long) focusID;
- else if ((focusID == FollowKeyboard) && followOK)
- focusWin = inputInfo.keyboard->focus->win;
- else if (!(focusWin = SecurityLookupWindow(focusID, client,
- SecurityReadAccess)))
- return BadWindow;
- else {
- /* It is a match error to try to set the input focus to an
- unviewable window. */
- if (!focusWin->realized)
- return (BadMatch);
- }
- focus = dev->focus;
- if ((CompareTimeStamps(time, currentTime) == LATER) ||
- (CompareTimeStamps(time, focus->time) == EARLIER))
- return Success;
- mode = (dev->grab) ? NotifyWhileGrabbed : NotifyNormal;
- if (focus->win == FollowKeyboardWin)
- DoFocusEvents(dev, inputInfo.keyboard->focus->win, focusWin, mode);
- else
- DoFocusEvents(dev, focus->win, focusWin, mode);
- focus->time = time;
- focus->revert = revertTo;
- if (focusID == FollowKeyboard)
- focus->win = FollowKeyboardWin;
- else
- focus->win = focusWin;
- if ((focusWin == NoneWin) || (focusWin == PointerRootWin))
- focus->traceGood = 0;
- else {
- int depth = 0;
- WindowPtr pWin;
- for (pWin = focusWin; pWin; pWin = pWin->parent)
- depth++;
- if (depth > focus->traceSize) {
- focus->traceSize = depth + 1;
- Must_have_memory = TRUE; /* XXX */
- focus->trace = (WindowPtr *) realloc(focus->trace,
- focus->traceSize *
- sizeof(WindowPtr));
- Must_have_memory = FALSE; /* XXX */
- }
- focus->traceGood = depth;
- for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--)
- focus->trace[depth] = pWin;
- }
- return Success;
- }
- int
- ProcSetInputFocus(client)
- ClientPtr client;
- {
- REQUEST(xSetInputFocusReq);
- REQUEST_SIZE_MATCH(xSetInputFocusReq);
- return SetInputFocus(client, inputInfo.keyboard, stuff->focus,
- stuff->revertTo, stuff->time, FALSE);
- }
- int
- ProcGetInputFocus(ClientPtr client)
- {
- xGetInputFocusReply rep = {0};
- /* REQUEST(xReq); */
- FocusClassPtr focus = inputInfo.keyboard->focus;
- REQUEST_SIZE_MATCH(xReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- if (focus->win == NoneWin)
- rep.focus = None;
- else if (focus->win == PointerRootWin)
- rep.focus = PointerRoot;
- else
- rep.focus = focus->win->drawable.id;
- rep.revertTo = focus->revert;
- WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep);
- return Success;
- }
- int
- ProcGrabPointer(ClientPtr client)
- {
- xGrabPointerReply rep;
- DeviceIntPtr device = inputInfo.pointer;
- GrabPtr grab;
- WindowPtr pWin, confineTo;
- CursorPtr cursor, oldCursor;
- REQUEST(xGrabPointerReq);
- TimeStamp time;
- REQUEST_SIZE_MATCH(xGrabPointerReq);
- UpdateCurrentTime();
- if ((stuff->pointerMode != GrabModeSync) &&
- (stuff->pointerMode != GrabModeAsync)) {
- client->errorValue = stuff->pointerMode;
- return BadValue;
- }
- if ((stuff->keyboardMode != GrabModeSync) &&
- (stuff->keyboardMode != GrabModeAsync)) {
- client->errorValue = stuff->keyboardMode;
- return BadValue;
- }
- if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue)) {
- client->errorValue = stuff->ownerEvents;
- return BadValue;
- }
- if (stuff->eventMask & ~PointerGrabMask) {
- client->errorValue = stuff->eventMask;
- return BadValue;
- }
- pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
- if (!pWin)
- return BadWindow;
- if (stuff->confineTo == None)
- confineTo = NullWindow;
- else {
- confineTo = SecurityLookupWindow(stuff->confineTo, client,
- SecurityReadAccess);
- if (!confineTo)
- return BadWindow;
- }
- if (stuff->cursor == None)
- cursor = NullCursor;
- else {
- cursor = (CursorPtr) SecurityLookupIDByType(client, stuff->cursor,
- RT_CURSOR,
- SecurityReadAccess);
- if (!cursor) {
- client->errorValue = stuff->cursor;
- return BadCursor;
- }
- }
- /* at this point, some sort of reply is guaranteed. */
- time = ClientTimeToServerTime(stuff->time);
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- grab = device->grab;
- if ((grab) && !SameClient(grab, client))
- rep.status = AlreadyGrabbed;
- else if ((!pWin->realized) ||
- (confineTo &&
- !(confineTo->realized && BorderSizeNotEmpty(confineTo))))
- rep.status = GrabNotViewable;
- else if (device->sync.frozen &&
- device->sync.other && !SameClient(device->sync.other, client))
- rep.status = GrabFrozen;
- else if ((CompareTimeStamps(time, currentTime) == LATER) ||
- (CompareTimeStamps(time, device->grabTime) == EARLIER))
- rep.status = GrabInvalidTime;
- else {
- GrabRec tempGrab;
- oldCursor = NullCursor;
- if (grab) {
- if (grab->confineTo && !confineTo)
- ConfineCursorToWindow(ROOT, FALSE, FALSE);
- oldCursor = grab->cursor;
- }
- tempGrab.cursor = cursor;
- tempGrab.resource = client->clientAsMask;
- tempGrab.ownerEvents = stuff->ownerEvents;
- tempGrab.eventMask = stuff->eventMask;
- tempGrab.confineTo = confineTo;
- tempGrab.window = pWin;
- tempGrab.keyboardMode = stuff->keyboardMode;
- tempGrab.pointerMode = stuff->pointerMode;
- tempGrab.device = device;
- (*device->ActivateGrab) (device, &tempGrab, time, FALSE);
- if (oldCursor)
- FreeCursor(oldCursor, (Cursor) 0);
- rep.status = GrabSuccess;
- }
- WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep);
- return Success;
- }
- int
- ProcChangeActivePointerGrab(ClientPtr client)
- {
- DeviceIntPtr device = inputInfo.pointer;
- GrabPtr grab = device->grab;
- CursorPtr newCursor, oldCursor;
- REQUEST(xChangeActivePointerGrabReq);
- TimeStamp time;
- REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq);
- if (stuff->eventMask & ~PointerGrabMask) {
- client->errorValue = stuff->eventMask;
- return BadValue;
- }
- if (stuff->cursor == None)
- newCursor = NullCursor;
- else {
- newCursor = (CursorPtr) SecurityLookupIDByType(client, stuff->cursor,
- RT_CURSOR,
- SecurityReadAccess);
- if (!newCursor) {
- client->errorValue = stuff->cursor;
- return BadCursor;
- }
- }
- if (!grab)
- return Success;
- if (!SameClient(grab, client))
- return Success;
- time = ClientTimeToServerTime(stuff->time);
- if ((CompareTimeStamps(time, currentTime) == LATER) ||
- (CompareTimeStamps(time, device->grabTime) == EARLIER))
- return Success;
- oldCursor = grab->cursor;
- grab->cursor = newCursor;
- if (newCursor)
- newCursor->refcnt++;
- PostNewCursor();
- if (oldCursor)
- FreeCursor(oldCursor, (Cursor) 0);
- grab->eventMask = stuff->eventMask;
- return Success;
- }
- int
- ProcUngrabPointer(ClientPtr client)
- {
- DeviceIntPtr device = inputInfo.pointer;
- GrabPtr grab;
- TimeStamp time;
- REQUEST(xResourceReq);
- REQUEST_SIZE_MATCH(xResourceReq);
- UpdateCurrentTime();
- grab = device->grab;
- time = ClientTimeToServerTime(stuff->id);
- if ((CompareTimeStamps(time, currentTime) != LATER) &&
- (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
- (grab) && SameClient(grab, client))
- (*device->DeactivateGrab) (device);
- return Success;
- }
- int
- GrabDevice(register ClientPtr client, register DeviceIntPtr dev,
- unsigned this_mode, unsigned other_mode, Window grabWindow,
- unsigned ownerEvents, Time ctime, Mask mask, CARD8 *status)
- {
- WindowPtr pWin;
- GrabPtr grab;
- TimeStamp time;
- UpdateCurrentTime();
- if ((this_mode != GrabModeSync) && (this_mode != GrabModeAsync)) {
- client->errorValue = this_mode;
- return BadValue;
- }
- if ((other_mode != GrabModeSync) && (other_mode != GrabModeAsync)) {
- client->errorValue = other_mode;
- return BadValue;
- }
- if ((ownerEvents != xFalse) && (ownerEvents != xTrue)) {
- client->errorValue = ownerEvents;
- return BadValue;
- }
- pWin = SecurityLookupWindow(grabWindow, client, SecurityReadAccess);
- if (!pWin)
- return BadWindow;
- time = ClientTimeToServerTime(ctime);
- grab = dev->grab;
- if (grab && !SameClient(grab, client))
- *status = AlreadyGrabbed;
- else if (!pWin->realized)
- *status = GrabNotViewable;
- else if ((CompareTimeStamps(time, currentTime) == LATER) ||
- (CompareTimeStamps(time, dev->grabTime) == EARLIER))
- *status = GrabInvalidTime;
- else if (dev->sync.frozen &&
- dev->sync.other && !SameClient(dev->sync.other, client))
- *status = GrabFrozen;
- else {
- GrabRec tempGrab;
- tempGrab.window = pWin;
- tempGrab.resource = client->clientAsMask;
- tempGrab.ownerEvents = ownerEvents;
- tempGrab.keyboardMode = this_mode;
- tempGrab.pointerMode = other_mode;
- tempGrab.eventMask = mask;
- tempGrab.device = dev;
- (*dev->ActivateGrab) (dev, &tempGrab, time, FALSE);
- *status = GrabSuccess;
- }
- return Success;
- }
- int
- ProcGrabKeyboard(ClientPtr client)
- {
- xGrabKeyboardReply rep;
- REQUEST(xGrabKeyboardReq);
- int result;
- REQUEST_SIZE_MATCH(xGrabKeyboardReq);
- result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode,
- stuff->pointerMode, stuff->grabWindow,
- stuff->ownerEvents, stuff->time,
- KeyPressMask | KeyReleaseMask, &rep.status);
- if (result != Success)
- return result;
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep);
- return Success;
- }
- int
- ProcUngrabKeyboard(ClientPtr client)
- {
- DeviceIntPtr device = inputInfo.keyboard;
- GrabPtr grab;
- TimeStamp time;
- REQUEST(xResourceReq);
- REQUEST_SIZE_MATCH(xResourceReq);
- UpdateCurrentTime();
- grab = device->grab;
- time = ClientTimeToServerTime(stuff->id);
- if ((CompareTimeStamps(time, currentTime) != LATER) &&
- (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
- (grab) && SameClient(grab, client))
- (*device->DeactivateGrab) (device);
- return Success;
- }
- int
- ProcQueryPointer(ClientPtr client)
- {
- xQueryPointerReply rep;
- WindowPtr pWin, t;
- REQUEST(xResourceReq);
- DeviceIntPtr mouse = inputInfo.pointer;
- REQUEST_SIZE_MATCH(xResourceReq);
- pWin = SecurityLookupWindow(stuff->id, client, SecurityReadAccess);
- if (!pWin)
- return BadWindow;
- if (mouse->valuator->motionHintWindow)
- MaybeStopHint(mouse, client);
- memset(&rep, 0, sizeof(xQueryPointerReply));
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.mask = mouse->button->state | inputInfo.keyboard->key->state;
- rep.length = 0;
- rep.root = (ROOT)->drawable.id;
- rep.rootX = sprite.hot.x;
- rep.rootY = sprite.hot.y;
- rep.child = None;
- if (sprite.hot.pScreen == pWin->drawable.pScreen) {
- rep.sameScreen = xTrue;
- rep.winX = sprite.hot.x - pWin->drawable.x;
- rep.winY = sprite.hot.y - pWin->drawable.y;
- for (t = sprite.win; t; t = t->parent)
- if (t->parent == pWin) {
- rep.child = t->drawable.id;
- break;
- }
- }
- else {
- rep.sameScreen = xFalse;
- rep.winX = 0;
- rep.winY = 0;
- }
- WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);
- return (Success);
- }
- void
- InitEvents()
- {
- int i;
- sprite.hot.pScreen = sprite.hotPhys.pScreen = (ScreenPtr) NULL;
- inputInfo.numDevices = 0;
- inputInfo.devices = (DeviceIntPtr) NULL;
- inputInfo.off_devices = (DeviceIntPtr) NULL;
- inputInfo.keyboard = (DeviceIntPtr) NULL;
- inputInfo.pointer = (DeviceIntPtr) NULL;
- memcpy(filters, initialFilters, 128 * sizeof(Mask));
- if (spriteTraceSize == 0) {
- spriteTraceSize = 32;
- spriteTrace = malloc(32 * sizeof(WindowPtr));
- if (!spriteTrace)
- FatalError("failed to allocate spriteTrace");
- }
- spriteTraceGood = 0;
- lastEventMask = OwnerGrabButtonMask;
- filters[MotionNotify] = PointerMotionMask;
- sprite.win = NullWindow;
- sprite.current = NullCursor;
- sprite.hotLimits.x1 = 0;
- sprite.hotLimits.y1 = 0;
- sprite.hotLimits.x2 = 0;
- sprite.hotLimits.y2 = 0;
- sprite.confined = FALSE;
- syncEvents.replayDev = (DeviceIntPtr) NULL;
- syncEvents.replayWin = NullWindow;
- while (syncEvents.pending) {
- QdEventPtr next = syncEvents.pending->next;
- free(syncEvents.pending);
- syncEvents.pending = next;
- }
- syncEvents.pendtail = &syncEvents.pending;
- syncEvents.playingEvents = FALSE;
- syncEvents.time.months = 0;
- syncEvents.time.milliseconds = 0; /* hardly matters */
- currentTime.months = 0;
- currentTime.milliseconds = GetTimeInMillis();
- lastDeviceEventTime = currentTime;
- for (i = 0; i < DNPMCOUNT; i++) {
- DontPropagateMasks[i] = 0;
- DontPropagateRefCnts[i] = 0;
- }
- }
- void
- CloseDownEvents(void)
- {
- free(spriteTrace);
- spriteTrace = NULL;
- spriteTraceSize = 0;
- }
- int
- ProcSendEvent(ClientPtr client)
- {
- WindowPtr pWin;
- WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
- REQUEST(xSendEventReq);
- REQUEST_SIZE_MATCH(xSendEventReq);
- /* The client's event type must be a core event type or one defined by an
- extension. */
- if (!((stuff->event.u.u.type > X_Reply &&
- stuff->event.u.u.type < LASTEvent) ||
- (stuff->event.u.u.type >= EXTENSION_EVENT_BASE &&
- stuff->event.u.u.type < (unsigned) lastEvent))) {
- client->errorValue = stuff->event.u.u.type;
- return BadValue;
- }
- if (stuff->event.u.u.type == ClientMessage &&
- stuff->event.u.u.detail != 8 &&
- stuff->event.u.u.detail != 16 && stuff->event.u.u.detail != 32) {
- client->errorValue = stuff->event.u.u.detail;
- return BadValue;
- }
- if (stuff->eventMask & ~AllEventMasks) {
- client->errorValue = stuff->eventMask;
- return BadValue;
- }
- if (stuff->destination == PointerWindow)
- pWin = sprite.win;
- else if (stuff->destination == InputFocus) {
- WindowPtr inputFocus = inputInfo.keyboard->focus->win;
- if (inputFocus == NoneWin)
- return Success;
- /* If the input focus is PointerRootWin, send the event to where
- the pointer is if possible, then perhaps propogate up to root. */
- if (inputFocus == PointerRootWin)
- inputFocus = ROOT;
- if (IsParent(inputFocus, sprite.win)) {
- effectiveFocus = inputFocus;
- pWin = sprite.win;
- }
- else
- effectiveFocus = pWin = inputFocus;
- }
- else
- pWin = SecurityLookupWindow(stuff->destination, client,
- SecurityReadAccess);
- if (!pWin)
- return BadWindow;
- if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue)) {
- client->errorValue = stuff->propagate;
- return BadValue;
- }
- stuff->event.u.u.type |= 0x80;
- if (stuff->propagate) {
- for (; pWin; pWin = pWin->parent) {
- if (DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
- NullGrab, 0))
- return Success;
- if (pWin == effectiveFocus)
- return Success;
- stuff->eventMask &= ~wDontPropagateMask(pWin);
- if (!stuff->eventMask)
- break;
- }
- }
- else
- (void) DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
- NullGrab, 0);
- return Success;
- }
- int
- ProcUngrabKey(ClientPtr client)
- {
- REQUEST(xUngrabKeyReq);
- WindowPtr pWin;
- GrabRec tempGrab;
- DeviceIntPtr keybd = inputInfo.keyboard;
- REQUEST_SIZE_MATCH(xUngrabKeyReq);
- pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
- if (!pWin)
- return BadWindow;
- if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
- (stuff->key < keybd->key->curKeySyms.minKeyCode))
- && (stuff->key != AnyKey)) {
- client->errorValue = stuff->key;
- return BadValue;
- }
- if ((stuff->modifiers != AnyModifier) &&
- (stuff->modifiers & ~AllModifiersMask)) {
- client->errorValue = stuff->modifiers;
- return BadValue;
- }
- tempGrab.resource = client->clientAsMask;
- tempGrab.device = keybd;
- tempGrab.window = pWin;
- tempGrab.modifiersDetail.exact = stuff->modifiers;
- tempGrab.modifiersDetail.pMask = NULL;
- tempGrab.modifierDevice = inputInfo.keyboard;
- tempGrab.type = KeyPress;
- tempGrab.detail.exact = stuff->key;
- tempGrab.detail.pMask = NULL;
- if (!DeletePassiveGrabFromList(&tempGrab))
- return (BadAlloc);
- return (Success);
- }
- int
- ProcGrabKey(ClientPtr client)
- {
- WindowPtr pWin;
- REQUEST(xGrabKeyReq);
- GrabPtr grab;
- DeviceIntPtr keybd = inputInfo.keyboard;
- REQUEST_SIZE_MATCH(xGrabKeyReq);
- if ((stuff->ownerEvents != xTrue) && (stuff->ownerEvents != xFalse)) {
- client->errorValue = stuff->ownerEvents;
- return (BadValue);
- }
- if ((stuff->pointerMode != GrabModeSync) &&
- (stuff->pointerMode != GrabModeAsync)) {
- client->errorValue = stuff->pointerMode;
- return BadValue;
- }
- if ((stuff->keyboardMode != GrabModeSync) &&
- (stuff->keyboardMode != GrabModeAsync)) {
- client->errorValue = stuff->keyboardMode;
- return BadValue;
- }
- if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
- (stuff->key < keybd->key->curKeySyms.minKeyCode))
- && (stuff->key != AnyKey)) {
- client->errorValue = stuff->key;
- return BadValue;
- }
- if ((stuff->modifiers != AnyModifier) &&
- (stuff->modifiers & ~AllModifiersMask)) {
- client->errorValue = stuff->modifiers;
- return BadValue;
- }
- pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
- if (!pWin)
- return BadWindow;
- grab = CreateGrab(client->index, keybd, pWin,
- (Mask) (KeyPressMask | KeyReleaseMask),
- (Bool) stuff->ownerEvents, (Bool) stuff->keyboardMode,
- (Bool) stuff->pointerMode, keybd, stuff->modifiers,
- KeyPress, stuff->key, NullWindow, NullCursor);
- if (!grab)
- return BadAlloc;
- return AddPassiveGrabToList(grab);
- }
- int
- ProcGrabButton(ClientPtr client)
- {
- WindowPtr pWin, confineTo;
- REQUEST(xGrabButtonReq);
- CursorPtr cursor;
- GrabPtr grab;
- REQUEST_SIZE_MATCH(xGrabButtonReq);
- if ((stuff->pointerMode != GrabModeSync) &&
- (stuff->pointerMode != GrabModeAsync)) {
- client->errorValue = stuff->pointerMode;
- return BadValue;
- }
- if ((stuff->keyboardMode != GrabModeSync) &&
- (stuff->keyboardMode != GrabModeAsync)) {
- client->errorValue = stuff->keyboardMode;
- return BadValue;
- }
- if ((stuff->modifiers != AnyModifier) &&
- (stuff->modifiers & ~AllModifiersMask)) {
- client->errorValue = stuff->modifiers;
- return BadValue;
- }
- if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue)) {
- client->errorValue = stuff->ownerEvents;
- return BadValue;
- }
- if (stuff->eventMask & ~PointerGrabMask) {
- client->errorValue = stuff->eventMask;
- return BadValue;
- }
- pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
- if (!pWin)
- return BadWindow;
- if (stuff->confineTo == None)
- confineTo = NullWindow;
- else {
- confineTo = SecurityLookupWindow(stuff->confineTo, client,
- SecurityReadAccess);
- if (!confineTo)
- return BadWindow;
- }
- if (stuff->cursor == None)
- cursor = NullCursor;
- else {
- cursor = (CursorPtr) SecurityLookupIDByType(client, stuff->cursor,
- RT_CURSOR,
- SecurityReadAccess);
- if (!cursor) {
- client->errorValue = stuff->cursor;
- return BadCursor;
- }
- }
- grab = CreateGrab(client->index, inputInfo.pointer, pWin,
- (Mask)stuff->eventMask, (Bool)stuff->ownerEvents,
- (Bool)stuff->keyboardMode, (Bool)stuff->pointerMode,
- inputInfo.keyboard, stuff->modifiers, ButtonPress,
- stuff->button, confineTo, cursor);
- if (!grab)
- return BadAlloc;
- return AddPassiveGrabToList(grab);
- }
- int
- ProcUngrabButton(ClientPtr client)
- {
- REQUEST(xUngrabButtonReq);
- WindowPtr pWin;
- GrabRec tempGrab;
- REQUEST_SIZE_MATCH(xUngrabButtonReq);
- if ((stuff->modifiers != AnyModifier) &&
- (stuff->modifiers & ~AllModifiersMask)) {
- client->errorValue = stuff->modifiers;
- return BadValue;
- }
- pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
- if (!pWin)
- return BadWindow;
- tempGrab.resource = client->clientAsMask;
- tempGrab.device = inputInfo.pointer;
- tempGrab.window = pWin;
- tempGrab.modifiersDetail.exact = stuff->modifiers;
- tempGrab.modifiersDetail.pMask = NULL;
- tempGrab.modifierDevice = inputInfo.keyboard;
- tempGrab.type = ButtonPress;
- tempGrab.detail.exact = stuff->button;
- tempGrab.detail.pMask = NULL;
- if (!DeletePassiveGrabFromList(&tempGrab))
- return (BadAlloc);
- return (Success);
- }
- void
- DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources)
- {
- WindowPtr parent;
- DeviceIntPtr mouse = inputInfo.pointer;
- DeviceIntPtr keybd = inputInfo.keyboard;
- FocusClassPtr focus = keybd->focus;
- OtherClientsPtr oc;
- GrabPtr passive;
- /* Deactivate any grabs performed on this window, before making any
- input focus changes. */
- if (mouse->grab &&
- ((mouse->grab->window == pWin) || (mouse->grab->confineTo == pWin)))
- (*mouse->DeactivateGrab) (mouse);
- /* Deactivating a keyboard grab should cause focus events. */
- if (keybd->grab && (keybd->grab->window == pWin))
- (*keybd->DeactivateGrab) (keybd);
- /* If the focus window is a root window (ie. has no parent) then don't
- delete the focus from it. */
- if ((pWin == focus->win) && (pWin->parent != NullWindow)) {
- int focusEventMode = NotifyNormal;
- /* If a grab is in progress, then alter the mode of focus events. */
- if (keybd->grab)
- focusEventMode = NotifyWhileGrabbed;
- switch (focus->revert) {
- case RevertToNone:
- DoFocusEvents(keybd, pWin, NoneWin, focusEventMode);
- focus->win = NoneWin;
- focus->traceGood = 0;
- break;
- case RevertToParent:
- parent = pWin;
- do {
- parent = parent->parent;
- focus->traceGood--;
- } while (!parent->realized
- /* This would be a good protocol change -- windows being reparented
- during SaveSet processing would cause the focus to revert to the
- nearest enclosing window which will survive the death of the exiting
- client, instead of ending up reverting to a dying window and thence
- to None
- */
- #ifdef NOTDEF
- || clients[CLIENT_ID(parent->drawable.id)]->clientGone
- #endif
- );
- DoFocusEvents(keybd, pWin, parent, focusEventMode);
- focus->win = parent;
- focus->revert = RevertToNone;
- break;
- case RevertToPointerRoot:
- DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode);
- focus->win = PointerRootWin;
- focus->traceGood = 0;
- break;
- }
- }
- if (mouse->valuator->motionHintWindow == pWin)
- mouse->valuator->motionHintWindow = NullWindow;
- if (freeResources) {
- if (pWin->dontPropagate)
- DontPropagateRefCnts[pWin->dontPropagate]--;
- while ((oc = wOtherClients(pWin)))
- FreeResource(oc->resource, RT_NONE);
- while ((passive = wPassiveGrabs(pWin)))
- FreeResource(passive->resource, RT_NONE);
- }
- }
- /**
- * Call this whenever some window at or below pWin has changed geometry
- */
- _X_EXPORT void
- CheckCursorConfinement(WindowPtr pWin)
- {
- GrabPtr grab = inputInfo.pointer->grab;
- WindowPtr confineTo;
- if (grab && (confineTo = grab->confineTo)) {
- if (!BorderSizeNotEmpty(confineTo))
- (*inputInfo.pointer->DeactivateGrab) (inputInfo.pointer);
- else if ((pWin == confineTo) || IsParent(pWin, confineTo))
- ConfineCursorToWindow(confineTo, TRUE, TRUE);
- }
- }
- Mask
- EventMaskForClient(WindowPtr pWin, ClientPtr client)
- {
- OtherClientsPtr other;
- if (wClient(pWin) == client)
- return pWin->eventMask;
- for (other = wOtherClients(pWin); other; other = other->next) {
- if (SameClient(other, client))
- return other->mask;
- }
- return 0;
- }
- int
- ProcRecolorCursor(ClientPtr client)
- {
- CursorPtr pCursor;
- int nscr;
- ScreenPtr pscr;
- Bool displayed;
- REQUEST(xRecolorCursorReq);
- REQUEST_SIZE_MATCH(xRecolorCursorReq);
- pCursor = (CursorPtr) SecurityLookupIDByType(client, stuff->cursor,
- RT_CURSOR,
- SecurityWriteAccess);
- if (!pCursor) {
- client->errorValue = stuff->cursor;
- return (BadCursor);
- }
- pCursor->foreRed = stuff->foreRed;
- pCursor->foreGreen = stuff->foreGreen;
- pCursor->foreBlue = stuff->foreBlue;
- pCursor->backRed = stuff->backRed;
- pCursor->backGreen = stuff->backGreen;
- pCursor->backBlue = stuff->backBlue;
- for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
- pscr = screenInfo.screens[nscr];
- displayed = (pscr == sprite.hotPhys.pScreen);
- (*pscr->RecolorCursor) (pscr, pCursor,
- (pCursor == sprite.current) && displayed);
- }
- return (Success);
- }
- _X_EXPORT void
- WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
- {
- xEvent eventTo, *eventFrom;
- int i;
- if (!pClient || pClient == serverClient || pClient->clientGone)
- return;
- for (i = 0; i < count; i++)
- if ((events[i].u.u.type & 0x7f) != KeymapNotify)
- events[i].u.u.sequenceNumber = pClient->sequence;
- if (EventCallback) {
- EventInfoRec eventinfo;
- eventinfo.client = pClient;
- eventinfo.events = events;
- eventinfo.count = count;
- CallCallbacks(&EventCallback, (pointer) &eventinfo);
- }
- if (pClient->swapped) {
- for (i = 0; i < count; i++) {
- eventFrom = &events[i];
- /* Remember to strip off the leading bit of type in case
- this event was sent with "SendEvent." */
- (*EventSwapVector[eventFrom->u.u.type & 0177])
- (eventFrom, &eventTo);
- (void) WriteToClient(pClient, sizeof(xEvent), (char *) &eventTo);
- }
- }
- else {
- (void) WriteToClient(pClient, count * sizeof(xEvent), (char *) events);
- }
- }
|