Mercurial > sdl-ios-xcode
comparison src/video/directfb/SDL_DirectFB_video.c @ 167:cb384ef627f6
Added support for DirectFB video on Linux (thanks Denis!)
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Tue, 04 Sep 2001 22:53:46 +0000 |
parents | |
children | f928da36f0e9 |
comparison
equal
deleted
inserted
replaced
166:39877400bd1e | 167:cb384ef627f6 |
---|---|
1 /* | |
2 SDL - Simple DirectMedia Layer | |
3 Copyright (C) 1997, 1998, 1999, 2000, 2001 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@devolution.com | |
21 */ | |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* DirectFB video driver implementation. | |
29 */ | |
30 | |
31 #include <stdlib.h> | |
32 #include <stdio.h> | |
33 #include <fcntl.h> | |
34 #include <unistd.h> | |
35 #include <sys/mman.h> | |
36 | |
37 #include <directfb.h> | |
38 | |
39 #include "SDL.h" | |
40 #include "SDL_error.h" | |
41 #include "SDL_video.h" | |
42 #include "SDL_mouse.h" | |
43 #include "SDL_sysvideo.h" | |
44 #include "SDL_pixels_c.h" | |
45 #include "SDL_events_c.h" | |
46 #include "SDL_DirectFB_video.h" | |
47 #include "SDL_DirectFB_events.h" | |
48 | |
49 | |
50 /* Initialization/Query functions */ | |
51 static int DirectFB_VideoInit(_THIS, SDL_PixelFormat *vformat); | |
52 static SDL_Rect **DirectFB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); | |
53 static SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | |
54 static int DirectFB_SetColors(_THIS, int firstcolor, int ncolors, | |
55 SDL_Color *colors); | |
56 static void DirectFB_VideoQuit(_THIS); | |
57 | |
58 /* Hardware surface functions */ | |
59 static int DirectFB_AllocHWSurface(_THIS, SDL_Surface *surface); | |
60 static int DirectFB_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color); | |
61 static int DirectFB_LockHWSurface(_THIS, SDL_Surface *surface); | |
62 static void DirectFB_UnlockHWSurface(_THIS, SDL_Surface *surface); | |
63 static void DirectFB_FreeHWSurface(_THIS, SDL_Surface *surface); | |
64 static int DirectFB_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst); | |
65 static int DirectFB_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, | |
66 SDL_Surface *dst, SDL_Rect *dstrect); | |
67 static int DirectFB_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key); | |
68 static int DirectFB_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha); | |
69 static int DirectFB_FlipHWSurface(_THIS, SDL_Surface *surface); | |
70 | |
71 /* Various screen update functions available */ | |
72 static void DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects); | |
73 static void DirectFB_WindowedUpdate(_THIS, int numrects, SDL_Rect *rects); | |
74 | |
75 /* This is the rect EnumModes2 uses */ | |
76 struct DirectFBEnumRect { | |
77 SDL_Rect r; | |
78 struct DirectFBEnumRect* next; | |
79 }; | |
80 | |
81 static struct DirectFBEnumRect *enumlists[NUM_MODELISTS]; | |
82 | |
83 | |
84 /* DirectFB driver bootstrap functions */ | |
85 | |
86 static int DirectFB_Available(void) | |
87 { | |
88 return 1; | |
89 } | |
90 | |
91 static void DirectFB_DeleteDevice(SDL_VideoDevice *device) | |
92 { | |
93 free(device->hidden); | |
94 free(device); | |
95 } | |
96 | |
97 static SDL_VideoDevice *DirectFB_CreateDevice(int devindex) | |
98 { | |
99 SDL_VideoDevice *device; | |
100 | |
101 /* Initialize all variables that we clean on shutdown */ | |
102 device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice)); | |
103 if (device) | |
104 { | |
105 memset (device, 0, (sizeof *device)); | |
106 device->hidden = (struct SDL_PrivateVideoData *) malloc (sizeof (*device->hidden)); | |
107 } | |
108 if (device == NULL || device->hidden == NULL) | |
109 { | |
110 SDL_OutOfMemory(); | |
111 if (device) | |
112 { | |
113 free (device); | |
114 } | |
115 return(0); | |
116 } | |
117 memset (device->hidden, 0, sizeof (*device->hidden)); | |
118 | |
119 /* Set the function pointers */ | |
120 device->VideoInit = DirectFB_VideoInit; | |
121 device->ListModes = DirectFB_ListModes; | |
122 device->SetVideoMode = DirectFB_SetVideoMode; | |
123 device->SetColors = DirectFB_SetColors; | |
124 device->UpdateRects = NULL; | |
125 device->VideoQuit = DirectFB_VideoQuit; | |
126 device->AllocHWSurface = DirectFB_AllocHWSurface; | |
127 device->CheckHWBlit = DirectFB_CheckHWBlit; | |
128 device->FillHWRect = DirectFB_FillHWRect; | |
129 device->SetHWColorKey = DirectFB_SetHWColorKey; | |
130 device->SetHWAlpha = DirectFB_SetHWAlpha; | |
131 device->LockHWSurface = DirectFB_LockHWSurface; | |
132 device->UnlockHWSurface = DirectFB_UnlockHWSurface; | |
133 device->FlipHWSurface = DirectFB_FlipHWSurface; | |
134 device->FreeHWSurface = DirectFB_FreeHWSurface; | |
135 device->SetCaption = NULL; | |
136 device->SetIcon = NULL; | |
137 device->IconifyWindow = NULL; | |
138 device->GrabInput = NULL; | |
139 device->GetWMInfo = NULL; | |
140 device->InitOSKeymap = DirectFB_InitOSKeymap; | |
141 device->PumpEvents = DirectFB_PumpEvents; | |
142 | |
143 device->free = DirectFB_DeleteDevice; | |
144 | |
145 return device; | |
146 } | |
147 | |
148 VideoBootStrap DirectFB_bootstrap = { | |
149 "directfb", "DirectFB", | |
150 DirectFB_Available, DirectFB_CreateDevice | |
151 }; | |
152 | |
153 static DFBEnumerationResult EnumModesCallback (unsigned int width, | |
154 unsigned int height, | |
155 unsigned int bpp, | |
156 void *data) | |
157 { | |
158 SDL_VideoDevice *this = (SDL_VideoDevice *)data; | |
159 struct DirectFBEnumRect *enumrect; | |
160 | |
161 switch (bpp) | |
162 { | |
163 case 8: | |
164 case 15: | |
165 case 16: | |
166 case 24: | |
167 case 32: | |
168 bpp /= 8; --bpp; | |
169 ++HIDDEN->SDL_nummodes[bpp]; | |
170 enumrect = (struct DirectFBEnumRect*)malloc(sizeof(struct DirectFBEnumRect)); | |
171 if ( !enumrect ) | |
172 { | |
173 SDL_OutOfMemory(); | |
174 return DFENUM_CANCEL; | |
175 } | |
176 enumrect->r.x = 0; | |
177 enumrect->r.y = 0; | |
178 enumrect->r.w = width; | |
179 enumrect->r.h = height; | |
180 enumrect->next = enumlists[bpp]; | |
181 enumlists[bpp] = enumrect; | |
182 break; | |
183 } | |
184 | |
185 return DFENUM_OK; | |
186 } | |
187 | |
188 struct private_hwdata { | |
189 IDirectFBSurface *surface; | |
190 }; | |
191 | |
192 void SetDirectFBerror (const char *function, DFBResult code) | |
193 { | |
194 const char *error = DirectFBErrorString (code); | |
195 | |
196 if (error) | |
197 SDL_SetError("%s: %s", function, error); | |
198 else | |
199 SDL_SetError("Unknown error code from %s", function); | |
200 } | |
201 | |
202 static DFBSurfacePixelFormat SDLToDFBPixelFormat (SDL_PixelFormat *format) | |
203 { | |
204 if (format->Rmask && format->Gmask && format->Bmask) | |
205 { | |
206 switch (format->BitsPerPixel) | |
207 { | |
208 case 16: | |
209 if (format->Rmask == 0xF800 && | |
210 format->Gmask == 0x07E0 && | |
211 format->Bmask == 0x001F) | |
212 return DSPF_RGB16; | |
213 /* fall through */ | |
214 | |
215 case 15: | |
216 if (format->Rmask == 0x7C00 && | |
217 format->Gmask == 0x03E0 && | |
218 format->Bmask == 0x001F) | |
219 return DSPF_RGB15; | |
220 break; | |
221 | |
222 case 24: | |
223 if (format->Rmask == 0xFF0000 && | |
224 format->Gmask == 0x00FF00 && | |
225 format->Bmask == 0x0000FF) | |
226 return DSPF_RGB24; | |
227 break; | |
228 | |
229 case 32: | |
230 if (format->Rmask == 0xFF0000 && | |
231 format->Gmask == 0x00FF00 && | |
232 format->Bmask == 0x0000FF) | |
233 { | |
234 if (format->Amask == 0xFF000000) | |
235 return DSPF_ARGB; | |
236 else | |
237 return DSPF_RGB32; | |
238 } | |
239 break; | |
240 } | |
241 } | |
242 else | |
243 { | |
244 switch (format->BitsPerPixel) | |
245 { | |
246 case 15: | |
247 return DSPF_RGB15; | |
248 case 16: | |
249 return DSPF_RGB16; | |
250 case 24: | |
251 return DSPF_RGB24; | |
252 case 32: | |
253 return DSPF_RGB32; | |
254 } | |
255 } | |
256 | |
257 return DSPF_UNKNOWN; | |
258 } | |
259 | |
260 static int DFBToSDLPixelFormat (DFBSurfacePixelFormat pixelformat, SDL_PixelFormat *format) | |
261 { | |
262 format->BitsPerPixel = 0; | |
263 format->Amask = format->Rmask = format->Gmask = format->Bmask = 0; | |
264 | |
265 switch (pixelformat) | |
266 { | |
267 case DSPF_A8: | |
268 format->Amask = 0x000000FF; | |
269 break; | |
270 case DSPF_RGB15: | |
271 format->Rmask = 0x00007C00; | |
272 format->Gmask = 0x000003E0; | |
273 format->Bmask = 0x0000001F; | |
274 break; | |
275 case DSPF_RGB16: | |
276 format->Rmask = 0x0000F800; | |
277 format->Gmask = 0x000007E0; | |
278 format->Bmask = 0x0000001F; | |
279 break; | |
280 case DSPF_ARGB: | |
281 format->Amask = 0xFF000000; | |
282 /* fall through */ | |
283 case DSPF_RGB24: | |
284 case DSPF_RGB32: | |
285 format->Rmask = 0x00FF0000; | |
286 format->Gmask = 0x0000FF00; | |
287 format->Bmask = 0x000000FF; | |
288 break; | |
289 default: | |
290 return -1; | |
291 } | |
292 | |
293 format->BitsPerPixel = BITS_PER_PIXEL(pixelformat); | |
294 | |
295 return 0; | |
296 } | |
297 | |
298 | |
299 int DirectFB_VideoInit(_THIS, SDL_PixelFormat *vformat) | |
300 { | |
301 int i, j; | |
302 DFBResult ret; | |
303 IDirectFB *dfb; | |
304 DFBCardCapabilities caps; | |
305 IDirectFBDisplayLayer *layer; | |
306 DFBDisplayLayerConfig dlc; | |
307 IDirectFBInputBuffer *inputbuffer; | |
308 | |
309 | |
310 ret = DirectFBInit (NULL, NULL); | |
311 if (ret) | |
312 { | |
313 SetDirectFBerror ("DirectFBInit", ret); | |
314 return -1; | |
315 } | |
316 | |
317 ret = DirectFBCreate (&dfb); | |
318 if (ret) | |
319 { | |
320 SetDirectFBerror ("DirectFBCreate", ret); | |
321 return -1; | |
322 } | |
323 | |
324 ret = dfb->GetDisplayLayer (dfb, DLID_PRIMARY, &layer); | |
325 if (ret) | |
326 { | |
327 SetDirectFBerror ("dfb->GetDisplayLayer", ret); | |
328 dfb->Release (dfb); | |
329 return -1; | |
330 } | |
331 | |
332 ret = dfb->CreateInputBuffer (dfb, DICAPS_BUTTONS | DICAPS_AXIS | DICAPS_KEYS, | |
333 &inputbuffer); | |
334 if (ret) | |
335 { | |
336 SetDirectFBerror ("dfb->CreateInputBuffer", ret); | |
337 layer->Release (layer); | |
338 dfb->Release (dfb); | |
339 return -1; | |
340 } | |
341 | |
342 layer->EnableCursor (layer, 1); | |
343 | |
344 /* Query layer configuration to determine the current mode and pixelformat */ | |
345 layer->GetConfiguration (layer, &dlc); | |
346 | |
347 if (DFBToSDLPixelFormat (dlc.pixelformat, vformat)) | |
348 { | |
349 SDL_SetError ("Unsupported pixelformat"); | |
350 layer->Release (layer); | |
351 dfb->Release (dfb); | |
352 return -1; | |
353 } | |
354 | |
355 /* Enumerate the available fullscreen modes */ | |
356 for ( i=0; i<NUM_MODELISTS; ++i ) | |
357 enumlists[i] = NULL; | |
358 | |
359 ret = dfb->EnumVideoModes (dfb, EnumModesCallback, this); | |
360 if (ret) | |
361 { | |
362 SetDirectFBerror ("dfb->EnumVideoModes", ret); | |
363 layer->Release (layer); | |
364 dfb->Release (dfb); | |
365 return(-1); | |
366 } | |
367 for ( i=0; i<NUM_MODELISTS; ++i ) | |
368 { | |
369 struct DirectFBEnumRect *rect; | |
370 HIDDEN->SDL_modelist[i] = (SDL_Rect **) malloc | |
371 ((HIDDEN->SDL_nummodes[i]+1)*sizeof(SDL_Rect *)); | |
372 if ( HIDDEN->SDL_modelist[i] == NULL ) | |
373 { | |
374 SDL_OutOfMemory(); | |
375 return(-1); | |
376 } | |
377 for ( j = 0, rect = enumlists[i]; rect; ++j, rect = rect->next ) | |
378 { | |
379 HIDDEN->SDL_modelist[i][j]=(SDL_Rect *)rect; | |
380 } | |
381 HIDDEN->SDL_modelist[i][j] = NULL; | |
382 } | |
383 | |
384 /* Query card capabilities to get the video memory size */ | |
385 dfb->GetCardCapabilities (dfb, &caps); | |
386 | |
387 this->info.wm_available = 1; | |
388 this->info.hw_available = 1; | |
389 this->info.blit_hw = 1; | |
390 this->info.blit_hw_CC = 1; | |
391 this->info.blit_hw_A = 1; | |
392 this->info.blit_fill = 1; | |
393 this->info.video_mem = caps.video_memory / 1024; | |
394 | |
395 HIDDEN->initialized = 1; | |
396 HIDDEN->dfb = dfb; | |
397 HIDDEN->layer = layer; | |
398 HIDDEN->inputbuffer = inputbuffer; | |
399 | |
400 return 0; | |
401 } | |
402 | |
403 static SDL_Rect **DirectFB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) | |
404 { | |
405 if (flags & SDL_FULLSCREEN) | |
406 return HIDDEN->SDL_modelist[((format->BitsPerPixel + 7) / 8) - 1]; | |
407 else | |
408 if (SDLToDFBPixelFormat (format) != DSPF_UNKNOWN) | |
409 return (SDL_Rect**) -1; | |
410 | |
411 return NULL; | |
412 } | |
413 | |
414 SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) | |
415 { | |
416 DFBResult ret; | |
417 DFBSurfaceDescription dsc; | |
418 DFBSurfacePixelFormat pixelformat; | |
419 | |
420 fprintf (stderr, "SDL DirectFB_SetVideoMode: %dx%d@%d, flags: 0x%08x\n", | |
421 width, height, bpp, flags); | |
422 | |
423 flags |= SDL_FULLSCREEN; | |
424 | |
425 /* Release previous primary surface */ | |
426 if (current->hwdata && current->hwdata->surface) | |
427 { | |
428 current->hwdata->surface->Release (current->hwdata->surface); | |
429 current->hwdata->surface = NULL; | |
430 } | |
431 else if (!current->hwdata) | |
432 { | |
433 /* Allocate the hardware acceleration data */ | |
434 current->hwdata = (struct private_hwdata *) malloc (sizeof(*current->hwdata)); | |
435 if (!current->hwdata) | |
436 { | |
437 SDL_OutOfMemory(); | |
438 return NULL; | |
439 } | |
440 memset (current->hwdata, 0, sizeof(*current->hwdata)); | |
441 } | |
442 | |
443 /* Set cooperative level depending on flag SDL_FULLSCREEN */ | |
444 if (flags & SDL_FULLSCREEN) | |
445 { | |
446 ret = HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_FULLSCREEN); | |
447 if (ret) | |
448 { | |
449 DirectFBError ("dfb->SetCooperativeLevel", ret); | |
450 flags &= ~SDL_FULLSCREEN; | |
451 } | |
452 } | |
453 else | |
454 HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_NORMAL); | |
455 | |
456 /* Set video mode */ | |
457 ret = HIDDEN->dfb->SetVideoMode (HIDDEN->dfb, width, height, bpp); | |
458 if (ret) | |
459 { | |
460 if (flags & SDL_FULLSCREEN) | |
461 { | |
462 flags &= ~SDL_FULLSCREEN; | |
463 HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_NORMAL); | |
464 ret = HIDDEN->dfb->SetVideoMode (HIDDEN->dfb, width, height, bpp); | |
465 } | |
466 | |
467 if (ret) | |
468 { | |
469 SetDirectFBerror ("dfb->SetVideoMode", ret); | |
470 return NULL; | |
471 } | |
472 } | |
473 | |
474 /* Create primary surface */ | |
475 dsc.flags = DSDESC_CAPS; | |
476 dsc.caps = DSCAPS_PRIMARY | ((flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0); | |
477 | |
478 ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, ¤t->hwdata->surface); | |
479 if (ret && (flags & SDL_DOUBLEBUF)) | |
480 { | |
481 /* Try without double buffering */ | |
482 dsc.caps &= ~DSCAPS_FLIPPING; | |
483 ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, ¤t->hwdata->surface); | |
484 } | |
485 if (ret) | |
486 { | |
487 SetDirectFBerror ("dfb->CreateSurface", ret); | |
488 current->hwdata->surface = NULL; | |
489 return NULL; | |
490 } | |
491 | |
492 current->w = width; | |
493 current->h = height; | |
494 current->flags = SDL_HWSURFACE | SDL_PREALLOC; | |
495 | |
496 if (flags & SDL_FULLSCREEN) | |
497 { | |
498 current->flags |= SDL_FULLSCREEN; | |
499 this->UpdateRects = DirectFB_DirectUpdate; | |
500 } | |
501 else | |
502 this->UpdateRects = DirectFB_WindowedUpdate; | |
503 | |
504 if (dsc.caps & DSCAPS_FLIPPING) | |
505 current->flags |= SDL_DOUBLEBUF; | |
506 | |
507 current->hwdata->surface->GetPixelFormat (current->hwdata->surface, &pixelformat); | |
508 DFBToSDLPixelFormat (pixelformat, current->format); | |
509 | |
510 return current; | |
511 } | |
512 | |
513 static int DirectFB_AllocHWSurface(_THIS, SDL_Surface *surface) | |
514 { | |
515 DFBResult ret; | |
516 DFBSurfaceDescription dsc; | |
517 | |
518 /* fprintf(stderr, "SDL: DirectFB_AllocHWSurface (%dx%d@%d, flags: 0x%08x)\n", | |
519 surface->w, surface->h, surface->format->BitsPerPixel, surface->flags);*/ | |
520 | |
521 if (surface->w < 8 || surface->h < 8) | |
522 return -1; | |
523 | |
524 /* fill surface description */ | |
525 dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS; | |
526 dsc.width = surface->w; | |
527 dsc.height = surface->h; | |
528 dsc.caps = surface->flags & SDL_DOUBLEBUF ? DSCAPS_FLIPPING : 0; | |
529 | |
530 /* find the right pixelformat */ | |
531 dsc.pixelformat = SDLToDFBPixelFormat (surface->format); | |
532 if (dsc.pixelformat == DSPF_UNKNOWN) | |
533 return -1; | |
534 | |
535 /* Allocate the hardware acceleration data */ | |
536 surface->hwdata = (struct private_hwdata *) malloc (sizeof(*surface->hwdata)); | |
537 if (surface->hwdata == NULL) | |
538 { | |
539 SDL_OutOfMemory(); | |
540 return -1; | |
541 } | |
542 | |
543 /* Create the surface */ | |
544 ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &surface->hwdata->surface); | |
545 if (ret) | |
546 { | |
547 SetDirectFBerror ("dfb->CreateSurface", ret); | |
548 free (surface->hwdata); | |
549 surface->hwdata = NULL; | |
550 return -1; | |
551 } | |
552 | |
553 surface->flags |= SDL_HWSURFACE | SDL_PREALLOC; | |
554 | |
555 return 0; | |
556 } | |
557 | |
558 static void DirectFB_FreeHWSurface(_THIS, SDL_Surface *surface) | |
559 { | |
560 if (surface->hwdata && HIDDEN->initialized) | |
561 { | |
562 surface->hwdata->surface->Release (surface->hwdata->surface); | |
563 free (surface->hwdata); | |
564 surface->hwdata = NULL; | |
565 } | |
566 } | |
567 | |
568 static int DirectFB_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst) | |
569 { | |
570 /* fprintf(stderr, "SDL: DirectFB_CheckHWBlit (src->hwdata: %p, dst->hwdata: %p)\n", | |
571 src->hwdata, dst->hwdata);*/ | |
572 | |
573 if (!src->hwdata || !dst->hwdata) | |
574 return 0; | |
575 | |
576 src->flags |= SDL_HWACCEL; | |
577 src->map->hw_blit = DirectFB_HWAccelBlit; | |
578 | |
579 return 1; | |
580 } | |
581 | |
582 static int DirectFB_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, | |
583 SDL_Surface *dst, SDL_Rect *dstrect) | |
584 { | |
585 DFBRectangle sr, dr; | |
586 IDirectFBSurface *surface; | |
587 DFBSurfaceBlittingFlags flags = DSBLIT_NOFX; | |
588 | |
589 sr.x = srcrect->x; | |
590 sr.y = srcrect->y; | |
591 sr.w = srcrect->w; | |
592 sr.h = srcrect->h; | |
593 | |
594 dr.x = dstrect->x; | |
595 dr.y = dstrect->y; | |
596 dr.w = dstrect->w; | |
597 dr.h = dstrect->h; | |
598 | |
599 surface = dst->hwdata->surface; | |
600 | |
601 if (src->flags & SDL_SRCCOLORKEY) | |
602 { | |
603 flags |= DSBLIT_SRC_COLORKEY; | |
604 surface->SetSrcColorKey (surface, src->format->colorkey); | |
605 } | |
606 | |
607 if (src->flags & SDL_SRCALPHA) | |
608 { | |
609 flags |= DSBLIT_BLEND_COLORALPHA; | |
610 surface->SetColor (surface, 0xff, 0xff, 0xff, src->format->alpha); | |
611 } | |
612 | |
613 surface->SetBlittingFlags (surface, flags); | |
614 | |
615 if (sr.w == dr.w && sr.h == dr.h) | |
616 surface->Blit (surface, src->hwdata->surface, &sr, dr.x, dr.y); | |
617 else | |
618 surface->StretchBlit (surface, src->hwdata->surface, &sr, &dr); | |
619 | |
620 return 0; | |
621 } | |
622 | |
623 static int DirectFB_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color) | |
624 { | |
625 SDL_PixelFormat *fmt = dst->format; | |
626 IDirectFBSurface *surface = dst->hwdata->surface; | |
627 | |
628 /* ugly */ | |
629 surface->SetColor (surface, | |
630 (color & fmt->Rmask) >> (fmt->Rshift - fmt->Rloss), | |
631 (color & fmt->Gmask) >> (fmt->Gshift - fmt->Gloss), | |
632 (color & fmt->Bmask) << (fmt->Bloss - fmt->Bshift), 0xFF); | |
633 surface->FillRectangle (surface, dstrect->x, dstrect->y, dstrect->w, dstrect->h); | |
634 | |
635 return 0; | |
636 } | |
637 | |
638 static int DirectFB_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key) | |
639 { | |
640 return 0; | |
641 } | |
642 | |
643 static int DirectFB_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha) | |
644 { | |
645 return 0; | |
646 } | |
647 | |
648 static int DirectFB_FlipHWSurface(_THIS, SDL_Surface *surface) | |
649 { | |
650 return surface->hwdata->surface->Flip (surface->hwdata->surface, NULL, DSFLIP_WAITFORSYNC); | |
651 } | |
652 | |
653 static int DirectFB_LockHWSurface(_THIS, SDL_Surface *surface) | |
654 { | |
655 DFBResult ret; | |
656 void *data; | |
657 int pitch; | |
658 | |
659 ret = surface->hwdata->surface->Lock (surface->hwdata->surface, | |
660 DSLF_WRITE, &data, &pitch); | |
661 if (ret) | |
662 { | |
663 SetDirectFBerror ("surface->Lock", ret); | |
664 return -1; | |
665 } | |
666 | |
667 surface->pixels = data; | |
668 surface->pitch = pitch; | |
669 | |
670 return 0; | |
671 } | |
672 | |
673 static void DirectFB_UnlockHWSurface(_THIS, SDL_Surface *surface) | |
674 { | |
675 surface->hwdata->surface->Unlock (surface->hwdata->surface); | |
676 surface->pixels = NULL; | |
677 } | |
678 | |
679 static void DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects) | |
680 { | |
681 } | |
682 | |
683 static void DirectFB_WindowedUpdate(_THIS, int numrects, SDL_Rect *rects) | |
684 { | |
685 IDirectFBSurface *surface = this->screen->hwdata->surface; | |
686 DFBRegion region = { rects->x, rects->y, | |
687 rects->x + rects->w - 1, | |
688 rects->y + rects->h - 1 }; | |
689 | |
690 while (--numrects) | |
691 { | |
692 int x2, y2; | |
693 | |
694 rects++; | |
695 | |
696 if (rects->x < region.x1) | |
697 region.x1 = rects->x; | |
698 | |
699 if (rects->y < region.y1) | |
700 region.y1 = rects->y; | |
701 | |
702 x2 = rects->x + rects->w - 1; | |
703 y2 = rects->y + rects->h - 1; | |
704 | |
705 if (x2 > region.x2) | |
706 region.x2 = x2; | |
707 | |
708 if (y2 > region.y2) | |
709 region.y2 = y2; | |
710 } | |
711 | |
712 surface->Flip (surface, ®ion, DSFLIP_WAITFORSYNC); | |
713 } | |
714 | |
715 int DirectFB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) | |
716 { | |
717 fprintf(stderr, "SDL: Unimplemented DirectFB_SetColors!\n"); | |
718 return 0; | |
719 } | |
720 | |
721 void DirectFB_VideoQuit(_THIS) | |
722 { | |
723 int i, j; | |
724 | |
725 HIDDEN->inputbuffer->Release (HIDDEN->inputbuffer); | |
726 HIDDEN->layer->Release (HIDDEN->layer); | |
727 HIDDEN->dfb->Release (HIDDEN->dfb); | |
728 | |
729 /* Free video mode lists */ | |
730 for ( i=0; i<NUM_MODELISTS; ++i ) | |
731 { | |
732 if ( HIDDEN->SDL_modelist[i] != NULL ) | |
733 { | |
734 for ( j=0; HIDDEN->SDL_modelist[i][j]; ++j ) | |
735 free(HIDDEN->SDL_modelist[i][j]); | |
736 free(HIDDEN->SDL_modelist[i]); | |
737 HIDDEN->SDL_modelist[i] = NULL; | |
738 } | |
739 } | |
740 | |
741 HIDDEN->initialized = 0; | |
742 } | |
743 | |
744 void DirectFB_FinalQuit(void) | |
745 { | |
746 } |