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