- allow to save/restore some properties into the registry (like font,
  cursor size...)
- implement the two sets of properties (default & current)
- fixed some bugs mainly in dialog
- enhanced font selection mechanisms,
- added and protected sub-menu for all operations (sysmenu is not
  avail in managed mode)
- better data separation for the backend(s)

diff --git a/programs/wineconsole/Makefile.in b/programs/wineconsole/Makefile.in
index 5149214..99a2d70 100644
--- a/programs/wineconsole/Makefile.in
+++ b/programs/wineconsole/Makefile.in
@@ -7,8 +7,9 @@
 
 C_SRCS = \
 	dialog.c \
+	registry.c \
 	user.c \
-        wineconsole.c
+	wineconsole.c
 
 RC_SRCS = \
         wineconsole_res.rc
diff --git a/programs/wineconsole/dialog.c b/programs/wineconsole/dialog.c
index 04220ac..4861254 100644
--- a/programs/wineconsole/dialog.c
+++ b/programs/wineconsole/dialog.c
@@ -1,28 +1,117 @@
 /* dialog management for wineconsole
+ * USER32 backend
  * (c) 2001 Eric Pouech
  */
 
 #include <stdio.h>
-#include "winecon_private.h"
 #include "commctrl.h"
 #include "prsht.h"
+#include "winecon_user.h"
 
 /* FIXME: so far, part of the code is made in ASCII because the Uncode property sheet functions
  * are not implemented yet
  */
+
+enum WCUSER_ApplyTo {
+    /* Prop sheet CFG */
+    WCUSER_ApplyToCursorSize, 
+    WCUSER_ApplyToHistorySize, WCUSER_ApplyToHistoryMode, WCUSER_ApplyToMenuMask,
+    /* Prop sheet FNT */
+    WCUSER_ApplyToFont, WCUSER_ApplyToAttribute,
+    /* Prop sheep CNF */
+    WCUSER_ApplyToBufferSize, WCUSER_ApplyToWindow
+};
+
 struct dialog_info 
 {
-    struct inner_data*	data;		/* pointer to current winecon info */
-    HWND		hDlg;		/* handle to window dialog */
+    struct config_data* config;         /* pointer to configuration used for dialog box */
+    struct inner_data*	data;	        /* pointer to current winecon info */
+    HWND		hDlg;		/* handle to active propsheet */
     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 */
+    void        (*apply)(struct dialog_info*, HWND, enum WCUSER_ApplyTo, DWORD);
 };
 
 /******************************************************************
+ *		WCUSER_ApplyDefault
+ *
+ *
+ */
+static void WCUSER_ApplyDefault(struct dialog_info* di, HWND hDlg, enum WCUSER_ApplyTo apply, DWORD val)
+{
+    switch (apply)
+    {
+    case WCUSER_ApplyToCursorSize:
+    case WCUSER_ApplyToHistorySize:
+    case WCUSER_ApplyToHistoryMode:
+    case WCUSER_ApplyToBufferSize:
+    case WCUSER_ApplyToWindow:
+        /* not saving those for now... */
+        break;
+    case WCUSER_ApplyToMenuMask:
+        di->config->menu_mask = val;
+        break;
+    case WCUSER_ApplyToFont:
+        WCUSER_CopyFont(di->config, &di->font[val].lf);
+        break;
+    case WCUSER_ApplyToAttribute:
+        di->config->def_attr = val;
+        break;
+    }
+    WINECON_RegSave(di->config);
+}
+
+/******************************************************************
+ *		WCUSER_ApplyCurrent
+ *
+ *
+ */
+static void WCUSER_ApplyCurrent(struct dialog_info* di, HWND hDlg, enum WCUSER_ApplyTo apply, DWORD val)
+{
+    switch (apply)
+    {
+    case WCUSER_ApplyToCursorSize:
+        {
+            CONSOLE_CURSOR_INFO cinfo;
+            cinfo.dwSize = val;
+            cinfo.bVisible = di->config->cursor_visible;
+            /* this shall update (through notif) curcfg */
+            SetConsoleCursorInfo(di->data->hConOut, &cinfo);
+        }
+        break;
+    case WCUSER_ApplyToHistorySize:
+        di->config->history_size = val;
+        WINECON_SetHistorySize(di->data->hConIn, val);
+        break;
+    case WCUSER_ApplyToHistoryMode:
+        WINECON_SetHistoryMode(di->data->hConIn, val);
+        break;
+    case WCUSER_ApplyToMenuMask:
+        di->config->menu_mask = val;
+        break;
+    case WCUSER_ApplyToFont:
+        WCUSER_SetFont(di->data, &di->font[val].lf);
+        break;
+    case WCUSER_ApplyToAttribute:
+        di->config->def_attr = val;
+        SetConsoleTextAttribute(di->data->hConOut, val);
+        break;
+    case WCUSER_ApplyToBufferSize:
+        /* this shall update (through notif) curcfg */
+        SetConsoleScreenBufferSize(di->data->hConOut, *(COORD*)val);
+        break;
+    case WCUSER_ApplyToWindow:
+        /* this shall update (through notif) curcfg */
+        SetConsoleWindowInfo(di->data->hConOut, FALSE, (SMALL_RECT*)val);
+        break;
+    }
+}
+
+/******************************************************************
  *		WCUSER_OptionDlgProc
  *
  * Dialog prop for the option property sheet
@@ -38,19 +127,25 @@
 	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;
+	if (di->config->cursor_size <= 25)	idc = IDC_OPT_CURSOR_SMALL;
+	else if (di->config->cursor_size <= 50)	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);
+        SendDlgItemMessage(hDlg, IDC_OPT_CONF_CTRL, BM_SETCHECK, 
+                           (di->config->menu_mask & MK_CONTROL) ? BST_CHECKED : BST_UNCHECKED, 0L);
+        SendDlgItemMessage(hDlg, IDC_OPT_CONF_SHIFT, BM_SETCHECK, 
+                           (di->config->menu_mask & MK_SHIFT) ? BST_CHECKED : BST_UNCHECKED, 0L);
 	return FALSE; /* because we set the focus */
     case WM_COMMAND:
 	break;
     case WM_NOTIFY:
     {
 	NMHDR*	nmhdr = (NMHDR*)lParam;
+        DWORD   val;
+        BOOL	done;
 
 	di = (struct dialog_info*)GetWindowLongA(hDlg, DWL_USER);
 	switch (nmhdr->code) 
@@ -67,30 +162,26 @@
 	    else
 		idc = IDC_OPT_CURSOR_LARGE;
 	    PostMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg, idc), TRUE);
+            di->hDlg = hDlg;
 	    break;
 	case PSN_APPLY:
-	{
-	    int		curs_size;
-	    int		hist_size;
-	    BOOL	done;
+	    if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_SMALL) == BST_CHECKED) val = 25;
+	    else if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_MEDIUM) == BST_CHECKED) val = 50;
+	    else val = 99;
+            (di->apply)(di, hDlg, WCUSER_ApplyToCursorSize, val);
 
-	    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);
+ 	    val = GetDlgItemInt(hDlg, IDC_OPT_HIST_SIZE, &done, FALSE);
+	    if (done) (di->apply)(di, hDlg, WCUSER_ApplyToHistorySize, val);
+
+	    (di->apply)(di, hDlg, WCUSER_ApplyToHistoryMode, 
+                        IsDlgButtonChecked(hDlg, IDC_OPT_HIST_DOUBLE) & BST_CHECKED);
+
+            val = 0;
+            if (IsDlgButtonChecked(hDlg, IDC_OPT_CONF_CTRL) & BST_CHECKED)  val |= MK_CONTROL;
+            if (IsDlgButtonChecked(hDlg, IDC_OPT_CONF_SHIFT) & BST_CHECKED) val |= MK_SHIFT;
+            (di->apply)(di, hDlg, WCUSER_ApplyToMenuMask, val);
+            SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
 	    return TRUE;
-	}
 	default:
 	    return FALSE;
 	}
@@ -112,45 +203,121 @@
     switch (msg)
     {
     case WM_PAINT:
-    {
-	PAINTSTRUCT	ps;
-	int		font_idx;
-	int		size_idx;
-	struct dialog_info*	di;
+        {
+            PAINTSTRUCT	        ps;
+            int		        font_idx;
+            int		        size_idx;
+            struct dialog_info*	di;
+            
+            di = (struct dialog_info*)GetWindowLong(GetParent(hWnd), DWL_USER);
+            BeginPaint(hWnd, &ps);
 
-	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;
+            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));
+                buf1[len1] = buf2[len2] = 0;
+                if (hFont && len1)
+                {
+                    hOldFont = SelectObject(ps.hdc, hFont);
+                    SetBkColor(ps.hdc, WCUSER_ColorMap[GetWindowLong(GetDlgItem(di->hDlg, IDC_FNT_COLOR_BK), 0)]);
+                    SetTextColor(ps.hdc, WCUSER_ColorMap[GetWindowLong(GetDlgItem(di->hDlg, IDC_FNT_COLOR_FG), 0)]);
+                    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;
+}
+
+/******************************************************************
+ *		WCUSER_ColorPreviewProc
+ *
+ * Window proc for color previewer in font property sheet
+ */
+static LRESULT WINAPI WCUSER_ColorPreviewProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    switch (msg)
+    {
+    case WM_PAINT:
+        {
+            PAINTSTRUCT     ps;
+            int             i, step;
+            RECT            client, r;
+            HBRUSH          hbr;
+            
+            BeginPaint(hWnd, &ps);
+            GetClientRect(hWnd, &client);
+            step = client.right / 8;
+            
+            for (i = 0; i < 16; i++)
+            {
+                r.top = (i / 8) * (client.bottom / 2);
+                r.bottom = r.top + client.bottom / 2;
+                r.left = (i & 7) * step;
+                r.right = r.left + step;
+                hbr = CreateSolidBrush(WCUSER_ColorMap[i]);
+                FillRect(ps.hdc, &r, hbr);
+                DeleteObject(hbr);
+                if (GetWindowLong(hWnd, 0) == i)
+                {
+                    HPEN        hOldPen;
+                    int         i = 2;
+
+                    hOldPen = SelectObject(ps.hdc, GetStockObject(WHITE_PEN));
+                    r.right--; r.bottom--;
+                    for (;;)
+                    {
+                        MoveToEx(ps.hdc, r.left, r.bottom, NULL);
+                        LineTo(ps.hdc, r.left, r.top);
+                        LineTo(ps.hdc, r.right, r.top);
+                        SelectObject(ps.hdc, GetStockObject(BLACK_PEN));
+                        LineTo(ps.hdc, r.right, r.bottom);
+                        LineTo(ps.hdc, r.left, r.bottom);
+
+                        if (--i == 0) break;
+                        r.left++; r.top++; r.right--; r.bottom--;
+                        SelectObject(ps.hdc, GetStockObject(WHITE_PEN));
+                    }
+                    SelectObject(ps.hdc, hOldPen);
+                }
+            }
+            EndPaint(hWnd, &ps);
+            break;
+        }
+    case WM_LBUTTONDOWN:
+        {
+            int             i, step;
+            RECT            client;
+            
+            GetClientRect(hWnd, &client);
+            step = client.right / 8;
+            i = (HIWORD(lParam) >= client.bottom / 2) ? 8 : 0;
+            i += LOWORD(lParam) / step;
+            SetWindowLong(hWnd, 0, i);
+            InvalidateRect(GetDlgItem(GetParent(hWnd), IDC_FNT_PREVIEW), NULL, FALSE);
+            InvalidateRect(hWnd, NULL, FALSE);
+        }
+        break;
     default:
 	return DefWindowProc(hWnd, msg, wParam, lParam);
     }
@@ -160,7 +327,7 @@
 /******************************************************************
  *		font_enum
  *
- *
+ * enumerates all the font names with at least one valid font
  */
 static int CALLBACK font_enum_size2(const LOGFONT* lf, const TEXTMETRIC* tm, 
 				    DWORD FontType, LPARAM lParam)
@@ -208,24 +375,44 @@
     if (WCUSER_ValidateFontMetric(di->data, tm))
     {
 	WCHAR	buf[32];
-	WCHAR	fmt[] = {'%','l','d',0};
+        static const 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);
+        if (idx < di->nFont &&
+            tm->tmHeight == di->font[idx].tm.tmHeight && 
+            tm->tmMaxCharWidth == di->font[idx].tm.tmMaxCharWidth)
+        {
+            /* we already have an entry with the same width & height...
+             * try to see which TEXTMETRIC (old or new) we should keep... 
+             */
+            if (di->font[idx].tm.tmWeight != tm->tmWeight)
+            {
+                /* get the weight closer to 400, the default value */
+                if (abs(tm->tmWeight - 400) < abs(di->font[idx].tm.tmWeight - 400))
+                {
+                    di->font[idx].tm = *tm;
+                }
+            }
+            /* else FIXME: skip the new tm for now */
+        }
+        else
+        {
+            /* here we need to add the new entry */
+            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++;
-
+            /* 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;
 }
@@ -283,7 +470,7 @@
     {
 	for (idx = 0; idx < di->nFont; idx++)
 	{
-	    if (memcmp(&di->data->logFont, &di->font[idx].lf, sizeof(LOGFONT)) == 0)
+	    if (WCUSER_AreFontsEqual(di->config, &di->font[idx].lf))
 		break;
 	}
 	if (idx == di->nFont) idx = 0;
@@ -311,7 +498,7 @@
     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)
+			   (WPARAM)-1, (LPARAM)di->config->face_name) == LB_ERR)
 	SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_SETCURSEL, 0L, 0L);
     fill_list_size(di, TRUE);
     return TRUE;
@@ -333,6 +520,8 @@
 	di->hDlg = hDlg;
 	SetWindowLong(hDlg, DWL_USER, (DWORD)di);
 	fill_list_font(di);
+        SetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_BK), 0, di->config->def_attr & 0x0F);
+        SetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_FG), 0, (di->config->def_attr >> 4) & 0x0F);
 	break;
     case WM_COMMAND:
 	di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER);
@@ -355,21 +544,25 @@
     case WM_NOTIFY:
     {
 	NMHDR*	nmhdr = (NMHDR*)lParam;
+        DWORD   val;
 
 	di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER);
 	switch (nmhdr->code) 
 	{
+        case PSN_SETACTIVE:
+            di->hDlg = hDlg;
+            break;
 	case PSN_APPLY:
-	{
-	    int idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
+ 	    val = SendDlgItemMessage(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);
+	    if (val < di->nFont) (di->apply)(di, hDlg, WCUSER_ApplyToFont, val);
+
+            (di->apply)(di, hDlg, WCUSER_ApplyToAttribute, 
+                        GetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_BK), 0) | 
+                        (GetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_FG), 0) << 4));
+
+            SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
 	    return TRUE;
-	}
 	default:
 	    return FALSE;
 	}
@@ -396,10 +589,10 @@
 	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);
+	SetDlgItemInt(hDlg, IDC_CNF_SB_WIDTH,   di->config->sb_width,   FALSE);
+	SetDlgItemInt(hDlg, IDC_CNF_SB_HEIGHT,  di->config->sb_height,  FALSE);
+	SetDlgItemInt(hDlg, IDC_CNF_WIN_WIDTH,  di->config->win_width,  FALSE);
+	SetDlgItemInt(hDlg, IDC_CNF_WIN_HEIGHT, di->config->win_height, FALSE);
 	break;
     case WM_COMMAND:
 	di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER);
@@ -409,37 +602,36 @@
 	break;
     case WM_NOTIFY:
     {
-	NMHDR*	nmhdr = (NMHDR*)lParam;
+	NMHDR*	        nmhdr = (NMHDR*)lParam;
+        COORD           sb;
+        SMALL_RECT	pos;
+        BOOL	        st_w, st_h;
 
 	di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER);
 	switch (nmhdr->code) 
 	{
+        case PSN_SETACTIVE:
+            di->hDlg = hDlg;
+            break;
 	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);
+            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->config->sb_width || sb.Y != di->config->sb_height))
+            {
+                (di->apply)(di, hDlg, WCUSER_ApplyToBufferSize, (DWORD)&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->config->win_width || pos.Bottom != di->config->win_height))
+            {
+                pos.Left = pos.Top = 0;
+                pos.Right--; pos.Bottom--;
+                (di->apply)(di, hDlg, WCUSER_ApplyToWindow, (DWORD)&pos);
+            }
+            SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
 	    return TRUE;
-	}
 	default:
 	    return FALSE;
 	}
@@ -456,18 +648,30 @@
  *
  * Runs the dialog box to set up the winconsole options
  */
-BOOL WCUSER_GetProperties(struct inner_data* data)
+BOOL WCUSER_GetProperties(struct inner_data* data, BOOL current)
 {
     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};
+    static const WCHAR szFntPreview[] = {'W','i','n','e','C','o','n','F','o','n','t','P','r','e','v','i','e','w',0};
+    static const WCHAR szColorPreview[] = {'W','i','n','e','C','o','n','C','o','l','o','r','P','r','e','v','i','e','w',0};
     struct dialog_info	di;
+    CHAR		buff[256];
 
     InitCommonControls();
 
     di.data = data;
+    if (current)
+    {
+        di.config = &data->curcfg;
+        di.apply = WCUSER_ApplyCurrent;
+    }
+    else
+    {
+        di.config = &data->defcfg;
+        di.apply = WCUSER_ApplyDefault;
+    }
     di.nFont = 0;
     di.font = NULL;
 
@@ -483,6 +687,18 @@
     wndclass.lpszClassName = szFntPreview;
     RegisterClass(&wndclass);
 
+    wndclass.style         = 0;
+    wndclass.lpfnWndProc   = WCUSER_ColorPreviewProc;
+    wndclass.cbClsExtra    = 0;
+    wndclass.cbWndExtra    = sizeof(DWORD);
+    wndclass.hInstance     = GetModuleHandle(NULL);
+    wndclass.hIcon         = 0;
+    wndclass.hCursor       = LoadCursor(0, IDC_ARROW);
+    wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
+    wndclass.lpszMenuName  = NULL;
+    wndclass.lpszClassName = szColorPreview;
+    RegisterClass(&wndclass);
+
     memset(&psp, 0, sizeof(psp));
     psp.dwSize = sizeof(psp);
     psp.dwFlags = 0;
@@ -503,9 +719,14 @@
 
     memset(&psHead, 0, sizeof(psHead));
     psHead.dwSize = sizeof(psHead);
-    psHead.pszCaption = "Setup";
+
+    if (!LoadStringA(GetModuleHandle(NULL), 
+                     (current) ? IDS_DLG_TIT_CURRENT : IDS_DLG_TIT_DEFAULT, 
+                     buff, sizeof(buff)))
+        strcpy(buff, "Setup");
+    psHead.pszCaption = buff;
     psHead.nPages = 3;
-    psHead.hwndParent = data->hWnd;
+    psHead.hwndParent = PRIVATE(data)->hWnd;
     psHead.u3.phpage = psPage;
  
     PropertySheetA(&psHead);
@@ -513,3 +734,4 @@
     return TRUE;
 }
 
+
diff --git a/programs/wineconsole/registry.c b/programs/wineconsole/registry.c
new file mode 100644
index 0000000..3dc7333
--- /dev/null
+++ b/programs/wineconsole/registry.c
@@ -0,0 +1,143 @@
+/*
+ * an application for displaying Win32 console
+ *      registry and init functions
+ *
+ * Copyright 2001 Eric Pouech
+ */
+
+#include "winbase.h"
+#include "winreg.h"
+#include "winecon_private.h"
+
+static const WCHAR wszConsole[]           = {'C','o','n','s','o','l','e',0};
+static const WCHAR wszCursorSize[]        = {'C','u','r','s','o','r','S','i','z','e',0};
+static const WCHAR wszCursorVisible[]     = {'C','u','r','s','o','r','V','i','s','i','b','l','e',0};
+static const WCHAR wszFaceName[]          = {'F','a','c','e','N','a','m','e',0};
+static const WCHAR wszFontSize[]          = {'F','o','n','t','S','i','z','e',0};
+static const WCHAR wszFontWeight[]        = {'F','o','n','t','W','e','i','g','h','t',0};
+static const WCHAR wszHistoryBufferSize[] = {'H','i','s','t','o','r','y','B','u','f','f','e','r','S','i','z','e',0};
+static const WCHAR wszMenuMask[]          = {'M','e','n','u','M','a','s','k',0};
+static const WCHAR wszScreenBufferSize[]  = {'S','c','r','e','e','n','B','u','f','f','e','r','S','i','z','e',0};
+static const WCHAR wszScreenColors[]      = {'S','c','r','e','e','n','C','o','l','o','r','s',0};
+static const WCHAR wszWindowSize[]        = {'W','i','n','d','o','w','S','i','z','e',0};
+
+/******************************************************************
+ *		WINECON_RegLoad
+ *
+ *
+ */
+BOOL WINECON_RegLoad(struct config_data* cfg)
+{
+    HKEY        hConKey;
+    DWORD 	type;
+    DWORD 	count;
+    DWORD       val;
+
+    if (RegOpenKey(HKEY_CURRENT_USER, wszConsole, &hConKey)) hConKey = 0;
+
+    count = sizeof(val);
+    if (!hConKey || RegQueryValueEx(hConKey, wszCursorSize, 0, &type, (char*)&val, &count)) 
+        val = 25;
+    cfg->cursor_size = val;
+
+    count = sizeof(val);
+    if (!hConKey || RegQueryValueEx(hConKey, wszCursorVisible, 0, &type, (char*)&val, &count)) 
+        val = 1;
+    cfg->cursor_visible = val;
+
+    count = sizeof(cfg->face_name); 
+    if (!hConKey || RegQueryValueEx(hConKey, wszFaceName, 0, &type, (char*)&cfg->face_name, &count))
+        cfg->face_name[0] = 0;
+
+    count = sizeof(val);
+    if (!hConKey || RegQueryValueEx(hConKey, wszFontSize, 0, &type, (char*)&val, &count)) 
+        val = 0x000C0008;
+    cfg->cell_height = HIWORD(val);
+    cfg->cell_width  = LOWORD(val);
+
+    count = sizeof(val);
+    if (!hConKey || RegQueryValueEx(hConKey, wszFontWeight, 0, &type, (char*)&val, &count)) 
+        val = 0;
+    cfg->font_weight = val;
+
+    count = sizeof(val);
+    if (!hConKey || RegQueryValueEx(hConKey, wszHistoryBufferSize, 0, &type, (char*)&val, &count)) 
+        val = 0;
+    cfg->history_size = val;
+
+    count = sizeof(val);
+    if (!hConKey || RegQueryValueEx(hConKey, wszMenuMask, 0, &type, (char*)&val, &count)) 
+        val = 0;
+    cfg->menu_mask = val;
+
+    count = sizeof(val);
+    if (!hConKey || RegQueryValueEx(hConKey, wszScreenBufferSize, 0, &type, (char*)&val, &count)) 
+        val = 0x000C0008;
+    cfg->sb_height = HIWORD(val);
+    cfg->sb_width  = LOWORD(val);
+
+    count = sizeof(val);
+    if (!hConKey || RegQueryValueEx(hConKey, wszScreenColors, 0, &type, (char*)&val, &count)) 
+        val = 0x0007;
+    cfg->def_attr = val;
+
+    count = sizeof(val);
+    if (!hConKey || RegQueryValueEx(hConKey, wszWindowSize, 0, &type, (char*)&val, &count)) 
+        val = 0x000C0008;
+    cfg->win_height = HIWORD(val);
+    cfg->win_width  = LOWORD(val);
+
+    /* win_pos isn't read from registry */
+
+    if (hConKey) RegCloseKey(hConKey);
+    return TRUE;
+}
+
+/******************************************************************
+ *		WINECON_RegSave
+ *
+ *
+ */
+BOOL WINECON_RegSave(const struct config_data* cfg)
+{
+    HKEY        hConKey;
+    DWORD       val;
+
+    if (RegCreateKey(HKEY_CURRENT_USER, wszConsole, &hConKey)) 
+    {
+        Trace(0, "Can't open registry for saving\n");
+        return FALSE;
+    }
+   
+    val = cfg->cursor_size;
+    RegSetValueEx(hConKey, wszCursorSize, 0, REG_DWORD, (char*)&val, sizeof(val));
+
+    val = cfg->cursor_visible;
+    RegSetValueEx(hConKey, wszCursorVisible, 0, REG_DWORD, (char*)&val, sizeof(val));
+
+    RegSetValueEx(hConKey, wszFaceName, 0, REG_SZ, (char*)&cfg->face_name, sizeof(cfg->face_name));
+
+    val = MAKELONG(cfg->cell_width, cfg->cell_height);
+    RegSetValueEx(hConKey, wszFontSize, 0, REG_DWORD, (char*)&val, sizeof(val));
+
+    val = cfg->font_weight;
+    RegSetValueEx(hConKey, wszFontWeight, 0, REG_DWORD, (char*)&val, sizeof(val));
+
+    val = cfg->history_size;
+    RegSetValueEx(hConKey, wszHistoryBufferSize, 0, REG_DWORD, (char*)&val, sizeof(val));
+
+    val = cfg->menu_mask;
+    RegSetValueEx(hConKey, wszMenuMask, 0, REG_DWORD, (char*)&val, sizeof(val));
+
+    val = MAKELONG(cfg->sb_width, cfg->sb_height);
+    RegSetValueEx(hConKey, wszScreenBufferSize, 0, REG_DWORD, (char*)&val, sizeof(val));
+
+    val = cfg->def_attr;
+    RegSetValueEx(hConKey, wszScreenColors, 0, REG_DWORD, (char*)&val, sizeof(val));
+
+    val = MAKELONG(cfg->win_width, cfg->win_height);
+    RegSetValueEx(hConKey, wszWindowSize, 0, REG_DWORD, (char*)&val, sizeof(val));
+
+    RegCloseKey(hConKey);
+    return TRUE;
+}
diff --git a/programs/wineconsole/user.c b/programs/wineconsole/user.c
index 2d25c66..5c96e26 100644
--- a/programs/wineconsole/user.c
+++ b/programs/wineconsole/user.c
@@ -5,14 +5,14 @@
  */
 
 #include <stdio.h>
-#include "winecon_private.h"
+#include "winecon_user.h"
 
 /* mapping console colors to RGB values */
-static	COLORREF	color_map[16] = 
+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(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xFF), RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0xFF),
+    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),
 };
 
@@ -29,28 +29,28 @@
     WORD		attr;
     WCHAR*		line;
 
-    if (!(line = HeapAlloc(GetProcessHeap(), 0, data->sb_width * sizeof(WCHAR))))
+    if (!(line = HeapAlloc(GetProcessHeap(), 0, data->curcfg.sb_width * sizeof(WCHAR))))
     {Trace(0, "OOM\n"); return;}
 
-    hOldFont = SelectObject(data->hMemDC, data->hFont);
+    hOldFont = SelectObject(PRIVATE(data)->hMemDC, PRIVATE(data)->hFont);
     for (j = upd_tp; j <= upd_bm; j++)
     {
-	cell = &data->cells[j * data->sb_width];
-	for (i = 0; i < data->win_width; i++)
+	cell = &data->cells[j * data->curcfg.sb_width];
+	for (i = 0; i < data->curcfg.win_width; i++)
 	{
 	    attr = cell[i].Attributes;
-	    SetBkColor(data->hMemDC, color_map[attr & 0x0F]);
-	    SetTextColor(data->hMemDC, color_map[(attr >> 4) & 0x0F]);
-	    for (k = i; k < data->win_width && cell[k].Attributes == attr; k++)
+	    SetBkColor(PRIVATE(data)->hMemDC, WCUSER_ColorMap[attr & 0x0F]);
+	    SetTextColor(PRIVATE(data)->hMemDC, WCUSER_ColorMap[(attr >> 4) & 0x0F]);
+	    for (k = i; k < data->curcfg.win_width && cell[k].Attributes == attr; k++)
 	    {
 		line[k - i] = cell[k].Char.UnicodeChar;
 	    }
-	    TextOut(data->hMemDC, i * data->cell_width, j * data->cell_height, 
+	    TextOut(PRIVATE(data)->hMemDC, i * data->curcfg.cell_width, j * data->curcfg.cell_height, 
 		    line, k - i);
 	    i = k - 1;
 	}
     }
-    SelectObject(data->hMemDC, hOldFont);
+    SelectObject(PRIVATE(data)->hMemDC, hOldFont);
     HeapFree(GetProcessHeap(), 0, line);
 }
 
@@ -62,25 +62,27 @@
  */
 static void WCUSER_NewBitmap(struct inner_data* data, BOOL fill)
 {
+    HDC         hDC;
     HBITMAP	hnew, hold;
 
-    if (!data->sb_width || !data->sb_height)
-	return;
-    hnew = CreateCompatibleBitmap(data->hMemDC, 
-				  data->sb_width  * data->cell_width, 
-				  data->sb_height * data->cell_height);
-    hold = SelectObject(data->hMemDC, hnew);
+    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 (data->hBitmap)
+    if (PRIVATE(data)->hBitmap)
     {
-	if (hold == data->hBitmap)
-	    DeleteObject(data->hBitmap);
+	if (hold == PRIVATE(data)->hBitmap)
+	    DeleteObject(PRIVATE(data)->hBitmap);
 	else
 	    Trace(0, "leak\n");
     }
-    data->hBitmap = hnew;
+    PRIVATE(data)->hBitmap = hnew;
     if (fill)
-	WCUSER_FillMemDC(data, 0, data->sb_height - 1);
+	WCUSER_FillMemDC(data, 0, data->curcfg.sb_height - 1);
 }
 
 /******************************************************************
@@ -100,11 +102,11 @@
  */
 static void	WCUSER_PosCursor(const struct inner_data* data)
 {
-    if (data->hWnd != GetFocus() || !data->cursor_visible) return;
+    if (PRIVATE(data)->hWnd != GetFocus() || !data->curcfg.cursor_visible) return;
 
-    SetCaretPos((data->cursor.X - data->win_pos.X) * data->cell_width, 
-		(data->cursor.Y - data->win_pos.Y) * data->cell_height);
-    ShowCaret(data->hWnd); 
+    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); 
 }
 
 /******************************************************************
@@ -114,44 +116,46 @@
  */
 void	WCUSER_ShapeCursor(struct inner_data* data, int size, int vis, BOOL force)
 {
-    if (force || size != data->cursor_size)
+    if (force || size != data->curcfg.cursor_size)
     {
-	if (data->cursor_visible && data->hWnd == GetFocus()) DestroyCaret();
-	if (data->cursor_bitmap) DeleteObject(data->cursor_bitmap);
-	data->cursor_bitmap = (HBITMAP)0;
+	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->cell_width + 15) & ~15) / 8;
-	    ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, w16b * data->cell_height);
+	    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->cell_height * size) / 100, 1);
-	    for (j = data->cell_height - nbl; j < data->cell_height; j++)
+	    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->cell_width; i++)
+		for (i = 0; i < data->curcfg.cell_width; i++)
 		{
 		    ptr[w16b * j + (i / 8)] |= 0x80 >> (i & 7);
 		}
 	    }
-	    data->cursor_bitmap = CreateBitmap(data->cell_width, data->cell_height, 1, 1, ptr);
+	    PRIVATE(data)->cursor_bitmap = CreateBitmap(data->curcfg.cell_width, 
+                                               data->curcfg.cell_height, 1, 1, ptr);
 	    HeapFree(GetProcessHeap(), 0, ptr);
 	}
-	data->cursor_size = size;
-	data->cursor_visible = -1;
+	data->curcfg.cursor_size = size;
+	data->curcfg.cursor_visible = -1;
     }
 
     vis = (vis) ? TRUE : FALSE;
-    if (force || vis != data->cursor_visible)
+    if (force || vis != data->curcfg.cursor_visible)
     {
-	data->cursor_visible = vis;
-	if (data->hWnd == GetFocus())
+	data->curcfg.cursor_visible = vis;
+	if (PRIVATE(data)->hWnd == GetFocus())
 	{
 	    if (vis)
 	    {
-		CreateCaret(data->hWnd, data->cursor_bitmap, data->cell_width, data->cell_height);
+		CreateCaret(PRIVATE(data)->hWnd, PRIVATE(data)->cursor_bitmap, 
+                            data->curcfg.cell_width, data->curcfg.cell_height);
 		WCUSER_PosCursor(data);
 	    }
 	    else
@@ -174,45 +178,47 @@
 
     /* compute window size from desired client size */
     r.left = r.top = 0;
-    r.right = data->win_width * data->cell_width;
-    r.bottom = data->win_height * data->cell_height;
+    r.right = data->curcfg.win_width * data->curcfg.cell_width;
+    r.bottom = data->curcfg.win_height * data->curcfg.cell_height;
 
     if (IsRectEmpty(&r))
     {
-	ShowWindow(data->hWnd, SW_HIDE);
+	ShowWindow(PRIVATE(data)->hWnd, SW_HIDE);
 	return;
     }
 
-    AdjustWindowRect(&r, GetWindowLong(data->hWnd, GWL_STYLE), FALSE);
+    AdjustWindowRect(&r, GetWindowLong(PRIVATE(data)->hWnd, GWL_STYLE), FALSE);
 
     dx = dy = 0;
-    if (data->sb_width > data->win_width)
+    if (data->curcfg.sb_width > data->curcfg.win_width)
     {
 	dy = GetSystemMetrics(SM_CYHSCROLL);
-	SetScrollRange(data->hWnd, SB_HORZ, 0, data->sb_width - data->win_width, FALSE);
-	SetScrollPos(data->hWnd, SB_HORZ, 0, FALSE); /* FIXME */
-	ShowScrollBar(data->hWnd, SB_HORZ, TRUE);
+	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(data->hWnd, SB_HORZ, FALSE);
+	ShowScrollBar(PRIVATE(data)->hWnd, SB_HORZ, FALSE);
     }
 
-    if (data->sb_height > data->win_height)
+    if (data->curcfg.sb_height > data->curcfg.win_height)
     {
 	dx = GetSystemMetrics(SM_CXVSCROLL);
-	SetScrollRange(data->hWnd, SB_VERT, 0, data->sb_height - data->win_height, FALSE);
-	SetScrollPos(data->hWnd, SB_VERT, 0, FALSE); /* FIXME */
-	ShowScrollBar(data->hWnd, SB_VERT, TRUE);
+	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(data->hWnd, SB_VERT, FALSE);
+	ShowScrollBar(PRIVATE(data)->hWnd, SB_VERT, FALSE);
     }
 
-    SetWindowPos(data->hWnd, 0, 0, 0, r.right - r.left + dx, r.bottom - r.top + dy,
+    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->cursor_size, data->cursor_visible, TRUE);
+    WCUSER_ShapeCursor(data, data->curcfg.cursor_size, data->curcfg.cursor_visible, TRUE);
     WCUSER_PosCursor(data);
 }
 
@@ -226,27 +232,87 @@
     WCHAR	buffer[256];	
 
     if (WINECON_GetConsoleTitle(data->hConIn, buffer, sizeof(buffer)))
-	SetWindowText(data->hWnd, 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, const TEXTMETRIC* tm)
+BOOL	WCUSER_SetFont(struct inner_data* data, const LOGFONT* logfont)
 {
-    if (!memcmp(logfont, &data->logFont, sizeof(LOGFONT))) return TRUE;
-    if (data->hFont) DeleteObject(data->hFont);
-    data->hFont = CreateFontIndirect(logfont);
-    if (!data->hFont) {Trace(0, "wrong font\n");return FALSE;}
-    data->cell_width = tm->tmMaxCharWidth; /* font is fixed Avg == Max */
-    data->cell_height = tm->tmHeight;
-    data->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(data->hWnd, NULL, FALSE);
-    UpdateWindow(data->hWnd);
+    InvalidateRect(PRIVATE(data)->hWnd, NULL, FALSE);
+    UpdateWindow(PRIVATE(data)->hWnd);
     return TRUE;
 }
 
@@ -260,8 +326,8 @@
 {
     COORD	c;
 
-    c.X = data->win_pos.X + (short)LOWORD(lParam) / data->cell_width;
-    c.Y = data->win_pos.Y + (short)HIWORD(lParam) / data->cell_height;
+    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;
 }
@@ -273,10 +339,10 @@
  */
 static void	WCUSER_GetSelectionRect(const struct inner_data* data, LPRECT r)
 {
-    r->left   = (min(data->selectPt1.X, data->selectPt2.X)    ) * data->cell_width;
-    r->top    = (min(data->selectPt1.Y, data->selectPt2.Y)    ) * data->cell_height;
-    r->right  = (max(data->selectPt1.X, data->selectPt2.X) + 1) * data->cell_width;
-    r->bottom = (max(data->selectPt1.Y, data->selectPt2.Y) + 1) * data->cell_height;
+    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;
 }
 
 /******************************************************************
@@ -290,16 +356,16 @@
     RECT	r;
 
     WCUSER_GetSelectionRect(data, &r);
-    hDC = hRefDC ? hRefDC : GetDC(data->hWnd);
+    hDC = hRefDC ? hRefDC : GetDC(PRIVATE(data)->hWnd);
     if (hDC)
     {
-	if (data->hWnd == GetFocus() && data->cursor_visible)
-	    HideCaret(data->hWnd);
+	if (PRIVATE(data)->hWnd == GetFocus() && data->curcfg.cursor_visible)
+	    HideCaret(PRIVATE(data)->hWnd);
 	InvertRect(hDC, &r);
 	if (hDC != hRefDC)
-	    ReleaseDC(data->hWnd, hDC);
-	if (data->hWnd == GetFocus() && data->cursor_visible)
-	    ShowCaret(data->hWnd);
+	    ReleaseDC(PRIVATE(data)->hWnd, hDC);
+	if (PRIVATE(data)->hWnd == GetFocus() && data->curcfg.cursor_visible)
+	    ShowCaret(PRIVATE(data)->hWnd);
     }
 }
 
@@ -314,26 +380,26 @@
     HDC		hDC;
 
     WCUSER_GetSelectionRect(data, &r);
-    hDC = GetDC(data->hWnd);
+    hDC = GetDC(PRIVATE(data)->hWnd);
     if (hDC)
     {
-	if (data->hWnd == GetFocus() && data->cursor_visible)
-	    HideCaret(data->hWnd);
+	if (PRIVATE(data)->hWnd == GetFocus() && data->curcfg.cursor_visible)
+	    HideCaret(PRIVATE(data)->hWnd);
 	InvertRect(hDC, &r);
     }
-    data->selectPt2 = dst;
+    PRIVATE(data)->selectPt2 = dst;
     if (hDC)
     {
 	WCUSER_GetSelectionRect(data, &r);
 	InvertRect(hDC, &r);
-	ReleaseDC(data->hWnd, hDC);
-	if (data->hWnd == GetFocus() && data->cursor_visible)
-	    ShowCaret(data->hWnd);
+	ReleaseDC(PRIVATE(data)->hWnd, hDC);
+	if (PRIVATE(data)->hWnd == GetFocus() && data->curcfg.cursor_visible)
+	    ShowCaret(PRIVATE(data)->hWnd);
     }
     if (final)
     {
 	ReleaseCapture();
-	data->hasSelection = TRUE;
+	PRIVATE(data)->hasSelection = TRUE;
     }
 }
 
@@ -348,10 +414,10 @@
     LPWSTR	p;
     unsigned	w, h;
 
-    w = abs(data->selectPt1.X - data->selectPt2.X) + 2;
-    h = abs(data->selectPt1.Y - data->selectPt2.Y) + 1;
+    w = abs(PRIVATE(data)->selectPt1.X - PRIVATE(data)->selectPt2.X) + 2;
+    h = abs(PRIVATE(data)->selectPt1.Y - PRIVATE(data)->selectPt2.Y) + 1;
 
-    if (!OpenClipboard(data->hWnd)) return;
+    if (!OpenClipboard(PRIVATE(data)->hWnd)) return;
     EmptyClipboard();
 
     hMem = GlobalAlloc(GMEM_MOVEABLE, (w * h - 1) * sizeof(WCHAR));
@@ -360,8 +426,8 @@
 	COORD	c;
 	int	y;
 
-	c.X = data->win_pos.X + min(data->selectPt1.X, data->selectPt2.X);
-	c.Y = data->win_pos.Y + min(data->selectPt1.Y, data->selectPt2.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++)
 	{
@@ -384,7 +450,7 @@
     HANDLE	h;
     WCHAR*	ptr;
 
-    if (!OpenClipboard(data->hWnd)) return;
+    if (!OpenClipboard(PRIVATE(data)->hWnd)) return;
     h = GetClipboardData(CF_UNICODETEXT);
     if (h && (ptr = GlobalLock(h)))
     {
@@ -417,19 +483,24 @@
     CloseClipboard();
 }
 
+/******************************************************************
+ *		Refresh
+ *
+ *
+ */
 static void WCUSER_Refresh(const struct inner_data* data, int tp, int bm)
 {
-    if (data->win_pos.Y <= bm && data->win_pos.Y + data->win_height >= tp)
+    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->win_width * data->cell_width;
-	r.top    = (tp - data->win_pos.Y) * data->cell_height;
-	r.bottom = (bm - data->win_pos.Y + 1) * data->cell_height;
-	InvalidateRect(data->hWnd, &r, FALSE);
+	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(data->hWnd);
+	UpdateWindow(PRIVATE(data)->hWnd);
     }
 }
 
@@ -442,13 +513,17 @@
 {
     PAINTSTRUCT		ps;
 
-    BeginPaint(data->hWnd, &ps);
-    BitBlt(ps.hdc, 0, 0, data->win_width * data->cell_width, data->win_height * data->cell_height,
-	   data->hMemDC, data->win_pos.X * data->cell_width, data->win_pos.Y * data->cell_height,
+    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 (data->hasSelection)
+    if (PRIVATE(data)->hasSelection)
 	WCUSER_SetSelection(data, ps.hdc);
-    EndPaint(data->hWnd, &ps);
+    EndPaint(PRIVATE(data)->hWnd, &ps);
 }
 
 /******************************************************************
@@ -460,16 +535,16 @@
 {
     if (horz)
     {
-	SetScrollPos(data->hWnd, SB_HORZ, pos, TRUE);
-	data->win_pos.X = pos;
-	InvalidateRect(data->hWnd, NULL, FALSE);
+	SetScrollPos(PRIVATE(data)->hWnd, SB_HORZ, pos, TRUE);
+	data->curcfg.win_pos.X = pos;
+	InvalidateRect(PRIVATE(data)->hWnd, NULL, FALSE);
     }
     else
     {
-	SetScrollPos(data->hWnd, SB_VERT, pos, TRUE);
-	data->win_pos.Y = pos;
+	SetScrollPos(PRIVATE(data)->hWnd, SB_VERT, pos, TRUE);
+	data->curcfg.win_pos.Y = pos;
     }
-    InvalidateRect(data->hWnd, NULL, FALSE);
+    InvalidateRect(PRIVATE(data)->hWnd, NULL, FALSE);
 }
 
 struct font_chooser {
@@ -484,8 +559,8 @@
  */
 BOOL	WCUSER_ValidateFontMetric(const struct inner_data* data, const TEXTMETRIC* tm)
 {
-    return tm->tmMaxCharWidth * data->win_width < GetSystemMetrics(SM_CXSCREEN) &&
-	tm->tmHeight * data->win_height < GetSystemMetrics(SM_CYSCREEN) &&
+    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;
 }
 
@@ -496,7 +571,9 @@
  */
 BOOL	WCUSER_ValidateFont(const struct inner_data* data, const LOGFONT* lf)
 {
-    return (lf->lfPitchAndFamily & 3) == FIXED_PITCH && (lf->lfPitchAndFamily & 0xF0) == FF_MODERN;
+    return (lf->lfPitchAndFamily & 3) == FIXED_PITCH && 
+        (lf->lfPitchAndFamily & 0xF0) == FF_MODERN &&
+        lf->lfCharSet != SYMBOL_CHARSET;
 }
 
 /******************************************************************
@@ -512,7 +589,7 @@
 
     if (WCUSER_ValidateFontMetric(fc->data, tm))
     {
-	WCUSER_SetFont(fc->data, lf, tm);
+	WCUSER_SetFont(fc->data, lf);
 	fc->done = 1;
 	return 0;
     }
@@ -526,36 +603,28 @@
 
     if (WCUSER_ValidateFont(fc->data, lf))
     {
-	EnumFontFamilies(fc->data->hMemDC, lf->lfFaceName, get_first_font_enum_2, lParam);
+	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_Create
+ *		WCUSER_FillMenu
  *
- * Creates the window for the rendering
+ *
  */
-static LRESULT WCUSER_Create(HWND hWnd, LPCREATESTRUCT lpcs)
+static BOOL WCUSER_FillMenu(HMENU hMenu, BOOL sep)
 {
-    struct inner_data*	data;
-    HMENU		hMenu;
     HMENU		hSubMenu;
-    WCHAR		buff[256];
     HINSTANCE		hInstance = GetModuleHandle(NULL);
+    WCHAR		buff[256];
 
-    data = lpcs->lpCreateParams;
-    SetWindowLong(hWnd, 0L, (DWORD)data);
-    data->hWnd = hWnd;
+    if (!hMenu) return FALSE;
 
-    data->cursor_size = 101; /* invalid value, will trigger a complete cleanup */
     /* FIXME: error handling & memory cleanup */
     hSubMenu = CreateMenu();
-    if (!hSubMenu) return 0;
-
-    hMenu = GetSystemMenu(hWnd, FALSE);
-    if (!hMenu) return 0;
+    if (!hSubMenu) return FALSE;
 
     LoadString(hInstance, IDS_MARK, buff, sizeof(buff) / sizeof(WCHAR));
     InsertMenu(hSubMenu, -1, MF_BYPOSITION|MF_STRING, IDS_MARK, buff);
@@ -570,7 +639,7 @@
     LoadString(hInstance, IDS_SEARCH, buff, sizeof(buff) / sizeof(WCHAR));
     InsertMenu(hSubMenu, -1, MF_BYPOSITION|MF_STRING, IDS_SEARCH, buff);
 
-    InsertMenu(hMenu, -1, MF_BYPOSITION|MF_SEPARATOR, 0, NULL);
+    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));
@@ -578,8 +647,35 @@
     LoadString(hInstance, IDS_PROPERTY, buff, sizeof(buff) / sizeof(WCHAR));
     InsertMenu(hMenu, -1, MF_BYPOSITION|MF_STRING, IDS_PROPERTY, buff);
 
-    data->hMemDC = CreateCompatibleDC(0);
-    if (!data->hMemDC) {Trace(0, "no mem dc\n");return 0;}
+    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;
 }
@@ -591,7 +687,7 @@
  */
 static void	WCUSER_SetMenuDetails(const struct inner_data* data)
 {
-    HMENU		hMenu = GetSystemMenu(data->hWnd, FALSE);
+    HMENU		hMenu = GetSystemMenu(PRIVATE(data)->hWnd, FALSE);
 
     if (!hMenu) {Trace(0, "Issue in getting menu bits\n");return;}
 
@@ -599,7 +695,7 @@
     EnableMenuItem(hMenu, IDS_DEFAULT, MF_BYCOMMAND|MF_GRAYED);
 
     EnableMenuItem(hMenu, IDS_MARK, MF_BYCOMMAND|MF_GRAYED);
-    EnableMenuItem(hMenu, IDS_COPY, MF_BYCOMMAND|(data->hasSelection ? MF_ENABLED : 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));
@@ -609,12 +705,12 @@
 }
 
 /******************************************************************
- *		WCUSER_GenerateInputRecord
+ *		WCUSER_GenerateKeyInputRecord
  *
  * generates input_record from windows WM_KEYUP/WM_KEYDOWN messages
  */
-static void    WCUSER_GenerateInputRecord(struct inner_data* data, BOOL down, 
-					   WPARAM wParam, LPARAM lParam, BOOL sys)
+static void    WCUSER_GenerateKeyInputRecord(struct inner_data* data, BOOL down, 
+                                             WPARAM wParam, LPARAM lParam, BOOL sys)
 {
     INPUT_RECORD	ir;
     DWORD		n;
@@ -644,10 +740,10 @@
     if (keyState[VK_NUMLOCK]  & 0x01)	ir.Event.KeyEvent.dwControlKeyState |= NUMLOCK_ON;
     if (keyState[VK_SCROLL]   & 0x01)	ir.Event.KeyEvent.dwControlKeyState |= SCROLLLOCK_ON;
 
-    if (data->hasSelection && ir.Event.KeyEvent.dwControlKeyState == 0 && 
+    if (PRIVATE(data)->hasSelection && ir.Event.KeyEvent.dwControlKeyState == 0 && 
 	ir.Event.KeyEvent.wVirtualKeyCode == VK_RETURN)
     {
-	data->hasSelection = FALSE;
+	PRIVATE(data)->hasSelection = FALSE;
 	WCUSER_SetSelection(data, 0);
 	WCUSER_CopySelectionToClipboard(data);
 	return;
@@ -691,7 +787,7 @@
     case WM_CREATE:
         return WCUSER_Create(hWnd, (LPCREATESTRUCT)lParam);
     case WM_DESTROY:
-	data->hWnd = 0;
+	PRIVATE(data)->hWnd = 0;
 	PostQuitMessage(0);
 	break;
     case WM_PAINT:
@@ -699,53 +795,54 @@
 	break;
     case WM_KEYDOWN:
     case WM_KEYUP:
-	WCUSER_GenerateInputRecord(data, uMsg == WM_KEYDOWN, wParam, lParam, FALSE);
+	WCUSER_GenerateKeyInputRecord(data, uMsg == WM_KEYDOWN, wParam, lParam, FALSE);
 	break;
     case WM_SYSKEYDOWN:
     case WM_SYSKEYUP:
-	WCUSER_GenerateInputRecord(data, uMsg == WM_SYSKEYDOWN, wParam, lParam, TRUE);
+	WCUSER_GenerateKeyInputRecord(data, uMsg == WM_SYSKEYDOWN, wParam, lParam, TRUE);
 	break;
     case WM_LBUTTONDOWN:
 	/* EPP if (wParam != MK_LBUTTON) */
-	if (data->hasSelection)
+	if (PRIVATE(data)->hasSelection)
 	{
-	    data->hasSelection = FALSE;
+	    PRIVATE(data)->hasSelection = FALSE;
 	}
 	else
 	{
-	    data->selectPt1 = data->selectPt2 = WCUSER_GetCell(data, lParam);
-	    SetCapture(data->hWnd);
+	    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() == data->hWnd)
+        if (GetCapture() == PRIVATE(data)->hWnd)
 	{
 	    WCUSER_MoveSelection(data, WCUSER_GetCell(data, lParam), FALSE);
 	}
 	break;
     case WM_LBUTTONUP:
 	/* EPP if (wParam != MK_LBUTTON) */
-        if (GetCapture() == data->hWnd)
+        if (GetCapture() == PRIVATE(data)->hWnd)
 	{
 	    WCUSER_MoveSelection(data, WCUSER_GetCell(data, lParam), TRUE);
 	}
 	break;
     case WM_SETFOCUS:
-	if (data->cursor_visible)
+	if (data->curcfg.cursor_visible)
 	{
-	    CreateCaret(data->hWnd, data->cursor_bitmap, data->cell_width, data->cell_height); 
+	    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->cursor_visible)
+	if (data->curcfg.cursor_visible)
 	    DestroyCaret(); 
 	break;
     case WM_HSCROLL: 
         {
-	    int	pos = data->win_pos.X;
+	    int	pos = data->curcfg.win_pos.X;
 
 	    switch (LOWORD(wParam)) 
 	    { 
@@ -757,11 +854,13 @@
             default: 					break;
 	    } 
 	    if (pos < 0) pos = 0;
-	    if (pos > data->sb_width - data->win_width) pos = data->sb_width - data->win_width;
-	    if (pos != data->win_pos.X)
+	    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->win_pos.X - pos) * data->cell_width, 0, NULL, NULL);
-		data->win_pos.X = pos;
+		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);
@@ -771,7 +870,7 @@
 	break;
     case WM_VSCROLL: 
         {
-	    int	pos = data->win_pos.Y;
+	    int	pos = data->curcfg.win_pos.Y;
 
 	    switch (LOWORD(wParam)) 
 	    { 
@@ -783,11 +882,13 @@
             default: 					break;
 	    } 
 	    if (pos < 0) pos = 0;
-	    if (pos > data->sb_height - data->win_height) pos = data->sb_height - data->win_height;
-	    if (pos != data->win_pos.Y)
+	    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->win_pos.Y - pos) * data->cell_height, NULL, NULL);
-		data->win_pos.Y = pos;
+		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);
@@ -799,25 +900,38 @@
 	switch (wParam)
 	{
 	case IDS_DEFAULT:
-	    Trace(0, "unhandled yet command: %x\n", wParam);
+	    WCUSER_GetProperties(data, FALSE);
 	    break;
 	case IDS_PROPERTY:
-	    WCUSER_GetProperties(data);
+	    WCUSER_GetProperties(data, TRUE);
 	    break;
 	default: 
 	    return DefWindowProc(hWnd, uMsg, wParam, lParam);
 	}
 	break;
     case WM_RBUTTONDOWN:
-	WCUSER_GetProperties(data);
+        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:
-	    data->hasSelection = FALSE;
+	    PRIVATE(data)->hasSelection = FALSE;
 	    WCUSER_SetSelection(data, 0);
 	    WCUSER_CopySelectionToClipboard(data);
 	    break;
@@ -825,11 +939,11 @@
 	    WCUSER_PasteFromClipboard(data);
 	    break;
 	case IDS_SELECTALL:
-	    data->selectPt1.X = data->selectPt1.Y = 0;
-	    data->selectPt2.X = (data->sb_width - 1) * data->cell_width;
-	    data->selectPt2.Y = (data->sb_height - 1) * data->cell_height;
+	    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);
-	    data->hasSelection = TRUE;
+	    PRIVATE(data)->hasSelection = TRUE;
 	    break;
 	case IDS_SCROLL:
 	case IDS_SEARCH:
@@ -857,11 +971,13 @@
  */
 void WCUSER_DeleteBackend(struct inner_data* data)
 {
-    if (data->hWnd)		DestroyWindow(data->hWnd);
-    if (data->hFont)		DeleteObject(data->hFont);
-    if (data->cursor_bitmap)	DeleteObject(data->cursor_bitmap);
-    if (data->hMemDC)		DeleteDC(data->hMemDC);
-    if (data->hBitmap)		DeleteObject(data->hBitmap);
+    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));
 }
 
 /******************************************************************
@@ -912,7 +1028,9 @@
     static WCHAR wClassName[] = {'W','i','n','e','C','o','n','s','o','l','e','C','l','a','s','s',0};
 
     WNDCLASS		wndclass;
-    struct font_chooser fc;
+
+    data->private = HeapAlloc(GetProcessHeap(), 0, sizeof(struct inner_data_user));
+    if (!data->private) return FALSE;
 
     data->fnMainLoop = WCUSER_MainLoop;
     data->fnPosCursor = WCUSER_PosCursor;
@@ -940,17 +1058,21 @@
     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 (!data->hWnd) return FALSE;
+    if (!PRIVATE(data)->hWnd) return FALSE;
 
     /* force update of current data */
     WINECON_GrabChanges(data);
 
-    /* try to find an acceptable font */
-    fc.data = data;
-    fc.done = 0;
-    EnumFontFamilies(data->hMemDC, NULL, get_first_font_enum, (LPARAM)&fc);
-
-    return fc.done;
+    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;
 }
 
 
diff --git a/programs/wineconsole/winecon_private.h b/programs/wineconsole/winecon_private.h
index b444164..ebb712b 100644
--- a/programs/wineconsole/winecon_private.h
+++ b/programs/wineconsole/winecon_private.h
@@ -1,21 +1,39 @@
+/*
+ * an application for displaying Win32 console
+ *
+ * Copyright 2001 Eric Pouech
+ */
+
 #include <winbase.h>
-#include <wingdi.h>
-#include <winuser.h>
 #include <wincon.h>
 
 #include "wineconsole_res.h"
 
+/* this is the configuration stored & loaded into the registry */
+struct config_data {
+    unsigned	cell_width;	/* width in pixels of a character */	
+    unsigned	cell_height;	/* height in pixels of a character */
+    int		cursor_size;	/* in % of cell height */
+    int		cursor_visible;
+    DWORD       def_attr;
+    WCHAR       face_name[32];  /* name of font (size is LF_FACESIZE) */
+    DWORD       font_weight;
+    DWORD       history_size;
+    DWORD       menu_mask;      /* MK_CONTROL MK_SHIFT mask to drive submenu opening */
+    unsigned	sb_width;	/* active screen buffer width */
+    unsigned	sb_height;	/* active screen buffer height */
+    unsigned	win_width;	/* size (in cells) of visible part of window (width & height) */
+    unsigned	win_height;
+    COORD	win_pos;	/* position (in cells) of visible part of screen buffer in window */
+};
+
 struct inner_data {
-    unsigned		sb_width;	/* active screen buffer width */
-    unsigned		sb_height;	/* active screen buffer height */
+    struct config_data  curcfg;
+    struct config_data  defcfg;
+
     CHAR_INFO*		cells;		/* local copy of cells (sb_width * sb_height) */
-    COORD		win_pos;	/* position (in cells) of visible part of screen buffer in window */
-    unsigned		win_width;	/* size (in cells) of visible part of window (width & height) */
-    unsigned		win_height;
 
     COORD		cursor;		/* position in cells of cursor */
-    int			cursor_visible;
-    int			cursor_size;	/* in % of cell height */
 
     HANDLE		hConIn;		/* console input handle */
     HANDLE		hConOut;	/* screen buffer handle: has to be changed when active sb changes */
@@ -31,19 +49,7 @@
     void		(*fnScroll)(struct inner_data* data, int pos, BOOL horz);
     void		(*fnDeleteBackend)(struct inner_data* data);
 
-    /* the following fields are only user by the USER backend (should be hidden in user) */
-    HWND		hWnd;		/* handle to windows for rendering */
-    HFONT		hFont;		/* font used for rendering, usually fixed */
-    LOGFONT		logFont;	/* logFont dscription for used hFont */
-    unsigned		cell_width;	/* width in pixels of a character */	
-    unsigned		cell_height;	/* height in pixels of a character */
-    HDC			hMemDC;		/* memory DC holding the bitmap below */
-    HBITMAP		hBitmap;	/* bitmap of display window content */
-
-    HBITMAP		cursor_bitmap;  /* bitmap used for the caret */
-    BOOL		hasSelection;	/* a rectangular mouse selection has taken place */
-    COORD		selectPt1;	/* start (and end) point of a mouse selection */
-    COORD		selectPt2;
+    void*               private;        /* data part belonging to the choosen backed */
 };
 
 #  ifdef __GNUC__
@@ -59,6 +65,7 @@
 #  define Trace (1) ? (void)0 : XTracer
 #endif
 
+/* from wineconsole.c */
 extern void WINECON_NotifyWindowChange(struct inner_data* data);
 extern int  WINECON_GetHistorySize(HANDLE hConIn);
 extern BOOL WINECON_SetHistorySize(HANDLE hConIn, int size);
@@ -68,8 +75,9 @@
 extern void WINECON_FetchCells(struct inner_data* data, int upd_tp, int upd_bm);
 extern int  WINECON_GrabChanges(struct inner_data* data);
 
-extern BOOL WCUSER_GetProperties(struct inner_data*);
-extern BOOL WCUSER_SetFont(struct inner_data* data, const LOGFONT* font, const TEXTMETRIC* tm);
-extern BOOL WCUSER_ValidateFont(const struct inner_data* data, const LOGFONT* lf);
-extern BOOL WCUSER_ValidateFontMetric(const struct inner_data* data, const TEXTMETRIC* tm);
+/* from registry.c */
+extern BOOL WINECON_RegLoad(struct config_data* cfg);
+extern BOOL WINECON_RegSave(const struct config_data* cfg);
+
+/* backends... */
 extern BOOL WCUSER_InitBackend(struct inner_data* data);
diff --git a/programs/wineconsole/winecon_user.h b/programs/wineconsole/winecon_user.h
new file mode 100644
index 0000000..944ec57
--- /dev/null
+++ b/programs/wineconsole/winecon_user.h
@@ -0,0 +1,37 @@
+/*
+ * an application for displaying Win32 console
+ * USER32 backend
+ *
+ * Copyright 2001 Eric Pouech
+ */
+
+#include <winbase.h>
+#include <wingdi.h>
+#include <winuser.h>
+#include "winecon_private.h"
+
+struct inner_data_user {
+    /* the following fields are only user by the USER backend (should be hidden in user) */
+    HWND		hWnd;		/* handle to windows for rendering */
+    HFONT		hFont;		/* font used for rendering, usually fixed */
+    HDC			hMemDC;		/* memory DC holding the bitmap below */
+    HBITMAP		hBitmap;	/* bitmap of display window content */
+    HMENU               hPopMenu;       /* popup menu triggered by right mouse click */
+
+    HBITMAP		cursor_bitmap;  /* bitmap used for the caret */
+    BOOL		hasSelection;	/* a rectangular mouse selection has taken place */
+    COORD		selectPt1;	/* start (and end) point of a mouse selection */
+    COORD		selectPt2;
+};
+
+#define PRIVATE(data)   ((struct inner_data_user*)((data)->private))
+
+/* from user.c */
+extern COLORREF	WCUSER_ColorMap[16];
+extern BOOL WCUSER_GetProperties(struct inner_data*, BOOL);
+extern BOOL WCUSER_SetFont(struct inner_data* data, const LOGFONT* font);
+extern BOOL WCUSER_ValidateFont(const struct inner_data* data, const LOGFONT* lf);
+extern BOOL WCUSER_ValidateFontMetric(const struct inner_data* data, const TEXTMETRIC* tm);
+extern BOOL WCUSER_AreFontsEqual(const struct config_data* config, const LOGFONT* lf);
+extern void WCUSER_CopyFont(struct config_data* config, const LOGFONT* lf);
+
diff --git a/programs/wineconsole/wineconsole.c b/programs/wineconsole/wineconsole.c
index 879c7a8..cfad511 100644
--- a/programs/wineconsole/wineconsole.c
+++ b/programs/wineconsole/wineconsole.c
@@ -19,7 +19,7 @@
     if (level > trace_level) return;
 
     va_start(valist, format);
-    len = wvsnprintfA(buf, sizeof(buf), format, valist);
+    len = vsnprintf(buf, sizeof(buf), format, valist);
     va_end(valist);
  
     if (len <= -1) 
@@ -45,8 +45,8 @@
         req->y      = upd_tp;
         req->mode   = CHAR_INFO_MODE_TEXTATTR;
         req->wrap   = TRUE;
-        wine_server_set_reply( req, &data->cells[upd_tp * data->sb_width],
-                               (upd_bm-upd_tp+1) * data->sb_width * sizeof(CHAR_INFO) );
+        wine_server_set_reply( req, &data->cells[upd_tp * data->curcfg.sb_width],
+                               (upd_bm-upd_tp+1) * data->curcfg.sb_width * sizeof(CHAR_INFO) );
         wine_server_call( req );
     }
     SERVER_END_REQ;
@@ -63,10 +63,10 @@
     SERVER_START_REQ( set_console_output_info )
     {
         req->handle       = (handle_t)data->hConOut;
-        req->win_left     = data->win_pos.X;
-        req->win_top      = data->win_pos.Y;
-        req->win_right    = data->win_pos.X + data->win_width - 1;
-        req->win_bottom   = data->win_pos.Y + data->win_height - 1;
+        req->win_left     = data->curcfg.win_pos.X;
+        req->win_top      = data->curcfg.win_pos.Y;
+        req->win_right    = data->curcfg.win_pos.X + data->curcfg.win_width - 1;
+        req->win_bottom   = data->curcfg.win_pos.Y + data->curcfg.win_height - 1;
         req->mask         = SET_CONSOLE_OUTPUT_INFO_DISPLAY_WINDOW;
         wine_server_call( req );
     }
@@ -223,15 +223,15 @@
 	    }
 	    break;
 	case CONSOLE_RENDERER_SB_RESIZE_EVENT:
-	    if (data->sb_width != evts[i].u.resize.width || 
-		data->sb_height != evts[i].u.resize.height)
+	    if (data->curcfg.sb_width != evts[i].u.resize.width || 
+		data->curcfg.sb_height != evts[i].u.resize.height)
 	    {
 		Trace(1, " resize(%d,%d)", evts[i].u.resize.width, evts[i].u.resize.height);
-		data->sb_width  = evts[i].u.resize.width;
-		data->sb_height = evts[i].u.resize.height;
+		data->curcfg.sb_width  = evts[i].u.resize.width;
+		data->curcfg.sb_height = evts[i].u.resize.height;
 		
 		data->cells = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, data->cells,
-					  data->sb_width * data->sb_height * sizeof(CHAR_INFO));
+					  data->curcfg.sb_width * data->curcfg.sb_height * sizeof(CHAR_INFO));
 		if (!data->cells) {Trace(0, "OOM\n"); exit(0);}
 		data->fnResizeScreenBuffer(data);
 		data->fnComputePositions(data);
@@ -251,8 +251,8 @@
 	    }
 	    break;
 	case CONSOLE_RENDERER_CURSOR_GEOM_EVENT:
-	    if (evts[i].u.cursor_geom.size != data->cursor_size || 
-		evts[i].u.cursor_geom.visible != data->cursor_visible)
+	    if (evts[i].u.cursor_geom.size != data->curcfg.cursor_size || 
+		evts[i].u.cursor_geom.visible != data->curcfg.cursor_visible)
 	    {
 		data->fnShapeCursor(data, evts[i].u.cursor_geom.size, 
 				    evts[i].u.cursor_geom.visible, FALSE);
@@ -261,24 +261,24 @@
 	    }
 	    break;
 	case CONSOLE_RENDERER_DISPLAY_EVENT:
-	    if (evts[i].u.display.left != data->win_pos.X)
+	    if (evts[i].u.display.left != data->curcfg.win_pos.X)
 	    {
 		data->fnScroll(data, evts[i].u.display.left, TRUE);
 		data->fnPosCursor(data);
 		Trace(1, " h-scroll(%d)", evts[i].u.display.left);
 	    }
-	    if (evts[i].u.display.top != data->win_pos.Y)
+	    if (evts[i].u.display.top != data->curcfg.win_pos.Y)
 	    {
 		data->fnScroll(data, evts[i].u.display.top, FALSE);
 		data->fnPosCursor(data);
 		Trace(1, " v-scroll(%d)", evts[i].u.display.top);
 	    }
-	    if (evts[i].u.display.width != data->win_width || 
-		evts[i].u.display.height != data->win_height)
+	    if (evts[i].u.display.width != data->curcfg.win_width || 
+		evts[i].u.display.height != data->curcfg.win_height)
 	    {
 		Trace(1, " win-size(%d,%d)", evts[i].u.display.width, evts[i].u.display.height);
-		data->win_width = evts[i].u.display.width;
-		data->win_height = evts[i].u.display.height;
+		data->curcfg.win_width = evts[i].u.display.width;
+		data->curcfg.win_height = evts[i].u.display.height;
 		data->fnComputePositions(data);
 	    }
 	    break;
@@ -326,6 +326,10 @@
     data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data));
     if (!data) return 0;
 
+    /* load default registry settings, and copy them into our current configuration */
+    WINECON_RegLoad(&data->defcfg);
+    data->curcfg = data->defcfg;
+
     /* the handles here are created without the whistles and bells required by console
      * (mainly because wineconsole doesn't need it)
      * - there are not inheritable
@@ -351,20 +355,18 @@
         ret = !wine_server_call_err( req );
     }
     SERVER_END_REQ;
+    if (!ret) goto error;
 
-    if (ret) 
-    {    
-	SERVER_START_REQ(create_console_output)
-	{
-	    req->handle_in = (handle_t)data->hConIn;
-	    req->access    = GENERIC_WRITE|GENERIC_READ;
-	    req->share     = FILE_SHARE_READ|FILE_SHARE_WRITE;
-	    req->inherit   = FALSE;
-	    data->hConOut  = (HANDLE)(wine_server_call_err( req ) ? 0 : reply->handle_out);
-	}
-	SERVER_END_REQ;
-	if (data->hConOut) return data;
+    SERVER_START_REQ(create_console_output)
+    {
+        req->handle_in = (handle_t)data->hConIn;
+        req->access    = GENERIC_WRITE|GENERIC_READ;
+        req->share     = FILE_SHARE_READ|FILE_SHARE_WRITE;
+        req->inherit   = FALSE;
+        data->hConOut  = (HANDLE)(wine_server_call_err( req ) ? 0 : reply->handle_out);
     }
+    SERVER_END_REQ;
+    if (data->hConOut) return data;
 
  error:
     WINECON_Delete(data);
@@ -386,8 +388,7 @@
     /* we're in the case wineconsole <exe> <options>... spawn the new process */
     memset(&startup, 0, sizeof(startup));
     startup.cb          = sizeof(startup);
-    startup.dwFlags     = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
-    startup.wShowWindow = SW_SHOWNORMAL;
+    startup.dwFlags     = STARTF_USESTDHANDLES;
 
     /* the attributes of wineconsole's handles are not adequate for inheritance, so
      * get them with the correct attributes before process creation
@@ -421,6 +422,11 @@
     return done;
 }
 
+/******************************************************************
+ *		 WINECON_HasEvent
+ *
+ *
+ */
 static BOOL WINECON_HasEvent(LPCSTR ptr, unsigned *evt)
 {
     while (*ptr == ' ' || *ptr == '\t') ptr++;
diff --git a/programs/wineconsole/wineconsole.spec b/programs/wineconsole/wineconsole.spec
index a5c6544..871d147 100644
--- a/programs/wineconsole/wineconsole.spec
+++ b/programs/wineconsole/wineconsole.spec
@@ -7,6 +7,6 @@
 import -delay comctl32
 import  gdi32.dll
 import  user32.dll
-#import	advapi32.dll
+import	advapi32.dll
 import	kernel32.dll
 import	ntdll.dll
diff --git a/programs/wineconsole/wineconsole_En.rc b/programs/wineconsole/wineconsole_En.rc
index 50b6f6d..0245d60 100644
--- a/programs/wineconsole/wineconsole_En.rc
+++ b/programs/wineconsole/wineconsole_En.rc
@@ -14,6 +14,8 @@
 IDS_FNT_DISPLAY,	"Each character is %ld pixels wide on %ld pixels high"
 IDS_FNT_PREVIEW_1,	"This is a test"
 IDS_FNT_PREVIEW_2,	""
+IDS_DLG_TIT_DEFAULT     "Setup - Default settings"
+IDS_DLG_TIT_CURRENT     "Setup - Current settings"
 END
 
 IDD_OPTION DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 140, 105 LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
@@ -26,7 +28,11 @@
 	AUTORADIOBUTTON "&Medium", IDC_OPT_CURSOR_MEDIUM, 14, 33, 84, 10, WS_TABSTOP
 	AUTORADIOBUTTON "&Large", IDC_OPT_CURSOR_LARGE, 14, 43, 84, 10, WS_TABSTOP
 
-	GROUPBOX "Command history", -1, 10, 57, 180, 35, BS_GROUPBOX
+	GROUPBOX "Conf. open", -1, 140, 11, 60, 44, BS_GROUPBOX
+	AUTOCHECKBOX "&Control", IDC_OPT_CONF_CTRL, 144, 23, 50, 10, WS_TABSTOP
+	AUTOCHECKBOX "S&hift", IDC_OPT_CONF_SHIFT, 144, 33, 50, 10, WS_TABSTOP
+
+	GROUPBOX "Command history", -1, 10, 57, 190, 35, BS_GROUPBOX
 	LTEXT "&Numbers of recalled commands :", -1, 14, 67, 78, 18
 	EDITTEXT IDC_OPT_HIST_SIZE, 92, 69, 31, 12, WS_TABSTOP|WS_BORDER|ES_NUMBER
 	CONTROL "", IDC_OPT_HIST_SIZE_UD, "msctls_updown32", UDS_SETBUDDYINT|UDS_ALIGNRIGHT|UDS_AUTOBUDDY|UDS_ARROWKEYS|UDS_NOTHOUSANDS, 0, 0, 0, 0
@@ -39,10 +45,13 @@
 FONT 8, "Helv"
 {
 	LTEXT "&Font", -1, 5, 5, 24, 8
-	LISTBOX IDC_FNT_LIST_FONT, 5,18,109,42, LBS_SORT|WS_VSCROLL
-	LTEXT "&Size", -1, 128, 5, 60, 8
-	LISTBOX IDC_FNT_LIST_SIZE, 128, 18, 50, 60, WS_VSCROLL
-	CONTROL "", IDC_FNT_PREVIEW, "WineConFontPreview", 0L, 5,60,109,40
+	LISTBOX IDC_FNT_LIST_FONT, 5, 18, 90, 42, LBS_SORT|WS_VSCROLL
+	LTEXT "&Color", -1, 100, 5, 50, 8
+	CONTROL "", IDC_FNT_COLOR_FG, "WineConColorPreview", 0L, 100, 18, 48, 16
+	CONTROL "", IDC_FNT_COLOR_BK, "WineConColorPreview", 0L, 100, 40, 48, 16
+	LTEXT "&Size", -1, 158, 5, 40, 8
+	LISTBOX IDC_FNT_LIST_SIZE, 158, 18, 40, 60, WS_VSCROLL
+	CONTROL "", IDC_FNT_PREVIEW, "WineConFontPreview", 0L, 5, 60, 109, 40
 	LTEXT "", IDC_FNT_FONT_INFO, 128, 76, 80, 18
 }
 
diff --git a/programs/wineconsole/wineconsole_Fr.rc b/programs/wineconsole/wineconsole_Fr.rc
index d5a7841..67e1236 100644
--- a/programs/wineconsole/wineconsole_Fr.rc
+++ b/programs/wineconsole/wineconsole_Fr.rc
@@ -14,6 +14,8 @@
 IDS_FNT_DISPLAY,	"Chaque caractère a %ld points en largeur et %ld points en hauteur"
 IDS_FNT_PREVIEW_1,	"Ceci est un test"
 IDS_FNT_PREVIEW_2,	"éèàôë"
+IDS_DLG_TIT_DEFAULT     "Configuration par défault"
+IDS_DLG_TIT_CURRENT     "Configuration courante"
 END
 
 IDD_OPTION DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 140, 105 LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
@@ -26,7 +28,11 @@
 	AUTORADIOBUTTON "&Moyen", IDC_OPT_CURSOR_MEDIUM, 14, 33, 84, 10, WS_TABSTOP
 	AUTORADIOBUTTON "&Grand", IDC_OPT_CURSOR_LARGE, 14, 43, 84, 10, WS_TABSTOP
 
-	GROUPBOX "Historique des commandes", -1, 10, 57, 180, 35, BS_GROUPBOX
+	GROUPBOX "Ouverture conf.", -1, 140, 11, 60, 44, BS_GROUPBOX
+	AUTOCHECKBOX "&Control", IDC_OPT_CONF_CTRL, 144, 23, 50, 10, WS_TABSTOP
+	AUTOCHECKBOX "S&hift", IDC_OPT_CONF_SHIFT, 144, 33, 50, 10, WS_TABSTOP
+
+	GROUPBOX "Historique des commandes", -1, 10, 57, 190, 35, BS_GROUPBOX
 	LTEXT "&Taille de la mémoire tampon :", -1, 14, 67, 78, 18
 	EDITTEXT IDC_OPT_HIST_SIZE, 92, 69, 31, 12, WS_TABSTOP|WS_BORDER|ES_NUMBER
 	CONTROL "", IDC_OPT_HIST_SIZE_UD, "msctls_updown32", UDS_SETBUDDYINT|UDS_ALIGNRIGHT|UDS_AUTOBUDDY|UDS_ARROWKEYS|UDS_NOTHOUSANDS, 0, 0, 0, 0
@@ -39,9 +45,12 @@
 FONT 8, "Helv"
 {
 	LTEXT "&Police", -1, 5, 5, 24, 8
-	LISTBOX IDC_FNT_LIST_FONT, 5, 18, 109, 42, LBS_SORT|WS_VSCROLL
-	LTEXT "&Taille", -1, 128, 5, 60, 8
-	LISTBOX IDC_FNT_LIST_SIZE, 128, 18, 50, 60, WS_VSCROLL
+	LISTBOX IDC_FNT_LIST_FONT, 5, 18, 90, 42, LBS_SORT|WS_VSCROLL
+	LTEXT "&Couleur", -1, 100, 5, 50, 8
+	CONTROL "", IDC_FNT_COLOR_FG, "WineConColorPreview", 0L, 100, 18, 48, 16
+	CONTROL "", IDC_FNT_COLOR_BK, "WineConColorPreview", 0L, 100, 40, 48, 16
+	LTEXT "&Taille", -1, 158, 5, 40, 8
+	LISTBOX IDC_FNT_LIST_SIZE, 158, 18, 40, 60, WS_VSCROLL
 	CONTROL "", IDC_FNT_PREVIEW, "WineConFontPreview", 0L, 5, 60, 109, 40
 	LTEXT "", IDC_FNT_FONT_INFO, 128, 76, 80, 18
 }
@@ -68,5 +77,3 @@
 	CONTROL "", IDC_CNF_WIN_HEIGHT_UD, "msctls_updown32", UDS_SETBUDDYINT|UDS_ALIGNRIGHT|UDS_AUTOBUDDY|UDS_ARROWKEYS|UDS_NOTHOUSANDS, 0, 0, 0, 0
 }
 
-
-
diff --git a/programs/wineconsole/wineconsole_res.h b/programs/wineconsole/wineconsole_res.h
index 17c8cba..66afd6b 100644
--- a/programs/wineconsole/wineconsole_res.h
+++ b/programs/wineconsole/wineconsole_res.h
@@ -12,6 +12,9 @@
 #define IDS_SCROLL		0x114
 #define IDS_SEARCH		0x115
 
+#define IDS_DLG_TIT_DEFAULT     0x120
+#define IDS_DLG_TIT_CURRENT     0x121
+
 #define IDS_FNT_DISPLAY		0x200
 #define IDS_FNT_PREVIEW_1	0x201
 #define IDS_FNT_PREVIEW_2	0x202
@@ -27,11 +30,15 @@
 #define IDC_OPT_HIST_SIZE	0x0104
 #define IDC_OPT_HIST_SIZE_UD	0x0105
 #define IDC_OPT_HIST_DOUBLE	0x0106
+#define IDC_OPT_CONF_CTRL       0x0107
+#define IDC_OPT_CONF_SHIFT      0x0108
 
 #define IDC_FNT_LIST_FONT	0x0201
 #define IDC_FNT_LIST_SIZE	0x0202
-#define IDC_FNT_FONT_INFO	0x0203
-#define IDC_FNT_PREVIEW		0x0204
+#define IDC_FNT_COLOR_BK 	0x0203
+#define IDC_FNT_COLOR_FG 	0x0204
+#define IDC_FNT_FONT_INFO	0x0205
+#define IDC_FNT_PREVIEW		0x0206
 
 #define IDC_CNF_SB_WIDTH	0x0301
 #define IDC_CNF_SB_WIDTH_UD	0x0302