1/************************************************************ 2 Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc. 3 4 Permission to use, copy, modify, and distribute this 5 software and its documentation for any purpose and without 6 fee is hereby granted, provided that the above copyright 7 notice appear in all copies and that both that copyright 8 notice and this permission notice appear in supporting 9 documentation, and that the name of Silicon Graphics not be 10 used in advertising or publicity pertaining to distribution 11 of the software without specific prior written permission. 12 Silicon Graphics makes no representation about the suitability 13 of this software for any purpose. It is provided "as is" 14 without any express or implied warranty. 15 16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23 THE USE OR PERFORMANCE OF THIS SOFTWARE. 24 25 ********************************************************/ 26 27#include <stdlib.h> 28#include <X11/X.h> 29#include <X11/Xlib.h> 30#include <X11/XKBlib.h> 31#include <X11/Intrinsic.h> 32#include <X11/StringDefs.h> 33#include <X11/Shell.h> 34#include <X11/Xaw/Cardinals.h> 35#include <X11/Xaw/Box.h> 36 37#define BOOLEAN_DEFINED 38#include "utils.h" 39#include "LED.h" 40 41/***====================================================================***/ 42 43static Display *inDpy, *outDpy; 44static int evBase, errBase; 45 46/***====================================================================***/ 47 48static XrmOptionDescRec options[] = { 49 {"-off", "*on.on", XrmoptionNoArg, "FALSE"}, 50 {"-on", "*on.on", XrmoptionNoArg, "TRUE"} 51}; 52 53/***====================================================================***/ 54 55int 56main(int argc, char *argv[]) 57{ 58 Widget toplevel; 59 XtAppContext app_con; 60 Widget panel; 61 Widget base[XkbNumModifiers]; 62 Widget latched[XkbNumModifiers]; 63 Widget locked[XkbNumModifiers]; 64 Widget effective[XkbNumModifiers]; 65 Widget compat[XkbNumModifiers]; 66 Widget baseBox, latchBox, lockBox, effBox, compatBox; 67 register int i; 68 unsigned bit; 69 XkbEvent ev; 70 XkbStateRec state; 71 static Arg hArgs[] = { {XtNorientation, (XtArgVal) XtorientHorizontal} }; 72 static Arg vArgs[] = { {XtNorientation, (XtArgVal) XtorientVertical} }; 73 static Arg onArgs[] = { {XtNon, (XtArgVal) True} }; 74 static Arg offArgs[] = { {XtNon, (XtArgVal) False} }; 75 static String fallback_resources[] = { 76 "*Box*background: grey50", 77 "*Box*borderWidth: 0", 78 "*Box*vSpace: 1", 79 NULL 80 }; 81 82 for (i = 1; i < argc; i++) { 83 if (strcmp(argv[i], "-version") == 0) { 84 printf("xkbwatch (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); 85 exit(0); 86 } 87 } 88 89 toplevel = XtOpenApplication(&app_con, "XkbWatch", 90 options, XtNumber(options), &argc, argv, 91 fallback_resources, 92 sessionShellWidgetClass, NULL, ZERO); 93 if (toplevel == NULL) { 94 uFatalError("Couldn't create application top level\n"); 95 exit(1); 96 } 97 inDpy = outDpy = XtDisplay(toplevel); 98 if (inDpy) { 99 int i1, mn, mj; 100 101 mj = XkbMajorVersion; 102 mn = XkbMinorVersion; 103 if (!XkbQueryExtension(inDpy, &i1, &evBase, &errBase, &mj, &mn)) { 104 uFatalError("Server doesn't support a compatible XKB\n"); 105 exit(1); 106 } 107 } 108 panel = 109 XtCreateManagedWidget("xkbwatch", boxWidgetClass, toplevel, vArgs, 1); 110 if (panel == NULL) { 111 uFatalError("Couldn't create top level box\n"); 112 exit(1); 113 } 114 baseBox = XtCreateManagedWidget("base", boxWidgetClass, panel, hArgs, 1); 115 if (baseBox == NULL) 116 uFatalError("Couldn't create base modifiers box\n"); 117 latchBox = 118 XtCreateManagedWidget("latched", boxWidgetClass, panel, hArgs, 1); 119 if (latchBox == NULL) 120 uFatalError("Couldn't create latched modifiers box\n"); 121 lockBox = XtCreateManagedWidget("locked", boxWidgetClass, panel, hArgs, 1); 122 if (lockBox == NULL) 123 uFatalError("Couldn't create locked modifiers box\n"); 124 effBox = 125 XtCreateManagedWidget("effective", boxWidgetClass, panel, hArgs, 1); 126 if (effBox == NULL) 127 uFatalError("Couldn't create effective modifiers box\n"); 128 compatBox = 129 XtCreateManagedWidget("compat", boxWidgetClass, panel, hArgs, 1); 130 if (compatBox == NULL) 131 uFatalError("Couldn't create compatibility state box\n"); 132 XkbSelectEvents(inDpy, XkbUseCoreKbd, XkbStateNotifyMask, 133 XkbStateNotifyMask); 134 XkbGetState(inDpy, XkbUseCoreKbd, &state); 135 for (i = XkbNumModifiers - 1, bit = 0x80; i >= 0; i--, bit >>= 1) { 136 ArgList list; 137 138 char buf[30]; 139 140 snprintf(buf, sizeof(buf), "base%d", i); 141 if (state.base_mods & bit) 142 list = onArgs; 143 else 144 list = offArgs; 145 base[i] = XtCreateManagedWidget(buf, ledWidgetClass, baseBox, list, 1); 146 snprintf(buf, sizeof(buf), "latched%d", i); 147 if (state.latched_mods & bit) 148 list = onArgs; 149 else 150 list = offArgs; 151 latched[i] = 152 XtCreateManagedWidget(buf, ledWidgetClass, latchBox, list, 1); 153 snprintf(buf, sizeof(buf), "locked%d", i); 154 if (state.locked_mods & bit) 155 list = onArgs; 156 else 157 list = offArgs; 158 locked[i] = 159 XtCreateManagedWidget(buf, ledWidgetClass, lockBox, list, 1); 160 snprintf(buf, sizeof(buf), "effective%d", i); 161 if (state.mods & bit) 162 list = onArgs; 163 else 164 list = offArgs; 165 effective[i] = 166 XtCreateManagedWidget(buf, ledWidgetClass, effBox, list, 1); 167 snprintf(buf, sizeof(buf), "compat%d", i); 168 if (state.compat_state & bit) 169 list = onArgs; 170 else 171 list = offArgs; 172 compat[i] = 173 XtCreateManagedWidget(buf, ledWidgetClass, compatBox, list, 1); 174 } 175 XtRealizeWidget(toplevel); 176 while (1) { 177 XtAppNextEvent(app_con, &ev.core); 178 if (ev.core.type == evBase + XkbEventCode) { 179 if (ev.any.xkb_type == XkbStateNotify) { 180 unsigned changed; 181 182 if (ev.state.changed & XkbModifierBaseMask) { 183 changed = ev.state.base_mods ^ state.base_mods; 184 state.base_mods = ev.state.base_mods; 185 for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) { 186 if (changed & bit) { 187 ArgList list; 188 189 if (state.base_mods & bit) 190 list = onArgs; 191 else 192 list = offArgs; 193 XtSetValues(base[i], list, 1); 194 } 195 } 196 } 197 if (ev.state.changed & XkbModifierLatchMask) { 198 changed = ev.state.latched_mods ^ state.latched_mods; 199 state.latched_mods = ev.state.latched_mods; 200 for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) { 201 if (changed & bit) { 202 ArgList list; 203 204 if (state.latched_mods & bit) 205 list = onArgs; 206 else 207 list = offArgs; 208 XtSetValues(latched[i], list, 1); 209 } 210 } 211 } 212 if (ev.state.changed & XkbModifierLockMask) { 213 changed = ev.state.locked_mods ^ state.locked_mods; 214 state.locked_mods = ev.state.locked_mods; 215 for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) { 216 if (changed & bit) { 217 ArgList list; 218 219 if (state.locked_mods & bit) 220 list = onArgs; 221 else 222 list = offArgs; 223 XtSetValues(locked[i], list, 1); 224 } 225 } 226 } 227 if (ev.state.changed & XkbModifierStateMask) { 228 changed = ev.state.mods ^ state.mods; 229 state.mods = ev.state.mods; 230 for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) { 231 if (changed & bit) { 232 ArgList list; 233 234 if (state.mods & bit) 235 list = onArgs; 236 else 237 list = offArgs; 238 XtSetValues(effective[i], list, 1); 239 } 240 } 241 } 242 if (ev.state.changed & XkbCompatStateMask) { 243 changed = ev.state.compat_state ^ state.compat_state; 244 state.compat_state = ev.state.compat_state; 245 for (i = 0, bit = 1; i < XkbNumModifiers; i++, bit <<= 1) { 246 if (changed & bit) { 247 ArgList list; 248 249 if (state.compat_state & bit) 250 list = onArgs; 251 else 252 list = offArgs; 253 XtSetValues(compat[i], list, 1); 254 } 255 } 256 } 257 } 258 } 259 else 260 XtDispatchEvent(&ev.core); 261 } 262/* BAIL: */ 263 if (inDpy) 264 XCloseDisplay(inDpy); 265 if (outDpy != inDpy) 266 XCloseDisplay(outDpy); 267 inDpy = outDpy = NULL; 268 return 0; 269} 270