1706f2543Smrg/************************************************************ 2706f2543Smrg 3706f2543SmrgCopyright 1987, 1998 The Open Group 4706f2543Smrg 5706f2543SmrgPermission to use, copy, modify, distribute, and sell this software and its 6706f2543Smrgdocumentation for any purpose is hereby granted without fee, provided that 7706f2543Smrgthe above copyright notice appear in all copies and that both that 8706f2543Smrgcopyright notice and this permission notice appear in supporting 9706f2543Smrgdocumentation. 10706f2543Smrg 11706f2543SmrgThe above copyright notice and this permission notice shall be included in 12706f2543Smrgall copies or substantial portions of the Software. 13706f2543Smrg 14706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15706f2543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16706f2543SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17706f2543SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18706f2543SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19706f2543SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20706f2543Smrg 21706f2543SmrgExcept as contained in this notice, the name of The Open Group shall not be 22706f2543Smrgused in advertising or otherwise to promote the sale, use or other dealings 23706f2543Smrgin this Software without prior written authorization from The Open Group. 24706f2543Smrg 25706f2543Smrg 26706f2543SmrgCopyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. 27706f2543Smrg 28706f2543Smrg All Rights Reserved 29706f2543Smrg 30706f2543SmrgPermission to use, copy, modify, and distribute this software and its 31706f2543Smrgdocumentation for any purpose and without fee is hereby granted, 32706f2543Smrgprovided that the above copyright notice appear in all copies and that 33706f2543Smrgboth that copyright notice and this permission notice appear in 34706f2543Smrgsupporting documentation, and that the name of Digital not be 35706f2543Smrgused in advertising or publicity pertaining to distribution of the 36706f2543Smrgsoftware without specific, written prior permission. 37706f2543Smrg 38706f2543SmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 39706f2543SmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 40706f2543SmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 41706f2543SmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 42706f2543SmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 43706f2543SmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 44706f2543SmrgSOFTWARE. 45706f2543Smrg 46706f2543Smrg********************************************************/ 47706f2543Smrg 48706f2543Smrg 49706f2543Smrg 50706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 51706f2543Smrg#include <dix-config.h> 52706f2543Smrg#endif 53706f2543Smrg 54706f2543Smrg#include <X11/X.h> 55706f2543Smrg#include "misc.h" 56706f2543Smrg#include "resource.h" 57706f2543Smrg#include <X11/Xproto.h> 58706f2543Smrg#include <X11/Xatom.h> 59706f2543Smrg#include "windowstr.h" 60706f2543Smrg#include "inputstr.h" 61706f2543Smrg#include "scrnintstr.h" 62706f2543Smrg#include "cursorstr.h" 63706f2543Smrg#include "dixstruct.h" 64706f2543Smrg#include "ptrveloc.h" 65706f2543Smrg#include "site.h" 66706f2543Smrg#include "xkbsrv.h" 67706f2543Smrg#include "privates.h" 68706f2543Smrg#include "xace.h" 69706f2543Smrg#include "mi.h" 70706f2543Smrg 71706f2543Smrg#include "dispatch.h" 72706f2543Smrg#include "swaprep.h" 73706f2543Smrg#include "dixevents.h" 74706f2543Smrg#include "mipointer.h" 75706f2543Smrg#include "eventstr.h" 76706f2543Smrg 77706f2543Smrg#include <X11/extensions/XI.h> 78706f2543Smrg#include <X11/extensions/XI2.h> 79706f2543Smrg#include <X11/extensions/XIproto.h> 80706f2543Smrg#include <math.h> 81706f2543Smrg#include <pixman.h> 82706f2543Smrg#include "exglobals.h" 83706f2543Smrg#include "exevents.h" 84706f2543Smrg#include "xiquerydevice.h" /* for SizeDeviceClasses */ 85706f2543Smrg#include "xiproperty.h" 86706f2543Smrg#include "enterleave.h" /* for EnterWindow() */ 87706f2543Smrg#include "xserver-properties.h" 88706f2543Smrg#include "xichangehierarchy.h" /* For XISendDeviceHierarchyEvent */ 89706f2543Smrg 90706f2543Smrg/** @file 91706f2543Smrg * This file handles input device-related stuff. 92706f2543Smrg */ 93706f2543Smrg 94706f2543Smrgstatic void RecalculateMasterButtons(DeviceIntPtr slave); 95706f2543Smrg 96706f2543Smrgstatic void 97706f2543SmrgDeviceSetTransform(DeviceIntPtr dev, float *transform) 98706f2543Smrg{ 99706f2543Smrg struct pixman_f_transform scale; 100706f2543Smrg double sx, sy; 101706f2543Smrg int x, y; 102706f2543Smrg 103706f2543Smrg /** 104706f2543Smrg * calculate combined transformation matrix: 105706f2543Smrg * 106706f2543Smrg * M = InvScale * Transform * Scale 107706f2543Smrg * 108706f2543Smrg * So we can later transform points using M * p 109706f2543Smrg * 110706f2543Smrg * Where: 111706f2543Smrg * Scale scales coordinates into 0..1 range 112706f2543Smrg * Transform is the user supplied (affine) transform 113706f2543Smrg * InvScale scales coordinates back up into their native range 114706f2543Smrg */ 115706f2543Smrg sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].min_value; 116706f2543Smrg sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value; 117706f2543Smrg 118706f2543Smrg /* invscale */ 119706f2543Smrg pixman_f_transform_init_scale(&scale, sx, sy); 120706f2543Smrg scale.m[0][2] = dev->valuator->axes[0].min_value; 121706f2543Smrg scale.m[1][2] = dev->valuator->axes[1].min_value; 122706f2543Smrg 123706f2543Smrg /* transform */ 124706f2543Smrg for (y=0; y<3; y++) 125706f2543Smrg for (x=0; x<3; x++) 126706f2543Smrg dev->transform.m[y][x] = *transform++; 127706f2543Smrg 128706f2543Smrg pixman_f_transform_multiply(&dev->transform, &scale, &dev->transform); 129706f2543Smrg 130706f2543Smrg /* scale */ 131706f2543Smrg pixman_f_transform_init_scale(&scale, 1.0 / sx, 1.0 / sy); 132706f2543Smrg scale.m[0][2] = -dev->valuator->axes[0].min_value / sx; 133706f2543Smrg scale.m[1][2] = -dev->valuator->axes[1].min_value / sy; 134706f2543Smrg 135706f2543Smrg pixman_f_transform_multiply(&dev->transform, &dev->transform, &scale); 136706f2543Smrg} 137706f2543Smrg 138706f2543Smrg/** 139706f2543Smrg * DIX property handler. 140706f2543Smrg */ 141706f2543Smrgstatic int 142706f2543SmrgDeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, 143706f2543Smrg BOOL checkonly) 144706f2543Smrg{ 145706f2543Smrg if (property == XIGetKnownProperty(XI_PROP_ENABLED)) 146706f2543Smrg { 147706f2543Smrg if (prop->format != 8 || prop->type != XA_INTEGER || prop->size != 1) 148706f2543Smrg return BadValue; 149706f2543Smrg 150706f2543Smrg /* Don't allow disabling of VCP/VCK */ 151706f2543Smrg if ((dev == inputInfo.pointer || dev == inputInfo.keyboard) && 152706f2543Smrg !(*(CARD8*)prop->data)) 153706f2543Smrg return BadAccess; 154706f2543Smrg 155706f2543Smrg if (!checkonly) 156706f2543Smrg { 157706f2543Smrg if ((*((CARD8*)prop->data)) && !dev->enabled) 158706f2543Smrg EnableDevice(dev, TRUE); 159706f2543Smrg else if (!(*((CARD8*)prop->data)) && dev->enabled) 160706f2543Smrg DisableDevice(dev, TRUE); 161706f2543Smrg } 162706f2543Smrg } else if (property == XIGetKnownProperty(XI_PROP_TRANSFORM)) 163706f2543Smrg { 164706f2543Smrg float *f = (float*)prop->data; 165706f2543Smrg int i; 166706f2543Smrg 167706f2543Smrg if (prop->format != 32 || prop->size != 9 || 168706f2543Smrg prop->type != XIGetKnownProperty(XATOM_FLOAT)) 169706f2543Smrg return BadValue; 170706f2543Smrg 171706f2543Smrg for (i=0; i<9; i++) 172706f2543Smrg if (!isfinite(f[i])) 173706f2543Smrg return BadValue; 174706f2543Smrg 175706f2543Smrg if (!checkonly) 176706f2543Smrg DeviceSetTransform(dev, f); 177706f2543Smrg } 178706f2543Smrg 179706f2543Smrg return Success; 180706f2543Smrg} 181706f2543Smrg 182706f2543Smrg/* Pair the keyboard to the pointer device. Keyboard events will follow the 183706f2543Smrg * pointer sprite. Only applicable for master devices. 184706f2543Smrg * If the client is set, the request to pair comes from some client. In this 185706f2543Smrg * case, we need to check for access. If the client is NULL, it's from an 186706f2543Smrg * internal automatic pairing, we must always permit this. 187706f2543Smrg */ 188706f2543Smrgstatic int 189706f2543SmrgPairDevices(ClientPtr client, DeviceIntPtr ptr, DeviceIntPtr kbd) 190706f2543Smrg{ 191706f2543Smrg if (!ptr) 192706f2543Smrg return BadDevice; 193706f2543Smrg 194706f2543Smrg /* Don't allow pairing for slave devices */ 195706f2543Smrg if (!IsMaster(ptr) || !IsMaster(kbd)) 196706f2543Smrg return BadDevice; 197706f2543Smrg 198706f2543Smrg if (ptr->spriteInfo->paired) 199706f2543Smrg return BadDevice; 200706f2543Smrg 201706f2543Smrg if (kbd->spriteInfo->spriteOwner) 202706f2543Smrg { 203706f2543Smrg free(kbd->spriteInfo->sprite); 204706f2543Smrg kbd->spriteInfo->sprite = NULL; 205706f2543Smrg kbd->spriteInfo->spriteOwner = FALSE; 206706f2543Smrg } 207706f2543Smrg 208706f2543Smrg kbd->spriteInfo->sprite = ptr->spriteInfo->sprite; 209706f2543Smrg kbd->spriteInfo->paired = ptr; 210706f2543Smrg ptr->spriteInfo->paired = kbd; 211706f2543Smrg return Success; 212706f2543Smrg} 213706f2543Smrg 214706f2543Smrg 215706f2543Smrg/** 216706f2543Smrg * Find and return the next unpaired MD pointer device. 217706f2543Smrg */ 218706f2543Smrgstatic DeviceIntPtr 219706f2543SmrgNextFreePointerDevice(void) 220706f2543Smrg{ 221706f2543Smrg DeviceIntPtr dev; 222706f2543Smrg for (dev = inputInfo.devices; dev; dev = dev->next) 223706f2543Smrg if (IsMaster(dev) && 224706f2543Smrg dev->spriteInfo->spriteOwner && 225706f2543Smrg !dev->spriteInfo->paired) 226706f2543Smrg return dev; 227706f2543Smrg return NULL; 228706f2543Smrg} 229706f2543Smrg 230706f2543Smrg/** 231706f2543Smrg * Create a new input device and init it to sane values. The device is added 232706f2543Smrg * to the server's off_devices list. 233706f2543Smrg * 234706f2543Smrg * @param deviceProc Callback for device control function (switch dev on/off). 235706f2543Smrg * @return The newly created device. 236706f2543Smrg */ 237706f2543SmrgDeviceIntPtr 238706f2543SmrgAddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart) 239706f2543Smrg{ 240706f2543Smrg DeviceIntPtr dev, *prev; /* not a typo */ 241706f2543Smrg DeviceIntPtr devtmp; 242706f2543Smrg int devid; 243706f2543Smrg char devind[MAXDEVICES]; 244706f2543Smrg BOOL enabled; 245706f2543Smrg float transform[9]; 246706f2543Smrg 247706f2543Smrg /* Find next available id, 0 and 1 are reserved */ 248706f2543Smrg memset(devind, 0, sizeof(char)*MAXDEVICES); 249706f2543Smrg for (devtmp = inputInfo.devices; devtmp; devtmp = devtmp->next) 250706f2543Smrg devind[devtmp->id]++; 251706f2543Smrg for (devtmp = inputInfo.off_devices; devtmp; devtmp = devtmp->next) 252706f2543Smrg devind[devtmp->id]++; 253706f2543Smrg for (devid = 2; devid < MAXDEVICES && devind[devid]; devid++) 254706f2543Smrg ; 255706f2543Smrg 256706f2543Smrg if (devid >= MAXDEVICES) 257706f2543Smrg return (DeviceIntPtr)NULL; 258706f2543Smrg dev = _dixAllocateObjectWithPrivates(sizeof(DeviceIntRec) + sizeof(SpriteInfoRec), 259706f2543Smrg sizeof(DeviceIntRec) + sizeof(SpriteInfoRec), 260706f2543Smrg offsetof(DeviceIntRec, devPrivates), PRIVATE_DEVICE); 261706f2543Smrg if (!dev) 262706f2543Smrg return (DeviceIntPtr)NULL; 263706f2543Smrg dev->id = devid; 264706f2543Smrg dev->public.processInputProc = ProcessOtherEvent; 265706f2543Smrg dev->public.realInputProc = ProcessOtherEvent; 266706f2543Smrg dev->public.enqueueInputProc = EnqueueEvent; 267706f2543Smrg dev->deviceProc = deviceProc; 268706f2543Smrg dev->startup = autoStart; 269706f2543Smrg 270706f2543Smrg /* device grab defaults */ 271706f2543Smrg dev->deviceGrab.grabTime = currentTime; 272706f2543Smrg dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab; 273706f2543Smrg dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab; 274706f2543Smrg 275706f2543Smrg XkbSetExtension(dev, ProcessKeyboardEvent); 276706f2543Smrg 277706f2543Smrg dev->coreEvents = TRUE; 278706f2543Smrg 279706f2543Smrg /* sprite defaults */ 280706f2543Smrg dev->spriteInfo = (SpriteInfoPtr)&dev[1]; 281706f2543Smrg 282706f2543Smrg /* security creation/labeling check 283706f2543Smrg */ 284706f2543Smrg if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixCreateAccess)) { 285706f2543Smrg free(dev); 286706f2543Smrg return NULL; 287706f2543Smrg } 288706f2543Smrg 289706f2543Smrg inputInfo.numDevices++; 290706f2543Smrg 291706f2543Smrg for (prev = &inputInfo.off_devices; *prev; prev = &(*prev)->next) 292706f2543Smrg ; 293706f2543Smrg *prev = dev; 294706f2543Smrg dev->next = NULL; 295706f2543Smrg 296706f2543Smrg enabled = FALSE; 297706f2543Smrg XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED), 298706f2543Smrg XA_INTEGER, 8, PropModeReplace, 1, &enabled, 299706f2543Smrg FALSE); 300706f2543Smrg XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_ENABLED), FALSE); 301706f2543Smrg 302706f2543Smrg /* unity matrix */ 303706f2543Smrg memset(transform, 0, sizeof(transform)); 304706f2543Smrg transform[0] = transform[4] = transform[8] = 1.0f; 305706f2543Smrg 306706f2543Smrg XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_TRANSFORM), 307706f2543Smrg XIGetKnownProperty(XATOM_FLOAT), 32, 308706f2543Smrg PropModeReplace, 9, transform, FALSE); 309706f2543Smrg XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_TRANSFORM), 310706f2543Smrg FALSE); 311706f2543Smrg 312706f2543Smrg XIRegisterPropertyHandler(dev, DeviceSetProperty, NULL, NULL); 313706f2543Smrg 314706f2543Smrg return dev; 315706f2543Smrg} 316706f2543Smrg 317706f2543Smrgvoid 318706f2543SmrgSendDevicePresenceEvent(int deviceid, int type) 319706f2543Smrg{ 320706f2543Smrg DeviceIntRec dummyDev; 321706f2543Smrg devicePresenceNotify ev; 322706f2543Smrg 323706f2543Smrg memset(&dummyDev, 0, sizeof(DeviceIntRec)); 324706f2543Smrg ev.type = DevicePresenceNotify; 325706f2543Smrg ev.time = currentTime.milliseconds; 326706f2543Smrg ev.devchange = type; 327706f2543Smrg ev.deviceid = deviceid; 328706f2543Smrg dummyDev.id = XIAllDevices; 329706f2543Smrg SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask, 330706f2543Smrg (xEvent*)&ev, 1); 331706f2543Smrg} 332706f2543Smrg 333706f2543Smrg/** 334706f2543Smrg * Enable the device through the driver, add the device to the device list. 335706f2543Smrg * Switch device ON through the driver and push it onto the global device 336706f2543Smrg * list. Initialize the DIX sprite or pair the device. All clients are 337706f2543Smrg * notified about the device being enabled. 338706f2543Smrg * 339706f2543Smrg * A master pointer device needs to be enabled before a master keyboard 340706f2543Smrg * device. 341706f2543Smrg * 342706f2543Smrg * @param The device to be enabled. 343706f2543Smrg * @param sendevent True if an XI2 event should be sent. 344706f2543Smrg * @return TRUE on success or FALSE otherwise. 345706f2543Smrg */ 346706f2543SmrgBool 347706f2543SmrgEnableDevice(DeviceIntPtr dev, BOOL sendevent) 348706f2543Smrg{ 349706f2543Smrg DeviceIntPtr *prev; 350706f2543Smrg int ret; 351706f2543Smrg DeviceIntPtr other; 352706f2543Smrg BOOL enabled; 353706f2543Smrg int flags[MAXDEVICES] = {0}; 354706f2543Smrg 355706f2543Smrg for (prev = &inputInfo.off_devices; 356706f2543Smrg *prev && (*prev != dev); 357706f2543Smrg prev = &(*prev)->next) 358706f2543Smrg ; 359706f2543Smrg 360706f2543Smrg if (!dev->spriteInfo->sprite) 361706f2543Smrg { 362706f2543Smrg if (IsMaster(dev)) 363706f2543Smrg { 364706f2543Smrg /* Sprites appear on first root window, so we can hardcode it */ 365706f2543Smrg if (dev->spriteInfo->spriteOwner) 366706f2543Smrg { 367706f2543Smrg InitializeSprite(dev, screenInfo.screens[0]->root); 368706f2543Smrg /* mode doesn't matter */ 369706f2543Smrg EnterWindow(dev, screenInfo.screens[0]->root, NotifyAncestor); 370706f2543Smrg } 371706f2543Smrg else if ((other = NextFreePointerDevice()) == NULL) 372706f2543Smrg { 373706f2543Smrg ErrorF("[dix] cannot find pointer to pair with. " 374706f2543Smrg "This is a bug.\n"); 375706f2543Smrg return FALSE; 376706f2543Smrg } else 377706f2543Smrg PairDevices(NULL, other, dev); 378706f2543Smrg } else 379706f2543Smrg { 380706f2543Smrg if (dev->coreEvents) 381706f2543Smrg other = (IsPointerDevice(dev)) ? inputInfo.pointer : 382706f2543Smrg inputInfo.keyboard; 383706f2543Smrg else 384706f2543Smrg other = NULL; /* auto-float non-core devices */ 385706f2543Smrg AttachDevice(NULL, dev, other); 386706f2543Smrg } 387706f2543Smrg } 388706f2543Smrg 389706f2543Smrg if ((*prev != dev) || !dev->inited || 390706f2543Smrg ((ret = (*dev->deviceProc)(dev, DEVICE_ON)) != Success)) { 391706f2543Smrg ErrorF("[dix] couldn't enable device %d\n", dev->id); 392706f2543Smrg return FALSE; 393706f2543Smrg } 394706f2543Smrg dev->enabled = TRUE; 395706f2543Smrg *prev = dev->next; 396706f2543Smrg 397706f2543Smrg for (prev = &inputInfo.devices; *prev; prev = &(*prev)->next) 398706f2543Smrg ; 399706f2543Smrg *prev = dev; 400706f2543Smrg dev->next = NULL; 401706f2543Smrg 402706f2543Smrg enabled = TRUE; 403706f2543Smrg XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED), 404706f2543Smrg XA_INTEGER, 8, PropModeReplace, 1, &enabled, 405706f2543Smrg TRUE); 406706f2543Smrg 407706f2543Smrg SendDevicePresenceEvent(dev->id, DeviceEnabled); 408706f2543Smrg if (sendevent) 409706f2543Smrg { 410706f2543Smrg flags[dev->id] |= XIDeviceEnabled; 411706f2543Smrg XISendDeviceHierarchyEvent(flags); 412706f2543Smrg } 413706f2543Smrg 414706f2543Smrg RecalculateMasterButtons(dev); 415706f2543Smrg 416706f2543Smrg return TRUE; 417706f2543Smrg} 418706f2543Smrg 419706f2543Smrg/** 420706f2543Smrg * Switch a device off through the driver and push it onto the off_devices 421706f2543Smrg * list. A device will not send events while disabled. All clients are 422706f2543Smrg * notified about the device being disabled. 423706f2543Smrg * 424706f2543Smrg * Master keyboard devices have to be disabled before master pointer devices 425706f2543Smrg * otherwise things turn bad. 426706f2543Smrg * 427706f2543Smrg * @param sendevent True if an XI2 event should be sent. 428706f2543Smrg * @return TRUE on success or FALSE otherwise. 429706f2543Smrg */ 430706f2543SmrgBool 431706f2543SmrgDisableDevice(DeviceIntPtr dev, BOOL sendevent) 432706f2543Smrg{ 433706f2543Smrg DeviceIntPtr *prev, other; 434706f2543Smrg BOOL enabled; 43591d321acSmrg BOOL dev_in_devices_list = FALSE; 436706f2543Smrg int flags[MAXDEVICES] = {0}; 437706f2543Smrg 43891d321acSmrg for (other = inputInfo.devices; other; other = other->next) { 43991d321acSmrg if (other == dev) { 44091d321acSmrg dev_in_devices_list = TRUE; 44191d321acSmrg break; 44291d321acSmrg } 44391d321acSmrg } 44491d321acSmrg 44591d321acSmrg if (!dev_in_devices_list) 446706f2543Smrg return FALSE; 447706f2543Smrg 448706f2543Smrg /* float attached devices */ 449706f2543Smrg if (IsMaster(dev)) 450706f2543Smrg { 451706f2543Smrg for (other = inputInfo.devices; other; other = other->next) 452706f2543Smrg { 453706f2543Smrg if (other->u.master == dev) 454706f2543Smrg { 455706f2543Smrg AttachDevice(NULL, other, NULL); 456706f2543Smrg flags[other->id] |= XISlaveDetached; 457706f2543Smrg } 458706f2543Smrg } 459706f2543Smrg } 460706f2543Smrg else 461706f2543Smrg { 462706f2543Smrg for (other = inputInfo.devices; other; other = other->next) 463706f2543Smrg { 464706f2543Smrg if (IsMaster(other) && other->u.lastSlave == dev) 465706f2543Smrg other->u.lastSlave = NULL; 466706f2543Smrg } 467706f2543Smrg } 468706f2543Smrg 469706f2543Smrg if (IsMaster(dev) && dev->spriteInfo->sprite) 470706f2543Smrg { 471706f2543Smrg for (other = inputInfo.devices; other; other = other->next) 472706f2543Smrg { 473706f2543Smrg if (other->spriteInfo->paired == dev) 474706f2543Smrg { 475706f2543Smrg ErrorF("[dix] cannot disable device, still paired. " 476706f2543Smrg "This is a bug. \n"); 477706f2543Smrg return FALSE; 478706f2543Smrg } 479706f2543Smrg } 480dd8addeeSmrg 481dd8addeeSmrg for (other = inputInfo.off_devices; other; other = other->next) { 482dd8addeeSmrg /* 483dd8addeeSmrg * XXXMRG, from newer GetMaster(). The GetMaster() with new 484dd8addeeSmrg * MASTER_ATTACHED avoids paired devices, and with this call 485dd8addeeSmrg * being !IsMaster() first, dev->u.master is the only answer 486dd8addeeSmrg * it can give. 487dd8addeeSmrg */ 488dd8addeeSmrg if (!IsMaster(other) && other->u.master == dev) { 489dd8addeeSmrg AttachDevice(NULL, other, NULL); 490dd8addeeSmrg flags[other->id] |= XISlaveDetached; 491dd8addeeSmrg } 492dd8addeeSmrg } 493706f2543Smrg } 494706f2543Smrg 495706f2543Smrg (void)(*dev->deviceProc)(dev, DEVICE_OFF); 496706f2543Smrg dev->enabled = FALSE; 497706f2543Smrg 498706f2543Smrg /* now that the device is disabled, we can reset the signal handler's 499706f2543Smrg * last.slave */ 500706f2543Smrg OsBlockSignals(); 501706f2543Smrg for (other = inputInfo.devices; other; other = other->next) 502706f2543Smrg { 503706f2543Smrg if (other->last.slave == dev) 504706f2543Smrg other->last.slave = NULL; 505706f2543Smrg } 506706f2543Smrg OsReleaseSignals(); 507706f2543Smrg 508706f2543Smrg LeaveWindow(dev); 509706f2543Smrg SetFocusOut(dev); 510706f2543Smrg 51191d321acSmrg for (prev = &inputInfo.devices; 51291d321acSmrg *prev && (*prev != dev); prev = &(*prev)->next); 51391d321acSmrg 514706f2543Smrg *prev = dev->next; 515706f2543Smrg dev->next = inputInfo.off_devices; 516706f2543Smrg inputInfo.off_devices = dev; 517706f2543Smrg 518706f2543Smrg enabled = FALSE; 519706f2543Smrg XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED), 520706f2543Smrg XA_INTEGER, 8, PropModeReplace, 1, &enabled, 521706f2543Smrg TRUE); 522706f2543Smrg 523706f2543Smrg SendDevicePresenceEvent(dev->id, DeviceDisabled); 524706f2543Smrg if (sendevent) 525706f2543Smrg { 526706f2543Smrg flags[dev->id] = XIDeviceDisabled; 527706f2543Smrg XISendDeviceHierarchyEvent(flags); 528706f2543Smrg } 529706f2543Smrg 530706f2543Smrg RecalculateMasterButtons(dev); 531706f2543Smrg 532706f2543Smrg return TRUE; 533706f2543Smrg} 534706f2543Smrg 535706f2543Smrg/** 536706f2543Smrg * Initialise a new device through the driver and tell all clients about the 537706f2543Smrg * new device. 538706f2543Smrg * 539706f2543Smrg * Must be called before EnableDevice. 540706f2543Smrg * The device will NOT send events until it is enabled! 541706f2543Smrg * 542706f2543Smrg * @param sendevent True if an XI2 event should be sent. 543706f2543Smrg * @return Success or an error code on failure. 544706f2543Smrg */ 545706f2543Smrgint 546706f2543SmrgActivateDevice(DeviceIntPtr dev, BOOL sendevent) 547706f2543Smrg{ 548706f2543Smrg int ret = Success; 549706f2543Smrg ScreenPtr pScreen = screenInfo.screens[0]; 550706f2543Smrg 551706f2543Smrg if (!dev || !dev->deviceProc) 552706f2543Smrg return BadImplementation; 553706f2543Smrg 554706f2543Smrg ret = (*dev->deviceProc) (dev, DEVICE_INIT); 555706f2543Smrg dev->inited = (ret == Success); 556706f2543Smrg if (!dev->inited) 557706f2543Smrg return ret; 558706f2543Smrg 559706f2543Smrg /* Initialize memory for sprites. */ 560706f2543Smrg if (IsMaster(dev) && dev->spriteInfo->spriteOwner) 561706f2543Smrg if (!pScreen->DeviceCursorInitialize(dev, pScreen)) 562706f2543Smrg ret = BadAlloc; 563706f2543Smrg 564706f2543Smrg SendDevicePresenceEvent(dev->id, DeviceAdded); 565706f2543Smrg if (sendevent) 566706f2543Smrg { 567706f2543Smrg int flags[MAXDEVICES] = {0}; 568706f2543Smrg flags[dev->id] = XISlaveAdded; 569706f2543Smrg XISendDeviceHierarchyEvent(flags); 570706f2543Smrg } 571706f2543Smrg return ret; 572706f2543Smrg} 573706f2543Smrg 574706f2543Smrg/** 575706f2543Smrg * Ring the bell. 576706f2543Smrg * The actual task of ringing the bell is the job of the DDX. 577706f2543Smrg */ 578706f2543Smrgstatic void 579706f2543SmrgCoreKeyboardBell(int volume, DeviceIntPtr pDev, pointer arg, int something) 580706f2543Smrg{ 581706f2543Smrg KeybdCtrl *ctrl = arg; 582706f2543Smrg 583706f2543Smrg DDXRingBell(volume, ctrl->bell_pitch, ctrl->bell_duration); 584706f2543Smrg} 585706f2543Smrg 586706f2543Smrgstatic void 587706f2543SmrgCoreKeyboardCtl(DeviceIntPtr pDev, KeybdCtrl *ctrl) 588706f2543Smrg{ 589706f2543Smrg return; 590706f2543Smrg} 591706f2543Smrg 592706f2543Smrg/** 593706f2543Smrg * Device control function for the Virtual Core Keyboard. 594706f2543Smrg */ 595706f2543Smrgint 596706f2543SmrgCoreKeyboardProc(DeviceIntPtr pDev, int what) 597706f2543Smrg{ 598706f2543Smrg 599706f2543Smrg switch (what) { 600706f2543Smrg case DEVICE_INIT: 601706f2543Smrg if (!InitKeyboardDeviceStruct(pDev, NULL, CoreKeyboardBell, 602706f2543Smrg CoreKeyboardCtl)) 603706f2543Smrg { 604706f2543Smrg ErrorF("Keyboard initialization failed. This could be a missing " 605706f2543Smrg "or incorrect setup of xkeyboard-config.\n"); 606706f2543Smrg return BadValue; 607706f2543Smrg } 608706f2543Smrg return Success; 609706f2543Smrg 610706f2543Smrg case DEVICE_ON: 611706f2543Smrg case DEVICE_OFF: 612706f2543Smrg return Success; 613706f2543Smrg 614706f2543Smrg case DEVICE_CLOSE: 615706f2543Smrg return Success; 616706f2543Smrg } 617706f2543Smrg 618706f2543Smrg return BadMatch; 619706f2543Smrg} 620706f2543Smrg 621706f2543Smrg/** 622706f2543Smrg * Device control function for the Virtual Core Pointer. 623706f2543Smrg */ 624706f2543Smrgint 625706f2543SmrgCorePointerProc(DeviceIntPtr pDev, int what) 626706f2543Smrg{ 627706f2543Smrg#define NBUTTONS 10 628706f2543Smrg#define NAXES 2 629706f2543Smrg BYTE map[NBUTTONS + 1]; 630706f2543Smrg int i = 0; 631706f2543Smrg Atom btn_labels[NBUTTONS] = {0}; 632706f2543Smrg Atom axes_labels[NAXES] = {0}; 633706f2543Smrg 634706f2543Smrg switch (what) { 635706f2543Smrg case DEVICE_INIT: 636706f2543Smrg for (i = 1; i <= NBUTTONS; i++) 637706f2543Smrg map[i] = i; 638706f2543Smrg 639706f2543Smrg btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); 640706f2543Smrg btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); 641706f2543Smrg btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); 642706f2543Smrg btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); 643706f2543Smrg btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); 644706f2543Smrg btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT); 645706f2543Smrg btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT); 646706f2543Smrg /* don't know about the rest */ 647706f2543Smrg 648706f2543Smrg axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); 649706f2543Smrg axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); 650706f2543Smrg 651706f2543Smrg if (!InitPointerDeviceStruct((DevicePtr)pDev, map, NBUTTONS, btn_labels, 652706f2543Smrg (PtrCtrlProcPtr)NoopDDA, 653706f2543Smrg GetMotionHistorySize(), NAXES, axes_labels)) 654706f2543Smrg { 655706f2543Smrg ErrorF("Could not initialize device '%s'. Out of memory.\n", 656706f2543Smrg pDev->name); 657706f2543Smrg return BadAlloc; /* IPDS only fails on allocs */ 658706f2543Smrg } 659706f2543Smrg pDev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2; 660706f2543Smrg pDev->last.valuators[0] = pDev->valuator->axisVal[0]; 661706f2543Smrg pDev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2; 662706f2543Smrg pDev->last.valuators[1] = pDev->valuator->axisVal[1]; 663706f2543Smrg break; 664706f2543Smrg 665706f2543Smrg case DEVICE_CLOSE: 666706f2543Smrg break; 667706f2543Smrg 668706f2543Smrg default: 669706f2543Smrg break; 670706f2543Smrg } 671706f2543Smrg 672706f2543Smrg return Success; 673706f2543Smrg 674706f2543Smrg#undef NBUTTONS 675706f2543Smrg#undef NAXES 676706f2543Smrg} 677706f2543Smrg 678706f2543Smrg/** 679706f2543Smrg * Initialise the two core devices, VCP and VCK (see events.c). 680706f2543Smrg * Both devices are not tied to physical devices, but guarantee that there is 681706f2543Smrg * always a keyboard and a pointer present and keep the protocol semantics. 682706f2543Smrg * 683706f2543Smrg * Note that the server MUST have two core devices at all times, even if there 684706f2543Smrg * is no physical device connected. 685706f2543Smrg */ 686706f2543Smrgvoid 687706f2543SmrgInitCoreDevices(void) 688706f2543Smrg{ 689706f2543Smrg if (AllocDevicePair(serverClient, "Virtual core", 690706f2543Smrg &inputInfo.pointer, &inputInfo.keyboard, 691706f2543Smrg CorePointerProc, CoreKeyboardProc, 692706f2543Smrg TRUE) != Success) 693706f2543Smrg FatalError("Failed to allocate core devices"); 694706f2543Smrg 695706f2543Smrg if (ActivateDevice(inputInfo.pointer, TRUE) != Success || 696706f2543Smrg ActivateDevice(inputInfo.keyboard, TRUE) != Success) 697706f2543Smrg FatalError("Failed to activate core devices."); 698706f2543Smrg if (!EnableDevice(inputInfo.pointer, TRUE) || 699706f2543Smrg !EnableDevice(inputInfo.keyboard, TRUE)) 700706f2543Smrg FatalError("Failed to enable core devices."); 701706f2543Smrg 702706f2543Smrg InitXTestDevices(); 703706f2543Smrg} 704706f2543Smrg 705706f2543Smrg/** 706706f2543Smrg * Activate all switched-off devices and then enable all those devices. 707706f2543Smrg * 708706f2543Smrg * Will return an error if no core keyboard or core pointer is present. 709706f2543Smrg * In theory this should never happen if you call InitCoreDevices() first. 710706f2543Smrg * 711706f2543Smrg * InitAndStartDevices needs to be called AFTER the windows are initialized. 712706f2543Smrg * Devices will start sending events after InitAndStartDevices() has 713706f2543Smrg * completed. 714706f2543Smrg * 715706f2543Smrg * @return Success or error code on failure. 716706f2543Smrg */ 717706f2543Smrgint 718706f2543SmrgInitAndStartDevices(void) 719706f2543Smrg{ 720706f2543Smrg DeviceIntPtr dev, next; 721706f2543Smrg 722706f2543Smrg for (dev = inputInfo.off_devices; dev; dev = dev->next) { 723706f2543Smrg DebugF("(dix) initialising device %d\n", dev->id); 724706f2543Smrg if (!dev->inited) 725706f2543Smrg ActivateDevice(dev, TRUE); 726706f2543Smrg } 727706f2543Smrg 728706f2543Smrg /* enable real devices */ 729706f2543Smrg for (dev = inputInfo.off_devices; dev; dev = next) 730706f2543Smrg { 731706f2543Smrg DebugF("(dix) enabling device %d\n", dev->id); 732706f2543Smrg next = dev->next; 733706f2543Smrg if (dev->inited && dev->startup) 734706f2543Smrg EnableDevice(dev, TRUE); 735706f2543Smrg } 736706f2543Smrg 737706f2543Smrg return Success; 738706f2543Smrg} 739706f2543Smrg 740706f2543Smrg/** 741706f2543Smrg * Free the given device class and reset the pointer to NULL. 742706f2543Smrg */ 743706f2543Smrgstatic void 744706f2543SmrgFreeDeviceClass(int type, pointer *class) 745706f2543Smrg{ 746706f2543Smrg if (!(*class)) 747706f2543Smrg return; 748706f2543Smrg 749706f2543Smrg switch(type) 750706f2543Smrg { 751706f2543Smrg case KeyClass: 752706f2543Smrg { 753706f2543Smrg KeyClassPtr* k = (KeyClassPtr*)class; 754706f2543Smrg if ((*k)->xkbInfo) 755706f2543Smrg { 756706f2543Smrg XkbFreeInfo((*k)->xkbInfo); 757706f2543Smrg (*k)->xkbInfo = NULL; 758706f2543Smrg } 759706f2543Smrg free((*k)); 760706f2543Smrg break; 761706f2543Smrg } 762706f2543Smrg case ButtonClass: 763706f2543Smrg { 764706f2543Smrg ButtonClassPtr *b = (ButtonClassPtr*)class; 765706f2543Smrg free((*b)->xkb_acts); 766706f2543Smrg free((*b)); 767706f2543Smrg break; 768706f2543Smrg } 769706f2543Smrg case ValuatorClass: 770706f2543Smrg { 771706f2543Smrg ValuatorClassPtr *v = (ValuatorClassPtr*)class; 772706f2543Smrg 773706f2543Smrg free((*v)->motion); 774706f2543Smrg free((*v)); 775706f2543Smrg break; 776706f2543Smrg } 777706f2543Smrg case FocusClass: 778706f2543Smrg { 779706f2543Smrg FocusClassPtr *f = (FocusClassPtr*)class; 780706f2543Smrg free((*f)->trace); 781706f2543Smrg free((*f)); 782706f2543Smrg break; 783706f2543Smrg } 784706f2543Smrg case ProximityClass: 785706f2543Smrg { 786706f2543Smrg ProximityClassPtr *p = (ProximityClassPtr*)class; 787706f2543Smrg free((*p)); 788706f2543Smrg break; 789706f2543Smrg } 790706f2543Smrg } 791706f2543Smrg *class = NULL; 792706f2543Smrg} 793706f2543Smrg 794706f2543Smrgstatic void 795706f2543SmrgFreeFeedbackClass(int type, pointer *class) 796706f2543Smrg{ 797706f2543Smrg if (!(*class)) 798706f2543Smrg return; 799706f2543Smrg 800706f2543Smrg switch(type) 801706f2543Smrg { 802706f2543Smrg case KbdFeedbackClass: 803706f2543Smrg { 804706f2543Smrg KbdFeedbackPtr *kbdfeed = (KbdFeedbackPtr*)class; 805706f2543Smrg KbdFeedbackPtr k, knext; 806706f2543Smrg for (k = (*kbdfeed); k; k = knext) { 807706f2543Smrg knext = k->next; 808706f2543Smrg if (k->xkb_sli) 809706f2543Smrg XkbFreeSrvLedInfo(k->xkb_sli); 810706f2543Smrg free(k); 811706f2543Smrg } 812706f2543Smrg break; 813706f2543Smrg } 814706f2543Smrg case PtrFeedbackClass: 815706f2543Smrg { 816706f2543Smrg PtrFeedbackPtr *ptrfeed = (PtrFeedbackPtr*)class; 817706f2543Smrg PtrFeedbackPtr p, pnext; 818706f2543Smrg 819706f2543Smrg for (p = (*ptrfeed); p; p = pnext) { 820706f2543Smrg pnext = p->next; 821706f2543Smrg free(p); 822706f2543Smrg } 823706f2543Smrg break; 824706f2543Smrg } 825706f2543Smrg case IntegerFeedbackClass: 826706f2543Smrg { 827706f2543Smrg IntegerFeedbackPtr *intfeed = (IntegerFeedbackPtr*)class; 828706f2543Smrg IntegerFeedbackPtr i, inext; 829706f2543Smrg 830706f2543Smrg for (i = (*intfeed); i; i = inext) { 831706f2543Smrg inext = i->next; 832706f2543Smrg free(i); 833706f2543Smrg } 834706f2543Smrg break; 835706f2543Smrg } 836706f2543Smrg case StringFeedbackClass: 837706f2543Smrg { 838706f2543Smrg StringFeedbackPtr *stringfeed = (StringFeedbackPtr*)class; 839706f2543Smrg StringFeedbackPtr s, snext; 840706f2543Smrg 841706f2543Smrg for (s = (*stringfeed); s; s = snext) { 842706f2543Smrg snext = s->next; 843706f2543Smrg free(s->ctrl.symbols_supported); 844706f2543Smrg free(s->ctrl.symbols_displayed); 845706f2543Smrg free(s); 846706f2543Smrg } 847706f2543Smrg break; 848706f2543Smrg } 849706f2543Smrg case BellFeedbackClass: 850706f2543Smrg { 851706f2543Smrg BellFeedbackPtr *bell = (BellFeedbackPtr*)class; 852706f2543Smrg BellFeedbackPtr b, bnext; 853706f2543Smrg 854706f2543Smrg for (b = (*bell); b; b = bnext) { 855706f2543Smrg bnext = b->next; 856706f2543Smrg free(b); 857706f2543Smrg } 858706f2543Smrg break; 859706f2543Smrg } 860706f2543Smrg case LedFeedbackClass: 861706f2543Smrg { 862706f2543Smrg LedFeedbackPtr *leds = (LedFeedbackPtr*)class; 863706f2543Smrg LedFeedbackPtr l, lnext; 864706f2543Smrg 865706f2543Smrg for (l = (*leds); l; l = lnext) { 866706f2543Smrg lnext = l->next; 867706f2543Smrg if (l->xkb_sli) 868706f2543Smrg XkbFreeSrvLedInfo(l->xkb_sli); 869706f2543Smrg free(l); 870706f2543Smrg } 871706f2543Smrg break; 872706f2543Smrg } 873706f2543Smrg } 874706f2543Smrg *class = NULL; 875706f2543Smrg} 876706f2543Smrg 877706f2543Smrgstatic void 878706f2543SmrgFreeAllDeviceClasses(ClassesPtr classes) 879706f2543Smrg{ 880706f2543Smrg if (!classes) 881706f2543Smrg return; 882706f2543Smrg 883706f2543Smrg FreeDeviceClass(KeyClass, (pointer)&classes->key); 884706f2543Smrg FreeDeviceClass(ValuatorClass, (pointer)&classes->valuator); 885706f2543Smrg FreeDeviceClass(ButtonClass, (pointer)&classes->button); 886706f2543Smrg FreeDeviceClass(FocusClass, (pointer)&classes->focus); 887706f2543Smrg FreeDeviceClass(ProximityClass, (pointer)&classes->proximity); 888706f2543Smrg 889706f2543Smrg FreeFeedbackClass(KbdFeedbackClass, (pointer)&classes->kbdfeed); 890706f2543Smrg FreeFeedbackClass(PtrFeedbackClass, (pointer)&classes->ptrfeed); 891706f2543Smrg FreeFeedbackClass(IntegerFeedbackClass, (pointer)&classes->intfeed); 892706f2543Smrg FreeFeedbackClass(StringFeedbackClass, (pointer)&classes->stringfeed); 893706f2543Smrg FreeFeedbackClass(BellFeedbackClass, (pointer)&classes->bell); 894706f2543Smrg FreeFeedbackClass(LedFeedbackClass, (pointer)&classes->leds); 895706f2543Smrg 896706f2543Smrg} 897706f2543Smrg 898706f2543Smrg/** 899706f2543Smrg * Close down a device and free all resources. 900706f2543Smrg * Once closed down, the driver will probably not expect you that you'll ever 901706f2543Smrg * enable it again and free associated structs. If you want the device to just 902706f2543Smrg * be disabled, DisableDevice(). 903706f2543Smrg * Don't call this function directly, use RemoveDevice() instead. 904706f2543Smrg */ 905706f2543Smrgstatic void 906706f2543SmrgCloseDevice(DeviceIntPtr dev) 907706f2543Smrg{ 908706f2543Smrg ScreenPtr screen = screenInfo.screens[0]; 909706f2543Smrg ClassesPtr classes; 910706f2543Smrg int j; 911706f2543Smrg 912706f2543Smrg if (!dev) 913706f2543Smrg return; 914706f2543Smrg 915706f2543Smrg XIDeleteAllDeviceProperties(dev); 916706f2543Smrg 917706f2543Smrg if (dev->inited) 918706f2543Smrg (void)(*dev->deviceProc)(dev, DEVICE_CLOSE); 919706f2543Smrg 920706f2543Smrg /* free sprite memory */ 921706f2543Smrg if (IsMaster(dev) && dev->spriteInfo->sprite) 922706f2543Smrg screen->DeviceCursorCleanup(dev, screen); 923706f2543Smrg 924706f2543Smrg /* free acceleration info */ 925706f2543Smrg if(dev->valuator && dev->valuator->accelScheme.AccelCleanupProc) 926706f2543Smrg dev->valuator->accelScheme.AccelCleanupProc(dev); 927706f2543Smrg 928706f2543Smrg while (dev->xkb_interest) 929706f2543Smrg XkbRemoveResourceClient((DevicePtr)dev,dev->xkb_interest->resource); 930706f2543Smrg 931706f2543Smrg free(dev->name); 932706f2543Smrg 933706f2543Smrg classes = (ClassesPtr)&dev->key; 934706f2543Smrg FreeAllDeviceClasses(classes); 935706f2543Smrg 936706f2543Smrg if (IsMaster(dev)) 937706f2543Smrg { 938706f2543Smrg classes = dev->unused_classes; 939706f2543Smrg FreeAllDeviceClasses(classes); 940706f2543Smrg free(classes); 941706f2543Smrg } 942706f2543Smrg 943706f2543Smrg if (DevHasCursor(dev) && dev->spriteInfo->sprite) { 944706f2543Smrg if (dev->spriteInfo->sprite->current) 945706f2543Smrg FreeCursor(dev->spriteInfo->sprite->current, None); 946706f2543Smrg free(dev->spriteInfo->sprite->spriteTrace); 947706f2543Smrg free(dev->spriteInfo->sprite); 948706f2543Smrg } 949706f2543Smrg 950706f2543Smrg /* a client may have the device set as client pointer */ 951706f2543Smrg for (j = 0; j < currentMaxClients; j++) 952706f2543Smrg { 953706f2543Smrg if (clients[j] && clients[j]->clientPtr == dev) 954706f2543Smrg { 955706f2543Smrg clients[j]->clientPtr = NULL; 956706f2543Smrg clients[j]->clientPtr = PickPointer(clients[j]); 957706f2543Smrg } 958706f2543Smrg } 959706f2543Smrg 960706f2543Smrg free(dev->deviceGrab.sync.event); 961706f2543Smrg free(dev->config_info); /* Allocated in xf86ActivateDevice. */ 962706f2543Smrg dev->config_info = NULL; 963706f2543Smrg dixFreeObjectWithPrivates(dev, PRIVATE_DEVICE); 964706f2543Smrg} 965706f2543Smrg 966706f2543Smrg/** 967706f2543Smrg * Shut down all devices of one list and free all resources. 968706f2543Smrg */ 969706f2543Smrgstatic 970706f2543Smrgvoid 971706f2543SmrgCloseDeviceList(DeviceIntPtr *listHead) 972706f2543Smrg{ 973706f2543Smrg /* Used to mark devices that we tried to free */ 974706f2543Smrg Bool freedIds[MAXDEVICES]; 975706f2543Smrg DeviceIntPtr dev; 976706f2543Smrg int i; 977706f2543Smrg 978706f2543Smrg if (listHead == NULL) 979706f2543Smrg return; 980706f2543Smrg 981706f2543Smrg for (i = 0; i < MAXDEVICES; i++) 982706f2543Smrg freedIds[i] = FALSE; 983706f2543Smrg 984706f2543Smrg dev = *listHead; 985706f2543Smrg while (dev != NULL) 986706f2543Smrg { 987706f2543Smrg freedIds[dev->id] = TRUE; 988706f2543Smrg DeleteInputDeviceRequest(dev); 989706f2543Smrg 990706f2543Smrg dev = *listHead; 991706f2543Smrg while (dev != NULL && freedIds[dev->id]) 992706f2543Smrg dev = dev->next; 993706f2543Smrg } 994706f2543Smrg} 995706f2543Smrg 996706f2543Smrg/** 997706f2543Smrg * Shut down all devices, free all resources, etc. 998706f2543Smrg * Only useful if you're shutting down the server! 999706f2543Smrg */ 1000706f2543Smrgvoid 1001706f2543SmrgCloseDownDevices(void) 1002706f2543Smrg{ 1003706f2543Smrg DeviceIntPtr dev; 1004706f2543Smrg 1005706f2543Smrg OsBlockSignals(); 1006706f2543Smrg 1007706f2543Smrg /* Float all SDs before closing them. Note that at this point resources 1008706f2543Smrg * (e.g. cursors) have been freed already, so we can't just call 1009706f2543Smrg * AttachDevice(NULL, dev, NULL). Instead, we have to forcibly set master 1010706f2543Smrg * to NULL and pretend nothing happened. 1011706f2543Smrg */ 1012706f2543Smrg for (dev = inputInfo.devices; dev; dev = dev->next) 1013706f2543Smrg { 1014706f2543Smrg if (!IsMaster(dev) && dev->u.master) 1015706f2543Smrg dev->u.master = NULL; 1016706f2543Smrg } 1017706f2543Smrg 1018dd8addeeSmrg for (dev = inputInfo.off_devices; dev; dev = dev->next) { 1019dd8addeeSmrg if (!IsMaster(dev) && dev->u.master) 1020dd8addeeSmrg dev->u.master = NULL; 1021dd8addeeSmrg } 1022dd8addeeSmrg 1023706f2543Smrg CloseDeviceList(&inputInfo.devices); 1024706f2543Smrg CloseDeviceList(&inputInfo.off_devices); 1025706f2543Smrg 1026706f2543Smrg CloseDevice(inputInfo.pointer); 1027706f2543Smrg CloseDevice(inputInfo.keyboard); 1028706f2543Smrg 1029706f2543Smrg inputInfo.devices = NULL; 1030706f2543Smrg inputInfo.off_devices = NULL; 1031706f2543Smrg inputInfo.keyboard = NULL; 1032706f2543Smrg inputInfo.pointer = NULL; 1033706f2543Smrg XkbDeleteRulesDflts(); 1034706f2543Smrg 1035706f2543Smrg OsReleaseSignals(); 1036706f2543Smrg} 1037706f2543Smrg 1038706f2543Smrg/** 1039706f2543Smrg * Remove the cursor sprite for all devices. This needs to be done before any 1040706f2543Smrg * resources are freed or any device is deleted. 1041706f2543Smrg */ 1042706f2543Smrgvoid 1043706f2543SmrgUndisplayDevices(void) 1044706f2543Smrg{ 1045706f2543Smrg DeviceIntPtr dev; 1046706f2543Smrg ScreenPtr screen = screenInfo.screens[0]; 1047706f2543Smrg 1048706f2543Smrg for (dev = inputInfo.devices; dev; dev = dev->next) 1049706f2543Smrg screen->DisplayCursor(dev, screen, NullCursor); 1050706f2543Smrg} 1051706f2543Smrg 1052706f2543Smrg/** 1053706f2543Smrg * Remove a device from the device list, closes it and thus frees all 1054706f2543Smrg * resources. 1055706f2543Smrg * Removes both enabled and disabled devices and notifies all devices about 1056706f2543Smrg * the removal of the device. 1057706f2543Smrg * 1058706f2543Smrg * No PresenceNotify is sent for device that the client never saw. This can 1059706f2543Smrg * happen if a malloc fails during the addition of master devices. If 1060706f2543Smrg * dev->init is FALSE it means the client never received a DeviceAdded event, 1061706f2543Smrg * so let's not send a DeviceRemoved event either. 1062706f2543Smrg * 1063706f2543Smrg * @param sendevent True if an XI2 event should be sent. 1064706f2543Smrg */ 1065706f2543Smrgint 1066706f2543SmrgRemoveDevice(DeviceIntPtr dev, BOOL sendevent) 1067706f2543Smrg{ 1068706f2543Smrg DeviceIntPtr prev,tmp,next; 1069706f2543Smrg int ret = BadMatch; 1070706f2543Smrg ScreenPtr screen = screenInfo.screens[0]; 1071706f2543Smrg int deviceid; 1072706f2543Smrg int initialized; 1073706f2543Smrg int flags[MAXDEVICES] = {0}; 1074706f2543Smrg 1075706f2543Smrg DebugF("(dix) removing device %d\n", dev->id); 1076706f2543Smrg 1077706f2543Smrg if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer) 1078706f2543Smrg return BadImplementation; 1079706f2543Smrg 1080706f2543Smrg initialized = dev->inited; 1081706f2543Smrg deviceid = dev->id; 1082706f2543Smrg 1083706f2543Smrg if (initialized) 1084706f2543Smrg { 1085706f2543Smrg if (DevHasCursor(dev)) 1086706f2543Smrg screen->DisplayCursor(dev, screen, NullCursor); 1087706f2543Smrg 1088706f2543Smrg DisableDevice(dev, sendevent); 1089706f2543Smrg flags[dev->id] = XIDeviceDisabled; 1090706f2543Smrg } 1091706f2543Smrg 1092706f2543Smrg prev = NULL; 1093706f2543Smrg for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) { 1094706f2543Smrg next = tmp->next; 1095706f2543Smrg if (tmp == dev) { 1096706f2543Smrg 1097706f2543Smrg if (prev==NULL) 1098706f2543Smrg inputInfo.devices = next; 1099706f2543Smrg else 1100706f2543Smrg prev->next = next; 1101706f2543Smrg 1102706f2543Smrg flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved; 1103706f2543Smrg CloseDevice(tmp); 1104706f2543Smrg ret = Success; 1105706f2543Smrg } 1106706f2543Smrg } 1107706f2543Smrg 1108706f2543Smrg prev = NULL; 1109706f2543Smrg for (tmp = inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) { 1110706f2543Smrg next = tmp->next; 1111706f2543Smrg if (tmp == dev) { 1112706f2543Smrg flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved; 1113706f2543Smrg CloseDevice(tmp); 1114706f2543Smrg 1115706f2543Smrg if (prev == NULL) 1116706f2543Smrg inputInfo.off_devices = next; 1117706f2543Smrg else 1118706f2543Smrg prev->next = next; 1119706f2543Smrg 1120706f2543Smrg ret = Success; 1121706f2543Smrg } 1122706f2543Smrg } 1123706f2543Smrg 1124706f2543Smrg if (ret == Success && initialized) { 1125706f2543Smrg inputInfo.numDevices--; 1126706f2543Smrg SendDevicePresenceEvent(deviceid, DeviceRemoved); 1127706f2543Smrg if (sendevent) 1128706f2543Smrg XISendDeviceHierarchyEvent(flags); 1129706f2543Smrg } 1130706f2543Smrg 1131706f2543Smrg return ret; 1132706f2543Smrg} 1133706f2543Smrg 1134706f2543Smrgint 1135706f2543SmrgNumMotionEvents(void) 1136706f2543Smrg{ 1137706f2543Smrg /* only called to fill data in initial connection reply. 1138706f2543Smrg * VCP is ok here, it is the only fixed device we have. */ 1139706f2543Smrg return inputInfo.pointer->valuator->numMotionEvents; 1140706f2543Smrg} 1141706f2543Smrg 1142706f2543Smrgint 1143706f2543SmrgdixLookupDevice(DeviceIntPtr *pDev, int id, ClientPtr client, Mask access_mode) 1144706f2543Smrg{ 1145706f2543Smrg DeviceIntPtr dev; 1146706f2543Smrg int rc; 1147706f2543Smrg *pDev = NULL; 1148706f2543Smrg 1149706f2543Smrg for (dev=inputInfo.devices; dev; dev=dev->next) { 1150706f2543Smrg if (dev->id == id) 1151706f2543Smrg goto found; 1152706f2543Smrg } 1153706f2543Smrg for (dev=inputInfo.off_devices; dev; dev=dev->next) { 1154706f2543Smrg if (dev->id == id) 1155706f2543Smrg goto found; 1156706f2543Smrg } 1157706f2543Smrg return BadDevice; 1158706f2543Smrg 1159706f2543Smrgfound: 1160706f2543Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 1161706f2543Smrg if (rc == Success) 1162706f2543Smrg *pDev = dev; 1163706f2543Smrg return rc; 1164706f2543Smrg} 1165706f2543Smrg 1166706f2543Smrgvoid 1167706f2543SmrgQueryMinMaxKeyCodes(KeyCode *minCode, KeyCode *maxCode) 1168706f2543Smrg{ 1169706f2543Smrg if (inputInfo.keyboard) { 1170706f2543Smrg *minCode = inputInfo.keyboard->key->xkbInfo->desc->min_key_code; 1171706f2543Smrg *maxCode = inputInfo.keyboard->key->xkbInfo->desc->max_key_code; 1172706f2543Smrg } 1173706f2543Smrg} 1174706f2543Smrg 1175706f2543Smrg/* Notably, this function does not expand the destination's keycode range, or 1176706f2543Smrg * notify clients. */ 1177706f2543SmrgBool 1178706f2543SmrgSetKeySymsMap(KeySymsPtr dst, KeySymsPtr src) 1179706f2543Smrg{ 1180706f2543Smrg int i, j; 1181706f2543Smrg KeySym *tmp; 1182706f2543Smrg int rowDif = src->minKeyCode - dst->minKeyCode; 1183706f2543Smrg 1184706f2543Smrg /* if keysym map size changes, grow map first */ 1185706f2543Smrg if (src->mapWidth < dst->mapWidth) { 1186706f2543Smrg for (i = src->minKeyCode; i <= src->maxKeyCode; i++) { 1187706f2543Smrg#define SI(r, c) (((r - src->minKeyCode) * src->mapWidth) + (c)) 1188706f2543Smrg#define DI(r, c) (((r - dst->minKeyCode) * dst->mapWidth) + (c)) 1189706f2543Smrg for (j = 0; j < src->mapWidth; j++) 1190706f2543Smrg dst->map[DI(i, j)] = src->map[SI(i, j)]; 1191706f2543Smrg for (j = src->mapWidth; j < dst->mapWidth; j++) 1192706f2543Smrg dst->map[DI(i, j)] = NoSymbol; 1193706f2543Smrg#undef SI 1194706f2543Smrg#undef DI 1195706f2543Smrg } 1196706f2543Smrg return TRUE; 1197706f2543Smrg } 1198706f2543Smrg else if (src->mapWidth > dst->mapWidth) { 1199706f2543Smrg i = sizeof(KeySym) * src->mapWidth * 1200706f2543Smrg (dst->maxKeyCode - dst->minKeyCode + 1); 1201706f2543Smrg tmp = calloc(sizeof(KeySym), i); 1202706f2543Smrg if (!tmp) 1203706f2543Smrg return FALSE; 1204706f2543Smrg 1205706f2543Smrg if (dst->map) { 1206706f2543Smrg for (i = 0; i <= dst->maxKeyCode-dst->minKeyCode; i++) 1207706f2543Smrg memmove(&tmp[i * src->mapWidth], &dst->map[i * dst->mapWidth], 1208706f2543Smrg dst->mapWidth * sizeof(KeySym)); 1209706f2543Smrg free(dst->map); 1210706f2543Smrg } 1211706f2543Smrg dst->mapWidth = src->mapWidth; 1212706f2543Smrg dst->map = tmp; 1213706f2543Smrg } 1214706f2543Smrg else if (!dst->map) { 1215706f2543Smrg i = sizeof(KeySym) * src->mapWidth * 1216706f2543Smrg (dst->maxKeyCode - dst->minKeyCode + 1); 1217706f2543Smrg tmp = calloc(sizeof(KeySym), i); 1218706f2543Smrg if (!tmp) 1219706f2543Smrg return FALSE; 1220706f2543Smrg 1221706f2543Smrg dst->map = tmp; 1222706f2543Smrg dst->mapWidth = src->mapWidth; 1223706f2543Smrg } 1224706f2543Smrg 1225706f2543Smrg memmove(&dst->map[rowDif * dst->mapWidth], src->map, 1226706f2543Smrg (src->maxKeyCode - src->minKeyCode + 1) * 1227706f2543Smrg dst->mapWidth * sizeof(KeySym)); 1228706f2543Smrg 1229706f2543Smrg return TRUE; 1230706f2543Smrg} 1231706f2543Smrg 1232706f2543SmrgBool 1233706f2543SmrgInitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons, Atom* labels, 1234706f2543Smrg CARD8 *map) 1235706f2543Smrg{ 1236706f2543Smrg ButtonClassPtr butc; 1237706f2543Smrg int i; 1238706f2543Smrg 1239706f2543Smrg butc = calloc(1, sizeof(ButtonClassRec)); 1240706f2543Smrg if (!butc) 1241706f2543Smrg return FALSE; 1242706f2543Smrg butc->numButtons = numButtons; 1243706f2543Smrg butc->sourceid = dev->id; 1244706f2543Smrg for (i = 1; i <= numButtons; i++) 1245706f2543Smrg butc->map[i] = map[i]; 1246706f2543Smrg for (i = numButtons + 1; i < MAP_LENGTH; i++) 1247706f2543Smrg butc->map[i] = i; 1248706f2543Smrg memcpy(butc->labels, labels, numButtons * sizeof(Atom)); 1249706f2543Smrg dev->button = butc; 1250706f2543Smrg return TRUE; 1251706f2543Smrg} 1252706f2543Smrg 1253706f2543Smrg/** 1254706f2543Smrg * Allocate a valuator class and set up the pointers for the axis values 1255706f2543Smrg * appropriately. 1256706f2543Smrg * 1257706f2543Smrg * @param src If non-NULL, the memory is reallocated from src. If NULL, the 1258706f2543Smrg * memory is calloc'd. 1259706f2543Smrg * @parma numAxes Number of axes to allocate. 1260706f2543Smrg * @return The allocated valuator struct. 1261706f2543Smrg */ 1262706f2543SmrgValuatorClassPtr 1263706f2543SmrgAllocValuatorClass(ValuatorClassPtr src, int numAxes) 1264706f2543Smrg{ 1265706f2543Smrg ValuatorClassPtr v; 1266706f2543Smrg /* force alignment with double */ 1267706f2543Smrg union align_u { ValuatorClassRec valc; double d; } *align; 1268706f2543Smrg int size; 1269706f2543Smrg 1270706f2543Smrg size = sizeof(union align_u) + numAxes * (sizeof(double) + sizeof(AxisInfo)); 1271706f2543Smrg align = (union align_u *) realloc(src, size); 1272706f2543Smrg 1273706f2543Smrg if (!align) 1274706f2543Smrg return NULL; 1275706f2543Smrg 1276706f2543Smrg if (!src) 1277706f2543Smrg memset(align, 0, size); 1278706f2543Smrg 1279706f2543Smrg v = &align->valc; 1280706f2543Smrg v->numAxes = numAxes; 1281706f2543Smrg v->axisVal = (double*)(align + 1); 1282706f2543Smrg v->axes = (AxisInfoPtr)(v->axisVal + numAxes); 1283706f2543Smrg 1284706f2543Smrg return v; 1285706f2543Smrg} 1286706f2543Smrg 1287706f2543SmrgBool 1288706f2543SmrgInitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels, 1289706f2543Smrg int numMotionEvents, int mode) 1290706f2543Smrg{ 1291706f2543Smrg int i; 1292706f2543Smrg ValuatorClassPtr valc; 1293706f2543Smrg 1294706f2543Smrg if (!dev) 1295706f2543Smrg return FALSE; 1296706f2543Smrg 1297706f2543Smrg if (numAxes > MAX_VALUATORS) 1298706f2543Smrg { 1299706f2543Smrg LogMessage(X_WARNING, 1300706f2543Smrg "Device '%s' has %d axes, only using first %d.\n", 1301706f2543Smrg dev->name, numAxes, MAX_VALUATORS); 1302706f2543Smrg numAxes = MAX_VALUATORS; 1303706f2543Smrg } 1304706f2543Smrg 1305706f2543Smrg valc = AllocValuatorClass(NULL, numAxes); 1306706f2543Smrg if (!valc) 1307706f2543Smrg return FALSE; 1308706f2543Smrg 1309706f2543Smrg valc->sourceid = dev->id; 1310706f2543Smrg valc->motion = NULL; 1311706f2543Smrg valc->first_motion = 0; 1312706f2543Smrg valc->last_motion = 0; 1313706f2543Smrg 1314706f2543Smrg valc->numMotionEvents = numMotionEvents; 1315706f2543Smrg valc->motionHintWindow = NullWindow; 1316706f2543Smrg 1317706f2543Smrg if (mode & OutOfProximity) 1318706f2543Smrg InitProximityClassDeviceStruct(dev); 1319706f2543Smrg 1320706f2543Smrg dev->valuator = valc; 1321706f2543Smrg 1322706f2543Smrg AllocateMotionHistory(dev); 1323706f2543Smrg 1324706f2543Smrg for (i=0; i<numAxes; i++) { 1325706f2543Smrg InitValuatorAxisStruct(dev, i, labels[i], NO_AXIS_LIMITS, NO_AXIS_LIMITS, 1326706f2543Smrg 0, 0, 0, mode); 1327706f2543Smrg valc->axisVal[i]=0; 1328706f2543Smrg } 1329706f2543Smrg 1330706f2543Smrg dev->last.numValuators = numAxes; 1331706f2543Smrg 1332706f2543Smrg if (IsMaster(dev) || /* do not accelerate master or xtest devices */ 1333706f2543Smrg IsXTestDevice(dev, NULL)) 1334706f2543Smrg InitPointerAccelerationScheme(dev, PtrAccelNoOp); 1335706f2543Smrg else 1336706f2543Smrg InitPointerAccelerationScheme(dev, PtrAccelDefault); 1337706f2543Smrg return TRUE; 1338706f2543Smrg} 1339706f2543Smrg 1340706f2543Smrg/* global list of acceleration schemes */ 1341706f2543SmrgValuatorAccelerationRec pointerAccelerationScheme[] = { 1342706f2543Smrg {PtrAccelNoOp, NULL, NULL, NULL}, 1343706f2543Smrg {PtrAccelPredictable, acceleratePointerPredictable, NULL, AccelerationDefaultCleanup}, 1344706f2543Smrg {PtrAccelLightweight, acceleratePointerLightweight, NULL, NULL}, 1345706f2543Smrg {-1, NULL, NULL, NULL} /* terminator */ 1346706f2543Smrg}; 1347706f2543Smrg 1348706f2543Smrg/** 1349706f2543Smrg * install an acceleration scheme. returns TRUE on success, and should not 1350706f2543Smrg * change anything if unsuccessful. 1351706f2543Smrg */ 1352706f2543SmrgBool 1353706f2543SmrgInitPointerAccelerationScheme(DeviceIntPtr dev, 1354706f2543Smrg int scheme) 1355706f2543Smrg{ 1356706f2543Smrg int x, i = -1; 1357706f2543Smrg void* data = NULL; 1358706f2543Smrg ValuatorClassPtr val; 1359706f2543Smrg 1360706f2543Smrg val = dev->valuator; 1361706f2543Smrg 1362706f2543Smrg if(!val) 1363706f2543Smrg return FALSE; 1364706f2543Smrg 1365706f2543Smrg if(IsMaster(dev) && scheme != PtrAccelNoOp) 1366706f2543Smrg return FALSE; 1367706f2543Smrg 1368706f2543Smrg for(x = 0; pointerAccelerationScheme[x].number >= 0; x++) { 1369706f2543Smrg if(pointerAccelerationScheme[x].number == scheme){ 1370706f2543Smrg i = x; 1371706f2543Smrg break; 1372706f2543Smrg } 1373706f2543Smrg } 1374706f2543Smrg 1375706f2543Smrg if(-1 == i) 1376706f2543Smrg return FALSE; 1377706f2543Smrg 1378706f2543Smrg if (val->accelScheme.AccelCleanupProc) 1379706f2543Smrg val->accelScheme.AccelCleanupProc(dev); 1380706f2543Smrg 1381706f2543Smrg /* init scheme-specific data */ 1382706f2543Smrg switch(scheme){ 1383706f2543Smrg case PtrAccelPredictable: 1384706f2543Smrg { 1385706f2543Smrg DeviceVelocityPtr s; 1386706f2543Smrg s = malloc(sizeof(DeviceVelocityRec)); 1387706f2543Smrg if(!s) 1388706f2543Smrg return FALSE; 1389706f2543Smrg InitVelocityData(s); 1390706f2543Smrg data = s; 1391706f2543Smrg break; 1392706f2543Smrg } 1393706f2543Smrg default: 1394706f2543Smrg break; 1395706f2543Smrg } 1396706f2543Smrg 1397706f2543Smrg val->accelScheme = pointerAccelerationScheme[i]; 1398706f2543Smrg val->accelScheme.accelData = data; 1399706f2543Smrg 1400706f2543Smrg /* post-init scheme */ 1401706f2543Smrg switch(scheme){ 1402706f2543Smrg case PtrAccelPredictable: 1403706f2543Smrg InitializePredictableAccelerationProperties(dev); 1404706f2543Smrg break; 1405706f2543Smrg 1406706f2543Smrg default: 1407706f2543Smrg break; 1408706f2543Smrg } 1409706f2543Smrg 1410706f2543Smrg return TRUE; 1411706f2543Smrg} 1412706f2543Smrg 1413706f2543SmrgBool 1414706f2543SmrgInitAbsoluteClassDeviceStruct(DeviceIntPtr dev) 1415706f2543Smrg{ 1416706f2543Smrg AbsoluteClassPtr abs; 1417706f2543Smrg 1418706f2543Smrg abs = malloc(sizeof(AbsoluteClassRec)); 1419706f2543Smrg if (!abs) 1420706f2543Smrg return FALSE; 1421706f2543Smrg 1422706f2543Smrg /* we don't do anything sensible with these, but should */ 1423706f2543Smrg abs->min_x = NO_AXIS_LIMITS; 1424706f2543Smrg abs->min_y = NO_AXIS_LIMITS; 1425706f2543Smrg abs->max_x = NO_AXIS_LIMITS; 1426706f2543Smrg abs->max_y = NO_AXIS_LIMITS; 1427706f2543Smrg abs->flip_x = 0; 1428706f2543Smrg abs->flip_y = 0; 1429706f2543Smrg abs->rotation = 0; 1430706f2543Smrg abs->button_threshold = 0; 1431706f2543Smrg 1432706f2543Smrg abs->offset_x = 0; 1433706f2543Smrg abs->offset_y = 0; 1434706f2543Smrg abs->width = NO_AXIS_LIMITS; 1435706f2543Smrg abs->height = NO_AXIS_LIMITS; 1436706f2543Smrg abs->following = 0; 1437706f2543Smrg abs->screen = 0; 1438706f2543Smrg 1439706f2543Smrg abs->sourceid = dev->id; 1440706f2543Smrg 1441706f2543Smrg dev->absolute = abs; 1442706f2543Smrg 1443706f2543Smrg return TRUE; 1444706f2543Smrg} 1445706f2543Smrg 1446706f2543SmrgBool 1447706f2543SmrgInitFocusClassDeviceStruct(DeviceIntPtr dev) 1448706f2543Smrg{ 1449706f2543Smrg FocusClassPtr focc; 1450706f2543Smrg 1451706f2543Smrg focc = malloc(sizeof(FocusClassRec)); 1452706f2543Smrg if (!focc) 1453706f2543Smrg return FALSE; 1454706f2543Smrg focc->win = PointerRootWin; 1455706f2543Smrg focc->revert = None; 1456706f2543Smrg focc->time = currentTime; 1457706f2543Smrg focc->trace = (WindowPtr *)NULL; 1458706f2543Smrg focc->traceSize = 0; 1459706f2543Smrg focc->traceGood = 0; 1460706f2543Smrg focc->sourceid = dev->id; 1461706f2543Smrg dev->focus = focc; 1462706f2543Smrg return TRUE; 1463706f2543Smrg} 1464706f2543Smrg 1465706f2543SmrgBool 1466706f2543SmrgInitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev, PtrCtrlProcPtr controlProc) 1467706f2543Smrg{ 1468706f2543Smrg PtrFeedbackPtr feedc; 1469706f2543Smrg 1470706f2543Smrg feedc = malloc(sizeof(PtrFeedbackClassRec)); 1471706f2543Smrg if (!feedc) 1472706f2543Smrg return FALSE; 1473706f2543Smrg feedc->CtrlProc = controlProc; 1474706f2543Smrg feedc->ctrl = defaultPointerControl; 1475706f2543Smrg feedc->ctrl.id = 0; 1476706f2543Smrg if ( (feedc->next = dev->ptrfeed) ) 1477706f2543Smrg feedc->ctrl.id = dev->ptrfeed->ctrl.id + 1; 1478706f2543Smrg dev->ptrfeed = feedc; 1479706f2543Smrg (*controlProc)(dev, &feedc->ctrl); 1480706f2543Smrg return TRUE; 1481706f2543Smrg} 1482706f2543Smrg 1483706f2543Smrg 1484706f2543Smrgstatic LedCtrl defaultLedControl = { 1485706f2543Smrg DEFAULT_LEDS, DEFAULT_LEDS_MASK, 0}; 1486706f2543Smrg 1487706f2543Smrgstatic BellCtrl defaultBellControl = { 1488706f2543Smrg DEFAULT_BELL, 1489706f2543Smrg DEFAULT_BELL_PITCH, 1490706f2543Smrg DEFAULT_BELL_DURATION, 1491706f2543Smrg 0}; 1492706f2543Smrg 1493706f2543Smrgstatic IntegerCtrl defaultIntegerControl = { 1494706f2543Smrg DEFAULT_INT_RESOLUTION, 1495706f2543Smrg DEFAULT_INT_MIN_VALUE, 1496706f2543Smrg DEFAULT_INT_MAX_VALUE, 1497706f2543Smrg DEFAULT_INT_DISPLAYED, 1498706f2543Smrg 0}; 1499706f2543Smrg 1500706f2543SmrgBool 1501706f2543SmrgInitStringFeedbackClassDeviceStruct ( 1502706f2543Smrg DeviceIntPtr dev, StringCtrlProcPtr controlProc, 1503706f2543Smrg int max_symbols, int num_symbols_supported, KeySym *symbols) 1504706f2543Smrg{ 1505706f2543Smrg int i; 1506706f2543Smrg StringFeedbackPtr feedc; 1507706f2543Smrg 1508706f2543Smrg feedc = malloc(sizeof(StringFeedbackClassRec)); 1509706f2543Smrg if (!feedc) 1510706f2543Smrg return FALSE; 1511706f2543Smrg feedc->CtrlProc = controlProc; 1512706f2543Smrg feedc->ctrl.num_symbols_supported = num_symbols_supported; 1513706f2543Smrg feedc->ctrl.num_symbols_displayed = 0; 1514706f2543Smrg feedc->ctrl.max_symbols = max_symbols; 1515706f2543Smrg feedc->ctrl.symbols_supported = malloc(sizeof (KeySym) * num_symbols_supported); 1516706f2543Smrg feedc->ctrl.symbols_displayed = malloc(sizeof (KeySym) * max_symbols); 1517706f2543Smrg if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed) 1518706f2543Smrg { 1519706f2543Smrg free(feedc->ctrl.symbols_supported); 1520706f2543Smrg free(feedc->ctrl.symbols_displayed); 1521706f2543Smrg free(feedc); 1522706f2543Smrg return FALSE; 1523706f2543Smrg } 1524706f2543Smrg for (i=0; i<num_symbols_supported; i++) 1525706f2543Smrg *(feedc->ctrl.symbols_supported+i) = *symbols++; 1526706f2543Smrg for (i=0; i<max_symbols; i++) 1527706f2543Smrg *(feedc->ctrl.symbols_displayed+i) = (KeySym) 0; 1528706f2543Smrg feedc->ctrl.id = 0; 1529706f2543Smrg if ( (feedc->next = dev->stringfeed) ) 1530706f2543Smrg feedc->ctrl.id = dev->stringfeed->ctrl.id + 1; 1531706f2543Smrg dev->stringfeed = feedc; 1532706f2543Smrg (*controlProc)(dev, &feedc->ctrl); 1533706f2543Smrg return TRUE; 1534706f2543Smrg} 1535706f2543Smrg 1536706f2543SmrgBool 1537706f2543SmrgInitBellFeedbackClassDeviceStruct (DeviceIntPtr dev, BellProcPtr bellProc, 1538706f2543Smrg BellCtrlProcPtr controlProc) 1539706f2543Smrg{ 1540706f2543Smrg BellFeedbackPtr feedc; 1541706f2543Smrg 1542706f2543Smrg feedc = malloc(sizeof(BellFeedbackClassRec)); 1543706f2543Smrg if (!feedc) 1544706f2543Smrg return FALSE; 1545706f2543Smrg feedc->CtrlProc = controlProc; 1546706f2543Smrg feedc->BellProc = bellProc; 1547706f2543Smrg feedc->ctrl = defaultBellControl; 1548706f2543Smrg feedc->ctrl.id = 0; 1549706f2543Smrg if ( (feedc->next = dev->bell) ) 1550706f2543Smrg feedc->ctrl.id = dev->bell->ctrl.id + 1; 1551706f2543Smrg dev->bell = feedc; 1552706f2543Smrg (*controlProc)(dev, &feedc->ctrl); 1553706f2543Smrg return TRUE; 1554706f2543Smrg} 1555706f2543Smrg 1556706f2543SmrgBool 1557706f2543SmrgInitLedFeedbackClassDeviceStruct (DeviceIntPtr dev, LedCtrlProcPtr controlProc) 1558706f2543Smrg{ 1559706f2543Smrg LedFeedbackPtr feedc; 1560706f2543Smrg 1561706f2543Smrg feedc = malloc(sizeof(LedFeedbackClassRec)); 1562706f2543Smrg if (!feedc) 1563706f2543Smrg return FALSE; 1564706f2543Smrg feedc->CtrlProc = controlProc; 1565706f2543Smrg feedc->ctrl = defaultLedControl; 1566706f2543Smrg feedc->ctrl.id = 0; 1567706f2543Smrg if ( (feedc->next = dev->leds) ) 1568706f2543Smrg feedc->ctrl.id = dev->leds->ctrl.id + 1; 1569706f2543Smrg feedc->xkb_sli= NULL; 1570706f2543Smrg dev->leds = feedc; 1571706f2543Smrg (*controlProc)(dev, &feedc->ctrl); 1572706f2543Smrg return TRUE; 1573706f2543Smrg} 1574706f2543Smrg 1575706f2543SmrgBool 1576706f2543SmrgInitIntegerFeedbackClassDeviceStruct (DeviceIntPtr dev, IntegerCtrlProcPtr controlProc) 1577706f2543Smrg{ 1578706f2543Smrg IntegerFeedbackPtr feedc; 1579706f2543Smrg 1580706f2543Smrg feedc = malloc(sizeof(IntegerFeedbackClassRec)); 1581706f2543Smrg if (!feedc) 1582706f2543Smrg return FALSE; 1583706f2543Smrg feedc->CtrlProc = controlProc; 1584706f2543Smrg feedc->ctrl = defaultIntegerControl; 1585706f2543Smrg feedc->ctrl.id = 0; 1586706f2543Smrg if ( (feedc->next = dev->intfeed) ) 1587706f2543Smrg feedc->ctrl.id = dev->intfeed->ctrl.id + 1; 1588706f2543Smrg dev->intfeed = feedc; 1589706f2543Smrg (*controlProc)(dev, &feedc->ctrl); 1590706f2543Smrg return TRUE; 1591706f2543Smrg} 1592706f2543Smrg 1593706f2543SmrgBool 1594706f2543SmrgInitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons, Atom* btn_labels, 1595706f2543Smrg PtrCtrlProcPtr controlProc, int numMotionEvents, 1596706f2543Smrg int numAxes, Atom *axes_labels) 1597706f2543Smrg{ 1598706f2543Smrg DeviceIntPtr dev = (DeviceIntPtr)device; 1599706f2543Smrg 1600706f2543Smrg return(InitButtonClassDeviceStruct(dev, numButtons, btn_labels, map) && 1601706f2543Smrg InitValuatorClassDeviceStruct(dev, numAxes, axes_labels, 1602706f2543Smrg numMotionEvents, Relative) && 1603706f2543Smrg InitPtrFeedbackClassDeviceStruct(dev, controlProc)); 1604706f2543Smrg} 1605706f2543Smrg 1606706f2543Smrg/* 1607706f2543Smrg * Check if the given buffer contains elements between low (inclusive) and 1608706f2543Smrg * high (inclusive) only. 1609706f2543Smrg * 1610706f2543Smrg * @return TRUE if the device map is invalid, FALSE otherwise. 1611706f2543Smrg */ 1612706f2543SmrgBool 1613706f2543SmrgBadDeviceMap(BYTE *buff, int length, unsigned low, unsigned high, XID *errval) 1614706f2543Smrg{ 1615706f2543Smrg int i; 1616706f2543Smrg 1617706f2543Smrg for (i = 0; i < length; i++) 1618706f2543Smrg if (buff[i]) /* only check non-zero elements */ 1619706f2543Smrg { 1620706f2543Smrg if ((low > buff[i]) || (high < buff[i])) 1621706f2543Smrg { 1622706f2543Smrg *errval = buff[i]; 1623706f2543Smrg return TRUE; 1624706f2543Smrg } 1625706f2543Smrg } 1626706f2543Smrg return FALSE; 1627706f2543Smrg} 1628706f2543Smrg 1629706f2543Smrgint 1630706f2543SmrgProcSetModifierMapping(ClientPtr client) 1631706f2543Smrg{ 1632706f2543Smrg xSetModifierMappingReply rep; 1633706f2543Smrg int rc; 1634706f2543Smrg REQUEST(xSetModifierMappingReq); 1635706f2543Smrg REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq); 1636706f2543Smrg 1637706f2543Smrg if (client->req_len != ((stuff->numKeyPerModifier << 1) + 1638706f2543Smrg bytes_to_int32(sizeof(xSetModifierMappingReq)))) 1639706f2543Smrg return BadLength; 1640706f2543Smrg 1641706f2543Smrg rep.type = X_Reply; 1642706f2543Smrg rep.length = 0; 1643706f2543Smrg rep.sequenceNumber = client->sequence; 1644706f2543Smrg 1645706f2543Smrg rc = change_modmap(client, PickKeyboard(client), (KeyCode *)&stuff[1], 1646706f2543Smrg stuff->numKeyPerModifier); 1647706f2543Smrg if (rc == MappingFailed || rc == -1) 1648706f2543Smrg return BadValue; 1649706f2543Smrg if (rc != Success && rc != MappingSuccess && rc != MappingFailed && 1650706f2543Smrg rc != MappingBusy) 1651706f2543Smrg return rc; 1652706f2543Smrg 1653706f2543Smrg rep.success = rc; 1654706f2543Smrg 1655706f2543Smrg WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep); 1656706f2543Smrg return Success; 1657706f2543Smrg} 1658706f2543Smrg 1659706f2543Smrgint 1660706f2543SmrgProcGetModifierMapping(ClientPtr client) 1661706f2543Smrg{ 1662706f2543Smrg xGetModifierMappingReply rep; 1663706f2543Smrg int max_keys_per_mod = 0; 1664706f2543Smrg KeyCode *modkeymap = NULL; 1665706f2543Smrg REQUEST_SIZE_MATCH(xReq); 1666706f2543Smrg 1667706f2543Smrg generate_modkeymap(client, PickKeyboard(client), &modkeymap, 1668706f2543Smrg &max_keys_per_mod); 1669706f2543Smrg 1670706f2543Smrg memset(&rep, 0, sizeof(xGetModifierMappingReply)); 1671706f2543Smrg rep.type = X_Reply; 1672706f2543Smrg rep.numKeyPerModifier = max_keys_per_mod; 1673706f2543Smrg rep.sequenceNumber = client->sequence; 1674706f2543Smrg /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */ 1675706f2543Smrg rep.length = max_keys_per_mod << 1; 1676706f2543Smrg 1677706f2543Smrg WriteReplyToClient(client, sizeof(xGetModifierMappingReply), &rep); 1678706f2543Smrg (void)WriteToClient(client, max_keys_per_mod * 8, (char *) modkeymap); 1679706f2543Smrg 1680706f2543Smrg free(modkeymap); 1681706f2543Smrg 1682706f2543Smrg return Success; 1683706f2543Smrg} 1684706f2543Smrg 1685706f2543Smrgint 1686706f2543SmrgProcChangeKeyboardMapping(ClientPtr client) 1687706f2543Smrg{ 1688706f2543Smrg REQUEST(xChangeKeyboardMappingReq); 1689706f2543Smrg unsigned len; 1690706f2543Smrg KeySymsRec keysyms; 1691706f2543Smrg DeviceIntPtr pDev, tmp; 1692706f2543Smrg int rc; 1693706f2543Smrg REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq); 1694706f2543Smrg 1695706f2543Smrg len = client->req_len - bytes_to_int32(sizeof(xChangeKeyboardMappingReq)); 1696706f2543Smrg if (len != (stuff->keyCodes * stuff->keySymsPerKeyCode)) 1697706f2543Smrg return BadLength; 1698706f2543Smrg 1699706f2543Smrg pDev = PickKeyboard(client); 1700706f2543Smrg 1701706f2543Smrg if ((stuff->firstKeyCode < pDev->key->xkbInfo->desc->min_key_code) || 1702706f2543Smrg (stuff->firstKeyCode > pDev->key->xkbInfo->desc->max_key_code)) { 1703706f2543Smrg client->errorValue = stuff->firstKeyCode; 1704706f2543Smrg return BadValue; 1705706f2543Smrg 1706706f2543Smrg } 1707706f2543Smrg if (((unsigned)(stuff->firstKeyCode + stuff->keyCodes - 1) > 1708706f2543Smrg pDev->key->xkbInfo->desc->max_key_code) || 1709706f2543Smrg (stuff->keySymsPerKeyCode == 0)) { 1710706f2543Smrg client->errorValue = stuff->keySymsPerKeyCode; 1711706f2543Smrg return BadValue; 1712706f2543Smrg } 1713706f2543Smrg 1714706f2543Smrg keysyms.minKeyCode = stuff->firstKeyCode; 1715706f2543Smrg keysyms.maxKeyCode = stuff->firstKeyCode + stuff->keyCodes - 1; 1716706f2543Smrg keysyms.mapWidth = stuff->keySymsPerKeyCode; 1717706f2543Smrg keysyms.map = (KeySym *) &stuff[1]; 1718706f2543Smrg 1719706f2543Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); 1720706f2543Smrg if (rc != Success) 1721706f2543Smrg return rc; 1722706f2543Smrg 1723706f2543Smrg XkbApplyMappingChange(pDev, &keysyms, stuff->firstKeyCode, 1724706f2543Smrg stuff->keyCodes, NULL, client); 1725706f2543Smrg 1726706f2543Smrg for (tmp = inputInfo.devices; tmp; tmp = tmp->next) { 1727706f2543Smrg if (IsMaster(tmp) || tmp->u.master != pDev) 1728706f2543Smrg continue; 1729706f2543Smrg if (!tmp->key) 1730706f2543Smrg continue; 1731706f2543Smrg 1732706f2543Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); 1733706f2543Smrg if (rc != Success) 1734706f2543Smrg continue; 1735706f2543Smrg 1736706f2543Smrg XkbApplyMappingChange(tmp, &keysyms, stuff->firstKeyCode, 1737706f2543Smrg stuff->keyCodes, NULL, client); 1738706f2543Smrg } 1739706f2543Smrg 1740706f2543Smrg return Success; 1741706f2543Smrg} 1742706f2543Smrg 1743706f2543Smrgint 1744706f2543SmrgProcSetPointerMapping(ClientPtr client) 1745706f2543Smrg{ 1746706f2543Smrg BYTE *map; 1747706f2543Smrg int ret; 1748706f2543Smrg int i, j; 1749706f2543Smrg DeviceIntPtr ptr = PickPointer(client); 1750706f2543Smrg xSetPointerMappingReply rep; 1751706f2543Smrg REQUEST(xSetPointerMappingReq); 1752706f2543Smrg REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq); 1753706f2543Smrg 1754706f2543Smrg if (client->req_len != 1755706f2543Smrg bytes_to_int32(sizeof(xSetPointerMappingReq) + stuff->nElts)) 1756706f2543Smrg return BadLength; 1757706f2543Smrg rep.type = X_Reply; 1758706f2543Smrg rep.length = 0; 1759706f2543Smrg rep.sequenceNumber = client->sequence; 1760706f2543Smrg rep.success = MappingSuccess; 1761706f2543Smrg map = (BYTE *)&stuff[1]; 1762706f2543Smrg 1763706f2543Smrg /* So we're bounded here by the number of core buttons. This check 1764706f2543Smrg * probably wants disabling through XFixes. */ 1765706f2543Smrg /* MPX: With ClientPointer, we can return the right number of buttons. 1766706f2543Smrg * Let's just hope nobody changed ClientPointer between GetPointerMapping 1767706f2543Smrg * and SetPointerMapping 1768706f2543Smrg */ 1769706f2543Smrg if (stuff->nElts != ptr->button->numButtons) { 1770706f2543Smrg client->errorValue = stuff->nElts; 1771706f2543Smrg return BadValue; 1772706f2543Smrg } 1773706f2543Smrg 1774706f2543Smrg /* Core protocol specs don't allow for duplicate mappings; this check 1775706f2543Smrg * almost certainly wants disabling through XFixes too. */ 1776706f2543Smrg for (i = 0; i < stuff->nElts; i++) { 1777706f2543Smrg for (j = i + 1; j < stuff->nElts; j++) { 1778706f2543Smrg if (map[i] && map[i] == map[j]) { 1779706f2543Smrg client->errorValue = map[i]; 1780706f2543Smrg return BadValue; 1781706f2543Smrg } 1782706f2543Smrg } 1783706f2543Smrg } 1784706f2543Smrg 1785706f2543Smrg ret = ApplyPointerMapping(ptr, map, stuff->nElts, client); 1786706f2543Smrg if (ret == MappingBusy) 1787706f2543Smrg rep.success = ret; 1788706f2543Smrg else if (ret == -1) 1789706f2543Smrg return BadValue; 1790706f2543Smrg else if (ret != Success) 1791706f2543Smrg return ret; 1792706f2543Smrg 1793706f2543Smrg WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep); 1794706f2543Smrg return Success; 1795706f2543Smrg} 1796706f2543Smrg 1797706f2543Smrgint 1798706f2543SmrgProcGetKeyboardMapping(ClientPtr client) 1799706f2543Smrg{ 1800706f2543Smrg xGetKeyboardMappingReply rep; 1801706f2543Smrg DeviceIntPtr kbd = PickKeyboard(client); 1802706f2543Smrg XkbDescPtr xkb; 1803706f2543Smrg KeySymsPtr syms; 1804706f2543Smrg int rc; 1805706f2543Smrg REQUEST(xGetKeyboardMappingReq); 1806706f2543Smrg REQUEST_SIZE_MATCH(xGetKeyboardMappingReq); 1807706f2543Smrg 1808706f2543Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess); 1809706f2543Smrg if (rc != Success) 1810706f2543Smrg return rc; 1811706f2543Smrg 1812706f2543Smrg xkb = kbd->key->xkbInfo->desc; 1813706f2543Smrg 1814706f2543Smrg if ((stuff->firstKeyCode < xkb->min_key_code) || 1815706f2543Smrg (stuff->firstKeyCode > xkb->max_key_code)) { 1816706f2543Smrg client->errorValue = stuff->firstKeyCode; 1817706f2543Smrg return BadValue; 1818706f2543Smrg } 1819706f2543Smrg if (stuff->firstKeyCode + stuff->count > xkb->max_key_code + 1) { 1820706f2543Smrg client->errorValue = stuff->count; 1821706f2543Smrg return BadValue; 1822706f2543Smrg } 1823706f2543Smrg 1824706f2543Smrg syms = XkbGetCoreMap(kbd); 1825706f2543Smrg if (!syms) 1826706f2543Smrg return BadAlloc; 1827706f2543Smrg 1828706f2543Smrg memset(&rep, 0, sizeof(xGetKeyboardMappingReply)); 1829706f2543Smrg rep.type = X_Reply; 1830706f2543Smrg rep.sequenceNumber = client->sequence; 1831706f2543Smrg rep.keySymsPerKeyCode = syms->mapWidth; 1832706f2543Smrg /* length is a count of 4 byte quantities and KeySyms are 4 bytes */ 1833706f2543Smrg rep.length = syms->mapWidth * stuff->count; 1834706f2543Smrg WriteReplyToClient(client, sizeof(xGetKeyboardMappingReply), &rep); 1835706f2543Smrg client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write; 1836706f2543Smrg WriteSwappedDataToClient(client, 1837706f2543Smrg syms->mapWidth * stuff->count * sizeof(KeySym), 1838706f2543Smrg &syms->map[syms->mapWidth * (stuff->firstKeyCode - 1839706f2543Smrg syms->minKeyCode)]); 1840706f2543Smrg free(syms->map); 1841706f2543Smrg free(syms); 1842706f2543Smrg 1843706f2543Smrg return Success; 1844706f2543Smrg} 1845706f2543Smrg 1846706f2543Smrgint 1847706f2543SmrgProcGetPointerMapping(ClientPtr client) 1848706f2543Smrg{ 1849706f2543Smrg xGetPointerMappingReply rep; 1850706f2543Smrg /* Apps may get different values each time they call GetPointerMapping as 1851706f2543Smrg * the ClientPointer could change. */ 1852706f2543Smrg DeviceIntPtr ptr = PickPointer(client); 1853706f2543Smrg ButtonClassPtr butc = ptr->button; 1854706f2543Smrg int rc; 1855706f2543Smrg REQUEST_SIZE_MATCH(xReq); 1856706f2543Smrg 1857706f2543Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess); 1858706f2543Smrg if (rc != Success) 1859706f2543Smrg return rc; 1860706f2543Smrg 1861706f2543Smrg rep.type = X_Reply; 1862706f2543Smrg rep.sequenceNumber = client->sequence; 1863706f2543Smrg rep.nElts = (butc) ? butc->numButtons : 0; 1864706f2543Smrg rep.length = ((unsigned)rep.nElts + (4-1))/4; 1865706f2543Smrg WriteReplyToClient(client, sizeof(xGetPointerMappingReply), &rep); 1866706f2543Smrg if (butc) 1867706f2543Smrg WriteToClient(client, (int)rep.nElts, (char *)&butc->map[1]); 1868706f2543Smrg return Success; 1869706f2543Smrg} 1870706f2543Smrg 1871706f2543Smrgvoid 1872706f2543SmrgNoteLedState(DeviceIntPtr keybd, int led, Bool on) 1873706f2543Smrg{ 1874706f2543Smrg KeybdCtrl *ctrl = &keybd->kbdfeed->ctrl; 1875706f2543Smrg if (on) 1876706f2543Smrg ctrl->leds |= ((Leds)1 << (led - 1)); 1877706f2543Smrg else 1878706f2543Smrg ctrl->leds &= ~((Leds)1 << (led - 1)); 1879706f2543Smrg} 1880706f2543Smrg 1881706f2543Smrgint 1882706f2543SmrgOnes(unsigned long mask) /* HACKMEM 169 */ 1883706f2543Smrg{ 1884706f2543Smrg unsigned long y; 1885706f2543Smrg 1886706f2543Smrg y = (mask >> 1) &033333333333; 1887706f2543Smrg y = mask - y - ((y >>1) & 033333333333); 1888706f2543Smrg return (((y + (y >> 3)) & 030707070707) % 077); 1889706f2543Smrg} 1890706f2543Smrg 1891706f2543Smrgstatic int 1892706f2543SmrgDoChangeKeyboardControl (ClientPtr client, DeviceIntPtr keybd, XID *vlist, 1893706f2543Smrg BITS32 vmask) 1894706f2543Smrg{ 1895706f2543Smrg#define DO_ALL (-1) 1896706f2543Smrg KeybdCtrl ctrl; 1897706f2543Smrg int t; 1898706f2543Smrg int led = DO_ALL; 1899706f2543Smrg int key = DO_ALL; 1900706f2543Smrg BITS32 index2; 1901706f2543Smrg int mask = vmask, i; 1902706f2543Smrg XkbEventCauseRec cause; 1903706f2543Smrg 1904706f2543Smrg ctrl = keybd->kbdfeed->ctrl; 1905706f2543Smrg while (vmask) { 1906706f2543Smrg index2 = (BITS32) lowbit (vmask); 1907706f2543Smrg vmask &= ~index2; 1908706f2543Smrg switch (index2) { 1909706f2543Smrg case KBKeyClickPercent: 1910706f2543Smrg t = (INT8)*vlist; 1911706f2543Smrg vlist++; 1912706f2543Smrg if (t == -1) { 1913706f2543Smrg t = defaultKeyboardControl.click; 1914706f2543Smrg } 1915706f2543Smrg else if (t < 0 || t > 100) { 1916706f2543Smrg client->errorValue = t; 1917706f2543Smrg return BadValue; 1918706f2543Smrg } 1919706f2543Smrg ctrl.click = t; 1920706f2543Smrg break; 1921706f2543Smrg case KBBellPercent: 1922706f2543Smrg t = (INT8)*vlist; 1923706f2543Smrg vlist++; 1924706f2543Smrg if (t == -1) { 1925706f2543Smrg t = defaultKeyboardControl.bell; 1926706f2543Smrg } 1927706f2543Smrg else if (t < 0 || t > 100) { 1928706f2543Smrg client->errorValue = t; 1929706f2543Smrg return BadValue; 1930706f2543Smrg } 1931706f2543Smrg ctrl.bell = t; 1932706f2543Smrg break; 1933706f2543Smrg case KBBellPitch: 1934706f2543Smrg t = (INT16)*vlist; 1935706f2543Smrg vlist++; 1936706f2543Smrg if (t == -1) { 1937706f2543Smrg t = defaultKeyboardControl.bell_pitch; 1938706f2543Smrg } 1939706f2543Smrg else if (t < 0) { 1940706f2543Smrg client->errorValue = t; 1941706f2543Smrg return BadValue; 1942706f2543Smrg } 1943706f2543Smrg ctrl.bell_pitch = t; 1944706f2543Smrg break; 1945706f2543Smrg case KBBellDuration: 1946706f2543Smrg t = (INT16)*vlist; 1947706f2543Smrg vlist++; 1948706f2543Smrg if (t == -1) 1949706f2543Smrg t = defaultKeyboardControl.bell_duration; 1950706f2543Smrg else if (t < 0) { 1951706f2543Smrg client->errorValue = t; 1952706f2543Smrg return BadValue; 1953706f2543Smrg } 1954706f2543Smrg ctrl.bell_duration = t; 1955706f2543Smrg break; 1956706f2543Smrg case KBLed: 1957706f2543Smrg led = (CARD8)*vlist; 1958706f2543Smrg vlist++; 1959706f2543Smrg if (led < 1 || led > 32) { 1960706f2543Smrg client->errorValue = led; 1961706f2543Smrg return BadValue; 1962706f2543Smrg } 1963706f2543Smrg if (!(mask & KBLedMode)) 1964706f2543Smrg return BadMatch; 1965706f2543Smrg break; 1966706f2543Smrg case KBLedMode: 1967706f2543Smrg t = (CARD8)*vlist; 1968706f2543Smrg vlist++; 1969706f2543Smrg if (t == LedModeOff) { 1970706f2543Smrg if (led == DO_ALL) 1971706f2543Smrg ctrl.leds = 0x0; 1972706f2543Smrg else 1973706f2543Smrg ctrl.leds &= ~(((Leds)(1)) << (led - 1)); 1974706f2543Smrg } 1975706f2543Smrg else if (t == LedModeOn) { 1976706f2543Smrg if (led == DO_ALL) 1977706f2543Smrg ctrl.leds = ~0L; 1978706f2543Smrg else 1979706f2543Smrg ctrl.leds |= (((Leds)(1)) << (led - 1)); 1980706f2543Smrg } 1981706f2543Smrg else { 1982706f2543Smrg client->errorValue = t; 1983706f2543Smrg return BadValue; 1984706f2543Smrg } 1985706f2543Smrg 1986706f2543Smrg XkbSetCauseCoreReq(&cause,X_ChangeKeyboardControl,client); 1987706f2543Smrg XkbSetIndicators(keybd,((led == DO_ALL) ? ~0L : (1L<<(led-1))), 1988706f2543Smrg ctrl.leds, &cause); 1989706f2543Smrg ctrl.leds = keybd->kbdfeed->ctrl.leds; 1990706f2543Smrg 1991706f2543Smrg break; 1992706f2543Smrg case KBKey: 1993706f2543Smrg key = (KeyCode)*vlist; 1994706f2543Smrg vlist++; 1995706f2543Smrg if ((KeyCode)key < keybd->key->xkbInfo->desc->min_key_code || 1996706f2543Smrg (KeyCode)key > keybd->key->xkbInfo->desc->max_key_code) { 1997706f2543Smrg client->errorValue = key; 1998706f2543Smrg return BadValue; 1999706f2543Smrg } 2000706f2543Smrg if (!(mask & KBAutoRepeatMode)) 2001706f2543Smrg return BadMatch; 2002706f2543Smrg break; 2003706f2543Smrg case KBAutoRepeatMode: 2004706f2543Smrg i = (key >> 3); 2005706f2543Smrg mask = (1 << (key & 7)); 2006706f2543Smrg t = (CARD8)*vlist; 2007706f2543Smrg vlist++; 2008706f2543Smrg if (key != DO_ALL) 2009706f2543Smrg XkbDisableComputedAutoRepeats(keybd,key); 2010706f2543Smrg if (t == AutoRepeatModeOff) { 2011706f2543Smrg if (key == DO_ALL) 2012706f2543Smrg ctrl.autoRepeat = FALSE; 2013706f2543Smrg else 2014706f2543Smrg ctrl.autoRepeats[i] &= ~mask; 2015706f2543Smrg } 2016706f2543Smrg else if (t == AutoRepeatModeOn) { 2017706f2543Smrg if (key == DO_ALL) 2018706f2543Smrg ctrl.autoRepeat = TRUE; 2019706f2543Smrg else 2020706f2543Smrg ctrl.autoRepeats[i] |= mask; 2021706f2543Smrg } 2022706f2543Smrg else if (t == AutoRepeatModeDefault) { 2023706f2543Smrg if (key == DO_ALL) 2024706f2543Smrg ctrl.autoRepeat = defaultKeyboardControl.autoRepeat; 2025706f2543Smrg else 2026706f2543Smrg ctrl.autoRepeats[i] = 2027706f2543Smrg (ctrl.autoRepeats[i] & ~mask) | 2028706f2543Smrg (defaultKeyboardControl.autoRepeats[i] & mask); 2029706f2543Smrg } 2030706f2543Smrg else { 2031706f2543Smrg client->errorValue = t; 2032706f2543Smrg return BadValue; 2033706f2543Smrg } 2034706f2543Smrg break; 2035706f2543Smrg default: 2036706f2543Smrg client->errorValue = mask; 2037706f2543Smrg return BadValue; 2038706f2543Smrg } 2039706f2543Smrg } 2040706f2543Smrg keybd->kbdfeed->ctrl = ctrl; 2041706f2543Smrg 2042706f2543Smrg /* The XKB RepeatKeys control and core protocol global autorepeat */ 2043706f2543Smrg /* value are linked */ 2044706f2543Smrg XkbSetRepeatKeys(keybd, key, keybd->kbdfeed->ctrl.autoRepeat); 2045706f2543Smrg 2046706f2543Smrg return Success; 2047706f2543Smrg 2048706f2543Smrg#undef DO_ALL 2049706f2543Smrg} 2050706f2543Smrg 2051706f2543Smrg/** 2052706f2543Smrg * Changes kbd control on the ClientPointer and all attached SDs. 2053706f2543Smrg */ 2054706f2543Smrgint 2055706f2543SmrgProcChangeKeyboardControl (ClientPtr client) 2056706f2543Smrg{ 2057706f2543Smrg XID *vlist; 2058706f2543Smrg BITS32 vmask; 2059706f2543Smrg int ret = Success, error = Success; 2060706f2543Smrg DeviceIntPtr pDev = NULL, keyboard; 2061706f2543Smrg REQUEST(xChangeKeyboardControlReq); 2062706f2543Smrg 2063706f2543Smrg REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq); 2064706f2543Smrg 2065706f2543Smrg vmask = stuff->mask; 2066706f2543Smrg vlist = (XID *)&stuff[1]; 2067706f2543Smrg 2068706f2543Smrg if (client->req_len != (sizeof(xChangeKeyboardControlReq)>>2)+Ones(vmask)) 2069706f2543Smrg return BadLength; 2070706f2543Smrg 2071706f2543Smrg keyboard = PickKeyboard(client); 2072706f2543Smrg 2073706f2543Smrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 2074706f2543Smrg if ((pDev == keyboard || 2075706f2543Smrg (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard)) 2076706f2543Smrg && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) { 2077706f2543Smrg ret = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); 2078706f2543Smrg if (ret != Success) 2079706f2543Smrg return ret; 2080706f2543Smrg } 2081706f2543Smrg } 2082706f2543Smrg 2083706f2543Smrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 2084706f2543Smrg if ((pDev == keyboard || 2085706f2543Smrg (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard)) 2086706f2543Smrg && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) { 2087706f2543Smrg ret = DoChangeKeyboardControl(client, pDev, vlist, vmask); 2088706f2543Smrg if (ret != Success) 2089706f2543Smrg error = ret; 2090706f2543Smrg } 2091706f2543Smrg } 2092706f2543Smrg 2093706f2543Smrg return error; 2094706f2543Smrg} 2095706f2543Smrg 2096706f2543Smrgint 2097706f2543SmrgProcGetKeyboardControl (ClientPtr client) 2098706f2543Smrg{ 2099706f2543Smrg int rc, i; 2100706f2543Smrg DeviceIntPtr kbd = PickKeyboard(client); 2101706f2543Smrg KeybdCtrl *ctrl = &kbd->kbdfeed->ctrl; 2102706f2543Smrg xGetKeyboardControlReply rep; 2103706f2543Smrg REQUEST_SIZE_MATCH(xReq); 2104706f2543Smrg 2105706f2543Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess); 2106706f2543Smrg if (rc != Success) 2107706f2543Smrg return rc; 2108706f2543Smrg 2109706f2543Smrg rep.type = X_Reply; 2110706f2543Smrg rep.length = 5; 2111706f2543Smrg rep.sequenceNumber = client->sequence; 2112706f2543Smrg rep.globalAutoRepeat = ctrl->autoRepeat; 2113706f2543Smrg rep.keyClickPercent = ctrl->click; 2114706f2543Smrg rep.bellPercent = ctrl->bell; 2115706f2543Smrg rep.bellPitch = ctrl->bell_pitch; 2116706f2543Smrg rep.bellDuration = ctrl->bell_duration; 2117706f2543Smrg rep.ledMask = ctrl->leds; 2118706f2543Smrg for (i = 0; i < 32; i++) 2119706f2543Smrg rep.map[i] = ctrl->autoRepeats[i]; 2120706f2543Smrg WriteReplyToClient(client, sizeof(xGetKeyboardControlReply), &rep); 2121706f2543Smrg return Success; 2122706f2543Smrg} 2123706f2543Smrg 2124706f2543Smrgint 2125706f2543SmrgProcBell(ClientPtr client) 2126706f2543Smrg{ 2127706f2543Smrg DeviceIntPtr dev, keybd = PickKeyboard(client); 2128706f2543Smrg int base = keybd->kbdfeed->ctrl.bell; 2129706f2543Smrg int newpercent; 2130706f2543Smrg int rc; 2131706f2543Smrg REQUEST(xBellReq); 2132706f2543Smrg REQUEST_SIZE_MATCH(xBellReq); 2133706f2543Smrg 2134706f2543Smrg if (stuff->percent < -100 || stuff->percent > 100) { 2135706f2543Smrg client->errorValue = stuff->percent; 2136706f2543Smrg return BadValue; 2137706f2543Smrg } 2138706f2543Smrg 2139706f2543Smrg newpercent = (base * stuff->percent) / 100; 2140706f2543Smrg if (stuff->percent < 0) 2141706f2543Smrg newpercent = base + newpercent; 2142706f2543Smrg else 2143706f2543Smrg newpercent = base - newpercent + stuff->percent; 2144706f2543Smrg 2145706f2543Smrg for (dev = inputInfo.devices; dev; dev = dev->next) { 2146706f2543Smrg if ((dev == keybd || 2147706f2543Smrg (!IsMaster(dev) && GetMaster(dev, MASTER_KEYBOARD) == keybd)) && 2148706f2543Smrg dev->kbdfeed && dev->kbdfeed->BellProc) { 2149706f2543Smrg 2150706f2543Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixBellAccess); 2151706f2543Smrg if (rc != Success) 2152706f2543Smrg return rc; 2153706f2543Smrg XkbHandleBell(FALSE, FALSE, dev, newpercent, 2154706f2543Smrg &dev->kbdfeed->ctrl, 0, None, NULL, client); 2155706f2543Smrg } 2156706f2543Smrg } 2157706f2543Smrg 2158706f2543Smrg return Success; 2159706f2543Smrg} 2160706f2543Smrg 2161706f2543Smrgint 2162706f2543SmrgProcChangePointerControl(ClientPtr client) 2163706f2543Smrg{ 2164706f2543Smrg DeviceIntPtr dev, mouse = PickPointer(client); 2165706f2543Smrg PtrCtrl ctrl; /* might get BadValue part way through */ 2166706f2543Smrg int rc; 2167706f2543Smrg REQUEST(xChangePointerControlReq); 2168706f2543Smrg REQUEST_SIZE_MATCH(xChangePointerControlReq); 2169706f2543Smrg 2170706f2543Smrg ctrl = mouse->ptrfeed->ctrl; 2171706f2543Smrg if ((stuff->doAccel != xTrue) && (stuff->doAccel != xFalse)) { 2172706f2543Smrg client->errorValue = stuff->doAccel; 2173706f2543Smrg return BadValue; 2174706f2543Smrg } 2175706f2543Smrg if ((stuff->doThresh != xTrue) && (stuff->doThresh != xFalse)) { 2176706f2543Smrg client->errorValue = stuff->doThresh; 2177706f2543Smrg return BadValue; 2178706f2543Smrg } 2179706f2543Smrg if (stuff->doAccel) { 2180706f2543Smrg if (stuff->accelNum == -1) { 2181706f2543Smrg ctrl.num = defaultPointerControl.num; 2182706f2543Smrg } 2183706f2543Smrg else if (stuff->accelNum < 0) { 2184706f2543Smrg client->errorValue = stuff->accelNum; 2185706f2543Smrg return BadValue; 2186706f2543Smrg } 2187706f2543Smrg else { 2188706f2543Smrg ctrl.num = stuff->accelNum; 2189706f2543Smrg } 2190706f2543Smrg 2191706f2543Smrg if (stuff->accelDenum == -1) { 2192706f2543Smrg ctrl.den = defaultPointerControl.den; 2193706f2543Smrg } 2194706f2543Smrg else if (stuff->accelDenum <= 0) { 2195706f2543Smrg client->errorValue = stuff->accelDenum; 2196706f2543Smrg return BadValue; 2197706f2543Smrg } 2198706f2543Smrg else { 2199706f2543Smrg ctrl.den = stuff->accelDenum; 2200706f2543Smrg } 2201706f2543Smrg } 2202706f2543Smrg if (stuff->doThresh) { 2203706f2543Smrg if (stuff->threshold == -1) { 2204706f2543Smrg ctrl.threshold = defaultPointerControl.threshold; 2205706f2543Smrg } 2206706f2543Smrg else if (stuff->threshold < 0) { 2207706f2543Smrg client->errorValue = stuff->threshold; 2208706f2543Smrg return BadValue; 2209706f2543Smrg } 2210706f2543Smrg else { 2211706f2543Smrg ctrl.threshold = stuff->threshold; 2212706f2543Smrg } 2213706f2543Smrg } 2214706f2543Smrg 2215706f2543Smrg for (dev = inputInfo.devices; dev; dev = dev->next) { 2216706f2543Smrg if ((dev == mouse || 2217706f2543Smrg (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) && 2218706f2543Smrg dev->ptrfeed) { 2219706f2543Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess); 2220706f2543Smrg if (rc != Success) 2221706f2543Smrg return rc; 2222706f2543Smrg } 2223706f2543Smrg } 2224706f2543Smrg 2225706f2543Smrg for (dev = inputInfo.devices; dev; dev = dev->next) { 2226706f2543Smrg if ((dev == mouse || 2227706f2543Smrg (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) && 2228706f2543Smrg dev->ptrfeed) { 2229706f2543Smrg dev->ptrfeed->ctrl = ctrl; 2230706f2543Smrg } 2231706f2543Smrg } 2232706f2543Smrg 2233706f2543Smrg return Success; 2234706f2543Smrg} 2235706f2543Smrg 2236706f2543Smrgint 2237706f2543SmrgProcGetPointerControl(ClientPtr client) 2238706f2543Smrg{ 2239706f2543Smrg DeviceIntPtr ptr = PickPointer(client); 2240706f2543Smrg PtrCtrl *ctrl = &ptr->ptrfeed->ctrl; 2241706f2543Smrg xGetPointerControlReply rep; 2242706f2543Smrg int rc; 2243706f2543Smrg REQUEST_SIZE_MATCH(xReq); 2244706f2543Smrg 2245706f2543Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess); 2246706f2543Smrg if (rc != Success) 2247706f2543Smrg return rc; 2248706f2543Smrg 2249706f2543Smrg rep.type = X_Reply; 2250706f2543Smrg rep.length = 0; 2251706f2543Smrg rep.sequenceNumber = client->sequence; 2252706f2543Smrg rep.threshold = ctrl->threshold; 2253706f2543Smrg rep.accelNumerator = ctrl->num; 2254706f2543Smrg rep.accelDenominator = ctrl->den; 2255706f2543Smrg WriteReplyToClient(client, sizeof(xGenericReply), &rep); 2256706f2543Smrg return Success; 2257706f2543Smrg} 2258706f2543Smrg 2259706f2543Smrgvoid 2260706f2543SmrgMaybeStopHint(DeviceIntPtr dev, ClientPtr client) 2261706f2543Smrg{ 2262706f2543Smrg GrabPtr grab = dev->deviceGrab.grab; 2263706f2543Smrg 2264706f2543Smrg if ((grab && SameClient(grab, client) && 2265706f2543Smrg ((grab->eventMask & PointerMotionHintMask) || 2266706f2543Smrg (grab->ownerEvents && 2267706f2543Smrg (EventMaskForClient(dev->valuator->motionHintWindow, client) & 2268706f2543Smrg PointerMotionHintMask)))) || 2269706f2543Smrg (!grab && 2270706f2543Smrg (EventMaskForClient(dev->valuator->motionHintWindow, client) & 2271706f2543Smrg PointerMotionHintMask))) 2272706f2543Smrg dev->valuator->motionHintWindow = NullWindow; 2273706f2543Smrg} 2274706f2543Smrg 2275706f2543Smrgint 2276706f2543SmrgProcGetMotionEvents(ClientPtr client) 2277706f2543Smrg{ 2278706f2543Smrg WindowPtr pWin; 2279706f2543Smrg xTimecoord * coords = (xTimecoord *) NULL; 2280706f2543Smrg xGetMotionEventsReply rep; 2281706f2543Smrg int i, count, xmin, xmax, ymin, ymax, rc; 2282706f2543Smrg unsigned long nEvents; 2283706f2543Smrg DeviceIntPtr mouse = PickPointer(client); 2284706f2543Smrg TimeStamp start, stop; 2285706f2543Smrg REQUEST(xGetMotionEventsReq); 2286706f2543Smrg REQUEST_SIZE_MATCH(xGetMotionEventsReq); 2287706f2543Smrg 2288706f2543Smrg rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); 2289706f2543Smrg if (rc != Success) 2290706f2543Smrg return rc; 2291706f2543Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, mouse, DixReadAccess); 2292706f2543Smrg if (rc != Success) 2293706f2543Smrg return rc; 2294706f2543Smrg 2295706f2543Smrg if (mouse->valuator->motionHintWindow) 2296706f2543Smrg MaybeStopHint(mouse, client); 2297706f2543Smrg rep.type = X_Reply; 2298706f2543Smrg rep.sequenceNumber = client->sequence; 2299706f2543Smrg nEvents = 0; 2300706f2543Smrg start = ClientTimeToServerTime(stuff->start); 2301706f2543Smrg stop = ClientTimeToServerTime(stuff->stop); 2302706f2543Smrg if ((CompareTimeStamps(start, stop) != LATER) && 2303706f2543Smrg (CompareTimeStamps(start, currentTime) != LATER) && 2304706f2543Smrg mouse->valuator->numMotionEvents) 2305706f2543Smrg { 2306706f2543Smrg if (CompareTimeStamps(stop, currentTime) == LATER) 2307706f2543Smrg stop = currentTime; 2308706f2543Smrg count = GetMotionHistory(mouse, &coords, start.milliseconds, 2309706f2543Smrg stop.milliseconds, pWin->drawable.pScreen, 2310706f2543Smrg TRUE); 2311706f2543Smrg xmin = pWin->drawable.x - wBorderWidth (pWin); 2312706f2543Smrg xmax = pWin->drawable.x + (int)pWin->drawable.width + 2313706f2543Smrg wBorderWidth (pWin); 2314706f2543Smrg ymin = pWin->drawable.y - wBorderWidth (pWin); 2315706f2543Smrg ymax = pWin->drawable.y + (int)pWin->drawable.height + 2316706f2543Smrg wBorderWidth (pWin); 2317706f2543Smrg for (i = 0; i < count; i++) 2318706f2543Smrg if ((xmin <= coords[i].x) && (coords[i].x < xmax) && 2319706f2543Smrg (ymin <= coords[i].y) && (coords[i].y < ymax)) 2320706f2543Smrg { 2321706f2543Smrg coords[nEvents].time = coords[i].time; 2322706f2543Smrg coords[nEvents].x = coords[i].x - pWin->drawable.x; 2323706f2543Smrg coords[nEvents].y = coords[i].y - pWin->drawable.y; 2324706f2543Smrg nEvents++; 2325706f2543Smrg } 2326706f2543Smrg } 2327706f2543Smrg rep.length = nEvents * bytes_to_int32(sizeof(xTimecoord)); 2328706f2543Smrg rep.nEvents = nEvents; 2329706f2543Smrg WriteReplyToClient(client, sizeof(xGetMotionEventsReply), &rep); 2330706f2543Smrg if (nEvents) 2331706f2543Smrg { 2332706f2543Smrg client->pSwapReplyFunc = (ReplySwapPtr) SwapTimeCoordWrite; 2333706f2543Smrg WriteSwappedDataToClient(client, nEvents * sizeof(xTimecoord), 2334706f2543Smrg (char *)coords); 2335706f2543Smrg } 2336706f2543Smrg free(coords); 2337706f2543Smrg return Success; 2338706f2543Smrg} 2339706f2543Smrg 2340706f2543Smrgint 2341706f2543SmrgProcQueryKeymap(ClientPtr client) 2342706f2543Smrg{ 2343706f2543Smrg xQueryKeymapReply rep; 2344706f2543Smrg int rc, i; 2345706f2543Smrg DeviceIntPtr keybd = PickKeyboard(client); 2346706f2543Smrg CARD8 *down = keybd->key->down; 2347706f2543Smrg 2348706f2543Smrg REQUEST_SIZE_MATCH(xReq); 2349706f2543Smrg rep.type = X_Reply; 2350706f2543Smrg rep.sequenceNumber = client->sequence; 2351706f2543Smrg rep.length = 2; 2352706f2543Smrg 2353706f2543Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess); 2354706f2543Smrg if (rc != Success && rc != BadAccess) 2355706f2543Smrg return rc; 2356706f2543Smrg 2357706f2543Smrg for (i = 0; i<32; i++) 2358706f2543Smrg rep.map[i] = down[i]; 2359706f2543Smrg 2360706f2543Smrg if (rc == BadAccess) 2361706f2543Smrg memset(rep.map, 0, 32); 2362706f2543Smrg 2363706f2543Smrg WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep); 2364706f2543Smrg 2365706f2543Smrg return Success; 2366706f2543Smrg} 2367706f2543Smrg 2368706f2543Smrg 2369706f2543Smrg/** 2370706f2543Smrg * Recalculate the number of buttons for the master device. The number of 2371706f2543Smrg * buttons on the master device is equal to the number of buttons on the 2372706f2543Smrg * slave device with the highest number of buttons. 2373706f2543Smrg */ 2374706f2543Smrgstatic void 2375706f2543SmrgRecalculateMasterButtons(DeviceIntPtr slave) 2376706f2543Smrg{ 2377706f2543Smrg DeviceIntPtr dev, master; 2378706f2543Smrg int maxbuttons = 0; 2379706f2543Smrg 2380706f2543Smrg if (!slave->button || IsMaster(slave)) 2381706f2543Smrg return; 2382706f2543Smrg 2383706f2543Smrg master = GetMaster(slave, MASTER_POINTER); 2384706f2543Smrg if (!master) 2385706f2543Smrg return; 2386706f2543Smrg 2387706f2543Smrg for (dev = inputInfo.devices; dev; dev = dev->next) 2388706f2543Smrg { 2389706f2543Smrg if (IsMaster(dev) || 2390706f2543Smrg dev->u.master != master || 2391706f2543Smrg !dev->button) 2392706f2543Smrg continue; 2393706f2543Smrg 2394706f2543Smrg maxbuttons = max(maxbuttons, dev->button->numButtons); 2395706f2543Smrg } 2396706f2543Smrg 2397706f2543Smrg if (master->button && master->button->numButtons != maxbuttons) 2398706f2543Smrg { 2399706f2543Smrg int i; 2400706f2543Smrg DeviceChangedEvent event; 2401706f2543Smrg 2402706f2543Smrg memset(&event, 0, sizeof(event)); 2403706f2543Smrg 2404706f2543Smrg master->button->numButtons = maxbuttons; 2405706f2543Smrg 2406706f2543Smrg event.header = ET_Internal; 2407706f2543Smrg event.type = ET_DeviceChanged; 2408706f2543Smrg event.time = GetTimeInMillis(); 2409706f2543Smrg event.deviceid = master->id; 2410706f2543Smrg event.flags = DEVCHANGE_POINTER_EVENT | DEVCHANGE_DEVICE_CHANGE; 2411706f2543Smrg event.buttons.num_buttons = maxbuttons; 2412706f2543Smrg memcpy(&event.buttons.names, master->button->labels, maxbuttons * 2413706f2543Smrg sizeof(Atom)); 2414706f2543Smrg 2415706f2543Smrg if (master->valuator) 2416706f2543Smrg { 2417706f2543Smrg event.num_valuators = master->valuator->numAxes; 2418706f2543Smrg for (i = 0; i < event.num_valuators; i++) 2419706f2543Smrg { 2420706f2543Smrg event.valuators[i].min = master->valuator->axes[i].min_value; 2421706f2543Smrg event.valuators[i].max = master->valuator->axes[i].max_value; 2422706f2543Smrg event.valuators[i].resolution = master->valuator->axes[i].resolution; 2423706f2543Smrg event.valuators[i].mode = master->valuator->axes[i].mode; 2424706f2543Smrg event.valuators[i].name = master->valuator->axes[i].label; 2425706f2543Smrg } 2426706f2543Smrg } 2427706f2543Smrg 2428706f2543Smrg if (master->key) 2429706f2543Smrg { 2430706f2543Smrg event.keys.min_keycode = master->key->xkbInfo->desc->min_key_code; 2431706f2543Smrg event.keys.max_keycode = master->key->xkbInfo->desc->max_key_code; 2432706f2543Smrg } 2433706f2543Smrg 2434706f2543Smrg XISendDeviceChangedEvent(master, master, &event); 2435706f2543Smrg } 2436706f2543Smrg} 2437706f2543Smrg 2438706f2543Smrg/** 2439706f2543Smrg * Generate release events for all keys/button currently down on this 2440706f2543Smrg * device. 2441706f2543Smrg */ 2442706f2543Smrgvoid 2443706f2543SmrgReleaseButtonsAndKeys(DeviceIntPtr dev) 2444706f2543Smrg{ 2445706f2543Smrg EventListPtr eventlist = InitEventList(GetMaximumEventsNum()); 2446706f2543Smrg ButtonClassPtr b = dev->button; 2447706f2543Smrg KeyClassPtr k = dev->key; 2448706f2543Smrg int i, j, nevents; 2449706f2543Smrg 2450706f2543Smrg if (!eventlist) /* no release events for you */ 2451706f2543Smrg return; 2452706f2543Smrg 2453706f2543Smrg /* Release all buttons */ 2454706f2543Smrg for (i = 0; b && i < b->numButtons; i++) 2455706f2543Smrg { 2456706f2543Smrg if (BitIsOn(b->down, i)) 2457706f2543Smrg { 2458706f2543Smrg nevents = GetPointerEvents(eventlist, dev, ButtonRelease, i, 0, NULL); 2459706f2543Smrg for (j = 0; j < nevents; j++) 2460706f2543Smrg mieqProcessDeviceEvent(dev, (InternalEvent*)(eventlist+j)->event, NULL); 2461706f2543Smrg } 2462706f2543Smrg } 2463706f2543Smrg 2464706f2543Smrg /* Release all keys */ 2465706f2543Smrg for (i = 0; k && i < MAP_LENGTH; i++) 2466706f2543Smrg { 2467706f2543Smrg if (BitIsOn(k->down, i)) 2468706f2543Smrg { 2469706f2543Smrg nevents = GetKeyboardEvents(eventlist, dev, KeyRelease, i); 2470706f2543Smrg for (j = 0; j < nevents; j++) 2471706f2543Smrg mieqProcessDeviceEvent(dev, (InternalEvent*)(eventlist+j)->event, NULL); 2472706f2543Smrg } 2473706f2543Smrg } 2474706f2543Smrg 2475706f2543Smrg FreeEventList(eventlist, GetMaximumEventsNum()); 2476706f2543Smrg} 2477706f2543Smrg 2478706f2543Smrg/** 2479706f2543Smrg * Attach device 'dev' to device 'master'. 2480706f2543Smrg * Client is set to the client that issued the request, or NULL if it comes 2481706f2543Smrg * from some internal automatic pairing. 2482706f2543Smrg * 2483706f2543Smrg * Master may be NULL to set the device floating. 2484706f2543Smrg * 2485706f2543Smrg * We don't allow multi-layer hierarchies right now. You can't attach a slave 2486706f2543Smrg * to another slave. 2487706f2543Smrg */ 2488706f2543Smrgint 2489706f2543SmrgAttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) 2490706f2543Smrg{ 2491706f2543Smrg ScreenPtr screen; 2492706f2543Smrg DeviceIntPtr oldmaster; 2493706f2543Smrg if (!dev || IsMaster(dev)) 2494706f2543Smrg return BadDevice; 2495706f2543Smrg 2496706f2543Smrg if (master && !IsMaster(master)) /* can't attach to slaves */ 2497706f2543Smrg return BadDevice; 2498706f2543Smrg 2499706f2543Smrg /* set from floating to floating? */ 2500706f2543Smrg if (!dev->u.master && !master && dev->enabled) 2501706f2543Smrg return Success; 2502706f2543Smrg 2503706f2543Smrg /* free the existing sprite. */ 2504706f2543Smrg if (!dev->u.master && dev->spriteInfo->paired == dev) 2505706f2543Smrg { 2506706f2543Smrg screen = miPointerGetScreen(dev); 2507706f2543Smrg screen->DeviceCursorCleanup(dev, screen); 2508706f2543Smrg free(dev->spriteInfo->sprite); 2509706f2543Smrg } 2510706f2543Smrg 2511706f2543Smrg oldmaster = dev->u.master; 2512706f2543Smrg dev->u.master = master; 2513706f2543Smrg 2514706f2543Smrg /* If device is set to floating, we need to create a sprite for it, 2515706f2543Smrg * otherwise things go bad. However, we don't want to render the cursor, 2516706f2543Smrg * so we reset spriteOwner. 2517706f2543Smrg * Sprite has to be forced to NULL first, otherwise InitializeSprite won't 2518706f2543Smrg * alloc new memory but overwrite the previous one. 2519706f2543Smrg */ 2520706f2543Smrg if (!master) 2521706f2543Smrg { 2522706f2543Smrg WindowPtr currentRoot; 2523706f2543Smrg 2524706f2543Smrg if (dev->spriteInfo->sprite) 2525706f2543Smrg currentRoot = GetCurrentRootWindow(dev); 2526706f2543Smrg else /* new device auto-set to floating */ 2527706f2543Smrg currentRoot = screenInfo.screens[0]->root; 2528706f2543Smrg 2529706f2543Smrg /* we need to init a fake sprite */ 2530706f2543Smrg screen = currentRoot->drawable.pScreen; 2531706f2543Smrg screen->DeviceCursorInitialize(dev, screen); 2532706f2543Smrg dev->spriteInfo->sprite = NULL; 2533706f2543Smrg InitializeSprite(dev, currentRoot); 2534706f2543Smrg dev->spriteInfo->spriteOwner = FALSE; 2535706f2543Smrg dev->spriteInfo->paired = dev; 2536706f2543Smrg } else 2537706f2543Smrg { 2538706f2543Smrg dev->spriteInfo->sprite = master->spriteInfo->sprite; 2539706f2543Smrg dev->spriteInfo->paired = master; 2540706f2543Smrg dev->spriteInfo->spriteOwner = FALSE; 2541706f2543Smrg 2542706f2543Smrg RecalculateMasterButtons(master); 2543706f2543Smrg } 2544706f2543Smrg 2545706f2543Smrg /* XXX: in theory, the MD should change back to its old, original 2546706f2543Smrg * classes when the last SD is detached. Thanks to the XTEST devices, 2547706f2543Smrg * we'll always have an SD attached until the MD is removed. 2548706f2543Smrg * So let's not worry about that. 2549706f2543Smrg */ 2550706f2543Smrg 2551706f2543Smrg return Success; 2552706f2543Smrg} 2553706f2543Smrg 2554706f2543Smrg/** 2555706f2543Smrg * Return the device paired with the given device or NULL. 2556706f2543Smrg * Returns the device paired with the parent master if the given device is a 2557706f2543Smrg * slave device. 2558706f2543Smrg */ 2559706f2543SmrgDeviceIntPtr 2560706f2543SmrgGetPairedDevice(DeviceIntPtr dev) 2561706f2543Smrg{ 2562706f2543Smrg if (!IsMaster(dev) && dev->u.master) 2563706f2543Smrg dev = dev->u.master; 2564706f2543Smrg 2565706f2543Smrg return dev->spriteInfo->paired; 2566706f2543Smrg} 2567706f2543Smrg 2568706f2543Smrg 2569706f2543Smrg/** 2570706f2543Smrg * Returns the right master for the type of event needed. If the event is a 2571706f2543Smrg * keyboard event. 2572706f2543Smrg * This function may be called with a master device as argument. If so, the 2573706f2543Smrg * returned master is either the device itself or the paired master device. 2574706f2543Smrg * If dev is a floating slave device, NULL is returned. 2575706f2543Smrg * 2576706f2543Smrg * @type ::MASTER_KEYBOARD or ::MASTER_POINTER 2577706f2543Smrg */ 2578706f2543SmrgDeviceIntPtr 2579706f2543SmrgGetMaster(DeviceIntPtr dev, int which) 2580706f2543Smrg{ 2581706f2543Smrg DeviceIntPtr master; 2582706f2543Smrg 2583706f2543Smrg if (IsMaster(dev)) 2584706f2543Smrg master = dev; 2585706f2543Smrg else 2586706f2543Smrg master = dev->u.master; 2587706f2543Smrg 2588706f2543Smrg if (master) 2589706f2543Smrg { 2590706f2543Smrg if (which == MASTER_KEYBOARD) 2591706f2543Smrg { 2592706f2543Smrg if (master->type != MASTER_KEYBOARD) 2593706f2543Smrg master = GetPairedDevice(master); 2594706f2543Smrg } else 2595706f2543Smrg { 2596706f2543Smrg if (master->type != MASTER_POINTER) 2597706f2543Smrg master = GetPairedDevice(master); 2598706f2543Smrg } 2599706f2543Smrg } 2600706f2543Smrg 2601706f2543Smrg return master; 2602706f2543Smrg} 2603706f2543Smrg 2604706f2543Smrg/** 2605706f2543Smrg * Create a new device pair (== one pointer, one keyboard device). 2606706f2543Smrg * Only allocates the devices, you will need to call ActivateDevice() and 2607706f2543Smrg * EnableDevice() manually. 2608706f2543Smrg * Either a master or a slave device can be created depending on 2609706f2543Smrg * the value for master. 2610706f2543Smrg */ 2611706f2543Smrgint 2612706f2543SmrgAllocDevicePair (ClientPtr client, char* name, 2613706f2543Smrg DeviceIntPtr* ptr, 2614706f2543Smrg DeviceIntPtr* keybd, 2615706f2543Smrg DeviceProc ptr_proc, 2616706f2543Smrg DeviceProc keybd_proc, 2617706f2543Smrg Bool master) 2618706f2543Smrg{ 2619706f2543Smrg DeviceIntPtr pointer; 2620706f2543Smrg DeviceIntPtr keyboard; 2621706f2543Smrg *ptr = *keybd = NULL; 2622706f2543Smrg 2623706f2543Smrg pointer = AddInputDevice(client, ptr_proc, TRUE); 2624706f2543Smrg if (!pointer) 2625706f2543Smrg return BadAlloc; 2626706f2543Smrg 2627706f2543Smrg if (asprintf(&pointer->name, "%s pointer", name) == -1) { 2628706f2543Smrg pointer->name = NULL; 2629706f2543Smrg RemoveDevice(pointer, FALSE); 2630706f2543Smrg return BadAlloc; 2631706f2543Smrg } 2632706f2543Smrg 2633706f2543Smrg pointer->public.processInputProc = ProcessOtherEvent; 2634706f2543Smrg pointer->public.realInputProc = ProcessOtherEvent; 2635706f2543Smrg XkbSetExtension(pointer, ProcessPointerEvent); 2636706f2543Smrg pointer->deviceGrab.ActivateGrab = ActivatePointerGrab; 2637706f2543Smrg pointer->deviceGrab.DeactivateGrab = DeactivatePointerGrab; 2638706f2543Smrg pointer->coreEvents = TRUE; 2639706f2543Smrg pointer->spriteInfo->spriteOwner = TRUE; 2640706f2543Smrg 2641706f2543Smrg pointer->u.lastSlave = NULL; 2642706f2543Smrg pointer->last.slave = NULL; 2643706f2543Smrg pointer->type = (master) ? MASTER_POINTER : SLAVE; 2644706f2543Smrg 2645706f2543Smrg keyboard = AddInputDevice(client, keybd_proc, TRUE); 2646706f2543Smrg if (!keyboard) 2647706f2543Smrg { 2648706f2543Smrg RemoveDevice(pointer, FALSE); 2649706f2543Smrg return BadAlloc; 2650706f2543Smrg } 2651706f2543Smrg 2652706f2543Smrg if (asprintf(&keyboard->name, "%s keyboard", name) == -1) { 2653706f2543Smrg keyboard->name = NULL; 2654706f2543Smrg RemoveDevice(keyboard, FALSE); 2655706f2543Smrg RemoveDevice(pointer, FALSE); 2656706f2543Smrg return BadAlloc; 2657706f2543Smrg } 2658706f2543Smrg 2659706f2543Smrg keyboard->public.processInputProc = ProcessOtherEvent; 2660706f2543Smrg keyboard->public.realInputProc = ProcessOtherEvent; 2661706f2543Smrg XkbSetExtension(keyboard, ProcessKeyboardEvent); 2662706f2543Smrg keyboard->deviceGrab.ActivateGrab = ActivateKeyboardGrab; 2663706f2543Smrg keyboard->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab; 2664706f2543Smrg keyboard->coreEvents = TRUE; 2665706f2543Smrg keyboard->spriteInfo->spriteOwner = FALSE; 2666706f2543Smrg 2667706f2543Smrg keyboard->u.lastSlave = NULL; 2668706f2543Smrg keyboard->last.slave = NULL; 2669706f2543Smrg keyboard->type = (master) ? MASTER_KEYBOARD : SLAVE; 2670706f2543Smrg 2671706f2543Smrg /* The ClassesRec stores the device classes currently not used. */ 2672706f2543Smrg pointer->unused_classes = calloc(1, sizeof(ClassesRec)); 2673706f2543Smrg keyboard->unused_classes = calloc(1, sizeof(ClassesRec)); 2674706f2543Smrg 2675706f2543Smrg *ptr = pointer; 2676706f2543Smrg *keybd = keyboard; 2677706f2543Smrg 2678706f2543Smrg return Success; 2679706f2543Smrg} 2680706f2543Smrg 2681706f2543Smrg/** 2682706f2543Smrg * Return Relative or Absolute for the device. 2683706f2543Smrg */ 2684706f2543Smrgint valuator_get_mode(DeviceIntPtr dev, int axis) 2685706f2543Smrg{ 2686706f2543Smrg return (dev->valuator->axes[axis].mode & DeviceMode); 2687706f2543Smrg} 2688706f2543Smrg 2689706f2543Smrg/** 2690706f2543Smrg * Set the given mode for the axis. If axis is VALUATOR_MODE_ALL_AXES, then 2691706f2543Smrg * set the mode for all axes. 2692706f2543Smrg */ 2693706f2543Smrgvoid valuator_set_mode(DeviceIntPtr dev, int axis, int mode) 2694706f2543Smrg{ 2695706f2543Smrg if (axis != VALUATOR_MODE_ALL_AXES) 2696706f2543Smrg dev->valuator->axes[axis].mode = mode; 2697706f2543Smrg else { 2698706f2543Smrg int i; 2699706f2543Smrg for (i = 0; i < dev->valuator->numAxes; i++) 2700706f2543Smrg dev->valuator->axes[i].mode = mode; 2701706f2543Smrg } 2702706f2543Smrg} 2703