symbian-qemu-0.9.1-12/libsdl-trunk/src/video/gem/SDL_gemvideo.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2     SDL - Simple DirectMedia Layer
       
     3     Copyright (C) 1997-2006 Sam Lantinga
       
     4 
       
     5     This library is free software; you can redistribute it and/or
       
     6     modify it under the terms of the GNU Lesser General Public
       
     7     License as published by the Free Software Foundation; either
       
     8     version 2.1 of the License, or (at your option) any later version.
       
     9 
       
    10     This library is distributed in the hope that it will be useful,
       
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    13     Lesser General Public License for more details.
       
    14 
       
    15     You should have received a copy of the GNU Lesser General Public
       
    16     License along with this library; if not, write to the Free Software
       
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
       
    18 
       
    19     Sam Lantinga
       
    20     slouken@libsdl.org
       
    21 */
       
    22 #include "SDL_config.h"
       
    23 
       
    24 /*
       
    25 	GEM video driver
       
    26 
       
    27 	Patrice Mandin
       
    28 	and work from
       
    29 	Olivier Landemarre, Johan Klockars, Xavier Joubert, Claude Attard
       
    30 */
       
    31 
       
    32 /* Mint includes */
       
    33 #include <gem.h>
       
    34 #include <gemx.h>
       
    35 #include <mint/osbind.h>
       
    36 #include <mint/cookie.h>
       
    37 
       
    38 #include "SDL_endian.h"
       
    39 #include "SDL_video.h"
       
    40 #include "SDL_mouse.h"
       
    41 #include "../SDL_sysvideo.h"
       
    42 #include "../SDL_pixels_c.h"
       
    43 #include "../../events/SDL_events_c.h"
       
    44 #include "../SDL_cursor_c.h"
       
    45 
       
    46 #include "../ataricommon/SDL_ataric2p_s.h"
       
    47 #include "../ataricommon/SDL_atarieddi_s.h"
       
    48 #include "../ataricommon/SDL_atarimxalloc_c.h"
       
    49 #include "../ataricommon/SDL_atarigl_c.h"
       
    50 
       
    51 #include "SDL_gemvideo.h"
       
    52 #include "SDL_gemevents_c.h"
       
    53 #include "SDL_gemmouse_c.h"
       
    54 #include "SDL_gemwm_c.h"
       
    55 #include "../ataricommon/SDL_xbiosevents_c.h"
       
    56 #include "../ataricommon/SDL_ataridevmouse_c.h"
       
    57 
       
    58 /* Defines */
       
    59 
       
    60 /*#define DEBUG_VIDEO_GEM	1*/
       
    61 
       
    62 #define GEM_VID_DRIVER_NAME "gem"
       
    63 
       
    64 #undef MIN
       
    65 #define MIN(a,b) (((a)<(b)) ? (a) : (b))
       
    66 #undef MAX
       
    67 #define MAX(a,b) (((a)>(b)) ? (a) : (b))
       
    68 
       
    69 /* Variables */
       
    70 
       
    71 static unsigned char vdi_index[256] = {
       
    72 	0,  2,  3,  6,  4,  7,  5,   8,
       
    73 	9, 10, 11, 14, 12, 15, 13, 255
       
    74 };
       
    75 
       
    76 static const unsigned char empty_name[]="";
       
    77 
       
    78 /* Initialization/Query functions */
       
    79 static int GEM_VideoInit(_THIS, SDL_PixelFormat *vformat);
       
    80 static SDL_Rect **GEM_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
       
    81 static SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
       
    82 static int GEM_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
       
    83 static void GEM_VideoQuit(_THIS);
       
    84 
       
    85 /* Hardware surface functions */
       
    86 static int GEM_AllocHWSurface(_THIS, SDL_Surface *surface);
       
    87 static int GEM_LockHWSurface(_THIS, SDL_Surface *surface);
       
    88 static int GEM_FlipHWSurface(_THIS, SDL_Surface *surface);
       
    89 static void GEM_UnlockHWSurface(_THIS, SDL_Surface *surface);
       
    90 static void GEM_FreeHWSurface(_THIS, SDL_Surface *surface);
       
    91 static void GEM_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
       
    92 #if 0
       
    93 static int GEM_ToggleFullScreen(_THIS, int on);
       
    94 #endif
       
    95 
       
    96 /* Internal functions */
       
    97 static void GEM_FreeBuffers(_THIS);
       
    98 static void GEM_ClearScreen(_THIS);
       
    99 static void GEM_ClearRect(_THIS, short *rect);
       
   100 static void GEM_SetNewPalette(_THIS, Uint16 newpal[256][3]);
       
   101 static void GEM_LockScreen(_THIS);
       
   102 static void GEM_UnlockScreen(_THIS);
       
   103 static void refresh_window(_THIS, int winhandle, short *rect);
       
   104 
       
   105 #if SDL_VIDEO_OPENGL
       
   106 /* OpenGL functions */
       
   107 static void GEM_GL_SwapBuffers(_THIS);
       
   108 #endif
       
   109 
       
   110 /* GEM driver bootstrap functions */
       
   111 
       
   112 static int GEM_Available(void)
       
   113 {
       
   114 	/* Test if AES available */
       
   115 	if (appl_init() == -1)
       
   116 		return 0;
       
   117 
       
   118 	appl_exit();
       
   119 	return 1;
       
   120 }
       
   121 
       
   122 static void GEM_DeleteDevice(SDL_VideoDevice *device)
       
   123 {
       
   124 	SDL_free(device->hidden);
       
   125 	SDL_free(device);
       
   126 }
       
   127 
       
   128 static SDL_VideoDevice *GEM_CreateDevice(int devindex)
       
   129 {
       
   130 	SDL_VideoDevice *device;
       
   131 	int vectors_mask;
       
   132 	unsigned long dummy;
       
   133 
       
   134 	/* Initialize all variables that we clean on shutdown */
       
   135 	device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
       
   136 	if ( device ) {
       
   137 		SDL_memset(device, 0, (sizeof *device));
       
   138 		device->hidden = (struct SDL_PrivateVideoData *)
       
   139 				SDL_malloc((sizeof *device->hidden));
       
   140 		device->gl_data = (struct SDL_PrivateGLData *)
       
   141 				SDL_malloc((sizeof *device->gl_data));
       
   142 	}
       
   143 	if ( (device == NULL) || (device->hidden == NULL) ) {
       
   144 		SDL_OutOfMemory();
       
   145 		if ( device ) {
       
   146 			SDL_free(device);
       
   147 		}
       
   148 		return(0);
       
   149 	}
       
   150 	SDL_memset(device->hidden, 0, (sizeof *device->hidden));
       
   151 	SDL_memset(device->gl_data, 0, sizeof(*device->gl_data));
       
   152 
       
   153 	/* Set the function pointers */
       
   154 	device->VideoInit = GEM_VideoInit;
       
   155 	device->ListModes = GEM_ListModes;
       
   156 	device->SetVideoMode = GEM_SetVideoMode;
       
   157 	device->SetColors = GEM_SetColors;
       
   158 	device->UpdateRects = NULL /*GEM_UpdateRects*/;
       
   159 	device->VideoQuit = GEM_VideoQuit;
       
   160 	device->AllocHWSurface = GEM_AllocHWSurface;
       
   161 	device->LockHWSurface = GEM_LockHWSurface;
       
   162 	device->UnlockHWSurface = GEM_UnlockHWSurface;
       
   163 	device->FlipHWSurface = GEM_FlipHWSurface;
       
   164 	device->FreeHWSurface = GEM_FreeHWSurface;
       
   165 	device->ToggleFullScreen = NULL /*GEM_ToggleFullScreen*/;
       
   166 
       
   167 	/* Window manager */
       
   168 	device->SetCaption = GEM_SetCaption;
       
   169 	device->SetIcon = GEM_SetIcon;
       
   170 	device->IconifyWindow = GEM_IconifyWindow;
       
   171 	device->GrabInput = GEM_GrabInput;
       
   172 
       
   173 	/* Events */
       
   174 	device->InitOSKeymap = GEM_InitOSKeymap;
       
   175 	device->PumpEvents = GEM_PumpEvents;
       
   176 
       
   177 	/* Mouse */
       
   178 	device->FreeWMCursor = GEM_FreeWMCursor;
       
   179 	device->CreateWMCursor = GEM_CreateWMCursor;
       
   180 	device->ShowWMCursor = GEM_ShowWMCursor;
       
   181 	device->WarpWMCursor = NULL /*GEM_WarpWMCursor*/;
       
   182 	device->CheckMouseMode = GEM_CheckMouseMode;
       
   183 
       
   184 #if SDL_VIDEO_OPENGL
       
   185 	/* OpenGL functions */
       
   186 	device->GL_LoadLibrary = SDL_AtariGL_LoadLibrary;
       
   187 	device->GL_GetProcAddress = SDL_AtariGL_GetProcAddress;
       
   188 	device->GL_GetAttribute = SDL_AtariGL_GetAttribute;
       
   189 	device->GL_MakeCurrent = SDL_AtariGL_MakeCurrent;
       
   190 	device->GL_SwapBuffers = GEM_GL_SwapBuffers;
       
   191 #endif
       
   192 
       
   193 	device->hidden->use_dev_mouse =
       
   194 		(SDL_AtariDevMouse_Open()!=0) ? SDL_TRUE : SDL_FALSE;
       
   195 
       
   196 	vectors_mask = ATARI_XBIOS_JOYSTICKEVENTS;	/* XBIOS joystick events */
       
   197 	if (!(device->hidden->use_dev_mouse)) {
       
   198 		vectors_mask |= ATARI_XBIOS_MOUSEEVENTS;	/* XBIOS mouse events */
       
   199 	}
       
   200 /*	if (Getcookie(C_MiNT, &dummy)==C_FOUND) {
       
   201 		vectors_mask = 0;
       
   202 	}*/
       
   203 
       
   204 	SDL_AtariXbios_InstallVectors(vectors_mask);
       
   205 
       
   206 	device->free = GEM_DeleteDevice;
       
   207 
       
   208 	return device;
       
   209 }
       
   210 
       
   211 VideoBootStrap GEM_bootstrap = {
       
   212 	GEM_VID_DRIVER_NAME, "Atari GEM video driver",
       
   213 	GEM_Available, GEM_CreateDevice
       
   214 };
       
   215 
       
   216 static void VDI_ReadExtInfo(_THIS, short *work_out)
       
   217 {
       
   218 	unsigned long EdDI_version;
       
   219 	unsigned long cookie_EdDI;
       
   220 	Uint32 num_colours;
       
   221 	Uint16 clut_type, num_bits;
       
   222 
       
   223 	/* Read EdDI informations */
       
   224 	if  (Getcookie(C_EdDI, &cookie_EdDI) == C_NOTFOUND) {
       
   225 		return;
       
   226 	}
       
   227 	
       
   228 	EdDI_version = Atari_get_EdDI_version( (void *)cookie_EdDI);
       
   229 
       
   230 	vq_scrninfo(VDI_handle, work_out);
       
   231 
       
   232 	VDI_format = work_out[0];
       
   233 	clut_type = work_out[1];
       
   234 	num_bits = work_out[2];
       
   235 	num_colours = *((Uint32 *) &work_out[3]);
       
   236 
       
   237 	/* With EdDI>=1.1, we can have screen pitch, address and format
       
   238 	 * so we can directly write to screen without using vro_cpyfm
       
   239 	 */
       
   240 	if (EdDI_version >= EDDI_11) {
       
   241 		VDI_pitch = work_out[5];
       
   242 		VDI_screen = (void *) *((unsigned long *) &work_out[6]);
       
   243 	}
       
   244 
       
   245 	switch(clut_type) {
       
   246 		case VDI_CLUT_HARDWARE:
       
   247 			{
       
   248 				int i;
       
   249 				Uint16 *tmp_p;
       
   250 
       
   251 				tmp_p = (Uint16 *)&work_out[16];
       
   252 
       
   253 				for (i=0;i<256;i++) {
       
   254 					vdi_index[*tmp_p++] = i;
       
   255 				}
       
   256 			}
       
   257 			break;
       
   258 		case VDI_CLUT_SOFTWARE:
       
   259 			{
       
   260 				int component; /* red, green, blue, alpha, overlay */
       
   261 				int num_bit;
       
   262 				unsigned short *tmp_p;
       
   263 
       
   264 				/* We can build masks with info here */
       
   265 				tmp_p = (unsigned short *) &work_out[16];
       
   266 				for (component=0;component<5;component++) {
       
   267 					for (num_bit=0;num_bit<16;num_bit++) {
       
   268 						unsigned short valeur;
       
   269 
       
   270 						valeur = *tmp_p++;
       
   271 
       
   272 						if (valeur == 0xffff) {
       
   273 							continue;
       
   274 						}
       
   275 
       
   276 						switch(component) {
       
   277 							case 0:
       
   278 								VDI_redmask |= 1<< valeur;
       
   279 								break;
       
   280 							case 1:
       
   281 								VDI_greenmask |= 1<< valeur;
       
   282 								break;
       
   283 							case 2:
       
   284 								VDI_bluemask |= 1<< valeur;
       
   285 								break;
       
   286 							case 3:
       
   287 								VDI_alphamask |= 1<< valeur;
       
   288 								break;
       
   289 						}
       
   290 					}
       
   291 				}
       
   292 			}
       
   293 
       
   294 			/* Remove lower green bits for Intel endian screen */
       
   295 			if ((VDI_greenmask == ((7<<13)|3)) || (VDI_greenmask == ((7<<13)|7))) {
       
   296 				VDI_greenmask &= ~(7<<13);
       
   297 			}
       
   298 			break;
       
   299 		case VDI_CLUT_NONE:
       
   300 			break;
       
   301 	}
       
   302 }
       
   303 
       
   304 int GEM_VideoInit(_THIS, SDL_PixelFormat *vformat)
       
   305 {
       
   306 	int i, menubar_size;
       
   307 	short work_in[12], work_out[272], dummy;
       
   308 
       
   309 	/* Open AES (Application Environment Services) */
       
   310 	if (appl_init() == -1) {
       
   311 		fprintf(stderr,"Can not open AES\n");
       
   312 		return 1;
       
   313 	}
       
   314 
       
   315 	/* Read version and features */
       
   316 	GEM_version = aes_global[0];
       
   317 	if (GEM_version >= 0x0410) {
       
   318 		short ap_gout[4], errorcode;
       
   319 		
       
   320 		GEM_wfeatures=0;
       
   321 		errorcode=appl_getinfo(AES_WINDOW, &ap_gout[0], &ap_gout[1], &ap_gout[2], &ap_gout[3]);
       
   322 
       
   323 		if (errorcode==0) {
       
   324 			GEM_wfeatures=ap_gout[0];			
       
   325 		}
       
   326 	}	
       
   327 
       
   328 	/* Ask VDI physical workstation handle opened by AES */
       
   329 	VDI_handle = graf_handle(&dummy, &dummy, &dummy, &dummy);
       
   330 	if (VDI_handle<1) {
       
   331 		fprintf(stderr,"Wrong VDI handle %d returned by AES\n",VDI_handle);
       
   332 		return 1;
       
   333 	}
       
   334 
       
   335 	/* Open virtual VDI workstation */
       
   336 	work_in[0]=Getrez()+2;
       
   337 	for(i = 1; i < 10; i++)
       
   338 		work_in[i] = 1;
       
   339 	work_in[10] = 2;
       
   340 
       
   341 	v_opnvwk(work_in, &VDI_handle, work_out);
       
   342 	if (VDI_handle == 0) {
       
   343 		fprintf(stderr,"Can not open VDI virtual workstation\n");
       
   344 		return 1;
       
   345 	}
       
   346 
       
   347 	/* Read fullscreen size */
       
   348 	VDI_w = work_out[0] + 1;
       
   349 	VDI_h = work_out[1] + 1;
       
   350 
       
   351 	/* Read desktop size and position */
       
   352 	if (!wind_get(DESKTOP_HANDLE, WF_WORKXYWH, &GEM_desk_x, &GEM_desk_y, &GEM_desk_w, &GEM_desk_h)) {
       
   353 		fprintf(stderr,"Can not read desktop properties\n");
       
   354 		return 1;
       
   355 	}
       
   356 
       
   357 	/* Read bit depth */
       
   358 	vq_extnd(VDI_handle, 1, work_out);
       
   359 	VDI_bpp = work_out[4];
       
   360 	VDI_oldnumcolors=0;
       
   361 
       
   362 	switch(VDI_bpp) {
       
   363 		case 8:
       
   364 			VDI_pixelsize=1;
       
   365 			break;
       
   366 		case 15:
       
   367 		case 16:
       
   368 			VDI_pixelsize=2;
       
   369 			break;
       
   370 		case 24:
       
   371 			VDI_pixelsize=3;
       
   372 			break;
       
   373 		case 32:
       
   374 			VDI_pixelsize=4;
       
   375 			break;
       
   376 		default:
       
   377 			fprintf(stderr,"%d bits colour depth not supported\n",VDI_bpp);
       
   378 			return 1;
       
   379 	}
       
   380 
       
   381 	/* Setup hardware -> VDI palette mapping */
       
   382 	for(i = 16; i < 255; i++) {
       
   383 		vdi_index[i] = i;
       
   384 	}
       
   385 	vdi_index[255] = 1;
       
   386 
       
   387 	/* Save current palette */
       
   388 	if (VDI_bpp>8) {
       
   389 		VDI_oldnumcolors=1<<8;
       
   390 	} else {
       
   391 		VDI_oldnumcolors=1<<VDI_bpp;
       
   392 	}
       
   393 	
       
   394 	for(i = 0; i < VDI_oldnumcolors; i++) {
       
   395 		short rgb[3];
       
   396 
       
   397 		vq_color(VDI_handle, i, 0, rgb);
       
   398 
       
   399 		VDI_oldpalette[i][0] = rgb[0];
       
   400 		VDI_oldpalette[i][1] = rgb[1];
       
   401 		VDI_oldpalette[i][2] = rgb[2];
       
   402 	}
       
   403 	VDI_setpalette = GEM_SetNewPalette;
       
   404 	SDL_memcpy(VDI_curpalette,VDI_oldpalette,sizeof(VDI_curpalette));
       
   405 
       
   406 	/* Setup screen info */
       
   407 	GEM_title_name = empty_name;
       
   408 	GEM_icon_name = empty_name;
       
   409 
       
   410 	GEM_handle = -1;
       
   411 	GEM_locked = SDL_FALSE;
       
   412 	GEM_win_fulled = SDL_FALSE;
       
   413 	GEM_fullscreen = SDL_FALSE;
       
   414 	GEM_lock_redraw = SDL_TRUE;	/* Prevent redraw till buffers are setup */
       
   415 
       
   416 	VDI_screen = NULL;
       
   417 	VDI_pitch = VDI_w * VDI_pixelsize;
       
   418 	VDI_format = ( (VDI_bpp <= 8) ? VDI_FORMAT_INTER : VDI_FORMAT_PACK);
       
   419 	VDI_redmask = VDI_greenmask = VDI_bluemask = VDI_alphamask = 0;
       
   420 	VDI_ReadExtInfo(this, work_out);
       
   421 
       
   422 #ifdef DEBUG_VIDEO_GEM
       
   423 	printf("sdl:video:gem: screen: address=0x%08x, pitch=%d\n", VDI_screen, VDI_pitch);
       
   424 	printf("sdl:video:gem: format=%d\n", VDI_format);
       
   425 	printf("sdl:video:gem: masks: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
       
   426 		VDI_alphamask, VDI_redmask, VDI_greenmask, VDI_bluemask
       
   427 	);
       
   428 #endif
       
   429 
       
   430 	/* Setup destination mfdb */
       
   431 	VDI_dst_mfdb.fd_addr = NULL;
       
   432 
       
   433 	/* Determine the current screen size */
       
   434 	this->info.current_w = VDI_w;
       
   435 	this->info.current_h = VDI_h;
       
   436 
       
   437 	/* Determine the screen depth */
       
   438 	/* we change this during the SDL_SetVideoMode implementation... */
       
   439 	vformat->BitsPerPixel = VDI_bpp;
       
   440 
       
   441 	/* Set mouse cursor to arrow */
       
   442 	graf_mouse(ARROW, NULL);
       
   443 	GEM_cursor = NULL;
       
   444 
       
   445 	/* Init chunky to planar routine */
       
   446 	SDL_Atari_C2pConvert = SDL_Atari_C2pConvert8;
       
   447 
       
   448 	/* Setup VDI fill functions */
       
   449 	vsf_color(VDI_handle,0);
       
   450 	vsf_interior(VDI_handle,1);
       
   451 	vsf_perimeter(VDI_handle,0);
       
   452 
       
   453 	/* Menu bar save buffer */
       
   454 	menubar_size = GEM_desk_w * GEM_desk_y * VDI_pixelsize;
       
   455 	GEM_menubar=Atari_SysMalloc(menubar_size,MX_PREFTTRAM);
       
   456 
       
   457 	/* Fill video modes list */
       
   458 	SDL_modelist[0] = SDL_malloc(sizeof(SDL_Rect));
       
   459 	SDL_modelist[0]->x = 0;
       
   460 	SDL_modelist[0]->y = 0;
       
   461 	SDL_modelist[0]->w = VDI_w;
       
   462 	SDL_modelist[0]->h = VDI_h;
       
   463 
       
   464 	SDL_modelist[1] = NULL;
       
   465 
       
   466 #if SDL_VIDEO_OPENGL
       
   467 	SDL_AtariGL_InitPointers(this);
       
   468 #endif
       
   469 
       
   470 	this->info.wm_available = 1;
       
   471 
       
   472 	/* We're done! */
       
   473 	return(0);
       
   474 }
       
   475 
       
   476 SDL_Rect **GEM_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
       
   477 {
       
   478 	if (format->BitsPerPixel != VDI_bpp) {
       
   479 		return ((SDL_Rect **)NULL);
       
   480 	}
       
   481 
       
   482 	if (flags & SDL_FULLSCREEN) {
       
   483 		return (SDL_modelist);
       
   484 	}
       
   485 
       
   486 	return((SDL_Rect **)-1);
       
   487 }
       
   488 
       
   489 static void GEM_FreeBuffers(_THIS)
       
   490 {
       
   491 	/* Release buffer */
       
   492 	if ( GEM_buffer2 ) {
       
   493 		Mfree( GEM_buffer2 );
       
   494 		GEM_buffer2=NULL;
       
   495 	}
       
   496 
       
   497 	if ( GEM_buffer1 ) {
       
   498 		Mfree( GEM_buffer1 );
       
   499 		GEM_buffer1=NULL;
       
   500 	}
       
   501 }
       
   502 
       
   503 static void GEM_ClearRect(_THIS, short *rect)
       
   504 {
       
   505 	short oldrgb[3], rgb[3]={0,0,0};
       
   506 
       
   507 	vq_color(VDI_handle, vdi_index[0], 0, oldrgb);
       
   508 	vs_color(VDI_handle, vdi_index[0], rgb);
       
   509 
       
   510 	vsf_color(VDI_handle,0);
       
   511 	vsf_interior(VDI_handle,1);
       
   512 	vsf_perimeter(VDI_handle,0);
       
   513 	v_bar(VDI_handle, rect);
       
   514 
       
   515 	vs_color(VDI_handle, vdi_index[0], oldrgb);
       
   516 }
       
   517 
       
   518 static void GEM_ClearScreen(_THIS)
       
   519 {
       
   520 	short pxy[4];
       
   521 
       
   522 	v_hide_c(VDI_handle);
       
   523 
       
   524 	pxy[0] = pxy[1] = 0;
       
   525 	pxy[2] = VDI_w - 1;
       
   526 	pxy[3] = VDI_h - 1;
       
   527 	GEM_ClearRect(this, pxy);
       
   528 
       
   529 	v_show_c(VDI_handle, 1);
       
   530 }
       
   531 
       
   532 static void GEM_SetNewPalette(_THIS, Uint16 newpal[256][3])
       
   533 {
       
   534 	int i;
       
   535 	short rgb[3];
       
   536 
       
   537 	if (VDI_oldnumcolors==0)
       
   538 		return;
       
   539 
       
   540 	for(i = 0; i < VDI_oldnumcolors; i++) {
       
   541 		rgb[0] = newpal[i][0];
       
   542 		rgb[1] = newpal[i][1];
       
   543 		rgb[2] = newpal[i][2];
       
   544 
       
   545 		vs_color(VDI_handle, i, rgb);
       
   546 	}
       
   547 }
       
   548 
       
   549 static void GEM_LockScreen(_THIS)
       
   550 {
       
   551 	if (!GEM_locked) {
       
   552 		/* Lock AES */
       
   553 		wind_update(BEG_UPDATE);
       
   554 		wind_update(BEG_MCTRL);
       
   555 		/* Reserve memory space, used to be sure of compatibility */
       
   556 		form_dial( FMD_START, 0,0,0,0, 0,0,VDI_w,VDI_h);
       
   557 
       
   558 		/* Save menu bar */
       
   559 		if (GEM_menubar) {
       
   560 			MFDB mfdb_src;
       
   561 			short blitcoords[8];
       
   562 
       
   563 			mfdb_src.fd_addr=GEM_menubar;
       
   564 			mfdb_src.fd_w=GEM_desk_w;
       
   565 			mfdb_src.fd_h=GEM_desk_y;
       
   566 			mfdb_src.fd_wdwidth=GEM_desk_w>>4;
       
   567 			mfdb_src.fd_nplanes=VDI_bpp;
       
   568 			mfdb_src.fd_stand=
       
   569 				mfdb_src.fd_r1=
       
   570 				mfdb_src.fd_r2=
       
   571 				mfdb_src.fd_r3= 0;
       
   572 
       
   573 			blitcoords[0] = blitcoords[4] = 0;
       
   574 			blitcoords[1] = blitcoords[5] = 0;
       
   575 			blitcoords[2] = blitcoords[6] = GEM_desk_w-1;
       
   576 			blitcoords[3] = blitcoords[7] = GEM_desk_y-1;
       
   577 
       
   578 			vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &VDI_dst_mfdb, &mfdb_src);
       
   579 		}
       
   580 
       
   581 		GEM_locked=SDL_TRUE;
       
   582 	}
       
   583 }
       
   584 
       
   585 static void GEM_UnlockScreen(_THIS)
       
   586 {
       
   587 	if (GEM_locked) {
       
   588 		/* Restore menu bar */
       
   589 		if (GEM_menubar) {
       
   590 			MFDB mfdb_src;
       
   591 			short blitcoords[8];
       
   592 
       
   593 			mfdb_src.fd_addr=GEM_menubar;
       
   594 			mfdb_src.fd_w=GEM_desk_w;
       
   595 			mfdb_src.fd_h=GEM_desk_y;
       
   596 			mfdb_src.fd_wdwidth=GEM_desk_w>>4;
       
   597 			mfdb_src.fd_nplanes=VDI_bpp;
       
   598 			mfdb_src.fd_stand=
       
   599 				mfdb_src.fd_r1=
       
   600 				mfdb_src.fd_r2=
       
   601 				mfdb_src.fd_r3= 0;
       
   602 
       
   603 			blitcoords[0] = blitcoords[4] = 0;
       
   604 			blitcoords[1] = blitcoords[5] = 0;
       
   605 			blitcoords[2] = blitcoords[6] = GEM_desk_w-1;
       
   606 			blitcoords[3] = blitcoords[7] = GEM_desk_y-1;
       
   607 
       
   608 			vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb);
       
   609 		}
       
   610 
       
   611 		/* Restore screen memory, and send REDRAW to all apps */
       
   612 		form_dial( FMD_FINISH, 0,0,0,0, 0,0,VDI_w,VDI_h);
       
   613 		/* Unlock AES */
       
   614 		wind_update(END_MCTRL);
       
   615 		wind_update(END_UPDATE);
       
   616 
       
   617 		GEM_locked=SDL_FALSE;
       
   618 	}
       
   619 }
       
   620 
       
   621 SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current,
       
   622 				int width, int height, int bpp, Uint32 flags)
       
   623 {
       
   624 	Uint32 modeflags, screensize;
       
   625 	SDL_bool use_shadow1, use_shadow2;
       
   626 
       
   627 	/* width must be multiple of 16, for vro_cpyfm() and c2p_convert() */
       
   628 	if ((width & 15) != 0) {
       
   629 		width = (width | 15) +1;
       
   630 	}
       
   631 
       
   632 	/*--- Verify if asked mode can be used ---*/
       
   633 	if (VDI_bpp != bpp) {
       
   634 		SDL_SetError("%d bpp mode not supported", bpp);
       
   635 		return(NULL);
       
   636 	}
       
   637 
       
   638 	if (flags & SDL_FULLSCREEN) {
       
   639 		if ((VDI_w < width) || (VDI_h < height)) {
       
   640 			SDL_SetError("%dx%d mode is too large", width, height);
       
   641 			return(NULL);
       
   642 		}
       
   643 	}
       
   644 
       
   645 	/*--- Allocate the new pixel format for the screen ---*/
       
   646 	if ( ! SDL_ReallocFormat(current, VDI_bpp, VDI_redmask, VDI_greenmask, VDI_bluemask, VDI_alphamask) ) {
       
   647 		SDL_SetError("Couldn't allocate new pixel format for requested mode");
       
   648 		return(NULL);
       
   649 	}
       
   650 
       
   651 	screensize = width * height * VDI_pixelsize;
       
   652 
       
   653 #ifdef DEBUG_VIDEO_GEM
       
   654 	printf("sdl:video:gem: setvideomode(): %dx%dx%d = %d\n", width, height, bpp, screensize);
       
   655 #endif
       
   656 
       
   657 	/*--- Allocate shadow buffers if needed, and conversion operations ---*/
       
   658 	GEM_FreeBuffers(this);
       
   659 
       
   660 	GEM_bufops=0;
       
   661 	use_shadow1=use_shadow2=SDL_FALSE;
       
   662 	if (VDI_screen && (flags & SDL_FULLSCREEN)) {
       
   663 		if (VDI_format==VDI_FORMAT_INTER) {
       
   664 			use_shadow1=SDL_TRUE;
       
   665 			GEM_bufops = B2S_C2P_1TOS;
       
   666 		}
       
   667 	} else {
       
   668 		use_shadow1=SDL_TRUE;
       
   669 		if (VDI_format==VDI_FORMAT_PACK) {
       
   670 			GEM_bufops = B2S_VROCPYFM_1TOS;
       
   671 		} else {
       
   672 			use_shadow2=SDL_TRUE;
       
   673 			GEM_bufops = B2S_C2P_1TO2|B2S_VROCPYFM_2TOS;
       
   674 		}
       
   675 	}
       
   676 
       
   677 	if (use_shadow1) {
       
   678 		GEM_buffer1 = Atari_SysMalloc(screensize, MX_PREFTTRAM);
       
   679 		if (GEM_buffer1==NULL) {
       
   680 			SDL_SetError("Can not allocate %d KB for frame buffer", screensize>>10);
       
   681 			return NULL;
       
   682 		}
       
   683 		SDL_memset(GEM_buffer1, 0, screensize);
       
   684 #ifdef DEBUG_VIDEO_GEM
       
   685 		printf("sdl:video:gem: setvideomode(): allocated buffer 1\n");
       
   686 #endif
       
   687 	}
       
   688 
       
   689 	if (use_shadow2) {
       
   690 		GEM_buffer2 = Atari_SysMalloc(screensize, MX_PREFTTRAM);
       
   691 		if (GEM_buffer2==NULL) {
       
   692 			SDL_SetError("Can not allocate %d KB for shadow buffer", screensize>>10);
       
   693 			return NULL;
       
   694 		}
       
   695 		SDL_memset(GEM_buffer2, 0, screensize);
       
   696 #ifdef DEBUG_VIDEO_GEM
       
   697 		printf("sdl:video:gem: setvideomode(): allocated buffer 2\n");
       
   698 #endif
       
   699 	}
       
   700 
       
   701 	/*--- Initialize screen ---*/
       
   702 	modeflags = SDL_PREALLOC;
       
   703 	if (VDI_bpp == 8) {
       
   704 		modeflags |= SDL_HWPALETTE;
       
   705 	}
       
   706 
       
   707 	if (flags & SDL_FULLSCREEN) {
       
   708 		GEM_LockScreen(this);
       
   709 
       
   710 		GEM_ClearScreen(this);
       
   711 
       
   712 		modeflags |= SDL_FULLSCREEN;
       
   713 		if (VDI_screen && (VDI_format==VDI_FORMAT_PACK) && !use_shadow1) {
       
   714 			modeflags |= SDL_HWSURFACE;
       
   715 		} else {
       
   716 			modeflags |= SDL_SWSURFACE;
       
   717 		}
       
   718 
       
   719 		GEM_fullscreen = SDL_TRUE;
       
   720 	} else {
       
   721 		int old_win_type;
       
   722 		short x2,y2,w2,h2;
       
   723 
       
   724 		GEM_UnlockScreen(this);
       
   725 
       
   726 		/* Set window gadgets */
       
   727 		old_win_type = GEM_win_type;
       
   728 		if (!(flags & SDL_NOFRAME)) {
       
   729 			GEM_win_type=NAME|MOVER|CLOSER|SMALLER;
       
   730 			if (flags & SDL_RESIZABLE) {
       
   731 				GEM_win_type |= FULLER|SIZER;
       
   732 				modeflags |= SDL_RESIZABLE;
       
   733 			}
       
   734 		} else {
       
   735 			GEM_win_type=0;
       
   736 			modeflags |= SDL_NOFRAME;
       
   737 		}
       
   738 		modeflags |= SDL_SWSURFACE;
       
   739 
       
   740 		/* Recreate window ? only for different widget or non-created window */
       
   741 		if ((old_win_type != GEM_win_type) || (GEM_handle < 0)) {
       
   742 			/* Calculate window size */
       
   743 			if (!wind_calc(WC_BORDER, GEM_win_type, 0,0,width,height, &x2,&y2,&w2,&h2)) {
       
   744 				GEM_FreeBuffers(this);
       
   745 				SDL_SetError("Can not calculate window attributes");
       
   746 				return NULL;
       
   747 			}
       
   748 
       
   749 			/* Center window */
       
   750 			x2 = (GEM_desk_w-w2)>>1;
       
   751 			y2 = (GEM_desk_h-h2)>>1;
       
   752 			if (x2<0) {
       
   753 				x2 = 0;
       
   754 			}
       
   755 			if (y2<0) {
       
   756 				y2 = 0;
       
   757 			}
       
   758 			x2 += GEM_desk_x;
       
   759 			y2 += GEM_desk_y;
       
   760 
       
   761 			/* Destroy existing window */
       
   762 			if (GEM_handle >= 0) {
       
   763 				wind_close(GEM_handle);
       
   764 				wind_delete(GEM_handle);
       
   765 			}
       
   766 
       
   767 			/* Create window */
       
   768 			GEM_handle=wind_create(GEM_win_type, x2,y2,w2,h2);
       
   769 			if (GEM_handle<0) {
       
   770 				GEM_FreeBuffers(this);
       
   771 				SDL_SetError("Can not create window");
       
   772 				return NULL;
       
   773 			}
       
   774 
       
   775 #ifdef DEBUG_VIDEO_GEM
       
   776 			printf("sdl:video:gem: handle=%d\n", GEM_handle);
       
   777 #endif
       
   778 
       
   779 			/* Setup window name */
       
   780 			wind_set(GEM_handle,WF_NAME,(short)(((unsigned long)GEM_title_name)>>16),(short)(((unsigned long)GEM_title_name) & 0xffff),0,0);
       
   781 			GEM_refresh_name = SDL_FALSE;
       
   782 
       
   783 			/* Open the window */
       
   784 			wind_open(GEM_handle,x2,y2,w2,h2);
       
   785 		} else {
       
   786 			/* Resize window to fit asked video mode */
       
   787 			wind_get (GEM_handle, WF_WORKXYWH, &x2,&y2,&w2,&h2);
       
   788 			if (wind_calc(WC_BORDER, GEM_win_type, x2,y2,width,height, &x2,&y2,&w2,&h2)) {
       
   789 				wind_set (GEM_handle, WF_CURRXYWH, x2,y2,w2,h2);
       
   790 			}
       
   791 		}
       
   792 
       
   793 		GEM_fullscreen = SDL_FALSE;
       
   794 	}
       
   795 
       
   796 	/* Set up the new mode framebuffer */
       
   797 	current->w = width;
       
   798 	current->h = height;
       
   799 	if (use_shadow1) {
       
   800 		current->pixels = GEM_buffer1;
       
   801 		current->pitch = width * VDI_pixelsize;
       
   802 	} else {
       
   803 		current->pixels = VDI_screen;
       
   804 		current->pitch = VDI_pitch;
       
   805 	}
       
   806 
       
   807 #if SDL_VIDEO_OPENGL
       
   808 	if (flags & SDL_OPENGL) {
       
   809 		if (!SDL_AtariGL_Init(this, current)) {
       
   810 			GEM_FreeBuffers(this);
       
   811 			SDL_SetError("Can not create OpenGL context");
       
   812 			return NULL;
       
   813 		}
       
   814 
       
   815 		modeflags |= SDL_OPENGL;
       
   816 	}
       
   817 #endif
       
   818 
       
   819 	current->flags = modeflags;
       
   820 
       
   821 #ifdef DEBUG_VIDEO_GEM
       
   822 	printf("sdl:video:gem: surface: %dx%d\n", current->w, current->h);
       
   823 #endif
       
   824 
       
   825 	this->UpdateRects = GEM_UpdateRects;
       
   826 	GEM_lock_redraw = SDL_FALSE;	/* Enable redraw */
       
   827 
       
   828 	/* We're done */
       
   829 	return(current);
       
   830 }
       
   831 
       
   832 static int GEM_AllocHWSurface(_THIS, SDL_Surface *surface)
       
   833 {
       
   834 	return -1;
       
   835 }
       
   836 
       
   837 static void GEM_FreeHWSurface(_THIS, SDL_Surface *surface)
       
   838 {
       
   839 	return;
       
   840 }
       
   841 
       
   842 static int GEM_LockHWSurface(_THIS, SDL_Surface *surface)
       
   843 {
       
   844 	return(0);
       
   845 }
       
   846 
       
   847 static void GEM_UnlockHWSurface(_THIS, SDL_Surface *surface)
       
   848 {
       
   849 	return;
       
   850 }
       
   851 
       
   852 static void GEM_UpdateRectsFullscreen(_THIS, int numrects, SDL_Rect *rects)
       
   853 {
       
   854 	SDL_Surface *surface;
       
   855 	int i, surf_width;
       
   856 
       
   857 	surface = this->screen;
       
   858 	/* Need to be a multiple of 16 pixels */
       
   859 	surf_width=surface->w;
       
   860 	if ((surf_width & 15) != 0) {
       
   861 		surf_width = (surf_width | 15) + 1;
       
   862 	}
       
   863 
       
   864 	if (GEM_bufops & (B2S_C2P_1TO2|B2S_C2P_1TOS)) {
       
   865 		void *destscr;
       
   866 		int destpitch;
       
   867 
       
   868 		if (GEM_bufops & B2S_C2P_1TOS) {
       
   869 			destscr = VDI_screen;
       
   870 			destpitch = VDI_pitch;
       
   871 		} else {
       
   872 			destscr = GEM_buffer2;
       
   873 			destpitch = surface->pitch;
       
   874 		}
       
   875 
       
   876 		for (i=0;i<numrects;i++) {
       
   877 			void *source,*destination;
       
   878 			int x1,x2;
       
   879 
       
   880 			x1 = rects[i].x & ~15;
       
   881 			x2 = rects[i].x+rects[i].w;
       
   882 			if (x2 & 15) {
       
   883 				x2 = (x2 | 15) +1;
       
   884 			}
       
   885 
       
   886 			source = surface->pixels;
       
   887 			source += surface->pitch * rects[i].y;
       
   888 			source += x1;
       
   889 
       
   890 			destination = destscr;
       
   891 			destination += destpitch * rects[i].y;
       
   892 			destination += x1;
       
   893 
       
   894 			SDL_Atari_C2pConvert(
       
   895 				source, destination,
       
   896 				x2-x1, rects[i].h,
       
   897 				SDL_FALSE,
       
   898 				surface->pitch, destpitch
       
   899 			);
       
   900 		}
       
   901 	}
       
   902 
       
   903 	if (GEM_bufops & (B2S_VROCPYFM_1TOS|B2S_VROCPYFM_2TOS)) {
       
   904 		MFDB mfdb_src;
       
   905 		short blitcoords[8];
       
   906 
       
   907 		mfdb_src.fd_addr=surface->pixels;
       
   908 		mfdb_src.fd_w=surf_width;
       
   909 		mfdb_src.fd_h=surface->h;
       
   910 		mfdb_src.fd_wdwidth= (surface->pitch/VDI_pixelsize) >> 4;
       
   911 		mfdb_src.fd_nplanes=surface->format->BitsPerPixel;
       
   912 		mfdb_src.fd_stand=
       
   913 			mfdb_src.fd_r1=
       
   914 			mfdb_src.fd_r2=
       
   915 			mfdb_src.fd_r3= 0;
       
   916 		if (GEM_bufops & B2S_VROCPYFM_2TOS) {
       
   917 			mfdb_src.fd_addr=GEM_buffer2;
       
   918 		}
       
   919 
       
   920 		for ( i=0; i<numrects; ++i ) {
       
   921 			blitcoords[0] = blitcoords[4] = rects[i].x;
       
   922 			blitcoords[1] = blitcoords[5] = rects[i].y;
       
   923 			blitcoords[2] = blitcoords[6] = rects[i].x + rects[i].w - 1;
       
   924 			blitcoords[3] = blitcoords[7] = rects[i].y + rects[i].h - 1;
       
   925 
       
   926 			vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb);
       
   927 		}
       
   928 	}
       
   929 }
       
   930 
       
   931 static void GEM_UpdateRectsWindowed(_THIS, int numrects, SDL_Rect *rects)
       
   932 {
       
   933 	short pxy[4], wind_pxy[4];
       
   934 	int i;
       
   935 
       
   936 	if (wind_get(GEM_handle, WF_WORKXYWH, &wind_pxy[0], &wind_pxy[1], &wind_pxy[2], &wind_pxy[3])==0) {
       
   937 		return;
       
   938 	}
       
   939 
       
   940 	for ( i=0; i<numrects; ++i ) {
       
   941 		pxy[0] = wind_pxy[0] + rects[i].x;
       
   942 		pxy[1] = wind_pxy[1] + rects[i].y;
       
   943 		pxy[2] = rects[i].w;
       
   944 		pxy[3] = rects[i].h;
       
   945 
       
   946 		GEM_wind_redraw(this, GEM_handle, pxy);
       
   947 	}
       
   948 }
       
   949 
       
   950 static void GEM_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
       
   951 {
       
   952 	SDL_Surface *surface;
       
   953 
       
   954 	if (GEM_lock_redraw) {
       
   955 		return;
       
   956 	}
       
   957 
       
   958 	surface = this->screen;
       
   959 
       
   960 	if (surface->flags & SDL_FULLSCREEN) {
       
   961 		GEM_UpdateRectsFullscreen(this, numrects, rects);
       
   962 	} else {
       
   963 		GEM_UpdateRectsWindowed(this, numrects, rects);
       
   964 	}
       
   965 }
       
   966 
       
   967 static int GEM_FlipHWSurfaceFullscreen(_THIS, SDL_Surface *surface)
       
   968 {
       
   969 	int surf_width;
       
   970 
       
   971 	/* Need to be a multiple of 16 pixels */
       
   972 	surf_width=surface->w;
       
   973 	if ((surf_width & 15) != 0) {
       
   974 		surf_width = (surf_width | 15) + 1;
       
   975 	}
       
   976 
       
   977 	if (GEM_bufops & (B2S_C2P_1TO2|B2S_C2P_1TOS)) {
       
   978 		void *destscr;
       
   979 		int destpitch;
       
   980 
       
   981 		if (GEM_bufops & B2S_C2P_1TOS) {
       
   982 			destscr = VDI_screen;
       
   983 			destpitch = VDI_pitch;
       
   984 		} else {
       
   985 			destscr = GEM_buffer2;
       
   986 			destpitch = surface->pitch;
       
   987 		}
       
   988 
       
   989 		SDL_Atari_C2pConvert(
       
   990 			surface->pixels, destscr,
       
   991 			surf_width, surface->h,
       
   992 			SDL_FALSE,
       
   993 			surface->pitch, destpitch
       
   994 		);
       
   995 	}
       
   996 
       
   997 	if (GEM_bufops & (B2S_VROCPYFM_1TOS|B2S_VROCPYFM_2TOS)) {
       
   998 		MFDB mfdb_src;
       
   999 		short blitcoords[8];
       
  1000 
       
  1001 		mfdb_src.fd_w=surf_width;
       
  1002 		mfdb_src.fd_h=surface->h;
       
  1003 		mfdb_src.fd_wdwidth=mfdb_src.fd_w >> 4;
       
  1004 		mfdb_src.fd_nplanes=surface->format->BitsPerPixel;
       
  1005 		mfdb_src.fd_stand=
       
  1006 			mfdb_src.fd_r1=
       
  1007 			mfdb_src.fd_r2=
       
  1008 			mfdb_src.fd_r3= 0;
       
  1009 		if (GEM_bufops & B2S_VROCPYFM_1TOS) {
       
  1010 			mfdb_src.fd_addr=surface->pixels;
       
  1011 		} else {
       
  1012 			mfdb_src.fd_addr=GEM_buffer2;
       
  1013 		}
       
  1014 
       
  1015 		blitcoords[0] = blitcoords[4] = 0;
       
  1016 		blitcoords[1] = blitcoords[5] = 0;
       
  1017 		blitcoords[2] = blitcoords[6] = surface->w - 1;
       
  1018 		blitcoords[3] = blitcoords[7] = surface->h - 1;
       
  1019 
       
  1020 		vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb);
       
  1021 	}
       
  1022 
       
  1023 	return(0);
       
  1024 }
       
  1025 
       
  1026 static int GEM_FlipHWSurfaceWindowed(_THIS, SDL_Surface *surface)
       
  1027 {
       
  1028 	short	pxy[8];
       
  1029 
       
  1030 	/* Update the whole window */
       
  1031 	wind_get(GEM_handle, WF_WORKXYWH, &pxy[0], &pxy[1], &pxy[2], &pxy[3]);
       
  1032 
       
  1033 	GEM_wind_redraw(this, GEM_handle, pxy);
       
  1034 
       
  1035 	return(0);
       
  1036 }
       
  1037 
       
  1038 static int GEM_FlipHWSurface(_THIS, SDL_Surface *surface)
       
  1039 {
       
  1040 	if (GEM_lock_redraw) {
       
  1041 		return(0);
       
  1042 	}
       
  1043 
       
  1044 	if (surface->flags & SDL_FULLSCREEN) {
       
  1045 		return GEM_FlipHWSurfaceFullscreen(this, surface);
       
  1046 	} else {
       
  1047 		return GEM_FlipHWSurfaceWindowed(this, surface);
       
  1048 	}
       
  1049 }
       
  1050 
       
  1051 static int GEM_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
       
  1052 {
       
  1053 	int i;
       
  1054 	SDL_Surface *surface;
       
  1055 
       
  1056 #ifdef DEBUG_VIDEO_GEM
       
  1057 	printf("sdl:video:gem: setcolors()\n");
       
  1058 #endif
       
  1059 
       
  1060 	/* Do not change palette in True Colour */
       
  1061 	surface = this->screen;
       
  1062 	if (surface->format->BitsPerPixel > 8) {
       
  1063 		return 1;
       
  1064 	}
       
  1065 
       
  1066 	for(i = 0; i < ncolors; i++)
       
  1067 	{
       
  1068 		int		r, g, b;
       
  1069 		short	rgb[3];
       
  1070 
       
  1071 		r = colors[i].r;
       
  1072 		g = colors[i].g;
       
  1073 		b = colors[i].b;
       
  1074 
       
  1075 		rgb[0] = VDI_curpalette[i][0] = (1000 * r) / 255;
       
  1076 		rgb[1] = VDI_curpalette[i][1] =(1000 * g) / 255;
       
  1077 		rgb[2] = VDI_curpalette[i][2] =(1000 * b) / 255;
       
  1078 
       
  1079 		vs_color(VDI_handle, vdi_index[firstcolor+i], rgb);
       
  1080 	}
       
  1081 
       
  1082 	return(1);
       
  1083 }
       
  1084 
       
  1085 #if 0
       
  1086 static int GEM_ToggleFullScreen(_THIS, int on)
       
  1087 {
       
  1088 	if (on) {
       
  1089 		GEM_LockScreen(this);
       
  1090 	} else {
       
  1091 		GEM_UnlockScreen(this);
       
  1092 	}
       
  1093 
       
  1094 	return(1);
       
  1095 }
       
  1096 #endif
       
  1097 
       
  1098 /* Note:  If we are terminated, this could be called in the middle of
       
  1099    another SDL video routine -- notably UpdateRects.
       
  1100 */
       
  1101 void GEM_VideoQuit(_THIS)
       
  1102 {
       
  1103 	SDL_AtariXbios_RestoreVectors();
       
  1104 	if (GEM_usedevmouse) {
       
  1105 		SDL_AtariDevMouse_Close();
       
  1106 	}
       
  1107 
       
  1108 	GEM_FreeBuffers(this);
       
  1109 
       
  1110 #if SDL_VIDEO_OPENGL
       
  1111 	if (gl_active) {
       
  1112 		SDL_AtariGL_Quit(this, SDL_TRUE);
       
  1113 	}
       
  1114 #endif
       
  1115 
       
  1116 	/* Destroy window */
       
  1117 	if (GEM_handle>=0) {
       
  1118 		wind_close(GEM_handle);
       
  1119 		wind_delete(GEM_handle);
       
  1120 		GEM_handle=-1;
       
  1121 	}
       
  1122 
       
  1123 	GEM_UnlockScreen(this);
       
  1124 	if (GEM_menubar) {
       
  1125 		Mfree(GEM_menubar);
       
  1126 		GEM_menubar=NULL;
       
  1127 	}
       
  1128 
       
  1129 	appl_exit();
       
  1130 
       
  1131 	GEM_SetNewPalette(this, VDI_oldpalette);
       
  1132 
       
  1133 	/* Close VDI workstation */
       
  1134 	if (VDI_handle) {
       
  1135 		v_clsvwk(VDI_handle);
       
  1136 	}
       
  1137 
       
  1138 	/* Free mode list */
       
  1139 	if (SDL_modelist[0]) {
       
  1140 		SDL_free(SDL_modelist[0]);
       
  1141 		SDL_modelist[0]=NULL;
       
  1142 	}
       
  1143 
       
  1144 	this->screen->pixels = NULL;	
       
  1145 }
       
  1146 
       
  1147 void GEM_wind_redraw(_THIS, int winhandle, short *inside)
       
  1148 {
       
  1149 	short todo[4];
       
  1150 
       
  1151 	/* Tell AES we are going to update */
       
  1152 	wind_update(BEG_UPDATE);
       
  1153 
       
  1154 	v_hide_c(VDI_handle);
       
  1155 
       
  1156 	/* Browse the rectangle list to redraw */
       
  1157 	if (wind_get(winhandle, WF_FIRSTXYWH, &todo[0], &todo[1], &todo[2], &todo[3])!=0) {
       
  1158 
       
  1159 		while (todo[2] && todo[3]) {
       
  1160 
       
  1161 			if (rc_intersect((GRECT *)inside,(GRECT *)todo)) {
       
  1162 				todo[2] += todo[0]-1;
       
  1163 				todo[3] += todo[1]-1;
       
  1164 				refresh_window(this, winhandle, todo);
       
  1165 			}
       
  1166 
       
  1167 			if (wind_get(winhandle, WF_NEXTXYWH, &todo[0], &todo[1], &todo[2], &todo[3])==0) {
       
  1168 				break;
       
  1169 			}
       
  1170 		}
       
  1171 
       
  1172 	}
       
  1173 
       
  1174 	/* Update finished */
       
  1175 	wind_update(END_UPDATE);
       
  1176 
       
  1177 	v_show_c(VDI_handle,1);
       
  1178 }
       
  1179 
       
  1180 static void refresh_window(_THIS, int winhandle, short *rect)
       
  1181 {
       
  1182 	MFDB mfdb_src;
       
  1183 	short pxy[8],wind_pxy[8];
       
  1184 	SDL_Surface *surface;
       
  1185 	int iconified;
       
  1186 
       
  1187 	/* Is window iconified ? */
       
  1188 	iconified = 0;
       
  1189 /*	if (GEM_wfeatures & (1<<WF_ICONIFY))*/ {
       
  1190 		if (wind_get(winhandle, WF_ICONIFY, &wind_pxy[0], &wind_pxy[1], &wind_pxy[2], &wind_pxy[3])!=0) {
       
  1191 			iconified = wind_pxy[0];
       
  1192 		}
       
  1193 	}
       
  1194 
       
  1195 	if (wind_get(winhandle, WF_WORKXYWH, &wind_pxy[0], &wind_pxy[1], &wind_pxy[2], &wind_pxy[3])==0) {
       
  1196 		return;
       
  1197 	}
       
  1198 
       
  1199 	if (iconified && GEM_icon) {
       
  1200 		short icon_rect[4], dst_rect[4];
       
  1201 		short iconx,icony;
       
  1202 		
       
  1203 		surface = GEM_icon;
       
  1204 
       
  1205 		GEM_ClearRect(this, rect);
       
  1206 
       
  1207 		/* Calculate centered icon(x,y,w,h) relative to window */
       
  1208 		iconx = (wind_pxy[2]-surface->w)>>1;
       
  1209 		icony = (wind_pxy[3]-surface->h)>>1;
       
  1210 
       
  1211 		icon_rect[0] = iconx;
       
  1212 		icon_rect[1] = icony;
       
  1213 		icon_rect[2] = surface->w;
       
  1214 		icon_rect[3] = surface->h;
       
  1215 
       
  1216 		/* Calculate redraw rectangle(x,y,w,h) relative to window */
       
  1217 		dst_rect[0] = rect[0]-wind_pxy[0];
       
  1218 		dst_rect[1] = rect[1]-wind_pxy[1];
       
  1219 		dst_rect[2] = rect[2]-rect[0]+1;
       
  1220 		dst_rect[3] = rect[3]-rect[1]+1;
       
  1221 
       
  1222 		/* Does the icon rectangle must be redrawn ? */
       
  1223 		if (!rc_intersect((GRECT *)icon_rect, (GRECT *)dst_rect)) {
       
  1224 			return;
       
  1225 		}
       
  1226 
       
  1227 #if DEBUG_VIDEO_GEM
       
  1228 		printf("sdl:video:gem:  clip(0,0,%d,%d) to (%d,%d,%d,%d)\n",
       
  1229 			surface->w-1,surface->h-1, dst_rect[0],dst_rect[1],dst_rect[2],dst_rect[3]);
       
  1230 		printf("sdl:video:gem:  icon(%d,%d,%d,%d)\n",
       
  1231 			icon_rect[0], icon_rect[1], icon_rect[2], icon_rect[3]);
       
  1232 		printf("sdl:video:gem: refresh_window(): draw icon\n");
       
  1233 #endif
       
  1234 
       
  1235 		/* Calculate icon(x1,y1,x2,y2) relative to screen */
       
  1236 		icon_rect[0] += wind_pxy[0];
       
  1237 		icon_rect[1] += wind_pxy[1];
       
  1238 		icon_rect[2] += icon_rect[0]-1;
       
  1239 		icon_rect[3] += icon_rect[1]-1;
       
  1240 
       
  1241 		/* Calculate intersection rectangle to redraw */
       
  1242 		pxy[4]=pxy[0]=MAX(icon_rect[0],rect[0]);
       
  1243 		pxy[5]=pxy[1]=MAX(icon_rect[1],rect[1]);
       
  1244  		pxy[6]=pxy[2]=MIN(icon_rect[2],rect[2]);
       
  1245 	 	pxy[7]=pxy[3]=MIN(icon_rect[3],rect[3]);
       
  1246 
       
  1247 		/* Calculate icon source image pos relative to window */
       
  1248 		pxy[0] -= wind_pxy[0]+iconx;
       
  1249 		pxy[1] -= wind_pxy[1]+icony;
       
  1250 		pxy[2] -= wind_pxy[0]+iconx;
       
  1251 		pxy[3] -= wind_pxy[1]+icony;
       
  1252 
       
  1253 	} else {
       
  1254 		surface = this->screen;
       
  1255 
       
  1256 #if DEBUG_VIDEO_GEM
       
  1257 		printf("sdl:video:gem: refresh_window(): draw frame buffer\n");
       
  1258 #endif
       
  1259 
       
  1260 		/* Redraw all window content */
       
  1261 		pxy[0] = rect[0]-wind_pxy[0];
       
  1262 		pxy[1] = rect[1]-wind_pxy[1];
       
  1263 	 	pxy[2] = rect[2]-wind_pxy[0];   
       
  1264 	 	pxy[3] = rect[3]-wind_pxy[1];  
       
  1265 
       
  1266 		pxy[4] = rect[0];
       
  1267 		pxy[5] = rect[1];
       
  1268 		pxy[6] = rect[2];  
       
  1269 		pxy[7] = rect[3];
       
  1270 	}
       
  1271 
       
  1272 	if (GEM_bufops & B2S_C2P_1TO2) {
       
  1273 		void *src, *dest;
       
  1274 		int x1,x2;
       
  1275 
       
  1276 		x1 = (rect[0]-wind_pxy[0]) & ~15;
       
  1277 		x2 = rect[2]-wind_pxy[0];
       
  1278 		if (x2 & 15) {
       
  1279 			x2 = (x2 | 15) +1;
       
  1280 		}
       
  1281 
       
  1282 		src = surface->pixels;
       
  1283 		src += surface->pitch * (rect[1]-wind_pxy[1]);
       
  1284 		src += x1;
       
  1285 
       
  1286 		dest = GEM_buffer2;
       
  1287 		dest += surface->pitch * (rect[1]-wind_pxy[1]);
       
  1288 		dest += x1;
       
  1289 
       
  1290 		SDL_Atari_C2pConvert(
       
  1291 			src, dest,
       
  1292 			x2-x1, rect[3]-rect[1]+1,
       
  1293 			SDL_FALSE,
       
  1294 			surface->pitch, surface->pitch
       
  1295 		);
       
  1296 	}
       
  1297 
       
  1298 	mfdb_src.fd_addr=surface->pixels;
       
  1299 	{
       
  1300 		int width;
       
  1301 
       
  1302 		/* Need to be a multiple of 16 pixels */
       
  1303 		width=surface->w;
       
  1304 		if ((width & 15) != 0) {
       
  1305 			width = (width | 15) + 1;
       
  1306 		}
       
  1307 		mfdb_src.fd_w=width;
       
  1308 	}
       
  1309 	mfdb_src.fd_h=surface->h;
       
  1310   	mfdb_src.fd_nplanes=surface->format->BitsPerPixel;
       
  1311 	mfdb_src.fd_wdwidth=mfdb_src.fd_w>>4;
       
  1312 	mfdb_src.fd_stand=
       
  1313 		mfdb_src.fd_r1=
       
  1314   		mfdb_src.fd_r2=
       
  1315 	  	mfdb_src.fd_r3= 0;
       
  1316 
       
  1317 	if (GEM_bufops & B2S_VROCPYFM_2TOS) {
       
  1318 		mfdb_src.fd_addr=GEM_buffer2;
       
  1319 	}
       
  1320 
       
  1321 #if DEBUG_VIDEO_GEM
       
  1322 	printf("sdl:video:gem: redraw %dx%d: (%d,%d,%d,%d) to (%d,%d,%d,%d)\n",
       
  1323 		surface->w, surface->h,
       
  1324 		pxy[0],pxy[1],pxy[2],pxy[3],
       
  1325 		pxy[4],pxy[5],pxy[6],pxy[7]
       
  1326 	);
       
  1327 #endif
       
  1328 
       
  1329 	vro_cpyfm( VDI_handle, S_ONLY, pxy, &mfdb_src, &VDI_dst_mfdb);
       
  1330 }
       
  1331 
       
  1332 #if SDL_VIDEO_OPENGL
       
  1333 
       
  1334 static void GEM_GL_SwapBuffers(_THIS)
       
  1335 {
       
  1336 	SDL_AtariGL_SwapBuffers(this);
       
  1337 	GEM_FlipHWSurface(this, this->screen);
       
  1338 }
       
  1339 
       
  1340 #endif