xf86Xinput.c revision 05b261ec
1/* 2 * Copyright 1995-1999 by Frederic Lepied, France. <Lepied@XFree86.org> 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of Frederic Lepied not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. Frederic Lepied makes no 11 * representations about the suitability of this software for any purpose. It 12 * is provided "as is" without express or implied warranty. 13 * 14 * FREDERIC LEPIED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL FREDERIC LEPIED BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 * 22 */ 23/* 24 * Copyright (c) 2000-2002 by The XFree86 Project, Inc. 25 * 26 * Permission is hereby granted, free of charge, to any person obtaining a 27 * copy of this software and associated documentation files (the "Software"), 28 * to deal in the Software without restriction, including without limitation 29 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 30 * and/or sell copies of the Software, and to permit persons to whom the 31 * Software is furnished to do so, subject to the following conditions: 32 * 33 * The above copyright notice and this permission notice shall be included in 34 * all copies or substantial portions of the Software. 35 * 36 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 37 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 38 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 39 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 40 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 41 * OTHER DEALINGS IN THE SOFTWARE. 42 * 43 * Except as contained in this notice, the name of the copyright holder(s) 44 * and author(s) shall not be used in advertising or otherwise to promote 45 * the sale, use or other dealings in this Software without prior written 46 * authorization from the copyright holder(s) and author(s). 47 */ 48 49#ifdef HAVE_XORG_CONFIG_H 50#include <xorg-config.h> 51#endif 52 53#include <X11/Xfuncproto.h> 54#include <X11/Xmd.h> 55#ifdef XINPUT 56#include <X11/extensions/XI.h> 57#include <X11/extensions/XIproto.h> 58#endif 59#include "xf86.h" 60#include "xf86Priv.h" 61#include "xf86Xinput.h" 62#ifdef XINPUT 63#include "XIstubs.h" 64#include "xf86Optrec.h" 65#endif 66#include "mipointer.h" 67#include "xf86InPriv.h" 68 69#ifdef DPMSExtension 70#define DPMS_SERVER 71#include <X11/extensions/dpms.h> 72#include "dpmsproc.h" 73#endif 74 75#include "exevents.h" /* AddInputDevice */ 76#include "exglobals.h" 77 78#define EXTENSION_PROC_ARGS void * 79#include "extnsionst.h" 80#include "extinit.h" /* LookupDeviceIntRec */ 81 82#include "windowstr.h" /* screenIsSaved */ 83 84#include <stdarg.h> 85 86#include <X11/Xpoll.h> 87 88#include "mi.h" 89 90#ifdef XFreeXDGA 91#include "dgaproc.h" 92#endif 93 94xEvent *xf86Events = NULL; 95 96static Bool 97xf86SendDragEvents(DeviceIntPtr device) 98{ 99 LocalDevicePtr local = (LocalDevicePtr) device->public.devicePrivate; 100 101 if (device->button && device->button->buttonsDown > 0) 102 return (local->flags & XI86_SEND_DRAG_EVENTS); 103 else 104 return (TRUE); 105} 106 107/*********************************************************************** 108 * 109 * xf86ProcessCommonOptions -- 110 * 111 * Process global options. 112 * 113 *********************************************************************** 114 */ 115_X_EXPORT void 116xf86ProcessCommonOptions(LocalDevicePtr local, 117 pointer list) 118{ 119 if (!xf86SetBoolOption(list, "AlwaysCore", 1) || 120 !xf86SetBoolOption(list, "SendCoreEvents", 1) || 121 !xf86SetBoolOption(list, "CorePointer", 1) || 122 !xf86SetBoolOption(list, "CoreKeyboard", 1)) { 123 xf86Msg(X_CONFIG, "%s: doesn't report core events\n", local->name); 124 } else { 125 local->flags |= XI86_ALWAYS_CORE; 126 xf86Msg(X_CONFIG, "%s: always reports core events\n", local->name); 127 } 128 129 if (xf86SetBoolOption(list, "SendDragEvents", 1)) { 130 local->flags |= XI86_SEND_DRAG_EVENTS; 131 } else { 132 xf86Msg(X_CONFIG, "%s: doesn't report drag events\n", local->name); 133 } 134 135 /* Backwards compatibility. */ 136 local->history_size = GetMotionHistorySize(); 137} 138 139/*********************************************************************** 140 * 141 * xf86ActivateDevice -- 142 * 143 * Initialize an input device. 144 * 145 *********************************************************************** 146 */ 147_X_EXPORT void 148xf86ActivateDevice(LocalDevicePtr local) 149{ 150 DeviceIntPtr dev; 151 152 if (local->flags & XI86_CONFIGURED) { 153 dev = AddInputDevice(local->device_control, TRUE); 154 155 if (dev == NULL) 156 FatalError("Too many input devices"); 157 158 local->atom = MakeAtom(local->type_name, 159 strlen(local->type_name), 160 TRUE); 161 AssignTypeAndName(dev, local->atom, local->name); 162 dev->public.devicePrivate = (pointer) local; 163 local->dev = dev; 164 165 dev->coreEvents = local->flags & XI86_ALWAYS_CORE; 166 RegisterOtherDevice(dev); 167 168#ifdef XKB 169 if (!noXkbExtension) 170 XkbSetExtension(dev, ProcessKeyboardEvent); 171#endif 172 173 if (serverGeneration == 1) 174 xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n", 175 local->name, local->type_name); 176 } 177} 178 179 180#ifdef XINPUT 181/*********************************************************************** 182 * 183 * Caller: ProcXOpenDevice 184 * 185 * This is the implementation-dependent routine to open an input device. 186 * Some implementations open all input devices when the server is first 187 * initialized, and never close them. Other implementations open only 188 * the X pointer and keyboard devices during server initialization, 189 * and only open other input devices when some client makes an 190 * XOpenDevice request. This entry point is for the latter type of 191 * implementation. 192 * 193 * If the physical device is not already open, do it here. In this case, 194 * you need to keep track of the fact that one or more clients has the 195 * device open, and physically close it when the last client that has 196 * it open does an XCloseDevice. 197 * 198 * The default implementation is to do nothing (assume all input devices 199 * are opened during X server initialization and kept open). 200 * 201 *********************************************************************** 202 */ 203 204void 205OpenInputDevice(DeviceIntPtr dev, 206 ClientPtr client, 207 int *status) 208{ 209 if (!dev->inited) 210 ActivateDevice(dev); 211 212 *status = Success; 213} 214 215void 216CloseInputDevice(DeviceIntPtr dev, 217 ClientPtr client) 218{ 219} 220 221/**************************************************************************** 222 * 223 * Caller: ProcXSetDeviceMode 224 * 225 * Change the mode of an extension device. 226 * This function is used to change the mode of a device from reporting 227 * relative motion to reporting absolute positional information, and 228 * vice versa. 229 * The default implementation below is that no such devices are supported. 230 * 231 *********************************************************************** 232 */ 233 234int 235SetDeviceMode (ClientPtr client, DeviceIntPtr dev, int mode) 236{ 237 LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate; 238 239 if (local->switch_mode) { 240 return (*local->switch_mode)(client, dev, mode); 241 } 242 else 243 return BadMatch; 244} 245 246 247/*********************************************************************** 248 * 249 * Caller: ProcXSetDeviceValuators 250 * 251 * Set the value of valuators on an extension input device. 252 * This function is used to set the initial value of valuators on 253 * those input devices that are capable of reporting either relative 254 * motion or an absolute position, and allow an initial position to be set. 255 * The default implementation below is that no such devices are supported. 256 * 257 *********************************************************************** 258 */ 259 260int 261SetDeviceValuators (ClientPtr client, DeviceIntPtr dev, int *valuators, 262 int first_valuator, int num_valuators) 263{ 264 LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate; 265 266 if (local->set_device_valuators) 267 return (*local->set_device_valuators)(local, valuators, first_valuator, 268 num_valuators); 269 270 return BadMatch; 271} 272 273 274/*********************************************************************** 275 * 276 * Caller: ProcXChangeDeviceControl 277 * 278 * Change the specified device controls on an extension input device. 279 * 280 *********************************************************************** 281 */ 282 283int 284ChangeDeviceControl (ClientPtr client, DeviceIntPtr dev, xDeviceCtl *control) 285{ 286 LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate; 287 288 if (!local->control_proc) { 289 switch (control->control) { 290 case DEVICE_CORE: 291 case DEVICE_RESOLUTION: 292 case DEVICE_ABS_CALIB: 293 case DEVICE_ABS_AREA: 294 case DEVICE_ENABLE: 295 return Success; 296 default: 297 return BadMatch; 298 } 299 } 300 else { 301 return (*local->control_proc)(local, control); 302 } 303} 304 305void 306AddOtherInputDevices() 307{ 308} 309#endif 310 311int 312NewInputDeviceRequest (InputOption *options, DeviceIntPtr *pdev) 313{ 314 IDevRec *idev = NULL; 315 InputDriverPtr drv = NULL; 316 InputInfoPtr pInfo = NULL; 317 InputOption *option = NULL; 318 DeviceIntPtr dev = NULL; 319 int rval = Success; 320 int is_auto = 0; 321 322 idev = xcalloc(sizeof(*idev), 1); 323 if (!idev) 324 return BadAlloc; 325 326 for (option = options; option; option = option->next) { 327 if (strcasecmp(option->key, "driver") == 0) { 328 if (idev->driver) { 329 rval = BadRequest; 330 goto unwind; 331 } 332 /* Memory leak for every attached device if we don't 333 * test if the module is already loaded first */ 334 drv = xf86LookupInputDriver(option->value); 335 if (!drv) 336 if (xf86LoadOneModule(option->value, NULL)) 337 drv = xf86LookupInputDriver(option->value); 338 if (!drv) { 339 xf86Msg(X_ERROR, "No input driver matching `%s'\n", 340 option->value); 341 rval = BadName; 342 goto unwind; 343 } 344 idev->driver = xstrdup(option->value); 345 if (!idev->driver) { 346 rval = BadAlloc; 347 goto unwind; 348 } 349 } 350 351 if (strcasecmp(option->key, "name") == 0 || 352 strcasecmp(option->key, "identifier") == 0) { 353 if (idev->identifier) { 354 rval = BadRequest; 355 goto unwind; 356 } 357 idev->identifier = xstrdup(option->value); 358 if (!idev->identifier) { 359 rval = BadAlloc; 360 goto unwind; 361 } 362 } 363 364 /* Right now, the only automatic config we know of is HAL. */ 365 if (strcmp(option->key, "_source") == 0 && 366 strcmp(option->value, "server/hal") == 0) { 367 if (!xf86Info.autoAddDevices) { 368 rval = BadMatch; 369 goto unwind; 370 } 371 372 is_auto = 1; 373 } 374 } 375 if (!idev->driver || !idev->identifier) { 376 xf86Msg(X_ERROR, "No input driver/identifier specified (ignoring)\n"); 377 rval = BadRequest; 378 goto unwind; 379 } 380 381 if (!drv->PreInit) { 382 xf86Msg(X_ERROR, 383 "Input driver `%s' has no PreInit function (ignoring)\n", 384 drv->driverName); 385 rval = BadImplementation; 386 goto unwind; 387 } 388 389 for (option = options; option; option = option->next) { 390 /* Steal option key/value strings from the provided list. 391 * We need those strings, the InputOption list doesn't. */ 392 idev->commonOptions = xf86addNewOption(idev->commonOptions, 393 option->key, option->value); 394 option->key = NULL; 395 option->value = NULL; 396 } 397 398 pInfo = drv->PreInit(drv, idev, 0); 399 400 if (!pInfo) { 401 xf86Msg(X_ERROR, "PreInit returned NULL for \"%s\"\n", idev->identifier); 402 rval = BadMatch; 403 goto unwind; 404 } 405 else if (!(pInfo->flags & XI86_CONFIGURED)) { 406 xf86Msg(X_ERROR, "PreInit failed for input device \"%s\"\n", 407 idev->identifier); 408 rval = BadMatch; 409 goto unwind; 410 } 411 412 xf86ActivateDevice(pInfo); 413 414 dev = pInfo->dev; 415 ActivateDevice(dev); 416 /* Enable it if it's properly initialised, we're currently in the VT, and 417 * either it's a manual request, or we're automatically enabling devices. */ 418 if (dev->inited && dev->startup && xf86Screens[0]->vtSema && 419 (!is_auto || xf86Info.autoEnableDevices)) 420 EnableDevice(dev); 421 422 *pdev = dev; 423 return Success; 424 425unwind: 426 if(pInfo) { 427 if(drv->UnInit) 428 drv->UnInit(drv, pInfo, 0); 429 else 430 xf86DeleteInput(pInfo, 0); 431 } 432 if(idev->driver) 433 xfree(idev->driver); 434 if(idev->identifier) 435 xfree(idev->identifier); 436 xf86optionListFree(idev->commonOptions); 437 xfree(idev); 438 return rval; 439} 440 441void 442DeleteInputDeviceRequest(DeviceIntPtr pDev) 443{ 444 LocalDevicePtr pInfo = (LocalDevicePtr) pDev->public.devicePrivate; 445 InputDriverPtr drv = pInfo->drv; 446 IDevRec *idev = pInfo->conf_idev; 447 448 RemoveDevice(pDev); 449 450 if(drv->UnInit) 451 drv->UnInit(drv, pInfo, 0); 452 else 453 xf86DeleteInput(pInfo, 0); 454 455 xfree(idev->driver); 456 xfree(idev->identifier); 457 xf86optionListFree(idev->commonOptions); 458 xfree(idev); 459} 460 461/* 462 * convenient functions to post events 463 */ 464 465_X_EXPORT void 466xf86PostMotionEvent(DeviceIntPtr device, 467 int is_absolute, 468 int first_valuator, 469 int num_valuators, 470 ...) 471{ 472 va_list var; 473 int i = 0; 474 static int *valuators = NULL; 475 static int n_valuators = 0; 476 477 if (num_valuators > n_valuators) { 478 xfree (valuators); 479 valuators = NULL; 480 } 481 482 if (!valuators) { 483 valuators = xcalloc(sizeof(int), num_valuators); 484 n_valuators = num_valuators; 485 } 486 487 va_start(var, num_valuators); 488 for (i = 0; i < num_valuators; i++) 489 valuators[i] = va_arg(var, int); 490 va_end(var); 491 492 xf86PostMotionEventP(device, is_absolute, first_valuator, num_valuators, valuators); 493} 494 495_X_EXPORT void 496xf86PostMotionEventP(DeviceIntPtr device, 497 int is_absolute, 498 int first_valuator, 499 int num_valuators, 500 int *valuators) 501{ 502 int i = 0, nevents = 0; 503 int dx, dy; 504 Bool drag = xf86SendDragEvents(device); 505 xEvent *xE = NULL; 506 int index; 507 int flags = 0; 508 509 if (is_absolute) 510 flags = POINTER_ABSOLUTE; 511 else 512 flags = POINTER_RELATIVE | POINTER_ACCELERATE; 513 514#if XFreeXDGA 515 if (first_valuator == 0 && num_valuators >= 2) { 516 if (miPointerGetScreen(inputInfo.pointer)) { 517 index = miPointerGetScreen(inputInfo.pointer)->myNum; 518 if (is_absolute) { 519 dx = valuators[0] - device->valuator->lastx; 520 dy = valuators[1] - device->valuator->lasty; 521 } 522 else { 523 dx = valuators[0]; 524 dy = valuators[1]; 525 } 526 if (DGAStealMotionEvent(index, dx, dy)) 527 return; 528 } 529 } 530#endif 531 532 if (!xf86Events) 533 xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); 534 if (!xf86Events) 535 FatalError("Couldn't allocate event store\n"); 536 537 nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0, 538 flags, first_valuator, num_valuators, 539 valuators); 540 541 for (i = 0; i < nevents; i++) { 542 xE = xf86Events + i; 543 /* Don't post core motion events for devices not registered to send 544 * drag events. */ 545 if (xE->u.u.type != MotionNotify || drag) { 546 mieqEnqueue(device, xf86Events + i); 547 } 548 } 549} 550 551_X_EXPORT void 552xf86PostProximityEvent(DeviceIntPtr device, 553 int is_in, 554 int first_valuator, 555 int num_valuators, 556 ...) 557{ 558 va_list var; 559 int i, nevents, *valuators = NULL; 560 561 valuators = xcalloc(sizeof(int), num_valuators); 562 563 va_start(var, num_valuators); 564 for (i = 0; i < num_valuators; i++) 565 valuators[i] = va_arg(var, int); 566 va_end(var); 567 568 if (!xf86Events) 569 xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); 570 if (!xf86Events) 571 FatalError("Couldn't allocate event store\n"); 572 573 nevents = GetProximityEvents(xf86Events, device, 574 is_in ? ProximityIn : ProximityOut, 575 first_valuator, num_valuators, valuators); 576 for (i = 0; i < nevents; i++) 577 mieqEnqueue(device, xf86Events + i); 578 579 xfree(valuators); 580} 581 582_X_EXPORT void 583xf86PostButtonEvent(DeviceIntPtr device, 584 int is_absolute, 585 int button, 586 int is_down, 587 int first_valuator, 588 int num_valuators, 589 ...) 590{ 591 va_list var; 592 int *valuators = NULL; 593 int i = 0, nevents = 0; 594 int index; 595 596#if XFreeXDGA 597 if (miPointerGetScreen(inputInfo.pointer)) { 598 index = miPointerGetScreen(inputInfo.pointer)->myNum; 599 if (DGAStealButtonEvent(index, button, is_down)) 600 return; 601 } 602#endif 603 604 valuators = xcalloc(sizeof(int), num_valuators); 605 606 va_start(var, num_valuators); 607 for (i = 0; i < num_valuators; i++) 608 valuators[i] = va_arg(var, int); 609 va_end(var); 610 611 if (!xf86Events) 612 xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); 613 if (!xf86Events) 614 FatalError("Couldn't allocate event store\n"); 615 616 nevents = GetPointerEvents(xf86Events, device, 617 is_down ? ButtonPress : ButtonRelease, button, 618 is_absolute ? POINTER_ABSOLUTE : 619 POINTER_RELATIVE, 620 first_valuator, num_valuators, valuators); 621 622 for (i = 0; i < nevents; i++) 623 mieqEnqueue(device, xf86Events + i); 624 625 xfree(valuators); 626} 627 628_X_EXPORT void 629xf86PostKeyEvent(DeviceIntPtr device, 630 unsigned int key_code, 631 int is_down, 632 int is_absolute, 633 int first_valuator, 634 int num_valuators, 635 ...) 636{ 637 va_list var; 638 int i = 0, nevents = 0, *valuators = NULL; 639 640 /* instil confidence in the user */ 641 DebugF("this function has never been tested properly. if things go quite " 642 "badly south after this message, then xf86PostKeyEvent is " 643 "broken.\n"); 644 645 if (!xf86Events) 646 xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); 647 if (!xf86Events) 648 FatalError("Couldn't allocate event store\n"); 649 650 if (is_absolute) { 651 valuators = xcalloc(sizeof(int), num_valuators); 652 va_start(var, num_valuators); 653 for (i = 0; i < num_valuators; i++) 654 valuators[i] = va_arg(var, int); 655 va_end(var); 656 657 nevents = GetKeyboardValuatorEvents(xf86Events, device, 658 is_down ? KeyPress : KeyRelease, 659 key_code, first_valuator, 660 num_valuators, valuators); 661 xfree(valuators); 662 } 663 else { 664 nevents = GetKeyboardEvents(xf86Events, device, 665 is_down ? KeyPress : KeyRelease, 666 key_code); 667 } 668 669 for (i = 0; i < nevents; i++) 670 mieqEnqueue(device, xf86Events + i); 671} 672 673_X_EXPORT void 674xf86PostKeyboardEvent(DeviceIntPtr device, 675 unsigned int key_code, 676 int is_down) 677{ 678 int nevents = 0, i = 0; 679 int index; 680 681#if XFreeXDGA 682 if (miPointerGetScreen(inputInfo.pointer)) { 683 index = miPointerGetScreen(inputInfo.pointer)->myNum; 684 if (DGAStealKeyEvent(index, key_code, is_down)) 685 return; 686 } 687#endif 688 689 if (!xf86Events) 690 xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); 691 if (!xf86Events) 692 FatalError("Couldn't allocate event store\n"); 693 694 nevents = GetKeyboardEvents(xf86Events, device, 695 is_down ? KeyPress : KeyRelease, key_code); 696 697 for (i = 0; i < nevents; i++) 698 mieqEnqueue(device, xf86Events + i); 699} 700 701_X_EXPORT LocalDevicePtr 702xf86FirstLocalDevice() 703{ 704 return xf86InputDevs; 705} 706 707/* 708 * Cx - raw data from touch screen 709 * Sxhigh - scaled highest dimension 710 * (remember, this is of rows - 1 because of 0 origin) 711 * Sxlow - scaled lowest dimension 712 * Rxhigh - highest raw value from touch screen calibration 713 * Rxlow - lowest raw value from touch screen calibration 714 * 715 * This function is the same for X or Y coordinates. 716 * You may have to reverse the high and low values to compensate for 717 * different orgins on the touch screen vs X. 718 */ 719 720_X_EXPORT int 721xf86ScaleAxis(int Cx, 722 int Sxhigh, 723 int Sxlow, 724 int Rxhigh, 725 int Rxlow ) 726{ 727 int X; 728 int dSx = Sxhigh - Sxlow; 729 int dRx = Rxhigh - Rxlow; 730 731 dSx = Sxhigh - Sxlow; 732 if (dRx) { 733 X = ((dSx * (Cx - Rxlow)) / dRx) + Sxlow; 734 } 735 else { 736 X = 0; 737 ErrorF ("Divide by Zero in xf86ScaleAxis"); 738 } 739 740 if (X > Sxlow) 741 X = Sxlow; 742 if (X < Sxhigh) 743 X = Sxhigh; 744 745 return (X); 746} 747 748/* 749 * This function checks the given screen against the current screen and 750 * makes changes if appropriate. It should be called from an XInput driver's 751 * ReadInput function before any events are posted, if the device is screen 752 * specific like a touch screen. 753 */ 754_X_EXPORT void 755xf86XInputSetScreen(LocalDevicePtr local, 756 int screen_number, 757 int x, 758 int y) 759{ 760 if (miPointerGetScreen(local->dev) != 761 screenInfo.screens[screen_number]) { 762 miPointerSetScreen(local->dev, screen_number, x, y); 763 } 764} 765 766 767_X_EXPORT void 768xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, int minval, int maxval, 769 int resolution, int min_res, int max_res) 770{ 771 if (!dev || !dev->valuator) 772 return; 773 774 InitValuatorAxisStruct(dev, axnum, minval, maxval, resolution, min_res, 775 max_res); 776} 777 778/* 779 * Set the valuator values to be in synch with dix/event.c 780 * DefineInitialRootWindow(). 781 */ 782_X_EXPORT void 783xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum) 784{ 785 if (axnum == 0) { 786 dev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2; 787 dev->valuator->lastx = dev->valuator->axisVal[0]; 788 } 789 else if (axnum == 1) { 790 dev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2; 791 dev->valuator->lasty = dev->valuator->axisVal[1]; 792 } 793} 794 795 796/** 797 * Deactivate a device. Call this function from the driver if you receive a 798 * read error or something else that spoils your day. 799 * Device will be moved to the off_devices list, but it will still be there 800 * until you really clean up after it. 801 * Notifies the client about an inactive device. 802 * 803 * @param panic True if device is unrecoverable and needs to be removed. 804 */ 805_X_EXPORT void 806xf86DisableDevice(DeviceIntPtr dev, Bool panic) 807{ 808 devicePresenceNotify ev; 809 DeviceIntRec dummyDev; 810 811 if(!panic) 812 { 813 DisableDevice(dev); 814 } else 815 { 816 ev.type = DevicePresenceNotify; 817 ev.time = currentTime.milliseconds; 818 ev.devchange = DeviceUnrecoverable; 819 ev.deviceid = dev->id; 820 dummyDev.id = 0; 821 SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask, 822 (xEvent *) &ev, 1); 823 824 DeleteInputDeviceRequest(dev); 825 } 826} 827 828/** 829 * Reactivate a device. Call this function from the driver if you just found 830 * out that the read error wasn't quite that bad after all. 831 * Device will be re-activated, and an event sent to the client. 832 */ 833_X_EXPORT void 834xf86EnableDevice(DeviceIntPtr dev) 835{ 836 EnableDevice(dev); 837} 838 839/* end of xf86Xinput.c */ 840