|
|
1.1 root 1: #include "copyright.h"
2:
3: /* $Header: XKeyBind.c,v 11.35 87/09/08 20:17:55 toddb Exp $ */
4: /* Copyright 1985, 1987, Massachusetts Institute of Technology */
5:
6: /* Beware, here be monsters (still under construction... - JG */
7:
8: #define NEED_EVENTS
9: #include "Xlib.h"
10: #include "Xlibint.h"
11: #include "Xutil.h"
12: #include "keysym.h"
13: #include <stdio.h>
14:
15: #define HAS_CTRL(c) ((c) >= '@' && (c) <= '\177')
16:
17: struct XKeytrans {
18: struct XKeytrans *next;/* next on list */
19: char *string; /* string to return when the time comes */
20: int len; /* length of string (since NULL is legit)*/
21: KeySym key; /* keysym rebound */
22: unsigned int state; /* modifier state */
23: KeySym *modifiers; /* modifier keysyms you want */
24: int mlen; /* length of modifier list */
25: };
26:
27: static struct XKeytrans *trans = NULL;
28:
29: static KeySym KeyCodetoKeySym(dpy, keycode, col)
30: register Display *dpy;
31: int keycode;
32: int col;
33: {
34: int ind;
35: /*
36: * if keycode not defined in set, this should really be impossible.
37: * in any case, if sanity check fails, return NoSymbol.
38: */
39: if (col < 0 || col > dpy->keysyms_per_keycode) return (NoSymbol);
40: if (keycode < dpy->min_keycode || keycode > dpy->max_keycode)
41: return(NoSymbol);
42:
43: ind = (keycode - dpy->min_keycode) * dpy->keysyms_per_keycode + col;
44: return (dpy->keysyms[ind]);
45: }
46:
47: KeySym XKeycodeToKeysym(dpy, kc, col)
48: Display *dpy;
49: KeyCode kc;
50: int col;
51: {
52: if (dpy->keysyms == NULL)
53: Initialize(dpy);
54: return (KeyCodetoKeySym(dpy, kc, col));
55: }
56:
57: KeyCode XKeysymToKeycode(dpy, ks)
58: Display *dpy;
59: KeySym ks;
60: {
61: int i;
62:
63: if (dpy->keysyms == NULL)
64: Initialize(dpy);
65: for (i = dpy->min_keycode; i <= dpy->max_keycode; i++) {
66: int j;
67:
68: for (j = 0; j < dpy->keysyms_per_keycode; j++) {
69: int ind = (i - dpy->min_keycode) * dpy->keysyms_per_keycode + j;
70:
71: if (ks == dpy->keysyms[ind])
72: return (i);
73: }
74: }
75: return (0);
76: }
77:
78: KeySym XLookupKeysym(event, col)
79: register XKeyEvent *event;
80: int col;
81: {
82: if (event->display->keysyms == NULL)
83: Initialize(event->display);
84: return (XKeycodeToKeysym(event->display, event->keycode, col));
85: }
86:
87: XRefreshKeyboardMapping(event)
88: register XMappingEvent *event;
89: {
90: LockDisplay(event->display);
91: /* XXX should really only refresh what is necessary, for now, make
92: initialize test fail */
93: if(event->request == MappingKeyboard)
94: if (event->display->keysyms != NULL) {
95: Xfree ((char *)event->display->keysyms);
96: event->display->keysyms = NULL;
97: }
98: if(event->request == MappingModifier) {
99: XFreeModifiermap(event->display->modifiermap);
100: event->display->keysyms = NULL;/* XXX - looks like astorage leak */
101: }
102: UnlockDisplay(event->display);
103: }
104: static InitTranslationList()
105: {
106: /* not yet implemented */
107: /* should read keymap file and initialize list */
108: }
109:
110: /*ARGSUSED*/
111: int XUseKeymap(filename)
112: char *filename;
113: {
114: /* not yet implemented */
115: }
116:
117: /* XXX not sure locking is race free here */
118: static Initialize(dpy)
119: Display *dpy;
120: {
121: register KeySym *bd;
122: int nbd;
123:
124: if (trans == NULL) InitTranslationList();
125: /*
126: * lets go get the keysyms from the server.
127: */
128: if (dpy->keysyms == NULL) {
129: dpy->keysyms = XGetKeyboardMapping (dpy, dpy->min_keycode,
130: dpy->max_keycode - dpy->min_keycode + 1, &dpy->keysyms_per_keycode);
131: LockDisplay(dpy);
132: nbd = (dpy->max_keycode - dpy->min_keycode + 1) * dpy->keysyms_per_keycode;
133: for (bd = dpy->keysyms; bd < (dpy->keysyms + nbd); bd += 2) {
134: if ((*(bd + 1) == NoSymbol) && (*bd >= XK_A) && (*bd <= XK_Z)) {
135: *(bd + 1) = *bd;
136: *bd += 0x20;
137: }
138: }
139: UnlockDisplay(dpy);
140: }
141: if (dpy->modifiermap == NULL) {
142: dpy->modifiermap = XGetModifierMapping(dpy);
143: }
144: }
145:
146: static int KeySymRebound(event, buf, symbol)
147: XKeyEvent *event;
148: char *buf;
149: KeySym symbol;
150: {
151: register struct XKeytrans *p;
152:
153: p = trans;
154: while (p != NULL) {
155: if (MatchEvent(event, symbol, p)) {
156: bcopy (p->string, buf, p->len);
157: return p->len;
158: }
159: p = p->next;
160: }
161: return -1;
162: }
163:
164: Bool MatchEvent(event, symbol, p)
165: XKeyEvent *event;
166: KeySym symbol;
167: register struct XKeytrans *p;
168: {
169: if ((event->state == p->state) && (symbol == p->key)) return True;
170: return False;
171: }
172:
173: int XLookupString (event, buffer, nbytes, keysym, status)
174: XKeyEvent *event;
175: char *buffer; /* buffer */
176: int nbytes; /* space in buffer for characters */
177: KeySym *keysym;
178: XComposeStatus *status;
179: {
180: register KeySym symbol, lsymbol, usymbol;
181: int length = 0;
182: char buf[BUFSIZ];
183: unsigned char byte3, byte4;
184:
185: if (event->display->keysyms == NULL)
186: Initialize(event->display);
187:
188: lsymbol = XKeycodeToKeysym(event->display, event->keycode, 0);
189: usymbol = XKeycodeToKeysym(event->display, event->keycode, 1);
190: /*
191: * we have to find out what kind of lock we are dealing with, if any.
192: * if caps lock, only shift caps.
193: */
194: symbol = lsymbol;
195: if (event->state & LockMask) {
196: XModifierKeymap *m = event->display->modifiermap;
197: int i;
198:
199: if (usymbol != NoSymbol)
200: symbol = usymbol;
201: for (i = m->max_keypermod; i < 2*m->max_keypermod; i++) {
202: /*
203: * Run through all the keys setting LOCK and, if
204: * ANY of them are CAPS_LOCK, do Caps Lock.
205: * This is kind of bogus, but what else to do?
206: * Supposing we have CAPS_LOCK, but on the shifted
207: * part of the key?
208: */
209: if (XKeycodeToKeysym(event->display, m->modifiermap[i], 0)
210: == XK_Caps_Lock) {
211: if (usymbol >= XK_A && usymbol <= XK_Z)
212: symbol = usymbol;
213: else
214: symbol = lsymbol;
215: break;
216: }
217: }
218: }
219: if ((event->state & ShiftMask) && usymbol != NoSymbol)
220: symbol = usymbol;
221:
222: if (keysym != NULL) *keysym = symbol;
223:
224: byte4 = symbol & 0xFF;
225: byte3 = (symbol >> 8 ) & 0xFF;
226:
227: /*
228: * see if symbol rebound, if so, return that string.
229: * if any of high order 16 bits set, can only do ascii.
230: * (reserved for future use, and for vendors).
231: */
232: if ((length = KeySymRebound(event, buf, symbol)) == -1) {
233: if ( IsModifierKey(symbol) || IsCursorKey(symbol)
234: || IsPFKey (symbol) || IsFunctionKey(symbol)
235: || IsMiscFunctionKey(symbol)
236: || (symbol == XK_Multi_key) || (symbol == XK_Kanji)) return 0;
237: buf[0] = byte4;
238: /* if X keysym, convert to ascii by grabbing low 7 bits */
239: if (byte3 == 0xFF) buf[0] &= 0x7F;
240: /* only apply Control key if it makes sense, else ignore it */
241: if ((event->state & ControlMask) && HAS_CTRL(buf[0]))
242: buf[0] = buf[0] & 0x1F;
243: length = 1;
244: }
245: if (length > nbytes) length = nbytes;
246: bcopy (buf, buffer, length);
247: return (length);
248: }
249:
250: XRebindKeysym (dpy, keysym, mlist, nm, str, nbytes)
251: Display *dpy;
252: KeySym keysym;
253: KeySym *mlist;
254: int nm; /* number of modifiers in mlist */
255: unsigned char *str;
256: int nbytes;
257: {
258: register struct XKeytrans *tmp, *p;
259: int nb;
260:
261: if (dpy->keysyms == NULL)
262: Initialize(dpy);
263: LockDisplay(dpy);
264: tmp = trans;
265: trans = p = (struct XKeytrans *)Xmalloc(sizeof(struct XKeytrans));
266: p->next = tmp; /* chain onto list */
267: p->string = (char *) Xmalloc(nbytes);
268: bcopy (str, p->string, nbytes);
269: p->len = nbytes;
270: nb = sizeof (KeySym) * nm;
271: p->modifiers = (KeySym *) Xmalloc(nb);
272: bcopy (mlist, p->modifiers, nb);
273: p->key = keysym;
274: p->mlen = nm;
275: ComputeMaskFromKeytrans(dpy, p);
276: UnlockDisplay(dpy);
277: return;
278: }
279:
280: /*
281: * given a KeySym, returns the first keycode found after the index value
282: * in the table. (Hopefully, can be found quickly).
283: */
284: static CARD8 FindKeyCode(dpy, ind, code)
285: register Display *dpy;
286: int ind;
287: register int code;
288: {
289:
290: register KeySym *kmax = dpy->keysyms +
291: (dpy->max_keycode - dpy->min_keycode + 1) * dpy->keysyms_per_keycode;
292: register KeySym *k = dpy->keysyms; /* XXX not yet dealing with ind */
293: if ((ind < dpy->min_keycode) || (ind > dpy->max_keycode)) return 0;
294: while (k < kmax) {
295: if (*k == code)
296: return(((k - dpy->keysyms)
297: / dpy->keysyms_per_keycode) + dpy->min_keycode);
298: k += 1;
299: }
300: return 0;
301: }
302:
303:
304: /*
305: * given a list of modifiers, computes the mask necessary for later matching.
306: * This routine must lookup the key in the Keymap and then search to see
307: * what modifier it is bound to, if any.
308: */
309: static ComputeMaskFromKeytrans(dpy, p)
310: Display *dpy;
311: register struct XKeytrans *p;
312: {
313: register int i;
314: register CARD8 code;
315: register XModifierKeymap *m = dpy->modifiermap;
316:
317: p->state = 0;
318: for (i = 0; i < p->mlen; i++) {
319: /* if not found, then not on current keyboard */
320: if ((code = FindKeyCode(dpy, dpy->min_keycode, p->modifiers[i])) == 0)
321: continue;
322: /* code is now the keycode for the modifier you want */
323: {
324: register int j;
325:
326: for (j = 0; j < (m->max_keypermod<<3); j++) {
327: if (m->modifiermap[j] && code == m->modifiermap[j])
328: p->state |= (1<<(j/m->max_keypermod));
329: }
330: }
331: }
332: return;
333: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.