diff --git a/src/posix/sdl/i_input.cpp b/src/posix/sdl/i_input.cpp
index 6fff2d2a9..372b23446 100644
--- a/src/posix/sdl/i_input.cpp
+++ b/src/posix/sdl/i_input.cpp
@@ -18,8 +18,6 @@
 #include "templates.h"
 #include "s_sound.h"
 
-void ScaleWithAspect (int &w, int &h, int Width, int Height);
-
 static void I_CheckGUICapture ();
 static void I_CheckNativeMouse ();
 
@@ -320,35 +318,11 @@ void MessagePump (const SDL_Event &sev)
 			int x, y;
 			SDL_GetMouseState (&x, &y);
 
-			// Detect if we're doing scaling in the Window and adjust the mouse
-			// coordinates accordingly. This could be more efficent, but I
-			// don't think performance is an issue in the menus.
-			SDL_Window *focus;
-			if (screen->IsFullscreen() && (focus = SDL_GetMouseFocus ()))
-			{
-				int w, h;
-				SDL_GetWindowSize (focus, &w, &h);
-				int realw = w, realh = h;
-				ScaleWithAspect (realw, realh, SCREENWIDTH, SCREENHEIGHT);
-				if (realw != SCREENWIDTH || realh != SCREENHEIGHT)
-				{
-					double xratio = (double)SCREENWIDTH/realw;
-					double yratio = (double)SCREENHEIGHT/realh;
-					if (realw < w)
-					{
-						x = (x - (w - realw)/2)*xratio;
-						y *= yratio;
-					}
-					else
-					{
-						y = (y - (h - realh)/2)*yratio;
-						x *= xratio;
-					}
-				}
-			}
-
 			event.data1 = x;
 			event.data2 = y;
+
+			screen->ScaleCoordsFromWindow(event.data1, event.data2);
+
 			event.type = EV_GUI_Event;
 			if(sev.type == SDL_MOUSEMOTION)
 				event.subtype = EV_GUI_MouseMove;
diff --git a/src/posix/sdl/sdlvideo.cpp b/src/posix/sdl/sdlvideo.cpp
index 309002456..c24fd797a 100644
--- a/src/posix/sdl/sdlvideo.cpp
+++ b/src/posix/sdl/sdlvideo.cpp
@@ -50,6 +50,7 @@ public:
 	friend class SDLVideo;
 
 	virtual void SetVSync (bool vsync);
+	virtual void ScaleCoordsFromWindow(SWORD &x, SWORD &y);
 
 private:
 	PalEntry SourcePalette[256];
@@ -723,6 +724,35 @@ void SDLFB::SetVSync (bool vsync)
 #endif // __APPLE__
 }
 
+void SDLFB::ScaleCoordsFromWindow(SWORD &x, SWORD &y)
+{
+	// Detect if we're doing scaling in the Window and adjust the mouse
+	// coordinates accordingly. This could be more efficent, but I
+	// don't think performance is an issue in the menus.
+	if(IsFullscreen())
+	{
+		int w, h;
+		SDL_GetWindowSize (Screen, &w, &h);
+		int realw = w, realh = h;
+		ScaleWithAspect (realw, realh, SCREENWIDTH, SCREENHEIGHT);
+		if (realw != SCREENWIDTH || realh != SCREENHEIGHT)
+		{
+			double xratio = (double)SCREENWIDTH/realw;
+			double yratio = (double)SCREENHEIGHT/realh;
+			if (realw < w)
+			{
+				x = (x - (w - realw)/2)*xratio;
+				y *= yratio;
+			}
+			else
+			{
+				y = (y - (h - realh)/2)*yratio;
+				x *= xratio;
+			}
+		}
+	}
+}
+
 ADD_STAT (blit)
 {
 	FString out;
diff --git a/src/v_video.h b/src/v_video.h
index 69741c7f8..5250cdaa9 100644
--- a/src/v_video.h
+++ b/src/v_video.h
@@ -398,8 +398,8 @@ public:
 	virtual void WipeEndScreen();
 	virtual bool WipeDo(int ticks);
 	virtual void WipeCleanup();
-	virtual int GetPixelDoubling() const { return 0; }
-	virtual int GetTrueHeight() { return GetHeight(); }
+
+	virtual void ScaleCoordsFromWindow(SWORD &x, SWORD &y) {}
 
 	uint32 GetLastFPS() const { return LastCount; }
 
diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp
index e23275734..9fd185431 100644
--- a/src/win32/fb_d3d9.cpp
+++ b/src/win32/fb_d3d9.cpp
@@ -1028,6 +1028,28 @@ bool D3DFB::IsFullscreen ()
 	return !Windowed;
 }
 
+//==========================================================================
+//
+// D3DFB :: ScaleCoordsFromWindow
+//
+// Given coordinates in window space, return coordinates in what the game
+// thinks screen space is.
+//
+//==========================================================================
+
+void D3DFB::ScaleCoordsFromWindow(SWORD &x, SWORD &y)
+{
+	RECT rect;
+
+	if (GetClientRect(Window, &rect))
+	{
+		x = SWORD(x * Width / (rect.right - rect.left));
+		y = SWORD(y * TrueHeight / (rect.bottom - rect.top));
+	}
+	// Subtract letterboxing borders
+	y -= (TrueHeight - Height) / 2;
+}
+
 //==========================================================================
 //
 // D3DFB :: Lock
diff --git a/src/win32/fb_ddraw.cpp b/src/win32/fb_ddraw.cpp
index 2aa694f3b..ecf570ff8 100644
--- a/src/win32/fb_ddraw.cpp
+++ b/src/win32/fb_ddraw.cpp
@@ -806,6 +806,19 @@ bool DDrawFB::Is8BitMode()
 	return vid_displaybits == 8;
 }
 
+void DDrawFB::ScaleCoordsFromWindow(SWORD &x, SWORD &y)
+{
+	RECT rect;
+
+	if (GetClientRect(Window, &rect))
+	{
+		x = SWORD(x * Width / (rect.right - rect.left));
+		y = SWORD(y * TrueHeight / (rect.bottom - rect.top));
+	}
+	// Subtract letterboxing borders
+	y -= (TrueHeight - Height) / 2;
+}
+
 bool DDrawFB::IsValid ()
 {
 	return PrimarySurf != NULL;
diff --git a/src/win32/i_input.cpp b/src/win32/i_input.cpp
index ed7c81cf1..a26ff320e 100644
--- a/src/win32/i_input.cpp
+++ b/src/win32/i_input.cpp
@@ -323,11 +323,11 @@ bool GUIWndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESU
 			if (BlockMouseMove > 0) return true;
 		}
 
+		ev.data1 = LOWORD(lParam);
+		ev.data2 = HIWORD(lParam);
+		if (screen != NULL)
 		{
-			int shift = screen? screen->GetPixelDoubling() : 0;
-			ev.data1 = LOWORD(lParam) >> shift; 
-			ev.data2 = HIWORD(lParam) >> shift; 
-			if (screen) ev.data2 -= (screen->GetTrueHeight() - screen->GetHeight())/2;
+			screen->ScaleCoordsFromWindow(ev.data1, ev.data2);
 		}
 
 		if (wParam & MK_SHIFT)				ev.data3 |= GKM_SHIFT;
diff --git a/src/win32/win32iface.h b/src/win32/win32iface.h
index 2704de0fa..9699157cd 100644
--- a/src/win32/win32iface.h
+++ b/src/win32/win32iface.h
@@ -164,8 +164,8 @@ public:
 	void SetVSync (bool vsync);
 	void NewRefreshRate();
 	HRESULT GetHR ();
-	virtual int GetTrueHeight() { return TrueHeight; }
 	bool Is8BitMode();
+	void ScaleCoordsFromWindow(SWORD &x, SWORD &y);
 
 	void Blank ();
 	bool PaintToWindow ();
@@ -269,8 +269,8 @@ public:
 	bool WipeDo(int ticks);
 	void WipeCleanup();
 	HRESULT GetHR ();
-	virtual int GetTrueHeight() { return TrueHeight; }
 	bool Is8BitMode() { return false; }
+	void ScaleCoordsFromWindow(SWORD &x, SWORD &y);
 
 private:
 	friend class D3DTex;
@@ -380,7 +380,6 @@ private:
 	void EndLineBatch();
 	void EndBatch();
 	void CopyNextFrontBuffer();
-	int GetPixelDoubling() const { return PixelDoubling; }
 
 	D3DCAPS9 DeviceCaps;