]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/xserver.git/blob - dix/eventconvert.c
Imported Upstream version 1.11.4
[glsdk/xserver.git] / dix / eventconvert.c
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  */
25 /**
26  * @file eventconvert.c
27  * This file contains event conversion routines from InternalEvent to the
28  * matching protocol events.
29  */
31 #ifdef HAVE_DIX_CONFIG_H
32 #include <dix-config.h>
33 #endif
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>
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"
52 static int countValuators(DeviceEvent *ev, int *first);
53 static int getValuatorEvents(DeviceEvent *ev, deviceValuator *xv);
54 static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count);
55 static int eventToDeviceChanged(DeviceChangedEvent *ev, xEvent **dcce);
56 static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi);
57 static int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi);
59 /* Do not use, read comments below */
60 BOOL EventIsKeyRepeat(xEvent *event);
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  */
70 static void
71 EventSetKeyRepeatFlag(xEvent *event, BOOL on)
72 {
73     event->u.u.sequenceNumber = on;
74 }
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  */
81 BOOL
82 EventIsKeyRepeat(xEvent *event)
83 {
84     return !!event->u.u.sequenceNumber;
85 }
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  */
99 int
100 EventToCore(InternalEvent *event, xEvent **core_out, int *count_out)
102     xEvent *core = NULL;
103     int count = 0;
104     int ret = BadImplementation;
106     switch(event->any.type)
107     {
108         case ET_Motion:
109             {
110                 DeviceEvent *e = &event->device_event;
111                 /* Don't create core motion event if neither x nor y are
112                  * present */
113                 if (!BitIsOn(e->valuators.mask, 0) &&
114                     !BitIsOn(e->valuators.mask, 1))
115                 {
116                     ret = BadMatch;
117                     goto out;
118                 }
119             }
120             /* fallthrough */
121         case ET_ButtonPress:
122         case ET_ButtonRelease:
123         case ET_KeyPress:
124         case ET_KeyRelease:
125             {
126                 DeviceEvent *e = &event->device_event;
128                 if (e->detail.key > 0xFF)
129                 {
130                     ret = BadMatch;
131                     goto out;
132                 }
134                 core = calloc(1, sizeof(*core));
135                 if (!core)
136                     return BadAlloc;
137                 count = 1;
138                 core->u.u.type = e->type - ET_KeyPress + KeyPress;
139                 core->u.u.detail = e->detail.key & 0xFF;
140                 core->u.keyButtonPointer.time = e->time;
141                 core->u.keyButtonPointer.rootX = e->root_x;
142                 core->u.keyButtonPointer.rootY = e->root_y;
143                 core->u.keyButtonPointer.state = e->corestate;
144                 core->u.keyButtonPointer.root = e->root;
145                 EventSetKeyRepeatFlag(core,
146                                       (e->type == ET_KeyPress &&
147                                        e->key_repeat));
148                 ret = Success;
149             }
150             break;
151         case ET_ProximityIn:
152         case ET_ProximityOut:
153         case ET_RawKeyPress:
154         case ET_RawKeyRelease:
155         case ET_RawButtonPress:
156         case ET_RawButtonRelease:
157         case ET_RawMotion:
158             ret = BadMatch;
159             break;
160         default:
161             /* XXX: */
162             ErrorF("[dix] EventToCore: Not implemented yet \n");
163             ret = BadImplementation;
164     }
166 out:
167     *core_out = core;
168     *count_out = count;
169     return ret;
172 /**
173  * Convert the given event to the respective XI 1.x event and store it in
174  * xi. xi is allocated on demand and must be freed by the caller.
175  * count returns the number of events in xi. If count is 1, and the type of
176  * xi is GenericEvent, then xi may be larger than 32 bytes.
177  *
178  * Return values:
179  * Success ... core contains the matching core event.
180  * BadValue .. One or more values in the internal event are invalid.
181  * BadMatch .. The event has no XI equivalent.
182  *
183  * @param[in] ev The event to convert into an XI 1 event.
184  * @param[out] xi Future memory location for the XI event.
185  * @param[out] count Number of elements in xi.
186  *
187  * @return Success or the error code.
188  */
189 int
190 EventToXI(InternalEvent *ev, xEvent **xi, int *count)
192     switch (ev->any.type)
193     {
194         case ET_Motion:
195         case ET_ButtonPress:
196         case ET_ButtonRelease:
197         case ET_KeyPress:
198         case ET_KeyRelease:
199         case ET_ProximityIn:
200         case ET_ProximityOut:
201             return eventToKeyButtonPointer(&ev->device_event, xi, count);
202         case ET_DeviceChanged:
203         case ET_RawKeyPress:
204         case ET_RawKeyRelease:
205         case ET_RawButtonPress:
206         case ET_RawButtonRelease:
207         case ET_RawMotion:
208             *count = 0;
209             *xi = NULL;
210             return BadMatch;
211         default:
212             break;
213     }
215     ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->any.type);
216     return BadImplementation;
219 /**
220  * Convert the given event to the respective XI 2.x event and store it in xi.
221  * xi is allocated on demand and must be freed by the caller.
222  *
223  * Return values:
224  * Success ... core contains the matching core event.
225  * BadValue .. One or more values in the internal event are invalid.
226  * BadMatch .. The event has no XI2 equivalent.
227  *
228  * @param[in] ev The event to convert into an XI2 event
229  * @param[out] xi Future memory location for the XI2 event.
230  *
231  * @return Success or the error code.
232  */
233 int
234 EventToXI2(InternalEvent *ev, xEvent **xi)
236     switch (ev->any.type)
237     {
238         /* Enter/FocusIn are for grabs. We don't need an actual event, since
239          * the real events delivered are triggered elsewhere */
240         case ET_Enter:
241         case ET_FocusIn:
242             *xi = NULL;
243             return Success;
244         case ET_Motion:
245         case ET_ButtonPress:
246         case ET_ButtonRelease:
247         case ET_KeyPress:
248         case ET_KeyRelease:
249             return eventToDeviceEvent(&ev->device_event, xi);
250         case ET_ProximityIn:
251         case ET_ProximityOut:
252             *xi = NULL;
253             return BadMatch;
254         case ET_DeviceChanged:
255             return eventToDeviceChanged(&ev->changed_event, xi);
256         case ET_RawKeyPress:
257         case ET_RawKeyRelease:
258         case ET_RawButtonPress:
259         case ET_RawButtonRelease:
260         case ET_RawMotion:
261             return eventToRawEvent(&ev->raw_event, xi);
262         default:
263             break;
264     }
266     ErrorF("[dix] EventToXI2: Not implemented for %d \n", ev->any.type);
267     return BadImplementation;
270 static int
271 eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count)
273     int num_events;
274     int first; /* dummy */
275     deviceKeyButtonPointer *kbp;
277     /* Sorry, XI 1.x protocol restrictions. */
278     if (ev->detail.button > 0xFF || ev->deviceid >= 0x80)
279     {
280         *count = 0;
281         return Success;
282     }
284     num_events = (countValuators(ev, &first) + 5)/6; /* valuator ev */
285     if (num_events <= 0)
286     {
287         switch (ev->type)
288         {
289             case ET_KeyPress:
290             case ET_KeyRelease:
291             case ET_ButtonPress:
292             case ET_ButtonRelease:
293                 /* no axes is ok */
294                 break;
295             case ET_Motion:
296             case ET_ProximityIn:
297             case ET_ProximityOut:
298                 *count = 0;
299                 return BadMatch;
300             default:
301                 *count = 0;
302                 return BadImplementation;
303         }
304     }
306     num_events++; /* the actual event event */
308     *xi = calloc(num_events, sizeof(xEvent));
309     if (!(*xi))
310     {
311         return BadAlloc;
312     }
314     kbp           = (deviceKeyButtonPointer*)(*xi);
315     kbp->detail   = ev->detail.button;
316     kbp->time     = ev->time;
317     kbp->root     = ev->root;
318     kbp->root_x   = ev->root_x;
319     kbp->root_y   = ev->root_y;
320     kbp->deviceid = ev->deviceid;
321     kbp->state    = ev->corestate;
322     EventSetKeyRepeatFlag((xEvent*)kbp,
323                           (ev->type == ET_KeyPress && ev->key_repeat));
325     if (num_events > 1)
326         kbp->deviceid |= MORE_EVENTS;
328     switch(ev->type)
329     {
330         case ET_Motion:        kbp->type = DeviceMotionNotify;  break;
331         case ET_ButtonPress:   kbp->type = DeviceButtonPress;   break;
332         case ET_ButtonRelease: kbp->type = DeviceButtonRelease; break;
333         case ET_KeyPress:      kbp->type = DeviceKeyPress;      break;
334         case ET_KeyRelease:    kbp->type = DeviceKeyRelease;    break;
335         case ET_ProximityIn:   kbp->type = ProximityIn;         break;
336         case ET_ProximityOut:  kbp->type = ProximityOut;        break;
337         default:
338             break;
339     }
341     if (num_events > 1)
342     {
343         getValuatorEvents(ev, (deviceValuator*)(kbp + 1));
344     }
346     *count = num_events;
347     return Success;
351 /**
352  * Set first to the first valuator in the event ev and return the number of
353  * valuators from first to the last set valuator.
354  */
355 static int
356 countValuators(DeviceEvent *ev, int *first)
358     int first_valuator = -1, last_valuator = -1, num_valuators = 0;
359     int i;
361     for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
362     {
363         if (BitIsOn(ev->valuators.mask, i))
364         {
365             if (first_valuator == -1)
366                 first_valuator = i;
367             last_valuator = i;
368         }
369     }
371     if (first_valuator != -1)
372     {
373         num_valuators = last_valuator - first_valuator + 1;
374         *first = first_valuator;
375     }
377     return num_valuators;
380 static int
381 getValuatorEvents(DeviceEvent *ev, deviceValuator *xv)
383     int i;
384     int state = 0;
385     int first_valuator, num_valuators;
388     num_valuators = countValuators(ev, &first_valuator);
389     if (num_valuators > 0)
390     {
391         DeviceIntPtr dev = NULL;
392         dixLookupDevice(&dev, ev->deviceid, serverClient, DixUseAccess);
393         /* State needs to be assembled BEFORE the device is updated. */
394         state = (dev && dev->key) ? XkbStateFieldFromRec(&dev->key->xkbInfo->state) : 0;
395         state |= (dev && dev->button) ? (dev->button->state) : 0;
396     }
398     for (i = 0; i < num_valuators; i += 6, xv++) {
399         INT32 *valuators = &xv->valuator0; // Treat all 6 vals as an array
400         int j;
402         xv->type = DeviceValuator;
403         xv->first_valuator = first_valuator + i;
404         xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i);
405         xv->deviceid = ev->deviceid;
406         xv->device_state = state;
408         /* Unset valuators in masked valuator events have the proper data values
409          * in the case of an absolute axis in between two set valuators. */
410         for (j = 0; j < xv->num_valuators; j++)
411             valuators[j] = ev->valuators.data[xv->first_valuator + j];
413         if (i + 6 < num_valuators)
414             xv->deviceid |= MORE_EVENTS;
415     }
417     return (num_valuators + 5) / 6;
421 static int
422 appendKeyInfo(DeviceChangedEvent *dce, xXIKeyInfo* info)
424     uint32_t *kc;
425     int i;
427     info->type = XIKeyClass;
428     info->num_keycodes = dce->keys.max_keycode - dce->keys.min_keycode + 1;
429     info->length = sizeof(xXIKeyInfo)/4 + info->num_keycodes;
430     info->sourceid = dce->sourceid;
432     kc = (uint32_t*)&info[1];
433     for (i = 0; i < info->num_keycodes; i++)
434         *kc++ = i + dce->keys.min_keycode;
436     return info->length * 4;
439 static int
440 appendButtonInfo(DeviceChangedEvent *dce, xXIButtonInfo *info)
442     unsigned char *bits;
443     int mask_len;
445     mask_len = bytes_to_int32(bits_to_bytes(dce->buttons.num_buttons));
447     info->type = XIButtonClass;
448     info->num_buttons = dce->buttons.num_buttons;
449     info->length = bytes_to_int32(sizeof(xXIButtonInfo)) +
450                    info->num_buttons + mask_len;
451     info->sourceid = dce->sourceid;
453     bits = (unsigned char*)&info[1];
454     memset(bits, 0, mask_len * 4);
455     /* FIXME: is_down? */
457     bits += mask_len * 4;
458     memcpy(bits, dce->buttons.names, dce->buttons.num_buttons * sizeof(Atom));
460     return info->length * 4;
463 static int
464 appendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo *info, int axisnumber)
466     info->type = XIValuatorClass;
467     info->length = sizeof(xXIValuatorInfo)/4;
468     info->label = dce->valuators[axisnumber].name;
469     info->min.integral = dce->valuators[axisnumber].min;
470     info->min.frac = 0;
471     info->max.integral = dce->valuators[axisnumber].max;
472     info->max.frac = 0;
473     /* FIXME: value */
474     info->value.integral = 0;
475     info->value.frac = 0;
476     info->resolution = dce->valuators[axisnumber].resolution;
477     info->number = axisnumber;
478     info->mode = dce->valuators[axisnumber].mode;
479     info->sourceid = dce->sourceid;
481     return info->length * 4;
484 static int
485 eventToDeviceChanged(DeviceChangedEvent *dce, xEvent **xi)
487     xXIDeviceChangedEvent *dcce;
488     int len = sizeof(xXIDeviceChangedEvent);
489     int nkeys;
490     char *ptr;
492     if (dce->buttons.num_buttons)
493     {
494         len += sizeof(xXIButtonInfo);
495         len += dce->buttons.num_buttons * sizeof(Atom); /* button names */
496         len += pad_to_int32(bits_to_bytes(dce->buttons.num_buttons));
497     }
498     if (dce->num_valuators)
499         len += sizeof(xXIValuatorInfo) * dce->num_valuators;
501     nkeys = (dce->keys.max_keycode > 0) ?
502                 dce->keys.max_keycode - dce->keys.min_keycode + 1 : 0;
503     if (nkeys > 0)
504     {
505         len += sizeof(xXIKeyInfo);
506         len += sizeof(CARD32) * nkeys; /* keycodes */
507     }
509     dcce = calloc(1, len);
510     if (!dcce)
511     {
512         ErrorF("[Xi] BadAlloc in SendDeviceChangedEvent.\n");
513         return BadAlloc;
514     }
516     dcce->type         = GenericEvent;
517     dcce->extension    = IReqCode;
518     dcce->evtype       = XI_DeviceChanged;
519     dcce->time         = dce->time;
520     dcce->deviceid     = dce->deviceid;
521     dcce->sourceid     = dce->sourceid;
522     dcce->reason       = (dce->flags & DEVCHANGE_DEVICE_CHANGE) ? XIDeviceChange : XISlaveSwitch;
523     dcce->num_classes  = 0;
524     dcce->length = bytes_to_int32(len - sizeof(xEvent));
526     ptr = (char*)&dcce[1];
527     if (dce->buttons.num_buttons)
528     {
529         dcce->num_classes++;
530         ptr += appendButtonInfo(dce, (xXIButtonInfo*)ptr);
531     }
533     if (nkeys)
534     {
535         dcce->num_classes++;
536         ptr += appendKeyInfo(dce, (xXIKeyInfo*)ptr);
537     }
539     if (dce->num_valuators)
540     {
541         int i;
543         dcce->num_classes += dce->num_valuators;
544         for (i = 0; i < dce->num_valuators; i++)
545             ptr += appendValuatorInfo(dce, (xXIValuatorInfo*)ptr, i);
546     }
548     *xi = (xEvent*)dcce;
550     return Success;
553 static int count_bits(unsigned char* ptr, int len)
555     int bits = 0;
556     unsigned int i;
557     unsigned char x;
559     for (i = 0; i < len; i++)
560     {
561         x = ptr[i];
562         while(x > 0)
563         {
564             bits += (x & 0x1);
565             x >>= 1;
566         }
567     }
568     return bits;
571 static int
572 eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
574     int len = sizeof(xXIDeviceEvent);
575     xXIDeviceEvent *xde;
576     int i, btlen, vallen;
577     char *ptr;
578     FP3232 *axisval;
580     /* FIXME: this should just send the buttons we have, not MAX_BUTTONs. Same
581      * with MAX_VALUATORS below */
582     /* btlen is in 4 byte units */
583     btlen = bytes_to_int32(bits_to_bytes(MAX_BUTTONS));
584     len += btlen * 4; /* buttonmask len */
587     vallen = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask)/sizeof(ev->valuators.mask[0]));
588     len += vallen * 2 * sizeof(uint32_t); /* axisvalues */
589     vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS));
590     len += vallen * 4; /* valuators mask */
592     *xi = calloc(1, len);
593     xde = (xXIDeviceEvent*)*xi;
594     xde->type           = GenericEvent;
595     xde->extension      = IReqCode;
596     xde->evtype         = GetXI2Type((InternalEvent*)ev);
597     xde->time           = ev->time;
598     xde->length         = bytes_to_int32(len - sizeof(xEvent));
599     xde->detail         = ev->detail.button;
600     xde->root           = ev->root;
601     xde->buttons_len    = btlen;
602     xde->valuators_len  = vallen;
603     xde->deviceid       = ev->deviceid;
604     xde->sourceid       = ev->sourceid;
605     xde->root_x         = FP1616(ev->root_x, ev->root_x_frac);
606     xde->root_y         = FP1616(ev->root_y, ev->root_y_frac);
608     if (ev->key_repeat)
609         xde->flags      |= XIKeyRepeat;
611     xde->mods.base_mods         = ev->mods.base;
612     xde->mods.latched_mods      = ev->mods.latched;
613     xde->mods.locked_mods       = ev->mods.locked;
614     xde->mods.effective_mods    = ev->mods.effective;
616     xde->group.base_group       = ev->group.base;
617     xde->group.latched_group    = ev->group.latched;
618     xde->group.locked_group     = ev->group.locked;
619     xde->group.effective_group  = ev->group.effective;
621     ptr = (char*)&xde[1];
622     for (i = 0; i < sizeof(ev->buttons) * 8; i++)
623     {
624         if (BitIsOn(ev->buttons, i))
625             SetBit(ptr, i);
626     }
628     ptr += xde->buttons_len * 4;
629     axisval = (FP3232*)(ptr + xde->valuators_len * 4);
630     for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
631     {
632         if (BitIsOn(ev->valuators.mask, i))
633         {
634             SetBit(ptr, i);
635             axisval->integral = ev->valuators.data[i];
636             axisval->frac = ev->valuators.data_frac[i];
637             axisval++;
638         }
639     }
641     return Success;
644 static int
645 eventToRawEvent(RawDeviceEvent *ev, xEvent **xi)
647     xXIRawEvent* raw;
648     int vallen, nvals;
649     int i, len = sizeof(xXIRawEvent);
650     char *ptr;
651     FP3232 *axisval;
653     nvals = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask));
654     len += nvals * sizeof(FP3232) * 2; /* 8 byte per valuator, once
655                                     raw, once processed */
656     vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS));
657     len += vallen * 4; /* valuators mask */
659     *xi = calloc(1, len);
660     raw = (xXIRawEvent*)*xi;
661     raw->type           = GenericEvent;
662     raw->extension      = IReqCode;
663     raw->evtype         = GetXI2Type((InternalEvent*)ev);
664     raw->time           = ev->time;
665     raw->length         = bytes_to_int32(len - sizeof(xEvent));
666     raw->detail         = ev->detail.button;
667     raw->deviceid       = ev->deviceid;
668     raw->valuators_len  = vallen;
670     ptr = (char*)&raw[1];
671     axisval = (FP3232*)(ptr + raw->valuators_len * 4);
672     for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
673     {
674         if (BitIsOn(ev->valuators.mask, i))
675         {
676             SetBit(ptr, i);
677             axisval->integral = ev->valuators.data[i];
678             axisval->frac = ev->valuators.data_frac[i];
679             (axisval + nvals)->integral = ev->valuators.data_raw[i];
680             (axisval + nvals)->frac = ev->valuators.data_raw_frac[i];
681             axisval++;
682         }
683     }
685     return Success;
688 /**
689  * Return the corresponding core type for the given event or 0 if no core
690  * equivalent exists.
691  */
692 int
693 GetCoreType(InternalEvent *event)
695     int coretype = 0;
696     switch(event->any.type)
697     {
698         case ET_Motion:         coretype = MotionNotify;  break;
699         case ET_ButtonPress:    coretype = ButtonPress;   break;
700         case ET_ButtonRelease:  coretype = ButtonRelease; break;
701         case ET_KeyPress:       coretype = KeyPress;      break;
702         case ET_KeyRelease:     coretype = KeyRelease;    break;
703         default:
704             break;
705     }
706     return coretype;
709 /**
710  * Return the corresponding XI 1.x type for the given event or 0 if no
711  * equivalent exists.
712  */
713 int
714 GetXIType(InternalEvent *event)
716     int xitype = 0;
717     switch(event->any.type)
718     {
719         case ET_Motion:         xitype = DeviceMotionNotify;  break;
720         case ET_ButtonPress:    xitype = DeviceButtonPress;   break;
721         case ET_ButtonRelease:  xitype = DeviceButtonRelease; break;
722         case ET_KeyPress:       xitype = DeviceKeyPress;      break;
723         case ET_KeyRelease:     xitype = DeviceKeyRelease;    break;
724         case ET_ProximityIn:    xitype = ProximityIn;         break;
725         case ET_ProximityOut:   xitype = ProximityOut;        break;
726         default:
727             break;
728     }
729     return xitype;
732 /**
733  * Return the corresponding XI 2.x type for the given event or 0 if no
734  * equivalent exists.
735  */
736 int
737 GetXI2Type(InternalEvent *event)
739     int xi2type = 0;
741     switch(event->any.type)
742     {
743         case ET_Motion:         xi2type = XI_Motion;           break;
744         case ET_ButtonPress:    xi2type = XI_ButtonPress;      break;
745         case ET_ButtonRelease:  xi2type = XI_ButtonRelease;    break;
746         case ET_KeyPress:       xi2type = XI_KeyPress;         break;
747         case ET_KeyRelease:     xi2type = XI_KeyRelease;       break;
748         case ET_Enter:          xi2type = XI_Enter;            break;
749         case ET_Leave:          xi2type = XI_Leave;            break;
750         case ET_Hierarchy:      xi2type = XI_HierarchyChanged; break;
751         case ET_DeviceChanged:  xi2type = XI_DeviceChanged;    break;
752         case ET_RawKeyPress:    xi2type = XI_RawKeyPress;      break;
753         case ET_RawKeyRelease:  xi2type = XI_RawKeyRelease;    break;
754         case ET_RawButtonPress: xi2type = XI_RawButtonPress;   break;
755         case ET_RawButtonRelease: xi2type = XI_RawButtonRelease; break;
756         case ET_RawMotion:      xi2type = XI_RawMotion;        break;
757         case ET_FocusIn:        xi2type = XI_FocusIn;          break;
758         case ET_FocusOut:       xi2type = XI_FocusOut;         break;
759         default:
760             break;
761     }
762     return xi2type;