winecfg: new internal api, libraries tab work
Mike Hearn
mike at navi.cx
Sat Sep 25 11:36:14 CDT 2004
Mike Hearn <mike at navi.cx>
- rewrite the transaction system to be based on a settings overlay,
to have a nicer API, and to actually work (always a bonus)
- change the libraries page to be based on a listbox rather than a
treeview, clean up and shrink the code
- add accelerator keys to the libraries page, focus management
- make the window title reflect what the user is currently editing
- remove bogus root warning
- remove some unused control IDs in resource.h
- start converting the x11drv dialog to kernel_style from javaStyle
- bugfixing
-------------- next part --------------
--- programs/winecfg.working/winecfg.c 2004-08-25 19:16:30.000000000 +0100
+++ programs/winecfg/winecfg.c 2004-09-20 21:54:25.042422688 +0100
@@ -19,23 +19,6 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * TODO: (in rough order of priority)
- * - A mind bogglingly vast amount of stuff
- *
- * - Implement autodetect for drive configuration
- * - Figure out whether we need the virtual vs real drive selection stuff at the top of the property page
- * - Implement explicit mode vs instant-apply mode
- * - DLL editing
- * - Multimedia page
- * - Settings migration code (from old configs)
- * - Clean up resource.h, it's a bog
- *
- * Minor things that should be done someday:
- * - Make the desktop size UI a combo box, with a Custom option, so it's more obvious what you might want to choose here
- *
- * BUGS:
- * - x11drv page triggers key writes on entry
- *
*/
#include <assert.h>
@@ -44,49 +27,70 @@
#include <windows.h>
#include <winreg.h>
#include <wine/debug.h>
+#include <wine/list.h>
WINE_DEFAULT_DEBUG_CHANNEL(winecfg);
#include "winecfg.h"
-HKEY configKey = NULL;
+HKEY config_key = NULL;
-int initialize(void) {
- DWORD res = RegCreateKey(HKEY_LOCAL_MACHINE, WINE_KEY_ROOT, &configKey);
- if (res != ERROR_SUCCESS) {
- WINE_ERR("RegOpenKey failed on wine config key (%ld)\n", res);
- return 1;
+
+/* this is called from the WM_SHOWWINDOW handlers of each tab page.
+ *
+ * it's a nasty hack, necessary because the property sheet insists on resetting the window title
+ * to the title of the tab, which is utterly useless. dropping the property sheet is on the todo list.
+ */
+void set_window_title(HWND dialog)
+{
+ char *newtitle;
+
+ /* update the window title */
+ if (currentApp)
+ {
+ char *template = "Wine Configuration for %s";
+ newtitle = HeapAlloc(GetProcessHeap(), 0, strlen(template) + strlen(currentApp) + 1);
+ sprintf(newtitle, template, currentApp);
}
- return 0;
+ else
+ {
+ newtitle = strdupA("Wine Configuration");
+ }
+
+ WINE_TRACE("setting title to %s\n", newtitle);
+ SendMessage(GetParent(dialog), PSM_SETTITLE, 0, (LPARAM) newtitle);
+ HeapFree(GetProcessHeap(), 0, newtitle);
}
-/*****************************************************************************
- * getConfigValue: Retrieves a configuration value from the registry
+/**
+ * getkey: Retrieves a configuration value from the registry
*
- * const char *subKey : the name of the config section
- * const char *valueName : the name of the config value
- * const char *defaultResult : if the key isn't found, return this value instead
+ * char *subkey : the name of the config section
+ * char *name : the name of the config value
+ * char *default : if the key isn't found, return this value instead
*
- * Returns a buffer holding the value if successful, NULL if not. Caller is responsible for freeing the result.
+ * Returns a buffer holding the value if successful, NULL if
+ * not. Caller is responsible for releasing the result.
*
*/
-char *getConfigValue (const char *subkey, const char *valueName, const char *defaultResult)
+static char *getkey (char *subkey, char *name, char *def)
{
- char *buffer = NULL;
- DWORD dataLength;
+ LPBYTE buffer = NULL;
+ DWORD len;
HKEY hSubKey = NULL;
DWORD res;
- WINE_TRACE("subkey=%s, valueName=%s, defaultResult=%s\n", subkey, valueName, defaultResult);
+ WINE_TRACE("subkey=%s, name=%s, def=%s\n", subkey, name, def);
- res = RegOpenKeyEx( configKey, subkey, 0, KEY_ALL_ACCESS, &hSubKey );
- if(res != ERROR_SUCCESS) {
- if( res==ERROR_FILE_NOT_FOUND )
+ res = RegOpenKeyEx(config_key, subkey, 0, KEY_READ, &hSubKey);
+ if (res != ERROR_SUCCESS)
+ {
+ if (res == ERROR_FILE_NOT_FOUND)
{
WINE_TRACE("Section key not present - using default\n");
- return defaultResult ? strdup(defaultResult) : NULL;
+ return def ? strdupA(def) : NULL;
}
else
{
@@ -95,192 +99,367 @@
goto end;
}
- res = RegQueryValueExA( hSubKey, valueName, NULL, NULL, NULL, &dataLength);
- if( res == ERROR_FILE_NOT_FOUND ) {
+ res = RegQueryValueExA(hSubKey, name, NULL, NULL, NULL, &len);
+ if (res == ERROR_FILE_NOT_FOUND)
+ {
WINE_TRACE("Value not present - using default\n");
- buffer = defaultResult ? strdup(defaultResult) : NULL;
+ buffer = def ? strdupA(def) : NULL;
goto end;
- } else if( res!=ERROR_SUCCESS ) {
- WINE_ERR("Couldn't query value's length (res=%ld)\n", res );
- goto end;
- }
-
- buffer = malloc(dataLength);
- if( buffer==NULL )
+ } else if (res != ERROR_SUCCESS)
{
- WINE_ERR("Couldn't allocate %lu bytes for the value\n", dataLength );
+ WINE_ERR("Couldn't query value's length (res=%ld)\n", res);
goto end;
}
-
- RegQueryValueEx(hSubKey, valueName, NULL, NULL, (LPBYTE)buffer, &dataLength);
-
+
+ buffer = HeapAlloc(GetProcessHeap(), 0, len + 1);
+
+ RegQueryValueEx(hSubKey, name, NULL, NULL, buffer, &len);
+
+ WINE_TRACE("buffer=%s\n", buffer);
end:
- if( hSubKey!=NULL )
- RegCloseKey( hSubKey );
+ if (hSubKey) RegCloseKey(hSubKey);
return buffer;
-
}
-/*****************************************************************************
- * setConfigValue : Sets a configuration key in the registry. Section
- * will be created if it doesn't already exist
+/**
+ * setkey: convenience wrapper to set a key/value pair
*
- * HKEY hCurrent : the registry key that the configuration is rooted at
* const char *subKey : the name of the config section
* const char *valueName : the name of the config value
* const char *value : the value to set the configuration key to
*
* Returns 0 on success, non-zero otherwise
- *
- * If *valueName or *value is NULL, an empty section will be created
+ *
+ * If valueName or value is NULL, an empty section will be created
*/
-int setConfigValue (const char *subkey, const char *valueName, const char *value) {
+int setkey(const char *subkey, const char *name, const char *value) {
DWORD res = 1;
HKEY key = NULL;
- WINE_TRACE("subkey=%s, valueName=%s, value=%s\n", subkey, valueName, value);
+ WINE_TRACE("subkey=%s: name=%s, value=%s\n", subkey, name, value);
assert( subkey != NULL );
-
- res = RegCreateKey(configKey, subkey, &key);
+
+ res = RegCreateKey(config_key, subkey, &key);
if (res != ERROR_SUCCESS) goto end;
- if (value == NULL || valueName == NULL) goto end;
+ if (name == NULL || value == NULL) goto end;
- res = RegSetValueEx(key, valueName, 0, REG_SZ, value, strlen(value) + 1);
+ res = RegSetValueEx(key, name, 0, REG_SZ, value, strlen(value) + 1);
if (res != ERROR_SUCCESS) goto end;
res = 0;
end:
if (key) RegCloseKey(key);
- if (res != 0) WINE_ERR("Unable to set configuration key %s in section %s to %s, res=%ld\n", valueName, subkey, value, res);
+ if (res != 0) WINE_ERR("Unable to set configuration key %s in section %s to %s, res=%ld\n", name, subkey, value, res);
return res;
}
-/* returns 0 on success, an HRESULT from the registry funtions otherwise */
-HRESULT doesConfigValueExist(const char *subkey, const char *valueName) {
+/* removes the requested value from the registry, however, does not
+ * remove the section if empty. Returns S_OK (0) on success.
+ */
+static HRESULT remove_value(const char *subkey, const char *name)
+{
HRESULT hr;
HKEY key;
- WINE_TRACE("subkey=%s, valueName=%s - ", subkey, valueName);
-
- hr = RegOpenKeyEx(configKey, subkey, 0, KEY_READ, &key);
- if (hr != S_OK) {
- WINE_TRACE("no: subkey does not exist\n");
- return hr;
+ WINE_TRACE("subkey=%s, name=%s\n", subkey, name);
+
+ hr = RegOpenKeyEx(config_key, subkey, 0, KEY_READ, &key);
+ if (hr != S_OK) return hr;
+
+ hr = RegDeleteValue(key, name);
+ if (hr != ERROR_SUCCESS) return hr;
+
+ return S_OK;
+}
+
+/* removes the requested subkey from the registry, assuming it exists */
+static HRESULT remove_path(char *section) {
+ WINE_TRACE("section=%s\n", section);
+
+ return RegDeleteKey(config_key, section);
+}
+
+
+/* ========================================================================= */
+
+/* This code exists for the following reasons:
+ *
+ * - It makes working with the registry easier
+ * - By storing a mini cache of the registry, we can more easily implement
+ * cancel/revert and apply. The 'settings list' is an overlay on top of
+ * the actual registry data that we can write out at will.
+ *
+ * Rather than model a tree in memory, we simply store each absolute (rooted
+ * at the config key) path.
+ *
+ */
+
+struct setting
+{
+ struct list entry;
+ char *path; /* path in the registry rooted at the config key */
+ char *name; /* name of the registry value */
+ char *value; /* contents of the registry value. if null, this means a deletion */
+};
+
+struct list *settings;
+
+static void free_setting(struct setting *setting)
+{
+ assert( setting != NULL );
+
+ WINE_TRACE("destroying %p\n", setting);
+
+ assert( setting->path && setting->name );
+
+ HeapFree(GetProcessHeap(), 0, setting->path);
+ HeapFree(GetProcessHeap(), 0, setting->name);
+ if (setting->value) HeapFree(GetProcessHeap(), 0, setting->value);
+
+ list_remove(&setting->entry);
+
+ HeapFree(GetProcessHeap(), 0, setting);
+}
+
+/**
+ * Returns the contents of the value at path. If not in the settings
+ * list, it will be fetched from the registry - failing that, the
+ * default will be used.
+ *
+ * If already in the list, the contents as given there will be
+ * returned. You are expected to HeapFree the result.
+ */
+char *get(char *path, char *name, char *def)
+{
+ struct list *cursor;
+ struct setting *s;
+ char *val;
+
+ WINE_TRACE("path=%s, name=%s, def=%s\n", path, name, def);
+
+ /* check if it's in the list */
+ LIST_FOR_EACH( cursor, settings )
+ {
+ s = LIST_ENTRY(cursor, struct setting, entry);
+
+ if (strcasecmp(path, s->path) != 0) continue;
+ if (strcasecmp(name, s->name) != 0) continue;
+
+ WINE_TRACE("found %s:%s in settings list, returning %s\n", path, name, s->value);
+ return strdupA(s->value);
}
- hr = RegQueryValueEx(key, valueName, NULL, NULL, NULL, NULL);
- if (hr != S_OK) {
- WINE_TRACE("no: key does not exist\n");
- return hr;
+ /* no, so get from the registry */
+ val = getkey(path, name, def);
+
+ WINE_TRACE("returning %s\n", val);
+
+ return val;
+}
+
+/**
+ * Used to set a registry key.
+ *
+ * path is rooted at the config key, ie use "Version" or
+ * "AppDefaults\\fooapp.exe\\Version". You can use keypath()
+ * to get such a string.
+ *
+ * name is the value name, it must not be null (you cannot create
+ * empty groups, sorry ...)
+ *
+ * value is what to set the value to, or NULL to delete it.
+ *
+ * These values will be copied when necessary.
+ */
+void set(char *path, char *name, char *value)
+{
+ struct list *cursor;
+ struct setting *s;
+
+ assert( path != NULL );
+ assert( name != NULL );
+
+ WINE_TRACE("path=%s, name=%s, value=%s\n", path, name, value);
+
+ /* firstly, see if we already set this setting */
+ LIST_FOR_EACH( cursor, settings )
+ {
+ struct setting *s = LIST_ENTRY(cursor, struct setting, entry);
+
+ if (strcasecmp(s->path, path) != 0) continue;
+ if (strcasecmp(s->name, name) != 0) continue;
+
+ /* yes, we have already set it, so just replace the content and return */
+ if (s->value) HeapFree(GetProcessHeap(), 0, s->value);
+ s->value = value ? strdupA(value) : NULL;
+
+ return;
}
- RegCloseKey(key);
- WINE_TRACE("yes\n");
- return S_OK;
+ /* otherwise add a new setting for it */
+ s = HeapAlloc(GetProcessHeap(), 0, sizeof(struct setting));
+ s->path = strdupA(path);
+ s->name = strdupA(name);
+ s->value = value ? strdupA(value) : NULL;
+
+ list_add_tail(settings, &s->entry);
}
-/* removes the requested value from the registry, however, does not remove the section if empty. Returns S_OK (0) on success. */
-HRESULT removeConfigValue(const char *subkey, const char *valueName) {
- HRESULT hr;
+/**
+ * enumerates the value names at the given path, taking into account
+ * the changes in the settings list.
+ *
+ * you are expected to HeapFree each element of the array, which is null
+ * terminated, as well as the array itself.
+ */
+char **enumerate_values(char *path)
+{
HKEY key;
- WINE_TRACE("subkey=%s, valueName=%s\n", subkey, valueName);
-
- hr = RegOpenKeyEx(configKey, subkey, 0, KEY_READ, &key);
- if (hr != S_OK) return hr;
+ DWORD res, i = 0;
+ char **values = NULL;
+ int valueslen = 0;
+ struct list *cursor;
- hr = RegDeleteValue(key, valueName);
- if (hr != ERROR_SUCCESS) return hr;
+ res = RegOpenKeyEx(config_key, path, 0, KEY_READ, &key);
+ if (res == ERROR_SUCCESS)
+ {
+ while (TRUE)
+ {
+ char name[1024];
+ DWORD namesize = sizeof(name);
+ BOOL removed = FALSE;
+
+ /* find out the needed size, allocate a buffer, read the value */
+ if ((res = RegEnumValue(key, i, name, &namesize, NULL, NULL, NULL, NULL)) != ERROR_SUCCESS)
+ break;
+
+ WINE_TRACE("name=%s\n", name);
+
+ /* check if this value name has been removed in the settings list */
+ LIST_FOR_EACH( cursor, settings )
+ {
+ struct setting *s = LIST_ENTRY(cursor, struct setting, entry);
+ if (strcasecmp(s->path, path) != 0) continue;
+ if (strcasecmp(s->name, name) != 0) continue;
+
+ if (!s->value)
+ {
+ WINE_TRACE("this key has been removed, so skipping\n");
+ removed = TRUE;
+ break;
+ }
+ }
+
+ if (removed) /* this value was deleted by the user, so don't include it */
+ {
+ HeapFree(GetProcessHeap(), 0, name);
+ i++;
+ continue;
+ }
+
+ /* grow the array if necessary, add buffer to it, iterate */
+ if (values) values = HeapReAlloc(GetProcessHeap(), 0, values, sizeof(char*) * (valueslen + 1));
+ else values = HeapAlloc(GetProcessHeap(), 0, sizeof(char*));
+
+ values[valueslen++] = strdupA(name);
+ WINE_TRACE("valueslen is now %d\n", valueslen);
+ i++;
+ }
+ }
+ else
+ {
+ WINE_WARN("failed opening registry key %s, res=0x%lx\n", path, res);
+ }
- return S_OK;
+ WINE_TRACE("adding settings in list but not registry\n");
+
+ /* now we have to add the values that aren't in the registry but are in the settings list */
+ LIST_FOR_EACH( cursor, settings )
+ {
+ struct setting *setting = LIST_ENTRY(cursor, struct setting, entry);
+ BOOL found = FALSE;
+
+ if (strcasecmp(setting->path, path) != 0) continue;
+
+ if (!setting->value) continue;
+
+ for (i = 0; i < valueslen; i++)
+ {
+ if (strcasecmp(setting->name, values[i]) == 0)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (found) continue;
+
+ WINE_TRACE("%s in list but not registry\n", setting->name);
+
+ /* otherwise it's been set by the user but isn't in the registry */
+ if (values) values = HeapReAlloc(GetProcessHeap(), 0, values, sizeof(char*) * (valueslen + 1));
+ else values = HeapAlloc(GetProcessHeap(), 0, sizeof(char*));
+
+ values[valueslen++] = strdupA(setting->name);
+ }
+
+ WINE_TRACE("adding null terminator\n");
+ if (values)
+ {
+ values = HeapReAlloc(GetProcessHeap(), 0, values, sizeof(char*) * (valueslen + 1));
+ values[valueslen] = NULL;
+ }
+
+ RegCloseKey(key);
+
+ return values;
}
-/* removes the requested configuration section (subkey) from the registry, assuming it exists */
-/* this function might be slightly pointless, but in future we may wish to treat recursion specially etc, so we'll keep it for now */
-HRESULT removeConfigSection(char *section) {
- HRESULT hr;
- WINE_TRACE("section=%s\n", section);
+/**
+ * returns true if the given key/value pair exists in the registry or
+ * has been written to.
+ */
+BOOL exists(char *path, char *name)
+{
+ char *val = get(path, name, NULL);
+
+ if (val)
+ {
+ HeapFree(GetProcessHeap(), 0, val);
+ return TRUE;
+ }
- return hr = RegDeleteKey(configKey, section);
+ return FALSE;
}
+static void process_setting(struct setting *s)
+{
+ if (s->value)
+ {
+ WINE_TRACE("Setting %s:%s to '%s'\n", s->path, s->name, s->value);
+ setkey(s->path, s->name, s->value);
+ }
+ else
+ {
+ /* NULL name means remove that path/section entirely */
+ if (s->path && s->name) remove_value(s->path, s->name);
+ else if (s->path && !s->name) remove_path(s->path);
+ }
+}
-/* ========================================================================= */
-/* Transaction management code */
+void apply(void)
+{
+ if (list_empty(settings)) return; /* we will be called for each page when the user clicks OK */
-struct transaction *tqhead, *tqtail;
-int instantApply = 1;
+ WINE_TRACE("()\n");
-void destroyTransaction(struct transaction *trans) {
- assert( trans != NULL );
-
- WINE_TRACE("destroying %p\n", trans);
-
- free(trans->section);
- if (trans->key) free(trans->key);
- if (trans->newValue) free(trans->newValue);
-
- if (trans->next) trans->next->prev = trans->prev;
- if (trans->prev) trans->prev->next = trans->next;
- if (trans == tqhead) tqhead = NULL;
- if (trans == tqtail) tqtail = NULL;
-
- free(trans);
-}
-
-void addTransaction(const char *section, const char *key, enum transaction_action action, const char *newValue) {
- struct transaction *trans = calloc(sizeof(struct transaction),1);
-
- assert( section != NULL );
- if (action == ACTION_SET) assert( newValue != NULL );
- if (action == ACTION_SET) assert( key != NULL );
-
- trans->section = strdup(section);
- if (key) trans->key = strdup(key);
- if (newValue) trans->newValue = strdup(newValue);
- trans->action = action;
-
- if (tqtail == NULL) {
- tqtail = trans;
- tqhead = tqtail;
- } else {
- tqhead->next = trans;
- trans->prev = tqhead;
- tqhead = trans;
- }
-
- if (instantApply) {
- processTransaction(trans);
- destroyTransaction(trans);
- }
-}
-
-void processTransaction(struct transaction *trans) {
- if (trans->action == ACTION_SET) {
- WINE_TRACE("Setting %s\\%s to '%s'\n", trans->section, trans->key, trans->newValue);
- setConfigValue(trans->section, trans->key, trans->newValue);
- } else if (trans->action == ACTION_REMOVE) {
- if (trans->key) {
- WINE_TRACE("Removing %s\\%s\n", trans->section, trans->key);
- removeConfigValue(trans->section, trans->key);
- } else {
- /* NULL key means remove that section entirely */
- WINE_TRACE("Removing section %s\n", trans->section);
- removeConfigSection(trans->section);
- }
- }
- /* TODO: implement notifications here */
-}
-
-void processTransQueue(void)
-{
- WINE_TRACE("\n");
- while (tqtail != NULL) {
- struct transaction *next = tqtail->next;
- processTransaction(tqtail);
- destroyTransaction(tqtail);
- tqtail = next;
+ while (!list_empty(settings))
+ {
+ struct setting *s = (struct setting *) list_head(settings);
+ process_setting(s);
+ free_setting(s);
}
}
@@ -292,19 +471,19 @@
char *keypath(char *section)
{
static char *result = NULL;
-
- if (result) release(result);
+
+ if (result) HeapFree(GetProcessHeap(), 0, result);
if (currentApp)
{
- result = alloc(strlen("AppDefaults\\") + strlen(currentApp) + 2 /* \\ */ + strlen(section) + 1 /* terminator */);
+ result = HeapAlloc(GetProcessHeap(), 0, strlen("AppDefaults\\") + strlen(currentApp) + 2 /* \\ */ + strlen(section) + 1 /* terminator */);
sprintf(result, "AppDefaults\\%s\\%s", currentApp, section);
}
else
{
result = strdupA(section);
}
-
+
return result;
}
@@ -326,3 +505,18 @@
(LPSTR)&msg, 0, NULL);
WINE_TRACE("error: '%s'\n", msg);
}
+
+int initialize(void) {
+ DWORD res = RegCreateKey(HKEY_LOCAL_MACHINE, WINE_KEY_ROOT, &config_key);
+
+ if (res != ERROR_SUCCESS) {
+ WINE_ERR("RegOpenKey failed on wine config key (%ld)\n", res);
+ return 1;
+ }
+
+ /* we could probably just have the list as static data */
+ settings = HeapAlloc(GetProcessHeap(), 0, sizeof(struct list));
+ list_init(settings);
+
+ return 0;
+}
--- programs/winecfg.working/libraries.c 2004-08-23 17:57:18.000000000 +0100
+++ programs/winecfg/libraries.c 2004-09-20 21:42:43.492074552 +0100
@@ -2,6 +2,7 @@
* WineCfg libraries tabsheet
*
* Copyright 2004 Robert van Herk
+ * 2004 Mike Hearn <mike at navi.cx>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -24,535 +25,324 @@
#include <commdlg.h>
#include <wine/debug.h>
#include <stdio.h>
+#include <assert.h>
#include "winecfg.h"
#include "resource.h"
WINE_DEFAULT_DEBUG_CHANNEL(winecfg);
-typedef enum _DLGMODE
+enum dllmode
{
- DLL,
- APP,
- GLOBAL,
-} DLGMODE;
-
-typedef enum _DLLMODE {
BUILTIN_NATIVE,
NATIVE_BUILTIN,
BUILTIN,
NATIVE,
DISABLE,
- UNKNOWN /*Special value indicating an erronous DLL override mode*/
-} DLLMODE;
+ UNKNOWN /* Special value indicating an erronous DLL override mode */
+};
+
+struct dll
+{
+ char *name;
+ enum dllmode mode;
+};
-static void removeSpaces(char* in, char* out)
+static enum dllmode parse_override(char *in)
{
- int i,j;
- j = 0;
- for (i = 0; i < strlen(in); i++)
- {
- if (in[i] != ' ')
+ int i, j;
+ char *out;
+
+ out = HeapAlloc(GetProcessHeap(), 0, strlen(in));
+
+ /* remove the spaces */
+ j = 0;
+ for (i = 0; i < strlen(in); i++)
{
- out[j] = in[i];
- j++;
+ if (in[i] != ' ')
+ {
+ out[j] = in[i];
+ j++;
+ }
}
- }
- out[j] = 0;
-}
+ out[j] = 0;
+
+ /* parse the string */
+ if (strcmp(out, "builtin,native") == 0) return BUILTIN_NATIVE;
+ else if (strcmp(out, "native,builtin") == 0) return NATIVE_BUILTIN;
+ else if (strcmp(out, "native") == 0) return NATIVE;
+ else if (strcmp(out, "builtin") == 0) return BUILTIN;
+ else if (strcmp(out, "") == 0) return DISABLE;
-static DLLMODE Str2DLLMode(char* c)
-{
- /*Parse a string into a DLLMode*/
- char* d = HeapAlloc(GetProcessHeap(), 0, sizeof(c));
- removeSpaces(c,d);
- if (strcmp (d, "builtin,native") == 0) {
- return BUILTIN_NATIVE;
- } else
- if (strcmp (d, "native,builtin") == 0) {
- return NATIVE_BUILTIN;
- } else
- if (strcmp (d, "native") == 0){
- return NATIVE;
- } else
- if (strcmp (d, "builtin") == 0) {
- return BUILTIN;
- } else
- if (strcmp (d, "") == 0) {
- return DISABLE;
- } else
return UNKNOWN;
}
-static char* DLLMode2Str(DLLMODE mode)
+/* this is used to convert a dllmode to a human readable string. we should read from the translations here */
+static char* mode_to_label(enum dllmode mode)
{
- char* res;
- switch (mode) {
- case NATIVE:
- res = "native";
- break;
- case BUILTIN:
- res = "builtin";
- break;
- case NATIVE_BUILTIN:
- res = "native, builtin";
- break;
- case BUILTIN_NATIVE:
- res = "builtin, native";
- break;
- case DISABLE:
- res = "";
- break;
- default:
- res = "unknown";
- }
- return strdup(res);
-}
+ char* res;
-typedef struct _DLLOVERRIDE
-{
- char* lpcKey; /*The actual dll name*/
- DLLMODE mode;
-} DLLOVERRIDE, *LPDLLOVERRIDE;
+ switch (mode) {
+ case NATIVE:
+ res = "native";
+ break;
+ case BUILTIN:
+ res = "builtin";
+ break;
+ case NATIVE_BUILTIN:
+ res = "native, builtin";
+ break;
+ case BUILTIN_NATIVE:
+ res = "builtin, native";
+ break;
+ case DISABLE:
+ res = "disabled";
+ break;
+ default:
+ res = "unknown/invalid";
+ break;
+ }
-static LPDLLOVERRIDE CreateDLLOverride(char* lpcKey)
-{
- LPDLLOVERRIDE out = HeapAlloc(GetProcessHeap(),0,sizeof(DLLOVERRIDE));
- out->lpcKey = strdup (lpcKey);
- return out;
+ return res;
}
-static VOID FreeDLLOverride(LPDLLOVERRIDE ldo)
+static void set_controls_from_selection(HWND dialog)
{
- if (ldo->lpcKey)
- free(ldo->lpcKey);
- HeapFree(GetProcessHeap(),0,ldo);
-}
+ int index = SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_GETCURSEL, 0, 0);
+ struct dll *dll;
+ DWORD id;
+ int i;
+
+ if (index == -1) /* no selection */
+ {
+ for (i = IDC_RAD_BUILTIN; i <= IDC_RAD_DISABLE; i++)
+ disable(i);
-typedef struct _APPL
-{
- BOOL isGlobal;
- char* lpcApplication;
- char* lpcSection; /*Registry section*/
-} APPL, *LPAPPL;
+ CheckRadioButton(dialog, IDC_RAD_BUILTIN, IDC_RAD_DISABLE, -1);
+
+ return;
+ }
-static LPAPPL CreateAppl(BOOL isGlobal, char* application, char* section)
-{
- LPAPPL out;
- out = HeapAlloc(GetProcessHeap(),0,sizeof(APPL));
- out->lpcApplication = strdup(application);
- out->lpcSection = strdup(section);
- out->isGlobal = isGlobal;
- return out;
-}
+ /* enable the controls */
+ for (i = IDC_RAD_BUILTIN; i <= IDC_RAD_DISABLE; i++)
+ enable(i);
+
+ dll = (struct dll *) SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_GETITEMDATA, index, 0);
+
+ switch (dll->mode)
+ {
+ case NATIVE:
+ id = IDC_RAD_NATIVE;
+ break;
+ case BUILTIN:
+ id = IDC_RAD_BUILTIN;
+ break;
+ case NATIVE_BUILTIN:
+ id = IDC_RAD_NATIVE_BUILTIN;
+ break;
+ case BUILTIN_NATIVE:
+ id = IDC_RAD_BUILTIN_NATIVE;
+ break;
+ case DISABLE:
+ id = IDC_RAD_DISABLE;
+ break;
+
+ case UNKNOWN:
+ default:
+ id = -1;
+ break;
+ }
-static VOID FreeAppl(LPAPPL lpAppl)
-{
- if (lpAppl->lpcApplication)
- free(lpAppl->lpcApplication); /* The strings were strdup-ped, so we use "free" */
- if (lpAppl->lpcSection)
- free(lpAppl->lpcSection);
- HeapFree(GetProcessHeap(),0,lpAppl);
+ CheckRadioButton(dialog, IDC_RAD_BUILTIN, IDC_RAD_DISABLE, id);
}
-typedef struct _ITEMTAG
-{
- LPAPPL lpAppl;
- LPDLLOVERRIDE lpDo;
-} ITEMTAG, *LPITEMTAG;
-static LPITEMTAG CreateItemTag()
+static void clear_settings(HWND dialog)
{
- LPITEMTAG out;
- out = HeapAlloc(GetProcessHeap(),0,sizeof(ITEMTAG));
- out->lpAppl = 0;
- out->lpDo = 0;
- return out;
-}
+ int count = SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_GETCOUNT, 0, 0);
+ int i;
-static VOID FreeItemTag(LPITEMTAG lpit)
-{
- if (lpit->lpAppl)
- FreeAppl(lpit->lpAppl);
- if (lpit->lpDo)
- FreeDLLOverride(lpit->lpDo);
- HeapFree(GetProcessHeap(),0,lpit);
+ WINE_TRACE("count=%d\n", count);
+
+ for (i = 0; i < count; i++)
+ {
+ struct dll *dll = (struct dll *) SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_GETITEMDATA, 0, 0);
+
+ SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_DELETESTRING, 0, 0);
+
+ HeapFree(GetProcessHeap(), 0, dll->name);
+ HeapFree(GetProcessHeap(), 0, dll);
+ }
}
-static VOID UpdateDLLList(HWND hDlg, char* dll)
+static void load_library_settings(HWND dialog)
{
- /*Add if it isn't already in*/
- if (SendDlgItemMessage(hDlg, IDC_DLLLIST, CB_FINDSTRING, 1, (LPARAM) dll) == CB_ERR)
- SendDlgItemMessage(hDlg,IDC_DLLLIST,CB_ADDSTRING,0,(LPARAM) dll);
-}
+ char **overrides = enumerate_values(keypath("DllOverrides"));
+ char **p;
+ int sel, count = 0;
-static VOID LoadLibrarySettings(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];
- LPITEMTAG lpIt;
- TVINSERTSTRUCT tis;
- HTREEITEM hParent;
- LPDLLOVERRIDE lpdo;
-
- WINE_TRACE("opening %s\n", appl->lpcSection);
- if (RegOpenKey (configKey, appl->lpcSection, &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;
-
- while (RegEnumValue(key, i, name, &size, NULL, NULL, read, &readSize) == ERROR_SUCCESS)
- {
- WINE_TRACE("Reading value %s, namely %s\n", name, read);
-
- lpIt = CreateItemTag();
- lpdo = CreateDLLOverride(name);
- lpIt->lpDo = lpdo;
- tis.u.item.lParam = (LPARAM)lpIt;
- tis.u.item.pszText = name;
-
- lpdo->mode = Str2DLLMode(read);
-
- TreeView_InsertItem(hwndTV,&tis);
- UpdateDLLList(hDlg, name);
- i ++; size = 255; readSize = 255;
- }
- RegCloseKey(key);
- }
-}
+ sel = SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_GETCURSEL, 0, 0);
-static VOID SetEnabledDLLControls(HWND dialog, DLGMODE dlgmode)
-{
- if (dlgmode == DLL) {
- enable(IDC_RAD_BUILTIN);
- enable(IDC_RAD_NATIVE);
- enable(IDC_RAD_BUILTIN_NATIVE);
- enable(IDC_RAD_NATIVE_BUILTIN);
- enable(IDC_RAD_DISABLE);
- enable(IDC_DLLS_REMOVEDLL);
- } else {
- disable(IDC_RAD_BUILTIN);
- disable(IDC_RAD_NATIVE);
- disable(IDC_RAD_BUILTIN_NATIVE);
- disable(IDC_RAD_NATIVE_BUILTIN);
- disable(IDC_RAD_DISABLE);
- disable(IDC_DLLS_REMOVEDLL);
- }
+ WINE_TRACE("sel=%d\n", sel);
- if (dlgmode == APP) {
- enable(IDC_DLLS_REMOVEAPP);
- }
- else {
- disable(IDC_DLLS_REMOVEAPP);
- }
-}
+ clear_settings(dialog);
+
+ if (!overrides || *overrides == NULL)
+ {
+ set_controls_from_selection(dialog);
+ disable(IDC_DLLS_REMOVEDLL);
+ HeapFree(GetProcessHeap(), 0, overrides);
+ return;
+ }
-static VOID OnInitLibrariesDlg(HWND hDlg)
-{
- HWND hwndTV;
- LPAPPL lpAppl;
- HKEY applKey;
- int i;
- DWORD size;
- char appl [255];
- char lpcKey [255];
- FILETIME ft;
-
- hwndTV = GetDlgItem(hDlg,IDC_TREE_DLLS);
- lpAppl = CreateAppl(TRUE,"Global DLL Overrides", "DllOverrides");
- LoadLibrarySettings(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(lpcKey, "AppDefaults\\%s\\DllOverrides", appl);
- lpAppl = CreateAppl(FALSE,appl, lpcKey);
- LoadLibrarySettings(lpAppl, hDlg, hwndTV);
- i++; size = 255;
- }
- RegCloseKey(applKey);
- }
+ enable(IDC_DLLS_REMOVEDLL);
+
+ for (p = overrides; *p != NULL; p++)
+ {
+ int index;
+ char *str, *value, *label;
+ struct dll *dll;
+
+ value = get(keypath("DllOverrides"), *p, NULL);
+
+ label = mode_to_label(parse_override(value));
+
+ str = HeapAlloc(GetProcessHeap(), 0, strlen(*p) + 2 + strlen(label) + 2);
+ strcpy(str, *p);
+ strcat(str, " (");
+ strcat(str, label);
+ strcat(str, ")");
+
+ dll = HeapAlloc(GetProcessHeap(), 0, sizeof(struct dll));
+ dll->name = *p;
+ dll->mode = parse_override(value);
- SetEnabledDLLControls(hDlg, GLOBAL);
-}
+ index = SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_ADDSTRING, (WPARAM) -1, (LPARAM) str);
+ SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_SETITEMDATA, index, (LPARAM) dll);
-static VOID OnTreeViewChangeItem(HWND hDlg, HWND hTV)
-{
- TVITEM ti;
- LPITEMTAG lpit;
- int buttonId;
+ HeapFree(GetProcessHeap(), 0, str);
- ti.mask = TVIF_PARAM;
- ti.hItem = TreeView_GetSelection(hTV);
- if (TreeView_GetItem (hTV, &ti))
- {
- lpit = (LPITEMTAG) ti.lParam;
- if (lpit->lpDo)
- {
- WINE_TRACE("%s\n", lpit->lpDo->lpcKey);
- buttonId = IDC_RAD_BUILTIN;
- switch (lpit->lpDo->mode)
- {
- case NATIVE:
- buttonId = IDC_RAD_NATIVE;
- break;
- case BUILTIN:
- buttonId = IDC_RAD_BUILTIN;
- break;
- case NATIVE_BUILTIN:
- buttonId = IDC_RAD_NATIVE_BUILTIN;
- break;
- case BUILTIN_NATIVE:
- buttonId = IDC_RAD_BUILTIN_NATIVE;
- break;
- case DISABLE:
- buttonId = IDC_RAD_DISABLE;
- break;
- case UNKNOWN:
- buttonId = -1;
- break;
- }
- CheckRadioButton(hDlg, IDC_RAD_BUILTIN, IDC_RAD_DISABLE, buttonId);
- SetEnabledDLLControls(hDlg, DLL);
- } else {
- if (lpit->lpAppl)
- {
- if (lpit->lpAppl->isGlobal == TRUE)
- SetEnabledDLLControls(hDlg, GLOBAL);
- else
- SetEnabledDLLControls(hDlg, APP);
- }
- }
- }
-}
+ count++;
+ }
-static VOID SetDLLMode(HWND hDlg, DLLMODE mode)
-{
- HWND hTV;
- TVITEM ti;
- LPITEMTAG lpit;
- char* cMode;
- TVITEM tiPar;
- LPITEMTAG lpitPar;
-
- hTV = GetDlgItem(hDlg, IDC_TREE_DLLS);
- ti.mask = TVIF_PARAM;
- ti.hItem = TreeView_GetSelection(hTV);
- if (TreeView_GetItem (hTV, &ti))
- {
- lpit = (LPITEMTAG) ti.lParam;
- if (lpit->lpDo)
- {
- lpit->lpDo->mode = mode;
- cMode = DLLMode2Str (mode);
- /*Find parent, so we can read registry section*/
- tiPar.mask = TVIF_PARAM;
- tiPar.hItem = TreeView_GetParent(hTV, ti.hItem);
- if (TreeView_GetItem(hTV,&tiPar))
- {
- lpitPar = (LPITEMTAG) tiPar.lParam;
- if (lpitPar->lpAppl)
- {
- addTransaction(lpitPar->lpAppl->lpcSection, lpit->lpDo->lpcKey, ACTION_SET, cMode);
- }
- }
- free(cMode);
- }
- }
-}
+ HeapFree(GetProcessHeap(), 0, overrides);
-static VOID OnBuiltinClick(HWND hDlg)
-{
- SetDLLMode(hDlg, BUILTIN);
-}
+ /* restore the previous selection, if possible */
+ if (sel >= count - 1) sel = count - 1;
+ else if (sel == -1) sel = 0;
+
+ SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_SETCURSEL, sel, 0);
-static VOID OnNativeClick(HWND hDlg)
-{
- SetDLLMode(hDlg, NATIVE);
+ set_controls_from_selection(dialog);
}
-static VOID OnBuiltinNativeClick(HWND hDlg)
+/* Called when the application is initialized (cannot reinit!) */
+static void init_libsheet(HWND dialog)
{
- SetDLLMode(hDlg, BUILTIN_NATIVE);
+ /* clear the add dll controls */
+ SendDlgItemMessage(dialog, IDC_DLLCOMBO, WM_SETTEXT, 1, (LPARAM) "");
+ disable(IDC_DLLS_ADDDLL);
}
-static VOID OnNativeBuiltinClick(HWND hDlg)
-{
- SetDLLMode(hDlg, NATIVE_BUILTIN);
-}
-static VOID OnDisableClick(HWND hDlg)
+static void on_add_combo_change(HWND dialog)
{
- SetDLLMode(hDlg, DISABLE);
-}
+ char buffer[1024];
-static VOID OnTreeViewDeleteItem(NMTREEVIEW* nmt)
-{
- FreeItemTag((LPITEMTAG)(nmt->itemOld.lParam));
+ SendDlgItemMessage(dialog, IDC_DLLCOMBO, WM_GETTEXT, sizeof(buffer), (LPARAM) buffer);
+
+ if (strlen(buffer))
+ enable(IDC_DLLS_ADDDLL)
+ else
+ disable(IDC_DLLS_ADDDLL);
}
-static VOID OnAddDLLClick(HWND hDlg)
+static void set_dllmode(HWND dialog, DWORD id)
{
- HWND hTV;
- TVITEM ti;
- LPITEMTAG lpit;
- LPITEMTAG lpitNew;
- TVITEM childti;
- char dll [255];
- BOOL doAdd;
- TVINSERTSTRUCT tis;
+ enum dllmode mode;
+ struct dll *dll;
+ int sel;
+ char *str;
- hTV = GetDlgItem(hDlg, IDC_TREE_DLLS);
- ti.mask = TVIF_PARAM;
- ti.hItem = TreeView_GetSelection(hTV);
- if (TreeView_GetItem (hTV, &ti))
- {
- lpit = (LPITEMTAG) ti.lParam;
- if (lpit->lpDo) { /*Is this a DLL override (that is: a subitem), then find the parent*/
- ti.hItem = TreeView_GetParent(hTV, ti.hItem);
- if (TreeView_GetItem(hTV,&ti)) {
- lpit = (LPITEMTAG) ti.lParam;
- } else return;
- }
- } else return;
- /*Now we should have an parent item*/
- if (lpit->lpAppl)
- {
- lpitNew = CreateItemTag();
- SendDlgItemMessage(hDlg,IDC_DLLLIST,WM_GETTEXT,(WPARAM)255, (LPARAM) dll);
- if (strlen(dll) > 0) {
- /*Is the dll already in the list? If so, don't do it*/
- doAdd = TRUE;
- childti.mask = TVIF_PARAM;
- if ((childti.hItem = TreeView_GetNextItem(hTV, ti.hItem, TVGN_CHILD))) {
- /*Retrieved first child*/
- while (TreeView_GetItem (hTV, &childti))
- {
- if (strcmp(((LPITEMTAG)childti.lParam)->lpDo->lpcKey,dll) == 0) {
- doAdd = FALSE;
- break;
- }
- childti.hItem = TreeView_GetNextItem(hTV, childti.hItem, TVGN_NEXT);
- }
- }
- if (doAdd)
- {
- lpitNew->lpDo = CreateDLLOverride(dll);
- lpitNew->lpDo->mode = NATIVE;
- tis.hInsertAfter = TVI_LAST;
- tis.u.item.mask = TVIF_TEXT | TVIF_PARAM;
- tis.u.item.pszText = dll;
- tis.u.item.lParam = (LPARAM)lpitNew;
- tis.hParent = ti.hItem;
- TreeView_InsertItem(hTV,&tis);
- UpdateDLLList(hDlg, dll);
- addTransaction(lpit->lpAppl->lpcSection, dll, ACTION_SET, "native");
- } else MessageBox(hDlg, "A DLL with that name is already in this list...", "", MB_OK | MB_ICONINFORMATION);
- }
- } else return;
-}
+#define CONVERT(s) case IDC_RAD_##s: mode = s; break;
+
+ switch (id)
+ {
+ CONVERT( BUILTIN );
+ CONVERT( NATIVE );
+ CONVERT( BUILTIN_NATIVE );
+ CONVERT( NATIVE_BUILTIN );
+ CONVERT( DISABLE );
-static VOID OnRemoveDLLClick(HWND hDlg)
-{
- HWND hTV;
- TVITEM ti;
- LPITEMTAG lpit;
- TVITEM tiPar;
- LPITEMTAG lpitPar;
-
- hTV = GetDlgItem(hDlg, IDC_TREE_DLLS);
- ti.mask = TVIF_PARAM;
- ti.hItem = TreeView_GetSelection(hTV);
- if (TreeView_GetItem (hTV, &ti)) {
- lpit = (LPITEMTAG) ti.lParam;
- if (lpit->lpDo)
- {
- /*Find parent for section*/
- tiPar.mask = TVIF_PARAM;
- tiPar.hItem = TreeView_GetParent(hTV, ti.hItem);
- if (TreeView_GetItem(hTV,&tiPar))
- {
- lpitPar = (LPITEMTAG) tiPar.lParam;
- if (lpitPar->lpAppl)
- {
- addTransaction(lpitPar->lpAppl->lpcSection, lpit->lpDo->lpcKey, ACTION_REMOVE, NULL);
- TreeView_DeleteItem(hTV,ti.hItem);
- }
- }
- }
- }
+ default: assert( FALSE ); /* should not be reached */
+ }
+
+#undef CONVERT
+
+ sel = SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_GETCURSEL, 0, 0);
+ if (sel == -1) return;
+
+ dll = (struct dll *) SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_GETITEMDATA, sel, 0);
+
+ switch (mode)
+ {
+ case BUILTIN: str = "builtin"; break;
+ case NATIVE: str = "native"; break;
+ case BUILTIN_NATIVE: str = "builtin, native"; break;
+ case NATIVE_BUILTIN: str = "native, builtin"; break;
+ case DISABLE: str = ""; break;
+ default: assert( FALSE ); /* unreachable */
+ }
+ WINE_TRACE("Setting %s to %s\n", dll->name, str);
+
+ set(keypath("DllOverrides"), dll->name, str);
+
+ load_library_settings(dialog); /* ... and refresh */
}
-static VOID OnAddApplicationClick(HWND hDlg)
+static void on_add_click(HWND dialog)
{
- char szFileTitle [255];
- char szFile [255];
- char lpcKey [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);
+ char buffer[1024];
- 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(lpcKey, "AppDefaults\\%s\\DllOverrides", szFileTitle);
- lpit->lpAppl = CreateAppl(FALSE,szFileTitle,lpcKey);
- tis.u.item.lParam = (LPARAM)lpit;
- TreeView_InsertItem(GetDlgItem(hDlg,IDC_TREE_DLLS), &tis);
- setConfigValue(lpcKey,NULL,NULL);
- }
+ ZeroMemory(buffer, sizeof(buffer));
+
+ SendDlgItemMessage(dialog, IDC_DLLCOMBO, WM_GETTEXT, sizeof(buffer), (LPARAM) buffer);
+
+ SendDlgItemMessage(dialog, IDC_DLLCOMBO, WM_SETTEXT, 0, (LPARAM) "");
+ disable(IDC_DLLS_ADDDLL);
+
+ WINE_TRACE("Adding %s as native, builtin", buffer);
+
+ set(keypath("DllOverrides"), buffer, "native,builtin");
+
+ load_library_settings(dialog);
+
+ SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_SELECTSTRING, (WPARAM) 0, (LPARAM) buffer);
+
+ set_controls_from_selection(dialog);
}
-static VOID OnRemoveApplicationClick(HWND hDlg)
+static void on_remove_click(HWND dialog)
{
- HWND hTV;
- TVITEM ti;
- LPITEMTAG lpit;
-
- hTV = GetDlgItem(hDlg, IDC_TREE_DLLS);
- ti.mask = TVIF_PARAM;
- ti.hItem = TreeView_GetSelection(hTV);
- if (TreeView_GetItem (hTV, &ti)) {
- lpit = (LPITEMTAG) ti.lParam;
- if (lpit->lpAppl)
- {
- addTransaction(lpit->lpAppl->lpcSection, NULL, ACTION_REMOVE, NULL);
- TreeView_DeleteItem(hTV,ti.hItem);
- }
- }
+ int sel = SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_GETCURSEL, 0, 0);
+ struct dll *dll;
+
+ if (sel == LB_ERR) return;
+
+ dll = (struct dll *) SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_GETITEMDATA, sel, 0);
+
+ SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_DELETESTRING, sel, 0);
+
+ set(keypath("DllOverrides"), dll->name, NULL);
+
+ HeapFree(GetProcessHeap(), 0, dll->name);
+ HeapFree(GetProcessHeap(), 0, dll);
+
+ if (SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_GETCOUNT, 0, 0) > 0)
+ SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_SETCURSEL, max(sel - 1, 0), 0);
+ else
+ disable(IDC_DLLS_REMOVEDLL);
+
+ set_controls_from_selection(dialog);
}
INT_PTR CALLBACK
@@ -561,56 +351,53 @@
switch (uMsg)
{
case WM_INITDIALOG:
- OnInitLibrariesDlg(hDlg);
- break;
+ init_libsheet(hDlg);
+ break;
+ case WM_SHOWWINDOW:
+ set_window_title(hDlg);
+ break;
case WM_NOTIFY:
switch (((LPNMHDR)lParam)->code) {
- case TVN_SELCHANGED: {
- switch(LOWORD(wParam)) {
- case IDC_TREE_DLLS:
- OnTreeViewChangeItem(hDlg, GetDlgItem(hDlg,IDC_TREE_DLLS));
- break;
- }
- }
- break;
- case TVN_DELETEITEM:
- OnTreeViewDeleteItem ((LPNMTREEVIEW)lParam);
- break;
+ case PSN_SETACTIVE:
+ load_library_settings(hDlg);
+ break;
}
break;
case WM_COMMAND:
switch(HIWORD(wParam)) {
+
+ /* FIXME: when the user hits enter in the DLL combo box we should invoke the add
+ * add button, rather than the propsheet OK button. But I don't know how to do that!
+ */
+
+ case CBN_EDITCHANGE:
+ if(LOWORD(wParam) == IDC_DLLCOMBO)
+ {
+ on_add_combo_change(hDlg);
+ break;
+ }
+
case BN_CLICKED:
switch(LOWORD(wParam)) {
case IDC_RAD_BUILTIN:
- OnBuiltinClick(hDlg);
- break;
case IDC_RAD_NATIVE:
- OnNativeClick(hDlg);
- break;
case IDC_RAD_BUILTIN_NATIVE:
- OnBuiltinNativeClick(hDlg);
- break;
case IDC_RAD_NATIVE_BUILTIN:
- OnNativeBuiltinClick(hDlg);
- break;
case IDC_RAD_DISABLE:
- OnDisableClick(hDlg);
- break;
- case IDC_DLLS_ADDAPP:
- OnAddApplicationClick(hDlg);
- break;
- case IDC_DLLS_REMOVEAPP:
- OnRemoveApplicationClick(hDlg);
- break;
+ set_dllmode(hDlg, LOWORD(wParam));
+ break;
+
case IDC_DLLS_ADDDLL:
- OnAddDLLClick(hDlg);
- break;
+ on_add_click(hDlg);
+ break;
case IDC_DLLS_REMOVEDLL:
- OnRemoveDLLClick(hDlg);
- break;
+ on_remove_click(hDlg);
+ break;
}
break;
+ case LBN_SELCHANGE:
+ set_controls_from_selection(hDlg);
+ break;
}
break;
}
--- programs/winecfg.working/winecfg.h 2004-08-25 20:46:30.000000000 +0100
+++ programs/winecfg/winecfg.h 2004-09-20 22:02:16.931684616 +0100
@@ -45,31 +45,22 @@
}
#define WRITEME(owner) MessageBox(owner, "Write me!", "", MB_OK | MB_ICONEXCLAMATION);
-
-
-/* Transaction management */
-enum transaction_action {
- ACTION_SET,
- ACTION_REMOVE
-};
-
-struct transaction {
- char *section;
- char *key;
- char *newValue;
- enum transaction_action action;
- struct transaction *next, *prev;
-};
-extern struct transaction *tqhead, *tqtail;
-
-extern int instantApply; /* non-zero means apply all changes instantly */
-
-#define EDITING_GLOBAL 0
-#define EDITING_APP 1
-extern int appSettings; /* non-zero means we are editing appdefault settings */
extern char *currentApp; /* NULL means editing global settings */
+/* Use get and set to alter registry settings. The changes made through set
+ won't be committed to the registry until process_all_settings is called,
+ however get will still return accurate information.
+
+ You are expected to release the result of get. The parameters to set will
+ be copied, so release them too when necessary.
+ */
+void set(char *path, char *name, char *value);
+char *get(char *path, char *name, char *def);
+BOOL exists(char *path, char *name);
+void apply(void);
+char **enumerate_values(char *path);
+
/* returns a string of the form "AppDefaults\\appname.exe\\section", or just "section" if
* the user is editing the global settings.
*
@@ -77,31 +68,11 @@
*/
char *keypath(char *section);
-/* Commits a transaction to the registry */
-void processTransaction(struct transaction *trans);
-
-/* Processes every pending transaction in the queue, removing them as it works from head to tail */
-void processTransQueue();
-
-/* Adds a transaction to the head of the queue. If we're using instant apply, this calls processTransaction
- * action can be either:
- * ACTION_SET -> this transaction will change a registry key, newValue is the replacement value
- * ACTION_REMOVE -> this transaction will remove a registry key. In this case, newValue is ignored.
- */
-void addTransaction(const char *section, const char *key, enum transaction_action action, const char *newValue);
-
-/* frees the transaction structure, all fields, and removes it from the queue if in it */
-void destroyTransaction(struct transaction *trans);
-
/* Initializes the transaction system */
int initialize(void);
-extern HKEY configKey;
+extern HKEY config_key;
-/* 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);
-HRESULT removeConfigValue (const char *subkey, const char *valueName);
+void set_window_title(HWND dialog);
/* Graphics */
@@ -125,14 +96,12 @@
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));
+ char *r = HeapAlloc(GetProcessHeap(), 0, strlen(s));
return strcpy(r, s);
}
--- programs/winecfg.working/En.rc 2004-08-25 19:16:30.000000000 +0100
+++ programs/winecfg/En.rc 2004-09-20 21:45:51.203538072 +0100
@@ -84,20 +84,18 @@
FONT 8, "MS Sans Serif"
BEGIN
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."
+ LTEXT "Dynamic Link Libraries can be specified individually to be either builtin (provided by Wine) or native (taken from Windows or provided by the application)."
, IDC_STATIC,15,17,228,32
- CONTROL "DLL Overrides", IDC_TREE_DLLS, "SysTreeView32", WS_BORDER | WS_TABSTOP | TVS_LINESATROOT | TVS_HASLINES | TVS_SHOWSELALWAYS | TVS_HASBUTTONS, 15,50,142,187
+ LISTBOX IDC_DLLS_LIST,15,50,142,187,WS_BORDER | WS_TABSTOP | WS_VSCROLL
LTEXT "Load order:",IDC_STATIC,163,50,37,8
- CONTROL "Builtin (Wine)",IDC_RAD_BUILTIN,"Button", BS_AUTORADIOBUTTON | WS_GROUP,163,65,75,10
- CONTROL "Native (Windows)",IDC_RAD_NATIVE,"Button", BS_AUTORADIOBUTTON,163,80,75,10
- CONTROL "Builtin, Native",IDC_RAD_BUILTIN_NATIVE,"Button", BS_AUTORADIOBUTTON,163,95,75,10
- CONTROL "Native, Builtin",IDC_RAD_NATIVE_BUILTIN,"Button", BS_AUTORADIOBUTTON,163,110,75,10
- CONTROL "Disable",IDC_RAD_DISABLE,"Button", BS_AUTORADIOBUTTON,163,125,75,10
- PUSHBUTTON "Add application...",IDC_DLLS_ADDAPP,163,144,82,14
- PUSHBUTTON "Remove application",IDC_DLLS_REMOVEAPP, 163,164,82,14
- PUSHBUTTON "Add DLL override for:",IDC_DLLS_ADDDLL, 163,184,82,14
- COMBOBOX IDC_DLLLIST,163,204,82,14,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP | CBS_SORT | CBS_LOWERCASE
- PUSHBUTTON "Remove DLL override",IDC_DLLS_REMOVEDLL,163,224,82,14
+ CONTROL "&Builtin (Wine)",IDC_RAD_BUILTIN,"Button", BS_AUTORADIOBUTTON | WS_GROUP,163,65,75,10
+ CONTROL "&Native (Windows)",IDC_RAD_NATIVE,"Button", BS_AUTORADIOBUTTON,163,80,75,10
+ CONTROL "Bui<in then Native",IDC_RAD_BUILTIN_NATIVE,"Button", BS_AUTORADIOBUTTON,163,95,75,10
+ CONTROL "Nati&ve then Builtin",IDC_RAD_NATIVE_BUILTIN,"Button", BS_AUTORADIOBUTTON,163,110,75,10
+ CONTROL "&Disable",IDC_RAD_DISABLE,"Button", BS_AUTORADIOBUTTON,163,125,75,10
+ PUSHBUTTON "&Add DLL override for:",IDC_DLLS_ADDDLL, 163,184,82,14
+ COMBOBOX IDC_DLLCOMBO,163,204,82,14,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP | CBS_SORT | CBS_LOWERCASE
+ PUSHBUTTON "&Remove DLL override",IDC_DLLS_REMOVEDLL,163,224,82,14
END
IDD_SYSTEMCFG DIALOG DISCARDABLE 0, 0, 260, 250
--- programs/winecfg.working/appdefaults.c 2004-08-25 19:16:30.000000000 +0100
+++ programs/winecfg/appdefaults.c 2004-09-19 18:02:17.000000000 +0100
@@ -40,23 +40,21 @@
char *winver, *dosver;
/* retrieve the registry values */
- winver = getConfigValue(keypath("Version"), "Windows", NULL);
- dosver = getConfigValue(keypath("Version"), "DOS", NULL);
+ winver = get(keypath("Version"), "Windows", "");
+ dosver = get(keypath("Version"), "DOS", "");
- /* NULL winver/dosver means use automatic mode (ie the builtin dll linkage heuristics) */
+ /* empty 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)");
+ WINE_TRACE("winver is %s\n", *winver != '\0' ? winver : "null (automatic mode)");
+ WINE_TRACE("dosver is %s\n", *dosver != '\0' ? dosver : "null (automatic mode)");
/* normalize the version strings */
- if (winver && strlen(winver))
+ if (*winver != '\0')
{
if ((pVer = getWinVersions ()))
{
- 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, winver))
{
SendDlgItemMessage (dialog, IDC_WINVER, CB_SETCURSEL, (WPARAM) (i + 1), 0);
@@ -71,14 +69,12 @@
SendDlgItemMessage (dialog, IDC_WINVER, CB_SETCURSEL, 0, 0);
}
- if (dosver && strlen(dosver))
+ if (*dosver != '\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, dosver))
{
SendDlgItemMessage (dialog, IDC_DOSVER, CB_SETCURSEL,
@@ -93,9 +89,9 @@
WINE_TRACE("setting dosver combobox to automatic/default\n");
SendDlgItemMessage (dialog, IDC_DOSVER, CB_SETCURSEL, 0, 0);
}
-
- if (winver) free(winver);
- if (dosver) free(dosver);
+
+ HeapFree(GetProcessHeap(), 0, winver);
+ HeapFree(GetProcessHeap(), 0, dosver);
}
void
@@ -153,6 +149,7 @@
ListView_InsertItem(listview, &item);
}
+/* Called when the application is initialized (cannot reinit!) */
static void init_appsheet(HWND dialog)
{
HWND listview;
@@ -160,22 +157,21 @@
int i;
DWORD size;
char appname[1024];
- FILETIME ft;
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)
+
+ /* because this list is only populated once, it's safe to bypass the settings list here */
+ if (RegOpenKey(config_key, "AppDefaults", &key) == ERROR_SUCCESS)
{
i = 0;
size = sizeof(appname);
- while (RegEnumKeyEx(key, i, appname, &size, NULL, NULL, NULL, &ft) == ERROR_SUCCESS)
+ while (RegEnumKeyEx(key, i, appname, &size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
add_listview_item(listview, appname, strdup(appname));
@@ -218,12 +214,13 @@
return -1;
}
+
/* called when the user selects a different application */
static void on_selection_change(HWND dialog, HWND listview)
{
LVITEM item;
char *oldapp = currentApp;
-
+
WINE_TRACE("()\n");
item.iItem = get_listview_selection(listview);
@@ -253,6 +250,8 @@
init_comboboxes(dialog);
update_comboboxes(dialog);
+
+ set_window_title(dialog);
}
static void on_add_app_click(HWND dialog)
@@ -295,14 +294,14 @@
{
HWND listview = GetDlgItem(dialog, IDC_APP_LISTVIEW);
int selection = get_listview_selection(listview);
- char *section = keypath("");
+ char *section = keypath(""); /* AppDefaults\\whatever.exe\\ */
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);
+ set(section, NULL, NULL); /* delete the section */
ListView_DeleteItem(listview, selection);
SetFocus(listview);
@@ -316,13 +315,16 @@
if (selection == 0)
{
WINE_TRACE("automatic/default selected so removing current setting\n");
- addTransaction(keypath("Version"), "Windows", ACTION_REMOVE, NULL);
+ set(keypath("Version"), "Windows", 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);
+ set(keypath("Version"), "Windows", ver[selection - 1].szVersion);
}
+
+ /* enable the apply button */
+ SendMessage(GetParent(dialog), PSM_CHANGED, (WPARAM) dialog, 0);
}
static void on_dosver_change(HWND dialog)
@@ -333,13 +335,16 @@
if (selection == 0)
{
WINE_TRACE("automatic/default selected so removing current setting\n");
- addTransaction(keypath("Version"), "DOS", ACTION_REMOVE, NULL);
+ set(keypath("Version"), "DOS", 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);
+ set(keypath("Version"), "DOS", ver[selection - 1].szVersion);
}
+
+ /* enable the apply button */
+ SendMessage(GetParent(dialog), PSM_CHANGED, (WPARAM) dialog, 0);
}
INT_PTR CALLBACK
@@ -348,17 +353,25 @@
switch (uMsg)
{
case WM_INITDIALOG:
- init_appsheet(hDlg);
- break;
+ init_appsheet(hDlg);
+ break;
+
+ case WM_SHOWWINDOW:
+ set_window_title(hDlg);
+ break;
case WM_NOTIFY:
-
switch (((LPNMHDR)lParam)->code)
{
case LVN_ITEMCHANGED:
- on_selection_change(hDlg, GetDlgItem(hDlg, IDC_APP_LISTVIEW));
- break;
+ on_selection_change(hDlg, GetDlgItem(hDlg, IDC_APP_LISTVIEW));
+ break;
+ case PSN_APPLY:
+ apply();
+ SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
+ break;
}
+
break;
case WM_COMMAND:
@@ -383,6 +396,7 @@
}
break;
}
+
break;
}
--- programs/winecfg.working/audio.c 2004-08-23 17:57:18.000000000 +0100
+++ programs/winecfg/audio.c 2004-08-26 20:49:26.000000000 +0100
@@ -55,7 +55,8 @@
{
if (!strcmp (pAudioDrv->szDriver, drivername))
{
- addTransaction("Winmm", "Drivers", ACTION_SET, pAudioDrv->szDriver);
+ set("Winmm", "Drivers", (char *) pAudioDrv->szDriver);
+ SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM) hDlg, 0); /* enable apply button */
SendDlgItemMessage(hDlg, IDC_AUDIO_DRIVER, CB_SETCURSEL,
(WPARAM) i, 0);
}
@@ -66,7 +67,7 @@
void
initAudioDlg (HWND hDlg)
{
- char *curAudioDriver = getConfigValue("Winmm", "Drivers", "winealsa.drv");
+ char *curAudioDriver = get("Winmm", "Drivers", "winealsa.drv");
const AUDIO_DRIVER *pAudioDrv = NULL;
int i;
@@ -175,13 +176,18 @@
break;
}
break;
-
+
+ case WM_SHOWWINDOW:
+ set_window_title(hDlg);
+ break;
+
case WM_NOTIFY:
switch(((LPNMHDR)lParam)->code) {
case PSN_KILLACTIVE:
SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
break;
case PSN_APPLY:
+ apply();
SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
break;
case PSN_SETACTIVE:
--- programs/winecfg.working/drive.c 2004-08-23 17:57:19.000000000 +0100
+++ programs/winecfg/drive.c 2004-08-25 20:24:18.000000000 +0100
@@ -212,14 +212,13 @@
ShowWindow(GetDlgItem(dialog, IDS_DRIVE_NO_C), SW_HIDE);
/* disable or enable controls depending on whether we are editing global vs app specific config */
- if (appSettings == EDITING_GLOBAL) {
+ if (currentApp) {
WINE_TRACE("enabling controls\n");
enable(IDC_LIST_DRIVES);
enable(IDC_BUTTON_ADD);
enable(IDC_BUTTON_REMOVE);
enable(IDC_BUTTON_EDIT);
enable(IDC_BUTTON_AUTODETECT);
-
} else {
WINE_TRACE("disabling controls\n");
disable(IDC_LIST_DRIVES);
@@ -1015,6 +1014,11 @@
case WM_INITDIALOG:
onDriveInitDialog();
break;
+
+ case WM_SHOWWINDOW:
+ set_window_title(hDlg);
+ break;
+
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_LIST_DRIVES:
--- programs/winecfg.working/main.c 2004-08-25 19:09:50.000000000 +0100
+++ programs/winecfg/main.c 2004-08-26 20:05:14.000000000 +0100
@@ -217,10 +217,6 @@
WINE_ERR("initialization failed, aborting\n");
ExitProcess(1);
}
-
- /* is the user running as root? */
- if(getuid() == 0)
- MessageBox(NULL, "It is not advisable to run wine as root. Doing so may compromise the security of your computer. Please run wine as a normal user.", "", MB_OK);
/*
* The next 3 lines should be all that is needed
--- programs/winecfg.working/resource.h 2004-08-25 19:16:30.000000000 +0100
+++ programs/winecfg/resource.h 2004-08-25 20:33:25.000000000 +0100
@@ -53,26 +53,17 @@
#define IDC_DESKTOP_BY 1026
#define IDC_XDGA 1027
#define IDC_XSHM 1028
+
+/* dll editing */
#define IDC_RAD_BUILTIN 1029
#define IDC_RAD_NATIVE 1030
#define IDC_RAD_BUILTIN_NATIVE 1031
#define IDC_RAD_NATIVE_BUILTIN 1032
#define IDC_RAD_DISABLE 1033
-#define IDC_TREE_DLLS 1034
-#define IDC_DLLS_ADDAPP 8000
+#define IDC_DLLS_LIST 1034
#define IDC_DLLS_ADDDLL 8001
-#define IDC_DLLS_REMOVEAPP 8002
#define IDC_DLLS_REMOVEDLL 8003
-#define IDC_DLLLIST 8004
-#define IDC_RADIO_DEFAULT_BUILTIN 1033
-#define IDC_RADIO_DEFAULT_NATIVE 1034
-#define IDC_RADIO_VIRTUAL 1035
-#define IDC_EDIT_VIRTUAL 1036
-#define IDC_BUTTON_VIRTUAL 1037
-#define IDC_RADIO_REAL 1038
-#define IDC_EDIT_REAL 1039
-#define IDC_BUTTON_REAL 1040
-#define IDC_BUTTON_FOLDERS 1041
+#define IDC_DLLCOMBO 8004
/* drive editing */
#define IDC_LIST_DRIVES 1042
--- programs/winecfg.working/x11drvdlg.c 2004-08-25 19:16:30.000000000 +0100
+++ programs/winecfg/x11drvdlg.c 2004-09-20 21:47:05.701212704 +0100
@@ -36,19 +36,18 @@
#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? */
-int updatingUI;
+int updating_ui;
-int appSettings = EDITING_GLOBAL; /* start by editing global */
-
-void updateGUIForDesktopMode(HWND dialog) {
+void update_gui_for_desktop_mode(HWND dialog) {
WINE_TRACE("\n");
- updatingUI = TRUE;
+ updating_ui = TRUE;
/* do we have desktop mode enabled? */
- if (doesConfigValueExist(keypath("x11drv"), "Desktop") == S_OK) {
+ if (exists(keypath("x11drv"), "Desktop"))
+ {
CheckDlgButton(dialog, IDC_ENABLE_DESKTOP, BST_CHECKED);
- /* enable the controls */
+
enable(IDC_DESKTOP_WIDTH);
enable(IDC_DESKTOP_HEIGHT);
enable(IDC_DESKTOP_SIZE);
@@ -57,9 +56,10 @@
SetWindowText(GetDlgItem(dialog, IDC_DESKTOP_WIDTH), "640");
SetWindowText(GetDlgItem(dialog, IDC_DESKTOP_HEIGHT), "480");
}
- else {
+ else
+ {
CheckDlgButton(dialog, IDC_ENABLE_DESKTOP, BST_UNCHECKED);
- /* disable the controls */
+
disable(IDC_DESKTOP_WIDTH);
disable(IDC_DESKTOP_HEIGHT);
disable(IDC_DESKTOP_SIZE);
@@ -69,22 +69,22 @@
SetWindowText(GetDlgItem(dialog, IDC_DESKTOP_HEIGHT), "");
}
- updatingUI = FALSE;
+ updating_ui = FALSE;
}
/* pokes the win32 api to setup the dialog from the config struct */
void initGraphDlg (HWND hDlg)
{
- static const char default_desktop[] = "640x480";
+ static char *default_desktop = "640x480";
char *buf;
char *bufindex;
- updateGUIForDesktopMode(hDlg);
+ update_gui_for_desktop_mode(hDlg);
- updatingUI = TRUE;
+ updating_ui = TRUE;
/* desktop size */
- buf = getConfigValue(keypath("x11drv"), "Desktop", default_desktop);
+ buf = get(keypath("x11drv"), "Desktop", default_desktop);
bufindex = strchr(buf, 'x');
if(!bufindex) /* handle invalid "Desktop" values */
{
@@ -96,7 +96,7 @@
bufindex++;
SetWindowText(GetDlgItem(hDlg, IDC_DESKTOP_WIDTH), buf);
SetWindowText(GetDlgItem(hDlg, IDC_DESKTOP_HEIGHT), bufindex);
- free(buf);
+ HeapFree(GetProcessHeap(), 0, buf);
SendDlgItemMessage(hDlg, IDC_SCREEN_DEPTH, CB_RESETCONTENT, 0, 0);
SendDlgItemMessage(hDlg, IDC_SCREEN_DEPTH, CB_ADDSTRING, 0, (LPARAM) "8 bit");
@@ -104,7 +104,7 @@
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(keypath("x11drv"), "ScreenDepth", "24");
+ buf = get(keypath("x11drv"), "ScreenDepth", "24");
if (strcmp(buf, "8") == 0)
SendDlgItemMessage(hDlg, IDC_SCREEN_DEPTH, CB_SETCURSEL, 0, 0);
else if (strcmp(buf, "16") == 0)
@@ -115,36 +115,34 @@
SendDlgItemMessage(hDlg, IDC_SCREEN_DEPTH, CB_SETCURSEL, 3, 0);
else
WINE_ERR("Invalid screen depth read from registry (%s)\n", buf);
- free(buf);
+ HeapFree(GetProcessHeap(), 0, buf);
SendDlgItemMessage(hDlg, IDC_DESKTOP_WIDTH, EM_LIMITTEXT, RES_MAXLEN, 0);
SendDlgItemMessage(hDlg, IDC_DESKTOP_HEIGHT, EM_LIMITTEXT, RES_MAXLEN, 0);
- buf = getConfigValue(keypath("x11drv"), "DXGrab", "Y");
+ buf = get(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);
+ HeapFree(GetProcessHeap(), 0, buf);
- buf = getConfigValue(keypath("x11drv"), "DesktopDoubleBuffered", "Y");
+ buf = get(keypath("x11drv"), "DesktopDoubleBuffered", "Y");
if (IS_OPTION_TRUE(*buf))
CheckDlgButton(hDlg, IDC_DOUBLE_BUFFER, BST_CHECKED);
else
CheckDlgButton(hDlg, IDC_DOUBLE_BUFFER, BST_UNCHECKED);
- free(buf);
+ HeapFree(GetProcessHeap(), 0, buf);
- updatingUI = FALSE;
+ updating_ui = FALSE;
}
-
-
void setFromDesktopSizeEdits(HWND hDlg) {
- char *width = malloc(RES_MAXLEN+1);
- char *height = malloc(RES_MAXLEN+1);
- char *newStr = malloc((RES_MAXLEN*2) + 2);
+ char *width = HeapAlloc(GetProcessHeap(), 0, RES_MAXLEN+1);
+ char *height = HeapAlloc(GetProcessHeap(), 0, RES_MAXLEN+1);
+ char *new = HeapAlloc(GetProcessHeap(), 0, (RES_MAXLEN*2) + 2);
- if (updatingUI) return;
+ if (updating_ui) goto end;
WINE_TRACE("\n");
@@ -154,12 +152,13 @@
if (strcmp(width, "") == 0) strcpy(width, "640");
if (strcmp(height, "") == 0) strcpy(height, "480");
- sprintf(newStr, "%sx%s", width, height);
- addTransaction(keypath("x11drv"), "Desktop", ACTION_SET, newStr);
-
- free(width);
- free(height);
- free(newStr);
+ sprintf(new, "%sx%s", width, height);
+ set(keypath("x11drv"), "Desktop", new);
+
+end:
+ HeapFree(GetProcessHeap(), 0, width);
+ HeapFree(GetProcessHeap(), 0, height);
+ HeapFree(GetProcessHeap(), 0, new);
}
void onEnableDesktopClicked(HWND hDlg) {
@@ -169,9 +168,9 @@
setFromDesktopSizeEdits(hDlg);
} else {
/* it was just checked, so remove the config values */
- addTransaction(keypath("x11drv"), "Desktop", ACTION_REMOVE, NULL);
+ set(keypath("x11drv"), "Desktop", NULL);
}
- updateGUIForDesktopMode(hDlg);
+ update_gui_for_desktop_mode(hDlg);
}
void onScreenDepthChanged(HWND hDlg) {
@@ -179,26 +178,26 @@
char *spaceIndex = strchr(newvalue, ' ');
WINE_TRACE("newvalue=%s\n", newvalue);
- if (updatingUI) return;
+ if (updating_ui) return;
*spaceIndex = '\0';
- addTransaction(keypath("x11drv"), "ScreenDepth", ACTION_SET, newvalue);
+ set(keypath("x11drv"), "ScreenDepth", newvalue);
free(newvalue);
}
void onDXMouseGrabClicked(HWND hDlg) {
if (IsDlgButtonChecked(hDlg, IDC_DX_MOUSE_GRAB) == BST_CHECKED)
- addTransaction(keypath("x11drv"), "DXGrab", ACTION_SET, "Y");
+ set(keypath("x11drv"), "DXGrab", "Y");
else
- addTransaction(keypath("x11drv"), "DXGrab", ACTION_SET, "N");
+ set(keypath("x11drv"), "DXGrab", "N");
}
void onDoubleBufferClicked(HWND hDlg) {
if (IsDlgButtonChecked(hDlg, IDC_DOUBLE_BUFFER) == BST_CHECKED)
- addTransaction(keypath("x11drv"), "DesktopDoubleBuffered", ACTION_SET, "Y");
+ set(keypath("x11drv"), "DesktopDoubleBuffered", "Y");
else
- addTransaction(keypath("x11drv"), "DesktopDoubleBuffered", ACTION_SET, "N");
+ set(keypath("x11drv"), "DesktopDoubleBuffered", "N");
}
INT_PTR CALLBACK
@@ -207,17 +206,21 @@
switch (uMsg) {
case WM_INITDIALOG:
break;
-
+
+ case WM_SHOWWINDOW:
+ set_window_title(hDlg);
+ break;
+
case WM_COMMAND:
switch(HIWORD(wParam)) {
case EN_CHANGE: {
SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0);
- if ( ((LOWORD(wParam) == IDC_DESKTOP_WIDTH) || (LOWORD(wParam) == IDC_DESKTOP_HEIGHT)) && !updatingUI )
+ if ( ((LOWORD(wParam) == IDC_DESKTOP_WIDTH) || (LOWORD(wParam) == IDC_DESKTOP_HEIGHT)) && !updating_ui )
setFromDesktopSizeEdits(hDlg);
break;
}
case BN_CLICKED: {
- if (updatingUI) break;
+ if (updating_ui) break;
switch(LOWORD(wParam)) {
case IDC_ENABLE_DESKTOP: onEnableDesktopClicked(hDlg); break;
case IDC_DX_MOUSE_GRAB: onDXMouseGrabClicked(hDlg); break;
@@ -243,6 +246,7 @@
break;
}
case PSN_APPLY: {
+ apply();
SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
break;
}
More information about the wine-patches
mailing list