/* 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"

/* cproto fails on missing include files */
#ifndef PROTO
# ifdef FEAT_TOOLBAR
#  include <photon/PxImage.h>
# endif
#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 separately,
     * 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, RESIZE_BOTH);
	    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 weird problems, 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, RESIZE_BOTH);
    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)
{
    PhGC_t *gc;

    gc = PgGetGC();
    PgSetRegion(PtWidgetRid(PtFindDisjoint(gui.vimTextArea)));
    PgClearClippingsCx(gc);
    PgClearTranslationCx(gc);

    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}; /* Arbitrary 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,
	int	ex_cmd)
{
    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,
	int direction)
{
    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
    }
}

    void
gui_mch_getmouse(int *x, int *y)
{
    PhCursorInfo_t info;
    short ix, iy;

    /* FIXME: does this return the correct position,
     * with respect to the border? */
    PhQueryCursor(PhInputGroup(NULL), &info);
    PtGetAbsPosition(gui.vimTextArea , &ix, &iy);

    *x = info.pos.x - ix;
    *y = info.pos.y - iy;
}

    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 separate 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(0xA9, 0xA9, 0xA9)},
	{"DarkGrey",	    RGB(0xA9, 0xA9, 0xA9)},
	{"Gray",	    RGB(0xC0, 0xC0, 0xC0)},
	{"Grey",	    RGB(0xC0, 0xC0, 0xC0)},
	{"LightGray",	    RGB(0xD3, 0xD3, 0xD3)},
	{"LightGrey",	    RGB(0xD3, 0xD3, 0xD3)},
	{"Gray10",	    RGB(0x1A, 0x1A, 0x1A)},
	{"Grey10",	    RGB(0x1A, 0x1A, 0x1A)},
	{"Gray20",	    RGB(0x33, 0x33, 0x33)},
	{"Grey20",	    RGB(0x33, 0x33, 0x33)},
	{"Gray30",	    RGB(0x4D, 0x4D, 0x4D)},
	{"Grey30",	    RGB(0x4D, 0x4D, 0x4D)},
	{"Gray40",	    RGB(0x66, 0x66, 0x66)},
	{"Grey40",	    RGB(0x66, 0x66, 0x66)},
	{"Gray50",	    RGB(0x7F, 0x7F, 0x7F)},
	{"Grey50",	    RGB(0x7F, 0x7F, 0x7F)},
	{"Gray60",	    RGB(0x99, 0x99, 0x99)},
	{"Grey60",	    RGB(0x99, 0x99, 0x99)},
	{"Gray70",	    RGB(0xB3, 0xB3, 0xB3)},
	{"Grey70",	    RGB(0xB3, 0xB3, 0xB3)},
	{"Gray80",	    RGB(0xCC, 0xCC, 0xCC)},
	{"Grey80",	    RGB(0xCC, 0xCC, 0xCC)},
	{"Gray90",	    RGB(0xE5, 0xE5, 0xE5)},
	{"Grey90",	    RGB(0xE5, 0xE5, 0xE5)},
	{"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(0xAD, 0xD8, 0xE6)},
	{"DarkGreen",	    RGB(0x00, 0x80, 0x00)},
	{"Green",	    RGB(0x00, 0xFF, 0x00)},
	{"LightGreen",	    RGB(0x90, 0xEE, 0x90)},
	{"DarkCyan",	    RGB(0x00, 0x80, 0x80)},
	{"Cyan",	    RGB(0x00, 0xFF, 0xFF)},
	{"LightCyan",	    RGB(0xE0, 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, 0xE0)},
	{"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_set_sp_color(guicolor_T 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 Terminal";
    }

    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;
}

/*
 * Adjust gui.char_height (after 'linespace' was changed).
 */
    int
gui_mch_adjust_charheight(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;
}

#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

    void
gui_mch_set_font(GuiFont font)
{
    PgSetFont(font);
}

    void
gui_mch_free_font(GuiFont font)
{
    vim_free(font);
}

