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