1/* 2 * Copyright © 2006 Nokia Corporation 3 * Copyright © 2006-2007 Daniel Stone 4 * Copyright © 2008 Red Hat, Inc. 5 * Copyright © 2011 The Chromium Authors 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the next 15 * paragraph) shall be included in all copies or substantial portions of the 16 * Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 * DEALINGS IN THE SOFTWARE. 25 * 26 * Authors: Daniel Stone <daniel@fooishbar.org> 27 * Peter Hutterer <peter.hutterer@who-t.net> 28 */ 29 30#ifdef HAVE_DIX_CONFIG_H 31#include <dix-config.h> 32#endif 33 34#include <X11/X.h> 35#include <X11/keysym.h> 36#include <X11/Xproto.h> 37#include <math.h> 38#include <limits.h> 39 40#include "misc.h" 41#include "resource.h" 42#include "inputstr.h" 43#include "scrnintstr.h" 44#include "cursorstr.h" 45#include "dixstruct.h" 46#include "globals.h" 47#include "dixevents.h" 48#include "mipointer.h" 49#include "eventstr.h" 50#include "eventconvert.h" 51#include "inpututils.h" 52#include "mi.h" 53#include "windowstr.h" 54 55#include <X11/extensions/XKBproto.h> 56#include "xkbsrv.h" 57 58#ifdef PANORAMIX 59#include "panoramiX.h" 60#include "panoramiXsrv.h" 61#endif 62 63#include <X11/extensions/XI.h> 64#include <X11/extensions/XI2.h> 65#include <X11/extensions/XIproto.h> 66#include <pixman.h> 67#include "exglobals.h" 68#include "exevents.h" 69#include "extnsionst.h" 70#include "listdev.h" /* for sizing up DeviceClassesChangedEvent */ 71#include "probes.h" 72 73/* Number of motion history events to store. */ 74#define MOTION_HISTORY_SIZE 256 75 76/** 77 * InputEventList is the storage for input events generated by 78 * QueuePointerEvents, QueueKeyboardEvents, and QueueProximityEvents. 79 * This list is allocated on startup by the DIX. 80 */ 81InternalEvent *InputEventList = NULL; 82 83/** 84 * Pick some arbitrary size for Xi motion history. 85 */ 86int 87GetMotionHistorySize(void) 88{ 89 return MOTION_HISTORY_SIZE; 90} 91 92void 93set_button_down(DeviceIntPtr pDev, int button, int type) 94{ 95 if (type == BUTTON_PROCESSED) 96 SetBit(pDev->button->down, button); 97 else 98 SetBit(pDev->button->postdown, button); 99} 100 101void 102set_button_up(DeviceIntPtr pDev, int button, int type) 103{ 104 if (type == BUTTON_PROCESSED) 105 ClearBit(pDev->button->down, button); 106 else 107 ClearBit(pDev->button->postdown, button); 108} 109 110Bool 111button_is_down(DeviceIntPtr pDev, int button, int type) 112{ 113 Bool ret = FALSE; 114 115 if (type & BUTTON_PROCESSED) 116 ret = ret || BitIsOn(pDev->button->down, button); 117 if (type & BUTTON_POSTED) 118 ret = ret || BitIsOn(pDev->button->postdown, button); 119 120 return ret; 121} 122 123void 124set_key_down(DeviceIntPtr pDev, int key_code, int type) 125{ 126 if (type == KEY_PROCESSED) 127 SetBit(pDev->key->down, key_code); 128 else 129 SetBit(pDev->key->postdown, key_code); 130} 131 132void 133set_key_up(DeviceIntPtr pDev, int key_code, int type) 134{ 135 if (type == KEY_PROCESSED) 136 ClearBit(pDev->key->down, key_code); 137 else 138 ClearBit(pDev->key->postdown, key_code); 139} 140 141Bool 142key_is_down(DeviceIntPtr pDev, int key_code, int type) 143{ 144 Bool ret = FALSE; 145 146 if (type & KEY_PROCESSED) 147 ret = ret || BitIsOn(pDev->key->down, key_code); 148 if (type & KEY_POSTED) 149 ret = ret || BitIsOn(pDev->key->postdown, key_code); 150 151 return ret; 152} 153 154static Bool 155key_autorepeats(DeviceIntPtr pDev, int key_code) 156{ 157 return ! !(pDev->kbdfeed->ctrl.autoRepeats[key_code >> 3] & 158 (1 << (key_code & 7))); 159} 160 161static void 162init_touch_ownership(DeviceIntPtr dev, TouchOwnershipEvent *event, Time ms) 163{ 164 memset(event, 0, sizeof(TouchOwnershipEvent)); 165 event->header = ET_Internal; 166 event->type = ET_TouchOwnership; 167 event->length = sizeof(TouchOwnershipEvent); 168 event->time = ms; 169 event->deviceid = dev->id; 170} 171 172static void 173init_raw(DeviceIntPtr dev, RawDeviceEvent *event, Time ms, int type, int detail) 174{ 175 memset(event, 0, sizeof(RawDeviceEvent)); 176 event->header = ET_Internal; 177 event->length = sizeof(RawDeviceEvent); 178 switch (type) { 179 case MotionNotify: 180 event->type = ET_RawMotion; 181 break; 182 case ButtonPress: 183 event->type = ET_RawButtonPress; 184 break; 185 case ButtonRelease: 186 event->type = ET_RawButtonRelease; 187 break; 188 case KeyPress: 189 event->type = ET_RawKeyPress; 190 break; 191 case KeyRelease: 192 event->type = ET_RawKeyRelease; 193 break; 194 case XI_TouchBegin: 195 event->type = ET_RawTouchBegin; 196 break; 197 case XI_TouchUpdate: 198 event->type = ET_RawTouchUpdate; 199 break; 200 case XI_TouchEnd: 201 event->type = ET_RawTouchEnd; 202 break; 203 } 204 event->time = ms; 205 event->deviceid = dev->id; 206 event->sourceid = dev->id; 207 event->detail.button = detail; 208} 209 210static void 211set_raw_valuators(RawDeviceEvent *event, ValuatorMask *mask, 212 BOOL use_unaccel, double *data) 213{ 214 int i; 215 216 use_unaccel = use_unaccel && valuator_mask_has_unaccelerated(mask); 217 218 for (i = 0; i < valuator_mask_size(mask); i++) { 219 if (valuator_mask_isset(mask, i)) { 220 double v; 221 222 SetBit(event->valuators.mask, i); 223 224 if (use_unaccel) 225 v = valuator_mask_get_unaccelerated(mask, i); 226 else 227 v = valuator_mask_get_double(mask, i); 228 229 data[i] = v; 230 } 231 } 232} 233 234static void 235set_valuators(DeviceIntPtr dev, DeviceEvent *event, ValuatorMask *mask) 236{ 237 int i; 238 239 /* Set the data to the previous value for unset absolute axes. The values 240 * may be used when sent as part of an XI 1.x valuator event. */ 241 for (i = 0; i < valuator_mask_size(mask); i++) { 242 if (valuator_mask_isset(mask, i)) { 243 SetBit(event->valuators.mask, i); 244 if (valuator_get_mode(dev, i) == Absolute) 245 SetBit(event->valuators.mode, i); 246 event->valuators.data[i] = valuator_mask_get_double(mask, i); 247 } 248 else 249 event->valuators.data[i] = dev->valuator->axisVal[i]; 250 } 251} 252 253void 254CreateClassesChangedEvent(InternalEvent *event, 255 DeviceIntPtr master, DeviceIntPtr slave, int flags) 256{ 257 int i; 258 DeviceChangedEvent *dce; 259 CARD32 ms = GetTimeInMillis(); 260 261 dce = &event->changed_event; 262 memset(dce, 0, sizeof(DeviceChangedEvent)); 263 dce->deviceid = slave->id; 264 dce->masterid = master ? master->id : 0; 265 dce->header = ET_Internal; 266 dce->length = sizeof(DeviceChangedEvent); 267 dce->type = ET_DeviceChanged; 268 dce->time = ms; 269 dce->flags = flags; 270 dce->sourceid = slave->id; 271 272 if (slave->button) { 273 dce->buttons.num_buttons = slave->button->numButtons; 274 for (i = 0; i < dce->buttons.num_buttons; i++) 275 dce->buttons.names[i] = slave->button->labels[i]; 276 } 277 if (slave->valuator) { 278 dce->num_valuators = slave->valuator->numAxes; 279 for (i = 0; i < dce->num_valuators; i++) { 280 dce->valuators[i].min = slave->valuator->axes[i].min_value; 281 dce->valuators[i].max = slave->valuator->axes[i].max_value; 282 dce->valuators[i].resolution = slave->valuator->axes[i].resolution; 283 dce->valuators[i].mode = slave->valuator->axes[i].mode; 284 dce->valuators[i].name = slave->valuator->axes[i].label; 285 dce->valuators[i].scroll = slave->valuator->axes[i].scroll; 286 dce->valuators[i].value = slave->valuator->axisVal[i]; 287 } 288 } 289 if (slave->key) { 290 dce->keys.min_keycode = slave->key->xkbInfo->desc->min_key_code; 291 dce->keys.max_keycode = slave->key->xkbInfo->desc->max_key_code; 292 } 293} 294 295/** 296 * Rescale the coord between the two axis ranges. 297 */ 298static double 299rescaleValuatorAxis(double coord, AxisInfoPtr from, AxisInfoPtr to, 300 double defmin, double defmax) 301{ 302 double fmin = defmin, fmax = defmax; 303 double tmin = defmin, tmax = defmax; 304 305 if (from && from->min_value < from->max_value) { 306 fmin = from->min_value; 307 fmax = from->max_value + 1; 308 } 309 if (to && to->min_value < to->max_value) { 310 tmin = to->min_value; 311 tmax = to->max_value + 1; 312 } 313 314 if (fmin == tmin && fmax == tmax) 315 return coord; 316 317 if (fmax == fmin) /* avoid division by 0 */ 318 return 0.0; 319 320 return (coord - fmin) * (tmax - tmin) / (fmax - fmin) + tmin; 321} 322 323/** 324 * Update all coordinates when changing to a different SD 325 * to ensure that relative reporting will work as expected 326 * without loss of precision. 327 * 328 * pDev->last.valuators will be in absolute device coordinates after this 329 * function. 330 */ 331static void 332updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev) 333{ 334 /* master->last.valuators[0]/[1] is in desktop-wide coords and the actual 335 * position of the pointer */ 336 pDev->last.valuators[0] = master->last.valuators[0]; 337 pDev->last.valuators[1] = master->last.valuators[1]; 338 339 if (!pDev->valuator) 340 return; 341 342 /* scale back to device coordinates */ 343 if (pDev->valuator->numAxes > 0) { 344 pDev->last.valuators[0] = rescaleValuatorAxis(pDev->last.valuators[0], 345 NULL, 346 pDev->valuator->axes + 0, 347 screenInfo.x, 348 screenInfo.width); 349 } 350 if (pDev->valuator->numAxes > 1) { 351 pDev->last.valuators[1] = rescaleValuatorAxis(pDev->last.valuators[1], 352 NULL, 353 pDev->valuator->axes + 1, 354 screenInfo.y, 355 screenInfo.height); 356 } 357 358 /* other axes are left as-is */ 359} 360 361/** 362 * Allocate the motion history buffer. 363 */ 364void 365AllocateMotionHistory(DeviceIntPtr pDev) 366{ 367 int size; 368 369 free(pDev->valuator->motion); 370 371 if (pDev->valuator->numMotionEvents < 1) 372 return; 373 374 /* An MD must have a motion history size large enough to keep all 375 * potential valuators, plus the respective range of the valuators. 376 * 3 * INT32 for (min_val, max_val, curr_val)) 377 */ 378 if (IsMaster(pDev)) 379 size = sizeof(INT32) * 3 * MAX_VALUATORS; 380 else { 381 ValuatorClassPtr v = pDev->valuator; 382 int numAxes; 383 384 /* XI1 doesn't understand mixed mode devices */ 385 for (numAxes = 0; numAxes < v->numAxes; numAxes++) 386 if (valuator_get_mode(pDev, numAxes) != valuator_get_mode(pDev, 0)) 387 break; 388 size = sizeof(INT32) * numAxes; 389 } 390 391 size += sizeof(Time); 392 393 pDev->valuator->motion = calloc(pDev->valuator->numMotionEvents, size); 394 pDev->valuator->first_motion = 0; 395 pDev->valuator->last_motion = 0; 396 if (!pDev->valuator->motion) 397 ErrorF("[dix] %s: Failed to alloc motion history (%d bytes).\n", 398 pDev->name, size * pDev->valuator->numMotionEvents); 399} 400 401/** 402 * Dump the motion history between start and stop into the supplied buffer. 403 * Only records the event for a given screen in theory, but in practice, we 404 * sort of ignore this. 405 * 406 * If core is set, we only generate x/y, in INT16, scaled to screen coords. 407 */ 408int 409GetMotionHistory(DeviceIntPtr pDev, xTimecoord ** buff, unsigned long start, 410 unsigned long stop, ScreenPtr pScreen, BOOL core) 411{ 412 char *ibuff = NULL, *obuff; 413 int i = 0, ret = 0; 414 int j, coord; 415 Time current; 416 417 /* The size of a single motion event. */ 418 int size; 419 AxisInfo from, *to; /* for scaling */ 420 INT32 *ocbuf, *icbuf; /* pointer to coordinates for copying */ 421 INT16 *corebuf; 422 AxisInfo core_axis = { 0 }; 423 424 if (!pDev->valuator || !pDev->valuator->numMotionEvents) 425 return 0; 426 427 if (core && !pScreen) 428 return 0; 429 430 if (IsMaster(pDev)) 431 size = (sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(Time); 432 else 433 size = (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time); 434 435 *buff = malloc(size * pDev->valuator->numMotionEvents); 436 if (!(*buff)) 437 return 0; 438 obuff = (char *) *buff; 439 440 for (i = pDev->valuator->first_motion; 441 i != pDev->valuator->last_motion; 442 i = (i + 1) % pDev->valuator->numMotionEvents) { 443 /* We index the input buffer by which element we're accessing, which 444 * is not monotonic, and the output buffer by how many events we've 445 * written so far. */ 446 ibuff = (char *) pDev->valuator->motion + (i * size); 447 memcpy(¤t, ibuff, sizeof(Time)); 448 449 if (current > stop) { 450 return ret; 451 } 452 else if (current >= start) { 453 if (core) { 454 memcpy(obuff, ibuff, sizeof(Time)); /* copy timestamp */ 455 456 icbuf = (INT32 *) (ibuff + sizeof(Time)); 457 corebuf = (INT16 *) (obuff + sizeof(Time)); 458 459 /* fetch x coordinate + range */ 460 memcpy(&from.min_value, icbuf++, sizeof(INT32)); 461 memcpy(&from.max_value, icbuf++, sizeof(INT32)); 462 memcpy(&coord, icbuf++, sizeof(INT32)); 463 464 /* scale to screen coords */ 465 to = &core_axis; 466 to->max_value = pScreen->width; 467 coord = 468 rescaleValuatorAxis(coord, &from, to, 0, pScreen->width); 469 470 memcpy(corebuf, &coord, sizeof(INT16)); 471 corebuf++; 472 473 /* fetch y coordinate + range */ 474 memcpy(&from.min_value, icbuf++, sizeof(INT32)); 475 memcpy(&from.max_value, icbuf++, sizeof(INT32)); 476 memcpy(&coord, icbuf++, sizeof(INT32)); 477 478 to->max_value = pScreen->height; 479 coord = 480 rescaleValuatorAxis(coord, &from, to, 0, pScreen->height); 481 memcpy(corebuf, &coord, sizeof(INT16)); 482 483 } 484 else if (IsMaster(pDev)) { 485 memcpy(obuff, ibuff, sizeof(Time)); /* copy timestamp */ 486 487 ocbuf = (INT32 *) (obuff + sizeof(Time)); 488 icbuf = (INT32 *) (ibuff + sizeof(Time)); 489 for (j = 0; j < MAX_VALUATORS; j++) { 490 if (j >= pDev->valuator->numAxes) 491 break; 492 493 /* fetch min/max/coordinate */ 494 memcpy(&from.min_value, icbuf++, sizeof(INT32)); 495 memcpy(&from.max_value, icbuf++, sizeof(INT32)); 496 memcpy(&coord, icbuf++, sizeof(INT32)); 497 498 to = (j < 499 pDev->valuator->numAxes) ? &pDev->valuator-> 500 axes[j] : NULL; 501 502 /* x/y scaled to screen if no range is present */ 503 if (j == 0 && (from.max_value < from.min_value)) 504 from.max_value = pScreen->width; 505 else if (j == 1 && (from.max_value < from.min_value)) 506 from.max_value = pScreen->height; 507 508 /* scale from stored range into current range */ 509 coord = rescaleValuatorAxis(coord, &from, to, 0, 0); 510 memcpy(ocbuf, &coord, sizeof(INT32)); 511 ocbuf++; 512 } 513 } 514 else 515 memcpy(obuff, ibuff, size); 516 517 /* don't advance by size here. size may be different to the 518 * actually written size if the MD has less valuators than MAX */ 519 if (core) 520 obuff += sizeof(INT32) + sizeof(Time); 521 else 522 obuff += 523 (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time); 524 ret++; 525 } 526 } 527 528 return ret; 529} 530 531/** 532 * Update the motion history for a specific device, with the list of 533 * valuators. 534 * 535 * Layout of the history buffer: 536 * for SDs: [time] [val0] [val1] ... [valn] 537 * for MDs: [time] [min_val0] [max_val0] [val0] [min_val1] ... [valn] 538 * 539 * For events that have some valuators unset: 540 * min_val == max_val == val == 0. 541 */ 542static void 543updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, ValuatorMask *mask, 544 double *valuators) 545{ 546 char *buff = (char *) pDev->valuator->motion; 547 ValuatorClassPtr v; 548 int i; 549 550 if (!pDev->valuator->numMotionEvents) 551 return; 552 553 v = pDev->valuator; 554 if (IsMaster(pDev)) { 555 buff += ((sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(CARD32)) * 556 v->last_motion; 557 558 memcpy(buff, &ms, sizeof(Time)); 559 buff += sizeof(Time); 560 561 memset(buff, 0, sizeof(INT32) * 3 * MAX_VALUATORS); 562 563 for (i = 0; i < v->numAxes; i++) { 564 int val; 565 566 /* XI1 doesn't support mixed mode devices */ 567 if (valuator_get_mode(pDev, i) != valuator_get_mode(pDev, 0)) 568 break; 569 if (valuator_mask_size(mask) <= i || !valuator_mask_isset(mask, i)) { 570 buff += 3 * sizeof(INT32); 571 continue; 572 } 573 memcpy(buff, &v->axes[i].min_value, sizeof(INT32)); 574 buff += sizeof(INT32); 575 memcpy(buff, &v->axes[i].max_value, sizeof(INT32)); 576 buff += sizeof(INT32); 577 val = valuators[i]; 578 memcpy(buff, &val, sizeof(INT32)); 579 buff += sizeof(INT32); 580 } 581 } 582 else { 583 584 buff += ((sizeof(INT32) * pDev->valuator->numAxes) + sizeof(CARD32)) * 585 pDev->valuator->last_motion; 586 587 memcpy(buff, &ms, sizeof(Time)); 588 buff += sizeof(Time); 589 590 memset(buff, 0, sizeof(INT32) * pDev->valuator->numAxes); 591 592 for (i = 0; i < MAX_VALUATORS; i++) { 593 int val; 594 595 if (valuator_mask_size(mask) <= i || !valuator_mask_isset(mask, i)) { 596 buff += sizeof(INT32); 597 continue; 598 } 599 val = valuators[i]; 600 memcpy(buff, &val, sizeof(INT32)); 601 buff += sizeof(INT32); 602 } 603 } 604 605 pDev->valuator->last_motion = (pDev->valuator->last_motion + 1) % 606 pDev->valuator->numMotionEvents; 607 /* If we're wrapping around, just keep the circular buffer going. */ 608 if (pDev->valuator->first_motion == pDev->valuator->last_motion) 609 pDev->valuator->first_motion = (pDev->valuator->first_motion + 1) % 610 pDev->valuator->numMotionEvents; 611 612 return; 613} 614 615/** 616 * Returns the maximum number of events GetKeyboardEvents 617 * and GetPointerEvents will ever return. 618 * 619 * This MUST be absolutely constant, from init until exit. 620 */ 621int 622GetMaximumEventsNum(void) 623{ 624 /* One raw event 625 * One device event 626 * One possible device changed event 627 * Lots of possible separate button scroll events (horiz + vert) 628 * Lots of possible separate raw button scroll events (horiz + vert) 629 */ 630 return 100; 631} 632 633/** 634 * Clip an axis to its bounds, which are declared in the call to 635 * InitValuatorAxisClassStruct. 636 */ 637static void 638clipAxis(DeviceIntPtr pDev, int axisNum, double *val) 639{ 640 AxisInfoPtr axis; 641 642 if (axisNum >= pDev->valuator->numAxes) 643 return; 644 645 axis = pDev->valuator->axes + axisNum; 646 647 /* If a value range is defined, clip. If not, do nothing */ 648 if (axis->max_value <= axis->min_value) 649 return; 650 651 if (*val < axis->min_value) 652 *val = axis->min_value; 653 if (*val > axis->max_value) 654 *val = axis->max_value; 655} 656 657/** 658 * Clip every axis in the list of valuators to its bounds. 659 */ 660static void 661clipValuators(DeviceIntPtr pDev, ValuatorMask *mask) 662{ 663 int i; 664 665 for (i = 0; i < valuator_mask_size(mask); i++) 666 if (valuator_mask_isset(mask, i)) { 667 double val = valuator_mask_get_double(mask, i); 668 669 clipAxis(pDev, i, &val); 670 valuator_mask_set_double(mask, i, val); 671 } 672} 673 674/** 675 * Create the DCCE event (does not update the master's device state yet, this 676 * is done in the event processing). 677 * Pull in the coordinates from the MD if necessary. 678 * 679 * @param events Pointer to a pre-allocated event array. 680 * @param dev The slave device that generated an event. 681 * @param type Either DEVCHANGE_POINTER_EVENT and/or DEVCHANGE_KEYBOARD_EVENT 682 * @param num_events The current number of events, returns the number of 683 * events if a DCCE was generated. 684 * @return The updated @events pointer. 685 */ 686InternalEvent * 687UpdateFromMaster(InternalEvent *events, DeviceIntPtr dev, int type, 688 int *num_events) 689{ 690 DeviceIntPtr master; 691 692 master = 693 GetMaster(dev, 694 (type & DEVCHANGE_POINTER_EVENT) ? MASTER_POINTER : 695 MASTER_KEYBOARD); 696 697 if (master && master->last.slave != dev) { 698 CreateClassesChangedEvent(events, master, dev, 699 type | DEVCHANGE_SLAVE_SWITCH); 700 if (IsPointerDevice(master)) { 701 updateSlaveDeviceCoords(master, dev); 702 master->last.numValuators = dev->last.numValuators; 703 } 704 master->last.slave = dev; 705 (*num_events)++; 706 events++; 707 } 708 return events; 709} 710 711/** 712 * Move the device's pointer to the position given in the valuators. 713 * 714 * @param dev The device whose pointer is to be moved. 715 * @param mask Valuator data for this event. 716 */ 717static void 718clipAbsolute(DeviceIntPtr dev, ValuatorMask *mask) 719{ 720 int i; 721 722 for (i = 0; i < valuator_mask_size(mask); i++) { 723 double val; 724 725 if (!valuator_mask_isset(mask, i)) 726 continue; 727 val = valuator_mask_get_double(mask, i); 728 clipAxis(dev, i, &val); 729 valuator_mask_set_double(mask, i, val); 730 } 731} 732 733static void 734add_to_scroll_valuator(DeviceIntPtr dev, ValuatorMask *mask, int valuator, double value) 735{ 736 double v; 737 738 if (!valuator_mask_fetch_double(mask, valuator, &v)) 739 return; 740 741 /* protect against scrolling overflow. INT_MAX for double, because 742 * we'll eventually write this as 32.32 fixed point */ 743 if ((value > 0 && v > INT_MAX - value) || (value < 0 && v < INT_MIN - value)) { 744 v = 0; 745 746 /* reset last.scroll to avoid a button storm */ 747 valuator_mask_set_double(dev->last.scroll, valuator, 0); 748 } 749 else 750 v += value; 751 752 valuator_mask_set_double(mask, valuator, v); 753} 754 755 756static void 757scale_for_device_resolution(DeviceIntPtr dev, ValuatorMask *mask) 758{ 759 double y; 760 ValuatorClassPtr v = dev->valuator; 761 int xrange = v->axes[0].max_value - v->axes[0].min_value + 1; 762 int yrange = v->axes[1].max_value - v->axes[1].min_value + 1; 763 764 double screen_ratio = 1.0 * screenInfo.width/screenInfo.height; 765 double device_ratio = 1.0 * xrange/yrange; 766 double resolution_ratio = 1.0; 767 double ratio; 768 769 if (!valuator_mask_fetch_double(mask, 1, &y)) 770 return; 771 772 if (v->axes[0].resolution != 0 && v->axes[1].resolution != 0) 773 resolution_ratio = 1.0 * v->axes[0].resolution/v->axes[1].resolution; 774 775 ratio = device_ratio/resolution_ratio/screen_ratio; 776 valuator_mask_set_double(mask, 1, y / ratio); 777} 778 779/** 780 * Move the device's pointer by the values given in @valuators. 781 * 782 * @param dev The device whose pointer is to be moved. 783 * @param[in,out] mask Valuator data for this event, modified in-place. 784 */ 785static void 786moveRelative(DeviceIntPtr dev, int flags, ValuatorMask *mask) 787{ 788 int i; 789 Bool clip_xy = IsMaster(dev) || !IsFloating(dev); 790 ValuatorClassPtr v = dev->valuator; 791 792 /* for abs devices in relative mode, we've just scaled wrong, since we 793 mapped the device's shape into the screen shape. Undo this. */ 794 if ((flags & POINTER_ABSOLUTE) == 0 && v && v->numAxes > 1 && 795 v->axes[0].min_value < v->axes[0].max_value && 796 v->axes[1].min_value < v->axes[1].max_value) { 797 scale_for_device_resolution(dev, mask); 798 } 799 800 /* calc other axes, clip, drop back into valuators */ 801 for (i = 0; i < valuator_mask_size(mask); i++) { 802 double val = dev->last.valuators[i]; 803 804 if (!valuator_mask_isset(mask, i)) 805 continue; 806 807 add_to_scroll_valuator(dev, mask, i, val); 808 809 /* x & y need to go over the limits to cross screens if the SD 810 * isn't currently attached; otherwise, clip to screen bounds. */ 811 if (valuator_get_mode(dev, i) == Absolute && 812 ((i != 0 && i != 1) || clip_xy)) { 813 val = valuator_mask_get_double(mask, i); 814 clipAxis(dev, i, &val); 815 valuator_mask_set_double(mask, i, val); 816 } 817 } 818} 819 820/** 821 * Accelerate the data in valuators based on the device's acceleration scheme. 822 * 823 * @param dev The device which's pointer is to be moved. 824 * @param valuators Valuator mask 825 * @param ms Current time. 826 */ 827static void 828accelPointer(DeviceIntPtr dev, ValuatorMask *valuators, CARD32 ms) 829{ 830 if (dev->valuator->accelScheme.AccelSchemeProc) 831 dev->valuator->accelScheme.AccelSchemeProc(dev, valuators, ms); 832} 833 834/** 835 * Scale from absolute screen coordinates to absolute coordinates in the 836 * device's coordinate range. 837 * 838 * @param dev The device to scale for. 839 * @param[in, out] mask The mask in desktop/screen coordinates, modified in place 840 * to contain device coordinate range. 841 * @param flags If POINTER_SCREEN is set, mask is in per-screen coordinates. 842 * Otherwise, mask is in desktop coords. 843 */ 844static void 845scale_from_screen(DeviceIntPtr dev, ValuatorMask *mask, int flags) 846{ 847 double scaled; 848 ScreenPtr scr = miPointerGetScreen(dev); 849 850 if (valuator_mask_isset(mask, 0)) { 851 scaled = valuator_mask_get_double(mask, 0); 852 if (flags & POINTER_SCREEN) 853 scaled += scr->x; 854 scaled = rescaleValuatorAxis(scaled, 855 NULL, dev->valuator->axes + 0, 856 screenInfo.x, screenInfo.width); 857 valuator_mask_set_double(mask, 0, scaled); 858 } 859 if (valuator_mask_isset(mask, 1)) { 860 scaled = valuator_mask_get_double(mask, 1); 861 if (flags & POINTER_SCREEN) 862 scaled += scr->y; 863 scaled = rescaleValuatorAxis(scaled, 864 NULL, dev->valuator->axes + 1, 865 screenInfo.y, screenInfo.height); 866 valuator_mask_set_double(mask, 1, scaled); 867 } 868} 869 870/** 871 * Scale from (absolute) device to screen coordinates here, 872 * 873 * The coordinates provided are always absolute. see fill_pointer_events for 874 * information on coordinate systems. 875 * 876 * @param dev The device to be moved. 877 * @param mask Mask of axis values for this event 878 * @param[out] devx x desktop-wide coordinate in device coordinate system 879 * @param[out] devy y desktop-wide coordinate in device coordinate system 880 * @param[out] screenx x coordinate in desktop coordinate system 881 * @param[out] screeny y coordinate in desktop coordinate system 882 */ 883static ScreenPtr 884scale_to_desktop(DeviceIntPtr dev, ValuatorMask *mask, 885 double *devx, double *devy, double *screenx, double *screeny) 886{ 887 ScreenPtr scr = miPointerGetScreen(dev); 888 double x, y; 889 890 BUG_WARN(dev->valuator && dev->valuator->numAxes < 2); 891 if (!dev->valuator || dev->valuator->numAxes < 2) { 892 /* if we have no axes, last.valuators must be in screen coords 893 * anyway */ 894 *devx = *screenx = dev->last.valuators[0]; 895 *devy = *screeny = dev->last.valuators[1]; 896 return scr; 897 } 898 899 if (valuator_mask_isset(mask, 0)) 900 x = valuator_mask_get_double(mask, 0); 901 else 902 x = dev->last.valuators[0]; 903 if (valuator_mask_isset(mask, 1)) 904 y = valuator_mask_get_double(mask, 1); 905 else 906 y = dev->last.valuators[1]; 907 908 /* scale x&y to desktop coordinates */ 909 *screenx = rescaleValuatorAxis(x, dev->valuator->axes + 0, NULL, 910 screenInfo.x, screenInfo.width); 911 *screeny = rescaleValuatorAxis(y, dev->valuator->axes + 1, NULL, 912 screenInfo.y, screenInfo.height); 913 914 *devx = x; 915 *devy = y; 916 917 return scr; 918} 919 920/** 921 * If we have HW cursors, this actually moves the visible sprite. If not, we 922 * just do all the screen crossing, etc. 923 * 924 * We use the screen coordinates here, call miPointerSetPosition() and then 925 * scale back into device coordinates (if needed). miPSP will change x/y if 926 * the screen was crossed. 927 * 928 * The coordinates provided are always absolute. The parameter mode 929 * specifies whether it was relative or absolute movement that landed us at 930 * those coordinates. see fill_pointer_events for information on coordinate 931 * systems. 932 * 933 * @param dev The device to be moved. 934 * @param mode Movement mode (Absolute or Relative) 935 * @param[out] mask Mask of axis values for this event, returns the 936 * per-screen device coordinates after confinement 937 * @param[in,out] devx x desktop-wide coordinate in device coordinate system 938 * @param[in,out] devy y desktop-wide coordinate in device coordinate system 939 * @param[in,out] screenx x coordinate in desktop coordinate system 940 * @param[in,out] screeny y coordinate in desktop coordinate system 941 * @param[out] nevents Number of barrier events added to events 942 * @param[in,out] events List of events barrier events are added to 943 */ 944static ScreenPtr 945positionSprite(DeviceIntPtr dev, int mode, ValuatorMask *mask, 946 double *devx, double *devy, double *screenx, double *screeny, 947 int *nevents, InternalEvent* events) 948{ 949 ScreenPtr scr = miPointerGetScreen(dev); 950 double tmpx, tmpy; 951 952 if (!dev->valuator || dev->valuator->numAxes < 2) 953 return scr; 954 955 tmpx = *screenx; 956 tmpy = *screeny; 957 958 /* miPointerSetPosition takes care of crossing screens for us, as well as 959 * clipping to the current screen. Coordinates returned are in desktop 960 * coord system */ 961 scr = miPointerSetPosition(dev, mode, screenx, screeny, nevents, events); 962 963 /* If we were constrained, rescale x/y from the screen coordinates so 964 * the device valuators reflect the correct position. For screen 965 * crossing this doesn't matter much, the coords would be 0 or max. 966 */ 967 if (tmpx != *screenx) 968 *devx = rescaleValuatorAxis(*screenx, NULL, dev->valuator->axes + 0, 969 screenInfo.x, screenInfo.width); 970 971 if (tmpy != *screeny) 972 *devy = rescaleValuatorAxis(*screeny, NULL, dev->valuator->axes + 1, 973 screenInfo.y, screenInfo.height); 974 975 /* Recalculate the per-screen device coordinates */ 976 if (valuator_mask_isset(mask, 0)) { 977 double x; 978 979 x = rescaleValuatorAxis(*screenx - scr->x, NULL, 980 dev->valuator->axes + 0, 0, scr->width); 981 valuator_mask_set_double(mask, 0, x); 982 } 983 if (valuator_mask_isset(mask, 1)) { 984 double y; 985 986 y = rescaleValuatorAxis(*screeny - scr->y, NULL, 987 dev->valuator->axes + 1, 0, scr->height); 988 valuator_mask_set_double(mask, 1, y); 989 } 990 991 return scr; 992} 993 994/** 995 * Update the motion history for the device and (if appropriate) for its 996 * master device. 997 * @param dev Slave device to update. 998 * @param mask Bit mask of valid valuators to append to history. 999 * @param num Total number of valuators to append to history. 1000 * @param ms Current time 1001 */ 1002static void 1003updateHistory(DeviceIntPtr dev, ValuatorMask *mask, CARD32 ms) 1004{ 1005 if (!dev->valuator) 1006 return; 1007 1008 updateMotionHistory(dev, ms, mask, dev->last.valuators); 1009 if (!IsMaster(dev) && !IsFloating(dev)) { 1010 DeviceIntPtr master = GetMaster(dev, MASTER_POINTER); 1011 1012 updateMotionHistory(master, ms, mask, dev->last.valuators); 1013 } 1014} 1015 1016static void 1017queueEventList(DeviceIntPtr device, InternalEvent *events, int nevents) 1018{ 1019 int i; 1020 1021 for (i = 0; i < nevents; i++) 1022 mieqEnqueue(device, &events[i]); 1023} 1024 1025static void 1026event_set_root_coordinates(DeviceEvent *event, double x, double y) 1027{ 1028 event->root_x = trunc(x); 1029 event->root_y = trunc(y); 1030 event->root_x_frac = x - trunc(x); 1031 event->root_y_frac = y - trunc(y); 1032} 1033 1034/** 1035 * Generate internal events representing this keyboard event and enqueue 1036 * them on the event queue. 1037 * 1038 * This function is not reentrant. Disable signals before calling. 1039 * 1040 * @param device The device to generate the event for 1041 * @param type Event type, one of KeyPress or KeyRelease 1042 * @param keycode Key code of the pressed/released key 1043 * 1044 */ 1045void 1046QueueKeyboardEvents(DeviceIntPtr device, int type, 1047 int keycode) 1048{ 1049 int nevents; 1050 1051 nevents = GetKeyboardEvents(InputEventList, device, type, keycode); 1052 queueEventList(device, InputEventList, nevents); 1053} 1054 1055/** 1056 * Returns a set of InternalEvents for KeyPress/KeyRelease, optionally 1057 * also with valuator events. 1058 * 1059 * The DDX is responsible for allocating the event list in the first 1060 * place via InitEventList(), and for freeing it. 1061 * 1062 * @return the number of events written into events. 1063 */ 1064int 1065GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type, 1066 int key_code) 1067{ 1068 int num_events = 0; 1069 CARD32 ms = 0; 1070 DeviceEvent *event; 1071 RawDeviceEvent *raw; 1072 enum DeviceEventSource source_type = EVENT_SOURCE_NORMAL; 1073 1074#ifdef XSERVER_DTRACE 1075 if (XSERVER_INPUT_EVENT_ENABLED()) { 1076 XSERVER_INPUT_EVENT(pDev->id, type, key_code, 0, 0, 1077 NULL, NULL); 1078 } 1079#endif 1080 1081 if (type == EnterNotify) { 1082 source_type = EVENT_SOURCE_FOCUS; 1083 type = KeyPress; 1084 } else if (type == LeaveNotify) { 1085 source_type = EVENT_SOURCE_FOCUS; 1086 type = KeyRelease; 1087 } 1088 1089 /* refuse events from disabled devices */ 1090 if (!pDev->enabled) 1091 return 0; 1092 1093 if (!events || !pDev->key || !pDev->focus || !pDev->kbdfeed || 1094 (type != KeyPress && type != KeyRelease) || 1095 (key_code < 8 || key_code > 255)) 1096 return 0; 1097 1098 num_events = 1; 1099 1100 events = 1101 UpdateFromMaster(events, pDev, DEVCHANGE_KEYBOARD_EVENT, &num_events); 1102 1103 /* Handle core repeating, via press/release/press/release. */ 1104 if (type == KeyPress && key_is_down(pDev, key_code, KEY_POSTED)) { 1105 /* If autorepeating is disabled either globally or just for that key, 1106 * or we have a modifier, don't generate a repeat event. */ 1107 if (!pDev->kbdfeed->ctrl.autoRepeat || 1108 !key_autorepeats(pDev, key_code) || 1109 pDev->key->xkbInfo->desc->map->modmap[key_code]) 1110 return 0; 1111 } 1112 1113 ms = GetTimeInMillis(); 1114 1115 if (source_type == EVENT_SOURCE_NORMAL) { 1116 raw = &events->raw_event; 1117 init_raw(pDev, raw, ms, type, key_code); 1118 events++; 1119 num_events++; 1120 } 1121 1122 event = &events->device_event; 1123 init_device_event(event, pDev, ms, source_type); 1124 event->detail.key = key_code; 1125 1126 if (type == KeyPress) { 1127 event->type = ET_KeyPress; 1128 set_key_down(pDev, key_code, KEY_POSTED); 1129 } 1130 else if (type == KeyRelease) { 1131 event->type = ET_KeyRelease; 1132 set_key_up(pDev, key_code, KEY_POSTED); 1133 } 1134 1135 return num_events; 1136} 1137 1138/** 1139 * Initialize an event array large enough for num_events arrays. 1140 * This event list is to be passed into GetPointerEvents() and 1141 * GetKeyboardEvents(). 1142 * 1143 * @param num_events Number of elements in list. 1144 */ 1145InternalEvent * 1146InitEventList(int num_events) 1147{ 1148 InternalEvent *events = calloc(num_events, sizeof(InternalEvent)); 1149 1150 return events; 1151} 1152 1153/** 1154 * Free an event list. 1155 * 1156 * @param list The list to be freed. 1157 * @param num_events Number of elements in list. 1158 */ 1159void 1160FreeEventList(InternalEvent *list, int num_events) 1161{ 1162 free(list); 1163} 1164 1165/** 1166 * Transform vector x/y according to matrix m and drop the rounded coords 1167 * back into x/y. 1168 */ 1169static void 1170transform(struct pixman_f_transform *m, double *x, double *y) 1171{ 1172 struct pixman_f_vector p = {.v = {*x, *y, 1} }; 1173 pixman_f_transform_point(m, &p); 1174 1175 *x = p.v[0]; 1176 *y = p.v[1]; 1177} 1178 1179static void 1180transformRelative(DeviceIntPtr dev, ValuatorMask *mask) 1181{ 1182 double x = 0, y = 0; 1183 1184 valuator_mask_fetch_double(mask, 0, &x); 1185 valuator_mask_fetch_double(mask, 1, &y); 1186 1187 transform(&dev->relative_transform, &x, &y); 1188 1189 if (x) 1190 valuator_mask_set_double(mask, 0, x); 1191 else 1192 valuator_mask_unset(mask, 0); 1193 1194 if (y) 1195 valuator_mask_set_double(mask, 1, y); 1196 else 1197 valuator_mask_unset(mask, 1); 1198} 1199 1200/** 1201 * Apply the device's transformation matrix to the valuator mask and replace 1202 * the scaled values in mask. This transformation only applies to valuators 1203 * 0 and 1, others will be untouched. 1204 * 1205 * @param dev The device the valuators came from 1206 * @param[in,out] mask The valuator mask. 1207 */ 1208static void 1209transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask) 1210{ 1211 double x, y, ox = 0.0, oy = 0.0; 1212 int has_x, has_y; 1213 1214 has_x = valuator_mask_isset(mask, 0); 1215 has_y = valuator_mask_isset(mask, 1); 1216 1217 if (!has_x && !has_y) 1218 return; 1219 1220 if (!has_x || !has_y) { 1221 struct pixman_f_transform invert; 1222 1223 /* undo transformation from last event */ 1224 ox = dev->last.valuators[0]; 1225 oy = dev->last.valuators[1]; 1226 1227 pixman_f_transform_invert(&invert, &dev->scale_and_transform); 1228 transform(&invert, &ox, &oy); 1229 } 1230 1231 if (has_x) 1232 ox = valuator_mask_get_double(mask, 0); 1233 1234 if (has_y) 1235 oy = valuator_mask_get_double(mask, 1); 1236 1237 x = ox; 1238 y = oy; 1239 1240 transform(&dev->scale_and_transform, &x, &y); 1241 1242 if (has_x || ox != x) 1243 valuator_mask_set_double(mask, 0, x); 1244 1245 if (has_y || oy != y) 1246 valuator_mask_set_double(mask, 1, y); 1247} 1248 1249static void 1250storeLastValuators(DeviceIntPtr dev, ValuatorMask *mask, 1251 int xaxis, int yaxis, double devx, double devy) 1252{ 1253 int i; 1254 1255 /* store desktop-wide in last.valuators */ 1256 if (valuator_mask_isset(mask, xaxis)) 1257 dev->last.valuators[0] = devx; 1258 if (valuator_mask_isset(mask, yaxis)) 1259 dev->last.valuators[1] = devy; 1260 1261 for (i = 0; i < valuator_mask_size(mask); i++) { 1262 if (i == xaxis || i == yaxis) 1263 continue; 1264 1265 if (valuator_mask_isset(mask, i)) 1266 dev->last.valuators[i] = valuator_mask_get_double(mask, i); 1267 } 1268 1269} 1270 1271/** 1272 * Generate internal events representing this pointer event and enqueue them 1273 * on the event queue. 1274 * 1275 * This function is not reentrant. Disable signals before calling. 1276 * 1277 * @param device The device to generate the event for 1278 * @param type Event type, one of ButtonPress, ButtonRelease, MotionNotify 1279 * @param buttons Button number of the buttons modified. Must be 0 for 1280 * MotionNotify 1281 * @param flags Event modification flags 1282 * @param mask Valuator mask for valuators present for this event. 1283 */ 1284void 1285QueuePointerEvents(DeviceIntPtr device, int type, 1286 int buttons, int flags, const ValuatorMask *mask) 1287{ 1288 int nevents; 1289 1290 nevents = 1291 GetPointerEvents(InputEventList, device, type, buttons, flags, mask); 1292 queueEventList(device, InputEventList, nevents); 1293} 1294 1295/** 1296 * Helper function for GetPointerEvents, which only generates motion and 1297 * raw motion events for the slave device: does not update the master device. 1298 * 1299 * Should not be called by anyone other than GetPointerEvents. 1300 * 1301 * We use several different coordinate systems and need to switch between 1302 * the three in fill_pointer_events, positionSprite and 1303 * miPointerSetPosition. "desktop" refers to the width/height of all 1304 * screenInfo.screens[n]->width/height added up. "screen" is ScreenRec, not 1305 * output. 1306 * 1307 * Coordinate systems: 1308 * - relative events have a mask_in in relative coordinates, mapped to 1309 * pixels. These events are mapped to the current position±delta. 1310 * - absolute events have a mask_in in absolute device coordinates in 1311 * device-specific range. This range is mapped to the desktop. 1312 * - POINTER_SCREEN absolute events (x86WarpCursor) are in screen-relative 1313 * screen coordinate range. 1314 * - rootx/rooty in events must be be relative to the current screen's 1315 * origin (screen coordinate system) 1316 * - XI2 valuators must be relative to the current screen's origin. On 1317 * the protocol the device min/max range maps to the current screen. 1318 * 1319 * For screen switching we need to get the desktop coordinates for each 1320 * event, then map that to the respective position on each screen and 1321 * position the cursor there. 1322 * The device's last.valuator[] stores the last position in desktop-wide 1323 * coordinates (in device range for slave devices, desktop range for master 1324 * devices). 1325 * 1326 * screen-relative device coordinates requires scaling: A device coordinate 1327 * x/y of range [n..m] that maps to positions Sx/Sy on Screen S must be 1328 * rescaled to match Sx/Sy for [n..m]. In the simplest example, x of (m/2-1) 1329 * is the last coordinate on the first screen and must be rescaled for the 1330 * event to be m. XI2 clients that do their own coordinate mapping would 1331 * otherwise interpret the position of the device elsewhere to the cursor. 1332 * However, this scaling leads to losses: 1333 * if we have two ScreenRecs we scale from e.g. [0..44704] (Wacom I4) to 1334 * [0..2048[. that gives us 2047.954 as desktop coord, or the per-screen 1335 * coordinate 1023.954. Scaling that back into the device coordinate range 1336 * gives us 44703. So off by one device unit. It's a bug, but we'll have to 1337 * live with it because with all this scaling, we just cannot win. 1338 * 1339 * @return the number of events written into events. 1340 */ 1341static int 1342fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type, 1343 int buttons, CARD32 ms, int flags, 1344 const ValuatorMask *mask_in) 1345{ 1346 int num_events = 0; 1347 DeviceEvent *event; 1348 RawDeviceEvent *raw = NULL; 1349 double screenx = 0.0, screeny = 0.0; /* desktop coordinate system */ 1350 double devx = 0.0, devy = 0.0; /* desktop-wide in device coords */ 1351 int sx = 0, sy = 0; /* for POINTER_SCREEN */ 1352 ValuatorMask mask; 1353 ScreenPtr scr; 1354 int num_barrier_events = 0; 1355 1356 switch (type) { 1357 case MotionNotify: 1358 if (!pDev->valuator) { 1359 ErrorF("[dix] motion events from device %d without valuators\n", 1360 pDev->id); 1361 return 0; 1362 } 1363 if (!mask_in || valuator_mask_num_valuators(mask_in) <= 0) 1364 return 0; 1365 break; 1366 case ButtonPress: 1367 case ButtonRelease: 1368 if (!pDev->button || !buttons) 1369 return 0; 1370 if (mask_in && valuator_mask_size(mask_in) > 0 && !pDev->valuator) { 1371 ErrorF 1372 ("[dix] button event with valuator from device %d without valuators\n", 1373 pDev->id); 1374 return 0; 1375 } 1376 break; 1377 default: 1378 return 0; 1379 } 1380 1381 valuator_mask_copy(&mask, mask_in); 1382 1383 if ((flags & POINTER_NORAW) == 0) { 1384 raw = &events->raw_event; 1385 events++; 1386 num_events++; 1387 1388 init_raw(pDev, raw, ms, type, buttons); 1389 1390 if (flags & POINTER_EMULATED) 1391 raw->flags = XIPointerEmulated; 1392 1393 set_raw_valuators(raw, &mask, TRUE, raw->valuators.data_raw); 1394 } 1395 1396 valuator_mask_drop_unaccelerated(&mask); 1397 1398 /* valuators are in driver-native format (rel or abs) */ 1399 1400 if (flags & POINTER_ABSOLUTE) { 1401 if (flags & (POINTER_SCREEN | POINTER_DESKTOP)) { /* valuators are in screen/desktop coords */ 1402 sx = valuator_mask_get(&mask, 0); 1403 sy = valuator_mask_get(&mask, 1); 1404 scale_from_screen(pDev, &mask, flags); 1405 } 1406 1407 transformAbsolute(pDev, &mask); 1408 clipAbsolute(pDev, &mask); 1409 if ((flags & POINTER_NORAW) == 0 && raw) 1410 set_raw_valuators(raw, &mask, FALSE, raw->valuators.data); 1411 } 1412 else { 1413 transformRelative(pDev, &mask); 1414 1415 if (flags & POINTER_ACCELERATE) 1416 accelPointer(pDev, &mask, ms); 1417 if ((flags & POINTER_NORAW) == 0 && raw) 1418 set_raw_valuators(raw, &mask, FALSE, raw->valuators.data); 1419 1420 moveRelative(pDev, flags, &mask); 1421 } 1422 1423 /* valuators are in device coordinate system in absolute coordinates */ 1424 scale_to_desktop(pDev, &mask, &devx, &devy, &screenx, &screeny); 1425 1426 /* #53037 XWarpPointer's scaling back and forth between screen and 1427 device may leave us with rounding errors. End result is that the 1428 pointer doesn't end up on the pixel it should. 1429 Avoid this by forcing screenx/screeny back to what the input 1430 coordinates were. 1431 */ 1432 if (flags & POINTER_SCREEN) { 1433 scr = miPointerGetScreen(pDev); 1434 screenx = sx + scr->x; 1435 screeny = sy + scr->y; 1436 } 1437 1438 scr = positionSprite(pDev, (flags & POINTER_ABSOLUTE) ? Absolute : Relative, 1439 &mask, &devx, &devy, &screenx, &screeny, 1440 &num_barrier_events, events); 1441 num_events += num_barrier_events; 1442 events += num_barrier_events; 1443 1444 /* screenx, screeny are in desktop coordinates, 1445 mask is in device coordinates per-screen (the event data) 1446 devx/devy is in device coordinate desktop-wide */ 1447 updateHistory(pDev, &mask, ms); 1448 1449 clipValuators(pDev, &mask); 1450 1451 storeLastValuators(pDev, &mask, 0, 1, devx, devy); 1452 1453 /* Update the MD's coordinates, which are always in desktop space. */ 1454 if (!IsMaster(pDev) && !IsFloating(pDev)) { 1455 DeviceIntPtr master = GetMaster(pDev, MASTER_POINTER); 1456 1457 master->last.valuators[0] = screenx; 1458 master->last.valuators[1] = screeny; 1459 } 1460 1461 if ((flags & POINTER_RAWONLY) == 0) { 1462 num_events++; 1463 1464 event = &events->device_event; 1465 init_device_event(event, pDev, ms, EVENT_SOURCE_NORMAL); 1466 1467 if (type == MotionNotify) { 1468 event->type = ET_Motion; 1469 event->detail.button = 0; 1470 } 1471 else { 1472 if (type == ButtonPress) { 1473 event->type = ET_ButtonPress; 1474 set_button_down(pDev, buttons, BUTTON_POSTED); 1475 } 1476 else if (type == ButtonRelease) { 1477 event->type = ET_ButtonRelease; 1478 set_button_up(pDev, buttons, BUTTON_POSTED); 1479 } 1480 event->detail.button = buttons; 1481 } 1482 1483 /* root_x and root_y must be in per-screen coordinates */ 1484 event_set_root_coordinates(event, screenx - scr->x, screeny - scr->y); 1485 1486 if (flags & POINTER_EMULATED) 1487 event->flags = XIPointerEmulated; 1488 1489 set_valuators(pDev, event, &mask); 1490 } 1491 1492 return num_events; 1493} 1494 1495/** 1496 * Generate events for each scroll axis that changed between before/after 1497 * for the device. 1498 * 1499 * @param events The pointer to the event list to fill the events 1500 * @param dev The device to generate the events for 1501 * @param type The real type of the event 1502 * @param axis The axis number to generate events for 1503 * @param mask State before this event in absolute coords 1504 * @param[in,out] last Last scroll state posted in absolute coords (modified 1505 * in-place) 1506 * @param ms Current time in ms 1507 * @param max_events Max number of events to be generated 1508 * @return The number of events generated 1509 */ 1510static int 1511emulate_scroll_button_events(InternalEvent *events, 1512 DeviceIntPtr dev, 1513 int type, 1514 int axis, 1515 const ValuatorMask *mask, 1516 ValuatorMask *last, CARD32 ms, int max_events) 1517{ 1518 AxisInfoPtr ax; 1519 double delta; 1520 double incr; 1521 int num_events = 0; 1522 double total; 1523 int b; 1524 int flags = 0; 1525 1526 if (dev->valuator->axes[axis].scroll.type == SCROLL_TYPE_NONE) 1527 return 0; 1528 1529 if (!valuator_mask_isset(mask, axis)) 1530 return 0; 1531 1532 ax = &dev->valuator->axes[axis]; 1533 incr = ax->scroll.increment; 1534 1535 BUG_WARN_MSG(incr == 0, "for device %s\n", dev->name); 1536 if (incr == 0) 1537 return 0; 1538 1539 if (type != ButtonPress && type != ButtonRelease) 1540 flags |= POINTER_EMULATED; 1541 1542 if (!valuator_mask_isset(last, axis)) 1543 valuator_mask_set_double(last, axis, 0); 1544 1545 delta = 1546 valuator_mask_get_double(mask, axis) - valuator_mask_get_double(last, 1547 axis); 1548 total = delta; 1549 b = (ax->scroll.type == SCROLL_TYPE_VERTICAL) ? 5 : 7; 1550 1551 if ((incr > 0 && delta < 0) || (incr < 0 && delta > 0)) 1552 b--; /* we're scrolling up or left → button 4 or 6 */ 1553 1554 while (fabs(delta) >= fabs(incr)) { 1555 int nev_tmp; 1556 1557 if (delta > 0) 1558 delta -= fabs(incr); 1559 else if (delta < 0) 1560 delta += fabs(incr); 1561 1562 /* fill_pointer_events() generates four events: one normal and one raw 1563 * event for button press and button release. 1564 * We may get a bigger scroll delta than we can generate events 1565 * for. In that case, we keep decreasing delta, but skip events. 1566 */ 1567 if (num_events + 4 < max_events) { 1568 if (type != ButtonRelease) { 1569 nev_tmp = fill_pointer_events(events, dev, ButtonPress, b, ms, 1570 flags, NULL); 1571 events += nev_tmp; 1572 num_events += nev_tmp; 1573 } 1574 if (type != ButtonPress) { 1575 nev_tmp = fill_pointer_events(events, dev, ButtonRelease, b, ms, 1576 flags, NULL); 1577 events += nev_tmp; 1578 num_events += nev_tmp; 1579 } 1580 } 1581 } 1582 1583 /* We emulated, update last.scroll */ 1584 if (total != delta) { 1585 total -= delta; 1586 valuator_mask_set_double(last, axis, 1587 valuator_mask_get_double(last, axis) + total); 1588 } 1589 1590 return num_events; 1591} 1592 1593 1594/** 1595 * Generate a complete series of InternalEvents (filled into the EventList) 1596 * representing pointer motion, or button presses. If the device is a slave 1597 * device, also potentially generate a DeviceClassesChangedEvent to update 1598 * the master device. 1599 * 1600 * events is not NULL-terminated; the return value is the number of events. 1601 * The DDX is responsible for allocating the event structure in the first 1602 * place via InitEventList() and GetMaximumEventsNum(), and for freeing it. 1603 * 1604 * In the generated events rootX/Y will be in absolute screen coords and 1605 * the valuator information in the absolute or relative device coords. 1606 * 1607 * last.valuators[x] of the device is always in absolute device coords. 1608 * last.valuators[x] of the master device is in absolute screen coords. 1609 * 1610 * master->last.valuators[x] for x > 2 is undefined. 1611 */ 1612int 1613GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, 1614 int buttons, int flags, const ValuatorMask *mask_in) 1615{ 1616 CARD32 ms = GetTimeInMillis(); 1617 int num_events = 0, nev_tmp; 1618 ValuatorMask mask; 1619 ValuatorMask scroll; 1620 int i; 1621 int realtype = type; 1622 1623#ifdef XSERVER_DTRACE 1624 if (XSERVER_INPUT_EVENT_ENABLED()) { 1625 XSERVER_INPUT_EVENT(pDev->id, type, buttons, flags, 1626 mask_in ? mask_in->last_bit + 1 : 0, 1627 mask_in ? mask_in->mask : NULL, 1628 mask_in ? mask_in->valuators : NULL); 1629 } 1630#endif 1631 1632 BUG_RETURN_VAL(buttons >= MAX_BUTTONS, 0); 1633 1634 /* refuse events from disabled devices */ 1635 if (!pDev->enabled) 1636 return 0; 1637 1638 if (!miPointerGetScreen(pDev)) 1639 return 0; 1640 1641 events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, 1642 &num_events); 1643 1644 valuator_mask_copy(&mask, mask_in); 1645 1646 /* Turn a scroll button press into a smooth-scrolling event if 1647 * necessary. This only needs to cater for the XIScrollFlagPreferred 1648 * axis (if more than one scrolling axis is present) */ 1649 if (type == ButtonPress) { 1650 double adj; 1651 int axis; 1652 int h_scroll_axis = -1; 1653 int v_scroll_axis = -1; 1654 1655 if (pDev->valuator) { 1656 h_scroll_axis = pDev->valuator->h_scroll_axis; 1657 v_scroll_axis = pDev->valuator->v_scroll_axis; 1658 } 1659 1660 /* Up is negative on valuators, down positive */ 1661 switch (buttons) { 1662 case 4: 1663 adj = -1.0; 1664 axis = v_scroll_axis; 1665 break; 1666 case 5: 1667 adj = 1.0; 1668 axis = v_scroll_axis; 1669 break; 1670 case 6: 1671 adj = -1.0; 1672 axis = h_scroll_axis; 1673 break; 1674 case 7: 1675 adj = 1.0; 1676 axis = h_scroll_axis; 1677 break; 1678 default: 1679 adj = 0.0; 1680 axis = -1; 1681 break; 1682 } 1683 1684 if (adj != 0.0 && axis != -1) { 1685 adj *= pDev->valuator->axes[axis].scroll.increment; 1686 if (!valuator_mask_isset(&mask, axis)) 1687 valuator_mask_set(&mask, axis, 0); 1688 add_to_scroll_valuator(pDev, &mask, axis, adj); 1689 type = MotionNotify; 1690 buttons = 0; 1691 flags |= POINTER_EMULATED; 1692 } 1693 } 1694 1695 /* First fill out the original event set, with smooth-scrolling axes. */ 1696 nev_tmp = fill_pointer_events(events, pDev, type, buttons, ms, flags, 1697 &mask); 1698 events += nev_tmp; 1699 num_events += nev_tmp; 1700 1701 valuator_mask_zero(&scroll); 1702 1703 /* Now turn the smooth-scrolling axes back into emulated button presses 1704 * for legacy clients, based on the integer delta between before and now */ 1705 for (i = 0; i < valuator_mask_size(&mask); i++) { 1706 if ( !pDev->valuator || (i >= pDev->valuator->numAxes)) 1707 break; 1708 1709 if (!valuator_mask_isset(&mask, i)) 1710 continue; 1711 1712 valuator_mask_set_double(&scroll, i, pDev->last.valuators[i]); 1713 1714 nev_tmp = 1715 emulate_scroll_button_events(events, pDev, realtype, i, &scroll, 1716 pDev->last.scroll, ms, 1717 GetMaximumEventsNum() - num_events); 1718 events += nev_tmp; 1719 num_events += nev_tmp; 1720 } 1721 1722 return num_events; 1723} 1724 1725/** 1726 * Generate internal events representing this proximity event and enqueue 1727 * them on the event queue. 1728 * 1729 * This function is not reentrant. Disable signals before calling. 1730 * 1731 * @param device The device to generate the event for 1732 * @param type Event type, one of ProximityIn or ProximityOut 1733 * @param keycode Key code of the pressed/released key 1734 * @param mask Valuator mask for valuators present for this event. 1735 * 1736 */ 1737void 1738QueueProximityEvents(DeviceIntPtr device, int type, const ValuatorMask *mask) 1739{ 1740 int nevents; 1741 1742 nevents = GetProximityEvents(InputEventList, device, type, mask); 1743 queueEventList(device, InputEventList, nevents); 1744} 1745 1746/** 1747 * Generate ProximityIn/ProximityOut InternalEvents, accompanied by 1748 * valuators. 1749 * 1750 * The DDX is responsible for allocating the events in the first place via 1751 * InitEventList(), and for freeing it. 1752 * 1753 * @return the number of events written into events. 1754 */ 1755int 1756GetProximityEvents(InternalEvent *events, DeviceIntPtr pDev, int type, 1757 const ValuatorMask *mask_in) 1758{ 1759 int num_events = 1, i; 1760 DeviceEvent *event; 1761 ValuatorMask mask; 1762 1763#ifdef XSERVER_DTRACE 1764 if (XSERVER_INPUT_EVENT_ENABLED()) { 1765 XSERVER_INPUT_EVENT(pDev->id, type, 0, 0, 1766 mask_in ? mask_in->last_bit + 1 : 0, 1767 mask_in ? mask_in->mask : NULL, 1768 mask_in ? mask_in->valuators : NULL); 1769 } 1770#endif 1771 1772 /* refuse events from disabled devices */ 1773 if (!pDev->enabled) 1774 return 0; 1775 1776 /* Sanity checks. */ 1777 if ((type != ProximityIn && type != ProximityOut) || !mask_in) 1778 return 0; 1779 if (!pDev->valuator || !pDev->proximity) 1780 return 0; 1781 1782 valuator_mask_copy(&mask, mask_in); 1783 1784 /* ignore relative axes for proximity. */ 1785 for (i = 0; i < valuator_mask_size(&mask); i++) { 1786 if (valuator_mask_isset(&mask, i) && 1787 valuator_get_mode(pDev, i) == Relative) 1788 valuator_mask_unset(&mask, i); 1789 } 1790 1791 /* FIXME: posting proximity events with relative valuators only results 1792 * in an empty event, EventToXI() will fail to convert → no event sent 1793 * to client. */ 1794 1795 events = 1796 UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events); 1797 1798 event = &events->device_event; 1799 init_device_event(event, pDev, GetTimeInMillis(), EVENT_SOURCE_NORMAL); 1800 event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut; 1801 1802 clipValuators(pDev, &mask); 1803 1804 set_valuators(pDev, event, &mask); 1805 1806 return num_events; 1807} 1808 1809int 1810GetTouchOwnershipEvents(InternalEvent *events, DeviceIntPtr pDev, 1811 TouchPointInfoPtr ti, uint8_t reason, XID resource, 1812 uint32_t flags) 1813{ 1814 TouchClassPtr t = pDev->touch; 1815 TouchOwnershipEvent *event; 1816 CARD32 ms = GetTimeInMillis(); 1817 1818 if (!pDev->enabled || !t || !ti) 1819 return 0; 1820 1821 event = &events->touch_ownership_event; 1822 init_touch_ownership(pDev, event, ms); 1823 1824 event->touchid = ti->client_id; 1825 event->sourceid = ti->sourceid; 1826 event->resource = resource; 1827 event->flags = flags; 1828 event->reason = reason; 1829 1830 return 1; 1831} 1832 1833/** 1834 * Generate internal events representing this touch event and enqueue them 1835 * on the event queue. 1836 * 1837 * This function is not reentrant. Disable signals before calling. 1838 * 1839 * @param device The device to generate the event for 1840 * @param type Event type, one of XI_TouchBegin, XI_TouchUpdate, XI_TouchEnd 1841 * @param touchid Touch point ID 1842 * @param flags Event modification flags 1843 * @param mask Valuator mask for valuators present for this event. 1844 */ 1845void 1846QueueTouchEvents(DeviceIntPtr device, int type, 1847 uint32_t ddx_touchid, int flags, const ValuatorMask *mask) 1848{ 1849 int nevents; 1850 1851 nevents = 1852 GetTouchEvents(InputEventList, device, ddx_touchid, type, flags, mask); 1853 queueEventList(device, InputEventList, nevents); 1854} 1855 1856/** 1857 * Get events for a touch. Generates a TouchBegin event if end is not set and 1858 * the touch id is not active. Generates a TouchUpdate event if end is not set 1859 * and the touch id is active. Generates a TouchEnd event if end is set and the 1860 * touch id is active. 1861 * 1862 * events is not NULL-terminated; the return value is the number of events. 1863 * The DDX is responsible for allocating the event structure in the first 1864 * place via GetMaximumEventsNum(), and for freeing it. 1865 * 1866 * @param[out] events The list of events generated 1867 * @param dev The device to generate the events for 1868 * @param ddx_touchid The touch ID as assigned by the DDX 1869 * @param type XI_TouchBegin, XI_TouchUpdate or XI_TouchEnd 1870 * @param flags Event flags 1871 * @param mask_in Valuator information for this event 1872 */ 1873int 1874GetTouchEvents(InternalEvent *events, DeviceIntPtr dev, uint32_t ddx_touchid, 1875 uint16_t type, uint32_t flags, const ValuatorMask *mask_in) 1876{ 1877 ScreenPtr scr; 1878 TouchClassPtr t = dev->touch; 1879 ValuatorClassPtr v = dev->valuator; 1880 DeviceEvent *event; 1881 CARD32 ms = GetTimeInMillis(); 1882 ValuatorMask mask; 1883 double screenx = 0.0, screeny = 0.0; /* desktop coordinate system */ 1884 double devx = 0.0, devy = 0.0; /* desktop-wide in device coords */ 1885 int i; 1886 int num_events = 0; 1887 RawDeviceEvent *raw; 1888 DDXTouchPointInfoPtr ti; 1889 int need_rawevent = TRUE; 1890 Bool emulate_pointer = FALSE; 1891 int client_id = 0; 1892 1893#ifdef XSERVER_DTRACE 1894 if (XSERVER_INPUT_EVENT_ENABLED()) { 1895 XSERVER_INPUT_EVENT(dev->id, type, ddx_touchid, flags, 1896 mask_in ? mask_in->last_bit + 1 : 0, 1897 mask_in ? mask_in->mask : NULL, 1898 mask_in ? mask_in->valuators : NULL); 1899 } 1900#endif 1901 1902 if (!dev->enabled || !t || !v) 1903 return 0; 1904 1905 /* Find and/or create the DDX touch info */ 1906 1907 ti = TouchFindByDDXID(dev, ddx_touchid, (type == XI_TouchBegin)); 1908 if (!ti) { 1909 ErrorFSigSafe("[dix] %s: unable to %s touch point %u\n", dev->name, 1910 type == XI_TouchBegin ? "begin" : "find", ddx_touchid); 1911 return 0; 1912 } 1913 client_id = ti->client_id; 1914 1915 emulate_pointer = ti->emulate_pointer; 1916 1917 if (!IsMaster(dev)) 1918 events = 1919 UpdateFromMaster(events, dev, DEVCHANGE_POINTER_EVENT, &num_events); 1920 1921 valuator_mask_copy(&mask, mask_in); 1922 1923 if (need_rawevent) { 1924 raw = &events->raw_event; 1925 events++; 1926 num_events++; 1927 init_raw(dev, raw, ms, type, client_id); 1928 set_raw_valuators(raw, &mask, TRUE, raw->valuators.data_raw); 1929 } 1930 1931 event = &events->device_event; 1932 num_events++; 1933 1934 init_device_event(event, dev, ms, EVENT_SOURCE_NORMAL); 1935 1936 switch (type) { 1937 case XI_TouchBegin: 1938 event->type = ET_TouchBegin; 1939 /* If we're starting a touch, we must have x & y coordinates. */ 1940 if (!mask_in || 1941 !valuator_mask_isset(mask_in, 0) || 1942 !valuator_mask_isset(mask_in, 1)) { 1943 ErrorFSigSafe("%s: Attempted to start touch without x/y " 1944 "(driver bug)\n", dev->name); 1945 return 0; 1946 } 1947 break; 1948 case XI_TouchUpdate: 1949 event->type = ET_TouchUpdate; 1950 if (!mask_in || valuator_mask_num_valuators(mask_in) <= 0) { 1951 ErrorFSigSafe("%s: TouchUpdate with no valuators? Driver bug\n", 1952 dev->name); 1953 } 1954 break; 1955 case XI_TouchEnd: 1956 event->type = ET_TouchEnd; 1957 /* We can end the DDX touch here, since we don't use the active 1958 * field below */ 1959 TouchEndDDXTouch(dev, ti); 1960 break; 1961 default: 1962 return 0; 1963 } 1964 1965 /* Get our screen event coordinates (root_x/root_y/event_x/event_y): 1966 * these come from the touchpoint in Absolute mode, or the sprite in 1967 * Relative. */ 1968 if (t->mode == XIDirectTouch) { 1969 for (i = 0; i < max(valuator_mask_size(&mask), 2); i++) { 1970 double val; 1971 1972 if (valuator_mask_fetch_double(&mask, i, &val)) 1973 valuator_mask_set_double(ti->valuators, i, val); 1974 /* If the device doesn't post new X and Y axis values, 1975 * use the last values posted. 1976 */ 1977 else if (i < 2 && 1978 valuator_mask_fetch_double(ti->valuators, i, &val)) 1979 valuator_mask_set_double(&mask, i, val); 1980 } 1981 1982 transformAbsolute(dev, &mask); 1983 clipAbsolute(dev, &mask); 1984 } 1985 else { 1986 screenx = dev->spriteInfo->sprite->hotPhys.x; 1987 screeny = dev->spriteInfo->sprite->hotPhys.y; 1988 } 1989 if (need_rawevent) 1990 set_raw_valuators(raw, &mask, FALSE, raw->valuators.data); 1991 1992 scr = dev->spriteInfo->sprite->hotPhys.pScreen; 1993 1994 /* Indirect device touch coordinates are not used for cursor positioning. 1995 * They are merely informational, and are provided in device coordinates. 1996 * The device sprite is used for positioning instead, and it is already 1997 * scaled. */ 1998 if (t->mode == XIDirectTouch) 1999 scr = scale_to_desktop(dev, &mask, &devx, &devy, &screenx, &screeny); 2000 if (emulate_pointer) 2001 scr = positionSprite(dev, Absolute, &mask, 2002 &devx, &devy, &screenx, &screeny, NULL, NULL); 2003 2004 /* see fill_pointer_events for coordinate systems */ 2005 if (emulate_pointer) 2006 updateHistory(dev, &mask, ms); 2007 2008 clipValuators(dev, &mask); 2009 2010 if (emulate_pointer) 2011 storeLastValuators(dev, &mask, 0, 1, devx, devy); 2012 2013 /* Update the MD's coordinates, which are always in desktop space. */ 2014 if (emulate_pointer && !IsMaster(dev) && !IsFloating(dev)) { 2015 DeviceIntPtr master = GetMaster(dev, MASTER_POINTER); 2016 2017 master->last.valuators[0] = screenx; 2018 master->last.valuators[1] = screeny; 2019 } 2020 2021 event->root = scr->root->drawable.id; 2022 2023 event_set_root_coordinates(event, screenx - scr->x, screeny - scr->y); 2024 event->touchid = client_id; 2025 event->flags = flags; 2026 2027 if (emulate_pointer) { 2028 event->flags |= TOUCH_POINTER_EMULATED; 2029 event->detail.button = 1; 2030 } 2031 2032 set_valuators(dev, event, &mask); 2033 for (i = 0; i < v->numAxes; i++) { 2034 if (valuator_mask_isset(&mask, i)) 2035 v->axisVal[i] = valuator_mask_get(&mask, i); 2036 } 2037 2038 return num_events; 2039} 2040 2041void 2042GetDixTouchEnd(InternalEvent *ievent, DeviceIntPtr dev, TouchPointInfoPtr ti, 2043 uint32_t flags) 2044{ 2045 ScreenPtr scr = dev->spriteInfo->sprite->hotPhys.pScreen; 2046 DeviceEvent *event = &ievent->device_event; 2047 CARD32 ms = GetTimeInMillis(); 2048 2049 BUG_WARN(!dev->enabled); 2050 2051 init_device_event(event, dev, ms, EVENT_SOURCE_NORMAL); 2052 2053 event->sourceid = ti->sourceid; 2054 event->type = ET_TouchEnd; 2055 2056 event->root = scr->root->drawable.id; 2057 2058 /* Get screen event coordinates from the sprite. Is this really the best 2059 * we can do? */ 2060 event_set_root_coordinates(event, 2061 dev->last.valuators[0] - scr->x, 2062 dev->last.valuators[1] - scr->y); 2063 event->touchid = ti->client_id; 2064 event->flags = flags; 2065 2066 if (flags & TOUCH_POINTER_EMULATED) { 2067 event->flags |= TOUCH_POINTER_EMULATED; 2068 event->detail.button = 1; 2069 } 2070} 2071 2072/** 2073 * Synthesize a single motion event for the core pointer. 2074 * 2075 * Used in cursor functions, e.g. when cursor confinement changes, and we need 2076 * to shift the pointer to get it inside the new bounds. 2077 */ 2078void 2079PostSyntheticMotion(DeviceIntPtr pDev, 2080 int x, int y, int screen, unsigned long time) 2081{ 2082 DeviceEvent ev; 2083 2084#ifdef PANORAMIX 2085 /* Translate back to the sprite screen since processInputProc 2086 will translate from sprite screen to screen 0 upon reentry 2087 to the DIX layer. */ 2088 if (!noPanoramiXExtension) { 2089 x += screenInfo.screens[0]->x - screenInfo.screens[screen]->x; 2090 y += screenInfo.screens[0]->y - screenInfo.screens[screen]->y; 2091 } 2092#endif 2093 2094 memset(&ev, 0, sizeof(DeviceEvent)); 2095 init_device_event(&ev, pDev, time, EVENT_SOURCE_NORMAL); 2096 ev.root_x = x; 2097 ev.root_y = y; 2098 ev.type = ET_Motion; 2099 ev.time = time; 2100 2101 /* FIXME: MD/SD considerations? */ 2102 (*pDev->public.processInputProc) ((InternalEvent *) &ev, pDev); 2103} 2104 2105void 2106InitGestureEvent(InternalEvent *ievent, DeviceIntPtr dev, CARD32 ms, 2107 int type, uint16_t num_touches, uint32_t flags, 2108 double delta_x, double delta_y, 2109 double delta_unaccel_x, double delta_unaccel_y, 2110 double scale, double delta_angle) 2111{ 2112 ScreenPtr scr = dev->spriteInfo->sprite->hotPhys.pScreen; 2113 GestureEvent *event = &ievent->gesture_event; 2114 double screenx = 0.0, screeny = 0.0; /* desktop coordinate system */ 2115 2116 init_gesture_event(event, dev, ms); 2117 2118 screenx = dev->spriteInfo->sprite->hotPhys.x; 2119 screeny = dev->spriteInfo->sprite->hotPhys.y; 2120 2121 event->type = type; 2122 event->root = scr->root->drawable.id; 2123 event->root_x = screenx - scr->x; 2124 event->root_y = screeny - scr->y; 2125 event->num_touches = num_touches; 2126 event->flags = flags; 2127 2128 event->delta_x = delta_x; 2129 event->delta_y = delta_y; 2130 event->delta_unaccel_x = delta_unaccel_x; 2131 event->delta_unaccel_y = delta_unaccel_y; 2132 event->scale = scale; 2133 event->delta_angle = delta_angle; 2134} 2135 2136/** 2137 * Get events for a pinch or swipe gesture. 2138 * 2139 * events is not NULL-terminated; the return value is the number of events. 2140 * The DDX is responsible for allocating the event structure in the first 2141 * place via GetMaximumEventsNum(), and for freeing it. 2142 * 2143 * @param[out] events The list of events generated 2144 * @param dev The device to generate the events for 2145 * @param type XI_Gesture{Pinch,Swipe}{Begin,Update,End} 2146 * @prama num_touches The number of touches in the gesture 2147 * @param flags Event flags 2148 * @param delta_x,delta_y accelerated relative motion delta 2149 * @param delta_unaccel_x,delta_unaccel_y unaccelerated relative motion delta 2150 * @param scale (valid only to pinch events) absolute scale of a pinch gesture 2151 * @param delta_angle (valid only to pinch events) the ange delta in degrees between the last and 2152 * the current pinch event. 2153 */ 2154int 2155GetGestureEvents(InternalEvent *events, DeviceIntPtr dev, 2156 uint16_t type, uint16_t num_touches, uint32_t flags, 2157 double delta_x, double delta_y, 2158 double delta_unaccel_x, double delta_unaccel_y, 2159 double scale, double delta_angle) 2160 2161{ 2162 GestureClassPtr g = dev->gesture; 2163 CARD32 ms = GetTimeInMillis(); 2164 enum EventType evtype; 2165 int num_events = 0; 2166 uint32_t evflags = 0; 2167 2168 if (!dev->enabled || !g) 2169 return 0; 2170 2171 if (!IsMaster(dev)) 2172 events = UpdateFromMaster(events, dev, DEVCHANGE_POINTER_EVENT, 2173 &num_events); 2174 2175 switch (type) { 2176 case XI_GesturePinchBegin: 2177 evtype = ET_GesturePinchBegin; 2178 break; 2179 case XI_GesturePinchUpdate: 2180 evtype = ET_GesturePinchUpdate; 2181 break; 2182 case XI_GesturePinchEnd: 2183 evtype = ET_GesturePinchEnd; 2184 if (flags & XIGesturePinchEventCancelled) 2185 evflags |= GESTURE_CANCELLED; 2186 break; 2187 case XI_GestureSwipeBegin: 2188 evtype = ET_GestureSwipeBegin; 2189 break; 2190 case XI_GestureSwipeUpdate: 2191 evtype = ET_GestureSwipeUpdate; 2192 break; 2193 case XI_GestureSwipeEnd: 2194 evtype = ET_GestureSwipeEnd; 2195 if (flags & XIGestureSwipeEventCancelled) 2196 evflags |= GESTURE_CANCELLED; 2197 break; 2198 default: 2199 return 0; 2200 } 2201 2202 InitGestureEvent(events, dev, ms, evtype, num_touches, evflags, 2203 delta_x, delta_y, delta_unaccel_x, delta_unaccel_y, 2204 scale, delta_angle); 2205 num_events++; 2206 2207 return num_events; 2208} 2209 2210void 2211QueueGesturePinchEvents(DeviceIntPtr dev, uint16_t type, 2212 uint16_t num_touches, uint32_t flags, 2213 double delta_x, double delta_y, 2214 double delta_unaccel_x, 2215 double delta_unaccel_y, 2216 double scale, double delta_angle) 2217{ 2218 int nevents; 2219 nevents = GetGestureEvents(InputEventList, dev, type, num_touches, flags, 2220 delta_x, delta_y, 2221 delta_unaccel_x, delta_unaccel_y, 2222 scale, delta_angle); 2223 queueEventList(dev, InputEventList, nevents); 2224} 2225 2226void 2227QueueGestureSwipeEvents(DeviceIntPtr dev, uint16_t type, 2228 uint16_t num_touches, uint32_t flags, 2229 double delta_x, double delta_y, 2230 double delta_unaccel_x, 2231 double delta_unaccel_y) 2232{ 2233 int nevents; 2234 nevents = GetGestureEvents(InputEventList, dev, type, num_touches, flags, 2235 delta_x, delta_y, 2236 delta_unaccel_x, delta_unaccel_y, 2237 0.0, 0.0); 2238 queueEventList(dev, InputEventList, nevents); 2239} 2240