Incorporate rosapps. 0.3.15 was branched somewhat incorrectly so rosapps is not synce...
[reactos.git] / modules / rosapps / applications / screensavers / ssstars / settings.c
1 /*
2 * Star field screensaver
3 *
4 * Copyright 2011 Carlo Bramini
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #define WIN32_LEAN_AND_MEAN
22 #include <windows.h>
23 #include <tchar.h>
24 #include <commctrl.h>
25 #include <shellapi.h>
26
27 #include "resource.h"
28 #include "settings.h"
29
30 #define SIZEOF(_v) (sizeof(_v) / sizeof(*_v))
31
32 // Options for the starfield
33 SSSTARS Settings;
34
35 // Factory default settings.
36 static const SSSTARS FactoryDefaults = {
37 MAX_STARS,
38 20,
39 ROTATION_PERIODIC,
40
41 TRUE,
42 TRUE,
43 TRUE,
44 TRUE
45 };
46
47 static const DWORD RotoStrings[] = {
48 IDS_ROTATION_NONE,
49 IDS_ROTATION_LINEAR,
50 IDS_ROTATION_PERIODIC
51 };
52
53 static DWORD QueryDWORD(HKEY hKey, LPCTSTR pszValueName, DWORD Default)
54 {
55 DWORD dwData, dwType, cbData;
56 LONG lRes;
57
58 dwType = REG_DWORD;
59 cbData = sizeof(DWORD);
60
61 lRes = RegQueryValueEx(
62 hKey,
63 pszValueName,
64 NULL,
65 &dwType,
66 (LPBYTE)&dwData,
67 &cbData);
68
69 if (lRes != ERROR_SUCCESS || dwType != REG_DWORD)
70 return Default;
71
72 return dwData;
73 }
74
75 static void SaveDWORD(HKEY hKey, LPCTSTR pszValueName, DWORD dwValue)
76 {
77 RegSetValueEx(hKey, pszValueName, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(dwValue));
78 }
79
80
81 void LoadSettings(void)
82 {
83 HKEY hKey;
84 LONG lRes;
85
86 Settings = FactoryDefaults;
87
88 lRes = RegCreateKeyEx(
89 HKEY_CURRENT_USER,
90 _T("Software\\Microsoft\\ScreenSavers\\Ssstars"),
91 0,
92 _T(""),
93 0,
94 KEY_READ,
95 NULL,
96 &hKey,
97 NULL);
98
99 if (lRes != ERROR_SUCCESS)
100 return;
101
102 Settings.uiNumStars = QueryDWORD(hKey, _T("NumberOfStars"), Settings.uiNumStars);
103 Settings.uiSpeed = QueryDWORD(hKey, _T("Speed"), Settings.uiSpeed);
104 Settings.uiRotation = QueryDWORD(hKey, _T("TypeOfRotation"), Settings.uiRotation);
105
106 Settings.bDoBlending = QueryDWORD(hKey, _T("DoBlending"), Settings.bDoBlending);
107 Settings.bFinePerspective = QueryDWORD(hKey, _T("FinePerspective"), Settings.bFinePerspective);
108 Settings.bEnableFiltering = QueryDWORD(hKey, _T("EnableFiltering"), Settings.bEnableFiltering);
109 Settings.bSmoothShading = QueryDWORD(hKey, _T("SmoothShading"), Settings.bSmoothShading);
110
111 // Check the number of stars to be in range
112 if (Settings.uiNumStars < MIN_STARS)
113 Settings.uiNumStars = MIN_STARS;
114 else
115 if (Settings.uiNumStars > MAX_STARS)
116 Settings.uiNumStars = MAX_STARS;
117
118 // Check the speed to be in range
119 if (Settings.uiSpeed < MIN_SPEED)
120 Settings.uiSpeed = MIN_SPEED;
121 else
122 if (Settings.uiSpeed > MAX_SPEED)
123 Settings.uiSpeed = MAX_SPEED;
124
125 // Check type of rotation to be in range
126 if (Settings.uiRotation != ROTATION_NONE &&
127 Settings.uiRotation != ROTATION_LINEAR &&
128 Settings.uiRotation != ROTATION_PERIODIC)
129 Settings.uiRotation = ROTATION_PERIODIC;
130
131 RegCloseKey(hKey);
132 }
133
134 void SaveSettings(void)
135 {
136 HKEY hKey;
137 LONG lRes;
138
139 lRes = RegCreateKeyEx(
140 HKEY_CURRENT_USER,
141 _T("Software\\Microsoft\\ScreenSavers\\Ssstars"),
142 0,
143 _T(""),
144 0,
145 KEY_WRITE,
146 NULL,
147 &hKey,
148 NULL);
149
150 if (lRes != ERROR_SUCCESS)
151 return;
152
153 SaveDWORD(hKey, _T("NumberOfStars"), Settings.uiNumStars);
154 SaveDWORD(hKey, _T("Speed"), Settings.uiSpeed);
155 SaveDWORD(hKey, _T("TypeOfRotation"), Settings.uiRotation);
156
157 SaveDWORD(hKey, _T("DoBlending"), Settings.bDoBlending);
158 SaveDWORD(hKey, _T("FinePerspective"), Settings.bFinePerspective);
159 SaveDWORD(hKey, _T("EnableFiltering"), Settings.bEnableFiltering);
160 SaveDWORD(hKey, _T("SmoothShading"), Settings.bSmoothShading);
161
162 RegCloseKey(hKey);
163 }
164
165 static void SetupControls(HWND hWnd)
166 {
167 TCHAR Strings[256];
168 HINSTANCE hInstance;
169 UINT x, gap;
170 LOGFONT lf;
171 HFONT hFont;
172 HBITMAP hCosmos;
173 HDC hDC, hMemDC;
174 HGDIOBJ hOldBmp, hOldFnt;
175 SIZE sizeReactOS;
176 SIZE sizeStarfield;
177 BITMAP bm;
178
179 hInstance = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE);
180
181 SendDlgItemMessage(hWnd, IDC_SLIDER_NUM_OF_STARS, TBM_SETRANGE, FALSE, MAKELPARAM(MIN_STARS, MAX_STARS));
182
183 SendDlgItemMessage(hWnd, IDC_SLIDER_SPEED, TBM_SETRANGE, FALSE, MAKELPARAM(1, 100));
184
185 for (x = 0; x < ROTATION_ITEMS; x++)
186 {
187 LoadString(hInstance, RotoStrings[x], Strings, sizeof(Strings)/sizeof(TCHAR));
188 SendDlgItemMessage(hWnd, IDC_COMBO_ROTATION, CB_ADDSTRING, 0, (LPARAM)Strings);
189 }
190
191 hCosmos = LoadImage(hInstance, MAKEINTRESOURCE(IDB_COSMOS), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
192
193 hDC = GetDC(hWnd);
194 hMemDC = CreateCompatibleDC(hDC);
195
196 // Create the font for the title
197 ZeroMemory(&lf, sizeof(lf));
198
199 lf.lfWeight = FW_THIN;
200 lf.lfCharSet = ANSI_CHARSET;
201 lf.lfQuality = PROOF_QUALITY;
202 lf.lfHeight = 36;
203 _tcscpy(lf.lfFaceName, _T("Tahoma"));
204
205 hFont = CreateFontIndirect(&lf);
206
207 hOldBmp = SelectObject(hMemDC, hCosmos);
208 hOldFnt = SelectObject(hMemDC, hFont);
209
210 SetBkMode(hMemDC, TRANSPARENT);
211 SetTextColor(hMemDC, RGB(0xFF, 0xFF, 0xFF));
212
213 x = LoadString(hInstance, IDS_DESCRIPTION, Strings, sizeof(Strings)/sizeof(TCHAR));
214
215 GetTextExtentPoint32(hMemDC, _T("ReactOS"), 7, &sizeReactOS);
216 GetTextExtentPoint32(hMemDC, Strings, x, &sizeStarfield);
217
218 GetObject(hCosmos, sizeof(BITMAP), &bm);
219
220 gap = bm.bmHeight - sizeReactOS.cy - sizeStarfield.cy;
221
222 TextOut(hMemDC, 16, gap * 2 / 5, _T("ReactOS"), 7);
223 TextOut(hMemDC, 16, gap * 3 / 5 + sizeReactOS.cy, Strings, x);
224
225 SelectObject(hMemDC, hOldBmp);
226 SelectObject(hMemDC, hOldFnt);
227
228 DeleteObject(hFont);
229
230 DeleteDC(hMemDC);
231 ReleaseDC(hWnd, hDC);
232
233 SendDlgItemMessage(hWnd, IDC_IMAGE_COSMOS, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hCosmos);
234 }
235
236 static void ApplySettings(HWND hWnd)
237 {
238 SendDlgItemMessage(hWnd, IDC_SLIDER_NUM_OF_STARS, TBM_SETPOS, TRUE, Settings.uiNumStars);
239 SetDlgItemInt(hWnd, IDC_TEXT_NUM_OF_STARS, Settings.uiNumStars, FALSE);
240
241 SendDlgItemMessage(hWnd, IDC_SLIDER_SPEED, TBM_SETPOS, TRUE, Settings.uiSpeed);
242 SetDlgItemInt(hWnd, IDC_TEXT_SPEED, Settings.uiSpeed, FALSE);
243
244 SendDlgItemMessage(hWnd, IDC_COMBO_ROTATION, CB_SETCURSEL, (WPARAM)Settings.uiRotation, 0);
245
246 SendDlgItemMessage(hWnd, IDC_CHECK_DOBLENDING, BM_SETCHECK, (WPARAM)Settings.bDoBlending, 0);
247 SendDlgItemMessage(hWnd, IDC_CHECK_PERSPECTIVE, BM_SETCHECK, (WPARAM)Settings.bFinePerspective, 0);
248 SendDlgItemMessage(hWnd, IDC_CHECK_FILTERING, BM_SETCHECK, (WPARAM)Settings.bEnableFiltering, 0);
249 SendDlgItemMessage(hWnd, IDC_CHECK_SHADING, BM_SETCHECK, (WPARAM)Settings.bSmoothShading, 0);
250 }
251
252 static void ReadSettings(HWND hWnd)
253 {
254 Settings.uiNumStars = SendDlgItemMessage(hWnd, IDC_SLIDER_NUM_OF_STARS, TBM_GETPOS, 0, 0);
255 SetDlgItemInt(hWnd, IDC_TEXT_NUM_OF_STARS, Settings.uiNumStars, FALSE);
256
257 Settings.uiSpeed = SendDlgItemMessage(hWnd, IDC_SLIDER_SPEED, TBM_GETPOS, 0, 0);
258 SetDlgItemInt(hWnd, IDC_TEXT_SPEED, Settings.uiSpeed, FALSE);
259
260 Settings.uiRotation = SendDlgItemMessage(hWnd, IDC_COMBO_ROTATION, CB_GETCURSEL, 0, 0);
261
262 Settings.bDoBlending = SendDlgItemMessage(hWnd, IDC_CHECK_DOBLENDING, BM_GETCHECK, 0, 0);
263 Settings.bFinePerspective = SendDlgItemMessage(hWnd, IDC_CHECK_PERSPECTIVE, BM_GETCHECK, 0, 0);
264 Settings.bEnableFiltering = SendDlgItemMessage(hWnd, IDC_CHECK_FILTERING, BM_GETCHECK, 0, 0);
265 Settings.bSmoothShading = SendDlgItemMessage(hWnd, IDC_CHECK_SHADING, BM_GETCHECK, 0, 0);
266 }
267
268 static BOOL OnCommandAbout(HWND hWnd)
269 {
270 HINSTANCE hInstance;
271 HICON hIcon;
272 TCHAR szAppName[256];
273 TCHAR szAuthor[256];
274 TCHAR szLicense[1024];
275
276 hInstance = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE);
277
278 hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_STARFIELD));
279
280 LoadString(hInstance, IDS_DESCRIPTION, szAppName, SIZEOF(szAppName));
281 LoadString(hInstance, IDS_AUTHOR, szAuthor, SIZEOF(szAuthor));
282 LoadString(hInstance, IDS_LICENSE, szLicense, SIZEOF(szLicense));
283
284 _tcscat(szAppName, _T("#"));
285 _tcscat(szAppName, szAuthor);
286
287 ShellAbout(hWnd, szAppName, szLicense, hIcon);
288
289 return TRUE;
290 }
291
292 //
293 // Dialogbox procedure for Configuration window
294 //
295 BOOL CALLBACK ScreenSaverConfigureDialog(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
296 {
297 switch (uMsg) {
298 case WM_INITDIALOG:
299 LoadSettings();
300 SetupControls(hDlg);
301 ApplySettings(hDlg);
302 return TRUE;
303
304 case WM_COMMAND:
305 switch (LOWORD( wParam )) {
306
307 case IDOK:
308 // Write configuration
309 SaveSettings();
310
311 // Fall down...
312 case IDCANCEL:
313 EndDialog( hDlg, LOWORD( wParam ));
314 return TRUE;
315
316 case IDC_BUTTON_ABOUT:
317 return OnCommandAbout(hDlg);
318 }
319
320 case WM_HSCROLL:
321 ReadSettings(hDlg);
322 return TRUE;
323
324 }
325
326 return FALSE;
327 }
328
329 BOOL WINAPI RegisterDialogClasses(HANDLE hInst)
330 {
331 InitCommonControls();
332
333 return TRUE;
334 }
335