xkbwatch.c revision b4485a66
1010cdda0Smrg/************************************************************ 2010cdda0Smrg Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc. 3010cdda0Smrg 4010cdda0Smrg Permission to use, copy, modify, and distribute this 5010cdda0Smrg software and its documentation for any purpose and without 6010cdda0Smrg fee is hereby granted, provided that the above copyright 7010cdda0Smrg notice appear in all copies and that both that copyright 8010cdda0Smrg notice and this permission notice appear in supporting 9010cdda0Smrg documentation, and that the name of Silicon Graphics not be 10010cdda0Smrg used in advertising or publicity pertaining to distribution 11010cdda0Smrg of the software without specific prior written permission. 12010cdda0Smrg Silicon Graphics makes no representation about the suitability 13010cdda0Smrg of this software for any purpose. It is provided "as is" 14010cdda0Smrg without any express or implied warranty. 15010cdda0Smrg 16010cdda0Smrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17010cdda0Smrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18010cdda0Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19010cdda0Smrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20010cdda0Smrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21010cdda0Smrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22010cdda0Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23010cdda0Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE. 24010cdda0Smrg 25010cdda0Smrg ********************************************************/ 26010cdda0Smrg 27010cdda0Smrg#include <stdlib.h> 28010cdda0Smrg#include <X11/X.h> 29010cdda0Smrg#include <X11/Xlib.h> 30010cdda0Smrg#include <X11/XKBlib.h> 31010cdda0Smrg#include <X11/Intrinsic.h> 32010cdda0Smrg#include <X11/StringDefs.h> 33010cdda0Smrg#include <X11/Shell.h> 34010cdda0Smrg#include <X11/Xaw/Cardinals.h> 35010cdda0Smrg#include <X11/Xaw/Box.h> 36010cdda0Smrg 37010cdda0Smrg#define BOOLEAN_DEFINED 38010cdda0Smrg#include "utils.h" 39010cdda0Smrg#include "LED.h" 40010cdda0Smrg 41010cdda0Smrg/***====================================================================***/ 42010cdda0Smrg 43b4485a66Smrgstatic Display *inDpy, *outDpy; 44b4485a66Smrgstatic int evBase, errBase; 45010cdda0Smrg 46010cdda0Smrg/***====================================================================***/ 47010cdda0Smrg 48010cdda0Smrgstatic XrmOptionDescRec options[] = { 49b4485a66Smrg {"-off", "*on.on", XrmoptionNoArg, "FALSE"}, 50b4485a66Smrg {"-on", "*on.on", XrmoptionNoArg, "TRUE"} 51010cdda0Smrg}; 52010cdda0Smrg 53010cdda0Smrg/***====================================================================***/ 54010cdda0Smrg 55010cdda0Smrgint 56010cdda0Smrgmain(int argc, char *argv[]) 57010cdda0Smrg{ 58b4485a66Smrg Widget toplevel; 59b4485a66Smrg XtAppContext app_con; 60b4485a66Smrg Widget panel; 61b4485a66Smrg Widget base[XkbNumModifiers]; 62b4485a66Smrg Widget latched[XkbNumModifiers]; 63b4485a66Smrg Widget locked[XkbNumModifiers]; 64b4485a66Smrg Widget effective[XkbNumModifiers]; 65b4485a66Smrg Widget compat[XkbNumModifiers]; 66b4485a66Smrg Widget baseBox, latchBox, lockBox, effBox, compatBox; 67b4485a66Smrg register int i; 68b4485a66Smrg unsigned bit; 69b4485a66Smrg XkbEvent ev; 70b4485a66Smrg XkbStateRec state; 71b4485a66Smrg static Arg hArgs[] = { {XtNorientation, (XtArgVal) XtorientHorizontal} }; 72b4485a66Smrg static Arg vArgs[] = { {XtNorientation, (XtArgVal) XtorientVertical} }; 73b4485a66Smrg static Arg onArgs[] = { {XtNon, (XtArgVal) True} }; 74b4485a66Smrg static Arg offArgs[] = { {XtNon, (XtArgVal) False} }; 75b4485a66Smrg static char *fallback_resources[] = { 76b4485a66Smrg "*Box*background: grey50", 77b4485a66Smrg "*Box*borderWidth: 0", 78b4485a66Smrg "*Box*vSpace: 1", 79b4485a66Smrg NULL 80b4485a66Smrg }; 81b4485a66Smrg 82b4485a66Smrg for (i = 1; i < argc; i++) { 83b4485a66Smrg if (strcmp(argv[i], "-version") == 0) { 84b4485a66Smrg printf("xkbwatch (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); 85b4485a66Smrg exit(0); 86b4485a66Smrg } 87b4485a66Smrg } 88010cdda0Smrg 89010cdda0Smrg uSetErrorFile(NullString); 90010cdda0Smrg toplevel = XtOpenApplication(&app_con, "XkbWatch", 91b4485a66Smrg options, XtNumber(options), &argc, argv, 92b4485a66Smrg fallback_resources, 93b4485a66Smrg sessionShellWidgetClass, NULL, ZERO); 94b4485a66Smrg if (toplevel == NULL) { 95b4485a66Smrg uFatalError("Couldn't create application top level\n"); 96b4485a66Smrg exit(1); 97010cdda0Smrg } 98b4485a66Smrg inDpy = outDpy = XtDisplay(toplevel); 99010cdda0Smrg if (inDpy) { 100b4485a66Smrg int i1, mn, mj; 101b4485a66Smrg 102b4485a66Smrg mj = XkbMajorVersion; 103b4485a66Smrg mn = XkbMinorVersion; 104b4485a66Smrg if (!XkbQueryExtension(inDpy, &i1, &evBase, &errBase, &mj, &mn)) { 105b4485a66Smrg uFatalError("Server doesn't support a compatible XKB\n"); 106b4485a66Smrg exit(1); 107b4485a66Smrg } 108010cdda0Smrg } 109b4485a66Smrg panel = 110b4485a66Smrg XtCreateManagedWidget("xkbwatch", boxWidgetClass, toplevel, vArgs, 1); 111b4485a66Smrg if (panel == NULL) { 112b4485a66Smrg uFatalError("Couldn't create top level box\n"); 113b4485a66Smrg exit(1); 114010cdda0Smrg } 115b4485a66Smrg baseBox = XtCreateManagedWidget("base", boxWidgetClass, panel, hArgs, 1); 116b4485a66Smrg if (baseBox == NULL) 117b4485a66Smrg uFatalError("Couldn't create base modifiers box\n"); 118b4485a66Smrg latchBox = 119b4485a66Smrg XtCreateManagedWidget("latched", boxWidgetClass, panel, hArgs, 1); 120b4485a66Smrg if (latchBox == NULL) 121b4485a66Smrg uFatalError("Couldn't create latched modifiers box\n"); 122b4485a66Smrg lockBox = XtCreateManagedWidget("locked", boxWidgetClass, panel, hArgs, 1); 123b4485a66Smrg if (lockBox == NULL) 124b4485a66Smrg uFatalError("Couldn't create locked modifiers box\n"); 125b4485a66Smrg effBox = 126b4485a66Smrg XtCreateManagedWidget("effective", boxWidgetClass, panel, hArgs, 1); 127b4485a66Smrg if (effBox == NULL) 128b4485a66Smrg uFatalError("Couldn't create effective modifiers box\n"); 129b4485a66Smrg compatBox = 130b4485a66Smrg XtCreateManagedWidget("compat", boxWidgetClass, panel, hArgs, 1); 131b4485a66Smrg if (compatBox == NULL) 132b4485a66Smrg uFatalError("Couldn't create compatibility state box\n"); 133b4485a66Smrg XkbSelectEvents(inDpy, XkbUseCoreKbd, XkbStateNotifyMask, 134b4485a66Smrg XkbStateNotifyMask); 135b4485a66Smrg XkbGetState(inDpy, XkbUseCoreKbd, &state); 136b4485a66Smrg for (i = XkbNumModifiers - 1, bit = 0x80; i >= 0; i--, bit >>= 1) { 137b4485a66Smrg ArgList list; 138b4485a66Smrg 139b4485a66Smrg char buf[30]; 140b4485a66Smrg 141b4485a66Smrg sprintf(buf, "base%d", i); 142b4485a66Smrg if (state.base_mods & bit) 143b4485a66Smrg list = onArgs; 144b4485a66Smrg else 145b4485a66Smrg list = offArgs; 146b4485a66Smrg base[i] = XtCreateManagedWidget(buf, ledWidgetClass, baseBox, list, 1); 147b4485a66Smrg sprintf(buf, "latched%d", i); 148b4485a66Smrg if (state.latched_mods & bit) 149b4485a66Smrg list = onArgs; 150b4485a66Smrg else 151b4485a66Smrg list = offArgs; 152b4485a66Smrg latched[i] = 153b4485a66Smrg XtCreateManagedWidget(buf, ledWidgetClass, latchBox, list, 1); 154b4485a66Smrg sprintf(buf, "locked%d", i); 155b4485a66Smrg if (state.locked_mods & bit) 156b4485a66Smrg list = onArgs; 157b4485a66Smrg else 158b4485a66Smrg list = offArgs; 159b4485a66Smrg locked[i] = 160b4485a66Smrg XtCreateManagedWidget(buf, ledWidgetClass, lockBox, list, 1); 161b4485a66Smrg sprintf(buf, "effective%d", i); 162b4485a66Smrg if (state.mods & bit) 163b4485a66Smrg list = onArgs; 164b4485a66Smrg else 165b4485a66Smrg list = offArgs; 166b4485a66Smrg effective[i] = 167b4485a66Smrg XtCreateManagedWidget(buf, ledWidgetClass, effBox, list, 1); 168b4485a66Smrg sprintf(buf, "compat%d", i); 169b4485a66Smrg if (state.compat_state & bit) 170b4485a66Smrg list = onArgs; 171b4485a66Smrg else 172b4485a66Smrg list = offArgs; 173b4485a66Smrg compat[i] = 174b4485a66Smrg XtCreateManagedWidget(buf, ledWidgetClass, compatBox, list, 1); 175010cdda0Smrg } 176010cdda0Smrg XtRealizeWidget(toplevel); 177010cdda0Smrg while (1) { 178b4485a66Smrg XtAppNextEvent(app_con, &ev.core); 179b4485a66Smrg if (ev.core.type == evBase + XkbEventCode) { 180b4485a66Smrg if (ev.any.xkb_type == XkbStateNotify) { 181b4485a66Smrg unsigned changed; 182b4485a66Smrg 183b4485a66Smrg if (ev.state.changed & XkbModifierBaseMask) { 184b4485a66Smrg changed = ev.state.base_mods ^ state.base_mods; 185b4485a66Smrg state.base_mods = ev.state.base_mods; 186b4485a66Smrg for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) { 187b4485a66Smrg if (changed & bit) { 188b4485a66Smrg ArgList list; 189b4485a66Smrg 190b4485a66Smrg if (state.base_mods & bit) 191b4485a66Smrg list = onArgs; 192b4485a66Smrg else 193b4485a66Smrg list = offArgs; 194b4485a66Smrg XtSetValues(base[i], list, 1); 195b4485a66Smrg } 196b4485a66Smrg } 197b4485a66Smrg } 198b4485a66Smrg if (ev.state.changed & XkbModifierLatchMask) { 199b4485a66Smrg changed = ev.state.latched_mods ^ state.latched_mods; 200b4485a66Smrg state.latched_mods = ev.state.latched_mods; 201b4485a66Smrg for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) { 202b4485a66Smrg if (changed & bit) { 203b4485a66Smrg ArgList list; 204b4485a66Smrg 205b4485a66Smrg if (state.latched_mods & bit) 206b4485a66Smrg list = onArgs; 207b4485a66Smrg else 208b4485a66Smrg list = offArgs; 209b4485a66Smrg XtSetValues(latched[i], list, 1); 210b4485a66Smrg } 211b4485a66Smrg } 212b4485a66Smrg } 213b4485a66Smrg if (ev.state.changed & XkbModifierLockMask) { 214b4485a66Smrg changed = ev.state.locked_mods ^ state.locked_mods; 215b4485a66Smrg state.locked_mods = ev.state.locked_mods; 216b4485a66Smrg for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) { 217b4485a66Smrg if (changed & bit) { 218b4485a66Smrg ArgList list; 219b4485a66Smrg 220b4485a66Smrg if (state.locked_mods & bit) 221b4485a66Smrg list = onArgs; 222b4485a66Smrg else 223b4485a66Smrg list = offArgs; 224b4485a66Smrg XtSetValues(locked[i], list, 1); 225b4485a66Smrg } 226b4485a66Smrg } 227b4485a66Smrg } 228b4485a66Smrg if (ev.state.changed & XkbModifierStateMask) { 229b4485a66Smrg changed = ev.state.mods ^ state.mods; 230b4485a66Smrg state.mods = ev.state.mods; 231b4485a66Smrg for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) { 232b4485a66Smrg if (changed & bit) { 233b4485a66Smrg ArgList list; 234b4485a66Smrg 235b4485a66Smrg if (state.mods & bit) 236b4485a66Smrg list = onArgs; 237b4485a66Smrg else 238b4485a66Smrg list = offArgs; 239b4485a66Smrg XtSetValues(effective[i], list, 1); 240b4485a66Smrg } 241b4485a66Smrg } 242b4485a66Smrg } 243b4485a66Smrg if (ev.state.changed & XkbCompatStateMask) { 244b4485a66Smrg changed = ev.state.compat_state ^ state.compat_state; 245b4485a66Smrg state.compat_state = ev.state.compat_state; 246b4485a66Smrg for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) { 247b4485a66Smrg if (changed & bit) { 248b4485a66Smrg ArgList list; 249b4485a66Smrg 250b4485a66Smrg if (state.compat_state & bit) 251b4485a66Smrg list = onArgs; 252b4485a66Smrg else 253b4485a66Smrg list = offArgs; 254b4485a66Smrg XtSetValues(compat[i], list, 1); 255b4485a66Smrg } 256b4485a66Smrg } 257b4485a66Smrg } 258b4485a66Smrg } 259b4485a66Smrg } 260b4485a66Smrg else 261b4485a66Smrg XtDispatchEvent(&ev.core); 262010cdda0Smrg } 263010cdda0Smrg/* BAIL: */ 264b4485a66Smrg if (inDpy) 265b4485a66Smrg XCloseDisplay(inDpy); 266b4485a66Smrg if (outDpy != inDpy) 267b4485a66Smrg XCloseDisplay(outDpy); 268b4485a66Smrg inDpy = outDpy = NULL; 269010cdda0Smrg return 0; 270010cdda0Smrg} 271