editor: #undef O after use
[0verkill.git] / xkbd.c
blob414b9440d860edbc870ce3190d41df85b9f73190
1 /* portable X keyboard patch by Peter Berg Larsen <pebl@diku.dk> */
3 #include <X11/Xlib.h>
4 #include <X11/X.h>
5 #include <X11/Xutil.h>
6 #include <signal.h>
7 #include <string.h>
9 #include "x.h"
10 #include "kbd.h"
11 #include "console.h"
12 #include "cfg.h"
13 #include "time.h"
15 #ifndef XK_MISCELLANY /* Escape and other Keysymdefinitions */
16 # define XK_MISCELLANY
17 #endif
18 #ifndef XK_LATIN1 /* Space, a, b etc */
19 # define XK_LATIN1
20 #endif
21 #include <X11/keysymdef.h>
24 static unsigned char keyboard[128]; /* 0=not pressed, !0=pressed */
25 static unsigned char old_keyboard[128]; /* 0=not pressed, !0=pressed */
26 extern Atom x_delete_window_atom,x_wm_protocols_atom;
29 void kbd_init(void)
31 /* nothing to initialize */
35 void kbd_close(void)
37 /* nothing to close */
41 /* convert key from scancode to key constant */
42 int remap_out(int k)
44 int remap_table[128]={
45 0,K_ESCAPE,'1','2','3','4','5','6','7','8','9','0','-','=',K_BACKSPACE,K_TAB,
46 'q','w','e','r','t','y','u','i','o','p','[',']',K_ENTER,K_LEFT_CTRL,'a','s',
47 'd','f','g','h','j','k','l',';','\'','`',K_LEFT_SHIFT,'\\','z','x','c','v',
48 'b','n','m',',','.','/',K_RIGHT_SHIFT,K_NUM_ASTERISK,K_LEFT_ALT,' ',K_CAPS_LOCK,K_F1,K_F2,K_F3,K_F4,K_F5,
49 K_F6,K_F7,K_F8,K_F9,K_F10,K_NUM_LOCK,K_SCROLL_LOCK,K_NUM7,K_NUM8,K_NUM9,K_NUM_MINUS,K_NUM4,K_NUM5,K_NUM6,K_NUM_PLUS,K_NUM1,
50 K_NUM2,K_NUM3,K_NUM0,K_NUM_DOT,0,0,0,K_F11,K_F12,K_HOME,K_UP,K_PGUP,K_LEFT,0,K_RIGHT,K_END,
51 K_DOWN,K_PGDOWN,K_INSERT,K_DELETE,K_NUM_ENTER,K_RIGHT_CTRL,K_PAUSE,K_SYSRQ,K_NUM_SLASH,K_RIGHT_ALT,0,0,0,0,0,0,
52 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
55 return remap_table[k&127];
59 /* convert key constant to scancode */
60 int remap_in(int k)
62 switch (k)
64 case K_ESCAPE: return 1;
65 case '1': return 2;
66 case '2': return 3;
67 case '3': return 4;
68 case '4': return 5;
69 case '5': return 6;
70 case '6': return 7;
71 case '7': return 8;
72 case '8': return 9;
73 case '9': return 10;
74 case '0': return 11;
75 case '-': return 12;
76 case '=': return 13;
77 case K_BACKSPACE: return 14;
78 case K_TAB: return 15;
79 case 'q': return 16;
80 case 'w': return 17;
81 case 'e': return 18;
82 case 'r': return 19;
83 case 't': return 20;
84 case 'y': return 21;
85 case 'u': return 22;
86 case 'i': return 23;
87 case 'o': return 24;
88 case 'p': return 25;
89 case '[': return 26;
90 case ']': return 27;
91 case K_ENTER: return 28;
92 case K_LEFT_CTRL: return 29;
93 case 'a': return 30;
94 case 's': return 31;
95 case 'd': return 32;
96 case 'f': return 33;
97 case 'g': return 34;
98 case 'h': return 35;
99 case 'j': return 36;
100 case 'k': return 37;
101 case 'l': return 38;
102 case ';': return 39;
103 case '\'': return 40;
104 case '`': return 41;
105 case K_LEFT_SHIFT: return 42;
106 case '\\': return 43;
107 case 'z': return 44;
108 case 'x': return 45;
109 case 'c': return 46;
110 case 'v': return 47;
111 case 'b': return 48;
112 case 'n': return 49;
113 case 'm': return 50;
114 case ',': return 51;
115 case '.': return 52;
116 case '/': return 53;
117 case K_RIGHT_SHIFT: return 54;
118 case K_NUM_ASTERISK: return 55;
119 case K_LEFT_ALT: return 56;
120 case ' ': return 57;
121 case K_CAPS_LOCK: return 58;
122 case K_F1: return 59;
123 case K_F2: return 60;
124 case K_F3: return 61;
125 case K_F4: return 62;
126 case K_F5: return 63;
127 case K_F6: return 64;
128 case K_F7: return 65;
129 case K_F8: return 66;
130 case K_F9: return 67;
131 case K_F10: return 68;
132 case K_NUM_LOCK: return 69;
133 case K_SCROLL_LOCK: return 70;
134 case K_NUM7: return 71;
135 case K_NUM8: return 72;
136 case K_NUM9: return 73;
137 case K_NUM_MINUS: return 74;
138 case K_NUM4: return 75;
139 case K_NUM5: return 76;
140 case K_NUM6: return 77;
141 case K_NUM_PLUS: return 78;
142 case K_NUM1: return 79;
143 case K_NUM2: return 80;
144 case K_NUM3: return 81;
145 case K_NUM0: return 82;
146 case K_NUM_DOT: return 83;
147 case K_F11: return 87;
148 case K_F12: return 88;
149 case K_NUM_ENTER: return 100;
150 case K_RIGHT_CTRL: return 101;
151 case K_NUM_SLASH: return 104;
152 case K_SYSRQ: return 103;
153 case K_RIGHT_ALT: return 105;
154 case K_HOME: return 89;
155 case K_UP: return 90;
156 case K_PGUP: return 91;
157 case K_LEFT: return 92;
158 case K_RIGHT: return 94;
159 case K_END: return 95;
160 case K_DOWN: return 96;
161 case K_PGDOWN: return 97;
162 case K_INSERT: return 98;
163 case K_DELETE: return 99;
164 case K_PAUSE: return 102;
165 default: return 0;
170 void sigwinch_handler(int);
171 void signal_handler(int);
174 /* 31/10/2000 22:31. pebl*/
175 int keycode2keysym (XKeyEvent* e)
177 KeySym ks;
178 int nbytes;
179 static char str[256+1];
181 nbytes = XLookupString (e, str, 256, &ks, NULL);
182 if (ks == NoSymbol)
183 return 0;
185 switch (ks)
187 case XK_Escape: return 1;
188 case XK_1: return 2;
189 case XK_exclam: return 2;
190 case XK_2: return 3;
191 case XK_at: return 3;
192 case XK_3: return 4;
193 case XK_numbersign: return 4;
194 case XK_4: return 5;
195 case XK_dollar: return 5;
196 case XK_5: return 6;
197 case XK_percent: return 6;
198 case XK_6: return 7;
199 case XK_asciicircum: return 7;
200 case XK_7: return 8;
201 case XK_ampersand: return 8;
202 case XK_8: return 9;
203 case XK_asterisk: return 9;
204 case XK_9: return 10;
205 case XK_parenleft: return 10;
206 case XK_0: return 11;
207 case XK_parenright: return 11;
208 case XK_minus: return 12;
209 case XK_underscore: return 12;
210 case XK_equal: return 13;
211 case XK_plus: return 13;
212 case XK_BackSpace: return 14;
213 case XK_Tab: return 15;
214 case XK_q: return 16;
215 case XK_Q: return 16;
216 case XK_w: return 17;
217 case XK_W: return 17;
218 case XK_e: return 18;
219 case XK_E: return 18;
220 case XK_r: return 19;
221 case XK_R: return 19;
222 case XK_t: return 20;
223 case XK_T: return 20;
224 case XK_y: return 21;
225 case XK_Y: return 21;
226 case XK_u: return 22;
227 case XK_U: return 22;
228 case XK_i: return 23;
229 case XK_I: return 23;
230 case XK_o: return 24;
231 case XK_O: return 24;
232 case XK_p: return 25;
233 case XK_P: return 25;
234 case XK_bracketleft: return 26;
235 case XK_braceleft: return 26;
236 case XK_bracketright: return 27;
237 case XK_braceright: return 27;
238 case XK_Return: return 28;
239 case XK_Control_L: return 29;
240 case XK_a: return 30;
241 case XK_A: return 30;
242 case XK_s: return 31;
243 case XK_S: return 31;
244 case XK_D: return 32;
245 case XK_d: return 32;
246 case XK_f: return 33;
247 case XK_F: return 33;
248 case XK_g: return 34;
249 case XK_G: return 34;
250 case XK_h: return 35;
251 case XK_H: return 35;
252 case XK_j: return 36;
253 case XK_J: return 36;
254 case XK_k: return 37;
255 case XK_K: return 37;
256 case XK_l: return 38;
257 case XK_L: return 38;
258 case XK_semicolon: return 39;
259 case XK_colon: return 39;
260 case XK_apostrophe: return 40;
261 case XK_quotedbl: return 40;
262 case XK_grave: return 41;
263 case XK_asciitilde: return 41;
264 case XK_Shift_L: return 42;
265 case XK_backslash: return 43;
266 case XK_bar: return 43;
267 case XK_z: return 44;
268 case XK_Z: return 44;
269 case XK_x: return 45;
270 case XK_X: return 45;
271 case XK_c: return 46;
272 case XK_C: return 46;
273 case XK_v: return 47;
274 case XK_V: return 47;
275 case XK_b: return 48;
276 case XK_B: return 48;
277 case XK_n: return 49;
278 case XK_N: return 49;
279 case XK_m: return 50;
280 case XK_M: return 50;
281 case XK_comma: return 51;
282 case XK_less: return 51;
283 case XK_period: return 52;
284 case XK_greater: return 52;
285 case XK_slash: return 53;
286 case XK_question: return 53;
287 case XK_Shift_R: return 54;
288 case XK_KP_Multiply: return 55;
289 case XK_Alt_L: return 56;
290 case XK_space: return 57;
291 case XK_Caps_Lock: return 58;
292 case XK_F1: return 59;
293 case XK_F2: return 60;
294 case XK_F3: return 61;
295 case XK_F4: return 62;
296 case XK_F5: return 63;
297 case XK_F6: return 64;
298 case XK_F7: return 65;
299 case XK_F8: return 66;
300 case XK_F9: return 67;
301 case XK_F10: return 68;
302 case XK_Num_Lock: return 69;
303 case XK_Scroll_Lock: return 70;
304 case XK_KP_7: return 71;
305 case XK_KP_8: return 72;
306 case XK_KP_9: return 73;
307 case XK_KP_Subtract: return 74;
308 case XK_KP_4: return 75;
309 case XK_KP_5: return 76;
310 case XK_KP_6: return 77;
311 case XK_KP_Add: return 78;
312 case XK_KP_1: return 79;
313 case XK_KP_2: return 80;
314 case XK_KP_3: return 81;
315 case XK_KP_0: return 82;
316 case XK_KP_Separator: return 83;
317 case XK_F11: return 87;
318 case XK_F12: return 88;
319 case XK_Home: return 89;
320 case XK_Up: return 90;
321 case XK_Page_Up: return 91;
322 case XK_Left: return 92;
323 case XK_Right: return 94;
324 case XK_End: return 95;
325 case XK_Down: return 96;
326 case XK_Page_Down: return 97;
327 case XK_Insert: return 98;
328 case XK_Delete: return 99;
329 case XK_KP_Enter: return 100;
330 case XK_Control_R: return 101;
331 case XK_Pause: return 102;
332 case XK_Sys_Req: return 103;
333 case XK_KP_Divide: return 104;
334 case XK_Alt_R: return 105;
335 default: return 0;
339 /* returns zero if nothing was read, non-zero otherwise */
340 /* maintains also all window events */
341 int kbd_update(void)
343 int retval=0,keysym=0;
344 int n,a;
345 XEvent event;
346 memcpy(old_keyboard,keyboard,128);
348 while((n=XPending(display)))
350 for (a=0;a<n;a++)
352 XNextEvent(display,&event);
353 switch (event.type)
355 case KeyPress:
356 retval=1;
357 keysym = keycode2keysym((XKeyEvent*)&event); /* 31/10/2000 22:31. pebl */
358 if (keysym > 127)break;
359 keyboard[keysym]=1;
360 break;
362 case KeyRelease:
363 retval=1;
364 keysym = keycode2keysym((XKeyEvent*)&event); /* 31/10/2000 22:31. pebl */
365 if (keysym>127)break;
366 keyboard[keysym]=0;
367 break;
369 case ClientMessage:
370 if (
371 event.xclient.format!=32||
372 event.xclient.message_type!=x_wm_protocols_atom||
373 event.xclient.data.l[0]!=(signed)x_delete_window_atom
375 break;
377 /* This event is destroy window event from window manager */
379 case DestroyNotify:
380 #ifdef SIGQUIT
381 raise(SIGQUIT);
382 #else
383 signal_handler(3);
384 #endif
385 break;
388 case ConfigureNotify: /* window was resized */
389 x_width=event.xconfigure.width/FONT_X_SIZE;
390 x_height=event.xconfigure.height/FONT_Y_SIZE;
392 case Expose: /* window was exposed - redraw it */
393 #ifdef SIGWINCH
394 raise(SIGWINCH);
395 #else
396 sigwinch_handler(-1);
397 #endif
398 break;
403 /* CTRL-C */
404 if ((keyboard[29]||keyboard[97])&&keyboard[46])
405 raise(SIGINT);
407 return retval;
411 /* returns 1 if given key is pressed, 0 otherwise */
412 int kbd_is_pressed(int key)
414 int a=remap_in(key);
415 return a?keyboard[a]:0;
419 /* same as kbd_is_pressed but tests rising edge of the key */
420 int kbd_was_pressed(int key)
422 int a=remap_in(key);
423 if (!a)return 0;
424 return !old_keyboard[remap_in(key)]&&keyboard[remap_in(key)];
428 void kbd_wait_for_key(void)
430 XEvent e;
431 #ifdef TRI_D
432 if (TRI_D_ON)
433 while (
434 XCheckWindowEvent(display,window2,KeyPressMask|KeyReleaseMask,&e)==False&&
435 XCheckWindowEvent(display,window,KeyPressMask|KeyReleaseMask,&e)==False
436 )my_sleep(50000);
437 else
438 XWindowEvent(display,window,KeyPressMask|KeyReleaseMask,&e);
439 #else
440 XWindowEvent(display,window,KeyPressMask|KeyReleaseMask,&e);
441 #endif
442 XPutBackEvent(display,&e);