Imported Upstream version 1.15.1
[deb_xorg-server.git] / Xi / chgfctl.c
CommitLineData
a09e091a
JB
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 * Change 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> /* control constants */
60
61#include "exglobals.h"
62
63#include "chgfctl.h"
64
65#define DO_ALL (-1)
66
67/***********************************************************************
68 *
69 * This procedure changes the control attributes for an extension device,
70 * for clients on machines with a different byte ordering than the server.
71 *
72 */
73
74int
75SProcXChangeFeedbackControl(ClientPtr client)
76{
77 REQUEST(xChangeFeedbackControlReq);
78 swaps(&stuff->length);
79 REQUEST_AT_LEAST_SIZE(xChangeFeedbackControlReq);
80 swapl(&stuff->mask);
81 return (ProcXChangeFeedbackControl(client));
82}
83
84/******************************************************************************
85 *
86 * This procedure changes KbdFeedbackClass data.
87 *
88 */
89
90static int
91ChangeKbdFeedback(ClientPtr client, DeviceIntPtr dev, long unsigned int mask,
92 KbdFeedbackPtr k, xKbdFeedbackCtl * f)
93{
94 KeybdCtrl kctrl;
95 int t;
96 int key = DO_ALL;
97
98 if (client->swapped) {
99 swaps(&f->length);
100 swaps(&f->pitch);
101 swaps(&f->duration);
102 swapl(&f->led_mask);
103 swapl(&f->led_values);
104 }
105
106 kctrl = k->ctrl;
107 if (mask & DvKeyClickPercent) {
108 t = f->click;
109 if (t == -1)
110 t = defaultKeyboardControl.click;
111 else if (t < 0 || t > 100) {
112 client->errorValue = t;
113 return BadValue;
114 }
115 kctrl.click = t;
116 }
117
118 if (mask & DvPercent) {
119 t = f->percent;
120 if (t == -1)
121 t = defaultKeyboardControl.bell;
122 else if (t < 0 || t > 100) {
123 client->errorValue = t;
124 return BadValue;
125 }
126 kctrl.bell = t;
127 }
128
129 if (mask & DvPitch) {
130 t = f->pitch;
131 if (t == -1)
132 t = defaultKeyboardControl.bell_pitch;
133 else if (t < 0) {
134 client->errorValue = t;
135 return BadValue;
136 }
137 kctrl.bell_pitch = t;
138 }
139
140 if (mask & DvDuration) {
141 t = f->duration;
142 if (t == -1)
143 t = defaultKeyboardControl.bell_duration;
144 else if (t < 0) {
145 client->errorValue = t;
146 return BadValue;
147 }
148 kctrl.bell_duration = t;
149 }
150
151 if (mask & DvLed) {
152 kctrl.leds &= ~(f->led_mask);
153 kctrl.leds |= (f->led_mask & f->led_values);
154 }
155
156 if (mask & DvKey) {
157 key = (KeyCode) f->key;
158 if (key < 8 || key > 255) {
159 client->errorValue = key;
160 return BadValue;
161 }
162 if (!(mask & DvAutoRepeatMode))
163 return BadMatch;
164 }
165
166 if (mask & DvAutoRepeatMode) {
167 int inx = (key >> 3);
168 int kmask = (1 << (key & 7));
169
170 t = (CARD8) f->auto_repeat_mode;
171 if (t == AutoRepeatModeOff) {
172 if (key == DO_ALL)
173 kctrl.autoRepeat = FALSE;
174 else
175 kctrl.autoRepeats[inx] &= ~kmask;
176 }
177 else if (t == AutoRepeatModeOn) {
178 if (key == DO_ALL)
179 kctrl.autoRepeat = TRUE;
180 else
181 kctrl.autoRepeats[inx] |= kmask;
182 }
183 else if (t == AutoRepeatModeDefault) {
184 if (key == DO_ALL)
185 kctrl.autoRepeat = defaultKeyboardControl.autoRepeat;
186 else
187 kctrl.autoRepeats[inx] &= ~kmask;
188 kctrl.autoRepeats[inx] =
189 (kctrl.autoRepeats[inx] & ~kmask) |
190 (defaultKeyboardControl.autoRepeats[inx] & kmask);
191 }
192 else {
193 client->errorValue = t;
194 return BadValue;
195 }
196 }
197
198 k->ctrl = kctrl;
199 (*k->CtrlProc) (dev, &k->ctrl);
200 return Success;
201}
202
203/******************************************************************************
204 *
205 * This procedure changes PtrFeedbackClass data.
206 *
207 */
208
209static int
210ChangePtrFeedback(ClientPtr client, DeviceIntPtr dev, long unsigned int mask,
211 PtrFeedbackPtr p, xPtrFeedbackCtl * f)
212{
213 PtrCtrl pctrl; /* might get BadValue part way through */
214
215 if (client->swapped) {
216 swaps(&f->length);
217 swaps(&f->num);
218 swaps(&f->denom);
219 swaps(&f->thresh);
220 }
221
222 pctrl = p->ctrl;
223 if (mask & DvAccelNum) {
224 int accelNum;
225
226 accelNum = f->num;
227 if (accelNum == -1)
228 pctrl.num = defaultPointerControl.num;
229 else if (accelNum < 0) {
230 client->errorValue = accelNum;
231 return BadValue;
232 }
233 else
234 pctrl.num = accelNum;
235 }
236
237 if (mask & DvAccelDenom) {
238 int accelDenom;
239
240 accelDenom = f->denom;
241 if (accelDenom == -1)
242 pctrl.den = defaultPointerControl.den;
243 else if (accelDenom <= 0) {
244 client->errorValue = accelDenom;
245 return BadValue;
246 }
247 else
248 pctrl.den = accelDenom;
249 }
250
251 if (mask & DvThreshold) {
252 int threshold;
253
254 threshold = f->thresh;
255 if (threshold == -1)
256 pctrl.threshold = defaultPointerControl.threshold;
257 else if (threshold < 0) {
258 client->errorValue = threshold;
259 return BadValue;
260 }
261 else
262 pctrl.threshold = threshold;
263 }
264
265 p->ctrl = pctrl;
266 (*p->CtrlProc) (dev, &p->ctrl);
267 return Success;
268}
269
270/******************************************************************************
271 *
272 * This procedure changes IntegerFeedbackClass data.
273 *
274 */
275
276static int
277ChangeIntegerFeedback(ClientPtr client, DeviceIntPtr dev,
278 long unsigned int mask, IntegerFeedbackPtr i,
279 xIntegerFeedbackCtl * f)
280{
281 if (client->swapped) {
282 swaps(&f->length);
283 swapl(&f->int_to_display);
284 }
285
286 i->ctrl.integer_displayed = f->int_to_display;
287 (*i->CtrlProc) (dev, &i->ctrl);
288 return Success;
289}
290
291/******************************************************************************
292 *
293 * This procedure changes StringFeedbackClass data.
294 *
295 */
296
297static int
298ChangeStringFeedback(ClientPtr client, DeviceIntPtr dev,
299 long unsigned int mask, StringFeedbackPtr s,
300 xStringFeedbackCtl * f)
301{
302 int i, j;
303 KeySym *syms, *sup_syms;
304
305 syms = (KeySym *) (f + 1);
306 if (client->swapped) {
307 swaps(&f->length); /* swapped num_keysyms in calling proc */
308 SwapLongs((CARD32 *) syms, f->num_keysyms);
309 }
310
311 if (f->num_keysyms > s->ctrl.max_symbols)
312 return BadValue;
313
314 sup_syms = s->ctrl.symbols_supported;
315 for (i = 0; i < f->num_keysyms; i++) {
316 for (j = 0; j < s->ctrl.num_symbols_supported; j++)
317 if (*(syms + i) == *(sup_syms + j))
318 break;
319 if (j == s->ctrl.num_symbols_supported)
320 return BadMatch;
321 }
322
323 s->ctrl.num_symbols_displayed = f->num_keysyms;
324 for (i = 0; i < f->num_keysyms; i++)
325 *(s->ctrl.symbols_displayed + i) = *(syms + i);
326 (*s->CtrlProc) (dev, &s->ctrl);
327 return Success;
328}
329
330/******************************************************************************
331 *
332 * This procedure changes BellFeedbackClass data.
333 *
334 */
335
336static int
337ChangeBellFeedback(ClientPtr client, DeviceIntPtr dev,
338 long unsigned int mask, BellFeedbackPtr b,
339 xBellFeedbackCtl * f)
340{
341 int t;
342 BellCtrl bctrl; /* might get BadValue part way through */
343
344 if (client->swapped) {
345 swaps(&f->length);
346 swaps(&f->pitch);
347 swaps(&f->duration);
348 }
349
350 bctrl = b->ctrl;
351 if (mask & DvPercent) {
352 t = f->percent;
353 if (t == -1)
354 t = defaultKeyboardControl.bell;
355 else if (t < 0 || t > 100) {
356 client->errorValue = t;
357 return BadValue;
358 }
359 bctrl.percent = t;
360 }
361
362 if (mask & DvPitch) {
363 t = f->pitch;
364 if (t == -1)
365 t = defaultKeyboardControl.bell_pitch;
366 else if (t < 0) {
367 client->errorValue = t;
368 return BadValue;
369 }
370 bctrl.pitch = t;
371 }
372
373 if (mask & DvDuration) {
374 t = f->duration;
375 if (t == -1)
376 t = defaultKeyboardControl.bell_duration;
377 else if (t < 0) {
378 client->errorValue = t;
379 return BadValue;
380 }
381 bctrl.duration = t;
382 }
383 b->ctrl = bctrl;
384 (*b->CtrlProc) (dev, &b->ctrl);
385 return Success;
386}
387
388/******************************************************************************
389 *
390 * This procedure changes LedFeedbackClass data.
391 *
392 */
393
394static int
395ChangeLedFeedback(ClientPtr client, DeviceIntPtr dev, long unsigned int mask,
396 LedFeedbackPtr l, xLedFeedbackCtl * f)
397{
398 LedCtrl lctrl; /* might get BadValue part way through */
399
400 if (client->swapped) {
401 swaps(&f->length);
402 swapl(&f->led_values);
403 swapl(&f->led_mask);
404 }
405
406 f->led_mask &= l->ctrl.led_mask; /* set only supported leds */
407 f->led_values &= l->ctrl.led_mask; /* set only supported leds */
408 if (mask & DvLed) {
409 lctrl.led_mask = f->led_mask;
410 lctrl.led_values = f->led_values;
411 (*l->CtrlProc) (dev, &lctrl);
412 l->ctrl.led_values &= ~(f->led_mask); /* zero changed leds */
413 l->ctrl.led_values |= (f->led_mask & f->led_values); /* OR in set leds */
414 }
415
416 return Success;
417}
418
419/***********************************************************************
420 *
421 * Change the control attributes.
422 *
423 */
424
425int
426ProcXChangeFeedbackControl(ClientPtr client)
427{
428 unsigned len;
429 DeviceIntPtr dev;
430 KbdFeedbackPtr k;
431 PtrFeedbackPtr p;
432 IntegerFeedbackPtr i;
433 StringFeedbackPtr s;
434 BellFeedbackPtr b;
435 LedFeedbackPtr l;
436 int rc;
437
438 REQUEST(xChangeFeedbackControlReq);
439 REQUEST_AT_LEAST_SIZE(xChangeFeedbackControlReq);
440
441 len = stuff->length - bytes_to_int32(sizeof(xChangeFeedbackControlReq));
442 rc = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
443 if (rc != Success)
444 return rc;
445
446 switch (stuff->feedbackid) {
447 case KbdFeedbackClass:
448 if (len != bytes_to_int32(sizeof(xKbdFeedbackCtl)))
449 return BadLength;
450
451 for (k = dev->kbdfeed; k; k = k->next)
452 if (k->ctrl.id == ((xKbdFeedbackCtl *) &stuff[1])->id)
453 return ChangeKbdFeedback(client, dev, stuff->mask, k,
454 (xKbdFeedbackCtl *) &stuff[1]);
455 break;
456 case PtrFeedbackClass:
457 if (len != bytes_to_int32(sizeof(xPtrFeedbackCtl)))
458 return BadLength;
459
460 for (p = dev->ptrfeed; p; p = p->next)
461 if (p->ctrl.id == ((xPtrFeedbackCtl *) &stuff[1])->id)
462 return ChangePtrFeedback(client, dev, stuff->mask, p,
463 (xPtrFeedbackCtl *) &stuff[1]);
464 break;
465 case StringFeedbackClass:
466 {
467 xStringFeedbackCtl *f = ((xStringFeedbackCtl *) &stuff[1]);
468
469 if (client->swapped) {
470 swaps(&f->num_keysyms);
471 }
472 if (len !=
473 (bytes_to_int32(sizeof(xStringFeedbackCtl)) + f->num_keysyms))
474 return BadLength;
475
476 for (s = dev->stringfeed; s; s = s->next)
477 if (s->ctrl.id == ((xStringFeedbackCtl *) &stuff[1])->id)
478 return ChangeStringFeedback(client, dev, stuff->mask, s,
479 (xStringFeedbackCtl *) &stuff[1]);
480 break;
481 }
482 case IntegerFeedbackClass:
483 if (len != bytes_to_int32(sizeof(xIntegerFeedbackCtl)))
484 return BadLength;
485
486 for (i = dev->intfeed; i; i = i->next)
487 if (i->ctrl.id == ((xIntegerFeedbackCtl *) &stuff[1])->id)
488 return ChangeIntegerFeedback(client, dev, stuff->mask, i,
489 (xIntegerFeedbackCtl *) &
490 stuff[1]);
491 break;
492 case LedFeedbackClass:
493 if (len != bytes_to_int32(sizeof(xLedFeedbackCtl)))
494 return BadLength;
495
496 for (l = dev->leds; l; l = l->next)
497 if (l->ctrl.id == ((xLedFeedbackCtl *) &stuff[1])->id)
498 return ChangeLedFeedback(client, dev, stuff->mask, l,
499 (xLedFeedbackCtl *) &stuff[1]);
500 break;
501 case BellFeedbackClass:
502 if (len != bytes_to_int32(sizeof(xBellFeedbackCtl)))
503 return BadLength;
504
505 for (b = dev->bell; b; b = b->next)
506 if (b->ctrl.id == ((xBellFeedbackCtl *) &stuff[1])->id)
507 return ChangeBellFeedback(client, dev, stuff->mask, b,
508 (xBellFeedbackCtl *) &stuff[1]);
509 break;
510 default:
511 break;
512 }
513
514 return BadMatch;
515}