getfctl.c revision 706f2543
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 *  Get feedback control attributes for an extension device.
50 *
51 */
52
53#ifdef HAVE_DIX_CONFIG_H
54#include <dix-config.h>
55#endif
56
57#include "inputstr.h"	/* DeviceIntPtr      */
58#include <X11/extensions/XI.h>
59#include <X11/extensions/XIproto.h>
60#include "exglobals.h"
61
62#include "getfctl.h"
63
64/***********************************************************************
65 *
66 * This procedure gets the control attributes for an extension device,
67 * for clients on machines with a different byte ordering than the server.
68 *
69 */
70
71int
72SProcXGetFeedbackControl(ClientPtr client)
73{
74    char n;
75
76    REQUEST(xGetFeedbackControlReq);
77    swaps(&stuff->length, n);
78    return (ProcXGetFeedbackControl(client));
79}
80
81/***********************************************************************
82 *
83 * This procedure copies KbdFeedbackClass data, swapping if necessary.
84 *
85 */
86
87static void
88CopySwapKbdFeedback(ClientPtr client, KbdFeedbackPtr k, char **buf)
89{
90    int i;
91    char n;
92    xKbdFeedbackState *k2;
93
94    k2 = (xKbdFeedbackState *) * buf;
95    k2->class = KbdFeedbackClass;
96    k2->length = sizeof(xKbdFeedbackState);
97    k2->id = k->ctrl.id;
98    k2->click = k->ctrl.click;
99    k2->percent = k->ctrl.bell;
100    k2->pitch = k->ctrl.bell_pitch;
101    k2->duration = k->ctrl.bell_duration;
102    k2->led_mask = k->ctrl.leds;
103    k2->global_auto_repeat = k->ctrl.autoRepeat;
104    for (i = 0; i < 32; i++)
105	k2->auto_repeats[i] = k->ctrl.autoRepeats[i];
106    if (client->swapped) {
107	swaps(&k2->length, n);
108	swaps(&k2->pitch, n);
109	swaps(&k2->duration, n);
110	swapl(&k2->led_mask, n);
111	swapl(&k2->led_values, n);
112    }
113    *buf += sizeof(xKbdFeedbackState);
114}
115
116/***********************************************************************
117 *
118 * This procedure copies PtrFeedbackClass data, swapping if necessary.
119 *
120 */
121
122static void
123CopySwapPtrFeedback(ClientPtr client, PtrFeedbackPtr p, char **buf)
124{
125    char n;
126    xPtrFeedbackState *p2;
127
128    p2 = (xPtrFeedbackState *) * buf;
129    p2->class = PtrFeedbackClass;
130    p2->length = sizeof(xPtrFeedbackState);
131    p2->id = p->ctrl.id;
132    p2->accelNum = p->ctrl.num;
133    p2->accelDenom = p->ctrl.den;
134    p2->threshold = p->ctrl.threshold;
135    if (client->swapped) {
136	swaps(&p2->length, n);
137	swaps(&p2->accelNum, n);
138	swaps(&p2->accelDenom, n);
139	swaps(&p2->threshold, n);
140    }
141    *buf += sizeof(xPtrFeedbackState);
142}
143
144/***********************************************************************
145 *
146 * This procedure copies IntegerFeedbackClass data, swapping if necessary.
147 *
148 */
149
150static void
151CopySwapIntegerFeedback(ClientPtr client, IntegerFeedbackPtr i, char **buf)
152{
153    char n;
154    xIntegerFeedbackState *i2;
155
156    i2 = (xIntegerFeedbackState *) * buf;
157    i2->class = IntegerFeedbackClass;
158    i2->length = sizeof(xIntegerFeedbackState);
159    i2->id = i->ctrl.id;
160    i2->resolution = i->ctrl.resolution;
161    i2->min_value = i->ctrl.min_value;
162    i2->max_value = i->ctrl.max_value;
163    if (client->swapped) {
164	swaps(&i2->length, n);
165	swapl(&i2->resolution, n);
166	swapl(&i2->min_value, n);
167	swapl(&i2->max_value, n);
168    }
169    *buf += sizeof(xIntegerFeedbackState);
170}
171
172/***********************************************************************
173 *
174 * This procedure copies StringFeedbackClass data, swapping if necessary.
175 *
176 */
177
178static void
179CopySwapStringFeedback(ClientPtr client, StringFeedbackPtr s, char **buf)
180{
181    int i;
182    char n;
183    xStringFeedbackState *s2;
184    KeySym *kptr;
185
186    s2 = (xStringFeedbackState *) * buf;
187    s2->class = StringFeedbackClass;
188    s2->length = sizeof(xStringFeedbackState) +
189	s->ctrl.num_symbols_supported * sizeof(KeySym);
190    s2->id = s->ctrl.id;
191    s2->max_symbols = s->ctrl.max_symbols;
192    s2->num_syms_supported = s->ctrl.num_symbols_supported;
193    *buf += sizeof(xStringFeedbackState);
194    kptr = (KeySym *) (*buf);
195    for (i = 0; i < s->ctrl.num_symbols_supported; i++)
196	*kptr++ = *(s->ctrl.symbols_supported + i);
197    if (client->swapped) {
198	swaps(&s2->length, n);
199	swaps(&s2->max_symbols, n);
200	swaps(&s2->num_syms_supported, n);
201	kptr = (KeySym *) (*buf);
202	for (i = 0; i < s->ctrl.num_symbols_supported; i++, kptr++) {
203	    swapl(kptr, n);
204	}
205    }
206    *buf += (s->ctrl.num_symbols_supported * sizeof(KeySym));
207}
208
209/***********************************************************************
210 *
211 * This procedure copies LedFeedbackClass data, swapping if necessary.
212 *
213 */
214
215static void
216CopySwapLedFeedback(ClientPtr client, LedFeedbackPtr l, char **buf)
217{
218    char n;
219    xLedFeedbackState *l2;
220
221    l2 = (xLedFeedbackState *) * buf;
222    l2->class = LedFeedbackClass;
223    l2->length = sizeof(xLedFeedbackState);
224    l2->id = l->ctrl.id;
225    l2->led_values = l->ctrl.led_values;
226    l2->led_mask = l->ctrl.led_mask;
227    if (client->swapped) {
228	swaps(&l2->length, n);
229	swapl(&l2->led_values, n);
230	swapl(&l2->led_mask, n);
231    }
232    *buf += sizeof(xLedFeedbackState);
233}
234
235/***********************************************************************
236 *
237 * This procedure copies BellFeedbackClass data, swapping if necessary.
238 *
239 */
240
241static void
242CopySwapBellFeedback(ClientPtr client, BellFeedbackPtr b, char **buf)
243{
244    char n;
245    xBellFeedbackState *b2;
246
247    b2 = (xBellFeedbackState *) * buf;
248    b2->class = BellFeedbackClass;
249    b2->length = sizeof(xBellFeedbackState);
250    b2->id = b->ctrl.id;
251    b2->percent = b->ctrl.percent;
252    b2->pitch = b->ctrl.pitch;
253    b2->duration = b->ctrl.duration;
254    if (client->swapped) {
255	swaps(&b2->length, n);
256	swaps(&b2->pitch, n);
257	swaps(&b2->duration, n);
258    }
259    *buf += sizeof(xBellFeedbackState);
260}
261
262/***********************************************************************
263 *
264 * This procedure writes the reply for the xGetFeedbackControl function,
265 * if the client and server have a different byte ordering.
266 *
267 */
268
269void
270SRepXGetFeedbackControl(ClientPtr client, int size,
271			xGetFeedbackControlReply * rep)
272{
273    char n;
274
275    swaps(&rep->sequenceNumber, n);
276    swapl(&rep->length, n);
277    swaps(&rep->num_feedbacks, n);
278    WriteToClient(client, size, (char *)rep);
279}
280
281/***********************************************************************
282 *
283 * Get the feedback control state.
284 *
285 */
286
287int
288ProcXGetFeedbackControl(ClientPtr client)
289{
290    int rc, total_length = 0;
291    char *buf, *savbuf;
292    DeviceIntPtr dev;
293    KbdFeedbackPtr k;
294    PtrFeedbackPtr p;
295    IntegerFeedbackPtr i;
296    StringFeedbackPtr s;
297    BellFeedbackPtr b;
298    LedFeedbackPtr l;
299    xGetFeedbackControlReply rep;
300
301    REQUEST(xGetFeedbackControlReq);
302    REQUEST_SIZE_MATCH(xGetFeedbackControlReq);
303
304    rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
305    if (rc != Success)
306	return rc;
307
308    rep.repType = X_Reply;
309    rep.RepType = X_GetFeedbackControl;
310    rep.length = 0;
311    rep.sequenceNumber = client->sequence;
312    rep.num_feedbacks = 0;
313
314    for (k = dev->kbdfeed; k; k = k->next) {
315	rep.num_feedbacks++;
316	total_length += sizeof(xKbdFeedbackState);
317    }
318    for (p = dev->ptrfeed; p; p = p->next) {
319	rep.num_feedbacks++;
320	total_length += sizeof(xPtrFeedbackState);
321    }
322    for (s = dev->stringfeed; s; s = s->next) {
323	rep.num_feedbacks++;
324	total_length += sizeof(xStringFeedbackState) +
325	    (s->ctrl.num_symbols_supported * sizeof(KeySym));
326    }
327    for (i = dev->intfeed; i; i = i->next) {
328	rep.num_feedbacks++;
329	total_length += sizeof(xIntegerFeedbackState);
330    }
331    for (l = dev->leds; l; l = l->next) {
332	rep.num_feedbacks++;
333	total_length += sizeof(xLedFeedbackState);
334    }
335    for (b = dev->bell; b; b = b->next) {
336	rep.num_feedbacks++;
337	total_length += sizeof(xBellFeedbackState);
338    }
339
340    if (total_length == 0)
341	return BadMatch;
342
343    buf = (char *)malloc(total_length);
344    if (!buf)
345	return BadAlloc;
346    savbuf = buf;
347
348    for (k = dev->kbdfeed; k; k = k->next)
349	CopySwapKbdFeedback(client, k, &buf);
350    for (p = dev->ptrfeed; p; p = p->next)
351	CopySwapPtrFeedback(client, p, &buf);
352    for (s = dev->stringfeed; s; s = s->next)
353	CopySwapStringFeedback(client, s, &buf);
354    for (i = dev->intfeed; i; i = i->next)
355	CopySwapIntegerFeedback(client, i, &buf);
356    for (l = dev->leds; l; l = l->next)
357	CopySwapLedFeedback(client, l, &buf);
358    for (b = dev->bell; b; b = b->next)
359	CopySwapBellFeedback(client, b, &buf);
360
361    rep.length = bytes_to_int32(total_length);
362    WriteReplyToClient(client, sizeof(xGetFeedbackControlReply), &rep);
363    WriteToClient(client, total_length, savbuf);
364    free(savbuf);
365    return Success;
366}
367