XKBleds.c revision 1ab64890
1/* $Xorg: XKBleds.c,v 1.3 2000/08/17 19:45:03 cpqbld Exp $ */
2/************************************************************
3Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
4
5Permission to use, copy, modify, and distribute this
6software and its documentation for any purpose and without
7fee is hereby granted, provided that the above copyright
8notice appear in all copies and that both that copyright
9notice and this permission notice appear in supporting
10documentation, and that the name of Silicon Graphics not be
11used in advertising or publicity pertaining to distribution
12of the software without specific prior written permission.
13Silicon Graphics makes no representation about the suitability
14of this software for any purpose. It is provided "as is"
15without any express or implied warranty.
16
17SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
18SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
19AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
20GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
21DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
23OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
24THE USE OR PERFORMANCE OF THIS SOFTWARE.
25
26********************************************************/
27/* $XFree86: xc/lib/X11/XKBleds.c,v 1.4 2003/04/13 19:22:18 dawes Exp $ */
28
29#define NEED_REPLIES
30#define NEED_EVENTS
31#define NEED_MAP_READERS
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35#include "Xlibint.h"
36#include <X11/extensions/XKBproto.h>
37#include "XKBlibint.h"
38
39Status
40XkbGetIndicatorState(Display *dpy,unsigned deviceSpec,unsigned *pStateRtrn)
41{
42    register xkbGetIndicatorStateReq *req;
43    xkbGetIndicatorStateReply	rep;
44    XkbInfoPtr xkbi;
45    Bool ok;
46
47    if ((dpy->flags & XlibDisplayNoXkb) ||
48	(!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL)))
49	return BadAccess;
50    LockDisplay(dpy);
51    xkbi = dpy->xkb_info;
52    GetReq(kbGetIndicatorState, req);
53    req->reqType = xkbi->codes->major_opcode;
54    req->xkbReqType = X_kbGetIndicatorState;
55    req->deviceSpec = deviceSpec;
56    ok=_XReply(dpy, (xReply *)&rep, 0, xFalse);
57    if (ok && (pStateRtrn!=NULL))
58	*pStateRtrn= rep.state;
59    UnlockDisplay(dpy);
60    SyncHandle();
61    return (ok?Success:BadImplementation);
62}
63
64Status
65_XkbReadGetIndicatorMapReply(	Display *			dpy,
66				xkbGetIndicatorMapReply *	rep,
67				XkbDescPtr			xkb,
68				int	*			nread_rtrn)
69{
70XkbIndicatorPtr		leds;
71XkbReadBufferRec	buf;
72
73    if ((!xkb->indicators)&&(XkbAllocIndicatorMaps(xkb)!=Success))
74	return BadAlloc;
75    leds= xkb->indicators;
76
77    leds->phys_indicators = rep->realIndicators;
78    if (rep->length>0) {
79	register int left;
80	if (!_XkbInitReadBuffer(dpy,&buf,(int)rep->length*4))
81	    return BadAlloc;
82	if (nread_rtrn)
83	    *nread_rtrn= (int)rep->length*4;
84	if (rep->which) {
85	    register int i,bit;
86	    left= (int)rep->which;
87	    for (i=0,bit=1;(i<XkbNumIndicators)&&(left);i++,bit<<=1) {
88		if (left&bit) {
89		    xkbIndicatorMapWireDesc *wire;
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 req->on= False;
298    if (pMap!=NULL) {
299	req->setMap= True;
300	req->createMap= createNewMap;
301	req->flags= pMap->flags;
302	req->whichGroups= pMap->which_groups;
303	req->groups= pMap->groups;
304	req->whichMods= pMap->which_mods;
305	req->realMods= pMap->mods.real_mods;
306	req->virtualMods= pMap->mods.vmods;
307	req->ctrls= pMap->ctrls;
308    }
309    else {
310	req->setMap= 		False;
311	req->createMap= 	False;
312	req->flags= 		0;
313	req->whichGroups= 	0;
314	req->groups= 		0;
315	req->whichMods= 	0;
316	req->realMods= 		0;
317	req->virtualMods= 	0;
318	req->ctrls=		0;
319    }
320    UnlockDisplay(dpy);
321    SyncHandle();
322    return True;
323}
324
325Bool
326XkbSetNamedIndicator(	Display *		dpy,
327			Atom			name,
328			Bool			changeState,
329			Bool			state,
330			Bool			createNewMap,
331			XkbIndicatorMapPtr	pMap)
332{
333    return XkbSetNamedDeviceIndicator(dpy,XkbUseCoreKbd,
334					  XkbDfltXIClass,XkbDfltXIId,
335					  name,changeState,state,
336					  createNewMap,pMap);
337}
338