00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00055 #define XK_PUBLISHING
00056 #define XK_TECHNICAL
00057
00058 #include "../StdAfx.h"
00059
00060 #if defined(HAVE_X11)
00061 #include "gui.h"
00062 #include "keymap.h"
00063 #include "../Configurator.h"
00064 #include "../VGA.h"
00065 #include "../Keyboard.h"
00066
00067 extern "C"
00068 {
00069 #include <X11/Xlib.h>
00070 #include <X11/Xutil.h>
00071 #include <X11/Xos.h>
00072 #include <X11/Xatom.h>
00073 #include <X11/keysym.h>
00074 }
00075 #include "gui_win32_font.h"
00076
00077 class bx_x11_gui_c : public bx_gui_c
00078 {
00079 public:
00080 bx_x11_gui_c(CConfigurator* cfg)
00081 {
00082 myCfg = cfg;
00083 bx_keymap = new bx_keymap_c(cfg);
00084 };
00085
00086 virtual void specific_init(unsigned x_tilesize,
00087 unsigned y_tilesize);
00088 virtual void text_update(u8* old_text, u8* new_text,
00089 unsigned long cursor_x,
00090 unsigned long cursor_y,
00091 bx_vga_tminfo_t tm_info,
00092 unsigned rows);
00093 virtual void graphics_tile_update(u8* snapshot, unsigned x,
00094 unsigned y);
00095 virtual void handle_events(void);
00096 virtual void flush(void);
00097 virtual void clear_screen(void);
00098 virtual bool palette_change(unsigned index, unsigned red,
00099 unsigned green, unsigned blue);
00100 virtual void dimension_update(unsigned x, unsigned y,
00101 unsigned fheight = 0,
00102 unsigned fwidth = 0,
00103 unsigned bpp = 8);
00104 virtual void mouse_enabled_changed_specific(bool val);
00105 virtual void exit(void);
00106 virtual bx_svga_tileinfo_t* graphics_tile_info(bx_svga_tileinfo_t* info);
00107 virtual u8* graphics_tile_get(unsigned x, unsigned y,
00108 unsigned* w, unsigned* h);
00109 virtual void graphics_tile_update_in_place(unsigned x,
00110 unsigned y,
00111 unsigned w,
00112 unsigned h);
00113 virtual void get_capabilities(u16* xres, u16* yres,
00114 u16* bpp);
00115 private:
00116 CConfigurator* myCfg;
00117 };
00118
00119
00120
00121 static bx_x11_gui_c* theGui = NULL;
00122 IMPLEMENT_GUI_PLUGIN_CODE(x11)
00123 #define MAX_MAPPED_STRING_LENGTH 10
00124
00125
00126
00127
00128 Display* bx_x_display;
00129 int bx_x_screen_num;
00130 static Visual* default_visual;
00131 static Colormap default_cmap;
00132 static unsigned long white_pixel = 0, black_pixel = 0;
00133
00134 static char* progname;
00135
00136 static unsigned int text_rows = 25, text_cols = 80;
00137 static u8 h_panning = 0, v_panning = 0;
00138 static u16 line_compare = 1023;
00139
00140 static Window win;
00141 static GC gc, gc_inv;
00142 static unsigned font_width, font_height;
00143 static unsigned dimension_x = 0, dimension_y = 0;
00144 static unsigned vga_bpp = 8;
00145
00146 static XImage* ximage = NULL;
00147 static unsigned imDepth, imWide, imBPP;
00148
00149
00150 static int prev_x = -1, prev_y = -1;
00151 static int current_x = -1, current_y = -1, current_z = 0;
00152 static unsigned mouse_button_state = 0;
00153 static bool CTRL_pressed = 0;
00154
00155 static unsigned prev_cursor_x = 0;
00156 static unsigned prev_cursor_y = 0;
00157
00158 static int warp_home_x = 200;
00159 static int warp_home_y = 200;
00160 static int mouse_enable_x = 0;
00161 static int mouse_enable_y = 0;
00162 static int warp_dx = 0;
00163 static int warp_dy = 0;
00164
00165 static void warp_cursor(int dx, int dy);
00166 static void disable_cursor();
00167 static void enable_cursor();
00168
00169 static u32 convertStringToXKeysym(const char* string);
00170
00171 static bool x_init_done = false;
00172
00173 static Pixmap vgafont[256];
00174
00175 static void send_keyboard_mouse_status(void);
00176
00177 static bool x_keymapping;
00178 static bool x_private_colormap;
00179
00180 u32 ascii_to_key_event[0x5f] = {
00181
00182 BX_KEY_SPACE,
00183 BX_KEY_1,
00184 BX_KEY_SINGLE_QUOTE,
00185 BX_KEY_3,
00186 BX_KEY_4,
00187 BX_KEY_5,
00188 BX_KEY_7,
00189 BX_KEY_SINGLE_QUOTE,
00190
00191
00192 BX_KEY_9,
00193 BX_KEY_0,
00194 BX_KEY_8,
00195 BX_KEY_EQUALS,
00196 BX_KEY_COMMA,
00197 BX_KEY_MINUS,
00198 BX_KEY_PERIOD,
00199 BX_KEY_SLASH,
00200
00201
00202 BX_KEY_0,
00203 BX_KEY_1,
00204 BX_KEY_2,
00205 BX_KEY_3,
00206 BX_KEY_4,
00207 BX_KEY_5,
00208 BX_KEY_6,
00209 BX_KEY_7,
00210
00211
00212 BX_KEY_8,
00213 BX_KEY_9,
00214 BX_KEY_SEMICOLON,
00215 BX_KEY_SEMICOLON,
00216 BX_KEY_COMMA,
00217 BX_KEY_EQUALS,
00218 BX_KEY_PERIOD,
00219 BX_KEY_SLASH,
00220
00221
00222 BX_KEY_2,
00223 BX_KEY_A,
00224 BX_KEY_B,
00225 BX_KEY_C,
00226 BX_KEY_D,
00227 BX_KEY_E,
00228 BX_KEY_F,
00229 BX_KEY_G,
00230
00231
00232 BX_KEY_H,
00233 BX_KEY_I,
00234 BX_KEY_J,
00235 BX_KEY_K,
00236 BX_KEY_L,
00237 BX_KEY_M,
00238 BX_KEY_N,
00239 BX_KEY_O,
00240
00241
00242 BX_KEY_P,
00243 BX_KEY_Q,
00244 BX_KEY_R,
00245 BX_KEY_S,
00246 BX_KEY_T,
00247 BX_KEY_U,
00248 BX_KEY_V,
00249 BX_KEY_W,
00250
00251
00252 BX_KEY_X,
00253 BX_KEY_Y,
00254 BX_KEY_Z,
00255 BX_KEY_LEFT_BRACKET,
00256 BX_KEY_BACKSLASH,
00257 BX_KEY_RIGHT_BRACKET,
00258 BX_KEY_6,
00259 BX_KEY_MINUS,
00260
00261
00262 BX_KEY_GRAVE,
00263 BX_KEY_A,
00264 BX_KEY_B,
00265 BX_KEY_C,
00266 BX_KEY_D,
00267 BX_KEY_E,
00268 BX_KEY_F,
00269 BX_KEY_G,
00270
00271
00272 BX_KEY_H,
00273 BX_KEY_I,
00274 BX_KEY_J,
00275 BX_KEY_K,
00276 BX_KEY_L,
00277 BX_KEY_M,
00278 BX_KEY_N,
00279 BX_KEY_O,
00280
00281
00282 BX_KEY_P,
00283 BX_KEY_Q,
00284 BX_KEY_R,
00285 BX_KEY_S,
00286 BX_KEY_T,
00287 BX_KEY_U,
00288 BX_KEY_V,
00289 BX_KEY_W,
00290
00291
00292 BX_KEY_X,
00293 BX_KEY_Y,
00294 BX_KEY_Z,
00295 BX_KEY_LEFT_BRACKET,
00296 BX_KEY_BACKSLASH,
00297 BX_KEY_RIGHT_BRACKET,
00298 BX_KEY_GRAVE
00299 };
00300
00301 extern u8 graphics_snapshot[32 * 1024];
00302
00303 static void create_internal_vga_font(void);
00304 static void xkeypress(KeySym keysym, int press_release);
00305
00306
00307 #define ROUNDUP(nbytes, pad) ((((nbytes) + ((pad) - 1)) / (pad)) * ((pad) >> 3))
00308 #define MAX_VGA_COLORS 256
00309
00310 unsigned long col_vals[MAX_VGA_COLORS];
00311 unsigned curr_foreground, curr_background;
00312
00313 static unsigned x_tilesize, y_tilesize;
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 static bool test_alloc_colors(Colormap cmap, u32 n_tries)
00326 {
00327 XColor color;
00328 unsigned long pixel[MAX_VGA_COLORS];
00329 bool pixel_valid[MAX_VGA_COLORS];
00330 u32 n_allocated = 0;
00331 u32 i;
00332 color.flags = DoRed | DoGreen | DoBlue;
00333 for(i = 0; i < n_tries; i++)
00334 {
00335
00336
00337
00338 color.red = ((i + 41) % MAX_VGA_COLORS) << 8;
00339 color.green = ((i + 42) % MAX_VGA_COLORS) << 8;
00340 color.blue = ((i + 43) % MAX_VGA_COLORS) << 8;
00341 pixel_valid[i] = false;
00342 if(XAllocColor(bx_x_display, cmap, &color))
00343 {
00344 pixel[i] = color.pixel;
00345 pixel_valid[i] = true;
00346 n_allocated++;
00347 }
00348 }
00349
00350 BX_INFO(("test_alloc_colors: %d colors available out of %d colors tried",
00351 n_allocated, n_tries));
00352
00353
00354 for(i = 0; i < n_tries; i++)
00355 {
00356 if(pixel_valid[i])
00357 XFreeColors(bx_x_display, cmap, &pixel[i], 1, 0);
00358 }
00359
00360 return(n_allocated == n_tries);
00361 }
00362
00363 void bx_x11_gui_c::specific_init(unsigned tilewidth, unsigned tileheight)
00364 {
00365 unsigned i;
00366 int x;
00367 int y;
00368 unsigned int border_width = 4;
00369 const char* window_name = "ES40 Emulator";
00370 const char* icon_name = "ES40";
00371 XSizeHints size_hints;
00372 char* display_name = NULL;
00373
00374
00375 unsigned long valuemask = 0;
00376 XGCValues values;
00377 int default_depth;
00378 XEvent report;
00379 XSetWindowAttributes win_attr;
00380 unsigned long plane_masks_return[1];
00381 XColor color;
00382
00383 x_tilesize = tilewidth;
00384 y_tilesize = tileheight;
00385
00386
00387 if((bx_x_display = XOpenDisplay(display_name)) == NULL)
00388 {
00389 BX_PANIC(("%s: cannot connect to X server %s", progname, XDisplayName(
00390 display_name)));
00391 }
00392
00393
00394 bx_x_screen_num = DefaultScreen(bx_x_display);
00395
00396
00397
00398
00399 x = y = 0;
00400
00401
00402 font_width = 8;
00403 font_height = 16;
00404
00405 dimension_x = text_cols * font_width;
00406 dimension_y = text_rows * font_height;
00407
00408
00409 win = XCreateSimpleWindow(bx_x_display,
00410 RootWindow(bx_x_display, bx_x_screen_num), x, y,
00411 dimension_x, dimension_y, border_width,
00412 BlackPixel(bx_x_display, bx_x_screen_num),
00413 BlackPixel(bx_x_display, bx_x_screen_num));
00414
00415
00416 win_attr.save_under = 1;
00417 win_attr.backing_store = Always;
00418 XChangeWindowAttributes(bx_x_display, win, CWSaveUnder | CWBackingStore,
00419 &win_attr);
00420
00421 default_depth = DefaultDepth(bx_x_display, bx_x_screen_num);
00422 default_visual = DefaultVisual(bx_x_display, bx_x_screen_num);
00423
00424 x_private_colormap = myCfg->get_bool_value("private_colormap", true);
00425 if(!x_private_colormap)
00426 {
00427
00428
00429 default_cmap = DefaultColormap(bx_x_display, bx_x_screen_num);
00430
00431
00432
00433
00434
00435 if(!test_alloc_colors(default_cmap, 16))
00436 {
00437 printf("xxx: I can't allocate 16 colors\n");
00438 x_private_colormap = true;
00439 }
00440
00441 col_vals[0] = BlackPixel(bx_x_display, bx_x_screen_num);
00442 col_vals[15] = WhitePixel(bx_x_display, bx_x_screen_num);
00443 for(i = 1; i < MAX_VGA_COLORS; i++)
00444 {
00445 if(i == 15)
00446 continue;
00447 col_vals[i] = col_vals[0];
00448 }
00449 }
00450
00451 if(x_private_colormap)
00452 {
00453
00454
00455 default_cmap = XCreateColormap(bx_x_display,
00456 DefaultRootWindow(bx_x_display),
00457 default_visual, AllocNone);
00458 if(XAllocColorCells(bx_x_display, default_cmap, False, plane_masks_return,
00459 0, col_vals, MAX_VGA_COLORS) == 0)
00460 {
00461 BX_PANIC(("XAllocColorCells returns error. Maybe your screen does not support a private colormap?"));
00462 }
00463
00464 win_attr.colormap = default_cmap;
00465 XChangeWindowAttributes(bx_x_display, win, CWColormap, &win_attr);
00466
00467 color.flags = DoRed | DoGreen | DoBlue;
00468
00469 for(i = 0; i < MAX_VGA_COLORS; i++)
00470 {
00471 color.pixel = i;
00472 if(i == 15)
00473 {
00474 color.red = 0xffff;
00475 color.green = 0xffff;
00476 color.blue = 0xffff;
00477 }
00478 else
00479 {
00480 color.red = 0;
00481 color.green = 0;
00482 color.blue = 0;
00483 }
00484
00485 XStoreColor(bx_x_display, default_cmap, &color);
00486 }
00487 }
00488
00489
00490 black_pixel = col_vals[0];
00491 white_pixel = col_vals[15];
00492
00493 BX_INFO(("font %u wide x %u high, display depth = %d", (unsigned) font_width,
00494 (unsigned) font_height, default_depth));
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509 size_hints.flags = PPosition | PSize | PMinSize | PMaxSize;
00510 size_hints.max_width = size_hints.min_width = dimension_x;
00511 size_hints.max_height = size_hints.min_height = dimension_y;
00512 {
00513 XWMHints wm_hints;
00514 XClassHint class_hints;
00515
00516
00517
00518
00519 XTextProperty windowName;
00520
00521
00522
00523
00524 XTextProperty iconName;
00525
00526
00527
00528
00529 if(XStringListToTextProperty((char**) &window_name, 1, &windowName) == 0)
00530 {
00531 BX_PANIC(("%s: structure allocation for windowName failed.", progname));
00532 }
00533
00534 if(XStringListToTextProperty((char**) &icon_name, 1, &iconName) == 0)
00535 {
00536 BX_PANIC(("%s: structure allocation for iconName failed.", progname));
00537 }
00538
00539 wm_hints.initial_state = NormalState;
00540 wm_hints.input = True;
00541 class_hints.res_name = progname;
00542 class_hints.res_class = (char*) "ES40 Emulator";
00543
00544 XSetWMProperties(bx_x_display, win, &windowName, &iconName, NULL ,
00545 0 , &size_hints, &wm_hints, &class_hints);
00546 XFree(windowName.value);
00547 XFree(iconName.value);
00548
00549 Atom wm_delete = XInternAtom(bx_x_display, "WM_DELETE_WINDOW", 1);
00550 XSetWMProtocols(bx_x_display, win, &wm_delete, 1);
00551 }
00552
00553
00554 XSelectInput(bx_x_display, win, ExposureMask | KeyPressMask | KeyReleaseMask |
00555 ButtonPressMask | ButtonReleaseMask | StructureNotifyMask |
00556 PointerMotionMask | EnterWindowMask | LeaveWindowMask);
00557
00558
00559 gc = XCreateGC(bx_x_display, win, valuemask, &values);
00560 gc_inv = XCreateGC(bx_x_display, win, valuemask, &values);
00561
00562 XSetState(bx_x_display, gc, white_pixel, black_pixel, GXcopy, AllPlanes);
00563
00564 XSetState(bx_x_display, gc_inv, black_pixel, white_pixel, GXinvert, AllPlanes);
00565
00566
00567 XMapWindow(bx_x_display, win);
00568 XSync(bx_x_display, 0);
00569
00570 BX_DEBUG(("waiting for MapNotify"));
00571 while(1)
00572 {
00573 XNextEvent(bx_x_display, &report);
00574 if(report.type == MapNotify)
00575 break;
00576 }
00577
00578 BX_DEBUG(("MapNotify found."));
00579
00580
00581 create_internal_vga_font();
00582 {
00583 char* imagedata;
00584
00585 ximage = XCreateImage(bx_x_display, default_visual,
00586 default_depth,
00587 ZPixmap, 0,
00588 NULL,
00589 x_tilesize, y_tilesize,
00590 32,
00591 0);
00592 if(!ximage)
00593 BX_PANIC(("vga: couldn't XCreateImage()"));
00594
00595 imDepth = default_depth;
00596 imWide = ximage->bytes_per_line;
00597 imBPP = ximage->bits_per_pixel;
00598
00599 imagedata = (char*) malloc((size_t) (ximage->bytes_per_line * y_tilesize));
00600 if(!imagedata)
00601 BX_PANIC(("imagedata: malloc returned error"));
00602
00603 ximage->data = imagedata;
00604
00605 if(imBPP < imDepth)
00606 {
00607 BX_PANIC(("vga_x: bits_per_pixel < depth ?"));
00608 }
00609
00610 x_init_done = true;
00611 }
00612
00613 curr_background = 0;
00614 XSetBackground(bx_x_display, gc, col_vals[curr_background]);
00615 curr_foreground = 1;
00616 XSetForeground(bx_x_display, gc, col_vals[curr_foreground]);
00617
00618
00619
00620 XFlush(bx_x_display);
00621
00622
00623 x_keymapping = myCfg->get_bool_value("keyboard.use_mapping", false);
00624 if(x_keymapping)
00625 {
00626
00627
00628 bx_keymap->loadKeymap(convertStringToXKeysym);
00629 }
00630
00631 new_gfx_api = 1;
00632 }
00633
00634
00635
00636
00637
00638
00639 void bx_x11_gui_c::mouse_enabled_changed_specific(bool val)
00640 {
00641 BX_DEBUG(("mouse_enabled=%d, x11 specific code", val ? 1 : 0));
00642 if(val)
00643 {
00644 BX_INFO(("[x] Mouse on"));
00645 mouse_enable_x = current_x;
00646 mouse_enable_y = current_y;
00647 disable_cursor();
00648
00649
00650 warp_cursor(warp_home_x - current_x, warp_home_y - current_y);
00651 }
00652 else
00653 {
00654 BX_INFO(("[x] Mouse off"));
00655 enable_cursor();
00656 warp_cursor(mouse_enable_x - current_x, mouse_enable_y - current_y);
00657 }
00658 }
00659
00663 void create_internal_vga_font(void)
00664 {
00665
00666
00667 font_width = 8;
00668 font_height = 16;
00669
00670 for(int i = 0; i < 256; i++)
00671 {
00672 vgafont[i] = XCreateBitmapFromData(bx_x_display, win,
00673 (const char*) bx_vgafont[i].data,
00674 font_width, font_height);
00675 if(vgafont[i] == None)
00676 BX_PANIC(("Can't create vga font [%d]", i));
00677 }
00678 }
00679
00680 void bx_x11_gui_c::handle_events(void)
00681 {
00682 XEvent report;
00683 XKeyEvent* key_event;
00684 KeySym keysym;
00685 XComposeStatus compose;
00686 char buffer[MAX_MAPPED_STRING_LENGTH];
00687 int bufsize = MAX_MAPPED_STRING_LENGTH;
00688 int charcount;
00689 bool mouse_update;
00690 int y;
00691 int height;
00692
00693 XPointerMovedEvent* pointer_event;
00694 XEnterWindowEvent* enter_event;
00695 XLeaveWindowEvent* leave_event;
00696 XButtonEvent* button_event;
00697 XExposeEvent* expose_event;
00698
00699
00700
00701 mouse_update = 0;
00702
00703 while(XPending(bx_x_display) > 0)
00704 {
00705 XNextEvent(bx_x_display, &report);
00706 current_z = 0;
00707 switch(report.type)
00708 {
00709 case Expose:
00710 expose_event = &report.xexpose;
00711
00712
00713 y = expose_event->y;
00714 height = expose_event->height;
00715 if(y < 0)
00716 {
00717 height += y;
00718 y = 0;
00719 }
00720
00721 theVGA->redraw_area((unsigned) expose_event->x, y,
00722 (unsigned) expose_event->width, height);
00723
00724 break;
00725
00726 case ConfigureNotify:
00727 BX_DEBUG(("ConfigureNotify Xevent"));
00728 break;
00729
00730 case ButtonPress:
00731 button_event = (XButtonEvent*) &report;
00732 BX_DEBUG(("xxx: buttonpress"));
00733 current_x = button_event->x;
00734 current_y = button_event->y;
00735 mouse_update = 1;
00736 BX_DEBUG(("xxx: x,y=(%d,%d)", current_x, current_y));
00737 switch(button_event->button)
00738 {
00739 case Button1:
00740 mouse_button_state |= 0x01;
00741 send_keyboard_mouse_status();
00742 mouse_update = 0;
00743 break;
00744
00745 case Button2:
00746 if(CTRL_pressed)
00747 {
00748
00749
00750 }
00751 else
00752 {
00753 mouse_button_state |= 0x04;
00754 send_keyboard_mouse_status();
00755 mouse_update = 0;
00756 }
00757 break;
00758
00759 case Button3:
00760 mouse_button_state |= 0x02;
00761 send_keyboard_mouse_status();
00762 mouse_update = 0;
00763 break;
00764 }
00765 break;
00766
00767 case ButtonRelease:
00768 button_event = (XButtonEvent*) &report;
00769 current_x = button_event->x;
00770 current_y = button_event->y;
00771 mouse_update = 1;
00772 switch(button_event->button)
00773 {
00774 case Button1:
00775 mouse_button_state &= ~0x01;
00776 send_keyboard_mouse_status();
00777 mouse_update = 0;
00778 break;
00779
00780 case Button2:
00781 mouse_button_state &= ~0x04;
00782 send_keyboard_mouse_status();
00783 mouse_update = 0;
00784 break;
00785
00786 case Button3:
00787 mouse_button_state &= ~0x02;
00788 send_keyboard_mouse_status();
00789 mouse_update = 0;
00790 break;
00791
00792 case Button4:
00793 current_z = 1;
00794 send_keyboard_mouse_status();
00795 mouse_update = 0;
00796 break;
00797
00798 case Button5:
00799 current_z = -1;
00800 send_keyboard_mouse_status();
00801 mouse_update = 0;
00802 break;
00803 }
00804 break;
00805
00806 case KeyPress:
00807 key_event = (XKeyEvent*) &report;
00808 charcount = XLookupString(key_event, buffer, bufsize, &keysym, &compose);
00809 xkeypress(keysym, 0);
00810 break;
00811
00812 case KeyRelease:
00813 key_event = (XKeyEvent*) &report;
00814 charcount = XLookupString(key_event, buffer, bufsize, &keysym, &compose);
00815 xkeypress(keysym, 1);
00816 break;
00817
00818 case MotionNotify:
00819 pointer_event = (XPointerMovedEvent*) &report;
00820 current_x = pointer_event->x;
00821 current_y = pointer_event->y;
00822 mouse_update = 1;
00823 break;
00824
00825 case EnterNotify:
00826 enter_event = (XEnterWindowEvent*) &report;
00827 prev_x = current_x = enter_event->x;
00828 prev_y = current_y = enter_event->y;
00829 break;
00830
00831 case LeaveNotify:
00832 leave_event = (XLeaveWindowEvent*) &report;
00833 prev_x = current_x = -1;
00834 prev_y = current_y = -1;
00835 break;
00836
00837 case MapNotify:
00838
00839
00840
00841
00842
00843
00844 break;
00845
00846 case ClientMessage:
00847 if(!strcmp(XGetAtomName(bx_x_display, report.xclient.message_type),
00848 "WM_PROTOCOLS"))
00849 {
00850 FAILURE(Graceful,"Emulator stopped from X");
00851
00852
00853 }
00854 break;
00855
00856 default:
00857
00858
00859 BX_DEBUG(("XXX: default Xevent type"));
00860
00861
00862
00863 break;
00864 }
00865 }
00866
00867 if(mouse_update)
00868 {
00869 BX_DEBUG(("handle_events(): send mouse status"));
00870 send_keyboard_mouse_status();
00871 }
00872 }
00873
00874 void send_keyboard_mouse_status(void)
00875 {
00876 BX_DEBUG(("XXX: prev=(%d,%d) curr=(%d,%d)", prev_x, prev_y, current_x, current_y));
00877
00878 if(((prev_x != -1) && (current_x != -1) && (prev_y != -1) && (current_y != -1)
00879 ) || (current_z != 0))
00880 {
00881 int dx;
00882
00883 int dy;
00884
00885 int dz;
00886
00887
00888 dx = current_x - prev_x - warp_dx;
00889 dy = -(current_y - prev_y - warp_dy);
00890 dz = current_z;
00891 warp_cursor(warp_home_x - current_x, warp_home_y - current_y);
00892
00893
00894 prev_x = current_x;
00895 prev_y = current_y;
00896 }
00897 else
00898 {
00899 if((current_x != -1) && (current_y != -1))
00900 {
00901 prev_x = current_x;
00902 prev_y = current_y;
00903 }
00904 else
00905 {
00906 prev_x = current_x = -1;
00907 prev_y = current_y = -1;
00908 }
00909 }
00910 }
00911
00912 void bx_x11_gui_c::flush(void)
00913 {
00914 if(bx_x_display)
00915 XFlush(bx_x_display);
00916 }
00917
00918 void xkeypress(KeySym keysym, int press_release)
00919 {
00920 u32 key_event;
00921
00922 if((keysym == XK_Control_L) || (keysym == XK_Control_R))
00923 {
00924 CTRL_pressed = !press_release;
00925 }
00926
00927
00928 if(!x_keymapping)
00929 {
00930
00931
00932
00933
00934
00935 if((keysym >= XK_space) && (keysym <= XK_asciitilde))
00936 {
00937 key_event = ascii_to_key_event[keysym - XK_space];
00938 }
00939 else
00940 {
00941 switch(keysym)
00942 {
00943 case XK_KP_1:
00944 #ifdef XK_KP_End
00945
00946 case XK_KP_End:
00947 #endif
00948 key_event = BX_KEY_KP_END;
00949 break;
00950
00951 case XK_KP_2:
00952 #ifdef XK_KP_Down
00953
00954 case XK_KP_Down:
00955 #endif
00956 key_event = BX_KEY_KP_DOWN;
00957 break;
00958
00959 case XK_KP_3:
00960 #ifdef XK_KP_Page_Down
00961
00962 case XK_KP_Page_Down:
00963 #endif
00964 key_event = BX_KEY_KP_PAGE_DOWN;
00965 break;
00966
00967 case XK_KP_4:
00968 #ifdef XK_KP_Left
00969
00970 case XK_KP_Left:
00971 #endif
00972 key_event = BX_KEY_KP_LEFT;
00973 break;
00974
00975 case XK_KP_5:
00976 #ifdef XK_KP_Begin
00977
00978 case XK_KP_Begin:
00979 #endif
00980 key_event = BX_KEY_KP_5;
00981 break;
00982
00983 case XK_KP_6:
00984 #ifdef XK_KP_Right
00985
00986 case XK_KP_Right:
00987 #endif
00988 key_event = BX_KEY_KP_RIGHT;
00989 break;
00990
00991 case XK_KP_7:
00992 #ifdef XK_KP_Home
00993
00994 case XK_KP_Home:
00995 #endif
00996 key_event = BX_KEY_KP_HOME;
00997 break;
00998
00999 case XK_KP_8:
01000 #ifdef XK_KP_Up
01001
01002 case XK_KP_Up:
01003 #endif
01004 key_event = BX_KEY_KP_UP;
01005 break;
01006
01007 case XK_KP_9:
01008 #ifdef XK_KP_Page_Up
01009
01010 case XK_KP_Page_Up:
01011 #endif
01012 key_event = BX_KEY_KP_PAGE_UP;
01013 break;
01014
01015 case XK_KP_0:
01016 #ifdef XK_KP_Insert
01017
01018 case XK_KP_Insert:
01019 #endif
01020 key_event = BX_KEY_KP_INSERT;
01021 break;
01022
01023 case XK_KP_Decimal:
01024 #ifdef XK_KP_Delete
01025
01026 case XK_KP_Delete:
01027 #endif
01028 key_event = BX_KEY_KP_DELETE;
01029 break;
01030
01031 #ifdef XK_KP_Enter
01032
01033 case XK_KP_Enter:
01034 key_event = BX_KEY_KP_ENTER;
01035 break;
01036 #endif
01037
01038 case XK_KP_Subtract:
01039 key_event = BX_KEY_KP_SUBTRACT;
01040 break;
01041
01042 case XK_KP_Add:
01043 key_event = BX_KEY_KP_ADD;
01044 break;
01045
01046 case XK_KP_Multiply:
01047 key_event = BX_KEY_KP_MULTIPLY;
01048 break;
01049
01050 case XK_KP_Divide:
01051 key_event = BX_KEY_KP_DIVIDE;
01052 break;
01053
01054 case XK_Up:
01055 key_event = BX_KEY_UP;
01056 break;
01057
01058 case XK_Down:
01059 key_event = BX_KEY_DOWN;
01060 break;
01061
01062 case XK_Left:
01063 key_event = BX_KEY_LEFT;
01064 break;
01065
01066 case XK_Right:
01067 key_event = BX_KEY_RIGHT;
01068 break;
01069
01070 case XK_Delete:
01071 key_event = BX_KEY_DELETE;
01072 break;
01073
01074 case XK_BackSpace:
01075 key_event = BX_KEY_BACKSPACE;
01076 break;
01077
01078 case XK_Tab:
01079 key_event = BX_KEY_TAB;
01080 break;
01081 #ifdef XK_ISO_Left_Tab
01082
01083 case XK_ISO_Left_Tab:
01084 key_event = BX_KEY_TAB;
01085 break;
01086 #endif
01087
01088 case XK_Return:
01089 key_event = BX_KEY_ENTER;
01090 break;
01091
01092 case XK_Escape:
01093 key_event = BX_KEY_ESC;
01094 break;
01095
01096 case XK_F1:
01097 key_event = BX_KEY_F1;
01098 break;
01099
01100 case XK_F2:
01101 key_event = BX_KEY_F2;
01102 break;
01103
01104 case XK_F3:
01105 key_event = BX_KEY_F3;
01106 break;
01107
01108 case XK_F4:
01109 key_event = BX_KEY_F4;
01110 break;
01111
01112 case XK_F5:
01113 key_event = BX_KEY_F5;
01114 break;
01115
01116 case XK_F6:
01117 key_event = BX_KEY_F6;
01118 break;
01119
01120 case XK_F7:
01121 key_event = BX_KEY_F7;
01122 break;
01123
01124 case XK_F8:
01125 key_event = BX_KEY_F8;
01126 break;
01127
01128 case XK_F9:
01129 key_event = BX_KEY_F9;
01130 break;
01131
01132 case XK_F10:
01133 key_event = BX_KEY_F10;
01134 break;
01135
01136 case XK_F11:
01137 key_event = BX_KEY_F11;
01138 break;
01139
01140 case XK_F12:
01141 key_event = BX_KEY_F12;
01142 break;
01143
01144 case XK_Control_L:
01145 key_event = BX_KEY_CTRL_L;
01146 break;
01147 #ifdef XK_Control_R
01148
01149 case XK_Control_R:
01150 key_event = BX_KEY_CTRL_R;
01151 break;
01152 #endif
01153
01154 case XK_Shift_L:
01155 key_event = BX_KEY_SHIFT_L;
01156 break;
01157
01158 case XK_Shift_R:
01159 key_event = BX_KEY_SHIFT_R;
01160 break;
01161
01162 case XK_Alt_L:
01163 key_event = BX_KEY_ALT_L;
01164 break;
01165 #ifdef XK_Alt_R
01166
01167 case XK_Alt_R:
01168 key_event = BX_KEY_ALT_R;
01169 break;
01170 #endif
01171
01172 case XK_Caps_Lock:
01173 key_event = BX_KEY_CAPS_LOCK;
01174 break;
01175
01176 case XK_Num_Lock:
01177 key_event = BX_KEY_NUM_LOCK;
01178 break;
01179 #ifdef XK_Scroll_Lock
01180
01181 case XK_Scroll_Lock:
01182 key_event = BX_KEY_SCRL_LOCK;
01183 break;
01184 #endif
01185 #ifdef XK_Print
01186
01187 case XK_Print:
01188 key_event = BX_KEY_PRINT;
01189 break;
01190 #endif
01191 #ifdef XK_Pause
01192
01193 case XK_Pause:
01194 key_event = BX_KEY_PAUSE;
01195 break;
01196 #endif
01197
01198 case XK_Insert:
01199 key_event = BX_KEY_INSERT;
01200 break;
01201
01202 case XK_Home:
01203 key_event = BX_KEY_HOME;
01204 break;
01205
01206 case XK_End:
01207 key_event = BX_KEY_END;
01208 break;
01209
01210 case XK_Page_Up:
01211 key_event = BX_KEY_PAGE_UP;
01212 break;
01213
01214 case XK_Page_Down:
01215 key_event = BX_KEY_PAGE_DOWN;
01216 break;
01217
01218 default:
01219 BX_ERROR(("xkeypress(): keysym %x unhandled!", (unsigned) keysym));
01220 return;
01221 break;
01222 }
01223 }
01224 }
01225 else
01226 {
01227
01228
01229 BXKeyEntry* entry = bx_keymap->findHostKey(keysym);
01230 if(!entry)
01231 {
01232 BX_ERROR(("xkeypress(): keysym %x unhandled!", (unsigned) keysym));
01233 return;
01234 }
01235
01236 key_event = entry->baseKey;
01237 }
01238
01239 if(press_release)
01240 key_event |= BX_KEY_RELEASED;
01241
01242 theKeyboard->gen_scancode(key_event);
01243 }
01244
01245 void bx_x11_gui_c::clear_screen(void)
01246 {
01247 XClearArea(bx_x_display, win, 0, 0, dimension_x, dimension_y, 0);
01248 }
01249
01250 void bx_x11_gui_c::text_update(u8* old_text, u8* new_text,
01251 unsigned long cursor_x, unsigned long cursor_y,
01252 bx_vga_tminfo_t tm_info, unsigned nrows)
01253 {
01254 u8* old_line;
01255
01256 u8 *new_line;
01257
01258 u8 *text_base;
01259 u8 cChar;
01260 unsigned int curs;
01261 unsigned int hchars;
01262 unsigned int i;
01263 unsigned int j;
01264 unsigned int offset;
01265 unsigned int rows;
01266 unsigned int x;
01267 unsigned int y;
01268 unsigned int xc;
01269 unsigned int yc;
01270 unsigned int yc2;
01271 unsigned int cs_y;
01272 unsigned new_foreground;
01273 unsigned new_background;
01274 u8 cfwidth;
01275 u8 cfheight;
01276 u8 cfheight2;
01277 u8 font_col;
01278 u8 font_row;
01279 u8 font_row2;
01280 u8 split_textrow;
01281 u8 split_fontrows;
01282 bool forceUpdate = 0;
01283 bool split_screen;
01284 unsigned char cell[64];
01285 unsigned long text_palette[16];
01286
01287 if(charmap_updated)
01288 {
01289 BX_INFO(("charmap update. Font Height is %d", font_height));
01290 for(unsigned c = 0; c < 256; c++)
01291 {
01292 if(char_changed[c])
01293 {
01294 XFreePixmap(bx_x_display, vgafont[c]);
01295
01296 bool gfxchar = tm_info.line_graphics && ((c & 0xE0) == 0xC0);
01297 j = 0;
01298 memset(cell, 0, sizeof(cell));
01299 for(i = 0; i < font_height * 2; i += 2)
01300 {
01301 cell[i] |= ((vga_charmap[(c << 5) + j] & 0x01) << 7);
01302 cell[i] |= ((vga_charmap[(c << 5) + j] & 0x02) << 5);
01303 cell[i] |= ((vga_charmap[(c << 5) + j] & 0x04) << 3);
01304 cell[i] |= ((vga_charmap[(c << 5) + j] & 0x08) << 1);
01305 cell[i] |= ((vga_charmap[(c << 5) + j] & 0x10) >> 1);
01306 cell[i] |= ((vga_charmap[(c << 5) + j] & 0x20) >> 3);
01307 cell[i] |= ((vga_charmap[(c << 5) + j] & 0x40) >> 5);
01308 cell[i] |= ((vga_charmap[(c << 5) + j] & 0x80) >> 7);
01309 if(gfxchar)
01310 {
01311 cell[i + 1] = (vga_charmap[(c << 5) + j] & 0x01);
01312 }
01313
01314 j++;
01315 }
01316
01317 vgafont[c] = XCreateBitmapFromData(bx_x_display, win, (const char*) cell,
01318 9, font_height);
01319 if(vgafont[c] == None)
01320 BX_PANIC(("Can't create vga font [%d]", c));
01321 char_changed[c] = 0;
01322 }
01323 }
01324
01325 forceUpdate = 1;
01326 charmap_updated = 0;
01327 }
01328
01329 for(i = 0; i < 16; i++)
01330 {
01331 text_palette[i] = col_vals[theVGA->get_actl_palette_idx(i)];
01332 }
01333
01334 if((tm_info.h_panning != h_panning) || (tm_info.v_panning != v_panning))
01335 {
01336 forceUpdate = 1;
01337 h_panning = tm_info.h_panning;
01338 v_panning = tm_info.v_panning;
01339 }
01340
01341 if(tm_info.line_compare != line_compare)
01342 {
01343 forceUpdate = 1;
01344 line_compare = tm_info.line_compare;
01345 }
01346
01347
01348 if((prev_cursor_y < text_rows) && (prev_cursor_x < text_cols))
01349 {
01350 curs = prev_cursor_y * tm_info.line_offset + prev_cursor_x * 2;
01351 old_text[curs] = ~new_text[curs];
01352 }
01353
01354 if((tm_info.cs_start <= tm_info.cs_end) && (tm_info.cs_start < font_height)
01355 && (cursor_y < text_rows) && (cursor_x < text_cols))
01356 {
01357 curs = cursor_y * tm_info.line_offset + cursor_x * 2;
01358 old_text[curs] = ~new_text[curs];
01359 }
01360 else
01361 {
01362 curs = 0xffff;
01363 }
01364
01365 rows = text_rows;
01366 if(v_panning)
01367 rows++;
01368 y = 0;
01369 cs_y = 0;
01370 text_base = new_text - tm_info.start_address;
01371 split_textrow = (line_compare + v_panning) / font_height;
01372 split_fontrows = ((line_compare + v_panning) % font_height) + 1;
01373 split_screen = 0;
01374 do
01375 {
01376 hchars = text_cols;
01377 if(h_panning)
01378 hchars++;
01379 if(split_screen)
01380 {
01381 yc = line_compare + cs_y * font_height + 1;
01382 font_row = 0;
01383 if(rows == 1)
01384 {
01385 cfheight = (dimension_y - line_compare - 1) % font_height;
01386 if(cfheight == 0)
01387 cfheight = font_height;
01388 }
01389 else
01390 {
01391 cfheight = font_height;
01392 }
01393 }
01394 else if(v_panning)
01395 {
01396 if(y == 0)
01397 {
01398 yc = 0;
01399 font_row = v_panning;
01400 cfheight = font_height - v_panning;
01401 }
01402 else
01403 {
01404 yc = y * font_height - v_panning;
01405 font_row = 0;
01406 if(rows == 1)
01407 {
01408 cfheight = v_panning;
01409 }
01410 else
01411 {
01412 cfheight = font_height;
01413 }
01414 }
01415 }
01416 else
01417 {
01418 yc = y * font_height;
01419 font_row = 0;
01420 cfheight = font_height;
01421 }
01422
01423 if(!split_screen && (y == split_textrow))
01424 {
01425 if(split_fontrows < cfheight)
01426 cfheight = split_fontrows;
01427 }
01428
01429 new_line = new_text;
01430 old_line = old_text;
01431 x = 0;
01432 offset = cs_y * tm_info.line_offset;
01433 do
01434 {
01435 if(h_panning)
01436 {
01437 if(hchars > text_cols)
01438 {
01439 xc = 0;
01440 font_col = h_panning;
01441 cfwidth = font_width - h_panning;
01442 }
01443 else
01444 {
01445 xc = x * font_width - h_panning;
01446 font_col = 0;
01447 if(hchars == 1)
01448 {
01449 cfwidth = h_panning;
01450 }
01451 else
01452 {
01453 cfwidth = font_width;
01454 }
01455 }
01456 }
01457 else
01458 {
01459 xc = x * font_width;
01460 font_col = 0;
01461 cfwidth = font_width;
01462 }
01463
01464 if(forceUpdate || (old_text[0] != new_text[0])
01465 || (old_text[1] != new_text[1]))
01466 {
01467 cChar = new_text[0];
01468 new_foreground = new_text[1] & 0x0f;
01469 new_background = (new_text[1] & 0xf0) >> 4;
01470
01471 XSetForeground(bx_x_display, gc, text_palette[new_foreground]);
01472 XSetBackground(bx_x_display, gc, text_palette[new_background]);
01473
01474 XCopyPlane(bx_x_display, vgafont[cChar], win, gc, font_col, font_row,
01475 cfwidth, cfheight, xc, yc, 1);
01476 if(offset == curs)
01477 {
01478 XSetForeground(bx_x_display, gc, text_palette[new_background]);
01479 XSetBackground(bx_x_display, gc, text_palette[new_foreground]);
01480 if(font_row == 0)
01481 {
01482 yc2 = yc + tm_info.cs_start;
01483 font_row2 = tm_info.cs_start;
01484 cfheight2 = tm_info.cs_end - tm_info.cs_start + 1;
01485 if((yc2 + cfheight2) > (dimension_y))
01486 {
01487 cfheight2 = dimension_y - yc2;
01488 }
01489 }
01490 else
01491 {
01492 if(v_panning > tm_info.cs_start)
01493 {
01494 yc2 = yc;
01495 font_row2 = font_row;
01496 cfheight2 = tm_info.cs_end - v_panning + 1;
01497 }
01498 else
01499 {
01500 yc2 = yc + tm_info.cs_start - v_panning;
01501 font_row2 = tm_info.cs_start;
01502 cfheight2 = tm_info.cs_end - tm_info.cs_start + 1;
01503 }
01504 }
01505
01506 if(yc2 < (dimension_y))
01507 {
01508 XCopyPlane(bx_x_display, vgafont[cChar], win, gc, font_col,
01509 font_row2, cfwidth, cfheight2, xc, yc2, 1);
01510 }
01511 }
01512 }
01513
01514 x++;
01515 new_text += 2;
01516 old_text += 2;
01517 offset += 2;
01518 } while(--hchars);
01519 if(!split_screen && (y == split_textrow))
01520 {
01521 new_text = text_base;
01522 forceUpdate = 1;
01523 cs_y = 0;
01524 if(tm_info.split_hpanning)
01525 h_panning = 0;
01526 rows = ((dimension_y - line_compare + font_height - 2) / font_height) + 1;
01527 split_screen = 1;
01528 }
01529 else
01530 {
01531 y++;
01532 cs_y++;
01533 new_text = new_line + tm_info.line_offset;
01534 old_text = old_line + tm_info.line_offset;
01535 }
01536 } while(--rows);
01537
01538 h_panning = tm_info.h_panning;
01539 prev_cursor_x = cursor_x;
01540 prev_cursor_y = cursor_y;
01541
01542 XFlush(bx_x_display);
01543 }
01544
01545 void bx_x11_gui_c::graphics_tile_update(u8* tile, unsigned x0, unsigned y0)
01546 {
01547 unsigned x;
01548
01549 unsigned y;
01550
01551 unsigned y_size;
01552 unsigned color;
01553 unsigned offset;
01554 u8 b0;
01555 u8 b1;
01556 u8 b2;
01557 u8 b3;
01558
01559 if((y0 + y_tilesize) > dimension_y)
01560 {
01561 y_size = dimension_y - y0;
01562 }
01563 else
01564 {
01565 y_size = y_tilesize;
01566 }
01567
01568 switch(vga_bpp)
01569 {
01570 case 8:
01571 for(y = 0; y < y_size; y++)
01572 {
01573 for(x = 0; x < x_tilesize; x++)
01574 {
01575 color = col_vals[tile[y * x_tilesize + x]];
01576 switch(imBPP)
01577 {
01578 case 8:
01579 ximage->data[imWide * y + x] = color;
01580 break;
01581
01582 case 16:
01583 offset = imWide * y + 2 * x;
01584 b0 = color >> 0;
01585 b1 = color >> 8;
01586 if(ximage->byte_order == LSBFirst)
01587 {
01588 ximage->data[offset + 0] = b0;
01589 ximage->data[offset + 1] = b1;
01590 }
01591 else
01592 {
01593 ximage->data[offset + 0] = b1;
01594 ximage->data[offset + 1] = b0;
01595 }
01596 break;
01597
01598 case 24:
01599 offset = imWide * y + 3 * x;
01600 b0 = color >> 0;
01601 b1 = color >> 8;
01602 b2 = color >> 16;
01603 if(ximage->byte_order == LSBFirst)
01604 {
01605 ximage->data[offset + 0] = b0;
01606 ximage->data[offset + 1] = b1;
01607 ximage->data[offset + 2] = b2;
01608 }
01609 else
01610 {
01611 ximage->data[offset + 0] = b2;
01612 ximage->data[offset + 1] = b1;
01613 ximage->data[offset + 2] = b0;
01614 }
01615 break;
01616
01617 case 32:
01618 offset = imWide * y + 4 * x;
01619 b0 = color >> 0;
01620 b1 = color >> 8;
01621 b2 = color >> 16;
01622 b3 = color >> 24;
01623 if(ximage->byte_order == LSBFirst)
01624 {
01625 ximage->data[offset + 0] = b0;
01626 ximage->data[offset + 1] = b1;
01627 ximage->data[offset + 2] = b2;
01628 ximage->data[offset + 3] = b3;
01629 }
01630 else
01631 {
01632 ximage->data[offset + 0] = b3;
01633 ximage->data[offset + 1] = b2;
01634 ximage->data[offset + 2] = b1;
01635 ximage->data[offset + 3] = b0;
01636 }
01637 break;
01638
01639 default:
01640 BX_PANIC((
01641 "X_graphics_tile_update: bits_per_pixel %u not implemented",
01642 (unsigned) imBPP));
01643 return;
01644 }
01645 }
01646 }
01647 break;
01648
01649 default:
01650 BX_PANIC((
01651 "X_graphics_tile_update: bits_per_pixel %u handled by new graphics API",
01652 (unsigned) vga_bpp));
01653 return;
01654 }
01655
01656 XPutImage(bx_x_display, win, gc, ximage, 0, 0, x0, y0, x_tilesize, y_size);
01657 }
01658
01659 bx_svga_tileinfo_t* bx_x11_gui_c::graphics_tile_info(bx_svga_tileinfo_t* info)
01660 {
01661 if(!info)
01662 {
01663 info = (bx_svga_tileinfo_t*) malloc(sizeof(bx_svga_tileinfo_t));
01664 if(!info)
01665 {
01666 return NULL;
01667 }
01668 }
01669
01670 info->bpp = ximage->bits_per_pixel;
01671 info->pitch = ximage->bytes_per_line;
01672 info->red_shift = 0;
01673 info->green_shift = 0;
01674 info->blue_shift = 0;
01675 info->red_mask = ximage->red_mask;
01676 info->green_mask = ximage->green_mask;
01677 info->blue_mask = ximage->blue_mask;
01678
01679 int i;
01680
01681 int rf;
01682
01683 int gf;
01684
01685 int bf;
01686 unsigned long red;
01687 unsigned long green;
01688 unsigned long blue;
01689
01690 i = rf = gf = bf = 0;
01691 red = ximage->red_mask;
01692 green = ximage->green_mask;
01693 blue = ximage->blue_mask;
01694
01695 while(red || rf || green || gf || blue || bf)
01696 {
01697 if(rf)
01698 {
01699 if(!(red & 1))
01700 {
01701 info->red_shift = i;
01702 rf = 0;
01703 }
01704 }
01705 else
01706 {
01707 if(red & 1)
01708 {
01709 rf = 1;
01710 }
01711 }
01712
01713 if(gf)
01714 {
01715 if(!(green & 1))
01716 {
01717 info->green_shift = i;
01718 gf = 0;
01719 }
01720 }
01721 else
01722 {
01723 if(green & 1)
01724 {
01725 gf = 1;
01726 }
01727 }
01728
01729 if(bf)
01730 {
01731 if(!(blue & 1))
01732 {
01733 info->blue_shift = i;
01734 bf = 0;
01735 }
01736 }
01737 else
01738 {
01739 if(blue & 1)
01740 {
01741 bf = 1;
01742 }
01743 }
01744
01745 i++;
01746 red >>= 1;
01747 green >>= 1;
01748 blue >>= 1;
01749 }
01750
01751 info->is_indexed = (default_visual->c_class != TrueColor)
01752 && (default_visual->c_class != DirectColor);
01753 info->is_little_endian = (ximage->byte_order == LSBFirst);
01754
01755 return info;
01756 }
01757
01758 u8* bx_x11_gui_c::graphics_tile_get(unsigned x0, unsigned y0, unsigned* w,
01759 unsigned* h)
01760 {
01761 if(x0 + x_tilesize > dimension_x)
01762 {
01763 *w = dimension_x - x0;
01764 }
01765 else
01766 {
01767 *w = x_tilesize;
01768 }
01769
01770 if(y0 + y_tilesize > dimension_y)
01771 {
01772 *h = dimension_y - y0;
01773 }
01774 else
01775 {
01776 *h = y_tilesize;
01777 }
01778
01779 return (u8*) ximage->data + ximage->xoffset * ximage->bits_per_pixel / 8;
01780 }
01781
01782 void bx_x11_gui_c::graphics_tile_update_in_place(unsigned x0, unsigned y0,
01783 unsigned w, unsigned h)
01784 {
01785 XPutImage(bx_x_display, win, gc, ximage, 0, 0, x0, y0, w, h);
01786 }
01787
01788 bool bx_x11_gui_c::palette_change(unsigned index, unsigned red, unsigned green,
01789 unsigned blue)
01790 {
01791
01792
01793
01794 XColor color;
01795
01796 color.flags = DoRed | DoGreen | DoBlue;
01797 color.red = red << 8;
01798 color.green = green << 8;
01799 color.blue = blue << 8;
01800
01801 if(x_private_colormap)
01802 {
01803
01804
01805 color.pixel = index;
01806 XStoreColor(bx_x_display, default_cmap, &color);
01807 return(0);
01808 }
01809 else
01810 {
01811 XAllocColor(bx_x_display, DefaultColormap(bx_x_display, bx_x_screen_num),
01812 &color);
01813 col_vals[index] = color.pixel;
01814 return(1);
01815 }
01816 }
01817
01818 void bx_x11_gui_c::dimension_update(unsigned x, unsigned y, unsigned fheight,
01819 unsigned fwidth, unsigned bpp)
01820 {
01821 if((bpp == 8) || (bpp == 15) || (bpp == 16) || (bpp == 24) || (bpp == 32))
01822 {
01823 vga_bpp = bpp;
01824 }
01825 else
01826 {
01827 BX_PANIC(("%d bpp graphics mode not supported", bpp));
01828 }
01829
01830 if(fheight > 0)
01831 {
01832 font_height = fheight;
01833 font_width = fwidth;
01834 text_cols = x / font_width;
01835 text_rows = y / font_height;
01836 }
01837
01838 if((x != dimension_x) || (y != dimension_y))
01839 {
01840 XSizeHints hints;
01841 long supplied_return;
01842
01843 if(XGetWMNormalHints(bx_x_display, win, &hints, &supplied_return)
01844 && supplied_return & PMaxSize)
01845 {
01846 hints.max_width = hints.min_width = x;
01847 hints.max_height = hints.min_height = y;
01848 XSetWMNormalHints(bx_x_display, win, &hints);
01849 }
01850
01851 XResizeWindow(bx_x_display, win, x, y);
01852 dimension_x = x;
01853 dimension_y = y;
01854 }
01855 }
01856
01857 void bx_x11_gui_c::exit(void)
01858 {
01859 if(!x_init_done)
01860 return;
01861
01862
01863 for(int i = 0; i < 256; i++)
01864 {
01865
01866
01867 XFreePixmap(bx_x_display, vgafont[i]);
01868 }
01869
01870 if(bx_x_display)
01871 XCloseDisplay(bx_x_display);
01872 BX_INFO(("Exit."));
01873 }
01874
01875 static void warp_cursor(int dx, int dy)
01876 {
01877 if(warp_dx || warp_dy || dx || dy)
01878 {
01879 warp_dx = dx;
01880 warp_dy = dy;
01881 XWarpPointer(bx_x_display, None, None, 0, 0, 0, 0, dx, dy);
01882 }
01883 }
01884
01885 static void disable_cursor()
01886 {
01887 static Cursor cursor;
01888 static unsigned cursor_created = 0;
01889
01890 static int shape_width = 16;
01891 static int shape_height = 16;
01892 static int mask_width = 16;
01893 static int mask_height = 16;
01894
01895 static u32 shape_bits[(16 * 16) / 32] = {
01896 0x00000000, 0x00000000, 0x00000000, 0x00000000,
01897 0x00000000, 0x00000000, 0x00000000, 0x00000000,
01898 };
01899 static u32 mask_bits[(16 * 16) / 32] = {
01900 0x00000000, 0x00000000, 0x00000000, 0x00000000,
01901 0x00000000, 0x00000000, 0x00000000, 0x00000000,
01902 };
01903
01904 if(!cursor_created)
01905 {
01906 Pixmap shape;
01907
01908 Pixmap mask;
01909 XColor white;
01910 XColor black;
01911 shape = XCreatePixmapFromBitmapData(bx_x_display,
01912 RootWindow(bx_x_display, bx_x_screen_num),
01913 (char*) shape_bits, shape_width,
01914 shape_height, 1, 0, 1);
01915 mask = XCreatePixmapFromBitmapData(bx_x_display,
01916 RootWindow(bx_x_display, bx_x_screen_num),
01917 (char*) mask_bits, mask_width,
01918 mask_height, 1, 0, 1);
01919 XParseColor(bx_x_display, default_cmap, "black", &black);
01920 XParseColor(bx_x_display, default_cmap, "white", &white);
01921 cursor = XCreatePixmapCursor(bx_x_display, shape, mask, &white, &black, 1, 1);
01922 cursor_created = 1;
01923 }
01924
01925 XDefineCursor(bx_x_display, win, cursor);
01926 }
01927
01928 static void enable_cursor()
01929 {
01930 XUndefineCursor(bx_x_display, win);
01931 }
01932
01933
01934
01935
01936
01937
01938
01939 static u32 convertStringToXKeysym(const char* string)
01940 {
01941 if(strncmp("XK_", string, 3) != 0)
01942 return BX_KEYMAP_UNKNOWN;
01943
01944 KeySym keysym = XStringToKeysym(string + 3);
01945
01946
01947 if(keysym == NoSymbol)
01948 return BX_KEYMAP_UNKNOWN;
01949
01950 return((u32) keysym);
01951 }
01952
01953 void bx_x11_gui_c::get_capabilities(u16* xres, u16* yres, u16* bpp)
01954 {
01955 *xres = 1024;
01956 *yres = 768;
01957 *bpp = 32;
01958 }
01959 #endif