diff --git a/src/gui_riscos.c b/src/gui_riscos.c
deleted file mode 100644
index 4a9378b..0000000
--- a/src/gui_riscos.c
+++ /dev/null
@@ -1,3558 +0,0 @@
-/* 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, direction)
-    int width;		/* In OS units */
-    int height;
-    int min_width;	/* Smallest permissible window size (ignored) */
-    int min_height;
-    int base_width;	/* Space for scroll bars, etc */
-    int base_height;
-    int direction;
-{
-    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! */
-
-    vim_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;
-}
-
-/*
- * Adjust gui.char_height (after 'linespace' was changed).
- */
-    int
-gui_mch_adjust_charheight()
-{
-    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;
-}
-
-#if defined(FEAT_EVAL) || defined(PROTO)
-/*
- * Return the name of font "font" in allocated memory.
- * Don't know how to get the actual name, thus use the provided name.
- */
-    char_u *
-gui_mch_get_fontname(font, name)
-    GuiFont font;
-    char_u  *name;
-{
-    if (name == NULL)
-	return NULL;
-    return vim_strsave(name);
-}
-#endif
-
-/*
- * 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 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)	},
-	{ "Gray10",		grgb(26,	26,	26)	},
-	{ "Grey10",		grgb(26,	26,	26)	},
-	{ "Gray20",		grgb(51,	51,	51)	},
-	{ "Grey20",		grgb(51,	51,	51)	},
-	{ "Gray30",		grgb(77,	77,	77)	},
-	{ "Grey30",		grgb(77,	77,	77)	},
-	{ "Gray40",		grgb(102,	102,	102)	},
-	{ "Grey40",		grgb(102,	102,	102)	},
-	{ "Gray50",		grgb(127,	127,	127)	},
-	{ "Grey50",		grgb(127,	127,	127)	},
-	{ "Gray60",		grgb(153,	153,	153)	},
-	{ "Grey60",		grgb(153,	153,	153)	},
-	{ "Gray70",		grgb(179,	179,	179)	},
-	{ "Grey70",		grgb(179,	179,	179)	},
-	{ "Gray80",		grgb(204,	204,	204)	},
-	{ "Grey80",		grgb(204,	204,	204)	},
-	{ "Gray90",		grgb(229,	229,	229)	},
-	{ "Grey90",		grgb(229,	229,	229)	},
-
-	{ "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[64];
-	    /* 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)
-    {
-	/* Resizing 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;			/* Original 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 subtracts 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 mouse coordinates in text window.
- * Note: (0,0) is the bottom left corner, positive y is UP.
- */
-    void
-gui_mch_getmouse(x, y)
-    int *x;
-    int *y;
-{
-    int left;
-    int top;
-    int block[10];
-
-    block[0] = gui.window_handle;
-    swi(Wimp_GetWindowState, 0, block);
-    left = block[1];
-    top = block[4];
-
-    swi(Wimp_GetPointerInfo, 0, block);
-    *x = block[0] - left;
-    *y = 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)
-	    smsg("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;
-}
diff --git a/src/gui_riscos.h b/src/gui_riscos.h
deleted file mode 100644
index fe22e6a..0000000
--- a/src/gui_riscos.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* 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.
- */
-
-#define FEAT_BROWSE
-
-#define TASK 0x4b534154
-
-/* Nested wimp flags: */
-#define CHILD_FIX_TO_WORKAREA	0
-#define CHILD_FIX_TO_LEFT	1
-#define CHILD_FIX_TO_BOTTOM	1
-#define CHILD_FIX_TO_RIGHT	2
-#define CHILD_FIX_TO_TOP	2
-
-#define CHILD_SELF_SCROLL	0
-#define CHILD_PARENT_SCROLL	1
-
-#define CHILD_LEFT		16
-#define CHILD_BOTTOM		18
-#define CHILD_RIGHT		20
-#define CHILD_TOP		22
-#define CHILD_SCROLL_X		24
-#define CHILD_SCROLL_Y		26
-
-int wimp_poll(int mask, int *block);
-int wimp_poll_idle(int mask, int *block, int end_time);
-void ro_open_main(int *block);
diff --git a/src/os_riscos.c b/src/os_riscos.c
deleted file mode 100644
index 5c443fc..0000000
--- a/src/os_riscos.c
+++ /dev/null
@@ -1,1292 +0,0 @@
-/* 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"
-
-/*
- * os_riscos.c
- *
- * Thomas Leonard <tal197@ecs.soton.ac.uk>
- */
-
-const char *__dynamic_da_name = "Vim heap"; /* Enable and name our dynamic area */
-int ro_line_mode = TRUE;  /* For Ex mode we much echo chars to the screen ourselves */
-int windowed;		/* Flag - are we running inside a text window? */
-int WinLeft, WinTop;	/* We might be started inside a text window */
-int ScrollTop;		/* Make cursor movements relative to ScrollTop. */
-
-int old_escape_state = -1;
-int old_cursor_state = -1;
-
-#define rgb(r,g,b) ((b<<24) + (g<<16) + (r<<8))
-#define NORMAL_FG 0x00000000
-#define NORMAL_BG 0xffffffff
-
-/* Convert a DOS colour number to an RGB palette entry.
- * Mappings from X11 rgb/txt file.
- */
-    static int
-map_colour(dos)
-    int dos;		/* Standard DOS colour number. */
-{
-    switch (dos)
-    {
-	case 0: return 0;			/* Black */
-	case 1: return rgb(0,0,139);		/* DarkBlue */
-	case 2: return rgb(0,100,0);		/* DarkGreen */
-	case 3: return rgb(0,139,139);		/* DarkCyan */
-	case 4: return rgb(139,0,0);		/* DarkRed */
-	case 5: return rgb(139,0,139);		/* DarkMagenta */
-	case 6: return rgb(165,42,42);		/* Brown, DarkYellow */
-	case 7: return rgb(211,211,211);	/* LightGray, LightGrey, Gray, Grey */
-	case 8: return rgb(169,169,169);	/* DarkGray, DarkGrey */
-	case 9: return rgb(173,216,230);	/* Blue, LightBlue */
-	case 10: return rgb(144,238,144);	/* Green, LightGreen */
-	case 11: return rgb(224,255,255);	/* Cyan, LightCyan */
-	case 12: return rgb(255,0,0);		/* Red, LightRed */
-	case 13: return rgb(255,0,255);		/* Magenta, LightMagenta */
-	case 14: return rgb(255,255,0);		/* Yellow, LightYellow */
-	case 15: return rgb(255,255,255);	/* White */
-    }
-    return rgb(100,100,100);
-}
-
-    static void
-text_fg(fg)
-    int fg;		/* Foregound colour in the form &BBGGRR00 */
-{
-    xswi(ColourTrans_SetTextColour, fg, 0, 0, 0);
-}
-
-    static void
-text_bg(bg)
-    int		bg;	/* Backgound colour in the form &BBGGRR00 */
-{
-    xswi(ColourTrans_SetTextColour, bg, 0, 0, 1 << 7);
-}
-
-#define OUT_NORMAL 0
-#define OUT_NUMBER 1		/* Reading in a number */
-
-    void
-mch_write(s, len)
-    char_u  *s;
-    int	    len;
-{
-    static int mode = OUT_NORMAL;
-    static int x, y;			/* For reading numbers in. */
-
-    if (!term_console)
-    {
-	/* Maybe we are running Vim remotely - don't interpret chars */
-	while (len--)
-	{
-	    char_u c = *s++;
-	    swi(OS_WriteC, c);
-	    /* We might need to send a CR too. This shouldn't
-	     * hurt if we don't need it, should it?
-	     */
-	    if (c == 10)
-		swi(OS_WriteI + 13);
-	}
-	return;
-    }
-
-    while (len--)
-    {
-	char_u c = *s++;
-	switch (mode)
-	{
-	    case OUT_NUMBER:
-		if (c < '0' || c > '9')
-		{
-		    mode = OUT_NORMAL;
-		}
-		else
-		{
-		    x = (x * 10) + c - '0';
-		    continue;
-		}
-	    /* note: no break here! */
-
-	    case OUT_NORMAL:
-		switch (c)
-		{
-		    case 1:
-			/* Number (in decimal) follows. */
-			mode = OUT_NUMBER;
-			y = x;
-			x = 0;
-			break;
-		    case 2:
-			/* Position cursor. */
-			swi(OS_WriteI + 31);
-			swi(OS_WriteC, x);
-			swi(OS_WriteC, y - ScrollTop);
-			break;
-		    case 3:
-			/* Set scroll region. */
-			if (x == Rows -1 && y == 0 && !windowed)
-			{
-			    /* Whole screen - remove text window.
-			     * This is MUCH faster.
-			     */
-			    swi(OS_WriteI + 26);
-			}
-			else
-			{
-			    /* Create a text window. */
-			    swi(OS_WriteI + 28);
-			    swi(OS_WriteC, WinLeft);
-			    swi(OS_WriteC, WinTop + x);
-			    swi(OS_WriteC, WinLeft + Columns - 1);
-			    swi(OS_WriteC, WinTop + y);
-			}
-			ScrollTop = y;
-			break;
-		    case 4:
-			/* Normal mode. */
-			text_fg(NORMAL_FG);
-			text_bg(NORMAL_BG);
-			break;
-		    case 5:
-			/* Reverse mode. */
-			text_fg(NORMAL_BG);
-			text_bg(NORMAL_FG);
-			break;
-		    case 10:
-			swi(OS_NewLine);
-			break;
-		    case 14:
-			/* Cursor invisible. */
-			swi(OS_WriteN,
-			     "\027\001\000\000\000\000\000\000\000\000",
-			     10);
-			break;
-		    case 15:
-			/* Cursor visible. */
-			swi(OS_WriteN,
-			     "\027\001\002\000\000\000\000\000\000\000",
-			     10);
-			break;
-		    case 16:
-			/* Cursor very visible (flash) */
-			swi(OS_WriteN,
-			     "\027\001\003\000\000\000\000\000\000\000",
-			     10);
-		    case 17:
-			/* Set foreground colour. */
-			text_fg(map_colour(x));
-			break;
-		    case 18:
-			/* Set background colour. */
-			text_bg(map_colour(x));
-			break;
-		    case 19:
-			/* Scroll text down. */
-			swi(OS_WriteN,
-			     "\027\007\000\002\000\000\000\000\000\000",
-			     10);
-			break;
-		    default:
-			swi(OS_WriteC, c);
-		}
-		continue;
-
-	    default:
-		printf("[output error]");
-		mode = OUT_NORMAL;
-	}
-    }
-}
-
-/*
- * mch_inchar(): low level input funcion.
- * Get a characters from the keyboard.
- * Return the number of characters that are available.
- * If wtime == 0 do not wait for characters.
- * If wtime == n wait n msecs for characters.
- * If wtime == -1 wait forever for characters.
- *
- * TODO: call convert_input() for 'fileencoding' to 'encoding' conversion.
- */
-    int
-mch_inchar(buf, maxlen, wtime, tb_change_cnt)
-    char_u  *buf;
-    int	    maxlen;
-    long    wtime;
-    int	    tb_change_cnt;
-{
-    int got=0;
-    unsigned int start_time = clock();
-
-    if (ro_line_mode)
-    {
-	/* We're probably in Ex mode - get whole lines at a time. */
-
-	static char_u	line_buffer[256];
-	static int	remaining_chars = 0;
-	static int	buf_pos = 0;
-
-	/* Do we need to fetch another line? */
-	if (remaining_chars == 0)
-	{
-	    int		old_esc_state;
-	    swi(OS_Byte, 200, 1, 0xfe);
-	    old_esc_state = r1;
-
-	    buf_pos = 0;
-	    if (xswi(OS_ReadLine, line_buffer, 255, 0, 255) & (c_flag | v_flag))
-	    {
-		got_int = TRUE;	    /* ESC pressed */
-		r1 = 0;
-	    }
-	    line_buffer[r1] = 13;
-	    remaining_chars = r1 + 1;	/* Count CR as part of input */
-
-	    swi(OS_Byte, 200, old_esc_state, 0);
-	}
-
-	/* Can we send the rest of the buffer back in one go? */
-	if (remaining_chars <= maxlen)
-	{
-	    int	    got = remaining_chars;
-
-	    memcpy(buf, line_buffer + buf_pos, got);
-	    remaining_chars = 0;
-	    return  got;
-	}
-
-	/* Send as much as we can */
-	memcpy(buf, line_buffer + buf_pos, maxlen);
-	buf_pos += maxlen;
-	remaining_chars -= maxlen;
-
-	return maxlen;
-    }
-
-    if (!term_console)
-    {
-	/* Use OS_ReadC for all input.
-	 * Avoids problems with remote access getting interference from
-	 * the keyboard.
-	 */
-	if (wtime == 0)
-	    return 0;	    /* Ignore quick key checks */
-
-	if (xswi(OS_ReadC) & c_flag)
-	{
-	    got_int = TRUE;	/* ESC pressed - can this happen? */
-	    swi(OS_Byte, 124);	/* Clear Escape state */
-	    r0 = 0x1b;		/* It *might* not have been Escape! */
-	}
-	buf[0] = r0;
-	return 1;
-    }
-
-    /*
-     * OK, here's the plan:
-     *
-     * 1) Wait until wtime expires or we get a key
-     * 2) Get keys until the keyboard buffer is empty or buf is full
-     */
-
-    while (xswi(OS_Byte,145,0) & c_flag)
-    {
-	/* Nothing at all in the keyboard buffer.
-	 * Has our time expired yet?
-	 */
-	if ( (wtime != -1) && (clock() - start_time) >= wtime )
-	    return 0;		/* Nothing read - giving up */
-    }
-
-    /* We've got one char (in r2) - are there any more? */
-
-    while (got < maxlen)
-    {
-	buf[got++] = r2;
-
-	if (xswi(OS_Byte,145,0) & c_flag)
-	    return got;		/* Keyboard buffer empty */
-    }
-    return got;			/* buf is full */
-}
-
-/*
- * return non-zero if a character is available
- */
-    int
-mch_char_avail()
-{
-    if (!term_console)
-	return 0;	    /* Can't tell */
-    if (xswi(OS_Byte, 152, 0) & c_flag)
-	return 0;
-    return 1;
-}
-
-/* Find out how much free memory we have.
- * I don't know how to work this out exactly but, since we can claim
- * more memory from the OS, let's just report the free pool size.
- * Dynamic area 6 doesn't exist pre 3.6 according to StrongHelp, so
- * we'll use Wimp_SlotSize. If that fails (outside the desktop?)
- * then just return a big number and hope.
- */
-    long_u
-mch_avail_mem(special)
-    int special;
-{
-    if (xswi(Wimp_SlotSize, -1, -1) & v_flag)
-	return 0x7fffffff;
-    return r2;
-}
-
-    void
-mch_delay(msec, ignoreinput)
-    long	msec;
-    int		ignoreinput;
-{
-    int		start_time, time_now;
-    int		csec = msec / 10;
-
-    swi(OS_ReadMonotonicTime);
-    start_time = r0;
-
-    for (;;)
-    {
-	swi(OS_ReadMonotonicTime);
-	time_now = r0;
-	if (time_now - start_time > csec)
-	    return;
-#ifdef FEAT_GUI
-	/* In the GUI, allow other programs to run while waiting. */
-	if (gui.in_use)
-	    gui_mch_wait_for_chars(start_time + csec);
-#endif
-    }
-}
-
-/*
- * If the machine has job control, use it to suspend the program,
- * otherwise fake it by starting a new shell.
- */
-    void
-mch_suspend()
-{
-    suspend_shell();
-}
-
-    void
-mch_init()
-{
-    /*
-     * Read window size first. Calls to mch_get_shellsize() will
-     * simply return these values in future so that setting the
-     * text window (used for scrolling) won't give strange results.
-     */
-
-    int buf[7] = {132, 135, 256, 257, 1, 2, -1};
-
-    /* Command windows are no longer forced open, since if we are
-     * in the desktop then we'll use the GUI version.
-     * Opening a command window here messes up the GUI version startup
-     */
-#ifndef FEAT_GUI
-    swi(OS_WriteI);
-#endif
-    swi(OS_ReadVduVariables, buf, buf);
-    WinLeft = buf[0];
-    WinTop  = buf[1];
-    Columns = buf[2];
-    Rows    = buf[3] + 1;	/* Seems to be one off (VduVars wrong?) */
-    ScrollTop = 0;
-
-    /* Are we running in a textwindow? */
-    if (Rows == buf[5] + 1 && Columns == buf[4] + 1)
-	windowed = 0;
-    else
-	windowed = 1;
-
-    /* Choose a nice colour scheme. */
-    text_fg(NORMAL_FG);
-    text_bg(NORMAL_BG);
-}
-
-/*
- * Check_win checks whether we have an interactive stdout.
- */
-/* ARGSUSED */
-    int
-mch_check_win(argc, argv)
-    int	    argc;
-    char    **argv;
-{
-    return OK;
-}
-
-/*
- * Return TRUE if the input comes from a terminal, FALSE otherwise.
- */
-    int
-mch_input_isatty()
-{
-    if (xswi(OS_ChangeRedirection, -1, -1) & v_flag)
-	return TRUE;		/* Error - TRUE is probably correct though */
-    if (r0 == 0)
-	return TRUE;
-    return FALSE;
-}
-
-#ifdef FEAT_TITLE
-    int
-mch_can_restore_title()
-{
-    return FALSE;
-}
-
-    int
-mch_can_restore_icon()
-{
-    return FALSE;
-}
-
-
-/*
- * Set the window title and icon.
- */
-    void
-mch_settitle(title, icon)
-    char_u *title;
-    char_u *icon;
-{
-    if (title == NULL)
-	title = (char_u *) "<untitled>";
-#ifdef FEAT_GUI
-    if (gui.in_use && strcmp(title, gui.window_title))
-    {
-	int length;
-	length = strlen(title);
-	if (length >= gui.window_title_size)
-	    length = gui.window_title_size - 1;
-	strncpy(gui.window_title, title, length);
-	gui.window_title[length] = 0;
-	ro_redraw_title(gui.window_handle);
-    }
-#endif
-    return;
-}
-
-/*
- * Restore the window/icon title.
- * "which" is one of:
- *  1  only restore title
- *  2  only restore icon
- *  3  restore title and icon
- */
-    void
-mch_restore_title(which)
-    int which;
-{
-    return;
-}
-#endif
-
-/*
- * Insert user name in s[len].
- * Return OK if a name found.
- */
-    int
-mch_get_user_name(s, len)
-    char_u  *s;
-    int	    len;
-{
-    /* RISC OS doesn't support user names. */
-    *s = NUL;
-    return FAIL;
-}
-
-/*
- * Insert host name in s[len].
- */
-
-    void
-mch_get_host_name(s, len)
-    char_u  *s;
-    int	    len;
-{
-    if (xswi(OS_ReadVarVal, "Machine$Name", s, len, 0, 3) & v_flag)
-    {
-	/* Variable does not exist (normal operation) */
-	vim_strncpy(s, "(unknown)", len - 1);
-    }
-}
-
-/*
- * return process ID
- */
-    long
-mch_get_pid()
-{
-    if (xswi(Wimp_ReadSysInfo, 5) & v_flag)
-	return 0;
-    return r0;
-}
-
-/*
- * Get name of current directory into buffer 'buf' of length 'len' bytes.
- * Return OK for success, FAIL for failure.
- */
-    int
-mch_dirname(buf, len)
-    char_u  *buf;
-    int	    len;
-{
-    if (xswi(OS_FSControl, 37, "@", buf, 0, 0, len) & v_flag)
-	return FAIL;
-    return OK;
-}
-
-/*
- * Get absolute file name into buffer 'buf' of length 'len' bytes.
- *
- * return FAIL for failure, OK for success
- */
-    int
-mch_FullName(fname, buf, len, force)
-    char_u *fname, *buf;
-    int len;
-    int	force;		/* Also expand when already absolute path name.
-			 * Not used under RISC OS.
-			 */
-{
-    if (xswi(OS_FSControl, 37, fname, buf, 0, 0, len) & v_flag)
-	return FAIL;
-    return OK;
-}
-
-/*
- * Return TRUE if "fname" does not depend on the current directory.
- */
-    int
-mch_isFullName(fname)
-    char_u	*fname;
-{
-    if (strstr(fname, "::") && strstr(fname,".$."))
-	return TRUE;
-    return FALSE;
-}
-
-/*
- * Get file permissions for 'name'.
- * Returns -1 when it doesn't exist.
- */
-    long
-mch_getperm(name)
-    char_u *name;
-{
-    struct stat statb;
-
-    if (stat((char *)name, &statb))
-	return -1;
-    return statb.st_mode;
-}
-
-/*
- * set file permission for 'name' to 'perm'
- *
- * return FAIL for failure, OK otherwise
- */
-    int
-mch_setperm(name, perm)
-    char_u  *name;
-    long    perm;
-{
-    return (chmod((char *)name, (mode_t)perm) == 0 ? OK : FAIL);
-}
-
-/*
- * Set hidden flag for "name".
- */
-/* ARGSUSED */
-    void
-mch_hide(name)
-    char_u	*name;
-{
-    /* can't hide a file */
-}
-
-/*
- * return TRUE if "name" is a directory
- * return FALSE if "name" is not a directory
- * return FALSE for error
- */
-    int
-mch_isdir(name)
-    char_u *name;
-{
-    if (xswi(OS_File, 17, name) & v_flag)
-	return FALSE;
-    if (r0 == 2 || r0 == 3)
-	return TRUE;		/* Count image files as directories. */
-    return FALSE;
-}
-
-/*
- * Return 1 if "name" can be executed, 0 if not.
- * Return -1 if unknown. Requires which to work.
- */
-    int
-mch_can_exe(name)
-    char_u	*name;
-{
-    char_u	*buf;
-    char_u	*p;
-    int		retval;
-
-    buf = alloc((unsigned)STRLEN(name) + 7);
-    if (buf == NULL)
-	return -1;
-    sprintf((char *)buf, "which %s", name);
-    p = get_cmd_output(buf, NULL, SHELL_SILENT);
-    vim_free(buf);
-    if (p == NULL)
-	return -1;
-    /* result can be: "name: Command not found" */
-    retval = (*p != NUL && strstr((char *)p, "not found") == NULL);
-    vim_free(p);
-    return retval;
-}
-
-/*
- * Check what "name" is:
- * NODE_NORMAL: file or directory (or doesn't exist)
- * NODE_WRITABLE: writable device, socket, fifo, etc.
- * NODE_OTHER: non-writable things
- */
-    int
-mch_nodetype(name)
-    char_u	*name;
-{
-    /* TODO */
-    return NODE_NORMAL;
-}
-
-    void
-mch_early_init()
-{
-    /* Turn off all the horrible filename munging in UnixLib. */
-    int __riscosify_control = __RISCOSIFY_NO_PROCESS;
-}
-
-    void
-mch_exit(r)
-    int r;
-{
-    settmode(TMODE_COOK);
-    exiting = TRUE;
-    out_flush();
-    ml_close_all(TRUE);		/* remove all memfiles */
-
-#ifdef FEAT_GUI
-    if (gui.in_use)
-	gui_exit(r);
-#endif
-    swi(OS_NewLine);
-    if (old_escape_state != -1)
-	swi(OS_Byte, 229, old_escape_state, 0);
-    if (old_cursor_state != -1)
-	swi(OS_Byte, 4, old_cursor_state);
-    exit(r);
-}
-
-    void
-mch_settmode(tmode)
-    int		tmode;	    /* TMODE_RAW or TMODE_COOK */
-{
-    if (tmode == TMODE_COOK)
-    {
-	ro_line_mode = TRUE;
-	return;
-    }
-
-    ro_line_mode = FALSE;
-
-    if (term_console)
-    {
-	/* Block cursor. */
-	swi(OS_WriteN,
-		"\027\000\012\000\000\000\000\000\000\000",
-		10);
-
-	/* Disable the standard cursor key actions. */
-	swi(OS_Byte, 4, 1);
-	if (old_cursor_state == -1)
-	    old_cursor_state = r1;
-    }
-
-    /* Stop Escape from quitting Vim! */
-    swi(OS_Byte, 229, 1, 0);
-    if (old_escape_state == -1)
-	old_escape_state = r1;
-}
-
-/*
- * set mouse clicks on or off (only works for xterms)
- */
-    void
-mch_setmouse(on)
-    int	    on;
-{
-}
-
-/*
- * set screen mode, always fails.
- */
-/* ARGSUSED */
-    int
-mch_screenmode(arg)
-    char_u   *arg;
-{
-    EMSG(_(e_screenmode));
-    return FAIL;
-}
-
-/*
- * Try to get the current window size.
- * Return OK when size could be determined, FAIL otherwise.
- * Simply return results stored by mch_init() if we are the
- * machine's console. If not, we don't know how big the screen is.
- */
-    int
-mch_get_shellsize()
-{
-    /* if size changed: screenalloc will allocate new screen buffers */
-    return term_console ? OK : FAIL;
-}
-
-/*
- * Can't change the size.
- * Assume the user knows what he's doing and use the new values.
- */
-    void
-mch_set_shellsize()
-{
-    /* Assume the user knows what he's doing and use the new values. */
-}
-
-/*
- * Rows and/or Columns has changed.
- */
-    void
-mch_new_shellsize()
-{
-    /* Nothing to do. */
-}
-
-    int
-mch_call_shell(cmd, options)
-    char_u	*cmd;
-    int		options;	/* SHELL_*, see vim.h */
-{
-    int		retval;
-    int		tmode = cur_tmode;
-
-    if (cmd == NULL)
-	cmd = (char_u *) "GOS";
-
-#ifdef FEAT_GUI
-    if (gui.in_use)
-	return gui_mch_call_shell(cmd, options);
-#endif
-    if (options & SHELL_COOKED)
-	settmode(TMODE_COOK);		/* set to normal mode */
-    MSG_PUTS("\n");
-
-   /* I don't even want to think about what UnixLib must
-    * be doing to allow this to work...
-    */
-    retval = system(cmd);
-    if (retval && !(options & SHELL_SILENT))
-	EMSG(strerror(EOPSYS));		/* Doesn't seem to set errno? */
-
-    swi(OS_Byte, 229, 1, 0);		/* Re-disable escape */
-    if (tmode == TMODE_RAW)
-	settmode(TMODE_RAW);		/* set to raw mode */
-    return retval ? FAIL : OK;
-}
-
-/*
- * Check for Escape being pressed right now.
- * [ different if !term_console? ]
- */
-    void
-mch_breakcheck()
-{
-    if (xswi(OS_Byte, 121, 0xf0) & v_flag)
-	return;
-    if (r1 == 0xff)
-    {
-	got_int = TRUE;
-	swi(OS_Byte, 15, 1);	/* Flush input buffer */
-    }
-}
-
-/*
- * Recursively expand one path component into all matching files and/or
- * directories.
- * "path" has backslashes before chars that are not to be expanded.
- * Return the number of matches found.
- */
-    int
-mch_expandpath(gap, path, flags)
-    garray_T	*gap;	/* Grow array for results. */
-    char_u	*path;
-    int		flags;	/* EW_* flags */
-{
-    int		got;	/* Number of matches. */
-    char_u	*pattern;
-
-   /* Plan:
-    *
-    * 1) Get first part of path - no wildcards
-    * 2) Get next path element (wildcarded)
-    * 3) Get rest of path
-    *
-    * If (3) is nothing then only the leaf is wildcarded - add to gap
-    * Otherwise call recursively for each path in (2), passing (3)
-    *
-    * This is just the header function.
-    */
-
-    /* We must be able to modifiy path, so make a copy */
-    pattern = vim_strsave(path);
-    if (pattern == NULL)
-	return 0;
-    got = expand_section(gap, (char_u *)"", pattern, flags);
-    vim_free(pattern);
-    return got;
-}
-
-/*
- * expand_section(gap, "$.Dir1.Dir2", "ABBA*.myleaf##")
- *
- * calls expand_section(gap, "$.Dir1.Dir2.ABBA_Gold", "myleaf##")
- *   and expand_section(gap, "$.Dir1.Dir2.ABBA_Live", "myleaf##")
- *
- * If rest is just a leaf then all matches are added to gap.
- *
- * Returns number of items added to gap.
- */
-    int
-expand_section(gap, root, rest, flags)
-    garray_T	*gap;
-    char_u	*root;	/* Non-wildcarded path to search */
-    char_u	*rest;	/* Wildcarded remainder of path */
-    int		flags;	/* Add dirs/files/missing objects. */
-{
-    static char_u buf[MAXPATHL];	/* Temporary buffer. */
-    char_u dir[MAXPATHL];
-    int start_element = -1;		/* Start of wildcarded element */
-    char_u c;
-    int i;
-    int got, dir_pos;
-    int buflen;			/* Chars used in buf[] */
-    int colon = 0;		/* Dir ends in ':' */
-
-    buflen = strlen(root);
-    STRNCPY(buf, root, buflen);	/* Copy root into buffer. */
-
-   /*
-    * Find end of nonwildcarded section.
-    * Count ':' as a path sep since Vim:Bug* is a valid pathname.
-    */
-
-    for (i = 0; c = rest[i]; i++)
-    {
-	if (c == PATHSEP)
-	{
-	    start_element = i;
-	    colon = 0;
-	}
-	if (c == ':')
-	{
-	    start_element = i + 1;
-	    colon = 1;
-	}
-	if (c == '#' || c == '*')
-	    break;
-    }
-    if (c == 0)
-	start_element = i;
-
-   /*
-    * start_element +> terminator for non-wildcarded section.
-    * Transfer this bit into buf.
-    */
-    if (buflen + start_element + 4 >= MAXPATHL)
-       return 0;			/* Buffer full */
-    if (start_element >= 0)
-    {
-	if (*root && !colon)
-	    buf[buflen++] = PATHSEP;
-	strncpy(buf + buflen, rest, start_element);
-	buflen += start_element;
-    }
-    buf[buflen] = 0;
-
-   /*
-    * Did we reach the end of the string without hitting any wildcards?
-    */
-    if (c == 0)
-    {
-	/* Yes - add combined path to grow array and return. */
-	addfile(gap, buf, flags);
-	return 1;
-    }
-
-    if (start_element < 0 || !colon)
-	start_element++;
-    rest += start_element;
-
-   /*
-    * rest does contain wildcards if we get here.
-    *
-    * Now : have we reached the leaf names part yet?
-    * If so, add all matches (files and dirs) to gap.
-    * If not, get next path element and scan all matching directories.
-    */
-
-    start_element = -1;
-    for (i = 0; rest[i]; i++)
-    {
-	if (rest[i] == '.')
-	{
-	    start_element = i;
-	    rest[i] = 0;		/* Break string here. */
-	    break;
-	}
-    }
-
-    /* If start_element is -1 then we are matching leaf names */
-
-    r3 = 0;			/* Number of objs read. */
-    dir_pos = 0;		/* Position through directory. */
-    got = 0;			/* Files added so far. */
-    while (dir_pos != -1)
-    {
-	buf[buflen] = 0;
-	if (xswi(OS_GBPB, 9,
-		buf,				/* Directory to scan. */
-		buf + buflen + (1 - colon),	/* Buffer for result. */
-		1,			/* Number of objects to read. */
-		dir_pos,		/* Search position. */
-		MAXPATHL - 2 - buflen,	/* Size of result buffer. */
-		rest)			/* Wildcarded leafname. */
-			& v_flag)
-	{
-	    EMSG(r0 + 4);
-	    r4 = -1;
-	}
-	dir_pos = r4;		/* r4 corrupted by addfile() */
-	if (r3 > 0)
-	{
-	    char_u *path = buf;
-	    if (buflen == 0)
-		path++;			/* Don't do '.File' */
-	    else if (!colon)
-		buf[buflen] = '.';		/* Join path and leaf */
-
-	   /* Path -> full path of object found */
-	    if (start_element == -1)
-	    {
-		addfile(gap, path, flags);
-		got++;
-	    }
-	    else
-	    {
-	       /* Scan into subdirectories and images; ignore files */
-		swi(OS_File, 17, path);
-		if (r0 == 2 || r0 == 3)
-		    got += expand_section(gap,
-						path,
-						rest + start_element + 1,
-						flags);
-	    }
-	}
-    }
-
-    /* Restore the dot if we removed it. */
-    if (start_element >= 0)
-	rest[start_element] = '.';
-    return got;
-}
-
-/*
- * mch_expand_wildcards() - this code does wild-card pattern matching using
- * the shell. It isn't used under RISC OS.
- *
- * return OK for success, FAIL for error (you may lose some memory) and put
- * an error message in *file.
- *
- * num_pat is number of input patterns
- * pat is array of pointers to input patterns
- * num_file is pointer to number of matched file names
- * file is pointer to array of pointers to matched file names
- */
-    int
-mch_expand_wildcards(num_pat, pat, num_file, file, flags)
-    int		    num_pat;
-    char_u	  **pat;
-    int		   *num_file;
-    char_u	 ***file;
-    int		    flags;		/* EW_* flags */
-{
-    /* This doesn't get called unless SPECIAL_WILDCHAR is defined. */
-    return FAIL;
-}
-
-/*
- * Return TRUE if "p" contains wildcards which can be expanded by
- * mch_expandpath().
- */
-    int
-mch_has_exp_wildcard(p)
-    char_u	*p;
-{
-    if (vim_strpbrk((char_u *)"*#", p))
-	return TRUE;
-    return FALSE;
-}
-
-/* Return TRUE if "p" contains wildcards. */
-    int
-mch_has_wildcard(p)
-    char_u	*p;
-{
-    if (vim_strpbrk((char_u *)"*#`", p))
-	return TRUE;
-    return FALSE;
-}
-
-    int			/* see Unix unlink(2) */
-mch_remove(file)
-    char_u *file;	/* Name of file to delete. */
-{
-    if (xswi(OS_FSControl, 27, file, 0, 0) & v_flag)
-	return EXIT_FAILURE;
-    return EXIT_SUCCESS;
-}
-
-/* Try to make existing scripts work without modification.
- * Return a pointer to the new string (freed by caller), or NULL
- *
- * Two main cases:
- * - Absolute : $VIM/syntax/help.vim
- * - Relative : Adfs::4.$.!Vim.Resources.Syntax/help.vim
- */
-    char_u *
-mch_munge_fname(fname)
-    char_u *fname;
-{
-    char_u c;
-    int len;
-    char_u *retval;
-
-    retval = fname = vim_strsave(fname);
-    if (fname == NULL)
-	return NULL;
-
-    if (strncmp(fname, "$VIM/", 5) == 0)
-    {
-	strncpy(fname, "Vim:", 4);
-	for (fname += 5; c = *fname; fname++)
-	{
-	    if (c == '.')
-		break;
-	    if (c == '/')
-		fname[-1] = '.';
-	    else
-		fname[-1] = c;
-	}
-	fname[-1] = '\0';
-    }
-    else
-    {
-	/* Check to see if the file exists without modification. */
-	if (xswi(OS_File, 17, fname) & v_flag)
-	    r0 == 0;		/* Invalid filename? */
-	if (r0)
-	    return retval;
-
-	len = strlen(fname);
-	if (strcmp(fname + len - 4, ".vim") == 0)
-	{
-	    fname[len - 4] = '\0';
-	    for (; c = *fname; fname++)
-	    {
-		if (c == '/')
-		    *fname = '.';
-	    }
-	}
-    }
-    return retval;
-}
-
-/* QuickFix reads munged names from the error file.
- * Correct them.
- */
-    int
-ro_buflist_add(old_name)
-    char_u  *old_name;	/* Name of file found by quickfix */
-{
-    char_u  *fname;
-    char_u  *leaf;	/* Pointer to start of leaf in old_name */
-    char_u  *ptr;
-    char_u  c;
-    int	    retval;
-
-    if (old_name == NULL)
-	return buflist_add(NULL, 0);
-
-    /* Copy the name so we can mess around with it. */
-    fname = vim_strsave(old_name);
-    if (fname == NULL)
-	/* Out of memory - can't modify name */
-	return buflist_add(old_name, 0);
-
-    /* Change `dir/main.c' into `dir.c.main' */
-    leaf = fname;
-    for (ptr = fname; c = *ptr; ptr++)
-    {
-	if (c == '/')
-	{
-	    leaf = ptr + 1;
-	    *ptr = '.';
-	}
-	else if (c == '.')
-	    break;
-    }
-    if (c == '.')
-    {
-	/* Change `main.c' into `c.main'
-	 *	  |    |
-	 *      leaf  ptr
-	 */
-	ptr += old_name - fname;
-	*ptr = '\0';
-	sprintf(leaf,
-		"%s.%s",
-		ptr + 1,
-		leaf - fname + old_name);
-    }
-
-    retval = buflist_add(fname, 0);
-    free(fname);
-    return retval;
-}
-
-/* Change the current directory.
- * Strip trailing dots to make it easier to use with filename completion.
- * Return 0 for success, -1 for failure.
- */
-    int
-mch_chdir(dir)
-    char_u  *dir;
-{
-    int	    length;
-    int	    retval;
-    char_u  *new_dir;
-
-    if (p_verbose >= 5)
-    {
-	verbose_enter();
-	smsg((char_u *)"chdir(%s)", dir);
-	verbose_leave();
-    }
-    length = strlen(dir);
-    if (dir[length - 1] != '.')
-	return chdir(dir);	    /* No trailing dots - nothing to do. */
-    new_dir = vim_strsave(dir);
-    if (new_dir == NULL)
-	return chdir(dir);	    /* Can't allocate memory. */
-
-    while (new_dir[--length] == '.')
-	new_dir[length] = '\0';
-
-    retval = chdir(new_dir);
-    vim_free(new_dir);
-    return retval;
-}
-
-/* Examine the named file, and set the 'osfiletype' option
- * (in curbuf) to the file's type.
- */
-    void
-mch_read_filetype(file)
-    char_u  *file;
-{
-    int	    type;
-    char_u  type_string[9];
-    int	    i;
-
-    if (xswi(OS_File, 23, file) & v_flag)
-	type = 0xfff;		/* Default to Text */
-    else
-	type = r6;
-
-    /* Type is the numerical value - see if we have a textual equivalent */
-    swi(OS_FSControl, 18, 0, type);
-    ((int *) type_string)[0] = r2;
-    ((int *) type_string)[1] = r3;
-    type_string[8] = 0;
-    for (i = 0; type_string[i] > ' '; i++)
-	;
-    type_string[i] = 0;
-
-    set_string_option_direct("osfiletype", -1, type_string, OPT_FREE, 0);
-    return;
-}
-
-    void
-mch_set_filetype(file, type)
-    char_u  *file;
-    char_u  *type;
-{
-    if (xswi(OS_FSControl, 31, type) & v_flag)
-    {
-	EMSG(_("E366: Invalid 'osfiletype' option - using Text"));
-	r2 = 0xfff;
-    }
-
-    swi(OS_File, 18, file, r2);
-}
-
-/* Return TRUE if the file's type matches 'type'
- * RISC OS types always start with '&'
- */
-    int
-mch_check_filetype(fname, type)
-    char_u  *fname;
-    char_u  *type;
-{
-    int	    value;
-    char    *end;
-
-    if (*type != '&')
-	return FALSE;
-
-    value = strtol(type + 1, &end, 16);
-    if (*end)
-	return FALSE;		/* Invalid type (report error?) */
-
-    if (xswi(OS_File, 23, fname) & v_flag)
-	return FALSE;		/* Invalid filename? */
-
-    return (r0 && r6 == value);
-}
diff --git a/src/os_riscos.h b/src/os_riscos.h
deleted file mode 100644
index 47a48da..0000000
--- a/src/os_riscos.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/* 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.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <termios.h>
-#include <stdlib.h>
-#include <unixlib/local.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#define CASE_INSENSITIVE_FILENAME
-#define FEAT_MODIFY_FNAME
-#define FEAT_OSFILETYPE
-#define DFLT_OFT	"Text"
-#define USE_TERM_CONSOLE
-#define HAVE_AVAIL_MEM
-
-/* Longer filenames now accessible to all */
-#ifndef BASENAMELEN
-# define BASENAMELEN 64 /* Same length as unzip */
-#endif
-
-#ifndef TEMNAME
-# define TEMPNAME	"<Wimp$ScrapDir>.v?XXXXXX"
-# define TEMPNAMELEN	25
-#endif
-
-#ifndef DFLT_HELPFILE
-# define DFLT_HELPFILE "Vim:doc.help"
-#endif
-
-#ifndef DFLT_BDIR
-# define DFLT_BDIR	".,<Wimp$ScrapDir>."	/* default for 'backupdir' */
-#endif
-
-/* Paths to try putting swap file in. */
-#ifndef DFLT_DIR
-# define DFLT_DIR	"<Wimp$ScrapDir>.,."	/* default for 'directory' */
-#endif
-
-#ifndef DFLT_VDIR
-# define DFLT_VDIR	"Choices:Vim.view"	/* default for 'viewdir' */
-#endif
-
-#ifndef TERMCAPFILE
-# define TERMCAPFILE	"Vim:TermCap"
-#endif
-#define HAVE_TGETENT
-
-#ifndef SYNTAX_FNAME
-# define SYNTAX_FNAME	"Vim:Syntax.%s"
-#endif
-
-#ifndef EVIM_FILE
-# define EVIM_FILE	"Vim:Evim"
-#endif
-
-#define FEAT_VIMINFO
-
-#ifndef VIMINFO_FILE
-# define VIMINFO_FILE	"<Choices$Write>.Vim.VimInfo"
-#endif
-#ifndef VIMINFO_FILE2
-# define VIMINFO_FILE2	"Choices:Vim.VimInfo"
-#endif
-
-#ifndef VIMRC_FILE
-# define VIMRC_FILE	"/vimrc"
-#endif
-#ifndef EXRC_FILE
-# define EXRC_FILE	"/exrc"
-#endif
-#ifndef GVIMRC_FILE
-# define GVIMRC_FILE	"/gvimrc"
-#endif
-#ifndef USR_VIMRC_FILE
-# define USR_VIMRC_FILE	"Vim:Evim"
-#endif
-#ifndef SESSION_FILE
-# define SESSION_FILE	"/Session.vim"
-#endif
-#ifndef USR_VIMRC_FILE
-# define USR_VIMRC_FILE	"Choices:Vim.VimRC"
-#endif
-#ifndef USR_GVIMRC_FILE
-# define USR_GVIMRC_FILE    "Choices:Vim.GVimRC"
-#endif
-#ifndef USR_EXRC_FILE
-# define USR_EXRC_FILE    "Choices:Vim.ExRC"
-#endif
-#ifndef SYS_VIMRC_FILE
-# define SYS_VIMRC_FILE	    "Vim:VimRC"
-#endif
-#ifndef SYS_GVIMRC_FILE
-# define SYS_GVIMRC_FILE    "Vim:GVimRC"
-#endif
-#ifndef SYS_MENU_FILE
-# define SYS_MENU_FILE	    "Vim:Menu"
-#endif
-#ifndef SYS_OPTWIN_FILE
-# define SYS_OPTWIN_FILE    "Vim:Optwin"
-#endif
-#ifndef FILETYPE_FILE
-# define FILETYPE_FILE	    "Vim:Filetype"
-#endif
-#ifndef FTPLUGIN_FILE
-# define FTPLUGIN_FILE	    "Vim:Ftplugin/vim"
-#endif
-#ifndef INDENT_FILE
-# define INDENT_FILE	    "Vim:Indent/vim"
-#endif
-#ifndef FTOFF_FILE
-# define FTOFF_FILE	    "Vim:Ftoff"
-#endif
-#ifndef FTPLUGOF_FILE
-# define FTPLUGOF_FILE	    "Vim:Ftplugof"
-#endif
-#ifndef INDOFF_FILE
-# define INDOFF_FILE	    "Vim:Indoff"
-#endif
-
-#define DFLT_ERRORFILE		"errors/vim"
-#define DFLT_RUNTIMEPATH	"Choices:Vim,Vim:,Choices:Vim.after"
-
-/*
- * RISC PCs have plenty of memory, use large buffers
- */
-#define CMDBUFFSIZE 1024	/* size of the command processing buffer */
-#define MAXPATHL    256		/* paths are always quite short though */
-
-#ifndef DFLT_MAXMEM
-# define DFLT_MAXMEM	(5*1024)    /* use up to 5 Mbyte for a buffer */
-#endif
-
-#ifndef DFLT_MAXMEMTOT
-# define DFLT_MAXMEMTOT	(10*1024)    /* use up to 10 Mbyte for Vim */
-#endif
-
-#ifdef HAVE_SIGSET
-# define signal sigset
-#endif
-
-#define n_flag (1<<31)
-#define z_flag (1<<30)
-#define c_flag (1<<29)
-#define v_flag (1<<28)
-
-/* These take r0-r7 as inputs, returns r0-r7 in global variables. */
-void swi(int swinum, ...);      /* Handles errors itself */
-int xswi(int swinum, ...);      /* Returns errors using v flag */
-extern int r0, r1, r2, r3, r4, r5, r6, r7;  /* For return values */
-
-#include <kernel.h>
-#include <swis.h>
-
-#define mch_memmove(to, from, len) memmove((char *)(to), (char *)(from), len)
-#define mch_rename(src, dst) rename(src, dst)
-#define mch_getenv(x) (char_u *)getenv((char *)x)
-#define mch_setenv(name, val, x) setenv(name, val, x)
