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