Update the address of the Free Software Foundation.
[wine] / programs / winecfg / x11drvdlg.c
1 /*
2  * Graphics configuration code
3  *
4  * Copyright 2003 Mark Westcott
5  * Copyright 2003-2004 Mike Hearn
6  * Copyright 2005 Raphael Junqueira
7  *
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.
12  *
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.
17  *
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  *
22  */
23
24 #define WIN32_LEAN_AND_MEAN
25
26 #include <stdarg.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29
30 #include <windows.h>
31 #include <wine/debug.h>
32
33 #include "resource.h"
34 #include "winecfg.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(winecfg);
37
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? */
39
40
41 static const char* D3D_VS_Modes[] = {
42   "hardware",
43   "none",
44   "emulation",
45   NULL
46 };
47
48
49 int updating_ui;
50
51 static void update_gui_for_desktop_mode(HWND dialog) {
52     int desktopenabled = FALSE;
53
54     WINE_TRACE("\n");
55     updating_ui = TRUE;
56
57     if (current_app)
58     {
59         disable(IDC_ENABLE_DESKTOP);
60         disable(IDC_DESKTOP_WIDTH);
61         disable(IDC_DESKTOP_HEIGHT);
62         disable(IDC_DESKTOP_SIZE);
63         disable(IDC_DESKTOP_BY);
64         return;
65     }
66     enable(IDC_ENABLE_DESKTOP);
67
68     /* do we have desktop mode enabled? */
69     if (reg_key_exists(config_key, keypath("X11 Driver"), "Desktop"))
70     {
71         char* buf, *bufindex;
72         CheckDlgButton(dialog, IDC_ENABLE_DESKTOP, BST_CHECKED);
73
74         buf = get_reg_key(config_key, keypath("X11 Driver"), "Desktop", "640x480");
75         /* note: this test must match the one in x11drv */
76         if( buf[0] != 'n' &&  buf[0] != 'N' &&  buf[0] != 'F' &&  buf[0] != 'f'
77                 &&  buf[0] != '0') {
78             desktopenabled = TRUE;
79             enable(IDC_DESKTOP_WIDTH);
80             enable(IDC_DESKTOP_HEIGHT);
81             enable(IDC_DESKTOP_SIZE);
82             enable(IDC_DESKTOP_BY);
83
84             bufindex = strchr(buf, 'x');
85             if (bufindex) {
86                 *bufindex = 0;
87                 ++bufindex;
88                 SetWindowText(GetDlgItem(dialog, IDC_DESKTOP_WIDTH), buf);
89                 SetWindowText(GetDlgItem(dialog, IDC_DESKTOP_HEIGHT), bufindex);
90             } else {
91                 WINE_TRACE("Desktop registry entry is malformed");
92                 SetWindowText(GetDlgItem(dialog, IDC_DESKTOP_WIDTH), "640");
93                 SetWindowText(GetDlgItem(dialog, IDC_DESKTOP_HEIGHT), "480");
94             }
95         }
96         HeapFree(GetProcessHeap(), 0, buf);
97     }
98     if (!desktopenabled)
99     {
100         CheckDlgButton(dialog, IDC_ENABLE_DESKTOP, BST_UNCHECKED);
101         
102         disable(IDC_DESKTOP_WIDTH);
103         disable(IDC_DESKTOP_HEIGHT);
104         disable(IDC_DESKTOP_SIZE);
105         disable(IDC_DESKTOP_BY);
106
107         SetWindowText(GetDlgItem(dialog, IDC_DESKTOP_WIDTH), "");
108         SetWindowText(GetDlgItem(dialog, IDC_DESKTOP_HEIGHT), "");
109     }
110
111     updating_ui = FALSE;
112 }
113
114 static void init_dialog(HWND dialog)
115 {
116     unsigned int it;
117     char* buf;
118
119     update_gui_for_desktop_mode(dialog);
120
121     updating_ui = TRUE;
122     
123     SendDlgItemMessage(dialog, IDC_DESKTOP_WIDTH, EM_LIMITTEXT, RES_MAXLEN, 0);
124     SendDlgItemMessage(dialog, IDC_DESKTOP_HEIGHT, EM_LIMITTEXT, RES_MAXLEN, 0);
125
126     buf = get_reg_key(config_key, keypath("X11 Driver"), "DXGrab", "N");
127     if (IS_OPTION_TRUE(*buf))
128         CheckDlgButton(dialog, IDC_DX_MOUSE_GRAB, BST_CHECKED);
129     else
130         CheckDlgButton(dialog, IDC_DX_MOUSE_GRAB, BST_UNCHECKED);
131     HeapFree(GetProcessHeap(), 0, buf);
132
133     buf = get_reg_key(config_key, keypath("X11 Driver"), "DesktopDoubleBuffered", "Y");
134     if (IS_OPTION_TRUE(*buf))
135         CheckDlgButton(dialog, IDC_DOUBLE_BUFFER, BST_CHECKED);
136     else
137         CheckDlgButton(dialog, IDC_DOUBLE_BUFFER, BST_UNCHECKED);
138     HeapFree(GetProcessHeap(), 0, buf);
139
140     buf = get_reg_key(config_key, keypath("X11 Driver"), "Managed", "Y");
141     if (IS_OPTION_TRUE(*buf))
142         CheckDlgButton(dialog, IDC_ENABLE_MANAGED, BST_CHECKED);
143     else
144         CheckDlgButton(dialog, IDC_ENABLE_MANAGED, BST_UNCHECKED);
145     HeapFree(GetProcessHeap(), 0, buf);
146
147     SendDlgItemMessage(dialog, IDC_D3D_VSHADER_MODE, CB_RESETCONTENT, 0, 0);
148     for (it = 0; NULL != D3D_VS_Modes[it]; ++it) {
149       SendDlgItemMessage(dialog, IDC_D3D_VSHADER_MODE, CB_ADDSTRING, 0, (LPARAM) D3D_VS_Modes[it]);
150     }  
151     buf = get_reg_key(config_key, keypath("Direct3D"), "VertexShaderMode", "hardware"); 
152     for (it = 0; NULL != D3D_VS_Modes[it]; ++it) {
153       if (strcmp(buf, D3D_VS_Modes[it]) == 0) {
154         SendDlgItemMessage(dialog, IDC_D3D_VSHADER_MODE, CB_SETCURSEL, it, 0);
155         break ;
156       }
157     }
158     if (NULL == D3D_VS_Modes[it]) {
159       WINE_ERR("Invalid Direct3D VertexShader Mode read from registry (%s)\n", buf);
160     }
161     HeapFree(GetProcessHeap(), 0, buf);
162
163     buf = get_reg_key(config_key, keypath("Direct3D"), "PixelShaderMode", "disabled");
164     if (!strcmp(buf, "enabled"))
165       CheckDlgButton(dialog, IDC_D3D_PSHADER_MODE, BST_CHECKED);
166     else
167       CheckDlgButton(dialog, IDC_D3D_PSHADER_MODE, BST_UNCHECKED);
168     HeapFree(GetProcessHeap(), 0, buf);
169
170     updating_ui = FALSE;
171 }
172
173 static void set_from_desktop_edits(HWND dialog) {
174     char *width, *height, *new;
175
176     if (updating_ui) return;
177     
178     WINE_TRACE("\n");
179
180     width = get_text(dialog, IDC_DESKTOP_WIDTH);
181     height = get_text(dialog, IDC_DESKTOP_HEIGHT);
182
183     if (width == NULL || strcmp(width, "") == 0) {
184         HeapFree(GetProcessHeap(), 0, width);
185         width = strdupA("640");
186     }
187     
188     if (height == NULL || strcmp(height, "") == 0) {
189         HeapFree(GetProcessHeap(), 0, height);
190         height = strdupA("480");
191     }
192
193     new = HeapAlloc(GetProcessHeap(), 0, strlen(width) + strlen(height) + 2 /* x + terminator */);
194     sprintf(new, "%sx%s", width, height);
195     set_reg_key(config_key, keypath("X11 Driver"), "Desktop", new);
196     
197     HeapFree(GetProcessHeap(), 0, width);
198     HeapFree(GetProcessHeap(), 0, height);
199     HeapFree(GetProcessHeap(), 0, new);
200 }
201
202 static void on_enable_desktop_clicked(HWND dialog) {
203     WINE_TRACE("\n");
204     
205     if (IsDlgButtonChecked(dialog, IDC_ENABLE_DESKTOP) == BST_CHECKED) {
206         set_from_desktop_edits(dialog);
207     } else {
208         set_reg_key(config_key, keypath("X11 Driver"), "Desktop", NULL);
209     }
210     
211     update_gui_for_desktop_mode(dialog);
212 }
213
214 static void on_enable_managed_clicked(HWND dialog) {
215     WINE_TRACE("\n");
216     
217     if (IsDlgButtonChecked(dialog, IDC_ENABLE_MANAGED) == BST_CHECKED) {
218         set_reg_key(config_key, keypath("X11 Driver"), "Managed", "Y");
219     } else {
220         set_reg_key(config_key, keypath("X11 Driver"), "Managed", "N");
221     }
222 }
223
224 static void on_dx_mouse_grab_clicked(HWND dialog) {
225     if (IsDlgButtonChecked(dialog, IDC_DX_MOUSE_GRAB) == BST_CHECKED) 
226         set_reg_key(config_key, keypath("X11 Driver"), "DXGrab", "Y");
227     else
228         set_reg_key(config_key, keypath("X11 Driver"), "DXGrab", "N");
229 }
230
231
232 static void on_double_buffer_clicked(HWND dialog) {
233     if (IsDlgButtonChecked(dialog, IDC_DOUBLE_BUFFER) == BST_CHECKED)
234         set_reg_key(config_key, keypath("X11 Driver"), "DesktopDoubleBuffered", "Y");
235     else
236         set_reg_key(config_key, keypath("X11 Driver"), "DesktopDoubleBuffered", "N");
237 }
238
239 static void on_d3d_vshader_mode_changed(HWND dialog) {
240   int selected_mode = SendDlgItemMessage(dialog, IDC_D3D_VSHADER_MODE, CB_GETCURSEL, 0, 0);  
241   set_reg_key(config_key, keypath("Direct3D"), "VertexShaderMode", D3D_VS_Modes[selected_mode]); 
242 }
243
244 static void on_d3d_pshader_mode_clicked(HWND dialog) {
245     if (IsDlgButtonChecked(dialog, IDC_D3D_PSHADER_MODE) == BST_CHECKED)
246         set_reg_key(config_key, keypath("Direct3D"), "PixelShaderMode", "enabled");
247     else
248         set_reg_key(config_key, keypath("Direct3D"), "PixelShaderMode", "disabled");
249 }
250
251 INT_PTR CALLBACK
252 GraphDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
253 {
254     switch (uMsg) {
255         case WM_INITDIALOG:
256             break;
257
258         case WM_SHOWWINDOW:
259             set_window_title(hDlg);
260             break;
261             
262         case WM_COMMAND:
263             switch(HIWORD(wParam)) {
264                 case EN_CHANGE: {
265                     if (updating_ui) break;
266                     SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0);
267                     if ( ((LOWORD(wParam) == IDC_DESKTOP_WIDTH) || (LOWORD(wParam) == IDC_DESKTOP_HEIGHT)) && !updating_ui )
268                         set_from_desktop_edits(hDlg);
269                     break;
270                 }
271                 case BN_CLICKED: {
272                     if (updating_ui) break;
273                     SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0);
274                     switch(LOWORD(wParam)) {
275                         case IDC_ENABLE_DESKTOP: on_enable_desktop_clicked(hDlg); break;
276                         case IDC_ENABLE_MANAGED: on_enable_managed_clicked(hDlg); break;
277                         case IDC_DX_MOUSE_GRAB:  on_dx_mouse_grab_clicked(hDlg); break;
278                         case IDC_DOUBLE_BUFFER:  on_double_buffer_clicked(hDlg); break;
279                         case IDC_D3D_PSHADER_MODE: on_d3d_pshader_mode_clicked(hDlg); break;
280                     }
281                     break;
282                 }
283                 case CBN_SELCHANGE: {
284                     SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0);
285                     switch (LOWORD(wParam)) {
286                     case IDC_D3D_VSHADER_MODE: on_d3d_vshader_mode_changed(hDlg); break;
287                     }
288                     break;
289                 }
290                     
291                 default:
292                     break;
293             }
294             break;
295         
296         
297         case WM_NOTIFY:
298             switch (((LPNMHDR)lParam)->code) {
299                 case PSN_KILLACTIVE: {
300                     SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
301                     break;
302                 }
303                 case PSN_APPLY: {
304                     apply();
305                     SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
306                     break;
307                 }
308                 case PSN_SETACTIVE: {
309                     init_dialog (hDlg);
310                     break;
311                 }
312             }
313             break;
314
315         default:
316             break;
317     }
318     return FALSE;
319 }