- added instructions how to update the online documentation
[bochs-mirror.git] / gui / gui.cc
blob3029e8b9d222721f611160c8e77863bd7d4aae03
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: gui.cc,v 1.105 2008/05/04 09:29:45 vruppert Exp $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 // Copyright (C) 2002 MandrakeSoft S.A.
6 //
7 // MandrakeSoft S.A.
8 // 43, rue d'Aboukir
9 // 75002 Paris - France
10 // http://www.linux-mandrake.com/
11 // http://www.mandrakesoft.com/
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Lesser General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Lesser General Public License for more details.
23 // You should have received a copy of the GNU Lesser General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include <signal.h>
29 #include "bochs.h"
30 #include "iodev.h"
31 #include "gui/bitmaps/floppya.h"
32 #include "gui/bitmaps/floppyb.h"
33 #include "gui/bitmaps/mouse.h"
34 #include "gui/bitmaps/reset.h"
35 #include "gui/bitmaps/power.h"
36 #include "gui/bitmaps/snapshot.h"
37 #include "gui/bitmaps/copy.h"
38 #include "gui/bitmaps/paste.h"
39 #include "gui/bitmaps/configbutton.h"
40 #include "gui/bitmaps/cdromd.h"
41 #include "gui/bitmaps/userbutton.h"
42 #include "gui/bitmaps/saverestore.h"
44 #if BX_WITH_MACOS
45 # include <Disks.h>
46 #endif
48 bx_gui_c *bx_gui = NULL;
50 #define BX_GUI_THIS bx_gui->
51 #define LOG_THIS BX_GUI_THIS
53 #define BX_KEY_UNKNOWN 0x7fffffff
54 #define N_USER_KEYS 37
56 typedef struct {
57 const char *key;
58 Bit32u symbol;
59 } user_key_t;
61 static user_key_t user_keys[N_USER_KEYS] =
63 { "f1", BX_KEY_F1 },
64 { "f2", BX_KEY_F2 },
65 { "f3", BX_KEY_F3 },
66 { "f4", BX_KEY_F4 },
67 { "f5", BX_KEY_F5 },
68 { "f6", BX_KEY_F6 },
69 { "f7", BX_KEY_F7 },
70 { "f8", BX_KEY_F8 },
71 { "f9", BX_KEY_F9 },
72 { "f10", BX_KEY_F10 },
73 { "f11", BX_KEY_F11 },
74 { "f12", BX_KEY_F12 },
75 { "alt", BX_KEY_ALT_L },
76 { "bksl", BX_KEY_BACKSLASH },
77 { "bksp", BX_KEY_BACKSPACE },
78 { "ctrl", BX_KEY_CTRL_L },
79 { "del", BX_KEY_DELETE },
80 { "down", BX_KEY_DOWN },
81 { "end", BX_KEY_END },
82 { "enter", BX_KEY_ENTER },
83 { "esc", BX_KEY_ESC },
84 { "home", BX_KEY_HOME },
85 { "ins", BX_KEY_INSERT },
86 { "left", BX_KEY_LEFT },
87 { "menu", BX_KEY_MENU },
88 { "minus", BX_KEY_MINUS },
89 { "pgdwn", BX_KEY_PAGE_DOWN },
90 { "pgup", BX_KEY_PAGE_UP },
91 { "plus", BX_KEY_KP_ADD },
92 { "right", BX_KEY_RIGHT },
93 { "shift", BX_KEY_SHIFT_L },
94 { "space", BX_KEY_SPACE },
95 { "tab", BX_KEY_TAB },
96 { "up", BX_KEY_UP },
97 { "win", BX_KEY_WIN_L },
98 { "print", BX_KEY_PRINT },
99 { "power", BX_KEY_POWER_POWER }
102 bx_gui_c::bx_gui_c(void)
104 put("GUI"); // Init in specific_init
105 settype(GUILOG);
106 statusitem_count = 0;
107 framebuffer = NULL;
110 bx_gui_c::~bx_gui_c()
112 if (framebuffer != NULL) {
113 delete [] framebuffer;
117 void bx_gui_c::init(int argc, char **argv, unsigned tilewidth, unsigned tileheight)
119 BX_GUI_THIS new_gfx_api = 0;
120 BX_GUI_THIS host_xres = 640;
121 BX_GUI_THIS host_yres = 480;
122 BX_GUI_THIS host_bpp = 8;
123 BX_GUI_THIS dialog_caps = BX_GUI_DLG_RUNTIME | BX_GUI_DLG_SAVE_RESTORE;
125 specific_init(argc, argv, tilewidth, tileheight, BX_HEADER_BAR_Y);
127 // Define some bitmaps to use in the headerbar
128 BX_GUI_THIS floppyA_bmap_id = create_bitmap(bx_floppya_bmap,
129 BX_FLOPPYA_BMAP_X, BX_FLOPPYA_BMAP_Y);
130 BX_GUI_THIS floppyA_eject_bmap_id = create_bitmap(bx_floppya_eject_bmap,
131 BX_FLOPPYA_BMAP_X, BX_FLOPPYA_BMAP_Y);
132 BX_GUI_THIS floppyB_bmap_id = create_bitmap(bx_floppyb_bmap,
133 BX_FLOPPYB_BMAP_X, BX_FLOPPYB_BMAP_Y);
134 BX_GUI_THIS floppyB_eject_bmap_id = create_bitmap(bx_floppyb_eject_bmap,
135 BX_FLOPPYB_BMAP_X, BX_FLOPPYB_BMAP_Y);
136 BX_GUI_THIS cdromD_bmap_id = create_bitmap(bx_cdromd_bmap,
137 BX_CDROMD_BMAP_X, BX_CDROMD_BMAP_Y);
138 BX_GUI_THIS cdromD_eject_bmap_id = create_bitmap(bx_cdromd_eject_bmap,
139 BX_CDROMD_BMAP_X, BX_CDROMD_BMAP_Y);
140 BX_GUI_THIS mouse_bmap_id = create_bitmap(bx_mouse_bmap,
141 BX_MOUSE_BMAP_X, BX_MOUSE_BMAP_Y);
142 BX_GUI_THIS nomouse_bmap_id = create_bitmap(bx_nomouse_bmap,
143 BX_MOUSE_BMAP_X, BX_MOUSE_BMAP_Y);
145 BX_GUI_THIS power_bmap_id = create_bitmap(bx_power_bmap, BX_POWER_BMAP_X, BX_POWER_BMAP_Y);
146 BX_GUI_THIS reset_bmap_id = create_bitmap(bx_reset_bmap, BX_RESET_BMAP_X, BX_RESET_BMAP_Y);
147 BX_GUI_THIS snapshot_bmap_id = create_bitmap(bx_snapshot_bmap, BX_SNAPSHOT_BMAP_X, BX_SNAPSHOT_BMAP_Y);
148 BX_GUI_THIS copy_bmap_id = create_bitmap(bx_copy_bmap, BX_COPY_BMAP_X, BX_COPY_BMAP_Y);
149 BX_GUI_THIS paste_bmap_id = create_bitmap(bx_paste_bmap, BX_PASTE_BMAP_X, BX_PASTE_BMAP_Y);
150 BX_GUI_THIS config_bmap_id = create_bitmap(bx_config_bmap, BX_CONFIG_BMAP_X, BX_CONFIG_BMAP_Y);
151 BX_GUI_THIS user_bmap_id = create_bitmap(bx_user_bmap, BX_USER_BMAP_X, BX_USER_BMAP_Y);
152 BX_GUI_THIS save_restore_bmap_id = create_bitmap(bx_save_restore_bmap,
153 BX_SAVE_RESTORE_BMAP_X, BX_SAVE_RESTORE_BMAP_Y);
155 // Add the initial bitmaps to the headerbar, and enable callback routine, for use
156 // when that bitmap is clicked on
158 // Floppy A:
159 BX_GUI_THIS floppyA_status = DEV_floppy_get_media_status(0);
160 if (BX_GUI_THIS floppyA_status)
161 BX_GUI_THIS floppyA_hbar_id = headerbar_bitmap(BX_GUI_THIS floppyA_bmap_id,
162 BX_GRAVITY_LEFT, floppyA_handler);
163 else
164 BX_GUI_THIS floppyA_hbar_id = headerbar_bitmap(BX_GUI_THIS floppyA_eject_bmap_id,
165 BX_GRAVITY_LEFT, floppyA_handler);
166 BX_GUI_THIS set_tooltip(BX_GUI_THIS floppyA_hbar_id, "Change floppy A: media");
168 // Floppy B:
169 BX_GUI_THIS floppyB_status = DEV_floppy_get_media_status(1);
170 if (BX_GUI_THIS floppyB_status)
171 BX_GUI_THIS floppyB_hbar_id = headerbar_bitmap(BX_GUI_THIS floppyB_bmap_id,
172 BX_GRAVITY_LEFT, floppyB_handler);
173 else
174 BX_GUI_THIS floppyB_hbar_id = headerbar_bitmap(BX_GUI_THIS floppyB_eject_bmap_id,
175 BX_GRAVITY_LEFT, floppyB_handler);
176 BX_GUI_THIS set_tooltip(BX_GUI_THIS floppyB_hbar_id, "Change floppy B: media");
178 // CDROM,
179 // the harddrive object is not initialised yet,
180 // so we just set the bitmap to ejected for now
181 BX_GUI_THIS cdromD_hbar_id = headerbar_bitmap(BX_GUI_THIS cdromD_eject_bmap_id,
182 BX_GRAVITY_LEFT, cdromD_handler);
183 BX_GUI_THIS set_tooltip(BX_GUI_THIS cdromD_hbar_id, "Change first CDROM media");
185 // Mouse button
186 if (SIM->get_param_bool(BXPN_MOUSE_ENABLED)->get())
187 BX_GUI_THIS mouse_hbar_id = headerbar_bitmap(BX_GUI_THIS mouse_bmap_id,
188 BX_GRAVITY_LEFT, toggle_mouse_enable);
189 else
190 BX_GUI_THIS mouse_hbar_id = headerbar_bitmap(BX_GUI_THIS nomouse_bmap_id,
191 BX_GRAVITY_LEFT, toggle_mouse_enable);
192 BX_GUI_THIS set_tooltip(BX_GUI_THIS mouse_hbar_id, "Enable mouse capture");
194 // These are the buttons on the right side. They are created in order
195 // of right to left.
197 // Power button
198 BX_GUI_THIS power_hbar_id = headerbar_bitmap(BX_GUI_THIS power_bmap_id,
199 BX_GRAVITY_RIGHT, power_handler);
200 BX_GUI_THIS set_tooltip(BX_GUI_THIS power_hbar_id, "Turn power off");
201 // Save/Restore Button
202 BX_GUI_THIS save_restore_hbar_id = headerbar_bitmap(BX_GUI_THIS save_restore_bmap_id,
203 BX_GRAVITY_RIGHT, save_restore_handler);
204 BX_GUI_THIS set_tooltip(BX_GUI_THIS save_restore_hbar_id, "Save simulation state");
205 // Reset button
206 BX_GUI_THIS reset_hbar_id = headerbar_bitmap(BX_GUI_THIS reset_bmap_id,
207 BX_GRAVITY_RIGHT, reset_handler);
208 BX_GUI_THIS set_tooltip(BX_GUI_THIS reset_hbar_id, "Reset the system");
209 // Configure button
210 BX_GUI_THIS config_hbar_id = headerbar_bitmap(BX_GUI_THIS config_bmap_id,
211 BX_GRAVITY_RIGHT, config_handler);
212 BX_GUI_THIS set_tooltip(BX_GUI_THIS config_hbar_id, "Runtime config dialog");
213 // Snapshot button
214 BX_GUI_THIS snapshot_hbar_id = headerbar_bitmap(BX_GUI_THIS snapshot_bmap_id,
215 BX_GRAVITY_RIGHT, snapshot_handler);
216 BX_GUI_THIS set_tooltip(BX_GUI_THIS snapshot_hbar_id, "Save snapshot of the text mode screen");
217 // Paste button
218 BX_GUI_THIS paste_hbar_id = headerbar_bitmap(BX_GUI_THIS paste_bmap_id,
219 BX_GRAVITY_RIGHT, paste_handler);
220 BX_GUI_THIS set_tooltip(BX_GUI_THIS paste_hbar_id, "Paste clipboard text as emulated keystrokes");
221 // Copy button
222 BX_GUI_THIS copy_hbar_id = headerbar_bitmap(BX_GUI_THIS copy_bmap_id,
223 BX_GRAVITY_RIGHT, copy_handler);
224 BX_GUI_THIS set_tooltip(BX_GUI_THIS copy_hbar_id, "Copy text mode screen to the clipboard");
225 // User button
226 BX_GUI_THIS user_hbar_id = headerbar_bitmap(BX_GUI_THIS user_bmap_id,
227 BX_GRAVITY_RIGHT, userbutton_handler);
228 BX_GUI_THIS set_tooltip(BX_GUI_THIS user_hbar_id, "Send keyboard shortcut");
230 if (SIM->get_param_bool(BXPN_TEXT_SNAPSHOT_CHECK)->get()) {
231 bx_pc_system.register_timer(this, bx_gui_c::snapshot_checker, (unsigned) 1000000, 1, 1, "snap_chk");
234 BX_GUI_THIS charmap_updated = 0;
236 if (!BX_GUI_THIS new_gfx_api && (BX_GUI_THIS framebuffer == NULL)) {
237 BX_GUI_THIS framebuffer = new Bit8u[BX_MAX_XRES * BX_MAX_YRES * 4];
239 show_headerbar();
242 void bx_gui_c::cleanup(void)
244 statusitem_count = 0;
247 void bx_gui_c::update_drive_status_buttons(void)
249 BX_GUI_THIS floppyA_status = DEV_floppy_get_media_status(0)
250 && (SIM->get_param_enum(BXPN_FLOPPYA_STATUS)->get() == BX_INSERTED);
251 BX_GUI_THIS floppyB_status = DEV_floppy_get_media_status(1)
252 && (SIM->get_param_enum(BXPN_FLOPPYB_STATUS)->get() == BX_INSERTED);
253 Bit32u handle = DEV_hd_get_first_cd_handle();
254 BX_GUI_THIS cdromD_status = DEV_hd_get_cd_media_status(handle);
255 if (BX_GUI_THIS floppyA_status)
256 replace_bitmap(BX_GUI_THIS floppyA_hbar_id, BX_GUI_THIS floppyA_bmap_id);
257 else {
258 #if BX_WITH_MACOS
259 // If we are using the Mac floppy driver, eject the disk
260 // from the floppy drive. This doesn't work in MacOS X.
261 if (!strcmp(SIM->get_param_string(BXPN_FLOPPYA_PATH)->getptr(), SuperDrive))
262 DiskEject(1);
263 #endif
264 replace_bitmap(BX_GUI_THIS floppyA_hbar_id, BX_GUI_THIS floppyA_eject_bmap_id);
266 if (BX_GUI_THIS floppyB_status)
267 replace_bitmap(BX_GUI_THIS floppyB_hbar_id, BX_GUI_THIS floppyB_bmap_id);
268 else {
269 #if BX_WITH_MACOS
270 // If we are using the Mac floppy driver, eject the disk
271 // from the floppy drive. This doesn't work in MacOS X.
272 if (!strcmp(SIM->get_param_string(BXPN_FLOPPYB_PATH)->getptr(), SuperDrive))
273 DiskEject(1);
274 #endif
275 replace_bitmap(BX_GUI_THIS floppyB_hbar_id, BX_GUI_THIS floppyB_eject_bmap_id);
277 if (BX_GUI_THIS cdromD_status)
278 replace_bitmap(BX_GUI_THIS cdromD_hbar_id, BX_GUI_THIS cdromD_bmap_id);
279 else {
280 replace_bitmap(BX_GUI_THIS cdromD_hbar_id, BX_GUI_THIS cdromD_eject_bmap_id);
284 void bx_gui_c::floppyA_handler(void)
286 if (SIM->get_param_enum(BXPN_FLOPPYA_DEVTYPE)->get() == BX_FLOPPY_NONE)
287 return; // no primary floppy device present
288 if (BX_GUI_THIS dialog_caps & BX_GUI_DLG_FLOPPY) {
289 // instead of just toggling the status, call win32dialog to bring up
290 // a dialog asking what disk image you want to switch to.
291 int ret = SIM->ask_param(BXPN_FLOPPYA_PATH);
292 if (ret > 0) {
293 BX_GUI_THIS update_drive_status_buttons();
295 return;
297 BX_GUI_THIS floppyA_status = !BX_GUI_THIS floppyA_status;
298 DEV_floppy_set_media_status(0, BX_GUI_THIS floppyA_status);
299 BX_GUI_THIS update_drive_status_buttons();
302 void bx_gui_c::floppyB_handler(void)
304 if (SIM->get_param_enum(BXPN_FLOPPYB_DEVTYPE)->get() == BX_FLOPPY_NONE)
305 return; // no secondary floppy device present
306 if (BX_GUI_THIS dialog_caps & BX_GUI_DLG_FLOPPY) {
307 // instead of just toggling the status, call win32dialog to bring up
308 // a dialog asking what disk image you want to switch to.
309 int ret = SIM->ask_param(BXPN_FLOPPYB_PATH);
310 if (ret > 0) {
311 BX_GUI_THIS update_drive_status_buttons();
313 return;
315 BX_GUI_THIS floppyB_status = !BX_GUI_THIS floppyB_status;
316 DEV_floppy_set_media_status(1, BX_GUI_THIS floppyB_status);
317 BX_GUI_THIS update_drive_status_buttons();
320 void bx_gui_c::cdromD_handler(void)
322 Bit32u handle = DEV_hd_get_first_cd_handle();
323 if (BX_GUI_THIS dialog_caps & BX_GUI_DLG_CDROM) {
324 // instead of just toggling the status, call win32dialog to bring up
325 // a dialog asking what disk image you want to switch to.
326 // This code handles the first cdrom only. The cdrom drives #2, #3 and
327 // #4 are handled in the win32 runtime dialog.
328 bx_param_c *cdrom = SIM->get_first_cdrom();
329 if (cdrom == NULL)
330 return; // no cdrom found
331 int ret = SIM->ask_param(cdrom);
332 if (ret > 0) {
333 BX_GUI_THIS update_drive_status_buttons();
335 return;
337 BX_GUI_THIS cdromD_status =
338 DEV_hd_set_cd_media_status(handle, !BX_GUI_THIS cdromD_status);
339 BX_GUI_THIS update_drive_status_buttons();
342 void bx_gui_c::reset_handler(void)
344 BX_INFO(("system RESET callback"));
345 bx_pc_system.Reset(BX_RESET_HARDWARE);
348 void bx_gui_c::power_handler(void)
350 // test case for yes/no dialog: confirm power off
351 //if (!SIM->ask_yes_no("Quit Bochs", "Are you sure ?", 0))
352 // return;
353 // the user pressed power button, so there's no doubt they want bochs
354 // to quit. Change panics to fatal for the GUI and then do a panic.
355 bx_user_quit = 1;
356 LOG_THIS setonoff(LOGLEV_PANIC, ACT_FATAL);
357 BX_PANIC (("POWER button turned off."));
358 // shouldn't reach this point, but if you do, QUIT!!!
359 fprintf (stderr, "Bochs is exiting because you pressed the power button.\n");
360 BX_EXIT (1);
363 Bit32s bx_gui_c::make_text_snapshot(char **snapshot, Bit32u *length)
365 Bit8u* raw_snap = NULL;
366 char *clean_snap;
367 unsigned line_addr, txt_addr, txHeight, txWidth;
369 DEV_vga_get_text_snapshot(&raw_snap, &txHeight, &txWidth);
370 if (txHeight <= 0) return -1;
371 clean_snap = (char*) malloc(txHeight*(txWidth+2)+1);
372 txt_addr = 0;
373 for (unsigned i=0; i<txHeight; i++) {
374 line_addr = i * txWidth * 2;
375 for (unsigned j=0; j<(txWidth*2); j+=2) {
376 clean_snap[txt_addr++] = raw_snap[line_addr+j];
378 while ((txt_addr > 0) && (clean_snap[txt_addr-1] == ' ')) txt_addr--;
379 #ifdef WIN32
380 if(!(SIM->get_param_bool(BXPN_TEXT_SNAPSHOT_CHECK)->get())) {
381 clean_snap[txt_addr++] = 13;
383 #endif
384 clean_snap[txt_addr++] = 10;
386 clean_snap[txt_addr] = 0;
387 *snapshot = clean_snap;
388 *length = txt_addr;
389 return 0;
392 // create a text snapshot and copy to the system clipboard. On guis that
393 // we haven't figured out how to support yet, dump to a file instead.
394 void bx_gui_c::copy_handler(void)
396 Bit32u len;
397 char *text_snapshot;
398 if (make_text_snapshot (&text_snapshot, &len) < 0) {
399 BX_INFO(("copy button failed, mode not implemented"));
400 return;
402 if (!BX_GUI_THIS set_clipboard_text(text_snapshot, len)) {
403 // platform specific code failed, use portable code instead
404 FILE *fp = fopen("copy.txt", "w");
405 fwrite(text_snapshot, 1, len, fp);
406 fclose(fp);
408 free(text_snapshot);
411 // Check the current text snapshot against file snapchk.txt.
412 void bx_gui_c::snapshot_checker(void *this_ptr)
414 char filename[BX_PATHNAME_LEN];
415 strcpy(filename,"snapchk.txt");
416 FILE *fp = fopen(filename, "rb");
417 if(fp) {
418 char *text_snapshot;
419 Bit32u len;
420 if (make_text_snapshot (&text_snapshot, &len) < 0) {
421 return;
423 char *compare_snapshot = (char *) malloc((len+1) * sizeof(char));
424 fread(compare_snapshot, 1, len, fp);
425 fclose(fp);
426 strcpy(filename,"snapmask.txt");
427 fp=fopen(filename, "rb");
428 if(fp) {
429 char *mask_snapshot = (char *) malloc((len+1) * sizeof(char));
430 unsigned i;
431 bx_bool flag = 1;
432 fread(mask_snapshot, 1, len, fp);
433 fclose(fp);
434 for(i=0;i<len;i++) {
435 if((text_snapshot[i] != compare_snapshot[i]) &&
436 (compare_snapshot[i] == mask_snapshot[i])) {
437 flag = 0;
438 break;
441 if(flag) {
442 if(!memcmp(text_snapshot,compare_snapshot,len)) {
443 BX_PASS(("Test Passed."));
444 } else {
445 BX_PASS(("Test Passed with Mask."));
448 } else {
449 if(!memcmp(text_snapshot,compare_snapshot,len)) {
450 BX_PASS(("Test Passed."));
453 free(compare_snapshot);
454 free(text_snapshot);
458 // create a text snapshot and dump it to a file
459 void bx_gui_c::snapshot_handler(void)
461 char *text_snapshot;
462 Bit32u len;
463 if (make_text_snapshot (&text_snapshot, &len) < 0) {
464 BX_ERROR(("snapshot button failed, mode not implemented"));
465 return;
467 //FIXME
468 char filename[BX_PATHNAME_LEN];
469 if (BX_GUI_THIS dialog_caps & BX_GUI_DLG_SNAPSHOT) {
470 int ret = SIM->ask_filename (filename, sizeof(filename),
471 "Save snapshot as...", "snapshot.txt",
472 bx_param_string_c::SAVE_FILE_DIALOG);
473 if (ret < 0) { // cancelled
474 free(text_snapshot);
475 return;
477 } else {
478 strcpy (filename, "snapshot.txt");
480 FILE *fp = fopen(filename, "wb");
481 fwrite(text_snapshot, 1, len, fp);
482 fclose(fp);
483 free(text_snapshot);
486 // Read ASCII chars from the system clipboard and paste them into bochs.
487 // Note that paste cannot work with the key mapping tables loaded.
488 void bx_gui_c::paste_handler(void)
490 Bit32s nbytes;
491 Bit8u *bytes;
492 if (!bx_keymap.isKeymapLoaded ()) {
493 BX_ERROR (("keyboard_mapping disabled, so paste cannot work"));
494 return;
496 if (!BX_GUI_THIS get_clipboard_text(&bytes, &nbytes)) {
497 BX_ERROR (("paste not implemented on this platform"));
498 return;
500 BX_INFO (("pasting %d bytes", nbytes));
501 DEV_kbd_paste_bytes (bytes, nbytes);
504 void bx_gui_c::config_handler(void)
506 if (BX_GUI_THIS dialog_caps & BX_GUI_DLG_RUNTIME) {
507 SIM->configuration_interface(NULL, CI_RUNTIME_CONFIG);
511 void bx_gui_c::toggle_mouse_enable(void)
513 int old = SIM->get_param_bool(BXPN_MOUSE_ENABLED)->get();
514 BX_DEBUG (("toggle mouse_enabled, now %d", !old));
515 SIM->get_param_bool(BXPN_MOUSE_ENABLED)->set(!old);
518 Bit32u get_user_key(char *key)
520 int i = 0;
522 while (i < N_USER_KEYS) {
523 if (!strcmp(key, user_keys[i].key))
524 return user_keys[i].symbol;
525 i++;
527 return BX_KEY_UNKNOWN;
530 void bx_gui_c::userbutton_handler(void)
532 Bit32u shortcut[4];
533 Bit32u symbol;
534 char user_shortcut[512];
535 char *ptr;
536 int i, len = 0, ret = 1;
538 if (BX_GUI_THIS dialog_caps & BX_GUI_DLG_USER) {
539 ret = SIM->ask_param(BXPN_USER_SHORTCUT);
541 strcpy(user_shortcut, SIM->get_param_string(BXPN_USER_SHORTCUT)->getptr());
542 if ((ret > 0) && user_shortcut[0] && (strcmp(user_shortcut, "none"))) {
543 ptr = strtok(user_shortcut, "-");
544 if ((strcmp(ptr, SIM->get_param_string(BXPN_USER_SHORTCUT)->getptr())) ||
545 (strlen(SIM->get_param_string(BXPN_USER_SHORTCUT)->getptr()) < 6)) {
546 while (ptr) {
547 symbol = get_user_key(ptr);
548 if (symbol == BX_KEY_UNKNOWN) {
549 BX_ERROR(("Unknown shortcut %s ignored", ptr));
550 return;
552 shortcut[len++] = symbol;
553 ptr = strtok(NULL, "-");
555 } else {
556 BX_ERROR(("Unknown shortcut %s ignored", user_shortcut));
557 return;
559 i = 0;
560 while (i < len) {
561 DEV_kbd_gen_scancode(shortcut[i++]);
563 i--;
564 while (i >= 0) {
565 DEV_kbd_gen_scancode(shortcut[i--] | BX_KEY_RELEASED);
570 void bx_gui_c::save_restore_handler(void)
572 int ret;
573 char sr_path[BX_PATHNAME_LEN];
575 if (BX_GUI_THIS dialog_caps & BX_GUI_DLG_SAVE_RESTORE) {
576 sr_path[0] = 0;
577 ret = SIM->ask_filename(sr_path, sizeof(sr_path),
578 "Save Bochs state to folder...", "none",
579 bx_param_string_c::SELECT_FOLDER_DLG);
580 if ((ret >= 0) && (strcmp(sr_path, "none"))) {
581 if (SIM->save_state(sr_path)) {
582 if (!SIM->ask_yes_no("WARNING",
583 "The save function currently doesn't handle the state of hard drive images,\n"
584 "so we don't recommend to continue, unless you are running a read-only\n"
585 "guest system (e.g. Live-CD).\n\n"
586 "Do you want to continue?", 0)) {
587 power_handler();
594 void bx_gui_c::mouse_enabled_changed(bx_bool val)
596 // This is only called when SIM->get_init_done is 1. Note that VAL
597 // is the new value of mouse_enabled, which may not match the old
598 // value which is still in SIM->get_param_bool(BXPN_MOUSE_ENABLED)->get().
599 BX_DEBUG (("replacing the mouse bitmaps"));
600 if (val)
601 BX_GUI_THIS replace_bitmap(BX_GUI_THIS mouse_hbar_id, BX_GUI_THIS mouse_bmap_id);
602 else
603 BX_GUI_THIS replace_bitmap(BX_GUI_THIS mouse_hbar_id, BX_GUI_THIS nomouse_bmap_id);
604 // give the GUI a chance to respond to the event. Most guis will hide
605 // the native mouse cursor and do something to trap the mouse inside the
606 // bochs VGA display window.
607 BX_GUI_THIS mouse_enabled_changed_specific (val);
610 void bx_gui_c::init_signal_handlers()
612 #if BX_GUI_SIGHANDLER
613 if (bx_gui_sighandler)
615 Bit32u mask = bx_gui->get_sighandler_mask ();
616 for (Bit32u sig=0; sig<32; sig++)
618 if (mask & (1<<sig))
619 signal (sig, bx_signal_handler);
622 #endif
625 void bx_gui_c::set_text_charmap(Bit8u *fbuffer)
627 memcpy(& BX_GUI_THIS vga_charmap, fbuffer, 0x2000);
628 for (unsigned i=0; i<256; i++) BX_GUI_THIS char_changed[i] = 1;
629 BX_GUI_THIS charmap_updated = 1;
632 void bx_gui_c::set_text_charbyte(Bit16u address, Bit8u data)
634 BX_GUI_THIS vga_charmap[address] = data;
635 BX_GUI_THIS char_changed[address >> 5] = 1;
636 BX_GUI_THIS charmap_updated = 1;
639 void bx_gui_c::beep_on(float frequency)
641 BX_INFO(("GUI Beep ON (frequency=%.2f)", frequency));
644 void bx_gui_c::beep_off()
646 BX_INFO(("GUI Beep OFF"));
649 int bx_gui_c::register_statusitem(const char *text)
651 if (statusitem_count < BX_MAX_STATUSITEMS) {
652 strncpy(statusitem_text[statusitem_count], text, 8);
653 statusitem_text[statusitem_count][7] = 0;
654 return statusitem_count++;
655 } else {
656 return -1;
660 void bx_gui_c::get_capabilities(Bit16u *xres, Bit16u *yres, Bit16u *bpp)
662 *xres = 1024;
663 *yres = 768;
664 *bpp = 32;
667 bx_svga_tileinfo_t *bx_gui_c::graphics_tile_info(bx_svga_tileinfo_t *info)
669 if (!info) {
670 info = (bx_svga_tileinfo_t *)malloc(sizeof(bx_svga_tileinfo_t));
671 if (!info) {
672 return NULL;
676 BX_GUI_THIS host_pitch = BX_GUI_THIS host_xres * ((BX_GUI_THIS host_bpp + 1) >> 3);
678 info->bpp = BX_GUI_THIS host_bpp;
679 info->pitch = BX_GUI_THIS host_pitch;
680 switch (info->bpp) {
681 case 15:
682 info->red_shift = 15;
683 info->green_shift = 10;
684 info->blue_shift = 5;
685 info->red_mask = 0x7c00;
686 info->green_mask = 0x03e0;
687 info->blue_mask = 0x001f;
688 break;
689 case 16:
690 info->red_shift = 16;
691 info->green_shift = 11;
692 info->blue_shift = 5;
693 info->red_mask = 0xf800;
694 info->green_mask = 0x07e0;
695 info->blue_mask = 0x001f;
696 break;
697 case 24:
698 case 32:
699 info->red_shift = 24;
700 info->green_shift = 16;
701 info->blue_shift = 8;
702 info->red_mask = 0xff0000;
703 info->green_mask = 0x00ff00;
704 info->blue_mask = 0x0000ff;
705 break;
707 info->is_indexed = (BX_GUI_THIS host_bpp == 8);
708 #ifdef BX_LITTLE_ENDIAN
709 info->is_little_endian = 1;
710 #else
711 info->is_little_endian = 0;
712 #endif
714 return info;
717 Bit8u *bx_gui_c::graphics_tile_get(unsigned x0, unsigned y0,
718 unsigned *w, unsigned *h)
720 if (x0+X_TILESIZE > BX_GUI_THIS host_xres) {
721 *w = BX_GUI_THIS host_xres - x0;
723 else {
724 *w = X_TILESIZE;
727 if (y0+Y_TILESIZE > BX_GUI_THIS host_yres) {
728 *h = BX_GUI_THIS host_yres - y0;
730 else {
731 *h = Y_TILESIZE;
734 return (Bit8u *)framebuffer + y0 * BX_GUI_THIS host_pitch +
735 x0 * ((BX_GUI_THIS host_bpp + 1) >> 3);
738 void bx_gui_c::graphics_tile_update_in_place(unsigned x0, unsigned y0,
739 unsigned w, unsigned h)
741 Bit8u tile[X_TILESIZE * Y_TILESIZE * 4];
742 Bit8u *tile_ptr, *fb_ptr;
743 Bit16u xc, yc, fb_pitch, tile_pitch;
744 Bit8u r, diffx, diffy;
746 diffx = (x0 % X_TILESIZE);
747 diffy = (y0 % Y_TILESIZE);
748 if (diffx > 0) {
749 x0 -= diffx;
750 w += diffx;
752 if (diffy > 0) {
753 y0 -= diffy;
754 h += diffy;
756 fb_pitch = BX_GUI_THIS host_pitch;
757 tile_pitch = X_TILESIZE * ((BX_GUI_THIS host_bpp + 1) >> 3);
758 for (yc=y0; yc<(y0+h); yc+=Y_TILESIZE) {
759 for (xc=x0; xc<(x0+w); xc+=X_TILESIZE) {
760 fb_ptr = BX_GUI_THIS framebuffer + (yc * fb_pitch + xc * ((BX_GUI_THIS host_bpp + 1) >> 3));
761 tile_ptr = &tile[0];
762 for (r=0; r<h; r++) {
763 memcpy(tile_ptr, fb_ptr, tile_pitch);
764 fb_ptr += fb_pitch;
765 tile_ptr += tile_pitch;
767 BX_GUI_THIS graphics_tile_update(tile, xc, yc);
772 void bx_gui_c::show_ips(Bit32u ips_count)
774 #if BX_SHOW_IPS
775 BX_INFO(("ips = %u", ips_count));
776 #endif
779 Bit8u bx_gui_c::get_mouse_headerbar_id()
781 return BX_GUI_THIS mouse_hbar_id;