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