diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index 0e45b2a90f3..a956ede0d57 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -156,6 +156,138 @@ bool GPG_Application::SetGameEngineData(struct Main *maggie, STR_String startSce } +#ifdef WIN32 +#define SCR_SAVE_MOUSE_MOVE_THRESHOLD 15 + +static HWND found_ghost_window_hwnd; +static GHOST_IWindow* ghost_window_to_find; +static WNDPROC ghost_wnd_proc; +static POINT scr_save_mouse_pos; + +static LRESULT CALLBACK screenSaverWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + BOOL close = FALSE; + switch (uMsg) + { + case WM_MOUSEMOVE: + { + POINT pt; + GetCursorPos(&pt); + LONG dx = scr_save_mouse_pos.x - pt.x; + LONG dy = scr_save_mouse_pos.y - pt.y; + if (abs(dx) > SCR_SAVE_MOUSE_MOVE_THRESHOLD + || abs(dy) > SCR_SAVE_MOUSE_MOVE_THRESHOLD) + { + close = TRUE; + } + scr_save_mouse_pos = pt; + break; + } + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_KEYDOWN: + close = TRUE; + } + if (close) + PostMessage(hwnd,WM_CLOSE,0,0); + return CallWindowProc(ghost_wnd_proc, hwnd, uMsg, wParam, lParam); +} + +BOOL CALLBACK findGhostWindowHWNDProc(HWND hwnd, LPARAM lParam) +{ + GHOST_IWindow *p = (GHOST_IWindow*) GetWindowLong(hwnd, GWL_USERDATA); + BOOL ret = TRUE; + if (p == ghost_window_to_find) + { + found_ghost_window_hwnd = hwnd; + ret = FALSE; + } + return ret; +} + +static HWND findGhostWindowHWND(GHOST_IWindow* window) +{ + found_ghost_window_hwnd = NULL; + ghost_window_to_find = window; + EnumWindows(findGhostWindowHWNDProc, NULL); + return found_ghost_window_hwnd; +} + +bool GPG_Application::startScreenSaverPreview( + HWND parentWindow, + const bool stereoVisual, + const int stereoMode) +{ + bool success = false; + + RECT rc; + if (GetWindowRect(parentWindow, &rc)) + { + int windowWidth = rc.right - rc.left; + int windowHeight = rc.bottom - rc.top; + STR_String title = ""; + + m_mainWindow = fSystem->createWindow(title, 0, 0, windowWidth, windowHeight, GHOST_kWindowStateMinimized, + GHOST_kDrawingContextTypeOpenGL, stereoVisual); + if (!m_mainWindow) { + printf("error: could not create main window\n"); + exit(-1); + } + + HWND ghost_hwnd = findGhostWindowHWND(m_mainWindow); + if (!ghost_hwnd) { + printf("error: could find main window\n"); + exit(-1); + } + + SetParent(ghost_hwnd, parentWindow); + LONG style = GetWindowLong(ghost_hwnd, GWL_STYLE); + LONG exstyle = GetWindowLong(ghost_hwnd, GWL_EXSTYLE); + + RECT adjrc = { 0, 0, windowWidth, windowHeight }; + AdjustWindowRectEx(&adjrc, style, FALSE, exstyle); + + style = (style & (~(WS_POPUP|WS_OVERLAPPEDWINDOW|WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_TILEDWINDOW ))) | WS_CHILD; + SetWindowLong(ghost_hwnd, GWL_STYLE, style); + SetWindowPos(ghost_hwnd, NULL, adjrc.left, adjrc.top, 0, 0, SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE); + + /* Check the size of the client rectangle of the window and resize the window + * so that the client rectangle has the size requested. + */ + m_mainWindow->setClientSize(windowWidth, windowHeight); + + success = initEngine(m_mainWindow, stereoMode); + if (success) { + success = startEngine(); + } + + } + return success; +} + +bool GPG_Application::startScreenSaverFullScreen( + int width, + int height, + int bpp,int frequency, + const bool stereoVisual, + const int stereoMode) +{ + bool ret = startFullScreen(width, height, bpp, frequency, stereoVisual, stereoMode); + if (ret) + { + HWND ghost_hwnd = findGhostWindowHWND(m_mainWindow); + if (ghost_hwnd != NULL) + { + GetCursorPos(&scr_save_mouse_pos); + ghost_wnd_proc = (WNDPROC) GetWindowLong(ghost_hwnd, GWL_WNDPROC); + SetWindowLong(ghost_hwnd,GWL_WNDPROC, (LONG) screenSaverWindowProc); + } + } + return ret; +} + +#endif bool GPG_Application::startWindow(STR_String& title, int windowLeft, diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.h b/source/gameengine/GamePlayer/ghost/GPG_Application.h index 4fcd66e64e0..183ca4318a9 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.h +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.h @@ -34,6 +34,10 @@ #include "GHOST_IEventConsumer.h" #include "STR_String.h" +#ifdef WIN32 +#include +#endif + class KX_KetsjiEngine; class KX_ISceneConverter; class NG_LoopBackNetworkDeviceInterface; @@ -60,6 +64,11 @@ public: bool startWindow(STR_String& title, int windowLeft, int windowTop, int windowWidth, int windowHeight, const bool stereoVisual, const int stereoMode); bool startFullScreen(int width, int height, int bpp, int frequency, const bool stereoVisual, const int stereoMode); +#ifdef WIN32 + bool startScreenSaverFullScreen(int width, int height, int bpp, int frequency, const bool stereoVisual, const int stereoMode); + bool startScreenSaverPreview(HWND parentWindow, const bool stereoVisual, const int stereoMode); +#endif + virtual bool processEvent(GHOST_IEvent* event); int getExitRequested(void); const STR_String& getExitString(void); diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp index a4b03628a46..d7a9ad2b41d 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp @@ -85,8 +85,8 @@ extern "C" #include "BKE_utildefines.h" #ifdef WIN32 -#ifdef NDEBUG #include +#ifdef NDEBUG #include #endif // NDEBUG #endif // WIN32 @@ -96,6 +96,62 @@ const int kMinWindowHeight = 100; char bprogname[FILE_MAXDIR+FILE_MAXFILE]; +#ifdef WIN32 +typedef enum +{ + SCREEN_SAVER_MODE_NONE = 0, + SCREEN_SAVER_MODE_PREVIEW, + SCREEN_SAVER_MODE_SAVER, + SCREEN_SAVER_MODE_CONFIGURATION, + SCREEN_SAVER_MODE_PASSWORD, +} ScreenSaverMode; + +static ScreenSaverMode scr_saver_mode = SCREEN_SAVER_MODE_NONE; +static HWND scr_saver_hwnd = NULL; + +static BOOL scr_saver_init(int argc, char **argv) +{ + scr_saver_mode = SCREEN_SAVER_MODE_NONE; + scr_saver_hwnd = NULL; + BOOL ret = FALSE; + + int len = ::strlen(argv[0]); + if (len > 4 && !::stricmp(".scr", argv[0] + len - 4)) + { + scr_saver_mode = SCREEN_SAVER_MODE_CONFIGURATION; + ret = TRUE; + if (argc >= 2) + { + if (argc >= 3) + { + scr_saver_hwnd = (HWND) ::atoi(argv[2]); + } + if (!::stricmp("/c", argv[1])) + { + scr_saver_mode = SCREEN_SAVER_MODE_CONFIGURATION; + if (scr_saver_hwnd == NULL) + scr_saver_hwnd = ::GetForegroundWindow(); + } + else if (!::stricmp("/s", argv[1])) + { + scr_saver_mode = SCREEN_SAVER_MODE_SAVER; + } + else if (!::stricmp("/a", argv[1])) + { + scr_saver_mode = SCREEN_SAVER_MODE_PASSWORD; + } + else if (!::stricmp("/p", argv[1]) + || !::stricmp("/l", argv[1])) + { + scr_saver_mode = SCREEN_SAVER_MODE_PREVIEW; + } + } + } + return ret; +} + +#endif /* WIN32 */ + void usage(char* program) { char * consoleoption; @@ -280,7 +336,34 @@ int main(int argc, char** argv) printf("argv[0] = '%s'\n", argv[0]); #endif - for (i = 1; (i < argc) && !error;) + +#ifdef WIN32 + if (scr_saver_init(argc, argv)) + { + switch (scr_saver_mode) + { + case SCREEN_SAVER_MODE_CONFIGURATION: + MessageBox(scr_saver_hwnd, "This screen saver has no options that you can set", "Screen Saver", MB_OK); + break; + case SCREEN_SAVER_MODE_PASSWORD: + /* This is W95 only, which we currently do not support. + Fall-back to normal screen saver behaviour in that case... */ + case SCREEN_SAVER_MODE_SAVER: + fullScreen = true; + fullScreenParFound = true; + break; + + case SCREEN_SAVER_MODE_PREVIEW: + /* This will actually be handled somewhere below... */ + break; + } + } +#endif + for (i = 1; (i < argc) && !error +#ifdef WIN32 + && scr_saver_mode == SCREEN_SAVER_MODE_NONE +#endif + ;) { #ifndef NDEBUG @@ -447,6 +530,9 @@ int main(int argc, char** argv) usage(argv[0]); } else +#ifdef WIN32 + if (scr_saver_mode != SCREEN_SAVER_MODE_CONFIGURATION) +#endif { #ifdef __APPLE__ //SYS_WriteCommandLineInt(syshandle, "show_framerate", 1); @@ -567,8 +653,18 @@ int main(int argc, char** argv) if (fullScreen) { - app.startFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency, - stereoWindow, stereomode); +#ifdef WIN32 + if (scr_saver_mode == SCREEN_SAVER_MODE_SAVER) + { + app.startScreenSaverFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency, + stereoWindow, stereomode); + } + else +#endif + { + app.startFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency, + stereoWindow, stereomode); + } } else { @@ -604,8 +700,17 @@ int main(int argc, char** argv) { title = "blenderplayer"; } - app.startWindow(title, windowLeft, windowTop, windowWidth, windowHeight, - stereoWindow, stereomode); +#ifdef WIN32 + if (scr_saver_mode == SCREEN_SAVER_MODE_PREVIEW) + { + app.startScreenSaverPreview(scr_saver_hwnd, stereoWindow, stereomode); + } + else +#endif + { + app.startWindow(title, windowLeft, windowTop, windowWidth, windowHeight, + stereoWindow, stereomode); + } } } else