2 * WineCfg libraries tabsheet
4 * Copyright 2004 Robert van Herk
5 * Copyright 2004 Mike Hearn
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #define NONAMELESSUNION
26 #include <wine/debug.h>
32 WINE_DEFAULT_DEBUG_CHANNEL(winecfg
);
41 UNKNOWN
/* Special value indicating an erronous DLL override mode */
50 /* Convert a registry string to a dllmode */
51 static enum dllmode
string_to_mode(char *in
)
58 out
= HeapAlloc(GetProcessHeap(), 0, len
);
60 /* remove the spaces */
61 for (i
= j
= 0; i
<= len
; ++i
) {
67 /* parse the string */
69 if (strcmp(out
, "builtin,native") == 0) res
= BUILTIN_NATIVE
;
70 if (strcmp(out
, "native,builtin") == 0) res
= NATIVE_BUILTIN
;
71 if (strcmp(out
, "builtin") == 0) res
= BUILTIN
;
72 if (strcmp(out
, "native") == 0) res
= NATIVE
;
73 if (strcmp(out
, "") == 0) res
= DISABLE
;
75 HeapFree(GetProcessHeap(), 0, out
);
79 /* Convert a dllmode to a registry string. */
80 static const char* mode_to_string(enum dllmode mode
)
84 case NATIVE
: return "native";
85 case BUILTIN
: return "builtin";
86 case NATIVE_BUILTIN
: return "native,builtin";
87 case BUILTIN_NATIVE
: return "builtin,native";
88 case DISABLE
: return "";
89 default: assert(FALSE
); return "";
93 /* Convert a dllmode to a pretty string for display. TODO: use translations. */
94 static const char* mode_to_label(enum dllmode mode
)
96 WINE_FIXME("translate me\n");
97 return mode_to_string(mode
);
100 /* Convert a control id (IDC_ constant) to a dllmode */
101 static enum dllmode
id_to_mode(DWORD id
)
105 case IDC_RAD_BUILTIN
: return BUILTIN
;
106 case IDC_RAD_NATIVE
: return NATIVE
;
107 case IDC_RAD_NATIVE_BUILTIN
: return NATIVE_BUILTIN
;
108 case IDC_RAD_BUILTIN_NATIVE
: return BUILTIN_NATIVE
;
109 case IDC_RAD_DISABLE
: return DISABLE
;
110 default: assert( FALSE
); return 0; /* should not be reached */
114 /* Convert a dllmode to a control id (IDC_ constant) */
115 static DWORD
mode_to_id(enum dllmode mode
)
119 case BUILTIN
: return IDC_RAD_BUILTIN
;
120 case NATIVE
: return IDC_RAD_NATIVE
;
121 case NATIVE_BUILTIN
: return IDC_RAD_NATIVE_BUILTIN
;
122 case BUILTIN_NATIVE
: return IDC_RAD_BUILTIN_NATIVE
;
123 case DISABLE
: return IDC_RAD_DISABLE
;
124 default: assert( FALSE
); return 0; /* should not be reached */
128 static void set_controls_from_selection(HWND dialog
)
130 /* FIXME: display/update some information about the selected dll (purpose, recommended loadorder) maybe? */
133 static void clear_settings(HWND dialog
)
135 int count
= SendDlgItemMessage(dialog
, IDC_DLLS_LIST
, LB_GETCOUNT
, 0, 0);
138 WINE_TRACE("count=%d\n", count
);
140 for (i
= 0; i
< count
; i
++)
142 struct dll
*dll
= (struct dll
*) SendDlgItemMessage(dialog
, IDC_DLLS_LIST
, LB_GETITEMDATA
, 0, 0);
144 SendDlgItemMessage(dialog
, IDC_DLLS_LIST
, LB_DELETESTRING
, 0, 0);
146 HeapFree(GetProcessHeap(), 0, dll
->name
);
147 HeapFree(GetProcessHeap(), 0, dll
);
151 static void load_library_settings(HWND dialog
)
153 char **overrides
= enumerate_values(config_key
, keypath("DllOverrides"));
157 sel
= SendDlgItemMessage(dialog
, IDC_DLLS_LIST
, LB_GETCURSEL
, 0, 0);
159 WINE_TRACE("sel=%d\n", sel
);
161 clear_settings(dialog
);
163 if (!overrides
|| *overrides
== NULL
)
165 set_controls_from_selection(dialog
);
166 disable(IDC_DLLS_EDITDLL
);
167 disable(IDC_DLLS_REMOVEDLL
);
168 HeapFree(GetProcessHeap(), 0, overrides
);
172 enable(IDC_DLLS_EDITDLL
);
173 enable(IDC_DLLS_REMOVEDLL
);
175 for (p
= overrides
; *p
!= NULL
; p
++)
182 value
= get_reg_key(config_key
, keypath("DllOverrides"), *p
, NULL
);
184 label
= mode_to_label(string_to_mode(value
));
186 str
= HeapAlloc(GetProcessHeap(), 0, strlen(*p
) + 2 + strlen(label
) + 2);
192 dll
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct dll
));
194 dll
->mode
= string_to_mode(value
);
196 index
= SendDlgItemMessage(dialog
, IDC_DLLS_LIST
, LB_ADDSTRING
, (WPARAM
) -1, (LPARAM
) str
);
197 SendDlgItemMessage(dialog
, IDC_DLLS_LIST
, LB_SETITEMDATA
, index
, (LPARAM
) dll
);
199 HeapFree(GetProcessHeap(), 0, str
);
204 HeapFree(GetProcessHeap(), 0, overrides
);
206 /* restore the previous selection, if possible */
207 if (sel
>= count
- 1) sel
= count
- 1;
208 else if (sel
== -1) sel
= 0;
210 SendDlgItemMessage(dialog
, IDC_DLLS_LIST
, LB_SETCURSEL
, sel
, 0);
212 set_controls_from_selection(dialog
);
215 /* Called when the application is initialized (cannot reinit!) */
216 static void init_libsheet(HWND dialog
)
218 /* clear the add dll controls */
219 SendDlgItemMessage(dialog
, IDC_DLLCOMBO
, WM_SETTEXT
, 1, (LPARAM
) "");
220 disable(IDC_DLLS_ADDDLL
);
223 static void on_add_combo_change(HWND dialog
)
227 SendDlgItemMessage(dialog
, IDC_DLLCOMBO
, WM_GETTEXT
, sizeof(buffer
), (LPARAM
) buffer
);
230 enable(IDC_DLLS_ADDDLL
)
232 disable(IDC_DLLS_ADDDLL
);
235 static void set_dllmode(HWND dialog
, DWORD id
)
242 mode
= id_to_mode(id
);
244 sel
= SendDlgItemMessage(dialog
, IDC_DLLS_LIST
, LB_GETCURSEL
, 0, 0);
245 if (sel
== -1) return;
247 dll
= (struct dll
*) SendDlgItemMessage(dialog
, IDC_DLLS_LIST
, LB_GETITEMDATA
, sel
, 0);
249 str
= mode_to_string(mode
);
250 WINE_TRACE("Setting %s to %s\n", dll
->name
, str
);
252 SendMessage(GetParent(dialog
), PSM_CHANGED
, 0, 0);
253 set_reg_key(config_key
, keypath("DllOverrides"), dll
->name
, str
);
255 load_library_settings(dialog
); /* ... and refresh */
258 static void on_add_click(HWND dialog
)
262 ZeroMemory(buffer
, sizeof(buffer
));
264 SendDlgItemMessage(dialog
, IDC_DLLCOMBO
, WM_GETTEXT
, sizeof(buffer
), (LPARAM
) buffer
);
266 SendDlgItemMessage(dialog
, IDC_DLLCOMBO
, WM_SETTEXT
, 0, (LPARAM
) "");
267 disable(IDC_DLLS_ADDDLL
);
269 WINE_TRACE("Adding %s as native, builtin", buffer
);
271 SendMessage(GetParent(dialog
), PSM_CHANGED
, 0, 0);
272 set_reg_key(config_key
, keypath("DllOverrides"), buffer
, "native,builtin");
274 load_library_settings(dialog
);
276 SendDlgItemMessage(dialog
, IDC_DLLS_LIST
, LB_SELECTSTRING
, (WPARAM
) 0, (LPARAM
) buffer
);
278 set_controls_from_selection(dialog
);
281 static INT_PTR CALLBACK
loadorder_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
288 CheckRadioButton(hwndDlg
, IDC_RAD_BUILTIN
, IDC_RAD_DISABLE
, lParam
);
293 if(HIWORD(wParam
) != BN_CLICKED
) break;
294 switch (LOWORD(wParam
))
296 case IDC_RAD_BUILTIN
:
298 case IDC_RAD_BUILTIN_NATIVE
:
299 case IDC_RAD_NATIVE_BUILTIN
:
300 case IDC_RAD_DISABLE
:
301 sel
= LOWORD(wParam
);
304 EndDialog(hwndDlg
, sel
);
307 EndDialog(hwndDlg
, wParam
);
314 static void on_edit_click(HWND hwnd
)
317 int index
= SendDlgItemMessage(hwnd
, IDC_DLLS_LIST
, LB_GETCURSEL
, 0, 0);
321 /* if no override is selected the edit button should be disabled... */
324 dll
= (struct dll
*) SendDlgItemMessage(hwnd
, IDC_DLLS_LIST
, LB_GETITEMDATA
, index
, 0);
325 id
= mode_to_id(dll
->mode
);
327 ret
= DialogBoxParam(0, MAKEINTRESOURCE(IDD_LOADORDER
), hwnd
, loadorder_dlgproc
, id
);
330 set_dllmode(hwnd
, ret
);
333 static void on_remove_click(HWND dialog
)
335 int sel
= SendDlgItemMessage(dialog
, IDC_DLLS_LIST
, LB_GETCURSEL
, 0, 0);
338 if (sel
== LB_ERR
) return;
340 dll
= (struct dll
*) SendDlgItemMessage(dialog
, IDC_DLLS_LIST
, LB_GETITEMDATA
, sel
, 0);
342 SendDlgItemMessage(dialog
, IDC_DLLS_LIST
, LB_DELETESTRING
, sel
, 0);
344 SendMessage(GetParent(dialog
), PSM_CHANGED
, 0, 0);
345 set_reg_key(config_key
, keypath("DllOverrides"), dll
->name
, NULL
);
347 HeapFree(GetProcessHeap(), 0, dll
->name
);
348 HeapFree(GetProcessHeap(), 0, dll
);
350 if (SendDlgItemMessage(dialog
, IDC_DLLS_LIST
, LB_GETCOUNT
, 0, 0) > 0)
351 SendDlgItemMessage(dialog
, IDC_DLLS_LIST
, LB_SETCURSEL
, max(sel
- 1, 0), 0);
354 disable(IDC_DLLS_EDITDLL
);
355 disable(IDC_DLLS_REMOVEDLL
);
358 set_controls_from_selection(dialog
);
362 LibrariesDlgProc (HWND hDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
370 set_window_title(hDlg
);
373 switch (((LPNMHDR
)lParam
)->code
) {
375 load_library_settings(hDlg
);
380 switch(HIWORD(wParam
)) {
382 /* FIXME: when the user hits enter in the DLL combo box we should invoke the add
383 * add button, rather than the propsheet OK button. But I don't know how to do that!
387 if(LOWORD(wParam
) == IDC_DLLCOMBO
)
389 on_add_combo_change(hDlg
);
394 switch(LOWORD(wParam
)) {
395 case IDC_DLLS_ADDDLL
:
398 case IDC_DLLS_EDITDLL
:
401 case IDC_DLLS_REMOVEDLL
:
402 on_remove_click(hDlg
);
407 set_controls_from_selection(hDlg
);