diff --git a/src/conio/ciolib.c b/src/conio/ciolib.c
index a0528467e488b3e06c2007abc1b9cc09cf3a98f6..065a81389c8823c64538bfa9861a9ab3b96e1aba 100644
--- a/src/conio/ciolib.c
+++ b/src/conio/ciolib.c
@@ -139,6 +139,7 @@ int try_sdl_init(int mode)
 #endif
 		cio_api.setfont=sdl_setfont;
 		cio_api.getfont=sdl_getfont;
+		cio_api.loadfont=sdl_loadfont;
 		return(1);
 	}
 	return(0);
@@ -172,6 +173,7 @@ int try_x_init(int mode)
 		cio_api.getcliptext=x_getcliptext;
 		cio_api.setfont=x_setfont;
 		cio_api.getfont=x_getfont;
+		cio_api.loadfont=x_loadfont;
 		return(1);
 	}
 	return(0);
@@ -979,3 +981,13 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_getfont(void)
 	else
 		return(-1);
 }
+
+CIOLIBEXPORT int CIOLIBCALL ciolib_loadfont(char *filename)
+{
+	CIOLIB_INIT();
+
+	if(cio_api.loadfont!=NULL)
+		return(cio_api.loadfont(filename));
+	else
+		return(-1);
+}
diff --git a/src/conio/ciolib.h b/src/conio/ciolib.h
index 222ff21acf55b2cf4d785fe52dfb3d251116ac11..4ee8e4d940c33cea569151572d21a8797bce3989 100644
--- a/src/conio/ciolib.h
+++ b/src/conio/ciolib.h
@@ -243,6 +243,7 @@ typedef struct {
 	void	(*resume)		(void);
 	int		(*setfont)		(int font, int force);
 	int		(*getfont)		(void);
+	int		(*loadfont)		(char *filename);
 } cioapi_t;
 
 CIOLIBEXPORTVAR cioapi_t cio_api;
@@ -298,6 +299,7 @@ CIOLIBEXPORT void CIOLIBCALL ciolib_copytext(const char *text, size_t buflen);
 CIOLIBEXPORT char * CIOLIBCALL ciolib_getcliptext(void);
 CIOLIBEXPORT int CIOLIBCALL ciolib_setfont(int font, int force);
 CIOLIBEXPORT int CIOLIBCALL ciolib_getfont(void);
+CIOLIBEXPORT int CIOLIBCALL ciolib_loadfont(char *filename);
 #ifdef __cplusplus
 }
 #endif
@@ -346,6 +348,7 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_getfont(void);
 	#define getcliptext()			ciolib_getcliptext()
 	#define setfont(a,b)			ciolib_setfont(a,b)
 	#define getfont()				ciolib_getfont()
+	#define loadfont(a)				ciolib_loadfont(a)
 #endif
 
 /* Special hackery for SDL */
diff --git a/src/conio/console.c b/src/conio/console.c
index 1d1a7b13bd46ec911d896e8c64b02ebac23c5a56..2a38654a8a6d963de9ec16be23419300d23f240d 100644
--- a/src/conio/console.c
+++ b/src/conio/console.c
@@ -111,6 +111,7 @@
 
 #include <threadwrap.h>
 #include <genwrap.h>
+#include <dirwrap.h>
 
 #include "console.h"
 #include "vidmodes.h"
@@ -130,6 +131,10 @@ sem_t	copybuf_set;
 sem_t	pastebuf_set;
 sem_t	pastebuf_request;
 sem_t	font_set;
+sem_t	x11_loadfont;
+sem_t	x11_fontloaded;
+int		x_load_font_ret;
+char	font_filename[MAX_PATH];
 int		new_font=-1;
 int		font_force;
 int		setfont_return;
@@ -154,7 +159,7 @@ WORD *vmem=NULL;
 static int show = 1;
 BYTE CursRow=0;
 BYTE CursCol=0;
-static int x_current_font=-1;
+static int x_current_font=-99;
 typedef struct TextLine {
     WORD	*data;
     u_char	max_length;	/* Not used, but here for future use */
@@ -1152,6 +1157,10 @@ video_async_event(void *crap)
 					x11.XBell(dpy, 0);
 				if(!sem_trywait(&x11_name))
 					x11.XSetIconName(dpy, win, window_name);
+				if(!sem_trywait(&x11_loadfont)) {
+					x_load_font_ret=load_font(font_filename,FW,FH,FontScale);
+					sem_post(&x11_fontloaded);
+				}
 				if(!sem_trywait(&x11_title))
 					x11.XStoreName(dpy, win, window_title);
 				if(!sem_trywait(&copybuf_set)) {
@@ -1329,13 +1338,13 @@ load_font(char *filename, int width, int height, int scale)
 	char *scaledfont;
 	char fontdata[256*16];
 	int	i,j;
+	static char current_filename[MAX_PATH];
+	FILE	*fontfile;
+	
+	if(height > 16)
+		return(-1);
 
-	/* I don't actually do this yet! */
-	if(filename != NULL) {
-		return(1);
-	}
-
-	if(x_current_font<0 || x_current_font>(sizeof(conio_fontdata)/sizeof(struct conio_font_data_struct)-2)) {
+	if(x_current_font==-99 || x_current_font>(sizeof(conio_fontdata)/sizeof(struct conio_font_data_struct)-2)) {
 		for(i=0; conio_fontdata[i].desc != NULL; i++) {
 			if(!strcmp(conio_fontdata[i].desc, "Codepage 437 English")) {
 				x_current_font=i;
@@ -1346,33 +1355,51 @@ load_font(char *filename, int width, int height, int scale)
 			x_current_font=0;
 		new_font=x_current_font;
 	}
-	if(conio_fontdata[x_current_font].desc==NULL)
+	if(x_current_font==-1)
+		filename=current_filename;
+	else if(conio_fontdata[x_current_font].desc==NULL)
 		return(-1);
 
-	switch(width) {
-		case 8:
-			switch(height) {
-				case 8:
-					font=conio_fontdata[x_current_font].eight_by_eight;
-					break;
-				case 14:
-					font=conio_fontdata[x_current_font].eight_by_fourteen;
-					break;
-				case 16:
-					font=conio_fontdata[x_current_font].eight_by_sixteen;
-					break;
-				default:
-					return(1);
-			}
-			break;
-		default:
+	if(filename != NULL) {
+		if(flength(filename)!=height*256)
+			return(-1);
+		if((fontfile=fopen(filename,"rb"))==NULL)
+			return(-1);
+		if(fread(fontdata, 1, height*256, fontfile)!=height*256) {
+			fclose(fontfile);
+			return(-1);
+		}
+		fclose(fontfile);
+		x_current_font=-1;
+		if(filename != current_filename)
+			SAFECOPY(current_filename,filename);
+	}
+	else {
+		switch(width) {
+			case 8:
+				switch(height) {
+					case 8:
+						font=conio_fontdata[x_current_font].eight_by_eight;
+						break;
+					case 14:
+						font=conio_fontdata[x_current_font].eight_by_fourteen;
+						break;
+					case 16:
+						font=conio_fontdata[x_current_font].eight_by_sixteen;
+						break;
+					default:
+						return(1);
+				}
+				break;
+			default:
+				return(1);
+		}
+		if(font==NULL)
 			return(1);
+		memcpy(fontdata, font, height*256);
 	}
-	if(font==NULL)
-		return(1);
 	FW = width;
     FH = height;
-	memcpy(fontdata, font, height*256);
 	/* Swap bit order... leftmost bit is most significant, X11 wants it the
 	 * other way. */
 	for(i=0; i<256; i++) {
@@ -1693,6 +1720,9 @@ console_init()
 	sem_init(&x11_title,0,0);
 	sem_init(&x11_name,0,0);
 	sem_init(&font_set,0,0);
+	sem_init(&x11_loadfont,0,0);
+	sem_init(&x11_fontloaded,0,0);
+
 	pthread_mutex_init(&copybuf_mutex, NULL);
 	pthread_mutex_init(&lines_mutex, NULL);
 
@@ -1821,3 +1851,11 @@ void x_win_name(const char *name)
 	SAFECOPY(window_name,name);
 	sem_post(&x11_name);
 }
+
+int x_load_font(const char *filename)
+{
+	SAFECOPY(font_filename, filename);
+	sem_post(&x11_loadfont);
+	sem_wait(&x11_fontloaded);
+	return(x_load_font_ret);
+}
diff --git a/src/conio/console.h b/src/conio/console.h
index 5d8c475267e021508fa552a414afca5ef515f59c..d87b009a5beedd4f2f7cb485f114a7b94a680e3e 100644
--- a/src/conio/console.h
+++ b/src/conio/console.h
@@ -87,6 +87,7 @@ int tty_kbhit(void);
 void tty_beep(void);
 void x_win_title(const char *title);
 int console_init(void);
+int x_load_font(const char *filename);
 
 #define	TTYF_BLOCK	0x00000008
 #define	TTYF_POLL	0x00000010
diff --git a/src/conio/sdl_con.c b/src/conio/sdl_con.c
index 37620aa2decc521239d277899ee757e80295dc38..a8e53f3ebd2b4ff3ba9ecbd62fa69a14d65c0a56 100644
--- a/src/conio/sdl_con.c
+++ b/src/conio/sdl_con.c
@@ -12,6 +12,7 @@
 
 #include "gen_defs.h"
 #include "genwrap.h"
+#include "dirwrap.h"
 #include "xpbeep.h"
 
 #if (defined CIOLIB_IMPORTS)
@@ -49,8 +50,11 @@ SDL_Surface	*win=NULL;
 SDL_mutex *sdl_keylock;
 SDL_mutex *sdl_updlock;
 SDL_mutex *sdl_vstatlock;
+SDL_mutex *sdl_ufunc_lock;
 SDL_sem *sdl_key_pending;
 SDL_sem *sdl_init_complete;
+SDL_sem *sdl_ufunc_ret;
+int sdl_ufunc_retval;
 int	sdl_init_good=0;
 int sdl_updated;
 int sdl_exitcode=0;
@@ -60,7 +64,7 @@ SDL_Surface	*sdl_cursor=NULL;
 
 static int lastcursor_x=0;
 static int lastcursor_y=0;
-static int sdl_current_font=-1;
+static int sdl_current_font=-99;
 static int lastfg=-1;
 static int lastbg=-1;
 
@@ -101,6 +105,7 @@ enum {
 	,SDL_USEREVENT_INIT
 	,SDL_USEREVENT_COPY
 	,SDL_USEREVENT_PASTE
+	,SDL_USEREVENT_LOADFONT
 };
 
 const struct sdl_keyvals sdl_keyval[] =
@@ -293,6 +298,44 @@ void sdl_user_func(int func, ...)
 	va_end(argptr);
 }
 
+/* Called from main thread only */
+int sdl_user_func_ret(int func, ...)
+{
+	unsigned int	*i;
+	va_list argptr;
+	void	**args;
+	SDL_Event	ev;
+	int		passed=FALSE;
+	char	*p;
+
+	sdl.mutexP(sdl_ufunc_lock);
+	ev.type=SDL_USEREVENT;
+	ev.user.data1=NULL;
+	ev.user.data2=NULL;
+	ev.user.code=func;
+	va_start(argptr, func);
+	switch(func) {
+		case SDL_USEREVENT_LOADFONT:
+			p=va_arg(argptr, char *);
+			if(p!=NULL) {
+				if((ev.user.data1=strdup(p))==NULL) {
+					va_end(argptr);
+					return;
+				}
+			}
+			while(sdl.PeepEvents(&ev, 1, SDL_ADDEVENT, 0xffffffff)!=1);
+			passed=TRUE;
+			break;
+	}
+	if(passed)
+		sdl.SemWait(sdl_ufunc_ret);
+	else
+		sdl_ufunc_retval=-1;
+	sdl.mutexV(sdl_ufunc_lock);
+	va_end(argptr);
+	return(sdl_ufunc_retval);
+}
+
 #if (defined(__MACH__) && defined(__APPLE__))
 int sdl_using_quartz=0;
 #endif
@@ -827,10 +870,23 @@ int sdl_hidemouse(void)
 	return(0);
 }
 
+int sdl_loadfont(char *filename)
+{
+	int retval;
+
+	FREE_AND_NULL(last_vmem);
+	retval=sdl_user_func_ret(SDL_USEREVENT_LOADFONT,filename);
+	sdl_user_func(SDL_USEREVENT_UPDATERECT,0,0,0,0);
+	return(retval);
+}
+
 int sdl_setfont(int font, int force)
 {
 	int changemode=0;
 
+	if(font < 0 || font>(sizeof(conio_fontdata)/sizeof(struct conio_font_data_struct)-2))
+		return(-1);
+
 	switch(vstat.charheight) {
 		case 8:
 			if(conio_fontdata[font].eight_by_eight==NULL) {
@@ -861,7 +917,7 @@ int sdl_setfont(int font, int force)
 	if(changemode)
 		sdl_init_mode(3);
 	FREE_AND_NULL(last_vmem);
-	sdl_load_font(NULL);
+	sdl_user_func_ret(SDL_USEREVENT_LOADFONT,0,0,0,0);
 	sdl_user_func(SDL_USEREVENT_UPDATERECT,0,0,0,0);
 	return(0);
 }
@@ -907,6 +963,7 @@ void sdl_add_key(unsigned int keyval)
 /* Called from event thread only */
 int sdl_load_font(char *filename)
 {
+	static char current_filename[MAX_PATH];
 	unsigned char *font;
 	unsigned int fontsize;
 	int fw;
@@ -917,12 +974,9 @@ int sdl_load_font(char *filename)
 	int charrow;
 	int charcol;
 	SDL_Rect r;
+	FILE	*fontfile;
 
-	/* I don't actually do this yet! */
-	if(filename != NULL)
-		return(-1);
-
-	if(sdl_current_font<0 || sdl_current_font>(sizeof(conio_fontdata)/sizeof(struct conio_font_data_struct)-2)) {
+	if(sdl_current_font==-99 || sdl_current_font>(sizeof(conio_fontdata)/sizeof(struct conio_font_data_struct)-2)) {
 		for(x=0; conio_fontdata[x].desc != NULL; x++) {
 			if(!strcmp(conio_fontdata[x].desc, "Codepage 437 English")) {
 				sdl_current_font=x;
@@ -932,7 +986,9 @@ int sdl_load_font(char *filename)
 		if(conio_fontdata[x].desc==NULL)
 			sdl_current_font=0;
 	}
-	if(conio_fontdata[sdl_current_font].desc==NULL)
+	if(sdl_current_font==-1)
+		filename=current_filename;
+	else if(conio_fontdata[sdl_current_font].desc==NULL)
 		return(-1);
 
 	sdl.mutexP(sdl_vstatlock);
@@ -946,43 +1002,67 @@ int sdl_load_font(char *filename)
 		return(-1);
 	}
 
-	switch(vstat.charwidth) {
-		case 8:
-			switch(vstat.charheight) {
-				case 8:
-					if(conio_fontdata[sdl_current_font].eight_by_eight==NULL) {
-						sdl.mutexV(sdl_vstatlock);
-						free(font);
-						return(-1);
-					}
-					memcpy(font, conio_fontdata[sdl_current_font].eight_by_eight, fontsize);
-					break;
-				case 14:
-					if(conio_fontdata[sdl_current_font].eight_by_fourteen==NULL) {
-						sdl.mutexV(sdl_vstatlock);
-						free(font);
-						return(-1);
-					}
-					memcpy(font, conio_fontdata[sdl_current_font].eight_by_fourteen, fontsize);
-					break;
-				case 16:
-					if(conio_fontdata[sdl_current_font].eight_by_sixteen==NULL) {
-						sdl.mutexV(sdl_vstatlock);
-						free(font);
-						return(-1);
-					}
-					memcpy(font, conio_fontdata[sdl_current_font].eight_by_sixteen, fontsize);
-					break;
-				default:
-					sdl.mutexV(sdl_vstatlock);
-					free(font);
-					return(-1);
-			}
-			break;
-		default:
+	if(filename != NULL) {
+		if(flength(filename)!=fontsize) {
+			sdl.mutexV(sdl_vstatlock);
+			free(font);
+			return(-1);
+		}
+		if((fontfile=fopen(filename,"rb"))==NULL) {
+			sdl.mutexV(sdl_vstatlock);
+			free(font);
+			return(-1);
+		}
+		if(fread(font, 1, fontsize, fontfile)!=fontsize) {
 			sdl.mutexV(sdl_vstatlock);
 			free(font);
+			fclose(fontfile);
 			return(-1);
+		}
+		fclose(fontfile);
+		sdl_current_font=-1;
+		if(filename != current_filename)
+			SAFECOPY(current_filename,filename);
+	}
+	else {
+		switch(vstat.charwidth) {
+			case 8:
+				switch(vstat.charheight) {
+					case 8:
+						if(conio_fontdata[sdl_current_font].eight_by_eight==NULL) {
+							sdl.mutexV(sdl_vstatlock);
+							free(font);
+							return(-1);
+						}
+						memcpy(font, conio_fontdata[sdl_current_font].eight_by_eight, fontsize);
+						break;
+					case 14:
+						if(conio_fontdata[sdl_current_font].eight_by_fourteen==NULL) {
+							sdl.mutexV(sdl_vstatlock);
+							free(font);
+							return(-1);
+						}
+						memcpy(font, conio_fontdata[sdl_current_font].eight_by_fourteen, fontsize);
+						break;
+					case 16:
+						if(conio_fontdata[sdl_current_font].eight_by_sixteen==NULL) {
+							sdl.mutexV(sdl_vstatlock);
+							free(font);
+							return(-1);
+						}
+						memcpy(font, conio_fontdata[sdl_current_font].eight_by_sixteen, fontsize);
+						break;
+					default:
+						sdl.mutexV(sdl_vstatlock);
+						free(font);
+						return(-1);
+				}
+				break;
+			default:
+				sdl.mutexV(sdl_vstatlock);
+				free(font);
+				return(-1);
+		}
 	}
 
 	if(sdl_font!=NULL)
@@ -1255,9 +1335,11 @@ int main(int argc, char **argv)
 
 		sdl_key_pending=sdl.SDL_CreateSemaphore(0);
 		sdl_init_complete=sdl.SDL_CreateSemaphore(0);
+		sdl_ufunc_ret=sdl.SDL_CreateSemaphore(0);
 		sdl_updlock=sdl.SDL_CreateMutex();
 		sdl_keylock=sdl.SDL_CreateMutex();
 		sdl_vstatlock=sdl.SDL_CreateMutex();
+		sdl_ufunc_lock=sdl.SDL_CreateMutex();
 #if !defined(NO_X) && defined(__unix__)
 		sdl_pastebuf_set=sdl.SDL_CreateSemaphore(0);
 		sdl_pastebuf_copied=sdl.SDL_CreateSemaphore(0);
@@ -1411,6 +1493,11 @@ int main(int argc, char **argv)
 					case SDL_USEREVENT: {
 						/* Tell SDL to do various stuff... */
 						switch(ev.user.code) {
+							case SDL_USEREVENT_LOADFONT:
+								sdl_ufunc_retval=sdl_load_font((char *)ev.user.data1);
+								FREE_AND_NULL(ev.user.data1);
+								sdl.SemPost(sdl_ufunc_ret);
+								break;
 							case SDL_USEREVENT_UPDATERECT:
 								sdl_full_screen_redraw();
 								break;
diff --git a/src/conio/sdl_con.h b/src/conio/sdl_con.h
index 5a62ef37eec1a399b24282a626cf213b7d259850..6ed46311e01a1c92e43dc44f9e5b872f16b0f841 100644
--- a/src/conio/sdl_con.h
+++ b/src/conio/sdl_con.h
@@ -37,6 +37,7 @@ void sdl_copytext(const char *text, size_t buflen);
 char *sdl_getcliptext(void);
 int sdl_setfont(int font, int force);
 int sdl_getfont(void);
+int sdl_loadfont(char *filename);
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/conio/x_cio.c b/src/conio/x_cio.c
index e75c9200ed3eb1de710160a6b9ff43e594d0e2fc..1038945d557b488f3ec30114e35a7971cea579c4 100644
--- a/src/conio/x_cio.c
+++ b/src/conio/x_cio.c
@@ -330,3 +330,8 @@ int x_getfont(void)
 {
 	return(new_font);
 }
+
+int x_loadfont(char *filename)
+{
+	return(x_load_font(filename));
+}
diff --git a/src/conio/x_cio.h b/src/conio/x_cio.h
index 067a926055a95bbaec9b2e880890226da20fd398..5b9d5c8d61f1c681cff0ff2b9824199395751d8a 100644
--- a/src/conio/x_cio.h
+++ b/src/conio/x_cio.h
@@ -67,6 +67,7 @@ void x_copytext(const char *text, size_t buflen);
 char *x_getcliptext(void);
 int x_setfont(int font, int force);
 int x_getfont(void);
+int x_loadfont(char *filename);
 #ifdef __cplusplus
 }
 #endif