First import
[xorg_rtime.git] / xorg-server-1.4 / Xi / chgfctl.c
blob2e0e13cad678ffcdb381fa5c13cfc05e31f668b0
1 /************************************************************
3 Copyright 1989, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
25 Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
27 All Rights Reserved
29 Permission to use, copy, modify, and distribute this software and its
30 documentation for any purpose and without fee is hereby granted,
31 provided that the above copyright notice appear in all copies and that
32 both that copyright notice and this permission notice appear in
33 supporting documentation, and that the name of Hewlett-Packard not be
34 used in advertising or publicity pertaining to distribution of the
35 software without specific, written prior permission.
37 HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
38 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
39 HEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
40 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
41 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
42 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
43 SOFTWARE.
45 ********************************************************/
47 /********************************************************************
49 * Change feedback control attributes for an extension device.
53 #define NEED_EVENTS /* for inputstr.h */
54 #define NEED_REPLIES
55 #ifdef HAVE_DIX_CONFIG_H
56 #include <dix-config.h>
57 #endif
59 #include <X11/X.h> /* for inputstr.h */
60 #include <X11/Xproto.h> /* Request macro */
61 #include "inputstr.h" /* DeviceIntPtr */
62 #include <X11/extensions/XI.h>
63 #include <X11/extensions/XIproto.h> /* control constants */
65 #include "extnsionst.h"
66 #include "extinit.h" /* LookupDeviceIntRec */
67 #include "exglobals.h"
69 #include "chgfctl.h"
71 #define DO_ALL (-1)
73 /***********************************************************************
75 * This procedure changes the control attributes for an extension device,
76 * for clients on machines with a different byte ordering than the server.
80 int
81 SProcXChangeFeedbackControl(ClientPtr client)
83 char n;
85 REQUEST(xChangeFeedbackControlReq);
86 swaps(&stuff->length, n);
87 REQUEST_AT_LEAST_SIZE(xChangeFeedbackControlReq);
88 swapl(&stuff->mask, n);
89 return (ProcXChangeFeedbackControl(client));
92 /******************************************************************************
94 * This procedure changes KbdFeedbackClass data.
98 static int
99 ChangeKbdFeedback(ClientPtr client, DeviceIntPtr dev, long unsigned int mask,
100 KbdFeedbackPtr k, xKbdFeedbackCtl * f)
102 char n;
103 KeybdCtrl kctrl;
104 int t;
105 int key = DO_ALL;
107 if (client->swapped) {
108 swaps(&f->length, n);
109 swaps(&f->pitch, n);
110 swaps(&f->duration, n);
111 swapl(&f->led_mask, n);
112 swapl(&f->led_values, n);
115 kctrl = k->ctrl;
116 if (mask & DvKeyClickPercent) {
117 t = f->click;
118 if (t == -1)
119 t = defaultKeyboardControl.click;
120 else if (t < 0 || t > 100) {
121 client->errorValue = t;
122 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl, 0,
123 BadValue);
124 return Success;
126 kctrl.click = t;
129 if (mask & DvPercent) {
130 t = f->percent;
131 if (t == -1)
132 t = defaultKeyboardControl.bell;
133 else if (t < 0 || t > 100) {
134 client->errorValue = t;
135 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl, 0,
136 BadValue);
137 return Success;
139 kctrl.bell = t;
142 if (mask & DvPitch) {
143 t = f->pitch;
144 if (t == -1)
145 t = defaultKeyboardControl.bell_pitch;
146 else if (t < 0) {
147 client->errorValue = t;
148 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl, 0,
149 BadValue);
150 return Success;
152 kctrl.bell_pitch = t;
155 if (mask & DvDuration) {
156 t = f->duration;
157 if (t == -1)
158 t = defaultKeyboardControl.bell_duration;
159 else if (t < 0) {
160 client->errorValue = t;
161 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl, 0,
162 BadValue);
163 return Success;
165 kctrl.bell_duration = t;
168 if (mask & DvLed) {
169 kctrl.leds &= ~(f->led_mask);
170 kctrl.leds |= (f->led_mask & f->led_values);
173 if (mask & DvKey) {
174 key = (KeyCode) f->key;
175 if (key < 8 || key > 255) {
176 client->errorValue = key;
177 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl, 0,
178 BadValue);
179 return Success;
181 if (!(mask & DvAutoRepeatMode)) {
182 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl, 0,
183 BadMatch);
184 return Success;
188 if (mask & DvAutoRepeatMode) {
189 int inx = (key >> 3);
190 int kmask = (1 << (key & 7));
192 t = (CARD8) f->auto_repeat_mode;
193 if (t == AutoRepeatModeOff) {
194 if (key == DO_ALL)
195 kctrl.autoRepeat = FALSE;
196 else
197 kctrl.autoRepeats[inx] &= ~kmask;
198 } else if (t == AutoRepeatModeOn) {
199 if (key == DO_ALL)
200 kctrl.autoRepeat = TRUE;
201 else
202 kctrl.autoRepeats[inx] |= kmask;
203 } else if (t == AutoRepeatModeDefault) {
204 if (key == DO_ALL)
205 kctrl.autoRepeat = defaultKeyboardControl.autoRepeat;
206 else
207 kctrl.autoRepeats[inx] &= ~kmask;
208 kctrl.autoRepeats[inx] =
209 (kctrl.autoRepeats[inx] & ~kmask) |
210 (defaultKeyboardControl.autoRepeats[inx] & kmask);
211 } else {
212 client->errorValue = t;
213 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl, 0,
214 BadValue);
215 return Success;
219 k->ctrl = kctrl;
220 (*k->CtrlProc) (dev, &k->ctrl);
221 return Success;
224 /******************************************************************************
226 * This procedure changes PtrFeedbackClass data.
230 static int
231 ChangePtrFeedback(ClientPtr client, DeviceIntPtr dev, long unsigned int mask,
232 PtrFeedbackPtr p, xPtrFeedbackCtl * f)
234 char n;
235 PtrCtrl pctrl; /* might get BadValue part way through */
237 if (client->swapped) {
238 swaps(&f->length, n);
239 swaps(&f->num, n);
240 swaps(&f->denom, n);
241 swaps(&f->thresh, n);
244 pctrl = p->ctrl;
245 if (mask & DvAccelNum) {
246 int accelNum;
248 accelNum = f->num;
249 if (accelNum == -1)
250 pctrl.num = defaultPointerControl.num;
251 else if (accelNum < 0) {
252 client->errorValue = accelNum;
253 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl, 0,
254 BadValue);
255 return Success;
256 } else
257 pctrl.num = accelNum;
260 if (mask & DvAccelDenom) {
261 int accelDenom;
263 accelDenom = f->denom;
264 if (accelDenom == -1)
265 pctrl.den = defaultPointerControl.den;
266 else if (accelDenom <= 0) {
267 client->errorValue = accelDenom;
268 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl, 0,
269 BadValue);
270 return Success;
271 } else
272 pctrl.den = accelDenom;
275 if (mask & DvThreshold) {
276 int threshold;
278 threshold = f->thresh;
279 if (threshold == -1)
280 pctrl.threshold = defaultPointerControl.threshold;
281 else if (threshold < 0) {
282 client->errorValue = threshold;
283 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl, 0,
284 BadValue);
285 return Success;
286 } else
287 pctrl.threshold = threshold;
290 p->ctrl = pctrl;
291 (*p->CtrlProc) (dev, &p->ctrl);
292 return Success;
295 /******************************************************************************
297 * This procedure changes IntegerFeedbackClass data.
301 static int
302 ChangeIntegerFeedback(ClientPtr client, DeviceIntPtr dev,
303 long unsigned int mask, IntegerFeedbackPtr i,
304 xIntegerFeedbackCtl * f)
306 char n;
308 if (client->swapped) {
309 swaps(&f->length, n);
310 swapl(&f->int_to_display, n);
313 i->ctrl.integer_displayed = f->int_to_display;
314 (*i->CtrlProc) (dev, &i->ctrl);
315 return Success;
318 /******************************************************************************
320 * This procedure changes StringFeedbackClass data.
324 static int
325 ChangeStringFeedback(ClientPtr client, DeviceIntPtr dev,
326 long unsigned int mask, StringFeedbackPtr s,
327 xStringFeedbackCtl * f)
329 char n;
330 long *p;
331 int i, j;
332 KeySym *syms, *sup_syms;
334 syms = (KeySym *) (f + 1);
335 if (client->swapped) {
336 swaps(&f->length, n); /* swapped num_keysyms in calling proc */
337 p = (long *)(syms);
338 for (i = 0; i < f->num_keysyms; i++) {
339 swapl(p, n);
340 p++;
344 if (f->num_keysyms > s->ctrl.max_symbols) {
345 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl, 0,
346 BadValue);
347 return Success;
349 sup_syms = s->ctrl.symbols_supported;
350 for (i = 0; i < f->num_keysyms; i++) {
351 for (j = 0; j < s->ctrl.num_symbols_supported; j++)
352 if (*(syms + i) == *(sup_syms + j))
353 break;
354 if (j == s->ctrl.num_symbols_supported) {
355 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl, 0,
356 BadMatch);
357 return Success;
361 s->ctrl.num_symbols_displayed = f->num_keysyms;
362 for (i = 0; i < f->num_keysyms; i++)
363 *(s->ctrl.symbols_displayed + i) = *(syms + i);
364 (*s->CtrlProc) (dev, &s->ctrl);
365 return Success;
368 /******************************************************************************
370 * This procedure changes BellFeedbackClass data.
374 static int
375 ChangeBellFeedback(ClientPtr client, DeviceIntPtr dev,
376 long unsigned int mask, BellFeedbackPtr b,
377 xBellFeedbackCtl * f)
379 char n;
380 int t;
381 BellCtrl bctrl; /* might get BadValue part way through */
383 if (client->swapped) {
384 swaps(&f->length, n);
385 swaps(&f->pitch, n);
386 swaps(&f->duration, n);
389 bctrl = b->ctrl;
390 if (mask & DvPercent) {
391 t = f->percent;
392 if (t == -1)
393 t = defaultKeyboardControl.bell;
394 else if (t < 0 || t > 100) {
395 client->errorValue = t;
396 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl, 0,
397 BadValue);
398 return Success;
400 bctrl.percent = t;
403 if (mask & DvPitch) {
404 t = f->pitch;
405 if (t == -1)
406 t = defaultKeyboardControl.bell_pitch;
407 else if (t < 0) {
408 client->errorValue = t;
409 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl, 0,
410 BadValue);
411 return Success;
413 bctrl.pitch = t;
416 if (mask & DvDuration) {
417 t = f->duration;
418 if (t == -1)
419 t = defaultKeyboardControl.bell_duration;
420 else if (t < 0) {
421 client->errorValue = t;
422 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl, 0,
423 BadValue);
424 return Success;
426 bctrl.duration = t;
428 b->ctrl = bctrl;
429 (*b->CtrlProc) (dev, &b->ctrl);
430 return Success;
433 /******************************************************************************
435 * This procedure changes LedFeedbackClass data.
439 static int
440 ChangeLedFeedback(ClientPtr client, DeviceIntPtr dev, long unsigned int mask,
441 LedFeedbackPtr l, xLedFeedbackCtl * f)
443 char n;
444 LedCtrl lctrl; /* might get BadValue part way through */
446 if (client->swapped) {
447 swaps(&f->length, n);
448 swapl(&f->led_values, n);
449 swapl(&f->led_mask, n);
452 f->led_mask &= l->ctrl.led_mask; /* set only supported leds */
453 f->led_values &= l->ctrl.led_mask; /* set only supported leds */
454 if (mask & DvLed) {
455 lctrl.led_mask = f->led_mask;
456 lctrl.led_values = f->led_values;
457 (*l->CtrlProc) (dev, &lctrl);
458 l->ctrl.led_values &= ~(f->led_mask); /* zero changed leds */
459 l->ctrl.led_values |= (f->led_mask & f->led_values); /* OR in set leds */
462 return Success;
465 /***********************************************************************
467 * Change the control attributes.
472 ProcXChangeFeedbackControl(ClientPtr client)
474 unsigned len;
475 DeviceIntPtr dev;
476 KbdFeedbackPtr k;
477 PtrFeedbackPtr p;
478 IntegerFeedbackPtr i;
479 StringFeedbackPtr s;
480 BellFeedbackPtr b;
481 LedFeedbackPtr l;
483 REQUEST(xChangeFeedbackControlReq);
484 REQUEST_AT_LEAST_SIZE(xChangeFeedbackControlReq);
486 len = stuff->length - (sizeof(xChangeFeedbackControlReq) >> 2);
487 dev = LookupDeviceIntRec(stuff->deviceid);
488 if (dev == NULL) {
489 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl, 0,
490 BadDevice);
491 return Success;
494 switch (stuff->feedbackid) {
495 case KbdFeedbackClass:
496 if (len != (sizeof(xKbdFeedbackCtl) >> 2)) {
497 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl,
498 0, BadLength);
499 return Success;
501 for (k = dev->kbdfeed; k; k = k->next)
502 if (k->ctrl.id == ((xKbdFeedbackCtl *) & stuff[1])->id) {
503 ChangeKbdFeedback(client, dev, stuff->mask, k,
504 (xKbdFeedbackCtl *) & stuff[1]);
505 return Success;
507 break;
508 case PtrFeedbackClass:
509 if (len != (sizeof(xPtrFeedbackCtl) >> 2)) {
510 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl,
511 0, BadLength);
512 return Success;
514 for (p = dev->ptrfeed; p; p = p->next)
515 if (p->ctrl.id == ((xPtrFeedbackCtl *) & stuff[1])->id) {
516 ChangePtrFeedback(client, dev, stuff->mask, p,
517 (xPtrFeedbackCtl *) & stuff[1]);
518 return Success;
520 break;
521 case StringFeedbackClass:
523 char n;
524 xStringFeedbackCtl *f = ((xStringFeedbackCtl *) & stuff[1]);
526 if (client->swapped) {
527 swaps(&f->num_keysyms, n);
529 if (len != ((sizeof(xStringFeedbackCtl) >> 2) + f->num_keysyms)) {
530 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl,
531 0, BadLength);
532 return Success;
534 for (s = dev->stringfeed; s; s = s->next)
535 if (s->ctrl.id == ((xStringFeedbackCtl *) & stuff[1])->id) {
536 ChangeStringFeedback(client, dev, stuff->mask, s,
537 (xStringFeedbackCtl *) & stuff[1]);
538 return Success;
540 break;
542 case IntegerFeedbackClass:
543 if (len != (sizeof(xIntegerFeedbackCtl) >> 2)) {
544 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl,
545 0, BadLength);
546 return Success;
548 for (i = dev->intfeed; i; i = i->next)
549 if (i->ctrl.id == ((xIntegerFeedbackCtl *) & stuff[1])->id) {
550 ChangeIntegerFeedback(client, dev, stuff->mask, i,
551 (xIntegerFeedbackCtl *) & stuff[1]);
552 return Success;
554 break;
555 case LedFeedbackClass:
556 if (len != (sizeof(xLedFeedbackCtl) >> 2)) {
557 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl,
558 0, BadLength);
559 return Success;
561 for (l = dev->leds; l; l = l->next)
562 if (l->ctrl.id == ((xLedFeedbackCtl *) & stuff[1])->id) {
563 ChangeLedFeedback(client, dev, stuff->mask, l,
564 (xLedFeedbackCtl *) & stuff[1]);
565 return Success;
567 break;
568 case BellFeedbackClass:
569 if (len != (sizeof(xBellFeedbackCtl) >> 2)) {
570 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl,
571 0, BadLength);
572 return Success;
574 for (b = dev->bell; b; b = b->next)
575 if (b->ctrl.id == ((xBellFeedbackCtl *) & stuff[1])->id) {
576 ChangeBellFeedback(client, dev, stuff->mask, b,
577 (xBellFeedbackCtl *) & stuff[1]);
578 return Success;
580 break;
581 default:
582 break;
585 SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl, 0, BadMatch);
586 return Success;