x11drvdlg.c 13 KB

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