Imported Upstream version 1.7.2
[platform/upstream/libXi.git] / src / XExtToWire.c
1 /************************************************************
2
3 Copyright 1989, 1998  The Open Group
4
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
24
25 Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
26
27                         All Rights Reserved
28
29 Permission to use, copy, modify, and distribute this software and its
30 documentation for any purpose and without fee is hereby granted,
31 provided that the above copyright notice appear in all copies and that
32 both that copyright notice and this permission notice appear in
33 supporting documentation, and that the name of Hewlett-Packard not be
34 used in advertising or publicity pertaining to distribution of the
35 software without specific, written prior permission.
36
37 HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
38 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
39 HEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
40 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
41 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
42 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
43 SOFTWARE.
44
45 ********************************************************/
46
47 /****************************************************************
48  *
49  *      XExtToWire.c - reformat an XEvent into a wire event.
50  */
51
52 #ifdef HAVE_CONFIG_H
53 #include <config.h>
54 #endif
55
56 #include <X11/extensions/XIproto.h>
57 #include <X11/Xlibint.h>
58 #include <X11/extensions/XInput.h>
59 #include <X11/extensions/extutil.h>
60 #include <X11/extensions/Xge.h>
61 #include <X11/extensions/geproto.h>
62 #include "XIint.h"
63
64 _X_HIDDEN Status
65 _XiEventToWire(
66     register Display     *dpy,          /* pointer to display structure */
67     register XEvent      *re,           /* pointer to client event */
68     register xEvent     **event,        /* wire protocol event */
69     register int         *count)
70 {
71     XExtDisplayInfo *info = XInput_find_display(dpy);
72     int i;
73
74     if ((re->type & 0x7f) != GenericEvent) {
75         switch ((re->type & 0x7f) - info->codes->first_event) {
76             case XI_DeviceKeyPress:
77             case XI_DeviceKeyRelease:
78                 {
79                     register XDeviceKeyEvent *ev = (XDeviceKeyEvent *) re;
80                     register deviceKeyButtonPointer *kev;
81                     register deviceValuator *vev;
82
83                     *count = 2;
84                     kev = (deviceKeyButtonPointer *) Xmalloc(*count * sizeof(xEvent));
85                     if (!kev)
86                         return (_XUnknownNativeEvent(dpy, re, *event));
87                     *event = (xEvent *) kev;
88
89                     kev->type = ev->type;
90                     kev->root = ev->root;
91                     kev->event = ev->window;
92                     kev->child = ev->subwindow;
93                     kev->time = ev->time;
94                     kev->event_x = ev->x;
95                     kev->event_y = ev->y;
96                     kev->root_x = ev->x_root;
97                     kev->root_y = ev->y_root;
98                     kev->state = ev->state;
99                     kev->same_screen = ev->same_screen;
100                     kev->detail = ev->keycode;
101                     kev->deviceid = ev->deviceid | MORE_EVENTS;
102
103                     vev = (deviceValuator *)++ kev;
104                     vev->type = info->codes->first_event + XI_DeviceValuator;
105                     vev->deviceid = ev->deviceid;
106                     vev->device_state = ev->device_state;
107                     vev->first_valuator = ev->first_axis;
108                     vev->num_valuators = ev->axes_count;
109                     i = vev->num_valuators;
110                     if (i > 6)
111                         i = 6;
112                     switch (i) {
113                         case 6:
114                             vev->valuator5 = ev->axis_data[5];
115                         case 5:
116                             vev->valuator4 = ev->axis_data[4];
117                         case 4:
118                             vev->valuator3 = ev->axis_data[3];
119                         case 3:
120                             vev->valuator2 = ev->axis_data[2];
121                         case 2:
122                             vev->valuator1 = ev->axis_data[1];
123                         case 1:
124                             vev->valuator0 = ev->axis_data[0];
125                     }
126                     break;
127                 }
128             case XI_ProximityIn:
129             case XI_ProximityOut:
130                 {
131                     register XProximityNotifyEvent *ev = (XProximityNotifyEvent *) re;
132                     register deviceKeyButtonPointer *pev;
133                     register deviceValuator *vev;
134
135                     *count = 2;
136                     pev = (deviceKeyButtonPointer *) Xmalloc(*count * sizeof(xEvent));
137                     if (!pev)
138                         return (_XUnknownNativeEvent(dpy, re, *event));
139                     *event = (xEvent *) pev;
140
141                     pev->type = ev->type;
142                     pev->root = ev->root;
143                     pev->event = ev->window;
144                     pev->child = ev->subwindow;
145                     pev->time = ev->time;
146                     pev->event_x = ev->x;
147                     pev->event_y = ev->y;
148                     pev->root_x = ev->x_root;
149                     pev->root_y = ev->y_root;
150                     pev->state = ev->state;
151                     pev->same_screen = ev->same_screen;
152                     pev->deviceid = ev->deviceid | MORE_EVENTS;
153
154                     vev = (deviceValuator *)++ pev;
155                     vev->type = info->codes->first_event + XI_DeviceValuator;
156                     vev->deviceid = ev->deviceid;
157                     vev->device_state = ev->device_state;
158                     vev->first_valuator = ev->first_axis;
159                     vev->num_valuators = ev->axes_count;
160
161                     i = vev->num_valuators;
162                     if (i > 6)
163                         i = 6;
164                     switch (i) {
165                         case 6:
166                             vev->valuator5 = ev->axis_data[5];
167                         case 5:
168                             vev->valuator4 = ev->axis_data[4];
169                         case 4:
170                             vev->valuator3 = ev->axis_data[3];
171                         case 3:
172                             vev->valuator2 = ev->axis_data[2];
173                         case 2:
174                             vev->valuator1 = ev->axis_data[1];
175                         case 1:
176                             vev->valuator0 = ev->axis_data[0];
177                     }
178                     break;
179                 }
180             case XI_DeviceButtonPress:
181             case XI_DeviceButtonRelease:
182                 {
183                     register XDeviceButtonEvent *ev = (XDeviceButtonEvent *) re;
184                     register deviceKeyButtonPointer *bev;
185                     register deviceValuator *vev;
186
187                     *count = 2;
188                     bev = (deviceKeyButtonPointer *) Xmalloc(*count * sizeof(xEvent));
189                     if (!bev)
190                         return (_XUnknownNativeEvent(dpy, re, *event));
191                     *event = (xEvent *) bev;
192
193                     bev->type = ev->type;
194                     bev->root = ev->root;
195                     bev->event = ev->window;
196                     bev->child = ev->subwindow;
197                     bev->time = ev->time;
198                     bev->event_x = ev->x;
199                     bev->event_y = ev->y;
200                     bev->root_x = ev->x_root;
201                     bev->root_y = ev->y_root;
202                     bev->state = ev->state;
203                     bev->same_screen = ev->same_screen;
204                     bev->detail = ev->button;
205                     bev->deviceid = ev->deviceid | MORE_EVENTS;
206
207                     vev = (deviceValuator *)++ bev;
208                     vev->type = info->codes->first_event + XI_DeviceValuator;
209                     vev->deviceid = ev->deviceid;
210                     vev->device_state = ev->device_state;
211                     vev->first_valuator = ev->first_axis;
212                     vev->num_valuators = ev->axes_count;
213
214                     i = vev->num_valuators;
215                     if (i > 6)
216                         i = 6;
217                     switch (i) {
218                         case 6:
219                             vev->valuator5 = ev->axis_data[5];
220                         case 5:
221                             vev->valuator4 = ev->axis_data[4];
222                         case 4:
223                             vev->valuator3 = ev->axis_data[3];
224                         case 3:
225                             vev->valuator2 = ev->axis_data[2];
226                         case 2:
227                             vev->valuator1 = ev->axis_data[1];
228                         case 1:
229                             vev->valuator0 = ev->axis_data[0];
230                     }
231                     break;
232                 }
233             case XI_DeviceMotionNotify:
234                 {
235                     register XDeviceMotionEvent *ev = (XDeviceMotionEvent *) re;
236                     register deviceKeyButtonPointer *mev;
237                     register deviceValuator *vev;
238
239                     *count = 2;
240                     mev = (deviceKeyButtonPointer *) Xmalloc(*count * sizeof(xEvent));
241                     if (!mev)
242                         return (_XUnknownNativeEvent(dpy, re, *event));
243                     *event = (xEvent *) mev;
244
245                     mev->type = ev->type;
246                     mev->root = ev->root;
247                     mev->event = ev->window;
248                     mev->child = ev->subwindow;
249                     mev->time = ev->time;
250                     mev->event_x = ev->x;
251                     mev->event_y = ev->y;
252                     mev->root_x = ev->x_root;
253                     mev->root_y = ev->y_root;
254                     mev->state = ev->state;
255                     mev->same_screen = ev->same_screen;
256                     mev->detail = ev->is_hint;
257                     mev->deviceid = ev->deviceid | MORE_EVENTS;
258
259                     vev = (deviceValuator *)++ mev;
260                     vev->type = info->codes->first_event + XI_DeviceValuator;
261                     vev->deviceid = ev->deviceid;
262                     vev->device_state = ev->device_state;
263                     vev->first_valuator = ev->first_axis;
264                     vev->num_valuators = ev->axes_count;
265
266                     i = vev->num_valuators;
267                     if (i > 6)
268                         i = 6;
269                     switch (i) {
270                         case 6:
271                             vev->valuator5 = ev->axis_data[5];
272                         case 5:
273                             vev->valuator4 = ev->axis_data[4];
274                         case 4:
275                             vev->valuator3 = ev->axis_data[3];
276                         case 3:
277                             vev->valuator2 = ev->axis_data[2];
278                         case 2:
279                             vev->valuator1 = ev->axis_data[1];
280                         case 1:
281                             vev->valuator0 = ev->axis_data[0];
282                     }
283                     break;
284                 }
285             case XI_DeviceFocusIn:
286             case XI_DeviceFocusOut:
287                 {
288                     register XDeviceFocusChangeEvent *ev = (XDeviceFocusChangeEvent *) re;
289                     register deviceFocus *fev;
290
291                     *count = 1;
292                     fev = (deviceFocus *) Xmalloc(*count * sizeof(xEvent));
293                     if (!fev)
294                         return (_XUnknownNativeEvent(dpy, re, *event));
295                     *event = (xEvent *) fev;
296
297                     fev->type = ev->type;
298                     fev->window = ev->window;
299                     fev->mode = ev->mode;
300                     fev->detail = ev->detail;
301                     fev->time = ev->time;
302                     fev->deviceid = ev->deviceid;
303                     break;
304                 }
305             case XI_DeviceMappingNotify:
306                 {
307                     register XDeviceMappingEvent *ev = (XDeviceMappingEvent *) re;
308                     register deviceMappingNotify *mev;
309
310                     *count = 1;
311                     mev = (deviceMappingNotify *) Xmalloc(*count * sizeof(xEvent));
312                     if (!mev)
313                         return (_XUnknownNativeEvent(dpy, re, *event));
314                     *event = (xEvent *) mev;
315
316                     mev->type = ev->type;
317                     mev->firstKeyCode = ev->first_keycode;
318                     mev->request = ev->request;
319                     mev->count = ev->count;
320                     mev->time = ev->time;
321                     mev->deviceid = ev->deviceid;
322                     break;
323                 }
324             case XI_DeviceStateNotify:
325                 {
326                     register XDeviceStateNotifyEvent *ev = (XDeviceStateNotifyEvent *) re;
327                     register deviceStateNotify *sev;
328                     register xEvent *tev;
329                     XInputClass *any = (XInputClass *) & ev->data[0];
330                     unsigned char *sav_id;
331
332                     *count = 1;
333
334                     for (i = 0; i < ev->num_classes; i++) {
335                         if (any->class == KeyClass) {
336                             XKeyStatus *k = (XKeyStatus *) any;
337
338                             if (k->num_keys > 32)
339                                 (*count)++;
340                         } else if (any->class == ButtonClass) {
341                             XButtonStatus *b = (XButtonStatus *) any;
342
343                             if (b->num_buttons > 32)
344                                 (*count)++;
345                         } else if (any->class == ValuatorClass) {
346                             XValuatorStatus *v = (XValuatorStatus *) any;
347
348                             if (v->num_valuators > 3)
349                                 (*count)++;
350                         }
351                         any = (XInputClass *) ((char *)any + any->length);
352                     }
353
354                     sev = (deviceStateNotify *) Xmalloc(*count * sizeof(xEvent));
355                     if (!sev)
356                         return (_XUnknownNativeEvent(dpy, re, *event));
357                     *event = (xEvent *) sev;
358                     tev = (xEvent *) (sev + 1);
359
360                     sev->type = ev->type;
361                     sev->deviceid = ev->deviceid;
362                     sav_id = &(sev->deviceid);
363                     sev->time = ev->time;
364                     sev->classes_reported = 0;
365
366                     any = (XInputClass *) & ev->data[0];
367                     for (i = 0; i < ev->num_classes; i++) {
368                         if (any->class == KeyClass) {
369                             XKeyStatus *k = (XKeyStatus *) any;
370                             register deviceKeyStateNotify *kev;
371
372                             sev->classes_reported |= (1 << KeyClass);
373                             sev->num_keys = k->num_keys;
374                             memcpy((char *)(sev->keys), (char *)(k->keys), 4);
375                             if (k->num_keys > 32) {
376                                 kev = (deviceKeyStateNotify *) tev++;
377                                 kev->type = info->codes->first_event +
378                                     XI_DeviceKeystateNotify;
379                                 kev->deviceid = ev->deviceid;
380                                 *sav_id |= MORE_EVENTS;
381                                 sav_id = &(kev->deviceid);
382                                 memcpy((char *)(kev->keys), (char *)(&k->keys[4]), 28);
383                             }
384                         } else if (any->class == ButtonClass) {
385                             XButtonStatus *b = (XButtonStatus *) any;
386                             register deviceButtonStateNotify *bev;
387
388                             sev->classes_reported |= (1 << ButtonClass);
389                             sev->num_buttons = b->num_buttons;
390                             memcpy((char *)(sev->buttons), (char *)(b->buttons), 4);
391                             if (b->num_buttons > 32) {
392                                 bev = (deviceButtonStateNotify *) tev++;
393                                 bev->type = info->codes->first_event +
394                                     XI_DeviceButtonstateNotify;
395                                 bev->deviceid = ev->deviceid;
396                                 *sav_id |= MORE_EVENTS;
397                                 sav_id = &(bev->deviceid);
398                                 memcpy((char *)(bev->buttons), (char *)(&b->buttons[4]),
399                                         28);
400                             }
401                         } else if (any->class == ValuatorClass) {
402                             XValuatorStatus *val = (XValuatorStatus *) any;
403                             register deviceValuator *vev;
404
405                             sev->classes_reported |= (1 << ValuatorClass);
406                             sev->num_valuators = val->num_valuators < 3 ?
407                                 val->num_valuators : 3;
408                             switch (sev->num_valuators) {
409                                 case 3:
410                                     sev->valuator2 = val->valuators[2];
411                                 case 2:
412                                     sev->valuator1 = val->valuators[1];
413                                 case 1:
414                                     sev->valuator0 = val->valuators[0];
415                             }
416                             if (val->num_valuators > 3) {
417                                 vev = (deviceValuator *) tev++;
418                                 vev->type = info->codes->first_event + XI_DeviceValuator;
419                                 vev->deviceid = ev->deviceid;
420                                 vev->first_valuator = 3;
421                                 vev->num_valuators = val->num_valuators - 3;
422                                 *sav_id |= MORE_EVENTS;
423                                 sav_id = &(vev->deviceid);
424                                 i = val->num_valuators;
425                                 if (i > 6)
426                                     i = 6;
427                                 switch (i) {
428                                     case 6:
429                                         vev->valuator2 = val->valuators[5];
430                                     case 5:
431                                         vev->valuator1 = val->valuators[4];
432                                     case 4:
433                                         vev->valuator0 = val->valuators[3];
434                                 }
435                             }
436                         }
437                         any = (XInputClass *) ((char *)any + any->length);
438                     }
439                     break;
440                 }
441             case XI_ChangeDeviceNotify:
442                 {
443                     register XChangeDeviceNotifyEvent *ev = (XChangeDeviceNotifyEvent *) re;
444                     register changeDeviceNotify *cev;
445
446                     *count = 1;
447                     cev = (changeDeviceNotify *) Xmalloc(*count * sizeof(xEvent));
448                     if (!cev)
449                         return (_XUnknownNativeEvent(dpy, re, *event));
450                     *event = (xEvent *) cev;
451
452                     cev->type = ev->type;
453                     cev->request = ev->request;
454                     cev->time = ev->time;
455                     cev->deviceid = ev->deviceid;
456                     break;
457                 }
458             default:
459                 return (_XUnknownNativeEvent(dpy, re, *event));
460         } /* switch */
461     } else /* if type != GenericEvent */
462     {
463 #if 0
464         switch (((XGenericEvent*)re)->evtype)
465         {
466             case XI_HierarchyChangedNotify:
467                 {
468                     XDeviceHierarchyChangedEvent *ev =
469                         (XDeviceHierarchyChangedEvent*)re;
470                     XIDeviceHierarchyEvent *dhcev;
471                     *count = 1;
472                     dhcev = (XIDeviceHierarchyEvent *)Xmalloc(*count * sizeof(xEvent));
473                     if (!dhcev)
474                         return (_XUnknownNativeEvent(dpy, re, *event));
475
476                     *event = (xEvent *) dhcev;
477                     dhcev->type = ev->type;
478                     dhcev->time = ev->time;
479                     break;
480                 }
481             default:
482                 return (_XUnknownNativeEvent(dpy, re, *event));
483         }
484 #endif
485     }
486     return (1);
487 }