2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
5 Desc: X11 hidd handling keypresses.
11 #define __OOP_NOATTRBASES__
13 #include <proto/utility.h>
14 #include <hidd/keyboard.h>
15 #include <devices/inputevent.h>
17 #define timeval sys_timeval
18 #include <X11/keysym.h>
21 #include "x11_types.h"
22 #include LC_LIBDEFS_FILE
23 #include "x11_hostlib.h"
25 /****************************************************************************************/
27 long xkey2hidd (XKeyEvent
*xk
, struct x11_staticdata
*xsd
);
29 static OOP_AttrBase HiddKbdAB
;
31 static struct OOP_ABDescr attrbases
[] =
33 { IID_Hidd_Kbd
, &HiddKbdAB
},
37 /****************************************************************************************/
39 static struct _keytable
53 {XK_BackSpace
, 0x41 },
58 {XK_Caps_Lock
, 0x62 },
76 {XK_F12
, 0x5f }, /* HELP, F12 would be 0x6F */
80 {XK_Prior
, 0x48 }, /* PageUP */
81 {XK_Next
, 0x49 }, /* PageDown */
83 {XK_Scroll_Lock
, 0x6b },
87 {XK_KP_Subtract
, 0x4a },
88 {XK_KP_Decimal
, 0x3c },
89 {XK_KP_Separator
, 0x3c },
90 {XK_KP_Delete
, 0x3c },
92 {XK_KP_Subtract
, 0x4a },
93 {XK_KP_Multiply
, 0x5d },
94 {XK_KP_Divide
, 0x5c },
97 {XK_KP_Insert
, 0x0f },
103 {XK_KP_Page_Down
, 0x1f },
107 {XK_KP_Begin
, 0x2e },
109 {XK_KP_Right
, 0x2f },
115 {XK_KP_Page_Up
, 0x3f },
173 /****************************************************************************************/
175 /* English keyboard */
176 static struct _keytable english_keytable
[] =
178 {XK_Control_L
, 0x63 }, /* left control = control */
179 {XK_Multi_key
, 0x63 }, /* right control = control */
180 {XK_Super_L
, 0x66 }, /* left win = LAMIGA */
181 {XK_Super_R
, 0x67 }, /* right win = RAMIGA */
182 {XK_Menu
, 0x67 }, /* menu key = RAMIGA */
183 {XK_Meta_L
, 0x64 }, /* left Alt = LALT */
184 {XK_Mode_switch
, 0x65 }, /* right Alt = RALT */
194 /* Key right of TAB */
198 /* Key between T and U */
214 /* Keys right of 0 */
218 /* Keys right of P */
219 {XK_bracketleft
, 0x1A },
220 {XK_bracketright
, 0x1B },
222 /* Keys right of L */
223 {XK_semicolon
, 0x29 },
224 {XK_apostrophe
, 0x2A },
225 {XK_backslash
, 0x2B }, /* Third key right of L might not be present */
227 /* Key right of shift and 2nd left of X (might not be present) */
230 /* Keys 2nd right of N (= usually right of M) */
238 /****************************************************************************************/
241 /* German keyboard */
242 static struct _keytable german_keytable
[] =
244 {XK_Control_L
, 0x63 }, /* linke STRG = control */
245 {XK_Multi_key
, 0x63 }, /* rechte STRG = control */
246 {XK_Super_L
, 0x66 }, /* Linke Win = LAMIGA */
247 {XK_Super_R
, 0x67 }, /* Rechte Win = RAMIGA */
248 {XK_Meta_L
, 0x64 }, /* Linke Alt = LALT */
249 {XK_Mode_switch
, 0x65 }, /* Alt Gr = RALT */
259 /* Key right of TAB */
263 /* Key between T and U */
276 {XK_asciicircum
, 0x00 }, /* Akzent links neben 1 Taste */
278 /* Keys right of 0 */
279 {XK_equal
, 0x0A }, /* = */
280 {XK_ssharp
, 0x0B }, /* scharfes s */
281 {XK_acute
, 0x0C }, /* Akzent rechts von scharfem s */
283 /* Keys right of P */
284 {XK_udiaeresis
, 0x1A }, /* Umlaut u */
285 {XK_Udiaeresis
, 0x1A },
286 {XK_plus
, 0x1B }, /* + */
288 /* Keys right of L */
289 {XK_odiaeresis
, 0x29 }, /* Umlaut o */
290 {XK_Odiaeresis
, 0x29 },
291 {XK_adiaeresis
, 0x2A }, /* Umlaut a */
292 {XK_Adiaeresis
, 0x2A },
293 {XK_numbersign
, 0x2B }, /* # */
295 /* Key right of shift and 2nd left of X (might not be present) */
296 {XK_less
, 0x30 }, /* < */
298 /* Keys 2nd right of N (= usually right of M) */
299 {XK_comma
, 0x38 }, /* Komma */
300 {XK_period
, 0x39 }, /* Punkt */
301 {XK_minus
, 0x3A }, /* Minus */
308 /* Italian keyboard */
309 static struct _keytable italian_keytable
[] =
311 {XK_Control_L
, 0x63 }, /* left CTRL = control */
312 {XK_Multi_key
, 0x63 }, /* right CTRL = control */
313 {XK_Super_L
, 0x66 }, /* left win = LAMIGA */
314 {XK_Super_R
, 0x67 }, /* right win = RAMIGA */
315 {XK_Meta_L
, 0x64 }, /* left alt = LALT */
316 {XK_Mode_switch
, 0x65 }, /* right alt = RALT */
327 /* Key right of TAB */
331 /* Key between T and U */
345 {XK_backslash
, 0x00 },
347 /* Keys right of 0 */
348 {XK_apostrophe
, 0x0B },
352 /* Keys right of P */
355 {XK_plus
, 0x1B }, /* + */
357 /* Keys right of L */
362 {XK_Ugrave
, 0x2B }, /* Third key right of L might not be present */
365 /* Key right of shift and 2nd left of X (might not be present) */
366 {XK_less
, 0x30 }, /* < */
368 /* Keys 2nd right of N (= usually right of M) */
377 /****************************************************************************************/
381 /* Use this template to create a keytable for your language:
383 Do not touch the right values (rawkey numbers). Only change
384 the XK's at the left side. To find out the XK_ names (keysym)
385 start "xev" and press the key the comment describes (for
386 example "Key left of S" in the xev window. In the Shell
387 window you will see output like this:
389 KeyPress event, serial 30, synthetic NO, window 0x5000001,
390 root 0x47, subw 0x5000002, time 3410089115, (24,45), root:(28,69),
391 state 0x0, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
392 XLookupString gives 0 characters: "" |
394 This is the keysym name _______________/
396 So in this case you would have to write "XK_Shift_L"
398 Check all keys, not just the ones with "XK_????"!!!
401 static struct _keytable template_keytable
[] =
403 {XK_Control_L
, 0x63 }, /* left control = control */
404 {XK_Multi_key
, 0x63 }, /* right control = control */
405 {XK_Super_L
, 0x66 }, /* left win = LAMIGA */
406 {XK_Super_R
, 0x67 }, /* right win = RAMIGA */
407 {XK_Meta_L
, 0x64 }, /* left Alt = LALT */
408 {XK_Mode_switch
, 0x65 }, /* right Alt = RALT */
418 /* Key right of TAB */
422 /* Key between T and U */
438 /* Keys right of 0 */
442 /* Keys right of P */
446 /* Keys right of L */
449 {XK_
????, 0x2B }, /* Third key right of L might not be present */
451 /* Key right of shift and 2nd left of X (might not be present) */
454 /* Keys 2nd right of N (= usually right of M) */
464 /****************************************************************************************/
466 OOP_Object
* X11Kbd__Root__New(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
468 BOOL has_kbd_hidd
= FALSE
;
469 struct TagItem
*tag
, *tstate
;
470 APTR callback
= NULL
;
471 APTR callbackdata
= NULL
;
473 EnterFunc(bug("X11Kbd::New()\n"));
475 ObtainSemaphoreShared( &XSD(cl
)->sema
);
477 if (XSD(cl
)->kbdhidd
)
480 ReleaseSemaphore( &XSD(cl
)->sema
);
482 if (has_kbd_hidd
) { /* Cannot open twice */
483 D(bug("[X11Kbd] Attempt to create second instance\n"));
484 ReturnPtr("X11Kbd::New", OOP_Object
*, NULL
); /* Should have some error code here */
487 tstate
= msg
->attrList
;
488 D(bug("tstate: %p, tag=%x\n", tstate
, tstate
->ti_Tag
));
490 while ((tag
= NextTagItem(&tstate
)))
494 D(bug("Got tag %d, data %x\n", tag
->ti_Tag
, tag
->ti_Data
));
496 if (IS_HIDDKBD_ATTR(tag
->ti_Tag
, idx
))
498 D(bug("Kbd hidd tag\n"));
501 case aoHidd_Kbd_IrqHandler
:
502 callback
= (APTR
)tag
->ti_Data
;
503 D(bug("Got callback %p\n", (APTR
)tag
->ti_Data
));
506 case aoHidd_Kbd_IrqHandlerData
:
507 callbackdata
= (APTR
)tag
->ti_Data
;
508 D(bug("Got data %p\n", (APTR
)tag
->ti_Data
));
513 } /* while (tags to process) */
515 if (NULL
== callback
)
516 ReturnPtr("X11Kbd::New", OOP_Object
*, NULL
); /* Should have some error code here */
518 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
521 struct x11kbd_data
*data
= OOP_INST_DATA(cl
, o
);
523 data
->kbd_callback
= (VOID (*)(APTR
, UWORD
))callback
;
524 data
->callbackdata
= callbackdata
;
525 data
->prev_keycode
= 0xFFFF;
527 ObtainSemaphore( &XSD(cl
)->sema
);
528 XSD(cl
)->kbdhidd
= o
;
529 ReleaseSemaphore( &XSD(cl
)->sema
);
532 ReturnPtr("X11Kbd::New", OOP_Object
*, o
);
535 /****************************************************************************************/
537 VOID
X11Kbd__Root__Dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
539 EnterFunc(bug("[X11Kbd] Dispose()\n"));
541 ObtainSemaphore( &XSD(cl
)->sema
);
542 XSD(cl
)->kbdhidd
= NULL
;
543 ReleaseSemaphore( &XSD(cl
)->sema
);
544 OOP_DoSuperMethod(cl
, o
, msg
);
547 /****************************************************************************************/
549 VOID
X11Kbd__Hidd_Kbd_X11__HandleEvent(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Kbd_X11_HandleEvent
*msg
)
551 struct x11kbd_data
*data
;
555 EnterFunc(bug("x11kbd_handleevent()\n"));
557 data
= OOP_INST_DATA(cl
, o
);
558 xk
= &(msg
->event
->xkey
);
560 keycode
= xkey2hidd(xk
, XSD(cl
));
563 ReturnVoid("X11Kbd::HandleEvent: Unknown key!");
566 if (msg
->event
->type
== KeyRelease
)
568 keycode
|= IECODE_UP_PREFIX
;
571 if (keycode
!= data
->prev_keycode
)
573 data
->kbd_callback(data
->callbackdata
, keycode
);
574 data
->prev_keycode
= keycode
;
577 ReturnVoid("X11Kbd::HandleEvent");
580 /****************************************************************************************/
585 /****************************************************************************************/
587 WORD
lookup_keytable(KeySym
*ks
, struct _keytable
*keytable
)
592 for (t
= 0; keytable
[t
].hiddcode
!= -1; t
++)
594 if (*ks
== keytable
[t
].keysym
)
596 D(bug("xktac: found in key table\n"));
597 result
= keytable
[t
].hiddcode
;
605 /****************************************************************************************/
607 long xkey2hidd (XKeyEvent
*xk
, struct x11_staticdata
*xsd
)
614 D(bug("xkey2hidd\n"));
619 if ((xk
->keycode
>= 0) && (xk
->keycode
< 256))
621 result
= xsd
->keycode2rawkey
[xk
->keycode
];
622 if (result
== 255) result
= -1;
630 D(count
=) XCALL(XLookupString
, xk
, buffer
, 10, &ks
, NULL
);
633 D(bug("xk2h: Code %d (0x%x). Event was decoded into %d chars: %d (0x%x)\n",xk
->keycode
, xk
->keycode
, count
,ks
,ks
));
635 result
= lookup_keytable(&ks
, keytable
);
636 if (result
== -1) result
= lookup_keytable(&ks
, english_keytable
);
638 ReturnInt ("xk2h", long, result
);
640 } /* XKeyToAmigaCode */
643 /****************************************************************************************/
646 #define XSD(cl) (&LIBBASE->xsd)
648 /****************************************************************************************/
650 static int kbd_init(LIBBASETYPEPTR LIBBASE
)
653 return OOP_ObtainAttrBases(attrbases
);
656 /****************************************************************************************/
658 static int kbd_expunge(LIBBASETYPEPTR LIBBASE
)
660 OOP_ReleaseAttrBases(attrbases
);
664 /****************************************************************************************/
666 ADD2INITLIB(kbd_init
, 0);
667 ADD2EXPUNGELIB(kbd_expunge
, 0);
669 /****************************************************************************************/