2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
5 Desc: X11 hidd handling keypresses.
10 #define __OOP_NOATTRBASES__
14 #include <proto/dos.h>
15 #include <proto/utility.h>
16 #include <proto/oop.h>
19 #define timeval sys_timeval
21 #include <X11/keysym.h>
22 #include <X11/Xutil.h>
27 #include <hidd/hidd.h>
28 #include <hidd/keyboard.h>
30 #include <devices/inputevent.h>
32 #include <aros/symbolsets.h>
35 #include <aros/debug.h>
37 #include LC_LIBDEFS_FILE
41 /****************************************************************************************/
43 long xkey2hidd (XKeyEvent
*xk
, struct x11_staticdata
*xsd
);
45 static OOP_AttrBase HiddKbdAB
;
47 static struct OOP_ABDescr attrbases
[] =
49 { IID_Hidd_Kbd
, &HiddKbdAB
},
53 /****************************************************************************************/
55 static struct _keytable
69 {XK_BackSpace
, 0x41 },
74 {XK_Caps_Lock
, 0x62 },
92 {XK_F12
, 0x5f }, /* HELP, F12 would be 0x6F */
96 {XK_Prior
, 0x48 }, /* PageUP */
97 {XK_Next
, 0x49 }, /* PageDown */
99 {XK_Scroll_Lock
, 0x6b },
102 {XK_KP_Enter
, 0x43 },
103 {XK_KP_Subtract
, 0x4a },
104 {XK_KP_Decimal
, 0x3c },
105 {XK_KP_Separator
, 0x3c },
106 {XK_KP_Delete
, 0x3c },
108 {XK_KP_Subtract
, 0x4a },
109 {XK_KP_Multiply
, 0x5d },
110 {XK_KP_Divide
, 0x5c },
113 {XK_KP_Insert
, 0x0f },
119 {XK_KP_Page_Down
, 0x1f },
123 {XK_KP_Begin
, 0x2e },
125 {XK_KP_Right
, 0x2f },
131 {XK_KP_Page_Up
, 0x3f },
189 /****************************************************************************************/
191 /* English keyboard */
192 static struct _keytable english_keytable
[] =
194 {XK_Control_L
, 0x63 }, /* left control = control */
195 {XK_Multi_key
, 0x63 }, /* right control = control */
196 {XK_Super_L
, 0x66 }, /* left win = LAMIGA */
197 {XK_Super_R
, 0x67 }, /* right win = RAMIGA */
198 {XK_Menu
, 0x67 }, /* menu key = RAMIGA */
199 {XK_Meta_L
, 0x64 }, /* left Alt = LALT */
200 {XK_Mode_switch
, 0x65 }, /* right Alt = RALT */
210 /* Key right of TAB */
214 /* Key between T and U */
230 /* Keys right of 0 */
234 /* Keys right of P */
235 {XK_bracketleft
, 0x1A },
236 {XK_bracketright
, 0x1B },
238 /* Keys right of L */
239 {XK_semicolon
, 0x29 },
240 {XK_apostrophe
, 0x2A },
241 {XK_backslash
, 0x2B }, /* Third key right of L might not be present */
243 /* Key right of shift and 2nd left of X (might not be present) */
246 /* Keys 2nd right of N (= usually right of M) */
254 /****************************************************************************************/
257 /* German keyboard */
258 static struct _keytable german_keytable
[] =
260 {XK_Control_L
, 0x63 }, /* linke STRG = control */
261 {XK_Multi_key
, 0x63 }, /* rechte STRG = control */
262 {XK_Super_L
, 0x66 }, /* Linke Win = LAMIGA */
263 {XK_Super_R
, 0x67 }, /* Rechte Win = RAMIGA */
264 {XK_Meta_L
, 0x64 }, /* Linke Alt = LALT */
265 {XK_Mode_switch
, 0x65 }, /* Alt Gr = RALT */
275 /* Key right of TAB */
279 /* Key between T and U */
292 {XK_asciicircum
, 0x00 }, /* Akzent links neben 1 Taste */
294 /* Keys right of 0 */
295 {XK_equal
, 0x0A }, /* = */
296 {XK_ssharp
, 0x0B }, /* scharfes s */
297 {XK_acute
, 0x0C }, /* Akzent rechts von scharfem s */
299 /* Keys right of P */
300 {XK_udiaeresis
, 0x1A }, /* Umlaut u */
301 {XK_Udiaeresis
, 0x1A },
302 {XK_plus
, 0x1B }, /* + */
304 /* Keys right of L */
305 {XK_odiaeresis
, 0x29 }, /* Umlaut o */
306 {XK_Odiaeresis
, 0x29 },
307 {XK_adiaeresis
, 0x2A }, /* Umlaut a */
308 {XK_Adiaeresis
, 0x2A },
309 {XK_numbersign
, 0x2B }, /* # */
311 /* Key right of shift and 2nd left of X (might not be present) */
312 {XK_less
, 0x30 }, /* < */
314 /* Keys 2nd right of N (= usually right of M) */
315 {XK_comma
, 0x38 }, /* Komma */
316 {XK_period
, 0x39 }, /* Punkt */
317 {XK_minus
, 0x3A }, /* Minus */
324 /* Italian keyboard */
325 static struct _keytable italian_keytable
[] =
327 {XK_Control_L
, 0x63 }, /* left CTRL = control */
328 {XK_Multi_key
, 0x63 }, /* right CTRL = control */
329 {XK_Super_L
, 0x66 }, /* left win = LAMIGA */
330 {XK_Super_R
, 0x67 }, /* right win = RAMIGA */
331 {XK_Meta_L
, 0x64 }, /* left alt = LALT */
332 {XK_Mode_switch
, 0x65 }, /* right alt = RALT */
343 /* Key right of TAB */
347 /* Key between T and U */
361 {XK_backslash
, 0x00 },
363 /* Keys right of 0 */
364 {XK_apostrophe
, 0x0B },
368 /* Keys right of P */
371 {XK_plus
, 0x1B }, /* + */
373 /* Keys right of L */
378 {XK_Ugrave
, 0x2B }, /* Third key right of L might not be present */
381 /* Key right of shift and 2nd left of X (might not be present) */
382 {XK_less
, 0x30 }, /* < */
384 /* Keys 2nd right of N (= usually right of M) */
393 /****************************************************************************************/
397 /* Use this template to create a keytable for your language:
399 Do not touch the right values (rawkey numbers). Only change
400 the XK's at the left side. To find out the XK_ names (keysym)
401 start "xev" and press the key the comment describes (for
402 example "Key left of S" in the xev window. In the Shell
403 window you will see output like this:
405 KeyPress event, serial 30, synthetic NO, window 0x5000001,
406 root 0x47, subw 0x5000002, time 3410089115, (24,45), root:(28,69),
407 state 0x0, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
408 XLookupString gives 0 characters: "" |
410 This is the keysym name _______________/
412 So in this case you would have to write "XK_Shift_L"
414 Check all keys, not just the ones with "XK_????"!!!
417 static struct _keytable template_keytable
[] =
419 {XK_Control_L
, 0x63 }, /* left control = control */
420 {XK_Multi_key
, 0x63 }, /* right control = control */
421 {XK_Super_L
, 0x66 }, /* left win = LAMIGA */
422 {XK_Super_R
, 0x67 }, /* right win = RAMIGA */
423 {XK_Meta_L
, 0x64 }, /* left Alt = LALT */
424 {XK_Mode_switch
, 0x65 }, /* right Alt = RALT */
434 /* Key right of TAB */
438 /* Key between T and U */
454 /* Keys right of 0 */
458 /* Keys right of P */
462 /* Keys right of L */
465 {XK_
????, 0x2B }, /* Third key right of L might not be present */
467 /* Key right of shift and 2nd left of X (might not be present) */
470 /* Keys 2nd right of N (= usually right of M) */
480 /****************************************************************************************/
482 OOP_Object
* X11Kbd__Root__New(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
484 BOOL has_kbd_hidd
= FALSE
;
485 struct TagItem
*tag
, *tstate
;
486 APTR callback
= NULL
;
487 APTR callbackdata
= NULL
;
489 EnterFunc(bug("X11Kbd::New()\n"));
491 ObtainSemaphoreShared( &XSD(cl
)->sema
);
493 if (XSD(cl
)->kbdhidd
)
496 ReleaseSemaphore( &XSD(cl
)->sema
);
498 if (has_kbd_hidd
) { /* Cannot open twice */
499 D(bug("[X11Kbd] Attempt to create second instance\n"));
500 ReturnPtr("X11Kbd::New", OOP_Object
*, NULL
); /* Should have some error code here */
503 tstate
= msg
->attrList
;
504 D(bug("tstate: %p, tag=%x\n", tstate
, tstate
->ti_Tag
));
506 while ((tag
= NextTagItem(&tstate
)))
510 D(bug("Got tag %d, data %x\n", tag
->ti_Tag
, tag
->ti_Data
));
512 if (IS_HIDDKBD_ATTR(tag
->ti_Tag
, idx
))
514 D(bug("Kbd hidd tag\n"));
517 case aoHidd_Kbd_IrqHandler
:
518 callback
= (APTR
)tag
->ti_Data
;
519 D(bug("Got callback %p\n", (APTR
)tag
->ti_Data
));
522 case aoHidd_Kbd_IrqHandlerData
:
523 callbackdata
= (APTR
)tag
->ti_Data
;
524 D(bug("Got data %p\n", (APTR
)tag
->ti_Data
));
529 } /* while (tags to process) */
531 if (NULL
== callback
)
532 ReturnPtr("X11Kbd::New", OOP_Object
*, NULL
); /* Should have some error code here */
534 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
537 struct x11kbd_data
*data
= OOP_INST_DATA(cl
, o
);
539 data
->kbd_callback
= (VOID (*)(APTR
, UWORD
))callback
;
540 data
->callbackdata
= callbackdata
;
541 data
->prev_keycode
= 0xFFFF;
543 ObtainSemaphore( &XSD(cl
)->sema
);
544 XSD(cl
)->kbdhidd
= o
;
545 ReleaseSemaphore( &XSD(cl
)->sema
);
548 ReturnPtr("X11Kbd::New", OOP_Object
*, o
);
551 /****************************************************************************************/
553 VOID
X11Kbd__Root__Dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
555 EnterFunc(bug("[X11Kbd] Dispose()\n"));
557 ObtainSemaphore( &XSD(cl
)->sema
);
558 XSD(cl
)->kbdhidd
= NULL
;
559 ReleaseSemaphore( &XSD(cl
)->sema
);
560 OOP_DoSuperMethod(cl
, o
, msg
);
563 /****************************************************************************************/
565 VOID
X11Kbd__Hidd_X11Kbd__HandleEvent(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_X11Kbd_HandleEvent
*msg
)
567 struct x11kbd_data
*data
;
571 EnterFunc(bug("x11kbd_handleevent()\n"));
573 data
= OOP_INST_DATA(cl
, o
);
574 xk
= &(msg
->event
->xkey
);
576 keycode
= xkey2hidd(xk
, XSD(cl
));
579 ReturnVoid("X11Kbd::HandleEvent: Unknown key!");
582 if (msg
->event
->type
== KeyRelease
)
584 keycode
|= IECODE_UP_PREFIX
;
587 if (keycode
!= data
->prev_keycode
)
589 data
->kbd_callback(data
->callbackdata
, keycode
);
590 data
->prev_keycode
= keycode
;
593 ReturnVoid("X11Kbd::HandleEvent");
596 /****************************************************************************************/
601 /****************************************************************************************/
603 WORD
lookup_keytable(KeySym
*ks
, struct _keytable
*keytable
)
608 for (t
= 0; keytable
[t
].hiddcode
!= -1; t
++)
610 if (*ks
== keytable
[t
].keysym
)
612 D(bug("xktac: found in key table\n"));
613 result
= keytable
[t
].hiddcode
;
621 /****************************************************************************************/
623 long xkey2hidd (XKeyEvent
*xk
, struct x11_staticdata
*xsd
)
630 D(bug("xkey2hidd\n"));
635 if ((xk
->keycode
>= 0) && (xk
->keycode
< 256))
637 result
= xsd
->keycode2rawkey
[xk
->keycode
];
638 if (result
== 255) result
= -1;
646 D(count
=) XCALL(XLookupString
, xk
, buffer
, 10, &ks
, NULL
);
649 D(bug("xk2h: Code %d (0x%x). Event was decoded into %d chars: %d (0x%x)\n",xk
->keycode
, xk
->keycode
, count
,ks
,ks
));
651 result
= lookup_keytable(&ks
, keytable
);
652 if (result
== -1) result
= lookup_keytable(&ks
, english_keytable
);
654 ReturnInt ("xk2h", long, result
);
656 } /* XKeyToAmigaCode */
659 /****************************************************************************************/
662 #define XSD(cl) (&LIBBASE->xsd)
664 /****************************************************************************************/
666 static int kbd_init(LIBBASETYPEPTR LIBBASE
)
669 return OOP_ObtainAttrBases(attrbases
);
672 /****************************************************************************************/
674 static int kbd_expunge(LIBBASETYPEPTR LIBBASE
)
676 OOP_ReleaseAttrBases(attrbases
);
680 /****************************************************************************************/
682 ADD2INITLIB(kbd_init
, 0);
683 ADD2EXPUNGELIB(kbd_expunge
, 0);
685 /****************************************************************************************/