ModMap.c revision b4ee4795
1/* 2 3Copyright 1986, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of The Open Group shall not be 22used in advertising or otherwise to promote the sale, use or other dealings 23in this Software without prior written authorization from The Open Group. 24 25*/ 26 27#define NEED_REPLIES 28#ifdef HAVE_CONFIG_H 29#include <config.h> 30#endif 31#include "Xlibint.h" 32 33XModifierKeymap * 34XGetModifierMapping(register Display *dpy) 35{ 36 xGetModifierMappingReply rep; 37 register xReq *req; 38 unsigned long nbytes; 39 XModifierKeymap *res; 40 41 LockDisplay(dpy); 42 GetEmptyReq(GetModifierMapping, req); 43 (void) _XReply (dpy, (xReply *)&rep, 0, xFalse); 44 45 nbytes = (unsigned long)rep.length << 2; 46 res = (XModifierKeymap *) Xmalloc(sizeof (XModifierKeymap)); 47 if (res) res->modifiermap = (KeyCode *) Xmalloc ((unsigned) nbytes); 48 if ((! res) || (! res->modifiermap)) { 49 if (res) Xfree((char *) res); 50 res = (XModifierKeymap *) NULL; 51 _XEatData(dpy, nbytes); 52 } else { 53 _XReadPad(dpy, (char *) res->modifiermap, (long) nbytes); 54 res->max_keypermod = rep.numKeyPerModifier; 55 } 56 57 UnlockDisplay(dpy); 58 SyncHandle(); 59 return (res); 60} 61 62/* 63 * Returns: 64 * 0 Success 65 * 1 Busy - one or more old or new modifiers are down 66 * 2 Failed - one or more new modifiers unacceptable 67 */ 68int 69XSetModifierMapping( 70 register Display *dpy, 71 register XModifierKeymap *modifier_map) 72{ 73 register xSetModifierMappingReq *req; 74 xSetModifierMappingReply rep; 75 int mapSize = modifier_map->max_keypermod << 3; /* 8 modifiers */ 76 77 LockDisplay(dpy); 78 GetReqExtra(SetModifierMapping, mapSize, req); 79 80 req->numKeyPerModifier = modifier_map->max_keypermod; 81 82 memcpy((char *) NEXTPTR(req,xSetModifierMappingReq), 83 (char *) modifier_map->modifiermap, 84 mapSize); 85 86 (void) _XReply(dpy, (xReply *) & rep, 87 (SIZEOF(xSetModifierMappingReply) - SIZEOF(xReply)) >> 2, xTrue); 88 UnlockDisplay(dpy); 89 SyncHandle(); 90 return (rep.success); 91} 92 93XModifierKeymap * 94XNewModifiermap(int keyspermodifier) 95{ 96 XModifierKeymap *res = (XModifierKeymap *) Xmalloc((sizeof (XModifierKeymap))); 97 if (res) { 98 res->max_keypermod = keyspermodifier; 99 res->modifiermap = (keyspermodifier > 0 ? 100 (KeyCode *) Xmalloc((unsigned) (8 * keyspermodifier)) 101 : (KeyCode *) NULL); 102 if (keyspermodifier && (res->modifiermap == NULL)) { 103 Xfree((char *) res); 104 return (XModifierKeymap *) NULL; 105 } 106 } 107 return (res); 108} 109 110 111int 112XFreeModifiermap(XModifierKeymap *map) 113{ 114 if (map) { 115 if (map->modifiermap) 116 Xfree((char *) map->modifiermap); 117 Xfree((char *) map); 118 } 119 return 1; 120} 121 122XModifierKeymap * 123XInsertModifiermapEntry(XModifierKeymap *map, 124#if NeedWidePrototypes 125 unsigned int keycode, 126#else 127 KeyCode keycode, 128#endif 129 int modifier) 130{ 131 XModifierKeymap *newmap; 132 int i, 133 row = modifier * map->max_keypermod, 134 newrow, 135 lastrow; 136 137 for (i=0; i<map->max_keypermod; i++) { 138 if (map->modifiermap[ row+i ] == keycode) 139 return(map); /* already in the map */ 140 if (map->modifiermap[ row+i ] == 0) { 141 map->modifiermap[ row+i ] = keycode; 142 return(map); /* we added it without stretching the map */ 143 } 144 } 145 146 /* stretch the map */ 147 if ((newmap = XNewModifiermap(map->max_keypermod+1)) == NULL) 148 return (XModifierKeymap *) NULL; 149 newrow = row = 0; 150 lastrow = newmap->max_keypermod * 8; 151 while (newrow < lastrow) { 152 for (i=0; i<map->max_keypermod; i++) 153 newmap->modifiermap[ newrow+i ] = map->modifiermap[ row+i ]; 154 newmap->modifiermap[ newrow+i ] = 0; 155 row += map->max_keypermod; 156 newrow += newmap->max_keypermod; 157 } 158 (void) XFreeModifiermap(map); 159 newrow = newmap->max_keypermod * modifier + newmap->max_keypermod - 1; 160 newmap->modifiermap[ newrow ] = keycode; 161 return(newmap); 162} 163 164XModifierKeymap * 165XDeleteModifiermapEntry(XModifierKeymap *map, 166#if NeedWidePrototypes 167 unsigned int keycode, 168#else 169 KeyCode keycode, 170#endif 171 int modifier) 172{ 173 int i, 174 row = modifier * map->max_keypermod; 175 176 for (i=0; i<map->max_keypermod; i++) { 177 if (map->modifiermap[ row+i ] == keycode) 178 map->modifiermap[ row+i ] = 0; 179 } 180 /* should we shrink the map?? */ 181 return (map); 182} 183