Commit a528b80cb09977806129249ea604aaef3830f3ec

Authored by balrog
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
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 +}
@@ -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
@@ -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 */