diff --git a/src/conio/sdl_con.c b/src/conio/sdl_con.c
index 1e36b4697adb87fb451c01c78dcba415bc678e4c..e151e0b655ab88bb30ae7a7f8a65caed92da4eb6 100644
--- a/src/conio/sdl_con.c
+++ b/src/conio/sdl_con.c
@@ -65,19 +65,6 @@ pthread_mutex_t sdl_keylock;
 sem_t sdl_key_pending;
 static unsigned int sdl_pending_mousekeys=0;
 
-/*
- * TODO:
- * The intent of this was a copy of current vstat that
- * does not require vstatlock to be held.
- *
- * Unfortunately, this is accessed from multiple threads
- * currently (at least main and video events), so it
- * requires *a* lock, and vstatlock is used for that purpose.
- * This should either have its own lock, or be used *only*
- * from a single thread.
- */
-static struct video_stats cvstat;
-
 struct sdl_keyvals {
 	int	keysym
 		,key
@@ -200,7 +187,7 @@ const struct sdl_keyvals sdl_keyval[] =
 };
 
 void sdl_video_event_thread(void *data);
-static void setup_surfaces_locked(void);
+static void setup_surfaces_locked(struct video_stats *vs);
 
 static void sdl_user_func(int func, ...)
 {
@@ -348,25 +335,29 @@ void sdl_flush(void)
  * vstat lock must be held
  */
 static bool
-window_can_scale_internally(int winwidth, int winheight)
+window_can_scale_internally(struct video_stats *vs)
 {
 	int fw, fh;
-	aspect_fix(&winwidth, &winheight, cvstat.aspect_width, cvstat.aspect_height);
-	fw = winwidth;
-	fh = winheight;
-	aspect_reverse(&winwidth, &winheight, cvstat.scrnwidth, cvstat.scrnheight, cvstat.aspect_width, cvstat.aspect_height);
-	if (fw == winwidth || fh == winheight)
+	int ww = vs->winwidth;
+	int wh = vs->winheight;
+	aspect_fix(&ww, &wh, vs->aspect_width, vs->aspect_height);
+	fw = ww;
+	fh = wh;
+	aspect_reverse(&ww, &wh, vs->scrnwidth, vs->scrnheight, vs->aspect_width, vs->aspect_height);
+	if (fw == ww || fh == wh)
 		return true;
 	return false;
 }
 
 static void
-internal_scaling_factors(int winwidth, int winheight, int *x, int *y)
+internal_scaling_factors(int *x, int *y, struct video_stats *vs)
 {
-	aspect_fix_low(&winwidth, &winheight, cvstat.aspect_width, cvstat.aspect_height);
-	aspect_reverse(&winwidth, &winheight, cvstat.scrnwidth, cvstat.scrnheight, cvstat.aspect_width, cvstat.aspect_height);
-	*x = winwidth / cvstat.scrnwidth;
-	*y = winheight / cvstat.scrnheight;
+	int winwidth = vs->winwidth;
+	int winheight = vs->winheight;
+	aspect_fix_low(&winwidth, &winheight, vs->aspect_width, vs->aspect_height);
+	aspect_reverse(&winwidth, &winheight, vs->scrnwidth, vs->scrnheight, vs->aspect_width, vs->aspect_height);
+	*x = winwidth / vs->scrnwidth;
+	*y = winheight / vs->scrnheight;
 	if (*x < 1 || *x > 14)
 		*x = 1;
 	if (*y < 1 || *y > 14)
@@ -391,10 +382,10 @@ static int sdl_init_mode(int mode)
 
 	pthread_mutex_lock(&blinker_lock);
 	pthread_mutex_lock(&vstatlock);
-	oldcols = cvstat.cols;
+	oldcols = vstat.cols;
 	bitmap_drv_init_mode(mode, &bitmap_width, &bitmap_height);
-	if (cvstat.scrnwidth > 0) {
-		for (scaling = 1; (scaling + 1) * cvstat.scrnwidth < cvstat.winwidth; scaling++)
+	if (vstat.scrnwidth > 0) {
+		for (scaling = 1; (scaling + 1) * vstat.scrnwidth < vstat.winwidth; scaling++)
 			;
 	}
 	vstat.winwidth = vstat.scrnwidth * scaling;
@@ -423,15 +414,14 @@ static int sdl_init_mode(int mode)
 	if (vstat.winheight < vstat.scrnheight)
 		vstat.winheight = vstat.scrnheight;
 
-	cvstat = vstat;
-	internal_scaling = window_can_scale_internally(vstat.winwidth, vstat.winheight);
+	internal_scaling = window_can_scale_internally(&vstat);
 	pthread_mutex_lock(&sdl_mode_mutex);
 	sdl_mode = true;
 	pthread_mutex_unlock(&sdl_mode_mutex);
 	pthread_mutex_unlock(&vstatlock);
 	pthread_mutex_unlock(&blinker_lock);
 
-	sdl_user_func_ret(SDL_USEREVENT_SETVIDMODE, cvstat.winwidth, cvstat.winheight);
+	sdl_user_func_ret(SDL_USEREVENT_SETVIDMODE, vstat.winwidth, vstat.winheight);
 
 	return(0);
 }
@@ -466,22 +456,26 @@ int sdl_init(int mode)
 	return(-1);
 }
 
-static void internal_setwinsize(int w, int h)
+static void internal_setwinsize(struct video_stats *vs)
 {
-	pthread_mutex_lock(&vstatlock);
+	int w, h;
+
+	w = vs->winwidth;
+	h = vs->winheight;
 	if (w > 16384)
 		w = 16384;
 	if (h > 16384)
 		h = 16384;
-	if (w < cvstat.scrnwidth)
-		w = cvstat.scrnwidth;
-	if (h < cvstat.scrnheight)
-		h = cvstat.scrnheight;
-	cvstat.winwidth = vstat.winwidth = w;
-	cvstat.winheight = vstat.winheight = h;
-	internal_scaling = window_can_scale_internally(cvstat.winwidth, cvstat.winheight);
-	setup_surfaces_locked();
+	if (w < vs->scrnwidth)
+		w = vs->scrnwidth;
+	if (h < vs->scrnheight)
+		h = vs->scrnheight;
+	pthread_mutex_lock(&vstatlock);
+	vs->winwidth = vstat.winwidth = w;
+	vs->winheight = vstat.winheight = h;
 	pthread_mutex_unlock(&vstatlock);
+	internal_scaling = window_can_scale_internally(vs);
+	setup_surfaces_locked(vs);
 }
 
 void sdl_setwinsize(int w, int h)
@@ -499,9 +493,9 @@ void sdl_setwinposition(int x, int y)
 void sdl_getwinsize_locked(int *w, int *h)
 {
 	if (w)
-		*w = cvstat.winwidth;
+		*w = vstat.winwidth;
 	if (h)
-		*h = cvstat.winheight;
+		*h = vstat.winheight;
 }
 
 void sdl_getwinsize(int *w, int *h)
@@ -599,16 +593,16 @@ int sdl_get_window_info(int *width, int *height, int *xpos, int *ypos)
 	if (width || height) {
 		pthread_mutex_lock(&vstatlock);
 		if(width)
-			*width=cvstat.winwidth;
+			*width=vstat.winwidth;
 		if(height)
-			*height=cvstat.winheight;
+			*height=vstat.winheight;
 		pthread_mutex_unlock(&vstatlock);
 	}
 
 	return(1);
 }
 
-static void setup_surfaces_locked(void)
+static void setup_surfaces_locked(struct video_stats *vs)
 {
 	int		flags=0;
 	SDL_Event	ev;
@@ -627,25 +621,25 @@ static void setup_surfaces_locked(void)
 #endif
 
 	pthread_mutex_lock(&win_mutex);
-	idealmw = cvstat.scrnwidth;
-	idealmh = cvstat.scrnheight;
-	aspect_correct(&idealmw, &idealmh, cvstat.aspect_width, cvstat.aspect_height);
-	idealw = cvstat.winwidth;
-	idealh = cvstat.winheight;
-	internal_scaling = window_can_scale_internally(idealw, idealh);
+	idealmw = vs->scrnwidth;
+	idealmh = vs->scrnheight;
+	aspect_correct(&idealmw, &idealmh, vs->aspect_width, vs->aspect_height);
+	idealw = vs->winwidth;
+	idealh = vs->winheight;
+	internal_scaling = window_can_scale_internally(vs);
 	sdl.SetHint(SDL_HINT_RENDER_SCALE_QUALITY, internal_scaling ? "0" : "2");
 
 	if (win == NULL) {
 		// SDL2: This is slow sometimes... not sure why.
-		if (sdl.CreateWindowAndRenderer(cvstat.winwidth, cvstat.winheight, flags, &win, &renderer) == 0) {
+		if (sdl.CreateWindowAndRenderer(vs->winwidth, vs->winheight, flags, &win, &renderer) == 0) {
 			sdl.GetWindowSize(win, &idealw, &idealh);
-			cvstat.winwidth = idealw;
-			cvstat.winheight = idealh;
+			vs->winwidth = idealw;
+			vs->winheight = idealh;
 			sdl.RenderClear(renderer);
 			if (internal_scaling)
 				newtexture = sdl.CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, idealw, idealh);
 			else
-				newtexture = sdl.CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, cvstat.scrnwidth, cvstat.scrnheight);
+				newtexture = sdl.CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, vs->scrnwidth, vs->scrnheight);
 
 			if (texture)
 				sdl.DestroyTexture(texture);
@@ -660,12 +654,12 @@ static void setup_surfaces_locked(void)
 		sdl.SetWindowMinimumSize(win, idealmw, idealmh);
 		sdl.SetWindowSize(win, idealw, idealh);
 		sdl.GetWindowSize(win, &idealw, &idealh);
-		cvstat.winwidth = idealw;
-		cvstat.winheight = idealh;
+		vs->winwidth = idealw;
+		vs->winheight = idealh;
 		if (internal_scaling)
 			newtexture = sdl.CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, idealw, idealh);
 		else
-			newtexture = sdl.CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, cvstat.scrnwidth, cvstat.scrnheight);
+			newtexture = sdl.CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, vs->scrnwidth, vs->scrnheight);
 		sdl.RenderClear(renderer);
 		if (texture)
 			sdl.DestroyTexture(texture);
@@ -687,7 +681,7 @@ static void setup_surfaces_locked(void)
 static void setup_surfaces(void)
 {
 	pthread_mutex_lock(&vstatlock);
-	setup_surfaces_locked();
+	setup_surfaces_locked(&vstat);
 	pthread_mutex_unlock(&vstatlock);
 }
 
@@ -698,6 +692,7 @@ static void sdl_add_key(unsigned int keyval)
 		fullscreen=!fullscreen;
 		cio_api.mode=fullscreen?CIOLIB_MODE_SDL_FULLSCREEN:CIOLIB_MODE_SDL;
 		sdl.SetWindowFullscreen(win, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
+		// TODO: This uses vstat from the video event thread...
 		setup_surfaces();
 		return;
 	}
@@ -816,51 +811,43 @@ static void sdl_mouse_thread(void *data)
 	}
 }
 
-static int win_to_text_xpos(int winpos)
+static int win_to_text_xpos(int winpos, struct video_stats *vs)
 {
 	int ret;
 
-	pthread_mutex_lock(&vstatlock);
-	ret = winpos/(((float)cvstat.winwidth)/cvstat.cols)+1;
-	if (ret > cvstat.cols)
-		ret = cvstat.cols;
+	ret = winpos/(((float)vs->winwidth)/vs->cols)+1;
+	if (ret > vs->cols)
+		ret = vs->cols;
 	if (ret < 1)
 		ret = 1;
-	pthread_mutex_unlock(&vstatlock);
 	return ret;
 }
 
-static int win_to_text_ypos(int winpos)
+static int win_to_text_ypos(int winpos, struct video_stats *vs)
 {
 	int ret;
 
-	pthread_mutex_lock(&vstatlock);
-	ret = winpos/(((float)cvstat.winheight)/cvstat.rows)+1;
-	if (ret > cvstat.rows)
-		ret = cvstat.rows;
+	ret = winpos/(((float)vs->winheight)/vs->rows)+1;
+	if (ret > vs->rows)
+		ret = vs->rows;
 	if (ret < 1)
 		ret = 1;
-	pthread_mutex_unlock(&vstatlock);
 	return ret;
 }
 
-static int win_to_res_xpos(int winpos)
+static int win_to_res_xpos(int winpos, struct video_stats *vs)
 {
 	int ret;
 
-	pthread_mutex_lock(&vstatlock);
-	ret = winpos * (cvstat.scrnwidth) / cvstat.winwidth;
-	pthread_mutex_unlock(&vstatlock);
+	ret = winpos * (vs->scrnwidth) / vs->winwidth;
 	return ret;
 }
 
-static int win_to_res_ypos(int winpos)
+static int win_to_res_ypos(int winpos, struct video_stats *vs)
 {
 	int ret;
 
-	pthread_mutex_lock(&vstatlock);
-	ret = winpos * (cvstat.scrnheight) / cvstat.winheight;
-	pthread_mutex_unlock(&vstatlock);
+	ret = winpos * (vs->scrnheight) / vs->winheight;
 	return ret;
 }
 
@@ -870,6 +857,7 @@ void sdl_video_event_thread(void *data)
 	int		block_text = 0;
 	static SDL_Keycode last_sym = SDLK_UNKNOWN;
 	static Uint16 last_mod = 0;
+	struct video_stats cvstat = vstat;
 
 	while(1) {
 		if(sdl.WaitEventTimeout(&ev, 1)!=1)
@@ -888,7 +876,6 @@ void sdl_video_event_thread(void *data)
 						// Don't allow ALT-DIR to change size when maximized...
 						if ((sdl.GetWindowFlags(win) & SDL_WINDOW_MAXIMIZED) == 0) {
 							bool wc;
-							pthread_mutex_lock(&vstatlock);
 							w = cvstat.winwidth;
 							h = cvstat.winheight;
 							aspect_fix(&w, &h, cvstat.aspect_width, cvstat.aspect_height);
@@ -936,10 +923,9 @@ void sdl_video_event_thread(void *data)
 							else {
 								cvstat.winwidth = w;
 								cvstat.winheight = h;
-								internal_scaling = window_can_scale_internally(w, h);
+								internal_scaling = window_can_scale_internally(&cvstat);
 							}
-							setup_surfaces_locked();
-							pthread_mutex_unlock(&vstatlock);
+							setup_surfaces_locked(&cvstat);
 						}
 						break;
 					}
@@ -984,20 +970,20 @@ void sdl_video_event_thread(void *data)
 			case SDL_MOUSEMOTION:
 				if(!ciolib_mouse_initialized)
 					break;
-				ciomouse_gotevent(CIOLIB_MOUSE_MOVE,win_to_text_xpos(ev.motion.x),win_to_text_ypos(ev.motion.y), win_to_res_xpos(ev.motion.x), win_to_res_ypos(ev.motion.y));
+				ciomouse_gotevent(CIOLIB_MOUSE_MOVE,win_to_text_xpos(ev.motion.x, &cvstat),win_to_text_ypos(ev.motion.y, &cvstat), win_to_res_xpos(ev.motion.x, &cvstat), win_to_res_ypos(ev.motion.y, &cvstat));
 				break;
 			case SDL_MOUSEBUTTONDOWN:
 				if(!ciolib_mouse_initialized)
 					break;
 				switch(ev.button.button) {
 					case SDL_BUTTON_LEFT:
-						ciomouse_gotevent(CIOLIB_BUTTON_PRESS(1),win_to_text_xpos(ev.button.x),win_to_text_ypos(ev.button.y), win_to_res_xpos(ev.button.x), win_to_res_ypos(ev.button.y));
+						ciomouse_gotevent(CIOLIB_BUTTON_PRESS(1),win_to_text_xpos(ev.button.x, &cvstat),win_to_text_ypos(ev.button.y, &cvstat), win_to_res_xpos(ev.button.x, &cvstat), win_to_res_ypos(ev.button.y, &cvstat));
 						break;
 					case SDL_BUTTON_MIDDLE:
-						ciomouse_gotevent(CIOLIB_BUTTON_PRESS(2),win_to_text_xpos(ev.button.x),win_to_text_ypos(ev.button.y), win_to_res_xpos(ev.button.x), win_to_res_ypos(ev.button.y));
+						ciomouse_gotevent(CIOLIB_BUTTON_PRESS(2),win_to_text_xpos(ev.button.x, &cvstat),win_to_text_ypos(ev.button.y, &cvstat), win_to_res_xpos(ev.button.x, &cvstat), win_to_res_ypos(ev.button.y, &cvstat));
 						break;
 					case SDL_BUTTON_RIGHT:
-						ciomouse_gotevent(CIOLIB_BUTTON_PRESS(3),win_to_text_xpos(ev.button.x),win_to_text_ypos(ev.button.y), win_to_res_xpos(ev.button.x), win_to_res_ypos(ev.button.y));
+						ciomouse_gotevent(CIOLIB_BUTTON_PRESS(3),win_to_text_xpos(ev.button.x, &cvstat),win_to_text_ypos(ev.button.y, &cvstat), win_to_res_xpos(ev.button.x, &cvstat), win_to_res_ypos(ev.button.y, &cvstat));
 						break;
 				}
 				break;
@@ -1020,13 +1006,13 @@ void sdl_video_event_thread(void *data)
 					break;
 				switch(ev.button.button) {
 					case SDL_BUTTON_LEFT:
-						ciomouse_gotevent(CIOLIB_BUTTON_RELEASE(1),win_to_text_xpos(ev.button.x),win_to_text_ypos(ev.button.y), win_to_res_xpos(ev.button.x), win_to_res_ypos(ev.button.y));
+						ciomouse_gotevent(CIOLIB_BUTTON_RELEASE(1),win_to_text_xpos(ev.button.x, &cvstat),win_to_text_ypos(ev.button.y, &cvstat), win_to_res_xpos(ev.button.x, &cvstat), win_to_res_ypos(ev.button.y, &cvstat));
 						break;
 					case SDL_BUTTON_MIDDLE:
-						ciomouse_gotevent(CIOLIB_BUTTON_RELEASE(2),win_to_text_xpos(ev.button.x),win_to_text_ypos(ev.button.y), win_to_res_xpos(ev.button.x), win_to_res_ypos(ev.button.y));
+						ciomouse_gotevent(CIOLIB_BUTTON_RELEASE(2),win_to_text_xpos(ev.button.x, &cvstat),win_to_text_ypos(ev.button.y, &cvstat), win_to_res_xpos(ev.button.x, &cvstat), win_to_res_ypos(ev.button.y, &cvstat));
 						break;
 					case SDL_BUTTON_RIGHT:
-						ciomouse_gotevent(CIOLIB_BUTTON_RELEASE(3),win_to_text_xpos(ev.button.x),win_to_text_ypos(ev.button.y), win_to_res_xpos(ev.button.x), win_to_res_ypos(ev.button.y));
+						ciomouse_gotevent(CIOLIB_BUTTON_RELEASE(3),win_to_text_xpos(ev.button.x, &cvstat),win_to_text_ypos(ev.button.y, &cvstat), win_to_res_xpos(ev.button.x, &cvstat), win_to_res_ypos(ev.button.y, &cvstat));
 						break;
 				}
 				break;
@@ -1052,7 +1038,7 @@ void sdl_video_event_thread(void *data)
 							break;
 						}
 						pthread_mutex_unlock(&sdl_mode_mutex);
-						internal_setwinsize(ev.window.data1, ev.window.data2);
+						internal_setwinsize(&cvstat);
 						break;
 					case SDL_WINDOWEVENT_EXPOSED:
 						bitmap_drv_request_pixels();
@@ -1070,9 +1056,6 @@ void sdl_video_event_thread(void *data)
 						sem_post(&sdl_ufunc_ret);
 						return;
 					case SDL_USEREVENT_FLUSH:
-						pthread_mutex_lock(&vstatlock);
-						struct video_stats lvstat = cvstat;
-						pthread_mutex_unlock(&vstatlock);
 						pthread_mutex_lock(&win_mutex);
 						if (win != NULL) {
 							pthread_mutex_lock(&sdl_headlock);
@@ -1096,9 +1079,9 @@ void sdl_video_event_thread(void *data)
 									if (internal_scaling) {
 										struct graphics_buffer *gb;
 										int xscale, yscale;
-										internal_scaling_factors(lvstat.winwidth, lvstat.winheight, &xscale, &yscale);
+										internal_scaling_factors(&xscale, &yscale, &cvstat);
 										gb = do_scale(list, xscale, yscale,
-										    lvstat.aspect_width, lvstat.aspect_height);
+										    cvstat.aspect_width, cvstat.aspect_height);
 										src.x = 0;
 										src.y = 0;
 										src.w = gb->w;
@@ -1125,8 +1108,8 @@ void sdl_video_event_thread(void *data)
 											memcpy(pixels, gb->data, gb->w * ch * sizeof(gb->data[0]));
 										}
 										sdl.UnlockTexture(texture);
-										dst.x = (lvstat.winwidth - gb->w) / 2;
-										dst.y = (lvstat.winheight - gb->h) / 2;
+										dst.x = (cvstat.winwidth - gb->w) / 2;
+										dst.y = (cvstat.winheight - gb->h) / 2;
 										dst.w = gb->w;
 										dst.h = gb->h;
 										release_buffer(gb);
@@ -1158,12 +1141,12 @@ void sdl_video_event_thread(void *data)
 											memcpy(pixels, list->data, list->rect.width * ch * sizeof(list->data[0]));
 										}
 										sdl.UnlockTexture(texture);
-										dst.w = lvstat.winwidth;
-										dst.h = lvstat.winheight;
+										dst.w = cvstat.winwidth;
+										dst.h = cvstat.winheight;
 										// Get correct aspect ratio for dst...
-										aspect_fix(&dst.w, &dst.h, lvstat.aspect_width, lvstat.aspect_height);
-										dst.x = (lvstat.winwidth - dst.w) / 2;
-										dst.y = (lvstat.winheight - dst.h) / 2;
+										aspect_fix(&dst.w, &dst.h, cvstat.aspect_width, cvstat.aspect_height);
+										dst.x = (cvstat.winwidth - dst.w) / 2;
+										dst.y = (cvstat.winheight - dst.h) / 2;
 									}
 									if (sdl.RenderCopy(renderer, texture, &src, &dst))
 										fprintf(stderr, "RenderCopy() failed! (%s)\n", sdl.GetError());
@@ -1210,7 +1193,10 @@ void sdl_video_event_thread(void *data)
 						sdl_mode = false;
 						pthread_mutex_unlock(&sdl_mode_mutex);
 
-						internal_setwinsize(ev.user.data1 - NULL, ev.user.data2 - NULL);
+						pthread_mutex_lock(&vstatlock);
+						cvstat = vstat;
+						pthread_mutex_unlock(&vstatlock);
+						internal_setwinsize(&cvstat);
 						sdl_ufunc_retval=0;
 						sem_post(&sdl_ufunc_ret);
 						break;