updated for version 7.0001
diff --git a/src/gui_amiga.c b/src/gui_amiga.c
new file mode 100644
index 0000000..28786aa
--- /dev/null
+++ b/src/gui_amiga.c
@@ -0,0 +1,1795 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved		by Bram Moolenaar
+ *				Amiga GUI support by Michael Nielsen
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <exec/types.h>
+#include <intuition/intuition.h>
+#include <utility/tagitem.h>
+#include <graphics/text.h>
+#include <graphics/rastport.h>
+#include <graphics/layers.h>
+#include <proto/intuition.h>
+#include <proto/graphics.h>
+#include <proto/layers.h>
+#include <devices/timer.h>
+#include <assert.h>
+#include "vim.h"
+#include "gui_amiga.h"
+#include <math.h>
+#include <limits.h>
+
+#ifdef __AROS__
+#include <aros/debug.h>
+#endif
+
+#include "version.h"
+
+#if defined(FEAT_GUI_AMIGA) || defined(PROTO)
+
+#define KEYUP		76
+#define KEYDOWN		77
+#define KEYRIGHT	78
+#define KEYLEFT		79
+#define KEYBACKSPACE	0x41
+#define KEYDELETE	0x46
+#define KEYINSERT	0x47
+#define KEYHOME		0x70
+#define KEYEND		0x71
+#define KEYWHEELUP	0x7A
+#define KEYWHEELDOWN	0x7B
+
+/* When generating prototypes on Unix, these need to be defined */
+#ifdef PROTO
+# define STRPTR char *
+# define BOOL int
+# define UBYTE int
+#endif
+
+static struct PropInfo Gadget2SInfo = { AUTOKNOB+PROPBORDERLESS+FREEVERT+PROPNEWLOOK, 0, 0, MAXBODY, MAXBODY, };
+//static struct Image Image1 = { 0, 0, 10, 397,	0, NULL, 0x0000, 0x0000, NULL };
+static struct Gadget propGadget = { NULL, -12, 15, 10, -28,
+	GFLG_RELRIGHT+GFLG_RELHEIGHT,
+	GACT_RELVERIFY+GACT_RIGHTBORDER+GACT_IMMEDIATE,
+	GTYP_PROPGADGET+GTYP_GZZGADGET,
+	NULL, NULL,
+	NULL, NULL, (APTR)&Gadget2SInfo, NULL, NULL };
+
+static struct timerequest *TimerIO;
+static struct MsgPort	  *TimerMP;
+static BOOL		   TimerSent;
+
+struct GFXBase		*gfxBase;
+struct ExecBase		*execBase;
+struct LayersBase	*layersBase;
+
+struct MyColor
+{
+    WORD pen;
+    BOOL alloced;
+};
+
+struct MyColor MyColorTable[256];
+
+struct TagItem tags[] =
+{
+    {WA_Left, 0},
+    {WA_Top, 0},
+    {WA_Width, 400},
+    {WA_Height, 400},
+    {WA_Title, (ULONG)VIM_VERSION_SHORT},
+    {WA_ScreenTitle, (ULONG)VIM_VERSION_LONG},
+    {WA_DragBar, TRUE},			/* enable dragging of the window */
+    {WA_DepthGadget, TRUE},		/* enable the depth gadget */
+    {WA_CloseGadget, TRUE},		/* enable the close gadget*/
+    {WA_SizeGadget, TRUE},		/* enable the size gadget */
+    {WA_SizeBBottom, TRUE},		/* sizegadget contained in bottom border */
+    {WA_SmartRefresh, TRUE},		/* choose smart refresh, saves us doing a lot of work */
+    {WA_ReportMouse, TRUE},		/* Report the position of the mouse */
+    {WA_GimmeZeroZero, TRUE},
+    {WA_Activate, TRUE},		/* Activate window on startup */
+    {WA_Activate, TRUE},		/* Activate window on startup */
+    {WA_NoCareRefresh, TRUE},		/* Refresh screen, don't tell us */
+    {WA_NewLookMenus, TRUE},		/* use the new options for the menu */
+    {WA_AutoAdjust, TRUE},		/* If window is too big for screen adjust size*/
+    {WA_NoCareRefresh, TRUE},		/* If window is too big for screen adjust size*/
+    {WA_MouseQueue, 1},			/* Limit number of pending mouse movement*/
+    {WA_RptQueue, 10},			/* Limit number of pending keystrokes*/
+    {WA_IDCMP,				/* IDCMP, what events interest us  */
+	IDCMP_NEWSIZE			/* Notify us about size change of window*/
+	    |IDCMP_REFRESHWINDOW	/* Notify us when the window needs refreshing */
+	    |IDCMP_MOUSEBUTTONS		/* Notify us when the mouse buttons have been used */
+	    |IDCMP_MOUSEMOVE		/* Notify us when the mouse is moving */
+	    |IDCMP_GADGETDOWN		/* Notify us when a gadget has been selected */
+	    |IDCMP_GADGETUP		/* Notify us when a gadget has been released */
+	    |IDCMP_MENUPICK		/* Notify us when a menu has been picked */
+	    |IDCMP_CLOSEWINDOW		/* Notify us when the user tries to close the window */
+	    |IDCMP_VANILLAKEY		/* Notify us about keystrokes */
+	    |IDCMP_RAWKEY		/* Notify us when raw key events have been used, ie cursor*/
+	    |IDCMP_INTUITICKS		/* Simpler timer for the blink option */
+	    |IDCMP_MENUHELP		/* Allow the help key to be used during menu events */
+	    |IDCMP_GADGETHELP		/* Allow the help key to be used during gadget events */
+	    |IDCMP_INACTIVEWINDOW	/* notify of inactive window */
+	    |IDCMP_ACTIVEWINDOW		/* notify of inactive window */
+    },
+    {TAG_DONE, NULL}
+};
+
+#if defined(D)
+#undef D
+#endif
+
+/*#define D(_msg) fprintf(stderr, "%s\n", _msg)*/
+
+#define D(_A)
+#define kprintf(s, ...)
+
+static void AmigaError(const char *string);
+
+void HandleEvent(unsigned long * object);
+static UBYTE getrealcolor(guicolor_T i);
+
+static struct NewWindow vimNewWindow =
+{
+    0, 0,		/* window XY origin relative to TopLeft of screen */
+    0, 0,		/* window width and height */
+    0, 1,		/* detail and block pens */
+    NULL,		/* IDCMP flags */
+    NULL,		/* other window flags */
+    &propGadget,	/* first gadget in gadget list */
+    NULL,		/* custom CHECKMARK imagery */
+    "Amiga Vim gui",	/* window title */
+    NULL,		/* custom screen pointer */
+    NULL,		/* custom bitmap */
+    50, 50,		/* minimum width and height */
+    (unsigned short)-1, (unsigned short)-1,	/* maximum width and height */
+    WBENCHSCREEN	/* destination screen type */
+};
+
+static struct
+{
+    unsigned int  key_sym;
+    char_u  vim_code0;
+    char_u  vim_code1;
+} special_keys[] =
+{
+    {0,		    0, 0}
+};
+
+#if 0
+    /* not used? */
+    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;
+}
+#endif
+
+static int characterWidth = -1;
+static int characterHeight = -1;
+static struct
+{
+    BOOL	active;
+    enum
+    {
+	CursorOff,
+	CursorOn,
+	CursorWait
+    }		state;
+    int		onTime;
+    int		offTime;
+    int		waitTime;
+    int		current;
+} cursor =
+{
+    TRUE,
+    CursorWait,
+    10,
+    10,
+    7,
+    0
+};
+
+enum DrawBoxMode
+{
+    DB_Filled,
+    DB_NotFilled
+};
+
+    static void
+TextDimensions(void)
+{
+    struct TextExtent textExt;
+
+    TextExtent(gui.window->RPort, "s", 1, &textExt);
+
+    characterWidth = textExt.te_Width;
+    characterHeight = textExt.te_Height;
+}
+
+    static int
+posWidthCharToPoint(int width)
+{
+    return (width)*characterWidth;
+}
+
+    static int
+posHeightCharToPoint(int height)
+{
+    return (int)(height)*characterHeight;
+}
+
+    static int
+posWidthPointToChar(int width)
+{
+    //return (int)floor((float)width/(float)characterWidth)-1;
+    return width /characterWidth;
+}
+
+    static int
+posHeightPointToChar(int height)
+{
+    //return (int)floor((float)height/(float)characterHeight)-2;
+    return height / characterHeight;
+}
+
+    static int
+widthCharToPoint(int width)
+{
+    return (width)*(characterWidth);
+}
+
+    static int
+heightCharToPoint(int height)
+{
+    return (height)*characterHeight;
+}
+
+    static int
+widthPointToChar(int width)
+{
+    return (width)/characterWidth;
+}
+
+    static int
+heightPointToChar(int height)
+{
+    return (height)/characterHeight;
+}
+
+    static void
+refreshBorder(void)
+{
+    /*WaitBOVP(gui.window->);*/
+    RefreshWindowFrame(gui.window);
+}
+
+    static void
+drawBox(enum DrawBoxMode mode, unsigned short col, unsigned short row, int w, int h, guicolor_T color)
+{
+    LONG apen = GetAPen(gui.window->RPort);
+    LONG x1, y1, x2, y2;
+
+kprintf(" drawbox %d,%d color %d\n", col, row, color);
+
+    SetAPen(gui.window->RPort, getrealcolor(color));
+
+    x1 = posWidthCharToPoint(col);
+    y1 = posHeightCharToPoint(row + 1) - h;
+    x2 = x1 + w - 1;
+    y2 = posHeightCharToPoint(row + 1) - 1;
+
+    switch(mode)
+    {
+	case DB_Filled:
+	    RectFill(gui.window->RPort, x1, y1, x2, y2);
+	    break;
+
+	case DB_NotFilled:
+	    Move(gui.window->RPort, x1, y1);
+	    Draw(gui.window->RPort, x2, y1);
+	    Draw(gui.window->RPort, x2, y2);
+	    Draw(gui.window->RPort, x1, y2);
+	    Draw(gui.window->RPort, x1, y1);
+	    break;
+    }
+
+    SetAPen(gui.window->RPort, apen);
+
+}
+
+    static enum event
+EventHandler(void)
+{
+    struct IntuiMessage *msg;
+    enum event		returnEvent = ev_Ignore;
+    int			class, code;
+    static int		dragging = 0;
+    static int		mouseX, mouseY;
+    char_u		string[40];
+    BOOL		quit_request = FALSE;
+
+    msg = (struct IntuiMessage *)GetMsg(gui.window->UserPort);
+
+    if (!msg)
+    {
+	returnEvent = ev_NullEvent;
+    }
+    else
+    {
+
+	class = msg->Class;
+	code = msg->Code;
+
+	switch(class)
+	{
+	    case IDCMP_INTUITICKS:
+		/*
+		   if (cursor.active)
+		   {
+		   cursor.current ++;
+		   if (cursor.state == CursorOff)
+		   {
+		   printf("cursor turned on\n");
+		   if (cursor.offTime < cursor.current)
+		   {
+		   gui_undraw_cursor();
+		   cursor.state = CursorOn;
+		   cursor.current = 0;
+		   }
+		   }
+		   else if (cursor.state == CursorOn)
+		   {
+		   printf("cursor turned off\n");
+		   if (cursor.onTime < cursor.current)
+		   {
+		   cursor.state = CursorOff;
+		   gui_update_cursor(FALSE);
+		   cursor.current = 0;
+		   }
+		   }
+		   else if (cursor.state == CursorWait)
+		   {
+		   printf("cursor turned Wait\n");
+		   if (cursor.waitTime < cursor.current)
+		   {
+		   cursor.state = CursorOn;
+		   cursor.current = 0;
+		   }
+	}
+	}
+		   else
+		   {
+		   }
+		   returnEvent = ev_IntuiTicks;
+		   */
+		   break;
+
+	    case IDCMP_MOUSEBUTTONS:
+		   {
+		       int vim_modifiers=0;
+		       D("Mouse button event detected");
+		       switch (msg->Qualifier )
+		       {
+			   case IEQUALIFIER_LALT:
+			   case IEQUALIFIER_RALT:
+			       D("detected a Alt key");
+			       vim_modifiers|=MOUSE_ALT;
+			       break;
+
+			   case IEQUALIFIER_LSHIFT:
+			   case IEQUALIFIER_RSHIFT:
+			       D("detected a Shift key");
+			       vim_modifiers|=MOUSE_SHIFT;
+			       break;
+			   case IEQUALIFIER_CONTROL:
+			       D("detected a Control key");
+			       vim_modifiers |= MOUSE_CTRL;
+			       break;
+		       }
+		       if (code == SELECTDOWN)
+		       {
+			   D("Select Down detected\n");
+			   dragging = 1;
+			   gui_send_mouse_event(MOUSE_LEFT,
+				   mouseX = msg->MouseX - gui.window->BorderLeft,
+				   mouseY = msg->MouseY - gui.window->BorderTop,
+				   FALSE,
+				   vim_modifiers);
+			   /*gui_start_highlight(HL_ALL);*/
+		       }
+		       else if (code == SELECTUP)
+		       {
+			   D("Select UP detected\n");
+			   dragging = 0;
+			   gui_send_mouse_event(MOUSE_RELEASE,
+				   msg->MouseX - gui.window->BorderLeft,
+				   msg->MouseY - gui.window->BorderTop,
+				   FALSE, vim_modifiers);
+			   /*gui_stop_highlight(mask);*/
+		       }
+		       returnEvent = ev_MouseButtons;
+		       break;
+		   }
+	    case IDCMP_MOUSEMOVE:
+		   if ((abs(mouseX-(msg->MouseX - gui.window->BorderLeft)) > characterWidth) ||
+		       (abs(mouseY-(msg->MouseY - gui.window->BorderTop))>characterHeight))
+		   {
+		       int vim_modifiers=0;
+
+		       switch (msg->Qualifier )
+		       {
+			   case IEQUALIFIER_LALT:
+			   case IEQUALIFIER_RALT:
+			       D("detected a Alt key");
+			       vim_modifiers|=MOUSE_ALT;
+			       break;
+
+			   case IEQUALIFIER_LSHIFT:
+			   case IEQUALIFIER_RSHIFT:
+			       D("detected a Shift key");
+			       vim_modifiers|=MOUSE_SHIFT;
+			       break;
+			   case IEQUALIFIER_CONTROL:
+			       D("detected a Control key");
+			       vim_modifiers |= MOUSE_CTRL;
+			       break;
+		       }
+
+		       mouseX = msg->MouseX - gui.window->BorderLeft;
+		       mouseY = msg->MouseY - gui.window->BorderTop;
+		       if (!dragging)
+		       {
+			   gui_send_mouse_event(MOUSE_SETPOS, mouseX, mouseY, FALSE, vim_modifiers);
+			   break;
+		       }
+		       else
+		       {
+			   D("dragging\n");
+			   gui_send_mouse_event(MOUSE_DRAG, mouseX, mouseY, FALSE, vim_modifiers);
+		       }
+		   }
+		   returnEvent = ev_MouseMove;
+		   break;
+	    case IDCMP_VANILLAKEY:
+kprintf("===vanillakey %d\n", code);
+		   {
+		       string[0] = (char_u)code;
+		       if (code == CSI)
+		       {
+			   /* Insert CSI as K_CSI.  Untested! */
+			   string[1] = KS_EXTRA;
+			   string[2] = (int)KE_CSI;
+			   add_to_input_buf(string, 3);
+		       }
+		       else if (code == 8)
+		       {
+			    string[0] = CSI;
+			    string[1] = 'k';
+			    string[2] = 'b';
+			    add_to_input_buf(string, 3);
+		       }
+		       else if (code == 127)
+		       {
+			    string[0] = CSI;
+			    string[1] = 'k';
+			    string[2] = 'D';
+			    add_to_input_buf(string, 3);
+		       }
+		       else
+		       {
+			   int	len = 1;
+
+			   if (input_conv.vc_type != CONV_NONE)
+			       len = convert_input(string, 1, sizeof(string));
+			   add_to_input_buf(string, len);
+		       }
+		       returnEvent = ev_KeyStroke;
+		       break;
+
+		case IDCMP_RAWKEY:
+		       if (msg->Qualifier & IEQUALIFIER_LSHIFT)
+		       {
+		       }
+		       else if (msg->Qualifier & IEQUALIFIER_RSHIFT)
+		       {
+		       }
+		       else if (msg->Qualifier & IEQUALIFIER_CONTROL)
+		       {
+			   if (code == 33)
+			   {
+			       trash_input_buf();
+			   }
+		       }
+		       else if (msg->Code == KEYUP)
+		       {
+			   string[0] = CSI;
+			   string[1] = 'k';
+			   string[2] = 'u';
+			   add_to_input_buf(string, 3);
+		       }
+		       else if (msg->Code == KEYLEFT)
+		       {
+			   string[0] = CSI;
+			   string[1] = 'k';
+			   string[2] = 'l';
+			   add_to_input_buf(string, 3);
+		       }
+		       else if (msg->Code == KEYRIGHT)
+		       {
+kprintf("## keyright");
+			   string[0] = CSI;
+			   string[1] = 'k';
+			   string[2] = 'r';
+			   add_to_input_buf(string, 3);
+		       }
+		       else if (msg->Code == KEYDOWN)
+		       {
+			   string[0] = CSI;
+			   string[1] = 'k';
+			   string[2] = 'd';
+			   add_to_input_buf(string, 3);
+		       }
+		       else if (msg->Code == KEYBACKSPACE)
+		       {
+			   string[0] = CSI;
+			   string[1] = 'k';
+			   string[2] = 'b';
+			   add_to_input_buf(string, 3);
+		       }
+		       else if (msg->Code == KEYDELETE)
+		       {
+			   string[0] = CSI;
+			   string[1] = 'k';
+			   string[2] = 'D';
+			   add_to_input_buf(string, 3);
+		       }
+		       else if (msg->Code == KEYINSERT)
+		       {
+			   string[0] = CSI;
+			   string[1] = 'k';
+			   string[2] = 'I';
+			   add_to_input_buf(string, 3);
+		       }
+		       else if (msg->Code == KEYHOME)
+		       {
+			   string[0] = CSI;
+			   string[1] = 'k';
+			   string[2] = 'h';
+			   add_to_input_buf(string, 3);
+		       }
+		       else if (msg->Code == KEYEND)
+		       {
+			   string[0] = CSI;
+			   string[1] = '@';
+			   string[2] = '7';
+			   add_to_input_buf(string, 3);
+		       }
+		       else if (msg->Code == KEYWHEELUP)
+		       {
+			   int vim_modifiers=0;
+
+			   switch (msg->Qualifier )
+			   {
+			       case IEQUALIFIER_LALT:
+			       case IEQUALIFIER_RALT:
+				   D("detected a Alt key");
+				   vim_modifiers|=MOUSE_ALT;
+				   break;
+
+			       case IEQUALIFIER_LSHIFT:
+			       case IEQUALIFIER_RSHIFT:
+				   D("detected a Shift key");
+				   vim_modifiers|=MOUSE_SHIFT;
+				   break;
+			       case IEQUALIFIER_CONTROL:
+				   D("detected a Control key");
+				   vim_modifiers |= MOUSE_CTRL;
+				   break;
+			   }
+			   gui_send_mouse_event(MOUSE_4, 0, 1, FALSE, vim_modifiers);
+
+		       }
+		       else if (msg->Code == KEYWHEELDOWN)
+		       {
+			   int vim_modifiers=0;
+
+			   switch (msg->Qualifier )
+			   {
+			       case IEQUALIFIER_LALT:
+			       case IEQUALIFIER_RALT:
+				   D("detected a Alt key");
+				   vim_modifiers|=MOUSE_ALT;
+				   break;
+
+			       case IEQUALIFIER_LSHIFT:
+			       case IEQUALIFIER_RSHIFT:
+				   D("detected a Shift key");
+				   vim_modifiers|=MOUSE_SHIFT;
+				   break;
+			       case IEQUALIFIER_CONTROL:
+				   D("detected a Control key");
+				   vim_modifiers |= MOUSE_CTRL;
+				   break;
+			   }
+			   gui_send_mouse_event(MOUSE_5, 0, 1, FALSE, vim_modifiers);
+		       }
+
+		       returnEvent = ev_KeyStroke;
+		       break;
+		   }
+	    case IDCMP_MENUVERIFY:
+		   returnEvent = ev_MenuVerify;
+		   /* Menu verification requested */
+		   switch (code)
+		   {
+		       case MENUWAITING:
+			   /*
+			    ** It's not for us, the user is accessing another
+			    ** programs menu, this is a good time to do some
+			    ** cleanup etc
+			    */
+			   break;
+		       case MENUHOT:
+			   /*
+			    ** It is our menu that is going hot, we have kontrol
+			    ** Menu action can be cancelled by
+			    ** msg->Code = MENUCANCEL;
+			    */
+			   break;
+		       default:
+			   break;
+		   }
+		   break;
+	    case IDCMP_MENUPICK:
+		   returnEvent = ev_MenuPick;
+		   {
+		       /*
+			** one of our menu's have been selected, let's find out which
+			*/
+		       union myMenuItemUnion *item;
+		       int menuNumber;
+
+		       menuNumber = code;
+
+		       item = (union myMenuItemUnion *) ItemAddress(gui.menu, menuNumber);
+
+
+		       if (item)
+		       {
+			   gui_menu_cb(item->myMenuItem.guiMenu);
+		       }
+		   }
+		   break;
+	    case IDCMP_CLOSEWINDOW:
+		    quit_request = TRUE;
+		    break;
+
+	    case IDCMP_NEWSIZE:
+		   {
+		       int cx, cy;
+		       //cx = widthPointToChar(gui.window->GZZWidth);
+		       //cy = heightPointToChar(gui.window->GZZHeight);
+
+		       cx = gui.window->GZZWidth;
+		       cy = gui.window->GZZHeight - characterHeight;
+
+		       gui_resize_shell(cx, cy);
+
+		       returnEvent = ev_NewSize;
+		       break;
+		   }
+	    case IDCMP_REFRESHWINDOW:
+		   refreshBorder();
+		   returnEvent = ev_RefreshWindow;
+		   break;
+	    case IDCMP_GADGETDOWN:
+		   returnEvent = ev_GadgetDown;
+		   break;
+	    case IDCMP_GADGETUP:
+		   returnEvent = ev_GadgetUp;
+		   break;
+	    case IDCMP_MENUHELP:
+		   returnEvent = ev_MenuHelp;
+		   break;
+	    case IDCMP_GADGETHELP:
+		   returnEvent = ev_GadgetHelp;
+		   break;
+	    case IDCMP_INACTIVEWINDOW:
+		   gui.in_focus = FALSE;
+		   gui_update_cursor(TRUE, FALSE);
+		   break;
+
+	    case IDCMP_ACTIVEWINDOW:
+		   gui.in_focus = TRUE;
+		   gui_update_cursor(TRUE, FALSE);
+		   break;
+	    default:
+		   break;
+	}
+	ReplyMsg((struct Message*)msg);
+    }
+
+    if (quit_request)
+    {
+	getout(0); // gui_mch_exit(1);
+    }
+
+    return returnEvent;
+    /* mouse positin gui.window->MoseY, gui.window->MouseX) */
+}
+
+    static int
+checkEventHandler(void)
+{
+    enum event happened;
+
+    do
+    {
+	happened = EventHandler() ;
+    }
+    while  (happened != ev_NullEvent);
+
+    return OK;
+}
+
+    static int
+charEventHandler(int wtime)
+{
+    enum event happened;
+    int rc;
+
+    do
+    {
+	Wait(1<<gui.window->UserPort->mp_SigBit);
+
+	happened = EventHandler() ;
+    }
+    while ((happened != ev_IntuiTicks) && (happened != ev_KeyStroke) && (happened != ev_MenuPick) && (happened != ev_MouseMove) &&(happened != ev_MouseButtons) );
+
+    if (happened == ev_KeyStroke || happened == ev_MenuPick)
+	rc = OK;
+    else
+	rc = FAIL;
+
+    return rc;
+}
+
+
+/*
+ * add primary menu
+ */
+    void
+gui_mch_add_menu_item(vimmenu_T *menu, int idx)
+{
+    union myMenuItemUnion *menuItemUnion = NULL;
+    struct IntuiText *menutext = NULL;
+    vimmenu_T *parent;
+
+    assert(menu != NULL);
+    assert(menu->parent != NULL);
+    parent = menu->parent;
+
+    /* Don't add menu separator */
+    if (menu_is_separator(menu->name))
+	return;
+
+    if (parent->menuItemPtr == NULL)
+	return;
+
+    /* TODO: use menu->mnemonic and menu->actext */
+    menutext = (struct IntuiText *) malloc(sizeof(struct IntuiText));
+
+    SetAttrib(menutext, FrontPen, 3);
+    SetAttrib(menutext, BackPen, 1);
+    SetAttrib(menutext, DrawMode, COMPLEMENT);
+    SetAttrib(menutext, LeftEdge, 0);
+    SetAttrib(menutext, TopEdge, 0);
+    SetAttrib(menutext, ITextFont, NULL);
+    SetAttrib(menutext, NextText, NULL);
+
+    menuItemUnion = malloc(sizeof(*menuItemUnion));
+
+    SetAttrib(&menuItemUnion->menuItem, NextItem, parent->menuItemPtr);
+    SetAttrib(&menuItemUnion->menuItem, LeftEdge, 0);
+    SetAttrib(&menuItemUnion->menuItem, Width, characterWidth*strlen(menu->dname));
+    SetAttrib(&menuItemUnion->menuItem, Height, characterHeight+2);
+    SetAttrib(&menuItemUnion->menuItem, Flags, ITEMTEXT+ITEMENABLED+HIGHCOMP);
+    SetAttrib(&menuItemUnion->menuItem, MutualExclude, 0);
+    SetAttrib(&menuItemUnion->menuItem, ItemFill, (APTR)menutext);
+    SetAttrib(&menuItemUnion->menuItem, SelectFill, NULL);
+    SetAttrib(&menuItemUnion->menuItem, Command, NULL);
+    SetAttrib(&menuItemUnion->menuItem, SubItem, NULL);
+    SetAttrib(&menuItemUnion->menuItem, NextSelect, MENUNULL);
+
+    menutext->IText = malloc(strlen(menu->dname) + 1);
+
+    strcpy(menutext->IText, menu->dname);
+
+    menuItemUnion->menuItem.NextItem = NULL;
+
+
+    if (parent)
+    {
+	if (!parent->menuItemPtr)
+	{
+	    D("Adding first subElement");
+	    SetAttrib(&menuItemUnion->menuItem, TopEdge, 0);
+	    parent->menuPtr->FirstItem = &menuItemUnion->menuItem;
+	    parent->menuItemPtr = &menuItemUnion->menuItem;
+	}
+	else
+	{
+	    struct MenuItem *tmpMenuItem;
+	    tmpMenuItem = parent->menuItemPtr;
+	    while (tmpMenuItem->NextItem)
+	    {
+		tmpMenuItem = tmpMenuItem->NextItem;
+	    }
+	    tmpMenuItem->NextItem = &menuItemUnion->menuItem;
+	    SetAttrib(&menuItemUnion->menuItem, TopEdge, tmpMenuItem->TopEdge+tmpMenuItem->Height);
+	}
+    }
+    menu->menuPtr= NULL;
+    menu->menuItemPtr = &menuItemUnion->menuItem;
+    menuItemUnion->myMenuItem.guiMenu = menu;
+}
+
+
+    static struct Menu *
+getMenu(struct RastPort *rast, int left, STRPTR name)
+{
+    struct Menu *menu;
+    struct TextExtent textExt;
+
+    menu = malloc(sizeof(*menu));
+    menu->NextMenu = NULL;
+    menu->LeftEdge = left;
+
+    TextExtent(rast, name, strlen(name), &textExt);
+
+    menu->TopEdge = 0;
+    menu->Width = textExt.te_Width;
+    menu->Height = textExt.te_Height;
+    menu->Flags = ITEMTEXT+HIGHCOMP+MENUENABLED;
+    menu->MenuName = name;
+    menu->FirstItem = NULL;
+
+    return menu;
+}
+
+/*
+ * add  1st level submenu item
+ */
+    void
+gui_mch_add_menu(vimmenu_T *menu, int idx)
+{
+    struct Menu	*newMenu;
+    int		pos = 0;
+
+    if (!menu_is_menubar(menu->name))
+	return;
+
+    menu->menuPtr = newMenu = getMenu(gui.window->RPort, 0, menu->dname);
+    menu->menuItemPtr = NULL;
+    newMenu->NextMenu = NULL;
+
+    if (!gui.menu)
+    {
+	D("Adding head menu");
+	gui.menu = newMenu ;
+    }
+    else
+    {
+	struct Menu *tmpMenu;
+
+	tmpMenu = gui.menu;
+	while (tmpMenu->NextMenu)
+	    tmpMenu = tmpMenu->NextMenu;
+	tmpMenu->NextMenu = newMenu;
+	pos = tmpMenu->LeftEdge +
+	    TextLength(gui.window->RPort, tmpMenu->MenuName,
+		    strlen(tmpMenu->MenuName));
+	newMenu->LeftEdge = pos;
+    }
+}
+
+    void
+gui_mch_toggle_tearoffs(enable)
+    int		enable;
+{
+    /* no tearoff menus */
+}
+
+    int
+gui_mch_set_blinking(long wait, long on, long off)
+{
+    cursor.waitTime = wait/100;
+    cursor.onTime = on/100;
+    cursor.offTime = off/100;
+    return OK;
+}
+
+    void
+gui_mch_prepare(int *argc, char **argv)
+{
+    D("gui_mch_prepare");
+
+    execBase = (struct ExecBase *)OpenLibrary("exec.library", NULL);
+    gfxBase = (struct GFXBase *)OpenLibrary("graphics.library", NULL);
+    layersBase = (struct LayersBase *)OpenLibrary("layers.library", NULL);
+
+    if (!execBase)
+    {
+	D("Cannot open exec.library, aborting");
+    }
+    if (!gfxBase)
+    {
+	D("Cannot open graphics.library, aborting");
+    }
+    if (!layersBase)
+    {
+	D("Cannot open graphics.library, aborting");
+    }
+    D("gui_mch_prepare done ");
+}
+
+    void
+atexitDoThis(void)
+{
+kprintf("atexitdothis###\n");
+    gui_mch_exit(-1);
+}
+
+/*
+ * Check if the GUI can be started.  Called before gvimrc is sourced.
+ * Return OK or FAIL.
+ */
+    int
+gui_mch_init_check(void)
+{
+    if (execBase && gfxBase && layersBase)
+	return OK;
+    return FAIL;
+}
+
+    int
+gui_mch_init(void)
+{
+    int returnCode = FAIL; /* assume failure*/
+
+    TimerMP = CreateMsgPort();
+    if (!TimerMP) return FAIL;
+
+    TimerIO = (struct timerequest *)CreateIORequest(TimerMP, sizeof(*TimerIO));
+    if (!TimerIO) return FAIL;
+
+    if (OpenDevice("timer.device", UNIT_VBLANK, &TimerIO->tr_node, 0)) return FAIL;
+
+    gui.window = OpenWindowTagList(&vimNewWindow, tags);
+    if (gui.window)
+    {
+	gui.in_use = TRUE;
+	gui.in_focus=TRUE;
+	gui.norm_pixel = gui.def_norm_pixel = 1;
+	gui.back_pixel = gui.def_back_pixel = 0;
+
+	set_normal_colors();
+	gui_check_colors();
+
+	SetDrMd(gui.window->RPort, JAM2);
+	gui_mch_set_colors(gui.norm_pixel, gui.back_pixel);
+
+	atexit(atexitDoThis);
+
+	TextDimensions();
+	returnCode = OK; /* we've had success */
+	if (gui_win_x != -1 && gui_win_y != -1)
+	    gui_mch_set_winpos(gui_win_x, gui_win_y);
+
+	gui_mch_clear_all();
+
+    }
+    gui.menu = NULL;
+
+    return returnCode;
+}
+
+    void
+gui_mch_new_colors(void)
+{
+kprintf("### gui_mch_new_colors\n");
+    SetAPen(gui.window->RPort, getrealcolor(gui.norm_pixel));
+    SetBPen(gui.window->RPort, getrealcolor(gui.back_pixel));
+
+    D("gui_mch_new_colors");
+}
+
+    int
+gui_mch_open(void)
+{
+    D("gui_mch_open");
+
+    highlight_gui_started();
+    return OK;
+}
+
+    void
+gui_mch_exit(int returnCode)
+{
+kprintf("###gui_mch_exit\n");
+    D("****gui_mch_exit");
+
+    if (TimerSent)
+    {
+	if (!CheckIO(&TimerIO->tr_node)) AbortIO(&TimerIO->tr_node);
+	WaitIO(&TimerIO->tr_node);
+	TimerSent = FALSE;
+    }
+
+    if (TimerIO)
+    {
+	CloseDevice(&TimerIO->tr_node);
+	DeleteIORequest(&TimerIO->tr_node);
+	TimerIO = NULL;
+    }
+
+    if (TimerMP)
+    {
+	DeleteMsgPort(TimerMP);
+	TimerMP = NULL;
+    }
+
+    if (gui.window)
+    {
+	int i;
+
+	for(i = 0; i < sizeof(MyColorTable) / sizeof(MyColorTable[0]); i++)
+	{
+	    if (MyColorTable[i].alloced)
+	    {
+		ReleasePen(gui.window->WScreen->ViewPort.ColorMap, MyColorTable[i].pen);
+		MyColorTable[i].alloced = FALSE;
+	    }
+	}
+
+	D("Closeing window ");
+	CloseWindow(gui.window);
+	CloseLibrary((struct Library*)execBase);
+	CloseLibrary((struct Library*)gfxBase);
+	gui.window = NULL;
+	gui.in_use = FALSE;
+	//getout(1);
+    }
+}
+
+/*
+ * Get the position of the top left corner of the window.
+ */
+    int
+gui_mch_get_winpos(int *x, int *y)
+{
+    if (gui.window)
+    {
+	*x = gui.window->LeftEdge;
+	*y = gui.window->TopEdge;
+    }
+    else
+    {
+	return FAIL;
+    }
+
+    return OK;
+}
+
+/*
+ * 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.window)
+    {
+	ChangeWindowBox(gui.window, x, y, gui.window->Width, gui.window->Height);
+    }
+}
+
+    void
+gui_mch_set_shellsize(int width, int height,
+	int min_width, int min_height, int base_width, int base_height)
+{
+    D("gui_mch_set_shellsize");
+
+    ChangeWindowBox(gui.window, gui.window->LeftEdge,
+	    gui.window->TopEdge, widthCharToPoint(width) + gui.window->BorderLeft + gui.window->BorderRight,
+	    heightCharToPoint(height) + gui.window->BorderTop + gui.window->BorderBottom);
+    checkEventHandler();
+}
+
+    void
+gui_mch_get_screen_dimensions(int *screen_w, int *screen_h)
+{
+//    *screen_w = widthPointToChar(gui.window->GZZWidth);
+//    *screen_h = heightPointToChar(gui.window->GZZHeight);
+    *screen_w = gui.window->GZZWidth;
+    *screen_h = gui.window->GZZHeight - characterHeight;
+
+
+kprintf("=== get_screen_dimensions: screen %d,%d character %d,%d  console %d,%d\n",
+gui.window->GZZWidth,
+gui.window->GZZHeight,
+characterWidth,
+characterHeight,
+*screen_w,
+*screen_h);
+
+}
+
+    void
+gui_mch_set_text_area_pos(int x, int y, int w, int h)
+{
+    D("gui_mch_set_text_area_pos");
+}
+
+    void
+gui_mch_enable_scrollbar(scrollbar_T *sb, int flag)
+{
+    /* done by default */
+    /* TODO: disable scrollbar when it's too small */
+}
+
+    void
+gui_mch_set_scrollbar_thumb(scrollbar_T *sb, long val, long size, long max)
+{
+    ULONG total = max;
+    ULONG visible = size;
+    ULONG top = val;
+    ULONG hidden;
+    ULONG overlap = 0;
+    UWORD body, pot;
+
+kprintf("__set_scrollbar_thumb val %d  size %d  max %d\n", val, size, max);
+
+    if (total > visible)
+	hidden = total - visible;
+    else
+	hidden = 0;
+
+    if (top > hidden)
+	top = hidden;
+
+    body = (hidden > 0) ?
+	    (UWORD)(((ULONG)(visible - overlap) * MAXBODY) / (total - overlap)) :
+	    MAXBODY;
+
+    pot  = (hidden > 0) ? (UWORD)(((ULONG) top * MAXPOT) / hidden) : 0;
+
+kprintf("__pot %x  body %x\n", pot, body);
+
+    NewModifyProp(&propGadget, gui.window, NULL,
+		  Gadget2SInfo.Flags,
+		  MAXPOT, pot,
+		  MAXBODY, body,
+		  1);
+    return;
+
+}
+
+    void
+gui_mch_set_scrollbar_pos(scrollbar_T *sb, int x, int y, int w, int h)
+{
+    D("gui_mch_set_scrollbar_pos");
+    /*NewModifyProp(&propGadget, gui.window, NULL, MAXPOT, MAXPOT/sb->max*y, MAXPOT, MAXBODY/sb->max/sb->size, 1);*/
+}
+
+    void
+gui_mch_create_scrollbar(scrollbar_T *sb, int orient)
+{
+    /* this is done by default */
+}
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+    void
+gui_mch_destroy_scrollbar(scrollbar_T *sb)
+{
+    /* this is done by default */
+}
+#endif
+
+int gui_mch_init_font(char_u *font_name, int fontset)
+{
+    /*D("gui_mch_init_font");*/
+
+    gui.char_width = characterWidth;
+    gui.char_height = characterHeight;
+    gui.char_ascent = gui.window->RPort->TxBaseline;
+
+    return OK;
+}
+
+    int
+gui_mch_adjust_charsize()
+{
+    return FAIL;
+}
+
+    GuiFont
+gui_mch_get_font( char_u *name, int giveErrorIfMissing)
+{
+    /*D("gui_mch_get_font");*/
+    return NULL;
+}
+
+    void
+gui_mch_set_font(GuiFont font)
+{
+    /*D("gui_mch_set_font");*/
+}
+
+#if 0 /* not used */
+    int
+gui_mch_same_font(GuiFont f1, GuiFont f2)
+{
+    D("gui_mch_same_font");
+}
+#endif
+
+    void
+gui_mch_free_font(GuiFont font)
+{
+    if (font)
+	D("gui_mch_free_font");
+}
+
+#define RGB(a, b, c) ((a && 0xff) * 0x10000 + (b * 0xff) * 0x100 + (c & 0xff))
+
+/*
+ * Get color handle for color "name".
+ * Return INVALCOLOR when not possible.
+ */
+
+    typedef struct guicolor_tTable
+    {
+	char	    *name;
+	unsigned long    color;
+	UBYTE		red;
+	UBYTE		green;
+	UBYTE		blue;
+    } guicolor_tTable;
+
+    static guicolor_tTable table[] =
+    {
+	{"Grey",	0, 190,190,190},
+	{"Black",	1, 0, 0, 0},
+	{"DarkBlue",	2, 0, 0, 139},
+	{"DarkGreen",	3, 0, 100, 0},
+	{"DarkCyan",	4, 0, 139, 139},
+	{"DarkRed",	5, 139, 0, 0},
+	{"DarkMagenta",	6, 139, 0, 139},
+	{"Brown",	7, 165, 42, 42},
+	{"Gray",	8, 190, 190, 190},
+	{"Grey",	9, 190, 190, 190},
+	{"LightGray",	10, 211, 211, 211},
+	{"LightGrey",	11, 211, 211, 211},
+	{"DarkGray",	12, 169, 169, 169},
+	{"DarkGrey",	13, 169, 169, 169},
+	{"Blue",	14, 0, 0, 255},
+	{"LightBlue",	15, 173, 216, 230},
+	{"Green",	16, 0, 255, 0},
+	{"LightGreen",	17, 144, 238, 144},
+	{"Cyan",	18, 0, 255, 255},
+	{"LightCyan",	19, 224, 255, 255},
+	{"Red",		20, 255, 0, 0},
+	{"LightRed",	21, 255, 0, 0}, /*?*/
+	{"Magenta",	22, 255, 0, 255},
+	{"LightMagenta",23, 255, 0, 255}, /*?*/
+	{"Yellow",	24, 255, 255, 0},
+	{"LightYellow",	25, 255, 255, 224},	/* TODO: add DarkYellow */
+	{"White",	26, 255, 255, 255},
+	{"SeaGreen",	27, 46, 139, 87},
+	{"Orange",	28, 255, 165, 0},
+	{"Purple",	30, 160, 32, 240},
+	{"SlateBlue",	31, 106, 90, 205},
+	{"grey90",	32, 229, 229, 229},
+	{"grey95",	33, 242, 242, 242},
+	{"grey80",	34, 204, 204, 204},
+	{NULL, NULL},
+    };
+
+    guicolor_T
+gui_mch_get_color(char_u *name)
+{
+
+    guicolor_T color = INVALCOLOR;
+
+    int i;
+
+    for (i = 0; table[i].name != NULL;i++)
+    {
+	if (stricmp(name, table[i].name) == 0)
+	{
+	    //color = table[i].color;
+	    color = i;
+	}
+    }
+
+#if 0
+    if (color == INVALCOLOR)
+    {
+	char *looky = NULL;
+
+	color = strtol((char*)name, &looky, 10);
+	if (*looky != NUL)
+	    color = INVALCOLOR;
+    }
+#endif
+
+    kprintf("gui_mch_get_color[%s] = %s\n", name, table[color].name);
+
+    return color;
+}
+
+static UBYTE getrealcolor(guicolor_T i)
+{
+    if (!MyColorTable[i].alloced)
+    {
+	MyColorTable[i].pen = ObtainBestPen(gui.window->WScreen->ViewPort.ColorMap,
+					    table[i].red * 0x01010101,
+					    table[i].green * 0x01010101,
+					    table[i].blue * 0x01010101,
+					    OBP_FailIfBad, FALSE,
+					    OBP_Precision, PRECISION_GUI,
+					    TAG_DONE);
+	if (MyColorTable[i].pen != -1)
+	{
+	    MyColorTable[i].alloced = TRUE;
+	}
+    }
+
+    return MyColorTable[i].pen;
+}
+
+
+    void
+gui_mch_set_colors(guicolor_T fg, guicolor_T bg)
+{
+#if 0
+    if (fg == 0)
+    {
+	fg = 1;
+    }
+#endif
+    SetABPenDrMd(gui.window->RPort, getrealcolor(fg), getrealcolor(bg), JAM2);
+
+kprintf("gui_mch_set_colors %s,%s\n", table[fg].name, table[bg].name);
+}
+
+    void
+gui_mch_set_fg_color(guicolor_T color)
+{
+#if 0
+    if (color == 0)
+    {
+	color = 1; /* vim sends 0 as default color which is ALWAYS the
+		      background on the amiga scrolling with colours as the
+		      background is a very bad idea on slow machines*/
+    }
+#endif
+    SetAPen(gui.window->RPort, getrealcolor(color));
+    SetDrMd(gui.window->RPort, JAM2);
+
+kprintf("gui_mch_set_fg_color %s\n", table[color].name);
+
+}
+
+    void
+gui_mch_set_bg_color(guicolor_T color)
+{
+    SetBPen(gui.window->RPort, getrealcolor(color));
+kprintf("gui_mch_set_bg_color %s\n", table[color].name);
+
+}
+
+    void
+gui_mch_draw_string(int row, int col, char_u *s, int len, int flags)
+{
+#if 1
+    char tempstring[300];
+
+    memcpy(tempstring, s, len);
+    tempstring[len] = '\0';
+
+    kprintf("gui_mch_draw_string(%s) flags %x\n", tempstring, flags);
+#endif
+
+    if (flags & DRAW_TRANSP)
+    {
+	SetDrMd(gui.window->RPort, JAM1);
+	Move(gui.window->RPort, posWidthCharToPoint(col), posHeightCharToPoint(row) + gui.window->RPort->TxBaseline);
+	Text(gui.window->RPort, s, len);
+    }
+    else
+    {
+	SetDrMd(gui.window->RPort, JAM2);
+	Move(gui.window->RPort, posWidthCharToPoint(col), posHeightCharToPoint(row) + gui.window->RPort->TxBaseline);
+	Text(gui.window->RPort, s, len);
+    }
+
+    if (flags & DRAW_BOLD)
+    {
+	SetDrMd(gui.window->RPort, JAM1);
+	Move(gui.window->RPort, posWidthCharToPoint(col)+1, posHeightCharToPoint(row) + gui.window->RPort->TxBaseline);
+	Text(gui.window->RPort, s, len);
+    }
+
+    if (flags & DRAW_UNDERL)
+    {
+	Move(gui.window->RPort, posWidthCharToPoint(col), posHeightCharToPoint(row + 1) - 1);
+	Draw(gui.window->RPort, posWidthCharToPoint(col+len) - 1, posHeightCharToPoint(row + 1) - 1);
+    }
+
+    SetDrMd(gui.window->RPort, JAM2);
+}
+
+    int
+gui_mch_haskey(char_u *name)
+{
+    int i;
+
+    D("gui_mch_haskey");
+
+    for (i = 0; special_keys[i].vim_code1 != NUL; i++)
+	if (name[0] == special_keys[i].vim_code0 &&
+		name[1] == special_keys[i].vim_code1)
+	    return OK;
+    return FAIL;
+}
+
+    void
+gui_mch_beep(void)
+{
+    D("gui_mch_beep");
+}
+
+    void
+gui_mch_flash(int msec)
+{
+    D("gui_mch_flash");
+
+    SetDrMd(gui.window->RPort, COMPLEMENT);
+    RectFill(gui.window->RPort, 0, 0, gui.window->GZZWidth - 1, gui.window->GZZHeight - 1);
+    Delay(msec * 50 / 1000);
+    RectFill(gui.window->RPort, 0, 0, gui.window->GZZWidth - 1, gui.window->GZZHeight - 1);
+    SetDrMd(gui.window->RPort, JAM2);
+}
+
+    void
+gui_mch_invert_rectangle( int r, int c, int nr, int nc)
+{
+    printf("gui_mch_invert_rectangle %d %d %d %d\n", r, c, nr, nc);
+}
+
+    void
+gui_mch_iconify(void)
+{
+    D("gui_mch_iconify");
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Bring the Vim window to the foreground.
+ */
+    void
+gui_mch_set_foreground()
+{
+    WindowToFront(gui.window);
+    D("gui_mch_set_foreground");
+}
+#endif
+
+    void
+gui_mch_settitle(char_u  *title, char_u  *icon)
+{
+    SetWindowTitles(gui.window, title, (STRPTR)~0);
+    D("gui_mch_settitle");
+}
+
+    void
+gui_mch_stop_blink(void)
+{
+    gui_undraw_cursor();
+    D("gui_mch_stop_blink");
+}
+
+    void
+gui_mch_start_blink(void)
+{
+    gui_update_cursor(FALSE, FALSE);
+    D("gui_mch_start_blink");
+}
+
+    void
+gui_mch_draw_hollow_cursor(guicolor_T color)
+{
+    drawBox(DB_NotFilled, gui.col, gui.row, characterWidth, characterHeight, color);
+}
+
+    void
+gui_mch_draw_part_cursor( int w, int h, guicolor_T color)
+{
+    D("gui_mch_part_cursor");
+    drawBox(DB_Filled, gui.col, gui.row, w, h, color);
+}
+
+    void
+gui_mch_update(void)
+{
+    checkEventHandler();
+    return ;
+}
+
+    int
+gui_mch_wait_for_chars(int wtime)
+{
+    ULONG timermask = 1L << TimerMP->mp_SigBit;
+    ULONG winmask = 1L << gui.window->UserPort->mp_SigBit;
+    int retval = FAIL;
+
+    kprintf("========== gui_mch_wait_for_chars %d\n", wtime);
+
+    if (wtime == -1) wtime = 1000000000;
+    if (wtime < 20) wtime = 20;
+
+    SetSignal(0, timermask);
+    TimerIO->tr_node.io_Command = TR_ADDREQUEST;
+    TimerIO->tr_time.tv_secs = wtime / 1000;
+    TimerIO->tr_time.tv_micro = (wtime % 1000) * 1000;
+    SendIO(&TimerIO->tr_node);
+    TimerSent = TRUE;
+
+    for(;;)
+    {
+	ULONG sigs = Wait(winmask | timermask);
+
+	if (sigs & winmask)
+	{
+	    checkEventHandler();
+	    if (!vim_is_input_buf_empty())
+	    {
+		retval = OK;
+		if (!CheckIO(&TimerIO->tr_node)) AbortIO(&TimerIO->tr_node);
+		WaitIO(&TimerIO->tr_node);
+		TimerSent = FALSE;
+		break;
+	    }
+	}
+
+	if (sigs & timermask)
+	{
+	    struct Message *msg;
+
+	    if ((msg = GetMsg(TimerMP)))
+	    {
+		ReplyMsg(msg);
+		TimerSent = FALSE;
+		retval = FAIL;
+		break;
+	    }
+	}
+    }
+
+    return retval;
+
+//    assert(wtime != 0);
+//    return charEventHandler(wtime);
+}
+
+    void
+gui_mch_flush(void)
+{
+}
+
+    void
+gui_mch_clear_block(int row1, int col1, int row2, int col2)
+{
+    UBYTE apen = GetAPen(gui.window->RPort);
+
+    SetAPen(gui.window->RPort, getrealcolor(gui.back_pixel));
+    RectFill(gui.window->RPort,
+	     posWidthCharToPoint(col1),
+	     posHeightCharToPoint(row1),
+	     posWidthCharToPoint(col2 + 1) - 1,
+	     posHeightCharToPoint(row2 + 1) - 1);
+    SetAPen(gui.window->RPort, apen);
+
+}
+
+    void
+gui_mch_clear_all(void)
+{
+    SetRast(gui.window->RPort, GetBPen(gui.window->RPort));
+    refreshBorder();
+    D("gui_mch_clear_all");
+}
+
+    void
+gui_mch_delete_lines(int row, int num_lines)
+{
+    ScrollWindowRaster(gui.window,
+	    0,
+	    characterHeight * num_lines,
+	    posWidthCharToPoint(gui.scroll_region_left),
+	    posHeightCharToPoint(row),
+	    posWidthCharToPoint(gui.scroll_region_right + 1) - 1,
+	    posHeightCharToPoint(gui.scroll_region_bot + 1) - 1);
+
+    gui_clear_block(gui.scroll_region_bot - num_lines + 1,
+		    gui.scroll_region_left,
+		    gui.scroll_region_bot,
+		    gui.scroll_region_right);
+
+}
+
+    void
+gui_mch_insert_lines(int row, int num_lines)
+{
+     ScrollWindowRaster(gui.window,
+	    0,
+	    -characterHeight*num_lines,
+	    posWidthCharToPoint(gui.scroll_region_left),
+	    posHeightCharToPoint(row),
+	    posWidthCharToPoint(gui.scroll_region_right + 1) - 1,
+	    posHeightCharToPoint(gui.scroll_region_bot +1 ) - 1);
+
+    gui_clear_block(row, gui.scroll_region_left,
+		    row + num_lines - 1, gui.scroll_region_right);
+
+}
+
+    void
+gui_mch_enable_menu(int flag)
+{
+    D("gui_mch_enable_menu");
+}
+
+    void
+gui_mch_set_menu_pos(int x, int y, int w, int h)
+{
+    D("gui_mch_set_menu_pos");
+}
+
+    void
+gui_mch_destroy_menu(vimmenu_T *menu)
+{
+    D("gui_mch_destroy_menu");
+    ClearMenuStrip(gui.window);
+}
+
+    void
+gui_mch_menu_grey(vimmenu_T *menu, int grey)
+{
+    D("gui_mch_menu_grey");
+}
+
+    void
+gui_mch_menu_hidden(vimmenu_T *menu, int hidden)
+{
+    D("gui_mch_menu_hidden");
+    ClearMenuStrip(gui.window);
+}
+
+    void
+gui_mch_draw_menubar(void)
+{
+    D("gui_mch_draw_menubar");
+    SetMenuStrip(gui.window, gui.menu);
+}
+
+    static void
+AmigaError(const char *string)
+{
+    static struct IntuiText pos = { 3, 0, JAM2, 17, 5, NULL, "Cancel", NULL} ;
+    static struct IntuiText neg = { 3, 0, JAM2, 17, 5, NULL, "Cancel", NULL} ;
+    static struct IntuiText message = { 3, 0, JAM2, 17, 5, NULL, NULL, NULL} ;
+    static char *strptr = 0;
+
+    if (strptr)
+	free(strptr);
+    strptr = malloc(strlen(string)+1);
+
+    message.IText = strptr;
+    strcpy(strptr, string);
+
+    AutoRequest(NULL, &message, &pos, &neg, 0, 0, 300, 300);
+}
+
+    int
+clip_mch_own_selection(VimClipboard *cbd)
+{
+    D("clib_mch_own_selection");
+    return OK;
+}
+
+    void
+mch_setmouse(int  on)
+{
+}
+
+/*
+ * Get current y mouse coordinate in text window.
+ * Return -1 when unknown.
+ */
+    int
+gui_mch_get_mouse_x()
+{
+    return gui.window->GZZMouseX;
+}
+
+    int
+gui_mch_get_mouse_y()
+{
+    return gui.window->GZZMouseY;
+}
+
+    void
+gui_mch_setmouse(x, y)
+    int		x;
+    int		y;
+{
+    /* TODO */
+}
+
+    void
+gui_mch_show_popupmenu(vimmenu_T *menu)
+{
+    /* TODO */
+}
+
+    void
+clip_mch_lose_selection(VimClipboard *cbd)
+{
+    D("clip_mch_lose_selecction");
+}
+
+    void
+clip_mch_request_selection(VimClipboard *cbd)
+{
+    D("clip_mch_requst_selection");
+}
+
+    void
+clip_mch_set_selection(VimClipboard *cbd)
+{
+}
+
+    long_u
+gui_mch_get_rgb(guicolor_T pixel)
+{
+    ULONG coltable[3], color;
+
+    GetRGB32(gui.window->WScreen->ViewPort.ColorMap,
+	     getrealcolor(pixel),
+	     1,
+	     coltable);
+
+    color = ((coltable[0] & 0xFF000000) >> 8) |
+	    ((coltable[1] & 0xFF000000) >> 16) |
+	    ((coltable[2] & 0xFF000000) >> 24);
+
+    return color;
+}
+
+#endif /* USE_AMIGA_GUI*/