00001 #include "saver.h"
00002
00010 #include <glutm/config.h>
00011
00012 #if defined(GLUTM_SAVER)
00013
00014 #if !defined(WIN32)
00015 #error GLUTM_SAVER is Windows only!
00016 #endif
00017
00018 #include <windows.h>
00019 #include <scrnsave.h>
00020
00021 #include <glt/gl.h>
00022 #include <glt/glu.h>
00023 #include <glt/error.h>
00024
00025 #include <glutm/window.h>
00026 #include <glutm/master.h>
00027 #include <glutm/main.h>
00028
00029 #include <vector>
00030 #include <string>
00031 #include <cassert>
00032 using namespace std;
00033
00035
00036 static GlutWindow *_instance = NULL;
00037
00038 static HDC _hdc = 0;
00039 static HGLRC _hrc = 0;
00040 static HWND _hWnd = 0;
00041 static int _width = 0;
00042 static int _height = 0;
00043
00044
00045 static int _miscData = 0;
00046
00047 const UINT idleID = 1;
00048 const UINT tickID = 2;
00049 const UINT miscID = 3;
00050
00052
00053 VOID CALLBACK TimerIdleProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime);
00054 VOID CALLBACK TimerTickProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime);
00055 VOID CALLBACK TimerMiscProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime);
00056 LRESULT WINAPI ScreenSaverProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
00057 BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
00058 BOOL WINAPI RegisterDialogClasses(HANDLE hInst);
00059
00061
00062
00063
00064
00065
00066 VOID CALLBACK TimerIdleProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime)
00067 {
00068 if (_instance)
00069 _instance->OnIdle();
00070 }
00071
00072 VOID CALLBACK TimerTickProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime)
00073 {
00074 if (_instance)
00075 _instance->OnTick();
00076 }
00077
00078 VOID CALLBACK TimerMiscProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime)
00079 {
00080 KillTimer(hwnd,miscID);
00081 if (_instance)
00082 _instance->OnTimer(_miscData);
00083 }
00084
00085
00086
00087
00088
00089 LRESULT WINAPI ScreenSaverProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
00090 {
00091
00092
00093 switch (message)
00094 {
00095 case WM_CREATE:
00096 {
00097 _hWnd = hWnd;
00098
00099
00100
00101 assert(!_instance);
00102 std::vector<std::string> arg;
00103 GlutMain(arg);
00104 assert(_instance);
00105
00106
00107
00108 RECT rect;
00109 GetClientRect( hWnd, &rect );
00110 _width = rect.right;
00111 _height = rect.bottom;
00112
00113
00114
00115 PIXELFORMATDESCRIPTOR pfd;
00116 memset(&pfd, 0, sizeof(pfd));
00117 pfd.nSize = sizeof(pfd);
00118 pfd.nVersion = 1;
00119 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
00120 pfd.iPixelType = PFD_TYPE_RGBA;
00121 pfd.cColorBits = 24;
00122 pfd.cDepthBits = 32;
00123 pfd.iLayerType = PFD_MAIN_PLANE;
00124
00125
00126
00127 _hdc = GetDC(_hWnd);
00128 int format = ChoosePixelFormat(_hdc, &pfd);
00129 if (SetPixelFormat(_hdc, format, &pfd))
00130 {
00131
00132 _hrc = wglCreateContext(_hdc);
00133
00134 if (_hrc)
00135 wglMakeCurrent(_hdc,_hrc);
00136 else
00137 gltError("Failed to create OpenGL context.");
00138 }
00139
00140
00141
00142 timeBeginPeriod(1);
00143
00144
00145
00146 if (!_hdc || !_hrc)
00147 {
00148 assert(_hdc);
00149 assert(_hrc);
00150
00151 PostMessage(hWnd,WM_CLOSE,0,0);
00152 return 0;
00153 }
00154
00155 SetCursor(NULL);
00156
00157 if (_instance)
00158 {
00159 _instance->OnOpen();
00160 _instance->OnReshape(_width,_height);
00161 }
00162 }
00163 return TRUE;
00164
00165 case WM_PAINT:
00166 if (hWnd && _hdc && _hrc)
00167 {
00168 PAINTSTRUCT ps;
00169 BeginPaint(hWnd, &ps);
00170 if (wglMakeCurrent(_hdc,_hrc) && _instance)
00171 {
00172 _instance->OnPreDisplay();
00173 _instance->OnDisplay();
00174 _instance->OnPostDisplay();
00175 }
00176 EndPaint(hWnd, &ps);
00177 }
00178 return TRUE;
00179
00180 case WM_DESTROY:
00181 KillTimer(_hWnd,idleID);
00182 KillTimer(_hWnd,tickID);
00183 KillTimer(_hWnd,miscID);
00184
00185 if (hWnd && _hdc && _hrc)
00186 wglMakeCurrent(_hdc,_hrc);
00187
00188 if (_instance)
00189 {
00190 _instance->OnClose();
00191 delete _instance;
00192 _instance = NULL;
00193 }
00194
00195 if (hWnd && _hdc && _hrc)
00196 {
00197 wglMakeCurrent(NULL,NULL);
00198 wglDeleteContext(_hrc);
00199 ReleaseDC(_hWnd,_hdc);
00200 _hdc = 0;
00201 _hrc = 0;
00202 }
00203
00204 timeEndPeriod(1);
00205 SetCursor(LoadCursor(NULL,IDC_ARROW));
00206 PostQuitMessage(0);
00207 return TRUE;
00208
00209 case WM_LBUTTONDOWN:
00210 case WM_MBUTTONDOWN:
00211 case WM_RBUTTONDOWN:
00212 case WM_KEYDOWN:
00213 PostMessage(hWnd,WM_CLOSE,0,0);
00214 return TRUE;
00215
00216 case WM_ERASEBKGND:
00217 return TRUE;
00218 }
00219
00220 return DefScreenSaverProc(hWnd,message,wParam,lParam);
00221 }
00222
00223
00224
00225
00226
00227 BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
00228 {
00229 switch (message)
00230 {
00231 case WM_INITDIALOG:
00232 return TRUE;
00233
00234 case WM_CLOSE:
00235 EndDialog(hDlg, TRUE);
00236 return TRUE;
00237
00238 case WM_COMMAND:
00239 switch (LOWORD(wParam))
00240 {
00241 case IDOK:
00242 case IDCANCEL:
00243 EndDialog(hDlg,TRUE);
00244 return TRUE;
00245 }
00246 }
00247
00248 return FALSE;
00249 }
00250
00251
00252
00253
00254
00255 BOOL WINAPI RegisterDialogClasses(HANDLE hInst)
00256 {
00257
00258
00259
00260 return TRUE;
00261 }
00262
00264
00265
00266
00267
00268
00269 GlutWindow *GlutMaster::currentWindow()
00270 {
00271 return _instance;
00272 }
00273
00274 void GlutMaster::openWindow(GlutWindow *glutWindow)
00275 {
00276 _instance = glutWindow;
00277 glutWindow->_windowID = 1;
00278 }
00279
00280 void GlutMaster::closeWindow(GlutWindow *glutWindow)
00281 {
00282 _instance = NULL;
00283 glutWindow->_windowID = -1;
00284 }
00285
00286 void GlutMaster::init(int argc,char *argv[])
00287 {
00288 if (!_glutInit)
00289 {
00290
00291
00292 #ifdef GLUTM_OPEN_INVENTOR
00293 GlutWindowInventor::initOpenInventor();
00294 #endif
00295 }
00296 _glutInit = true;
00297 }
00298
00299 void GlutMaster::mainLoop()
00300 {
00301 }
00302
00303 void GlutMaster::positionWindow(GlutWindow *glutWindow,int x,int y) {}
00304 void GlutMaster::reshapeWindow(GlutWindow *glutWindow,int width,int height) {}
00305 void GlutMaster::setCursor(GlutWindow *glutWindow,int cursor) {}
00306 void GlutMaster::updateModifiers(GlutWindow *window) {}
00307
00308 void GlutMaster::setIdle(GlutWindow *window,bool idle)
00309 {
00310 if (!window)
00311 return;
00312
00313 if (idle)
00314 ::SetTimer(_hWnd,idleID,1,TimerIdleProc);
00315 else
00316 ::KillTimer(_hWnd,idleID);
00317 }
00318
00319 void GlutMaster::setTick(GlutWindow *window,unsigned int msec)
00320 {
00321 if (!window)
00322 return;
00323
00324 window->_tick = msec;
00325
00326 if (msec>0)
00327 ::SetTimer(_hWnd,tickID,msec,TimerTickProc);
00328 else
00329 ::KillTimer(_hWnd,tickID);
00330 }
00331
00332 void GlutMaster::setTimer(GlutWindow *window,unsigned int msec,unsigned int val)
00333 {
00334 if (!window)
00335 return;
00336
00337 _miscData = val;
00338
00339 if (msec>0)
00340 ::SetTimer(_hWnd,miscID,msec,TimerMiscProc);
00341 else
00342 ::KillTimer(_hWnd,miscID);
00343 }
00344
00345 void
00346 GlutMaster::postRedisplay(GlutWindow *glutWindow)
00347 {
00348 assert(_hWnd);
00349 if (_hWnd)
00350 ::InvalidateRect(_hWnd, NULL, FALSE);
00351 }
00352
00353 void
00354 GlutMaster::swapBuffers(GlutWindow *glutWindow)
00355 {
00356 assert(_hdc);
00357 if (_hdc)
00358 ::SwapBuffers(_hdc);
00359 }
00360
00361
00362
00363 int GlutMaster::get(const GlutWindow *window,int info) { return 0; }
00364
00365 int GlutMaster::getScreenWidth() { return _width; }
00366 int GlutMaster::getScreenHeight() { return _height; }
00367 int GlutMaster::getScreenWidthMm() { return 0; }
00368 int GlutMaster::getScreenHeightMm() { return 0; }
00369 int GlutMaster::getElapsedTime() { return 0; }
00370
00371 void GlutMaster::fullScreen(GlutWindow *window) {}
00372 void GlutMaster::gameMode (GlutWindow *window) {}
00373
00374 #endif