chgfctl.c revision 0b0d8713
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
5705b261ecSmrg#include "inputstr.h"	/* DeviceIntPtr      */
5805b261ecSmrg#include <X11/extensions/XI.h>
5905b261ecSmrg#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
7405b261ecSmrgint
7505b261ecSmrgSProcXChangeFeedbackControl(ClientPtr client)
7605b261ecSmrg{
7705b261ecSmrg    char n;
7805b261ecSmrg
7905b261ecSmrg    REQUEST(xChangeFeedbackControlReq);
8005b261ecSmrg    swaps(&stuff->length, n);
8105b261ecSmrg    REQUEST_AT_LEAST_SIZE(xChangeFeedbackControlReq);
8205b261ecSmrg    swapl(&stuff->mask, n);
8305b261ecSmrg    return (ProcXChangeFeedbackControl(client));
8405b261ecSmrg}
8505b261ecSmrg
8605b261ecSmrg/******************************************************************************
8705b261ecSmrg *
8805b261ecSmrg * This procedure changes KbdFeedbackClass data.
8905b261ecSmrg *
9005b261ecSmrg */
9105b261ecSmrg
9205b261ecSmrgstatic int
9305b261ecSmrgChangeKbdFeedback(ClientPtr client, DeviceIntPtr dev, long unsigned int mask,
9405b261ecSmrg		  KbdFeedbackPtr k, xKbdFeedbackCtl * f)
9505b261ecSmrg{
9605b261ecSmrg    char n;
9705b261ecSmrg    KeybdCtrl kctrl;
9805b261ecSmrg    int t;
9905b261ecSmrg    int key = DO_ALL;
10005b261ecSmrg
10105b261ecSmrg    if (client->swapped) {
10205b261ecSmrg	swaps(&f->length, n);
10305b261ecSmrg	swaps(&f->pitch, n);
10405b261ecSmrg	swaps(&f->duration, n);
10505b261ecSmrg	swapl(&f->led_mask, n);
10605b261ecSmrg	swapl(&f->led_values, n);
10705b261ecSmrg    }
10805b261ecSmrg
10905b261ecSmrg    kctrl = k->ctrl;
11005b261ecSmrg    if (mask & DvKeyClickPercent) {
11105b261ecSmrg	t = f->click;
11205b261ecSmrg	if (t == -1)
11305b261ecSmrg	    t = defaultKeyboardControl.click;
11405b261ecSmrg	else if (t < 0 || t > 100) {
11505b261ecSmrg	    client->errorValue = t;
1164642e01fSmrg	    return BadValue;
11705b261ecSmrg	}
11805b261ecSmrg	kctrl.click = t;
11905b261ecSmrg    }
12005b261ecSmrg
12105b261ecSmrg    if (mask & DvPercent) {
12205b261ecSmrg	t = f->percent;
12305b261ecSmrg	if (t == -1)
12405b261ecSmrg	    t = defaultKeyboardControl.bell;
12505b261ecSmrg	else if (t < 0 || t > 100) {
12605b261ecSmrg	    client->errorValue = t;
1274642e01fSmrg	    return BadValue;
12805b261ecSmrg	}
12905b261ecSmrg	kctrl.bell = t;
13005b261ecSmrg    }
13105b261ecSmrg
13205b261ecSmrg    if (mask & DvPitch) {
13305b261ecSmrg	t = f->pitch;
13405b261ecSmrg	if (t == -1)
13505b261ecSmrg	    t = defaultKeyboardControl.bell_pitch;
13605b261ecSmrg	else if (t < 0) {
13705b261ecSmrg	    client->errorValue = t;
1384642e01fSmrg	    return BadValue;
13905b261ecSmrg	}
14005b261ecSmrg	kctrl.bell_pitch = t;
14105b261ecSmrg    }
14205b261ecSmrg
14305b261ecSmrg    if (mask & DvDuration) {
14405b261ecSmrg	t = f->duration;
14505b261ecSmrg	if (t == -1)
14605b261ecSmrg	    t = defaultKeyboardControl.bell_duration;
14705b261ecSmrg	else if (t < 0) {
14805b261ecSmrg	    client->errorValue = t;
1494642e01fSmrg	    return BadValue;
15005b261ecSmrg	}
15105b261ecSmrg	kctrl.bell_duration = t;
15205b261ecSmrg    }
15305b261ecSmrg
15405b261ecSmrg    if (mask & DvLed) {
15505b261ecSmrg	kctrl.leds &= ~(f->led_mask);
15605b261ecSmrg	kctrl.leds |= (f->led_mask & f->led_values);
15705b261ecSmrg    }
15805b261ecSmrg
15905b261ecSmrg    if (mask & DvKey) {
16005b261ecSmrg	key = (KeyCode) f->key;
16105b261ecSmrg	if (key < 8 || key > 255) {
16205b261ecSmrg	    client->errorValue = key;
1634642e01fSmrg	    return BadValue;
16405b261ecSmrg	}
1654642e01fSmrg	if (!(mask & DvAutoRepeatMode))
1664642e01fSmrg	    return BadMatch;
16705b261ecSmrg    }
16805b261ecSmrg
16905b261ecSmrg    if (mask & DvAutoRepeatMode) {
17005b261ecSmrg	int inx = (key >> 3);
17105b261ecSmrg	int kmask = (1 << (key & 7));
17205b261ecSmrg
17305b261ecSmrg	t = (CARD8) f->auto_repeat_mode;
17405b261ecSmrg	if (t == AutoRepeatModeOff) {
17505b261ecSmrg	    if (key == DO_ALL)
17605b261ecSmrg		kctrl.autoRepeat = FALSE;
17705b261ecSmrg	    else
17805b261ecSmrg		kctrl.autoRepeats[inx] &= ~kmask;
17905b261ecSmrg	} else if (t == AutoRepeatModeOn) {
18005b261ecSmrg	    if (key == DO_ALL)
18105b261ecSmrg		kctrl.autoRepeat = TRUE;
18205b261ecSmrg	    else
18305b261ecSmrg		kctrl.autoRepeats[inx] |= kmask;
18405b261ecSmrg	} else if (t == AutoRepeatModeDefault) {
18505b261ecSmrg	    if (key == DO_ALL)
18605b261ecSmrg		kctrl.autoRepeat = defaultKeyboardControl.autoRepeat;
18705b261ecSmrg	    else
18805b261ecSmrg		kctrl.autoRepeats[inx] &= ~kmask;
18905b261ecSmrg	    kctrl.autoRepeats[inx] =
19005b261ecSmrg		(kctrl.autoRepeats[inx] & ~kmask) |
19105b261ecSmrg		(defaultKeyboardControl.autoRepeats[inx] & kmask);
19205b261ecSmrg	} else {
19305b261ecSmrg	    client->errorValue = t;
1944642e01fSmrg	    return BadValue;
19505b261ecSmrg	}
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,
21105b261ecSmrg		  PtrFeedbackPtr p, xPtrFeedbackCtl * f)
21205b261ecSmrg{
21305b261ecSmrg    char n;
21405b261ecSmrg    PtrCtrl pctrl;	/* might get BadValue part way through */
21505b261ecSmrg
21605b261ecSmrg    if (client->swapped) {
21705b261ecSmrg	swaps(&f->length, n);
21805b261ecSmrg	swaps(&f->num, n);
21905b261ecSmrg	swaps(&f->denom, n);
22005b261ecSmrg	swaps(&f->thresh, n);
22105b261ecSmrg    }
22205b261ecSmrg
22305b261ecSmrg    pctrl = p->ctrl;
22405b261ecSmrg    if (mask & DvAccelNum) {
22505b261ecSmrg	int accelNum;
22605b261ecSmrg
22705b261ecSmrg	accelNum = f->num;
22805b261ecSmrg	if (accelNum == -1)
22905b261ecSmrg	    pctrl.num = defaultPointerControl.num;
23005b261ecSmrg	else if (accelNum < 0) {
23105b261ecSmrg	    client->errorValue = accelNum;
2324642e01fSmrg	    return BadValue;
23305b261ecSmrg	} else
23405b261ecSmrg	    pctrl.num = accelNum;
23505b261ecSmrg    }
23605b261ecSmrg
23705b261ecSmrg    if (mask & DvAccelDenom) {
23805b261ecSmrg	int accelDenom;
23905b261ecSmrg
24005b261ecSmrg	accelDenom = f->denom;
24105b261ecSmrg	if (accelDenom == -1)
24205b261ecSmrg	    pctrl.den = defaultPointerControl.den;
24305b261ecSmrg	else if (accelDenom <= 0) {
24405b261ecSmrg	    client->errorValue = accelDenom;
2454642e01fSmrg	    return BadValue;
24605b261ecSmrg	} else
24705b261ecSmrg	    pctrl.den = accelDenom;
24805b261ecSmrg    }
24905b261ecSmrg
25005b261ecSmrg    if (mask & DvThreshold) {
25105b261ecSmrg	int threshold;
25205b261ecSmrg
25305b261ecSmrg	threshold = f->thresh;
25405b261ecSmrg	if (threshold == -1)
25505b261ecSmrg	    pctrl.threshold = defaultPointerControl.threshold;
25605b261ecSmrg	else if (threshold < 0) {
25705b261ecSmrg	    client->errorValue = threshold;
2584642e01fSmrg	    return BadValue;
25905b261ecSmrg	} else
26005b261ecSmrg	    pctrl.threshold = threshold;
26105b261ecSmrg    }
26205b261ecSmrg
26305b261ecSmrg    p->ctrl = pctrl;
26405b261ecSmrg    (*p->CtrlProc) (dev, &p->ctrl);
26505b261ecSmrg    return Success;
26605b261ecSmrg}
26705b261ecSmrg
26805b261ecSmrg/******************************************************************************
26905b261ecSmrg *
27005b261ecSmrg * This procedure changes IntegerFeedbackClass data.
27105b261ecSmrg *
27205b261ecSmrg */
27305b261ecSmrg
27405b261ecSmrgstatic int
27505b261ecSmrgChangeIntegerFeedback(ClientPtr client, DeviceIntPtr dev,
27605b261ecSmrg		      long unsigned int mask, IntegerFeedbackPtr i,
27705b261ecSmrg		      xIntegerFeedbackCtl * f)
27805b261ecSmrg{
27905b261ecSmrg    char n;
28005b261ecSmrg
28105b261ecSmrg    if (client->swapped) {
28205b261ecSmrg	swaps(&f->length, n);
28305b261ecSmrg	swapl(&f->int_to_display, n);
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,
29905b261ecSmrg		     long unsigned int mask, StringFeedbackPtr s,
30005b261ecSmrg		     xStringFeedbackCtl * f)
30105b261ecSmrg{
30205b261ecSmrg    char n;
30305b261ecSmrg    int i, j;
30405b261ecSmrg    KeySym *syms, *sup_syms;
30505b261ecSmrg
30605b261ecSmrg    syms = (KeySym *) (f + 1);
30705b261ecSmrg    if (client->swapped) {
30805b261ecSmrg	swaps(&f->length, n);	/* swapped num_keysyms in calling proc */
30905b261ecSmrg	SwapLongs((CARD32 *) syms, f->num_keysyms);
31005b261ecSmrg    }
31105b261ecSmrg
3124642e01fSmrg    if (f->num_keysyms > s->ctrl.max_symbols)
3134642e01fSmrg	return BadValue;
3144642e01fSmrg
31505b261ecSmrg    sup_syms = s->ctrl.symbols_supported;
31605b261ecSmrg    for (i = 0; i < f->num_keysyms; i++) {
31705b261ecSmrg	for (j = 0; j < s->ctrl.num_symbols_supported; j++)
31805b261ecSmrg	    if (*(syms + i) == *(sup_syms + j))
31905b261ecSmrg		break;
3204642e01fSmrg	if (j == s->ctrl.num_symbols_supported)
3214642e01fSmrg	    return BadMatch;
32205b261ecSmrg    }
32305b261ecSmrg
32405b261ecSmrg    s->ctrl.num_symbols_displayed = f->num_keysyms;
32505b261ecSmrg    for (i = 0; i < f->num_keysyms; i++)
32605b261ecSmrg	*(s->ctrl.symbols_displayed + i) = *(syms + i);
32705b261ecSmrg    (*s->CtrlProc) (dev, &s->ctrl);
32805b261ecSmrg    return Success;
32905b261ecSmrg}
33005b261ecSmrg
33105b261ecSmrg/******************************************************************************
33205b261ecSmrg *
33305b261ecSmrg * This procedure changes BellFeedbackClass data.
33405b261ecSmrg *
33505b261ecSmrg */
33605b261ecSmrg
33705b261ecSmrgstatic int
33805b261ecSmrgChangeBellFeedback(ClientPtr client, DeviceIntPtr dev,
33905b261ecSmrg		   long unsigned int mask, BellFeedbackPtr b,
34005b261ecSmrg		   xBellFeedbackCtl * f)
34105b261ecSmrg{
34205b261ecSmrg    char n;
34305b261ecSmrg    int t;
34405b261ecSmrg    BellCtrl bctrl;	/* might get BadValue part way through */
34505b261ecSmrg
34605b261ecSmrg    if (client->swapped) {
34705b261ecSmrg	swaps(&f->length, n);
34805b261ecSmrg	swaps(&f->pitch, n);
34905b261ecSmrg	swaps(&f->duration, n);
35005b261ecSmrg    }
35105b261ecSmrg
35205b261ecSmrg    bctrl = b->ctrl;
35305b261ecSmrg    if (mask & DvPercent) {
35405b261ecSmrg	t = f->percent;
35505b261ecSmrg	if (t == -1)
35605b261ecSmrg	    t = defaultKeyboardControl.bell;
35705b261ecSmrg	else if (t < 0 || t > 100) {
35805b261ecSmrg	    client->errorValue = t;
3594642e01fSmrg	    return BadValue;
36005b261ecSmrg	}
36105b261ecSmrg	bctrl.percent = t;
36205b261ecSmrg    }
36305b261ecSmrg
36405b261ecSmrg    if (mask & DvPitch) {
36505b261ecSmrg	t = f->pitch;
36605b261ecSmrg	if (t == -1)
36705b261ecSmrg	    t = defaultKeyboardControl.bell_pitch;
36805b261ecSmrg	else if (t < 0) {
36905b261ecSmrg	    client->errorValue = t;
3704642e01fSmrg	    return BadValue;
37105b261ecSmrg	}
37205b261ecSmrg	bctrl.pitch = t;
37305b261ecSmrg    }
37405b261ecSmrg
37505b261ecSmrg    if (mask & DvDuration) {
37605b261ecSmrg	t = f->duration;
37705b261ecSmrg	if (t == -1)
37805b261ecSmrg	    t = defaultKeyboardControl.bell_duration;
37905b261ecSmrg	else if (t < 0) {
38005b261ecSmrg	    client->errorValue = t;
3814642e01fSmrg	    return BadValue;
38205b261ecSmrg	}
38305b261ecSmrg	bctrl.duration = t;
38405b261ecSmrg    }
38505b261ecSmrg    b->ctrl = bctrl;
38605b261ecSmrg    (*b->CtrlProc) (dev, &b->ctrl);
38705b261ecSmrg    return Success;
38805b261ecSmrg}
38905b261ecSmrg
39005b261ecSmrg/******************************************************************************
39105b261ecSmrg *
39205b261ecSmrg * This procedure changes LedFeedbackClass data.
39305b261ecSmrg *
39405b261ecSmrg */
39505b261ecSmrg
39605b261ecSmrgstatic int
39705b261ecSmrgChangeLedFeedback(ClientPtr client, DeviceIntPtr dev, long unsigned int mask,
39805b261ecSmrg		  LedFeedbackPtr l, xLedFeedbackCtl * f)
39905b261ecSmrg{
40005b261ecSmrg    char n;
40105b261ecSmrg    LedCtrl lctrl;	/* might get BadValue part way through */
40205b261ecSmrg
40305b261ecSmrg    if (client->swapped) {
40405b261ecSmrg	swaps(&f->length, n);
40505b261ecSmrg	swapl(&f->led_values, n);
40605b261ecSmrg	swapl(&f->led_mask, n);
40705b261ecSmrg    }
40805b261ecSmrg
40905b261ecSmrg    f->led_mask &= l->ctrl.led_mask;	/* set only supported leds */
41005b261ecSmrg    f->led_values &= l->ctrl.led_mask;	/* set only supported leds */
41105b261ecSmrg    if (mask & DvLed) {
41205b261ecSmrg	lctrl.led_mask = f->led_mask;
41305b261ecSmrg	lctrl.led_values = f->led_values;
41405b261ecSmrg	(*l->CtrlProc) (dev, &lctrl);
41505b261ecSmrg	l->ctrl.led_values &= ~(f->led_mask);	/* zero changed leds */
41605b261ecSmrg	l->ctrl.led_values |= (f->led_mask & f->led_values);	/* OR in set leds */
41705b261ecSmrg    }
41805b261ecSmrg
41905b261ecSmrg    return Success;
42005b261ecSmrg}
42105b261ecSmrg
42205b261ecSmrg/***********************************************************************
42305b261ecSmrg *
42405b261ecSmrg * Change the control attributes.
42505b261ecSmrg *
42605b261ecSmrg */
42705b261ecSmrg
42805b261ecSmrgint
42905b261ecSmrgProcXChangeFeedbackControl(ClientPtr client)
43005b261ecSmrg{
43105b261ecSmrg    unsigned len;
43205b261ecSmrg    DeviceIntPtr dev;
43305b261ecSmrg    KbdFeedbackPtr k;
43405b261ecSmrg    PtrFeedbackPtr p;
43505b261ecSmrg    IntegerFeedbackPtr i;
43605b261ecSmrg    StringFeedbackPtr s;
43705b261ecSmrg    BellFeedbackPtr b;
43805b261ecSmrg    LedFeedbackPtr l;
4394642e01fSmrg    int rc;
44005b261ecSmrg
44105b261ecSmrg    REQUEST(xChangeFeedbackControlReq);
44205b261ecSmrg    REQUEST_AT_LEAST_SIZE(xChangeFeedbackControlReq);
44305b261ecSmrg
4446747b715Smrg    len = stuff->length - bytes_to_int32(sizeof(xChangeFeedbackControlReq));
4454642e01fSmrg    rc = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
4464642e01fSmrg    if (rc != Success)
4474642e01fSmrg	return rc;
44805b261ecSmrg
44905b261ecSmrg    switch (stuff->feedbackid) {
45005b261ecSmrg    case KbdFeedbackClass:
4516747b715Smrg	if (len != bytes_to_int32(sizeof(xKbdFeedbackCtl)))
4524642e01fSmrg	    return BadLength;
4534642e01fSmrg
45405b261ecSmrg	for (k = dev->kbdfeed; k; k = k->next)
4554642e01fSmrg	    if (k->ctrl.id == ((xKbdFeedbackCtl *) & stuff[1])->id)
4564642e01fSmrg		return ChangeKbdFeedback(client, dev, stuff->mask, k,
4574642e01fSmrg					 (xKbdFeedbackCtl *) & stuff[1]);
45805b261ecSmrg	break;
45905b261ecSmrg    case PtrFeedbackClass:
4606747b715Smrg	if (len != bytes_to_int32(sizeof(xPtrFeedbackCtl)))
4614642e01fSmrg	    return BadLength;
4624642e01fSmrg
46305b261ecSmrg	for (p = dev->ptrfeed; p; p = p->next)
4644642e01fSmrg	    if (p->ctrl.id == ((xPtrFeedbackCtl *) & stuff[1])->id)
4654642e01fSmrg		return ChangePtrFeedback(client, dev, stuff->mask, p,
4664642e01fSmrg					 (xPtrFeedbackCtl *) & stuff[1]);
46705b261ecSmrg	break;
46805b261ecSmrg    case StringFeedbackClass:
46905b261ecSmrg    {
47005b261ecSmrg	char n;
47105b261ecSmrg	xStringFeedbackCtl *f = ((xStringFeedbackCtl *) & stuff[1]);
47205b261ecSmrg
47305b261ecSmrg	if (client->swapped) {
4740b0d8713Smrg            if (len < bytes_to_int32(sizeof(xStringFeedbackCtl)))
4750b0d8713Smrg                return BadLength;
47605b261ecSmrg	    swaps(&f->num_keysyms, n);
47705b261ecSmrg	}
4786747b715Smrg	if (len != (bytes_to_int32(sizeof(xStringFeedbackCtl)) + f->num_keysyms))
4794642e01fSmrg	    return BadLength;
4804642e01fSmrg
48105b261ecSmrg	for (s = dev->stringfeed; s; s = s->next)
4824642e01fSmrg	    if (s->ctrl.id == ((xStringFeedbackCtl *) & stuff[1])->id)
4834642e01fSmrg		return ChangeStringFeedback(client, dev, stuff->mask, s,
4844642e01fSmrg					    (xStringFeedbackCtl *) & stuff[1]);
48505b261ecSmrg	break;
48605b261ecSmrg    }
48705b261ecSmrg    case IntegerFeedbackClass:
4886747b715Smrg	if (len != bytes_to_int32(sizeof(xIntegerFeedbackCtl)))
4894642e01fSmrg	    return BadLength;
4904642e01fSmrg
49105b261ecSmrg	for (i = dev->intfeed; i; i = i->next)
4924642e01fSmrg	    if (i->ctrl.id == ((xIntegerFeedbackCtl *) & stuff[1])->id)
4934642e01fSmrg		return ChangeIntegerFeedback(client, dev, stuff->mask, i,
4944642e01fSmrg					     (xIntegerFeedbackCtl *)&stuff[1]);
49505b261ecSmrg	break;
49605b261ecSmrg    case LedFeedbackClass:
4976747b715Smrg	if (len != bytes_to_int32(sizeof(xLedFeedbackCtl)))
4984642e01fSmrg	    return BadLength;
4994642e01fSmrg
50005b261ecSmrg	for (l = dev->leds; l; l = l->next)
5014642e01fSmrg	    if (l->ctrl.id == ((xLedFeedbackCtl *) & stuff[1])->id)
5024642e01fSmrg		return ChangeLedFeedback(client, dev, stuff->mask, l,
5034642e01fSmrg					 (xLedFeedbackCtl *) & stuff[1]);
50405b261ecSmrg	break;
50505b261ecSmrg    case BellFeedbackClass:
5066747b715Smrg	if (len != bytes_to_int32(sizeof(xBellFeedbackCtl)))
5074642e01fSmrg	    return BadLength;
5084642e01fSmrg
50905b261ecSmrg	for (b = dev->bell; b; b = b->next)
5104642e01fSmrg	    if (b->ctrl.id == ((xBellFeedbackCtl *) & stuff[1])->id)
5114642e01fSmrg		return ChangeBellFeedback(client, dev, stuff->mask, b,
5124642e01fSmrg					  (xBellFeedbackCtl *) & stuff[1]);
51305b261ecSmrg	break;
51405b261ecSmrg    default:
51505b261ecSmrg	break;
51605b261ecSmrg    }
51705b261ecSmrg
5184642e01fSmrg    return BadMatch;
51905b261ecSmrg}
52005b261ecSmrg
521