SDL-1.2: atari:video:gem: refactor using recent gemlib

From 84d8e33b72d03c024b7b4f327bb1e14ff38cd621 Mon Sep 17 00:00:00 2001
From: Thorsten Otto <[EMAIL REDACTED]>
Date: Thu, 21 Dec 2023 09:23:42 +0100
Subject: [PATCH] atari:video:gem: refactor using recent gemlib

---
 src/video/gem/SDL_gemevents.c |  99 ++++++--------
 src/video/gem/SDL_gemvideo.c  | 237 +++++++++++++++++-----------------
 src/video/gem/SDL_gemvideo.h  |  18 +--
 src/video/gem/SDL_gemwm.c     |   2 +-
 4 files changed, 165 insertions(+), 191 deletions(-)

diff --git a/src/video/gem/SDL_gemevents.c b/src/video/gem/SDL_gemevents.c
index f8a267658..512771012 100644
--- a/src/video/gem/SDL_gemevents.c
+++ b/src/video/gem/SDL_gemevents.c
@@ -84,12 +84,14 @@ void GEM_InitOSKeymap(_THIS)
 
 void GEM_PumpEvents(_THIS)
 {
-	short prevkc=0, mousex, mousey, mouseb, kstate;
+	short prevkc=0, mousex, mousey, mouseb;
 	int i, quit = 0;
 	SDL_keysym keysym;
 	Uint32 cur_tick;
 	static Uint32 prev_now = 0, prev_msg = 0;
 	static short latest_msg_id = 0;
+	EVMULT_IN em_in;
+	EVMULT_OUT em_out;
 
 	cur_tick = SDL_GetTicks();
 	if (prev_now == cur_tick) {
@@ -114,19 +116,14 @@ void GEM_PumpEvents(_THIS)
 		--latest_msg_id;
 	}
 
+	em_in.emi_flags = MU_MESAG|MU_TIMER|MU_KEYBD;
+	em_in.emi_tlow = 1000;
+	em_in.emi_thigh = 0;
 	while (!quit) {
 		int resultat;
-		short buffer[8], kc, dummy;
-
-		resultat = evnt_multi(
-			MU_MESAG|MU_TIMER|MU_KEYBD,
-			0,0,0,
-			0,0,0,0,0,
-			0,0,0,0,0,
-			buffer,
-			1000,
-			&dummy,&dummy,&dummy,&kstate,&kc,&dummy
-		);
+		short buffer[8];
+
+		resultat = evnt_multi_fast(&em_in, buffer, &em_out);
 
 		/* Message event ? */
 		if (resultat & MU_MESAG)
@@ -134,10 +131,10 @@ void GEM_PumpEvents(_THIS)
 
 		/* Keyboard event ? */
 		if (resultat & MU_KEYBD) {
-			do_keyboard_special(kstate, cur_tick);
-			if (prevkc != kc) {
-				do_keyboard(kc, cur_tick);
-				prevkc = kc;
+			do_keyboard_special(em_out.emo_kmeta, cur_tick);
+			if (prevkc != em_out.emo_kreturn) {
+				do_keyboard(em_out.emo_kreturn, cur_tick);
+				prevkc = em_out.emo_kreturn;
 			}
 		}
 
@@ -150,8 +147,8 @@ void GEM_PumpEvents(_THIS)
 	GEM_CheckMouseMode(this);
 
 	/* Update mouse state */
-	graf_mkstate(&mousex, &mousey, &mouseb, &kstate);
-	do_keyboard_special(kstate, cur_tick);
+	graf_mkstate(&mousex, &mousey, &mouseb, &em_out.emo_kmeta);
+	do_keyboard_special(em_out.emo_kmeta, cur_tick);
 	do_mouse_motion(this, mousex, mousey);
 	do_mouse_buttons(this, mouseb);
 
@@ -160,12 +157,12 @@ void GEM_PumpEvents(_THIS)
 		/* Key pressed ? */
 		if (gem_currentkeyboard[i] && !gem_previouskeyboard[i])
 			SDL_PrivateKeyboard(SDL_PRESSED,
-				SDL_Atari_TranslateKey(i, &keysym, SDL_TRUE, kstate));
+				SDL_Atari_TranslateKey(i, &keysym, SDL_TRUE, em_out.emo_kmeta));
 
 		/* Key unpressed ? */
 		if (gem_previouskeyboard[i] && !gem_currentkeyboard[i])
 			SDL_PrivateKeyboard(SDL_RELEASED,
-				SDL_Atari_TranslateKey(i, &keysym, SDL_FALSE, kstate));
+				SDL_Atari_TranslateKey(i, &keysym, SDL_FALSE, em_out.emo_kmeta));
 	}
 
 	SDL_memcpy(gem_previouskeyboard,gem_currentkeyboard,sizeof(gem_previouskeyboard));
@@ -176,10 +173,7 @@ void GEM_PumpEvents(_THIS)
 			(SDL_GetAppState() & SDL_APPACTIVE)
 			? GEM_title_name : GEM_icon_name;
 		if (window_name) {
-			wind_set(GEM_handle,WF_NAME,
-				(short)(((unsigned long)window_name)>>16),
-				(short)(((unsigned long)window_name) & 0xffff),
-				0,0);
+			wind_set_str(GEM_handle,WF_NAME,window_name);
 		}
 		GEM_refresh_name = SDL_FALSE;
 	}
@@ -200,11 +194,11 @@ static int do_messages(_THIS, short *message, short latest_msg_id)
 			quit=1;
 			break;
 		case WM_MOVED:
-			wind_set(message[3],WF_CURRXYWH,message[4],message[5],message[6],message[7]);
+			wind_set_grect(message[3],WF_CURRXYWH,(GRECT *)&message[4]);
 			update_work_area = 1;
 			break;
 		case WM_TOPPED:
-			wind_set(message[3],WF_TOP,message[4],0,0,0);
+			wind_set_int(message[3],WF_TOP,message[4]);
 			/* Continue with TOP event processing */
 		case WM_ONTOP:
 			SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
@@ -212,12 +206,12 @@ static int do_messages(_THIS, short *message, short latest_msg_id)
 			break;
 		case WM_REDRAW:
 			if (!GEM_lock_redraw) {
-				GEM_wind_redraw(this, message[3], &message[4], SDL_FALSE);
+				GEM_wind_redraw(this, message[3], (GRECT *)&message[4], SDL_FALSE);
 			}
 			break;
 		case WM_ICONIFY:
 		case WM_ALLICONIFY:
-			wind_set (message[3],WF_ICONIFY,message[4],message[5],message[6],message[7]);
+			wind_set_grect (message[3],WF_ICONIFY,(GRECT *)&message[4]);
 			/* If we're active, make ourselves inactive */
 			if ( SDL_GetAppState() & SDL_APPACTIVE ) {
 				/* Send an internal deactivate event */
@@ -225,59 +219,50 @@ static int do_messages(_THIS, short *message, short latest_msg_id)
 			}
 			/* Update window title */
 			if (GEM_refresh_name && GEM_icon_name) {
-				wind_set(GEM_handle,WF_NAME,
-					(short)(((unsigned long)GEM_icon_name)>>16),
-					(short)(((unsigned long)GEM_icon_name) & 0xffff),
-					0,0);
+				wind_set_str(GEM_handle,WF_NAME, GEM_icon_name);
 				GEM_refresh_name = SDL_FALSE;
 			}
 			GEM_iconified = SDL_TRUE;
 			update_work_area = 1;
 			break;
 		case WM_UNICONIFY:
-			wind_set (message[3],WF_UNICONIFY,message[4],message[5],message[6],message[7]);
+			wind_set_grect (message[3],WF_UNICONIFY, (GRECT *)&message[4]);
 			/* If we're not active, make ourselves active */
 			if ( !(SDL_GetAppState() & SDL_APPACTIVE) ) {
 				/* Send an internal activate event */
 				SDL_PrivateAppActive(1, SDL_APPACTIVE);
 			}
 			if (GEM_refresh_name && GEM_title_name) {
-				wind_set(GEM_handle,WF_NAME,
-					(short)(((unsigned long)GEM_title_name)>>16),
-					(short)(((unsigned long)GEM_title_name) & 0xffff),
-					0,0);
+				wind_set_str(GEM_handle,WF_NAME, GEM_title_name);
 				GEM_refresh_name = SDL_FALSE;
 			}
 			GEM_iconified = SDL_FALSE;
 			update_work_area = 1;
 			break;
 		case WM_SIZED:
-			wind_set (message[3], WF_CURRXYWH, message[4], message[5], message[6], message[7]);
+			wind_set_grect (message[3], WF_CURRXYWH, (GRECT *)&message[4]);
 			update_work_area = sdl_resize = 1;
 			GEM_win_fulled = SDL_FALSE;		/* Cancel maximized flag */
 			GEM_lock_redraw = SDL_TRUE;		/* Prevent redraw till buffers resized */
 			break;
 		case WM_FULLED:
 			{
-				short x,y,w,h;
+				GRECT gr;
 
 				if (GEM_win_fulled) {
-					wind_get (message[3], WF_PREVXYWH, &x, &y, &w, &h);
+					wind_get_grect (message[3], WF_PREVXYWH, &gr);
 					GEM_win_fulled = SDL_FALSE;
 				} else {
-					x = GEM_desk_x;
-					y = GEM_desk_y;
-					w = GEM_desk_w;
-					h = GEM_desk_h;
+					gr = GEM_desk;
 					GEM_win_fulled = SDL_TRUE;
 				}
-				wind_set (message[3], WF_CURRXYWH, x, y, w, h);
+				wind_set_grect (message[3], WF_CURRXYWH, &gr);
 				update_work_area = sdl_resize = 1;
 				GEM_lock_redraw = SDL_TRUE;		/* Prevent redraw till buffers resized */
 			}
 			break;
 		case WM_BOTTOMED:
-			wind_set(message[3],WF_BOTTOM,0,0,0,0);
+			wind_set_int(message[3],WF_BOTTOM,0);
 			/* Continue with BOTTOM event processing */
 		case WM_UNTOPPED:
 			SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS);
@@ -289,7 +274,7 @@ static int do_messages(_THIS, short *message, short latest_msg_id)
 		GEM_align_work_area(this, message[3], SDL_TRUE);
 
 		if (sdl_resize) {
-			SDL_PrivateResize(GEM_work_w, GEM_work_h);
+			SDL_PrivateResize(GEM_work.g_w, GEM_work.g_h);
 		}
 	}
 
@@ -361,10 +346,10 @@ static void do_mouse_motion(_THIS, short mx, short my)
 	w2 = VDI_w;
 	h2 = VDI_h;
 	if ((!GEM_fullscreen) && (GEM_handle>=0)) {
-		x2 = GEM_work_x;
-		y2 = GEM_work_y;
-		w2 = GEM_work_w;
-		h2 = GEM_work_h;
+		x2 = GEM_work.g_x;
+		y2 = GEM_work.g_y;
+		w2 = GEM_work.g_w;
+		h2 = GEM_work.g_h;
 	}
 
 	if ((prevmx!=mx) || (prevmy!=my)) {
@@ -416,17 +401,17 @@ static void do_mouse_buttons(_THIS, short mb)
 /* Check if mouse in visible area of the window */
 static int mouse_in_work_area(int winhandle, short mx, short my)
 {
-	short todo[4];
-	short inside[4] = {mx,my,1,1};
+	GRECT todo;
+	GRECT inside = {mx,my,1,1};
 
 	/* Browse the rectangle list */
-	if (wind_get(winhandle, WF_FIRSTXYWH, &todo[0], &todo[1], &todo[2], &todo[3])!=0) {
-		while (todo[2] && todo[3]) {
-			if (rc_intersect((GRECT *)inside,(GRECT *)todo)) {
+	if (wind_get_grect(winhandle, WF_FIRSTXYWH, &todo)!=0) {
+		while (todo.g_w && todo.g_h) {
+			if (rc_intersect(&inside, &todo)) {
 				return 1;
 			}
 
-			if (wind_get(winhandle, WF_NEXTXYWH, &todo[0], &todo[1], &todo[2], &todo[3])==0) {
+			if (wind_get_grect(winhandle, WF_NEXTXYWH, &todo)==0) {
 				break;
 			}
 		}
diff --git a/src/video/gem/SDL_gemvideo.c b/src/video/gem/SDL_gemvideo.c
index c67a60aec..29c236929 100644
--- a/src/video/gem/SDL_gemvideo.c
+++ b/src/video/gem/SDL_gemvideo.c
@@ -96,11 +96,11 @@ static void GEM_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
 static void GEM_FreeBuffers(_THIS);
 static void GEM_ClearScreen(_THIS);
 static void GEM_ClearRect(_THIS, short *pxy);
-static void GEM_ClearRectXYWH(_THIS, short *rect);
+static void GEM_ClearRectXYWH(_THIS, GRECT *rect);
 static void GEM_SetNewPalette(_THIS, Uint16 newpal[256][3]);
 static void GEM_LockScreen(_THIS);
 static void GEM_UnlockScreen(_THIS);
-static void refresh_window(_THIS, int winhandle, short *rect, SDL_bool pad_only);
+static void refresh_window(_THIS, int winhandle, GRECT *rect, SDL_bool pad_only);
 
 #if SDL_VIDEO_OPENGL
 /* OpenGL functions */
@@ -338,7 +338,13 @@ static void VDI_ReadExtInfo(_THIS, short *work_out)
 int GEM_VideoInit(_THIS, SDL_PixelFormat *vformat)
 {
 	int i, menubar_size;
-	short work_in[12], work_out[272], dummy;
+	short work_in[12];
+	/*
+	 * The standalone enhancer.prg has a bug
+	 * and copies 273 values here
+	 */
+	short work_out[273];
+	short dummy;
 
 	/* Open AES (Application Environment Services) */
 	GEM_ap_id = internal_ap_id;
@@ -384,15 +390,12 @@ int GEM_VideoInit(_THIS, SDL_PixelFormat *vformat)
 	VDI_h = work_out[1] + 1;
 
 	/* Read desktop size and position */
-	if (!wind_get(DESKTOP_HANDLE, WF_WORKXYWH, &GEM_desk_x, &GEM_desk_y, &GEM_desk_w, &GEM_desk_h)) {
+	if (!wind_get_grect(DESKTOP_HANDLE, WF_WORKXYWH, &GEM_desk)) {
 		fprintf(stderr,"Can not read desktop properties\n");
 		return 1;
 	}
 
-	GEM_work_x = GEM_desk_x;
-	GEM_work_y = GEM_desk_y;
-	GEM_work_w = GEM_desk_w;
-	GEM_work_h = GEM_desk_h;
+	GEM_work = GEM_desk;
 
 	/* Read bit depth */
 	vq_extnd(VDI_handle, 1, work_out);
@@ -493,7 +496,7 @@ int GEM_VideoInit(_THIS, SDL_PixelFormat *vformat)
 	vsf_perimeter(VDI_handle,0);
 
 	/* Menu bar save buffer */
-	menubar_size = GEM_desk_w * GEM_desk_y * VDI_pixelsize;
+	menubar_size = GEM_desk.g_w * GEM_desk.g_y * VDI_pixelsize;
 	GEM_menubar=Atari_SysMalloc(menubar_size,MX_PREFTTRAM);
 
 	/* Fill video modes list */
@@ -564,14 +567,14 @@ void GEM_ClearRect(_THIS, short *pxy)
 	vs_color(VDI_handle, 0, oldrgb);
 }
 
-void GEM_ClearRectXYWH(_THIS, short *rect)
+void GEM_ClearRectXYWH(_THIS, GRECT *rect)
 {
 	short pxy[4];
 
-	pxy[0] = rect[0];
-	pxy[1] = rect[1];
-	pxy[2] = rect[0]+rect[2]-1;
-	pxy[3] = rect[1]+rect[3]-1;
+	pxy[0] = rect->g_x;
+	pxy[1] = rect->g_y;
+	pxy[2] = rect->g_x+rect->g_w-1;
+	pxy[3] = rect->g_y+rect->g_h-1;
 
 	GEM_ClearRect(this, pxy);
 }
@@ -614,9 +617,9 @@ static void GEM_LockScreen(_THIS)
 			short blitcoords[8];
 
 			mfdb_src.fd_addr=GEM_menubar;
-			mfdb_src.fd_w=GEM_desk_w;
-			mfdb_src.fd_h=GEM_desk_y;
-			mfdb_src.fd_wdwidth=GEM_desk_w>>4;
+			mfdb_src.fd_w=GEM_desk.g_w;
+			mfdb_src.fd_h=GEM_desk.g_y;
+			mfdb_src.fd_wdwidth=GEM_desk.g_w>>4;
 			mfdb_src.fd_nplanes=VDI_bpp;
 			mfdb_src.fd_stand=
 				mfdb_src.fd_r1=
@@ -625,8 +628,8 @@ static void GEM_LockScreen(_THIS)
 
 			blitcoords[0] = blitcoords[4] = 0;
 			blitcoords[1] = blitcoords[5] = 0;
-			blitcoords[2] = blitcoords[6] = GEM_desk_w-1;
-			blitcoords[3] = blitcoords[7] = GEM_desk_y-1;
+			blitcoords[2] = blitcoords[6] = GEM_desk.g_w-1;
+			blitcoords[3] = blitcoords[7] = GEM_desk.g_y-1;
 
 			vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &VDI_dst_mfdb, &mfdb_src);
 		}
@@ -644,9 +647,9 @@ static void GEM_UnlockScreen(_THIS)
 			short blitcoords[8];
 
 			mfdb_src.fd_addr=GEM_menubar;
-			mfdb_src.fd_w=GEM_desk_w;
-			mfdb_src.fd_h=GEM_desk_y;
-			mfdb_src.fd_wdwidth=GEM_desk_w>>4;
+			mfdb_src.fd_w=GEM_desk.g_w;
+			mfdb_src.fd_h=GEM_desk.g_y;
+			mfdb_src.fd_wdwidth=GEM_desk.g_w>>4;
 			mfdb_src.fd_nplanes=VDI_bpp;
 			mfdb_src.fd_stand=
 				mfdb_src.fd_r1=
@@ -655,8 +658,8 @@ static void GEM_UnlockScreen(_THIS)
 
 			blitcoords[0] = blitcoords[4] = 0;
 			blitcoords[1] = blitcoords[5] = 0;
-			blitcoords[2] = blitcoords[6] = GEM_desk_w-1;
-			blitcoords[3] = blitcoords[7] = GEM_desk_y-1;
+			blitcoords[2] = blitcoords[6] = GEM_desk.g_w-1;
+			blitcoords[3] = blitcoords[7] = GEM_desk.g_y-1;
 
 			vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb);
 		}
@@ -772,7 +775,7 @@ SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current,
 		GEM_fullscreen = SDL_TRUE;
 	} else {
 		int old_win_type;
-		short x2,y2,w2,h2;
+		GRECT gr;
 
 		GEM_UnlockScreen(this);
 
@@ -793,29 +796,33 @@ SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current,
 		/* Recreate window ? only for different widget or non-created window */
 		if ((old_win_type != GEM_win_type) || (GEM_handle < 0)) {
 			/* Calculate window size */
-			if (!wind_calc(WC_BORDER, GEM_win_type, 0,0,width+16,height, &x2,&y2,&w2,&h2)) {
+			gr.g_x = 0;
+			gr.g_y = 0;
+			gr.g_w = width + 16;
+			gr.g_h = height;
+			if (!wind_calc_grect(WC_BORDER, GEM_win_type, &gr, &gr)) {
 				GEM_FreeBuffers(this);
 				SDL_SetError("Can not calculate window attributes");
 				return NULL;
 			}
 
 			/* Center window */
-			x2 = (GEM_desk_w-w2)>>1;
-			y2 = (GEM_desk_h-h2)>>1;
-			if (x2<0) {
-				x2 = 0;
+			gr.g_x = (GEM_desk.g_w-gr.g_w)>>1;
+			gr.g_y = (GEM_desk.g_h-gr.g_h)>>1;
+			if (gr.g_x<0) {
+				gr.g_x = 0;
 			}
-			if (y2<0) {
-				y2 = 0;
+			if (gr.g_y<0) {
+				gr.g_y = 0;
 			}
-			x2 += GEM_desk_x;
-			y2 += GEM_desk_y;
+			gr.g_x += GEM_desk.g_x;
+			gr.g_y += GEM_desk.g_y;
 
 			/* Align work area on 16 pixels boundary (faster for bitplanes modes) */
-			wind_calc(WC_WORK, GEM_win_type, x2,y2,w2,h2, &x2,&y2,&w2,&h2);
-			x2 &= ~15;
-			x2 -= 8;
-			wind_calc(WC_BORDER, GEM_win_type, x2,y2,w2,h2, &x2,&y2,&w2,&h2);
+			wind_calc_grect(WC_WORK, GEM_win_type, &gr, &gr);
+			gr.g_x &= ~15;
+			gr.g_x -= 8;
+			wind_calc_grect(WC_BORDER, GEM_win_type, &gr, &gr);
 
 			/* Destroy existing window */
 			if (GEM_handle >= 0) {
@@ -824,7 +831,7 @@ SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current,
 			}
 
 			/* Create window */
-			GEM_handle=wind_create(GEM_win_type, x2,y2,w2,h2);
+			GEM_handle=wind_create_grect(GEM_win_type, &gr);
 			if (GEM_handle<0) {
 				GEM_FreeBuffers(this);
 				SDL_SetError("Can not create window");
@@ -836,21 +843,20 @@ SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current,
 #endif
 
 			/* Setup window name */
-			wind_set(GEM_handle,WF_NAME,
-				(short)(((unsigned long)GEM_title_name)>>16),
-				(short)(((unsigned long)GEM_title_name) & 0xffff),
-				0,0);
+			wind_set_str(GEM_handle,WF_NAME,GEM_title_name);
 			GEM_refresh_name = SDL_FALSE;
 
 			/* Open the window */
-			wind_open(GEM_handle,x2,y2,w2,h2);
+			wind_open_grect(GEM_handle,&gr);
 
 			GEM_iconified = SDL_FALSE;
 		} else {
 			/* Resize window to fit asked video mode */
-			wind_get (GEM_handle, WF_WORKXYWH, &x2,&y2,&w2,&h2);
-			if (wind_calc(WC_BORDER, GEM_win_type, x2,y2,width+16,height, &x2,&y2,&w2,&h2)) {
-				wind_set (GEM_handle, WF_CURRXYWH, x2,y2,w2,h2);
+			wind_get_grect (GEM_handle, WF_WORKXYWH, &gr);
+			gr.g_w = width;
+			gr.g_h = height;
+			if (wind_calc_grect(WC_BORDER, GEM_win_type, &gr, &gr)) {
+				wind_set_grect (GEM_handle, WF_CURRXYWH, &gr);
 			}
 		}
 
@@ -898,40 +904,40 @@ void GEM_align_work_area(_THIS, short windowid, SDL_bool clear_pads)
 {
 	int new_x, new_w, old_x, old_w;
 
-	wind_get(windowid, WF_WORKXYWH, &GEM_work_x,&GEM_work_y,&GEM_work_w,&GEM_work_h);
+	wind_get_grect(windowid, WF_WORKXYWH, &GEM_work);
 	if (GEM_iconified) {
 		return;
 	}
 
 	/* Align work area on 16 pixels boundary (faster for bitplanes modes) */
-	new_x = old_x = GEM_work_x;
-	new_w = old_w = GEM_work_w;
+	new_x = old_x = GEM_work.g_x;
+	new_w = old_w = GEM_work.g_w;
 	if (new_x & 15) {
 		new_x = (new_x|15)+1;
 	} else {
 		new_w -= 16;
 	}
-	new_w -= (new_x - GEM_work_x);
+	new_w -= (new_x - GEM_work.g_x);
 	new_w &= ~15;
 
-	GEM_work_x = new_x;
-	GEM_work_w = new_w;
+	GEM_work.g_x = new_x;
+	GEM_work.g_w = new_w;
 
 	if (clear_pads) {
-		short rect[4];
+		GRECT rect;
 
-		rect[1] = GEM_work_y;
-		rect[3] = GEM_work_h;
+		rect.g_y = GEM_work.g_y;
+		rect.g_h = GEM_work.g_h;
 
 		/* Left padding */
-		rect[0] = old_x;
-		rect[2] = new_x-old_x+1;
-		GEM_wind_redraw(this, GEM_handle, rect, SDL_TRUE);
+		rect.g_x = old_x;
+		rect.g_w = new_x-old_x+1;
+		GEM_wind_redraw(this, GEM_handle, &rect, SDL_TRUE);
 
 		/* Right padding */
-		rect[0] = new_x + new_w;
-		rect[2] = (old_w-new_w)-(new_x-old_x)+1;
-		GEM_wind_redraw(this, GEM_handle, rect, SDL_TRUE);
+		rect.g_x = new_x + new_w;
+		rect.g_w = (old_w-new_w)-(new_x-old_x)+1;
+		GEM_wind_redraw(this, GEM_handle, &rect, SDL_TRUE);
 	}
 }
 
@@ -1036,16 +1042,16 @@ static void GEM_UpdateRectsFullscreen(_THIS, int numrects, SDL_Rect *rects)
 
 static void GEM_UpdateRectsWindowed(_THIS, int numrects, SDL_Rect *rects)
 {
-	short rect[4];
+	GRECT rect;
 	int i;
 
 	for ( i=0; i<numrects; ++i ) {
-		rect[0] = GEM_work_x + rects[i].x;
-		rect[1] = GEM_work_y + rects[i].y;
-		rect[2] = rects[i].w;
-		rect[3] = rects[i].h;
+		rect.g_x = GEM_work.g_x + rects[i].x;
+		rect.g_y = GEM_work.g_y + rects[i].y;
+		rect.g_w = rects[i].w;
+		rect.g_h = rects[i].h;
 
-		GEM_wind_redraw(this, GEM_handle, rect, SDL_FALSE);
+		GEM_wind_redraw(this, GEM_handle, &rect, SDL_FALSE);
 	}
 }
 
@@ -1127,15 +1133,8 @@ static int GEM_FlipHWSurfaceFullscreen(_THIS, SDL_Surface *surface)
 
 static int GEM_FlipHWSurfaceWindowed(_THIS, SDL_Surface *surface)
 {
-	short rect[4];
-
 	/* Update the whole window */
-	rect[0] = GEM_work_x;
-	rect[1] = GEM_work_y;
-	rect[2] = GEM_work_w;
-	rect[3] = GEM_work_h;
-
-	GEM_wind_redraw(this, GEM_handle, rect, SDL_FALSE);
+	GEM_wind_redraw(this, GEM_handle, &GEM_work, SDL_FALSE);
 
 	return(0);
 }
@@ -1242,9 +1241,9 @@ void GEM_VideoQuit(_THIS)
 	this->screen->pixels = NULL;
 }
 
-void GEM_wind_redraw(_THIS, int winhandle, short *inside, SDL_bool pad_only)
+void GEM_wind_redraw(_THIS, int winhandle, const GRECT *inside, SDL_bool pad_only)
 {
-	short todo[4];
+	GRECT todo;
 
 	/* Tell AES we are going to update */
 	wind_update(BEG_UPDATE);
@@ -1252,15 +1251,15 @@ void GEM_wind_redraw(_THIS, int winhandle, short *inside, SDL_bool pad_only)
 	v_hide_c(VDI_handle);
 
 	/* Browse the rectangle list to redraw */
-	if (wind_get(winhandle, WF_FIRSTXYWH, &todo[0], &todo[1], &todo[2], &todo[3])!=0) {
+	if (wind_get_grect(winhandle, WF_FIRSTXYWH, &todo)!=0) {
 
-		while (todo[2] && todo[3]) {
+		while (todo.g_w && todo.g_h) {
 
-			if (rc_intersect((GRECT *)inside,(GRECT *)todo)) {
-				refresh_window(this, winhandle, todo, pad_only);
+			if (rc_intersect(inside, &todo)) {
+				refresh_window(this, winhandle, &todo, pad_only);
 			}
 
-			if (wind_get(winhandle, WF_NEXTXYWH, &todo[0], &todo[1], &todo[2], &todo[3])==0) {
+			if (wind_get_grect(winhandle, WF_NEXTXYWH, &todo)==0) {
 				break;
 			}
 		}
@@ -1273,32 +1272,30 @@ void GEM_wind_redraw(_THIS, int winhandle, short *inside, SDL_bool pad_only)
 	v_show_c(VDI_handle,1);
 }
 
-static void refresh_window(_THIS, int winhandle, short *rect, SDL_bool pad_only)
+static void refresh_window(_THIS, int winhandle, GRECT *rect, SDL_bool pad_only)
 {
 	MFDB mfdb_src;
-	short pxy[8], work_rect[4];
+	short pxy[8];
+	GRECT work_rect;
 	SDL_Surface *surface;
 	int max_width, max_height;
 
-	work_rect[0] = GEM_work_x;
-	work_rect[1] = GEM_work_y;
-	work_rect[2] = GEM_work_w;
-	work_rect[3] = GEM_work_h;
+	work_rect = GEM_work;
 
 	/* Clip against screen */
-	if (work_rect[0]<0) {
-		work_rect[2] += work_rect[0];
-		work_rect[0] = 0;
+	if (work_rect.g_x<0) {
+		work_rect.g_w += work_rect.g_x;
+		work_rect.g_x = 0;
 	}
-	if (work_rect[0]+work_rect[2]>=VDI_w) {
-		work_rect[2] = VDI_w-work_rect[0];
+	if (work_rect.g_x+work_rect.g_w>=VDI_w) {
+		work_rect.g_w = VDI_w-work_rect.g_x;
 	}
-	if (work_rect[1]<0) {
-		work_rect[3] += work_rect[1];
-		work_rect[1] = 0;
+	if (work_rect.g_y<0) {
+		work_rect.g_h += work_rect.g_y;
+		work_rect.g_y = 0;
 	}
-	if (work_rect[1]+work_rect[3]>=VDI_h) {
-		work_rect[3] = VDI_h-work_rect[1];
+	if (work_rect.g_y+work_rect.g_h>=VDI_h) {
+		work_rect.g_h = VDI_h-work_rect.g_y;
 	}
 
 	surface = this->screen;
@@ -1312,53 +1309,53 @@ static void refresh_window(_THIS, int winhandle, short *rect, SDL_bool pad_only)
 		}
 
 		/* Center icon inside window if it is smaller */
-		if (GEM_work_w>surface->w) {
-			work_rect[0] += (GEM_work_w-surface->w)>>1;
-			work_rect[2] = surface->w;
+		if (GEM_work.g_w>surface->w) {
+			work_rect.g_x += (GEM_work.g_w-surface->w)>>1;
+			work_rect.g_w = surface->w;
 		}
-		if (GEM_work_h>surface->h) {
-			work_rect[1] += (GEM_work_h-surface->h)>>1;
-			work_rect[3] = surface->h;
+		if (GEM_work.g_h>surface->h) {
+			work_rect.g_y += (GEM_work.g_h-surface->h)>>1;
+			work_rect.g_h = surface->h;
 		}
 	} else {
 		/* Y1,Y2 for padding zones */
-		pxy[1] = rect[1];
-		pxy[3] = rect[1]+rect[3]-1;
+		pxy[1] = rect->g_y;
+		pxy[3] = rect->g_y+rect->g_h-1;
 
 		/* Clear left padding zone ? */
-		pxy[0] = rect[0];
-		pxy[2] = MIN(rect[0]+rect[2]-1, GEM_work_x-1);
+		pxy[0] = rect->g_x;
+		pxy[2] = MIN(rect->g_x+rect->g_w-1, GEM_work.g_x-1);
 		if (pxy[0]<=pxy[2]) {
 			GEM_ClearRect(this, pxy);
 		}
 
 		/* Clear right padding zone ? */
-		pxy[0] = MAX(rect[0], GEM_work_x+GEM_work_w);
-		pxy[2] = rect[0]+rect[2]-1;
+		pxy[0] = MAX(rect->g_x, GEM_work.g_x+GEM_work.g_w);
+		pxy[2] = rect->g_x+rect->g_w-1;
 		if (pxy[0]<=pxy[2]) {
 			GEM_ClearRect(this, pxy);
 		}
 	}
 
 	/* Do we intersect zone to redraw ? */
-	if (pad_only || !rc_intersect((GRECT *)work_rect, (GRECT *)rect)) {
+	if (pad_only || !rc_intersect(&work_rect, rect)) {
 		return;
 	}
 
 	/* Calculate intersection rectangle to redraw */
-	max_width = MIN(work_rect[2], rect[2]);
-	max_height = MIN(work_rect[3], rect[3]);
+	max_width = MIN(work_rect.g_w, rect->g_w);
+	max_height = MIN(work_rect.g_h, rect->g_h);
 
-	pxy[4]=pxy[0]=MAX(work_rect[0],rect[0]);
-	pxy[5]=pxy[1]=MAX(work_rect[1],rect[1]);
+	pxy[4]=pxy[0]=MAX(work_rect.g_x,rect->g_x);
+	pxy[5]=pxy[1]=MAX(work_rect.g_y,rect->g_y);
 	pxy[6]=pxy[2]=pxy[0]+max_width-1;
 	pxy[7]=pxy[3]=pxy[1]+max_height-1;
 
 	/* Calculate source image pos relative to window */
-	pxy[0] -= GEM_work_x;
-	pxy[1] -= GEM_work_y;
-	pxy[2] -= GEM_work_x;
-	pxy[3] -= GEM_work_y;
+	pxy[0] -= GEM_work.g_x;
+	pxy[1] -= GEM_work.g_y;
+	pxy[2] -= GEM_work.g_x;
+	pxy[3] -= GEM_work.g_y;
 
 #if DEBUG_VIDEO_GEM
 	printf("sdl:video:gem: redraw %dx%d: (%d,%d,%d,%d) to (%d,%d,%d,%d)\n",
diff --git a/src/video/gem/SDL_gemvideo.h b/src/video/gem/SDL_gemvideo.h
index d5f6fcbf2..e769cab7b 100644
--- a/src/video/gem/SDL_gemvideo.h
+++ b/src/video/gem/SDL_gemvideo.h
@@ -36,7 +36,7 @@ struct WMcursor {
 #define _THIS	SDL_VideoDevice *this
 
 /* Functions prototypes */
-void GEM_wind_redraw(_THIS, int winhandle, short *inside, SDL_bool pad_only);
+void GEM_wind_redraw(_THIS, int winhandle, const GRECT *inside, SDL_bool pad_only);
 void GEM_align_work_area(_THIS, short windowid, SDL_bool clear_pads);
 
 /* Private display data */
@@ -72,12 +72,10 @@ struct SDL_PrivateVideoData {
 
 	/* GEM infos */
 	short ap_id;
-	short desk_x, desk_y;		/* Desktop properties */
-	short desk_w, desk_h;
+	GRECT desk;					/* Desktop properties */
 	short win_handle;			/* Our window handle */
 	int window_type;			/* Window type */
-	short work_x, work_y;		/* Window work area x,y,w,h */
-	short work_w, work_h;
+	GRECT work;					/* Window work area x,y,w,h */
 	const char *title_name;		/* Window title */
 	const char *icon_name;		/* Icon title */
 	short version;				/* AES version */
@@ -121,16 +119,10 @@ struct SDL_PrivateVideoData {
 #define VDI_dst_mfdb		(this->hidden->dst_mfdb)
 
 #define GEM_ap_id			(this->hidden->ap_id)
-#define GEM_desk_x			(this->hidden->desk_x)
-#define GEM_desk_y			(this->hidden->desk_y)
-#define GEM_desk_w			(this->hidden->desk_w)
-#define GEM_desk_h			(this->hidden->desk_h)
+#define GEM_desk			(this->hidden->desk)
 #define GEM_handle			(this->hidden->win_handle)
 #define GEM_win_type		(this->hidden->window_type)
-#define GEM_work_x			(this->hidden->work_x)
-#define GEM_work_y			(this->hidden->work_y)
-#define GEM_work_w			(this->hidden->work_w)
-#define GEM_work_h			(this->hidden->work_h)
+#define GEM_work			(this->hidden->work)
 #define GEM_title_name		(this->hidden->title_name)
 #define GEM_icon_name		(this->hidden->icon_name)
 #define GEM_refresh_name	(this->hidden->refresh_name)
diff --git a/src/video/gem/SDL_gemwm.c b/src/video/gem/SDL_gemwm.c
index 10776fd2e..89613f88d 100644
--- a/src/video/gem/SDL_gemwm.c
+++ b/src/video/gem/SDL_gemwm.c
@@ -97,7 +97,7 @@ int GEM_IconifyWindow(_THIS)
 	GEM_message[2] = 0;
 	GEM_message[3] = GEM_handle;
 	GEM_message[4] = 0;
-	GEM_message[5] = GEM_desk_h-ICONHEIGHT;
+	GEM_message[5] = GEM_desk.g_h-ICONHEIGHT;
 	GEM_message[6] = ICONWIDTH;
 	GEM_message[7] = ICONHEIGHT;