From c38dead3ea7e177728d90cd815cf4eead0c9f534 Mon Sep 17 00:00:00 2001 From: marha Date: Sat, 15 May 2010 16:28:11 +0000 Subject: xserver git update 15/5/2010 --- xorg-server/Xi/exevents.c | 4356 ++++++++++++++++++------------------ xorg-server/Xi/extinit.c | 2 +- xorg-server/Xi/getdctl.c | 628 +++--- xorg-server/Xi/getfctl.c | 732 +++--- xorg-server/Xi/getkmap.c | 316 +-- xorg-server/Xi/getmmap.c | 274 +-- xorg-server/Xi/getprop.c | 374 ++-- xorg-server/Xi/getselev.c | 356 +-- xorg-server/Xi/gtmotion.c | 356 +-- xorg-server/Xi/listdev.c | 868 +++---- xorg-server/Xi/queryst.c | 382 ++-- xorg-server/Xi/xichangehierarchy.c | 908 ++++---- xorg-server/Xi/xipassivegrab.c | 626 +++--- xorg-server/Xi/xiproperty.c | 28 +- xorg-server/Xi/xiquerydevice.c | 1006 ++++----- xorg-server/Xi/xiquerypointer.c | 456 ++-- xorg-server/Xi/xiselectev.c | 598 ++--- 17 files changed, 6133 insertions(+), 6133 deletions(-) (limited to 'xorg-server/Xi') diff --git a/xorg-server/Xi/exevents.c b/xorg-server/Xi/exevents.c index 949efe77f..97ad6fdd2 100644 --- a/xorg-server/Xi/exevents.c +++ b/xorg-server/Xi/exevents.c @@ -1,2178 +1,2178 @@ -/************************************************************ - -Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. - - 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 Hewlett-Packard not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -HEWLETT-PACKARD 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. - -********************************************************/ - -/******************************************************************** - * - * Routines to register and initialize extension input devices. - * This also contains ProcessOtherEvent, the routine called from DDX - * to route extension events. - * - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "inputstr.h" -#include -#include -#include -#include -#include -#include -#include "windowstr.h" -#include "miscstruct.h" -#include "region.h" -#include "exevents.h" -#include "extnsionst.h" -#include "exglobals.h" -#include "dixevents.h" /* DeliverFocusedEvent */ -#include "dixgrabs.h" /* CreateGrab() */ -#include "scrnintstr.h" -#include "listdev.h" /* for CopySwapXXXClass */ -#include "xace.h" -#include "xiquerydevice.h" /* For List*Info */ -#include "eventconvert.h" -#include "eventstr.h" - -#include -#include "xkbsrv.h" - -#define WID(w) ((w) ? ((w)->drawable.id) : 0) -#define AllModifiersMask ( \ - ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \ - Mod3Mask | Mod4Mask | Mod5Mask ) -#define AllButtonsMask ( \ - Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask ) - -Bool ShouldFreeInputMasks(WindowPtr /* pWin */ , - Bool /* ignoreSelectedEvents */ - ); -static Bool MakeInputMasks(WindowPtr /* pWin */ - ); - -/* - * Only let the given client know of core events which will affect its - * interpretation of input events, if the client's ClientPointer (or the - * paired keyboard) is the current device. - */ -int -XIShouldNotify(ClientPtr client, DeviceIntPtr dev) -{ - DeviceIntPtr current_ptr = PickPointer(client); - DeviceIntPtr current_kbd = GetPairedDevice(current_ptr); - - if (dev == current_kbd || dev == current_ptr) - return 1; - - return 0; -} - -void -RegisterOtherDevice(DeviceIntPtr device) -{ - device->public.processInputProc = ProcessOtherEvent; - device->public.realInputProc = ProcessOtherEvent; -} - -Bool -IsPointerEvent(InternalEvent* event) -{ - switch(event->any.type) - { - case ET_ButtonPress: - case ET_ButtonRelease: - case ET_Motion: - /* XXX: enter/leave ?? */ - return TRUE; - default: - break; - } - return FALSE; -} - -/** - * @return the device matching the deviceid of the device set in the event, or - * NULL if the event is not an XInput event. - */ -DeviceIntPtr -XIGetDevice(xEvent* xE) -{ - DeviceIntPtr pDev = NULL; - - if (xE->u.u.type == DeviceButtonPress || - xE->u.u.type == DeviceButtonRelease || - xE->u.u.type == DeviceMotionNotify || - xE->u.u.type == ProximityIn || - xE->u.u.type == ProximityOut || - xE->u.u.type == DevicePropertyNotify) - { - int rc; - int id; - - id = ((deviceKeyButtonPointer*)xE)->deviceid & ~MORE_EVENTS; - - rc = dixLookupDevice(&pDev, id, serverClient, DixUnknownAccess); - if (rc != Success) - ErrorF("[dix] XIGetDevice failed on XACE restrictions (%d)\n", rc); - } - return pDev; -} - - -/** - * Copy the device->key into master->key and send a mapping notify to the - * clients if appropriate. - * master->key needs to be allocated by the caller. - * - * Device is the slave device. If it is attached to a master device, we may - * need to send a mapping notify to the client because it causes the MD - * to change state. - * - * Mapping notify needs to be sent in the following cases: - * - different slave device on same master - * - different master - * - * XXX: They way how the code is we also send a map notify if the slave device - * stays the same, but the master changes. This isn't really necessary though. - * - * XXX: this gives you funny behaviour with the ClientPointer. When a - * MappingNotify is sent to the client, the client usually responds with a - * GetKeyboardMapping. This will retrieve the ClientPointer's keyboard - * mapping, regardless of which keyboard sent the last mapping notify request. - * So depending on the CP setting, your keyboard may change layout in each - * app... - * - * This code is basically the old SwitchCoreKeyboard. - */ - -void -CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master) -{ - KeyClassPtr mk = master->key; - KeyClassPtr dk = device->key; - int i; - - if (device == master) - return; - - mk->sourceid = device->id; - - for (i = 0; i < 8; i++) - mk->modifierKeyCount[i] = dk->modifierKeyCount[i]; - - if (!XkbCopyDeviceKeymap(master, device)) - FatalError("Couldn't pivot keymap from device to core!\n"); -} - -/** - * Copies the feedback classes from device "from" into device "to". Classes - * are duplicated (not just flipping the pointers). All feedback classes are - * linked lists, the full list is duplicated. - */ -static void -DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) -{ - ClassesPtr classes; - - - if (from->intfeed) - { - IntegerFeedbackPtr *i, it; - - if (!to->intfeed) - { - classes = to->unused_classes; - to->intfeed = classes->intfeed; - } - - i = &to->intfeed; - for (it = from->intfeed; it; it = it->next) - { - if (!(*i)) - { - *i = xcalloc(1, sizeof(IntegerFeedbackClassRec)); - if (!(*i)) - { - ErrorF("[Xi] Cannot alloc memory for class copy."); - return; - } - } - (*i)->CtrlProc = it->CtrlProc; - (*i)->ctrl = it->ctrl; - - i = &(*i)->next; - } - } else if (to->intfeed && !from->intfeed) - { - ClassesPtr classes; - classes = to->unused_classes; - classes->intfeed = to->intfeed; - to->intfeed = NULL; - } - - if (from->stringfeed) - { - StringFeedbackPtr *s, it; - - if (!to->stringfeed) - { - classes = to->unused_classes; - to->stringfeed = classes->stringfeed; - } - - s = &to->stringfeed; - for (it = from->stringfeed; it; it = it->next) - { - if (!(*s)) - { - *s = xcalloc(1, sizeof(StringFeedbackClassRec)); - if (!(*s)) - { - ErrorF("[Xi] Cannot alloc memory for class copy."); - return; - } - } - (*s)->CtrlProc = it->CtrlProc; - (*s)->ctrl = it->ctrl; - - s = &(*s)->next; - } - } else if (to->stringfeed && !from->stringfeed) - { - ClassesPtr classes; - classes = to->unused_classes; - classes->stringfeed = to->stringfeed; - to->stringfeed = NULL; - } - - if (from->bell) - { - BellFeedbackPtr *b, it; - - if (!to->bell) - { - classes = to->unused_classes; - to->bell = classes->bell; - } - - b = &to->bell; - for (it = from->bell; it; it = it->next) - { - if (!(*b)) - { - *b = xcalloc(1, sizeof(BellFeedbackClassRec)); - if (!(*b)) - { - ErrorF("[Xi] Cannot alloc memory for class copy."); - return; - } - } - (*b)->BellProc = it->BellProc; - (*b)->CtrlProc = it->CtrlProc; - (*b)->ctrl = it->ctrl; - - b = &(*b)->next; - } - } else if (to->bell && !from->bell) - { - ClassesPtr classes; - classes = to->unused_classes; - classes->bell = to->bell; - to->bell = NULL; - } - - if (from->leds) - { - LedFeedbackPtr *l, it; - - if (!to->leds) - { - classes = to->unused_classes; - to->leds = classes->leds; - } - - l = &to->leds; - for (it = from->leds; it; it = it->next) - { - if (!(*l)) - { - *l = xcalloc(1, sizeof(LedFeedbackClassRec)); - if (!(*l)) - { - ErrorF("[Xi] Cannot alloc memory for class copy."); - return; - } - } - (*l)->CtrlProc = it->CtrlProc; - (*l)->ctrl = it->ctrl; - if ((*l)->xkb_sli) - XkbFreeSrvLedInfo((*l)->xkb_sli); - (*l)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, NULL, *l); - - l = &(*l)->next; - } - } else if (to->leds && !from->leds) - { - ClassesPtr classes; - classes = to->unused_classes; - classes->leds = to->leds; - to->leds = NULL; - } -} - -static void -DeepCopyKeyboardClasses(DeviceIntPtr from, DeviceIntPtr to) -{ - ClassesPtr classes; - - /* XkbInitDevice (->XkbInitIndicatorMap->XkbFindSrvLedInfo) relies on the - * kbdfeed to be set up properly, so let's do the feedback classes first. - */ - if (from->kbdfeed) - { - KbdFeedbackPtr *k, it; - - if (!to->kbdfeed) - { - classes = to->unused_classes; - - to->kbdfeed = classes->kbdfeed; - if (!to->kbdfeed) - InitKeyboardDeviceStruct(to, NULL, NULL, NULL); - } - - k = &to->kbdfeed; - for(it = from->kbdfeed; it; it = it->next) - { - if (!(*k)) - { - *k = xcalloc(1, sizeof(KbdFeedbackClassRec)); - if (!*k) - { - ErrorF("[Xi] Cannot alloc memory for class copy."); - return; - } - } - (*k)->BellProc = it->BellProc; - (*k)->CtrlProc = it->CtrlProc; - (*k)->ctrl = it->ctrl; - if ((*k)->xkb_sli) - XkbFreeSrvLedInfo((*k)->xkb_sli); - (*k)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, *k, NULL); - - k = &(*k)->next; - } - } else if (to->kbdfeed && !from->kbdfeed) - { - ClassesPtr classes; - classes = to->unused_classes; - classes->kbdfeed = to->kbdfeed; - to->kbdfeed = NULL; - } - - if (from->key) - { - if (!to->key) - { - classes = to->unused_classes; - to->key = classes->key; - if (!to->key) - InitKeyboardDeviceStruct(to, NULL, NULL, NULL); - else - classes->key = NULL; - } - - CopyKeyClass(from, to); - } else if (to->key && !from->key) - { - ClassesPtr classes; - classes = to->unused_classes; - classes->key = to->key; - to->key = NULL; - } - - /* If a SrvLedInfoPtr's flags are XkbSLI_IsDefault, the names and maps - * pointer point into the xkbInfo->desc struct. XkbCopySrvLedInfo - * didn't update the pointers so we need to do it manually here. - */ - if (to->kbdfeed) - { - KbdFeedbackPtr k; - - for (k = to->kbdfeed; k; k = k->next) - { - if (!k->xkb_sli) - continue; - if (k->xkb_sli->flags & XkbSLI_IsDefault) - { - k->xkb_sli->names = to->key->xkbInfo->desc->names->indicators; - k->xkb_sli->maps = to->key->xkbInfo->desc->indicators->maps; - } - } - } - - /* We can't just copy over the focus class. When an app sets the focus, - * it'll do so on the master device. Copying the SDs focus means losing - * the focus. - * So we only copy the focus class if the device didn't have one, - * otherwise we leave it as it is. - */ - if (from->focus) - { - if (!to->focus) - { - WindowPtr *oldTrace; - - classes = to->unused_classes; - to->focus = classes->focus; - if (!to->focus) - { - to->focus = xcalloc(1, sizeof(FocusClassRec)); - if (!to->focus) - FatalError("[Xi] no memory for class shift.\n"); - } else - classes->focus = NULL; - - oldTrace = to->focus->trace; - memcpy(to->focus, from->focus, sizeof(FocusClassRec)); - to->focus->trace = xrealloc(oldTrace, - to->focus->traceSize * sizeof(WindowPtr)); - if (!to->focus->trace && to->focus->traceSize) - FatalError("[Xi] no memory for trace.\n"); - memcpy(to->focus->trace, from->focus->trace, - from->focus->traceSize * sizeof(WindowPtr)); - to->focus->sourceid = from->id; - } - } else if (to->focus) - { - ClassesPtr classes; - classes = to->unused_classes; - classes->focus = to->focus; - to->focus = NULL; - } - -} - -static void -DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to) -{ - ClassesPtr classes; - - /* Feedback classes must be copied first */ - if (from->ptrfeed) - { - PtrFeedbackPtr *p, it; - if (!to->ptrfeed) - { - classes = to->unused_classes; - to->ptrfeed = classes->ptrfeed; - } - - p = &to->ptrfeed; - for (it = from->ptrfeed; it; it = it->next) - { - if (!(*p)) - { - *p = xcalloc(1, sizeof(PtrFeedbackClassRec)); - if (!*p) - { - ErrorF("[Xi] Cannot alloc memory for class copy."); - return; - } - } - (*p)->CtrlProc = it->CtrlProc; - (*p)->ctrl = it->ctrl; - - p = &(*p)->next; - } - } else if (to->ptrfeed && !from->ptrfeed) - { - ClassesPtr classes; - classes = to->unused_classes; - classes->ptrfeed = to->ptrfeed; - to->ptrfeed = NULL; - } - - if (from->valuator) - { - ValuatorClassPtr v; - if (!to->valuator) - { - classes = to->unused_classes; - to->valuator = classes->valuator; - if (to->valuator) - classes->valuator = NULL; - } - - to->valuator = xrealloc(to->valuator, sizeof(ValuatorClassRec) + - from->valuator->numAxes * sizeof(AxisInfo) + - from->valuator->numAxes * sizeof(double)); - v = to->valuator; - if (!v) - FatalError("[Xi] no memory for class shift.\n"); - - v->numAxes = from->valuator->numAxes; - v->axes = (AxisInfoPtr)&v[1]; - memcpy(v->axes, from->valuator->axes, v->numAxes * sizeof(AxisInfo)); - - v->axisVal = (double*)(v->axes + from->valuator->numAxes); - v->sourceid = from->id; - v->mode = from->valuator->mode; - } else if (to->valuator && !from->valuator) - { - ClassesPtr classes; - classes = to->unused_classes; - classes->valuator = to->valuator; - to->valuator = NULL; - } - - if (from->button) - { - if (!to->button) - { - classes = to->unused_classes; - to->button = classes->button; - if (!to->button) - { - to->button = xcalloc(1, sizeof(ButtonClassRec)); - if (!to->button) - FatalError("[Xi] no memory for class shift.\n"); - } else - classes->button = NULL; - } - - if (from->button->xkb_acts) - { - if (!to->button->xkb_acts) - { - to->button->xkb_acts = xcalloc(1, sizeof(XkbAction)); - if (!to->button->xkb_acts) - FatalError("[Xi] not enough memory for xkb_acts.\n"); - } - memcpy(to->button->xkb_acts, from->button->xkb_acts, - sizeof(XkbAction)); - } else - xfree(to->button->xkb_acts); - - memcpy(to->button->labels, from->button->labels, - from->button->numButtons * sizeof(Atom)); - to->button->sourceid = from->id; - } else if (to->button && !from->button) - { - ClassesPtr classes; - classes = to->unused_classes; - classes->button = to->button; - to->button = NULL; - } - - if (from->proximity) - { - if (!to->proximity) - { - classes = to->unused_classes; - to->proximity = classes->proximity; - if (!to->proximity) - { - to->proximity = xcalloc(1, sizeof(ProximityClassRec)); - if (!to->proximity) - FatalError("[Xi] no memory for class shift.\n"); - } else - classes->proximity = NULL; - } - memcpy(to->proximity, from->proximity, sizeof(ProximityClassRec)); - to->proximity->sourceid = from->id; - } else if (to->proximity) - { - ClassesPtr classes; - classes = to->unused_classes; - classes->proximity = to->proximity; - to->proximity = NULL; - } - - if (from->absolute) - { - if (!to->absolute) - { - classes = to->unused_classes; - to->absolute = classes->absolute; - if (!to->absolute) - { - to->absolute = xcalloc(1, sizeof(AbsoluteClassRec)); - if (!to->absolute) - FatalError("[Xi] no memory for class shift.\n"); - } else - classes->absolute = NULL; - } - memcpy(to->absolute, from->absolute, sizeof(AbsoluteClassRec)); - to->absolute->sourceid = from->id; - } else if (to->absolute) - { - ClassesPtr classes; - classes = to->unused_classes; - classes->absolute = to->absolute; - to->absolute = NULL; - } -} - -/** - * Copies the CONTENT of the classes of device from into the classes in device - * to. From and to are identical after finishing. - * - * If to does not have classes from currenly has, the classes are stored in - * to's devPrivates system. Later, we recover it again from there if needed. - * Saves a few memory allocations. - */ -void -DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to, DeviceChangedEvent *dce) -{ - /* generic feedback classes, not tied to pointer and/or keyboard */ - DeepCopyFeedbackClasses(from, to); - - if ((dce->flags & DEVCHANGE_KEYBOARD_EVENT)) - DeepCopyKeyboardClasses(from, to); - if ((dce->flags & DEVCHANGE_POINTER_EVENT)) - DeepCopyPointerClasses(from, to); -} - - -/** - * Send an XI2 DeviceChangedEvent to all interested clients. - */ -void -XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChangedEvent *dce) -{ - xXIDeviceChangedEvent *dcce; - int rc; - - rc = EventToXI2((InternalEvent*)dce, (xEvent**)&dcce); - if (rc != Success) - { - ErrorF("[Xi] event conversion from DCE failed with code %d\n", rc); - return; - } - - /* we don't actually swap if there's a NullClient, swapping is done - * later when event is delivered. */ - SendEventToAllWindows(master, XI_DeviceChangedMask, (xEvent*)dcce, 1); - xfree(dcce); -} - -static void -ChangeMasterDeviceClasses(DeviceIntPtr device, DeviceChangedEvent *dce) -{ - DeviceIntPtr slave; - int rc; - - /* For now, we don't have devices that change physically. */ - if (!IsMaster(device)) - return; - - rc = dixLookupDevice(&slave, dce->sourceid, serverClient, DixReadAccess); - - if (rc != Success) - return; /* Device has disappeared */ - - if (!slave->u.master) - return; /* set floating since the event */ - - if (slave->u.master->id != dce->masterid) - return; /* not our slave anymore, don't care */ - - /* FIXME: we probably need to send a DCE for the new slave now */ - - device->public.devicePrivate = slave->public.devicePrivate; - - /* FIXME: the classes may have changed since we generated the event. */ - DeepCopyDeviceClasses(slave, device, dce); - XISendDeviceChangedEvent(slave, device, dce); -} - -/** - * Update the device state according to the data in the event. - * - * return values are - * DEFAULT ... process as normal - * DONT_PROCESS ... return immediately from caller - */ -#define DEFAULT 0 -#define DONT_PROCESS 1 -int -UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event) -{ - int i; - int key = 0, - bit = 0, - last_valuator; - - KeyClassPtr k = NULL; - ButtonClassPtr b = NULL; - ValuatorClassPtr v = NULL; - BYTE *kptr = NULL; - - /* This event is always the first we get, before the actual events with - * the data. However, the way how the DDX is set up, "device" will - * actually be the slave device that caused the event. - */ - switch(event->type) - { - case ET_DeviceChanged: - ChangeMasterDeviceClasses(device, (DeviceChangedEvent*)event); - return DONT_PROCESS; /* event has been sent already */ - case ET_Motion: - case ET_ButtonPress: - case ET_ButtonRelease: - case ET_KeyPress: - case ET_KeyRelease: - case ET_ProximityIn: - case ET_ProximityOut: - break; - default: - /* other events don't update the device */ - return DEFAULT; - } - - k = device->key; - v = device->valuator; - b = device->button; - - key = event->detail.key; - bit = 1 << (key & 7); - - /* Update device axis */ - /* Check valuators first */ - last_valuator = -1; - for (i = 0; i < MAX_VALUATORS; i++) - { - if (BitIsOn(&event->valuators.mask, i)) - { - if (!v) - { - ErrorF("[Xi] Valuators reported for non-valuator device '%s'. " - "Ignoring event.\n", device->name); - return DONT_PROCESS; - } else if (v->numAxes < i) - { - ErrorF("[Xi] Too many valuators reported for device '%s'. " - "Ignoring event.\n", device->name); - return DONT_PROCESS; - } - last_valuator = i; - } - } - - for (i = 0; i <= last_valuator && i < v->numAxes; i++) - { - if (BitIsOn(&event->valuators.mask, i)) - { - /* XXX: Relative/Absolute mode */ - v->axisVal[i] = event->valuators.data[i]; - v->axisVal[i] += (event->valuators.data_frac[i] * 1.0f / (1 << 16) / (1 << 16)); - } - } - - if (event->type == ET_KeyPress) { - if (!k) - return DONT_PROCESS; - - kptr = &k->down[key >> 3]; - /* don't allow ddx to generate multiple downs, but repeats are okay */ - if ((*kptr & bit) && !event->key_repeat) - return DONT_PROCESS; - if (device->valuator) - device->valuator->motionHintWindow = NullWindow; - *kptr |= bit; - } else if (event->type == ET_KeyRelease) { - if (!k) - return DONT_PROCESS; - - kptr = &k->down[key >> 3]; - if (!(*kptr & bit)) /* guard against duplicates */ - return DONT_PROCESS; - if (device->valuator) - device->valuator->motionHintWindow = NullWindow; - *kptr &= ~bit; - } else if (event->type == ET_ButtonPress) { - Mask mask; - if (!b) - return DONT_PROCESS; - - kptr = &b->down[key >> 3]; - if ((*kptr & bit) != 0) - return DONT_PROCESS; - *kptr |= bit; - if (device->valuator) - device->valuator->motionHintWindow = NullWindow; - if (!b->map[key]) - return DONT_PROCESS; - b->buttonsDown++; - b->motionMask = DeviceButtonMotionMask; - if (b->map[key] <= 5) - b->state |= (Button1Mask >> 1) << b->map[key]; - - /* Add state and motionMask to the filter for this event */ - mask = DevicePointerMotionMask | b->state | b->motionMask; - SetMaskForEvent(device->id, mask, DeviceMotionNotify); - mask = PointerMotionMask | b->state | b->motionMask; - SetMaskForEvent(device->id, mask, MotionNotify); - } else if (event->type == ET_ButtonRelease) { - Mask mask; - if (!b) - return DONT_PROCESS; - - kptr = &b->down[key>>3]; - if (!(*kptr & bit)) - return DONT_PROCESS; - if (IsMaster(device)) { - DeviceIntPtr sd; - - /* - * Leave the button down if any slave has the - * button still down. Note that this depends on the - * event being delivered through the slave first - */ - for (sd = inputInfo.devices; sd; sd = sd->next) { - if (IsMaster(sd) || sd->u.master != device) - continue; - if (!sd->button) - continue; - if ((sd->button->down[key>>3] & bit) != 0) - return DONT_PROCESS; - } - } - *kptr &= ~bit; - if (device->valuator) - device->valuator->motionHintWindow = NullWindow; - if (!b->map[key]) - return DONT_PROCESS; - if (b->buttonsDown >= 1 && !--b->buttonsDown) - b->motionMask = 0; - if (b->map[key] <= 5) - b->state &= ~((Button1Mask >> 1) << b->map[key]); - - /* Add state and motionMask to the filter for this event */ - mask = DevicePointerMotionMask | b->state | b->motionMask; - SetMaskForEvent(device->id, mask, DeviceMotionNotify); - mask = PointerMotionMask | b->state | b->motionMask; - SetMaskForEvent(device->id, mask, MotionNotify); - } else if (event->type == ET_ProximityIn) - device->valuator->mode &= ~OutOfProximity; - else if (event->type == ET_ProximityOut) - device->valuator->mode |= OutOfProximity; - - return DEFAULT; -} - -static void -ProcessRawEvent(RawDeviceEvent *ev, DeviceIntPtr device) -{ - GrabPtr grab = device->deviceGrab.grab; - - if (grab) - DeliverGrabbedEvent((InternalEvent*)ev, device, FALSE); - else { /* deliver to all root windows */ - xEvent *xi; - int i; - - i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi); - if (i != Success) - { - ErrorF("[Xi] %s: XI2 conversion failed in ProcessRawEvent (%d)\n", - device->name, i); - return; - } - - for (i = 0; i < screenInfo.numScreens; i++) - DeliverEventsToWindow(device, WindowTable[i], xi, 1, - GetEventFilter(device, xi), NULL); - xfree(xi); - } -} - -/** - * Main device event processing function. - * Called from when processing the events from the event queue. - * - */ -void -ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device) -{ - GrabPtr grab; - Bool deactivateDeviceGrab = FALSE; - int key = 0, rootX, rootY; - ButtonClassPtr b; - KeyClassPtr k; - ValuatorClassPtr v; - int ret = 0; - int state, i; - DeviceIntPtr mouse = NULL, kbd = NULL; - DeviceEvent *event = &ev->device_event; - - CHECKEVENT(ev); - - if (ev->any.type == ET_RawKeyPress || - ev->any.type == ET_RawKeyRelease || - ev->any.type == ET_RawButtonPress || - ev->any.type == ET_RawButtonRelease || - ev->any.type == ET_RawMotion) - { - ProcessRawEvent(&ev->raw_event, device); - return; - } - - if (IsPointerDevice(device)) - { - kbd = GetPairedDevice(device); - mouse = device; - if (!kbd->key) /* can happen with floating SDs */ - kbd = NULL; - } else - { - mouse = GetPairedDevice(device); - kbd = device; - if (!mouse->valuator || !mouse->button) /* may be float. SDs */ - mouse = NULL; - } - - /* State needs to be assembled BEFORE the device is updated. */ - state = (kbd && kbd->key) ? XkbStateFieldFromRec(&kbd->key->xkbInfo->state) : 0; - state |= (mouse && mouse->button) ? (mouse->button->state) : 0; - - for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) - if (BitIsOn(mouse->button->down, i)) - SetBit(event->buttons, i); - - if (kbd && kbd->key) - { - XkbStatePtr state; - /* we need the state before the event happens */ - if (event->type == ET_KeyPress || event->type == ET_KeyRelease) - state = &kbd->key->xkbInfo->prev_state; - else - state = &kbd->key->xkbInfo->state; - - event->mods.base = state->base_mods; - event->mods.latched = state->latched_mods; - event->mods.locked = state->locked_mods; - event->mods.effective = state->mods; - - event->group.base = state->base_group; - event->group.latched = state->latched_group; - event->group.locked = state->locked_group; - event->group.effective = state->group; - } - - ret = UpdateDeviceState(device, event); - if (ret == DONT_PROCESS) - return; - - v = device->valuator; - b = device->button; - k = device->key; - - if (IsMaster(device) || !device->u.master) - CheckMotion(event, device); - - switch (event->type) - { - case ET_Motion: - case ET_ButtonPress: - case ET_ButtonRelease: - case ET_KeyPress: - case ET_KeyRelease: - case ET_ProximityIn: - case ET_ProximityOut: - GetSpritePosition(device, &rootX, &rootY); - event->root_x = rootX; - event->root_y = rootY; - NoticeEventTime((InternalEvent*)event); - event->corestate = state; - key = event->detail.key; - break; - default: - break; - } - - if (DeviceEventCallback && !syncEvents.playingEvents) { - DeviceEventInfoRec eventinfo; - SpritePtr pSprite = device->spriteInfo->sprite; - - /* see comment in EnqueueEvents regarding the next three lines */ - if (ev->any.type == ET_Motion) - ev->device_event.root = WindowTable[pSprite->hotPhys.pScreen->myNum]->drawable.id; - - eventinfo.device = device; - eventinfo.event = ev; - CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo); - } - - grab = device->deviceGrab.grab; - - switch(event->type) - { - case ET_KeyPress: - if (!grab && CheckDeviceGrabs(device, event, 0)) { - device->deviceGrab.activatingKey = key; - return; - } - break; - case ET_KeyRelease: - if (grab && device->deviceGrab.fromPassiveGrab && - (key == device->deviceGrab.activatingKey) && - (device->deviceGrab.grab->type == KeyPress || - device->deviceGrab.grab->type == DeviceKeyPress || - device->deviceGrab.grab->type == XI_KeyPress)) - deactivateDeviceGrab = TRUE; - break; - case ET_ButtonPress: - event->detail.button = b->map[key]; - if (!event->detail.button) { /* there's no button 0 */ - event->detail.button = key; - return; - } - if (!grab && CheckDeviceGrabs(device, event, 0)) - { - /* if a passive grab was activated, the event has been sent - * already */ - return; - } - break; - case ET_ButtonRelease: - event->detail.button = b->map[key]; - if (!event->detail.button) { /* there's no button 0 */ - event->detail.button = key; - return; - } - if (grab && !b->buttonsDown && - device->deviceGrab.fromPassiveGrab && - (device->deviceGrab.grab->type == ButtonPress || - device->deviceGrab.grab->type == DeviceButtonPress || - device->deviceGrab.grab->type == XI_ButtonPress)) - deactivateDeviceGrab = TRUE; - default: - break; - } - - - if (grab) - DeliverGrabbedEvent((InternalEvent*)event, device, deactivateDeviceGrab); - else if (device->focus && !IsPointerEvent((InternalEvent*)ev)) - DeliverFocusedEvent(device, (InternalEvent*)event, - GetSpriteWindow(device)); - else - DeliverDeviceEvents(GetSpriteWindow(device), (InternalEvent*)event, - NullGrab, NullWindow, device); - - if (deactivateDeviceGrab == TRUE) - (*device->deviceGrab.DeactivateGrab) (device); - event->detail.key = key; -} - -int -InitProximityClassDeviceStruct(DeviceIntPtr dev) -{ - ProximityClassPtr proxc; - - proxc = (ProximityClassPtr) xalloc(sizeof(ProximityClassRec)); - if (!proxc) - return FALSE; - proxc->sourceid = dev->id; - dev->proximity = proxc; - return TRUE; -} - -/** - * Initialise the device's valuators. The memory must already be allocated, - * this function merely inits the matching axis (specified through axnum) to - * sane values. - * - * It is a condition that (minval < maxval). - * - * @see InitValuatorClassDeviceStruct - */ -void -InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval, - int resolution, int min_res, int max_res) -{ - AxisInfoPtr ax; - - if (!dev || !dev->valuator || minval > maxval) - return; - if (axnum >= dev->valuator->numAxes) - return; - - ax = dev->valuator->axes + axnum; - - ax->min_value = minval; - ax->max_value = maxval; - ax->resolution = resolution; - ax->min_resolution = min_res; - ax->max_resolution = max_res; - ax->label = label; -} - -static void -FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k, - ButtonClassPtr b, ValuatorClassPtr v, int first) -{ - ev->type = DeviceStateNotify; - ev->deviceid = dev->id; - ev->time = currentTime.milliseconds; - ev->classes_reported = 0; - ev->num_keys = 0; - ev->num_buttons = 0; - ev->num_valuators = 0; - - if (b) { - ev->classes_reported |= (1 << ButtonClass); - ev->num_buttons = b->numButtons; - memcpy((char*)ev->buttons, (char*)b->down, 4); - } else if (k) { - ev->classes_reported |= (1 << KeyClass); - ev->num_keys = k->xkbInfo->desc->max_key_code - - k->xkbInfo->desc->min_key_code; - memmove((char *)&ev->keys[0], (char *)k->down, 4); - } - if (v) { - int nval = v->numAxes - first; - - ev->classes_reported |= (1 << ValuatorClass); - ev->classes_reported |= (dev->valuator->mode << ModeBitsShift); - ev->num_valuators = nval < 3 ? nval : 3; - switch (ev->num_valuators) { - case 3: - ev->valuator2 = v->axisVal[first + 2]; - case 2: - ev->valuator1 = v->axisVal[first + 1]; - case 1: - ev->valuator0 = v->axisVal[first]; - break; - } - } -} - -static void -FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, - int first) -{ - int nval = v->numAxes - first; - - ev->type = DeviceValuator; - ev->deviceid = dev->id; - ev->num_valuators = nval < 3 ? nval : 3; - ev->first_valuator = first; - switch (ev->num_valuators) { - case 3: - ev->valuator2 = v->axisVal[first + 2]; - case 2: - ev->valuator1 = v->axisVal[first + 1]; - case 1: - ev->valuator0 = v->axisVal[first]; - break; - } - first += ev->num_valuators; -} - -void -DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, - WindowPtr pWin) -{ - deviceFocus event; - xXIFocusInEvent *xi2event; - DeviceIntPtr mouse; - int btlen, len, i; - - mouse = (IsMaster(dev) || dev->u.master) ? GetMaster(dev, MASTER_POINTER) : dev; - - /* XI 2 event */ - btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0; - btlen = bytes_to_int32(btlen); - len = sizeof(xXIFocusInEvent) + btlen * 4; - - xi2event = xcalloc(1, len); - xi2event->type = GenericEvent; - xi2event->extension = IReqCode; - xi2event->evtype = type; - xi2event->length = bytes_to_int32(len - sizeof(xEvent)); - xi2event->buttons_len = btlen; - xi2event->detail = detail; - xi2event->time = currentTime.milliseconds; - xi2event->deviceid = dev->id; - xi2event->sourceid = dev->id; /* a device doesn't change focus by itself */ - xi2event->mode = mode; - xi2event->root_x = FP1616(mouse->spriteInfo->sprite->hot.x, 0); - xi2event->root_y = FP1616(mouse->spriteInfo->sprite->hot.y, 0); - - for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) - if (BitIsOn(mouse->button->down, i)) - SetBit(&xi2event[1], i); - - if (dev->key) - { - xi2event->mods.base_mods = dev->key->xkbInfo->state.base_mods; - xi2event->mods.latched_mods = dev->key->xkbInfo->state.latched_mods; - xi2event->mods.locked_mods = dev->key->xkbInfo->state.locked_mods; - xi2event->mods.effective_mods = dev->key->xkbInfo->state.mods; - - xi2event->group.base_group = dev->key->xkbInfo->state.base_group; - xi2event->group.latched_group = dev->key->xkbInfo->state.latched_group; - xi2event->group.locked_group = dev->key->xkbInfo->state.locked_group; - xi2event->group.effective_group = dev->key->xkbInfo->state.group; - } - - FixUpEventFromWindow(dev, (xEvent*)xi2event, pWin, None, FALSE); - - DeliverEventsToWindow(dev, pWin, (xEvent*)xi2event, 1, - GetEventFilter(dev, (xEvent*)xi2event), NullGrab); - - xfree(xi2event); - - /* XI 1.x event */ - event.deviceid = dev->id; - event.mode = mode; - event.type = (type == XI_FocusIn) ? DeviceFocusIn : DeviceFocusOut; - event.detail = detail; - event.window = pWin->drawable.id; - event.time = currentTime.milliseconds; - - DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1, - DeviceFocusChangeMask, NullGrab); - - if ((type == DeviceFocusIn) && - (wOtherInputMasks(pWin)) && - (wOtherInputMasks(pWin)->inputEvents[dev->id] & DeviceStateNotifyMask)) - { - int evcount = 1; - deviceStateNotify *ev, *sev; - deviceKeyStateNotify *kev; - deviceButtonStateNotify *bev; - - KeyClassPtr k; - ButtonClassPtr b; - ValuatorClassPtr v; - int nval = 0, nkeys = 0, nbuttons = 0, first = 0; - - if ((b = dev->button) != NULL) { - nbuttons = b->numButtons; - if (nbuttons > 32) - evcount++; - } - if ((k = dev->key) != NULL) { - nkeys = k->xkbInfo->desc->max_key_code - - k->xkbInfo->desc->min_key_code; - if (nkeys > 32) - evcount++; - if (nbuttons > 0) { - evcount++; - } - } - if ((v = dev->valuator) != NULL) { - nval = v->numAxes; - - if (nval > 3) - evcount++; - if (nval > 6) { - if (!(k && b)) - evcount++; - if (nval > 9) - evcount += ((nval - 7) / 3); - } - } - - sev = ev = (deviceStateNotify *) xalloc(evcount * sizeof(xEvent)); - FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); - - if (b != NULL) { - FixDeviceStateNotify(dev, ev++, NULL, b, v, first); - first += 3; - nval -= 3; - if (nbuttons > 32) { - (ev - 1)->deviceid |= MORE_EVENTS; - bev = (deviceButtonStateNotify *) ev++; - bev->type = DeviceButtonStateNotify; - bev->deviceid = dev->id; - memcpy((char*)&bev->buttons[4], (char*)&b->down[4], DOWN_LENGTH - 4); - } - if (nval > 0) { - (ev - 1)->deviceid |= MORE_EVENTS; - FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); - first += 3; - nval -= 3; - } - } - - if (k != NULL) { - FixDeviceStateNotify(dev, ev++, k, NULL, v, first); - first += 3; - nval -= 3; - if (nkeys > 32) { - (ev - 1)->deviceid |= MORE_EVENTS; - kev = (deviceKeyStateNotify *) ev++; - kev->type = DeviceKeyStateNotify; - kev->deviceid = dev->id; - memmove((char *)&kev->keys[0], (char *)&k->down[4], 28); - } - if (nval > 0) { - (ev - 1)->deviceid |= MORE_EVENTS; - FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); - first += 3; - nval -= 3; - } - } - - while (nval > 0) { - FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first); - first += 3; - nval -= 3; - if (nval > 0) { - (ev - 1)->deviceid |= MORE_EVENTS; - FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); - first += 3; - nval -= 3; - } - } - - DeliverEventsToWindow(dev, pWin, (xEvent *) sev, evcount, - DeviceStateNotifyMask, NullGrab); - xfree(sev); - } -} - -int -CheckGrabValues(ClientPtr client, GrabParameters* param) -{ - if (param->grabtype != GRABTYPE_CORE && - param->grabtype != GRABTYPE_XI && - param->grabtype != GRABTYPE_XI2) - { - ErrorF("[Xi] grabtype is invalid. This is a bug.\n"); - return BadImplementation; - } - - if ((param->this_device_mode != GrabModeSync) && - (param->this_device_mode != GrabModeAsync)) { - client->errorValue = param->this_device_mode; - return BadValue; - } - if ((param->other_devices_mode != GrabModeSync) && - (param->other_devices_mode != GrabModeAsync)) { - client->errorValue = param->other_devices_mode; - return BadValue; - } - - if (param->grabtype != GRABTYPE_XI2 && (param->modifiers != AnyModifier) && - (param->modifiers & ~AllModifiersMask)) { - client->errorValue = param->modifiers; - return BadValue; - } - - if ((param->ownerEvents != xFalse) && (param->ownerEvents != xTrue)) { - client->errorValue = param->ownerEvents; - return BadValue; - } - return Success; -} - -int -GrabButton(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device, - int button, GrabParameters *param, GrabType grabtype, - GrabMask *mask) -{ - WindowPtr pWin, confineTo; - CursorPtr cursor; - GrabPtr grab; - int rc, type = -1; - Mask access_mode = DixGrabAccess; - - rc = CheckGrabValues(client, param); - if (rc != Success) - return rc; - if (param->confineTo == None) - confineTo = NullWindow; - else { - rc = dixLookupWindow(&confineTo, param->confineTo, client, DixSetAttrAccess); - if (rc != Success) - return rc; - } - if (param->cursor == None) - cursor = NullCursor; - else { - rc = dixLookupResourceByType((pointer *)&cursor, param->cursor, - RT_CURSOR, client, DixUseAccess); - if (rc != Success) - { - client->errorValue = param->cursor; - return (rc == BadValue) ? BadCursor : rc; - } - access_mode |= DixForceAccess; - } - if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) - access_mode |= DixFreezeAccess; - rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); - if (rc != Success) - return rc; - rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); - if (rc != Success) - return rc; - - if (grabtype == GRABTYPE_XI) - type = DeviceButtonPress; - else if (grabtype == GRABTYPE_XI2) - type = XI_ButtonPress; - - grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype, - mask, param, type, button, confineTo, cursor); - if (!grab) - return BadAlloc; - return AddPassiveGrabToList(client, grab); -} - -/** - * Grab the given key. If grabtype is GRABTYPE_XI, the key is a keycode. If - * grabtype is GRABTYPE_XI2, the key is a keysym. - */ -int -GrabKey(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device, - int key, GrabParameters *param, GrabType grabtype, GrabMask *mask) -{ - WindowPtr pWin; - GrabPtr grab; - KeyClassPtr k = dev->key; - Mask access_mode = DixGrabAccess; - int rc, type = -1; - - rc = CheckGrabValues(client, param); - if (rc != Success) - return rc; - if (k == NULL) - return BadMatch; - if (grabtype == GRABTYPE_XI) - { - if ((key > k->xkbInfo->desc->max_key_code || - key < k->xkbInfo->desc->min_key_code) - && (key != AnyKey)) { - client->errorValue = key; - return BadValue; - } - type = DeviceKeyPress; - } else if (grabtype == GRABTYPE_XI2) - type = XI_KeyPress; - - rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); - if (rc != Success) - return rc; - if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) - access_mode |= DixFreezeAccess; - rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); - if (rc != Success) - return rc; - - grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype, - mask, param, type, key, NULL, NULL); - if (!grab) - return BadAlloc; - return AddPassiveGrabToList(client, grab); -} - -/* Enter/FocusIn grab */ -int -GrabWindow(ClientPtr client, DeviceIntPtr dev, int type, - GrabParameters *param, GrabMask *mask) -{ - WindowPtr pWin; - CursorPtr cursor; - GrabPtr grab; - Mask access_mode = DixGrabAccess; - int rc; - - rc = CheckGrabValues(client, param); - if (rc != Success) - return rc; - - rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); - if (rc != Success) - return rc; - if (param->cursor == None) - cursor = NullCursor; - else { - rc = dixLookupResourceByType((pointer *)&cursor, param->cursor, - RT_CURSOR, client, DixUseAccess); - if (rc != Success) - { - client->errorValue = param->cursor; - return (rc == BadValue) ? BadCursor : rc; - } - access_mode |= DixForceAccess; - } - if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) - access_mode |= DixFreezeAccess; - rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); - if (rc != Success) - return rc; - - grab = CreateGrab(client->index, dev, dev, pWin, GRABTYPE_XI2, - mask, param, (type == XIGrabtypeEnter) ? XI_Enter : XI_FocusIn, - 0, NULL, cursor); - - if (!grab) - return BadAlloc; - - return AddPassiveGrabToList(client, grab); -} - -int -SelectForWindow(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client, - Mask mask, Mask exclusivemasks) -{ - int mskidx = dev->id; - int i, ret; - Mask check; - InputClientsPtr others; - - check = (mask & exclusivemasks); - if (wOtherInputMasks(pWin)) { - if (check & wOtherInputMasks(pWin)->inputEvents[mskidx]) { /* It is illegal for two different - * clients to select on any of the - * events for maskcheck. However, - * it is OK, for some client to - * continue selecting on one of those - * events. */ - for (others = wOtherInputMasks(pWin)->inputClients; others; - others = others->next) { - if (!SameClient(others, client) && (check & - others->mask[mskidx])) - return BadAccess; - } - } - for (others = wOtherInputMasks(pWin)->inputClients; others; - others = others->next) { - if (SameClient(others, client)) { - check = others->mask[mskidx]; - others->mask[mskidx] = mask; - if (mask == 0) { - for (i = 0; i < EMASKSIZE; i++) - if (i != mskidx && others->mask[i] != 0) - break; - if (i == EMASKSIZE) { - RecalculateDeviceDeliverableEvents(pWin); - if (ShouldFreeInputMasks(pWin, FALSE)) - FreeResource(others->resource, RT_NONE); - return Success; - } - } - goto maskSet; - } - } - } - check = 0; - if ((ret = AddExtensionClient(pWin, client, mask, mskidx)) != Success) - return ret; - maskSet: - if (dev->valuator) - if ((dev->valuator->motionHintWindow == pWin) && - (mask & DevicePointerMotionHintMask) && - !(check & DevicePointerMotionHintMask) && !dev->deviceGrab.grab) - dev->valuator->motionHintWindow = NullWindow; - RecalculateDeviceDeliverableEvents(pWin); - return Success; -} - -int -AddExtensionClient(WindowPtr pWin, ClientPtr client, Mask mask, int mskidx) -{ - InputClientsPtr others; - - if (!pWin->optional && !MakeWindowOptional(pWin)) - return BadAlloc; - others = xcalloc(1, sizeof(InputClients)); - if (!others) - return BadAlloc; - if (!pWin->optional->inputMasks && !MakeInputMasks(pWin)) - return BadAlloc; - others->mask[mskidx] = mask; - others->resource = FakeClientID(client->index); - others->next = pWin->optional->inputMasks->inputClients; - pWin->optional->inputMasks->inputClients = others; - if (!AddResource(others->resource, RT_INPUTCLIENT, (pointer) pWin)) - return BadAlloc; - return Success; -} - -static Bool -MakeInputMasks(WindowPtr pWin) -{ - struct _OtherInputMasks *imasks; - - imasks = xcalloc(1, sizeof(struct _OtherInputMasks)); - if (!imasks) - return FALSE; - pWin->optional->inputMasks = imasks; - return TRUE; -} - -void -RecalculateDeviceDeliverableEvents(WindowPtr pWin) -{ - InputClientsPtr others; - struct _OtherInputMasks *inputMasks; /* default: NULL */ - WindowPtr pChild, tmp; - int i, j; - - pChild = pWin; - while (1) { - if ((inputMasks = wOtherInputMasks(pChild)) != 0) { - for (i = 0; i < EMASKSIZE; i++) - memset(inputMasks->xi2mask[i], 0, sizeof(inputMasks->xi2mask[i])); - for (others = inputMasks->inputClients; others; - others = others->next) { - for (i = 0; i < EMASKSIZE; i++) - inputMasks->inputEvents[i] |= others->mask[i]; - for (i = 0; i < EMASKSIZE; i++) - for (j = 0; j < XI2MASKSIZE; j++) - inputMasks->xi2mask[i][j] |= others->xi2mask[i][j]; - } - for (i = 0; i < EMASKSIZE; i++) - inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i]; - for (tmp = pChild->parent; tmp; tmp = tmp->parent) - if (wOtherInputMasks(tmp)) - for (i = 0; i < EMASKSIZE; i++) - inputMasks->deliverableEvents[i] |= - (wOtherInputMasks(tmp)->deliverableEvents[i] - & ~inputMasks-> - dontPropagateMask[i] & PropagateMask[i]); - } - if (pChild->firstChild) { - pChild = pChild->firstChild; - continue; - } - while (!pChild->nextSib && (pChild != pWin)) - pChild = pChild->parent; - if (pChild == pWin) - break; - pChild = pChild->nextSib; - } -} - -int -InputClientGone(WindowPtr pWin, XID id) -{ - InputClientsPtr other, prev; - - if (!wOtherInputMasks(pWin)) - return (Success); - prev = 0; - for (other = wOtherInputMasks(pWin)->inputClients; other; - other = other->next) { - if (other->resource == id) { - if (prev) { - prev->next = other->next; - xfree(other); - } else if (!(other->next)) { - if (ShouldFreeInputMasks(pWin, TRUE)) { - wOtherInputMasks(pWin)->inputClients = other->next; - xfree(wOtherInputMasks(pWin)); - pWin->optional->inputMasks = (OtherInputMasks *) NULL; - CheckWindowOptionalNeed(pWin); - xfree(other); - } else { - other->resource = FakeClientID(0); - if (!AddResource(other->resource, RT_INPUTCLIENT, - (pointer) pWin)) - return BadAlloc; - } - } else { - wOtherInputMasks(pWin)->inputClients = other->next; - xfree(other); - } - RecalculateDeviceDeliverableEvents(pWin); - return (Success); - } - prev = other; - } - FatalError("client not on device event list"); -} - -int -SendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate, - xEvent * ev, Mask mask, int count) -{ - WindowPtr pWin; - WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */ - WindowPtr spriteWin = GetSpriteWindow(d); - - if (dest == PointerWindow) - pWin = spriteWin; - else if (dest == InputFocus) { - WindowPtr inputFocus; - - if (!d->focus) - inputFocus = spriteWin; - else - inputFocus = d->focus->win; - - if (inputFocus == FollowKeyboardWin) - 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 = GetCurrentRootWindow(d); - - if (IsParent(inputFocus, spriteWin)) { - effectiveFocus = inputFocus; - pWin = spriteWin; - } else - effectiveFocus = pWin = inputFocus; - } else - dixLookupWindow(&pWin, dest, client, DixSendAccess); - if (!pWin) - return BadWindow; - if ((propagate != xFalse) && (propagate != xTrue)) { - client->errorValue = propagate; - return BadValue; - } - ev->u.u.type |= 0x80; - if (propagate) { - for (; pWin; pWin = pWin->parent) { - if (DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab)) - return Success; - if (pWin == effectiveFocus) - return Success; - if (wOtherInputMasks(pWin)) - mask &= ~wOtherInputMasks(pWin)->dontPropagateMask[d->id]; - if (!mask) - break; - } - } else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, ev, count)) - DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab); - return Success; -} - -int -SetButtonMapping(ClientPtr client, DeviceIntPtr dev, int nElts, BYTE * map) -{ - int i; - ButtonClassPtr b = dev->button; - - if (b == NULL) - return BadMatch; - - if (nElts != b->numButtons) { - client->errorValue = nElts; - return BadValue; - } - if (BadDeviceMap(&map[0], nElts, 1, 255, &client->errorValue)) - return BadValue; - for (i = 0; i < nElts; i++) - if ((b->map[i + 1] != map[i]) && BitIsOn(b->down, i + 1)) - return MappingBusy; - for (i = 0; i < nElts; i++) - b->map[i + 1] = map[i]; - return Success; -} - -int -ChangeKeyMapping(ClientPtr client, - DeviceIntPtr dev, - unsigned len, - int type, - KeyCode firstKeyCode, - CARD8 keyCodes, CARD8 keySymsPerKeyCode, KeySym * map) -{ - KeySymsRec keysyms; - KeyClassPtr k = dev->key; - - if (k == NULL) - return (BadMatch); - - if (len != (keyCodes * keySymsPerKeyCode)) - return BadLength; - - if ((firstKeyCode < k->xkbInfo->desc->min_key_code) || - (firstKeyCode + keyCodes - 1 > k->xkbInfo->desc->max_key_code)) { - client->errorValue = firstKeyCode; - return BadValue; - } - if (keySymsPerKeyCode == 0) { - client->errorValue = 0; - return BadValue; - } - keysyms.minKeyCode = firstKeyCode; - keysyms.maxKeyCode = firstKeyCode + keyCodes - 1; - keysyms.mapWidth = keySymsPerKeyCode; - keysyms.map = map; - - XkbApplyMappingChange(dev, &keysyms, firstKeyCode, keyCodes, NULL, - serverClient); - - return client->noClientException; -} - -static void -DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev) -{ - WindowPtr parent; - - /* Deactivate any grabs performed on this window, before making - * any input focus changes. - * Deactivating a device grab should cause focus events. */ - - if (dev->deviceGrab.grab && (dev->deviceGrab.grab->window == pWin)) - (*dev->deviceGrab.DeactivateGrab) (dev); - - /* If the focus window is a root window (ie. has no parent) - * then don't delete the focus from it. */ - - if (dev->focus && (pWin == dev->focus->win) && (pWin->parent != NullWindow)) { - int focusEventMode = NotifyNormal; - - /* If a grab is in progress, then alter the mode of focus events. */ - - if (dev->deviceGrab.grab) - focusEventMode = NotifyWhileGrabbed; - - switch (dev->focus->revert) { - case RevertToNone: - if (!ActivateFocusInGrab(dev, pWin, NoneWin)) - DoFocusEvents(dev, pWin, NoneWin, focusEventMode); - dev->focus->win = NoneWin; - dev->focus->traceGood = 0; - break; - case RevertToParent: - parent = pWin; - do { - parent = parent->parent; - dev->focus->traceGood--; - } - while (!parent->realized); - if (!ActivateFocusInGrab(dev, pWin, parent)) - DoFocusEvents(dev, pWin, parent, focusEventMode); - dev->focus->win = parent; - dev->focus->revert = RevertToNone; - break; - case RevertToPointerRoot: - if (!ActivateFocusInGrab(dev, pWin, PointerRootWin)) - DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode); - dev->focus->win = PointerRootWin; - dev->focus->traceGood = 0; - break; - case RevertToFollowKeyboard: - { - DeviceIntPtr kbd = GetMaster(dev, MASTER_KEYBOARD); - if (!kbd || (kbd == dev && kbd != inputInfo.keyboard)) - kbd = inputInfo.keyboard; - if (kbd->focus->win) { - if (!ActivateFocusInGrab(dev, pWin, kbd->focus->win)) - DoFocusEvents(dev, pWin, kbd->focus->win, focusEventMode); - dev->focus->win = FollowKeyboardWin; - dev->focus->traceGood = 0; - } else { - if (!ActivateFocusInGrab(dev, pWin, NoneWin)) - DoFocusEvents(dev, pWin, NoneWin, focusEventMode); - dev->focus->win = NoneWin; - dev->focus->traceGood = 0; - } - } - break; - } - } - - if (dev->valuator) - if (dev->valuator->motionHintWindow == pWin) - dev->valuator->motionHintWindow = NullWindow; -} - -void -DeleteWindowFromAnyExtEvents(WindowPtr pWin, Bool freeResources) -{ - int i; - DeviceIntPtr dev; - InputClientsPtr ic; - struct _OtherInputMasks *inputMasks; - - for (dev = inputInfo.devices; dev; dev = dev->next) { - DeleteDeviceFromAnyExtEvents(pWin, dev); - } - - for (dev = inputInfo.off_devices; dev; dev = dev->next) - DeleteDeviceFromAnyExtEvents(pWin, dev); - - if (freeResources) - while ((inputMasks = wOtherInputMasks(pWin)) != 0) { - ic = inputMasks->inputClients; - for (i = 0; i < EMASKSIZE; i++) - inputMasks->dontPropagateMask[i] = 0; - FreeResource(ic->resource, RT_NONE); - } -} - -int -MaybeSendDeviceMotionNotifyHint(deviceKeyButtonPointer * pEvents, Mask mask) -{ - DeviceIntPtr dev; - - dixLookupDevice(&dev, pEvents->deviceid & DEVICE_BITS, serverClient, - DixReadAccess); - if (!dev) - return 0; - - if (pEvents->type == DeviceMotionNotify) { - if (mask & DevicePointerMotionHintMask) { - if (WID(dev->valuator->motionHintWindow) == pEvents->event) { - return 1; /* don't send, but pretend we did */ - } - pEvents->detail = NotifyHint; - } else { - pEvents->detail = NotifyNormal; - } - } - return (0); -} - -void -CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type, - deviceKeyButtonPointer * xE, GrabPtr grab, - ClientPtr client, Mask deliveryMask) -{ - DeviceIntPtr dev; - - dixLookupDevice(&dev, xE->deviceid & DEVICE_BITS, serverClient, - DixGrabAccess); - if (!dev) - return; - - if (type == DeviceMotionNotify) - dev->valuator->motionHintWindow = pWin; - else if ((type == DeviceButtonPress) && (!grab) && - (deliveryMask & DeviceButtonGrabMask)) { - GrabRec tempGrab; - - tempGrab.device = dev; - tempGrab.resource = client->clientAsMask; - tempGrab.window = pWin; - tempGrab.ownerEvents = - (deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE; - tempGrab.eventMask = deliveryMask; - tempGrab.keyboardMode = GrabModeAsync; - tempGrab.pointerMode = GrabModeAsync; - tempGrab.confineTo = NullWindow; - tempGrab.cursor = NullCursor; - tempGrab.next = NULL; - (*dev->deviceGrab.ActivateGrab) (dev, &tempGrab, currentTime, TRUE); - } -} - -static Mask -DeviceEventMaskForClient(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client) -{ - InputClientsPtr other; - - if (!wOtherInputMasks(pWin)) - return 0; - for (other = wOtherInputMasks(pWin)->inputClients; other; - other = other->next) { - if (SameClient(other, client)) - return other->mask[dev->id]; - } - return 0; -} - -void -MaybeStopDeviceHint(DeviceIntPtr dev, ClientPtr client) -{ - WindowPtr pWin; - GrabPtr grab = dev->deviceGrab.grab; - - pWin = dev->valuator->motionHintWindow; - - if ((grab && SameClient(grab, client) && - ((grab->eventMask & DevicePointerMotionHintMask) || - (grab->ownerEvents && - (DeviceEventMaskForClient(dev, pWin, client) & - DevicePointerMotionHintMask)))) || - (!grab && - (DeviceEventMaskForClient(dev, pWin, client) & - DevicePointerMotionHintMask))) - dev->valuator->motionHintWindow = NullWindow; -} - -int -DeviceEventSuppressForWindow(WindowPtr pWin, ClientPtr client, Mask mask, - int maskndx) -{ - struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); - - if (mask & ~PropagateMask[maskndx]) { - client->errorValue = mask; - return BadValue; - } - - if (mask == 0) { - if (inputMasks) - inputMasks->dontPropagateMask[maskndx] = mask; - } else { - if (!inputMasks) - AddExtensionClient(pWin, client, 0, 0); - inputMasks = wOtherInputMasks(pWin); - inputMasks->dontPropagateMask[maskndx] = mask; - } - RecalculateDeviceDeliverableEvents(pWin); - if (ShouldFreeInputMasks(pWin, FALSE)) - FreeResource(inputMasks->inputClients->resource, RT_NONE); - return Success; -} - -Bool -ShouldFreeInputMasks(WindowPtr pWin, Bool ignoreSelectedEvents) -{ - int i; - Mask allInputEventMasks = 0; - struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); - - for (i = 0; i < EMASKSIZE; i++) - allInputEventMasks |= inputMasks->dontPropagateMask[i]; - if (!ignoreSelectedEvents) - for (i = 0; i < EMASKSIZE; i++) - allInputEventMasks |= inputMasks->inputEvents[i]; - if (allInputEventMasks == 0) - return TRUE; - else - return FALSE; -} - -/*********************************************************************** - * - * Walk through the window tree, finding all clients that want to know - * about the Event. - * - */ - -static void -FindInterestedChildren(DeviceIntPtr dev, WindowPtr p1, Mask mask, - xEvent * ev, int count) -{ - WindowPtr p2; - - while (p1) { - p2 = p1->firstChild; - DeliverEventsToWindow(dev, p1, ev, count, mask, NullGrab); - FindInterestedChildren(dev, p2, mask, ev, count); - p1 = p1->nextSib; - } -} - -/*********************************************************************** - * - * Send an event to interested clients in all windows on all screens. - * - */ - -void -SendEventToAllWindows(DeviceIntPtr dev, Mask mask, xEvent * ev, int count) -{ - int i; - WindowPtr pWin, p1; - - for (i = 0; i < screenInfo.numScreens; i++) { - pWin = WindowTable[i]; - if (!pWin) - continue; - DeliverEventsToWindow(dev, pWin, ev, count, mask, NullGrab); - p1 = pWin->firstChild; - FindInterestedChildren(dev, p1, mask, ev, count); - } -} - -/** - * Set the XI2 mask for the given client on the given window. - * @param dev The device to set the mask for. - * @param win The window to set the mask on. - * @param client The client setting the mask. - * @param len Number of bytes in mask. - * @param mask Event mask in the form of (1 << eventtype) - */ -int -XISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client, - unsigned int len, unsigned char* mask) -{ - OtherInputMasks *masks; - InputClientsPtr others = NULL; - - masks = wOtherInputMasks(win); - if (masks) - { - for (others = wOtherInputMasks(win)->inputClients; others; - others = others->next) { - if (SameClient(others, client)) { - memset(others->xi2mask[dev->id], 0, - sizeof(others->xi2mask[dev->id])); - break; - } - } - } - - len = min(len, sizeof(others->xi2mask[dev->id])); - - if (len && !others) - { - if (AddExtensionClient(win, client, 0, 0) != Success) - return BadAlloc; - others= wOtherInputMasks(win)->inputClients; - } - - if (others) - memset(others->xi2mask[dev->id], 0, sizeof(others->xi2mask[dev->id])); - - if (len) - memcpy(others->xi2mask[dev->id], mask, len); - - RecalculateDeviceDeliverableEvents(win); - - return Success; -} +/************************************************************ + +Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. + + 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 Hewlett-Packard not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +HEWLETT-PACKARD 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. + +********************************************************/ + +/******************************************************************** + * + * Routines to register and initialize extension input devices. + * This also contains ProcessOtherEvent, the routine called from DDX + * to route extension events. + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "inputstr.h" +#include +#include +#include +#include +#include +#include +#include "windowstr.h" +#include "miscstruct.h" +#include "region.h" +#include "exevents.h" +#include "extnsionst.h" +#include "exglobals.h" +#include "dixevents.h" /* DeliverFocusedEvent */ +#include "dixgrabs.h" /* CreateGrab() */ +#include "scrnintstr.h" +#include "listdev.h" /* for CopySwapXXXClass */ +#include "xace.h" +#include "xiquerydevice.h" /* For List*Info */ +#include "eventconvert.h" +#include "eventstr.h" + +#include +#include "xkbsrv.h" + +#define WID(w) ((w) ? ((w)->drawable.id) : 0) +#define AllModifiersMask ( \ + ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \ + Mod3Mask | Mod4Mask | Mod5Mask ) +#define AllButtonsMask ( \ + Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask ) + +Bool ShouldFreeInputMasks(WindowPtr /* pWin */ , + Bool /* ignoreSelectedEvents */ + ); +static Bool MakeInputMasks(WindowPtr /* pWin */ + ); + +/* + * Only let the given client know of core events which will affect its + * interpretation of input events, if the client's ClientPointer (or the + * paired keyboard) is the current device. + */ +int +XIShouldNotify(ClientPtr client, DeviceIntPtr dev) +{ + DeviceIntPtr current_ptr = PickPointer(client); + DeviceIntPtr current_kbd = GetPairedDevice(current_ptr); + + if (dev == current_kbd || dev == current_ptr) + return 1; + + return 0; +} + +void +RegisterOtherDevice(DeviceIntPtr device) +{ + device->public.processInputProc = ProcessOtherEvent; + device->public.realInputProc = ProcessOtherEvent; +} + +Bool +IsPointerEvent(InternalEvent* event) +{ + switch(event->any.type) + { + case ET_ButtonPress: + case ET_ButtonRelease: + case ET_Motion: + /* XXX: enter/leave ?? */ + return TRUE; + default: + break; + } + return FALSE; +} + +/** + * @return the device matching the deviceid of the device set in the event, or + * NULL if the event is not an XInput event. + */ +DeviceIntPtr +XIGetDevice(xEvent* xE) +{ + DeviceIntPtr pDev = NULL; + + if (xE->u.u.type == DeviceButtonPress || + xE->u.u.type == DeviceButtonRelease || + xE->u.u.type == DeviceMotionNotify || + xE->u.u.type == ProximityIn || + xE->u.u.type == ProximityOut || + xE->u.u.type == DevicePropertyNotify) + { + int rc; + int id; + + id = ((deviceKeyButtonPointer*)xE)->deviceid & ~MORE_EVENTS; + + rc = dixLookupDevice(&pDev, id, serverClient, DixUnknownAccess); + if (rc != Success) + ErrorF("[dix] XIGetDevice failed on XACE restrictions (%d)\n", rc); + } + return pDev; +} + + +/** + * Copy the device->key into master->key and send a mapping notify to the + * clients if appropriate. + * master->key needs to be allocated by the caller. + * + * Device is the slave device. If it is attached to a master device, we may + * need to send a mapping notify to the client because it causes the MD + * to change state. + * + * Mapping notify needs to be sent in the following cases: + * - different slave device on same master + * - different master + * + * XXX: They way how the code is we also send a map notify if the slave device + * stays the same, but the master changes. This isn't really necessary though. + * + * XXX: this gives you funny behaviour with the ClientPointer. When a + * MappingNotify is sent to the client, the client usually responds with a + * GetKeyboardMapping. This will retrieve the ClientPointer's keyboard + * mapping, regardless of which keyboard sent the last mapping notify request. + * So depending on the CP setting, your keyboard may change layout in each + * app... + * + * This code is basically the old SwitchCoreKeyboard. + */ + +void +CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master) +{ + KeyClassPtr mk = master->key; + KeyClassPtr dk = device->key; + int i; + + if (device == master) + return; + + mk->sourceid = device->id; + + for (i = 0; i < 8; i++) + mk->modifierKeyCount[i] = dk->modifierKeyCount[i]; + + if (!XkbCopyDeviceKeymap(master, device)) + FatalError("Couldn't pivot keymap from device to core!\n"); +} + +/** + * Copies the feedback classes from device "from" into device "to". Classes + * are duplicated (not just flipping the pointers). All feedback classes are + * linked lists, the full list is duplicated. + */ +static void +DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) +{ + ClassesPtr classes; + + + if (from->intfeed) + { + IntegerFeedbackPtr *i, it; + + if (!to->intfeed) + { + classes = to->unused_classes; + to->intfeed = classes->intfeed; + } + + i = &to->intfeed; + for (it = from->intfeed; it; it = it->next) + { + if (!(*i)) + { + *i = calloc(1, sizeof(IntegerFeedbackClassRec)); + if (!(*i)) + { + ErrorF("[Xi] Cannot alloc memory for class copy."); + return; + } + } + (*i)->CtrlProc = it->CtrlProc; + (*i)->ctrl = it->ctrl; + + i = &(*i)->next; + } + } else if (to->intfeed && !from->intfeed) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->intfeed = to->intfeed; + to->intfeed = NULL; + } + + if (from->stringfeed) + { + StringFeedbackPtr *s, it; + + if (!to->stringfeed) + { + classes = to->unused_classes; + to->stringfeed = classes->stringfeed; + } + + s = &to->stringfeed; + for (it = from->stringfeed; it; it = it->next) + { + if (!(*s)) + { + *s = calloc(1, sizeof(StringFeedbackClassRec)); + if (!(*s)) + { + ErrorF("[Xi] Cannot alloc memory for class copy."); + return; + } + } + (*s)->CtrlProc = it->CtrlProc; + (*s)->ctrl = it->ctrl; + + s = &(*s)->next; + } + } else if (to->stringfeed && !from->stringfeed) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->stringfeed = to->stringfeed; + to->stringfeed = NULL; + } + + if (from->bell) + { + BellFeedbackPtr *b, it; + + if (!to->bell) + { + classes = to->unused_classes; + to->bell = classes->bell; + } + + b = &to->bell; + for (it = from->bell; it; it = it->next) + { + if (!(*b)) + { + *b = calloc(1, sizeof(BellFeedbackClassRec)); + if (!(*b)) + { + ErrorF("[Xi] Cannot alloc memory for class copy."); + return; + } + } + (*b)->BellProc = it->BellProc; + (*b)->CtrlProc = it->CtrlProc; + (*b)->ctrl = it->ctrl; + + b = &(*b)->next; + } + } else if (to->bell && !from->bell) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->bell = to->bell; + to->bell = NULL; + } + + if (from->leds) + { + LedFeedbackPtr *l, it; + + if (!to->leds) + { + classes = to->unused_classes; + to->leds = classes->leds; + } + + l = &to->leds; + for (it = from->leds; it; it = it->next) + { + if (!(*l)) + { + *l = calloc(1, sizeof(LedFeedbackClassRec)); + if (!(*l)) + { + ErrorF("[Xi] Cannot alloc memory for class copy."); + return; + } + } + (*l)->CtrlProc = it->CtrlProc; + (*l)->ctrl = it->ctrl; + if ((*l)->xkb_sli) + XkbFreeSrvLedInfo((*l)->xkb_sli); + (*l)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, NULL, *l); + + l = &(*l)->next; + } + } else if (to->leds && !from->leds) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->leds = to->leds; + to->leds = NULL; + } +} + +static void +DeepCopyKeyboardClasses(DeviceIntPtr from, DeviceIntPtr to) +{ + ClassesPtr classes; + + /* XkbInitDevice (->XkbInitIndicatorMap->XkbFindSrvLedInfo) relies on the + * kbdfeed to be set up properly, so let's do the feedback classes first. + */ + if (from->kbdfeed) + { + KbdFeedbackPtr *k, it; + + if (!to->kbdfeed) + { + classes = to->unused_classes; + + to->kbdfeed = classes->kbdfeed; + if (!to->kbdfeed) + InitKeyboardDeviceStruct(to, NULL, NULL, NULL); + } + + k = &to->kbdfeed; + for(it = from->kbdfeed; it; it = it->next) + { + if (!(*k)) + { + *k = calloc(1, sizeof(KbdFeedbackClassRec)); + if (!*k) + { + ErrorF("[Xi] Cannot alloc memory for class copy."); + return; + } + } + (*k)->BellProc = it->BellProc; + (*k)->CtrlProc = it->CtrlProc; + (*k)->ctrl = it->ctrl; + if ((*k)->xkb_sli) + XkbFreeSrvLedInfo((*k)->xkb_sli); + (*k)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, *k, NULL); + + k = &(*k)->next; + } + } else if (to->kbdfeed && !from->kbdfeed) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->kbdfeed = to->kbdfeed; + to->kbdfeed = NULL; + } + + if (from->key) + { + if (!to->key) + { + classes = to->unused_classes; + to->key = classes->key; + if (!to->key) + InitKeyboardDeviceStruct(to, NULL, NULL, NULL); + else + classes->key = NULL; + } + + CopyKeyClass(from, to); + } else if (to->key && !from->key) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->key = to->key; + to->key = NULL; + } + + /* If a SrvLedInfoPtr's flags are XkbSLI_IsDefault, the names and maps + * pointer point into the xkbInfo->desc struct. XkbCopySrvLedInfo + * didn't update the pointers so we need to do it manually here. + */ + if (to->kbdfeed) + { + KbdFeedbackPtr k; + + for (k = to->kbdfeed; k; k = k->next) + { + if (!k->xkb_sli) + continue; + if (k->xkb_sli->flags & XkbSLI_IsDefault) + { + k->xkb_sli->names = to->key->xkbInfo->desc->names->indicators; + k->xkb_sli->maps = to->key->xkbInfo->desc->indicators->maps; + } + } + } + + /* We can't just copy over the focus class. When an app sets the focus, + * it'll do so on the master device. Copying the SDs focus means losing + * the focus. + * So we only copy the focus class if the device didn't have one, + * otherwise we leave it as it is. + */ + if (from->focus) + { + if (!to->focus) + { + WindowPtr *oldTrace; + + classes = to->unused_classes; + to->focus = classes->focus; + if (!to->focus) + { + to->focus = calloc(1, sizeof(FocusClassRec)); + if (!to->focus) + FatalError("[Xi] no memory for class shift.\n"); + } else + classes->focus = NULL; + + oldTrace = to->focus->trace; + memcpy(to->focus, from->focus, sizeof(FocusClassRec)); + to->focus->trace = realloc(oldTrace, + to->focus->traceSize * sizeof(WindowPtr)); + if (!to->focus->trace && to->focus->traceSize) + FatalError("[Xi] no memory for trace.\n"); + memcpy(to->focus->trace, from->focus->trace, + from->focus->traceSize * sizeof(WindowPtr)); + to->focus->sourceid = from->id; + } + } else if (to->focus) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->focus = to->focus; + to->focus = NULL; + } + +} + +static void +DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to) +{ + ClassesPtr classes; + + /* Feedback classes must be copied first */ + if (from->ptrfeed) + { + PtrFeedbackPtr *p, it; + if (!to->ptrfeed) + { + classes = to->unused_classes; + to->ptrfeed = classes->ptrfeed; + } + + p = &to->ptrfeed; + for (it = from->ptrfeed; it; it = it->next) + { + if (!(*p)) + { + *p = calloc(1, sizeof(PtrFeedbackClassRec)); + if (!*p) + { + ErrorF("[Xi] Cannot alloc memory for class copy."); + return; + } + } + (*p)->CtrlProc = it->CtrlProc; + (*p)->ctrl = it->ctrl; + + p = &(*p)->next; + } + } else if (to->ptrfeed && !from->ptrfeed) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->ptrfeed = to->ptrfeed; + to->ptrfeed = NULL; + } + + if (from->valuator) + { + ValuatorClassPtr v; + if (!to->valuator) + { + classes = to->unused_classes; + to->valuator = classes->valuator; + if (to->valuator) + classes->valuator = NULL; + } + + to->valuator = realloc(to->valuator, sizeof(ValuatorClassRec) + + from->valuator->numAxes * sizeof(AxisInfo) + + from->valuator->numAxes * sizeof(double)); + v = to->valuator; + if (!v) + FatalError("[Xi] no memory for class shift.\n"); + + v->numAxes = from->valuator->numAxes; + v->axes = (AxisInfoPtr)&v[1]; + memcpy(v->axes, from->valuator->axes, v->numAxes * sizeof(AxisInfo)); + + v->axisVal = (double*)(v->axes + from->valuator->numAxes); + v->sourceid = from->id; + v->mode = from->valuator->mode; + } else if (to->valuator && !from->valuator) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->valuator = to->valuator; + to->valuator = NULL; + } + + if (from->button) + { + if (!to->button) + { + classes = to->unused_classes; + to->button = classes->button; + if (!to->button) + { + to->button = calloc(1, sizeof(ButtonClassRec)); + if (!to->button) + FatalError("[Xi] no memory for class shift.\n"); + } else + classes->button = NULL; + } + + if (from->button->xkb_acts) + { + if (!to->button->xkb_acts) + { + to->button->xkb_acts = calloc(1, sizeof(XkbAction)); + if (!to->button->xkb_acts) + FatalError("[Xi] not enough memory for xkb_acts.\n"); + } + memcpy(to->button->xkb_acts, from->button->xkb_acts, + sizeof(XkbAction)); + } else + free(to->button->xkb_acts); + + memcpy(to->button->labels, from->button->labels, + from->button->numButtons * sizeof(Atom)); + to->button->sourceid = from->id; + } else if (to->button && !from->button) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->button = to->button; + to->button = NULL; + } + + if (from->proximity) + { + if (!to->proximity) + { + classes = to->unused_classes; + to->proximity = classes->proximity; + if (!to->proximity) + { + to->proximity = calloc(1, sizeof(ProximityClassRec)); + if (!to->proximity) + FatalError("[Xi] no memory for class shift.\n"); + } else + classes->proximity = NULL; + } + memcpy(to->proximity, from->proximity, sizeof(ProximityClassRec)); + to->proximity->sourceid = from->id; + } else if (to->proximity) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->proximity = to->proximity; + to->proximity = NULL; + } + + if (from->absolute) + { + if (!to->absolute) + { + classes = to->unused_classes; + to->absolute = classes->absolute; + if (!to->absolute) + { + to->absolute = calloc(1, sizeof(AbsoluteClassRec)); + if (!to->absolute) + FatalError("[Xi] no memory for class shift.\n"); + } else + classes->absolute = NULL; + } + memcpy(to->absolute, from->absolute, sizeof(AbsoluteClassRec)); + to->absolute->sourceid = from->id; + } else if (to->absolute) + { + ClassesPtr classes; + classes = to->unused_classes; + classes->absolute = to->absolute; + to->absolute = NULL; + } +} + +/** + * Copies the CONTENT of the classes of device from into the classes in device + * to. From and to are identical after finishing. + * + * If to does not have classes from currenly has, the classes are stored in + * to's devPrivates system. Later, we recover it again from there if needed. + * Saves a few memory allocations. + */ +void +DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to, DeviceChangedEvent *dce) +{ + /* generic feedback classes, not tied to pointer and/or keyboard */ + DeepCopyFeedbackClasses(from, to); + + if ((dce->flags & DEVCHANGE_KEYBOARD_EVENT)) + DeepCopyKeyboardClasses(from, to); + if ((dce->flags & DEVCHANGE_POINTER_EVENT)) + DeepCopyPointerClasses(from, to); +} + + +/** + * Send an XI2 DeviceChangedEvent to all interested clients. + */ +void +XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChangedEvent *dce) +{ + xXIDeviceChangedEvent *dcce; + int rc; + + rc = EventToXI2((InternalEvent*)dce, (xEvent**)&dcce); + if (rc != Success) + { + ErrorF("[Xi] event conversion from DCE failed with code %d\n", rc); + return; + } + + /* we don't actually swap if there's a NullClient, swapping is done + * later when event is delivered. */ + SendEventToAllWindows(master, XI_DeviceChangedMask, (xEvent*)dcce, 1); + free(dcce); +} + +static void +ChangeMasterDeviceClasses(DeviceIntPtr device, DeviceChangedEvent *dce) +{ + DeviceIntPtr slave; + int rc; + + /* For now, we don't have devices that change physically. */ + if (!IsMaster(device)) + return; + + rc = dixLookupDevice(&slave, dce->sourceid, serverClient, DixReadAccess); + + if (rc != Success) + return; /* Device has disappeared */ + + if (!slave->u.master) + return; /* set floating since the event */ + + if (slave->u.master->id != dce->masterid) + return; /* not our slave anymore, don't care */ + + /* FIXME: we probably need to send a DCE for the new slave now */ + + device->public.devicePrivate = slave->public.devicePrivate; + + /* FIXME: the classes may have changed since we generated the event. */ + DeepCopyDeviceClasses(slave, device, dce); + XISendDeviceChangedEvent(slave, device, dce); +} + +/** + * Update the device state according to the data in the event. + * + * return values are + * DEFAULT ... process as normal + * DONT_PROCESS ... return immediately from caller + */ +#define DEFAULT 0 +#define DONT_PROCESS 1 +int +UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event) +{ + int i; + int key = 0, + bit = 0, + last_valuator; + + KeyClassPtr k = NULL; + ButtonClassPtr b = NULL; + ValuatorClassPtr v = NULL; + BYTE *kptr = NULL; + + /* This event is always the first we get, before the actual events with + * the data. However, the way how the DDX is set up, "device" will + * actually be the slave device that caused the event. + */ + switch(event->type) + { + case ET_DeviceChanged: + ChangeMasterDeviceClasses(device, (DeviceChangedEvent*)event); + return DONT_PROCESS; /* event has been sent already */ + case ET_Motion: + case ET_ButtonPress: + case ET_ButtonRelease: + case ET_KeyPress: + case ET_KeyRelease: + case ET_ProximityIn: + case ET_ProximityOut: + break; + default: + /* other events don't update the device */ + return DEFAULT; + } + + k = device->key; + v = device->valuator; + b = device->button; + + key = event->detail.key; + bit = 1 << (key & 7); + + /* Update device axis */ + /* Check valuators first */ + last_valuator = -1; + for (i = 0; i < MAX_VALUATORS; i++) + { + if (BitIsOn(&event->valuators.mask, i)) + { + if (!v) + { + ErrorF("[Xi] Valuators reported for non-valuator device '%s'. " + "Ignoring event.\n", device->name); + return DONT_PROCESS; + } else if (v->numAxes < i) + { + ErrorF("[Xi] Too many valuators reported for device '%s'. " + "Ignoring event.\n", device->name); + return DONT_PROCESS; + } + last_valuator = i; + } + } + + for (i = 0; i <= last_valuator && i < v->numAxes; i++) + { + if (BitIsOn(&event->valuators.mask, i)) + { + /* XXX: Relative/Absolute mode */ + v->axisVal[i] = event->valuators.data[i]; + v->axisVal[i] += (event->valuators.data_frac[i] * 1.0f / (1 << 16) / (1 << 16)); + } + } + + if (event->type == ET_KeyPress) { + if (!k) + return DONT_PROCESS; + + kptr = &k->down[key >> 3]; + /* don't allow ddx to generate multiple downs, but repeats are okay */ + if ((*kptr & bit) && !event->key_repeat) + return DONT_PROCESS; + if (device->valuator) + device->valuator->motionHintWindow = NullWindow; + *kptr |= bit; + } else if (event->type == ET_KeyRelease) { + if (!k) + return DONT_PROCESS; + + kptr = &k->down[key >> 3]; + if (!(*kptr & bit)) /* guard against duplicates */ + return DONT_PROCESS; + if (device->valuator) + device->valuator->motionHintWindow = NullWindow; + *kptr &= ~bit; + } else if (event->type == ET_ButtonPress) { + Mask mask; + if (!b) + return DONT_PROCESS; + + kptr = &b->down[key >> 3]; + if ((*kptr & bit) != 0) + return DONT_PROCESS; + *kptr |= bit; + if (device->valuator) + device->valuator->motionHintWindow = NullWindow; + if (!b->map[key]) + return DONT_PROCESS; + b->buttonsDown++; + b->motionMask = DeviceButtonMotionMask; + if (b->map[key] <= 5) + b->state |= (Button1Mask >> 1) << b->map[key]; + + /* Add state and motionMask to the filter for this event */ + mask = DevicePointerMotionMask | b->state | b->motionMask; + SetMaskForEvent(device->id, mask, DeviceMotionNotify); + mask = PointerMotionMask | b->state | b->motionMask; + SetMaskForEvent(device->id, mask, MotionNotify); + } else if (event->type == ET_ButtonRelease) { + Mask mask; + if (!b) + return DONT_PROCESS; + + kptr = &b->down[key>>3]; + if (!(*kptr & bit)) + return DONT_PROCESS; + if (IsMaster(device)) { + DeviceIntPtr sd; + + /* + * Leave the button down if any slave has the + * button still down. Note that this depends on the + * event being delivered through the slave first + */ + for (sd = inputInfo.devices; sd; sd = sd->next) { + if (IsMaster(sd) || sd->u.master != device) + continue; + if (!sd->button) + continue; + if ((sd->button->down[key>>3] & bit) != 0) + return DONT_PROCESS; + } + } + *kptr &= ~bit; + if (device->valuator) + device->valuator->motionHintWindow = NullWindow; + if (!b->map[key]) + return DONT_PROCESS; + if (b->buttonsDown >= 1 && !--b->buttonsDown) + b->motionMask = 0; + if (b->map[key] <= 5) + b->state &= ~((Button1Mask >> 1) << b->map[key]); + + /* Add state and motionMask to the filter for this event */ + mask = DevicePointerMotionMask | b->state | b->motionMask; + SetMaskForEvent(device->id, mask, DeviceMotionNotify); + mask = PointerMotionMask | b->state | b->motionMask; + SetMaskForEvent(device->id, mask, MotionNotify); + } else if (event->type == ET_ProximityIn) + device->valuator->mode &= ~OutOfProximity; + else if (event->type == ET_ProximityOut) + device->valuator->mode |= OutOfProximity; + + return DEFAULT; +} + +static void +ProcessRawEvent(RawDeviceEvent *ev, DeviceIntPtr device) +{ + GrabPtr grab = device->deviceGrab.grab; + + if (grab) + DeliverGrabbedEvent((InternalEvent*)ev, device, FALSE); + else { /* deliver to all root windows */ + xEvent *xi; + int i; + + i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi); + if (i != Success) + { + ErrorF("[Xi] %s: XI2 conversion failed in ProcessRawEvent (%d)\n", + device->name, i); + return; + } + + for (i = 0; i < screenInfo.numScreens; i++) + DeliverEventsToWindow(device, WindowTable[i], xi, 1, + GetEventFilter(device, xi), NULL); + free(xi); + } +} + +/** + * Main device event processing function. + * Called from when processing the events from the event queue. + * + */ +void +ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device) +{ + GrabPtr grab; + Bool deactivateDeviceGrab = FALSE; + int key = 0, rootX, rootY; + ButtonClassPtr b; + KeyClassPtr k; + ValuatorClassPtr v; + int ret = 0; + int state, i; + DeviceIntPtr mouse = NULL, kbd = NULL; + DeviceEvent *event = &ev->device_event; + + CHECKEVENT(ev); + + if (ev->any.type == ET_RawKeyPress || + ev->any.type == ET_RawKeyRelease || + ev->any.type == ET_RawButtonPress || + ev->any.type == ET_RawButtonRelease || + ev->any.type == ET_RawMotion) + { + ProcessRawEvent(&ev->raw_event, device); + return; + } + + if (IsPointerDevice(device)) + { + kbd = GetPairedDevice(device); + mouse = device; + if (!kbd->key) /* can happen with floating SDs */ + kbd = NULL; + } else + { + mouse = GetPairedDevice(device); + kbd = device; + if (!mouse->valuator || !mouse->button) /* may be float. SDs */ + mouse = NULL; + } + + /* State needs to be assembled BEFORE the device is updated. */ + state = (kbd && kbd->key) ? XkbStateFieldFromRec(&kbd->key->xkbInfo->state) : 0; + state |= (mouse && mouse->button) ? (mouse->button->state) : 0; + + for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) + if (BitIsOn(mouse->button->down, i)) + SetBit(event->buttons, i); + + if (kbd && kbd->key) + { + XkbStatePtr state; + /* we need the state before the event happens */ + if (event->type == ET_KeyPress || event->type == ET_KeyRelease) + state = &kbd->key->xkbInfo->prev_state; + else + state = &kbd->key->xkbInfo->state; + + event->mods.base = state->base_mods; + event->mods.latched = state->latched_mods; + event->mods.locked = state->locked_mods; + event->mods.effective = state->mods; + + event->group.base = state->base_group; + event->group.latched = state->latched_group; + event->group.locked = state->locked_group; + event->group.effective = state->group; + } + + ret = UpdateDeviceState(device, event); + if (ret == DONT_PROCESS) + return; + + v = device->valuator; + b = device->button; + k = device->key; + + if (IsMaster(device) || !device->u.master) + CheckMotion(event, device); + + switch (event->type) + { + case ET_Motion: + case ET_ButtonPress: + case ET_ButtonRelease: + case ET_KeyPress: + case ET_KeyRelease: + case ET_ProximityIn: + case ET_ProximityOut: + GetSpritePosition(device, &rootX, &rootY); + event->root_x = rootX; + event->root_y = rootY; + NoticeEventTime((InternalEvent*)event); + event->corestate = state; + key = event->detail.key; + break; + default: + break; + } + + if (DeviceEventCallback && !syncEvents.playingEvents) { + DeviceEventInfoRec eventinfo; + SpritePtr pSprite = device->spriteInfo->sprite; + + /* see comment in EnqueueEvents regarding the next three lines */ + if (ev->any.type == ET_Motion) + ev->device_event.root = WindowTable[pSprite->hotPhys.pScreen->myNum]->drawable.id; + + eventinfo.device = device; + eventinfo.event = ev; + CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo); + } + + grab = device->deviceGrab.grab; + + switch(event->type) + { + case ET_KeyPress: + if (!grab && CheckDeviceGrabs(device, event, 0)) { + device->deviceGrab.activatingKey = key; + return; + } + break; + case ET_KeyRelease: + if (grab && device->deviceGrab.fromPassiveGrab && + (key == device->deviceGrab.activatingKey) && + (device->deviceGrab.grab->type == KeyPress || + device->deviceGrab.grab->type == DeviceKeyPress || + device->deviceGrab.grab->type == XI_KeyPress)) + deactivateDeviceGrab = TRUE; + break; + case ET_ButtonPress: + event->detail.button = b->map[key]; + if (!event->detail.button) { /* there's no button 0 */ + event->detail.button = key; + return; + } + if (!grab && CheckDeviceGrabs(device, event, 0)) + { + /* if a passive grab was activated, the event has been sent + * already */ + return; + } + break; + case ET_ButtonRelease: + event->detail.button = b->map[key]; + if (!event->detail.button) { /* there's no button 0 */ + event->detail.button = key; + return; + } + if (grab && !b->buttonsDown && + device->deviceGrab.fromPassiveGrab && + (device->deviceGrab.grab->type == ButtonPress || + device->deviceGrab.grab->type == DeviceButtonPress || + device->deviceGrab.grab->type == XI_ButtonPress)) + deactivateDeviceGrab = TRUE; + default: + break; + } + + + if (grab) + DeliverGrabbedEvent((InternalEvent*)event, device, deactivateDeviceGrab); + else if (device->focus && !IsPointerEvent((InternalEvent*)ev)) + DeliverFocusedEvent(device, (InternalEvent*)event, + GetSpriteWindow(device)); + else + DeliverDeviceEvents(GetSpriteWindow(device), (InternalEvent*)event, + NullGrab, NullWindow, device); + + if (deactivateDeviceGrab == TRUE) + (*device->deviceGrab.DeactivateGrab) (device); + event->detail.key = key; +} + +int +InitProximityClassDeviceStruct(DeviceIntPtr dev) +{ + ProximityClassPtr proxc; + + proxc = (ProximityClassPtr) malloc(sizeof(ProximityClassRec)); + if (!proxc) + return FALSE; + proxc->sourceid = dev->id; + dev->proximity = proxc; + return TRUE; +} + +/** + * Initialise the device's valuators. The memory must already be allocated, + * this function merely inits the matching axis (specified through axnum) to + * sane values. + * + * It is a condition that (minval < maxval). + * + * @see InitValuatorClassDeviceStruct + */ +void +InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval, + int resolution, int min_res, int max_res) +{ + AxisInfoPtr ax; + + if (!dev || !dev->valuator || minval > maxval) + return; + if (axnum >= dev->valuator->numAxes) + return; + + ax = dev->valuator->axes + axnum; + + ax->min_value = minval; + ax->max_value = maxval; + ax->resolution = resolution; + ax->min_resolution = min_res; + ax->max_resolution = max_res; + ax->label = label; +} + +static void +FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k, + ButtonClassPtr b, ValuatorClassPtr v, int first) +{ + ev->type = DeviceStateNotify; + ev->deviceid = dev->id; + ev->time = currentTime.milliseconds; + ev->classes_reported = 0; + ev->num_keys = 0; + ev->num_buttons = 0; + ev->num_valuators = 0; + + if (b) { + ev->classes_reported |= (1 << ButtonClass); + ev->num_buttons = b->numButtons; + memcpy((char*)ev->buttons, (char*)b->down, 4); + } else if (k) { + ev->classes_reported |= (1 << KeyClass); + ev->num_keys = k->xkbInfo->desc->max_key_code - + k->xkbInfo->desc->min_key_code; + memmove((char *)&ev->keys[0], (char *)k->down, 4); + } + if (v) { + int nval = v->numAxes - first; + + ev->classes_reported |= (1 << ValuatorClass); + ev->classes_reported |= (dev->valuator->mode << ModeBitsShift); + ev->num_valuators = nval < 3 ? nval : 3; + switch (ev->num_valuators) { + case 3: + ev->valuator2 = v->axisVal[first + 2]; + case 2: + ev->valuator1 = v->axisVal[first + 1]; + case 1: + ev->valuator0 = v->axisVal[first]; + break; + } + } +} + +static void +FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, + int first) +{ + int nval = v->numAxes - first; + + ev->type = DeviceValuator; + ev->deviceid = dev->id; + ev->num_valuators = nval < 3 ? nval : 3; + ev->first_valuator = first; + switch (ev->num_valuators) { + case 3: + ev->valuator2 = v->axisVal[first + 2]; + case 2: + ev->valuator1 = v->axisVal[first + 1]; + case 1: + ev->valuator0 = v->axisVal[first]; + break; + } + first += ev->num_valuators; +} + +void +DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, + WindowPtr pWin) +{ + deviceFocus event; + xXIFocusInEvent *xi2event; + DeviceIntPtr mouse; + int btlen, len, i; + + mouse = (IsMaster(dev) || dev->u.master) ? GetMaster(dev, MASTER_POINTER) : dev; + + /* XI 2 event */ + btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0; + btlen = bytes_to_int32(btlen); + len = sizeof(xXIFocusInEvent) + btlen * 4; + + xi2event = calloc(1, len); + xi2event->type = GenericEvent; + xi2event->extension = IReqCode; + xi2event->evtype = type; + xi2event->length = bytes_to_int32(len - sizeof(xEvent)); + xi2event->buttons_len = btlen; + xi2event->detail = detail; + xi2event->time = currentTime.milliseconds; + xi2event->deviceid = dev->id; + xi2event->sourceid = dev->id; /* a device doesn't change focus by itself */ + xi2event->mode = mode; + xi2event->root_x = FP1616(mouse->spriteInfo->sprite->hot.x, 0); + xi2event->root_y = FP1616(mouse->spriteInfo->sprite->hot.y, 0); + + for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) + if (BitIsOn(mouse->button->down, i)) + SetBit(&xi2event[1], i); + + if (dev->key) + { + xi2event->mods.base_mods = dev->key->xkbInfo->state.base_mods; + xi2event->mods.latched_mods = dev->key->xkbInfo->state.latched_mods; + xi2event->mods.locked_mods = dev->key->xkbInfo->state.locked_mods; + xi2event->mods.effective_mods = dev->key->xkbInfo->state.mods; + + xi2event->group.base_group = dev->key->xkbInfo->state.base_group; + xi2event->group.latched_group = dev->key->xkbInfo->state.latched_group; + xi2event->group.locked_group = dev->key->xkbInfo->state.locked_group; + xi2event->group.effective_group = dev->key->xkbInfo->state.group; + } + + FixUpEventFromWindow(dev, (xEvent*)xi2event, pWin, None, FALSE); + + DeliverEventsToWindow(dev, pWin, (xEvent*)xi2event, 1, + GetEventFilter(dev, (xEvent*)xi2event), NullGrab); + + free(xi2event); + + /* XI 1.x event */ + event.deviceid = dev->id; + event.mode = mode; + event.type = (type == XI_FocusIn) ? DeviceFocusIn : DeviceFocusOut; + event.detail = detail; + event.window = pWin->drawable.id; + event.time = currentTime.milliseconds; + + DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1, + DeviceFocusChangeMask, NullGrab); + + if ((type == DeviceFocusIn) && + (wOtherInputMasks(pWin)) && + (wOtherInputMasks(pWin)->inputEvents[dev->id] & DeviceStateNotifyMask)) + { + int evcount = 1; + deviceStateNotify *ev, *sev; + deviceKeyStateNotify *kev; + deviceButtonStateNotify *bev; + + KeyClassPtr k; + ButtonClassPtr b; + ValuatorClassPtr v; + int nval = 0, nkeys = 0, nbuttons = 0, first = 0; + + if ((b = dev->button) != NULL) { + nbuttons = b->numButtons; + if (nbuttons > 32) + evcount++; + } + if ((k = dev->key) != NULL) { + nkeys = k->xkbInfo->desc->max_key_code - + k->xkbInfo->desc->min_key_code; + if (nkeys > 32) + evcount++; + if (nbuttons > 0) { + evcount++; + } + } + if ((v = dev->valuator) != NULL) { + nval = v->numAxes; + + if (nval > 3) + evcount++; + if (nval > 6) { + if (!(k && b)) + evcount++; + if (nval > 9) + evcount += ((nval - 7) / 3); + } + } + + sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent)); + FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); + + if (b != NULL) { + FixDeviceStateNotify(dev, ev++, NULL, b, v, first); + first += 3; + nval -= 3; + if (nbuttons > 32) { + (ev - 1)->deviceid |= MORE_EVENTS; + bev = (deviceButtonStateNotify *) ev++; + bev->type = DeviceButtonStateNotify; + bev->deviceid = dev->id; + memcpy((char*)&bev->buttons[4], (char*)&b->down[4], DOWN_LENGTH - 4); + } + if (nval > 0) { + (ev - 1)->deviceid |= MORE_EVENTS; + FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); + first += 3; + nval -= 3; + } + } + + if (k != NULL) { + FixDeviceStateNotify(dev, ev++, k, NULL, v, first); + first += 3; + nval -= 3; + if (nkeys > 32) { + (ev - 1)->deviceid |= MORE_EVENTS; + kev = (deviceKeyStateNotify *) ev++; + kev->type = DeviceKeyStateNotify; + kev->deviceid = dev->id; + memmove((char *)&kev->keys[0], (char *)&k->down[4], 28); + } + if (nval > 0) { + (ev - 1)->deviceid |= MORE_EVENTS; + FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); + first += 3; + nval -= 3; + } + } + + while (nval > 0) { + FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first); + first += 3; + nval -= 3; + if (nval > 0) { + (ev - 1)->deviceid |= MORE_EVENTS; + FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); + first += 3; + nval -= 3; + } + } + + DeliverEventsToWindow(dev, pWin, (xEvent *) sev, evcount, + DeviceStateNotifyMask, NullGrab); + free(sev); + } +} + +int +CheckGrabValues(ClientPtr client, GrabParameters* param) +{ + if (param->grabtype != GRABTYPE_CORE && + param->grabtype != GRABTYPE_XI && + param->grabtype != GRABTYPE_XI2) + { + ErrorF("[Xi] grabtype is invalid. This is a bug.\n"); + return BadImplementation; + } + + if ((param->this_device_mode != GrabModeSync) && + (param->this_device_mode != GrabModeAsync)) { + client->errorValue = param->this_device_mode; + return BadValue; + } + if ((param->other_devices_mode != GrabModeSync) && + (param->other_devices_mode != GrabModeAsync)) { + client->errorValue = param->other_devices_mode; + return BadValue; + } + + if (param->grabtype != GRABTYPE_XI2 && (param->modifiers != AnyModifier) && + (param->modifiers & ~AllModifiersMask)) { + client->errorValue = param->modifiers; + return BadValue; + } + + if ((param->ownerEvents != xFalse) && (param->ownerEvents != xTrue)) { + client->errorValue = param->ownerEvents; + return BadValue; + } + return Success; +} + +int +GrabButton(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device, + int button, GrabParameters *param, GrabType grabtype, + GrabMask *mask) +{ + WindowPtr pWin, confineTo; + CursorPtr cursor; + GrabPtr grab; + int rc, type = -1; + Mask access_mode = DixGrabAccess; + + rc = CheckGrabValues(client, param); + if (rc != Success) + return rc; + if (param->confineTo == None) + confineTo = NullWindow; + else { + rc = dixLookupWindow(&confineTo, param->confineTo, client, DixSetAttrAccess); + if (rc != Success) + return rc; + } + if (param->cursor == None) + cursor = NullCursor; + else { + rc = dixLookupResourceByType((pointer *)&cursor, param->cursor, + RT_CURSOR, client, DixUseAccess); + if (rc != Success) + { + client->errorValue = param->cursor; + return (rc == BadValue) ? BadCursor : rc; + } + access_mode |= DixForceAccess; + } + if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) + access_mode |= DixFreezeAccess; + rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); + if (rc != Success) + return rc; + rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); + if (rc != Success) + return rc; + + if (grabtype == GRABTYPE_XI) + type = DeviceButtonPress; + else if (grabtype == GRABTYPE_XI2) + type = XI_ButtonPress; + + grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype, + mask, param, type, button, confineTo, cursor); + if (!grab) + return BadAlloc; + return AddPassiveGrabToList(client, grab); +} + +/** + * Grab the given key. If grabtype is GRABTYPE_XI, the key is a keycode. If + * grabtype is GRABTYPE_XI2, the key is a keysym. + */ +int +GrabKey(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device, + int key, GrabParameters *param, GrabType grabtype, GrabMask *mask) +{ + WindowPtr pWin; + GrabPtr grab; + KeyClassPtr k = dev->key; + Mask access_mode = DixGrabAccess; + int rc, type = -1; + + rc = CheckGrabValues(client, param); + if (rc != Success) + return rc; + if (k == NULL) + return BadMatch; + if (grabtype == GRABTYPE_XI) + { + if ((key > k->xkbInfo->desc->max_key_code || + key < k->xkbInfo->desc->min_key_code) + && (key != AnyKey)) { + client->errorValue = key; + return BadValue; + } + type = DeviceKeyPress; + } else if (grabtype == GRABTYPE_XI2) + type = XI_KeyPress; + + rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); + if (rc != Success) + return rc; + if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) + access_mode |= DixFreezeAccess; + rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); + if (rc != Success) + return rc; + + grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype, + mask, param, type, key, NULL, NULL); + if (!grab) + return BadAlloc; + return AddPassiveGrabToList(client, grab); +} + +/* Enter/FocusIn grab */ +int +GrabWindow(ClientPtr client, DeviceIntPtr dev, int type, + GrabParameters *param, GrabMask *mask) +{ + WindowPtr pWin; + CursorPtr cursor; + GrabPtr grab; + Mask access_mode = DixGrabAccess; + int rc; + + rc = CheckGrabValues(client, param); + if (rc != Success) + return rc; + + rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); + if (rc != Success) + return rc; + if (param->cursor == None) + cursor = NullCursor; + else { + rc = dixLookupResourceByType((pointer *)&cursor, param->cursor, + RT_CURSOR, client, DixUseAccess); + if (rc != Success) + { + client->errorValue = param->cursor; + return (rc == BadValue) ? BadCursor : rc; + } + access_mode |= DixForceAccess; + } + if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) + access_mode |= DixFreezeAccess; + rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); + if (rc != Success) + return rc; + + grab = CreateGrab(client->index, dev, dev, pWin, GRABTYPE_XI2, + mask, param, (type == XIGrabtypeEnter) ? XI_Enter : XI_FocusIn, + 0, NULL, cursor); + + if (!grab) + return BadAlloc; + + return AddPassiveGrabToList(client, grab); +} + +int +SelectForWindow(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client, + Mask mask, Mask exclusivemasks) +{ + int mskidx = dev->id; + int i, ret; + Mask check; + InputClientsPtr others; + + check = (mask & exclusivemasks); + if (wOtherInputMasks(pWin)) { + if (check & wOtherInputMasks(pWin)->inputEvents[mskidx]) { /* It is illegal for two different + * clients to select on any of the + * events for maskcheck. However, + * it is OK, for some client to + * continue selecting on one of those + * events. */ + for (others = wOtherInputMasks(pWin)->inputClients; others; + others = others->next) { + if (!SameClient(others, client) && (check & + others->mask[mskidx])) + return BadAccess; + } + } + for (others = wOtherInputMasks(pWin)->inputClients; others; + others = others->next) { + if (SameClient(others, client)) { + check = others->mask[mskidx]; + others->mask[mskidx] = mask; + if (mask == 0) { + for (i = 0; i < EMASKSIZE; i++) + if (i != mskidx && others->mask[i] != 0) + break; + if (i == EMASKSIZE) { + RecalculateDeviceDeliverableEvents(pWin); + if (ShouldFreeInputMasks(pWin, FALSE)) + FreeResource(others->resource, RT_NONE); + return Success; + } + } + goto maskSet; + } + } + } + check = 0; + if ((ret = AddExtensionClient(pWin, client, mask, mskidx)) != Success) + return ret; + maskSet: + if (dev->valuator) + if ((dev->valuator->motionHintWindow == pWin) && + (mask & DevicePointerMotionHintMask) && + !(check & DevicePointerMotionHintMask) && !dev->deviceGrab.grab) + dev->valuator->motionHintWindow = NullWindow; + RecalculateDeviceDeliverableEvents(pWin); + return Success; +} + +int +AddExtensionClient(WindowPtr pWin, ClientPtr client, Mask mask, int mskidx) +{ + InputClientsPtr others; + + if (!pWin->optional && !MakeWindowOptional(pWin)) + return BadAlloc; + others = calloc(1, sizeof(InputClients)); + if (!others) + return BadAlloc; + if (!pWin->optional->inputMasks && !MakeInputMasks(pWin)) + return BadAlloc; + others->mask[mskidx] = mask; + others->resource = FakeClientID(client->index); + others->next = pWin->optional->inputMasks->inputClients; + pWin->optional->inputMasks->inputClients = others; + if (!AddResource(others->resource, RT_INPUTCLIENT, (pointer) pWin)) + return BadAlloc; + return Success; +} + +static Bool +MakeInputMasks(WindowPtr pWin) +{ + struct _OtherInputMasks *imasks; + + imasks = calloc(1, sizeof(struct _OtherInputMasks)); + if (!imasks) + return FALSE; + pWin->optional->inputMasks = imasks; + return TRUE; +} + +void +RecalculateDeviceDeliverableEvents(WindowPtr pWin) +{ + InputClientsPtr others; + struct _OtherInputMasks *inputMasks; /* default: NULL */ + WindowPtr pChild, tmp; + int i, j; + + pChild = pWin; + while (1) { + if ((inputMasks = wOtherInputMasks(pChild)) != 0) { + for (i = 0; i < EMASKSIZE; i++) + memset(inputMasks->xi2mask[i], 0, sizeof(inputMasks->xi2mask[i])); + for (others = inputMasks->inputClients; others; + others = others->next) { + for (i = 0; i < EMASKSIZE; i++) + inputMasks->inputEvents[i] |= others->mask[i]; + for (i = 0; i < EMASKSIZE; i++) + for (j = 0; j < XI2MASKSIZE; j++) + inputMasks->xi2mask[i][j] |= others->xi2mask[i][j]; + } + for (i = 0; i < EMASKSIZE; i++) + inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i]; + for (tmp = pChild->parent; tmp; tmp = tmp->parent) + if (wOtherInputMasks(tmp)) + for (i = 0; i < EMASKSIZE; i++) + inputMasks->deliverableEvents[i] |= + (wOtherInputMasks(tmp)->deliverableEvents[i] + & ~inputMasks-> + dontPropagateMask[i] & PropagateMask[i]); + } + if (pChild->firstChild) { + pChild = pChild->firstChild; + continue; + } + while (!pChild->nextSib && (pChild != pWin)) + pChild = pChild->parent; + if (pChild == pWin) + break; + pChild = pChild->nextSib; + } +} + +int +InputClientGone(WindowPtr pWin, XID id) +{ + InputClientsPtr other, prev; + + if (!wOtherInputMasks(pWin)) + return (Success); + prev = 0; + for (other = wOtherInputMasks(pWin)->inputClients; other; + other = other->next) { + if (other->resource == id) { + if (prev) { + prev->next = other->next; + free(other); + } else if (!(other->next)) { + if (ShouldFreeInputMasks(pWin, TRUE)) { + wOtherInputMasks(pWin)->inputClients = other->next; + free(wOtherInputMasks(pWin)); + pWin->optional->inputMasks = (OtherInputMasks *) NULL; + CheckWindowOptionalNeed(pWin); + free(other); + } else { + other->resource = FakeClientID(0); + if (!AddResource(other->resource, RT_INPUTCLIENT, + (pointer) pWin)) + return BadAlloc; + } + } else { + wOtherInputMasks(pWin)->inputClients = other->next; + free(other); + } + RecalculateDeviceDeliverableEvents(pWin); + return (Success); + } + prev = other; + } + FatalError("client not on device event list"); +} + +int +SendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate, + xEvent * ev, Mask mask, int count) +{ + WindowPtr pWin; + WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */ + WindowPtr spriteWin = GetSpriteWindow(d); + + if (dest == PointerWindow) + pWin = spriteWin; + else if (dest == InputFocus) { + WindowPtr inputFocus; + + if (!d->focus) + inputFocus = spriteWin; + else + inputFocus = d->focus->win; + + if (inputFocus == FollowKeyboardWin) + 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 = GetCurrentRootWindow(d); + + if (IsParent(inputFocus, spriteWin)) { + effectiveFocus = inputFocus; + pWin = spriteWin; + } else + effectiveFocus = pWin = inputFocus; + } else + dixLookupWindow(&pWin, dest, client, DixSendAccess); + if (!pWin) + return BadWindow; + if ((propagate != xFalse) && (propagate != xTrue)) { + client->errorValue = propagate; + return BadValue; + } + ev->u.u.type |= 0x80; + if (propagate) { + for (; pWin; pWin = pWin->parent) { + if (DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab)) + return Success; + if (pWin == effectiveFocus) + return Success; + if (wOtherInputMasks(pWin)) + mask &= ~wOtherInputMasks(pWin)->dontPropagateMask[d->id]; + if (!mask) + break; + } + } else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, ev, count)) + DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab); + return Success; +} + +int +SetButtonMapping(ClientPtr client, DeviceIntPtr dev, int nElts, BYTE * map) +{ + int i; + ButtonClassPtr b = dev->button; + + if (b == NULL) + return BadMatch; + + if (nElts != b->numButtons) { + client->errorValue = nElts; + return BadValue; + } + if (BadDeviceMap(&map[0], nElts, 1, 255, &client->errorValue)) + return BadValue; + for (i = 0; i < nElts; i++) + if ((b->map[i + 1] != map[i]) && BitIsOn(b->down, i + 1)) + return MappingBusy; + for (i = 0; i < nElts; i++) + b->map[i + 1] = map[i]; + return Success; +} + +int +ChangeKeyMapping(ClientPtr client, + DeviceIntPtr dev, + unsigned len, + int type, + KeyCode firstKeyCode, + CARD8 keyCodes, CARD8 keySymsPerKeyCode, KeySym * map) +{ + KeySymsRec keysyms; + KeyClassPtr k = dev->key; + + if (k == NULL) + return (BadMatch); + + if (len != (keyCodes * keySymsPerKeyCode)) + return BadLength; + + if ((firstKeyCode < k->xkbInfo->desc->min_key_code) || + (firstKeyCode + keyCodes - 1 > k->xkbInfo->desc->max_key_code)) { + client->errorValue = firstKeyCode; + return BadValue; + } + if (keySymsPerKeyCode == 0) { + client->errorValue = 0; + return BadValue; + } + keysyms.minKeyCode = firstKeyCode; + keysyms.maxKeyCode = firstKeyCode + keyCodes - 1; + keysyms.mapWidth = keySymsPerKeyCode; + keysyms.map = map; + + XkbApplyMappingChange(dev, &keysyms, firstKeyCode, keyCodes, NULL, + serverClient); + + return Success; +} + +static void +DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev) +{ + WindowPtr parent; + + /* Deactivate any grabs performed on this window, before making + * any input focus changes. + * Deactivating a device grab should cause focus events. */ + + if (dev->deviceGrab.grab && (dev->deviceGrab.grab->window == pWin)) + (*dev->deviceGrab.DeactivateGrab) (dev); + + /* If the focus window is a root window (ie. has no parent) + * then don't delete the focus from it. */ + + if (dev->focus && (pWin == dev->focus->win) && (pWin->parent != NullWindow)) { + int focusEventMode = NotifyNormal; + + /* If a grab is in progress, then alter the mode of focus events. */ + + if (dev->deviceGrab.grab) + focusEventMode = NotifyWhileGrabbed; + + switch (dev->focus->revert) { + case RevertToNone: + if (!ActivateFocusInGrab(dev, pWin, NoneWin)) + DoFocusEvents(dev, pWin, NoneWin, focusEventMode); + dev->focus->win = NoneWin; + dev->focus->traceGood = 0; + break; + case RevertToParent: + parent = pWin; + do { + parent = parent->parent; + dev->focus->traceGood--; + } + while (!parent->realized); + if (!ActivateFocusInGrab(dev, pWin, parent)) + DoFocusEvents(dev, pWin, parent, focusEventMode); + dev->focus->win = parent; + dev->focus->revert = RevertToNone; + break; + case RevertToPointerRoot: + if (!ActivateFocusInGrab(dev, pWin, PointerRootWin)) + DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode); + dev->focus->win = PointerRootWin; + dev->focus->traceGood = 0; + break; + case RevertToFollowKeyboard: + { + DeviceIntPtr kbd = GetMaster(dev, MASTER_KEYBOARD); + if (!kbd || (kbd == dev && kbd != inputInfo.keyboard)) + kbd = inputInfo.keyboard; + if (kbd->focus->win) { + if (!ActivateFocusInGrab(dev, pWin, kbd->focus->win)) + DoFocusEvents(dev, pWin, kbd->focus->win, focusEventMode); + dev->focus->win = FollowKeyboardWin; + dev->focus->traceGood = 0; + } else { + if (!ActivateFocusInGrab(dev, pWin, NoneWin)) + DoFocusEvents(dev, pWin, NoneWin, focusEventMode); + dev->focus->win = NoneWin; + dev->focus->traceGood = 0; + } + } + break; + } + } + + if (dev->valuator) + if (dev->valuator->motionHintWindow == pWin) + dev->valuator->motionHintWindow = NullWindow; +} + +void +DeleteWindowFromAnyExtEvents(WindowPtr pWin, Bool freeResources) +{ + int i; + DeviceIntPtr dev; + InputClientsPtr ic; + struct _OtherInputMasks *inputMasks; + + for (dev = inputInfo.devices; dev; dev = dev->next) { + DeleteDeviceFromAnyExtEvents(pWin, dev); + } + + for (dev = inputInfo.off_devices; dev; dev = dev->next) + DeleteDeviceFromAnyExtEvents(pWin, dev); + + if (freeResources) + while ((inputMasks = wOtherInputMasks(pWin)) != 0) { + ic = inputMasks->inputClients; + for (i = 0; i < EMASKSIZE; i++) + inputMasks->dontPropagateMask[i] = 0; + FreeResource(ic->resource, RT_NONE); + } +} + +int +MaybeSendDeviceMotionNotifyHint(deviceKeyButtonPointer * pEvents, Mask mask) +{ + DeviceIntPtr dev; + + dixLookupDevice(&dev, pEvents->deviceid & DEVICE_BITS, serverClient, + DixReadAccess); + if (!dev) + return 0; + + if (pEvents->type == DeviceMotionNotify) { + if (mask & DevicePointerMotionHintMask) { + if (WID(dev->valuator->motionHintWindow) == pEvents->event) { + return 1; /* don't send, but pretend we did */ + } + pEvents->detail = NotifyHint; + } else { + pEvents->detail = NotifyNormal; + } + } + return (0); +} + +void +CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type, + deviceKeyButtonPointer * xE, GrabPtr grab, + ClientPtr client, Mask deliveryMask) +{ + DeviceIntPtr dev; + + dixLookupDevice(&dev, xE->deviceid & DEVICE_BITS, serverClient, + DixGrabAccess); + if (!dev) + return; + + if (type == DeviceMotionNotify) + dev->valuator->motionHintWindow = pWin; + else if ((type == DeviceButtonPress) && (!grab) && + (deliveryMask & DeviceButtonGrabMask)) { + GrabRec tempGrab; + + tempGrab.device = dev; + tempGrab.resource = client->clientAsMask; + tempGrab.window = pWin; + tempGrab.ownerEvents = + (deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE; + tempGrab.eventMask = deliveryMask; + tempGrab.keyboardMode = GrabModeAsync; + tempGrab.pointerMode = GrabModeAsync; + tempGrab.confineTo = NullWindow; + tempGrab.cursor = NullCursor; + tempGrab.next = NULL; + (*dev->deviceGrab.ActivateGrab) (dev, &tempGrab, currentTime, TRUE); + } +} + +static Mask +DeviceEventMaskForClient(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client) +{ + InputClientsPtr other; + + if (!wOtherInputMasks(pWin)) + return 0; + for (other = wOtherInputMasks(pWin)->inputClients; other; + other = other->next) { + if (SameClient(other, client)) + return other->mask[dev->id]; + } + return 0; +} + +void +MaybeStopDeviceHint(DeviceIntPtr dev, ClientPtr client) +{ + WindowPtr pWin; + GrabPtr grab = dev->deviceGrab.grab; + + pWin = dev->valuator->motionHintWindow; + + if ((grab && SameClient(grab, client) && + ((grab->eventMask & DevicePointerMotionHintMask) || + (grab->ownerEvents && + (DeviceEventMaskForClient(dev, pWin, client) & + DevicePointerMotionHintMask)))) || + (!grab && + (DeviceEventMaskForClient(dev, pWin, client) & + DevicePointerMotionHintMask))) + dev->valuator->motionHintWindow = NullWindow; +} + +int +DeviceEventSuppressForWindow(WindowPtr pWin, ClientPtr client, Mask mask, + int maskndx) +{ + struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); + + if (mask & ~PropagateMask[maskndx]) { + client->errorValue = mask; + return BadValue; + } + + if (mask == 0) { + if (inputMasks) + inputMasks->dontPropagateMask[maskndx] = mask; + } else { + if (!inputMasks) + AddExtensionClient(pWin, client, 0, 0); + inputMasks = wOtherInputMasks(pWin); + inputMasks->dontPropagateMask[maskndx] = mask; + } + RecalculateDeviceDeliverableEvents(pWin); + if (ShouldFreeInputMasks(pWin, FALSE)) + FreeResource(inputMasks->inputClients->resource, RT_NONE); + return Success; +} + +Bool +ShouldFreeInputMasks(WindowPtr pWin, Bool ignoreSelectedEvents) +{ + int i; + Mask allInputEventMasks = 0; + struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); + + for (i = 0; i < EMASKSIZE; i++) + allInputEventMasks |= inputMasks->dontPropagateMask[i]; + if (!ignoreSelectedEvents) + for (i = 0; i < EMASKSIZE; i++) + allInputEventMasks |= inputMasks->inputEvents[i]; + if (allInputEventMasks == 0) + return TRUE; + else + return FALSE; +} + +/*********************************************************************** + * + * Walk through the window tree, finding all clients that want to know + * about the Event. + * + */ + +static void +FindInterestedChildren(DeviceIntPtr dev, WindowPtr p1, Mask mask, + xEvent * ev, int count) +{ + WindowPtr p2; + + while (p1) { + p2 = p1->firstChild; + DeliverEventsToWindow(dev, p1, ev, count, mask, NullGrab); + FindInterestedChildren(dev, p2, mask, ev, count); + p1 = p1->nextSib; + } +} + +/*********************************************************************** + * + * Send an event to interested clients in all windows on all screens. + * + */ + +void +SendEventToAllWindows(DeviceIntPtr dev, Mask mask, xEvent * ev, int count) +{ + int i; + WindowPtr pWin, p1; + + for (i = 0; i < screenInfo.numScreens; i++) { + pWin = WindowTable[i]; + if (!pWin) + continue; + DeliverEventsToWindow(dev, pWin, ev, count, mask, NullGrab); + p1 = pWin->firstChild; + FindInterestedChildren(dev, p1, mask, ev, count); + } +} + +/** + * Set the XI2 mask for the given client on the given window. + * @param dev The device to set the mask for. + * @param win The window to set the mask on. + * @param client The client setting the mask. + * @param len Number of bytes in mask. + * @param mask Event mask in the form of (1 << eventtype) + */ +int +XISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client, + unsigned int len, unsigned char* mask) +{ + OtherInputMasks *masks; + InputClientsPtr others = NULL; + + masks = wOtherInputMasks(win); + if (masks) + { + for (others = wOtherInputMasks(win)->inputClients; others; + others = others->next) { + if (SameClient(others, client)) { + memset(others->xi2mask[dev->id], 0, + sizeof(others->xi2mask[dev->id])); + break; + } + } + } + + len = min(len, sizeof(others->xi2mask[dev->id])); + + if (len && !others) + { + if (AddExtensionClient(win, client, 0, 0) != Success) + return BadAlloc; + others= wOtherInputMasks(win)->inputClients; + } + + if (others) + memset(others->xi2mask[dev->id], 0, sizeof(others->xi2mask[dev->id])); + + if (len) + memcpy(others->xi2mask[dev->id], mask, len); + + RecalculateDeviceDeliverableEvents(win); + + return Success; +} diff --git a/xorg-server/Xi/extinit.c b/xorg-server/Xi/extinit.c index 07057377a..9d6c81a5b 100644 --- a/xorg-server/Xi/extinit.c +++ b/xorg-server/Xi/extinit.c @@ -1156,7 +1156,7 @@ void AssignTypeAndName(DeviceIntPtr dev, Atom type, char *name) { dev->xinput_type = type; - dev->name = (char *)xalloc(strlen(name) + 1); + dev->name = (char *)malloc(strlen(name) + 1); strcpy(dev->name, name); } diff --git a/xorg-server/Xi/getdctl.c b/xorg-server/Xi/getdctl.c index 68181fa61..35ddd3f8e 100644 --- a/xorg-server/Xi/getdctl.c +++ b/xorg-server/Xi/getdctl.c @@ -1,314 +1,314 @@ -/************************************************************ - -Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. - - 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 Hewlett-Packard not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -HEWLETT-PACKARD 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. - -********************************************************/ - -/******************************************************************** - * - * Get Device control attributes for an extension device. - * - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "inputstr.h" /* DeviceIntPtr */ -#include -#include -#include "exglobals.h" - -#include "getdctl.h" - -/*********************************************************************** - * - * This procedure gets the control attributes for an extension device, - * for clients on machines with a different byte ordering than the server. - * - */ - -int -SProcXGetDeviceControl(ClientPtr client) -{ - char n; - - REQUEST(xGetDeviceControlReq); - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xGetDeviceControlReq); - swaps(&stuff->control, n); - return (ProcXGetDeviceControl(client)); -} - -/*********************************************************************** - * - * This procedure copies DeviceResolution data, swapping if necessary. - * - */ - -static void -CopySwapDeviceResolution(ClientPtr client, ValuatorClassPtr v, char *buf, - int length) -{ - char n; - AxisInfoPtr a; - xDeviceResolutionState *r; - int i, *iptr; - - r = (xDeviceResolutionState *) buf; - r->control = DEVICE_RESOLUTION; - r->length = length; - r->num_valuators = v->numAxes; - buf += sizeof(xDeviceResolutionState); - iptr = (int *)buf; - for (i = 0, a = v->axes; i < v->numAxes; i++, a++) - *iptr++ = a->resolution; - for (i = 0, a = v->axes; i < v->numAxes; i++, a++) - *iptr++ = a->min_resolution; - for (i = 0, a = v->axes; i < v->numAxes; i++, a++) - *iptr++ = a->max_resolution; - if (client->swapped) { - swaps(&r->control, n); - swaps(&r->length, n); - swapl(&r->num_valuators, n); - iptr = (int *)buf; - for (i = 0; i < (3 * v->numAxes); i++, iptr++) { - swapl(iptr, n); - } - } -} - -static void CopySwapDeviceAbsCalib (ClientPtr client, AbsoluteClassPtr dts, - char *buf) -{ - char n; - xDeviceAbsCalibState *calib = (xDeviceAbsCalibState *) buf; - - calib->control = DEVICE_ABS_CALIB; - calib->length = sizeof(xDeviceAbsCalibState); - calib->min_x = dts->min_x; - calib->max_x = dts->max_x; - calib->min_y = dts->min_y; - calib->max_y = dts->max_y; - calib->flip_x = dts->flip_x; - calib->flip_y = dts->flip_y; - calib->rotation = dts->rotation; - calib->button_threshold = dts->button_threshold; - - if (client->swapped) { - swaps(&calib->control, n); - swaps(&calib->length, n); - swapl(&calib->min_x, n); - swapl(&calib->max_x, n); - swapl(&calib->min_y, n); - swapl(&calib->max_y, n); - swapl(&calib->flip_x, n); - swapl(&calib->flip_y, n); - swapl(&calib->rotation, n); - swapl(&calib->button_threshold, n); - } -} - -static void CopySwapDeviceAbsArea (ClientPtr client, AbsoluteClassPtr dts, - char *buf) -{ - char n; - xDeviceAbsAreaState *area = (xDeviceAbsAreaState *) buf; - - area->control = DEVICE_ABS_AREA; - area->length = sizeof(xDeviceAbsAreaState); - area->offset_x = dts->offset_x; - area->offset_y = dts->offset_y; - area->width = dts->width; - area->height = dts->height; - area->screen = dts->screen; - area->following = dts->following; - - if (client->swapped) { - swaps(&area->control, n); - swaps(&area->length, n); - swapl(&area->offset_x, n); - swapl(&area->offset_y, n); - swapl(&area->width, n); - swapl(&area->height, n); - swapl(&area->screen, n); - swapl(&area->following, n); - } -} - -static void CopySwapDeviceCore (ClientPtr client, DeviceIntPtr dev, char *buf) -{ - char n; - xDeviceCoreState *c = (xDeviceCoreState *) buf; - - c->control = DEVICE_CORE; - c->length = sizeof(xDeviceCoreState); - c->status = dev->coreEvents; - c->iscore = (dev == inputInfo.keyboard || dev == inputInfo.pointer); - - if (client->swapped) { - swaps(&c->control, n); - swaps(&c->length, n); - swaps(&c->status, n); - } -} - -static void CopySwapDeviceEnable (ClientPtr client, DeviceIntPtr dev, char *buf) -{ - char n; - xDeviceEnableState *e = (xDeviceEnableState *) buf; - - e->control = DEVICE_ENABLE; - e->length = sizeof(xDeviceEnableState); - e->enable = dev->enabled; - - if (client->swapped) { - swaps(&e->control, n); - swaps(&e->length, n); - swaps(&e->enable, n); - } -} - -/*********************************************************************** - * - * This procedure writes the reply for the xGetDeviceControl function, - * if the client and server have a different byte ordering. - * - */ - -void -SRepXGetDeviceControl(ClientPtr client, int size, xGetDeviceControlReply * rep) -{ - char n; - - swaps(&rep->sequenceNumber, n); - swapl(&rep->length, n); - WriteToClient(client, size, (char *)rep); -} - -/*********************************************************************** - * - * Get the state of the specified device control. - * - */ - -int -ProcXGetDeviceControl(ClientPtr client) -{ - int rc, total_length = 0; - char *buf, *savbuf; - DeviceIntPtr dev; - xGetDeviceControlReply rep; - - REQUEST(xGetDeviceControlReq); - REQUEST_SIZE_MATCH(xGetDeviceControlReq); - - rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess); - if (rc != Success) - return rc; - - rep.repType = X_Reply; - rep.RepType = X_GetDeviceControl; - rep.length = 0; - rep.sequenceNumber = client->sequence; - - switch (stuff->control) { - case DEVICE_RESOLUTION: - if (!dev->valuator) - return BadMatch; - total_length = sizeof(xDeviceResolutionState) + - (3 * sizeof(int) * dev->valuator->numAxes); - break; - case DEVICE_ABS_CALIB: - if (!dev->absolute) - return BadMatch; - - total_length = sizeof(xDeviceAbsCalibState); - break; - case DEVICE_ABS_AREA: - if (!dev->absolute) - return BadMatch; - - total_length = sizeof(xDeviceAbsAreaState); - break; - case DEVICE_CORE: - total_length = sizeof(xDeviceCoreState); - break; - case DEVICE_ENABLE: - total_length = sizeof(xDeviceEnableState); - break; - default: - return BadValue; - } - - buf = (char *)xalloc(total_length); - if (!buf) - return BadAlloc; - savbuf = buf; - - switch (stuff->control) { - case DEVICE_RESOLUTION: - CopySwapDeviceResolution(client, dev->valuator, buf, total_length); - break; - case DEVICE_ABS_CALIB: - CopySwapDeviceAbsCalib(client, dev->absolute, buf); - break; - case DEVICE_ABS_AREA: - CopySwapDeviceAbsArea(client, dev->absolute, buf); - break; - case DEVICE_CORE: - CopySwapDeviceCore(client, dev, buf); - break; - case DEVICE_ENABLE: - CopySwapDeviceEnable(client, dev, buf); - break; - default: - break; - } - - rep.length = bytes_to_int32(total_length); - WriteReplyToClient(client, sizeof(xGetDeviceControlReply), &rep); - WriteToClient(client, total_length, savbuf); - xfree(savbuf); - return Success; -} +/************************************************************ + +Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. + + 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 Hewlett-Packard not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +HEWLETT-PACKARD 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. + +********************************************************/ + +/******************************************************************** + * + * Get Device control attributes for an extension device. + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "inputstr.h" /* DeviceIntPtr */ +#include +#include +#include "exglobals.h" + +#include "getdctl.h" + +/*********************************************************************** + * + * This procedure gets the control attributes for an extension device, + * for clients on machines with a different byte ordering than the server. + * + */ + +int +SProcXGetDeviceControl(ClientPtr client) +{ + char n; + + REQUEST(xGetDeviceControlReq); + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xGetDeviceControlReq); + swaps(&stuff->control, n); + return (ProcXGetDeviceControl(client)); +} + +/*********************************************************************** + * + * This procedure copies DeviceResolution data, swapping if necessary. + * + */ + +static void +CopySwapDeviceResolution(ClientPtr client, ValuatorClassPtr v, char *buf, + int length) +{ + char n; + AxisInfoPtr a; + xDeviceResolutionState *r; + int i, *iptr; + + r = (xDeviceResolutionState *) buf; + r->control = DEVICE_RESOLUTION; + r->length = length; + r->num_valuators = v->numAxes; + buf += sizeof(xDeviceResolutionState); + iptr = (int *)buf; + for (i = 0, a = v->axes; i < v->numAxes; i++, a++) + *iptr++ = a->resolution; + for (i = 0, a = v->axes; i < v->numAxes; i++, a++) + *iptr++ = a->min_resolution; + for (i = 0, a = v->axes; i < v->numAxes; i++, a++) + *iptr++ = a->max_resolution; + if (client->swapped) { + swaps(&r->control, n); + swaps(&r->length, n); + swapl(&r->num_valuators, n); + iptr = (int *)buf; + for (i = 0; i < (3 * v->numAxes); i++, iptr++) { + swapl(iptr, n); + } + } +} + +static void CopySwapDeviceAbsCalib (ClientPtr client, AbsoluteClassPtr dts, + char *buf) +{ + char n; + xDeviceAbsCalibState *calib = (xDeviceAbsCalibState *) buf; + + calib->control = DEVICE_ABS_CALIB; + calib->length = sizeof(xDeviceAbsCalibState); + calib->min_x = dts->min_x; + calib->max_x = dts->max_x; + calib->min_y = dts->min_y; + calib->max_y = dts->max_y; + calib->flip_x = dts->flip_x; + calib->flip_y = dts->flip_y; + calib->rotation = dts->rotation; + calib->button_threshold = dts->button_threshold; + + if (client->swapped) { + swaps(&calib->control, n); + swaps(&calib->length, n); + swapl(&calib->min_x, n); + swapl(&calib->max_x, n); + swapl(&calib->min_y, n); + swapl(&calib->max_y, n); + swapl(&calib->flip_x, n); + swapl(&calib->flip_y, n); + swapl(&calib->rotation, n); + swapl(&calib->button_threshold, n); + } +} + +static void CopySwapDeviceAbsArea (ClientPtr client, AbsoluteClassPtr dts, + char *buf) +{ + char n; + xDeviceAbsAreaState *area = (xDeviceAbsAreaState *) buf; + + area->control = DEVICE_ABS_AREA; + area->length = sizeof(xDeviceAbsAreaState); + area->offset_x = dts->offset_x; + area->offset_y = dts->offset_y; + area->width = dts->width; + area->height = dts->height; + area->screen = dts->screen; + area->following = dts->following; + + if (client->swapped) { + swaps(&area->control, n); + swaps(&area->length, n); + swapl(&area->offset_x, n); + swapl(&area->offset_y, n); + swapl(&area->width, n); + swapl(&area->height, n); + swapl(&area->screen, n); + swapl(&area->following, n); + } +} + +static void CopySwapDeviceCore (ClientPtr client, DeviceIntPtr dev, char *buf) +{ + char n; + xDeviceCoreState *c = (xDeviceCoreState *) buf; + + c->control = DEVICE_CORE; + c->length = sizeof(xDeviceCoreState); + c->status = dev->coreEvents; + c->iscore = (dev == inputInfo.keyboard || dev == inputInfo.pointer); + + if (client->swapped) { + swaps(&c->control, n); + swaps(&c->length, n); + swaps(&c->status, n); + } +} + +static void CopySwapDeviceEnable (ClientPtr client, DeviceIntPtr dev, char *buf) +{ + char n; + xDeviceEnableState *e = (xDeviceEnableState *) buf; + + e->control = DEVICE_ENABLE; + e->length = sizeof(xDeviceEnableState); + e->enable = dev->enabled; + + if (client->swapped) { + swaps(&e->control, n); + swaps(&e->length, n); + swaps(&e->enable, n); + } +} + +/*********************************************************************** + * + * This procedure writes the reply for the xGetDeviceControl function, + * if the client and server have a different byte ordering. + * + */ + +void +SRepXGetDeviceControl(ClientPtr client, int size, xGetDeviceControlReply * rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + WriteToClient(client, size, (char *)rep); +} + +/*********************************************************************** + * + * Get the state of the specified device control. + * + */ + +int +ProcXGetDeviceControl(ClientPtr client) +{ + int rc, total_length = 0; + char *buf, *savbuf; + DeviceIntPtr dev; + xGetDeviceControlReply rep; + + REQUEST(xGetDeviceControlReq); + REQUEST_SIZE_MATCH(xGetDeviceControlReq); + + rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + rep.repType = X_Reply; + rep.RepType = X_GetDeviceControl; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + switch (stuff->control) { + case DEVICE_RESOLUTION: + if (!dev->valuator) + return BadMatch; + total_length = sizeof(xDeviceResolutionState) + + (3 * sizeof(int) * dev->valuator->numAxes); + break; + case DEVICE_ABS_CALIB: + if (!dev->absolute) + return BadMatch; + + total_length = sizeof(xDeviceAbsCalibState); + break; + case DEVICE_ABS_AREA: + if (!dev->absolute) + return BadMatch; + + total_length = sizeof(xDeviceAbsAreaState); + break; + case DEVICE_CORE: + total_length = sizeof(xDeviceCoreState); + break; + case DEVICE_ENABLE: + total_length = sizeof(xDeviceEnableState); + break; + default: + return BadValue; + } + + buf = (char *)malloc(total_length); + if (!buf) + return BadAlloc; + savbuf = buf; + + switch (stuff->control) { + case DEVICE_RESOLUTION: + CopySwapDeviceResolution(client, dev->valuator, buf, total_length); + break; + case DEVICE_ABS_CALIB: + CopySwapDeviceAbsCalib(client, dev->absolute, buf); + break; + case DEVICE_ABS_AREA: + CopySwapDeviceAbsArea(client, dev->absolute, buf); + break; + case DEVICE_CORE: + CopySwapDeviceCore(client, dev, buf); + break; + case DEVICE_ENABLE: + CopySwapDeviceEnable(client, dev, buf); + break; + default: + break; + } + + rep.length = bytes_to_int32(total_length); + WriteReplyToClient(client, sizeof(xGetDeviceControlReply), &rep); + WriteToClient(client, total_length, savbuf); + free(savbuf); + return Success; +} diff --git a/xorg-server/Xi/getfctl.c b/xorg-server/Xi/getfctl.c index 607765e98..99b94158c 100644 --- a/xorg-server/Xi/getfctl.c +++ b/xorg-server/Xi/getfctl.c @@ -1,366 +1,366 @@ -/************************************************************ - -Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. - - 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 Hewlett-Packard not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -HEWLETT-PACKARD 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. - -********************************************************/ - -/******************************************************************** - * - * Get feedback control attributes for an extension device. - * - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "inputstr.h" /* DeviceIntPtr */ -#include -#include -#include "exglobals.h" - -#include "getfctl.h" - -/*********************************************************************** - * - * This procedure gets the control attributes for an extension device, - * for clients on machines with a different byte ordering than the server. - * - */ - -int -SProcXGetFeedbackControl(ClientPtr client) -{ - char n; - - REQUEST(xGetFeedbackControlReq); - swaps(&stuff->length, n); - return (ProcXGetFeedbackControl(client)); -} - -/*********************************************************************** - * - * This procedure copies KbdFeedbackClass data, swapping if necessary. - * - */ - -static void -CopySwapKbdFeedback(ClientPtr client, KbdFeedbackPtr k, char **buf) -{ - int i; - char n; - xKbdFeedbackState *k2; - - k2 = (xKbdFeedbackState *) * buf; - k2->class = KbdFeedbackClass; - k2->length = sizeof(xKbdFeedbackState); - k2->id = k->ctrl.id; - k2->click = k->ctrl.click; - k2->percent = k->ctrl.bell; - k2->pitch = k->ctrl.bell_pitch; - k2->duration = k->ctrl.bell_duration; - k2->led_mask = k->ctrl.leds; - k2->global_auto_repeat = k->ctrl.autoRepeat; - for (i = 0; i < 32; i++) - k2->auto_repeats[i] = k->ctrl.autoRepeats[i]; - if (client->swapped) { - swaps(&k2->length, n); - swaps(&k2->pitch, n); - swaps(&k2->duration, n); - swapl(&k2->led_mask, n); - swapl(&k2->led_values, n); - } - *buf += sizeof(xKbdFeedbackState); -} - -/*********************************************************************** - * - * This procedure copies PtrFeedbackClass data, swapping if necessary. - * - */ - -static void -CopySwapPtrFeedback(ClientPtr client, PtrFeedbackPtr p, char **buf) -{ - char n; - xPtrFeedbackState *p2; - - p2 = (xPtrFeedbackState *) * buf; - p2->class = PtrFeedbackClass; - p2->length = sizeof(xPtrFeedbackState); - p2->id = p->ctrl.id; - p2->accelNum = p->ctrl.num; - p2->accelDenom = p->ctrl.den; - p2->threshold = p->ctrl.threshold; - if (client->swapped) { - swaps(&p2->length, n); - swaps(&p2->accelNum, n); - swaps(&p2->accelDenom, n); - swaps(&p2->threshold, n); - } - *buf += sizeof(xPtrFeedbackState); -} - -/*********************************************************************** - * - * This procedure copies IntegerFeedbackClass data, swapping if necessary. - * - */ - -static void -CopySwapIntegerFeedback(ClientPtr client, IntegerFeedbackPtr i, char **buf) -{ - char n; - xIntegerFeedbackState *i2; - - i2 = (xIntegerFeedbackState *) * buf; - i2->class = IntegerFeedbackClass; - i2->length = sizeof(xIntegerFeedbackState); - i2->id = i->ctrl.id; - i2->resolution = i->ctrl.resolution; - i2->min_value = i->ctrl.min_value; - i2->max_value = i->ctrl.max_value; - if (client->swapped) { - swaps(&i2->length, n); - swapl(&i2->resolution, n); - swapl(&i2->min_value, n); - swapl(&i2->max_value, n); - } - *buf += sizeof(xIntegerFeedbackState); -} - -/*********************************************************************** - * - * This procedure copies StringFeedbackClass data, swapping if necessary. - * - */ - -static void -CopySwapStringFeedback(ClientPtr client, StringFeedbackPtr s, char **buf) -{ - int i; - char n; - xStringFeedbackState *s2; - KeySym *kptr; - - s2 = (xStringFeedbackState *) * buf; - s2->class = StringFeedbackClass; - s2->length = sizeof(xStringFeedbackState) + - s->ctrl.num_symbols_supported * sizeof(KeySym); - s2->id = s->ctrl.id; - s2->max_symbols = s->ctrl.max_symbols; - s2->num_syms_supported = s->ctrl.num_symbols_supported; - *buf += sizeof(xStringFeedbackState); - kptr = (KeySym *) (*buf); - for (i = 0; i < s->ctrl.num_symbols_supported; i++) - *kptr++ = *(s->ctrl.symbols_supported + i); - if (client->swapped) { - swaps(&s2->length, n); - swaps(&s2->max_symbols, n); - swaps(&s2->num_syms_supported, n); - kptr = (KeySym *) (*buf); - for (i = 0; i < s->ctrl.num_symbols_supported; i++, kptr++) { - swapl(kptr, n); - } - } - *buf += (s->ctrl.num_symbols_supported * sizeof(KeySym)); -} - -/*********************************************************************** - * - * This procedure copies LedFeedbackClass data, swapping if necessary. - * - */ - -static void -CopySwapLedFeedback(ClientPtr client, LedFeedbackPtr l, char **buf) -{ - char n; - xLedFeedbackState *l2; - - l2 = (xLedFeedbackState *) * buf; - l2->class = LedFeedbackClass; - l2->length = sizeof(xLedFeedbackState); - l2->id = l->ctrl.id; - l2->led_values = l->ctrl.led_values; - l2->led_mask = l->ctrl.led_mask; - if (client->swapped) { - swaps(&l2->length, n); - swapl(&l2->led_values, n); - swapl(&l2->led_mask, n); - } - *buf += sizeof(xLedFeedbackState); -} - -/*********************************************************************** - * - * This procedure copies BellFeedbackClass data, swapping if necessary. - * - */ - -static void -CopySwapBellFeedback(ClientPtr client, BellFeedbackPtr b, char **buf) -{ - char n; - xBellFeedbackState *b2; - - b2 = (xBellFeedbackState *) * buf; - b2->class = BellFeedbackClass; - b2->length = sizeof(xBellFeedbackState); - b2->id = b->ctrl.id; - b2->percent = b->ctrl.percent; - b2->pitch = b->ctrl.pitch; - b2->duration = b->ctrl.duration; - if (client->swapped) { - swaps(&b2->length, n); - swaps(&b2->pitch, n); - swaps(&b2->duration, n); - } - *buf += sizeof(xBellFeedbackState); -} - -/*********************************************************************** - * - * This procedure writes the reply for the xGetFeedbackControl function, - * if the client and server have a different byte ordering. - * - */ - -void -SRepXGetFeedbackControl(ClientPtr client, int size, - xGetFeedbackControlReply * rep) -{ - char n; - - swaps(&rep->sequenceNumber, n); - swapl(&rep->length, n); - swaps(&rep->num_feedbacks, n); - WriteToClient(client, size, (char *)rep); -} - -/*********************************************************************** - * - * Get the feedback control state. - * - */ - -int -ProcXGetFeedbackControl(ClientPtr client) -{ - int rc, total_length = 0; - char *buf, *savbuf; - DeviceIntPtr dev; - KbdFeedbackPtr k; - PtrFeedbackPtr p; - IntegerFeedbackPtr i; - StringFeedbackPtr s; - BellFeedbackPtr b; - LedFeedbackPtr l; - xGetFeedbackControlReply rep; - - REQUEST(xGetFeedbackControlReq); - REQUEST_SIZE_MATCH(xGetFeedbackControlReq); - - rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess); - if (rc != Success) - return rc; - - rep.repType = X_Reply; - rep.RepType = X_GetFeedbackControl; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.num_feedbacks = 0; - - for (k = dev->kbdfeed; k; k = k->next) { - rep.num_feedbacks++; - total_length += sizeof(xKbdFeedbackState); - } - for (p = dev->ptrfeed; p; p = p->next) { - rep.num_feedbacks++; - total_length += sizeof(xPtrFeedbackState); - } - for (s = dev->stringfeed; s; s = s->next) { - rep.num_feedbacks++; - total_length += sizeof(xStringFeedbackState) + - (s->ctrl.num_symbols_supported * sizeof(KeySym)); - } - for (i = dev->intfeed; i; i = i->next) { - rep.num_feedbacks++; - total_length += sizeof(xIntegerFeedbackState); - } - for (l = dev->leds; l; l = l->next) { - rep.num_feedbacks++; - total_length += sizeof(xLedFeedbackState); - } - for (b = dev->bell; b; b = b->next) { - rep.num_feedbacks++; - total_length += sizeof(xBellFeedbackState); - } - - if (total_length == 0) - return BadMatch; - - buf = (char *)xalloc(total_length); - if (!buf) - return BadAlloc; - savbuf = buf; - - for (k = dev->kbdfeed; k; k = k->next) - CopySwapKbdFeedback(client, k, &buf); - for (p = dev->ptrfeed; p; p = p->next) - CopySwapPtrFeedback(client, p, &buf); - for (s = dev->stringfeed; s; s = s->next) - CopySwapStringFeedback(client, s, &buf); - for (i = dev->intfeed; i; i = i->next) - CopySwapIntegerFeedback(client, i, &buf); - for (l = dev->leds; l; l = l->next) - CopySwapLedFeedback(client, l, &buf); - for (b = dev->bell; b; b = b->next) - CopySwapBellFeedback(client, b, &buf); - - rep.length = bytes_to_int32(total_length); - WriteReplyToClient(client, sizeof(xGetFeedbackControlReply), &rep); - WriteToClient(client, total_length, savbuf); - xfree(savbuf); - return Success; -} +/************************************************************ + +Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. + + 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 Hewlett-Packard not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +HEWLETT-PACKARD 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. + +********************************************************/ + +/******************************************************************** + * + * Get feedback control attributes for an extension device. + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "inputstr.h" /* DeviceIntPtr */ +#include +#include +#include "exglobals.h" + +#include "getfctl.h" + +/*********************************************************************** + * + * This procedure gets the control attributes for an extension device, + * for clients on machines with a different byte ordering than the server. + * + */ + +int +SProcXGetFeedbackControl(ClientPtr client) +{ + char n; + + REQUEST(xGetFeedbackControlReq); + swaps(&stuff->length, n); + return (ProcXGetFeedbackControl(client)); +} + +/*********************************************************************** + * + * This procedure copies KbdFeedbackClass data, swapping if necessary. + * + */ + +static void +CopySwapKbdFeedback(ClientPtr client, KbdFeedbackPtr k, char **buf) +{ + int i; + char n; + xKbdFeedbackState *k2; + + k2 = (xKbdFeedbackState *) * buf; + k2->class = KbdFeedbackClass; + k2->length = sizeof(xKbdFeedbackState); + k2->id = k->ctrl.id; + k2->click = k->ctrl.click; + k2->percent = k->ctrl.bell; + k2->pitch = k->ctrl.bell_pitch; + k2->duration = k->ctrl.bell_duration; + k2->led_mask = k->ctrl.leds; + k2->global_auto_repeat = k->ctrl.autoRepeat; + for (i = 0; i < 32; i++) + k2->auto_repeats[i] = k->ctrl.autoRepeats[i]; + if (client->swapped) { + swaps(&k2->length, n); + swaps(&k2->pitch, n); + swaps(&k2->duration, n); + swapl(&k2->led_mask, n); + swapl(&k2->led_values, n); + } + *buf += sizeof(xKbdFeedbackState); +} + +/*********************************************************************** + * + * This procedure copies PtrFeedbackClass data, swapping if necessary. + * + */ + +static void +CopySwapPtrFeedback(ClientPtr client, PtrFeedbackPtr p, char **buf) +{ + char n; + xPtrFeedbackState *p2; + + p2 = (xPtrFeedbackState *) * buf; + p2->class = PtrFeedbackClass; + p2->length = sizeof(xPtrFeedbackState); + p2->id = p->ctrl.id; + p2->accelNum = p->ctrl.num; + p2->accelDenom = p->ctrl.den; + p2->threshold = p->ctrl.threshold; + if (client->swapped) { + swaps(&p2->length, n); + swaps(&p2->accelNum, n); + swaps(&p2->accelDenom, n); + swaps(&p2->threshold, n); + } + *buf += sizeof(xPtrFeedbackState); +} + +/*********************************************************************** + * + * This procedure copies IntegerFeedbackClass data, swapping if necessary. + * + */ + +static void +CopySwapIntegerFeedback(ClientPtr client, IntegerFeedbackPtr i, char **buf) +{ + char n; + xIntegerFeedbackState *i2; + + i2 = (xIntegerFeedbackState *) * buf; + i2->class = IntegerFeedbackClass; + i2->length = sizeof(xIntegerFeedbackState); + i2->id = i->ctrl.id; + i2->resolution = i->ctrl.resolution; + i2->min_value = i->ctrl.min_value; + i2->max_value = i->ctrl.max_value; + if (client->swapped) { + swaps(&i2->length, n); + swapl(&i2->resolution, n); + swapl(&i2->min_value, n); + swapl(&i2->max_value, n); + } + *buf += sizeof(xIntegerFeedbackState); +} + +/*********************************************************************** + * + * This procedure copies StringFeedbackClass data, swapping if necessary. + * + */ + +static void +CopySwapStringFeedback(ClientPtr client, StringFeedbackPtr s, char **buf) +{ + int i; + char n; + xStringFeedbackState *s2; + KeySym *kptr; + + s2 = (xStringFeedbackState *) * buf; + s2->class = StringFeedbackClass; + s2->length = sizeof(xStringFeedbackState) + + s->ctrl.num_symbols_supported * sizeof(KeySym); + s2->id = s->ctrl.id; + s2->max_symbols = s->ctrl.max_symbols; + s2->num_syms_supported = s->ctrl.num_symbols_supported; + *buf += sizeof(xStringFeedbackState); + kptr = (KeySym *) (*buf); + for (i = 0; i < s->ctrl.num_symbols_supported; i++) + *kptr++ = *(s->ctrl.symbols_supported + i); + if (client->swapped) { + swaps(&s2->length, n); + swaps(&s2->max_symbols, n); + swaps(&s2->num_syms_supported, n); + kptr = (KeySym *) (*buf); + for (i = 0; i < s->ctrl.num_symbols_supported; i++, kptr++) { + swapl(kptr, n); + } + } + *buf += (s->ctrl.num_symbols_supported * sizeof(KeySym)); +} + +/*********************************************************************** + * + * This procedure copies LedFeedbackClass data, swapping if necessary. + * + */ + +static void +CopySwapLedFeedback(ClientPtr client, LedFeedbackPtr l, char **buf) +{ + char n; + xLedFeedbackState *l2; + + l2 = (xLedFeedbackState *) * buf; + l2->class = LedFeedbackClass; + l2->length = sizeof(xLedFeedbackState); + l2->id = l->ctrl.id; + l2->led_values = l->ctrl.led_values; + l2->led_mask = l->ctrl.led_mask; + if (client->swapped) { + swaps(&l2->length, n); + swapl(&l2->led_values, n); + swapl(&l2->led_mask, n); + } + *buf += sizeof(xLedFeedbackState); +} + +/*********************************************************************** + * + * This procedure copies BellFeedbackClass data, swapping if necessary. + * + */ + +static void +CopySwapBellFeedback(ClientPtr client, BellFeedbackPtr b, char **buf) +{ + char n; + xBellFeedbackState *b2; + + b2 = (xBellFeedbackState *) * buf; + b2->class = BellFeedbackClass; + b2->length = sizeof(xBellFeedbackState); + b2->id = b->ctrl.id; + b2->percent = b->ctrl.percent; + b2->pitch = b->ctrl.pitch; + b2->duration = b->ctrl.duration; + if (client->swapped) { + swaps(&b2->length, n); + swaps(&b2->pitch, n); + swaps(&b2->duration, n); + } + *buf += sizeof(xBellFeedbackState); +} + +/*********************************************************************** + * + * This procedure writes the reply for the xGetFeedbackControl function, + * if the client and server have a different byte ordering. + * + */ + +void +SRepXGetFeedbackControl(ClientPtr client, int size, + xGetFeedbackControlReply * rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->num_feedbacks, n); + WriteToClient(client, size, (char *)rep); +} + +/*********************************************************************** + * + * Get the feedback control state. + * + */ + +int +ProcXGetFeedbackControl(ClientPtr client) +{ + int rc, total_length = 0; + char *buf, *savbuf; + DeviceIntPtr dev; + KbdFeedbackPtr k; + PtrFeedbackPtr p; + IntegerFeedbackPtr i; + StringFeedbackPtr s; + BellFeedbackPtr b; + LedFeedbackPtr l; + xGetFeedbackControlReply rep; + + REQUEST(xGetFeedbackControlReq); + REQUEST_SIZE_MATCH(xGetFeedbackControlReq); + + rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + rep.repType = X_Reply; + rep.RepType = X_GetFeedbackControl; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.num_feedbacks = 0; + + for (k = dev->kbdfeed; k; k = k->next) { + rep.num_feedbacks++; + total_length += sizeof(xKbdFeedbackState); + } + for (p = dev->ptrfeed; p; p = p->next) { + rep.num_feedbacks++; + total_length += sizeof(xPtrFeedbackState); + } + for (s = dev->stringfeed; s; s = s->next) { + rep.num_feedbacks++; + total_length += sizeof(xStringFeedbackState) + + (s->ctrl.num_symbols_supported * sizeof(KeySym)); + } + for (i = dev->intfeed; i; i = i->next) { + rep.num_feedbacks++; + total_length += sizeof(xIntegerFeedbackState); + } + for (l = dev->leds; l; l = l->next) { + rep.num_feedbacks++; + total_length += sizeof(xLedFeedbackState); + } + for (b = dev->bell; b; b = b->next) { + rep.num_feedbacks++; + total_length += sizeof(xBellFeedbackState); + } + + if (total_length == 0) + return BadMatch; + + buf = (char *)malloc(total_length); + if (!buf) + return BadAlloc; + savbuf = buf; + + for (k = dev->kbdfeed; k; k = k->next) + CopySwapKbdFeedback(client, k, &buf); + for (p = dev->ptrfeed; p; p = p->next) + CopySwapPtrFeedback(client, p, &buf); + for (s = dev->stringfeed; s; s = s->next) + CopySwapStringFeedback(client, s, &buf); + for (i = dev->intfeed; i; i = i->next) + CopySwapIntegerFeedback(client, i, &buf); + for (l = dev->leds; l; l = l->next) + CopySwapLedFeedback(client, l, &buf); + for (b = dev->bell; b; b = b->next) + CopySwapBellFeedback(client, b, &buf); + + rep.length = bytes_to_int32(total_length); + WriteReplyToClient(client, sizeof(xGetFeedbackControlReply), &rep); + WriteToClient(client, total_length, savbuf); + free(savbuf); + return Success; +} diff --git a/xorg-server/Xi/getkmap.c b/xorg-server/Xi/getkmap.c index 78449e212..6672ed32c 100644 --- a/xorg-server/Xi/getkmap.c +++ b/xorg-server/Xi/getkmap.c @@ -1,158 +1,158 @@ -/************************************************************ - -Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. - - 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 Hewlett-Packard not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -HEWLETT-PACKARD 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. - -********************************************************/ - -/******************************************************************** - * - * Get the key mapping for an extension device. - * - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "inputstr.h" /* DeviceIntPtr */ -#include -#include -#include "exglobals.h" -#include "swaprep.h" -#include "xkbsrv.h" -#include "xkbstr.h" - -#include "getkmap.h" - -/*********************************************************************** - * - * This procedure gets the key mapping for an extension device, - * for clients on machines with a different byte ordering than the server. - * - */ - -int -SProcXGetDeviceKeyMapping(ClientPtr client) -{ - char n; - - REQUEST(xGetDeviceKeyMappingReq); - swaps(&stuff->length, n); - return (ProcXGetDeviceKeyMapping(client)); -} - -/*********************************************************************** - * - * Get the device key mapping. - * - */ - -int -ProcXGetDeviceKeyMapping(ClientPtr client) -{ - xGetDeviceKeyMappingReply rep; - DeviceIntPtr dev; - XkbDescPtr xkb; - KeySymsPtr syms; - int rc; - - REQUEST(xGetDeviceKeyMappingReq); - REQUEST_SIZE_MATCH(xGetDeviceKeyMappingReq); - - rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess); - if (rc != Success) - return rc; - if (dev->key == NULL) - return BadMatch; - xkb = dev->key->xkbInfo->desc; - - if (stuff->firstKeyCode < xkb->min_key_code || - stuff->firstKeyCode > xkb->max_key_code) { - client->errorValue = stuff->firstKeyCode; - return BadValue; - } - - if (stuff->firstKeyCode + stuff->count > xkb->max_key_code + 1) { - client->errorValue = stuff->count; - return BadValue; - } - - syms = XkbGetCoreMap(dev); - if (!syms) - return BadAlloc; - - rep.repType = X_Reply; - rep.RepType = X_GetDeviceKeyMapping; - rep.sequenceNumber = client->sequence; - rep.keySymsPerKeyCode = syms->mapWidth; - rep.length = (syms->mapWidth * stuff->count); /* KeySyms are 4 bytes */ - WriteReplyToClient(client, sizeof(xGetDeviceKeyMappingReply), &rep); - - client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write; - WriteSwappedDataToClient(client, - syms->mapWidth * stuff->count * sizeof(KeySym), - &syms->map[syms->mapWidth * (stuff->firstKeyCode - - syms->minKeyCode)]); - xfree(syms->map); - xfree(syms); - - return Success; -} - -/*********************************************************************** - * - * This procedure writes the reply for the XGetDeviceKeyMapping function, - * if the client and server have a different byte ordering. - * - */ - -void -SRepXGetDeviceKeyMapping(ClientPtr client, int size, - xGetDeviceKeyMappingReply * rep) -{ - char n; - - swaps(&rep->sequenceNumber, n); - swapl(&rep->length, n); - WriteToClient(client, size, (char *)rep); -} +/************************************************************ + +Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. + + 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 Hewlett-Packard not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +HEWLETT-PACKARD 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. + +********************************************************/ + +/******************************************************************** + * + * Get the key mapping for an extension device. + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "inputstr.h" /* DeviceIntPtr */ +#include +#include +#include "exglobals.h" +#include "swaprep.h" +#include "xkbsrv.h" +#include "xkbstr.h" + +#include "getkmap.h" + +/*********************************************************************** + * + * This procedure gets the key mapping for an extension device, + * for clients on machines with a different byte ordering than the server. + * + */ + +int +SProcXGetDeviceKeyMapping(ClientPtr client) +{ + char n; + + REQUEST(xGetDeviceKeyMappingReq); + swaps(&stuff->length, n); + return (ProcXGetDeviceKeyMapping(client)); +} + +/*********************************************************************** + * + * Get the device key mapping. + * + */ + +int +ProcXGetDeviceKeyMapping(ClientPtr client) +{ + xGetDeviceKeyMappingReply rep; + DeviceIntPtr dev; + XkbDescPtr xkb; + KeySymsPtr syms; + int rc; + + REQUEST(xGetDeviceKeyMappingReq); + REQUEST_SIZE_MATCH(xGetDeviceKeyMappingReq); + + rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess); + if (rc != Success) + return rc; + if (dev->key == NULL) + return BadMatch; + xkb = dev->key->xkbInfo->desc; + + if (stuff->firstKeyCode < xkb->min_key_code || + stuff->firstKeyCode > xkb->max_key_code) { + client->errorValue = stuff->firstKeyCode; + return BadValue; + } + + if (stuff->firstKeyCode + stuff->count > xkb->max_key_code + 1) { + client->errorValue = stuff->count; + return BadValue; + } + + syms = XkbGetCoreMap(dev); + if (!syms) + return BadAlloc; + + rep.repType = X_Reply; + rep.RepType = X_GetDeviceKeyMapping; + rep.sequenceNumber = client->sequence; + rep.keySymsPerKeyCode = syms->mapWidth; + rep.length = (syms->mapWidth * stuff->count); /* KeySyms are 4 bytes */ + WriteReplyToClient(client, sizeof(xGetDeviceKeyMappingReply), &rep); + + client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write; + WriteSwappedDataToClient(client, + syms->mapWidth * stuff->count * sizeof(KeySym), + &syms->map[syms->mapWidth * (stuff->firstKeyCode - + syms->minKeyCode)]); + free(syms->map); + free(syms); + + return Success; +} + +/*********************************************************************** + * + * This procedure writes the reply for the XGetDeviceKeyMapping function, + * if the client and server have a different byte ordering. + * + */ + +void +SRepXGetDeviceKeyMapping(ClientPtr client, int size, + xGetDeviceKeyMappingReply * rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + WriteToClient(client, size, (char *)rep); +} diff --git a/xorg-server/Xi/getmmap.c b/xorg-server/Xi/getmmap.c index ddf27a5f0..96e9643fc 100644 --- a/xorg-server/Xi/getmmap.c +++ b/xorg-server/Xi/getmmap.c @@ -1,137 +1,137 @@ -/************************************************************ - -Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. - - 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 Hewlett-Packard not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -HEWLETT-PACKARD 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. - -********************************************************/ - -/******************************************************************** - * - * Get the modifier mapping for an extension device. - * - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "inputstr.h" /* DeviceIntPtr */ -#include -#include /* Request macro */ -#include "exglobals.h" - -#include "getmmap.h" - -/*********************************************************************** - * - * This procedure gets the modifier mapping for an extension device, - * for clients on machines with a different byte ordering than the server. - * - */ - -int -SProcXGetDeviceModifierMapping(ClientPtr client) -{ - char n; - - REQUEST(xGetDeviceModifierMappingReq); - swaps(&stuff->length, n); - return (ProcXGetDeviceModifierMapping(client)); -} - -/*********************************************************************** - * - * Get the device Modifier mapping. - * - */ - -int -ProcXGetDeviceModifierMapping(ClientPtr client) -{ - DeviceIntPtr dev; - xGetDeviceModifierMappingReply rep; - KeyCode *modkeymap = NULL; - int ret, max_keys_per_mod; - - REQUEST(xGetDeviceModifierMappingReq); - REQUEST_SIZE_MATCH(xGetDeviceModifierMappingReq); - - ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess); - if (ret != Success) - return ret; - - ret = generate_modkeymap(client, dev, &modkeymap, &max_keys_per_mod); - if (ret != Success) - return ret; - - rep.repType = X_Reply; - rep.RepType = X_GetDeviceModifierMapping; - rep.numKeyPerModifier = max_keys_per_mod; - rep.sequenceNumber = client->sequence; - /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */ - rep.length = max_keys_per_mod << 1; - - WriteReplyToClient(client, sizeof(xGetDeviceModifierMappingReply), &rep); - WriteToClient(client, max_keys_per_mod * 8, (char *) modkeymap); - - xfree(modkeymap); - - return Success; -} - -/*********************************************************************** - * - * This procedure writes the reply for the XGetDeviceModifierMapping function, - * if the client and server have a different byte ordering. - * - */ - -void -SRepXGetDeviceModifierMapping(ClientPtr client, int size, - xGetDeviceModifierMappingReply * rep) -{ - char n; - - swaps(&rep->sequenceNumber, n); - swapl(&rep->length, n); - WriteToClient(client, size, (char *)rep); -} +/************************************************************ + +Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. + + 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 Hewlett-Packard not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +HEWLETT-PACKARD 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. + +********************************************************/ + +/******************************************************************** + * + * Get the modifier mapping for an extension device. + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "inputstr.h" /* DeviceIntPtr */ +#include +#include /* Request macro */ +#include "exglobals.h" + +#include "getmmap.h" + +/*********************************************************************** + * + * This procedure gets the modifier mapping for an extension device, + * for clients on machines with a different byte ordering than the server. + * + */ + +int +SProcXGetDeviceModifierMapping(ClientPtr client) +{ + char n; + + REQUEST(xGetDeviceModifierMappingReq); + swaps(&stuff->length, n); + return (ProcXGetDeviceModifierMapping(client)); +} + +/*********************************************************************** + * + * Get the device Modifier mapping. + * + */ + +int +ProcXGetDeviceModifierMapping(ClientPtr client) +{ + DeviceIntPtr dev; + xGetDeviceModifierMappingReply rep; + KeyCode *modkeymap = NULL; + int ret, max_keys_per_mod; + + REQUEST(xGetDeviceModifierMappingReq); + REQUEST_SIZE_MATCH(xGetDeviceModifierMappingReq); + + ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess); + if (ret != Success) + return ret; + + ret = generate_modkeymap(client, dev, &modkeymap, &max_keys_per_mod); + if (ret != Success) + return ret; + + rep.repType = X_Reply; + rep.RepType = X_GetDeviceModifierMapping; + rep.numKeyPerModifier = max_keys_per_mod; + rep.sequenceNumber = client->sequence; + /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */ + rep.length = max_keys_per_mod << 1; + + WriteReplyToClient(client, sizeof(xGetDeviceModifierMappingReply), &rep); + WriteToClient(client, max_keys_per_mod * 8, (char *) modkeymap); + + free(modkeymap); + + return Success; +} + +/*********************************************************************** + * + * This procedure writes the reply for the XGetDeviceModifierMapping function, + * if the client and server have a different byte ordering. + * + */ + +void +SRepXGetDeviceModifierMapping(ClientPtr client, int size, + xGetDeviceModifierMappingReply * rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + WriteToClient(client, size, (char *)rep); +} diff --git a/xorg-server/Xi/getprop.c b/xorg-server/Xi/getprop.c index 1f28a8a40..8f2d792be 100644 --- a/xorg-server/Xi/getprop.c +++ b/xorg-server/Xi/getprop.c @@ -1,187 +1,187 @@ -/************************************************************ - -Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. - - 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 Hewlett-Packard not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -HEWLETT-PACKARD 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. - -********************************************************/ - -/*********************************************************************** - * - * Function to return the dont-propagate-list for an extension device. - * - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "inputstr.h" /* DeviceIntPtr */ -#include "windowstr.h" /* window structs */ -#include -#include -#include "exglobals.h" -#include "swaprep.h" - -#include "getprop.h" - -extern XExtEventInfo EventInfo[]; -extern int ExtEventIndex; - -/*********************************************************************** - * - * Handle a request from a client with a different byte order. - * - */ - -int -SProcXGetDeviceDontPropagateList(ClientPtr client) -{ - char n; - - REQUEST(xGetDeviceDontPropagateListReq); - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xGetDeviceDontPropagateListReq); - swapl(&stuff->window, n); - return (ProcXGetDeviceDontPropagateList(client)); -} - -/*********************************************************************** - * - * This procedure lists the input devices available to the server. - * - */ - -int -ProcXGetDeviceDontPropagateList(ClientPtr client) -{ - CARD16 count = 0; - int i, rc; - XEventClass *buf = NULL, *tbuf; - WindowPtr pWin; - xGetDeviceDontPropagateListReply rep; - OtherInputMasks *others; - - REQUEST(xGetDeviceDontPropagateListReq); - REQUEST_SIZE_MATCH(xGetDeviceDontPropagateListReq); - - rep.repType = X_Reply; - rep.RepType = X_GetDeviceDontPropagateList; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.count = 0; - - rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); - if (rc != Success) - return rc; - - if ((others = wOtherInputMasks(pWin)) != 0) { - for (i = 0; i < EMASKSIZE; i++) - tbuf = ClassFromMask(NULL, others->dontPropagateMask[i], i, - &count, COUNT); - if (count) { - rep.count = count; - buf = (XEventClass *) xalloc(rep.count * sizeof(XEventClass)); - rep.length = bytes_to_int32(rep.count * sizeof(XEventClass)); - - tbuf = buf; - for (i = 0; i < EMASKSIZE; i++) - tbuf = ClassFromMask(tbuf, others->dontPropagateMask[i], i, - NULL, CREATE); - } - } - - WriteReplyToClient(client, sizeof(xGetDeviceDontPropagateListReply), &rep); - - if (count) { - client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; - WriteSwappedDataToClient(client, count * sizeof(XEventClass), buf); - xfree(buf); - } - return Success; -} - -/*********************************************************************** - * - * This procedure gets a list of event classes from a mask word. - * A single mask may translate to more than one event class. - * - */ - -XEventClass - * ClassFromMask(XEventClass * buf, Mask mask, int maskndx, CARD16 * count, - int mode) -{ - int i, j; - int id = maskndx; - Mask tmask = 0x80000000; - - for (i = 0; i < 32; i++, tmask >>= 1) - if (tmask & mask) { - for (j = 0; j < ExtEventIndex; j++) - if (EventInfo[j].mask == tmask) { - if (mode == COUNT) - (*count)++; - else - *buf++ = (id << 8) | EventInfo[j].type; - } - } - return (buf); -} - -/*********************************************************************** - * - * This procedure writes the reply for the XGetDeviceDontPropagateList function, - * if the client and server have a different byte ordering. - * - */ - -void -SRepXGetDeviceDontPropagateList(ClientPtr client, int size, - xGetDeviceDontPropagateListReply * rep) -{ - char n; - - swaps(&rep->sequenceNumber, n); - swapl(&rep->length, n); - swaps(&rep->count, n); - WriteToClient(client, size, (char *)rep); -} +/************************************************************ + +Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. + + 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 Hewlett-Packard not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +HEWLETT-PACKARD 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. + +********************************************************/ + +/*********************************************************************** + * + * Function to return the dont-propagate-list for an extension device. + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structs */ +#include +#include +#include "exglobals.h" +#include "swaprep.h" + +#include "getprop.h" + +extern XExtEventInfo EventInfo[]; +extern int ExtEventIndex; + +/*********************************************************************** + * + * Handle a request from a client with a different byte order. + * + */ + +int +SProcXGetDeviceDontPropagateList(ClientPtr client) +{ + char n; + + REQUEST(xGetDeviceDontPropagateListReq); + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xGetDeviceDontPropagateListReq); + swapl(&stuff->window, n); + return (ProcXGetDeviceDontPropagateList(client)); +} + +/*********************************************************************** + * + * This procedure lists the input devices available to the server. + * + */ + +int +ProcXGetDeviceDontPropagateList(ClientPtr client) +{ + CARD16 count = 0; + int i, rc; + XEventClass *buf = NULL, *tbuf; + WindowPtr pWin; + xGetDeviceDontPropagateListReply rep; + OtherInputMasks *others; + + REQUEST(xGetDeviceDontPropagateListReq); + REQUEST_SIZE_MATCH(xGetDeviceDontPropagateListReq); + + rep.repType = X_Reply; + rep.RepType = X_GetDeviceDontPropagateList; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.count = 0; + + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + if ((others = wOtherInputMasks(pWin)) != 0) { + for (i = 0; i < EMASKSIZE; i++) + tbuf = ClassFromMask(NULL, others->dontPropagateMask[i], i, + &count, COUNT); + if (count) { + rep.count = count; + buf = (XEventClass *) malloc(rep.count * sizeof(XEventClass)); + rep.length = bytes_to_int32(rep.count * sizeof(XEventClass)); + + tbuf = buf; + for (i = 0; i < EMASKSIZE; i++) + tbuf = ClassFromMask(tbuf, others->dontPropagateMask[i], i, + NULL, CREATE); + } + } + + WriteReplyToClient(client, sizeof(xGetDeviceDontPropagateListReply), &rep); + + if (count) { + client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; + WriteSwappedDataToClient(client, count * sizeof(XEventClass), buf); + free(buf); + } + return Success; +} + +/*********************************************************************** + * + * This procedure gets a list of event classes from a mask word. + * A single mask may translate to more than one event class. + * + */ + +XEventClass + * ClassFromMask(XEventClass * buf, Mask mask, int maskndx, CARD16 * count, + int mode) +{ + int i, j; + int id = maskndx; + Mask tmask = 0x80000000; + + for (i = 0; i < 32; i++, tmask >>= 1) + if (tmask & mask) { + for (j = 0; j < ExtEventIndex; j++) + if (EventInfo[j].mask == tmask) { + if (mode == COUNT) + (*count)++; + else + *buf++ = (id << 8) | EventInfo[j].type; + } + } + return (buf); +} + +/*********************************************************************** + * + * This procedure writes the reply for the XGetDeviceDontPropagateList function, + * if the client and server have a different byte ordering. + * + */ + +void +SRepXGetDeviceDontPropagateList(ClientPtr client, int size, + xGetDeviceDontPropagateListReply * rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->count, n); + WriteToClient(client, size, (char *)rep); +} diff --git a/xorg-server/Xi/getselev.c b/xorg-server/Xi/getselev.c index 90f6284e5..3b556000c 100644 --- a/xorg-server/Xi/getselev.c +++ b/xorg-server/Xi/getselev.c @@ -1,178 +1,178 @@ -/************************************************************ - -Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. - - 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 Hewlett-Packard not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -HEWLETT-PACKARD 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. - -********************************************************/ - -/*********************************************************************** - * - * Extension function to get the current selected events for a given window. - * - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include -#include -#include "inputstr.h" /* DeviceIntPtr */ -#include "windowstr.h" /* window struct */ -#include "exglobals.h" -#include "swaprep.h" - -#include "getprop.h" -#include "getselev.h" - -/*********************************************************************** - * - * This procedure gets the current selected extension events. - * - */ - -int -SProcXGetSelectedExtensionEvents(ClientPtr client) -{ - char n; - - REQUEST(xGetSelectedExtensionEventsReq); - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xGetSelectedExtensionEventsReq); - swapl(&stuff->window, n); - return (ProcXGetSelectedExtensionEvents(client)); -} - -/*********************************************************************** - * - * This procedure gets the current device select mask, - * if the client and server have a different byte ordering. - * - */ - -int -ProcXGetSelectedExtensionEvents(ClientPtr client) -{ - int i, rc, total_length = 0; - xGetSelectedExtensionEventsReply rep; - WindowPtr pWin; - XEventClass *buf = NULL; - XEventClass *tclient; - XEventClass *aclient; - OtherInputMasks *pOthers; - InputClientsPtr others; - - REQUEST(xGetSelectedExtensionEventsReq); - REQUEST_SIZE_MATCH(xGetSelectedExtensionEventsReq); - - rep.repType = X_Reply; - rep.RepType = X_GetSelectedExtensionEvents; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.this_client_count = 0; - rep.all_clients_count = 0; - - rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); - if (rc != Success) - return rc; - - if ((pOthers = wOtherInputMasks(pWin)) != 0) { - for (others = pOthers->inputClients; others; others = others->next) - for (i = 0; i < EMASKSIZE; i++) - tclient = ClassFromMask(NULL, others->mask[i], i, - &rep.all_clients_count, COUNT); - - for (others = pOthers->inputClients; others; others = others->next) - if (SameClient(others, client)) { - for (i = 0; i < EMASKSIZE; i++) - tclient = ClassFromMask(NULL, others->mask[i], i, - &rep.this_client_count, COUNT); - break; - } - - total_length = (rep.all_clients_count + rep.this_client_count) * - sizeof(XEventClass); - rep.length = bytes_to_int32(total_length); - buf = (XEventClass *) xalloc(total_length); - - tclient = buf; - aclient = buf + rep.this_client_count; - if (others) - for (i = 0; i < EMASKSIZE; i++) - tclient = - ClassFromMask(tclient, others->mask[i], i, NULL, CREATE); - - for (others = pOthers->inputClients; others; others = others->next) - for (i = 0; i < EMASKSIZE; i++) - aclient = - ClassFromMask(aclient, others->mask[i], i, NULL, CREATE); - } - - WriteReplyToClient(client, sizeof(xGetSelectedExtensionEventsReply), &rep); - - if (total_length) { - client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; - WriteSwappedDataToClient(client, total_length, buf); - xfree(buf); - } - return Success; -} - -/*********************************************************************** - * - * This procedure writes the reply for the XGetSelectedExtensionEvents function, - * if the client and server have a different byte ordering. - * - */ - -void -SRepXGetSelectedExtensionEvents(ClientPtr client, int size, - xGetSelectedExtensionEventsReply * rep) -{ - char n; - - swaps(&rep->sequenceNumber, n); - swapl(&rep->length, n); - swaps(&rep->this_client_count, n); - swaps(&rep->all_clients_count, n); - WriteToClient(client, size, (char *)rep); -} +/************************************************************ + +Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. + + 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 Hewlett-Packard not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +HEWLETT-PACKARD 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. + +********************************************************/ + +/*********************************************************************** + * + * Extension function to get the current selected events for a given window. + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include +#include +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window struct */ +#include "exglobals.h" +#include "swaprep.h" + +#include "getprop.h" +#include "getselev.h" + +/*********************************************************************** + * + * This procedure gets the current selected extension events. + * + */ + +int +SProcXGetSelectedExtensionEvents(ClientPtr client) +{ + char n; + + REQUEST(xGetSelectedExtensionEventsReq); + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xGetSelectedExtensionEventsReq); + swapl(&stuff->window, n); + return (ProcXGetSelectedExtensionEvents(client)); +} + +/*********************************************************************** + * + * This procedure gets the current device select mask, + * if the client and server have a different byte ordering. + * + */ + +int +ProcXGetSelectedExtensionEvents(ClientPtr client) +{ + int i, rc, total_length = 0; + xGetSelectedExtensionEventsReply rep; + WindowPtr pWin; + XEventClass *buf = NULL; + XEventClass *tclient; + XEventClass *aclient; + OtherInputMasks *pOthers; + InputClientsPtr others; + + REQUEST(xGetSelectedExtensionEventsReq); + REQUEST_SIZE_MATCH(xGetSelectedExtensionEventsReq); + + rep.repType = X_Reply; + rep.RepType = X_GetSelectedExtensionEvents; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.this_client_count = 0; + rep.all_clients_count = 0; + + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + if ((pOthers = wOtherInputMasks(pWin)) != 0) { + for (others = pOthers->inputClients; others; others = others->next) + for (i = 0; i < EMASKSIZE; i++) + tclient = ClassFromMask(NULL, others->mask[i], i, + &rep.all_clients_count, COUNT); + + for (others = pOthers->inputClients; others; others = others->next) + if (SameClient(others, client)) { + for (i = 0; i < EMASKSIZE; i++) + tclient = ClassFromMask(NULL, others->mask[i], i, + &rep.this_client_count, COUNT); + break; + } + + total_length = (rep.all_clients_count + rep.this_client_count) * + sizeof(XEventClass); + rep.length = bytes_to_int32(total_length); + buf = (XEventClass *) malloc(total_length); + + tclient = buf; + aclient = buf + rep.this_client_count; + if (others) + for (i = 0; i < EMASKSIZE; i++) + tclient = + ClassFromMask(tclient, others->mask[i], i, NULL, CREATE); + + for (others = pOthers->inputClients; others; others = others->next) + for (i = 0; i < EMASKSIZE; i++) + aclient = + ClassFromMask(aclient, others->mask[i], i, NULL, CREATE); + } + + WriteReplyToClient(client, sizeof(xGetSelectedExtensionEventsReply), &rep); + + if (total_length) { + client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; + WriteSwappedDataToClient(client, total_length, buf); + free(buf); + } + return Success; +} + +/*********************************************************************** + * + * This procedure writes the reply for the XGetSelectedExtensionEvents function, + * if the client and server have a different byte ordering. + * + */ + +void +SRepXGetSelectedExtensionEvents(ClientPtr client, int size, + xGetSelectedExtensionEventsReply * rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->this_client_count, n); + swaps(&rep->all_clients_count, n); + WriteToClient(client, size, (char *)rep); +} diff --git a/xorg-server/Xi/gtmotion.c b/xorg-server/Xi/gtmotion.c index 8e91c5a47..930e08c8c 100644 --- a/xorg-server/Xi/gtmotion.c +++ b/xorg-server/Xi/gtmotion.c @@ -1,178 +1,178 @@ -/************************************************************ - -Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. - - 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 Hewlett-Packard not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -HEWLETT-PACKARD 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. - -********************************************************/ - -/*********************************************************************** - * - * Request to get the motion history from an extension device. - * - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "inputstr.h" /* DeviceIntPtr */ -#include -#include -#include "exevents.h" -#include "exglobals.h" - -#include "gtmotion.h" - -/*********************************************************************** - * - * Swap the request if server and client have different byte ordering. - * - */ - -int -SProcXGetDeviceMotionEvents(ClientPtr client) -{ - char n; - - REQUEST(xGetDeviceMotionEventsReq); - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xGetDeviceMotionEventsReq); - swapl(&stuff->start, n); - swapl(&stuff->stop, n); - return (ProcXGetDeviceMotionEvents(client)); -} - -/**************************************************************************** - * - * Get the motion history for an extension pointer devices. - * - */ - -int -ProcXGetDeviceMotionEvents(ClientPtr client) -{ - INT32 *coords = NULL, *bufptr; - xGetDeviceMotionEventsReply rep; - unsigned long i; - int rc, num_events, axes, size = 0; - unsigned long nEvents; - DeviceIntPtr dev; - TimeStamp start, stop; - int length = 0; - ValuatorClassPtr v; - - REQUEST(xGetDeviceMotionEventsReq); - - REQUEST_SIZE_MATCH(xGetDeviceMotionEventsReq); - rc = dixLookupDevice(&dev, stuff->deviceid, client, DixReadAccess); - if (rc != Success) - return rc; - v = dev->valuator; - if (v == NULL || v->numAxes == 0) - return BadMatch; - if (dev->valuator->motionHintWindow) - MaybeStopDeviceHint(dev, client); - axes = v->numAxes; - rep.repType = X_Reply; - rep.RepType = X_GetDeviceMotionEvents; - rep.sequenceNumber = client->sequence; - rep.nEvents = 0; - rep.axes = axes; - rep.mode = Absolute; /* XXX we don't do relative at the moment */ - rep.length = 0; - start = ClientTimeToServerTime(stuff->start); - stop = ClientTimeToServerTime(stuff->stop); - if (CompareTimeStamps(start, stop) == LATER || - CompareTimeStamps(start, currentTime) == LATER) { - WriteReplyToClient(client, sizeof(xGetDeviceMotionEventsReply), &rep); - return Success; - } - if (CompareTimeStamps(stop, currentTime) == LATER) - stop = currentTime; - num_events = v->numMotionEvents; - if (num_events) { - size = sizeof(Time) + (axes * sizeof(INT32)); - rep.nEvents = GetMotionHistory(dev, (xTimecoord **) &coords,/* XXX */ - start.milliseconds, stop.milliseconds, - (ScreenPtr) NULL, FALSE); - } - if (rep.nEvents > 0) { - length = bytes_to_int32(rep.nEvents * size); - rep.length = length; - } - nEvents = rep.nEvents; - WriteReplyToClient(client, sizeof(xGetDeviceMotionEventsReply), &rep); - if (nEvents) { - if (client->swapped) { - char n; - - bufptr = coords; - for (i = 0; i < nEvents * (axes + 1); i++) { - swapl(bufptr, n); - bufptr++; - } - } - WriteToClient(client, length * 4, (char *)coords); - } - if (coords) - xfree(coords); - return Success; -} - -/*********************************************************************** - * - * This procedure writes the reply for the XGetDeviceMotionEvents function, - * if the client and server have a different byte ordering. - * - */ - -void -SRepXGetDeviceMotionEvents(ClientPtr client, int size, - xGetDeviceMotionEventsReply * rep) -{ - char n; - - swaps(&rep->sequenceNumber, n); - swapl(&rep->length, n); - swapl(&rep->nEvents, n); - WriteToClient(client, size, (char *)rep); -} +/************************************************************ + +Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. + + 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 Hewlett-Packard not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +HEWLETT-PACKARD 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. + +********************************************************/ + +/*********************************************************************** + * + * Request to get the motion history from an extension device. + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "inputstr.h" /* DeviceIntPtr */ +#include +#include +#include "exevents.h" +#include "exglobals.h" + +#include "gtmotion.h" + +/*********************************************************************** + * + * Swap the request if server and client have different byte ordering. + * + */ + +int +SProcXGetDeviceMotionEvents(ClientPtr client) +{ + char n; + + REQUEST(xGetDeviceMotionEventsReq); + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xGetDeviceMotionEventsReq); + swapl(&stuff->start, n); + swapl(&stuff->stop, n); + return (ProcXGetDeviceMotionEvents(client)); +} + +/**************************************************************************** + * + * Get the motion history for an extension pointer devices. + * + */ + +int +ProcXGetDeviceMotionEvents(ClientPtr client) +{ + INT32 *coords = NULL, *bufptr; + xGetDeviceMotionEventsReply rep; + unsigned long i; + int rc, num_events, axes, size = 0; + unsigned long nEvents; + DeviceIntPtr dev; + TimeStamp start, stop; + int length = 0; + ValuatorClassPtr v; + + REQUEST(xGetDeviceMotionEventsReq); + + REQUEST_SIZE_MATCH(xGetDeviceMotionEventsReq); + rc = dixLookupDevice(&dev, stuff->deviceid, client, DixReadAccess); + if (rc != Success) + return rc; + v = dev->valuator; + if (v == NULL || v->numAxes == 0) + return BadMatch; + if (dev->valuator->motionHintWindow) + MaybeStopDeviceHint(dev, client); + axes = v->numAxes; + rep.repType = X_Reply; + rep.RepType = X_GetDeviceMotionEvents; + rep.sequenceNumber = client->sequence; + rep.nEvents = 0; + rep.axes = axes; + rep.mode = Absolute; /* XXX we don't do relative at the moment */ + rep.length = 0; + start = ClientTimeToServerTime(stuff->start); + stop = ClientTimeToServerTime(stuff->stop); + if (CompareTimeStamps(start, stop) == LATER || + CompareTimeStamps(start, currentTime) == LATER) { + WriteReplyToClient(client, sizeof(xGetDeviceMotionEventsReply), &rep); + return Success; + } + if (CompareTimeStamps(stop, currentTime) == LATER) + stop = currentTime; + num_events = v->numMotionEvents; + if (num_events) { + size = sizeof(Time) + (axes * sizeof(INT32)); + rep.nEvents = GetMotionHistory(dev, (xTimecoord **) &coords,/* XXX */ + start.milliseconds, stop.milliseconds, + (ScreenPtr) NULL, FALSE); + } + if (rep.nEvents > 0) { + length = bytes_to_int32(rep.nEvents * size); + rep.length = length; + } + nEvents = rep.nEvents; + WriteReplyToClient(client, sizeof(xGetDeviceMotionEventsReply), &rep); + if (nEvents) { + if (client->swapped) { + char n; + + bufptr = coords; + for (i = 0; i < nEvents * (axes + 1); i++) { + swapl(bufptr, n); + bufptr++; + } + } + WriteToClient(client, length * 4, (char *)coords); + } + if (coords) + free(coords); + return Success; +} + +/*********************************************************************** + * + * This procedure writes the reply for the XGetDeviceMotionEvents function, + * if the client and server have a different byte ordering. + * + */ + +void +SRepXGetDeviceMotionEvents(ClientPtr client, int size, + xGetDeviceMotionEventsReply * rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swapl(&rep->nEvents, n); + WriteToClient(client, size, (char *)rep); +} diff --git a/xorg-server/Xi/listdev.c b/xorg-server/Xi/listdev.c index 98ef7aa43..2015f9cdd 100644 --- a/xorg-server/Xi/listdev.c +++ b/xorg-server/Xi/listdev.c @@ -1,434 +1,434 @@ -/************************************************************ - -Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. - - 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 Hewlett-Packard not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -HEWLETT-PACKARD 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. - -********************************************************/ - -/*********************************************************************** - * - * Extension function to list the available input devices. - * - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include /* for inputstr.h */ -#include /* Request macro */ -#include "inputstr.h" /* DeviceIntPtr */ -#include -#include -#include "XIstubs.h" -#include "extnsionst.h" -#include "exevents.h" -#include "xace.h" -#include "xkbsrv.h" -#include "xkbstr.h" - -#include "listdev.h" - - -/*********************************************************************** - * - * This procedure lists the input devices available to the server. - * - */ - -int -SProcXListInputDevices(ClientPtr client) -{ - char n; - - REQUEST(xListInputDevicesReq); - swaps(&stuff->length, n); - return (ProcXListInputDevices(client)); -} - -/*********************************************************************** - * - * This procedure calculates the size of the information to be returned - * for an input device. - * - */ - -static void -SizeDeviceInfo(DeviceIntPtr d, int *namesize, int *size) -{ - int chunks; - - *namesize += 1; - if (d->name) - *namesize += strlen(d->name); - if (d->key != NULL) - *size += sizeof(xKeyInfo); - if (d->button != NULL) - *size += sizeof(xButtonInfo); - if (d->valuator != NULL) { - chunks = ((int)d->valuator->numAxes + 19) / VPC; - *size += (chunks * sizeof(xValuatorInfo) + - d->valuator->numAxes * sizeof(xAxisInfo)); - } -} - -/*********************************************************************** - * - * This procedure copies data to the DeviceInfo struct, swapping if necessary. - * - * We need the extra byte in the allocated buffer, because the trailing null - * hammers one extra byte, which is overwritten by the next name except for - * the last name copied. - * - */ - -static void -CopyDeviceName(char **namebuf, char *name) -{ - char *nameptr = (char *)*namebuf; - - if (name) { - *nameptr++ = strlen(name); - strcpy(nameptr, name); - *namebuf += (strlen(name) + 1); - } else { - *nameptr++ = 0; - *namebuf += 1; - } -} - -/*********************************************************************** - * - * This procedure copies ButtonClass information, swapping if necessary. - * - */ - -static void -CopySwapButtonClass(ClientPtr client, ButtonClassPtr b, char **buf) -{ - char n; - xButtonInfoPtr b2; - - b2 = (xButtonInfoPtr) * buf; - b2->class = ButtonClass; - b2->length = sizeof(xButtonInfo); - b2->num_buttons = b->numButtons; - if (client && client->swapped) { - swaps(&b2->num_buttons, n); /* macro - braces are required */ - } - *buf += sizeof(xButtonInfo); -} - -/*********************************************************************** - * - * This procedure copies data to the DeviceInfo struct, swapping if necessary. - * - */ - -static void -CopySwapDevice(ClientPtr client, DeviceIntPtr d, int num_classes, - char **buf) -{ - char n; - xDeviceInfoPtr dev; - - dev = (xDeviceInfoPtr) * buf; - - dev->id = d->id; - dev->type = d->xinput_type; - dev->num_classes = num_classes; - if (IsMaster(d) && IsKeyboardDevice(d)) - dev->use = IsXKeyboard; - else if (IsMaster(d) && IsPointerDevice(d)) - dev->use = IsXPointer; - else if (d->key && d->kbdfeed) - dev->use = IsXExtensionKeyboard; - else if (d->valuator && d->button) - dev->use = IsXExtensionPointer; - else - dev->use = IsXExtensionDevice; - - if (client->swapped) { - swapl(&dev->type, n); /* macro - braces are required */ - } - *buf += sizeof(xDeviceInfo); -} - -/*********************************************************************** - * - * This procedure copies KeyClass information, swapping if necessary. - * - */ - -static void -CopySwapKeyClass(ClientPtr client, KeyClassPtr k, char **buf) -{ - char n; - xKeyInfoPtr k2; - - k2 = (xKeyInfoPtr) * buf; - k2->class = KeyClass; - k2->length = sizeof(xKeyInfo); - k2->min_keycode = k->xkbInfo->desc->min_key_code; - k2->max_keycode = k->xkbInfo->desc->max_key_code; - k2->num_keys = k2->max_keycode - k2->min_keycode + 1; - if (client && client->swapped) { - swaps(&k2->num_keys, n); - } - *buf += sizeof(xKeyInfo); -} - -/*********************************************************************** - * - * This procedure copies ValuatorClass information, swapping if necessary. - * - * Devices may have up to 255 valuators. The length of a ValuatorClass is - * defined to be sizeof(ValuatorClassInfo) + num_axes * sizeof (xAxisInfo). - * The maximum length is therefore (8 + 255 * 12) = 3068. However, the - * length field is one byte. If a device has more than 20 valuators, we - * must therefore return multiple valuator classes to the client. - * - */ - -static int -CopySwapValuatorClass(ClientPtr client, ValuatorClassPtr v, char **buf) -{ - int i, j, axes, t_axes; - char n; - xValuatorInfoPtr v2; - AxisInfo *a; - xAxisInfoPtr a2; - - for (i = 0, axes = v->numAxes; i < ((v->numAxes + 19) / VPC); - i++, axes -= VPC) { - t_axes = axes < VPC ? axes : VPC; - if (t_axes < 0) - t_axes = v->numAxes % VPC; - v2 = (xValuatorInfoPtr) * buf; - v2->class = ValuatorClass; - v2->length = sizeof(xValuatorInfo) + t_axes * sizeof(xAxisInfo); - v2->num_axes = t_axes; - v2->mode = v->mode & DeviceMode; - v2->motion_buffer_size = v->numMotionEvents; - if (client && client->swapped) { - swapl(&v2->motion_buffer_size, n); - } - *buf += sizeof(xValuatorInfo); - a = v->axes + (VPC * i); - a2 = (xAxisInfoPtr) * buf; - for (j = 0; j < t_axes; j++) { - a2->min_value = a->min_value; - a2->max_value = a->max_value; - a2->resolution = a->resolution; - if (client && client->swapped) { - swapl(&a2->min_value, n); - swapl(&a2->max_value, n); - swapl(&a2->resolution, n); - } - a2++; - a++; - *buf += sizeof(xAxisInfo); - } - } - return (i); -} - -static void -CopySwapClasses(ClientPtr client, DeviceIntPtr dev, CARD8 *num_classes, - char** classbuf) -{ - if (dev->key != NULL) { - CopySwapKeyClass(client, dev->key, classbuf); - (*num_classes)++; - } - if (dev->button != NULL) { - CopySwapButtonClass(client, dev->button, classbuf); - (*num_classes)++; - } - if (dev->valuator != NULL) { - (*num_classes) += - CopySwapValuatorClass(client, dev->valuator, classbuf); - } -} - -/*********************************************************************** - * - * This procedure lists information to be returned for an input device. - * - */ - -static void -ListDeviceInfo(ClientPtr client, DeviceIntPtr d, xDeviceInfoPtr dev, - char **devbuf, char **classbuf, char **namebuf) -{ - CopyDeviceName(namebuf, d->name); - CopySwapDevice(client, d, 0, devbuf); - CopySwapClasses(client, d, &dev->num_classes, classbuf); -} - -/*********************************************************************** - * - * This procedure checks if a device should be left off the list. - * - */ - -static Bool -ShouldSkipDevice(ClientPtr client, DeviceIntPtr d) -{ - /* don't send master devices other than VCP/VCK */ - if (!IsMaster(d) || d == inputInfo.pointer || d == inputInfo.keyboard) - { - int rc = XaceHook(XACE_DEVICE_ACCESS, client, d, DixGetAttrAccess); - if (rc == Success) - return FALSE; - } - return TRUE; -} - - -/*********************************************************************** - * - * This procedure lists the input devices available to the server. - * - * If this request is called by a client that has not issued a - * GetExtensionVersion request with major/minor version set, we don't send the - * complete device list. Instead, we only send the VCP, the VCK and floating - * SDs. This resembles the setup found on XI 1.x machines. - */ - -int -ProcXListInputDevices(ClientPtr client) -{ - xListInputDevicesReply rep; - int numdevs = 0; - int namesize = 1; /* need 1 extra byte for strcpy */ - int i = 0, size = 0; - int total_length; - char *devbuf, *classbuf, *namebuf, *savbuf; - Bool *skip; - xDeviceInfo *dev; - DeviceIntPtr d; - - REQUEST_SIZE_MATCH(xListInputDevicesReq); - - memset(&rep, 0, sizeof(xListInputDevicesReply)); - rep.repType = X_Reply; - rep.RepType = X_ListInputDevices; - rep.length = 0; - rep.sequenceNumber = client->sequence; - - - AddOtherInputDevices(); - - /* allocate space for saving skip value */ - skip = xcalloc(sizeof(Bool), inputInfo.numDevices); - if (!skip) - return BadAlloc; - - /* figure out which devices to skip */ - numdevs = 0; - for (d = inputInfo.devices; d; d = d->next, i++) { - skip[i] = ShouldSkipDevice(client, d); - if (skip[i]) - continue; - - SizeDeviceInfo(d, &namesize, &size); - numdevs++; - } - - for (d = inputInfo.off_devices; d; d = d->next, i++) { - skip[i] = ShouldSkipDevice(client, d); - if (skip[i]) - continue; - - SizeDeviceInfo(d, &namesize, &size); - numdevs++; - } - - /* allocate space for reply */ - total_length = numdevs * sizeof(xDeviceInfo) + size + namesize; - devbuf = (char *)xcalloc(1, total_length); - classbuf = devbuf + (numdevs * sizeof(xDeviceInfo)); - namebuf = classbuf + size; - savbuf = devbuf; - - /* fill in and send reply */ - i = 0; - dev = (xDeviceInfoPtr) devbuf; - for (d = inputInfo.devices; d; d = d->next, i++) { - if (skip[i]) - continue; - - ListDeviceInfo(client, d, dev++, &devbuf, &classbuf, &namebuf); - } - - for (d = inputInfo.off_devices; d; d = d->next, i++) { - if (skip[i]) - continue; - - ListDeviceInfo(client, d, dev++, &devbuf, &classbuf, &namebuf); - } - rep.ndevices = numdevs; - rep.length = bytes_to_int32(total_length); - WriteReplyToClient(client, sizeof(xListInputDevicesReply), &rep); - WriteToClient(client, total_length, savbuf); - xfree(savbuf); - xfree(skip); - return Success; -} - -/*********************************************************************** - * - * This procedure writes the reply for the XListInputDevices function, - * if the client and server have a different byte ordering. - * - */ - -void -SRepXListInputDevices(ClientPtr client, int size, xListInputDevicesReply * rep) -{ - char n; - - swaps(&rep->sequenceNumber, n); - swapl(&rep->length, n); - WriteToClient(client, size, (char *)rep); -} +/************************************************************ + +Copyright 1989, 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 1989 by Hewlett-Packard Company, Palo Alto, California. + + 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 Hewlett-Packard not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +HEWLETT-PACKARD 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. + +********************************************************/ + +/*********************************************************************** + * + * Extension function to list the available input devices. + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include /* for inputstr.h */ +#include /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include +#include +#include "XIstubs.h" +#include "extnsionst.h" +#include "exevents.h" +#include "xace.h" +#include "xkbsrv.h" +#include "xkbstr.h" + +#include "listdev.h" + + +/*********************************************************************** + * + * This procedure lists the input devices available to the server. + * + */ + +int +SProcXListInputDevices(ClientPtr client) +{ + char n; + + REQUEST(xListInputDevicesReq); + swaps(&stuff->length, n); + return (ProcXListInputDevices(client)); +} + +/*********************************************************************** + * + * This procedure calculates the size of the information to be returned + * for an input device. + * + */ + +static void +SizeDeviceInfo(DeviceIntPtr d, int *namesize, int *size) +{ + int chunks; + + *namesize += 1; + if (d->name) + *namesize += strlen(d->name); + if (d->key != NULL) + *size += sizeof(xKeyInfo); + if (d->button != NULL) + *size += sizeof(xButtonInfo); + if (d->valuator != NULL) { + chunks = ((int)d->valuator->numAxes + 19) / VPC; + *size += (chunks * sizeof(xValuatorInfo) + + d->valuator->numAxes * sizeof(xAxisInfo)); + } +} + +/*********************************************************************** + * + * This procedure copies data to the DeviceInfo struct, swapping if necessary. + * + * We need the extra byte in the allocated buffer, because the trailing null + * hammers one extra byte, which is overwritten by the next name except for + * the last name copied. + * + */ + +static void +CopyDeviceName(char **namebuf, char *name) +{ + char *nameptr = (char *)*namebuf; + + if (name) { + *nameptr++ = strlen(name); + strcpy(nameptr, name); + *namebuf += (strlen(name) + 1); + } else { + *nameptr++ = 0; + *namebuf += 1; + } +} + +/*********************************************************************** + * + * This procedure copies ButtonClass information, swapping if necessary. + * + */ + +static void +CopySwapButtonClass(ClientPtr client, ButtonClassPtr b, char **buf) +{ + char n; + xButtonInfoPtr b2; + + b2 = (xButtonInfoPtr) * buf; + b2->class = ButtonClass; + b2->length = sizeof(xButtonInfo); + b2->num_buttons = b->numButtons; + if (client && client->swapped) { + swaps(&b2->num_buttons, n); /* macro - braces are required */ + } + *buf += sizeof(xButtonInfo); +} + +/*********************************************************************** + * + * This procedure copies data to the DeviceInfo struct, swapping if necessary. + * + */ + +static void +CopySwapDevice(ClientPtr client, DeviceIntPtr d, int num_classes, + char **buf) +{ + char n; + xDeviceInfoPtr dev; + + dev = (xDeviceInfoPtr) * buf; + + dev->id = d->id; + dev->type = d->xinput_type; + dev->num_classes = num_classes; + if (IsMaster(d) && IsKeyboardDevice(d)) + dev->use = IsXKeyboard; + else if (IsMaster(d) && IsPointerDevice(d)) + dev->use = IsXPointer; + else if (d->key && d->kbdfeed) + dev->use = IsXExtensionKeyboard; + else if (d->valuator && d->button) + dev->use = IsXExtensionPointer; + else + dev->use = IsXExtensionDevice; + + if (client->swapped) { + swapl(&dev->type, n); /* macro - braces are required */ + } + *buf += sizeof(xDeviceInfo); +} + +/*********************************************************************** + * + * This procedure copies KeyClass information, swapping if necessary. + * + */ + +static void +CopySwapKeyClass(ClientPtr client, KeyClassPtr k, char **buf) +{ + char n; + xKeyInfoPtr k2; + + k2 = (xKeyInfoPtr) * buf; + k2->class = KeyClass; + k2->length = sizeof(xKeyInfo); + k2->min_keycode = k->xkbInfo->desc->min_key_code; + k2->max_keycode = k->xkbInfo->desc->max_key_code; + k2->num_keys = k2->max_keycode - k2->min_keycode + 1; + if (client && client->swapped) { + swaps(&k2->num_keys, n); + } + *buf += sizeof(xKeyInfo); +} + +/*********************************************************************** + * + * This procedure copies ValuatorClass information, swapping if necessary. + * + * Devices may have up to 255 valuators. The length of a ValuatorClass is + * defined to be sizeof(ValuatorClassInfo) + num_axes * sizeof (xAxisInfo). + * The maximum length is therefore (8 + 255 * 12) = 3068. However, the + * length field is one byte. If a device has more than 20 valuators, we + * must therefore return multiple valuator classes to the client. + * + */ + +static int +CopySwapValuatorClass(ClientPtr client, ValuatorClassPtr v, char **buf) +{ + int i, j, axes, t_axes; + char n; + xValuatorInfoPtr v2; + AxisInfo *a; + xAxisInfoPtr a2; + + for (i = 0, axes = v->numAxes; i < ((v->numAxes + 19) / VPC); + i++, axes -= VPC) { + t_axes = axes < VPC ? axes : VPC; + if (t_axes < 0) + t_axes = v->numAxes % VPC; + v2 = (xValuatorInfoPtr) * buf; + v2->class = ValuatorClass; + v2->length = sizeof(xValuatorInfo) + t_axes * sizeof(xAxisInfo); + v2->num_axes = t_axes; + v2->mode = v->mode & DeviceMode; + v2->motion_buffer_size = v->numMotionEvents; + if (client && client->swapped) { + swapl(&v2->motion_buffer_size, n); + } + *buf += sizeof(xValuatorInfo); + a = v->axes + (VPC * i); + a2 = (xAxisInfoPtr) * buf; + for (j = 0; j < t_axes; j++) { + a2->min_value = a->min_value; + a2->max_value = a->max_value; + a2->resolution = a->resolution; + if (client && client->swapped) { + swapl(&a2->min_value, n); + swapl(&a2->max_value, n); + swapl(&a2->resolution, n); + } + a2++; + a++; + *buf += sizeof(xAxisInfo); + } + } + return (i); +} + +static void +CopySwapClasses(ClientPtr client, DeviceIntPtr dev, CARD8 *num_classes, + char** classbuf) +{ + if (dev->key != NULL) { + CopySwapKeyClass(client, dev->key, classbuf); + (*num_classes)++; + } + if (dev->button != NULL) { + CopySwapButtonClass(client, dev->button, classbuf); + (*num_classes)++; + } + if (dev->valuator != NULL) { + (*num_classes) += + CopySwapValuatorClass(client, dev->valuator, classbuf); + } +} + +/*********************************************************************** + * + * This procedure lists information to be returned for an input device. + * + */ + +static void +ListDeviceInfo(ClientPtr client, DeviceIntPtr d, xDeviceInfoPtr dev, + char **devbuf, char **classbuf, char **namebuf) +{ + CopyDeviceName(namebuf, d->name); + CopySwapDevice(client, d, 0, devbuf); + CopySwapClasses(client, d, &dev->num_classes, classbuf); +} + +/*********************************************************************** + * + * This procedure checks if a device should be left off the list. + * + */ + +static Bool +ShouldSkipDevice(ClientPtr client, DeviceIntPtr d) +{ + /* don't send master devices other than VCP/VCK */ + if (!IsMaster(d) || d == inputInfo.pointer || d == inputInfo.keyboard) + { + int rc = XaceHook(XACE_DEVICE_ACCESS, client, d, DixGetAttrAccess); + if (rc == Success) + return FALSE; + } + return TRUE; +} + + +/*********************************************************************** + * + * This procedure lists the input devices available to the server. + * + * If this request is called by a client that has not issued a + * GetExtensionVersion request with major/minor version set, we don't send the + * complete device list. Instead, we only send the VCP, the VCK and floating + * SDs. This resembles the setup found on XI 1.x machines. + */ + +int +ProcXListInputDevices(ClientPtr client) +{ + xListInputDevicesReply rep; + int numdevs = 0; + int namesize = 1; /* need 1 extra byte for strcpy */ + int i = 0, size = 0; + int total_length; + char *devbuf, *classbuf, *namebuf, *savbuf; + Bool *skip; + xDeviceInfo *dev; + DeviceIntPtr d; + + REQUEST_SIZE_MATCH(xListInputDevicesReq); + + memset(&rep, 0, sizeof(xListInputDevicesReply)); + rep.repType = X_Reply; + rep.RepType = X_ListInputDevices; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + + AddOtherInputDevices(); + + /* allocate space for saving skip value */ + skip = calloc(sizeof(Bool), inputInfo.numDevices); + if (!skip) + return BadAlloc; + + /* figure out which devices to skip */ + numdevs = 0; + for (d = inputInfo.devices; d; d = d->next, i++) { + skip[i] = ShouldSkipDevice(client, d); + if (skip[i]) + continue; + + SizeDeviceInfo(d, &namesize, &size); + numdevs++; + } + + for (d = inputInfo.off_devices; d; d = d->next, i++) { + skip[i] = ShouldSkipDevice(client, d); + if (skip[i]) + continue; + + SizeDeviceInfo(d, &namesize, &size); + numdevs++; + } + + /* allocate space for reply */ + total_length = numdevs * sizeof(xDeviceInfo) + size + namesize; + devbuf = (char *)calloc(1, total_length); + classbuf = devbuf + (numdevs * sizeof(xDeviceInfo)); + namebuf = classbuf + size; + savbuf = devbuf; + + /* fill in and send reply */ + i = 0; + dev = (xDeviceInfoPtr) devbuf; + for (d = inputInfo.devices; d; d = d->next, i++) { + if (skip[i]) + continue; + + ListDeviceInfo(client, d, dev++, &devbuf, &classbuf, &namebuf); + } + + for (d = inputInfo.off_devices; d; d = d->next, i++) { + if (skip[i]) + continue; + + ListDeviceInfo(client, d, dev++, &devbuf, &classbuf, &namebuf); + } + rep.ndevices = numdevs; + rep.length = bytes_to_int32(total_length); + WriteReplyToClient(client, sizeof(xListInputDevicesReply), &rep); + WriteToClient(client, total_length, savbuf); + free(savbuf); + free(skip); + return Success; +} + +/*********************************************************************** + * + * This procedure writes the reply for the XListInputDevices function, + * if the client and server have a different byte ordering. + * + */ + +void +SRepXListInputDevices(ClientPtr client, int size, xListInputDevicesReply * rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + WriteToClient(client, size, (char *)rep); +} diff --git a/xorg-server/Xi/queryst.c b/xorg-server/Xi/queryst.c index 78b97a769..15d44592e 100644 --- a/xorg-server/Xi/queryst.c +++ b/xorg-server/Xi/queryst.c @@ -1,191 +1,191 @@ -/* - -Copyright 1998, 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. - -*/ - -/*********************************************************************** - * - * Request to query the state of an extension input device. - * - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "inputstr.h" /* DeviceIntPtr */ -#include "windowstr.h" /* window structure */ -#include -#include -#include "exevents.h" -#include "exglobals.h" -#include "xkbsrv.h" -#include "xkbstr.h" - -#include "queryst.h" - -/*********************************************************************** - * - * This procedure allows a client to query the state of a device. - * - */ - -int -SProcXQueryDeviceState(ClientPtr client) -{ - char n; - - REQUEST(xQueryDeviceStateReq); - swaps(&stuff->length, n); - return (ProcXQueryDeviceState(client)); -} - -/*********************************************************************** - * - * This procedure allows frozen events to be routed. - * - */ - -int -ProcXQueryDeviceState(ClientPtr client) -{ - char n; - int rc, i; - int num_classes = 0; - int total_length = 0; - char *buf, *savbuf; - KeyClassPtr k; - xKeyState *tk; - ButtonClassPtr b; - xButtonState *tb; - ValuatorClassPtr v; - xValuatorState *tv; - xQueryDeviceStateReply rep; - DeviceIntPtr dev; - double *values; - - REQUEST(xQueryDeviceStateReq); - REQUEST_SIZE_MATCH(xQueryDeviceStateReq); - - rep.repType = X_Reply; - rep.RepType = X_QueryDeviceState; - rep.length = 0; - rep.sequenceNumber = client->sequence; - - rc = dixLookupDevice(&dev, stuff->deviceid, client, DixReadAccess); - if (rc != Success && rc != BadAccess) - return rc; - - v = dev->valuator; - if (v != NULL && v->motionHintWindow != NULL) - MaybeStopDeviceHint(dev, client); - - k = dev->key; - if (k != NULL) { - total_length += sizeof(xKeyState); - num_classes++; - } - - b = dev->button; - if (b != NULL) { - total_length += sizeof(xButtonState); - num_classes++; - } - - if (v != NULL) { - total_length += (sizeof(xValuatorState) + (v->numAxes * sizeof(int))); - num_classes++; - } - buf = (char *)xcalloc(total_length, 1); - if (!buf) - return BadAlloc; - savbuf = buf; - - if (k != NULL) { - tk = (xKeyState *) buf; - tk->class = KeyClass; - tk->length = sizeof(xKeyState); - tk->num_keys = k->xkbInfo->desc->max_key_code - - k->xkbInfo->desc->min_key_code + 1; - if (rc != BadAccess) - for (i = 0; i < 32; i++) - tk->keys[i] = k->down[i]; - buf += sizeof(xKeyState); - } - - if (b != NULL) { - tb = (xButtonState *) buf; - tb->class = ButtonClass; - tb->length = sizeof(xButtonState); - tb->num_buttons = b->numButtons; - if (rc != BadAccess) - memcpy(tb->buttons, b->down, sizeof(b->down)); - buf += sizeof(xButtonState); - } - - if (v != NULL) { - tv = (xValuatorState *) buf; - tv->class = ValuatorClass; - tv->length = sizeof(xValuatorState) + v->numAxes * 4; - tv->num_valuators = v->numAxes; - tv->mode = v->mode; - buf += sizeof(xValuatorState); - for (i = 0, values = v->axisVal; i < v->numAxes; i++) { - if (rc != BadAccess) - *((int *)buf) = *values; - values++; - if (client->swapped) { - swapl((int *)buf, n); /* macro - braces needed */ - } - buf += sizeof(int); - } - } - - rep.num_classes = num_classes; - rep.length = bytes_to_int32(total_length); - WriteReplyToClient(client, sizeof(xQueryDeviceStateReply), &rep); - if (total_length > 0) - WriteToClient(client, total_length, savbuf); - xfree(savbuf); - return Success; -} - -/*********************************************************************** - * - * This procedure writes the reply for the XQueryDeviceState function, - * if the client and server have a different byte ordering. - * - */ - -void -SRepXQueryDeviceState(ClientPtr client, int size, xQueryDeviceStateReply * rep) -{ - char n; - - swaps(&rep->sequenceNumber, n); - swapl(&rep->length, n); - WriteToClient(client, size, (char *)rep); -} +/* + +Copyright 1998, 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. + +*/ + +/*********************************************************************** + * + * Request to query the state of an extension input device. + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include +#include +#include "exevents.h" +#include "exglobals.h" +#include "xkbsrv.h" +#include "xkbstr.h" + +#include "queryst.h" + +/*********************************************************************** + * + * This procedure allows a client to query the state of a device. + * + */ + +int +SProcXQueryDeviceState(ClientPtr client) +{ + char n; + + REQUEST(xQueryDeviceStateReq); + swaps(&stuff->length, n); + return (ProcXQueryDeviceState(client)); +} + +/*********************************************************************** + * + * This procedure allows frozen events to be routed. + * + */ + +int +ProcXQueryDeviceState(ClientPtr client) +{ + char n; + int rc, i; + int num_classes = 0; + int total_length = 0; + char *buf, *savbuf; + KeyClassPtr k; + xKeyState *tk; + ButtonClassPtr b; + xButtonState *tb; + ValuatorClassPtr v; + xValuatorState *tv; + xQueryDeviceStateReply rep; + DeviceIntPtr dev; + double *values; + + REQUEST(xQueryDeviceStateReq); + REQUEST_SIZE_MATCH(xQueryDeviceStateReq); + + rep.repType = X_Reply; + rep.RepType = X_QueryDeviceState; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + rc = dixLookupDevice(&dev, stuff->deviceid, client, DixReadAccess); + if (rc != Success && rc != BadAccess) + return rc; + + v = dev->valuator; + if (v != NULL && v->motionHintWindow != NULL) + MaybeStopDeviceHint(dev, client); + + k = dev->key; + if (k != NULL) { + total_length += sizeof(xKeyState); + num_classes++; + } + + b = dev->button; + if (b != NULL) { + total_length += sizeof(xButtonState); + num_classes++; + } + + if (v != NULL) { + total_length += (sizeof(xValuatorState) + (v->numAxes * sizeof(int))); + num_classes++; + } + buf = (char *)calloc(total_length, 1); + if (!buf) + return BadAlloc; + savbuf = buf; + + if (k != NULL) { + tk = (xKeyState *) buf; + tk->class = KeyClass; + tk->length = sizeof(xKeyState); + tk->num_keys = k->xkbInfo->desc->max_key_code - + k->xkbInfo->desc->min_key_code + 1; + if (rc != BadAccess) + for (i = 0; i < 32; i++) + tk->keys[i] = k->down[i]; + buf += sizeof(xKeyState); + } + + if (b != NULL) { + tb = (xButtonState *) buf; + tb->class = ButtonClass; + tb->length = sizeof(xButtonState); + tb->num_buttons = b->numButtons; + if (rc != BadAccess) + memcpy(tb->buttons, b->down, sizeof(b->down)); + buf += sizeof(xButtonState); + } + + if (v != NULL) { + tv = (xValuatorState *) buf; + tv->class = ValuatorClass; + tv->length = sizeof(xValuatorState) + v->numAxes * 4; + tv->num_valuators = v->numAxes; + tv->mode = v->mode; + buf += sizeof(xValuatorState); + for (i = 0, values = v->axisVal; i < v->numAxes; i++) { + if (rc != BadAccess) + *((int *)buf) = *values; + values++; + if (client->swapped) { + swapl((int *)buf, n); /* macro - braces needed */ + } + buf += sizeof(int); + } + } + + rep.num_classes = num_classes; + rep.length = bytes_to_int32(total_length); + WriteReplyToClient(client, sizeof(xQueryDeviceStateReply), &rep); + if (total_length > 0) + WriteToClient(client, total_length, savbuf); + free(savbuf); + return Success; +} + +/*********************************************************************** + * + * This procedure writes the reply for the XQueryDeviceState function, + * if the client and server have a different byte ordering. + * + */ + +void +SRepXQueryDeviceState(ClientPtr client, int size, xQueryDeviceStateReply * rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + WriteToClient(client, size, (char *)rep); +} diff --git a/xorg-server/Xi/xichangehierarchy.c b/xorg-server/Xi/xichangehierarchy.c index 1a06e4555..5deb52eac 100644 --- a/xorg-server/Xi/xichangehierarchy.c +++ b/xorg-server/Xi/xichangehierarchy.c @@ -1,454 +1,454 @@ -/* - * Copyright 2007-2008 Peter Hutterer - * Copyright 2009 Red Hat, Inc. - * - * 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, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Author: Peter Hutterer, University of South Australia, NICTA - */ - -/*********************************************************************** - * - * Request change in the device hierarchy. - * - */ - - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include /* for inputstr.h */ -#include /* Request macro */ -#include "inputstr.h" /* DeviceIntPtr */ -#include "windowstr.h" /* window structure */ -#include "scrnintstr.h" /* screen structure */ -#include -#include -#include -#include "extnsionst.h" -#include "exevents.h" -#include "exglobals.h" -#include "geext.h" -#include "xace.h" -#include "xiquerydevice.h" /* for GetDeviceUse */ - -#include "xkbsrv.h" - -#include "xichangehierarchy.h" - -/** - * Send the current state of the device hierarchy to all clients. - */ -void XISendDeviceHierarchyEvent(int flags[MAXDEVICES]) -{ - xXIHierarchyEvent *ev; - xXIHierarchyInfo *info; - DeviceIntRec dummyDev; - DeviceIntPtr dev; - int i; - - if (!flags) - return; - - ev = xcalloc(1, sizeof(xXIHierarchyEvent) + - MAXDEVICES * sizeof(xXIHierarchyInfo)); - ev->type = GenericEvent; - ev->extension = IReqCode; - ev->evtype = XI_HierarchyChanged; - ev->time = GetTimeInMillis(); - ev->flags = 0; - ev->num_info = inputInfo.numDevices; - - info = (xXIHierarchyInfo*)&ev[1]; - for (dev = inputInfo.devices; dev; dev = dev->next) - { - info->deviceid = dev->id; - info->enabled = dev->enabled; - info->use = GetDeviceUse(dev, &info->attachment); - info->flags = flags[dev->id]; - ev->flags |= info->flags; - info++; - } - for (dev = inputInfo.off_devices; dev; dev = dev->next) - { - info->deviceid = dev->id; - info->enabled = dev->enabled; - info->use = GetDeviceUse(dev, &info->attachment); - info->flags = flags[dev->id]; - ev->flags |= info->flags; - info++; - } - - - for (i = 0; i < MAXDEVICES; i++) - { - if (flags[i] & (XIMasterRemoved | XISlaveRemoved)) - { - info->deviceid = i; - info->enabled = FALSE; - info->flags = flags[i]; - info->use = 0; - ev->flags |= info->flags; - ev->num_info++; - info++; - } - } - - ev->length = bytes_to_int32(ev->num_info * sizeof(xXIHierarchyInfo)); - - dummyDev.id = XIAllDevices; - SendEventToAllWindows(&dummyDev, (XI_HierarchyChangedMask >> 8), (xEvent*)ev, 1); - xfree(ev); -} - - -/*********************************************************************** - * - * This procedure allows a client to change the device hierarchy through - * adding new master devices, removing them, etc. - * - */ - -int SProcXIChangeHierarchy(ClientPtr client) -{ - char n; - - REQUEST(xXIChangeHierarchyReq); - swaps(&stuff->length, n); - return (ProcXIChangeHierarchy(client)); -} - -#define SWAPIF(cmd) if (client->swapped) { cmd; } - -int -ProcXIChangeHierarchy(ClientPtr client) -{ - DeviceIntPtr ptr, keybd, XTestptr, XTestkeybd; - xXIAnyHierarchyChangeInfo *any; - int required_len = sizeof(xXIChangeHierarchyReq); - char n; - int rc = Success; - int flags[MAXDEVICES] = {0}; - - REQUEST(xXIChangeHierarchyReq); - REQUEST_AT_LEAST_SIZE(xXIChangeHierarchyReq); - - if (!stuff->num_changes) - return rc; - - any = (xXIAnyHierarchyChangeInfo*)&stuff[1]; - while(stuff->num_changes--) - { - SWAPIF(swapl(&any->type, n)); - SWAPIF(swaps(&any->length, n)); - - required_len += any->length; - if ((stuff->length * 4) < required_len) - return BadLength; - - switch(any->type) - { - case XIAddMaster: - { - xXIAddMasterInfo* c = (xXIAddMasterInfo*)any; - char* name; - - SWAPIF(swaps(&c->name_len, n)); - name = xcalloc(c->name_len + 1, sizeof(char)); - strncpy(name, (char*)&c[1], c->name_len); - - - rc = AllocDevicePair(client, name, &ptr, &keybd, - CorePointerProc, CoreKeyboardProc, - TRUE); - if (rc != Success) - { - xfree(name); - goto unwind; - } - - if (!c->send_core) - ptr->coreEvents = keybd->coreEvents = FALSE; - - /* Allocate virtual slave devices for xtest events */ - rc = AllocXTestDevice(client, name, &XTestptr, &XTestkeybd, - ptr, keybd); - if (rc != Success) - { - - xfree(name); - goto unwind; - } - - ActivateDevice(ptr, FALSE); - ActivateDevice(keybd, FALSE); - flags[ptr->id] |= XIMasterAdded; - flags[keybd->id] |= XIMasterAdded; - - ActivateDevice(XTestptr, FALSE); - ActivateDevice(XTestkeybd, FALSE); - flags[XTestptr->id] |= XISlaveAdded; - flags[XTestkeybd->id] |= XISlaveAdded; - - if (c->enable) - { - EnableDevice(ptr, FALSE); - EnableDevice(keybd, FALSE); - flags[ptr->id] |= XIDeviceEnabled; - flags[keybd->id] |= XIDeviceEnabled; - - EnableDevice(XTestptr, FALSE); - EnableDevice(XTestkeybd, FALSE); - flags[XTestptr->id] |= XIDeviceEnabled; - flags[XTestkeybd->id] |= XIDeviceEnabled; - } - - /* Attach the XTest virtual devices to the newly - created master device */ - AttachDevice(NULL, XTestptr, ptr); - AttachDevice(NULL, XTestkeybd, keybd); - flags[XTestptr->id] |= XISlaveAttached; - flags[XTestkeybd->id] |= XISlaveAttached; - - xfree(name); - } - break; - case XIRemoveMaster: - { - xXIRemoveMasterInfo* r = (xXIRemoveMasterInfo*)any; - - if (r->return_mode != XIAttachToMaster && - r->return_mode != XIFloating) - return BadValue; - - rc = dixLookupDevice(&ptr, r->deviceid, client, - DixDestroyAccess); - if (rc != Success) - goto unwind; - - if (!IsMaster(ptr)) - { - client->errorValue = r->deviceid; - rc = BadDevice; - goto unwind; - } - - /* XXX: For now, don't allow removal of VCP, VCK */ - if (ptr == inputInfo.pointer || - ptr == inputInfo.keyboard) - { - rc = BadDevice; - goto unwind; - } - - - ptr = GetMaster(ptr, MASTER_POINTER); - rc = dixLookupDevice(&ptr, - ptr->id, - client, - DixDestroyAccess); - if (rc != Success) - goto unwind; - keybd = GetMaster(ptr, MASTER_KEYBOARD); - rc = dixLookupDevice(&keybd, - keybd->id, - client, - DixDestroyAccess); - if (rc != Success) - goto unwind; - - XTestptr = GetXTestDevice(ptr); - rc = dixLookupDevice(&XTestptr, XTestptr->id, client, - DixDestroyAccess); - if (rc != Success) - goto unwind; - - XTestkeybd = GetXTestDevice(keybd); - rc = dixLookupDevice(&XTestkeybd, XTestkeybd->id, client, - DixDestroyAccess); - if (rc != Success) - goto unwind; - - /* Disabling sends the devices floating, reattach them if - * desired. */ - if (r->return_mode == XIAttachToMaster) - { - DeviceIntPtr attached, - newptr, - newkeybd; - - rc = dixLookupDevice(&newptr, r->return_pointer, - client, DixAddAccess); - if (rc != Success) - goto unwind; - - if (!IsMaster(newptr)) - { - client->errorValue = r->return_pointer; - rc = BadDevice; - goto unwind; - } - - rc = dixLookupDevice(&newkeybd, r->return_keyboard, - client, DixAddAccess); - if (rc != Success) - goto unwind; - - if (!IsMaster(newkeybd)) - { - client->errorValue = r->return_keyboard; - rc = BadDevice; - goto unwind; - } - - for (attached = inputInfo.devices; - attached; - attached = attached->next) - { - if (!IsMaster(attached)) { - if (attached->u.master == ptr) - { - AttachDevice(client, attached, newptr); - flags[attached->id] |= XISlaveAttached; - } - if (attached->u.master == keybd) - { - AttachDevice(client, attached, newkeybd); - flags[attached->id] |= XISlaveAttached; - } - } - } - } - - /* can't disable until we removed pairing */ - keybd->spriteInfo->paired = NULL; - ptr->spriteInfo->paired = NULL; - XTestptr->spriteInfo->paired = NULL; - XTestkeybd->spriteInfo->paired = NULL; - - /* disable the remove the devices, XTest devices must be done first - else the sprites they rely on will be destroyed */ - DisableDevice(XTestptr, FALSE); - DisableDevice(XTestkeybd, FALSE); - DisableDevice(keybd, FALSE); - DisableDevice(ptr, FALSE); - flags[XTestptr->id] |= XIDeviceDisabled | XISlaveDetached; - flags[XTestkeybd->id] |= XIDeviceDisabled | XISlaveDetached; - flags[keybd->id] |= XIDeviceDisabled; - flags[ptr->id] |= XIDeviceDisabled; - - RemoveDevice(XTestptr, FALSE); - RemoveDevice(XTestkeybd, FALSE); - RemoveDevice(keybd, FALSE); - RemoveDevice(ptr, FALSE); - flags[XTestptr->id] |= XISlaveRemoved; - flags[XTestkeybd->id] |= XISlaveRemoved; - flags[keybd->id] |= XIMasterRemoved; - flags[ptr->id] |= XIMasterRemoved; - } - break; - case XIDetachSlave: - { - xXIDetachSlaveInfo* c = (xXIDetachSlaveInfo*)any; - - rc = dixLookupDevice(&ptr, c->deviceid, client, - DixManageAccess); - if (rc != Success) - goto unwind; - - if (IsMaster(ptr)) - { - client->errorValue = c->deviceid; - rc = BadDevice; - goto unwind; - } - - /* Don't allow changes to XTest Devices, these are fixed */ - if (IsXTestDevice(ptr, NULL)) - { - client->errorValue = c->deviceid; - rc = BadDevice; - goto unwind; - } - - AttachDevice(client, ptr, NULL); - flags[ptr->id] |= XISlaveDetached; - } - break; - case XIAttachSlave: - { - xXIAttachSlaveInfo* c = (xXIAttachSlaveInfo*)any; - DeviceIntPtr newmaster; - - rc = dixLookupDevice(&ptr, c->deviceid, client, - DixManageAccess); - if (rc != Success) - goto unwind; - - if (IsMaster(ptr)) - { - client->errorValue = c->deviceid; - rc = BadDevice; - goto unwind; - } - - /* Don't allow changes to XTest Devices, these are fixed */ - if (IsXTestDevice(ptr, NULL)) - { - client->errorValue = c->deviceid; - rc = BadDevice; - goto unwind; - } - - rc = dixLookupDevice(&newmaster, c->new_master, - client, DixAddAccess); - if (rc != Success) - goto unwind; - if (!IsMaster(newmaster)) - { - client->errorValue = c->new_master; - rc = BadDevice; - goto unwind; - } - - if (!((IsPointerDevice(newmaster) && - IsPointerDevice(ptr)) || - (IsKeyboardDevice(newmaster) && - IsKeyboardDevice(ptr)))) - { - rc = BadDevice; - goto unwind; - } - AttachDevice(client, ptr, newmaster); - flags[ptr->id] |= XISlaveAttached; - } - break; - } - - any = (xXIAnyHierarchyChangeInfo*)((char*)any + any->length * 4); - } - -unwind: - - XISendDeviceHierarchyEvent(flags); - return rc; -} - +/* + * Copyright 2007-2008 Peter Hutterer + * Copyright 2009 Red Hat, Inc. + * + * 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, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Author: Peter Hutterer, University of South Australia, NICTA + */ + +/*********************************************************************** + * + * Request change in the device hierarchy. + * + */ + + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include /* for inputstr.h */ +#include /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include "scrnintstr.h" /* screen structure */ +#include +#include +#include +#include "extnsionst.h" +#include "exevents.h" +#include "exglobals.h" +#include "geext.h" +#include "xace.h" +#include "xiquerydevice.h" /* for GetDeviceUse */ + +#include "xkbsrv.h" + +#include "xichangehierarchy.h" + +/** + * Send the current state of the device hierarchy to all clients. + */ +void XISendDeviceHierarchyEvent(int flags[MAXDEVICES]) +{ + xXIHierarchyEvent *ev; + xXIHierarchyInfo *info; + DeviceIntRec dummyDev; + DeviceIntPtr dev; + int i; + + if (!flags) + return; + + ev = calloc(1, sizeof(xXIHierarchyEvent) + + MAXDEVICES * sizeof(xXIHierarchyInfo)); + ev->type = GenericEvent; + ev->extension = IReqCode; + ev->evtype = XI_HierarchyChanged; + ev->time = GetTimeInMillis(); + ev->flags = 0; + ev->num_info = inputInfo.numDevices; + + info = (xXIHierarchyInfo*)&ev[1]; + for (dev = inputInfo.devices; dev; dev = dev->next) + { + info->deviceid = dev->id; + info->enabled = dev->enabled; + info->use = GetDeviceUse(dev, &info->attachment); + info->flags = flags[dev->id]; + ev->flags |= info->flags; + info++; + } + for (dev = inputInfo.off_devices; dev; dev = dev->next) + { + info->deviceid = dev->id; + info->enabled = dev->enabled; + info->use = GetDeviceUse(dev, &info->attachment); + info->flags = flags[dev->id]; + ev->flags |= info->flags; + info++; + } + + + for (i = 0; i < MAXDEVICES; i++) + { + if (flags[i] & (XIMasterRemoved | XISlaveRemoved)) + { + info->deviceid = i; + info->enabled = FALSE; + info->flags = flags[i]; + info->use = 0; + ev->flags |= info->flags; + ev->num_info++; + info++; + } + } + + ev->length = bytes_to_int32(ev->num_info * sizeof(xXIHierarchyInfo)); + + dummyDev.id = XIAllDevices; + SendEventToAllWindows(&dummyDev, (XI_HierarchyChangedMask >> 8), (xEvent*)ev, 1); + free(ev); +} + + +/*********************************************************************** + * + * This procedure allows a client to change the device hierarchy through + * adding new master devices, removing them, etc. + * + */ + +int SProcXIChangeHierarchy(ClientPtr client) +{ + char n; + + REQUEST(xXIChangeHierarchyReq); + swaps(&stuff->length, n); + return (ProcXIChangeHierarchy(client)); +} + +#define SWAPIF(cmd) if (client->swapped) { cmd; } + +int +ProcXIChangeHierarchy(ClientPtr client) +{ + DeviceIntPtr ptr, keybd, XTestptr, XTestkeybd; + xXIAnyHierarchyChangeInfo *any; + int required_len = sizeof(xXIChangeHierarchyReq); + char n; + int rc = Success; + int flags[MAXDEVICES] = {0}; + + REQUEST(xXIChangeHierarchyReq); + REQUEST_AT_LEAST_SIZE(xXIChangeHierarchyReq); + + if (!stuff->num_changes) + return rc; + + any = (xXIAnyHierarchyChangeInfo*)&stuff[1]; + while(stuff->num_changes--) + { + SWAPIF(swapl(&any->type, n)); + SWAPIF(swaps(&any->length, n)); + + required_len += any->length; + if ((stuff->length * 4) < required_len) + return BadLength; + + switch(any->type) + { + case XIAddMaster: + { + xXIAddMasterInfo* c = (xXIAddMasterInfo*)any; + char* name; + + SWAPIF(swaps(&c->name_len, n)); + name = calloc(c->name_len + 1, sizeof(char)); + strncpy(name, (char*)&c[1], c->name_len); + + + rc = AllocDevicePair(client, name, &ptr, &keybd, + CorePointerProc, CoreKeyboardProc, + TRUE); + if (rc != Success) + { + free(name); + goto unwind; + } + + if (!c->send_core) + ptr->coreEvents = keybd->coreEvents = FALSE; + + /* Allocate virtual slave devices for xtest events */ + rc = AllocXTestDevice(client, name, &XTestptr, &XTestkeybd, + ptr, keybd); + if (rc != Success) + { + + free(name); + goto unwind; + } + + ActivateDevice(ptr, FALSE); + ActivateDevice(keybd, FALSE); + flags[ptr->id] |= XIMasterAdded; + flags[keybd->id] |= XIMasterAdded; + + ActivateDevice(XTestptr, FALSE); + ActivateDevice(XTestkeybd, FALSE); + flags[XTestptr->id] |= XISlaveAdded; + flags[XTestkeybd->id] |= XISlaveAdded; + + if (c->enable) + { + EnableDevice(ptr, FALSE); + EnableDevice(keybd, FALSE); + flags[ptr->id] |= XIDeviceEnabled; + flags[keybd->id] |= XIDeviceEnabled; + + EnableDevice(XTestptr, FALSE); + EnableDevice(XTestkeybd, FALSE); + flags[XTestptr->id] |= XIDeviceEnabled; + flags[XTestkeybd->id] |= XIDeviceEnabled; + } + + /* Attach the XTest virtual devices to the newly + created master device */ + AttachDevice(NULL, XTestptr, ptr); + AttachDevice(NULL, XTestkeybd, keybd); + flags[XTestptr->id] |= XISlaveAttached; + flags[XTestkeybd->id] |= XISlaveAttached; + + free(name); + } + break; + case XIRemoveMaster: + { + xXIRemoveMasterInfo* r = (xXIRemoveMasterInfo*)any; + + if (r->return_mode != XIAttachToMaster && + r->return_mode != XIFloating) + return BadValue; + + rc = dixLookupDevice(&ptr, r->deviceid, client, + DixDestroyAccess); + if (rc != Success) + goto unwind; + + if (!IsMaster(ptr)) + { + client->errorValue = r->deviceid; + rc = BadDevice; + goto unwind; + } + + /* XXX: For now, don't allow removal of VCP, VCK */ + if (ptr == inputInfo.pointer || + ptr == inputInfo.keyboard) + { + rc = BadDevice; + goto unwind; + } + + + ptr = GetMaster(ptr, MASTER_POINTER); + rc = dixLookupDevice(&ptr, + ptr->id, + client, + DixDestroyAccess); + if (rc != Success) + goto unwind; + keybd = GetMaster(ptr, MASTER_KEYBOARD); + rc = dixLookupDevice(&keybd, + keybd->id, + client, + DixDestroyAccess); + if (rc != Success) + goto unwind; + + XTestptr = GetXTestDevice(ptr); + rc = dixLookupDevice(&XTestptr, XTestptr->id, client, + DixDestroyAccess); + if (rc != Success) + goto unwind; + + XTestkeybd = GetXTestDevice(keybd); + rc = dixLookupDevice(&XTestkeybd, XTestkeybd->id, client, + DixDestroyAccess); + if (rc != Success) + goto unwind; + + /* Disabling sends the devices floating, reattach them if + * desired. */ + if (r->return_mode == XIAttachToMaster) + { + DeviceIntPtr attached, + newptr, + newkeybd; + + rc = dixLookupDevice(&newptr, r->return_pointer, + client, DixAddAccess); + if (rc != Success) + goto unwind; + + if (!IsMaster(newptr)) + { + client->errorValue = r->return_pointer; + rc = BadDevice; + goto unwind; + } + + rc = dixLookupDevice(&newkeybd, r->return_keyboard, + client, DixAddAccess); + if (rc != Success) + goto unwind; + + if (!IsMaster(newkeybd)) + { + client->errorValue = r->return_keyboard; + rc = BadDevice; + goto unwind; + } + + for (attached = inputInfo.devices; + attached; + attached = attached->next) + { + if (!IsMaster(attached)) { + if (attached->u.master == ptr) + { + AttachDevice(client, attached, newptr); + flags[attached->id] |= XISlaveAttached; + } + if (attached->u.master == keybd) + { + AttachDevice(client, attached, newkeybd); + flags[attached->id] |= XISlaveAttached; + } + } + } + } + + /* can't disable until we removed pairing */ + keybd->spriteInfo->paired = NULL; + ptr->spriteInfo->paired = NULL; + XTestptr->spriteInfo->paired = NULL; + XTestkeybd->spriteInfo->paired = NULL; + + /* disable the remove the devices, XTest devices must be done first + else the sprites they rely on will be destroyed */ + DisableDevice(XTestptr, FALSE); + DisableDevice(XTestkeybd, FALSE); + DisableDevice(keybd, FALSE); + DisableDevice(ptr, FALSE); + flags[XTestptr->id] |= XIDeviceDisabled | XISlaveDetached; + flags[XTestkeybd->id] |= XIDeviceDisabled | XISlaveDetached; + flags[keybd->id] |= XIDeviceDisabled; + flags[ptr->id] |= XIDeviceDisabled; + + RemoveDevice(XTestptr, FALSE); + RemoveDevice(XTestkeybd, FALSE); + RemoveDevice(keybd, FALSE); + RemoveDevice(ptr, FALSE); + flags[XTestptr->id] |= XISlaveRemoved; + flags[XTestkeybd->id] |= XISlaveRemoved; + flags[keybd->id] |= XIMasterRemoved; + flags[ptr->id] |= XIMasterRemoved; + } + break; + case XIDetachSlave: + { + xXIDetachSlaveInfo* c = (xXIDetachSlaveInfo*)any; + + rc = dixLookupDevice(&ptr, c->deviceid, client, + DixManageAccess); + if (rc != Success) + goto unwind; + + if (IsMaster(ptr)) + { + client->errorValue = c->deviceid; + rc = BadDevice; + goto unwind; + } + + /* Don't allow changes to XTest Devices, these are fixed */ + if (IsXTestDevice(ptr, NULL)) + { + client->errorValue = c->deviceid; + rc = BadDevice; + goto unwind; + } + + AttachDevice(client, ptr, NULL); + flags[ptr->id] |= XISlaveDetached; + } + break; + case XIAttachSlave: + { + xXIAttachSlaveInfo* c = (xXIAttachSlaveInfo*)any; + DeviceIntPtr newmaster; + + rc = dixLookupDevice(&ptr, c->deviceid, client, + DixManageAccess); + if (rc != Success) + goto unwind; + + if (IsMaster(ptr)) + { + client->errorValue = c->deviceid; + rc = BadDevice; + goto unwind; + } + + /* Don't allow changes to XTest Devices, these are fixed */ + if (IsXTestDevice(ptr, NULL)) + { + client->errorValue = c->deviceid; + rc = BadDevice; + goto unwind; + } + + rc = dixLookupDevice(&newmaster, c->new_master, + client, DixAddAccess); + if (rc != Success) + goto unwind; + if (!IsMaster(newmaster)) + { + client->errorValue = c->new_master; + rc = BadDevice; + goto unwind; + } + + if (!((IsPointerDevice(newmaster) && + IsPointerDevice(ptr)) || + (IsKeyboardDevice(newmaster) && + IsKeyboardDevice(ptr)))) + { + rc = BadDevice; + goto unwind; + } + AttachDevice(client, ptr, newmaster); + flags[ptr->id] |= XISlaveAttached; + } + break; + } + + any = (xXIAnyHierarchyChangeInfo*)((char*)any + any->length * 4); + } + +unwind: + + XISendDeviceHierarchyEvent(flags); + return rc; +} + diff --git a/xorg-server/Xi/xipassivegrab.c b/xorg-server/Xi/xipassivegrab.c index 41a56b14e..4a79ed497 100644 --- a/xorg-server/Xi/xipassivegrab.c +++ b/xorg-server/Xi/xipassivegrab.c @@ -1,313 +1,313 @@ -/* - * Copyright © 2009 Red Hat, Inc. - * - * 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, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Author: Peter Hutterer - */ - -/*********************************************************************** - * - * Request to grab or ungrab input device. - * - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "inputstr.h" /* DeviceIntPtr */ -#include "windowstr.h" /* window structure */ -#include -#include -#include "swaprep.h" - -#include "exglobals.h" /* BadDevice */ -#include "exevents.h" -#include "xipassivegrab.h" -#include "dixgrabs.h" - -int -SProcXIPassiveGrabDevice(ClientPtr client) -{ - int i; - char n; - xXIModifierInfo *mods; - - REQUEST(xXIPassiveGrabDeviceReq); - - swaps(&stuff->length, n); - swaps(&stuff->deviceid, n); - swapl(&stuff->grab_window, n); - swapl(&stuff->cursor, n); - swapl(&stuff->time, n); - swapl(&stuff->detail, n); - swaps(&stuff->mask_len, n); - swaps(&stuff->num_modifiers, n); - - mods = (xXIModifierInfo*)&stuff[1]; - - for (i = 0; i < stuff->num_modifiers; i++, mods++) - { - swapl(&mods->base_mods, n); - swapl(&mods->latched_mods, n); - swapl(&mods->locked_mods, n); - } - - return ProcXIPassiveGrabDevice(client); -} - -int -ProcXIPassiveGrabDevice(ClientPtr client) -{ - DeviceIntPtr dev, mod_dev; - xXIPassiveGrabDeviceReply rep; - int i, ret = Success; - uint8_t status; - uint32_t *modifiers; - xXIGrabModifierInfo *modifiers_failed; - GrabMask mask; - GrabParameters param; - void *tmp; - int mask_len; - - REQUEST(xXIPassiveGrabDeviceReq); - REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq); - - if (stuff->deviceid == XIAllDevices) - dev = inputInfo.all_devices; - else if (stuff->deviceid == XIAllMasterDevices) - dev = inputInfo.all_master_devices; - else - { - ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess); - if (ret != Success) - return ret; - } - - if (stuff->grab_type != XIGrabtypeButton && - stuff->grab_type != XIGrabtypeKeycode && - stuff->grab_type != XIGrabtypeEnter && - stuff->grab_type != XIGrabtypeFocusIn) - { - client->errorValue = stuff->grab_type; - return BadValue; - } - - if ((stuff->grab_type == XIGrabtypeEnter || - stuff->grab_type == XIGrabtypeFocusIn) && stuff->detail != 0) - { - client->errorValue = stuff->detail; - return BadValue; - } - - if (XICheckInvalidMaskBits((unsigned char*)&stuff[1], - stuff->mask_len * 4) != Success) - return BadValue; - - mask_len = min(sizeof(mask.xi2mask[stuff->deviceid]), stuff->mask_len * 4); - memset(mask.xi2mask, 0, sizeof(mask.xi2mask)); - memcpy(mask.xi2mask[stuff->deviceid], &stuff[1], mask_len * 4); - - rep.repType = X_Reply; - rep.RepType = X_XIPassiveGrabDevice; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.num_modifiers = 0; - - memset(¶m, 0, sizeof(param)); - param.grabtype = GRABTYPE_XI2; - param.ownerEvents = stuff->owner_events; - param.this_device_mode = stuff->grab_mode; - param.other_devices_mode = stuff->paired_device_mode; - param.grabWindow = stuff->grab_window; - param.cursor = stuff->cursor; - - if (stuff->cursor != None) - { - status = dixLookupResourceByType(&tmp, stuff->cursor, - RT_CURSOR, client, DixUseAccess); - if (status != Success) - { - client->errorValue = stuff->cursor; - return (status == BadValue) ? BadCursor : status; - } - } - - status = dixLookupWindow((WindowPtr*)&tmp, stuff->grab_window, client, DixSetAttrAccess); - if (status != Success) - return status; - - status = CheckGrabValues(client, ¶m); - - modifiers = (uint32_t*)&stuff[1] + stuff->mask_len; - modifiers_failed = xcalloc(stuff->num_modifiers, sizeof(xXIGrabModifierInfo)); - if (!modifiers_failed) - return BadAlloc; - - if (!IsMaster(dev) && dev->u.master) - mod_dev = GetMaster(dev, MASTER_KEYBOARD); - else - mod_dev = dev; - - for (i = 0; i < stuff->num_modifiers; i++, modifiers++) - { - param.modifiers = *modifiers; - switch(stuff->grab_type) - { - case XIGrabtypeButton: - status = GrabButton(client, dev, mod_dev, stuff->detail, - ¶m, GRABTYPE_XI2, &mask); - break; - case XIGrabtypeKeycode: - status = GrabKey(client, dev, mod_dev, stuff->detail, - ¶m, GRABTYPE_XI2, &mask); - break; - case XIGrabtypeEnter: - case XIGrabtypeFocusIn: - status = GrabWindow(client, dev, stuff->grab_type, - ¶m, &mask); - break; - } - - if (status != GrabSuccess) - { - xXIGrabModifierInfo *info = modifiers_failed + rep.num_modifiers; - - info->status = status; - info->modifiers = *modifiers; - rep.num_modifiers++; - rep.length++; - } - } - - WriteReplyToClient(client, sizeof(rep), &rep); - if (rep.num_modifiers) - { - client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; - WriteSwappedDataToClient(client, rep.num_modifiers * 4, (char*)modifiers_failed); - } - xfree(modifiers_failed); - return ret; -} - -void -SRepXIPassiveGrabDevice(ClientPtr client, int size, - xXIPassiveGrabDeviceReply * rep) -{ - char n; - - swaps(&rep->sequenceNumber, n); - swapl(&rep->length, n); - swaps(&rep->num_modifiers, n); - - WriteToClient(client, size, (char *)rep); -} - -int -SProcXIPassiveUngrabDevice(ClientPtr client) -{ - char n; - int i; - uint32_t *modifiers; - - REQUEST(xXIPassiveUngrabDeviceReq); - - swaps(&stuff->length, n); - swapl(&stuff->grab_window, n); - swaps(&stuff->deviceid, n); - swapl(&stuff->detail, n); - swaps(&stuff->num_modifiers, n); - - modifiers = (uint32_t*)&stuff[1]; - - for (i = 0; i < stuff->num_modifiers; i++, modifiers++) - swapl(modifiers, n); - - return ProcXIPassiveUngrabDevice(client); -} - -int -ProcXIPassiveUngrabDevice(ClientPtr client) -{ - DeviceIntPtr dev, mod_dev; - WindowPtr win; - GrabRec tempGrab; - uint32_t* modifiers; - int i, rc; - - REQUEST(xXIPassiveUngrabDeviceReq); - REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq); - - rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess); - if (rc != Success) - return rc; - - if (stuff->grab_type != XIGrabtypeButton && - stuff->grab_type != XIGrabtypeKeycode && - stuff->grab_type != XIGrabtypeEnter && - stuff->grab_type != XIGrabtypeFocusIn) - { - client->errorValue = stuff->grab_type; - return BadValue; - } - - if ((stuff->grab_type == XIGrabtypeEnter || - stuff->grab_type == XIGrabtypeFocusIn) && stuff->detail != 0) - { - client->errorValue = stuff->detail; - return BadValue; - } - - rc = dixLookupWindow(&win, stuff->grab_window, client, DixSetAttrAccess); - if (rc != Success) - return rc; - - if (!IsMaster(dev) && dev->u.master) - mod_dev = GetMaster(dev, MASTER_KEYBOARD); - else - mod_dev = dev; - - tempGrab.resource = client->clientAsMask; - tempGrab.device = dev; - tempGrab.window = win; - switch(stuff->grab_type) - { - case XIGrabtypeButton: tempGrab.type = XI_ButtonPress; break; - case XIGrabtypeKeycode: tempGrab.type = XI_KeyPress; break; - case XIGrabtypeEnter: tempGrab.type = XI_Enter; break; - case XIGrabtypeFocusIn: tempGrab.type = XI_FocusIn; break; - } - tempGrab.grabtype = GRABTYPE_XI2; - tempGrab.modifierDevice = mod_dev; - tempGrab.modifiersDetail.pMask = NULL; - tempGrab.detail.exact = stuff->detail; - tempGrab.detail.pMask = NULL; - - modifiers = (uint32_t*)&stuff[1]; - - for (i = 0; i < stuff->num_modifiers; i++, modifiers++) - { - tempGrab.modifiersDetail.exact = *modifiers; - DeletePassiveGrabFromList(&tempGrab); - } - - return Success; -} +/* + * Copyright © 2009 Red Hat, Inc. + * + * 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, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Author: Peter Hutterer + */ + +/*********************************************************************** + * + * Request to grab or ungrab input device. + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include +#include +#include "swaprep.h" + +#include "exglobals.h" /* BadDevice */ +#include "exevents.h" +#include "xipassivegrab.h" +#include "dixgrabs.h" + +int +SProcXIPassiveGrabDevice(ClientPtr client) +{ + int i; + char n; + xXIModifierInfo *mods; + + REQUEST(xXIPassiveGrabDeviceReq); + + swaps(&stuff->length, n); + swaps(&stuff->deviceid, n); + swapl(&stuff->grab_window, n); + swapl(&stuff->cursor, n); + swapl(&stuff->time, n); + swapl(&stuff->detail, n); + swaps(&stuff->mask_len, n); + swaps(&stuff->num_modifiers, n); + + mods = (xXIModifierInfo*)&stuff[1]; + + for (i = 0; i < stuff->num_modifiers; i++, mods++) + { + swapl(&mods->base_mods, n); + swapl(&mods->latched_mods, n); + swapl(&mods->locked_mods, n); + } + + return ProcXIPassiveGrabDevice(client); +} + +int +ProcXIPassiveGrabDevice(ClientPtr client) +{ + DeviceIntPtr dev, mod_dev; + xXIPassiveGrabDeviceReply rep; + int i, ret = Success; + uint8_t status; + uint32_t *modifiers; + xXIGrabModifierInfo *modifiers_failed; + GrabMask mask; + GrabParameters param; + void *tmp; + int mask_len; + + REQUEST(xXIPassiveGrabDeviceReq); + REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq); + + if (stuff->deviceid == XIAllDevices) + dev = inputInfo.all_devices; + else if (stuff->deviceid == XIAllMasterDevices) + dev = inputInfo.all_master_devices; + else + { + ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess); + if (ret != Success) + return ret; + } + + if (stuff->grab_type != XIGrabtypeButton && + stuff->grab_type != XIGrabtypeKeycode && + stuff->grab_type != XIGrabtypeEnter && + stuff->grab_type != XIGrabtypeFocusIn) + { + client->errorValue = stuff->grab_type; + return BadValue; + } + + if ((stuff->grab_type == XIGrabtypeEnter || + stuff->grab_type == XIGrabtypeFocusIn) && stuff->detail != 0) + { + client->errorValue = stuff->detail; + return BadValue; + } + + if (XICheckInvalidMaskBits((unsigned char*)&stuff[1], + stuff->mask_len * 4) != Success) + return BadValue; + + mask_len = min(sizeof(mask.xi2mask[stuff->deviceid]), stuff->mask_len * 4); + memset(mask.xi2mask, 0, sizeof(mask.xi2mask)); + memcpy(mask.xi2mask[stuff->deviceid], &stuff[1], mask_len * 4); + + rep.repType = X_Reply; + rep.RepType = X_XIPassiveGrabDevice; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.num_modifiers = 0; + + memset(¶m, 0, sizeof(param)); + param.grabtype = GRABTYPE_XI2; + param.ownerEvents = stuff->owner_events; + param.this_device_mode = stuff->grab_mode; + param.other_devices_mode = stuff->paired_device_mode; + param.grabWindow = stuff->grab_window; + param.cursor = stuff->cursor; + + if (stuff->cursor != None) + { + status = dixLookupResourceByType(&tmp, stuff->cursor, + RT_CURSOR, client, DixUseAccess); + if (status != Success) + { + client->errorValue = stuff->cursor; + return (status == BadValue) ? BadCursor : status; + } + } + + status = dixLookupWindow((WindowPtr*)&tmp, stuff->grab_window, client, DixSetAttrAccess); + if (status != Success) + return status; + + status = CheckGrabValues(client, ¶m); + + modifiers = (uint32_t*)&stuff[1] + stuff->mask_len; + modifiers_failed = calloc(stuff->num_modifiers, sizeof(xXIGrabModifierInfo)); + if (!modifiers_failed) + return BadAlloc; + + if (!IsMaster(dev) && dev->u.master) + mod_dev = GetMaster(dev, MASTER_KEYBOARD); + else + mod_dev = dev; + + for (i = 0; i < stuff->num_modifiers; i++, modifiers++) + { + param.modifiers = *modifiers; + switch(stuff->grab_type) + { + case XIGrabtypeButton: + status = GrabButton(client, dev, mod_dev, stuff->detail, + ¶m, GRABTYPE_XI2, &mask); + break; + case XIGrabtypeKeycode: + status = GrabKey(client, dev, mod_dev, stuff->detail, + ¶m, GRABTYPE_XI2, &mask); + break; + case XIGrabtypeEnter: + case XIGrabtypeFocusIn: + status = GrabWindow(client, dev, stuff->grab_type, + ¶m, &mask); + break; + } + + if (status != GrabSuccess) + { + xXIGrabModifierInfo *info = modifiers_failed + rep.num_modifiers; + + info->status = status; + info->modifiers = *modifiers; + rep.num_modifiers++; + rep.length++; + } + } + + WriteReplyToClient(client, sizeof(rep), &rep); + if (rep.num_modifiers) + { + client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; + WriteSwappedDataToClient(client, rep.num_modifiers * 4, (char*)modifiers_failed); + } + free(modifiers_failed); + return ret; +} + +void +SRepXIPassiveGrabDevice(ClientPtr client, int size, + xXIPassiveGrabDeviceReply * rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->num_modifiers, n); + + WriteToClient(client, size, (char *)rep); +} + +int +SProcXIPassiveUngrabDevice(ClientPtr client) +{ + char n; + int i; + uint32_t *modifiers; + + REQUEST(xXIPassiveUngrabDeviceReq); + + swaps(&stuff->length, n); + swapl(&stuff->grab_window, n); + swaps(&stuff->deviceid, n); + swapl(&stuff->detail, n); + swaps(&stuff->num_modifiers, n); + + modifiers = (uint32_t*)&stuff[1]; + + for (i = 0; i < stuff->num_modifiers; i++, modifiers++) + swapl(modifiers, n); + + return ProcXIPassiveUngrabDevice(client); +} + +int +ProcXIPassiveUngrabDevice(ClientPtr client) +{ + DeviceIntPtr dev, mod_dev; + WindowPtr win; + GrabRec tempGrab; + uint32_t* modifiers; + int i, rc; + + REQUEST(xXIPassiveUngrabDeviceReq); + REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq); + + rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess); + if (rc != Success) + return rc; + + if (stuff->grab_type != XIGrabtypeButton && + stuff->grab_type != XIGrabtypeKeycode && + stuff->grab_type != XIGrabtypeEnter && + stuff->grab_type != XIGrabtypeFocusIn) + { + client->errorValue = stuff->grab_type; + return BadValue; + } + + if ((stuff->grab_type == XIGrabtypeEnter || + stuff->grab_type == XIGrabtypeFocusIn) && stuff->detail != 0) + { + client->errorValue = stuff->detail; + return BadValue; + } + + rc = dixLookupWindow(&win, stuff->grab_window, client, DixSetAttrAccess); + if (rc != Success) + return rc; + + if (!IsMaster(dev) && dev->u.master) + mod_dev = GetMaster(dev, MASTER_KEYBOARD); + else + mod_dev = dev; + + tempGrab.resource = client->clientAsMask; + tempGrab.device = dev; + tempGrab.window = win; + switch(stuff->grab_type) + { + case XIGrabtypeButton: tempGrab.type = XI_ButtonPress; break; + case XIGrabtypeKeycode: tempGrab.type = XI_KeyPress; break; + case XIGrabtypeEnter: tempGrab.type = XI_Enter; break; + case XIGrabtypeFocusIn: tempGrab.type = XI_FocusIn; break; + } + tempGrab.grabtype = GRABTYPE_XI2; + tempGrab.modifierDevice = mod_dev; + tempGrab.modifiersDetail.pMask = NULL; + tempGrab.detail.exact = stuff->detail; + tempGrab.detail.pMask = NULL; + + modifiers = (uint32_t*)&stuff[1]; + + for (i = 0; i < stuff->num_modifiers; i++, modifiers++) + { + tempGrab.modifiersDetail.exact = *modifiers; + DeletePassiveGrabFromList(&tempGrab); + } + + return Success; +} diff --git a/xorg-server/Xi/xiproperty.c b/xorg-server/Xi/xiproperty.c index 6e298b7d1..4f8d2430d 100644 --- a/xorg-server/Xi/xiproperty.c +++ b/xorg-server/Xi/xiproperty.c @@ -225,7 +225,7 @@ static int list_atoms(DeviceIntPtr dev, int *natoms, Atom **atoms_return) { Atom *a; - atoms = xalloc(nprops * sizeof(Atom)); + atoms = malloc(nprops * sizeof(Atom)); if(!atoms) return BadAlloc; a = atoms; @@ -457,7 +457,7 @@ XIPropToInt(XIPropertyValuePtr val, int *nelem_return, int **buf_return) if (!buf && !(*nelem_return)) { - buf = xcalloc(val->size, sizeof(int)); + buf = calloc(val->size, sizeof(int)); if (!buf) return BadAlloc; *buf_return = buf; @@ -517,7 +517,7 @@ XIPropToFloat(XIPropertyValuePtr val, int *nelem_return, float **buf_return) if (!buf && !(*nelem_return)) { - buf = xcalloc(val->size, sizeof(float)); + buf = calloc(val->size, sizeof(float)); if (!buf) return BadAlloc; *buf_return = buf; @@ -549,7 +549,7 @@ XIRegisterPropertyHandler(DeviceIntPtr dev, { XIPropertyHandlerPtr new_handler; - new_handler = xcalloc(1, sizeof(XIPropertyHandler)); + new_handler = calloc(1, sizeof(XIPropertyHandler)); if (!new_handler) return 0; @@ -583,7 +583,7 @@ XIUnregisterPropertyHandler(DeviceIntPtr dev, long id) else prev->next = curr->next; - xfree(curr); + free(curr); } static XIPropertyPtr @@ -591,7 +591,7 @@ XICreateDeviceProperty (Atom property) { XIPropertyPtr prop; - prop = (XIPropertyPtr)xalloc(sizeof(XIPropertyRec)); + prop = (XIPropertyPtr)malloc(sizeof(XIPropertyRec)); if (!prop) return NULL; @@ -621,8 +621,8 @@ static void XIDestroyDeviceProperty (XIPropertyPtr prop) { if (prop->value.data) - xfree(prop->value.data); - xfree(prop); + free(prop->value.data); + free(prop); } /* This function destroys all of the device's property-related stuff, @@ -649,7 +649,7 @@ XIDeleteAllDeviceProperties (DeviceIntPtr device) while(curr_handler) { next_handler = curr_handler->next; - xfree(curr_handler); + free(curr_handler); curr_handler = next_handler; } @@ -745,7 +745,7 @@ XIChangeDeviceProperty (DeviceIntPtr dev, Atom property, Atom type, pointer new_data = NULL, old_data = NULL; total_size = total_len * size_in_bytes; - new_value.data = (pointer)xalloc (total_size); + new_value.data = (pointer)malloc(total_size); if (!new_value.data && total_size) { if (add) @@ -797,7 +797,7 @@ XIChangeDeviceProperty (DeviceIntPtr dev, Atom property, Atom type, if (checkonly && rc != Success) { if (new_value.data) - xfree (new_value.data); + free(new_value.data); return (rc); } } @@ -807,7 +807,7 @@ XIChangeDeviceProperty (DeviceIntPtr dev, Atom property, Atom type, } while (!checkonly); } if (prop_value->data) - xfree (prop_value->data); + free(prop_value->data); *prop_value = new_value; } else if (len == 0) { @@ -905,7 +905,7 @@ ProcXListDeviceProperties (ClientPtr client) { client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write; WriteSwappedDataToClient(client, natoms * sizeof(Atom), atoms); - xfree(atoms); + free(atoms); } return rc; } @@ -1149,7 +1149,7 @@ ProcXIListProperties(ClientPtr client) { client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write; WriteSwappedDataToClient(client, natoms * sizeof(Atom), atoms); - xfree(atoms); + free(atoms); } return rc; } diff --git a/xorg-server/Xi/xiquerydevice.c b/xorg-server/Xi/xiquerydevice.c index 47ab688fd..c24f8a894 100644 --- a/xorg-server/Xi/xiquerydevice.c +++ b/xorg-server/Xi/xiquerydevice.c @@ -1,503 +1,503 @@ -/* - * Copyright © 2009 Red Hat, Inc. - * - * 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, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Authors: Peter Hutterer - * - */ - -/** - * @file Protocol handling for the XIQueryDevice request/reply. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "inputstr.h" -#include -#include -#include -#include "xkbstr.h" -#include "xkbsrv.h" -#include "xserver-properties.h" -#include "exevents.h" -#include "xace.h" - -#include "xiquerydevice.h" - -static Bool ShouldSkipDevice(ClientPtr client, int deviceid, DeviceIntPtr d); -static int -ListDeviceInfo(ClientPtr client, DeviceIntPtr dev, xXIDeviceInfo* info); -static int SizeDeviceInfo(DeviceIntPtr dev); -static void SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info); -int -SProcXIQueryDevice(ClientPtr client) -{ - char n; - - REQUEST(xXIQueryDeviceReq); - - swaps(&stuff->length, n); - swaps(&stuff->deviceid, n); - - return ProcXIQueryDevice(client); -} - -int -ProcXIQueryDevice(ClientPtr client) -{ - xXIQueryDeviceReply rep; - DeviceIntPtr dev = NULL; - int rc = Success; - int i = 0, len = 0; - char *info, *ptr; - Bool *skip = NULL; - - REQUEST(xXIQueryDeviceReq); - REQUEST_SIZE_MATCH(xXIQueryDeviceReq); - - if (stuff->deviceid != XIAllDevices && stuff->deviceid != XIAllMasterDevices) - { - rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess); - if (rc != Success) - { - client->errorValue = stuff->deviceid; - return rc; - } - len += SizeDeviceInfo(dev); - } - else - { - skip = xcalloc(sizeof(Bool), inputInfo.numDevices); - if (!skip) - return BadAlloc; - - for (dev = inputInfo.devices; dev; dev = dev->next, i++) - { - skip[i] = ShouldSkipDevice(client, stuff->deviceid, dev); - if (!skip[i]) - len += SizeDeviceInfo(dev); - } - - for (dev = inputInfo.off_devices; dev; dev = dev->next, i++) - { - skip[i] = ShouldSkipDevice(client, stuff->deviceid, dev); - if (!skip[i]) - len += SizeDeviceInfo(dev); - } - } - - info = xcalloc(1, len); - if (!info) - return BadAlloc; - - memset(&rep, 0, sizeof(xXIQueryDeviceReply)); - rep.repType = X_Reply; - rep.RepType = X_XIQueryDevice; - rep.sequenceNumber = client->sequence; - rep.length = len/4; - rep.num_devices = 0; - - ptr = info; - if (dev) - { - len = ListDeviceInfo(client, dev, (xXIDeviceInfo*)info); - if (client->swapped) - SwapDeviceInfo(dev, (xXIDeviceInfo*)info); - info += len; - rep.num_devices = 1; - } else - { - i = 0; - for (dev = inputInfo.devices; dev; dev = dev->next, i++) - { - if (!skip[i]) - { - len = ListDeviceInfo(client, dev, (xXIDeviceInfo*)info); - if (client->swapped) - SwapDeviceInfo(dev, (xXIDeviceInfo*)info); - info += len; - rep.num_devices++; - } - } - - for (dev = inputInfo.off_devices; dev; dev = dev->next, i++) - { - if (!skip[i]) - { - len = ListDeviceInfo(client, dev, (xXIDeviceInfo*)info); - if (client->swapped) - SwapDeviceInfo(dev, (xXIDeviceInfo*)info); - info += len; - rep.num_devices++; - } - } - } - - WriteReplyToClient(client, sizeof(xXIQueryDeviceReply), &rep); - WriteToClient(client, rep.length * 4, ptr); - xfree(ptr); - xfree(skip); - return rc; -} - -void -SRepXIQueryDevice(ClientPtr client, int size, xXIQueryDeviceReply *rep) -{ - char n; - - swaps(&rep->sequenceNumber, n); - swapl(&rep->length, n); - swaps(&rep->num_devices, n); - - /* Device info is already swapped, see ProcXIQueryDevice */ - - WriteToClient(client, size, (char *)rep); -} - - -/** - * @return Whether the device should be included in the returned list. - */ -static Bool -ShouldSkipDevice(ClientPtr client, int deviceid, DeviceIntPtr dev) -{ - /* if all devices are not being queried, only master devices are */ - if (deviceid == XIAllDevices || IsMaster(dev)) - { - int rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixGetAttrAccess); - if (rc == Success) - return FALSE; - } - return TRUE; -} - -/** - * @return The number of bytes needed to store this device's xXIDeviceInfo - * (and its classes). - */ -static int -SizeDeviceInfo(DeviceIntPtr dev) -{ - int len = sizeof(xXIDeviceInfo); - - /* 4-padded name */ - len += pad_to_int32(strlen(dev->name)); - - return len + SizeDeviceClasses(dev); - -} - -/* - * @return The number of bytes needed to store this device's classes. - */ -int -SizeDeviceClasses(DeviceIntPtr dev) -{ - int len = 0; - - if (dev->button) - { - len += sizeof(xXIButtonInfo); - len += dev->button->numButtons * sizeof(Atom); - len += pad_to_int32(bits_to_bytes(dev->button->numButtons)); - } - - if (dev->key) - { - XkbDescPtr xkb = dev->key->xkbInfo->desc; - len += sizeof(xXIKeyInfo); - len += (xkb->max_key_code - xkb->min_key_code + 1) * sizeof(uint32_t); - } - - if (dev->valuator) - len += sizeof(xXIValuatorInfo) * dev->valuator->numAxes; - - return len; -} - - -/** - * Write button information into info. - * @return Number of bytes written into info. - */ -int -ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info, Bool reportState) -{ - unsigned char *bits; - int mask_len; - int i; - - if (!dev || !dev->button) - return 0; - - mask_len = bytes_to_int32(bits_to_bytes(dev->button->numButtons)); - - info->type = ButtonClass; - info->num_buttons = dev->button->numButtons; - info->length = bytes_to_int32(sizeof(xXIButtonInfo)) + - info->num_buttons + mask_len; - info->sourceid = dev->button->sourceid; - - bits = (unsigned char*)&info[1]; - memset(bits, 0, mask_len * 4); - - if (reportState) - for (i = 0; i < dev->button->numButtons; i++) - if (BitIsOn(dev->button->down, i)) - SetBit(bits, i); - - bits += mask_len * 4; - memcpy(bits, dev->button->labels, dev->button->numButtons * sizeof(Atom)); - - return info->length * 4; -} - -static void -SwapButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info) -{ - char n; - Atom *btn; - int i; - swaps(&info->type, n); - swaps(&info->length, n); - swaps(&info->sourceid, n); - - for (i = 0, btn = (Atom*)&info[1]; i < info->num_buttons; i++, btn++) - swaps(btn, n); - - swaps(&info->num_buttons, n); -} - -/** - * Write key information into info. - * @return Number of bytes written into info. - */ -int -ListKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info) -{ - int i; - XkbDescPtr xkb = dev->key->xkbInfo->desc; - uint32_t *kc; - - info->type = KeyClass; - info->num_keycodes = xkb->max_key_code - xkb->min_key_code + 1; - info->length = sizeof(xXIKeyInfo)/4 + info->num_keycodes; - info->sourceid = dev->key->sourceid; - - kc = (uint32_t*)&info[1]; - for (i = xkb->min_key_code; i <= xkb->max_key_code; i++, kc++) - *kc = i; - - return info->length * 4; -} - -static void -SwapKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info) -{ - char n; - uint32_t *key; - int i; - swaps(&info->type, n); - swaps(&info->length, n); - swaps(&info->sourceid, n); - - for (i = 0, key = (uint32_t*)&info[1]; i < info->num_keycodes; i++, key++) - swapl(key, n); - - swaps(&info->num_keycodes, n); -} - -/** - * List axis information for the given axis. - * - * @return The number of bytes written into info. - */ -int -ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, int axisnumber, - Bool reportState) -{ - ValuatorClassPtr v = dev->valuator; - - info->type = ValuatorClass; - info->length = sizeof(xXIValuatorInfo)/4; - info->label = v->axes[axisnumber].label; - info->min.integral = v->axes[axisnumber].min_value; - info->min.frac = 0; - info->max.integral = v->axes[axisnumber].max_value; - info->max.frac = 0; - info->value.integral = (int)v->axisVal[axisnumber]; - info->value.frac = (int)(v->axisVal[axisnumber] * (1 << 16) * (1 << 16)); - info->resolution = v->axes[axisnumber].resolution; - info->number = axisnumber; - info->mode = v->mode; /* Server doesn't have per-axis mode yet */ - info->sourceid = v->sourceid; - - if (!reportState) - info->value = info->min; - - return info->length * 4; -} - -static void -SwapValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info) -{ - char n; - swaps(&info->type, n); - swaps(&info->length, n); - swapl(&info->label, n); - swapl(&info->min.integral, n); - swapl(&info->min.frac, n); - swapl(&info->max.integral, n); - swapl(&info->max.frac, n); - swaps(&info->number, n); - swaps(&info->sourceid, n); -} - -int GetDeviceUse(DeviceIntPtr dev, uint16_t *attachment) -{ - DeviceIntPtr master = dev->u.master; - int use; - - if (IsMaster(dev)) - { - DeviceIntPtr paired = GetPairedDevice(dev); - use = IsPointerDevice(dev) ? XIMasterPointer : XIMasterKeyboard; - *attachment = (paired ? paired->id : 0); - } else if (master) - { - use = IsPointerDevice(master) ? XISlavePointer : XISlaveKeyboard; - *attachment = master->id; - } else - use = XIFloatingSlave; - - return use; -} - -/** - * Write the info for device dev into the buffer pointed to by info. - * - * @return The number of bytes used. - */ -static int -ListDeviceInfo(ClientPtr client, DeviceIntPtr dev, xXIDeviceInfo* info) -{ - char *any = (char*)&info[1]; - int len = 0, total_len = 0; - - info->deviceid = dev->id; - info->use = GetDeviceUse(dev, &info->attachment); - info->num_classes = 0; - info->name_len = strlen(dev->name); - info->enabled = dev->enabled; - total_len = sizeof(xXIDeviceInfo); - - len = pad_to_int32(info->name_len); - memset(any, 0, len); - strncpy(any, dev->name, info->name_len); - any += len; - total_len += len; - - total_len += ListDeviceClasses(client, dev, any, &info->num_classes); - return total_len; -} - -/** - * Write the class info of the device into the memory pointed to by any, set - * nclasses to the number of classes in total and return the number of bytes - * written. - */ -int -ListDeviceClasses(ClientPtr client, DeviceIntPtr dev, - char *any, uint16_t *nclasses) -{ - int total_len = 0; - int len; - int i; - int rc; - - /* Check if the current device state should be suppressed */ - rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixReadAccess); - - if (dev->button) - { - (*nclasses)++; - len = ListButtonInfo(dev, (xXIButtonInfo*)any, rc == Success); - any += len; - total_len += len; - } - - if (dev->key) - { - (*nclasses)++; - len = ListKeyInfo(dev, (xXIKeyInfo*)any); - any += len; - total_len += len; - } - - for (i = 0; dev->valuator && i < dev->valuator->numAxes; i++) - { - (*nclasses)++; - len = ListValuatorInfo(dev, (xXIValuatorInfo*)any, i, rc == Success); - any += len; - total_len += len; - } - - return total_len; -} - -static void -SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info) -{ - char n; - char *any = (char*)&info[1]; - int i; - - /* Skip over name */ - any += pad_to_int32(info->name_len); - - for (i = 0; i < info->num_classes; i++) - { - int len = ((xXIAnyInfo*)any)->length; - switch(((xXIAnyInfo*)any)->type) - { - case XIButtonClass: - SwapButtonInfo(dev, (xXIButtonInfo*)any); - break; - case XIKeyClass: - SwapKeyInfo(dev, (xXIKeyInfo*)any); - break; - case XIValuatorClass: - SwapValuatorInfo(dev, (xXIValuatorInfo*)any); - break; - } - - any += len * 4; - } - - swaps(&info->deviceid, n); - swaps(&info->use, n); - swaps(&info->attachment, n); - swaps(&info->num_classes, n); - swaps(&info->name_len, n); - -} +/* + * Copyright © 2009 Red Hat, Inc. + * + * 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, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Authors: Peter Hutterer + * + */ + +/** + * @file Protocol handling for the XIQueryDevice request/reply. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "inputstr.h" +#include +#include +#include +#include "xkbstr.h" +#include "xkbsrv.h" +#include "xserver-properties.h" +#include "exevents.h" +#include "xace.h" + +#include "xiquerydevice.h" + +static Bool ShouldSkipDevice(ClientPtr client, int deviceid, DeviceIntPtr d); +static int +ListDeviceInfo(ClientPtr client, DeviceIntPtr dev, xXIDeviceInfo* info); +static int SizeDeviceInfo(DeviceIntPtr dev); +static void SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info); +int +SProcXIQueryDevice(ClientPtr client) +{ + char n; + + REQUEST(xXIQueryDeviceReq); + + swaps(&stuff->length, n); + swaps(&stuff->deviceid, n); + + return ProcXIQueryDevice(client); +} + +int +ProcXIQueryDevice(ClientPtr client) +{ + xXIQueryDeviceReply rep; + DeviceIntPtr dev = NULL; + int rc = Success; + int i = 0, len = 0; + char *info, *ptr; + Bool *skip = NULL; + + REQUEST(xXIQueryDeviceReq); + REQUEST_SIZE_MATCH(xXIQueryDeviceReq); + + if (stuff->deviceid != XIAllDevices && stuff->deviceid != XIAllMasterDevices) + { + rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess); + if (rc != Success) + { + client->errorValue = stuff->deviceid; + return rc; + } + len += SizeDeviceInfo(dev); + } + else + { + skip = calloc(sizeof(Bool), inputInfo.numDevices); + if (!skip) + return BadAlloc; + + for (dev = inputInfo.devices; dev; dev = dev->next, i++) + { + skip[i] = ShouldSkipDevice(client, stuff->deviceid, dev); + if (!skip[i]) + len += SizeDeviceInfo(dev); + } + + for (dev = inputInfo.off_devices; dev; dev = dev->next, i++) + { + skip[i] = ShouldSkipDevice(client, stuff->deviceid, dev); + if (!skip[i]) + len += SizeDeviceInfo(dev); + } + } + + info = calloc(1, len); + if (!info) + return BadAlloc; + + memset(&rep, 0, sizeof(xXIQueryDeviceReply)); + rep.repType = X_Reply; + rep.RepType = X_XIQueryDevice; + rep.sequenceNumber = client->sequence; + rep.length = len/4; + rep.num_devices = 0; + + ptr = info; + if (dev) + { + len = ListDeviceInfo(client, dev, (xXIDeviceInfo*)info); + if (client->swapped) + SwapDeviceInfo(dev, (xXIDeviceInfo*)info); + info += len; + rep.num_devices = 1; + } else + { + i = 0; + for (dev = inputInfo.devices; dev; dev = dev->next, i++) + { + if (!skip[i]) + { + len = ListDeviceInfo(client, dev, (xXIDeviceInfo*)info); + if (client->swapped) + SwapDeviceInfo(dev, (xXIDeviceInfo*)info); + info += len; + rep.num_devices++; + } + } + + for (dev = inputInfo.off_devices; dev; dev = dev->next, i++) + { + if (!skip[i]) + { + len = ListDeviceInfo(client, dev, (xXIDeviceInfo*)info); + if (client->swapped) + SwapDeviceInfo(dev, (xXIDeviceInfo*)info); + info += len; + rep.num_devices++; + } + } + } + + WriteReplyToClient(client, sizeof(xXIQueryDeviceReply), &rep); + WriteToClient(client, rep.length * 4, ptr); + free(ptr); + free(skip); + return rc; +} + +void +SRepXIQueryDevice(ClientPtr client, int size, xXIQueryDeviceReply *rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->num_devices, n); + + /* Device info is already swapped, see ProcXIQueryDevice */ + + WriteToClient(client, size, (char *)rep); +} + + +/** + * @return Whether the device should be included in the returned list. + */ +static Bool +ShouldSkipDevice(ClientPtr client, int deviceid, DeviceIntPtr dev) +{ + /* if all devices are not being queried, only master devices are */ + if (deviceid == XIAllDevices || IsMaster(dev)) + { + int rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixGetAttrAccess); + if (rc == Success) + return FALSE; + } + return TRUE; +} + +/** + * @return The number of bytes needed to store this device's xXIDeviceInfo + * (and its classes). + */ +static int +SizeDeviceInfo(DeviceIntPtr dev) +{ + int len = sizeof(xXIDeviceInfo); + + /* 4-padded name */ + len += pad_to_int32(strlen(dev->name)); + + return len + SizeDeviceClasses(dev); + +} + +/* + * @return The number of bytes needed to store this device's classes. + */ +int +SizeDeviceClasses(DeviceIntPtr dev) +{ + int len = 0; + + if (dev->button) + { + len += sizeof(xXIButtonInfo); + len += dev->button->numButtons * sizeof(Atom); + len += pad_to_int32(bits_to_bytes(dev->button->numButtons)); + } + + if (dev->key) + { + XkbDescPtr xkb = dev->key->xkbInfo->desc; + len += sizeof(xXIKeyInfo); + len += (xkb->max_key_code - xkb->min_key_code + 1) * sizeof(uint32_t); + } + + if (dev->valuator) + len += sizeof(xXIValuatorInfo) * dev->valuator->numAxes; + + return len; +} + + +/** + * Write button information into info. + * @return Number of bytes written into info. + */ +int +ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info, Bool reportState) +{ + unsigned char *bits; + int mask_len; + int i; + + if (!dev || !dev->button) + return 0; + + mask_len = bytes_to_int32(bits_to_bytes(dev->button->numButtons)); + + info->type = ButtonClass; + info->num_buttons = dev->button->numButtons; + info->length = bytes_to_int32(sizeof(xXIButtonInfo)) + + info->num_buttons + mask_len; + info->sourceid = dev->button->sourceid; + + bits = (unsigned char*)&info[1]; + memset(bits, 0, mask_len * 4); + + if (reportState) + for (i = 0; i < dev->button->numButtons; i++) + if (BitIsOn(dev->button->down, i)) + SetBit(bits, i); + + bits += mask_len * 4; + memcpy(bits, dev->button->labels, dev->button->numButtons * sizeof(Atom)); + + return info->length * 4; +} + +static void +SwapButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info) +{ + char n; + Atom *btn; + int i; + swaps(&info->type, n); + swaps(&info->length, n); + swaps(&info->sourceid, n); + + for (i = 0, btn = (Atom*)&info[1]; i < info->num_buttons; i++, btn++) + swaps(btn, n); + + swaps(&info->num_buttons, n); +} + +/** + * Write key information into info. + * @return Number of bytes written into info. + */ +int +ListKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info) +{ + int i; + XkbDescPtr xkb = dev->key->xkbInfo->desc; + uint32_t *kc; + + info->type = KeyClass; + info->num_keycodes = xkb->max_key_code - xkb->min_key_code + 1; + info->length = sizeof(xXIKeyInfo)/4 + info->num_keycodes; + info->sourceid = dev->key->sourceid; + + kc = (uint32_t*)&info[1]; + for (i = xkb->min_key_code; i <= xkb->max_key_code; i++, kc++) + *kc = i; + + return info->length * 4; +} + +static void +SwapKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info) +{ + char n; + uint32_t *key; + int i; + swaps(&info->type, n); + swaps(&info->length, n); + swaps(&info->sourceid, n); + + for (i = 0, key = (uint32_t*)&info[1]; i < info->num_keycodes; i++, key++) + swapl(key, n); + + swaps(&info->num_keycodes, n); +} + +/** + * List axis information for the given axis. + * + * @return The number of bytes written into info. + */ +int +ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, int axisnumber, + Bool reportState) +{ + ValuatorClassPtr v = dev->valuator; + + info->type = ValuatorClass; + info->length = sizeof(xXIValuatorInfo)/4; + info->label = v->axes[axisnumber].label; + info->min.integral = v->axes[axisnumber].min_value; + info->min.frac = 0; + info->max.integral = v->axes[axisnumber].max_value; + info->max.frac = 0; + info->value.integral = (int)v->axisVal[axisnumber]; + info->value.frac = (int)(v->axisVal[axisnumber] * (1 << 16) * (1 << 16)); + info->resolution = v->axes[axisnumber].resolution; + info->number = axisnumber; + info->mode = v->mode; /* Server doesn't have per-axis mode yet */ + info->sourceid = v->sourceid; + + if (!reportState) + info->value = info->min; + + return info->length * 4; +} + +static void +SwapValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info) +{ + char n; + swaps(&info->type, n); + swaps(&info->length, n); + swapl(&info->label, n); + swapl(&info->min.integral, n); + swapl(&info->min.frac, n); + swapl(&info->max.integral, n); + swapl(&info->max.frac, n); + swaps(&info->number, n); + swaps(&info->sourceid, n); +} + +int GetDeviceUse(DeviceIntPtr dev, uint16_t *attachment) +{ + DeviceIntPtr master = dev->u.master; + int use; + + if (IsMaster(dev)) + { + DeviceIntPtr paired = GetPairedDevice(dev); + use = IsPointerDevice(dev) ? XIMasterPointer : XIMasterKeyboard; + *attachment = (paired ? paired->id : 0); + } else if (master) + { + use = IsPointerDevice(master) ? XISlavePointer : XISlaveKeyboard; + *attachment = master->id; + } else + use = XIFloatingSlave; + + return use; +} + +/** + * Write the info for device dev into the buffer pointed to by info. + * + * @return The number of bytes used. + */ +static int +ListDeviceInfo(ClientPtr client, DeviceIntPtr dev, xXIDeviceInfo* info) +{ + char *any = (char*)&info[1]; + int len = 0, total_len = 0; + + info->deviceid = dev->id; + info->use = GetDeviceUse(dev, &info->attachment); + info->num_classes = 0; + info->name_len = strlen(dev->name); + info->enabled = dev->enabled; + total_len = sizeof(xXIDeviceInfo); + + len = pad_to_int32(info->name_len); + memset(any, 0, len); + strncpy(any, dev->name, info->name_len); + any += len; + total_len += len; + + total_len += ListDeviceClasses(client, dev, any, &info->num_classes); + return total_len; +} + +/** + * Write the class info of the device into the memory pointed to by any, set + * nclasses to the number of classes in total and return the number of bytes + * written. + */ +int +ListDeviceClasses(ClientPtr client, DeviceIntPtr dev, + char *any, uint16_t *nclasses) +{ + int total_len = 0; + int len; + int i; + int rc; + + /* Check if the current device state should be suppressed */ + rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixReadAccess); + + if (dev->button) + { + (*nclasses)++; + len = ListButtonInfo(dev, (xXIButtonInfo*)any, rc == Success); + any += len; + total_len += len; + } + + if (dev->key) + { + (*nclasses)++; + len = ListKeyInfo(dev, (xXIKeyInfo*)any); + any += len; + total_len += len; + } + + for (i = 0; dev->valuator && i < dev->valuator->numAxes; i++) + { + (*nclasses)++; + len = ListValuatorInfo(dev, (xXIValuatorInfo*)any, i, rc == Success); + any += len; + total_len += len; + } + + return total_len; +} + +static void +SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info) +{ + char n; + char *any = (char*)&info[1]; + int i; + + /* Skip over name */ + any += pad_to_int32(info->name_len); + + for (i = 0; i < info->num_classes; i++) + { + int len = ((xXIAnyInfo*)any)->length; + switch(((xXIAnyInfo*)any)->type) + { + case XIButtonClass: + SwapButtonInfo(dev, (xXIButtonInfo*)any); + break; + case XIKeyClass: + SwapKeyInfo(dev, (xXIKeyInfo*)any); + break; + case XIValuatorClass: + SwapValuatorInfo(dev, (xXIValuatorInfo*)any); + break; + } + + any += len * 4; + } + + swaps(&info->deviceid, n); + swaps(&info->use, n); + swaps(&info->attachment, n); + swaps(&info->num_classes, n); + swaps(&info->name_len, n); + +} diff --git a/xorg-server/Xi/xiquerypointer.c b/xorg-server/Xi/xiquerypointer.c index 93ceba4c3..a5855bef3 100644 --- a/xorg-server/Xi/xiquerypointer.c +++ b/xorg-server/Xi/xiquerypointer.c @@ -1,228 +1,228 @@ -/* - * Copyright 2007-2008 Peter Hutterer - * - * 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, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Author: Peter Hutterer, University of South Australia, NICTA - */ - -/*********************************************************************** - * - * Request to query the pointer location of an extension input device. - * - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include /* for inputstr.h */ -#include /* Request macro */ -#include "inputstr.h" /* DeviceIntPtr */ -#include "windowstr.h" /* window structure */ -#include -#include -#include "extnsionst.h" -#include "exevents.h" -#include "exglobals.h" -#include "eventconvert.h" -#include "xkbsrv.h" - -#ifdef PANORAMIX -#include "panoramiXsrv.h" -#endif - -#include "xiquerypointer.h" - -/*********************************************************************** - * - * This procedure allows a client to query the pointer of a device. - * - */ - -int -SProcXIQueryPointer(ClientPtr client) -{ - char n; - - REQUEST(xXIQueryPointerReq); - swaps(&stuff->length, n); - swaps(&stuff->deviceid, n); - swapl(&stuff->win, n); - return (ProcXIQueryPointer(client)); -} - -int -ProcXIQueryPointer(ClientPtr client) -{ - int rc; - xXIQueryPointerReply rep; - DeviceIntPtr pDev, kbd; - WindowPtr pWin, t; - SpritePtr pSprite; - XkbStatePtr state; - char *buttons = NULL; - int buttons_size = 0; /* size of buttons array */ - - REQUEST(xXIQueryPointerReq); - REQUEST_SIZE_MATCH(xXIQueryPointerReq); - - rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixReadAccess); - if (rc != Success) - { - client->errorValue = stuff->deviceid; - return rc; - } - - if (pDev->valuator == NULL || IsKeyboardDevice(pDev) || - (!IsMaster(pDev) && pDev->u.master)) /* no attached devices */ - { - client->errorValue = stuff->deviceid; - return BadDevice; - } - - rc = dixLookupWindow(&pWin, stuff->win, client, DixGetAttrAccess); - if (rc != Success) - { - SendErrorToClient(client, IReqCode, X_XIQueryPointer, - stuff->win, rc); - return Success; - } - - if (pDev->valuator->motionHintWindow) - MaybeStopHint(pDev, client); - - if (IsMaster(pDev)) - kbd = GetPairedDevice(pDev); - else - kbd = (pDev->key) ? pDev : NULL; - - pSprite = pDev->spriteInfo->sprite; - - memset(&rep, 0, sizeof(rep)); - rep.repType = X_Reply; - rep.RepType = X_XIQueryPointer; - rep.length = 6; - rep.sequenceNumber = client->sequence; - rep.root = (GetCurrentRootWindow(pDev))->drawable.id; - rep.root_x = FP1616(pSprite->hot.x, 0); - rep.root_y = FP1616(pSprite->hot.y, 0); - rep.child = None; - - if (kbd) - { - state = &kbd->key->xkbInfo->prev_state; - rep.mods.base_mods = state->base_mods; - rep.mods.latched_mods = state->latched_mods; - rep.mods.locked_mods = state->locked_mods; - - rep.group.base_group = state->base_group; - rep.group.latched_group = state->latched_group; - rep.group.locked_group = state->locked_group; - } - - if (pDev->button) - { - int i, down; - rep.buttons_len = bytes_to_int32(bits_to_bytes(pDev->button->numButtons)); - rep.length += rep.buttons_len; - buttons_size = rep.buttons_len * 4; - buttons = xcalloc(1, buttons_size); - if (!buttons) - return BadAlloc; - - down = pDev->button->buttonsDown; - - for (i = 0; i < pDev->button->numButtons && down; i++) - { - if (BitIsOn(pDev->button->down, i)) - { - SetBit(buttons, i); - down--; - } - } - } else - rep.buttons_len = 0; - - if (pSprite->hot.pScreen == pWin->drawable.pScreen) - { - rep.same_screen = xTrue; - rep.win_x = FP1616(pSprite->hot.x - pWin->drawable.x, 0); - rep.win_y = FP1616(pSprite->hot.y - pWin->drawable.y, 0); - for (t = pSprite->win; t; t = t->parent) - if (t->parent == pWin) - { - rep.child = t->drawable.id; - break; - } - } else - { - rep.same_screen = xFalse; - rep.win_x = 0; - rep.win_y = 0; - } - -#ifdef PANORAMIX - if(!noPanoramiXExtension) { - rep.root_x += FP1616(panoramiXdataPtr[0].x, 0); - rep.root_y += FP1616(panoramiXdataPtr[0].y, 0); - if (stuff->win == rep.root) - { - rep.win_x += FP1616(panoramiXdataPtr[0].x, 0); - rep.win_y += FP1616(panoramiXdataPtr[0].y, 0); - } - } -#endif - - WriteReplyToClient(client, sizeof(xXIQueryPointerReply), &rep); - if (buttons) - WriteToClient(client, buttons_size, buttons); - - xfree(buttons); - - return Success; -} - -/*********************************************************************** - * - * This procedure writes the reply for the XIQueryPointer function, - * if the client and server have a different byte ordering. - * - */ - -void -SRepXIQueryPointer(ClientPtr client, int size, - xXIQueryPointerReply * rep) -{ - char n; - - swaps(&rep->sequenceNumber, n); - swapl(&rep->length, n); - swapl(&rep->root, n); - swapl(&rep->child, n); - swapl(&rep->root_x, n); - swapl(&rep->root_y, n); - swapl(&rep->win_x, n); - swapl(&rep->win_y, n); - swaps(&rep->buttons_len, n); - - WriteToClient(client, size, (char *)rep); -} - +/* + * Copyright 2007-2008 Peter Hutterer + * + * 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, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Author: Peter Hutterer, University of South Australia, NICTA + */ + +/*********************************************************************** + * + * Request to query the pointer location of an extension input device. + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include /* for inputstr.h */ +#include /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include +#include +#include "extnsionst.h" +#include "exevents.h" +#include "exglobals.h" +#include "eventconvert.h" +#include "xkbsrv.h" + +#ifdef PANORAMIX +#include "panoramiXsrv.h" +#endif + +#include "xiquerypointer.h" + +/*********************************************************************** + * + * This procedure allows a client to query the pointer of a device. + * + */ + +int +SProcXIQueryPointer(ClientPtr client) +{ + char n; + + REQUEST(xXIQueryPointerReq); + swaps(&stuff->length, n); + swaps(&stuff->deviceid, n); + swapl(&stuff->win, n); + return (ProcXIQueryPointer(client)); +} + +int +ProcXIQueryPointer(ClientPtr client) +{ + int rc; + xXIQueryPointerReply rep; + DeviceIntPtr pDev, kbd; + WindowPtr pWin, t; + SpritePtr pSprite; + XkbStatePtr state; + char *buttons = NULL; + int buttons_size = 0; /* size of buttons array */ + + REQUEST(xXIQueryPointerReq); + REQUEST_SIZE_MATCH(xXIQueryPointerReq); + + rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixReadAccess); + if (rc != Success) + { + client->errorValue = stuff->deviceid; + return rc; + } + + if (pDev->valuator == NULL || IsKeyboardDevice(pDev) || + (!IsMaster(pDev) && pDev->u.master)) /* no attached devices */ + { + client->errorValue = stuff->deviceid; + return BadDevice; + } + + rc = dixLookupWindow(&pWin, stuff->win, client, DixGetAttrAccess); + if (rc != Success) + { + SendErrorToClient(client, IReqCode, X_XIQueryPointer, + stuff->win, rc); + return Success; + } + + if (pDev->valuator->motionHintWindow) + MaybeStopHint(pDev, client); + + if (IsMaster(pDev)) + kbd = GetPairedDevice(pDev); + else + kbd = (pDev->key) ? pDev : NULL; + + pSprite = pDev->spriteInfo->sprite; + + memset(&rep, 0, sizeof(rep)); + rep.repType = X_Reply; + rep.RepType = X_XIQueryPointer; + rep.length = 6; + rep.sequenceNumber = client->sequence; + rep.root = (GetCurrentRootWindow(pDev))->drawable.id; + rep.root_x = FP1616(pSprite->hot.x, 0); + rep.root_y = FP1616(pSprite->hot.y, 0); + rep.child = None; + + if (kbd) + { + state = &kbd->key->xkbInfo->prev_state; + rep.mods.base_mods = state->base_mods; + rep.mods.latched_mods = state->latched_mods; + rep.mods.locked_mods = state->locked_mods; + + rep.group.base_group = state->base_group; + rep.group.latched_group = state->latched_group; + rep.group.locked_group = state->locked_group; + } + + if (pDev->button) + { + int i, down; + rep.buttons_len = bytes_to_int32(bits_to_bytes(pDev->button->numButtons)); + rep.length += rep.buttons_len; + buttons_size = rep.buttons_len * 4; + buttons = calloc(1, buttons_size); + if (!buttons) + return BadAlloc; + + down = pDev->button->buttonsDown; + + for (i = 0; i < pDev->button->numButtons && down; i++) + { + if (BitIsOn(pDev->button->down, i)) + { + SetBit(buttons, i); + down--; + } + } + } else + rep.buttons_len = 0; + + if (pSprite->hot.pScreen == pWin->drawable.pScreen) + { + rep.same_screen = xTrue; + rep.win_x = FP1616(pSprite->hot.x - pWin->drawable.x, 0); + rep.win_y = FP1616(pSprite->hot.y - pWin->drawable.y, 0); + for (t = pSprite->win; t; t = t->parent) + if (t->parent == pWin) + { + rep.child = t->drawable.id; + break; + } + } else + { + rep.same_screen = xFalse; + rep.win_x = 0; + rep.win_y = 0; + } + +#ifdef PANORAMIX + if(!noPanoramiXExtension) { + rep.root_x += FP1616(panoramiXdataPtr[0].x, 0); + rep.root_y += FP1616(panoramiXdataPtr[0].y, 0); + if (stuff->win == rep.root) + { + rep.win_x += FP1616(panoramiXdataPtr[0].x, 0); + rep.win_y += FP1616(panoramiXdataPtr[0].y, 0); + } + } +#endif + + WriteReplyToClient(client, sizeof(xXIQueryPointerReply), &rep); + if (buttons) + WriteToClient(client, buttons_size, buttons); + + free(buttons); + + return Success; +} + +/*********************************************************************** + * + * This procedure writes the reply for the XIQueryPointer function, + * if the client and server have a different byte ordering. + * + */ + +void +SRepXIQueryPointer(ClientPtr client, int size, + xXIQueryPointerReply * rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swapl(&rep->root, n); + swapl(&rep->child, n); + swapl(&rep->root_x, n); + swapl(&rep->root_y, n); + swapl(&rep->win_x, n); + swapl(&rep->win_y, n); + swaps(&rep->buttons_len, n); + + WriteToClient(client, size, (char *)rep); +} + diff --git a/xorg-server/Xi/xiselectev.c b/xorg-server/Xi/xiselectev.c index 672edab3b..6a810bce4 100644 --- a/xorg-server/Xi/xiselectev.c +++ b/xorg-server/Xi/xiselectev.c @@ -1,299 +1,299 @@ -/* - * Copyright 2008 Red Hat, Inc. - * - * 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, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Author: Peter Hutterer - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - - -#include "dixstruct.h" -#include "windowstr.h" -#include "exglobals.h" -#include "exevents.h" -#include - -#include "xiselectev.h" - -/** - * Check the given mask (in len bytes) for invalid mask bits. - * Invalid mask bits are any bits above XI2LastEvent. - * - * @return BadValue if at least one invalid bit is set or Success otherwise. - */ -int XICheckInvalidMaskBits(unsigned char *mask, int len) -{ - if (len >= XIMaskLen(XI2LASTEVENT)) - { - int i; - for (i = XI2LASTEVENT + 1; i < len * 8; i++) - if (BitIsOn(mask, i)) - return BadValue; - } - - return Success; -} - -int -SProcXISelectEvents(ClientPtr client) -{ - char n; - int i; - xXIEventMask* evmask; - - REQUEST(xXISelectEventsReq); - swaps(&stuff->length, n); - REQUEST_AT_LEAST_SIZE(xXISelectEventsReq); - swapl(&stuff->win, n); - swaps(&stuff->num_masks, n); - - evmask = (xXIEventMask*)&stuff[1]; - for (i = 0; i < stuff->num_masks; i++) - { - swaps(&evmask->deviceid, n); - swaps(&evmask->mask_len, n); - evmask = (xXIEventMask*)(((char*)&evmask[1]) + evmask->mask_len * 4); - } - - return (ProcXISelectEvents(client)); -} - -int -ProcXISelectEvents(ClientPtr client) -{ - int rc, num_masks; - WindowPtr win; - DeviceIntPtr dev; - DeviceIntRec dummy; - xXIEventMask *evmask; - int *types = NULL; - int len; - - REQUEST(xXISelectEventsReq); - REQUEST_AT_LEAST_SIZE(xXISelectEventsReq); - - if (stuff->num_masks == 0) - return BadValue; - - rc = dixLookupWindow(&win, stuff->win, client, DixReceiveAccess); - if (rc != Success) - return rc; - - len = sz_xXISelectEventsReq; - - /* check request validity */ - evmask = (xXIEventMask*)&stuff[1]; - num_masks = stuff->num_masks; - while(num_masks--) - { - len += sizeof(xXIEventMask) + evmask->mask_len * 4; - - if (bytes_to_int32(len) > stuff->length) - return BadLength; - - if (evmask->deviceid != XIAllDevices && - evmask->deviceid != XIAllMasterDevices) - rc = dixLookupDevice(&dev, evmask->deviceid, client, DixUseAccess); - else { - /* XXX: XACE here? */ - } - if (rc != Success) - return rc; - - /* hierarchy event mask is not allowed on devices */ - if (evmask->deviceid != XIAllDevices && evmask->mask_len >= 1) - { - unsigned char *bits = (unsigned char*)&evmask[1]; - if (BitIsOn(bits, XI_HierarchyChanged)) - return BadValue; - } - - /* Raw events may only be selected on root windows */ - if (win->parent && evmask->mask_len >= 1) - { - unsigned char *bits = (unsigned char*)&evmask[1]; - if (BitIsOn(bits, XI_RawKeyPress) || - BitIsOn(bits, XI_RawKeyRelease) || - BitIsOn(bits, XI_RawButtonPress) || - BitIsOn(bits, XI_RawButtonRelease) || - BitIsOn(bits, XI_RawMotion)) - return BadValue; - } - - if (XICheckInvalidMaskBits((unsigned char*)&evmask[1], - evmask->mask_len * 4) != Success) - return BadValue; - - evmask = (xXIEventMask*)(((unsigned char*)evmask) + evmask->mask_len * 4); - evmask++; - } - - if (bytes_to_int32(len) != stuff->length) - return BadLength; - - /* Set masks on window */ - evmask = (xXIEventMask*)&stuff[1]; - num_masks = stuff->num_masks; - while(num_masks--) - { - if (evmask->deviceid == XIAllDevices || - evmask->deviceid == XIAllMasterDevices) - { - dummy.id = evmask->deviceid; - dev = &dummy; - } else - dixLookupDevice(&dev, evmask->deviceid, client, DixUseAccess); - if (XISetEventMask(dev, win, client, evmask->mask_len * 4, - (unsigned char*)&evmask[1]) != Success) - return BadAlloc; - evmask = (xXIEventMask*)(((unsigned char*)evmask) + evmask->mask_len * 4); - evmask++; - } - - RecalculateDeliverableEvents(win); - - xfree(types); - return Success; -} - - -int -SProcXIGetSelectedEvents(ClientPtr client) -{ - char n; - - REQUEST(xXIGetSelectedEventsReq); - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xXIGetSelectedEventsReq); - swapl(&stuff->win, n); - - return (ProcXIGetSelectedEvents(client)); -} - -int -ProcXIGetSelectedEvents(ClientPtr client) -{ - int rc, i; - WindowPtr win; - char n; - char *buffer = NULL; - xXIGetSelectedEventsReply reply; - OtherInputMasks *masks; - InputClientsPtr others = NULL; - xXIEventMask *evmask = NULL; - DeviceIntPtr dev; - - REQUEST(xXIGetSelectedEventsReq); - REQUEST_SIZE_MATCH(xXIGetSelectedEventsReq); - - rc = dixLookupWindow(&win, stuff->win, client, DixGetAttrAccess); - if (rc != Success) - return rc; - - reply.repType = X_Reply; - reply.RepType = X_XIGetSelectedEvents; - reply.length = 0; - reply.sequenceNumber = client->sequence; - reply.num_masks = 0; - - masks = wOtherInputMasks(win); - if (masks) - { - for (others = wOtherInputMasks(win)->inputClients; others; - others = others->next) { - if (SameClient(others, client)) { - break; - } - } - } - - if (!others) - { - WriteReplyToClient(client, sizeof(xXIGetSelectedEventsReply), &reply); - return Success; - } - - buffer = xcalloc(MAXDEVICES, sizeof(xXIEventMask) + pad_to_int32(XI2MASKSIZE)); - if (!buffer) - return BadAlloc; - - evmask = (xXIEventMask*)buffer; - for (i = 0; i < MAXDEVICES; i++) - { - int j; - unsigned char *devmask = others->xi2mask[i]; - - if (i > 2) - { - rc = dixLookupDevice(&dev, i, client, DixGetAttrAccess); - if (rc != Success) - continue; - } - - - for (j = XI2MASKSIZE - 1; j >= 0; j--) - { - if (devmask[j] != 0) - { - int mask_len = (j + 4)/4; /* j is an index, hence + 4, not + 3 */ - evmask->deviceid = i; - evmask->mask_len = mask_len; - reply.num_masks++; - reply.length += sizeof(xXIEventMask)/4 + evmask->mask_len; - - if (client->swapped) - { - swaps(&evmask->deviceid, n); - swaps(&evmask->mask_len, n); - } - - memcpy(&evmask[1], devmask, j + 1); - evmask = (xXIEventMask*)((char*)evmask + - sizeof(xXIEventMask) + mask_len * 4); - break; - } - } - } - - WriteReplyToClient(client, sizeof(xXIGetSelectedEventsReply), &reply); - - if (reply.num_masks) - WriteToClient(client, reply.length * 4, buffer); - - xfree(buffer); - return Success; -} - -void SRepXIGetSelectedEvents(ClientPtr client, - int len, xXIGetSelectedEventsReply *rep) -{ - char n; - - swaps(&rep->sequenceNumber, n); - swapl(&rep->length, n); - swaps(&rep->num_masks, n); - WriteToClient(client, len, (char *)rep); -} - - +/* + * Copyright 2008 Red Hat, Inc. + * + * 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, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Author: Peter Hutterer + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + + +#include "dixstruct.h" +#include "windowstr.h" +#include "exglobals.h" +#include "exevents.h" +#include + +#include "xiselectev.h" + +/** + * Check the given mask (in len bytes) for invalid mask bits. + * Invalid mask bits are any bits above XI2LastEvent. + * + * @return BadValue if at least one invalid bit is set or Success otherwise. + */ +int XICheckInvalidMaskBits(unsigned char *mask, int len) +{ + if (len >= XIMaskLen(XI2LASTEVENT)) + { + int i; + for (i = XI2LASTEVENT + 1; i < len * 8; i++) + if (BitIsOn(mask, i)) + return BadValue; + } + + return Success; +} + +int +SProcXISelectEvents(ClientPtr client) +{ + char n; + int i; + xXIEventMask* evmask; + + REQUEST(xXISelectEventsReq); + swaps(&stuff->length, n); + REQUEST_AT_LEAST_SIZE(xXISelectEventsReq); + swapl(&stuff->win, n); + swaps(&stuff->num_masks, n); + + evmask = (xXIEventMask*)&stuff[1]; + for (i = 0; i < stuff->num_masks; i++) + { + swaps(&evmask->deviceid, n); + swaps(&evmask->mask_len, n); + evmask = (xXIEventMask*)(((char*)&evmask[1]) + evmask->mask_len * 4); + } + + return (ProcXISelectEvents(client)); +} + +int +ProcXISelectEvents(ClientPtr client) +{ + int rc, num_masks; + WindowPtr win; + DeviceIntPtr dev; + DeviceIntRec dummy; + xXIEventMask *evmask; + int *types = NULL; + int len; + + REQUEST(xXISelectEventsReq); + REQUEST_AT_LEAST_SIZE(xXISelectEventsReq); + + if (stuff->num_masks == 0) + return BadValue; + + rc = dixLookupWindow(&win, stuff->win, client, DixReceiveAccess); + if (rc != Success) + return rc; + + len = sz_xXISelectEventsReq; + + /* check request validity */ + evmask = (xXIEventMask*)&stuff[1]; + num_masks = stuff->num_masks; + while(num_masks--) + { + len += sizeof(xXIEventMask) + evmask->mask_len * 4; + + if (bytes_to_int32(len) > stuff->length) + return BadLength; + + if (evmask->deviceid != XIAllDevices && + evmask->deviceid != XIAllMasterDevices) + rc = dixLookupDevice(&dev, evmask->deviceid, client, DixUseAccess); + else { + /* XXX: XACE here? */ + } + if (rc != Success) + return rc; + + /* hierarchy event mask is not allowed on devices */ + if (evmask->deviceid != XIAllDevices && evmask->mask_len >= 1) + { + unsigned char *bits = (unsigned char*)&evmask[1]; + if (BitIsOn(bits, XI_HierarchyChanged)) + return BadValue; + } + + /* Raw events may only be selected on root windows */ + if (win->parent && evmask->mask_len >= 1) + { + unsigned char *bits = (unsigned char*)&evmask[1]; + if (BitIsOn(bits, XI_RawKeyPress) || + BitIsOn(bits, XI_RawKeyRelease) || + BitIsOn(bits, XI_RawButtonPress) || + BitIsOn(bits, XI_RawButtonRelease) || + BitIsOn(bits, XI_RawMotion)) + return BadValue; + } + + if (XICheckInvalidMaskBits((unsigned char*)&evmask[1], + evmask->mask_len * 4) != Success) + return BadValue; + + evmask = (xXIEventMask*)(((unsigned char*)evmask) + evmask->mask_len * 4); + evmask++; + } + + if (bytes_to_int32(len) != stuff->length) + return BadLength; + + /* Set masks on window */ + evmask = (xXIEventMask*)&stuff[1]; + num_masks = stuff->num_masks; + while(num_masks--) + { + if (evmask->deviceid == XIAllDevices || + evmask->deviceid == XIAllMasterDevices) + { + dummy.id = evmask->deviceid; + dev = &dummy; + } else + dixLookupDevice(&dev, evmask->deviceid, client, DixUseAccess); + if (XISetEventMask(dev, win, client, evmask->mask_len * 4, + (unsigned char*)&evmask[1]) != Success) + return BadAlloc; + evmask = (xXIEventMask*)(((unsigned char*)evmask) + evmask->mask_len * 4); + evmask++; + } + + RecalculateDeliverableEvents(win); + + free(types); + return Success; +} + + +int +SProcXIGetSelectedEvents(ClientPtr client) +{ + char n; + + REQUEST(xXIGetSelectedEventsReq); + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xXIGetSelectedEventsReq); + swapl(&stuff->win, n); + + return (ProcXIGetSelectedEvents(client)); +} + +int +ProcXIGetSelectedEvents(ClientPtr client) +{ + int rc, i; + WindowPtr win; + char n; + char *buffer = NULL; + xXIGetSelectedEventsReply reply; + OtherInputMasks *masks; + InputClientsPtr others = NULL; + xXIEventMask *evmask = NULL; + DeviceIntPtr dev; + + REQUEST(xXIGetSelectedEventsReq); + REQUEST_SIZE_MATCH(xXIGetSelectedEventsReq); + + rc = dixLookupWindow(&win, stuff->win, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + reply.repType = X_Reply; + reply.RepType = X_XIGetSelectedEvents; + reply.length = 0; + reply.sequenceNumber = client->sequence; + reply.num_masks = 0; + + masks = wOtherInputMasks(win); + if (masks) + { + for (others = wOtherInputMasks(win)->inputClients; others; + others = others->next) { + if (SameClient(others, client)) { + break; + } + } + } + + if (!others) + { + WriteReplyToClient(client, sizeof(xXIGetSelectedEventsReply), &reply); + return Success; + } + + buffer = calloc(MAXDEVICES, sizeof(xXIEventMask) + pad_to_int32(XI2MASKSIZE)); + if (!buffer) + return BadAlloc; + + evmask = (xXIEventMask*)buffer; + for (i = 0; i < MAXDEVICES; i++) + { + int j; + unsigned char *devmask = others->xi2mask[i]; + + if (i > 2) + { + rc = dixLookupDevice(&dev, i, client, DixGetAttrAccess); + if (rc != Success) + continue; + } + + + for (j = XI2MASKSIZE - 1; j >= 0; j--) + { + if (devmask[j] != 0) + { + int mask_len = (j + 4)/4; /* j is an index, hence + 4, not + 3 */ + evmask->deviceid = i; + evmask->mask_len = mask_len; + reply.num_masks++; + reply.length += sizeof(xXIEventMask)/4 + evmask->mask_len; + + if (client->swapped) + { + swaps(&evmask->deviceid, n); + swaps(&evmask->mask_len, n); + } + + memcpy(&evmask[1], devmask, j + 1); + evmask = (xXIEventMask*)((char*)evmask + + sizeof(xXIEventMask) + mask_len * 4); + break; + } + } + } + + WriteReplyToClient(client, sizeof(xXIGetSelectedEventsReply), &reply); + + if (reply.num_masks) + WriteToClient(client, reply.length * 4, buffer); + + free(buffer); + return Success; +} + +void SRepXIGetSelectedEvents(ClientPtr client, + int len, xXIGetSelectedEventsReply *rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->num_masks, n); + WriteToClient(client, len, (char *)rep); +} + + -- cgit v1.2.3