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