symbian-qemu-0.9.1-12/libsdl-trunk/src/video/wscons/SDL_wsconsvideo.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 #include <sys/time.h>
       
    25 #include <sys/mman.h>
       
    26 #include <sys/ioctl.h>
       
    27 #include <dev/wscons/wsdisplay_usl_io.h>
       
    28 #include <fcntl.h>
       
    29 #include <unistd.h>
       
    30 #include <errno.h>
       
    31 
       
    32 #include "SDL_video.h"
       
    33 #include "SDL_mouse.h"
       
    34 #include "../SDL_sysvideo.h"
       
    35 #include "../SDL_pixels_c.h"
       
    36 #include "../../events/SDL_events_c.h"
       
    37 
       
    38 #include "SDL_wsconsvideo.h"
       
    39 #include "SDL_wsconsevents_c.h"
       
    40 #include "SDL_wsconsmouse_c.h"
       
    41 
       
    42 #define WSCONSVID_DRIVER_NAME "wscons"
       
    43 enum {
       
    44   WSCONS_ROTATE_NONE = 0,
       
    45   WSCONS_ROTATE_CCW = 90,
       
    46   WSCONS_ROTATE_UD = 180,
       
    47   WSCONS_ROTATE_CW = 270
       
    48 };
       
    49 
       
    50 #define min(a,b) ((a)<(b)?(a):(b))
       
    51 
       
    52 /* Initialization/Query functions */
       
    53 static int WSCONS_VideoInit(_THIS, SDL_PixelFormat *vformat);
       
    54 static SDL_Rect **WSCONS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
       
    55 static SDL_Surface *WSCONS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
       
    56 static int WSCONS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
       
    57 static void WSCONS_VideoQuit(_THIS);
       
    58 
       
    59 /* Hardware surface functions */
       
    60 static int WSCONS_AllocHWSurface(_THIS, SDL_Surface *surface);
       
    61 static int WSCONS_LockHWSurface(_THIS, SDL_Surface *surface);
       
    62 static void WSCONS_UnlockHWSurface(_THIS, SDL_Surface *surface);
       
    63 static void WSCONS_FreeHWSurface(_THIS, SDL_Surface *surface);
       
    64 
       
    65 /* etc. */
       
    66 static WSCONS_bitBlit WSCONS_blit16;
       
    67 static WSCONS_bitBlit WSCONS_blit16blocked;
       
    68 static void WSCONS_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
       
    69 
       
    70 void WSCONS_ReportError(char *fmt, ...)
       
    71 {
       
    72   char message[200];
       
    73   va_list vaArgs;
       
    74   
       
    75   message[199] = '\0';
       
    76   
       
    77   va_start(vaArgs, fmt);
       
    78   vsnprintf(message, 199, fmt, vaArgs);
       
    79   va_end(vaArgs);
       
    80 
       
    81   SDL_SetError(message); 
       
    82   fprintf(stderr, "WSCONS error: %s\n", message);
       
    83 }
       
    84 
       
    85 /* WSCONS driver bootstrap functions */
       
    86 
       
    87 static int WSCONS_Available(void)
       
    88 {
       
    89   return 1;
       
    90 }
       
    91 
       
    92 static void WSCONS_DeleteDevice(SDL_VideoDevice *device)
       
    93 {
       
    94   SDL_free(device->hidden);
       
    95   SDL_free(device);
       
    96 }
       
    97 
       
    98 static SDL_VideoDevice *WSCONS_CreateDevice(int devindex)
       
    99 {
       
   100   SDL_VideoDevice *device;
       
   101   
       
   102   /* Initialize all variables that we clean on shutdown */
       
   103   device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
       
   104   if (device == NULL) {
       
   105     SDL_OutOfMemory();
       
   106     return 0;
       
   107   }
       
   108   SDL_memset(device, 0, (sizeof *device));
       
   109   device->hidden = 
       
   110     (struct SDL_PrivateVideoData *)SDL_malloc((sizeof *device->hidden));
       
   111   if (device->hidden == NULL) {
       
   112     SDL_OutOfMemory();
       
   113     SDL_free(device);
       
   114     return(0);
       
   115   }
       
   116   SDL_memset(device->hidden, 0, (sizeof *device->hidden));
       
   117   device->hidden->fd = -1;
       
   118   
       
   119   /* Set the function pointers */
       
   120   device->VideoInit = WSCONS_VideoInit;
       
   121   device->ListModes = WSCONS_ListModes;
       
   122   device->SetVideoMode = WSCONS_SetVideoMode;
       
   123   device->SetColors = WSCONS_SetColors;
       
   124   device->UpdateRects = WSCONS_UpdateRects;
       
   125   device->VideoQuit = WSCONS_VideoQuit;
       
   126   device->AllocHWSurface = WSCONS_AllocHWSurface;
       
   127   device->LockHWSurface = WSCONS_LockHWSurface;
       
   128   device->UnlockHWSurface = WSCONS_UnlockHWSurface;
       
   129   device->FreeHWSurface = WSCONS_FreeHWSurface;
       
   130   device->InitOSKeymap = WSCONS_InitOSKeymap;
       
   131   device->PumpEvents = WSCONS_PumpEvents;
       
   132   device->free = WSCONS_DeleteDevice;
       
   133   
       
   134   return device;
       
   135 }
       
   136 
       
   137 VideoBootStrap WSCONS_bootstrap = {
       
   138   WSCONSVID_DRIVER_NAME,
       
   139   "SDL wscons video driver",
       
   140   WSCONS_Available,
       
   141   WSCONS_CreateDevice
       
   142 };
       
   143 
       
   144 #define WSCONSDEV_FORMAT "/dev/ttyC%01x"
       
   145 
       
   146 int WSCONS_VideoInit(_THIS, SDL_PixelFormat *vformat)
       
   147 {
       
   148   char devnamebuf[30];
       
   149   char *devname;
       
   150   char *rotation;
       
   151   int wstype;
       
   152   int wsmode = WSDISPLAYIO_MODE_DUMBFB;
       
   153   size_t len, mapsize;
       
   154   int pagemask;
       
   155   int width, height;
       
   156   
       
   157   devname = SDL_getenv("SDL_WSCONSDEV");
       
   158   if (devname == NULL) {
       
   159     int activeVT;
       
   160     if (ioctl(STDIN_FILENO, VT_GETACTIVE, &activeVT) == -1) {
       
   161       WSCONS_ReportError("Unable to determine active terminal: %s", 
       
   162 			 strerror(errno));
       
   163       return -1;
       
   164     }
       
   165     SDL_snprintf(devnamebuf, sizeof(devnamebuf), WSCONSDEV_FORMAT, activeVT - 1);
       
   166     devname = devnamebuf;
       
   167   }
       
   168 
       
   169   private->fd = open(devname, O_RDWR | O_NONBLOCK, 0);
       
   170   if (private->fd == -1) {
       
   171     WSCONS_ReportError("open %s: %s", devname, strerror(errno));
       
   172     return -1;
       
   173   }
       
   174   if (ioctl(private->fd, WSDISPLAYIO_GINFO, &private->info) == -1) {
       
   175     WSCONS_ReportError("ioctl WSDISPLAY_GINFO: %s", strerror(errno));
       
   176     return -1;
       
   177   }
       
   178   if (ioctl(private->fd, WSDISPLAYIO_GTYPE, &wstype) == -1) {
       
   179     WSCONS_ReportError("ioctl WSDISPLAY_GTYPE: %s", strerror(errno));
       
   180     return -1;
       
   181   }
       
   182   if (ioctl(private->fd, WSDISPLAYIO_LINEBYTES, &private->physlinebytes) == -1) {
       
   183     WSCONS_ReportError("ioctl WSDISPLAYIO_LINEBYTES: %s", strerror(errno));
       
   184     return -1;
       
   185   }
       
   186   if (private->info.depth > 8) {
       
   187     if (wstype == WSDISPLAY_TYPE_SUN24 ||
       
   188 	wstype == WSDISPLAY_TYPE_SUNCG12 ||
       
   189 	wstype == WSDISPLAY_TYPE_SUNCG14 ||
       
   190 	wstype == WSDISPLAY_TYPE_SUNTCX ||
       
   191 	wstype == WSDISPLAY_TYPE_SUNFFB) {
       
   192       private->redMask = 0x0000ff;
       
   193       private->greenMask = 0x00ff00;
       
   194       private->blueMask = 0xff0000;
       
   195 #ifdef WSDISPLAY_TYPE_PXALCD
       
   196     } else if (wstype == WSDISPLAY_TYPE_PXALCD) {
       
   197       private->redMask = 0x1f << 11;
       
   198       private->greenMask = 0x3f << 5;
       
   199       private->blueMask = 0x1f;
       
   200 #endif
       
   201     } else {
       
   202       WSCONS_ReportError("Unknown video hardware");
       
   203       return -1;
       
   204     }
       
   205   } else {
       
   206     WSCONS_ReportError("Displays with 8 bpp or less are not supported");
       
   207     return -1;
       
   208   }
       
   209   
       
   210   private->rotate = WSCONS_ROTATE_NONE;
       
   211   rotation = SDL_getenv("SDL_VIDEO_WSCONS_ROTATION");
       
   212   if (rotation != NULL) {
       
   213     if (SDL_strlen(rotation) == 0) {
       
   214       private->shadowFB = 0;
       
   215       private->rotate = WSCONS_ROTATE_NONE;
       
   216       printf("Not rotating, no shadow\n");
       
   217     } else if (!SDL_strcmp(rotation, "NONE")) {
       
   218       private->shadowFB = 1;
       
   219       private->rotate = WSCONS_ROTATE_NONE;
       
   220       printf("Not rotating, but still using shadow\n");
       
   221     } else if (!SDL_strcmp(rotation, "CW")) {
       
   222       private->shadowFB = 1;
       
   223       private->rotate = WSCONS_ROTATE_CW;
       
   224       printf("Rotating screen clockwise\n");
       
   225     } else if (!SDL_strcmp(rotation, "CCW")) {
       
   226       private->shadowFB = 1;
       
   227       private->rotate = WSCONS_ROTATE_CCW;
       
   228       printf("Rotating screen counter clockwise\n");
       
   229     } else if (!SDL_strcmp(rotation, "UD")) {
       
   230       private->shadowFB = 1;
       
   231       private->rotate = WSCONS_ROTATE_UD;
       
   232       printf("Rotating screen upside down\n");
       
   233     } else {
       
   234       WSCONS_ReportError("\"%s\" is not a valid value for "
       
   235 			 "SDL_VIDEO_WSCONS_ROTATION", rotation);
       
   236       return -1;
       
   237     }
       
   238   }
       
   239 
       
   240   switch (private->info.depth) {
       
   241     case 1:
       
   242     case 4:
       
   243     case 8:
       
   244       len = private->physlinebytes * private->info.height;
       
   245       break;
       
   246     case 16:
       
   247       if (private->physlinebytes == private->info.width) {
       
   248 	len = private->info.width * private->info.height * sizeof(short);
       
   249       } else {
       
   250 	len = private->physlinebytes * private->info.height;
       
   251       }
       
   252       if (private->rotate == WSCONS_ROTATE_NONE ||
       
   253 	  private->rotate == WSCONS_ROTATE_UD) {
       
   254 	private->blitFunc = WSCONS_blit16;
       
   255       } else {
       
   256 	private->blitFunc = WSCONS_blit16blocked;
       
   257       }
       
   258       break;
       
   259     case 32:
       
   260       if (private->physlinebytes == private->info.width) {
       
   261 	len = private->info.width * private->info.height * sizeof(int);
       
   262       } else {
       
   263 	len = private->physlinebytes * private->info.height;
       
   264       }
       
   265       break;
       
   266     default:
       
   267       WSCONS_ReportError("unsupported depth %d", private->info.depth);
       
   268       return -1;
       
   269   }
       
   270 
       
   271   if (private->shadowFB && private->blitFunc == NULL) {
       
   272     WSCONS_ReportError("Using software buffer, but no blitter function is "
       
   273 		       "available for this %d bpp.", private->info.depth);
       
   274     return -1;
       
   275   }
       
   276 
       
   277   if (ioctl(private->fd, WSDISPLAYIO_SMODE, &wsmode) == -1) {
       
   278     WSCONS_ReportError("ioctl SMODE");
       
   279     return -1;
       
   280   }
       
   281 
       
   282   pagemask = getpagesize() - 1;
       
   283   mapsize = ((int)len + pagemask) & ~pagemask;
       
   284   private->physmem = (Uint8 *)mmap(NULL, mapsize,
       
   285 				   PROT_READ | PROT_WRITE, MAP_SHARED,
       
   286 				   private->fd, (off_t)0);
       
   287   if (private->physmem == (Uint8 *)MAP_FAILED) {
       
   288     private->physmem = NULL;
       
   289     WSCONS_ReportError("mmap: %s", strerror(errno));
       
   290     return -1;
       
   291   }
       
   292   private->fbmem_len = len;
       
   293 
       
   294   if (private->rotate == WSCONS_ROTATE_CW || 
       
   295       private->rotate == WSCONS_ROTATE_CCW) {
       
   296     width = private->info.height;
       
   297     height = private->info.width;
       
   298   } else {
       
   299     width = private->info.width;
       
   300     height = private->info.height;
       
   301   }
       
   302 
       
   303   this->info.current_w = width;
       
   304   this->info.current_h = height;
       
   305 
       
   306   if (private->shadowFB) {
       
   307     private->shadowmem = (Uint8 *)SDL_malloc(len);
       
   308     if (private->shadowmem == NULL) {
       
   309       WSCONS_ReportError("No memory for shadow");
       
   310       return -1;
       
   311     }
       
   312     private->fbstart = private->shadowmem;
       
   313     private->fblinebytes = width * ((private->info.depth + 7) / 8);
       
   314   } else { 
       
   315     private->fbstart = private->physmem;
       
   316     private->fblinebytes = private->physlinebytes;
       
   317   }
       
   318   
       
   319   private->SDL_modelist[0] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
       
   320   private->SDL_modelist[0]->w = width;
       
   321   private->SDL_modelist[0]->h = height;
       
   322 
       
   323   vformat->BitsPerPixel = private->info.depth;
       
   324   vformat->BytesPerPixel = private->info.depth / 8;
       
   325   
       
   326   if (WSCONS_InitKeyboard(this) == -1) {
       
   327     return -1;
       
   328   }
       
   329   
       
   330   return 0;
       
   331 }
       
   332 
       
   333 SDL_Rect **WSCONS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
       
   334 {
       
   335   if (format->BitsPerPixel == private->info.depth) {
       
   336     return private->SDL_modelist;
       
   337   } else {
       
   338     return NULL;
       
   339   }
       
   340 }
       
   341 
       
   342 SDL_Surface *WSCONS_SetVideoMode(_THIS, SDL_Surface *current,
       
   343 				 int width, int height, int bpp, Uint32 flags)
       
   344 {
       
   345   if (width != private->SDL_modelist[0]->w || 
       
   346       height != private->SDL_modelist[0]->h) {
       
   347     WSCONS_ReportError("Requested video mode %dx%d not supported.",
       
   348 		       width, height);
       
   349     return NULL;
       
   350   }
       
   351   if (bpp != private->info.depth) {
       
   352     WSCONS_ReportError("Requested video depth %d bpp not supported.", bpp);
       
   353     return NULL;
       
   354   }
       
   355 
       
   356   if (!SDL_ReallocFormat(current, 
       
   357 			 bpp, 
       
   358 			 private->redMask,
       
   359 			 private->greenMask,
       
   360 			 private->blueMask,
       
   361 			 0)) {
       
   362     WSCONS_ReportError("Couldn't allocate new pixel format");
       
   363     return NULL;
       
   364   }
       
   365 
       
   366   current->flags &= SDL_FULLSCREEN;
       
   367   if (private->shadowFB) {
       
   368     current->flags |= SDL_SWSURFACE;
       
   369   } else {
       
   370     current->flags |= SDL_HWSURFACE;
       
   371   }
       
   372   current->w = width;
       
   373   current->h = height;
       
   374   current->pitch = private->fblinebytes;
       
   375   current->pixels = private->fbstart;
       
   376 
       
   377   SDL_memset(private->fbstart, 0, private->fbmem_len);
       
   378 
       
   379   return current;
       
   380 }
       
   381 
       
   382 static int WSCONS_AllocHWSurface(_THIS, SDL_Surface *surface)
       
   383 {
       
   384   return -1;
       
   385 }
       
   386 static void WSCONS_FreeHWSurface(_THIS, SDL_Surface *surface)
       
   387 {
       
   388 }
       
   389 
       
   390 static int WSCONS_LockHWSurface(_THIS, SDL_Surface *surface)
       
   391 {
       
   392   return 0;
       
   393 }
       
   394 
       
   395 static void WSCONS_UnlockHWSurface(_THIS, SDL_Surface *surface)
       
   396 {
       
   397 }
       
   398 
       
   399 static void WSCONS_blit16(Uint8 *byte_src_pos,
       
   400 			  int srcRightDelta, 
       
   401 			  int srcDownDelta, 
       
   402 			  Uint8 *byte_dst_pos,
       
   403 			  int dst_linebytes,
       
   404 			  int width,
       
   405 			  int height)
       
   406 {
       
   407   int w;
       
   408   Uint16 *src_pos = (Uint16 *)byte_src_pos;
       
   409   Uint16 *dst_pos = (Uint16 *)byte_dst_pos;
       
   410 
       
   411   while (height) {
       
   412     Uint16 *src = src_pos;
       
   413     Uint16 *dst = dst_pos;
       
   414     for (w = width; w != 0; w--) {
       
   415       *dst = *src;
       
   416       src += srcRightDelta;
       
   417       dst++;
       
   418     }
       
   419     dst_pos = (Uint16 *)((Uint8 *)dst_pos + dst_linebytes);
       
   420     src_pos += srcDownDelta;
       
   421     height--;
       
   422   }
       
   423 }
       
   424 
       
   425 #define BLOCKSIZE_W 32
       
   426 #define BLOCKSIZE_H 32
       
   427 
       
   428 static void WSCONS_blit16blocked(Uint8 *byte_src_pos,
       
   429 				 int srcRightDelta, 
       
   430 				 int srcDownDelta, 
       
   431 				 Uint8 *byte_dst_pos,
       
   432 				 int dst_linebytes,
       
   433 				 int width,
       
   434 				 int height)
       
   435 {
       
   436   int w;
       
   437   Uint16 *src_pos = (Uint16 *)byte_src_pos;
       
   438   Uint16 *dst_pos = (Uint16 *)byte_dst_pos;
       
   439 
       
   440   while (height > 0) {
       
   441     Uint16 *src = src_pos;
       
   442     Uint16 *dst = dst_pos;
       
   443     for (w = width; w > 0; w -= BLOCKSIZE_W) {
       
   444       WSCONS_blit16((Uint8 *)src,
       
   445 		    srcRightDelta,
       
   446 		    srcDownDelta,
       
   447 		    (Uint8 *)dst,
       
   448 		    dst_linebytes,
       
   449 		    min(w, BLOCKSIZE_W),
       
   450 		    min(height, BLOCKSIZE_H));
       
   451       src += srcRightDelta * BLOCKSIZE_W;
       
   452       dst += BLOCKSIZE_W;
       
   453     }
       
   454     dst_pos = (Uint16 *)((Uint8 *)dst_pos + dst_linebytes * BLOCKSIZE_H);
       
   455     src_pos += srcDownDelta * BLOCKSIZE_H;
       
   456     height -= BLOCKSIZE_H;
       
   457   }
       
   458 }
       
   459 
       
   460 static void WSCONS_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
       
   461 {
       
   462   int width = private->SDL_modelist[0]->w;
       
   463   int height = private->SDL_modelist[0]->h;
       
   464   int bytesPerPixel = (private->info.depth + 7) / 8;
       
   465   int i;
       
   466 
       
   467   if (!private->shadowFB) {
       
   468     return;
       
   469   }
       
   470 
       
   471   if (private->info.depth != 16) {
       
   472     WSCONS_ReportError("Shadow copy only implemented for 16 bpp");
       
   473     return;
       
   474   }
       
   475 
       
   476   for (i = 0; i < numrects; i++) {
       
   477     int x1, y1, x2, y2;
       
   478     int scr_x1, scr_y1, scr_x2, scr_y2;
       
   479     int sha_x1, sha_y1;
       
   480     int shadowRightDelta;  /* Address change when moving right in dest */
       
   481     int shadowDownDelta;   /* Address change when moving down in dest */
       
   482     Uint8 *src_start;
       
   483     Uint8 *dst_start;
       
   484 
       
   485     x1 = rects[i].x; 
       
   486     y1 = rects[i].y;
       
   487     x2 = x1 + rects[i].w; 
       
   488     y2 = y1 + rects[i].h;
       
   489 
       
   490     if (x1 < 0) {
       
   491       x1 = 0;
       
   492     } else if (x1 > width) {
       
   493       x1 = width;
       
   494     }
       
   495     if (x2 < 0) {
       
   496       x2 = 0;
       
   497     } else if (x2 > width) {
       
   498       x2 = width;
       
   499     }
       
   500     if (y1 < 0) {
       
   501       y1 = 0;
       
   502     } else if (y1 > height) {
       
   503       y1 = height;
       
   504     }
       
   505     if (y2 < 0) {
       
   506       y2 = 0;
       
   507     } else if (y2 > height) {
       
   508       y2 = height;
       
   509     }
       
   510     if (x2 <= x1 || y2 <= y1) {
       
   511       continue;
       
   512     }
       
   513 
       
   514     switch (private->rotate) {
       
   515       case WSCONS_ROTATE_NONE:
       
   516 	sha_x1 = scr_x1 = x1;
       
   517 	sha_y1 = scr_y1 = y1;
       
   518 	scr_x2 = x2;
       
   519 	scr_y2 = y2;
       
   520 	shadowRightDelta = 1;
       
   521 	shadowDownDelta = width;
       
   522 	break;
       
   523       case WSCONS_ROTATE_CCW:
       
   524 	scr_x1 = y1;
       
   525 	scr_y1 = width - x2;
       
   526 	scr_x2 = y2;
       
   527 	scr_y2 = width - x1;
       
   528 	sha_x1 = x2 - 1;
       
   529 	sha_y1 = y1;
       
   530 	shadowRightDelta = width;
       
   531 	shadowDownDelta = -1;
       
   532 	break;
       
   533       case WSCONS_ROTATE_UD:
       
   534 	scr_x1 = width - x2;
       
   535 	scr_y1 = height - y2;
       
   536 	scr_x2 = width - x1;
       
   537 	scr_y2 = height - y1;
       
   538 	sha_x1 = x2 - 1;
       
   539 	sha_y1 = y2 - 1;
       
   540 	shadowRightDelta = -1;
       
   541 	shadowDownDelta = -width;
       
   542 	break;
       
   543       case WSCONS_ROTATE_CW:
       
   544 	scr_x1 = height - y2;
       
   545 	scr_y1 = x1;
       
   546 	scr_x2 = height - y1;
       
   547 	scr_y2 = x2;
       
   548 	sha_x1 = x1;
       
   549 	sha_y1 = y2 - 1;
       
   550 	shadowRightDelta = -width;
       
   551 	shadowDownDelta = 1;
       
   552 	break;
       
   553       default:
       
   554 	WSCONS_ReportError("Unknown rotation");
       
   555 	return;
       
   556     }
       
   557 
       
   558     src_start = private->shadowmem + (sha_y1 * width + sha_x1) * bytesPerPixel;
       
   559     dst_start = private->physmem + scr_y1 * private->physlinebytes + 
       
   560       scr_x1 * bytesPerPixel;
       
   561 
       
   562     private->blitFunc(src_start,
       
   563 		      shadowRightDelta, 
       
   564 		      shadowDownDelta, 
       
   565 		      dst_start,
       
   566 		      private->physlinebytes,
       
   567 		      scr_x2 - scr_x1,
       
   568 		      scr_y2 - scr_y1);
       
   569   }
       
   570 }
       
   571 
       
   572 int WSCONS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
       
   573 {
       
   574   return 0;
       
   575 }
       
   576 
       
   577 /*
       
   578  * Note: If we are terminated, this could be called in the middle of
       
   579  * another SDL video routine -- notably UpdateRects.
       
   580  */
       
   581 void WSCONS_VideoQuit(_THIS)
       
   582 {
       
   583   int mode = WSDISPLAYIO_MODE_EMUL;
       
   584 
       
   585   if (private->shadowmem != NULL) {
       
   586     SDL_free(private->shadowmem);
       
   587     private->shadowmem = NULL;
       
   588   }
       
   589   private->fbstart = NULL;
       
   590   if (this->screen != NULL) {
       
   591     this->screen->pixels = NULL;
       
   592   }
       
   593 
       
   594   if (private->SDL_modelist[0] != NULL) {
       
   595     SDL_free(private->SDL_modelist[0]);
       
   596     private->SDL_modelist[0] = NULL;
       
   597   }
       
   598 
       
   599   if (ioctl(private->fd, WSDISPLAYIO_SMODE, &mode) == -1) {
       
   600     WSCONS_ReportError("ioctl SMODE");
       
   601   }
       
   602 
       
   603   WSCONS_ReleaseKeyboard(this);
       
   604 
       
   605   if (private->fd != -1) {
       
   606     close(private->fd);
       
   607     private->fd = -1;
       
   608   }
       
   609 }