XKBleds.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#define NEED_MAP_READERS
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include "Xlibint.h"
32#include <X11/extensions/XKBproto.h>
33#include "XKBlibint.h"
34
35Status
36XkbGetIndicatorState(Display *dpy, unsigned deviceSpec, unsigned *pStateRtrn)
37{
38    register xkbGetIndicatorStateReq *req;
39    xkbGetIndicatorStateReply rep;
40    XkbInfoPtr xkbi;
41    Bool ok;
42
43    if ((dpy->flags & XlibDisplayNoXkb) ||
44        (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
45        return BadAccess;
46    LockDisplay(dpy);
47    xkbi = dpy->xkb_info;
48    GetReq(kbGetIndicatorState, req);
49    req->reqType = xkbi->codes->major_opcode;
50    req->xkbReqType = X_kbGetIndicatorState;
51    req->deviceSpec = deviceSpec;
52    ok = _XReply(dpy, (xReply *) &rep, 0, xFalse);
53    if (ok && (pStateRtrn != NULL))
54        *pStateRtrn = rep.state;
55    UnlockDisplay(dpy);
56    SyncHandle();
57    return (ok ? Success : BadImplementation);
58}
59
60Status
61_XkbReadGetIndicatorMapReply(Display *dpy,
62                             xkbGetIndicatorMapReply *rep,
63                             XkbDescPtr xkb,
64                             int *nread_rtrn)
65{
66    XkbIndicatorPtr leds;
67    XkbReadBufferRec buf;
68
69    if ((!xkb->indicators) && (XkbAllocIndicatorMaps(xkb) != Success))
70        return BadAlloc;
71    leds = xkb->indicators;
72
73    leds->phys_indicators = rep->realIndicators;
74    if (rep->length > 0) {
75        register int left;
76
77        if (!_XkbInitReadBuffer(dpy, &buf, (int) rep->length * 4))
78            return BadAlloc;
79        if (nread_rtrn)
80            *nread_rtrn = (int) rep->length * 4;
81        if (rep->which) {
82            register int i, bit;
83
84            left = (int) rep->which;
85            for (i = 0, bit = 1; (i < XkbNumIndicators) && (left);
86                 i++, bit <<= 1) {
87                if (left & bit) {
88                    xkbIndicatorMapWireDesc *wire;
89
90                    wire = (xkbIndicatorMapWireDesc *)
91                        _XkbGetReadBufferPtr(&buf,
92                                             SIZEOF(xkbIndicatorMapWireDesc));
93                    if (wire == NULL) {
94                        _XkbFreeReadBuffer(&buf);
95                        return BadAlloc;
96                    }
97                    leds->maps[i].flags = wire->flags;
98                    leds->maps[i].which_groups = wire->whichGroups;
99                    leds->maps[i].groups = wire->groups;
100                    leds->maps[i].which_mods = wire->whichMods;
101                    leds->maps[i].mods.mask = wire->mods;
102                    leds->maps[i].mods.real_mods = wire->realMods;
103                    leds->maps[i].mods.vmods = wire->virtualMods;
104                    leds->maps[i].ctrls = wire->ctrls;
105                    left &= ~bit;
106                }
107            }
108        }
109        left = _XkbFreeReadBuffer(&buf);
110    }
111    return Success;
112}
113
114Bool
115XkbGetIndicatorMap(Display *dpy, unsigned long which, XkbDescPtr xkb)
116{
117    register xkbGetIndicatorMapReq *req;
118    xkbGetIndicatorMapReply rep;
119    XkbInfoPtr xkbi;
120    Status status;
121
122    if ((dpy->flags & XlibDisplayNoXkb) ||
123        (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
124        return BadAccess;
125    if ((!which) || (!xkb))
126        return BadValue;
127
128    LockDisplay(dpy);
129    xkbi = dpy->xkb_info;
130    if (!xkb->indicators) {
131        xkb->indicators = _XkbTypedCalloc(1, XkbIndicatorRec);
132        if (!xkb->indicators) {
133            UnlockDisplay(dpy);
134            SyncHandle();
135            return BadAlloc;
136        }
137    }
138    GetReq(kbGetIndicatorMap, req);
139    req->reqType = xkbi->codes->major_opcode;
140    req->xkbReqType = X_kbGetIndicatorMap;
141    req->deviceSpec = xkb->device_spec;
142    req->which = (CARD32) which;
143    if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
144        UnlockDisplay(dpy);
145        SyncHandle();
146        return BadValue;
147    }
148    status = _XkbReadGetIndicatorMapReply(dpy, &rep, xkb, NULL);
149    UnlockDisplay(dpy);
150    SyncHandle();
151    return status;
152}
153
154Bool
155XkbSetIndicatorMap(Display *dpy, unsigned long which, XkbDescPtr xkb)
156{
157    register xkbSetIndicatorMapReq *req;
158    register int i, bit;
159    int nMaps;
160    xkbIndicatorMapWireDesc *wire;
161    XkbInfoPtr xkbi;
162
163    if ((dpy->flags & XlibDisplayNoXkb) ||
164        (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
165        return False;
166    if ((!xkb) || (!which) || (!xkb->indicators))
167        return False;
168    LockDisplay(dpy);
169    xkbi = dpy->xkb_info;
170    GetReq(kbSetIndicatorMap, req);
171    req->reqType = xkbi->codes->major_opcode;
172    req->xkbReqType = X_kbSetIndicatorMap;
173    req->deviceSpec = xkb->device_spec;
174    req->which = (CARD32) which;
175    for (i = nMaps = 0, bit = 1; i < 32; i++, bit <<= 1) {
176        if (which & bit)
177            nMaps++;
178    }
179    req->length += (nMaps * sizeof(XkbIndicatorMapRec)) / 4;
180    BufAlloc(xkbIndicatorMapWireDesc *, wire,
181             (nMaps * SIZEOF(xkbIndicatorMapWireDesc)));
182    for (i = 0, bit = 1; i < 32; i++, bit <<= 1) {
183        if (which & bit) {
184            wire->flags = xkb->indicators->maps[i].flags;
185            wire->whichGroups = xkb->indicators->maps[i].which_groups;
186            wire->groups = xkb->indicators->maps[i].groups;
187            wire->whichMods = xkb->indicators->maps[i].which_mods;
188            wire->mods = xkb->indicators->maps[i].mods.real_mods;
189            wire->virtualMods = xkb->indicators->maps[i].mods.vmods;
190            wire->ctrls = xkb->indicators->maps[i].ctrls;
191            wire++;
192        }
193    }
194    UnlockDisplay(dpy);
195    SyncHandle();
196    return True;
197}
198
199Bool
200XkbGetNamedDeviceIndicator(Display *dpy,
201                           unsigned device,
202                           unsigned class,
203                           unsigned id,
204                           Atom name,
205                           int *pNdxRtrn,
206                           Bool *pStateRtrn,
207                           XkbIndicatorMapPtr pMapRtrn,
208                           Bool *pRealRtrn)
209{
210    register xkbGetNamedIndicatorReq *req;
211    xkbGetNamedIndicatorReply rep;
212    XkbInfoPtr xkbi;
213
214    if ((dpy->flags & XlibDisplayNoXkb) || (name == None) ||
215        (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
216        return False;
217    LockDisplay(dpy);
218    xkbi = dpy->xkb_info;
219    GetReq(kbGetNamedIndicator, req);
220    req->reqType = xkbi->codes->major_opcode;
221    req->xkbReqType = X_kbGetNamedIndicator;
222    req->deviceSpec = device;
223    req->ledClass = class;
224    req->ledID = id;
225    req->indicator = (CARD32) name;
226    if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
227        UnlockDisplay(dpy);
228        SyncHandle();
229        return False;
230    }
231    UnlockDisplay(dpy);
232    SyncHandle();
233    if ((!rep.found) || (!rep.supported))
234        return False;
235    if (pNdxRtrn != NULL)
236        *pNdxRtrn = rep.ndx;
237    if (pStateRtrn != NULL)
238        *pStateRtrn = rep.on;
239    if (pMapRtrn != NULL) {
240        pMapRtrn->flags = rep.flags;
241        pMapRtrn->which_groups = rep.whichGroups;
242        pMapRtrn->groups = rep.groups;
243        pMapRtrn->which_mods = rep.whichMods;
244        pMapRtrn->mods.mask = rep.mods;
245        pMapRtrn->mods.real_mods = rep.realMods;
246        pMapRtrn->mods.vmods = rep.virtualMods;
247        pMapRtrn->ctrls = rep.ctrls;
248    }
249    if (pRealRtrn != NULL)
250        *pRealRtrn = rep.realIndicator;
251    return True;
252}
253
254Bool
255XkbGetNamedIndicator(Display *dpy,
256                     Atom name,
257                     int *pNdxRtrn,
258                     Bool *pStateRtrn,
259                     XkbIndicatorMapPtr pMapRtrn,
260                     Bool *pRealRtrn)
261{
262    return XkbGetNamedDeviceIndicator(dpy, XkbUseCoreKbd,
263                                      XkbDfltXIClass, XkbDfltXIId,
264                                      name, pNdxRtrn, pStateRtrn,
265                                      pMapRtrn, pRealRtrn);
266}
267
268Bool
269XkbSetNamedDeviceIndicator(Display *dpy,
270                           unsigned device,
271                           unsigned class,
272                           unsigned id,
273                           Atom name,
274                           Bool changeState,
275                           Bool state,
276                           Bool createNewMap,
277                           XkbIndicatorMapPtr pMap)
278{
279    register xkbSetNamedIndicatorReq *req;
280    XkbInfoPtr xkbi;
281
282    if ((dpy->flags & XlibDisplayNoXkb) || (name == None) ||
283        (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
284        return False;
285    LockDisplay(dpy);
286    xkbi = dpy->xkb_info;
287    GetReq(kbSetNamedIndicator, req);
288    req->reqType = xkbi->codes->major_opcode;
289    req->xkbReqType = X_kbSetNamedIndicator;
290    req->deviceSpec = device;
291    req->ledClass = class;
292    req->ledID = id;
293    req->indicator = (CARD32) name;
294    req->setState = changeState;
295    if (req->setState)
296        req->on = state;
297    else
298        req->on = False;
299    if (pMap != NULL) {
300        req->setMap = True;
301        req->createMap = createNewMap;
302        req->flags = pMap->flags;
303        req->whichGroups = pMap->which_groups;
304        req->groups = pMap->groups;
305        req->whichMods = pMap->which_mods;
306        req->realMods = pMap->mods.real_mods;
307        req->virtualMods = pMap->mods.vmods;
308        req->ctrls = pMap->ctrls;
309    }
310    else {
311        req->setMap = False;
312        req->createMap = False;
313        req->flags = 0;
314        req->whichGroups = 0;
315        req->groups = 0;
316        req->whichMods = 0;
317        req->realMods = 0;
318        req->virtualMods = 0;
319        req->ctrls = 0;
320    }
321    UnlockDisplay(dpy);
322    SyncHandle();
323    return True;
324}
325
326Bool
327XkbSetNamedIndicator(Display *dpy,
328                     Atom name,
329                     Bool changeState,
330                     Bool state,
331                     Bool createNewMap,
332                     XkbIndicatorMapPtr pMap)
333{
334    return XkbSetNamedDeviceIndicator(dpy, XkbUseCoreKbd,
335                                      XkbDfltXIClass, XkbDfltXIId,
336                                      name, changeState, state,
337                                      createNewMap, pMap);
338}
339