1
2
/*
* QEMU keysym to keycode conversion using rdesktop keymaps
ths
authored
18 years ago
3
*
4
* Copyright ( c ) 2004 Johannes Schindelin
ths
authored
18 years ago
5
*
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the "Software" ), to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED "AS IS" , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE .
*/
25
26
27
28
29
# include "keymaps.h"
# include "sysemu.h"
static int get_keysym ( const name2keysym_t * table ,
const char * name )
30
{
31
const name2keysym_t * p ;
32
for ( p = table ; p -> name != NULL ; p ++ ) {
33
34
35
36
37
38
39
if ( ! strcmp ( p -> name , name ))
return p -> keysym ;
}
return 0 ;
}
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
static void add_to_key_range ( struct key_range ** krp , int code ) {
struct key_range * kr ;
for ( kr = * krp ; kr ; kr = kr -> next ) {
if ( code >= kr -> start && code <= kr -> end )
break ;
if ( code == kr -> start - 1 ) {
kr -> start -- ;
break ;
}
if ( code == kr -> end + 1 ) {
kr -> end ++ ;
break ;
}
}
if ( kr == NULL ) {
kr = qemu_mallocz ( sizeof ( * kr ));
56
57
58
kr -> start = kr -> end = code ;
kr -> next = * krp ;
* krp = kr ;
59
60
61
}
}
62
63
static kbd_layout_t * parse_keyboard_layout ( const name2keysym_t * table ,
const char * language ,
64
65
66
kbd_layout_t * k )
{
FILE * f ;
67
char * filename ;
68
69
70
char line [ 1024 ];
int len ;
71
filename = qemu_find_file ( QEMU_FILE_TYPE_KEYMAP , language );
72
73
74
if ( ! k )
k = qemu_mallocz ( sizeof ( kbd_layout_t ));
75
if ( ! ( filename && ( f = fopen ( filename , "r" )))) {
76
fprintf ( stderr ,
77
"Could not read keymap file: '%s' \n " , language );
78
79
return 0 ;
}
80
qemu_free ( filename );
81
82
83
84
85
86
87
88
89
90
91
for (;;) {
if ( fgets ( line , 1024 , f ) == NULL )
break ;
len = strlen ( line );
if ( len > 0 && line [ len - 1 ] == '\n' )
line [ len - 1 ] = '\0' ;
if ( line [ 0 ] == '#' )
continue ;
if ( ! strncmp ( line , "map " , 4 ))
continue ;
if ( ! strncmp ( line , "include " , 8 )) {
92
parse_keyboard_layout ( table , line + 8 , k );
93
94
95
96
97
98
99
} else {
char * end_of_keysym = line ;
while ( * end_of_keysym != 0 && * end_of_keysym != ' ' )
end_of_keysym ++ ;
if ( * end_of_keysym ) {
int keysym ;
* end_of_keysym = 0 ;
100
keysym = get_keysym ( table , line );
101
102
103
104
if ( keysym == 0 ) {
// fprintf ( stderr , "Warning: unknown keysym %s \n " , line );
} else {
const char * rest = end_of_keysym + 1 ;
105
106
107
108
109
110
111
112
113
char * rest2 ;
int keycode = strtol ( rest , & rest2 , 0 );
if ( rest && strstr ( rest , "numlock" )) {
add_to_key_range ( & k -> keypad_range , keycode );
add_to_key_range ( & k -> numlock_range , keysym );
// fprintf ( stderr , "keypad keysym %04x keycode %d \n " , keysym , keycode );
}
114
115
116
117
118
119
120
121
122
123
124
/* if ( keycode & 0x80 )
keycode = ( keycode << 8 ) ^ 0x80e0 ; */
if ( keysym < MAX_NORMAL_KEYCODE ) {
// fprintf ( stderr , "Setting keysym %s (%d) to %d \n " , line , keysym , keycode );
k -> keysym2keycode [ keysym ] = keycode ;
} else {
if ( k -> extra_count >= MAX_EXTRA_COUNT ) {
fprintf ( stderr ,
"Warning: Could not assign keysym %s (0x%x) because of memory constraints. \n " ,
line , keysym );
} else {
125
# if 0
126
127
fprintf ( stderr , "Setting %d: %d,%d \n " ,
k -> extra_count , keysym , keycode );
128
# endif
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
k -> keysym2keycode_extra [ k -> extra_count ].
keysym = keysym ;
k -> keysym2keycode_extra [ k -> extra_count ].
keycode = keycode ;
k -> extra_count ++ ;
}
}
}
}
}
}
fclose ( f );
return k ;
}
144
145
void * init_keyboard_layout ( const name2keysym_t * table , const char * language )
146
{
147
return parse_keyboard_layout ( table , language , 0 );
148
149
}
150
151
int keysym2scancode ( void * kbd_layout , int keysym )
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
{
kbd_layout_t * k = kbd_layout ;
if ( keysym < MAX_NORMAL_KEYCODE ) {
if ( k -> keysym2keycode [ keysym ] == 0 )
fprintf ( stderr , "Warning: no scancode found for keysym %d \n " ,
keysym );
return k -> keysym2keycode [ keysym ];
} else {
int i ;
# ifdef XK_ISO_Left_Tab
if ( keysym == XK_ISO_Left_Tab )
keysym = XK_Tab ;
# endif
for ( i = 0 ; i < k -> extra_count ; i ++ )
if ( k -> keysym2keycode_extra [ i ]. keysym == keysym )
return k -> keysym2keycode_extra [ i ]. keycode ;
}
return 0 ;
}
171
172
int keycode_is_keypad ( void * kbd_layout , int keycode )
173
174
175
176
177
178
179
180
181
182
{
kbd_layout_t * k = kbd_layout ;
struct key_range * kr ;
for ( kr = k -> keypad_range ; kr ; kr = kr -> next )
if ( keycode >= kr -> start && keycode <= kr -> end )
return 1 ;
return 0 ;
}
183
int keysym_is_numlock ( void * kbd_layout , int keysym )
184
185
186
187
188
189
190
191
192
{
kbd_layout_t * k = kbd_layout ;
struct key_range * kr ;
for ( kr = k -> numlock_range ; kr ; kr = kr -> next )
if ( keysym >= kr -> start && keysym <= kr -> end )
return 1 ;
return 0 ;
}