Add penmount touchscreen configuration file
[profile/ivi/xorg-x11-server.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  */
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
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);
58
59 /* Do not use, read comments below */
60 BOOL 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  */
70 static void
71 EventSetKeyRepeatFlag(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  */
81 BOOL
82 EventIsKeyRepeat(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  */
99 int
100 EventToCore(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  */
168 int
169 EventToXI(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  */
212 int
213 EventToXI2(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
249 static int
250 eventToKeyButtonPointer(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  */
313 static int
314 countValuators(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
338 static int
339 getValuatorEvents(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
386 static int
387 appendKeyInfo(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
404 static int
405 appendButtonInfo(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
428 static int
429 appendValuatorInfo(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
449 static int
450 eventToDeviceChanged(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
518 static 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
536 static int
537 eventToDeviceEvent(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
609 static int
610 eventToRawEvent(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  */
657 int
658 GetCoreType(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  */
678 int
679 GetXIType(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  */
701 int
702 GetXI2Type(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 }