Commit a528b80cb09977806129249ea604aaef3830f3ec
1 parent
12bc92ab
Miscellaneous VNC related fixes from Xen forwarded by Matthew Kent.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3489 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
124 additions
and
11 deletions
console.c
@@ -509,7 +509,7 @@ static void text_console_resize(TextConsole *s) | @@ -509,7 +509,7 @@ static void text_console_resize(TextConsole *s) | ||
509 | c++; | 509 | c++; |
510 | } | 510 | } |
511 | } | 511 | } |
512 | - free(s->cells); | 512 | + qemu_free(s->cells); |
513 | s->cells = cells; | 513 | s->cells = cells; |
514 | } | 514 | } |
515 | 515 | ||
@@ -1167,11 +1167,21 @@ int is_graphic_console(void) | @@ -1167,11 +1167,21 @@ int is_graphic_console(void) | ||
1167 | return active_console->console_type == GRAPHIC_CONSOLE; | 1167 | return active_console->console_type == GRAPHIC_CONSOLE; |
1168 | } | 1168 | } |
1169 | 1169 | ||
1170 | +void console_color_init(DisplayState *ds) | ||
1171 | +{ | ||
1172 | + int i, j; | ||
1173 | + for (j = 0; j < 2; j++) { | ||
1174 | + for (i = 0; i < 8; i++) { | ||
1175 | + color_table[j][i] = col_expand(ds, | ||
1176 | + vga_get_color(ds, color_table_rgb[j][i])); | ||
1177 | + } | ||
1178 | + } | ||
1179 | +} | ||
1180 | + | ||
1170 | CharDriverState *text_console_init(DisplayState *ds, const char *p) | 1181 | CharDriverState *text_console_init(DisplayState *ds, const char *p) |
1171 | { | 1182 | { |
1172 | CharDriverState *chr; | 1183 | CharDriverState *chr; |
1173 | TextConsole *s; | 1184 | TextConsole *s; |
1174 | - int i,j; | ||
1175 | unsigned width; | 1185 | unsigned width; |
1176 | unsigned height; | 1186 | unsigned height; |
1177 | static int color_inited; | 1187 | static int color_inited; |
@@ -1195,12 +1205,7 @@ CharDriverState *text_console_init(DisplayState *ds, const char *p) | @@ -1195,12 +1205,7 @@ CharDriverState *text_console_init(DisplayState *ds, const char *p) | ||
1195 | 1205 | ||
1196 | if (!color_inited) { | 1206 | if (!color_inited) { |
1197 | color_inited = 1; | 1207 | color_inited = 1; |
1198 | - for(j = 0; j < 2; j++) { | ||
1199 | - for(i = 0; i < 8; i++) { | ||
1200 | - color_table[j][i] = col_expand(s->ds, | ||
1201 | - vga_get_color(s->ds, color_table_rgb[j][i])); | ||
1202 | - } | ||
1203 | - } | 1208 | + console_color_init(s->ds); |
1204 | } | 1209 | } |
1205 | s->y_displayed = 0; | 1210 | s->y_displayed = 0; |
1206 | s->y_base = 0; | 1211 | s->y_base = 0; |
keymaps.c
@@ -32,6 +32,12 @@ static int get_keysym(const char *name) | @@ -32,6 +32,12 @@ static int get_keysym(const char *name) | ||
32 | return 0; | 32 | return 0; |
33 | } | 33 | } |
34 | 34 | ||
35 | +struct key_range { | ||
36 | + int start; | ||
37 | + int end; | ||
38 | + struct key_range *next; | ||
39 | +}; | ||
40 | + | ||
35 | #define MAX_NORMAL_KEYCODE 512 | 41 | #define MAX_NORMAL_KEYCODE 512 |
36 | #define MAX_EXTRA_COUNT 256 | 42 | #define MAX_EXTRA_COUNT 256 |
37 | typedef struct { | 43 | typedef struct { |
@@ -41,8 +47,34 @@ typedef struct { | @@ -41,8 +47,34 @@ typedef struct { | ||
41 | uint16_t keycode; | 47 | uint16_t keycode; |
42 | } keysym2keycode_extra[MAX_EXTRA_COUNT]; | 48 | } keysym2keycode_extra[MAX_EXTRA_COUNT]; |
43 | int extra_count; | 49 | int extra_count; |
50 | + struct key_range *keypad_range; | ||
51 | + struct key_range *numlock_range; | ||
44 | } kbd_layout_t; | 52 | } kbd_layout_t; |
45 | 53 | ||
54 | +static void add_to_key_range(struct key_range **krp, int code) { | ||
55 | + struct key_range *kr; | ||
56 | + for (kr = *krp; kr; kr = kr->next) { | ||
57 | + if (code >= kr->start && code <= kr->end) | ||
58 | + break; | ||
59 | + if (code == kr->start - 1) { | ||
60 | + kr->start--; | ||
61 | + break; | ||
62 | + } | ||
63 | + if (code == kr->end + 1) { | ||
64 | + kr->end++; | ||
65 | + break; | ||
66 | + } | ||
67 | + } | ||
68 | + if (kr == NULL) { | ||
69 | + kr = qemu_mallocz(sizeof(*kr)); | ||
70 | + if (kr) { | ||
71 | + kr->start = kr->end = code; | ||
72 | + kr->next = *krp; | ||
73 | + *krp = kr; | ||
74 | + } | ||
75 | + } | ||
76 | +} | ||
77 | + | ||
46 | static kbd_layout_t *parse_keyboard_layout(const char *language, | 78 | static kbd_layout_t *parse_keyboard_layout(const char *language, |
47 | kbd_layout_t * k) | 79 | kbd_layout_t * k) |
48 | { | 80 | { |
@@ -87,7 +119,15 @@ static kbd_layout_t *parse_keyboard_layout(const char *language, | @@ -87,7 +119,15 @@ static kbd_layout_t *parse_keyboard_layout(const char *language, | ||
87 | // fprintf(stderr, "Warning: unknown keysym %s\n", line); | 119 | // fprintf(stderr, "Warning: unknown keysym %s\n", line); |
88 | } else { | 120 | } else { |
89 | const char *rest = end_of_keysym + 1; | 121 | const char *rest = end_of_keysym + 1; |
90 | - int keycode = strtol(rest, NULL, 0); | 122 | + char *rest2; |
123 | + int keycode = strtol(rest, &rest2, 0); | ||
124 | + | ||
125 | + if (rest && strstr(rest, "numlock")) { | ||
126 | + add_to_key_range(&k->keypad_range, keycode); | ||
127 | + add_to_key_range(&k->numlock_range, keysym); | ||
128 | + //fprintf(stderr, "keypad keysym %04x keycode %d\n", keysym, keycode); | ||
129 | + } | ||
130 | + | ||
91 | /* if(keycode&0x80) | 131 | /* if(keycode&0x80) |
92 | keycode=(keycode<<8)^0x80e0; */ | 132 | keycode=(keycode<<8)^0x80e0; */ |
93 | if (keysym < MAX_NORMAL_KEYCODE) { | 133 | if (keysym < MAX_NORMAL_KEYCODE) { |
@@ -143,3 +183,25 @@ static int keysym2scancode(void *kbd_layout, int keysym) | @@ -143,3 +183,25 @@ static int keysym2scancode(void *kbd_layout, int keysym) | ||
143 | } | 183 | } |
144 | return 0; | 184 | return 0; |
145 | } | 185 | } |
186 | + | ||
187 | +static inline int keycode_is_keypad(void *kbd_layout, int keycode) | ||
188 | +{ | ||
189 | + kbd_layout_t *k = kbd_layout; | ||
190 | + struct key_range *kr; | ||
191 | + | ||
192 | + for (kr = k->keypad_range; kr; kr = kr->next) | ||
193 | + if (keycode >= kr->start && keycode <= kr->end) | ||
194 | + return 1; | ||
195 | + return 0; | ||
196 | +} | ||
197 | + | ||
198 | +static inline int keysym_is_numlock(void *kbd_layout, int keysym) | ||
199 | +{ | ||
200 | + kbd_layout_t *k = kbd_layout; | ||
201 | + struct key_range *kr; | ||
202 | + | ||
203 | + for (kr = k->numlock_range; kr; kr = kr->next) | ||
204 | + if (keysym >= kr->start && keysym <= kr->end) | ||
205 | + return 1; | ||
206 | + return 0; | ||
207 | +} |
vl.h
@@ -374,6 +374,7 @@ void vga_hw_screen_dump(const char *filename); | @@ -374,6 +374,7 @@ void vga_hw_screen_dump(const char *filename); | ||
374 | int is_graphic_console(void); | 374 | int is_graphic_console(void); |
375 | CharDriverState *text_console_init(DisplayState *ds, const char *p); | 375 | CharDriverState *text_console_init(DisplayState *ds, const char *p); |
376 | void console_select(unsigned int index); | 376 | void console_select(unsigned int index); |
377 | +void console_color_init(DisplayState *ds); | ||
377 | 378 | ||
378 | /* serial ports */ | 379 | /* serial ports */ |
379 | 380 |
vnc.c
@@ -284,7 +284,10 @@ static void vnc_dpy_resize(DisplayState *ds, int w, int h) | @@ -284,7 +284,10 @@ static void vnc_dpy_resize(DisplayState *ds, int w, int h) | ||
284 | exit(1); | 284 | exit(1); |
285 | } | 285 | } |
286 | 286 | ||
287 | - ds->depth = vs->depth * 8; | 287 | + if (ds->depth != vs->depth * 8) { |
288 | + ds->depth = vs->depth * 8; | ||
289 | + console_color_init(ds); | ||
290 | + } | ||
288 | size_changed = ds->width != w || ds->height != h; | 291 | size_changed = ds->width != w || ds->height != h; |
289 | ds->width = w; | 292 | ds->width = w; |
290 | ds->height = h; | 293 | ds->height = h; |
@@ -907,6 +910,12 @@ static void reset_keys(VncState *vs) | @@ -907,6 +910,12 @@ static void reset_keys(VncState *vs) | ||
907 | } | 910 | } |
908 | } | 911 | } |
909 | 912 | ||
913 | +static void press_key(VncState *vs, int keysym) | ||
914 | +{ | ||
915 | + kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) & 0x7f); | ||
916 | + kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80); | ||
917 | +} | ||
918 | + | ||
910 | static void do_key_event(VncState *vs, int down, uint32_t sym) | 919 | static void do_key_event(VncState *vs, int down, uint32_t sym) |
911 | { | 920 | { |
912 | int keycode; | 921 | int keycode; |
@@ -934,6 +943,28 @@ static void do_key_event(VncState *vs, int down, uint32_t sym) | @@ -934,6 +943,28 @@ static void do_key_event(VncState *vs, int down, uint32_t sym) | ||
934 | return; | 943 | return; |
935 | } | 944 | } |
936 | break; | 945 | break; |
946 | + case 0x45: /* NumLock */ | ||
947 | + if (!down) | ||
948 | + vs->modifiers_state[keycode] ^= 1; | ||
949 | + break; | ||
950 | + } | ||
951 | + | ||
952 | + if (keycode_is_keypad(vs->kbd_layout, keycode)) { | ||
953 | + /* If the numlock state needs to change then simulate an additional | ||
954 | + keypress before sending this one. This will happen if the user | ||
955 | + toggles numlock away from the VNC window. | ||
956 | + */ | ||
957 | + if (keysym_is_numlock(vs->kbd_layout, sym & 0xFFFF)) { | ||
958 | + if (!vs->modifiers_state[0x45]) { | ||
959 | + vs->modifiers_state[0x45] = 1; | ||
960 | + press_key(vs, 0xff7f); | ||
961 | + } | ||
962 | + } else { | ||
963 | + if (vs->modifiers_state[0x45]) { | ||
964 | + vs->modifiers_state[0x45] = 0; | ||
965 | + press_key(vs, 0xff7f); | ||
966 | + } | ||
967 | + } | ||
937 | } | 968 | } |
938 | 969 | ||
939 | if (is_graphic_console()) { | 970 | if (is_graphic_console()) { |
@@ -991,7 +1022,7 @@ static void do_key_event(VncState *vs, int down, uint32_t sym) | @@ -991,7 +1022,7 @@ static void do_key_event(VncState *vs, int down, uint32_t sym) | ||
991 | 1022 | ||
992 | static void key_event(VncState *vs, int down, uint32_t sym) | 1023 | static void key_event(VncState *vs, int down, uint32_t sym) |
993 | { | 1024 | { |
994 | - if (sym >= 'A' && sym <= 'Z') | 1025 | + if (sym >= 'A' && sym <= 'Z' && is_graphic_console()) |
995 | sym = sym - 'A' + 'a'; | 1026 | sym = sym - 'A' + 'a'; |
996 | do_key_event(vs, down, sym); | 1027 | do_key_event(vs, down, sym); |
997 | } | 1028 | } |
vnc_keysym.h
@@ -231,6 +231,19 @@ static name2keysym_t name2keysym[]={ | @@ -231,6 +231,19 @@ static name2keysym_t name2keysym[]={ | ||
231 | {"Home", 0xff50}, /* XK_Home */ | 231 | {"Home", 0xff50}, /* XK_Home */ |
232 | {"End", 0xff57}, /* XK_End */ | 232 | {"End", 0xff57}, /* XK_End */ |
233 | {"Scroll_Lock", 0xff14}, /* XK_Scroll_Lock */ | 233 | {"Scroll_Lock", 0xff14}, /* XK_Scroll_Lock */ |
234 | +{"KP_Home", 0xff95}, | ||
235 | +{"KP_Left", 0xff96}, | ||
236 | +{"KP_Up", 0xff97}, | ||
237 | +{"KP_Right", 0xff98}, | ||
238 | +{"KP_Down", 0xff99}, | ||
239 | +{"KP_Prior", 0xff9a}, | ||
240 | +{"KP_Page_Up", 0xff9a}, | ||
241 | +{"KP_Next", 0xff9b}, | ||
242 | +{"KP_Page_Down", 0xff9b}, | ||
243 | +{"KP_End", 0xff9c}, | ||
244 | +{"KP_Begin", 0xff9d}, | ||
245 | +{"KP_Insert", 0xff9e}, | ||
246 | +{"KP_Delete", 0xff9f}, | ||
234 | {"F1", 0xffbe}, /* XK_F1 */ | 247 | {"F1", 0xffbe}, /* XK_F1 */ |
235 | {"F2", 0xffbf}, /* XK_F2 */ | 248 | {"F2", 0xffbf}, /* XK_F2 */ |
236 | {"F3", 0xffc0}, /* XK_F3 */ | 249 | {"F3", 0xffc0}, /* XK_F3 */ |
@@ -258,6 +271,7 @@ static name2keysym_t name2keysym[]={ | @@ -258,6 +271,7 @@ static name2keysym_t name2keysym[]={ | ||
258 | {"KP_8", 0xffb8}, /* XK_KP_8 */ | 271 | {"KP_8", 0xffb8}, /* XK_KP_8 */ |
259 | {"KP_9", 0xffb9}, /* XK_KP_9 */ | 272 | {"KP_9", 0xffb9}, /* XK_KP_9 */ |
260 | {"KP_Add", 0xffab}, /* XK_KP_Add */ | 273 | {"KP_Add", 0xffab}, /* XK_KP_Add */ |
274 | +{"KP_Separator", 0xffac},/* XK_KP_Separator */ | ||
261 | {"KP_Decimal", 0xffae}, /* XK_KP_Decimal */ | 275 | {"KP_Decimal", 0xffae}, /* XK_KP_Decimal */ |
262 | {"KP_Divide", 0xffaf}, /* XK_KP_Divide */ | 276 | {"KP_Divide", 0xffaf}, /* XK_KP_Divide */ |
263 | {"KP_Enter", 0xff8d}, /* XK_KP_Enter */ | 277 | {"KP_Enter", 0xff8d}, /* XK_KP_Enter */ |