/*
 * a GUI application for displaying a console
 *	USER32 back end
 * Copyright 2001 Eric Pouech
 */

#include <stdio.h>
#include <stdlib.h>
#include "winecon_user.h"

/* mapping console colors to RGB values */
COLORREF	WCUSER_ColorMap[16] = 
{
    RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x80), RGB(0x00, 0x80, 0x00), RGB(0x00, 0x80, 0x80),
    RGB(0x80, 0x00, 0x00), RGB(0x80, 0x00, 0x80), RGB(0x80, 0x80, 0x00), RGB(0x80, 0x80, 0x80),
    RGB(0xC0, 0xC0, 0xC0), RGB(0x00, 0x00, 0xFF), RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0xFF),
    RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0xFF, 0x00), RGB(0xFF, 0xFF, 0xFF),
};

/******************************************************************
 *		WCUSER_FillMemDC
 *
 * Fills the Mem DC with current cells values
 */
static void WCUSER_FillMemDC(const struct inner_data* data, int upd_tp, int upd_bm)
{
    unsigned		i, j, k;
    CHAR_INFO*		cell;
    HFONT		hOldFont;
    WORD		attr;
    WCHAR*		line;

    if (!(line = HeapAlloc(GetProcessHeap(), 0, data->curcfg.sb_width * sizeof(WCHAR))))
    {Trace(0, "OOM\n"); return;}

    hOldFont = SelectObject(PRIVATE(data)->hMemDC, PRIVATE(data)->hFont);
    for (j = upd_tp; j <= upd_bm; j++)
    {
	cell = &data->cells[j * data->curcfg.sb_width];
	for (i = 0; i < data->curcfg.win_width; i++)
	{
	    attr = cell[i].Attributes;
	    SetBkColor(PRIVATE(data)->hMemDC,WCUSER_ColorMap[(attr>>4)&0x0F]);
	    SetTextColor(PRIVATE(data)->hMemDC, WCUSER_ColorMap[attr&0x0F]);
	    for (k = i; k < data->curcfg.win_width && cell[k].Attributes == attr; k++)
	    {
		line[k - i] = cell[k].Char.UnicodeChar;
	    }
	    TextOut(PRIVATE(data)->hMemDC, i * data->curcfg.cell_width, j * data->curcfg.cell_height, 
		    line, k - i);
	    i = k - 1;
	}
    }
    SelectObject(PRIVATE(data)->hMemDC, hOldFont);
    HeapFree(GetProcessHeap(), 0, line);
}

/******************************************************************
 *		WCUSER_NewBitmap
 *
 * Either the font geometry or the sb geometry has changed. we need to recreate the
 * bitmap geometry
 */
static void WCUSER_NewBitmap(struct inner_data* data, BOOL fill)
{
    HDC         hDC;
    HBITMAP	hnew, hold;

    if (!data->curcfg.sb_width || !data->curcfg.sb_height || !(hDC = GetDC(PRIVATE(data)->hWnd))) 
        return;
    hnew = CreateCompatibleBitmap(hDC, 
				  data->curcfg.sb_width  * data->curcfg.cell_width, 
				  data->curcfg.sb_height * data->curcfg.cell_height);
    ReleaseDC(PRIVATE(data)->hWnd, hDC);
    hold = SelectObject(PRIVATE(data)->hMemDC, hnew);

    if (PRIVATE(data)->hBitmap)
    {
	if (hold == PRIVATE(data)->hBitmap)
	    DeleteObject(PRIVATE(data)->hBitmap);
	else
	    Trace(0, "leak\n");
    }
    PRIVATE(data)->hBitmap = hnew;
    if (fill)
	WCUSER_FillMemDC(data, 0, data->curcfg.sb_height - 1);
}

/******************************************************************
 *		WCUSER_ResizeScreenBuffer
 *
 *
 */
static void WCUSER_ResizeScreenBuffer(struct inner_data* data)
{
    WCUSER_NewBitmap(data, FALSE);
}

/******************************************************************
 *		WCUSER_PosCursor
 *
 * Set a new position for the cursor
 */
static void	WCUSER_PosCursor(const struct inner_data* data)
{
    if (PRIVATE(data)->hWnd != GetFocus() || !data->curcfg.cursor_visible) return;

    SetCaretPos((data->cursor.X - data->curcfg.win_pos.X) * data->curcfg.cell_width, 
		(data->cursor.Y - data->curcfg.win_pos.Y) * data->curcfg.cell_height);
    ShowCaret(PRIVATE(data)->hWnd); 
}

/******************************************************************
 *		WCUSER_ShapeCursor
 *
 * Sets a new shape for the cursor
 */
void	WCUSER_ShapeCursor(struct inner_data* data, int size, int vis, BOOL force)
{
    if (force || size != data->curcfg.cursor_size)
    {
	if (data->curcfg.cursor_visible && PRIVATE(data)->hWnd == GetFocus()) DestroyCaret();
	if (PRIVATE(data)->cursor_bitmap) DeleteObject(PRIVATE(data)->cursor_bitmap);
	PRIVATE(data)->cursor_bitmap = (HBITMAP)0;
	if (size != 100)
	{
	    int		w16b; /* number of byets per row, aligned on word size */
	    BYTE*	ptr;
	    int		i, j, nbl;

	    w16b = ((data->curcfg.cell_width + 15) & ~15) / 8;
	    ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, w16b * data->curcfg.cell_height);
	    if (!ptr) {Trace(0, "OOM\n"); return;}
	    nbl = max((data->curcfg.cell_height * size) / 100, 1);
	    for (j = data->curcfg.cell_height - nbl; j < data->curcfg.cell_height; j++)
	    {
		for (i = 0; i < data->curcfg.cell_width; i++)
		{
		    ptr[w16b * j + (i / 8)] |= 0x80 >> (i & 7);
		}
	    }
	    PRIVATE(data)->cursor_bitmap = CreateBitmap(data->curcfg.cell_width, 
                                               data->curcfg.cell_height, 1, 1, ptr);
	    HeapFree(GetProcessHeap(), 0, ptr);
	}
	data->curcfg.cursor_size = size;
	data->curcfg.cursor_visible = -1;
    }

    vis = (vis) ? TRUE : FALSE;
    if (force || vis != data->curcfg.cursor_visible)
    {
	data->curcfg.cursor_visible = vis;
	if (PRIVATE(data)->hWnd == GetFocus())
	{
	    if (vis)
	    {
		CreateCaret(PRIVATE(data)->hWnd, PRIVATE(data)->cursor_bitmap, 
                            data->curcfg.cell_width, data->curcfg.cell_height);
		WCUSER_PosCursor(data);
	    }
	    else
	    {
		DestroyCaret();
	    }
	}
    }
}

/******************************************************************
 *		INECON_ComputePositions
 *
 * Recomputes all the components (mainly scroll bars) positions
 */
void	WCUSER_ComputePositions(struct inner_data* data)
{
    RECT		r;
    int			dx, dy;

    /* compute window size from desired client size */
    r.left = r.top = 0;
    r.right = data->curcfg.win_width * data->curcfg.cell_width;
    r.bottom = data->curcfg.win_height * data->curcfg.cell_height;

    if (IsRectEmpty(&r))
    {
	ShowWindow(PRIVATE(data)->hWnd, SW_HIDE);
	return;
    }

    AdjustWindowRect(&r, GetWindowLong(PRIVATE(data)->hWnd, GWL_STYLE), FALSE);

    dx = dy = 0;
    if (data->curcfg.sb_width > data->curcfg.win_width)
    {
	dy = GetSystemMetrics(SM_CYHSCROLL);
	SetScrollRange(PRIVATE(data)->hWnd, SB_HORZ, 0, 
                       data->curcfg.sb_width - data->curcfg.win_width, FALSE);
	SetScrollPos(PRIVATE(data)->hWnd, SB_HORZ, 0, FALSE); /* FIXME */
	ShowScrollBar(PRIVATE(data)->hWnd, SB_HORZ, TRUE);
    }
    else
    {
	ShowScrollBar(PRIVATE(data)->hWnd, SB_HORZ, FALSE);
    }

    if (data->curcfg.sb_height > data->curcfg.win_height)
    {
	dx = GetSystemMetrics(SM_CXVSCROLL);
	SetScrollRange(PRIVATE(data)->hWnd, SB_VERT, 0, 
                       data->curcfg.sb_height - data->curcfg.win_height, FALSE);
	SetScrollPos(PRIVATE(data)->hWnd, SB_VERT, 0, FALSE); /* FIXME */
	ShowScrollBar(PRIVATE(data)->hWnd, SB_VERT, TRUE);
    }	
    else
    {
	ShowScrollBar(PRIVATE(data)->hWnd, SB_VERT, FALSE);
    }

    SetWindowPos(PRIVATE(data)->hWnd, 0, 0, 0, r.right - r.left + dx, r.bottom - r.top + dy,
		 SWP_NOMOVE|SWP_NOZORDER|SWP_SHOWWINDOW);
    WCUSER_ShapeCursor(data, data->curcfg.cursor_size, data->curcfg.cursor_visible, TRUE);
    WCUSER_PosCursor(data);
}

/******************************************************************
 *		WCUSER_SetTitle
 *
 * Sets the title to the wine console
 */
static void	WCUSER_SetTitle(const struct inner_data* data)
{
    WCHAR	buffer[256];	

    if (WINECON_GetConsoleTitle(data->hConIn, buffer, sizeof(buffer)))
	SetWindowText(PRIVATE(data)->hWnd, buffer);
}

/******************************************************************
 *		FontEqual
 *
 *
 */
BOOL WCUSER_AreFontsEqual(const struct config_data* config, const LOGFONT* lf)
{
    return lf->lfHeight == config->cell_height &&
        lf->lfWidth  == config->cell_width &&
        lf->lfWeight == config->font_weight &&
        !lf->lfItalic && !lf->lfUnderline && !lf->lfStrikeOut &&
        !lstrcmpW(lf->lfFaceName, config->face_name);
}

/******************************************************************
 *		CopyFont
 *
 *
 */
void WCUSER_CopyFont(struct config_data* config, const LOGFONT* lf)
{
    config->cell_width  = lf->lfWidth;
    config->cell_height = lf->lfHeight;
    config->font_weight  = lf->lfWeight;
    lstrcpyW(config->face_name, lf->lfFaceName);
}

/******************************************************************
 *		WCUSER_InitFont
 *
 * create a hFont from the settings saved in registry...
 * (called on init, assuming no font has been created before)
 */
BOOL	WCUSER_InitFont(struct inner_data* data)
{
    LOGFONT lf;
        
    lf.lfHeight        = -data->curcfg.cell_height;
    lf.lfWidth         = data->curcfg.cell_width;
    lf.lfEscapement    = 0;
    lf.lfOrientation   = 0;
    lf.lfWeight        = data->curcfg.font_weight;
    lf.lfItalic        = FALSE;
    lf.lfUnderline     = FALSE;
    lf.lfStrikeOut     = FALSE;
    lf.lfCharSet       = DEFAULT_CHARSET;
    lf.lfOutPrecision  = OUT_DEFAULT_PRECIS;
    lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; 
    lf.lfQuality       = DEFAULT_QUALITY;
    lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
    lstrcpy(lf.lfFaceName, data->curcfg.face_name);
    PRIVATE(data)->hFont = CreateFontIndirect(&lf);
    if (!PRIVATE(data)->hFont) return FALSE;

    WCUSER_ComputePositions(data);
    WCUSER_NewBitmap(data, TRUE);
    InvalidateRect(PRIVATE(data)->hWnd, NULL, FALSE);
    UpdateWindow(PRIVATE(data)->hWnd);
    return TRUE;
}

/******************************************************************
 *		WCUSER_SetFont
 *
 * sets logfont as the new font for the console
 */
BOOL	WCUSER_SetFont(struct inner_data* data, const LOGFONT* logfont)
{
    if (WCUSER_AreFontsEqual(&data->curcfg, logfont)) return TRUE;
    if (PRIVATE(data)->hFont) DeleteObject(PRIVATE(data)->hFont);
    PRIVATE(data)->hFont = CreateFontIndirect(logfont);
    if (!PRIVATE(data)->hFont) {Trace(0, "wrong font\n");return FALSE;}
    WCUSER_CopyFont(&data->curcfg, logfont);

    WCUSER_ComputePositions(data);
    WCUSER_NewBitmap(data, TRUE);
    InvalidateRect(PRIVATE(data)->hWnd, NULL, FALSE);
    UpdateWindow(PRIVATE(data)->hWnd);
    return TRUE;
}

/******************************************************************
 *		WCUSER_GetCell
 *
 * Get a cell from the a relative coordinate in window (takes into
 * account the scrolling)
 */
static COORD	WCUSER_GetCell(const struct inner_data* data, LPARAM lParam)
{
    COORD	c;

    c.X = data->curcfg.win_pos.X + (short)LOWORD(lParam) / data->curcfg.cell_width;
    c.Y = data->curcfg.win_pos.Y + (short)HIWORD(lParam) / data->curcfg.cell_height;

    return c;
}

/******************************************************************
 *		WCUSER_GetSelectionRect
 *
 * Get the selection rectangle
 */
static void	WCUSER_GetSelectionRect(const struct inner_data* data, LPRECT r)
{
    r->left   = (min(PRIVATE(data)->selectPt1.X, PRIVATE(data)->selectPt2.X)    ) * data->curcfg.cell_width;
    r->top    = (min(PRIVATE(data)->selectPt1.Y, PRIVATE(data)->selectPt2.Y)    ) * data->curcfg.cell_height;
    r->right  = (max(PRIVATE(data)->selectPt1.X, PRIVATE(data)->selectPt2.X) + 1) * data->curcfg.cell_width;
    r->bottom = (max(PRIVATE(data)->selectPt1.Y, PRIVATE(data)->selectPt2.Y) + 1) * data->curcfg.cell_height;
}

/******************************************************************
 *		WCUSER_SetSelection
 *
 *
 */
static void	WCUSER_SetSelection(const struct inner_data* data, HDC hRefDC)
{
    HDC		hDC;
    RECT	r;

    WCUSER_GetSelectionRect(data, &r);
    hDC = hRefDC ? hRefDC : GetDC(PRIVATE(data)->hWnd);
    if (hDC)
    {
	if (PRIVATE(data)->hWnd == GetFocus() && data->curcfg.cursor_visible)
	    HideCaret(PRIVATE(data)->hWnd);
	InvertRect(hDC, &r);
	if (hDC != hRefDC)
	    ReleaseDC(PRIVATE(data)->hWnd, hDC);
	if (PRIVATE(data)->hWnd == GetFocus() && data->curcfg.cursor_visible)
	    ShowCaret(PRIVATE(data)->hWnd);
    }
}

/******************************************************************
 *		WCUSER_MoveSelection
 *
 *
 */
static void	WCUSER_MoveSelection(struct inner_data* data, COORD dst, BOOL final)
{
    RECT	r;
    HDC		hDC;

    WCUSER_GetSelectionRect(data, &r);
    hDC = GetDC(PRIVATE(data)->hWnd);
    if (hDC)
    {
	if (PRIVATE(data)->hWnd == GetFocus() && data->curcfg.cursor_visible)
	    HideCaret(PRIVATE(data)->hWnd);
	InvertRect(hDC, &r);
    }
    PRIVATE(data)->selectPt2 = dst;
    if (hDC)
    {
	WCUSER_GetSelectionRect(data, &r);
	InvertRect(hDC, &r);
	ReleaseDC(PRIVATE(data)->hWnd, hDC);
	if (PRIVATE(data)->hWnd == GetFocus() && data->curcfg.cursor_visible)
	    ShowCaret(PRIVATE(data)->hWnd);
    }
    if (final)
    {
	ReleaseCapture();
	PRIVATE(data)->hasSelection = TRUE;
    }
}

/******************************************************************
 *		WCUSER_CopySelectionToClipboard
 *
 * Copies the current selection into the clipboard
 */
static void	WCUSER_CopySelectionToClipboard(const struct inner_data* data)
{
    HANDLE	hMem;
    LPWSTR	p;
    unsigned	w, h;

    w = abs(PRIVATE(data)->selectPt1.X - PRIVATE(data)->selectPt2.X) + 2;
    h = abs(PRIVATE(data)->selectPt1.Y - PRIVATE(data)->selectPt2.Y) + 1;

    if (!OpenClipboard(PRIVATE(data)->hWnd)) return;
    EmptyClipboard();

    hMem = GlobalAlloc(GMEM_MOVEABLE, (w * h - 1) * sizeof(WCHAR));
    if (hMem && (p = GlobalLock(hMem)))
    {
	COORD	c;
	int	y;

	c.X = data->curcfg.win_pos.X + min(PRIVATE(data)->selectPt1.X, PRIVATE(data)->selectPt2.X);
	c.Y = data->curcfg.win_pos.Y + min(PRIVATE(data)->selectPt1.Y, PRIVATE(data)->selectPt2.Y);
	
	for (y = 0; y < h; y++, c.Y++)
	{
	    ReadConsoleOutputCharacter(data->hConOut, &p[y * w], w - 1, c, NULL);
	    if (y < h - 1) p[y * w + w - 1] = '\n';
	}
	GlobalUnlock(hMem);
	SetClipboardData(CF_UNICODETEXT, hMem);
    }
    CloseClipboard();
}

/******************************************************************
 *		WCUSER_PasteFromClipboard
 *
 *
 */
static void	WCUSER_PasteFromClipboard(struct inner_data* data)
{
    HANDLE	h;
    WCHAR*	ptr;

    if (!OpenClipboard(PRIVATE(data)->hWnd)) return;
    h = GetClipboardData(CF_UNICODETEXT);
    if (h && (ptr = GlobalLock(h)))
    {
	int		i, len = GlobalSize(h) / sizeof(WCHAR);
	INPUT_RECORD	ir[2];
	DWORD		n;
	SHORT		sh;

	ir[0].EventType = KEY_EVENT;
	ir[0].Event.KeyEvent.wRepeatCount = 0;
	ir[0].Event.KeyEvent.dwControlKeyState = 0;
	ir[0].Event.KeyEvent.bKeyDown = TRUE;

	/* generate the corresponding input records */
	for (i = 0; i < len; i++)
	{
	    /* FIXME: the modifying keys are not generated (shift, ctrl...) */
	    sh = VkKeyScan(ptr[i]);
	    ir[0].Event.KeyEvent.wVirtualKeyCode = LOBYTE(sh);
	    ir[0].Event.KeyEvent.wVirtualScanCode = MapVirtualKey(LOBYTE(sh), 0);
	    ir[0].Event.KeyEvent.uChar.UnicodeChar = ptr[i];
	    
	    ir[1] = ir[0];
	    ir[1].Event.KeyEvent.bKeyDown = FALSE;
	    
	    WriteConsoleInput(data->hConIn, ir, 2, &n);
	}
	GlobalUnlock(h);
    }
    CloseClipboard();
}

/******************************************************************
 *		Refresh
 *
 *
 */
static void WCUSER_Refresh(const struct inner_data* data, int tp, int bm)
{
    if (data->curcfg.win_pos.Y <= bm && data->curcfg.win_pos.Y + data->curcfg.win_height >= tp)
    {
	RECT	r;

	r.left   = 0;
	r.right  = data->curcfg.win_width * data->curcfg.cell_width;
	r.top    = (tp - data->curcfg.win_pos.Y) * data->curcfg.cell_height;
	r.bottom = (bm - data->curcfg.win_pos.Y + 1) * data->curcfg.cell_height;
	InvalidateRect(PRIVATE(data)->hWnd, &r, FALSE);
	WCUSER_FillMemDC(data, tp, bm);
	UpdateWindow(PRIVATE(data)->hWnd);
    }
}

/******************************************************************
 *		WCUSER_Paint
 *
 *
 */
static void	WCUSER_Paint(const struct inner_data* data)
{
    PAINTSTRUCT		ps;

    BeginPaint(PRIVATE(data)->hWnd, &ps);
    BitBlt(ps.hdc, 0, 0, 
           data->curcfg.win_width * data->curcfg.cell_width, 
           data->curcfg.win_height * data->curcfg.cell_height,
	   PRIVATE(data)->hMemDC, 
           data->curcfg.win_pos.X * data->curcfg.cell_width, 
           data->curcfg.win_pos.Y * data->curcfg.cell_height,
	   SRCCOPY);
    if (PRIVATE(data)->hasSelection)
	WCUSER_SetSelection(data, ps.hdc);
    EndPaint(PRIVATE(data)->hWnd, &ps);
}

/******************************************************************
 *		WCUSER_Scroll
 *
 *
 */
static void WCUSER_Scroll(struct inner_data* data, int pos, BOOL horz)
{
    if (horz)
    {
	SetScrollPos(PRIVATE(data)->hWnd, SB_HORZ, pos, TRUE);
	data->curcfg.win_pos.X = pos;
	InvalidateRect(PRIVATE(data)->hWnd, NULL, FALSE);
    }
    else
    {
	SetScrollPos(PRIVATE(data)->hWnd, SB_VERT, pos, TRUE);
	data->curcfg.win_pos.Y = pos;
    }
    InvalidateRect(PRIVATE(data)->hWnd, NULL, FALSE);
}

struct font_chooser {
    struct inner_data*	data;
    int			done;
};

/******************************************************************
 *		WCUSER_ValidateFontMetric
 *
 * Returns true if the font described in tm is usable as a font for the renderer
 */
BOOL	WCUSER_ValidateFontMetric(const struct inner_data* data, const TEXTMETRIC* tm)
{
    return tm->tmMaxCharWidth * data->curcfg.win_width < GetSystemMetrics(SM_CXSCREEN) &&
	tm->tmHeight * data->curcfg.win_height < GetSystemMetrics(SM_CYSCREEN) &&
	!tm->tmItalic && !tm->tmUnderlined && !tm->tmStruckOut;
}

/******************************************************************
 *		WCUSER_ValidateFont
 *
 * Returns true if the font family described in lf is usable as a font for the renderer
 */
BOOL	WCUSER_ValidateFont(const struct inner_data* data, const LOGFONT* lf)
{
    return (lf->lfPitchAndFamily & 3) == FIXED_PITCH && 
        (lf->lfPitchAndFamily & 0xF0) == FF_MODERN &&
        lf->lfCharSet != SYMBOL_CHARSET;
}

/******************************************************************
 *		get_first_font_enum_2
 *		get_first_font_enum
 *
 * Helper functions to get a decent font for the renderer
 */
static int CALLBACK get_first_font_enum_2(const LOGFONT* lf, const TEXTMETRIC* tm, 
					  DWORD FontType, LPARAM lParam)
{
    struct font_chooser*	fc = (struct font_chooser*)lParam;

    if (WCUSER_ValidateFontMetric(fc->data, tm))
    {
	WCUSER_SetFont(fc->data, lf);
	fc->done = 1;
	return 0;
    }
    return 1;
}

static int CALLBACK get_first_font_enum(const LOGFONT* lf, const TEXTMETRIC* tm, 
					DWORD FontType, LPARAM lParam)
{
    struct font_chooser*	fc = (struct font_chooser*)lParam;

    if (WCUSER_ValidateFont(fc->data, lf))
    {
	EnumFontFamilies(PRIVATE(fc->data)->hMemDC, lf->lfFaceName, get_first_font_enum_2, lParam);
	return !fc->done; /* we just need the first matching one... */
    }
    return 1;
}

/******************************************************************
 *		WCUSER_FillMenu
 *
 *
 */
static BOOL WCUSER_FillMenu(HMENU hMenu, BOOL sep)
{
    HMENU		hSubMenu;
    HINSTANCE		hInstance = GetModuleHandle(NULL);
    WCHAR		buff[256];

    if (!hMenu) return FALSE;

    /* FIXME: error handling & memory cleanup */
    hSubMenu = CreateMenu();
    if (!hSubMenu) return FALSE;

    LoadString(hInstance, IDS_MARK, buff, sizeof(buff) / sizeof(WCHAR));
    InsertMenu(hSubMenu, -1, MF_BYPOSITION|MF_STRING, IDS_MARK, buff);
    LoadString(hInstance, IDS_COPY, buff, sizeof(buff) / sizeof(WCHAR));
    InsertMenu(hSubMenu, -1, MF_BYPOSITION|MF_STRING, IDS_COPY, buff);
    LoadString(hInstance, IDS_PASTE, buff, sizeof(buff) / sizeof(WCHAR));
    InsertMenu(hSubMenu, -1, MF_BYPOSITION|MF_STRING, IDS_PASTE, buff);
    LoadString(hInstance, IDS_SELECTALL, buff, sizeof(buff) / sizeof(WCHAR));
    InsertMenu(hSubMenu, -1, MF_BYPOSITION|MF_STRING, IDS_SELECTALL, buff);
    LoadString(hInstance, IDS_SCROLL, buff, sizeof(buff) / sizeof(WCHAR));
    InsertMenu(hSubMenu, -1, MF_BYPOSITION|MF_STRING, IDS_SCROLL, buff);
    LoadString(hInstance, IDS_SEARCH, buff, sizeof(buff) / sizeof(WCHAR));
    InsertMenu(hSubMenu, -1, MF_BYPOSITION|MF_STRING, IDS_SEARCH, buff);

    if (sep) InsertMenu(hMenu, -1, MF_BYPOSITION|MF_SEPARATOR, 0, NULL);
    LoadString(hInstance, IDS_EDIT, buff, sizeof(buff) / sizeof(WCHAR));
    InsertMenu(hMenu, -1, MF_BYPOSITION|MF_STRING|MF_POPUP, (UINT_PTR)hSubMenu, buff);
    LoadString(hInstance, IDS_DEFAULT, buff, sizeof(buff) / sizeof(WCHAR));
    InsertMenu(hMenu, -1, MF_BYPOSITION|MF_STRING, IDS_DEFAULT, buff);
    LoadString(hInstance, IDS_PROPERTY, buff, sizeof(buff) / sizeof(WCHAR));
    InsertMenu(hMenu, -1, MF_BYPOSITION|MF_STRING, IDS_PROPERTY, buff);

    return TRUE;
}

/******************************************************************
 *		WCUSER_Create
 *
 * Creates the window for the rendering
 */
static LRESULT WCUSER_Create(HWND hWnd, LPCREATESTRUCT lpcs)
{
    struct inner_data*	data;
    HMENU		hSysMenu;

    data = lpcs->lpCreateParams;
    SetWindowLong(hWnd, 0L, (DWORD)data);
    PRIVATE(data)->hWnd = hWnd;

    data->curcfg.cursor_size = 101; /* invalid value, will trigger a complete cleanup */

    hSysMenu = GetSystemMenu(hWnd, FALSE);
    if (!hSysMenu) return 0;
    PRIVATE(data)->hPopMenu = CreatePopupMenu();
    if (!PRIVATE(data)->hPopMenu) return 0;

    WCUSER_FillMenu(hSysMenu, TRUE);
    WCUSER_FillMenu(PRIVATE(data)->hPopMenu, FALSE);

    PRIVATE(data)->hMemDC = CreateCompatibleDC(0);
    if (!PRIVATE(data)->hMemDC) {Trace(0, "no mem dc\n");return 0;}

    return 0;
}

/******************************************************************
 *		WCUSER_SetMenuDetails
 *
 * Grays / ungrays the menu items according to their state
 */
static void	WCUSER_SetMenuDetails(const struct inner_data* data)
{
    HMENU		hMenu = GetSystemMenu(PRIVATE(data)->hWnd, FALSE);

    if (!hMenu) {Trace(0, "Issue in getting menu bits\n");return;}

    /* FIXME: set the various menu items to their state (if known) */
    EnableMenuItem(hMenu, IDS_DEFAULT, MF_BYCOMMAND|MF_GRAYED);

    EnableMenuItem(hMenu, IDS_MARK, MF_BYCOMMAND|MF_GRAYED);
    EnableMenuItem(hMenu, IDS_COPY, MF_BYCOMMAND|(PRIVATE(data)->hasSelection ? MF_ENABLED : MF_GRAYED));
    EnableMenuItem(hMenu, IDS_PASTE, 
		   MF_BYCOMMAND|(IsClipboardFormatAvailable(CF_UNICODETEXT) 
				 ? MF_ENABLED : MF_GRAYED));
    /* Select all: always active */
    EnableMenuItem(hMenu, IDS_SCROLL, MF_BYCOMMAND|MF_GRAYED);
    EnableMenuItem(hMenu, IDS_SEARCH, MF_BYCOMMAND|MF_GRAYED);
}

/******************************************************************
 *		WCUSER_GenerateKeyInputRecord
 *
 * generates input_record from windows WM_KEYUP/WM_KEYDOWN messages
 */
static void    WCUSER_GenerateKeyInputRecord(struct inner_data* data, BOOL down, 
                                             WPARAM wParam, LPARAM lParam, BOOL sys)
{
    INPUT_RECORD	ir;
    DWORD		n;
    WCHAR		buf[2];
    BYTE		keyState[256];
    static	WCHAR	last; /* keep last char seen as feed for key up message */

    ir.EventType = KEY_EVENT;
    ir.Event.KeyEvent.bKeyDown = down;
    ir.Event.KeyEvent.wRepeatCount = LOWORD(lParam);
    ir.Event.KeyEvent.wVirtualKeyCode = wParam;
    
    ir.Event.KeyEvent.wVirtualScanCode = HIWORD(lParam) & 0xFF;
    GetKeyboardState(keyState);
    
    ir.Event.KeyEvent.uChar.UnicodeChar = 0;
    ir.Event.KeyEvent.dwControlKeyState = 0;
    if (lParam & (1L << 24))		ir.Event.KeyEvent.dwControlKeyState |= ENHANCED_KEY;
    if (keyState[VK_SHIFT]    & 0x80)	ir.Event.KeyEvent.dwControlKeyState |= SHIFT_PRESSED;
    if (keyState[VK_CONTROL]  & 0x80)	ir.Event.KeyEvent.dwControlKeyState |= LEFT_CTRL_PRESSED; /* FIXME: gotta choose one */
    if (keyState[VK_LCONTROL] & 0x80)	ir.Event.KeyEvent.dwControlKeyState |= LEFT_CTRL_PRESSED;
    if (keyState[VK_RCONTROL] & 0x80)	ir.Event.KeyEvent.dwControlKeyState |= RIGHT_CTRL_PRESSED;
    if (sys)				ir.Event.KeyEvent.dwControlKeyState |= LEFT_ALT_PRESSED; /* FIXME: gotta choose one */
    if (keyState[VK_LMENU]    & 0x80)	ir.Event.KeyEvent.dwControlKeyState |= LEFT_ALT_PRESSED;
    if (keyState[VK_RMENU]    & 0x80)	ir.Event.KeyEvent.dwControlKeyState |= RIGHT_ALT_PRESSED;
    if (keyState[VK_CAPITAL]  & 0x01)	ir.Event.KeyEvent.dwControlKeyState |= CAPSLOCK_ON;	    
    if (keyState[VK_NUMLOCK]  & 0x01)	ir.Event.KeyEvent.dwControlKeyState |= NUMLOCK_ON;
    if (keyState[VK_SCROLL]   & 0x01)	ir.Event.KeyEvent.dwControlKeyState |= SCROLLLOCK_ON;

    if (PRIVATE(data)->hasSelection && ir.Event.KeyEvent.dwControlKeyState == 0 && 
	ir.Event.KeyEvent.wVirtualKeyCode == VK_RETURN)
    {
	PRIVATE(data)->hasSelection = FALSE;
	WCUSER_SetSelection(data, 0);
	WCUSER_CopySelectionToClipboard(data);
	return;
    }
    
    if (!(ir.Event.KeyEvent.dwControlKeyState & ENHANCED_KEY))
    {
	if (down)
	{
	    switch (ToUnicode(wParam, HIWORD(lParam), keyState, buf, 2, 0))
	    {
	    case 2:
		/* FIXME... should generate two events... */
		/* fall thru */
	    case 1:	
		last = buf[0];
		break;
	    default:
		last = 0;
		break;
	    }
	}
	ir.Event.KeyEvent.uChar.UnicodeChar = last; /* FIXME HACKY... and buggy 'coz it should be a stack, not a single value */
	if (!down) last = 0;
    }

    WriteConsoleInput(data->hConIn, &ir, 1, &n);
}

/******************************************************************
 *		WCUSER_Proc
 *
 *
 */
static LRESULT CALLBACK WCUSER_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    struct inner_data*	data = (struct inner_data*)GetWindowLong(hWnd, 0);

    switch (uMsg)
    {
    case WM_CREATE:
        return WCUSER_Create(hWnd, (LPCREATESTRUCT)lParam);
    case WM_DESTROY:
	PRIVATE(data)->hWnd = 0;
	PostQuitMessage(0);
	break;
    case WM_PAINT:
	WCUSER_Paint(data);
	break;
    case WM_KEYDOWN:
    case WM_KEYUP:
	WCUSER_GenerateKeyInputRecord(data, uMsg == WM_KEYDOWN, wParam, lParam, FALSE);
	break;
    case WM_SYSKEYDOWN:
    case WM_SYSKEYUP:
	WCUSER_GenerateKeyInputRecord(data, uMsg == WM_SYSKEYDOWN, wParam, lParam, TRUE);
	break;
    case WM_LBUTTONDOWN:
	/* EPP if (wParam != MK_LBUTTON) */
	if (PRIVATE(data)->hasSelection)
	{
	    PRIVATE(data)->hasSelection = FALSE;
	}
	else
	{
	    PRIVATE(data)->selectPt1 = PRIVATE(data)->selectPt2 = WCUSER_GetCell(data, lParam);
	    SetCapture(PRIVATE(data)->hWnd);
	}
	WCUSER_SetSelection(data, 0);
	break;
    case WM_MOUSEMOVE:
	/* EPP if (wParam != MK_LBUTTON) */
        if (GetCapture() == PRIVATE(data)->hWnd)
	{
	    WCUSER_MoveSelection(data, WCUSER_GetCell(data, lParam), FALSE);
	}
	break;
    case WM_LBUTTONUP:
	/* EPP if (wParam != MK_LBUTTON) */
        if (GetCapture() == PRIVATE(data)->hWnd)
	{
	    WCUSER_MoveSelection(data, WCUSER_GetCell(data, lParam), TRUE);
	}
	break;
    case WM_SETFOCUS:
	if (data->curcfg.cursor_visible)
	{
	    CreateCaret(PRIVATE(data)->hWnd, PRIVATE(data)->cursor_bitmap, 
                        data->curcfg.cell_width, data->curcfg.cell_height); 
	    WCUSER_PosCursor(data);
	}
        break; 
    case WM_KILLFOCUS: 
	if (data->curcfg.cursor_visible)
	    DestroyCaret(); 
	break;
    case WM_HSCROLL: 
        {
	    int	pos = data->curcfg.win_pos.X;

	    switch (LOWORD(wParam)) 
	    { 
            case SB_PAGEUP: 	pos -= 8; 		break; 
            case SB_PAGEDOWN: 	pos += 8; 		break; 
            case SB_LINEUP: 	pos--;			break;
	    case SB_LINEDOWN: 	pos++;	 		break;
            case SB_THUMBTRACK: pos = HIWORD(wParam);	break;
            default: 					break;
	    } 
	    if (pos < 0) pos = 0;
	    if (pos > data->curcfg.sb_width - data->curcfg.win_width) 
                pos = data->curcfg.sb_width - data->curcfg.win_width;
	    if (pos != data->curcfg.win_pos.X)
	    {
		ScrollWindow(hWnd, (data->curcfg.win_pos.X - pos) * data->curcfg.cell_width, 0, 
                             NULL, NULL);
		data->curcfg.win_pos.X = pos;
		SetScrollPos(hWnd, SB_HORZ, pos, TRUE); 
		UpdateWindow(hWnd); 
		WCUSER_PosCursor(data);
		WINECON_NotifyWindowChange(data);
	    }
        } 
	break;
    case WM_VSCROLL: 
        {
	    int	pos = data->curcfg.win_pos.Y;

	    switch (LOWORD(wParam)) 
	    { 
            case SB_PAGEUP: 	pos -= 8; 		break; 
            case SB_PAGEDOWN: 	pos += 8; 		break; 
            case SB_LINEUP: 	pos--;			break;
	    case SB_LINEDOWN: 	pos++;	 		break;
            case SB_THUMBTRACK: pos = HIWORD(wParam);	break;
            default: 					break;
	    } 
	    if (pos < 0) pos = 0;
	    if (pos > data->curcfg.sb_height - data->curcfg.win_height) 
                pos = data->curcfg.sb_height - data->curcfg.win_height;
	    if (pos != data->curcfg.win_pos.Y)
	    {
		ScrollWindow(hWnd, 0, (data->curcfg.win_pos.Y - pos) * data->curcfg.cell_height, 
                             NULL, NULL);
		data->curcfg.win_pos.Y = pos;
		SetScrollPos(hWnd, SB_VERT, pos, TRUE); 
		UpdateWindow(hWnd); 
		WCUSER_PosCursor(data);
		WINECON_NotifyWindowChange(data);
	    }
        } 
	break;
    case WM_SYSCOMMAND:
	switch (wParam)
	{
	case IDS_DEFAULT:
	    WCUSER_GetProperties(data, FALSE);
	    break;
	case IDS_PROPERTY:
	    WCUSER_GetProperties(data, TRUE);
	    break;
	default: 
	    return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}
	break;
    case WM_RBUTTONDOWN:
        if ((wParam & (MK_CONTROL|MK_SHIFT)) == data->curcfg.menu_mask)
        {
            RECT        r;

            GetWindowRect(hWnd, &r);
            TrackPopupMenu(PRIVATE(data)->hPopMenu, TPM_LEFTALIGN|TPM_TOPALIGN, 
                           r.left + LOWORD(lParam), r.top + HIWORD(lParam), 0, hWnd, NULL);
        }
	break;    
    case WM_COMMAND:
	switch (wParam)
	{
	case IDS_DEFAULT:
	    WCUSER_GetProperties(data, FALSE);
	    break;
	case IDS_PROPERTY:
	    WCUSER_GetProperties(data, TRUE);
	    break;
	case IDS_MARK:
	    goto niy;
	case IDS_COPY:
	    PRIVATE(data)->hasSelection = FALSE;
	    WCUSER_SetSelection(data, 0);
	    WCUSER_CopySelectionToClipboard(data);
	    break;
	case IDS_PASTE:
	    WCUSER_PasteFromClipboard(data);
	    break;
	case IDS_SELECTALL:
	    PRIVATE(data)->selectPt1.X = PRIVATE(data)->selectPt1.Y = 0;
	    PRIVATE(data)->selectPt2.X = (data->curcfg.sb_width - 1) * data->curcfg.cell_width;
	    PRIVATE(data)->selectPt2.Y = (data->curcfg.sb_height - 1) * data->curcfg.cell_height;
	    WCUSER_SetSelection(data, 0);
	    PRIVATE(data)->hasSelection = TRUE;
	    break;
	case IDS_SCROLL:
	case IDS_SEARCH:
	niy:
	    Trace(0, "unhandled yet command: %x\n", wParam);
	    break;
	default: 
	    return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}
	break;
    case WM_INITMENUPOPUP:
	if (!HIWORD(lParam))	return DefWindowProc(hWnd, uMsg, wParam, lParam);
	WCUSER_SetMenuDetails(data);
	break;
    default:
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    return 0;
}

/******************************************************************
 *		WCUSER_DeleteBackend
 *
 *
 */
void WCUSER_DeleteBackend(struct inner_data* data)
{
    if (!PRIVATE(data)) return;
    if (PRIVATE(data)->hWnd)		DestroyWindow(PRIVATE(data)->hWnd);
    if (PRIVATE(data)->hFont)		DeleteObject(PRIVATE(data)->hFont);
    if (PRIVATE(data)->cursor_bitmap)	DeleteObject(PRIVATE(data)->cursor_bitmap);
    if (PRIVATE(data)->hMemDC)		DeleteDC(PRIVATE(data)->hMemDC);
    if (PRIVATE(data)->hBitmap)		DeleteObject(PRIVATE(data)->hBitmap);
    HeapFree(GetProcessHeap(), 0, PRIVATE(data));
}

/******************************************************************
 *		WCUSER_MainLoop
 *
 *
 */
static int WCUSER_MainLoop(struct inner_data* data)
{
    MSG		msg;

    for (;;) 
    {
	switch (MsgWaitForMultipleObjects(1, &data->hSynchro, FALSE, INFINITE, QS_ALLINPUT))
	{
	case WAIT_OBJECT_0:
	    if (!WINECON_GrabChanges(data))
		PostQuitMessage(0);
	    break;
	case WAIT_OBJECT_0+1:
	    switch (GetMessage(&msg, 0, 0, 0))
	    {
	    case -1: /* the event handle became invalid, so exit */
		return -1;
	    case 0: /* WM_QUIT has been posted */
		return 0;
	    default:
		DispatchMessage(&msg);
		break;
	    }
	    break;
	default:
	    Trace(0, "got pb\n");
	    /* err */
	    break;
	}
    }	
}

/******************************************************************
 *		WCUSER_InitBackend
 *
 * Initialisation part II: creation of window.
 *
 */
BOOL WCUSER_InitBackend(struct inner_data* data)
{
    static WCHAR wClassName[] = {'W','i','n','e','C','o','n','s','o','l','e','C','l','a','s','s',0};

    WNDCLASS		wndclass;

    data->private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct inner_data_user));
    if (!data->private) return FALSE;

    data->fnMainLoop = WCUSER_MainLoop;
    data->fnPosCursor = WCUSER_PosCursor;
    data->fnShapeCursor = WCUSER_ShapeCursor;
    data->fnComputePositions = WCUSER_ComputePositions;
    data->fnRefresh = WCUSER_Refresh;
    data->fnResizeScreenBuffer = WCUSER_ResizeScreenBuffer;
    data->fnSetTitle = WCUSER_SetTitle;
    data->fnScroll = WCUSER_Scroll;
    data->fnDeleteBackend = WCUSER_DeleteBackend;

    wndclass.style         = 0;
    wndclass.lpfnWndProc   = WCUSER_Proc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = sizeof(DWORD);
    wndclass.hInstance     = GetModuleHandle(NULL);
    wndclass.hIcon         = LoadIcon(0, IDI_WINLOGO);
    wndclass.hCursor       = LoadCursor(0, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
    wndclass.lpszMenuName  = NULL;
    wndclass.lpszClassName = wClassName;
  
    RegisterClass(&wndclass);

    CreateWindow(wndclass.lpszClassName, NULL,
		 WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_HSCROLL|WS_VSCROLL, 
		 CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, 0, 0, wndclass.hInstance, data);   
    if (!PRIVATE(data)->hWnd) return FALSE;

    /* force update of current data */
    WINECON_GrabChanges(data);

    if (!WCUSER_InitFont(data))
    {
        struct font_chooser fc;
        /* try to find an acceptable font */
        fc.data = data;
        fc.done = 0;
        EnumFontFamilies(PRIVATE(data)->hMemDC, NULL, get_first_font_enum, (LPARAM)&fc);
        return fc.done;
    }
    return TRUE;
}



