From f305bb22b7e5f809063539cdb76a24727f41a11a Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Tue, 9 Sep 2008 21:15:30 +0000 Subject: Patch 17508: Blender Web Plugin - XEmbed. Enable XEmbed integration of blenderplayer, using -i as input parameter to pass embedder window id. create a minimal web plugin to embed blenderplayer on web pages (using gecko/mozilla as browser). Only for *nix. --- CMakeLists.txt | 8 +++ intern/ghost/GHOST_ISystem.h | 4 +- intern/ghost/GHOST_Types.h | 10 ++++ intern/ghost/intern/GHOST_SystemCarbon.cpp | 3 +- intern/ghost/intern/GHOST_SystemCarbon.h | 4 +- intern/ghost/intern/GHOST_SystemWin32.cpp | 2 +- intern/ghost/intern/GHOST_SystemWin32.h | 3 +- intern/ghost/intern/GHOST_SystemX11.cpp | 13 ++++- intern/ghost/intern/GHOST_SystemX11.h | 6 +- intern/ghost/intern/GHOST_WindowX11.cpp | 67 +++++++++++++++++----- intern/ghost/intern/GHOST_WindowX11.h | 2 + source/gameengine/GamePlayer/CMakeLists.txt | 4 ++ .../GamePlayer/ghost/GPG_Application.cpp | 25 +++++++- .../gameengine/GamePlayer/ghost/GPG_Application.h | 3 + source/gameengine/GamePlayer/ghost/GPG_ghost.cpp | 21 ++++++- 15 files changed, 147 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 97113c22f98..4c1b863178f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,7 @@ OPTION(WITH_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" ON) OPTION(WITH_FFMPEG "Enable FFMPeg Support (http://ffmpeg.mplayerhq.hu/)" OFF) OPTION(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON) OPTION(WITH_OPENMP "Enable OpenMP (has to be supported by the compiler)" OFF) +OPTION(WITH_WEBPLUGIN "Enable Web Plugin (Mozilla-Unix only)" OFF) IF(NOT WITH_GAMEENGINE AND WITH_PLAYER) MESSAGE("WARNING: WITH_PLAYER needs WITH_GAMEENGINE") @@ -456,6 +457,13 @@ SUBDIRS( # Blender Application SUBDIRS(source/creator) +#----------------------------------------------------------------------------- +# Blender WebPlugin +IF(WITH_WEBPLUGIN) + SET(MOZILLA_DIR "${CMAKE_SOURCE_DIR}/../gecko-sdk/" CACHE PATH "Gecko SDK path") + SET(WITH_PLAYER ON) +ENDIF(WITH_WEBPLUGIN) + #----------------------------------------------------------------------------- # Blender Player IF(WITH_PLAYER) diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h index 2ad2e9ddce7..baf0cb813f8 100644 --- a/intern/ghost/GHOST_ISystem.h +++ b/intern/ghost/GHOST_ISystem.h @@ -224,13 +224,15 @@ public: * @param state The state of the window when opened. * @param type The type of drawing context installed in this window. * @param stereoVisual Create a stereo visual for quad buffered stereo. + * @param parentWindow Parent (embedder) window * @return The new window (or 0 if creation failed). */ virtual GHOST_IWindow* createWindow( const STR_String& title, GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height, GHOST_TWindowState state, GHOST_TDrawingContextType type, - const bool stereoVisual) = 0; + const bool stereoVisual, + const GHOST_TEmbedderWindowID parentWindow = 0) = 0; /** * Dispose a window. diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h index f81192f1887..6b1295f649b 100644 --- a/intern/ghost/GHOST_Types.h +++ b/intern/ghost/GHOST_Types.h @@ -100,6 +100,7 @@ typedef enum { GHOST_kWindowStateMaximized, GHOST_kWindowStateMinimized, GHOST_kWindowStateFullScreen, + GHOST_kWindowStateEmbedded, GHOST_kWindowState8Normal = 8, GHOST_kWindowState8Maximized, GHOST_kWindowState8Minimized, @@ -392,6 +393,15 @@ typedef struct { } GHOST_DisplaySetting; +#ifdef _WIN32 +typedef long GHOST_TEmbedderWindowID; +#endif // _WIN32 + +#ifndef _WIN32 +// I can't use "Window" from "" because it conflits with Window defined in winlay.h +typedef int GHOST_TEmbedderWindowID; +#endif // _WIN32 + /** * A timer task callback routine. * @param task The timer task object. diff --git a/intern/ghost/intern/GHOST_SystemCarbon.cpp b/intern/ghost/intern/GHOST_SystemCarbon.cpp index 78c25997806..067c8deee32 100644 --- a/intern/ghost/intern/GHOST_SystemCarbon.cpp +++ b/intern/ghost/intern/GHOST_SystemCarbon.cpp @@ -402,7 +402,8 @@ GHOST_IWindow* GHOST_SystemCarbon::createWindow( GHOST_TUns32 height, GHOST_TWindowState state, GHOST_TDrawingContextType type, - bool stereoVisual + bool stereoVisual, + const GHOST_TEmbedderWindowID parentWindow ) { GHOST_IWindow* window = 0; diff --git a/intern/ghost/intern/GHOST_SystemCarbon.h b/intern/ghost/intern/GHOST_SystemCarbon.h index 2afc8e0885a..2a1d6325784 100644 --- a/intern/ghost/intern/GHOST_SystemCarbon.h +++ b/intern/ghost/intern/GHOST_SystemCarbon.h @@ -103,6 +103,7 @@ public: * @param height The height the window. * @param state The state of the window when opened. * @param type The type of drawing context installed in this window. + * @param parentWindow Parent (embedder) window * @return The new window (or 0 if creation failed). */ virtual GHOST_IWindow* createWindow( @@ -113,7 +114,8 @@ public: GHOST_TUns32 height, GHOST_TWindowState state, GHOST_TDrawingContextType type, - const bool stereoVisual + const bool stereoVisual, + const GHOST_TEmbedderWindowID parentWindow = 0 ); /*************************************************************************************** diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 7bc20d38739..feb0fe39040 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -169,7 +169,7 @@ GHOST_IWindow* GHOST_SystemWin32::createWindow( const STR_String& title, GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height, GHOST_TWindowState state, GHOST_TDrawingContextType type, - bool stereoVisual) + bool stereoVisual, const GHOST_TEmbedderWindowID parentWindow ) { GHOST_Window* window = 0; window = new GHOST_WindowWin32 (title, left, top, width, height, state, type, stereoVisual); diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h index c26ef25e366..00f7af00162 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.h +++ b/intern/ghost/intern/GHOST_SystemWin32.h @@ -109,13 +109,14 @@ public: * @param height The height the window. * @param state The state of the window when opened. * @param type The type of drawing context installed in this window. + * @param parentWindow Parent (embedder) window * @return The new window (or 0 if creation failed). */ virtual GHOST_IWindow* createWindow( const STR_String& title, GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height, GHOST_TWindowState state, GHOST_TDrawingContextType type, - const bool stereoVisual); + const bool stereoVisual, const GHOST_TEmbedderWindowID parentWindow = 0 ); /*************************************************************************************** ** Event management functionality diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 3003e0b8b14..1b90831986d 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -191,6 +191,7 @@ getMainDisplayDimensions( * @param height The height the window. * @param state The state of the window when opened. * @param type The type of drawing context installed in this window. + * @param parentWindow Parent (embedder) window * @return The new window (or 0 if creation failed). */ GHOST_IWindow* @@ -203,14 +204,18 @@ createWindow( GHOST_TUns32 height, GHOST_TWindowState state, GHOST_TDrawingContextType type, - bool stereoVisual + bool stereoVisual, + const GHOST_TEmbedderWindowID parentWindow ){ GHOST_WindowX11 * window = 0; if (!m_display) return 0; + + + window = new GHOST_WindowX11 ( - this,m_display,title, left, top, width, height, state, type, stereoVisual + this,m_display,title, left, top, width, height, state, parentWindow, type, stereoVisual ); if (window) { @@ -511,7 +516,9 @@ GHOST_SystemX11::processEvent(XEvent *xe) } break; } - + + case DestroyNotify: + ::exit(-1); // We're not interested in the following things.(yet...) case NoExpose : case GraphicsExpose : diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h index 726cdfb2fff..c67f7d81e60 100644 --- a/intern/ghost/intern/GHOST_SystemX11.h +++ b/intern/ghost/intern/GHOST_SystemX11.h @@ -108,6 +108,7 @@ public: * @param state The state of the window when opened. * @param type The type of drawing context installed in this window. * @param stereoVisual Create a stereo visual for quad buffered stereo. + * @param parentWindow Parent (embedder) window * @return The new window (or 0 if creation failed). */ GHOST_IWindow* @@ -119,9 +120,10 @@ public: GHOST_TUns32 height, GHOST_TWindowState state, GHOST_TDrawingContextType type, - const bool stereoVisual + const bool stereoVisual, + const GHOST_TEmbedderWindowID parentWindow = 0 ); - + /** * @section Interface Inherited from GHOST_ISystem */ diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index a98a59377c7..7b0606c40b7 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -138,6 +138,7 @@ GHOST_WindowX11( GHOST_TUns32 width, GHOST_TUns32 height, GHOST_TWindowState state, + const GHOST_TEmbedderWindowID parentWindow, GHOST_TDrawingContextType type, const bool stereoVisual ) : @@ -205,21 +206,57 @@ GHOST_WindowX11( // create the window! - m_window = - XCreateWindow( - m_display, - RootWindow(m_display, m_visual->screen), - left, - top, - width, - height, - 0, // no border. - m_visual->depth, - InputOutput, - m_visual->visual, - CWBorderPixel|CWColormap|CWEventMask, - &xattributes - ); + ; + if (parentWindow == 0) { + m_window = + XCreateWindow( + m_display, + RootWindow(m_display, m_visual->screen), + left, + top, + width, + height, + 0, // no border. + m_visual->depth, + InputOutput, + m_visual->visual, + CWBorderPixel|CWColormap|CWEventMask, + &xattributes + ); + } else { + + Window root_return; + int x_return,y_return; + unsigned int w_return,h_return,border_w_return,depth_return; + GHOST_TInt32 screen_x, screen_y; + + XGetGeometry(m_display, parentWindow, &root_return, &x_return, &y_return, + &w_return, &h_return, &border_w_return, &depth_return ); + + left = 0; + top = 0; + width = w_return; + height = h_return; + + + m_window = XCreateWindow( + m_display, + parentWindow, // reparent against embedder + left, + top, + width, + height, + 0, // no border. + m_visual->depth, + InputOutput, + m_visual->visual, + CWBorderPixel|CWColormap|CWEventMask, + &xattributes + ); + + XSelectInput(m_display , parentWindow, SubstructureNotifyMask); + + } // Are we in fullscreen mode - then include diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h index 1203dbde80d..abb5c131cb7 100644 --- a/intern/ghost/intern/GHOST_WindowX11.h +++ b/intern/ghost/intern/GHOST_WindowX11.h @@ -64,6 +64,7 @@ public: * @param width The width the window. * @param height The height the window. * @param state The state the window is initially opened with. + * @param parentWindow Parent (embedder) window * @param type The type of drawing context installed in this window. * @param stereoVisual Stereo visual for quad buffered stereo. */ @@ -76,6 +77,7 @@ public: GHOST_TUns32 width, GHOST_TUns32 height, GHOST_TWindowState state, + const GHOST_TEmbedderWindowID parentWindow, GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone, const bool stereoVisual = false ); diff --git a/source/gameengine/GamePlayer/CMakeLists.txt b/source/gameengine/GamePlayer/CMakeLists.txt index ff1040bfb40..fc5912155cf 100644 --- a/source/gameengine/GamePlayer/CMakeLists.txt +++ b/source/gameengine/GamePlayer/CMakeLists.txt @@ -25,3 +25,7 @@ # ***** END GPL LICENSE BLOCK ***** SUBDIRS(common ghost) + +IF(WITH_WEBPLUGIN) + SUBDIRS(xembed) +ENDIF(WITH_WEBPLUGIN) diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index 806216e05bb..3d9ae66c9ea 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -129,7 +129,8 @@ GPG_Application::GPG_Application(GHOST_ISystem* system) m_blendermat(0), m_blenderglslmat(0), m_pyGlobalDictString(0), - m_pyGlobalDictString_Length(0) + m_pyGlobalDictString_Length(0), + m_isEmbedded(false) { fSystem = system; } @@ -325,6 +326,26 @@ bool GPG_Application::startWindow(STR_String& title, return success; } +bool GPG_Application::startEmbeddedWindow(STR_String& title, + const GHOST_TEmbedderWindowID parentWindow, + const bool stereoVisual, + const int stereoMode) { + + m_mainWindow = fSystem->createWindow(title, 0, 0, 0, 0, GHOST_kWindowStateNormal, + GHOST_kDrawingContextTypeOpenGL, stereoVisual, parentWindow); + + if (!m_mainWindow) { + printf("error: could not create main window\n"); + exit(-1); + } + m_isEmbedded = true; + + bool success = initEngine(m_mainWindow, stereoMode); + if (success) { + success = startEngine(); + } + return success; +} bool GPG_Application::startFullScreen( @@ -887,7 +908,7 @@ bool GPG_Application::handleKey(GHOST_IEvent* event, bool isDown) GHOST_TEventKeyData* keyData = static_cast(eventData); //no need for this test //if (fSystem->getFullScreen()) { - if (keyData->key == GHOST_kKeyEsc && !m_keyboard->m_hookesc) { + if (keyData->key == GHOST_kKeyEsc && !m_keyboard->m_hookesc && !m_isEmbedded) { m_exitRequested = KX_EXIT_REQUEST_OUTSIDE; } //} diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.h b/source/gameengine/GamePlayer/ghost/GPG_Application.h index 5242a419808..7fc369fc0fd 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.h +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.h @@ -62,6 +62,7 @@ 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); + bool startEmbeddedWindow(STR_String& title, const GHOST_TEmbedderWindowID parent_window, 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); @@ -143,6 +144,8 @@ protected: bool m_engineInitialized; /** Engine state. */ bool m_engineRunning; + /** Running on embedded window */ + bool m_isEmbedded; /** the gameengine itself */ KX_KetsjiEngine* m_ketsjiengine; diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp index cc781a38bbb..d44e983af89 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp @@ -178,6 +178,9 @@ void usage(char* program) printf(" anaglyph (Red-Blue glasses)\n"); printf(" vinterlace (Vertical interlace for autostereo display)\n"); printf(" depending on the type of stereo you want\n"); +#ifndef _WIN32 + printf(" -i: parent windows ID \n"); +#endif #ifdef _WIN32 printf(" -c: keep console window open\n"); #endif @@ -297,6 +300,9 @@ int main(int argc, char** argv) int fullScreenFrequency = 60; char* pyGlobalDictString = NULL; /* store python dict data between blend file loading */ int pyGlobalDictString_Length = 0; + GHOST_TEmbedderWindowID parentWindow = 0; + + #ifdef __linux__ #ifdef __alpha__ @@ -457,6 +463,16 @@ int main(int argc, char** argv) usage(argv[0]); return 0; break; +#ifndef _WIN32 + case 'i': + i++; + if ( (i + 1) < argc ) + parentWindow = atoi(argv[i++]); +#ifndef NDEBUG + printf("XWindows ID = %d\n", parentWindow); +#endif //NDEBUG + +#endif // _WIN32 case 'c': i++; closeConsole = false; @@ -729,7 +745,10 @@ int main(int argc, char** argv) else #endif { - app.startWindow(title, windowLeft, windowTop, windowWidth, windowHeight, + if (parentWindow != 0) + app.startEmbeddedWindow(title, parentWindow, stereoWindow, stereomode); + else + app.startWindow(title, windowLeft, windowTop, windowWidth, windowHeight, stereoWindow, stereomode); } } -- cgit v1.2.3