1 /************************************************************
2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
3 
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be
10 used in advertising or publicity pertaining to distribution
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
15 
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 
25 ********************************************************/
26 
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30 #include <stdio.h>
31 #include "Xlibint.h"
32 #include <X11/extensions/XKBproto.h>
33 #include "XKBlibint.h"
34 
35 
36 static xkbSetControlsReq *
_XkbGetSetControlsReq(Display * dpy,XkbInfoPtr xkbi,unsigned int deviceSpec)37 _XkbGetSetControlsReq(Display *dpy, XkbInfoPtr xkbi, unsigned int deviceSpec)
38 {
39     xkbSetControlsReq *req;
40 
41     GetReq(kbSetControls, req);
42     bzero(req, SIZEOF(xkbSetControlsReq));
43     req->reqType = xkbi->codes->major_opcode;
44     req->length = (SIZEOF(xkbSetControlsReq) >> 2);
45     req->xkbReqType = X_kbSetControls;
46     req->deviceSpec = deviceSpec;
47     return req;
48 }
49 
50 Bool
XkbSetAutoRepeatRate(Display * dpy,unsigned int deviceSpec,unsigned int timeout,unsigned int interval)51 XkbSetAutoRepeatRate(Display *dpy,
52                      unsigned int deviceSpec,
53                      unsigned int timeout,
54                      unsigned int interval)
55 {
56     register xkbSetControlsReq *req;
57 
58     if ((dpy->flags & XlibDisplayNoXkb) ||
59         (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
60         return False;
61     LockDisplay(dpy);
62     req = _XkbGetSetControlsReq(dpy, dpy->xkb_info, deviceSpec);
63     req->changeCtrls = XkbRepeatKeysMask;
64     req->repeatDelay = timeout;
65     req->repeatInterval = interval;
66     UnlockDisplay(dpy);
67     SyncHandle();
68     return True;
69 }
70 
71 Bool
XkbGetAutoRepeatRate(Display * dpy,unsigned int deviceSpec,unsigned int * timeoutp,unsigned int * intervalp)72 XkbGetAutoRepeatRate(Display *dpy,
73                      unsigned int deviceSpec,
74                      unsigned int *timeoutp,
75                      unsigned int *intervalp)
76 {
77     register xkbGetControlsReq *req;
78     xkbGetControlsReply rep;
79     XkbInfoPtr xkbi;
80 
81     if ((dpy->flags & XlibDisplayNoXkb) ||
82         (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
83         return False;
84     LockDisplay(dpy);
85     xkbi = dpy->xkb_info;
86     GetReq(kbGetControls, req);
87     req->reqType = xkbi->codes->major_opcode;
88     req->xkbReqType = X_kbGetControls;
89     req->deviceSpec = deviceSpec;
90     if (!_XReply(dpy, (xReply *) &rep,
91                  (SIZEOF(xkbGetControlsReply) - SIZEOF(xReply)) >> 2, xFalse)) {
92         UnlockDisplay(dpy);
93         SyncHandle();
94         return False;
95     }
96     UnlockDisplay(dpy);
97     SyncHandle();
98     *timeoutp = rep.repeatDelay;
99     *intervalp = rep.repeatInterval;
100     return True;
101 }
102 
103 Bool
XkbSetServerInternalMods(Display * dpy,unsigned deviceSpec,unsigned affectReal,unsigned realValues,unsigned affectVirtual,unsigned virtualValues)104 XkbSetServerInternalMods(Display *dpy,
105                          unsigned deviceSpec,
106                          unsigned affectReal,
107                          unsigned realValues,
108                          unsigned affectVirtual,
109                          unsigned virtualValues)
110 {
111     register xkbSetControlsReq *req;
112 
113     if ((dpy->flags & XlibDisplayNoXkb) ||
114         (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
115         return False;
116     LockDisplay(dpy);
117     req = _XkbGetSetControlsReq(dpy, dpy->xkb_info, deviceSpec);
118     req->affectInternalMods = affectReal;
119     req->internalMods = realValues;
120     req->affectInternalVMods = affectVirtual;
121     req->internalVMods = virtualValues;
122     req->changeCtrls = XkbInternalModsMask;
123     UnlockDisplay(dpy);
124     SyncHandle();
125     return True;
126 }
127 
128 Bool
XkbSetIgnoreLockMods(Display * dpy,unsigned int deviceSpec,unsigned affectReal,unsigned realValues,unsigned affectVirtual,unsigned virtualValues)129 XkbSetIgnoreLockMods(Display *dpy,
130                      unsigned int deviceSpec,
131                      unsigned affectReal,
132                      unsigned realValues,
133                      unsigned affectVirtual,
134                      unsigned virtualValues)
135 {
136     register xkbSetControlsReq *req;
137 
138     if ((dpy->flags & XlibDisplayNoXkb) ||
139         (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
140         return False;
141     LockDisplay(dpy);
142     req = _XkbGetSetControlsReq(dpy, dpy->xkb_info, deviceSpec);
143     req->affectIgnoreLockMods = affectReal;
144     req->ignoreLockMods = realValues;
145     req->affectIgnoreLockVMods = affectVirtual;
146     req->ignoreLockVMods = virtualValues;
147     req->changeCtrls = XkbIgnoreLockModsMask;
148     UnlockDisplay(dpy);
149     SyncHandle();
150     return True;
151 }
152 
153 Bool
XkbChangeEnabledControls(Display * dpy,unsigned deviceSpec,unsigned affect,unsigned values)154 XkbChangeEnabledControls(Display *dpy,
155                          unsigned deviceSpec,
156                          unsigned affect,
157                          unsigned values)
158 {
159     register xkbSetControlsReq *req;
160 
161     if ((dpy->flags & XlibDisplayNoXkb) ||
162         (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
163         return False;
164     LockDisplay(dpy);
165     req = _XkbGetSetControlsReq(dpy, dpy->xkb_info, deviceSpec);
166     req->affectEnabledCtrls = affect;
167     req->enabledCtrls = (affect & values);
168     req->changeCtrls = XkbControlsEnabledMask;
169     UnlockDisplay(dpy);
170     SyncHandle();
171     return True;
172 }
173 
174 Status
XkbGetControls(Display * dpy,unsigned long which,XkbDescPtr xkb)175 XkbGetControls(Display *dpy, unsigned long which, XkbDescPtr xkb)
176 {
177     register xkbGetControlsReq *req;
178     xkbGetControlsReply rep;
179     XkbControlsPtr ctrls;
180     XkbInfoPtr xkbi;
181 
182     if ((dpy->flags & XlibDisplayNoXkb) ||
183         (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
184         return BadAccess;
185     if ((!xkb) || (!which))
186         return BadMatch;
187 
188     LockDisplay(dpy);
189     xkbi = dpy->xkb_info;
190     GetReq(kbGetControls, req);
191     if (!xkb->ctrls) {
192         xkb->ctrls = _XkbTypedCalloc(1, XkbControlsRec);
193         if (!xkb->ctrls) {
194             UnlockDisplay(dpy);
195             SyncHandle();
196             return BadAlloc;
197         }
198     }
199     req->reqType = xkbi->codes->major_opcode;
200     req->xkbReqType = X_kbGetControls;
201     req->deviceSpec = xkb->device_spec;
202     if (!_XReply(dpy, (xReply *) &rep,
203                  (SIZEOF(xkbGetControlsReply) - SIZEOF(xReply)) >> 2, xFalse)) {
204         UnlockDisplay(dpy);
205         SyncHandle();
206         return BadImplementation;
207     }
208     if (xkb->device_spec == XkbUseCoreKbd)
209         xkb->device_spec = rep.deviceID;
210     ctrls = xkb->ctrls;
211     if (which & XkbControlsEnabledMask)
212         ctrls->enabled_ctrls = rep.enabledCtrls;
213     ctrls->num_groups = rep.numGroups;
214     if (which & XkbGroupsWrapMask)
215         ctrls->groups_wrap = rep.groupsWrap;
216     if (which & XkbInternalModsMask) {
217         ctrls->internal.mask = rep.internalMods;
218         ctrls->internal.real_mods = rep.internalRealMods;
219         ctrls->internal.vmods = rep.internalVMods;
220     }
221     if (which & XkbIgnoreLockModsMask) {
222         ctrls->ignore_lock.mask = rep.ignoreLockMods;
223         ctrls->ignore_lock.real_mods = rep.ignoreLockRealMods;
224         ctrls->ignore_lock.vmods = rep.ignoreLockVMods;
225     }
226     if (which & XkbRepeatKeysMask) {
227         ctrls->repeat_delay = rep.repeatDelay;
228         ctrls->repeat_interval = rep.repeatInterval;
229     }
230     if (which & XkbSlowKeysMask)
231         ctrls->slow_keys_delay = rep.slowKeysDelay;
232     if (which & XkbBounceKeysMask)
233         ctrls->debounce_delay = rep.debounceDelay;
234     if (which & XkbMouseKeysMask) {
235         ctrls->mk_dflt_btn = rep.mkDfltBtn;
236     }
237     if (which & XkbMouseKeysAccelMask) {
238         ctrls->mk_delay = rep.mkDelay;
239         ctrls->mk_interval = rep.mkInterval;
240         ctrls->mk_time_to_max = rep.mkTimeToMax;
241         ctrls->mk_max_speed = rep.mkMaxSpeed;
242         ctrls->mk_curve = rep.mkCurve;
243     }
244     if (which & XkbAccessXKeysMask)
245         ctrls->ax_options = rep.axOptions;
246     if (which & XkbStickyKeysMask) {
247         ctrls->ax_options &= ~XkbAX_SKOptionsMask;
248         ctrls->ax_options |= rep.axOptions & XkbAX_SKOptionsMask;
249     }
250     if (which & XkbAccessXFeedbackMask) {
251         ctrls->ax_options &= ~XkbAX_FBOptionsMask;
252         ctrls->ax_options |= rep.axOptions & XkbAX_FBOptionsMask;
253     }
254     if (which & XkbAccessXTimeoutMask) {
255         ctrls->ax_timeout = rep.axTimeout;
256         ctrls->axt_ctrls_mask = rep.axtCtrlsMask;
257         ctrls->axt_ctrls_values = rep.axtCtrlsValues;
258         ctrls->axt_opts_mask = rep.axtOptsMask;
259         ctrls->axt_opts_values = rep.axtOptsValues;
260     }
261     if (which & XkbPerKeyRepeatMask) {
262         memcpy(ctrls->per_key_repeat, rep.perKeyRepeat, XkbPerKeyBitArraySize);
263     }
264     UnlockDisplay(dpy);
265     SyncHandle();
266     return Success;
267 }
268 
269 Bool
XkbSetControls(Display * dpy,unsigned long which,XkbDescPtr xkb)270 XkbSetControls(Display *dpy, unsigned long which, XkbDescPtr xkb)
271 {
272     register xkbSetControlsReq *req;
273     XkbControlsPtr ctrls;
274 
275     if ((dpy->flags & XlibDisplayNoXkb) ||
276         (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
277         return False;
278     if ((!xkb) || (!xkb->ctrls))
279         return False;
280 
281     ctrls = xkb->ctrls;
282     LockDisplay(dpy);
283     req = _XkbGetSetControlsReq(dpy, dpy->xkb_info, xkb->device_spec);
284     req->changeCtrls = (CARD32) which;
285     if (which & XkbInternalModsMask) {
286         req->affectInternalMods = ~0;
287         req->internalMods = ctrls->internal.real_mods;
288         req->affectInternalVMods = ~0;
289         req->internalVMods = ctrls->internal.vmods;
290     }
291     if (which & XkbIgnoreLockModsMask) {
292         req->affectIgnoreLockMods = ~0;
293         req->ignoreLockMods = ctrls->ignore_lock.real_mods;
294         req->affectIgnoreLockVMods = ~0;
295         req->ignoreLockVMods = ctrls->ignore_lock.vmods;
296     }
297     if (which & XkbControlsEnabledMask) {
298         req->affectEnabledCtrls = XkbAllBooleanCtrlsMask;
299         req->enabledCtrls = ctrls->enabled_ctrls;
300     }
301     if (which & XkbRepeatKeysMask) {
302         req->repeatDelay = ctrls->repeat_delay;
303         req->repeatInterval = ctrls->repeat_interval;
304     }
305     if (which & XkbSlowKeysMask)
306         req->slowKeysDelay = ctrls->slow_keys_delay;
307     if (which & XkbBounceKeysMask)
308         req->debounceDelay = ctrls->debounce_delay;
309     if (which & XkbMouseKeysMask) {
310         req->mkDfltBtn = ctrls->mk_dflt_btn;
311     }
312     if (which & XkbGroupsWrapMask)
313         req->groupsWrap = ctrls->groups_wrap;
314     if (which &
315         (XkbAccessXKeysMask | XkbStickyKeysMask | XkbAccessXFeedbackMask))
316         req->axOptions = ctrls->ax_options;
317     if (which & XkbMouseKeysAccelMask) {
318         req->mkDelay = ctrls->mk_delay;
319         req->mkInterval = ctrls->mk_interval;
320         req->mkTimeToMax = ctrls->mk_time_to_max;
321         req->mkMaxSpeed = ctrls->mk_max_speed;
322         req->mkCurve = ctrls->mk_curve;
323     }
324     if (which & XkbAccessXTimeoutMask) {
325         req->axTimeout = ctrls->ax_timeout;
326         req->axtCtrlsMask = ctrls->axt_ctrls_mask;
327         req->axtCtrlsValues = ctrls->axt_ctrls_values;
328         req->axtOptsMask = ctrls->axt_opts_mask;
329         req->axtOptsValues = ctrls->axt_opts_values;
330     }
331     if (which & XkbPerKeyRepeatMask) {
332         memcpy(req->perKeyRepeat, ctrls->per_key_repeat, XkbPerKeyBitArraySize);
333     }
334     UnlockDisplay(dpy);
335     SyncHandle();
336     return True;
337 }
338 
339 /***====================================================================***/
340 
341 void
XkbNoteControlsChanges(XkbControlsChangesPtr old,XkbControlsNotifyEvent * new,unsigned int wanted)342 XkbNoteControlsChanges(XkbControlsChangesPtr old,
343                        XkbControlsNotifyEvent *new,
344                        unsigned int wanted)
345 {
346     old->changed_ctrls |= (new->changed_ctrls & wanted);
347     if (new->changed_ctrls & XkbControlsEnabledMask & wanted)
348         old->enabled_ctrls_changes ^= new->enabled_ctrl_changes;
349     /* num_groups_changed?? */
350     return;
351 }
352