getevents.c revision 65b04b38
1/* 2 * Copyright © 2006 Nokia Corporation 3 * Copyright © 2006-2007 Daniel Stone 4 * Copyright © 2008 Red Hat, Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the next 14 * paragraph) shall be included in all copies or substantial portions of the 15 * Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 * DEALINGS IN THE SOFTWARE. 24 * 25 * Authors: Daniel Stone <daniel@fooishbar.org> 26 * Peter Hutterer <peter.hutterer@who-t.net> 27 */ 28 29#ifdef HAVE_DIX_CONFIG_H 30#include <dix-config.h> 31#endif 32 33#include <X11/X.h> 34#include <X11/keysym.h> 35#include <X11/Xproto.h> 36#include <math.h> 37 38#include "misc.h" 39#include "resource.h" 40#include "inputstr.h" 41#include "scrnintstr.h" 42#include "cursorstr.h" 43#include "dixstruct.h" 44#include "globals.h" 45#include "dixevents.h" 46#include "mipointer.h" 47#include "eventstr.h" 48#include "eventconvert.h" 49#include "inpututils.h" 50 51#include <X11/extensions/XKBproto.h> 52#include "xkbsrv.h" 53 54#ifdef PANORAMIX 55#include "panoramiX.h" 56#include "panoramiXsrv.h" 57#endif 58 59#include <X11/extensions/XI.h> 60#include <X11/extensions/XIproto.h> 61#include <pixman.h> 62#include "exglobals.h" 63#include "exevents.h" 64#include "exglobals.h" 65#include "extnsionst.h" 66#include "listdev.h" /* for sizing up DeviceClassesChangedEvent */ 67 68/* Number of motion history events to store. */ 69#define MOTION_HISTORY_SIZE 256 70 71/* InputEventList is the container list for all input events generated by the 72 * DDX. The DDX is expected to call GetEventList() and then pass the list into 73 * Get{Pointer|Keyboard}Events. 74 */ 75EventListPtr InputEventList = NULL; 76int InputEventListLen = 0; 77 78int 79GetEventList(EventListPtr* list) 80{ 81 *list = InputEventList; 82 return InputEventListLen; 83} 84 85/** 86 * Pick some arbitrary size for Xi motion history. 87 */ 88int 89GetMotionHistorySize(void) 90{ 91 return MOTION_HISTORY_SIZE; 92} 93 94void 95set_button_down(DeviceIntPtr pDev, int button, int type) 96{ 97 if (type == BUTTON_PROCESSED) 98 SetBit(pDev->button->down, button); 99 else 100 SetBit(pDev->button->postdown, button); 101} 102 103void 104set_button_up(DeviceIntPtr pDev, int button, int type) 105{ 106 if (type == BUTTON_PROCESSED) 107 ClearBit(pDev->button->down, button); 108 else 109 ClearBit(pDev->button->postdown, button); 110} 111 112Bool 113button_is_down(DeviceIntPtr pDev, int button, int type) 114{ 115 Bool ret = FALSE; 116 117 if (type & BUTTON_PROCESSED) 118 ret = ret || BitIsOn(pDev->button->down, button); 119 if (type & BUTTON_POSTED) 120 ret = ret || BitIsOn(pDev->button->postdown, button); 121 122 return ret; 123} 124 125void 126set_key_down(DeviceIntPtr pDev, int key_code, int type) 127{ 128 if (type == KEY_PROCESSED) 129 SetBit(pDev->key->down, key_code); 130 else 131 SetBit(pDev->key->postdown, key_code); 132} 133 134void 135set_key_up(DeviceIntPtr pDev, int key_code, int type) 136{ 137 if (type == KEY_PROCESSED) 138 ClearBit(pDev->key->down, key_code); 139 else 140 ClearBit(pDev->key->postdown, key_code); 141} 142 143Bool 144key_is_down(DeviceIntPtr pDev, int key_code, int type) 145{ 146 Bool ret = FALSE; 147 148 if (type & KEY_PROCESSED) 149 ret = ret || BitIsOn(pDev->key->down, key_code); 150 if (type & KEY_POSTED) 151 ret = ret || BitIsOn(pDev->key->postdown, key_code); 152 153 return ret; 154} 155 156static Bool 157key_autorepeats(DeviceIntPtr pDev, int key_code) 158{ 159 return !!(pDev->kbdfeed->ctrl.autoRepeats[key_code >> 3] & 160 (1 << (key_code & 7))); 161} 162 163static void 164init_event(DeviceIntPtr dev, DeviceEvent* event, Time ms) 165{ 166 memset(event, 0, sizeof(DeviceEvent)); 167 event->header = ET_Internal; 168 event->length = sizeof(DeviceEvent); 169 event->time = ms; 170 event->deviceid = dev->id; 171 event->sourceid = dev->id; 172} 173 174static void 175init_raw(DeviceIntPtr dev, RawDeviceEvent *event, Time ms, int type, int detail) 176{ 177 memset(event, 0, sizeof(RawDeviceEvent)); 178 event->header = ET_Internal; 179 event->length = sizeof(RawDeviceEvent); 180 event->type = ET_RawKeyPress - ET_KeyPress + type; 181 event->time = ms; 182 event->deviceid = dev->id; 183 event->sourceid = dev->id; 184 event->detail.button = detail; 185} 186 187static void 188set_raw_valuators(RawDeviceEvent *event, ValuatorMask *mask, int32_t* data) 189{ 190 int i; 191 192 for (i = 0; i < valuator_mask_size(mask); i++) 193 { 194 if (valuator_mask_isset(mask, i)) 195 { 196 SetBit(event->valuators.mask, i); 197 data[i] = valuator_mask_get(mask, i); 198 } 199 } 200} 201 202 203static void 204set_valuators(DeviceIntPtr dev, DeviceEvent* event, ValuatorMask *mask) 205{ 206 int i; 207 208 /* Set the data to the previous value for unset absolute axes. The values 209 * may be used when sent as part of an XI 1.x valuator event. */ 210 for (i = 0; i < valuator_mask_size(mask); i++) 211 { 212 if (valuator_mask_isset(mask, i)) 213 { 214 SetBit(event->valuators.mask, i); 215 if (valuator_get_mode(dev, i) == Absolute) 216 SetBit(event->valuators.mode, i); 217 event->valuators.data[i] = valuator_mask_get(mask, i); 218 event->valuators.data_frac[i] = 219 dev->last.remainder[i] * (1 << 16) * (1 << 16); 220 } 221 else if (valuator_get_mode(dev, i) == Absolute) 222 event->valuators.data[i] = dev->valuator->axisVal[i]; 223 } 224} 225 226void 227CreateClassesChangedEvent(EventList* event, 228 DeviceIntPtr master, 229 DeviceIntPtr slave, 230 int type) 231{ 232 int i; 233 DeviceChangedEvent *dce; 234 CARD32 ms = GetTimeInMillis(); 235 236 dce = (DeviceChangedEvent*)event->event; 237 memset(dce, 0, sizeof(DeviceChangedEvent)); 238 dce->deviceid = slave->id; 239 dce->masterid = master->id; 240 dce->header = ET_Internal; 241 dce->length = sizeof(DeviceChangedEvent); 242 dce->type = ET_DeviceChanged; 243 dce->time = ms; 244 dce->flags = type; 245 dce->flags |= DEVCHANGE_SLAVE_SWITCH; 246 dce->sourceid = slave->id; 247 248 if (slave->button) 249 { 250 dce->buttons.num_buttons = slave->button->numButtons; 251 for (i = 0; i < dce->buttons.num_buttons; i++) 252 dce->buttons.names[i] = slave->button->labels[i]; 253 } 254 if (slave->valuator) 255 { 256 dce->num_valuators = slave->valuator->numAxes; 257 for (i = 0; i < dce->num_valuators; i++) 258 { 259 dce->valuators[i].min = slave->valuator->axes[i].min_value; 260 dce->valuators[i].max = slave->valuator->axes[i].max_value; 261 dce->valuators[i].resolution = slave->valuator->axes[i].resolution; 262 dce->valuators[i].mode = slave->valuator->axes[i].mode; 263 dce->valuators[i].name = slave->valuator->axes[i].label; 264 } 265 } 266 if (slave->key) 267 { 268 dce->keys.min_keycode = slave->key->xkbInfo->desc->min_key_code; 269 dce->keys.max_keycode = slave->key->xkbInfo->desc->max_key_code; 270 } 271} 272 273/** 274 * Rescale the coord between the two axis ranges. 275 */ 276static int 277rescaleValuatorAxis(int coord, float remainder, float *remainder_return, AxisInfoPtr from, AxisInfoPtr to, 278 int defmax) 279{ 280 int fmin = 0, tmin = 0, fmax = defmax, tmax = defmax, coord_return; 281 float value; 282 283 if(from && from->min_value < from->max_value) { 284 fmin = from->min_value; 285 fmax = from->max_value; 286 } 287 if(to && to->min_value < to->max_value) { 288 tmin = to->min_value; 289 tmax = to->max_value; 290 } 291 292 if(fmin == tmin && fmax == tmax) { 293 if (remainder_return) 294 *remainder_return = remainder; 295 return coord; 296 } 297 298 if(fmax == fmin) { /* avoid division by 0 */ 299 if (remainder_return) 300 *remainder_return = 0.0; 301 return 0; 302 } 303 304 value = (coord + remainder - fmin) * (tmax - tmin) / (fmax - fmin) + tmin; 305 coord_return = lroundf(value); 306 if (remainder_return) 307 *remainder_return = value - coord_return; 308 return coord_return; 309} 310 311/** 312 * Update all coordinates when changing to a different SD 313 * to ensure that relative reporting will work as expected 314 * without loss of precision. 315 * 316 * pDev->last.valuators will be in absolute device coordinates after this 317 * function. 318 */ 319static void 320updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev) 321{ 322 ScreenPtr scr = miPointerGetScreen(pDev); 323 int i; 324 DeviceIntPtr lastSlave; 325 326 /* master->last.valuators[0]/[1] is in screen coords and the actual 327 * position of the pointer */ 328 pDev->last.valuators[0] = master->last.valuators[0]; 329 pDev->last.valuators[1] = master->last.valuators[1]; 330 331 if (!pDev->valuator) 332 return; 333 334 /* scale back to device coordinates */ 335 if(pDev->valuator->numAxes > 0) 336 pDev->last.valuators[0] = rescaleValuatorAxis(pDev->last.valuators[0], pDev->last.remainder[0], 337 &pDev->last.remainder[0], NULL, pDev->valuator->axes + 0, scr->width); 338 if(pDev->valuator->numAxes > 1) 339 pDev->last.valuators[1] = rescaleValuatorAxis(pDev->last.valuators[1], pDev->last.remainder[1], 340 &pDev->last.remainder[1], NULL, pDev->valuator->axes + 1, scr->height); 341 342 /* calculate the other axis as well based on info from the old 343 * slave-device. If the old slave had less axes than this one, 344 * last.valuators is reset to 0. 345 */ 346 if ((lastSlave = master->last.slave) && lastSlave->valuator) { 347 for (i = 2; i < pDev->valuator->numAxes; i++) { 348 if (i >= lastSlave->valuator->numAxes) 349 pDev->last.valuators[i] = 0; 350 else 351 pDev->last.valuators[i] = 352 rescaleValuatorAxis(pDev->last.valuators[i], 353 pDev->last.remainder[i], 354 &pDev->last.remainder[i], 355 lastSlave->valuator->axes + i, 356 pDev->valuator->axes + i, 0); 357 } 358 } 359 360} 361 362/** 363 * Allocate the motion history buffer. 364 */ 365void 366AllocateMotionHistory(DeviceIntPtr pDev) 367{ 368 int size; 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 /* XI1 doesn't understand mixed mode devices */ 384 for (numAxes = 0; numAxes < v->numAxes; numAxes++) 385 if (valuator_get_mode(pDev, numAxes) != valuator_get_mode(pDev, 0)) 386 break; 387 size = sizeof(INT32) * numAxes; 388 } 389 390 size += sizeof(Time); 391 392 pDev->valuator->motion = calloc(pDev->valuator->numMotionEvents, size); 393 pDev->valuator->first_motion = 0; 394 pDev->valuator->last_motion = 0; 395 if (!pDev->valuator->motion) 396 ErrorF("[dix] %s: Failed to alloc motion history (%d bytes).\n", 397 pDev->name, size * pDev->valuator->numMotionEvents); 398} 399 400/** 401 * Dump the motion history between start and stop into the supplied buffer. 402 * Only records the event for a given screen in theory, but in practice, we 403 * sort of ignore this. 404 * 405 * If core is set, we only generate x/y, in INT16, scaled to screen coords. 406 */ 407int 408GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start, 409 unsigned long stop, ScreenPtr pScreen, BOOL core) 410{ 411 char *ibuff = NULL, *obuff; 412 int i = 0, ret = 0; 413 int j, coord; 414 Time current; 415 /* The size of a single motion event. */ 416 int size; 417 int dflt; 418 AxisInfo from, *to; /* for scaling */ 419 INT32 *ocbuf, *icbuf; /* pointer to coordinates for copying */ 420 INT16 *corebuf; 421 AxisInfo core_axis = {0}; 422 423 if (!pDev->valuator || !pDev->valuator->numMotionEvents) 424 return 0; 425 426 if (core && !pScreen) 427 return 0; 428 429 if (IsMaster(pDev)) 430 size = (sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(Time); 431 else 432 size = (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time); 433 434 *buff = malloc(size * pDev->valuator->numMotionEvents); 435 if (!(*buff)) 436 return 0; 437 obuff = (char *)*buff; 438 439 for (i = pDev->valuator->first_motion; 440 i != pDev->valuator->last_motion; 441 i = (i + 1) % pDev->valuator->numMotionEvents) { 442 /* We index the input buffer by which element we're accessing, which 443 * is not monotonic, and the output buffer by how many events we've 444 * written so far. */ 445 ibuff = (char *) pDev->valuator->motion + (i * size); 446 memcpy(¤t, ibuff, sizeof(Time)); 447 448 if (current > stop) { 449 return ret; 450 } 451 else if (current >= start) { 452 if (core) 453 { 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 = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, pScreen->width); 468 469 memcpy(corebuf, &coord, sizeof(INT16)); 470 corebuf++; 471 472 /* fetch y coordinate + range */ 473 memcpy(&from.min_value, icbuf++, sizeof(INT32)); 474 memcpy(&from.max_value, icbuf++, sizeof(INT32)); 475 memcpy(&coord, icbuf++, sizeof(INT32)); 476 477 to->max_value = pScreen->height; 478 coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, pScreen->height); 479 memcpy(corebuf, &coord, sizeof(INT16)); 480 481 } else if (IsMaster(pDev)) 482 { 483 memcpy(obuff, ibuff, sizeof(Time)); /* copy timestamp */ 484 485 ocbuf = (INT32*)(obuff + sizeof(Time)); 486 icbuf = (INT32*)(ibuff + sizeof(Time)); 487 for (j = 0; j < MAX_VALUATORS; j++) 488 { 489 if (j >= pDev->valuator->numAxes) 490 break; 491 492 /* fetch min/max/coordinate */ 493 memcpy(&from.min_value, icbuf++, sizeof(INT32)); 494 memcpy(&from.max_value, icbuf++, sizeof(INT32)); 495 memcpy(&coord, icbuf++, sizeof(INT32)); 496 497 to = (j < pDev->valuator->numAxes) ? &pDev->valuator->axes[j] : NULL; 498 499 /* x/y scaled to screen if no range is present */ 500 if (j == 0 && (from.max_value < from.min_value)) 501 from.max_value = pScreen->width; 502 else if (j == 1 && (from.max_value < from.min_value)) 503 from.max_value = pScreen->height; 504 505 if (j == 0 && (to->max_value < to->min_value)) 506 dflt = pScreen->width; 507 else if (j == 1 && (to->max_value < to->min_value)) 508 dflt = pScreen->height; 509 else 510 dflt = 0; 511 512 /* scale from stored range into current range */ 513 coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, 0); 514 memcpy(ocbuf, &coord, sizeof(INT32)); 515 ocbuf++; 516 } 517 } else 518 memcpy(obuff, ibuff, size); 519 520 /* don't advance by size here. size may be different to the 521 * actually written size if the MD has less valuators than MAX */ 522 if (core) 523 obuff += sizeof(INT32) + sizeof(Time); 524 else 525 obuff += (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time); 526 ret++; 527 } 528 } 529 530 return ret; 531} 532 533 534/** 535 * Update the motion history for a specific device, with the list of 536 * valuators. 537 * 538 * Layout of the history buffer: 539 * for SDs: [time] [val0] [val1] ... [valn] 540 * for MDs: [time] [min_val0] [max_val0] [val0] [min_val1] ... [valn] 541 * 542 * For events that have some valuators unset: 543 * min_val == max_val == val == 0. 544 */ 545static void 546updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, ValuatorMask *mask, 547 int *valuators) 548{ 549 char *buff = (char *) pDev->valuator->motion; 550 ValuatorClassPtr v; 551 int i; 552 553 if (!pDev->valuator->numMotionEvents) 554 return; 555 556 v = pDev->valuator; 557 if (IsMaster(pDev)) 558 { 559 buff += ((sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(CARD32)) * 560 v->last_motion; 561 562 memcpy(buff, &ms, sizeof(Time)); 563 buff += sizeof(Time); 564 565 memset(buff, 0, sizeof(INT32) * 3 * MAX_VALUATORS); 566 567 for (i = 0; i < v->numAxes; i++) 568 { 569 /* XI1 doesn't support mixed mode devices */ 570 if (valuator_get_mode(pDev, i) != valuator_get_mode(pDev, 0)) 571 break; 572 if (valuator_mask_size(mask) <= i || !valuator_mask_isset(mask, i)) 573 { 574 buff += 3 * sizeof(INT32); 575 continue; 576 } 577 memcpy(buff, &v->axes[i].min_value, sizeof(INT32)); 578 buff += sizeof(INT32); 579 memcpy(buff, &v->axes[i].max_value, sizeof(INT32)); 580 buff += sizeof(INT32); 581 memcpy(buff, &valuators[i], sizeof(INT32)); 582 buff += sizeof(INT32); 583 } 584 } else 585 { 586 587 buff += ((sizeof(INT32) * pDev->valuator->numAxes) + sizeof(CARD32)) * 588 pDev->valuator->last_motion; 589 590 memcpy(buff, &ms, sizeof(Time)); 591 buff += sizeof(Time); 592 593 memset(buff, 0, sizeof(INT32) * pDev->valuator->numAxes); 594 595 for (i = 0; i < MAX_VALUATORS; i++) 596 { 597 if (valuator_mask_size(mask) <= i || !valuator_mask_isset(mask, i)) 598 { 599 buff += sizeof(INT32); 600 continue; 601 } 602 memcpy(buff, &valuators[i], sizeof(INT32)); 603 buff += sizeof(INT32); 604 } 605 } 606 607 pDev->valuator->last_motion = (pDev->valuator->last_motion + 1) % 608 pDev->valuator->numMotionEvents; 609 /* If we're wrapping around, just keep the circular buffer going. */ 610 if (pDev->valuator->first_motion == pDev->valuator->last_motion) 611 pDev->valuator->first_motion = (pDev->valuator->first_motion + 1) % 612 pDev->valuator->numMotionEvents; 613 614 return; 615} 616 617 618/** 619 * Returns the maximum number of events GetKeyboardEvents, 620 * GetKeyboardValuatorEvents, and GetPointerEvents will ever return. 621 * 622 * This MUST be absolutely constant, from init until exit. 623 */ 624int 625GetMaximumEventsNum(void) { 626 /* One raw event 627 * One device event 628 * One possible device changed event 629 */ 630 return 3; 631} 632 633 634/** 635 * Clip an axis to its bounds, which are declared in the call to 636 * InitValuatorAxisClassStruct. 637 */ 638static void 639clipAxis(DeviceIntPtr pDev, int axisNum, int *val) 640{ 641 AxisInfoPtr axis; 642 643 if (axisNum >= pDev->valuator->numAxes) 644 return; 645 646 axis = pDev->valuator->axes + axisNum; 647 648 /* If a value range is defined, clip. If not, do nothing */ 649 if (axis->max_value <= axis->min_value) 650 return; 651 652 if (*val < axis->min_value) 653 *val = axis->min_value; 654 if (*val > axis->max_value) 655 *val = axis->max_value; 656} 657 658/** 659 * Clip every axis in the list of valuators to its bounds. 660 */ 661static void 662clipValuators(DeviceIntPtr pDev, ValuatorMask *mask) 663{ 664 int i; 665 666 for (i = 0; i < valuator_mask_size(mask); i++) 667 if (valuator_mask_isset(mask, i)) 668 { 669 int val = valuator_mask_get(mask, i); 670 clipAxis(pDev, i, &val); 671 valuator_mask_set(mask, i, val); 672 } 673} 674 675/** 676 * Create the DCCE event (does not update the master's device state yet, this 677 * is done in the event processing). 678 * Pull in the coordinates from the MD if necessary. 679 * 680 * @param events Pointer to a pre-allocated event list. 681 * @param dev The slave device that generated an event. 682 * @param type Either DEVCHANGE_POINTER_EVENT and/or DEVCHANGE_KEYBOARD_EVENT 683 * @param num_events The current number of events, returns the number of 684 * events if a DCCE was generated. 685 * @return The updated @events pointer. 686 */ 687EventListPtr 688UpdateFromMaster(EventListPtr events, DeviceIntPtr dev, int type, int *num_events) 689{ 690 DeviceIntPtr master; 691 692 master = GetMaster(dev, (type & DEVCHANGE_POINTER_EVENT) ? MASTER_POINTER : MASTER_KEYBOARD); 693 694 if (master && master->last.slave != dev) 695 { 696 CreateClassesChangedEvent(events, master, dev, type); 697 if (IsPointerDevice(master)) 698 { 699 updateSlaveDeviceCoords(master, dev); 700 master->last.numValuators = dev->last.numValuators; 701 } 702 master->last.slave = dev; 703 (*num_events)++; 704 events++; 705 } 706 return events; 707} 708 709/** 710 * Move the device's pointer to the position given in the valuators. 711 * 712 * @param dev The device which's pointer is to be moved. 713 * @param x Returns the x position of the pointer after the move. 714 * @param y Returns the y position of the pointer after the move. 715 * @param mask Bit mask of valid valuators. 716 * @param valuators Valuator data for each axis between @first and 717 * @first+@num. 718 */ 719static void 720moveAbsolute(DeviceIntPtr dev, int *x, int *y, ValuatorMask *mask) 721{ 722 int i; 723 724 if (valuator_mask_isset(mask, 0)) 725 *x = valuator_mask_get(mask, 0); 726 else 727 *x = dev->last.valuators[0]; 728 729 if (valuator_mask_isset(mask, 1)) 730 *y = valuator_mask_get(mask, 1); 731 else 732 *y = dev->last.valuators[1]; 733 734 clipAxis(dev, 0, x); 735 clipAxis(dev, 1, y); 736 737 for (i = 2; i < valuator_mask_size(mask); i++) 738 { 739 if (valuator_mask_isset(mask, i)) 740 { 741 dev->last.valuators[i] = valuator_mask_get(mask, i); 742 clipAxis(dev, i, &dev->last.valuators[i]); 743 } 744 } 745} 746 747/** 748 * Move the device's pointer by the values given in @valuators. 749 * 750 * @param dev The device which's pointer is to be moved. 751 * @param x Returns the x position of the pointer after the move. 752 * @param y Returns the y position of the pointer after the move. 753 * @param mask Bit mask of valid valuators. 754 * @param valuators Valuator data for each axis between @first and 755 * @first+@num. 756 */ 757static void 758moveRelative(DeviceIntPtr dev, int *x, int *y, ValuatorMask *mask) 759{ 760 int i; 761 762 *x = dev->last.valuators[0]; 763 *y = dev->last.valuators[1]; 764 765 if (valuator_mask_isset(mask, 0)) 766 *x += valuator_mask_get(mask, 0); 767 768 if (valuator_mask_isset(mask, 1)) 769 *y += valuator_mask_get(mask, 1); 770 771 /* if attached, clip both x and y to the defined limits (usually 772 * co-ord space limit). If it is attached, we need x/y to go over the 773 * limits to be able to change screens. */ 774 if(dev->u.master && dev->valuator) { 775 if (valuator_get_mode(dev, 0) == Absolute) 776 clipAxis(dev, 0, x); 777 if (valuator_get_mode(dev, 1) == Absolute) 778 clipAxis(dev, 1, y); 779 } 780 781 /* calc other axes, clip, drop back into valuators */ 782 for (i = 2; i < valuator_mask_size(mask); i++) 783 { 784 if (valuator_mask_isset(mask, i)) 785 { 786 dev->last.valuators[i] += valuator_mask_get(mask, i); 787 if (valuator_get_mode(dev, i) == Absolute) 788 clipAxis(dev, i, &dev->last.valuators[i]); 789 valuator_mask_set(mask, i, dev->last.valuators[i]); 790 } 791 } 792} 793 794/** 795 * Accelerate the data in valuators based on the device's acceleration scheme. 796 * 797 * @param dev The device which's pointer is to be moved. 798 * @param first The first valuator in @valuators 799 * @param num Total number of valuators in @valuators. 800 * @param valuators Valuator data for each axis between @first and 801 * @first+@num. 802 * @param ms Current time. 803 */ 804static void 805accelPointer(DeviceIntPtr dev, int first, int num, int *valuators, CARD32 ms) 806{ 807 if (dev->valuator->accelScheme.AccelSchemeProc) 808 dev->valuator->accelScheme.AccelSchemeProc(dev, first, num, valuators, ms); 809} 810 811/** 812 * If we have HW cursors, this actually moves the visible sprite. If not, we 813 * just do all the screen crossing, etc. 814 * 815 * We scale from device to screen coordinates here, call 816 * miPointerSetPosition() and then scale back into device coordinates (if 817 * needed). miPSP will change x/y if the screen was crossed. 818 * 819 * @param dev The device to be moved. 820 * @param x Pointer to current x-axis value, may be modified. 821 * @param y Pointer to current y-axis value, may be modified. 822 * @param x_frac Fractional part of current x-axis value, may be modified. 823 * @param y_frac Fractional part of current y-axis value, may be modified. 824 * @param scr Screen the device's sprite is currently on. 825 * @param screenx Screen x coordinate the sprite is on after the update. 826 * @param screeny Screen y coordinate the sprite is on after the update. 827 * @param screenx_frac Fractional part of screen x coordinate, as above. 828 * @param screeny_frac Fractional part of screen y coordinate, as above. 829 */ 830static void 831positionSprite(DeviceIntPtr dev, int *x, int *y, float x_frac, float y_frac, 832 ScreenPtr scr, int *screenx, int *screeny, float *screenx_frac, float *screeny_frac) 833{ 834 int old_screenx, old_screeny; 835 836 /* scale x&y to screen */ 837 if (dev->valuator && dev->valuator->numAxes > 0) { 838 *screenx = rescaleValuatorAxis(*x, x_frac, screenx_frac, 839 dev->valuator->axes + 0, NULL, scr->width); 840 } else { 841 *screenx = dev->last.valuators[0]; 842 *screenx_frac = dev->last.remainder[0]; 843 } 844 845 if (dev->valuator && dev->valuator->numAxes > 1) { 846 *screeny = rescaleValuatorAxis(*y, y_frac, screeny_frac, 847 dev->valuator->axes + 1, NULL, scr->height); 848 } else { 849 *screeny = dev->last.valuators[1]; 850 *screeny_frac = dev->last.remainder[1]; 851 } 852 853 /* Hit the left screen edge? */ 854 if (*screenx <= 0 && *screenx_frac < 0.0f) 855 { 856 *screenx_frac = 0.0f; 857 x_frac = 0.0f; 858 } 859 if (*screeny <= 0 && *screeny_frac < 0.0f) 860 { 861 *screeny_frac = 0.0f; 862 y_frac = 0.0f; 863 } 864 865 866 old_screenx = *screenx; 867 old_screeny = *screeny; 868 /* This takes care of crossing screens for us, as well as clipping 869 * to the current screen. */ 870 miPointerSetPosition(dev, screenx, screeny); 871 872 if (dev->u.master) { 873 dev->u.master->last.valuators[0] = *screenx; 874 dev->u.master->last.valuators[1] = *screeny; 875 dev->u.master->last.remainder[0] = *screenx_frac; 876 dev->u.master->last.remainder[1] = *screeny_frac; 877 } 878 879 if (dev->valuator) 880 { 881 /* Crossed screen? Scale back to device coordiantes */ 882 if(*screenx != old_screenx) 883 { 884 scr = miPointerGetScreen(dev); 885 *x = rescaleValuatorAxis(*screenx, *screenx_frac, &x_frac, NULL, 886 dev->valuator->axes + 0, scr->width); 887 } 888 if(*screeny != old_screeny) 889 { 890 scr = miPointerGetScreen(dev); 891 *y = rescaleValuatorAxis(*screeny, *screeny_frac, &y_frac, NULL, 892 dev->valuator->axes + 1, scr->height); 893 } 894 } 895 896 /* dropy x/y (device coordinates) back into valuators for next event */ 897 dev->last.valuators[0] = *x; 898 dev->last.valuators[1] = *y; 899 dev->last.remainder[0] = x_frac; 900 dev->last.remainder[1] = y_frac; 901} 902 903/** 904 * Update the motion history for the device and (if appropriate) for its 905 * master device. 906 * @param dev Slave device to update. 907 * @param mask Bit mask of valid valuators to append to history. 908 * @param num Total number of valuators to append to history. 909 * @param ms Current time 910 */ 911static void 912updateHistory(DeviceIntPtr dev, ValuatorMask *mask, CARD32 ms) 913{ 914 if (!dev->valuator) 915 return; 916 917 updateMotionHistory(dev, ms, mask, dev->last.valuators); 918 if (dev->u.master) 919 { 920 DeviceIntPtr master = GetMaster(dev, MASTER_POINTER); 921 updateMotionHistory(master, ms, mask, dev->last.valuators); 922 } 923} 924 925/** 926 * Convenience wrapper around GetKeyboardValuatorEvents, that takes no 927 * valuators. 928 */ 929int 930GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, int key_code) { 931 ValuatorMask mask; 932 933 valuator_mask_zero(&mask); 934 return GetKeyboardValuatorEvents(events, pDev, type, key_code, &mask); 935} 936 937 938/** 939 * Returns a set of InternalEvents for KeyPress/KeyRelease, optionally 940 * also with valuator events. 941 * 942 * events is not NULL-terminated; the return value is the number of events. 943 * The DDX is responsible for allocating the event structure in the first 944 * place via GetMaximumEventsNum(), and for freeing it. 945 */ 946int 947GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type, 948 int key_code, const ValuatorMask *mask_in) { 949 int num_events = 0; 950 CARD32 ms = 0; 951 DeviceEvent *event; 952 RawDeviceEvent *raw; 953 ValuatorMask mask; 954 955 /* refuse events from disabled devices */ 956 if (!pDev->enabled) 957 return 0; 958 959 if (!events ||!pDev->key || !pDev->focus || !pDev->kbdfeed || 960 (type != KeyPress && type != KeyRelease) || 961 (key_code < 8 || key_code > 255)) 962 return 0; 963 964 num_events = 1; 965 966 events = UpdateFromMaster(events, pDev, DEVCHANGE_KEYBOARD_EVENT, &num_events); 967 968 /* Handle core repeating, via press/release/press/release. */ 969 if (type == KeyPress && key_is_down(pDev, key_code, KEY_POSTED)) { 970 /* If autorepeating is disabled either globally or just for that key, 971 * or we have a modifier, don't generate a repeat event. */ 972 if (!pDev->kbdfeed->ctrl.autoRepeat || 973 !key_autorepeats(pDev, key_code) || 974 pDev->key->xkbInfo->desc->map->modmap[key_code]) 975 return 0; 976 } 977 978 ms = GetTimeInMillis(); 979 980 raw = (RawDeviceEvent*)events->event; 981 events++; 982 num_events++; 983 984 valuator_mask_copy(&mask, mask_in); 985 986 init_raw(pDev, raw, ms, type, key_code); 987 set_raw_valuators(raw, &mask, raw->valuators.data_raw); 988 989 clipValuators(pDev, &mask); 990 991 set_raw_valuators(raw, &mask, raw->valuators.data); 992 993 event = (DeviceEvent*) events->event; 994 init_event(pDev, event, ms); 995 event->detail.key = key_code; 996 997 if (type == KeyPress) { 998 event->type = ET_KeyPress; 999 set_key_down(pDev, key_code, KEY_POSTED); 1000 } 1001 else if (type == KeyRelease) { 1002 event->type = ET_KeyRelease; 1003 set_key_up(pDev, key_code, KEY_POSTED); 1004 } 1005 1006 clipValuators(pDev, &mask); 1007 1008 set_valuators(pDev, event, &mask); 1009 1010 return num_events; 1011} 1012 1013/** 1014 * Initialize an event list and fill with 32 byte sized events. 1015 * This event list is to be passed into GetPointerEvents() and 1016 * GetKeyboardEvents(). 1017 * 1018 * @param num_events Number of elements in list. 1019 */ 1020EventListPtr 1021InitEventList(int num_events) 1022{ 1023 EventListPtr events; 1024 int i; 1025 1026 events = (EventListPtr)calloc(num_events, sizeof(EventList)); 1027 if (!events) 1028 return NULL; 1029 1030 for (i = 0; i < num_events; i++) 1031 { 1032 events[i].evlen = sizeof(InternalEvent); 1033 events[i].event = calloc(1, sizeof(InternalEvent)); 1034 if (!events[i].event) 1035 { 1036 /* rollback */ 1037 while(i--) 1038 free(events[i].event); 1039 free(events); 1040 events = NULL; 1041 break; 1042 } 1043 } 1044 1045 return events; 1046} 1047 1048/** 1049 * Free an event list. 1050 * 1051 * @param list The list to be freed. 1052 * @param num_events Number of elements in list. 1053 */ 1054void 1055FreeEventList(EventListPtr list, int num_events) 1056{ 1057 if (!list) 1058 return; 1059 while(num_events--) 1060 free(list[num_events].event); 1061 free(list); 1062} 1063 1064static void 1065transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask) 1066{ 1067 struct pixman_f_vector p; 1068 1069 /* p' = M * p in homogeneous coordinates */ 1070 p.v[0] = (valuator_mask_isset(mask, 0) ? valuator_mask_get(mask, 0) : 1071 dev->last.valuators[0]); 1072 p.v[1] = (valuator_mask_isset(mask, 1) ? valuator_mask_get(mask, 1) : 1073 dev->last.valuators[1]); 1074 p.v[2] = 1.0; 1075 1076 pixman_f_transform_point(&dev->transform, &p); 1077 1078 if (lround(p.v[0]) != dev->last.valuators[0]) 1079 valuator_mask_set(mask, 0, lround(p.v[0])); 1080 if (lround(p.v[1]) != dev->last.valuators[1]) 1081 valuator_mask_set(mask, 1, lround(p.v[1])); 1082} 1083 1084/** 1085 * Generate a series of InternalEvents (filled into the EventList) 1086 * representing pointer motion, or button presses. 1087 * 1088 * events is not NULL-terminated; the return value is the number of events. 1089 * The DDX is responsible for allocating the event structure in the first 1090 * place via InitEventList() and GetMaximumEventsNum(), and for freeing it. 1091 * 1092 * In the generated events rootX/Y will be in absolute screen coords and 1093 * the valuator information in the absolute or relative device coords. 1094 * 1095 * last.valuators[x] of the device is always in absolute device coords. 1096 * last.valuators[x] of the master device is in absolute screen coords. 1097 * 1098 * master->last.valuators[x] for x > 2 is undefined. 1099 */ 1100int 1101GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons, 1102 int flags, const ValuatorMask *mask_in) { 1103 int num_events = 1; 1104 CARD32 ms; 1105 DeviceEvent *event; 1106 RawDeviceEvent *raw; 1107 int x = 0, y = 0, /* device coords */ 1108 cx, cy; /* only screen coordinates */ 1109 float x_frac = 0.0, y_frac = 0.0, cx_frac, cy_frac; 1110 ScreenPtr scr = miPointerGetScreen(pDev); 1111 ValuatorMask mask; 1112 1113 /* refuse events from disabled devices */ 1114 if (!pDev->enabled) 1115 return 0; 1116 1117 if (!scr) 1118 return 0; 1119 1120 switch (type) 1121 { 1122 case MotionNotify: 1123 if (!mask_in || valuator_mask_num_valuators(mask_in) <= 0) 1124 return 0; 1125 break; 1126 case ButtonPress: 1127 case ButtonRelease: 1128 if (!pDev->button || !buttons) 1129 return 0; 1130 break; 1131 default: 1132 return 0; 1133 } 1134 1135 ms = GetTimeInMillis(); /* before pointer update to help precision */ 1136 1137 events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events); 1138 1139 raw = (RawDeviceEvent*)events->event; 1140 events++; 1141 num_events++; 1142 1143 valuator_mask_copy(&mask, mask_in); 1144 1145 init_raw(pDev, raw, ms, type, buttons); 1146 set_raw_valuators(raw, &mask, raw->valuators.data_raw); 1147 1148 if (flags & POINTER_ABSOLUTE) 1149 { 1150 if (flags & POINTER_SCREEN) /* valuators are in screen coords */ 1151 { 1152 int scaled; 1153 1154 if (valuator_mask_isset(&mask, 0)) 1155 { 1156 scaled = rescaleValuatorAxis(valuator_mask_get(&mask, 0), 1157 0.0, &x_frac, NULL, 1158 pDev->valuator->axes + 0, 1159 scr->width); 1160 valuator_mask_set(&mask, 0, scaled); 1161 } 1162 if (valuator_mask_isset(&mask, 1)) 1163 { 1164 scaled = rescaleValuatorAxis(valuator_mask_get(&mask, 1), 1165 0.0, &y_frac, NULL, 1166 pDev->valuator->axes + 1, 1167 scr->height); 1168 valuator_mask_set(&mask, 1, scaled); 1169 } 1170 } 1171 1172 transformAbsolute(pDev, &mask); 1173 moveAbsolute(pDev, &x, &y, &mask); 1174 } else { 1175 if (flags & POINTER_ACCELERATE) { 1176 /* FIXME: Pointer acceleration only requires X and Y values. This 1177 * should be converted to masked valuators. */ 1178 int vals[2]; 1179 vals[0] = valuator_mask_isset(&mask, 0) ? 1180 valuator_mask_get(&mask, 0) : 0; 1181 vals[1] = valuator_mask_isset(&mask, 1) ? 1182 valuator_mask_get(&mask, 1) : 0; 1183 accelPointer(pDev, 0, 2, vals, ms); 1184 1185 if (valuator_mask_isset(&mask, 0)) 1186 valuator_mask_set(&mask, 0, vals[0]); 1187 if (valuator_mask_isset(&mask, 1)) 1188 valuator_mask_set(&mask, 1, vals[1]); 1189 1190 /* The pointer acceleration code modifies the fractional part 1191 * in-place, so we need to extract this information first */ 1192 x_frac = pDev->last.remainder[0]; 1193 y_frac = pDev->last.remainder[1]; 1194 } 1195 moveRelative(pDev, &x, &y, &mask); 1196 } 1197 1198 set_raw_valuators(raw, &mask, raw->valuators.data); 1199 1200 positionSprite(pDev, &x, &y, x_frac, y_frac, scr, &cx, &cy, &cx_frac, &cy_frac); 1201 updateHistory(pDev, &mask, ms); 1202 1203 /* Update the valuators with the true value sent to the client*/ 1204 if (valuator_mask_isset(&mask, 0)) 1205 valuator_mask_set(&mask, 0, x); 1206 if (valuator_mask_isset(&mask, 1)) 1207 valuator_mask_set(&mask, 1, y); 1208 1209 clipValuators(pDev, &mask); 1210 1211 event = (DeviceEvent*) events->event; 1212 init_event(pDev, event, ms); 1213 1214 if (type == MotionNotify) { 1215 event->type = ET_Motion; 1216 event->detail.button = 0; 1217 } 1218 else { 1219 if (type == ButtonPress) { 1220 event->type = ET_ButtonPress; 1221 set_button_down(pDev, buttons, BUTTON_POSTED); 1222 } 1223 else if (type == ButtonRelease) { 1224 event->type = ET_ButtonRelease; 1225 set_button_up(pDev, buttons, BUTTON_POSTED); 1226 } 1227 event->detail.button = buttons; 1228 } 1229 1230 event->root_x = cx; /* root_x/y always in screen coords */ 1231 event->root_y = cy; 1232 event->root_x_frac = cx_frac; 1233 event->root_y_frac = cy_frac; 1234 1235 set_valuators(pDev, event, &mask); 1236 1237 return num_events; 1238} 1239 1240 1241/** 1242 * Generate ProximityIn/ProximityOut InternalEvents, accompanied by 1243 * valuators. 1244 * 1245 * events is not NULL-terminated; the return value is the number of events. 1246 * The DDX is responsible for allocating the event structure in the first 1247 * place via GetMaximumEventsNum(), and for freeing it. 1248 */ 1249int 1250GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type, const ValuatorMask *mask_in) 1251{ 1252 int num_events = 1, i; 1253 DeviceEvent *event; 1254 ValuatorMask mask; 1255 1256 /* refuse events from disabled devices */ 1257 if (!pDev->enabled) 1258 return 0; 1259 1260 /* Sanity checks. */ 1261 if ((type != ProximityIn && type != ProximityOut) || !mask_in) 1262 return 0; 1263 if (!pDev->valuator) 1264 return 0; 1265 1266 valuator_mask_copy(&mask, mask_in); 1267 1268 /* ignore relative axes for proximity. */ 1269 for (i = 0; i < valuator_mask_size(&mask); i++) 1270 { 1271 if (valuator_mask_isset(&mask, i) && 1272 valuator_get_mode(pDev, i) == Relative) 1273 valuator_mask_unset(&mask, i); 1274 } 1275 1276 /* FIXME: posting proximity events with relative valuators only results 1277 * in an empty event, EventToXI() will fail to convert → no event sent 1278 * to client. */ 1279 1280 events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events); 1281 1282 event = (DeviceEvent *) events->event; 1283 init_event(pDev, event, GetTimeInMillis()); 1284 event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut; 1285 1286 clipValuators(pDev, &mask); 1287 1288 set_valuators(pDev, event, &mask); 1289 1290 return num_events; 1291} 1292 1293/** 1294 * Synthesize a single motion event for the core pointer. 1295 * 1296 * Used in cursor functions, e.g. when cursor confinement changes, and we need 1297 * to shift the pointer to get it inside the new bounds. 1298 */ 1299void 1300PostSyntheticMotion(DeviceIntPtr pDev, 1301 int x, 1302 int y, 1303 int screen, 1304 unsigned long time) 1305{ 1306 DeviceEvent ev; 1307 1308#ifdef PANORAMIX 1309 /* Translate back to the sprite screen since processInputProc 1310 will translate from sprite screen to screen 0 upon reentry 1311 to the DIX layer. */ 1312 if (!noPanoramiXExtension) { 1313 x += screenInfo.screens[0]->x - screenInfo.screens[screen]->x; 1314 y += screenInfo.screens[0]->y - screenInfo.screens[screen]->y; 1315 } 1316#endif 1317 1318 memset(&ev, 0, sizeof(DeviceEvent)); 1319 init_event(pDev, &ev, time); 1320 ev.root_x = x; 1321 ev.root_y = y; 1322 ev.type = ET_Motion; 1323 ev.time = time; 1324 1325 /* FIXME: MD/SD considerations? */ 1326 (*pDev->public.processInputProc)((InternalEvent*)&ev, pDev); 1327} 1328