x11drvdlg.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  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. #define WIN32_LEAN_AND_MEAN
  24. #include <stdarg.h>
  25. #include <stdlib.h>
  26. #include <stdio.h>
  27. #include <windows.h>
  28. #include <wine/debug.h>
  29. #include "resource.h"
  30. #include "winecfg.h"
  31. WINE_DEFAULT_DEBUG_CHANNEL(winecfg);
  32. #define RES_MAXLEN 5 /* max number of digits in a screen dimension. 5 digits should be plenty */
  33. #define MINDPI 96
  34. #define MAXDPI 480
  35. #define DEFDPI 96
  36. #define IDT_DPIEDIT 0x1234
  37. static const UINT dpi_values[] = { 96, 120, 144, 168, 192, 216, 240, 288, 336, 384, 432, 480 };
  38. static BOOL updating_ui;
  39. /* convert the x11 desktop key to the new explorer config */
  40. static void convert_x11_desktop_key(void)
  41. {
  42. WCHAR *buf;
  43. if (!(buf = get_reg_key(config_key, L"X11 Driver", L"Desktop", NULL))) return;
  44. set_reg_key(config_key, L"Explorer\\Desktops", L"Default", buf);
  45. set_reg_key(config_key, L"Explorer", L"Desktop", L"Default");
  46. set_reg_key(config_key, L"X11 Driver", L"Desktop", NULL);
  47. HeapFree(GetProcessHeap(), 0, buf);
  48. }
  49. static void update_gui_for_desktop_mode(HWND dialog)
  50. {
  51. WCHAR *buf, *bufindex;
  52. const WCHAR *desktop_name = current_app ? current_app : L"Default";
  53. WINE_TRACE("\n");
  54. updating_ui = TRUE;
  55. buf = get_reg_key(config_key, L"Explorer\\Desktops", desktop_name, NULL);
  56. if (buf && (bufindex = wcschr(buf, 'x')))
  57. {
  58. *bufindex++ = 0;
  59. SetDlgItemTextW(dialog, IDC_DESKTOP_WIDTH, buf);
  60. SetDlgItemTextW(dialog, IDC_DESKTOP_HEIGHT, bufindex);
  61. } else {
  62. SetDlgItemTextW(dialog, IDC_DESKTOP_WIDTH, L"800");
  63. SetDlgItemTextW(dialog, IDC_DESKTOP_HEIGHT, L"600");
  64. }
  65. HeapFree(GetProcessHeap(), 0, buf);
  66. /* do we have desktop mode enabled? */
  67. if (reg_key_exists(config_key, keypath(L"Explorer"), L"Desktop"))
  68. {
  69. CheckDlgButton(dialog, IDC_ENABLE_DESKTOP, BST_CHECKED);
  70. enable(IDC_DESKTOP_WIDTH);
  71. enable(IDC_DESKTOP_HEIGHT);
  72. enable(IDC_DESKTOP_SIZE);
  73. enable(IDC_DESKTOP_BY);
  74. }
  75. else
  76. {
  77. CheckDlgButton(dialog, IDC_ENABLE_DESKTOP, BST_UNCHECKED);
  78. disable(IDC_DESKTOP_WIDTH);
  79. disable(IDC_DESKTOP_HEIGHT);
  80. disable(IDC_DESKTOP_SIZE);
  81. disable(IDC_DESKTOP_BY);
  82. }
  83. updating_ui = FALSE;
  84. }
  85. static BOOL can_enable_desktop(void)
  86. {
  87. WCHAR *value;
  88. UINT guid_atom;
  89. BOOL ret = FALSE;
  90. WCHAR key[sizeof("System\\CurrentControlSet\\Control\\Video\\{}\\0000") + 40];
  91. guid_atom = HandleToULong(GetPropW(GetDesktopWindow(), L"__wine_display_device_guid"));
  92. wcscpy( key, L"System\\CurrentControlSet\\Control\\Video\\{" );
  93. if (!GlobalGetAtomNameW(guid_atom, key + wcslen(key), 40)) return ret;
  94. wcscat( key, L"}\\0000" );
  95. if ((value = get_reg_key(HKEY_LOCAL_MACHINE, key, L"GraphicsDriver", NULL)))
  96. {
  97. if(wcscmp(value, L"winemac.drv"))
  98. ret = TRUE;
  99. HeapFree(GetProcessHeap(), 0, value);
  100. }
  101. return ret;
  102. }
  103. static void init_dialog(HWND dialog)
  104. {
  105. WCHAR *buf;
  106. BOOL enable_desktop;
  107. convert_x11_desktop_key();
  108. if ((enable_desktop = can_enable_desktop()))
  109. update_gui_for_desktop_mode(dialog);
  110. else
  111. disable(IDC_ENABLE_DESKTOP);
  112. updating_ui = TRUE;
  113. if (enable_desktop)
  114. {
  115. SendDlgItemMessageW(dialog, IDC_DESKTOP_WIDTH, EM_LIMITTEXT, RES_MAXLEN, 0);
  116. SendDlgItemMessageW(dialog, IDC_DESKTOP_HEIGHT, EM_LIMITTEXT, RES_MAXLEN, 0);
  117. }
  118. buf = get_reg_key(config_key, keypath(L"X11 Driver"), L"GrabFullscreen", L"N");
  119. if (IS_OPTION_TRUE(*buf))
  120. CheckDlgButton(dialog, IDC_FULLSCREEN_GRAB, BST_CHECKED);
  121. else
  122. CheckDlgButton(dialog, IDC_FULLSCREEN_GRAB, BST_UNCHECKED);
  123. HeapFree(GetProcessHeap(), 0, buf);
  124. buf = get_reg_key(config_key, keypath(L"X11 Driver"), L"Managed", L"Y");
  125. if (IS_OPTION_TRUE(*buf))
  126. CheckDlgButton(dialog, IDC_ENABLE_MANAGED, BST_CHECKED);
  127. else
  128. CheckDlgButton(dialog, IDC_ENABLE_MANAGED, BST_UNCHECKED);
  129. HeapFree(GetProcessHeap(), 0, buf);
  130. buf = get_reg_key(config_key, keypath(L"X11 Driver"), L"Decorated", L"Y");
  131. if (IS_OPTION_TRUE(*buf))
  132. CheckDlgButton(dialog, IDC_ENABLE_DECORATED, BST_CHECKED);
  133. else
  134. CheckDlgButton(dialog, IDC_ENABLE_DECORATED, BST_UNCHECKED);
  135. HeapFree(GetProcessHeap(), 0, buf);
  136. updating_ui = FALSE;
  137. }
  138. static void set_from_desktop_edits(HWND dialog)
  139. {
  140. WCHAR *width, *height;
  141. int w = 800, h = 600;
  142. WCHAR buffer[32];
  143. const WCHAR *desktop_name = current_app ? current_app : L"Default";
  144. if (updating_ui) return;
  145. WINE_TRACE("\n");
  146. width = get_text(dialog, IDC_DESKTOP_WIDTH);
  147. height = get_text(dialog, IDC_DESKTOP_HEIGHT);
  148. if (width && width[0]) w = max( 640, wcstol(width, NULL, 10) );
  149. if (height && height[0]) h = max( 480, wcstol(height, NULL, 10) );
  150. swprintf( buffer, ARRAY_SIZE(buffer), L"%ux%u", w, h );
  151. set_reg_key(config_key, L"Explorer\\Desktops", desktop_name, buffer);
  152. set_reg_key(config_key, keypath(L"Explorer"), L"Desktop", desktop_name);
  153. HeapFree(GetProcessHeap(), 0, width);
  154. HeapFree(GetProcessHeap(), 0, height);
  155. }
  156. static void on_enable_desktop_clicked(HWND dialog) {
  157. WINE_TRACE("\n");
  158. if (IsDlgButtonChecked(dialog, IDC_ENABLE_DESKTOP) == BST_CHECKED) {
  159. set_from_desktop_edits(dialog);
  160. } else {
  161. set_reg_key(config_key, keypath(L"Explorer"), L"Desktop", NULL);
  162. }
  163. update_gui_for_desktop_mode(dialog);
  164. }
  165. static void on_enable_managed_clicked(HWND dialog) {
  166. WINE_TRACE("\n");
  167. if (IsDlgButtonChecked(dialog, IDC_ENABLE_MANAGED) == BST_CHECKED) {
  168. set_reg_key(config_key, keypath(L"X11 Driver"), L"Managed", L"Y");
  169. } else {
  170. set_reg_key(config_key, keypath(L"X11 Driver"), L"Managed", L"N");
  171. }
  172. }
  173. static void on_enable_decorated_clicked(HWND dialog) {
  174. WINE_TRACE("\n");
  175. if (IsDlgButtonChecked(dialog, IDC_ENABLE_DECORATED) == BST_CHECKED) {
  176. set_reg_key(config_key, keypath(L"X11 Driver"), L"Decorated", L"Y");
  177. } else {
  178. set_reg_key(config_key, keypath(L"X11 Driver"), L"Decorated", L"N");
  179. }
  180. }
  181. static void on_fullscreen_grab_clicked(HWND dialog)
  182. {
  183. if (IsDlgButtonChecked(dialog, IDC_FULLSCREEN_GRAB) == BST_CHECKED)
  184. set_reg_key(config_key, keypath(L"X11 Driver"), L"GrabFullscreen", L"Y");
  185. else
  186. set_reg_key(config_key, keypath(L"X11 Driver"), L"GrabFullscreen", L"N");
  187. }
  188. static INT read_logpixels_reg(void)
  189. {
  190. DWORD dwLogPixels;
  191. WCHAR *buf = get_reg_key(HKEY_CURRENT_USER, L"Control Panel\\Desktop", L"LogPixels", NULL);
  192. if (!buf) buf = get_reg_key(HKEY_CURRENT_CONFIG, L"Software\\Fonts", L"LogPixels", NULL);
  193. dwLogPixels = buf ? *buf : DEFDPI;
  194. HeapFree(GetProcessHeap(), 0, buf);
  195. return dwLogPixels;
  196. }
  197. static void init_dpi_editbox(HWND hDlg)
  198. {
  199. DWORD dwLogpixels;
  200. updating_ui = TRUE;
  201. dwLogpixels = read_logpixels_reg();
  202. WINE_TRACE("%u\n", dwLogpixels);
  203. SetDlgItemInt(hDlg, IDC_RES_DPIEDIT, dwLogpixels, FALSE);
  204. updating_ui = FALSE;
  205. }
  206. static int get_trackbar_pos( UINT dpi )
  207. {
  208. UINT i;
  209. for (i = 0; i < ARRAY_SIZE(dpi_values) - 1; i++)
  210. if ((dpi_values[i] + dpi_values[i + 1]) / 2 >= dpi) break;
  211. return i;
  212. }
  213. static void init_trackbar(HWND hDlg)
  214. {
  215. HWND hTrackBar = GetDlgItem(hDlg, IDC_RES_TRACKBAR);
  216. DWORD dwLogpixels;
  217. updating_ui = TRUE;
  218. dwLogpixels = read_logpixels_reg();
  219. SendMessageW(hTrackBar, TBM_SETRANGE, TRUE, MAKELONG(0, ARRAY_SIZE(dpi_values)-1));
  220. SendMessageW(hTrackBar, TBM_SETPAGESIZE, 0, 1);
  221. SendMessageW(hTrackBar, TBM_SETPOS, TRUE, get_trackbar_pos(dwLogpixels));
  222. updating_ui = FALSE;
  223. }
  224. static void update_dpi_trackbar_from_edit(HWND hDlg, BOOL fix)
  225. {
  226. DWORD dpi;
  227. updating_ui = TRUE;
  228. dpi = GetDlgItemInt(hDlg, IDC_RES_DPIEDIT, NULL, FALSE);
  229. if (fix)
  230. {
  231. DWORD fixed_dpi = dpi;
  232. if (dpi < MINDPI) fixed_dpi = MINDPI;
  233. if (dpi > MAXDPI) fixed_dpi = MAXDPI;
  234. if (fixed_dpi != dpi)
  235. {
  236. dpi = fixed_dpi;
  237. SetDlgItemInt(hDlg, IDC_RES_DPIEDIT, dpi, FALSE);
  238. }
  239. }
  240. if (dpi >= MINDPI && dpi <= MAXDPI)
  241. {
  242. SendDlgItemMessageW(hDlg, IDC_RES_TRACKBAR, TBM_SETPOS, TRUE, get_trackbar_pos(dpi));
  243. set_reg_key_dword(HKEY_CURRENT_USER, L"Control Panel\\Desktop", L"LogPixels", dpi);
  244. }
  245. updating_ui = FALSE;
  246. }
  247. static void update_font_preview(HWND hDlg)
  248. {
  249. DWORD dpi;
  250. updating_ui = TRUE;
  251. dpi = GetDlgItemInt(hDlg, IDC_RES_DPIEDIT, NULL, FALSE);
  252. if (dpi >= MINDPI && dpi <= MAXDPI)
  253. {
  254. static const WCHAR tahomaW[] = {'T','a','h','o','m','a',0};
  255. LOGFONTW lf;
  256. HFONT hfont;
  257. hfont = (HFONT)SendDlgItemMessageW(hDlg, IDC_RES_FONT_PREVIEW, WM_GETFONT, 0, 0);
  258. GetObjectW(hfont, sizeof(lf), &lf);
  259. if (wcscmp(lf.lfFaceName, tahomaW) != 0)
  260. lstrcpyW(lf.lfFaceName, tahomaW);
  261. else
  262. DeleteObject(hfont);
  263. lf.lfHeight = MulDiv(-10, dpi, 72);
  264. hfont = CreateFontIndirectW(&lf);
  265. SendDlgItemMessageW(hDlg, IDC_RES_FONT_PREVIEW, WM_SETFONT, (WPARAM)hfont, 1);
  266. }
  267. updating_ui = FALSE;
  268. }
  269. INT_PTR CALLBACK
  270. GraphDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  271. {
  272. switch (uMsg) {
  273. case WM_INITDIALOG:
  274. init_dpi_editbox(hDlg);
  275. init_trackbar(hDlg);
  276. update_font_preview(hDlg);
  277. break;
  278. case WM_SHOWWINDOW:
  279. set_window_title(hDlg);
  280. break;
  281. case WM_TIMER:
  282. if (wParam == IDT_DPIEDIT)
  283. {
  284. KillTimer(hDlg, IDT_DPIEDIT);
  285. update_dpi_trackbar_from_edit(hDlg, TRUE);
  286. update_font_preview(hDlg);
  287. }
  288. break;
  289. case WM_COMMAND:
  290. switch(HIWORD(wParam)) {
  291. case EN_CHANGE: {
  292. if (updating_ui) break;
  293. SendMessageW(GetParent(hDlg), PSM_CHANGED, 0, 0);
  294. if ( ((LOWORD(wParam) == IDC_DESKTOP_WIDTH) || (LOWORD(wParam) == IDC_DESKTOP_HEIGHT)) && !updating_ui )
  295. set_from_desktop_edits(hDlg);
  296. else if (LOWORD(wParam) == IDC_RES_DPIEDIT)
  297. {
  298. update_dpi_trackbar_from_edit(hDlg, FALSE);
  299. update_font_preview(hDlg);
  300. SetTimer(hDlg, IDT_DPIEDIT, 1500, NULL);
  301. }
  302. break;
  303. }
  304. case BN_CLICKED: {
  305. if (updating_ui) break;
  306. SendMessageW(GetParent(hDlg), PSM_CHANGED, 0, 0);
  307. switch(LOWORD(wParam)) {
  308. case IDC_ENABLE_DESKTOP: on_enable_desktop_clicked(hDlg); break;
  309. case IDC_ENABLE_MANAGED: on_enable_managed_clicked(hDlg); break;
  310. case IDC_ENABLE_DECORATED: on_enable_decorated_clicked(hDlg); break;
  311. case IDC_FULLSCREEN_GRAB: on_fullscreen_grab_clicked(hDlg); break;
  312. }
  313. break;
  314. }
  315. case CBN_SELCHANGE: {
  316. SendMessageW(GetParent(hDlg), PSM_CHANGED, 0, 0);
  317. break;
  318. }
  319. default:
  320. break;
  321. }
  322. break;
  323. case WM_NOTIFY:
  324. switch (((LPNMHDR)lParam)->code) {
  325. case PSN_KILLACTIVE: {
  326. SetWindowLongPtrW(hDlg, DWLP_MSGRESULT, FALSE);
  327. break;
  328. }
  329. case PSN_APPLY: {
  330. apply();
  331. SetWindowLongPtrW(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
  332. break;
  333. }
  334. case PSN_SETACTIVE: {
  335. init_dialog (hDlg);
  336. break;
  337. }
  338. }
  339. break;
  340. case WM_HSCROLL:
  341. switch (wParam) {
  342. default: {
  343. int i = SendMessageW(GetDlgItem(hDlg, IDC_RES_TRACKBAR), TBM_GETPOS, 0, 0);
  344. SetDlgItemInt(hDlg, IDC_RES_DPIEDIT, dpi_values[i], TRUE);
  345. update_font_preview(hDlg);
  346. set_reg_key_dword(HKEY_CURRENT_USER, L"Control Panel\\Desktop", L"LogPixels", dpi_values[i]);
  347. break;
  348. }
  349. }
  350. break;
  351. default:
  352. break;
  353. }
  354. return FALSE;
  355. }