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