xf86Xinput.c revision 4642e01f
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#include <X11/extensions/XI.h> 56#include <X11/extensions/XIproto.h> 57#include "xf86.h" 58#include "xf86Priv.h" 59#include "xf86Xinput.h" 60#include "XIstubs.h" 61#include "xf86Optrec.h" 62#include "mipointer.h" 63#include "xf86InPriv.h" 64#include "compiler.h" 65#include "extinit.h" 66 67#ifdef DPMSExtension 68#define DPMS_SERVER 69#include <X11/extensions/dpms.h> 70#include "dpmsproc.h" 71#endif 72 73#include "exevents.h" /* AddInputDevice */ 74#include "exglobals.h" 75 76#define EXTENSION_PROC_ARGS void * 77#include "extnsionst.h" 78 79#include "windowstr.h" /* screenIsSaved */ 80 81#include <stdarg.h> 82 83#include <X11/Xpoll.h> 84 85#include "mi.h" 86 87#include <ptrveloc.h> /* dix pointer acceleration */ 88 89#ifdef XFreeXDGA 90#include "dgaproc.h" 91#endif 92 93#ifdef XKB 94#include "xkbsrv.h" 95#endif 96 97#include "os.h" 98 99EventListPtr xf86Events = NULL; 100 101/** 102 * Eval config and modify DeviceVelocityRec accordingly 103 */ 104static void 105ProcessVelocityConfiguration(char* devname, pointer list, DeviceVelocityPtr s){ 106 int tempi, i; 107 float tempf, tempf2; 108 109 if(!s) 110 return; 111 112 tempf = xf86SetRealOption(list, "FilterHalflife", -1); 113 if(tempf > 0) 114 tempf = 1.0 / tempf; /* set reciprocal if possible */ 115 116 tempf2 = xf86SetRealOption(list, "FilterChainProgression", 2.0); 117 xf86Msg(X_CONFIG, "%s: (accel) filter chain progression: %.2f\n", 118 devname, tempf2); 119 if(tempf2 < 1) 120 tempf2 = 2; 121 122 tempi = xf86SetIntOption(list, "FilterChainLength", 1); 123 if(tempi < 1 || tempi > MAX_VELOCITY_FILTERS) 124 tempi = 1; 125 126 if(tempf > 0.0f && tempi >= 1 && tempf2 >= 1.0f) 127 InitFilterChain(s, tempf, tempf2, tempi, 40); 128 129 for(i = 0; i < tempi; i++) 130 xf86Msg(X_CONFIG, "%s: (accel) filter stage %i: %.2f ms\n", 131 devname, i, 1.0f / (s->filters[i].rdecay)); 132 133 tempf = xf86SetRealOption(list, "ConstantDeceleration", 1.0); 134 if(tempf > 1.0){ 135 xf86Msg(X_CONFIG, "%s: (accel) constant deceleration by %.1f\n", 136 devname, tempf); 137 s->const_acceleration = 1.0 / tempf; /* set reciprocal deceleration 138 alias acceleration */ 139 } 140 141 tempf = xf86SetRealOption(list, "AdaptiveDeceleration", 1.0); 142 if(tempf > 1.0){ 143 xf86Msg(X_CONFIG, "%s: (accel) adaptive deceleration by %.1f\n", 144 devname, tempf); 145 s->min_acceleration = 1.0 / tempf; /* set minimum acceleration */ 146 } 147 148 tempf = xf86SetRealOption(list, "VelocityCoupling", -1); 149 if(tempf >= 0){ 150 xf86Msg(X_CONFIG, "%s: (accel) velocity coupling is %.1f%%\n", devname, 151 tempf*100.0); 152 s->coupling = tempf; 153 } 154 155 /* Configure softening. If const deceleration is used, this is expected 156 * to provide better subpixel information so we enable 157 * softening by default only if ConstantDeceleration is not used 158 */ 159 s->use_softening = xf86SetBoolOption(list, "Softening", 160 s->const_acceleration == 1.0); 161 162 s->average_accel = xf86SetBoolOption(list, "AccelerationProfileAveraging", 163 s->average_accel); 164 165 s->reset_time = xf86SetIntOption(list, "VelocityReset", s->reset_time); 166 167 tempf = xf86SetRealOption(list, "ExpectedRate", 0); 168 if(tempf > 0){ 169 s->corr_mul = 1000.0 / tempf; 170 }else{ 171 s->corr_mul = xf86SetRealOption(list, "VelocityScale", s->corr_mul); 172 } 173 174 /* select profile by number */ 175 tempi= xf86SetIntOption(list, "AccelerationProfile", 176 s->statistics.profile_number); 177 178 if(SetAccelerationProfile(s, tempi)){ 179 xf86Msg(X_CONFIG, "%s: (accel) set acceleration profile %i\n", devname, tempi); 180 }else{ 181 xf86Msg(X_CONFIG, "%s: (accel) acceleration profile %i is unknown\n", 182 devname, tempi); 183 } 184} 185 186static void 187ApplyAccelerationSettings(DeviceIntPtr dev){ 188 int scheme; 189 DeviceVelocityPtr pVel; 190 LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate; 191 char* schemeStr; 192 193 if(dev->valuator){ 194 schemeStr = xf86SetStrOption(local->options, "AccelerationScheme", ""); 195 196 scheme = dev->valuator->accelScheme.number; 197 198 if(!xf86NameCmp(schemeStr, "predictable")) 199 scheme = PtrAccelPredictable; 200 201 if(!xf86NameCmp(schemeStr, "lightweight")) 202 scheme = PtrAccelLightweight; 203 204 if(!xf86NameCmp(schemeStr, "none")) 205 scheme = PtrAccelNoOp; 206 207 /* reinit scheme if needed */ 208 if(dev->valuator->accelScheme.number != scheme){ 209 if(dev->valuator->accelScheme.AccelCleanupProc){ 210 dev->valuator->accelScheme.AccelCleanupProc(dev); 211 } 212 213 if(InitPointerAccelerationScheme(dev, scheme)){ 214 xf86Msg(X_CONFIG, "%s: (accel) selected scheme %s/%i\n", 215 local->name, schemeStr, scheme); 216 }else{ 217 xf86Msg(X_CONFIG, "%s: (accel) could not init scheme %s\n", 218 local->name, schemeStr); 219 scheme = dev->valuator->accelScheme.number; 220 } 221 }else{ 222 xf86Msg(X_CONFIG, "%s: (accel) keeping acceleration scheme %i\n", 223 local->name, scheme); 224 } 225 226 xfree(schemeStr); 227 228 /* process special configuration */ 229 switch(scheme){ 230 case PtrAccelPredictable: 231 pVel = GetDevicePredictableAccelData(dev); 232 ProcessVelocityConfiguration (local->name, local->options, 233 pVel); 234 break; 235 } 236 } 237} 238 239static Bool 240xf86SendDragEvents(DeviceIntPtr device) 241{ 242 LocalDevicePtr local = (LocalDevicePtr) device->public.devicePrivate; 243 244 if (device->button && device->button->buttonsDown > 0) 245 return (local->flags & XI86_SEND_DRAG_EVENTS); 246 else 247 return (TRUE); 248} 249 250/*********************************************************************** 251 * 252 * xf86ProcessCommonOptions -- 253 * 254 * Process global options. 255 * 256 *********************************************************************** 257 */ 258_X_EXPORT void 259xf86ProcessCommonOptions(LocalDevicePtr local, 260 pointer list) 261{ 262 if (!xf86SetBoolOption(list, "AlwaysCore", 1) || 263 !xf86SetBoolOption(list, "SendCoreEvents", 1) || 264 !xf86SetBoolOption(list, "CorePointer", 1) || 265 !xf86SetBoolOption(list, "CoreKeyboard", 1)) { 266 xf86Msg(X_CONFIG, "%s: doesn't report core events\n", local->name); 267 } else { 268 local->flags |= XI86_ALWAYS_CORE; 269 xf86Msg(X_CONFIG, "%s: always reports core events\n", local->name); 270 } 271 272 if (xf86SetBoolOption(list, "SendDragEvents", 1)) { 273 local->flags |= XI86_SEND_DRAG_EVENTS; 274 } else { 275 xf86Msg(X_CONFIG, "%s: doesn't report drag events\n", local->name); 276 } 277 278 /* Backwards compatibility. */ 279 local->history_size = GetMotionHistorySize(); 280 /* Preallocate xEvent store */ 281 if (!xf86Events) 282 GetEventList(&xf86Events); 283 if (!xf86Events) 284 FatalError("Couldn't allocate event store\n"); 285} 286 287/*********************************************************************** 288 * 289 * xf86ActivateDevice -- 290 * 291 * Initialize an input device. 292 * 293 * Returns TRUE on success, or FALSE otherwise. 294 *********************************************************************** 295 */ 296_X_EXPORT int 297xf86ActivateDevice(LocalDevicePtr local) 298{ 299 DeviceIntPtr dev; 300 301 if (local->flags & XI86_CONFIGURED) { 302 dev = AddInputDevice(serverClient, local->device_control, TRUE); 303 304 if (dev == NULL) 305 { 306 xf86Msg(X_ERROR, "Too many input devices. Ignoring %s\n", 307 local->name); 308 local->dev = NULL; 309 return FALSE; 310 } 311 312 local->atom = MakeAtom(local->type_name, 313 strlen(local->type_name), 314 TRUE); 315 AssignTypeAndName(dev, local->atom, local->name); 316 dev->public.devicePrivate = (pointer) local; 317 local->dev = dev; 318 319 dev->coreEvents = local->flags & XI86_ALWAYS_CORE; 320 dev->isMaster = FALSE; 321 dev->spriteInfo->spriteOwner = FALSE; 322 323 if (DeviceIsPointerType(dev)) 324 { 325 dev->deviceGrab.ActivateGrab = ActivatePointerGrab; 326 dev->deviceGrab.DeactivateGrab = DeactivatePointerGrab; 327 } else 328 { 329 dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab; 330 dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab; 331 } 332 333 RegisterOtherDevice(dev); 334#ifdef XKB 335 if (!noXkbExtension) 336 XkbSetExtension(dev, ProcessKeyboardEvent); 337#endif 338 339 if (serverGeneration == 1) 340 xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n", 341 local->name, local->type_name); 342 } 343 344 return TRUE; 345} 346 347 348/*********************************************************************** 349 * 350 * Caller: ProcXOpenDevice 351 * 352 * This is the implementation-dependent routine to open an input device. 353 * Some implementations open all input devices when the server is first 354 * initialized, and never close them. Other implementations open only 355 * the X pointer and keyboard devices during server initialization, 356 * and only open other input devices when some client makes an 357 * XOpenDevice request. This entry point is for the latter type of 358 * implementation. 359 * 360 * If the physical device is not already open, do it here. In this case, 361 * you need to keep track of the fact that one or more clients has the 362 * device open, and physically close it when the last client that has 363 * it open does an XCloseDevice. 364 * 365 * The default implementation is to do nothing (assume all input devices 366 * are opened during X server initialization and kept open). 367 * 368 *********************************************************************** 369 */ 370 371void 372OpenInputDevice(DeviceIntPtr dev, 373 ClientPtr client, 374 int *status) 375{ 376 if (!dev->inited) 377 ActivateDevice(dev); 378 379 *status = Success; 380} 381 382void 383CloseInputDevice(DeviceIntPtr dev, 384 ClientPtr client) 385{ 386} 387 388/**************************************************************************** 389 * 390 * Caller: ProcXSetDeviceMode 391 * 392 * Change the mode of an extension device. 393 * This function is used to change the mode of a device from reporting 394 * relative motion to reporting absolute positional information, and 395 * vice versa. 396 * The default implementation below is that no such devices are supported. 397 * 398 *********************************************************************** 399 */ 400 401int 402SetDeviceMode (ClientPtr client, DeviceIntPtr dev, int mode) 403{ 404 LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate; 405 406 if (local->switch_mode) { 407 return (*local->switch_mode)(client, dev, mode); 408 } 409 else 410 return BadMatch; 411} 412 413 414/*********************************************************************** 415 * 416 * Caller: ProcXSetDeviceValuators 417 * 418 * Set the value of valuators on an extension input device. 419 * This function is used to set the initial value of valuators on 420 * those input devices that are capable of reporting either relative 421 * motion or an absolute position, and allow an initial position to be set. 422 * The default implementation below is that no such devices are supported. 423 * 424 *********************************************************************** 425 */ 426 427int 428SetDeviceValuators (ClientPtr client, DeviceIntPtr dev, int *valuators, 429 int first_valuator, int num_valuators) 430{ 431 LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate; 432 433 if (local->set_device_valuators) 434 return (*local->set_device_valuators)(local, valuators, first_valuator, 435 num_valuators); 436 437 return BadMatch; 438} 439 440 441/*********************************************************************** 442 * 443 * Caller: ProcXChangeDeviceControl 444 * 445 * Change the specified device controls on an extension input device. 446 * 447 *********************************************************************** 448 */ 449 450int 451ChangeDeviceControl (ClientPtr client, DeviceIntPtr dev, xDeviceCtl *control) 452{ 453 LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate; 454 455 if (!local->control_proc) { 456 switch (control->control) { 457 case DEVICE_CORE: 458 return BadMatch; 459 case DEVICE_RESOLUTION: 460 case DEVICE_ABS_CALIB: 461 case DEVICE_ABS_AREA: 462 case DEVICE_ENABLE: 463 return Success; 464 default: 465 return BadMatch; 466 } 467 } 468 else { 469 return (*local->control_proc)(local, control); 470 } 471} 472 473void 474AddOtherInputDevices() 475{ 476} 477 478/** 479 * Create a new input device, activate and enable it. 480 * 481 * Possible return codes: 482 * BadName .. a bad driver name was supplied. 483 * BadImplementation ... The driver does not have a PreInit function. This 484 * is a driver bug. 485 * BadMatch .. device initialization failed. 486 * BadAlloc .. too many input devices 487 * 488 * @param idev The device, already set up with identifier, driver, and the 489 * options. 490 * @param pdev Pointer to the new device, if Success was reported. 491 * @param enable Enable the device after activating it. 492 * 493 * @return Success or an error code 494 */ 495_X_INTERNAL int 496xf86NewInputDevice(IDevPtr idev, DeviceIntPtr *pdev, BOOL enable) 497{ 498 InputDriverPtr drv = NULL; 499 InputInfoPtr pInfo = NULL; 500 DeviceIntPtr dev = NULL; 501 int rval; 502 503 /* Memory leak for every attached device if we don't 504 * test if the module is already loaded first */ 505 drv = xf86LookupInputDriver(idev->driver); 506 if (!drv) 507 if (xf86LoadOneModule(idev->driver, NULL)) 508 drv = xf86LookupInputDriver(idev->driver); 509 if (!drv) { 510 xf86Msg(X_ERROR, "No input driver matching `%s'\n", idev->driver); 511 rval = BadName; 512 goto unwind; 513 } 514 515 if (!drv->PreInit) { 516 xf86Msg(X_ERROR, 517 "Input driver `%s' has no PreInit function (ignoring)\n", 518 drv->driverName); 519 rval = BadImplementation; 520 goto unwind; 521 } 522 523 pInfo = drv->PreInit(drv, idev, 0); 524 525 if (!pInfo) { 526 xf86Msg(X_ERROR, "PreInit returned NULL for \"%s\"\n", idev->identifier); 527 rval = BadMatch; 528 goto unwind; 529 } 530 else if (!(pInfo->flags & XI86_CONFIGURED)) { 531 xf86Msg(X_ERROR, "PreInit failed for input device \"%s\"\n", 532 idev->identifier); 533 rval = BadMatch; 534 goto unwind; 535 } 536 537 if (!xf86ActivateDevice(pInfo)) 538 { 539 rval = BadAlloc; 540 goto unwind; 541 } 542 543 dev = pInfo->dev; 544 rval = ActivateDevice(dev); 545 if (rval != Success) 546 { 547 xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", idev->identifier); 548 RemoveDevice(dev); 549 goto unwind; 550 } 551 552 /* Enable it if it's properly initialised and we're currently in the VT */ 553 if (enable && dev->inited && dev->startup && xf86Screens[0]->vtSema) 554 { 555 EnableDevice(dev); 556 /* send enter/leave event, update sprite window */ 557 CheckMotion(NULL, dev); 558 } 559 560 *pdev = dev; 561 return Success; 562 563unwind: 564 if(pInfo) { 565 if(drv->UnInit) 566 drv->UnInit(drv, pInfo, 0); 567 else 568 xf86DeleteInput(pInfo, 0); 569 } 570 return rval; 571} 572 573_X_EXPORT int 574NewInputDeviceRequest (InputOption *options, DeviceIntPtr *pdev) 575{ 576 IDevRec *idev = NULL; 577 InputOption *option = NULL; 578 int rval = Success; 579 int is_auto = 0; 580 581 idev = xcalloc(sizeof(*idev), 1); 582 if (!idev) 583 return BadAlloc; 584 585 for (option = options; option; option = option->next) { 586 if (strcasecmp(option->key, "driver") == 0) { 587 if (idev->driver) { 588 rval = BadRequest; 589 goto unwind; 590 } 591 idev->driver = xstrdup(option->value); 592 if (!idev->driver) { 593 rval = BadAlloc; 594 goto unwind; 595 } 596 } 597 598 if (strcasecmp(option->key, "name") == 0 || 599 strcasecmp(option->key, "identifier") == 0) { 600 if (idev->identifier) { 601 rval = BadRequest; 602 goto unwind; 603 } 604 idev->identifier = xstrdup(option->value); 605 if (!idev->identifier) { 606 rval = BadAlloc; 607 goto unwind; 608 } 609 } 610 611 /* Right now, the only automatic config we know of is HAL. */ 612 if (strcmp(option->key, "_source") == 0 && 613 strcmp(option->value, "server/hal") == 0) { 614 if (!xf86Info.autoAddDevices) { 615 rval = BadMatch; 616 goto unwind; 617 } 618 619 is_auto = 1; 620 } 621 } 622 if (!idev->driver || !idev->identifier) { 623 xf86Msg(X_ERROR, "No input driver/identifier specified (ignoring)\n"); 624 rval = BadRequest; 625 goto unwind; 626 } 627 628 if (!idev->identifier) { 629 xf86Msg(X_ERROR, "No device identifier specified (ignoring)\n"); 630 return BadMatch; 631 } 632 633 for (option = options; option; option = option->next) { 634 /* Steal option key/value strings from the provided list. 635 * We need those strings, the InputOption list doesn't. */ 636 idev->commonOptions = xf86addNewOption(idev->commonOptions, 637 option->key, option->value); 638 option->key = NULL; 639 option->value = NULL; 640 } 641 642 rval = xf86NewInputDevice(idev, pdev, 643 (!is_auto || (is_auto && xf86Info.autoEnableDevices))); 644 if (rval == Success) 645 return Success; 646 647unwind: 648 if(idev->driver) 649 xfree(idev->driver); 650 if(idev->identifier) 651 xfree(idev->identifier); 652 xf86optionListFree(idev->commonOptions); 653 xfree(idev); 654 return rval; 655} 656 657_X_EXPORT void 658DeleteInputDeviceRequest(DeviceIntPtr pDev) 659{ 660 LocalDevicePtr pInfo = (LocalDevicePtr) pDev->public.devicePrivate; 661 InputDriverPtr drv = NULL; 662 IDevRec *idev = NULL; 663 IDevPtr *it; 664 Bool isMaster = pDev->isMaster; 665 666 if (pInfo) /* need to get these before RemoveDevice */ 667 { 668 drv = pInfo->drv; 669 idev = pInfo->conf_idev; 670 } 671 672 OsBlockSignals(); 673 RemoveDevice(pDev); 674 675 if (!isMaster) 676 { 677 if(drv->UnInit) 678 drv->UnInit(drv, pInfo, 0); 679 else 680 xf86DeleteInput(pInfo, 0); 681 682 /* devices added through HAL aren't in the config layout */ 683 it = xf86ConfigLayout.inputs; 684 while(*it && *it != idev) 685 it++; 686 687 if (!(*it)) /* end of list, not in the layout */ 688 { 689 xfree(idev->driver); 690 xfree(idev->identifier); 691 xf86optionListFree(idev->commonOptions); 692 xfree(idev); 693 } 694 } 695 OsReleaseSignals(); 696} 697 698/* 699 * convenient functions to post events 700 */ 701 702_X_EXPORT void 703xf86PostMotionEvent(DeviceIntPtr device, 704 int is_absolute, 705 int first_valuator, 706 int num_valuators, 707 ...) 708{ 709 va_list var; 710 int i = 0; 711 static int valuators[MAX_VALUATORS]; 712 713 if (num_valuators > MAX_VALUATORS) { 714 xf86Msg(X_ERROR, "%s: num_valuator %d is greater than" 715 " MAX_VALUATORS\n", __FUNCTION__, num_valuators); 716 return; 717 } 718 719 va_start(var, num_valuators); 720 for (i = 0; i < num_valuators; i++) 721 valuators[i] = va_arg(var, int); 722 va_end(var); 723 724 xf86PostMotionEventP(device, is_absolute, first_valuator, num_valuators, valuators); 725} 726 727_X_EXPORT void 728xf86PostMotionEventP(DeviceIntPtr device, 729 int is_absolute, 730 int first_valuator, 731 int num_valuators, 732 int *valuators) 733{ 734 int i = 0, nevents = 0; 735 int dx = 0, dy = 0; 736 Bool drag = xf86SendDragEvents(device); 737 xEvent *xE = NULL; 738 int index; 739 int flags = 0; 740 741 if (num_valuators > MAX_VALUATORS) { 742 xf86Msg(X_ERROR, "%s: num_valuator %d is greater than" 743 " MAX_VALUATORS\n", __FUNCTION__, num_valuators); 744 return; 745 } 746 747 if (is_absolute) 748 flags = POINTER_ABSOLUTE; 749 else 750 flags = POINTER_RELATIVE | POINTER_ACCELERATE; 751 752#if XFreeXDGA 753 /* The evdev driver may not always send all axes across. */ 754 if (num_valuators >= 1 && first_valuator <= 1) { 755 if (miPointerGetScreen(device)) { 756 index = miPointerGetScreen(device)->myNum; 757 if (first_valuator == 0) 758 { 759 dx = valuators[0]; 760 if (is_absolute) 761 dx -= device->last.valuators[0]; 762 } 763 764 if (first_valuator == 1 || num_valuators >= 2) 765 { 766 dy = valuators[1 - first_valuator]; 767 if (is_absolute) 768 dy -= device->last.valuators[1]; 769 } 770 771 if (DGAStealMotionEvent(device, index, dx, dy)) 772 return; 773 } 774 } 775#endif 776 777 GetEventList(&xf86Events); 778 nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0, 779 flags, first_valuator, num_valuators, 780 valuators); 781 782 for (i = 0; i < nevents; i++) { 783 xE = (xf86Events + i)->event; 784 /* Don't post core motion events for devices not registered to send 785 * drag events. */ 786 if (xE->u.u.type != MotionNotify || drag) { 787 mieqEnqueue(device, (xf86Events + i)->event); 788 } 789 } 790} 791 792_X_EXPORT void 793xf86PostProximityEvent(DeviceIntPtr device, 794 int is_in, 795 int first_valuator, 796 int num_valuators, 797 ...) 798{ 799 va_list var; 800 int i, nevents; 801 int valuators[MAX_VALUATORS]; 802 803 804 if (num_valuators > MAX_VALUATORS) { 805 xf86Msg(X_ERROR, "%s: num_valuator %d is greater than" 806 " MAX_VALUATORS\n", __FUNCTION__, num_valuators); 807 return; 808 } 809 810 va_start(var, num_valuators); 811 for (i = 0; i < num_valuators; i++) 812 valuators[i] = va_arg(var, int); 813 va_end(var); 814 815 GetEventList(&xf86Events); 816 nevents = GetProximityEvents(xf86Events, device, 817 is_in ? ProximityIn : ProximityOut, 818 first_valuator, num_valuators, valuators); 819 for (i = 0; i < nevents; i++) 820 mieqEnqueue(device, (xf86Events + i)->event); 821 822} 823 824_X_EXPORT void 825xf86PostButtonEvent(DeviceIntPtr device, 826 int is_absolute, 827 int button, 828 int is_down, 829 int first_valuator, 830 int num_valuators, 831 ...) 832{ 833 va_list var; 834 int valuators[MAX_VALUATORS]; 835 int i = 0, nevents = 0; 836 int index; 837 838#if XFreeXDGA 839 if (miPointerGetScreen(device)) { 840 index = miPointerGetScreen(device)->myNum; 841 if (DGAStealButtonEvent(device, index, button, is_down)) 842 return; 843 } 844#endif 845 if (num_valuators > MAX_VALUATORS) { 846 xf86Msg(X_ERROR, "%s: num_valuator %d is greater than" 847 " MAX_VALUATORS\n", __FUNCTION__, num_valuators); 848 return; 849 } 850 851 va_start(var, num_valuators); 852 for (i = 0; i < num_valuators; i++) 853 valuators[i] = va_arg(var, int); 854 va_end(var); 855 856 GetEventList(&xf86Events); 857 nevents = GetPointerEvents(xf86Events, device, 858 is_down ? ButtonPress : ButtonRelease, button, 859 (is_absolute) ? POINTER_ABSOLUTE : POINTER_RELATIVE, 860 first_valuator, num_valuators, valuators); 861 862 for (i = 0; i < nevents; i++) 863 mieqEnqueue(device, (xf86Events + i)->event); 864 865} 866 867_X_EXPORT void 868xf86PostKeyEvent(DeviceIntPtr device, 869 unsigned int key_code, 870 int is_down, 871 int is_absolute, 872 int first_valuator, 873 int num_valuators, 874 ...) 875{ 876 va_list var; 877 int i = 0, nevents = 0; 878 static int valuators[MAX_VALUATORS]; 879 880 /* instil confidence in the user */ 881 DebugF("this function has never been tested properly. if things go quite " 882 "badly south after this message, then xf86PostKeyEvent is " 883 "broken.\n"); 884 885 if (num_valuators > MAX_VALUATORS) { 886 xf86Msg(X_ERROR, "%s: num_valuator %d is greater than" 887 " MAX_VALUATORS\n", __FUNCTION__, num_valuators); 888 return; 889 } 890 891 if (is_absolute) { 892 va_start(var, num_valuators); 893 for (i = 0; i < num_valuators; i++) 894 valuators[i] = va_arg(var, int); 895 va_end(var); 896 897 GetEventList(&xf86Events); 898 nevents = GetKeyboardValuatorEvents(xf86Events, device, 899 is_down ? KeyPress : KeyRelease, 900 key_code, first_valuator, 901 num_valuators, valuators); 902 } 903 else { 904 nevents = GetKeyboardEvents(xf86Events, device, 905 is_down ? KeyPress : KeyRelease, 906 key_code); 907 } 908 909 for (i = 0; i < nevents; i++) 910 mieqEnqueue(device, (xf86Events + i)->event); 911} 912 913_X_EXPORT void 914xf86PostKeyboardEvent(DeviceIntPtr device, 915 unsigned int key_code, 916 int is_down) 917{ 918 int nevents = 0, i = 0; 919 int index; 920 921#if XFreeXDGA 922 DeviceIntPtr pointer; 923 924 /* Some pointers send key events, paired device is wrong then. */ 925 pointer = IsPointerDevice(device) ? device : GetPairedDevice(device); 926 927 if (miPointerGetScreen(pointer)) { 928 index = miPointerGetScreen(pointer)->myNum; 929 if (DGAStealKeyEvent(device, index, key_code, is_down)) 930 return; 931 } 932#endif 933 934 GetEventList(&xf86Events); 935 nevents = GetKeyboardEvents(xf86Events, device, 936 is_down ? KeyPress : KeyRelease, key_code); 937 938 for (i = 0; i < nevents; i++) 939 mieqEnqueue(device, (xf86Events + i)->event); 940} 941 942_X_EXPORT LocalDevicePtr 943xf86FirstLocalDevice() 944{ 945 return xf86InputDevs; 946} 947 948/* 949 * Cx - raw data from touch screen 950 * Sxhigh - scaled highest dimension 951 * (remember, this is of rows - 1 because of 0 origin) 952 * Sxlow - scaled lowest dimension 953 * Rxhigh - highest raw value from touch screen calibration 954 * Rxlow - lowest raw value from touch screen calibration 955 * 956 * This function is the same for X or Y coordinates. 957 * You may have to reverse the high and low values to compensate for 958 * different orgins on the touch screen vs X. 959 */ 960 961_X_EXPORT int 962xf86ScaleAxis(int Cx, 963 int Sxhigh, 964 int Sxlow, 965 int Rxhigh, 966 int Rxlow ) 967{ 968 int X; 969 int dSx = Sxhigh - Sxlow; 970 int dRx = Rxhigh - Rxlow; 971 972 dSx = Sxhigh - Sxlow; 973 if (dRx) { 974 X = ((dSx * (Cx - Rxlow)) / dRx) + Sxlow; 975 } 976 else { 977 X = 0; 978 ErrorF ("Divide by Zero in xf86ScaleAxis"); 979 } 980 981 if (X > Sxhigh) 982 X = Sxhigh; 983 if (X < Sxlow) 984 X = Sxlow; 985 986 return (X); 987} 988 989/* 990 * This function checks the given screen against the current screen and 991 * makes changes if appropriate. It should be called from an XInput driver's 992 * ReadInput function before any events are posted, if the device is screen 993 * specific like a touch screen. 994 */ 995_X_EXPORT void 996xf86XInputSetScreen(LocalDevicePtr local, 997 int screen_number, 998 int x, 999 int y) 1000{ 1001 if (miPointerGetScreen(local->dev) != 1002 screenInfo.screens[screen_number]) { 1003 miPointerSetScreen(local->dev, screen_number, x, y); 1004 } 1005} 1006 1007 1008_X_EXPORT void 1009xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, int minval, int maxval, 1010 int resolution, int min_res, int max_res) 1011{ 1012 if (!dev || !dev->valuator) 1013 return; 1014 1015 InitValuatorAxisStruct(dev, axnum, minval, maxval, resolution, min_res, 1016 max_res); 1017} 1018 1019/* 1020 * Set the valuator values to be in synch with dix/event.c 1021 * DefineInitialRootWindow(). 1022 */ 1023_X_EXPORT void 1024xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum) 1025{ 1026 if (axnum == 0) { 1027 dev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2; 1028 dev->last.valuators[0] = dev->valuator->axisVal[0]; 1029 } 1030 else if (axnum == 1) { 1031 dev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2; 1032 dev->last.valuators[1] = dev->valuator->axisVal[1]; 1033 } 1034 1035 if(axnum == 0) /* to prevent double invocation */ 1036 ApplyAccelerationSettings(dev); 1037} 1038 1039 1040/** 1041 * Deactivate a device. Call this function from the driver if you receive a 1042 * read error or something else that spoils your day. 1043 * Device will be moved to the off_devices list, but it will still be there 1044 * until you really clean up after it. 1045 * Notifies the client about an inactive device. 1046 * 1047 * @param panic True if device is unrecoverable and needs to be removed. 1048 */ 1049_X_EXPORT void 1050xf86DisableDevice(DeviceIntPtr dev, Bool panic) 1051{ 1052 devicePresenceNotify ev; 1053 DeviceIntRec dummyDev; 1054 1055 if(!panic) 1056 { 1057 DisableDevice(dev); 1058 } else 1059 { 1060 ev.type = DevicePresenceNotify; 1061 ev.time = currentTime.milliseconds; 1062 ev.devchange = DeviceUnrecoverable; 1063 ev.deviceid = dev->id; 1064 dummyDev.id = 0; 1065 SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask, 1066 (xEvent *) &ev, 1); 1067 1068 DeleteInputDeviceRequest(dev); 1069 } 1070} 1071 1072/** 1073 * Reactivate a device. Call this function from the driver if you just found 1074 * out that the read error wasn't quite that bad after all. 1075 * Device will be re-activated, and an event sent to the client. 1076 */ 1077_X_EXPORT void 1078xf86EnableDevice(DeviceIntPtr dev) 1079{ 1080 EnableDevice(dev); 1081} 1082 1083/* end of xf86Xinput.c */ 1084