XKBleds.c revision b4ee4795
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_REPLIES
28#define NEED_EVENTS
29#define NEED_MAP_READERS
30#ifdef HAVE_CONFIG_H
31#include <config.h>
32#endif
33#include "Xlibint.h"
34#include <X11/extensions/XKBproto.h>
35#include "XKBlibint.h"
36
37Status
38XkbGetIndicatorState(Display *dpy,unsigned deviceSpec,unsigned *pStateRtrn)
39{
40    register xkbGetIndicatorStateReq *req;
41    xkbGetIndicatorStateReply	rep;
42    XkbInfoPtr xkbi;
43    Bool ok;
44
45    if ((dpy->flags & XlibDisplayNoXkb) ||
46	(!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
47	return BadAccess;
48    LockDisplay(dpy);
49    xkbi = dpy->xkb_info;
50    GetReq(kbGetIndicatorState, req);
51    req->reqType = xkbi->codes->major_opcode;
52    req->xkbReqType = X_kbGetIndicatorState;
53    req->deviceSpec = deviceSpec;
54    ok=_XReply(dpy, (xReply *)&rep, 0, xFalse);
55    if (ok && (pStateRtrn!=NULL))
56	*pStateRtrn= rep.state;
57    UnlockDisplay(dpy);
58    SyncHandle();
59    return (ok?Success:BadImplementation);
60}
61
62Status
63_XkbReadGetIndicatorMapReply(	Display *			dpy,
64				xkbGetIndicatorMapReply *	rep,
65				XkbDescPtr			xkb,
66				int	*			nread_rtrn)
67{
68XkbIndicatorPtr		leds;
69XkbReadBufferRec	buf;
70
71    if ((!xkb->indicators)&&(XkbAllocIndicatorMaps(xkb)!=Success))
72	return BadAlloc;
73    leds= xkb->indicators;
74
75    leds->phys_indicators = rep->realIndicators;
76    if (rep->length>0) {
77	register int left;
78	if (!_XkbInitReadBuffer(dpy,&buf,(int)rep->length*4))
79	    return BadAlloc;
80	if (nread_rtrn)
81	    *nread_rtrn= (int)rep->length*4;
82	if (rep->which) {
83	    register int i,bit;
84	    left= (int)rep->which;
85	    for (i=0,bit=1;(i<XkbNumIndicators)&&(left);i++,bit<<=1) {
86		if (left&bit) {
87		    xkbIndicatorMapWireDesc *wire;
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	left= _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 req->on= False;
296    if (pMap!=NULL) {
297	req->setMap= True;
298	req->createMap= createNewMap;
299	req->flags= pMap->flags;
300	req->whichGroups= pMap->which_groups;
301	req->groups= pMap->groups;
302	req->whichMods= pMap->which_mods;
303	req->realMods= pMap->mods.real_mods;
304	req->virtualMods= pMap->mods.vmods;
305	req->ctrls= pMap->ctrls;
306    }
307    else {
308	req->setMap= 		False;
309	req->createMap= 	False;
310	req->flags= 		0;
311	req->whichGroups= 	0;
312	req->groups= 		0;
313	req->whichMods= 	0;
314	req->realMods= 		0;
315	req->virtualMods= 	0;
316	req->ctrls=		0;
317    }
318    UnlockDisplay(dpy);
319    SyncHandle();
320    return True;
321}
322
323Bool
324XkbSetNamedIndicator(	Display *		dpy,
325			Atom			name,
326			Bool			changeState,
327			Bool			state,
328			Bool			createNewMap,
329			XkbIndicatorMapPtr	pMap)
330{
331    return XkbSetNamedDeviceIndicator(dpy,XkbUseCoreKbd,
332					  XkbDfltXIClass,XkbDfltXIId,
333					  name,changeState,state,
334					  createNewMap,pMap);
335}
336