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#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}
488