105b261ecSmrg/************************************************************
205b261ecSmrg
305b261ecSmrgCopyright 1989, 1998  The Open Group
405b261ecSmrg
505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its
605b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that
705b261ecSmrgthe above copyright notice appear in all copies and that both that
805b261ecSmrgcopyright notice and this permission notice appear in supporting
905b261ecSmrgdocumentation.
1005b261ecSmrg
1105b261ecSmrgThe above copyright notice and this permission notice shall be included in
1205b261ecSmrgall copies or substantial portions of the Software.
1305b261ecSmrg
1405b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1505b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1605b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
1705b261ecSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1805b261ecSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1905b261ecSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2005b261ecSmrg
2105b261ecSmrgExcept as contained in this notice, the name of The Open Group shall not be
2205b261ecSmrgused in advertising or otherwise to promote the sale, use or other dealings
2305b261ecSmrgin this Software without prior written authorization from The Open Group.
2405b261ecSmrg
2505b261ecSmrgCopyright 1989 by Hewlett-Packard Company, Palo Alto, California.
2605b261ecSmrg
2705b261ecSmrg			All Rights Reserved
2805b261ecSmrg
2905b261ecSmrgPermission to use, copy, modify, and distribute this software and its
3005b261ecSmrgdocumentation for any purpose and without fee is hereby granted,
3105b261ecSmrgprovided that the above copyright notice appear in all copies and that
3205b261ecSmrgboth that copyright notice and this permission notice appear in
3305b261ecSmrgsupporting documentation, and that the name of Hewlett-Packard not be
3405b261ecSmrgused in advertising or publicity pertaining to distribution of the
3505b261ecSmrgsoftware without specific, written prior permission.
3605b261ecSmrg
3705b261ecSmrgHEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
3805b261ecSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
3905b261ecSmrgHEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
4005b261ecSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
4105b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
4205b261ecSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
4305b261ecSmrgSOFTWARE.
4405b261ecSmrg
4505b261ecSmrg********************************************************/
4605b261ecSmrg
4705b261ecSmrg/********************************************************************
4805b261ecSmrg *
4905b261ecSmrg *  Change feedback control attributes for an extension device.
5005b261ecSmrg *
5105b261ecSmrg */
5205b261ecSmrg
5305b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
5405b261ecSmrg#include <dix-config.h>
5505b261ecSmrg#endif
5605b261ecSmrg
57f7df2e56Smrg#include "inputstr.h"           /* DeviceIntPtr      */
5805b261ecSmrg#include <X11/extensions/XI.h>
59f7df2e56Smrg#include <X11/extensions/XIproto.h>     /* control constants */
6005b261ecSmrg
6105b261ecSmrg#include "exglobals.h"
6205b261ecSmrg
6305b261ecSmrg#include "chgfctl.h"
6405b261ecSmrg
6505b261ecSmrg#define DO_ALL    (-1)
6605b261ecSmrg
6705b261ecSmrg/***********************************************************************
6805b261ecSmrg *
6905b261ecSmrg * This procedure changes the control attributes for an extension device,
7005b261ecSmrg * for clients on machines with a different byte ordering than the server.
7105b261ecSmrg *
7205b261ecSmrg */
7305b261ecSmrg
747e31ba66Smrgint _X_COLD
7505b261ecSmrgSProcXChangeFeedbackControl(ClientPtr client)
7605b261ecSmrg{
7705b261ecSmrg    REQUEST(xChangeFeedbackControlReq);
78f7df2e56Smrg    swaps(&stuff->length);
7905b261ecSmrg    REQUEST_AT_LEAST_SIZE(xChangeFeedbackControlReq);
80f7df2e56Smrg    swapl(&stuff->mask);
8105b261ecSmrg    return (ProcXChangeFeedbackControl(client));
8205b261ecSmrg}
8305b261ecSmrg
8405b261ecSmrg/******************************************************************************
8505b261ecSmrg *
8605b261ecSmrg * This procedure changes KbdFeedbackClass data.
8705b261ecSmrg *
8805b261ecSmrg */
8905b261ecSmrg
9005b261ecSmrgstatic int
9105b261ecSmrgChangeKbdFeedback(ClientPtr client, DeviceIntPtr dev, long unsigned int mask,
92f7df2e56Smrg                  KbdFeedbackPtr k, xKbdFeedbackCtl * f)
9305b261ecSmrg{
9405b261ecSmrg    KeybdCtrl kctrl;
9505b261ecSmrg    int t;
9605b261ecSmrg    int key = DO_ALL;
9705b261ecSmrg
9805b261ecSmrg    if (client->swapped) {
99f7df2e56Smrg        swaps(&f->length);
100f7df2e56Smrg        swaps(&f->pitch);
101f7df2e56Smrg        swaps(&f->duration);
102f7df2e56Smrg        swapl(&f->led_mask);
103f7df2e56Smrg        swapl(&f->led_values);
10405b261ecSmrg    }
10505b261ecSmrg
10605b261ecSmrg    kctrl = k->ctrl;
10705b261ecSmrg    if (mask & DvKeyClickPercent) {
108f7df2e56Smrg        t = f->click;
109f7df2e56Smrg        if (t == -1)
110f7df2e56Smrg            t = defaultKeyboardControl.click;
111f7df2e56Smrg        else if (t < 0 || t > 100) {
112f7df2e56Smrg            client->errorValue = t;
113f7df2e56Smrg            return BadValue;
114f7df2e56Smrg        }
115f7df2e56Smrg        kctrl.click = t;
11605b261ecSmrg    }
11705b261ecSmrg
11805b261ecSmrg    if (mask & DvPercent) {
119f7df2e56Smrg        t = f->percent;
120f7df2e56Smrg        if (t == -1)
121f7df2e56Smrg            t = defaultKeyboardControl.bell;
122f7df2e56Smrg        else if (t < 0 || t > 100) {
123f7df2e56Smrg            client->errorValue = t;
124f7df2e56Smrg            return BadValue;
125f7df2e56Smrg        }
126f7df2e56Smrg        kctrl.bell = t;
12705b261ecSmrg    }
12805b261ecSmrg
12905b261ecSmrg    if (mask & DvPitch) {
130f7df2e56Smrg        t = f->pitch;
131f7df2e56Smrg        if (t == -1)
132f7df2e56Smrg            t = defaultKeyboardControl.bell_pitch;
133f7df2e56Smrg        else if (t < 0) {
134f7df2e56Smrg            client->errorValue = t;
135f7df2e56Smrg            return BadValue;
136f7df2e56Smrg        }
137f7df2e56Smrg        kctrl.bell_pitch = t;
13805b261ecSmrg    }
13905b261ecSmrg
14005b261ecSmrg    if (mask & DvDuration) {
141f7df2e56Smrg        t = f->duration;
142f7df2e56Smrg        if (t == -1)
143f7df2e56Smrg            t = defaultKeyboardControl.bell_duration;
144f7df2e56Smrg        else if (t < 0) {
145f7df2e56Smrg            client->errorValue = t;
146f7df2e56Smrg            return BadValue;
147f7df2e56Smrg        }
148f7df2e56Smrg        kctrl.bell_duration = t;
14905b261ecSmrg    }
15005b261ecSmrg
15105b261ecSmrg    if (mask & DvLed) {
152f7df2e56Smrg        kctrl.leds &= ~(f->led_mask);
153f7df2e56Smrg        kctrl.leds |= (f->led_mask & f->led_values);
15405b261ecSmrg    }
15505b261ecSmrg
15605b261ecSmrg    if (mask & DvKey) {
157f7df2e56Smrg        key = (KeyCode) f->key;
158f7df2e56Smrg        if (key < 8 || key > 255) {
159f7df2e56Smrg            client->errorValue = key;
160f7df2e56Smrg            return BadValue;
161f7df2e56Smrg        }
162f7df2e56Smrg        if (!(mask & DvAutoRepeatMode))
163f7df2e56Smrg            return BadMatch;
16405b261ecSmrg    }
16505b261ecSmrg
16605b261ecSmrg    if (mask & DvAutoRepeatMode) {
167f7df2e56Smrg        int inx = (key >> 3);
168f7df2e56Smrg        int kmask = (1 << (key & 7));
169f7df2e56Smrg
170f7df2e56Smrg        t = (CARD8) f->auto_repeat_mode;
171f7df2e56Smrg        if (t == AutoRepeatModeOff) {
172f7df2e56Smrg            if (key == DO_ALL)
173f7df2e56Smrg                kctrl.autoRepeat = FALSE;
174f7df2e56Smrg            else
175f7df2e56Smrg                kctrl.autoRepeats[inx] &= ~kmask;
176f7df2e56Smrg        }
177f7df2e56Smrg        else if (t == AutoRepeatModeOn) {
178f7df2e56Smrg            if (key == DO_ALL)
179f7df2e56Smrg                kctrl.autoRepeat = TRUE;
180f7df2e56Smrg            else
181f7df2e56Smrg                kctrl.autoRepeats[inx] |= kmask;
182f7df2e56Smrg        }
183f7df2e56Smrg        else if (t == AutoRepeatModeDefault) {
184f7df2e56Smrg            if (key == DO_ALL)
185f7df2e56Smrg                kctrl.autoRepeat = defaultKeyboardControl.autoRepeat;
186f7df2e56Smrg            else
187f7df2e56Smrg                kctrl.autoRepeats[inx] &= ~kmask;
188f7df2e56Smrg            kctrl.autoRepeats[inx] =
189f7df2e56Smrg                (kctrl.autoRepeats[inx] & ~kmask) |
190f7df2e56Smrg                (defaultKeyboardControl.autoRepeats[inx] & kmask);
191f7df2e56Smrg        }
192f7df2e56Smrg        else {
193f7df2e56Smrg            client->errorValue = t;
194f7df2e56Smrg            return BadValue;
195f7df2e56Smrg        }
19605b261ecSmrg    }
19705b261ecSmrg
19805b261ecSmrg    k->ctrl = kctrl;
19905b261ecSmrg    (*k->CtrlProc) (dev, &k->ctrl);
20005b261ecSmrg    return Success;
20105b261ecSmrg}
20205b261ecSmrg
20305b261ecSmrg/******************************************************************************
20405b261ecSmrg *
20505b261ecSmrg * This procedure changes PtrFeedbackClass data.
20605b261ecSmrg *
20705b261ecSmrg */
20805b261ecSmrg
20905b261ecSmrgstatic int
21005b261ecSmrgChangePtrFeedback(ClientPtr client, DeviceIntPtr dev, long unsigned int mask,
211f7df2e56Smrg                  PtrFeedbackPtr p, xPtrFeedbackCtl * f)
21205b261ecSmrg{
213f7df2e56Smrg    PtrCtrl pctrl;              /* might get BadValue part way through */
21405b261ecSmrg
21505b261ecSmrg    if (client->swapped) {
216f7df2e56Smrg        swaps(&f->length);
217f7df2e56Smrg        swaps(&f->num);
218f7df2e56Smrg        swaps(&f->denom);
219f7df2e56Smrg        swaps(&f->thresh);
22005b261ecSmrg    }
22105b261ecSmrg
22205b261ecSmrg    pctrl = p->ctrl;
22305b261ecSmrg    if (mask & DvAccelNum) {
224f7df2e56Smrg        int accelNum;
225f7df2e56Smrg
226f7df2e56Smrg        accelNum = f->num;
227f7df2e56Smrg        if (accelNum == -1)
228f7df2e56Smrg            pctrl.num = defaultPointerControl.num;
229f7df2e56Smrg        else if (accelNum < 0) {
230f7df2e56Smrg            client->errorValue = accelNum;
231f7df2e56Smrg            return BadValue;
232f7df2e56Smrg        }
233f7df2e56Smrg        else
234f7df2e56Smrg            pctrl.num = accelNum;
23505b261ecSmrg    }
23605b261ecSmrg
23705b261ecSmrg    if (mask & DvAccelDenom) {
238f7df2e56Smrg        int accelDenom;
239f7df2e56Smrg
240f7df2e56Smrg        accelDenom = f->denom;
241f7df2e56Smrg        if (accelDenom == -1)
242f7df2e56Smrg            pctrl.den = defaultPointerControl.den;
243f7df2e56Smrg        else if (accelDenom <= 0) {
244f7df2e56Smrg            client->errorValue = accelDenom;
245f7df2e56Smrg            return BadValue;
246f7df2e56Smrg        }
247f7df2e56Smrg        else
248f7df2e56Smrg            pctrl.den = accelDenom;
24905b261ecSmrg    }
25005b261ecSmrg
25105b261ecSmrg    if (mask & DvThreshold) {
252f7df2e56Smrg        int threshold;
253f7df2e56Smrg
254f7df2e56Smrg        threshold = f->thresh;
255f7df2e56Smrg        if (threshold == -1)
256f7df2e56Smrg            pctrl.threshold = defaultPointerControl.threshold;
257f7df2e56Smrg        else if (threshold < 0) {
258f7df2e56Smrg            client->errorValue = threshold;
259f7df2e56Smrg            return BadValue;
260f7df2e56Smrg        }
261f7df2e56Smrg        else
262f7df2e56Smrg            pctrl.threshold = threshold;
26305b261ecSmrg    }
26405b261ecSmrg
26505b261ecSmrg    p->ctrl = pctrl;
26605b261ecSmrg    (*p->CtrlProc) (dev, &p->ctrl);
26705b261ecSmrg    return Success;
26805b261ecSmrg}
26905b261ecSmrg
27005b261ecSmrg/******************************************************************************
27105b261ecSmrg *
27205b261ecSmrg * This procedure changes IntegerFeedbackClass data.
27305b261ecSmrg *
27405b261ecSmrg */
27505b261ecSmrg
27605b261ecSmrgstatic int
27705b261ecSmrgChangeIntegerFeedback(ClientPtr client, DeviceIntPtr dev,
278f7df2e56Smrg                      long unsigned int mask, IntegerFeedbackPtr i,
279f7df2e56Smrg                      xIntegerFeedbackCtl * f)
28005b261ecSmrg{
28105b261ecSmrg    if (client->swapped) {
282f7df2e56Smrg        swaps(&f->length);
283f7df2e56Smrg        swapl(&f->int_to_display);
28405b261ecSmrg    }
28505b261ecSmrg
28605b261ecSmrg    i->ctrl.integer_displayed = f->int_to_display;
28705b261ecSmrg    (*i->CtrlProc) (dev, &i->ctrl);
28805b261ecSmrg    return Success;
28905b261ecSmrg}
29005b261ecSmrg
29105b261ecSmrg/******************************************************************************
29205b261ecSmrg *
29305b261ecSmrg * This procedure changes StringFeedbackClass data.
29405b261ecSmrg *
29505b261ecSmrg */
29605b261ecSmrg
29705b261ecSmrgstatic int
29805b261ecSmrgChangeStringFeedback(ClientPtr client, DeviceIntPtr dev,
299f7df2e56Smrg                     long unsigned int mask, StringFeedbackPtr s,
300f7df2e56Smrg                     xStringFeedbackCtl * f)
30105b261ecSmrg{
30205b261ecSmrg    int i, j;
30305b261ecSmrg    KeySym *syms, *sup_syms;
30405b261ecSmrg
30505b261ecSmrg    syms = (KeySym *) (f + 1);
30605b261ecSmrg    if (client->swapped) {
307f7df2e56Smrg        swaps(&f->length);      /* swapped num_keysyms in calling proc */
308f7df2e56Smrg        SwapLongs((CARD32 *) syms, f->num_keysyms);
30905b261ecSmrg    }
31005b261ecSmrg
3114642e01fSmrg    if (f->num_keysyms > s->ctrl.max_symbols)
312f7df2e56Smrg        return BadValue;
3134642e01fSmrg
31405b261ecSmrg    sup_syms = s->ctrl.symbols_supported;
31505b261ecSmrg    for (i = 0; i < f->num_keysyms; i++) {
316f7df2e56Smrg        for (j = 0; j < s->ctrl.num_symbols_supported; j++)
317f7df2e56Smrg            if (*(syms + i) == *(sup_syms + j))
318f7df2e56Smrg                break;
319f7df2e56Smrg        if (j == s->ctrl.num_symbols_supported)
320f7df2e56Smrg            return BadMatch;
32105b261ecSmrg    }
32205b261ecSmrg
32305b261ecSmrg    s->ctrl.num_symbols_displayed = f->num_keysyms;
32405b261ecSmrg    for (i = 0; i < f->num_keysyms; i++)
325f7df2e56Smrg        *(s->ctrl.symbols_displayed + i) = *(syms + i);
32605b261ecSmrg    (*s->CtrlProc) (dev, &s->ctrl);
32705b261ecSmrg    return Success;
32805b261ecSmrg}
32905b261ecSmrg
33005b261ecSmrg/******************************************************************************
33105b261ecSmrg *
33205b261ecSmrg * This procedure changes BellFeedbackClass data.
33305b261ecSmrg *
33405b261ecSmrg */
33505b261ecSmrg
33605b261ecSmrgstatic int
33705b261ecSmrgChangeBellFeedback(ClientPtr client, DeviceIntPtr dev,
338f7df2e56Smrg                   long unsigned int mask, BellFeedbackPtr b,
339f7df2e56Smrg                   xBellFeedbackCtl * f)
34005b261ecSmrg{
34105b261ecSmrg    int t;
342f7df2e56Smrg    BellCtrl bctrl;             /* might get BadValue part way through */
34305b261ecSmrg
34405b261ecSmrg    if (client->swapped) {
345f7df2e56Smrg        swaps(&f->length);
346f7df2e56Smrg        swaps(&f->pitch);
347f7df2e56Smrg        swaps(&f->duration);
34805b261ecSmrg    }
34905b261ecSmrg
35005b261ecSmrg    bctrl = b->ctrl;
35105b261ecSmrg    if (mask & DvPercent) {
352f7df2e56Smrg        t = f->percent;
353f7df2e56Smrg        if (t == -1)
354f7df2e56Smrg            t = defaultKeyboardControl.bell;
355f7df2e56Smrg        else if (t < 0 || t > 100) {
356f7df2e56Smrg            client->errorValue = t;
357f7df2e56Smrg            return BadValue;
358f7df2e56Smrg        }
359f7df2e56Smrg        bctrl.percent = t;
36005b261ecSmrg    }
36105b261ecSmrg
36205b261ecSmrg    if (mask & DvPitch) {
363f7df2e56Smrg        t = f->pitch;
364f7df2e56Smrg        if (t == -1)
365f7df2e56Smrg            t = defaultKeyboardControl.bell_pitch;
366f7df2e56Smrg        else if (t < 0) {
367f7df2e56Smrg            client->errorValue = t;
368f7df2e56Smrg            return BadValue;
369f7df2e56Smrg        }
370f7df2e56Smrg        bctrl.pitch = t;
37105b261ecSmrg    }
37205b261ecSmrg
37305b261ecSmrg    if (mask & DvDuration) {
374f7df2e56Smrg        t = f->duration;
375f7df2e56Smrg        if (t == -1)
376f7df2e56Smrg            t = defaultKeyboardControl.bell_duration;
377f7df2e56Smrg        else if (t < 0) {
378f7df2e56Smrg            client->errorValue = t;
379f7df2e56Smrg            return BadValue;
380f7df2e56Smrg        }
381f7df2e56Smrg        bctrl.duration = t;
38205b261ecSmrg    }
38305b261ecSmrg    b->ctrl = bctrl;
38405b261ecSmrg    (*b->CtrlProc) (dev, &b->ctrl);
38505b261ecSmrg    return Success;
38605b261ecSmrg}
38705b261ecSmrg
38805b261ecSmrg/******************************************************************************
38905b261ecSmrg *
39005b261ecSmrg * This procedure changes LedFeedbackClass data.
39105b261ecSmrg *
39205b261ecSmrg */
39305b261ecSmrg
39405b261ecSmrgstatic int
39505b261ecSmrgChangeLedFeedback(ClientPtr client, DeviceIntPtr dev, long unsigned int mask,
396f7df2e56Smrg                  LedFeedbackPtr l, xLedFeedbackCtl * f)
39705b261ecSmrg{
398f7df2e56Smrg    LedCtrl lctrl;              /* might get BadValue part way through */
39905b261ecSmrg
40005b261ecSmrg    if (client->swapped) {
401f7df2e56Smrg        swaps(&f->length);
402f7df2e56Smrg        swapl(&f->led_values);
403f7df2e56Smrg        swapl(&f->led_mask);
40405b261ecSmrg    }
40505b261ecSmrg
406f7df2e56Smrg    f->led_mask &= l->ctrl.led_mask;    /* set only supported leds */
407f7df2e56Smrg    f->led_values &= l->ctrl.led_mask;  /* set only supported leds */
40805b261ecSmrg    if (mask & DvLed) {
409f7df2e56Smrg        lctrl.led_mask = f->led_mask;
410f7df2e56Smrg        lctrl.led_values = f->led_values;
411f7df2e56Smrg        (*l->CtrlProc) (dev, &lctrl);
412f7df2e56Smrg        l->ctrl.led_values &= ~(f->led_mask);   /* zero changed leds */
413f7df2e56Smrg        l->ctrl.led_values |= (f->led_mask & f->led_values);    /* OR in set leds */
41405b261ecSmrg    }
41505b261ecSmrg
41605b261ecSmrg    return Success;
41705b261ecSmrg}
41805b261ecSmrg
41905b261ecSmrg/***********************************************************************
42005b261ecSmrg *
42105b261ecSmrg * Change the control attributes.
42205b261ecSmrg *
42305b261ecSmrg */
42405b261ecSmrg
42505b261ecSmrgint
42605b261ecSmrgProcXChangeFeedbackControl(ClientPtr client)
42705b261ecSmrg{
42805b261ecSmrg    unsigned len;
42905b261ecSmrg    DeviceIntPtr dev;
43005b261ecSmrg    KbdFeedbackPtr k;
43105b261ecSmrg    PtrFeedbackPtr p;
43205b261ecSmrg    IntegerFeedbackPtr i;
43305b261ecSmrg    StringFeedbackPtr s;
43405b261ecSmrg    BellFeedbackPtr b;
43505b261ecSmrg    LedFeedbackPtr l;
4364642e01fSmrg    int rc;
43705b261ecSmrg
43805b261ecSmrg    REQUEST(xChangeFeedbackControlReq);
43905b261ecSmrg    REQUEST_AT_LEAST_SIZE(xChangeFeedbackControlReq);
44005b261ecSmrg
4416747b715Smrg    len = stuff->length - bytes_to_int32(sizeof(xChangeFeedbackControlReq));
4424642e01fSmrg    rc = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
4434642e01fSmrg    if (rc != Success)
444f7df2e56Smrg        return rc;
44505b261ecSmrg
44605b261ecSmrg    switch (stuff->feedbackid) {
44705b261ecSmrg    case KbdFeedbackClass:
448f7df2e56Smrg        if (len != bytes_to_int32(sizeof(xKbdFeedbackCtl)))
449f7df2e56Smrg            return BadLength;
450f7df2e56Smrg
451f7df2e56Smrg        for (k = dev->kbdfeed; k; k = k->next)
452f7df2e56Smrg            if (k->ctrl.id == ((xKbdFeedbackCtl *) &stuff[1])->id)
453f7df2e56Smrg                return ChangeKbdFeedback(client, dev, stuff->mask, k,
454f7df2e56Smrg                                         (xKbdFeedbackCtl *) &stuff[1]);
455f7df2e56Smrg        break;
45605b261ecSmrg    case PtrFeedbackClass:
457f7df2e56Smrg        if (len != bytes_to_int32(sizeof(xPtrFeedbackCtl)))
458f7df2e56Smrg            return BadLength;
459f7df2e56Smrg
460f7df2e56Smrg        for (p = dev->ptrfeed; p; p = p->next)
461f7df2e56Smrg            if (p->ctrl.id == ((xPtrFeedbackCtl *) &stuff[1])->id)
462f7df2e56Smrg                return ChangePtrFeedback(client, dev, stuff->mask, p,
463f7df2e56Smrg                                         (xPtrFeedbackCtl *) &stuff[1]);
464f7df2e56Smrg        break;
46505b261ecSmrg    case StringFeedbackClass:
46605b261ecSmrg    {
4675fad172eSmrg        xStringFeedbackCtl *f;
46805b261ecSmrg
4695fad172eSmrg        REQUEST_AT_LEAST_EXTRA_SIZE(xChangeFeedbackControlReq,
4705fad172eSmrg                                    sizeof(xStringFeedbackCtl));
4715fad172eSmrg        f = ((xStringFeedbackCtl *) &stuff[1]);
472f7df2e56Smrg        if (client->swapped) {
4730b0d8713Smrg            if (len < bytes_to_int32(sizeof(xStringFeedbackCtl)))
4740b0d8713Smrg                return BadLength;
475f7df2e56Smrg            swaps(&f->num_keysyms);
476f7df2e56Smrg        }
477f7df2e56Smrg        if (len !=
478f7df2e56Smrg            (bytes_to_int32(sizeof(xStringFeedbackCtl)) + f->num_keysyms))
479f7df2e56Smrg            return BadLength;
480f7df2e56Smrg
481f7df2e56Smrg        for (s = dev->stringfeed; s; s = s->next)
482f7df2e56Smrg            if (s->ctrl.id == ((xStringFeedbackCtl *) &stuff[1])->id)
483f7df2e56Smrg                return ChangeStringFeedback(client, dev, stuff->mask, s,
484f7df2e56Smrg                                            (xStringFeedbackCtl *) &stuff[1]);
485f7df2e56Smrg        break;
48605b261ecSmrg    }
48705b261ecSmrg    case IntegerFeedbackClass:
488f7df2e56Smrg        if (len != bytes_to_int32(sizeof(xIntegerFeedbackCtl)))
489f7df2e56Smrg            return BadLength;
490f7df2e56Smrg
491f7df2e56Smrg        for (i = dev->intfeed; i; i = i->next)
492f7df2e56Smrg            if (i->ctrl.id == ((xIntegerFeedbackCtl *) &stuff[1])->id)
493f7df2e56Smrg                return ChangeIntegerFeedback(client, dev, stuff->mask, i,
494f7df2e56Smrg                                             (xIntegerFeedbackCtl *) &
495f7df2e56Smrg                                             stuff[1]);
496f7df2e56Smrg        break;
49705b261ecSmrg    case LedFeedbackClass:
498f7df2e56Smrg        if (len != bytes_to_int32(sizeof(xLedFeedbackCtl)))
499f7df2e56Smrg            return BadLength;
500f7df2e56Smrg
501f7df2e56Smrg        for (l = dev->leds; l; l = l->next)
502f7df2e56Smrg            if (l->ctrl.id == ((xLedFeedbackCtl *) &stuff[1])->id)
503f7df2e56Smrg                return ChangeLedFeedback(client, dev, stuff->mask, l,
504f7df2e56Smrg                                         (xLedFeedbackCtl *) &stuff[1]);
505f7df2e56Smrg        break;
50605b261ecSmrg    case BellFeedbackClass:
507f7df2e56Smrg        if (len != bytes_to_int32(sizeof(xBellFeedbackCtl)))
508f7df2e56Smrg            return BadLength;
509f7df2e56Smrg
510f7df2e56Smrg        for (b = dev->bell; b; b = b->next)
511f7df2e56Smrg            if (b->ctrl.id == ((xBellFeedbackCtl *) &stuff[1])->id)
512f7df2e56Smrg                return ChangeBellFeedback(client, dev, stuff->mask, b,
513f7df2e56Smrg                                          (xBellFeedbackCtl *) &stuff[1]);
514f7df2e56Smrg        break;
51505b261ecSmrg    default:
516f7df2e56Smrg        break;
51705b261ecSmrg    }
51805b261ecSmrg
5194642e01fSmrg    return BadMatch;
52005b261ecSmrg}
521