Some work on the gui console support for the text runtime configuration.

- Added gui console support to the rfb and vncsrv guis.
- Started preparing the legacy SDL gui for console support.
- TODO: The sdl and sdl2 guis need a special keyboard handling for shifted keys.
This commit is contained in:
Volker Ruppert 2017-01-05 18:20:47 +00:00
parent 48ae057bc9
commit ff776d7c3a
4 changed files with 695 additions and 611 deletions

View File

@ -10,8 +10,9 @@ Changes after 2.6.8 release:
- Added Android host platform support.
- GUI and display libraries
- X11: Show the runtime configuration in the Bochs VGA window instead of
console / xterm.
- Show the runtime configuration in the Bochs VGA window instead of
console / xterm (rfb, vncsrv and X11 guis).
- SDL2: Added get/set clipboard text support.
- CPU / CPUDB
- Bugfixes for CPU emulation correctness (critical bugfix for x86-64 and AVX opcodes emulation,

View File

@ -51,12 +51,17 @@ public:
bx_rfb_gui_c (void) {}
DECLARE_GUI_VIRTUAL_METHODS()
DECLARE_GUI_NEW_VIRTUAL_METHODS()
virtual void set_display_mode(disp_mode_t newmode);
void get_capabilities(Bit16u *xres, Bit16u *yres, Bit16u *bpp);
void statusbar_setitem_specific(int element, bx_bool active, bx_bool w);
virtual void set_mouse_mode_absxy(bx_bool mode);
#if BX_SHOW_IPS
void show_ips(Bit32u ips_count);
#endif
private:
void headerbar_click(int x);
void rfbMouseMove(int x, int y, int z, int bmask);
void rfbKeyPressed(Bit32u key, int press_release);
};
// declare one instance of the gui object and call macro to insert the
@ -200,8 +205,6 @@ void SendUpdate(int x, int y, int width, int height, Bit32u encoding);
void rfbAddUpdateRegion(unsigned x0, unsigned y0, unsigned w, unsigned h);
void rfbSetStatusText(int element, const char *text, bx_bool active, bx_bool w = 0);
static Bit32u convertStringToRfbKey(const char *string);
void rfbKeyPressed(Bit32u key, int press_release);
void rfbMouseMove(int x, int y, int z, int bmask);
#if BX_SHOW_IPS && defined(WIN32)
DWORD WINAPI rfbShowIPSthread(LPVOID);
#endif
@ -329,8 +332,8 @@ void bx_rfb_gui_c::specific_init(int argc, char **argv, unsigned headerbar_y)
#endif
new_gfx_api = 1;
dialog_caps = 0;
// console.present = 1;
dialog_caps = BX_GUI_DLG_RUNTIME;
console.present = 1;
}
// ::HANDLE_EVENTS()
@ -858,6 +861,468 @@ void bx_rfb_gui_c::show_ips(Bit32u ips_count)
}
#endif
void bx_rfb_gui_c::set_display_mode(disp_mode_t newmode)
{
// if no mode change, do nothing.
if (disp_mode == newmode) return;
// remember the display mode for next time
disp_mode = newmode;
if ((newmode == DISP_MODE_SIM) && console_running()) {
console_cleanup();
}
}
void bx_rfb_gui_c::headerbar_click(int x)
{
int xorigin;
for (unsigned i = 0; i < rfbHeaderbarBitmapCount; i++) {
if (rfbHeaderbarBitmaps[i].alignment == BX_GRAVITY_LEFT)
xorigin = rfbHeaderbarBitmaps[i].xorigin;
else
xorigin = rfbWindowX - rfbHeaderbarBitmaps[i].xorigin;
if ((x >= xorigin) &&
(x < (xorigin + int(rfbBitmaps[rfbHeaderbarBitmaps[i].index].xdim)))) {
if (console_running() && (i != power_hbar_id))
return;
rfbKeyboardEvents = 0;
bKeyboardInUse = 0;
rfbHeaderbarBitmaps[i].f();
return;
}
}
}
void bx_rfb_gui_c::rfbMouseMove(int x, int y, int z, int bmask)
{
static int oldx = -1;
static int oldy = -1;
int dx, dy;
if ((oldx == 1) && (oldy == -1)) {
oldx = x;
oldy = y;
return;
}
if (y > rfbHeaderbarY) {
if (console_running())
return;
if (rfbMouseModeAbsXY) {
if ((y >= rfbHeaderbarY) && (y < (int)(rfbDimensionY + rfbHeaderbarY))) {
dx = x * 0x7fff / rfbDimensionX;
dy = (y - rfbHeaderbarY) * 0x7fff / rfbDimensionY;
DEV_mouse_motion(dx, dy, z, bmask, 1);
}
} else {
DEV_mouse_motion(x - oldx, oldy - y, z, bmask, 0);
}
oldx = x;
oldy = y;
} else {
if (bmask == 1) {
headerbar_click(x);
}
}
}
// function to convert key names into rfb key values.
// This first try will be horribly inefficient, but it only has
// to be done while loading a keymap. Once the simulation starts,
// this function won't be called.
static Bit32u convertStringToRfbKey(const char *string)
{
rfbKeyTabEntry *ptr;
for (ptr = &rfb_keytable[0]; ptr->name != NULL; ptr++) {
if (!strcmp(string, ptr->name))
return ptr->value;
}
return BX_KEYMAP_UNKNOWN;
}
static Bit32u rfb_ascii_to_key_event[0x5f] = {
// !"#$%&'
BX_KEY_SPACE,
BX_KEY_1,
BX_KEY_SINGLE_QUOTE,
BX_KEY_3,
BX_KEY_4,
BX_KEY_5,
BX_KEY_7,
BX_KEY_SINGLE_QUOTE,
// ()*+,-./
BX_KEY_9,
BX_KEY_0,
BX_KEY_8,
BX_KEY_EQUALS,
BX_KEY_COMMA,
BX_KEY_MINUS,
BX_KEY_PERIOD,
BX_KEY_SLASH,
// 01234567
BX_KEY_0,
BX_KEY_1,
BX_KEY_2,
BX_KEY_3,
BX_KEY_4,
BX_KEY_5,
BX_KEY_6,
BX_KEY_7,
// 89:;<=>?
BX_KEY_8,
BX_KEY_9,
BX_KEY_SEMICOLON,
BX_KEY_SEMICOLON,
BX_KEY_COMMA,
BX_KEY_EQUALS,
BX_KEY_PERIOD,
BX_KEY_SLASH,
// @ABCDEFG
BX_KEY_2,
BX_KEY_A,
BX_KEY_B,
BX_KEY_C,
BX_KEY_D,
BX_KEY_E,
BX_KEY_F,
BX_KEY_G,
// HIJKLMNO
BX_KEY_H,
BX_KEY_I,
BX_KEY_J,
BX_KEY_K,
BX_KEY_L,
BX_KEY_M,
BX_KEY_N,
BX_KEY_O,
// PQRSTUVW
BX_KEY_P,
BX_KEY_Q,
BX_KEY_R,
BX_KEY_S,
BX_KEY_T,
BX_KEY_U,
BX_KEY_V,
BX_KEY_W,
// XYZ[\]^_
BX_KEY_X,
BX_KEY_Y,
BX_KEY_Z,
BX_KEY_LEFT_BRACKET,
BX_KEY_BACKSLASH,
BX_KEY_RIGHT_BRACKET,
BX_KEY_6,
BX_KEY_MINUS,
// `abcdefg
BX_KEY_GRAVE,
BX_KEY_A,
BX_KEY_B,
BX_KEY_C,
BX_KEY_D,
BX_KEY_E,
BX_KEY_F,
BX_KEY_G,
// hijklmno
BX_KEY_H,
BX_KEY_I,
BX_KEY_J,
BX_KEY_K,
BX_KEY_L,
BX_KEY_M,
BX_KEY_N,
BX_KEY_O,
// pqrstuvw
BX_KEY_P,
BX_KEY_Q,
BX_KEY_R,
BX_KEY_S,
BX_KEY_T,
BX_KEY_U,
BX_KEY_V,
BX_KEY_W,
// xyz{|}~
BX_KEY_X,
BX_KEY_Y,
BX_KEY_Z,
BX_KEY_LEFT_BRACKET,
BX_KEY_BACKSLASH,
BX_KEY_RIGHT_BRACKET,
BX_KEY_GRAVE
};
void bx_rfb_gui_c::rfbKeyPressed(Bit32u key, int press_release)
{
Bit32u key_event;
if (console_running() && press_release) {
if (((key >= XK_space) && (key <= XK_asciitilde)) ||
(key == XK_Return) || (key == XK_BackSpace)) {
console_key_enq((Bit8u)(key & 0xff));
}
return;
}
if (!SIM->get_param_bool(BXPN_KBD_USEMAPPING)->get()) {
if ((key >= XK_space) && (key <= XK_asciitilde)) {
key_event = rfb_ascii_to_key_event[key - XK_space];
} else {
switch (key) {
case XK_KP_1:
#ifdef XK_KP_End
case XK_KP_End:
#endif
key_event = BX_KEY_KP_END;
break;
case XK_KP_2:
#ifdef XK_KP_Down
case XK_KP_Down:
#endif
key_event = BX_KEY_KP_DOWN;
break;
case XK_KP_3:
#ifdef XK_KP_Page_Down
case XK_KP_Page_Down:
#endif
key_event = BX_KEY_KP_PAGE_DOWN;
break;
case XK_KP_4:
#ifdef XK_KP_Left
case XK_KP_Left:
#endif
key_event = BX_KEY_KP_LEFT;
break;
case XK_KP_5:
#ifdef XK_KP_Begin
case XK_KP_Begin:
#endif
key_event = BX_KEY_KP_5;
break;
case XK_KP_6:
#ifdef XK_KP_Right
case XK_KP_Right:
#endif
key_event = BX_KEY_KP_RIGHT;
break;
case XK_KP_7:
#ifdef XK_KP_Home
case XK_KP_Home:
#endif
key_event = BX_KEY_KP_HOME;
break;
case XK_KP_8:
#ifdef XK_KP_Up
case XK_KP_Up:
#endif
key_event = BX_KEY_KP_UP;
break;
case XK_KP_9:
#ifdef XK_KP_Page_Up
case XK_KP_Page_Up:
#endif
key_event = BX_KEY_KP_PAGE_UP;
break;
case XK_KP_0:
#ifdef XK_KP_Insert
case XK_KP_Insert:
#endif
key_event = BX_KEY_KP_INSERT;
break;
case XK_KP_Decimal:
#ifdef XK_KP_Delete
case XK_KP_Delete:
#endif
key_event = BX_KEY_KP_DELETE;
break;
#ifdef XK_KP_Enter
case XK_KP_Enter:
key_event = BX_KEY_KP_ENTER;
break;
#endif
case XK_KP_Subtract:
key_event = BX_KEY_KP_SUBTRACT;
break;
case XK_KP_Add:
key_event = BX_KEY_KP_ADD;
break;
case XK_KP_Multiply:
key_event = BX_KEY_KP_MULTIPLY;
break;
case XK_KP_Divide:
key_event = BX_KEY_KP_DIVIDE;
break;
case XK_Up:
key_event = BX_KEY_UP;
break;
case XK_Down:
key_event = BX_KEY_DOWN;
break;
case XK_Left:
key_event = BX_KEY_LEFT;
break;
case XK_Right:
key_event = BX_KEY_RIGHT;
break;
case XK_Delete:
key_event = BX_KEY_DELETE;
break;
case XK_BackSpace:
key_event = BX_KEY_BACKSPACE;
break;
case XK_Tab:
key_event = BX_KEY_TAB;
break;
#ifdef XK_ISO_Left_Tab
case XK_ISO_Left_Tab:
key_event = BX_KEY_TAB;
break;
#endif
case XK_Return:
key_event = BX_KEY_ENTER;
break;
case XK_Escape:
key_event = BX_KEY_ESC;
break;
case XK_F1:
key_event = BX_KEY_F1;
break;
case XK_F2:
key_event = BX_KEY_F2;
break;
case XK_F3:
key_event = BX_KEY_F3;
break;
case XK_F4:
key_event = BX_KEY_F4;
break;
case XK_F5:
key_event = BX_KEY_F5;
break;
case XK_F6:
key_event = BX_KEY_F6;
break;
case XK_F7:
key_event = BX_KEY_F7;
break;
case XK_F8:
key_event = BX_KEY_F8;
break;
case XK_F9:
key_event = BX_KEY_F9;
break;
case XK_F10:
key_event = BX_KEY_F10;
break;
case XK_F11:
key_event = BX_KEY_F11;
break;
case XK_F12:
key_event = BX_KEY_F12;
break;
case XK_Control_L:
key_event = BX_KEY_CTRL_L;
break;
#ifdef XK_Control_R
case XK_Control_R:
key_event = BX_KEY_CTRL_R;
break;
#endif
case XK_Shift_L:
key_event = BX_KEY_SHIFT_L;
break;
case XK_Shift_R:
key_event = BX_KEY_SHIFT_R;
break;
case XK_Alt_L:
key_event = BX_KEY_ALT_L;
break;
#ifdef XK_Alt_R
case XK_Alt_R:
key_event = BX_KEY_ALT_R;
break;
#endif
case XK_Caps_Lock:
key_event = BX_KEY_CAPS_LOCK;
break;
case XK_Num_Lock:
key_event = BX_KEY_NUM_LOCK;
break;
#ifdef XK_Scroll_Lock
case XK_Scroll_Lock:
key_event = BX_KEY_SCRL_LOCK;
break;
#endif
#ifdef XK_Print
case XK_Print:
key_event = BX_KEY_PRINT;
break;
#endif
#ifdef XK_Pause
case XK_Pause:
key_event = BX_KEY_PAUSE;
break;
#endif
case XK_Insert:
key_event = BX_KEY_INSERT;
break;
case XK_Home:
key_event = BX_KEY_HOME;
break;
case XK_End:
key_event = BX_KEY_END;
break;
case XK_Page_Up:
key_event = BX_KEY_PAGE_UP;
break;
case XK_Page_Down:
key_event = BX_KEY_PAGE_DOWN;
break;
default:
BX_ERROR(("rfbKeyPress(): key %04x unhandled!", key));
return;
}
}
} else {
BXKeyEntry *entry = bx_keymap.findHostKey(key);
if (!entry) {
BX_ERROR(("rfbKeyPressed(): key %x unhandled!", (unsigned) key));
return;
}
key_event = entry->baseKey;
}
if (!press_release)
key_event |= BX_KEY_RELEASED;
DEV_kbd_gen_scancode(key_event);
}
// RFB specific functions
#ifdef BX_RFB_WIN32
@ -1405,439 +1870,6 @@ void rfbSetStatusText(int element, const char *text, bx_bool active, bx_bool w)
rfbAddUpdateRegion(xleft, rfbWindowY - rfbStatusbarY + 1, xsize, rfbStatusbarY - 2);
}
// function to convert key names into rfb key values.
// This first try will be horribly inefficient, but it only has
// to be done while loading a keymap. Once the simulation starts,
// this function won't be called.
static Bit32u convertStringToRfbKey(const char *string)
{
rfbKeyTabEntry *ptr;
for (ptr = &rfb_keytable[0]; ptr->name != NULL; ptr++) {
if (!strcmp(string, ptr->name))
return ptr->value;
}
return BX_KEYMAP_UNKNOWN;
}
static Bit32u rfb_ascii_to_key_event[0x5f] = {
// !"#$%&'
BX_KEY_SPACE,
BX_KEY_1,
BX_KEY_SINGLE_QUOTE,
BX_KEY_3,
BX_KEY_4,
BX_KEY_5,
BX_KEY_7,
BX_KEY_SINGLE_QUOTE,
// ()*+,-./
BX_KEY_9,
BX_KEY_0,
BX_KEY_8,
BX_KEY_EQUALS,
BX_KEY_COMMA,
BX_KEY_MINUS,
BX_KEY_PERIOD,
BX_KEY_SLASH,
// 01234567
BX_KEY_0,
BX_KEY_1,
BX_KEY_2,
BX_KEY_3,
BX_KEY_4,
BX_KEY_5,
BX_KEY_6,
BX_KEY_7,
// 89:;<=>?
BX_KEY_8,
BX_KEY_9,
BX_KEY_SEMICOLON,
BX_KEY_SEMICOLON,
BX_KEY_COMMA,
BX_KEY_EQUALS,
BX_KEY_PERIOD,
BX_KEY_SLASH,
// @ABCDEFG
BX_KEY_2,
BX_KEY_A,
BX_KEY_B,
BX_KEY_C,
BX_KEY_D,
BX_KEY_E,
BX_KEY_F,
BX_KEY_G,
// HIJKLMNO
BX_KEY_H,
BX_KEY_I,
BX_KEY_J,
BX_KEY_K,
BX_KEY_L,
BX_KEY_M,
BX_KEY_N,
BX_KEY_O,
// PQRSTUVW
BX_KEY_P,
BX_KEY_Q,
BX_KEY_R,
BX_KEY_S,
BX_KEY_T,
BX_KEY_U,
BX_KEY_V,
BX_KEY_W,
// XYZ[\]^_
BX_KEY_X,
BX_KEY_Y,
BX_KEY_Z,
BX_KEY_LEFT_BRACKET,
BX_KEY_BACKSLASH,
BX_KEY_RIGHT_BRACKET,
BX_KEY_6,
BX_KEY_MINUS,
// `abcdefg
BX_KEY_GRAVE,
BX_KEY_A,
BX_KEY_B,
BX_KEY_C,
BX_KEY_D,
BX_KEY_E,
BX_KEY_F,
BX_KEY_G,
// hijklmno
BX_KEY_H,
BX_KEY_I,
BX_KEY_J,
BX_KEY_K,
BX_KEY_L,
BX_KEY_M,
BX_KEY_N,
BX_KEY_O,
// pqrstuvw
BX_KEY_P,
BX_KEY_Q,
BX_KEY_R,
BX_KEY_S,
BX_KEY_T,
BX_KEY_U,
BX_KEY_V,
BX_KEY_W,
// xyz{|}~
BX_KEY_X,
BX_KEY_Y,
BX_KEY_Z,
BX_KEY_LEFT_BRACKET,
BX_KEY_BACKSLASH,
BX_KEY_RIGHT_BRACKET,
BX_KEY_GRAVE
};
void rfbKeyPressed(Bit32u key, int press_release)
{
Bit32u key_event;
if (!SIM->get_param_bool(BXPN_KBD_USEMAPPING)->get()) {
if ((key >= XK_space) && (key <= XK_asciitilde)) {
key_event = rfb_ascii_to_key_event[key - XK_space];
} else {
switch (key) {
case XK_KP_1:
#ifdef XK_KP_End
case XK_KP_End:
#endif
key_event = BX_KEY_KP_END;
break;
case XK_KP_2:
#ifdef XK_KP_Down
case XK_KP_Down:
#endif
key_event = BX_KEY_KP_DOWN;
break;
case XK_KP_3:
#ifdef XK_KP_Page_Down
case XK_KP_Page_Down:
#endif
key_event = BX_KEY_KP_PAGE_DOWN;
break;
case XK_KP_4:
#ifdef XK_KP_Left
case XK_KP_Left:
#endif
key_event = BX_KEY_KP_LEFT;
break;
case XK_KP_5:
#ifdef XK_KP_Begin
case XK_KP_Begin:
#endif
key_event = BX_KEY_KP_5;
break;
case XK_KP_6:
#ifdef XK_KP_Right
case XK_KP_Right:
#endif
key_event = BX_KEY_KP_RIGHT;
break;
case XK_KP_7:
#ifdef XK_KP_Home
case XK_KP_Home:
#endif
key_event = BX_KEY_KP_HOME;
break;
case XK_KP_8:
#ifdef XK_KP_Up
case XK_KP_Up:
#endif
key_event = BX_KEY_KP_UP;
break;
case XK_KP_9:
#ifdef XK_KP_Page_Up
case XK_KP_Page_Up:
#endif
key_event = BX_KEY_KP_PAGE_UP;
break;
case XK_KP_0:
#ifdef XK_KP_Insert
case XK_KP_Insert:
#endif
key_event = BX_KEY_KP_INSERT;
break;
case XK_KP_Decimal:
#ifdef XK_KP_Delete
case XK_KP_Delete:
#endif
key_event = BX_KEY_KP_DELETE;
break;
#ifdef XK_KP_Enter
case XK_KP_Enter:
key_event = BX_KEY_KP_ENTER;
break;
#endif
case XK_KP_Subtract:
key_event = BX_KEY_KP_SUBTRACT;
break;
case XK_KP_Add:
key_event = BX_KEY_KP_ADD;
break;
case XK_KP_Multiply:
key_event = BX_KEY_KP_MULTIPLY;
break;
case XK_KP_Divide:
key_event = BX_KEY_KP_DIVIDE;
break;
case XK_Up:
key_event = BX_KEY_UP;
break;
case XK_Down:
key_event = BX_KEY_DOWN;
break;
case XK_Left:
key_event = BX_KEY_LEFT;
break;
case XK_Right:
key_event = BX_KEY_RIGHT;
break;
case XK_Delete:
key_event = BX_KEY_DELETE;
break;
case XK_BackSpace:
key_event = BX_KEY_BACKSPACE;
break;
case XK_Tab:
key_event = BX_KEY_TAB;
break;
#ifdef XK_ISO_Left_Tab
case XK_ISO_Left_Tab:
key_event = BX_KEY_TAB;
break;
#endif
case XK_Return:
key_event = BX_KEY_ENTER;
break;
case XK_Escape:
key_event = BX_KEY_ESC;
break;
case XK_F1:
key_event = BX_KEY_F1;
break;
case XK_F2:
key_event = BX_KEY_F2;
break;
case XK_F3:
key_event = BX_KEY_F3;
break;
case XK_F4:
key_event = BX_KEY_F4;
break;
case XK_F5:
key_event = BX_KEY_F5;
break;
case XK_F6:
key_event = BX_KEY_F6;
break;
case XK_F7:
key_event = BX_KEY_F7;
break;
case XK_F8:
key_event = BX_KEY_F8;
break;
case XK_F9:
key_event = BX_KEY_F9;
break;
case XK_F10:
key_event = BX_KEY_F10;
break;
case XK_F11:
key_event = BX_KEY_F11;
break;
case XK_F12:
key_event = BX_KEY_F12;
break;
case XK_Control_L:
key_event = BX_KEY_CTRL_L;
break;
#ifdef XK_Control_R
case XK_Control_R:
key_event = BX_KEY_CTRL_R;
break;
#endif
case XK_Shift_L:
key_event = BX_KEY_SHIFT_L;
break;
case XK_Shift_R:
key_event = BX_KEY_SHIFT_R;
break;
case XK_Alt_L:
key_event = BX_KEY_ALT_L;
break;
#ifdef XK_Alt_R
case XK_Alt_R:
key_event = BX_KEY_ALT_R;
break;
#endif
case XK_Caps_Lock:
key_event = BX_KEY_CAPS_LOCK;
break;
case XK_Num_Lock:
key_event = BX_KEY_NUM_LOCK;
break;
#ifdef XK_Scroll_Lock
case XK_Scroll_Lock:
key_event = BX_KEY_SCRL_LOCK;
break;
#endif
#ifdef XK_Print
case XK_Print:
key_event = BX_KEY_PRINT;
break;
#endif
#ifdef XK_Pause
case XK_Pause:
key_event = BX_KEY_PAUSE;
break;
#endif
case XK_Insert:
key_event = BX_KEY_INSERT;
break;
case XK_Home:
key_event = BX_KEY_HOME;
break;
case XK_End:
key_event = BX_KEY_END;
break;
case XK_Page_Up:
key_event = BX_KEY_PAGE_UP;
break;
case XK_Page_Down:
key_event = BX_KEY_PAGE_DOWN;
break;
default:
BX_ERROR(("rfbKeyPress(): key %04x unhandled!", key));
return;
}
}
} else {
BXKeyEntry *entry = bx_keymap.findHostKey(key);
if (!entry) {
BX_ERROR(("rfbKeyPressed(): key %x unhandled!", (unsigned) key));
return;
}
key_event = entry->baseKey;
}
if (!press_release)
key_event |= BX_KEY_RELEASED;
DEV_kbd_gen_scancode(key_event);
}
void rfbMouseMove(int x, int y, int z, int bmask)
{
static int oldx = -1;
static int oldy = -1;
int dx, dy, xorigin;
if ((oldx == 1) && (oldy == -1)) {
oldx = x;
oldy = y;
return;
}
if (y > rfbHeaderbarY) {
if (rfbMouseModeAbsXY) {
if ((y >= rfbHeaderbarY) && (y < (int)(rfbDimensionY + rfbHeaderbarY))) {
dx = x * 0x7fff / rfbDimensionX;
dy = (y - rfbHeaderbarY) * 0x7fff / rfbDimensionY;
DEV_mouse_motion(dx, dy, z, bmask, 1);
}
} else {
DEV_mouse_motion(x - oldx, oldy - y, z, bmask, 0);
}
oldx = x;
oldy = y;
} else {
if (bmask == 1) {
for (unsigned i = 0; i < rfbHeaderbarBitmapCount; i++) {
if (rfbHeaderbarBitmaps[i].alignment == BX_GRAVITY_LEFT)
xorigin = rfbHeaderbarBitmaps[i].xorigin;
else
xorigin = rfbWindowX - rfbHeaderbarBitmaps[i].xorigin;
if ((x >= xorigin) &&
(x < (xorigin + int(rfbBitmaps[rfbHeaderbarBitmaps[i].index].xdim)))) {
rfbKeyboardEvents = 0;
bKeyboardInUse = 0;
rfbHeaderbarBitmaps[i].f();
return;
}
}
}
}
}
#if BX_SHOW_IPS && defined(WIN32)
VOID CALLBACK IPSTimerProc(HWND hWnd, UINT nMsg, UINT_PTR nIDEvent, DWORD dwTime)
{

View File

@ -54,6 +54,8 @@ public:
#if BX_SHOW_IPS
virtual void show_ips(Bit32u ips_count);
#endif
private:
void headerbar_click(int x);
};
// declare one instance of the gui object and call macro to insert the
@ -127,24 +129,6 @@ static char sdl_ips_text[20];
#endif
static void headerbar_click(int x)
{
int xdim,xorigin;
for (unsigned i=0; i<bx_headerbar_entries; i++) {
xdim = sdl_bitmaps[hb_entry[i].bmp_id]->src.w;
if (hb_entry[i].alignment == BX_GRAVITY_LEFT)
xorigin = sdl_bitmaps[hb_entry[i].bmp_id]->dst.x;
else
xorigin = res_x - sdl_bitmaps[hb_entry[i].bmp_id]->dst.x;
if ((x>=xorigin) && (x<(xorigin+xdim))) {
hb_entry[i].f();
return;
}
}
}
static void sdl_set_status_text(int element, const char *text, bx_bool active, bx_bool w = 0)
{
Uint32 *buf, *buf_row;
@ -866,7 +850,7 @@ void bx_sdl_gui_c::handle_events(void)
break;
case SDL_MOUSEMOTION:
if (!sdl_grab) {
if (!sdl_grab || console_running()) {
break;
}
if (just_warped
@ -935,6 +919,9 @@ void bx_sdl_gui_c::handle_events(void)
&& (sdl_fullscreen_toggle == 0)) {
mouse_toggle_check(BX_MT_MBUTTON, 0);
}
if (console_running()) {
break;
}
// figure out mouse state
new_mousex = (int)(sdl_event.button.x);
new_mousey = (int)(sdl_event.button.y);
@ -965,6 +952,14 @@ void bx_sdl_gui_c::handle_events(void)
break;
case SDL_KEYDOWN:
if (console_running()) {
SDLKey keysym = sdl_event.key.keysym.sym;
if (((keysym >= SDLK_SPACE) && (keysym < SDLK_DELETE)) ||
(keysym == SDLK_RETURN) || (keysym == SDLK_BACKSPACE)) {
// TODO
}
break;
}
// mouse capture toggle-check
if (sdl_fullscreen_toggle == 0) {
if ((sdl_event.key.keysym.sym == SDLK_LCTRL) ||
@ -1428,6 +1423,26 @@ void bx_sdl_gui_c::mouse_enabled_changed_specific (bx_bool val)
}
void bx_sdl_gui_c::headerbar_click(int x)
{
int xdim,xorigin;
for (unsigned i=0; i<bx_headerbar_entries; i++) {
xdim = sdl_bitmaps[hb_entry[i].bmp_id]->src.w;
if (hb_entry[i].alignment == BX_GRAVITY_LEFT)
xorigin = sdl_bitmaps[hb_entry[i].bmp_id]->dst.x;
else
xorigin = res_x - sdl_bitmaps[hb_entry[i].bmp_id]->dst.x;
if ((x>=xorigin) && (x<(xorigin+xdim))) {
if (console_running() && (i != power_hbar_id))
return;
hb_entry[i].f();
return;
}
}
}
void bx_sdl_gui_c::exit(void)
{
if (sdl_screen)
@ -1520,6 +1535,10 @@ void bx_sdl_gui_c::set_display_mode(disp_mode_t newmode)
if (disp_mode == newmode) return;
// remember the display mode for next time
disp_mode = newmode;
if ((newmode == DISP_MODE_SIM) && console_running()) {
console_cleanup();
return;
}
// If fullscreen mode is on, we must switch back to windowed mode if
// the user needs to see the text console.
if (sdl_fullscreen_toggle) {

View File

@ -64,6 +64,7 @@ public:
bx_vncsrv_gui_c(void) : screen(NULL) {}
DECLARE_GUI_VIRTUAL_METHODS()
DECLARE_GUI_NEW_VIRTUAL_METHODS()
virtual void set_display_mode(disp_mode_t newmode);
void get_capabilities(Bit16u *xres, Bit16u *yres, Bit16u *bpp);
void statusbar_setitem_specific(int element, bx_bool active, bx_bool w);
virtual void set_mouse_mode_absxy(bx_bool mode);
@ -71,6 +72,10 @@ public:
void show_ips(Bit32u ips_count);
#endif
rfbScreenInfoPtr screen;
private:
void headerbar_click(int x);
void vncMouseMove(int x, int y, int z, int bmask);
void vncKeyPressed(Bit32u key, int press_release);
};
// declare one instance of the gui object and call macro to insert the
@ -206,8 +211,6 @@ void UpdateScreen(rfbPixel *newBits, int x, int y, int width, int height);
void SendUpdate(int x, int y, int width, int height);
void vncSetStatusText(int element, const char *text, bx_bool active, bx_bool w = 0);
static Bit32u convertStringToRfbKey(const char *string);
void vncKeyPressed(Bit32u key, int press_release);
void vncMouseMove(int x, int y, int z, int bmask);
void clientgone(rfbClientPtr cl);
enum rfbNewClientAction newclient(rfbClientPtr cl);
@ -343,8 +346,8 @@ void bx_vncsrv_gui_c::specific_init(int argc, char **argv, unsigned headerbar_y)
#endif
new_gfx_api = 1;
dialog_caps = 0;
// console.present = 1;
dialog_caps = BX_GUI_DLG_RUNTIME;
console.present = 1;
}
// ::HANDLE_EVENTS()
@ -882,135 +885,68 @@ void bx_vncsrv_gui_c::show_ips(Bit32u ips_count)
}
#endif
// VNCSRV specific functions
BX_THREAD_FUNC(vncServerThreadInit, indata)
void bx_vncsrv_gui_c::set_display_mode(disp_mode_t newmode)
{
/* this is the blocking event loop, i.e. it never returns */
/* 40000 are the microseconds to wait on select(), i.e. 0.04 seconds*/
rfbRunEventLoop(theGui->screen, 40000, FALSE);
free(theGui->screen->frameBuffer);
rfbScreenCleanup(theGui->screen);
rfbServerDown = true;
BX_THREAD_EXIT;
}
void vncStartThread()
{
BX_THREAD_ID(threadID);
BX_THREAD_CREATE(vncServerThreadInit, NULL, threadID);
}
void DrawBitmap(int x, int y, int width, int height, char *bmap,
rfbPixel fgcolor, rfbPixel bgcolor)
{
rfbPixel *newBits;
newBits = (rfbPixel *) malloc(width * height * sizeof(rfbPixel));
memset(newBits, 0, (width * height * sizeof(rfbPixel)));
for (int i = 0; i < (width * height) / 8; i++) {
newBits[i * 8 + 0] = (bmap[i] & 0x01) ? fgcolor : bgcolor;
newBits[i * 8 + 1] = (bmap[i] & 0x02) ? fgcolor : bgcolor;
newBits[i * 8 + 2] = (bmap[i] & 0x04) ? fgcolor : bgcolor;
newBits[i * 8 + 3] = (bmap[i] & 0x08) ? fgcolor : bgcolor;
newBits[i * 8 + 4] = (bmap[i] & 0x10) ? fgcolor : bgcolor;
newBits[i * 8 + 5] = (bmap[i] & 0x20) ? fgcolor : bgcolor;
newBits[i * 8 + 6] = (bmap[i] & 0x40) ? fgcolor : bgcolor;
newBits[i * 8 + 7] = (bmap[i] & 0x80) ? fgcolor : bgcolor;
// if no mode change, do nothing.
if (disp_mode == newmode) return;
// remember the display mode for next time
disp_mode = newmode;
if ((newmode == DISP_MODE_SIM) && console_running()) {
console_cleanup();
}
UpdateScreen(newBits, x, y, width, height);
free(newBits);
}
void DrawChar(int x, int y, int width, int height, int fonty, char *bmap,
rfbPixel fgcolor, rfbPixel bgcolor, bx_bool gfxchar)
void bx_vncsrv_gui_c::headerbar_click(int x)
{
static rfbPixel newBits[18 * 32];
unsigned char mask;
int bytes = width * height;
bx_bool dwidth = (width > 9);
int xorigin;
for (int i = 0; i < bytes; i += width) {
mask = 0x80;
for (int j = 0; j < width; j++) {
if (mask > 0) {
newBits[i + j] = (bmap[fonty] & mask) ? fgcolor : bgcolor;
} else {
if (gfxchar) {
newBits[i + j] = (bmap[fonty] & 0x01) ? fgcolor : bgcolor;
} else {
newBits[i + j] = bgcolor;
}
}
if (!dwidth || (j & 1)) mask >>= 1;
for (unsigned i = 0; i < rfbHeaderbarBitmapCount; i++) {
if (rfbHeaderbarBitmaps[i].alignment == BX_GRAVITY_LEFT)
xorigin = rfbHeaderbarBitmaps[i].xorigin;
else
xorigin = rfbWindowX - rfbHeaderbarBitmaps[i].xorigin;
if ((x >= xorigin) &&
(x < (xorigin + int(rfbBitmaps[rfbHeaderbarBitmaps[i].index].xdim)))) {
if (console_running() && (i != power_hbar_id))
return;
rfbKeyboardEvents = 0;
BX_UNLOCK(bKeyboardInUse);
rfbHeaderbarBitmaps[i].f();
return;
}
fonty++;
}
UpdateScreen(newBits, x, y, width, height);
}
void UpdateScreen(rfbPixel *newBits, int x, int y, int width, int height)
void bx_vncsrv_gui_c::vncMouseMove(int x, int y, int z, int bmask)
{
int i, x0, y0;
x0 = x;
y0 = y;
if ((unsigned)(x + width - 1) >= rfbWindowX) {
width = rfbWindowX - x + 1;
}
if ((unsigned)(y + height - 1) >= rfbWindowY) {
height = rfbWindowY - y + 1;
}
for (i = 0; i < height; i++) {
memcpy(&(theGui->screen->frameBuffer[y * rfbWindowX * sizeof(rfbPixel)
+ x * sizeof(rfbPixel)]),
&newBits[i * width], width * sizeof(rfbPixel));
y++;
}
SendUpdate(x0, y0, width, height);
}
static int oldx = -1;
static int oldy = -1;
int dx, dy;
void SendUpdate(int x, int y, int width, int height)
{
rfbMarkRectAsModified(theGui->screen, x, y, x + width, y + height);
}
void vncSetStatusText(int element, const char *text, bx_bool active, bx_bool w)
{
char *newBits;
unsigned xleft, xsize, i, len;
rfbStatusitemActive[element] = active;
xleft = rfbStatusitemPos[element] + 2;
xsize = rfbStatusitemPos[element + 1] - xleft - 1;
newBits = (char *) malloc(((xsize / 8) + 1) * (rfbStatusbarY - 2));
memset(newBits, 0, ((xsize / 8) + 1) * (rfbStatusbarY - 2));
for (i = 0; i < (rfbStatusbarY - 2); i++) {
newBits[((xsize / 8) + 1) * i] = 0;
if ((oldx == 1) && (oldy == -1)) {
oldx = x;
oldy = y;
return;
}
rfbPixel fgcolor = active ? headerbar_fg : status_gray_text;
rfbPixel bgcolor = 0;
if (element > 0) {
bgcolor = active ? (w ? status_led_red : status_led_green) : headerbar_bg;
if (y > rfbHeaderbarY) {
if (console_running())
return;
if (rfbMouseModeAbsXY) {
if ((y >= rfbHeaderbarY) && (y < (int)(rfbDimensionY + rfbHeaderbarY))) {
dx = x * 0x7fff / rfbDimensionX;
dy = (y - rfbHeaderbarY) * 0x7fff / rfbDimensionY;
DEV_mouse_motion(dx, dy, z, bmask, 1);
}
} else {
DEV_mouse_motion(x - oldx, oldy - y, z, bmask, 0);
}
oldx = x;
oldy = y;
} else {
bgcolor = headerbar_bg;
if (bmask == 1) {
headerbar_click(x);
}
}
DrawBitmap(xleft, rfbWindowY - rfbStatusbarY + 1, xsize, rfbStatusbarY - 2,
newBits, fgcolor, bgcolor);
free(newBits);
len = ((element > 0) && (strlen(text) > 4)) ? 4 : strlen(text);
for (i = 0; i < len; i++) {
DrawChar(xleft + i * 8 + 2, rfbWindowY - rfbStatusbarY + 5, 8, 8, 0,
(char *) &sdl_font8x8[(unsigned) text[i]][0], fgcolor, bgcolor, 0);
}
rfbMarkRectAsModified(theGui->screen, xleft, rfbWindowY - rfbStatusbarY + 1,
xleft + xsize, rfbWindowY - 2);
}
// function to convert key names into rfb key values.
@ -1077,10 +1013,17 @@ static Bit32u rfb_ascii_to_key_event[0x5f] = {
BX_KEY_RIGHT_BRACKET, BX_KEY_GRAVE
};
void vncKeyPressed(Bit32u key, int press_release)
void bx_vncsrv_gui_c::vncKeyPressed(Bit32u key, int press_release)
{
Bit32u key_event;
if (console_running() && press_release) {
if (((key >= XK_space) && (key <= XK_asciitilde)) ||
(key == XK_Return) || (key == XK_BackSpace)) {
console_key_enq((Bit8u)(key & 0xff));
}
return;
}
if (!SIM->get_param_bool(BXPN_KBD_USEMAPPING)->get()) {
if ((key >= XK_space) && (key <= XK_asciitilde)) {
key_event = rfb_ascii_to_key_event[key - XK_space];
@ -1331,46 +1274,135 @@ void vncKeyPressed(Bit32u key, int press_release)
DEV_kbd_gen_scancode(key_event);
}
void vncMouseMove(int x, int y, int z, int bmask)
{
static int oldx = -1;
static int oldy = -1;
int dx, dy, xorigin;
// VNCSRV specific functions
if ((oldx == 1) && (oldy == -1)) {
oldx = x;
oldy = y;
return;
BX_THREAD_FUNC(vncServerThreadInit, indata)
{
/* this is the blocking event loop, i.e. it never returns */
/* 40000 are the microseconds to wait on select(), i.e. 0.04 seconds*/
rfbRunEventLoop(theGui->screen, 40000, FALSE);
free(theGui->screen->frameBuffer);
rfbScreenCleanup(theGui->screen);
rfbServerDown = true;
BX_THREAD_EXIT;
}
void vncStartThread()
{
BX_THREAD_ID(threadID);
BX_THREAD_CREATE(vncServerThreadInit, NULL, threadID);
}
void DrawBitmap(int x, int y, int width, int height, char *bmap,
rfbPixel fgcolor, rfbPixel bgcolor)
{
rfbPixel *newBits;
newBits = (rfbPixel *) malloc(width * height * sizeof(rfbPixel));
memset(newBits, 0, (width * height * sizeof(rfbPixel)));
for (int i = 0; i < (width * height) / 8; i++) {
newBits[i * 8 + 0] = (bmap[i] & 0x01) ? fgcolor : bgcolor;
newBits[i * 8 + 1] = (bmap[i] & 0x02) ? fgcolor : bgcolor;
newBits[i * 8 + 2] = (bmap[i] & 0x04) ? fgcolor : bgcolor;
newBits[i * 8 + 3] = (bmap[i] & 0x08) ? fgcolor : bgcolor;
newBits[i * 8 + 4] = (bmap[i] & 0x10) ? fgcolor : bgcolor;
newBits[i * 8 + 5] = (bmap[i] & 0x20) ? fgcolor : bgcolor;
newBits[i * 8 + 6] = (bmap[i] & 0x40) ? fgcolor : bgcolor;
newBits[i * 8 + 7] = (bmap[i] & 0x80) ? fgcolor : bgcolor;
}
if (y > rfbHeaderbarY) {
if (rfbMouseModeAbsXY) {
if ((y >= rfbHeaderbarY) && (y < (int)(rfbDimensionY + rfbHeaderbarY))) {
dx = x * 0x7fff / rfbDimensionX;
dy = (y - rfbHeaderbarY) * 0x7fff / rfbDimensionY;
DEV_mouse_motion(dx, dy, z, bmask, 1);
}
} else {
DEV_mouse_motion(x - oldx, oldy - y, z, bmask, 0);
}
oldx = x;
oldy = y;
} else {
if (bmask == 1) {
for (unsigned i = 0; i < rfbHeaderbarBitmapCount; i++) {
if (rfbHeaderbarBitmaps[i].alignment == BX_GRAVITY_LEFT)
xorigin = rfbHeaderbarBitmaps[i].xorigin;
else
xorigin = rfbWindowX - rfbHeaderbarBitmaps[i].xorigin;
if ((x >= xorigin) &&
(x < (xorigin + int(rfbBitmaps[rfbHeaderbarBitmaps[i].index].xdim)))) {
rfbKeyboardEvents = 0;
BX_UNLOCK(bKeyboardInUse);
rfbHeaderbarBitmaps[i].f();
return;
UpdateScreen(newBits, x, y, width, height);
free(newBits);
}
void DrawChar(int x, int y, int width, int height, int fonty, char *bmap,
rfbPixel fgcolor, rfbPixel bgcolor, bx_bool gfxchar)
{
static rfbPixel newBits[18 * 32];
unsigned char mask;
int bytes = width * height;
bx_bool dwidth = (width > 9);
for (int i = 0; i < bytes; i += width) {
mask = 0x80;
for (int j = 0; j < width; j++) {
if (mask > 0) {
newBits[i + j] = (bmap[fonty] & mask) ? fgcolor : bgcolor;
} else {
if (gfxchar) {
newBits[i + j] = (bmap[fonty] & 0x01) ? fgcolor : bgcolor;
} else {
newBits[i + j] = bgcolor;
}
}
if (!dwidth || (j & 1)) mask >>= 1;
}
fonty++;
}
UpdateScreen(newBits, x, y, width, height);
}
void UpdateScreen(rfbPixel *newBits, int x, int y, int width, int height)
{
int i, x0, y0;
x0 = x;
y0 = y;
if ((unsigned)(x + width - 1) >= rfbWindowX) {
width = rfbWindowX - x + 1;
}
if ((unsigned)(y + height - 1) >= rfbWindowY) {
height = rfbWindowY - y + 1;
}
for (i = 0; i < height; i++) {
memcpy(&(theGui->screen->frameBuffer[y * rfbWindowX * sizeof(rfbPixel)
+ x * sizeof(rfbPixel)]),
&newBits[i * width], width * sizeof(rfbPixel));
y++;
}
SendUpdate(x0, y0, width, height);
}
void SendUpdate(int x, int y, int width, int height)
{
rfbMarkRectAsModified(theGui->screen, x, y, x + width, y + height);
}
void vncSetStatusText(int element, const char *text, bx_bool active, bx_bool w)
{
char *newBits;
unsigned xleft, xsize, i, len;
rfbStatusitemActive[element] = active;
xleft = rfbStatusitemPos[element] + 2;
xsize = rfbStatusitemPos[element + 1] - xleft - 1;
newBits = (char *) malloc(((xsize / 8) + 1) * (rfbStatusbarY - 2));
memset(newBits, 0, ((xsize / 8) + 1) * (rfbStatusbarY - 2));
for (i = 0; i < (rfbStatusbarY - 2); i++) {
newBits[((xsize / 8) + 1) * i] = 0;
}
rfbPixel fgcolor = active ? headerbar_fg : status_gray_text;
rfbPixel bgcolor = 0;
if (element > 0) {
bgcolor = active ? (w ? status_led_red : status_led_green) : headerbar_bg;
} else {
bgcolor = headerbar_bg;
}
DrawBitmap(xleft, rfbWindowY - rfbStatusbarY + 1, xsize, rfbStatusbarY - 2,
newBits, fgcolor, bgcolor);
free(newBits);
len = ((element > 0) && (strlen(text) > 4)) ? 4 : strlen(text);
for (i = 0; i < len; i++) {
DrawChar(xleft + i * 8 + 2, rfbWindowY - rfbStatusbarY + 5, 8, 8, 0,
(char *) &sdl_font8x8[(unsigned) text[i]][0], fgcolor, bgcolor, 0);
}
rfbMarkRectAsModified(theGui->screen, xleft, rfbWindowY - rfbStatusbarY + 1,
xleft + xsize, rfbWindowY - 2);
}
void newframebuffer(rfbScreenInfoPtr screen, int width, int height)