3 * This module converts keysym values into the corresponding ISO 10646
4 * (UCS, Unicode) values.
6 * The array keysymtab[] contains pairs of X11 keysym values for graphical
7 * characters and the corresponding Unicode value. The function
8 * keysym2ucs() maps a keysym onto a Unicode value using a binary search,
9 * therefore keysymtab[] must remain SORTED by keysym value.
11 * The keysym -> UTF-8 conversion will hopefully one day be provided
12 * by Xlib via XmbLookupString() and should ideally not have to be
13 * done in X applications. But we are not there yet.
15 * We allow to represent any UCS character in the range U-00000000 to
16 * U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff.
17 * This admittedly does not cover the entire 31-bit space of UCS, but
18 * it does cover all of the characters up to U-10FFFF, which can be
19 * represented by UTF-16, and more, and it is very unlikely that higher
20 * UCS codes will ever be assigned by ISO. So to get Unicode character
21 * U+ABCD you can directly use keysym 0x0100abcd.
23 * NOTE: The comments in the table below contain the actual character
24 * encoded in UTF-8, so for viewing and editing best use an editor in
27 * Author: Markus G. Kuhn <mkuhn@acm.org>, University of Cambridge, April 2001
29 * Special thanks to Richard Verhoeven <river@win.tue.nl> for preparing
30 * an initial draft of the mapping table.
32 * This software is in the public domain. Share and enjoy!
34 * AUTOMATICALLY GENERATED FILE, DO NOT EDIT !!! (unicode/convmap.pl)
37 #include "keysym2ucs.h"
43 unsigned short keysym
;
47 const static struct codepair keysymtab
[] = {
802 /* FIXME: there is no keysym 0x13a4? But 0x20ac is EuroSign in both
803 keysym and Unicode */
811 /* Special function keys. */
813 { 0xff08, 0x0008 }, /* XK_BackSpace */
814 { 0xff09, 0x0009 }, /* XK_Tab */
815 { 0xff0a, 0x000a }, /* XK_Linefeed */
816 { 0xff0d, 0x000d }, /* XK_Return */
817 { 0xff13, 0x0013 }, /* XK_Pause */
818 { 0xff1b, 0x001b }, /* XK_Escape */
819 { 0xff50, 0x0001 }, /* XK_Home */
820 { 0xff51, 0x001c }, /* XK_Left */
821 { 0xff52, 0x001e }, /* XK_Up */
822 { 0xff53, 0x001d }, /* XK_Right */
823 { 0xff54, 0x001f }, /* XK_Down */
824 { 0xff55, 0x000b }, /* XK_Prior */
825 { 0xff56, 0x000c }, /* XK_Next */
826 { 0xff57, 0x0004 }, /* XK_End */
827 { 0xff6a, 0x0005 }, /* XK_Help */
828 { 0xffff, 0x007f }, /* XK_Delete */
832 keysym2ucs(int keysym
)
835 int max
= sizeof(keysymtab
) / sizeof(struct codepair
) - 1;
838 /* first check for Latin-1 characters (1:1 mapping) */
839 if ((keysym
>= 0x0020 && keysym
<= 0x007e) ||
840 (keysym
>= 0x00a0 && keysym
<= 0x00ff))
843 /* also check for directly encoded 24-bit UCS characters */
844 if ((keysym
& 0xff000000) == 0x01000000)
845 return keysym
& 0x00ffffff;
847 /* binary search in table */
849 mid
= (min
+ max
) / 2;
850 if (keysymtab
[mid
].keysym
< keysym
)
852 else if (keysymtab
[mid
].keysym
> keysym
)
856 return keysymtab
[mid
].ucs
;
860 /* no matching Unicode value found */
865 reverse_compare(const void *a
, const void *b
)
867 const struct codepair
*ca
= a
, *cb
= b
;
869 return ca
->ucs
- cb
->ucs
;
875 static struct codepair
*reverse_keysymtab
;
878 int max
= sizeof(keysymtab
) / sizeof(struct codepair
) - 1;
881 if (reverse_keysymtab
== NULL
) {
882 reverse_keysymtab
= malloc(sizeof(keysymtab
));
883 memcpy(reverse_keysymtab
, keysymtab
, sizeof(keysymtab
));
885 qsort(reverse_keysymtab
,
886 sizeof(keysymtab
) / sizeof(struct codepair
),
887 sizeof(struct codepair
),
891 /* first check for Latin-1 characters (1:1 mapping) */
892 if ((ucs
>= 0x0020 && ucs
<= 0x007e) ||
893 (ucs
>= 0x00a0 && ucs
<= 0x00ff))
896 /* binary search in table */
898 mid
= (min
+ max
) / 2;
899 if (reverse_keysymtab
[mid
].ucs
< ucs
)
901 else if (reverse_keysymtab
[mid
].ucs
> ucs
)
905 return reverse_keysymtab
[mid
].keysym
;
909 /* finally, assume a directly encoded 24-bit UCS character */
910 return ucs
| 0x01000000;