Stub implementations for SHUpdateImageA, SHHandleUpdateImage,
[wine/multimedia.git] / programs / winecfg / libraries.c
blob32f936838d6ce57dfa0a4a7d089764fc626b4c91
1 /*
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
24 #include <windows.h>
25 #include <commdlg.h>
26 #include <wine/debug.h>
27 #include <stdio.h>
28 #include <assert.h>
29 #include "winecfg.h"
30 #include "resource.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(winecfg);
34 enum dllmode
36 BUILTIN_NATIVE,
37 NATIVE_BUILTIN,
38 BUILTIN,
39 NATIVE,
40 DISABLE,
41 UNKNOWN /* Special value indicating an erronous DLL override mode */
44 struct dll
46 char *name;
47 enum dllmode mode;
50 static enum dllmode parse_override(char *in)
52 int i, j;
53 char *out;
55 out = HeapAlloc(GetProcessHeap(), 0, strlen(in));
57 /* remove the spaces */
58 j = 0;
59 for (i = 0; i < strlen(in); i++)
61 if (in[i] != ' ')
63 out[j] = in[i];
64 j++;
67 out[j] = 0;
69 /* parse the string */
70 if (strcmp(out, "builtin,native") == 0) return BUILTIN_NATIVE;
71 else if (strcmp(out, "native,builtin") == 0) return NATIVE_BUILTIN;
72 else if (strcmp(out, "native") == 0) return NATIVE;
73 else if (strcmp(out, "builtin") == 0) return BUILTIN;
74 else if (strcmp(out, "") == 0) return DISABLE;
76 return UNKNOWN;
79 /* this is used to convert a dllmode to a human readable string. we should read from the translations here */
80 static char* mode_to_label(enum dllmode mode)
82 char* res;
84 switch (mode) {
85 case NATIVE:
86 res = "native";
87 break;
88 case BUILTIN:
89 res = "builtin";
90 break;
91 case NATIVE_BUILTIN:
92 res = "native, builtin";
93 break;
94 case BUILTIN_NATIVE:
95 res = "builtin, native";
96 break;
97 case DISABLE:
98 res = "disabled";
99 break;
100 default:
101 res = "unknown/invalid";
102 break;
105 return res;
108 static void set_controls_from_selection(HWND dialog)
110 int index = SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_GETCURSEL, 0, 0);
111 struct dll *dll;
112 DWORD id;
113 int i;
115 if (index == -1) /* no selection */
117 for (i = IDC_RAD_BUILTIN; i <= IDC_RAD_DISABLE; i++)
118 disable(i);
120 CheckRadioButton(dialog, IDC_RAD_BUILTIN, IDC_RAD_DISABLE, -1);
122 return;
125 /* enable the controls */
126 for (i = IDC_RAD_BUILTIN; i <= IDC_RAD_DISABLE; i++)
127 enable(i);
129 dll = (struct dll *) SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_GETITEMDATA, index, 0);
131 switch (dll->mode)
133 case NATIVE:
134 id = IDC_RAD_NATIVE;
135 break;
136 case BUILTIN:
137 id = IDC_RAD_BUILTIN;
138 break;
139 case NATIVE_BUILTIN:
140 id = IDC_RAD_NATIVE_BUILTIN;
141 break;
142 case BUILTIN_NATIVE:
143 id = IDC_RAD_BUILTIN_NATIVE;
144 break;
145 case DISABLE:
146 id = IDC_RAD_DISABLE;
147 break;
149 case UNKNOWN:
150 default:
151 id = -1;
152 break;
155 CheckRadioButton(dialog, IDC_RAD_BUILTIN, IDC_RAD_DISABLE, id);
159 static void clear_settings(HWND dialog)
161 int count = SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_GETCOUNT, 0, 0);
162 int i;
164 WINE_TRACE("count=%d\n", count);
166 for (i = 0; i < count; i++)
168 struct dll *dll = (struct dll *) SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_GETITEMDATA, 0, 0);
170 SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_DELETESTRING, 0, 0);
172 HeapFree(GetProcessHeap(), 0, dll->name);
173 HeapFree(GetProcessHeap(), 0, dll);
177 static void load_library_settings(HWND dialog)
179 char **overrides = enumerate_values(keypath("DllOverrides"));
180 char **p;
181 int sel, count = 0;
183 sel = SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_GETCURSEL, 0, 0);
185 WINE_TRACE("sel=%d\n", sel);
187 clear_settings(dialog);
189 if (!overrides || *overrides == NULL)
191 set_controls_from_selection(dialog);
192 disable(IDC_DLLS_REMOVEDLL);
193 HeapFree(GetProcessHeap(), 0, overrides);
194 return;
197 enable(IDC_DLLS_REMOVEDLL);
199 for (p = overrides; *p != NULL; p++)
201 int index;
202 char *str, *value, *label;
203 struct dll *dll;
205 value = get(keypath("DllOverrides"), *p, NULL);
207 label = mode_to_label(parse_override(value));
209 str = HeapAlloc(GetProcessHeap(), 0, strlen(*p) + 2 + strlen(label) + 2);
210 strcpy(str, *p);
211 strcat(str, " (");
212 strcat(str, label);
213 strcat(str, ")");
215 dll = HeapAlloc(GetProcessHeap(), 0, sizeof(struct dll));
216 dll->name = *p;
217 dll->mode = parse_override(value);
219 index = SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_ADDSTRING, (WPARAM) -1, (LPARAM) str);
220 SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_SETITEMDATA, index, (LPARAM) dll);
222 HeapFree(GetProcessHeap(), 0, str);
224 count++;
227 HeapFree(GetProcessHeap(), 0, overrides);
229 /* restore the previous selection, if possible */
230 if (sel >= count - 1) sel = count - 1;
231 else if (sel == -1) sel = 0;
233 SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_SETCURSEL, sel, 0);
235 set_controls_from_selection(dialog);
238 /* Called when the application is initialized (cannot reinit!) */
239 static void init_libsheet(HWND dialog)
241 /* clear the add dll controls */
242 SendDlgItemMessage(dialog, IDC_DLLCOMBO, WM_SETTEXT, 1, (LPARAM) "");
243 disable(IDC_DLLS_ADDDLL);
247 static void on_add_combo_change(HWND dialog)
249 char buffer[1024];
251 SendDlgItemMessage(dialog, IDC_DLLCOMBO, WM_GETTEXT, sizeof(buffer), (LPARAM) buffer);
253 if (strlen(buffer))
254 enable(IDC_DLLS_ADDDLL)
255 else
256 disable(IDC_DLLS_ADDDLL);
259 static void set_dllmode(HWND dialog, DWORD id)
261 enum dllmode mode;
262 struct dll *dll;
263 int sel;
264 char *str;
266 #define CONVERT(s) case IDC_RAD_##s: mode = s; break;
268 switch (id)
270 CONVERT( BUILTIN );
271 CONVERT( NATIVE );
272 CONVERT( BUILTIN_NATIVE );
273 CONVERT( NATIVE_BUILTIN );
274 CONVERT( DISABLE );
276 default:
277 assert( FALSE ); /* should not be reached */
278 return;
281 #undef CONVERT
283 sel = SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_GETCURSEL, 0, 0);
284 if (sel == -1) return;
286 dll = (struct dll *) SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_GETITEMDATA, sel, 0);
288 switch (mode)
290 case BUILTIN: str = "builtin"; break;
291 case NATIVE: str = "native"; break;
292 case BUILTIN_NATIVE: str = "builtin, native"; break;
293 case NATIVE_BUILTIN: str = "native, builtin"; break;
294 case DISABLE: str = ""; break;
295 default:
296 assert( FALSE ); /* unreachable */
297 return;
299 WINE_TRACE("Setting %s to %s\n", dll->name, str);
301 set(keypath("DllOverrides"), dll->name, str);
303 load_library_settings(dialog); /* ... and refresh */
306 static void on_add_click(HWND dialog)
308 char buffer[1024];
310 ZeroMemory(buffer, sizeof(buffer));
312 SendDlgItemMessage(dialog, IDC_DLLCOMBO, WM_GETTEXT, sizeof(buffer), (LPARAM) buffer);
314 SendDlgItemMessage(dialog, IDC_DLLCOMBO, WM_SETTEXT, 0, (LPARAM) "");
315 disable(IDC_DLLS_ADDDLL);
317 WINE_TRACE("Adding %s as native, builtin", buffer);
319 set(keypath("DllOverrides"), buffer, "native,builtin");
321 load_library_settings(dialog);
323 SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_SELECTSTRING, (WPARAM) 0, (LPARAM) buffer);
325 set_controls_from_selection(dialog);
328 static void on_remove_click(HWND dialog)
330 int sel = SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_GETCURSEL, 0, 0);
331 struct dll *dll;
333 if (sel == LB_ERR) return;
335 dll = (struct dll *) SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_GETITEMDATA, sel, 0);
337 SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_DELETESTRING, sel, 0);
339 set(keypath("DllOverrides"), dll->name, NULL);
341 HeapFree(GetProcessHeap(), 0, dll->name);
342 HeapFree(GetProcessHeap(), 0, dll);
344 if (SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_GETCOUNT, 0, 0) > 0)
345 SendDlgItemMessage(dialog, IDC_DLLS_LIST, LB_SETCURSEL, max(sel - 1, 0), 0);
346 else
347 disable(IDC_DLLS_REMOVEDLL);
349 set_controls_from_selection(dialog);
352 INT_PTR CALLBACK
353 LibrariesDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
355 switch (uMsg)
357 case WM_INITDIALOG:
358 init_libsheet(hDlg);
359 break;
360 case WM_SHOWWINDOW:
361 set_window_title(hDlg);
362 break;
363 case WM_NOTIFY:
364 switch (((LPNMHDR)lParam)->code) {
365 case PSN_SETACTIVE:
366 load_library_settings(hDlg);
367 break;
369 break;
370 case WM_COMMAND:
371 switch(HIWORD(wParam)) {
373 /* FIXME: when the user hits enter in the DLL combo box we should invoke the add
374 * add button, rather than the propsheet OK button. But I don't know how to do that!
377 case CBN_EDITCHANGE:
378 if(LOWORD(wParam) == IDC_DLLCOMBO)
380 on_add_combo_change(hDlg);
381 break;
384 case BN_CLICKED:
385 switch(LOWORD(wParam)) {
386 case IDC_RAD_BUILTIN:
387 case IDC_RAD_NATIVE:
388 case IDC_RAD_BUILTIN_NATIVE:
389 case IDC_RAD_NATIVE_BUILTIN:
390 case IDC_RAD_DISABLE:
391 set_dllmode(hDlg, LOWORD(wParam));
392 break;
394 case IDC_DLLS_ADDDLL:
395 on_add_click(hDlg);
396 break;
397 case IDC_DLLS_REMOVEDLL:
398 on_remove_click(hDlg);
399 break;
401 break;
402 case LBN_SELCHANGE:
403 set_controls_from_selection(hDlg);
404 break;
406 break;
409 return 0;