comparison src/video/qtopia/SDL_sysvideo.cc @ 371:db0cc6034336

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