diff options
Diffstat (limited to 'xorg-server/dix')
-rw-r--r-- | xorg-server/dix/Xserver-dtrace.h | 75 | ||||
-rw-r--r-- | xorg-server/dix/colormap.c | 4 | ||||
-rw-r--r-- | xorg-server/dix/devices.c | 5216 | ||||
-rw-r--r-- | xorg-server/dix/dispatch.c | 51 | ||||
-rw-r--r-- | xorg-server/dix/dixfonts.c | 108 | ||||
-rw-r--r-- | xorg-server/dix/eventconvert.c | 1492 | ||||
-rw-r--r-- | xorg-server/dix/events.c | 8 | ||||
-rw-r--r-- | xorg-server/dix/gc.c | 20 | ||||
-rw-r--r-- | xorg-server/dix/getevents.c | 17 | ||||
-rw-r--r-- | xorg-server/dix/inpututils.c | 6 | ||||
-rw-r--r-- | xorg-server/dix/main.c | 46 | ||||
-rw-r--r-- | xorg-server/dix/makefile | 41 | ||||
-rw-r--r-- | xorg-server/dix/privates.c | 91 | ||||
-rw-r--r-- | xorg-server/dix/ptrveloc.c | 9 | ||||
-rw-r--r-- | xorg-server/dix/registry.c | 1 | ||||
-rw-r--r-- | xorg-server/dix/resource.c | 61 |
16 files changed, 3785 insertions, 3461 deletions
diff --git a/xorg-server/dix/Xserver-dtrace.h b/xorg-server/dix/Xserver-dtrace.h new file mode 100644 index 000000000..0ced498af --- /dev/null +++ b/xorg-server/dix/Xserver-dtrace.h @@ -0,0 +1,75 @@ +/* Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +/* + * Generated by dtrace(1M), and then modified for backwards compatibility + * with older versions of dtrace. Used if dtrace -h fails. + * (Since _ENABLED support was added after dtrace -h, this assumes if + * dtrace -h fails, _ENABLED will too.) + */ + +#ifndef _XSERVER_DTRACE_H +#define _XSERVER_DTRACE_H + +#include <unistd.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define XSERVER_CLIENT_AUTH(arg0, arg1, arg2, arg3) \ + winDebug4("XSERVER_CLIENT_AUTH: %d %s %d %d\n",arg0, arg1, arg2, arg3) +#define XSERVER_CLIENT_CONNECT(arg0, arg1) \ + winDebug4("XSERVER_CLIENT_CONNECT: %d %d\n",arg0, arg1) +#define XSERVER_CLIENT_DISCONNECT(arg0) \ + winDebug4("XSERVER_CLIENT_DISCONNECT: %d %d\n",arg0) +#define XSERVER_REQUEST_DONE(arg0, arg1, arg2, arg3, arg4) \ + winDebug4("XSERVER_REQUEST_DONE: %s %d %d %d %d\n",arg0, arg1, arg2, arg3, arg4) +#define XSERVER_REQUEST_START(arg0, arg1, arg2, arg3, arg4) \ + winDebug4("XSERVER_REQUEST_START: %s %d %d %d ->%p\n",arg0, arg1, arg2, arg3, arg4) +#define XSERVER_RESOURCE_ALLOC(arg0, arg1, arg2, arg3) \ + winDebug4("XSERVER_RESOURCE_ALLOC: 0x%x 0x%x ->%p %s\n",arg0, arg1, arg2, arg3) +#define XSERVER_RESOURCE_FREE(arg0, arg1, arg2, arg3) \ + winDebug4("XSERVER_RESOURCE_FREE: 0x%x 0x%x ->%p %s\n",arg0, arg1, arg2, arg3) +#define XSERVER_SEND_EVENT(arg0, arg1, arg2) \ + winDebug4("XSERVER_SEND_EVENT: 0x%x 0x%x ->%p\n",arg0, arg1, arg2) + +#define XSERVER_CLIENT_AUTH_ENABLED() (1) +#define XSERVER_CLIENT_CONNECT_ENABLED() (1) +#define XSERVER_CLIENT_DISCONNECT_ENABLED() (1) +#define XSERVER_REQUEST_DONE_ENABLED() (1) +#define XSERVER_REQUEST_START_ENABLED() (1) +#define XSERVER_RESOURCE_ALLOC_ENABLED() (1) +#define XSERVER_RESOURCE_FREE_ENABLED() (1) +#define XSERVER_SEND_EVENT_ENABLED() (1) + +#ifdef __cplusplus +} +#endif + +#endif /* _XSERVER_DTRACE_H */ diff --git a/xorg-server/dix/colormap.c b/xorg-server/dix/colormap.c index b04739ad0..d8c702703 100644 --- a/xorg-server/dix/colormap.c +++ b/xorg-server/dix/colormap.c @@ -66,6 +66,10 @@ SOFTWARE. #include "privates.h"
#include "xace.h"
+#ifdef _MSC_VER
+#define UpdateColors thisUpdateColors
+#endif
+
static Pixel FindBestPixel(
EntryPtr /*pentFirst*/,
int /*size*/,
diff --git a/xorg-server/dix/devices.c b/xorg-server/dix/devices.c index 89294aacb..1c2cc9807 100644 --- a/xorg-server/dix/devices.c +++ b/xorg-server/dix/devices.c @@ -1,2604 +1,2612 @@ -/************************************************************ - -Copyright 1987, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -********************************************************/ - - - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <X11/X.h> -#include "misc.h" -#include "resource.h" -#include <X11/Xproto.h> -#include <X11/Xatom.h> -#include "windowstr.h" -#include "inputstr.h" -#include "scrnintstr.h" -#include "cursorstr.h" -#include "dixstruct.h" -#include "ptrveloc.h" -#include "site.h" -#include "xkbsrv.h" -#include "privates.h" -#include "xace.h" -#include "mi.h" - -#include "dispatch.h" -#include "swaprep.h" -#include "dixevents.h" -#include "mipointer.h" -#include "eventstr.h" - -#include <X11/extensions/XI.h> -#include <X11/extensions/XI2.h> -#include <X11/extensions/XIproto.h> -#include <math.h> -#include <pixman.h> -#include "exglobals.h" -#include "exevents.h" -#include "xiquerydevice.h" /* for SizeDeviceClasses */ -#include "xiproperty.h" -#include "enterleave.h" /* for EnterWindow() */ -#include "xserver-properties.h" -#include "xichangehierarchy.h" /* For XISendDeviceHierarchyEvent */ - -/** @file - * This file handles input device-related stuff. - */ - -static void RecalculateMasterButtons(DeviceIntPtr slave); - -static void -DeviceSetTransform(DeviceIntPtr dev, float *transform) -{ - struct pixman_f_transform scale; - double sx, sy; - int x, y; - - /** - * calculate combined transformation matrix: - * - * M = InvScale * Transform * Scale - * - * So we can later transform points using M * p - * - * Where: - * Scale scales coordinates into 0..1 range - * Transform is the user supplied (affine) transform - * InvScale scales coordinates back up into their native range - */ - sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].min_value; - sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value; - - /* invscale */ - pixman_f_transform_init_scale(&scale, sx, sy); - scale.m[0][2] = dev->valuator->axes[0].min_value; - scale.m[1][2] = dev->valuator->axes[1].min_value; - - /* transform */ - for (y=0; y<3; y++) - for (x=0; x<3; x++) - dev->transform.m[y][x] = *transform++; - - pixman_f_transform_multiply(&dev->transform, &scale, &dev->transform); - - /* scale */ - pixman_f_transform_init_scale(&scale, 1.0 / sx, 1.0 / sy); - scale.m[0][2] = -dev->valuator->axes[0].min_value / sx; - scale.m[1][2] = -dev->valuator->axes[1].min_value / sy; - - pixman_f_transform_multiply(&dev->transform, &dev->transform, &scale); -} - -/** - * DIX property handler. - */ -static int -DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, - BOOL checkonly) -{ - if (property == XIGetKnownProperty(XI_PROP_ENABLED)) - { - if (prop->format != 8 || prop->type != XA_INTEGER || prop->size != 1) - return BadValue; - - /* Don't allow disabling of VCP/VCK */ - if ((dev == inputInfo.pointer || dev == inputInfo.keyboard) && - !(*(CARD8*)prop->data)) - return BadAccess; - - if (!checkonly) - { - if ((*((CARD8*)prop->data)) && !dev->enabled) - EnableDevice(dev, TRUE); - else if (!(*((CARD8*)prop->data)) && dev->enabled) - DisableDevice(dev, TRUE); - } - } else if (property == XIGetKnownProperty(XI_PROP_TRANSFORM)) - { - float *f = (float*)prop->data; - int i; - - if (prop->format != 32 || prop->size != 9 || - prop->type != XIGetKnownProperty(XATOM_FLOAT)) - return BadValue; - - for (i=0; i<9; i++) - if (!isfinite(f[i])) - return BadValue; - - if (!checkonly) - DeviceSetTransform(dev, f); - } - - return Success; -} - -/* Pair the keyboard to the pointer device. Keyboard events will follow the - * pointer sprite. Only applicable for master devices. - * If the client is set, the request to pair comes from some client. In this - * case, we need to check for access. If the client is NULL, it's from an - * internal automatic pairing, we must always permit this. - */ -static int -PairDevices(ClientPtr client, DeviceIntPtr ptr, DeviceIntPtr kbd) -{ - if (!ptr) - return BadDevice; - - /* Don't allow pairing for slave devices */ - if (!IsMaster(ptr) || !IsMaster(kbd)) - return BadDevice; - - if (ptr->spriteInfo->paired) - return BadDevice; - - if (kbd->spriteInfo->spriteOwner) - { - free(kbd->spriteInfo->sprite); - kbd->spriteInfo->sprite = NULL; - kbd->spriteInfo->spriteOwner = FALSE; - } - - kbd->spriteInfo->sprite = ptr->spriteInfo->sprite; - kbd->spriteInfo->paired = ptr; - ptr->spriteInfo->paired = kbd; - return Success; -} - - -/** - * Find and return the next unpaired MD pointer device. - */ -static DeviceIntPtr -NextFreePointerDevice(void) -{ - DeviceIntPtr dev; - for (dev = inputInfo.devices; dev; dev = dev->next) - if (IsMaster(dev) && - dev->spriteInfo->spriteOwner && - !dev->spriteInfo->paired) - return dev; - return NULL; -} - -/** - * Create a new input device and init it to sane values. The device is added - * to the server's off_devices list. - * - * @param deviceProc Callback for device control function (switch dev on/off). - * @return The newly created device. - */ -DeviceIntPtr -AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart) -{ - DeviceIntPtr dev, *prev; /* not a typo */ - DeviceIntPtr devtmp; - int devid; - char devind[MAXDEVICES]; - BOOL enabled; - float transform[9]; - - /* Find next available id, 0 and 1 are reserved */ - memset(devind, 0, sizeof(char)*MAXDEVICES); - for (devtmp = inputInfo.devices; devtmp; devtmp = devtmp->next) - devind[devtmp->id]++; - for (devtmp = inputInfo.off_devices; devtmp; devtmp = devtmp->next) - devind[devtmp->id]++; - for (devid = 2; devid < MAXDEVICES && devind[devid]; devid++) - ; - - if (devid >= MAXDEVICES) - return (DeviceIntPtr)NULL; - dev = _dixAllocateObjectWithPrivates(sizeof(DeviceIntRec) + sizeof(SpriteInfoRec), - sizeof(DeviceIntRec) + sizeof(SpriteInfoRec), - offsetof(DeviceIntRec, devPrivates), PRIVATE_DEVICE); - if (!dev) - return (DeviceIntPtr)NULL; - dev->id = devid; - dev->public.processInputProc = ProcessOtherEvent; - dev->public.realInputProc = ProcessOtherEvent; - dev->public.enqueueInputProc = EnqueueEvent; - dev->deviceProc = deviceProc; - dev->startup = autoStart; - - /* device grab defaults */ - dev->deviceGrab.grabTime = currentTime; - dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab; - dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab; - - XkbSetExtension(dev, ProcessKeyboardEvent); - - dev->coreEvents = TRUE; - - /* sprite defaults */ - dev->spriteInfo = (SpriteInfoPtr)&dev[1]; - - /* security creation/labeling check - */ - if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixCreateAccess)) { - free(dev); - return NULL; - } - - inputInfo.numDevices++; - - for (prev = &inputInfo.off_devices; *prev; prev = &(*prev)->next) - ; - *prev = dev; - dev->next = NULL; - - enabled = FALSE; - XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED), - XA_INTEGER, 8, PropModeReplace, 1, &enabled, - FALSE); - XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_ENABLED), FALSE); - - /* unity matrix */ - memset(transform, 0, sizeof(transform)); - transform[0] = transform[4] = transform[8] = 1.0f; - - XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_TRANSFORM), - XIGetKnownProperty(XATOM_FLOAT), 32, - PropModeReplace, 9, transform, FALSE); - XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_TRANSFORM), - FALSE); - - XIRegisterPropertyHandler(dev, DeviceSetProperty, NULL, NULL); - - return dev; -} - -void -SendDevicePresenceEvent(int deviceid, int type) -{ - DeviceIntRec dummyDev; - devicePresenceNotify ev; - - memset(&dummyDev, 0, sizeof(DeviceIntRec)); - ev.type = DevicePresenceNotify; - ev.time = currentTime.milliseconds; - ev.devchange = type; - ev.deviceid = deviceid; - dummyDev.id = XIAllDevices; - SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask, - (xEvent*)&ev, 1); -} - -/** - * Enable the device through the driver, add the device to the device list. - * Switch device ON through the driver and push it onto the global device - * list. Initialize the DIX sprite or pair the device. All clients are - * notified about the device being enabled. - * - * A master pointer device needs to be enabled before a master keyboard - * device. - * - * @param The device to be enabled. - * @param sendevent True if an XI2 event should be sent. - * @return TRUE on success or FALSE otherwise. - */ -Bool -EnableDevice(DeviceIntPtr dev, BOOL sendevent) -{ - DeviceIntPtr *prev; - int ret; - DeviceIntPtr other; - BOOL enabled; - int flags[MAXDEVICES] = {0}; - - for (prev = &inputInfo.off_devices; - *prev && (*prev != dev); - prev = &(*prev)->next) - ; - - if (!dev->spriteInfo->sprite) - { - if (IsMaster(dev)) - { - /* Sprites appear on first root window, so we can hardcode it */ - if (dev->spriteInfo->spriteOwner) - { - InitializeSprite(dev, screenInfo.screens[0]->root); - /* mode doesn't matter */ - EnterWindow(dev, screenInfo.screens[0]->root, NotifyAncestor); - } - else if ((other = NextFreePointerDevice()) == NULL) - { - ErrorF("[dix] cannot find pointer to pair with. " - "This is a bug.\n"); - return FALSE; - } else - PairDevices(NULL, other, dev); - } else - { - if (dev->coreEvents) - other = (IsPointerDevice(dev)) ? inputInfo.pointer : - inputInfo.keyboard; - else - other = NULL; /* auto-float non-core devices */ - AttachDevice(NULL, dev, other); - } - } - - if ((*prev != dev) || !dev->inited || - ((ret = (*dev->deviceProc)(dev, DEVICE_ON)) != Success)) { - ErrorF("[dix] couldn't enable device %d\n", dev->id); - return FALSE; - } - dev->enabled = TRUE; - *prev = dev->next; - - for (prev = &inputInfo.devices; *prev; prev = &(*prev)->next) - ; - *prev = dev; - dev->next = NULL; - - enabled = TRUE; - XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED), - XA_INTEGER, 8, PropModeReplace, 1, &enabled, - TRUE); - - SendDevicePresenceEvent(dev->id, DeviceEnabled); - if (sendevent) - { - flags[dev->id] |= XIDeviceEnabled; - XISendDeviceHierarchyEvent(flags); - } - - RecalculateMasterButtons(dev); - - return TRUE; -} - -/** - * Switch a device off through the driver and push it onto the off_devices - * list. A device will not send events while disabled. All clients are - * notified about the device being disabled. - * - * Master keyboard devices have to be disabled before master pointer devices - * otherwise things turn bad. - * - * @param sendevent True if an XI2 event should be sent. - * @return TRUE on success or FALSE otherwise. - */ -Bool -DisableDevice(DeviceIntPtr dev, BOOL sendevent) -{ - DeviceIntPtr *prev, other; - BOOL enabled; - int flags[MAXDEVICES] = {0}; - - for (prev = &inputInfo.devices; - *prev && (*prev != dev); - prev = &(*prev)->next) - ; - if (*prev != dev) - return FALSE; - - /* float attached devices */ - if (IsMaster(dev)) - { - for (other = inputInfo.devices; other; other = other->next) - { - if (other->u.master == dev) - { - AttachDevice(NULL, other, NULL); - flags[other->id] |= XISlaveDetached; - } - } - } - else - { - for (other = inputInfo.devices; other; other = other->next) - { - if (IsMaster(other) && other->u.lastSlave == dev) - other->u.lastSlave = NULL; - } - } - - if (IsMaster(dev) && dev->spriteInfo->sprite) - { - for (other = inputInfo.devices; other; other = other->next) - { - if (other->spriteInfo->paired == dev) - { - ErrorF("[dix] cannot disable device, still paired. " - "This is a bug. \n"); - return FALSE; - } - } - } - - (void)(*dev->deviceProc)(dev, DEVICE_OFF); - dev->enabled = FALSE; - - /* now that the device is disabled, we can reset the signal handler's - * last.slave */ - OsBlockSignals(); - for (other = inputInfo.devices; other; other = other->next) - { - if (other->last.slave == dev) - other->last.slave = NULL; - } - OsReleaseSignals(); - - LeaveWindow(dev); - SetFocusOut(dev); - - *prev = dev->next; - dev->next = inputInfo.off_devices; - inputInfo.off_devices = dev; - - enabled = FALSE; - XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED), - XA_INTEGER, 8, PropModeReplace, 1, &enabled, - TRUE); - - SendDevicePresenceEvent(dev->id, DeviceDisabled); - if (sendevent) - { - flags[dev->id] = XIDeviceDisabled; - XISendDeviceHierarchyEvent(flags); - } - - RecalculateMasterButtons(dev); - - return TRUE; -} - -/** - * Initialise a new device through the driver and tell all clients about the - * new device. - * - * Must be called before EnableDevice. - * The device will NOT send events until it is enabled! - * - * @param sendevent True if an XI2 event should be sent. - * @return Success or an error code on failure. - */ -int -ActivateDevice(DeviceIntPtr dev, BOOL sendevent) -{ - int ret = Success; - ScreenPtr pScreen = screenInfo.screens[0]; - - if (!dev || !dev->deviceProc) - return BadImplementation; - - ret = (*dev->deviceProc) (dev, DEVICE_INIT); - dev->inited = (ret == Success); - if (!dev->inited) - return ret; - - /* Initialize memory for sprites. */ - if (IsMaster(dev) && dev->spriteInfo->spriteOwner) - if (!pScreen->DeviceCursorInitialize(dev, pScreen)) - ret = BadAlloc; - - SendDevicePresenceEvent(dev->id, DeviceAdded); - if (sendevent) - { - int flags[MAXDEVICES] = {0}; - flags[dev->id] = XISlaveAdded; - XISendDeviceHierarchyEvent(flags); - } - return ret; -} - -/** - * Ring the bell. - * The actual task of ringing the bell is the job of the DDX. - */ -static void -CoreKeyboardBell(int volume, DeviceIntPtr pDev, pointer arg, int something) -{ - KeybdCtrl *ctrl = arg; - - DDXRingBell(volume, ctrl->bell_pitch, ctrl->bell_duration); -} - -static void -CoreKeyboardCtl(DeviceIntPtr pDev, KeybdCtrl *ctrl) -{ - return; -} - -/** - * Device control function for the Virtual Core Keyboard. - */ -int -CoreKeyboardProc(DeviceIntPtr pDev, int what) -{ - - switch (what) { - case DEVICE_INIT: - if (!InitKeyboardDeviceStruct(pDev, NULL, CoreKeyboardBell, - CoreKeyboardCtl)) - { - ErrorF("Keyboard initialization failed. This could be a missing " - "or incorrect setup of xkeyboard-config.\n"); - return BadValue; - } - return Success; - - case DEVICE_ON: - case DEVICE_OFF: - return Success; - - case DEVICE_CLOSE: - return Success; - } - - return BadMatch; -} - -/** - * Device control function for the Virtual Core Pointer. - */ -int -CorePointerProc(DeviceIntPtr pDev, int what) -{ -#define NBUTTONS 10 -#define NAXES 2 - BYTE map[NBUTTONS + 1]; - int i = 0; - Atom btn_labels[NBUTTONS] = {0}; - Atom axes_labels[NAXES] = {0}; - - switch (what) { - case DEVICE_INIT: - for (i = 1; i <= NBUTTONS; i++) - map[i] = i; - - btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); - btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); - btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); - btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); - btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); - btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT); - btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT); - /* don't know about the rest */ - - axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); - axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); - - if (!InitPointerDeviceStruct((DevicePtr)pDev, map, NBUTTONS, btn_labels, - (PtrCtrlProcPtr)NoopDDA, - GetMotionHistorySize(), NAXES, axes_labels)) - { - ErrorF("Could not initialize device '%s'. Out of memory.\n", - pDev->name); - return BadAlloc; /* IPDS only fails on allocs */ - } - pDev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2; - pDev->last.valuators[0] = pDev->valuator->axisVal[0]; - pDev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2; - pDev->last.valuators[1] = pDev->valuator->axisVal[1]; - break; - - case DEVICE_CLOSE: - break; - - default: - break; - } - - return Success; - -#undef NBUTTONS -#undef NAXES -} - -/** - * Initialise the two core devices, VCP and VCK (see events.c). - * Both devices are not tied to physical devices, but guarantee that there is - * always a keyboard and a pointer present and keep the protocol semantics. - * - * Note that the server MUST have two core devices at all times, even if there - * is no physical device connected. - */ -void -InitCoreDevices(void) -{ - if (AllocDevicePair(serverClient, "Virtual core", - &inputInfo.pointer, &inputInfo.keyboard, - CorePointerProc, CoreKeyboardProc, - TRUE) != Success) - FatalError("Failed to allocate core devices"); - - if (ActivateDevice(inputInfo.pointer, TRUE) != Success || - ActivateDevice(inputInfo.keyboard, TRUE) != Success) - FatalError("Failed to activate core devices."); - if (!EnableDevice(inputInfo.pointer, TRUE) || - !EnableDevice(inputInfo.keyboard, TRUE)) - FatalError("Failed to enable core devices."); - - InitXTestDevices(); -} - -/** - * Activate all switched-off devices and then enable all those devices. - * - * Will return an error if no core keyboard or core pointer is present. - * In theory this should never happen if you call InitCoreDevices() first. - * - * InitAndStartDevices needs to be called AFTER the windows are initialized. - * Devices will start sending events after InitAndStartDevices() has - * completed. - * - * @return Success or error code on failure. - */ -int -InitAndStartDevices(void) -{ - DeviceIntPtr dev, next; - - for (dev = inputInfo.off_devices; dev; dev = dev->next) { - DebugF("(dix) initialising device %d\n", dev->id); - if (!dev->inited) - ActivateDevice(dev, TRUE); - } - - /* enable real devices */ - for (dev = inputInfo.off_devices; dev; dev = next) - { - DebugF("(dix) enabling device %d\n", dev->id); - next = dev->next; - if (dev->inited && dev->startup) - EnableDevice(dev, TRUE); - } - - return Success; -} - -/** - * Free the given device class and reset the pointer to NULL. - */ -static void -FreeDeviceClass(int type, pointer *class) -{ - if (!(*class)) - return; - - switch(type) - { - case KeyClass: - { - KeyClassPtr* k = (KeyClassPtr*)class; - if ((*k)->xkbInfo) - { - XkbFreeInfo((*k)->xkbInfo); - (*k)->xkbInfo = NULL; - } - free((*k)); - break; - } - case ButtonClass: - { - ButtonClassPtr *b = (ButtonClassPtr*)class; - free((*b)->xkb_acts); - free((*b)); - break; - } - case ValuatorClass: - { - ValuatorClassPtr *v = (ValuatorClassPtr*)class; - - free((*v)->motion); - free((*v)); - break; - } - case FocusClass: - { - FocusClassPtr *f = (FocusClassPtr*)class; - free((*f)->trace); - free((*f)); - break; - } - case ProximityClass: - { - ProximityClassPtr *p = (ProximityClassPtr*)class; - free((*p)); - break; - } - } - *class = NULL; -} - -static void -FreeFeedbackClass(int type, pointer *class) -{ - if (!(*class)) - return; - - switch(type) - { - case KbdFeedbackClass: - { - KbdFeedbackPtr *kbdfeed = (KbdFeedbackPtr*)class; - KbdFeedbackPtr k, knext; - for (k = (*kbdfeed); k; k = knext) { - knext = k->next; - if (k->xkb_sli) - XkbFreeSrvLedInfo(k->xkb_sli); - free(k); - } - break; - } - case PtrFeedbackClass: - { - PtrFeedbackPtr *ptrfeed = (PtrFeedbackPtr*)class; - PtrFeedbackPtr p, pnext; - - for (p = (*ptrfeed); p; p = pnext) { - pnext = p->next; - free(p); - } - break; - } - case IntegerFeedbackClass: - { - IntegerFeedbackPtr *intfeed = (IntegerFeedbackPtr*)class; - IntegerFeedbackPtr i, inext; - - for (i = (*intfeed); i; i = inext) { - inext = i->next; - free(i); - } - break; - } - case StringFeedbackClass: - { - StringFeedbackPtr *stringfeed = (StringFeedbackPtr*)class; - StringFeedbackPtr s, snext; - - for (s = (*stringfeed); s; s = snext) { - snext = s->next; - free(s->ctrl.symbols_supported); - free(s->ctrl.symbols_displayed); - free(s); - } - break; - } - case BellFeedbackClass: - { - BellFeedbackPtr *bell = (BellFeedbackPtr*)class; - BellFeedbackPtr b, bnext; - - for (b = (*bell); b; b = bnext) { - bnext = b->next; - free(b); - } - break; - } - case LedFeedbackClass: - { - LedFeedbackPtr *leds = (LedFeedbackPtr*)class; - LedFeedbackPtr l, lnext; - - for (l = (*leds); l; l = lnext) { - lnext = l->next; - if (l->xkb_sli) - XkbFreeSrvLedInfo(l->xkb_sli); - free(l); - } - break; - } - } - *class = NULL; -} - -static void -FreeAllDeviceClasses(ClassesPtr classes) -{ - if (!classes) - return; - - FreeDeviceClass(KeyClass, (pointer)&classes->key); - FreeDeviceClass(ValuatorClass, (pointer)&classes->valuator); - FreeDeviceClass(ButtonClass, (pointer)&classes->button); - FreeDeviceClass(FocusClass, (pointer)&classes->focus); - FreeDeviceClass(ProximityClass, (pointer)&classes->proximity); - - FreeFeedbackClass(KbdFeedbackClass, (pointer)&classes->kbdfeed); - FreeFeedbackClass(PtrFeedbackClass, (pointer)&classes->ptrfeed); - FreeFeedbackClass(IntegerFeedbackClass, (pointer)&classes->intfeed); - FreeFeedbackClass(StringFeedbackClass, (pointer)&classes->stringfeed); - FreeFeedbackClass(BellFeedbackClass, (pointer)&classes->bell); - FreeFeedbackClass(LedFeedbackClass, (pointer)&classes->leds); - -} - -/** - * Close down a device and free all resources. - * Once closed down, the driver will probably not expect you that you'll ever - * enable it again and free associated structs. If you want the device to just - * be disabled, DisableDevice(). - * Don't call this function directly, use RemoveDevice() instead. - */ -static void -CloseDevice(DeviceIntPtr dev) -{ - ScreenPtr screen = screenInfo.screens[0]; - ClassesPtr classes; - int j; - - if (!dev) - return; - - XIDeleteAllDeviceProperties(dev); - - if (dev->inited) - (void)(*dev->deviceProc)(dev, DEVICE_CLOSE); - - /* free sprite memory */ - if (IsMaster(dev) && dev->spriteInfo->sprite) - screen->DeviceCursorCleanup(dev, screen); - - /* free acceleration info */ - if(dev->valuator && dev->valuator->accelScheme.AccelCleanupProc) - dev->valuator->accelScheme.AccelCleanupProc(dev); - - while (dev->xkb_interest) - XkbRemoveResourceClient((DevicePtr)dev,dev->xkb_interest->resource); - - free(dev->name); - - classes = (ClassesPtr)&dev->key; - FreeAllDeviceClasses(classes); - - if (IsMaster(dev)) - { - classes = dev->unused_classes; - FreeAllDeviceClasses(classes); - free(classes); - } - - if (DevHasCursor(dev) && dev->spriteInfo->sprite) { - if (dev->spriteInfo->sprite->current) - FreeCursor(dev->spriteInfo->sprite->current, None); - free(dev->spriteInfo->sprite->spriteTrace); - free(dev->spriteInfo->sprite); - } - - /* a client may have the device set as client pointer */ - for (j = 0; j < currentMaxClients; j++) - { - if (clients[j] && clients[j]->clientPtr == dev) - { - clients[j]->clientPtr = NULL; - clients[j]->clientPtr = PickPointer(clients[j]); - } - } - - free(dev->deviceGrab.sync.event); - dixFreeObjectWithPrivates(dev, PRIVATE_DEVICE); -} - -/** - * Shut down all devices of one list and free all resources. - */ -static -void -CloseDeviceList(DeviceIntPtr *listHead) -{ - /* Used to mark devices that we tried to free */ - Bool freedIds[MAXDEVICES]; - DeviceIntPtr dev; - int i; - - if (listHead == NULL) - return; - - for (i = 0; i < MAXDEVICES; i++) - freedIds[i] = FALSE; - - dev = *listHead; - while (dev != NULL) - { - freedIds[dev->id] = TRUE; - DeleteInputDeviceRequest(dev); - - dev = *listHead; - while (dev != NULL && freedIds[dev->id]) - dev = dev->next; - } -} - -/** - * Shut down all devices, free all resources, etc. - * Only useful if you're shutting down the server! - */ -void -CloseDownDevices(void) -{ - DeviceIntPtr dev; - - /* Float all SDs before closing them. Note that at this point resources - * (e.g. cursors) have been freed already, so we can't just call - * AttachDevice(NULL, dev, NULL). Instead, we have to forcibly set master - * to NULL and pretend nothing happened. - */ - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (!IsMaster(dev) && dev->u.master) - dev->u.master = NULL; - } - - CloseDeviceList(&inputInfo.devices); - CloseDeviceList(&inputInfo.off_devices); - - CloseDevice(inputInfo.pointer); - CloseDevice(inputInfo.keyboard); - - inputInfo.devices = NULL; - inputInfo.off_devices = NULL; - inputInfo.keyboard = NULL; - inputInfo.pointer = NULL; - XkbDeleteRulesDflts(); -} - -/** - * Remove the cursor sprite for all devices. This needs to be done before any - * resources are freed or any device is deleted. - */ -void -UndisplayDevices(void) -{ - DeviceIntPtr dev; - ScreenPtr screen = screenInfo.screens[0]; - - for (dev = inputInfo.devices; dev; dev = dev->next) - screen->DisplayCursor(dev, screen, NullCursor); -} - -/** - * Remove a device from the device list, closes it and thus frees all - * resources. - * Removes both enabled and disabled devices and notifies all devices about - * the removal of the device. - * - * No PresenceNotify is sent for device that the client never saw. This can - * happen if a malloc fails during the addition of master devices. If - * dev->init is FALSE it means the client never received a DeviceAdded event, - * so let's not send a DeviceRemoved event either. - * - * @param sendevent True if an XI2 event should be sent. - */ -int -RemoveDevice(DeviceIntPtr dev, BOOL sendevent) -{ - DeviceIntPtr prev,tmp,next; - int ret = BadMatch; - ScreenPtr screen = screenInfo.screens[0]; - int deviceid; - int initialized; - int flags[MAXDEVICES] = {0}; - - DebugF("(dix) removing device %d\n", dev->id); - - if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer) - return BadImplementation; - - initialized = dev->inited; - deviceid = dev->id; - - if (initialized) - { - if (DevHasCursor(dev)) - screen->DisplayCursor(dev, screen, NullCursor); - - DisableDevice(dev, sendevent); - flags[dev->id] = XIDeviceDisabled; - } - - prev = NULL; - for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) { - next = tmp->next; - if (tmp == dev) { - - if (prev==NULL) - inputInfo.devices = next; - else - prev->next = next; - - flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved; - CloseDevice(tmp); - ret = Success; - } - } - - prev = NULL; - for (tmp = inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) { - next = tmp->next; - if (tmp == dev) { - flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved; - CloseDevice(tmp); - - if (prev == NULL) - inputInfo.off_devices = next; - else - prev->next = next; - - ret = Success; - } - } - - if (ret == Success && initialized) { - inputInfo.numDevices--; - SendDevicePresenceEvent(deviceid, DeviceRemoved); - if (sendevent) - XISendDeviceHierarchyEvent(flags); - } - - return ret; -} - -int -NumMotionEvents(void) -{ - /* only called to fill data in initial connection reply. - * VCP is ok here, it is the only fixed device we have. */ - return inputInfo.pointer->valuator->numMotionEvents; -} - -int -dixLookupDevice(DeviceIntPtr *pDev, int id, ClientPtr client, Mask access_mode) -{ - DeviceIntPtr dev; - int rc; - *pDev = NULL; - - for (dev=inputInfo.devices; dev; dev=dev->next) { - if (dev->id == id) - goto found; - } - for (dev=inputInfo.off_devices; dev; dev=dev->next) { - if (dev->id == id) - goto found; - } - return BadDevice; - -found: - rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); - if (rc == Success) - *pDev = dev; - return rc; -} - -void -QueryMinMaxKeyCodes(KeyCode *minCode, KeyCode *maxCode) -{ - if (inputInfo.keyboard) { - *minCode = inputInfo.keyboard->key->xkbInfo->desc->min_key_code; - *maxCode = inputInfo.keyboard->key->xkbInfo->desc->max_key_code; - } -} - -/* Notably, this function does not expand the destination's keycode range, or - * notify clients. */ -Bool -SetKeySymsMap(KeySymsPtr dst, KeySymsPtr src) -{ - int i, j; - KeySym *tmp; - int rowDif = src->minKeyCode - dst->minKeyCode; - - /* if keysym map size changes, grow map first */ - if (src->mapWidth < dst->mapWidth) { - for (i = src->minKeyCode; i <= src->maxKeyCode; i++) { -#define SI(r, c) (((r - src->minKeyCode) * src->mapWidth) + (c)) -#define DI(r, c) (((r - dst->minKeyCode) * dst->mapWidth) + (c)) - for (j = 0; j < src->mapWidth; j++) - dst->map[DI(i, j)] = src->map[SI(i, j)]; - for (j = src->mapWidth; j < dst->mapWidth; j++) - dst->map[DI(i, j)] = NoSymbol; -#undef SI -#undef DI - } - return TRUE; - } - else if (src->mapWidth > dst->mapWidth) { - i = sizeof(KeySym) * src->mapWidth * - (dst->maxKeyCode - dst->minKeyCode + 1); - tmp = calloc(sizeof(KeySym), i); - if (!tmp) - return FALSE; - - if (dst->map) { - for (i = 0; i <= dst->maxKeyCode-dst->minKeyCode; i++) - memmove(&tmp[i * src->mapWidth], &dst->map[i * dst->mapWidth], - dst->mapWidth * sizeof(KeySym)); - free(dst->map); - } - dst->mapWidth = src->mapWidth; - dst->map = tmp; - } - else if (!dst->map) { - i = sizeof(KeySym) * src->mapWidth * - (dst->maxKeyCode - dst->minKeyCode + 1); - tmp = calloc(sizeof(KeySym), i); - if (!tmp) - return FALSE; - - dst->map = tmp; - dst->mapWidth = src->mapWidth; - } - - memmove(&dst->map[rowDif * dst->mapWidth], src->map, - (src->maxKeyCode - src->minKeyCode + 1) * - dst->mapWidth * sizeof(KeySym)); - - return TRUE; -} - -Bool -InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons, Atom* labels, - CARD8 *map) -{ - ButtonClassPtr butc; - int i; - - butc = calloc(1, sizeof(ButtonClassRec)); - if (!butc) - return FALSE; - butc->numButtons = numButtons; - butc->sourceid = dev->id; - for (i = 1; i <= numButtons; i++) - butc->map[i] = map[i]; - for (i = numButtons + 1; i < MAP_LENGTH; i++) - butc->map[i] = i; - memcpy(butc->labels, labels, numButtons * sizeof(Atom)); - dev->button = butc; - return TRUE; -} - -Bool -InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels, - int numMotionEvents, int mode) -{ - int i; - ValuatorClassPtr valc; - union align_u { ValuatorClassRec valc; double d; } *align; - - if (!dev) - return FALSE; - - if (numAxes > MAX_VALUATORS) - { - LogMessage(X_WARNING, - "Device '%s' has %d axes, only using first %d.\n", - dev->name, numAxes, MAX_VALUATORS); - numAxes = MAX_VALUATORS; - } - - align = (union align_u *) calloc(1, sizeof(union align_u) + - numAxes * sizeof(double) + - numAxes * sizeof(AxisInfo)); - if (!align) - return FALSE; - - valc = &align->valc; - valc->sourceid = dev->id; - valc->motion = NULL; - valc->first_motion = 0; - valc->last_motion = 0; - - valc->numMotionEvents = numMotionEvents; - valc->motionHintWindow = NullWindow; - valc->numAxes = numAxes; - valc->axisVal = (double *)(align + 1); - valc->axes = (AxisInfoPtr)(valc->axisVal + numAxes); - - if (mode & OutOfProximity) - InitProximityClassDeviceStruct(dev); - - dev->valuator = valc; - - AllocateMotionHistory(dev); - - for (i=0; i<numAxes; i++) { - InitValuatorAxisStruct(dev, i, labels[i], NO_AXIS_LIMITS, NO_AXIS_LIMITS, - 0, 0, 0, mode); - valc->axisVal[i]=0; - } - - dev->last.numValuators = numAxes; - - if (IsMaster(dev) || /* do not accelerate master or xtest devices */ - IsXTestDevice(dev, NULL)) - InitPointerAccelerationScheme(dev, PtrAccelNoOp); - else - InitPointerAccelerationScheme(dev, PtrAccelDefault); - return TRUE; -} - -/* global list of acceleration schemes */ -ValuatorAccelerationRec pointerAccelerationScheme[] = { - {PtrAccelNoOp, NULL, NULL, NULL}, - {PtrAccelPredictable, acceleratePointerPredictable, NULL, AccelerationDefaultCleanup}, - {PtrAccelLightweight, acceleratePointerLightweight, NULL, NULL}, - {-1, NULL, NULL, NULL} /* terminator */ -}; - -/** - * install an acceleration scheme. returns TRUE on success, and should not - * change anything if unsuccessful. - */ -Bool -InitPointerAccelerationScheme(DeviceIntPtr dev, - int scheme) -{ - int x, i = -1; - void* data = NULL; - ValuatorClassPtr val; - - val = dev->valuator; - - if(!val) - return FALSE; - - if(IsMaster(dev) && scheme != PtrAccelNoOp) - return FALSE; - - for(x = 0; pointerAccelerationScheme[x].number >= 0; x++) { - if(pointerAccelerationScheme[x].number == scheme){ - i = x; - break; - } - } - - if(-1 == i) - return FALSE; - - if (val->accelScheme.AccelCleanupProc) - val->accelScheme.AccelCleanupProc(dev); - - /* init scheme-specific data */ - switch(scheme){ - case PtrAccelPredictable: - { - DeviceVelocityPtr s; - s = malloc(sizeof(DeviceVelocityRec)); - if(!s) - return FALSE; - InitVelocityData(s); - data = s; - break; - } - default: - break; - } - - val->accelScheme = pointerAccelerationScheme[i]; - val->accelScheme.accelData = data; - - /* post-init scheme */ - switch(scheme){ - case PtrAccelPredictable: - InitializePredictableAccelerationProperties(dev); - break; - - default: - break; - } - - return TRUE; -} - -Bool -InitAbsoluteClassDeviceStruct(DeviceIntPtr dev) -{ - AbsoluteClassPtr abs; - - abs = malloc(sizeof(AbsoluteClassRec)); - if (!abs) - return FALSE; - - /* we don't do anything sensible with these, but should */ - abs->min_x = NO_AXIS_LIMITS; - abs->min_y = NO_AXIS_LIMITS; - abs->max_x = NO_AXIS_LIMITS; - abs->max_y = NO_AXIS_LIMITS; - abs->flip_x = 0; - abs->flip_y = 0; - abs->rotation = 0; - abs->button_threshold = 0; - - abs->offset_x = 0; - abs->offset_y = 0; - abs->width = NO_AXIS_LIMITS; - abs->height = NO_AXIS_LIMITS; - abs->following = 0; - abs->screen = 0; - - abs->sourceid = dev->id; - - dev->absolute = abs; - - return TRUE; -} - -Bool -InitFocusClassDeviceStruct(DeviceIntPtr dev) -{ - FocusClassPtr focc; - - focc = malloc(sizeof(FocusClassRec)); - if (!focc) - return FALSE; - focc->win = PointerRootWin; - focc->revert = None; - focc->time = currentTime; - focc->trace = (WindowPtr *)NULL; - focc->traceSize = 0; - focc->traceGood = 0; - focc->sourceid = dev->id; - dev->focus = focc; - return TRUE; -} - -Bool -InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev, PtrCtrlProcPtr controlProc) -{ - PtrFeedbackPtr feedc; - - feedc = malloc(sizeof(PtrFeedbackClassRec)); - if (!feedc) - return FALSE; - feedc->CtrlProc = controlProc; - feedc->ctrl = defaultPointerControl; - feedc->ctrl.id = 0; - if ( (feedc->next = dev->ptrfeed) ) - feedc->ctrl.id = dev->ptrfeed->ctrl.id + 1; - dev->ptrfeed = feedc; - (*controlProc)(dev, &feedc->ctrl); - return TRUE; -} - - -static LedCtrl defaultLedControl = { - DEFAULT_LEDS, DEFAULT_LEDS_MASK, 0}; - -static BellCtrl defaultBellControl = { - DEFAULT_BELL, - DEFAULT_BELL_PITCH, - DEFAULT_BELL_DURATION, - 0}; - -static IntegerCtrl defaultIntegerControl = { - DEFAULT_INT_RESOLUTION, - DEFAULT_INT_MIN_VALUE, - DEFAULT_INT_MAX_VALUE, - DEFAULT_INT_DISPLAYED, - 0}; - -Bool -InitStringFeedbackClassDeviceStruct ( - DeviceIntPtr dev, StringCtrlProcPtr controlProc, - int max_symbols, int num_symbols_supported, KeySym *symbols) -{ - int i; - StringFeedbackPtr feedc; - - feedc = malloc(sizeof(StringFeedbackClassRec)); - if (!feedc) - return FALSE; - feedc->CtrlProc = controlProc; - feedc->ctrl.num_symbols_supported = num_symbols_supported; - feedc->ctrl.num_symbols_displayed = 0; - feedc->ctrl.max_symbols = max_symbols; - feedc->ctrl.symbols_supported = malloc(sizeof (KeySym) * num_symbols_supported); - feedc->ctrl.symbols_displayed = malloc(sizeof (KeySym) * max_symbols); - if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed) - { - free(feedc->ctrl.symbols_supported); - free(feedc->ctrl.symbols_displayed); - free(feedc); - return FALSE; - } - for (i=0; i<num_symbols_supported; i++) - *(feedc->ctrl.symbols_supported+i) = *symbols++; - for (i=0; i<max_symbols; i++) - *(feedc->ctrl.symbols_displayed+i) = (KeySym) 0; - feedc->ctrl.id = 0; - if ( (feedc->next = dev->stringfeed) ) - feedc->ctrl.id = dev->stringfeed->ctrl.id + 1; - dev->stringfeed = feedc; - (*controlProc)(dev, &feedc->ctrl); - return TRUE; -} - -Bool -InitBellFeedbackClassDeviceStruct (DeviceIntPtr dev, BellProcPtr bellProc, - BellCtrlProcPtr controlProc) -{ - BellFeedbackPtr feedc; - - feedc = malloc(sizeof(BellFeedbackClassRec)); - if (!feedc) - return FALSE; - feedc->CtrlProc = controlProc; - feedc->BellProc = bellProc; - feedc->ctrl = defaultBellControl; - feedc->ctrl.id = 0; - if ( (feedc->next = dev->bell) ) - feedc->ctrl.id = dev->bell->ctrl.id + 1; - dev->bell = feedc; - (*controlProc)(dev, &feedc->ctrl); - return TRUE; -} - -Bool -InitLedFeedbackClassDeviceStruct (DeviceIntPtr dev, LedCtrlProcPtr controlProc) -{ - LedFeedbackPtr feedc; - - feedc = malloc(sizeof(LedFeedbackClassRec)); - if (!feedc) - return FALSE; - feedc->CtrlProc = controlProc; - feedc->ctrl = defaultLedControl; - feedc->ctrl.id = 0; - if ( (feedc->next = dev->leds) ) - feedc->ctrl.id = dev->leds->ctrl.id + 1; - feedc->xkb_sli= NULL; - dev->leds = feedc; - (*controlProc)(dev, &feedc->ctrl); - return TRUE; -} - -Bool -InitIntegerFeedbackClassDeviceStruct (DeviceIntPtr dev, IntegerCtrlProcPtr controlProc) -{ - IntegerFeedbackPtr feedc; - - feedc = malloc(sizeof(IntegerFeedbackClassRec)); - if (!feedc) - return FALSE; - feedc->CtrlProc = controlProc; - feedc->ctrl = defaultIntegerControl; - feedc->ctrl.id = 0; - if ( (feedc->next = dev->intfeed) ) - feedc->ctrl.id = dev->intfeed->ctrl.id + 1; - dev->intfeed = feedc; - (*controlProc)(dev, &feedc->ctrl); - return TRUE; -} - -Bool -InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons, Atom* btn_labels, - PtrCtrlProcPtr controlProc, int numMotionEvents, - int numAxes, Atom *axes_labels) -{ - DeviceIntPtr dev = (DeviceIntPtr)device; - - return(InitButtonClassDeviceStruct(dev, numButtons, btn_labels, map) && - InitValuatorClassDeviceStruct(dev, numAxes, axes_labels, - numMotionEvents, Relative) && - InitPtrFeedbackClassDeviceStruct(dev, controlProc)); -} - -/* - * Check if the given buffer contains elements between low (inclusive) and - * high (inclusive) only. - * - * @return TRUE if the device map is invalid, FALSE otherwise. - */ -Bool -BadDeviceMap(BYTE *buff, int length, unsigned low, unsigned high, XID *errval) -{ - int i; - - for (i = 0; i < length; i++) - if (buff[i]) /* only check non-zero elements */ - { - if ((low > buff[i]) || (high < buff[i])) - { - *errval = buff[i]; - return TRUE; - } - } - return FALSE; -} - -int -ProcSetModifierMapping(ClientPtr client) -{ - xSetModifierMappingReply rep; - int rc; - REQUEST(xSetModifierMappingReq); - REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq); - - if (client->req_len != ((stuff->numKeyPerModifier << 1) + - bytes_to_int32(sizeof(xSetModifierMappingReq)))) - return BadLength; - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - - rc = change_modmap(client, PickKeyboard(client), (KeyCode *)&stuff[1], - stuff->numKeyPerModifier); - if (rc == MappingFailed || rc == -1) - return BadValue; - if (rc != Success && rc != MappingSuccess && rc != MappingFailed && - rc != MappingBusy) - return rc; - - rep.success = rc; - - WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep); - return Success; -} - -int -ProcGetModifierMapping(ClientPtr client) -{ - xGetModifierMappingReply rep; - int max_keys_per_mod = 0; - KeyCode *modkeymap = NULL; - REQUEST_SIZE_MATCH(xReq); - - generate_modkeymap(client, PickKeyboard(client), &modkeymap, - &max_keys_per_mod); - - memset(&rep, 0, sizeof(xGetModifierMappingReply)); - rep.type = X_Reply; - 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(xGetModifierMappingReply), &rep); - (void)WriteToClient(client, max_keys_per_mod * 8, (char *) modkeymap); - - free(modkeymap); - - return Success; -} - -int -ProcChangeKeyboardMapping(ClientPtr client) -{ - REQUEST(xChangeKeyboardMappingReq); - unsigned len; - KeySymsRec keysyms; - DeviceIntPtr pDev, tmp; - int rc; - REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq); - - len = client->req_len - bytes_to_int32(sizeof(xChangeKeyboardMappingReq)); - if (len != (stuff->keyCodes * stuff->keySymsPerKeyCode)) - return BadLength; - - pDev = PickKeyboard(client); - - if ((stuff->firstKeyCode < pDev->key->xkbInfo->desc->min_key_code) || - (stuff->firstKeyCode > pDev->key->xkbInfo->desc->max_key_code)) { - client->errorValue = stuff->firstKeyCode; - return BadValue; - - } - if (((unsigned)(stuff->firstKeyCode + stuff->keyCodes - 1) > - pDev->key->xkbInfo->desc->max_key_code) || - (stuff->keySymsPerKeyCode == 0)) { - client->errorValue = stuff->keySymsPerKeyCode; - return BadValue; - } - - keysyms.minKeyCode = stuff->firstKeyCode; - keysyms.maxKeyCode = stuff->firstKeyCode + stuff->keyCodes - 1; - keysyms.mapWidth = stuff->keySymsPerKeyCode; - keysyms.map = (KeySym *) &stuff[1]; - - rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); - if (rc != Success) - return rc; - - XkbApplyMappingChange(pDev, &keysyms, stuff->firstKeyCode, - stuff->keyCodes, NULL, client); - - for (tmp = inputInfo.devices; tmp; tmp = tmp->next) { - if (IsMaster(tmp) || tmp->u.master != pDev) - continue; - if (!tmp->key) - continue; - - rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); - if (rc != Success) - continue; - - XkbApplyMappingChange(tmp, &keysyms, stuff->firstKeyCode, - stuff->keyCodes, NULL, client); - } - - return Success; -} - -int -ProcSetPointerMapping(ClientPtr client) -{ - BYTE *map; - int ret; - int i, j; - DeviceIntPtr ptr = PickPointer(client); - xSetPointerMappingReply rep; - REQUEST(xSetPointerMappingReq); - REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq); - - if (client->req_len != - bytes_to_int32(sizeof(xSetPointerMappingReq) + stuff->nElts)) - return BadLength; - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.success = MappingSuccess; - map = (BYTE *)&stuff[1]; - - /* So we're bounded here by the number of core buttons. This check - * probably wants disabling through XFixes. */ - /* MPX: With ClientPointer, we can return the right number of buttons. - * Let's just hope nobody changed ClientPointer between GetPointerMapping - * and SetPointerMapping - */ - if (stuff->nElts != ptr->button->numButtons) { - client->errorValue = stuff->nElts; - return BadValue; - } - - /* Core protocol specs don't allow for duplicate mappings; this check - * almost certainly wants disabling through XFixes too. */ - for (i = 0; i < stuff->nElts; i++) { - for (j = i + 1; j < stuff->nElts; j++) { - if (map[i] && map[i] == map[j]) { - client->errorValue = map[i]; - return BadValue; - } - } - } - - ret = ApplyPointerMapping(ptr, map, stuff->nElts, client); - if (ret == MappingBusy) - rep.success = ret; - else if (ret == -1) - return BadValue; - else if (ret != Success) - return ret; - - WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep); - return Success; -} - -int -ProcGetKeyboardMapping(ClientPtr client) -{ - xGetKeyboardMappingReply rep; - DeviceIntPtr kbd = PickKeyboard(client); - XkbDescPtr xkb; - KeySymsPtr syms; - int rc; - REQUEST(xGetKeyboardMappingReq); - REQUEST_SIZE_MATCH(xGetKeyboardMappingReq); - - rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess); - if (rc != Success) - return rc; - - xkb = kbd->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(kbd); - if (!syms) - return BadAlloc; - - memset(&rep, 0, sizeof(xGetKeyboardMappingReply)); - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.keySymsPerKeyCode = syms->mapWidth; - /* length is a count of 4 byte quantities and KeySyms are 4 bytes */ - rep.length = syms->mapWidth * stuff->count; - WriteReplyToClient(client, sizeof(xGetKeyboardMappingReply), &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; -} - -int -ProcGetPointerMapping(ClientPtr client) -{ - xGetPointerMappingReply rep; - /* Apps may get different values each time they call GetPointerMapping as - * the ClientPointer could change. */ - DeviceIntPtr ptr = PickPointer(client); - ButtonClassPtr butc = ptr->button; - int rc; - REQUEST_SIZE_MATCH(xReq); - - rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess); - if (rc != Success) - return rc; - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.nElts = (butc) ? butc->numButtons : 0; - rep.length = ((unsigned)rep.nElts + (4-1))/4; - WriteReplyToClient(client, sizeof(xGetPointerMappingReply), &rep); - if (butc) - WriteToClient(client, (int)rep.nElts, (char *)&butc->map[1]); - return Success; -} - -void -NoteLedState(DeviceIntPtr keybd, int led, Bool on) -{ - KeybdCtrl *ctrl = &keybd->kbdfeed->ctrl; - if (on) - ctrl->leds |= ((Leds)1 << (led - 1)); - else - ctrl->leds &= ~((Leds)1 << (led - 1)); -} - -int -Ones(unsigned long mask) /* HACKMEM 169 */ -{ - unsigned long y; - - y = (mask >> 1) &033333333333; - y = mask - y - ((y >>1) & 033333333333); - return (((y + (y >> 3)) & 030707070707) % 077); -} - -static int -DoChangeKeyboardControl (ClientPtr client, DeviceIntPtr keybd, XID *vlist, - BITS32 vmask) -{ -#define DO_ALL (-1) - KeybdCtrl ctrl; - int t; - int led = DO_ALL; - int key = DO_ALL; - BITS32 index2; - int mask = vmask, i; - XkbEventCauseRec cause; - - ctrl = keybd->kbdfeed->ctrl; - while (vmask) { - index2 = (BITS32) lowbit (vmask); - vmask &= ~index2; - switch (index2) { - case KBKeyClickPercent: - t = (INT8)*vlist; - vlist++; - if (t == -1) { - t = defaultKeyboardControl.click; - } - else if (t < 0 || t > 100) { - client->errorValue = t; - return BadValue; - } - ctrl.click = t; - break; - case KBBellPercent: - t = (INT8)*vlist; - vlist++; - if (t == -1) { - t = defaultKeyboardControl.bell; - } - else if (t < 0 || t > 100) { - client->errorValue = t; - return BadValue; - } - ctrl.bell = t; - break; - case KBBellPitch: - t = (INT16)*vlist; - vlist++; - if (t == -1) { - t = defaultKeyboardControl.bell_pitch; - } - else if (t < 0) { - client->errorValue = t; - return BadValue; - } - ctrl.bell_pitch = t; - break; - case KBBellDuration: - t = (INT16)*vlist; - vlist++; - if (t == -1) - t = defaultKeyboardControl.bell_duration; - else if (t < 0) { - client->errorValue = t; - return BadValue; - } - ctrl.bell_duration = t; - break; - case KBLed: - led = (CARD8)*vlist; - vlist++; - if (led < 1 || led > 32) { - client->errorValue = led; - return BadValue; - } - if (!(mask & KBLedMode)) - return BadMatch; - break; - case KBLedMode: - t = (CARD8)*vlist; - vlist++; - if (t == LedModeOff) { - if (led == DO_ALL) - ctrl.leds = 0x0; - else - ctrl.leds &= ~(((Leds)(1)) << (led - 1)); - } - else if (t == LedModeOn) { - if (led == DO_ALL) - ctrl.leds = ~0L; - else - ctrl.leds |= (((Leds)(1)) << (led - 1)); - } - else { - client->errorValue = t; - return BadValue; - } - - XkbSetCauseCoreReq(&cause,X_ChangeKeyboardControl,client); - XkbSetIndicators(keybd,((led == DO_ALL) ? ~0L : (1L<<(led-1))), - ctrl.leds, &cause); - ctrl.leds = keybd->kbdfeed->ctrl.leds; - - break; - case KBKey: - key = (KeyCode)*vlist; - vlist++; - if ((KeyCode)key < keybd->key->xkbInfo->desc->min_key_code || - (KeyCode)key > keybd->key->xkbInfo->desc->max_key_code) { - client->errorValue = key; - return BadValue; - } - if (!(mask & KBAutoRepeatMode)) - return BadMatch; - break; - case KBAutoRepeatMode: - i = (key >> 3); - mask = (1 << (key & 7)); - t = (CARD8)*vlist; - vlist++; - if (key != DO_ALL) - XkbDisableComputedAutoRepeats(keybd,key); - if (t == AutoRepeatModeOff) { - if (key == DO_ALL) - ctrl.autoRepeat = FALSE; - else - ctrl.autoRepeats[i] &= ~mask; - } - else if (t == AutoRepeatModeOn) { - if (key == DO_ALL) - ctrl.autoRepeat = TRUE; - else - ctrl.autoRepeats[i] |= mask; - } - else if (t == AutoRepeatModeDefault) { - if (key == DO_ALL) - ctrl.autoRepeat = defaultKeyboardControl.autoRepeat; - else - ctrl.autoRepeats[i] = - (ctrl.autoRepeats[i] & ~mask) | - (defaultKeyboardControl.autoRepeats[i] & mask); - } - else { - client->errorValue = t; - return BadValue; - } - break; - default: - client->errorValue = mask; - return BadValue; - } - } - keybd->kbdfeed->ctrl = ctrl; - - /* The XKB RepeatKeys control and core protocol global autorepeat */ - /* value are linked */ - XkbSetRepeatKeys(keybd, key, keybd->kbdfeed->ctrl.autoRepeat); - - return Success; - -#undef DO_ALL -} - -/** - * Changes kbd control on the ClientPointer and all attached SDs. - */ -int -ProcChangeKeyboardControl (ClientPtr client) -{ - XID *vlist; - BITS32 vmask; - int ret = Success, error = Success; - DeviceIntPtr pDev = NULL, keyboard; - REQUEST(xChangeKeyboardControlReq); - - REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq); - - vmask = stuff->mask; - vlist = (XID *)&stuff[1]; - - if (client->req_len != (sizeof(xChangeKeyboardControlReq)>>2)+Ones(vmask)) - return BadLength; - - keyboard = PickKeyboard(client); - - for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { - if ((pDev == keyboard || - (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard)) - && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) { - ret = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); - if (ret != Success) - return ret; - } - } - - for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { - if ((pDev == keyboard || - (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard)) - && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) { - ret = DoChangeKeyboardControl(client, pDev, vlist, vmask); - if (ret != Success) - error = ret; - } - } - - return error; -} - -int -ProcGetKeyboardControl (ClientPtr client) -{ - int rc, i; - DeviceIntPtr kbd = PickKeyboard(client); - KeybdCtrl *ctrl = &kbd->kbdfeed->ctrl; - xGetKeyboardControlReply rep; - REQUEST_SIZE_MATCH(xReq); - - rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess); - if (rc != Success) - return rc; - - rep.type = X_Reply; - rep.length = 5; - rep.sequenceNumber = client->sequence; - rep.globalAutoRepeat = ctrl->autoRepeat; - rep.keyClickPercent = ctrl->click; - rep.bellPercent = ctrl->bell; - rep.bellPitch = ctrl->bell_pitch; - rep.bellDuration = ctrl->bell_duration; - rep.ledMask = ctrl->leds; - for (i = 0; i < 32; i++) - rep.map[i] = ctrl->autoRepeats[i]; - WriteReplyToClient(client, sizeof(xGetKeyboardControlReply), &rep); - return Success; -} - -int -ProcBell(ClientPtr client) -{ - DeviceIntPtr dev, keybd = PickKeyboard(client); - int base = keybd->kbdfeed->ctrl.bell; - int newpercent; - int rc; - REQUEST(xBellReq); - REQUEST_SIZE_MATCH(xBellReq); - - if (stuff->percent < -100 || stuff->percent > 100) { - client->errorValue = stuff->percent; - return BadValue; - } - - newpercent = (base * stuff->percent) / 100; - if (stuff->percent < 0) - newpercent = base + newpercent; - else - newpercent = base - newpercent + stuff->percent; - - for (dev = inputInfo.devices; dev; dev = dev->next) { - if ((dev == keybd || - (!IsMaster(dev) && GetMaster(dev, MASTER_KEYBOARD) == keybd)) && - dev->kbdfeed && dev->kbdfeed->BellProc) { - - rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixBellAccess); - if (rc != Success) - return rc; - XkbHandleBell(FALSE, FALSE, dev, newpercent, - &dev->kbdfeed->ctrl, 0, None, NULL, client); - } - } - - return Success; -} - -int -ProcChangePointerControl(ClientPtr client) -{ - DeviceIntPtr dev, mouse = PickPointer(client); - PtrCtrl ctrl; /* might get BadValue part way through */ - int rc; - REQUEST(xChangePointerControlReq); - REQUEST_SIZE_MATCH(xChangePointerControlReq); - - ctrl = mouse->ptrfeed->ctrl; - if ((stuff->doAccel != xTrue) && (stuff->doAccel != xFalse)) { - client->errorValue = stuff->doAccel; - return BadValue; - } - if ((stuff->doThresh != xTrue) && (stuff->doThresh != xFalse)) { - client->errorValue = stuff->doThresh; - return BadValue; - } - if (stuff->doAccel) { - if (stuff->accelNum == -1) { - ctrl.num = defaultPointerControl.num; - } - else if (stuff->accelNum < 0) { - client->errorValue = stuff->accelNum; - return BadValue; - } - else { - ctrl.num = stuff->accelNum; - } - - if (stuff->accelDenum == -1) { - ctrl.den = defaultPointerControl.den; - } - else if (stuff->accelDenum <= 0) { - client->errorValue = stuff->accelDenum; - return BadValue; - } - else { - ctrl.den = stuff->accelDenum; - } - } - if (stuff->doThresh) { - if (stuff->threshold == -1) { - ctrl.threshold = defaultPointerControl.threshold; - } - else if (stuff->threshold < 0) { - client->errorValue = stuff->threshold; - return BadValue; - } - else { - ctrl.threshold = stuff->threshold; - } - } - - for (dev = inputInfo.devices; dev; dev = dev->next) { - if ((dev == mouse || - (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) && - dev->ptrfeed) { - rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess); - if (rc != Success) - return rc; - } - } - - for (dev = inputInfo.devices; dev; dev = dev->next) { - if ((dev == mouse || - (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) && - dev->ptrfeed) { - dev->ptrfeed->ctrl = ctrl; - } - } - - return Success; -} - -int -ProcGetPointerControl(ClientPtr client) -{ - DeviceIntPtr ptr = PickPointer(client); - PtrCtrl *ctrl = &ptr->ptrfeed->ctrl; - xGetPointerControlReply rep; - int rc; - REQUEST_SIZE_MATCH(xReq); - - rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess); - if (rc != Success) - return rc; - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.threshold = ctrl->threshold; - rep.accelNumerator = ctrl->num; - rep.accelDenominator = ctrl->den; - WriteReplyToClient(client, sizeof(xGenericReply), &rep); - return Success; -} - -void -MaybeStopHint(DeviceIntPtr dev, ClientPtr client) -{ - GrabPtr grab = dev->deviceGrab.grab; - - if ((grab && SameClient(grab, client) && - ((grab->eventMask & PointerMotionHintMask) || - (grab->ownerEvents && - (EventMaskForClient(dev->valuator->motionHintWindow, client) & - PointerMotionHintMask)))) || - (!grab && - (EventMaskForClient(dev->valuator->motionHintWindow, client) & - PointerMotionHintMask))) - dev->valuator->motionHintWindow = NullWindow; -} - -int -ProcGetMotionEvents(ClientPtr client) -{ - WindowPtr pWin; - xTimecoord * coords = (xTimecoord *) NULL; - xGetMotionEventsReply rep; - int i, count, xmin, xmax, ymin, ymax, rc; - unsigned long nEvents; - DeviceIntPtr mouse = PickPointer(client); - TimeStamp start, stop; - REQUEST(xGetMotionEventsReq); - REQUEST_SIZE_MATCH(xGetMotionEventsReq); - - rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); - if (rc != Success) - return rc; - rc = XaceHook(XACE_DEVICE_ACCESS, client, mouse, DixReadAccess); - if (rc != Success) - return rc; - - if (mouse->valuator->motionHintWindow) - MaybeStopHint(mouse, client); - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - nEvents = 0; - start = ClientTimeToServerTime(stuff->start); - stop = ClientTimeToServerTime(stuff->stop); - if ((CompareTimeStamps(start, stop) != LATER) && - (CompareTimeStamps(start, currentTime) != LATER) && - mouse->valuator->numMotionEvents) - { - if (CompareTimeStamps(stop, currentTime) == LATER) - stop = currentTime; - count = GetMotionHistory(mouse, &coords, start.milliseconds, - stop.milliseconds, pWin->drawable.pScreen, - TRUE); - xmin = pWin->drawable.x - wBorderWidth (pWin); - xmax = pWin->drawable.x + (int)pWin->drawable.width + - wBorderWidth (pWin); - ymin = pWin->drawable.y - wBorderWidth (pWin); - ymax = pWin->drawable.y + (int)pWin->drawable.height + - wBorderWidth (pWin); - for (i = 0; i < count; i++) - if ((xmin <= coords[i].x) && (coords[i].x < xmax) && - (ymin <= coords[i].y) && (coords[i].y < ymax)) - { - coords[nEvents].time = coords[i].time; - coords[nEvents].x = coords[i].x - pWin->drawable.x; - coords[nEvents].y = coords[i].y - pWin->drawable.y; - nEvents++; - } - } - rep.length = nEvents * bytes_to_int32(sizeof(xTimecoord)); - rep.nEvents = nEvents; - WriteReplyToClient(client, sizeof(xGetMotionEventsReply), &rep); - if (nEvents) - { - client->pSwapReplyFunc = (ReplySwapPtr) SwapTimeCoordWrite; - WriteSwappedDataToClient(client, nEvents * sizeof(xTimecoord), - (char *)coords); - } - free(coords); - return Success; -} - -int -ProcQueryKeymap(ClientPtr client) -{ - xQueryKeymapReply rep; - int rc, i; - DeviceIntPtr keybd = PickKeyboard(client); - CARD8 *down = keybd->key->down; - - REQUEST_SIZE_MATCH(xReq); - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = 2; - - rc = XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess); - if (rc != Success && rc != BadAccess) - return rc; - - for (i = 0; i<32; i++) - rep.map[i] = down[i]; - - if (rc == BadAccess) - memset(rep.map, 0, 32); - - WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep); - - return Success; -} - - -/** - * Recalculate the number of buttons for the master device. The number of - * buttons on the master device is equal to the number of buttons on the - * slave device with the highest number of buttons. - */ -static void -RecalculateMasterButtons(DeviceIntPtr slave) -{ - DeviceIntPtr dev, master; - int maxbuttons = 0; - - if (!slave->button || IsMaster(slave)) - return; - - master = GetMaster(slave, MASTER_POINTER); - if (!master) - return; - - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (IsMaster(dev) || - dev->u.master != master || - !dev->button) - continue; - - maxbuttons = max(maxbuttons, dev->button->numButtons); - } - - if (master->button && master->button->numButtons != maxbuttons) - { - int i; - DeviceChangedEvent event; - - memset(&event, 0, sizeof(event)); - - master->button->numButtons = maxbuttons; - - event.header = ET_Internal; - event.type = ET_DeviceChanged; - event.time = GetTimeInMillis(); - event.deviceid = master->id; - event.flags = DEVCHANGE_POINTER_EVENT | DEVCHANGE_DEVICE_CHANGE; - event.buttons.num_buttons = maxbuttons; - memcpy(&event.buttons.names, master->button->labels, maxbuttons * - sizeof(Atom)); - - if (master->valuator) - { - event.num_valuators = master->valuator->numAxes; - for (i = 0; i < event.num_valuators; i++) - { - event.valuators[i].min = master->valuator->axes[i].min_value; - event.valuators[i].max = master->valuator->axes[i].max_value; - event.valuators[i].resolution = master->valuator->axes[i].resolution; - event.valuators[i].mode = master->valuator->axes[i].mode; - event.valuators[i].name = master->valuator->axes[i].label; - } - } - - if (master->key) - { - event.keys.min_keycode = master->key->xkbInfo->desc->min_key_code; - event.keys.max_keycode = master->key->xkbInfo->desc->max_key_code; - } - - XISendDeviceChangedEvent(master, master, &event); - } -} - -/** - * Attach device 'dev' to device 'master'. - * Client is set to the client that issued the request, or NULL if it comes - * from some internal automatic pairing. - * - * Master may be NULL to set the device floating. - * - * We don't allow multi-layer hierarchies right now. You can't attach a slave - * to another slave. - */ -int -AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) -{ - ScreenPtr screen; - DeviceIntPtr oldmaster; - if (!dev || IsMaster(dev)) - return BadDevice; - - if (master && !IsMaster(master)) /* can't attach to slaves */ - return BadDevice; - - /* set from floating to floating? */ - if (!dev->u.master && !master && dev->enabled) - return Success; - - /* free the existing sprite. */ - if (!dev->u.master && dev->spriteInfo->paired == dev) - { - screen = miPointerGetScreen(dev); - screen->DeviceCursorCleanup(dev, screen); - free(dev->spriteInfo->sprite); - } - - oldmaster = dev->u.master; - dev->u.master = master; - - /* If device is set to floating, we need to create a sprite for it, - * otherwise things go bad. However, we don't want to render the cursor, - * so we reset spriteOwner. - * Sprite has to be forced to NULL first, otherwise InitializeSprite won't - * alloc new memory but overwrite the previous one. - */ - if (!master) - { - WindowPtr currentRoot; - - if (dev->spriteInfo->sprite) - currentRoot = GetCurrentRootWindow(dev); - else /* new device auto-set to floating */ - currentRoot = screenInfo.screens[0]->root; - - /* we need to init a fake sprite */ - screen = currentRoot->drawable.pScreen; - screen->DeviceCursorInitialize(dev, screen); - dev->spriteInfo->sprite = NULL; - InitializeSprite(dev, currentRoot); - dev->spriteInfo->spriteOwner = FALSE; - dev->spriteInfo->paired = dev; - } else - { - dev->spriteInfo->sprite = master->spriteInfo->sprite; - dev->spriteInfo->paired = master; - dev->spriteInfo->spriteOwner = FALSE; - - RecalculateMasterButtons(master); - } - - /* XXX: in theory, the MD should change back to its old, original - * classes when the last SD is detached. Thanks to the XTEST devices, - * we'll always have an SD attached until the MD is removed. - * So let's not worry about that. - */ - - return Success; -} - -/** - * Return the device paired with the given device or NULL. - * Returns the device paired with the parent master if the given device is a - * slave device. - */ -DeviceIntPtr -GetPairedDevice(DeviceIntPtr dev) -{ - if (!IsMaster(dev) && dev->u.master) - dev = dev->u.master; - - return dev->spriteInfo->paired; -} - - -/** - * Returns the right master for the type of event needed. If the event is a - * keyboard event. - * This function may be called with a master device as argument. If so, the - * returned master is either the device itself or the paired master device. - * If dev is a floating slave device, NULL is returned. - * - * @type ::MASTER_KEYBOARD or ::MASTER_POINTER - */ -DeviceIntPtr -GetMaster(DeviceIntPtr dev, int which) -{ - DeviceIntPtr master; - - if (IsMaster(dev)) - master = dev; - else - master = dev->u.master; - - if (master) - { - if (which == MASTER_KEYBOARD) - { - if (master->type != MASTER_KEYBOARD) - master = GetPairedDevice(master); - } else - { - if (master->type != MASTER_POINTER) - master = GetPairedDevice(master); - } - } - - return master; -} - -/** - * Create a new device pair (== one pointer, one keyboard device). - * Only allocates the devices, you will need to call ActivateDevice() and - * EnableDevice() manually. - * Either a master or a slave device can be created depending on - * the value for master. - */ -int -AllocDevicePair (ClientPtr client, char* name, - DeviceIntPtr* ptr, - DeviceIntPtr* keybd, - DeviceProc ptr_proc, - DeviceProc keybd_proc, - Bool master) -{ - DeviceIntPtr pointer; - DeviceIntPtr keyboard; - *ptr = *keybd = NULL; - - pointer = AddInputDevice(client, ptr_proc, TRUE); - if (!pointer) - return BadAlloc; - - if (asprintf(&pointer->name, "%s pointer", name) == -1) { - pointer->name = NULL; - RemoveDevice(pointer, FALSE); - return BadAlloc; - } - - pointer->public.processInputProc = ProcessOtherEvent; - pointer->public.realInputProc = ProcessOtherEvent; - XkbSetExtension(pointer, ProcessPointerEvent); - pointer->deviceGrab.ActivateGrab = ActivatePointerGrab; - pointer->deviceGrab.DeactivateGrab = DeactivatePointerGrab; - pointer->coreEvents = TRUE; - pointer->spriteInfo->spriteOwner = TRUE; - - pointer->u.lastSlave = NULL; - pointer->last.slave = NULL; - pointer->type = (master) ? MASTER_POINTER : SLAVE; - - keyboard = AddInputDevice(client, keybd_proc, TRUE); - if (!keyboard) - { - RemoveDevice(pointer, FALSE); - return BadAlloc; - } - - if (asprintf(&keyboard->name, "%s keyboard", name) == -1) { - keyboard->name = NULL; - RemoveDevice(keyboard, FALSE); - RemoveDevice(pointer, FALSE); - return BadAlloc; - } - - keyboard->public.processInputProc = ProcessOtherEvent; - keyboard->public.realInputProc = ProcessOtherEvent; - XkbSetExtension(keyboard, ProcessKeyboardEvent); - keyboard->deviceGrab.ActivateGrab = ActivateKeyboardGrab; - keyboard->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab; - keyboard->coreEvents = TRUE; - keyboard->spriteInfo->spriteOwner = FALSE; - - keyboard->u.lastSlave = NULL; - keyboard->last.slave = NULL; - keyboard->type = (master) ? MASTER_KEYBOARD : SLAVE; - - /* The ClassesRec stores the device classes currently not used. */ - pointer->unused_classes = calloc(1, sizeof(ClassesRec)); - keyboard->unused_classes = calloc(1, sizeof(ClassesRec)); - - *ptr = pointer; - *keybd = keyboard; - - return Success; -} - -/** - * Return Relative or Absolute for the device. - */ -int valuator_get_mode(DeviceIntPtr dev, int axis) -{ - return (dev->valuator->axes[axis].mode & DeviceMode); -} - -/** - * Set the given mode for the axis. If axis is VALUATOR_MODE_ALL_AXES, then - * set the mode for all axes. - */ -void valuator_set_mode(DeviceIntPtr dev, int axis, int mode) -{ - if (axis != VALUATOR_MODE_ALL_AXES) - dev->valuator->axes[axis].mode = mode; - else { - int i; - for (i = 0; i < dev->valuator->numAxes; i++) - dev->valuator->axes[i].mode = mode; - } -} +/************************************************************
+
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+********************************************************/
+
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "misc.h"
+#include "resource.h"
+#include <X11/Xproto.h>
+#include <X11/Xatom.h>
+#include "windowstr.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "ptrveloc.h"
+#include "site.h"
+#include "xkbsrv.h"
+#include "privates.h"
+#include "xace.h"
+#include "mi.h"
+
+#include "dispatch.h"
+#include "swaprep.h"
+#include "dixevents.h"
+#include "mipointer.h"
+#include "eventstr.h"
+
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XI2.h>
+#include <X11/extensions/XIproto.h>
+#include <math.h>
+#include <pixman.h>
+#include "exglobals.h"
+#include "exevents.h"
+#include "xiquerydevice.h" /* for SizeDeviceClasses */
+#include "xiproperty.h"
+#include "enterleave.h" /* for EnterWindow() */
+#include "xserver-properties.h"
+#include "xichangehierarchy.h" /* For XISendDeviceHierarchyEvent */
+
+#ifdef _MSC_VER
+#define isfinite(val) _finite(val)
+#endif
+
+/** @file
+ * This file handles input device-related stuff.
+ */
+
+static void RecalculateMasterButtons(DeviceIntPtr slave);
+
+static void
+DeviceSetTransform(DeviceIntPtr dev, float *transform)
+{
+ struct pixman_f_transform scale;
+ double sx, sy;
+ int x, y;
+
+ /**
+ * calculate combined transformation matrix:
+ *
+ * M = InvScale * Transform * Scale
+ *
+ * So we can later transform points using M * p
+ *
+ * Where:
+ * Scale scales coordinates into 0..1 range
+ * Transform is the user supplied (affine) transform
+ * InvScale scales coordinates back up into their native range
+ */
+ sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].min_value;
+ sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value;
+
+ /* invscale */
+ pixman_f_transform_init_scale(&scale, sx, sy);
+ scale.m[0][2] = dev->valuator->axes[0].min_value;
+ scale.m[1][2] = dev->valuator->axes[1].min_value;
+
+ /* transform */
+ for (y=0; y<3; y++)
+ for (x=0; x<3; x++)
+ dev->transform.m[y][x] = *transform++;
+
+ pixman_f_transform_multiply(&dev->transform, &scale, &dev->transform);
+
+ /* scale */
+ pixman_f_transform_init_scale(&scale, 1.0 / sx, 1.0 / sy);
+ scale.m[0][2] = -dev->valuator->axes[0].min_value / sx;
+ scale.m[1][2] = -dev->valuator->axes[1].min_value / sy;
+
+ pixman_f_transform_multiply(&dev->transform, &dev->transform, &scale);
+}
+
+/**
+ * DIX property handler.
+ */
+static int
+DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
+ BOOL checkonly)
+{
+ if (property == XIGetKnownProperty(XI_PROP_ENABLED))
+ {
+ if (prop->format != 8 || prop->type != XA_INTEGER || prop->size != 1)
+ return BadValue;
+
+ /* Don't allow disabling of VCP/VCK */
+ if ((dev == inputInfo.pointer || dev == inputInfo.keyboard) &&
+ !(*(CARD8*)prop->data))
+ return BadAccess;
+
+ if (!checkonly)
+ {
+ if ((*((CARD8*)prop->data)) && !dev->enabled)
+ EnableDevice(dev, TRUE);
+ else if (!(*((CARD8*)prop->data)) && dev->enabled)
+ DisableDevice(dev, TRUE);
+ }
+ } else if (property == XIGetKnownProperty(XI_PROP_TRANSFORM))
+ {
+ float *f = (float*)prop->data;
+ int i;
+
+ if (prop->format != 32 || prop->size != 9 ||
+ prop->type != XIGetKnownProperty(XATOM_FLOAT))
+ return BadValue;
+
+ for (i=0; i<9; i++)
+ if (!isfinite(f[i]))
+ return BadValue;
+
+ if (!checkonly)
+ DeviceSetTransform(dev, f);
+ }
+
+ return Success;
+}
+
+/* Pair the keyboard to the pointer device. Keyboard events will follow the
+ * pointer sprite. Only applicable for master devices.
+ * If the client is set, the request to pair comes from some client. In this
+ * case, we need to check for access. If the client is NULL, it's from an
+ * internal automatic pairing, we must always permit this.
+ */
+static int
+PairDevices(ClientPtr client, DeviceIntPtr ptr, DeviceIntPtr kbd)
+{
+ if (!ptr)
+ return BadDevice;
+
+ /* Don't allow pairing for slave devices */
+ if (!IsMaster(ptr) || !IsMaster(kbd))
+ return BadDevice;
+
+ if (ptr->spriteInfo->paired)
+ return BadDevice;
+
+ if (kbd->spriteInfo->spriteOwner)
+ {
+ free(kbd->spriteInfo->sprite);
+ kbd->spriteInfo->sprite = NULL;
+ kbd->spriteInfo->spriteOwner = FALSE;
+ }
+
+ kbd->spriteInfo->sprite = ptr->spriteInfo->sprite;
+ kbd->spriteInfo->paired = ptr;
+ ptr->spriteInfo->paired = kbd;
+ return Success;
+}
+
+
+/**
+ * Find and return the next unpaired MD pointer device.
+ */
+static DeviceIntPtr
+NextFreePointerDevice(void)
+{
+ DeviceIntPtr dev;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ if (IsMaster(dev) &&
+ dev->spriteInfo->spriteOwner &&
+ !dev->spriteInfo->paired)
+ return dev;
+ return NULL;
+}
+
+/**
+ * Create a new input device and init it to sane values. The device is added
+ * to the server's off_devices list.
+ *
+ * @param deviceProc Callback for device control function (switch dev on/off).
+ * @return The newly created device.
+ */
+DeviceIntPtr
+AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
+{
+ DeviceIntPtr dev, *prev; /* not a typo */
+ DeviceIntPtr devtmp;
+ int devid;
+ char devind[MAXDEVICES];
+ BOOL enabled;
+ float transform[9];
+
+ /* Find next available id, 0 and 1 are reserved */
+ memset(devind, 0, sizeof(char)*MAXDEVICES);
+ for (devtmp = inputInfo.devices; devtmp; devtmp = devtmp->next)
+ devind[devtmp->id]++;
+ for (devtmp = inputInfo.off_devices; devtmp; devtmp = devtmp->next)
+ devind[devtmp->id]++;
+ for (devid = 2; devid < MAXDEVICES && devind[devid]; devid++)
+ ;
+
+ if (devid >= MAXDEVICES)
+ return (DeviceIntPtr)NULL;
+ dev = _dixAllocateObjectWithPrivates(sizeof(DeviceIntRec) + sizeof(SpriteInfoRec),
+ sizeof(DeviceIntRec) + sizeof(SpriteInfoRec),
+ offsetof(DeviceIntRec, devPrivates), PRIVATE_DEVICE);
+ if (!dev)
+ return (DeviceIntPtr)NULL;
+ dev->id = devid;
+ dev->public.processInputProc = ProcessOtherEvent;
+ dev->public.realInputProc = ProcessOtherEvent;
+ dev->public.enqueueInputProc = EnqueueEvent;
+ dev->deviceProc = deviceProc;
+ dev->startup = autoStart;
+
+ /* device grab defaults */
+ dev->deviceGrab.grabTime = currentTime;
+ dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
+ dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
+
+ XkbSetExtension(dev, ProcessKeyboardEvent);
+
+ dev->coreEvents = TRUE;
+
+ /* sprite defaults */
+ dev->spriteInfo = (SpriteInfoPtr)&dev[1];
+
+ /* security creation/labeling check
+ */
+ if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixCreateAccess)) {
+ free(dev);
+ return NULL;
+ }
+
+ inputInfo.numDevices++;
+
+ for (prev = &inputInfo.off_devices; *prev; prev = &(*prev)->next)
+ ;
+ *prev = dev;
+ dev->next = NULL;
+
+ enabled = FALSE;
+ XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
+ XA_INTEGER, 8, PropModeReplace, 1, &enabled,
+ FALSE);
+ XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_ENABLED), FALSE);
+
+ /* unity matrix */
+ memset(transform, 0, sizeof(transform));
+ transform[0] = transform[4] = transform[8] = 1.0f;
+
+ XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_TRANSFORM),
+ XIGetKnownProperty(XATOM_FLOAT), 32,
+ PropModeReplace, 9, transform, FALSE);
+ XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_TRANSFORM),
+ FALSE);
+
+ XIRegisterPropertyHandler(dev, DeviceSetProperty, NULL, NULL);
+
+ return dev;
+}
+
+void
+SendDevicePresenceEvent(int deviceid, int type)
+{
+ DeviceIntRec dummyDev;
+ devicePresenceNotify ev;
+
+ memset(&dummyDev, 0, sizeof(DeviceIntRec));
+ ev.type = DevicePresenceNotify;
+ ev.time = currentTime.milliseconds;
+ ev.devchange = type;
+ ev.deviceid = deviceid;
+ dummyDev.id = XIAllDevices;
+ SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
+ (xEvent*)&ev, 1);
+}
+
+/**
+ * Enable the device through the driver, add the device to the device list.
+ * Switch device ON through the driver and push it onto the global device
+ * list. Initialize the DIX sprite or pair the device. All clients are
+ * notified about the device being enabled.
+ *
+ * A master pointer device needs to be enabled before a master keyboard
+ * device.
+ *
+ * @param The device to be enabled.
+ * @param sendevent True if an XI2 event should be sent.
+ * @return TRUE on success or FALSE otherwise.
+ */
+Bool
+EnableDevice(DeviceIntPtr dev, BOOL sendevent)
+{
+ DeviceIntPtr *prev;
+ int ret;
+ DeviceIntPtr other;
+ BOOL enabled;
+ int flags[MAXDEVICES] = {0};
+
+ for (prev = &inputInfo.off_devices;
+ *prev && (*prev != dev);
+ prev = &(*prev)->next)
+ ;
+
+ if (!dev->spriteInfo->sprite)
+ {
+ if (IsMaster(dev))
+ {
+ /* Sprites appear on first root window, so we can hardcode it */
+ if (dev->spriteInfo->spriteOwner)
+ {
+ InitializeSprite(dev, screenInfo.screens[0]->root);
+ /* mode doesn't matter */
+ EnterWindow(dev, screenInfo.screens[0]->root, NotifyAncestor);
+ }
+ else if ((other = NextFreePointerDevice()) == NULL)
+ {
+ ErrorF("[dix] cannot find pointer to pair with. "
+ "This is a bug.\n");
+ return FALSE;
+ } else
+ PairDevices(NULL, other, dev);
+ } else
+ {
+ if (dev->coreEvents)
+ other = (IsPointerDevice(dev)) ? inputInfo.pointer :
+ inputInfo.keyboard;
+ else
+ other = NULL; /* auto-float non-core devices */
+ AttachDevice(NULL, dev, other);
+ }
+ }
+
+ if ((*prev != dev) || !dev->inited ||
+ ((ret = (*dev->deviceProc)(dev, DEVICE_ON)) != Success)) {
+ ErrorF("[dix] couldn't enable device %d\n", dev->id);
+ return FALSE;
+ }
+ dev->enabled = TRUE;
+ *prev = dev->next;
+
+ for (prev = &inputInfo.devices; *prev; prev = &(*prev)->next)
+ ;
+ *prev = dev;
+ dev->next = NULL;
+
+ enabled = TRUE;
+ XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
+ XA_INTEGER, 8, PropModeReplace, 1, &enabled,
+ TRUE);
+
+ SendDevicePresenceEvent(dev->id, DeviceEnabled);
+ if (sendevent)
+ {
+ flags[dev->id] |= XIDeviceEnabled;
+ XISendDeviceHierarchyEvent(flags);
+ }
+
+ RecalculateMasterButtons(dev);
+
+ return TRUE;
+}
+
+/**
+ * Switch a device off through the driver and push it onto the off_devices
+ * list. A device will not send events while disabled. All clients are
+ * notified about the device being disabled.
+ *
+ * Master keyboard devices have to be disabled before master pointer devices
+ * otherwise things turn bad.
+ *
+ * @param sendevent True if an XI2 event should be sent.
+ * @return TRUE on success or FALSE otherwise.
+ */
+Bool
+DisableDevice(DeviceIntPtr dev, BOOL sendevent)
+{
+ DeviceIntPtr *prev, other;
+ BOOL enabled;
+ int flags[MAXDEVICES] = {0};
+
+ for (prev = &inputInfo.devices;
+ *prev && (*prev != dev);
+ prev = &(*prev)->next)
+ ;
+ if (*prev != dev)
+ return FALSE;
+
+ /* float attached devices */
+ if (IsMaster(dev))
+ {
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if (other->u.master == dev)
+ {
+ AttachDevice(NULL, other, NULL);
+ flags[other->id] |= XISlaveDetached;
+ }
+ }
+ }
+ else
+ {
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if (IsMaster(other) && other->u.lastSlave == dev)
+ other->u.lastSlave = NULL;
+ }
+ }
+
+ if (IsMaster(dev) && dev->spriteInfo->sprite)
+ {
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if (other->spriteInfo->paired == dev)
+ {
+ ErrorF("[dix] cannot disable device, still paired. "
+ "This is a bug. \n");
+ return FALSE;
+ }
+ }
+ }
+
+ (void)(*dev->deviceProc)(dev, DEVICE_OFF);
+ dev->enabled = FALSE;
+
+ /* now that the device is disabled, we can reset the signal handler's
+ * last.slave */
+ OsBlockSignals();
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if (other->last.slave == dev)
+ other->last.slave = NULL;
+ }
+ OsReleaseSignals();
+
+ LeaveWindow(dev);
+ SetFocusOut(dev);
+
+ *prev = dev->next;
+ dev->next = inputInfo.off_devices;
+ inputInfo.off_devices = dev;
+
+ enabled = FALSE;
+ XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
+ XA_INTEGER, 8, PropModeReplace, 1, &enabled,
+ TRUE);
+
+ SendDevicePresenceEvent(dev->id, DeviceDisabled);
+ if (sendevent)
+ {
+ flags[dev->id] = XIDeviceDisabled;
+ XISendDeviceHierarchyEvent(flags);
+ }
+
+ RecalculateMasterButtons(dev);
+
+ return TRUE;
+}
+
+/**
+ * Initialise a new device through the driver and tell all clients about the
+ * new device.
+ *
+ * Must be called before EnableDevice.
+ * The device will NOT send events until it is enabled!
+ *
+ * @param sendevent True if an XI2 event should be sent.
+ * @return Success or an error code on failure.
+ */
+int
+ActivateDevice(DeviceIntPtr dev, BOOL sendevent)
+{
+ int ret = Success;
+ ScreenPtr pScreen = screenInfo.screens[0];
+
+ if (!dev || !dev->deviceProc)
+ return BadImplementation;
+
+ ret = (*dev->deviceProc) (dev, DEVICE_INIT);
+ dev->inited = (ret == Success);
+ if (!dev->inited)
+ return ret;
+
+ /* Initialize memory for sprites. */
+ if (IsMaster(dev) && dev->spriteInfo->spriteOwner)
+ if (!pScreen->DeviceCursorInitialize(dev, pScreen))
+ ret = BadAlloc;
+
+ SendDevicePresenceEvent(dev->id, DeviceAdded);
+ if (sendevent)
+ {
+ int flags[MAXDEVICES] = {0};
+ flags[dev->id] = XISlaveAdded;
+ XISendDeviceHierarchyEvent(flags);
+ }
+ return ret;
+}
+
+/**
+ * Ring the bell.
+ * The actual task of ringing the bell is the job of the DDX.
+ */
+static void
+CoreKeyboardBell(int volume, DeviceIntPtr pDev, pointer arg, int something)
+{
+ KeybdCtrl *ctrl = arg;
+
+ DDXRingBell(volume, ctrl->bell_pitch, ctrl->bell_duration);
+}
+
+static void
+CoreKeyboardCtl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
+{
+ return;
+}
+
+/**
+ * Device control function for the Virtual Core Keyboard.
+ */
+int
+CoreKeyboardProc(DeviceIntPtr pDev, int what)
+{
+
+ switch (what) {
+ case DEVICE_INIT:
+ if (!InitKeyboardDeviceStruct(pDev, NULL, CoreKeyboardBell,
+ CoreKeyboardCtl))
+ {
+ ErrorF("Keyboard initialization failed. This could be a missing "
+ "or incorrect setup of xkeyboard-config.\n");
+ return BadValue;
+ }
+ return Success;
+
+ case DEVICE_ON:
+ case DEVICE_OFF:
+ return Success;
+
+ case DEVICE_CLOSE:
+ return Success;
+ }
+
+ return BadMatch;
+}
+
+/**
+ * Device control function for the Virtual Core Pointer.
+ */
+int
+CorePointerProc(DeviceIntPtr pDev, int what)
+{
+#define NBUTTONS 10
+#define NAXES 2
+ BYTE map[NBUTTONS + 1];
+ int i = 0;
+ Atom btn_labels[NBUTTONS] = {0};
+ Atom axes_labels[NAXES] = {0};
+
+ switch (what) {
+ case DEVICE_INIT:
+ for (i = 1; i <= NBUTTONS; i++)
+ map[i] = i;
+
+ btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
+ btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
+ btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
+ btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
+ btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
+ btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
+ btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
+ /* don't know about the rest */
+
+ axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
+ axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
+
+ if (!InitPointerDeviceStruct((DevicePtr)pDev, map, NBUTTONS, btn_labels,
+ (PtrCtrlProcPtr)NoopDDA,
+ GetMotionHistorySize(), NAXES, axes_labels))
+ {
+ ErrorF("Could not initialize device '%s'. Out of memory.\n",
+ pDev->name);
+ return BadAlloc; /* IPDS only fails on allocs */
+ }
+ pDev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2;
+ pDev->last.valuators[0] = pDev->valuator->axisVal[0];
+ pDev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
+ pDev->last.valuators[1] = pDev->valuator->axisVal[1];
+ break;
+
+ case DEVICE_CLOSE:
+ break;
+
+ default:
+ break;
+ }
+
+ return Success;
+
+#undef NBUTTONS
+#undef NAXES
+}
+
+/**
+ * Initialise the two core devices, VCP and VCK (see events.c).
+ * Both devices are not tied to physical devices, but guarantee that there is
+ * always a keyboard and a pointer present and keep the protocol semantics.
+ *
+ * Note that the server MUST have two core devices at all times, even if there
+ * is no physical device connected.
+ */
+void
+InitCoreDevices(void)
+{
+ if (AllocDevicePair(serverClient, "Virtual core",
+ &inputInfo.pointer, &inputInfo.keyboard,
+ CorePointerProc, CoreKeyboardProc,
+ TRUE) != Success)
+ FatalError("Failed to allocate core devices");
+
+ if (ActivateDevice(inputInfo.pointer, TRUE) != Success ||
+ ActivateDevice(inputInfo.keyboard, TRUE) != Success)
+ FatalError("Failed to activate core devices.");
+ if (!EnableDevice(inputInfo.pointer, TRUE) ||
+ !EnableDevice(inputInfo.keyboard, TRUE))
+ FatalError("Failed to enable core devices.");
+
+ InitXTestDevices();
+}
+
+/**
+ * Activate all switched-off devices and then enable all those devices.
+ *
+ * Will return an error if no core keyboard or core pointer is present.
+ * In theory this should never happen if you call InitCoreDevices() first.
+ *
+ * InitAndStartDevices needs to be called AFTER the windows are initialized.
+ * Devices will start sending events after InitAndStartDevices() has
+ * completed.
+ *
+ * @return Success or error code on failure.
+ */
+int
+InitAndStartDevices(void)
+{
+ DeviceIntPtr dev, next;
+
+ for (dev = inputInfo.off_devices; dev; dev = dev->next) {
+ DebugF("(dix) initialising device %d\n", dev->id);
+ if (!dev->inited)
+ ActivateDevice(dev, TRUE);
+ }
+
+ /* enable real devices */
+ for (dev = inputInfo.off_devices; dev; dev = next)
+ {
+ DebugF("(dix) enabling device %d\n", dev->id);
+ next = dev->next;
+ if (dev->inited && dev->startup)
+ EnableDevice(dev, TRUE);
+ }
+
+ return Success;
+}
+
+/**
+ * Free the given device class and reset the pointer to NULL.
+ */
+static void
+FreeDeviceClass(int type, pointer *class)
+{
+ if (!(*class))
+ return;
+
+ switch(type)
+ {
+ case KeyClass:
+ {
+ KeyClassPtr* k = (KeyClassPtr*)class;
+ if ((*k)->xkbInfo)
+ {
+ XkbFreeInfo((*k)->xkbInfo);
+ (*k)->xkbInfo = NULL;
+ }
+ free((*k));
+ break;
+ }
+ case ButtonClass:
+ {
+ ButtonClassPtr *b = (ButtonClassPtr*)class;
+ free((*b)->xkb_acts);
+ free((*b));
+ break;
+ }
+ case ValuatorClass:
+ {
+ ValuatorClassPtr *v = (ValuatorClassPtr*)class;
+
+ free((*v)->motion);
+ free((*v));
+ break;
+ }
+ case FocusClass:
+ {
+ FocusClassPtr *f = (FocusClassPtr*)class;
+ free((*f)->trace);
+ free((*f));
+ break;
+ }
+ case ProximityClass:
+ {
+ ProximityClassPtr *p = (ProximityClassPtr*)class;
+ free((*p));
+ break;
+ }
+ }
+ *class = NULL;
+}
+
+static void
+FreeFeedbackClass(int type, pointer *class)
+{
+ if (!(*class))
+ return;
+
+ switch(type)
+ {
+ case KbdFeedbackClass:
+ {
+ KbdFeedbackPtr *kbdfeed = (KbdFeedbackPtr*)class;
+ KbdFeedbackPtr k, knext;
+ for (k = (*kbdfeed); k; k = knext) {
+ knext = k->next;
+ if (k->xkb_sli)
+ XkbFreeSrvLedInfo(k->xkb_sli);
+ free(k);
+ }
+ break;
+ }
+ case PtrFeedbackClass:
+ {
+ PtrFeedbackPtr *ptrfeed = (PtrFeedbackPtr*)class;
+ PtrFeedbackPtr p, pnext;
+
+ for (p = (*ptrfeed); p; p = pnext) {
+ pnext = p->next;
+ free(p);
+ }
+ break;
+ }
+ case IntegerFeedbackClass:
+ {
+ IntegerFeedbackPtr *intfeed = (IntegerFeedbackPtr*)class;
+ IntegerFeedbackPtr i, inext;
+
+ for (i = (*intfeed); i; i = inext) {
+ inext = i->next;
+ free(i);
+ }
+ break;
+ }
+ case StringFeedbackClass:
+ {
+ StringFeedbackPtr *stringfeed = (StringFeedbackPtr*)class;
+ StringFeedbackPtr s, snext;
+
+ for (s = (*stringfeed); s; s = snext) {
+ snext = s->next;
+ free(s->ctrl.symbols_supported);
+ free(s->ctrl.symbols_displayed);
+ free(s);
+ }
+ break;
+ }
+ case BellFeedbackClass:
+ {
+ BellFeedbackPtr *bell = (BellFeedbackPtr*)class;
+ BellFeedbackPtr b, bnext;
+
+ for (b = (*bell); b; b = bnext) {
+ bnext = b->next;
+ free(b);
+ }
+ break;
+ }
+ case LedFeedbackClass:
+ {
+ LedFeedbackPtr *leds = (LedFeedbackPtr*)class;
+ LedFeedbackPtr l, lnext;
+
+ for (l = (*leds); l; l = lnext) {
+ lnext = l->next;
+ if (l->xkb_sli)
+ XkbFreeSrvLedInfo(l->xkb_sli);
+ free(l);
+ }
+ break;
+ }
+ }
+ *class = NULL;
+}
+
+static void
+FreeAllDeviceClasses(ClassesPtr classes)
+{
+ if (!classes)
+ return;
+
+ FreeDeviceClass(KeyClass, (pointer)&classes->key);
+ FreeDeviceClass(ValuatorClass, (pointer)&classes->valuator);
+ FreeDeviceClass(ButtonClass, (pointer)&classes->button);
+ FreeDeviceClass(FocusClass, (pointer)&classes->focus);
+ FreeDeviceClass(ProximityClass, (pointer)&classes->proximity);
+
+ FreeFeedbackClass(KbdFeedbackClass, (pointer)&classes->kbdfeed);
+ FreeFeedbackClass(PtrFeedbackClass, (pointer)&classes->ptrfeed);
+ FreeFeedbackClass(IntegerFeedbackClass, (pointer)&classes->intfeed);
+ FreeFeedbackClass(StringFeedbackClass, (pointer)&classes->stringfeed);
+ FreeFeedbackClass(BellFeedbackClass, (pointer)&classes->bell);
+ FreeFeedbackClass(LedFeedbackClass, (pointer)&classes->leds);
+
+}
+
+/**
+ * Close down a device and free all resources.
+ * Once closed down, the driver will probably not expect you that you'll ever
+ * enable it again and free associated structs. If you want the device to just
+ * be disabled, DisableDevice().
+ * Don't call this function directly, use RemoveDevice() instead.
+ */
+static void
+CloseDevice(DeviceIntPtr dev)
+{
+ ScreenPtr screen = screenInfo.screens[0];
+ ClassesPtr classes;
+ int j;
+
+ if (!dev)
+ return;
+
+ XIDeleteAllDeviceProperties(dev);
+
+ if (dev->inited)
+ (void)(*dev->deviceProc)(dev, DEVICE_CLOSE);
+
+ /* free sprite memory */
+ if (IsMaster(dev) && dev->spriteInfo->sprite)
+ screen->DeviceCursorCleanup(dev, screen);
+
+ /* free acceleration info */
+ if(dev->valuator && dev->valuator->accelScheme.AccelCleanupProc)
+ dev->valuator->accelScheme.AccelCleanupProc(dev);
+
+ while (dev->xkb_interest)
+ XkbRemoveResourceClient((DevicePtr)dev,dev->xkb_interest->resource);
+
+ free(dev->name);
+
+ classes = (ClassesPtr)&dev->key;
+ FreeAllDeviceClasses(classes);
+
+ if (IsMaster(dev))
+ {
+ classes = dev->unused_classes;
+ FreeAllDeviceClasses(classes);
+ free(classes);
+ }
+
+ if (DevHasCursor(dev) && dev->spriteInfo->sprite) {
+ if (dev->spriteInfo->sprite->current)
+ FreeCursor(dev->spriteInfo->sprite->current, None);
+ free(dev->spriteInfo->sprite->spriteTrace);
+ free(dev->spriteInfo->sprite);
+ }
+
+ /* a client may have the device set as client pointer */
+ for (j = 0; j < currentMaxClients; j++)
+ {
+ if (clients[j] && clients[j]->clientPtr == dev)
+ {
+ clients[j]->clientPtr = NULL;
+ clients[j]->clientPtr = PickPointer(clients[j]);
+ }
+ }
+
+ free(dev->deviceGrab.sync.event);
+ dixFreeObjectWithPrivates(dev, PRIVATE_DEVICE);
+}
+
+/**
+ * Shut down all devices of one list and free all resources.
+ */
+static
+void
+CloseDeviceList(DeviceIntPtr *listHead)
+{
+ /* Used to mark devices that we tried to free */
+ Bool freedIds[MAXDEVICES];
+ DeviceIntPtr dev;
+ int i;
+
+ if (listHead == NULL)
+ return;
+
+ for (i = 0; i < MAXDEVICES; i++)
+ freedIds[i] = FALSE;
+
+ dev = *listHead;
+ while (dev != NULL)
+ {
+ freedIds[dev->id] = TRUE;
+ DeleteInputDeviceRequest(dev);
+
+ dev = *listHead;
+ while (dev != NULL && freedIds[dev->id])
+ dev = dev->next;
+ }
+}
+
+/**
+ * Shut down all devices, free all resources, etc.
+ * Only useful if you're shutting down the server!
+ */
+void
+CloseDownDevices(void)
+{
+ DeviceIntPtr dev;
+
+ /* Float all SDs before closing them. Note that at this point resources
+ * (e.g. cursors) have been freed already, so we can't just call
+ * AttachDevice(NULL, dev, NULL). Instead, we have to forcibly set master
+ * to NULL and pretend nothing happened.
+ */
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (!IsMaster(dev) && dev->u.master)
+ dev->u.master = NULL;
+ /* Initialise the sprite and paired members of all devices
+ to avoid crashes in CloseDevice later */
+ dev->spriteInfo->sprite=NULL;
+ dev->spriteInfo->paired=NULL;
+ }
+
+ CloseDeviceList(&inputInfo.devices);
+ CloseDeviceList(&inputInfo.off_devices);
+
+ CloseDevice(inputInfo.pointer);
+ CloseDevice(inputInfo.keyboard);
+
+ inputInfo.devices = NULL;
+ inputInfo.off_devices = NULL;
+ inputInfo.keyboard = NULL;
+ inputInfo.pointer = NULL;
+ XkbDeleteRulesDflts();
+}
+
+/**
+ * Remove the cursor sprite for all devices. This needs to be done before any
+ * resources are freed or any device is deleted.
+ */
+void
+UndisplayDevices(void)
+{
+ DeviceIntPtr dev;
+ ScreenPtr screen = screenInfo.screens[0];
+
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ screen->DisplayCursor(dev, screen, NullCursor);
+}
+
+/**
+ * Remove a device from the device list, closes it and thus frees all
+ * resources.
+ * Removes both enabled and disabled devices and notifies all devices about
+ * the removal of the device.
+ *
+ * No PresenceNotify is sent for device that the client never saw. This can
+ * happen if a malloc fails during the addition of master devices. If
+ * dev->init is FALSE it means the client never received a DeviceAdded event,
+ * so let's not send a DeviceRemoved event either.
+ *
+ * @param sendevent True if an XI2 event should be sent.
+ */
+int
+RemoveDevice(DeviceIntPtr dev, BOOL sendevent)
+{
+ DeviceIntPtr prev,tmp,next;
+ int ret = BadMatch;
+ ScreenPtr screen = screenInfo.screens[0];
+ int deviceid;
+ int initialized;
+ int flags[MAXDEVICES] = {0};
+
+ DebugF("(dix) removing device %d\n", dev->id);
+
+ if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer)
+ return BadImplementation;
+
+ initialized = dev->inited;
+ deviceid = dev->id;
+
+ if (initialized)
+ {
+ if (DevHasCursor(dev))
+ screen->DisplayCursor(dev, screen, NullCursor);
+
+ DisableDevice(dev, sendevent);
+ flags[dev->id] = XIDeviceDisabled;
+ }
+
+ prev = NULL;
+ for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
+ next = tmp->next;
+ if (tmp == dev) {
+
+ if (prev==NULL)
+ inputInfo.devices = next;
+ else
+ prev->next = next;
+
+ flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved;
+ CloseDevice(tmp);
+ ret = Success;
+ }
+ }
+
+ prev = NULL;
+ for (tmp = inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) {
+ next = tmp->next;
+ if (tmp == dev) {
+ flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved;
+ CloseDevice(tmp);
+
+ if (prev == NULL)
+ inputInfo.off_devices = next;
+ else
+ prev->next = next;
+
+ ret = Success;
+ }
+ }
+
+ if (ret == Success && initialized) {
+ inputInfo.numDevices--;
+ SendDevicePresenceEvent(deviceid, DeviceRemoved);
+ if (sendevent)
+ XISendDeviceHierarchyEvent(flags);
+ }
+
+ return ret;
+}
+
+int
+NumMotionEvents(void)
+{
+ /* only called to fill data in initial connection reply.
+ * VCP is ok here, it is the only fixed device we have. */
+ return inputInfo.pointer->valuator->numMotionEvents;
+}
+
+int
+dixLookupDevice(DeviceIntPtr *pDev, int id, ClientPtr client, Mask access_mode)
+{
+ DeviceIntPtr dev;
+ int rc;
+ *pDev = NULL;
+
+ for (dev=inputInfo.devices; dev; dev=dev->next) {
+ if (dev->id == id)
+ goto found;
+ }
+ for (dev=inputInfo.off_devices; dev; dev=dev->next) {
+ if (dev->id == id)
+ goto found;
+ }
+ return BadDevice;
+
+found:
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
+ if (rc == Success)
+ *pDev = dev;
+ return rc;
+}
+
+void
+QueryMinMaxKeyCodes(KeyCode *minCode, KeyCode *maxCode)
+{
+ if (inputInfo.keyboard) {
+ *minCode = inputInfo.keyboard->key->xkbInfo->desc->min_key_code;
+ *maxCode = inputInfo.keyboard->key->xkbInfo->desc->max_key_code;
+ }
+}
+
+/* Notably, this function does not expand the destination's keycode range, or
+ * notify clients. */
+Bool
+SetKeySymsMap(KeySymsPtr dst, KeySymsPtr src)
+{
+ int i, j;
+ KeySym *tmp;
+ int rowDif = src->minKeyCode - dst->minKeyCode;
+
+ /* if keysym map size changes, grow map first */
+ if (src->mapWidth < dst->mapWidth) {
+ for (i = src->minKeyCode; i <= src->maxKeyCode; i++) {
+#define SI(r, c) (((r - src->minKeyCode) * src->mapWidth) + (c))
+#define DI(r, c) (((r - dst->minKeyCode) * dst->mapWidth) + (c))
+ for (j = 0; j < src->mapWidth; j++)
+ dst->map[DI(i, j)] = src->map[SI(i, j)];
+ for (j = src->mapWidth; j < dst->mapWidth; j++)
+ dst->map[DI(i, j)] = NoSymbol;
+#undef SI
+#undef DI
+ }
+ return TRUE;
+ }
+ else if (src->mapWidth > dst->mapWidth) {
+ i = sizeof(KeySym) * src->mapWidth *
+ (dst->maxKeyCode - dst->minKeyCode + 1);
+ tmp = calloc(sizeof(KeySym), i);
+ if (!tmp)
+ return FALSE;
+
+ if (dst->map) {
+ for (i = 0; i <= dst->maxKeyCode-dst->minKeyCode; i++)
+ memmove(&tmp[i * src->mapWidth], &dst->map[i * dst->mapWidth],
+ dst->mapWidth * sizeof(KeySym));
+ free(dst->map);
+ }
+ dst->mapWidth = src->mapWidth;
+ dst->map = tmp;
+ }
+ else if (!dst->map) {
+ i = sizeof(KeySym) * src->mapWidth *
+ (dst->maxKeyCode - dst->minKeyCode + 1);
+ tmp = calloc(sizeof(KeySym), i);
+ if (!tmp)
+ return FALSE;
+
+ dst->map = tmp;
+ dst->mapWidth = src->mapWidth;
+ }
+
+ memmove(&dst->map[rowDif * dst->mapWidth], src->map,
+ (src->maxKeyCode - src->minKeyCode + 1) *
+ dst->mapWidth * sizeof(KeySym));
+
+ return TRUE;
+}
+
+Bool
+InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons, Atom* labels,
+ CARD8 *map)
+{
+ ButtonClassPtr butc;
+ int i;
+
+ butc = calloc(1, sizeof(ButtonClassRec));
+ if (!butc)
+ return FALSE;
+ butc->numButtons = numButtons;
+ butc->sourceid = dev->id;
+ for (i = 1; i <= numButtons; i++)
+ butc->map[i] = map[i];
+ for (i = numButtons + 1; i < MAP_LENGTH; i++)
+ butc->map[i] = i;
+ memcpy(butc->labels, labels, numButtons * sizeof(Atom));
+ dev->button = butc;
+ return TRUE;
+}
+
+Bool
+InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels,
+ int numMotionEvents, int mode)
+{
+ int i;
+ ValuatorClassPtr valc;
+ union align_u { ValuatorClassRec valc; double d; } *align;
+
+ if (!dev)
+ return FALSE;
+
+ if (numAxes > MAX_VALUATORS)
+ {
+ LogMessage(X_WARNING,
+ "Device '%s' has %d axes, only using first %d.\n",
+ dev->name, numAxes, MAX_VALUATORS);
+ numAxes = MAX_VALUATORS;
+ }
+
+ align = (union align_u *) calloc(1, sizeof(union align_u) +
+ numAxes * sizeof(double) +
+ numAxes * sizeof(AxisInfo));
+ if (!align)
+ return FALSE;
+
+ valc = &align->valc;
+ valc->sourceid = dev->id;
+ valc->motion = NULL;
+ valc->first_motion = 0;
+ valc->last_motion = 0;
+
+ valc->numMotionEvents = numMotionEvents;
+ valc->motionHintWindow = NullWindow;
+ valc->numAxes = numAxes;
+ valc->axisVal = (double *)(align + 1);
+ valc->axes = (AxisInfoPtr)(valc->axisVal + numAxes);
+
+ if (mode & OutOfProximity)
+ InitProximityClassDeviceStruct(dev);
+
+ dev->valuator = valc;
+
+ AllocateMotionHistory(dev);
+
+ for (i=0; i<numAxes; i++) {
+ InitValuatorAxisStruct(dev, i, labels[i], NO_AXIS_LIMITS, NO_AXIS_LIMITS,
+ 0, 0, 0, mode);
+ valc->axisVal[i]=0;
+ }
+
+ dev->last.numValuators = numAxes;
+
+ if (IsMaster(dev) || /* do not accelerate master or xtest devices */
+ IsXTestDevice(dev, NULL))
+ InitPointerAccelerationScheme(dev, PtrAccelNoOp);
+ else
+ InitPointerAccelerationScheme(dev, PtrAccelDefault);
+ return TRUE;
+}
+
+/* global list of acceleration schemes */
+ValuatorAccelerationRec pointerAccelerationScheme[] = {
+ {PtrAccelNoOp, NULL, NULL, NULL},
+ {PtrAccelPredictable, acceleratePointerPredictable, NULL, AccelerationDefaultCleanup},
+ {PtrAccelLightweight, acceleratePointerLightweight, NULL, NULL},
+ {-1, NULL, NULL, NULL} /* terminator */
+};
+
+/**
+ * install an acceleration scheme. returns TRUE on success, and should not
+ * change anything if unsuccessful.
+ */
+Bool
+InitPointerAccelerationScheme(DeviceIntPtr dev,
+ int scheme)
+{
+ int x, i = -1;
+ void* data = NULL;
+ ValuatorClassPtr val;
+
+ val = dev->valuator;
+
+ if(!val)
+ return FALSE;
+
+ if(IsMaster(dev) && scheme != PtrAccelNoOp)
+ return FALSE;
+
+ for(x = 0; pointerAccelerationScheme[x].number >= 0; x++) {
+ if(pointerAccelerationScheme[x].number == scheme){
+ i = x;
+ break;
+ }
+ }
+
+ if(-1 == i)
+ return FALSE;
+
+ if (val->accelScheme.AccelCleanupProc)
+ val->accelScheme.AccelCleanupProc(dev);
+
+ /* init scheme-specific data */
+ switch(scheme){
+ case PtrAccelPredictable:
+ {
+ DeviceVelocityPtr s;
+ s = malloc(sizeof(DeviceVelocityRec));
+ if(!s)
+ return FALSE;
+ InitVelocityData(s);
+ data = s;
+ break;
+ }
+ default:
+ break;
+ }
+
+ val->accelScheme = pointerAccelerationScheme[i];
+ val->accelScheme.accelData = data;
+
+ /* post-init scheme */
+ switch(scheme){
+ case PtrAccelPredictable:
+ InitializePredictableAccelerationProperties(dev);
+ break;
+
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+Bool
+InitAbsoluteClassDeviceStruct(DeviceIntPtr dev)
+{
+ AbsoluteClassPtr abs;
+
+ abs = malloc(sizeof(AbsoluteClassRec));
+ if (!abs)
+ return FALSE;
+
+ /* we don't do anything sensible with these, but should */
+ abs->min_x = NO_AXIS_LIMITS;
+ abs->min_y = NO_AXIS_LIMITS;
+ abs->max_x = NO_AXIS_LIMITS;
+ abs->max_y = NO_AXIS_LIMITS;
+ abs->flip_x = 0;
+ abs->flip_y = 0;
+ abs->rotation = 0;
+ abs->button_threshold = 0;
+
+ abs->offset_x = 0;
+ abs->offset_y = 0;
+ abs->width = NO_AXIS_LIMITS;
+ abs->height = NO_AXIS_LIMITS;
+ abs->following = 0;
+ abs->screen = 0;
+
+ abs->sourceid = dev->id;
+
+ dev->absolute = abs;
+
+ return TRUE;
+}
+
+Bool
+InitFocusClassDeviceStruct(DeviceIntPtr dev)
+{
+ FocusClassPtr focc;
+
+ focc = malloc(sizeof(FocusClassRec));
+ if (!focc)
+ return FALSE;
+ focc->win = PointerRootWin;
+ focc->revert = None;
+ focc->time = currentTime;
+ focc->trace = (WindowPtr *)NULL;
+ focc->traceSize = 0;
+ focc->traceGood = 0;
+ focc->sourceid = dev->id;
+ dev->focus = focc;
+ return TRUE;
+}
+
+Bool
+InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev, PtrCtrlProcPtr controlProc)
+{
+ PtrFeedbackPtr feedc;
+
+ feedc = malloc(sizeof(PtrFeedbackClassRec));
+ if (!feedc)
+ return FALSE;
+ feedc->CtrlProc = controlProc;
+ feedc->ctrl = defaultPointerControl;
+ feedc->ctrl.id = 0;
+ if ( (feedc->next = dev->ptrfeed) )
+ feedc->ctrl.id = dev->ptrfeed->ctrl.id + 1;
+ dev->ptrfeed = feedc;
+ (*controlProc)(dev, &feedc->ctrl);
+ return TRUE;
+}
+
+
+static LedCtrl defaultLedControl = {
+ DEFAULT_LEDS, DEFAULT_LEDS_MASK, 0};
+
+static BellCtrl defaultBellControl = {
+ DEFAULT_BELL,
+ DEFAULT_BELL_PITCH,
+ DEFAULT_BELL_DURATION,
+ 0};
+
+static IntegerCtrl defaultIntegerControl = {
+ DEFAULT_INT_RESOLUTION,
+ DEFAULT_INT_MIN_VALUE,
+ DEFAULT_INT_MAX_VALUE,
+ DEFAULT_INT_DISPLAYED,
+ 0};
+
+Bool
+InitStringFeedbackClassDeviceStruct (
+ DeviceIntPtr dev, StringCtrlProcPtr controlProc,
+ int max_symbols, int num_symbols_supported, KeySym *symbols)
+{
+ int i;
+ StringFeedbackPtr feedc;
+
+ feedc = malloc(sizeof(StringFeedbackClassRec));
+ if (!feedc)
+ return FALSE;
+ feedc->CtrlProc = controlProc;
+ feedc->ctrl.num_symbols_supported = num_symbols_supported;
+ feedc->ctrl.num_symbols_displayed = 0;
+ feedc->ctrl.max_symbols = max_symbols;
+ feedc->ctrl.symbols_supported = malloc(sizeof (KeySym) * num_symbols_supported);
+ feedc->ctrl.symbols_displayed = malloc(sizeof (KeySym) * max_symbols);
+ if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed)
+ {
+ free(feedc->ctrl.symbols_supported);
+ free(feedc->ctrl.symbols_displayed);
+ free(feedc);
+ return FALSE;
+ }
+ for (i=0; i<num_symbols_supported; i++)
+ *(feedc->ctrl.symbols_supported+i) = *symbols++;
+ for (i=0; i<max_symbols; i++)
+ *(feedc->ctrl.symbols_displayed+i) = (KeySym) 0;
+ feedc->ctrl.id = 0;
+ if ( (feedc->next = dev->stringfeed) )
+ feedc->ctrl.id = dev->stringfeed->ctrl.id + 1;
+ dev->stringfeed = feedc;
+ (*controlProc)(dev, &feedc->ctrl);
+ return TRUE;
+}
+
+Bool
+InitBellFeedbackClassDeviceStruct (DeviceIntPtr dev, BellProcPtr bellProc,
+ BellCtrlProcPtr controlProc)
+{
+ BellFeedbackPtr feedc;
+
+ feedc = malloc(sizeof(BellFeedbackClassRec));
+ if (!feedc)
+ return FALSE;
+ feedc->CtrlProc = controlProc;
+ feedc->BellProc = bellProc;
+ feedc->ctrl = defaultBellControl;
+ feedc->ctrl.id = 0;
+ if ( (feedc->next = dev->bell) )
+ feedc->ctrl.id = dev->bell->ctrl.id + 1;
+ dev->bell = feedc;
+ (*controlProc)(dev, &feedc->ctrl);
+ return TRUE;
+}
+
+Bool
+InitLedFeedbackClassDeviceStruct (DeviceIntPtr dev, LedCtrlProcPtr controlProc)
+{
+ LedFeedbackPtr feedc;
+
+ feedc = malloc(sizeof(LedFeedbackClassRec));
+ if (!feedc)
+ return FALSE;
+ feedc->CtrlProc = controlProc;
+ feedc->ctrl = defaultLedControl;
+ feedc->ctrl.id = 0;
+ if ( (feedc->next = dev->leds) )
+ feedc->ctrl.id = dev->leds->ctrl.id + 1;
+ feedc->xkb_sli= NULL;
+ dev->leds = feedc;
+ (*controlProc)(dev, &feedc->ctrl);
+ return TRUE;
+}
+
+Bool
+InitIntegerFeedbackClassDeviceStruct (DeviceIntPtr dev, IntegerCtrlProcPtr controlProc)
+{
+ IntegerFeedbackPtr feedc;
+
+ feedc = malloc(sizeof(IntegerFeedbackClassRec));
+ if (!feedc)
+ return FALSE;
+ feedc->CtrlProc = controlProc;
+ feedc->ctrl = defaultIntegerControl;
+ feedc->ctrl.id = 0;
+ if ( (feedc->next = dev->intfeed) )
+ feedc->ctrl.id = dev->intfeed->ctrl.id + 1;
+ dev->intfeed = feedc;
+ (*controlProc)(dev, &feedc->ctrl);
+ return TRUE;
+}
+
+Bool
+InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons, Atom* btn_labels,
+ PtrCtrlProcPtr controlProc, int numMotionEvents,
+ int numAxes, Atom *axes_labels)
+{
+ DeviceIntPtr dev = (DeviceIntPtr)device;
+
+ return(InitButtonClassDeviceStruct(dev, numButtons, btn_labels, map) &&
+ InitValuatorClassDeviceStruct(dev, numAxes, axes_labels,
+ numMotionEvents, Relative) &&
+ InitPtrFeedbackClassDeviceStruct(dev, controlProc));
+}
+
+/*
+ * Check if the given buffer contains elements between low (inclusive) and
+ * high (inclusive) only.
+ *
+ * @return TRUE if the device map is invalid, FALSE otherwise.
+ */
+Bool
+BadDeviceMap(BYTE *buff, int length, unsigned low, unsigned high, XID *errval)
+{
+ int i;
+
+ for (i = 0; i < length; i++)
+ if (buff[i]) /* only check non-zero elements */
+ {
+ if ((low > buff[i]) || (high < buff[i]))
+ {
+ *errval = buff[i];
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+int
+ProcSetModifierMapping(ClientPtr client)
+{
+ xSetModifierMappingReply rep;
+ int rc;
+ REQUEST(xSetModifierMappingReq);
+ REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq);
+
+ if (client->req_len != ((stuff->numKeyPerModifier << 1) +
+ bytes_to_int32(sizeof(xSetModifierMappingReq))))
+ return BadLength;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ rc = change_modmap(client, PickKeyboard(client), (KeyCode *)&stuff[1],
+ stuff->numKeyPerModifier);
+ if (rc == MappingFailed || rc == -1)
+ return BadValue;
+ if (rc != Success && rc != MappingSuccess && rc != MappingFailed &&
+ rc != MappingBusy)
+ return rc;
+
+ rep.success = rc;
+
+ WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep);
+ return Success;
+}
+
+int
+ProcGetModifierMapping(ClientPtr client)
+{
+ xGetModifierMappingReply rep;
+ int max_keys_per_mod = 0;
+ KeyCode *modkeymap = NULL;
+ REQUEST_SIZE_MATCH(xReq);
+
+ generate_modkeymap(client, PickKeyboard(client), &modkeymap,
+ &max_keys_per_mod);
+
+ memset(&rep, 0, sizeof(xGetModifierMappingReply));
+ rep.type = X_Reply;
+ 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(xGetModifierMappingReply), &rep);
+ (void)WriteToClient(client, max_keys_per_mod * 8, (char *) modkeymap);
+
+ free(modkeymap);
+
+ return Success;
+}
+
+int
+ProcChangeKeyboardMapping(ClientPtr client)
+{
+ REQUEST(xChangeKeyboardMappingReq);
+ unsigned len;
+ KeySymsRec keysyms;
+ DeviceIntPtr pDev, tmp;
+ int rc;
+ REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq);
+
+ len = client->req_len - bytes_to_int32(sizeof(xChangeKeyboardMappingReq));
+ if (len != (stuff->keyCodes * stuff->keySymsPerKeyCode))
+ return BadLength;
+
+ pDev = PickKeyboard(client);
+
+ if ((stuff->firstKeyCode < pDev->key->xkbInfo->desc->min_key_code) ||
+ (stuff->firstKeyCode > pDev->key->xkbInfo->desc->max_key_code)) {
+ client->errorValue = stuff->firstKeyCode;
+ return BadValue;
+
+ }
+ if (((unsigned)(stuff->firstKeyCode + stuff->keyCodes - 1) >
+ pDev->key->xkbInfo->desc->max_key_code) ||
+ (stuff->keySymsPerKeyCode == 0)) {
+ client->errorValue = stuff->keySymsPerKeyCode;
+ return BadValue;
+ }
+
+ keysyms.minKeyCode = stuff->firstKeyCode;
+ keysyms.maxKeyCode = stuff->firstKeyCode + stuff->keyCodes - 1;
+ keysyms.mapWidth = stuff->keySymsPerKeyCode;
+ keysyms.map = (KeySym *) &stuff[1];
+
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
+ if (rc != Success)
+ return rc;
+
+ XkbApplyMappingChange(pDev, &keysyms, stuff->firstKeyCode,
+ stuff->keyCodes, NULL, client);
+
+ for (tmp = inputInfo.devices; tmp; tmp = tmp->next) {
+ if (IsMaster(tmp) || tmp->u.master != pDev)
+ continue;
+ if (!tmp->key)
+ continue;
+
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
+ if (rc != Success)
+ continue;
+
+ XkbApplyMappingChange(tmp, &keysyms, stuff->firstKeyCode,
+ stuff->keyCodes, NULL, client);
+ }
+
+ return Success;
+}
+
+int
+ProcSetPointerMapping(ClientPtr client)
+{
+ BYTE *map;
+ int ret;
+ int i, j;
+ DeviceIntPtr ptr = PickPointer(client);
+ xSetPointerMappingReply rep;
+ REQUEST(xSetPointerMappingReq);
+ REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq);
+
+ if (client->req_len !=
+ bytes_to_int32(sizeof(xSetPointerMappingReq) + stuff->nElts))
+ return BadLength;
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.success = MappingSuccess;
+ map = (BYTE *)&stuff[1];
+
+ /* So we're bounded here by the number of core buttons. This check
+ * probably wants disabling through XFixes. */
+ /* MPX: With ClientPointer, we can return the right number of buttons.
+ * Let's just hope nobody changed ClientPointer between GetPointerMapping
+ * and SetPointerMapping
+ */
+ if (stuff->nElts != ptr->button->numButtons) {
+ client->errorValue = stuff->nElts;
+ return BadValue;
+ }
+
+ /* Core protocol specs don't allow for duplicate mappings; this check
+ * almost certainly wants disabling through XFixes too. */
+ for (i = 0; i < stuff->nElts; i++) {
+ for (j = i + 1; j < stuff->nElts; j++) {
+ if (map[i] && map[i] == map[j]) {
+ client->errorValue = map[i];
+ return BadValue;
+ }
+ }
+ }
+
+ ret = ApplyPointerMapping(ptr, map, stuff->nElts, client);
+ if (ret == MappingBusy)
+ rep.success = ret;
+ else if (ret == -1)
+ return BadValue;
+ else if (ret != Success)
+ return ret;
+
+ WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
+ return Success;
+}
+
+int
+ProcGetKeyboardMapping(ClientPtr client)
+{
+ xGetKeyboardMappingReply rep;
+ DeviceIntPtr kbd = PickKeyboard(client);
+ XkbDescPtr xkb;
+ KeySymsPtr syms;
+ int rc;
+ REQUEST(xGetKeyboardMappingReq);
+ REQUEST_SIZE_MATCH(xGetKeyboardMappingReq);
+
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ xkb = kbd->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(kbd);
+ if (!syms)
+ return BadAlloc;
+
+ memset(&rep, 0, sizeof(xGetKeyboardMappingReply));
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.keySymsPerKeyCode = syms->mapWidth;
+ /* length is a count of 4 byte quantities and KeySyms are 4 bytes */
+ rep.length = syms->mapWidth * stuff->count;
+ WriteReplyToClient(client, sizeof(xGetKeyboardMappingReply), &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;
+}
+
+int
+ProcGetPointerMapping(ClientPtr client)
+{
+ xGetPointerMappingReply rep;
+ /* Apps may get different values each time they call GetPointerMapping as
+ * the ClientPointer could change. */
+ DeviceIntPtr ptr = PickPointer(client);
+ ButtonClassPtr butc = ptr->button;
+ int rc;
+ REQUEST_SIZE_MATCH(xReq);
+
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.nElts = (butc) ? butc->numButtons : 0;
+ rep.length = ((unsigned)rep.nElts + (4-1))/4;
+ WriteReplyToClient(client, sizeof(xGetPointerMappingReply), &rep);
+ if (butc)
+ WriteToClient(client, (int)rep.nElts, (char *)&butc->map[1]);
+ return Success;
+}
+
+void
+NoteLedState(DeviceIntPtr keybd, int led, Bool on)
+{
+ KeybdCtrl *ctrl = &keybd->kbdfeed->ctrl;
+ if (on)
+ ctrl->leds |= ((Leds)1 << (led - 1));
+ else
+ ctrl->leds &= ~((Leds)1 << (led - 1));
+}
+
+int
+Ones(unsigned long mask) /* HACKMEM 169 */
+{
+ unsigned long y;
+
+ y = (mask >> 1) &033333333333;
+ y = mask - y - ((y >>1) & 033333333333);
+ return (((y + (y >> 3)) & 030707070707) % 077);
+}
+
+static int
+DoChangeKeyboardControl (ClientPtr client, DeviceIntPtr keybd, XID *vlist,
+ BITS32 vmask)
+{
+#define DO_ALL (-1)
+ KeybdCtrl ctrl;
+ int t;
+ int led = DO_ALL;
+ int key = DO_ALL;
+ BITS32 index2;
+ int mask = vmask, i;
+ XkbEventCauseRec cause;
+
+ ctrl = keybd->kbdfeed->ctrl;
+ while (vmask) {
+ index2 = (BITS32) lowbit (vmask);
+ vmask &= ~index2;
+ switch (index2) {
+ case KBKeyClickPercent:
+ t = (INT8)*vlist;
+ vlist++;
+ if (t == -1) {
+ t = defaultKeyboardControl.click;
+ }
+ else if (t < 0 || t > 100) {
+ client->errorValue = t;
+ return BadValue;
+ }
+ ctrl.click = t;
+ break;
+ case KBBellPercent:
+ t = (INT8)*vlist;
+ vlist++;
+ if (t == -1) {
+ t = defaultKeyboardControl.bell;
+ }
+ else if (t < 0 || t > 100) {
+ client->errorValue = t;
+ return BadValue;
+ }
+ ctrl.bell = t;
+ break;
+ case KBBellPitch:
+ t = (INT16)*vlist;
+ vlist++;
+ if (t == -1) {
+ t = defaultKeyboardControl.bell_pitch;
+ }
+ else if (t < 0) {
+ client->errorValue = t;
+ return BadValue;
+ }
+ ctrl.bell_pitch = t;
+ break;
+ case KBBellDuration:
+ t = (INT16)*vlist;
+ vlist++;
+ if (t == -1)
+ t = defaultKeyboardControl.bell_duration;
+ else if (t < 0) {
+ client->errorValue = t;
+ return BadValue;
+ }
+ ctrl.bell_duration = t;
+ break;
+ case KBLed:
+ led = (CARD8)*vlist;
+ vlist++;
+ if (led < 1 || led > 32) {
+ client->errorValue = led;
+ return BadValue;
+ }
+ if (!(mask & KBLedMode))
+ return BadMatch;
+ break;
+ case KBLedMode:
+ t = (CARD8)*vlist;
+ vlist++;
+ if (t == LedModeOff) {
+ if (led == DO_ALL)
+ ctrl.leds = 0x0;
+ else
+ ctrl.leds &= ~(((Leds)(1)) << (led - 1));
+ }
+ else if (t == LedModeOn) {
+ if (led == DO_ALL)
+ ctrl.leds = ~0L;
+ else
+ ctrl.leds |= (((Leds)(1)) << (led - 1));
+ }
+ else {
+ client->errorValue = t;
+ return BadValue;
+ }
+
+ XkbSetCauseCoreReq(&cause,X_ChangeKeyboardControl,client);
+ XkbSetIndicators(keybd,((led == DO_ALL) ? ~0L : (1L<<(led-1))),
+ ctrl.leds, &cause);
+ ctrl.leds = keybd->kbdfeed->ctrl.leds;
+
+ break;
+ case KBKey:
+ key = (KeyCode)*vlist;
+ vlist++;
+ if ((KeyCode)key < keybd->key->xkbInfo->desc->min_key_code ||
+ (KeyCode)key > keybd->key->xkbInfo->desc->max_key_code) {
+ client->errorValue = key;
+ return BadValue;
+ }
+ if (!(mask & KBAutoRepeatMode))
+ return BadMatch;
+ break;
+ case KBAutoRepeatMode:
+ i = (key >> 3);
+ mask = (1 << (key & 7));
+ t = (CARD8)*vlist;
+ vlist++;
+ if (key != DO_ALL)
+ XkbDisableComputedAutoRepeats(keybd,key);
+ if (t == AutoRepeatModeOff) {
+ if (key == DO_ALL)
+ ctrl.autoRepeat = FALSE;
+ else
+ ctrl.autoRepeats[i] &= ~mask;
+ }
+ else if (t == AutoRepeatModeOn) {
+ if (key == DO_ALL)
+ ctrl.autoRepeat = TRUE;
+ else
+ ctrl.autoRepeats[i] |= mask;
+ }
+ else if (t == AutoRepeatModeDefault) {
+ if (key == DO_ALL)
+ ctrl.autoRepeat = defaultKeyboardControl.autoRepeat;
+ else
+ ctrl.autoRepeats[i] =
+ (ctrl.autoRepeats[i] & ~mask) |
+ (defaultKeyboardControl.autoRepeats[i] & mask);
+ }
+ else {
+ client->errorValue = t;
+ return BadValue;
+ }
+ break;
+ default:
+ client->errorValue = mask;
+ return BadValue;
+ }
+ }
+ keybd->kbdfeed->ctrl = ctrl;
+
+ /* The XKB RepeatKeys control and core protocol global autorepeat */
+ /* value are linked */
+ XkbSetRepeatKeys(keybd, key, keybd->kbdfeed->ctrl.autoRepeat);
+
+ return Success;
+
+#undef DO_ALL
+}
+
+/**
+ * Changes kbd control on the ClientPointer and all attached SDs.
+ */
+int
+ProcChangeKeyboardControl (ClientPtr client)
+{
+ XID *vlist;
+ BITS32 vmask;
+ int ret = Success, error = Success;
+ DeviceIntPtr pDev = NULL, keyboard;
+ REQUEST(xChangeKeyboardControlReq);
+
+ REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq);
+
+ vmask = stuff->mask;
+ vlist = (XID *)&stuff[1];
+
+ if (client->req_len != (sizeof(xChangeKeyboardControlReq)>>2)+Ones(vmask))
+ return BadLength;
+
+ keyboard = PickKeyboard(client);
+
+ for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
+ if ((pDev == keyboard ||
+ (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard))
+ && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
+ ret = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
+ if (ret != Success)
+ return ret;
+ }
+ }
+
+ for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
+ if ((pDev == keyboard ||
+ (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard))
+ && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
+ ret = DoChangeKeyboardControl(client, pDev, vlist, vmask);
+ if (ret != Success)
+ error = ret;
+ }
+ }
+
+ return error;
+}
+
+int
+ProcGetKeyboardControl (ClientPtr client)
+{
+ int rc, i;
+ DeviceIntPtr kbd = PickKeyboard(client);
+ KeybdCtrl *ctrl = &kbd->kbdfeed->ctrl;
+ xGetKeyboardControlReply rep;
+ REQUEST_SIZE_MATCH(xReq);
+
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ rep.type = X_Reply;
+ rep.length = 5;
+ rep.sequenceNumber = client->sequence;
+ rep.globalAutoRepeat = ctrl->autoRepeat;
+ rep.keyClickPercent = ctrl->click;
+ rep.bellPercent = ctrl->bell;
+ rep.bellPitch = ctrl->bell_pitch;
+ rep.bellDuration = ctrl->bell_duration;
+ rep.ledMask = ctrl->leds;
+ for (i = 0; i < 32; i++)
+ rep.map[i] = ctrl->autoRepeats[i];
+ WriteReplyToClient(client, sizeof(xGetKeyboardControlReply), &rep);
+ return Success;
+}
+
+int
+ProcBell(ClientPtr client)
+{
+ DeviceIntPtr dev, keybd = PickKeyboard(client);
+ int base = keybd->kbdfeed->ctrl.bell;
+ int newpercent;
+ int rc;
+ REQUEST(xBellReq);
+ REQUEST_SIZE_MATCH(xBellReq);
+
+ if (stuff->percent < -100 || stuff->percent > 100) {
+ client->errorValue = stuff->percent;
+ return BadValue;
+ }
+
+ newpercent = (base * stuff->percent) / 100;
+ if (stuff->percent < 0)
+ newpercent = base + newpercent;
+ else
+ newpercent = base - newpercent + stuff->percent;
+
+ for (dev = inputInfo.devices; dev; dev = dev->next) {
+ if ((dev == keybd ||
+ (!IsMaster(dev) && GetMaster(dev, MASTER_KEYBOARD) == keybd)) &&
+ dev->kbdfeed && dev->kbdfeed->BellProc) {
+
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixBellAccess);
+ if (rc != Success)
+ return rc;
+ XkbHandleBell(FALSE, FALSE, dev, newpercent,
+ &dev->kbdfeed->ctrl, 0, None, NULL, client);
+ }
+ }
+
+ return Success;
+}
+
+int
+ProcChangePointerControl(ClientPtr client)
+{
+ DeviceIntPtr dev, mouse = PickPointer(client);
+ PtrCtrl ctrl; /* might get BadValue part way through */
+ int rc;
+ REQUEST(xChangePointerControlReq);
+ REQUEST_SIZE_MATCH(xChangePointerControlReq);
+
+ ctrl = mouse->ptrfeed->ctrl;
+ if ((stuff->doAccel != xTrue) && (stuff->doAccel != xFalse)) {
+ client->errorValue = stuff->doAccel;
+ return BadValue;
+ }
+ if ((stuff->doThresh != xTrue) && (stuff->doThresh != xFalse)) {
+ client->errorValue = stuff->doThresh;
+ return BadValue;
+ }
+ if (stuff->doAccel) {
+ if (stuff->accelNum == -1) {
+ ctrl.num = defaultPointerControl.num;
+ }
+ else if (stuff->accelNum < 0) {
+ client->errorValue = stuff->accelNum;
+ return BadValue;
+ }
+ else {
+ ctrl.num = stuff->accelNum;
+ }
+
+ if (stuff->accelDenum == -1) {
+ ctrl.den = defaultPointerControl.den;
+ }
+ else if (stuff->accelDenum <= 0) {
+ client->errorValue = stuff->accelDenum;
+ return BadValue;
+ }
+ else {
+ ctrl.den = stuff->accelDenum;
+ }
+ }
+ if (stuff->doThresh) {
+ if (stuff->threshold == -1) {
+ ctrl.threshold = defaultPointerControl.threshold;
+ }
+ else if (stuff->threshold < 0) {
+ client->errorValue = stuff->threshold;
+ return BadValue;
+ }
+ else {
+ ctrl.threshold = stuff->threshold;
+ }
+ }
+
+ for (dev = inputInfo.devices; dev; dev = dev->next) {
+ if ((dev == mouse ||
+ (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) &&
+ dev->ptrfeed) {
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess);
+ if (rc != Success)
+ return rc;
+ }
+ }
+
+ for (dev = inputInfo.devices; dev; dev = dev->next) {
+ if ((dev == mouse ||
+ (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) &&
+ dev->ptrfeed) {
+ dev->ptrfeed->ctrl = ctrl;
+ }
+ }
+
+ return Success;
+}
+
+int
+ProcGetPointerControl(ClientPtr client)
+{
+ DeviceIntPtr ptr = PickPointer(client);
+ PtrCtrl *ctrl = &ptr->ptrfeed->ctrl;
+ xGetPointerControlReply rep;
+ int rc;
+ REQUEST_SIZE_MATCH(xReq);
+
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.threshold = ctrl->threshold;
+ rep.accelNumerator = ctrl->num;
+ rep.accelDenominator = ctrl->den;
+ WriteReplyToClient(client, sizeof(xGenericReply), &rep);
+ return Success;
+}
+
+void
+MaybeStopHint(DeviceIntPtr dev, ClientPtr client)
+{
+ GrabPtr grab = dev->deviceGrab.grab;
+
+ if ((grab && SameClient(grab, client) &&
+ ((grab->eventMask & PointerMotionHintMask) ||
+ (grab->ownerEvents &&
+ (EventMaskForClient(dev->valuator->motionHintWindow, client) &
+ PointerMotionHintMask)))) ||
+ (!grab &&
+ (EventMaskForClient(dev->valuator->motionHintWindow, client) &
+ PointerMotionHintMask)))
+ dev->valuator->motionHintWindow = NullWindow;
+}
+
+int
+ProcGetMotionEvents(ClientPtr client)
+{
+ WindowPtr pWin;
+ xTimecoord * coords = (xTimecoord *) NULL;
+ xGetMotionEventsReply rep;
+ int i, count, xmin, xmax, ymin, ymax, rc;
+ unsigned long nEvents;
+ DeviceIntPtr mouse = PickPointer(client);
+ TimeStamp start, stop;
+ REQUEST(xGetMotionEventsReq);
+ REQUEST_SIZE_MATCH(xGetMotionEventsReq);
+
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, mouse, DixReadAccess);
+ if (rc != Success)
+ return rc;
+
+ if (mouse->valuator->motionHintWindow)
+ MaybeStopHint(mouse, client);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ nEvents = 0;
+ start = ClientTimeToServerTime(stuff->start);
+ stop = ClientTimeToServerTime(stuff->stop);
+ if ((CompareTimeStamps(start, stop) != LATER) &&
+ (CompareTimeStamps(start, currentTime) != LATER) &&
+ mouse->valuator->numMotionEvents)
+ {
+ if (CompareTimeStamps(stop, currentTime) == LATER)
+ stop = currentTime;
+ count = GetMotionHistory(mouse, &coords, start.milliseconds,
+ stop.milliseconds, pWin->drawable.pScreen,
+ TRUE);
+ xmin = pWin->drawable.x - wBorderWidth (pWin);
+ xmax = pWin->drawable.x + (int)pWin->drawable.width +
+ wBorderWidth (pWin);
+ ymin = pWin->drawable.y - wBorderWidth (pWin);
+ ymax = pWin->drawable.y + (int)pWin->drawable.height +
+ wBorderWidth (pWin);
+ for (i = 0; i < count; i++)
+ if ((xmin <= coords[i].x) && (coords[i].x < xmax) &&
+ (ymin <= coords[i].y) && (coords[i].y < ymax))
+ {
+ coords[nEvents].time = coords[i].time;
+ coords[nEvents].x = coords[i].x - pWin->drawable.x;
+ coords[nEvents].y = coords[i].y - pWin->drawable.y;
+ nEvents++;
+ }
+ }
+ rep.length = nEvents * bytes_to_int32(sizeof(xTimecoord));
+ rep.nEvents = nEvents;
+ WriteReplyToClient(client, sizeof(xGetMotionEventsReply), &rep);
+ if (nEvents)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) SwapTimeCoordWrite;
+ WriteSwappedDataToClient(client, nEvents * sizeof(xTimecoord),
+ (char *)coords);
+ }
+ free(coords);
+ return Success;
+}
+
+int
+ProcQueryKeymap(ClientPtr client)
+{
+ xQueryKeymapReply rep;
+ int rc, i;
+ DeviceIntPtr keybd = PickKeyboard(client);
+ CARD8 *down = keybd->key->down;
+
+ REQUEST_SIZE_MATCH(xReq);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 2;
+
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess);
+ if (rc != Success && rc != BadAccess)
+ return rc;
+
+ for (i = 0; i<32; i++)
+ rep.map[i] = down[i];
+
+ if (rc == BadAccess)
+ memset(rep.map, 0, 32);
+
+ WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep);
+
+ return Success;
+}
+
+
+/**
+ * Recalculate the number of buttons for the master device. The number of
+ * buttons on the master device is equal to the number of buttons on the
+ * slave device with the highest number of buttons.
+ */
+static void
+RecalculateMasterButtons(DeviceIntPtr slave)
+{
+ DeviceIntPtr dev, master;
+ int maxbuttons = 0;
+
+ if (!slave->button || IsMaster(slave))
+ return;
+
+ master = GetMaster(slave, MASTER_POINTER);
+ if (!master)
+ return;
+
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (IsMaster(dev) ||
+ dev->u.master != master ||
+ !dev->button)
+ continue;
+
+ maxbuttons = max(maxbuttons, dev->button->numButtons);
+ }
+
+ if (master->button && master->button->numButtons != maxbuttons)
+ {
+ int i;
+ DeviceChangedEvent event;
+
+ memset(&event, 0, sizeof(event));
+
+ master->button->numButtons = maxbuttons;
+
+ event.header = ET_Internal;
+ event.type = ET_DeviceChanged;
+ event.time = GetTimeInMillis();
+ event.deviceid = master->id;
+ event.flags = DEVCHANGE_POINTER_EVENT | DEVCHANGE_DEVICE_CHANGE;
+ event.buttons.num_buttons = maxbuttons;
+ memcpy(&event.buttons.names, master->button->labels, maxbuttons *
+ sizeof(Atom));
+
+ if (master->valuator)
+ {
+ event.num_valuators = master->valuator->numAxes;
+ for (i = 0; i < event.num_valuators; i++)
+ {
+ event.valuators[i].min = master->valuator->axes[i].min_value;
+ event.valuators[i].max = master->valuator->axes[i].max_value;
+ event.valuators[i].resolution = master->valuator->axes[i].resolution;
+ event.valuators[i].mode = master->valuator->axes[i].mode;
+ event.valuators[i].name = master->valuator->axes[i].label;
+ }
+ }
+
+ if (master->key)
+ {
+ event.keys.min_keycode = master->key->xkbInfo->desc->min_key_code;
+ event.keys.max_keycode = master->key->xkbInfo->desc->max_key_code;
+ }
+
+ XISendDeviceChangedEvent(master, master, &event);
+ }
+}
+
+/**
+ * Attach device 'dev' to device 'master'.
+ * Client is set to the client that issued the request, or NULL if it comes
+ * from some internal automatic pairing.
+ *
+ * Master may be NULL to set the device floating.
+ *
+ * We don't allow multi-layer hierarchies right now. You can't attach a slave
+ * to another slave.
+ */
+int
+AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
+{
+ ScreenPtr screen;
+ DeviceIntPtr oldmaster;
+ if (!dev || IsMaster(dev))
+ return BadDevice;
+
+ if (master && !IsMaster(master)) /* can't attach to slaves */
+ return BadDevice;
+
+ /* set from floating to floating? */
+ if (!dev->u.master && !master && dev->enabled)
+ return Success;
+
+ /* free the existing sprite. */
+ if (!dev->u.master && dev->spriteInfo->paired == dev)
+ {
+ screen = miPointerGetScreen(dev);
+ screen->DeviceCursorCleanup(dev, screen);
+ free(dev->spriteInfo->sprite);
+ }
+
+ oldmaster = dev->u.master;
+ dev->u.master = master;
+
+ /* If device is set to floating, we need to create a sprite for it,
+ * otherwise things go bad. However, we don't want to render the cursor,
+ * so we reset spriteOwner.
+ * Sprite has to be forced to NULL first, otherwise InitializeSprite won't
+ * alloc new memory but overwrite the previous one.
+ */
+ if (!master)
+ {
+ WindowPtr currentRoot;
+
+ if (dev->spriteInfo->sprite)
+ currentRoot = GetCurrentRootWindow(dev);
+ else /* new device auto-set to floating */
+ currentRoot = screenInfo.screens[0]->root;
+
+ /* we need to init a fake sprite */
+ screen = currentRoot->drawable.pScreen;
+ screen->DeviceCursorInitialize(dev, screen);
+ dev->spriteInfo->sprite = NULL;
+ InitializeSprite(dev, currentRoot);
+ dev->spriteInfo->spriteOwner = FALSE;
+ dev->spriteInfo->paired = dev;
+ } else
+ {
+ dev->spriteInfo->sprite = master->spriteInfo->sprite;
+ dev->spriteInfo->paired = master;
+ dev->spriteInfo->spriteOwner = FALSE;
+
+ RecalculateMasterButtons(master);
+ }
+
+ /* XXX: in theory, the MD should change back to its old, original
+ * classes when the last SD is detached. Thanks to the XTEST devices,
+ * we'll always have an SD attached until the MD is removed.
+ * So let's not worry about that.
+ */
+
+ return Success;
+}
+
+/**
+ * Return the device paired with the given device or NULL.
+ * Returns the device paired with the parent master if the given device is a
+ * slave device.
+ */
+DeviceIntPtr
+GetPairedDevice(DeviceIntPtr dev)
+{
+ if (!IsMaster(dev) && dev->u.master)
+ dev = dev->u.master;
+
+ return dev->spriteInfo->paired;
+}
+
+
+/**
+ * Returns the right master for the type of event needed. If the event is a
+ * keyboard event.
+ * This function may be called with a master device as argument. If so, the
+ * returned master is either the device itself or the paired master device.
+ * If dev is a floating slave device, NULL is returned.
+ *
+ * @type ::MASTER_KEYBOARD or ::MASTER_POINTER
+ */
+DeviceIntPtr
+GetMaster(DeviceIntPtr dev, int which)
+{
+ DeviceIntPtr master;
+
+ if (IsMaster(dev))
+ master = dev;
+ else
+ master = dev->u.master;
+
+ if (master)
+ {
+ if (which == MASTER_KEYBOARD)
+ {
+ if (master->type != MASTER_KEYBOARD)
+ master = GetPairedDevice(master);
+ } else
+ {
+ if (master->type != MASTER_POINTER)
+ master = GetPairedDevice(master);
+ }
+ }
+
+ return master;
+}
+
+/**
+ * Create a new device pair (== one pointer, one keyboard device).
+ * Only allocates the devices, you will need to call ActivateDevice() and
+ * EnableDevice() manually.
+ * Either a master or a slave device can be created depending on
+ * the value for master.
+ */
+int
+AllocDevicePair (ClientPtr client, char* name,
+ DeviceIntPtr* ptr,
+ DeviceIntPtr* keybd,
+ DeviceProc ptr_proc,
+ DeviceProc keybd_proc,
+ Bool master)
+{
+ DeviceIntPtr pointer;
+ DeviceIntPtr keyboard;
+ *ptr = *keybd = NULL;
+
+ pointer = AddInputDevice(client, ptr_proc, TRUE);
+ if (!pointer)
+ return BadAlloc;
+
+ if (asprintf(&pointer->name, "%s pointer", name) == -1) {
+ pointer->name = NULL;
+ RemoveDevice(pointer, FALSE);
+ return BadAlloc;
+ }
+
+ pointer->public.processInputProc = ProcessOtherEvent;
+ pointer->public.realInputProc = ProcessOtherEvent;
+ XkbSetExtension(pointer, ProcessPointerEvent);
+ pointer->deviceGrab.ActivateGrab = ActivatePointerGrab;
+ pointer->deviceGrab.DeactivateGrab = DeactivatePointerGrab;
+ pointer->coreEvents = TRUE;
+ pointer->spriteInfo->spriteOwner = TRUE;
+
+ pointer->u.lastSlave = NULL;
+ pointer->last.slave = NULL;
+ pointer->type = (master) ? MASTER_POINTER : SLAVE;
+
+ keyboard = AddInputDevice(client, keybd_proc, TRUE);
+ if (!keyboard)
+ {
+ RemoveDevice(pointer, FALSE);
+ return BadAlloc;
+ }
+
+ if (asprintf(&keyboard->name, "%s keyboard", name) == -1) {
+ keyboard->name = NULL;
+ RemoveDevice(keyboard, FALSE);
+ RemoveDevice(pointer, FALSE);
+ return BadAlloc;
+ }
+
+ keyboard->public.processInputProc = ProcessOtherEvent;
+ keyboard->public.realInputProc = ProcessOtherEvent;
+ XkbSetExtension(keyboard, ProcessKeyboardEvent);
+ keyboard->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
+ keyboard->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
+ keyboard->coreEvents = TRUE;
+ keyboard->spriteInfo->spriteOwner = FALSE;
+
+ keyboard->u.lastSlave = NULL;
+ keyboard->last.slave = NULL;
+ keyboard->type = (master) ? MASTER_KEYBOARD : SLAVE;
+
+ /* The ClassesRec stores the device classes currently not used. */
+ pointer->unused_classes = calloc(1, sizeof(ClassesRec));
+ keyboard->unused_classes = calloc(1, sizeof(ClassesRec));
+
+ *ptr = pointer;
+ *keybd = keyboard;
+
+ return Success;
+}
+
+/**
+ * Return Relative or Absolute for the device.
+ */
+int valuator_get_mode(DeviceIntPtr dev, int axis)
+{
+ return (dev->valuator->axes[axis].mode & DeviceMode);
+}
+
+/**
+ * Set the given mode for the axis. If axis is VALUATOR_MODE_ALL_AXES, then
+ * set the mode for all axes.
+ */
+void valuator_set_mode(DeviceIntPtr dev, int axis, int mode)
+{
+ if (axis != VALUATOR_MODE_ALL_AXES)
+ dev->valuator->axes[axis].mode = mode;
+ else {
+ int i;
+ for (i = 0; i < dev->valuator->numAxes; i++)
+ dev->valuator->axes[i].mode = mode;
+ }
+}
diff --git a/xorg-server/dix/dispatch.c b/xorg-server/dix/dispatch.c index 2474c2f3b..87b27dfa6 100644 --- a/xorg-server/dix/dispatch.c +++ b/xorg-server/dix/dispatch.c @@ -104,6 +104,10 @@ Equipment Corporation. #include <version-config.h>
#endif
+#ifdef CreateWindow
+#undef CreateWindow
+#endif
+
#ifdef PANORAMIX_DEBUG
#include <stdio.h>
int ProcInitialConnection();
@@ -395,6 +399,9 @@ Dispatch(void) start_tick = SmartScheduleTime;
while (!isItTimeToYield)
{
+#ifdef XSERVER_DTRACE
+ CARD8 StartMajorOp;
+#endif
if (*icheck[0] != *icheck[1])
ProcessInputEvents();
@@ -419,7 +426,8 @@ Dispatch(void) client->sequence++;
#ifdef XSERVER_DTRACE
- XSERVER_REQUEST_START(LookupMajorName(MAJOROP), MAJOROP,
+ StartMajorOp=MAJOROP;
+ XSERVER_REQUEST_START(LookupMajorName(StartMajorOp), StartMajorOp,
((xReq *)client->requestBuffer)->length,
client->index, client->requestBuffer);
#endif
@@ -432,8 +440,28 @@ Dispatch(void) XaceHookAuditEnd(client, result);
}
#ifdef XSERVER_DTRACE
- XSERVER_REQUEST_DONE(LookupMajorName(MAJOROP), MAJOROP,
- client->sequence, client->index, result);
+ if (result!=Success)
+ {
+ char Message[255];
+ sprintf(Message,"ERROR: %s (0x%x)",LookupMajorName(StartMajorOp),client->errorValue);
+ XSERVER_REQUEST_DONE(Message, MAJOROP,
+ client->sequence, client->index, result);
+ }
+ else
+ {
+ if (StartMajorOp!=MAJOROP)
+ {
+ char Message[255];
+ sprintf(Message,"Changed request: %s -> %s",LookupMajorName(StartMajorOp),LookupMajorName(MAJOROP));
+ XSERVER_REQUEST_DONE(Message, MAJOROP,
+ client->sequence, client->index, result);
+ }
+ else
+ {
+ XSERVER_REQUEST_DONE(LookupMajorName(MAJOROP), MAJOROP,
+ client->sequence, client->index, result);
+ }
+ }
#endif
if (client->noClientException != Success)
@@ -946,6 +974,13 @@ ProcGetGeometry(ClientPtr client) return Success;
}
+#ifdef WIN32
+/* Do not return the clipboard window in ProcQueryTree, cause this may cause
+ the clipboard client being closed when connecting through xdmcp.
+*/
+extern Window g_iClipboardWindow;
+
+#endif
int
ProcQueryTree(ClientPtr client)
@@ -970,7 +1005,10 @@ ProcQueryTree(ClientPtr client) reply.parent = (Window)None;
pHead = RealChildHead(pWin);
for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
- numChildren++;
+#ifdef WIN32
+ if (pChild->drawable.id!=g_iClipboardWindow)
+#endif
+ numChildren++;
if (numChildren)
{
int curChild = 0;
@@ -979,7 +1017,10 @@ ProcQueryTree(ClientPtr client) if (!childIDs)
return BadAlloc;
for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
- childIDs[curChild++] = pChild->drawable.id;
+#ifdef WIN32
+ if (pChild->drawable.id!=g_iClipboardWindow)
+#endif
+ childIDs[curChild++] = pChild->drawable.id;
}
reply.nChildren = numChildren;
diff --git a/xorg-server/dix/dixfonts.c b/xorg-server/dix/dixfonts.c index d8f15290b..fec32bb98 100644 --- a/xorg-server/dix/dixfonts.c +++ b/xorg-server/dix/dixfonts.c @@ -130,6 +130,7 @@ SetDefaultFont(char *defaultfontname) int err; FontPtr pf; XID fid; + static FontPtr last_pf; fid = FakeClientID(0); err = OpenFont(serverClient, fid, FontLoadAll | FontOpenSync, @@ -138,9 +139,10 @@ SetDefaultFont(char *defaultfontname) return FALSE; err = dixLookupResourceByType((pointer *)&pf, fid, RT_FONT, serverClient, DixReadAccess); - if (err != Success) + if (err == Success) last_pf = pf; + if (last_pf == (FontPtr) NULL) return FALSE; - defaultFont = pf; + defaultFont = last_pf; return TRUE; } @@ -239,6 +241,8 @@ doOpenFont(ClientPtr client, OFclosurePtr c) *newname; int newlen; int aliascount = 20; + Bool fromDispatch = c->from_dispatch; + Bool finished = FALSE; /* * Decide at runtime what FontFormat to use. */ @@ -270,6 +274,8 @@ doOpenFont(ClientPtr client, OFclosurePtr c) BitmapFormatScanlineUnit8; + c->from_dispatch = FALSE; + if (client->clientGone) { if (c->current_fpe < c->num_fpes) @@ -374,13 +380,16 @@ bail: c->fontid, FontToXError(err)); } ClientWakeup(c->client); + finished = TRUE; xinerama_sleep: - for (i = 0; i < c->num_fpes; i++) { - FreeFPE(c->fpe_list[i]); + if (finished || fromDispatch) { + for (i = 0; i < c->num_fpes; i++) { + FreeFPE(c->fpe_list[i]); + } + free(c->fpe_list); + free(c->fontname); + free(c); } - free(c->fpe_list); - free(c->fontname); - free(c); return TRUE; } @@ -461,6 +470,7 @@ OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, char *pfontna c->num_fpes = num_fpes; c->fnamelen = lenfname; c->flags = flags; + c->from_dispatch = TRUE; c->non_cachable_font = cached; (void) doOpenFont(client, c); @@ -592,6 +602,10 @@ doListFontsAndAliases(ClientPtr client, LFclosurePtr c) char *bufptr; char *bufferStart; int aliascount = 0; + Bool fromDispatch = c->from_dispatch; + Bool finished = FALSE; + + c->from_dispatch = FALSE; if (client->clientGone) { @@ -822,13 +836,16 @@ finish: bail: ClientWakeup(client); + finished = TRUE; xinerama_sleep: - for (i = 0; i < c->num_fpes; i++) - FreeFPE(c->fpe_list[i]); - free(c->fpe_list); - free(c->savedName); - FreeFontNames(names); - free(c); + if (finished || fromDispatch) { + for (i = 0; i < c->num_fpes; i++) + FreeFPE(c->fpe_list[i]); + free(c->fpe_list); + free(c->savedName); + FreeFontNames(names); + free(c); + } free(resolved); return TRUE; } @@ -880,6 +897,7 @@ ListFonts(ClientPtr client, unsigned char *pattern, unsigned length, c->current.list_started = FALSE; c->current.private = 0; c->haveSaved = FALSE; + c->from_dispatch = TRUE; c->savedName = 0; doListFontsAndAliases(client, c); return Success; @@ -891,6 +909,8 @@ doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c) FontPathElementPtr fpe; int err = Successful; char *name; + Bool fromDispatch = c->from_dispatch; + Bool finished = FALSE; int namelen; int numFonts; FontInfoRec fontInfo, @@ -902,6 +922,8 @@ doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c) int aliascount = 0; xListFontsWithInfoReply finalReply; + c->from_dispatch = FALSE; + if (client->clientGone) { if (c->current.current_fpe < c->num_fpes) @@ -1095,13 +1117,16 @@ finish: WriteSwappedDataToClient(client, length, &finalReply); bail: ClientWakeup(client); + finished = TRUE; xinerama_sleep: - for (i = 0; i < c->num_fpes; i++) - FreeFPE(c->fpe_list[i]); - free(c->reply); - free(c->fpe_list); - free(c->savedName); - free(c); + if (finished || fromDispatch) { + for (i = 0; i < c->num_fpes; i++) + FreeFPE(c->fpe_list[i]); + free(c->reply); + free(c->fpe_list); + free(c->savedName); + free(c); + } return TRUE; } @@ -1150,6 +1175,7 @@ StartListFontsWithInfo(ClientPtr client, int length, unsigned char *pattern, c->current.private = 0; c->savedNumFonts = 0; c->haveSaved = FALSE; + c->from_dispatch = TRUE; c->savedName = 0; doListFontsWithInfo(client, c); return Success; @@ -1159,7 +1185,7 @@ badAlloc: #define TextEltHeader 2 #define FontShiftSize 5 -static ChangeGCVal clearGC[] = { { .ptr = NullPixmap } }; +static ChangeGCVal clearGC[] = { NullPixmap }; #define clearGCmask (GCClipMask) int @@ -1171,6 +1197,10 @@ doPolyText(ClientPtr client, PTclosurePtr c) FontPathElementPtr fpe; GC *origGC = NULL; int itemSize = c->reqType == X_PolyText8 ? 1 : 2; + Bool fromDispatch = c->from_dispatch; + Bool finished = FALSE; + + c->from_dispatch = FALSE; if (client->clientGone) { @@ -1417,16 +1447,19 @@ bail: if (ClientIsAsleep(client)) { ClientWakeup(c->client); + finished = TRUE; xinerama_sleep: - ChangeGC(NullClient, c->pGC, clearGCmask, clearGC); + if (finished || fromDispatch) { + ChangeGC(NullClient, c->pGC, clearGCmask, clearGC); - /* Unreference the font from the scratch GC */ - CloseFont(c->pGC->font, (Font)0); - c->pGC->font = NullFont; + /* Unreference the font from the scratch GC */ + CloseFont(c->pGC->font, (Font)0); + c->pGC->font = NullFont; - FreeScratchGC(c->pGC); - free(c->data); - free(c); + FreeScratchGC(c->pGC); + free(c->data); + free(c); + } } return TRUE; } @@ -1462,6 +1495,10 @@ doImageText(ClientPtr client, ITclosurePtr c) int err = Success, lgerr; /* err is in X error, not font error, space */ FontPathElementPtr fpe; int itemSize = c->reqType == X_ImageText8 ? 1 : 2; + Bool fromDispatch = c->from_dispatch; + Bool finished = FALSE; + + c->from_dispatch = FALSE; if (client->clientGone) { @@ -1571,16 +1608,19 @@ bail: if (ClientIsAsleep(client)) { ClientWakeup(c->client); + finished = TRUE; xinerama_sleep: - ChangeGC(NullClient, c->pGC, clearGCmask, clearGC); + if (finished || fromDispatch) { + ChangeGC(NullClient, c->pGC, clearGCmask, clearGC); - /* Unreference the font from the scratch GC */ - CloseFont(c->pGC->font, (Font)0); - c->pGC->font = NullFont; + /* Unreference the font from the scratch GC */ + CloseFont(c->pGC->font, (Font)0); + c->pGC->font = NullFont; - FreeScratchGC(c->pGC); - free(c->data); - free(c); + FreeScratchGC(c->pGC); + free(c->data); + free(c); + } } return TRUE; } diff --git a/xorg-server/dix/eventconvert.c b/xorg-server/dix/eventconvert.c index dd1ca460b..1009550c3 100644 --- a/xorg-server/dix/eventconvert.c +++ b/xorg-server/dix/eventconvert.c @@ -1,746 +1,746 @@ -/* - * 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. - * - */ - -/** - * @file eventconvert.c - * This file contains event conversion routines from InternalEvent to the - * matching protocol events. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <stdint.h> -#include <X11/X.h> -#include <X11/extensions/XIproto.h> -#include <X11/extensions/XI2proto.h> -#include <X11/extensions/XI.h> -#include <X11/extensions/XI2.h> - -#include "dix.h" -#include "inputstr.h" -#include "misc.h" -#include "eventstr.h" -#include "exglobals.h" -#include "eventconvert.h" -#include "xiquerydevice.h" -#include "xkbsrv.h" - - -static int countValuators(DeviceEvent *ev, int *first); -static int getValuatorEvents(DeviceEvent *ev, deviceValuator *xv); -static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count); -static int eventToDeviceChanged(DeviceChangedEvent *ev, xEvent **dcce); -static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi); -static int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi); - -/* Do not use, read comments below */ -BOOL EventIsKeyRepeat(xEvent *event); - -/** - * Hack to allow detectable autorepeat for core and XI1 events. - * The sequence number is unused until we send to the client and can be - * misused to store data. More or less, anyway. - * - * Do not use this. It may change any time without warning, eat your babies - * and piss on your cat. - */ -static void -EventSetKeyRepeatFlag(xEvent *event, BOOL on) -{ - event->u.u.sequenceNumber = on; -} - -/** - * Check if the event was marked as a repeat event before. - * NOTE: This is a nasty hack and should NOT be used by anyone else but - * TryClientEvents. - */ -BOOL -EventIsKeyRepeat(xEvent *event) -{ - return !!event->u.u.sequenceNumber; -} - -/** - * Convert the given event to the respective core event. - * - * Return values: - * Success ... core contains the matching core event. - * BadValue .. One or more values in the internal event are invalid. - * BadMatch .. The event has no core equivalent. - * - * @param[in] event The event to convert into a core event. - * @param[in] core The memory location to store the core event at. - * @return Success or the matching error code. - */ -int -EventToCore(InternalEvent *event, xEvent *core) -{ - switch(event->any.type) - { - case ET_Motion: - { - DeviceEvent *e = &event->device_event; - /* Don't create core motion event if neither x nor y are - * present */ - if (!BitIsOn(e->valuators.mask, 0) && - !BitIsOn(e->valuators.mask, 1)) - return BadMatch; - } - /* fallthrough */ - case ET_ButtonPress: - case ET_ButtonRelease: - case ET_KeyPress: - case ET_KeyRelease: - { - DeviceEvent *e = &event->device_event; - - if (e->detail.key > 0xFF) - return BadMatch; - - memset(core, 0, sizeof(xEvent)); - core->u.u.type = e->type - ET_KeyPress + KeyPress; - core->u.u.detail = e->detail.key & 0xFF; - core->u.keyButtonPointer.time = e->time; - core->u.keyButtonPointer.rootX = e->root_x; - core->u.keyButtonPointer.rootY = e->root_y; - core->u.keyButtonPointer.state = e->corestate; - core->u.keyButtonPointer.root = e->root; - EventSetKeyRepeatFlag(core, (e->type == ET_KeyPress && e->key_repeat)); - } - break; - case ET_ProximityIn: - case ET_ProximityOut: - case ET_RawKeyPress: - case ET_RawKeyRelease: - case ET_RawButtonPress: - case ET_RawButtonRelease: - case ET_RawMotion: - return BadMatch; - default: - /* XXX: */ - ErrorF("[dix] EventToCore: Not implemented yet \n"); - return BadImplementation; - } - return Success; -} - -/** - * Convert the given event to the respective XI 1.x event and store it in - * xi. xi is allocated on demand and must be freed by the caller. - * count returns the number of events in xi. If count is 1, and the type of - * xi is GenericEvent, then xi may be larger than 32 bytes. - * - * Return values: - * Success ... core contains the matching core event. - * BadValue .. One or more values in the internal event are invalid. - * BadMatch .. The event has no XI equivalent. - * - * @param[in] ev The event to convert into an XI 1 event. - * @param[out] xi Future memory location for the XI event. - * @param[out] count Number of elements in xi. - * - * @return Success or the error code. - */ -int -EventToXI(InternalEvent *ev, xEvent **xi, int *count) -{ - switch (ev->any.type) - { - case ET_Motion: - case ET_ButtonPress: - case ET_ButtonRelease: - case ET_KeyPress: - case ET_KeyRelease: - case ET_ProximityIn: - case ET_ProximityOut: - return eventToKeyButtonPointer(&ev->device_event, xi, count); - case ET_DeviceChanged: - case ET_RawKeyPress: - case ET_RawKeyRelease: - case ET_RawButtonPress: - case ET_RawButtonRelease: - case ET_RawMotion: - *count = 0; - *xi = NULL; - return BadMatch; - default: - break; - } - - ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->any.type); - return BadImplementation; -} - -/** - * Convert the given event to the respective XI 2.x event and store it in xi. - * xi is allocated on demand and must be freed by the caller. - * - * Return values: - * Success ... core contains the matching core event. - * BadValue .. One or more values in the internal event are invalid. - * BadMatch .. The event has no XI2 equivalent. - * - * @param[in] ev The event to convert into an XI2 event - * @param[out] xi Future memory location for the XI2 event. - * - * @return Success or the error code. - */ -int -EventToXI2(InternalEvent *ev, xEvent **xi) -{ - switch (ev->any.type) - { - /* Enter/FocusIn are for grabs. We don't need an actual event, since - * the real events delivered are triggered elsewhere */ - case ET_Enter: - case ET_FocusIn: - *xi = NULL; - return Success; - case ET_Motion: - case ET_ButtonPress: - case ET_ButtonRelease: - case ET_KeyPress: - case ET_KeyRelease: - return eventToDeviceEvent(&ev->device_event, xi); - case ET_ProximityIn: - case ET_ProximityOut: - *xi = NULL; - return BadMatch; - case ET_DeviceChanged: - return eventToDeviceChanged(&ev->changed_event, xi); - case ET_RawKeyPress: - case ET_RawKeyRelease: - case ET_RawButtonPress: - case ET_RawButtonRelease: - case ET_RawMotion: - return eventToRawEvent(&ev->raw_event, xi); - default: - break; - } - - ErrorF("[dix] EventToXI2: Not implemented for %d \n", ev->any.type); - return BadImplementation; -} - -static int -eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count) -{ - int num_events; - int first; /* dummy */ - deviceKeyButtonPointer *kbp; - - /* Sorry, XI 1.x protocol restrictions. */ - if (ev->detail.button > 0xFF || ev->deviceid >= 0x80) - { - *count = 0; - return Success; - } - - num_events = (countValuators(ev, &first) + 5)/6; /* valuator ev */ - if (num_events <= 0) - { - switch (ev->type) - { - case ET_KeyPress: - case ET_KeyRelease: - case ET_ButtonPress: - case ET_ButtonRelease: - /* no axes is ok */ - break; - case ET_Motion: - case ET_ProximityIn: - case ET_ProximityOut: - *count = 0; - return BadMatch; - } - } - - num_events++; /* the actual event event */ - - *xi = calloc(num_events, sizeof(xEvent)); - if (!(*xi)) - { - return BadAlloc; - } - - kbp = (deviceKeyButtonPointer*)(*xi); - kbp->detail = ev->detail.button; - kbp->time = ev->time; - kbp->root = ev->root; - kbp->root_x = ev->root_x; - kbp->root_y = ev->root_y; - kbp->deviceid = ev->deviceid; - kbp->state = ev->corestate; - EventSetKeyRepeatFlag((xEvent*)kbp, - (ev->type == ET_KeyPress && ev->key_repeat)); - - if (num_events > 1) - kbp->deviceid |= MORE_EVENTS; - - switch(ev->type) - { - case ET_Motion: kbp->type = DeviceMotionNotify; break; - case ET_ButtonPress: kbp->type = DeviceButtonPress; break; - case ET_ButtonRelease: kbp->type = DeviceButtonRelease; break; - case ET_KeyPress: kbp->type = DeviceKeyPress; break; - case ET_KeyRelease: kbp->type = DeviceKeyRelease; break; - case ET_ProximityIn: kbp->type = ProximityIn; break; - case ET_ProximityOut: kbp->type = ProximityOut; break; - default: - break; - } - - if (num_events > 1) - { - getValuatorEvents(ev, (deviceValuator*)(kbp + 1)); - } - - *count = num_events; - return Success; -} - - -/** - * Set first to the first valuator in the event ev and return the number of - * valuators from first to the last set valuator. - */ -static int -countValuators(DeviceEvent *ev, int *first) -{ - int first_valuator = -1, last_valuator = -1, num_valuators = 0; - int i; - - for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) - { - if (BitIsOn(ev->valuators.mask, i)) - { - if (first_valuator == -1) - first_valuator = i; - last_valuator = i; - } - } - - if (first_valuator != -1) - { - num_valuators = last_valuator - first_valuator + 1; - *first = first_valuator; - } - - return num_valuators; -} - -static int -getValuatorEvents(DeviceEvent *ev, deviceValuator *xv) -{ - int i; - int state = 0; - int first_valuator, num_valuators; - - - num_valuators = countValuators(ev, &first_valuator); - if (num_valuators > 0) - { - DeviceIntPtr dev = NULL; - dixLookupDevice(&dev, ev->deviceid, serverClient, DixUseAccess); - /* State needs to be assembled BEFORE the device is updated. */ - state = (dev && dev->key) ? XkbStateFieldFromRec(&dev->key->xkbInfo->state) : 0; - state |= (dev && dev->button) ? (dev->button->state) : 0; - } - - /* FIXME: non-continuous valuator data in internal events*/ - for (i = 0; i < num_valuators; i += 6, xv++) { - xv->type = DeviceValuator; - xv->first_valuator = first_valuator + i; - xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i); - xv->deviceid = ev->deviceid; - xv->device_state = state; - switch (xv->num_valuators) { - case 6: - xv->valuator5 = ev->valuators.data[xv->first_valuator + 5]; - case 5: - xv->valuator4 = ev->valuators.data[xv->first_valuator + 4]; - case 4: - xv->valuator3 = ev->valuators.data[xv->first_valuator + 3]; - case 3: - xv->valuator2 = ev->valuators.data[xv->first_valuator + 2]; - case 2: - xv->valuator1 = ev->valuators.data[xv->first_valuator + 1]; - case 1: - xv->valuator0 = ev->valuators.data[xv->first_valuator + 0]; - } - - if (i + 6 < num_valuators) - xv->deviceid |= MORE_EVENTS; - } - - return (num_valuators + 5) / 6; -} - - -static int -appendKeyInfo(DeviceChangedEvent *dce, xXIKeyInfo* info) -{ - uint32_t *kc; - int i; - - info->type = XIKeyClass; - info->num_keycodes = dce->keys.max_keycode - dce->keys.min_keycode + 1; - info->length = sizeof(xXIKeyInfo)/4 + info->num_keycodes; - info->sourceid = dce->sourceid; - - kc = (uint32_t*)&info[1]; - for (i = 0; i < info->num_keycodes; i++) - *kc++ = i + dce->keys.min_keycode; - - return info->length * 4; -} - -static int -appendButtonInfo(DeviceChangedEvent *dce, xXIButtonInfo *info) -{ - unsigned char *bits; - int mask_len; - - mask_len = bytes_to_int32(bits_to_bytes(dce->buttons.num_buttons)); - - info->type = XIButtonClass; - info->num_buttons = dce->buttons.num_buttons; - info->length = bytes_to_int32(sizeof(xXIButtonInfo)) + - info->num_buttons + mask_len; - info->sourceid = dce->sourceid; - - bits = (unsigned char*)&info[1]; - memset(bits, 0, mask_len * 4); - /* FIXME: is_down? */ - - bits += mask_len * 4; - memcpy(bits, dce->buttons.names, dce->buttons.num_buttons * sizeof(Atom)); - - return info->length * 4; -} - -static int -appendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo *info, int axisnumber) -{ - info->type = XIValuatorClass; - info->length = sizeof(xXIValuatorInfo)/4; - info->label = dce->valuators[axisnumber].name; - info->min.integral = dce->valuators[axisnumber].min; - info->min.frac = 0; - info->max.integral = dce->valuators[axisnumber].max; - info->max.frac = 0; - /* FIXME: value */ - info->value.integral = 0; - info->value.frac = 0; - info->resolution = dce->valuators[axisnumber].resolution; - info->number = axisnumber; - info->mode = dce->valuators[axisnumber].mode; - info->sourceid = dce->sourceid; - - return info->length * 4; -} - -static int -eventToDeviceChanged(DeviceChangedEvent *dce, xEvent **xi) -{ - xXIDeviceChangedEvent *dcce; - int len = sizeof(xXIDeviceChangedEvent); - int nkeys; - char *ptr; - - if (dce->buttons.num_buttons) - { - len += sizeof(xXIButtonInfo); - len += dce->buttons.num_buttons * sizeof(Atom); /* button names */ - len += pad_to_int32(bits_to_bytes(dce->buttons.num_buttons)); - } - if (dce->num_valuators) - len += sizeof(xXIValuatorInfo) * dce->num_valuators; - - nkeys = (dce->keys.max_keycode > 0) ? - dce->keys.max_keycode - dce->keys.min_keycode + 1 : 0; - if (nkeys > 0) - { - len += sizeof(xXIKeyInfo); - len += sizeof(CARD32) * nkeys; /* keycodes */ - } - - dcce = calloc(1, len); - if (!dcce) - { - ErrorF("[Xi] BadAlloc in SendDeviceChangedEvent.\n"); - return BadAlloc; - } - - dcce->type = GenericEvent; - dcce->extension = IReqCode; - dcce->evtype = XI_DeviceChanged; - dcce->time = dce->time; - dcce->deviceid = dce->deviceid; - dcce->sourceid = dce->sourceid; - dcce->reason = (dce->flags & DEVCHANGE_DEVICE_CHANGE) ? XIDeviceChange : XISlaveSwitch; - dcce->num_classes = 0; - dcce->length = bytes_to_int32(len - sizeof(xEvent)); - - ptr = (char*)&dcce[1]; - if (dce->buttons.num_buttons) - { - dcce->num_classes++; - ptr += appendButtonInfo(dce, (xXIButtonInfo*)ptr); - } - - if (nkeys) - { - dcce->num_classes++; - ptr += appendKeyInfo(dce, (xXIKeyInfo*)ptr); - } - - if (dce->num_valuators) - { - int i; - - dcce->num_classes += dce->num_valuators; - for (i = 0; i < dce->num_valuators; i++) - ptr += appendValuatorInfo(dce, (xXIValuatorInfo*)ptr, i); - } - - *xi = (xEvent*)dcce; - - return Success; -} - -static int count_bits(unsigned char* ptr, int len) -{ - int bits = 0; - unsigned int i; - unsigned char x; - - for (i = 0; i < len; i++) - { - x = ptr[i]; - while(x > 0) - { - bits += (x & 0x1); - x >>= 1; - } - } - return bits; -} - -static int -eventToDeviceEvent(DeviceEvent *ev, xEvent **xi) -{ - int len = sizeof(xXIDeviceEvent); - xXIDeviceEvent *xde; - int i, btlen, vallen; - char *ptr; - FP3232 *axisval; - - /* FIXME: this should just send the buttons we have, not MAX_BUTTONs. Same - * with MAX_VALUATORS below */ - /* btlen is in 4 byte units */ - btlen = bytes_to_int32(bits_to_bytes(MAX_BUTTONS)); - len += btlen * 4; /* buttonmask len */ - - - vallen = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask)/sizeof(ev->valuators.mask[0])); - len += vallen * 2 * sizeof(uint32_t); /* axisvalues */ - vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS)); - len += vallen * 4; /* valuators mask */ - - *xi = calloc(1, len); - xde = (xXIDeviceEvent*)*xi; - xde->type = GenericEvent; - xde->extension = IReqCode; - xde->evtype = GetXI2Type((InternalEvent*)ev); - xde->time = ev->time; - xde->length = bytes_to_int32(len - sizeof(xEvent)); - xde->detail = ev->detail.button; - xde->root = ev->root; - xde->buttons_len = btlen; - xde->valuators_len = vallen; - xde->deviceid = ev->deviceid; - xde->sourceid = ev->sourceid; - xde->root_x = FP1616(ev->root_x, ev->root_x_frac); - xde->root_y = FP1616(ev->root_y, ev->root_y_frac); - - if (ev->key_repeat) - xde->flags |= XIKeyRepeat; - - xde->mods.base_mods = ev->mods.base; - xde->mods.latched_mods = ev->mods.latched; - xde->mods.locked_mods = ev->mods.locked; - xde->mods.effective_mods = ev->mods.effective; - - xde->group.base_group = ev->group.base; - xde->group.latched_group = ev->group.latched; - xde->group.locked_group = ev->group.locked; - xde->group.effective_group = ev->group.effective; - - ptr = (char*)&xde[1]; - for (i = 0; i < sizeof(ev->buttons) * 8; i++) - { - if (BitIsOn(ev->buttons, i)) - SetBit(ptr, i); - } - - ptr += xde->buttons_len * 4; - axisval = (FP3232*)(ptr + xde->valuators_len * 4); - for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) - { - if (BitIsOn(ev->valuators.mask, i)) - { - SetBit(ptr, i); - axisval->integral = ev->valuators.data[i]; - axisval->frac = ev->valuators.data_frac[i]; - axisval++; - } - } - - return Success; -} - -static int -eventToRawEvent(RawDeviceEvent *ev, xEvent **xi) -{ - xXIRawEvent* raw; - int vallen, nvals; - int i, len = sizeof(xXIRawEvent); - char *ptr; - FP3232 *axisval; - - nvals = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask)); - len += nvals * sizeof(FP3232) * 2; /* 8 byte per valuator, once - raw, once processed */ - vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS)); - len += vallen * 4; /* valuators mask */ - - *xi = calloc(1, len); - raw = (xXIRawEvent*)*xi; - raw->type = GenericEvent; - raw->extension = IReqCode; - raw->evtype = GetXI2Type((InternalEvent*)ev); - raw->time = ev->time; - raw->length = bytes_to_int32(len - sizeof(xEvent)); - raw->detail = ev->detail.button; - raw->deviceid = ev->deviceid; - raw->valuators_len = vallen; - - ptr = (char*)&raw[1]; - axisval = (FP3232*)(ptr + raw->valuators_len * 4); - for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) - { - if (BitIsOn(ev->valuators.mask, i)) - { - SetBit(ptr, i); - axisval->integral = ev->valuators.data[i]; - axisval->frac = ev->valuators.data_frac[i]; - (axisval + nvals)->integral = ev->valuators.data_raw[i]; - (axisval + nvals)->frac = ev->valuators.data_raw_frac[i]; - axisval++; - } - } - - return Success; -} - -/** - * Return the corresponding core type for the given event or 0 if no core - * equivalent exists. - */ -int -GetCoreType(InternalEvent *event) -{ - int coretype = 0; - switch(event->any.type) - { - case ET_Motion: coretype = MotionNotify; break; - case ET_ButtonPress: coretype = ButtonPress; break; - case ET_ButtonRelease: coretype = ButtonRelease; break; - case ET_KeyPress: coretype = KeyPress; break; - case ET_KeyRelease: coretype = KeyRelease; break; - default: - break; - } - return coretype; -} - -/** - * Return the corresponding XI 1.x type for the given event or 0 if no - * equivalent exists. - */ -int -GetXIType(InternalEvent *event) -{ - int xitype = 0; - switch(event->any.type) - { - case ET_Motion: xitype = DeviceMotionNotify; break; - case ET_ButtonPress: xitype = DeviceButtonPress; break; - case ET_ButtonRelease: xitype = DeviceButtonRelease; break; - case ET_KeyPress: xitype = DeviceKeyPress; break; - case ET_KeyRelease: xitype = DeviceKeyRelease; break; - case ET_ProximityIn: xitype = ProximityIn; break; - case ET_ProximityOut: xitype = ProximityOut; break; - default: - break; - } - return xitype; -} - -/** - * Return the corresponding XI 2.x type for the given event or 0 if no - * equivalent exists. - */ -int -GetXI2Type(InternalEvent *event) -{ - int xi2type = 0; - - switch(event->any.type) - { - case ET_Motion: xi2type = XI_Motion; break; - case ET_ButtonPress: xi2type = XI_ButtonPress; break; - case ET_ButtonRelease: xi2type = XI_ButtonRelease; break; - case ET_KeyPress: xi2type = XI_KeyPress; break; - case ET_KeyRelease: xi2type = XI_KeyRelease; break; - case ET_Enter: xi2type = XI_Enter; break; - case ET_Leave: xi2type = XI_Leave; break; - case ET_Hierarchy: xi2type = XI_HierarchyChanged; break; - case ET_DeviceChanged: xi2type = XI_DeviceChanged; break; - case ET_RawKeyPress: xi2type = XI_RawKeyPress; break; - case ET_RawKeyRelease: xi2type = XI_RawKeyRelease; break; - case ET_RawButtonPress: xi2type = XI_RawButtonPress; break; - case ET_RawButtonRelease: xi2type = XI_RawButtonRelease; break; - case ET_RawMotion: xi2type = XI_RawMotion; break; - case ET_FocusIn: xi2type = XI_FocusIn; break; - case ET_FocusOut: xi2type = XI_FocusOut; break; - default: - break; - } - return xi2type; -} +/*
+ * 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.
+ *
+ */
+
+/**
+ * @file eventconvert.c
+ * This file contains event conversion routines from InternalEvent to the
+ * matching protocol events.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdint.h>
+#include <X11/X.h>
+#include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI2proto.h>
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XI2.h>
+
+#include "dix.h"
+#include "inputstr.h"
+#include "misc.h"
+#include "eventstr.h"
+#include "exglobals.h"
+#include "eventconvert.h"
+#include "xiquerydevice.h"
+#include "xkbsrv.h"
+
+
+static int countValuators(DeviceEvent *ev, int *first);
+static int getValuatorEvents(DeviceEvent *ev, deviceValuator *xv);
+static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count);
+static int eventToDeviceChanged(DeviceChangedEvent *ev, xEvent **dcce);
+static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi);
+static int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi);
+
+/* Do not use, read comments below */
+BOOL EventIsKeyRepeat(xEvent *event);
+
+/**
+ * Hack to allow detectable autorepeat for core and XI1 events.
+ * The sequence number is unused until we send to the client and can be
+ * misused to store data. More or less, anyway.
+ *
+ * Do not use this. It may change any time without warning, eat your babies
+ * and piss on your cat.
+ */
+static void
+EventSetKeyRepeatFlag(xEvent *event, BOOL on)
+{
+ event->u.u.sequenceNumber = on;
+}
+
+/**
+ * Check if the event was marked as a repeat event before.
+ * NOTE: This is a nasty hack and should NOT be used by anyone else but
+ * TryClientEvents.
+ */
+BOOL
+EventIsKeyRepeat(xEvent *event)
+{
+ return !!event->u.u.sequenceNumber;
+}
+
+/**
+ * Convert the given event to the respective core event.
+ *
+ * Return values:
+ * Success ... core contains the matching core event.
+ * BadValue .. One or more values in the internal event are invalid.
+ * BadMatch .. The event has no core equivalent.
+ *
+ * @param[in] event The event to convert into a core event.
+ * @param[in] core The memory location to store the core event at.
+ * @return Success or the matching error code.
+ */
+int
+EventToCore(InternalEvent *event, xEvent *core)
+{
+ switch(event->any.type)
+ {
+ case ET_Motion:
+ {
+ DeviceEvent *e = &event->device_event;
+ /* Don't create core motion event if neither x nor y are
+ * present */
+ if (!BitIsOn(e->valuators.mask, 0) &&
+ !BitIsOn(e->valuators.mask, 1))
+ return BadMatch;
+ }
+ /* fallthrough */
+ case ET_ButtonPress:
+ case ET_ButtonRelease:
+ case ET_KeyPress:
+ case ET_KeyRelease:
+ {
+ DeviceEvent *e = &event->device_event;
+
+ if (e->detail.key > 0xFF)
+ return BadMatch;
+
+ memset(core, 0, sizeof(xEvent));
+ core->u.u.type = e->type - ET_KeyPress + KeyPress;
+ core->u.u.detail = e->detail.key & 0xFF;
+ core->u.keyButtonPointer.time = e->time;
+ core->u.keyButtonPointer.rootX = e->root_x;
+ core->u.keyButtonPointer.rootY = e->root_y;
+ core->u.keyButtonPointer.state = e->corestate;
+ core->u.keyButtonPointer.root = e->root;
+ EventSetKeyRepeatFlag(core, (e->type == ET_KeyPress && e->key_repeat));
+ }
+ break;
+ case ET_ProximityIn:
+ case ET_ProximityOut:
+ case ET_RawKeyPress:
+ case ET_RawKeyRelease:
+ case ET_RawButtonPress:
+ case ET_RawButtonRelease:
+ case ET_RawMotion:
+ return BadMatch;
+ default:
+ /* XXX: */
+ ErrorF("[dix] EventToCore: Not implemented yet \n");
+ return BadImplementation;
+ }
+ return Success;
+}
+
+/**
+ * Convert the given event to the respective XI 1.x event and store it in
+ * xi. xi is allocated on demand and must be freed by the caller.
+ * count returns the number of events in xi. If count is 1, and the type of
+ * xi is GenericEvent, then xi may be larger than 32 bytes.
+ *
+ * Return values:
+ * Success ... core contains the matching core event.
+ * BadValue .. One or more values in the internal event are invalid.
+ * BadMatch .. The event has no XI equivalent.
+ *
+ * @param[in] ev The event to convert into an XI 1 event.
+ * @param[out] xi Future memory location for the XI event.
+ * @param[out] count Number of elements in xi.
+ *
+ * @return Success or the error code.
+ */
+int
+EventToXI(InternalEvent *ev, xEvent **xi, int *count)
+{
+ switch (ev->any.type)
+ {
+ case ET_Motion:
+ case ET_ButtonPress:
+ case ET_ButtonRelease:
+ case ET_KeyPress:
+ case ET_KeyRelease:
+ case ET_ProximityIn:
+ case ET_ProximityOut:
+ return eventToKeyButtonPointer(&ev->device_event, xi, count);
+ case ET_DeviceChanged:
+ case ET_RawKeyPress:
+ case ET_RawKeyRelease:
+ case ET_RawButtonPress:
+ case ET_RawButtonRelease:
+ case ET_RawMotion:
+ *count = 0;
+ *xi = NULL;
+ return BadMatch;
+ default:
+ break;
+ }
+
+ ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->any.type);
+ return BadImplementation;
+}
+
+/**
+ * Convert the given event to the respective XI 2.x event and store it in xi.
+ * xi is allocated on demand and must be freed by the caller.
+ *
+ * Return values:
+ * Success ... core contains the matching core event.
+ * BadValue .. One or more values in the internal event are invalid.
+ * BadMatch .. The event has no XI2 equivalent.
+ *
+ * @param[in] ev The event to convert into an XI2 event
+ * @param[out] xi Future memory location for the XI2 event.
+ *
+ * @return Success or the error code.
+ */
+int
+EventToXI2(InternalEvent *ev, xEvent **xi)
+{
+ switch (ev->any.type)
+ {
+ /* Enter/FocusIn are for grabs. We don't need an actual event, since
+ * the real events delivered are triggered elsewhere */
+ case ET_Enter:
+ case ET_FocusIn:
+ *xi = NULL;
+ return Success;
+ case ET_Motion:
+ case ET_ButtonPress:
+ case ET_ButtonRelease:
+ case ET_KeyPress:
+ case ET_KeyRelease:
+ return eventToDeviceEvent(&ev->device_event, xi);
+ case ET_ProximityIn:
+ case ET_ProximityOut:
+ *xi = NULL;
+ return BadMatch;
+ case ET_DeviceChanged:
+ return eventToDeviceChanged(&ev->changed_event, xi);
+ case ET_RawKeyPress:
+ case ET_RawKeyRelease:
+ case ET_RawButtonPress:
+ case ET_RawButtonRelease:
+ case ET_RawMotion:
+ return eventToRawEvent(&ev->raw_event, xi);
+ default:
+ break;
+ }
+
+ ErrorF("[dix] EventToXI2: Not implemented for %d \n", ev->any.type);
+ return BadImplementation;
+}
+
+static int
+eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count)
+{
+ int num_events;
+ int first; /* dummy */
+ deviceKeyButtonPointer *kbp;
+
+ /* Sorry, XI 1.x protocol restrictions. */
+ if (ev->detail.button > 0xFF || ev->deviceid >= 0x80)
+ {
+ *count = 0;
+ return Success;
+ }
+
+ num_events = (countValuators(ev, &first) + 5)/6; /* valuator ev */
+ if (num_events <= 0)
+ {
+ switch (ev->type)
+ {
+ case ET_KeyPress:
+ case ET_KeyRelease:
+ case ET_ButtonPress:
+ case ET_ButtonRelease:
+ /* no axes is ok */
+ break;
+ case ET_Motion:
+ case ET_ProximityIn:
+ case ET_ProximityOut:
+ *count = 0;
+ return BadMatch;
+ }
+ }
+
+ num_events++; /* the actual event event */
+
+ *xi = calloc(num_events, sizeof(xEvent));
+ if (!(*xi))
+ {
+ return BadAlloc;
+ }
+
+ kbp = (deviceKeyButtonPointer*)(*xi);
+ kbp->detail = ev->detail.button;
+ kbp->time = ev->time;
+ kbp->root = ev->root;
+ kbp->root_x = ev->root_x;
+ kbp->root_y = ev->root_y;
+ kbp->deviceid = ev->deviceid;
+ kbp->state = ev->corestate;
+ EventSetKeyRepeatFlag((xEvent*)kbp,
+ (ev->type == ET_KeyPress && ev->key_repeat));
+
+ if (num_events > 1)
+ kbp->deviceid |= MORE_EVENTS;
+
+ switch(ev->type)
+ {
+ case ET_Motion: kbp->type = DeviceMotionNotify; break;
+ case ET_ButtonPress: kbp->type = DeviceButtonPress; break;
+ case ET_ButtonRelease: kbp->type = DeviceButtonRelease; break;
+ case ET_KeyPress: kbp->type = DeviceKeyPress; break;
+ case ET_KeyRelease: kbp->type = DeviceKeyRelease; break;
+ case ET_ProximityIn: kbp->type = ProximityIn; break;
+ case ET_ProximityOut: kbp->type = ProximityOut; break;
+ default:
+ break;
+ }
+
+ if (num_events > 1)
+ {
+ getValuatorEvents(ev, (deviceValuator*)(kbp + 1));
+ }
+
+ *count = num_events;
+ return Success;
+}
+
+
+/**
+ * Set first to the first valuator in the event ev and return the number of
+ * valuators from first to the last set valuator.
+ */
+static int
+countValuators(DeviceEvent *ev, int *first)
+{
+ int first_valuator = -1, last_valuator = -1, num_valuators = 0;
+ int i;
+
+ for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
+ {
+ if (BitIsOn(ev->valuators.mask, i))
+ {
+ if (first_valuator == -1)
+ first_valuator = i;
+ last_valuator = i;
+ }
+ }
+
+ if (first_valuator != -1)
+ {
+ num_valuators = last_valuator - first_valuator + 1;
+ *first = first_valuator;
+ }
+
+ return num_valuators;
+}
+
+static int
+getValuatorEvents(DeviceEvent *ev, deviceValuator *xv)
+{
+ int i;
+ int state = 0;
+ int first_valuator, num_valuators;
+
+
+ num_valuators = countValuators(ev, &first_valuator);
+ if (num_valuators > 0)
+ {
+ DeviceIntPtr dev = NULL;
+ dixLookupDevice(&dev, ev->deviceid, serverClient, DixUseAccess);
+ /* State needs to be assembled BEFORE the device is updated. */
+ state = (dev && dev->key) ? XkbStateFieldFromRec(&dev->key->xkbInfo->state) : 0;
+ state |= (dev && dev->button) ? (dev->button->state) : 0;
+ }
+
+ /* FIXME: non-continuous valuator data in internal events*/
+ for (i = 0; i < num_valuators; i += 6, xv++) {
+ xv->type = DeviceValuator;
+ xv->first_valuator = first_valuator + i;
+ xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i);
+ xv->deviceid = ev->deviceid;
+ xv->device_state = state;
+ switch (xv->num_valuators) {
+ case 6:
+ xv->valuator5 = ev->valuators.data[xv->first_valuator + 5];
+ case 5:
+ xv->valuator4 = ev->valuators.data[xv->first_valuator + 4];
+ case 4:
+ xv->valuator3 = ev->valuators.data[xv->first_valuator + 3];
+ case 3:
+ xv->valuator2 = ev->valuators.data[xv->first_valuator + 2];
+ case 2:
+ xv->valuator1 = ev->valuators.data[xv->first_valuator + 1];
+ case 1:
+ xv->valuator0 = ev->valuators.data[xv->first_valuator + 0];
+ }
+
+ if (i + 6 < num_valuators)
+ xv->deviceid |= MORE_EVENTS;
+ }
+
+ return (num_valuators + 5) / 6;
+}
+
+
+static int
+appendKeyInfo(DeviceChangedEvent *dce, xXIKeyInfo* info)
+{
+ uint32_t *kc;
+ int i;
+
+ info->type = XIKeyClass;
+ info->num_keycodes = dce->keys.max_keycode - dce->keys.min_keycode + 1;
+ info->length = sizeof(xXIKeyInfo)/4 + info->num_keycodes;
+ info->sourceid = dce->sourceid;
+
+ kc = (uint32_t*)&info[1];
+ for (i = 0; i < info->num_keycodes; i++)
+ *kc++ = i + dce->keys.min_keycode;
+
+ return info->length * 4;
+}
+
+static int
+appendButtonInfo(DeviceChangedEvent *dce, xXIButtonInfo *info)
+{
+ unsigned char *bits;
+ int mask_len;
+
+ mask_len = bytes_to_int32(bits_to_bytes(dce->buttons.num_buttons));
+
+ info->type = XIButtonClass;
+ info->num_buttons = dce->buttons.num_buttons;
+ info->length = bytes_to_int32(sizeof(xXIButtonInfo)) +
+ info->num_buttons + mask_len;
+ info->sourceid = dce->sourceid;
+
+ bits = (unsigned char*)&info[1];
+ memset(bits, 0, mask_len * 4);
+ /* FIXME: is_down? */
+
+ bits += mask_len * 4;
+ memcpy(bits, dce->buttons.names, dce->buttons.num_buttons * sizeof(Atom));
+
+ return info->length * 4;
+}
+
+static int
+appendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo *info, int axisnumber)
+{
+ info->type = XIValuatorClass;
+ info->length = sizeof(xXIValuatorInfo)/4;
+ info->label = dce->valuators[axisnumber].name;
+ info->min.integral = dce->valuators[axisnumber].min;
+ info->min.frac = 0;
+ info->max.integral = dce->valuators[axisnumber].max;
+ info->max.frac = 0;
+ /* FIXME: value */
+ info->value.integral = 0;
+ info->value.frac = 0;
+ info->resolution = dce->valuators[axisnumber].resolution;
+ info->number = axisnumber;
+ info->mode = dce->valuators[axisnumber].mode;
+ info->sourceid = dce->sourceid;
+
+ return info->length * 4;
+}
+
+static int
+eventToDeviceChanged(DeviceChangedEvent *dce, xEvent **xi)
+{
+ xXIDeviceChangedEvent *dcce;
+ int len = sizeof(xXIDeviceChangedEvent);
+ int nkeys;
+ char *ptr;
+
+ if (dce->buttons.num_buttons)
+ {
+ len += sizeof(xXIButtonInfo);
+ len += dce->buttons.num_buttons * sizeof(Atom); /* button names */
+ len += pad_to_int32(bits_to_bytes(dce->buttons.num_buttons));
+ }
+ if (dce->num_valuators)
+ len += sizeof(xXIValuatorInfo) * dce->num_valuators;
+
+ nkeys = (dce->keys.max_keycode > 0) ?
+ dce->keys.max_keycode - dce->keys.min_keycode + 1 : 0;
+ if (nkeys > 0)
+ {
+ len += sizeof(xXIKeyInfo);
+ len += sizeof(CARD32) * nkeys; /* keycodes */
+ }
+
+ dcce = calloc(1, len);
+ if (!dcce)
+ {
+ ErrorF("[Xi] BadAlloc in SendDeviceChangedEvent.\n");
+ return BadAlloc;
+ }
+
+ dcce->type = GenericEvent;
+ dcce->extension = IReqCode;
+ dcce->evtype = XI_DeviceChanged;
+ dcce->time = dce->time;
+ dcce->deviceid = dce->deviceid;
+ dcce->sourceid = dce->sourceid;
+ dcce->reason = (dce->flags & DEVCHANGE_DEVICE_CHANGE) ? XIDeviceChange : XISlaveSwitch;
+ dcce->num_classes = 0;
+ dcce->length = bytes_to_int32(len - sizeof(xEvent));
+
+ ptr = (char*)&dcce[1];
+ if (dce->buttons.num_buttons)
+ {
+ dcce->num_classes++;
+ ptr += appendButtonInfo(dce, (xXIButtonInfo*)ptr);
+ }
+
+ if (nkeys)
+ {
+ dcce->num_classes++;
+ ptr += appendKeyInfo(dce, (xXIKeyInfo*)ptr);
+ }
+
+ if (dce->num_valuators)
+ {
+ int i;
+
+ dcce->num_classes += dce->num_valuators;
+ for (i = 0; i < dce->num_valuators; i++)
+ ptr += appendValuatorInfo(dce, (xXIValuatorInfo*)ptr, i);
+ }
+
+ *xi = (xEvent*)dcce;
+
+ return Success;
+}
+
+static int count_bits(unsigned char* ptr, int len)
+{
+ int bits = 0;
+ unsigned int i;
+ unsigned char x;
+
+ for (i = 0; i < len; i++)
+ {
+ x = ptr[i];
+ while(x > 0)
+ {
+ bits += (x & 0x1);
+ x >>= 1;
+ }
+ }
+ return bits;
+}
+
+static int
+eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
+{
+ int len = sizeof(xXIDeviceEvent);
+ xXIDeviceEvent *xde;
+ int i, btlen, vallen;
+ char *ptr;
+ FP3232 *axisval;
+
+ /* FIXME: this should just send the buttons we have, not MAX_BUTTONs. Same
+ * with MAX_VALUATORS below */
+ /* btlen is in 4 byte units */
+ btlen = bytes_to_int32(bits_to_bytes(MAX_BUTTONS));
+ len += btlen * 4; /* buttonmask len */
+
+
+ vallen = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask)/sizeof(ev->valuators.mask[0]));
+ len += vallen * 2 * sizeof(uint32_t); /* axisvalues */
+ vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS));
+ len += vallen * 4; /* valuators mask */
+
+ *xi = calloc(1, len);
+ xde = (xXIDeviceEvent*)*xi;
+ xde->type = GenericEvent;
+ xde->extension = IReqCode;
+ xde->evtype = GetXI2Type((InternalEvent*)ev);
+ xde->time = ev->time;
+ xde->length = bytes_to_int32(len - sizeof(xEvent));
+ xde->detail = ev->detail.button;
+ xde->root = ev->root;
+ xde->buttons_len = btlen;
+ xde->valuators_len = vallen;
+ xde->deviceid = ev->deviceid;
+ xde->sourceid = ev->sourceid;
+ xde->root_x = FP1616(ev->root_x, ev->root_x_frac);
+ xde->root_y = FP1616(ev->root_y, ev->root_y_frac);
+
+ if (ev->key_repeat)
+ xde->flags |= XIKeyRepeat;
+
+ xde->mods.base_mods = ev->mods.base;
+ xde->mods.latched_mods = ev->mods.latched;
+ xde->mods.locked_mods = ev->mods.locked;
+ xde->mods.effective_mods = ev->mods.effective;
+
+ xde->group.base_group = ev->group.base;
+ xde->group.latched_group = ev->group.latched;
+ xde->group.locked_group = ev->group.locked;
+ xde->group.effective_group = ev->group.effective;
+
+ ptr = (char*)&xde[1];
+ for (i = 0; i < sizeof(ev->buttons) * 8; i++)
+ {
+ if (BitIsOn(ev->buttons, i))
+ SetBit(ptr, i);
+ }
+
+ ptr += xde->buttons_len * 4;
+ axisval = (FP3232*)(ptr + xde->valuators_len * 4);
+ for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
+ {
+ if (BitIsOn(ev->valuators.mask, i))
+ {
+ SetBit(ptr, i);
+ axisval->integral = ev->valuators.data[i];
+ axisval->frac = ev->valuators.data_frac[i];
+ axisval++;
+ }
+ }
+
+ return Success;
+}
+
+static int
+eventToRawEvent(RawDeviceEvent *ev, xEvent **xi)
+{
+ xXIRawEvent* raw;
+ int vallen, nvals;
+ int i, len = sizeof(xXIRawEvent);
+ char *ptr;
+ FP3232 *axisval;
+
+ nvals = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask));
+ len += nvals * sizeof(FP3232) * 2; /* 8 byte per valuator, once
+ raw, once processed */
+ vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS));
+ len += vallen * 4; /* valuators mask */
+
+ *xi = calloc(1, len);
+ raw = (xXIRawEvent*)*xi;
+ raw->type = GenericEvent;
+ raw->extension = IReqCode;
+ raw->evtype = GetXI2Type((InternalEvent*)ev);
+ raw->time = ev->time;
+ raw->length = bytes_to_int32(len - sizeof(xEvent));
+ raw->detail = ev->detail.button;
+ raw->deviceid = ev->deviceid;
+ raw->valuators_len = vallen;
+
+ ptr = (char*)&raw[1];
+ axisval = (FP3232*)(ptr + raw->valuators_len * 4);
+ for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
+ {
+ if (BitIsOn(ev->valuators.mask, i))
+ {
+ SetBit(ptr, i);
+ axisval->integral = ev->valuators.data[i];
+ axisval->frac = ev->valuators.data_frac[i];
+ (axisval + nvals)->integral = ev->valuators.data_raw[i];
+ (axisval + nvals)->frac = ev->valuators.data_raw_frac[i];
+ axisval++;
+ }
+ }
+
+ return Success;
+}
+
+/**
+ * Return the corresponding core type for the given event or 0 if no core
+ * equivalent exists.
+ */
+int
+GetCoreType(InternalEvent *event)
+{
+ int coretype = 0;
+ switch(event->any.type)
+ {
+ case ET_Motion: coretype = MotionNotify; break;
+ case ET_ButtonPress: coretype = ButtonPress; break;
+ case ET_ButtonRelease: coretype = ButtonRelease; break;
+ case ET_KeyPress: coretype = KeyPress; break;
+ case ET_KeyRelease: coretype = KeyRelease; break;
+ default:
+ break;
+ }
+ return coretype;
+}
+
+/**
+ * Return the corresponding XI 1.x type for the given event or 0 if no
+ * equivalent exists.
+ */
+int
+GetXIType(InternalEvent *event)
+{
+ int xitype = 0;
+ switch(event->any.type)
+ {
+ case ET_Motion: xitype = DeviceMotionNotify; break;
+ case ET_ButtonPress: xitype = DeviceButtonPress; break;
+ case ET_ButtonRelease: xitype = DeviceButtonRelease; break;
+ case ET_KeyPress: xitype = DeviceKeyPress; break;
+ case ET_KeyRelease: xitype = DeviceKeyRelease; break;
+ case ET_ProximityIn: xitype = ProximityIn; break;
+ case ET_ProximityOut: xitype = ProximityOut; break;
+ default:
+ break;
+ }
+ return xitype;
+}
+
+/**
+ * Return the corresponding XI 2.x type for the given event or 0 if no
+ * equivalent exists.
+ */
+int
+GetXI2Type(InternalEvent *event)
+{
+ int xi2type = 0;
+
+ switch(event->any.type)
+ {
+ case ET_Motion: xi2type = XI_Motion; break;
+ case ET_ButtonPress: xi2type = XI_ButtonPress; break;
+ case ET_ButtonRelease: xi2type = XI_ButtonRelease; break;
+ case ET_KeyPress: xi2type = XI_KeyPress; break;
+ case ET_KeyRelease: xi2type = XI_KeyRelease; break;
+ case ET_Enter: xi2type = XI_Enter; break;
+ case ET_Leave: xi2type = XI_Leave; break;
+ case ET_Hierarchy: xi2type = XI_HierarchyChanged; break;
+ case ET_DeviceChanged: xi2type = XI_DeviceChanged; break;
+ case ET_RawKeyPress: xi2type = XI_RawKeyPress; break;
+ case ET_RawKeyRelease: xi2type = XI_RawKeyRelease; break;
+ case ET_RawButtonPress: xi2type = XI_RawButtonPress; break;
+ case ET_RawButtonRelease: xi2type = XI_RawButtonRelease; break;
+ case ET_RawMotion: xi2type = XI_RawMotion; break;
+ case ET_FocusIn: xi2type = XI_FocusIn; break;
+ case ET_FocusOut: xi2type = XI_FocusOut; break;
+ default:
+ break;
+ }
+ return xi2type;
+}
diff --git a/xorg-server/dix/events.c b/xorg-server/dix/events.c index 07f8b05ea..47f35ac93 100644 --- a/xorg-server/dix/events.c +++ b/xorg-server/dix/events.c @@ -741,7 +741,10 @@ CheckPhysLimits( { #ifdef PANORAMIX if (!noPanoramiXExtension) - XineramaSetCursorPosition (pDev, new.x, new.y, generateEvents); + { + if (pScreen && ((new.x != pSprite->hotPhys.x) || (new.y != pSprite->hotPhys.y))) + XineramaSetCursorPosition (pDev, new.x, new.y, generateEvents); + } else #endif { @@ -2691,6 +2694,9 @@ CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev) CHECKEVENT(ev); + if (!pSprite) + return FALSE; + prevSpriteWin = pSprite->win; if (ev && !syncEvents.playingEvents) diff --git a/xorg-server/dix/gc.c b/xorg-server/dix/gc.c index e7bcc66f1..92d24dde4 100644 --- a/xorg-server/dix/gc.c +++ b/xorg-server/dix/gc.c @@ -321,10 +321,30 @@ ChangeGC(ClientPtr client, GC *pGC, BITS32 mask, ChangeGCValPtr pUnion) break;
}
case GCClipXOrigin:
+ #ifndef _DEBUG
NEXTVAL(INT16, pGC->clipOrg.x);
+ #else
+ {
+ long Val;
+ NEXTVAL(long, Val);
+ if (abs(Val)>65535)
+ ErrorF("Value received for GCClipXOrigin is too large %x\n",Val);
+ pGC->clipOrg.x=(INT16)(Val&0xffff);
+ }
+ #endif
break;
case GCClipYOrigin:
+ #ifndef _DEBUG
NEXTVAL(INT16, pGC->clipOrg.y);
+ #else
+ {
+ long Val;
+ NEXTVAL(long, Val);
+ if (abs(Val)>65535)
+ ErrorF("Value received for GCClipYOrigin is too large %x\n",Val);
+ pGC->clipOrg.y=(INT16)(Val&0xffff);
+ }
+ #endif
break;
case GCClipMask:
NEXT_PTR(PixmapPtr, pPixmap);
diff --git a/xorg-server/dix/getevents.c b/xorg-server/dix/getevents.c index 794df420b..f58c41df2 100644 --- a/xorg-server/dix/getevents.c +++ b/xorg-server/dix/getevents.c @@ -65,6 +65,21 @@ #include "extnsionst.h" #include "listdev.h" /* for sizing up DeviceClassesChangedEvent */ +#ifdef _MSC_VER +#include <math.h> + +float roundf(float f) +{ + return ((f<0.0f) ? ceil(f-.5) : floor (f+.5)); +} +double roundd(double f) +{ + return ((f<0.0) ? ceil(f-.5) : floor (f+.5)); +} +#define lroundf(val) ((int)roundf(val)) +#define lround(val) ((int)roundd(val)) +#endif + /* Number of motion history events to store. */ #define MOTION_HISTORY_SIZE 256 @@ -949,7 +964,7 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type, ValuatorMask mask; /* refuse events from disabled devices */ - if (!pDev->enabled) + if (!pDev || !pDev->enabled) return 0; if (!events ||!pDev->key || !pDev->focus || !pDev->kbdfeed || diff --git a/xorg-server/dix/inpututils.c b/xorg-server/dix/inpututils.c index ef3142c84..4c6112b7f 100644 --- a/xorg-server/dix/inpututils.c +++ b/xorg-server/dix/inpututils.c @@ -238,10 +238,10 @@ static int build_modmap_from_modkeymap(CARD8 *modmap, KeyCode *modkeymap, if (modkeymap[i] >= MAP_LENGTH) return BadValue; - if (modmap[modkeymap[i]]) - return BadValue; + //if (modmap[modkeymap[i]]) It looks like it needlessly gives errors back + // return BadValue; - modmap[modkeymap[i]] = 1 << (i / max_keys_per_mod); + modmap[modkeymap[i]] |= 1 << (i / max_keys_per_mod); // Now or it because of previous line removal } return Success; diff --git a/xorg-server/dix/main.c b/xorg-server/dix/main.c index 15d39d7be..169147112 100644 --- a/xorg-server/dix/main.c +++ b/xorg-server/dix/main.c @@ -115,6 +115,10 @@ Equipment Corporation. #include "dpmsproc.h"
#endif
+#ifdef _DEBUG
+#include <crtdbg.h>
+#endif
+
extern void Dispatch(void);
#ifdef XQUARTZ
@@ -133,9 +137,49 @@ int main(int argc, char *argv[], char *envp[]) {
int i;
HWEventQueueType alwaysCheckForInput[2];
-
+ #ifdef _DEBUG
+ //int TmpFlag=_CrtSetDbgFlag( _CRTDBG_REPORT_FLAG);
+
+ //TmpFlag|=_CRTDBG_ALLOC_MEM_DF;
+ //TmpFlag|=_CRTDBG_DELAY_FREE_MEM_DF;
+ //TmpFlag|=_CRTDBG_CHECK_ALWAYS_DF;
+ //TmpFlag|=_CRTDBG_CHECK_CRT_DF;
+ //TmpFlag|=_CRTDBG_LEAK_CHECK_DF;
+
+ //_CrtSetDbgFlag(TmpFlag);
+ #endif
+
+ ptw32_processInitialize();
display = "0";
+ #ifdef WIN32
+
+ if (InitWSA()<0)
+ {
+ printf("Error initialising WSA\n");
+ return -1;
+ }
+ /* In Win32 we have different threads call Xlib functions (depending
+ on the commandline options given).
+ XInitThreads has to be called before
+ any xlib function is called (aoccording to the man page) */
+ XInitThreads();
+ /* change the current directory to the directory where the vcxsrv.exe executable is installed.
+ This is needed because the font directories are relative to the current directory.
+ */
+ {
+ char ModuleFilename[MAX_PATH];
+ char *pSlash;
+ GetModuleFileName(NULL,ModuleFilename,sizeof(ModuleFilename));
+ pSlash=strrchr(ModuleFilename,'\\');
+ if (pSlash)
+ {
+ *pSlash='\0';
+ chdir(ModuleFilename);
+ }
+ }
+ #endif
+
InitRegions();
pixman_disable_out_of_bounds_workaround();
diff --git a/xorg-server/dix/makefile b/xorg-server/dix/makefile new file mode 100644 index 000000000..eeb18919c --- /dev/null +++ b/xorg-server/dix/makefile @@ -0,0 +1,41 @@ +ifeq ($(DEBUG),1)
+DEFINES += FONTDEBUG XSERVER_DTRACE
+endif
+
+LIBRARY=libdix
+
+CSRCS=\
+ atom.c \
+ colormap.c \
+ cursor.c \
+ deprecated.c \
+ devices.c \
+ dispatch.c \
+ dixfonts.c \
+ dixutils.c \
+ enterleave.c \
+ events.c \
+ eventconvert.c \
+ extension.c \
+ ffs.c \
+ gc.c \
+ getevents.c \
+ globals.c \
+ glyphcurs.c \
+ grabs.c \
+ initatoms.c \
+ inpututils.c \
+ main.c \
+ pixmap.c \
+ privates.c \
+ property.c \
+ ptrveloc.c \
+ region.c \
+ registry.c \
+ resource.c \
+ selection.c \
+ swaprep.c \
+ swapreq.c \
+ tables.c \
+ window.c
+
diff --git a/xorg-server/dix/privates.c b/xorg-server/dix/privates.c index 583b9f1f5..d261f6895 100644 --- a/xorg-server/dix/privates.c +++ b/xorg-server/dix/privates.c @@ -71,19 +71,24 @@ static struct { } keys[PRIVATE_LAST];
static const Bool xselinux_private[PRIVATE_LAST] = {
- [PRIVATE_SCREEN] = TRUE,
- [PRIVATE_CLIENT] = TRUE,
- [PRIVATE_WINDOW] = TRUE,
- [PRIVATE_PIXMAP] = TRUE,
- [PRIVATE_GC] = TRUE,
- [PRIVATE_CURSOR] = TRUE,
- [PRIVATE_COLORMAP] = TRUE,
- [PRIVATE_DEVICE] = TRUE,
- [PRIVATE_EXTENSION] = TRUE,
- [PRIVATE_SELECTION] = TRUE,
- [PRIVATE_PROPERTY] = TRUE,
- [PRIVATE_PICTURE] = TRUE,
- [PRIVATE_GLYPHSET] = TRUE,
+ /* PRIVATE_XSELINUX,*/ FALSE,
+ /* PRIVATE_SCREEN,*/ TRUE,
+ /* [PRIVATE_EXTENSION] =*/TRUE,
+ /* [PRIVATE_COLORMAP] =*/ TRUE,
+ /* [PRIVATE_DEVICE] =*/ TRUE,
+ /* [PRIVATE_CLIENT] = */ TRUE,
+ /* [PRIVATE_PROPERTY] =*/ TRUE,
+ /* [PRIVATE_SELECTION] =*/TRUE,
+ /* [PRIVATE_WINDOW] =*/ TRUE,
+ /* [PRIVATE_PIXMAP] =*/ TRUE,
+ /* [PRIVATE_GC] =*/ TRUE,
+ /* [PRIVATE_CURSOR] =*/ TRUE,
+ /* PRIVATE_CURSOR_BITS,*/ FALSE,
+ /* PRIVATE_DBE_WINDOW,*/ FALSE,
+ /* PRIVATE_DAMAGE,*/ FALSE,
+ /* PRIVATE_GLYPH,*/ FALSE,
+ /* [PRIVATE_GLYPHSET] =*/ TRUE,
+ /* [PRIVATE_PICTURE] =*/ TRUE
};
typedef Bool (*FixupFunc)(PrivatePtr *privates, int offset, unsigned bytes);
@@ -153,10 +158,24 @@ fixupDefaultColormaps(FixupFunc fixup, unsigned bytes) }
static Bool (* const allocated_early[PRIVATE_LAST])(FixupFunc, unsigned) = {
- [PRIVATE_SCREEN] = fixupScreens,
- [PRIVATE_CLIENT] = fixupServerClient,
- [PRIVATE_EXTENSION] = fixupExtensions,
- [PRIVATE_COLORMAP] = fixupDefaultColormaps,
+ /*PRIVATE_XSELINUX,*/ NULL,
+ /*[PRIVATE_SCREEN] =*/ fixupScreens,
+ /*[PRIVATE_EXTENSION] =*/ fixupExtensions,
+ /*[PRIVATE_COLORMAP] =*/ fixupDefaultColormaps,
+ /*PRIVATE_DEVICE,*/ NULL,
+ /*[PRIVATE_CLIENT] =*/ fixupServerClient,
+ /*PRIVATE_PROPERTY,*/ NULL,
+ /*PRIVATE_SELECTION,*/ NULL,
+ /*PRIVATE_WINDOW,*/ NULL,
+ /*PRIVATE_PIXMAP,*/ NULL,
+ /*PRIVATE_GC,*/ NULL,
+ /*PRIVATE_CURSOR,*/ NULL,
+ /*PRIVATE_CURSOR_BITS,*/ NULL,
+ /*PRIVATE_DBE_WINDOW,*/ NULL,
+ /*PRIVATE_DAMAGE,*/ NULL,
+ /*PRIVATE_GLYPH,*/ NULL,
+ /*PRIVATE_GLYPHSET,*/ NULL,
+ /*PRIVATE_PICTURE,*/ NULL
};
/*
@@ -421,33 +440,33 @@ dixLookupPrivateOffset(RESTYPE type) static const char *key_names[PRIVATE_LAST] = {
/* XSELinux uses the same private keys for numerous objects */
- [PRIVATE_XSELINUX] = "XSELINUX",
+ /*[PRIVATE_XSELINUX] =*/ "XSELINUX",
/* Otherwise, you get a private in just the requested structure
*/
/* These can have objects created before all of the keys are registered */
- [PRIVATE_SCREEN] = "SCREEN",
- [PRIVATE_EXTENSION] = "EXTENSION",
- [PRIVATE_COLORMAP] = "COLORMAP",
+ /*[PRIVATE_SCREEN] =*/ "SCREEN",
+ /*[PRIVATE_EXTENSION] =*/ "EXTENSION",
+ /*[PRIVATE_COLORMAP] =*/ "COLORMAP",
/* These cannot have any objects before all relevant keys are registered */
- [PRIVATE_DEVICE] = "DEVICE",
- [PRIVATE_CLIENT] = "CLIENT",
- [PRIVATE_PROPERTY] = "PROPERTY",
- [PRIVATE_SELECTION] = "SELECTION",
- [PRIVATE_WINDOW] = "WINDOW",
- [PRIVATE_PIXMAP] = "PIXMAP",
- [PRIVATE_GC] = "GC",
- [PRIVATE_CURSOR] = "CURSOR",
- [PRIVATE_CURSOR_BITS] = "CURSOR_BITS",
+ /*[PRIVATE_DEVICE] =*/ "DEVICE",
+ /*[PRIVATE_CLIENT] =*/ "CLIENT",
+ /*[PRIVATE_PROPERTY] =*/ "PROPERTY",
+ /*[PRIVATE_SELECTION] =*/ "SELECTION",
+ /*[PRIVATE_WINDOW] =*/ "WINDOW",
+ /*[PRIVATE_PIXMAP] =*/ "PIXMAP",
+ /*[PRIVATE_GC] =*/ "GC",
+ /*[PRIVATE_CURSOR] =*/ "CURSOR",
+ /*[PRIVATE_CURSOR_BITS] =*/ "CURSOR_BITS",
/* extension privates */
- [PRIVATE_DBE_WINDOW] = "DBE_WINDOW",
- [PRIVATE_DAMAGE] = "DAMAGE",
- [PRIVATE_GLYPH] = "GLYPH",
- [PRIVATE_GLYPHSET] = "GLYPHSET",
- [PRIVATE_PICTURE] = "PICTURE",
- [PRIVATE_SYNC_FENCE] = "SYNC_FENCE",
+ /*[PRIVATE_DBE_WINDOW] =*/ "DBE_WINDOW",
+ /*[PRIVATE_DAMAGE] =*/ "DAMAGE",
+ /*[PRIVATE_GLYPH] =*/ "GLYPH",
+ /*[PRIVATE_GLYPHSET] =*/ "GLYPHSET",
+ /*[PRIVATE_PICTURE] =*/ "PICTURE" ,
+ /*[PRIVATE_SYNC_FENCE] =*/ "SYNC_FENCE"
};
void
diff --git a/xorg-server/dix/ptrveloc.c b/xorg-server/dix/ptrveloc.c index 9a8737cf4..74a3d3a90 100644 --- a/xorg-server/dix/ptrveloc.c +++ b/xorg-server/dix/ptrveloc.c @@ -26,6 +26,10 @@ #include <dix-config.h>
#endif
+#ifdef _MSC_VER
+#define _USE_MATH_DEFINES
+#endif
+
#include <math.h>
#include <ptrveloc.h>
#include <exevents.h>
@@ -59,6 +63,11 @@ *
****************************************************************************/
+#ifdef _MSC_VER
+#define inline __inline
+#define lrintf(val) ((int)val)
+#endif
+
/* fwds */
int
SetAccelerationProfile(DeviceVelocityPtr vel, int profile_num);
diff --git a/xorg-server/dix/registry.c b/xorg-server/dix/registry.c index 9a83ff74e..7221359b8 100644 --- a/xorg-server/dix/registry.c +++ b/xorg-server/dix/registry.c @@ -25,6 +25,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include <X11/X.h>
#include <X11/Xproto.h>
#include "resource.h"
diff --git a/xorg-server/dix/resource.c b/xorg-server/dix/resource.c index 26d2c72aa..960aaab50 100644 --- a/xorg-server/dix/resource.c +++ b/xorg-server/dix/resource.c @@ -187,46 +187,47 @@ struct ResourceType { }; static struct ResourceType *resourceTypes; + static const struct ResourceType predefTypes[] = { - [RT_NONE & (RC_LASTPREDEF - 1)] = { - .deleteFunc = (DeleteType)NoopDDA, - .errorValue = BadValue, + /* [RT_NONE & (RC_LASTPREDEF - 1)] = */ { + /*.deleteFunc = */(DeleteType)NoopDDA, + /*.errorValue = */BadValue, }, - [RT_WINDOW & (RC_LASTPREDEF - 1)] = { - .deleteFunc = DeleteWindow, - .errorValue = BadWindow, + /* [RT_WINDOW & (RC_LASTPREDEF - 1)] = */ { + /*.deleteFunc = */DeleteWindow, + /*.errorValue = */BadWindow, }, - [RT_PIXMAP & (RC_LASTPREDEF - 1)] = { - .deleteFunc = dixDestroyPixmap, - .errorValue = BadPixmap, + /* [RT_PIXMAP & (RC_LASTPREDEF - 1)] = */ { + /*.deleteFunc = */dixDestroyPixmap, + /*.errorValue = */BadPixmap, }, - [RT_GC & (RC_LASTPREDEF - 1)] = { - .deleteFunc = FreeGC, - .errorValue = BadGC, + /* [RT_GC & (RC_LASTPREDEF - 1)] = */ { + /*.deleteFunc = */FreeGC, + /*.errorValue = */BadGC, }, - [RT_FONT & (RC_LASTPREDEF - 1)] = { - .deleteFunc = CloseFont, - .errorValue = BadFont, + /* [RT_FONT & (RC_LASTPREDEF - 1)] = */ { + /*.deleteFunc = */CloseFont, + /*.errorValue = */BadFont, }, - [RT_CURSOR & (RC_LASTPREDEF - 1)] = { - .deleteFunc = FreeCursor, - .errorValue = BadCursor, + /* [RT_CURSOR & (RC_LASTPREDEF - 1)] = */ { + /*.deleteFunc = */FreeCursor, + /*.errorValue = */BadCursor, }, - [RT_COLORMAP & (RC_LASTPREDEF - 1)] = { - .deleteFunc = FreeColormap, - .errorValue = BadColor, + /* [RT_COLORMAP & (RC_LASTPREDEF - 1)] = */ { + /*.deleteFunc = */FreeColormap, + /*.errorValue = */BadColor, }, - [RT_CMAPENTRY & (RC_LASTPREDEF - 1)] = { - .deleteFunc = FreeClientPixels, - .errorValue = BadColor, + /* [RT_CMAPENTRY & (RC_LASTPREDEF - 1)] = */ { + /*.deleteFunc = */FreeClientPixels, + /*.errorValue = */BadColor, }, - [RT_OTHERCLIENT & (RC_LASTPREDEF - 1)] = { - .deleteFunc = OtherClientGone, - .errorValue = BadValue, + /* [RT_OTHERCLIENT & (RC_LASTPREDEF - 1)] = */ { + /*.deleteFunc = */OtherClientGone, + /*.errorValue = */BadValue, }, - [RT_PASSIVEGRAB & (RC_LASTPREDEF - 1)] = { - .deleteFunc = DeletePassiveGrab, - .errorValue = BadValue, + /* [RT_PASSIVEGRAB & (RC_LASTPREDEF - 1)] = */ { + /*.deleteFunc = */DeletePassiveGrab, + /*.errorValue = */BadValue, }, }; |