Screen depth cannot be selected when double buffering is enabled.
[wine/multimedia.git] / programs / winecfg / x11drvdlg.c
blob8cf89b411ec9dcc786bc47eb48f64f22cacac9c8
1 /*
2 * Graphics configuration code
4 * Copyright 2003 Mark Westcott
5 * Copyright 2003-2004 Mike Hearn
6 * Copyright 2005 Raphael Junqueira
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include <stdarg.h>
25 #include <stdlib.h>
26 #include <stdio.h>
28 #include <windef.h>
29 #include <winbase.h>
30 #include <winreg.h>
31 #include <wine/debug.h>
33 #include "resource.h"
34 #include "winecfg.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(winecfg);
38 #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? */
41 static const char* D3D_VS_Modes[] = {
42 "hardware",
43 "none",
44 "emulation",
45 NULL
49 int updating_ui;
51 static void update_gui_for_desktop_mode(HWND dialog) {
52 WINE_TRACE("\n");
54 updating_ui = TRUE;
56 /* do we have desktop mode enabled? */
57 if (reg_key_exists(config_key, keypath("X11 Driver"), "Desktop"))
59 char* buf, *bufindex;
60 CheckDlgButton(dialog, IDC_ENABLE_DESKTOP, BST_CHECKED);
62 enable(IDC_DESKTOP_WIDTH);
63 enable(IDC_DESKTOP_HEIGHT);
64 enable(IDC_DESKTOP_SIZE);
65 enable(IDC_DESKTOP_BY);
67 buf = get_reg_key(config_key, keypath("X11 Driver"), "Desktop", "640x480");
68 bufindex = strchr(buf, 'x');
69 if (bufindex) {
70 *bufindex = 0;
71 ++bufindex;
72 SetWindowText(GetDlgItem(dialog, IDC_DESKTOP_WIDTH), buf);
73 SetWindowText(GetDlgItem(dialog, IDC_DESKTOP_HEIGHT), bufindex);
74 } else {
75 WINE_TRACE("Desktop registry entry is malformed");
76 SetWindowText(GetDlgItem(dialog, IDC_DESKTOP_WIDTH), "640");
77 SetWindowText(GetDlgItem(dialog, IDC_DESKTOP_HEIGHT), "480");
80 HeapFree(GetProcessHeap(), 0, buf);
82 else
84 CheckDlgButton(dialog, IDC_ENABLE_DESKTOP, BST_UNCHECKED);
86 disable(IDC_DESKTOP_WIDTH);
87 disable(IDC_DESKTOP_HEIGHT);
88 disable(IDC_DESKTOP_SIZE);
89 disable(IDC_DESKTOP_BY);
91 SetWindowText(GetDlgItem(dialog, IDC_DESKTOP_WIDTH), "");
92 SetWindowText(GetDlgItem(dialog, IDC_DESKTOP_HEIGHT), "");
95 updating_ui = FALSE;
98 static void init_screen_depth(HWND dialog)
100 char* buf;
101 buf = get_reg_key(config_key, keypath("X11 Driver"), "ScreenDepth", "24");
102 if (strcmp(buf, "8") == 0)
103 SendDlgItemMessage(dialog, IDC_SCREEN_DEPTH, CB_SETCURSEL, 0, 0);
104 else if (strcmp(buf, "16") == 0)
105 SendDlgItemMessage(dialog, IDC_SCREEN_DEPTH, CB_SETCURSEL, 1, 0);
106 else if (strcmp(buf, "24") == 0)
107 SendDlgItemMessage(dialog, IDC_SCREEN_DEPTH, CB_SETCURSEL, 2, 0);
108 else if (strcmp(buf, "32") == 0)
109 SendDlgItemMessage(dialog, IDC_SCREEN_DEPTH, CB_SETCURSEL, 3, 0);
110 else
111 WINE_ERR("Invalid screen depth read from registry (%s)\n", buf);
112 HeapFree(GetProcessHeap(), 0, buf);
115 static void init_dialog(HWND dialog)
117 unsigned int it;
118 char* buf;
120 update_gui_for_desktop_mode(dialog);
122 updating_ui = TRUE;
124 SendDlgItemMessage(dialog, IDC_SCREEN_DEPTH, CB_RESETCONTENT, 0, 0);
125 SendDlgItemMessage(dialog, IDC_SCREEN_DEPTH, CB_ADDSTRING, 0, (LPARAM) "8 bit");
126 SendDlgItemMessage(dialog, IDC_SCREEN_DEPTH, CB_ADDSTRING, 0, (LPARAM) "16 bit");
127 SendDlgItemMessage(dialog, IDC_SCREEN_DEPTH, CB_ADDSTRING, 0, (LPARAM) "24 bit");
128 SendDlgItemMessage(dialog, IDC_SCREEN_DEPTH, CB_ADDSTRING, 0, (LPARAM) "32 bit"); /* is this valid? */
130 SendDlgItemMessage(dialog, IDC_DESKTOP_WIDTH, EM_LIMITTEXT, RES_MAXLEN, 0);
131 SendDlgItemMessage(dialog, IDC_DESKTOP_HEIGHT, EM_LIMITTEXT, RES_MAXLEN, 0);
133 buf = get_reg_key(config_key, keypath("X11 Driver"), "DXGrab", "Y");
134 if (IS_OPTION_TRUE(*buf))
135 CheckDlgButton(dialog, IDC_DX_MOUSE_GRAB, BST_CHECKED);
136 else
137 CheckDlgButton(dialog, IDC_DX_MOUSE_GRAB, BST_UNCHECKED);
138 HeapFree(GetProcessHeap(), 0, buf);
140 buf = get_reg_key(config_key, keypath("X11 Driver"), "DesktopDoubleBuffered", "Y");
141 if (IS_OPTION_TRUE(*buf)) {
142 CheckDlgButton(dialog, IDC_DOUBLE_BUFFER, BST_CHECKED);
143 SendDlgItemMessage(dialog, IDC_SCREEN_DEPTH, CB_SETCURSEL, -1, 0);
144 disable(IDC_SCREEN_DEPTH);
145 } else {
146 CheckDlgButton(dialog, IDC_DOUBLE_BUFFER, BST_UNCHECKED);
147 init_screen_depth(dialog);
148 enable(IDC_SCREEN_DEPTH);
150 HeapFree(GetProcessHeap(), 0, buf);
152 SendDlgItemMessage(dialog, IDC_D3D_VSHADER_MODE, CB_RESETCONTENT, 0, 0);
153 for (it = 0; NULL != D3D_VS_Modes[it]; ++it) {
154 SendDlgItemMessage(dialog, IDC_D3D_VSHADER_MODE, CB_ADDSTRING, 0, (LPARAM) D3D_VS_Modes[it]);
156 buf = get_reg_key(config_key, keypath("Direct3D"), "VertexShaderMode", "hardware");
157 for (it = 0; NULL != D3D_VS_Modes[it]; ++it) {
158 if (strcmp(buf, D3D_VS_Modes[it]) == 0) {
159 SendDlgItemMessage(dialog, IDC_D3D_VSHADER_MODE, CB_SETCURSEL, it, 0);
160 break ;
163 if (NULL == D3D_VS_Modes[it]) {
164 WINE_ERR("Invalid Direct3D VertexShader Mode read from registry (%s)\n", buf);
166 HeapFree(GetProcessHeap(), 0, buf);
168 buf = get_reg_key(config_key, keypath("Direct3D"), "PixelShaderMode", "enabled");
169 if (!strcmp(buf, "enabled"))
170 CheckDlgButton(dialog, IDC_D3D_PSHADER_MODE, BST_CHECKED);
171 else
172 CheckDlgButton(dialog, IDC_D3D_PSHADER_MODE, BST_UNCHECKED);
173 HeapFree(GetProcessHeap(), 0, buf);
175 updating_ui = FALSE;
178 static void set_from_desktop_edits(HWND dialog) {
179 char *width, *height, *new;
181 if (updating_ui) return;
183 WINE_TRACE("\n");
185 width = get_text(dialog, IDC_DESKTOP_WIDTH);
186 height = get_text(dialog, IDC_DESKTOP_HEIGHT);
188 if (width == NULL || strcmp(width, "") == 0) {
189 HeapFree(GetProcessHeap(), 0, width);
190 width = strdupA("640");
193 if (height == NULL || strcmp(height, "") == 0) {
194 HeapFree(GetProcessHeap(), 0, height);
195 height = strdupA("480");
198 new = HeapAlloc(GetProcessHeap(), 0, strlen(width) + strlen(height) + 2 /* x + terminator */);
199 sprintf(new, "%sx%s", width, height);
200 set_reg_key(config_key, keypath("X11 Driver"), "Desktop", new);
202 HeapFree(GetProcessHeap(), 0, width);
203 HeapFree(GetProcessHeap(), 0, height);
204 HeapFree(GetProcessHeap(), 0, new);
207 static void on_enable_desktop_clicked(HWND dialog) {
208 WINE_TRACE("\n");
210 if (IsDlgButtonChecked(dialog, IDC_ENABLE_DESKTOP) == BST_CHECKED) {
211 set_from_desktop_edits(dialog);
212 } else {
213 set_reg_key(config_key, keypath("X11 Driver"), "Desktop", NULL);
216 update_gui_for_desktop_mode(dialog);
219 static void on_screen_depth_changed(HWND dialog) {
220 char *newvalue = get_text(dialog, IDC_SCREEN_DEPTH);
221 char *spaceIndex = strchr(newvalue, ' ');
223 WINE_TRACE("newvalue=%s\n", newvalue);
224 if (updating_ui) return;
226 *spaceIndex = '\0';
227 set_reg_key(config_key, keypath("X11 Driver"), "ScreenDepth", newvalue);
228 HeapFree(GetProcessHeap(), 0, newvalue);
231 static void on_dx_mouse_grab_clicked(HWND dialog) {
232 if (IsDlgButtonChecked(dialog, IDC_DX_MOUSE_GRAB) == BST_CHECKED)
233 set_reg_key(config_key, keypath("X11 Driver"), "DXGrab", "Y");
234 else
235 set_reg_key(config_key, keypath("X11 Driver"), "DXGrab", "N");
239 static void on_double_buffer_clicked(HWND dialog) {
240 if (IsDlgButtonChecked(dialog, IDC_DOUBLE_BUFFER) == BST_CHECKED) {
241 set_reg_key(config_key, keypath("X11 Driver"), "DesktopDoubleBuffered", "Y");
242 SendDlgItemMessage(dialog, IDC_SCREEN_DEPTH, CB_SETCURSEL, -1, 0);
243 disable(IDC_SCREEN_DEPTH);
244 } else {
245 set_reg_key(config_key, keypath("X11 Driver"), "DesktopDoubleBuffered", "N");
246 init_screen_depth(dialog);
247 enable(IDC_SCREEN_DEPTH);
251 static void on_d3d_vshader_mode_changed(HWND dialog) {
252 int selected_mode = SendDlgItemMessage(dialog, IDC_D3D_VSHADER_MODE, CB_GETCURSEL, 0, 0);
253 set_reg_key(config_key, keypath("Direct3D"), "VertexShaderMode", D3D_VS_Modes[selected_mode]);
256 static void on_d3d_pshader_mode_clicked(HWND dialog) {
257 if (IsDlgButtonChecked(dialog, IDC_D3D_PSHADER_MODE) == BST_CHECKED)
258 set_reg_key(config_key, keypath("Direct3D"), "PixelShaderMode", "enabled");
259 else
260 set_reg_key(config_key, keypath("Direct3D"), "PixelShaderMode", "disabled");
263 INT_PTR CALLBACK
264 GraphDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
266 switch (uMsg) {
267 case WM_INITDIALOG:
268 break;
270 case WM_SHOWWINDOW:
271 set_window_title(hDlg);
272 break;
274 case WM_COMMAND:
275 switch(HIWORD(wParam)) {
276 case EN_CHANGE: {
277 if (updating_ui) break;
278 SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0);
279 if ( ((LOWORD(wParam) == IDC_DESKTOP_WIDTH) || (LOWORD(wParam) == IDC_DESKTOP_HEIGHT)) && !updating_ui )
280 set_from_desktop_edits(hDlg);
281 break;
283 case BN_CLICKED: {
284 if (updating_ui) break;
285 SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0);
286 switch(LOWORD(wParam)) {
287 case IDC_ENABLE_DESKTOP: on_enable_desktop_clicked(hDlg); break;
288 case IDC_DX_MOUSE_GRAB: on_dx_mouse_grab_clicked(hDlg); break;
289 case IDC_DOUBLE_BUFFER: on_double_buffer_clicked(hDlg); break;
290 case IDC_D3D_PSHADER_MODE: on_d3d_pshader_mode_clicked(hDlg); break;
292 break;
294 case CBN_SELCHANGE: {
295 SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0);
296 switch (LOWORD(wParam)) {
297 case IDC_SCREEN_DEPTH: on_screen_depth_changed(hDlg); break;
298 case IDC_D3D_VSHADER_MODE: on_d3d_vshader_mode_changed(hDlg); break;
300 break;
303 default:
304 break;
306 break;
309 case WM_NOTIFY:
310 switch (((LPNMHDR)lParam)->code) {
311 case PSN_KILLACTIVE: {
312 SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
313 break;
315 case PSN_APPLY: {
316 apply();
317 SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
318 break;
320 case PSN_SETACTIVE: {
321 init_dialog (hDlg);
322 break;
325 break;
327 default:
328 break;
330 return FALSE;