eventconvert.c revision 1b5d61b8
1/* 2 * Copyright © 2009 Red Hat, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 * 23 */ 24 25/** 26 * @file eventconvert.c 27 * This file contains event conversion routines from InternalEvent to the 28 * matching protocol events. 29 */ 30 31#ifdef HAVE_DIX_CONFIG_H 32#include <dix-config.h> 33#endif 34 35#include <stdint.h> 36#include <X11/X.h> 37#include <X11/extensions/XIproto.h> 38#include <X11/extensions/XI2proto.h> 39#include <X11/extensions/XI.h> 40#include <X11/extensions/XI2.h> 41 42#include "dix.h" 43#include "inputstr.h" 44#include "misc.h" 45#include "eventstr.h" 46#include "exevents.h" 47#include "exglobals.h" 48#include "eventconvert.h" 49#include "inpututils.h" 50#include "xiquerydevice.h" 51#include "xkbsrv.h" 52#include "inpututils.h" 53 54static int countValuators(DeviceEvent *ev, int *first); 55static int getValuatorEvents(DeviceEvent *ev, deviceValuator * xv); 56static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count); 57static int eventToDeviceChanged(DeviceChangedEvent *ev, xEvent **dcce); 58static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi); 59static int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi); 60static int eventToBarrierEvent(BarrierEvent *ev, xEvent **xi); 61static int eventToTouchOwnershipEvent(TouchOwnershipEvent *ev, xEvent **xi); 62 63/* Do not use, read comments below */ 64BOOL EventIsKeyRepeat(xEvent *event); 65 66/** 67 * Hack to allow detectable autorepeat for core and XI1 events. 68 * The sequence number is unused until we send to the client and can be 69 * misused to store data. More or less, anyway. 70 * 71 * Do not use this. It may change any time without warning, eat your babies 72 * and piss on your cat. 73 */ 74static void 75EventSetKeyRepeatFlag(xEvent *event, BOOL on) 76{ 77 event->u.u.sequenceNumber = on; 78} 79 80/** 81 * Check if the event was marked as a repeat event before. 82 * NOTE: This is a nasty hack and should NOT be used by anyone else but 83 * TryClientEvents. 84 */ 85BOOL 86EventIsKeyRepeat(xEvent *event) 87{ 88 return ! !event->u.u.sequenceNumber; 89} 90 91/** 92 * Convert the given event to the respective core event. 93 * 94 * Return values: 95 * Success ... core contains the matching core event. 96 * BadValue .. One or more values in the internal event are invalid. 97 * BadMatch .. The event has no core equivalent. 98 * 99 * @param[in] event The event to convert into a core event. 100 * @param[in] core The memory location to store the core event at. 101 * @return Success or the matching error code. 102 */ 103int 104EventToCore(InternalEvent *event, xEvent **core_out, int *count_out) 105{ 106 xEvent *core = NULL; 107 int count = 0; 108 int ret = BadImplementation; 109 110 switch (event->any.type) { 111 case ET_Motion: 112 { 113 DeviceEvent *e = &event->device_event; 114 115 /* Don't create core motion event if neither x nor y are 116 * present */ 117 if (!BitIsOn(e->valuators.mask, 0) && !BitIsOn(e->valuators.mask, 1)) { 118 ret = BadMatch; 119 goto out; 120 } 121 } 122 /* fallthrough */ 123 case ET_ButtonPress: 124 case ET_ButtonRelease: 125 case ET_KeyPress: 126 case ET_KeyRelease: 127 { 128 DeviceEvent *e = &event->device_event; 129 130 if (e->detail.key > 0xFF) { 131 ret = BadMatch; 132 goto out; 133 } 134 135 core = calloc(1, sizeof(*core)); 136 if (!core) 137 return BadAlloc; 138 count = 1; 139 core->u.u.type = e->type - ET_KeyPress + KeyPress; 140 core->u.u.detail = e->detail.key & 0xFF; 141 core->u.keyButtonPointer.time = e->time; 142 core->u.keyButtonPointer.rootX = e->root_x; 143 core->u.keyButtonPointer.rootY = e->root_y; 144 core->u.keyButtonPointer.state = e->corestate; 145 core->u.keyButtonPointer.root = e->root; 146 EventSetKeyRepeatFlag(core, (e->type == ET_KeyPress && e->key_repeat)); 147 ret = Success; 148 } 149 break; 150 case ET_ProximityIn: 151 case ET_ProximityOut: 152 case ET_RawKeyPress: 153 case ET_RawKeyRelease: 154 case ET_RawButtonPress: 155 case ET_RawButtonRelease: 156 case ET_RawMotion: 157 case ET_RawTouchBegin: 158 case ET_RawTouchUpdate: 159 case ET_RawTouchEnd: 160 case ET_TouchBegin: 161 case ET_TouchUpdate: 162 case ET_TouchEnd: 163 case ET_TouchOwnership: 164 case ET_BarrierHit: 165 case ET_BarrierLeave: 166 ret = BadMatch; 167 break; 168 default: 169 /* XXX: */ 170 ErrorF("[dix] EventToCore: Not implemented yet \n"); 171 ret = BadImplementation; 172 } 173 174 out: 175 *core_out = core; 176 *count_out = count; 177 return ret; 178} 179 180/** 181 * Convert the given event to the respective XI 1.x event and store it in 182 * xi. xi is allocated on demand and must be freed by the caller. 183 * count returns the number of events in xi. If count is 1, and the type of 184 * xi is GenericEvent, then xi may be larger than 32 bytes. 185 * 186 * Return values: 187 * Success ... core contains the matching core event. 188 * BadValue .. One or more values in the internal event are invalid. 189 * BadMatch .. The event has no XI equivalent. 190 * 191 * @param[in] ev The event to convert into an XI 1 event. 192 * @param[out] xi Future memory location for the XI event. 193 * @param[out] count Number of elements in xi. 194 * 195 * @return Success or the error code. 196 */ 197int 198EventToXI(InternalEvent *ev, xEvent **xi, int *count) 199{ 200 switch (ev->any.type) { 201 case ET_Motion: 202 case ET_ButtonPress: 203 case ET_ButtonRelease: 204 case ET_KeyPress: 205 case ET_KeyRelease: 206 case ET_ProximityIn: 207 case ET_ProximityOut: 208 return eventToKeyButtonPointer(&ev->device_event, xi, count); 209 case ET_DeviceChanged: 210 case ET_RawKeyPress: 211 case ET_RawKeyRelease: 212 case ET_RawButtonPress: 213 case ET_RawButtonRelease: 214 case ET_RawMotion: 215 case ET_RawTouchBegin: 216 case ET_RawTouchUpdate: 217 case ET_RawTouchEnd: 218 case ET_TouchBegin: 219 case ET_TouchUpdate: 220 case ET_TouchEnd: 221 case ET_TouchOwnership: 222 case ET_BarrierHit: 223 case ET_BarrierLeave: 224 *count = 0; 225 *xi = NULL; 226 return BadMatch; 227 default: 228 break; 229 } 230 231 ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->any.type); 232 return BadImplementation; 233} 234 235/** 236 * Convert the given event to the respective XI 2.x event and store it in xi. 237 * xi is allocated on demand and must be freed by the caller. 238 * 239 * Return values: 240 * Success ... core contains the matching core event. 241 * BadValue .. One or more values in the internal event are invalid. 242 * BadMatch .. The event has no XI2 equivalent. 243 * 244 * @param[in] ev The event to convert into an XI2 event 245 * @param[out] xi Future memory location for the XI2 event. 246 * 247 * @return Success or the error code. 248 */ 249int 250EventToXI2(InternalEvent *ev, xEvent **xi) 251{ 252 switch (ev->any.type) { 253 /* Enter/FocusIn are for grabs. We don't need an actual event, since 254 * the real events delivered are triggered elsewhere */ 255 case ET_Enter: 256 case ET_FocusIn: 257 *xi = NULL; 258 return Success; 259 case ET_Motion: 260 case ET_ButtonPress: 261 case ET_ButtonRelease: 262 case ET_KeyPress: 263 case ET_KeyRelease: 264 case ET_TouchBegin: 265 case ET_TouchUpdate: 266 case ET_TouchEnd: 267 return eventToDeviceEvent(&ev->device_event, xi); 268 case ET_TouchOwnership: 269 return eventToTouchOwnershipEvent(&ev->touch_ownership_event, xi); 270 case ET_ProximityIn: 271 case ET_ProximityOut: 272 *xi = NULL; 273 return BadMatch; 274 case ET_DeviceChanged: 275 return eventToDeviceChanged(&ev->changed_event, xi); 276 case ET_RawKeyPress: 277 case ET_RawKeyRelease: 278 case ET_RawButtonPress: 279 case ET_RawButtonRelease: 280 case ET_RawMotion: 281 case ET_RawTouchBegin: 282 case ET_RawTouchUpdate: 283 case ET_RawTouchEnd: 284 return eventToRawEvent(&ev->raw_event, xi); 285 case ET_BarrierHit: 286 case ET_BarrierLeave: 287 return eventToBarrierEvent(&ev->barrier_event, xi); 288 default: 289 break; 290 } 291 292 ErrorF("[dix] EventToXI2: Not implemented for %d \n", ev->any.type); 293 return BadImplementation; 294} 295 296static int 297eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count) 298{ 299 int num_events; 300 int first; /* dummy */ 301 deviceKeyButtonPointer *kbp; 302 303 /* Sorry, XI 1.x protocol restrictions. */ 304 if (ev->detail.button > 0xFF || ev->deviceid >= 0x80) { 305 *count = 0; 306 return Success; 307 } 308 309 num_events = (countValuators(ev, &first) + 5) / 6; /* valuator ev */ 310 if (num_events <= 0) { 311 switch (ev->type) { 312 case ET_KeyPress: 313 case ET_KeyRelease: 314 case ET_ButtonPress: 315 case ET_ButtonRelease: 316 /* no axes is ok */ 317 break; 318 case ET_Motion: 319 case ET_ProximityIn: 320 case ET_ProximityOut: 321 *count = 0; 322 return BadMatch; 323 default: 324 *count = 0; 325 return BadImplementation; 326 } 327 } 328 329 num_events++; /* the actual event event */ 330 331 *xi = calloc(num_events, sizeof(xEvent)); 332 if (!(*xi)) { 333 return BadAlloc; 334 } 335 336 kbp = (deviceKeyButtonPointer *) (*xi); 337 kbp->detail = ev->detail.button; 338 kbp->time = ev->time; 339 kbp->root = ev->root; 340 kbp->root_x = ev->root_x; 341 kbp->root_y = ev->root_y; 342 kbp->deviceid = ev->deviceid; 343 kbp->state = ev->corestate; 344 EventSetKeyRepeatFlag((xEvent *) kbp, 345 (ev->type == ET_KeyPress && ev->key_repeat)); 346 347 if (num_events > 1) 348 kbp->deviceid |= MORE_EVENTS; 349 350 switch (ev->type) { 351 case ET_Motion: 352 kbp->type = DeviceMotionNotify; 353 break; 354 case ET_ButtonPress: 355 kbp->type = DeviceButtonPress; 356 break; 357 case ET_ButtonRelease: 358 kbp->type = DeviceButtonRelease; 359 break; 360 case ET_KeyPress: 361 kbp->type = DeviceKeyPress; 362 break; 363 case ET_KeyRelease: 364 kbp->type = DeviceKeyRelease; 365 break; 366 case ET_ProximityIn: 367 kbp->type = ProximityIn; 368 break; 369 case ET_ProximityOut: 370 kbp->type = ProximityOut; 371 break; 372 default: 373 break; 374 } 375 376 if (num_events > 1) { 377 getValuatorEvents(ev, (deviceValuator *) (kbp + 1)); 378 } 379 380 *count = num_events; 381 return Success; 382} 383 384/** 385 * Set first to the first valuator in the event ev and return the number of 386 * valuators from first to the last set valuator. 387 */ 388static int 389countValuators(DeviceEvent *ev, int *first) 390{ 391 int first_valuator = -1, last_valuator = -1, num_valuators = 0; 392 int i; 393 394 for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) { 395 if (BitIsOn(ev->valuators.mask, i)) { 396 if (first_valuator == -1) 397 first_valuator = i; 398 last_valuator = i; 399 } 400 } 401 402 if (first_valuator != -1) { 403 num_valuators = last_valuator - first_valuator + 1; 404 *first = first_valuator; 405 } 406 407 return num_valuators; 408} 409 410static int 411getValuatorEvents(DeviceEvent *ev, deviceValuator * xv) 412{ 413 int i; 414 int state = 0; 415 int first_valuator, num_valuators; 416 417 num_valuators = countValuators(ev, &first_valuator); 418 if (num_valuators > 0) { 419 DeviceIntPtr dev = NULL; 420 421 dixLookupDevice(&dev, ev->deviceid, serverClient, DixUseAccess); 422 /* State needs to be assembled BEFORE the device is updated. */ 423 state = (dev && 424 dev->key) ? XkbStateFieldFromRec(&dev->key->xkbInfo-> 425 state) : 0; 426 state |= (dev && dev->button) ? (dev->button->state) : 0; 427 } 428 429 for (i = 0; i < num_valuators; i += 6, xv++) { 430 INT32 *valuators = &xv->valuator0; // Treat all 6 vals as an array 431 int j; 432 433 xv->type = DeviceValuator; 434 xv->first_valuator = first_valuator + i; 435 xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i); 436 xv->deviceid = ev->deviceid; 437 xv->device_state = state; 438 439 /* Unset valuators in masked valuator events have the proper data values 440 * in the case of an absolute axis in between two set valuators. */ 441 for (j = 0; j < xv->num_valuators; j++) 442 valuators[j] = ev->valuators.data[xv->first_valuator + j]; 443 444 if (i + 6 < num_valuators) 445 xv->deviceid |= MORE_EVENTS; 446 } 447 448 return (num_valuators + 5) / 6; 449} 450 451static int 452appendKeyInfo(DeviceChangedEvent *dce, xXIKeyInfo * info) 453{ 454 uint32_t *kc; 455 int i; 456 457 info->type = XIKeyClass; 458 info->num_keycodes = dce->keys.max_keycode - dce->keys.min_keycode + 1; 459 info->length = sizeof(xXIKeyInfo) / 4 + info->num_keycodes; 460 info->sourceid = dce->sourceid; 461 462 kc = (uint32_t *) &info[1]; 463 for (i = 0; i < info->num_keycodes; i++) 464 *kc++ = i + dce->keys.min_keycode; 465 466 return info->length * 4; 467} 468 469static int 470appendButtonInfo(DeviceChangedEvent *dce, xXIButtonInfo * info) 471{ 472 unsigned char *bits; 473 int mask_len; 474 475 mask_len = bytes_to_int32(bits_to_bytes(dce->buttons.num_buttons)); 476 477 info->type = XIButtonClass; 478 info->num_buttons = dce->buttons.num_buttons; 479 info->length = bytes_to_int32(sizeof(xXIButtonInfo)) + 480 info->num_buttons + mask_len; 481 info->sourceid = dce->sourceid; 482 483 bits = (unsigned char *) &info[1]; 484 memset(bits, 0, mask_len * 4); 485 /* FIXME: is_down? */ 486 487 bits += mask_len * 4; 488 memcpy(bits, dce->buttons.names, dce->buttons.num_buttons * sizeof(Atom)); 489 490 return info->length * 4; 491} 492 493static int 494appendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo * info, 495 int axisnumber) 496{ 497 info->type = XIValuatorClass; 498 info->length = sizeof(xXIValuatorInfo) / 4; 499 info->label = dce->valuators[axisnumber].name; 500 info->min.integral = dce->valuators[axisnumber].min; 501 info->min.frac = 0; 502 info->max.integral = dce->valuators[axisnumber].max; 503 info->max.frac = 0; 504 info->value = double_to_fp3232(dce->valuators[axisnumber].value); 505 info->resolution = dce->valuators[axisnumber].resolution; 506 info->number = axisnumber; 507 info->mode = dce->valuators[axisnumber].mode; 508 info->sourceid = dce->sourceid; 509 510 return info->length * 4; 511} 512 513static int 514appendScrollInfo(DeviceChangedEvent *dce, xXIScrollInfo * info, int axisnumber) 515{ 516 if (dce->valuators[axisnumber].scroll.type == SCROLL_TYPE_NONE) 517 return 0; 518 519 info->type = XIScrollClass; 520 info->length = sizeof(xXIScrollInfo) / 4; 521 info->number = axisnumber; 522 switch (dce->valuators[axisnumber].scroll.type) { 523 case SCROLL_TYPE_VERTICAL: 524 info->scroll_type = XIScrollTypeVertical; 525 break; 526 case SCROLL_TYPE_HORIZONTAL: 527 info->scroll_type = XIScrollTypeHorizontal; 528 break; 529 default: 530 ErrorF("[Xi] Unknown scroll type %d. This is a bug.\n", 531 dce->valuators[axisnumber].scroll.type); 532 break; 533 } 534 info->increment = 535 double_to_fp3232(dce->valuators[axisnumber].scroll.increment); 536 info->sourceid = dce->sourceid; 537 538 info->flags = 0; 539 540 if (dce->valuators[axisnumber].scroll.flags & SCROLL_FLAG_DONT_EMULATE) 541 info->flags |= XIScrollFlagNoEmulation; 542 if (dce->valuators[axisnumber].scroll.flags & SCROLL_FLAG_PREFERRED) 543 info->flags |= XIScrollFlagPreferred; 544 545 return info->length * 4; 546} 547 548static int 549eventToDeviceChanged(DeviceChangedEvent *dce, xEvent **xi) 550{ 551 xXIDeviceChangedEvent *dcce; 552 int len = sizeof(xXIDeviceChangedEvent); 553 int nkeys; 554 char *ptr; 555 556 if (dce->buttons.num_buttons) { 557 len += sizeof(xXIButtonInfo); 558 len += dce->buttons.num_buttons * sizeof(Atom); /* button names */ 559 len += pad_to_int32(bits_to_bytes(dce->buttons.num_buttons)); 560 } 561 if (dce->num_valuators) { 562 int i; 563 564 len += sizeof(xXIValuatorInfo) * dce->num_valuators; 565 566 for (i = 0; i < dce->num_valuators; i++) 567 if (dce->valuators[i].scroll.type != SCROLL_TYPE_NONE) 568 len += sizeof(xXIScrollInfo); 569 } 570 571 nkeys = (dce->keys.max_keycode > 0) ? 572 dce->keys.max_keycode - dce->keys.min_keycode + 1 : 0; 573 if (nkeys > 0) { 574 len += sizeof(xXIKeyInfo); 575 len += sizeof(CARD32) * nkeys; /* keycodes */ 576 } 577 578 dcce = calloc(1, len); 579 if (!dcce) { 580 ErrorF("[Xi] BadAlloc in SendDeviceChangedEvent.\n"); 581 return BadAlloc; 582 } 583 584 dcce->type = GenericEvent; 585 dcce->extension = IReqCode; 586 dcce->evtype = XI_DeviceChanged; 587 dcce->time = dce->time; 588 dcce->deviceid = dce->deviceid; 589 dcce->sourceid = dce->sourceid; 590 dcce->reason = 591 (dce->flags & DEVCHANGE_DEVICE_CHANGE) ? XIDeviceChange : XISlaveSwitch; 592 dcce->num_classes = 0; 593 dcce->length = bytes_to_int32(len - sizeof(xEvent)); 594 595 ptr = (char *) &dcce[1]; 596 if (dce->buttons.num_buttons) { 597 dcce->num_classes++; 598 ptr += appendButtonInfo(dce, (xXIButtonInfo *) ptr); 599 } 600 601 if (nkeys) { 602 dcce->num_classes++; 603 ptr += appendKeyInfo(dce, (xXIKeyInfo *) ptr); 604 } 605 606 if (dce->num_valuators) { 607 int i; 608 609 dcce->num_classes += dce->num_valuators; 610 for (i = 0; i < dce->num_valuators; i++) 611 ptr += appendValuatorInfo(dce, (xXIValuatorInfo *) ptr, i); 612 613 for (i = 0; i < dce->num_valuators; i++) { 614 if (dce->valuators[i].scroll.type != SCROLL_TYPE_NONE) { 615 dcce->num_classes++; 616 ptr += appendScrollInfo(dce, (xXIScrollInfo *) ptr, i); 617 } 618 } 619 } 620 621 *xi = (xEvent *) dcce; 622 623 return Success; 624} 625 626static int 627count_bits(unsigned char *ptr, int len) 628{ 629 int bits = 0; 630 unsigned int i; 631 unsigned char x; 632 633 for (i = 0; i < len; i++) { 634 x = ptr[i]; 635 while (x > 0) { 636 bits += (x & 0x1); 637 x >>= 1; 638 } 639 } 640 return bits; 641} 642 643static int 644eventToDeviceEvent(DeviceEvent *ev, xEvent **xi) 645{ 646 int len = sizeof(xXIDeviceEvent); 647 xXIDeviceEvent *xde; 648 int i, btlen, vallen; 649 char *ptr; 650 FP3232 *axisval; 651 652 /* FIXME: this should just send the buttons we have, not MAX_BUTTONs. Same 653 * with MAX_VALUATORS below */ 654 /* btlen is in 4 byte units */ 655 btlen = bytes_to_int32(bits_to_bytes(MAX_BUTTONS)); 656 len += btlen * 4; /* buttonmask len */ 657 658 vallen = count_bits(ev->valuators.mask, ARRAY_SIZE(ev->valuators.mask)); 659 len += vallen * 2 * sizeof(uint32_t); /* axisvalues */ 660 vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS)); 661 len += vallen * 4; /* valuators mask */ 662 663 *xi = calloc(1, len); 664 xde = (xXIDeviceEvent *) * xi; 665 xde->type = GenericEvent; 666 xde->extension = IReqCode; 667 xde->evtype = GetXI2Type(ev->type); 668 xde->time = ev->time; 669 xde->length = bytes_to_int32(len - sizeof(xEvent)); 670 if (IsTouchEvent((InternalEvent *) ev)) 671 xde->detail = ev->touchid; 672 else 673 xde->detail = ev->detail.button; 674 675 xde->root = ev->root; 676 xde->buttons_len = btlen; 677 xde->valuators_len = vallen; 678 xde->deviceid = ev->deviceid; 679 xde->sourceid = ev->sourceid; 680 xde->root_x = double_to_fp1616(ev->root_x + ev->root_x_frac); 681 xde->root_y = double_to_fp1616(ev->root_y + ev->root_y_frac); 682 683 if (IsTouchEvent((InternalEvent *)ev)) { 684 if (ev->type == ET_TouchUpdate) 685 xde->flags |= (ev->flags & TOUCH_PENDING_END) ? XITouchPendingEnd : 0; 686 687 if (ev->flags & TOUCH_POINTER_EMULATED) 688 xde->flags |= XITouchEmulatingPointer; 689 } else { 690 xde->flags = ev->flags; 691 692 if (ev->key_repeat) 693 xde->flags |= XIKeyRepeat; 694 } 695 696 xde->mods.base_mods = ev->mods.base; 697 xde->mods.latched_mods = ev->mods.latched; 698 xde->mods.locked_mods = ev->mods.locked; 699 xde->mods.effective_mods = ev->mods.effective; 700 701 xde->group.base_group = ev->group.base; 702 xde->group.latched_group = ev->group.latched; 703 xde->group.locked_group = ev->group.locked; 704 xde->group.effective_group = ev->group.effective; 705 706 ptr = (char *) &xde[1]; 707 for (i = 0; i < sizeof(ev->buttons) * 8; i++) { 708 if (BitIsOn(ev->buttons, i)) 709 SetBit(ptr, i); 710 } 711 712 ptr += xde->buttons_len * 4; 713 axisval = (FP3232 *) (ptr + xde->valuators_len * 4); 714 for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) { 715 if (BitIsOn(ev->valuators.mask, i)) { 716 SetBit(ptr, i); 717 *axisval = double_to_fp3232(ev->valuators.data[i]); 718 axisval++; 719 } 720 } 721 722 return Success; 723} 724 725static int 726eventToTouchOwnershipEvent(TouchOwnershipEvent *ev, xEvent **xi) 727{ 728 int len = sizeof(xXITouchOwnershipEvent); 729 xXITouchOwnershipEvent *xtoe; 730 731 *xi = calloc(1, len); 732 xtoe = (xXITouchOwnershipEvent *) * xi; 733 xtoe->type = GenericEvent; 734 xtoe->extension = IReqCode; 735 xtoe->length = bytes_to_int32(len - sizeof(xEvent)); 736 xtoe->evtype = GetXI2Type(ev->type); 737 xtoe->deviceid = ev->deviceid; 738 xtoe->time = ev->time; 739 xtoe->sourceid = ev->sourceid; 740 xtoe->touchid = ev->touchid; 741 xtoe->flags = 0; /* we don't have wire flags for ownership yet */ 742 743 return Success; 744} 745 746static int 747eventToRawEvent(RawDeviceEvent *ev, xEvent **xi) 748{ 749 xXIRawEvent *raw; 750 int vallen, nvals; 751 int i, len = sizeof(xXIRawEvent); 752 char *ptr; 753 FP3232 *axisval, *axisval_raw; 754 755 nvals = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask)); 756 len += nvals * sizeof(FP3232) * 2; /* 8 byte per valuator, once 757 raw, once processed */ 758 vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS)); 759 len += vallen * 4; /* valuators mask */ 760 761 *xi = calloc(1, len); 762 raw = (xXIRawEvent *) * xi; 763 raw->type = GenericEvent; 764 raw->extension = IReqCode; 765 raw->evtype = GetXI2Type(ev->type); 766 raw->time = ev->time; 767 raw->length = bytes_to_int32(len - sizeof(xEvent)); 768 raw->detail = ev->detail.button; 769 raw->deviceid = ev->deviceid; 770 raw->sourceid = ev->sourceid; 771 raw->valuators_len = vallen; 772 raw->flags = ev->flags; 773 774 ptr = (char *) &raw[1]; 775 axisval = (FP3232 *) (ptr + raw->valuators_len * 4); 776 axisval_raw = axisval + nvals; 777 for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) { 778 if (BitIsOn(ev->valuators.mask, i)) { 779 SetBit(ptr, i); 780 *axisval = double_to_fp3232(ev->valuators.data[i]); 781 *axisval_raw = double_to_fp3232(ev->valuators.data_raw[i]); 782 axisval++; 783 axisval_raw++; 784 } 785 } 786 787 return Success; 788} 789 790static int 791eventToBarrierEvent(BarrierEvent *ev, xEvent **xi) 792{ 793 xXIBarrierEvent *barrier; 794 int len = sizeof(xXIBarrierEvent); 795 796 *xi = calloc(1, len); 797 barrier = (xXIBarrierEvent*) *xi; 798 barrier->type = GenericEvent; 799 barrier->extension = IReqCode; 800 barrier->evtype = GetXI2Type(ev->type); 801 barrier->length = bytes_to_int32(len - sizeof(xEvent)); 802 barrier->deviceid = ev->deviceid; 803 barrier->sourceid = ev->sourceid; 804 barrier->time = ev->time; 805 barrier->event = ev->window; 806 barrier->root = ev->root; 807 barrier->dx = double_to_fp3232(ev->dx); 808 barrier->dy = double_to_fp3232(ev->dy); 809 barrier->dtime = ev->dt; 810 barrier->flags = ev->flags; 811 barrier->eventid = ev->event_id; 812 barrier->barrier = ev->barrierid; 813 barrier->root_x = double_to_fp1616(ev->root_x); 814 barrier->root_y = double_to_fp1616(ev->root_y); 815 816 return Success; 817} 818 819/** 820 * Return the corresponding core type for the given event or 0 if no core 821 * equivalent exists. 822 */ 823int 824GetCoreType(enum EventType type) 825{ 826 int coretype = 0; 827 828 switch (type) { 829 case ET_Motion: 830 coretype = MotionNotify; 831 break; 832 case ET_ButtonPress: 833 coretype = ButtonPress; 834 break; 835 case ET_ButtonRelease: 836 coretype = ButtonRelease; 837 break; 838 case ET_KeyPress: 839 coretype = KeyPress; 840 break; 841 case ET_KeyRelease: 842 coretype = KeyRelease; 843 break; 844 default: 845 break; 846 } 847 return coretype; 848} 849 850/** 851 * Return the corresponding XI 1.x type for the given event or 0 if no 852 * equivalent exists. 853 */ 854int 855GetXIType(enum EventType type) 856{ 857 int xitype = 0; 858 859 switch (type) { 860 case ET_Motion: 861 xitype = DeviceMotionNotify; 862 break; 863 case ET_ButtonPress: 864 xitype = DeviceButtonPress; 865 break; 866 case ET_ButtonRelease: 867 xitype = DeviceButtonRelease; 868 break; 869 case ET_KeyPress: 870 xitype = DeviceKeyPress; 871 break; 872 case ET_KeyRelease: 873 xitype = DeviceKeyRelease; 874 break; 875 case ET_ProximityIn: 876 xitype = ProximityIn; 877 break; 878 case ET_ProximityOut: 879 xitype = ProximityOut; 880 break; 881 default: 882 break; 883 } 884 return xitype; 885} 886 887/** 888 * Return the corresponding XI 2.x type for the given event or 0 if no 889 * equivalent exists. 890 */ 891int 892GetXI2Type(enum EventType type) 893{ 894 int xi2type = 0; 895 896 switch (type) { 897 case ET_Motion: 898 xi2type = XI_Motion; 899 break; 900 case ET_ButtonPress: 901 xi2type = XI_ButtonPress; 902 break; 903 case ET_ButtonRelease: 904 xi2type = XI_ButtonRelease; 905 break; 906 case ET_KeyPress: 907 xi2type = XI_KeyPress; 908 break; 909 case ET_KeyRelease: 910 xi2type = XI_KeyRelease; 911 break; 912 case ET_Enter: 913 xi2type = XI_Enter; 914 break; 915 case ET_Leave: 916 xi2type = XI_Leave; 917 break; 918 case ET_Hierarchy: 919 xi2type = XI_HierarchyChanged; 920 break; 921 case ET_DeviceChanged: 922 xi2type = XI_DeviceChanged; 923 break; 924 case ET_RawKeyPress: 925 xi2type = XI_RawKeyPress; 926 break; 927 case ET_RawKeyRelease: 928 xi2type = XI_RawKeyRelease; 929 break; 930 case ET_RawButtonPress: 931 xi2type = XI_RawButtonPress; 932 break; 933 case ET_RawButtonRelease: 934 xi2type = XI_RawButtonRelease; 935 break; 936 case ET_RawMotion: 937 xi2type = XI_RawMotion; 938 break; 939 case ET_RawTouchBegin: 940 xi2type = XI_RawTouchBegin; 941 break; 942 case ET_RawTouchUpdate: 943 xi2type = XI_RawTouchUpdate; 944 break; 945 case ET_RawTouchEnd: 946 xi2type = XI_RawTouchEnd; 947 break; 948 case ET_FocusIn: 949 xi2type = XI_FocusIn; 950 break; 951 case ET_FocusOut: 952 xi2type = XI_FocusOut; 953 break; 954 case ET_TouchBegin: 955 xi2type = XI_TouchBegin; 956 break; 957 case ET_TouchEnd: 958 xi2type = XI_TouchEnd; 959 break; 960 case ET_TouchUpdate: 961 xi2type = XI_TouchUpdate; 962 break; 963 case ET_TouchOwnership: 964 xi2type = XI_TouchOwnership; 965 break; 966 case ET_BarrierHit: 967 xi2type = XI_BarrierHit; 968 break; 969 case ET_BarrierLeave: 970 xi2type = XI_BarrierLeave; 971 break; 972 default: 973 break; 974 } 975 return xi2type; 976} 977