src/video/qtopia/SDL_sysvideo.cc
author Ozkan Sezer <sezeroz@gmail.com>
Sun, 14 Oct 2018 15:25:04 +0300
branchSDL-1.2
changeset 12325 c4f2eeda176f
parent 6137 4720145f848b
permissions -rw-r--r--
remove symlink for libSDL-1.0.so.0 from the rpm spec file.

also fix a changelog date.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2012 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 /* Qtopia based framebuffer implementation */
    25 
    26 #include <unistd.h>
    27 
    28 #include <qapplication.h>
    29 #include <qpe/qpeapplication.h>
    30 
    31 #include "SDL_timer.h"
    32 
    33 #include "SDL_QWin.h"
    34 
    35 extern "C" {
    36 
    37 #include "../SDL_sysvideo.h"
    38 #include "../../events/SDL_events_c.h"
    39 #include "SDL_sysevents_c.h"
    40 #include "SDL_sysmouse_c.h"
    41 #include "SDL_syswm_c.h"
    42 #include "SDL_lowvideo.h"
    43 
    44   //#define QTOPIA_DEBUG
    45 #define QT_HIDDEN_SIZE	32	/* starting hidden window size */
    46 
    47   /* Name of the environment variable used to invert the screen rotation or not:
    48      Possible values:
    49      !=0 : Screen is 270 rotated
    50      0: Screen is 90 rotated*/
    51 #define SDL_QT_ROTATION_ENV_NAME "SDL_QT_INVERT_ROTATION"
    52   
    53   /* Initialization/Query functions */
    54   static int QT_VideoInit(_THIS, SDL_PixelFormat *vformat);
    55   static SDL_Rect **QT_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
    56   static SDL_Surface *QT_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
    57   static void QT_UpdateMouse(_THIS);
    58   static int QT_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
    59   static void QT_VideoQuit(_THIS);
    60 
    61   /* Hardware surface functions */
    62   static int QT_AllocHWSurface(_THIS, SDL_Surface *surface);
    63   static int QT_LockHWSurface(_THIS, SDL_Surface *surface);
    64   static void QT_UnlockHWSurface(_THIS, SDL_Surface *surface);
    65   static void QT_FreeHWSurface(_THIS, SDL_Surface *surface);
    66 
    67   static int QT_ToggleFullScreen(_THIS, int fullscreen);
    68 
    69   static int QT_IconifyWindow(_THIS);
    70   static SDL_GrabMode QT_GrabInput(_THIS, SDL_GrabMode mode);
    71 
    72   /* FB driver bootstrap functions */
    73 
    74   static int QT_Available(void)
    75   {
    76     return(1);
    77   }
    78 
    79   static void QT_DeleteDevice(SDL_VideoDevice *device)
    80   {
    81     SDL_free(device->hidden);
    82     SDL_free(device);
    83   }
    84 
    85   static SDL_VideoDevice *QT_CreateDevice(int devindex)
    86   {
    87     SDL_VideoDevice *device;
    88 
    89     /* Initialize all variables that we clean on shutdown */
    90     device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
    91     if ( device ) {
    92       SDL_memset(device, 0, (sizeof *device));
    93       device->hidden = (struct SDL_PrivateVideoData *)
    94 	SDL_malloc((sizeof *device->hidden));
    95     }
    96     if ( (device == NULL) || (device->hidden == NULL) ) {
    97       SDL_OutOfMemory();
    98       if ( device ) {
    99 	SDL_free(device);
   100       }
   101       return(0);
   102     }
   103     SDL_memset(device->hidden, 0, (sizeof *device->hidden));
   104 
   105     /* Set the function pointers */
   106     device->VideoInit = QT_VideoInit;
   107     device->ListModes = QT_ListModes;
   108     device->SetVideoMode = QT_SetVideoMode;
   109     device->UpdateMouse = QT_UpdateMouse;
   110     device->SetColors = QT_SetColors;
   111     device->UpdateRects = NULL;
   112     device->VideoQuit = QT_VideoQuit;
   113     device->AllocHWSurface = QT_AllocHWSurface;
   114     device->CheckHWBlit = NULL;
   115     device->FillHWRect = NULL;
   116     device->SetHWColorKey = NULL;
   117     device->SetHWAlpha = NULL;
   118     device->LockHWSurface = QT_LockHWSurface;
   119     device->UnlockHWSurface = QT_UnlockHWSurface;
   120     device->FlipHWSurface = NULL;
   121     device->FreeHWSurface = QT_FreeHWSurface;
   122     device->SetIcon = NULL;
   123     device->SetCaption = QT_SetWMCaption;
   124     device->IconifyWindow = QT_IconifyWindow;
   125     device->GrabInput = QT_GrabInput;
   126     device->GetWMInfo = NULL;
   127     device->FreeWMCursor = QT_FreeWMCursor;
   128     device->CreateWMCursor = QT_CreateWMCursor;
   129     device->ShowWMCursor = QT_ShowWMCursor;
   130     device->WarpWMCursor = QT_WarpWMCursor;
   131     device->InitOSKeymap = QT_InitOSKeymap;
   132     device->PumpEvents = QT_PumpEvents;
   133 
   134     device->free = QT_DeleteDevice;
   135     device->ToggleFullScreen = QT_ToggleFullScreen;
   136 
   137     /* Set the driver flags */
   138     device->handles_any_size = 0;
   139 	
   140     return device;
   141   }
   142 
   143   VideoBootStrap Qtopia_bootstrap = {
   144     "qtopia", "Qtopia / QPE graphics",
   145     QT_Available, QT_CreateDevice
   146   };
   147 
   148   /* Function to sort the display_list */
   149   static int CompareModes(const void *A, const void *B)
   150   {
   151 #if 0
   152     const display_mode *a = (display_mode *)A;
   153     const display_mode *b = (display_mode *)B;
   154 
   155     if ( a->space == b->space ) {
   156       return((b->virtual_width*b->virtual_height)-
   157 	     (a->virtual_width*a->virtual_height));
   158     } else {
   159       return(ColorSpaceToBitsPerPixel(b->space)-
   160 	     ColorSpaceToBitsPerPixel(a->space));
   161     }
   162 #endif
   163     return 0;
   164   }
   165 
   166   /* Yes, this isn't the fastest it could be, but it works nicely */
   167   static int QT_AddMode(_THIS, int index, unsigned int w, unsigned int h)
   168   {
   169     SDL_Rect *mode;
   170     int i;
   171     int next_mode;
   172 
   173     /* Check to see if we already have this mode */
   174     if ( SDL_nummodes[index] > 0 ) {
   175       for ( i=SDL_nummodes[index]-1; i >= 0; --i ) {
   176 	mode = SDL_modelist[index][i];
   177 	if ( (mode->w == w) && (mode->h == h) ) {
   178 	  return(0);
   179 	}
   180       }
   181     }
   182 
   183     /* Set up the new video mode rectangle */
   184     mode = (SDL_Rect *)SDL_malloc(sizeof *mode);
   185     if ( mode == NULL ) {
   186       SDL_OutOfMemory();
   187       return(-1);
   188     }
   189     mode->x = 0;
   190     mode->y = 0;
   191     mode->w = w;
   192     mode->h = h;
   193 #ifdef QTOPIA_DEBUG
   194     fprintf(stderr, "Adding mode %dx%d at %d bytes per pixel\n", w, h, index+1);
   195 #endif
   196 
   197     /* Allocate the new list of modes, and fill in the new mode */
   198     next_mode = SDL_nummodes[index];
   199     SDL_modelist[index] = (SDL_Rect **)
   200       SDL_realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *));
   201     if ( SDL_modelist[index] == NULL ) {
   202       SDL_OutOfMemory();
   203       SDL_nummodes[index] = 0;
   204       SDL_free(mode);
   205       return(-1);
   206     }
   207     SDL_modelist[index][next_mode] = mode;
   208     SDL_modelist[index][next_mode+1] = NULL;
   209     SDL_nummodes[index]++;
   210 
   211     return(0);
   212   }
   213 
   214   int QT_VideoInit(_THIS, SDL_PixelFormat *vformat)
   215   {
   216     /* Initialize the QPE Application  */
   217      /* Determine the screen depth */
   218     vformat->BitsPerPixel = QPixmap::defaultDepth();
   219 
   220     // For now we hardcode the current depth because anything else
   221     // might as well be emulated by SDL rather than by Qtopia.
   222     
   223     QSize desktop_size = qApp->desktop()->size();
   224     QT_AddMode(_this, ((vformat->BitsPerPixel+7)/8)-1,
   225 	       desktop_size.width(), desktop_size.height());
   226     QT_AddMode(_this, ((vformat->BitsPerPixel+7)/8)-1,
   227 	       desktop_size.height(), desktop_size.width());
   228 
   229     /* Determine the current screen size */
   230     _this->info.current_w = desktop_size.width();
   231     _this->info.current_h = desktop_size.height();
   232 
   233     /* Create the window / widget */
   234     SDL_Win = new SDL_QWin(QSize(QT_HIDDEN_SIZE, QT_HIDDEN_SIZE));
   235     ((QPEApplication*)qApp)->showMainWidget(SDL_Win);
   236     /* Fill in some window manager capabilities */
   237     _this->info.wm_available = 0;
   238 
   239     /* We're done! */
   240     return(0);
   241   }
   242 
   243   /* We support any dimension at our bit-depth */
   244   SDL_Rect **QT_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
   245   {
   246     SDL_Rect **modes;
   247 
   248     modes = ((SDL_Rect **)0);
   249     if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
   250       modes = SDL_modelist[((format->BitsPerPixel+7)/8)-1];
   251     } else {
   252       if ( format->BitsPerPixel ==
   253 	   _this->screen->format->BitsPerPixel ) {
   254 	modes = ((SDL_Rect **)-1);
   255       }
   256     }
   257     return(modes);
   258   }
   259 
   260   /* Various screen update functions available */
   261   static void QT_NormalUpdate(_THIS, int numrects, SDL_Rect *rects);
   262 
   263 
   264   static int QT_SetFullScreen(_THIS, SDL_Surface *screen, int fullscreen)
   265   {
   266     return -1;
   267   }
   268 
   269   static int QT_ToggleFullScreen(_THIS, int fullscreen)
   270   {
   271     return -1;
   272   }
   273 
   274   /* FIXME: check return values and cleanup here */
   275   SDL_Surface *QT_SetVideoMode(_THIS, SDL_Surface *current,
   276 			       int width, int height, int bpp, Uint32 flags)
   277   {
   278 
   279     QImage *qimage;
   280     QSize desktop_size = qApp->desktop()->size();
   281 
   282     
   283     current->flags = 0; //SDL_FULLSCREEN; // We always run fullscreen.
   284 
   285     if(width <= desktop_size.width()
   286 	      && height <= desktop_size.height()) {
   287       current->w = desktop_size.width();
   288       current->h = desktop_size.height();
   289     } else if(width <= desktop_size.height() && height <= desktop_size.width()) {
   290       // Landscape mode
   291       char * envString = SDL_getenv(SDL_QT_ROTATION_ENV_NAME);
   292       int envValue = envString ? atoi(envString) : 0;
   293       screenRotation = envValue ? SDL_QT_ROTATION_270 : SDL_QT_ROTATION_90;
   294       current->h = desktop_size.width();
   295       current->w = desktop_size.height();
   296     } else {
   297       SDL_SetError("Unsupported resolution, %dx%d\n", width, height);
   298     }
   299     if ( flags & SDL_OPENGL ) {
   300       SDL_SetError("OpenGL not supported");
   301       return(NULL);
   302     } 
   303     /* Create the QImage framebuffer */
   304     qimage = new QImage(current->w, current->h, bpp);
   305     if (qimage->isNull()) {
   306       SDL_SetError("Couldn't create screen bitmap");
   307       delete qimage;
   308       return(NULL);
   309     }
   310     current->pitch = qimage->bytesPerLine();
   311     current->pixels = (void *)qimage->bits();
   312     SDL_Win->setImage(qimage);
   313     _this->UpdateRects = QT_NormalUpdate;
   314     SDL_Win->setFullscreen(true);
   315     /* We're done */
   316     return(current);
   317   }
   318 
   319   /* Update the current mouse state and position */
   320   void QT_UpdateMouse(_THIS)
   321   {
   322     QPoint point(-1, -1);
   323     if ( SDL_Win->isActiveWindow() ) {
   324       point = SDL_Win->mousePos();
   325     }
   326     
   327     if ( (point.x() >= 0) && (point.x() < SDL_VideoSurface->w) &&
   328 	 (point.y() >= 0) && (point.y() < SDL_VideoSurface->h) ) {
   329       SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
   330       SDL_PrivateMouseMotion(0, 0,
   331 			     (Sint16)point.x(), (Sint16)point.y());
   332     } else {
   333       SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
   334     }
   335   }
   336 
   337   /* We don't actually allow hardware surfaces other than the main one */
   338   static int QT_AllocHWSurface(_THIS, SDL_Surface *surface)
   339   {
   340     return(-1);
   341   }
   342   static void QT_FreeHWSurface(_THIS, SDL_Surface *surface)
   343   {
   344     return;
   345   }
   346   static int QT_LockHWSurface(_THIS, SDL_Surface *surface)
   347   {
   348     return(0);
   349   }
   350   static void QT_UnlockHWSurface(_THIS, SDL_Surface *surface)
   351   {
   352     return;
   353   }
   354 
   355   static void QT_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
   356   {
   357     if(SDL_Win->lockScreen()) {
   358       for(int i=0; i<numrects; ++i ) {
   359 	QRect rect(rects[i].x, rects[i].y,
   360 		   rects[i].w, rects[i].h);
   361 	SDL_Win->repaintRect(rect);
   362       }
   363       SDL_Win->unlockScreen();
   364     }
   365   }
   366   /* Is the system palette settable? */
   367   int QT_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
   368   {
   369     return -1;
   370   }
   371 
   372   void QT_VideoQuit(_THIS)
   373   {
   374     // This is dumb, but if I free this, the app doesn't exit correctly.
   375     // Of course, this will leak memory if init video is done more than once.
   376     // Sucks but such is life.
   377     
   378     //    -- David Hedbor
   379     //    delete SDL_Win; 
   380     //    SDL_Win = 0;
   381     _this->screen->pixels = NULL;
   382     QT_GrabInput(_this, SDL_GRAB_OFF);
   383   }
   384 
   385   static int QT_IconifyWindow(_THIS) {
   386     SDL_Win->hide();
   387     
   388     return true;
   389   }
   390 
   391   static SDL_GrabMode QT_GrabInput(_THIS, SDL_GrabMode mode) {
   392     if(mode == SDL_GRAB_OFF) {
   393       QPEApplication::grabKeyboard();
   394       qApp->processEvents();
   395       QPEApplication::ungrabKeyboard();
   396     } else {
   397       QPEApplication::grabKeyboard();
   398     }
   399     qApp->processEvents();
   400     return mode;
   401   }
   402   
   403 }; /* Extern C */