exec.c revision ce62200c
11a30de1fSmrg/* $XdotOrg: exec.c,v 1.4 2001/02/09 02:05:56 xorgcvs Exp $ */ 21a30de1fSmrg/* $Xorg: exec.c,v 1.4 2001/02/09 02:05:56 xorgcvs Exp $ */ 31a30de1fSmrg/* 41a30de1fSmrg 51a30de1fSmrgCopyright 1988, 1998 The Open Group 61a30de1fSmrg 71a30de1fSmrgPermission to use, copy, modify, distribute, and sell this software and its 81a30de1fSmrgdocumentation for any purpose is hereby granted without fee, provided that 91a30de1fSmrgthe above copyright notice appear in all copies and that both that 101a30de1fSmrgcopyright notice and this permission notice appear in supporting 111a30de1fSmrgdocumentation. 121a30de1fSmrg 131a30de1fSmrgThe above copyright notice and this permission notice shall be included 141a30de1fSmrgin all copies or substantial portions of the Software. 151a30de1fSmrg 161a30de1fSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 171a30de1fSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 181a30de1fSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 191a30de1fSmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 201a30de1fSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 211a30de1fSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 221a30de1fSmrgOTHER DEALINGS IN THE SOFTWARE. 231a30de1fSmrg 241a30de1fSmrgExcept as contained in this notice, the name of The Open Group shall 251a30de1fSmrgnot be used in advertising or otherwise to promote the sale, use or 261a30de1fSmrgother dealings in this Software without prior written authorization 271a30de1fSmrgfrom The Open Group. 281a30de1fSmrg 291a30de1fSmrg*/ 301a30de1fSmrg 311a30de1fSmrg/* 32ce62200cSmrg * Copyright (c) 1987, Oracle and/or its affiliates. All rights reserved. 331a30de1fSmrg * 34ce62200cSmrg * Permission is hereby granted, free of charge, to any person obtaining a 35ce62200cSmrg * copy of this software and associated documentation files (the "Software"), 36ce62200cSmrg * to deal in the Software without restriction, including without limitation 37ce62200cSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 38ce62200cSmrg * and/or sell copies of the Software, and to permit persons to whom the 39ce62200cSmrg * Software is furnished to do so, subject to the following conditions: 401a30de1fSmrg * 41ce62200cSmrg * The above copyright notice and this permission notice (including the next 42ce62200cSmrg * paragraph) shall be included in all copies or substantial portions of the 43ce62200cSmrg * Software. 44ce62200cSmrg * 45ce62200cSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 46ce62200cSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 47ce62200cSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 48ce62200cSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 49ce62200cSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 50ce62200cSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 51ce62200cSmrg * DEALINGS IN THE SOFTWARE. 52ce62200cSmrg */ 53ce62200cSmrg 54ce62200cSmrg/* 551a30de1fSmrg * Author: Jim Fulton, MIT X Consortium; derived from parts of the 561a30de1fSmrg * original xmodmap, written by David Rosenthal, of Sun Microsystems. 571a30de1fSmrg */ 581a30de1fSmrg/* $XFree86: xc/programs/xmodmap/exec.c,v 1.5 2001/12/14 20:02:13 dawes Exp $ */ 591a30de1fSmrg 601a30de1fSmrg#include <X11/Xos.h> 611a30de1fSmrg#include <X11/Xlib.h> 621a30de1fSmrg#include <stdio.h> 631a30de1fSmrg#include "xmodmap.h" 641a30de1fSmrg#include "wq.h" 651a30de1fSmrg 661a30de1fSmrgstatic void 671a30de1fSmrgmapping_busy_key(int timeout) 681a30de1fSmrg{ 691a30de1fSmrg int i; 701a30de1fSmrg unsigned char keymap[32]; 711a30de1fSmrg static unsigned int masktable[8] = { 721a30de1fSmrg 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; 731a30de1fSmrg 741a30de1fSmrg XQueryKeymap (dpy, (char *) keymap); 751a30de1fSmrg 761a30de1fSmrg fprintf (stderr, 771a30de1fSmrg "%s: please release the following keys within %d seconds:\n", 781a30de1fSmrg ProgramName, timeout); 791a30de1fSmrg for (i = 0; i < 256; i++) { 801a30de1fSmrg if (keymap[i >> 3] & masktable[i & 7]) { 811a30de1fSmrg KeySym ks = XKeycodeToKeysym (dpy, (KeyCode) i, 0); 821a30de1fSmrg char *cp = XKeysymToString (ks); 831a30de1fSmrg fprintf (stderr, " %s (keysym 0x%x, keycode %d)\n", 841a30de1fSmrg cp ? cp : "UNNAMED", (unsigned int)ks, i); 851a30de1fSmrg } 861a30de1fSmrg } 871a30de1fSmrg sleep (timeout); 881a30de1fSmrg return; 891a30de1fSmrg} 901a30de1fSmrg 911a30de1fSmrgstatic void 921a30de1fSmrgmapping_busy_pointer(int timeout) 931a30de1fSmrg{ 941a30de1fSmrg int i; 951a30de1fSmrg Window root, child; /* dummy variables */ 961a30de1fSmrg int rx, ry, wx, wy; /* dummy variables */ 971a30de1fSmrg unsigned int mask; 981a30de1fSmrg static unsigned int masks[5] = { 991a30de1fSmrg Button1Mask, Button2Mask, Button3Mask, Button4Mask, Button5Mask }; 1001a30de1fSmrg 1011a30de1fSmrg if (!XQueryPointer (dpy, RootWindow(dpy,DefaultScreen(dpy)), 1021a30de1fSmrg &root, &child, &rx, &ry, &wx, &wy, &mask)) 1031a30de1fSmrg mask = 0; 1041a30de1fSmrg 1051a30de1fSmrg fprintf (stderr, 1061a30de1fSmrg "%s: please release the following buttons within %d seconds:\n", 1071a30de1fSmrg ProgramName, timeout); 1081a30de1fSmrg for (i = 0; i < 5; i++) { 1091a30de1fSmrg if (mask & masks[i]) 1101a30de1fSmrg fprintf (stderr, " Button%d\n", i+1); 1111a30de1fSmrg } 1121a30de1fSmrg sleep (timeout); 1131a30de1fSmrg return; 1141a30de1fSmrg} 1151a30de1fSmrg 1161a30de1fSmrg 1171a30de1fSmrg/* 1181a30de1fSmrg * UpdateModifierMapping - this sends the modifier map to the server 1191a30de1fSmrg * and deals with retransmissions due to the keyboard being busy. 1201a30de1fSmrg */ 1211a30de1fSmrg 1221a30de1fSmrgint 1231a30de1fSmrgUpdateModifierMapping(XModifierKeymap *map) 1241a30de1fSmrg{ 1251a30de1fSmrg int retries, timeout; 1261a30de1fSmrg 1271a30de1fSmrg for (retries = 5, timeout = 2; retries > 0; retries--, timeout *= 2) { 1281a30de1fSmrg int result; 1291a30de1fSmrg 1301a30de1fSmrg result = XSetModifierMapping (dpy, map); 1311a30de1fSmrg switch (result) { 1321a30de1fSmrg case MappingSuccess: /* Success */ 1331a30de1fSmrg return (0); 1341a30de1fSmrg case MappingBusy: /* Busy */ 1351a30de1fSmrg mapping_busy_key (timeout); 1361a30de1fSmrg continue; 1371a30de1fSmrg case MappingFailed: 1381a30de1fSmrg fprintf (stderr, "%s: bad set modifier mapping.\n", 1391a30de1fSmrg ProgramName); 1401a30de1fSmrg return (-1); 1411a30de1fSmrg default: 1421a30de1fSmrg fprintf (stderr, "%s: bad return %d from XSetModifierMapping\n", 1431a30de1fSmrg ProgramName, result); 1441a30de1fSmrg return (-1); 1451a30de1fSmrg } 1461a30de1fSmrg } 1471a30de1fSmrg fprintf (stderr, 1481a30de1fSmrg "%s: unable to set modifier mapping, keyboard problem\n", 1491a30de1fSmrg ProgramName); 1501a30de1fSmrg return (-1); 1511a30de1fSmrg} 1521a30de1fSmrg 1531a30de1fSmrg 1541a30de1fSmrg/* 1551a30de1fSmrg * AddModifier - this adds a keycode to the modifier list 1561a30de1fSmrg */ 1571a30de1fSmrg 1581a30de1fSmrgint 1591a30de1fSmrgAddModifier(XModifierKeymap **mapp, KeyCode keycode, int modifier) 1601a30de1fSmrg{ 1611a30de1fSmrg if (keycode) { 1621a30de1fSmrg *mapp = XInsertModifiermapEntry (*mapp, keycode, modifier); 1631a30de1fSmrg return (0); 1641a30de1fSmrg } else { 1651a30de1fSmrg return (-1); 1661a30de1fSmrg } 1671a30de1fSmrg /*NOTREACHED*/ 1681a30de1fSmrg} 1691a30de1fSmrg 1701a30de1fSmrg 1711a30de1fSmrg/* 1721a30de1fSmrg * DeleteModifier - this removes a keycode from the modifier list 1731a30de1fSmrg */ 1741a30de1fSmrg 1751a30de1fSmrgint 1761a30de1fSmrgRemoveModifier(XModifierKeymap **mapp, KeyCode keycode, int modifier) 1771a30de1fSmrg{ 1781a30de1fSmrg if (keycode) { 1791a30de1fSmrg *mapp = XDeleteModifiermapEntry (*mapp, keycode, modifier); 1801a30de1fSmrg return (0); 1811a30de1fSmrg } else { 1821a30de1fSmrg return (-1); 1831a30de1fSmrg } 1841a30de1fSmrg /*NOTREACHED*/ 1851a30de1fSmrg} 1861a30de1fSmrg 1871a30de1fSmrg 1881a30de1fSmrg/* 1891a30de1fSmrg * ClearModifier - this removes all entries from the modifier list 1901a30de1fSmrg */ 1911a30de1fSmrg 1921a30de1fSmrgint 1931a30de1fSmrgClearModifier(XModifierKeymap **mapp, int modifier) 1941a30de1fSmrg{ 1951a30de1fSmrg int i; 1961a30de1fSmrg XModifierKeymap *map = *mapp; 1971a30de1fSmrg KeyCode *kcp; 1981a30de1fSmrg 1991a30de1fSmrg kcp = &map->modifiermap[modifier * map->max_keypermod]; 2001a30de1fSmrg for (i = 0; i < map->max_keypermod; i++) { 2011a30de1fSmrg *kcp++ = (KeyCode) 0; 2021a30de1fSmrg } 2031a30de1fSmrg return (0); 2041a30de1fSmrg} 2051a30de1fSmrg 2061a30de1fSmrg 2071a30de1fSmrg/* 2081a30de1fSmrg * print the contents of the map 2091a30de1fSmrg */ 2101a30de1fSmrgvoid 2111a30de1fSmrgPrintModifierMapping(XModifierKeymap *map, FILE *fp) 2121a30de1fSmrg{ 2131a30de1fSmrg int i, k = 0; 2141a30de1fSmrg int min_keycode, max_keycode, keysyms_per_keycode = 0; 2151a30de1fSmrg 2161a30de1fSmrg XDisplayKeycodes (dpy, &min_keycode, &max_keycode); 2171a30de1fSmrg XGetKeyboardMapping (dpy, min_keycode, (max_keycode - min_keycode + 1), 2181a30de1fSmrg &keysyms_per_keycode); 2191a30de1fSmrg 2201a30de1fSmrg fprintf (fp, 2211a30de1fSmrg "%s: up to %d keys per modifier, (keycodes in parentheses):\n\n", 2221a30de1fSmrg ProgramName, map->max_keypermod); 2231a30de1fSmrg for (i = 0; i < 8; i++) { 2241a30de1fSmrg int j; 2251a30de1fSmrg 2261a30de1fSmrg fprintf(fp, "%-10s", modifier_table[i].name); 2271a30de1fSmrg for (j = 0; j < map->max_keypermod; j++) { 2281a30de1fSmrg if (map->modifiermap[k]) { 2291a30de1fSmrg KeySym ks; 2301a30de1fSmrg int index = 0; 2311a30de1fSmrg char *nm; 2321a30de1fSmrg do { 2331a30de1fSmrg ks = XKeycodeToKeysym(dpy, map->modifiermap[k], index); 2341a30de1fSmrg index++; 2351a30de1fSmrg } while ( !ks && index < keysyms_per_keycode); 2361a30de1fSmrg nm = XKeysymToString(ks); 2371a30de1fSmrg 2381a30de1fSmrg fprintf (fp, "%s %s (0x%0x)", (j > 0 ? "," : ""), 2391a30de1fSmrg (nm ? nm : "BadKey"), map->modifiermap[k]); 2401a30de1fSmrg } 2411a30de1fSmrg k++; 2421a30de1fSmrg } 2431a30de1fSmrg fprintf(fp, "\n"); 2441a30de1fSmrg } 2451a30de1fSmrg fprintf (fp, "\n"); 2461a30de1fSmrg return; 2471a30de1fSmrg} 2481a30de1fSmrg 2491a30de1fSmrgvoid 2501a30de1fSmrgPrintKeyTable(Bool exprs, FILE *fp) 2511a30de1fSmrg{ 2521a30de1fSmrg int i; 2531a30de1fSmrg int min_keycode, max_keycode, keysyms_per_keycode; 2541a30de1fSmrg KeySym *keymap, *origkeymap; 2551a30de1fSmrg 2561a30de1fSmrg XDisplayKeycodes (dpy, &min_keycode, &max_keycode); 2571a30de1fSmrg origkeymap = XGetKeyboardMapping (dpy, min_keycode, 2581a30de1fSmrg (max_keycode - min_keycode + 1), 2591a30de1fSmrg &keysyms_per_keycode); 2601a30de1fSmrg 2611a30de1fSmrg if (!origkeymap) { 2621a30de1fSmrg fprintf (stderr, "%s: unable to get keyboard mapping table.\n", 2631a30de1fSmrg ProgramName); 2641a30de1fSmrg return; 2651a30de1fSmrg } 2661a30de1fSmrg if (!exprs) { 2671a30de1fSmrg fprintf (fp, 2681a30de1fSmrg "There are %d KeySyms per KeyCode; KeyCodes range from %d to %d.\n\n", 2691a30de1fSmrg keysyms_per_keycode, min_keycode, max_keycode); 2701a30de1fSmrg fprintf (fp, " KeyCode\tKeysym (Keysym)\t...\n"); 2711a30de1fSmrg fprintf (fp, " Value \tValue (Name) \t...\n\n"); 2721a30de1fSmrg } 2731a30de1fSmrg keymap = origkeymap; 2741a30de1fSmrg for (i = min_keycode; i <= max_keycode; i++) { 2751a30de1fSmrg int j, max; 2761a30de1fSmrg 2771a30de1fSmrg if (exprs) 2781a30de1fSmrg fprintf(fp, "keycode %3d =", i); 2791a30de1fSmrg else 2801a30de1fSmrg fprintf(fp, " %3d \t", i); 2811a30de1fSmrg max = keysyms_per_keycode - 1; 2821a30de1fSmrg while ((max >= 0) && (keymap[max] == NoSymbol)) 2831a30de1fSmrg max--; 2841a30de1fSmrg for (j = 0; j <= max; j++) { 2851a30de1fSmrg register KeySym ks = keymap[j]; 2861a30de1fSmrg char *s; 2871a30de1fSmrg if (ks != NoSymbol) 2881a30de1fSmrg s = XKeysymToString (ks); 2891a30de1fSmrg else 2901a30de1fSmrg s = "NoSymbol"; 2911a30de1fSmrg if (!exprs) 2921a30de1fSmrg fprintf (fp, "0x%04x (%s)\t", 2931a30de1fSmrg (unsigned int)ks, s ? s : "no name"); 2941a30de1fSmrg else if (s) 2951a30de1fSmrg fprintf (fp, " %s", s); 2961a30de1fSmrg else 2971a30de1fSmrg fprintf (fp, " 0x%04x", (unsigned int)ks); 2981a30de1fSmrg } 2991a30de1fSmrg keymap += keysyms_per_keycode; 3001a30de1fSmrg fprintf (fp, "\n"); 3011a30de1fSmrg } 3021a30de1fSmrg 3031a30de1fSmrg XFree ((char *) origkeymap); 3041a30de1fSmrg return; 3051a30de1fSmrg} 3061a30de1fSmrg 3071a30de1fSmrgvoid 3081a30de1fSmrgPrintPointerMap(FILE *fp) 3091a30de1fSmrg{ 3101a30de1fSmrg unsigned char pmap[256]; /* there are 8 bits of buttons */ 3111a30de1fSmrg int count, i; 3121a30de1fSmrg 3131a30de1fSmrg count = XGetPointerMapping (dpy, pmap, 256); 3141a30de1fSmrg 3151a30de1fSmrg fprintf (fp, "There are %d pointer buttons defined.\n\n", count); 3161a30de1fSmrg fprintf (fp, " Physical Button\n"); 3171a30de1fSmrg fprintf (fp, " Button Code\n"); 3181a30de1fSmrg/* " ### ###\n" */ 3191a30de1fSmrg for (i = 0; i < count; i++) { 3201a30de1fSmrg fprintf (fp, " %3u %3u\n", 3211a30de1fSmrg i+1, (unsigned int) pmap[i]); 3221a30de1fSmrg } 3231a30de1fSmrg fprintf (fp, "\n"); 3241a30de1fSmrg return; 3251a30de1fSmrg} 3261a30de1fSmrg 3271a30de1fSmrg 3281a30de1fSmrg/* 3291a30de1fSmrg * SetPointerMap - set the pointer map 3301a30de1fSmrg */ 3311a30de1fSmrg 3321a30de1fSmrgint 3331a30de1fSmrgSetPointerMap(unsigned char *map, int n) 3341a30de1fSmrg{ 3351a30de1fSmrg unsigned char defmap[MAXBUTTONCODES]; 3361a30de1fSmrg int j; 3371a30de1fSmrg int retries, timeout; 3381a30de1fSmrg 3391a30de1fSmrg if (n == 0) { /* reset to default */ 3401a30de1fSmrg n = XGetPointerMapping (dpy, defmap, MAXBUTTONCODES); 3411a30de1fSmrg for (j = 0; j < n; j++) defmap[j] = (unsigned char) (j + 1); 3421a30de1fSmrg map = defmap; 3431a30de1fSmrg } 3441a30de1fSmrg 3451a30de1fSmrg for (retries = 5, timeout = 2; retries > 0; retries--, timeout *= 2) { 3461a30de1fSmrg int result; 3471a30de1fSmrg 3481a30de1fSmrg switch (result = XSetPointerMapping (dpy, map, n)) { 3491a30de1fSmrg case MappingSuccess: 3501a30de1fSmrg return 0; 3511a30de1fSmrg case MappingBusy: 3521a30de1fSmrg mapping_busy_pointer (timeout); 3531a30de1fSmrg continue; 3541a30de1fSmrg case MappingFailed: 3551a30de1fSmrg fprintf (stderr, "%s: bad pointer mapping\n", ProgramName); 3561a30de1fSmrg return -1; 3571a30de1fSmrg default: 3581a30de1fSmrg fprintf (stderr, "%s: bad return %d from XSetPointerMapping\n", 3591a30de1fSmrg ProgramName, result); 3601a30de1fSmrg return -1; 3611a30de1fSmrg } 3621a30de1fSmrg } 3631a30de1fSmrg fprintf (stderr, "%s: unable to set pointer mapping\n", ProgramName); 3641a30de1fSmrg return -1; 3651a30de1fSmrg} 366