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