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