? winecfg.patch
Index: En.rc
===================================================================
RCS file: /home/wine/wine/programs/winecfg/En.rc,v
retrieving revision 1.16
diff -u -r1.16 En.rc
--- En.rc	20 Jan 2004 02:07:36 -0000	1.16
+++ En.rc	4 Feb 2004 04:44:36 -0000
@@ -23,24 +23,15 @@
 
 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
 
-IDD_GENERALCFG DIALOGEX 0, 0, 260, 250
+IDD_ABOUTCFG DIALOGEX 0, 0, 260, 250
 STYLE WS_CHILD
 FONT 8, "MS Sans Serif"
 BEGIN
-    COMBOBOX        IDC_WINVER,83,153,158,56,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
-    COMBOBOX        IDC_DOSVER,83,172,158,56,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
-    COMBOBOX        IDC_WINELOOK,83,190,158,56,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
     LTEXT           "Wine Version:",IDC_STATIC,119,17,45,8
     LTEXT           "CVS",IDC_WINEVER,169,17,56,8
-    LTEXT           "Windows Version:",IDC_STATIC,17,155,58,8
-    LTEXT           "Windows Look:",IDC_STATIC,17,193,58,8
-    LTEXT           "DOS Version:",IDC_STATIC,17,173,57,8
     CONTROL         IDB_WINE,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE | 
                     SS_REALSIZEIMAGE | WS_BORDER,15,17,157,111, WS_EX_TRANSPARENT
     LTEXT           "http://www.winehq.org/",IDC_STATIC,119,31,106,8
-    GROUPBOX        "Default Behaviour",IDC_STATIC,8,115,244,97
-    LTEXT           "Wine provides the ability for Windows applications to mimic various Windows versions and styles",
-                    IDC_STATIC,15,128,227,20
     GROUPBOX        "Information",IDC_STATIC,8,4,244,106
     CTEXT           "This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.",
                     IDC_STATIC,119,44,124,59
@@ -50,20 +41,18 @@
 STYLE WS_CHILD | WS_DISABLED
 FONT 8, "MS Sans Serif"
 BEGIN
-    CONTROL         "Configuring global settings",IDC_EDITING_GLOBAL,
-                    "Button",BS_AUTORADIOBUTTON,8,8,244,10 
-    CONTROL         "Configuring application specific setttings",IDC_EDITING_APP,
-  	                  "Button",BS_AUTORADIOBUTTON,8,18,244,10
-
- 
-    LTEXT           "Here you can override the default settings on a per-application basis:",
-                    IDC_STATIC,8,35,244,20
-		    
-    LISTBOX         IDC_LIST_APPS,8,48,244,176,WS_TABSTOP | WS_VSCROLL		    
-		    
-    PUSHBUTTON	    "Add new application...",IDC_ADD_APPDEFAULT,170,226,82,14
-    PUSHBUTTON	    "Remove",IDC_REMOVE_APPDEFAULT,130,226,37,14
-		    
+    GROUPBOX        "Application Settings",IDC_STATIC, 8,4,244,240
+    LTEXT           "Wine provides the ability for Windows applications to mimic various Windows versions and styles",
+                    IDC_STATIC,15,20,227,20
+    CONTROL         "Applications",IDC_APP_TREEVIEW,"SysTreeView32",WS_BORDER | WS_TABSTOP | TVS_LINESATROOT | TVS_HASLINES | TVS_SHOWSELALWAYS | TVS_HASBUTTONS, 15,40,142,145
+    PUSHBUTTON	    "Add application...",IDC_APP_ADDAPP, 163,40,82,60
+    PUSHBUTTON	    "Remove application",IDC_APP_REMOVEAPP, 163,125,82,60
+    LTEXT           "Windows Version:",IDC_STATIC,17,192,58,8
+    LTEXT           "DOS Version:",IDC_STATIC,17,211,57,8
+    LTEXT           "Windows Look:",IDC_STATIC,17,229,58,8
+    COMBOBOX        IDC_WINVER,83,190,158,56,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_DOSVER,83,208,158,56,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_WINELOOK,83,226,158,56,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
 END
 
 IDD_X11DRVCFG DIALOG DISCARDABLE  0, 0, 260, 250
@@ -98,7 +87,7 @@
     GROUPBOX        "DLL Overrides",IDC_STATIC,8,4,244,240
     LTEXT           "Libraries can be specified individually to be either builtin or native. A DLL entry specified as ""*"" pertains to all DLLs not specified explicitly.\n\nBe careful, wrong settings here have the potential to pretty much kill your setup."
                     ,  IDC_STATIC,15,17,228,47
-    CONTROL         "DLL Overrides", IDC_TREE_DLLS, "SysTreeView32", WS_TABSTOP | TVS_LINESATROOT | TVS_HASLINES | TVS_SHOWSELALWAYS | TVS_HASBUTTONS, 15,65,142,172
+    CONTROL         "DLL Overrides", IDC_TREE_DLLS, "SysTreeView32", WS_BORDER | WS_TABSTOP | TVS_LINESATROOT | TVS_HASLINES | TVS_SHOWSELALWAYS | TVS_HASBUTTONS, 15,65,142,172
     LTEXT           "Load order:",IDC_STATIC,163,65,37,8
     CONTROL         "Builtin (Wine)",IDC_RAD_BUILTIN,"Button", BS_AUTORADIOBUTTON | WS_GROUP,163,80,57,10
     CONTROL         "Native (Windows)",IDC_RAD_NATIVE,"Button", BS_AUTORADIOBUTTON,163,95,72,10
Index: Es.rc
===================================================================
RCS file: /home/wine/wine/programs/winecfg/Es.rc,v
retrieving revision 1.5
diff -u -r1.5 Es.rc
--- Es.rc	7 Jan 2004 00:43:40 -0000	1.5
+++ Es.rc	4 Feb 2004 04:44:36 -0000
@@ -49,11 +49,6 @@
 STYLE WS_CHILD | WS_DISABLED
 FONT 8, "MS Sans Serif"
 BEGIN
-    CONTROL         "List2",IDC_LIST_APPS,"SysListView32",LVS_LIST | 
-                    LVS_NOLABELWRAP | WS_BORDER | WS_TABSTOP,16,39,226,108
-    GROUPBOX        "Configuraci�n espec�fica de aplicaciones",IDC_STATIC,8,4,244,151
-    LTEXT           "Esta configuraci�n le permite sobreponerse a la configuraci�n por defecto de Wine (como est� especificada en otras pesta�as de configuraci�n) para aplicaciones concretas.",
-                    IDC_STATIC,15,17,228,20
 END
 
 IDD_X11DRVCFG DIALOG DISCARDABLE  0, 0, 260, 250
Index: Pt.rc
===================================================================
RCS file: /home/wine/wine/programs/winecfg/Pt.rc,v
retrieving revision 1.6
diff -u -r1.6 Pt.rc
--- Pt.rc	18 Jan 2004 23:18:33 -0000	1.6
+++ Pt.rc	4 Feb 2004 04:44:37 -0000
@@ -48,18 +48,6 @@
 STYLE WS_CHILD | WS_DISABLED
 FONT 8, "MS Sans Serif"
 BEGIN
-    CONTROL         "Configura��es globais",IDC_EDITING_GLOBAL,
-                    "Button",BS_AUTORADIOBUTTON,8,8,244,10 
-    CONTROL         "Configura��es espec�ficas da aplica��o",IDC_EDITING_APP,
-	            "Button",BS_AUTORADIOBUTTON,8,18,244,10
-
-    LTEXT           "Sobreescreva aqui as configura��es padr�es para cada aplica��o:",
-                    IDC_STATIC,8,35,244,20
-		    
-    LISTBOX         IDC_LIST_APPS,8,48,244,176,WS_TABSTOP | WS_VSCROLL		    
-		    
-    PUSHBUTTON	    "Adionar nova aplica��o...",IDC_ADD_APPDEFAULT,170,226,82,14
-    PUSHBUTTON	    "Remover",IDC_REMOVE_APPDEFAULT,130,226,37,14
 END
 
 IDD_X11DRVCFG DIALOG DISCARDABLE  0, 0, 260, 250
Index: Ru.rc
===================================================================
RCS file: /home/wine/wine/programs/winecfg/Ru.rc,v
retrieving revision 1.3
diff -u -r1.3 Ru.rc
--- Ru.rc	7 Jan 2004 00:43:40 -0000	1.3
+++ Ru.rc	4 Feb 2004 04:44:38 -0000
@@ -62,11 +62,6 @@
 STYLE WS_CHILD | WS_DISABLED
 FONT 8, "MS Sans Serif"
 BEGIN
-    CONTROL         "List2",IDC_LIST_APPS,"SysListView32",LVS_LIST | 
-                    LVS_NOLABELWRAP | WS_BORDER | WS_TABSTOP,16,39,226,108
-    GROUPBOX        "����������� ��������� ��� ����������",IDC_STATIC,8,4,244,151
-    LTEXT           "��� ��������� ��������� �������������� ��������� Wine �� ��������� (������������ � ������ ��������) ��� ������� ����������� ����������.",
-                    IDC_STATIC,15,17,228,20
 END
 
 IDD_X11DRVCFG DIALOG DISCARDABLE  0, 0, 260, 250
Index: Si.rc
===================================================================
RCS file: /home/wine/wine/programs/winecfg/Si.rc,v
retrieving revision 1.4
diff -u -r1.4 Si.rc
--- Si.rc	7 Jan 2004 00:43:40 -0000	1.4
+++ Si.rc	4 Feb 2004 04:44:38 -0000
@@ -49,11 +49,6 @@
 STYLE WS_CHILD | WS_DISABLED
 FONT 8, "MS Sans Serif"
 BEGIN
-    CONTROL         "List2",IDC_LIST_APPS,"SysListView32",LVS_LIST | 
-                    LVS_NOLABELWRAP | WS_BORDER | WS_TABSTOP,16,39,226,108
-    GROUPBOX        "Application Specific Setting",IDC_STATIC,8,4,244,151
-    LTEXT           "These settings allow you to overwrite Wine default settings (as specified in other configuration tabs) on a per-application basis.",
-                    IDC_STATIC,15,17,228,20
 END
 
 IDD_X11DRVCFG DIALOG DISCARDABLE  0, 0, 260, 250
Index: appdefaults.c
===================================================================
RCS file: /home/wine/wine/programs/winecfg/appdefaults.c,v
retrieving revision 1.2
diff -u -r1.2 appdefaults.c
--- appdefaults.c	22 Oct 2003 00:01:46 -0000	1.2
+++ appdefaults.c	4 Feb 2004 04:44:39 -0000
@@ -1,7 +1,8 @@
 /*
- * Application defaults page
+ * WineCfg app settings tabsheet
  *
- * Copyright 2003 Mike Hearn
+ * Copyright 2004 Robert van Herk
+ *                Chris Morgan
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -19,140 +20,619 @@
  *
  */
 
+#define NONAMELESSUNION
+#include <windows.h>
+#include <commdlg.h>
+#include <wine/debug.h>
 #include <stdio.h>
-
 #include "winecfg.h"
-#include <windef.h>
-#include <winbase.h>
-#include <winreg.h>
-#include <wine/debug.h>
-
 #include "resource.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(winecfg);
 
-int appSettings = EDITING_GLOBAL; /* start by editing global */
-char *currentApp; /* the app we are currently editing, or NULL if editing global */
+typedef struct _APPL
+{
+  BOOL isGlobal;
+  char* lpcApplication;
+  char* lpcVersionSection;
+  char* lpcWinelookSection;
+} APPL, *LPAPPL;
 
-static int needToRefresh = 1;
+static LPAPPL CreateAppl(BOOL isGlobal, char* application, char* version_section, char* winelook_section)
+{
+  LPAPPL out;
+  WINE_TRACE("application: '%s', version_section: '%s', winelook_section: '%s'\n", application,
+	     version_section, winelook_section);
+  out = HeapAlloc(GetProcessHeap(),0,sizeof(APPL));
+  out->lpcApplication = strdup(application);
+  out->lpcVersionSection = strdup(version_section);
+  out->lpcWinelookSection = strdup(winelook_section);
+  out->isGlobal = isGlobal;
+  return out;
+}
 
-char *getSectionForApp(char *section) {
-    static char *lastResult = NULL;
-    if (lastResult) HeapFree(GetProcessHeap(), 0, lastResult);
-    lastResult = HeapAlloc(GetProcessHeap(), 0, strlen("AppDefaults\\") + strlen(currentApp) + 2 /* \\ */ + strlen(section) + 1 /* terminator */);
-    sprintf(lastResult, "AppDefaults\\%s\\%s", currentApp, section);
-    return lastResult;
-}
-
-static void configureFor(HWND dialog, int mode) {
-    CheckRadioButton(dialog, IDC_EDITING_GLOBAL, IDC_EDITING_APP, mode == EDITING_APP ? IDC_EDITING_APP : IDC_EDITING_GLOBAL);
-    if (mode == EDITING_GLOBAL) {
-	disable(IDC_LIST_APPS);
-	disable(IDC_ADD_APPDEFAULT);
-	disable(IDC_REMOVE_APPDEFAULT);
-    } else {
-	enable(IDC_LIST_APPS);
-	enable(IDC_ADD_APPDEFAULT);
-	enable(IDC_REMOVE_APPDEFAULT);
-    }
-    appSettings = mode;
-}
-
-/* fill the dialog with the current appdefault entries */
-static void refreshDialog(HWND dialog) {
-    HKEY key;
-    char *subKeyName = HeapAlloc(GetProcessHeap(), 0, MAX_NAME_LENGTH);
-    DWORD sizeOfSubKeyName = MAX_NAME_LENGTH;
-    int i, itemIndex;
-    
-    WINE_TRACE("\n");
-    
-    /* Clear the listbox */
-    SendMessageA(GetDlgItem(dialog, IDC_LIST_APPS), LB_RESETCONTENT, 0, 0);
-
-    return_if_fail(
-	RegCreateKey(HKEY_LOCAL_MACHINE, WINE_KEY_ROOT "\\AppDefaults", &key) == ERROR_SUCCESS
-    );
-    
-    /* Iterate over each subkey in the AppDefaults tree */
-    for (i = 0;
-	 RegEnumKeyEx(key, i, subKeyName, &sizeOfSubKeyName, NULL, NULL, NULL, NULL ) != ERROR_NO_MORE_ITEMS;
-	 ++i, sizeOfSubKeyName = MAX_NAME_LENGTH) {
-
-	WINE_TRACE("appdefault entry=%s\n", subKeyName);
-	itemIndex = SendMessageA(GetDlgItem(dialog, IDC_LIST_APPS), LB_ADDSTRING ,(WPARAM) -1, (LPARAM) subKeyName);
-    }
-
-    configureFor(dialog, appSettings);
-
-    WINE_TRACE("done\n");
-    RegCloseKey(key);
-    HeapFree(GetProcessHeap(), 0, subKeyName);
-
-}
-
-static void onAppsListSelChange(HWND dialog) {
-    int newPos = SendDlgItemMessage(dialog, IDC_LIST_APPS, LB_GETCURSEL, 0, 0);
-    int appLen = SendDlgItemMessage(dialog, IDC_LIST_APPS, LB_GETTEXTLEN, newPos, 0);
-    if (currentApp) HeapFree(GetProcessHeap(), 0, currentApp);
-    currentApp = HeapAlloc(GetProcessHeap(), 0, appLen+1);
-    return_if_fail(
-	SendDlgItemMessage(dialog, IDC_LIST_APPS, LB_GETTEXT, newPos, (LPARAM) currentApp) != LB_ERR
-    );
-    WINE_TRACE("new selection is %s\n", currentApp);
+static VOID FreeAppl(LPAPPL lpAppl)
+{
+ /* The strings were strdup-ped, so we use "free" */
+  if (lpAppl->lpcApplication) free(lpAppl->lpcApplication);
+  if (lpAppl->lpcVersionSection) free(lpAppl->lpcVersionSection);
+  if (lpAppl->lpcWinelookSection) free(lpAppl->lpcWinelookSection);
+  HeapFree(GetProcessHeap(),0,lpAppl);
 }
 
-INT_PTR CALLBACK
-AppDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+/* section can be "Version" or "Tweak.Layout" */
+/* key can be "Windows"/"Dos"/"WineLook" */
+/* value can be appropriate values for the above keys */
+typedef struct _APPSETTING
+{
+  char* section;
+  char* lpcKey;
+  char* value;
+} APPSETTING, *LPAPPSETTING;
+
+static LPAPPSETTING CreateAppSetting(char* lpcKey, char* value)
+{
+	LPAPPSETTING out = HeapAlloc(GetProcessHeap(),0,sizeof(APPSETTING));
+	out->lpcKey = strdup (lpcKey);
+	out->value = strdup(value);
+	return out;
+}
+
+static VOID FreeAppSetting(LPAPPSETTING las)
+{
+  if (las->lpcKey) free(las->lpcKey);
+  if (las->value) free(las->value);
+  HeapFree(GetProcessHeap(),0,las);
+}
+
+typedef struct _ITEMTAG
+{
+  LPAPPL lpAppl;
+  LPAPPSETTING lpSetting;
+} ITEMTAG, *LPITEMTAG;
+
+static LPITEMTAG CreateItemTag()
+{
+  LPITEMTAG out;
+  out = HeapAlloc(GetProcessHeap(),0,sizeof(ITEMTAG));
+  out->lpAppl = 0;
+  out->lpSetting = 0;
+  return out;
+}
+
+static VOID FreeItemTag(LPITEMTAG lpit)
+{
+  /* if child, only free the lpSetting, the lpAppl will be freed when we free the parents item tag */
+  if (lpit->lpSetting)
+  {
+    FreeAppSetting(lpit->lpSetting);
+  } else
+  {
+    if (lpit->lpAppl)
+      FreeAppl(lpit->lpAppl);
+  }
+  HeapFree(GetProcessHeap(), 0, lpit);
+}
+
+static VOID LoadAppSettings(LPAPPL appl /*DON'T FREE, treeview will own this*/, HWND hDlg, HWND hwndTV)
+{
+  HKEY key;
+  int i;
+  DWORD size;
+  DWORD readSize;
+  char name [255];
+  char read [255];
+  char *description;
+  LPITEMTAG lpIt;
+  TVINSERTSTRUCT tis;	
+  HTREEITEM hParent;
+  LPAPPSETTING lpas;
+	
+  WINE_TRACE("opening '%s' and '%s'\n", appl->lpcVersionSection, appl->lpcWinelookSection);
+  if ((RegOpenKey (configKey, appl->lpcVersionSection, &key) == ERROR_SUCCESS) ||
+      (RegOpenKey (configKey, appl->lpcWinelookSection, &key) == ERROR_SUCCESS))
+  {
+     i = 0;
+     size = 255;
+     readSize = 255;
+
+     lpIt = CreateItemTag();
+     lpIt->lpAppl = appl;
+
+     tis.hParent = NULL;
+     tis.hInsertAfter = TVI_LAST;
+     tis.u.item.mask = TVIF_TEXT | TVIF_PARAM;
+     tis.u.item.pszText = appl->lpcApplication;
+     tis.u.item.lParam = (LPARAM)lpIt;
+     hParent = TreeView_InsertItem(hwndTV,&tis);
+     tis.hParent = hParent;
+
+     /* insert version entries */
+     if(RegOpenKey (configKey, appl->lpcVersionSection, &key) == ERROR_SUCCESS)
+     {
+       while (RegEnumValue(key, i, name, &size, NULL, NULL, read, &readSize) == ERROR_SUCCESS)
+       {
+	 char itemtext[128];
+
+	 WINE_TRACE("Reading value %s, namely %s\n", name, read);
+			
+	 lpIt = CreateItemTag();
+	 lpas = CreateAppSetting(name, read);
+	 lpIt->lpSetting = lpas;
+	 lpIt->lpAppl = appl;
+	 tis.u.item.lParam = (LPARAM)lpIt;
+
+	 /* convert the value for 'dosver or winver' to human readable form */
+	 description = getDescriptionFromVersion(getWinVersions(), read);
+	 if(!description)
+	 {
+	   description = getDescriptionFromVersion(getDOSVersions(), read);
+	   if(!description)
+	     description = "Not found";
+	 }
+
+	 sprintf(itemtext, "%s - %s", name, description);
+	 tis.u.item.pszText = itemtext;
+
+	 TreeView_InsertItem(hwndTV,&tis);
+	 i++; size = 255; readSize = 255;
+       }
+       RegCloseKey(key);
+     } else
+     {
+       WINE_TRACE("no version section found\n");
+     }
+
+     i = 0; /* reset i to 0 before calling RegEnumValue() again */
+
+     /* insert winelook entries */
+     if(RegOpenKey (configKey, appl->lpcWinelookSection, &key) == ERROR_SUCCESS)
+     {
+       while (RegEnumValue(key, i, name, &size, NULL, NULL, read, &readSize) == ERROR_SUCCESS)
+       {
+	 char itemtext[128];
+
+	 WINE_TRACE("Reading value %s, namely %s\n", name, read);
+			
+	 lpIt = CreateItemTag();
+	 lpas = CreateAppSetting(name, read);
+	 lpIt->lpSetting = lpas;
+	 lpIt->lpAppl = appl;
+	 tis.u.item.lParam = (LPARAM)lpIt;
+
+	 /* convert the value for 'winelook' to human readable form */
+	 description = getDescriptionFromVersion(getWinelook(), read);
+	 if(!description) description = "Not found";
+	 
+	 sprintf(itemtext, "%s - %s", name, description);
+	 tis.u.item.pszText = itemtext;
+
+	 TreeView_InsertItem(hwndTV,&tis);
+	 i++; size = 255; readSize = 255;
+       }
+       RegCloseKey(key);
+     } else
+     {
+       WINE_TRACE("no winelook section found\n");
+     }
+  }
+}
+
+static VOID SetEnabledAppControls(HWND dialog)
 {
-    switch (uMsg)
+}
+
+static VOID UpdateComboboxes(HWND hDlg, LPAPPL lpAppl)
+{
+  int i;
+  const VERSION_DESC *pVer = NULL;
+
+  /* retrieve the registry values for this application */
+  char *curWinVer = getConfigValue(lpAppl->lpcVersionSection, "Windows", "");
+  char *curDOSVer = getConfigValue(lpAppl->lpcVersionSection, "DOS", "");
+  char *curWineLook = getConfigValue(lpAppl->lpcWinelookSection, "WineLook", "");
+
+  if(curWinVer) WINE_TRACE("curWinVer is '%s'\n", curWinVer);
+  else WINE_TRACE("curWinVer is null\n");
+  if(curDOSVer) WINE_TRACE("curDOSVer is '%s'\n", curDOSVer);
+  else WINE_TRACE("curDOSVer is null\n");
+  if(curWineLook) WINE_TRACE("curWineLook is '%s'\n", curWineLook);
+  else WINE_TRACE("curWineLook is null\n");
+
+  /* normalize the version strings */
+  if(strlen(curWinVer) != 0)
+  {
+    if ((pVer = getWinVersions ()))
     {
-	case WM_COMMAND: switch (LOWORD(wParam)) {
-	    case IDC_EDITING_APP:
-		if (SendDlgItemMessage(hDlg, IDC_LIST_APPS, LB_GETCURSEL, 0, 0) == LB_ERR) {
-		    /* no selection, so select the first one */
-		    SendDlgItemMessage(hDlg, IDC_LIST_APPS, LB_SETCURSEL, 0, 0);
-		    onAppsListSelChange(hDlg);
-		}
-		configureFor(hDlg, EDITING_APP);
-		break;
-	    case IDC_EDITING_GLOBAL:
-		configureFor(hDlg, EDITING_GLOBAL);
-		break;
-	    case IDC_ADD_APPDEFAULT:
-		WRITEME(hDlg);
-		refreshDialog(hDlg);
-		break;
-	    case IDC_REMOVE_APPDEFAULT:
-		WRITEME(hDlg);
-		refreshDialog(hDlg);
-		break;
-	    case IDC_LIST_APPS:
-		if (HIWORD(wParam) == LBN_SELCHANGE) onAppsListSelChange(hDlg);
-		break;
+      WINE_TRACE("Windows version\n");
+      for (i = 0; *pVer->szVersion || *pVer->szDescription; i++, pVer++)
+      {
+	WINE_TRACE("pVer->szVersion == %s\n", pVer->szVersion);
+	if (!strcasecmp (pVer->szVersion, curWinVer))
+	{
+	  SendDlgItemMessage (hDlg, IDC_WINVER, CB_SETCURSEL,
+			      (WPARAM) i, 0);
+	  WINE_TRACE("match with %s\n", pVer->szVersion);
 	}
-	break;
+      }
+    }
+  } else /* clear selection */
+  {
+    WINE_TRACE("setting winver to nothing\n");
+    SendDlgItemMessage (hDlg, IDC_WINVER, CB_SETCURSEL,
+			-1, 0);
+  }
+
+  if(strlen(curDOSVer) != 0)
+  {
+    if ((pVer = getDOSVersions ()))
+    {
+      WINE_TRACE("DOS version\n");
+      for (i = 0; *pVer->szVersion || *pVer->szDescription; i++, pVer++)
+      {
+	WINE_TRACE("pVer->szVersion == %s\n", pVer->szVersion);
+	if (!strcasecmp (pVer->szVersion, curDOSVer))
+	{
+	  SendDlgItemMessage (hDlg, IDC_DOSVER, CB_SETCURSEL,
+			      (WPARAM) i, 0);
+	  WINE_TRACE("match with %s\n", pVer->szVersion);
+	}
+      }
+    }
+  } else
+  {
+    WINE_TRACE("setting dosver to nothing\n");
+    SendDlgItemMessage (hDlg, IDC_DOSVER, CB_SETCURSEL,
+			-1, 0);
+  }
+
+  if(strlen(curWineLook) != 0)
+  {
+    if ((pVer = getWinelook ()))
+    {
+      WINE_TRACE("Winelook\n");
 
-	case WM_NOTIFY: switch(((LPNMHDR)lParam)->code) {
-	    case PSN_KILLACTIVE:
-		SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
-		break;
-	    case PSN_APPLY:
-		SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
-		break;
-	    case PSN_SETACTIVE:
-		if (needToRefresh) {
-		    refreshDialog(hDlg);
-		    needToRefresh = 0;
-		}
-		break;
+      for (i = 0; *pVer->szVersion || *pVer->szDescription; i++, pVer++)
+      {
+	WINE_TRACE("pVer->szVersion == %s\n", pVer->szVersion);
+	if (!strcasecmp (pVer->szVersion, curWineLook))
+	{
+	  SendDlgItemMessage (hDlg, IDC_WINELOOK, CB_SETCURSEL,
+			      (WPARAM) i, 0);
+	  WINE_TRACE("match with %s\n", pVer->szVersion);
 	}
-	break;
+      }
+    }
+  } else
+  {
+    WINE_TRACE("setting winelook to nothing\n");
+    SendDlgItemMessage (hDlg, IDC_WINELOOK, CB_SETCURSEL,
+			      -1, 0);
+  }
+
+  if(curWinVer) free(curWinVer);
+  if(curDOSVer) free(curDOSVer);
+  if(curWineLook) free(curWineLook);
+}
+
+void
+initAppDlgComboboxes (HWND hDlg)
+{
+  int i;
+  const VERSION_DESC *pVer = NULL;
+
+  if ((pVer = getWinVersions ()))
+  {
+    for (i = 0; *pVer->szVersion || *pVer->szDescription; i++, pVer++)
+    {
+      SendDlgItemMessage (hDlg, IDC_WINVER, CB_ADDSTRING,
+			  0, (LPARAM) pVer->szDescription);
+    }
+  }
+  if ((pVer = getDOSVersions ()))
+  {
+    for (i = 0; *pVer->szVersion || *pVer->szDescription ; i++, pVer++)
+    {
+      SendDlgItemMessage (hDlg, IDC_DOSVER, CB_ADDSTRING,
+			  0, (LPARAM) pVer->szDescription);
+    }
+  }
+  if ((pVer = getWinelook ()))
+  {
+    for (i = 0; *pVer->szVersion || *pVer->szDescription; i++, pVer++)
+    {
+      SendDlgItemMessage (hDlg, IDC_WINELOOK, CB_ADDSTRING,
+			  0, (LPARAM) pVer->szDescription);
+    }
+  }
+}
+
+
+static VOID OnInitAppDlg(HWND hDlg)
+{
+  HWND hwndTV;
+  LPAPPL lpAppl;
+  HKEY applKey;
+  int i;
+  DWORD size;
+  char appl [255];
+  char lpcVersionKey [255];
+  char lpcWinelookKey [255];
+  FILETIME ft;
+
+  hwndTV = GetDlgItem(hDlg,IDC_APP_TREEVIEW);
+  lpAppl = CreateAppl(TRUE, "Global Settings", "Version", "Tweak.Layout");
+  LoadAppSettings(lpAppl, hDlg, hwndTV);
+	
+  /*And now the application specific stuff:*/
+  if (RegOpenKey(configKey, "AppDefaults", &applKey) == ERROR_SUCCESS)
+  {
+    i = 0;
+    size = 255;
+    while (RegEnumKeyEx(applKey, i, appl, &size, NULL, NULL, NULL, &ft) == ERROR_SUCCESS)
+    {
+      sprintf(lpcVersionKey, "AppDefaults\\%s\\Version", appl);
+      sprintf(lpcWinelookKey, "AppDefaults\\%s\\Tweak.Layout", appl);
+      lpAppl = CreateAppl(FALSE, appl, lpcVersionKey, lpcWinelookKey);
+      LoadAppSettings(lpAppl, hDlg, hwndTV);
+      i++; size = 255;
+    }
+    RegCloseKey(applKey);
+  }
+  SetEnabledAppControls(hDlg);
+}
+
+static VOID OnTreeViewChangeItem(HWND hDlg, HWND hTV)
+{
+  TVITEM ti;
+  LPITEMTAG lpit;
 
-	case WM_INITDIALOG:
-	    WINE_TRACE("Init appdefaults\n");
-	    break;
-	    
+  ti.mask = TVIF_PARAM;
+  ti.hItem = TreeView_GetSelection(hTV);
+  if (TreeView_GetItem (hTV, &ti))
+  {
+    lpit = (LPITEMTAG) ti.lParam;
+    if (lpit->lpAppl)
+    {
+      WINE_TRACE("lpit->lpAppl is non-null\n");
+      /* update comboboxes to reflect settings for this app */
+      UpdateComboboxes(hDlg, lpit->lpAppl);
+    } else
+    {
+      WINE_TRACE("lpit->lpAppl is null\n");
     }
-    return FALSE;
+  }
+}
+
+static VOID OnTreeViewDeleteItem(NMTREEVIEW* nmt)
+{
+  FreeItemTag((LPITEMTAG)(nmt->itemOld.lParam));
+}
+
+static VOID OnAddApplicationClick(HWND hDlg)
+{
+  char szFileTitle [255];
+  char szFile [255];
+  char lpcVersionKey [255];
+  char lpcWinelookKey [255];
+
+  TVINSERTSTRUCT tis;
+  LPITEMTAG lpit;
+  OPENFILENAME ofn = { sizeof(OPENFILENAME),
+		       0, /*hInst*/0, "Wine Programs (*.exe,*.exe.so)\0*.exe;*.exe.so\0", NULL, 0, 0, NULL,
+		       0, NULL, 0, NULL, NULL,
+		       OFN_SHOWHELP, 0, 0, NULL, 0, NULL };
+
+  ofn.lpstrFileTitle = szFileTitle;
+  ofn.lpstrFileTitle[0] = '\0';
+  ofn.nMaxFileTitle = sizeof(szFileTitle);
+  ofn.lpstrFile = szFile;
+  ofn.lpstrFile[0] = '\0';
+  ofn.nMaxFile = sizeof(szFile);
+
+  if (GetOpenFileName(&ofn))
+  {
+    tis.hParent = NULL;
+    tis.hInsertAfter = TVI_LAST;
+    tis.u.item.mask = TVIF_TEXT | TVIF_PARAM;
+    tis.u.item.pszText = szFileTitle;
+    lpit = CreateItemTag();
+    sprintf(lpcVersionKey, "AppDefaults\\%s\\Version", szFileTitle);
+    sprintf(lpcWinelookKey, "AppDefaults\\%s\\Tweak.Layout", szFileTitle);
+    lpit->lpAppl = CreateAppl(FALSE, szFileTitle, lpcVersionKey, lpcWinelookKey);
+    tis.u.item.lParam = (LPARAM)lpit;
+    TreeView_InsertItem(GetDlgItem(hDlg, IDC_APP_TREEVIEW), &tis);
+
+    /* add the empty entries for the Version and Winelook sections for this app */
+    setConfigValue(lpcVersionKey,NULL,NULL);
+    setConfigValue(lpcWinelookKey,NULL,NULL);
+  }
+}
+
+static VOID OnRemoveApplicationClick(HWND hDlg)
+{
+  HWND hTV;
+  TVITEM ti;
+  LPITEMTAG lpit;
+
+  hTV = GetDlgItem(hDlg, IDC_APP_TREEVIEW);
+  ti.mask = TVIF_PARAM;
+  ti.hItem = TreeView_GetSelection(hTV);
+  if (TreeView_GetItem (hTV, &ti))
+  {
+    lpit = (LPITEMTAG) ti.lParam;
+    if (lpit->lpAppl)
+    {
+      /* add transactions to remove all entries for this application */
+      addTransaction(lpit->lpAppl->lpcVersionSection, NULL, ACTION_REMOVE, NULL);
+      addTransaction(lpit->lpAppl->lpcWinelookSection, NULL, ACTION_REMOVE, NULL);
+      TreeView_DeleteItem(hTV,ti.hItem);
+    }
+  }
+}
+
+static void UpdateWinverSelection(HWND hDlg, int selection)
+{
+  TVITEM ti;
+  LPITEMTAG lpit;
+  VERSION_DESC *pVer = NULL;
+  HWND hTV = GetDlgItem(hDlg, IDC_APP_TREEVIEW);
+
+  ti.mask = TVIF_PARAM;
+  ti.hItem = TreeView_GetSelection(hTV);
+  if (TreeView_GetItem (hTV, &ti))
+  {
+    lpit = (LPITEMTAG) ti.lParam;
+
+    if(lpit->lpAppl)
+    {
+      pVer = getWinVersions();
+
+      /* if no item is selected OR if our version string is null */
+      /* remove this applications setting */
+      if((selection == CB_ERR) || !(*pVer[selection].szVersion))
+      {
+	WINE_TRACE("removing section '%s'\n", lpit->lpAppl->lpcWinelookSection);
+	addTransaction(lpit->lpAppl->lpcVersionSection, "Windows", ACTION_REMOVE, NULL); /* change registry entry */
+      } else
+      {
+	WINE_TRACE("setting section '%s', key '%s', value '%s'\n", lpit->lpAppl->lpcVersionSection, "Windows", pVer[selection].szVersion);
+	addTransaction(lpit->lpAppl->lpcVersionSection, "Windows", ACTION_SET, pVer[selection].szVersion); /* change registry entry */
+      }
+
+      TreeView_DeleteAllItems(hTV); /* delete all items from the treeview */
+      OnInitAppDlg(hDlg);
+    }
+  }
+}
+
+static void UpdateDosverSelection(HWND hDlg, int selection)
+{
+  TVITEM ti;
+  LPITEMTAG lpit;
+  VERSION_DESC *pVer = NULL;
+  HWND hTV = GetDlgItem(hDlg, IDC_APP_TREEVIEW);
+
+  ti.mask = TVIF_PARAM;
+  ti.hItem = TreeView_GetSelection(hTV);
+  if (TreeView_GetItem (hTV, &ti))
+  {
+    lpit = (LPITEMTAG) ti.lParam;
+
+    if(lpit->lpAppl)
+    {
+      pVer = getDOSVersions();
+
+      /* if no item is selected OR if our version string is null */
+      /* remove this applications setting */
+      if((selection == CB_ERR) || !(*pVer[selection].szVersion))
+      {
+	WINE_TRACE("removing section '%s'\n", lpit->lpAppl->lpcWinelookSection);
+	addTransaction(lpit->lpAppl->lpcVersionSection, "DOS", ACTION_REMOVE, NULL); /* change registry entry */
+      } else
+      {
+	WINE_TRACE("setting section '%s', key '%s', value '%s'\n", lpit->lpAppl->lpcVersionSection, "DOS", pVer[selection].szVersion);
+	addTransaction(lpit->lpAppl->lpcVersionSection, "DOS", ACTION_SET, pVer[selection].szVersion); /* change registry entry */
+      }
+
+      TreeView_DeleteAllItems(hTV); /* delete all items from the treeview */
+      OnInitAppDlg(hDlg);
+    }
+  }
+}
+
+static void UpdateWinelookSelection(HWND hDlg, int selection)
+{
+  TVITEM ti;
+  LPITEMTAG lpit;
+  VERSION_DESC *pVer = NULL;
+  HWND hTV = GetDlgItem(hDlg, IDC_APP_TREEVIEW);
+
+  ti.mask = TVIF_PARAM;
+  ti.hItem = TreeView_GetSelection(hTV);
+  if (TreeView_GetItem (hTV, &ti))
+  {
+    lpit = (LPITEMTAG) ti.lParam;
+
+    if(lpit->lpAppl)
+    {
+      pVer = getWinelook();
+
+      /* if no item is selected OR if our version string is null */
+      /* remove this applications setting */
+      if((selection == CB_ERR) || !(*pVer[selection].szVersion))
+      {
+	WINE_TRACE("removing section '%s'\n", lpit->lpAppl->lpcWinelookSection);
+	addTransaction(lpit->lpAppl->lpcWinelookSection, "WineLook", ACTION_REMOVE, NULL); /* change registry entry */
+      } else
+      {
+	WINE_TRACE("setting section '%s', key '%s', value '%s'\n", lpit->lpAppl->lpcWinelookSection, "WineLook", pVer[selection].szVersion);
+	addTransaction(lpit->lpAppl->lpcWinelookSection, "WineLook", ACTION_SET, pVer[selection].szVersion); /* change registry entry */
+      }
+
+      TreeView_DeleteAllItems(hTV); /* delete all items from the treeview */
+      OnInitAppDlg(hDlg);
+    }
+  }
+}
+
+
+
+INT_PTR CALLBACK
+AppDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+  int selection;
+  switch (uMsg)
+  {
+  case WM_INITDIALOG:
+    OnInitAppDlg(hDlg);
+    initAppDlgComboboxes(hDlg);
+    break;  
+  case WM_NOTIFY:
+    switch (((LPNMHDR)lParam)->code) {
+    case TVN_SELCHANGED: {
+      switch(LOWORD(wParam)) {
+      case IDC_APP_TREEVIEW:
+	OnTreeViewChangeItem(hDlg, GetDlgItem(hDlg,IDC_APP_TREEVIEW));
+	break;
+      }
+    }
+      break;
+    case TVN_DELETEITEM:
+      OnTreeViewDeleteItem ((LPNMTREEVIEW)lParam);
+      break;
+    }
+    break;
+  case WM_COMMAND:
+    switch(HIWORD(wParam)) {
+    case CBN_SELCHANGE:
+      switch(LOWORD(wParam)) {
+      case IDC_WINVER:
+	selection = SendDlgItemMessage( hDlg, IDC_WINVER, CB_GETCURSEL, 0, 0);
+	UpdateWinverSelection(hDlg, selection);
+	break;
+      case IDC_DOSVER:
+	selection = SendDlgItemMessage( hDlg, IDC_DOSVER, CB_GETCURSEL, 0, 0);
+	UpdateDosverSelection(hDlg, selection);
+	break;
+      case IDC_WINELOOK:
+	selection = SendDlgItemMessage( hDlg, IDC_WINELOOK, CB_GETCURSEL, 0, 0);
+	UpdateWinelookSelection(hDlg, selection);
+	break;
+      }
+    case BN_CLICKED:
+      switch(LOWORD(wParam)) {
+      case IDC_APP_ADDAPP:
+	OnAddApplicationClick(hDlg);
+	break;
+      case IDC_APP_REMOVEAPP:
+	OnRemoveApplicationClick(hDlg);
+	break;
+      }
+      break;
+    }
+    break;
+  }
+
+  return 0;
 }
Index: main.c
===================================================================
RCS file: /home/wine/wine/programs/winecfg/main.c,v
retrieving revision 1.13
diff -u -r1.13 main.c
--- main.c	20 Jan 2004 02:07:36 -0000	1.13
+++ main.c	4 Feb 2004 04:44:39 -0000
@@ -36,10 +36,6 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(winecfg);
 
-
-#define versionSection (appSettings == EDITING_GLOBAL ? "Version" : (getSectionForApp("Version")))
-#define tweakSection (appSettings == EDITING_GLOBAL ? "Tweak.Layout" : (getSectionForApp("Tweak.Layout")))
-
 void CALLBACK
 PropSheetCallback (HWND hWnd, UINT uMsg, LPARAM lParam)
 {
@@ -59,67 +55,8 @@
     }
 }
 
-void
-initGeneralDlg (HWND hDlg)
-{
-    int i;
-    const VERSION_DESC *pVer = NULL;
-    char *curWinVer = getConfigValue(versionSection, "Windows", "win98");
-    char *curDOSVer = getConfigValue(versionSection, "DOS", "6.22");
-    char *curWineLook = getConfigValue(tweakSection, "WineLook", "win95");
-
-    /* normalize the version strings */
-    if (!strcmp(curWinVer, "win2000") || !strcmp(curWinVer, "nt2k") || !strcmp(curWinVer, "nt2000")) {
-	free(curWinVer);
-	curWinVer = strdup("win2k");
-    }
-
-    if (!strcmp(curWinVer, "win2k3")) {
-	free(curWinVer);
-	curWinVer = strdup("win2003");
-    }
-    
-    if ((pVer = getWinVersions ()))
-    {
-	for (i = 0; *pVer->szVersion; i++, pVer++)
-	{
-	    SendDlgItemMessage (hDlg, IDC_WINVER, CB_ADDSTRING,
-				0, (LPARAM) pVer->szDescription);
-	    if (!strcmp (pVer->szVersion, curWinVer))
-		SendDlgItemMessage (hDlg, IDC_WINVER, CB_SETCURSEL,
-				    (WPARAM) i, 0);
-	}
-    }
-    if ((pVer = getDOSVersions ()))
-    {
-	for (i = 0; *pVer->szVersion; i++, pVer++)
-	{
-	    SendDlgItemMessage (hDlg, IDC_DOSVER, CB_ADDSTRING,
-				0, (LPARAM) pVer->szDescription);
-	    if (!strcmp (pVer->szVersion, curDOSVer))
-		SendDlgItemMessage (hDlg, IDC_DOSVER, CB_SETCURSEL,
-				    (WPARAM) i, 0);
-	}
-    }
-    if ((pVer = getWinelook ()))
-    {
-	for (i = 0; *pVer->szVersion; i++, pVer++)
-	{
-	    SendDlgItemMessage (hDlg, IDC_WINELOOK, CB_ADDSTRING,
-				0, (LPARAM) pVer->szDescription);
-	    if (!strcmp (pVer->szVersion, curWineLook))
-		SendDlgItemMessage (hDlg, IDC_WINELOOK, CB_SETCURSEL,
-				    (WPARAM) i, 0);
-	}
-    }
-
-    free(curWinVer);
-    free(curDOSVer);
-    free(curWineLook);
-}
-
 INT_PTR CALLBACK
-GeneralDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+AboutDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
     switch (uMsg) {
 
@@ -127,47 +64,9 @@
 	    if (((LPNMHDR)lParam)->code != PSN_SETACTIVE) break;
 	    /* otherwise fall through, we want to refresh the page as well */
 	case WM_INITDIALOG:
-	    initGeneralDlg (hDlg);
 	    break;
 
 	case WM_COMMAND:
-	    switch (LOWORD(wParam)) {
-		case IDC_WINVER: if (HIWORD(wParam) == CBN_SELCHANGE) {
-		    /* user changed the wine version combobox */
-		    int selection = SendDlgItemMessage( hDlg, IDC_WINVER, CB_GETCURSEL, 0, 0);
-		    VERSION_DESC *desc = getWinVersions();
-
-		    while (selection > 0) {
-			desc++; selection--;
-		    }
-		    addTransaction(versionSection, "Windows", ACTION_SET, desc->szVersion);
-		}
-	        break;
-
-		case IDC_WINELOOK: if (HIWORD(wParam) == CBN_SELCHANGE) {
-		    /* user changed the wine look combo box */
-		    int selection = SendDlgItemMessage( hDlg, IDC_WINELOOK, CB_GETCURSEL, 0, 0);
-		    VERSION_DESC *desc = getWinelook();
-
-		    while (selection > 0) {
-			desc++; selection--;
-		    }
-		    addTransaction(tweakSection, "WineLook", ACTION_SET, desc->szVersion);
-		}
-		break;
-
-		case IDC_DOSVER: if (HIWORD(wParam) == CBN_SELCHANGE) {
-		    /* user changed the dos version combo box */
-		    int selection = SendDlgItemMessage( hDlg, IDC_WINELOOK, CB_GETCURSEL, 0, 0);
-		    VERSION_DESC *desc = getDOSVersions();
-
-		    while (selection > 0) {
-			desc++; selection--;
-		    }
-		    addTransaction(versionSection, "DOS", ACTION_SET, desc->szVersion);
-		    
-		}
-	    }
 	    break;
 	    
 	default:
@@ -184,77 +83,84 @@
 {
     PROPSHEETPAGE psp[NUM_PROPERTY_PAGES];
     PROPSHEETHEADER psh;
-
-    /*
-     * Fill out the (General) PROPSHEETPAGE data structure 
-     * for the property sheet
-     */
-    psp[0].dwSize = sizeof (PROPSHEETPAGE);
-    psp[0].dwFlags = PSP_USETITLE;
-    psp[0].hInstance = hInstance;
-    psp[0].u.pszTemplate = MAKEINTRESOURCE (IDD_GENERALCFG);
-    psp[0].u2.pszIcon = NULL;
-    psp[0].pfnDlgProc = GeneralDlgProc;
-    psp[0].pszTitle = "General";
-    psp[0].lParam = 0;
+    int pg = 0; /* start with page 0 */
 
     /*
      * Fill out the (Applications) PROPSHEETPAGE data structure 
      * for the property sheet
      */
-    psp[1].dwSize = sizeof (PROPSHEETPAGE);
-    psp[1].dwFlags = PSP_USETITLE;
-    psp[1].hInstance = hInstance;
-    psp[1].u.pszTemplate = MAKEINTRESOURCE (IDD_APPCFG);
-    psp[1].u2.pszIcon = NULL;
-    psp[1].pfnDlgProc = AppDlgProc;
-    psp[1].pszTitle = "Applications";
-    psp[1].lParam = 0;
+    psp[pg].dwSize = sizeof (PROPSHEETPAGE);
+    psp[pg].dwFlags = PSP_USETITLE;
+    psp[pg].hInstance = hInstance;
+    psp[pg].u.pszTemplate = MAKEINTRESOURCE (IDD_APPCFG);
+    psp[pg].u2.pszIcon = NULL;
+    psp[pg].pfnDlgProc = AppDlgProc;
+    psp[pg].pszTitle = "Applications";
+    psp[pg].lParam = 0;
+    pg++;
 
     /*
      * Fill out the (Libraries) PROPSHEETPAGE data structure 
      * for the property sheet
      */
-    psp[2].dwSize = sizeof (PROPSHEETPAGE);
-    psp[2].dwFlags = PSP_USETITLE;
-    psp[2].hInstance = hInstance;
-    psp[2].u.pszTemplate = MAKEINTRESOURCE (IDD_DLLCFG);
-    psp[2].u2.pszIcon = NULL;
-    psp[2].pfnDlgProc = LibrariesDlgProc;
-    psp[2].pszTitle = "Libraries";
-    psp[2].lParam = 0;
+    psp[pg].dwSize = sizeof (PROPSHEETPAGE);
+    psp[pg].dwFlags = PSP_USETITLE;
+    psp[pg].hInstance = hInstance;
+    psp[pg].u.pszTemplate = MAKEINTRESOURCE (IDD_DLLCFG);
+    psp[pg].u2.pszIcon = NULL;
+    psp[pg].pfnDlgProc = LibrariesDlgProc;
+    psp[pg].pszTitle = "Libraries";
+    psp[pg].lParam = 0;
+    pg++;
     
     /*
      * Fill out the (X11Drv) PROPSHEETPAGE data structure 
      * for the property sheet
      */
-    psp[3].dwSize = sizeof (PROPSHEETPAGE);
-    psp[3].dwFlags = PSP_USETITLE;
-    psp[3].hInstance = hInstance;
-    psp[3].u.pszTemplate = MAKEINTRESOURCE (IDD_X11DRVCFG);
-    psp[3].u2.pszIcon = NULL;
-    psp[3].pfnDlgProc = X11DrvDlgProc;
-    psp[3].pszTitle = "X11 Driver";
-    psp[3].lParam = 0;
-
-    psp[4].dwSize = sizeof (PROPSHEETPAGE);
-    psp[4].dwFlags = PSP_USETITLE;
-    psp[4].hInstance = hInstance;
-    psp[4].u.pszTemplate = MAKEINTRESOURCE (IDD_DRIVECFG);
-    psp[4].u2.pszIcon = NULL;
-    psp[4].pfnDlgProc = DriveDlgProc;
-    psp[4].pszTitle = "Drives";
-    psp[4].lParam = 0;
-
-    psp[5].dwSize = sizeof (PROPSHEETPAGE);
-    psp[5].dwFlags = PSP_USETITLE;
-    psp[5].hInstance = hInstance;
-    psp[5].u.pszTemplate = MAKEINTRESOURCE (IDD_AUDIOCFG);
-    psp[5].u2.pszIcon = NULL;
-    psp[5].pfnDlgProc = AudioDlgProc;
-    psp[5].pszTitle = "Audio";
-    psp[5].lParam = 0;
-    
+    psp[pg].dwSize = sizeof (PROPSHEETPAGE);
+    psp[pg].dwFlags = PSP_USETITLE;
+    psp[pg].hInstance = hInstance;
+    psp[pg].u.pszTemplate = MAKEINTRESOURCE (IDD_X11DRVCFG);
+    psp[pg].u2.pszIcon = NULL;
+    psp[pg].pfnDlgProc = X11DrvDlgProc;
+    psp[pg].pszTitle = "X11 Driver";
+    psp[pg].lParam = 0;
+    pg++;
+
+    psp[pg].dwSize = sizeof (PROPSHEETPAGE);
+    psp[pg].dwFlags = PSP_USETITLE;
+    psp[pg].hInstance = hInstance;
+    psp[pg].u.pszTemplate = MAKEINTRESOURCE (IDD_DRIVECFG);
+    psp[pg].u2.pszIcon = NULL;
+    psp[pg].pfnDlgProc = DriveDlgProc;
+    psp[pg].pszTitle = "Drives";
+    psp[pg].lParam = 0;
+    pg++;
+
+    psp[pg].dwSize = sizeof (PROPSHEETPAGE);
+    psp[pg].dwFlags = PSP_USETITLE;
+    psp[pg].hInstance = hInstance;
+    psp[pg].u.pszTemplate = MAKEINTRESOURCE (IDD_AUDIOCFG);
+    psp[pg].u2.pszIcon = NULL;
+    psp[pg].pfnDlgProc = AudioDlgProc;
+    psp[pg].pszTitle = "Audio";
+    psp[pg].lParam = 0;
+    pg++;
+
+    /*
+     * Fill out the (General) PROPSHEETPAGE data structure 
+     * for the property sheet
+     */
+    psp[pg].dwSize = sizeof (PROPSHEETPAGE);
+    psp[pg].dwFlags = PSP_USETITLE;
+    psp[pg].hInstance = hInstance;
+    psp[pg].u.pszTemplate = MAKEINTRESOURCE (IDD_ABOUTCFG);
+    psp[pg].u2.pszIcon = NULL;
+    psp[pg].pfnDlgProc = AboutDlgProc;
+    psp[pg].pszTitle = "About";
+    psp[pg].lParam = 0;
+    pg++;
+
     /*
      * Fill out the PROPSHEETHEADER
      */
Index: properties.c
===================================================================
RCS file: /home/wine/wine/programs/winecfg/properties.c,v
retrieving revision 1.6
diff -u -r1.6 properties.c
--- properties.c	20 Jan 2004 02:07:36 -0000	1.6
+++ properties.c	4 Feb 2004 04:44:40 -0000
@@ -25,6 +25,7 @@
 #include "properties.h"
 
 static VERSION_DESC sWinVersions[] = {
+    {"", "Use default(Global setting)"},
     {"win20", "Windows 2.0"},
     {"win30", "Windows 3.0"},
     {"win31", "Windows 3.1"},
@@ -40,11 +41,13 @@
 };
 
 static VERSION_DESC sDOSVersions[] = {
+    {"", "Use default(Global setting)"},
     {"6.22", "MS-DOS 6.22"},
     {"", ""}
 };
 
 static VERSION_DESC sWineLook[] = {
+    {"", "Use default(Global setting)"},
     {"win31", "Windows 3.1"},
     {"win95", "Windows 95"},
     {"win98", "Windows 98"},
@@ -126,4 +129,28 @@
 AUDIO_DRIVER* getAudioDrivers(void)
 {
     return sAudioDrivers;
+}
+
+
+/* Functions to convert from version to description and back */
+char* getVersionFromDescription(VERSION_DESC* pVer, char *desc)
+{
+  for (; *pVer->szVersion; pVer++)
+  {
+    if(!strcasecmp(pVer->szDescription, desc))
+      return pVer->szVersion;
+  }
+
+  return NULL;
+}
+
+char* getDescriptionFromVersion(VERSION_DESC* pVer, char *ver)
+{
+  for (; *pVer->szDescription; pVer++)
+  {
+    if(!strcasecmp(pVer->szVersion, ver))
+      return pVer->szDescription;
+  }
+
+  return NULL;
 }
Index: properties.h
===================================================================
RCS file: /home/wine/wine/programs/winecfg/properties.h,v
retrieving revision 1.9
diff -u -r1.9 properties.h
--- properties.h	20 Jan 2004 02:07:36 -0000	1.9
+++ properties.h	4 Feb 2004 04:44:40 -0000
@@ -92,5 +92,7 @@
 VERSION_DESC *getWinelook(void);
 DLL_DESC *getDLLDefaults(void);
 AUDIO_DRIVER *getAudioDrivers(void);
+char* getVersionFromDescription(VERSION_DESC *pVer, char *desc);
+char* getDescriptionFromVersion(VERSION_DESC *pVer, char *ver);
 
 #endif
Index: resource.h
===================================================================
RCS file: /home/wine/wine/programs/winecfg/resource.h,v
retrieving revision 1.11
diff -u -r1.11 resource.h
--- resource.h	20 Jan 2004 02:07:36 -0000	1.11
+++ resource.h	4 Feb 2004 04:44:40 -0000
@@ -28,7 +28,7 @@
 #define IDS_TAB_DRIVES                  4
 #define IDD_MAINDLG                     101
 #define IDB_WINE                        104
-#define IDD_GENERALCFG                  107
+#define IDD_ABOUTCFG                    107
 #define IDD_APPCFG                      108
 #define IDD_AUDIOCFG                    109
 #define IDD_X11DRVCFG                   110
@@ -116,11 +116,9 @@
 #define IDC_DOUBLE_BUFFER               1080
 
 /* applications tab */
-#define IDC_LIST_APPS                   1021
-#define IDC_EDITING_GLOBAL              1081
-#define IDC_EDITING_APP                 1082
-#define IDC_ADD_APPDEFAULT              1083
-#define IDC_REMOVE_APPDEFAULT           1084
+#define IDC_APP_TREEVIEW                1021
+#define IDC_APP_ADDAPP                  1081
+#define IDC_APP_REMOVEAPP               1082
 
 /* audio tab */
 #define IDC_AUDIO_AUTODETECT            1085
Index: winecfg.h
===================================================================
RCS file: /home/wine/wine/programs/winecfg/winecfg.h,v
retrieving revision 1.13
diff -u -r1.13 winecfg.h
--- winecfg.h	20 Jan 2004 02:07:35 -0000	1.13
+++ winecfg.h	4 Feb 2004 04:44:40 -0000
@@ -119,7 +119,6 @@
 #define disable(id) EnableWindow(GetDlgItem(dialog, id), 0);
 #define enable(id) EnableWindow(GetDlgItem(dialog, id), 1);
 
-
 #define WINE_KEY_ROOT "Software\\Wine\\Wine\\Config"
 
 #endif
Index: x11drvdlg.c
===================================================================
RCS file: /home/wine/wine/programs/winecfg/x11drvdlg.c,v
retrieving revision 1.9
diff -u -r1.9 x11drvdlg.c
--- x11drvdlg.c	22 Oct 2003 00:01:46 -0000	1.9
+++ x11drvdlg.c	4 Feb 2004 04:44:41 -0000
@@ -39,6 +39,18 @@
 
 int updatingUI;
 
+int appSettings = EDITING_GLOBAL; /* start by editing global */
+char *currentApp; /* the app we are currently editing, or NULL if editing global */
+
+char *getSectionForApp(char *pSection)
+{
+    static char *lastResult = NULL;
+    if (lastResult) HeapFree(GetProcessHeap(), 0, lastResult);
+    lastResult = HeapAlloc(GetProcessHeap(), 0, strlen("AppDefaults\\") + strlen(currentApp) + 2 /* \\ */ + strlen(pSection) + 1 /* terminator */);
+    sprintf(lastResult, "AppDefaults\\%s\\%s", currentApp, pSection);
+    return lastResult;
+}
+
 void updateGUIForDesktopMode(HWND dialog) {
     WINE_TRACE("\n");
 
