diff --git a/src/gui_haiku.cc b/src/gui_haiku.cc
new file mode 100644
index 0000000..b7ecf64
--- /dev/null
+++ b/src/gui_haiku.cc
@@ -0,0 +1,5242 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *    BeBox GUI support Copyright 1998 by Olaf Seibert.
+ *                  All Rights Reserved.
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ *
+ * Based on "GUI support for the Buzzword Enhanced Operating System."
+ *
+ * Ported to R4 by Richard Offer <richard@whitequeen.com> Jul 99
+ *
+ * Haiku support by Siarzhuk Zharski <imker@gmx.li> Apr-Mai 2009
+ *
+ */
+
+/*
+ * Structure of the Haiku GUI code:
+ *
+ * There are 3 threads.
+ * 1. The initial thread. In gui_mch_prepare() this gets to run the
+ *    BApplication message loop. But before it starts doing that,
+ *    it creates thread 2
+ * 2. The main() thread. This thread is created in gui_mch_prepare()
+ *    and its purpose in life is to call main(argc, argv) again.
+ *    This thread is doing the bulk of the work.
+ * 3. Sooner or later, a window is opened by the main() thread. This
+ *    causes a second message loop to be created: the window thread.
+ *
+ * == alternatively ===
+ *
+ * #if RUN_BAPPLICATION_IN_NEW_THREAD...
+ *
+ * 1. The initial thread. In gui_mch_prepare() this gets to spawn
+ *    thread 2. After doing that, it returns to main() to do the
+ *    bulk of the work, being the main() thread.
+ * 2. Runs the BApplication.
+ * 3. The window thread, just like in the first case.
+ *
+ * This second alternative is cleaner from Vim's viewpoint. However,
+ * the BeBook seems to assume everywhere that the BApplication *must*
+ * run in the initial thread. So perhaps doing otherwise is very wrong.
+ *
+ * However, from a B_SINGLE_LAUNCH viewpoint, the first is better.
+ * If Vim is marked "Single Launch" in its application resources,
+ * and a file is dropped on the Vim icon, and another Vim is already
+ * running, the file is passed on to the earlier Vim. This happens
+ * in BApplication::Run(). So we want Vim to terminate if
+ * BApplication::Run() terminates. (See the BeBook, on BApplication.
+ * However, it seems that the second copy of Vim isn't even started
+ * in this case... which is for the better since I wouldn't know how
+ * to detect this case.)
+ *
+ * Communication between these threads occurs mostly by translating
+ * BMessages that come in and posting an appropriate translation on
+ * the VDCMP (Vim Direct Communication Message Port). Therefore the
+ * actions required for keypresses and window resizes, etc, are mostly
+ * performed in the main() thread.
+ *
+ * A notable exception to this is the Draw() event. The redrawing of
+ * the window contents is performed asynchronously from the window
+ * thread. To make this work correctly, a locking protocol is used when
+ * any thread is accessing the essential variables that are used by
+ * the window thread.
+ *
+ * This locking protocol consists of locking Vim's window. This is both
+ * convenient and necessary.
+ */
+
+extern "C" {
+
+#include <assert.h>
+#include <float.h>
+#include <syslog.h>
+
+#include "vim.h"
+#include "globals.h"
+#include "proto.h"
+#include "version.h"
+
+}	// extern "C"
+
+// ---------------- start of header part ----------------
+
+//#include <Alert.h>
+#include <Application.h>
+#include <Beep.h>
+#include <Bitmap.h>
+#include <Box.h>
+#include <Button.h>
+#include <Clipboard.h>
+#include <Debug.h>
+//#include <Directory.h>
+//#include <Entry.h>
+#include <File.h>
+#include <FilePanel.h>
+#include <FindDirectory.h>
+//#include <Font.h>
+#include <IconUtils.h>
+#include <Input.h>
+#include <ListView.h>
+#include <MenuBar.h>
+#include <MenuItem.h>
+//#include <MessageQueue.h>
+//#include <OS.h>
+#include <Path.h>
+#include <PictureButton.h>
+#include <PopUpMenu.h>
+//#include <Region.h>
+#include <Resources.h>
+//#include <Roster.h>
+#include <Screen.h>
+#include <ScrollBar.h>
+#include <ScrollView.h>
+#include <String.h>
+#include <StringView.h>
+//#include <SupportDefs.h>
+#include <TabView.h>
+#include <TextControl.h>
+#include <TextView.h>
+#include <TranslationUtils.h>
+#include <TranslatorFormats.h>
+#include <View.h>
+#include <Window.h>
+
+class VimApp;
+class VimFormView;
+class VimTextAreaView;
+class VimWindow;
+class VimToolbar;
+class VimTabLine;
+
+extern key_map *keyMap;
+extern char *keyMapChars;
+
+extern int main(int argc, char **argv);
+
+#ifndef B_MAX_PORT_COUNT
+#define B_MAX_PORT_COUNT    255
+#endif
+
+// VimApp seems comparable to the X "vimShell"
+class VimApp: public BApplication
+{
+	typedef BApplication Inherited;
+	public:
+	VimApp(const char *appsig);
+	~VimApp();
+
+	// callbacks:
+#if 0
+	virtual void DispatchMessage(BMessage *m, BHandler *h)
+	{
+		m->PrintToStream();
+		Inherited::DispatchMessage(m, h);
+	}
+#endif
+	virtual void ReadyToRun();
+	virtual void ArgvReceived(int32 argc, char **argv);
+	virtual void RefsReceived(BMessage *m);
+	virtual bool QuitRequested();
+	virtual void MessageReceived(BMessage *m);
+
+	static void SendRefs(BMessage *m, bool changedir);
+
+	sem_id		fFilePanelSem;
+	BFilePanel*	fFilePanel;
+	BPath		fBrowsedPath;
+	private:
+};
+
+class VimWindow: public BWindow
+{
+	typedef BWindow Inherited;
+	public:
+	VimWindow();
+	~VimWindow();
+
+	//    virtual void DispatchMessage(BMessage *m, BHandler *h);
+	virtual void WindowActivated(bool active);
+	virtual bool QuitRequested();
+
+	VimFormView		*formView;
+
+	private:
+	void init();
+
+};
+
+class VimFormView: public BView
+{
+	typedef BView Inherited;
+	public:
+	VimFormView(BRect frame);
+	~VimFormView();
+
+	// callbacks:
+	virtual void AllAttached();
+	virtual void FrameResized(float new_width, float new_height);
+
+#define MENUBAR_MARGIN	1
+	float MenuHeight() const
+	{ return menuBar ? menuBar->Frame().Height() + MENUBAR_MARGIN: 0; }
+	BMenuBar *MenuBar() const
+	{ return menuBar; }
+
+	private:
+	void init(BRect);
+
+	BMenuBar		*menuBar;
+	VimTextAreaView	*textArea;
+
+#ifdef FEAT_TOOLBAR
+	public:
+	float ToolbarHeight() const;
+	VimToolbar *ToolBar() const
+	{ return toolBar; }
+	private:
+	VimToolbar		*toolBar;
+#endif
+
+#ifdef FEAT_GUI_TABLINE
+	public:
+	VimTabLine *TabLine() const	{ return tabLine; }
+	bool IsShowingTabLine() const { return showingTabLine; }
+	void SetShowingTabLine(bool showing) { showingTabLine = showing;	}
+	float TablineHeight() const;
+	private:
+	VimTabLine	*tabLine;
+	int	showingTabLine;
+#endif
+};
+
+class VimTextAreaView: public BView
+{
+	typedef BView Inherited;
+	public:
+	VimTextAreaView(BRect frame);
+	~VimTextAreaView();
+
+	// callbacks:
+	virtual void Draw(BRect updateRect);
+	virtual void KeyDown(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 *m);
+
+	// own functions:
+	int mchInitFont(char_u *name);
+	void mchDrawString(int row, int col, char_u *s, int len, int flags);
+	void mchClearBlock(int row1, int col1, int row2, int col2);
+	void mchClearAll();
+	void mchDeleteLines(int row, int num_lines);
+	void mchInsertLines(int row, int num_lines);
+
+	static void guiSendMouseEvent(int button, int x, int y, int repeated_click, int_u modifiers);
+	static void guiMouseMoved(int x, int y);
+	static void guiBlankMouse(bool should_hide);
+	static int_u mouseModifiersToVim(int32 beModifiers);
+
+	int32 mouseDragEventCount;
+
+#ifdef FEAT_MBYTE_IME
+	void DrawIMString(void);
+#endif
+
+	private:
+	void init(BRect);
+
+	int_u	    vimMouseButton;
+	int_u	    vimMouseModifiers;
+
+#ifdef FEAT_MBYTE_IME
+	struct {
+		BMessenger* messenger;
+		BMessage* message;
+		BPoint location;
+		int row;
+		int col;
+		int count;
+	} IMData;
+#endif
+};
+
+class VimScrollBar: public BScrollBar
+{
+	typedef BScrollBar Inherited;
+	public:
+	VimScrollBar(scrollbar_T *gsb, orientation posture);
+	~VimScrollBar();
+
+	virtual void ValueChanged(float newValue);
+	virtual void MouseUp(BPoint where);
+	void SetValue(float newval);
+	scrollbar_T *getGsb()
+	{ return gsb; }
+
+	int32	    scrollEventCount;
+
+	private:
+	scrollbar_T *gsb;
+	float	ignoreValue;
+};
+
+
+#ifdef FEAT_TOOLBAR
+
+class VimToolbar : public BBox
+{
+	static BBitmap *normalButtonsBitmap;
+	static BBitmap *grayedButtonsBitmap;
+
+	BBitmap *LoadVimBitmap(const char* fileName);
+	bool GetPictureFromBitmap(BPicture *pictureTo, int32 index, BBitmap *bitmapFrom, bool pressed);
+	bool ModifyBitmapToGrayed(BBitmap *bitmap);
+
+	BList fButtonsList;
+	void InvalidateLayout();
+
+	public:
+	VimToolbar(BRect frame, const char * name);
+	~VimToolbar();
+
+	bool PrepareButtonBitmaps();
+
+	bool AddButton(int32 index, vimmenu_T *menu);
+	bool RemoveButton(vimmenu_T *menu);
+	bool GrayButton(vimmenu_T *menu, int grey);
+
+	float ToolbarHeight() const;
+	virtual void AttachedToWindow();
+};
+
+BBitmap *VimToolbar::normalButtonsBitmap  = NULL;
+BBitmap *VimToolbar::grayedButtonsBitmap  = NULL;
+
+const float ToolbarMargin = 3.;
+const float ButtonMargin  = 3.;
+
+#endif //FEAT_TOOLBAR
+
+#ifdef FEAT_GUI_TABLINE
+
+class VimTabLine : public BTabView
+{
+	public:
+		class VimTab : public BTab {
+			public:
+				VimTab() : BTab(new BView(BRect(), "-Empty-", 0, 0)) {}
+
+			virtual void Select(BView* owner);
+		};
+
+		VimTabLine(BRect r) : BTabView(r, "vimTabLine", B_WIDTH_FROM_LABEL,
+			   B_FOLLOW_LEFT | B_FOLLOW_TOP | B_FOLLOW_RIGHT, B_WILL_DRAW | B_FRAME_EVENTS) {}
+
+	float TablineHeight() const;
+	virtual void MouseDown(BPoint point);
+};
+
+#endif //FEAT_GUI_TABLINE
+
+
+// For caching the fonts that are used;
+// Vim seems rather sloppy in this regard.
+class VimFont: public BFont
+{
+	typedef BFont Inherited;
+	public:
+	VimFont();
+	VimFont(const VimFont *rhs);
+	VimFont(const BFont *rhs);
+	VimFont(const VimFont &rhs);
+	~VimFont();
+
+	VimFont *next;
+	int refcount;
+	char_u *name;
+
+	private:
+	void init();
+};
+
+#if defined(FEAT_GUI_DIALOG)
+
+class VimDialog : public BWindow
+{
+	typedef BWindow Inherited;
+
+	BButton* _CreateButton(int32 which, const char* label);
+
+	public:
+
+	class View : public BView {
+		typedef BView Inherited;
+
+		public:
+		View(BRect frame);
+		~View();
+
+		virtual void Draw(BRect updateRect);
+		void InitIcon(int32 type);
+
+		private:
+		BBitmap*	fIconBitmap;
+	};
+
+	VimDialog(int type, const char *title, const char *message,
+			const char *buttons, int dfltbutton, const char *textfield,
+			int ex_cmd);
+	~VimDialog();
+
+	int Go();
+
+	virtual void MessageReceived(BMessage *msg);
+
+	private:
+	sem_id			fDialogSem;
+	int				fDialogValue;
+	BList			fButtonsList;
+	BTextView*		fMessageView;
+	BTextControl*	fInputControl;
+	const char*		fInputValue;
+};
+
+class VimSelectFontDialog : public BWindow
+{
+	typedef BWindow Inherited;
+
+	void _CleanList(BListView* list);
+	void _UpdateFontStyles();
+	void _UpdateSizeInputPreview();
+	void _UpdateFontPreview();
+	bool _UpdateFromListItem(BListView* list, char* text, int textSize);
+	public:
+
+	VimSelectFontDialog(font_family* family, font_style* style, float* size);
+	~VimSelectFontDialog();
+
+	bool Go();
+
+	virtual void MessageReceived(BMessage *msg);
+
+	private:
+	status_t		fStatus;
+	sem_id			fDialogSem;
+	bool			fDialogValue;
+	font_family*	fFamily;
+	font_style*		fStyle;
+	float*			fSize;
+	font_family		fFontFamily;
+	font_style		fFontStyle;
+	float			fFontSize;
+	BStringView*	fPreview;
+	BListView*		fFamiliesList;
+	BListView*		fStylesList;
+	BListView*		fSizesList;
+	BTextControl*	fSizesInput;
+};
+
+#endif // FEAT_GUI_DIALOG
+
+// ---------------- end of GUI classes ----------------
+
+struct MainArgs {
+	int		 argc;
+	char	**argv;
+};
+
+// These messages are copied through the VDCMP.
+// Therefore they ought not to have anything fancy.
+// They must be of POD type (Plain Old Data)
+// as the C++ standard calls them.
+
+#define	KEY_MSG_BUFSIZ	7
+#if KEY_MSG_BUFSIZ < MAX_KEY_CODE_LEN
+#error Increase KEY_MSG_BUFSIZ!
+#endif
+
+struct VimKeyMsg {
+	char_u	length;
+	char_u	chars[KEY_MSG_BUFSIZ];	// contains Vim encoding
+	bool    csi_escape;
+};
+
+struct VimResizeMsg {
+	int		width;
+	int		height;
+};
+
+struct VimScrollBarMsg {
+	VimScrollBar *sb;
+	long	value;
+	int		stillDragging;
+};
+
+struct VimMenuMsg {
+	vimmenu_T	*guiMenu;
+};
+
+struct VimMouseMsg {
+	int		button;
+	int		x;
+	int		y;
+	int		repeated_click;
+	int_u	modifiers;
+};
+
+struct VimMouseMovedMsg {
+	int		x;
+	int		y;
+};
+
+struct VimFocusMsg {
+	bool	active;
+};
+
+struct VimRefsMsg {
+	BMessage   *message;
+	bool	changedir;
+};
+
+struct VimTablineMsg {
+	int		index;
+};
+
+struct VimTablineMenuMsg {
+	int		index;
+	int		event;
+};
+
+struct VimMsg {
+	enum VimMsgType {
+		Key, Resize, ScrollBar, Menu, Mouse, MouseMoved, Focus, Refs, Tabline, TablineMenu
+	};
+
+	union {
+		struct VimKeyMsg	Key;
+		struct VimResizeMsg	NewSize;
+		struct VimScrollBarMsg	Scroll;
+		struct VimMenuMsg	Menu;
+		struct VimMouseMsg	Mouse;
+		struct VimMouseMovedMsg	MouseMoved;
+		struct VimFocusMsg	Focus;
+		struct VimRefsMsg	Refs;
+		struct VimTablineMsg	Tabline;
+		struct VimTablineMenuMsg	TablineMenu;
+	} u;
+};
+
+#define RGB(r, g, b)	((char_u)(r) << 16 | (char_u)(g) << 8 | (char_u)(b) << 0)
+#define GUI_TO_RGB(g)	{ (g) >> 16, (g) >> 8, (g) >> 0, 255 }
+
+// ---------------- end of header part ----------------
+
+static struct specialkey
+{
+	uint16  BeKeys;
+#define KEY(a,b)	((a)<<8|(b))
+#define K(a)		KEY(0,a)		    // for ASCII codes
+#define F(b)		KEY(1,b)		    // for scancodes
+	char_u  vim_code0;
+	char_u  vim_code1;
+} special_keys[] =
+{
+	{K(B_UP_ARROW),	    'k', 'u'},
+	{K(B_DOWN_ARROW),	    'k', 'd'},
+	{K(B_LEFT_ARROW),	    'k', 'l'},
+	{K(B_RIGHT_ARROW),	    'k', 'r'},
+	{K(B_BACKSPACE),	    'k', 'b'},
+	{K(B_INSERT),	    'k', 'I'},
+	{K(B_DELETE),	    'k', 'D'},
+	{K(B_HOME),		    'k', 'h'},
+	{K(B_END),		    '@', '7'},
+	{K(B_PAGE_UP),	    'k', 'P'},	    // XK_Prior
+	{K(B_PAGE_DOWN),	    'k', 'N'},	    // XK_Next,
+
+#define FIRST_FUNCTION_KEY  11
+	{F(B_F1_KEY),	    'k', '1'},
+	{F(B_F2_KEY),	    'k', '2'},
+	{F(B_F3_KEY),	    'k', '3'},
+	{F(B_F4_KEY),	    'k', '4'},
+	{F(B_F5_KEY),	    'k', '5'},
+	{F(B_F6_KEY),	    'k', '6'},
+	{F(B_F7_KEY),	    'k', '7'},
+	{F(B_F8_KEY),	    'k', '8'},
+	{F(B_F9_KEY),	    'k', '9'},
+	{F(B_F10_KEY),	    'k', ';'},
+
+	{F(B_F11_KEY),	    'F', '1'},
+	{F(B_F12_KEY),	    'F', '2'},
+	//  {XK_F13,		    'F', '3'},	// would be print screen
+	// sysreq
+	{F(0x0F),		    'F', '4'},		// scroll lock
+	{F(0x10),		    'F', '5'},		// pause/break
+	//  {XK_F16,	    'F', '6'},
+	//  {XK_F17,	    'F', '7'},
+	//  {XK_F18,	    'F', '8'},
+	//  {XK_F19,	    'F', '9'},
+	//   {XK_F20,	    'F', 'A'},
+	//  {XK_F21,	    'F', 'B'},
+	//  {XK_F22,	    'F', 'C'},
+	//  {XK_F23,	    'F', 'D'},
+	//  {XK_F24,	    'F', 'E'},
+	//  {XK_F25,	    'F', 'F'},
+	//  {XK_F26,	    'F', 'G'},
+	//  {XK_F27,	    'F', 'H'},
+	//  {XK_F28,	    'F', 'I'},
+	//  {XK_F29,	    'F', 'J'},
+	//  {XK_F30,	    'F', 'K'},
+	//  {XK_F31,	    'F', 'L'},
+	//  {XK_F32,	    'F', 'M'},
+	//  {XK_F33,	    'F', 'N'},
+	//  {XK_F34,	    'F', 'O'},
+	//  {XK_F35,	    'F', 'P'},	    // keysymdef.h defines up to F35
+
+	//  {XK_Help,	    '%', '1'},	    // XK_Help
+	{F(B_PRINT_KEY),	    '%', '9'},
+
+#if 0
+	// Keypad keys:
+	{F(0x48),	    'k', 'l'},	    // XK_KP_Left
+	{F(0x4A),	    'k', 'r'},	    // XK_KP_Right
+	{F(0x38),	    'k', 'u'},	    // XK_KP_Up
+	{F(0x59),	    'k', 'd'},	    // XK_KP_Down
+	{F(0x64),	    'k', 'I'},	    // XK_KP_Insert
+	{F(0x65),	    'k', 'D'},	    // XK_KP_Delete
+	{F(0x37),	    'k', 'h'},	    // XK_KP_Home
+	{F(0x58),	    '@', '7'},	    // XK_KP_End
+	{F(0x39),	    'k', 'P'},	    // XK_KP_Prior
+	{F(0x60),	    'k', 'N'},	    // XK_KP_Next
+	{F(0x49),	    '&', '8'},	    // XK_Undo, keypad 5
+#endif
+
+	// End of list marker:
+	{0,			    0, 0}
+};
+
+#define NUM_SPECIAL_KEYS    (sizeof(special_keys)/sizeof(special_keys[0]))
+
+// ---------------- VimApp ----------------
+
+	static void
+docd(BPath &path)
+{
+	mch_chdir((char *)path.Path());
+	// Do this to get the side effects of a :cd command
+	do_cmdline_cmd((char_u *)"cd .");
+}
+
+        static void
+drop_callback(void *cookie)
+{
+    // TODO here we could handle going to a specific position in the dropped
+    // file (see src/gui_mac.c)
+    // Update the screen display
+    update_screen(NOT_VALID);
+}
+
+    // Really handle dropped files and folders.
+        static void
+RefsReceived(BMessage *m, bool changedir)
+{
+	uint32 type;
+	int32 count;
+
+	m->PrintToStream();
+	switch (m->what) {
+		case B_REFS_RECEIVED:
+		case B_SIMPLE_DATA:
+			m->GetInfo("refs", &type, &count);
+			if (type != B_REF_TYPE)
+				goto bad;
+			break;
+		case B_ARGV_RECEIVED:
+			m->GetInfo("argv", &type, &count);
+			if (type != B_STRING_TYPE)
+				goto bad;
+			if (changedir) {
+				char *dirname;
+				if (m->FindString("cwd", (const char **) &dirname) == B_OK) {
+					chdir(dirname);
+					do_cmdline_cmd((char_u *)"cd .");
+				}
+			}
+			break;
+		default:
+bad:
+			/*fprintf(stderr, "bad!\n"); */
+			delete m;
+			return;
+	}
+
+#ifdef FEAT_VISUAL
+	reset_VIsual();
+#endif
+
+	char_u  **fnames;
+	fnames = (char_u **) alloc(count * sizeof(char_u *));
+	int fname_index = 0;
+
+	switch (m->what) {
+		case B_REFS_RECEIVED:
+		case B_SIMPLE_DATA:
+			// fprintf(stderr, "case B_REFS_RECEIVED\n");
+			for (int i = 0; i < count; ++i)
+			{
+				entry_ref ref;
+				if (m->FindRef("refs", i, &ref) == B_OK) {
+					BEntry entry(&ref, false);
+					BPath path;
+					entry.GetPath(&path);
+
+					// Change to parent directory?
+					if (changedir) {
+						BPath parentpath;
+						path.GetParent(&parentpath);
+						docd(parentpath);
+					}
+
+					// Is it a directory? If so, cd into it.
+					BDirectory bdir(&ref);
+					if (bdir.InitCheck() == B_OK) {
+						// don't cd if we already did it
+						if (!changedir)
+							docd(path);
+					} else {
+						mch_dirname(IObuff, IOSIZE);
+						char_u *fname = shorten_fname((char_u *)path.Path(), IObuff);
+						if (fname == NULL)
+							fname = (char_u *)path.Path();
+						fnames[fname_index++] = vim_strsave(fname);
+						// fprintf(stderr, "%s\n", fname);
+					}
+
+					// Only do it for the first file/dir
+					changedir = false;
+				}
+			}
+			break;
+		case B_ARGV_RECEIVED:
+			// fprintf(stderr, "case B_ARGV_RECEIVED\n");
+			for (int i = 1; i < count; ++i)
+			{
+				char *fname;
+
+				if (m->FindString("argv", i, (const char **) &fname) == B_OK) {
+					fnames[fname_index++] = vim_strsave((char_u *)fname);
+				}
+			}
+			break;
+		default:
+			// fprintf(stderr, "case default\n");
+			break;
+	}
+
+	delete m;
+
+	// Handle the drop, :edit to get to the file
+	if (fname_index > 0) {
+		handle_drop(fname_index, fnames, FALSE, drop_callback, NULL);
+
+		setcursor();
+		out_flush();
+	} else {
+		vim_free(fnames);
+	}
+}
+
+VimApp::VimApp(const char *appsig):
+	BApplication(appsig),
+	fFilePanelSem(-1),
+	fFilePanel(NULL)
+{
+}
+
+VimApp::~VimApp()
+{
+}
+
+	void
+VimApp::ReadyToRun()
+{
+	/*
+	 * Apparently signals are inherited by the created thread -
+	 * disable the most annoying ones.
+	 */
+	signal(SIGINT, SIG_IGN);
+	signal(SIGQUIT, SIG_IGN);
+}
+
+	void
+VimApp::ArgvReceived(int32 arg_argc, char **arg_argv)
+{
+	if (!IsLaunching()) {
+		/*
+		 * This can happen if we are set to Single or Exclusive
+		 * Launch. Be nice and open the file(s).
+		 */
+		if (gui.vimWindow)
+			gui.vimWindow->Minimize(false);
+		BMessage *m = CurrentMessage();
+		DetachCurrentMessage();
+		SendRefs(m, true);
+	}
+}
+
+	void
+VimApp::RefsReceived(BMessage *m)
+{
+	// Horrible hack!!! XXX XXX XXX
+	// The real problem is that b_start_ffc is set too late for
+	// the initial empty buffer. As a result the window will be
+	// split instead of abandoned.
+	int limit = 15;
+	while (--limit >= 0 && (curbuf == NULL || curbuf->b_start_ffc == 0))
+		snooze(100000);    //  0.1 s
+	if (gui.vimWindow)
+		gui.vimWindow->Minimize(false);
+	DetachCurrentMessage();
+	SendRefs(m, true);
+}
+
+/*
+ * Pass a BMessage on to the main() thread.
+ * Caller must have detached the message.
+ */
+	void
+VimApp::SendRefs(BMessage *m, bool changedir)
+{
+	VimRefsMsg rm;
+	rm.message = m;
+	rm.changedir = changedir;
+
+	write_port(gui.vdcmp, VimMsg::Refs, &rm, sizeof(rm));
+	//  calls ::RefsReceived
+}
+
+	void
+VimApp::MessageReceived(BMessage *m)
+{
+	switch (m->what) {
+		case 'save':
+			{
+				entry_ref refDirectory;
+				m->FindRef("directory", &refDirectory);
+				fBrowsedPath.SetTo(&refDirectory);
+				BString strName;
+				m->FindString("name", &strName);
+				fBrowsedPath.Append(strName.String());
+			}
+			break;
+		case 'open':
+			{
+				entry_ref ref;
+				m->FindRef("refs", &ref);
+				fBrowsedPath.SetTo(&ref);
+			}
+			break;
+		case B_CANCEL:
+			{
+				BFilePanel *panel;
+				m->FindPointer("source", (void**)&panel);
+				if(fFilePanelSem != -1 && panel == fFilePanel)
+				{
+					delete_sem(fFilePanelSem);
+					fFilePanelSem = -1;
+				}
+
+			}
+			break;
+		default:
+			Inherited::MessageReceived(m);
+			break;
+	}
+}
+
+	bool
+VimApp::QuitRequested()
+{
+	(void)Inherited::QuitRequested();
+	return false;
+}
+
+// ---------------- VimWindow ----------------
+
+VimWindow::VimWindow():
+	BWindow(BRect(40, 40, 150, 150),
+			"Vim",
+			B_TITLED_WINDOW,
+			0,
+			B_CURRENT_WORKSPACE)
+
+{
+	init();
+}
+
+VimWindow::~VimWindow()
+{
+	if (formView) {
+		RemoveChild(formView);
+		delete formView;
+	}
+	gui.vimWindow = NULL;
+}
+
+	void
+VimWindow::init()
+{
+	// Attach the VimFormView
+	formView = new VimFormView(Bounds());
+	if (formView != NULL) {
+		AddChild(formView);
+	}
+}
+
+#if 0  //  disabled in zeta patch
+	void
+VimWindow::DispatchMessage(BMessage *m, BHandler *h)
+{
+	/*
+	 * Route B_MOUSE_UP messages to MouseUp(), in
+	 * a manner that should be compatible with the
+	 * intended future system behaviour.
+	 */
+	switch (m->what) {
+		case B_MOUSE_UP:
+			//  if (!h) h = PreferredHandler();
+			//  gcc isn't happy without this extra set of braces, complains about
+			//  jump to case label crosses init of 'class BView * v'
+			//  richard@whitequeen.com jul 99
+			{
+				BView *v = dynamic_cast<BView *>(h);
+				if (v) {
+					// m->PrintToStream();
+					BPoint where;
+					m->FindPoint("where", &where);
+					v->MouseUp(where);
+				} else {
+					Inherited::DispatchMessage(m, h);
+				}
+			}
+			break;
+		default:
+			Inherited::DispatchMessage(m, h);
+	}
+}
+#endif
+
+	void
+VimWindow::WindowActivated(bool active)
+{
+	Inherited::WindowActivated(active);
+	// the textArea gets the keyboard action
+	if (active && gui.vimTextArea)
+		gui.vimTextArea->MakeFocus(true);
+
+	struct VimFocusMsg fm;
+	fm.active = active;
+
+	write_port(gui.vdcmp, VimMsg::Focus, &fm, sizeof(fm));
+}
+
+	bool
+VimWindow::QuitRequested()
+{
+	struct VimKeyMsg km;
+	km.length = 5;
+	memcpy((char *)km.chars, "\033:qa\r", km.length);
+	km.csi_escape = false;
+	write_port(gui.vdcmp, VimMsg::Key, &km, sizeof(km));
+	return false;
+}
+
+// ---------------- VimFormView ----------------
+
+VimFormView::VimFormView(BRect frame):
+	BView(frame, "VimFormView", B_FOLLOW_ALL_SIDES,
+			B_WILL_DRAW | B_FRAME_EVENTS),
+	menuBar(NULL),
+#ifdef FEAT_TOOLBAR
+	toolBar(NULL),
+#endif
+#ifdef FEAT_GUI_TABLINE
+//	showingTabLine(false),
+	tabLine(NULL),
+#endif
+	textArea(NULL)
+{
+	init(frame);
+}
+
+VimFormView::~VimFormView()
+{
+	if (menuBar) {
+		RemoveChild(menuBar);
+#ifdef never
+		//  deleting the menuBar leads to SEGV on exit
+		//  richard@whitequeen.com Jul 99
+		delete menuBar;
+#endif
+	}
+
+#ifdef FEAT_TOOLBAR
+	delete toolBar;
+#endif
+
+#ifdef FEAT_GUI_TABLINE
+	delete tabLine;
+#endif
+
+	if (textArea) {
+		RemoveChild(textArea);
+		delete textArea;
+	}
+	gui.vimForm = NULL;
+}
+
+	void
+VimFormView::init(BRect frame)
+{
+	menuBar = new BMenuBar(BRect(0,0,-MENUBAR_MARGIN,-MENUBAR_MARGIN),
+			"VimMenuBar");
+
+	AddChild(menuBar);
+
+#ifdef FEAT_TOOLBAR
+	toolBar = new VimToolbar(BRect(0,0,0,0), "VimToolBar");
+	toolBar->PrepareButtonBitmaps();
+	AddChild(toolBar);
+#endif
+
+#ifdef FEAT_GUI_TABLINE
+	tabLine = new VimTabLine(BRect(0,0,0,0));
+//	tabLine->PrepareButtonBitmaps();
+	AddChild(tabLine);
+#endif
+
+	BRect remaining = frame;
+	textArea = new VimTextAreaView(remaining);
+	AddChild(textArea);
+	// The textArea will be resized later when menus are added
+
+	gui.vimForm = this;
+}
+
+#ifdef FEAT_TOOLBAR
+	float
+VimFormView::ToolbarHeight() const
+{
+	return toolBar ? toolBar->ToolbarHeight() : 0.;
+}
+#endif
+
+#ifdef FEAT_GUI_TABLINE
+	float
+VimFormView::TablineHeight() const
+{
+	return (tabLine && IsShowingTabLine()) ? tabLine->TablineHeight() : 0.;
+}
+#endif
+
+	void
+VimFormView::AllAttached()
+{
+	/*
+	 * Apparently signals are inherited by the created thread -
+	 * disable the most annoying ones.
+	 */
+	signal(SIGINT, SIG_IGN);
+	signal(SIGQUIT, SIG_IGN);
+
+	if (menuBar && textArea) {
+		/*
+		 * Resize the textArea to fill the space left over by the menu.
+		 * This is somewhat futile since it will be done again once
+		 * menus are added to the menu bar.
+		 */
+		BRect remaining = Bounds();
+
+#ifdef FEAT_MENU
+		remaining.top += MenuHeight();
+		menuBar->ResizeTo(remaining.right, remaining.top);
+		gui.menu_height = (int) MenuHeight();
+#endif
+
+#ifdef FEAT_TOOLBAR
+		toolBar->MoveTo(remaining.left, remaining.top);
+		toolBar->ResizeTo(remaining.right, ToolbarHeight());
+		remaining.top += ToolbarHeight();
+		gui.toolbar_height = ToolbarHeight();
+#endif
+
+#ifdef FEAT_GUI_TABLINE
+		tabLine->MoveTo(remaining.left, remaining.top);
+		tabLine->ResizeTo(remaining.right + 1, TablineHeight());
+		remaining.top += TablineHeight();
+		gui.tabline_height = TablineHeight();
+#endif
+
+		textArea->ResizeTo(remaining.Width(), remaining.Height());
+		textArea->MoveTo(remaining.left, remaining.top);
+	}
+
+
+	Inherited::AllAttached();
+}
+
+	void
+VimFormView::FrameResized(float new_width, float new_height)
+{
+	struct VimResizeMsg sm;
+	int adjust_h, adjust_w;
+
+	new_width += 1;	    //  adjust from width to number of pixels occupied
+	new_height += 1;
+
+	sm.width = (int) new_width;
+	sm.height = (int) new_height;
+	adjust_w = ((int)new_width - gui_get_base_width()) % gui.char_width;
+	adjust_h = ((int)new_height - gui_get_base_height()) % gui.char_height;
+
+	if (adjust_w > 0 || adjust_h > 0) {
+		sm.width  -= adjust_w;
+		sm.height -= adjust_h;
+	}
+
+	write_port(gui.vdcmp, VimMsg::Resize, &sm, sizeof(sm));
+	//  calls gui_resize_shell(new_width, new_height);
+
+	return;
+
+	/*
+	 * The area below the vertical scrollbar is erased to the colour
+	 * set with SetViewColor() automatically, because we had set
+	 * B_WILL_DRAW. Resizing the window tight around the vertical
+	 * scroll bar also helps to avoid debris.
+	 */
+}
+
+// ---------------- VimTextAreaView ----------------
+
+VimTextAreaView::VimTextAreaView(BRect frame):
+	BView(frame, "VimTextAreaView", B_FOLLOW_ALL_SIDES,
+#ifdef FEAT_MBYTE_IME
+		B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_INPUT_METHOD_AWARE),
+#else
+		B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
+#endif
+	mouseDragEventCount(0)
+{
+#ifdef FEAT_MBYTE_IME
+	IMData.messenger = NULL;
+	IMData.message = NULL;
+#endif
+	init(frame);
+}
+
+VimTextAreaView::~VimTextAreaView()
+{
+	gui.vimTextArea = NULL;
+}
+
+	void
+VimTextAreaView::init(BRect frame)
+{
+	// set up global var for fast access
+	gui.vimTextArea = this;
+
+	/*
+	 * Tell the app server not to erase the view: we will
+	 * fill it in completely by ourselves.
+	 * (Does this really work? Even if not, it won't harm either.)
+	 */
+	SetViewColor(B_TRANSPARENT_32_BIT);
+#define PEN_WIDTH   1
+	SetPenSize(PEN_WIDTH);
+#define W_WIDTH(curwin)   0
+}
+
+	void
+VimTextAreaView::Draw(BRect updateRect)
+{
+	/*
+	 * XXX Other ports call here:
+	 * out_flush();	     * make sure all output has been processed *
+	 * but we can't do that, since it involves too much information
+	 * that is owned by other threads...
+	 */
+
+	/*
+	 *  No need to use gui.vimWindow->Lock(): we are locked already.
+	 *  However, it would not hurt.
+	 */
+	rgb_color rgb = GUI_TO_RGB(gui.back_pixel);
+	SetLowColor(rgb);
+	FillRect(updateRect, B_SOLID_LOW);
+	gui_redraw((int) updateRect.left, (int) updateRect.top,
+			(int) (updateRect.Width() + PEN_WIDTH), (int) (updateRect.Height() + PEN_WIDTH));
+
+	// Clear the border areas if needed
+	SetLowColor(rgb);
+
+	if (updateRect.left < FILL_X(0))	//  left border
+		FillRect(BRect(updateRect.left, updateRect.top,
+					FILL_X(0)-PEN_WIDTH, updateRect.bottom), B_SOLID_LOW);
+	if (updateRect.top < FILL_Y(0))	//  top border
+		FillRect(BRect(updateRect.left, updateRect.top,
+					updateRect.right, FILL_Y(0)-PEN_WIDTH), B_SOLID_LOW);
+	if (updateRect.right >= FILL_X(Columns)) //  right border
+		FillRect(BRect(FILL_X((int)Columns), updateRect.top,
+					updateRect.right, updateRect.bottom), B_SOLID_LOW);
+	if (updateRect.bottom >= FILL_Y(Rows))   //  bottom border
+		FillRect(BRect(updateRect.left, FILL_Y((int)Rows),
+					updateRect.right, updateRect.bottom), B_SOLID_LOW);
+
+#ifdef FEAT_MBYTE_IME
+	DrawIMString();
+#endif
+}
+
+	void
+VimTextAreaView::KeyDown(const char *bytes, int32 numBytes)
+{
+	struct VimKeyMsg km;
+	char_u *dest = km.chars;
+
+	bool canHaveVimModifiers = false;
+
+	BMessage *msg = Window()->CurrentMessage();
+	assert(msg);
+	// msg->PrintToStream();
+
+	/*
+	 * Convert special keys to Vim codes.
+	 * I think it is better to do it in the window thread
+	 * so we use at least a little bit of the potential
+	 * of our 2 CPUs. Besides, due to the fantastic mapping
+	 * of special keys to UTF-8, we have quite some work to
+	 * do...
+	 * TODO: I'm not quite happy with detection of special
+	 * keys. Perhaps I should use scan codes after all...
+	 */
+	if (numBytes > 1) {
+		// This cannot be a special key
+		if (numBytes > KEY_MSG_BUFSIZ)
+			numBytes = KEY_MSG_BUFSIZ;	    //  should never happen... ???
+		km.length = numBytes;
+		memcpy((char *)dest, bytes, numBytes);
+		km.csi_escape = true;
+	} else {
+		int32 scancode = 0;
+		msg->FindInt32("key", &scancode);
+
+		int32 beModifiers = 0;
+		msg->FindInt32("modifiers", &beModifiers);
+
+		char_u string[3];
+		int len = 0;
+		km.length = 0;
+
+		/*
+		 * For normal, printable ASCII characters, don't look them up
+		 * to check if they might be a special key. They aren't.
+		 */
+		assert(B_BACKSPACE <= 0x20);
+		assert(B_DELETE == 0x7F);
+		if (((char_u)bytes[0] <= 0x20 || (char_u)bytes[0] == 0x7F) &&
+				numBytes == 1) {
+			/*
+			 * Due to the great nature of Be's mapping of special keys,
+			 * viz. into the range of the control characters,
+			 * we can only be sure it is *really* a special key if
+			 * if it is special without using ctrl. So, only if ctrl is
+			 * used, we need to check it unmodified.
+			 */
+			if (beModifiers & B_CONTROL_KEY) {
+				int index = keyMap->normal_map[scancode];
+				int newNumBytes = keyMapChars[index];
+				char_u *newBytes = (char_u *)&keyMapChars[index + 1];
+
+				/*
+				 * Check if still special without the control key.
+				 * This is needed for BACKSPACE: that key does produce
+				 * different values with modifiers (DEL).
+				 * Otherwise we could simply have checked for equality.
+				 */
+				if (newNumBytes != 1 || (*newBytes > 0x20 &&
+							*newBytes != 0x7F )) {
+					goto notspecial;
+				}
+				bytes = (char *)newBytes;
+			}
+			canHaveVimModifiers = true;
+
+			uint16 beoskey;
+			int first, last;
+
+			/*
+			 * If numBytes == 0 that probably always indicates a special key.
+			 * (does not happen yet)
+			 */
+			if (numBytes == 0 || bytes[0] == B_FUNCTION_KEY) {
+				beoskey = F(scancode);
+				first = FIRST_FUNCTION_KEY;
+				last = NUM_SPECIAL_KEYS;
+			} else if (*bytes == '\n' && scancode == 0x47) {
+				// remap the (non-keypad) ENTER key from \n to \r.
+				string[0] = '\r';
+				len = 1;
+				first = last = 0;
+			} else {
+				beoskey = K(bytes[0]);
+				first = 0;
+				last = FIRST_FUNCTION_KEY;
+			}
+
+			for (int i = first; i < last; i++) {
+				if (special_keys[i].BeKeys == beoskey) {
+					string[0] = CSI;
+					string[1] = special_keys[i].vim_code0;
+					string[2] = special_keys[i].vim_code1;
+					len = 3;
+				}
+			}
+		}
+notspecial:
+		if (len == 0) {
+			string[0] = bytes[0];
+			len = 1;
+		}
+
+		// Special keys (and a few others) may have modifiers
+#if 0
+		if (len == 3 ||
+				bytes[0] == B_SPACE || bytes[0] == B_TAB ||
+				bytes[0] == B_RETURN || bytes[0] == '\r' ||
+				bytes[0] == B_ESCAPE)
+#else
+			if (canHaveVimModifiers)
+#endif
+			{
+				int modifiers;
+				modifiers = 0;
+				if (beModifiers & B_SHIFT_KEY)
+					modifiers |= MOD_MASK_SHIFT;
+				if (beModifiers & B_CONTROL_KEY)
+					modifiers |= MOD_MASK_CTRL;
+				if (beModifiers & B_OPTION_KEY)
+					modifiers |= MOD_MASK_ALT;
+
+				/*
+				 * For some keys a shift modifier is translated into another key
+				 * code.  Do we need to handle the case where len != 1 and
+				 * string[0] != CSI? (Not for BeOS, since len == 3 implies
+				 * string[0] == CSI...)
+				 */
+				int key;
+				if (string[0] == CSI && len == 3)
+					key = TO_SPECIAL(string[1], string[2]);
+				else
+					key = string[0];
+				key = simplify_key(key, &modifiers);
+				if (IS_SPECIAL(key))
+				{
+					string[0] = CSI;
+					string[1] = K_SECOND(key);
+					string[2] = K_THIRD(key);
+					len = 3;
+				}
+				else
+				{
+					string[0] = key;
+					len = 1;
+				}
+
+				if (modifiers)
+				{
+					*dest++ = CSI;
+					*dest++ = KS_MODIFIER;
+					*dest++ = modifiers;
+					km.length = 3;
+				}
+			}
+		memcpy((char *)dest, string, len);
+		km.length += len;
+		km.csi_escape = false;
+	}
+
+	write_port(gui.vdcmp, VimMsg::Key, &km, sizeof(km));
+
+	/*
+	 * blank out the pointer if necessary
+	 */
+	if (p_mh && !gui.pointer_hidden)
+	{
+		guiBlankMouse(true);
+		gui.pointer_hidden = TRUE;
+	}
+}
+void
+VimTextAreaView::guiSendMouseEvent(
+		int	    button,
+		int	    x,
+		int	    y,
+		int	    repeated_click,
+		int_u   modifiers)
+{
+	VimMouseMsg mm;
+
+	mm.button = button;
+	mm.x = x;
+	mm.y = y;
+	mm.repeated_click = repeated_click;
+	mm.modifiers = modifiers;
+
+	write_port(gui.vdcmp, VimMsg::Mouse, &mm, sizeof(mm));
+	//  calls gui_send_mouse_event()
+
+	/*
+	 * if our pointer is currently hidden, then we should show it.
+	 */
+	if (gui.pointer_hidden)
+	{
+		guiBlankMouse(false);
+		gui.pointer_hidden = FALSE;
+	}
+}
+
+void
+VimTextAreaView::guiMouseMoved(
+		int	    x,
+		int	    y)
+{
+	VimMouseMovedMsg mm;
+
+	mm.x = x;
+	mm.y = y;
+
+	write_port(gui.vdcmp, VimMsg::MouseMoved, &mm, sizeof(mm));
+
+	if (gui.pointer_hidden)
+	{
+		guiBlankMouse(false);
+		gui.pointer_hidden = FALSE;
+	}
+}
+
+	void
+VimTextAreaView::guiBlankMouse(bool should_hide)
+{
+	if (should_hide) {
+		// gui.vimApp->HideCursor();
+		gui.vimApp->ObscureCursor();
+		/*
+		 * ObscureCursor() would even be easier, but then
+		 * Vim's idea of mouse visibility does not necessarily
+		 * correspond to reality.
+		 */
+	} else {
+		// gui.vimApp->ShowCursor();
+	}
+}
+
+	int_u
+VimTextAreaView::mouseModifiersToVim(int32 beModifiers)
+{
+	int_u vim_modifiers = 0x0;
+
+	if (beModifiers & B_SHIFT_KEY)
+		vim_modifiers |= MOUSE_SHIFT;
+	if (beModifiers & B_CONTROL_KEY)
+		vim_modifiers |= MOUSE_CTRL;
+	if (beModifiers & B_OPTION_KEY)	    // Alt or Meta key
+		vim_modifiers |= MOUSE_ALT;
+
+	return vim_modifiers;
+}
+
+	void
+VimTextAreaView::MouseDown(BPoint point)
+{
+	BMessage *m = Window()->CurrentMessage();
+	assert(m);
+
+	int32 buttons = 0;
+	m->FindInt32("buttons", &buttons);
+
+	int vimButton;
+
+	if (buttons & B_PRIMARY_MOUSE_BUTTON)
+		vimButton = MOUSE_LEFT;
+	else if (buttons & B_SECONDARY_MOUSE_BUTTON)
+		vimButton = MOUSE_RIGHT;
+	else if (buttons & B_TERTIARY_MOUSE_BUTTON)
+		vimButton = MOUSE_MIDDLE;
+	else
+		return;			// Unknown button
+
+	vimMouseButton = 1;		// don't care which one
+
+	// Handle multiple clicks
+	int32 clicks = 0;
+	m->FindInt32("clicks", &clicks);
+
+	int32 modifiers = 0;
+	m->FindInt32("modifiers", &modifiers);
+
+	vimMouseModifiers = mouseModifiersToVim(modifiers);
+
+	guiSendMouseEvent(vimButton, point.x, point.y,
+			clicks > 1 /* = repeated_click*/, vimMouseModifiers);
+}
+
+	void
+VimTextAreaView::MouseUp(BPoint point)
+{
+	vimMouseButton = 0;
+
+	BMessage *m = Window()->CurrentMessage();
+	assert(m);
+	// m->PrintToStream();
+
+	int32 modifiers = 0;
+	m->FindInt32("modifiers", &modifiers);
+
+	vimMouseModifiers = mouseModifiersToVim(modifiers);
+
+	guiSendMouseEvent(MOUSE_RELEASE, point.x, point.y,
+			0 /* = repeated_click*/, vimMouseModifiers);
+
+	Inherited::MouseUp(point);
+}
+
+	void
+VimTextAreaView::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
+{
+	/*
+	 * if our pointer is currently hidden, then we should show it.
+	 */
+	if (gui.pointer_hidden)
+	{
+		guiBlankMouse(false);
+		gui.pointer_hidden = FALSE;
+	}
+
+	if (!vimMouseButton) {    // could also check m->"buttons"
+		guiMouseMoved(point.x, point.y);
+		return;
+	}
+
+	atomic_add(&mouseDragEventCount, 1);
+
+	// Don't care much about "transit"
+	guiSendMouseEvent(MOUSE_DRAG, point.x, point.y, 0, vimMouseModifiers);
+}
+
+	void
+VimTextAreaView::MessageReceived(BMessage *m)
+{
+	switch (m->what) {
+		case 'menu':
+			{
+				VimMenuMsg mm;
+				mm.guiMenu = NULL;	// in case no pointer in msg
+				m->FindPointer("VimMenu", (void **)&mm.guiMenu);
+				write_port(gui.vdcmp, VimMsg::Menu, &mm, sizeof(mm));
+			}
+			break;
+		case B_MOUSE_WHEEL_CHANGED:
+			{
+				VimScrollBar* scb = curwin->w_scrollbars[1].id;
+				float small=0, big=0, dy=0;
+				m->FindFloat("be:wheel_delta_y", &dy);
+				scb->GetSteps(&small, &big);
+				scb->SetValue(scb->Value()+small*dy*3);
+				scb->ValueChanged(scb->Value());
+#if 0
+				scb = curwin->w_scrollbars[0].id;
+				scb->GetSteps(&small, &big);
+				scb->SetValue(scb->Value()+small*dy);
+				scb->ValueChanged(scb->Value());
+#endif
+			}
+			break;
+#ifdef FEAT_MBYTE_IME
+		case B_INPUT_METHOD_EVENT:
+			{
+				int32 opcode;
+				m->FindInt32("be:opcode", &opcode);
+				switch(opcode)
+				{
+					case B_INPUT_METHOD_STARTED:
+						if(!IMData.messenger) delete IMData.messenger;
+						IMData.messenger = new BMessenger();
+						m->FindMessenger("be:reply_to", IMData.messenger);
+						break;
+					case B_INPUT_METHOD_CHANGED:
+						{
+							BString str;
+							bool confirmed;
+							if(IMData.message) *(IMData.message) = *m;
+							else               IMData.message = new BMessage(*m);
+							DrawIMString();
+							m->FindBool("be:confirmed", &confirmed);
+							if (confirmed)
+							{
+								m->FindString("be:string", &str);
+								char_u *chars = (char_u*)str.String();
+								struct VimKeyMsg km;
+								km.csi_escape = true;
+								int clen;
+								int i = 0;
+								while (i < str.Length())
+								{
+									clen = utf_ptr2len(chars+i);
+									memcpy(km.chars, chars+i, clen);
+									km.length = clen;
+									write_port(gui.vdcmp, VimMsg::Key, &km, sizeof(km));
+									i += clen;
+								}
+							}
+						}
+						break;
+					case B_INPUT_METHOD_LOCATION_REQUEST:
+						{
+							BMessage msg(B_INPUT_METHOD_EVENT);
+							msg.AddInt32("be:opcode", B_INPUT_METHOD_LOCATION_REQUEST);
+							msg.AddPoint("be:location_reply", IMData.location);
+							msg.AddFloat("be:height_reply", FILL_Y(1));
+							IMData.messenger->SendMessage(&msg);
+						}
+						break;
+					case B_INPUT_METHOD_STOPPED:
+						delete IMData.messenger;
+						delete IMData.message;
+						IMData.messenger = NULL;
+						IMData.message = NULL;
+						break;
+				}
+			}
+			// TODO: sz: break here???
+#endif
+		default:
+			if (m->WasDropped()) {
+				BWindow *w = Window();
+				w->DetachCurrentMessage();
+				w->Minimize(false);
+				VimApp::SendRefs(m, (modifiers() & B_SHIFT_KEY) != 0);
+			} else {
+				Inherited::MessageReceived(m);
+			}
+			break;
+	}
+}
+
+	int
+VimTextAreaView::mchInitFont(char_u *name)
+{
+	VimFont *newFont = (VimFont *)gui_mch_get_font(name, 1);
+	if(newFont != NOFONT) {
+		gui.norm_font = (GuiFont)newFont;
+		gui_mch_set_font((GuiFont)newFont);
+		if (name && STRCMP(name, "*") != 0)
+			hl_set_font_name(name);
+
+		SetDrawingMode(B_OP_COPY);
+
+		/*
+		 * Try to load other fonts for bold, italic, and bold-italic.
+		 * We should also try to work out what font to use for these when they are
+		 * not specified by X resources, but we don't yet.
+		 */
+		return OK;
+	}
+	return FAIL;
+}
+
+	void
+VimTextAreaView::mchDrawString(int row, int col, char_u *s, int len, int flags)
+{
+	/*
+	 * First we must erase the area, because DrawString won't do
+	 * that for us. XXX Most of the time this is a waste of effort
+	 * since the bachground has been erased already... DRAW_TRANSP
+	 * should be set when appropriate!!!
+	 * (Rectangles include the bottom and right edge)
+	 */
+	if (!(flags & DRAW_TRANSP)) {
+		int cells;
+		cells = 0;
+		for(int i=0; i<len; i++) {
+			int cn = utf_ptr2cells((char_u *)(s+i));
+			if(cn<4) cells += cn;
+		}
+
+		BRect r(FILL_X(col), FILL_Y(row),
+				FILL_X(col + cells) - PEN_WIDTH, FILL_Y(row + 1) - PEN_WIDTH);
+		FillRect(r, B_SOLID_LOW);
+	}
+
+	BFont font;
+	this->GetFont(&font);
+	if(!font.IsFixed())
+	{
+		char* p = (char*)s;
+		int32 clen, lastpos = 0;
+		BPoint where;
+		int cells;
+		while((p - (char*)s) < len) {
+			clen = utf_ptr2len((u_char*)p);
+			where.Set(TEXT_X(col+lastpos), TEXT_Y(row));
+			DrawString(p, clen, where);
+			if (flags & DRAW_BOLD) {
+				where.x += 1.0;
+				SetDrawingMode(B_OP_BLEND);
+				DrawString(p, clen, where);
+				SetDrawingMode(B_OP_COPY);
+			}
+			cells = utf_ptr2cells((char_u *)p);
+			if(cells<4) lastpos += cells;
+			else        lastpos++;
+			p += clen;
+		}
+	}
+	else
+	{
+		BPoint where(TEXT_X(col), TEXT_Y(row));
+		DrawString((char*)s, len, where);
+		if (flags & DRAW_BOLD) {
+			where.x += 1.0;
+			SetDrawingMode(B_OP_BLEND);
+			DrawString((char*)s, len, where);
+			SetDrawingMode(B_OP_COPY);
+		}
+	}
+
+	if (flags & DRAW_UNDERL) {
+		int cells;
+		cells = 0;
+		for(int i=0; i<len; i++) {
+			int cn = utf_ptr2cells((char_u *)(s+i));
+			if(cn<4) cells += cn;
+		}
+
+		BPoint start(FILL_X(col), FILL_Y(row + 1) - PEN_WIDTH);
+		BPoint end(FILL_X(col + cells) - PEN_WIDTH, start.y);
+
+		StrokeLine(start, end);
+	}
+}
+
+void
+VimTextAreaView::mchClearBlock(
+		int		row1,
+		int		col1,
+		int		row2,
+		int		col2)
+{
+	BRect r(FILL_X(col1), FILL_Y(row1),
+			FILL_X(col2 + 1) - PEN_WIDTH, FILL_Y(row2 + 1) - PEN_WIDTH);
+	gui_mch_set_bg_color(gui.back_pixel);
+	FillRect(r, B_SOLID_LOW);
+}
+
+	void
+VimTextAreaView::mchClearAll()
+{
+	gui_mch_set_bg_color(gui.back_pixel);
+	FillRect(Bounds(), B_SOLID_LOW);
+}
+
+/*
+ * mchDeleteLines() Lock()s the window by itself.
+ */
+	void
+VimTextAreaView::mchDeleteLines(int row, int num_lines)
+{
+	BRect source, dest;
+	source.left = FILL_X(gui.scroll_region_left);
+	source.top = FILL_Y(row + num_lines);
+	source.right = FILL_X(gui.scroll_region_right + 1) - PEN_WIDTH;
+	source.bottom = FILL_Y(gui.scroll_region_bot + 1) - PEN_WIDTH;
+
+	dest.left = FILL_X(gui.scroll_region_left);
+	dest.top = FILL_Y(row);
+	dest.right = FILL_X(gui.scroll_region_right + 1) - PEN_WIDTH;
+	dest.bottom = FILL_Y(gui.scroll_region_bot - num_lines + 1) - PEN_WIDTH;
+
+	if (gui.vimWindow->Lock()) {
+		// Clear one column more for when bold has spilled over
+		CopyBits(source, dest);
+		gui_clear_block(gui.scroll_region_bot - num_lines + 1,
+				gui.scroll_region_left,
+				gui.scroll_region_bot, gui.scroll_region_right);
+
+
+		gui.vimWindow->Unlock();
+		/*
+		 * The Draw() callback will be called now if some of the source
+		 * bits were not in the visible region.
+		 */
+	}
+	// gui_x11_check_copy_area();
+	//  }
+}
+
+/*
+ * mchInsertLines() Lock()s the window by itself.
+ */
+	void
+VimTextAreaView::mchInsertLines(int row, int num_lines)
+{
+	BRect source, dest;
+
+	// XXX Attempt at a hack:
+	gui.vimWindow->UpdateIfNeeded();
+	source.left = FILL_X(gui.scroll_region_left);
+	source.top = FILL_Y(row);
+	source.right = FILL_X(gui.scroll_region_right + 1) - PEN_WIDTH;
+	source.bottom = FILL_Y(gui.scroll_region_bot - num_lines + 1) - PEN_WIDTH;
+
+	dest.left = FILL_X(gui.scroll_region_left);
+	dest.top = FILL_Y(row + num_lines);
+	dest.right = FILL_X(gui.scroll_region_right + 1) - PEN_WIDTH;
+	dest.bottom = FILL_Y(gui.scroll_region_bot + 1) - PEN_WIDTH;
+
+	if (gui.vimWindow->Lock()) {
+		// Clear one column more for when bold has spilled over
+		CopyBits(source, dest);
+		gui_clear_block(row, gui.scroll_region_left,
+				row + num_lines - 1, gui.scroll_region_right);
+
+		gui.vimWindow->Unlock();
+		/*
+		 * The Draw() callback will be called now if some of the source
+		 * bits were not in the visible region.
+		 * However, if we scroll too fast it can't keep up and the
+		 * update region gets messed up. This seems to be because copying
+		 * un-Draw()n bits does not generate Draw() calls for the copy...
+		 * I moved the hack to before the CopyBits() to reduce the
+		 * amount of additional waiting needed.
+		 */
+
+		// gui_x11_check_copy_area();
+
+	}
+}
+
+#ifdef FEAT_MBYTE_IME
+/*
+ * DrawIMString draws string with IMData.message.
+ */
+void VimTextAreaView::DrawIMString(void)
+{
+	static const rgb_color r_highlight = {255, 152, 152, 255},
+				 b_highlight = {152, 203, 255, 255};
+	BString str;
+	const char* s;
+	int len;
+	BMessage* msg = IMData.message;
+	if (!msg)
+		return;
+	gui_redraw_block(IMData.row, 0,
+			IMData.row + IMData.count, W_WIDTH(curwin), GUI_MON_NOCLEAR);
+	bool confirmed = false;
+	msg->FindBool("be:confirmed", &confirmed);
+	if (confirmed)
+		return;
+	rgb_color hcolor = HighColor(), lcolor = LowColor();
+	msg->FindString("be:string", &str);
+	s = str.String();
+	len = str.Length();
+	SetHighColor(0, 0, 0);
+	IMData.row = gui.row;
+	IMData.col = gui.col;
+	int32 sel_start = 0, sel_end = 0;
+	msg->FindInt32("be:selection", 0, &sel_start);
+	msg->FindInt32("be:selection", 1, &sel_end);
+	int clen, cn;
+	BPoint pos(IMData.col, 0);
+	BRect r;
+	BPoint where;
+	IMData.location = ConvertToScreen(
+			BPoint(FILL_X(pos.x), FILL_Y(IMData.row + pos.y)));
+	for (int i=0; i<len; i+=clen)
+	{
+		cn = utf_ptr2cells((char_u *)(s+i));
+		clen = utf_ptr2len((char_u *)(s+i));
+		if (pos.x + cn > W_WIDTH(curwin))
+		{
+			pos.y++;
+			pos.x = 0;
+		}
+		if (sel_start<=i && i<sel_end)
+		{
+			SetLowColor(r_highlight);
+			IMData.location = ConvertToScreen(
+					BPoint(FILL_X(pos.x), FILL_Y(IMData.row + pos.y)));
+		}
+		else
+		{
+			SetLowColor(b_highlight);
+		}
+		r.Set(FILL_X(pos.x), FILL_Y(IMData.row + pos.y),
+				FILL_X(pos.x + cn) - PEN_WIDTH,
+				FILL_Y(IMData.row + pos.y + 1) - PEN_WIDTH);
+		FillRect(r, B_SOLID_LOW);
+		where.Set(TEXT_X(pos.x), TEXT_Y(IMData.row + pos.y));
+		DrawString((s+i), clen, where);
+		pos.x += cn;
+	}
+	IMData.count = (int)pos.y;
+
+	SetHighColor(hcolor);
+	SetLowColor(lcolor);
+}
+#endif
+// ---------------- VimScrollBar ----------------
+
+/*
+ * BUG: XXX
+ * It seems that BScrollBar determine their direction not from
+ * "posture" but from if they are "tall" or "wide" in shape...
+ *
+ * Also, place them out of sight, because Vim enables them before
+ * they are positioned.
+ */
+VimScrollBar::VimScrollBar(scrollbar_T *g, orientation posture):
+	BScrollBar(posture == B_HORIZONTAL ?  BRect(-100,-100,-10,-90) :
+			BRect(-100,-100,-90,-10),
+			"vim scrollbar", (BView *)NULL,
+			0.0, 10.0, posture),
+	ignoreValue(-1),
+	scrollEventCount(0)
+{
+	gsb = g;
+	SetResizingMode(B_FOLLOW_NONE);
+}
+
+VimScrollBar::~VimScrollBar()
+{
+}
+
+	void
+VimScrollBar::ValueChanged(float newValue)
+{
+	if (ignoreValue >= 0.0 && newValue == ignoreValue) {
+		ignoreValue = -1;
+		return;
+	}
+	ignoreValue = -1;
+	/*
+	 * We want to throttle the amount of scroll messages generated.
+	 * Normally I presume you won't get a new message before we've
+	 * handled the previous one, but because we're passing them on this
+	 * happens very quickly. So instead we keep a counter of how many
+	 * scroll events there are (or will be) in the VDCMP, and the
+	 * throttling happens at the receiving end.
+	 */
+	atomic_add(&scrollEventCount, 1);
+
+	struct VimScrollBarMsg sm;
+
+	sm.sb = this;
+	sm.value = (long) newValue;
+	sm.stillDragging = TRUE;
+
+	write_port(gui.vdcmp, VimMsg::ScrollBar, &sm, sizeof(sm));
+
+	//  calls gui_drag_scrollbar(sb, newValue, TRUE);
+}
+
+/*
+ * When the mouse goes up, report that scrolling has stopped.
+ * MouseUp() is NOT called when the mouse-up occurs outside
+ * the window, even though the thumb does move while the mouse
+ * is outside... This has some funny effects... XXX
+ * So we do special processing when the window de/activates.
+ */
+	void
+VimScrollBar::MouseUp(BPoint where)
+{
+	// BMessage *m = Window()->CurrentMessage();
+	// m->PrintToStream();
+
+	atomic_add(&scrollEventCount, 1);
+
+	struct VimScrollBarMsg sm;
+
+	sm.sb = this;
+	sm.value = (long) Value();
+	sm.stillDragging = FALSE;
+
+	write_port(gui.vdcmp, VimMsg::ScrollBar, &sm, sizeof(sm));
+
+	//  calls gui_drag_scrollbar(sb, newValue, FALSE);
+
+	Inherited::MouseUp(where);
+}
+
+	void
+VimScrollBar::SetValue(float newValue)
+{
+	if (newValue == Value())
+		return;
+
+	ignoreValue = newValue;
+	Inherited::SetValue(newValue);
+}
+
+// ---------------- VimFont ----------------
+
+VimFont::VimFont(): BFont()
+{
+	init();
+}
+
+VimFont::VimFont(const VimFont *rhs): BFont(rhs)
+{
+	init();
+}
+
+VimFont::VimFont(const BFont *rhs): BFont(rhs)
+{
+	init();
+}
+
+VimFont::VimFont(const VimFont &rhs): BFont(rhs)
+{
+	init();
+}
+
+VimFont::~VimFont()
+{
+}
+
+	void
+VimFont::init()
+{
+	next = NULL;
+	refcount = 1;
+	name = NULL;
+}
+
+// ---------------- VimDialog ----------------
+
+#if defined(FEAT_GUI_DIALOG)
+
+const unsigned int	kVimDialogButtonMsg = 'VMDB';
+const unsigned int	kVimDialogIconStripeWidth = 30;
+const unsigned int	kVimDialogButtonsSpacingX = 9;
+const unsigned int	kVimDialogButtonsSpacingY = 4;
+const unsigned int	kVimDialogSpacingX = 6;
+const unsigned int	kVimDialogSpacingY = 10;
+const unsigned int	kVimDialogMinimalWidth  = 310;
+const unsigned int	kVimDialogMinimalHeight = 75;
+const BRect			kDefaultRect =
+BRect(0, 0, kVimDialogMinimalWidth, kVimDialogMinimalHeight);
+
+VimDialog::VimDialog(int type, const char *title, const char *message,
+		const char *buttons, int dfltbutton, const char *textfield, int ex_cmd)
+: BWindow(kDefaultRect, title, B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
+		B_NOT_CLOSABLE | B_NOT_RESIZABLE |
+		B_NOT_ZOOMABLE | B_NOT_MINIMIZABLE | B_ASYNCHRONOUS_CONTROLS)
+	, fDialogSem(-1)
+	, fDialogValue(dfltbutton)
+	, fMessageView(NULL)
+	, fInputControl(NULL)
+	, fInputValue(textfield)
+{
+	//  master view
+	VimDialog::View* view = new VimDialog::View(Bounds());
+	if(view == NULL)
+		return;
+
+	if(title == NULL)
+		SetTitle("Vim " VIM_VERSION_MEDIUM);
+
+	AddChild(view);
+
+	//  icon
+	view->InitIcon(type);
+
+	//  buttons
+	int32 which = 1;
+	float maxButtonWidth  = 0;
+	float maxButtonHeight = 0;
+	float buttonsWidth    = 0;
+	float buttonsHeight   = 0;
+	BString strButtons(buttons);
+	strButtons.RemoveAll("&");
+	do {
+		int32 end = strButtons.FindFirst('\n');
+		if(end != B_ERROR)
+			strButtons.SetByteAt(end, '\0');
+
+		BButton *button = _CreateButton(which++, strButtons.String());
+		view->AddChild(button);
+		fButtonsList.AddItem(button);
+
+		maxButtonWidth  = max_c(maxButtonWidth,  button->Bounds().Width());
+		maxButtonHeight = max_c(maxButtonHeight, button->Bounds().Height());
+		buttonsWidth   += button->Bounds().Width();
+		buttonsHeight  += button->Bounds().Height();
+
+		if(end == B_ERROR)
+			break;
+
+		strButtons.Remove(0, end + 1);
+	} while(true);
+
+	int32 buttonsCount = fButtonsList.CountItems();
+	buttonsWidth      += kVimDialogButtonsSpacingX * (buttonsCount - 1);
+	buttonsHeight     += kVimDialogButtonsSpacingY * (buttonsCount - 1);
+	float dialogWidth  = buttonsWidth + kVimDialogIconStripeWidth +
+		kVimDialogSpacingX * 2;
+	float dialogHeight = maxButtonHeight + kVimDialogSpacingY * 3;
+
+	// Check 'v' flag in 'guioptions': vertical button placement.
+	bool vertical = (vim_strchr(p_go, GO_VERTICAL) != NULL) ||
+		dialogWidth >= gui.vimWindow->Bounds().Width();
+	if(vertical) {
+		dialogWidth  -= buttonsWidth;
+		dialogWidth  += maxButtonWidth;
+		dialogHeight -= maxButtonHeight;
+		dialogHeight += buttonsHeight;
+	}
+
+	dialogWidth  = max_c(dialogWidth,  kVimDialogMinimalWidth);
+
+	//  message view
+	BRect rect(0, 0, dialogWidth, 0);
+	rect.left  += kVimDialogIconStripeWidth + 16 + kVimDialogSpacingX;
+	rect.top   += kVimDialogSpacingY;
+	rect.right -= kVimDialogSpacingX;
+	rect.bottom = rect.top;
+	fMessageView = new BTextView(rect, "_tv_", rect.OffsetByCopy(B_ORIGIN),
+			B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW);
+
+	fMessageView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
+	rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR);
+	fMessageView->SetFontAndColor(be_plain_font, B_FONT_ALL, &textColor);
+	fMessageView->SetText(message);
+	fMessageView->MakeEditable(false);
+	fMessageView->MakeSelectable(false);
+	fMessageView->SetWordWrap(true);
+	AddChild(fMessageView);
+
+	float messageHeight = fMessageView->TextHeight(0, fMessageView->CountLines());
+	fMessageView->ResizeBy(0, messageHeight);
+	fMessageView->SetTextRect(BRect(0, 0, rect.Width(), messageHeight));
+
+	dialogHeight += messageHeight;
+
+	//  input view
+	if(fInputValue != NULL) {
+		rect.top     =
+			rect.bottom += messageHeight + kVimDialogSpacingY;
+		fInputControl = new BTextControl(rect, "_iv_", NULL, fInputValue, NULL,
+				B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE |  B_PULSE_NEEDED);
+		fInputControl->TextView()->SetText(fInputValue);
+		fInputControl->TextView()->SetWordWrap(false);
+		AddChild(fInputControl);
+
+		float width = 0.f, height = 0.f;
+		fInputControl->GetPreferredSize(&width, &height);
+		fInputControl->MakeFocus(true);
+
+		dialogHeight += height + kVimDialogSpacingY * 1.5;
+	}
+
+	dialogHeight = max_c(dialogHeight, kVimDialogMinimalHeight);
+
+	ResizeTo(dialogWidth, dialogHeight);
+	MoveTo((gui.vimWindow->Bounds().Width() - dialogWidth) / 2,
+			(gui.vimWindow->Bounds().Height() - dialogHeight) / 2);
+
+	//  adjust layout of buttons
+	float buttonWidth = max_c(maxButtonWidth, rect.Width() * 0.66);
+	BPoint origin(dialogWidth, dialogHeight);
+	origin.x -= kVimDialogSpacingX + (vertical ? buttonWidth : buttonsWidth);
+	origin.y -= kVimDialogSpacingY + (vertical ? buttonsHeight  : maxButtonHeight);
+
+	for(int32 i = 0 ; i < buttonsCount; i++) {
+		BButton *button = (BButton*)fButtonsList.ItemAt(i);
+		button->MoveTo(origin);
+		if(vertical) {
+			origin.y += button->Frame().Height() + kVimDialogButtonsSpacingY;
+			button->ResizeTo(buttonWidth, button->Frame().Height());
+		} else
+			origin.x += button->Frame().Width() + kVimDialogButtonsSpacingX;
+
+		if(dfltbutton == i + 1) {
+			button->MakeDefault(true);
+			button->MakeFocus(fInputControl == NULL);
+		}
+	}
+}
+
+VimDialog::~VimDialog()
+{
+	if(fDialogSem > B_OK)
+		delete_sem(fDialogSem);
+}
+
+	int
+VimDialog::Go()
+{
+	fDialogSem = create_sem(0, "VimDialogSem");
+	if(fDialogSem < B_OK) {
+		Quit();
+		return fDialogValue;
+	}
+
+	Show();
+
+	while(acquire_sem(fDialogSem) == B_INTERRUPTED);
+
+	int retValue = fDialogValue;
+	if(fInputValue != NULL)
+		vim_strncpy((char_u*)fInputValue, (char_u*)fInputControl->Text(), IOSIZE - 1);
+
+	if(Lock())
+		Quit();
+
+	return retValue;
+}
+
+void VimDialog::MessageReceived(BMessage *msg)
+{
+	int32 which = 0;
+	if(msg->what != kVimDialogButtonMsg ||
+			msg->FindInt32("which", &which) != B_OK)
+		return BWindow::MessageReceived(msg);
+
+	fDialogValue = which;
+	delete_sem(fDialogSem);
+	fDialogSem = -1;
+}
+
+BButton* VimDialog::_CreateButton(int32 which, const char* label)
+{
+	BMessage *message = new BMessage(kVimDialogButtonMsg);
+	message->AddInt32("which", which);
+
+	BRect rect(0, 0, 0, 0);
+	BString name;
+	name << "_b" << which << "_";
+
+	BButton* button = new BButton(rect, name.String(), label, message,
+			B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
+
+	float width = 0.f, height = 0.f;
+	button->GetPreferredSize(&width, &height);
+	button->ResizeTo(width, height);
+
+	return button;
+}
+
+VimDialog::View::View(BRect frame)
+	:	BView(frame, "VimDialogView", B_FOLLOW_ALL_SIDES, B_WILL_DRAW),
+	fIconBitmap(NULL)
+{
+	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
+}
+
+VimDialog::View::~View()
+{
+	delete fIconBitmap;
+}
+
+void VimDialog::View::Draw(BRect updateRect)
+{
+	BRect stripeRect = Bounds();
+	stripeRect.right = kVimDialogIconStripeWidth;
+	SetHighColor(tint_color(ViewColor(), B_DARKEN_1_TINT));
+	FillRect(stripeRect);
+
+	if(fIconBitmap == NULL)
+		return;
+
+	SetDrawingMode(B_OP_ALPHA);
+	SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
+	DrawBitmapAsync(fIconBitmap, BPoint(18, 6));
+}
+
+void VimDialog::View::InitIcon(int32 type)
+{
+	if(type == VIM_GENERIC)
+		return;
+
+	BPath path;
+	status_t status = find_directory(B_BEOS_SERVERS_DIRECTORY, &path);
+	if(status != B_OK) {
+		fprintf(stderr, "Cannot retrieve app info:%s\n", strerror(status));
+		return;
+	}
+
+	path.Append("app_server");
+
+	BFile file(path.Path(), O_RDONLY);
+	if(file.InitCheck() != B_OK) {
+		fprintf(stderr, "App file assignment failed:%s\n",
+				strerror(file.InitCheck()));
+		return;
+	}
+
+	BResources resources(&file);
+	if(resources.InitCheck() != B_OK) {
+		fprintf(stderr, "App server resources assignment failed:%s\n",
+				strerror(resources.InitCheck()));
+		return;
+	}
+
+	const char *name = "";
+	switch(type) {
+		case VIM_ERROR:		name = "stop"; break;
+		case VIM_WARNING:	name = "warn"; break;
+		case VIM_INFO:		name = "info"; break;
+		case VIM_QUESTION:	name = "idea"; break;
+		default: return;
+	}
+
+	int32 iconSize = 32;
+	fIconBitmap = new BBitmap(BRect(0, 0, iconSize - 1, iconSize - 1), 0, B_RGBA32);
+	if(fIconBitmap == NULL || fIconBitmap->InitCheck() != B_OK) {
+		fprintf(stderr, "Icon bitmap allocation failed:%s\n",
+				(fIconBitmap == NULL) ? "null" : strerror(fIconBitmap->InitCheck()));
+		return;
+	}
+
+	size_t size = 0;
+	const uint8* iconData = NULL;
+	//  try vector icon first?
+	iconData = (const uint8*)resources.LoadResource(B_VECTOR_ICON_TYPE, name, &size);
+	if(iconData != NULL && BIconUtils::GetVectorIcon(iconData, size, fIconBitmap) == B_OK)
+		return;
+
+	//  try bitmap icon now
+	iconData = (const uint8*)resources.LoadResource(B_LARGE_ICON_TYPE, name, &size);
+	if(iconData == NULL) {
+		fprintf(stderr, "Bitmap icon resource not found\n");
+		delete fIconBitmap;
+		fIconBitmap = NULL;
+		return;
+	}
+
+	if(fIconBitmap->ColorSpace() != B_CMAP8)
+		BIconUtils::ConvertFromCMAP8(iconData, iconSize, iconSize, iconSize, fIconBitmap);
+}
+
+const unsigned int	kVimDialogOKButtonMsg = 'FDOK';
+const unsigned int	kVimDialogCancelButtonMsg = 'FDCN';
+const unsigned int	kVimDialogSizeInputMsg = 'SICH';
+const unsigned int	kVimDialogFamilySelectMsg = 'MSFM';
+const unsigned int	kVimDialogStyleSelectMsg = 'MSST';
+const unsigned int	kVimDialogSizeSelectMsg = 'MSSZ';
+
+VimSelectFontDialog::VimSelectFontDialog(font_family* family, font_style* style, float* size)
+: BWindow(kDefaultRect, "Font Selection", B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
+		B_NOT_CLOSABLE | B_NOT_RESIZABLE |
+		B_NOT_ZOOMABLE | B_NOT_MINIMIZABLE | B_ASYNCHRONOUS_CONTROLS)
+	, fStatus(B_NO_INIT)
+	, fDialogSem(-1)
+	, fDialogValue(false)
+	, fFamily(family)
+	, fStyle(style)
+	, fSize(size)
+	, fFontSize(*size)
+	, fPreview(0)
+	, fFamiliesList(0)
+	, fStylesList(0)
+	, fSizesList(0)
+	, fSizesInput(0)
+{
+	strncpy(fFontFamily, *family, B_FONT_FAMILY_LENGTH);
+	strncpy(fFontStyle, *style, B_FONT_STYLE_LENGTH);
+
+	//  "client" area view
+	BBox *clientBox = new BBox(Bounds(), B_EMPTY_STRING, B_FOLLOW_ALL_SIDES,
+					B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE_JUMP | B_PULSE_NEEDED,
+					B_PLAIN_BORDER);
+	AddChild(clientBox);
+
+	//  client view
+	BRect RC = clientBox->Bounds();
+	RC.InsetBy(kVimDialogSpacingX, kVimDialogSpacingY);
+	BRect rc(RC.LeftTop(), RC.LeftTop());
+
+	//  at first create all controls
+	fPreview = new BStringView(rc, "preview", "DejaVu Sans Mono");
+	clientBox->AddChild(fPreview);
+
+	BBox* boxDivider = new BBox(rc, B_EMPTY_STRING,
+			B_FOLLOW_NONE, B_WILL_DRAW, B_FANCY_BORDER);
+	clientBox->AddChild(boxDivider);
+
+	BStringView *labelFamily = new BStringView(rc, "labelFamily", "Family:");
+	clientBox->AddChild(labelFamily);
+	labelFamily->ResizeToPreferred();
+
+	BStringView *labelStyle = new BStringView(rc, "labelStyle", "Style:");
+	clientBox->AddChild(labelStyle);
+	labelStyle->ResizeToPreferred();
+
+	BStringView *labelSize = new BStringView(rc, "labelSize", "Size:");
+	clientBox->AddChild(labelSize);
+	labelSize->ResizeToPreferred();
+
+	fFamiliesList = new BListView(rc, "listFamily",
+			B_SINGLE_SELECTION_LIST, B_FOLLOW_ALL_SIDES);
+	BScrollView *scrollFamilies = new BScrollView("scrollFamily",
+			fFamiliesList, B_FOLLOW_LEFT_RIGHT, 0, false, true);
+	clientBox->AddChild(scrollFamilies);
+
+	fStylesList= new BListView(rc, "listStyles",
+			B_SINGLE_SELECTION_LIST, B_FOLLOW_ALL_SIDES);
+	BScrollView *scrollStyles = new BScrollView("scrollStyle",
+			fStylesList, B_FOLLOW_LEFT_RIGHT, 0, false, true);
+	clientBox->AddChild(scrollStyles);
+
+	fSizesInput = new BTextControl(rc, "inputSize", NULL, "???",
+			new BMessage(kVimDialogSizeInputMsg));
+	clientBox->AddChild(fSizesInput);
+	fSizesInput->ResizeToPreferred();
+
+	fSizesList = new BListView(rc, "listSizes",
+			B_SINGLE_SELECTION_LIST, B_FOLLOW_ALL_SIDES);
+	BScrollView *scrollSizes = new BScrollView("scrollSize",
+			fSizesList, B_FOLLOW_LEFT_RIGHT, 0, false, true);
+	clientBox->AddChild(scrollSizes);
+
+	BButton *buttonOK = new BButton(rc, "buttonOK", "OK",
+						new BMessage(kVimDialogOKButtonMsg));
+	clientBox->AddChild(buttonOK);
+	buttonOK->ResizeToPreferred();
+
+	BButton *buttonCancel = new BButton(rc, "buttonCancel", "Cancel",
+						new BMessage(kVimDialogCancelButtonMsg));
+	clientBox->AddChild(buttonCancel);
+	buttonCancel->ResizeToPreferred();
+
+	//  layout controls
+	float lineHeight = labelFamily->Bounds().Height();
+	float previewHeight = lineHeight * 3;
+	float offsetYLabels = previewHeight + kVimDialogSpacingY;
+	float offsetYLists = offsetYLabels + lineHeight + kVimDialogSpacingY / 2;
+	float offsetYSizes = offsetYLists + fSizesInput->Bounds().Height() + kVimDialogSpacingY / 2;
+	float listsHeight = lineHeight * 9;
+	float offsetYButtons = offsetYLists + listsHeight +  kVimDialogSpacingY;
+	float maxControlsHeight = offsetYButtons + buttonOK->Bounds().Height();
+	float familiesWidth = labelFamily->Bounds().Width() * 5;
+	float offsetXStyles = familiesWidth + kVimDialogSpacingX;
+	float stylesWidth = labelStyle->Bounds().Width() * 4;
+	float offsetXSizes = offsetXStyles + stylesWidth + kVimDialogSpacingX;
+	float sizesWidth = labelSize->Bounds().Width() * 2;
+	float maxControlsWidth = offsetXSizes + sizesWidth;
+
+	ResizeTo(maxControlsWidth + kVimDialogSpacingX * 2,
+		maxControlsHeight + kVimDialogSpacingY * 2);
+
+	BRect rcVim = gui.vimWindow->Frame();
+	MoveTo(rcVim.left + (rcVim.Width() - Frame().Width()) / 2,
+			rcVim.top + (rcVim.Height() - Frame().Height()) / 2);
+
+	fPreview->ResizeTo(maxControlsWidth, previewHeight);
+	fPreview->SetAlignment(B_ALIGN_CENTER);
+
+	boxDivider->MoveBy(0.f, previewHeight + kVimDialogSpacingY / 2);
+	boxDivider->ResizeTo(maxControlsWidth, 1.f);
+
+	labelFamily->MoveBy(0.f, offsetYLabels);
+	labelStyle->MoveBy(offsetXStyles, offsetYLabels);
+	labelSize->MoveBy(offsetXSizes, offsetYLabels);
+
+	//  text control alignment issues
+	float insetX = fSizesInput->TextView()->Bounds().Width() - fSizesInput->Bounds().Width();
+	float insetY = fSizesInput->TextView()->Bounds().Width() - fSizesInput->Bounds().Width();
+
+	scrollFamilies->MoveBy(0.f, offsetYLists);
+	scrollStyles->MoveBy(offsetXStyles, offsetYLists);
+	fSizesInput->MoveBy(offsetXSizes + insetX / 2, offsetYLists + insetY / 2);
+	scrollSizes->MoveBy(offsetXSizes, offsetYSizes);
+
+	fSizesInput->SetAlignment(B_ALIGN_CENTER, B_ALIGN_CENTER);
+
+	scrollFamilies->ResizeTo(familiesWidth, listsHeight);
+	scrollStyles->ResizeTo(stylesWidth, listsHeight);
+	fSizesInput->ResizeTo(sizesWidth, fSizesInput->Bounds().Height());
+	scrollSizes->ResizeTo(sizesWidth,
+			listsHeight - (offsetYSizes - offsetYLists));
+
+	buttonOK->MoveBy(maxControlsWidth - buttonOK->Bounds().Width(), offsetYButtons);
+	buttonCancel->MoveBy(maxControlsWidth - buttonOK->Bounds().Width()
+			- buttonCancel->Bounds().Width() - kVimDialogSpacingX, offsetYButtons);
+
+	//  fill lists
+	int selIndex = -1;
+	int count = count_font_families();
+	for (int i = 0; i < count; i++) {
+		font_family family;
+		if (get_font_family(i, &family ) == B_OK) {
+			fFamiliesList->AddItem(new BStringItem((const char*)family));
+			if (strncmp(family, fFontFamily, B_FONT_FAMILY_LENGTH) == 0)
+				selIndex = i;
+		}
+	}
+
+	if (selIndex >= 0) {
+		fFamiliesList->Select(selIndex);
+		fFamiliesList->ScrollToSelection();
+	}
+
+	_UpdateFontStyles();
+
+	selIndex = -1;
+	for (int size = 8, index = 0; size <= 18; size++, index++) {
+		BString str;
+		str << size;
+		fSizesList->AddItem(new BStringItem(str));
+		if (size == fFontSize)
+			selIndex = index;
+
+	}
+
+	if (selIndex >= 0) {
+		fSizesList->Select(selIndex);
+		fSizesList->ScrollToSelection();
+	}
+
+	fFamiliesList->SetSelectionMessage(new BMessage(kVimDialogFamilySelectMsg));
+	fStylesList->SetSelectionMessage(new BMessage(kVimDialogStyleSelectMsg));
+	fSizesList->SetSelectionMessage(new BMessage(kVimDialogSizeSelectMsg));
+	fSizesInput->SetModificationMessage(new BMessage(kVimDialogSizeInputMsg));
+
+	_UpdateSizeInputPreview();
+	_UpdateFontPreview();
+
+	fStatus = B_OK;
+}
+
+VimSelectFontDialog::~VimSelectFontDialog()
+{
+	_CleanList(fFamiliesList);
+	_CleanList(fStylesList);
+	_CleanList(fSizesList);
+
+	if (fDialogSem > B_OK)
+		delete_sem(fDialogSem);
+}
+
+	void
+VimSelectFontDialog::_CleanList(BListView* list)
+{
+	while(0 < list->CountItems())
+		delete (dynamic_cast<BStringItem*>(list->RemoveItem((int32)0)));
+}
+
+	bool
+VimSelectFontDialog::Go()
+{
+	if (fStatus != B_OK) {
+		Quit();
+		return NOFONT;
+	}
+
+	fDialogSem = create_sem(0, "VimFontSelectDialogSem");
+	if(fDialogSem < B_OK) {
+		Quit();
+		return fDialogValue;
+	}
+
+	Show();
+
+	while(acquire_sem(fDialogSem) == B_INTERRUPTED);
+
+	bool retValue = fDialogValue;
+
+	if(Lock())
+		Quit();
+
+	return retValue;
+}
+
+
+void VimSelectFontDialog::_UpdateFontStyles()
+{
+	_CleanList(fStylesList);
+
+	int32 selIndex = -1;
+	int32 count = count_font_styles(fFontFamily);
+	for (int32 i = 0; i < count; i++) {
+		font_style style;
+		uint32 flags = 0;
+		if (get_font_style(fFontFamily, i, &style, &flags) == B_OK) {
+			fStylesList->AddItem(new BStringItem((const char*)style));
+			if (strncmp(style, fFontStyle, B_FONT_STYLE_LENGTH) == 0)
+				selIndex = i;
+		}
+	}
+
+	if (selIndex >= 0) {
+		fStylesList->Select(selIndex);
+		fStylesList->ScrollToSelection();
+	} else
+		fStylesList->Select(0);
+}
+
+
+void VimSelectFontDialog::_UpdateSizeInputPreview()
+{
+	char buf[10] = {0};
+	vim_snprintf(buf, sizeof(buf), (char*)"%.0f", fFontSize);
+	fSizesInput->SetText(buf);
+}
+
+
+void VimSelectFontDialog::_UpdateFontPreview()
+{
+	BFont font;
+	fPreview->GetFont(&font);
+	font.SetSize(fFontSize);
+	font.SetFamilyAndStyle(fFontFamily, fFontStyle);
+	fPreview->SetFont(&font, B_FONT_FAMILY_AND_STYLE | B_FONT_SIZE);
+
+	BString str;
+	str << fFontFamily << " " << fFontStyle << ", " << (int)fFontSize << " pt.";
+	fPreview->SetText(str);
+}
+
+
+	bool
+VimSelectFontDialog::_UpdateFromListItem(BListView* list, char* text, int textSize)
+{
+	int32 index = list->CurrentSelection();
+	if (index < 0)
+		return false;
+	BStringItem* item = (BStringItem*)list->ItemAt(index);
+	if (item == NULL)
+		return false;
+	strncpy(text, item->Text(), textSize);
+	return true;
+}
+
+
+void VimSelectFontDialog::MessageReceived(BMessage *msg)
+{
+	switch (msg->what) {
+		case kVimDialogOKButtonMsg:
+			strncpy(*fFamily, fFontFamily, B_FONT_FAMILY_LENGTH);
+			strncpy(*fStyle, fFontStyle, B_FONT_STYLE_LENGTH);
+			*fSize = fFontSize;
+			fDialogValue = true;
+		case kVimDialogCancelButtonMsg:
+			delete_sem(fDialogSem);
+			fDialogSem = -1;
+			return;
+		case B_KEY_UP:
+			{
+				int32 key = 0;
+				if (msg->FindInt32("raw_char", &key) == B_OK
+						&& key == B_ESCAPE) {
+					delete_sem(fDialogSem);
+					fDialogSem = -1;
+				}
+			}
+			break;
+
+		case kVimDialogFamilySelectMsg:
+			if (_UpdateFromListItem(fFamiliesList,
+					fFontFamily, B_FONT_FAMILY_LENGTH)) {
+				_UpdateFontStyles();
+				_UpdateFontPreview();
+			}
+			break;
+		case kVimDialogStyleSelectMsg:
+			if (_UpdateFromListItem(fStylesList,
+					fFontStyle, B_FONT_STYLE_LENGTH))
+				_UpdateFontPreview();
+			break;
+		case kVimDialogSizeSelectMsg:
+			{
+				char buf[10] = {0};
+				if (_UpdateFromListItem(fSizesList,	buf, sizeof(buf))) {
+					float size = atof(buf);
+					if (size > 0.f) {
+						fFontSize = size;
+						_UpdateSizeInputPreview();
+						_UpdateFontPreview();
+					}
+				}
+			}
+			break;
+		case kVimDialogSizeInputMsg:
+			{
+				float size = atof(fSizesInput->Text());
+				if (size > 0.f) {
+					fFontSize = size;
+					_UpdateFontPreview();
+				}
+			}
+			break;
+		default:
+			break;
+	}
+	return BWindow::MessageReceived(msg);
+}
+
+#endif // FEAT_GUI_DIALOG
+
+#ifdef FEAT_TOOLBAR
+
+//  some forward declaration required by toolbar functions...
+static BMessage * MenuMessage(vimmenu_T *menu);
+
+VimToolbar::VimToolbar(BRect frame, const char *name) :
+	BBox(frame, name, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_FRAME_EVENTS, B_PLAIN_BORDER)
+{
+}
+
+VimToolbar::~VimToolbar()
+{
+	int32 count = fButtonsList.CountItems();
+	for(int32 i = 0; i < count; i++)
+		delete (BPictureButton*)fButtonsList.ItemAt(i);
+	fButtonsList.MakeEmpty();
+
+	delete normalButtonsBitmap;
+	delete grayedButtonsBitmap;
+	normalButtonsBitmap    = NULL;
+	grayedButtonsBitmap  = NULL;
+}
+
+	void
+VimToolbar::AttachedToWindow()
+{
+	BBox::AttachedToWindow();
+
+	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
+}
+
+	float
+VimToolbar::ToolbarHeight() const
+{
+	float size = NULL == normalButtonsBitmap ? 18. : normalButtonsBitmap->Bounds().Height();
+	return size + ToolbarMargin * 2 + ButtonMargin * 2 + 1;
+}
+
+	bool
+VimToolbar::ModifyBitmapToGrayed(BBitmap *bitmap)
+{
+	float height = bitmap->Bounds().Height();
+	float width  = bitmap->Bounds().Width();
+
+	rgb_color *bits = (rgb_color*)bitmap->Bits();
+	int32 pixels = bitmap->BitsLength() / 4;
+	for(int32 i = 0; i < pixels; i++) {
+		bits[i].red = bits[i].green =
+		bits[i].blue = ((uint32)bits[i].red + bits[i].green + bits[i].blue) / 3;
+		bits[i].alpha /= 4;
+	}
+
+	return true;
+}
+
+	bool
+VimToolbar::PrepareButtonBitmaps()
+{
+	//  first try to load potentially customized $VIRUNTIME/bitmaps/builtin-tools.png
+	normalButtonsBitmap = LoadVimBitmap("builtin-tools.png");
+	if(normalButtonsBitmap == NULL)
+		//  customized not found? dig application resources for "builtin-tools" one
+		normalButtonsBitmap = BTranslationUtils::GetBitmap(B_PNG_FORMAT, "builtin-tools");
+
+	if(normalButtonsBitmap == NULL)
+		return false;
+
+	BMessage archive;
+	normalButtonsBitmap->Archive(&archive);
+
+	grayedButtonsBitmap = new BBitmap(&archive);
+	if(grayedButtonsBitmap == NULL)
+		return false;
+
+	//  modify grayed bitmap
+	ModifyBitmapToGrayed(grayedButtonsBitmap);
+
+	return true;
+}
+
+BBitmap *VimToolbar::LoadVimBitmap(const char* fileName)
+{
+	BBitmap *bitmap = NULL;
+
+	int mustfree = 0;
+	char_u* runtimePath = vim_getenv((char_u*)"VIMRUNTIME", &mustfree);
+	if(runtimePath != NULL && fileName != NULL) {
+		BString strPath((char*)runtimePath);
+		strPath << "/bitmaps/" << fileName;
+		bitmap = BTranslationUtils::GetBitmap(strPath.String());
+	}
+
+	if(mustfree)
+		vim_free(runtimePath);
+
+	return bitmap;
+}
+
+	bool
+VimToolbar::GetPictureFromBitmap(BPicture *pictureTo, int32 index, BBitmap *bitmapFrom, bool pressed)
+{
+	float size = bitmapFrom->Bounds().Height() + 1.;
+
+	BView view(BRect(0, 0, size, size), "", 0, 0);
+
+	AddChild(&view);
+	view.BeginPicture(pictureTo);
+
+	view.SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
+	view.FillRect(view.Bounds());
+	view.SetDrawingMode(B_OP_OVER);
+
+	BRect source(0, 0, size - 1, size - 1);
+	BRect destination(source);
+
+	source.OffsetBy(size * index, 0);
+	destination.OffsetBy(ButtonMargin, ButtonMargin);
+
+	view.DrawBitmap(bitmapFrom, source, destination);
+
+	if(pressed)	{
+		rgb_color shineColor  = ui_color(B_SHINE_COLOR);
+		rgb_color shadowColor = ui_color(B_SHADOW_COLOR);
+		size += ButtonMargin * 2 - 1;
+		view.BeginLineArray(4);
+		view.AddLine(BPoint(0, 0),		 BPoint(size, 0),	 shadowColor);
+		view.AddLine(BPoint(size, 0),	 BPoint(size, size), shineColor);
+		view.AddLine(BPoint(size, size), BPoint(0, size),	 shineColor);
+		view.AddLine(BPoint(0, size),	 BPoint(0, 0),		 shadowColor);
+		view.EndLineArray();
+	}
+
+	view.EndPicture();
+	RemoveChild(&view);
+
+	return true;
+}
+
+	bool
+VimToolbar::AddButton(int32 index, vimmenu_T *menu)
+{
+	BPictureButton *button = NULL;
+	if(!menu_is_separator(menu->name)) {
+		float size = normalButtonsBitmap ?
+			normalButtonsBitmap->Bounds().Height() + 1. + ButtonMargin * 2 : 18.;
+		BRect frame(0, 0, size, size);
+		BPicture pictureOn;
+		BPicture pictureOff;
+		BPicture pictureGray;
+
+		if(menu->iconfile == NULL && menu->iconidx >= 0 && normalButtonsBitmap) {
+			GetPictureFromBitmap(&pictureOn,  menu->iconidx, normalButtonsBitmap, true);
+			GetPictureFromBitmap(&pictureOff, menu->iconidx, normalButtonsBitmap, false);
+			GetPictureFromBitmap(&pictureGray, menu->iconidx, grayedButtonsBitmap, false);
+		} else {
+
+			char_u buffer[MAXPATHL] = {0};
+			BBitmap *bitmap = NULL;
+
+			if(menu->iconfile) {
+				gui_find_iconfile(menu->iconfile, buffer, (char*)"png");
+				bitmap = BTranslationUtils::GetBitmap((char*)buffer);
+			}
+
+			if(bitmap == NULL && gui_find_bitmap(menu->name, buffer, (char*)"png") == OK)
+				bitmap = BTranslationUtils::GetBitmap((char*)buffer);
+
+			if(bitmap == NULL)
+				bitmap = new BBitmap(BRect(0, 0, size, size), B_RGB32);
+
+			GetPictureFromBitmap(&pictureOn,   0, bitmap, true);
+			GetPictureFromBitmap(&pictureOff,  0, bitmap, false);
+			ModifyBitmapToGrayed(bitmap);
+			GetPictureFromBitmap(&pictureGray, 0, bitmap, false);
+
+			delete bitmap;
+		}
+
+		button = new BPictureButton(frame, (char*)menu->name,
+					&pictureOff, &pictureOn, MenuMessage(menu));
+
+		button->SetDisabledOn(&pictureGray);
+		button->SetDisabledOff(&pictureGray);
+
+		button->SetTarget(gui.vimTextArea);
+
+		AddChild(button);
+
+		menu->button = button;
+	}
+
+	bool result = fButtonsList.AddItem(button, index);
+	InvalidateLayout();
+	return result;
+}
+
+	bool
+VimToolbar::RemoveButton(vimmenu_T *menu)
+{
+	if(menu->button) {
+		if(fButtonsList.RemoveItem(menu->button)) {
+			delete menu->button;
+			menu->button = NULL;
+		}
+	}
+}
+
+	bool
+VimToolbar::GrayButton(vimmenu_T *menu, int grey)
+{
+	if(menu->button) {
+		int32 index = fButtonsList.IndexOf(menu->button);
+		if(index >= 0)
+			menu->button->SetEnabled(grey ? false : true);
+	}
+}
+
+	void
+VimToolbar::InvalidateLayout()
+{
+	int32 offset = ToolbarMargin;
+	int32 count = fButtonsList.CountItems();
+	for(int32 i = 0; i < count; i++) {
+		BPictureButton *button = (BPictureButton *)fButtonsList.ItemAt(i);
+		if(button) {
+			button->MoveTo(offset, ToolbarMargin);
+			offset += button->Bounds().Width() + ToolbarMargin;
+		} else
+			offset += ToolbarMargin * 3;
+	}
+}
+
+#endif /*FEAT_TOOLBAR*/
+
+#if defined(FEAT_GUI_TABLINE)
+
+	float
+VimTabLine::TablineHeight() const
+{
+//	float size = NULL == normalButtonsBitmap ? 18. : normalButtonsBitmap->Bounds().Height();
+//	return size + ToolbarMargin * 2 + ButtonMargin * 2 + 1;
+	return TabHeight(); //  + ToolbarMargin;
+}
+
+void
+VimTabLine::MouseDown(BPoint point)
+{
+	if(!gui_mch_showing_tabline())
+		return;
+
+	BMessage *m = Window()->CurrentMessage();
+	assert(m);
+
+	int32 buttons = 0;
+	m->FindInt32("buttons", &buttons);
+
+	int32 clicks = 0;
+	m->FindInt32("clicks", &clicks);
+
+	int index = 0; //  0 means here - no tab found
+	for (int i = 0; i < CountTabs(); i++) {
+		if(TabFrame(i).Contains(point)) {
+			index = i + 1; //  indexes are 1-based
+			break;
+		}
+	}
+
+	int event = -1;
+
+	if ((buttons & B_PRIMARY_MOUSE_BUTTON) && clicks > 1)
+		//  left button double click on - create new tab
+		event = TABLINE_MENU_NEW;
+
+	else if (buttons & B_TERTIARY_MOUSE_BUTTON)
+		//  middle button click - close the pointed tab
+		//  or create new one in case empty space
+		event = index > 0 ? TABLINE_MENU_CLOSE : TABLINE_MENU_NEW;
+
+	else if (buttons & B_SECONDARY_MOUSE_BUTTON) {
+		//  right button click - show context menu
+		BPopUpMenu* popUpMenu = new BPopUpMenu("tabLineContextMenu", false, false);
+		popUpMenu->AddItem(new BMenuItem(_("Close tabi R"), new BMessage(TABLINE_MENU_CLOSE)));
+		popUpMenu->AddItem(new BMenuItem(_("New tab    T"), new BMessage(TABLINE_MENU_NEW)));
+		popUpMenu->AddItem(new BMenuItem(_("Open tab..."), new BMessage(TABLINE_MENU_OPEN)));
+
+		ConvertToScreen(&point);
+		BMenuItem* item = popUpMenu->Go(point);
+		if (item != NULL) {
+			event = item->Command();
+		}
+
+		delete popUpMenu;
+
+	} else {
+		//  default processing
+		BTabView::MouseDown(point);
+		return;
+	}
+
+	if (event < 0)
+		return;
+
+	VimTablineMenuMsg tmm;
+	tmm.index = index;
+	tmm.event = event;
+	write_port(gui.vdcmp, VimMsg::TablineMenu, &tmm, sizeof(tmm));
+}
+
+void
+VimTabLine::VimTab::Select(BView* owner)
+{
+	BTab::Select(owner);
+
+	VimTabLine *tabLine = gui.vimForm->TabLine();
+	if(tabLine != NULL) {
+
+		int32 i = 0;
+		for (; i < tabLine->CountTabs(); i++)
+			if(this == tabLine->TabAt(i))
+				break;
+
+//		printf("%d:%d:%s\n", i, tabLine->CountTabs(), tabLine->TabAt(i)->Label());
+		if(i < tabLine->CountTabs()) {
+			VimTablineMsg tm;
+			tm.index = i + 1;
+			write_port(gui.vdcmp, VimMsg::Tabline, &tm, sizeof(tm));
+		}
+	}
+}
+
+#endif //  defined(FEAT_GUI_TABLINE)
+
+// ---------------- ----------------
+
+//  some global variables
+static char appsig[] = "application/x-vnd.Haiku-Vim-8";
+key_map *keyMap;
+char *keyMapChars;
+int main_exitcode = 127;
+
+	status_t
+gui_haiku_process_event(bigtime_t timeout)
+{
+	struct VimMsg vm;
+	int32 what;
+	ssize_t size;
+
+	size = read_port_etc(gui.vdcmp, &what, &vm, sizeof(vm),
+			B_TIMEOUT, timeout);
+
+	if (size >= 0) {
+		switch (what) {
+			case VimMsg::Key:
+				{
+					char_u *string = vm.u.Key.chars;
+					int len = vm.u.Key.length;
+					if (len == 1 && string[0] == Ctrl_chr('C')) {
+						trash_input_buf();
+						got_int = TRUE;
+					}
+
+					if (vm.u.Key.csi_escape)
+#ifndef FEAT_MBYTE_IME
+					{
+						int		i;
+						char_u	buf[2];
+
+						for (i = 0; i < len; ++i)
+						{
+							add_to_input_buf(string + i, 1);
+							if (string[i] == CSI)
+							{
+								// Turn CSI into K_CSI.
+								buf[0] = KS_EXTRA;
+								buf[1] = (int)KE_CSI;
+								add_to_input_buf(buf, 2);
+							}
+						}
+					}
+#else
+					add_to_input_buf_csi(string, len);
+#endif
+					else
+						add_to_input_buf(string, len);
+				}
+				break;
+			case VimMsg::Resize:
+				gui_resize_shell(vm.u.NewSize.width, vm.u.NewSize.height);
+				break;
+			case VimMsg::ScrollBar:
+				{
+					/*
+					 * If loads of scroll messages queue up, use only the last
+					 * one. Always report when the scrollbar stops dragging.
+					 * This is not perfect yet anyway: these events are queued
+					 * yet again, this time in the keyboard input buffer.
+					 */
+					int32 oldCount =
+						atomic_add(&vm.u.Scroll.sb->scrollEventCount, -1);
+					if (oldCount <= 1 || !vm.u.Scroll.stillDragging)
+						gui_drag_scrollbar(vm.u.Scroll.sb->getGsb(),
+								vm.u.Scroll.value, vm.u.Scroll.stillDragging);
+				}
+				break;
+#if defined(FEAT_MENU)
+			case VimMsg::Menu:
+				gui_menu_cb(vm.u.Menu.guiMenu);
+				break;
+#endif
+			case VimMsg::Mouse:
+				{
+					int32 oldCount;
+					if (vm.u.Mouse.button == MOUSE_DRAG)
+						oldCount =
+							atomic_add(&gui.vimTextArea->mouseDragEventCount, -1);
+					else
+						oldCount = 0;
+					if (oldCount <= 1)
+						gui_send_mouse_event(vm.u.Mouse.button, vm.u.Mouse.x,
+								vm.u.Mouse.y, vm.u.Mouse.repeated_click,
+								vm.u.Mouse.modifiers);
+				}
+				break;
+			case VimMsg::MouseMoved:
+				{
+					gui_mouse_moved(vm.u.MouseMoved.x, vm.u.MouseMoved.y);
+				}
+				break;
+			case VimMsg::Focus:
+				gui.in_focus = vm.u.Focus.active;
+				// XXX Signal that scrollbar dragging has stopped?
+				// This is needed because we don't get a MouseUp if
+				// that happens while outside the window... :-(
+				if (gui.dragged_sb) {
+					gui.dragged_sb = SBAR_NONE;
+				}
+				//  gui_update_cursor(TRUE, FALSE);
+				break;
+			case VimMsg::Refs:
+				::RefsReceived(vm.u.Refs.message, vm.u.Refs.changedir);
+				break;
+			case VimMsg::Tabline:
+				send_tabline_event(vm.u.Tabline.index);
+				break;
+			case VimMsg::TablineMenu:
+				send_tabline_menu_event(vm.u.TablineMenu.index, vm.u.TablineMenu.event);
+				break;
+			default:
+				//  unrecognised message, ignore it
+				break;
+		}
+	}
+
+	/*
+	 * If size < B_OK, it is an error code.
+	 */
+	return size;
+}
+
+/*
+ * Here are some functions to protect access to ScreenLines[] and
+ * LineOffset[]. These are used from the window thread to respond
+ * to a Draw() callback. When that occurs, the window is already
+ * locked by the system.
+ *
+ * Other code that needs to lock is any code that changes these
+ * variables. Other read-only access, or access merely to the
+ * contents of the screen buffer, need not be locked.
+ *
+ * If there is no window, don't call Lock() but do succeed.
+ */
+
+	int
+vim_lock_screen()
+{
+	return !gui.vimWindow || gui.vimWindow->Lock();
+}
+
+	void
+vim_unlock_screen()
+{
+	if (gui.vimWindow)
+		gui.vimWindow->Unlock();
+}
+
+#define RUN_BAPPLICATION_IN_NEW_THREAD	0
+
+#if RUN_BAPPLICATION_IN_NEW_THREAD
+
+	int32
+run_vimapp(void *args)
+{
+	VimApp app(appsig);
+
+	gui.vimApp = &app;
+	app.Run();			    // Run until Quit() called
+
+	return 0;
+}
+
+#else
+
+	int32
+call_main(void *args)
+{
+	struct MainArgs *ma = (MainArgs *)args;
+
+	return main(ma->argc, ma->argv);
+}
+#endif
+
+/*
+ * Parse the GUI related command-line arguments.  Any arguments used are
+ * deleted from argv, and *argc is decremented accordingly.  This is called
+ * when vim is started, whether or not the GUI has been started.
+ */
+	void
+gui_mch_prepare(
+		int		*argc,
+		char	**argv)
+{
+	/*
+	 * We don't have any command line arguments for the BeOS GUI yet,
+	 * but this is an excellent place to create our Application object.
+	 */
+	if (!gui.vimApp) {
+		thread_info tinfo;
+		get_thread_info(find_thread(NULL), &tinfo);
+
+		// May need the port very early on to process RefsReceived()
+		gui.vdcmp = create_port(B_MAX_PORT_COUNT, "vim VDCMP");
+
+#if RUN_BAPPLICATION_IN_NEW_THREAD
+		thread_id tid = spawn_thread(run_vimapp, "vim VimApp",
+				tinfo.priority, NULL);
+		if (tid >= B_OK) {
+			resume_thread(tid);
+		} else {
+			getout(1);
+		}
+#else
+		MainArgs ma = { *argc, argv };
+		thread_id tid = spawn_thread(call_main, "vim main()",
+				tinfo.priority, &ma);
+		if (tid >= B_OK) {
+			VimApp app(appsig);
+
+			gui.vimApp = &app;
+			resume_thread(tid);
+			/*
+			 * This is rather horrible.
+			 * call_main will call main() again...
+			 * There will be no infinite recursion since
+			 * gui.vimApp is set now.
+			 */
+			app.Run();			    // Run until Quit() called
+			// fprintf(stderr, "app.Run() returned...\n");
+			status_t dummy_exitcode;
+			(void)wait_for_thread(tid, &dummy_exitcode);
+
+			/*
+			 * This path should be the normal one taken to exit Vim.
+			 * The main() thread calls mch_exit() which calls
+			 * gui_mch_exit() which terminates its thread.
+			 */
+			exit(main_exitcode);
+		}
+#endif
+	}
+	// Don't fork() when starting the GUI. Spawned threads are not
+	// duplicated with a fork(). The result is a mess.
+	gui.dofork = FALSE;
+	/*
+	 * XXX Try to determine whether we were started from
+	 * the Tracker or the terminal.
+	 * It would be nice to have this work, because the Tracker
+	 * follows symlinks, so even if you double-click on gvim,
+	 * when it is a link to vim it will still pass a command name
+	 * of vim...
+	 * We try here to see if stdin comes from /dev/null. If so,
+	 * (or if there is an error, which should never happen) start the GUI.
+	 * This does the wrong thing for vim - </dev/null, and we're
+	 * too early to see the command line parsing. Tough.
+	 * On the other hand, it starts the gui for vim file & which is nice.
+	 */
+	if (!isatty(0)) {
+		struct stat stat_stdin, stat_dev_null;
+
+		if (fstat(0, &stat_stdin) == -1 ||
+				stat("/dev/null", &stat_dev_null) == -1 ||
+				(stat_stdin.st_dev == stat_dev_null.st_dev &&
+				 stat_stdin.st_ino == stat_dev_null.st_ino))
+			gui.starting = TRUE;
+	}
+}
+
+/*
+ * Check if the GUI can be started.  Called before gvimrc is sourced.
+ * Return OK or FAIL.
+ */
+	int
+gui_mch_init_check(void)
+{
+	return OK;		// TODO: GUI can always be started?
+}
+
+/*
+ * Initialise the GUI.  Create all the windows, set up all the call-backs
+ * etc.
+ */
+	int
+gui_mch_init()
+{
+    display_errors();
+	gui.def_norm_pixel = RGB(0x00, 0x00, 0x00);	//  black
+	gui.def_back_pixel = RGB(0xFF, 0xFF, 0xFF);	//  white
+	gui.norm_pixel = gui.def_norm_pixel;
+	gui.back_pixel = gui.def_back_pixel;
+
+	gui.scrollbar_width = (int) B_V_SCROLL_BAR_WIDTH;
+	gui.scrollbar_height = (int) B_H_SCROLL_BAR_HEIGHT;
+#ifdef FEAT_MENU
+	gui.menu_height = 19;	//  initial guess -
+	//  correct for my default settings
+#endif
+	gui.border_offset = 3;	//  coordinates are inside window borders
+
+	if (gui.vdcmp < B_OK)
+		return FAIL;
+	get_key_map(&keyMap, &keyMapChars);
+
+	gui.vimWindow = new VimWindow();	// hidden and locked
+	if (!gui.vimWindow)
+		return FAIL;
+
+	gui.vimWindow->Run();		// Run() unlocks but does not show
+
+	// Get the colors from the "Normal" group (set in syntax.c or in a vimrc
+	// file)
+	set_normal_colors();
+
+	/*
+	 * Check that none of the colors are the same as the background color
+	 */
+	gui_check_colors();
+
+	// Get the colors for the highlight groups (gui_check_colors() might have
+	// changed them)
+	highlight_gui_started();		// re-init colors and fonts
+
+	gui_mch_new_colors();		// window must exist for this
+
+	return OK;
+}
+
+/*
+ * Called when the foreground or background color has been changed.
+ */
+	void
+gui_mch_new_colors()
+{
+	rgb_color rgb = GUI_TO_RGB(gui.back_pixel);
+
+	if (gui.vimWindow->Lock()) {
+		gui.vimForm->SetViewColor(rgb);
+		//  Does this not have too much effect for those small rectangles?
+		gui.vimForm->Invalidate();
+		gui.vimWindow->Unlock();
+	}
+}
+
+/*
+ * Open the GUI window which was created by a call to gui_mch_init().
+ */
+	int
+gui_mch_open()
+{
+	if (gui_win_x != -1 && gui_win_y != -1)
+		gui_mch_set_winpos(gui_win_x, gui_win_y);
+
+	// Actually open the window
+	if (gui.vimWindow->Lock()) {
+		gui.vimWindow->Show();
+		gui.vimWindow->Unlock();
+		return OK;
+	}
+
+	return FAIL;
+}
+
+	void
+gui_mch_exit(int vim_exitcode)
+{
+	if (gui.vimWindow) {
+		thread_id tid = gui.vimWindow->Thread();
+		gui.vimWindow->Lock();
+		gui.vimWindow->Quit();
+		// Wait until it is truely gone
+		int32 exitcode;
+		wait_for_thread(tid, &exitcode);
+	}
+	delete_port(gui.vdcmp);
+#if !RUN_BAPPLICATION_IN_NEW_THREAD
+	/*
+	 * We are in the main() thread - quit the App thread and
+	 * quit ourselves (passing on the exitcode). Use a global since the
+	 * value from exit_thread() is only used if wait_for_thread() is
+	 * called in time (race condition).
+	 */
+#endif
+	if (gui.vimApp) {
+		VimTextAreaView::guiBlankMouse(false);
+
+		main_exitcode = vim_exitcode;
+#if RUN_BAPPLICATION_IN_NEW_THREAD
+		thread_id tid = gui.vimApp->Thread();
+		int32 exitcode;
+		gui.vimApp->Lock();
+		gui.vimApp->Quit();
+		gui.vimApp->Unlock();
+		wait_for_thread(tid, &exitcode);
+#else
+		gui.vimApp->Lock();
+		gui.vimApp->Quit();
+		gui.vimApp->Unlock();
+		// suicide
+		exit_thread(vim_exitcode);
+#endif
+	}
+	// If we are somehow still here, let mch_exit() handle things.
+}
+
+/*
+ * Get the position of the top left corner of the window.
+ */
+	int
+gui_mch_get_winpos(int *x, int *y)
+{
+	if (gui.vimWindow->Lock()) {
+		BRect r;
+		r = gui.vimWindow->Frame();
+		gui.vimWindow->Unlock();
+		*x = (int)r.left;
+		*y = (int)r.top;
+		return OK;
+	}
+	else
+		return FAIL;
+}
+
+/*
+ * Set the position of the top left corner of the window to the given
+ * coordinates.
+ */
+	void
+gui_mch_set_winpos(int x, int y)
+{
+	if (gui.vimWindow->Lock()) {
+		gui.vimWindow->MoveTo(x, y);
+		gui.vimWindow->Unlock();
+	}
+}
+
+/*
+ * Set the size of the window to the given width and height in pixels.
+ */
+void
+gui_mch_set_shellsize(
+		int		width,
+		int		height,
+		int		min_width,
+		int		min_height,
+		int		base_width,
+		int		base_height,
+		int		direction) // TODO: utilize?
+{
+	/*
+	 * We are basically given the size of the VimForm, if I understand
+	 * correctly. Since it fills the window completely, this will also
+	 * be the size of the window.
+	 */
+	if (gui.vimWindow->Lock()) {
+		gui.vimWindow->ResizeTo(width - PEN_WIDTH, height - PEN_WIDTH);
+
+		// set size limits
+		float minWidth, maxWidth, minHeight, maxHeight;
+
+		gui.vimWindow->GetSizeLimits(&minWidth, &maxWidth,
+				&minHeight, &maxHeight);
+		gui.vimWindow->SetSizeLimits(min_width, maxWidth,
+				min_height, maxHeight);
+
+		/*
+		 * Set the resizing alignment depending on font size.
+		 */
+		gui.vimWindow->SetWindowAlignment(
+				B_PIXEL_ALIGNMENT,		//  window_alignment mode,
+				1,				//  int32 h,
+				0,				//  int32 hOffset = 0,
+				gui.char_width,		//  int32 width = 0,
+				base_width,			//  int32 widthOffset = 0,
+				1,				//  int32 v = 0,
+				0,				//  int32 vOffset = 0,
+				gui.char_height,		//  int32 height = 0,
+				base_height			//  int32 heightOffset = 0
+				);
+
+		gui.vimWindow->Unlock();
+	}
+}
+
+void
+gui_mch_get_screen_dimensions(
+		int		*screen_w,
+		int		*screen_h)
+{
+	BRect frame;
+
+	{
+		BScreen screen(gui.vimWindow);
+
+		if (screen.IsValid()) {
+			frame = screen.Frame();
+		} else {
+			frame.right = 640;
+			frame.bottom = 480;
+		}
+	}
+
+	// XXX approximations...
+	*screen_w = (int) frame.right - 2 * gui.scrollbar_width - 20;
+	*screen_h = (int) frame.bottom - gui.scrollbar_height
+#ifdef FEAT_MENU
+		- gui.menu_height
+#endif
+		- 30;
+}
+
+void
+gui_mch_set_text_area_pos(
+		int		x,
+		int		y,
+		int		w,
+		int		h)
+{
+	if (!gui.vimTextArea)
+		return;
+
+	if (gui.vimWindow->Lock()) {
+		gui.vimTextArea->MoveTo(x, y);
+		gui.vimTextArea->ResizeTo(w - PEN_WIDTH, h - PEN_WIDTH);
+
+/*#ifdef FEAT_GUI_TABLINE
+		if(gui.vimForm->TabLine() != NULL) {
+			gui.vimForm->TabLine()->ResizeTo(w, gui.vimForm->TablineHeight());
+		}
+#endif // FEAT_GUI_TABLINE
+
+		gui.vimWindow->Unlock();
+	}
+}
+
+
+/*
+ * Scrollbar stuff:
+ */
+
+void
+gui_mch_enable_scrollbar(
+		scrollbar_T	*sb,
+		int		flag)
+{
+	VimScrollBar *vsb = sb->id;
+	if (gui.vimWindow->Lock()) {
+		/*
+		 * This function is supposed to be idempotent, but Show()/Hide()
+		 * is not. Therefore we test if they are needed.
+		 */
+		if (flag) {
+			if (vsb->IsHidden()) {
+				vsb->Show();
+			}
+		} else {
+			if (!vsb->IsHidden()) {
+				vsb->Hide();
+			}
+		}
+		gui.vimWindow->Unlock();
+	}
+}
+
+void
+gui_mch_set_scrollbar_thumb(
+		scrollbar_T *sb,
+		int		val,
+		int		size,
+		int		max)
+{
+	if (gui.vimWindow->Lock()) {
+		VimScrollBar *s = sb->id;
+		if (max == 0) {
+			s->SetValue(0);
+			s->SetRange(0.0, 0.0);
+		} else {
+			s->SetProportion((float)size / (max + 1.0));
+			s->SetSteps(1.0, size > 5 ? size - 2 : size);
+#ifndef SCROLL_PAST_END		//  really only defined in gui.c...
+			max = max + 1 - size;
+#endif
+			if (max < s->Value()) {
+				/*
+				 * If the new maximum is lower than the current value,
+				 * setting it would cause the value to be clipped and
+				 * therefore a ValueChanged() call.
+				 * We avoid this by setting the value first, because
+				 * it presumably is <= max.
+				 */
+				s->SetValue(val);
+				s->SetRange(0.0, max);
+			} else {
+				/*
+				 * In the other case, set the range first, since the
+				 * new value might be higher than the current max.
+				 */
+				s->SetRange(0.0, max);
+				s->SetValue(val);
+			}
+		}
+		gui.vimWindow->Unlock();
+	}
+}
+
+void
+gui_mch_set_scrollbar_pos(
+		scrollbar_T *sb,
+		int		x,
+		int		y,
+		int		w,
+		int		h)
+{
+	if (gui.vimWindow->Lock()) {
+		BRect winb = gui.vimWindow->Bounds();
+		float vsbx = x, vsby = y;
+		VimScrollBar *vsb = sb->id;
+		vsb->ResizeTo(w - PEN_WIDTH, h - PEN_WIDTH);
+		if(winb.right-(x+w)<w) vsbx = winb.right - (w - PEN_WIDTH);
+		vsb->MoveTo(vsbx, vsby);
+		gui.vimWindow->Unlock();
+	}
+}
+
+void
+gui_mch_create_scrollbar(
+		scrollbar_T *sb,
+		int		orient)		// SBAR_VERT or SBAR_HORIZ
+{
+	orientation posture =
+		(orient == SBAR_HORIZ) ? B_HORIZONTAL : B_VERTICAL;
+
+	VimScrollBar *vsb = sb->id = new VimScrollBar(sb, posture);
+	if (gui.vimWindow->Lock()) {
+		vsb->SetTarget(gui.vimTextArea);
+		vsb->Hide();
+		gui.vimForm->AddChild(vsb);
+		gui.vimWindow->Unlock();
+	}
+}
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+void
+gui_mch_destroy_scrollbar(
+		scrollbar_T	*sb)
+{
+	if (gui.vimWindow->Lock()) {
+		sb->id->RemoveSelf();
+		delete sb->id;
+		gui.vimWindow->Unlock();
+	}
+}
+#endif
+
+/*
+ * Cursor does not flash
+ */
+    int
+gui_mch_is_blink_off(void)
+{
+    return FALSE;
+}
+
+/*
+ * Cursor blink functions.
+ *
+ * This is a simple state machine:
+ * BLINK_NONE	not blinking at all
+ * BLINK_OFF	blinking, cursor is not shown
+ * BLINK_ON	blinking, cursor is shown
+ */
+
+#define BLINK_NONE  0
+#define BLINK_OFF   1
+#define BLINK_ON    2
+
+static int		blink_state = BLINK_NONE;
+static long_u		blink_waittime = 700;
+static long_u		blink_ontime = 400;
+static long_u		blink_offtime = 250;
+static int	blink_timer = 0;
+
+void
+gui_mch_set_blinking(
+		long    waittime,
+		long    on,
+		long    off)
+{
+	// TODO
+	blink_waittime = waittime;
+	blink_ontime = on;
+	blink_offtime = off;
+}
+
+/*
+ * Stop the cursor blinking.  Show the cursor if it wasn't shown.
+ */
+	void
+gui_mch_stop_blink()
+{
+	// TODO
+	if (blink_timer != 0)
+	{
+		// XtRemoveTimeOut(blink_timer);
+		blink_timer = 0;
+	}
+	if (blink_state == BLINK_OFF)
+		gui_update_cursor(TRUE, FALSE);
+	blink_state = BLINK_NONE;
+}
+
+/*
+ * Start the cursor blinking.  If it was already blinking, this restarts the
+ * waiting time and shows the cursor.
+ */
+	void
+gui_mch_start_blink()
+{
+	// TODO
+	if (blink_timer != 0)
+		;// XtRemoveTimeOut(blink_timer);
+	// Only switch blinking on if none of the times is zero
+	if (blink_waittime && blink_ontime && blink_offtime && gui.in_focus)
+	{
+		blink_timer = 1; // XtAppAddTimeOut(app_context, blink_waittime,
+		blink_state = BLINK_ON;
+		gui_update_cursor(TRUE, FALSE);
+	}
+}
+
+/*
+ * Initialise vim to use the font with the given name.	Return FAIL if the font
+ * could not be loaded, OK otherwise.
+ */
+int
+gui_mch_init_font(
+		char_u		*font_name,
+		int			fontset)
+{
+	if (gui.vimWindow->Lock())
+	{
+		int rc = gui.vimTextArea->mchInitFont(font_name);
+		gui.vimWindow->Unlock();
+
+		return rc;
+	}
+
+	return FAIL;
+}
+
+
+	int
+gui_mch_adjust_charsize()
+{
+	return FAIL;
+}
+
+
+	int
+gui_mch_font_dialog(font_family* family, font_style* style, float* size)
+{
+#if defined(FEAT_GUI_DIALOG)
+		// gui.vimWindow->Unlock();
+	VimSelectFontDialog *dialog = new VimSelectFontDialog(family, style, size);
+	return dialog->Go();
+#else
+	return NOFONT;
+#endif // FEAT_GUI_DIALOG
+}
+
+
+GuiFont
+gui_mch_get_font(
+		char_u		*name,
+		int			giveErrorIfMissing)
+{
+	static VimFont *fontList = NULL;
+
+	if (!gui.in_use)	//  can't do this when GUI not running
+		return NOFONT;
+
+	//  storage for locally modified name;
+	const int buff_size = B_FONT_FAMILY_LENGTH + B_FONT_STYLE_LENGTH + 20;
+	static char font_name[buff_size] = {0};
+	font_family family = {0};
+	font_style  style  = {0};
+	float size = 0.f;
+
+	if (name == 0 && be_fixed_font == 0) {
+		if(giveErrorIfMissing)
+                        semsg(_(e_font), name);
+		return NOFONT;
+	}
+
+	bool useSelectGUI = false;
+	if (name != NULL)
+		if (STRCMP(name, "*") == 0) {
+			useSelectGUI = true;
+			STRNCPY(font_name, hl_get_font_name(), buff_size);
+		} else
+			STRNCPY(font_name, name, buff_size);
+
+	if (font_name[0] == 0) {
+		be_fixed_font->GetFamilyAndStyle(&family, &style);
+		size = be_fixed_font->Size();
+		vim_snprintf(font_name, buff_size,
+			(char*)"%s/%s/%.0f", family, style, size);
+	}
+
+	//  replace underscores with spaces
+	char* end = 0;
+	while (end = strchr((char *)font_name, '_'))
+		*end = ' ';
+
+	//  store the name before strtok corrupt the buffer ;-)
+	static char buff[buff_size] = {0};
+	STRNCPY(buff, font_name, buff_size);
+	STRNCPY(family, strtok(buff, "/\0"), B_FONT_FAMILY_LENGTH);
+	char* style_s = strtok(0, "/\0");
+	if (style_s != 0)
+		STRNCPY(style, style_s, B_FONT_STYLE_LENGTH);
+	size = atof((style_s != 0) ? strtok(0, "/\0") : "0");
+
+	if (useSelectGUI) {
+		if(gui_mch_font_dialog(&family, &style, &size) == NOFONT)
+			return FAIL;
+		//  compose for further processing
+		vim_snprintf(font_name, buff_size,
+				(char*)"%s/%s/%.0f", family, style, size);
+		hl_set_font_name((char_u*)font_name);
+
+		//  Set guifont to the name of the selected font.
+		char_u* new_p_guifont = alloc(STRLEN(font_name) + 1);
+		if (new_p_guifont != NULL) {
+			STRCPY(new_p_guifont, font_name);
+			vim_free(p_guifont);
+			p_guifont = new_p_guifont;
+			//  Replace spaces in the font name with underscores.
+			for ( ; *new_p_guifont; ++new_p_guifont)
+				if (*new_p_guifont == ' ')
+					*new_p_guifont = '_';
+		}
+	}
+
+	VimFont *flp;
+	for (flp = fontList; flp; flp = flp->next) {
+		if (STRCMP(font_name, flp->name) == 0) {
+			flp->refcount++;
+			return (GuiFont)flp;
+		}
+	}
+
+	VimFont *font = new VimFont();
+	font->name = vim_strsave((char_u*)font_name);
+
+	if(count_font_styles(family) <= 0) {
+		if (giveErrorIfMissing)
+                        semsg(_(e_font), font->name);
+		delete font;
+		return NOFONT;
+	}
+
+	//  Remember font in the static list for later use
+	font->next = fontList;
+	fontList = font;
+
+	font->SetFamilyAndStyle(family, style);
+	if(size > 0.f)
+		font->SetSize(size);
+
+	font->SetSpacing(B_FIXED_SPACING);
+	font->SetEncoding(B_UNICODE_UTF8);
+
+	return (GuiFont)font;
+}
+
+/*
+ * Set the current text font.
+ */
+void
+gui_mch_set_font(
+		GuiFont	font)
+{
+	if (gui.vimWindow->Lock()) {
+		VimFont *vf = (VimFont *)font;
+
+		gui.vimTextArea->SetFont(vf);
+
+		gui.char_width = (int) vf->StringWidth("n");
+		font_height fh;
+		vf->GetHeight(&fh);
+		gui.char_height = (int)(fh.ascent + 0.9999)
+			+ (int)(fh.descent + 0.9999) + (int)(fh.leading + 0.9999);
+		gui.char_ascent = (int)(fh.ascent + 0.9999);
+
+		gui.vimWindow->Unlock();
+	}
+}
+
+// XXX TODO This is apparently never called...
+void
+gui_mch_free_font(
+		GuiFont	font)
+{
+	if(font == NOFONT)
+		return;
+	VimFont *f = (VimFont *)font;
+	if (--f->refcount <= 0) {
+		if (f->refcount < 0)
+			fprintf(stderr, "VimFont: refcount < 0\n");
+		delete f;
+	}
+}
+
+	char_u *
+gui_mch_get_fontname(GuiFont font, char_u *name)
+{
+	if (name == NULL)
+		return NULL;
+	return vim_strsave(name);
+}
+
+/*
+ * Adjust gui.char_height (after 'linespace' was changed).
+ */
+	int
+gui_mch_adjust_charheight()
+{
+
+	// TODO: linespace support?
+
+// #ifdef FEAT_XFONTSET
+//	if (gui.fontset != NOFONTSET)
+//	{
+//	gui.char_height = fontset_height((XFontSet)gui.fontset) + p_linespace;
+//	gui.char_ascent = fontset_ascent((XFontSet)gui.fontset)
+//	+ p_linespace / 2;
+//	}
+//	else
+// #endif
+	{
+		VimFont *font = (VimFont *)gui.norm_font;
+		font_height fh = {0};
+		font->GetHeight(&fh);
+		gui.char_height = (int)(fh.ascent + fh.descent + 0.5) + p_linespace;
+		gui.char_ascent = (int)(fh.ascent + 0.5) + p_linespace / 2;
+	}
+	return OK;
+}
+
+/*
+ * Display the saved error message(s).
+ */
+#ifdef USE_MCH_ERRMSG
+    void
+display_errors(void)
+{
+    char	*p;
+    char_u	pError[256];
+
+    if (error_ga.ga_data == NULL)
+	return;
+
+    // avoid putting up a message box with blanks only
+    for (p = (char *)error_ga.ga_data; *p; ++p)
+	if (!isspace(*p))
+	{
+	    if (STRLEN(p) > 255)
+		pError[0] = 255;
+	    else
+		pError[0] = STRLEN(p);
+
+	    STRNCPY(&pError[1], p, pError[0]);
+//	    ParamText(pError, nil, nil, nil);
+//	    Alert(128, nil);
+	    break;
+	    // TODO: handled message longer than 256 chars
+	    //	 use auto-sizeable alert
+	    //	 or dialog with scrollbars (TextEdit zone)
+	}
+    ga_clear(&error_ga);
+}
+#endif
+
+	void
+gui_mch_getmouse(int *x, int *y)
+{
+	fprintf(stderr, "gui_mch_getmouse");
+
+	/*int		rootx, rooty, winx, winy;
+	  Window	root, child;
+	  unsigned int mask;
+
+	  if (gui.wid && XQueryPointer(gui.dpy, gui.wid, &root, &child,
+	  &rootx, &rooty, &winx, &winy, &mask)) {
+	 *x = winx;
+	 *y = winy;
+	 } else*/ {
+		 *x = -1;
+		 *y = -1;
+	 }
+}
+
+	void
+gui_mch_mousehide(int hide)
+{
+	fprintf(stderr, "gui_mch_getmouse");
+	//  TODO
+}
+
+	static int
+hex_digit(int c)
+{
+	if (isdigit(c))
+		return c - '0';
+	c = TOLOWER_ASC(c);
+	if (c >= 'a' && c <= 'f')
+		return c - 'a' + 10;
+	return -1000;
+}
+
+/*
+ * This function has been lifted from gui_w32.c and extended a bit.
+ *
+ * Return the Pixel value (color) for the given color name.
+ * Return INVALCOLOR for error.
+ */
+guicolor_T
+gui_mch_get_color(
+		char_u	*name)
+{
+	typedef struct GuiColourTable
+	{
+		const char    *name;
+		guicolor_T     colour;
+	} GuiColourTable;
+
+#define NSTATIC_COLOURS		50 // 32
+#define NDYNAMIC_COLOURS	33
+#define NCOLOURS		(NSTATIC_COLOURS + NDYNAMIC_COLOURS)
+
+	static GuiColourTable table[NCOLOURS] =
+	{
+		{"Black",	    RGB(0x00, 0x00, 0x00)},
+		{"DarkGray",	    RGB(0x80, 0x80, 0x80)},
+		{"DarkGrey",	    RGB(0x80, 0x80, 0x80)},
+		{"Gray",	    RGB(0xC0, 0xC0, 0xC0)},
+		{"Grey",	    RGB(0xC0, 0xC0, 0xC0)},
+		{"LightGray",	    RGB(0xD3, 0xD3, 0xD3)},
+		{"LightGrey",	    RGB(0xD3, 0xD3, 0xD3)},
+		{"Gray10",	    RGB(0x1A, 0x1A, 0x1A)},
+		{"Grey10",	    RGB(0x1A, 0x1A, 0x1A)},
+		{"Gray20",	    RGB(0x33, 0x33, 0x33)},
+		{"Grey20",	    RGB(0x33, 0x33, 0x33)},
+		{"Gray30",	    RGB(0x4D, 0x4D, 0x4D)},
+		{"Grey30",	    RGB(0x4D, 0x4D, 0x4D)},
+		{"Gray40",	    RGB(0x66, 0x66, 0x66)},
+		{"Grey40",	    RGB(0x66, 0x66, 0x66)},
+		{"Gray50",	    RGB(0x7F, 0x7F, 0x7F)},
+		{"Grey50",	    RGB(0x7F, 0x7F, 0x7F)},
+		{"Gray60",	    RGB(0x99, 0x99, 0x99)},
+		{"Grey60",	    RGB(0x99, 0x99, 0x99)},
+		{"Gray70",	    RGB(0xB3, 0xB3, 0xB3)},
+		{"Grey70",	    RGB(0xB3, 0xB3, 0xB3)},
+		{"Gray80",	    RGB(0xCC, 0xCC, 0xCC)},
+		{"Grey80",	    RGB(0xCC, 0xCC, 0xCC)},
+		{"Gray90",	    RGB(0xE5, 0xE5, 0xE5)},
+		{"Grey90",	    RGB(0xE5, 0xE5, 0xE5)},
+		{"White",	    RGB(0xFF, 0xFF, 0xFF)},
+		{"DarkRed",	    RGB(0x80, 0x00, 0x00)},
+		{"Red",		    RGB(0xFF, 0x00, 0x00)},
+		{"LightRed",	    RGB(0xFF, 0xA0, 0xA0)},
+		{"DarkBlue",	    RGB(0x00, 0x00, 0x80)},
+		{"Blue",	    RGB(0x00, 0x00, 0xFF)},
+		{"LightBlue",	    RGB(0xA0, 0xA0, 0xFF)},
+		{"DarkGreen",	    RGB(0x00, 0x80, 0x00)},
+		{"Green",	    RGB(0x00, 0xFF, 0x00)},
+		{"LightGreen",	    RGB(0xA0, 0xFF, 0xA0)},
+		{"DarkCyan",	    RGB(0x00, 0x80, 0x80)},
+		{"Cyan",	    RGB(0x00, 0xFF, 0xFF)},
+		{"LightCyan",	    RGB(0xA0, 0xFF, 0xFF)},
+		{"DarkMagenta",	    RGB(0x80, 0x00, 0x80)},
+		{"Magenta",	    RGB(0xFF, 0x00, 0xFF)},
+		{"LightMagenta",    RGB(0xFF, 0xA0, 0xFF)},
+		{"Brown",	    RGB(0x80, 0x40, 0x40)},
+		{"Yellow",	    RGB(0xFF, 0xFF, 0x00)},
+		{"LightYellow",	    RGB(0xFF, 0xFF, 0xA0)},
+		{"DarkYellow",	    RGB(0xBB, 0xBB, 0x00)},
+		{"SeaGreen",	    RGB(0x2E, 0x8B, 0x57)},
+		{"Orange",	    RGB(0xFF, 0xA5, 0x00)},
+		{"Purple",	    RGB(0xA0, 0x20, 0xF0)},
+		{"SlateBlue",	    RGB(0x6A, 0x5A, 0xCD)},
+		{"Violet",	    RGB(0xEE, 0x82, 0xEE)},
+		//  NOTE: some entries are zero-allocated for NDDYNAMIC_COLORS
+		//		 in this table!
+	};
+
+	static int endColour = NSTATIC_COLOURS;
+	static int newColour = NSTATIC_COLOURS;
+
+	int		    r, g, b;
+	int		    i;
+
+	if (name[0] == '#' && STRLEN(name) == 7)
+	{
+		// Name is in "#rrggbb" format
+		r = hex_digit(name[1]) * 16 + hex_digit(name[2]);
+		g = hex_digit(name[3]) * 16 + hex_digit(name[4]);
+		b = hex_digit(name[5]) * 16 + hex_digit(name[6]);
+		if (r < 0 || g < 0 || b < 0)
+			return INVALCOLOR;
+		return RGB(r, g, b);
+	}
+	else
+	{
+		// Check if the name is one of the colours we know
+		for (i = 0; i < endColour; i++)
+			if (STRICMP(name, table[i].name) == 0)
+				return table[i].colour;
+	}
+
+	/*
+	 * Last attempt. Look in the file "$VIMRUNTIME/rgb.txt".
+	 */
+	{
+#define LINE_LEN 100
+		FILE	*fd;
+		char	line[LINE_LEN];
+		char_u	*fname;
+
+		fname = expand_env_save((char_u *)"$VIMRUNTIME/rgb.txt");
+		if (fname == NULL)
+			return INVALCOLOR;
+
+		fd = fopen((char *)fname, "rt");
+		vim_free(fname);
+		if (fd == NULL)
+			return INVALCOLOR;
+
+		while (!feof(fd))
+		{
+			int	    len;
+			int	    pos;
+			char    *colour;
+
+			fgets(line, LINE_LEN, fd);
+			len = strlen(line);
+
+			if (len <= 1 || line[len-1] != '\n')
+				continue;
+
+			line[len-1] = '\0';
+
+			i = sscanf(line, "%d %d %d %n", &r, &g, &b, &pos);
+			if (i != 3)
+				continue;
+
+			colour = line + pos;
+
+			if (STRICMP(colour, name) == 0)
+			{
+				fclose(fd);
+				/*
+				 * Now remember this colour in the table.
+				 * A LRU scheme might be better but this is simpler.
+				 * Or could use a growing array.
+				 */
+				guicolor_T gcolour = RGB(r,g,b);
+
+				// NOTE: see note above in table allocation! We are working here with
+				//		dynamically allocated names, not constant ones!
+				vim_free((char*)table[newColour].name);
+				table[newColour].name = (char *)vim_strsave((char_u *)colour);
+				table[newColour].colour = gcolour;
+
+				newColour++;
+				if (newColour >= NCOLOURS)
+					newColour = NSTATIC_COLOURS;
+				if (endColour < NCOLOURS)
+					endColour = newColour;
+
+				return gcolour;
+			}
+		}
+
+		fclose(fd);
+	}
+
+	return INVALCOLOR;
+}
+
+/*
+ * Set the current text foreground color.
+ */
+void
+gui_mch_set_fg_color(
+		guicolor_T	color)
+{
+	rgb_color rgb = GUI_TO_RGB(color);
+	if (gui.vimWindow->Lock()) {
+		gui.vimTextArea->SetHighColor(rgb);
+		gui.vimWindow->Unlock();
+	}
+}
+
+/*
+ * Set the current text background color.
+ */
+void
+gui_mch_set_bg_color(
+		guicolor_T	color)
+{
+	rgb_color rgb = GUI_TO_RGB(color);
+	if (gui.vimWindow->Lock()) {
+		gui.vimTextArea->SetLowColor(rgb);
+		gui.vimWindow->Unlock();
+	}
+}
+
+/*
+ * Set the current text special color.
+ */
+	void
+gui_mch_set_sp_color(guicolor_T	color)
+{
+	// prev_sp_color = color;
+}
+
+void
+gui_mch_draw_string(
+		int		row,
+		int		col,
+		char_u	*s,
+		int		len,
+		int		flags)
+{
+	if (gui.vimWindow->Lock()) {
+		gui.vimTextArea->mchDrawString(row, col, s, len, flags);
+		gui.vimWindow->Unlock();
+	}
+}
+
+        guicolor_T
+gui_mch_get_rgb_color(int r, int g, int b)
+{
+    return gui_get_rgb_color_cmn(r, g, b);
+}
+
+
+// Return OK if the key with the termcap name "name" is supported.
+int
+gui_mch_haskey(
+		char_u	*name)
+{
+	int i;
+
+	for (i = 0; special_keys[i].BeKeys != 0; i++)
+		if (name[0] == special_keys[i].vim_code0 &&
+				name[1] == special_keys[i].vim_code1)
+			return OK;
+	return FAIL;
+}
+
+	void
+gui_mch_beep()
+{
+	::beep();
+}
+
+	void
+gui_mch_flash(int msec)
+{
+	// Do a visual beep by reversing the foreground and background colors
+
+	if (gui.vimWindow->Lock()) {
+		BRect rect = gui.vimTextArea->Bounds();
+
+		gui.vimTextArea->SetDrawingMode(B_OP_INVERT);
+		gui.vimTextArea->FillRect(rect);
+		gui.vimTextArea->Sync();
+		snooze(msec * 1000);	 // wait for a few msec
+		gui.vimTextArea->FillRect(rect);
+		gui.vimTextArea->SetDrawingMode(B_OP_COPY);
+		gui.vimTextArea->Flush();
+		gui.vimWindow->Unlock();
+	}
+}
+
+/*
+ * Invert a rectangle from row r, column c, for nr rows and nc columns.
+ */
+void
+gui_mch_invert_rectangle(
+		int		r,
+		int		c,
+		int		nr,
+		int		nc)
+{
+	BRect rect;
+	rect.left = FILL_X(c);
+	rect.top = FILL_Y(r);
+	rect.right = rect.left + nc * gui.char_width - PEN_WIDTH;
+	rect.bottom = rect.top + nr * gui.char_height - PEN_WIDTH;
+
+	if (gui.vimWindow->Lock()) {
+		gui.vimTextArea->SetDrawingMode(B_OP_INVERT);
+		gui.vimTextArea->FillRect(rect);
+		gui.vimTextArea->SetDrawingMode(B_OP_COPY);
+		gui.vimWindow->Unlock();
+	}
+}
+
+/*
+ * Iconify the GUI window.
+ */
+	void
+gui_mch_iconify()
+{
+	if (gui.vimWindow->Lock()) {
+		gui.vimWindow->Minimize(true);
+		gui.vimWindow->Unlock();
+	}
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Bring the Vim window to the foreground.
+ */
+	void
+gui_mch_set_foreground(void)
+{
+	// TODO
+}
+#endif
+
+/*
+ * Set the window title
+ */
+void
+gui_mch_settitle(
+		char_u	*title,
+		char_u	*icon)
+{
+	if (gui.vimWindow->Lock()) {
+		gui.vimWindow->SetTitle((char *)title);
+		gui.vimWindow->Unlock();
+	}
+}
+
+/*
+ * Draw a cursor without focus.
+ */
+	void
+gui_mch_draw_hollow_cursor(guicolor_T color)
+{
+	gui_mch_set_fg_color(color);
+
+	BRect r;
+	r.left = FILL_X(gui.col);
+	r.top = FILL_Y(gui.row);
+	int cells = utf_off2cells(LineOffset[gui.row] + gui.col, 100); // TODO-TODO
+	if(cells>=4) cells = 1;
+	r.right = r.left + cells*gui.char_width - PEN_WIDTH;
+	r.bottom = r.top + gui.char_height - PEN_WIDTH;
+
+	if (gui.vimWindow->Lock()) {
+		gui.vimTextArea->StrokeRect(r);
+		gui.vimWindow->Unlock();
+		// gui_mch_flush();
+	}
+}
+
+/*
+ * Draw part of a cursor, only w pixels wide, and h pixels high.
+ */
+void
+gui_mch_draw_part_cursor(
+		int		w,
+		int		h,
+		guicolor_T	color)
+{
+	gui_mch_set_fg_color(color);
+
+	BRect r;
+	r.left =
+#ifdef FEAT_RIGHTLEFT
+		// vertical line should be on the right of current point
+		CURSOR_BAR_RIGHT ? FILL_X(gui.col + 1) - w :
+#endif
+		FILL_X(gui.col);
+	r.right = r.left + w - PEN_WIDTH;
+	r.bottom = FILL_Y(gui.row + 1) - PEN_WIDTH;
+	r.top = r.bottom - h + PEN_WIDTH;
+
+	if (gui.vimWindow->Lock()) {
+		gui.vimTextArea->FillRect(r);
+		gui.vimWindow->Unlock();
+		// gui_mch_flush();
+	}
+}
+
+/*
+ * Catch up with any queued events.  This may put keyboard input into the
+ * input buffer, call resize call-backs, trigger timers etc.  If there is
+ * nothing in the event queue (& no timers pending), then we return
+ * immediately.
+ */
+	void
+gui_mch_update()
+{
+	gui_mch_flush();
+	while (port_count(gui.vdcmp) > 0 &&
+			!vim_is_input_buf_full() &&
+			gui_haiku_process_event(0) >= B_OK)
+		/* nothing */ ;
+}
+
+/*
+ * GUI input routine called by gui_wait_for_chars().  Waits for a character
+ * from the keyboard.
+ *	wtime == -1		Wait forever.
+ *	wtime == 0		This should never happen.
+ *	wtime > 0		Wait wtime milliseconds for a character.
+ * Returns OK if a character was found to be available within the given time,
+ * or FAIL otherwise.
+ */
+int
+gui_mch_wait_for_chars(
+		int		wtime)
+{
+	int		    focus;
+	bigtime_t	    until, timeout;
+	status_t	    st;
+
+	if (wtime >= 0) {
+		timeout = wtime * 1000;
+		until = system_time() + timeout;
+	} else {
+		timeout = B_INFINITE_TIMEOUT;
+	}
+
+	focus = gui.in_focus;
+	for (;;)
+	{
+		// Stop or start blinking when focus changes
+		if (gui.in_focus != focus)
+		{
+			if (gui.in_focus)
+				gui_mch_start_blink();
+			else
+				gui_mch_stop_blink();
+			focus = gui.in_focus;
+		}
+
+		gui_mch_flush();
+		/*
+		 * Don't use gui_mch_update() because then we will spin-lock until a
+		 * char arrives, instead we use gui_haiku_process_event() to hang until
+		 * an event arrives.  No need to check for input_buf_full because we
+		 * are returning as soon as it contains a single char.
+		 */
+		st = gui_haiku_process_event(timeout);
+
+		if (input_available())
+			return OK;
+		if (st < B_OK)		    // includes B_TIMED_OUT
+			return FAIL;
+
+		/*
+		 * Calculate how much longer we're willing to wait for the
+		 * next event.
+		 */
+		if (wtime >= 0) {
+			timeout = until - system_time();
+			if (timeout < 0)
+				break;
+		}
+	}
+	return FAIL;
+
+}
+
+/*
+ * Output routines.
+ */
+
+/*
+ * Flush any output to the screen. This is typically called before
+ * the app goes to sleep.
+ */
+	void
+gui_mch_flush()
+{
+	//  does this need to lock the window? Apparently not but be safe.
+	if (gui.vimWindow->Lock()) {
+		gui.vimWindow->Flush();
+		gui.vimWindow->Unlock();
+	}
+	return;
+}
+
+/*
+ * Clear a rectangular region of the screen from text pos (row1, col1) to
+ * (row2, col2) inclusive.
+ */
+void
+gui_mch_clear_block(
+		int		row1,
+		int		col1,
+		int		row2,
+		int		col2)
+{
+	if (gui.vimWindow->Lock()) {
+		gui.vimTextArea->mchClearBlock(row1, col1, row2, col2);
+		gui.vimWindow->Unlock();
+	}
+}
+
+	void
+gui_mch_clear_all()
+{
+	if (gui.vimWindow->Lock()) {
+		gui.vimTextArea->mchClearAll();
+		gui.vimWindow->Unlock();
+	}
+}
+
+/*
+ * Delete the given number of lines from the given row, scrolling up any
+ * text further down within the scroll region.
+ */
+void
+gui_mch_delete_lines(
+		int		row,
+		int		num_lines)
+{
+	gui.vimTextArea->mchDeleteLines(row, num_lines);
+}
+
+/*
+ * Insert the given number of lines before the given row, scrolling down any
+ * following text within the scroll region.
+ */
+void
+gui_mch_insert_lines(
+		int		row,
+		int		num_lines)
+{
+	gui.vimTextArea->mchInsertLines(row, num_lines);
+}
+
+#if defined(FEAT_MENU) || defined(PROTO)
+/*
+ * Menu stuff.
+ */
+
+void
+gui_mch_enable_menu(
+		int		flag)
+{
+	if (gui.vimWindow->Lock())
+	{
+		BMenuBar *menubar = gui.vimForm->MenuBar();
+		menubar->SetEnabled(flag);
+		gui.vimWindow->Unlock();
+	}
+}
+
+void
+gui_mch_set_menu_pos(
+		int		x,
+		int		y,
+		int		w,
+		int		h)
+{
+	// It will be in the right place anyway
+}
+
+/*
+ * Add a sub menu to the menu bar.
+ */
+void
+gui_mch_add_menu(
+		vimmenu_T	*menu,
+		int		idx)
+{
+	vimmenu_T	*parent = menu->parent;
+
+	//  popup menu - just create it unattached
+	if (menu_is_popup(menu->name) && parent == NULL) {
+		BPopUpMenu* popUpMenu = new BPopUpMenu((const char*)menu->name, false, false);
+		menu->submenu_id = popUpMenu;
+		menu->id = NULL;
+		return;
+	}
+
+	if (!menu_is_menubar(menu->name)
+			|| (parent != NULL && parent->submenu_id == NULL))
+		return;
+
+	if (gui.vimWindow->Lock())
+	{
+		// Major re-write of the menu code, it was failing with memory corruption when
+		// we started loading multiple files (the Buffer menu)
+		//
+		// Note we don't use the preference values yet, all are inserted into the
+		// menubar on a first come-first served basis...
+		//
+		// richard@whitequeen.com jul 99
+
+		BMenu *tmp;
+
+		if ( parent )
+			tmp = parent->submenu_id;
+		else
+			tmp = gui.vimForm->MenuBar();
+		//  make sure we don't try and add the same menu twice. The Buffers menu tries to
+		//  do this and Be starts to crash...
+
+		if ( ! tmp->FindItem((const char *) menu->dname)) {
+
+			BMenu *bmenu = new BMenu((char *)menu->dname);
+
+			menu->submenu_id = bmenu;
+
+			//  when we add a BMenu to another Menu, it creates the interconnecting BMenuItem
+			tmp->AddItem(bmenu);
+
+			//  Now its safe to query the menu for the associated MenuItem....
+			menu->id = tmp->FindItem((const char *) menu->dname);
+
+		}
+		gui.vimWindow->Unlock();
+	}
+}
+
+	void
+gui_mch_toggle_tearoffs(int enable)
+{
+	// no tearoff menus
+}
+
+	static BMessage *
+MenuMessage(vimmenu_T *menu)
+{
+	BMessage *m = new BMessage('menu');
+	m->AddPointer("VimMenu", (void *)menu);
+
+	return m;
+}
+
+/*
+ * Add a menu item to a menu
+ */
+void
+gui_mch_add_menu_item(
+		vimmenu_T	*menu,
+		int		idx)
+{
+	int		mnemonic = 0;
+	vimmenu_T	*parent = menu->parent;
+
+	// TODO: use menu->actext
+	// This is difficult, since on Be, an accelerator must be a single char
+	// and a lot of Vim ones are the standard VI commands.
+	//
+	// Punt for Now...
+	// richard@whiequeen.com jul 99
+	if (gui.vimWindow->Lock())
+	{
+#ifdef FEAT_TOOLBAR
+		if(menu_is_toolbar(parent->name)) {
+			VimToolbar *toolbar = gui.vimForm->ToolBar();
+			if(toolbar != NULL) {
+				toolbar->AddButton(idx, menu);
+			}
+		} else
+#endif
+
+		if (parent->submenu_id != NULL || menu_is_popup(parent->name)) {
+			if (menu_is_separator(menu->name)) {
+				BSeparatorItem *item = new BSeparatorItem();
+				parent->submenu_id->AddItem(item);
+				menu->id = item;
+				menu->submenu_id = NULL;
+			}
+			else {
+				BMenuItem *item = new BMenuItem((char *)menu->dname,
+						MenuMessage(menu));
+				item->SetTarget(gui.vimTextArea);
+				item->SetTrigger((char) menu->mnemonic);
+				parent->submenu_id->AddItem(item);
+				menu->id = item;
+				menu->submenu_id = NULL;
+			}
+		}
+		gui.vimWindow->Unlock();
+	}
+}
+
+/*
+ * Destroy the machine specific menu widget.
+ */
+void
+gui_mch_destroy_menu(
+		vimmenu_T	*menu)
+{
+	if (gui.vimWindow->Lock())
+	{
+#ifdef FEAT_TOOLBAR
+		if(menu->parent && menu_is_toolbar(menu->parent->name)) {
+			VimToolbar *toolbar = gui.vimForm->ToolBar();
+			if(toolbar != NULL) {
+				toolbar->RemoveButton(menu);
+			}
+		} else
+#endif
+		{
+			assert(menu->submenu_id == NULL || menu->submenu_id->CountItems() == 0);
+			/*
+			 * Detach this menu from its parent, so that it is not deleted
+			 * twice once we get to delete that parent.
+			 * Deleting a BMenuItem also deletes the associated BMenu, if any
+			 * (which does not have any items anymore since they were
+			 * removed and deleted before).
+			 */
+			BMenu *bmenu = menu->id->Menu();
+			if (bmenu)
+			{
+				bmenu->RemoveItem(menu->id);
+				/*
+				 * If we removed the last item from the menu bar,
+				 * resize it out of sight.
+				 */
+				if (bmenu == gui.vimForm->MenuBar() && bmenu->CountItems() == 0)
+				{
+					bmenu->ResizeTo(-MENUBAR_MARGIN, -MENUBAR_MARGIN);
+				}
+			}
+			delete menu->id;
+			menu->id = NULL;
+			menu->submenu_id = NULL;
+
+			gui.menu_height = (int) gui.vimForm->MenuHeight();
+		}
+		gui.vimWindow->Unlock();
+	}
+}
+
+/*
+ * Make a menu either grey or not grey.
+ */
+void
+gui_mch_menu_grey(
+		vimmenu_T	*menu,
+		int		grey)
+{
+#ifdef FEAT_TOOLBAR
+	if(menu->parent && menu_is_toolbar(menu->parent->name)) {
+		if (gui.vimWindow->Lock()) {
+			VimToolbar *toolbar = gui.vimForm->ToolBar();
+			if(toolbar != NULL) {
+				toolbar->GrayButton(menu, grey);
+			}
+			gui.vimWindow->Unlock();
+		}
+	} else
+#endif
+	if (menu->id != NULL)
+		menu->id->SetEnabled(!grey);
+}
+
+/*
+ * Make menu item hidden or not hidden
+ */
+void
+gui_mch_menu_hidden(
+		vimmenu_T	*menu,
+		int		hidden)
+{
+	if (menu->id != NULL)
+		menu->id->SetEnabled(!hidden);
+}
+
+/*
+ * This is called after setting all the menus to grey/hidden or not.
+ */
+	void
+gui_mch_draw_menubar()
+{
+	// Nothing to do in BeOS
+}
+
+	void
+gui_mch_show_popupmenu(vimmenu_T *menu)
+{
+	if (!menu_is_popup(menu->name) || menu->submenu_id == NULL)
+		return;
+
+	BPopUpMenu* popupMenu = dynamic_cast<BPopUpMenu*>(menu->submenu_id);
+	if (popupMenu == NULL)
+		return;
+
+	BPoint point;
+	if(gui.vimWindow->Lock()) {
+		uint32 buttons = 0;
+		gui.vimTextArea->GetMouse(&point, &buttons);
+		gui.vimTextArea->ConvertToScreen(&point);
+		gui.vimWindow->Unlock();
+	}
+	popupMenu->Go(point, true);
+}
+
+#endif // FEAT_MENU
+
+// Mouse stuff
+
+#ifdef FEAT_CLIPBOARD
+/*
+ * Clipboard stuff, for cutting and pasting text to other windows.
+ */
+char textplain[] = "text/plain";
+char vimselectiontype[] = "application/x-vnd.Rhialto-Vim-selectiontype";
+
+/*
+ * Get the current selection and put it in the clipboard register.
+ */
+	void
+clip_mch_request_selection(Clipboard_T *cbd)
+{
+	if (be_clipboard->Lock())
+	{
+		BMessage *m = be_clipboard->Data();
+		// m->PrintToStream();
+
+		char_u *string = NULL;
+		ssize_t stringlen = -1;
+
+		if (m->FindData(textplain, B_MIME_TYPE,
+					(const void **)&string, &stringlen) == B_OK
+				|| m->FindString("text", (const char **)&string) == B_OK)
+		{
+			if (stringlen == -1)
+				stringlen = STRLEN(string);
+
+			int type;
+			char *seltype;
+			ssize_t seltypelen;
+
+			/*
+			 * Try to get the special vim selection type first
+			 */
+			if (m->FindData(vimselectiontype, B_MIME_TYPE,
+						(const void **)&seltype, &seltypelen) == B_OK)
+			{
+				switch (*seltype)
+				{
+					default:
+					case 'L':	type = MLINE;	break;
+					case 'C':	type = MCHAR;	break;
+#ifdef FEAT_VISUAL
+					case 'B':	type = MBLOCK;	break;
+#endif
+				}
+			}
+			else
+			{
+				// Otherwise use heuristic as documented
+				type = memchr(string, stringlen, '\n') ? MLINE : MCHAR;
+			}
+			clip_yank_selection(type, string, (long)stringlen, cbd);
+		}
+		be_clipboard->Unlock();
+	}
+}
+/*
+ * Make vim the owner of the current selection.
+ */
+	void
+clip_mch_lose_selection(Clipboard_T *cbd)
+{
+	// Nothing needs to be done here
+}
+
+/*
+ * Make vim the owner of the current selection.  Return OK upon success.
+ */
+	int
+clip_mch_own_selection(Clipboard_T *cbd)
+{
+	/*
+	 * Never actually own the clipboard.  If another application sets the
+	 * clipboard, we don't want to think that we still own it.
+	 */
+	return FAIL;
+}
+
+/*
+ * Send the current selection to the clipboard.
+ */
+	void
+clip_mch_set_selection(Clipboard_T *cbd)
+{
+	if (be_clipboard->Lock())
+	{
+		be_clipboard->Clear();
+		BMessage *m = be_clipboard->Data();
+		assert(m);
+
+		// If the '*' register isn't already filled in, fill it in now
+		cbd->owned = TRUE;
+		clip_get_selection(cbd);
+		cbd->owned = FALSE;
+
+		char_u  *str = NULL;
+		long_u  count;
+		int	type;
+
+		type = clip_convert_selection(&str, &count, cbd);
+
+		if (type < 0)
+			return;
+
+		m->AddData(textplain, B_MIME_TYPE, (void *)str, count);
+
+		// Add type of selection
+		char    vtype;
+		switch (type)
+		{
+			default:
+			case MLINE:    vtype = 'L';    break;
+			case MCHAR:    vtype = 'C';    break;
+#ifdef FEAT_VISUAL
+			case MBLOCK:   vtype = 'B';    break;
+#endif
+		}
+		m->AddData(vimselectiontype, B_MIME_TYPE, (void *)&vtype, 1);
+
+		vim_free(str);
+
+		be_clipboard->Commit();
+		be_clipboard->Unlock();
+	}
+}
+
+#endif	// FEAT_CLIPBOARD
+
+#ifdef FEAT_BROWSE
+/*
+ * Pop open a file browser and return the file selected, in allocated memory,
+ * or NULL if Cancel is hit.
+ *  saving  - TRUE if the file will be saved to, FALSE if it will be opened.
+ *  title   - Title message for the file browser dialog.
+ *  dflt    - Default name of file.
+ *  ext     - Default extension to be added to files without extensions.
+ *  initdir - directory in which to open the browser (NULL = current dir)
+ *  filter  - Filter for matched files to choose from.
+ *  Has a format like this:
+ *  "C Files (*.c)\0*.c\0"
+ *  "All Files\0*.*\0\0"
+ *  If these two strings were concatenated, then a choice of two file
+ *  filters will be selectable to the user.  Then only matching files will
+ *  be shown in the browser.  If NULL, the default allows all files.
+ *
+ *  *NOTE* - the filter string must be terminated with TWO nulls.
+ */
+char_u *
+gui_mch_browse(
+		int saving,
+		char_u *title,
+		char_u *dflt,
+		char_u *ext,
+		char_u *initdir,
+		char_u *filter)
+{
+	gui.vimApp->fFilePanel = new BFilePanel((saving == TRUE) ? B_SAVE_PANEL : B_OPEN_PANEL,
+			NULL, NULL, 0, false,
+			new BMessage((saving == TRUE) ? 'save' : 'open'), NULL, true);
+
+	gui.vimApp->fBrowsedPath.Unset();
+
+	gui.vimApp->fFilePanel->Window()->SetTitle((char*)title);
+	gui.vimApp->fFilePanel->SetPanelDirectory((const char*)initdir);
+
+	gui.vimApp->fFilePanel->Show();
+
+	gui.vimApp->fFilePanelSem = create_sem(0, "FilePanelSem");
+
+	while(acquire_sem(gui.vimApp->fFilePanelSem) == B_INTERRUPTED);
+
+	char_u *fileName = NULL;
+	status_t result = gui.vimApp->fBrowsedPath.InitCheck();
+	if(result == B_OK) {
+		fileName = vim_strsave((char_u*)gui.vimApp->fBrowsedPath.Path());
+	} else
+		if(result != B_NO_INIT) {
+			fprintf(stderr, "gui_mch_browse: BPath error: %#08x (%s)\n",
+					result, strerror(result));
+		}
+
+	delete gui.vimApp->fFilePanel;
+	gui.vimApp->fFilePanel = NULL;
+
+	return fileName;
+}
+#endif // FEAT_BROWSE
+
+
+#if defined(FEAT_GUI_DIALOG)
+
+/*
+ * Create a dialog dynamically from the parameter strings.
+ * type		= type of dialog (question, alert, etc.)
+ * title	= dialog title. may be NULL for default title.
+ * message	= text to display. Dialog sizes to accommodate it.
+ * buttons	= '\n' separated list of button captions, default first.
+ * dfltbutton	= number of default button.
+ *
+ * This routine returns 1 if the first button is pressed,
+ *			2 for the second, etc.
+ *
+ *			0 indicates Esc was pressed.
+ *			-1 for unexpected error
+ *
+ * If stubbing out this fn, return 1.
+ */
+
+int
+gui_mch_dialog(
+		int		 type,
+		char_u	*title,
+		char_u	*message,
+		char_u	*buttons,
+		int		 dfltbutton,
+		char_u	*textfield,
+		int ex_cmd)
+{
+	VimDialog *dialog = new VimDialog(type, (char*)title, (char*)message,
+			(char*)buttons, dfltbutton, (char*)textfield, ex_cmd);
+	return dialog->Go();
+}
+
+#endif // FEAT_GUI_DIALOG
+
+
+/*
+ * Return the RGB value of a pixel as long.
+ */
+    guicolor_T
+gui_mch_get_rgb(guicolor_T pixel)
+{
+	rgb_color rgb = GUI_TO_RGB(pixel);
+
+	return ((rgb.red & 0xff) << 16) + ((rgb.green & 0xff) << 8)
+		+ (rgb.blue & 0xff);
+}
+
+	void
+gui_mch_setmouse(int x, int y)
+{
+	TRACE();
+	// TODO
+}
+
+#ifdef FEAT_MBYTE_IME
+	void
+im_set_position(int row, int col)
+{
+	if(gui.vimWindow->Lock())
+	{
+		gui.vimTextArea->DrawIMString();
+		gui.vimWindow->Unlock();
+	}
+	return;
+}
+#endif
+
+	void
+gui_mch_show_toolbar(int showit)
+{
+	VimToolbar *toolbar = gui.vimForm->ToolBar();
+	gui.toolbar_height = (toolbar && showit) ? toolbar->ToolbarHeight() : 0.;
+}
+
+	void
+gui_mch_set_toolbar_pos(int x, int y, int w, int h)
+{
+	VimToolbar *toolbar = gui.vimForm->ToolBar();
+	if(toolbar != NULL) {
+		if (gui.vimWindow->Lock()) {
+			toolbar->MoveTo(x, y);
+			toolbar->ResizeTo(w - 1, h - 1);
+			gui.vimWindow->Unlock();
+		}
+	}
+}
+
+#if defined(FEAT_GUI_TABLINE) || defined(PROTO)
+
+/*
+ * Show or hide the tabline.
+ */
+    void
+gui_mch_show_tabline(int showit)
+{
+	VimTabLine *tabLine = gui.vimForm->TabLine();
+
+    if (tabLine == NULL)
+		return;
+
+    if (!showit != !gui.vimForm->IsShowingTabLine()) {
+		gui.vimForm->SetShowingTabLine(showit != 0);
+		gui.tabline_height = gui.vimForm->TablineHeight();
+    }
+}
+
+	void
+gui_mch_set_tabline_pos(int x, int y, int w, int h)
+{
+	VimTabLine *tabLine = gui.vimForm->TabLine();
+	if(tabLine != NULL) {
+		if (gui.vimWindow->Lock()) {
+			tabLine->MoveTo(x, y);
+			tabLine->ResizeTo(w - 1, h - 1);
+			gui.vimWindow->Unlock();
+		}
+	}
+}
+
+/*
+ * Return TRUE when tabline is displayed.
+ */
+    int
+gui_mch_showing_tabline()
+{
+	VimTabLine *tabLine = gui.vimForm->TabLine();
+    return tabLine != NULL && gui.vimForm->IsShowingTabLine();
+}
+
+/*
+ * Update the labels of the tabline.
+ */
+    void
+gui_mch_update_tabline()
+{
+    tabpage_T	*tp;
+    int		nr = 0;
+    int		curtabidx = 0;
+
+	VimTabLine *tabLine = gui.vimForm->TabLine();
+
+    if (tabLine == NULL)
+		return;
+
+	gui.vimWindow->Lock();
+
+    // Add a label for each tab page.  They all contain the same text area.
+    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, ++nr) {
+		if (tp == curtab)
+		    curtabidx = nr;
+
+		BTab* tab = tabLine->TabAt(nr);
+
+		if (tab == NULL) {
+			tab = new VimTabLine::VimTab();
+			tabLine->AddTab(NULL, tab);
+		}
+
+		get_tabline_label(tp, FALSE);
+		tab->SetLabel((const char*)NameBuff);
+		tabLine->Invalidate();
+    }
+
+    // Remove any old labels.
+	while (nr < tabLine->CountTabs())
+		tabLine->RemoveTab(nr);
+
+	if(tabLine->Selection() != curtabidx)
+		tabLine->Select(curtabidx);
+
+	gui.vimWindow->Unlock();
+}
+
+/*
+ * Set the current tab to "nr".  First tab is 1.
+ */
+    void
+gui_mch_set_curtab(int nr)
+{
+	VimTabLine *tabLine = gui.vimForm->TabLine();
+	if(tabLine == NULL)
+		return;
+
+	gui.vimWindow->Lock();
+
+	if(tabLine->Selection() != nr -1)
+		tabLine->Select(nr -1);
+
+	gui.vimWindow->Unlock();
+}
+
+#endif // FEAT_GUI_TABLINE
