----------------------------------------------------------------------
Patch name: patch.beos-gui-fabo
Author: Marton Fabo <morton@eik.bme.hu>
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 <app/Application.h>
 #include <interface/Window.h>
 #include <interface/View.h>
+#include <MessageFilter.h>
 #include <interface/Screen.h>
 #include <interface/Bitmap.h>
 #include <interface/GraphicsDefs.h>
@@ -39,1179 +40,1279 @@
 #include <string.h>
 
 #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(&current, &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; i<nchars*2; i+=2) {
-    if ( (old_text[i]!=new_text[i]) ||
-         (old_text[i+1]!=new_text[i+1]) ) {
-
-      achar = new_text[i];
-
-      x = (i/2) % ncols;
-      y = (i/2) / ncols;
-
-      point.Set(x*8, y*16 + bx_headerbar_y);
-      aView->DrawBitmap(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; y<y_tilesize; y++) {
-    for (unsigned x=0; x<x_tilesize; x++) {
-      rawdata[y*rowsize_padded + x] = cmap_index[ tile[y*x_tilesize + x] ];
-      }
-    }
-  aWindow->Lock();
-  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; i<bitslength; i++) {
-    data[i] = reverse_bitorder(bmap[i]);
-    }
-
-  bx_bitmaps[bx_bitmap_entries].xdim = xdim;
-  bx_bitmaps[bx_bitmap_entries].ydim = ydim;
-  if (!bx_bitmaps[bx_bitmap_entries].bmap) {
-    BX_PANIC(("beos: could not create bitmap"));
-    }
-  bx_bitmap_entries++;
-  return(bx_bitmap_entries-1); // return index as handle
+	BX_DEBUG(("palette_change"));
+	return bView->PaletteChange(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; i<bx_headerbar_entries; i++) {
-    if (bx_headerbar_entry[i].alignment == BX_GRAVITY_LEFT)
-      xorigin = bx_headerbar_entry[i].xorigin;
-    else
-      xorigin = dimension_x - bx_headerbar_entry[i].xorigin;
-    origin.Set(xorigin, 0);
-    aView->DrawBitmap( 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<bx_headerbar_entries; i++) {
-    if (bx_headerbar_entry[i].alignment == BX_GRAVITY_LEFT)
-      xorigin = bx_headerbar_entry[i].xorigin;
-    else
-      xorigin = dimension_x - bx_headerbar_entry[i].xorigin;
-    if ( (x>=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
