eventconvert.c revision 8223e2f2
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 "exglobals.h" 47#include "eventconvert.h" 48#include "xiquerydevice.h" 49#include "xkbsrv.h" 50 51 52static int countValuators(DeviceEvent *ev, int *first); 53static int getValuatorEvents(DeviceEvent *ev, deviceValuator *xv); 54static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count); 55static int eventToDeviceChanged(DeviceChangedEvent *ev, xEvent **dcce); 56static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi); 57static int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi); 58 59/* Do not use, read comments below */ 60BOOL EventIsKeyRepeat(xEvent *event); 61 62/** 63 * Hack to allow detectable autorepeat for core and XI1 events. 64 * The sequence number is unused until we send to the client and can be 65 * misused to store data. More or less, anyway. 66 * 67 * Do not use this. It may change any time without warning, eat your babies 68 * and piss on your cat. 69 */ 70static void 71EventSetKeyRepeatFlag(xEvent *event, BOOL on) 72{ 73 event->u.u.sequenceNumber = on; 74} 75 76/** 77 * Check if the event was marked as a repeat event before. 78 * NOTE: This is a nasty hack and should NOT be used by anyone else but 79 * TryClientEvents. 80 */ 81BOOL 82EventIsKeyRepeat(xEvent *event) 83{ 84 return !!event->u.u.sequenceNumber; 85} 86 87/** 88 * Convert the given event to the respective core event. 89 * 90 * Return values: 91 * Success ... core contains the matching core event. 92 * BadValue .. One or more values in the internal event are invalid. 93 * BadMatch .. The event has no core equivalent. 94 * 95 * @param[in] event The event to convert into a core event. 96 * @param[in] core The memory location to store the core event at. 97 * @return Success or the matching error code. 98 */ 99int 100EventToCore(InternalEvent *event, xEvent *core) 101{ 102 switch(event->any.type) 103 { 104 case ET_Motion: 105 { 106 DeviceEvent *e = &event->device_event; 107 /* Don't create core motion event if neither x nor y are 108 * present */ 109 if (!BitIsOn(e->valuators.mask, 0) && 110 !BitIsOn(e->valuators.mask, 1)) 111 return BadMatch; 112 } 113 /* fallthrough */ 114 case ET_ButtonPress: 115 case ET_ButtonRelease: 116 case ET_KeyPress: 117 case ET_KeyRelease: 118 { 119 DeviceEvent *e = &event->device_event; 120 121 if (e->detail.key > 0xFF) 122 return BadMatch; 123 124 memset(core, 0, sizeof(xEvent)); 125 core->u.u.type = e->type - ET_KeyPress + KeyPress; 126 core->u.u.detail = e->detail.key & 0xFF; 127 core->u.keyButtonPointer.time = e->time; 128 core->u.keyButtonPointer.rootX = e->root_x; 129 core->u.keyButtonPointer.rootY = e->root_y; 130 core->u.keyButtonPointer.state = e->corestate; 131 core->u.keyButtonPointer.root = e->root; 132 EventSetKeyRepeatFlag(core, (e->type == ET_KeyPress && e->key_repeat)); 133 } 134 break; 135 case ET_ProximityIn: 136 case ET_ProximityOut: 137 case ET_RawKeyPress: 138 case ET_RawKeyRelease: 139 case ET_RawButtonPress: 140 case ET_RawButtonRelease: 141 case ET_RawMotion: 142 return BadMatch; 143 default: 144 /* XXX: */ 145 ErrorF("[dix] EventToCore: Not implemented yet \n"); 146 return BadImplementation; 147 } 148 return Success; 149} 150 151/** 152 * Convert the given event to the respective XI 1.x event and store it in 153 * xi. xi is allocated on demand and must be freed by the caller. 154 * count returns the number of events in xi. If count is 1, and the type of 155 * xi is GenericEvent, then xi may be larger than 32 bytes. 156 * 157 * Return values: 158 * Success ... core contains the matching core event. 159 * BadValue .. One or more values in the internal event are invalid. 160 * BadMatch .. The event has no XI equivalent. 161 * 162 * @param[in] ev The event to convert into an XI 1 event. 163 * @param[out] xi Future memory location for the XI event. 164 * @param[out] count Number of elements in xi. 165 * 166 * @return Success or the error code. 167 */ 168int 169EventToXI(InternalEvent *ev, xEvent **xi, int *count) 170{ 171 switch (ev->any.type) 172 { 173 case ET_Motion: 174 case ET_ButtonPress: 175 case ET_ButtonRelease: 176 case ET_KeyPress: 177 case ET_KeyRelease: 178 case ET_ProximityIn: 179 case ET_ProximityOut: 180 return eventToKeyButtonPointer(&ev->device_event, xi, count); 181 case ET_DeviceChanged: 182 case ET_RawKeyPress: 183 case ET_RawKeyRelease: 184 case ET_RawButtonPress: 185 case ET_RawButtonRelease: 186 case ET_RawMotion: 187 *count = 0; 188 *xi = NULL; 189 return BadMatch; 190 default: 191 break; 192 } 193 194 ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->any.type); 195 return BadImplementation; 196} 197 198/** 199 * Convert the given event to the respective XI 2.x event and store it in xi. 200 * xi is allocated on demand and must be freed by the caller. 201 * 202 * Return values: 203 * Success ... core contains the matching core event. 204 * BadValue .. One or more values in the internal event are invalid. 205 * BadMatch .. The event has no XI2 equivalent. 206 * 207 * @param[in] ev The event to convert into an XI2 event 208 * @param[out] xi Future memory location for the XI2 event. 209 * 210 * @return Success or the error code. 211 */ 212int 213EventToXI2(InternalEvent *ev, xEvent **xi) 214{ 215 switch (ev->any.type) 216 { 217 /* Enter/FocusIn are for grabs. We don't need an actual event, since 218 * the real events delivered are triggered elsewhere */ 219 case ET_Enter: 220 case ET_FocusIn: 221 *xi = NULL; 222 return Success; 223 case ET_Motion: 224 case ET_ButtonPress: 225 case ET_ButtonRelease: 226 case ET_KeyPress: 227 case ET_KeyRelease: 228 return eventToDeviceEvent(&ev->device_event, xi); 229 case ET_ProximityIn: 230 case ET_ProximityOut: 231 *xi = NULL; 232 return BadMatch; 233 case ET_DeviceChanged: 234 return eventToDeviceChanged(&ev->changed_event, xi); 235 case ET_RawKeyPress: 236 case ET_RawKeyRelease: 237 case ET_RawButtonPress: 238 case ET_RawButtonRelease: 239 case ET_RawMotion: 240 return eventToRawEvent(&ev->raw_event, xi); 241 default: 242 break; 243 } 244 245 ErrorF("[dix] EventToXI2: Not implemented for %d \n", ev->any.type); 246 return BadImplementation; 247} 248 249static int 250eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count) 251{ 252 int num_events; 253 int first; /* dummy */ 254 deviceKeyButtonPointer *kbp; 255 256 /* Sorry, XI 1.x protocol restrictions. */ 257 if (ev->detail.button > 0xFF || ev->deviceid >= 0x80) 258 { 259 *count = 0; 260 return Success; 261 } 262 263 num_events = (countValuators(ev, &first) + 5)/6; /* valuator ev */ 264 num_events++; /* the actual event event */ 265 266 *xi = calloc(num_events, sizeof(xEvent)); 267 if (!(*xi)) 268 { 269 return BadAlloc; 270 } 271 272 kbp = (deviceKeyButtonPointer*)(*xi); 273 kbp->detail = ev->detail.button; 274 kbp->time = ev->time; 275 kbp->root = ev->root; 276 kbp->root_x = ev->root_x; 277 kbp->root_y = ev->root_y; 278 kbp->deviceid = ev->deviceid; 279 kbp->state = ev->corestate; 280 EventSetKeyRepeatFlag((xEvent*)kbp, 281 (ev->type == ET_KeyPress && ev->key_repeat)); 282 283 if (num_events > 1) 284 kbp->deviceid |= MORE_EVENTS; 285 286 switch(ev->type) 287 { 288 case ET_Motion: kbp->type = DeviceMotionNotify; break; 289 case ET_ButtonPress: kbp->type = DeviceButtonPress; break; 290 case ET_ButtonRelease: kbp->type = DeviceButtonRelease; break; 291 case ET_KeyPress: kbp->type = DeviceKeyPress; break; 292 case ET_KeyRelease: kbp->type = DeviceKeyRelease; break; 293 case ET_ProximityIn: kbp->type = ProximityIn; break; 294 case ET_ProximityOut: kbp->type = ProximityOut; break; 295 default: 296 break; 297 } 298 299 if (num_events > 1) 300 { 301 getValuatorEvents(ev, (deviceValuator*)(kbp + 1)); 302 } 303 304 *count = num_events; 305 return Success; 306} 307 308 309/** 310 * Set first to the first valuator in the event ev and return the number of 311 * valuators from first to the last set valuator. 312 */ 313static int 314countValuators(DeviceEvent *ev, int *first) 315{ 316 int first_valuator = -1, last_valuator = -1, num_valuators = 0; 317 int i; 318 319 for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) 320 { 321 if (BitIsOn(ev->valuators.mask, i)) 322 { 323 if (first_valuator == -1) 324 first_valuator = i; 325 last_valuator = i; 326 } 327 } 328 329 if (first_valuator != -1) 330 { 331 num_valuators = last_valuator - first_valuator + 1; 332 *first = first_valuator; 333 } 334 335 return num_valuators; 336} 337 338static int 339getValuatorEvents(DeviceEvent *ev, deviceValuator *xv) 340{ 341 int i; 342 int state = 0; 343 int first_valuator, num_valuators; 344 345 346 num_valuators = countValuators(ev, &first_valuator); 347 if (num_valuators > 0) 348 { 349 DeviceIntPtr dev = NULL; 350 dixLookupDevice(&dev, ev->deviceid, serverClient, DixUseAccess); 351 /* State needs to be assembled BEFORE the device is updated. */ 352 state = (dev && dev->key) ? XkbStateFieldFromRec(&dev->key->xkbInfo->state) : 0; 353 state |= (dev && dev->button) ? (dev->button->state) : 0; 354 } 355 356 /* FIXME: non-continuous valuator data in internal events*/ 357 for (i = 0; i < num_valuators; i += 6, xv++) { 358 xv->type = DeviceValuator; 359 xv->first_valuator = first_valuator + i; 360 xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i); 361 xv->deviceid = ev->deviceid; 362 xv->device_state = state; 363 switch (xv->num_valuators) { 364 case 6: 365 xv->valuator5 = ev->valuators.data[xv->first_valuator + 5]; 366 case 5: 367 xv->valuator4 = ev->valuators.data[xv->first_valuator + 4]; 368 case 4: 369 xv->valuator3 = ev->valuators.data[xv->first_valuator + 3]; 370 case 3: 371 xv->valuator2 = ev->valuators.data[xv->first_valuator + 2]; 372 case 2: 373 xv->valuator1 = ev->valuators.data[xv->first_valuator + 1]; 374 case 1: 375 xv->valuator0 = ev->valuators.data[xv->first_valuator + 0]; 376 } 377 378 if (i + 6 < num_valuators) 379 xv->deviceid |= MORE_EVENTS; 380 } 381 382 return (num_valuators + 5) / 6; 383} 384 385 386static int 387appendKeyInfo(DeviceChangedEvent *dce, xXIKeyInfo* info) 388{ 389 uint32_t *kc; 390 int i; 391 392 info->type = XIKeyClass; 393 info->num_keycodes = dce->keys.max_keycode - dce->keys.min_keycode + 1; 394 info->length = sizeof(xXIKeyInfo)/4 + info->num_keycodes; 395 info->sourceid = dce->sourceid; 396 397 kc = (uint32_t*)&info[1]; 398 for (i = 0; i < info->num_keycodes; i++) 399 *kc++ = i + dce->keys.min_keycode; 400 401 return info->length * 4; 402} 403 404static int 405appendButtonInfo(DeviceChangedEvent *dce, xXIButtonInfo *info) 406{ 407 unsigned char *bits; 408 int mask_len; 409 410 mask_len = bytes_to_int32(bits_to_bytes(dce->buttons.num_buttons)); 411 412 info->type = XIButtonClass; 413 info->num_buttons = dce->buttons.num_buttons; 414 info->length = bytes_to_int32(sizeof(xXIButtonInfo)) + 415 info->num_buttons + mask_len; 416 info->sourceid = dce->sourceid; 417 418 bits = (unsigned char*)&info[1]; 419 memset(bits, 0, mask_len * 4); 420 /* FIXME: is_down? */ 421 422 bits += mask_len * 4; 423 memcpy(bits, dce->buttons.names, dce->buttons.num_buttons * sizeof(Atom)); 424 425 return info->length * 4; 426} 427 428static int 429appendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo *info, int axisnumber) 430{ 431 info->type = XIValuatorClass; 432 info->length = sizeof(xXIValuatorInfo)/4; 433 info->label = dce->valuators[axisnumber].name; 434 info->min.integral = dce->valuators[axisnumber].min; 435 info->min.frac = 0; 436 info->max.integral = dce->valuators[axisnumber].max; 437 info->max.frac = 0; 438 /* FIXME: value */ 439 info->value.integral = 0; 440 info->value.frac = 0; 441 info->resolution = dce->valuators[axisnumber].resolution; 442 info->number = axisnumber; 443 info->mode = dce->valuators[axisnumber].mode; /* Server doesn't have per-axis mode yet */ 444 info->sourceid = dce->sourceid; 445 446 return info->length * 4; 447} 448 449static int 450eventToDeviceChanged(DeviceChangedEvent *dce, xEvent **xi) 451{ 452 xXIDeviceChangedEvent *dcce; 453 int len = sizeof(xXIDeviceChangedEvent); 454 int nkeys; 455 char *ptr; 456 457 if (dce->buttons.num_buttons) 458 { 459 len += sizeof(xXIButtonInfo); 460 len += dce->buttons.num_buttons * sizeof(Atom); /* button names */ 461 len += pad_to_int32(bits_to_bytes(dce->buttons.num_buttons)); 462 } 463 if (dce->num_valuators) 464 len += sizeof(xXIValuatorInfo) * dce->num_valuators; 465 466 nkeys = (dce->keys.max_keycode > 0) ? 467 dce->keys.max_keycode - dce->keys.min_keycode + 1 : 0; 468 if (nkeys > 0) 469 { 470 len += sizeof(xXIKeyInfo); 471 len += sizeof(CARD32) * nkeys; /* keycodes */ 472 } 473 474 dcce = calloc(1, len); 475 if (!dcce) 476 { 477 ErrorF("[Xi] BadAlloc in SendDeviceChangedEvent.\n"); 478 return BadAlloc; 479 } 480 481 dcce->type = GenericEvent; 482 dcce->extension = IReqCode; 483 dcce->evtype = XI_DeviceChanged; 484 dcce->time = dce->time; 485 dcce->deviceid = dce->deviceid; 486 dcce->sourceid = dce->sourceid; 487 dcce->reason = (dce->flags & DEVCHANGE_DEVICE_CHANGE) ? XIDeviceChange : XISlaveSwitch; 488 dcce->num_classes = 0; 489 dcce->length = bytes_to_int32(len - sizeof(xEvent)); 490 491 ptr = (char*)&dcce[1]; 492 if (dce->buttons.num_buttons) 493 { 494 dcce->num_classes++; 495 ptr += appendButtonInfo(dce, (xXIButtonInfo*)ptr); 496 } 497 498 if (nkeys) 499 { 500 dcce->num_classes++; 501 ptr += appendKeyInfo(dce, (xXIKeyInfo*)ptr); 502 } 503 504 if (dce->num_valuators) 505 { 506 int i; 507 508 dcce->num_classes += dce->num_valuators; 509 for (i = 0; i < dce->num_valuators; i++) 510 ptr += appendValuatorInfo(dce, (xXIValuatorInfo*)ptr, i); 511 } 512 513 *xi = (xEvent*)dcce; 514 515 return Success; 516} 517 518static int count_bits(unsigned char* ptr, int len) 519{ 520 int bits = 0; 521 unsigned int i; 522 unsigned char x; 523 524 for (i = 0; i < len; i++) 525 { 526 x = ptr[i]; 527 while(x > 0) 528 { 529 bits += (x & 0x1); 530 x >>= 1; 531 } 532 } 533 return bits; 534} 535 536static int 537eventToDeviceEvent(DeviceEvent *ev, xEvent **xi) 538{ 539 int len = sizeof(xXIDeviceEvent); 540 xXIDeviceEvent *xde; 541 int i, btlen, vallen; 542 char *ptr; 543 FP3232 *axisval; 544 545 /* FIXME: this should just send the buttons we have, not MAX_BUTTONs. Same 546 * with MAX_VALUATORS below */ 547 /* btlen is in 4 byte units */ 548 btlen = bytes_to_int32(bits_to_bytes(MAX_BUTTONS)); 549 len += btlen * 4; /* buttonmask len */ 550 551 552 vallen = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask)/sizeof(ev->valuators.mask[0])); 553 len += vallen * 2 * sizeof(uint32_t); /* axisvalues */ 554 vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS)); 555 len += vallen * 4; /* valuators mask */ 556 557 *xi = calloc(1, len); 558 xde = (xXIDeviceEvent*)*xi; 559 xde->type = GenericEvent; 560 xde->extension = IReqCode; 561 xde->evtype = GetXI2Type((InternalEvent*)ev); 562 xde->time = ev->time; 563 xde->length = bytes_to_int32(len - sizeof(xEvent)); 564 xde->detail = ev->detail.button; 565 xde->root = ev->root; 566 xde->buttons_len = btlen; 567 xde->valuators_len = vallen; 568 xde->deviceid = ev->deviceid; 569 xde->sourceid = ev->sourceid; 570 xde->root_x = FP1616(ev->root_x, ev->root_x_frac); 571 xde->root_y = FP1616(ev->root_y, ev->root_y_frac); 572 573 if (ev->key_repeat) 574 xde->flags |= XIKeyRepeat; 575 576 xde->mods.base_mods = ev->mods.base; 577 xde->mods.latched_mods = ev->mods.latched; 578 xde->mods.locked_mods = ev->mods.locked; 579 xde->mods.effective_mods = ev->mods.effective; 580 581 xde->group.base_group = ev->group.base; 582 xde->group.latched_group = ev->group.latched; 583 xde->group.locked_group = ev->group.locked; 584 xde->group.effective_group = ev->group.effective; 585 586 ptr = (char*)&xde[1]; 587 for (i = 0; i < sizeof(ev->buttons) * 8; i++) 588 { 589 if (BitIsOn(ev->buttons, i)) 590 SetBit(ptr, i); 591 } 592 593 ptr += xde->buttons_len * 4; 594 axisval = (FP3232*)(ptr + xde->valuators_len * 4); 595 for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) 596 { 597 if (BitIsOn(ev->valuators.mask, i)) 598 { 599 SetBit(ptr, i); 600 axisval->integral = ev->valuators.data[i]; 601 axisval->frac = ev->valuators.data_frac[i]; 602 axisval++; 603 } 604 } 605 606 return Success; 607} 608 609static int 610eventToRawEvent(RawDeviceEvent *ev, xEvent **xi) 611{ 612 xXIRawEvent* raw; 613 int vallen, nvals; 614 int i, len = sizeof(xXIRawEvent); 615 char *ptr; 616 FP3232 *axisval; 617 618 nvals = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask)); 619 len += nvals * sizeof(FP3232) * 2; /* 8 byte per valuator, once 620 raw, once processed */ 621 vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS)); 622 len += vallen * 4; /* valuators mask */ 623 624 *xi = calloc(1, len); 625 raw = (xXIRawEvent*)*xi; 626 raw->type = GenericEvent; 627 raw->extension = IReqCode; 628 raw->evtype = GetXI2Type((InternalEvent*)ev); 629 raw->time = ev->time; 630 raw->length = bytes_to_int32(len - sizeof(xEvent)); 631 raw->detail = ev->detail.button; 632 raw->deviceid = ev->deviceid; 633 raw->valuators_len = vallen; 634 635 ptr = (char*)&raw[1]; 636 axisval = (FP3232*)(ptr + raw->valuators_len * 4); 637 for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) 638 { 639 if (BitIsOn(ev->valuators.mask, i)) 640 { 641 SetBit(ptr, i); 642 axisval->integral = ev->valuators.data[i]; 643 axisval->frac = ev->valuators.data_frac[i]; 644 (axisval + nvals)->integral = ev->valuators.data_raw[i]; 645 (axisval + nvals)->frac = ev->valuators.data_raw_frac[i]; 646 axisval++; 647 } 648 } 649 650 return Success; 651} 652 653/** 654 * Return the corresponding core type for the given event or 0 if no core 655 * equivalent exists. 656 */ 657int 658GetCoreType(InternalEvent *event) 659{ 660 int coretype = 0; 661 switch(event->any.type) 662 { 663 case ET_Motion: coretype = MotionNotify; break; 664 case ET_ButtonPress: coretype = ButtonPress; break; 665 case ET_ButtonRelease: coretype = ButtonRelease; break; 666 case ET_KeyPress: coretype = KeyPress; break; 667 case ET_KeyRelease: coretype = KeyRelease; break; 668 default: 669 break; 670 } 671 return coretype; 672} 673 674/** 675 * Return the corresponding XI 1.x type for the given event or 0 if no 676 * equivalent exists. 677 */ 678int 679GetXIType(InternalEvent *event) 680{ 681 int xitype = 0; 682 switch(event->any.type) 683 { 684 case ET_Motion: xitype = DeviceMotionNotify; break; 685 case ET_ButtonPress: xitype = DeviceButtonPress; break; 686 case ET_ButtonRelease: xitype = DeviceButtonRelease; break; 687 case ET_KeyPress: xitype = DeviceKeyPress; break; 688 case ET_KeyRelease: xitype = DeviceKeyRelease; break; 689 case ET_ProximityIn: xitype = ProximityIn; break; 690 case ET_ProximityOut: xitype = ProximityOut; break; 691 default: 692 break; 693 } 694 return xitype; 695} 696 697/** 698 * Return the corresponding XI 2.x type for the given event or 0 if no 699 * equivalent exists. 700 */ 701int 702GetXI2Type(InternalEvent *event) 703{ 704 int xi2type = 0; 705 706 switch(event->any.type) 707 { 708 case ET_Motion: xi2type = XI_Motion; break; 709 case ET_ButtonPress: xi2type = XI_ButtonPress; break; 710 case ET_ButtonRelease: xi2type = XI_ButtonRelease; break; 711 case ET_KeyPress: xi2type = XI_KeyPress; break; 712 case ET_KeyRelease: xi2type = XI_KeyRelease; break; 713 case ET_Enter: xi2type = XI_Enter; break; 714 case ET_Leave: xi2type = XI_Leave; break; 715 case ET_Hierarchy: xi2type = XI_HierarchyChanged; break; 716 case ET_DeviceChanged: xi2type = XI_DeviceChanged; break; 717 case ET_RawKeyPress: xi2type = XI_RawKeyPress; break; 718 case ET_RawKeyRelease: xi2type = XI_RawKeyRelease; break; 719 case ET_RawButtonPress: xi2type = XI_RawButtonPress; break; 720 case ET_RawButtonRelease: xi2type = XI_RawButtonRelease; break; 721 case ET_RawMotion: xi2type = XI_RawMotion; break; 722 case ET_FocusIn: xi2type = XI_FocusIn; break; 723 case ET_FocusOut: xi2type = XI_FocusOut; break; 724 default: 725 break; 726 } 727 return xi2type; 728} 729