1 /* key.c
2 *
3 * $Id$
4 *
5 * Copyright 1990, 1991, 1992, 1993, 1994, 1995, Oliver Laumann, Berlin
6 * Copyright 2002, 2003 Sam Hocevar <sam@hocevar.net>, Paris
7 *
8 * This software was derived from Elk 1.2, which was Copyright 1987, 1988,
9 * 1989, Nixdorf Computer AG and TELES GmbH, Berlin (Elk 1.2 has been written
10 * by Oliver Laumann for TELES Telematic Services, Berlin, in a joint project
11 * between TELES and Nixdorf Microprocessor Engineering, Berlin).
12 *
13 * Oliver Laumann, TELES GmbH, Nixdorf Computer AG and Sam Hocevar, as co-
14 * owners or individual owners of copyright in this software, grant to any
15 * person or company a worldwide, royalty free, license to
16 *
17 * i) copy this software,
18 * ii) prepare derivative works based on this software,
19 * iii) distribute copies of this software or derivative works,
20 * iv) perform this software, or
21 * v) display this software,
22 *
23 * provided that this notice is not removed and that neither Oliver Laumann
24 * nor Teles nor Nixdorf are deemed to have made any representations as to
25 * the suitability of this software for any purpose nor are held responsible
26 * for any defects of this software.
27 *
28 * THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
29 */
30
31 #include "xlib.h"
32
33 #include <string.h>
34
35 #ifdef XLIB_RELEASE_5_OR_LATER
36
37 /* I don't know if XDisplayKeycodes() was already there in X11R4.
38 */
P_Display_Min_Keycode(Object d)39 static Object P_Display_Min_Keycode (Object d) {
40 int mink, maxk;
41
42 Check_Type (d, T_Display);
43 XDisplayKeycodes(DISPLAY(d)->dpy, &mink, &maxk);
44 return Make_Integer (mink);
45 }
46
P_Display_Max_Keycode(Object d)47 static Object P_Display_Max_Keycode (Object d) {
48 int mink, maxk;
49
50 Check_Type (d, T_Display);
51 XDisplayKeycodes(DISPLAY(d)->dpy, &mink, &maxk);
52 return Make_Integer (maxk);
53 }
54
55 #else
P_Display_Min_Keycode(Object d)56 static Object P_Display_Min_Keycode (Object d) {
57 Check_Type (d, T_Display);
58 return Make_Integer (DISPLAY(d)->dpy->min_keycode);
59 }
60
P_Display_Max_Keycode(Object d)61 static Object P_Display_Max_Keycode (Object d) {
62 Check_Type (d, T_Display);
63 return Make_Integer (DISPLAY(d)->dpy->max_keycode);
64 }
65 #endif
66
67 #ifdef XLIB_RELEASE_5_OR_LATER
68
69 /* I'm not sure if this works correctly in X11R4:
70 */
P_Display_Keysyms_Per_Keycode(Object d)71 static Object P_Display_Keysyms_Per_Keycode (Object d) {
72 KeySym *ksyms;
73 int mink, maxk, ksyms_per_kode;
74
75 Check_Type (d, T_Display);
76 XDisplayKeycodes(DISPLAY(d)->dpy, &mink, &maxk);
77 ksyms = XGetKeyboardMapping(DISPLAY(d)->dpy, (KeyCode)mink,
78 maxk - mink + 1, &ksyms_per_kode);
79 return Make_Integer (ksyms_per_kode);
80 }
81
82 #else
P_Display_Keysyms_Per_Keycode(Object d)83 static Object P_Display_Keysyms_Per_Keycode (Object d) {
84 Check_Type (d, T_Display);
85 /* Force initialization: */
86 Disable_Interrupts;
87 (void)XKeycodeToKeysym (DISPLAY(d)->dpy, DISPLAY(d)->dpy->min_keycode, 0);
88 Enable_Interrupts;
89 return Make_Integer (DISPLAY(d)->dpy->keysyms_per_keycode);
90 }
91 #endif
92
P_String_To_Keysym(Object s)93 static Object P_String_To_Keysym (Object s) {
94 KeySym k;
95
96 k = XStringToKeysym (Get_Strsym (s));
97 return k == NoSymbol ? False : Make_Unsigned_Long ((unsigned long)k);
98 }
99
P_Keysym_To_String(Object k)100 static Object P_Keysym_To_String (Object k) {
101 register char *s;
102
103 s = XKeysymToString ((KeySym)Get_Long (k));
104 return s ? Make_String (s, strlen (s)) : False;
105 }
106
P_Keycode_To_Keysym(Object d,Object k,Object index)107 static Object P_Keycode_To_Keysym (Object d, Object k, Object index) {
108 Object ret;
109
110 Check_Type (d, T_Display);
111 Disable_Interrupts;
112 ret = Make_Unsigned_Long ((unsigned long)XKeycodeToKeysym (DISPLAY(d)->dpy,
113 Get_Integer (k), Get_Integer (index)));
114 Enable_Interrupts;
115 return ret;
116 }
117
P_Keysym_To_Keycode(Object d,Object k)118 static Object P_Keysym_To_Keycode (Object d, Object k) {
119 Object ret;
120
121 Check_Type (d, T_Display);
122 Disable_Interrupts;
123 ret = Make_Unsigned (XKeysymToKeycode (DISPLAY(d)->dpy,
124 (KeySym)Get_Long (k)));
125 Enable_Interrupts;
126 return ret;
127 }
128
P_Lookup_String(Object d,Object k,Object mask)129 static Object P_Lookup_String (Object d, Object k, Object mask) {
130 XKeyEvent e;
131 char buf[1024];
132 register int len;
133 KeySym keysym_return;
134 XComposeStatus status_return;
135
136 Check_Type (d, T_Display);
137 e.display = DISPLAY(d)->dpy;
138 e.keycode = Get_Integer (k);
139 e.state = Symbols_To_Bits (mask, 1, State_Syms);
140 Disable_Interrupts;
141 len = XLookupString (&e, buf, 1024, &keysym_return, &status_return);
142 Enable_Interrupts;
143 return Make_String (buf, len);
144 }
145
P_Rebind_Keysym(Object d,Object k,Object mods,Object str)146 static Object P_Rebind_Keysym (Object d, Object k, Object mods, Object str) {
147 KeySym *p;
148 register int i, n;
149 Alloca_Begin;
150
151 Check_Type (d, T_Display);
152 Check_Type (str, T_String);
153 Check_Type (mods, T_Vector);
154 n = VECTOR(mods)->size;
155 Alloca (p, KeySym*, n * sizeof (KeySym));
156 for (i = 0; i < n; i++)
157 p[i] = (KeySym)Get_Long (VECTOR(mods)->data[i]);
158 XRebindKeysym (DISPLAY(d)->dpy, (KeySym)Get_Long (k), p, n,
159 (unsigned char *)STRING(str)->data, STRING(str)->size);
160 Alloca_End;
161 return Void;
162 }
163
P_Refresh_Keyboard_Mapping(Object w,Object event)164 static Object P_Refresh_Keyboard_Mapping (Object w, Object event) {
165 static XMappingEvent fake;
166
167 Check_Type (w, T_Window);
168 fake.type = MappingNotify;
169 fake.display = WINDOW(w)->dpy;
170 fake.window = WINDOW(w)->win;
171 fake.request = Symbols_To_Bits (event, 0, Mapping_Syms);
172 XRefreshKeyboardMapping (&fake);
173 return Void;
174 }
175
elk_init_xlib_key()176 void elk_init_xlib_key () {
177 Define_Primitive (P_Display_Min_Keycode, "display-min-keycode",
178 1, 1, EVAL);
179 Define_Primitive (P_Display_Max_Keycode, "display-max-keycode",
180 1, 1, EVAL);
181 Define_Primitive (P_Display_Keysyms_Per_Keycode,
182 "display-keysyms-per-keycode", 1, 1, EVAL);
183 Define_Primitive (P_String_To_Keysym, "string->keysym", 1, 1, EVAL);
184 Define_Primitive (P_Keysym_To_String, "keysym->string", 1, 1, EVAL);
185 Define_Primitive (P_Keycode_To_Keysym, "keycode->keysym", 3, 3, EVAL);
186 Define_Primitive (P_Keysym_To_Keycode, "keysym->keycode", 2, 2, EVAL);
187 Define_Primitive (P_Lookup_String, "lookup-string", 3, 3, EVAL);
188 Define_Primitive (P_Rebind_Keysym, "rebind-keysym", 4, 4, EVAL);
189 Define_Primitive (P_Refresh_Keyboard_Mapping,
190 "refresh-keyboard-mapping", 2, 2, EVAL);
191 }
192