changeset 1047:efc5b62b9539

reorganization
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 09 Oct 2019 18:06:58 +0200
parents 513a4053c54a
children f6be9412e42a
files Applications/Samples/SingleFrameEditorApplication.h Applications/Sdl/SdlCairoSurface.h Applications/Sdl/SdlOpenGLContext.cpp Applications/Sdl/SdlOpenGLContext.h Applications/Sdl/SdlOrthancSurface.h Applications/Sdl/SdlWindow.cpp Applications/Sdl/SdlWindow.h Framework/OpenGL/SdlOpenGLContext.cpp Framework/OpenGL/SdlOpenGLContext.h Framework/StoneException.h Framework/StoneInitialization.cpp Framework/Viewport/SdlViewport.h Framework/Viewport/SdlWindow.cpp Framework/Viewport/SdlWindow.h Resources/CMake/OrthancStoneConfiguration.cmake Samples/Sdl/FusionMprSdl.cpp Samples/Sdl/TrackerSample.cpp Samples/Sdl/TrackerSampleApp.cpp
diffstat 18 files changed, 483 insertions(+), 479 deletions(-) [+]
line wrap: on
line diff
--- a/Applications/Samples/SingleFrameEditorApplication.h	Wed Oct 09 17:18:29 2019 +0200
+++ b/Applications/Samples/SingleFrameEditorApplication.h	Wed Oct 09 18:06:58 2019 +0200
@@ -117,12 +117,12 @@
           if (tool_ == Tool_Windowing)
           {
             return new RadiographyWindowingTracker(
-                  undoRedoStack_, widget.GetScene(),
-                  viewportX, viewportY,
-                  RadiographyWindowingTracker::Action_DecreaseWidth,
-                  RadiographyWindowingTracker::Action_IncreaseWidth,
-                  RadiographyWindowingTracker::Action_DecreaseCenter,
-                  RadiographyWindowingTracker::Action_IncreaseCenter);
+              undoRedoStack_, widget.GetScene(), widget, ImageInterpolation_Nearest,
+              viewportX, viewportY,
+              RadiographyWindowingTracker::Action_DecreaseWidth,
+              RadiographyWindowingTracker::Action_IncreaseWidth,
+              RadiographyWindowingTracker::Action_DecreaseCenter,
+              RadiographyWindowingTracker::Action_IncreaseCenter);
           }
           else if (!widget.LookupSelectedLayer(selected))
           {
--- a/Applications/Sdl/SdlCairoSurface.h	Wed Oct 09 17:18:29 2019 +0200
+++ b/Applications/Sdl/SdlCairoSurface.h	Wed Oct 09 18:06:58 2019 +0200
@@ -23,7 +23,7 @@
 
 #if ORTHANC_ENABLE_SDL == 1
 
-#include "SdlWindow.h"
+#include "../../Framework/Viewport/SdlWindow.h"
 #include "../../Framework/Wrappers/CairoSurface.h"
 #include "../../Framework/Deprecated/Viewport/IViewport.h"
 
--- a/Applications/Sdl/SdlOpenGLContext.cpp	Wed Oct 09 17:18:29 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2019 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "SdlOpenGLContext.h"
-#include "../../Framework/StoneException.h"
-
-#if ORTHANC_ENABLE_SDL == 1
-
-#if !defined(ORTHANC_ENABLE_GLEW)
-#  error Macro ORTHANC_ENABLE_GLEW must be defined
-#endif
-
-#if ORTHANC_ENABLE_GLEW == 1
-#  include <GL/glew.h>
-#endif
-
-#include <Core/OrthancException.h>
-
-namespace OrthancStone
-{
-  SdlOpenGLContext::SdlOpenGLContext(const char* title,
-                                     unsigned int width,
-                                     unsigned int height,
-                                     bool allowDpiScaling) 
-    : window_(title, width, height, true /* enable OpenGL */, allowDpiScaling)
-    , context_(NULL)
-  {
-    context_ = SDL_GL_CreateContext(window_.GetObject());
-    
-    if (context_ == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError,
-                                      "Cannot initialize OpenGL");
-    }
-
-#if ORTHANC_ENABLE_GLEW == 1
-    // The initialization function of glew (i.e. "glewInit()") can
-    // only be called once an OpenGL is setup.
-    // https://stackoverflow.com/a/45033669/881731
-    {
-      static boost::mutex  mutex_;
-      static bool          isGlewInitialized_ = false;
-  
-      boost::mutex::scoped_lock lock(mutex_);
-
-      if (!isGlewInitialized_)
-      {
-        LOG(INFO) << "Initializing glew";
-        
-        GLenum err = glewInit();
-        if (GLEW_OK != err)
-        {
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError,
-                                          "Cannot initialize glew");
-        }
-
-        isGlewInitialized_ = true;
-      }
-    }    
-#endif
-  }
-
-  
-  SdlOpenGLContext::~SdlOpenGLContext()
-  {
-    SDL_GL_DeleteContext(context_);
-  }
-
-  void SdlOpenGLContext::MakeCurrent()
-  {
-    if (SDL_GL_MakeCurrent(window_.GetObject(), context_) != 0)
-    {
-      const char* errText = SDL_GetError();
-      std::stringstream ss;
-      ss << "Cannot set current OpenGL context. SDL error text: " << errText;
-      std::string errStr = ss.str();
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, errStr.c_str());
-    }
-
-    // This makes our buffer swap synchronized with the monitor's vertical refresh
-    SDL_GL_SetSwapInterval(1);
-  }
-
-  
-  void SdlOpenGLContext::SwapBuffer()
-  {
-    // Swap our buffer to display the current contents of buffer on screen
-    SDL_GL_SwapWindow(window_.GetObject());
-  }
-
-  
-  unsigned int SdlOpenGLContext::GetCanvasWidth() const
-  {
-    int w = 0;
-    SDL_GL_GetDrawableSize(window_.GetObject(), &w, NULL);
-    return static_cast<unsigned int>(w);
-  }
-
-  
-  unsigned int SdlOpenGLContext::GetCanvasHeight() const
-  {
-    int h = 0;
-    SDL_GL_GetDrawableSize(window_.GetObject(), NULL, &h);
-    return static_cast<unsigned int>(h);
-  }
-}
-
-#endif
--- a/Applications/Sdl/SdlOpenGLContext.h	Wed Oct 09 17:18:29 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2019 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#if ORTHANC_ENABLE_SDL == 1
-
-#include "../../Framework/OpenGL/IOpenGLContext.h"
-#include "SdlWindow.h"
-
-#include <Core/Enumerations.h>
-
-namespace OrthancStone
-{
-  class SdlOpenGLContext : public OpenGL::IOpenGLContext
-  {
-  private:
-    SdlWindow      window_;
-    SDL_GLContext  context_;
-
-  public:
-    SdlOpenGLContext(const char* title,
-                     unsigned int width,
-                     unsigned int height,
-                     bool allowDpiScaling = true);
-
-    ~SdlOpenGLContext();
-
-    SdlWindow& GetWindow()
-    {
-      return window_;
-    }
-
-    virtual bool IsContextLost() ORTHANC_OVERRIDE
-    {
-      // On desktop applications, an OpenGL context should never be lost
-      return false;
-    }
-
-    virtual void MakeCurrent() ORTHANC_OVERRIDE;
-
-    virtual void SwapBuffer() ORTHANC_OVERRIDE;
-
-    virtual unsigned int GetCanvasWidth() const ORTHANC_OVERRIDE;
-
-    virtual unsigned int GetCanvasHeight() const ORTHANC_OVERRIDE;
-  };
-}
-
-#endif
--- a/Applications/Sdl/SdlOrthancSurface.h	Wed Oct 09 17:18:29 2019 +0200
+++ b/Applications/Sdl/SdlOrthancSurface.h	Wed Oct 09 18:06:58 2019 +0200
@@ -23,7 +23,7 @@
 
 #if ORTHANC_ENABLE_SDL == 1
 
-#include "SdlWindow.h"
+#include "../../Framework/Viewport/SdlWindow.h"
 
 #include <Core/Images/ImageAccessor.h>
 #include <boost/thread/mutex.hpp>
--- a/Applications/Sdl/SdlWindow.cpp	Wed Oct 09 17:18:29 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,201 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2019 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "SdlWindow.h"
-
-#if ORTHANC_ENABLE_SDL == 1
-
-#include <Core/Logging.h>
-#include <Core/OrthancException.h>
-
-#ifdef WIN32 
-#include <windows.h> // for SetProcessDpiAware
-#endif 
-// WIN32
-
-#include <SDL.h>
-
-namespace OrthancStone
-{
-  SdlWindow::SdlWindow(const char* title,
-                       unsigned int width,
-                       unsigned int height,
-                       bool enableOpenGl,
-                       bool allowDpiScaling) :
-    maximized_(false)
-  {
-    // TODO Understand why, with SDL_WINDOW_OPENGL + MinGW32 + Release
-    // build mode, the application crashes whenever the SDL window is
-    // resized or maximized
-
-    uint32_t windowFlags, rendererFlags;
-    if (enableOpenGl)
-    {
-      windowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
-      rendererFlags = SDL_RENDERER_ACCELERATED;
-    }
-    else
-    {
-      windowFlags = SDL_WINDOW_RESIZABLE;
-      rendererFlags = SDL_RENDERER_SOFTWARE;
-    }
-
-// TODO: probably required on MacOS X, too
-#if defined(WIN32) && (_WIN32_WINNT >= 0x0600)
-    if (!allowDpiScaling)
-    {
-      // if we do NOT allow DPI scaling, it means an SDL pixel will be a real
-      // monitor pixel. This is needed for high-DPI applications
-
-      // Enable high-DPI support on Windows
-
-      // THE FOLLOWING HAS BEEN COMMENTED OUT BECAUSE IT WILL CRASH UNDER 
-      // OLD WINDOWS VERSIONS
-      // ADD THIS AT THE TOP TO ENABLE IT:
-      // 
-      //#pragma comment(lib, "Shcore.lib") THIS IS ONLY REQUIRED FOR SetProcessDpiAwareness
-      //#include <windows.h>
-      //#include <ShellScalingAPI.h> THIS IS ONLY REQUIRED FOR SetProcessDpiAwareness
-      //#include <comdef.h> THIS IS ONLY REQUIRED FOR SetProcessDpiAwareness
-      // SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
-      
-      // This is supported on Vista+
-      SetProcessDPIAware();
-
-      windowFlags |= SDL_WINDOW_ALLOW_HIGHDPI;
-    }
-#endif 
-// WIN32
-    
-    window_ = SDL_CreateWindow(title,
-                               SDL_WINDOWPOS_UNDEFINED,
-                               SDL_WINDOWPOS_UNDEFINED,
-                               width, height, windowFlags);
-
-    if (window_ == NULL) 
-    {
-      LOG(ERROR) << "Cannot create the SDL window: " << SDL_GetError();
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-    }
-
-    renderer_ = SDL_CreateRenderer(window_, -1, rendererFlags);
-    if (!renderer_)
-    {
-      LOG(ERROR) << "Cannot create the SDL renderer: " << SDL_GetError();
-      SDL_DestroyWindow(window_);
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-    }
-  }
-
-
-  SdlWindow::~SdlWindow()
-  {
-    if (renderer_ != NULL)
-    { 
-      SDL_DestroyRenderer(renderer_);
-    }
-
-    if (window_ != NULL)
-    { 
-      SDL_DestroyWindow(window_);
-    }
-  }
-
-
-  unsigned int SdlWindow::GetWidth() const
-  {
-    int w = -1;
-    SDL_GetWindowSize(window_, &w, NULL);
-
-    if (w < 0)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-    }
-    else
-    {
-      return static_cast<unsigned int>(w);
-    }
-  }
-
-
-  unsigned int SdlWindow::GetHeight() const
-  {
-    int h = -1;
-    SDL_GetWindowSize(window_, NULL, &h);
-
-    if (h < 0)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-    }
-    else
-    {
-      return static_cast<unsigned int>(h);
-    }
-  }
-
-
-  void SdlWindow::Render(SDL_Surface* surface)
-  {
-    //SDL_RenderClear(renderer_);
-
-    SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer_, surface);
-    if (texture != NULL)
-    {
-      SDL_RenderCopy(renderer_, texture, NULL, NULL);
-      SDL_DestroyTexture(texture);
-    }
-
-    SDL_RenderPresent(renderer_);
-  }
-
-
-  void SdlWindow::ToggleMaximize()
-  {
-    if (maximized_)
-    {
-      SDL_RestoreWindow(window_);
-      maximized_ = false;
-    }
-    else
-    {
-      SDL_MaximizeWindow(window_);
-      maximized_ = true;
-    }
-  }
-
-
-  void SdlWindow::GlobalInitialize()
-  {
-    if (SDL_Init(SDL_INIT_VIDEO) != 0)
-    {
-      LOG(ERROR) << "Cannot initialize SDL";
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-    }
-  }
-
-
-  void SdlWindow::GlobalFinalize()
-  {
-    SDL_Quit();
-  }
-}
-
-#endif
--- a/Applications/Sdl/SdlWindow.h	Wed Oct 09 17:18:29 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2019 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#if ORTHANC_ENABLE_SDL == 1
-
-#include <SDL_render.h>
-#include <SDL_video.h>
-#include <boost/noncopyable.hpp>
-
-namespace OrthancStone
-{
-  class SdlWindow : public boost::noncopyable
-  {
-  private:
-    SDL_Window    *window_;
-    SDL_Renderer  *renderer_;
-    bool           maximized_;
-
-  public:
-    SdlWindow(const char* title,
-              unsigned int width,
-              unsigned int height,
-              bool enableOpenGl,
-              bool allowDpiScaling = true);
-
-    ~SdlWindow();
-
-    SDL_Window *GetObject() const
-    {
-      return window_;
-    }
-
-    unsigned int GetWidth() const;
-
-    unsigned int GetHeight() const;
-
-    void Render(SDL_Surface* surface);
-
-    void ToggleMaximize();
-
-    static void GlobalInitialize();
-
-    static void GlobalFinalize();
-  };
-}
-
-#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/OpenGL/SdlOpenGLContext.cpp	Wed Oct 09 18:06:58 2019 +0200
@@ -0,0 +1,126 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2019 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Affero General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "SdlOpenGLContext.h"
+#include "../../Framework/StoneException.h"
+
+#if ORTHANC_ENABLE_SDL == 1
+
+#if !defined(ORTHANC_ENABLE_GLEW)
+#  error Macro ORTHANC_ENABLE_GLEW must be defined
+#endif
+
+#if ORTHANC_ENABLE_GLEW == 1
+#  include <GL/glew.h>
+#endif
+
+#include <Core/OrthancException.h>
+
+namespace OrthancStone
+{
+  SdlOpenGLContext::SdlOpenGLContext(const char* title,
+                                     unsigned int width,
+                                     unsigned int height,
+                                     bool allowDpiScaling) 
+    : window_(title, width, height, true /* enable OpenGL */, allowDpiScaling)
+    , context_(NULL)
+  {
+    context_ = SDL_GL_CreateContext(window_.GetObject());
+    
+    if (context_ == NULL)
+    {
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError,
+                                      "Cannot initialize OpenGL");
+    }
+
+#if ORTHANC_ENABLE_GLEW == 1
+    // The initialization function of glew (i.e. "glewInit()") can
+    // only be called once an OpenGL is setup.
+    // https://stackoverflow.com/a/45033669/881731
+    {
+      static boost::mutex  mutex_;
+      static bool          isGlewInitialized_ = false;
+  
+      boost::mutex::scoped_lock lock(mutex_);
+
+      if (!isGlewInitialized_)
+      {
+        LOG(INFO) << "Initializing glew";
+        
+        GLenum err = glewInit();
+        if (GLEW_OK != err)
+        {
+          throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError,
+                                          "Cannot initialize glew");
+        }
+
+        isGlewInitialized_ = true;
+      }
+    }    
+#endif
+  }
+
+  
+  SdlOpenGLContext::~SdlOpenGLContext()
+  {
+    SDL_GL_DeleteContext(context_);
+  }
+
+  void SdlOpenGLContext::MakeCurrent()
+  {
+    if (SDL_GL_MakeCurrent(window_.GetObject(), context_) != 0)
+    {
+      const char* errText = SDL_GetError();
+      std::stringstream ss;
+      ss << "Cannot set current OpenGL context. SDL error text: " << errText;
+      std::string errStr = ss.str();
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, errStr.c_str());
+    }
+
+    // This makes our buffer swap synchronized with the monitor's vertical refresh
+    SDL_GL_SetSwapInterval(1);
+  }
+
+  
+  void SdlOpenGLContext::SwapBuffer()
+  {
+    // Swap our buffer to display the current contents of buffer on screen
+    SDL_GL_SwapWindow(window_.GetObject());
+  }
+
+  
+  unsigned int SdlOpenGLContext::GetCanvasWidth() const
+  {
+    int w = 0;
+    SDL_GL_GetDrawableSize(window_.GetObject(), &w, NULL);
+    return static_cast<unsigned int>(w);
+  }
+
+  
+  unsigned int SdlOpenGLContext::GetCanvasHeight() const
+  {
+    int h = 0;
+    SDL_GL_GetDrawableSize(window_.GetObject(), NULL, &h);
+    return static_cast<unsigned int>(h);
+  }
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/OpenGL/SdlOpenGLContext.h	Wed Oct 09 18:06:58 2019 +0200
@@ -0,0 +1,68 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2019 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Affero General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#if ORTHANC_ENABLE_SDL == 1
+
+#include "IOpenGLContext.h"
+#include "../Viewport/SdlWindow.h"
+
+#include <Core/Enumerations.h>
+
+namespace OrthancStone
+{
+  class SdlOpenGLContext : public OpenGL::IOpenGLContext
+  {
+  private:
+    SdlWindow      window_;
+    SDL_GLContext  context_;
+
+  public:
+    SdlOpenGLContext(const char* title,
+                     unsigned int width,
+                     unsigned int height,
+                     bool allowDpiScaling = true);
+
+    ~SdlOpenGLContext();
+
+    SdlWindow& GetWindow()
+    {
+      return window_;
+    }
+
+    virtual bool IsContextLost() ORTHANC_OVERRIDE
+    {
+      // On desktop applications, an OpenGL context should never be lost
+      return false;
+    }
+
+    virtual void MakeCurrent() ORTHANC_OVERRIDE;
+
+    virtual void SwapBuffer() ORTHANC_OVERRIDE;
+
+    virtual unsigned int GetCanvasWidth() const ORTHANC_OVERRIDE;
+
+    virtual unsigned int GetCanvasHeight() const ORTHANC_OVERRIDE;
+  };
+}
+
+#endif
--- a/Framework/StoneException.h	Wed Oct 09 17:18:29 2019 +0200
+++ b/Framework/StoneException.h	Wed Oct 09 18:06:58 2019 +0200
@@ -86,6 +86,7 @@
     void* context_;
   };
 
+  // TODO - Is this still necessary?
   class StoneOrthancException : public StoneException
   {
   protected:
@@ -109,6 +110,7 @@
     }
   };
 
+  // TODO - To be moved in "../Applications/"
   class StoneApplicationException : public StoneException
   {
   protected:
--- a/Framework/StoneInitialization.cpp	Wed Oct 09 17:18:29 2019 +0200
+++ b/Framework/StoneInitialization.cpp	Wed Oct 09 18:06:58 2019 +0200
@@ -28,7 +28,7 @@
 #endif
 
 #if ORTHANC_ENABLE_SDL == 1
-#  include "../Applications/Sdl/SdlWindow.h"
+#  include "Viewport/SdlWindow.h"
 #endif
 
 #if ORTHANC_ENABLE_CURL == 1
--- a/Framework/Viewport/SdlViewport.h	Wed Oct 09 17:18:29 2019 +0200
+++ b/Framework/Viewport/SdlViewport.h	Wed Oct 09 18:06:58 2019 +0200
@@ -36,7 +36,7 @@
 #  error Support for OpenGL is disabled
 #endif
 
-#include "../../Applications/Sdl/SdlOpenGLContext.h"
+#include "../OpenGL/SdlOpenGLContext.h"
 #include "../Scene2D/OpenGLCompositor.h"
 #include "../Scene2D/CairoCompositor.h"
 #include "ViewportBase.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Viewport/SdlWindow.cpp	Wed Oct 09 18:06:58 2019 +0200
@@ -0,0 +1,201 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2019 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Affero General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "SdlWindow.h"
+
+#if ORTHANC_ENABLE_SDL == 1
+
+#include <Core/Logging.h>
+#include <Core/OrthancException.h>
+
+#ifdef WIN32 
+#include <windows.h> // for SetProcessDpiAware
+#endif 
+// WIN32
+
+#include <SDL.h>
+
+namespace OrthancStone
+{
+  SdlWindow::SdlWindow(const char* title,
+                       unsigned int width,
+                       unsigned int height,
+                       bool enableOpenGl,
+                       bool allowDpiScaling) :
+    maximized_(false)
+  {
+    // TODO Understand why, with SDL_WINDOW_OPENGL + MinGW32 + Release
+    // build mode, the application crashes whenever the SDL window is
+    // resized or maximized
+
+    uint32_t windowFlags, rendererFlags;
+    if (enableOpenGl)
+    {
+      windowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
+      rendererFlags = SDL_RENDERER_ACCELERATED;
+    }
+    else
+    {
+      windowFlags = SDL_WINDOW_RESIZABLE;
+      rendererFlags = SDL_RENDERER_SOFTWARE;
+    }
+
+// TODO: probably required on MacOS X, too
+#if defined(WIN32) && (_WIN32_WINNT >= 0x0600)
+    if (!allowDpiScaling)
+    {
+      // if we do NOT allow DPI scaling, it means an SDL pixel will be a real
+      // monitor pixel. This is needed for high-DPI applications
+
+      // Enable high-DPI support on Windows
+
+      // THE FOLLOWING HAS BEEN COMMENTED OUT BECAUSE IT WILL CRASH UNDER 
+      // OLD WINDOWS VERSIONS
+      // ADD THIS AT THE TOP TO ENABLE IT:
+      // 
+      //#pragma comment(lib, "Shcore.lib") THIS IS ONLY REQUIRED FOR SetProcessDpiAwareness
+      //#include <windows.h>
+      //#include <ShellScalingAPI.h> THIS IS ONLY REQUIRED FOR SetProcessDpiAwareness
+      //#include <comdef.h> THIS IS ONLY REQUIRED FOR SetProcessDpiAwareness
+      // SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
+      
+      // This is supported on Vista+
+      SetProcessDPIAware();
+
+      windowFlags |= SDL_WINDOW_ALLOW_HIGHDPI;
+    }
+#endif 
+// WIN32
+    
+    window_ = SDL_CreateWindow(title,
+                               SDL_WINDOWPOS_UNDEFINED,
+                               SDL_WINDOWPOS_UNDEFINED,
+                               width, height, windowFlags);
+
+    if (window_ == NULL) 
+    {
+      LOG(ERROR) << "Cannot create the SDL window: " << SDL_GetError();
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
+    }
+
+    renderer_ = SDL_CreateRenderer(window_, -1, rendererFlags);
+    if (!renderer_)
+    {
+      LOG(ERROR) << "Cannot create the SDL renderer: " << SDL_GetError();
+      SDL_DestroyWindow(window_);
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
+    }
+  }
+
+
+  SdlWindow::~SdlWindow()
+  {
+    if (renderer_ != NULL)
+    { 
+      SDL_DestroyRenderer(renderer_);
+    }
+
+    if (window_ != NULL)
+    { 
+      SDL_DestroyWindow(window_);
+    }
+  }
+
+
+  unsigned int SdlWindow::GetWidth() const
+  {
+    int w = -1;
+    SDL_GetWindowSize(window_, &w, NULL);
+
+    if (w < 0)
+    {
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
+    }
+    else
+    {
+      return static_cast<unsigned int>(w);
+    }
+  }
+
+
+  unsigned int SdlWindow::GetHeight() const
+  {
+    int h = -1;
+    SDL_GetWindowSize(window_, NULL, &h);
+
+    if (h < 0)
+    {
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
+    }
+    else
+    {
+      return static_cast<unsigned int>(h);
+    }
+  }
+
+
+  void SdlWindow::Render(SDL_Surface* surface)
+  {
+    //SDL_RenderClear(renderer_);
+
+    SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer_, surface);
+    if (texture != NULL)
+    {
+      SDL_RenderCopy(renderer_, texture, NULL, NULL);
+      SDL_DestroyTexture(texture);
+    }
+
+    SDL_RenderPresent(renderer_);
+  }
+
+
+  void SdlWindow::ToggleMaximize()
+  {
+    if (maximized_)
+    {
+      SDL_RestoreWindow(window_);
+      maximized_ = false;
+    }
+    else
+    {
+      SDL_MaximizeWindow(window_);
+      maximized_ = true;
+    }
+  }
+
+
+  void SdlWindow::GlobalInitialize()
+  {
+    if (SDL_Init(SDL_INIT_VIDEO) != 0)
+    {
+      LOG(ERROR) << "Cannot initialize SDL";
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
+    }
+  }
+
+
+  void SdlWindow::GlobalFinalize()
+  {
+    SDL_Quit();
+  }
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Viewport/SdlWindow.h	Wed Oct 09 18:06:58 2019 +0200
@@ -0,0 +1,67 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2019 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Affero General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#if ORTHANC_ENABLE_SDL == 1
+
+#include <SDL_render.h>
+#include <SDL_video.h>
+#include <boost/noncopyable.hpp>
+
+namespace OrthancStone
+{
+  class SdlWindow : public boost::noncopyable
+  {
+  private:
+    SDL_Window    *window_;
+    SDL_Renderer  *renderer_;
+    bool           maximized_;
+
+  public:
+    SdlWindow(const char* title,
+              unsigned int width,
+              unsigned int height,
+              bool enableOpenGl,
+              bool allowDpiScaling = true);
+
+    ~SdlWindow();
+
+    SDL_Window *GetObject() const
+    {
+      return window_;
+    }
+
+    unsigned int GetWidth() const;
+
+    unsigned int GetHeight() const;
+
+    void Render(SDL_Surface* surface);
+
+    void ToggleMaximize();
+
+    static void GlobalInitialize();
+
+    static void GlobalFinalize();
+  };
+}
+
+#endif
--- a/Resources/CMake/OrthancStoneConfiguration.cmake	Wed Oct 09 17:18:29 2019 +0200
+++ b/Resources/CMake/OrthancStoneConfiguration.cmake	Wed Oct 09 18:06:58 2019 +0200
@@ -275,17 +275,20 @@
     endif()
       
     if (ENABLE_SDL)
+      list(APPEND ORTHANC_STONE_SOURCES
+        ${ORTHANC_STONE_ROOT}/Framework/Viewport/SdlWindow.cpp
+        )
+
       list(APPEND APPLICATIONS_SOURCES
         ${ORTHANC_STONE_ROOT}/Applications/Sdl/SdlCairoSurface.cpp
         ${ORTHANC_STONE_ROOT}/Applications/Sdl/SdlEngine.cpp
         ${ORTHANC_STONE_ROOT}/Applications/Sdl/SdlOrthancSurface.cpp
         ${ORTHANC_STONE_ROOT}/Applications/Sdl/SdlStoneApplicationRunner.cpp
-        ${ORTHANC_STONE_ROOT}/Applications/Sdl/SdlWindow.cpp
         )
 
       if (ENABLE_OPENGL)
-        list(APPEND APPLICATIONS_SOURCES
-          ${ORTHANC_STONE_ROOT}/Applications/Sdl/SdlOpenGLContext.cpp
+        list(APPEND ORTHANC_STONE_SOURCES
+          ${ORTHANC_STONE_ROOT}/Framework/OpenGL/SdlOpenGLContext.cpp
           ${ORTHANC_STONE_ROOT}/Framework/Viewport/SdlViewport.cpp
           )
       endif()
--- a/Samples/Sdl/FusionMprSdl.cpp	Wed Oct 09 17:18:29 2019 +0200
+++ b/Samples/Sdl/FusionMprSdl.cpp	Wed Oct 09 18:06:58 2019 +0200
@@ -20,7 +20,7 @@
 
 #include "FusionMprSdl.h"
 
-#include "../../Applications/Sdl/SdlOpenGLContext.h"
+#include "../../Framework/OpenGL/SdlOpenGLContext.h"
 
 #include "../../Framework/StoneInitialization.h"
 
--- a/Samples/Sdl/TrackerSample.cpp	Wed Oct 09 17:18:29 2019 +0200
+++ b/Samples/Sdl/TrackerSample.cpp	Wed Oct 09 18:06:58 2019 +0200
@@ -21,7 +21,7 @@
 #include "TrackerSampleApp.h"
 
  // From Stone
-#include "../../Applications/Sdl/SdlOpenGLContext.h"
+#include "../../Framework/OpenGL/SdlOpenGLContext.h"
 #include "../../Framework/Scene2D/CairoCompositor.h"
 #include "../../Framework/Scene2D/ColorTextureSceneLayer.h"
 #include "../../Framework/Scene2D/OpenGLCompositor.h"
--- a/Samples/Sdl/TrackerSampleApp.cpp	Wed Oct 09 17:18:29 2019 +0200
+++ b/Samples/Sdl/TrackerSampleApp.cpp	Wed Oct 09 18:06:58 2019 +0200
@@ -20,8 +20,7 @@
 
 #include "TrackerSampleApp.h"
 
-#include "../../Applications/Sdl/SdlOpenGLContext.h"
-
+#include "../../Framework/OpenGL/SdlOpenGLContext.h"
 #include "../../Framework/Scene2D/CairoCompositor.h"
 #include "../../Framework/Scene2D/ColorTextureSceneLayer.h"
 #include "../../Framework/Scene2D/OpenGLCompositor.h"