]> OCCT Git - occt-copy.git/commitdiff
WebAssembly fixes
authorkgv <kgv@opencascade.com>
Sun, 21 Mar 2021 17:01:12 +0000 (20:01 +0300)
committerkgv <kgv@opencascade.com>
Sun, 21 Mar 2021 18:59:25 +0000 (21:59 +0300)
CMakeLists.txt
adm/cmake/occt_csf.cmake
adm/cmake/occt_toolkit.cmake
adm/scripts/wasm_build.bat
src/DRAWBUNDLE/CMakeLists.txt
src/DRAWBUNDLE/DRAWBUNDLE.cxx
src/DRAWBUNDLE/EXTERNLIB
src/Draw/Draw_Viewer.cxx
src/Draw/Draw_Window.cxx
src/Draw/Draw_Window.hxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx

index e79e4ecd701566b974d85f4509a7d727e962d9c2..2f4c9b50649daa7aeab951909daab25a58e7964b 100644 (file)
@@ -439,7 +439,9 @@ endforeach()
 # DRAWEXE excluded when library build is static
 if (NOT BUILD_SHARED_LIBS)
   list (REMOVE_ITEM BUILD_TOOLKITS DRAWEXE)
-  #list (REMOVE_ITEM BUILD_TOOLKITS DRAWBUNDLE)
+  #if (EMSCRIPTEN)
+  #  list (REMOVE_ITEM BUILD_TOOLKITS DRAWBUNDLE)
+  #endif()
   message (STATUS "Info: DRAWEXE is not included due to ${BUILD_LIBRARY_TYPE} build library type")
 endif()
 
@@ -507,8 +509,10 @@ if (USE_TCL)
   message (STATUS "Info: TCL is used by OCCT")
   OCCT_INCLUDE_CMAKE_FILE ("adm/cmake/tcl")
 
-  message (STATUS "Info: TK is used by OCCT")
-  OCCT_INCLUDE_CMAKE_FILE ("adm/cmake/tk")
+  if (NOT EMSCRIPTEN)
+    message (STATUS "Info: TK is used by OCCT")
+    OCCT_INCLUDE_CMAKE_FILE ("adm/cmake/tk")
+  endif()
 else()
   OCCT_CHECK_AND_UNSET_GROUP ("3RDPARTY_TCL")
   OCCT_CHECK_AND_UNSET_GROUP ("3RDPARTY_TK")
index 4d716241b080efdea55c6c9d2937342b96469386..9f7d80e1ac5e885cc37db798ff36583f76dfbbb7 100644 (file)
@@ -108,6 +108,10 @@ else()
       OCCT_CHECK_AND_UNSET (OpenGlLibs_LIB)
     endif()
 
+  elseif (EMSCRIPTEN)
+    set (CSF_ThreadLibs   "pthread rt stdc++")
+    set (CSF_OpenGlesLibs "EGL GLESv2")
+    set (CSF_dl           "dl")
   elseif (ANDROID)
     set (CSF_ThreadLibs  "c")
     set (CSF_OpenGlesLibs "EGL GLESv2")
index c13ec3863fd3b4601006ca19ffc79635b04b0423..d9d30011bf9de12366280a172abc6374764880e5 100644 (file)
@@ -228,6 +228,10 @@ if (EXECUTABLE_PROJECT)
 
   install (TARGETS ${PROJECT_NAME}
            DESTINATION "${INSTALL_DIR_BIN}\${OCCT_INSTALL_BIN_LETTER}")
+
+  if (EMSCRIPTEN)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.wasm DESTINATION "${INSTALL_DIR_BIN}/${OCCT_INSTALL_BIN_LETTER}")
+  endif()
 else()
   add_library (${PROJECT_NAME} ${USED_SRCFILES} ${USED_INCFILES} ${USED_RCFILE} ${RESOURCE_FILES} ${${PROJECT_NAME}_MOC_FILES})
 
index 6581b7eaef7307aedc6ddad3ec00488a0fb5cd55..af9bfcd14ccd15154d1c84ba58e09ceceb0a064f 100644 (file)
@@ -13,6 +13,7 @@ rem Paths to 3rd-party tools and libraries
 set "aCmakeBin="
 set "aFreeType="
 set "aRapidJson="
+set "aTcl="
 
 rem Build stages to perform
 set "toCMake=1"
@@ -30,6 +31,7 @@ set "BUILD_ModelingAlgorithms=ON"
 set "BUILD_Visualization=ON"
 set "BUILD_ApplicationFramework=ON"
 set "BUILD_DataExchange=ON"
+set "BUILD_Draw=OFF"
 
 rem Optional 3rd-party libraries to enable
 set "USE_RAPIDJSON=OFF"
@@ -162,11 +164,15 @@ if ["%toCMake%"] == ["1"] (
  -D BUILD_MODULE_Visualization:BOOL="%BUILD_Visualization%" ^
  -D BUILD_MODULE_ApplicationFramework:BOOL="%BUILD_ApplicationFramework%" ^
  -D BUILD_MODULE_DataExchange:BOOL="%BUILD_DataExchange%" ^
- -D BUILD_MODULE_Draw:BOOL="OFF" ^
+ -D BUILD_MODULE_Draw:BOOL="%BUILD_Draw%" ^
  -D BUILD_DOC_Overview:BOOL="OFF" ^
  -D USE_RAPIDJSON:BOOL="%USE_RAPIDJSON%" ^
  -D 3RDPARTY_RAPIDJSON_DIR:PATH="%aRapidJson%" ^
  -D 3RDPARTY_RAPIDJSON_INCLUDE_DIR:PATH="%aRapidJson%/include" ^
+ -D 3RDPARTY_TCL_DIR:PATH="%aTcl%" ^
+ -D 3RDPARTY_TCL_INCLUDE_DIR:PATH="%aTcl%/include" ^
+ -D 3RDPARTY_TCL_LIBRARY_DIR:PATH="%aTcl%/lib" ^
+ -D 3RDPARTY_TCL_LIBRARY:FILEPATH="%aTcl%/lib/libtcl.a" ^
  "%aCasSrc%"
 
   if errorlevel 1 (
index 33a62b3e57a60707317fe6fd1e9c9657ee1512f8..05f1b1d144a6688d0428d057ef0cd0798e687798 100644 (file)
@@ -2,4 +2,17 @@ project(DRAWBUNDLE)
 
 set (EXECUTABLE_PROJECT ON)
 OCCT_INCLUDE_CMAKE_FILE (adm/cmake/occt_toolkit)
+
+if (EMSCRIPTEN)
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s WASM=1")
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s MAX_WEBGL_VERSION=2")
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s ALLOW_MEMORY_GROWTH=1")
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --bind")
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s TOTAL_MEMORY=512MB")
+
+  #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s MODULARIZE=1")
+  #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXPORT_NAME='createDRAWEXE'")
+  #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXTRA_EXPORTED_RUNTIME_METHODS=['ccall','cwrap']")
+endif()
+
 unset (EXECUTABLE_PROJECT)
index 83b8b7e570d7aedc7e409f904c8bc26bdf70f9f8..acd1e22bed914b703937355885c9172e0955a5ee 100644 (file)
@@ -16,6 +16,8 @@
 #include <Draw.hxx>
 #include <DBRep.hxx>
 #include <DrawTrSurf.hxx>
+#include <Message.hxx>
+#include <Message_PrinterSystemLog.hxx>
 
 #include <BOPTest.hxx>
 #include <DPrsStd.hxx>
 #include <XSDRAWSTLVRML.hxx>
 #include <XDEDRAW.hxx>
 
+#if defined(__EMSCRIPTEN__)
+#include <emscripten/bind.h>
+
+class DRAWEXE
+{
+public:
+  static int eval (const std::string& theCode)
+  {
+Message::SendInfo() << "DRAWEXE::eval(" << theCode.c_str() << ")"; ///
+    return Draw::GetInterpretor().Eval (theCode.c_str());
+  }
+};
+
+EMSCRIPTEN_BINDINGS(DRAWEXE) {
+  emscripten::function("eval", &DRAWEXE::eval);
+}
+#endif
+
 //=======================================================================
 //function : Draw_InitAppli
 //purpose  : 
 
 void Draw_InitAppli (Draw_Interpretor& di)
 {
+#if defined(__EMSCRIPTEN__)
+  Message_Gravity aGravity = Message_Trace;
+  Message::DefaultMessenger()->Printers().First()->SetTraceLevel (aGravity);
+  Handle(Message_PrinterSystemLog) aJSConsolePrinter = new Message_PrinterSystemLog ("DRAWEXE", aGravity);
+  Message::DefaultMessenger()->AddPrinter (aJSConsolePrinter); // open JavaScript console within the Browser to see this output
+Message::SendInfo ("Hello #1"); ///
+#endif
+
   Draw::Commands (di);
   DBRep::BasicCommands (di);
   DrawTrSurf::BasicCommands (di);
@@ -47,6 +75,7 @@ void Draw_InitAppli (Draw_Interpretor& di)
   //OpenGlesTest::Factory (di);
   //D3DHostTest::Factory (di);
   //IVtkDraw::Factory (di);
+Message::SendInfo ("Hello #2"); ///
 }
 
 #include <Draw_Main.hxx>
index 2e6318ded317dfdc0ce868ddc0ff9e9f56f6f8af..f14fb0efd5b3a0868197bc7b2a64e2513dc5b6a5 100644 (file)
@@ -66,3 +66,4 @@ CSF_objc
 CSF_Appkit
 CSF_IOKit
 CSF_winmm
+CSF_ThreadLibs
index 34fac0d5bf50192c5c4494a9b06cde7b18e657fe..af52da326363f8bbecbeed53e1ad07ba46c27db0 100644 (file)
@@ -965,7 +965,55 @@ void Draw_Viewer::Select (Standard_Integer& id, Standard_Integer& X, Standard_In
     return;
   }
   Flush();
-#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
+#ifdef _WIN32
+  HANDLE hWnd;
+
+  id = MAXVIEW; //:abv 29.05.02: cycle for working in console mode
+  while (id >= MAXVIEW)
+  {
+    if (wait)
+    {
+      Draw_Window::SelectWait (hWnd, X, Y, Button);
+    }
+    else
+    {
+      Draw_Window::SelectNoWait (hWnd, X, Y, Button);
+    }
+
+    // Recherche du numero de la vue grace au HANDLE
+    for (int i = 0; i < MAXVIEW; ++i)
+    {
+      if (myViews[i] && myViews[i]->win == hWnd ) { id = i; }
+    }
+  }
+  X =  X - myViews[id]->GetDx();
+  Y = -Y - myViews[id]->GetDy();
+#elif defined(__EMSCRIPTEN__) || defined(__ANDROID__)
+  /// TODO
+  (void )wait;
+#elif !defined(__APPLE__) || defined(MACOSX_USE_GLX)
+  id = MAXVIEW;
+  while (id >= MAXVIEW)
+  {
+    Standard_Integer aWindowNumber = 0;
+    GetNextEvent (wait, aWindowNumber, X, Y, Button);
+    if (Y < 0)
+    {
+      continue; // mouse clicked on window title
+    }
+
+    for (Standard_Integer anIter = 0; anIter < MAXVIEW; anIter++)
+    {
+      if (myViews[anIter] && myViews[anIter]->IsEqualWindows (aWindowNumber))
+      {
+        id = anIter;
+      }
+    }
+  }
+
+  X =  X - myViews[id]->GetDx();
+  Y = -Y - myViews[id]->GetDy();
+#else
   if (!wait) {
     if (id >=0 && id < MAXVIEW) {
       if (myViews[id]) myViews[id]->Wait(wait);
@@ -1023,47 +1071,6 @@ void Draw_Viewer::Select (Standard_Integer& id, Standard_Integer& X, Standard_In
     Y = -Y - myViews[id]->GetDy();
   }
   if (!wait) myViews[id]->Wait(!wait);
-#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
-  Standard_Integer aWindowNumber;
-
-  id = MAXVIEW;
-  while (id >= MAXVIEW)
-  {
-    GetNextEvent(wait, aWindowNumber, X, Y, Button);
-
-    if (Y < 0)
-    {
-      continue; // mouse clicked on window title
-    }
-
-    for (Standard_Integer anIter = 0; anIter < MAXVIEW; anIter++)
-    {
-      if (myViews[anIter] && myViews[anIter]->IsEqualWindows (aWindowNumber))
-      {
-        id = anIter;
-      }
-    }
-  }
-
-  X =  X - myViews[id]->GetDx();
-  Y = -Y - myViews[id]->GetDy();
-
-#else
-  HANDLE hWnd;
-
-  id = MAXVIEW; //:abv 29.05.02: cycle for working in console mode
-  while ( id >= MAXVIEW ) {
-    if (wait)
-      Draw_Window::SelectWait(hWnd, X, Y, Button);
-    else
-      Draw_Window::SelectNoWait(hWnd, X, Y, Button);
-
-    // Recherche du numero de la vue grace au HANDLE
-    for(int i=0 ; i<MAXVIEW ; i++)
-      if (myViews[i] && myViews[i]->win == hWnd )  id = i;
-  }
-  X =  X - myViews[id]->GetDx();
-  Y = -Y - myViews[id]->GetDy();
 #endif
 }
 
index e0f3be4882fdc53bd6b13bb7ab3a06863bac0dee..49900ab0b91e97bc5b9d693c84a927266cde25fe 100644 (file)
@@ -167,8 +167,95 @@ Standard_Boolean Draw_BlackBackGround = Standard_True;
 //======================================================
 Draw_Window* Draw_Window::firstWindow = NULL;
 
+#if defined(__EMSCRIPTEN__) || defined(__ANDROID__)
+  /// TODO
+Draw_Window::Draw_Window()
+: myWindow (NULL),
+  myView (NULL),
+  myImageBuffer (NULL),
+  myUseBuffer (false),
+  nextWindow (firstWindow),
+  previousWindow (NULL)
+{
+  if (firstWindow != NULL) firstWindow->previousWindow = this;
+  firstWindow = this;
+  (void )myWindow; (void )myView; (void )myImageBuffer; (void )myUseBuffer;
+}
+
+Draw_Window::Draw_Window (Standard_CString theTitle,
+                          const Standard_Integer& theXLeft, const Standard_Integer& theYTop,
+                          const Standard_Integer& theWidth, const Standard_Integer& theHeight)
+: myWindow (NULL),
+  myView (NULL),
+  myImageBuffer (NULL),
+  myUseBuffer (false),
+  nextWindow (firstWindow),
+  previousWindow (NULL)
+{
+  if (firstWindow != NULL) firstWindow->previousWindow = this;
+  firstWindow = this;
+  Init (theXLeft, theYTop, theWidth, theHeight);
+  SetTitle (theTitle);
+}
+
+Draw_Window::Draw_Window (NSWindow* , Standard_CString theTitle,
+                          const Standard_Integer& theXLeft, const Standard_Integer& theYTop,
+                          const Standard_Integer& theWidth, const Standard_Integer& theHeight)
+: myWindow (NULL),
+  myView (NULL),
+  myImageBuffer (NULL),
+  myUseBuffer (false),
+  nextWindow (firstWindow),
+  previousWindow (NULL)
+{
+  if (firstWindow != NULL) firstWindow->previousWindow = this;
+  firstWindow = this;
+  Init (theXLeft, theYTop, theWidth, theHeight);
+  SetTitle (theTitle);
+}
+
+Draw_Window::~Draw_Window()
+{
+  if (previousWindow != NULL)
+  {
+    previousWindow->nextWindow = nextWindow;
+  }
+  else
+  {
+    firstWindow = nextWindow;
+  }
+
+  if (nextWindow != NULL)
+  {
+    nextWindow->previousWindow = previousWindow;
+  }
+}
+void Draw_Window::Init (const Standard_Integer& , const Standard_Integer& , const Standard_Integer& , const Standard_Integer& ) {}
+void Draw_Window::InitBuffer() {}
+void Draw_Window::SetPosition (const Standard_Integer& , const Standard_Integer& ) {}
+void Draw_Window::SetDimension (const Standard_Integer& , const Standard_Integer& ) {}
+void Draw_Window::GetPosition (Standard_Integer& thePosX, Standard_Integer& thePosY) { thePosX = 0; thePosY = 0; }
+Standard_Integer Draw_Window::HeightWin() const { return 1; }
+Standard_Integer Draw_Window::WidthWin() const { return 1; }
+void Draw_Window::SetTitle (const TCollection_AsciiString& ) {}
+TCollection_AsciiString Draw_Window::GetTitle() const { return ""; }
+Standard_Boolean Draw_Window::DefineColor (const Standard_Integer& , Standard_CString ) { return Standard_True; }
+bool Draw_Window::IsMapped() const { return false; }
+void Draw_Window::DisplayWindow() {}
+void Draw_Window::Hide() {}
+void Draw_Window::Destroy() {}
+void Draw_Window::Clear() {}
+void Draw_Window::Flush() {}
+void Draw_Window::DrawString (const Standard_Integer& , const Standard_Integer& , char* ) {}
+void Draw_Window::DrawSegments (Segment* , const Standard_Integer& ) {}
+void Draw_Window::Redraw() {}
+void Draw_Window::SetColor (const Standard_Integer& theColor) { myCurrentColor = theColor; }
+void Draw_Window::SetMode (const Standard_Integer& ) {}
+Standard_Boolean Draw_Window::Save (Standard_CString ) const { return false; }
+Standard_Boolean Draw_Window::IsEqualWindows (const Standard_Integer& ) { return false; }
+
+#elif !defined(__APPLE__) || defined(MACOSX_USE_GLX)
 // X11 specific part
-#if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
 #include <X11/Xutil.h>
 #include <Aspect_DisplayConnection.hxx>
 
@@ -1014,7 +1101,7 @@ void Run_Appli(Standard_Boolean (*interprete) (const char*))
   }
 
   // Create a handler for the draw display
-#if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
+#if (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__)
   Tcl_CreateFileHandler (ConnectionNumber(Draw_WindowDisplay), TCL_READABLE, ProcessEvents, (ClientData) 0);
 #endif // __APPLE__
 
@@ -1096,7 +1183,7 @@ Standard_Boolean Init_Appli()
   Tk_GeometryRequest (aMainWindow, 200, 200);
 #endif
 
-#if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
+#if (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__)
   if (Draw_DisplayConnection.IsNull())
   {
     try
index 7f382fa7820b12b08e9aa775c660f8113b8fa5d4..9e1a74de0288bf3efb95ac344f55a336de600cfb 100644 (file)
@@ -21,7 +21,7 @@
 #include <Standard_Integer.hxx>
 #include <TCollection_AsciiString.hxx>
 
-#if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
+#if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__)
 
 const Standard_Integer MAXCOLOR = 15;
 
@@ -205,7 +205,7 @@ void Destroy_Appli();
 //======================================================
 void GetNextEvent(Event&);
 
-#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
+#elif (defined(__APPLE__) && !defined(MACOSX_USE_GLX)) || defined(__EMSCRIPTEN__) || defined(__ANDROID__)
 
 const Standard_Integer MAXCOLOR = 15;
 
index 8190dfa10baf7fe24a78ecfab28c332994c2a3c5..f42b82d3052e226f5e36047981443d346c3992a8 100644 (file)
   #include <WNT_HIDSpaceMouse.hxx>
 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
   #include <Cocoa_Window.hxx>
+#elif defined(__EMSCRIPTEN__) || defined(__ANDROID__)
+  /// TODO
+  #include <Aspect_NeutralWindow.hxx>
 #else
   #include <Xw_Window.hxx>
   #include <X11/Xlib.h> /* contains some dangerous #defines such as Status, True etc. */
   #include <X11/Xutil.h>
-  #ifdef HAVE_TK
-    #include <tk.h>
-  #endif
 #endif
 
 //==============================================================================
@@ -122,28 +122,26 @@ Standard_EXPORT int ViewerMainLoop(Standard_Integer , const char** argv);
 extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
 
 #if defined(_WIN32)
-static Handle(WNT_Window)& VT_GetWindow() {
-  static Handle(WNT_Window) WNTWin;
-  return WNTWin;
-}
+typedef WNT_Window ViewerTest_Window;
 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
-static Handle(Cocoa_Window)& VT_GetWindow()
-{
-  static Handle(Cocoa_Window) aWindow;
-  return aWindow;
-}
+typedef Cocoa_Window ViewerTest_Window;
+
 extern void ViewerTest_SetCocoaEventManagerView (const Handle(Cocoa_Window)& theWindow);
 extern void GetCocoaScreenResolution (Standard_Integer& theWidth, Standard_Integer& theHeight);
-
+#elif defined(__EMSCRIPTEN__) || defined(__ANDROID__)
+typedef Aspect_NeutralWindow ViewerTest_Window;
 #else
-static Handle(Xw_Window)& VT_GetWindow(){
-  static Handle(Xw_Window) XWWin;
-  return XWWin;
-}
+typedef Xw_Window ViewerTest_Window;
 
 static void VProcessEvents(ClientData,int);
 #endif
 
+static Handle(ViewerTest_Window)& VT_GetWindow()
+{
+  static Handle(ViewerTest_Window) aWindow;
+  return aWindow;
+}
+
 static Handle(Aspect_DisplayConnection)& GetDisplayConnection()
 {
   static Handle(Aspect_DisplayConnection) aDisplayConnection;
@@ -1718,7 +1716,7 @@ TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft
   if (isNewDriver)
   {
     // Get connection string
-  #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
+  #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__)
     if (!theDisplayName.IsEmpty())
     {
       SetDisplayConnection (new Aspect_DisplayConnection (theDisplayName));
@@ -1727,7 +1725,7 @@ TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft
     {
       ::Display* aDispX = NULL;
       // create dedicated display connection instead of reusing Tk connection
-      // so that to procede events independently through VProcessEvents()/ViewerMainLoop() callbacks
+      // so that to proceed events independently through VProcessEvents()/ViewerMainLoop() callbacks
       /*Draw_Interpretor& aCommands = Draw::GetInterpretor();
       Tcl_Interp* aTclInterp = aCommands.Interp();
       Tk_Window aMainWindow = Tk_MainWindow (aTclInterp);
@@ -1772,6 +1770,8 @@ TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft
     aScreenWidth = aWindowSize.right;
 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
     GetCocoaScreenResolution (aScreenWidth, aScreenHeight);
+#elif defined(__EMSCRIPTEN__) || defined(__ANDROID__)
+    /// TODO
 #else
     Screen *aScreen = DefaultScreenOfDisplay(GetDisplayConnection()->GetDisplay());
     aScreenWidth = WidthOfScreen(aScreen);
@@ -1863,6 +1863,10 @@ TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft
                                      aPxLeft, aPxTop,
                                      aPxWidth, aPxHeight);
   ViewerTest_SetCocoaEventManagerView (VT_GetWindow());
+#elif defined(__EMSCRIPTEN__) || defined(__ANDROID__)
+  /// TODO
+  VT_GetWindow() = new Aspect_NeutralWindow();
+  VT_GetWindow()->SetSize (aPxWidth, aPxHeight);
 #else
   VT_GetWindow() = new Xw_Window (aGraphicDriver->GetDisplayConnection(),
                                   aTitle.ToCString(),
@@ -1902,7 +1906,7 @@ TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft
     a3DViewer->SetLightOn();
   }
 
-#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
+#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__)
   if (isNewDriver)
   {
     ::Display* aDispX = GetDisplayConnection()->GetDisplay();
@@ -2238,7 +2242,7 @@ static int VInit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const cha
     }
   }
 
-#if defined(_WIN32) || (defined(__APPLE__) && !defined(MACOSX_USE_GLX))
+#if defined(_WIN32) || (defined(__APPLE__) && !defined(MACOSX_USE_GLX)) || defined(__EMSCRIPTEN__) || defined(__ANDROID__)
   if (!aDisplayName.IsEmpty())
   {
     aDisplayName.Clear();
@@ -2547,6 +2551,8 @@ void ActivateView (const TCollection_AsciiString& theViewName,
     VT_GetWindow() = Handle(WNT_Window)::DownCast(ViewerTest::CurrentView()->Window());
 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
     VT_GetWindow() = Handle(Cocoa_Window)::DownCast(ViewerTest::CurrentView()->Window());
+#elif defined(__EMSCRIPTEN__) || defined(__ANDROID__)
+    VT_GetWindow() = Handle(Aspect_NeutralWindow)::DownCast(ViewerTest::CurrentView()->Window());
 #else
     VT_GetWindow() = Handle(Xw_Window)::DownCast(ViewerTest::CurrentView()->Window());
 #endif
@@ -2626,7 +2632,7 @@ void ViewerTest::RemoveView (const TCollection_AsciiString& theViewName, const S
   aView->Window()->Unmap();
   aView->Remove();
 
-#if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
+#if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__)
   XFlush (GetDisplayConnection()->GetDisplay());
 #endif
 
@@ -2655,7 +2661,7 @@ void ViewerTest::RemoveView (const TCollection_AsciiString& theViewName, const S
       if(isRemoveDriver)
       {
         ViewerTest_myDrivers.UnBind2 (aCurrentContext->CurrentViewer()->Driver());
-      #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
+      #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__)
         Tcl_DeleteFileHandler (XConnectionNumber (aCurrentContext->CurrentViewer()->Driver()->GetDisplayConnection()->GetDisplay()));
       #endif
       }
@@ -3519,23 +3525,20 @@ int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
   return 0;
 }
 
-#elif !defined(__APPLE__) || defined(MACOSX_USE_GLX)
+#elif defined(__EMSCRIPTEN__) || defined(__ANDROID__)
 
-int min( int a, int b )
+  /// TODO
+// =======================================================================
+// function : ViewerMainLoop
+// purpose  :
+// =======================================================================
+int ViewerMainLoop (Standard_Integer , const char** )
 {
-  if( a<b )
-    return a;
-  else
-    return b;
+  // unused
+  return 0;
 }
 
-int max( int a, int b )
-{
-  if( a>b )
-    return a;
-  else
-    return b;
-}
+#elif !defined(__APPLE__) || defined(MACOSX_USE_GLX)
 
 int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
 {
@@ -3813,43 +3816,39 @@ static void VProcessEvents (ClientData theDispX, int)
 
 //==============================================================================
 //function : OSWindowSetup
-//purpose  : Setup for the X11 window to be able to cath the event
+//purpose  : Setup for the X11 window to be able to catch the event
 //==============================================================================
-
-
 static void OSWindowSetup()
 {
-#if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
+#ifdef _WIN32
+  //
+#elif defined(__EMSCRIPTEN__) || defined(__ANDROID__)
+  //
+#elif (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
   // X11
-
-  Window  window   = VT_GetWindow()->XWindow();
+  Window anXWin = VT_GetWindow()->XWindow();
   SetDisplayConnection (ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
-  Display *aDisplay = GetDisplayConnection()->GetDisplay();
-  XSynchronize(aDisplay, 1);
+  DisplayaDisplay = GetDisplayConnection()->GetDisplay();
+  XSynchronize (aDisplay, 1);
 
   // X11 : For keyboard on SUN
-  XWMHints wmhints;
-  wmhints.flags = InputHint;
-  wmhints.input = 1;
-
-  XSetWMHints( aDisplay, window, &wmhints);
-
-  XSelectInput( aDisplay, window,  ExposureMask | KeyPressMask | KeyReleaseMask |
-    ButtonPressMask | ButtonReleaseMask |
-    StructureNotifyMask |
-    PointerMotionMask |
-    Button1MotionMask | Button2MotionMask |
-    Button3MotionMask | FocusChangeMask
-    );
-  Atom aDeleteWindowAtom = GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW);
-  XSetWMProtocols(aDisplay, window, &aDeleteWindowAtom, 1);
-
-  XSynchronize(aDisplay, 0);
-
-#else
-  // _WIN32
+  XWMHints aWmHints = {};
+  aWmHints.flags = InputHint;
+  aWmHints.input = 1;
+  XSetWMHints (aDisplay, anXWin, &aWmHints);
+
+  XSelectInput (aDisplay, anXWin,
+                ExposureMask | KeyPressMask | KeyReleaseMask
+              | ButtonPressMask | ButtonReleaseMask
+              | StructureNotifyMask
+              | PointerMotionMask
+              | Button1MotionMask | Button2MotionMask
+              | Button3MotionMask | FocusChangeMask);
+  Atom aDeleteWindowAtom = GetDisplayConnection()->GetAtom (Aspect_XA_DELETE_WINDOW);
+  XSetWMProtocols (aDisplay, anXWin, &aDeleteWindowAtom, 1);
+
+  XSynchronize (aDisplay, 0);
 #endif
-
 }
 
 //==============================================================================