1706f2543Smrg/************************************************************
2706f2543Smrg
3706f2543SmrgCopyright 1989, 1998  The Open Group
4706f2543Smrg
5706f2543SmrgPermission to use, copy, modify, distribute, and sell this software and its
6706f2543Smrgdocumentation for any purpose is hereby granted without fee, provided that
7706f2543Smrgthe above copyright notice appear in all copies and that both that
8706f2543Smrgcopyright notice and this permission notice appear in supporting
9706f2543Smrgdocumentation.
10706f2543Smrg
11706f2543SmrgThe above copyright notice and this permission notice shall be included in
12706f2543Smrgall copies or substantial portions of the Software.
13706f2543Smrg
14706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15706f2543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16706f2543SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17706f2543SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18706f2543SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19706f2543SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20706f2543Smrg
21706f2543SmrgExcept as contained in this notice, the name of The Open Group shall not be
22706f2543Smrgused in advertising or otherwise to promote the sale, use or other dealings
23706f2543Smrgin this Software without prior written authorization from The Open Group.
24706f2543Smrg
25706f2543SmrgCopyright 1989 by Hewlett-Packard Company, Palo Alto, California.
26706f2543Smrg
27706f2543Smrg			All Rights Reserved
28706f2543Smrg
29706f2543SmrgPermission to use, copy, modify, and distribute this software and its
30706f2543Smrgdocumentation for any purpose and without fee is hereby granted,
31706f2543Smrgprovided that the above copyright notice appear in all copies and that
32706f2543Smrgboth that copyright notice and this permission notice appear in
33706f2543Smrgsupporting documentation, and that the name of Hewlett-Packard not be
34706f2543Smrgused in advertising or publicity pertaining to distribution of the
35706f2543Smrgsoftware without specific, written prior permission.
36706f2543Smrg
37706f2543SmrgHEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
38706f2543SmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
39706f2543SmrgHEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
40706f2543SmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
41706f2543SmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
42706f2543SmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
43706f2543SmrgSOFTWARE.
44706f2543Smrg
45706f2543Smrg********************************************************/
46706f2543Smrg
47706f2543Smrg/********************************************************************
48706f2543Smrg *
49706f2543Smrg *  Change feedback control attributes for an extension device.
50706f2543Smrg *
51706f2543Smrg */
52706f2543Smrg
53706f2543Smrg#ifdef HAVE_DIX_CONFIG_H
54706f2543Smrg#include <dix-config.h>
55706f2543Smrg#endif
56706f2543Smrg
57706f2543Smrg#include "inputstr.h"	/* DeviceIntPtr      */
58706f2543Smrg#include <X11/extensions/XI.h>
59706f2543Smrg#include <X11/extensions/XIproto.h>	/* control constants */
60706f2543Smrg
61706f2543Smrg#include "exglobals.h"
62706f2543Smrg
63706f2543Smrg#include "chgfctl.h"
64706f2543Smrg
65706f2543Smrg#define DO_ALL    (-1)
66706f2543Smrg
67706f2543Smrg/***********************************************************************
68706f2543Smrg *
69706f2543Smrg * This procedure changes the control attributes for an extension device,
70706f2543Smrg * for clients on machines with a different byte ordering than the server.
71706f2543Smrg *
72706f2543Smrg */
73706f2543Smrg
74706f2543Smrgint
75706f2543SmrgSProcXChangeFeedbackControl(ClientPtr client)
76706f2543Smrg{
77706f2543Smrg    char n;
78706f2543Smrg
79706f2543Smrg    REQUEST(xChangeFeedbackControlReq);
80706f2543Smrg    swaps(&stuff->length, n);
81706f2543Smrg    REQUEST_AT_LEAST_SIZE(xChangeFeedbackControlReq);
82706f2543Smrg    swapl(&stuff->mask, n);
83706f2543Smrg    return (ProcXChangeFeedbackControl(client));
84706f2543Smrg}
85706f2543Smrg
86706f2543Smrg/******************************************************************************
87706f2543Smrg *
88706f2543Smrg * This procedure changes KbdFeedbackClass data.
89706f2543Smrg *
90706f2543Smrg */
91706f2543Smrg
92706f2543Smrgstatic int
93706f2543SmrgChangeKbdFeedback(ClientPtr client, DeviceIntPtr dev, long unsigned int mask,
94706f2543Smrg		  KbdFeedbackPtr k, xKbdFeedbackCtl * f)
95706f2543Smrg{
96706f2543Smrg    char n;
97706f2543Smrg    KeybdCtrl kctrl;
98706f2543Smrg    int t;
99706f2543Smrg    int key = DO_ALL;
100706f2543Smrg
101706f2543Smrg    if (client->swapped) {
102706f2543Smrg	swaps(&f->length, n);
103706f2543Smrg	swaps(&f->pitch, n);
104706f2543Smrg	swaps(&f->duration, n);
105706f2543Smrg	swapl(&f->led_mask, n);
106706f2543Smrg	swapl(&f->led_values, n);
107706f2543Smrg    }
108706f2543Smrg
109706f2543Smrg    kctrl = k->ctrl;
110706f2543Smrg    if (mask & DvKeyClickPercent) {
111706f2543Smrg	t = f->click;
112706f2543Smrg	if (t == -1)
113706f2543Smrg	    t = defaultKeyboardControl.click;
114706f2543Smrg	else if (t < 0 || t > 100) {
115706f2543Smrg	    client->errorValue = t;
116706f2543Smrg	    return BadValue;
117706f2543Smrg	}
118706f2543Smrg	kctrl.click = t;
119706f2543Smrg    }
120706f2543Smrg
121706f2543Smrg    if (mask & DvPercent) {
122706f2543Smrg	t = f->percent;
123706f2543Smrg	if (t == -1)
124706f2543Smrg	    t = defaultKeyboardControl.bell;
125706f2543Smrg	else if (t < 0 || t > 100) {
126706f2543Smrg	    client->errorValue = t;
127706f2543Smrg	    return BadValue;
128706f2543Smrg	}
129706f2543Smrg	kctrl.bell = t;
130706f2543Smrg    }
131706f2543Smrg
132706f2543Smrg    if (mask & DvPitch) {
133706f2543Smrg	t = f->pitch;
134706f2543Smrg	if (t == -1)
135706f2543Smrg	    t = defaultKeyboardControl.bell_pitch;
136706f2543Smrg	else if (t < 0) {
137706f2543Smrg	    client->errorValue = t;
138706f2543Smrg	    return BadValue;
139706f2543Smrg	}
140706f2543Smrg	kctrl.bell_pitch = t;
141706f2543Smrg    }
142706f2543Smrg
143706f2543Smrg    if (mask & DvDuration) {
144706f2543Smrg	t = f->duration;
145706f2543Smrg	if (t == -1)
146706f2543Smrg	    t = defaultKeyboardControl.bell_duration;
147706f2543Smrg	else if (t < 0) {
148706f2543Smrg	    client->errorValue = t;
149706f2543Smrg	    return BadValue;
150706f2543Smrg	}
151706f2543Smrg	kctrl.bell_duration = t;
152706f2543Smrg    }
153706f2543Smrg
154706f2543Smrg    if (mask & DvLed) {
155706f2543Smrg	kctrl.leds &= ~(f->led_mask);
156706f2543Smrg	kctrl.leds |= (f->led_mask & f->led_values);
157706f2543Smrg    }
158706f2543Smrg
159706f2543Smrg    if (mask & DvKey) {
160706f2543Smrg	key = (KeyCode) f->key;
161706f2543Smrg	if (key < 8 || key > 255) {
162706f2543Smrg	    client->errorValue = key;
163706f2543Smrg	    return BadValue;
164706f2543Smrg	}
165706f2543Smrg	if (!(mask & DvAutoRepeatMode))
166706f2543Smrg	    return BadMatch;
167706f2543Smrg    }
168706f2543Smrg
169706f2543Smrg    if (mask & DvAutoRepeatMode) {
170706f2543Smrg	int inx = (key >> 3);
171706f2543Smrg	int kmask = (1 << (key & 7));
172706f2543Smrg
173706f2543Smrg	t = (CARD8) f->auto_repeat_mode;
174706f2543Smrg	if (t == AutoRepeatModeOff) {
175706f2543Smrg	    if (key == DO_ALL)
176706f2543Smrg		kctrl.autoRepeat = FALSE;
177706f2543Smrg	    else
178706f2543Smrg		kctrl.autoRepeats[inx] &= ~kmask;
179706f2543Smrg	} else if (t == AutoRepeatModeOn) {
180706f2543Smrg	    if (key == DO_ALL)
181706f2543Smrg		kctrl.autoRepeat = TRUE;
182706f2543Smrg	    else
183706f2543Smrg		kctrl.autoRepeats[inx] |= kmask;
184706f2543Smrg	} else if (t == AutoRepeatModeDefault) {
185706f2543Smrg	    if (key == DO_ALL)
186706f2543Smrg		kctrl.autoRepeat = defaultKeyboardControl.autoRepeat;
187706f2543Smrg	    else
188706f2543Smrg		kctrl.autoRepeats[inx] &= ~kmask;
189706f2543Smrg	    kctrl.autoRepeats[inx] =
190706f2543Smrg		(kctrl.autoRepeats[inx] & ~kmask) |
191706f2543Smrg		(defaultKeyboardControl.autoRepeats[inx] & kmask);
192706f2543Smrg	} else {
193706f2543Smrg	    client->errorValue = t;
194706f2543Smrg	    return BadValue;
195706f2543Smrg	}
196706f2543Smrg    }
197706f2543Smrg
198706f2543Smrg    k->ctrl = kctrl;
199706f2543Smrg    (*k->CtrlProc) (dev, &k->ctrl);
200706f2543Smrg    return Success;
201706f2543Smrg}
202706f2543Smrg
203706f2543Smrg/******************************************************************************
204706f2543Smrg *
205706f2543Smrg * This procedure changes PtrFeedbackClass data.
206706f2543Smrg *
207706f2543Smrg */
208706f2543Smrg
209706f2543Smrgstatic int
210706f2543SmrgChangePtrFeedback(ClientPtr client, DeviceIntPtr dev, long unsigned int mask,
211706f2543Smrg		  PtrFeedbackPtr p, xPtrFeedbackCtl * f)
212706f2543Smrg{
213706f2543Smrg    char n;
214706f2543Smrg    PtrCtrl pctrl;	/* might get BadValue part way through */
215706f2543Smrg
216706f2543Smrg    if (client->swapped) {
217706f2543Smrg	swaps(&f->length, n);
218706f2543Smrg	swaps(&f->num, n);
219706f2543Smrg	swaps(&f->denom, n);
220706f2543Smrg	swaps(&f->thresh, n);
221706f2543Smrg    }
222706f2543Smrg
223706f2543Smrg    pctrl = p->ctrl;
224706f2543Smrg    if (mask & DvAccelNum) {
225706f2543Smrg	int accelNum;
226706f2543Smrg
227706f2543Smrg	accelNum = f->num;
228706f2543Smrg	if (accelNum == -1)
229706f2543Smrg	    pctrl.num = defaultPointerControl.num;
230706f2543Smrg	else if (accelNum < 0) {
231706f2543Smrg	    client->errorValue = accelNum;
232706f2543Smrg	    return BadValue;
233706f2543Smrg	} else
234706f2543Smrg	    pctrl.num = accelNum;
235706f2543Smrg    }
236706f2543Smrg
237706f2543Smrg    if (mask & DvAccelDenom) {
238706f2543Smrg	int accelDenom;
239706f2543Smrg
240706f2543Smrg	accelDenom = f->denom;
241706f2543Smrg	if (accelDenom == -1)
242706f2543Smrg	    pctrl.den = defaultPointerControl.den;
243706f2543Smrg	else if (accelDenom <= 0) {
244706f2543Smrg	    client->errorValue = accelDenom;
245706f2543Smrg	    return BadValue;
246706f2543Smrg	} else
247706f2543Smrg	    pctrl.den = accelDenom;
248706f2543Smrg    }
249706f2543Smrg
250706f2543Smrg    if (mask & DvThreshold) {
251706f2543Smrg	int threshold;
252706f2543Smrg
253706f2543Smrg	threshold = f->thresh;
254706f2543Smrg	if (threshold == -1)
255706f2543Smrg	    pctrl.threshold = defaultPointerControl.threshold;
256706f2543Smrg	else if (threshold < 0) {
257706f2543Smrg	    client->errorValue = threshold;
258706f2543Smrg	    return BadValue;
259706f2543Smrg	} else
260706f2543Smrg	    pctrl.threshold = threshold;
261706f2543Smrg    }
262706f2543Smrg
263706f2543Smrg    p->ctrl = pctrl;
264706f2543Smrg    (*p->CtrlProc) (dev, &p->ctrl);
265706f2543Smrg    return Success;
266706f2543Smrg}
267706f2543Smrg
268706f2543Smrg/******************************************************************************
269706f2543Smrg *
270706f2543Smrg * This procedure changes IntegerFeedbackClass data.
271706f2543Smrg *
272706f2543Smrg */
273706f2543Smrg
274706f2543Smrgstatic int
275706f2543SmrgChangeIntegerFeedback(ClientPtr client, DeviceIntPtr dev,
276706f2543Smrg		      long unsigned int mask, IntegerFeedbackPtr i,
277706f2543Smrg		      xIntegerFeedbackCtl * f)
278706f2543Smrg{
279706f2543Smrg    char n;
280706f2543Smrg
281706f2543Smrg    if (client->swapped) {
282706f2543Smrg	swaps(&f->length, n);
283706f2543Smrg	swapl(&f->int_to_display, n);
284706f2543Smrg    }
285706f2543Smrg
286706f2543Smrg    i->ctrl.integer_displayed = f->int_to_display;
287706f2543Smrg    (*i->CtrlProc) (dev, &i->ctrl);
288706f2543Smrg    return Success;
289706f2543Smrg}
290706f2543Smrg
291706f2543Smrg/******************************************************************************
292706f2543Smrg *
293706f2543Smrg * This procedure changes StringFeedbackClass data.
294706f2543Smrg *
295706f2543Smrg */
296706f2543Smrg
297706f2543Smrgstatic int
298706f2543SmrgChangeStringFeedback(ClientPtr client, DeviceIntPtr dev,
299706f2543Smrg		     long unsigned int mask, StringFeedbackPtr s,
300706f2543Smrg		     xStringFeedbackCtl * f)
301706f2543Smrg{
302706f2543Smrg    char n;
303706f2543Smrg    int i, j;
304706f2543Smrg    KeySym *syms, *sup_syms;
305706f2543Smrg
306706f2543Smrg    syms = (KeySym *) (f + 1);
307706f2543Smrg    if (client->swapped) {
308706f2543Smrg	swaps(&f->length, n);	/* swapped num_keysyms in calling proc */
309706f2543Smrg	SwapLongs((CARD32 *) syms, f->num_keysyms);
310706f2543Smrg    }
311706f2543Smrg
312706f2543Smrg    if (f->num_keysyms > s->ctrl.max_symbols)
313706f2543Smrg	return BadValue;
314706f2543Smrg
315706f2543Smrg    sup_syms = s->ctrl.symbols_supported;
316706f2543Smrg    for (i = 0; i < f->num_keysyms; i++) {
317706f2543Smrg	for (j = 0; j < s->ctrl.num_symbols_supported; j++)
318706f2543Smrg	    if (*(syms + i) == *(sup_syms + j))
319706f2543Smrg		break;
320706f2543Smrg	if (j == s->ctrl.num_symbols_supported)
321706f2543Smrg	    return BadMatch;
322706f2543Smrg    }
323706f2543Smrg
324706f2543Smrg    s->ctrl.num_symbols_displayed = f->num_keysyms;
325706f2543Smrg    for (i = 0; i < f->num_keysyms; i++)
326706f2543Smrg	*(s->ctrl.symbols_displayed + i) = *(syms + i);
327706f2543Smrg    (*s->CtrlProc) (dev, &s->ctrl);
328706f2543Smrg    return Success;
329706f2543Smrg}
330706f2543Smrg
331706f2543Smrg/******************************************************************************
332706f2543Smrg *
333706f2543Smrg * This procedure changes BellFeedbackClass data.
334706f2543Smrg *
335706f2543Smrg */
336706f2543Smrg
337706f2543Smrgstatic int
338706f2543SmrgChangeBellFeedback(ClientPtr client, DeviceIntPtr dev,
339706f2543Smrg		   long unsigned int mask, BellFeedbackPtr b,
340706f2543Smrg		   xBellFeedbackCtl * f)
341706f2543Smrg{
342706f2543Smrg    char n;
343706f2543Smrg    int t;
344706f2543Smrg    BellCtrl bctrl;	/* might get BadValue part way through */
345706f2543Smrg
346706f2543Smrg    if (client->swapped) {
347706f2543Smrg	swaps(&f->length, n);
348706f2543Smrg	swaps(&f->pitch, n);
349706f2543Smrg	swaps(&f->duration, n);
350706f2543Smrg    }
351706f2543Smrg
352706f2543Smrg    bctrl = b->ctrl;
353706f2543Smrg    if (mask & DvPercent) {
354706f2543Smrg	t = f->percent;
355706f2543Smrg	if (t == -1)
356706f2543Smrg	    t = defaultKeyboardControl.bell;
357706f2543Smrg	else if (t < 0 || t > 100) {
358706f2543Smrg	    client->errorValue = t;
359706f2543Smrg	    return BadValue;
360706f2543Smrg	}
361706f2543Smrg	bctrl.percent = t;
362706f2543Smrg    }
363706f2543Smrg
364706f2543Smrg    if (mask & DvPitch) {
365706f2543Smrg	t = f->pitch;
366706f2543Smrg	if (t == -1)
367706f2543Smrg	    t = defaultKeyboardControl.bell_pitch;
368706f2543Smrg	else if (t < 0) {
369706f2543Smrg	    client->errorValue = t;
370706f2543Smrg	    return BadValue;
371706f2543Smrg	}
372706f2543Smrg	bctrl.pitch = t;
373706f2543Smrg    }
374706f2543Smrg
375706f2543Smrg    if (mask & DvDuration) {
376706f2543Smrg	t = f->duration;
377706f2543Smrg	if (t == -1)
378706f2543Smrg	    t = defaultKeyboardControl.bell_duration;
379706f2543Smrg	else if (t < 0) {
380706f2543Smrg	    client->errorValue = t;
381706f2543Smrg	    return BadValue;
382706f2543Smrg	}
383706f2543Smrg	bctrl.duration = t;
384706f2543Smrg    }
385706f2543Smrg    b->ctrl = bctrl;
386706f2543Smrg    (*b->CtrlProc) (dev, &b->ctrl);
387706f2543Smrg    return Success;
388706f2543Smrg}
389706f2543Smrg
390706f2543Smrg/******************************************************************************
391706f2543Smrg *
392706f2543Smrg * This procedure changes LedFeedbackClass data.
393706f2543Smrg *
394706f2543Smrg */
395706f2543Smrg
396706f2543Smrgstatic int
397706f2543SmrgChangeLedFeedback(ClientPtr client, DeviceIntPtr dev, long unsigned int mask,
398706f2543Smrg		  LedFeedbackPtr l, xLedFeedbackCtl * f)
399706f2543Smrg{
400706f2543Smrg    char n;
401706f2543Smrg    LedCtrl lctrl;	/* might get BadValue part way through */
402706f2543Smrg
403706f2543Smrg    if (client->swapped) {
404706f2543Smrg	swaps(&f->length, n);
405706f2543Smrg	swapl(&f->led_values, n);
406706f2543Smrg	swapl(&f->led_mask, n);
407706f2543Smrg    }
408706f2543Smrg
409706f2543Smrg    f->led_mask &= l->ctrl.led_mask;	/* set only supported leds */
410706f2543Smrg    f->led_values &= l->ctrl.led_mask;	/* set only supported leds */
411706f2543Smrg    if (mask & DvLed) {
412706f2543Smrg	lctrl.led_mask = f->led_mask;
413706f2543Smrg	lctrl.led_values = f->led_values;
414706f2543Smrg	(*l->CtrlProc) (dev, &lctrl);
415706f2543Smrg	l->ctrl.led_values &= ~(f->led_mask);	/* zero changed leds */
416706f2543Smrg	l->ctrl.led_values |= (f->led_mask & f->led_values);	/* OR in set leds */
417706f2543Smrg    }
418706f2543Smrg
419706f2543Smrg    return Success;
420706f2543Smrg}
421706f2543Smrg
422706f2543Smrg/***********************************************************************
423706f2543Smrg *
424706f2543Smrg * Change the control attributes.
425706f2543Smrg *
426706f2543Smrg */
427706f2543Smrg
428706f2543Smrgint
429706f2543SmrgProcXChangeFeedbackControl(ClientPtr client)
430706f2543Smrg{
431706f2543Smrg    unsigned len;
432706f2543Smrg    DeviceIntPtr dev;
433706f2543Smrg    KbdFeedbackPtr k;
434706f2543Smrg    PtrFeedbackPtr p;
435706f2543Smrg    IntegerFeedbackPtr i;
436706f2543Smrg    StringFeedbackPtr s;
437706f2543Smrg    BellFeedbackPtr b;
438706f2543Smrg    LedFeedbackPtr l;
439706f2543Smrg    int rc;
440706f2543Smrg
441706f2543Smrg    REQUEST(xChangeFeedbackControlReq);
442706f2543Smrg    REQUEST_AT_LEAST_SIZE(xChangeFeedbackControlReq);
443706f2543Smrg
444706f2543Smrg    len = stuff->length - bytes_to_int32(sizeof(xChangeFeedbackControlReq));
445706f2543Smrg    rc = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
446706f2543Smrg    if (rc != Success)
447706f2543Smrg	return rc;
448706f2543Smrg
449706f2543Smrg    switch (stuff->feedbackid) {
450706f2543Smrg    case KbdFeedbackClass:
451706f2543Smrg	if (len != bytes_to_int32(sizeof(xKbdFeedbackCtl)))
452706f2543Smrg	    return BadLength;
453706f2543Smrg
454706f2543Smrg	for (k = dev->kbdfeed; k; k = k->next)
455706f2543Smrg	    if (k->ctrl.id == ((xKbdFeedbackCtl *) & stuff[1])->id)
456706f2543Smrg		return ChangeKbdFeedback(client, dev, stuff->mask, k,
457706f2543Smrg					 (xKbdFeedbackCtl *) & stuff[1]);
458706f2543Smrg	break;
459706f2543Smrg    case PtrFeedbackClass:
460706f2543Smrg	if (len != bytes_to_int32(sizeof(xPtrFeedbackCtl)))
461706f2543Smrg	    return BadLength;
462706f2543Smrg
463706f2543Smrg	for (p = dev->ptrfeed; p; p = p->next)
464706f2543Smrg	    if (p->ctrl.id == ((xPtrFeedbackCtl *) & stuff[1])->id)
465706f2543Smrg		return ChangePtrFeedback(client, dev, stuff->mask, p,
466706f2543Smrg					 (xPtrFeedbackCtl *) & stuff[1]);
467706f2543Smrg	break;
468706f2543Smrg    case StringFeedbackClass:
469706f2543Smrg    {
470706f2543Smrg	char n;
471c023c32cSmrg        xStringFeedbackCtl *f;
472706f2543Smrg
473c023c32cSmrg        REQUEST_AT_LEAST_EXTRA_SIZE(xChangeFeedbackControlReq,
474c023c32cSmrg                                    sizeof(xStringFeedbackCtl));
475c023c32cSmrg        f = ((xStringFeedbackCtl *) &stuff[1]);
476706f2543Smrg	if (client->swapped) {
477706f2543Smrg            if (len < bytes_to_int32(sizeof(xStringFeedbackCtl)))
478706f2543Smrg                return BadLength;
479706f2543Smrg	    swaps(&f->num_keysyms, n);
480706f2543Smrg	}
481706f2543Smrg	if (len != (bytes_to_int32(sizeof(xStringFeedbackCtl)) + f->num_keysyms))
482706f2543Smrg	    return BadLength;
483706f2543Smrg
484706f2543Smrg	for (s = dev->stringfeed; s; s = s->next)
485706f2543Smrg	    if (s->ctrl.id == ((xStringFeedbackCtl *) & stuff[1])->id)
486706f2543Smrg		return ChangeStringFeedback(client, dev, stuff->mask, s,
487706f2543Smrg					    (xStringFeedbackCtl *) & stuff[1]);
488706f2543Smrg	break;
489706f2543Smrg    }
490706f2543Smrg    case IntegerFeedbackClass:
491706f2543Smrg	if (len != bytes_to_int32(sizeof(xIntegerFeedbackCtl)))
492706f2543Smrg	    return BadLength;
493706f2543Smrg
494706f2543Smrg	for (i = dev->intfeed; i; i = i->next)
495706f2543Smrg	    if (i->ctrl.id == ((xIntegerFeedbackCtl *) & stuff[1])->id)
496706f2543Smrg		return ChangeIntegerFeedback(client, dev, stuff->mask, i,
497706f2543Smrg					     (xIntegerFeedbackCtl *)&stuff[1]);
498706f2543Smrg	break;
499706f2543Smrg    case LedFeedbackClass:
500706f2543Smrg	if (len != bytes_to_int32(sizeof(xLedFeedbackCtl)))
501706f2543Smrg	    return BadLength;
502706f2543Smrg
503706f2543Smrg	for (l = dev->leds; l; l = l->next)
504706f2543Smrg	    if (l->ctrl.id == ((xLedFeedbackCtl *) & stuff[1])->id)
505706f2543Smrg		return ChangeLedFeedback(client, dev, stuff->mask, l,
506706f2543Smrg					 (xLedFeedbackCtl *) & stuff[1]);
507706f2543Smrg	break;
508706f2543Smrg    case BellFeedbackClass:
509706f2543Smrg	if (len != bytes_to_int32(sizeof(xBellFeedbackCtl)))
510706f2543Smrg	    return BadLength;
511706f2543Smrg
512706f2543Smrg	for (b = dev->bell; b; b = b->next)
513706f2543Smrg	    if (b->ctrl.id == ((xBellFeedbackCtl *) & stuff[1])->id)
514706f2543Smrg		return ChangeBellFeedback(client, dev, stuff->mask, b,
515706f2543Smrg					  (xBellFeedbackCtl *) & stuff[1]);
516706f2543Smrg	break;
517706f2543Smrg    default:
518706f2543Smrg	break;
519706f2543Smrg    }
520706f2543Smrg
521706f2543Smrg    return BadMatch;
522706f2543Smrg}
523706f2543Smrg
524