diff --git a/src/gui_beos.cc b/src/gui_beos.cc
new file mode 100644
index 0000000..e2c6598
--- /dev/null
+++ b/src/gui_beos.cc
@@ -0,0 +1,3347 @@
+/* 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.
+ *
+ * BeOS GUI.
+ *
+ * GUI support for the Buzzword Enhanced Operating System.
+ *
+ * Ported to R4 by Richard Offer <richard@whitequeen.com> Jul 99
+ *
+ */
+
+/*
+ * Structure of the BeOS 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" {
+
+#define new		xxx_new_xxx
+
+#include <float.h>
+#include <assert.h>
+#include "vim.h"
+#include "globals.h"
+#include "proto.h"
+#include "option.h"
+
+#undef new
+
+}	/* extern "C" */
+
+/* ---------------- start of header part ---------------- */
+
+#include <be/app/MessageQueue.h>
+#include <be/app/Clipboard.h>
+#include <be/kernel/OS.h>
+#include <be/support/Beep.h>
+#include <be/interface/View.h>
+#include <be/interface/Window.h>
+#include <be/interface/MenuBar.h>
+#include <be/interface/MenuItem.h>
+#include <be/interface/ScrollBar.h>
+#include <be/interface/Region.h>
+#include <be/interface/Screen.h>
+#include <be/storage/Path.h>
+#include <be/storage/Directory.h>
+#include <be/storage/Entry.h>
+#include <be/app/Application.h>
+#include <be/support/Debug.h>
+
+/*
+ * The macro B_PIXEL_ALIGNMENT shows us which version
+ * of the header files we're using.
+ */
+#if defined(B_PIXEL_ALIGNMENT)
+#define HAVE_R3_OR_LATER    1
+#else
+#define HAVE_R3_OR_LATER    0
+#endif
+
+class VimApp;
+class VimFormView;
+class VimTextAreaView;
+class VimWindow;
+
+extern key_map *keyMap;
+extern char *keyMapChars;
+
+extern int main(int argc, char **argv);
+
+#ifndef B_MAX_PORT_COUNT
+#define B_MAX_PORT_COUNT    100
+#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();
+
+    static void SendRefs(BMessage *m, bool changedir);
+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;
+};
+
+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 guiBlankMouse(bool should_hide);
+    static int_u mouseModifiersToVim(int32 beModifiers);
+
+    int32 mouseDragEventCount;
+
+private:
+    void init(BRect);
+
+    int_u	    vimMouseButton;
+    int_u	    vimMouseModifiers;
+};
+
+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;
+};
+
+
+/*
+ * 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();
+};
+
+/* ---------------- 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 */
+};
+
+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 VimFocusMsg {
+    bool	active;
+};
+
+struct VimRefsMsg {
+    BMessage   *message;
+    bool	changedir;
+};
+
+struct VimMsg {
+    enum VimMsgType {
+	Key, Resize, ScrollBar, Menu, Mouse, Focus, Refs
+    };
+
+    union {
+	struct VimKeyMsg	Key;
+	struct VimResizeMsg	NewSize;
+	struct VimScrollBarMsg	Scroll;
+	struct VimMenuMsg	Menu;
+	struct VimMouseMsg	Mouse;
+	struct VimFocusMsg	Focus;
+	struct VimRefsMsg	Refs;
+    } 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(path.Path());
+    /* Do this to get the side effects of a :cd command */
+    do_cmdline_cmd((char_u *)"cd .");
+}
+
+/*
+ * 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);
+
+	/* Update the screen display */
+	update_screen(NOT_VALID);
+	setcursor();
+	out_flush();
+    } else {
+	vim_free(fnames);
+    }
+}
+
+VimApp::VimApp(const char *appsig):
+    BApplication(appsig)
+{
+}
+
+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
+}
+
+    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);
+    }
+}
+
+    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);
+    }
+}
+
+    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);
+
+    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),
+    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
+    }
+    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);
+
+    BRect remaining = frame;
+    textArea = new VimTextAreaView(remaining);
+    AddChild(textArea);
+    /* The textArea will be resized later when menus are added */
+
+    gui.vimForm = this;
+}
+
+    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();
+	remaining.top = MenuHeight();
+	textArea->ResizeTo(remaining.Width(), remaining.Height());
+	textArea->MoveTo(remaining.left, remaining.top);
+
+#ifdef FEAT_MENU
+	menuBar->ResizeTo(remaining.right, remaining.top);
+	gui.menu_height = (int) remaining.top;
+#endif
+    }
+    Inherited::AllAttached();
+}
+
+    void
+VimFormView::FrameResized(float new_width, float new_height)
+{
+    BWindow *w = Window();
+#if 1
+    /*
+     * Look if there are more resize messages in the queue.
+     * If so, ignore this one. The later one will be handled
+     * eventually.
+     */
+    BMessageQueue *q = w->MessageQueue();
+    if (q->FindMessage(B_VIEW_RESIZED, 0) != NULL) {
+	return;
+    }
+#endif
+    new_width += 1;	    // adjust from width to number of pixels occupied
+    new_height += 1;
+
+#if !HAVE_R3_OR_LATER
+    int adjust_h, adjust_w;
+
+    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) {
+	/*
+	 * This will generate a new FrameResized() message.
+	 * If we're running R3 or later, SetWindowAlignment() should make
+	 * sure that this does not happen.
+	 */
+	w->ResizeBy(-adjust_w, -adjust_h);
+
+	return;
+    }
+#endif
+
+    struct VimResizeMsg sm;
+    sm.width = (int) new_width;
+    sm.height = (int) new_height;
+
+    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,
+	    B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
+    mouseDragEventCount(0)
+{
+    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);
+}
+
+    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.
+     */
+    gui_redraw((int) updateRect.left, (int) updateRect.top,
+	    (int) (updateRect.Width() + PEN_WIDTH), (int) (updateRect.Height() + PEN_WIDTH));
+
+    /* Clear the border areas if needed */
+    rgb_color rgb = GUI_TO_RGB(gui.back_pixel);
+    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);
+}
+
+    void
+VimTextAreaView::KeyDown(const char *bytes, int32 numBytes)
+{
+    struct VimKeyMsg km;
+    char_u *dest = km.chars;
+
+    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);
+    } 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;
+
+	bool canHaveVimModifiers = false;
+
+	/*
+	 * 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;
+    }
+
+    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::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" */
+	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;
+    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, 0);
+
+    gui.norm_font = (GuiFont)newFont;
+    gui_mch_set_font((GuiFont)newFont);
+    if (name)
+	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;
+}
+
+    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)) {
+	BRect r(FILL_X(col), FILL_Y(row),
+		FILL_X(col + len) - PEN_WIDTH, FILL_Y(row + 1) - PEN_WIDTH);
+	FillRect(r, B_SOLID_LOW);
+    }
+    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) {
+	BPoint start(FILL_X(col), FILL_Y(row + 1) - PEN_WIDTH);
+	BPoint end(FILL_X(col + len) - 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)
+{
+    if (row + num_lines > gui.scroll_region_bot)
+    {
+	/* Scrolled out of region, just blank the lines out */
+	gui_clear_block(row, gui.scroll_region_left,
+		gui.scroll_region_bot, gui.scroll_region_right);
+    }
+    else
+    {
+	/* copy one extra pixel, for when bold has spilled over */
+	int width = gui.char_width * (gui.scroll_region_right
+				- gui.scroll_region_left + 1) + 1 - PEN_WIDTH;
+	int height = gui.char_height *
+		     (gui.scroll_region_bot - row - num_lines + 1) - PEN_WIDTH;
+
+	BRect source, dest;
+
+	source.left = FILL_X(gui.scroll_region_left);
+	source.top = FILL_Y(row + num_lines);
+	source.right = source.left + width;
+	source.bottom = source.top + height;
+
+	dest.left = FILL_X(gui.scroll_region_left);
+	dest.top = FILL_Y(row);
+	dest.right = dest.left + width;
+	dest.bottom = dest.top + height;
+
+	/* XXX Attempt at a hack: */
+	gui.vimWindow->UpdateIfNeeded();
+#if 0
+	/* XXX Attempt at a hack: */
+	if (gui.vimWindow->NeedsUpdate()) {
+	    fprintf(stderr, "mchDeleteLines: NeedsUpdate!\n");
+	    gui.vimWindow->UpdateIfNeeded();
+	    while (gui.vimWindow->NeedsUpdate()) {
+		if (false && gui.vimWindow->Lock()) {
+		    Sync();
+		    gui.vimWindow->Unlock();
+		}
+		snooze(2);
+	    }
+	}
+#endif
+
+	if (gui.vimWindow->Lock()) {
+	    Sync();
+	    CopyBits(source, dest);
+	    //Sync();
+
+	    /* Update gui.cursor_row if the cursor scrolled or copied over */
+	    if (gui.cursor_row >= row
+		&& gui.cursor_col >= gui.scroll_region_left
+		&& gui.cursor_col <= gui.scroll_region_right)
+	    {
+		if (gui.cursor_row < row + num_lines)
+		    gui.cursor_is_valid = FALSE;
+		else if (gui.cursor_row <= gui.scroll_region_bot)
+		    gui.cursor_row -= num_lines;
+	    }
+
+	    /* Clear one column more for when bold has spilled over */
+	    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)
+{
+    if (row + num_lines > gui.scroll_region_bot)
+    {
+	/* Scrolled out of region, just blank the lines out */
+	gui_clear_block(row, gui.scroll_region_left,
+		gui.scroll_region_bot, gui.scroll_region_right);
+    }
+    else
+    {
+	/* copy one extra pixel, for when bold has spilled over */
+	int width = gui.char_width * (gui.scroll_region_right
+				- gui.scroll_region_left + 1) + 1 - PEN_WIDTH;
+	int height = gui.char_height *
+		     (gui.scroll_region_bot - row - num_lines + 1) - PEN_WIDTH;
+
+	BRect source, dest;
+
+	source.left = FILL_X(gui.scroll_region_left);
+	source.top = FILL_Y(row);
+	source.right = source.left + width;
+	source.bottom = source.top + height;
+
+	dest.left = FILL_X(gui.scroll_region_left);
+	dest.top = FILL_Y(row + num_lines);
+	dest.right = dest.left + width;
+	dest.bottom = dest.top + height;
+
+	/* XXX Attempt at a hack: */
+	gui.vimWindow->UpdateIfNeeded();
+#if 0
+	/* XXX Attempt at a hack: */
+	if (gui.vimWindow->NeedsUpdate())
+	    fprintf(stderr, "mchInsertLines: NeedsUpdate!\n");
+	gui.vimWindow->UpdateIfNeeded();
+	while (gui.vimWindow->NeedsUpdate())
+	    snooze(2);
+#endif
+
+	if (gui.vimWindow->Lock()) {
+	    Sync();
+	    CopyBits(source, dest);
+	    //Sync();
+
+	    /* Update gui.cursor_row if the cursor scrolled or copied over */
+	    if (gui.cursor_row >= gui.row
+		&& gui.cursor_col >= gui.scroll_region_left
+		&& gui.cursor_col <= gui.scroll_region_right)
+	    {
+		if (gui.cursor_row <= gui.scroll_region_bot - num_lines)
+		    gui.cursor_row += num_lines;
+		else if (gui.cursor_row <= gui.scroll_region_bot)
+		    gui.cursor_is_valid = FALSE;
+	    }
+	    /* Clear one column more for when bold has spilled over */
+	    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();
+	}
+    }
+
+}
+
+/* ---------------- 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;
+}
+
+/* ---------------- ---------------- */
+
+// some global variables
+static char appsig[] = "application/x-vnd.Rhialto-Vim-5";
+key_map *keyMap;
+char *keyMapChars;
+int main_exitcode = 127;
+
+    status_t
+gui_beos_process_event(bigtime_t timeout)
+{
+    struct VimMsg vm;
+    long 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;
+		}
+		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;
+	case VimMsg::Menu:
+	    gui_menu_cb(vm.u.Menu.guiMenu);
+	    break;
+	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::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;
+	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
+
+extern "C" {
+
+/*
+ * 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()
+{
+    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();
+
+#if USE_THREAD_FOR_INPUT_WITH_TIMEOUT
+	/* Kill the thread that may have been created for the Terminal */
+	beos_cleanup_read_thread();
+#endif
+
+	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)
+{
+    /* TODO */
+    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)
+{
+    /* TODO */
+}
+
+/*
+ * 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)
+{
+    /*
+     * 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);
+
+#if HAVE_R3_OR_LATER
+	/*
+	 * Set the resizing alignment depending on font size.
+	 * XXX This is untested, since I don't have R3 yet.
+	 */
+	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
+	);
+#else
+	/* don't know what to do with base_{width,height}. */
+#endif
+
+	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);
+	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()) {
+	VimScrollBar *vsb = sb->id;
+	vsb->MoveTo(x, y);
+	vsb->ResizeTo(w - PEN_WIDTH, h - PEN_WIDTH);
+	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 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;
+}
+
+    GuiFont
+gui_mch_get_font(
+    char_u		*name,
+    int			giveErrorIfMissing)
+{
+    VimFont		*font = 0;
+    static VimFont *fontList = NULL;
+
+    if (!gui.in_use)		    /* can't do this when GUI not running */
+	return NOFONT;
+
+    if (!name)
+	name = (char_u *)"be_fixed_font";
+
+    VimFont *flp;
+    for (flp = fontList; flp; flp = flp->next) {
+	if (STRCMP(name, flp->name) == 0) {
+	    flp->refcount++;
+	    return (GuiFont)flp;
+	}
+    }
+
+    font = new VimFont(be_fixed_font);
+
+    /* Set some universal features: */
+    font->SetSpacing(B_FIXED_SPACING);
+    font->SetEncoding(B_ISO_8859_1);
+
+    /* Remember font for later use */
+    font->name = vim_strsave(name);
+    font->next = fontList;
+    fontList = font;
+
+    font_family family;
+    font_style style;
+    int size;
+    int len;
+    char_u *end;
+
+#ifdef never
+    // This leads to SEGV/BUS on R4+
+    // Replace underscores with spaces, and I can't see why ?
+    // richard@whitequeen.com jul 99
+    while (end = (char_u *)strchr((char *)name, '_'))
+	*end = ' ';
+#endif
+    /*
+     *  Parse font names as Family/Style/Size.
+     *  On errors, just keep the be_fixed_font.
+     */
+    end = (char_u *)strchr((char *)name, '/');
+    if (!end)
+	goto error;
+    strncpy(family, (char *)name, len = end - name);
+    family[len] = '\0';
+
+    name = end + 1;
+    end = (char_u *)strchr((char *)name, '/');
+    if (!end)
+	goto error;
+    strncpy(style, (char *)name, len = end - name);
+    style[len] = '\0';
+
+    name = end + 1;
+    size = atoi((char *)name);
+    if (size <= 0)
+	goto error;
+
+    font->SetFamilyAndStyle(family, style);
+    font->SetSize(size);
+    font->SetSpacing(B_FIXED_SPACING);
+    font->SetEncoding(B_ISO_8859_1);
+    //font->PrintToStream();
+
+    return (GuiFont)font;
+
+error:
+    if (giveErrorIfMissing)
+	EMSG2("(fe0) Unknown font: %s", name);
+
+    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();
+    }
+}
+
+#if 0 /* not used */
+/*
+ * Return TRUE if the two fonts given are equivalent.
+ */
+    int
+gui_mch_same_font(
+    GuiFont	f1,
+    GuiFont	f2)
+{
+    VimFont *vf1 = (VimFont *)f1;
+    VimFont *vf2 = (VimFont *)f2;
+
+    return f1 == f2 ||
+	    (vf1->FamilyAndStyle() == vf2->FamilyAndStyle() &&
+	     vf1->Size() == vf2->Size());
+}
+#endif
+
+/* XXX TODO This is apparently never called... */
+    void
+gui_mch_free_font(
+    GuiFont	font)
+{
+    VimFont *f = (VimFont *)font;
+    if (--f->refcount <= 0) {
+	if (f->refcount < 0)
+	    fprintf(stderr, "VimFont: refcount < 0\n");
+	delete f;
+    }
+}
+
+    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
+    {
+	char	    *name;
+	guicolor_T     colour;
+    } GuiColourTable;
+
+#define NSTATIC_COLOURS		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)},
+	{"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)},
+    };
+
+    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 "$VIM/rgb.txt".
+     */
+    {
+#define LINE_LEN 100
+	FILE	*fd;
+	char	line[LINE_LEN];
+	char_u	*fname;
+
+	fname = expand_env_save((char_u *)"$VIM/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);
+
+		vim_free(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();
+    }
+}
+
+    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();
+    }
+}
+
+/*
+ * 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()
+{
+    /* 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);
+    r.right = r.left + 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_beos_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_beos_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_beos_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;
+
+    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;
+
+    if (parent->submenu_id == NULL)
+	return;
+
+#ifdef never
+    /* why not add separators ?
+     * richard
+     */
+    /* Don't add menu separator */
+    if (menu_is_separator(menu->name))
+	return;
+#endif
+
+    /* 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())
+    {
+	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())
+    {
+	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)
+{
+    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 */
+}
+
+#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(VimClipboard *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(VimClipboard *cbd)
+{
+    /* Nothing needs to be done here */
+}
+
+/*
+ * Make vim the owner of the current selection.  Return OK upon success.
+ */
+    int
+clip_mch_own_selection(VimClipboard *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(VimClipboard *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 */
+
+/*
+ * Return the RGB value of a pixel as long.
+ */
+    long_u
+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 */
+}
+
+    void
+gui_mch_show_popupmenu(vimmenu_T *menu)
+{
+    TRACE();
+    /* TODO */
+}
+
+int
+gui_mch_get_mouse_x()
+{
+    TRACE();
+    return 0;
+}
+
+
+int
+gui_mch_get_mouse_y()
+{
+    TRACE();
+    return 0;
+}
+
+} /* extern "C" */
