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
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.
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
45 ********************************************************/
47 /********************************************************************
49 * Change feedback control attributes for an extension device.
53 #define NEED_EVENTS /* for inputstr.h */
55 #ifdef HAVE_DIX_CONFIG_H
56 #include <dix-config.h>
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"
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.
81 SProcXChangeFeedbackControl(ClientPtr client
)
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.
99 ChangeKbdFeedback(ClientPtr client
, DeviceIntPtr dev
, long unsigned int mask
,
100 KbdFeedbackPtr k
, xKbdFeedbackCtl
* f
)
107 if (client
->swapped
) {
108 swaps(&f
->length
, n
);
110 swaps(&f
->duration
, n
);
111 swapl(&f
->led_mask
, n
);
112 swapl(&f
->led_values
, n
);
116 if (mask
& DvKeyClickPercent
) {
119 t
= defaultKeyboardControl
.click
;
120 else if (t
< 0 || t
> 100) {
121 client
->errorValue
= t
;
122 SendErrorToClient(client
, IReqCode
, X_ChangeFeedbackControl
, 0,
129 if (mask
& DvPercent
) {
132 t
= defaultKeyboardControl
.bell
;
133 else if (t
< 0 || t
> 100) {
134 client
->errorValue
= t
;
135 SendErrorToClient(client
, IReqCode
, X_ChangeFeedbackControl
, 0,
142 if (mask
& DvPitch
) {
145 t
= defaultKeyboardControl
.bell_pitch
;
147 client
->errorValue
= t
;
148 SendErrorToClient(client
, IReqCode
, X_ChangeFeedbackControl
, 0,
152 kctrl
.bell_pitch
= t
;
155 if (mask
& DvDuration
) {
158 t
= defaultKeyboardControl
.bell_duration
;
160 client
->errorValue
= t
;
161 SendErrorToClient(client
, IReqCode
, X_ChangeFeedbackControl
, 0,
165 kctrl
.bell_duration
= t
;
169 kctrl
.leds
&= ~(f
->led_mask
);
170 kctrl
.leds
|= (f
->led_mask
& f
->led_values
);
174 key
= (KeyCode
) f
->key
;
175 if (key
< 8 || key
> 255) {
176 client
->errorValue
= key
;
177 SendErrorToClient(client
, IReqCode
, X_ChangeFeedbackControl
, 0,
181 if (!(mask
& DvAutoRepeatMode
)) {
182 SendErrorToClient(client
, IReqCode
, X_ChangeFeedbackControl
, 0,
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
) {
195 kctrl
.autoRepeat
= FALSE
;
197 kctrl
.autoRepeats
[inx
] &= ~kmask
;
198 } else if (t
== AutoRepeatModeOn
) {
200 kctrl
.autoRepeat
= TRUE
;
202 kctrl
.autoRepeats
[inx
] |= kmask
;
203 } else if (t
== AutoRepeatModeDefault
) {
205 kctrl
.autoRepeat
= defaultKeyboardControl
.autoRepeat
;
207 kctrl
.autoRepeats
[inx
] &= ~kmask
;
208 kctrl
.autoRepeats
[inx
] =
209 (kctrl
.autoRepeats
[inx
] & ~kmask
) |
210 (defaultKeyboardControl
.autoRepeats
[inx
] & kmask
);
212 client
->errorValue
= t
;
213 SendErrorToClient(client
, IReqCode
, X_ChangeFeedbackControl
, 0,
220 (*k
->CtrlProc
) (dev
, &k
->ctrl
);
224 /******************************************************************************
226 * This procedure changes PtrFeedbackClass data.
231 ChangePtrFeedback(ClientPtr client
, DeviceIntPtr dev
, long unsigned int mask
,
232 PtrFeedbackPtr p
, xPtrFeedbackCtl
* f
)
235 PtrCtrl pctrl
; /* might get BadValue part way through */
237 if (client
->swapped
) {
238 swaps(&f
->length
, n
);
241 swaps(&f
->thresh
, n
);
245 if (mask
& DvAccelNum
) {
250 pctrl
.num
= defaultPointerControl
.num
;
251 else if (accelNum
< 0) {
252 client
->errorValue
= accelNum
;
253 SendErrorToClient(client
, IReqCode
, X_ChangeFeedbackControl
, 0,
257 pctrl
.num
= accelNum
;
260 if (mask
& DvAccelDenom
) {
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,
272 pctrl
.den
= accelDenom
;
275 if (mask
& DvThreshold
) {
278 threshold
= f
->thresh
;
280 pctrl
.threshold
= defaultPointerControl
.threshold
;
281 else if (threshold
< 0) {
282 client
->errorValue
= threshold
;
283 SendErrorToClient(client
, IReqCode
, X_ChangeFeedbackControl
, 0,
287 pctrl
.threshold
= threshold
;
291 (*p
->CtrlProc
) (dev
, &p
->ctrl
);
295 /******************************************************************************
297 * This procedure changes IntegerFeedbackClass data.
302 ChangeIntegerFeedback(ClientPtr client
, DeviceIntPtr dev
,
303 long unsigned int mask
, IntegerFeedbackPtr i
,
304 xIntegerFeedbackCtl
* f
)
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
);
318 /******************************************************************************
320 * This procedure changes StringFeedbackClass data.
325 ChangeStringFeedback(ClientPtr client
, DeviceIntPtr dev
,
326 long unsigned int mask
, StringFeedbackPtr s
,
327 xStringFeedbackCtl
* f
)
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 */
338 for (i
= 0; i
< f
->num_keysyms
; i
++) {
344 if (f
->num_keysyms
> s
->ctrl
.max_symbols
) {
345 SendErrorToClient(client
, IReqCode
, X_ChangeFeedbackControl
, 0,
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
))
354 if (j
== s
->ctrl
.num_symbols_supported
) {
355 SendErrorToClient(client
, IReqCode
, X_ChangeFeedbackControl
, 0,
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
);
368 /******************************************************************************
370 * This procedure changes BellFeedbackClass data.
375 ChangeBellFeedback(ClientPtr client
, DeviceIntPtr dev
,
376 long unsigned int mask
, BellFeedbackPtr b
,
377 xBellFeedbackCtl
* f
)
381 BellCtrl bctrl
; /* might get BadValue part way through */
383 if (client
->swapped
) {
384 swaps(&f
->length
, n
);
386 swaps(&f
->duration
, n
);
390 if (mask
& DvPercent
) {
393 t
= defaultKeyboardControl
.bell
;
394 else if (t
< 0 || t
> 100) {
395 client
->errorValue
= t
;
396 SendErrorToClient(client
, IReqCode
, X_ChangeFeedbackControl
, 0,
403 if (mask
& DvPitch
) {
406 t
= defaultKeyboardControl
.bell_pitch
;
408 client
->errorValue
= t
;
409 SendErrorToClient(client
, IReqCode
, X_ChangeFeedbackControl
, 0,
416 if (mask
& DvDuration
) {
419 t
= defaultKeyboardControl
.bell_duration
;
421 client
->errorValue
= t
;
422 SendErrorToClient(client
, IReqCode
, X_ChangeFeedbackControl
, 0,
429 (*b
->CtrlProc
) (dev
, &b
->ctrl
);
433 /******************************************************************************
435 * This procedure changes LedFeedbackClass data.
440 ChangeLedFeedback(ClientPtr client
, DeviceIntPtr dev
, long unsigned int mask
,
441 LedFeedbackPtr l
, xLedFeedbackCtl
* f
)
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 */
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 */
465 /***********************************************************************
467 * Change the control attributes.
472 ProcXChangeFeedbackControl(ClientPtr client
)
478 IntegerFeedbackPtr i
;
483 REQUEST(xChangeFeedbackControlReq
);
484 REQUEST_AT_LEAST_SIZE(xChangeFeedbackControlReq
);
486 len
= stuff
->length
- (sizeof(xChangeFeedbackControlReq
) >> 2);
487 dev
= LookupDeviceIntRec(stuff
->deviceid
);
489 SendErrorToClient(client
, IReqCode
, X_ChangeFeedbackControl
, 0,
494 switch (stuff
->feedbackid
) {
495 case KbdFeedbackClass
:
496 if (len
!= (sizeof(xKbdFeedbackCtl
) >> 2)) {
497 SendErrorToClient(client
, IReqCode
, X_ChangeFeedbackControl
,
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]);
508 case PtrFeedbackClass
:
509 if (len
!= (sizeof(xPtrFeedbackCtl
) >> 2)) {
510 SendErrorToClient(client
, IReqCode
, X_ChangeFeedbackControl
,
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]);
521 case StringFeedbackClass
:
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
,
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]);
542 case IntegerFeedbackClass
:
543 if (len
!= (sizeof(xIntegerFeedbackCtl
) >> 2)) {
544 SendErrorToClient(client
, IReqCode
, X_ChangeFeedbackControl
,
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]);
555 case LedFeedbackClass
:
556 if (len
!= (sizeof(xLedFeedbackCtl
) >> 2)) {
557 SendErrorToClient(client
, IReqCode
, X_ChangeFeedbackControl
,
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]);
568 case BellFeedbackClass
:
569 if (len
!= (sizeof(xBellFeedbackCtl
) >> 2)) {
570 SendErrorToClient(client
, IReqCode
, X_ChangeFeedbackControl
,
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]);
585 SendErrorToClient(client
, IReqCode
, X_ChangeFeedbackControl
, 0, BadMatch
);