xmodmap.c revision 1a30de1f
11a30de1fSmrg/* $Xorg: xmodmap.c,v 1.4 2001/02/09 02:05:56 xorgcvs Exp $ */ 21a30de1fSmrg/* 31a30de1fSmrg 41a30de1fSmrgCopyright 1988, 1998 The Open Group 51a30de1fSmrg 61a30de1fSmrgPermission to use, copy, modify, distribute, and sell this software and its 71a30de1fSmrgdocumentation for any purpose is hereby granted without fee, provided that 81a30de1fSmrgthe above copyright notice appear in all copies and that both that 91a30de1fSmrgcopyright notice and this permission notice appear in supporting 101a30de1fSmrgdocumentation. 111a30de1fSmrg 121a30de1fSmrgThe above copyright notice and this permission notice shall be included 131a30de1fSmrgin all copies or substantial portions of the Software. 141a30de1fSmrg 151a30de1fSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 161a30de1fSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 171a30de1fSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 181a30de1fSmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 191a30de1fSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 201a30de1fSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 211a30de1fSmrgOTHER DEALINGS IN THE SOFTWARE. 221a30de1fSmrg 231a30de1fSmrgExcept as contained in this notice, the name of The Open Group shall 241a30de1fSmrgnot be used in advertising or otherwise to promote the sale, use or 251a30de1fSmrgother dealings in this Software without prior written authorization 261a30de1fSmrgfrom The Open Group. 271a30de1fSmrg 281a30de1fSmrg*/ 291a30de1fSmrg/* $XFree86: xc/programs/xmodmap/xmodmap.c,v 1.8tsi Exp $ */ 301a30de1fSmrg 311a30de1fSmrg#include <X11/Xos.h> 321a30de1fSmrg#include <X11/Xlib.h> 331a30de1fSmrg#include <stdio.h> 341a30de1fSmrg#include <stdlib.h> 351a30de1fSmrg#include <ctype.h> 361a30de1fSmrg#include "xmodmap.h" 371a30de1fSmrg 381a30de1fSmrgconst char *ProgramName; 391a30de1fSmrgDisplay *dpy = NULL; 401a30de1fSmrgint min_keycode, max_keycode; 411a30de1fSmrgBool verbose = False; 421a30de1fSmrgBool dontExecute = False; 431a30de1fSmrg 441a30de1fSmrgstatic void 451a30de1fSmrgExit(int status) 461a30de1fSmrg{ 471a30de1fSmrg if (dpy) { 481a30de1fSmrg XCloseDisplay (dpy); 491a30de1fSmrg dpy = NULL; 501a30de1fSmrg } 511a30de1fSmrg exit (status); 521a30de1fSmrg} 531a30de1fSmrg 541a30de1fSmrgvoid * 551a30de1fSmrgchk_malloc(size_t n_bytes) 561a30de1fSmrg{ 571a30de1fSmrg void *buf = malloc(n_bytes); 581a30de1fSmrg if (!buf) { 591a30de1fSmrg fprintf(stderr, "%s: Could not allocate %d bytes\n", ProgramName, (int)n_bytes); 601a30de1fSmrg Exit(-1); 611a30de1fSmrg } 621a30de1fSmrg return buf; 631a30de1fSmrg} 641a30de1fSmrg 651a30de1fSmrgstatic const char help_message[] = 661a30de1fSmrg"\nwhere options include:\n" 671a30de1fSmrg" -display host:dpy X server to use\n" 681a30de1fSmrg" -verbose, -quiet turn logging on or off\n" 691a30de1fSmrg" -n don't execute changes, just show like make\n" 701a30de1fSmrg" -e expression execute string\n" 711a30de1fSmrg" -pm print modifier map\n" 721a30de1fSmrg" -pk print keymap table\n" 731a30de1fSmrg" -pke print keymap table as expressions\n" 741a30de1fSmrg" -pp print pointer map\n" 751a30de1fSmrg" -grammar print out short help on allowable input\n" 761a30de1fSmrg" - read standard input\n" 771a30de1fSmrg"\n"; 781a30de1fSmrg 791a30de1fSmrg 801a30de1fSmrgstatic void 811a30de1fSmrgusage(void) 821a30de1fSmrg{ 831a30de1fSmrg fprintf (stderr, "usage: %s [-options ...] [filename]\n", ProgramName); 841a30de1fSmrg fprintf (stderr, "%s\n", help_message); 851a30de1fSmrg Exit (1); 861a30de1fSmrg} 871a30de1fSmrg 881a30de1fSmrgstatic const char grammar_message[] = 891a30de1fSmrg" pointer = default reset pointer buttons to default\n" 901a30de1fSmrg" pointer = NUMBER ... set pointer button codes\n" 911a30de1fSmrg" keycode NUMBER = [KEYSYM ...] map keycode to given keysyms\n" 921a30de1fSmrg" keysym KEYSYM = [KEYSYM ...] look up keysym and do a keycode operation\n" 931a30de1fSmrg" clear MODIFIER remove all keys for this modifier\n" 941a30de1fSmrg" add MODIFIER = KEYSYM ... add the keysyms to the modifier\n" 951a30de1fSmrg" remove MODIFIER = KEYSYM ... remove the keysyms from the modifier\n" 961a30de1fSmrg"\n" 971a30de1fSmrg"where NUMBER is a decimal, octal, or hex constant; KEYSYM is a valid\n" 981a30de1fSmrg"Key Symbol name; and MODIFIER is one of the eight modifier names: Shift,\n" 991a30de1fSmrg"Lock, Control, Mod1, Mod2, Mod3, Mod4, or Mod5. Lines beginning with\n" 1001a30de1fSmrg"an exclamation mark (!) are taken as comments. Case is significant except\n" 1011a30de1fSmrg"for MODIFIER names.\n" 1021a30de1fSmrg"\n" 1031a30de1fSmrg"Keysyms on the left hand side of the = sign are looked up before any changes\n" 1041a30de1fSmrg"are made; keysyms on the right are looked up after all of those on the left\n" 1051a30de1fSmrg"have been resolved. This makes it possible to swap modifier keys.\n" 1061a30de1fSmrg"\n"; 1071a30de1fSmrg 1081a30de1fSmrg 1091a30de1fSmrgstatic void 1101a30de1fSmrggrammar_usage(void) 1111a30de1fSmrg{ 1121a30de1fSmrg fprintf (stderr, "%s accepts the following input expressions:\n\n", 1131a30de1fSmrg ProgramName); 1141a30de1fSmrg fprintf (stderr, "%s\n", grammar_message); 1151a30de1fSmrg Exit (0); 1161a30de1fSmrg} 1171a30de1fSmrg 1181a30de1fSmrgint parse_errors = 0; 1191a30de1fSmrg 1201a30de1fSmrgint 1211a30de1fSmrgmain(int argc, char *argv[]) 1221a30de1fSmrg{ 1231a30de1fSmrg int i; 1241a30de1fSmrg char *displayname = NULL; 1251a30de1fSmrg int status; 1261a30de1fSmrg Bool printMap = False; 1271a30de1fSmrg Bool printKeyTable = False; 1281a30de1fSmrg Bool printKeyTableExprs = False; 1291a30de1fSmrg Bool printPointerMap = False; 1301a30de1fSmrg Bool didAnything = False; 1311a30de1fSmrg 1321a30de1fSmrg ProgramName = argv[0]; 1331a30de1fSmrg 1341a30de1fSmrg /* 1351a30de1fSmrg * scan the arg list once to find out which display to use 1361a30de1fSmrg */ 1371a30de1fSmrg 1381a30de1fSmrg for (i = 1; i < argc; i++) { 1391a30de1fSmrg if (strncmp (argv[i], "-d", 2) == 0) { 1401a30de1fSmrg if (++i >= argc) usage (); 1411a30de1fSmrg displayname = argv[i]; 1421a30de1fSmrg } 1431a30de1fSmrg } 1441a30de1fSmrg 1451a30de1fSmrg dpy = XOpenDisplay (displayname); 1461a30de1fSmrg if (!dpy) { 1471a30de1fSmrg fprintf (stderr, "%s: unable to open display '%s'\n", 1481a30de1fSmrg ProgramName, XDisplayName (displayname)); 1491a30de1fSmrg Exit (1); 1501a30de1fSmrg } 1511a30de1fSmrg 1521a30de1fSmrg XDisplayKeycodes (dpy, &min_keycode, &max_keycode); 1531a30de1fSmrg 1541a30de1fSmrg initialize_map (); 1551a30de1fSmrg 1561a30de1fSmrg /* 1571a30de1fSmrg * scan the arg list again to do the actual work (since it requires 1581a30de1fSmrg * the display being open. 1591a30de1fSmrg */ 1601a30de1fSmrg 1611a30de1fSmrg status = 0; 1621a30de1fSmrg for (i = 1; i < argc; i++) { 1631a30de1fSmrg char *arg = argv[i]; 1641a30de1fSmrg 1651a30de1fSmrg if (arg[0] == '-') { 1661a30de1fSmrg switch (arg[1]) { 1671a30de1fSmrg case 'd': /* -display host:dpy */ 1681a30de1fSmrg ++i; /* handled above */ 1691a30de1fSmrg continue; 1701a30de1fSmrg case 'v': /* -verbose */ 1711a30de1fSmrg verbose = True; 1721a30de1fSmrg continue; 1731a30de1fSmrg case 'q': /* -quiet */ 1741a30de1fSmrg verbose = False; 1751a30de1fSmrg continue; 1761a30de1fSmrg case 'n': /* -n (like make) */ 1771a30de1fSmrg dontExecute = True; 1781a30de1fSmrg continue; 1791a30de1fSmrg case 'e': /* -e expression */ 1801a30de1fSmrg didAnything = True; 1811a30de1fSmrg if (++i >= argc) usage (); 1821a30de1fSmrg process_line (argv[i]); 1831a30de1fSmrg continue; 1841a30de1fSmrg case 'p': /* -p... */ 1851a30de1fSmrg switch (arg[2]) { 1861a30de1fSmrg case '\0': 1871a30de1fSmrg case 'm': /* -pm */ 1881a30de1fSmrg printMap = True; 1891a30de1fSmrg break; 1901a30de1fSmrg case 'k': /* -pk, -pke */ 1911a30de1fSmrg switch (arg[3]) { 1921a30de1fSmrg case '\0': 1931a30de1fSmrg printKeyTable = True; 1941a30de1fSmrg break; 1951a30de1fSmrg case 'e': 1961a30de1fSmrg printKeyTableExprs = True; 1971a30de1fSmrg break; 1981a30de1fSmrg default: 1991a30de1fSmrg usage (); 2001a30de1fSmrg } 2011a30de1fSmrg break; 2021a30de1fSmrg case 'p': /* -pp */ 2031a30de1fSmrg printPointerMap = True; 2041a30de1fSmrg break; 2051a30de1fSmrg default: 2061a30de1fSmrg usage (); 2071a30de1fSmrg /* NOTREACHED */ 2081a30de1fSmrg } 2091a30de1fSmrg didAnything = True; 2101a30de1fSmrg continue; 2111a30de1fSmrg case 'g': /* -grammar */ 2121a30de1fSmrg grammar_usage (); 2131a30de1fSmrg /*NOTREACHED*/ 2141a30de1fSmrg case '\0': /* - (use standard input) */ 2151a30de1fSmrg didAnything = True; 2161a30de1fSmrg process_file (NULL); 2171a30de1fSmrg continue; 2181a30de1fSmrg 2191a30de1fSmrg /* 2201a30de1fSmrg * provide old xmodmap args 2211a30de1fSmrg */ 2221a30de1fSmrg case 'S': 2231a30de1fSmrg didAnything = True; 2241a30de1fSmrg process_line ("clear shift"); 2251a30de1fSmrg continue; 2261a30de1fSmrg case 'L': 2271a30de1fSmrg didAnything = True; 2281a30de1fSmrg process_line ("clear lock"); 2291a30de1fSmrg continue; 2301a30de1fSmrg case 'C': 2311a30de1fSmrg didAnything = True; 2321a30de1fSmrg process_line ("clear control"); 2331a30de1fSmrg continue; 2341a30de1fSmrg case '1': 2351a30de1fSmrg case '2': 2361a30de1fSmrg case '3': 2371a30de1fSmrg case '4': 2381a30de1fSmrg case '5': { 2391a30de1fSmrg char cmd[11] = "clear modX"; 2401a30de1fSmrg cmd[9] = arg[1]; 2411a30de1fSmrg process_line (cmd); 2421a30de1fSmrg continue; 2431a30de1fSmrg } 2441a30de1fSmrg case 's': 2451a30de1fSmrg case 'l': 2461a30de1fSmrg case 'c': { 2471a30de1fSmrg char *cmd; 2481a30de1fSmrg didAnything = True; 2491a30de1fSmrg if (++i >= argc) usage (); 2501a30de1fSmrg cmd = chk_malloc (strlen ("remove control = ") + strlen (argv[i]) + 1); 2511a30de1fSmrg (void) sprintf (cmd, "remove %s = %s", 2521a30de1fSmrg ((arg[1] == 's') ? "shift" : 2531a30de1fSmrg ((arg[1] == 'l') ? "lock" : 2541a30de1fSmrg "control")), argv[i]); 2551a30de1fSmrg process_line (cmd); 2561a30de1fSmrg continue; 2571a30de1fSmrg } 2581a30de1fSmrg default: 2591a30de1fSmrg usage (); 2601a30de1fSmrg /*NOTREACHED*/ 2611a30de1fSmrg } 2621a30de1fSmrg } else if (arg[0] == '+') { /* old xmodmap args */ 2631a30de1fSmrg switch (arg[1]) { 2641a30de1fSmrg case '1': 2651a30de1fSmrg case '2': 2661a30de1fSmrg case '3': 2671a30de1fSmrg case '4': 2681a30de1fSmrg case '5': { 2691a30de1fSmrg char *cmd; 2701a30de1fSmrg didAnything = True; 2711a30de1fSmrg if (++i >= argc) usage (); 2721a30de1fSmrg cmd = chk_malloc (strlen ("add modX = ") + strlen (argv[i]) + 1); 2731a30de1fSmrg (void) sprintf (cmd, "add mod%c = %s", arg[1], argv[i]); 2741a30de1fSmrg process_line (cmd); 2751a30de1fSmrg continue; 2761a30de1fSmrg } 2771a30de1fSmrg case 'S': 2781a30de1fSmrg case 'L': 2791a30de1fSmrg case 'C': 2801a30de1fSmrg arg[1] = tolower (arg[1]); 2811a30de1fSmrg /* fall through to handler below */ 2821a30de1fSmrg case 's': 2831a30de1fSmrg case 'l': 2841a30de1fSmrg case 'c': { 2851a30de1fSmrg char *cmd; 2861a30de1fSmrg didAnything = True; 2871a30de1fSmrg if (++i >= argc) usage (); 2881a30de1fSmrg cmd = chk_malloc (strlen ("add control = ") + strlen (argv[i]) + 1); 2891a30de1fSmrg (void) sprintf (cmd, "add %s = %s", 2901a30de1fSmrg ((arg[1] == 's') ? "shift" : 2911a30de1fSmrg ((arg[1] == 'l') ? "lock" : 2921a30de1fSmrg "control")), argv[i]); 2931a30de1fSmrg process_line (cmd); 2941a30de1fSmrg continue; 2951a30de1fSmrg } 2961a30de1fSmrg default: 2971a30de1fSmrg usage (); 2981a30de1fSmrg } 2991a30de1fSmrg } else { 3001a30de1fSmrg didAnything = True; 3011a30de1fSmrg process_file (arg); 3021a30de1fSmrg continue; 3031a30de1fSmrg } 3041a30de1fSmrg } /* end for loop */ 3051a30de1fSmrg 3061a30de1fSmrg /* for compatibility */ 3071a30de1fSmrg if (!didAnything) printMap = True; 3081a30de1fSmrg 3091a30de1fSmrg /* 3101a30de1fSmrg * at this point, the work list has been built and we can view it or 3111a30de1fSmrg * execute it 3121a30de1fSmrg */ 3131a30de1fSmrg 3141a30de1fSmrg if (dontExecute) { 3151a30de1fSmrg print_work_queue (); 3161a30de1fSmrg Exit (0); 3171a30de1fSmrg } 3181a30de1fSmrg 3191a30de1fSmrg if (parse_errors != 0) { 3201a30de1fSmrg fprintf (stderr, "%s: %d error%s encountered, aborting.\n", 3211a30de1fSmrg ProgramName, parse_errors, 3221a30de1fSmrg (parse_errors == 1 ? "" : "s")); 3231a30de1fSmrg status = -1; /* return an error condition */ 3241a30de1fSmrg } else { 3251a30de1fSmrg status = execute_work_queue (); 3261a30de1fSmrg } 3271a30de1fSmrg 3281a30de1fSmrg if (printMap) { 3291a30de1fSmrg print_modifier_map (); 3301a30de1fSmrg } 3311a30de1fSmrg 3321a30de1fSmrg if (printKeyTable) { 3331a30de1fSmrg print_key_table (False); 3341a30de1fSmrg } 3351a30de1fSmrg 3361a30de1fSmrg if (printKeyTableExprs) { 3371a30de1fSmrg print_key_table (True); 3381a30de1fSmrg } 3391a30de1fSmrg 3401a30de1fSmrg if (printPointerMap) { 3411a30de1fSmrg print_pointer_map (); 3421a30de1fSmrg } 3431a30de1fSmrg 3441a30de1fSmrg Exit (status < 0 ? 1 : 0); 3451a30de1fSmrg 3461a30de1fSmrg /* Muffle gcc */ 3471a30de1fSmrg return 0; 3481a30de1fSmrg} 3491a30de1fSmrg 350