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