New console code based on Win32 windows.

diff --git a/programs/wineconsole/dialog.c b/programs/wineconsole/dialog.c
new file mode 100644
index 0000000..04220ac
--- /dev/null
+++ b/programs/wineconsole/dialog.c
@@ -0,0 +1,515 @@
+/* dialog management for wineconsole
+ * (c) 2001 Eric Pouech
+ */
+
+#include <stdio.h>
+#include "winecon_private.h"
+#include "commctrl.h"
+#include "prsht.h"
+
+/* FIXME: so far, part of the code is made in ASCII because the Uncode property sheet functions
+ * are not implemented yet
+ */
+struct dialog_info 
+{
+    struct inner_data*	data;		/* pointer to current winecon info */
+    HWND		hDlg;		/* handle to window dialog */
+    int			nFont;		/* number of font size in size LB */
+    struct font_info 
+    {
+	TEXTMETRIC		tm;
+	LOGFONT			lf;
+    } 			*font;		/* array of nFont. index sync'ed with SIZE LB */
+};
+
+/******************************************************************
+ *		WCUSER_OptionDlgProc
+ *
+ * Dialog prop for the option property sheet
+ */
+static BOOL WINAPI WCUSER_OptionDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    struct dialog_info*		di;
+    unsigned 			idc;
+    
+    switch (msg) 
+    {
+    case WM_INITDIALOG:
+	di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam;
+	di->hDlg = hDlg;
+	SetWindowLongA(hDlg, DWL_USER, (DWORD)di);
+	if (di->data->cursor_size < 33)		idc = IDC_OPT_CURSOR_SMALL;
+	else if (di->data->cursor_size < 66)	idc = IDC_OPT_CURSOR_MEDIUM;
+	else					idc = IDC_OPT_CURSOR_LARGE;
+	SendDlgItemMessage(hDlg, idc, BM_SETCHECK, BST_CHECKED, 0L);
+	SetDlgItemInt(hDlg, IDC_OPT_HIST_SIZE, WINECON_GetHistorySize(di->data->hConIn),  FALSE);
+	if (WINECON_GetHistoryMode(di->data->hConIn))
+	    SendDlgItemMessage(hDlg, IDC_OPT_HIST_DOUBLE, BM_SETCHECK, BST_CHECKED, 0L);
+	return FALSE; /* because we set the focus */
+    case WM_COMMAND:
+	break;
+    case WM_NOTIFY:
+    {
+	NMHDR*	nmhdr = (NMHDR*)lParam;
+
+	di = (struct dialog_info*)GetWindowLongA(hDlg, DWL_USER);
+	switch (nmhdr->code) 
+	{
+	case PSN_SETACTIVE:
+	    /* needed in propsheet to keep properly the selected radio button
+	     * otherwise, the focus would be set to the first tab stop in the
+	     * propsheet, which would always activate the first radio button
+	     */
+	    if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_SMALL) == BST_CHECKED) 
+		idc = IDC_OPT_CURSOR_SMALL;
+	    else if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_MEDIUM) == BST_CHECKED)
+		idc = IDC_OPT_CURSOR_MEDIUM;
+	    else
+		idc = IDC_OPT_CURSOR_LARGE;
+	    PostMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg, idc), TRUE);
+	    break;
+	case PSN_APPLY:
+	{
+	    int		curs_size;
+	    int		hist_size;
+	    BOOL	done;
+
+	    if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_SMALL) == BST_CHECKED)	curs_size = 33;
+	    else if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_MEDIUM) == BST_CHECKED) curs_size = 66;
+	    else curs_size = 99;
+	    if (curs_size != di->data->cursor_size)
+	    {
+		CONSOLE_CURSOR_INFO cinfo;
+		cinfo.dwSize = curs_size;
+		cinfo.bVisible = di->data->cursor_visible;
+		SetConsoleCursorInfo(di->data->hConOut, &cinfo);
+	    }
+	    hist_size = GetDlgItemInt(hDlg, IDC_OPT_HIST_SIZE, &done, FALSE);
+	    if (done) WINECON_SetHistorySize(di->data->hConIn, hist_size);
+	    SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
+	    WINECON_SetHistoryMode(di->data->hConIn, 
+				   IsDlgButtonChecked(hDlg, IDC_OPT_HIST_DOUBLE) & BST_CHECKED);
+	    return TRUE;
+	}
+	default:
+	    return FALSE;
+	}
+	break;
+    }
+    default:
+	return FALSE;
+    }
+    return TRUE;
+}
+
+/******************************************************************
+ *		WCUSER_FontPreviewProc
+ *
+ * Window proc for font previewer in font property sheet
+ */
+static LRESULT WINAPI WCUSER_FontPreviewProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    switch (msg)
+    {
+    case WM_PAINT:
+    {
+	PAINTSTRUCT	ps;
+	int		font_idx;
+	int		size_idx;
+	struct dialog_info*	di;
+
+	di = (struct dialog_info*)GetWindowLong(GetParent(hWnd), DWL_USER);
+	BeginPaint(hWnd, &ps);
+	
+	font_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0L, 0L);
+	size_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
+
+	if (font_idx >= 0 && size_idx >= 0 && size_idx < di->nFont)
+	{
+	    HFONT	hFont, hOldFont;
+	    WCHAR	buf1[256];
+	    WCHAR	buf2[256];
+	    int		len1, len2;
+
+	    hFont = CreateFontIndirect(&di->font[size_idx].lf);
+	    len1 = LoadString(GetModuleHandle(NULL), IDS_FNT_PREVIEW_1, 
+			      buf1, sizeof(buf1) / sizeof(WCHAR));
+	    len2 = LoadString(GetModuleHandle(NULL), IDS_FNT_PREVIEW_2,
+			      buf2, sizeof(buf2) / sizeof(WCHAR));
+	    if (hFont && len1)
+	    {
+		hOldFont = SelectObject(ps.hdc, hFont);
+		SetBkColor(ps.hdc, RGB(0x00, 0x00, 0x00));
+		SetTextColor(ps.hdc, RGB(0xFF, 0xFF, 0xFF));
+		TextOut(ps.hdc, 0, 0, buf1, len1);
+		if (len2)
+		    TextOut(ps.hdc, 0, di->font[size_idx].tm.tmHeight, buf2, len2);
+		SelectObject(ps.hdc, hOldFont);
+		DeleteObject(hFont);
+	    }
+	}
+	EndPaint(hWnd, &ps);
+	break;
+    }
+    default:
+	return DefWindowProc(hWnd, msg, wParam, lParam);
+    }
+    return 0L;
+}
+
+/******************************************************************
+ *		font_enum
+ *
+ *
+ */
+static int CALLBACK font_enum_size2(const LOGFONT* lf, const TEXTMETRIC* tm, 
+				    DWORD FontType, LPARAM lParam)
+{
+    struct dialog_info*	di = (struct dialog_info*)lParam;
+
+    if (WCUSER_ValidateFontMetric(di->data, tm))
+    {
+	di->nFont++;
+    }
+    return 1;
+}
+
+static int CALLBACK font_enum(const LOGFONT* lf, const TEXTMETRIC* tm, 
+			      DWORD FontType, LPARAM lParam)
+{
+    struct dialog_info*	di = (struct dialog_info*)lParam;
+    HDC	hdc;
+
+    if (WCUSER_ValidateFont(di->data, lf) && (hdc = GetDC(di->hDlg)))
+    {
+	di->nFont = 0;
+	EnumFontFamilies(hdc, lf->lfFaceName, font_enum_size2, (LPARAM)di);
+	if (di->nFont)
+	{
+	    int idx;
+	    idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_ADDSTRING, 
+				     0, (LPARAM)lf->lfFaceName);
+	}
+	ReleaseDC(di->hDlg, hdc);
+    }
+    return 1;
+}
+
+/******************************************************************
+ *		font_enum_size
+ *
+ *
+ */
+static int CALLBACK font_enum_size(const LOGFONT* lf, const TEXTMETRIC* tm, 
+				   DWORD FontType, LPARAM lParam)
+{
+    struct dialog_info*	di = (struct dialog_info*)lParam;
+
+    if (WCUSER_ValidateFontMetric(di->data, tm))
+    {
+	WCHAR	buf[32];
+	WCHAR	fmt[] = {'%','l','d',0};
+	int	idx;
+
+	/* we want the string to be sorted with a numeric order, not a lexicographic...
+	 * do the job by hand... get where to insert the new string
+	 */
+	for (idx = 0; idx < di->nFont && tm->tmHeight > di->font[idx].tm.tmHeight; idx++);
+	wsprintfW(buf, fmt, tm->tmHeight);
+	SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_INSERTSTRING, idx, (LPARAM)buf);
+
+	/* now grow our arrays and insert to values at the same index than in the list box */
+	di->font = HeapReAlloc(GetProcessHeap(), 0, di->font, sizeof(*di->font) * (di->nFont + 1));
+	if (idx != di->nFont)
+	    memmove(&di->font[idx + 1], &di->font[idx], (di->nFont - idx) * sizeof(*di->font));
+	di->font[idx].tm = *tm;
+	di->font[idx].lf = *lf;
+	di->nFont++;
+
+    }
+    return 1;
+}
+
+/******************************************************************
+ *		select_font
+ *
+ *
+ */
+static BOOL  select_font(struct dialog_info* di)
+{
+    int		idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
+    WCHAR	buf[256];
+    WCHAR	fmt[128];
+
+    if (idx < 0 || idx >= di->nFont)
+	return FALSE;
+
+    LoadString(GetModuleHandle(NULL), IDS_FNT_DISPLAY, fmt, sizeof(fmt) / sizeof(WCHAR));
+    wsprintfW(buf, fmt, di->font[idx].tm.tmMaxCharWidth, di->font[idx].tm.tmHeight);
+
+    SendDlgItemMessage(di->hDlg, IDC_FNT_FONT_INFO, WM_SETTEXT, 0, (LPARAM)buf);
+    InvalidateRect(GetDlgItem(di->hDlg, IDC_FNT_PREVIEW), NULL, TRUE);
+    UpdateWindow(GetDlgItem(di->hDlg, IDC_FNT_PREVIEW));
+    return TRUE;
+}
+
+/******************************************************************
+ *		fill_list_size
+ *
+ * fills the size list box according to selected family in font LB
+ */
+static BOOL  fill_list_size(struct dialog_info* di, BOOL doInit)
+{
+    HDC 	hdc;
+    int		idx;
+    WCHAR	lfFaceName[LF_FACESIZE];
+
+    idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0L, 0L);
+    if (idx < 0) return FALSE;
+    
+    hdc = GetDC(di->hDlg);
+    if (!hdc) return FALSE;
+
+    SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETTEXT, idx, (LPARAM)lfFaceName);
+    SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_RESETCONTENT, 0L, 0L);
+    if (di->font) HeapFree(GetProcessHeap(), 0, di->font);
+    di->nFont = 0;
+    di->font = NULL;
+
+    EnumFontFamilies(hdc, lfFaceName, font_enum_size, (LPARAM)di);
+    ReleaseDC(di->hDlg, hdc);
+
+    if (doInit)
+    {
+	for (idx = 0; idx < di->nFont; idx++)
+	{
+	    if (memcmp(&di->data->logFont, &di->font[idx].lf, sizeof(LOGFONT)) == 0)
+		break;
+	}
+	if (idx == di->nFont) idx = 0;
+    }
+    else
+	idx = 0;
+    SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_SETCURSEL, idx, 0L);
+    select_font(di);
+    return TRUE;
+}
+
+/******************************************************************
+ *		fill_list_font
+ *
+ * Fills the font LB
+ */
+static BOOL fill_list_font(struct dialog_info* di)
+{
+    HDC hdc;
+
+    hdc = GetDC(di->hDlg);
+    if (!hdc) return FALSE;
+
+    SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_RESETCONTENT, 0L, 0L);
+    EnumFontFamilies(hdc, NULL, font_enum, (LPARAM)di);
+    ReleaseDC(di->hDlg, hdc);
+    if (SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_SELECTSTRING, 
+			   (WPARAM)-1, (LPARAM)di->data->logFont.lfFaceName) == LB_ERR)
+	SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_SETCURSEL, 0L, 0L);
+    fill_list_size(di, TRUE);
+    return TRUE;
+}
+
+/******************************************************************
+ *		WCUSER_FontDlgProc
+ *
+ * Dialog proc for the Font property sheet
+ */
+static BOOL WINAPI WCUSER_FontDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    struct dialog_info*		di;
+
+    switch (msg) 
+    {
+    case WM_INITDIALOG:
+	di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam;
+	di->hDlg = hDlg;
+	SetWindowLong(hDlg, DWL_USER, (DWORD)di);
+	fill_list_font(di);
+	break;
+    case WM_COMMAND:
+	di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER);
+	switch (LOWORD(wParam)) 
+	{
+	case IDC_FNT_LIST_FONT:	
+	    if (HIWORD(wParam) == LBN_SELCHANGE)
+	    {
+		fill_list_size(di, FALSE);
+	    }
+	    break;
+	case IDC_FNT_LIST_SIZE:	
+	    if (HIWORD(wParam) == LBN_SELCHANGE)
+	    {
+		select_font(di);
+	    }
+	    break;
+	}
+	break;
+    case WM_NOTIFY:
+    {
+	NMHDR*	nmhdr = (NMHDR*)lParam;
+
+	di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER);
+	switch (nmhdr->code) 
+	{
+	case PSN_APPLY:
+	{
+	    int idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
+
+	    if (idx >= 0 && idx < di->nFont)
+	    {
+		WCUSER_SetFont(di->data, &di->font[idx].lf, &di->font[idx].tm);
+	    }
+	    SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
+	    return TRUE;
+	}
+	default:
+	    return FALSE;
+	}
+	break;
+    }
+    default:
+	return FALSE;
+    }
+    return TRUE;
+}
+
+/******************************************************************
+ *		WCUSER_ConfigDlgProc
+ *
+ * Dialog proc for the config property sheet
+ */
+static BOOL WINAPI WCUSER_ConfigDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    struct dialog_info*		di;
+
+    switch (msg) 
+    {
+    case WM_INITDIALOG:
+	di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam;
+	di->hDlg = hDlg;
+	SetWindowLong(hDlg, DWL_USER, (DWORD)di);
+	SetDlgItemInt(hDlg, IDC_CNF_SB_WIDTH,   di->data->sb_width,   FALSE);
+	SetDlgItemInt(hDlg, IDC_CNF_SB_HEIGHT,  di->data->sb_height,  FALSE);
+	SetDlgItemInt(hDlg, IDC_CNF_WIN_WIDTH,  di->data->win_width,  FALSE);
+	SetDlgItemInt(hDlg, IDC_CNF_WIN_HEIGHT, di->data->win_height, FALSE);
+	break;
+    case WM_COMMAND:
+	di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER);
+	switch (LOWORD(wParam)) 
+	{
+	}
+	break;
+    case WM_NOTIFY:
+    {
+	NMHDR*	nmhdr = (NMHDR*)lParam;
+
+	di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER);
+	switch (nmhdr->code) 
+	{
+	case PSN_APPLY:
+	{
+	    COORD	sb;
+	    SMALL_RECT	pos;
+	    BOOL	st_w, st_h;
+
+	    sb.X = GetDlgItemInt(hDlg, IDC_CNF_SB_WIDTH,  &st_w, FALSE);
+	    sb.Y = GetDlgItemInt(hDlg, IDC_CNF_SB_HEIGHT, &st_h, FALSE);
+	    if (st_w && st_h && (sb.X != di->data->sb_width || sb.Y != di->data->sb_height))
+	    {
+		SetConsoleScreenBufferSize(di->data->hConOut, sb);
+	    }
+
+	    pos.Right  = GetDlgItemInt(hDlg, IDC_CNF_WIN_WIDTH,  &st_w, FALSE);
+	    pos.Bottom = GetDlgItemInt(hDlg, IDC_CNF_WIN_HEIGHT, &st_h, FALSE);
+	    if (st_w && st_h && 
+		(pos.Right != di->data->win_width || pos.Bottom != di->data->win_height))
+	    {
+		pos.Left = pos.Top = 0;
+		pos.Right--; pos.Bottom--;
+		SetConsoleWindowInfo(di->data->hConOut, FALSE, &pos);
+	    }
+
+	    SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
+	    return TRUE;
+	}
+	default:
+	    return FALSE;
+	}
+	break;
+    }
+    default:
+	return FALSE;
+    }
+    return TRUE;
+}
+
+/******************************************************************
+ *		WCUSER_GetProperties
+ *
+ * Runs the dialog box to set up the winconsole options
+ */
+BOOL WCUSER_GetProperties(struct inner_data* data)
+{
+    HPROPSHEETPAGE	psPage[3];
+    PROPSHEETPAGEA	psp;
+    PROPSHEETHEADERA	psHead;
+    WNDCLASS		wndclass;
+    static WCHAR	szFntPreview[] = {'W','i','n','e','C','o','n','F','o','n','t','P','r','e','v','i','e','w',0};
+    struct dialog_info	di;
+
+    InitCommonControls();
+
+    di.data = data;
+    di.nFont = 0;
+    di.font = NULL;
+
+    wndclass.style         = 0;
+    wndclass.lpfnWndProc   = WCUSER_FontPreviewProc;
+    wndclass.cbClsExtra    = 0;
+    wndclass.cbWndExtra    = 0;
+    wndclass.hInstance     = GetModuleHandle(NULL);
+    wndclass.hIcon         = 0;
+    wndclass.hCursor       = LoadCursor(0, IDC_ARROW);
+    wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
+    wndclass.lpszMenuName  = NULL;
+    wndclass.lpszClassName = szFntPreview;
+    RegisterClass(&wndclass);
+
+    memset(&psp, 0, sizeof(psp));
+    psp.dwSize = sizeof(psp);
+    psp.dwFlags = 0;
+    psp.hInstance = wndclass.hInstance;
+    psp.lParam = (LPARAM)&di;
+
+    psp.u.pszTemplate = MAKEINTRESOURCEA(IDD_OPTION);
+    psp.pfnDlgProc = WCUSER_OptionDlgProc;
+    psPage[0] = CreatePropertySheetPageA(&psp);
+
+    psp.u.pszTemplate = MAKEINTRESOURCEA(IDD_FONT);
+    psp.pfnDlgProc = WCUSER_FontDlgProc;
+    psPage[1] = CreatePropertySheetPageA(&psp);
+
+    psp.u.pszTemplate = MAKEINTRESOURCEA(IDD_CONFIG);
+    psp.pfnDlgProc = WCUSER_ConfigDlgProc;
+    psPage[2] = CreatePropertySheetPageA(&psp);
+
+    memset(&psHead, 0, sizeof(psHead));
+    psHead.dwSize = sizeof(psHead);
+    psHead.pszCaption = "Setup";
+    psHead.nPages = 3;
+    psHead.hwndParent = data->hWnd;
+    psHead.u3.phpage = psPage;
+ 
+    PropertySheetA(&psHead);
+
+    return TRUE;
+}
+