1 /* $XConsortium: exec.c,v 1.13 94/04/17 20:24:20 rws Exp $ */
2 /*
3
4 Copyright (c) 1988 X Consortium
5
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 "Software"), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
13
14 The above copyright notice and this permission notice shall be included
15 in all copies or substantial portions of the Software.
16
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 OTHER DEALINGS IN THE SOFTWARE.
24
25 Except as contained in this notice, the name of the X Consortium shall
26 not be used in advertising or otherwise to promote the sale, use or
27 other dealings in this Software without prior written authorization
28 from the X Consortium.
29
30 */
31
32 /*
33 * Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
34 *
35 * All Rights Reserved
36 *
37 * Permission to use, copy, modify, and distribute this
38 * software and its documentation for any purpose and without
39 * fee is hereby granted, provided that the above copyright no-
40 * tice appear in all copies and that both that copyright no-
41 * tice and this permission notice appear in supporting docu-
42 * mentation, and that the name of Sun not be used in
43 * advertising or publicity pertaining to distribution of the
44 * software without specific prior written permission. Sun
45 * makes no representations about the suitability of this
46 * software for any purpose. It is provided "as is" without any
47 * express or implied warranty.
48 *
49 * SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
50 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
51 * NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
52 * ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
53 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
54 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
55 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
56 * THE USE OR PERFORMANCE OF THIS SOFTWARE.
57 *
58 * Author: Jim Fulton, MIT X Consortium; derived from parts of the
59 * original xmodmap, written by David Rosenthal, of Sun Microsystems.
60 */
61
62 #include <X11/Xos.h>
63 #include <X11/Xlib.h>
64 #include <stdio.h>
65 #include "xmodmap.h"
66 #include "wq.h"
67
mapping_busy_key(timeout)68 static void mapping_busy_key (timeout)
69 int timeout;
70 {
71 int i;
72 unsigned char keymap[32];
73 static unsigned int masktable[8] = {
74 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
75
76 XQueryKeymap (dpy, (char *) keymap);
77
78 fprintf (stderr,
79 "%s: please release the following keys within %d seconds:\n",
80 ProgramName, timeout);
81 for (i = 0; i < 256; i++) {
82 if (keymap[i >> 3] & masktable[i & 7]) {
83 KeySym ks = XKeycodeToKeysym (dpy, (KeyCode) i, 0);
84 char *cp = XKeysymToString (ks);
85 fprintf (stderr, " %s (keysym 0x%x, keycode %d)\n",
86 cp ? cp : "UNNAMED", (unsigned)ks, i);
87 }
88 }
89 sleep (timeout);
90 return;
91 }
92
mapping_busy_pointer(timeout)93 static void mapping_busy_pointer (timeout)
94 int timeout;
95 {
96 int i;
97 Window root, child; /* dummy variables */
98 int rx, ry, wx, wy; /* dummy variables */
99 unsigned int mask;
100 static unsigned int masks[5] = {
101 Button1Mask, Button2Mask, Button3Mask, Button4Mask, Button5Mask };
102
103 if (!XQueryPointer (dpy, RootWindow(dpy,DefaultScreen(dpy)),
104 &root, &child, &rx, &ry, &wx, &wy, &mask))
105 mask = 0;
106
107 fprintf (stderr,
108 "%s: please release the following buttons within %d seconds:\n",
109 ProgramName, timeout);
110 for (i = 0; i < 5; i++) {
111 if (mask & masks[i])
112 fprintf (stderr, " Button%d\n", i+1);
113 }
114 sleep (timeout);
115 return;
116 }
117
118
119 /*
120 * UpdateModifierMapping - this sends the modifier map to the server
121 * and deals with retransmissions due to the keyboard being busy.
122 */
123
UpdateModifierMapping(map)124 int UpdateModifierMapping (map)
125 XModifierKeymap *map;
126 {
127 int retries, timeout;
128
129 for (retries = 5, timeout = 2; retries > 0; retries--, timeout *= 2) {
130 int result;
131
132 result = XSetModifierMapping (dpy, map);
133 switch (result) {
134 case MappingSuccess: /* Success */
135 return (0);
136 case MappingBusy: /* Busy */
137 mapping_busy_key (timeout);
138 continue;
139 case MappingFailed:
140 fprintf (stderr, "%s: bad set modifier mapping.\n",
141 ProgramName);
142 return (-1);
143 default:
144 fprintf (stderr, "%s: bad return %d from XSetModifierMapping\n",
145 ProgramName, result);
146 return (-1);
147 }
148 }
149 fprintf (stderr,
150 "%s: unable to set modifier mapping, keyboard problem\n",
151 ProgramName);
152 return (-1);
153 }
154
155
156 /*
157 * AddModifier - this adds a keycode to the modifier list
158 */
159
AddModifier(mapp,keycode,modifier)160 int AddModifier (mapp, keycode, modifier)
161 XModifierKeymap **mapp;
162 KeyCode keycode;
163 int modifier;
164 {
165 if (keycode) {
166 *mapp = XInsertModifiermapEntry (*mapp, keycode, modifier);
167 return (0);
168 } else {
169 return (-1);
170 }
171 /*NOTREACHED*/
172 }
173
174
175 /*
176 * DeleteModifier - this removes a keycode from the modifier list
177 */
178
RemoveModifier(mapp,keycode,modifier)179 int RemoveModifier (mapp, keycode, modifier)
180 XModifierKeymap **mapp;
181 KeyCode keycode;
182 int modifier;
183 {
184 if (keycode) {
185 *mapp = XDeleteModifiermapEntry (*mapp, keycode, modifier);
186 return (0);
187 } else {
188 return (-1);
189 }
190 /*NOTREACHED*/
191 }
192
193
194 /*
195 * ClearModifier - this removes all entries from the modifier list
196 */
197
ClearModifier(mapp,modifier)198 int ClearModifier (mapp, modifier)
199 XModifierKeymap **mapp;
200 int modifier;
201 {
202 int i;
203 XModifierKeymap *map = *mapp;
204 KeyCode *kcp;
205
206 kcp = &map->modifiermap[modifier * map->max_keypermod];
207 for (i = 0; i < map->max_keypermod; i++) {
208 *kcp++ = (KeyCode) 0;
209 }
210 return (0);
211 }
212
213
214 /*
215 * print the contents of the map
216 */
217
PrintModifierMapping(map,fp)218 void PrintModifierMapping (map, fp)
219 XModifierKeymap *map;
220 FILE *fp;
221 {
222 int i, k = 0;
223
224 fprintf (fp,
225 "%s: up to %d keys per modifier, (keycodes in parentheses):\n\n",
226 ProgramName, map->max_keypermod);
227 for (i = 0; i < 8; i++) {
228 int j;
229
230 fprintf(fp, "%-10s", modifier_table[i].name);
231 for (j = 0; j < map->max_keypermod; j++) {
232 if (map->modifiermap[k]) {
233 KeySym ks = XKeycodeToKeysym(dpy, map->modifiermap[k], 0);
234 char *nm = XKeysymToString(ks);
235
236 fprintf (fp, "%s %s (0x%0x)", (j > 0 ? "," : ""),
237 (nm ? nm : "BadKey"), map->modifiermap[k]);
238 }
239 k++;
240 }
241 fprintf(fp, "\n");
242 }
243 fprintf (fp, "\n");
244 return;
245 }
246
247
PrintKeyTable(exprs,fp)248 void PrintKeyTable (exprs, fp)
249 Bool exprs;
250 FILE *fp;
251 {
252 int i;
253 int min_keycode, max_keycode, keysyms_per_keycode;
254 KeySym *keymap, *origkeymap;
255
256 XDisplayKeycodes (dpy, &min_keycode, &max_keycode);
257 origkeymap = XGetKeyboardMapping (dpy, min_keycode,
258 (max_keycode - min_keycode + 1),
259 &keysyms_per_keycode);
260
261 if (!origkeymap) {
262 fprintf (stderr, "%s: unable to get keyboard mapping table.\n",
263 ProgramName);
264 return;
265 }
266 if (!exprs) {
267 fprintf (fp,
268 "There are %d KeySyms per KeyCode; KeyCodes range from %d to %d.\n\n",
269 keysyms_per_keycode, min_keycode, max_keycode);
270 fprintf (fp, " KeyCode\tKeysym (Keysym)\t...\n");
271 fprintf (fp, " Value \tValue (Name) \t...\n\n");
272 }
273 keymap = origkeymap;
274 for (i = min_keycode; i <= max_keycode; i++) {
275 int j, max;
276
277 if (exprs)
278 fprintf(fp, "keycode %3d =", i);
279 else
280 fprintf(fp, " %3d \t", i);
281 max = keysyms_per_keycode - 1;
282 while ((max >= 0) && (keymap[max] == NoSymbol))
283 max--;
284 for (j = 0; j <= max; j++) {
285 register KeySym ks = keymap[j];
286 char *s;
287 if (ks != NoSymbol)
288 s = XKeysymToString (ks);
289 else
290 s = "NoSymbol";
291 if (!exprs)
292 fprintf (fp, "0x%04x (%s)\t", (unsigned)ks, s ? s : "no name");
293 else if (s)
294 fprintf (fp, " %s", s);
295 else
296 fprintf (fp, " 0x%04x", (unsigned)ks);
297 }
298 keymap += keysyms_per_keycode;
299 fprintf (fp, "\n");
300 }
301
302 XFree ((char *) origkeymap);
303 return;
304 }
305
306
PrintPointerMap(fp)307 void PrintPointerMap (fp)
308 FILE *fp;
309 {
310 unsigned char pmap[256]; /* there are 8 bits of buttons */
311 int count, i;
312
313 count = XGetPointerMapping (dpy, pmap, 256);
314
315 fprintf (fp, "There are %d pointer buttons defined.\n\n", count);
316 fprintf (fp, " Physical Button\n");
317 fprintf (fp, " Button Code\n");
318 /* " ### ###\n" */
319 for (i = 0; i < count; i++) {
320 fprintf (fp, " %3u %3u\n",
321 i+1, (unsigned int) pmap[i]);
322 }
323 fprintf (fp, "\n");
324 return;
325 }
326
327
328 /*
329 * SetPointerMap - set the pointer map
330 */
331
SetPointerMap(map,n)332 int SetPointerMap (map, n)
333 unsigned char *map;
334 int n;
335 {
336 unsigned char defmap[MAXBUTTONCODES];
337 int j;
338 int retries, timeout;
339
340 if (n == 0) { /* reset to default */
341 n = XGetPointerMapping (dpy, defmap, MAXBUTTONCODES);
342 for (j = 0; j < n; j++) defmap[j] = (unsigned char) (j + 1);
343 map = defmap;
344 }
345
346 for (retries = 5, timeout = 2; retries > 0; retries--, timeout *= 2) {
347 int result;
348
349 switch (result = XSetPointerMapping (dpy, map, n)) {
350 case MappingSuccess:
351 return 0;
352 case MappingBusy:
353 mapping_busy_pointer (timeout);
354 continue;
355 case MappingFailed:
356 fprintf (stderr, "%s: bad pointer mapping\n", ProgramName);
357 return -1;
358 default:
359 fprintf (stderr, "%s: bad return %d from XSetPointerMapping\n",
360 ProgramName, result);
361 return -1;
362 }
363 }
364 fprintf (stderr, "%s: unable to set pointer mapping\n", ProgramName);
365 return -1;
366 }
367