aboutsummaryrefslogtreecommitdiffstats
path: root/tools/ioemu/gui/svga.cc
diff options
context:
space:
mode:
Diffstat (limited to 'tools/ioemu/gui/svga.cc')
-rw-r--r--tools/ioemu/gui/svga.cc514
1 files changed, 514 insertions, 0 deletions
diff --git a/tools/ioemu/gui/svga.cc b/tools/ioemu/gui/svga.cc
new file mode 100644
index 0000000000..33020fca80
--- /dev/null
+++ b/tools/ioemu/gui/svga.cc
@@ -0,0 +1,514 @@
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#define _MULTI_THREAD
+
+// Define BX_PLUGGABLE in files that can be compiled into plugins. For
+// platforms that require a special tag on exported symbols, BX_PLUGGABLE
+// is used to know when we are exporting symbols and when we are importing.
+#define BX_PLUGGABLE
+
+#include "bochs.h"
+#if BX_WITH_SVGA
+
+#include <stdlib.h>
+#include </usr/include/vga.h>
+#include <vgagl.h>
+#include <vgakeyboard.h>
+#include <vgamouse.h>
+
+#include "font/vga.bitmap.h"
+//#include "icon_bochs.h"
+
+class bx_svga_gui_c : public bx_gui_c {
+public:
+ bx_svga_gui_c (void);
+ DECLARE_GUI_VIRTUAL_METHODS()
+ virtual void set_display_mode (disp_mode_t newmode);
+};
+
+// declare one instance of the gui object and call macro to insert the
+// plugin code
+static bx_svga_gui_c *theGui = NULL;
+
+IMPLEMENT_GUI_PLUGIN_CODE(svga)
+
+#define LOG_THIS theGui->
+
+static unsigned res_x, res_y;
+static int fontwidth = 8, fontheight = 16;
+static unsigned tilewidth, tileheight;
+static unsigned char vgafont[256 * 16];
+static int clut8 = 0;
+GraphicsContext *screen = NULL;
+static int save_vga_mode;
+static int save_vga_pal[256 * 3];
+
+void keyboard_handler(int scancode, int press);
+void mouse_handler(int button, int dx, int dy, int dz,
+ int drx, int dry, int drz);
+
+unsigned char reverse_byteorder(unsigned char b)
+{
+ unsigned char ret = 0;
+
+ for (unsigned i=0;i<8;i++){
+ ret |= (b & 0x01) << (7 - i);
+ b >>= 1;
+ }
+ return ret;
+}
+
+void create_vga_font()
+{
+ memcpy(vgafont, bx_vgafont, sizeof(bx_vgafont));
+
+ for (unsigned i=0;i< sizeof(bx_vgafont);i++) {
+ vgafont[i] = reverse_byteorder(vgafont[i]);
+ }
+}
+
+bx_svga_gui_c::bx_svga_gui_c ()
+{
+ put("SVGA");
+}
+
+void bx_svga_gui_c::specific_init(
+ int argc,
+ char **argv,
+ unsigned x_tilesize,
+ unsigned y_tilesize,
+ unsigned header_bar_y)
+{
+ tilewidth = x_tilesize;
+ tileheight = y_tilesize;
+
+ if(vga_init() != 0 )
+ {
+ LOG_THIS setonoff(LOGLEV_PANIC, ACT_FATAL);
+ BX_PANIC (("Unable to initialize SVGAlib"));
+ return;
+ }
+
+ screen = gl_allocatecontext();
+
+ dimension_update(640,400);
+ create_vga_font();
+ gl_setfont(8, 16, (void *)vgafont);
+ gl_setwritemode(FONT_COMPRESSED);
+
+ keyboard_init();
+ keyboard_seteventhandler((__keyboard_handler) keyboard_handler);
+
+ vga_setmousesupport(1);
+ mouse_seteventhandler((__mouse_handler) mouse_handler);
+ if (vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_FLAGS) & VGA_CLUT8) {
+ vga_ext_set(VGA_EXT_SET, VGA_CLUT8);
+ clut8 = 1;
+ }
+ // Save settings to prepare for mode transition in set_display_mode.
+ // If DISP_MODE_SIM is called first, these values will be used.
+ save_vga_mode = vga_getcurrentmode();
+ vga_getpalvec(0, 256, save_vga_pal);
+}
+
+void bx_svga_gui_c::text_update(
+ Bit8u *old_text,
+ Bit8u *new_text,
+ unsigned long cursor_x,
+ unsigned long cursor_y,
+ bx_vga_tminfo_t tm_info,
+ unsigned rows)
+{
+ unsigned x, y, i;
+ unsigned chars, cols;
+ char s[] = " ";
+ static unsigned int previ;
+ unsigned int cursori;
+
+ cols = res_x/fontwidth;
+
+ cursori = (cursor_y*cols + cursor_x) * 2;
+
+ chars = cols*rows;
+
+ for (i=0; i<chars*2; i+=2) {
+ if (i == cursori || i == previ || old_text[i] != new_text[i] ||
+ old_text[i+1] != new_text[i+1]) {
+
+ s[0] = new_text[i];
+ x = (i/2) % cols;
+ y = (i/2) / cols;
+
+ if (i == cursori) {
+ gl_setfontcolors(new_text[i+1] & 0x0F, (new_text[i+1] & 0xF0) >> 4);
+ } else {
+ gl_setfontcolors((new_text[i+1] & 0xF0) >> 4, new_text[i+1] & 0x0F);
+ }
+ gl_write(x * fontwidth, y * fontheight, s);
+ }
+ }
+ previ = cursori;
+}
+
+ int
+bx_svga_gui_c::get_clipboard_text(Bit8u **bytes, Bit32s *nbytes)
+{
+ return 0;
+}
+
+ int
+bx_svga_gui_c::set_clipboard_text(char *text_snapshot, Bit32u len)
+{
+ return 0;
+}
+
+
+void bx_svga_gui_c::graphics_tile_update(
+ Bit8u *snapshot,
+ unsigned x,
+ unsigned y)
+{
+ gl_putbox(x, y, tilewidth, tileheight, snapshot);
+}
+
+static Bit32u vga_to_bx_key(int key)
+{
+ switch (key) {
+ case SCANCODE_ESCAPE: return BX_KEY_ESC;
+ case SCANCODE_1: return BX_KEY_1;
+ case SCANCODE_2: return BX_KEY_2;
+ case SCANCODE_3: return BX_KEY_3;
+ case SCANCODE_4: return BX_KEY_4;
+ case SCANCODE_5: return BX_KEY_5;
+ case SCANCODE_6: return BX_KEY_6;
+ case SCANCODE_7: return BX_KEY_7;
+ case SCANCODE_8: return BX_KEY_8;
+ case SCANCODE_9: return BX_KEY_9;
+ case SCANCODE_0: return BX_KEY_0;
+
+ case SCANCODE_MINUS: return BX_KEY_MINUS;
+ case SCANCODE_EQUAL: return BX_KEY_EQUALS;
+ case SCANCODE_TAB: return BX_KEY_TAB;
+ case SCANCODE_BACKSPACE: return BX_KEY_BACKSPACE;
+
+ case SCANCODE_Q: return BX_KEY_Q;
+ case SCANCODE_W: return BX_KEY_W;
+ case SCANCODE_E: return BX_KEY_E;
+ case SCANCODE_R: return BX_KEY_R;
+ case SCANCODE_T: return BX_KEY_T;
+ case SCANCODE_Y: return BX_KEY_Y;
+ case SCANCODE_U: return BX_KEY_U;
+ case SCANCODE_I: return BX_KEY_I;
+ case SCANCODE_O: return BX_KEY_O;
+ case SCANCODE_P: return BX_KEY_P;
+
+ case SCANCODE_BRACKET_LEFT: return BX_KEY_LEFT_BRACKET;
+ case SCANCODE_BRACKET_RIGHT: return BX_KEY_RIGHT_BRACKET;
+
+ case SCANCODE_ENTER: return BX_KEY_ENTER;
+ case SCANCODE_LEFTCONTROL: return BX_KEY_CTRL_L;
+
+ case SCANCODE_A: return BX_KEY_A;
+ case SCANCODE_S: return BX_KEY_S;
+ case SCANCODE_D: return BX_KEY_D;
+ case SCANCODE_F: return BX_KEY_F;
+ case SCANCODE_G: return BX_KEY_G;
+ case SCANCODE_H: return BX_KEY_H;
+ case SCANCODE_J: return BX_KEY_J;
+ case SCANCODE_K: return BX_KEY_K;
+ case SCANCODE_L: return BX_KEY_L;
+
+ case SCANCODE_SEMICOLON: return BX_KEY_SEMICOLON;
+ case SCANCODE_APOSTROPHE: return BX_KEY_SINGLE_QUOTE;
+ case SCANCODE_GRAVE: return BX_KEY_GRAVE;
+
+ case SCANCODE_LEFTSHIFT: return BX_KEY_SHIFT_L;
+ case SCANCODE_BACKSLASH: return BX_KEY_BACKSLASH;
+
+ case SCANCODE_Z: return BX_KEY_Z;
+ case SCANCODE_X: return BX_KEY_X;
+ case SCANCODE_C: return BX_KEY_C;
+ case SCANCODE_V: return BX_KEY_V;
+ case SCANCODE_B: return BX_KEY_B;
+ case SCANCODE_N: return BX_KEY_N;
+ case SCANCODE_M: return BX_KEY_M;
+
+ case SCANCODE_COMMA: return BX_KEY_COMMA;
+ case SCANCODE_PERIOD: return BX_KEY_PERIOD;
+ case SCANCODE_SLASH: return BX_KEY_SLASH;
+
+ case SCANCODE_RIGHTSHIFT: return BX_KEY_SHIFT_R;
+ case SCANCODE_KEYPADMULTIPLY: return BX_KEY_KP_MULTIPLY;
+
+ case SCANCODE_LEFTALT: return BX_KEY_ALT_L;
+ case SCANCODE_SPACE: return BX_KEY_SPACE;
+ case SCANCODE_CAPSLOCK: return BX_KEY_CAPS_LOCK;
+
+ case SCANCODE_F1: return BX_KEY_F1;
+ case SCANCODE_F2: return BX_KEY_F2;
+ case SCANCODE_F3: return BX_KEY_F3;
+ case SCANCODE_F4: return BX_KEY_F4;
+ case SCANCODE_F5: return BX_KEY_F5;
+ case SCANCODE_F6: return BX_KEY_F6;
+ case SCANCODE_F7: return BX_KEY_F7;
+ case SCANCODE_F8: return BX_KEY_F8;
+ case SCANCODE_F9: return BX_KEY_F9;
+ case SCANCODE_F10: return BX_KEY_F10;
+
+ case SCANCODE_NUMLOCK: return BX_KEY_NUM_LOCK;
+ case SCANCODE_SCROLLLOCK: return BX_KEY_SCRL_LOCK;
+
+ case SCANCODE_KEYPAD7: return BX_KEY_KP_HOME;
+ case SCANCODE_KEYPAD8: return BX_KEY_KP_UP;
+ case SCANCODE_KEYPAD9: return BX_KEY_KP_PAGE_UP;
+ case SCANCODE_KEYPADMINUS: return BX_KEY_KP_SUBTRACT;
+ case SCANCODE_KEYPAD4: return BX_KEY_KP_LEFT;
+ case SCANCODE_KEYPAD5: return BX_KEY_KP_5;
+ case SCANCODE_KEYPAD6: return BX_KEY_KP_RIGHT;
+ case SCANCODE_KEYPADPLUS: return BX_KEY_KP_ADD;
+ case SCANCODE_KEYPAD1: return BX_KEY_KP_END;
+ case SCANCODE_KEYPAD2: return BX_KEY_KP_DOWN;
+ case SCANCODE_KEYPAD3: return BX_KEY_KP_PAGE_DOWN;
+ case SCANCODE_KEYPAD0: return BX_KEY_KP_INSERT;
+// case SCANCODE_KEYPADPERIOD: return BX_KEY_KP_; /* ??? */
+
+// case SCANCODE_LESS: return BX_KEY_KP_LESS; /* ??? */
+
+ case SCANCODE_F11: return BX_KEY_F11;
+ case SCANCODE_F12: return BX_KEY_F12;
+
+ case SCANCODE_KEYPADENTER: return BX_KEY_KP_ENTER;
+ case SCANCODE_RIGHTCONTROL: return BX_KEY_CTRL_R;
+ case SCANCODE_KEYPADDIVIDE: return BX_KEY_KP_DIVIDE;
+ case SCANCODE_PRINTSCREEN: return BX_KEY_PRINT;
+ case SCANCODE_RIGHTALT: return BX_KEY_ALT_R;
+ case SCANCODE_BREAK: return BX_KEY_PAUSE;
+
+ case SCANCODE_HOME: return BX_KEY_HOME;
+ case SCANCODE_CURSORBLOCKUP: return BX_KEY_UP;
+ case SCANCODE_PAGEUP: return BX_KEY_PAGE_UP;
+ case SCANCODE_CURSORBLOCKLEFT: return BX_KEY_LEFT;
+ case SCANCODE_CURSORBLOCKRIGHT: return BX_KEY_RIGHT;
+ case SCANCODE_END: return BX_KEY_END;
+ case SCANCODE_CURSORBLOCKDOWN: return BX_KEY_DOWN;
+ case SCANCODE_PAGEDOWN: return BX_KEY_PAGE_DOWN;
+ case SCANCODE_INSERT: return BX_KEY_INSERT;
+ case SCANCODE_REMOVE: return BX_KEY_DELETE;
+
+ case SCANCODE_RIGHTWIN: return BX_KEY_WIN_R;
+ case SCANCODE_LEFTWIN: return BX_KEY_WIN_L;
+
+ default: return 0;
+ }
+}
+
+void keyboard_handler(int scancode, int press)
+{
+ if (scancode != SCANCODE_F12) {
+ int bx_key = vga_to_bx_key(scancode);
+ Bit32u key_state;
+
+ if (press) {
+ key_state = BX_KEY_PRESSED;
+ } else {
+ key_state = BX_KEY_RELEASED;
+ }
+
+ DEV_kbd_gen_scancode(bx_key | key_state);
+ } else {
+ BX_INFO(("F12 pressed"));
+ // show runtime options menu, which uses stdin/stdout
+ SIM->configuration_interface (NULL, CI_RUNTIME_CONFIG);
+ }
+}
+
+void mouse_handler(int button, int dx, int dy, int dz,
+ int drx, int dry, int drz)
+{
+ int buttons = 0;
+
+ if (button & MOUSE_LEFTBUTTON) {
+ buttons |= 0x01;
+ }
+
+ if (button & MOUSE_RIGHTBUTTON) {
+ buttons |= 0x02;
+ }
+ DEV_mouse_motion((int) (0.25 * dx), (int) -(0.25 * dy), buttons);
+}
+
+void bx_svga_gui_c::handle_events(void)
+{
+ keyboard_update();
+ keyboard_clearstate();
+ mouse_update();
+}
+
+void bx_svga_gui_c::flush(void)
+{
+ gl_copyscreen(screen);
+}
+
+void bx_svga_gui_c::clear_screen(void)
+{
+ gl_clearscreen(0);
+}
+
+bx_bool bx_svga_gui_c::palette_change(
+ unsigned index,
+ unsigned red,
+ unsigned green,
+ unsigned blue)
+{
+ if( index > 255 ) return 0;
+
+ // without VGA_CLUT8 extension we have only 6 bits for each r,g,b value
+ if (!clut8 && (red > 63 || green > 63 || blue > 63)) {
+ red = red >> 2;
+ green = green >> 2;
+ blue = blue >> 2;
+ }
+
+ vga_setpalette(index, red, green, blue);
+
+ return 1;
+}
+
+
+void bx_svga_gui_c::dimension_update(
+ unsigned x,
+ unsigned y,
+ unsigned fheight,
+ unsigned fwidth,
+ unsigned bpp)
+{
+ int newmode = 0;
+
+ if (bpp > 8) {
+ BX_PANIC(("%d bpp graphics mode not supported yet", bpp));
+ }
+ if( fheight > 0 )
+ {
+ fontheight = fheight;
+ if (fwidth != 8) {
+ x = x * 8 / fwidth;
+ }
+ fontwidth = 8;
+ }
+
+ if( (x == res_x) && (y == res_y )) return;
+
+ if (x == 640 && y == 480) {
+ newmode = G640x480x256;
+ } else if (x == 640 && y == 400) {
+ newmode = G640x400x256;
+ } else if (x == 320 && y == 200) {
+ newmode = G320x200x256;
+ }
+
+ if (!vga_hasmode(newmode)) {
+ newmode = G640x480x256; // trying "default" mode...
+ }
+
+ if (vga_setmode(newmode) != 0)
+ {
+ LOG_THIS setonoff(LOGLEV_PANIC, ACT_FATAL);
+ BX_PANIC (("Unable to set requested videomode: %ix%i", x, y));
+ }
+
+ gl_setcontextvga(newmode);
+ gl_getcontext(screen);
+ gl_setcontextvgavirtual(newmode);
+ save_vga_mode = newmode;
+
+ res_x = x;
+ res_y = y;
+}
+
+
+unsigned bx_svga_gui_c::create_bitmap(
+ const unsigned char *bmap,
+ unsigned xdim,
+ unsigned ydim)
+{
+ return 0;
+}
+
+
+unsigned bx_svga_gui_c::headerbar_bitmap(
+ unsigned bmap_id,
+ unsigned alignment,
+ void (*f)(void))
+{
+ return 0;
+}
+
+
+void bx_svga_gui_c::replace_bitmap(
+ unsigned hbar_id,
+ unsigned bmap_id)
+{
+}
+
+
+void bx_svga_gui_c::show_headerbar(void)
+{
+}
+
+
+void bx_svga_gui_c::mouse_enabled_changed_specific (bx_bool val)
+{
+}
+
+
+void headerbar_click(int x)
+{
+}
+
+void bx_svga_gui_c::exit(void)
+{
+ vga_setmode(TEXT);
+ keyboard_close();
+ mouse_close();
+}
+
+void
+bx_svga_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;
+ switch (newmode) {
+ case DISP_MODE_CONFIG:
+ BX_DEBUG (("switch to configuration mode (back to console)"));
+ // remember old values and switch to text mode
+ save_vga_mode = vga_getcurrentmode();
+ vga_getpalvec(0, 256, save_vga_pal);
+ keyboard_close();
+ vga_setmode(TEXT);
+ break;
+ case DISP_MODE_SIM:
+ BX_DEBUG (("switch to simulation mode (fullscreen)"));
+ keyboard_init();
+ keyboard_seteventhandler((__keyboard_handler) keyboard_handler);
+ vga_setmode(save_vga_mode);
+ vga_setpalvec(0, 256, save_vga_pal);
+ break;
+ }
+}
+
+#endif /* if BX_WITH_SVGA */