XKBCtrls.c revision 818534a1
1/************************************************************
2Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
3
4Permission to use, copy, modify, and distribute this
5software and its documentation for any purpose and without
6fee is hereby granted, provided that the above copyright
7notice appear in all copies and that both that copyright
8notice and this permission notice appear in supporting
9documentation, and that the name of Silicon Graphics not be
10used in advertising or publicity pertaining to distribution
11of the software without specific prior written permission.
12Silicon Graphics makes no representation about the suitability
13of this software for any purpose. It is provided "as is"
14without any express or implied warranty.
15
16SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23THE 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
36static xkbSetControlsReq *
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
50Bool
51XkbSetAutoRepeatRate(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
71Bool
72XkbGetAutoRepeatRate(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
103Bool
104XkbSetServerInternalMods(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
128Bool
129XkbSetIgnoreLockMods(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
153Bool
154XkbChangeEnabledControls(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
174Status
175XkbGetControls(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
269Bool
270XkbSetControls(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
341void
342XkbNoteControlsChanges(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