1 /*
2  *  Copyright 2003 J Brown
3  *  Copyright 2006 Eric Kohl
4  *  Copyright 2007 Marc Piulachs (marc.piulachs@codexchange.net)
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program 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
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License along
17  *  with this program; if not, write to the Free Software Foundation, Inc.,
18  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 #include <stdarg.h>
22 #include <windef.h>
23 #include <winbase.h>
24 #include <wingdi.h>
25 #include <winuser.h>
26 #include <scrnsave.h>
27 #include <stdlib.h>
28 #include <tchar.h>
29 
30 #include "resource.h"
31 
32 #define RANDOM( min, max ) ((rand() % (int)(((max)+1) - (min))) + (min))
33 
34 #define APPNAME               _T("Logon")
35 #define APP_TIMER             1
36 #define APP_TIMER_INTERVAL    2000
37 
38 HBITMAP
39 GetScreenSaverBitmap(VOID)
40 {
41     OSVERSIONINFOEX osvi;
42 
43     ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
44     osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
45     GetVersionEx ((OSVERSIONINFO *) &osvi);
46 
47     switch(osvi.wProductType)
48     {
49         case VER_NT_WORKSTATION:
50             return LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_WORKSTATION), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
51             break;
52         default:
53             return LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_SERVER), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
54             break;
55     }
56 }
57 
58 LRESULT
59 CALLBACK
60 ScreenSaverProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
61 {
62     static RECT rect;
63     static HBITMAP bitmap;
64 
65     switch (message)
66     {
67         case WM_CREATE:
68         {
69             bitmap = GetScreenSaverBitmap ();
70             if (bitmap == NULL)
71             {
72                 MessageBox(hWnd,
73                            _T("Fatal Error: Could not load bitmap"),
74                            _T("Error"),
75                            MB_OK | MB_ICONEXCLAMATION);
76             }
77 
78             SetTimer(hWnd,
79                      APP_TIMER,
80                      APP_TIMER_INTERVAL,
81                      NULL);
82 
83              break;
84         }
85         case WM_PAINT:
86         {
87              BITMAP bm; /* Bitmap structure as seen in bmWidth & bmHeight */
88              PAINTSTRUCT ps;
89              HDC hdc;
90              HDC hdcMem;
91              HBITMAP hbmOld;
92 
93              // Obtain window coordinates.
94              GetClientRect (hWnd, &rect);
95 
96              hdc = BeginPaint(hWnd, &ps);
97              hdcMem = CreateCompatibleDC(hdc);
98              hbmOld = SelectObject(hdcMem, bitmap);
99 
100              GetObject(bitmap, sizeof(bm), &bm);
101 
102              if (rect.right < bm.bmWidth ||
103                  rect.bottom < bm.bmHeight)
104              {
105                 StretchBlt(
106                     hdc,
107                     RANDOM (0, rect.right - (bm.bmWidth /5)),
108                     RANDOM (0, rect.bottom - (bm.bmHeight /5)),
109                     bm.bmWidth /5,
110                     bm.bmHeight /5,
111                     hdcMem,
112                     0,
113                     0,
114                     bm.bmWidth,
115                     bm.bmHeight,
116                     SRCCOPY);
117              }
118              else
119              {
120                  BitBlt(
121                      hdc,
122                      RANDOM (0, rect.right - bm.bmWidth),
123                      RANDOM (0, rect.bottom - bm.bmHeight),
124                      bm.bmWidth,
125                      bm.bmHeight,
126                      hdcMem,
127                      0,
128                      0,
129                      SRCCOPY);
130              }
131 
132              SelectObject(hdcMem, hbmOld);
133              DeleteDC(hdcMem);
134 
135              EndPaint(hWnd, &ps);
136              break;
137         }
138         case WM_TIMER:
139         {
140           InvalidateRect(hWnd, NULL, 1);
141           break;
142         }
143         case WM_DESTROY:
144         {
145             KillTimer(hWnd, APP_TIMER);
146             DeleteObject(bitmap);
147             PostQuitMessage(0);
148             break;
149         }
150 
151         default:
152             // Pass Windows Messages to the default screensaver window procedure
153             return DefScreenSaverProc(hWnd, message, wParam, lParam);
154     }
155 
156     return 0;
157 }
158 
159 BOOL
160 WINAPI
161 ScreenSaverConfigureDialog(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
162 {
163     return FALSE;
164 }
165 
166 // This function is only called one time before opening the configuration dialog.
167 // Use it to show a message that no configuration is necessary and return FALSE to indicate that no configuration dialog shall be opened.
168 BOOL
169 WINAPI
170 RegisterDialogClasses(HANDLE hInst)
171 {
172     TCHAR szMessage[256];
173     TCHAR szTitle[25];
174 
175     LoadString(hInst, IDS_TEXT, szMessage, sizeof(szMessage) / sizeof(TCHAR));
176     LoadString(hInst, IDS_DESCRIPTION, szTitle, sizeof(szTitle) / sizeof(TCHAR));
177 
178     MessageBox(NULL, szMessage, szTitle, MB_OK | MB_ICONEXCLAMATION);
179 
180     return FALSE;
181 }
182