mirror of https://github.com/proxmox/mirror_qemu
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-71466251a162master
parent
12bc92ab8a
commit
a528b80cb0
21
console.c
21
console.c
|
@ -509,7 +509,7 @@ static void text_console_resize(TextConsole *s)
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(s->cells);
|
qemu_free(s->cells);
|
||||||
s->cells = cells;
|
s->cells = cells;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1167,11 +1167,21 @@ int is_graphic_console(void)
|
||||||
return active_console->console_type == GRAPHIC_CONSOLE;
|
return active_console->console_type == GRAPHIC_CONSOLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void console_color_init(DisplayState *ds)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
for (j = 0; j < 2; j++) {
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
color_table[j][i] = col_expand(ds,
|
||||||
|
vga_get_color(ds, color_table_rgb[j][i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CharDriverState *text_console_init(DisplayState *ds, const char *p)
|
CharDriverState *text_console_init(DisplayState *ds, const char *p)
|
||||||
{
|
{
|
||||||
CharDriverState *chr;
|
CharDriverState *chr;
|
||||||
TextConsole *s;
|
TextConsole *s;
|
||||||
int i,j;
|
|
||||||
unsigned width;
|
unsigned width;
|
||||||
unsigned height;
|
unsigned height;
|
||||||
static int color_inited;
|
static int color_inited;
|
||||||
|
@ -1195,12 +1205,7 @@ CharDriverState *text_console_init(DisplayState *ds, const char *p)
|
||||||
|
|
||||||
if (!color_inited) {
|
if (!color_inited) {
|
||||||
color_inited = 1;
|
color_inited = 1;
|
||||||
for(j = 0; j < 2; j++) {
|
console_color_init(s->ds);
|
||||||
for(i = 0; i < 8; i++) {
|
|
||||||
color_table[j][i] = col_expand(s->ds,
|
|
||||||
vga_get_color(s->ds, color_table_rgb[j][i]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
s->y_displayed = 0;
|
s->y_displayed = 0;
|
||||||
s->y_base = 0;
|
s->y_base = 0;
|
||||||
|
|
64
keymaps.c
64
keymaps.c
|
@ -32,6 +32,12 @@ static int get_keysym(const char *name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct key_range {
|
||||||
|
int start;
|
||||||
|
int end;
|
||||||
|
struct key_range *next;
|
||||||
|
};
|
||||||
|
|
||||||
#define MAX_NORMAL_KEYCODE 512
|
#define MAX_NORMAL_KEYCODE 512
|
||||||
#define MAX_EXTRA_COUNT 256
|
#define MAX_EXTRA_COUNT 256
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -41,8 +47,34 @@ typedef struct {
|
||||||
uint16_t keycode;
|
uint16_t keycode;
|
||||||
} keysym2keycode_extra[MAX_EXTRA_COUNT];
|
} keysym2keycode_extra[MAX_EXTRA_COUNT];
|
||||||
int extra_count;
|
int extra_count;
|
||||||
|
struct key_range *keypad_range;
|
||||||
|
struct key_range *numlock_range;
|
||||||
} kbd_layout_t;
|
} kbd_layout_t;
|
||||||
|
|
||||||
|
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));
|
||||||
|
if (kr) {
|
||||||
|
kr->start = kr->end = code;
|
||||||
|
kr->next = *krp;
|
||||||
|
*krp = kr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static kbd_layout_t *parse_keyboard_layout(const char *language,
|
static kbd_layout_t *parse_keyboard_layout(const char *language,
|
||||||
kbd_layout_t * k)
|
kbd_layout_t * k)
|
||||||
{
|
{
|
||||||
|
@ -87,7 +119,15 @@ static kbd_layout_t *parse_keyboard_layout(const char *language,
|
||||||
// fprintf(stderr, "Warning: unknown keysym %s\n", line);
|
// fprintf(stderr, "Warning: unknown keysym %s\n", line);
|
||||||
} else {
|
} else {
|
||||||
const char *rest = end_of_keysym + 1;
|
const char *rest = end_of_keysym + 1;
|
||||||
int keycode = strtol(rest, NULL, 0);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
/* if(keycode&0x80)
|
/* if(keycode&0x80)
|
||||||
keycode=(keycode<<8)^0x80e0; */
|
keycode=(keycode<<8)^0x80e0; */
|
||||||
if (keysym < MAX_NORMAL_KEYCODE) {
|
if (keysym < MAX_NORMAL_KEYCODE) {
|
||||||
|
@ -143,3 +183,25 @@ static int keysym2scancode(void *kbd_layout, int keysym)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int keycode_is_keypad(void *kbd_layout, int keycode)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int keysym_is_numlock(void *kbd_layout, int keysym)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
1
vl.h
1
vl.h
|
@ -374,6 +374,7 @@ void vga_hw_screen_dump(const char *filename);
|
||||||
int is_graphic_console(void);
|
int is_graphic_console(void);
|
||||||
CharDriverState *text_console_init(DisplayState *ds, const char *p);
|
CharDriverState *text_console_init(DisplayState *ds, const char *p);
|
||||||
void console_select(unsigned int index);
|
void console_select(unsigned int index);
|
||||||
|
void console_color_init(DisplayState *ds);
|
||||||
|
|
||||||
/* serial ports */
|
/* serial ports */
|
||||||
|
|
||||||
|
|
33
vnc.c
33
vnc.c
|
@ -284,7 +284,10 @@ static void vnc_dpy_resize(DisplayState *ds, int w, int h)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ds->depth != vs->depth * 8) {
|
||||||
ds->depth = vs->depth * 8;
|
ds->depth = vs->depth * 8;
|
||||||
|
console_color_init(ds);
|
||||||
|
}
|
||||||
size_changed = ds->width != w || ds->height != h;
|
size_changed = ds->width != w || ds->height != h;
|
||||||
ds->width = w;
|
ds->width = w;
|
||||||
ds->height = h;
|
ds->height = h;
|
||||||
|
@ -907,6 +910,12 @@ static void reset_keys(VncState *vs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void press_key(VncState *vs, int keysym)
|
||||||
|
{
|
||||||
|
kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) & 0x7f);
|
||||||
|
kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80);
|
||||||
|
}
|
||||||
|
|
||||||
static void do_key_event(VncState *vs, int down, uint32_t sym)
|
static void do_key_event(VncState *vs, int down, uint32_t sym)
|
||||||
{
|
{
|
||||||
int keycode;
|
int keycode;
|
||||||
|
@ -934,6 +943,28 @@ static void do_key_event(VncState *vs, int down, uint32_t sym)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 0x45: /* NumLock */
|
||||||
|
if (!down)
|
||||||
|
vs->modifiers_state[keycode] ^= 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keycode_is_keypad(vs->kbd_layout, keycode)) {
|
||||||
|
/* If the numlock state needs to change then simulate an additional
|
||||||
|
keypress before sending this one. This will happen if the user
|
||||||
|
toggles numlock away from the VNC window.
|
||||||
|
*/
|
||||||
|
if (keysym_is_numlock(vs->kbd_layout, sym & 0xFFFF)) {
|
||||||
|
if (!vs->modifiers_state[0x45]) {
|
||||||
|
vs->modifiers_state[0x45] = 1;
|
||||||
|
press_key(vs, 0xff7f);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (vs->modifiers_state[0x45]) {
|
||||||
|
vs->modifiers_state[0x45] = 0;
|
||||||
|
press_key(vs, 0xff7f);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_graphic_console()) {
|
if (is_graphic_console()) {
|
||||||
|
@ -991,7 +1022,7 @@ static void do_key_event(VncState *vs, int down, uint32_t sym)
|
||||||
|
|
||||||
static void key_event(VncState *vs, int down, uint32_t sym)
|
static void key_event(VncState *vs, int down, uint32_t sym)
|
||||||
{
|
{
|
||||||
if (sym >= 'A' && sym <= 'Z')
|
if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
|
||||||
sym = sym - 'A' + 'a';
|
sym = sym - 'A' + 'a';
|
||||||
do_key_event(vs, down, sym);
|
do_key_event(vs, down, sym);
|
||||||
}
|
}
|
||||||
|
|
14
vnc_keysym.h
14
vnc_keysym.h
|
@ -231,6 +231,19 @@ static name2keysym_t name2keysym[]={
|
||||||
{"Home", 0xff50}, /* XK_Home */
|
{"Home", 0xff50}, /* XK_Home */
|
||||||
{"End", 0xff57}, /* XK_End */
|
{"End", 0xff57}, /* XK_End */
|
||||||
{"Scroll_Lock", 0xff14}, /* XK_Scroll_Lock */
|
{"Scroll_Lock", 0xff14}, /* XK_Scroll_Lock */
|
||||||
|
{"KP_Home", 0xff95},
|
||||||
|
{"KP_Left", 0xff96},
|
||||||
|
{"KP_Up", 0xff97},
|
||||||
|
{"KP_Right", 0xff98},
|
||||||
|
{"KP_Down", 0xff99},
|
||||||
|
{"KP_Prior", 0xff9a},
|
||||||
|
{"KP_Page_Up", 0xff9a},
|
||||||
|
{"KP_Next", 0xff9b},
|
||||||
|
{"KP_Page_Down", 0xff9b},
|
||||||
|
{"KP_End", 0xff9c},
|
||||||
|
{"KP_Begin", 0xff9d},
|
||||||
|
{"KP_Insert", 0xff9e},
|
||||||
|
{"KP_Delete", 0xff9f},
|
||||||
{"F1", 0xffbe}, /* XK_F1 */
|
{"F1", 0xffbe}, /* XK_F1 */
|
||||||
{"F2", 0xffbf}, /* XK_F2 */
|
{"F2", 0xffbf}, /* XK_F2 */
|
||||||
{"F3", 0xffc0}, /* XK_F3 */
|
{"F3", 0xffc0}, /* XK_F3 */
|
||||||
|
@ -258,6 +271,7 @@ static name2keysym_t name2keysym[]={
|
||||||
{"KP_8", 0xffb8}, /* XK_KP_8 */
|
{"KP_8", 0xffb8}, /* XK_KP_8 */
|
||||||
{"KP_9", 0xffb9}, /* XK_KP_9 */
|
{"KP_9", 0xffb9}, /* XK_KP_9 */
|
||||||
{"KP_Add", 0xffab}, /* XK_KP_Add */
|
{"KP_Add", 0xffab}, /* XK_KP_Add */
|
||||||
|
{"KP_Separator", 0xffac},/* XK_KP_Separator */
|
||||||
{"KP_Decimal", 0xffae}, /* XK_KP_Decimal */
|
{"KP_Decimal", 0xffae}, /* XK_KP_Decimal */
|
||||||
{"KP_Divide", 0xffaf}, /* XK_KP_Divide */
|
{"KP_Divide", 0xffaf}, /* XK_KP_Divide */
|
||||||
{"KP_Enter", 0xff8d}, /* XK_KP_Enter */
|
{"KP_Enter", 0xff8d}, /* XK_KP_Enter */
|
||||||
|
|
Loading…
Reference in New Issue