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