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