---------------------------------------------------------------------- Patch name: patch.beos-gui-fabo Author: Marton Fabo Date: Thu, 6 Dec 2001 19:52:18 +0100 (CET) Detailed description: I grabbed the CVS snapshot of 20011129, started with the BeOS GUI code found in it, rewrote it totally (almost no original code left), and I now have a Bochs that runs under BeOS quite nicely. New features compared to the BeOS GUI code found in the above snapshot: - color support in text mode (not perfect yet, but not BW at least) - almost full keyboard capturing (modifier keys work, function keys also, keypad, arrow keys work, capslock doesn't work properly, numlock not at all. I need some help about how to tell Bochs to switch those properly) - full mouse capturing, it works quite great! Also see beos-gui-fabo.capture-filter and the associated README. I updated this patch file to make it apply with the current CVS version. I have added the cursor size and cursor hide feature for BeOS. The copy/paste functions are still to do. The capture filter works now - we have only the binary in this directory, but not the source. -Volker Patch was created with: diff -u Apply patch to what version: gui/beos r1.16 Instructions: To patch, go to main bochs directory. Type "patch -p0 < THIS_PATCH_FILE". ---------------------------------------------------------------------- --- gui/beos.cc Sat Apr 20 09:19:35 2002 +++ gui/beos.cc Tue Jul 9 20:19:33 2002 @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -39,1179 +40,1279 @@ #include #include "bochs.h" -//#include "icon_bochs.h" +// #include "icon_bochs.h" #include "font/vga.bitmap.h" #define LOG_THIS bx_gui. -#define PAD_NEAREST(n, quantum) (( ((n) + ((quantum) - 1)) / (n) ) * (n)) +#undef uint8 +#undef int32 +#undef uint32 + +#define BOCHS_APP_SIG "application/x-vnd.MandrakeSoft-BeBochs" +#define SCANCODE_BUFSIZE 20 +#define MOUSE_BUFSIZE 20 +#define MOUSE_L 0x00000001 +#define MOUSE_R 0x00000002 +#define INITIAL_SCREEN_WIDTH 640 +#define INITIAL_SCREEN_HEIGHT 350 + +const uint32 MSG_REQUEST_CAPTURE = 'CFrq'; +const uint32 MSG_START_CAPTURE = 'strt'; +const uint32 MSG_ALREADY_CAPTURING = 'CFac'; +const uint32 MSG_CAPTURE_OK = 'CFok'; +const uint32 MSG_BAD_MESSAGE = 'CFbm'; +const uint32 MSG_STOP_CAPTURE = 'stop'; + +const uint32 INPUT_TYPE_KEYBOARD = 0x00000001; +const uint32 INPUT_TYPE_MOUSE = 0x00000002; + +const uint32 MSG_ENQ_COMMAND = 'BCec'; + +// ========== STRUCTS ========== + +struct mouse_event +{ + mouse_event() { } + mouse_event(uint32 X, uint32 Y, uint32 buttons): + x(X), y(Y), buttonState(buttons) { } + uint32 x; + uint32 y; + uint32 buttonState; +}; + +// ========== CLASSES ========== + +#define QUEUECLASS(ClassName, ContentType) class ClassName \ +{ \ +public: \ + ClassName(uint32 maxItems, const char *name): \ + fMaxItems(maxItems), \ + fHead(0), \ + fTail(0) \ + { \ + fItems = new ContentType[fMaxItems]; \ + fName = strdup(name); \ + } \ + ~ClassName() \ + { \ + delete [] fItems; \ + delete fName; \ + } \ + bool Enq(const ContentType &item) \ + { \ + if ( ((fTail + 1) % fMaxItems) == fHead ) \ + { \ + BX_DEBUG(("%s enqueue: buffer full", fName)); \ + return false; \ + } \ + fItems[fTail] = item; \ + fTail = (fTail + 1) % fMaxItems; \ + return true; \ + } \ + bool Deq(ContentType *item) \ + { \ + if ( fHead == fTail ) \ + { \ + BX_DEBUG(("%s dequeue: buffer empty", fName)); \ + return false; \ + } \ + *item = fItems[fHead]; \ + fHead = (fHead + 1) % fMaxItems; \ + return true; \ + } \ + bool QueueEmpty() { return (fHead == fTail); } \ + uint32 ItemCount() { return (fTail > fHead) ? fTail - fHead : fHead + fMaxItems - fTail; } \ + ContentType &ItemAt(uint32 index) { return fItems[(fHead + index) % fMaxItems]; } \ +private: \ + ContentType *fItems; \ + uint32 fMaxItems; \ + uint32 fHead; \ + uint32 fTail; \ + const char *fName; \ +} \ + +QUEUECLASS(KeyQueue, uint32); +QUEUECLASS(MouseQueue, mouse_event); +typedef void (*handler_func)(void); +QUEUECLASS(CommandQueue, handler_func); +class BochsApplication: public BApplication +{ +public: + BochsApplication(bx_gui_c *bxGui, int argc, char **argv, + uint32 tileWidth, uint32 tileHeight, uint32 headerBarHeight, handler_func powerHandlerFunc); + ~BochsApplication(); + static int32 runme(void *data); + virtual bool QuitRequested(); + virtual void Quit(); + void BxExit(); +private: + handler_func fPowerHandlerFunc; +}; - -class BochsApplication : public BApplication { - +class BochsWindow: public BWindow +{ public: - BochsApplication(); - }; + BochsWindow(BRect frame); + virtual bool QuitRequested(); +}; -class BochsWindow : public BWindow { +class BochsView: public BView { +public: + BochsView(BRect frame, char *name, uint32 headerHeight, uint32 tileWidth, uint32 tileHeight); + ~BochsView(); + virtual void AttachedToWindow(); + virtual void DetachedFromWindow(); + virtual void Draw(BRect updateRect); + virtual void KeyDown(const char *bytes, int32 numBytes); + virtual void KeyUp(const char *bytes, int32 numBytes); + virtual void MouseDown(BPoint point); + virtual void MouseUp(BPoint point); + virtual void MouseMoved(BPoint point, uint32 transit, const BMessage *message); + virtual void MessageReceived(BMessage *msg); + virtual void WindowActivated(bool active); + virtual void Pulse(); + void HandleEvents(); + void ClearScreen(); + void TextUpdate(uint8 *oldText, uint8 *newText, + uint32 cursorX, uint32 cursorY, uint32 rowCount, + uint32 cursorShape); + void GraphicsTileUpdate(uint8 *tile, uint32 xPos, uint32 yPos); + bool PaletteChange(uint32 index, uint32 red, uint32 green, uint32 blue); + void DimensionUpdate(uint32 x, uint32 y, uint32 fheight); + void HandleEnableMouse(bool enable); + uint32 CreateBitmap(const uchar *bitmap, uint32 width, uint32 height); + uint32 HeaderbarBitmap(uint32 bitmapID, uint32 alignment, void (*f)(void)); + void ReplaceBitmap(uint32 headerBarID, uint32 bitmapID); + void ShowHeaderbar(); + void GotCapturedInput(BMessage *msg); + static void release_mouse(); + +private: + void ShowCursor(bool show); + uchar ReverseBitorder(uchar b); + void CaptureInput(); + void ReleaseInput(); + + BBitmap *fBackBitmap; + BView *fBackView; + uint32 fLastModifiers; + uint32 fLastMouseX, fLastMouseY; + uint32 fCursorX, fCursorY; + uint8 fCursorValue[2]; + uint8 fCursorStart; + uint8 fCursorEnd; + bool fCursorHide; + bool fCursorVisible; + bool fInTextMode; + BScreen fScreen; + uint8 fColorMap[256]; // indices into system colormap + BBitmap *fVgafont[256]; + BBitmap *fCursorBitmap; + uint32 fTileWidth; + uint32 fTileHeight; + bool fUseStandardInput; + bool fMouseEnabled; + BHandler *fCaptureTarget; + + KeyQueue fKeyQueue; + MouseQueue fMouseQueue; + CommandQueue fCommandQueue; + + struct + { + BBitmap *bmap; + unsigned xdim; + unsigned ydim; + } fBitmaps[BX_MAX_PIXMAPS]; + uint32 fBitmapCount; + + struct + { + BBitmap *bitmap; + unsigned xdim; + unsigned ydim; + unsigned xorigin; + unsigned yorigin; + unsigned alignment; + void (*f)(void); + } fHeaderEntries[BX_MAX_HEADERBAR_ENTRIES]; + uint32 fHeaderEntryCount; + + uint32 fHeaderHeight; + uint32 fHeaderLeft; // pixels from left + uint32 fHeaderRight; // pixels from right +}; +class ModifierFilter: public BMessageFilter +{ public: - BochsWindow(BRect frame); - virtual bool QuitRequested(); - virtual void FrameResized(float width, float height); - }; + ModifierFilter(BHandler *target); + virtual filter_result Filter(BMessage *msg, BHandler **target); +private: + BHandler *fTarget; +}; -class BochsView : public BView { +class CaptureTarget: public BHandler +{ +public: + CaptureTarget(BochsView *myTarget): fMyTarget(myTarget) { } + virtual void MessageReceived(BMessage *msg); private: - BBitmap *backing_store; - BView *backing_view; + BochsView *fMyTarget; +}; + +// ========== GLOBAL DATA ========== + +static BochsApplication *bApp = NULL; +static BochsView *bView = NULL; + +// ========== keytable ========== + +static const uint8 key_to_scancode[] = { + 0, + BX_KEY_ESC, + BX_KEY_F1, + BX_KEY_F2, + BX_KEY_F3, + BX_KEY_F4, + BX_KEY_F5, + BX_KEY_F6, + BX_KEY_F7, + BX_KEY_F8, + BX_KEY_F9, + BX_KEY_F10, + BX_KEY_F11, + BX_KEY_F12, + BX_KEY_PRINT, + BX_KEY_SCRL_LOCK, + BX_KEY_PAUSE, /*0x10*/ + BX_KEY_GRAVE, + BX_KEY_1, + BX_KEY_2, + BX_KEY_3, + BX_KEY_4, + BX_KEY_5, + BX_KEY_6, + BX_KEY_7, + BX_KEY_8, + BX_KEY_9, + BX_KEY_0, + BX_KEY_MINUS, + BX_KEY_EQUALS, + BX_KEY_BACKSPACE, + BX_KEY_INSERT, + BX_KEY_HOME, /*0x20*/ + BX_KEY_PAGE_UP, + BX_KEY_NUM_LOCK, + BX_KEY_KP_DIVIDE, + BX_KEY_KP_MULTIPLY, + BX_KEY_KP_SUBTRACT, + BX_KEY_TAB, + BX_KEY_Q, + BX_KEY_W, + BX_KEY_E, + BX_KEY_R, + BX_KEY_T, + BX_KEY_Y, + BX_KEY_U, + BX_KEY_I, + BX_KEY_O, + BX_KEY_P, /*0x30*/ + BX_KEY_LEFT_BRACKET, + BX_KEY_RIGHT_BRACKET, + BX_KEY_BACKSLASH, + BX_KEY_DELETE, + BX_KEY_END, + BX_KEY_PAGE_DOWN, + BX_KEY_KP_HOME, + BX_KEY_KP_UP, + BX_KEY_KP_PAGE_UP, + BX_KEY_KP_ADD, + BX_KEY_CAPS_LOCK, + BX_KEY_A, + BX_KEY_S, + BX_KEY_D, + BX_KEY_F, + BX_KEY_G, /*0x40*/ + BX_KEY_H, + BX_KEY_J, + BX_KEY_K, + BX_KEY_L, + BX_KEY_SEMICOLON, + BX_KEY_SINGLE_QUOTE, + BX_KEY_ENTER, + BX_KEY_KP_LEFT, + BX_KEY_KP_5, + BX_KEY_KP_RIGHT, + BX_KEY_SHIFT_L, + BX_KEY_Z, + BX_KEY_X, + BX_KEY_C, + BX_KEY_V, + BX_KEY_B, /*0x50*/ + BX_KEY_N, + BX_KEY_M, + BX_KEY_COMMA, + BX_KEY_PERIOD, + BX_KEY_SLASH, + BX_KEY_SHIFT_R, + BX_KEY_UP, + BX_KEY_KP_END, + BX_KEY_KP_DOWN, + BX_KEY_KP_PAGE_DOWN, + BX_KEY_KP_ENTER, + BX_KEY_CTRL_L, + BX_KEY_ALT_L, + BX_KEY_SPACE, + BX_KEY_ALT_R, + BX_KEY_CTRL_R, /*0x60*/ + BX_KEY_LEFT, + BX_KEY_DOWN, + BX_KEY_RIGHT, + BX_KEY_KP_INSERT, + BX_KEY_KP_DELETE +}; + +// ========== class BochsApplication definitions ========== + +BochsApplication::BochsApplication(bx_gui_c *bxGui, int argc, char **argv, + uint32 tileWidth, uint32 tileHeight, uint32 header_bar_y, handler_func powerHandlerFunc): + BApplication(BOCHS_APP_SIG), + fPowerHandlerFunc(powerHandlerFunc) +{ + bxGui->put("BGUI"); + + if (bx_options.Oprivate_colormap->get ()) + { + BX_INFO(( "BeOS: private_colormap option not handled yet.")); + } -public: - BochsView(BRect frame, char *name); - ~BochsView(); - virtual void AttachedToWindow(); - virtual void Draw(BRect updateRect); - virtual void KeyDown(const char *bytes, int32 numBytes); - virtual void KeyUp(const char *bytes, int32 numBytes); - virtual void MouseDown(BPoint point); - virtual void MouseUp(BPoint point); - virtual void MouseMoved(BPoint point, - uint32 transit, const BMessage *message); - void DrawBitmap(const BBitmap *aBitmap, BPoint where); - void FillRect(BRect r, pattern p = B_SOLID_HIGH); - void SetHighColor(uchar r, uchar g, uchar b, uchar a = 255); - void SetLowColor(uchar r, uchar g, uchar b, uchar a = 255); - void SetFont(const BFont *font, uint32 mask = B_FONT_ALL); - void set_text_colors(void); - void set_inv_text_colors(void); - void set_headerbar_colors(void); - }; - - -void GUI_end(void); -void enq_key_event(Bit32u key, Bit32u press_release); -Bit32u deq_key_event(void); -#define SCANCODE_BUFSIZE 20 -static Bit32u keyevents[SCANCODE_BUFSIZE]; -static unsigned head=0, tail=0; -static bool view_attached = 0; - -static BochsApplication *myApplication = NULL; -static BochsWindow *aWindow = NULL; -static BochsView *aView = NULL; -static BView *canvas = NULL; -static uint8 cmap_index[256]; // indeces into system colormap - -static BRect rect; -static BPoint image_origin; -static BBitmap *image = NULL; -static BScreen *screen; -static unsigned long rowsize_padded=0; -static uint8 *rawdata = NULL; - -//static int rows=25, columns=80; - -static unsigned font_width, font_height; -static Bit8u blank_line[80]; -static unsigned dimension_x, dimension_y; - -//static unsigned imDepth, imWide, imBPP; - -// current cursor coordinates -//IRA=> Start -static BPoint current; -static BPoint previous; -static Bit8u mouse_button_state = 0; -//IRA=> End -//static int prev_x=-1, prev_y=-1; -//static int current_x=-1, current_y=-1; - -static unsigned prev_block_cursor_x=0; -static unsigned prev_block_cursor_y=0; - -static void headerbar_click(int x, int y); - -Bit8u ascii_to_scancode[0x7f] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0x39, 0x02, 0x28, 0x04, 0x05, 0x06, 0x08, 0x28, /* !"#$%&' */ - 0x0a, 0x0b, 0x09, 0x0d, 0x33, 0x0c, 0x34, 0x35, /* ()*+,-./ */ - 0x0b, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, /* 01234567 */ - 0x09, 0x0a, 0x27, 0x27, 0x33, 0x0d, 0x34, 0x35, /* 89:;<=>? */ - 0x03, 0x1e, 0x30, 0x2e, 0x20, 0x12, 0x21, 0x22, /* @ABCDEFG */ - 0x23, 0x17, 0x24, 0x25, 0x26, 0x32, 0x31, 0x18, /* HIJKLMNO */ - 0x19, 0x10, 0x13, 0x1f, 0x14, 0x16, 0x2f, 0x11, /* PQRSTUVW */ - 0x2d, 0x15, 0x2c, 0x1a, 0x2b, 0x1b, 0x07, 0x0c, /* XYZ[\]^_ */ - 0x29, 0x1e, 0x30, 0x2e, 0x20, 0x12, 0x21, 0x22, /* `abcdefg */ - 0x23, 0x17, 0x24, 0x25, 0x26, 0x32, 0x31, 0x18, /* hijklmno */ - 0x19, 0x10, 0x13, 0x1f, 0x14, 0x16, 0x2f, 0x11, /* pqrstuvw */ - 0x2d, 0x15, 0x2c, 0x1a, 0x2b, 0x1b, 0x29 /* xyz{|}~ */ - }; - -extern Bit8u graphics_snapshot[32 * 1024]; -//extern pc_keyb_c *pc_keyboard; - - - - -unsigned col_vals[256], curr_foreground, curr_background; - -static unsigned x_tilesize, y_tilesize; - -struct { - BBitmap *bmap; - unsigned xdim; - unsigned ydim; - } bx_bitmaps[BX_MAX_PIXMAPS]; -unsigned bx_bitmap_entries = 0; - -static struct { - BBitmap *bitmap; - unsigned xdim; - unsigned ydim; - unsigned xorigin; - unsigned yorigin; - unsigned alignment; - void (*f)(void); - } bx_headerbar_entry[BX_MAX_HEADERBAR_ENTRIES]; -static unsigned bx_headerbar_y = 0; -static unsigned bx_headerbar_entries = 0; -static unsigned bx_bitmap_left_xorigin = 0; // pixels from left -static unsigned bx_bitmap_right_xorigin = 0; // pixels from right - -static void headerbar_click(int x, int y); -static unsigned char reverse_bitorder(unsigned char b); -static void create_vga_font(void); -static BBitmap *vgafont[256]; - -static bx_gui_c *bx_gui_c_ptr; - - void -bx_gui_c::specific_init(bx_gui_c *th, int argc, char **argv, - unsigned tilewidth, unsigned tileheight, - unsigned header_bar_y) -{ - unsigned i; -#if BX_CPU_LEVEL < 2 - char *window_name = "Bochs 8086 emulator, http://world.std.com/~bochs"; -#elif BX_CPU_LEVEL == 2 - char *window_name = "Bochs 80286 emulator, http://world.std.com/~bochs"; -#elif BX_CPU_LEVEL == 3 - char *window_name = "Bochs 80386 emulator, http://world.std.com/~bochs"; -#else - char *window_name = "Bochs 80386+ emulator, http://world.std.com/~bochs"; -#endif - - bx_gui_c_ptr = th; -UNUSED(argc); -UNUSED(argv); -UNUSED(window_name); - th->put("BGUI"); - -if (bx_options.Oprivate_colormap->get ()) { - BX_INFO(( "BeOS: private_colormap option not handled yet.")); - } - - x_tilesize = tilewidth; - y_tilesize = tileheight; - bx_headerbar_y = header_bar_y; - - for (i=0; i<80; i++) { - blank_line[i] = ' '; - } - - - font_width = 8; - font_height = 16; - - // width = columns * font_width; - // height = rows * font_height; - -BX_INFO(("font_width = %u", (unsigned) font_width)); -BX_INFO(("font_height = %u", (unsigned) font_height)); - - // Create pixmap of depth 1 (bitmap) for icon - // icon_pixmap = XCreateBitmapFromData(bx_x_display, win, - // (char *) bochs_icon_bits, bochs_icon_width, bochs_icon_height); - - curr_background = 0; - // XSetBackground(bx_x_display, gc, col_vals[curr_background]); - curr_foreground = 1; - // XSetForeground(bx_x_display, gc, col_vals[curr_foreground]); - //XGrabPointer( bx_x_display, win, True, 0, GrabModeAsync, GrabModeAsync, - // win, None, CurrentTime ); - //XFlush(bx_x_display); - - myApplication = new BochsApplication(); - - // wait until window on screen - while (1) { - aWindow->Lock(); - if (aWindow->IsHidden()) { - aWindow->Unlock(); - continue; - } - aWindow->Unlock(); - break; - } - - screen = new BScreen; - // start out with all color map indeces pointing to Black - cmap_index[0] = screen->IndexForColor(0, 0, 0); - for (unsigned i=1; i<256; i++) { - cmap_index[i] = cmap_index[0]; - } - - rect.Set(0,0, x_tilesize-1, y_tilesize-1); - image = new BBitmap(rect, B_COLOR_8_BIT); - rowsize_padded = PAD_NEAREST(x_tilesize, sizeof(int32)); - rawdata = new uint8[rowsize_padded * y_tilesize]; - - create_vga_font(); -} - - - - void -bx_gui_c::handle_events(void) -{ - Bit32u key; - - while ( head != tail ) { - key = deq_key_event(); - bx_devices.keyboard->gen_scancode(key); - } -//IRA=> Start - if (aView) { - unsigned long buttons; - aView->LockLooper(); - aView->GetMouse(¤t, &buttons, false); - aView->UnlockLooper(); - - Bit8u newstate = 0; //please note: 2nd and 3rd button are mapped the same - if (buttons & B_PRIMARY_MOUSE_BUTTON) - newstate |= 0x01; - if (buttons & B_SECONDARY_MOUSE_BUTTON) - newstate |= 0x02; - if (buttons & B_TERTIARY_MOUSE_BUTTON) - newstate |= 0x02; - - if (current != previous || - mouse_button_state != newstate) { - int dx = (int)(current.x - previous.x) *2; - int dy = -(int)((current.y - previous.y) *2); - bx_devices.keyboard->mouse_motion( dx, dy, newstate); - mouse_button_state = newstate; - previous = current; - } - } -//IRA=> End -} - - void -bx_gui_c::flush(void) -{ - if (view_attached) - aView->Flush(); -} - - - void -bx_gui_c::clear_screen(void) -{ - aWindow->Lock(); - aView->FillRect(BRect(0, bx_headerbar_y, dimension_x-1, dimension_y-1), B_SOLID_LOW); - aWindow->Unlock(); -} - - - - void -bx_gui_c::text_update(Bit8u *old_text, Bit8u *new_text, - unsigned long cursor_x, unsigned long cursor_y, - Bit16u cursor_state, unsigned nrows) -{ - unsigned i, x, y; - BPoint point; - unsigned char achar; - unsigned nchars, ncols; - - aWindow->Lock(); - - // Number of characters on screen, variable number of rows - ncols = dimension_x/8; - nchars = ncols*nrows; - - // first draw over character at original block cursor location - if ( (prev_block_cursor_y*ncols + prev_block_cursor_x) < nchars ) { - achar = new_text[(prev_block_cursor_y*ncols + prev_block_cursor_x)*2]; - point.Set(prev_block_cursor_x*8, prev_block_cursor_y*16 + bx_headerbar_y); - aView->DrawBitmap(vgafont[achar], point ); - } - - for (i=0; iDrawBitmap(vgafont[achar], point ); - } - } - - prev_block_cursor_x = cursor_x; - prev_block_cursor_y = cursor_y; - - // now draw character at new block cursor location in reverse - if ( (cursor_y*ncols + cursor_x) < nchars ) { - achar = new_text[(cursor_y*ncols + cursor_x)*2]; - point.Set(cursor_x*8, cursor_y*16 + bx_headerbar_y); - aView->set_inv_text_colors(); - aView->DrawBitmap(vgafont[achar], point ); - aView->set_text_colors(); - } + // ------------------------------- + + BRect rect(0, 0, INITIAL_SCREEN_WIDTH - 1, INITIAL_SCREEN_HEIGHT + header_bar_y); + + BochsWindow *window = new BochsWindow(rect.OffsetToCopy(5, 80)); + + bView = new BochsView(rect, "BochsView", header_bar_y, tileWidth, tileHeight); - aWindow->Unlock(); + // add view to window + window->AddChild(bView); + + // make window visible + window->Show(); } - int -bx_gui_c::get_clipboard_text(Bit8u **bytes, Bit32s *nbytes) +BochsApplication::~BochsApplication() { - return 0; + bApp = NULL; } - int -bx_gui_c::set_clipboard_text(char *text_snapshot, Bit32u len) +int32 BochsApplication::runme(void *data) { - return 0; + be_app->Lock(); + be_app->Run(); } - - void -bx_gui_c::graphics_tile_update(Bit8u *tile, unsigned x0, unsigned y0) +bool BochsApplication::QuitRequested() { - for (unsigned y=0; yLock(); - image->SetBits(rawdata, rowsize_padded * y_tilesize, 0, B_COLOR_8_BIT); - image_origin.Set(x0, y0 + bx_headerbar_y); - - aView->DrawBitmap( image, image_origin ); - aWindow->Unlock(); + BMessage msg(MSG_ENQ_COMMAND); + msg.AddPointer("command", (void*)fPowerHandlerFunc); + bView->Window()->PostMessage(&msg, bView); + return false; } - - Boolean -bx_gui_c::palette_change(unsigned index, unsigned red, unsigned green, unsigned blue) +void BochsApplication::Quit() { - cmap_index[index] = screen->IndexForColor( - red, green, blue); - return(1); + uint32 lockCount = 0; + while (IsLocked()) + { + Unlock(); + lockCount++; + } + bView->LockLooper(); + bView->Window()->Close(); + while (lockCount--) Lock(); } - - void -bx_gui_c::dimension_update(unsigned x, unsigned y, unsigned fheight) +void BochsApplication::BxExit() { - if (fheight > 0) { - if (fheight != 16) { - y = y * 16 / fheight; - } - } - aWindow->Lock(); - aWindow->ResizeTo(x, y + bx_headerbar_y); - aWindow->Unlock(); + if (Lock()) Quit(); } +// ========== class BochsWindow definitions ========== -////////////////////////////////////////////////////// - - - void -GUI_end() +BochsWindow::BochsWindow(BRect frame): + BWindow(frame, "Bochs", B_TITLED_WINDOW, B_NOT_RESIZABLE) { - //myApplication->Run(); - delete(myApplication); } -BochsApplication::BochsApplication() - : BApplication("application/x-vnd.Be-Bochs") +bool BochsWindow::QuitRequested() { - BRect aRect; - - int left, right, top, bottom; - left = 5; - top = 80; - dimension_x = 640; - dimension_y = 480 + bx_headerbar_y; - right = left + dimension_x - 1; - bottom = top + dimension_y - 1; - - // set up a rectangle and instantiate a new window - aRect.Set(left, top, right, bottom); - aWindow = new BochsWindow(aRect); - - // set up a rectangle and instantiate a new view - // view rect should be same size as window rect but with left top at (0, 0) - aRect.OffsetTo(B_ORIGIN); - aView = new BochsView(aRect, "BochsView"); - aView->SetViewColor(0, 0, 0); - - aView->set_text_colors(); - - // add view to window - aWindow->AddChild(aView); - - // make window visible - aWindow->Show(); + be_app->PostMessage(B_QUIT_REQUESTED); + return false; } -//void set_palette_entry(long i,rgb_color c); +// ========== class BochsView definitions ========== -BochsWindow::BochsWindow(BRect frame) - : BWindow(frame, "BeBochs V1.3.pre compiled Bernd Korz", B_TITLED_WINDOW, B_NOT_RESIZABLE) -{ +BochsView::BochsView(BRect rect, char *name, uint32 headerHeight, uint32 tileWidth, uint32 tileHeight): + BView(rect, name, B_FOLLOW_ALL, B_WILL_DRAW | B_PULSE_NEEDED), + fLastModifiers(0), + fCursorX(0), fCursorY(0), + fCursorHide(false), + fCursorVisible(false), + fInTextMode(true), + fTileWidth(tileWidth), + fTileHeight(tileHeight), + fUseStandardInput(true), + fMouseEnabled(false), + fKeyQueue(SCANCODE_BUFSIZE, "keyboard queue"), + fMouseQueue(MOUSE_BUFSIZE, "mouse queue"), + fCommandQueue(10, "headerbar queue"), + fBitmapCount(0), + fHeaderEntryCount(0), + fHeaderHeight(headerHeight), + fHeaderLeft(0), + fHeaderRight(0) +{ + SetViewColor(0, 0, 0); + fBackBitmap = new BBitmap(rect, B_BITMAP_ACCEPTS_VIEWS, B_CMAP8); + fBackView = new BView(rect,"BackView", B_FOLLOW_ALL, B_WILL_DRAW); + fBackView->SetViewColor(0, 0, 0); + fBackBitmap->AddChild(fBackView); + + fCaptureTarget = new CaptureTarget(this); + + // start out with all color map indeces pointing to Black + fColorMap[0] = fScreen.IndexForColor(0, 0, 0); + for (unsigned i=1; i<256; i++) + { + fColorMap[i] = fColorMap[0]; + } + + BX_INFO(( "BeOS: creating VGA font from bitmaps" )); + + // VGA font is 8wide x 16high + uint8 *bits; + for (uint32 c = 0; c < 256; c++) + { + fVgafont[c] = new BBitmap(BRect(0,0, 7,15), B_MONOCHROME_1_BIT); + if (!fVgafont[c]) + { + BX_PANIC(("beos: could not create bitmap")); + } + + int32 bytesPerRow = fVgafont[c]->BytesPerRow(); + bits = (uint8*)fVgafont[c]->Bits(); + memset(bits, 0, fVgafont[c]->BitsLength()); + for (uint32 i = 0; i < 16; i++) + { + bits[i * bytesPerRow] = ReverseBitorder(bx_vgafont[c].data[i]); + } + } } -bool BochsWindow::QuitRequested() +BochsView::~BochsView() { - be_app->PostMessage(B_QUIT_REQUESTED); - return(TRUE); + delete fBackBitmap; + for (int32 i = 0; i < 256; i++) delete fVgafont[i]; + delete fCursorBitmap; + delete fCaptureTarget; + bView = NULL; } - - void -BochsWindow::FrameResized(float width, float height) +void BochsView::AttachedToWindow() { - dimension_x = unsigned(width); - dimension_y = unsigned(height) + bx_headerbar_y; - if ( bx_gui_c_ptr ) - bx_gui_c_ptr->show_headerbar(); + SetViewColor(B_TRANSPARENT_COLOR); + MakeFocus(true); + Window()->AddFilter(new ModifierFilter(this)); + be_app->AddHandler(fCaptureTarget); + BMessage modifiersMessage(B_MODIFIERS_CHANGED); + modifiersMessage.AddInt32("modifiers", (int32)modifiers()); + Window()->PostMessage(&modifiersMessage, this); + BPoint p; + uint32 buttons; + GetMouse(&p, &buttons); + fLastMouseX = (uint32)p.x; + fLastMouseY = (uint32)p.y; +} + +void BochsView::DetachedFromWindow() +{ + if (be_app->Lock()) + { + be_app->RemoveHandler(fCaptureTarget); + be_app->Unlock(); + } } - -//------------------------------ - - -BochsView::BochsView(BRect rect, char *name) - : BView(rect, name, B_FOLLOW_ALL, B_WILL_DRAW) +void BochsView::Draw(BRect rect) { - backing_store = new BBitmap(rect, B_BITMAP_ACCEPTS_VIEWS, B_COLOR_8_BIT); - backing_view = new BView(rect,"backing store", B_FOLLOW_ALL, B_WILL_DRAW); - backing_store->AddChild(backing_view); + if (fBackBitmap->Lock()) + { + fBackView->Sync(); + fBackBitmap->Unlock(); + } + DrawBitmapAsync(fBackBitmap, rect, rect); +} + +void BochsView::MouseDown(BPoint point) +{ + if (point.y < fHeaderHeight) + { + int xorigin; + for (unsigned i = 0; i < fHeaderEntryCount; i++) + { + if (fHeaderEntries[i].alignment == BX_GRAVITY_LEFT) + xorigin = fHeaderEntries[i].xorigin; + else + xorigin = bView->Bounds().IntegerWidth() - fHeaderEntries[i].xorigin; + if ( (point.x >= xorigin) && (point.x < (xorigin + int(fHeaderEntries[i].xdim))) ) + { + fCommandQueue.Enq(fHeaderEntries[i].f); + break; + } + } + return; + } + uint32 buttons; + Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons); + + fMouseQueue.Enq(mouse_event(0, 0, + ((buttons & B_PRIMARY_MOUSE_BUTTON) ? MOUSE_L : 0) | + ((buttons & B_SECONDARY_MOUSE_BUTTON) ? MOUSE_R : 0))); + + BX_DEBUG(("mousedown()")); } - void -BochsView::set_text_colors(void) +void BochsView::MouseUp(BPoint point) { - aView->SetHighColor(255, 255, 255); - aView->SetLowColor(0, 0, 0); + uint32 buttons; + Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons); + + fMouseQueue.Enq(mouse_event(0, 0, + ((buttons & B_PRIMARY_MOUSE_BUTTON) ? MOUSE_L : 0) | + ((buttons & B_SECONDARY_MOUSE_BUTTON) ? MOUSE_R : 0))); + + BX_DEBUG(( "mouseup()" )); +} + +void BochsView::MouseMoved(BPoint point, uint32 transit, const BMessage *message) +{ + if (!fUseStandardInput && fMouseEnabled) + { + be_app->ObscureCursor(); + return; + } + uint32 buttons; + Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons); + fMouseQueue.Enq(mouse_event((uint32)point.x - fLastMouseX, fLastMouseY - (uint32)point.y, + ((buttons & B_PRIMARY_MOUSE_BUTTON) ? MOUSE_L : 0) | + ((buttons & B_SECONDARY_MOUSE_BUTTON) ? MOUSE_R : 0))); + fLastMouseX = (uint32)point.x; + fLastMouseY = (uint32)point.y; + BX_DEBUG(( "mousemoved()" )); } - void -BochsView::set_inv_text_colors(void) +void BochsView::KeyDown(const char *bytes, int32 numBytes) { - aView->SetHighColor(0, 0, 0); - aView->SetLowColor(255, 255, 255); + int32 key; + Window()->CurrentMessage()->FindInt32("key", &key); + fKeyQueue.Enq(key_to_scancode[key] | BX_KEY_PRESSED); } - void -BochsView::set_headerbar_colors(void) +void BochsView::KeyUp(const char *bytes, int32 numBytes) { - aView->SetHighColor(0, 0, 0); - aView->SetLowColor(255, 255, 255); + int32 key; + Window()->CurrentMessage()->FindInt32("key", &key); + fKeyQueue.Enq(key_to_scancode[key] | BX_KEY_RELEASED); +} + +void BochsView::MessageReceived(BMessage *msg) +{ + switch (msg->what) + { + case MSG_ENQ_COMMAND: + { + handler_func command; + msg->FindPointer("command", (void**)&command); + fCommandQueue.Enq(command); + } + break; + case B_MODIFIERS_CHANGED: + { + uint32 modifiers = 0; + msg->FindInt32("modifiers", (int32*)&modifiers); + //fprintf(stderr, "# modifiers: %08x -> %08x\n", fLastModifiers, modifiers); + if (!(fLastModifiers & B_LEFT_SHIFT_KEY) && (modifiers & B_LEFT_SHIFT_KEY)) + { + fKeyQueue.Enq(BX_KEY_SHIFT_L | BX_KEY_PRESSED); + //fprintf(stderr, "# left shift down\n"); + } + else if ((fLastModifiers & B_LEFT_SHIFT_KEY) && !(modifiers & B_LEFT_SHIFT_KEY)) + { + fKeyQueue.Enq(BX_KEY_SHIFT_L | BX_KEY_RELEASED); + //fprintf(stderr, "# left shift up\n"); + } + + if (!(fLastModifiers & B_RIGHT_SHIFT_KEY) && (modifiers & B_RIGHT_SHIFT_KEY)) + { + fKeyQueue.Enq(BX_KEY_SHIFT_R | BX_KEY_PRESSED); + //fprintf(stderr, "# right shift down\n"); + } + else if ((fLastModifiers & B_RIGHT_SHIFT_KEY) && !(modifiers & B_RIGHT_SHIFT_KEY)) + { + fKeyQueue.Enq(BX_KEY_SHIFT_R | BX_KEY_RELEASED); + //fprintf(stderr, "# right shift up\n"); + } + + if (!(fLastModifiers & B_CONTROL_KEY) && (modifiers & B_CONTROL_KEY)) + { + fKeyQueue.Enq(BX_KEY_CTRL_L | BX_KEY_PRESSED); + //fprintf(stderr, "# left ctrl down\n"); + } + else if ((fLastModifiers & B_CONTROL_KEY) && !(modifiers & B_CONTROL_KEY)) + { + fKeyQueue.Enq(BX_KEY_CTRL_L | BX_KEY_RELEASED); + //fprintf(stderr, "# left ctrl up\n"); + } + + if (!(fLastModifiers & B_OPTION_KEY) && (modifiers & B_OPTION_KEY)) + { + fKeyQueue.Enq(BX_KEY_CTRL_R | BX_KEY_PRESSED); + //fprintf(stderr, "# right ctrl down\n"); + } + else if ((fLastModifiers & B_OPTION_KEY) && !(modifiers & B_OPTION_KEY)) + { + fKeyQueue.Enq(BX_KEY_CTRL_R | BX_KEY_RELEASED); + //fprintf(stderr, "# right ctrl up\n"); + } + + if (!(fLastModifiers & B_LEFT_COMMAND_KEY) && (modifiers & B_LEFT_COMMAND_KEY)) + { + fKeyQueue.Enq(BX_KEY_ALT_L | BX_KEY_PRESSED); + //fprintf(stderr, "# left alt down\n"); + } + else if ((fLastModifiers & B_LEFT_COMMAND_KEY) && !(modifiers & B_LEFT_COMMAND_KEY)) + { + fKeyQueue.Enq(BX_KEY_ALT_L | BX_KEY_RELEASED); + //fprintf(stderr, "# left alt up\n"); + } + + if (!(fLastModifiers & B_RIGHT_COMMAND_KEY) && (modifiers & B_RIGHT_COMMAND_KEY)) + { + fKeyQueue.Enq(BX_KEY_ALT_R | BX_KEY_PRESSED); + //fprintf(stderr, "# right alt down\n"); + } + else if ((fLastModifiers & B_RIGHT_COMMAND_KEY) && !(modifiers & B_RIGHT_COMMAND_KEY)) + { + fKeyQueue.Enq(BX_KEY_ALT_R | BX_KEY_RELEASED); + //fprintf(stderr, "# right alt up\n"); + } + + if (!(fLastModifiers & B_CAPS_LOCK) && (modifiers & B_CAPS_LOCK)) + { + fKeyQueue.Enq(BX_KEY_CAPS_LOCK | BX_KEY_PRESSED); + fKeyQueue.Enq(BX_KEY_CAPS_LOCK | BX_KEY_RELEASED); + //fprintf(stderr, "# caps down\n"); + } + else if ((fLastModifiers & B_CAPS_LOCK) && !(modifiers & B_CAPS_LOCK)) + { + fKeyQueue.Enq(BX_KEY_CAPS_LOCK | BX_KEY_PRESSED); + fKeyQueue.Enq(BX_KEY_CAPS_LOCK | BX_KEY_RELEASED); + //fprintf(stderr, "# caps up\n"); + } + + if (!(fLastModifiers & B_SCROLL_LOCK) && (modifiers & B_SCROLL_LOCK)) + { + fKeyQueue.Enq(BX_KEY_SCRL_LOCK | BX_KEY_PRESSED); + fKeyQueue.Enq(BX_KEY_SCRL_LOCK | BX_KEY_RELEASED); + //fprintf(stderr, "# scrollock down\n"); + } + else if ((fLastModifiers & B_SCROLL_LOCK) && !(modifiers & B_SCROLL_LOCK)) + { + fKeyQueue.Enq(BX_KEY_SCRL_LOCK | BX_KEY_PRESSED); + fKeyQueue.Enq(BX_KEY_SCRL_LOCK | BX_KEY_RELEASED); + //fprintf(stderr, "# scrollock up\n"); + } + + if (!(fLastModifiers & B_NUM_LOCK) && (modifiers & B_NUM_LOCK)) + { + fKeyQueue.Enq(BX_KEY_NUM_LOCK | BX_KEY_PRESSED); + fKeyQueue.Enq(BX_KEY_NUM_LOCK | BX_KEY_RELEASED); + //fprintf(stderr, "# num down\n"); + } + else if ((fLastModifiers & B_NUM_LOCK) && !(modifiers & B_NUM_LOCK)) + { + fKeyQueue.Enq(BX_KEY_NUM_LOCK | BX_KEY_PRESSED); + fKeyQueue.Enq(BX_KEY_NUM_LOCK | BX_KEY_RELEASED); + //fprintf(stderr, "# num up\n"); + } + fLastModifiers = modifiers; + } + break; + default: + BView::MessageReceived(msg); + } +} + +void BochsView::GotCapturedInput(BMessage *msg) +{ + switch (msg->what) + { + case B_MOUSE_MOVED: + { + uint32 buttons; + msg->FindInt32("buttons", (int32*)&buttons); + BPoint motion; + msg->FindPoint("motion", &motion); + fMouseQueue.Enq(mouse_event((uint32)motion.x, -(uint32)motion.y, + ((buttons & B_PRIMARY_MOUSE_BUTTON) ? MOUSE_L : 0) | + ((buttons & B_SECONDARY_MOUSE_BUTTON) ? MOUSE_R : 0))); + BX_DEBUG(( "mousemoved()" )); + } + break; + case B_MOUSE_DOWN: + case B_MOUSE_UP: + { + uint32 buttons; + msg->FindInt32("buttons", (int32*)&buttons); + if (buttons & B_PRIMARY_MOUSE_BUTTON && buttons & B_SECONDARY_MOUSE_BUTTON) + { + fCommandQueue.Enq(release_mouse); + break; + } + + fMouseQueue.Enq(mouse_event(0, 0, + ((buttons & B_PRIMARY_MOUSE_BUTTON) ? MOUSE_L : 0) | + ((buttons & B_SECONDARY_MOUSE_BUTTON) ? MOUSE_R : 0))); + + //BX_DEBUG(("mousedown()")); + } + break; + case B_KEY_DOWN: + case B_UNMAPPED_KEY_DOWN: + { + int32 key; + msg->FindInt32("key", &key); + fKeyQueue.Enq(key_to_scancode[key] | BX_KEY_PRESSED); + } + break; + case B_KEY_UP: + case B_UNMAPPED_KEY_UP: + { + int32 key; + msg->FindInt32("key", &key); + fKeyQueue.Enq(key_to_scancode[key] | BX_KEY_RELEASED); + } + } +} + +void BochsView::WindowActivated(bool active) +{ + if (active) CaptureInput(); + else ReleaseInput(); +} + +void BochsView::CaptureInput() +{ + BMessenger inputServer("application/x-vnd.Be-input_server"); + BMessage msg(MSG_REQUEST_CAPTURE); + msg.AddMessenger("target", BMessenger(fCaptureTarget)); + msg.AddInt32("command", MSG_START_CAPTURE); + msg.AddInt32("input", (fMouseEnabled ? INPUT_TYPE_MOUSE : 0) | INPUT_TYPE_KEYBOARD); + inputServer.SendMessage(&msg, &msg); + if (msg.what == MSG_CAPTURE_OK) + { + BX_INFO(( "capturing keyboard%s input", (fMouseEnabled ? " and mouse" : ""))); + fUseStandardInput = false; + if (fMouseEnabled) be_app->ObscureCursor(); + else be_app->ShowCursor(); + } + else + { + BX_ERROR(( "couldn't set up input capturing, using loser method" )); + fUseStandardInput = true; + BMessage modifiersMessage(B_MODIFIERS_CHANGED); + modifiersMessage.AddInt32("modifiers", (int32)modifiers()); + Window()->PostMessage(&modifiersMessage, this); + } +} + +void BochsView::ReleaseInput() +{ + BMessenger inputServer("application/x-vnd.Be-input_server"); + BMessage msg(MSG_REQUEST_CAPTURE); + msg.AddInt32("command", MSG_STOP_CAPTURE); + inputServer.SendMessage(&msg); + be_app->ShowCursor(); + fUseStandardInput = true; +} + +void BochsView::Pulse() +{ + if (!fInTextMode) return; + if (fBackView->LockLooper()) + { + if (fCursorHide) + { + if (fCursorVisible) ShowCursor(false); + } + else + { + ShowCursor(!fCursorVisible); + } + fBackView->UnlockLooper(); + } +} + +void BochsView::HandleEvents() +{ + if (LockLooper()) + { + while (!fKeyQueue.QueueEmpty()) + { + uint32 key; + fKeyQueue.Deq(&key); + bx_devices.keyboard->gen_scancode(key); + } + + while (!fMouseQueue.QueueEmpty()) + { + mouse_event event; + fMouseQueue.Deq(&event); + if (fMouseEnabled) bx_devices.keyboard->mouse_motion(event.x, + event.y, event.buttonState); + } + + while (!fCommandQueue.QueueEmpty()) + { + void (*f)(void); + fCommandQueue.Deq(&f); + f(); + } + UnlockLooper(); + } +} + +void BochsView::ClearScreen() +{ + if (fBackBitmap->Lock()) + { + fBackView->SetLowColor(0, 0, 0); + BRect rect(fBackView->Bounds()); + rect.top += fHeaderHeight; + fBackView->FillRect(rect, B_SOLID_LOW); + fBackBitmap->Unlock(); + } + if (LockLooper()) + { + Invalidate(); + UnlockLooper(); + } +} + +void BochsView::TextUpdate(uint8 *oldText, uint8 *newText, + uint32 cursorX, uint32 cursorY, uint32 rowCount, + uint32 cursorShape) +{ + if (LockLooper() && fBackBitmap->Lock()) + { + fInTextMode = true; + bool cursorWasShown = fCursorVisible; + BRect rect(Bounds().OffsetToSelf(0, 0)); + uint32 colCount = (uint32)rect.IntegerWidth()/8; + fCursorStart = (uint8)((cursorShape >> 8) & 0x3f); + fCursorEnd = (uint8)(cursorShape & 0x1f); + ShowCursor(false); + for (uint32 i = 0; i < rowCount * colCount * 2; i += 2) + { + if ( (oldText[i] != newText[i]) || + (oldText[i+1]!=newText[i+1]) ) + { + uint8 achar = newText[i]; + uint8 acolor = newText[i + 1]; + + fBackView->SetLowColor(fScreen.ColorForIndex(fColorMap[acolor >> 4])); + fBackView->SetHighColor(fScreen.ColorForIndex(fColorMap[acolor & 0x0F])); + + BPoint point(((i / 2) % colCount) * 8, (i/2) / colCount * 16 + fHeaderHeight); + fBackView->DrawBitmapAsync(fVgafont[achar], point); + Invalidate(fVgafont[achar]->Bounds().OffsetToSelf(point)); + } + } + + fCursorX = cursorX; + fCursorY = cursorY; + + if ( (cursorY * colCount + cursorX) < rowCount * colCount) + { + fCursorValue[0] = newText[(cursorY * colCount + cursorX) * 2]; + fCursorValue[1] = newText[(cursorY * colCount + cursorX) * 2 + 1]; + fCursorHide = (fCursorStart > fCursorEnd); + } + if (!fCursorHide) ShowCursor(cursorWasShown); + fBackBitmap->Unlock(); + UnlockLooper(); + } +} + +void BochsView::GraphicsTileUpdate(uint8 *tile, uint32 x0, uint32 y0) +{ + if (LockLooper()) + { + fInTextMode = false; + uint8 *bits = (uint8*)fBackBitmap->Bits(); + int32 bytesPerRow = fBackBitmap->BytesPerRow(); + bits += (y0 + fHeaderHeight) * bytesPerRow + x0; + if (fBackBitmap->Lock()) + { + fBackView->Sync(); + for (uint32 y = 0; y < fTileHeight; y++) + { + for (uint32 x = 0; x < fTileWidth; x++) + { + *(bits + x) = fColorMap[ tile[y*fTileWidth + x] ]; + } + bits += bytesPerRow; + } + fBackBitmap->Unlock(); + } + Invalidate(BRect(x0, y0 + fHeaderHeight, x0 + fTileWidth - 1, y0 + fHeaderHeight + fTileHeight -1)); + UnlockLooper(); + } +} + +bool BochsView::PaletteChange(uint32 index, uint32 red, uint32 green, uint32 blue) +{ + if (LockLooper()) + { + fColorMap[index] = fScreen.IndexForColor(red, green, blue); + UnlockLooper(); + } + return true; +} + +void BochsView::DimensionUpdate(uint32 x, uint32 y, uint32 fheight) +{ + if (LockLooper()) + { + if (fheight > 0) + { + if (fheight != 16) + { + y = y * 16 / fheight; + } + } + BRect rect(Bounds().OffsetToSelf(0, 0)); + if (x != (uint32)rect.IntegerWidth() || y + fHeaderHeight != (uint32)rect.IntegerHeight()) + { + Window()->ResizeTo(x, y + fHeaderHeight); + delete fBackBitmap; + rect.Set(0, 0, x, y + fHeaderHeight); + fBackBitmap = new BBitmap(rect, B_BITMAP_ACCEPTS_VIEWS, B_CMAP8); + fBackView = new BView(rect,"BackView", B_FOLLOW_NONE, B_WILL_DRAW); + fBackBitmap->AddChild(fBackView); + ShowHeaderbar(); + } + UnlockLooper(); + } +} + +void BochsView::HandleEnableMouse(bool enable) +{ + if (LockLooper()) + { + fMouseEnabled = enable; + if (Window()->IsActive()) CaptureInput(); + UnlockLooper(); + } +} + +uint32 BochsView::CreateBitmap(const uchar *bmap, uint32 xdim, uint32 ydim) +{ + if (LockLooper()) + { + if (fBitmapCount >= BX_MAX_PIXMAPS) + { + BX_PANIC(("beos: too many pixmaps, increase BX_MAX_PIXMAPS")); + } + + uint32 bmpIndex = fBitmapCount++; + + fBitmaps[bmpIndex].bmap = + new BBitmap(BRect(0, 0, xdim-1, ydim-1), B_MONOCHROME_1_BIT); + if (!fBitmaps[bmpIndex].bmap) + { + BX_PANIC(("beos: could not create bitmap")); + } + + int32 bitsLength = fBitmaps[bmpIndex].bmap->BitsLength(); + uchar *bits = (uchar *) fBitmaps[bmpIndex].bmap->Bits(); + for (int32 i = 0; i < bitsLength; i++) + { + bits[i] = ReverseBitorder(bmap[i]); + } + + fBitmaps[bmpIndex].xdim = xdim; + fBitmaps[bmpIndex].ydim = ydim; + UnlockLooper(); + return bmpIndex; + } + return 0; +} + +uint32 BochsView::HeaderbarBitmap(uint32 bmap_id, uint32 alignment, void (*f)(void)) +{ + if (LockLooper()) + { + if ( (fHeaderEntryCount + 1) > BX_MAX_HEADERBAR_ENTRIES ) + BX_PANIC(("beos: too many headerbar entries, increase BX_MAX_HEADERBAR_ENTRIES")); + + + uint32 hbIndex = fHeaderEntryCount++; + + fHeaderEntries[hbIndex].bitmap = fBitmaps[bmap_id].bmap; + fHeaderEntries[hbIndex].xdim = fBitmaps[bmap_id].xdim; + fHeaderEntries[hbIndex].ydim = fBitmaps[bmap_id].ydim; + fHeaderEntries[hbIndex].alignment = alignment; + fHeaderEntries[hbIndex].f = f; + if (alignment == BX_GRAVITY_LEFT) + { + fHeaderEntries[hbIndex].xorigin = fHeaderLeft; + fHeaderEntries[hbIndex].yorigin = 0; + fHeaderLeft += fBitmaps[bmap_id].xdim; + } + else // BX_GRAVITY_RIGHT + { + fHeaderRight += fBitmaps[bmap_id].xdim; + fHeaderEntries[hbIndex].xorigin = fHeaderRight; + fHeaderEntries[hbIndex].yorigin = 0; + } + UnlockLooper(); + return(hbIndex); + } + return 0; +} + +void BochsView::ReplaceBitmap(uint32 hbar_id, uint32 bmap_id) +{ + if (LockLooper() && fBackBitmap->Lock()) + { + uint32 xorigin; + + fHeaderEntries[hbar_id].bitmap = fBitmaps[bmap_id].bmap; + + if (fHeaderEntries[hbar_id].alignment == BX_GRAVITY_LEFT) + xorigin = fHeaderEntries[hbar_id].xorigin; + else + xorigin = Bounds().IntegerWidth() - fHeaderEntries[hbar_id].xorigin; + fBackView->SetLowColor(192, 192, 192); + fBackView->SetHighColor(0, 0, 0); + fBackView->DrawBitmapAsync(fHeaderEntries[hbar_id].bitmap, BPoint(xorigin, 0)); + fBackBitmap->Unlock(); + Invalidate(fHeaderEntries[hbar_id].bitmap->Bounds().OffsetToSelf(xorigin, 0)); + UnlockLooper(); + } } -void BochsView::AttachedToWindow() +void BochsView::ShowHeaderbar() { - BFont font(be_fixed_font); - - aWindow->Lock(); - font.SetSize(16); - font.SetFlags(B_DISABLE_ANTIALIASING); - aView->SetFont(&font); - - aView->MakeFocus(true); - aWindow->Unlock(); - - view_attached = 1; + if (LockLooper() && fBackBitmap->Lock()) + { + uint32 xorigin; + fBackView->SetLowColor(192, 192, 192); + fBackView->SetHighColor(0, 0, 0); + BRect rect(Bounds()); + rect.bottom = rect.top + fHeaderHeight - 1; + fBackView->FillRect(rect, B_SOLID_LOW); + for (unsigned i = 0; i < fHeaderEntryCount; i++) + { + if (fHeaderEntries[i].alignment == BX_GRAVITY_LEFT) + xorigin = fHeaderEntries[i].xorigin; + else + xorigin = rect.IntegerWidth() - fHeaderEntries[i].xorigin; + fBackView->DrawBitmapAsync( fHeaderEntries[i].bitmap, BPoint(xorigin, 0) ); + } + fBackBitmap->Unlock(); + Invalidate(rect); + UnlockLooper(); + } } -void BochsView::MouseDown(BPoint point) +void BochsView::ShowCursor(bool show) { - UNUSED(point); - if (point.y < BX_HEADER_BAR_Y) { - headerbar_click(int(point.x), int(point.y)); - return; - } - BX_DEBUG(("mousedown()")); + if (fBackBitmap->Lock()) + { + fCursorVisible = show; + BRect rect; + if (show) + { + BPoint point(fCursorX * 8, fHeaderHeight + fCursorY * 16 + fCursorStart); + rect.Set(point.x, point.y, point.x + 7, point.y + (fCursorEnd - fCursorStart)); + fBackView->SetHighColor(fScreen.ColorForIndex(fColorMap[fCursorValue[1] & 0x0F])); + fBackView->FillRect(rect, B_SOLID_HIGH); + Invalidate(rect); + } + else + { + BPoint point(fCursorX * 8, fHeaderHeight + fCursorY * 16); + rect.Set(point.x, point.y, point.x + 7, point.y + 15); + fBackView->SetHighColor(fScreen.ColorForIndex(fColorMap[fCursorValue[1] & 0x0F])); + fBackView->SetLowColor(fScreen.ColorForIndex(fColorMap[fCursorValue[1] >> 4])); + fBackView->DrawBitmapAsync(fVgafont[fCursorValue[0]], point); + } + Invalidate(rect); + fBackBitmap->Unlock(); + } } -void BochsView::MouseUp(BPoint point) +uchar BochsView::ReverseBitorder(uchar b) { - UNUSED(point); - // currently a place holder function - BX_DEBUG(( "mouseup()" )); - BView::MouseUp(point); + uchar ret=0; + for (uint32 i=0; i<8; i++) + { + ret |= (b & 0x01) << (7-i); + b >>= 1; + } + return ret; } -void BochsView::MouseMoved(BPoint point, - uint32 transit, const BMessage *message) +void BochsView::release_mouse() { - UNUSED(point); - UNUSED(transit); - UNUSED(message); - BX_DEBUG(( "mousemoved()" )); + bx_options.Omouse_enabled->set(false); } -void BochsView::KeyDown(const char *bytes, int32 numBytes) -{ - BMessage *msg; - //int32 key; - int32 modifiers; - - uint8 byte; - - msg = Window()->CurrentMessage(); - if ( !msg ) { - BX_DEBUG(( "keydown() msg NULL" )); - return; - } - modifiers = msg->FindInt32("modifiers"); -#if 0 - B_SHIFT_KEY = 0x00000001, - B_COMMAND_KEY = 0x00000002, - B_CONTROL_KEY = 0x00000004, - B_CAPS_LOCK = 0x00000008, - B_SCROLL_LOCK = 0x00000010, - B_NUM_LOCK = 0x00000020, - B_OPTION_KEY = 0x00000040, - B_MENU_KEY = 0x00000080, - B_LEFT_SHIFT_KEY = 0x00000100, - B_RIGHT_SHIFT_KEY = 0x00000200, - B_LEFT_COMMAND_KEY = 0x00000400, - B_RIGHT_COMMAND_KEY = 0x00000800, - B_LEFT_CONTROL_KEY = 0x00001000, - B_RIGHT_CONTROL_KEY = 0x00002000, - B_LEFT_OPTION_KEY = 0x00004000, - B_RIGHT_OPTION_KEY = 0x00008000 -#endif -//if (modifiers) { -// fprintf(stderr, "# modifiers = %08x\n", (unsigned) modifiers); -// } - - if (numBytes == 1) { - //fprintf(stderr, "# down: char %02xh\n", (unsigned) bytes[0]); - byte = bytes[0]; - if ( byte == 0x00 ) { - // Ctrl-Space - enq_key_event(BX_KEY_CTRL_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_SPACE, BX_KEY_PRESSED); - enq_key_event(BX_KEY_SPACE, BX_KEY_RELEASED); - enq_key_event(BX_KEY_CTRL_L, BX_KEY_RELEASED); - return; - } - if ( byte == 0x1b ) { - // Esc - if (modifiers & B_CONTROL_KEY) - enq_key_event(BX_KEY_CTRL_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_ESC, BX_KEY_PRESSED); - enq_key_event(BX_KEY_ESC, BX_KEY_RELEASED); - if (modifiers & B_CONTROL_KEY) - enq_key_event(BX_KEY_CTRL_L, BX_KEY_RELEASED); - return; - } - if ( (byte >= 0x30) && (byte <= 0x39) ) { - // 0 .. 9 - byte -= 0x30; - enq_key_event(BX_KEY_0 + byte, BX_KEY_PRESSED); - enq_key_event(BX_KEY_0 + byte, BX_KEY_RELEASED); - return; - } - if ( (byte >= 0x41) && (byte <= 0x5A) ) { - // A .. Z - byte -= 0x41; - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_A + byte, BX_KEY_PRESSED); - enq_key_event(BX_KEY_A + byte, BX_KEY_RELEASED); - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_RELEASED); - return; - } - if ( (byte >= 0x61) && (byte <= 0x7A) ) { - // a .. z - byte -= 0x61; - enq_key_event(BX_KEY_A + byte, BX_KEY_PRESSED); - enq_key_event(BX_KEY_A + byte, BX_KEY_RELEASED); - return; - } - switch (byte) { - case 0x20: // Space - enq_key_event(BX_KEY_SPACE, BX_KEY_PRESSED); - enq_key_event(BX_KEY_SPACE, BX_KEY_RELEASED); - break; - case 0x21: // Exclamation Point - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_1, BX_KEY_PRESSED); - enq_key_event(BX_KEY_1, BX_KEY_RELEASED); - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_RELEASED); - break; - case 0x22: // Double Quotes - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_SINGLE_QUOTE, BX_KEY_PRESSED); - enq_key_event(BX_KEY_SINGLE_QUOTE, BX_KEY_RELEASED); - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_RELEASED); - break; - case 0x23: // Pound Sign - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_3, BX_KEY_PRESSED); - enq_key_event(BX_KEY_3, BX_KEY_RELEASED); - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_RELEASED); - break; - case 0x24: // Dollar Sign - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_4, BX_KEY_PRESSED); - enq_key_event(BX_KEY_4, BX_KEY_RELEASED); - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_RELEASED); - break; - case 0x25: // Percent - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_5, BX_KEY_PRESSED); - enq_key_event(BX_KEY_5, BX_KEY_RELEASED); - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_RELEASED); - break; - case 0x26: // Ampersand - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_7, BX_KEY_PRESSED); - enq_key_event(BX_KEY_7, BX_KEY_RELEASED); - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_RELEASED); - break; - case 0x27: // Single Quote - enq_key_event(BX_KEY_SINGLE_QUOTE, BX_KEY_PRESSED); - enq_key_event(BX_KEY_SINGLE_QUOTE, BX_KEY_RELEASED); - break; - case 0x28: // Left Paren - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_9, BX_KEY_PRESSED); - enq_key_event(BX_KEY_9, BX_KEY_RELEASED); - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_RELEASED); - break; - case 0x29: // Right Paren - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_0, BX_KEY_PRESSED); - enq_key_event(BX_KEY_0, BX_KEY_RELEASED); - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_RELEASED); - break; - case 0x2a: // Multiply - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_8, BX_KEY_PRESSED); - enq_key_event(BX_KEY_8, BX_KEY_RELEASED); - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_RELEASED); - break; - case 0x2b: // Add - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_EQUALS, BX_KEY_PRESSED); - enq_key_event(BX_KEY_EQUALS, BX_KEY_RELEASED); - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_RELEASED); - break; - case 0x2c: // Comma - enq_key_event(BX_KEY_COMMA, BX_KEY_PRESSED); - enq_key_event(BX_KEY_COMMA, BX_KEY_RELEASED); - break; - case 0x2d: // Minus - enq_key_event(BX_KEY_MINUS, BX_KEY_PRESSED); - enq_key_event(BX_KEY_MINUS, BX_KEY_RELEASED); - break; - case 0x2e: // Period - enq_key_event(BX_KEY_PERIOD, BX_KEY_PRESSED); - enq_key_event(BX_KEY_PERIOD, BX_KEY_RELEASED); - break; - case 0x2f: // Slash - enq_key_event(BX_KEY_SLASH, BX_KEY_PRESSED); - enq_key_event(BX_KEY_SLASH, BX_KEY_RELEASED); - break; - - case 0x3a: // Colon - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_SEMICOLON, BX_KEY_PRESSED); - enq_key_event(BX_KEY_SEMICOLON, BX_KEY_RELEASED); - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_RELEASED); - break; - case 0x3b: // Semi-Colon - enq_key_event(BX_KEY_SEMICOLON, BX_KEY_PRESSED); - enq_key_event(BX_KEY_SEMICOLON, BX_KEY_RELEASED); - break; - case 0x3c: // Less Than - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_COMMA, BX_KEY_PRESSED); - enq_key_event(BX_KEY_COMMA, BX_KEY_RELEASED); - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_RELEASED); - break; - case 0x3d: // Equals - enq_key_event(BX_KEY_EQUALS, BX_KEY_PRESSED); - enq_key_event(BX_KEY_EQUALS, BX_KEY_RELEASED); - break; - case 0x3e: // Greater Than - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_PERIOD, BX_KEY_PRESSED); - enq_key_event(BX_KEY_PERIOD, BX_KEY_RELEASED); - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_RELEASED); - break; - case 0x3f: // Question Mark - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_SLASH, BX_KEY_PRESSED); - enq_key_event(BX_KEY_SLASH, BX_KEY_RELEASED); - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_RELEASED); - break; - case 0x40: // At Sign - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_2, BX_KEY_PRESSED); - enq_key_event(BX_KEY_2, BX_KEY_RELEASED); - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_RELEASED); - break; - - case 0x5b: // Left Bracket - enq_key_event(BX_KEY_LEFT_BRACKET, BX_KEY_PRESSED); - enq_key_event(BX_KEY_LEFT_BRACKET, BX_KEY_RELEASED); - break; - case 0x5c: // Back Slash - enq_key_event(BX_KEY_BACKSLASH, BX_KEY_PRESSED); - enq_key_event(BX_KEY_BACKSLASH, BX_KEY_RELEASED); - break; - case 0x5d: // Right Bracket - enq_key_event(BX_KEY_RIGHT_BRACKET, BX_KEY_PRESSED); - enq_key_event(BX_KEY_RIGHT_BRACKET, BX_KEY_RELEASED); - break; - case 0x5e: // Caret - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_6, BX_KEY_PRESSED); - enq_key_event(BX_KEY_6, BX_KEY_RELEASED); - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_RELEASED); - break; - case 0x5f: // Underscore - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_MINUS, BX_KEY_PRESSED); - enq_key_event(BX_KEY_MINUS, BX_KEY_RELEASED); - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_RELEASED); - break; - case 0x60: // Grave Accent - enq_key_event(BX_KEY_GRAVE, BX_KEY_PRESSED); - enq_key_event(BX_KEY_GRAVE, BX_KEY_RELEASED); - break; - - case 0x7b: // Left Brace - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_LEFT_BRACKET, BX_KEY_PRESSED); - enq_key_event(BX_KEY_LEFT_BRACKET, BX_KEY_RELEASED); - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_RELEASED); - break; - case 0x7c: // Verticle Bar - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_BACKSLASH, BX_KEY_PRESSED); - enq_key_event(BX_KEY_BACKSLASH, BX_KEY_RELEASED); - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_RELEASED); - break; - case 0x7d: // Right Brace - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_RIGHT_BRACKET, BX_KEY_PRESSED); - enq_key_event(BX_KEY_RIGHT_BRACKET, BX_KEY_RELEASED); - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_RELEASED); - break; - case 0x7e: // Tilde - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_GRAVE, BX_KEY_PRESSED); - enq_key_event(BX_KEY_GRAVE, BX_KEY_RELEASED); - enq_key_event(BX_KEY_SHIFT_L, BX_KEY_RELEASED); - break; - - case B_BACKSPACE: - enq_key_event(BX_KEY_BACKSPACE, BX_KEY_PRESSED); - enq_key_event(BX_KEY_BACKSPACE, BX_KEY_RELEASED); - break; - case B_ENTER: //case B_RETURN: - enq_key_event(BX_KEY_ENTER, BX_KEY_PRESSED); - enq_key_event(BX_KEY_ENTER, BX_KEY_RELEASED); - break; - case B_TAB: - enq_key_event(BX_KEY_TAB, BX_KEY_PRESSED); - enq_key_event(BX_KEY_TAB, BX_KEY_RELEASED); - break; - case B_LEFT_ARROW: - enq_key_event(BX_KEY_LEFT, BX_KEY_PRESSED); - enq_key_event(BX_KEY_LEFT, BX_KEY_RELEASED); - break; - case B_RIGHT_ARROW: - enq_key_event(BX_KEY_RIGHT, BX_KEY_PRESSED); - enq_key_event(BX_KEY_RIGHT, BX_KEY_RELEASED); - break; - case B_UP_ARROW: - enq_key_event(BX_KEY_UP, BX_KEY_PRESSED); - enq_key_event(BX_KEY_UP, BX_KEY_RELEASED); - break; - case B_DOWN_ARROW: - enq_key_event(BX_KEY_DOWN, BX_KEY_PRESSED); - enq_key_event(BX_KEY_DOWN, BX_KEY_RELEASED); - break; -#if 0 - case B_FUNCTION_KEY: break; - msg->FindInt32("key", &key); - switch ( key ) { - case B_F1_KEY: break; - case B_F2_KEY: break; - case B_F3_KEY: break; - case B_F4_KEY: break; - case B_F5_KEY: break; - case B_F6_KEY: break; - case B_F7_KEY: break; - case B_F8_KEY: break; - case B_F9_KEY: break; - case B_F10_KEY: break; - case B_F11_KEY: break; - case B_F12_KEY: break; - case B_PRINT_KEY: break; - case B_SCROLL_KEY: break; - case B_PAUSE_KEY: break; - default: - fprintf(stderr, "# keydown() unknown function key %08xh\n", - (unsigned) key); - } -#endif - case B_INSERT: break; - enq_key_event(BX_KEY_INSERT, BX_KEY_PRESSED); - enq_key_event(BX_KEY_INSERT, BX_KEY_RELEASED); - break; - case B_DELETE: break; - enq_key_event(BX_KEY_DELETE, BX_KEY_PRESSED); - enq_key_event(BX_KEY_DELETE, BX_KEY_RELEASED); - break; - case B_HOME: break; - enq_key_event(BX_KEY_HOME, BX_KEY_PRESSED); - enq_key_event(BX_KEY_HOME, BX_KEY_RELEASED); - break; - case B_END: break; - enq_key_event(BX_KEY_END, BX_KEY_PRESSED); - enq_key_event(BX_KEY_END, BX_KEY_RELEASED); - break; - case B_PAGE_UP: break; - enq_key_event(BX_KEY_PAGE_UP, BX_KEY_PRESSED); - enq_key_event(BX_KEY_PAGE_UP, BX_KEY_RELEASED); - break; - case B_PAGE_DOWN: break; - enq_key_event(BX_KEY_PAGE_DOWN, BX_KEY_PRESSED); - enq_key_event(BX_KEY_PAGE_DOWN, BX_KEY_RELEASED); - break; - - default: - if ( (byte >= 0x01) && (byte <= 0x1a) ) { - // If the above keys dont catch this case, synthesize a - // Ctrl-A .. Ctrl-Z event - byte -= 1; - enq_key_event(BX_KEY_CTRL_L, BX_KEY_PRESSED); - enq_key_event(BX_KEY_A + byte, BX_KEY_PRESSED); - enq_key_event(BX_KEY_A + byte, BX_KEY_RELEASED); - enq_key_event(BX_KEY_CTRL_L, BX_KEY_RELEASED); - return; - } - fprintf(stderr, "# keydown: char %02xh unhandled\n", - (unsigned) bytes[0]); - return; - } - return; - } - else { - // ignore for now - fprintf(stderr, "# keydown() ignoring multibyte key\n"); - } -} +// ========== class ModifierFilter definitions ========== -void BochsView::KeyUp(const char *bytes, int32 numBytes) +ModifierFilter::ModifierFilter(BHandler *target): + BMessageFilter(B_MODIFIERS_CHANGED), + fTarget(target) { - UNUSED(bytes); - UNUSED(numBytes); + } -void BochsView::Draw(BRect rect) +filter_result ModifierFilter::Filter(BMessage *msg, BHandler **target) { - DrawBitmapAsync(backing_store, rect, rect); + *target = fTarget; + return B_DISPATCH_MESSAGE; } -BochsView::~BochsView() +void CaptureTarget::MessageReceived(BMessage *msg) { - delete backing_store; - delete backing_view; + if (fMyTarget->LockLooper()) + { + fMyTarget->GotCapturedInput(msg); + fMyTarget->UnlockLooper(); + } } -void -BochsView::SetFont(const BFont *font, uint32 mask) +// ========== class bx_gui_c definitions ========== + +void bx_gui_c::specific_init(bx_gui_c *th, int argc, char **argv, + unsigned tilewidth, unsigned tileheight, + unsigned header_bar_y) { - backing_store->Lock(); - backing_view->SetFont(font,mask); - backing_store->Unlock(); + BX_DEBUG(("init")); + bApp = new BochsApplication(th, argc, argv, tilewidth, tileheight, header_bar_y, power_handler); + be_app->Unlock(); + thread_id appThread = spawn_thread(BochsApplication::runme, "App thread", B_NORMAL_PRIORITY, NULL); + resume_thread(appThread); } -void -BochsView::SetHighColor(uchar r, uchar g, uchar b, uchar a) +void bx_gui_c::handle_events(void) { - backing_store->Lock(); - backing_view->SetHighColor(r,g,b,a); - backing_store->Unlock(); + bView->HandleEvents(); } -void -BochsView::SetLowColor(uchar r, uchar g, uchar b, uchar a) +void bx_gui_c::flush(void) { - backing_store->Lock(); - backing_view->SetLowColor(r,g,b,a); - backing_store->Unlock(); + BX_DEBUG(("flush")); + if (!bView) + { + BX_DEBUG(("flush called before init")); + return; + } + bView->Flush(); } -void -BochsView::DrawBitmap(const BBitmap *aBitmap, BPoint where) +void bx_gui_c::clear_screen(void) { - backing_store->Lock(); - backing_view->DrawBitmap(aBitmap,where); - backing_store->Unlock(); - BRect r = aBitmap->Bounds(); - r.OffsetBy(where); - Invalidate(r); + BX_DEBUG(("clear_screen")); + bView->ClearScreen(); } -void -BochsView::FillRect(BRect r, pattern p) +void bx_gui_c::text_update(Bit8u *old_text, Bit8u *new_text, + unsigned long cursor_x, unsigned long cursor_y, + Bit16u cursor_state, unsigned nrows) { - backing_store->Lock(); - backing_view->FillRect(r,p); - backing_store->Unlock(); - Invalidate(r); + BX_DEBUG(("text_update")); + bView->TextUpdate(old_text, new_text, cursor_x, cursor_y, nrows, cursor_state); } - - - void -enq_key_event(Bit32u key, Bit32u press_release) +int bx_gui_c::get_clipboard_text(Bit8u **bytes, Bit32s *nbytes) { - if ( ((tail+1) % SCANCODE_BUFSIZE) == head ) { - fprintf(stderr, "# enq_key_event: buffer full\n"); - return; - } - keyevents[tail] = key | press_release; - tail = (tail + 1) % SCANCODE_BUFSIZE; + return 0; } - Bit32u -deq_key_event(void) +int bx_gui_c::set_clipboard_text(char *text_snapshot, Bit32u len) { - Bit32u key; - - if ( head == tail ) { - fprintf(stderr, "# deq_key_event: buffer empty\n"); - return(0); - } - key = keyevents[head]; - head = (head + 1) % SCANCODE_BUFSIZE; - return(key); + return 0; } - - unsigned char -reverse_bitorder(unsigned char b) + +void bx_gui_c::graphics_tile_update(Bit8u *tile, unsigned x0, unsigned y0) { - unsigned char ret=0; - for (unsigned i=0; i<8; i++) { - ret |= (b & 0x01) << (7-i); - b >>= 1; - } - return(ret); + //fprintf(stderr, "# gui: graphics_update\n"); + bView->GraphicsTileUpdate(tile, x0, y0); } - unsigned -bx_gui_c::create_bitmap(const unsigned char *bmap, - unsigned xdim, unsigned ydim) +Boolean bx_gui_c::palette_change(unsigned index, unsigned red, unsigned green, unsigned blue) { - BRect rect(0.0, 0.0, xdim-1, ydim-1); - int32 bitslength; - //int32 bytesperrow; - unsigned char *data; - - if (bx_bitmap_entries >= BX_MAX_PIXMAPS) { - BX_PANIC(("beos: too many pixmaps, increase BX_MAX_PIXMAPS")); - } - - bx_bitmaps[bx_bitmap_entries].bmap = - new BBitmap(rect, B_MONOCHROME_1_BIT); - - bitslength = bx_bitmaps[bx_bitmap_entries].bmap->BitsLength(); - //bytesperrow = bx_bitmaps[bx_bitmap_entries].bmap->BytesPerRow(); - data = (unsigned char *) bx_bitmaps[bx_bitmap_entries].bmap->Bits(); - for (int32 i=0; iPaletteChange(index, red, green, blue); } - unsigned -bx_gui_c::headerbar_bitmap(unsigned bmap_id, unsigned alignment, - void (*f)(void)) +void bx_gui_c::dimension_update(unsigned x, unsigned y, unsigned fheight) { - unsigned hb_index; - - if ( (bx_headerbar_entries+1) > BX_MAX_HEADERBAR_ENTRIES ) - BX_PANIC(("beos: too many headerbar entries, increase BX_MAX_HEADERBAR_ENTRIES")); - - bx_headerbar_entries++; - hb_index = bx_headerbar_entries - 1; - - bx_headerbar_entry[hb_index].bitmap = bx_bitmaps[bmap_id].bmap; - bx_headerbar_entry[hb_index].xdim = bx_bitmaps[bmap_id].xdim; - bx_headerbar_entry[hb_index].ydim = bx_bitmaps[bmap_id].ydim; - bx_headerbar_entry[hb_index].alignment = alignment; - bx_headerbar_entry[hb_index].f = f; - if (alignment == BX_GRAVITY_LEFT) { - bx_headerbar_entry[hb_index].xorigin = bx_bitmap_left_xorigin; - bx_headerbar_entry[hb_index].yorigin = 0; - bx_bitmap_left_xorigin += bx_bitmaps[bmap_id].xdim; - } - else { // BX_GRAVITY_RIGHT - bx_bitmap_right_xorigin += bx_bitmaps[bmap_id].xdim; - bx_headerbar_entry[hb_index].xorigin = bx_bitmap_right_xorigin; - bx_headerbar_entry[hb_index].yorigin = 0; - } - return(hb_index); + //fprintf(stderr, "dimension_update %d x %d\n", x, y); + bView->DimensionUpdate(x, y, fheight); } - void -bx_gui_c::replace_bitmap(unsigned hbar_id, unsigned bmap_id) +void bx_gui_c::exit(void) { - unsigned xorigin; - - bx_headerbar_entry[hbar_id].bitmap = bx_bitmaps[bmap_id].bmap; - - if (bx_headerbar_entry[hbar_id].alignment == BX_GRAVITY_LEFT) - xorigin = bx_headerbar_entry[hbar_id].xorigin; - else - xorigin = dimension_x - bx_headerbar_entry[hbar_id].xorigin; - aWindow->Lock(); - aView->set_headerbar_colors(); - aView->DrawBitmap(bx_headerbar_entry[hbar_id].bitmap, BPoint(xorigin, 0)); - aView->set_text_colors(); - aWindow->Unlock(); + BX_DEBUG(("exit")); + bApp->BxExit(); } - void -bx_gui_c::show_headerbar(void) +void bx_gui_c::mouse_enabled_changed_specific(Boolean val) { - unsigned xorigin; - BPoint origin; - - // clear header bar area to white - - aWindow->Lock(); - aView->set_headerbar_colors(); - aView->FillRect(BRect(0, 0, dimension_x-1, bx_headerbar_y-1), B_SOLID_LOW); - for (unsigned i=0; iDrawBitmap( bx_headerbar_entry[i].bitmap, origin ); - } - aView->set_text_colors(); - aWindow->Unlock(); + //fprintf(stderr, "mouse_enabled_changed to %s\n", val ? "enabled" : "disabled"); + bView->HandleEnableMouse(val); } - - void -headerbar_click(int x, int y) +unsigned bx_gui_c::create_bitmap(const unsigned char *bmap, + unsigned xdim, unsigned ydim) { - int xorigin; - - // assuming y is in bounds - UNUSED(y); - for (unsigned i=0; i=xorigin) && (x<(xorigin+int(bx_headerbar_entry[i].xdim))) ) { - bx_headerbar_entry[i].f(); - return; - } - } + BX_DEBUG(("create_bitmap")); + return bView->CreateBitmap(bmap, xdim, ydim); } - - void -create_vga_font(void) +unsigned bx_gui_c::headerbar_bitmap(unsigned bmap_id, unsigned alignment, void (*f)(void)) { - int32 bitslength; - int32 bytesperrow; - unsigned char *data; - BRect brect(0,0, 7,15); - - BX_INFO(( "BeOS: creating VGA font from bitmaps" )); - - // VGA font is 8wide x 16high - for (unsigned c=0; c<256; c++) { - vgafont[c] = new BBitmap(brect, B_MONOCHROME_1_BIT); - if (!vgafont[c]) { - BX_PANIC(("beos: could not create bitmap")); - } - - bitslength = vgafont[c]->BitsLength(); - bytesperrow = vgafont[c]->BytesPerRow(); - data = (unsigned char *) vgafont[c]->Bits(); - memset(data, 0, bitslength); - for (unsigned i=0; i<16; i++) { - data[i*bytesperrow] = reverse_bitorder(bx_vgafont[c].data[i]); - } - } + BX_DEBUG(("headerbar_bitmap")); + return bView->HeaderbarBitmap(bmap_id, alignment, f); } - - void -bx_gui_c::exit(void) +void bx_gui_c::replace_bitmap(unsigned hbar_id, unsigned bmap_id) { - fprintf(stderr, "# WARNING: BEOS: bx_gui_c::exit() not implemented yet.\n"); + BX_DEBUG(("replace_bitmap")); + bView->ReplaceBitmap(hbar_id, bmap_id); } -//IRA=> Start -// This is called whenever the mouse_enabled parameter changes. It -// can change because of a gui event such as clicking on the mouse-enable -// bitmap or pressing the middle button, or from the control panel. -// In all those cases, setting the parameter value will get you here. - - void -bx_gui_c::mouse_enabled_changed_specific (Boolean val) +void bx_gui_c::show_headerbar(void) { - BX_DEBUG (("mouse_enabled=%d, BeOS specific code", val?1:0)); - if (val) { - BX_INFO(("[x] Mouse on")); -// mouse_enable_x = current_x; -// mouse_enable_y = current_y; - be_app->HideCursor(); - // Move the cursor to a 'safe' place -// warp_cursor(warp_home_x-current_x, warp_home_y-current_y); - } else { - BX_INFO(("[x] Mouse off")); - be_app->ShowCursor(); -// warp_cursor(mouse_enable_x-current_x, mouse_enable_y-current_y); - } + BX_DEBUG(("show_headrebar")); + bView->ShowHeaderbar(); } -//IRA=> End