diff --git a/build.sh b/build.sh
index 2bcdb88ccad807964849a61a41251b9aaa1ebad9..94b867435a862bfbe35ca6e4a40b0a6c2928c20b 100755
--- a/build.sh
+++ b/build.sh
@@ -1,7 +1,7 @@
 #!/bin/bash
 
 ###########################################################################
-#   Copyright (C) 2008-2009 by Oliver Bock                                #
+#   Copyright (C) 2008-2020 by Oliver Bock                                #
 #   oliver.bock[AT]aei.mpg.de                                             #
 #                                                                         #
 #   This file is part of Einstein@Home.                                   #
@@ -23,13 +23,16 @@
 
 ### globals ###############################################################
 
+FREETYPE_VERSION=2.10.1
+LIBXML_VERSION=2.9.10
+SDL_VERSION=2.0.10
+TAG_GFXAPPS="current_gfx_apps"
+
 ROOT=`pwd`
 PATH_ORG="$PATH"
 PATH_MINGW="$PATH"
 LOGFILE=$ROOT/build.log
 
-TAG_GFXAPPS="current_gfx_apps"
-
 TARGET=0
 TARGET_LINUX=1
 TARGET_MAC=2
@@ -65,7 +68,7 @@ failure()
         echo "Please check logfile: `basename $LOGFILE`"
         echo "These are the final ten lines:"
         echo "------------------------------------"
-        tail -n 14 $LOGFILE | head -n 10
+        tail -n 13 $LOGFILE | head -n 10
     fi
 
     echo "************************************" | tee -a $LOGFILE
@@ -152,6 +155,7 @@ check_prerequisites()
     for tool in $TOOLS; do
         if ! ( type $tool >/dev/null 2>&1 ); then
             echo "Missing \"$tool\" which is a required tool!" | tee -a $LOGFILE
+            echo "Required are: $TOOLS" | tee -a $LOGFILE
             return 1
         fi
     done
@@ -249,8 +253,8 @@ prepare_sdl()
         # local changes (patches) are reverted, hence also updated
         hg update --clean >> $LOGFILE 2>&1 || failure
     else
-        echo "Retrieving SDL (this may take a while)..." | tee -a $LOGFILE
-        hg clone -r SDL-1.2 http://hg.libsdl.org/SDL . >> $LOGFILE 2>&1 || failure
+        echo "Retrieving SDL $SDL_VERSION (this may take a while)..." | tee -a $LOGFILE
+        hg clone -r release-$SDL_VERSION http://hg.libsdl.org/SDL . >> $LOGFILE 2>&1 || failure
     fi
 
     return 0
@@ -262,14 +266,14 @@ prepare_freetype()
     echo "Preparing Freetype2..." | tee -a $LOGFILE
     mkdir -p $ROOT/build/freetype2 >> $LOGFILE || failure
 
-    echo "Retrieving Freetype2 (this may take a while)..." | tee -a $LOGFILE
+    echo "Retrieving Freetype2 $FREETYPE_VERSION (this may take a while)..." | tee -a $LOGFILE
     cd $ROOT/3rdparty || failure
-    wget http://download.savannah.gnu.org/releases/freetype/freetype-2.3.5.tar.bz2 >> $LOGFILE 2>&1 || failure
-    tar -xjf freetype-2.3.5.tar.bz2 >> $LOGFILE 2>&1 || failure
-    rm freetype-2.3.5.tar.bz2 >> $LOGFILE 2>&1 || failure
+    wget https://download.savannah.gnu.org/releases/freetype/freetype-$FREETYPE_VERSION.tar.gz >> $LOGFILE 2>&1 || failure
+    tar -xzf freetype-$FREETYPE_VERSION.tar.gz >> $LOGFILE 2>&1 || failure
+    rm freetype-$FREETYPE_VERSION.tar.gz >> $LOGFILE 2>&1 || failure
     # substitute old source tree
     rm -rf freetype2 >> $LOGFILE 2>&1 || failure
-    mv freetype-2.3.5 freetype2 >> $LOGFILE 2>&1 || failure
+    mv freetype-$FREETYPE_VERSION freetype2 >> $LOGFILE 2>&1 || failure
 
     return 0
 }
@@ -280,15 +284,15 @@ prepare_libxml()
     echo "Preparing libxml2..." | tee -a $LOGFILE
     mkdir -p $ROOT/build/libxml2 >> $LOGFILE || failure
 
-    echo "Retrieving libxml2 (this may take a while)..." | tee -a $LOGFILE
+    echo "Retrieving libxml2 $LIBXML_VERSION (this may take a while)..." | tee -a $LOGFILE
     cd $ROOT/3rdparty || failure
-    rm -f libxml2-sources-2.6.32.tar.gz >> $LOGFILE 2>&1 || failure
-    wget --passive-ftp ftp://xmlsoft.org/libxml2/old/libxml2-sources-2.6.32.tar.gz >> $LOGFILE 2>&1 || failure
-    tar -xzf libxml2-sources-2.6.32.tar.gz >> $LOGFILE 2>&1 || failure
-    rm libxml2-sources-2.6.32.tar.gz >> $LOGFILE 2>&1 || failure
+    rm -f libxml2-sources-$LIBXML_VERSION.tar.gz >> $LOGFILE 2>&1 || failure
+    wget --passive-ftp ftp://xmlsoft.org/libxml2/libxml2-sources-$LIBXML_VERSION.tar.gz >> $LOGFILE 2>&1 || failure
+    tar -xzf libxml2-sources-$LIBXML_VERSION.tar.gz >> $LOGFILE 2>&1 || failure
+    rm libxml2-sources-$LIBXML_VERSION.tar.gz >> $LOGFILE 2>&1 || failure
     # substitute old source tree
     rm -rf libxml2 >> $LOGFILE 2>&1 || failure
-    mv libxml2-2.6.32 libxml2 >> $LOGFILE 2>&1 || failure
+    mv libxml2-$LIBXML_VERSION libxml2 >> $LOGFILE 2>&1 || failure
 
     return 0
 }
@@ -308,7 +312,7 @@ prepare_oglft()
         svn update >> $LOGFILE  2>&1 || failure
     else
         echo "Retrieving OGLFT (this may take a while)..." | tee -a $LOGFILE
-        svn checkout http://oglft.svn.sourceforge.net/svnroot/oglft/trunk . >> $LOGFILE 2>&1 || failure
+        svn checkout https://svn.code.sf.net/p/oglft/code/trunk . >> $LOGFILE 2>&1 || failure
     fi
 }
 
@@ -386,8 +390,7 @@ build_freetype()
     ./autogen.sh >> $LOGFILE 2>&1 || failure
     chmod +x configure >> $LOGFILE 2>&1 || failure
     cd $ROOT/build/freetype2 || failure
-    # note: freetype (or sdl?) probably doesn't need *no* configure when static -> ansi build, see readme!
-    $ROOT/3rdparty/freetype2/configure --prefix=$ROOT/install --enable-shared=no --enable-static=yes >> $LOGFILE 2>&1 || failure
+    $ROOT/3rdparty/freetype2/configure --prefix=$ROOT/install --enable-freetype-config --enable-shared=no --enable-static=yes --without-png --without-zlib --without-bzip2 >> $LOGFILE 2>&1 || failure
     make >> $LOGFILE 2>&1 || failure
     make install >> $LOGFILE 2>&1 || failure
     echo "Successfully built and installed Freetype2!" | tee -a $LOGFILE
@@ -409,7 +412,7 @@ build_libxml()
     cd $ROOT/3rdparty/libxml2 || failure
     chmod +x configure >> $LOGFILE 2>&1 || failure
     cd $ROOT/build/libxml2 || failure
-    $ROOT/3rdparty/libxml2/configure --prefix=$ROOT/install --enable-shared=no --enable-static=yes --without-python >> $LOGFILE 2>&1 || failure
+    $ROOT/3rdparty/libxml2/configure --prefix=$ROOT/install --enable-shared=no --enable-static=yes --without-python --without-zlib --without-lzma --without-http --without-iconv  >> $LOGFILE 2>&1 || failure
     make >> $LOGFILE 2>&1 || failure
     make install >> $LOGFILE 2>&1 || failure
     echo "Successfully built and installed libxml2!" | tee -a $LOGFILE
@@ -464,8 +467,17 @@ build_boinc()
     chmod +x configure >> $LOGFILE 2>&1 || failure
     cd $ROOT/build/boinc || failure
     if [ "$1" == "$TARGET_MAC" ]; then
+        echo "Compiling derived sources..." | tee -a $LOGFILE
+        cd $ROOT/3rdparty/boinc/mac_build || failure
+        xcodebuild -project boinc.xcodeproj -target gfx2libboinc -configuration Deployment build >> $LOGFILE 2>&1 || failure
+        cp $ROOT/3rdparty/boinc/mac_build/build/boinc.build/Deployment/gfx2libboinc.build/DerivedSources/x86_64/*.h $ROOT/build/boinc >> $LOGFILE 2>&1 || failure
+	cd $ROOT/build/boinc || failure
         export CPPFLAGS="-I/sw/include -I/opt/local/include $CPPFLAGS"
         $ROOT/3rdparty/boinc/configure --prefix=$ROOT/install --enable-shared=no --enable-static=yes --disable-server --disable-client --with-apple-opengl-framework --enable-install-headers --enable-libraries --disable-manager --disable-fcgi >> $LOGFILE 2>&1 || failure
+        echo "Fixing up BOINC's incomplete out-of-tree build..." | tee -a $LOGFILE
+        mkdir -p $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
+        cp $ROOT/build/boinc/config.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
+        cp $ROOT/3rdparty/boinc/project_specific_defines.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
     elif [ -d "/usr/local/ssl" ]; then
         echo "Using local SSL library..." | tee -a $LOGFILE
         $ROOT/3rdparty/boinc/configure --prefix=$ROOT/install --enable-shared=no --enable-static=yes --disable-server --disable-client --enable-install-headers --enable-libraries --disable-manager --disable-fcgi CPPFLAGS=-I/usr/local/ssl/include LDFLAGS=-L/usr/local/ssl/lib >> $LOGFILE 2>&1 || failure
@@ -575,7 +587,7 @@ build_freetype_mingw()
     fi
     cd $ROOT/build/freetype2 || failure
     # note: freetype (or sdl?) probably doesn't need *no* configure when static -> ansi build, see readme!
-    $ROOT/3rdparty/freetype2/configure --host=$TARGET_HOST --build=$BUILD_HOST --prefix=$PREFIX --enable-shared=no --enable-static=yes >> $LOGFILE 2>&1 || failure
+    $ROOT/3rdparty/freetype2/configure --host=$TARGET_HOST --build=$BUILD_HOST --prefix=$PREFIX --enable-shared=no --enable-static=yes --without-png --without-zlib --without-bzip2 >> $LOGFILE 2>&1 || failure
     make >> $LOGFILE 2>&1 || failure
     make install >> $LOGFILE 2>&1 || failure
     echo "Successfully built and installed Freetype2!" | tee -a $LOGFILE
@@ -602,7 +614,7 @@ build_libxml_mingw()
         echo "Cross-compile LIBXML2_CONFIG: $LIBXML2_CONFIG" >> $LOGFILE
     fi
     cd $ROOT/build/libxml2 || failure
-    $ROOT/3rdparty/libxml2/configure --host=$TARGET_HOST --build=$BUILD_HOST --prefix=$PREFIX --enable-shared=no --enable-static=yes --without-python >> $LOGFILE 2>&1 || failure
+    $ROOT/3rdparty/libxml2/configure --host=$TARGET_HOST --build=$BUILD_HOST --prefix=$PREFIX --enable-shared=no --enable-static=yes --without-python --without-zlib --without-lzma --without-http --without-iconv >> $LOGFILE 2>&1 || failure
     make >> $LOGFILE 2>&1 || failure
     make install >> $LOGFILE 2>&1 || failure
     echo "Successfully built and installed libxml2!" | tee -a $LOGFILE
@@ -670,6 +682,8 @@ build_starsphere()
     mkdir -p $ROOT/build/starsphere >> $LOGFILE || failure
     export PATH=$PATH_ORG
 
+    export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$ROOT/install/lib/pkgconfig
+
     prepare_version_header || failure
 
     echo "Building Starsphere [ORC]..." | tee -a $LOGFILE
@@ -860,17 +874,16 @@ case $TARGET in
         build_linux || failure
         ;;
     $TARGET_MAC)
-        if [ -d /Developer/SDKs/MacOSX10.4u.sdk ]; then
-            echo "Preparing Mac OS X 10.4 SDK build environment..." | tee -a $LOGFILE
-            # use 10.4 (Tiger) SDK because of BOINC/10.5 incompatibility (http://boinc.berkeley.edu/doxygen/api/html/QBacktrace_8h.html)
-            export LDFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk -Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk -arch i386 $LDFLAGS"
-            export CPPFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 $CPPFLAGS"
-            export CFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 $CFLAGS"
-            export CXXFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 $CXXFLAGS"
-            export SDKROOT="/Developer/SDKs/MacOSX10.4u.sdk"
-            export MACOSX_DEPLOYMENT_TARGET=10.4
+        if [ -d /Users/Shared/Developer/SDKs/MacOSX10.8.sdk ]; then
+            echo "Preparing Mac OS X 10.8 SDK build environment..." | tee -a $LOGFILE
+            export LDFLAGS="-isysroot /Users/Shared/Developer/SDKs/MacOSX10.8.sdk -Wl,-syslibroot,/Users/Shared/Developer/SDKs/MacOSX10.8.sdk -arch x86_64 $LDFLAGS"
+            export CPPFLAGS="-isysroot /Users/Shared/Developer/SDKs/MacOSX10.8.sdk -arch x86_64 $CPPFLAGS"
+            export CFLAGS="-isysroot /Users/Shared/Developer/SDKs/MacOSX10.8.sdk -arch x86_64 $CFLAGS"
+            export CXXFLAGS="-isysroot /Users/Shared/Developer/SDKs/MacOSX10.8.sdk -arch x86_64 $CXXFLAGS"
+            export SDKROOT="/Users/Shared/Developer/SDKs/MacOSX10.8.sdk"
+            export MACOSX_DEPLOYMENT_TARGET=10.8
         else
-            echo "Mac OS X 10.4 SDK required but missing!" | tee -a $LOGFILE
+            echo "Mac OS X 10.8 SDK required but missing (in /Users/Shared/Developer/SDKs)!" | tee -a $LOGFILE
             failure
         fi
         check_prerequisites || failure
diff --git a/src/framework/Makefile b/src/framework/Makefile
index 64c5001714c9a1050aa066083ff747448aac4aee..97f02c8cac5b87c06e2ce5102f2ef1cc6f962765 100644
--- a/src/framework/Makefile
+++ b/src/framework/Makefile
@@ -26,7 +26,8 @@ FRAMEWORK_INSTALL?=$(PWD)
 CXX?=g++
 
 # variables
-CPPFLAGS += $(shell $(FRAMEWORK_INSTALL)/bin/sdl-config --cflags)
+CPPFLAGS += -I$(FRAMEWORK_INSTALL)/include
+CPPFLAGS += $(shell $(FRAMEWORK_INSTALL)/bin/sdl2-config --cflags)
 CPPFLAGS += $(shell $(FRAMEWORK_INSTALL)/bin/freetype-config --cflags)
 CPPFLAGS += $(shell $(FRAMEWORK_INSTALL)/bin/xml2-config --cflags)
 CPPFLAGS += -I$(FRAMEWORK_INSTALL)/include/boinc -I/usr/include
diff --git a/src/framework/Makefile.mingw b/src/framework/Makefile.mingw
index 0ee35cad2f42572f62dce171d4d563d4bc5bcd27..d9bd874a11dcd915217cf010a79bf10a49fe189c 100644
--- a/src/framework/Makefile.mingw
+++ b/src/framework/Makefile.mingw
@@ -27,7 +27,7 @@ CXX?=g++
 TARGET_HOST?=i586-pc-mingw32
 
 # variables
-CPPFLAGS += $(shell $(FRAMEWORK_INSTALL)/bin/sdl-config --cflags)
+CPPFLAGS += $(shell $(FRAMEWORK_INSTALL)/bin/sdl2-config --cflags)
 CPPFLAGS += $(shell $(FRAMEWORK_INSTALL)/bin/freetype-config --cflags)
 CPPFLAGS += $(shell $(FRAMEWORK_INSTALL)/bin/xml2-config --cflags)
 CPPFLAGS += -I$(FRAMEWORK_INSTALL)/include/boinc -I$(FRAMEWORK_INSTALL)/include
diff --git a/src/framework/WindowManager.cpp b/src/framework/WindowManager.cpp
index 537a4edd96eea919a83ee85ea858044efaf35b86..3e8d08eb661bd7c4bd612acf2986b16fb5a4c3f8 100644
--- a/src/framework/WindowManager.cpp
+++ b/src/framework/WindowManager.cpp
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Oliver Bock                                     *
+ *   Copyright (C) 2008-2020 by Oliver Bock                                     *
  *   oliver.bock[AT]aei.mpg.de                                             *
  *                                                                         *
  *   This file is part of Einstein@Home.                                   *
@@ -40,19 +40,12 @@ bool WindowManager::initialize(const int width, const int height, const int fram
 
 	atexit(SDL_Quit);
 
-	// retrieve current video settings
-	const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo();
-
-	if (videoInfo->current_w != 0) {
-		m_DesktopWidth = videoInfo->current_w;
-	}
-
-	if (videoInfo->current_h != 0) {
-		m_DesktopHeight = videoInfo->current_h;
-	}
-
-	if (videoInfo->vfmt->BitsPerPixel != 0) {
-		m_DesktopBitsPerPixel = videoInfo->vfmt->BitsPerPixel;
+	// retrieve current video settings (of the primary display)
+	SDL_DisplayMode mode;
+	if (!SDL_GetDesktopDisplayMode(0, &mode)) {
+		m_DesktopWidth = mode.w;
+		m_DesktopHeight = mode.h;
+		m_DesktopBitsPerPixel = SDL_BITSPERPIXEL(mode.format);
 	}
 
 	// get initial non-fullscreen resolution and frame rate from project preferences
@@ -80,51 +73,45 @@ bool WindowManager::initialize(const int width, const int height, const int fram
 	 */
 
 	// set common video flags
-	// (for OpenGL nothing more than SDL_OPENGL and SDL_FULLSCREEN should be used)
-	m_VideoModeFlags = SDL_OPENGL;
+	m_VideoModeFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
+	// enable HDPI (retina) support
+	// m_VideoModeFlags |= SDL_WINDOW_ALLOW_HIGHDPI;
 
 	// check fullscreen video mode
 	m_FullscreenModeAvailable = true;
-	Uint32 bitPerPixel = SDL_VideoModeOK(
-							m_DesktopWidth,
-							m_DesktopHeight,
-							m_DesktopBitsPerPixel,
-							m_VideoModeFlags | SDL_FULLSCREEN);
-
-	if(!bitPerPixel) {
-		cerr << "Fullscreen video mode not supported: " << SDL_GetError() << endl;
-		m_FullscreenModeAvailable = false;
-	}
-
+	// Uint32 bitPerPixel = SDL_VideoModeOK(
+	// 						m_DesktopWidth,
+	// 						m_DesktopHeight,
+	// 						m_DesktopBitsPerPixel,
+	// 						m_VideoModeFlags | SDL_WINDOW_FULLSCREEN);
+	//
+	// if(!bitPerPixel) {
+	// 	cerr << "Fullscreen video mode not supported: " << SDL_GetError() << endl;
+	// 	m_FullscreenModeAvailable = false;
+	// }
+	//
 	// check initial windowed video mode
 	m_WindowedModeAvailable = true;
-	bitPerPixel = SDL_VideoModeOK(
-							m_WindowedWidth,
-							m_WindowedHeight,
-							m_DesktopBitsPerPixel,
-							m_VideoModeFlags | SDL_RESIZABLE);
-
-	if(!bitPerPixel) {
-		cerr << "Windowed video mode not supported: " << SDL_GetError() << endl;
-		m_WindowedModeAvailable = false;
-	}
-
-	// both checks failed
-	if(!(m_FullscreenModeAvailable || m_WindowedModeAvailable)) {
-		cerr << "No suitable video mode available!"<< endl;
-		return false;
-	}
+	// bitPerPixel = SDL_VideoModeOK(
+	// 						m_WindowedWidth,
+	// 						m_WindowedHeight,
+	// 						m_DesktopBitsPerPixel,
+	// 						m_VideoModeFlags | SDL_WINDOW_RESIZABLE);
+	//
+	// if(!bitPerPixel) {
+	// 	cerr << "Windowed video mode not supported: " << SDL_GetError() << endl;
+	// 	m_WindowedModeAvailable = false;
+	// }
+	//
+	// // both checks failed
+	// if(!(m_FullscreenModeAvailable || m_WindowedModeAvailable)) {
+	// 	cerr << "No suitable video mode available!"<< endl;
+	// 	return false;
+	// }
 
 	// minimum requirements
-	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 1);
-	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 1);
-	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 1);
 	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-	SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
-
-	// desired requirement for high quality mode
-	//FIXME: commented out right now as it interferes with the FSAA attributes below!)
-//	SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
+	SDL_GL_SetSwapInterval(1);
 
 	if(m_BoincAdapter->graphicsQualitySetting() == BOINCClientAdapter::HighGraphicsQualitySetting) {
 		// enable opt-in quality feature FSAA (4x)
@@ -132,26 +119,29 @@ bool WindowManager::initialize(const int width, const int height, const int fram
 		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
 	}
 
-	// unused requirements
-	//SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
-	//SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
-	//SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
-
 	// we always start in windowed mode (starting in fullscreen fails with high CPU load!)
 	m_CurrentWidth = m_WindowedWidth;
 	m_CurrentHeight = m_WindowedHeight;
-	m_VideoModeFlags |= SDL_RESIZABLE;
 
-	// finally, get surface
-	m_DisplaySurface = SDL_SetVideoMode(
-							m_CurrentWidth,
-							m_CurrentHeight,
-							m_DesktopBitsPerPixel,
-							m_VideoModeFlags);
+	// create window
+	m_Window = SDL_CreateWindow(
+			"Einstein@Home",
+			SDL_WINDOWPOS_CENTERED,
+			SDL_WINDOWPOS_CENTERED,
+			m_CurrentWidth,
+			m_CurrentHeight,
+			m_VideoModeFlags);
 
-	if (m_DisplaySurface == NULL) {
+	if (m_Window == NULL) {
 		cerr << "Could not acquire rendering surface (" << SDL_GetError() << "): will try fallback..." << endl;
 	}
+	else {
+		// create OpenGL context
+		m_GLContext = SDL_GL_CreateContext(m_Window);
+		if (m_GLContext == NULL) {
+			cerr << "Could not acquire OpenGL context (" << SDL_GetError() << "): will try fallback..." << endl;
+		}
+	}
 
 	// check if we got acceleration
 	int accelerated = 0;
@@ -159,28 +149,39 @@ bool WindowManager::initialize(const int width, const int height, const int fram
 		cerr << "Could not ensure accelerated rendering surface. Assuming no acceleration..." << endl;
 	}
 
-	if (m_DisplaySurface == NULL || !accelerated) {
+	// handle fallback
+	if (m_Window == NULL || m_GLContext == NULL || !accelerated) {
 		cerr << "Disabling high quality features..." << endl;
 
 		// disable features that demand acceleration
-//		SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 0);
 		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
 		SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
 
 		// TODO: we should override m_BoincAdapter->graphicsQualitySetting() to medium or low!
 		// note, requires to extend starsphere's constructor (uses its own BOINCClientAdapter!)
 
-		// reset display surface
-		m_DisplaySurface = SDL_SetVideoMode(
-								m_CurrentWidth,
-								m_CurrentHeight,
-								m_DesktopBitsPerPixel,
-								m_VideoModeFlags);
-
-		if (m_DisplaySurface == NULL) {
-			cerr << "Could not acquire rendering surface (" << SDL_GetError() << "): giving up!" << endl;
+		// reset window
+		if (m_Window) SDL_DestroyWindow(m_Window);
+		m_Window = SDL_CreateWindow(
+				"Einstein@Home",
+				SDL_WINDOWPOS_CENTERED,
+				SDL_WINDOWPOS_CENTERED,
+				m_CurrentWidth,
+				m_CurrentHeight,
+				m_VideoModeFlags);
+
+		if (m_Window == NULL) {
+			cerr << "Could not acquire window (" << SDL_GetError() << "): giving up!" << endl;
 			return false;
 		}
+		else {
+			// create OpenGL context
+			m_GLContext = SDL_GL_CreateContext(m_Window);
+			if (m_GLContext == NULL) {
+				cerr << "Could not acquire OpenGL context (" << SDL_GetError() << "): giving up!" << endl;
+				SDL_DestroyWindow(m_Window);
+			}
+		}
 	}
 
 	return true;
@@ -200,18 +201,16 @@ void WindowManager::eventLoop()
 	//SDL_EventState(SDL_KEYDOWN, SDL_IGNORE);
 	//SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
 	//SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_IGNORE);
-	//SDL_EventState(SDL_VIDEORESIZE, SDL_IGNORE);
+	//SDL_EventState(SDL_WINDOWEVENT_SIZE_CHANGED, SDL_IGNORE);
 	//SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
 
 	// events we ignore
-	SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
 	SDL_EventState(SDL_KEYUP, SDL_IGNORE);
 	SDL_EventState(SDL_JOYAXISMOTION, SDL_IGNORE);
 	SDL_EventState(SDL_JOYBALLMOTION, SDL_IGNORE);
 	SDL_EventState(SDL_JOYHATMOTION, SDL_IGNORE);
 	SDL_EventState(SDL_JOYBUTTONDOWN, SDL_IGNORE);
 	SDL_EventState(SDL_JOYBUTTONUP, SDL_IGNORE);
-	SDL_EventState(SDL_VIDEOEXPOSE, SDL_IGNORE);
 	SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
 
 	SDL_Event event;
@@ -228,10 +227,15 @@ void WindowManager::eventLoop()
 #endif
 				// notify our observers (currently exactly one, hence front())
 				eventObservers.front()->render(dtime());
+				SDL_GL_SwapWindow(m_Window);
+
 #ifdef DEBUG_VALGRIND
 			}
 			else {
-				if (m_DisplaySurface) SDL_FreeSurface(m_DisplaySurface);
+				if (m_Window) {
+					SDL_GL_DeleteContext(m_GLContext);
+					SDL_DestroyWindow(m_Window);
+				}
 				break;
 			}
 #endif
@@ -247,6 +251,8 @@ void WindowManager::eventLoop()
 				 event.type == SDL_KEYDOWN)) {
 
 			// we're in screensaver mode so exit on user input
+			SDL_GL_DeleteContext(m_GLContext);
+			SDL_DestroyWindow(m_Window);
 			SDL_Quit();
 		}
 		else if (event.motion.state & (SDL_BUTTON(1) | SDL_BUTTON(3)) &&
@@ -267,16 +273,9 @@ void WindowManager::eventLoop()
 										AbstractGraphicsEngine::MouseButtonRight);
 			}
 		}
-		else if (event.type == SDL_VIDEORESIZE) {
-			m_CurrentWidth = m_WindowedWidth = event.resize.w;
-			m_CurrentHeight = m_WindowedHeight = event.resize.h;
-
-			// update video mode
-			m_DisplaySurface = SDL_SetVideoMode(
-									m_CurrentWidth,
-									m_CurrentHeight,
-									m_DesktopBitsPerPixel,
-									m_VideoModeFlags);
+		else if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
+			m_CurrentWidth = m_WindowedWidth = event.window.data1;
+			m_CurrentHeight = m_WindowedHeight = event.window.data2;
 
 			// notify our observers (currently exactly one, hence front())
 			// (windoze needs to be reinitialized instead of just resized, oh well)
@@ -286,7 +285,8 @@ void WindowManager::eventLoop()
 		else if (event.type == SDL_QUIT ||
 				(event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE)) {
 
-			// just exit (SDL_FreeSurface is called automatically)
+			SDL_GL_DeleteContext(m_GLContext);
+			SDL_DestroyWindow(m_Window);
 			SDL_Quit();
 
 			break;
@@ -396,13 +396,13 @@ int WindowManager::windowHeight() const
 
 void WindowManager::setWindowCaption(const string caption) const
 {
-	SDL_WM_SetCaption(caption.c_str(), NULL);
+	SDL_SetWindowTitle(m_Window, caption.c_str());
 }
 
 void WindowManager::setWindowIcon(const string filename) const
 {
 	if (filename.length() > 0) {
-		SDL_WM_SetIcon(SDL_LoadBMP(filename.c_str()), NULL);
+		SDL_SetWindowIcon(m_Window, SDL_LoadBMP(filename.c_str()));
 	}
 }
 
@@ -417,7 +417,7 @@ void WindowManager::setWindowIcon(const unsigned char *data, const int size) con
 
 		if(surface != NULL) {
 			// set window icon
-			SDL_WM_SetIcon(surface, NULL);
+			SDL_SetWindowIcon(m_Window, surface);
 			SDL_FreeSurface(surface);
 		}
 		else {
@@ -431,47 +431,27 @@ void WindowManager::setWindowIcon(const unsigned char *data, const int size) con
 
 void WindowManager::toggleFullscreen()
 {
-	// toggle fullscreen bit and reset video mode
-	if(m_WindowedModeAvailable && (m_VideoModeFlags & SDL_FULLSCREEN)) {
-		// set new dimensions
-		m_CurrentWidth = m_WindowedWidth;
-		m_CurrentHeight = m_WindowedHeight;
-
-		// (un)set video mode flags
-		m_VideoModeFlags &= ~SDL_FULLSCREEN;
-		m_VideoModeFlags |= SDL_RESIZABLE;
+	if(m_WindowedModeAvailable && (m_VideoModeFlags & SDL_WINDOW_FULLSCREEN)) {
+		// restore windowed mode
+		SDL_SetWindowFullscreen(m_Window, 0);
 
-		// show cursor in fullscreen mode
+		// show cursor
 		SDL_ShowCursor(SDL_ENABLE);
+
+		// store state
+		m_VideoModeFlags &= ~SDL_WINDOW_FULLSCREEN;
 	}
-	else if(m_FullscreenModeAvailable && !(m_VideoModeFlags & SDL_FULLSCREEN)) {
-		// set new dimensions
-		m_CurrentWidth = m_DesktopWidth;
-		m_CurrentHeight = m_DesktopHeight;
-
-		// (un)set video mode flags
-#ifdef __APPLE__
-        if (m_ScreensaverMode) {
-            m_CurrentWidth = m_DesktopWidth;
-            m_CurrentHeight = m_DesktopHeight;
-            m_VideoModeFlags |= SDL_NOFRAME;
-        } else
-#endif
-        {
-            m_VideoModeFlags |= SDL_FULLSCREEN;
-        }
-		m_VideoModeFlags &= ~SDL_RESIZABLE;
+	else if(m_FullscreenModeAvailable && !(m_VideoModeFlags & SDL_WINDOW_FULLSCREEN)) {
+		// enable fullscreen mode
+		// (not using real SDL_WINDOW_FULLSCREEN which triggers a SDL_MOUSEMOTION event)
+		SDL_SetWindowFullscreen(m_Window, SDL_WINDOW_FULLSCREEN_DESKTOP);
 
 		// hide cursor
 		SDL_ShowCursor(SDL_DISABLE);
-	}
 
-	// reset video mode
-	m_DisplaySurface = SDL_SetVideoMode(
-							m_CurrentWidth,
-							m_CurrentHeight,
-							m_DesktopBitsPerPixel,
-							m_VideoModeFlags);
+		// store state
+		m_VideoModeFlags |= SDL_WINDOW_FULLSCREEN;
+	}
 
 	// notify our observers (currently exactly one, hence front())
 	// (windoze needs to be reinitialized instead of just resized, oh well)
diff --git a/src/framework/WindowManager.h b/src/framework/WindowManager.h
index 850effefd563981fe8dd012175f041e99c0df593..d598dafeed6186e22b2c60d4ee37bdfc7d6f9c32 100644
--- a/src/framework/WindowManager.h
+++ b/src/framework/WindowManager.h
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Oliver Bock                                     *
+ *   Copyright (C) 2008-2020 by Oliver Bock                                     *
  *   oliver.bock[AT]aei.mpg.de                                             *
  *                                                                         *
  *   This file is part of Einstein@Home.                                   *
@@ -258,8 +258,11 @@ private:
     /// Indicator for desired window mode availability (resolution, color depth, features)
     bool m_WindowedModeAvailable;
 
-    /// The SDL display surface handle
-    SDL_Surface *m_DisplaySurface;
+    /// The SDL window handle
+    SDL_Window *m_Window;
+
+    /// The SDL OpenGL context handle
+    SDL_GLContext m_GLContext;
 
     /// The screensaver mode indicator
     bool m_ScreensaverMode;
diff --git a/src/starsphere/Makefile b/src/starsphere/Makefile
index 4ae58e0ed5b7a7e1dfff9a324528f6fbbbcc3ab5..535600dc7cdf0cc31a04b13ced03240b8d554937 100644
--- a/src/starsphere/Makefile
+++ b/src/starsphere/Makefile
@@ -32,14 +32,14 @@ LIBS += $(shell $(STARSPHERE_INSTALL)/bin/xml2-config --libs)
 LIBS += -lboinc_api -lboinc
 LIBS += -lstdc++
 LIBS += -L/usr/lib
-LIBS += -Wl,-Bdynamic $(shell $(STARSPHERE_INSTALL)/bin/sdl-config --static-libs)
+LIBS += -Wl,-Bdynamic $(shell $(STARSPHERE_INSTALL)/bin/sdl2-config --static-libs)
 LIBS += -lGL -lGLU
 LIBS += -lpthread -lm -lc
 
 LDFLAGS += -static-libgcc
 
 CPPFLAGS += -I$(STARSPHERE_INSTALL)/include
-CPPFLAGS += $(shell $(STARSPHERE_INSTALL)/bin/sdl-config --cflags)
+CPPFLAGS += $(shell $(STARSPHERE_INSTALL)/bin/sdl2-config --cflags)
 CPPFLAGS += $(shell $(STARSPHERE_INSTALL)/bin/freetype-config --cflags)
 CPPFLAGS += $(shell $(STARSPHERE_INSTALL)/bin/xml2-config --cflags)
 CPPFLAGS += -I$(STARSPHERE_INSTALL)/include/boinc -I/usr/include
@@ -69,10 +69,10 @@ callgrind: CPPFLAGS += $(DEBUGFLAGSCPP) -D DEBUG_VALGRIND
 
 # file based targets
 starsphere_Einstein_LVC: $(DEPS) $(STARSPHERE_SRC)/main.cpp $(OBJS)
-	$(CXX) -g $(CPPFLAGS) $(LDFLAGS) $(STARSPHERE_SRC)/main.cpp -o "graphics_app=einstein_RUNLABEL_VERSION_graphics_i686-pc-linux-gnu" $(OBJS) $(LIBS)
+	$(CXX) -g $(CPPFLAGS) $(LDFLAGS) $(STARSPHERE_SRC)/main.cpp -o "graphics_app=einstein_RUNLABEL_VERSION_graphics_x86_64-pc-linux-gnu" $(OBJS) $(LIBS)
 
 starsphere_Einstein_ABP: $(DEPS) $(STARSPHERE_SRC)/main.cpp $(OBJS)
-	$(CXX) -g $(CPPFLAGS) $(LDFLAGS) $(STARSPHERE_SRC)/main.cpp -o "graphics_app=einsteinbinary_RUNLABEL_VERSION_graphics_i686-pc-linux-gnu" $(OBJS) $(LIBS)
+	$(CXX) -g $(CPPFLAGS) $(LDFLAGS) $(STARSPHERE_SRC)/main.cpp -o "graphics_app=einsteinbinary_RUNLABEL_VERSION_graphics_x86_64-pc-linux-gnu" $(OBJS) $(LIBS)
 
 Starsphere.o: $(DEPS) $(STARSPHERE_SRC)/Starsphere.cpp $(STARSPHERE_SRC)/Starsphere.h
 	$(CXX) -g $(CPPFLAGS) -c $(STARSPHERE_SRC)/Starsphere.cpp
diff --git a/src/starsphere/Makefile.macos b/src/starsphere/Makefile.macos
index 3c4c9f359a399997d5c1fffbeb1647a456b288aa..9bfb2a32f8ff3b2ea38c31591ef7304c13f42f92 100644
--- a/src/starsphere/Makefile.macos
+++ b/src/starsphere/Makefile.macos
@@ -30,14 +30,12 @@ LIBS += -lframework -loglft -L$(STARSPHERE_INSTALL)/lib
 LIBS += $(shell $(STARSPHERE_INSTALL)/bin/freetype-config --libs)
 LIBS += $(shell $(STARSPHERE_INSTALL)/bin/xml2-config --libs)
 LIBS += -lboinc_graphics2 -lboinc_api -lboinc -L$(STARSPHERE_INSTALL)/lib
-LIBS += $(shell $(STARSPHERE_INSTALL)/bin/sdl-config --static-libs)
-LIBS += -lstdc++
+LIBS += $(shell $(STARSPHERE_INSTALL)/bin/sdl2-config --static-libs)
+LIBS += -Wl,-framework,OpenGL
 LIBS += -lpthread -lm -lc
 
-LDFLAGS += -static-libgcc
-
 CPPFLAGS += -I$(STARSPHERE_INSTALL)/include
-CPPFLAGS += $(shell $(STARSPHERE_INSTALL)/bin/sdl-config --cflags)
+CPPFLAGS += $(shell $(STARSPHERE_INSTALL)/bin/sdl2-config --cflags)
 CPPFLAGS += $(shell $(STARSPHERE_INSTALL)/bin/freetype-config --cflags)
 CPPFLAGS += $(shell $(STARSPHERE_INSTALL)/bin/xml2-config --cflags)
 CPPFLAGS += -I$(STARSPHERE_INSTALL)/include/boinc -I/usr/include
@@ -68,14 +66,14 @@ callgrind: CPPFLAGS += $(DEBUGFLAGSCPP) -D DEBUG_VALGRIND
 
 # file based targets
 starsphere_Einstein_LVC: $(DEPS) $(STARSPHERE_SRC)/main.cpp $(STARSPHERE_SRC)/EaHMacIcon.h $(OBJS)
-	$(CXX) -g $(CPPFLAGS) $(LDFLAGS) $(STARSPHERE_SRC)/main.cpp -o "graphics_app=einstein_RUNLABEL_VERSION_graphics_i686-apple-darwin" $(OBJS) $(LIBS)
+	$(CXX) -g $(CPPFLAGS) $(LDFLAGS) $(STARSPHERE_SRC)/main.cpp -o "graphics_app=einstein_RUNLABEL_VERSION_graphics_x86_64-apple-darwin" $(OBJS) $(LIBS)
 
 starsphere_Einstein_ABP: $(DEPS) $(STARSPHERE_SRC)/main.cpp $(STARSPHERE_SRC)/EaHMacIcon.h $(OBJS)
-	$(CXX) -g $(CPPFLAGS) $(LDFLAGS) $(STARSPHERE_SRC)/main.cpp -o "graphics_app=einsteinbinary_RUNLABEL_VERSION_graphics_i686-apple-darwin" $(OBJS) $(LIBS)
+	$(CXX) -g $(CPPFLAGS) $(LDFLAGS) $(STARSPHERE_SRC)/main.cpp -o "graphics_app=einsteinbinary_RUNLABEL_VERSION_graphics_x86_64-apple-darwin" $(OBJS) $(LIBS)
 
 Starsphere.o: $(DEPS) $(STARSPHERE_SRC)/Starsphere.cpp $(STARSPHERE_SRC)/Starsphere.h
 	$(CXX) -g $(CPPFLAGS) -c $(STARSPHERE_SRC)/Starsphere.cpp
-	
+
 StarsphereS5R3.o: $(DEPS) $(STARSPHERE_SRC)/StarsphereS5R3.cpp $(STARSPHERE_SRC)/StarsphereS5R3.h
 	$(CXX) -g $(CPPFLAGS) -c $(STARSPHERE_SRC)/StarsphereS5R3.cpp
 
@@ -96,7 +94,7 @@ snr_list.o: $(DEPS) $(STARSPHERE_SRC)/snr_list.C
 
 pulsar_list.o: $(DEPS) $(STARSPHERE_SRC)/pulsar_list.C
 	$(CXX) -g $(CPPFLAGS) -c $(STARSPHERE_SRC)/pulsar_list.C
-    
+
 SetMacSSLevel.o: $(DEPS) $(STARSPHERE_SRC)/SetMacSSLevel.m
 	$(CXX) -g $(CPPFLAGS) -c $(STARSPHERE_SRC)/SetMacSSLevel.m
 
@@ -108,7 +106,7 @@ $(RESOURCESPEC).o: $(STARSPHERE_SRC)/$(RESOURCESPEC).orc
 
 install:
 	mkdir -p $(STARSPHERE_INSTALL)/../dist
-	cp graphics_app* $(STARSPHERE_INSTALL)/../dist
+	cp graphics_app*darwin $(STARSPHERE_INSTALL)/../dist
 
 clean:
 	rm -rf $(RESOURCESPEC).cpp $(OBJS) graphics_app*
diff --git a/src/starsphere/Makefile.mingw b/src/starsphere/Makefile.mingw
index f705df7334e0473332981c9a8b1080d786dd0bbe..05842e8c52bc6081886ab51cdcecdd3c7b9e717d 100644
--- a/src/starsphere/Makefile.mingw
+++ b/src/starsphere/Makefile.mingw
@@ -34,13 +34,13 @@ LIBS += $(shell $(STARSPHERE_INSTALL)/bin/xml2-config --libs)
 LIBS += -lws2_32 # required by libxml2
 LIBS += -lboinc_graphics2 -lboinc_api -lboinc
 LIBS += -Wl,-Bdynamic
-LIBS += $(shell $(STARSPHERE_INSTALL)/bin/sdl-config --static-libs)
+LIBS += $(shell $(STARSPHERE_INSTALL)/bin/sdl2-config --static-libs)
 LIBS += -lopengl32 -lglu32
 
 LDFLAGS += -static-libgcc
 
 CPPFLAGS += -I$(STARSPHERE_INSTALL)/include
-CPPFLAGS += $(shell $(STARSPHERE_INSTALL)/bin/sdl-config --cflags)
+CPPFLAGS += $(shell $(STARSPHERE_INSTALL)/bin/sdl2-config --cflags)
 CPPFLAGS += $(shell $(STARSPHERE_INSTALL)/bin/freetype-config --cflags)
 CPPFLAGS += $(shell $(STARSPHERE_INSTALL)/bin/xml2-config --cflags)
 CPPFLAGS += -I$(STARSPHERE_INSTALL)/include/boinc
@@ -78,7 +78,7 @@ starsphere_Einstein_ABP: $(DEPS) $(STARSPHERE_SRC)/main.cpp $(OBJS)
 
 Starsphere.o: $(DEPS) $(STARSPHERE_SRC)/Starsphere.cpp $(STARSPHERE_SRC)/Starsphere.h
 	$(CXX) -g $(CPPFLAGS) -c $(STARSPHERE_SRC)/Starsphere.cpp
-	
+
 StarsphereS5R3.o: $(DEPS) $(STARSPHERE_SRC)/StarsphereS5R3.cpp $(STARSPHERE_SRC)/StarsphereS5R3.h
 	$(CXX) -g $(CPPFLAGS) -c $(STARSPHERE_SRC)/StarsphereS5R3.cpp
 
diff --git a/src/starsphere/Starsphere.cpp b/src/starsphere/Starsphere.cpp
index 8a93220f08b6807b7e23ce91c3e856602f696bb0..a7ecf9a36a12de4f28b941135dc883e33ff0cd74 100644
--- a/src/starsphere/Starsphere.cpp
+++ b/src/starsphere/Starsphere.cpp
@@ -864,8 +864,6 @@ void Starsphere::render(const double timeOfDay)
 		// enable depth testing since we're leaving 2D mode
 		glEnable(GL_DEPTH_TEST);
 	}
-
-	SDL_GL_SwapBuffers();
 }
 
 void Starsphere::renderAdditionalObservatories() {