From a5ce4ee7aa20bf0a92ebfc604ddec6653c533c37 Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Tue, 28 Sep 2004 03:16:43 +0000 Subject: [PATCH] - introduce keypath() function - rewrite and clean up appdefaults.c, use a listview rather than treeview - usability tweak: reverse windows version combo so more recent versions come first - usability tweak: improve the add application open dialog box - add accelerator keys - enable/disable controls correctly - begin to standardise on underscore_style for consistency with the rest of wine - comment out the translations for now, the UI will be changing more - begin phasing out libc malloc in favour of the win32 heap --- programs/winecfg/En.rc | 18 +- programs/winecfg/appdefaults.c | 631 +++++++++++++-------------------- programs/winecfg/properties.c | 30 +- programs/winecfg/resource.h | 3 +- programs/winecfg/winecfg.c | 31 +- programs/winecfg/winecfg.h | 23 +- programs/winecfg/winecfg.rc | 12 +- programs/winecfg/x11drvdlg.c | 37 +- 8 files changed, 340 insertions(+), 445 deletions(-) diff --git a/programs/winecfg/En.rc b/programs/winecfg/En.rc index 171e9f4a649..0029f37dd59 100644 --- a/programs/winecfg/En.rc +++ b/programs/winecfg/En.rc @@ -4,6 +4,7 @@ * * Copyright 2002 Jaco Greeff * Copyright 2003 Dimitrie O. Paun + * Copyright 2003-2004 Mike Hearn * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -42,15 +43,16 @@ STYLE WS_CHILD | WS_DISABLED FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Application Settings",IDC_STATIC, 8,4,244,240 - LTEXT "Wine provides the ability for Windows applications to mimic various Windows versions and styles", + LTEXT "Wine can mimic different Windows versions for each application.", 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 - 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 + CONTROL "Applications",IDC_APP_LISTVIEW,"SysListView32",WS_BORDER | WS_TABSTOP | LVS_LIST | LVS_SINGLESEL | LVS_SHOWSELALWAYS, + 15,40,230,140 + PUSHBUTTON "&Add application...",IDC_APP_ADDAPP, 90,184,75,14 + PUSHBUTTON "&Remove application",IDC_APP_REMOVEAPP, 170,184,75,14 + LTEXT "&Windows Version:",IDC_STATIC,17,204,58,8 + COMBOBOX IDC_WINVER,83,202,163,56,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "&DOS Version:",IDC_STATIC,17,223,57,8 + COMBOBOX IDC_DOSVER,83,224,163,56,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END IDD_GRAPHCFG DIALOG DISCARDABLE 0, 0, 260, 250 diff --git a/programs/winecfg/appdefaults.c b/programs/winecfg/appdefaults.c index 4ae58790da5..e0b24ee8953 100644 --- a/programs/winecfg/appdefaults.c +++ b/programs/winecfg/appdefaults.c @@ -2,7 +2,8 @@ * WineCfg app settings tabsheet * * Copyright 2004 Robert van Herk - * Chris Morgan + * Copyright 2004 Chris Morgan + * Copyright 2004 Mike Hearn * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,181 +26,30 @@ #include #include #include +#include #include "winecfg.h" #include "resource.h" WINE_DEFAULT_DEBUG_CHANNEL(winecfg); -typedef struct _APPL -{ - BOOL isGlobal; - char* lpcApplication; - char* lpcVersionSection; -} APPL, *LPAPPL; - -static LPAPPL CreateAppl(BOOL isGlobal, char* application, char* version_section) -{ - LPAPPL out; - WINE_TRACE("application: '%s', version_section: '%s'\n", application, version_section); - out = HeapAlloc(GetProcessHeap(),0,sizeof(APPL)); - out->lpcApplication = strdup(application); - out->lpcVersionSection = strdup(version_section); - out->isGlobal = isGlobal; - return out; -} - -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); - HeapFree(GetProcessHeap(),0,lpAppl); -} - -/* section can be "Version" */ -/* key can be "Windows"/"Dos" */ -/* 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'\n", appl->lpcVersionSection); - if (RegOpenKey (configKey, appl->lpcVersionSection, &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"); - } - } -} - -static VOID SetEnabledAppControls(HWND dialog) -{ -} - -static VOID UpdateComboboxes(HWND hDlg, LPAPPL lpAppl) +static void update_comboboxes(HWND dialog) { 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 *winver, *dosver; + + /* retrieve the registry values */ + winver = getConfigValue(keypath("Version"), "Windows", NULL); + dosver = getConfigValue(keypath("Version"), "DOS", NULL); - 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"); + /* NULL winver/dosver means use automatic mode (ie the builtin dll linkage heuristics) */ + + WINE_TRACE("winver is %s\n", winver ? winver : "null (automatic mode)"); + WINE_TRACE("dosver is %s\n", dosver ? dosver : "null (automatic mode)"); /* normalize the version strings */ - if(strlen(curWinVer) != 0) + if (winver && strlen(winver)) { if ((pVer = getWinVersions ())) { @@ -207,22 +57,21 @@ static VOID UpdateComboboxes(HWND hDlg, LPAPPL lpAppl) for (i = 0; *pVer->szVersion || *pVer->szDescription; i++, pVer++) { WINE_TRACE("pVer->szVersion == %s\n", pVer->szVersion); - if (!strcasecmp (pVer->szVersion, curWinVer)) + if (!strcasecmp (pVer->szVersion, winver)) { - SendDlgItemMessage (hDlg, IDC_WINVER, CB_SETCURSEL, - (WPARAM) i, 0); + SendDlgItemMessage (dialog, IDC_WINVER, CB_SETCURSEL, (WPARAM) (i + 1), 0); WINE_TRACE("match with %s\n", pVer->szVersion); } } } - } else /* clear selection */ + } + else /* no explicit setting */ { - WINE_TRACE("setting winver to nothing\n"); - SendDlgItemMessage (hDlg, IDC_WINVER, CB_SETCURSEL, - -1, 0); + WINE_TRACE("setting winver combobox to automatic/default\n"); + SendDlgItemMessage (dialog, IDC_WINVER, CB_SETCURSEL, 0, 0); } - if(strlen(curDOSVer) != 0) + if (dosver && strlen(dosver)) { if ((pVer = getDOSVersions ())) { @@ -230,288 +79,312 @@ static VOID UpdateComboboxes(HWND hDlg, LPAPPL lpAppl) for (i = 0; *pVer->szVersion || *pVer->szDescription; i++, pVer++) { WINE_TRACE("pVer->szVersion == %s\n", pVer->szVersion); - if (!strcasecmp (pVer->szVersion, curDOSVer)) + if (!strcasecmp (pVer->szVersion, dosver)) { - SendDlgItemMessage (hDlg, IDC_DOSVER, CB_SETCURSEL, - (WPARAM) i, 0); + SendDlgItemMessage (dialog, IDC_DOSVER, CB_SETCURSEL, + (WPARAM) (i + 1), 0); WINE_TRACE("match with %s\n", pVer->szVersion); } } } - } else + } + else { - WINE_TRACE("setting dosver to nothing\n"); - SendDlgItemMessage (hDlg, IDC_DOSVER, CB_SETCURSEL, - -1, 0); + WINE_TRACE("setting dosver combobox to automatic/default\n"); + SendDlgItemMessage (dialog, IDC_DOSVER, CB_SETCURSEL, 0, 0); } - if(curWinVer) free(curWinVer); - if(curDOSVer) free(curDOSVer); + if (winver) free(winver); + if (dosver) free(dosver); } void -initAppDlgComboboxes (HWND hDlg) +init_comboboxes (HWND dialog) { int i; - const VERSION_DESC *pVer = NULL; + const VERSION_DESC *ver = NULL; - if ((pVer = getWinVersions ())) + + SendDlgItemMessage(dialog, IDC_WINVER, CB_RESETCONTENT, 0, 0); + SendDlgItemMessage(dialog, IDC_DOSVER, CB_RESETCONTENT, 0, 0); + + /* add the default entries (automatic) which correspond to no setting */ + if (currentApp) { - for (i = 0; *pVer->szVersion || *pVer->szDescription; i++, pVer++) + SendDlgItemMessage(dialog, IDC_WINVER, CB_ADDSTRING, 0, (LPARAM) "Use global settings"); + SendDlgItemMessage(dialog, IDC_DOSVER, CB_ADDSTRING, 0, (LPARAM) "Use global settings"); + } + else + { + SendDlgItemMessage(dialog, IDC_WINVER, CB_ADDSTRING, 0, (LPARAM) "Automatically detect required version"); + SendDlgItemMessage(dialog, IDC_DOSVER, CB_ADDSTRING, 0, (LPARAM) "Automatically detect required version"); + } + + if ((ver = getWinVersions ())) + { + for (i = 0; *ver->szVersion || *ver->szDescription; i++, ver++) { - SendDlgItemMessage (hDlg, IDC_WINVER, CB_ADDSTRING, - 0, (LPARAM) pVer->szDescription); + SendDlgItemMessage (dialog, IDC_WINVER, CB_ADDSTRING, + 0, (LPARAM) ver->szDescription); } } - if ((pVer = getDOSVersions ())) + if ((ver = getDOSVersions ())) { - for (i = 0; *pVer->szVersion || *pVer->szDescription ; i++, pVer++) + for (i = 0; *ver->szVersion || *ver->szDescription ; i++, ver++) { - SendDlgItemMessage (hDlg, IDC_DOSVER, CB_ADDSTRING, - 0, (LPARAM) pVer->szDescription); + SendDlgItemMessage (dialog, IDC_DOSVER, CB_ADDSTRING, + 0, (LPARAM) ver->szDescription); } } } - -static VOID OnInitAppDlg(HWND hDlg) +static void add_listview_item(HWND listview, char *text, void *association) { - HWND hwndTV; - LPAPPL lpAppl; - HKEY applKey; + LVITEM item; + + ZeroMemory(&item, sizeof(LVITEM)); + + item.mask = LVIF_TEXT | LVIF_PARAM; + item.pszText = text; + item.cchTextMax = strlen(text); + item.lParam = (LPARAM) association; + item.iItem = ListView_GetItemCount(listview); + + ListView_InsertItem(listview, &item); +} + +static void init_appsheet(HWND dialog) +{ + HWND listview; + HKEY key; int i; DWORD size; - char appl [255]; - char lpcVersionKey [255]; + char appname[1024]; FILETIME ft; - hwndTV = GetDlgItem(hDlg,IDC_APP_TREEVIEW); - lpAppl = CreateAppl(TRUE, "Global Settings", "Version"); - LoadAppSettings(lpAppl, hDlg, hwndTV); - - /*And now the application specific stuff:*/ - if (RegOpenKey(configKey, "AppDefaults", &applKey) == ERROR_SUCCESS) + WINE_TRACE("()\n"); + + listview = GetDlgItem(dialog, IDC_APP_LISTVIEW); + + /* we use the lparam field of the item so we can alter the presentation later and not change code + * for instance, to use the tile view or to display the EXEs embedded 'display name' */ + add_listview_item(listview, "Default Settings", NULL); + + /* do the application specific stuff, then add the default item last */ + if (RegOpenKey(configKey, "AppDefaults", &key) == ERROR_SUCCESS) { - i = 0; - size = 255; - while (RegEnumKeyEx(applKey, i, appl, &size, NULL, NULL, NULL, &ft) == ERROR_SUCCESS) - { - sprintf(lpcVersionKey, "AppDefaults\\%s\\Version", appl); - lpAppl = CreateAppl(FALSE, appl, lpcVersionKey); - LoadAppSettings(lpAppl, hDlg, hwndTV); - i++; size = 255; - } - RegCloseKey(applKey); + i = 0; + size = sizeof(appname); + while (RegEnumKeyEx(key, i, appname, &size, NULL, NULL, NULL, &ft) == ERROR_SUCCESS) + { + add_listview_item(listview, appname, strdup(appname)); + + i++; + size = sizeof(appname); + } + + RegCloseKey(key); } - SetEnabledAppControls(hDlg); -} -static VOID OnTreeViewChangeItem(HWND hDlg, HWND hTV) -{ - TVITEM ti; - LPITEMTAG lpit; - - ti.mask = TVIF_PARAM; - ti.hItem = TreeView_GetSelection(hTV); - if (TreeView_GetItem (hTV, &ti)) + init_comboboxes(dialog); + + /* Select the default settings listview item */ { - 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"); - } + LVITEM item; + + ZeroMemory(&item, sizeof(item)); + + item.mask = LVIF_STATE; + item.iItem = 0; + item.state = LVIS_SELECTED | LVIS_FOCUSED; + item.stateMask = LVIS_SELECTED | LVIS_FOCUSED; + + ListView_SetItem(listview, &item); } + } -static VOID OnTreeViewDeleteItem(NMTREEVIEW* nmt) +/* there has to be an easier way than this */ +static int get_listview_selection(HWND listview) { - FreeItemTag((LPITEMTAG)(nmt->itemOld.lParam)); + int count = ListView_GetItemCount(listview); + int i; + + for (i = 0; i < count; i++) + { + if (ListView_GetItemState(listview, i, LVIS_SELECTED)) return i; + } + + return -1; } -static VOID OnAddApplicationClick(HWND hDlg) +/* called when the user selects a different application */ +static void on_selection_change(HWND dialog, HWND listview) { - char szFileTitle [255]; - char szFile [255]; - char lpcVersionKey [255]; + LVITEM item; + char *oldapp = currentApp; + + WINE_TRACE("()\n"); + + item.iItem = get_listview_selection(listview); + item.mask = LVIF_PARAM; + + if (item.iItem == -1) return; + + ListView_GetItem(listview, &item); + + currentApp = (char *) item.lParam; + + if (currentApp) + { + WINE_TRACE("currentApp is now %s\n", currentApp); + enable(IDC_APP_REMOVEAPP); + } + else + { + WINE_TRACE("currentApp=NULL, editing global settings\n"); + /* focus will never be on the button in this callback so it's safe */ + disable(IDC_APP_REMOVEAPP); + } + + /* reset the combo boxes if we changed from/to global/app-specific */ + + if ((oldapp && !currentApp) || (!oldapp && currentApp)) + init_comboboxes(dialog); + + update_comboboxes(dialog); +} + +static void on_add_app_click(HWND dialog) +{ + char filetitle[MAX_PATH]; + char file[MAX_PATH]; - 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 }; + 0, NULL, 0, "c:\\", "Select a Windows executable file", + OFN_SHOWHELP | OFN_HIDEREADONLY, 0, 0, NULL, 0, NULL }; - ofn.lpstrFileTitle = szFileTitle; + ofn.lpstrFileTitle = filetitle; ofn.lpstrFileTitle[0] = '\0'; - ofn.nMaxFileTitle = sizeof(szFileTitle); - ofn.lpstrFile = szFile; + ofn.nMaxFileTitle = sizeof(filetitle); + ofn.lpstrFile = file; ofn.lpstrFile[0] = '\0'; - ofn.nMaxFile = sizeof(szFile); + ofn.nMaxFile = sizeof(file); 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); - lpit->lpAppl = CreateAppl(FALSE, szFileTitle, lpcVersionKey); - tis.u.item.lParam = (LPARAM)lpit; - TreeView_InsertItem(GetDlgItem(hDlg, IDC_APP_TREEVIEW), &tis); + HWND listview = GetDlgItem(dialog, IDC_APP_LISTVIEW); + int count = ListView_GetItemCount(listview); + + if (currentApp) free(currentApp); + currentApp = strdup(filetitle); - /* add the empty entries for the Version section for this app */ - setConfigValue(lpcVersionKey,NULL,NULL); + WINE_TRACE("adding %s\n", currentApp); + + add_listview_item(listview, currentApp, currentApp); + + ListView_SetItemState(listview, count, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); + + SetFocus(listview); } + else WINE_TRACE("user cancelled\n"); } -static VOID OnRemoveApplicationClick(HWND hDlg) +static void on_remove_app_click(HWND dialog) { - HWND hTV; - TVITEM ti; - LPITEMTAG lpit; + HWND listview = GetDlgItem(dialog, IDC_APP_LISTVIEW); + int selection = get_listview_selection(listview); + char *section = keypath(""); - 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); - TreeView_DeleteItem(hTV,ti.hItem); - } - } + WINE_TRACE("selection=%d, section=%s\n", selection, section); + + assert( selection != 0 ); /* user cannot click this button when "default settings" is selected */ + + section[strlen(section)] = '\0'; /* remove last backslash */ + addTransaction(section, NULL, ACTION_REMOVE, NULL); + ListView_DeleteItem(listview, selection); + + SetFocus(listview); } -static void UpdateWinverSelection(HWND hDlg, int selection) +static void on_winver_change(HWND dialog) { - TVITEM ti; - LPITEMTAG lpit; - VERSION_DESC *pVer = NULL; - HWND hTV = GetDlgItem(hDlg, IDC_APP_TREEVIEW); + int selection = SendDlgItemMessage(dialog, IDC_WINVER, CB_GETCURSEL, 0, 0); + VERSION_DESC *ver = getWinVersions(); - ti.mask = TVIF_PARAM; - ti.hItem = TreeView_GetSelection(hTV); - if (TreeView_GetItem (hTV, &ti)) - { - lpit = (LPITEMTAG) ti.lParam; - - if(lpit->lpAppl) + if (selection == 0) { - 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->lpcVersionSection); - 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); + WINE_TRACE("automatic/default selected so removing current setting\n"); + addTransaction(keypath("Version"), "Windows", ACTION_REMOVE, NULL); + } + else + { + WINE_TRACE("setting Version\\Windows key to value '%s'\n", ver[selection - 1].szVersion); + addTransaction(keypath("Version"), "Windows", ACTION_SET, ver[selection - 1].szVersion); } - } } -static void UpdateDosverSelection(HWND hDlg, int selection) +static void on_dosver_change(HWND dialog) { - TVITEM ti; - LPITEMTAG lpit; - VERSION_DESC *pVer = NULL; - HWND hTV = GetDlgItem(hDlg, IDC_APP_TREEVIEW); + int selection = SendDlgItemMessage(dialog, IDC_DOSVER, CB_GETCURSEL, 0, 0); + VERSION_DESC *ver = getDOSVersions(); - ti.mask = TVIF_PARAM; - ti.hItem = TreeView_GetSelection(hTV); - if (TreeView_GetItem (hTV, &ti)) - { - lpit = (LPITEMTAG) ti.lParam; - - if(lpit->lpAppl) + if (selection == 0) { - 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->lpcVersionSection); - 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); + WINE_TRACE("automatic/default selected so removing current setting\n"); + addTransaction(keypath("Version"), "DOS", ACTION_REMOVE, NULL); + } + else + { + WINE_TRACE("setting Version\\DOS key to value '%s'\n", ver[selection - 1].szVersion); + addTransaction(keypath("Version"), "DOS", ACTION_SET, ver[selection - 1].szVersion); } - } } 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; - } - } + case WM_INITDIALOG: + init_appsheet(hDlg); 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 BN_CLICKED: - switch(LOWORD(wParam)) { - case IDC_APP_ADDAPP: - OnAddApplicationClick(hDlg); - break; - case IDC_APP_REMOVEAPP: - OnRemoveApplicationClick(hDlg); - break; - } - break; - } - break; - } + case WM_NOTIFY: + + switch (((LPNMHDR)lParam)->code) + { + case LVN_ITEMCHANGED: + on_selection_change(hDlg, GetDlgItem(hDlg, IDC_APP_LISTVIEW)); + break; + } + break; + + case WM_COMMAND: + switch(HIWORD(wParam)) { + case CBN_SELCHANGE: + switch(LOWORD(wParam)) { + case IDC_WINVER: + on_winver_change(hDlg); + break; + case IDC_DOSVER: + on_dosver_change(hDlg); + break; + } + case BN_CLICKED: + switch(LOWORD(wParam)) { + case IDC_APP_ADDAPP: + on_add_app_click(hDlg); + break; + case IDC_APP_REMOVEAPP: + on_remove_app_click(hDlg); + break; + } + break; + } + break; + } + return 0; } diff --git a/programs/winecfg/properties.c b/programs/winecfg/properties.c index b67768760fe..ada5f42354b 100644 --- a/programs/winecfg/properties.c +++ b/programs/winecfg/properties.c @@ -25,35 +25,25 @@ #include "properties.h" static VERSION_DESC sWinVersions[] = { - {"", "Use default(Global setting)"}, - {"win20", "Windows 2.0"}, - {"win30", "Windows 3.0"}, - {"win31", "Windows 3.1"}, - {"nt351", "Windows NT 3.5"}, - {"nt40", "Windows NT 4.0"}, - {"win95", "Windows 95"}, - {"win98", "Windows 98"}, - {"winme", "Windows ME"}, - {"win2k", "Windows 2000"}, - {"winxp", "Windows XP"}, {"win2003", "Windows 2003"}, + {"winxp", "Windows XP"}, + {"win2k", "Windows 2000"}, + {"winme", "Windows ME"}, + {"win98", "Windows 98"}, + {"win95", "Windows 95"}, + {"nt40", "Windows NT 4.0"}, + {"nt351", "Windows NT 3.5"}, + {"win31", "Windows 3.1"}, + {"win30", "Windows 3.0"}, + {"win20", "Windows 2.0"}, {"", ""} }; static VERSION_DESC sDOSVersions[] = { - {"", "Use default(Global setting)"}, {"6.22", "MS-DOS 6.22"}, {"", ""} }; -#if 0 -static VERSION_DESC sWineDrivers[] = { - {"x11drv", "X11 Interface"}, - {"ttydrv", "TTY Interface"}, - {"", ""} -}; -#endif - static DLL_DESC sDLLType[] = { {"oleaut32", DLL_BUILTIN}, {"ole32", DLL_BUILTIN}, diff --git a/programs/winecfg/resource.h b/programs/winecfg/resource.h index 57eb6c52b49..5112774a8a6 100644 --- a/programs/winecfg/resource.h +++ b/programs/winecfg/resource.h @@ -4,6 +4,7 @@ * Copyright 2002 Jaco Greeff * Copyright 2003 Dimitrie O. Paun * Copyright 2003 Mark Westcott + * Copyright 2004 Mike Hearn * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -119,7 +120,7 @@ #define IDC_DOUBLE_BUFFER 1104 /* applications tab */ -#define IDC_APP_TREEVIEW 1200 +#define IDC_APP_LISTVIEW 1200 #define IDC_APP_ADDAPP 1201 #define IDC_APP_REMOVEAPP 1202 diff --git a/programs/winecfg/winecfg.c b/programs/winecfg/winecfg.c index c212f1532ea..e7a6b4ab8e9 100644 --- a/programs/winecfg/winecfg.c +++ b/programs/winecfg/winecfg.c @@ -3,7 +3,7 @@ * * Copyright 2002 Jaco Greeff * Copyright 2003 Dimitrie O. Paun - * Copyright 2003 Mike Hearn + * Copyright 2003-2004 Mike Hearn * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -86,7 +86,7 @@ char *getConfigValue (const char *subkey, const char *valueName, const char *def if( res==ERROR_FILE_NOT_FOUND ) { WINE_TRACE("Section key not present - using default\n"); - return strdup(defaultResult); + return defaultResult ? strdup(defaultResult) : NULL; } else { @@ -98,7 +98,7 @@ char *getConfigValue (const char *subkey, const char *valueName, const char *def res = RegQueryValueExA( hSubKey, valueName, NULL, NULL, NULL, &dataLength); if( res == ERROR_FILE_NOT_FOUND ) { WINE_TRACE("Value not present - using default\n"); - buffer = strdup(defaultResult); + buffer = defaultResult ? strdup(defaultResult) : NULL; goto end; } else if( res!=ERROR_SUCCESS ) { WINE_ERR("Couldn't query value's length (res=%ld)\n", res ); @@ -123,7 +123,8 @@ end: } /***************************************************************************** - * setConfigValue : Sets a configuration key in the registry. Section will be created if it doesn't already exist + * setConfigValue : Sets a configuration key in the registry. Section + * will be created if it doesn't already exist * * HKEY hCurrent : the registry key that the configuration is rooted at * const char *subKey : the name of the config section @@ -285,6 +286,28 @@ void processTransQueue(void) /* ================================== utility functions ============================ */ +char *currentApp = NULL; /* the app we are currently editing, or NULL if editing global */ + +/* returns a registry key path suitable for passing to addTransaction */ +char *keypath(char *section) +{ + static char *result = NULL; + + if (result) release(result); + + if (currentApp) + { + result = alloc(strlen("AppDefaults\\") + strlen(currentApp) + 2 /* \\ */ + strlen(section) + 1 /* terminator */); + sprintf(result, "AppDefaults\\%s\\%s", currentApp, section); + } + else + { + result = strdupA(section); + } + + return result; +} + /* returns a string with the window text of the dialog item. user is responsible for freeing the result */ char *getDialogItemText(HWND hDlg, WORD controlID) { HWND item = GetDlgItem(hDlg, controlID); diff --git a/programs/winecfg/winecfg.h b/programs/winecfg/winecfg.h index f7d11b66226..1bef221d9fd 100644 --- a/programs/winecfg/winecfg.h +++ b/programs/winecfg/winecfg.h @@ -3,6 +3,7 @@ * * Copyright 2002 Jaco Greeff * Copyright 2003 Dimitrie O. Paun + * Copyright 2004 Mike Hearn * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -67,9 +68,14 @@ extern int instantApply; /* non-zero means apply all changes instantly */ #define EDITING_APP 1 extern int appSettings; /* non-zero means we are editing appdefault settings */ -/* returns a string of the form AppDefaults\\appname.exe\\section */ -/* no explicit free is needed of the string returned by this function */ -char *getSectionForApp(char *section); +extern char *currentApp; /* NULL means editing global settings */ + +/* returns a string of the form "AppDefaults\\appname.exe\\section", or just "section" if + * the user is editing the global settings. + * + * no explicit free is needed of the string returned by this function + */ +char *keypath(char *section); /* Commits a transaction to the registry */ void processTransaction(struct transaction *trans); @@ -91,6 +97,7 @@ void destroyTransaction(struct transaction *trans); int initialize(void); extern HKEY configKey; +/* don't use these directly! */ int setConfigValue (const char *subkey, const char *valueName, const char *value); char *getConfigValue (const char *subkey, const char *valueName, const char *defaultResult); HRESULT doesConfigValueExist (const char *subkey, const char *valueName); @@ -118,8 +125,18 @@ INT_PTR CALLBACK AudioDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara char *getDialogItemText(HWND hDlg, WORD controlID); #define disable(id) EnableWindow(GetDlgItem(dialog, id), 0); #define enable(id) EnableWindow(GetDlgItem(dialog, id), 1); +#define alloc(size) HeapAlloc(GetProcessHeap(), 0, size); +#define release(ptr) HeapFree(GetProcessHeap(), 0, ptr); void PRINTERROR(void); /* WINE_TRACE() the plaintext error message from GetLastError() */ +/* returns a string in the win32 heap */ +static inline char *strdupA(char *s) +{ + char *r = alloc(strlen(s)); + return strcpy(r, s); +} + + #define WINE_KEY_ROOT "Software\\Wine\\Wine\\Config" #endif diff --git a/programs/winecfg/winecfg.rc b/programs/winecfg/winecfg.rc index de396653c7a..9f099330ba5 100644 --- a/programs/winecfg/winecfg.rc +++ b/programs/winecfg/winecfg.rc @@ -28,12 +28,12 @@ #include "resource.h" #include "En.rc" -#include "Es.rc" -#include "It.rc" -#include "Nl.rc" -#include "Pt.rc" -#include "Ru.rc" -#include "Si.rc" +/* #include "Es.rc" */ +/* #include "It.rc" */ +/* #include "Nl.rc" */ +/* #include "Pt.rc" */ +/* #include "Ru.rc" */ +/* #include "Si.rc" */ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL diff --git a/programs/winecfg/x11drvdlg.c b/programs/winecfg/x11drvdlg.c index 7119677f7a7..8003944f636 100644 --- a/programs/winecfg/x11drvdlg.c +++ b/programs/winecfg/x11drvdlg.c @@ -2,7 +2,7 @@ * Graphics configuration code * * Copyright 2003 Mark Westcott - * Copyright 2003 Mike Hearn + * Copyright 2003-2004 Mike Hearn * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -35,21 +35,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(winecfg); #define RES_MAXLEN 5 /* the maximum number of characters in a screen dimension. 5 digits should be plenty, what kind of crazy person runs their screen >10,000 pixels across? */ -#define section (appSettings == EDITING_GLOBAL ? "graphics" : (getSectionForApp("graphics"))) 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"); @@ -57,7 +46,7 @@ void updateGUIForDesktopMode(HWND dialog) { updatingUI = TRUE; /* do we have desktop mode enabled? */ - if (doesConfigValueExist(section, "Desktop") == S_OK) { + if (doesConfigValueExist(keypath("x11drv"), "Desktop") == S_OK) { CheckDlgButton(dialog, IDC_ENABLE_DESKTOP, BST_CHECKED); /* enable the controls */ enable(IDC_DESKTOP_WIDTH); @@ -95,7 +84,7 @@ void initGraphDlg (HWND hDlg) updatingUI = TRUE; /* desktop size */ - buf = getConfigValue(section, "Desktop", default_desktop); + buf = getConfigValue(keypath("x11drv"), "Desktop", default_desktop); bufindex = strchr(buf, 'x'); if(!bufindex) /* handle invalid "Desktop" values */ { @@ -115,7 +104,7 @@ void initGraphDlg (HWND hDlg) SendDlgItemMessage(hDlg, IDC_SCREEN_DEPTH, CB_ADDSTRING, 0, (LPARAM) "24 bit"); SendDlgItemMessage(hDlg, IDC_SCREEN_DEPTH, CB_ADDSTRING, 0, (LPARAM) "32 bit"); /* is this valid? */ - buf = getConfigValue(section, "ScreenDepth", "24"); + buf = getConfigValue(keypath("x11drv"), "ScreenDepth", "24"); if (strcmp(buf, "8") == 0) SendDlgItemMessage(hDlg, IDC_SCREEN_DEPTH, CB_SETCURSEL, 0, 0); else if (strcmp(buf, "16") == 0) @@ -131,14 +120,14 @@ void initGraphDlg (HWND hDlg) SendDlgItemMessage(hDlg, IDC_DESKTOP_WIDTH, EM_LIMITTEXT, RES_MAXLEN, 0); SendDlgItemMessage(hDlg, IDC_DESKTOP_HEIGHT, EM_LIMITTEXT, RES_MAXLEN, 0); - buf = getConfigValue(section, "DXGrab", "Y"); + buf = getConfigValue(keypath("x11drv"), "DXGrab", "Y"); if (IS_OPTION_TRUE(*buf)) CheckDlgButton(hDlg, IDC_DX_MOUSE_GRAB, BST_CHECKED); else CheckDlgButton(hDlg, IDC_DX_MOUSE_GRAB, BST_UNCHECKED); free(buf); - buf = getConfigValue(section, "DesktopDoubleBuffered", "Y"); + buf = getConfigValue(keypath("x11drv"), "DesktopDoubleBuffered", "Y"); if (IS_OPTION_TRUE(*buf)) CheckDlgButton(hDlg, IDC_DOUBLE_BUFFER, BST_CHECKED); else @@ -166,7 +155,7 @@ void setFromDesktopSizeEdits(HWND hDlg) { if (strcmp(height, "") == 0) strcpy(height, "480"); sprintf(newStr, "%sx%s", width, height); - addTransaction(section, "Desktop", ACTION_SET, newStr); + addTransaction(keypath("x11drv"), "Desktop", ACTION_SET, newStr); free(width); free(height); @@ -180,7 +169,7 @@ void onEnableDesktopClicked(HWND hDlg) { setFromDesktopSizeEdits(hDlg); } else { /* it was just checked, so remove the config values */ - addTransaction(section, "Desktop", ACTION_REMOVE, NULL); + addTransaction(keypath("x11drv"), "Desktop", ACTION_REMOVE, NULL); } updateGUIForDesktopMode(hDlg); } @@ -193,23 +182,23 @@ void onScreenDepthChanged(HWND hDlg) { if (updatingUI) return; *spaceIndex = '\0'; - addTransaction(section, "ScreenDepth", ACTION_SET, newvalue); + addTransaction(keypath("x11drv"), "ScreenDepth", ACTION_SET, newvalue); free(newvalue); } void onDXMouseGrabClicked(HWND hDlg) { if (IsDlgButtonChecked(hDlg, IDC_DX_MOUSE_GRAB) == BST_CHECKED) - addTransaction(section, "DXGrab", ACTION_SET, "Y"); + addTransaction(keypath("x11drv"), "DXGrab", ACTION_SET, "Y"); else - addTransaction(section, "DXGrab", ACTION_SET, "N"); + addTransaction(keypath("x11drv"), "DXGrab", ACTION_SET, "N"); } void onDoubleBufferClicked(HWND hDlg) { if (IsDlgButtonChecked(hDlg, IDC_DOUBLE_BUFFER) == BST_CHECKED) - addTransaction(section, "DesktopDoubleBuffered", ACTION_SET, "Y"); + addTransaction(keypath("x11drv"), "DesktopDoubleBuffered", ACTION_SET, "Y"); else - addTransaction(section, "DesktopDoubleBuffered", ACTION_SET, "N"); + addTransaction(keypath("x11drv"), "DesktopDoubleBuffered", ACTION_SET, "N"); } INT_PTR CALLBACK