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