diff --git a/src/gui_riscos.c b/src/gui_riscos.c
new file mode 100644
index 0000000..b823a79
--- /dev/null
+++ b/src/gui_riscos.c
@@ -0,0 +1,3547 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * 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 "vim.h"
+#include <string.h>
+
+/*
+ * gui_riscos.c
+ *
+ * Thomas Leonard <tal197@ecs.soton.ac.uk>
+ * Updated by Andy Wingate <andy@sparse.net>
+ */
+
+extern int time_of_last_poll;
+
+int task_handle = 0;		/* Zero means we are not yet a Wimp task */
+int child_handle = 0;		/* Task handle of our child process (zero if none). */
+int *wimp_menu = (int *) -1;	/* Pointer to a Wimp menu structure (or -1) */
+int save_window = -1;		/* Save As window handle */
+
+int *redraw_block = NULL;	/* NULL means not in a redraw loop. */
+int ro_return_early = FALSE;	/* Break out of gui_mch_wait_for_chars() */
+
+int leaf_ref = 0;		/* Wimp message number - send via Wimp$Scrap */
+char_u *leaf_name = NULL;	/* Leaf name from DataSave */
+
+int default_columns = 120;	/* These values are used if the --rows and --columns */
+int default_rows = 32;		/* options aren't used on startup. */
+
+#define DRAG_FALSE	    0
+#define DRAG_SELECTION	    1
+#define DRAG_RESIZE_WINDOW  2
+int ro_dragging = DRAG_FALSE;
+int drag_button;
+int drag_modifiers;
+int drag_x_offset;
+int drag_y_offset;
+
+int nested_wimp = FALSE;	/* Bool - can we use the new wimp? */
+
+int changed_mode = FALSE;
+int x_eigen_factor;
+int y_eigen_factor;
+
+/* If ro_current_font is non-zero then use the outline font with that handle,
+ * otherwise, if zap_redraw is TRUE then use ZapRedraw, otherwise use the
+ * system font.
+ *
+ * If zap_redraw is TRUE then zap_file[] contains valid Zap font file
+ * pointers (or NULLs).
+ */
+int ro_current_font = 0;	/* 0 is system font, or ZapRedraw */
+int font_x_offset   = 0;	/* Where to position each char in its box */
+int font_y_offset   = 0;
+
+int zap_redraw	    = FALSE;
+int double_height   = FALSE;	/* Plot each line twice? */
+
+#define grgb(r,g,b) ((b<<16) + (g<<8) + (r))
+#define UNUSED_COLOUR (gui.back_pixel)
+
+#define RO_LOAD_CLIPBOARD -2	/* Internal handle for DataSave message. */
+
+/* Changes by John Kortink, 22-23 July 1998
+ *
+ * Stuff to make redraw a lot faster. Almost all of it is right here below,
+ * elsewhere changes are marked with 'JK230798'. Apart from a small change in
+ * 'gui.c' all changes are limited to this file, 'gui_riscos.c'. The change in
+ * 'gui.c' is to make Vim stop being 'smart' not redrawing characters that are
+ * 'already there' (i.e. from the previous line, by coincidence). This caused a
+ * lot more calls to the redraw code, which we want to avoid because a few nice
+ * big strings at a time is a lot faster than a truckload of small ones. ('Dear
+ * Bram ...').
+ */
+
+/* The ZapRedraw structure */
+
+static struct
+{
+    int		r_flags;
+    int		r_minx;
+    int		r_miny;
+    int		r_maxx;
+    int		r_maxy;
+    int		r_screen;
+    int		r_bpl;
+    int		r_bpp;
+    int		r_charw;
+    int		r_charh;
+    char	*r_caddr;
+    int		r_cbpl;
+    int		r_cbpc;
+    int		r_linesp;
+    int		r_data;
+    int		r_scrollx;
+    int		r_scrolly;
+    int		*r_palette;
+    int		r_for;
+    int		r_bac;
+    char	*r_workarea;
+    int		r_magx;
+    int		r_magy;
+    int		r_xsize;
+    int		r_ysize;
+    int		r_mode;
+}
+zap_redraw_block;
+
+/* Other globals */
+
+static int	zap_redraw_initialised = FALSE;
+static int	zap_redraw_update_colours;
+static int	zap_redraw_colours[2];
+static int	zap_redraw_palette[16];
+
+/* Holds the current Zap font file(s).
+ * The font is recreated from this block on a mode change.
+ * When using zap, element ZAP_NORMAL is always valid, but
+ * the others can be NULL.
+ */
+
+#define ZAP_NORMAL  0
+#define ZAP_BOLD    1
+#define ZAP_ITALIC  2
+#define ZAP_BITALIC 3
+#define ZAP_STYLES  4
+
+/* Zap font file format data */
+static char	*zap_file[ZAP_STYLES] = {NULL, NULL, NULL, NULL};
+
+/* r_caddr format for current mode */
+static char	*zap_caddr[ZAP_STYLES] = {NULL, NULL, NULL, NULL};
+
+static void ro_remove_menu(int *menu);
+
+/*
+ * Initialise all the ZapRedraw stuff.
+ * Call this when changing font and after each mode change.
+ * zap_redraw_bitmap must contain a valid Zap font file (possibly
+ * created from the system font).
+ *
+ * Return FAIL to revert to system font (if we can't use ZapRedraw).
+ */
+    int
+ro_zap_redraw_initialise()
+{
+    int	    bytes_per_bitmap_char;
+    int	    first, last;
+    int	    i;
+
+    /* Can't have initialisers for struct members :-(, ok, this way then ... */
+    if (!zap_redraw_initialised)
+    {
+	zap_redraw_block.r_workarea = NULL;
+	zap_redraw_initialised = TRUE;
+    }
+
+    /* We redraw in DSA mode */
+    zap_redraw_block.r_flags = 0x0;
+
+    /* Let ZapRedraw get the screen address for us */
+    zap_redraw_block.r_screen = 0;
+
+    /* Read the font width and height from the font file header.
+     * Assume that all styles are the same size.
+     * ZAP_NORMAL is always present.
+     */
+    zap_redraw_block.r_charw = ((int *) zap_file[ZAP_NORMAL])[2];
+    zap_redraw_block.r_charh = ((int *) zap_file[ZAP_NORMAL])[3];
+
+    /* We have no linespacing */
+    zap_redraw_block.r_linesp = 0;
+
+    /* Fix foreground = colour 1 */
+    zap_redraw_block.r_for = 1;
+
+    /* Fix background = colour 0 */
+    zap_redraw_block.r_bac = 0;
+
+    /* Colour mask buffer */
+    zap_redraw_block.r_palette = zap_redraw_palette;
+
+    /* Allocate local workspace (for the few calls following here) */
+    if (zap_redraw_block.r_workarea != NULL)
+	free(zap_redraw_block.r_workarea);
+    zap_redraw_block.r_workarea = (char*) malloc(128);
+    if (!zap_redraw_block.r_workarea)
+	return FAIL;	/* Out of memory */
+
+    /* Fill in VDU variables */
+    if (xswi(ZapRedraw_ReadVduVars, 0, &zap_redraw_block) & v_flag)
+	return FAIL;	    /* Can't find ZapRedraw module - use VDU instead */
+
+    /* Determine cbpl and cbpc */
+    swi(ZapRedraw_CachedCharSize, zap_redraw_block.r_bpp, 0,
+	zap_redraw_block.r_charw, zap_redraw_block.r_charh);
+    zap_redraw_block.r_cbpl = r2;
+    zap_redraw_block.r_cbpc = r3;
+
+    /* Allocate general workspace (for the calls outside) */
+    if (zap_redraw_block.r_workarea != NULL)
+	free(zap_redraw_block.r_workarea);
+    zap_redraw_block.r_workarea = (char*) malloc(128 + zap_redraw_block.r_cbpl);
+    if (!zap_redraw_block.r_workarea)
+	return FAIL;	/* Out of memory */
+
+    /* Now convert the 1 bpp character data ready for the current mode */
+
+    bytes_per_bitmap_char = (zap_redraw_block.r_charw * zap_redraw_block.r_charh + 7) / 8;
+
+    /* Convert the fonts from 1bpp to a format suitable for the
+     * current mode.
+     */
+    for (i = 0; i < ZAP_STYLES; i++)
+    {
+	first = ((int *) zap_file[i])[4];
+	last  = ((int *) zap_file[i])[5];
+
+	if (last > 255)
+	    last = 255;	/* Don't convert cursors (overwrites memory!) */
+
+	/* Allocate the font cache */
+	vim_free(zap_caddr[i]);
+	if (zap_file[i])
+	    zap_caddr[i] = (char*) malloc(zap_redraw_block.r_cbpc * 256);
+	else
+	    zap_caddr[i] = NULL;    /* No file for this style */
+
+	if (zap_caddr[i])
+	{
+	    zap_redraw_block.r_caddr = zap_caddr[i];
+
+	    swi(ZapRedraw_ConvertBitmap, 0, &zap_redraw_block,
+		    first, last,		/* Range of characters to convert */
+		    zap_file[i] + 0x20	/* Addr of first char provided by font */
+		    - first * bytes_per_bitmap_char);
+	}
+    }
+
+    if (!zap_caddr[ZAP_NORMAL])
+    {
+	zap_redraw = FALSE;	/* Out of memory */
+	return FAIL;
+    }
+
+    /* Next time we need them, we have to update the colour masks */
+    zap_redraw_update_colours = TRUE;
+
+    return OK;
+}
+
+/*
+ * Redraw a string at OS coordinates <x,y> (top-left, x inclusive, y exclusive).
+ * Graphics clip window is window[0..3] as in R1+28..40 of Wimp_RedrawWindow.
+ * Returns (possibly modified) flags.
+ */
+    int
+ro_zap_redraw_draw_string(x, y, string, length, flags, clip)
+    int	    x;
+    int	    y;
+    char    *string;
+    int	    length;
+    int	    flags;	/* DRAW_TRANSP, DRAW_BOLD, DRAW_UNDERL, DRAW_ITALIC */
+    int	    *clip;
+{
+    char redraw_data[1024];
+    int clip_minx;
+    int clip_miny;
+    int clip_maxx;
+    int clip_maxy;
+    int os_xshift = zap_redraw_block.r_magx;
+    int os_yshift = zap_redraw_block.r_magy;
+
+    if (flags & DRAW_TRANSP)
+	return flags;	/* We don't do transparent plotting yet. */
+
+    if (flags & DRAW_BOLD)
+    {
+	if (flags & DRAW_ITALIC && zap_caddr[ZAP_BITALIC])
+	    zap_redraw_block.r_caddr = zap_caddr[ZAP_BITALIC];
+	else
+	    zap_redraw_block.r_caddr = zap_caddr[ZAP_BOLD];
+    }
+    else
+    {
+	if (flags & DRAW_ITALIC)
+	    zap_redraw_block.r_caddr = zap_caddr[ZAP_ITALIC];
+	else
+	    zap_redraw_block.r_caddr = zap_caddr[ZAP_NORMAL];
+    }
+    if (!zap_redraw_block.r_caddr)
+    {
+	zap_redraw_block.r_caddr = zap_caddr[ZAP_NORMAL];
+	flags |= DRAW_UNDERL;	    /* Style missing - we can always underline */
+    }
+
+    /* Set the vertical scaling flag */
+    if (double_height)
+	zap_redraw_block.r_flags = 1 << 1;
+    else
+	zap_redraw_block.r_flags = 0;
+
+    /* Update the colour masks (if needed) */
+    if (zap_redraw_update_colours)
+    {
+	swi(ZapRedraw_CreatePalette, 2,
+		&zap_redraw_block,
+		zap_redraw_colours,
+		zap_redraw_block.r_palette, 2);
+	zap_redraw_update_colours = FALSE;
+    }
+
+    /* Target rectangle in ZapRedraw rectangle coordinates (pixels, Y-min/max reversed !!!) */
+    zap_redraw_block.r_minx = x >> os_xshift;					/* inclusive */
+    zap_redraw_block.r_miny = zap_redraw_block.r_ysize - (y >> os_yshift);	/* inclusive */
+    zap_redraw_block.r_maxx = (x + length * gui.char_width) >> os_xshift;	/* exclusive */
+    zap_redraw_block.r_maxy = zap_redraw_block.r_ysize - ((y - gui.char_height) >> os_yshift);
+										/* exclusive */
+
+    /* Clip rectangle in ZapRedraw rectangle coordinates (pixels, Y-min/max reversed !!!) */
+    clip_minx = clip[0] >> os_xshift;					/* inclusive */
+    clip_miny = zap_redraw_block.r_ysize - (clip[3] >> os_yshift);	/* inclusive */
+    clip_maxx = clip[2] >> os_xshift;					/* exclusive */
+    clip_maxy = zap_redraw_block.r_ysize - (clip[1] >> os_yshift);	/* exclusive */
+
+    /* Clip target rectangle against the current graphics window */
+    if (zap_redraw_block.r_minx < clip_minx)
+    {
+	zap_redraw_block.r_scrollx = clip_minx - zap_redraw_block.r_minx;
+	zap_redraw_block.r_minx = clip_minx;
+    }
+    else
+	zap_redraw_block.r_scrollx = 0;
+    if (zap_redraw_block.r_miny < clip_miny)
+    {
+	zap_redraw_block.r_scrolly = clip_miny - zap_redraw_block.r_miny;
+	zap_redraw_block.r_miny = clip_miny;
+    }
+    else
+	zap_redraw_block.r_scrolly = 0;
+    if (zap_redraw_block.r_maxx > clip_maxx)
+	zap_redraw_block.r_maxx = clip_maxx;
+    if (zap_redraw_block.r_maxy > clip_maxy)
+	zap_redraw_block.r_maxy = clip_maxy;
+
+    /* Fill in the character data structure */
+    if (length > (sizeof(redraw_data) - 2 * 4 - 2))
+	length = sizeof(redraw_data) - 2 * 4 - 2;
+    ((int*) redraw_data)[0] = 2 * 4;
+    ((int*) redraw_data)[1] = 0;
+    strncpy(redraw_data + 2 * 4, string, length);
+    redraw_data[2 * 4 + length + 0] = '\0';
+    redraw_data[2 * 4 + length + 1] = '\x2';
+    zap_redraw_block.r_data = (int) redraw_data;
+
+    /* Perform the draw */
+    swi(ZapRedraw_RedrawArea, 0, &zap_redraw_block);
+
+    return flags;
+}
+
+/*
+ * Okay that was it from me, back to Thomas ...
+ */
+
+/*
+ * 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)
+{
+    int	    arg = 1;
+
+    while (arg < *argc - 1)
+    {
+	if (strcmp(argv[arg], "--rows") == 0 || strcmp(argv[arg], "--columns") == 0)
+	{
+	    int	    value;
+
+	    value = atoi(argv[arg + 1]);
+
+	    if (argv[arg][2] == 'r')
+		default_rows = value;
+	    else
+		default_columns = value;
+
+	    /* Delete argument from argv[]. (hope this is read/write!) */
+
+	    *argc -= 2;
+	    if (*argc > arg)
+	    mch_memmove(&argv[arg], &argv[arg + 2], (*argc - arg)
+		    * sizeof(char *));
+	}
+	else
+	    arg++;
+    }
+}
+
+/* Fatal error on initialisation - report it and die. */
+    void
+ro_die(error)
+    char_u *error;	/* RISC OS error block */
+{
+    swi(Wimp_ReportError, error, 5, "GVim");
+    exit(EXIT_FAILURE);
+}
+
+/* Find the sizes of the window tools:
+ *
+ * Create a test window.
+ * Find inner and outer sizes.
+ * Find the difference.
+ * Delete window.
+ *
+ * While we're here, find the eigen values too.
+ */
+    void
+ro_measure_tools()
+{
+    int block[10];
+    int vdu[] = { 4, 5, -1};
+    int test_window[] =
+	{
+	    -100, -100,		/* Visible area : min X,Y */
+	    -50, -50,		/*		  max X,Y */
+	    0,   0,		/* Scroll offsets */
+	    -1,			/* Window in front */
+	    0xd0800150,		/* Window flags */
+	    0xff070207,		/* Colours */
+	    0x000c0103,		/* More colours */
+	    0, -0x4000,		/* Workarea extent */
+	    0x4000, 0,		/* max X,Y */
+	    0x00000000,		/* No title */
+	    0 << 12,		/* No workarea button type */
+	    1,			/* Wimp sprite area */
+	    0x00010001,		/* Minimum width, height */
+	    0, 0, 0,		/* Title data (none) */
+	    0			/* No icons */
+	};
+    int inner_max_x, inner_min_y;
+
+    swi(Wimp_CreateWindow, 0, test_window);
+
+    block[0] = r0;
+    /* Open the window (and read state).
+     * GetWindowOutline needs it too if the wimp isn't nested.
+     */
+    swi(Wimp_OpenWindow, 0, block);
+    inner_max_x = block[3];
+    inner_min_y = block[2];
+
+    swi(Wimp_GetWindowOutline, 0, block);
+
+    gui.scrollbar_width = block[3] - inner_max_x;
+    gui.scrollbar_height = inner_min_y - block[2];
+
+    swi(Wimp_DeleteWindow, 0, block);
+
+    /* Read the size of one pixel. */
+    swi(OS_ReadVduVariables, vdu, vdu);
+    x_eigen_factor = vdu[0];
+    y_eigen_factor = vdu[1];
+}
+
+/* Load a template from the current templates file.
+ * Create the window and return its handle.
+ */
+    int
+ro_load_template(str_name, title, title_size)
+    char_u  *str_name;      /* Identifier of window in file (max 12 chars)   */
+    char_u  **title;	    /* If not NULL then return pointer to title here */
+    int     *title_size;    /* If not NULL then return the title length here */
+{
+    int     *window;
+    char    *data;
+    int     name[4];
+
+    strcpy( (char *) name, str_name);
+
+    /* Find how big we must make the buffers */
+
+    if (xswi(Wimp_LoadTemplate, 0, 0, 0, 0, -1, name, 0) & v_flag)
+	ro_die( (char *) r0);
+
+    window = malloc(r1);	/* Don't print text messages from alloc() */
+    data = malloc(r2);
+    if (window == NULL || data == NULL)
+	ro_die("\0\0\0\0Out of memory - Can't load templates");
+
+    /* Load the template into the buffers */
+
+    swi(Wimp_LoadTemplate, 0,
+				window,		/* Temp block */
+				data,		/* Icon data */
+				data + r2 + 1,	/* End of icon data */
+				-1,		/* No fonts */
+				name, 0);	/* First match */
+    if (r6 == 0)
+	ro_die("\0\0\0\0Can't find window in Templates file");
+
+    /* Create the window */
+
+    if (xswi(Wimp_CreateWindow, 0, window) & v_flag)
+	ro_die( (char *) r0);
+
+    if (title)
+	*title = (char_u *) window[18];
+    if (title_size)
+	*title_size = window[20];
+
+    free(window);	/* Free temp block */
+    return r0;		/* Return the window handle */
+}
+
+/*
+ * Check if the GUI can be started.  Called before gvimrc is sourced.
+ * Return OK or FAIL.
+ */
+    int
+gui_mch_init_check()
+{
+    return OK;		/* TODO: GUI can always be started? */
+}
+
+/*
+ * Initialise the RISC OS GUI.
+ * Create all the windows.
+ * Returns OK for success, FAIL when the GUI can't be started.
+ */
+    int
+gui_mch_init()
+{
+    int     messages[] = {
+	    1, 2, 3, 4,	/* DataSave, DataSaveAck, DataLoad, DataLoadAck */
+	    8,		/* PreQuit */
+	    0xf,	/* ClaimEntity (for clipboard) */
+	    0x10,	/* DataRequest (for clipboard) */
+	    0x400c1,	/* Mode change */
+	    0x400c3,	/* TaskCloseDown */
+	    0x400c9,	/* MenusDeleted */
+	    0x808c1,	/* TW_Output */
+	    0x808c2,    /* TW_Ego */
+	    0x808c3,	/* TW_Morio */
+	    0x808c4,	/* TW_Morite */
+	    0};		/* End-of-list. */
+
+
+    /* There may have been some errors reported in the
+     * command window before we get here. Wait if so.
+     */
+    swi(Wimp_ReadSysInfo, 3);
+    if (r0 == 0)
+	swi(Wimp_CommandWindow, 0);	/* Window opened - close with prompt */
+
+    if (xswi(Wimp_Initialise, 310, 0x4b534154, "GVim", messages) & v_flag)
+	return FAIL;
+    nested_wimp = r0 >= 397;
+    task_handle = r1;
+
+    /* Load the templates. */
+
+    if (xswi(Wimp_OpenTemplate, 0, "Vim:Templates") & v_flag)
+	ro_die( (char *) r0);
+
+    gui.window_handle = ro_load_template("editor",
+	    &gui.window_title,
+	    &gui.window_title_size);
+
+    save_window = ro_load_template("save", NULL, NULL);
+
+    swi(Wimp_CloseTemplate);
+
+    /* Set default foreground and background colours. */
+
+    gui.norm_pixel = gui.def_norm_pixel;
+    gui.back_pixel = gui.def_back_pixel;
+
+    /* Get the colours from the "Normal" and "Menu" 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 colours for the highlight groups (gui_check_colors() might have
+     * changed them) */
+
+    highlight_gui_started();		/* re-init colours and fonts */
+
+    /* Set geometry based on values read on initialisation. */
+
+    gui.num_cols = Columns = default_columns;
+    gui.num_rows = Rows    = default_rows;
+
+    /* Get some information about our environment. */
+
+    ro_measure_tools();
+
+    return OK;
+}
+
+/*
+ * Called when the foreground or background colour has been changed.
+ */
+    void
+gui_mch_new_colors()
+{
+}
+
+/*
+ * Open the GUI window which was created by a call to gui_mch_init().
+ */
+    int
+gui_mch_open(void)
+{
+    int block[10];
+
+    block[0] = gui.window_handle;
+    swi(Wimp_GetWindowState, 0, block);
+    block[7] = -1;		    /* Open at the top of the stack */
+    swi(Wimp_OpenWindow, 0, block);
+
+    /* Give the new window the input focus */
+    swi(Wimp_SetCaretPosition, gui.window_handle, -1, 0, 0, -1, -1);
+
+    if (gui_win_x != -1 && gui_win_y != -1)
+	gui_mch_set_winpos(gui_win_x, gui_win_y);
+
+    return OK;
+}
+
+    void
+gui_mch_exit(int rc)
+{
+    int	    block[64];
+
+    /* Close window. Stops us from getting troublesome events
+     * if we take a while to die.
+     */
+    block[0] = gui.window_handle;
+    swi(Wimp_CloseWindow, 0, block);
+
+    if (child_handle)
+    {
+	/* We still have a sub-task running - kill it */
+	block[0] = 20;
+	block[3] = 0;
+	block[4] = 0;	    /* Quit */
+	if ((xswi(Wimp_SendMessage, 17, block, child_handle) & v_flag) == 0)
+	{
+	    /* Idle until child dies. */
+	    while (child_handle)
+	    {
+		process_event(wimp_poll(1, block), block);
+	    }
+	}
+    }
+
+    exit(rc);
+}
+
+/*
+ * 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 */
+}
+
+    void
+gui_mch_set_shellsize(width, height, min_width, min_height, base_width, base_height)
+    int width;		/* In OS units */
+    int height;
+    int min_width;	/* Smallest permissable window size (ignored) */
+    int min_height;
+    int base_width;	/* Space for scroll bars, etc */
+    int base_height;
+{
+    int s_width, s_height;
+    int block[] = {
+	gui.window_handle,
+	0,
+	-height + 1,
+	width,
+	1};
+
+    gui_mch_get_screen_dimensions(&s_width, &s_height);
+    s_width -= base_width;
+    s_height -= base_height;		    /* Underestimate - ignores titlebar */
+
+    swi(Wimp_GetWindowState, 0, block);
+    block[3]  = block[1] + width;
+    block[2]  = block[4] - height;
+    if (block[3] > s_width)
+    {
+	block[3] = s_width;
+	block[1] = block[3] - width;
+    }
+    if (block[2] < gui.scrollbar_height)
+    {
+	block[2] = gui.scrollbar_height;
+	block[4] = block[2] + height;
+    }
+    swi(Wimp_OpenWindow, 0, block);
+    swi(Wimp_ForceRedraw, gui.window_handle, 0, -height, width, 0);
+}
+
+    void
+gui_mch_get_screen_dimensions(int *screen_w, int *screen_h)
+{
+    int block[] = {4, 5, 11, 12, -1};
+
+    swi(OS_ReadVduVariables, block, block);
+    *screen_w = (block[2] + 1) << block[0];
+    *screen_h = (block[3] + 1) << block[1];
+}
+
+/* Take a font name with options and return a font handle, or
+ * zero for failure.
+ * Replace extension with 'Bold' or 'Italic' depending on modifiers.
+ */
+    int
+ro_get_font(fullname, weight)
+    char_u	*fullname;
+    int		weight;		/* Initial weights:
+				 * BIT	    MEANING
+				 * 0	    bold
+				 * 1	    italic
+				 */
+{
+    char_u	*arg;
+    char_u	font[41];
+    int		width = -1;
+    int		height = -1;
+    int		name_len;
+    int		i;
+    char_u	c;
+
+    for (i = 0; i < 39;)
+    {
+	c = fullname[i];
+	if (c == ':' || c == NUL || c == '.')
+	    break;
+	font[i++] = c;
+    }
+
+    /* find the first modifier, NULL if none */
+    arg = strchr(fullname + i, ':');
+
+    while (arg)
+    {
+	switch (*++arg)
+	{
+	    case 'h':
+		height = strtol(arg + 1, (char **) &arg, 10);
+		break;
+	    case 'w':
+		width = strtol(arg + 1, (char **) &arg, 10);
+		break;
+	    case 'b':
+		weight |= 1;
+		break;
+	    case 'i':
+		weight |= 2;
+		break;
+	    default:
+		return 0;
+	}
+	arg = strchr(arg, ':');
+    }
+
+    if ((weight & 1) && i < 35)
+    {
+	/* Bold goes instead of given suffix */
+	strncpy(font + i, ".Bold", 5);
+	i += 5;
+    }
+    else
+    {
+	/* Copy rest of name unless we are using Bold */
+	while (i < 39)
+	{
+	    c = fullname[i];
+	    if (c == ':' || c == NUL)
+		break;
+	    font[i++] = c;
+	}
+    }
+    if ((weight & 2) && i < 32)
+    {
+	strncpy(font + i, ".Oblique", 8);
+	i += 8;
+    }
+
+    font[i] = 0;
+
+    if (height < 1 && width < 1)
+	height = width = 10;	/* Default to 10pt */
+    else if (height < 1)
+	height = width;
+    else if (width < 1)
+	width = height;
+
+    if (xswi(Font_FindFont, 0, font, width << 4, height << 4, 0, 0) & v_flag)
+	return NOFONT;		/* Can't find font */
+
+    return r0;
+}
+
+/* Load a file into allocated memory and check it is valid.
+ * Return a pointer to the allocated block on success.
+ */
+    char    *
+zap_load_file(name, style)
+    char_u  *name;	    /* Name of directory containing styles */
+    char_u  *style;	    /* Name of style within directory */
+{
+    char_u  fname[256];
+    char_u  *file;
+
+    if (strlen(name) + strlen(style) > 254)
+	return NULL;	    /* Names too long */
+
+    sprintf(fname, "%s.%s", name, style);
+
+    /* Load the named font in 1bpp format. */
+    if (xswi(OS_File, 13, fname, 0, 0, "VimFonts:") & v_flag || r0 != 1)
+	return NULL;	    /* Error reading file info, or not a file */
+
+    /* Allocate enough memory to load the whole file */
+    file = (char *) alloc(r4);
+    if (!file)
+	return NULL;	/* Out of memory */
+
+    if (xswi(OS_File, 12, fname, file, 0, "VimFonts:") & v_flag)
+	return NULL;	/* Unable to load file */
+
+    if (strncmp(file, "ZapFont\015", 8) == 0)
+	return file;	/* Loaded OK! */
+
+    free(file);
+    return NULL;	/* Not a valid font file */
+}
+
+/* Load and convert the named font.
+ * If name is NULL or a null string then convert the system font.
+ * Return OK on success; FAIL and we revert to using the VDU drivers.
+ *
+ * 'name' is the name of a directory.
+ * Tries to load 'name.0', 'name.B', 'name.I' and 'name.IB'.
+ */
+    int
+zap_load_font(name)
+    char_u  *name;
+{
+    int	    i;
+
+    /* Free the existing font files, if any */
+    for (i = 0; i < ZAP_STYLES; i++)
+    {
+	vim_free(zap_file[i]);
+	zap_file[i] = NULL;
+    }
+
+    if (name && *name == '!')
+    {
+	name++;
+	double_height = TRUE;
+    }
+    else
+	double_height = FALSE;
+
+    if (name && *name)
+    {
+	zap_file[ZAP_NORMAL]	= zap_load_file(name, "0");
+	if (!zap_file[ZAP_NORMAL])
+	    return FAIL;	/* Can't load the 'normal' style - error */
+
+	zap_file[ZAP_BOLD]	= zap_load_file(name, "B");
+	zap_file[ZAP_ITALIC]	= zap_load_file(name, "I");
+	zap_file[ZAP_BITALIC]	= zap_load_file(name, "IB");
+    }
+    else
+    {
+	int	*header;
+	char	workarea[16];
+	char	*old_wa;
+
+	/* Allocate memory for system font (8 x 8 x 256 bits, plus header) */
+	header = (int *) alloc(0x20 + 8 * 256);
+	if (header == NULL)
+	    return FAIL;
+	zap_file[ZAP_NORMAL] = (char *) header;
+
+	/* Store details about the system font */
+	header[2] = 8;	    /* Width */
+	header[3] = 8;	    /* Height */
+	header[4] = 0;	    /* First char */
+	header[5] = 255;    /* Last char */
+	header[6] = header[7] = 0;  /* Reserved */
+
+	/* Get system font bitmap */
+	old_wa = zap_redraw_block.r_workarea;
+	zap_redraw_block.r_workarea = workarea;
+	swi(ZapRedraw_ReadSystemChars, zap_file[ZAP_NORMAL] + 0x20, &zap_redraw_block);
+	zap_redraw_block.r_workarea = old_wa;
+    }
+
+    return ro_zap_redraw_initialise();
+}
+
+/*
+ * 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)
+{
+    int	    new_handle	= 0;	    /* Use the system font by default */
+
+    if (font_name[0] == '!')
+    {
+	/* Select a ZapRedraw font */
+	if (zap_load_font(font_name + 1))
+	    zap_redraw = TRUE;
+	else
+	{
+	    EMSG2(_("E610: Can't load Zap font '%s'"), font_name);
+	    font_name = "System";   /* Error - use system font */
+	    zap_redraw = FALSE;
+	}
+    }
+    else
+    {
+	zap_redraw = FALSE;
+
+	if (font_name)
+	{
+	    /* Extract any extra details about the font */
+	    new_handle = ro_get_font(font_name, 0);
+	    if (!new_handle)
+		return FAIL;
+	}
+	else
+	    font_name = "System";
+    }
+
+    /* Free the previous font, if any */
+    gui_mch_free_font(gui.norm_font);
+    gui.norm_font = new_handle;
+    gui.char_ascent = 0;
+
+    if (new_handle)
+    {
+	/* Read details about the chosen font */
+	swi(Font_ReadInfo, new_handle);
+
+	gui.char_width	= r3 - r1;
+	gui.char_height = r4 - r2;
+
+	font_x_offset = -r1;	/* Where to position each char in its box */
+	font_y_offset = -r4;
+
+	/* Try to load other fonts for bold, italic, and bold-italic */
+	gui_mch_free_font(gui.bold_font);
+	gui.bold_font = ro_get_font(font_name, 1);
+	gui_mch_free_font(gui.ital_font);
+	gui.ital_font = ro_get_font(font_name, 2);
+	gui_mch_free_font(gui.boldital_font);
+	gui.boldital_font = ro_get_font(font_name, 3);
+    }
+    else
+    {
+	/* Use the system font or ZapRedraw. */
+	if (zap_redraw)
+	{
+	    gui.char_width	= zap_redraw_block.r_charw << zap_redraw_block.r_magx;
+	    gui.char_height	= zap_redraw_block.r_charh << zap_redraw_block.r_magy;
+	    if (double_height)
+		gui.char_height <<= 1;
+	}
+	else
+	{
+	    gui.char_width	= 16;
+	    gui.char_height	= 32;
+	}
+
+	gui_mch_free_font(gui.bold_font);
+	gui.bold_font = 0;
+	gui_mch_free_font(gui.ital_font);
+	gui.ital_font = 0;
+	gui_mch_free_font(gui.boldital_font);
+	gui.boldital_font = 0;
+    }
+    hl_set_font_name(font_name);
+
+    must_redraw = CLEAR;
+    return OK;
+}
+
+    int
+gui_mch_adjust_charsize()
+{
+    return FAIL;
+}
+
+/*
+ * Get a font structure for highlighting.
+ */
+    GuiFont
+gui_mch_get_font(name, giveErrorIfMissing)
+    char_u	*name;
+    int		giveErrorIfMissing;
+{
+    int		handle;
+
+    if (!name)
+	return NOFONT;		/* System font if no name */
+
+    handle = ro_get_font(name, 0);
+    if (!handle)
+    {
+	if (giveErrorIfMissing)
+	    EMSG2(_("E611: Can't use font %s"), name);
+	return NOFONT;
+    }
+
+    return handle;
+}
+
+/*
+ * Set the current text font.
+ */
+    void
+gui_mch_set_font(GuiFont font)
+{
+    ro_current_font = font;
+
+    if (font)
+    {
+	/* Not the system font or ZapRedraw font - select it */
+	swi(Font_SetFont, font);
+    }
+}
+
+#if 0 /* not used */
+/*
+ * Return TRUE if the two fonts given are equivalent.
+ */
+    int
+gui_mch_same_font(GuiFont f1, GuiFont f2)
+{
+    return f1 == f2;
+}
+#endif
+
+/*
+ * If a font is not going to be used, free its structure.
+ */
+    void
+gui_mch_free_font(GuiFont font)
+{
+    if (font)
+	swi(Font_LoseFont, font);
+}
+
+/*
+ * Return the Pixel value (colour) for the given colour name.
+ * Return INVALCOLOR for error.
+ * NB: I've changed Green for now, since it looked really sick
+ */
+    guicolor_T
+gui_mch_get_color(char_u *name)
+{
+    int		i;
+    struct colour
+    {
+	char_u		*name;
+	guicolor_T	value;
+    } colours[] =
+    {
+	{ "Red",		grgb(255,	0,	0)	},
+	{ "LightRed",		grgb(255,	0,	0)	},
+	{ "DarkRed",		grgb(139,	0,	0)	},
+
+	{ "Green",		grgb(50,	200,	50)	},
+	{ "LightGreen",		grgb(144,	238,	144)	},
+	{ "DarkGreen",		grgb(0,		100,	0)	},
+	{ "SeaGreen",		grgb(46,	139,	87)	},
+
+	{ "Blue",		grgb(0,		0,	255)	},
+	{ "LightBlue",		grgb(173,	216,	230)	},
+	{ "DarkBlue",		grgb(0,		0,	139)	},
+	{ "SlateBlue",		grgb(160,	90,	205)	},
+
+	{ "Cyan",		grgb(0,		255,	255)	},
+	{ "LightCyan",		grgb(224,	255,	255)	},
+	{ "DarkCyan",		grgb(0,		139,	139)	},
+
+	{ "Magenta",		grgb(255,	0,	255)	},
+	{ "LightMagenta",	grgb(255,	224,	255)	},
+	{ "DarkMagenta",	grgb(139,	0,	139)	},
+
+	{ "Yellow",		grgb(255,	255,	0)	},
+	{ "LightYellow",	grgb(255,	255,	224)	},
+	{ "DarkYellow",		grgb(139,	139,	0)	},
+	{ "Brown",		grgb(165,	42,	42)	},
+
+	{ "Gray",		grgb(190,	190,	190)	},
+	{ "Grey",		grgb(190,	190,	190)	},
+	{ "LightGray",		grgb(211,	211,	211)	},
+	{ "LightGrey",		grgb(211,	211,	211)	},
+	{ "DarkGray",		grgb(169,	169,	169)	},
+	{ "DarkGrey",		grgb(169,	169,	169)	},
+
+	{ "Black",		grgb(0,		0,	0)	},
+	{ "White",		grgb(255,	255,	255)	},
+
+	{ "Orange",		grgb(255,	165,	0)	},
+	{ "Purple",		grgb(160,	32,	240)	},
+	{ "Violet",		grgb(238,	130,	238)	},
+	{NULL, 0}
+    };
+
+    if (name[0] == '#')
+    {
+	char	    *end;
+	int	    c;
+
+	c = strtol(name + 1, &end, 16);
+	return (guicolor_T) ((c >> 16) & 0xff) | (c & 0xff00) | ((c & 0xff) << 16);
+    }
+
+    for (i = 0; colours[i].name != NULL; i++)
+    {
+	if (STRICMP(name, colours[i].name) == 0)
+	    return colours[i].value;
+    }
+    if (strnicmp(name, "grey", 4) == 0 || strnicmp(name, "gray", 4) == 0)
+    {
+	int level = (255 * atoi(name + 4)) / 100;
+	return (guicolor_T) grgb(level, level, level);
+    }
+    return INVALCOLOR;
+}
+
+/*
+ * Set the current text colours.
+ * If we are using fonts then set the antialiasing colours too.
+ */
+    void
+gui_mch_set_colors(guicolor_T fg, guicolor_T bg)
+{
+    zap_redraw_colours[0] = bg << 8;	/* JK230798, register new background colour */
+    zap_redraw_colours[1] = fg << 8;	/* JK230798, register new foreground colour */
+    zap_redraw_update_colours = TRUE;	/* JK230798, need update of colour masks */
+
+    swi(ColourTrans_ReturnGCOL, fg << 8);
+    gui.fg_colour = r0;
+    swi(ColourTrans_ReturnGCOL, bg << 8);
+    gui.bg_colour = r0;
+
+    if (ro_current_font)
+	swi(ColourTrans_SetFontColours, 0, bg << 8, fg << 8, 14);
+}
+
+    void
+ro_draw_string(x, y, s, len, flags, clip)
+    int	    x;		/* Top-left coord to plot at (x incl, y excl) */
+    int	    y;		/* (screen coords) */
+    char_u  *s;		/* String to plot */
+    int	    len;	/* Length of string */
+    int	    flags;	/* DRAW_TRANSP, DRAW_BOLD, DRAW_UNDERL */
+    int*    clip;	/* JK230798, added clip window */
+{
+    if (ro_current_font)
+    {
+	int	fx;
+	int	flen = len;	/* Preserve for underline */
+
+	/* Use the Font manager to paint the string.
+	 * Must do one char at a time to get monospacing.
+	 */
+
+	if (flags & DRAW_ITALIC && !gui.ital_font)
+	    flags |= DRAW_UNDERL;	/* No italic - underline instead */
+
+	if ((flags & DRAW_TRANSP) == 0)
+	{
+	    swi(ColourTrans_SetColour, gui.bg_colour, 0, 0, 0, 0);
+	    swi(OS_Plot, 4, x, y - gui.char_height);
+	    swi(OS_Plot, 96 + 5, x + len * gui.char_width - 1, y - 1);
+	}
+
+	fx = x + font_x_offset;
+	while (flen--)
+	{
+	    swi(Font_Paint, 0, s++, 0x90, fx, y + font_y_offset, 0, 0, 1);
+	    fx += gui.char_width;
+	}
+    }
+    else
+    {
+	if (zap_redraw)
+	{
+	    /* Using fast Zap redraw. */
+	    flags = ro_zap_redraw_draw_string(x, y, s, len, flags, clip);
+	}
+	else
+	{
+	    /* Using the system font */
+	    if (flags & DRAW_ITALIC)
+		flags |= DRAW_UNDERL;
+
+	    if ((flags & DRAW_TRANSP) == 0)
+	    {
+		swi(ColourTrans_SetColour, gui.bg_colour, 0, 0, 0, 0);
+		swi(OS_Plot, 4, x, y - gui.char_height);
+		swi(OS_Plot, 96 + 5, x + len * gui.char_width - 1, y - 1);
+	    }
+	    swi(OS_Plot, 4,			/* Move the drawing cursor */
+		    x,
+		    y - 1);
+	    swi(ColourTrans_SetColour, gui.fg_colour, 0, 0, 0, 0);
+	    swi(OS_WriteN, s, len);
+
+	    if (flags & DRAW_BOLD)
+	    {
+		swi(OS_Plot, 4, x + (1 << x_eigen_factor), y - 1);
+		swi(OS_WriteN, s, len);
+	    }
+	}
+    }
+
+    if (flags & DRAW_UNDERL)
+    {
+	if (ro_current_font || zap_redraw)
+	    swi(ColourTrans_SetColour, gui.fg_colour, 0, 0, 0, 0);
+	/* Underlined is the same with all plotting methods */
+	swi(OS_Plot, 4, x, y - gui.char_height);
+	swi(OS_Plot, 1, gui.char_width * len, 0);
+    }
+}
+
+    void
+gui_mch_draw_string(int row, int col, char_u *s, int len, int flags)
+{
+    int x, y;		/* Workarea x,y */
+    x = col * gui.char_width;
+    y = -row * gui.char_height;
+
+    if (redraw_block)
+    {
+	ro_draw_string(x + redraw_block[1], y + redraw_block[4],
+			s, len, flags, &redraw_block[7]);	/* JK230798, added clip window */
+    }
+    else
+    {
+	int block[44];
+	block[0] = gui.window_handle;
+	block[1] = x;
+	block[2] = y - gui.char_height;
+	block[3] = (col + len) * gui.char_width;
+	block[4] = y;
+	swi(Wimp_UpdateWindow, 0, block);
+	while (r0)
+	{
+	    ro_draw_string(x + block[1], y + block[4],
+			s, len, flags, &block[7]);	/* JK230798, added clip window */
+	    swi(Wimp_GetRectangle, 0, block);
+	}
+    }
+}
+
+/*
+ * Return OK if the key with the termcap name "name" is supported.
+ */
+    int
+gui_mch_haskey(char_u *name)
+{
+    return FAIL;
+}
+
+    void
+gui_mch_beep(void)
+{
+    swi(OS_WriteI + 7);
+}
+
+/*
+ * Visual bell.
+ */
+    void
+gui_mch_flash(int msec)
+{
+    /* TODO */
+}
+
+
+/*
+ * Plot a solid rectangle using the given plot action and colour.
+ * Coordinates are inclusive and window-relative.
+ */
+    void
+plot_rectangle(plot, colour, minx, miny, maxx, maxy)
+    int plot;		/* OS_Plot action */
+    int colour;
+    int minx;
+    int miny;
+    int maxx;
+    int maxy;
+{
+    if (redraw_block)
+    {
+	swi(ColourTrans_SetColour, colour, 0, 0, 0, 0);
+	swi(OS_Plot, 4, minx + redraw_block[1], miny + redraw_block[4]);
+	swi(OS_Plot, plot, maxx + redraw_block[1], maxy + redraw_block[4]);
+    }
+    else
+    {
+	int block[44];
+	block[0] = gui.window_handle;
+	block[1] = minx;
+	block[2] = miny;
+	block[3] = maxx + 1;
+	block[4] = maxy + 1;
+	swi(Wimp_UpdateWindow, 0, block);
+	while (r0)
+	{
+	    swi(ColourTrans_SetColour, colour, 0, 0, 0, 0);
+	    swi(OS_Plot, 4, minx + block[1], miny + block[4]);
+	    swi(OS_Plot, plot, maxx + block[1], maxy + block[4]);
+	    swi(Wimp_GetRectangle, 0, block);
+	}
+    }
+}
+
+/*
+ * 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)
+{
+    plot_rectangle(96 + 6, 0, FILL_X(c), -FILL_Y(r + nr), FILL_X(c + nc), -FILL_Y(r));
+}
+
+/*
+ * Iconify the GUI window.
+ */
+    void
+gui_mch_iconify(void)
+{
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Bring the Vim window to the foreground.
+ */
+    void
+gui_mch_set_foreground()
+{
+    /* TODO */
+}
+#endif
+
+/* Draw a hollow rectangle relative to the current
+ * graphics cursor position, with the given width
+ * and height. Start position is top-left.
+ */
+    void
+draw_hollow(w, h)
+    int	w;
+    int	h;
+{
+    swi(OS_Plot, 1, w - 1, 0);
+    swi(OS_Plot, 1, 0, 1 - h);
+    swi(OS_Plot, 1, 1 - w, 0);
+    swi(OS_Plot, 1, 0, h - 1);
+}
+
+/*
+ * Draw a cursor without focus.
+ */
+    void
+gui_mch_draw_hollow_cursor(guicolor_T colour)
+{
+    int x = FILL_X(gui.cursor_col);	/* Window relative, top-left */
+    int y = -FILL_Y(gui.cursor_row);
+    if (redraw_block == NULL)
+    {
+	int block[11];
+
+	block[0] = gui.window_handle;
+	block[1] = x;
+	block[2] = y - gui.char_height;
+	block[3] = x + gui.char_width;
+	block[4] = y;
+	swi(Wimp_UpdateWindow, 0, block);
+	while (r0)
+	{
+	    swi(ColourTrans_SetGCOL, colour << 8, 0, 0, 0, 0);
+
+	    swi(OS_Plot, 4, x + block[1], y + block[4] - 1);
+	    draw_hollow(gui.char_width, gui.char_height);
+
+	    swi(Wimp_GetRectangle, 0, block);
+	}
+    }
+    else
+    {
+	swi(ColourTrans_SetGCOL, colour << 8, 0, 0, 0, 0);
+
+	swi(OS_Plot, 4, x + redraw_block[1], y + redraw_block[4] - 1);
+	draw_hollow(gui.char_width, gui.char_height);
+    }
+}
+
+/*
+ * Draw part of a cursor, "w" pixels wide, and "h" pixels high, using
+ * color "color".
+ */
+    void
+gui_mch_draw_part_cursor(w, h, colour)
+    int w;
+    int h;
+    guicolor_T colour;
+{
+    int x = FILL_X(gui.cursor_col);
+    int y = -FILL_Y(gui.cursor_row);
+    swi(ColourTrans_ReturnGCOL, colour << 8);
+    plot_rectangle(96 + 5, r0, x, y - h, x + w - 1, y - 1);
+}
+
+/*
+ * 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 (well, after a Wimp_Poll).
+ */
+    void
+gui_mch_update(void)
+{
+    int block[64];
+    int reason;
+
+    swi(OS_ReadMonotonicTime);
+    if ((r0 - time_of_last_poll) < 50)
+	return;			    /* Don't return too often */
+
+    reason = wimp_poll(0, block);
+    if (reason)
+	process_event(reason, block);
+    ro_return_early = FALSE;		/* We're returning anyway. */
+}
+
+    void
+redraw_window(block)
+    int *block;
+{
+    int x, y;			/* Vim workarea coords */
+    int width, height;
+    int blank_col;
+
+    swi(ColourTrans_ReturnGCOL, UNUSED_COLOUR << 8, 0, 0, 1<<7, 0);
+    blank_col = r0;
+
+    swi(Wimp_RedrawWindow, 0, block);
+    redraw_block = block;
+    while (r0)
+    {
+	x = block[7] - block[1];
+	y = block[4] - block[10];
+	width  = block[9]  - block[7];
+	height = block[10] - block[8];
+
+	if (height + y > Rows * gui.char_height)
+	{
+	    /* Blank everything off the bottom. */
+	    plot_rectangle(96 + 5, blank_col,
+				0, block[8] - block[4],
+				block[9] - block[1], -FILL_Y(Rows) - 1);
+	    height = Rows * gui.char_height;
+	}
+	if (width + x> Columns * gui.char_width)
+	{
+	    /* Blank everything off to the right. */
+	    plot_rectangle(96 + 5, blank_col,
+				FILL_X(Columns), block[8] - block[4],
+				block[9] - block[1], 0);
+	    width = Columns * gui.char_width;
+	}
+	gui_redraw(x , y, width, height);
+	swi(Wimp_GetRectangle, 0, block);
+    }
+    redraw_block = NULL;
+}
+
+/* Check if we have modified data.
+ * If we do then ack the message to stop the shutdown.
+ * Otherwise, ignore the message.
+ */
+    void
+ro_prequit(block)
+    int	    *block;
+{
+    if (!ro_ok_to_quit())
+    {
+	/* Not OK to quit - stop shutdown */
+	block[3] = block[2];
+	swi(Wimp_SendMessage, 19, block, block[1]);
+    }
+    /* Do nothing. We may get a Message_Quit later. */
+}
+
+/* If there is unsaved data then ask the user if they mind losing it.
+ * Return TRUE if we can quit without saving, FALSE to halt the
+ * shutdown.
+ */
+    int
+ro_ok_to_quit()
+{
+    int	    old_confirm = cmdmod.confirm;
+
+    cmdmod.confirm = FALSE;	    /* Use our own, single tasking, box */
+
+    if (check_changed_any(FALSE))
+    {
+	swi(Wimp_ReportError,
+		"\0\0\0\0Vim contains unsaved data - quit anyway?",
+		0x17,
+		"Vim");
+	cmdmod.confirm = old_confirm;
+	if (r1 != 1)
+	    return FALSE;
+    }
+    cmdmod.confirm = old_confirm;
+    return TRUE;
+}
+
+/* Quit without checking for unsaved data. */
+    void
+ro_quit()
+{
+    exiting = TRUE;
+    getout(0);
+
+    exiting = FALSE;		    /* probably can't get here */
+    setcursor();		    /* position cursor */
+    out_flush();
+}
+
+/* Insent the given vim special code into the input buffer */
+    void
+ro_press(a, b, modifier)
+    char a;
+    char b;
+    int modifier;	/* %<Ctrl><Shift> 0000 0000 */
+{
+    char_u buf[6];
+    int	    vim_mod;
+    int	    key;
+
+
+    /* Convert RISC OS modifier to Vim modifier. */
+    vim_mod = ((modifier & 0x10) ? MOD_MASK_SHIFT : 0)
+	       | ((modifier & 0x20) ? MOD_MASK_CTRL : 0);
+    key = simplify_key(TERMCAP2KEY(a, b), &vim_mod);
+
+    buf[3] = CSI;
+    buf[4] = KEY2TERMCAP0(key);
+    buf[5] = KEY2TERMCAP1(key);
+    if (vim_mod)
+    {
+	buf[0] = CSI;
+	buf[1] = KS_MODIFIER;
+	buf[2] = vim_mod;
+	add_to_input_buf(buf, 6);
+    }
+    else
+	add_to_input_buf(buf + 3, 3);
+}
+
+/* Take a wimp key code and insert the vim equivalent
+ * into vim's input buffer.
+ * CTRL-C also sets got_int.
+ */
+    void
+ro_insert_key(code)
+    char_u *code;		/* Wimp_ProcessKey code (4 bytes) */
+{
+    char a = code[0];
+    char b = code[1];
+    int base, modifier;
+
+    if (a == 3 && ctrl_c_interrupts)
+	got_int = TRUE;
+
+    /* Is it a normal key? */
+    if (a > 31 && a < 127)
+    {
+	add_to_input_buf(code, 1);
+	return;
+    }
+
+    /* We should pass any unrecognised keys on, but
+     * for now just pass on F12 combinations.
+     */
+    switch (b)
+    {
+	case 0:
+	    /* Home and Delete are the only special cases */
+	    switch (a)
+	    {
+		case 0x1e:
+		    ro_press('k','h', 0);	/* Home */
+		    return;
+		case 0x7f:
+		    ro_press('k','D', 0);	/* Delete */
+		    return;
+		case CSI:
+		    {
+			/* Turn CSI into K_CSI.  Untested! */
+			char_u string[3] = {CSI, KS_EXTRA, KE_CSI};
+
+			add_to_input_buf(string, 3);
+			return;
+		    }
+		default:
+		    add_to_input_buf(code, 1);
+		    return;
+	    }
+	case 1:
+	    if ((a & 0xcf) == 0xcc)
+	    {
+		/* F12 pressed - pass it on (quick hack) */
+		swi(Wimp_ProcessKey, a | 0x100);
+		return;
+	    }
+	    base = a & 0xcf;
+	    modifier = a & 0x30;
+	    switch (base)
+	    {
+		case 0x8a:	/* Tab */
+		    add_to_input_buf("\011", 1);
+		    return;
+		case 0x8b:	/* Copy (End) */
+		    return ro_press('@', '7', modifier);
+		case 0x8c:	/* Left */
+		    return ro_press('k', 'l', modifier);
+		case 0x8d:	/* Right */
+		    return ro_press('k', 'r', modifier);
+		case 0x8e:	/* Down */
+		    if (modifier & 0x10)
+			return ro_press('k', 'N', modifier ^ 0x10);
+		    else
+			return ro_press('k', 'd', modifier);
+		case 0x8f:	/* Up */
+		    if (modifier & 0x10)
+			return ro_press('k', 'P', modifier ^ 0x10);
+		    else
+			return ro_press('k', 'u', modifier);
+		case 0xca:	/* F10 */
+		    return ro_press('k', ';', modifier);
+		case 0xcb:	/* F11 */
+		    return ro_press('F', '1', modifier);
+		case 0xcd:	/* Insert */
+		    return ro_press('k', 'I', modifier);
+		default:
+		    if (base > 0x80 && base < 0x18a)
+		    {
+			/* One of the other function keys */
+			return ro_press('k', '0' + (base & 15), modifier);
+		    }
+	    }
+    }
+}
+
+/* Process a mouse event. */
+    void
+ro_mouse(block)
+    int *block;
+{
+    int x, y, button, vim_button;
+    int modifiers = 0;
+    int min_x, min_y;		/* Visible area of editor window */
+    int max_x, max_y;
+
+    if (block[3] != gui.window_handle || ro_dragging)
+	return;			/* Not our window or ignoring clicks*/
+
+    x = block[0];		/* Click position - screen coords */
+    y = block[1];
+    button = block[2];
+
+    block[0] = gui.window_handle;
+    swi(Wimp_GetWindowState, 0, block);
+    min_x = block[1];
+    min_y = block[2];
+    max_x = block[3];
+    max_y = block[4];
+
+    if (block[3] - x < gui.scrollbar_width)
+    {
+	/* Click in that blank area under the scrollbars */
+
+	if (button & 0x444)
+	{
+	    int	    front_block[10];
+	    /* Dragging with Select - bring window to front first */
+	    front_block[0] = gui.window_handle;
+	    swi(Wimp_GetWindowState, 0, front_block);
+	    front_block[7] = -1;
+	    ro_open_main(front_block);
+	}
+
+	block[0] = gui.window_handle;
+	block[1] = 7;			/* Drag point */
+	block[2] = block[4] = 0;	/* Coords of point. */
+	block[3] = block[5] = 0;
+	drag_x_offset = max_x - x;
+	drag_y_offset = min_y - y;
+
+	/* Parent box. */
+	block[6] = min_x +
+			gui.scrollbar_width * 2 +
+			MIN_COLUMNS * gui.char_width;
+	block[7] = 0;
+	gui_mch_get_screen_dimensions(&block[8], &block[9]);
+	block[9] = max_y -
+			4 * gui.char_height -
+			gui.scrollbar_height;
+
+	swi(Wimp_DragBox, 0, block);
+	ro_dragging = DRAG_RESIZE_WINDOW;
+	drag_button = vim_button;
+	drag_modifiers = modifiers;
+	return;
+    }
+
+    if (button & 0x111)
+	vim_button = MOUSE_RIGHT;
+    else if (button & 0x222)
+	vim_button = MOUSE_MIDDLE;
+    else
+	vim_button = MOUSE_LEFT;
+
+    swi(OS_Byte, 121, 0x80);
+    if (r1 == 0xff)
+	modifiers |= MOUSE_SHIFT;
+    swi(OS_Byte, 121, 0x81);
+    if (r1 == 0xff)
+	modifiers |= MOUSE_CTRL;
+    swi(OS_Byte, 121, 0x82);
+    if (r1 == 0xff)
+	modifiers |= MOUSE_ALT;
+
+    if (button == 2)
+    {
+	/* Menu click:
+	 * If shift was pressed then do the paste action.
+	 * If not, then open the pop-up menu.
+	 */
+	modifiers ^= MOUSE_SHIFT;
+	if (modifiers && MOUSE_SHIFT)
+	{
+	    vimmenu_T	main;
+	    /* Shift was NOT pressed - show menu */
+	    main.dname = (char_u *) "Vim";
+	    main.children = root_menu;
+	    gui_mch_show_popupmenu(&main);
+	    return;
+	}
+    }
+
+    /* Gain the input focus */
+    swi(Wimp_SetCaretPosition, gui.window_handle, -1, 0, 0, -1, -1);
+
+    if (button & 0xf0)
+    {
+	/* Drag operation:
+	 *
+	 * Tell the Wimp to start a drag.
+	 * Monitor null events.
+	 */
+	block[1] = 7;			/* Drag a point. */
+	block[2] = block[4] = x;	/* Coords of point. */
+	block[3] = block[5] = y;
+	block[6] = 0;			/* Coords of bounding box. */
+	block[7] = 0;
+	gui_mch_get_screen_dimensions(&block[8], &block[9]);
+
+	drag_x_offset = drag_y_offset = 0;
+
+	swi(Wimp_DragBox, 0, block);
+	ro_dragging = DRAG_SELECTION;
+	drag_button = vim_button;
+	drag_modifiers = modifiers;
+
+	vim_button |= MOUSE_DRAG;
+    }
+
+    gui_send_mouse_event(
+		vim_button,
+		x - min_x,
+		max_y - y,
+		button & 0xf ? TRUE : FALSE,	/* dclick */
+		modifiers);
+}
+
+    void
+ro_continue_drag(block)
+    int *block;			/* Just used as scrap. */
+{
+    int x, y;
+
+    /* Get screen coords of pointer. */
+    swi(Wimp_GetPointerInfo, 0, block);
+    x = block[0] + drag_x_offset;
+    y = block[1] + drag_y_offset;
+
+    block[0] = gui.window_handle;
+    swi(Wimp_GetWindowState, 0, block);
+
+    if (ro_dragging == DRAG_RESIZE_WINDOW)
+    {
+	/* Resizeing the main window. */
+	block[2] = y;
+	block[3] = x;
+	ro_open_main(block);
+    }
+    else
+    {
+	/* Selecting some text. */
+	gui_send_mouse_event(
+	    drag_button | MOUSE_DRAG,	/* Always report the same button */
+	    x - block[1],
+	    block[4] - y,
+	    FALSE,			/* Not a double click. */
+	    drag_modifiers);
+    }
+}
+
+/* User has released all mouse buttons, marking the end of a drag. */
+    void
+ro_drag_finished(block)
+    int *block;
+{
+    int x;
+    int y;
+    int width, height;
+
+    /* I don't trust the box returned by Wimp_Poll; look at the pointer
+     * ourselves.
+     */
+    swi(Wimp_GetPointerInfo, 0, block);
+    x = block[0] + drag_x_offset;
+    y = block[1] + drag_y_offset;
+
+    if (ro_dragging == DRAG_RESIZE_WINDOW)
+    {
+	block[0] = gui.window_handle;
+	swi(Wimp_GetWindowState, 0, block);
+	block[2] = y;
+	block[3] = x;
+	ro_open_main(block);
+
+	width = (block[3] - block[1]);
+	height = (block[4] - block[2]);
+
+	swi(Wimp_ForceRedraw, gui.window_handle, 0, -height, width, 0);
+	gui_resize_shell(width, height);
+    }
+    else
+    {
+	block[0] = gui.window_handle;
+	swi(Wimp_GetWindowState, 0, block);
+	gui_send_mouse_event(
+		MOUSE_RELEASE,
+		x - block[1],
+		block[4] - y,
+		FALSE,			/* not a double click */
+		drag_modifiers);
+    }
+    ro_dragging = DRAG_FALSE;
+}
+
+/* Load the file/pathname given in block into a [new] buffer.
+ *
+ * Modifier	Action
+ *
+ * None		:confirm e <file>
+ * Ctrl		:sp <file>
+ * Shift	<file>
+ *
+ * Insert into typebuf, at the start.
+ * If loading from !Scrap then use saved leafname instead, and
+ * delete the scrap file. Also, ignore shift key.
+ *
+ * NB: Doesn't send DataLoadAck (other app might delete temp file?).
+ */
+    void
+ro_dataload(block)
+    int	    *block;
+{
+    char_u  new_path[MAXPATHL];
+    char_u  *path = ((char_u *) block) + 44;
+    int	    scrap = FALSE;
+
+    if (block[3] == leaf_ref && leaf_name)
+	scrap = TRUE;
+
+    switch (get_real_state() & 0xff)
+    {
+	case INSERT:
+	case CMDLINE:
+	case CMDLINE+LANGMAP:
+	    /* For insert mode we can only insert the pathname (currently)
+	     * Make sure Shift is pressed.
+	     */
+	    swi(OS_Byte, 121, 0x80);	    /* Is Shift pressed? */
+	    if (r1 == 0xff)
+	    {
+		ins_typebuf(" ", REMAP_NONE, 0, TRUE, FALSE);
+		ins_typebuf(path, REMAP_NONE, 0, TRUE, FALSE);
+		ro_return_early = TRUE;		    /* Return even though nothing was typed. */
+	    }
+	    else
+		swi(Wimp_ReportError,
+			"\0\0\0\0Sorry, you can only load text in normal mode", 5, "Vim");
+	    break;
+
+	case NORMAL:
+	    ro_return_early = TRUE;	    /* Return even though nothing was typed. */
+
+	    if (scrap)			    /* Remove <Wimp$Scrap>. Later. */
+		ins_typebuf(":!~remove <Wimp$Scrap>\r", REMAP_NONE, 0, TRUE, FALSE);
+
+	    /* Insert {:sp ,:confirm e }[+f\ <leaf> ]<file><CR> */
+	    ins_typebuf("\r", REMAP_NONE, 0, TRUE, FALSE);
+	    ins_typebuf(path, REMAP_NONE, 0, TRUE, FALSE);
+	    ins_typebuf(" ", REMAP_NONE, 0, TRUE, FALSE);
+
+	    if (scrap)
+	    {
+		/* Loading via !Scrap - change pathname to stored leafname */
+		ins_typebuf(leaf_name, REMAP_NONE, 0, TRUE, FALSE);
+		ins_typebuf(" +f\\ ", REMAP_NONE, 0, TRUE, FALSE);
+		leaf_ref = 0;
+		vim_free(leaf_name);
+		leaf_name = NULL;
+	    }
+
+	    swi(OS_Byte, 121, 0x81);	    /* Is Ctrl pressed? */
+	    if (r1 == 0xff)
+		/* Yes, split window */
+		ins_typebuf(":sp", REMAP_NONE, 0, TRUE, FALSE);
+	    else
+		ins_typebuf(":confirm e", REMAP_NONE, 0, TRUE, FALSE);
+	    break;
+
+	default:
+	    swi(Wimp_ReportError, "\0\0\0\0You can only load text in normal mode.", 5, "Vim");
+    }
+    /* Send DataSaveAck so other program doesn't think we died
+     * and delete <Wimp$Scrap>.
+     */
+    block[3] = block[2];
+    block[4] = 4;
+    swi(Wimp_SendMessage, 17, block, block[1]);
+}
+
+    void
+ro_datasave(block)
+    int	    *block;
+{
+    char_u *path = ((char_u *) block) + 44;
+
+    /* Preserve the name given so we can use it, not <Wimp$Scrap> */
+    if (leaf_name)
+	vim_free(leaf_name);
+    leaf_name = vim_strsave(path);
+
+    block[9] = -1;	    /* File is unsafe. */
+    strcpy(path, "<Wimp$Scrap>");
+    block[0] = 60;
+    block[3] = block[2];
+    block[4] = 2;
+    swi(Wimp_SendMessage, 17, block, block[1]);
+
+    leaf_ref = block[2];
+}
+
+    void
+ro_message(block)
+    int *block;
+{
+    char_u	*buffer;
+    long_u	len;
+
+    if (block[1] == task_handle)
+	return;			    /* Don't talk to ourself! */
+    switch (block[4])
+    {
+	case 0:		/* Quit. */
+	    if (block[4] == 0)
+		ro_quit();
+	    break;
+	case 1:	/* DataSave */
+	    ro_datasave(block);
+	    break;
+	case 2:		/* DataSaveAck. */
+	    if (clip_convert_selection(&buffer, &len, &clip_star) == -1)
+		return;
+
+	    /* Save the clipboard contents to a file. */
+	    swi(OS_File, 10, ((char_u *) block) + 44, 0xfff, 0, buffer, buffer + len);
+
+	    /* Ack with DataLoad message. */
+	    block[3] = block[2];
+	    block[4] = 3;
+	    block[9] = len;
+	    swi(Wimp_SendMessage, 17, block, block[1]);
+
+	    vim_free(buffer);
+	    break;
+	case 3:		/* DataLoad */
+	    ro_dataload(block);
+	    break;
+	case 8:		/* PreQuit */
+	    ro_prequit(block);
+	    break;
+	case 0xf:	/* Lose clipboard. */
+	    if (block[5] & 4)
+	    {
+		clip_free_selection(&clip_star);
+		clip_star.owned = FALSE;
+	    }
+	    break;
+	case 0x10:	/* DataRequest (clip_star) */
+	    if (clip_star.owned)
+	    {
+		int rows;
+
+		/* Tell other program that we have the clipboard. */
+		block[0] = 52;
+		block[3] = block[2];	    /* Copy myref to yourref. */
+		block[4] = 1;		    /* DataSave message. */
+		/* Create an estimate for the size (larger or same as true
+		 * value) */
+		rows = clip_star.end.lnum - clip_star.start.lnum;
+		if (rows < 0)
+		    rows = -rows;
+		block[9] = (rows + 1) * Columns + 1; /* Add one for possible
+							final newline. */
+		block[10] = 0xfff;	    /* Clipboard is text. */
+		strcpy( ((char_u *) block) + 44, "VimClip");
+		swi(Wimp_SendMessage, 17, block, block[1]);
+	    }
+	    break;
+	case 0x400c1:	/* Mode change */
+	    changed_mode = TRUE;		/* Flag - update on next OpenWindow */
+	    if (zap_redraw)
+	    {
+		/* JK230798, re-initialise ZapRedraw stuff */
+		if (ro_zap_redraw_initialise() == FAIL)
+		    zap_redraw = FALSE;
+	    }
+	    break;
+	case 0x400c3:	/* TaskCloseDown */
+	    if (block[1] == child_handle)
+		child_handle = 0;
+	    break;
+    }
+}
+
+/*
+ * Converts a scrollbar's window handle into a scrollbar pointer.
+ * NULL on failure.
+ */
+    scrollbar_T *
+ro_find_sbar(id)
+    int		id;
+{
+    win_T	*wp;
+
+    if (gui.bottom_sbar.id == id)
+	return &gui.bottom_sbar;
+    FOR_ALL_WINDOWS(wp)
+    {
+	if (wp->w_scrollbars[SBAR_LEFT].id == id)
+	    return &wp->w_scrollbars[SBAR_LEFT];
+	if (wp->w_scrollbars[SBAR_RIGHT].id == id)
+	    return &wp->w_scrollbars[SBAR_RIGHT];
+    }
+    return NULL;
+}
+
+    void
+scroll_to(line, sb)
+    int sb;	/* Scrollbar number */
+    int line;
+{
+    char_u code[8];
+
+    /* Don't put events in the input queue now. */
+    if (hold_gui_events)
+	return;
+
+    /* Send a scroll event:
+     *
+     * A scrollbar event is CSI (NOT K_SPECIAL), KS_VER_SCROLLBAR,
+     * KE_FILLER followed by:
+     * one byte representing the scrollbar number, and then four bytes
+     * representing a long_u which is the new value of the scrollbar.
+     */
+    code[0] = CSI;
+    code[1] = KS_VER_SCROLLBAR;
+    code[2] = KE_FILLER;
+    code[3] = sb;
+    code[4] = line >> 24;
+    code[5] = line >> 16;
+    code[6] = line >> 8;
+    code[7] = line;
+    add_to_input_buf(code, 8);
+}
+
+    void
+h_scroll_to(col)
+    int col;
+{
+    char_u code[8];
+
+    /* Don't put events in the input queue now. */
+    if (hold_gui_events)
+	return;
+
+    /* Send a scroll event:
+     *
+     * A scrollbar event is CSI (NOT K_SPECIAL)
+     *
+     * A horizontal scrollbar event is K_SPECIAL, KS_HOR_SCROLLBAR,
+     * KE_FILLER followed by four bytes representing a long_u which is the
+     * new value of the scrollbar.
+     */
+    code[0] = CSI;
+    code[1] = KS_HOR_SCROLLBAR;
+    code[2] = KE_FILLER;
+    code[4] = col >> 24;
+    code[5] = col >> 16;
+    code[6] = col >> 8;
+    code[7] = col;
+    add_to_input_buf(code, 8);
+}
+
+    void
+ro_scroll(block)
+    int		*block;
+{
+    scrollbar_T	*sb;
+    int		offset;
+    win_T	*wp;
+
+    /* Block is ready for Wimp_OpenWindow, and also contains:
+     *
+     * +32 = scroll X direction (-2 .. +2)
+     * +36 = scroll Y direction (-2 .. +2)
+     */
+
+    sb = ro_find_sbar(block[0]);
+    if (!sb)
+	return;		/* Window not found (error). */
+
+    wp = sb-> wp;
+
+    if (wp == NULL)
+    {
+	/* Horizontal bar. */
+	offset = block[8];
+	if (offset == -2)
+	    offset = (block[1] - block[3]) / gui.char_width;
+	else if (offset == 2)
+	    offset = (block[3] - block[1]) / gui.char_width;
+
+	block[5] += offset * gui.char_width;
+
+	gui_drag_scrollbar(sb, block[5] / gui.char_width, FALSE);
+
+	swi(Wimp_OpenWindow, 0, block);
+    }
+    else
+    {
+	offset = -block[9];
+	if (offset == -2)
+	    offset = -(wp -> w_height - 1);
+	else if (offset == 2)
+	    offset = wp -> w_height - 1;
+
+	/* Possibly we should reposition the scrollbar?
+	 * Vim seems to update the bar anyway...
+	 */
+	gui_drag_scrollbar(sb, offset - (block[6] / gui.char_height), FALSE);
+    }
+}
+
+/* Move a window by a given offset. Used to simulate the function of the
+ * nested wimp.
+ */
+    void
+ro_move_child(window, x, y, pos_wanted, pos_got)
+    int	window;
+    int x,y;		/* offset to move by */
+    int	pos_wanted, pos_got;
+{
+    int	block[10];
+
+    block[0] = window;
+    swi(Wimp_GetWindowState, 0, block);
+    block[1] += x;
+    block[2] += y;
+    block[3] += x;
+    block[4] += y;
+    if (pos_wanted == -1)
+	block[7] = -1;
+    else if (pos_wanted == -2)
+	block[7] = pos_got;
+    swi(Wimp_OpenWindow, 0, block);
+}
+
+/* Open the main window. Also updates scrollbars if we are not
+ * using the nested Wimp.
+ * If we have just changed mode then re-read all values.
+ */
+    void
+ro_open_main(block)
+    int	    *block;
+{
+    int	    toggle_size;
+
+    /* Find out if the user clicked on the toggle size icon. */
+    block[20] = block[0];
+    swi(Wimp_GetWindowState, 0, block + 20);
+    toggle_size = block[28] & (1 << 19);
+
+    if (nested_wimp)
+    {
+	swi(Wimp_OpenWindow, 0, block);
+    }
+    else
+    {
+	int	old[10];
+	int	x_offset, y_offset;	    /* Move children same as parent. */
+	int	pos_wanted, pos_got;
+	int	left_bar  = gui.which_scrollbars[SBAR_LEFT];
+	int	right_bar = gui.which_scrollbars[SBAR_RIGHT];
+	win_T	*wp;
+
+	/* Three cases to think about:
+	 * 1) Move to top. Open each window at the top.
+	 * 2) Same stack position. Open each with same position.
+	 * 3) Open at bottom. Open children with parent's new position.
+	 */
+
+	old[0] = block[0];
+	swi(Wimp_GetWindowState, 0, old);
+	pos_wanted = block[7];
+	swi(Wimp_OpenWindow, 0, block);
+	/* Block updated by OpenWindow? I don't think so! */
+	swi(Wimp_GetWindowState, 0, block);
+	pos_got = block[7];
+
+	x_offset = block[1] - old[1];
+	y_offset = block[4] - old[4];
+	if (x_offset || y_offset || pos_wanted == -1 || pos_wanted == -2)
+	{
+	    /* If parent has moved, re-open all the child windows. */
+	    FOR_ALL_WINDOWS(wp)
+	    {
+		/* Reopen scrollbars for this window. */
+		if (left_bar)
+		    ro_move_child(wp -> w_scrollbars[SBAR_LEFT].id,
+				x_offset, y_offset,
+				pos_wanted, pos_got);
+		if (right_bar)
+		    ro_move_child(wp -> w_scrollbars[SBAR_RIGHT].id,
+				x_offset, y_offset,
+				pos_wanted, pos_got);
+	    }
+	}
+    }
+    if (changed_mode || toggle_size)
+    {
+	int	width, height;
+
+	if (changed_mode)
+	    ro_measure_tools();
+	block[0] = gui.window_handle;
+	swi(Wimp_GetWindowState, 0, block);
+
+	width = block[3] - block[1];
+	height = block[4] - block[2];
+	swi(Wimp_ForceRedraw, gui.window_handle, 0, -height, width, 0);
+	gui_resize_shell(width, height);
+	changed_mode = FALSE;
+    }
+}
+
+    void
+ro_open_window(block)
+    int		*block;
+{
+    int		pos;
+    scrollbar_T *sb;
+
+    if (block[0] == gui.window_handle)
+	ro_open_main(block);
+    else
+    {
+	swi(Wimp_OpenWindow, 0, block);
+	if (block[0] != gui.window_handle)
+	{
+	    sb = ro_find_sbar(block[0]);
+	    if (sb)
+	    {
+		if (sb-> wp != NULL)
+		    gui_drag_scrollbar(sb, -block[6] / gui.char_height, FALSE);
+		else
+		    gui_drag_scrollbar(sb, block[5] / gui.char_width, FALSE);
+	    }
+	}
+    }
+}
+
+    void
+ro_menu_selection(block)
+    int		*block;
+{
+    int		*item = wimp_menu + 7;
+    vimmenu_T	*menu;
+    /* wimp_menu points to a wimp menu structure */
+
+    for (;;)
+    {
+	while (block[0]--)
+	    item += 6;
+	if (block[1] == -1)
+	    break;
+	item = ((int *) item[1]) + 7;
+	block++;
+    }
+    /* item points to the wimp menu item structure chosen */
+    menu = (vimmenu_T *) item[5];
+
+    swi(Wimp_GetPointerInfo, 0, block);
+    if (block[2] == 1)
+	/* Adjust used - keep menu open */
+	swi(Wimp_CreateMenu, 0, wimp_menu);
+
+    if (menu-> cb)
+	menu-> cb(menu);
+}
+
+    void
+ro_open_parent()
+{
+    int head;
+    char_u *i = curbuf-> b_ffname;
+    char_u  buffer[256];
+
+    head = 0;
+    for (; *i; i++)
+    {
+	if (*i == '.')
+	    head = i - curbuf-> b_ffname;
+    }
+
+    /* Append head chars to buffer */
+    if (head < 240 && curbuf-> b_ffname && head)
+    {
+	strcpy(buffer, "%filer_opendir ");
+	strncpy(buffer + 15, curbuf-> b_ffname, head);
+	buffer[15 + head] = '\0';
+	swi(OS_CLI, buffer);
+    }
+}
+
+    void
+process_event(event, block)
+    int event;
+    int *block;
+{
+    switch (event)
+    {
+	case 0:		/* Nothing - update drag state. */
+	    if (ro_dragging)
+		ro_continue_drag(block);
+	    break;
+	case 1:		/* Redraw window. */
+	    redraw_window(block);
+	    break;
+	case 2:		/* Open window. */
+	    ro_open_window(block);
+	    break;
+	case 3:		/* Close window. */
+	    swi(Wimp_GetPointerInfo, 0, block + 1);
+	    if (block[3] == 1)
+		ro_open_parent();
+	    else
+		if (ro_ok_to_quit())
+		    ro_quit();
+	    break;
+	case 6:		/* Mouse click. */
+	    ro_mouse(block);
+	    break;
+	case 7:		/* Finished drag. */
+	    ro_drag_finished(block);
+	    break;
+	case 8:		/* Key pressed. */
+	    ro_insert_key((char_u *) &block[6]);
+	    break;
+	case 9:
+	    ro_menu_selection(block);
+	    break;
+	case 10:	/* Scroll request. */
+	    ro_scroll(block);
+	    break;
+	case 11:	/* Lose caret. */
+	    if (block[0] == gui.window_handle)
+		gui_focus_change(FALSE);
+	    break;
+	case 12:	/* Gain caret. */
+	    if (block[0] == gui.window_handle)
+		gui_focus_change(TRUE);
+	    break;
+	case 17:	/* User message. */
+	case 18:	/* User message recorded. */
+	    ro_message(block);
+	    break;
+    }
+}
+
+/*
+ * 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(long wtime)
+{
+    int block[64];
+    int	reason;
+    int start_time = -1;
+    int ctime = wtime / 10;	/* delay in cs */
+
+    if (wtime != -1)
+    {
+	swi(OS_ReadMonotonicTime);
+	start_time = r0;
+    }
+
+    for (;;)
+    {
+	if (ro_dragging)
+	    reason = wimp_poll(0, block);	/* Always return immediately */
+	else if (wtime == -1)
+	    reason = wimp_poll(1, block);
+	else
+	    reason = wimp_pollidle(0, block, start_time + ctime);
+
+	process_event(reason, block);
+
+	if (input_available() || ro_return_early)
+	{
+	    ro_return_early = FALSE;
+	    return OK;	    /* There is something to process (key / menu event) */
+	}
+
+	if (wtime != -1)
+	{
+	    swi(OS_ReadMonotonicTime);
+	    if (r0 - start_time > ctime)
+		return FAIL;	/* We've been waiting too long - return failure */
+	}
+    }
+}
+
+/* Flush any output to the screen */
+    void
+gui_mch_flush(void)
+{
+}
+
+/*
+ * 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)
+{
+    swi(ColourTrans_ReturnGCOL, gui.back_pixel << 8, 0, 0, 1<<7, 0);
+    plot_rectangle(96 + 5, r0,
+			FILL_X(col1), -FILL_Y(row2 + 1),
+			FILL_X(col2 + 1), -FILL_Y(row1));
+}
+
+    void
+gui_mch_clear_all(void)
+{
+    if (redraw_block)
+    {
+	swi(ColourTrans_SetGCOL, gui.back_pixel << 8, 0, 0, 1<<7, 0);
+	swi(OS_WriteI + 16);
+    }
+    else
+    {
+	int block[44];
+	block[0] = gui.window_handle;
+	block[1] = 0;
+	block[2] = -gui.num_rows * gui.char_height;
+	block[3] = gui.num_cols * gui.char_width;
+	block[4] = 0;
+	swi(Wimp_UpdateWindow, 0, block);
+	while (r0)
+	{
+	    swi(ColourTrans_SetGCOL, gui.back_pixel << 8, 0, 0, 1<<7, 0);
+	    swi(OS_WriteI + 16);
+	    swi(Wimp_GetRectangle, 0, block);
+	}
+    }
+}
+
+/*
+ * 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)
+{
+    int top_from = -row - num_lines;
+    int bot_from = -gui.scroll_region_bot - 1;
+    int bot_to   = bot_from + num_lines;
+
+    swi(ColourTrans_SetGCOL, gui.back_pixel << 8, 0, 0, 0x80, 0);
+
+    /* Changed without checking! */
+    swi(Wimp_BlockCopy, gui.window_handle,
+			    gui.scroll_region_left * gui.char_width,
+			    bot_from * gui.char_height,
+			    (gui.scroll_region_right - gui.scroll_region_left
+							+ 1) * gui.char_width,
+			    top_from * gui.char_height,
+
+			    gui.scroll_region_left * gui.char_width,
+			    bot_to * gui.char_height);
+
+    gui_clear_block(gui.scroll_region_bot - num_lines + 1,
+						       gui.scroll_region_left,
+	gui.scroll_region_bot, gui.scroll_region_right);
+}
+
+/*
+ * 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)
+{
+    int top_from = -row;
+    int bot_to   = -gui.scroll_region_bot - 1;
+    int bot_from = bot_to + num_lines;
+
+    swi(ColourTrans_SetGCOL, gui.back_pixel << 8, 0, 0, 0x80, 0);
+
+    swi(Wimp_BlockCopy, gui.window_handle,
+			    gui.scroll_region_left * gui.char_width,
+			    bot_from * gui.char_height,
+			    (gui.scroll_region_right - gui.scroll_region_left
+							+ 1) * gui.char_width,
+			    top_from * gui.char_height,
+
+			    gui.scroll_region_left * gui.char_width,
+			    bot_to * gui.char_height);
+
+    gui_clear_block(row, gui.scroll_region_left,
+				row + num_lines - 1, gui.scroll_region_right);
+}
+
+/* Put selection in clipboard buffer.
+ * Should we become the new owner?
+ */
+    void
+clip_mch_request_selection(VimClipboard *cbd)
+{
+    int		block[64];	/* Will be used in Wimp_Poll. */
+    int		reason;
+    char_u	*buffer;
+    long_u	length;
+
+    block[0] = 48;			/* Size of block. */
+    block[3] = 0;			/* Orinial message. */
+    block[4] = 0x10;			/* Data request. */
+    block[5] = gui.window_handle;
+    block[6] = RO_LOAD_CLIPBOARD;	/* Internal handle. */
+    block[7] = block[8] = 0;		/* (x,y) not used. */
+    block[9] = 4;
+    block[10] = 0xfff;	    /* We want text files if possible, I think. */
+    block[11] = -1;	    /* End of list. */
+    swi(Wimp_SendMessage, 17, block, 0);    /* Broadcast request. */
+
+    /* OK, we've sent the request. Poll until we get a null poll (failure) or
+     * we load the clipboard.
+     * If we receive a DataSave event with icon handle = -2 then put it on the
+     * clipboard. RISC OS should ensure that key events will not be delivered
+     * until the clipboard operation completes (unless the owner starts idling
+     * - we can't wait forever!).
+     */
+    for (;;)
+    {
+	reason = wimp_poll(0, block);
+	if (reason == 0)
+	    return;	    /* Failed to get clipboard. */
+	if ((reason == 17 || reason == 18) &&
+		block[4] == 1 && block[6] == RO_LOAD_CLIPBOARD)
+	    break;	    /* Got it - stop waiting. */
+	process_event(reason, block);
+	if (ro_return_early)
+	    return;
+    }
+    /* Tell owner to save data in <Wimp$Scrap>. */
+    block[0] = 60;
+    block[3] = block[2];   /* Copy myref -> yourref */
+    block[4] = 2;	    /* DataSaveAck. */
+    block[9] = -1;	    /* Data is unsafe. */
+    strcpy( ((char_u *) block) + 44, "<Wimp$Scrap>");
+    swi(Wimp_SendMessage, 17, block, block[1]);
+
+    /* Wait again for reply. */
+    for (;;)
+    {
+	reason = wimp_poll(0, block);
+	if (reason == 0)
+	    return;	/* Other program has given up! */
+	if ((reason == 17 || reason == 18) && block[4] == 3 && block[6] == RO_LOAD_CLIPBOARD)
+	    break;	/* Clipboard data saved to <Wimp$Scrap> */
+	process_event(reason, block);
+	if (ro_return_early)
+	    return;
+    }
+
+    /* <Wimp$Scrap> contains clipboard - load it. */
+    if (xswi(OS_File, 17, "<Wimp$Scrap>") & v_flag)
+	return;		/* Error! */
+    if (r0 != 1 && r0 != 3)
+	return;
+    length = r4;
+
+    buffer = lalloc(length, TRUE);  /* Claim memory (and report errors). */
+    if (buffer == NULL)
+	return;
+
+    if (xswi(OS_File, 16, "<Wimp$Scrap>", buffer, 0) & v_flag)
+	return;
+
+    clip_yank_selection(MCHAR, buffer, length, cbd);
+
+    vim_free(buffer);
+
+    swi(OS_FSControl, 27, "<Wimp$Scrap>", 0, 0);    /* Delete temp file. */
+
+    block[4] = 4;		    /* Send DataLoadAck. */
+    block[3] = block[2];	    /* Copy myref -> yourref. */
+    swi(Wimp_SendMessage, 17, block, block[1]);
+}
+
+/* Not sure what this means under RISC OS. */
+    void
+clip_mch_lose_selection(VimClipboard *cbd)
+{
+}
+
+/* Tell everyone that we now own the clipboard.
+ * Return OK if our claim is accepted (always, under RISC OS)
+ */
+    int
+clip_mch_own_selection(VimClipboard *cbd)
+{
+    int block[6];
+    block[0] = 24;	/* Length of block.  */
+    block[3] = 0;	/* Original message. */
+    block[4] = 0xf;	/* ClaimEntity. */
+    block[5] = 0x4;	/* Claim clipboard only. */
+    swi(Wimp_SendMessage, 17, block, 0);
+    return OK;
+}
+
+/*
+ * Send the current selection to the clipboard.  Do nothing for X because we
+ * will fill in the selection only when requested by another app. Sounds good
+ * for RISC OS too.
+ */
+    void
+clip_mch_set_selection(VimClipboard *cbd)
+{
+    clip_get_selection(cbd);
+}
+
+/*
+ * Make a menu either grey or not grey.
+ */
+    void
+gui_mch_menu_grey(vimmenu_T *menu, int grey)
+{
+    menu-> greyed_out = grey;
+}
+
+/*
+ * Make menu item hidden or not hidden
+ */
+    void
+gui_mch_menu_hidden(vimmenu_T *menu, int hidden)
+{
+    menu-> hidden = hidden;
+}
+
+/*
+ * This is called after setting all the menus to grey/hidden or not.
+ */
+    void
+gui_mch_draw_menubar(void)
+{
+    swi(Wimp_CreateMenu, 0, -1);
+    if (wimp_menu != (int *) -1)
+    {
+	ro_remove_menu(wimp_menu);
+	wimp_menu = (int *) -1;
+    }
+}
+
+/* Add or remove a scrollbar. Note that this is only called when
+ * the scrollbar state is changing.
+ * The scroll bar window has already been created.
+ * We can't do anything except remove the scroll bar
+ * until we know what size to use.
+ */
+    void
+gui_mch_enable_scrollbar(sb, flag)
+    scrollbar_T	*sb;
+    int		flag;
+{
+    if (!flag)
+	swi(Wimp_CloseWindow, 0, & (sb->id) );
+    return;
+}
+
+    void
+gui_mch_set_blinking(long waittime, long on, long off)
+{
+}
+
+/*
+ * Stop the cursor blinking.  Show the cursor if it wasn't shown.
+ */
+    void
+gui_mch_stop_blink(void)
+{
+}
+
+/*
+ * Start the cursor blinking.  If it was already blinking, this restarts the
+ * waiting time and shows the cursor.
+ */
+    void
+gui_mch_start_blink(void)
+{
+}
+
+/*
+ * Return the RGB value of a pixel as a long.
+ */
+    long_u
+gui_mch_get_rgb(guicolor_T pixel)
+{
+    return (long_u)pixel;
+}
+
+    void
+gui_mch_set_text_area_pos(int x, int y, int w, int h)
+{
+}
+
+    void
+gui_mch_enable_menu(int flag)
+{
+}
+
+    void
+gui_mch_set_menu_pos(int x, int y, int w, int h)
+{
+}
+
+    void
+gui_mch_add_menu(vimmenu_T *menu, int idx)
+{
+}
+
+    void
+gui_mch_add_menu_item(vimmenu_T *menu, int idx)
+{
+}
+
+    void
+gui_mch_new_menu_colors(void)
+{
+}
+
+    void
+gui_mch_destroy_menu(vimmenu_T *menu)
+{
+}
+
+/* Size of buffer has changed.
+ * Add one to max since gui.c substracts one more than it should!
+ */
+    void
+gui_mch_set_scrollbar_thumb(sb, val, size, max)
+    scrollbar_T	*sb;
+    long	val;
+    long	size;
+    long	max;
+{
+    int		block[10], width, height;
+
+    width = (max + 1) * gui.char_width;
+    height = (max + 1 + W_STATUS_HEIGHT(sb->wp)) * gui.char_height;
+
+    block[0] = block[3] = 0;
+    block[1] = -height + (1 << y_eigen_factor);
+    block[2] = width;
+
+    swi(Wimp_SetExtent, sb -> id, block);
+
+    block[0] = sb -> id;
+    swi(Wimp_GetWindowState, 0, block);
+    block[5] = val * gui.char_width;
+    block[6] = -val * gui.char_height;
+    swi(Wimp_OpenWindow, 0, block, 0x4b534154,
+			gui.window_handle,	/* Parent window handle. */
+			(CHILD_FIX_TO_RIGHT  << CHILD_LEFT  )   |
+			(CHILD_FIX_TO_RIGHT  << CHILD_RIGHT )   |
+			(CHILD_FIX_TO_BOTTOM << CHILD_TOP   )   |
+			(CHILD_FIX_TO_BOTTOM << CHILD_BOTTOM)   |
+			(CHILD_SELF_SCROLL   << CHILD_SCROLL_X) |
+			(CHILD_SELF_SCROLL   << CHILD_SCROLL_Y)
+			);
+}
+
+/* Set the position of the scrollbar within the editor
+ * window. Note that, for vertical scrollbars, x and w
+ * are ignored. For horizontal bars y and h are ignored.
+ */
+    void
+gui_mch_set_scrollbar_pos(sb, x, y, w, h)
+    scrollbar_T *sb;
+    int		x;		/* Horizontal sb position */
+    int		y;		/* Top of scroll bar */
+    int		w;		/* Width */
+    int		h;		/* Height */
+{
+    int		block[24];
+    int		px1, py1;	/* Parent window min coords */
+    int		px2, py2;	/* Parent window max coords */
+
+    /* Find where the parent window is. */
+    block[0] = gui.window_handle;
+    swi(Wimp_GetWindowState, 0, block);
+    px1 = block[1];
+    py1 = block[2];
+    px2 = block[3];
+    py2 = block[4];
+
+    block[0] = sb -> id;
+
+    /* Find out how big the scroll window is at the moment. */
+    swi(Wimp_GetWindowInfo, 0, ((char_u *)block) + 1);
+
+    if (block[13] < w || block[12] > -h)
+    {
+	/* Current window is too small! */
+	if (block[12] > -h)
+	    block[12] = -h;
+	if (block[13] < w)
+	    block[13] = w;
+	swi(Wimp_SetExtent, block[0], block + 11);
+    }
+
+    /* This works better on the nested_wimp. */
+    if (sb-> wp)
+    {
+	/* This is a vertical scrollbar. */
+	block[1] = block[3] = px2 - gui.scrollbar_width + (1 << x_eigen_factor);
+	block[2] = 1 + py2 - (y + h) + (1 << y_eigen_factor);
+	block[4] = 1 + py2 - y;
+    }
+    else
+    {
+	/* This is a horizontal scrollbar. */
+	block[2] = block[4] = py1 + gui.scrollbar_height;
+	block[1] = px1;
+	block[3] = px2 - gui.scrollbar_width;
+    }
+
+    block[5] = 0;
+    block[6] = 0;
+    block[7] = -1;
+
+    swi(Wimp_OpenWindow, 0, block, 0x4b534154,
+	    gui.window_handle,	/* Parent window handle. */
+	    (CHILD_FIX_TO_RIGHT  << CHILD_LEFT  )   |
+	    (CHILD_FIX_TO_RIGHT  << CHILD_RIGHT )   |
+	    (CHILD_FIX_TO_BOTTOM << CHILD_TOP   )   |
+	    (CHILD_FIX_TO_BOTTOM << CHILD_BOTTOM)   |
+	    (CHILD_SELF_SCROLL   << CHILD_SCROLL_X) |
+	    (CHILD_SELF_SCROLL   << CHILD_SCROLL_Y)
+       );
+}
+
+/* Create a window with no workarea to place inside editor window.
+ * (what happens without the nested wimp?)
+ * Data for scrollbar is invalid.
+ */
+    void
+gui_mch_create_scrollbar(sb, orient)
+    scrollbar_T *sb;
+    int		orient;	/* orient is SBAR_HORIZ or SBAR_VERT */
+{
+    int bar[] =
+	{
+	    0,   0,		/* Visible area : min X,Y */
+	    100, 100,		/*		  max X,Y */
+	    0,   0,		/* Scroll offsets */
+	    -1,			/* Window in front */
+	    0x80800150 | (orient == SBAR_HORIZ ? (1 << 30) : (1 << 28)),
+	    0xff070207,		/* Colours */
+	    0x000c0103,		/* More colours */
+	    0, -0x4000,		/* Workarea extent */
+	    0x4000, 0,		/* max X,Y */
+	    0x00000000,		/* No title */
+	    0 << 12,		/* No workarea button type */
+	    1,			/* Wimp sprite area */
+	    0x00010001,		/* Minimum width, height */
+	    0, 0, 0,		/* Title data (none) */
+	    0			/* No icons */
+	};
+    swi(Wimp_CreateWindow, 0, bar);
+    sb -> id = r0;
+}
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+    void
+gui_mch_destroy_scrollbar(scrollbar_T *sb)
+{
+    swi(Wimp_DeleteWindow, 0, & (sb->id));
+    sb -> id = -1;
+}
+#endif
+
+    void
+gui_mch_set_scrollbar_colors(scrollbar_T *sb)
+{
+    /* Always use default RO colour scheme. */
+}
+
+/*
+ * Get current x mouse coordinate in text window.
+ * Note: (0,0) is the bottom left corner, positive y is UP.
+ * Return -1 when unknown.
+ */
+    int
+gui_mch_get_mouse_x()
+{
+    int left;
+    int block[10];
+
+    block[0] = gui.window_handle;
+    swi(Wimp_GetWindowState, 0, block);
+    left = block[1];
+
+    swi(Wimp_GetPointerInfo, 0, block);
+    return block[0] - left;
+}
+
+/*
+ * Get current y mouse coordinate in text window.
+ * Return -1 when unknown.
+ */
+    int
+gui_mch_get_mouse_y()
+{
+    int top;
+    int block[10];
+
+    block[0] = gui.window_handle;
+    swi(Wimp_GetWindowState, 0, block);
+    top = block[4];
+
+    swi(Wimp_GetPointerInfo, 0, block);
+    return top - block[1];
+}
+
+/* MouseTo(x, y) */
+    void
+gui_mch_setmouse(x, y)
+    int		x;
+    int		y;
+{
+}
+
+    void
+gui_mch_toggle_tearoffs(enable)
+    int		enable;
+{
+    /* no tearoff menus */
+}
+
+/* Redraw a window's title.
+ * For the nested wimp we use the new 'redraw-title-bar' reason code.
+ * For older wimps we mark the area of the screen where the title bar
+ * is as invalid.
+ */
+    void
+ro_redraw_title(window)
+    int window;
+{
+    if (nested_wimp)
+    {
+	swi(Wimp_ForceRedraw, window, 0x4b534154, 3);
+    }
+    else
+    {
+	int block[10];
+	int miny;
+
+	block[0] = window;
+	swi(Wimp_GetWindowState, 0, block);
+	miny = block[4];
+	swi(Wimp_GetWindowOutline, 0, block);
+	swi(Wimp_ForceRedraw, -1,
+			block[1], miny,
+			block[3], block[4]);
+    }
+}
+
+/* Turn a vimmenu_T structure into a wimp menu structure.
+ * -1 if resulting menu is empty.
+ * Only the children and dname items in the root menu are used.
+ */
+    int *
+ro_build_menu(menu)
+    vimmenu_T	*menu;
+{
+    int		*wimp_menu;
+    int		width = 4;
+    int		w;
+    int		size = 28;
+    vimmenu_T	*item;
+    int		*wimp_item;
+
+    /* Find out how big the menu is so we can allocate memory for it */
+    for (item = menu-> children; item; item = item-> next)
+    {
+	if (item-> hidden == FALSE && !menu_is_separator(item->name))
+	    size += 24;
+    }
+
+    if (size <= 28)
+	return (int *) -1;		/* No children - shouldn't happen */
+
+    wimp_menu = (int *) alloc(size);
+
+    wimp_menu[0] = (int) menu-> dname;
+    wimp_menu[1] = -1;
+    wimp_menu[2] = 0;
+    wimp_menu[3] = 0x00070207;
+    wimp_menu[5] = 44;
+    wimp_menu[6] = 0;
+
+    wimp_item = wimp_menu + 7;
+
+    for (item = menu-> children; item; item = item-> next)
+    {
+	if (menu_is_separator(item-> name))
+	{
+	    /* This menu entry is actually a separator. If it is not the first
+	     * menu entry then mark the previous menu item as needing a dotted
+	     * line after it.
+	     */
+	    if (wimp_item > wimp_menu + 7)
+		wimp_item[-6] |= 0x2;
+	}
+	else if (item-> hidden == FALSE)
+	{
+	    wimp_item[0] = 0;
+	    wimp_item[1] = item-> children ? (int) ro_build_menu(item) : -1;
+	    wimp_item[2] = 0x07009131 | (item-> greyed_out << 22);
+	    wimp_item[3] = (int) item-> dname;
+	    wimp_item[4] = -1;
+	    wimp_item[5] = (int) item;  /* Stuff the menu address in this unused space */
+
+	    w = strlen(item-> dname) + 1;
+	    if (w > width)
+		width = w;
+	    wimp_item += 6;
+	}
+    }
+
+    wimp_menu[4] = (width + 2) * 16;
+    wimp_menu[7]  |= 0x100;	    /* Menu title is indirected */
+    wimp_item[-6] |= 0x080;	    /* Last entry in menu */
+    return wimp_menu;
+}
+
+    static void
+ro_remove_menu(menu)
+    int	    *menu;
+{
+    int	    *item = menu + 7;
+
+    if (menu == NULL || menu == (int *) -1)
+	return;
+
+    for (;;)
+    {
+	if (item[1] != -1)
+	    ro_remove_menu((int *) item[1]);	/* Remove sub-menu */
+	if (item[0] & 0x80)
+	    break;			/* This was the last entry */
+	item += 6;
+    }
+    vim_free(menu);
+}
+
+    void
+gui_mch_show_popupmenu(menu)
+    vimmenu_T	*menu;
+{
+    int		block[10];
+
+    /* Remove the existing menu, if any */
+    if (wimp_menu != (int *) -1)
+    {
+	swi(Wimp_CreateMenu, 0, -1);
+	ro_remove_menu(wimp_menu);
+	wimp_menu = (int *) -1;
+    }
+
+    wimp_menu = ro_build_menu(menu);
+    if (wimp_menu != (int *) -1)
+    {
+	swi(Wimp_GetPointerInfo, 0, block);
+	swi(Wimp_CreateMenu, 0, wimp_menu, block[0] - 64, block[1] + 64);
+    }
+}
+
+/* Run a command using the TaskWindow module.
+ * If SHELL_FILTER is set then output is not echoed to the screen,
+ * If it is not set, then \r is not sent to the output file.
+ */
+    int
+gui_mch_call_shell(cmd, options)
+    char_u  *cmd;
+    int	    options;	/* SHELL_FILTER if called by do_filter() */
+			/* SHELL_COOKED if term needs cooked mode */
+{
+    char_u  task_cmd[256];	/* Contains *TaskWindow command. */
+    int	    block[64];
+    int	    reason;
+    char_u  *out;
+    char_u  c;
+    int	    old_msg_col;
+    char_u  *out_redir;
+    int	    length;
+    FILE    *out_file = NULL;
+
+    out_redir = strstr(cmd, " > ");
+    if (out_redir == NULL)
+	length = strlen(cmd);	/* No redirection. */
+    else
+    {
+	length = out_redir - cmd;
+	out_file = fopen(out_redir + 3, "wb");
+	if (out_file == NULL)
+	    msg_str("WARNING : Can't open file %s for writing\n",
+							       out_redir + 3);
+    }
+
+    if (length > 180)
+    {
+	if (out_file)
+	    fclose(out_file);
+	return FAIL;		/* Command too long. */
+    }
+
+    strcpy(task_cmd, "TaskWindow \"");
+    strncpy(task_cmd + 12, cmd, length);
+    sprintf(task_cmd + 12 + length,
+	    "\" -task &%08x -ctrl -quit -name \"Vim command\"",
+	    task_handle);
+
+    if (options & SHELL_COOKED)
+	settmode(TMODE_COOK);
+
+    if (xswi(Wimp_StartTask, task_cmd) & v_flag)
+    {
+	/* Failed to even start a new task (out of memory?) */
+	settmode(TMODE_RAW);
+	if (out_file)
+	    fclose(out_file);
+	return FAIL;
+    }
+
+    /* Wait for the child process to initialise. */
+    child_handle = 0;
+    while (!child_handle)
+    {
+	reason = wimp_poll(0, block);
+	if ((reason == 17 || reason == 18) && block[4] == 0x808c2)
+	    child_handle = block[1];
+	else
+	    process_event(reason, block);
+    }
+
+    /* Block until finished */
+    while (child_handle)
+    {
+	reason = wimp_poll(1, block);
+	if (reason == 3 || (reason == 8 && block[6] == 3))
+	{
+	    /* Close window request or CTRL-C - kill child task. */
+	    block[0] = 20;
+	    block[3] = 0;
+	    block[4] = 0x808c4;	    /* Morite */
+	    swi(Wimp_SendMessage, 17, block, child_handle);
+	    MSG_PUTS(_("\nSending message to terminate child process.\n"));
+	    continue;
+	}
+	else if (reason == 8)
+	{
+	    block[0] = 28;
+	    block[3] = 0;
+	    block[4] = 0x808c0;	    /* Input */
+	    block[5] = 1;
+	    /* Block[6] is OK as it is! */
+	    swi(Wimp_SendMessage, 17, block, child_handle);
+	    continue;
+	}
+	else if (reason == 17 || reason == 18)
+	{
+	    if (block[4] == 0x808c1)
+	    {
+		/* Ack message. */
+		block[3] = block[2];
+		swi(Wimp_SendMessage, 19, block, block[1]);
+		out = (char_u *)block + 24;
+		old_msg_col = msg_col;
+		while (block[5]--)
+		{
+		    c = *out++;
+		    if (out_file && (c != '\r' || (options & SHELL_FILTER)))
+			fputc(c, out_file);
+		    if ((options & SHELL_FILTER) == 0)
+		    {
+			if (c == 127)
+			    msg_puts("\b \b");
+			else if (c > 31)
+			    msg_putchar(c);
+			else if (c == 10)
+			{
+			    lines_left = 8;	/* Don't do More prompt! */
+			    msg_putchar(10);
+			}
+		    }
+		}
+		/* Flush output to the screen. */
+		windgoto(msg_row, msg_col);
+		out_flush();
+		continue;
+	    }
+	}
+	process_event(reason, block);
+    }
+    msg_putchar('\n');
+    settmode(TMODE_RAW);
+    if (out_file)
+	fclose(out_file);
+    return OK;
+}
+
+/* Like strsave(), but stops at any control char */
+    char_u *
+wimp_strsave(str)
+    char    *str;
+{
+    int	    strlen = 0;
+    char_u  *retval;
+    while (str[strlen] > 31)
+	strlen++;
+    retval = alloc(strlen + 1);
+    if (retval)
+    {
+	memcpy(retval, str, strlen);
+	retval[strlen] = '\0';
+    }
+    return retval;
+}
+
+/* If we are saving then pop up a standard RISC OS save box.
+ * Otherwise, open a directory viewer on the given directory (and return NULL)
+ * The string we return will be freed later.
+ */
+    char_u *
+gui_mch_browse(saving, title, dflt, ext, initdir, filter)
+    int		saving;		/* write action */
+    char_u	*title;		/* title for the window */
+    char_u	*dflt;		/* default file name */
+    char_u	*ext;		/* extension added */
+    char_u	*initdir;	/* initial directory, NULL for current dir */
+    char_u	*filter;	/* file name filter */
+{
+    char command[256];
+    int length;
+
+    if (saving)
+    {
+	int	block[64];
+	int	reason;
+	int	done_save = FALSE;
+	char_u	*retval = NULL;
+	char_u  *sprname;
+	char_u	*fname;
+	int	dragging_icon = FALSE;
+	int	filetype;
+
+	if (!dflt)
+	    dflt = "TextFile";
+
+	block[0] = save_window;
+	block[1] = 0;
+	swi(Wimp_GetIconState, 0, block);
+	sprname = ((char_u *) block[7]);
+	block[1] = 1;
+	swi(Wimp_GetIconState, 0, block);
+	fname = ((char *) block[7]);
+	strncpy(fname, dflt, 255);
+
+	if (xswi(OS_FSControl, 31, curbuf->b_p_oft) & v_flag)
+	{
+	    filetype = 0xfff;
+	    strcpy(sprname + 5, "xxx");
+	}
+	else
+	{
+	    filetype = r2;
+	    sprintf(sprname + 5, "%03x", filetype);
+	}
+
+	/* Open the save box */
+
+	swi(Wimp_GetPointerInfo, 0, block);
+	swi(Wimp_CreateMenu, 0, save_window, block[0] - 64, block[1] + 64);
+	swi(Wimp_SetCaretPosition, save_window, 1, 0, 0, -1, -1);
+
+	while (!done_save)
+	{
+	    reason = wimp_poll(1, block);
+	    switch (reason)
+	    {
+		case 1:
+		    redraw_window(block);
+		    break;
+		case 2:
+		    if (block[0] == save_window)
+			swi(Wimp_OpenWindow, 0, block);
+		    else
+			ro_open_window(block);
+		    break;
+		case 3:
+		    done_save = TRUE;
+		    break;
+		case 6:
+		    if (block[3] != save_window)
+			done_save = TRUE;
+		    else
+		    {
+			int drag_box[4];
+			int min_x, max_y;
+
+			switch (block[4])
+			{
+			    case    0: /* Start drag */
+				block[0] = save_window;
+				swi(Wimp_GetWindowState, 0, block);
+				min_x = block[1];
+				max_y = block[4];
+				block[1] = 0;
+				swi(Wimp_GetIconState, 0, block);
+				drag_box[0] = block[2] + min_x;
+				drag_box[1] = block[3] + max_y;
+				drag_box[2] = block[4] + min_x;
+				drag_box[3] = block[5] + max_y;
+
+				swi(DragASprite_Start,
+					0x45,
+					1,
+					sprname,
+					drag_box);
+				dragging_icon = TRUE;
+				break;
+			    case    2: /* OK */
+				retval = wimp_strsave(fname);
+				done_save = TRUE;
+				break;
+			    case    3: /* Cancel */
+				done_save = TRUE;
+				break;
+			}
+		    }
+		    break;
+		case 7:
+		    if (dragging_icon)
+		    {
+			int len = 0;
+
+			dragging_icon = FALSE;
+			swi(Wimp_GetPointerInfo, 0, block);
+			block[5] = block[3];
+			block[6] = block[4];
+			block[7] = block[0];
+			block[8] = block[1];
+			block[9] = 0;		/* Don't know the size */
+			block[10] = filetype;
+
+			while (fname[len] > 31)
+			{
+			    if (fname[len] == '.')
+			    {
+				fname += len + 1;
+				len = 0;
+			    }
+			    else
+				len++;
+			}
+			if (len > 211)
+			    len = 211;
+
+			memcpy(((char_u *) block) + 44, fname, len);
+			((char_u *)block)[44 + len] = '\0';
+
+			block[0] = (len + 48) & 0xfc;
+			block[3] = 0;
+			block[4] = 1;	    /* DataSave */
+
+			swi(Wimp_SendMessage, 17, block, block[5], block[6]);
+		    }
+		    else
+			ro_drag_finished(block);
+		    break;
+		case 8:
+		    if (block[6] == 13)
+		    {
+			retval = wimp_strsave(fname);
+			done_save = TRUE;
+		    }
+		    else if (block[6] == 0x1b)
+			done_save = TRUE;
+		    else
+			swi(Wimp_ProcessKey, block[6]);
+		    break;
+		case 17:
+		case 18:
+		    if (block[4] == 2 && block[9] != -1)
+		    {
+			/* DataSaveAck from dragging icon. */
+			retval = wimp_strsave(((char_u *) block) + 44);
+			done_save = TRUE;
+		    }
+		    else if (block[4] == 0x400c9)
+		    {
+			/* MenusDeleted */
+			done_save = TRUE;
+		    }
+		    else
+			ro_message(block);
+		    break;
+	    }
+	}
+	block[0] = save_window;
+	swi(Wimp_CloseWindow, 0, block);
+	swi(Wimp_GetCaretPosition, 0, block);
+	if (block[0] == -1)
+	    swi(Wimp_SetCaretPosition, gui.window_handle, -1, 0, 0, -1, -1);
+
+	return retval;
+    }
+    else if (initdir)
+    {
+	/* Open a directory viewer */
+	length = strlen(initdir);
+
+	if (length > 240)
+	    return NULL;	/* Path too long! */
+
+	length = sprintf(command, "Filer_OpenDir %s", initdir);
+	while (command[length - 1] == '.')
+	    length--;
+	command[length] = '\0';
+	swi(OS_CLI, command);
+    }
+    return NULL;
+}
+
