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