diff --git a/src/gui_photon.c b/src/gui_photon.c
new file mode 100644
index 0000000..f2bd5f0
--- /dev/null
+++ b/src/gui_photon.c
@@ -0,0 +1,3060 @@
+/* vi:set ts=8 sw=4 sts=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *			Photon GUI support by Julian Kinraid
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ *
+ *
+ * Clipboard support is in os_qnx.c
+ * PhAttach() is called in os_qnx.c:qnx_init()
+ */
+
+#include "vim.h"
+
+#ifdef FEAT_TOOLBAR
+# include <photon/PxImage.h>
+#endif
+
+#if !defined(__QNX__)
+/* Used when generating prototypes. */
+# define PgColor_t	int
+# define PhEvent_t	int
+# define PhPoint_t	int
+# define PtWidget_t	int
+# define Pg_BLACK	0
+# define PtCallbackF_t	int
+# define PtCallbackInfo_t int
+# define PhTile_t	int
+# define PtWidget_t	int
+# define PhImage_t	int
+#endif
+
+#define ARRAY_LENGTH(a) (sizeof(a) / sizeof(a[0]))
+#define RGB(r,g,b) PgRGB(r,g,b)
+
+#define EVENT_BUFFER_SIZE sizeof( PhEvent_t ) + 1000
+
+/* Some defines for gui_mch_mousehide() */
+#define MOUSE_HIDE		TRUE
+#define MOUSE_SHOW		FALSE
+
+/* Optional support for using a PtPanelGroup widget, needs work */
+#undef USE_PANEL_GROUP
+
+#ifdef USE_PANEL_GROUP
+static char	*empty_title = "    ";
+static char	**panel_titles = NULL;
+static ushort_t	num_panels = 0;
+static short pg_margin_left, pg_margin_right, pg_margin_top, pg_margin_bottom;
+#endif
+
+#define GUI_PH_MARGIN		4	/* Size of the bevel */
+
+#define GUI_PH_MOUSE_TYPE		Ph_CURSOR_INSERT
+static PgColor_t gui_ph_mouse_color =	Pg_BLACK;
+
+static PhPoint_t    gui_ph_raw_offset;
+static PtWidget_t   *gui_ph_timer_cursor;   /* handle cursor blinking */
+static PtWidget_t   *gui_ph_timer_timeout;  /* used in gui_mch_wait_for_chars */
+static short	    is_timeout;		    /* Has the timeout occured? */
+
+/*
+ * This is set inside the mouse callback for a right mouse
+ * button click, and used for the popup menus
+ */
+static PhPoint_t    abs_mouse;
+
+/* Try and avoid redraws while a resize is in progress */
+static int is_ignore_draw = FALSE;
+
+/* Used for converting to/from utf-8 and other charsets */
+static struct PxTransCtrl *charset_translate;
+
+/*
+ * Cursor blink functions.
+ *
+ * This is a simple state machine:
+ * BLINK_NONE	not blinking at all
+ * BLINK_OFF	blinking, cursor is not shown
+ * BLINK_ON	blinking, cursor is shown
+ */
+static enum {
+    BLINK_NONE,
+    BLINK_OFF,
+    BLINK_ON
+} blink_state = BLINK_NONE;
+
+static long_u	blink_waittime	= 700;
+static long_u	blink_ontime	= 400;
+static long_u	blink_offtime	= 250;
+
+static struct
+{
+    int	    key_sym;
+    char_u  vim_code0;
+    char_u  vim_code1;
+} special_keys[] =
+{
+    {Pk_Up,	    'k', 'u'},
+    {Pk_Down,	    'k', 'd'},
+    {Pk_Left,	    'k', 'l'},
+    {Pk_Right,	    'k', 'r'},
+
+    {Pk_F1,	    'k', '1'},
+    {Pk_F2,	    'k', '2'},
+    {Pk_F3,	    'k', '3'},
+    {Pk_F4,	    'k', '4'},
+    {Pk_F5,	    'k', '5'},
+    {Pk_F6,	    'k', '6'},
+    {Pk_F7,	    'k', '7'},
+    {Pk_F8,	    'k', '8'},
+    {Pk_F9,	    'k', '9'},
+    {Pk_F10,	    'k', ';'},
+
+    {Pk_F11,	    'F', '1'},
+    {Pk_F12,	    'F', '2'},
+    {Pk_F13,	    'F', '3'},
+    {Pk_F14,	    'F', '4'},
+    {Pk_F15,	    'F', '5'},
+    {Pk_F16,	    'F', '6'},
+    {Pk_F17,	    'F', '7'},
+    {Pk_F18,	    'F', '8'},
+    {Pk_F19,	    'F', '9'},
+    {Pk_F20,	    'F', 'A'},
+
+    {Pk_F21,	    'F', 'B'},
+    {Pk_F22,	    'F', 'C'},
+    {Pk_F23,	    'F', 'D'},
+    {Pk_F24,	    'F', 'E'},
+    {Pk_F25,	    'F', 'F'},
+    {Pk_F26,	    'F', 'G'},
+    {Pk_F27,	    'F', 'H'},
+    {Pk_F28,	    'F', 'I'},
+    {Pk_F29,	    'F', 'J'},
+
+    {Pk_F30,	    'F', 'K'},
+    {Pk_F31,	    'F', 'L'},
+    {Pk_F32,	    'F', 'M'},
+    {Pk_F33,	    'F', 'N'},
+    {Pk_F34,	    'F', 'O'},
+    {Pk_F35,	    'F', 'P'},
+
+    {Pk_Help,	    '%', '1'},
+    {Pk_BackSpace,  'k', 'b'},
+    {Pk_Insert,	    'k', 'I'},
+    {Pk_Delete,	    'k', 'D'},
+    {Pk_Home,	    'k', 'h'},
+    {Pk_End,	    '@', '7'},
+    {Pk_Prior,	    'k', 'P'},
+    {Pk_Next,	    'k', 'N'},
+    {Pk_Print,	    '%', '9'},
+
+    {Pk_KP_Add,	    'K', '6'},
+    {Pk_KP_Subtract,'K', '7'},
+    {Pk_KP_Divide,  'K', '8'},
+    {Pk_KP_Multiply,'K', '9'},
+    {Pk_KP_Enter,   'K', 'A'},
+
+    {Pk_KP_0,	    KS_EXTRA, KE_KINS}, /* Insert    */
+    {Pk_KP_Decimal, KS_EXTRA, KE_KDEL}, /* Delete    */
+
+    {Pk_KP_4,	    'k', 'l'}, /* Left	    */
+    {Pk_KP_6,	    'k', 'r'}, /* Right	    */
+    {Pk_KP_8,	    'k', 'u'}, /* Up	    */
+    {Pk_KP_2,	    'k', 'd'}, /* Down	    */
+
+    {Pk_KP_7,	    'K', '1'}, /* Home	    */
+    {Pk_KP_1,	    'K', '4'}, /* End	    */
+
+    {Pk_KP_9,	    'K', '3'}, /* Page Up   */
+    {Pk_KP_3,	    'K', '5'}, /* Page Down */
+
+    {Pk_KP_5,	    '&', '8'}, /* Undo	    */
+
+    /* Keys that we want to be able to use any modifier with: */
+    {Pk_Return,	    CAR,  NUL},
+    {Pk_space,	    ' ', NUL},
+    {Pk_Tab,	    TAB, NUL},
+    {Pk_Escape,	    ESC, NUL},
+    {NL,	    NL,	 NUL},
+    {CAR,	    CAR,  NUL},
+
+    /* End of list marker: */
+    {0,		0, 0}
+};
+
+
+/****************************************************************************/
+
+static PtCallbackF_t gui_ph_handle_timer_cursor;
+static PtCallbackF_t gui_ph_handle_timer_timeout;
+
+static PtCallbackF_t gui_ph_handle_window_cb;
+
+static PtCallbackF_t gui_ph_handle_scrollbar;
+static PtCallbackF_t gui_ph_handle_keyboard;
+static PtCallbackF_t gui_ph_handle_mouse;
+static PtCallbackF_t gui_ph_handle_pulldown_menu;
+static PtCallbackF_t gui_ph_handle_menu;
+static PtCallbackF_t gui_ph_handle_focus;	/* focus change of text area */
+
+static PtCallbackF_t gui_ph_handle_menu_resize;
+
+/* When a menu is unrealized, give focus back to vimTextArea */
+static PtCallbackF_t gui_ph_handle_menu_unrealized;
+
+#ifdef USE_PANEL_GROUP
+static void gui_ph_get_panelgroup_margins( short*, short*, short*, short* );
+#endif
+
+#ifdef FEAT_TOOLBAR
+static PhImage_t *gui_ph_toolbar_find_icon( vimmenu_T *menu );
+#endif
+
+static void gui_ph_draw_start( void );
+static void gui_ph_draw_end( void );
+
+/* Set the text for the balloon */
+static PtWidget_t * gui_ph_show_tooltip( PtWidget_t *window,
+			     PtWidget_t *widget,
+			     int position,
+			     char *text,
+			     char *font,
+			     PgColor_t fill_color,
+			     PgColor_t text_color );
+
+/****************************************************************************/
+
+static PtWidget_t * gui_ph_show_tooltip( PtWidget_t *window,
+			     PtWidget_t *widget,
+			     int position,
+			     char *text,
+			     char *font,
+			     PgColor_t fill_color,
+			     PgColor_t text_color )
+{
+    PtArg_t arg;
+    vimmenu_T *menu;
+    char_u  *tooltip;
+
+    PtSetArg( &arg, Pt_ARG_POINTER, &menu, 0 );
+    PtGetResources( widget, 1, &arg );
+
+    /* Override the text and position */
+
+    tooltip = text;
+    if( menu != NULL )
+    {
+	int index = MENU_INDEX_TIP;
+	if( menu->strings[ index ] != NULL )
+	    tooltip = menu->strings[ index ];
+    }
+
+    return( PtInflateBalloon(
+	    window,
+	    widget,
+	    /* Don't put the balloon at the bottom,
+	     * it gets drawn over by gfx done in the PtRaw */
+	    Pt_BALLOON_TOP,
+	    tooltip,
+	    font,
+	    fill_color,
+	    text_color ) );
+}
+
+    static void
+gui_ph_resize_container( void )
+{
+    PhArea_t area;
+
+    PtWidgetArea( gui.vimWindow, &area );
+    PtWidgetPos ( gui.vimContainer, &area.pos );
+
+    PtSetResource( gui.vimContainer, Pt_ARG_AREA, &area, 0 );
+}
+
+    static int
+gui_ph_handle_menu_resize(
+	PtWidget_t *widget,
+	void *other,
+	PtCallbackInfo_t *info )
+{
+    PtContainerCallback_t *sizes = info->cbdata;
+    PtWidget_t		*container;
+    PhPoint_t		below_menu;
+    int_u		height;
+
+    height = sizes->new_dim.h;
+
+    /* Because vim treats the toolbar and menubar separatly,
+     * and here they're lumped together into a PtToolbarGroup,
+     * we only need either menu_height or toolbar_height set at once */
+    if( gui.menu_is_active )
+    {
+	gui.menu_height = height;
+	gui.toolbar_height = 0;
+    }
+#ifdef FEAT_TOOLBAR
+    else
+	gui.toolbar_height = height;
+#endif
+
+    below_menu.x = 0;
+    below_menu.y = height;
+
+#ifdef USE_PANEL_GROUP
+    container = gui.vimPanelGroup;
+#else
+    container = gui.vimContainer;
+#endif
+
+    PtSetResource( container, Pt_ARG_POS, &below_menu, 0 );
+
+    gui_ph_resize_container();
+
+#ifdef USE_PANEL_GROUP
+    gui_ph_get_panelgroup_margins(
+	    &pg_margin_top, &pg_margin_bottom,
+	    &pg_margin_left, &pg_margin_right );
+#endif
+    return( Pt_CONTINUE );
+}
+
+/*
+ * Pt_ARG_TIMER_REPEAT isn't used because the on & off times
+ * are different
+ */
+    static int
+gui_ph_handle_timer_cursor(
+	PtWidget_t *widget,
+	void *data,
+	PtCallbackInfo_t *info )
+{
+    if( blink_state == BLINK_ON )
+    {
+	gui_undraw_cursor();
+	blink_state = BLINK_OFF;
+	PtSetResource( gui_ph_timer_cursor, Pt_ARG_TIMER_INITIAL,
+		blink_offtime, 0 );
+    }
+    else
+    {
+	gui_update_cursor(TRUE, FALSE);
+	blink_state = BLINK_ON;
+	PtSetResource( gui_ph_timer_cursor, Pt_ARG_TIMER_INITIAL,
+		blink_ontime, 0 );
+    }
+    return( Pt_CONTINUE );
+}
+
+    static int
+gui_ph_handle_timer_timeout(PtWidget_t *widget, void *data, PtCallbackInfo_t *info)
+{
+    is_timeout = TRUE;
+
+    return( Pt_CONTINUE );
+}
+
+    static int
+gui_ph_handle_window_cb( PtWidget_t *widget, void *data, PtCallbackInfo_t *info )
+{
+    PhWindowEvent_t *we = info->cbdata;
+    ushort_t *width, *height;
+
+    switch( we->event_f ) {
+	case Ph_WM_CLOSE:
+	    gui_shell_closed();
+	    break;
+
+	case Ph_WM_FOCUS:
+	    /* Just in case it's hidden and needs to be shown */
+	    gui_mch_mousehide( MOUSE_SHOW );
+
+	    if( we->event_state == Ph_WM_EVSTATE_FOCUS )
+	    {
+		gui_focus_change(TRUE);
+		gui_mch_start_blink();
+	    }
+	    else
+	    {
+		gui_focus_change(FALSE);
+		gui_mch_stop_blink();
+	    }
+	    break;
+
+	case Ph_WM_RESIZE:
+	    PtGetResource( gui.vimWindow, Pt_ARG_WIDTH, &width, 0 );
+	    PtGetResource( gui.vimWindow, Pt_ARG_HEIGHT, &height, 0 );
+#ifdef USE_PANEL_GROUP
+	    width  -= (pg_margin_left + pg_margin_right);
+	    height -= (pg_margin_top + pg_margin_bottom);
+#endif
+	    gui_resize_shell( *width, *height );
+	    gui_set_shellsize( FALSE, FALSE );
+	    is_ignore_draw = FALSE;
+	    PtEndFlux( gui.vimContainer );
+	    PtContainerRelease( gui.vimContainer );
+	    break;
+
+	default:
+	    break;
+    }
+
+    return( Pt_CONTINUE );
+}
+
+    static int
+gui_ph_handle_scrollbar( PtWidget_t *widget, void *data, PtCallbackInfo_t *info )
+{
+    PtScrollbarCallback_t *scroll;
+    scrollbar_T *sb;
+    int	    value, dragging = FALSE;
+
+    scroll = info->cbdata;
+
+    sb = (scrollbar_T *) data;
+    if( sb != NULL )
+    {
+	value = scroll->position;
+	switch( scroll->action )
+	{
+	    case Pt_SCROLL_DRAGGED:
+		dragging = TRUE;
+		break;
+
+	    case Pt_SCROLL_SET:
+		/* FIXME: return straight away here? */
+		return( Pt_CONTINUE );
+		break;
+	}
+
+	gui_drag_scrollbar(sb, value, dragging);
+    }
+    return( Pt_CONTINUE );
+}
+
+    static int
+gui_ph_handle_keyboard( PtWidget_t *widget, void *data, PtCallbackInfo_t *info )
+{
+    PhKeyEvent_t    *key;
+    unsigned char   string[6];
+    int		    len, i;
+    int		    ch, modifiers;
+
+    key = PhGetData( info->event );
+
+    ch = modifiers = len = 0;
+
+    if( p_mh )
+	gui_mch_mousehide( MOUSE_HIDE );
+
+    /* We're a good lil photon program, aren't we? yes we are, yeess wee arrr */
+    if( key->key_flags & Pk_KF_Compose )
+    {
+	return( Pt_CONTINUE );
+    }
+
+    if( (key->key_flags & Pk_KF_Cap_Valid) &&
+	    PkIsKeyDown( key->key_flags ) )
+    {
+#ifdef FEAT_MENU
+	/*
+	 * Only show the menu if the Alt key is down, and the Shift & Ctrl
+	 * keys aren't down, as well as the other conditions
+	 */
+	if( ( ( key->key_mods & Pk_KM_Alt ) &&
+		    !( key->key_mods & Pk_KM_Shift ) &&
+		    !( key->key_mods & Pk_KM_Ctrl ) ) &&
+	    gui.menu_is_active &&
+	    ( *p_wak == 'y' ||
+	      ( *p_wak == 'm' &&
+		gui_is_menu_shortcut( key->key_cap ) ) ) )
+	{
+	    /* Fallthrough and let photon look for the hotkey */
+	    return( Pt_CONTINUE );
+	}
+#endif
+
+	for( i = 0; special_keys[i].key_sym != 0; i++ )
+	{
+	    if( special_keys[i].key_sym == key->key_cap )
+	    {
+		len = 0;
+		if( special_keys[i].vim_code1 == NUL )
+		    ch = special_keys[i].vim_code0;
+		else
+		{
+		    /* Detect if a keypad number key has been pressed
+		     * and change the key if Num Lock is on */
+		    if( key->key_cap >= Pk_KP_Enter && key->key_cap <= Pk_KP_9
+			    && ( key->key_mods & Pk_KM_Num_Lock ) )
+		    {
+			/* FIXME: For now, just map the key to a ascii value
+			 * (see <photon/PkKeyDef.h>) */
+			ch = key->key_cap - 0xf080;
+		    }
+		    else
+			ch = TO_SPECIAL( special_keys[i].vim_code0,
+				special_keys[i].vim_code1 );
+		}
+		break;
+	    }
+	}
+
+	if( key->key_mods & Pk_KM_Ctrl )
+	    modifiers |= MOD_MASK_CTRL;
+	if( key->key_mods & Pk_KM_Alt )
+	    modifiers |= MOD_MASK_ALT;
+	if( key->key_mods & Pk_KM_Shift )
+	    modifiers |= MOD_MASK_SHIFT;
+
+	/* Is this not a special key? */
+	if( special_keys[i].key_sym == 0 )
+	{
+	    ch = PhTo8859_1( key );
+	    if( ch == -1
+#ifdef FEAT_MBYTE
+		|| ( enc_utf8 && ch > 127 )
+#endif
+		)
+	    {
+#ifdef FEAT_MBYTE
+		len = PhKeyToMb( string, key );
+		if( len > 0 )
+		{
+		    static char buf[6];
+		    int src_taken, dst_made;
+		    if( enc_utf8 != TRUE )
+		    {
+			PxTranslateFromUTF(
+				charset_translate,
+				string,
+				len,
+				&src_taken,
+				buf,
+				6,
+				&dst_made );
+
+			add_to_input_buf( buf, dst_made );
+		    }
+		    else
+		    {
+			add_to_input_buf( string, len );
+		    }
+
+		    return( Pt_CONSUME );
+		}
+		len = 0;
+#endif
+		ch = key->key_cap;
+		if( ch < 0xff )
+		{
+		    /* FIXME: is this the right thing to do? */
+		    if( modifiers & MOD_MASK_CTRL )
+		    {
+			modifiers &= ~MOD_MASK_CTRL;
+
+			if( ( ch >= 'a'  &&  ch <= 'z' ) ||
+				ch == '[' ||
+				ch == ']' ||
+				ch == '\\' )
+			    ch = Ctrl_chr( ch );
+			else if( ch == '2' )
+			    ch = NUL;
+			else if( ch == '6' )
+			    ch = 0x1e;
+			else if( ch == '-' )
+			    ch = 0x1f;
+			else
+			    modifiers |= MOD_MASK_CTRL;
+		    }
+
+		    if( modifiers & MOD_MASK_ALT )
+		    {
+			ch = Meta( ch );
+			modifiers &= ~MOD_MASK_ALT;
+		    }
+		}
+		else
+		{
+		    return( Pt_CONTINUE );
+		}
+	    }
+	    else
+		modifiers &= ~MOD_MASK_SHIFT;
+	}
+
+	ch = simplify_key( ch, &modifiers );
+	if( modifiers )
+	{
+	    string[ len++ ] = CSI;
+	    string[ len++ ] = KS_MODIFIER;
+	    string[ len++ ] = modifiers;
+	}
+
+	if( IS_SPECIAL( ch ) )
+	{
+	    string[ len++ ] = CSI;
+	    string[ len++ ] = K_SECOND( ch );
+	    string[ len++ ] = K_THIRD( ch );
+	}
+	else
+	{
+	    string[ len++ ] = ch;
+	}
+
+	if (len == 1 && ((ch == Ctrl_C && ctrl_c_interrupts)
+							  || ch == intr_char))
+	{
+	    trash_input_buf();
+	    got_int = TRUE;
+	}
+
+	if (len == 1 && string[0] == CSI)
+	{
+	    /* Turn CSI into K_CSI. */
+	    string[ len++ ] = KS_EXTRA;
+	    string[ len++ ] = KE_CSI;
+	}
+
+	if( len > 0 )
+	{
+	    add_to_input_buf( string, len );
+	    return( Pt_CONSUME );
+	}
+    }
+
+    return( Pt_CONTINUE );
+}
+
+    static int
+gui_ph_handle_mouse( PtWidget_t *widget, void *data, PtCallbackInfo_t *info )
+{
+    PhPointerEvent_t *pointer;
+    PhRect_t	     *pos;
+    int		     button = 0, repeated_click, modifiers = 0x0;
+    short	     mouse_x, mouse_y;
+
+    pointer = PhGetData( info->event );
+    pos = PhGetRects( info->event );
+
+    gui_mch_mousehide( MOUSE_SHOW );
+
+    /*
+     * Coordinates need to be relative to the base window,
+     * not relative to the vimTextArea widget
+     */
+    mouse_x = pos->ul.x + gui.border_width;
+    mouse_y = pos->ul.y + gui.border_width;
+
+    if( info->event->type == Ph_EV_PTR_MOTION_NOBUTTON )
+    {
+	gui_mouse_moved( mouse_x, mouse_y );
+	return( Pt_CONTINUE );
+    }
+
+    if( pointer->key_mods & Pk_KM_Shift )
+	modifiers |= MOUSE_SHIFT;
+    if( pointer->key_mods & Pk_KM_Ctrl )
+	modifiers |= MOUSE_CTRL;
+    if( pointer->key_mods & Pk_KM_Alt )
+	modifiers |= MOUSE_ALT;
+
+    /*
+     * FIXME More than one button may be involved, but for
+     * now just deal with one
+     */
+    if( pointer->buttons & Ph_BUTTON_SELECT )
+	button = MOUSE_LEFT;
+
+    if( pointer->buttons & Ph_BUTTON_MENU )
+    {
+	button = MOUSE_RIGHT;
+	/* Need the absolute coordinates for the popup menu */
+	abs_mouse.x = pointer->pos.x;
+	abs_mouse.y = pointer->pos.y;
+    }
+
+    if( pointer->buttons & Ph_BUTTON_ADJUST )
+	button = MOUSE_MIDDLE;
+
+    /* Catch a real release (not phantom or other releases */
+    if( info->event->type == Ph_EV_BUT_RELEASE )
+	button = MOUSE_RELEASE;
+
+    if( info->event->type & Ph_EV_PTR_MOTION_BUTTON )
+	button = MOUSE_DRAG;
+
+#if 0
+    /* Vim doesn't use button repeats */
+    if( info->event->type & Ph_EV_BUT_REPEAT )
+	button = MOUSE_DRAG;
+#endif
+
+    /* Don't do anything if it is one of the phantom mouse release events */
+    if( ( button != MOUSE_RELEASE ) ||
+	    ( info->event->subtype == Ph_EV_RELEASE_REAL ) )
+    {
+	repeated_click = (pointer->click_count >= 2) ? TRUE : FALSE;
+
+	gui_send_mouse_event( button , mouse_x, mouse_y, repeated_click, modifiers );
+    }
+
+    return( Pt_CONTINUE );
+}
+
+/* Handle a focus change of the PtRaw widget */
+    static int
+gui_ph_handle_focus( PtWidget_t *widget, void *data, PtCallbackInfo_t *info )
+{
+    if( info->reason == Pt_CB_LOST_FOCUS )
+    {
+	PtRemoveEventHandler( gui.vimTextArea, Ph_EV_PTR_MOTION_NOBUTTON,
+		gui_ph_handle_mouse, NULL );
+
+	gui_mch_mousehide( MOUSE_SHOW );
+    }
+    else
+    {
+	PtAddEventHandler( gui.vimTextArea, Ph_EV_PTR_MOTION_NOBUTTON,
+		gui_ph_handle_mouse, NULL );
+    }
+    return( Pt_CONTINUE );
+}
+
+    static void
+gui_ph_handle_raw_draw( PtWidget_t *widget, PhTile_t *damage )
+{
+    PhRect_t	*r;
+    PhPoint_t	offset;
+    PhPoint_t	translation;
+
+    if( is_ignore_draw == TRUE )
+	return;
+
+    PtSuperClassDraw( PtBasic, widget, damage );
+    PgGetTranslation( &translation );
+    PgClearTranslation();
+
+#if 0
+    /*
+     * This causes some wierd probems, with drawing being done from
+     * within this raw drawing function (rather than just simple clearing
+     * and text drawing done by gui_redraw)
+     *
+     * The main problem is when PhBlit is used, and the cursor appearing
+     * in places where it shouldn't
+     */
+    out_flush();
+#endif
+
+    PtWidgetOffset( widget, &offset );
+    PhTranslatePoint( &offset, PtWidgetPos( gui.vimTextArea, NULL ) );
+
+#if 1
+    /* Redraw individual damage regions */
+    if( damage->next != NULL )
+	damage = damage->next;
+
+    while( damage != NULL )
+    {
+	r = &damage->rect;
+	gui_redraw(
+		r->ul.x - offset.x, r->ul.y - offset.y,
+		r->lr.x - r->ul.x + 1,
+		r->lr.y - r->ul.y + 1 );
+	damage = damage->next;
+    }
+#else
+    /* Redraw the rectangle that covers all the damaged regions */
+    r = &damage->rect;
+    gui_redraw(
+	    r->ul.x - offset.x, r->ul.y - offset.y,
+	    r->lr.x - r->ul.x + 1,
+	    r->lr.y - r->ul.y + 1 );
+#endif
+
+    PgSetTranslation( &translation, 0 );
+}
+
+    static int
+gui_ph_handle_pulldown_menu(
+	PtWidget_t *widget,
+	void *data,
+	PtCallbackInfo_t *info )
+{
+    if( data != NULL )
+    {
+	vimmenu_T *menu = (vimmenu_T *) data;
+
+	PtPositionMenu( menu->submenu_id, NULL );
+	PtRealizeWidget( menu->submenu_id );
+    }
+
+    return( Pt_CONTINUE );
+}
+
+/* This is used for pulldown/popup menus and also toolbar buttons */
+    static int
+gui_ph_handle_menu( PtWidget_t *widget, void *data, PtCallbackInfo_t *info )
+{
+    if( data != NULL )
+    {
+	vimmenu_T *menu = (vimmenu_T *) data;
+	gui_menu_cb( menu );
+    }
+    return( Pt_CONTINUE );
+}
+
+/* Stop focus from disappearing into the menubar... */
+    static int
+gui_ph_handle_menu_unrealized(
+	PtWidget_t *widget,
+	void *data,
+	PtCallbackInfo_t *info )
+{
+    PtGiveFocus( gui.vimTextArea, NULL );
+    return( Pt_CONTINUE );
+}
+
+    static int
+gui_ph_handle_window_open(
+	PtWidget_t *widget,
+	void *data,
+	PtCallbackInfo_t *info )
+{
+    gui_set_shellsize( FALSE, TRUE );
+    return( Pt_CONTINUE );
+}
+
+/****************************************************************************/
+
+#define DRAW_START  gui_ph_draw_start()
+#define DRAW_END    gui_ph_draw_end()
+
+/* TODO: Set a clipping rect? */
+    static void
+gui_ph_draw_start( void )
+{
+    PgSetRegion( PtWidgetRid( PtFindDisjoint( gui.vimTextArea ) ) );
+
+    PtWidgetOffset( gui.vimTextArea, &gui_ph_raw_offset );
+    PhTranslatePoint( &gui_ph_raw_offset, PtWidgetPos( gui.vimTextArea, NULL ) );
+
+    PgSetTranslation( &gui_ph_raw_offset, Pg_RELATIVE );
+}
+
+    static void
+gui_ph_draw_end( void )
+{
+    gui_ph_raw_offset.x = -gui_ph_raw_offset.x;
+    gui_ph_raw_offset.y = -gui_ph_raw_offset.y;
+    PgSetTranslation( &gui_ph_raw_offset, Pg_RELATIVE );
+}
+
+#ifdef USE_PANEL_GROUP
+    static vimmenu_T *
+gui_ph_find_buffer_item( char_u *name )
+{
+    vimmenu_T *top_level = root_menu;
+    vimmenu_T *items = NULL;
+
+    while( top_level != NULL &&
+	    ( STRCMP( top_level->dname, "Buffers" ) != 0 ) )
+	top_level = top_level->next;
+
+    if( top_level != NULL )
+    {
+	items = top_level->children;
+
+	while( items != NULL &&
+		( STRCMP( items->dname, name ) != 0 ) )
+	    items = items->next;
+    }
+    return( items );
+}
+
+    static void
+gui_ph_pg_set_buffer_num( int_u buf_num )
+{
+    int i;
+    char search[16];
+    char *mark;
+
+    if( gui.vimTextArea == NULL || buf_num == 0 )
+	return;
+
+    search[0] = '(';
+    ultoa( buf_num, &search[1], 10 );
+    STRCAT( search, ")" );
+
+    for( i = 0; i < num_panels; i++ )
+    {
+	/* find the last "(" in the panel title and see if the buffer
+	 * number in the title matches the one we're looking for */
+	mark = STRRCHR( panel_titles[ i ], '(' );
+	if( mark != NULL && STRCMP( mark, search ) == 0 )
+	{
+	    PtSetResource( gui.vimPanelGroup, Pt_ARG_PG_CURRENT_INDEX,
+		    i, 0 );
+	}
+    }
+}
+
+    static int
+gui_ph_handle_pg_change(
+	PtWidget_t *widget,
+	void *data,
+	PtCallbackInfo_t *info )
+{
+    vimmenu_T *menu;
+    PtPanelGroupCallback_t *panel;
+
+    if( info->event != NULL )
+    {
+	panel = info->cbdata;
+	if( panel->new_panel != NULL )
+	{
+	    menu = gui_ph_find_buffer_item( panel->new_panel );
+	    if( menu )
+		gui_menu_cb( menu );
+	}
+    }
+    return( Pt_CONTINUE );
+}
+
+    static void
+gui_ph_get_panelgroup_margins(
+	short *top,
+	short *bottom,
+	short *left,
+	short *right )
+{
+    unsigned short abs_raw_x, abs_raw_y, abs_panel_x, abs_panel_y;
+    const unsigned short *margin_top, *margin_bottom;
+    const unsigned short *margin_left, *margin_right;
+
+    PtGetAbsPosition( gui.vimTextArea, &abs_raw_x, &abs_raw_y );
+    PtGetAbsPosition( gui.vimPanelGroup, &abs_panel_x, &abs_panel_y );
+
+    PtGetResource( gui.vimPanelGroup, Pt_ARG_MARGIN_RIGHT, &margin_right, 0 );
+    PtGetResource( gui.vimPanelGroup, Pt_ARG_MARGIN_BOTTOM, &margin_bottom, 0 );
+
+    abs_raw_x -= abs_panel_x;
+    abs_raw_y -= abs_panel_y;
+
+    *top    = abs_raw_y;
+    *bottom = *margin_bottom;
+
+    *left  = abs_raw_x;
+    *right = *margin_right;
+}
+
+/* Used for the tabs for PtPanelGroup */
+    static int
+gui_ph_is_buffer_item( vimmenu_T *menu, vimmenu_T *parent )
+{
+    char *mark;
+
+    if( STRCMP( parent->dname, "Buffers" ) == 0 )
+    {
+	/* Look for '(' digits ')' */
+	mark = vim_strchr( menu->dname, '(' );
+	if( mark != NULL )
+	{
+	    mark++;
+	    while( isdigit( *mark ) )
+		mark++;
+
+	    if( *mark == ')' )
+		return( TRUE);
+	}
+    }
+    return( FALSE );
+}
+
+    static void
+gui_ph_pg_add_buffer(char *name )
+{
+    char **new_titles = NULL;
+
+    new_titles = (char **) alloc( ( num_panels + 1 ) * sizeof( char ** ) );
+    if( new_titles != NULL )
+    {
+	if( num_panels > 0 )
+	    memcpy( new_titles, panel_titles, num_panels * sizeof( char ** ) );
+
+	new_titles[ num_panels++ ] = name;
+
+	PtSetResource( gui.vimPanelGroup, Pt_ARG_PG_PANEL_TITLES, new_titles,
+		num_panels );
+
+	vim_free( panel_titles );
+	panel_titles = new_titles;
+    }
+}
+
+    static void
+gui_ph_pg_remove_buffer( char *name )
+{
+    int i;
+    char **new_titles = NULL;
+
+    /* If there is only 1 panel, we just use the temporary place holder */
+    if( num_panels > 1 )
+    {
+	new_titles = (char **) alloc( ( num_panels - 1 ) * sizeof( char ** ) );
+	if( new_titles != NULL )
+	{
+	    char **s = new_titles;
+	    /* Copy all the titles except the one we're removing */
+	    for( i = 0; i < num_panels; i++ )
+	    {
+		if( STRCMP( panel_titles[ i ], name ) != 0 )
+		{
+		    *s++ = panel_titles[ i ];
+		}
+	    }
+	    num_panels--;
+
+	    PtSetResource( gui.vimPanelGroup, Pt_ARG_PG_PANEL_TITLES, new_titles,
+		    num_panels );
+
+	    vim_free( panel_titles );
+	    panel_titles = new_titles;
+	}
+    }
+    else
+    {
+	num_panels--;
+	PtSetResource( gui.vimPanelGroup, Pt_ARG_PG_PANEL_TITLES, &empty_title,
+		1 );
+
+	vim_free( panel_titles );
+	panel_titles = NULL;
+    }
+}
+
+/* When a buffer item is deleted from the buffer menu */
+    static int
+gui_ph_handle_buffer_remove(
+	PtWidget_t *widget,
+	void *data,
+	PtCallbackInfo_t *info )
+{
+    vimmenu_T *menu;
+
+    if( data != NULL )
+    {
+	menu = (vimmenu_T *) data;
+	gui_ph_pg_remove_buffer( menu->dname );
+    }
+
+    return( Pt_CONTINUE );
+}
+#endif
+
+    static int
+gui_ph_pane_resize( PtWidget_t *widget, void *data, PtCallbackInfo_t *info )
+{
+    if( PtWidgetIsRealized( widget ) )
+    {
+	is_ignore_draw = TRUE;
+	PtStartFlux( gui.vimContainer );
+	PtContainerHold( gui.vimContainer );
+    }
+
+    return( Pt_CONTINUE );
+}
+
+/****************************************************************************/
+
+#ifdef FEAT_MBYTE
+    void
+gui_ph_encoding_changed( int new_encoding )
+{
+    /* Default encoding is latin1 */
+    char *charset = "latin1";
+    int i;
+
+    struct {
+	int encoding;
+	char *name;
+    } charsets[] = {
+	{ DBCS_JPN, "SHIFT_JIS" },
+	{ DBCS_KOR, "csEUCKR" },
+	{ DBCS_CHT, "big5" },
+	{ DBCS_CHS, "gb" }
+    };
+
+    for( i = 0; i < ARRAY_LENGTH( charsets ); i++ )
+    {
+	if( new_encoding == charsets[ i ].encoding )
+	    charset = charsets[ i ].name;
+    }
+
+    charset_translate = PxTranslateSet( charset_translate, charset );
+}
+#endif
+
+/****************************************************************************/
+/****************************************************************************/
+
+    void
+gui_mch_prepare(argc, argv)
+    int	    *argc;
+    char    **argv;
+{
+    PtInit( NULL );
+}
+
+    int
+gui_mch_init(void)
+{
+    PtArg_t args[10];
+    int	    flags = 0, n = 0;
+
+    PhDim_t	window_size = {100, 100}; /* Abitrary values */
+    PhPoint_t	pos = {0, 0};
+
+    gui.event_buffer = (PhEvent_t *) alloc( EVENT_BUFFER_SIZE );
+    if( gui.event_buffer == NULL )
+	return( FAIL );
+
+    /* Get a translation so we can convert from ISO Latin-1 to UTF */
+    charset_translate = PxTranslateSet( NULL, "latin1" );
+
+    /* The +2 is for the 1 pixel dark line on each side */
+    gui.border_offset = gui.border_width = GUI_PH_MARGIN + 2;
+
+    /* Handle close events ourselves */
+    PtSetArg( &args[ n++ ], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_CLOSE );
+    PtSetArg( &args[ n++ ], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE,
+	    Ph_WM_CLOSE | Ph_WM_RESIZE | Ph_WM_FOCUS );
+    PtSetArg( &args[ n++ ], Pt_ARG_DIM, &window_size, 0 );
+    gui.vimWindow = PtCreateWidget( PtWindow, NULL, n, args );
+    if( gui.vimWindow == NULL )
+	return( FAIL );
+
+    PtAddCallback( gui.vimWindow, Pt_CB_WINDOW, gui_ph_handle_window_cb, NULL );
+    PtAddCallback( gui.vimWindow, Pt_CB_WINDOW_OPENING,
+	    gui_ph_handle_window_open, NULL );
+
+    n = 0;
+    PtSetArg( &args[ n++ ], Pt_ARG_ANCHOR_FLAGS, Pt_ANCHOR_ALL, Pt_IS_ANCHORED );
+    PtSetArg( &args[ n++ ], Pt_ARG_DIM, &window_size, 0 );
+    PtSetArg( &args[ n++ ], Pt_ARG_POS, &pos, 0 );
+
+#ifdef USE_PANEL_GROUP
+    /* Put in a temprary place holder title */
+    PtSetArg( &args[ n++ ], Pt_ARG_PG_PANEL_TITLES, &empty_title, 1 );
+
+    gui.vimPanelGroup = PtCreateWidget( PtPanelGroup, gui.vimWindow, n, args );
+    if( gui.vimPanelGroup == NULL )
+	return( FAIL );
+
+    PtAddCallback( gui.vimPanelGroup, Pt_CB_PG_PANEL_SWITCHING,
+	    gui_ph_handle_pg_change, NULL );
+#else
+    /* Turn off all edge decorations */
+    PtSetArg( &args[ n++ ], Pt_ARG_BASIC_FLAGS, Pt_FALSE, Pt_ALL );
+    PtSetArg( &args[ n++ ], Pt_ARG_BEVEL_WIDTH, 0, 0 );
+    PtSetArg( &args[ n++ ], Pt_ARG_MARGIN_WIDTH, 0, 0 );
+    PtSetArg( &args[ n++ ], Pt_ARG_MARGIN_HEIGHT, 0, 0 );
+    PtSetArg( &args[ n++ ], Pt_ARG_CONTAINER_FLAGS, Pt_TRUE, Pt_AUTO_EXTENT );
+
+    gui.vimContainer = PtCreateWidget( PtPane, gui.vimWindow, n, args );
+    if( gui.vimContainer == NULL )
+	return( FAIL );
+
+    PtAddCallback( gui.vimContainer, Pt_CB_RESIZE, gui_ph_pane_resize, NULL );
+#endif
+
+    /* Size for the text area is set in gui_mch_set_text_area_pos */
+    n = 0;
+
+    PtSetArg( &args[ n++ ], Pt_ARG_RAW_DRAW_F, gui_ph_handle_raw_draw, 1 );
+    PtSetArg( &args[ n++ ], Pt_ARG_BEVEL_WIDTH, GUI_PH_MARGIN, 0 );
+    /*
+     * Using focus render also causes the whole widget to be redrawn
+     * whenever it changes focus, which is very annoying :p
+     */
+    PtSetArg( &args[ n++ ], Pt_ARG_FLAGS, Pt_TRUE,
+	    Pt_GETS_FOCUS | Pt_HIGHLIGHTED );
+#ifndef FEAT_MOUSESHAPE
+    PtSetArg( &args[ n++ ], Pt_ARG_CURSOR_TYPE, GUI_PH_MOUSE_TYPE, 0 );
+    PtSetArg( &args[ n++ ], Pt_ARG_CURSOR_COLOR, gui_ph_mouse_color, 0 );
+#endif
+
+    gui.vimTextArea = PtCreateWidget( PtRaw, Pt_DFLT_PARENT, n, args );
+    if( gui.vimTextArea == NULL)
+	return( FAIL );
+
+    /* TODO: use PtAddEventHandlers instead? */
+    /* Not using Ph_EV_BUT_REPEAT because vim wouldn't use it anyway */
+    PtAddEventHandler( gui.vimTextArea,
+	    Ph_EV_BUT_PRESS | Ph_EV_BUT_RELEASE | Ph_EV_PTR_MOTION_BUTTON,
+	    gui_ph_handle_mouse, NULL );
+    PtAddEventHandler( gui.vimTextArea, Ph_EV_KEY,
+	    gui_ph_handle_keyboard, NULL );
+    PtAddCallback( gui.vimTextArea, Pt_CB_GOT_FOCUS,
+	    gui_ph_handle_focus, NULL );
+    PtAddCallback( gui.vimTextArea, Pt_CB_LOST_FOCUS,
+	    gui_ph_handle_focus, NULL );
+
+    /*
+     * Now that the text area widget has been created, set up the colours,
+     * which wil call PtSetResource from gui_mch_new_colors
+     */
+
+    /*
+     * Create the two timers, not as accurate as using the kernel timer
+     * functions, but good enough
+     */
+    gui_ph_timer_cursor  = PtCreateWidget( PtTimer, gui.vimWindow, 0, NULL );
+    if( gui_ph_timer_cursor == NULL )
+	return( FAIL );
+
+    gui_ph_timer_timeout = PtCreateWidget( PtTimer, gui.vimWindow, 0, NULL );
+    if( gui_ph_timer_timeout == NULL )
+	return( FAIL );
+
+    PtAddCallback( gui_ph_timer_cursor,  Pt_CB_TIMER_ACTIVATE,
+	    gui_ph_handle_timer_cursor, NULL);
+    PtAddCallback( gui_ph_timer_timeout, Pt_CB_TIMER_ACTIVATE,
+	    gui_ph_handle_timer_timeout, NULL);
+
+#ifdef FEAT_MENU
+    n = 0;
+    PtSetArg( &args[ n++ ], Pt_ARG_WIDTH, window_size.w, 0 );
+    PtSetArg( &args[ n++ ], Pt_ARG_ANCHOR_FLAGS, Pt_ANCHOR_LEFT_RIGHT,
+	    Pt_IS_ANCHORED );
+    gui.vimToolBarGroup = PtCreateWidget( PtToolbarGroup, gui.vimWindow,
+	    n, args );
+    if( gui.vimToolBarGroup == NULL )
+	return( FAIL );
+
+    PtAddCallback( gui.vimToolBarGroup, Pt_CB_RESIZE,
+	    gui_ph_handle_menu_resize, NULL );
+
+    n = 0;
+    flags = 0;
+    PtSetArg( &args[ n++ ], Pt_ARG_WIDTH, window_size.w, 0 );
+    if( ! vim_strchr( p_go, GO_MENUS ) )
+    {
+	flags |= Pt_DELAY_REALIZE;
+	PtSetArg( &args[ n++ ], Pt_ARG_FLAGS, Pt_TRUE, flags );
+    }
+    gui.vimMenuBar = PtCreateWidget( PtMenuBar, gui.vimToolBarGroup, n, args );
+    if( gui.vimMenuBar == NULL )
+	return( FAIL );
+
+# ifdef FEAT_TOOLBAR
+    n = 0;
+
+    PtSetArg( &args[ n++ ], Pt_ARG_ANCHOR_FLAGS,
+	    Pt_ANCHOR_LEFT_RIGHT |Pt_TOP_ANCHORED_TOP, Pt_IS_ANCHORED );
+    PtSetArg( &args[ n++ ], Pt_ARG_RESIZE_FLAGS, Pt_TRUE,
+	    Pt_RESIZE_Y_AS_REQUIRED );
+    PtSetArg( &args[ n++ ], Pt_ARG_WIDTH, window_size.w, 0 );
+
+    flags = Pt_GETS_FOCUS;
+    if( ! vim_strchr( p_go, GO_TOOLBAR ) )
+	flags |= Pt_DELAY_REALIZE;
+
+    PtSetArg( &args[ n++ ], Pt_ARG_FLAGS, Pt_DELAY_REALIZE, flags );
+
+    gui.vimToolBar = PtCreateWidget( PtToolbar, gui.vimToolBarGroup, n, args );
+    if( gui.vimToolBar == NULL )
+	return( FAIL );
+
+    /*
+     * Size for the toolbar is fetched in gui_mch_show_toolbar, after
+     * the buttons have been added and the toolbar has resized it's height
+     * for the buttons to fit
+     */
+# endif
+
+#endif
+
+    return( OK );
+}
+
+    int
+gui_mch_init_check(void)
+{
+    return( (is_photon_available == TRUE) ? OK : FAIL );
+}
+
+    int
+gui_mch_open(void)
+{
+    gui.norm_pixel =  Pg_BLACK;
+    gui.back_pixel =  Pg_WHITE;
+
+    set_normal_colors();
+
+    gui_check_colors();
+    gui.def_norm_pixel = gui.norm_pixel;
+    gui.def_back_pixel = gui.back_pixel;
+
+    highlight_gui_started();
+
+    if (gui_win_x != -1 && gui_win_y != -1)
+	gui_mch_set_winpos(gui_win_x, gui_win_y);
+
+    return( (PtRealizeWidget( gui.vimWindow ) == 0) ? OK : FAIL );
+}
+
+    void
+gui_mch_exit(int rc)
+{
+    PtDestroyWidget( gui.vimWindow );
+
+    PxTranslateSet( charset_translate, NULL );
+
+    vim_free( gui.event_buffer );
+
+#ifdef USE_PANEL_GROUPS
+    vim_free( panel_titles );
+#endif
+}
+
+/****************************************************************************/
+/* events */
+
+/* When no events are available, photon will call this function, working is
+ * set to FALSE, and the gui_mch_update loop will exit. */
+    static int
+exit_gui_mch_update( void *data )
+{
+    *(int *)data = FALSE;
+    return( Pt_END );
+}
+
+    void
+gui_mch_update(void)
+{
+    int working = TRUE;
+
+    PtAppAddWorkProc( NULL, exit_gui_mch_update, &working );
+    while( ( working == TRUE ) && !vim_is_input_buf_full())
+    {
+	PtProcessEvent();
+    }
+}
+
+    int
+gui_mch_wait_for_chars(int wtime)
+{
+    is_timeout = FALSE;
+
+    if( wtime > 0 )
+	PtSetResource( gui_ph_timer_timeout, Pt_ARG_TIMER_INITIAL, wtime, 0 );
+
+    while( 1 )
+    {
+	PtProcessEvent();
+	if( input_available() )
+	{
+	    PtSetResource( gui_ph_timer_timeout, Pt_ARG_TIMER_INITIAL, 0, 0 );
+	    return( OK );
+	}
+	else if( is_timeout == TRUE )
+	    return( FAIL );
+    }
+}
+
+#if defined( FEAT_BROWSE ) || defined( PROTO )
+/*
+ * Put up a file requester.
+ * Returns the selected name in allocated memory, or NULL for Cancel.
+ * saving,	    select file to write
+ * title	    title for the window
+ * default_name	    default name (well duh!)
+ * ext		    not used (extension added)
+ * initdir	    initial directory, NULL for current dir
+ * filter	    not used (file name filter)
+ */
+    char_u *
+gui_mch_browse(
+	int saving,
+	char_u *title,
+	char_u *default_name,
+	char_u *ext,
+	char_u *initdir,
+	char_u *filter)
+{
+    PtFileSelectionInfo_t file;
+    int	    flags;
+    char_u  *default_path;
+    char_u  *open_text = NULL;
+
+    flags = 0;
+    memset( &file, 0, sizeof( file ) );
+
+    default_path = alloc( MAXPATHL + 1 + NAME_MAX + 1 );
+    if( default_path != NULL )
+    {
+	if( saving == TRUE )
+	{
+	    /* Don't need Pt_FSR_CONFIRM_EXISTING, vim will ask anyway */
+	    flags |= Pt_FSR_NO_FCHECK;
+	    open_text = "&Save";
+	}
+
+	/* combine the directory and filename into a single path */
+	if( initdir == NULL || *initdir == NUL )
+	{
+	    mch_dirname( default_path, MAXPATHL );
+	    initdir = default_path;
+	}
+	else
+	{
+	    STRCPY( default_path, initdir );
+	    initdir = default_path;
+	}
+
+	if( default_name != NULL )
+	{
+	    if( default_path[ STRLEN( default_path ) - 1 ] != '/' )
+		STRCAT( default_path, "/" );
+
+	    STRCAT( default_path, default_name );
+	}
+
+	/* TODO: add a filter? */
+	PtFileSelection(
+		gui.vimWindow,
+		NULL,
+		title,
+		default_path,
+		NULL,
+		open_text,
+		NULL,
+		NULL,
+		&file,
+		flags );
+
+	vim_free( default_path );
+
+	if( file.ret == Pt_FSDIALOG_BTN1 )
+	    return( vim_strsave( file.path ) );
+    }
+    return( NULL );
+}
+#endif
+
+#if defined( FEAT_GUI_DIALOG ) || defined( PROTO )
+static PtWidget_t *gui_ph_dialog_text = NULL;
+
+    static int
+gui_ph_dialog_close( int button, void *data )
+{
+    PtModalCtrl_t *modal_ctrl = data;
+    char_u *dialog_text, *vim_text;
+
+    if( gui_ph_dialog_text != NULL )
+    {
+	PtGetResource( gui_ph_dialog_text, Pt_ARG_TEXT_STRING, &dialog_text, 0 );
+	PtGetResource( gui_ph_dialog_text, Pt_ARG_POINTER, &vim_text, 0 );
+	STRNCPY( vim_text, dialog_text, IOSIZE - 1 );
+    }
+
+    PtModalUnblock( modal_ctrl, (void *) button );
+
+    return( Pt_TRUE );
+}
+
+    static int
+gui_ph_dialog_text_enter( PtWidget_t *widget, void *data, PtCallbackInfo_t *info )
+{
+    if( info->reason_subtype == Pt_EDIT_ACTIVATE )
+	gui_ph_dialog_close( 1, data );
+    return( Pt_CONTINUE );
+}
+
+    static int
+gui_ph_dialog_esc( PtWidget_t *widget, void *data, PtCallbackInfo_t *info )
+{
+    PhKeyEvent_t *key;
+
+    key = PhGetData( info->event );
+    if( ( key->key_flags & Pk_KF_Cap_Valid ) && ( key->key_cap == Pk_Escape ) )
+    {
+	gui_ph_dialog_close( 0, data );
+	return( Pt_CONSUME );
+    }
+    return( Pt_PROCESS );
+}
+
+    int
+gui_mch_dialog(
+	int	type,
+	char_u	*title,
+	char_u	*message,
+	char_u	*buttons,
+	int	default_button,
+	char_u	*textfield)
+{
+    char_u	*str;
+    char_u	**button_array;
+    char_u	*buttons_copy;
+
+    int		button_count;
+    int		i, len;
+    int		dialog_result = -1;
+
+    /* FIXME: the vertical option in guioptions is blatantly ignored */
+    /* FIXME: so is the type */
+
+    button_count = len = i = 0;
+
+    if( buttons == NULL || *buttons == NUL )
+	return( -1 );
+
+    /* There is one less separator than buttons, so bump up the button count */
+    button_count = 1;
+
+    /* Count string length and number of seperators */
+    for( str = buttons; *str; str++ )
+    {
+	len++;
+	if( *str == DLG_BUTTON_SEP )
+	    button_count++;
+    }
+
+    if ( title == NULL )
+	title = "Vim";
+
+    buttons_copy = alloc( len + 1 );
+    button_array = (char_u **) alloc( button_count * sizeof( char_u * ) );
+    if( buttons_copy != NULL && button_array != NULL )
+    {
+	STRCPY( buttons_copy, buttons );
+
+	/*
+	 * Convert DLG_BUTTON_SEP into NUL's and fill in
+	 * button_array with the pointer to each NUL terminated string
+	 */
+	str = buttons_copy;
+	for( i = 0; i < button_count; i++ )
+	{
+	    button_array[ i ] = str;
+	    for( ; *str; str++ )
+	    {
+		if( *str == DLG_BUTTON_SEP )
+		{
+		    *str++ = NUL;
+		    break;
+		}
+	    }
+	}
+#ifndef FEAT_GUI_TEXTDIALOG
+	dialog_result = PtAlert(
+		gui.vimWindow, NULL,
+		title,
+		NULL,
+		message, NULL,
+		button_count, (const char **) button_array, NULL,
+		default_button, 0, Pt_MODAL );
+#else
+	/* Writing the dialog ourselves lets us add extra features, like
+	 * trapping the escape key and returning 0 to vim */
+	{
+	    int n;
+	    PtArg_t args[5];
+	    PtWidget_t *dialog, *pane;
+	    PtModalCtrl_t modal_ctrl;
+	    PtDialogInfo_t di;
+
+	    memset( &di, 0, sizeof( di ) );
+	    memset( &modal_ctrl, 0, sizeof( modal_ctrl ) );
+
+	    n = 0;
+	    PtSetArg( &args[n++], Pt_ARG_GROUP_ROWS_COLS, 0, 0 );
+	    PtSetArg( &args[n++], Pt_ARG_WIDTH, 350, 0 );
+	    PtSetArg( &args[n++], Pt_ARG_GROUP_ORIENTATION,
+		    Pt_GROUP_VERTICAL, 0 );
+	    PtSetArg( &args[n++], Pt_ARG_GROUP_FLAGS,
+		    Pt_TRUE, Pt_GROUP_NO_KEYS | Pt_GROUP_STRETCH_HORIZONTAL );
+	    PtSetArg( &args[n++], Pt_ARG_CONTAINER_FLAGS, Pt_FALSE, Pt_TRUE );
+	    pane = PtCreateWidget( PtGroup, NULL, n, args );
+
+	    n = 0;
+	    PtSetArg( &args[n++], Pt_ARG_TEXT_STRING, message, 0 );
+	    PtCreateWidget( PtLabel, pane, n, args );
+
+	    if( textfield != NULL )
+	    {
+		n = 0;
+		PtSetArg( &args[n++], Pt_ARG_MAX_LENGTH, IOSIZE - 1, 0 );
+		PtSetArg( &args[n++], Pt_ARG_TEXT_STRING, textfield, 0 );
+		PtSetArg( &args[n++], Pt_ARG_POINTER, textfield, 0 );
+		gui_ph_dialog_text = PtCreateWidget( PtText, pane, n, args );
+		PtAddCallback( gui_ph_dialog_text, Pt_CB_ACTIVATE,
+			gui_ph_dialog_text_enter, &modal_ctrl );
+	    }
+
+	    di.parent = gui.vimWindow;
+	    di.pane = pane;
+	    di.title = title;
+	    di.buttons = (const char **) button_array;
+	    di.nbtns = button_count;
+	    di.def_btn = default_button;
+	    /* This is just to give the dialog the close button.
+	     * We check for the Escape key ourselves and return 0 */
+	    di.esc_btn = button_count;
+	    di.callback = gui_ph_dialog_close;
+	    di.data = &modal_ctrl;
+
+	    dialog = PtCreateDialog( &di );
+	    PtAddFilterCallback( dialog, Ph_EV_KEY,
+		    gui_ph_dialog_esc, &modal_ctrl );
+
+	    if( gui_ph_dialog_text != NULL )
+		PtGiveFocus( gui_ph_dialog_text, NULL );
+
+	    /* Open dialog, block the vim window and wait for the dialog to close */
+	    PtRealizeWidget( dialog );
+	    PtMakeModal( dialog, Ph_CURSOR_NOINPUT, Ph_CURSOR_DEFAULT_COLOR );
+	    dialog_result = (int) PtModalBlock( &modal_ctrl, 0 );
+
+	    PtDestroyWidget( dialog );
+	    gui_ph_dialog_text = NULL;
+	}
+#endif
+    }
+
+    vim_free( button_array );
+    vim_free( buttons_copy );
+
+    return( dialog_result );
+}
+#endif
+/****************************************************************************/
+/* window size/position/state */
+
+    int
+gui_mch_get_winpos(int *x, int *y)
+{
+    PhPoint_t *pos;
+
+    pos = PtWidgetPos( gui.vimWindow, NULL );
+
+    *x = pos->x;
+    *y = pos->y;
+
+    return( OK );
+}
+
+    void
+gui_mch_set_winpos(int x, int y)
+{
+    PhPoint_t pos = { x, y };
+
+    PtSetResource( gui.vimWindow, Pt_ARG_POS, &pos, 0 );
+}
+
+    void
+gui_mch_set_shellsize(int width, int height,
+	int min_width, int min_height, int base_width, int base_height)
+{
+    PhDim_t window_size = { width, height };
+    PhDim_t min_size = { min_width, min_height };
+
+#ifdef USE_PANEL_GROUP
+    window_size.w += pg_margin_left + pg_margin_right;
+    window_size.h += pg_margin_top + pg_margin_bottom;
+#endif
+
+    PtSetResource( gui.vimWindow, Pt_ARG_MINIMUM_DIM, &min_size, 0 );
+    PtSetResource( gui.vimWindow, Pt_ARG_DIM, &window_size, 0 );
+
+    if( ! PtWidgetIsRealized( gui.vimWindow ) )
+	gui_ph_resize_container();
+}
+
+/*
+ * Return the amount of screen space that hasn't been allocated (such as
+ * by the shelf).
+ */
+    void
+gui_mch_get_screen_dimensions(int *screen_w, int *screen_h)
+{
+    PhRect_t console;
+
+    PhWindowQueryVisible( Ph_QUERY_WORKSPACE, 0,
+	    PhInputGroup( NULL ), &console );
+
+    *screen_w = console.lr.x - console.ul.x + 1;
+    *screen_h = console.lr.y - console.ul.y + 1;
+}
+
+    void
+gui_mch_iconify(void)
+{
+    PhWindowEvent_t event;
+
+    memset( &event, 0, sizeof (event) );
+    event.event_f = Ph_WM_HIDE;
+    event.event_state = Ph_WM_EVSTATE_HIDE;
+    event.rid = PtWidgetRid( gui.vimWindow );
+    PtForwardWindowEvent( &event );
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Bring the Vim window to the foreground.
+ */
+    void
+gui_mch_set_foreground()
+{
+    PhWindowEvent_t event;
+
+    memset( &event, 0, sizeof (event) );
+    event.event_f = Ph_WM_TOFRONT;
+    event.event_state = Ph_WM_EVSTATE_FFRONT;
+    event.rid = PtWidgetRid( gui.vimWindow );
+    PtForwardWindowEvent( &event );
+}
+#endif
+
+    void
+gui_mch_settitle(char_u *title,	char_u *icon)
+{
+#ifdef USE_PANEL_GROUP
+    gui_ph_pg_set_buffer_num( curwin->w_buffer->b_fnum );
+#endif
+    PtSetResource( gui.vimWindow, Pt_ARG_WINDOW_TITLE, title, 0 );
+    /* Not sure what to do with the icon text, set balloon text somehow? */
+}
+
+/****************************************************************************/
+/* Scrollbar */
+
+    void
+gui_mch_set_scrollbar_thumb(scrollbar_T *sb, int val, int size, int max)
+{
+    int	    n = 0;
+    PtArg_t args[3];
+
+    PtSetArg( &args[ n++ ], Pt_ARG_MAXIMUM, max, 0 );
+    PtSetArg( &args[ n++ ], Pt_ARG_SLIDER_SIZE, size, 0 );
+    PtSetArg( &args[ n++ ], Pt_ARG_GAUGE_VALUE, val, 0 );
+    PtSetResources( sb->id, n, args );
+}
+
+    void
+gui_mch_set_scrollbar_pos(scrollbar_T *sb, int x, int y, int w, int h)
+{
+    PhArea_t area = {{ x, y }, { w, h }};
+
+    PtSetResource( sb->id, Pt_ARG_AREA, &area, 0 );
+}
+
+    void
+gui_mch_create_scrollbar(scrollbar_T *sb, int orient)
+{
+    int	    n = 0;
+/*    int	    anchor_flags = 0;*/
+    PtArg_t args[4];
+
+    /*
+     * Stop the scrollbar from being realized when the parent
+     * is realized, so it can be explicitly realized by vim.
+     *
+     * Also, don't let the scrollbar get focus
+     */
+    PtSetArg( &args[ n++ ], Pt_ARG_FLAGS, Pt_DELAY_REALIZE,
+	    Pt_DELAY_REALIZE | Pt_GETS_FOCUS );
+    PtSetArg( &args[ n++ ], Pt_ARG_SCROLLBAR_FLAGS, Pt_SCROLLBAR_SHOW_ARROWS, 0);
+#if 0
+    /* Don't need this anchoring for the scrollbars */
+    if( orient == SBAR_HORIZ )
+    {
+	anchor_flags = Pt_BOTTOM_ANCHORED_BOTTOM |
+	    Pt_LEFT_ANCHORED_LEFT | Pt_RIGHT_ANCHORED_RIGHT;
+    }
+    else
+    {
+	anchor_flags = Pt_BOTTOM_ANCHORED_BOTTOM | Pt_TOP_ANCHORED_TOP;
+	if( sb->wp != NULL )
+	{
+	    if( sb == &sb->wp->w_scrollbars[ SBAR_LEFT ] )
+		anchor_flags |= Pt_LEFT_ANCHORED_LEFT;
+	    else
+		anchor_flags |= Pt_RIGHT_ANCHORED_RIGHT;
+	}
+    }
+    PtSetArg( &args[ n++ ], Pt_ARG_ANCHOR_FLAGS, anchor_flags, Pt_IS_ANCHORED );
+#endif
+    PtSetArg( &args[ n++ ], Pt_ARG_ORIENTATION,
+	    (orient == SBAR_HORIZ) ? Pt_HORIZONTAL : Pt_VERTICAL, 0 );
+#ifdef USE_PANEL_GROUP
+    sb->id = PtCreateWidget( PtScrollbar, gui.vimPanelGroup, n, args );
+#else
+    sb->id = PtCreateWidget( PtScrollbar, gui.vimContainer, n, args );
+#endif
+
+    PtAddCallback( sb->id, Pt_CB_SCROLLBAR_MOVE, gui_ph_handle_scrollbar, sb );
+}
+
+    void
+gui_mch_enable_scrollbar(scrollbar_T *sb, int flag)
+{
+    if( flag != 0 )
+	PtRealizeWidget( sb->id );
+    else
+	PtUnrealizeWidget( sb->id );
+}
+
+    void
+gui_mch_destroy_scrollbar(scrollbar_T *sb)
+{
+    PtDestroyWidget( sb->id );
+    sb->id = NULL;
+}
+
+/****************************************************************************/
+/* Mouse functions */
+
+#if defined(FEAT_MOUSESHAPE) || defined(PROTO)
+/* The last set mouse pointer shape is remembered, to be used when it goes
+ * from hidden to not hidden. */
+static int last_shape = 0;
+
+/* Table for shape IDs.  Keep in sync with the mshape_names[] table in
+ * misc2.c! */
+static int mshape_ids[] =
+{
+    Ph_CURSOR_POINTER,		/* arrow */
+    Ph_CURSOR_NONE,		/* blank */
+    Ph_CURSOR_INSERT,		/* beam */
+    Ph_CURSOR_DRAG_VERTICAL,	/* updown */
+    Ph_CURSOR_DRAG_VERTICAL,	/* udsizing */
+    Ph_CURSOR_DRAG_HORIZONTAL,	/* leftright */
+    Ph_CURSOR_DRAG_HORIZONTAL,	/* lrsizing */
+    Ph_CURSOR_WAIT,		/* busy */
+    Ph_CURSOR_DONT,		/* no */
+    Ph_CURSOR_CROSSHAIR,	/* crosshair */
+    Ph_CURSOR_FINGER,		/* hand1 */
+    Ph_CURSOR_FINGER,		/* hand2 */
+    Ph_CURSOR_FINGER,		/* pencil */
+    Ph_CURSOR_QUESTION_POINT,	/* question */
+    Ph_CURSOR_POINTER,		/* right-arrow */
+    Ph_CURSOR_POINTER,		/* up-arrow */
+    Ph_CURSOR_POINTER		/* last one */
+};
+
+    void
+mch_set_mouse_shape(shape)
+    int	shape;
+{
+    int	    id;
+
+    if (!gui.in_use)
+	return;
+
+    if (shape == MSHAPE_HIDE || gui.pointer_hidden)
+	PtSetResource( gui.vimTextArea, Pt_ARG_CURSOR_TYPE, Ph_CURSOR_NONE,
+		0 );
+    else
+    {
+	if (shape >= MSHAPE_NUMBERED)
+	    id = Ph_CURSOR_POINTER;
+	else
+	    id = mshape_ids[shape];
+
+	PtSetResource( gui.vimTextArea, Pt_ARG_CURSOR_TYPE, id,	0 );
+    }
+    if (shape != MSHAPE_HIDE)
+	last_shape = shape;
+}
+#endif
+
+    void
+gui_mch_mousehide(int hide)
+{
+    if( gui.pointer_hidden != hide )
+    {
+	gui.pointer_hidden = hide;
+#ifdef FEAT_MOUSESHAPE
+	if( hide )
+	    PtSetResource( gui.vimTextArea, Pt_ARG_CURSOR_TYPE,
+		    Ph_CURSOR_NONE, 0 );
+	else
+	    mch_set_mouse_shape( last_shape );
+#else
+	PtSetResource( gui.vimTextArea, Pt_ARG_CURSOR_TYPE,
+		( hide == MOUSE_SHOW ) ? GUI_PH_MOUSE_TYPE : Ph_CURSOR_NONE,
+		0 );
+#endif
+    }
+}
+
+    int
+gui_mch_get_mouse_x(void)
+{
+    PhCursorInfo_t info;
+    short x, y;
+
+    /* FIXME: does this return the correct position,
+     * with respect to the border? */
+    PhQueryCursor( PhInputGroup( NULL ), &info );
+    PtGetAbsPosition( gui.vimTextArea , &x, &y );
+
+    return( info.pos.x - x );
+}
+
+    int
+gui_mch_get_mouse_y(void)
+{
+    PhCursorInfo_t info;
+    short x, y;
+
+    PhQueryCursor( PhInputGroup( NULL ), &info );
+    PtGetAbsPosition( gui.vimTextArea , &x, &y );
+    /* TODO: Add border offset? */
+    return( info.pos.y - y );
+}
+
+    void
+gui_mch_setmouse(int x, int y)
+{
+    short abs_x, abs_y;
+
+    PtGetAbsPosition( gui.vimTextArea, &abs_x, &abs_y );
+    /* Add the border offset? */
+    PhMoveCursorAbs( PhInputGroup( NULL ), abs_x + x, abs_y + y );
+}
+
+/****************************************************************************/
+/* Colours */
+
+/*
+ * Return the RGB value of a pixel as a long.
+ */
+    long_u
+gui_mch_get_rgb(guicolor_T pixel)
+{
+    return PgRGB(PgRedValue(pixel), PgGreenValue(pixel), PgBlueValue(pixel));
+}
+
+    void
+gui_mch_new_colors(void)
+{
+#if 0 /* Don't bother changing the cursor colour */
+    short color_diff;
+
+    /*
+     * If there isn't enough difference between the background colour and
+     * the mouse pointer colour then change the mouse pointer colour
+     */
+    color_diff = gui_get_lightness(gui_ph_mouse_color)
+					  - gui_get_lightness(gui.back_pixel);
+
+    if( abs( color_diff ) < 64 )
+    {
+	short r, g, b;
+	/* not a great algorithm... */
+	r = PgRedValue( gui_ph_mouse_color ) ^ 255;
+	g = PgGreenValue( gui_ph_mouse_color ) ^ 255;
+	b = PgBlueValue( gui_ph_mouse_color ) ^ 255;
+
+#ifndef FEAT_MOUSESHAPE
+	gui_ph_mouse_color = PgRGB( r, g, b );
+	PtSetResource( gui.vimTextArea, Pt_ARG_CURSOR_COLOR,
+		gui_ph_mouse_color, 0 );
+#endif
+    }
+#endif
+
+    PtSetResource( gui.vimTextArea, Pt_ARG_FILL_COLOR, gui.back_pixel, 0 );
+}
+
+    static int
+hex_digit(int c)
+{
+    if (VIM_ISDIGIT(c))
+	return( c - '0' );
+    c = TOLOWER_ASC(c);
+    if (c >= 'a' && c <= 'f')
+	return( c - 'a' + 10 );
+    return( -1000 );
+}
+
+
+/*
+ * This should be split out into a seperate file,
+ * every port does basically the same thing.
+ *
+ * This is the gui_w32.c version (i think..)
+ * Return INVALCOLOR when failed.
+ */
+
+    guicolor_T
+gui_mch_get_color(char_u *name)
+{
+    int i;
+    int r, g, b;
+
+
+    typedef struct GuiColourTable
+    {
+	char	    *name;
+	guicolor_T     colour;
+    } GuiColourTable;
+
+    static GuiColourTable table[] =
+    {
+	{"Black",	    RGB(0x00, 0x00, 0x00)},
+	{"DarkGray",	    RGB(0x80, 0x80, 0x80)},
+	{"DarkGrey",	    RGB(0x80, 0x80, 0x80)},
+	{"Gray",	    RGB(0xC0, 0xC0, 0xC0)},
+	{"Grey",	    RGB(0xC0, 0xC0, 0xC0)},
+	{"LightGray",	    RGB(0xD3, 0xD3, 0xD3)},
+	{"LightGrey",	    RGB(0xD3, 0xD3, 0xD3)},
+	{"White",	    RGB(0xFF, 0xFF, 0xFF)},
+	{"DarkRed",	    RGB(0x80, 0x00, 0x00)},
+	{"Red",		    RGB(0xFF, 0x00, 0x00)},
+	{"LightRed",	    RGB(0xFF, 0xA0, 0xA0)},
+	{"DarkBlue",	    RGB(0x00, 0x00, 0x80)},
+	{"Blue",	    RGB(0x00, 0x00, 0xFF)},
+	{"LightBlue",	    RGB(0xA0, 0xA0, 0xFF)},
+	{"DarkGreen",	    RGB(0x00, 0x80, 0x00)},
+	{"Green",	    RGB(0x00, 0xFF, 0x00)},
+	{"LightGreen",	    RGB(0xA0, 0xFF, 0xA0)},
+	{"DarkCyan",	    RGB(0x00, 0x80, 0x80)},
+	{"Cyan",	    RGB(0x00, 0xFF, 0xFF)},
+	{"LightCyan",	    RGB(0xA0, 0xFF, 0xFF)},
+	{"DarkMagenta",	    RGB(0x80, 0x00, 0x80)},
+	{"Magenta",	    RGB(0xFF, 0x00, 0xFF)},
+	{"LightMagenta",    RGB(0xFF, 0xA0, 0xFF)},
+	{"Brown",	    RGB(0x80, 0x40, 0x40)},
+	{"Yellow",	    RGB(0xFF, 0xFF, 0x00)},
+	{"LightYellow",	    RGB(0xFF, 0xFF, 0xA0)},
+	{"SeaGreen",	    RGB(0x2E, 0x8B, 0x57)},
+	{"Orange",	    RGB(0xFF, 0xA5, 0x00)},
+	{"Purple",	    RGB(0xA0, 0x20, 0xF0)},
+	{"SlateBlue",	    RGB(0x6A, 0x5A, 0xCD)},
+	{"Violet",	    RGB(0xEE, 0x82, 0xEE)},
+    };
+
+    /* is name #rrggbb format? */
+    if( name[0] == '#' && STRLEN( name ) == 7 )
+    {
+	r = hex_digit( name[1] ) * 16 + hex_digit( name[2] );
+	g = hex_digit( name[3] ) * 16 + hex_digit( name[4] );
+	b = hex_digit( name[5] ) * 16 + hex_digit( name[6] );
+	if( r < 0 || g < 0 || b < 0 )
+	    return INVALCOLOR;
+	return( RGB( r, g, b ) );
+    }
+
+    for( i = 0; i < ARRAY_LENGTH( table ); i++ )
+    {
+	if( STRICMP( name, table[i].name ) == 0 )
+	    return( table[i].colour );
+    }
+
+    /*
+     * Last attempt. Look in the file "$VIMRUNTIME/rgb.txt".
+     */
+    {
+#define LINE_LEN 100
+	FILE	*fd;
+	char	line[LINE_LEN];
+	char_u	*fname;
+
+	fname = expand_env_save((char_u *)"$VIMRUNTIME/rgb.txt");
+	if (fname == NULL)
+	    return INVALCOLOR;
+
+	fd = fopen((char *)fname, "rt");
+	vim_free(fname);
+	if (fd == NULL)
+	    return INVALCOLOR;
+
+	while (!feof(fd))
+	{
+	    int	    len;
+	    int	    pos;
+	    char    *color;
+
+	    fgets(line, LINE_LEN, fd);
+	    len = STRLEN(line);
+
+	    if (len <= 1 || line[len-1] != '\n')
+		continue;
+
+	    line[len-1] = '\0';
+
+	    i = sscanf(line, "%d %d %d %n", &r, &g, &b, &pos);
+	    if (i != 3)
+		continue;
+
+	    color = line + pos;
+
+	    if (STRICMP(color, name) == 0)
+	    {
+		fclose(fd);
+		return( (guicolor_T) RGB(r,g,b) );
+	    }
+	}
+
+	fclose(fd);
+    }
+
+
+    return INVALCOLOR;
+}
+
+    void
+gui_mch_set_fg_color(guicolor_T color)
+{
+    PgSetTextColor( color );
+}
+
+    void
+gui_mch_set_bg_color(guicolor_T color)
+{
+    PgSetFillColor( color );
+}
+
+    void
+gui_mch_invert_rectangle(int row, int col, int nr, int nc)
+{
+    PhRect_t rect;
+
+    rect.ul.x = FILL_X( col );
+    rect.ul.y = FILL_Y( row );
+
+    /* FIXME: This has an off by one pixel problem */
+    rect.lr.x = rect.ul.x + nc * gui.char_width;
+    rect.lr.y = rect.ul.y + nr * gui.char_height;
+    if( nc > 0 )
+	rect.lr.x -= 1;
+    if( nr > 0 )
+	rect.lr.y -= 1;
+
+    DRAW_START;
+    PgSetDrawMode( Pg_DrawModeDSTINVERT );
+    PgDrawRect( &rect, Pg_DRAW_FILL );
+    PgSetDrawMode( Pg_DrawModeSRCCOPY );
+    DRAW_END;
+}
+
+    void
+gui_mch_clear_block(int row1, int col1, int row2, int col2)
+{
+    PhRect_t block = {
+	{ FILL_X( col1 ), FILL_Y( row1 ) },
+	{ FILL_X( col2 + 1 ) - 1, FILL_Y( row2 + 1 ) - 1}
+    };
+
+    DRAW_START;
+    gui_mch_set_bg_color( gui.back_pixel );
+    PgDrawRect( &block, Pg_DRAW_FILL );
+    DRAW_END;
+}
+
+    void
+gui_mch_clear_all()
+{
+    PhRect_t text_rect = {
+	{ gui.border_width, gui.border_width },
+	{ Columns * gui.char_width + gui.border_width - 1 ,
+	    Rows * gui.char_height + gui.border_width - 1 }
+    };
+
+    if( is_ignore_draw == TRUE )
+	return;
+
+    DRAW_START;
+    gui_mch_set_bg_color( gui.back_pixel );
+    PgDrawRect( &text_rect, Pg_DRAW_FILL );
+    DRAW_END;
+}
+
+    void
+gui_mch_delete_lines(int row, int num_lines)
+{
+    PhRect_t    rect;
+    PhPoint_t   delta;
+
+    rect.ul.x = FILL_X( gui.scroll_region_left );
+    rect.ul.y = FILL_Y( row + num_lines );
+
+    rect.lr.x = FILL_X( gui.scroll_region_right + 1 ) - 1;
+    rect.lr.y = FILL_Y( gui.scroll_region_bot + 1) - 1;
+
+    PtWidgetOffset( gui.vimTextArea, &gui_ph_raw_offset );
+    PhTranslatePoint( &gui_ph_raw_offset, PtWidgetPos(gui.vimTextArea, NULL));
+    PhTranslateRect( &rect, &gui_ph_raw_offset );
+
+    delta.x = 0;
+    delta.y = -num_lines * gui.char_height;
+
+    PgFlush();
+
+    PhBlit( PtWidgetRid( PtFindDisjoint( gui.vimTextArea ) ), &rect, &delta );
+
+    gui_clear_block(
+	gui.scroll_region_bot - num_lines + 1,
+	gui.scroll_region_left,
+	gui.scroll_region_bot,
+	gui.scroll_region_right );
+}
+
+    void
+gui_mch_insert_lines(int row, int num_lines)
+{
+    PhRect_t    rect;
+    PhPoint_t   delta;
+
+    rect.ul.x = FILL_X( gui.scroll_region_left );
+    rect.ul.y = FILL_Y( row );
+
+    rect.lr.x = FILL_X( gui.scroll_region_right + 1 ) - 1;
+    rect.lr.y = FILL_Y( gui.scroll_region_bot - num_lines + 1 ) - 1;
+
+    PtWidgetOffset( gui.vimTextArea, &gui_ph_raw_offset );
+    PhTranslatePoint( &gui_ph_raw_offset, PtWidgetPos( gui.vimTextArea, NULL ) );
+    PhTranslateRect( &rect, &gui_ph_raw_offset );
+
+    delta.x = 0;
+    delta.y = num_lines * gui.char_height;
+
+    PgFlush();
+
+    PhBlit( PtWidgetRid( PtFindDisjoint( gui.vimTextArea ) ) , &rect, &delta );
+
+    gui_clear_block( row, gui.scroll_region_left,
+	    row + num_lines - 1, gui.scroll_region_right );
+}
+
+    void
+gui_mch_draw_string(int row, int col, char_u *s, int len, int flags)
+{
+    static char *utf8_buffer = NULL;
+    static int	utf8_len = 0;
+
+    PhPoint_t	pos = { TEXT_X( col ), TEXT_Y( row ) };
+    PhRect_t	rect;
+
+    if( is_ignore_draw == TRUE )
+	return;
+
+    DRAW_START;
+
+    if( !( flags & DRAW_TRANSP ) )
+    {
+	PgDrawIRect(
+		FILL_X( col ), FILL_Y( row ),
+		FILL_X( col + len ) - 1, FILL_Y( row + 1 ) - 1,
+		Pg_DRAW_FILL );
+    }
+
+    if( flags & DRAW_UNDERL )
+	PgSetUnderline( gui.norm_pixel, Pg_TRANSPARENT, 0 );
+
+    if( charset_translate != NULL
+#ifdef FEAT_MBYTE
+	    && enc_utf8 == 0
+#endif
+	    )
+    {
+	int src_taken, dst_made;
+
+	/* Use a static buffer to avoid large amounts of de/allocations */
+	if( utf8_len < len )
+	{
+	    utf8_buffer = realloc( utf8_buffer, len * MB_LEN_MAX );
+	    utf8_len = len;
+	}
+
+	PxTranslateToUTF(
+		charset_translate,
+		s,
+		len,
+		&src_taken,
+		utf8_buffer,
+		utf8_len,
+		&dst_made );
+	s = utf8_buffer;
+	len = dst_made;
+    }
+
+    PgDrawText( s, len, &pos, 0 );
+
+    if( flags & DRAW_BOLD )
+    {
+	/* FIXME: try and only calculate these values once... */
+	rect.ul.x = FILL_X( col ) + 1;
+	rect.ul.y = FILL_Y( row );
+	rect.lr.x = FILL_X( col + len ) - 1;
+	rect.lr.y = FILL_Y( row + 1) - 1;
+	/* PgSetUserClip( NULL ) causes the scrollbar to not redraw... */
+#if 0
+	pos.x++;
+
+	PgSetUserClip( &rect );
+	PgDrawText( s, len, &pos, 0 );
+	PgSetUserClip( NULL );
+#else
+	rect.lr.y -= ( p_linespace + 1 ) / 2;
+	/* XXX: DrawTextArea doesn't work with phditto */
+	PgDrawTextArea( s, len, &rect, Pg_TEXT_BOTTOM );
+#endif
+    }
+
+    if( flags & DRAW_UNDERL )
+	PgSetUnderline( Pg_TRANSPARENT, Pg_TRANSPARENT, 0 );
+
+    DRAW_END;
+}
+
+/****************************************************************************/
+/* Cursor */
+
+    void
+gui_mch_draw_hollow_cursor(guicolor_T color)
+{
+    PhRect_t r;
+
+    /* FIXME: Double width characters */
+
+    r.ul.x = FILL_X( gui.col );
+    r.ul.y = FILL_Y( gui.row );
+    r.lr.x = r.ul.x + gui.char_width - 1;
+    r.lr.y = r.ul.y + gui.char_height - 1;
+
+    DRAW_START;
+    PgSetStrokeColor( color );
+    PgDrawRect( &r, Pg_DRAW_STROKE );
+    DRAW_END;
+}
+
+    void
+gui_mch_draw_part_cursor(int w, int h, guicolor_T color)
+{
+    PhRect_t r;
+
+    r.ul.x = FILL_X( gui.col );
+    r.ul.y = FILL_Y( gui.row ) + gui.char_height - h;
+    r.lr.x = r.ul.x + w - 1;
+    r.lr.y = r.ul.y + h - 1;
+
+    DRAW_START;
+    gui_mch_set_bg_color( color );
+    PgDrawRect( &r, Pg_DRAW_FILL );
+    DRAW_END;
+}
+
+    void
+gui_mch_set_blinking(long wait, long on, long off)
+{
+    blink_waittime = wait;
+    blink_ontime = on;
+    blink_offtime = off;
+}
+
+    void
+gui_mch_start_blink(void)
+{
+    /* Only turn on the timer on if none of the times are zero */
+    if( blink_waittime && blink_ontime && blink_offtime && gui.in_focus)
+    {
+	PtSetResource( gui_ph_timer_cursor, Pt_ARG_TIMER_INITIAL,
+		blink_waittime, 0 );
+	blink_state = BLINK_ON;
+	gui_update_cursor(TRUE, FALSE);
+    }
+}
+
+    void
+gui_mch_stop_blink(void)
+{
+    PtSetResource( gui_ph_timer_cursor, Pt_ARG_TIMER_INITIAL, 0, 0 );
+
+    if( blink_state == BLINK_OFF )
+	gui_update_cursor(TRUE, FALSE);
+
+    blink_state = BLINK_NONE;
+}
+
+/****************************************************************************/
+/* miscellaneous functions */
+
+    void
+gui_mch_beep(void)
+{
+    PtBeep();
+}
+
+    void
+gui_mch_flash(int msec)
+{
+    PgSetFillXORColor( Pg_BLACK, Pg_WHITE );
+    PgSetDrawMode( Pg_DRAWMODE_XOR );
+    gui_mch_clear_all();
+    gui_mch_flush();
+
+    ui_delay( (long) msec, TRUE );
+
+    gui_mch_clear_all();
+    PgSetDrawMode( Pg_DRAWMODE_OPAQUE );
+    gui_mch_flush();
+}
+
+    void
+gui_mch_flush(void)
+{
+    PgFlush();
+}
+
+    void
+gui_mch_set_text_area_pos(int x, int y, int w, int h)
+{
+    PhArea_t area = {{x, y}, {w, h}};
+
+    PtSetResource( gui.vimTextArea, Pt_ARG_AREA, &area, 0 );
+}
+
+    int
+gui_mch_haskey(char_u *name)
+{
+    int i;
+
+    for (i = 0; special_keys[i].key_sym != 0; i++)
+	if (name[0] == special_keys[i].vim_code0 &&
+		 name[1] == special_keys[i].vim_code1)
+	    return( OK );
+    return( FAIL );
+}
+
+/****************************************************************************/
+/* Menu */
+
+#ifdef FEAT_TOOLBAR
+#include "toolbar.phi"
+
+static PhImage_t *gui_ph_toolbar_images[] = {
+    &tb_new_phi,
+    &tb_open_phi,
+    &tb_save_phi,
+    &tb_undo_phi,
+    &tb_redo_phi,
+    &tb_cut_phi,
+    &tb_copy_phi,
+    &tb_paste_phi,
+    &tb_print_phi,
+    &tb_help_phi,
+    &tb_find_phi,
+    &tb_save_all_phi,
+    &tb_save_session_phi,
+    &tb_new_session_phi,
+    &tb_load_session_phi,
+    &tb_macro_phi,
+    &tb_replace_phi,
+    &tb_close_phi,
+    &tb_maximize_phi,
+    &tb_minimize_phi,
+    &tb_split_phi,
+    &tb_shell_phi,
+    &tb_find_prev_phi,
+    &tb_find_next_phi,
+    &tb_find_help_phi,
+    &tb_make_phi,
+    &tb_jump_phi,
+    &tb_ctags_phi,
+    &tb_vsplit_phi,
+    &tb_maxwidth_phi,
+    &tb_minwidth_phi
+};
+
+static PhImage_t *
+gui_ph_toolbar_load_icon( char_u *iconfile )
+{
+    static PhImage_t external_icon;
+    PhImage_t *temp_phi = NULL;
+
+    temp_phi = PxLoadImage( iconfile, NULL );
+    if( temp_phi != NULL )
+    {
+	/* The label widget will free the image/palette/etc. for us when
+	 * it's destroyed */
+	temp_phi->flags |= Ph_RELEASE_IMAGE_ALL;
+	memcpy( &external_icon, temp_phi, sizeof( external_icon ) );
+	free( temp_phi );
+
+	temp_phi = &external_icon;
+    }
+    return( temp_phi );
+}
+
+/*
+ * This returns either a builtin icon image, an external image or NULL
+ * if it can't find either.  The caller can't and doesn't need to try and
+ * free() the returned image, and it can't store the image pointer.
+ * (When setting the Pt_ARG_LABEL_IMAGE resource, the contents of the
+ * PhImage_t are copied, and the original PhImage_t aren't needed anymore).
+ */
+static PhImage_t *
+gui_ph_toolbar_find_icon( vimmenu_T *menu )
+{
+    char_u full_pathname[ MAXPATHL + 1 ];
+    PhImage_t *icon = NULL;
+
+    if( menu->icon_builtin == FALSE )
+    {
+	if( menu->iconfile != NULL )
+	    /* TODO: use gui_find_iconfile() */
+	    icon = gui_ph_toolbar_load_icon( menu->iconfile );
+
+	/* TODO: Restrict loading to just .png? Search for any format? */
+	if( ( icon == NULL ) &&
+	    ( ( gui_find_bitmap( menu->name, full_pathname, "gif" ) == OK ) ||
+	      ( gui_find_bitmap( menu->name, full_pathname, "png" ) == OK ) ) )
+	    icon = gui_ph_toolbar_load_icon( full_pathname );
+
+	if( icon != NULL )
+	    return( icon );
+    }
+
+    if( menu->iconidx >= 0 &&
+	    ( menu->iconidx < ARRAY_LENGTH( gui_ph_toolbar_images ) ) )
+    {
+	return( gui_ph_toolbar_images[ menu->iconidx ] );
+    }
+
+    return( NULL );
+}
+#endif
+
+#if defined( FEAT_MENU ) || defined( PROTO )
+    void
+gui_mch_enable_menu(int flag)
+{
+    if( flag != 0 )
+	PtRealizeWidget( gui.vimMenuBar );
+    else
+	PtUnrealizeWidget( gui.vimMenuBar );
+}
+
+    void
+gui_mch_set_menu_pos(int x, int y, int w, int h)
+{
+    /* Nothing */
+}
+
+/* Change the position of a menu button in the parent */
+    static void
+gui_ph_position_menu( PtWidget_t *widget, int priority )
+{
+    PtWidget_t	*traverse;
+    vimmenu_T	*menu;
+
+    traverse = PtWidgetChildBack( PtWidgetParent( widget ) );
+
+    /* Iterate through the list of widgets in traverse, until
+     * we find the position we want to insert our widget into */
+    /* TODO: traverse from front to back, possible speedup? */
+    while( traverse != NULL )
+    {
+	PtGetResource( traverse, Pt_ARG_POINTER, &menu, 0 );
+
+	if( menu != NULL &&
+		priority < menu->priority &&
+		widget != traverse )
+	{
+	    /* Insert the widget before the current traverse widget */
+	    PtWidgetInsert( widget, traverse, 1 );
+	    return;
+	}
+
+	traverse = PtWidgetBrotherInFront( traverse );
+    }
+}
+
+/* the index is ignored because it's not useful for our purposes */
+    void
+gui_mch_add_menu(vimmenu_T *menu, int index)
+{
+    vimmenu_T	*parent = menu->parent;
+    char_u	*accel_key;
+    char_u	mnemonic_str[MB_LEN_MAX];
+    int	    n;
+    PtArg_t args[5];
+
+    menu->submenu_id = menu->id = NULL;
+
+    if( menu_is_menubar( menu->name ) )
+    {
+
+	accel_key = vim_strchr( menu->name, '&' );
+	if( accel_key != NULL )
+	{
+	    mnemonic_str[0] = accel_key[1];
+	    mnemonic_str[1] = NUL;
+	}
+
+	/* Create the menu button */
+	n = 0;
+	PtSetArg( &args[ n++ ], Pt_ARG_TEXT_STRING, menu->dname, 0 );
+	PtSetArg( &args[ n++ ], Pt_ARG_ACCEL_TEXT, menu->actext, 0 );
+	if( accel_key != NULL )
+	    PtSetArg( &args[ n++ ], Pt_ARG_ACCEL_KEY, mnemonic_str, 0 );
+	PtSetArg( &args[ n++ ], Pt_ARG_POINTER, menu, 0 );
+
+	if( parent != NULL )
+	    PtSetArg( &args[ n++ ], Pt_ARG_BUTTON_TYPE, Pt_MENU_RIGHT, 0 );
+
+	menu->id = PtCreateWidget( PtMenuButton,
+		(parent == NULL) ? gui.vimMenuBar : parent->submenu_id,
+		n, args );
+
+	PtAddCallback( menu->id, Pt_CB_ARM, gui_ph_handle_pulldown_menu, menu );
+
+	/* Create the actual menu */
+	n = 0;
+	if( parent != NULL )
+	    PtSetArg( &args[ n++ ], Pt_ARG_MENU_FLAGS, Pt_TRUE, Pt_MENU_CHILD );
+
+	menu->submenu_id = PtCreateWidget( PtMenu, menu->id, n, args );
+
+	if( parent == NULL )
+	{
+	    PtAddCallback( menu->submenu_id, Pt_CB_UNREALIZED,
+		    gui_ph_handle_menu_unrealized, menu );
+
+	    if( menu->mnemonic != 0 )
+	    {
+		PtAddHotkeyHandler( gui.vimWindow, tolower( menu->mnemonic ),
+			Pk_KM_Alt, 0, menu, gui_ph_handle_pulldown_menu );
+	    }
+	}
+
+	gui_ph_position_menu( menu->id, menu->priority );
+
+	/* Redraw menubar here instead of gui_mch_draw_menubar */
+	if( gui.menu_is_active )
+	    PtRealizeWidget( menu->id );
+    }
+    else if( menu_is_popup( menu->name ) )
+    {
+	menu->submenu_id = PtCreateWidget( PtMenu, gui.vimWindow, 0, NULL );
+	PtAddCallback( menu->submenu_id, Pt_CB_UNREALIZED,
+		gui_ph_handle_menu_unrealized, menu );
+    }
+}
+
+    void
+gui_mch_add_menu_item(vimmenu_T *menu, int index)
+{
+    vimmenu_T	*parent = menu->parent;
+    char_u	*accel_key;
+    char_u	mnemonic_str[MB_LEN_MAX];
+    int	    n;
+    PtArg_t args[13];
+
+    n = 0;
+    PtSetArg( &args[ n++ ], Pt_ARG_POINTER, menu, 0 );
+
+#ifdef FEAT_TOOLBAR
+    if( menu_is_toolbar( parent->name ) )
+    {
+	if( menu_is_separator( menu->name ) )
+	{
+	    PtSetArg( &args[ n++ ], Pt_ARG_SEP_FLAGS,
+		    Pt_SEP_VERTICAL, Pt_SEP_ORIENTATION );
+	    PtSetArg( &args[ n++ ], Pt_ARG_SEP_TYPE, Pt_ETCHED_IN, 0 );
+	    PtSetArg( &args[ n++ ], Pt_ARG_ANCHOR_FLAGS,
+		    Pt_TRUE, Pt_ANCHOR_TOP_BOTTOM );
+	    PtSetArg( &args[ n++ ], Pt_ARG_WIDTH, 2, 0 );
+	    menu->id = PtCreateWidget( PtSeparator, gui.vimToolBar, n, args );
+	}
+	else
+	{
+	    if( strstr( (const char *) p_toolbar, "text" ) != NULL )
+	    {
+		PtSetArg( &args[ n++ ], Pt_ARG_BALLOON_POSITION,
+			Pt_BALLOON_BOTTOM, 0 );
+		PtSetArg( &args[ n++ ], Pt_ARG_TEXT_STRING, menu->dname, 0 );
+		PtSetArg( &args[ n++ ], Pt_ARG_TEXT_FONT, "TextFont08", 0 );
+	    }
+	    if( ( strstr( (const char *) p_toolbar, "icons" ) != NULL ) &&
+		    ( gui_ph_toolbar_images != NULL ) )
+	    {
+		PtSetArg( &args[ n++ ], Pt_ARG_LABEL_IMAGE,
+			gui_ph_toolbar_find_icon( menu ), 0 );
+		PtSetArg( &args[ n++ ], Pt_ARG_LABEL_TYPE, Pt_TEXT_IMAGE, 0 );
+		PtSetArg( &args[ n++ ], Pt_ARG_TEXT_IMAGE_SPACING, 0, 0 );
+	    }
+	    if( strstr( (const char *) p_toolbar, "tooltips" ) != NULL )
+	    {
+		PtSetArg( &args[ n++ ], Pt_ARG_LABEL_BALLOON,
+			gui_ph_show_tooltip, 0 );
+		PtSetArg( &args[ n++ ], Pt_ARG_LABEL_FLAGS,
+			Pt_TRUE, Pt_SHOW_BALLOON );
+	    }
+	    PtSetArg( &args[ n++ ], Pt_ARG_MARGIN_HEIGHT, 1, 0 );
+	    PtSetArg( &args[ n++ ], Pt_ARG_MARGIN_WIDTH, 1, 0 );
+	    PtSetArg( &args[ n++ ], Pt_ARG_FLAGS, Pt_FALSE,
+		    Pt_HIGHLIGHTED | Pt_GETS_FOCUS );
+	    PtSetArg( &args[ n++ ], Pt_ARG_FILL_COLOR, Pg_TRANSPARENT, 0 );
+	    menu->id = PtCreateWidget( PtButton, gui.vimToolBar, n, args );
+
+	    PtAddCallback( menu->id, Pt_CB_ACTIVATE, gui_ph_handle_menu, menu );
+	}
+	/* Update toolbar if it's open */
+	if( PtWidgetIsRealized( gui.vimToolBar ) )
+	    PtRealizeWidget( menu->id );
+    }
+    else
+#endif
+	if( menu_is_separator( menu->name ) )
+    {
+	menu->id = PtCreateWidget( PtSeparator, parent->submenu_id, n, args );
+    }
+    else
+    {
+	accel_key = vim_strchr( menu->name, '&' );
+	if( accel_key != NULL )
+	{
+	    mnemonic_str[0] = accel_key[1];
+	    mnemonic_str[1] = NUL;
+	}
+
+	PtSetArg( &args[ n++ ], Pt_ARG_TEXT_STRING, menu->dname, 0 );
+	if( accel_key != NULL )
+	    PtSetArg( &args[ n++ ], Pt_ARG_ACCEL_KEY, mnemonic_str,
+		    0 );
+
+	PtSetArg( &args[ n++ ], Pt_ARG_ACCEL_TEXT, menu->actext, 0 );
+
+	menu->id = PtCreateWidget( PtMenuButton, parent->submenu_id, n, args );
+
+	PtAddCallback( menu->id, Pt_CB_ACTIVATE, gui_ph_handle_menu, menu );
+
+#ifdef USE_PANEL_GROUP
+	if( gui_ph_is_buffer_item( menu, parent ) == TRUE )
+	{
+	    PtAddCallback( menu->id, Pt_CB_DESTROYED,
+		    gui_ph_handle_buffer_remove, menu );
+	    gui_ph_pg_add_buffer( menu->dname );
+	}
+#endif
+    }
+
+    gui_ph_position_menu( menu->id, menu->priority );
+}
+
+    void
+gui_mch_destroy_menu(vimmenu_T *menu)
+{
+    if( menu->submenu_id != NULL )
+	PtDestroyWidget( menu->submenu_id );
+    if( menu->id != NULL )
+	PtDestroyWidget( menu->id );
+
+    menu->submenu_id = NULL;
+    menu->id = NULL;
+}
+
+    void
+gui_mch_menu_grey(vimmenu_T *menu, int grey)
+{
+    long    flags, mask, fields;
+
+    if( menu->id == NULL )
+	return;
+
+    flags = PtWidgetFlags( menu->id );
+    if( PtWidgetIsClass( menu->id, PtMenuButton ) &&
+	    PtWidgetIsClass( PtWidgetParent( menu->id ), PtMenu ) )
+    {
+	fields = Pt_FALSE;
+	mask = Pt_SELECTABLE | Pt_HIGHLIGHTED;
+    }
+    else
+    {
+	fields = Pt_TRUE;
+	mask = Pt_BLOCKED | Pt_GHOST;
+    }
+
+    if( ! grey )
+	fields = ~fields;
+
+    PtSetResource( menu->id, Pt_ARG_FLAGS, fields,
+	    mask );
+}
+
+    void
+gui_mch_menu_hidden(vimmenu_T *menu, int hidden)
+{
+    /* TODO: [un]realize the widget? */
+}
+
+    void
+gui_mch_draw_menubar(void)
+{
+    /* The only time a redraw is needed is when a menu button
+     * is added to the menubar, and that is detected and the bar
+     * redrawn in gui_mch_add_menu_item
+     */
+}
+
+    void
+gui_mch_show_popupmenu(vimmenu_T *menu)
+{
+    PtSetResource( menu->submenu_id, Pt_ARG_POS, &abs_mouse, 0 );
+    PtRealizeWidget( menu->submenu_id );
+}
+
+    void
+gui_mch_toggle_tearoffs(int enable)
+{
+    /* No tearoffs yet */
+}
+
+#endif
+
+#if defined( FEAT_TOOLBAR ) || defined( PROTO )
+    void
+gui_mch_show_toolbar(int showit)
+{
+    if( showit )
+	PtRealizeWidget( gui.vimToolBar );
+    else
+	PtUnrealizeWidget( gui.vimToolBar );
+}
+#endif
+
+/****************************************************************************/
+/* Fonts */
+
+    static GuiFont
+gui_ph_get_font(
+	char_u	*font_name,
+	int_u	font_flags,
+	int_u	font_size,
+	/* Check whether the resulting font has the font flags and size that
+	 * was asked for */
+	int_u	enforce
+	)
+{
+    char_u	    *font_tag;
+    FontQueryInfo   info;
+    int_u	    style;
+
+    font_tag = alloc( MAX_FONT_TAG );
+    if( font_tag != NULL )
+    {
+	if( PfGenerateFontName( font_name, font_flags, font_size,
+		    font_tag ) != NULL )
+	{
+	    /* Enforce some limits on the font used */
+	    style = PHFONT_INFO_FIXED;
+
+	    if( enforce & PF_STYLE_BOLD )
+		style |= PHFONT_INFO_BOLD;
+	    if( enforce & PF_STYLE_ANTIALIAS )
+		style |= PHFONT_INFO_ALIAS;
+	    if( enforce & PF_STYLE_ITALIC )
+		style |= PHFONT_INFO_ITALIC;
+
+	    PfQueryFontInfo( font_tag, &info );
+
+	    if( info.size == 0 )
+		font_size = 0;
+
+	    /* Make sure font size matches, and that the font style
+	     * at least has the bits we're checking for */
+	    if( font_size == info.size &&
+		    style == (info.style & style) )
+		return( (GuiFont) font_tag );
+	}
+	vim_free( font_tag );
+    }
+    return( NULL );
+}
+
+/*
+ * Split up the vim font name
+ *
+ * vim_font is in the form of
+ * <name>:s<height>:a:b:i
+ *
+ * a = antialias
+ * b = bold
+ * i = italic
+ *
+ */
+
+    static int
+gui_ph_parse_font_name(
+	char_u *vim_font,
+	char_u **font_name,
+	int_u *font_flags,
+	int_u *font_size )
+{
+    char_u  *mark;
+    int_u   name_len, size;
+
+    mark = vim_strchr( vim_font, ':' );
+    if( mark == NULL )
+	name_len = STRLEN( vim_font );
+    else
+	name_len = (int_u) ( mark - vim_font );
+
+    *font_name = vim_strnsave( vim_font, name_len );
+    if( *font_name != NULL )
+    {
+	if( mark != NULL )
+	{
+	    while( *mark != NUL && *mark++ == ':')
+	    {
+		switch( tolower( *mark++ ) )
+		{
+		    case 'a': *font_flags |= PF_STYLE_ANTIALIAS; break;
+		    case 'b': *font_flags |= PF_STYLE_BOLD; break;
+		    case 'i': *font_flags |= PF_STYLE_ITALIC; break;
+
+		    case 's':
+			size = getdigits( &mark );
+			/* Restrict the size to some vague limits */
+			if( size < 1 || size > 100 )
+			    size = 8;
+
+			*font_size = size;
+			break;
+
+		    default:
+			break;
+		}
+	    }
+	}
+	return( TRUE );
+    }
+    return( FALSE );
+}
+
+    int
+gui_mch_init_font(char_u *vim_font_name, int fontset)
+{
+    char_u  *font_tag;
+    char_u  *font_name = NULL;
+    int_u   font_flags = 0;
+    int_u   font_size  = 12;
+
+    FontQueryInfo info;
+    PhRect_t extent;
+
+    if( vim_font_name == NULL )
+    {
+	/* Default font */
+	vim_font_name = "PC Term";
+    }
+
+    if( STRCMP( vim_font_name, "*" ) == 0 )
+    {
+	font_tag = PtFontSelection( gui.vimWindow, NULL, NULL,
+		"pcterm12", -1, PHFONT_FIXED, NULL );
+
+	if( font_tag == NULL )
+	    return( FAIL );
+
+	gui_mch_free_font( gui.norm_font );
+	gui.norm_font = font_tag;
+
+	PfQueryFontInfo( font_tag, &info );
+	font_name = vim_strsave( info.font );
+    }
+    else
+    {
+	if( gui_ph_parse_font_name( vim_font_name, &font_name, &font_flags,
+		    &font_size ) == FALSE )
+	    return( FAIL );
+
+	font_tag = gui_ph_get_font( font_name, font_flags, font_size, 0 );
+	if( font_tag == NULL )
+	{
+	    vim_free( font_name );
+	    return( FAIL );
+	}
+	gui_mch_free_font( gui.norm_font );
+	gui.norm_font = font_tag;
+    }
+
+    gui_mch_free_font( gui.bold_font );
+    gui.bold_font = gui_ph_get_font( font_name, font_flags | PF_STYLE_BOLD,
+	    font_size, PF_STYLE_BOLD );
+
+    gui_mch_free_font( gui.ital_font );
+    gui.ital_font = gui_ph_get_font( font_name, font_flags | PF_STYLE_ITALIC,
+	    font_size, PF_STYLE_ITALIC );
+
+    /* This extent was brought to you by the letter 'g' */
+    PfExtentText( &extent, NULL, font_tag, "g", 1 );
+
+    gui.char_width = extent.lr.x - extent.ul.x + 1;
+    gui.char_height = (- extent.ul.y) + extent.lr.y + 1;
+    gui.char_ascent = - extent.ul.y;
+
+    vim_free( font_name );
+    return( OK );
+}
+
+    int
+gui_mch_adjust_charsize(void)
+{
+    FontQueryInfo info;
+
+    PfQueryFontInfo( gui.norm_font, &info );
+
+    gui.char_height = - info.ascender + info.descender + p_linespace;
+    gui.char_ascent = - info.ascender + p_linespace / 2;
+
+    return( OK );
+}
+
+    GuiFont
+gui_mch_get_font(char_u *vim_font_name, int report_error)
+{
+    char_u  *font_name;
+    char_u  *font_tag;
+    int_u   font_size = 12;
+    int_u   font_flags = 0;
+
+    if( gui_ph_parse_font_name( vim_font_name, &font_name, &font_flags,
+		&font_size ) != FALSE )
+    {
+	font_tag = gui_ph_get_font( font_name, font_flags, font_size, -1 );
+	vim_free( font_name );
+
+	if( font_tag != NULL )
+	    return( (GuiFont) font_tag );
+    }
+
+    if( report_error )
+	EMSG2(e_font, vim_font_name );
+
+    return( FAIL );
+}
+
+    void
+gui_mch_set_font(GuiFont font)
+{
+    PgSetFont( font );
+}
+
+    void
+gui_mch_free_font(GuiFont font)
+{
+    vim_free( font );
+}
+
