getevents.c revision 05b261ec
1/* 2 * Copyright © 2006 Nokia Corporation 3 * Copyright © 2006-2007 Daniel Stone 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 * 24 * Author: Daniel Stone <daniel@fooishbar.org> 25 */ 26 27#ifdef HAVE_DIX_CONFIG_H 28#include <dix-config.h> 29#endif 30 31#include <X11/X.h> 32#include <X11/keysym.h> 33#define NEED_EVENTS 34#define NEED_REPLIES 35#include <X11/Xproto.h> 36 37#include "misc.h" 38#include "resource.h" 39#include "inputstr.h" 40#include "scrnintstr.h" 41#include "cursorstr.h" 42#include "dixstruct.h" 43#include "globals.h" 44#include "dixevents.h" 45#include "mipointer.h" 46 47#ifdef XKB 48#include <X11/extensions/XKBproto.h> 49#include <xkbsrv.h> 50extern Bool XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies); 51#endif 52 53#ifdef PANORAMIX 54#include "panoramiX.h" 55#include "panoramiXsrv.h" 56#endif 57 58#include <X11/extensions/XI.h> 59#include <X11/extensions/XIproto.h> 60#include "exglobals.h" 61#include "exevents.h" 62#include "exglobals.h" 63#include "extnsionst.h" 64 65 66/* Maximum number of valuators, divided by six, rounded up, to get number 67 * of events. */ 68#define MAX_VALUATOR_EVENTS 6 69 70/* Number of motion history events to store. */ 71#define MOTION_HISTORY_SIZE 256 72 73 74/** 75 * Pick some arbitrary size for Xi motion history. 76 */ 77_X_EXPORT int 78GetMotionHistorySize(void) 79{ 80 return MOTION_HISTORY_SIZE; 81} 82 83static void 84set_key_down(DeviceIntPtr pDev, int key_code) 85{ 86 pDev->key->postdown[key_code >> 3] |= (1 << (key_code & 7)); 87} 88 89static void 90set_key_up(DeviceIntPtr pDev, int key_code) 91{ 92 pDev->key->postdown[key_code >> 3] &= ~(1 << (key_code & 7)); 93} 94 95static Bool 96key_is_down(DeviceIntPtr pDev, int key_code) 97{ 98 return !!(pDev->key->postdown[key_code >> 3] & (1 << (key_code & 7))); 99} 100 101static Bool 102key_autorepeats(DeviceIntPtr pDev, int key_code) 103{ 104 return !!(pDev->kbdfeed->ctrl.autoRepeats[key_code >> 3] & 105 (1 << (key_code & 7))); 106} 107 108/** 109 * Allocate the motion history buffer. 110 */ 111_X_EXPORT void 112AllocateMotionHistory(DeviceIntPtr pDev) 113{ 114 if (pDev->valuator->motion) 115 xfree(pDev->valuator->motion); 116 117 if (pDev->valuator->numMotionEvents < 1) 118 return; 119 120 pDev->valuator->motion = xalloc(((sizeof(INT32) * pDev->valuator->numAxes) + 121 sizeof(Time)) * 122 pDev->valuator->numMotionEvents); 123 pDev->valuator->first_motion = 0; 124 pDev->valuator->last_motion = 0; 125} 126 127 128/** 129 * Dump the motion history between start and stop into the supplied buffer. 130 * Only records the event for a given screen in theory, but in practice, we 131 * sort of ignore this. 132 */ 133_X_EXPORT int 134GetMotionHistory(DeviceIntPtr pDev, xTimecoord *buff, unsigned long start, 135 unsigned long stop, ScreenPtr pScreen) 136{ 137 char *ibuff = NULL, *obuff = (char *) buff; 138 int i = 0, ret = 0; 139 Time current; 140 /* The size of a single motion event. */ 141 int size = (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time); 142 143 if (!pDev->valuator || !pDev->valuator->numMotionEvents) 144 return 0; 145 146 for (i = pDev->valuator->first_motion; 147 i != pDev->valuator->last_motion; 148 i = (i + 1) % pDev->valuator->numMotionEvents) { 149 /* We index the input buffer by which element we're accessing, which 150 * is not monotonic, and the output buffer by how many events we've 151 * written so far. */ 152 ibuff = (char *) pDev->valuator->motion + (i * size); 153 memcpy(¤t, ibuff, sizeof(Time)); 154 155 if (current > stop) { 156 return ret; 157 } 158 else if (current >= start) { 159 memcpy(obuff, ibuff, size); 160 obuff += size; 161 ret++; 162 } 163 } 164 165 return ret; 166} 167 168 169/** 170 * Update the motion history for a specific device, with the list of 171 * valuators. 172 */ 173static void 174updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, int first_valuator, 175 int num_valuators, int *valuators) 176{ 177 char *buff = (char *) pDev->valuator->motion; 178 179 if (!pDev->valuator->numMotionEvents) 180 return; 181 182 buff += ((sizeof(INT32) * pDev->valuator->numAxes) + sizeof(CARD32)) * 183 pDev->valuator->last_motion; 184 memcpy(buff, &ms, sizeof(Time)); 185 186 buff += sizeof(Time); 187 bzero(buff, sizeof(INT32) * pDev->valuator->numAxes); 188 189 buff += sizeof(INT32) * first_valuator; 190 memcpy(buff, valuators, sizeof(INT32) * num_valuators); 191 192 pDev->valuator->last_motion = (pDev->valuator->last_motion + 1) % 193 pDev->valuator->numMotionEvents; 194 195 /* If we're wrapping around, just keep the circular buffer going. */ 196 if (pDev->valuator->first_motion == pDev->valuator->last_motion) 197 pDev->valuator->first_motion = (pDev->valuator->first_motion + 1) % 198 pDev->valuator->numMotionEvents; 199 200 return; 201} 202 203 204/** 205 * Returns the maximum number of events GetKeyboardEvents, 206 * GetKeyboardValuatorEvents, and GetPointerEvents will ever return. 207 * 208 * Should be used in DIX as: 209 * xEvent *events = xcalloc(sizeof(xEvent), GetMaximumEventsNum()); 210 */ 211_X_EXPORT int 212GetMaximumEventsNum(void) { 213 /* Two base events -- core and device, plus valuator events. Multiply 214 * by two if we're doing key repeats. */ 215 int ret = 2 + MAX_VALUATOR_EVENTS; 216 217#ifdef XKB 218 if (noXkbExtension) 219#endif 220 ret *= 2; 221 222 return ret; 223} 224 225 226/* Originally a part of xf86PostMotionEvent; modifies valuators 227 * in-place. */ 228static void 229acceleratePointer(DeviceIntPtr pDev, int first_valuator, int num_valuators, 230 int *valuators) 231{ 232 float mult = 0.0; 233 int dx = 0, dy = 0; 234 int *px = NULL, *py = NULL; 235 236 if (!num_valuators || !valuators) 237 return; 238 239 if (first_valuator == 0) { 240 dx = valuators[0]; 241 px = &valuators[0]; 242 } 243 if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) { 244 dy = valuators[1 - first_valuator]; 245 py = &valuators[1 - first_valuator]; 246 } 247 248 if (!dx && !dy) 249 return; 250 251 if (pDev->ptrfeed && pDev->ptrfeed->ctrl.num) { 252 /* modeled from xf86Events.c */ 253 if (pDev->ptrfeed->ctrl.threshold) { 254 if ((abs(dx) + abs(dy)) >= pDev->ptrfeed->ctrl.threshold) { 255 pDev->valuator->dxremaind = ((float)dx * 256 (float)(pDev->ptrfeed->ctrl.num)) / 257 (float)(pDev->ptrfeed->ctrl.den) + 258 pDev->valuator->dxremaind; 259 if (px) { 260 *px = (int)pDev->valuator->dxremaind; 261 pDev->valuator->dxremaind = pDev->valuator->dxremaind - 262 (float)(*px); 263 } 264 265 pDev->valuator->dyremaind = ((float)dy * 266 (float)(pDev->ptrfeed->ctrl.num)) / 267 (float)(pDev->ptrfeed->ctrl.den) + 268 pDev->valuator->dyremaind; 269 if (py) { 270 *py = (int)pDev->valuator->dyremaind; 271 pDev->valuator->dyremaind = pDev->valuator->dyremaind - 272 (float)(*py); 273 } 274 } 275 } 276 else { 277 mult = pow((float)dx * (float)dx + (float)dy * (float)dy, 278 ((float)(pDev->ptrfeed->ctrl.num) / 279 (float)(pDev->ptrfeed->ctrl.den) - 1.0) / 280 2.0) / 2.0; 281 if (dx) { 282 pDev->valuator->dxremaind = mult * (float)dx + 283 pDev->valuator->dxremaind; 284 *px = (int)pDev->valuator->dxremaind; 285 pDev->valuator->dxremaind = pDev->valuator->dxremaind - 286 (float)(*px); 287 } 288 if (dy) { 289 pDev->valuator->dyremaind = mult * (float)dy + 290 pDev->valuator->dyremaind; 291 *py = (int)pDev->valuator->dyremaind; 292 pDev->valuator->dyremaind = pDev->valuator->dyremaind - 293 (float)(*py); 294 } 295 } 296 } 297} 298 299 300/** 301 * Clip an axis to its bounds, which are declared in the call to 302 * InitValuatorAxisClassStruct. 303 */ 304static void 305clipAxis(DeviceIntPtr pDev, int axisNum, int *val) 306{ 307 AxisInfoPtr axes = pDev->valuator->axes + axisNum; 308 309 /* No clipping if the value-range <= 0 */ 310 if(axes->min_value < axes->min_value) { 311 if (*val < axes->min_value) 312 *val = axes->min_value; 313 if (*val > axes->max_value) 314 *val = axes->max_value; 315 } 316} 317 318/** 319 * Clip every axis in the list of valuators to its bounds. 320 */ 321static void 322clipValuators(DeviceIntPtr pDev, int first_valuator, int num_valuators, 323 int *valuators) 324{ 325 AxisInfoPtr axes = pDev->valuator->axes + first_valuator; 326 int i; 327 328 for (i = 0; i < num_valuators; i++, axes++) 329 clipAxis(pDev, i + first_valuator, &(valuators[i])); 330} 331 332 333/** 334 * Fills events with valuator events for pDev, as given by the other 335 * parameters. 336 * 337 * FIXME: Need to fix ValuatorClassRec to store all the valuators as 338 * last posted, not just x and y; otherwise relative non-x/y 339 * valuators, though a very narrow use case, will be broken. 340 */ 341static xEvent * 342getValuatorEvents(xEvent *events, DeviceIntPtr pDev, int first_valuator, 343 int num_valuators, int *valuators) { 344 deviceValuator *xv = (deviceValuator *) events; 345 int i = 0, final_valuator = first_valuator + num_valuators; 346 347 for (i = first_valuator; i < final_valuator; i += 6, xv++, events++) { 348 xv->type = DeviceValuator; 349 xv->first_valuator = i; 350 xv->num_valuators = ((final_valuator - i) > 6) ? 6 : (final_valuator - i); 351 xv->deviceid = pDev->id; 352 switch (final_valuator - i) { 353 case 6: 354 xv->valuator5 = valuators[i + 5]; 355 case 5: 356 xv->valuator4 = valuators[i + 4]; 357 case 4: 358 xv->valuator3 = valuators[i + 3]; 359 case 3: 360 xv->valuator2 = valuators[i + 2]; 361 case 2: 362 xv->valuator1 = valuators[i + 1]; 363 case 1: 364 xv->valuator0 = valuators[i]; 365 } 366 367 if (i + 6 < final_valuator) 368 xv->deviceid |= MORE_EVENTS; 369 } 370 371 return events; 372} 373 374 375/** 376 * Convenience wrapper around GetKeyboardValuatorEvents, that takes no 377 * valuators. 378 */ 379_X_EXPORT int 380GetKeyboardEvents(xEvent *events, DeviceIntPtr pDev, int type, int key_code) { 381 return GetKeyboardValuatorEvents(events, pDev, type, key_code, 0, 0, NULL); 382} 383 384 385/** 386 * Returns a set of keyboard events for KeyPress/KeyRelease, optionally 387 * also with valuator events. Handles Xi and XKB. 388 * 389 * events is not NULL-terminated; the return value is the number of events. 390 * The DDX is responsible for allocating the event structure in the first 391 * place via GetMaximumEventsNum(), and for freeing it. 392 * 393 * This function does not change the core keymap to that of the device; 394 * that is done by SwitchCoreKeyboard, which is called from 395 * mieqProcessInputEvents. If replacing that function, take care to call 396 * SetCoreKeyboard before processInputProc, so keymaps are altered to suit. 397 * 398 * Note that this function recurses! If called for non-XKB, a repeating 399 * key press will trigger a matching KeyRelease, as well as the 400 * KeyPresses. 401 */ 402_X_EXPORT int 403GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type, 404 int key_code, int first_valuator, 405 int num_valuators, int *valuators) { 406 int numEvents = 0; 407 CARD32 ms = 0; 408 KeySym *map = pDev->key->curKeySyms.map; 409 KeySym sym = map[key_code * pDev->key->curKeySyms.mapWidth]; 410 deviceKeyButtonPointer *kbp = NULL; 411 412 if (!events) 413 return 0; 414 415 /* DO NOT WANT */ 416 if (type != KeyPress && type != KeyRelease) 417 return 0; 418 419 if (!pDev->key || !pDev->focus || !pDev->kbdfeed || 420 (pDev->coreEvents && !inputInfo.keyboard->key)) 421 return 0; 422 423 if (key_code < 8 || key_code > 255) 424 return 0; 425 426 if (pDev->coreEvents) 427 numEvents = 2; 428 else 429 numEvents = 1; 430 431 if (num_valuators) { 432 if ((num_valuators / 6) + 1 > MAX_VALUATOR_EVENTS) 433 num_valuators = MAX_VALUATOR_EVENTS; 434 numEvents += (num_valuators / 6) + 1; 435 } 436 437#ifdef XKB 438 if (noXkbExtension) 439#endif 440 { 441 switch (sym) { 442 case XK_Num_Lock: 443 case XK_Caps_Lock: 444 case XK_Scroll_Lock: 445 case XK_Shift_Lock: 446 if (type == KeyRelease) 447 return 0; 448 else if (type == KeyPress && key_is_down(pDev, key_code)) 449 type = KeyRelease; 450 } 451 } 452 453 /* Handle core repeating, via press/release/press/release. 454 * FIXME: In theory, if you're repeating with two keyboards in non-XKB, 455 * you could get unbalanced events here. */ 456 if (type == KeyPress && key_is_down(pDev, key_code)) { 457 /* If autorepeating is disabled either globally or just for that key, 458 * or we have a modifier, don't generate a repeat event. */ 459 if (!pDev->kbdfeed->ctrl.autoRepeat || 460 !key_autorepeats(pDev, key_code) || 461 pDev->key->modifierMap[key_code]) 462 return 0; 463 464#ifdef XKB 465 if (noXkbExtension) 466#endif 467 { 468 numEvents += GetKeyboardValuatorEvents(events, pDev, 469 KeyRelease, key_code, 470 first_valuator, num_valuators, 471 valuators); 472 events += numEvents; 473 } 474 } 475 476 ms = GetTimeInMillis(); 477 478 if (pDev->coreEvents) { 479 events->u.keyButtonPointer.time = ms; 480 events->u.u.type = type; 481 events->u.u.detail = key_code; 482 if (type == KeyPress) 483 set_key_down(inputInfo.keyboard, key_code); 484 else if (type == KeyRelease) 485 set_key_up(inputInfo.keyboard, key_code); 486 events++; 487 } 488 489 kbp = (deviceKeyButtonPointer *) events; 490 kbp->time = ms; 491 kbp->deviceid = pDev->id; 492 kbp->detail = key_code; 493 if (type == KeyPress) { 494 kbp->type = DeviceKeyPress; 495 set_key_down(pDev, key_code); 496 } 497 else if (type == KeyRelease) { 498 kbp->type = DeviceKeyRelease; 499 set_key_up(pDev, key_code); 500 } 501 502 events++; 503 if (num_valuators) { 504 kbp->deviceid |= MORE_EVENTS; 505 clipValuators(pDev, first_valuator, num_valuators, valuators); 506 events = getValuatorEvents(events, pDev, first_valuator, 507 num_valuators, valuators); 508 } 509 510 return numEvents; 511} 512 513 514/** 515 * Generate a series of xEvents (returned in xE) representing pointer 516 * motion, or button presses. Xi and XKB-aware. 517 * 518 * events is not NULL-terminated; the return value is the number of events. 519 * The DDX is responsible for allocating the event structure in the first 520 * place via GetMaximumEventsNum(), and for freeing it. 521 */ 522_X_EXPORT int 523GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, 524 int flags, int first_valuator, int num_valuators, 525 int *valuators) { 526 int num_events = 0, final_valuator = 0; 527 CARD32 ms = 0; 528 deviceKeyButtonPointer *kbp = NULL; 529 DeviceIntPtr cp = inputInfo.pointer; 530 int x = 0, y = 0; 531 Bool coreOnly = (pDev == inputInfo.pointer); 532 ScreenPtr scr = miPointerGetScreen(pDev); 533 534 /* Sanity checks. */ 535 if (type != MotionNotify && type != ButtonPress && type != ButtonRelease) 536 return 0; 537 538 if ((type == ButtonPress || type == ButtonRelease) && !pDev->button) 539 return 0; 540 541 /* FIXME: I guess it should, in theory, be possible to post button events 542 * from devices without valuators. */ 543 if (!pDev->valuator) 544 return 0; 545 546 if (!coreOnly && pDev->coreEvents) 547 num_events = 2; 548 else 549 num_events = 1; 550 551 if (type == MotionNotify && num_valuators <= 0) 552 return 0; 553 554 /* Do we need to send a DeviceValuator event? */ 555 if (!coreOnly && num_valuators) { 556 if ((((num_valuators - 1) / 6) + 1) > MAX_VALUATOR_EVENTS) 557 num_valuators = MAX_VALUATOR_EVENTS * 6; 558 num_events += ((num_valuators - 1) / 6) + 1; 559 } 560 561 final_valuator = num_valuators + first_valuator; 562 563 /* You fail. */ 564 if (first_valuator < 0 || final_valuator > pDev->valuator->numAxes) 565 return 0; 566 567 ms = GetTimeInMillis(); 568 569 /* Set x and y based on whether this is absolute or relative, and 570 * accelerate if we need to. */ 571 if (flags & POINTER_ABSOLUTE) { 572 if (num_valuators >= 1 && first_valuator == 0) { 573 x = valuators[0]; 574 } 575 else { 576 /* If we're sending core events but didn't provide a value, 577 * translate the core value (but use the device coord if 578 * it translates to the same coord to preserve sub-pixel 579 * coord information). If we're not sending core events use 580 * whatever value we have */ 581 x = pDev->valuator->lastx; 582 if(pDev->coreEvents) { 583 int min = pDev->valuator->axes[0].min_value; 584 int max = pDev->valuator->axes[0].max_value; 585 if(min < max) { 586 if((int)((float)(x-min)*scr->width/(max-min+1)) != cp->valuator->lastx) 587 x = (int)((float)(cp->valuator->lastx)*(max-min+1)/scr->width)+min; 588 } 589 else 590 x = cp->valuator->lastx; 591 } 592 } 593 594 if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) { 595 y = valuators[1 - first_valuator]; 596 } 597 else { 598 y = pDev->valuator->lasty; 599 if(pDev->coreEvents) { 600 int min = pDev->valuator->axes[1].min_value; 601 int max = pDev->valuator->axes[1].max_value; 602 if(min < max) { 603 if((int)((float)(y-min)*scr->height/(max-min+1)) != cp->valuator->lasty) 604 y = (int)((float)(cp->valuator->lasty)*(max-min+1)/scr->height)+min; 605 } 606 else 607 y = cp->valuator->lasty; 608 } 609 } 610 611 /* Clip both x and y to the defined limits (usually co-ord space limit). */ 612 clipAxis(pDev, 0, &x); 613 clipAxis(pDev, 1, &y); 614 } 615 else { 616 if (flags & POINTER_ACCELERATE) 617 acceleratePointer(pDev, first_valuator, num_valuators, 618 valuators); 619 620 if (pDev->coreEvents) { 621 /* Get and convert the core pointer coordinate space into 622 * device coordinates. Use the device coords if it translates 623 * into the same position as the core to preserve relative sub- 624 * pixel movements from the device. */ 625 int min = pDev->valuator->axes[0].min_value; 626 int max = pDev->valuator->axes[0].max_value; 627 if(min < max) { 628 x = pDev->valuator->lastx; 629 if((int)((float)(x-min)*scr->width/(max-min+1)) != cp->valuator->lastx) 630 x = (int)((float)(cp->valuator->lastx)*(max-min+1)/scr->width)+min; 631 } 632 else 633 x = cp->valuator->lastx; 634 635 min = pDev->valuator->axes[1].min_value; 636 max = pDev->valuator->axes[1].max_value; 637 if(min < max) { 638 y = pDev->valuator->lasty; 639 if((int)((float)(y-min)*scr->height/(max-min+1)) != cp->valuator->lasty) 640 y = (int)((float)(cp->valuator->lasty)*(max-min+1)/scr->height)+min; 641 } 642 else 643 y = cp->valuator->lasty; 644 645 /* Add relative movement */ 646 if (first_valuator == 0 && num_valuators >= 1) 647 x += valuators[0]; 648 if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) 649 y += valuators[1 - first_valuator]; 650 } 651 else { 652 x = pDev->valuator->lastx; 653 y = pDev->valuator->lasty; 654 if (first_valuator == 0 && num_valuators >= 1) 655 x += valuators[0]; 656 if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) 657 y += valuators[1 - first_valuator]; 658 659 if(!coreOnly) { 660 /* Since we're not sending core-events we must clip both x and y 661 * to the defined limits so we don't run outside the box. */ 662 clipAxis(pDev, 0, &x); 663 clipAxis(pDev, 1, &y); 664 } 665 } 666 } 667 668 pDev->valuator->lastx = x; 669 pDev->valuator->lasty = y; 670 /* Convert the dev coord back to screen coord if we're 671 * sending core events */ 672 if (pDev->coreEvents) { 673 int min = pDev->valuator->axes[0].min_value; 674 int max = pDev->valuator->axes[0].max_value; 675 if(min < max) 676 x = (int)((float)(x-min)*scr->width/(max-min+1)); 677 cp->valuator->lastx = x; 678 min = pDev->valuator->axes[1].min_value; 679 max = pDev->valuator->axes[1].max_value; 680 if(min < max) 681 y = (int)((float)(y-min)*scr->height/(max-min+1)); 682 cp->valuator->lasty = y; 683 } 684 685 /* This takes care of crossing screens for us, as well as clipping 686 * to the current screen. Right now, we only have one history buffer, 687 * so we don't set this for both the device and core.*/ 688 miPointerSetPosition(pDev, &x, &y, ms); 689 690 if (pDev->coreEvents) { 691 /* miPointerSetPosition may have changed screen */ 692 scr = miPointerGetScreen(pDev); 693 if(x != cp->valuator->lastx) { 694 int min = pDev->valuator->axes[0].min_value; 695 int max = pDev->valuator->axes[0].max_value; 696 cp->valuator->lastx = pDev->valuator->lastx = x; 697 if(min < max) 698 pDev->valuator->lastx = (int)((float)(x)*(max-min+1)/scr->width)+min; 699 } 700 if(y != cp->valuator->lasty) { 701 int min = pDev->valuator->axes[1].min_value; 702 int max = pDev->valuator->axes[1].max_value; 703 cp->valuator->lasty = pDev->valuator->lasty = y; 704 if(min < max) 705 pDev->valuator->lasty = (int)((float)(y)*(max-min+1)/scr->height)+min; 706 } 707 } 708 else if (coreOnly) { 709 cp->valuator->lastx = x; 710 cp->valuator->lasty = y; 711 } 712 713 /* Drop x and y back into the valuators list, if they were originally 714 * present. */ 715 if (first_valuator == 0 && num_valuators >= 1) 716 valuators[0] = pDev->valuator->lastx; 717 if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) 718 valuators[1 - first_valuator] = pDev->valuator->lasty; 719 720 updateMotionHistory(pDev, ms, first_valuator, num_valuators, valuators); 721 722 /* for some reason inputInfo.pointer does not have coreEvents set */ 723 if (coreOnly || pDev->coreEvents) { 724 events->u.u.type = type; 725 events->u.keyButtonPointer.time = ms; 726 events->u.keyButtonPointer.rootX = x; 727 events->u.keyButtonPointer.rootY = y; 728 729 if (type == ButtonPress || type == ButtonRelease) { 730 /* We hijack SetPointerMapping to work on all core-sending 731 * devices, so we use the device-specific map here instead of 732 * the core one. */ 733 events->u.u.detail = pDev->button->map[buttons]; 734 } 735 else { 736 events->u.u.detail = 0; 737 } 738 739 events++; 740 } 741 742 if (!coreOnly) { 743 kbp = (deviceKeyButtonPointer *) events; 744 kbp->time = ms; 745 kbp->deviceid = pDev->id; 746 747 if (type == MotionNotify) { 748 kbp->type = DeviceMotionNotify; 749 } 750 else { 751 if (type == ButtonPress) 752 kbp->type = DeviceButtonPress; 753 else if (type == ButtonRelease) 754 kbp->type = DeviceButtonRelease; 755 kbp->detail = pDev->button->map[buttons]; 756 } 757 758 kbp->root_x = pDev->valuator->lastx; 759 kbp->root_y = pDev->valuator->lasty; 760 761 events++; 762 if (num_valuators) { 763 kbp->deviceid |= MORE_EVENTS; 764 clipValuators(pDev, first_valuator, num_valuators, valuators); 765 events = getValuatorEvents(events, pDev, first_valuator, 766 num_valuators, valuators); 767 } 768 } 769 770 return num_events; 771} 772 773 774/** 775 * Post ProximityIn/ProximityOut events, accompanied by valuators. 776 * 777 * events is not NULL-terminated; the return value is the number of events. 778 * The DDX is responsible for allocating the event structure in the first 779 * place via GetMaximumEventsNum(), and for freeing it. 780 */ 781_X_EXPORT int 782GetProximityEvents(xEvent *events, DeviceIntPtr pDev, int type, 783 int first_valuator, int num_valuators, int *valuators) 784{ 785 int num_events = 1; 786 deviceKeyButtonPointer *kbp = (deviceKeyButtonPointer *) events; 787 788 /* Sanity checks. */ 789 if (type != ProximityIn && type != ProximityOut) 790 return 0; 791 792 if (!pDev->valuator) 793 return 0; 794 795 /* Do we need to send a DeviceValuator event? */ 796 if ((pDev->valuator->mode & 1) == Relative) 797 num_valuators = 0; 798 799 if (num_valuators) { 800 if ((((num_valuators - 1) / 6) + 1) > MAX_VALUATOR_EVENTS) 801 num_valuators = MAX_VALUATOR_EVENTS * 6; 802 num_events += ((num_valuators - 1) / 6) + 1; 803 } 804 805 /* You fail. */ 806 if (first_valuator < 0 || 807 (num_valuators + first_valuator) > pDev->valuator->numAxes) 808 return 0; 809 810 kbp->type = type; 811 kbp->deviceid = pDev->id; 812 kbp->detail = 0; 813 kbp->time = GetTimeInMillis(); 814 815 if (num_valuators) { 816 kbp->deviceid |= MORE_EVENTS; 817 events++; 818 clipValuators(pDev, first_valuator, num_valuators, valuators); 819 events = getValuatorEvents(events, pDev, first_valuator, 820 num_valuators, valuators); 821 } 822 823 return num_events; 824} 825 826 827/** 828 * Note that pDev was the last device to send a core event. This function 829 * copies the complete keymap from the originating device to the core 830 * device, and makes sure the appropriate notifications are generated. 831 * 832 * Call this just before processInputProc. 833 */ 834_X_EXPORT void 835SwitchCoreKeyboard(DeviceIntPtr pDev) 836{ 837 KeyClassPtr ckeyc = inputInfo.keyboard->key; 838 int i = 0; 839 840 if (inputInfo.keyboard->devPrivates[CoreDevicePrivatesIndex].ptr != pDev) { 841 memcpy(ckeyc->modifierMap, pDev->key->modifierMap, MAP_LENGTH); 842 if (ckeyc->modifierKeyMap) 843 xfree(ckeyc->modifierKeyMap); 844 ckeyc->modifierKeyMap = xalloc(8 * pDev->key->maxKeysPerModifier); 845 memcpy(ckeyc->modifierKeyMap, pDev->key->modifierKeyMap, 846 (8 * pDev->key->maxKeysPerModifier)); 847 848 ckeyc->maxKeysPerModifier = pDev->key->maxKeysPerModifier; 849 ckeyc->curKeySyms.minKeyCode = pDev->key->curKeySyms.minKeyCode; 850 ckeyc->curKeySyms.maxKeyCode = pDev->key->curKeySyms.maxKeyCode; 851 SetKeySymsMap(&ckeyc->curKeySyms, &pDev->key->curKeySyms); 852 853 /* 854 * Copy state from the extended keyboard to core. If you omit this, 855 * holding Ctrl on keyboard one, and pressing Q on keyboard two, will 856 * cause your app to quit. This feels wrong to me, hence the below 857 * code. 858 * 859 * XXX: If you synthesise core modifier events, the state will get 860 * clobbered here. You'll have to work out something sensible 861 * to fix that. Good luck. 862 */ 863 864#define KEYBOARD_MASK (ShiftMask | LockMask | ControlMask | Mod1Mask | \ 865 Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask) 866 ckeyc->state &= ~(KEYBOARD_MASK); 867 ckeyc->state |= (pDev->key->state & KEYBOARD_MASK); 868#undef KEYBOARD_MASK 869 for (i = 0; i < 8; i++) 870 ckeyc->modifierKeyCount[i] = pDev->key->modifierKeyCount[i]; 871 872#ifdef XKB 873 if (!noXkbExtension && pDev->key->xkbInfo && pDev->key->xkbInfo->desc) { 874 if (!XkbCopyKeymap(pDev->key->xkbInfo->desc, ckeyc->xkbInfo->desc, 875 True)) 876 FatalError("Couldn't pivot keymap from device to core!\n"); 877 } 878#endif 879 880 SendMappingNotify(MappingKeyboard, ckeyc->curKeySyms.minKeyCode, 881 (ckeyc->curKeySyms.maxKeyCode - 882 ckeyc->curKeySyms.minKeyCode), 883 serverClient); 884 inputInfo.keyboard->devPrivates[CoreDevicePrivatesIndex].ptr = pDev; 885 } 886} 887 888 889/** 890 * Note that pDev was the last function to send a core pointer event. 891 * Currently a no-op. 892 * 893 * Call this just before processInputProc. 894 */ 895_X_EXPORT void 896SwitchCorePointer(DeviceIntPtr pDev) 897{ 898 if (inputInfo.pointer->devPrivates[CoreDevicePrivatesIndex].ptr != pDev) 899 inputInfo.pointer->devPrivates[CoreDevicePrivatesIndex].ptr = pDev; 900} 901 902 903/** 904 * Synthesize a single motion event for the core pointer. 905 * 906 * Used in cursor functions, e.g. when cursor confinement changes, and we need 907 * to shift the pointer to get it inside the new bounds. 908 */ 909void 910PostSyntheticMotion(int x, int y, int screen, unsigned long time) 911{ 912 xEvent xE; 913 914#ifdef PANORAMIX 915 /* Translate back to the sprite screen since processInputProc 916 will translate from sprite screen to screen 0 upon reentry 917 to the DIX layer. */ 918 if (!noPanoramiXExtension) { 919 x += panoramiXdataPtr[0].x - panoramiXdataPtr[screen].x; 920 y += panoramiXdataPtr[0].y - panoramiXdataPtr[screen].y; 921 } 922#endif 923 924 memset(&xE, 0, sizeof(xEvent)); 925 xE.u.u.type = MotionNotify; 926 xE.u.keyButtonPointer.rootX = x; 927 xE.u.keyButtonPointer.rootY = y; 928 xE.u.keyButtonPointer.time = time; 929 930 (*inputInfo.pointer->public.processInputProc)(&xE, inputInfo.pointer, 1); 931} 932