diff --git a/3d-viewer/3d_model_viewer/eda_3d_model_viewer.cpp b/3d-viewer/3d_model_viewer/eda_3d_model_viewer.cpp
index b6501abc1a..1fce95d2e2 100644
--- a/3d-viewer/3d_model_viewer/eda_3d_model_viewer.cpp
+++ b/3d-viewer/3d_model_viewer/eda_3d_model_viewer.cpp
@@ -38,7 +38,7 @@
 #include <gal/opengl/gl_context_mgr.h>
 #include <settings/common_settings.h>
 #include <pgm_base.h>
-#include <gal/dpi_scaling.h>
+#include <dpi_scaling_common.h>
 #include <class_draw_panel_gal.h>
 #include <macros.h>
 
@@ -105,7 +105,7 @@ EDA_3D_MODEL_VIEWER::EDA_3D_MODEL_VIEWER( wxWindow* aParent, const int* aAttribL
 
     COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
 
-    const DPI_SCALING dpi{ settings, this };
+    const DPI_SCALING_COMMON dpi{ settings, this };
     SetScaleFactor( dpi.GetScaleFactor() );
 }
 
diff --git a/3d-viewer/3d_viewer/eda_3d_viewer_frame.cpp b/3d-viewer/3d_viewer/eda_3d_viewer_frame.cpp
index 04f72a1a84..cba5c70fe1 100644
--- a/3d-viewer/3d_viewer/eda_3d_viewer_frame.cpp
+++ b/3d-viewer/3d_viewer/eda_3d_viewer_frame.cpp
@@ -42,7 +42,7 @@
 #include <bitmaps.h>
 #include <board_design_settings.h>
 #include <core/arraydim.h>
-#include <gal/dpi_scaling.h>
+#include <dpi_scaling_common.h>
 #include <pgm_base.h>
 #include <project.h>
 #include <project/project_file.h>
@@ -810,7 +810,7 @@ void EDA_3D_VIEWER_FRAME::loadCommonSettings()
 
     COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
 
-    const DPI_SCALING dpi{ settings, this };
+    const DPI_SCALING_COMMON dpi{ settings, this };
     m_canvas->SetScaleFactor( dpi.GetScaleFactor() );
 
     // TODO(JE) use all control options
diff --git a/3d-viewer/dialogs/appearance_controls_3D.cpp b/3d-viewer/dialogs/appearance_controls_3D.cpp
index 5bb8501edb..fe79ca36cb 100644
--- a/3d-viewer/dialogs/appearance_controls_3D.cpp
+++ b/3d-viewer/dialogs/appearance_controls_3D.cpp
@@ -22,6 +22,7 @@
 
 #include <bitmaps.h>
 #include <pgm_base.h>
+#include <dpi_scaling_common.h>
 #include <eda_list_dialog.h>
 #include <pcb_display_options.h>
 #include <eda_3d_viewer_frame.h>
@@ -88,7 +89,7 @@ APPEARANCE_CONTROLS_3D::APPEARANCE_CONTROLS_3D( EDA_3D_VIEWER_FRAME* aParent,
         m_focusOwner( aFocusOwner ),
         m_lastSelectedViewport( nullptr )
 {
-    DPI_SCALING dpi( nullptr, m_frame );
+    DPI_SCALING_COMMON dpi( nullptr, m_frame );
 
     int indicatorSize = ConvertDialogToPixels( wxSize( 6, 6 ) ).x / dpi.GetContentScaleFactor();
     int screenHeight  = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y );
@@ -142,7 +143,7 @@ APPEARANCE_CONTROLS_3D::~APPEARANCE_CONTROLS_3D()
 
 wxSize APPEARANCE_CONTROLS_3D::GetBestSize() const
 {
-    DPI_SCALING dpi( nullptr, m_frame );
+    DPI_SCALING_COMMON dpi( nullptr, m_frame );
     wxSize      size( 220 * dpi.GetScaleFactor(), 480 * dpi.GetScaleFactor() );
     return size;
 }
diff --git a/3d-viewer/dialogs/panel_preview_3d_model.cpp b/3d-viewer/dialogs/panel_preview_3d_model.cpp
index 0938da4a5e..ee29468392 100644
--- a/3d-viewer/dialogs/panel_preview_3d_model.cpp
+++ b/3d-viewer/dialogs/panel_preview_3d_model.cpp
@@ -35,7 +35,7 @@
 #include <bitmaps.h>
 #include <board.h>
 #include <common_ogl/ogl_attr_list.h>
-#include <gal/dpi_scaling.h>
+#include <dpi_scaling_common.h>
 #include <pgm_base.h>
 #include <settings/common_settings.h>
 #include <settings/settings_manager.h>
@@ -210,7 +210,7 @@ void PANEL_PREVIEW_3D_MODEL::loadSettings()
 
     COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
 
-    const DPI_SCALING dpi{ settings, this };
+    const DPI_SCALING_COMMON dpi{ settings, this };
     m_previewPane->SetScaleFactor( dpi.GetScaleFactor() );
 
     // TODO(JE) use all control options
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index 647cb2ef52..d889c89a39 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -414,7 +414,9 @@ set( COMMON_SRCS
     config_params.cpp
     confirm.cpp
     dialog_shim.cpp
+    dpi_scaling_common.cpp
     draw_panel_gal.cpp
+    gal_display_options_common.cpp
     gr_text.cpp
     dsnlexer.cpp
     eda_base_frame.cpp
@@ -482,6 +484,7 @@ set( COMMON_SRCS
     wildcards_and_files_ext.cpp
     drawing_sheet/ds_painter.cpp
     xnode.cpp
+    view/wx_view_controls.cpp
     )
 
 if( TRUE OR NOT USE_KIWAY_DLLS )
diff --git a/common/dialogs/panel_common_settings.cpp b/common/dialogs/panel_common_settings.cpp
index 1adf9b523f..e4f2ccfd80 100644
--- a/common/dialogs/panel_common_settings.cpp
+++ b/common/dialogs/panel_common_settings.cpp
@@ -26,7 +26,7 @@
 #include <advanced_config.h>
 #include <bitmaps.h>
 #include <dialog_shim.h>
-#include <gal/dpi_scaling.h>
+#include <dpi_scaling_common.h>
 #include <kiface_base.h>
 #include <kiplatform/ui.h>
 #include <pgm_base.h>
@@ -270,7 +270,7 @@ bool PANEL_COMMON_SETTINGS::TransferDataFromWindow()
 
     if( m_canvasScaleCtrl )
     {
-        DPI_SCALING dpi( commonSettings, this );
+        DPI_SCALING_COMMON dpi( commonSettings, this );
         dpi.SetDpiConfig( m_canvasScaleAuto->GetValue(), m_canvasScaleCtrl->GetValue() );
     }
 
@@ -366,7 +366,7 @@ void PANEL_COMMON_SETTINGS::applySettingsToPanel( COMMON_SETTINGS& aSettings )
 
     if( m_canvasScaleCtrl )
     {
-        const DPI_SCALING dpi( &aSettings, this );
+        const DPI_SCALING_COMMON dpi( &aSettings, this );
         m_canvasScaleCtrl->SetValue( dpi.GetScaleFactor() );
         m_canvasScaleAuto->SetValue( dpi.GetCanvasIsAutoScaled() );
     }
@@ -440,7 +440,7 @@ void PANEL_COMMON_SETTINGS::OnCanvasScaleAuto( wxCommandEvent& aEvent )
     if( automatic && m_canvasScaleCtrl )
     {
         // set the scale to the auto value, without consulting the config
-        DPI_SCALING dpi( nullptr, this );
+        DPI_SCALING_COMMON dpi( nullptr, this );
 
         // update the field (no events sent)
         m_canvasScaleCtrl->SetValue( dpi.GetScaleFactor() );
diff --git a/common/dialogs/panel_data_collection.cpp b/common/dialogs/panel_data_collection.cpp
index 5e6ace5250..af51e5bd5f 100644
--- a/common/dialogs/panel_data_collection.cpp
+++ b/common/dialogs/panel_data_collection.cpp
@@ -26,7 +26,6 @@
 #include <advanced_config.h>
 #include <bitmaps.h>
 #include <dialog_shim.h>
-#include <gal/dpi_scaling.h>
 #include <kiface_base.h>
 #include <kiplatform/policy.h>
 #include <kiplatform/ui.h>
diff --git a/common/dpi_scaling_common.cpp b/common/dpi_scaling_common.cpp
new file mode 100644
index 0000000000..b8bb25d641
--- /dev/null
+++ b/common/dpi_scaling_common.cpp
@@ -0,0 +1,191 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2019 KiCad Developers, see AUTHORS.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#include <dpi_scaling_common.h>
+
+#include <optional>
+
+#include <env_vars.h>
+#include <settings/common_settings.h>
+#include <kiplatform/ui.h>
+
+#include <wx/log.h>
+#include <wx/window.h>
+
+
+/**
+ * Flag to enable trace for HiDPI scaling factors
+ *
+ * Use "KICAD_TRACE_HIGH_DPI" to enable.
+ *
+ * @ingroup trace_env_vars
+ */
+const wxChar* const traceHiDpi = wxT( "KICAD_TRACE_HIGH_DPI" );
+
+
+/**
+ * Get a user-configured scale factor from KiCad config file
+ *
+ * @return the scale factor, if set
+ */
+static std::optional<double> getKiCadConfiguredScale( const COMMON_SETTINGS& aConfig )
+{
+    std::optional<double> scale;
+    double      canvas_scale = aConfig.m_Appearance.canvas_scale;
+
+    if( canvas_scale > 0.0 )
+    {
+        scale = canvas_scale;
+    }
+
+    return scale;
+}
+
+
+/**
+ * Get the toolkit scale factor from a user-set environment variable
+ * (for example GDK_SCALE on GTK).
+ *
+ * @return the scale factor, if set
+ */
+static std::optional<double> getEnvironmentScale()
+{
+    const wxPortId port_id = wxPlatformInfo::Get().GetPortId();
+    std::optional<double>    scale;
+
+    if( port_id == wxPORT_GTK )
+    {
+        // Under GTK, the user can use GDK_SCALE to force the scaling
+        scale = ENV_VAR::GetEnvVar<double>( wxS( "GDK_SCALE" ) );
+    }
+
+    return scale;
+}
+
+
+DPI_SCALING_COMMON::DPI_SCALING_COMMON( COMMON_SETTINGS* aConfig, const wxWindow* aWindow )
+        : m_config( aConfig ), m_window( aWindow )
+{
+}
+
+
+double DPI_SCALING_COMMON::GetScaleFactor() const
+{
+    std::optional<double> val;
+    wxString              src;
+
+    if( m_config )
+    {
+        val = getKiCadConfiguredScale( *m_config );
+        src = wxS( "config" );
+    }
+
+    if( !val )
+    {
+        val = getEnvironmentScale();
+        src = wxS( "env" );
+    }
+
+    if( !val && m_window )
+    {
+        // Use the native WX reporting.
+        // On Linux, this will not work until WX 3.2 and GTK >= 3.10
+        // Otherwise it returns 1.0
+        val = KIPLATFORM::UI::GetPixelScaleFactor( m_window );
+        src = wxS( "platform" );
+    }
+
+    if( !val )
+    {
+        // Nothing else we can do, give it a default value
+        val = GetDefaultScaleFactor();
+        src = wxS( "default" );
+    }
+
+    wxLogTrace( traceHiDpi, wxS( "Scale factor (%s): %f" ), src, *val );
+
+    return *val;
+}
+
+
+double DPI_SCALING_COMMON::GetContentScaleFactor() const
+{
+    std::optional<double> val;
+    wxString              src;
+
+    if( m_config )
+    {
+        val = getKiCadConfiguredScale( *m_config );
+        src = wxS( "config" );
+    }
+
+    if( !val )
+    {
+        val = getEnvironmentScale();
+        src = wxS( "env" );
+    }
+
+    if( !val && m_window )
+    {
+        // Use the native WX reporting.
+        // On Linux, this will not work until WX 3.2 and GTK >= 3.10
+        // Otherwise it returns 1.0
+        val = KIPLATFORM::UI::GetContentScaleFactor( m_window );
+        src = wxS( "platform" );
+    }
+
+    if( !val )
+    {
+        // Nothing else we can do, give it a default value
+        val = GetDefaultScaleFactor();
+        src = wxS( "default" );
+    }
+
+    wxLogTrace( traceHiDpi, wxS( "Content scale factor (%s): %f" ), src, *val );
+
+    return *val;
+}
+
+
+bool DPI_SCALING_COMMON::GetCanvasIsAutoScaled() const
+{
+    if( m_config == nullptr )
+    {
+        // No configuration given, so has to be automatic scaling
+        return true;
+    }
+
+    const bool automatic = getKiCadConfiguredScale( *m_config ) == std::nullopt;
+    wxLogTrace( traceHiDpi, wxS( "Scale is automatic: %d" ), automatic );
+    return automatic;
+}
+
+
+void DPI_SCALING_COMMON::SetDpiConfig( bool aAuto, double aValue )
+{
+    wxCHECK_RET( m_config != nullptr, wxS( "Setting DPI config without a config store." ) );
+
+    const double value = aAuto ? 0.0 : aValue;
+
+    m_config->m_Appearance.canvas_scale = value;
+}
diff --git a/common/gal/CMakeLists.txt b/common/gal/CMakeLists.txt
index bb69157d8b..076300f69c 100644
--- a/common/gal/CMakeLists.txt
+++ b/common/gal/CMakeLists.txt
@@ -12,7 +12,6 @@ set( GAL_SRCS
 
     ../view/view_controls.cpp
     ../view/view_overlay.cpp
-    ../view/wx_view_controls.cpp
     ../view/zoom_controller.cpp
 
     # OpenGL GAL
diff --git a/common/gal/dpi_scaling.cpp b/common/gal/dpi_scaling.cpp
index 0ea64e7b81..3a93320b1b 100644
--- a/common/gal/dpi_scaling.cpp
+++ b/common/gal/dpi_scaling.cpp
@@ -23,173 +23,6 @@
 
 #include <gal/dpi_scaling.h>
 
-#include <optional>
-
-#include <env_vars.h>
-#include <settings/common_settings.h>
-#include <kiplatform/ui.h>
-
-#include <wx/log.h>
-
-
-/**
- * Flag to enable trace for HiDPI scaling factors
- *
- * Use "KICAD_TRACE_HIGH_DPI" to enable.
- *
- * @ingroup trace_env_vars
- */
-const wxChar* const traceHiDpi = wxT( "KICAD_TRACE_HIGH_DPI" );
-
-
-/**
- * Get a user-configured scale factor from KiCad config file
- *
- * @return the scale factor, if set
- */
-static std::optional<double> getKiCadConfiguredScale( const COMMON_SETTINGS& aConfig )
-{
-    std::optional<double> scale;
-    double      canvas_scale = aConfig.m_Appearance.canvas_scale;
-
-    if( canvas_scale > 0.0 )
-    {
-        scale = canvas_scale;
-    }
-
-    return scale;
-}
-
-
-/**
- * Get the toolkit scale factor from a user-set environment variable
- * (for example GDK_SCALE on GTK).
- *
- * @return the scale factor, if set
- */
-static std::optional<double> getEnvironmentScale()
-{
-    const wxPortId port_id = wxPlatformInfo::Get().GetPortId();
-    std::optional<double>    scale;
-
-    if( port_id == wxPORT_GTK )
-    {
-        // Under GTK, the user can use GDK_SCALE to force the scaling
-        scale = ENV_VAR::GetEnvVar<double>( wxS( "GDK_SCALE" ) );
-    }
-
-    return scale;
-}
-
-
-DPI_SCALING::DPI_SCALING( COMMON_SETTINGS* aConfig, const wxWindow* aWindow )
-        : m_config( aConfig ), m_window( aWindow )
-{
-}
-
-
-double DPI_SCALING::GetScaleFactor() const
-{
-    std::optional<double> val;
-    wxString              src;
-
-    if( m_config )
-    {
-        val = getKiCadConfiguredScale( *m_config );
-        src = wxS( "config" );
-    }
-
-    if( !val )
-    {
-        val = getEnvironmentScale();
-        src = wxS( "env" );
-    }
-
-    if( !val && m_window )
-    {
-        // Use the native WX reporting.
-        // On Linux, this will not work until WX 3.2 and GTK >= 3.10
-        // Otherwise it returns 1.0
-        val = KIPLATFORM::UI::GetPixelScaleFactor( m_window );
-        src = wxS( "platform" );
-    }
-
-    if( !val )
-    {
-        // Nothing else we can do, give it a default value
-        val = GetDefaultScaleFactor();
-        src = wxS( "default" );
-    }
-
-    wxLogTrace( traceHiDpi, wxS( "Scale factor (%s): %f" ), src, *val );
-
-    return *val;
-}
-
-
-double DPI_SCALING::GetContentScaleFactor() const
-{
-    std::optional<double> val;
-    wxString              src;
-
-    if( m_config )
-    {
-        val = getKiCadConfiguredScale( *m_config );
-        src = wxS( "config" );
-    }
-
-    if( !val )
-    {
-        val = getEnvironmentScale();
-        src = wxS( "env" );
-    }
-
-    if( !val && m_window )
-    {
-        // Use the native WX reporting.
-        // On Linux, this will not work until WX 3.2 and GTK >= 3.10
-        // Otherwise it returns 1.0
-        val = KIPLATFORM::UI::GetContentScaleFactor( m_window );
-        src = wxS( "platform" );
-    }
-
-    if( !val )
-    {
-        // Nothing else we can do, give it a default value
-        val = GetDefaultScaleFactor();
-        src = wxS( "default" );
-    }
-
-    wxLogTrace( traceHiDpi, wxS( "Content scale factor (%s): %f" ), src, *val );
-
-    return *val;
-}
-
-
-bool DPI_SCALING::GetCanvasIsAutoScaled() const
-{
-    if( m_config == nullptr )
-    {
-        // No configuration given, so has to be automatic scaling
-        return true;
-    }
-
-    const bool automatic = getKiCadConfiguredScale( *m_config ) == std::nullopt;
-    wxLogTrace( traceHiDpi, wxS( "Scale is automatic: %d" ), automatic );
-    return automatic;
-}
-
-
-void DPI_SCALING::SetDpiConfig( bool aAuto, double aValue )
-{
-    wxCHECK_RET( m_config != nullptr, wxS( "Setting DPI config without a config store." ) );
-
-    const double value = aAuto ? 0.0 : aValue;
-
-    m_config->m_Appearance.canvas_scale = value;
-}
-
-
 double DPI_SCALING::GetMaxScaleFactor()
 {
     // displays with higher than 4.0 DPI are not really going to be useful
diff --git a/common/gal/gal_display_options.cpp b/common/gal/gal_display_options.cpp
index a3dd04ecbc..af2daedd88 100644
--- a/common/gal/gal_display_options.cpp
+++ b/common/gal/gal_display_options.cpp
@@ -32,20 +32,6 @@
 
 using namespace KIGFX;
 
-static const UTIL::CFG_MAP<KIGFX::GRID_STYLE> gridStyleConfigVals =
-{
-    { KIGFX::GRID_STYLE::DOTS,       0 },
-    { KIGFX::GRID_STYLE::LINES,      1 },
-    { KIGFX::GRID_STYLE::SMALL_CROSS,2 },
-};
-
-static const UTIL::CFG_MAP<KIGFX::GRID_SNAPPING> gridSnapConfigVals =
-{
-    { KIGFX::GRID_SNAPPING::ALWAYS,     0 },
-    { KIGFX::GRID_SNAPPING::WITH_GRID,  1 },
-    { KIGFX::GRID_SNAPPING::NEVER,      2 }
-};
-
 
 /**
  * Flag to enable GAL_DISPLAY_OPTIONS logging
@@ -60,7 +46,6 @@ static const wxChar* traceGalDispOpts = wxT( "KICAD_GAL_DISPLAY_OPTIONS" );
 GAL_DISPLAY_OPTIONS::GAL_DISPLAY_OPTIONS()
     : gl_antialiasing_mode( OPENGL_ANTIALIASING_MODE::NONE ),
       cairo_antialiasing_mode( CAIRO_ANTIALIASING_MODE::NONE ),
-      m_dpi( nullptr, nullptr ),
       m_gridStyle( GRID_STYLE::DOTS ),
       m_gridSnapping( GRID_SNAPPING::ALWAYS ),
       m_gridLineWidth( 1.0 ),
@@ -69,75 +54,7 @@ GAL_DISPLAY_OPTIONS::GAL_DISPLAY_OPTIONS()
       m_fullscreenCursor( false ),
       m_forceDisplayCursor( false ),
       m_scaleFactor( DPI_SCALING::GetDefaultScaleFactor() )
-{}
-
-
-void GAL_DISPLAY_OPTIONS::ReadWindowSettings( WINDOW_SETTINGS& aCfg )
 {
-    wxLogTrace( traceGalDispOpts, wxS( "Reading app-specific options" ) );
-
-    m_gridStyle = UTIL::GetValFromConfig( gridStyleConfigVals, aCfg.grid.style );
-    m_gridSnapping = UTIL::GetValFromConfig( gridSnapConfigVals, aCfg.grid.snap );
-    m_gridLineWidth = aCfg.grid.line_width;
-    m_gridMinSpacing = aCfg.grid.min_spacing;
-    m_axesEnabled = aCfg.grid.axes_enabled;
-
-    m_fullscreenCursor = aCfg.cursor.fullscreen_cursor;
-    m_forceDisplayCursor = aCfg.cursor.always_show_cursor;
-
-    NotifyChanged();
-}
-
-
-void GAL_DISPLAY_OPTIONS::ReadCommonConfig( COMMON_SETTINGS& aSettings, wxWindow* aWindow )
-{
-    wxLogTrace( traceGalDispOpts, wxS( "Reading common config" ) );
-
-    gl_antialiasing_mode = static_cast<KIGFX::OPENGL_ANTIALIASING_MODE>(
-            aSettings.m_Graphics.opengl_aa_mode );
-
-    cairo_antialiasing_mode = static_cast<KIGFX::CAIRO_ANTIALIASING_MODE>(
-            aSettings.m_Graphics.cairo_aa_mode );
-
-    m_dpi = DPI_SCALING( &aSettings, aWindow );
-    UpdateScaleFactor();
-
-    NotifyChanged();
-}
-
-
-void GAL_DISPLAY_OPTIONS::ReadConfig( COMMON_SETTINGS& aCommonConfig,
-                                      WINDOW_SETTINGS& aWindowConfig, wxWindow* aWindow )
-{
-    wxLogTrace( traceGalDispOpts, wxS( "Reading common and app config" ) );
-
-    ReadWindowSettings( aWindowConfig );
-
-    ReadCommonConfig( aCommonConfig, aWindow );
-}
-
-
-void GAL_DISPLAY_OPTIONS::WriteConfig( WINDOW_SETTINGS& aCfg )
-{
-    wxLogTrace( traceGalDispOpts, wxS( "Writing window settings" ) );
-
-    aCfg.grid.style = UTIL::GetConfigForVal( gridStyleConfigVals, m_gridStyle );
-    aCfg.grid.snap = UTIL::GetConfigForVal( gridSnapConfigVals, m_gridSnapping );
-    aCfg.grid.line_width = m_gridLineWidth;
-    aCfg.grid.min_spacing = m_gridMinSpacing;
-    aCfg.grid.axes_enabled = m_axesEnabled;
-    aCfg.cursor.fullscreen_cursor = m_fullscreenCursor;
-    aCfg.cursor.always_show_cursor = m_forceDisplayCursor;
-}
-
-
-void GAL_DISPLAY_OPTIONS::UpdateScaleFactor()
-{
-    if( m_scaleFactor != m_dpi.GetScaleFactor() )
-    {
-        m_scaleFactor = m_dpi.GetScaleFactor();
-        NotifyChanged();
-    }
 }
 
 
@@ -146,4 +63,4 @@ void GAL_DISPLAY_OPTIONS::NotifyChanged()
     wxLogTrace( traceGalDispOpts, wxS( "Change notification" ) );
 
     Notify( &GAL_DISPLAY_OPTIONS_OBSERVER::OnGalDisplayOptionsChanged, *this );
-}
+}
\ No newline at end of file
diff --git a/common/gal_display_options_common.cpp b/common/gal_display_options_common.cpp
new file mode 100644
index 0000000000..50d3d0fd1f
--- /dev/null
+++ b/common/gal_display_options_common.cpp
@@ -0,0 +1,130 @@
+/*
+* This program source code file is part of KICAD, a free EDA CAD application.
+*
+* Copyright (C) 2016-2020 Kicad Developers, see change_log.txt for contributors.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* 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 General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, you may find one here:
+* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+* or you may search the http://www.gnu.org website for the version 2 license,
+* or you may write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+
+#include <gal_display_options_common.h>
+#include <settings/app_settings.h>
+#include <settings/common_settings.h>
+
+#include <wx/log.h>
+
+#include <config_map.h>
+#include <dpi_scaling_common.h>
+
+using namespace KIGFX;
+
+/**
+ * Flag to enable GAL_DISPLAY_OPTIONS logging
+ *
+ * Use "KICAD_GAL_DISPLAY_OPTIONS" to enable.
+ *
+ * @ingroup trace_env_vars
+ */
+static const wxChar* traceGalDispOpts = wxT( "KICAD_GAL_DISPLAY_OPTIONS" );
+
+
+static const UTIL::CFG_MAP<KIGFX::GRID_STYLE> gridStyleConfigVals = {
+    { KIGFX::GRID_STYLE::DOTS, 0 },
+    { KIGFX::GRID_STYLE::LINES, 1 },
+    { KIGFX::GRID_STYLE::SMALL_CROSS, 2 },
+};
+
+static const UTIL::CFG_MAP<KIGFX::GRID_SNAPPING> gridSnapConfigVals = {
+    { KIGFX::GRID_SNAPPING::ALWAYS, 0 },
+    { KIGFX::GRID_SNAPPING::WITH_GRID, 1 },
+    { KIGFX::GRID_SNAPPING::NEVER, 2 }
+};
+
+GAL_DISPLAY_OPTIONS_IMPL::GAL_DISPLAY_OPTIONS_IMPL() :
+    GAL_DISPLAY_OPTIONS(),
+    m_dpi( { nullptr, nullptr } )
+{
+}
+
+
+void GAL_DISPLAY_OPTIONS_IMPL::ReadWindowSettings( WINDOW_SETTINGS& aCfg )
+{
+    wxLogTrace( traceGalDispOpts, wxS( "Reading app-specific options" ) );
+
+    m_gridStyle = UTIL::GetValFromConfig( gridStyleConfigVals, aCfg.grid.style );
+    m_gridSnapping = UTIL::GetValFromConfig( gridSnapConfigVals, aCfg.grid.snap );
+    m_gridLineWidth = aCfg.grid.line_width;
+    m_gridMinSpacing = aCfg.grid.min_spacing;
+    m_axesEnabled = aCfg.grid.axes_enabled;
+
+    m_fullscreenCursor = aCfg.cursor.fullscreen_cursor;
+    m_forceDisplayCursor = aCfg.cursor.always_show_cursor;
+
+    NotifyChanged();
+}
+
+
+void GAL_DISPLAY_OPTIONS_IMPL::ReadCommonConfig( COMMON_SETTINGS& aSettings, wxWindow* aWindow )
+{
+    wxLogTrace( traceGalDispOpts, wxS( "Reading common config" ) );
+
+    gl_antialiasing_mode =
+            static_cast<KIGFX::OPENGL_ANTIALIASING_MODE>( aSettings.m_Graphics.opengl_aa_mode );
+
+    cairo_antialiasing_mode =
+            static_cast<KIGFX::CAIRO_ANTIALIASING_MODE>( aSettings.m_Graphics.cairo_aa_mode );
+
+    m_dpi = DPI_SCALING_COMMON( &aSettings, aWindow );
+    UpdateScaleFactor();
+
+    NotifyChanged();
+}
+
+
+void GAL_DISPLAY_OPTIONS_IMPL::ReadConfig( COMMON_SETTINGS& aCommonConfig,
+                                           WINDOW_SETTINGS& aWindowConfig, wxWindow* aWindow )
+{
+    wxLogTrace( traceGalDispOpts, wxS( "Reading common and app config" ) );
+
+    ReadWindowSettings( aWindowConfig );
+
+    ReadCommonConfig( aCommonConfig, aWindow );
+}
+
+
+void GAL_DISPLAY_OPTIONS_IMPL::WriteConfig( WINDOW_SETTINGS& aCfg )
+{
+    wxLogTrace( traceGalDispOpts, wxS( "Writing window settings" ) );
+
+    aCfg.grid.style = UTIL::GetConfigForVal( gridStyleConfigVals, m_gridStyle );
+    aCfg.grid.snap = UTIL::GetConfigForVal( gridSnapConfigVals, m_gridSnapping );
+    aCfg.grid.line_width = m_gridLineWidth;
+    aCfg.grid.min_spacing = m_gridMinSpacing;
+    aCfg.grid.axes_enabled = m_axesEnabled;
+    aCfg.cursor.fullscreen_cursor = m_fullscreenCursor;
+    aCfg.cursor.always_show_cursor = m_forceDisplayCursor;
+}
+
+
+void GAL_DISPLAY_OPTIONS_IMPL::UpdateScaleFactor()
+{
+    if( m_scaleFactor != m_dpi.GetScaleFactor() )
+    {
+        m_scaleFactor = m_dpi.GetScaleFactor();
+        NotifyChanged();
+    }
+}
diff --git a/common/tool/common_tools.cpp b/common/tool/common_tools.cpp
index 154da3539d..0c33960be7 100644
--- a/common/tool/common_tools.cpp
+++ b/common/tool/common_tools.cpp
@@ -653,7 +653,7 @@ int COMMON_TOOLS::ToggleCursor( const TOOL_EVENT& aEvent )
 
 int COMMON_TOOLS::ToggleCursorStyle( const TOOL_EVENT& aEvent )
 {
-    KIGFX::GAL_DISPLAY_OPTIONS& galOpts = m_frame->GetGalDisplayOptions();
+    GAL_DISPLAY_OPTIONS_IMPL& galOpts = m_frame->GetGalDisplayOptions();
 
     galOpts.m_fullscreenCursor = !galOpts.m_fullscreenCursor;
     galOpts.WriteConfig( m_toolMgr->GetSettings()->m_Window );
diff --git a/common/view/view_overlay.cpp b/common/view/view_overlay.cpp
index e3fb530d1d..1a6044fcc0 100644
--- a/common/view/view_overlay.cpp
+++ b/common/view/view_overlay.cpp
@@ -30,7 +30,6 @@
 #include <gal/graphics_abstraction_layer.h>
 #include <gal/painter.h>
 
-#include <layer_ids.h>
 #include <geometry/seg.h>
 
 namespace KIGFX {
diff --git a/common/widgets/color_swatch.cpp b/common/widgets/color_swatch.cpp
index 335970143d..6a8b3444ba 100644
--- a/common/widgets/color_swatch.cpp
+++ b/common/widgets/color_swatch.cpp
@@ -24,7 +24,7 @@
 #include <widgets/color_swatch.h>
 #include <wx/dcmemory.h>
 
-#include <gal/dpi_scaling.h>
+#include <dpi_scaling_common.h>
 #include <dialogs/dialog_color_picker.h>
 #include <memory>
 
@@ -149,7 +149,7 @@ COLOR_SWATCH::COLOR_SWATCH( wxWindow* aParent, const COLOR4D& aColor, int aID,
     // These need additional scaling on Windows because of some discrepancy between pixel and
     // content scaling that only affects certain widgets on Windows HiDPI.  On other platforms, the
     // value returned by ConvertDialogToPixels appears to be correct.
-    DPI_SCALING dpi( nullptr, aParent );
+    DPI_SCALING_COMMON dpi( nullptr, aParent );
 
     m_size /= dpi.GetContentScaleFactor();
     m_checkerboardSize /= dpi.GetContentScaleFactor();
diff --git a/common/widgets/layer_box_selector.cpp b/common/widgets/layer_box_selector.cpp
index 7592a6ed15..da19b8665b 100644
--- a/common/widgets/layer_box_selector.cpp
+++ b/common/widgets/layer_box_selector.cpp
@@ -28,7 +28,7 @@
 #include <wx/menuitem.h>
 #include <wx/settings.h>
 
-#include <gal/dpi_scaling.h>
+#include <dpi_scaling_common.h>
 #include <layer_ids.h>
 #include <widgets/layer_box_selector.h>
 #include "kiplatform/ui.h"
@@ -134,7 +134,7 @@ int LAYER_BOX_SELECTOR::SetLayerSelection( int layer )
 
 void LAYER_BOX_SELECTOR::ResyncBitmapOnly()
 {
-    DPI_SCALING dpi( nullptr, this );
+    DPI_SCALING_COMMON dpi( nullptr, this );
     int size = static_cast<int>( dpi.GetScaleFactor() * 14 );
 
     for( int i = 0; i < (int) GetCount(); ++i )
diff --git a/common/widgets/wx_infobar.cpp b/common/widgets/wx_infobar.cpp
index 8d61a6c8c7..984baaf92c 100644
--- a/common/widgets/wx_infobar.cpp
+++ b/common/widgets/wx_infobar.cpp
@@ -32,7 +32,7 @@
 #include <eda_base_frame.h>
 
 #ifdef __WXMSW__
-#include <gal/dpi_scaling.h>
+#include <dpi_scaling_common.h>
 #endif
 
 
@@ -85,7 +85,7 @@ WX_INFOBAR::WX_INFOBAR( wxWindow* aParent, wxAuiManager* aMgr, wxWindowID aWinid
     wxSize   iconSize = wxArtProvider::GetSizeHint( wxART_BUTTON );
 
 #ifdef __WXMSW__
-    DPI_SCALING dpi( nullptr, aParent );
+    DPI_SCALING_COMMON dpi( nullptr, aParent );
     iconSize.x *= dpi.GetContentScaleFactor();
     sx *= dpi.GetContentScaleFactor();
     sy *= dpi.GetContentScaleFactor();
diff --git a/eeschema/dialogs/panel_eeschema_color_settings.h b/eeschema/dialogs/panel_eeschema_color_settings.h
index 6ce8dba84a..6e3227bdb8 100644
--- a/eeschema/dialogs/panel_eeschema_color_settings.h
+++ b/eeschema/dialogs/panel_eeschema_color_settings.h
@@ -24,6 +24,7 @@
 
 #include <dialogs/panel_color_settings.h>
 #include <class_draw_panel_gal.h>
+#include <gal_display_options_common.h>
 
 class PAGE_INFO;
 class EDA_ITEM;
@@ -71,7 +72,7 @@ private:
     DS_PROXY_VIEW_ITEM*          m_drawingSheet;
     std::vector<EDA_ITEM*>       m_previewItems;
 
-    KIGFX::GAL_DISPLAY_OPTIONS   m_galDisplayOptions;
+    GAL_DISPLAY_OPTIONS_IMPL     m_galDisplayOptions;
     EDA_DRAW_PANEL_GAL::GAL_TYPE m_galType;
 };
 
diff --git a/eeschema/widgets/symbol_preview_widget.h b/eeschema/widgets/symbol_preview_widget.h
index 69b25e9b85..ce70758fb0 100644
--- a/eeschema/widgets/symbol_preview_widget.h
+++ b/eeschema/widgets/symbol_preview_widget.h
@@ -22,7 +22,7 @@
 
 #include <wx/panel.h>
 #include <kiway.h>
-#include <gal/gal_display_options.h>
+#include <gal_display_options_common.h>
 #include <class_draw_panel_gal.h>
 
 
@@ -67,7 +67,7 @@ protected:
 
     KIWAY*                     m_kiway;
 
-    KIGFX::GAL_DISPLAY_OPTIONS m_galDisplayOptions;
+    GAL_DISPLAY_OPTIONS_IMPL   m_galDisplayOptions;
     EDA_DRAW_PANEL_GAL*        m_preview;
 
     wxStaticText*              m_status;
diff --git a/gerbview/widgets/gbr_layer_box_selector.cpp b/gerbview/widgets/gbr_layer_box_selector.cpp
index c8f244cd9e..8f1eb4df56 100644
--- a/gerbview/widgets/gbr_layer_box_selector.cpp
+++ b/gerbview/widgets/gbr_layer_box_selector.cpp
@@ -27,7 +27,7 @@
 #include <gerber_file_image_list.h>
 
 #ifdef __WXMSW__
-#include <gal/dpi_scaling.h>
+#include <dpi_scaling_common.h>
 #endif
 
 #include "gbr_layer_box_selector.h"
@@ -38,7 +38,7 @@ void GBR_LAYER_BOX_SELECTOR::Resync()
     Clear();
 
 #ifdef __WXMSW__
-    DPI_SCALING dpi( nullptr, this );
+    DPI_SCALING_COMMON dpi( nullptr, this );
     int size = static_cast<int>( 14 / dpi.GetContentScaleFactor() );
 #else
     const int size = 14;
diff --git a/include/dpi_scaling_common.h b/include/dpi_scaling_common.h
new file mode 100644
index 0000000000..204c003ca8
--- /dev/null
+++ b/include/dpi_scaling_common.h
@@ -0,0 +1,95 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2019 KiCad Developers, see AUTHORS.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#ifndef DPI_SCALING_COMMON__H
+#define DPI_SCALING_COMMON__H
+
+#include <gal/dpi_scaling.h>
+
+class COMMON_SETTINGS;
+class wxWindow;
+
+/**
+ * Class to handle configuration and automatic determination of the DPI
+ * scale to use for canvases. This has several sources and the availability of
+ * some of them are platform dependent.
+ */
+class DPI_SCALING_COMMON : public DPI_SCALING
+{
+public:
+    /**
+     * Construct a DPI scale provider.
+     *
+     * @param aConfig the config store to check for a user value (can be nullptr,
+     * in which case on automatically determined values are considered)
+     * @param aWindow a WX window to use for automatic DPI determination
+     * @return the scaling factor (1.0 = no scaling)
+     */
+    DPI_SCALING_COMMON( COMMON_SETTINGS* aConfig, const wxWindow* aWindow );
+
+    /**
+     * Get the DPI scale from all known sources in order:
+     *
+     * * user config, if given
+     * * user's environment variables, if set and according to platform
+     * * WX's internal determination of the DPI scaling (WX > 3.1)
+     */
+    double GetScaleFactor() const override;
+
+    /**
+     * Get the content scale factor, which may be different from the scale
+     * factor on some platforms.  This value should be used for scaling
+     * user interface elements (fonts, icons, etc) whereas the scale
+     * factor should be used for scaling canvases.
+     */
+    double GetContentScaleFactor() const override;
+
+    /**
+     * Is the current value auto scaled, or is it user-set in the config
+     */
+    bool GetCanvasIsAutoScaled() const override;
+
+    /**
+     * Set the common DPI config in a given config object
+     *
+     * The encoding of the automatic/manual nature of the config is handled internally.
+     *
+     * @param aAuto   store a value meaning "no user-set scale"
+     * @param aValue  the value to store (ignored if aAuto set)
+     */
+    void SetDpiConfig( bool aAuto, double aValue ) override;
+
+private:
+    /**
+     * The configuration object to use to get/set user setting. nullptr
+     * if only automatic options are wanted
+     */
+    COMMON_SETTINGS* m_config;
+
+    /**
+     * The WX window to use for WX's automatic DPI checking
+     */
+    const wxWindow* m_window;
+};
+
+#endif // DPI_SCALING__H
\ No newline at end of file
diff --git a/include/eda_draw_frame.h b/include/eda_draw_frame.h
index 3606625c4d..284bc9da37 100644
--- a/include/eda_draw_frame.h
+++ b/include/eda_draw_frame.h
@@ -29,6 +29,7 @@
 #include <eda_base_frame.h>
 #include <kiway_player.h>
 #include <gal/gal_display_options.h>
+#include <gal_display_options_common.h>
 #include <gal/color4d.h>
 #include <class_draw_panel_gal.h>
 #include <kiid.h>
@@ -432,7 +433,7 @@ public:
     /**
      * Return a reference to the gal rendering options used by GAL for rendering.
      */
-    KIGFX::GAL_DISPLAY_OPTIONS& GetGalDisplayOptions() { return m_galDisplayOptions; }
+    GAL_DISPLAY_OPTIONS_IMPL& GetGalDisplayOptions() { return m_galDisplayOptions; }
 
     void RefreshCanvas() override
     {
@@ -548,7 +549,7 @@ private:
     EDA_DRAW_PANEL_GAL*         m_canvas;
 
     ///< This the frame's interface to setting GAL display options.
-    KIGFX::GAL_DISPLAY_OPTIONS  m_galDisplayOptions;
+    GAL_DISPLAY_OPTIONS_IMPL  m_galDisplayOptions;
 };
 
 #endif  // DRAW_FRAME_H_
diff --git a/include/gal/dpi_scaling.h b/include/gal/dpi_scaling.h
index 5652a95d60..7ce7dd757d 100644
--- a/include/gal/dpi_scaling.h
+++ b/include/gal/dpi_scaling.h
@@ -26,8 +26,6 @@
 
 #include <wx/window.h>
 
-class COMMON_SETTINGS;
-
 /**
  * Class to handle configuration and automatic determination of the DPI
  * scale to use for canvases. This has several sources and the availability of
@@ -44,7 +42,9 @@ public:
      * @param aWindow a WX window to use for automatic DPI determination
      * @return the scaling factor (1.0 = no scaling)
      */
-    DPI_SCALING( COMMON_SETTINGS* aConfig, const wxWindow* aWindow );
+    DPI_SCALING(){};
+
+    virtual ~DPI_SCALING() {}
 
     /**
      * Get the DPI scale from all known sources in order:
@@ -53,7 +53,7 @@ public:
      * * user's environment variables, if set and according to platform
      * * WX's internal determination of the DPI scaling (WX > 3.1)
      */
-    double GetScaleFactor() const;
+    virtual double GetScaleFactor() const = 0;
 
     /**
      * Get the content scale factor, which may be different from the scale
@@ -61,12 +61,12 @@ public:
      * user interface elements (fonts, icons, etc) whereas the scale
      * factor should be used for scaling canvases.
      */
-    double GetContentScaleFactor() const;
+    virtual double GetContentScaleFactor() const = 0;
 
     /**
      * Is the current value auto scaled, or is it user-set in the config
      */
-    bool GetCanvasIsAutoScaled() const;
+    virtual bool GetCanvasIsAutoScaled() const = 0;
 
     /**
      * Set the common DPI config in a given config object
@@ -76,7 +76,7 @@ public:
      * @param aAuto   store a value meaning "no user-set scale"
      * @param aValue  the value to store (ignored if aAuto set)
      */
-    void SetDpiConfig( bool aAuto, double aValue );
+    virtual void SetDpiConfig( bool aAuto, double aValue ) = 0;
 
     /*
      * Get the maximum scaling factor that should be presented to the user.
@@ -94,18 +94,6 @@ public:
      * Get the "default" scaling factor to use if not other config is available
      */
     static double GetDefaultScaleFactor();
-
-private:
-    /**
-     * The configuration object to use to get/set user setting. nullptr
-     * if only automatic options are wanted
-     */
-    COMMON_SETTINGS* m_config;
-
-    /**
-     * The WX window to use for WX's automatic DPI checking
-     */
-    const wxWindow* m_window;
 };
 
 #endif // DPI_SCALING__H
\ No newline at end of file
diff --git a/include/gal/gal_display_options.h b/include/gal/gal_display_options.h
index 726509b8c2..9ad33758fc 100644
--- a/include/gal/gal_display_options.h
+++ b/include/gal/gal_display_options.h
@@ -82,41 +82,10 @@ namespace KIGFX
     public:
         GAL_DISPLAY_OPTIONS();
 
-        /**
-         * Read GAL config options from application-level config
-         * @param aCfg      the window settings to load from
-         */
-        void ReadWindowSettings( WINDOW_SETTINGS& aCfg );
-
-        /**
-         * Read GAL config options from the common config store
-         * @param aCommonSettings the common config store
-         * @param aWindow         the wx parent window (used for DPI scaling)
-         */
-        void ReadCommonConfig( COMMON_SETTINGS& aCommonSettings, wxWindow* aWindow );
-
-        /**
-         * Read application and common configs
-         * @param aCommonConfig the common config store
-         * @param aCfg          the application config base
-         * @param aBaseName     the application's GAL options key prefix
-         * @param aWindow       the wx parent window (used for DPI scaling)
-         */
-        void ReadConfig( COMMON_SETTINGS& aCommonConfig, WINDOW_SETTINGS& aWindowConfig,
-                wxWindow* aWindow );
-
-        void WriteConfig( WINDOW_SETTINGS& aCfg );
-
-        void UpdateScaleFactor();
-
-        void NotifyChanged();
-
         OPENGL_ANTIALIASING_MODE gl_antialiasing_mode;
 
         CAIRO_ANTIALIASING_MODE cairo_antialiasing_mode;
 
-        DPI_SCALING m_dpi;
-
         ///< The grid style to draw the grid in
         KIGFX::GRID_STYLE m_gridStyle;
 
@@ -140,8 +109,9 @@ namespace KIGFX
 
         ///< The pixel scale factor (>1 for hi-DPI scaled displays)
         double m_scaleFactor;
-    };
 
+        void NotifyChanged();
+    };
 }
 
 #endif
diff --git a/include/gal_display_options_common.h b/include/gal_display_options_common.h
new file mode 100644
index 0000000000..f11f15a75f
--- /dev/null
+++ b/include/gal_display_options_common.h
@@ -0,0 +1,71 @@
+/*
+* This program source code file is part of KICAD, a free EDA CAD application.
+*
+* Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* 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 General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, you may find one here:
+* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+* or you may search the http://www.gnu.org website for the version 2 license,
+* or you may write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+*/
+
+#ifndef GAL_DISPLAY_OPTIONS_COMMON_H__
+#define GAL_DISPLAY_OPTIONS_COMMON_H__
+
+#include <gal/gal_display_options.h>
+#include <dpi_scaling_common.h>
+
+class COMMON_SETTINGS;
+struct WINDOW_SETTINGS;
+class wxString;
+class wxWindow;
+
+
+class GAL_DISPLAY_OPTIONS_IMPL : public KIGFX::GAL_DISPLAY_OPTIONS
+{
+public:
+    GAL_DISPLAY_OPTIONS_IMPL();
+
+    /**
+         * Read GAL config options from application-level config
+         * @param aCfg      the window settings to load from
+         */
+    void ReadWindowSettings( WINDOW_SETTINGS& aCfg );
+
+    /**
+         * Read GAL config options from the common config store
+         * @param aCommonSettings the common config store
+         * @param aWindow         the wx parent window (used for DPI scaling)
+         */
+    void ReadCommonConfig( COMMON_SETTINGS& aCommonSettings, wxWindow* aWindow );
+
+    /**
+         * Read application and common configs
+         * @param aCommonConfig the common config store
+         * @param aCfg          the application config base
+         * @param aBaseName     the application's GAL options key prefix
+         * @param aWindow       the wx parent window (used for DPI scaling)
+         */
+    void ReadConfig( COMMON_SETTINGS& aCommonConfig, WINDOW_SETTINGS& aWindowConfig,
+                     wxWindow* aWindow );
+
+    void WriteConfig( WINDOW_SETTINGS& aCfg );
+
+    void UpdateScaleFactor();
+
+    DPI_SCALING_COMMON m_dpi;
+};
+
+#endif
diff --git a/pcbnew/dialogs/dialog_pad_properties.cpp b/pcbnew/dialogs/dialog_pad_properties.cpp
index 983a5f2837..5529f5e11c 100644
--- a/pcbnew/dialogs/dialog_pad_properties.cpp
+++ b/pcbnew/dialogs/dialog_pad_properties.cpp
@@ -335,7 +335,7 @@ void DIALOG_PAD_PROPERTIES::OnCancel( wxCommandEvent& event )
 
 void DIALOG_PAD_PROPERTIES::prepareCanvas()
 {
-    KIGFX::GAL_DISPLAY_OPTIONS opts = m_parent->GetGalDisplayOptions();
+    GAL_DISPLAY_OPTIONS_IMPL opts = m_parent->GetGalDisplayOptions();
     COLOR_SETTINGS*            colorSettings = m_parent->GetColorSettings();
 
     opts.m_forceDisplayCursor = false;
diff --git a/pcbnew/footprint_preview_panel.cpp b/pcbnew/footprint_preview_panel.cpp
index 478f0e813f..2fdf5cd109 100644
--- a/pcbnew/footprint_preview_panel.cpp
+++ b/pcbnew/footprint_preview_panel.cpp
@@ -28,6 +28,7 @@
 #include <board.h>
 #include <footprint.h>
 #include <pcb_dimension.h>
+#include <dpi_scaling_common.h>
 #include <eda_draw_frame.h>
 #include <footprint_preview_panel.h>
 #include <fp_lib_table.h>
@@ -254,9 +255,9 @@ FOOTPRINT_PREVIEW_PANEL* FOOTPRINT_PREVIEW_PANEL::New( KIWAY* aKiway, wxWindow*
             cfg->m_Window.zoom_factors = { ZOOM_LIST_PCBNEW };
     }
 
-    std::unique_ptr<KIGFX::GAL_DISPLAY_OPTIONS> gal_opts;
+    std::unique_ptr<GAL_DISPLAY_OPTIONS_IMPL> gal_opts;
 
-    gal_opts = std::make_unique<KIGFX::GAL_DISPLAY_OPTIONS>();
+    gal_opts = std::make_unique<GAL_DISPLAY_OPTIONS_IMPL>();
     gal_opts->ReadConfig( *Pgm().GetCommonSettings(), cfg->m_Window, aParent );
 
     auto galType = static_cast<EDA_DRAW_PANEL_GAL::GAL_TYPE>( cfg->m_Graphics.canvas_type );
diff --git a/pcbnew/pcb_layer_box_selector.cpp b/pcbnew/pcb_layer_box_selector.cpp
index 3dd8bae5b6..05b9ea20db 100644
--- a/pcbnew/pcb_layer_box_selector.cpp
+++ b/pcbnew/pcb_layer_box_selector.cpp
@@ -32,6 +32,7 @@
 #include <board.h>
 #include <pcb_layer_box_selector.h>
 #include <tools/pcb_actions.h>
+#include <dpi_scaling_common.h>
 
 
 // class to display a layer list in a wxBitmapComboBox.
@@ -43,7 +44,7 @@ void PCB_LAYER_BOX_SELECTOR::Resync()
     Clear();
 
 #ifdef __WXMSW__
-    DPI_SCALING dpi( nullptr, this );
+    DPI_SCALING_COMMON dpi( nullptr, this );
     int size = static_cast<int>( 14 / dpi.GetContentScaleFactor() );
 #else
     const int size = 14;
diff --git a/pcbnew/widgets/appearance_controls.cpp b/pcbnew/widgets/appearance_controls.cpp
index 122101c1c3..30f62a4492 100644
--- a/pcbnew/widgets/appearance_controls.cpp
+++ b/pcbnew/widgets/appearance_controls.cpp
@@ -25,6 +25,7 @@
 #include <board_design_settings.h>
 #include <pad.h>
 #include <pcb_track.h>
+#include <dpi_scaling_common.h>
 #include <eda_list_dialog.h>
 #include <string_utils.h>
 #include <footprint_edit_frame.h>
@@ -406,7 +407,7 @@ APPEARANCE_CONTROLS::APPEARANCE_CONTROLS( PCB_BASE_FRAME* aParent, wxWindow* aFo
         m_lastSelectedUserPreset( nullptr ),
         m_layerContextMenu( nullptr )
 {
-    DPI_SCALING dpi( nullptr, m_frame );
+    DPI_SCALING_COMMON dpi( nullptr, m_frame );
 
     int indicatorSize = ConvertDialogToPixels( wxSize( 6, 6 ) ).x / dpi.GetContentScaleFactor();
     int screenHeight  = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y );
@@ -804,7 +805,7 @@ void APPEARANCE_CONTROLS::createControls()
 
 wxSize APPEARANCE_CONTROLS::GetBestSize() const
 {
-    DPI_SCALING dpi( nullptr, m_frame );
+    DPI_SCALING_COMMON dpi( nullptr, m_frame );
     wxSize      size( 220 * dpi.GetScaleFactor(), 480 * dpi.GetScaleFactor() );
     return size;
 }
diff --git a/qa/qa_utils/pcb_test_frame.cpp b/qa/qa_utils/pcb_test_frame.cpp
index 7f7808739a..2972326b3c 100644
--- a/qa/qa_utils/pcb_test_frame.cpp
+++ b/qa/qa_utils/pcb_test_frame.cpp
@@ -35,7 +35,7 @@
 #include <layer_ids.h>
 
 #include <gal/graphics_abstraction_layer.h>
-#include <gal/dpi_scaling.h>
+#include <dpi_scaling_common.h>
 #include <class_draw_panel_gal.h>
 #include <pcb_draw_panel_gal.h>
 #include <view/wx_view_controls.h>
@@ -129,7 +129,7 @@ void PCB_TEST_FRAME_BASE::createView( wxWindow *aParent, PCB_DRAW_PANEL_GAL::GAL
     // SUPERSAMPLING_X4;
     m_displayOptions.gl_antialiasing_mode = KIGFX::OPENGL_ANTIALIASING_MODE::NONE;
 
-    DPI_SCALING dpi( Pgm().GetCommonSettings(), aParent );
+    DPI_SCALING_COMMON dpi( Pgm().GetCommonSettings(), aParent );
     m_displayOptions.m_scaleFactor = dpi.GetScaleFactor();
 
     m_galPanel = std::make_shared<PCB_DRAW_PANEL_GAL>( aParent, -1, wxPoint( 0, 0 ),