3 Copyright 1988, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
11 The above copyright notice and this permission notice shall be included
12 in all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 OTHER DEALINGS IN THE SOFTWARE.
22 Except as contained in this notice, the name of The Open Group shall
23 not be used in advertising or otherwise to promote the sale, use or
24 other dealings in this Software without prior written authorization
37 const char *ProgramName;
39 int min_keycode, max_keycode;
41 Bool dontExecute = False;
54 static void _X_NORETURN
55 FatalError(const char *message)
57 fprintf(stderr, "%s: %s\n", ProgramName, message);
62 /* sprintf variant found in newer libc's which allocates string to print to */
63 static int _X_ATTRIBUTE_PRINTF(2,3)
64 asprintf(char ** ret, const char *format, ...)
71 len = vsnprintf(buf, sizeof(buf), format, ap);
77 if (len < sizeof(buf))
83 *ret = malloc(len + 1); /* snprintf doesn't count trailing '\0' */
87 len = vsnprintf(*ret, len + 1, format, ap);
101 #endif /* HAVE_ASPRINTF */
103 static const char help_message[] =
104 "\nwhere options include:\n"
105 " -display host:dpy X server to use\n"
106 " -verbose, -quiet turn logging on or off\n"
107 " -n don't execute changes, just show like make\n"
108 " -e expression execute string\n"
109 " -pm print modifier map\n"
110 " -pk print keymap table\n"
111 " -pke print keymap table as expressions\n"
112 " -pp print pointer map\n"
113 " -grammar print out short help on allowable input\n"
114 " - read standard input\n"
122 fprintf (stderr, "usage: %s [-options ...] [filename]\n", ProgramName);
123 fprintf (stderr, "%s\n", help_message);
127 static const char grammar_message[] =
128 " pointer = default reset pointer buttons to default\n"
129 " pointer = NUMBER ... set pointer button codes\n"
130 " keycode NUMBER = [KEYSYM ...] map keycode to given keysyms\n"
131 " keysym KEYSYM = [KEYSYM ...] look up keysym and do a keycode operation\n"
132 " clear MODIFIER remove all keys for this modifier\n"
133 " add MODIFIER = KEYSYM ... add the keysyms to the modifier\n"
134 " remove MODIFIER = KEYSYM ... remove the keysyms from the modifier\n"
136 "where NUMBER is a decimal, octal, or hex constant; KEYSYM is a valid\n"
137 "Key Symbol name; and MODIFIER is one of the eight modifier names: Shift,\n"
138 "Lock, Control, Mod1, Mod2, Mod3, Mod4, or Mod5. Lines beginning with\n"
139 "an exclamation mark (!) are taken as comments. Case is significant except\n"
140 "for MODIFIER names.\n"
142 "Keysyms on the left hand side of the = sign are looked up before any changes\n"
143 "are made; keysyms on the right are looked up after all of those on the left\n"
144 "have been resolved. This makes it possible to swap modifier keys.\n"
152 fprintf (stderr, "%s accepts the following input expressions:\n\n",
154 fprintf (stderr, "%s\n", grammar_message);
158 int parse_errors = 0;
161 main(int argc, char *argv[])
164 char *displayname = NULL;
166 Bool printMap = False;
167 Bool printKeyTable = False;
168 Bool printKeyTableExprs = False;
169 Bool printPointerMap = False;
170 Bool didAnything = False;
172 ProgramName = argv[0];
175 * scan the arg list once to find out which display to use
178 for (i = 1; i < argc; i++) {
179 if (strncmp (argv[i], "-d", 2) == 0) {
180 if (++i >= argc) usage ();
181 displayname = argv[i];
185 dpy = XOpenDisplay (displayname);
187 fprintf (stderr, "%s: unable to open display '%s'\n",
188 ProgramName, XDisplayName (displayname));
192 XDisplayKeycodes (dpy, &min_keycode, &max_keycode);
197 * scan the arg list again to do the actual work (since it requires
198 * the display being open.
201 for (i = 1; i < argc; i++) {
206 case 'd': /* -display host:dpy */
207 ++i; /* handled above */
209 case 'v': /* -verbose */
212 case 'q': /* -quiet */
215 case 'n': /* -n (like make) */
218 case 'e': /* -e expression */
220 if (++i >= argc) usage ();
221 process_line (argv[i]);
223 case 'p': /* -p... */
229 case 'k': /* -pk, -pke */
232 printKeyTable = True;
235 printKeyTableExprs = True;
242 printPointerMap = True;
250 case 'g': /* -grammar */
253 case '\0': /* - (use standard input) */
259 * provide old xmodmap args
263 process_line ("clear shift");
267 process_line ("clear lock");
271 process_line ("clear control");
278 char cmd[11] = "clear modX";
288 if (++i >= argc) usage ();
289 if (asprintf (&cmd, "remove %s = %s",
290 ((arg[1] == 's') ? "shift" :
291 ((arg[1] == 'l') ? "lock" :
292 "control")), argv[i]) == -1)
293 FatalError("Could not allocate memory for remove cmd");
301 } else if (arg[0] == '+') { /* old xmodmap args */
310 if (++i >= argc) usage ();
311 if (asprintf (&cmd, "add mod%c = %s", arg[1], argv[i]) == -1)
312 FatalError("Could not allocate memory for add cmd");
319 arg[1] = tolower (arg[1]);
320 /* fall through to handler below */
326 if (++i >= argc) usage ();
327 if (asprintf (&cmd, "add %s = %s",
328 ((arg[1] == 's') ? "shift" :
329 ((arg[1] == 'l') ? "lock" :
330 "control")), argv[i]) == -1)
331 FatalError("Could not allocate memory for remove cmd");
345 /* for compatibility */
346 if (!didAnything) printMap = True;
349 * at this point, the work list has been built and we can view it or
358 if (parse_errors != 0) {
359 fprintf (stderr, "%s: %d error%s encountered, aborting.\n",
360 ProgramName, parse_errors,
361 (parse_errors == 1 ? "" : "s"));
362 status = -1; /* return an error condition */
364 status = execute_work_queue ();
368 print_modifier_map ();
372 print_key_table (False);
375 if (printKeyTableExprs) {
376 print_key_table (True);
379 if (printPointerMap) {
380 print_pointer_map ();
383 Exit (status < 0 ? 1 : 0);