[Bf-committers] Screenblender (Using blenderplayer.exe as a screen saver)

Raymond Penners dotsphinx at gmail.com
Fri Nov 26 22:45:54 CET 2004


Hi,

Attached is a patch that enables the blenderplayer to be run as a
screen saver on Windows machines.

- The patch only alters files in: blender/source/gameengine/GamePlayer/ghost

- Any blenderplayer.exe (with the patch applied) can be renamed into
something.scr, and it will behave as a Windows screen saver.
(Right-click the .scr file, and select "Install". Then, it will appear
in the screen saver properties dialog part of the display settings,
including small preview et al).

- The screen saving functionality does not affect the executable when
it is NOT named .scr

- The screen saver automatically exits when the mouse/keyboard is
moved/pressed. There is no more need to wrap blenderplayer.exe into a
bat file and use python quit controllers, or whatever else is
suggested at http://download.blender.org/documentation/oldsite/oldsite.blender3d.org/181_Blender%20news%20haloParty.html

- It has been currently been tested to work Windows XP

Please let me know what you think of this patch. Is it commit worthy? :)

Regards,
--
Raymond Penners -*- raymond at dotsphinx.com -*- www.dotsphinx.com
-------------- next part --------------
diff -u -r /cygdrive/d/blenderdev/blender-2.35/source/gameengine/GamePlayer//ghost/GPG_Application.cpp ./GPG_Application.cpp
--- /cygdrive/d/blenderdev/blender-2.35/source/gameengine/GamePlayer//ghost/GPG_Application.cpp	2004-08-10 14:34:12.000000000 +0200
+++ ./GPG_Application.cpp	2004-11-25 22:13:32.000000000 +0100
@@ -156,6 +156,138 @@
 }
 
 
+#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 -u -r /cygdrive/d/blenderdev/blender-2.35/source/gameengine/GamePlayer//ghost/GPG_Application.h ./GPG_Application.h
--- /cygdrive/d/blenderdev/blender-2.35/source/gameengine/GamePlayer//ghost/GPG_Application.h	2004-05-03 02:45:04.000000000 +0200
+++ ./GPG_Application.h	2004-11-25 21:56:24.000000000 +0100
@@ -34,6 +34,10 @@
 #include "GHOST_IEventConsumer.h"
 #include "STR_String.h"
 
+#ifdef WIN32
+#include <wtypes.h>
+#endif
+
 class KX_KetsjiEngine;
 class KX_ISceneConverter;
 class NG_LoopBackNetworkDeviceInterface;
@@ -60,6 +64,11 @@
 			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 -u -r /cygdrive/d/blenderdev/blender-2.35/source/gameengine/GamePlayer//ghost/GPG_ghost.cpp ./GPG_ghost.cpp
--- /cygdrive/d/blenderdev/blender-2.35/source/gameengine/GamePlayer//ghost/GPG_ghost.cpp	2004-11-07 23:21:48.000000000 +0100
+++ ./GPG_ghost.cpp	2004-11-25 21:58:37.000000000 +0100
@@ -90,12 +90,70 @@
 #include <wincon.h>
 #endif // NDEBUG
 #endif // WIN32
+//fixme
+#include <windows.h>
 
 const int kMinWindowWidth = 100;
 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 +338,34 @@
 	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 +532,9 @@
 		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 +655,18 @@
 							
 							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 +702,17 @@
 								{
 									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



More information about the Bf-committers mailing list