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} }; 75affd2f3fSmrg static String 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 toplevel = XtOpenApplication(&app_con, "XkbWatch", 90b4485a66Smrg options, XtNumber(options), &argc, argv, 91b4485a66Smrg fallback_resources, 92b4485a66Smrg sessionShellWidgetClass, NULL, ZERO); 93b4485a66Smrg if (toplevel == NULL) { 94b4485a66Smrg uFatalError("Couldn't create application top level\n"); 95b4485a66Smrg exit(1); 96010cdda0Smrg } 97b4485a66Smrg inDpy = outDpy = XtDisplay(toplevel); 98010cdda0Smrg if (inDpy) { 99b4485a66Smrg int i1, mn, mj; 100b4485a66Smrg 101b4485a66Smrg mj = XkbMajorVersion; 102b4485a66Smrg mn = XkbMinorVersion; 103b4485a66Smrg if (!XkbQueryExtension(inDpy, &i1, &evBase, &errBase, &mj, &mn)) { 104b4485a66Smrg uFatalError("Server doesn't support a compatible XKB\n"); 105b4485a66Smrg exit(1); 106b4485a66Smrg } 107010cdda0Smrg } 108b4485a66Smrg panel = 109b4485a66Smrg XtCreateManagedWidget("xkbwatch", boxWidgetClass, toplevel, vArgs, 1); 110b4485a66Smrg if (panel == NULL) { 111b4485a66Smrg uFatalError("Couldn't create top level box\n"); 112b4485a66Smrg exit(1); 113010cdda0Smrg } 114b4485a66Smrg baseBox = XtCreateManagedWidget("base", boxWidgetClass, panel, hArgs, 1); 115b4485a66Smrg if (baseBox == NULL) 116b4485a66Smrg uFatalError("Couldn't create base modifiers box\n"); 117b4485a66Smrg latchBox = 118b4485a66Smrg XtCreateManagedWidget("latched", boxWidgetClass, panel, hArgs, 1); 119b4485a66Smrg if (latchBox == NULL) 120b4485a66Smrg uFatalError("Couldn't create latched modifiers box\n"); 121b4485a66Smrg lockBox = XtCreateManagedWidget("locked", boxWidgetClass, panel, hArgs, 1); 122b4485a66Smrg if (lockBox == NULL) 123b4485a66Smrg uFatalError("Couldn't create locked modifiers box\n"); 124b4485a66Smrg effBox = 125b4485a66Smrg XtCreateManagedWidget("effective", boxWidgetClass, panel, hArgs, 1); 126b4485a66Smrg if (effBox == NULL) 127b4485a66Smrg uFatalError("Couldn't create effective modifiers box\n"); 128b4485a66Smrg compatBox = 129b4485a66Smrg XtCreateManagedWidget("compat", boxWidgetClass, panel, hArgs, 1); 130b4485a66Smrg if (compatBox == NULL) 131b4485a66Smrg uFatalError("Couldn't create compatibility state box\n"); 132b4485a66Smrg XkbSelectEvents(inDpy, XkbUseCoreKbd, XkbStateNotifyMask, 133b4485a66Smrg XkbStateNotifyMask); 134b4485a66Smrg XkbGetState(inDpy, XkbUseCoreKbd, &state); 135b4485a66Smrg for (i = XkbNumModifiers - 1, bit = 0x80; i >= 0; i--, bit >>= 1) { 136b4485a66Smrg ArgList list; 137b4485a66Smrg 138b4485a66Smrg char buf[30]; 139b4485a66Smrg 140affd2f3fSmrg snprintf(buf, sizeof(buf), "base%d", i); 141b4485a66Smrg if (state.base_mods & bit) 142b4485a66Smrg list = onArgs; 143b4485a66Smrg else 144b4485a66Smrg list = offArgs; 145b4485a66Smrg base[i] = XtCreateManagedWidget(buf, ledWidgetClass, baseBox, list, 1); 146affd2f3fSmrg snprintf(buf, sizeof(buf), "latched%d", i); 147b4485a66Smrg if (state.latched_mods & bit) 148b4485a66Smrg list = onArgs; 149b4485a66Smrg else 150b4485a66Smrg list = offArgs; 151b4485a66Smrg latched[i] = 152b4485a66Smrg XtCreateManagedWidget(buf, ledWidgetClass, latchBox, list, 1); 153affd2f3fSmrg snprintf(buf, sizeof(buf), "locked%d", i); 154b4485a66Smrg if (state.locked_mods & bit) 155b4485a66Smrg list = onArgs; 156b4485a66Smrg else 157b4485a66Smrg list = offArgs; 158b4485a66Smrg locked[i] = 159b4485a66Smrg XtCreateManagedWidget(buf, ledWidgetClass, lockBox, list, 1); 160affd2f3fSmrg snprintf(buf, sizeof(buf), "effective%d", i); 161b4485a66Smrg if (state.mods & bit) 162b4485a66Smrg list = onArgs; 163b4485a66Smrg else 164b4485a66Smrg list = offArgs; 165b4485a66Smrg effective[i] = 166b4485a66Smrg XtCreateManagedWidget(buf, ledWidgetClass, effBox, list, 1); 167affd2f3fSmrg snprintf(buf, sizeof(buf), "compat%d", i); 168b4485a66Smrg if (state.compat_state & bit) 169b4485a66Smrg list = onArgs; 170b4485a66Smrg else 171b4485a66Smrg list = offArgs; 172b4485a66Smrg compat[i] = 173b4485a66Smrg XtCreateManagedWidget(buf, ledWidgetClass, compatBox, list, 1); 174010cdda0Smrg } 175010cdda0Smrg XtRealizeWidget(toplevel); 176010cdda0Smrg while (1) { 177b4485a66Smrg XtAppNextEvent(app_con, &ev.core); 178b4485a66Smrg if (ev.core.type == evBase + XkbEventCode) { 179b4485a66Smrg if (ev.any.xkb_type == XkbStateNotify) { 180b4485a66Smrg unsigned changed; 181b4485a66Smrg 182b4485a66Smrg if (ev.state.changed & XkbModifierBaseMask) { 183b4485a66Smrg changed = ev.state.base_mods ^ state.base_mods; 184b4485a66Smrg state.base_mods = ev.state.base_mods; 185b4485a66Smrg for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) { 186b4485a66Smrg if (changed & bit) { 187b4485a66Smrg ArgList list; 188b4485a66Smrg 189b4485a66Smrg if (state.base_mods & bit) 190b4485a66Smrg list = onArgs; 191b4485a66Smrg else 192b4485a66Smrg list = offArgs; 193b4485a66Smrg XtSetValues(base[i], list, 1); 194b4485a66Smrg } 195b4485a66Smrg } 196b4485a66Smrg } 197b4485a66Smrg if (ev.state.changed & XkbModifierLatchMask) { 198b4485a66Smrg changed = ev.state.latched_mods ^ state.latched_mods; 199b4485a66Smrg state.latched_mods = ev.state.latched_mods; 200b4485a66Smrg for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) { 201b4485a66Smrg if (changed & bit) { 202b4485a66Smrg ArgList list; 203b4485a66Smrg 204b4485a66Smrg if (state.latched_mods & bit) 205b4485a66Smrg list = onArgs; 206b4485a66Smrg else 207b4485a66Smrg list = offArgs; 208b4485a66Smrg XtSetValues(latched[i], list, 1); 209b4485a66Smrg } 210b4485a66Smrg } 211b4485a66Smrg } 212b4485a66Smrg if (ev.state.changed & XkbModifierLockMask) { 213b4485a66Smrg changed = ev.state.locked_mods ^ state.locked_mods; 214b4485a66Smrg state.locked_mods = ev.state.locked_mods; 215b4485a66Smrg for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) { 216b4485a66Smrg if (changed & bit) { 217b4485a66Smrg ArgList list; 218b4485a66Smrg 219b4485a66Smrg if (state.locked_mods & bit) 220b4485a66Smrg list = onArgs; 221b4485a66Smrg else 222b4485a66Smrg list = offArgs; 223b4485a66Smrg XtSetValues(locked[i], list, 1); 224b4485a66Smrg } 225b4485a66Smrg } 226b4485a66Smrg } 227b4485a66Smrg if (ev.state.changed & XkbModifierStateMask) { 228b4485a66Smrg changed = ev.state.mods ^ state.mods; 229b4485a66Smrg state.mods = ev.state.mods; 230b4485a66Smrg for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) { 231b4485a66Smrg if (changed & bit) { 232b4485a66Smrg ArgList list; 233b4485a66Smrg 234b4485a66Smrg if (state.mods & bit) 235b4485a66Smrg list = onArgs; 236b4485a66Smrg else 237b4485a66Smrg list = offArgs; 238b4485a66Smrg XtSetValues(effective[i], list, 1); 239b4485a66Smrg } 240b4485a66Smrg } 241b4485a66Smrg } 242b4485a66Smrg if (ev.state.changed & XkbCompatStateMask) { 243b4485a66Smrg changed = ev.state.compat_state ^ state.compat_state; 244b4485a66Smrg state.compat_state = ev.state.compat_state; 245b4485a66Smrg for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) { 246b4485a66Smrg if (changed & bit) { 247b4485a66Smrg ArgList list; 248b4485a66Smrg 249b4485a66Smrg if (state.compat_state & bit) 250b4485a66Smrg list = onArgs; 251b4485a66Smrg else 252b4485a66Smrg list = offArgs; 253b4485a66Smrg XtSetValues(compat[i], list, 1); 254b4485a66Smrg } 255b4485a66Smrg } 256b4485a66Smrg } 257b4485a66Smrg } 258b4485a66Smrg } 259b4485a66Smrg else 260b4485a66Smrg XtDispatchEvent(&ev.core); 261010cdda0Smrg } 262010cdda0Smrg/* BAIL: */ 263b4485a66Smrg if (inDpy) 264b4485a66Smrg XCloseDisplay(inDpy); 265b4485a66Smrg if (outDpy != inDpy) 266b4485a66Smrg XCloseDisplay(outDpy); 267b4485a66Smrg inDpy = outDpy = NULL; 268010cdda0Smrg return 0; 269010cdda0Smrg} 270