exevents.c revision 05b261ec
105b261ecSmrg/************************************************************ 205b261ecSmrg 305b261ecSmrgCopyright 1989, 1998 The Open Group 405b261ecSmrg 505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its 605b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that 705b261ecSmrgthe above copyright notice appear in all copies and that both that 805b261ecSmrgcopyright notice and this permission notice appear in supporting 905b261ecSmrgdocumentation. 1005b261ecSmrg 1105b261ecSmrgThe above copyright notice and this permission notice shall be included in 1205b261ecSmrgall copies or substantial portions of the Software. 1305b261ecSmrg 1405b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1505b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1605b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1705b261ecSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 1805b261ecSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 1905b261ecSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2005b261ecSmrg 2105b261ecSmrgExcept as contained in this notice, the name of The Open Group shall not be 2205b261ecSmrgused in advertising or otherwise to promote the sale, use or other dealings 2305b261ecSmrgin this Software without prior written authorization from The Open Group. 2405b261ecSmrg 2505b261ecSmrgCopyright 1989 by Hewlett-Packard Company, Palo Alto, California. 2605b261ecSmrg 2705b261ecSmrg All Rights Reserved 2805b261ecSmrg 2905b261ecSmrgPermission to use, copy, modify, and distribute this software and its 3005b261ecSmrgdocumentation for any purpose and without fee is hereby granted, 3105b261ecSmrgprovided that the above copyright notice appear in all copies and that 3205b261ecSmrgboth that copyright notice and this permission notice appear in 3305b261ecSmrgsupporting documentation, and that the name of Hewlett-Packard not be 3405b261ecSmrgused in advertising or publicity pertaining to distribution of the 3505b261ecSmrgsoftware without specific, written prior permission. 3605b261ecSmrg 3705b261ecSmrgHEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 3805b261ecSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 3905b261ecSmrgHEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 4005b261ecSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 4105b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 4205b261ecSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 4305b261ecSmrgSOFTWARE. 4405b261ecSmrg 4505b261ecSmrg********************************************************/ 4605b261ecSmrg 4705b261ecSmrg/******************************************************************** 4805b261ecSmrg * 4905b261ecSmrg * Routines to register and initialize extension input devices. 5005b261ecSmrg * This also contains ProcessOtherEvent, the routine called from DDX 5105b261ecSmrg * to route extension events. 5205b261ecSmrg * 5305b261ecSmrg */ 5405b261ecSmrg 5505b261ecSmrg#define NEED_EVENTS 5605b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 5705b261ecSmrg#include <dix-config.h> 5805b261ecSmrg#endif 5905b261ecSmrg 6005b261ecSmrg#include <X11/X.h> 6105b261ecSmrg#include <X11/Xproto.h> 6205b261ecSmrg#include <X11/extensions/XI.h> 6305b261ecSmrg#include <X11/extensions/XIproto.h> 6405b261ecSmrg#include "inputstr.h" 6505b261ecSmrg#include "windowstr.h" 6605b261ecSmrg#include "miscstruct.h" 6705b261ecSmrg#include "region.h" 6805b261ecSmrg#include "exevents.h" 6905b261ecSmrg#include "extnsionst.h" 7005b261ecSmrg#include "extinit.h" /* LookupDeviceIntRec */ 7105b261ecSmrg#include "exglobals.h" 7205b261ecSmrg#include "dixevents.h" /* DeliverFocusedEvent */ 7305b261ecSmrg#include "dixgrabs.h" /* CreateGrab() */ 7405b261ecSmrg#include "scrnintstr.h" 7505b261ecSmrg 7605b261ecSmrg#ifdef XKB 7705b261ecSmrg#include "xkbsrv.h" 7805b261ecSmrg#endif 7905b261ecSmrg 8005b261ecSmrg#define WID(w) ((w) ? ((w)->drawable.id) : 0) 8105b261ecSmrg#define AllModifiersMask ( \ 8205b261ecSmrg ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \ 8305b261ecSmrg Mod3Mask | Mod4Mask | Mod5Mask ) 8405b261ecSmrg#define AllButtonsMask ( \ 8505b261ecSmrg Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask ) 8605b261ecSmrg#define Motion_Filter(class) (DevicePointerMotionMask | \ 8705b261ecSmrg (class)->state | (class)->motionMask) 8805b261ecSmrg 8905b261ecSmrgstatic Bool ShouldFreeInputMasks(WindowPtr /* pWin */ , 9005b261ecSmrg Bool /* ignoreSelectedEvents */ 9105b261ecSmrg ); 9205b261ecSmrgstatic Bool MakeInputMasks(WindowPtr /* pWin */ 9305b261ecSmrg ); 9405b261ecSmrg 9505b261ecSmrg/************************************************************************** 9605b261ecSmrg * 9705b261ecSmrg * Procedures for extension device event routing. 9805b261ecSmrg * 9905b261ecSmrg */ 10005b261ecSmrg 10105b261ecSmrgvoid 10205b261ecSmrgRegisterOtherDevice(DeviceIntPtr device) 10305b261ecSmrg{ 10405b261ecSmrg device->public.processInputProc = ProcessOtherEvent; 10505b261ecSmrg device->public.realInputProc = ProcessOtherEvent; 10605b261ecSmrg (device)->ActivateGrab = ActivateKeyboardGrab; 10705b261ecSmrg (device)->DeactivateGrab = DeactivateKeyboardGrab; 10805b261ecSmrg} 10905b261ecSmrg 11005b261ecSmrg /*ARGSUSED*/ void 11105b261ecSmrgProcessOtherEvent(xEventPtr xE, DeviceIntPtr other, int count) 11205b261ecSmrg{ 11305b261ecSmrg BYTE *kptr; 11405b261ecSmrg int i; 11505b261ecSmrg CARD16 modifiers; 11605b261ecSmrg CARD16 mask; 11705b261ecSmrg GrabPtr grab = other->grab; 11805b261ecSmrg Bool deactivateDeviceGrab = FALSE; 11905b261ecSmrg int key = 0, bit = 0, rootX, rootY; 12005b261ecSmrg ButtonClassPtr b = other->button; 12105b261ecSmrg KeyClassPtr k = other->key; 12205b261ecSmrg ValuatorClassPtr v = other->valuator; 12305b261ecSmrg deviceValuator *xV = (deviceValuator *) xE; 12405b261ecSmrg 12505b261ecSmrg if (xE->u.u.type != DeviceValuator) { 12605b261ecSmrg /* Other types already have root{X,Y} filled in. */ 12705b261ecSmrg if (xE->u.u.type == DeviceKeyPress || 12805b261ecSmrg xE->u.u.type == DeviceKeyRelease) { 12905b261ecSmrg GetSpritePosition(&rootX, &rootY); 13005b261ecSmrg xE->u.keyButtonPointer.rootX = rootX; 13105b261ecSmrg xE->u.keyButtonPointer.rootY = rootY; 13205b261ecSmrg } 13305b261ecSmrg 13405b261ecSmrg key = xE->u.u.detail; 13505b261ecSmrg NoticeEventTime(xE); 13605b261ecSmrg xE->u.keyButtonPointer.state = inputInfo.keyboard->key->state | 13705b261ecSmrg inputInfo.pointer->button->state; 13805b261ecSmrg bit = 1 << (key & 7); 13905b261ecSmrg } 14005b261ecSmrg if (DeviceEventCallback) { 14105b261ecSmrg DeviceEventInfoRec eventinfo; 14205b261ecSmrg 14305b261ecSmrg eventinfo.events = (xEventPtr) xE; 14405b261ecSmrg eventinfo.count = count; 14505b261ecSmrg CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo); 14605b261ecSmrg } 14705b261ecSmrg for (i = 1; i < count; i++) 14805b261ecSmrg if ((++xV)->type == DeviceValuator) { 14905b261ecSmrg int first = xV->first_valuator; 15005b261ecSmrg int *axisvals; 15105b261ecSmrg 15205b261ecSmrg if (xV->num_valuators 15305b261ecSmrg && (!v 15405b261ecSmrg || (xV->num_valuators 15505b261ecSmrg && (first + xV->num_valuators > v->numAxes)))) 15605b261ecSmrg FatalError("Bad valuators reported for device %s\n", 15705b261ecSmrg other->name); 15805b261ecSmrg xV->device_state = 0; 15905b261ecSmrg if (k) 16005b261ecSmrg xV->device_state |= k->state; 16105b261ecSmrg if (b) 16205b261ecSmrg xV->device_state |= b->state; 16305b261ecSmrg if (v && v->axisVal) { 16405b261ecSmrg axisvals = v->axisVal; 16505b261ecSmrg switch (xV->num_valuators) { 16605b261ecSmrg case 6: 16705b261ecSmrg *(axisvals + first + 5) = xV->valuator5; 16805b261ecSmrg case 5: 16905b261ecSmrg *(axisvals + first + 4) = xV->valuator4; 17005b261ecSmrg case 4: 17105b261ecSmrg *(axisvals + first + 3) = xV->valuator3; 17205b261ecSmrg case 3: 17305b261ecSmrg *(axisvals + first + 2) = xV->valuator2; 17405b261ecSmrg case 2: 17505b261ecSmrg *(axisvals + first + 1) = xV->valuator1; 17605b261ecSmrg case 1: 17705b261ecSmrg *(axisvals + first) = xV->valuator0; 17805b261ecSmrg case 0: 17905b261ecSmrg default: 18005b261ecSmrg break; 18105b261ecSmrg } 18205b261ecSmrg } 18305b261ecSmrg } 18405b261ecSmrg 18505b261ecSmrg if (xE->u.u.type == DeviceKeyPress) { 18605b261ecSmrg if (!k) 18705b261ecSmrg return; 18805b261ecSmrg 18905b261ecSmrg modifiers = k->modifierMap[key]; 19005b261ecSmrg kptr = &k->down[key >> 3]; 19105b261ecSmrg if (*kptr & bit) { /* allow ddx to generate multiple downs */ 19205b261ecSmrg if (!modifiers) { 19305b261ecSmrg xE->u.u.type = DeviceKeyRelease; 19405b261ecSmrg ProcessOtherEvent(xE, other, count); 19505b261ecSmrg xE->u.u.type = DeviceKeyPress; 19605b261ecSmrg /* release can have side effects, don't fall through */ 19705b261ecSmrg ProcessOtherEvent(xE, other, count); 19805b261ecSmrg } 19905b261ecSmrg return; 20005b261ecSmrg } 20105b261ecSmrg if (other->valuator) 20205b261ecSmrg other->valuator->motionHintWindow = NullWindow; 20305b261ecSmrg *kptr |= bit; 20405b261ecSmrg k->prev_state = k->state; 20505b261ecSmrg for (i = 0, mask = 1; modifiers; i++, mask <<= 1) { 20605b261ecSmrg if (mask & modifiers) { 20705b261ecSmrg /* This key affects modifier "i" */ 20805b261ecSmrg k->modifierKeyCount[i]++; 20905b261ecSmrg k->state |= mask; 21005b261ecSmrg modifiers &= ~mask; 21105b261ecSmrg } 21205b261ecSmrg } 21305b261ecSmrg if (!grab && CheckDeviceGrabs(other, xE, 0, count)) { 21405b261ecSmrg other->activatingKey = key; 21505b261ecSmrg return; 21605b261ecSmrg } 21705b261ecSmrg } else if (xE->u.u.type == DeviceKeyRelease) { 21805b261ecSmrg if (!k) 21905b261ecSmrg return; 22005b261ecSmrg 22105b261ecSmrg kptr = &k->down[key >> 3]; 22205b261ecSmrg if (!(*kptr & bit)) /* guard against duplicates */ 22305b261ecSmrg return; 22405b261ecSmrg modifiers = k->modifierMap[key]; 22505b261ecSmrg if (other->valuator) 22605b261ecSmrg other->valuator->motionHintWindow = NullWindow; 22705b261ecSmrg *kptr &= ~bit; 22805b261ecSmrg k->prev_state = k->state; 22905b261ecSmrg for (i = 0, mask = 1; modifiers; i++, mask <<= 1) { 23005b261ecSmrg if (mask & modifiers) { 23105b261ecSmrg /* This key affects modifier "i" */ 23205b261ecSmrg if (--k->modifierKeyCount[i] <= 0) { 23305b261ecSmrg k->modifierKeyCount[i] = 0; 23405b261ecSmrg k->state &= ~mask; 23505b261ecSmrg } 23605b261ecSmrg modifiers &= ~mask; 23705b261ecSmrg } 23805b261ecSmrg } 23905b261ecSmrg 24005b261ecSmrg if (other->fromPassiveGrab && (key == other->activatingKey)) 24105b261ecSmrg deactivateDeviceGrab = TRUE; 24205b261ecSmrg } else if (xE->u.u.type == DeviceButtonPress) { 24305b261ecSmrg if (!b) 24405b261ecSmrg return; 24505b261ecSmrg 24605b261ecSmrg kptr = &b->down[key >> 3]; 24705b261ecSmrg *kptr |= bit; 24805b261ecSmrg if (other->valuator) 24905b261ecSmrg other->valuator->motionHintWindow = NullWindow; 25005b261ecSmrg b->buttonsDown++; 25105b261ecSmrg b->motionMask = DeviceButtonMotionMask; 25205b261ecSmrg xE->u.u.detail = key; 25305b261ecSmrg if (xE->u.u.detail == 0) 25405b261ecSmrg return; 25505b261ecSmrg if (xE->u.u.detail <= 5) 25605b261ecSmrg b->state |= (Button1Mask >> 1) << xE->u.u.detail; 25705b261ecSmrg SetMaskForEvent(Motion_Filter(b), DeviceMotionNotify); 25805b261ecSmrg if (!grab) 25905b261ecSmrg if (CheckDeviceGrabs(other, xE, 0, count)) 26005b261ecSmrg /* if a passive grab was activated, the event has been sent 26105b261ecSmrg * already */ 26205b261ecSmrg return; 26305b261ecSmrg 26405b261ecSmrg } else if (xE->u.u.type == DeviceButtonRelease) { 26505b261ecSmrg if (!b) 26605b261ecSmrg return; 26705b261ecSmrg 26805b261ecSmrg kptr = &b->down[key >> 3]; 26905b261ecSmrg *kptr &= ~bit; 27005b261ecSmrg if (other->valuator) 27105b261ecSmrg other->valuator->motionHintWindow = NullWindow; 27205b261ecSmrg if (b->buttonsDown >= 1 && !--b->buttonsDown) 27305b261ecSmrg b->motionMask = 0; 27405b261ecSmrg xE->u.u.detail = key; 27505b261ecSmrg if (xE->u.u.detail == 0) 27605b261ecSmrg return; 27705b261ecSmrg if (xE->u.u.detail <= 5) 27805b261ecSmrg b->state &= ~((Button1Mask >> 1) << xE->u.u.detail); 27905b261ecSmrg SetMaskForEvent(Motion_Filter(b), DeviceMotionNotify); 28005b261ecSmrg if (!b->state && other->fromPassiveGrab) 28105b261ecSmrg deactivateDeviceGrab = TRUE; 28205b261ecSmrg } else if (xE->u.u.type == ProximityIn) 28305b261ecSmrg other->valuator->mode &= ~OutOfProximity; 28405b261ecSmrg else if (xE->u.u.type == ProximityOut) 28505b261ecSmrg other->valuator->mode |= OutOfProximity; 28605b261ecSmrg 28705b261ecSmrg if (grab) 28805b261ecSmrg DeliverGrabbedEvent(xE, other, deactivateDeviceGrab, count); 28905b261ecSmrg else if (other->focus) 29005b261ecSmrg DeliverFocusedEvent(other, xE, GetSpriteWindow(), count); 29105b261ecSmrg else 29205b261ecSmrg DeliverDeviceEvents(GetSpriteWindow(), xE, NullGrab, NullWindow, 29305b261ecSmrg other, count); 29405b261ecSmrg 29505b261ecSmrg if (deactivateDeviceGrab == TRUE) 29605b261ecSmrg (*other->DeactivateGrab) (other); 29705b261ecSmrg} 29805b261ecSmrg 29905b261ecSmrg_X_EXPORT int 30005b261ecSmrgInitProximityClassDeviceStruct(DeviceIntPtr dev) 30105b261ecSmrg{ 30205b261ecSmrg ProximityClassPtr proxc; 30305b261ecSmrg 30405b261ecSmrg proxc = (ProximityClassPtr) xalloc(sizeof(ProximityClassRec)); 30505b261ecSmrg if (!proxc) 30605b261ecSmrg return FALSE; 30705b261ecSmrg dev->proximity = proxc; 30805b261ecSmrg return TRUE; 30905b261ecSmrg} 31005b261ecSmrg 31105b261ecSmrg_X_EXPORT void 31205b261ecSmrgInitValuatorAxisStruct(DeviceIntPtr dev, int axnum, int minval, int maxval, 31305b261ecSmrg int resolution, int min_res, int max_res) 31405b261ecSmrg{ 31505b261ecSmrg AxisInfoPtr ax; 31605b261ecSmrg 31705b261ecSmrg if (!dev || !dev->valuator) 31805b261ecSmrg return; 31905b261ecSmrg 32005b261ecSmrg ax = dev->valuator->axes + axnum; 32105b261ecSmrg 32205b261ecSmrg ax->min_value = minval; 32305b261ecSmrg ax->max_value = maxval; 32405b261ecSmrg ax->resolution = resolution; 32505b261ecSmrg ax->min_resolution = min_res; 32605b261ecSmrg ax->max_resolution = max_res; 32705b261ecSmrg} 32805b261ecSmrg 32905b261ecSmrgstatic void 33005b261ecSmrgFixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k, 33105b261ecSmrg ButtonClassPtr b, ValuatorClassPtr v, int first) 33205b261ecSmrg{ 33305b261ecSmrg ev->type = DeviceStateNotify; 33405b261ecSmrg ev->deviceid = dev->id; 33505b261ecSmrg ev->time = currentTime.milliseconds; 33605b261ecSmrg ev->classes_reported = 0; 33705b261ecSmrg ev->num_keys = 0; 33805b261ecSmrg ev->num_buttons = 0; 33905b261ecSmrg ev->num_valuators = 0; 34005b261ecSmrg 34105b261ecSmrg if (b) { 34205b261ecSmrg ev->classes_reported |= (1 << ButtonClass); 34305b261ecSmrg ev->num_buttons = b->numButtons; 34405b261ecSmrg memmove((char *)&ev->buttons[0], (char *)b->down, 4); 34505b261ecSmrg } else if (k) { 34605b261ecSmrg ev->classes_reported |= (1 << KeyClass); 34705b261ecSmrg ev->num_keys = k->curKeySyms.maxKeyCode - k->curKeySyms.minKeyCode; 34805b261ecSmrg memmove((char *)&ev->keys[0], (char *)k->down, 4); 34905b261ecSmrg } 35005b261ecSmrg if (v) { 35105b261ecSmrg int nval = v->numAxes - first; 35205b261ecSmrg 35305b261ecSmrg ev->classes_reported |= (1 << ValuatorClass); 35405b261ecSmrg ev->classes_reported |= (dev->valuator->mode << ModeBitsShift); 35505b261ecSmrg ev->num_valuators = nval < 3 ? nval : 3; 35605b261ecSmrg switch (ev->num_valuators) { 35705b261ecSmrg case 3: 35805b261ecSmrg ev->valuator2 = v->axisVal[first + 2]; 35905b261ecSmrg case 2: 36005b261ecSmrg ev->valuator1 = v->axisVal[first + 1]; 36105b261ecSmrg case 1: 36205b261ecSmrg ev->valuator0 = v->axisVal[first]; 36305b261ecSmrg break; 36405b261ecSmrg } 36505b261ecSmrg } 36605b261ecSmrg} 36705b261ecSmrg 36805b261ecSmrgstatic void 36905b261ecSmrgFixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, 37005b261ecSmrg int first) 37105b261ecSmrg{ 37205b261ecSmrg int nval = v->numAxes - first; 37305b261ecSmrg 37405b261ecSmrg ev->type = DeviceValuator; 37505b261ecSmrg ev->deviceid = dev->id; 37605b261ecSmrg ev->num_valuators = nval < 3 ? nval : 3; 37705b261ecSmrg ev->first_valuator = first; 37805b261ecSmrg switch (ev->num_valuators) { 37905b261ecSmrg case 3: 38005b261ecSmrg ev->valuator2 = v->axisVal[first + 2]; 38105b261ecSmrg case 2: 38205b261ecSmrg ev->valuator1 = v->axisVal[first + 1]; 38305b261ecSmrg case 1: 38405b261ecSmrg ev->valuator0 = v->axisVal[first]; 38505b261ecSmrg break; 38605b261ecSmrg } 38705b261ecSmrg first += ev->num_valuators; 38805b261ecSmrg} 38905b261ecSmrg 39005b261ecSmrgvoid 39105b261ecSmrgDeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, 39205b261ecSmrg WindowPtr pWin) 39305b261ecSmrg{ 39405b261ecSmrg deviceFocus event; 39505b261ecSmrg 39605b261ecSmrg if (type == FocusIn) 39705b261ecSmrg type = DeviceFocusIn; 39805b261ecSmrg else 39905b261ecSmrg type = DeviceFocusOut; 40005b261ecSmrg 40105b261ecSmrg event.deviceid = dev->id; 40205b261ecSmrg event.mode = mode; 40305b261ecSmrg event.type = type; 40405b261ecSmrg event.detail = detail; 40505b261ecSmrg event.window = pWin->drawable.id; 40605b261ecSmrg event.time = currentTime.milliseconds; 40705b261ecSmrg 40805b261ecSmrg (void)DeliverEventsToWindow(pWin, (xEvent *) & event, 1, 40905b261ecSmrg DeviceFocusChangeMask, NullGrab, dev->id); 41005b261ecSmrg 41105b261ecSmrg if ((type == DeviceFocusIn) && 41205b261ecSmrg (wOtherInputMasks(pWin)) && 41305b261ecSmrg (wOtherInputMasks(pWin)->inputEvents[dev->id] & DeviceStateNotifyMask)) 41405b261ecSmrg { 41505b261ecSmrg int evcount = 1; 41605b261ecSmrg deviceStateNotify *ev, *sev; 41705b261ecSmrg deviceKeyStateNotify *kev; 41805b261ecSmrg deviceButtonStateNotify *bev; 41905b261ecSmrg 42005b261ecSmrg KeyClassPtr k; 42105b261ecSmrg ButtonClassPtr b; 42205b261ecSmrg ValuatorClassPtr v; 42305b261ecSmrg int nval = 0, nkeys = 0, nbuttons = 0, first = 0; 42405b261ecSmrg 42505b261ecSmrg if ((b = dev->button) != NULL) { 42605b261ecSmrg nbuttons = b->numButtons; 42705b261ecSmrg if (nbuttons > 32) 42805b261ecSmrg evcount++; 42905b261ecSmrg } 43005b261ecSmrg if ((k = dev->key) != NULL) { 43105b261ecSmrg nkeys = k->curKeySyms.maxKeyCode - k->curKeySyms.minKeyCode; 43205b261ecSmrg if (nkeys > 32) 43305b261ecSmrg evcount++; 43405b261ecSmrg if (nbuttons > 0) { 43505b261ecSmrg evcount++; 43605b261ecSmrg } 43705b261ecSmrg } 43805b261ecSmrg if ((v = dev->valuator) != NULL) { 43905b261ecSmrg nval = v->numAxes; 44005b261ecSmrg 44105b261ecSmrg if (nval > 3) 44205b261ecSmrg evcount++; 44305b261ecSmrg if (nval > 6) { 44405b261ecSmrg if (!(k && b)) 44505b261ecSmrg evcount++; 44605b261ecSmrg if (nval > 9) 44705b261ecSmrg evcount += ((nval - 7) / 3); 44805b261ecSmrg } 44905b261ecSmrg } 45005b261ecSmrg 45105b261ecSmrg sev = ev = (deviceStateNotify *) xalloc(evcount * sizeof(xEvent)); 45205b261ecSmrg FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); 45305b261ecSmrg 45405b261ecSmrg if (b != NULL) { 45505b261ecSmrg FixDeviceStateNotify(dev, ev++, NULL, b, v, first); 45605b261ecSmrg first += 3; 45705b261ecSmrg nval -= 3; 45805b261ecSmrg if (nbuttons > 32) { 45905b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 46005b261ecSmrg bev = (deviceButtonStateNotify *) ev++; 46105b261ecSmrg bev->type = DeviceButtonStateNotify; 46205b261ecSmrg bev->deviceid = dev->id; 46305b261ecSmrg memmove((char *)&bev->buttons[0], (char *)&b->down[4], 28); 46405b261ecSmrg } 46505b261ecSmrg if (nval > 0) { 46605b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 46705b261ecSmrg FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 46805b261ecSmrg first += 3; 46905b261ecSmrg nval -= 3; 47005b261ecSmrg } 47105b261ecSmrg } 47205b261ecSmrg 47305b261ecSmrg if (k != NULL) { 47405b261ecSmrg FixDeviceStateNotify(dev, ev++, k, NULL, v, first); 47505b261ecSmrg first += 3; 47605b261ecSmrg nval -= 3; 47705b261ecSmrg if (nkeys > 32) { 47805b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 47905b261ecSmrg kev = (deviceKeyStateNotify *) ev++; 48005b261ecSmrg kev->type = DeviceKeyStateNotify; 48105b261ecSmrg kev->deviceid = dev->id; 48205b261ecSmrg memmove((char *)&kev->keys[0], (char *)&k->down[4], 28); 48305b261ecSmrg } 48405b261ecSmrg if (nval > 0) { 48505b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 48605b261ecSmrg FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 48705b261ecSmrg first += 3; 48805b261ecSmrg nval -= 3; 48905b261ecSmrg } 49005b261ecSmrg } 49105b261ecSmrg 49205b261ecSmrg while (nval > 0) { 49305b261ecSmrg FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first); 49405b261ecSmrg first += 3; 49505b261ecSmrg nval -= 3; 49605b261ecSmrg if (nval > 0) { 49705b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 49805b261ecSmrg FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 49905b261ecSmrg first += 3; 50005b261ecSmrg nval -= 3; 50105b261ecSmrg } 50205b261ecSmrg } 50305b261ecSmrg 50405b261ecSmrg (void)DeliverEventsToWindow(pWin, (xEvent *) sev, evcount, 50505b261ecSmrg DeviceStateNotifyMask, NullGrab, dev->id); 50605b261ecSmrg xfree(sev); 50705b261ecSmrg } 50805b261ecSmrg} 50905b261ecSmrg 51005b261ecSmrgint 51105b261ecSmrgGrabButton(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode, 51205b261ecSmrg BYTE other_devices_mode, CARD16 modifiers, 51305b261ecSmrg DeviceIntPtr modifier_device, CARD8 button, Window grabWindow, 51405b261ecSmrg BOOL ownerEvents, Cursor rcursor, Window rconfineTo, Mask eventMask) 51505b261ecSmrg{ 51605b261ecSmrg WindowPtr pWin, confineTo; 51705b261ecSmrg CursorPtr cursor; 51805b261ecSmrg GrabPtr grab; 51905b261ecSmrg int rc; 52005b261ecSmrg 52105b261ecSmrg if ((this_device_mode != GrabModeSync) && 52205b261ecSmrg (this_device_mode != GrabModeAsync)) { 52305b261ecSmrg client->errorValue = this_device_mode; 52405b261ecSmrg return BadValue; 52505b261ecSmrg } 52605b261ecSmrg if ((other_devices_mode != GrabModeSync) && 52705b261ecSmrg (other_devices_mode != GrabModeAsync)) { 52805b261ecSmrg client->errorValue = other_devices_mode; 52905b261ecSmrg return BadValue; 53005b261ecSmrg } 53105b261ecSmrg if ((modifiers != AnyModifier) && (modifiers & ~AllModifiersMask)) { 53205b261ecSmrg client->errorValue = modifiers; 53305b261ecSmrg return BadValue; 53405b261ecSmrg } 53505b261ecSmrg if ((ownerEvents != xFalse) && (ownerEvents != xTrue)) { 53605b261ecSmrg client->errorValue = ownerEvents; 53705b261ecSmrg return BadValue; 53805b261ecSmrg } 53905b261ecSmrg rc = dixLookupWindow(&pWin, grabWindow, client, DixUnknownAccess); 54005b261ecSmrg if (rc != Success) 54105b261ecSmrg return rc; 54205b261ecSmrg if (rconfineTo == None) 54305b261ecSmrg confineTo = NullWindow; 54405b261ecSmrg else { 54505b261ecSmrg rc = dixLookupWindow(&confineTo, rconfineTo, client, DixUnknownAccess); 54605b261ecSmrg if (rc != Success) 54705b261ecSmrg return rc; 54805b261ecSmrg } 54905b261ecSmrg if (rcursor == None) 55005b261ecSmrg cursor = NullCursor; 55105b261ecSmrg else { 55205b261ecSmrg cursor = (CursorPtr) LookupIDByType(rcursor, RT_CURSOR); 55305b261ecSmrg if (!cursor) { 55405b261ecSmrg client->errorValue = rcursor; 55505b261ecSmrg return BadCursor; 55605b261ecSmrg } 55705b261ecSmrg } 55805b261ecSmrg 55905b261ecSmrg grab = CreateGrab(client->index, dev, pWin, eventMask, 56005b261ecSmrg (Bool) ownerEvents, (Bool) this_device_mode, 56105b261ecSmrg (Bool) other_devices_mode, modifier_device, modifiers, 56205b261ecSmrg DeviceButtonPress, button, confineTo, cursor); 56305b261ecSmrg if (!grab) 56405b261ecSmrg return BadAlloc; 56505b261ecSmrg return AddPassiveGrabToList(grab); 56605b261ecSmrg} 56705b261ecSmrg 56805b261ecSmrgint 56905b261ecSmrgGrabKey(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode, 57005b261ecSmrg BYTE other_devices_mode, CARD16 modifiers, 57105b261ecSmrg DeviceIntPtr modifier_device, CARD8 key, Window grabWindow, 57205b261ecSmrg BOOL ownerEvents, Mask mask) 57305b261ecSmrg{ 57405b261ecSmrg WindowPtr pWin; 57505b261ecSmrg GrabPtr grab; 57605b261ecSmrg KeyClassPtr k = dev->key; 57705b261ecSmrg int rc; 57805b261ecSmrg 57905b261ecSmrg if (k == NULL) 58005b261ecSmrg return BadMatch; 58105b261ecSmrg if ((other_devices_mode != GrabModeSync) && 58205b261ecSmrg (other_devices_mode != GrabModeAsync)) { 58305b261ecSmrg client->errorValue = other_devices_mode; 58405b261ecSmrg return BadValue; 58505b261ecSmrg } 58605b261ecSmrg if ((this_device_mode != GrabModeSync) && 58705b261ecSmrg (this_device_mode != GrabModeAsync)) { 58805b261ecSmrg client->errorValue = this_device_mode; 58905b261ecSmrg return BadValue; 59005b261ecSmrg } 59105b261ecSmrg if (((key > k->curKeySyms.maxKeyCode) || (key < k->curKeySyms.minKeyCode)) 59205b261ecSmrg && (key != AnyKey)) { 59305b261ecSmrg client->errorValue = key; 59405b261ecSmrg return BadValue; 59505b261ecSmrg } 59605b261ecSmrg if ((modifiers != AnyModifier) && (modifiers & ~AllModifiersMask)) { 59705b261ecSmrg client->errorValue = modifiers; 59805b261ecSmrg return BadValue; 59905b261ecSmrg } 60005b261ecSmrg if ((ownerEvents != xTrue) && (ownerEvents != xFalse)) { 60105b261ecSmrg client->errorValue = ownerEvents; 60205b261ecSmrg return BadValue; 60305b261ecSmrg } 60405b261ecSmrg rc = dixLookupWindow(&pWin, grabWindow, client, DixUnknownAccess); 60505b261ecSmrg if (rc != Success) 60605b261ecSmrg return rc; 60705b261ecSmrg 60805b261ecSmrg grab = CreateGrab(client->index, dev, pWin, 60905b261ecSmrg mask, ownerEvents, this_device_mode, other_devices_mode, 61005b261ecSmrg modifier_device, modifiers, DeviceKeyPress, key, 61105b261ecSmrg NullWindow, NullCursor); 61205b261ecSmrg if (!grab) 61305b261ecSmrg return BadAlloc; 61405b261ecSmrg return AddPassiveGrabToList(grab); 61505b261ecSmrg} 61605b261ecSmrg 61705b261ecSmrgint 61805b261ecSmrgSelectForWindow(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client, 61905b261ecSmrg Mask mask, Mask exclusivemasks, Mask validmasks) 62005b261ecSmrg{ 62105b261ecSmrg int mskidx = dev->id; 62205b261ecSmrg int i, ret; 62305b261ecSmrg Mask check; 62405b261ecSmrg InputClientsPtr others; 62505b261ecSmrg 62605b261ecSmrg if (mask & ~validmasks) { 62705b261ecSmrg client->errorValue = mask; 62805b261ecSmrg return BadValue; 62905b261ecSmrg } 63005b261ecSmrg check = (mask & exclusivemasks); 63105b261ecSmrg if (wOtherInputMasks(pWin)) { 63205b261ecSmrg if (check & wOtherInputMasks(pWin)->inputEvents[mskidx]) { /* It is illegal for two different 63305b261ecSmrg * clients to select on any of the 63405b261ecSmrg * events for maskcheck. However, 63505b261ecSmrg * it is OK, for some client to 63605b261ecSmrg * continue selecting on one of those 63705b261ecSmrg * events. */ 63805b261ecSmrg for (others = wOtherInputMasks(pWin)->inputClients; others; 63905b261ecSmrg others = others->next) { 64005b261ecSmrg if (!SameClient(others, client) && (check & 64105b261ecSmrg others->mask[mskidx])) 64205b261ecSmrg return BadAccess; 64305b261ecSmrg } 64405b261ecSmrg } 64505b261ecSmrg for (others = wOtherInputMasks(pWin)->inputClients; others; 64605b261ecSmrg others = others->next) { 64705b261ecSmrg if (SameClient(others, client)) { 64805b261ecSmrg check = others->mask[mskidx]; 64905b261ecSmrg others->mask[mskidx] = mask; 65005b261ecSmrg if (mask == 0) { 65105b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 65205b261ecSmrg if (i != mskidx && others->mask[i] != 0) 65305b261ecSmrg break; 65405b261ecSmrg if (i == EMASKSIZE) { 65505b261ecSmrg RecalculateDeviceDeliverableEvents(pWin); 65605b261ecSmrg if (ShouldFreeInputMasks(pWin, FALSE)) 65705b261ecSmrg FreeResource(others->resource, RT_NONE); 65805b261ecSmrg return Success; 65905b261ecSmrg } 66005b261ecSmrg } 66105b261ecSmrg goto maskSet; 66205b261ecSmrg } 66305b261ecSmrg } 66405b261ecSmrg } 66505b261ecSmrg check = 0; 66605b261ecSmrg if ((ret = AddExtensionClient(pWin, client, mask, mskidx)) != Success) 66705b261ecSmrg return ret; 66805b261ecSmrg maskSet: 66905b261ecSmrg if (dev->valuator) 67005b261ecSmrg if ((dev->valuator->motionHintWindow == pWin) && 67105b261ecSmrg (mask & DevicePointerMotionHintMask) && 67205b261ecSmrg !(check & DevicePointerMotionHintMask) && !dev->grab) 67305b261ecSmrg dev->valuator->motionHintWindow = NullWindow; 67405b261ecSmrg RecalculateDeviceDeliverableEvents(pWin); 67505b261ecSmrg return Success; 67605b261ecSmrg} 67705b261ecSmrg 67805b261ecSmrgint 67905b261ecSmrgAddExtensionClient(WindowPtr pWin, ClientPtr client, Mask mask, int mskidx) 68005b261ecSmrg{ 68105b261ecSmrg InputClientsPtr others; 68205b261ecSmrg 68305b261ecSmrg if (!pWin->optional && !MakeWindowOptional(pWin)) 68405b261ecSmrg return BadAlloc; 68505b261ecSmrg others = (InputClients *) xalloc(sizeof(InputClients)); 68605b261ecSmrg if (!others) 68705b261ecSmrg return BadAlloc; 68805b261ecSmrg if (!pWin->optional->inputMasks && !MakeInputMasks(pWin)) 68905b261ecSmrg return BadAlloc; 69005b261ecSmrg bzero((char *)&others->mask[0], sizeof(Mask) * EMASKSIZE); 69105b261ecSmrg others->mask[mskidx] = mask; 69205b261ecSmrg others->resource = FakeClientID(client->index); 69305b261ecSmrg others->next = pWin->optional->inputMasks->inputClients; 69405b261ecSmrg pWin->optional->inputMasks->inputClients = others; 69505b261ecSmrg if (!AddResource(others->resource, RT_INPUTCLIENT, (pointer) pWin)) 69605b261ecSmrg return BadAlloc; 69705b261ecSmrg return Success; 69805b261ecSmrg} 69905b261ecSmrg 70005b261ecSmrgstatic Bool 70105b261ecSmrgMakeInputMasks(WindowPtr pWin) 70205b261ecSmrg{ 70305b261ecSmrg struct _OtherInputMasks *imasks; 70405b261ecSmrg 70505b261ecSmrg imasks = (struct _OtherInputMasks *) 70605b261ecSmrg xalloc(sizeof(struct _OtherInputMasks)); 70705b261ecSmrg if (!imasks) 70805b261ecSmrg return FALSE; 70905b261ecSmrg bzero((char *)imasks, sizeof(struct _OtherInputMasks)); 71005b261ecSmrg pWin->optional->inputMasks = imasks; 71105b261ecSmrg return TRUE; 71205b261ecSmrg} 71305b261ecSmrg 71405b261ecSmrgvoid 71505b261ecSmrgRecalculateDeviceDeliverableEvents(WindowPtr pWin) 71605b261ecSmrg{ 71705b261ecSmrg InputClientsPtr others; 71805b261ecSmrg struct _OtherInputMasks *inputMasks; /* default: NULL */ 71905b261ecSmrg WindowPtr pChild, tmp; 72005b261ecSmrg int i; 72105b261ecSmrg 72205b261ecSmrg pChild = pWin; 72305b261ecSmrg while (1) { 72405b261ecSmrg if ((inputMasks = wOtherInputMasks(pChild)) != 0) { 72505b261ecSmrg for (others = inputMasks->inputClients; others; 72605b261ecSmrg others = others->next) { 72705b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 72805b261ecSmrg inputMasks->inputEvents[i] |= others->mask[i]; 72905b261ecSmrg } 73005b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 73105b261ecSmrg inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i]; 73205b261ecSmrg for (tmp = pChild->parent; tmp; tmp = tmp->parent) 73305b261ecSmrg if (wOtherInputMasks(tmp)) 73405b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 73505b261ecSmrg inputMasks->deliverableEvents[i] |= 73605b261ecSmrg (wOtherInputMasks(tmp)->deliverableEvents[i] 73705b261ecSmrg & ~inputMasks-> 73805b261ecSmrg dontPropagateMask[i] & PropagateMask[i]); 73905b261ecSmrg } 74005b261ecSmrg if (pChild->firstChild) { 74105b261ecSmrg pChild = pChild->firstChild; 74205b261ecSmrg continue; 74305b261ecSmrg } 74405b261ecSmrg while (!pChild->nextSib && (pChild != pWin)) 74505b261ecSmrg pChild = pChild->parent; 74605b261ecSmrg if (pChild == pWin) 74705b261ecSmrg break; 74805b261ecSmrg pChild = pChild->nextSib; 74905b261ecSmrg } 75005b261ecSmrg} 75105b261ecSmrg 75205b261ecSmrgint 75305b261ecSmrgInputClientGone(WindowPtr pWin, XID id) 75405b261ecSmrg{ 75505b261ecSmrg InputClientsPtr other, prev; 75605b261ecSmrg 75705b261ecSmrg if (!wOtherInputMasks(pWin)) 75805b261ecSmrg return (Success); 75905b261ecSmrg prev = 0; 76005b261ecSmrg for (other = wOtherInputMasks(pWin)->inputClients; other; 76105b261ecSmrg other = other->next) { 76205b261ecSmrg if (other->resource == id) { 76305b261ecSmrg if (prev) { 76405b261ecSmrg prev->next = other->next; 76505b261ecSmrg xfree(other); 76605b261ecSmrg } else if (!(other->next)) { 76705b261ecSmrg if (ShouldFreeInputMasks(pWin, TRUE)) { 76805b261ecSmrg wOtherInputMasks(pWin)->inputClients = other->next; 76905b261ecSmrg xfree(wOtherInputMasks(pWin)); 77005b261ecSmrg pWin->optional->inputMasks = (OtherInputMasks *) NULL; 77105b261ecSmrg CheckWindowOptionalNeed(pWin); 77205b261ecSmrg xfree(other); 77305b261ecSmrg } else { 77405b261ecSmrg other->resource = FakeClientID(0); 77505b261ecSmrg if (!AddResource(other->resource, RT_INPUTCLIENT, 77605b261ecSmrg (pointer) pWin)) 77705b261ecSmrg return BadAlloc; 77805b261ecSmrg } 77905b261ecSmrg } else { 78005b261ecSmrg wOtherInputMasks(pWin)->inputClients = other->next; 78105b261ecSmrg xfree(other); 78205b261ecSmrg } 78305b261ecSmrg RecalculateDeviceDeliverableEvents(pWin); 78405b261ecSmrg return (Success); 78505b261ecSmrg } 78605b261ecSmrg prev = other; 78705b261ecSmrg } 78805b261ecSmrg FatalError("client not on device event list"); 78905b261ecSmrg} 79005b261ecSmrg 79105b261ecSmrgint 79205b261ecSmrgSendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate, 79305b261ecSmrg xEvent * ev, Mask mask, int count) 79405b261ecSmrg{ 79505b261ecSmrg WindowPtr pWin; 79605b261ecSmrg WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */ 79705b261ecSmrg WindowPtr spriteWin = GetSpriteWindow(); 79805b261ecSmrg 79905b261ecSmrg if (dest == PointerWindow) 80005b261ecSmrg pWin = spriteWin; 80105b261ecSmrg else if (dest == InputFocus) { 80205b261ecSmrg WindowPtr inputFocus; 80305b261ecSmrg 80405b261ecSmrg if (!d->focus) 80505b261ecSmrg inputFocus = spriteWin; 80605b261ecSmrg else 80705b261ecSmrg inputFocus = d->focus->win; 80805b261ecSmrg 80905b261ecSmrg if (inputFocus == FollowKeyboardWin) 81005b261ecSmrg inputFocus = inputInfo.keyboard->focus->win; 81105b261ecSmrg 81205b261ecSmrg if (inputFocus == NoneWin) 81305b261ecSmrg return Success; 81405b261ecSmrg 81505b261ecSmrg /* If the input focus is PointerRootWin, send the event to where 81605b261ecSmrg * the pointer is if possible, then perhaps propogate up to root. */ 81705b261ecSmrg if (inputFocus == PointerRootWin) 81805b261ecSmrg inputFocus = GetCurrentRootWindow(); 81905b261ecSmrg 82005b261ecSmrg if (IsParent(inputFocus, spriteWin)) { 82105b261ecSmrg effectiveFocus = inputFocus; 82205b261ecSmrg pWin = spriteWin; 82305b261ecSmrg } else 82405b261ecSmrg effectiveFocus = pWin = inputFocus; 82505b261ecSmrg } else 82605b261ecSmrg dixLookupWindow(&pWin, dest, client, DixUnknownAccess); 82705b261ecSmrg if (!pWin) 82805b261ecSmrg return BadWindow; 82905b261ecSmrg if ((propagate != xFalse) && (propagate != xTrue)) { 83005b261ecSmrg client->errorValue = propagate; 83105b261ecSmrg return BadValue; 83205b261ecSmrg } 83305b261ecSmrg ev->u.u.type |= 0x80; 83405b261ecSmrg if (propagate) { 83505b261ecSmrg for (; pWin; pWin = pWin->parent) { 83605b261ecSmrg if (DeliverEventsToWindow(pWin, ev, count, mask, NullGrab, d->id)) 83705b261ecSmrg return Success; 83805b261ecSmrg if (pWin == effectiveFocus) 83905b261ecSmrg return Success; 84005b261ecSmrg if (wOtherInputMasks(pWin)) 84105b261ecSmrg mask &= ~wOtherInputMasks(pWin)->dontPropagateMask[d->id]; 84205b261ecSmrg if (!mask) 84305b261ecSmrg break; 84405b261ecSmrg } 84505b261ecSmrg } else 84605b261ecSmrg (void)(DeliverEventsToWindow(pWin, ev, count, mask, NullGrab, d->id)); 84705b261ecSmrg return Success; 84805b261ecSmrg} 84905b261ecSmrg 85005b261ecSmrgint 85105b261ecSmrgSetButtonMapping(ClientPtr client, DeviceIntPtr dev, int nElts, BYTE * map) 85205b261ecSmrg{ 85305b261ecSmrg int i; 85405b261ecSmrg ButtonClassPtr b = dev->button; 85505b261ecSmrg 85605b261ecSmrg if (b == NULL) 85705b261ecSmrg return BadMatch; 85805b261ecSmrg 85905b261ecSmrg if (nElts != b->numButtons) { 86005b261ecSmrg client->errorValue = nElts; 86105b261ecSmrg return BadValue; 86205b261ecSmrg } 86305b261ecSmrg if (BadDeviceMap(&map[0], nElts, 1, 255, &client->errorValue)) 86405b261ecSmrg return BadValue; 86505b261ecSmrg for (i = 0; i < nElts; i++) 86605b261ecSmrg if ((b->map[i + 1] != map[i]) && BitIsOn(b->down, i + 1)) 86705b261ecSmrg return MappingBusy; 86805b261ecSmrg for (i = 0; i < nElts; i++) 86905b261ecSmrg b->map[i + 1] = map[i]; 87005b261ecSmrg return Success; 87105b261ecSmrg} 87205b261ecSmrg 87305b261ecSmrgint 87405b261ecSmrgSetModifierMapping(ClientPtr client, DeviceIntPtr dev, int len, int rlen, 87505b261ecSmrg int numKeyPerModifier, KeyCode * inputMap, KeyClassPtr * k) 87605b261ecSmrg{ 87705b261ecSmrg KeyCode *map = NULL; 87805b261ecSmrg int inputMapLen; 87905b261ecSmrg int i; 88005b261ecSmrg 88105b261ecSmrg *k = dev->key; 88205b261ecSmrg if (*k == NULL) 88305b261ecSmrg return BadMatch; 88405b261ecSmrg if (len != ((numKeyPerModifier << 1) + rlen)) 88505b261ecSmrg return BadLength; 88605b261ecSmrg 88705b261ecSmrg inputMapLen = 8 * numKeyPerModifier; 88805b261ecSmrg 88905b261ecSmrg /* 89005b261ecSmrg * Now enforce the restriction that "all of the non-zero keycodes must be 89105b261ecSmrg * in the range specified by min-keycode and max-keycode in the 89205b261ecSmrg * connection setup (else a Value error)" 89305b261ecSmrg */ 89405b261ecSmrg i = inputMapLen; 89505b261ecSmrg while (i--) { 89605b261ecSmrg if (inputMap[i] 89705b261ecSmrg && (inputMap[i] < (*k)->curKeySyms.minKeyCode 89805b261ecSmrg || inputMap[i] > (*k)->curKeySyms.maxKeyCode)) { 89905b261ecSmrg client->errorValue = inputMap[i]; 90005b261ecSmrg return -1; /* BadValue collides with MappingFailed */ 90105b261ecSmrg } 90205b261ecSmrg } 90305b261ecSmrg 90405b261ecSmrg /* 90505b261ecSmrg * Now enforce the restriction that none of the old or new 90605b261ecSmrg * modifier keys may be down while we change the mapping, and 90705b261ecSmrg * that the DDX layer likes the choice. 90805b261ecSmrg */ 90905b261ecSmrg if (!AllModifierKeysAreUp(dev, (*k)->modifierKeyMap, 91005b261ecSmrg (int)(*k)->maxKeysPerModifier, inputMap, 91105b261ecSmrg (int)numKeyPerModifier) 91205b261ecSmrg || !AllModifierKeysAreUp(dev, inputMap, (int)numKeyPerModifier, 91305b261ecSmrg (*k)->modifierKeyMap, 91405b261ecSmrg (int)(*k)->maxKeysPerModifier)) { 91505b261ecSmrg return MappingBusy; 91605b261ecSmrg } else { 91705b261ecSmrg for (i = 0; i < inputMapLen; i++) { 91805b261ecSmrg if (inputMap[i] && !LegalModifier(inputMap[i], dev)) { 91905b261ecSmrg return MappingFailed; 92005b261ecSmrg } 92105b261ecSmrg } 92205b261ecSmrg } 92305b261ecSmrg 92405b261ecSmrg /* 92505b261ecSmrg * Now build the keyboard's modifier bitmap from the 92605b261ecSmrg * list of keycodes. 92705b261ecSmrg */ 92805b261ecSmrg if (inputMapLen) { 92905b261ecSmrg map = (KeyCode *) xalloc(inputMapLen); 93005b261ecSmrg if (!map) 93105b261ecSmrg return BadAlloc; 93205b261ecSmrg } 93305b261ecSmrg if ((*k)->modifierKeyMap) 93405b261ecSmrg xfree((*k)->modifierKeyMap); 93505b261ecSmrg if (inputMapLen) { 93605b261ecSmrg (*k)->modifierKeyMap = map; 93705b261ecSmrg memmove((char *)(*k)->modifierKeyMap, (char *)inputMap, inputMapLen); 93805b261ecSmrg } else 93905b261ecSmrg (*k)->modifierKeyMap = NULL; 94005b261ecSmrg 94105b261ecSmrg (*k)->maxKeysPerModifier = numKeyPerModifier; 94205b261ecSmrg for (i = 0; i < MAP_LENGTH; i++) 94305b261ecSmrg (*k)->modifierMap[i] = 0; 94405b261ecSmrg for (i = 0; i < inputMapLen; i++) 94505b261ecSmrg if (inputMap[i]) { 94605b261ecSmrg (*k)->modifierMap[inputMap[i]] 94705b261ecSmrg |= (1 << (i / (*k)->maxKeysPerModifier)); 94805b261ecSmrg } 94905b261ecSmrg 95005b261ecSmrg return (MappingSuccess); 95105b261ecSmrg} 95205b261ecSmrg 95305b261ecSmrgvoid 95405b261ecSmrgSendDeviceMappingNotify(ClientPtr client, CARD8 request, 95505b261ecSmrg KeyCode firstKeyCode, CARD8 count, DeviceIntPtr dev) 95605b261ecSmrg{ 95705b261ecSmrg xEvent event; 95805b261ecSmrg deviceMappingNotify *ev = (deviceMappingNotify *) & event; 95905b261ecSmrg 96005b261ecSmrg ev->type = DeviceMappingNotify; 96105b261ecSmrg ev->request = request; 96205b261ecSmrg ev->deviceid = dev->id; 96305b261ecSmrg ev->time = currentTime.milliseconds; 96405b261ecSmrg if (request == MappingKeyboard) { 96505b261ecSmrg ev->firstKeyCode = firstKeyCode; 96605b261ecSmrg ev->count = count; 96705b261ecSmrg } 96805b261ecSmrg 96905b261ecSmrg#ifdef XKB 97005b261ecSmrg if (request == MappingKeyboard || request == MappingModifier) 97105b261ecSmrg XkbApplyMappingChange(dev, request, firstKeyCode, count, client); 97205b261ecSmrg#endif 97305b261ecSmrg 97405b261ecSmrg SendEventToAllWindows(dev, DeviceMappingNotifyMask, (xEvent *) ev, 1); 97505b261ecSmrg} 97605b261ecSmrg 97705b261ecSmrgint 97805b261ecSmrgChangeKeyMapping(ClientPtr client, 97905b261ecSmrg DeviceIntPtr dev, 98005b261ecSmrg unsigned len, 98105b261ecSmrg int type, 98205b261ecSmrg KeyCode firstKeyCode, 98305b261ecSmrg CARD8 keyCodes, CARD8 keySymsPerKeyCode, KeySym * map) 98405b261ecSmrg{ 98505b261ecSmrg KeySymsRec keysyms; 98605b261ecSmrg KeyClassPtr k = dev->key; 98705b261ecSmrg 98805b261ecSmrg if (k == NULL) 98905b261ecSmrg return (BadMatch); 99005b261ecSmrg 99105b261ecSmrg if (len != (keyCodes * keySymsPerKeyCode)) 99205b261ecSmrg return BadLength; 99305b261ecSmrg 99405b261ecSmrg if ((firstKeyCode < k->curKeySyms.minKeyCode) || 99505b261ecSmrg (firstKeyCode + keyCodes - 1 > k->curKeySyms.maxKeyCode)) { 99605b261ecSmrg client->errorValue = firstKeyCode; 99705b261ecSmrg return BadValue; 99805b261ecSmrg } 99905b261ecSmrg if (keySymsPerKeyCode == 0) { 100005b261ecSmrg client->errorValue = 0; 100105b261ecSmrg return BadValue; 100205b261ecSmrg } 100305b261ecSmrg keysyms.minKeyCode = firstKeyCode; 100405b261ecSmrg keysyms.maxKeyCode = firstKeyCode + keyCodes - 1; 100505b261ecSmrg keysyms.mapWidth = keySymsPerKeyCode; 100605b261ecSmrg keysyms.map = map; 100705b261ecSmrg if (!SetKeySymsMap(&k->curKeySyms, &keysyms)) 100805b261ecSmrg return BadAlloc; 100905b261ecSmrg SendDeviceMappingNotify(client, MappingKeyboard, firstKeyCode, keyCodes, dev); 101005b261ecSmrg return client->noClientException; 101105b261ecSmrg} 101205b261ecSmrg 101305b261ecSmrgstatic void 101405b261ecSmrgDeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev) 101505b261ecSmrg{ 101605b261ecSmrg WindowPtr parent; 101705b261ecSmrg 101805b261ecSmrg /* Deactivate any grabs performed on this window, before making 101905b261ecSmrg * any input focus changes. 102005b261ecSmrg * Deactivating a device grab should cause focus events. */ 102105b261ecSmrg 102205b261ecSmrg if (dev->grab && (dev->grab->window == pWin)) 102305b261ecSmrg (*dev->DeactivateGrab) (dev); 102405b261ecSmrg 102505b261ecSmrg /* If the focus window is a root window (ie. has no parent) 102605b261ecSmrg * then don't delete the focus from it. */ 102705b261ecSmrg 102805b261ecSmrg if (dev->focus && (pWin == dev->focus->win) && (pWin->parent != NullWindow)) { 102905b261ecSmrg int focusEventMode = NotifyNormal; 103005b261ecSmrg 103105b261ecSmrg /* If a grab is in progress, then alter the mode of focus events. */ 103205b261ecSmrg 103305b261ecSmrg if (dev->grab) 103405b261ecSmrg focusEventMode = NotifyWhileGrabbed; 103505b261ecSmrg 103605b261ecSmrg switch (dev->focus->revert) { 103705b261ecSmrg case RevertToNone: 103805b261ecSmrg DoFocusEvents(dev, pWin, NoneWin, focusEventMode); 103905b261ecSmrg dev->focus->win = NoneWin; 104005b261ecSmrg dev->focus->traceGood = 0; 104105b261ecSmrg break; 104205b261ecSmrg case RevertToParent: 104305b261ecSmrg parent = pWin; 104405b261ecSmrg do { 104505b261ecSmrg parent = parent->parent; 104605b261ecSmrg dev->focus->traceGood--; 104705b261ecSmrg } 104805b261ecSmrg while (!parent->realized); 104905b261ecSmrg DoFocusEvents(dev, pWin, parent, focusEventMode); 105005b261ecSmrg dev->focus->win = parent; 105105b261ecSmrg dev->focus->revert = RevertToNone; 105205b261ecSmrg break; 105305b261ecSmrg case RevertToPointerRoot: 105405b261ecSmrg DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode); 105505b261ecSmrg dev->focus->win = PointerRootWin; 105605b261ecSmrg dev->focus->traceGood = 0; 105705b261ecSmrg break; 105805b261ecSmrg case RevertToFollowKeyboard: 105905b261ecSmrg if (inputInfo.keyboard->focus->win) { 106005b261ecSmrg DoFocusEvents(dev, pWin, inputInfo.keyboard->focus->win, 106105b261ecSmrg focusEventMode); 106205b261ecSmrg dev->focus->win = FollowKeyboardWin; 106305b261ecSmrg dev->focus->traceGood = 0; 106405b261ecSmrg } else { 106505b261ecSmrg DoFocusEvents(dev, pWin, NoneWin, focusEventMode); 106605b261ecSmrg dev->focus->win = NoneWin; 106705b261ecSmrg dev->focus->traceGood = 0; 106805b261ecSmrg } 106905b261ecSmrg break; 107005b261ecSmrg } 107105b261ecSmrg } 107205b261ecSmrg 107305b261ecSmrg if (dev->valuator) 107405b261ecSmrg if (dev->valuator->motionHintWindow == pWin) 107505b261ecSmrg dev->valuator->motionHintWindow = NullWindow; 107605b261ecSmrg} 107705b261ecSmrg 107805b261ecSmrgvoid 107905b261ecSmrgDeleteWindowFromAnyExtEvents(WindowPtr pWin, Bool freeResources) 108005b261ecSmrg{ 108105b261ecSmrg int i; 108205b261ecSmrg DeviceIntPtr dev; 108305b261ecSmrg InputClientsPtr ic; 108405b261ecSmrg struct _OtherInputMasks *inputMasks; 108505b261ecSmrg 108605b261ecSmrg for (dev = inputInfo.devices; dev; dev = dev->next) { 108705b261ecSmrg if (dev == inputInfo.pointer || dev == inputInfo.keyboard) 108805b261ecSmrg continue; 108905b261ecSmrg DeleteDeviceFromAnyExtEvents(pWin, dev); 109005b261ecSmrg } 109105b261ecSmrg 109205b261ecSmrg for (dev = inputInfo.off_devices; dev; dev = dev->next) 109305b261ecSmrg DeleteDeviceFromAnyExtEvents(pWin, dev); 109405b261ecSmrg 109505b261ecSmrg if (freeResources) 109605b261ecSmrg while ((inputMasks = wOtherInputMasks(pWin)) != 0) { 109705b261ecSmrg ic = inputMasks->inputClients; 109805b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 109905b261ecSmrg inputMasks->dontPropagateMask[i] = 0; 110005b261ecSmrg FreeResource(ic->resource, RT_NONE); 110105b261ecSmrg } 110205b261ecSmrg} 110305b261ecSmrg 110405b261ecSmrgint 110505b261ecSmrgMaybeSendDeviceMotionNotifyHint(deviceKeyButtonPointer * pEvents, Mask mask) 110605b261ecSmrg{ 110705b261ecSmrg DeviceIntPtr dev; 110805b261ecSmrg 110905b261ecSmrg dev = LookupDeviceIntRec(pEvents->deviceid & DEVICE_BITS); 111005b261ecSmrg if (!dev) 111105b261ecSmrg return 0; 111205b261ecSmrg 111305b261ecSmrg if (pEvents->type == DeviceMotionNotify) { 111405b261ecSmrg if (mask & DevicePointerMotionHintMask) { 111505b261ecSmrg if (WID(dev->valuator->motionHintWindow) == pEvents->event) { 111605b261ecSmrg return 1; /* don't send, but pretend we did */ 111705b261ecSmrg } 111805b261ecSmrg pEvents->detail = NotifyHint; 111905b261ecSmrg } else { 112005b261ecSmrg pEvents->detail = NotifyNormal; 112105b261ecSmrg } 112205b261ecSmrg } 112305b261ecSmrg return (0); 112405b261ecSmrg} 112505b261ecSmrg 112605b261ecSmrgvoid 112705b261ecSmrgCheckDeviceGrabAndHintWindow(WindowPtr pWin, int type, 112805b261ecSmrg deviceKeyButtonPointer * xE, GrabPtr grab, 112905b261ecSmrg ClientPtr client, Mask deliveryMask) 113005b261ecSmrg{ 113105b261ecSmrg DeviceIntPtr dev; 113205b261ecSmrg 113305b261ecSmrg dev = LookupDeviceIntRec(xE->deviceid & DEVICE_BITS); 113405b261ecSmrg if (!dev) 113505b261ecSmrg return; 113605b261ecSmrg 113705b261ecSmrg if (type == DeviceMotionNotify) 113805b261ecSmrg dev->valuator->motionHintWindow = pWin; 113905b261ecSmrg else if ((type == DeviceButtonPress) && (!grab) && 114005b261ecSmrg (deliveryMask & DeviceButtonGrabMask)) { 114105b261ecSmrg GrabRec tempGrab; 114205b261ecSmrg 114305b261ecSmrg tempGrab.device = dev; 114405b261ecSmrg tempGrab.resource = client->clientAsMask; 114505b261ecSmrg tempGrab.window = pWin; 114605b261ecSmrg tempGrab.ownerEvents = 114705b261ecSmrg (deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE; 114805b261ecSmrg tempGrab.eventMask = deliveryMask; 114905b261ecSmrg tempGrab.keyboardMode = GrabModeAsync; 115005b261ecSmrg tempGrab.pointerMode = GrabModeAsync; 115105b261ecSmrg tempGrab.confineTo = NullWindow; 115205b261ecSmrg tempGrab.cursor = NullCursor; 115305b261ecSmrg (*dev->ActivateGrab) (dev, &tempGrab, currentTime, TRUE); 115405b261ecSmrg } 115505b261ecSmrg} 115605b261ecSmrg 115705b261ecSmrgstatic Mask 115805b261ecSmrgDeviceEventMaskForClient(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client) 115905b261ecSmrg{ 116005b261ecSmrg InputClientsPtr other; 116105b261ecSmrg 116205b261ecSmrg if (!wOtherInputMasks(pWin)) 116305b261ecSmrg return 0; 116405b261ecSmrg for (other = wOtherInputMasks(pWin)->inputClients; other; 116505b261ecSmrg other = other->next) { 116605b261ecSmrg if (SameClient(other, client)) 116705b261ecSmrg return other->mask[dev->id]; 116805b261ecSmrg } 116905b261ecSmrg return 0; 117005b261ecSmrg} 117105b261ecSmrg 117205b261ecSmrgvoid 117305b261ecSmrgMaybeStopDeviceHint(DeviceIntPtr dev, ClientPtr client) 117405b261ecSmrg{ 117505b261ecSmrg WindowPtr pWin; 117605b261ecSmrg GrabPtr grab = dev->grab; 117705b261ecSmrg 117805b261ecSmrg pWin = dev->valuator->motionHintWindow; 117905b261ecSmrg 118005b261ecSmrg if ((grab && SameClient(grab, client) && 118105b261ecSmrg ((grab->eventMask & DevicePointerMotionHintMask) || 118205b261ecSmrg (grab->ownerEvents && 118305b261ecSmrg (DeviceEventMaskForClient(dev, pWin, client) & 118405b261ecSmrg DevicePointerMotionHintMask)))) || 118505b261ecSmrg (!grab && 118605b261ecSmrg (DeviceEventMaskForClient(dev, pWin, client) & 118705b261ecSmrg DevicePointerMotionHintMask))) 118805b261ecSmrg dev->valuator->motionHintWindow = NullWindow; 118905b261ecSmrg} 119005b261ecSmrg 119105b261ecSmrgint 119205b261ecSmrgDeviceEventSuppressForWindow(WindowPtr pWin, ClientPtr client, Mask mask, 119305b261ecSmrg int maskndx) 119405b261ecSmrg{ 119505b261ecSmrg struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); 119605b261ecSmrg 119705b261ecSmrg if (mask & ~PropagateMask[maskndx]) { 119805b261ecSmrg client->errorValue = mask; 119905b261ecSmrg return BadValue; 120005b261ecSmrg } 120105b261ecSmrg 120205b261ecSmrg if (mask == 0) { 120305b261ecSmrg if (inputMasks) 120405b261ecSmrg inputMasks->dontPropagateMask[maskndx] = mask; 120505b261ecSmrg } else { 120605b261ecSmrg if (!inputMasks) 120705b261ecSmrg AddExtensionClient(pWin, client, 0, 0); 120805b261ecSmrg inputMasks = wOtherInputMasks(pWin); 120905b261ecSmrg inputMasks->dontPropagateMask[maskndx] = mask; 121005b261ecSmrg } 121105b261ecSmrg RecalculateDeviceDeliverableEvents(pWin); 121205b261ecSmrg if (ShouldFreeInputMasks(pWin, FALSE)) 121305b261ecSmrg FreeResource(inputMasks->inputClients->resource, RT_NONE); 121405b261ecSmrg return Success; 121505b261ecSmrg} 121605b261ecSmrg 121705b261ecSmrgstatic Bool 121805b261ecSmrgShouldFreeInputMasks(WindowPtr pWin, Bool ignoreSelectedEvents) 121905b261ecSmrg{ 122005b261ecSmrg int i; 122105b261ecSmrg Mask allInputEventMasks = 0; 122205b261ecSmrg struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); 122305b261ecSmrg 122405b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 122505b261ecSmrg allInputEventMasks |= inputMasks->dontPropagateMask[i]; 122605b261ecSmrg if (!ignoreSelectedEvents) 122705b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 122805b261ecSmrg allInputEventMasks |= inputMasks->inputEvents[i]; 122905b261ecSmrg if (allInputEventMasks == 0) 123005b261ecSmrg return TRUE; 123105b261ecSmrg else 123205b261ecSmrg return FALSE; 123305b261ecSmrg} 123405b261ecSmrg 123505b261ecSmrg/*********************************************************************** 123605b261ecSmrg * 123705b261ecSmrg * Walk through the window tree, finding all clients that want to know 123805b261ecSmrg * about the Event. 123905b261ecSmrg * 124005b261ecSmrg */ 124105b261ecSmrg 124205b261ecSmrgstatic void 124305b261ecSmrgFindInterestedChildren(DeviceIntPtr dev, WindowPtr p1, Mask mask, 124405b261ecSmrg xEvent * ev, int count) 124505b261ecSmrg{ 124605b261ecSmrg WindowPtr p2; 124705b261ecSmrg 124805b261ecSmrg while (p1) { 124905b261ecSmrg p2 = p1->firstChild; 125005b261ecSmrg (void)DeliverEventsToWindow(p1, ev, count, mask, NullGrab, dev->id); 125105b261ecSmrg FindInterestedChildren(dev, p2, mask, ev, count); 125205b261ecSmrg p1 = p1->nextSib; 125305b261ecSmrg } 125405b261ecSmrg} 125505b261ecSmrg 125605b261ecSmrg/*********************************************************************** 125705b261ecSmrg * 125805b261ecSmrg * Send an event to interested clients in all windows on all screens. 125905b261ecSmrg * 126005b261ecSmrg */ 126105b261ecSmrg 126205b261ecSmrgvoid 126305b261ecSmrgSendEventToAllWindows(DeviceIntPtr dev, Mask mask, xEvent * ev, int count) 126405b261ecSmrg{ 126505b261ecSmrg int i; 126605b261ecSmrg WindowPtr pWin, p1; 126705b261ecSmrg 126805b261ecSmrg for (i = 0; i < screenInfo.numScreens; i++) { 126905b261ecSmrg pWin = WindowTable[i]; 127005b261ecSmrg (void)DeliverEventsToWindow(pWin, ev, count, mask, NullGrab, dev->id); 127105b261ecSmrg p1 = pWin->firstChild; 127205b261ecSmrg FindInterestedChildren(dev, p1, mask, ev, count); 127305b261ecSmrg } 127405b261ecSmrg} 1275