xkbvleds.c revision 010cdda0
1010cdda0Smrg/* $Xorg: xkbvleds.c,v 1.4 2000/08/17 19:54:51 cpqbld Exp $ */
2010cdda0Smrg/************************************************************
3010cdda0Smrg Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
4010cdda0Smrg
5010cdda0Smrg Permission to use, copy, modify, and distribute this
6010cdda0Smrg software and its documentation for any purpose and without
7010cdda0Smrg fee is hereby granted, provided that the above copyright
8010cdda0Smrg notice appear in all copies and that both that copyright
9010cdda0Smrg notice and this permission notice appear in supporting
10010cdda0Smrg documentation, and that the name of Silicon Graphics not be
11010cdda0Smrg used in advertising or publicity pertaining to distribution
12010cdda0Smrg of the software without specific prior written permission.
13010cdda0Smrg Silicon Graphics makes no representation about the suitability
14010cdda0Smrg of this software for any purpose. It is provided "as is"
15010cdda0Smrg without any express or implied warranty.
16010cdda0Smrg
17010cdda0Smrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
18010cdda0Smrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
19010cdda0Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
20010cdda0Smrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
21010cdda0Smrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22010cdda0Smrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
23010cdda0Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
24010cdda0Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE.
25010cdda0Smrg
26010cdda0Smrg ********************************************************/
27010cdda0Smrg/* $XFree86: xc/programs/xkbutils/xkbvleds.c,v 3.4 2001/01/17 23:46:14 dawes Exp $ */
28010cdda0Smrg
29010cdda0Smrg#include <stdlib.h>
30010cdda0Smrg#include <X11/X.h>
31010cdda0Smrg#include <X11/Xlib.h>
32010cdda0Smrg#include <X11/XKBlib.h>
33010cdda0Smrg#include <X11/Intrinsic.h>
34010cdda0Smrg#include <X11/StringDefs.h>
35010cdda0Smrg#include <X11/Shell.h>
36010cdda0Smrg#include <X11/Xaw/Cardinals.h>
37010cdda0Smrg#include <X11/Xaw/Box.h>
38010cdda0Smrg
39010cdda0Smrg#define	OPAQUE_DEFINED
40010cdda0Smrg#define	BOOLEAN_DEFINED
41010cdda0Smrg#define	DEBUG_VAR_NOT_LOCAL
42010cdda0Smrg#define	DEBUG_VAR debugFlags
43010cdda0Smrg#include "utils.h"
44010cdda0Smrg#include "LED.h"
45010cdda0Smrg
46010cdda0Smrg/***====================================================================***/
47010cdda0Smrg
48010cdda0Smrg#define	YES		1
49010cdda0Smrg#define	NO		0
50010cdda0Smrg#define	DONT_CARE	-1
51010cdda0Smrg
52010cdda0Smrg	Display *	inDpy,*outDpy;
53010cdda0Smrgstatic	unsigned long	wanted,real,named,explicit,automatic,virtual;
54010cdda0Smrgstatic	char *		inDpyName;
55010cdda0Smrg	int		wantNamed= DONT_CARE;
56010cdda0Smrg	int		wantExplicit= DONT_CARE;
57010cdda0Smrg	int		wantAutomatic= DONT_CARE;
58010cdda0Smrg	int		wantReal= DONT_CARE;
59010cdda0Smrg	int		wantVirtual= DONT_CARE;
60010cdda0Smrg	int		evBase,errBase;
61010cdda0Smrg	Bool		synch;
62010cdda0Smrg	Bool		useUnion= True;
63010cdda0Smrg
64010cdda0Smrg/***====================================================================***/
65010cdda0Smrg
66010cdda0Smrgstatic void
67010cdda0Smrgusage(char *program)
68010cdda0Smrg{
69010cdda0Smrg    uInformation("Usage: %s <options>\n",program);
70010cdda0Smrg    uInformation("Legal options include the usual X toolkit options plus:\n");
71010cdda0Smrg    uInformation("  -help           Print this message\n");
72010cdda0Smrg    uInformation("  -indpy <name>   Name of display to watch\n");
73010cdda0Smrg    uInformation("  -watch <leds>   Mask of LEDs to watch\n");
74010cdda0Smrg    uInformation("  [-+]automatic   (Don't) watch automatic LEDs\n");
75010cdda0Smrg    uInformation("  [-+]explicit    (Don't) watch explicit LEDs\n");
76010cdda0Smrg    uInformation("  [-+]name        (Don't) watch named LEDs\n");
77010cdda0Smrg    uInformation("  [-+]real        (Don't) watch real LEDs\n");
78010cdda0Smrg    uInformation("  [-+]virtual     (Don't) watch virtual LEDs\n");
79010cdda0Smrg    uInformation("  -intersection   Watch only LEDs in all desired sets\n");
80010cdda0Smrg    uInformation("  -union          Watch LEDs in any desired sets\n");
81010cdda0Smrg    uInformation("The default set of LEDs is -union +name +automatic +real\n");
82010cdda0Smrg    return;
83010cdda0Smrg}
84010cdda0Smrg
85010cdda0Smrgstatic Bool
86010cdda0SmrgparseArgs(int argc, char *argv[])
87010cdda0Smrg{
88010cdda0Smrgregister int 	i;
89010cdda0Smrg
90010cdda0Smrg    for (i=1;i<argc;i++) {
91010cdda0Smrg	if (uStrCaseEqual(argv[i],"-indpy")) {
92010cdda0Smrg	    if (i<argc-1)	inDpyName= argv[++i];
93010cdda0Smrg	    else {
94010cdda0Smrg		uWarning("No name specified for input display\n");
95010cdda0Smrg		uAction("Ignoring trailing -indpy argument\n");
96010cdda0Smrg	    }
97010cdda0Smrg	}
98010cdda0Smrg	else if (uStrCaseEqual(argv[i],"-watch")) {
99010cdda0Smrg	    if (i<argc-1) {
100010cdda0Smrg		int tmp;
101010cdda0Smrg		if (sscanf(argv[++i],"%i",&tmp)!=1) {
102010cdda0Smrg		    uWarning("Set of LEDs must be specified as an integer\n");
103010cdda0Smrg		    uAction("Ignoring bogus value \"%s\" for -watch flag\n",
104010cdda0Smrg								argv[i]);
105010cdda0Smrg		}
106010cdda0Smrg		else wanted= tmp;
107010cdda0Smrg	    }
108010cdda0Smrg	    else {
109010cdda0Smrg		uWarning("Didn't specify any LEDs to watch\n");
110010cdda0Smrg		uAction("Ignoring trailing -watch argument\n");
111010cdda0Smrg	    }
112010cdda0Smrg	}
113010cdda0Smrg	else if (uStrCaseEqual(argv[i],"-union")) {
114010cdda0Smrg	    useUnion= True;
115010cdda0Smrg	}
116010cdda0Smrg	else if (uStrCaseEqual(argv[i],"-intersection")) {
117010cdda0Smrg	    useUnion= False;
118010cdda0Smrg	}
119010cdda0Smrg	else if (uStrCaseEqual(argv[i],"-help")) {
120010cdda0Smrg	    usage(argv[0]);
121010cdda0Smrg	    exit(0);
122010cdda0Smrg	}
123010cdda0Smrg	else if ((argv[i][0]=='+')||(argv[i][0]=='-')) {
124010cdda0Smrg	    Bool 	onoff;
125010cdda0Smrg	    int	 *	which;
126010cdda0Smrg	    onoff= (argv[i][0]=='+');
127010cdda0Smrg	    which= NULL;
128010cdda0Smrg	    if (uStrCaseEqual(&argv[i][1],"name"))
129010cdda0Smrg		 which= &wantNamed;
130010cdda0Smrg	    else if (uStrCaseEqual(&argv[i][1],"explicit"))
131010cdda0Smrg		 which= &wantExplicit;
132010cdda0Smrg	    else if (uStrCaseEqual(&argv[i][1],"automatic"))
133010cdda0Smrg		 which= &wantAutomatic;
134010cdda0Smrg	    else if (uStrCaseEqual(&argv[i][1],"real"))
135010cdda0Smrg		 which= &wantReal;
136010cdda0Smrg	    else if (uStrCaseEqual(&argv[i][1],"virtual"))
137010cdda0Smrg		 which= &wantVirtual;
138010cdda0Smrg	    if (which!=NULL) {
139010cdda0Smrg		if (*which!=DONT_CARE) {
140010cdda0Smrg		    uWarning("Multiple settings for [+-]%s\n",&argv[i][1]);
141010cdda0Smrg		    uAction("Using %c%s, ignoring %c%s\n",
142010cdda0Smrg					(onoff?'+':'-'),&argv[i][1],
143010cdda0Smrg					(onoff?'-':'+'),&argv[i][1]);
144010cdda0Smrg		}
145010cdda0Smrg		*which= (onoff?YES:NO);
146010cdda0Smrg	    }
147010cdda0Smrg	}
148010cdda0Smrg    }
149010cdda0Smrg    return True;
150010cdda0Smrg}
151010cdda0Smrg
152010cdda0Smrg/***====================================================================***/
153010cdda0Smrg
154010cdda0Smrgstatic Display *
155010cdda0SmrgGetDisplay(char *program, char *dpyName)
156010cdda0Smrg{
157010cdda0Smrgint		mjr,mnr,error;
158010cdda0SmrgDisplay	*	dpy;
159010cdda0Smrg
160010cdda0Smrg    mjr= XkbMajorVersion;
161010cdda0Smrg    mnr= XkbMinorVersion;
162010cdda0Smrg    dpy= XkbOpenDisplay(dpyName,&evBase,&errBase,&mjr,&mnr,&error);
163010cdda0Smrg    if (dpy==NULL) {
164010cdda0Smrg	switch (error) {
165010cdda0Smrg	    case XkbOD_BadLibraryVersion:
166010cdda0Smrg		uInformation("%s was compiled with XKB version %d.%02d\n",
167010cdda0Smrg				program,XkbMajorVersion,XkbMinorVersion);
168010cdda0Smrg		uError("X library supports incompatible version %d.%02d\n",
169010cdda0Smrg				mjr,mnr);
170010cdda0Smrg		break;
171010cdda0Smrg	    case XkbOD_ConnectionRefused:
172010cdda0Smrg		uError("Cannot open display \"%s\"\n",dpyName);
173010cdda0Smrg		break;
174010cdda0Smrg	    case XkbOD_NonXkbServer:
175010cdda0Smrg		uError("XKB extension not present on %s\n",dpyName);
176010cdda0Smrg		break;
177010cdda0Smrg	    case XkbOD_BadServerVersion:
178010cdda0Smrg		uInformation("%s was compiled with XKB version %d.%02d\n",
179010cdda0Smrg				program,XkbMajorVersion,XkbMinorVersion);
180010cdda0Smrg		uError("Server %s uses incompatible version %d.%02d\n",
181010cdda0Smrg				dpyName,mjr,mnr);
182010cdda0Smrg		break;
183010cdda0Smrg	    default:
184010cdda0Smrg		uInternalError("Unknown error %d from XkbOpenDisplay\n",error);
185010cdda0Smrg	}
186010cdda0Smrg    }
187010cdda0Smrg    else if (synch)
188010cdda0Smrg	XSynchronize(dpy,True);
189010cdda0Smrg    return dpy;
190010cdda0Smrg}
191010cdda0Smrg
192010cdda0Smrg/***====================================================================***/
193010cdda0Smrg
194010cdda0Smrgint
195010cdda0Smrgmain(int argc, char *argv[])
196010cdda0Smrg{
197010cdda0SmrgWidget		toplevel;
198010cdda0SmrgXtAppContext	app_con;
199010cdda0SmrgWidget		panel;
200010cdda0SmrgWidget		leds[XkbNumIndicators];
201010cdda0Smrgregister int	i;
202010cdda0Smrgunsigned	bit;
203010cdda0Smrgunsigned	n;
204010cdda0SmrgXkbDescPtr	xkb;
205010cdda0SmrgXkbEvent	ev;
206010cdda0Smrgstatic Arg	boxArgs[]= {{ XtNorientation, (XtArgVal)XtorientHorizontal }};
207010cdda0Smrgstatic Arg	onArgs[]=  {{ XtNon, (XtArgVal)True }};
208010cdda0Smrgstatic Arg	offArgs[]=  {{ XtNon, (XtArgVal)False }};
209010cdda0Smrgstatic char *	fallback_resources[] = {
210010cdda0Smrg    "*Box*background: grey40",
211010cdda0Smrg    NULL
212010cdda0Smrg};
213010cdda0Smrg
214010cdda0Smrg    uSetEntryFile(NullString);
215010cdda0Smrg    uSetDebugFile(NullString);
216010cdda0Smrg    uSetErrorFile(NullString);
217010cdda0Smrg    bzero(leds,XkbNumIndicators*sizeof(Widget));
218010cdda0Smrg    toplevel = XtOpenApplication(&app_con, "XkbLEDPanel", NULL, 0, &argc, argv,
219010cdda0Smrg				 fallback_resources,
220010cdda0Smrg				 sessionShellWidgetClass, NULL, ZERO);
221010cdda0Smrg    if (toplevel==NULL) {
222010cdda0Smrg	uFatalError("Couldn't create application top level\n");
223010cdda0Smrg	return 1;
224010cdda0Smrg    }
225010cdda0Smrg    if ((argc>1)&&(!parseArgs(argc,argv))) {
226010cdda0Smrg	usage(argv[0]);
227010cdda0Smrg	return 1;
228010cdda0Smrg    }
229010cdda0Smrg    if ((wanted==0)&&(wantNamed==DONT_CARE)&&(wantExplicit==DONT_CARE)&&
230010cdda0Smrg			(wantAutomatic==DONT_CARE)&&(wantReal==DONT_CARE)) {
231010cdda0Smrg	wantNamed= YES;
232010cdda0Smrg	wantReal= YES;
233010cdda0Smrg	wantAutomatic= YES;
234010cdda0Smrg    }
235010cdda0Smrg    outDpy= XtDisplay(toplevel);
236010cdda0Smrg    if (inDpyName!=NULL) {
237010cdda0Smrg	inDpy= GetDisplay(argv[0],inDpyName);
238010cdda0Smrg	if (!inDpy)
239010cdda0Smrg	    return 1;
240010cdda0Smrg    }
241010cdda0Smrg    else {
242010cdda0Smrg	inDpy= outDpy;
243010cdda0Smrg    }
244010cdda0Smrg    if (inDpy) {
245010cdda0Smrg	int i1,mn,mj;
246010cdda0Smrg	mj= XkbMajorVersion;
247010cdda0Smrg	mn= XkbMinorVersion;
248010cdda0Smrg	if (!XkbLibraryVersion(&mj,&mn)) {
249010cdda0Smrg	    uInformation("%s was compiled with XKB version %d.%02d\n",
250010cdda0Smrg				argv[0],XkbMajorVersion,XkbMinorVersion);
251010cdda0Smrg	    uError("X library supports incompatible version %d.%02d\n",
252010cdda0Smrg				mj,mn);
253010cdda0Smrg	}
254010cdda0Smrg	if (!XkbQueryExtension(inDpy,&i1,&evBase,&errBase,&mj,&mn)) {
255010cdda0Smrg	    uFatalError("Server doesn't support a compatible XKB\n");
256010cdda0Smrg	    return 1;
257010cdda0Smrg	}
258010cdda0Smrg    }
259010cdda0Smrg    else {
260010cdda0Smrg	uFatalError("No input display\n");
261010cdda0Smrg	return 1;
262010cdda0Smrg    }
263010cdda0Smrg    panel= XtCreateManagedWidget("xkbleds",boxWidgetClass,toplevel,boxArgs,1);
264010cdda0Smrg    if (panel==NULL) {
265010cdda0Smrg	uFatalError("Couldn't create list of leds\n");
266010cdda0Smrg	return 1;
267010cdda0Smrg    }
268010cdda0Smrg    real= virtual= named= explicit= automatic= 0;
269010cdda0Smrg    if (wantReal || wantNamed || wantAutomatic || wantExplicit || wantVirtual) {
270010cdda0Smrg	register int i,bit;
271010cdda0Smrg	xkb= XkbGetMap(inDpy,0,XkbUseCoreKbd);
272010cdda0Smrg	if (!xkb) {
273010cdda0Smrg	    uFatalError("Couldn't read keymap\n");
274010cdda0Smrg	    return 1;
275010cdda0Smrg	}
276010cdda0Smrg	if (XkbGetIndicatorMap(inDpy,XkbAllIndicatorsMask,xkb)!=Success) {
277010cdda0Smrg	    uFatalError("Couldn't read indicator map\n");
278010cdda0Smrg	    return 1;
279010cdda0Smrg	}
280010cdda0Smrg	if (XkbGetNames(inDpy,XkbAllNamesMask,xkb)!=Success) {
281010cdda0Smrg	    uFatalError("Couldn't read indicator names\n");
282010cdda0Smrg	    return 1;
283010cdda0Smrg	}
284010cdda0Smrg	for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
285010cdda0Smrg	    XkbIndicatorMapPtr map= &xkb->indicators->maps[i];
286010cdda0Smrg	    if (xkb->names->indicators[i]!=None)
287010cdda0Smrg		named|= bit;
288010cdda0Smrg	    if (xkb->indicators->phys_indicators&bit)
289010cdda0Smrg		real|= bit;
290010cdda0Smrg	    if ((((map->which_groups!=0)&&(map->groups!=0))||
291010cdda0Smrg		((map->which_mods!=0)&&
292010cdda0Smrg		((map->mods.real_mods!=0)||(map->mods.vmods!=0)))||
293010cdda0Smrg		(map->ctrls!=0))&&
294010cdda0Smrg		((map->flags&XkbIM_NoAutomatic)==0)) {
295010cdda0Smrg		automatic|= bit;
296010cdda0Smrg	    }
297010cdda0Smrg	    else explicit|= bit;
298010cdda0Smrg	}
299010cdda0Smrg	virtual= ~real;
300010cdda0Smrg	if (wantReal==NO)			real= ~real;
301010cdda0Smrg	else if (wantReal==DONT_CARE)		real= (useUnion?0:~0);
302010cdda0Smrg	if (wantVirtual==NO)			virtual= ~virtual;
303010cdda0Smrg	else if (wantVirtual==DONT_CARE)	virtual= (useUnion?0:~0);
304010cdda0Smrg	if (wantNamed==NO)			named= ~named;
305010cdda0Smrg	else if (wantNamed==DONT_CARE)		named= (useUnion?0:~0);
306010cdda0Smrg	if (wantAutomatic==NO)			automatic= ~automatic;
307010cdda0Smrg	else if (wantAutomatic==DONT_CARE)	automatic= (useUnion?0:~0);
308010cdda0Smrg	if (wantExplicit==NO)			explicit= ~explicit;
309010cdda0Smrg	else if (wantExplicit==DONT_CARE)	explicit= (useUnion?0:~0);
310010cdda0Smrg	if (useUnion)
311010cdda0Smrg	     wanted|= real|virtual|named|automatic|explicit;
312010cdda0Smrg	else wanted&= real&virtual&named&automatic&explicit;
313010cdda0Smrg    }
314010cdda0Smrg    else xkb= NULL;
315010cdda0Smrg    if (wanted==0) {
316010cdda0Smrg	uError("No indicator maps match the selected criteria\n");
317010cdda0Smrg	uAction("Exiting\n");
318010cdda0Smrg	return 1;
319010cdda0Smrg    }
320010cdda0Smrg
321010cdda0Smrg    XkbSelectEvents(inDpy,XkbUseCoreKbd,XkbIndicatorStateNotifyMask,
322010cdda0Smrg						XkbIndicatorStateNotifyMask);
323010cdda0Smrg    XkbGetIndicatorState(inDpy,XkbUseCoreKbd,&n);
324010cdda0Smrg    bit= (1<<(XkbNumIndicators-1));
325010cdda0Smrg    for (i=XkbNumIndicators-1;i>=0;i--,bit>>=1) {
326010cdda0Smrg	if (wanted&bit) {
327010cdda0Smrg	    char 	buf[12];
328010cdda0Smrg	    ArgList	list;
329010cdda0Smrg
330010cdda0Smrg	    sprintf(buf,"led%d",i+1);
331010cdda0Smrg	    if (n&bit)	list= onArgs;
332010cdda0Smrg	    else	list= offArgs;
333010cdda0Smrg	    leds[i]= XtCreateManagedWidget(buf,ledWidgetClass,panel,list,1);
334010cdda0Smrg	}
335010cdda0Smrg    }
336010cdda0Smrg    XtRealizeWidget(toplevel);
337010cdda0Smrg    while (1) {
338010cdda0Smrg        XtAppNextEvent(app_con,&ev.core);
339010cdda0Smrg	if (ev.core.type==evBase+XkbEventCode) {
340010cdda0Smrg	    if (ev.any.xkb_type==XkbIndicatorStateNotify) {
341010cdda0Smrg		for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
342010cdda0Smrg		    if ((ev.indicators.changed&bit)&&(leds[i])) {
343010cdda0Smrg			ArgList	list;
344010cdda0Smrg			if (ev.indicators.state&bit)	list= onArgs;
345010cdda0Smrg			else				list= offArgs;
346010cdda0Smrg			XtSetValues(leds[i],list,1);
347010cdda0Smrg		    }
348010cdda0Smrg		}
349010cdda0Smrg	    }
350010cdda0Smrg	}
351010cdda0Smrg	else XtDispatchEvent(&ev.core);
352010cdda0Smrg    }
353010cdda0Smrg/* BAIL: */
354010cdda0Smrg    if (inDpy)
355010cdda0Smrg	XCloseDisplay(inDpy);
356010cdda0Smrg    if (outDpy!=inDpy)
357010cdda0Smrg	XCloseDisplay(outDpy);
358010cdda0Smrg    inDpy= outDpy= NULL;
359010cdda0Smrg    return 0;
360010cdda0Smrg}
361