Mercurial > sdl-ios-xcode
changeset 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 | 39877400bd1e |
children | e92aa316c517 |
files | configure.in docs.html src/video/Makefile.am src/video/SDL_sysvideo.h src/video/SDL_video.c src/video/directfb/.cvsignore src/video/directfb/Makefile.am src/video/directfb/SDL_DirectFB_events.c src/video/directfb/SDL_DirectFB_events.h src/video/directfb/SDL_DirectFB_keys.h src/video/directfb/SDL_DirectFB_video.c src/video/directfb/SDL_DirectFB_video.h |
diffstat | 12 files changed, 1262 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.in Tue Sep 04 22:48:09 2001 +0000 +++ b/configure.in Tue Sep 04 22:53:46 2001 +0000 @@ -695,6 +695,46 @@ fi } +dnl Find DirectFB +CheckDirectFB() +{ + AC_ARG_ENABLE(video-directfb, +[ --enable-video-directfb use DirectFB video driver [default=yes]], + , enable_video_directfb=yes) + if test x$enable_video = xyes -a x$enable_video_directfb = xyes; then + video_directfb=no + + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + if test x$PKG_CONFIG = xno ; then + AC_MSG_WARN([*** pkg-config is required to build the DirectFB video driver.]) + else + AC_MSG_CHECKING(for DirectFB support) + + if ! pkg-config --atleast-pkgconfig-version 0.5 ; then + AC_MSG_ERROR([*** pkg-config too old; version 0.5 or better required.]) + fi + + DIRECTFB_REQUIRED_VERSION=0.9.5 + + if $PKG_CONFIG --atleast-version $DIRECTFB_REQUIRED_VERSION directfb ; then + DIRECTFB_CFLAGS=`$PKG_CONFIG --cflags directfb` + DIRECTFB_LIBS=`$PKG_CONFIG --libs directfb` + video_directfb=yes + fi + fi + + AC_MSG_RESULT($video_directfb) + if test x$video_directfb = xyes; then + CFLAGS="$CFLAGS -DENABLE_DIRECTFB" + VIDEO_SUBDIRS="$VIDEO_SUBDIRS directfb" + VIDEO_DRIVERS="$VIDEO_DRIVERS directfb/libvideo_directfb.la" + + AC_SUBST(DIRECTFB_CFLAGS) + AC_SUBST(DIRECTFB_LIBS) + fi + fi +} + dnl See if we're running on PlayStation 2 hardware CheckPS2GS() { @@ -1219,6 +1259,7 @@ CheckNANOX CheckDGA CheckFBCON + CheckDirectFB CheckPS2GS CheckGGI CheckSVGA @@ -2174,6 +2215,7 @@ src/video/dga/Makefile src/video/nanox/Makefile src/video/fbcon/Makefile +src/video/directfb/Makefile src/video/ps2gs/Makefile src/video/ggi/Makefile src/video/maccommon/Makefile
--- a/docs.html Tue Sep 04 22:48:09 2001 +0000 +++ b/docs.html Tue Sep 04 22:53:46 2001 +0000 @@ -16,6 +16,7 @@ Major changes since SDL 1.0.0: </H2> <UL> + <LI> 1.2.3: Added support for DirectFB video on Linux (thanks Denis!) <LI> 1.2.3: Fixed IDE and SCSI CD-ROM detection on BeOS (thanks Caz!) <LI> 1.2.3: Fixed the system dependent SDL_WINDOWID hack on Windows <LI> 1.2.3: Added 640x480 as a scaled resolution for NTSC/PAL output
--- a/src/video/Makefile.am Tue Sep 04 22:48:09 2001 +0000 +++ b/src/video/Makefile.am Tue Sep 04 22:53:46 2001 +0000 @@ -5,7 +5,7 @@ # Define which subdirectories need to be built SUBDIRS = @VIDEO_SUBDIRS@ -DIST_SUBDIRS = dummy x11 dga nanox fbcon vgl svga ggi aalib \ +DIST_SUBDIRS = dummy x11 dga nanox fbcon directfb vgl svga ggi aalib \ wincommon windib windx5 \ maccommon macdsp macrom quartz \ bwindow ps2gs photon cybergfx
--- a/src/video/SDL_sysvideo.h Tue Sep 04 22:48:09 2001 +0000 +++ b/src/video/SDL_sysvideo.h Tue Sep 04 22:53:46 2001 +0000 @@ -337,6 +337,9 @@ #ifdef ENABLE_FBCON extern VideoBootStrap FBCON_bootstrap; #endif +#ifdef ENABLE_DIRECTFB +extern VideoBootStrap DirectFB_bootstrap; +#endif #ifdef ENABLE_PS2GS extern VideoBootStrap PS2GS_bootstrap; #endif
--- a/src/video/SDL_video.c Tue Sep 04 22:48:09 2001 +0000 +++ b/src/video/SDL_video.c Tue Sep 04 22:53:46 2001 +0000 @@ -57,6 +57,9 @@ #ifdef ENABLE_FBCON &FBCON_bootstrap, #endif +#ifdef ENABLE_DIRECTFB + &DirectFB_bootstrap, +#endif #ifdef ENABLE_PS2GS &PS2GS_bootstrap, #endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/directfb/.cvsignore Tue Sep 04 22:53:46 2001 +0000 @@ -0,0 +1,6 @@ +Makefile.in +Makefile +.libs +*.o +*.lo +*.la
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/directfb/Makefile.am Tue Sep 04 22:53:46 2001 +0000 @@ -0,0 +1,15 @@ + +## Makefile.am for SDL using the DirectFB video driver + +CFLAGS = @CFLAGS@ $(DIRECTFB_CFLAGS) + +noinst_LTLIBRARIES = libvideo_directfb.la +libvideo_directfb_la_SOURCES = $(DIRECTFB_SRCS) +libvideo_directfb_la_LIBADD = $(DIRECTFB_LIBS) + +# The SDL DirectFB video driver sources +DIRECTFB_SRCS = \ + SDL_DirectFB_events.c \ + SDL_DirectFB_events.h \ + SDL_DirectFB_video.c \ + SDL_DirectFB_video.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/directfb/SDL_DirectFB_events.c Tue Sep 04 22:53:46 2001 +0000 @@ -0,0 +1,222 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +/* Handle the event stream, converting DirectFB input events into SDL events */ + +#include <sys/types.h> +#include <sys/time.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <termios.h> + +#include <directfb.h> + +#include "SDL.h" +#include "SDL_sysevents.h" +#include "SDL_sysvideo.h" +#include "SDL_events_c.h" +#include "SDL_DirectFB_video.h" +#include "SDL_DirectFB_events.h" + +/* The translation tables from a DirectFB keycode to a SDL keysym */ +static SDLKey keymap[256]; +static SDL_keysym *DirectFB_TranslateKey (DFBInputEvent *ev, SDL_keysym *keysym); +static int DirectFB_TranslateButton (DFBInputEvent *ev); + +static int posted = 0; + + +void DirectFB_PumpEvents (_THIS) +{ + DFBInputEvent evt; + + while (HIDDEN->inputbuffer->GetEvent (HIDDEN->inputbuffer, &evt) == DFB_OK) + { + SDL_keysym keysym; + + switch (evt.type) + { + case DIET_BUTTONPRESS: + posted += SDL_PrivateMouseButton(SDL_PRESSED, + DirectFB_TranslateButton (&evt), 0, 0); + break; + case DIET_BUTTONRELEASE: + posted += SDL_PrivateMouseButton(SDL_RELEASED, + DirectFB_TranslateButton (&evt), 0, 0); + break; + case DIET_KEYPRESS: + posted += SDL_PrivateKeyboard(SDL_PRESSED, DirectFB_TranslateKey(&evt, &keysym)); + break; + case DIET_KEYRELEASE: + posted += SDL_PrivateKeyboard(SDL_RELEASED, DirectFB_TranslateKey(&evt, &keysym)); + break; + case DIET_AXISMOTION: + if (evt.flags & DIEF_AXISREL) + { + if (evt.axis == DIAI_X) + posted += SDL_PrivateMouseMotion(0, 1, evt.axisrel, 0); + else if (evt.axis == DIAI_Y) + posted += SDL_PrivateMouseMotion(0, 1, 0, evt.axisrel); + } + break; + default: + ; + } + } +} + +void DirectFB_InitOSKeymap (_THIS) +{ + int i; + + /* Initialize the DirectFB key translation table */ + for (i=0; i<SDL_TABLESIZE(keymap); ++i) + keymap[i] = SDLK_UNKNOWN; + + keymap[DIKC_A] = SDLK_a; + keymap[DIKC_B] = SDLK_b; + keymap[DIKC_C] = SDLK_c; + keymap[DIKC_D] = SDLK_d; + keymap[DIKC_E] = SDLK_e; + keymap[DIKC_F] = SDLK_f; + keymap[DIKC_G] = SDLK_g; + keymap[DIKC_H] = SDLK_h; + keymap[DIKC_I] = SDLK_i; + keymap[DIKC_J] = SDLK_j; + keymap[DIKC_K] = SDLK_k; + keymap[DIKC_L] = SDLK_l; + keymap[DIKC_M] = SDLK_m; + keymap[DIKC_N] = SDLK_n; + keymap[DIKC_O] = SDLK_o; + keymap[DIKC_P] = SDLK_p; + keymap[DIKC_Q] = SDLK_q; + keymap[DIKC_R] = SDLK_r; + keymap[DIKC_S] = SDLK_s; + keymap[DIKC_T] = SDLK_t; + keymap[DIKC_U] = SDLK_u; + keymap[DIKC_V] = SDLK_v; + keymap[DIKC_W] = SDLK_w; + keymap[DIKC_X] = SDLK_x; + keymap[DIKC_Y] = SDLK_y; + keymap[DIKC_Z] = SDLK_z; + + keymap[DIKC_0] = SDLK_0; + keymap[DIKC_1] = SDLK_1; + keymap[DIKC_2] = SDLK_2; + keymap[DIKC_3] = SDLK_3; + keymap[DIKC_4] = SDLK_4; + keymap[DIKC_5] = SDLK_5; + keymap[DIKC_6] = SDLK_6; + keymap[DIKC_7] = SDLK_7; + keymap[DIKC_8] = SDLK_8; + keymap[DIKC_9] = SDLK_9; + + keymap[DIKC_F1] = SDLK_F1; + keymap[DIKC_F2] = SDLK_F2; + keymap[DIKC_F3] = SDLK_F3; + keymap[DIKC_F4] = SDLK_F4; + keymap[DIKC_F5] = SDLK_F5; + keymap[DIKC_F6] = SDLK_F6; + keymap[DIKC_F7] = SDLK_F7; + keymap[DIKC_F8] = SDLK_F8; + keymap[DIKC_F9] = SDLK_F9; + keymap[DIKC_F10] = SDLK_F10; + keymap[DIKC_F11] = SDLK_F11; + keymap[DIKC_F12] = SDLK_F12; + + keymap[DIKC_ESCAPE] = SDLK_ESCAPE; + keymap[DIKC_LEFT] = SDLK_LEFT; + keymap[DIKC_RIGHT] = SDLK_RIGHT; + keymap[DIKC_UP] = SDLK_UP; + keymap[DIKC_DOWN] = SDLK_DOWN; + keymap[DIKC_CTRL] = SDLK_LCTRL; + keymap[DIKC_SHIFT] = SDLK_LSHIFT; + keymap[DIKC_ALT] = SDLK_LALT; + keymap[DIKC_ALTGR] = SDLK_RALT; + keymap[DIKC_TAB] = SDLK_TAB; + keymap[DIKC_ENTER] = SDLK_RETURN; + keymap[DIKC_SPACE] = SDLK_SPACE; + keymap[DIKC_BACKSPACE] = SDLK_BACKSPACE; + keymap[DIKC_INSERT] = SDLK_INSERT; + keymap[DIKC_DELETE] = SDLK_DELETE; + keymap[DIKC_HOME] = SDLK_HOME; + keymap[DIKC_END] = SDLK_END; + keymap[DIKC_PAGEUP] = SDLK_PAGEUP; + keymap[DIKC_PAGEDOWN] = SDLK_PAGEDOWN; + keymap[DIKC_CAPSLOCK] = SDLK_CAPSLOCK; + keymap[DIKC_NUMLOCK] = SDLK_NUMLOCK; + keymap[DIKC_SCRLOCK] = SDLK_SCROLLOCK; + keymap[DIKC_PRINT] = SDLK_PRINT; + keymap[DIKC_PAUSE] = SDLK_PAUSE; + keymap[DIKC_KP_DIV] = SDLK_KP_DIVIDE; + keymap[DIKC_KP_MULT] = SDLK_KP_MULTIPLY; + keymap[DIKC_KP_MINUS] = SDLK_KP_MINUS; + keymap[DIKC_KP_PLUS] = SDLK_KP_PLUS; + keymap[DIKC_KP_ENTER] = SDLK_KP_ENTER; + + keymap[DIKC_OK] = SDLK_RETURN; + keymap[DIKC_CANCEL] = SDLK_BREAK; + keymap[DIKC_CLEAR] = SDLK_DELETE; + keymap[DIKC_POWER] = SDLK_POWER; + keymap[DIKC_POWER2] = SDLK_POWER; + keymap[DIKC_MENU] = SDLK_MENU; + keymap[DIKC_HELP] = SDLK_HELP; + keymap[DIKC_BACK] = SDLK_ESCAPE; +} + + +static SDL_keysym *DirectFB_TranslateKey (DFBInputEvent *ev, SDL_keysym *keysym) +{ + /* Set the keysym information */ + keysym->scancode = ev->keycode; + keysym->mod = KMOD_NONE; + keysym->unicode = 0; + + if (ev->key_ascii > 0 && ev->key_ascii < 128) + keysym->sym = ev->key_ascii; + else + keysym->sym = keymap[ev->keycode]; + + return keysym; +} + +static int DirectFB_TranslateButton (DFBInputEvent *ev) +{ + switch (ev->button) + { + case DIBI_LEFT: + return 1; + case DIBI_MIDDLE: + return 2; + case DIBI_RIGHT: + return 3; + default: + return 0; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/directfb/SDL_DirectFB_events.h Tue Sep 04 22:53:46 2001 +0000 @@ -0,0 +1,33 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +#include "SDL_DirectFB_video.h" + +/* Functions to be exported */ +extern void DirectFB_InitOSKeymap(_THIS); +extern void DirectFB_PumpEvents(_THIS); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/directfb/SDL_DirectFB_keys.h Tue Sep 04 22:53:46 2001 +0000 @@ -0,0 +1,135 @@ + +#define SCANCODE_ESCAPE 1 + +#define SCANCODE_1 2 +#define SCANCODE_2 3 +#define SCANCODE_3 4 +#define SCANCODE_4 5 +#define SCANCODE_5 6 +#define SCANCODE_6 7 +#define SCANCODE_7 8 +#define SCANCODE_8 9 +#define SCANCODE_9 10 +#define SCANCODE_0 11 + +#define SCANCODE_MINUS 12 +#define SCANCODE_EQUAL 13 + +#define SCANCODE_BACKSPACE 14 +#define SCANCODE_TAB 15 + +#define SCANCODE_Q 16 +#define SCANCODE_W 17 +#define SCANCODE_E 18 +#define SCANCODE_R 19 +#define SCANCODE_T 20 +#define SCANCODE_Y 21 +#define SCANCODE_U 22 +#define SCANCODE_I 23 +#define SCANCODE_O 24 +#define SCANCODE_P 25 +#define SCANCODE_BRACKET_LEFT 26 +#define SCANCODE_BRACKET_RIGHT 27 + +#define SCANCODE_ENTER 28 + +#define SCANCODE_LEFTCONTROL 29 + +#define SCANCODE_A 30 +#define SCANCODE_S 31 +#define SCANCODE_D 32 +#define SCANCODE_F 33 +#define SCANCODE_G 34 +#define SCANCODE_H 35 +#define SCANCODE_J 36 +#define SCANCODE_K 37 +#define SCANCODE_L 38 +#define SCANCODE_SEMICOLON 39 +#define SCANCODE_APOSTROPHE 40 +#define SCANCODE_GRAVE 41 + +#define SCANCODE_LEFTSHIFT 42 +#define SCANCODE_BACKSLASH 43 + +#define SCANCODE_Z 44 +#define SCANCODE_X 45 +#define SCANCODE_C 46 +#define SCANCODE_V 47 +#define SCANCODE_B 48 +#define SCANCODE_N 49 +#define SCANCODE_M 50 +#define SCANCODE_COMMA 51 +#define SCANCODE_PERIOD 52 +#define SCANCODE_SLASH 53 + +#define SCANCODE_RIGHTSHIFT 54 +#define SCANCODE_KEYPADMULTIPLY 55 + +#define SCANCODE_LEFTALT 56 +#define SCANCODE_SPACE 57 +#define SCANCODE_CAPSLOCK 58 + +#define SCANCODE_F1 59 +#define SCANCODE_F2 60 +#define SCANCODE_F3 61 +#define SCANCODE_F4 62 +#define SCANCODE_F5 63 +#define SCANCODE_F6 64 +#define SCANCODE_F7 65 +#define SCANCODE_F8 66 +#define SCANCODE_F9 67 +#define SCANCODE_F10 68 + +#define SCANCODE_NUMLOCK 69 +#define SCANCODE_SCROLLLOCK 70 + +#define SCANCODE_KEYPAD7 71 +#define SCANCODE_CURSORUPLEFT 71 +#define SCANCODE_KEYPAD8 72 +#define SCANCODE_CURSORUP 72 +#define SCANCODE_KEYPAD9 73 +#define SCANCODE_CURSORUPRIGHT 73 +#define SCANCODE_KEYPADMINUS 74 +#define SCANCODE_KEYPAD4 75 +#define SCANCODE_CURSORLEFT 75 +#define SCANCODE_KEYPAD5 76 +#define SCANCODE_KEYPAD6 77 +#define SCANCODE_CURSORRIGHT 77 +#define SCANCODE_KEYPADPLUS 78 +#define SCANCODE_KEYPAD1 79 +#define SCANCODE_CURSORDOWNLEFT 79 +#define SCANCODE_KEYPAD2 80 +#define SCANCODE_CURSORDOWN 80 +#define SCANCODE_KEYPAD3 81 +#define SCANCODE_CURSORDOWNRIGHT 81 +#define SCANCODE_KEYPAD0 82 +#define SCANCODE_KEYPADPERIOD 83 + +#define SCANCODE_LESS 86 + +#define SCANCODE_F11 87 +#define SCANCODE_F12 88 + +#define SCANCODE_KEYPADENTER 96 +#define SCANCODE_RIGHTCONTROL 97 +#define SCANCODE_CONTROL 97 +#define SCANCODE_KEYPADDIVIDE 98 +#define SCANCODE_PRINTSCREEN 99 +#define SCANCODE_RIGHTALT 100 +#define SCANCODE_BREAK 101 /* Beware: is 119 */ +#define SCANCODE_BREAK_ALTERNATIVE 119 /* on some keyboards! */ + +#define SCANCODE_HOME 102 +#define SCANCODE_CURSORBLOCKUP 90 /* Cursor key block */ +#define SCANCODE_PAGEUP 104 +#define SCANCODE_CURSORBLOCKLEFT 92 /* Cursor key block */ +#define SCANCODE_CURSORBLOCKRIGHT 94 /* Cursor key block */ +#define SCANCODE_END 107 +#define SCANCODE_CURSORBLOCKDOWN 108 /* Cursor key block */ +#define SCANCODE_PAGEDOWN 109 +#define SCANCODE_INSERT 110 +#define SCANCODE_REMOVE 111 + +#define SCANCODE_RIGHTWIN 126 +#define SCANCODE_LEFTWIN 125 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/directfb/SDL_DirectFB_video.c Tue Sep 04 22:53:46 2001 +0000 @@ -0,0 +1,746 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +/* DirectFB video driver implementation. +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/mman.h> + +#include <directfb.h> + +#include "SDL.h" +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_mouse.h" +#include "SDL_sysvideo.h" +#include "SDL_pixels_c.h" +#include "SDL_events_c.h" +#include "SDL_DirectFB_video.h" +#include "SDL_DirectFB_events.h" + + +/* Initialization/Query functions */ +static int DirectFB_VideoInit(_THIS, SDL_PixelFormat *vformat); +static SDL_Rect **DirectFB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); +static SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); +static int DirectFB_SetColors(_THIS, int firstcolor, int ncolors, + SDL_Color *colors); +static void DirectFB_VideoQuit(_THIS); + +/* Hardware surface functions */ +static int DirectFB_AllocHWSurface(_THIS, SDL_Surface *surface); +static int DirectFB_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color); +static int DirectFB_LockHWSurface(_THIS, SDL_Surface *surface); +static void DirectFB_UnlockHWSurface(_THIS, SDL_Surface *surface); +static void DirectFB_FreeHWSurface(_THIS, SDL_Surface *surface); +static int DirectFB_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst); +static int DirectFB_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect); +static int DirectFB_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key); +static int DirectFB_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha); +static int DirectFB_FlipHWSurface(_THIS, SDL_Surface *surface); + +/* Various screen update functions available */ +static void DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects); +static void DirectFB_WindowedUpdate(_THIS, int numrects, SDL_Rect *rects); + +/* This is the rect EnumModes2 uses */ +struct DirectFBEnumRect { + SDL_Rect r; + struct DirectFBEnumRect* next; +}; + +static struct DirectFBEnumRect *enumlists[NUM_MODELISTS]; + + +/* DirectFB driver bootstrap functions */ + +static int DirectFB_Available(void) +{ + return 1; +} + +static void DirectFB_DeleteDevice(SDL_VideoDevice *device) +{ + free(device->hidden); + free(device); +} + +static SDL_VideoDevice *DirectFB_CreateDevice(int devindex) +{ + SDL_VideoDevice *device; + + /* Initialize all variables that we clean on shutdown */ + device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice)); + if (device) + { + memset (device, 0, (sizeof *device)); + device->hidden = (struct SDL_PrivateVideoData *) malloc (sizeof (*device->hidden)); + } + if (device == NULL || device->hidden == NULL) + { + SDL_OutOfMemory(); + if (device) + { + free (device); + } + return(0); + } + memset (device->hidden, 0, sizeof (*device->hidden)); + + /* Set the function pointers */ + device->VideoInit = DirectFB_VideoInit; + device->ListModes = DirectFB_ListModes; + device->SetVideoMode = DirectFB_SetVideoMode; + device->SetColors = DirectFB_SetColors; + device->UpdateRects = NULL; + device->VideoQuit = DirectFB_VideoQuit; + device->AllocHWSurface = DirectFB_AllocHWSurface; + device->CheckHWBlit = DirectFB_CheckHWBlit; + device->FillHWRect = DirectFB_FillHWRect; + device->SetHWColorKey = DirectFB_SetHWColorKey; + device->SetHWAlpha = DirectFB_SetHWAlpha; + device->LockHWSurface = DirectFB_LockHWSurface; + device->UnlockHWSurface = DirectFB_UnlockHWSurface; + device->FlipHWSurface = DirectFB_FlipHWSurface; + device->FreeHWSurface = DirectFB_FreeHWSurface; + device->SetCaption = NULL; + device->SetIcon = NULL; + device->IconifyWindow = NULL; + device->GrabInput = NULL; + device->GetWMInfo = NULL; + device->InitOSKeymap = DirectFB_InitOSKeymap; + device->PumpEvents = DirectFB_PumpEvents; + + device->free = DirectFB_DeleteDevice; + + return device; +} + +VideoBootStrap DirectFB_bootstrap = { + "directfb", "DirectFB", + DirectFB_Available, DirectFB_CreateDevice +}; + +static DFBEnumerationResult EnumModesCallback (unsigned int width, + unsigned int height, + unsigned int bpp, + void *data) +{ + SDL_VideoDevice *this = (SDL_VideoDevice *)data; + struct DirectFBEnumRect *enumrect; + + switch (bpp) + { + case 8: + case 15: + case 16: + case 24: + case 32: + bpp /= 8; --bpp; + ++HIDDEN->SDL_nummodes[bpp]; + enumrect = (struct DirectFBEnumRect*)malloc(sizeof(struct DirectFBEnumRect)); + if ( !enumrect ) + { + SDL_OutOfMemory(); + return DFENUM_CANCEL; + } + enumrect->r.x = 0; + enumrect->r.y = 0; + enumrect->r.w = width; + enumrect->r.h = height; + enumrect->next = enumlists[bpp]; + enumlists[bpp] = enumrect; + break; + } + + return DFENUM_OK; +} + +struct private_hwdata { + IDirectFBSurface *surface; +}; + +void SetDirectFBerror (const char *function, DFBResult code) +{ + const char *error = DirectFBErrorString (code); + + if (error) + SDL_SetError("%s: %s", function, error); + else + SDL_SetError("Unknown error code from %s", function); +} + +static DFBSurfacePixelFormat SDLToDFBPixelFormat (SDL_PixelFormat *format) +{ + if (format->Rmask && format->Gmask && format->Bmask) + { + switch (format->BitsPerPixel) + { + case 16: + if (format->Rmask == 0xF800 && + format->Gmask == 0x07E0 && + format->Bmask == 0x001F) + return DSPF_RGB16; + /* fall through */ + + case 15: + if (format->Rmask == 0x7C00 && + format->Gmask == 0x03E0 && + format->Bmask == 0x001F) + return DSPF_RGB15; + break; + + case 24: + if (format->Rmask == 0xFF0000 && + format->Gmask == 0x00FF00 && + format->Bmask == 0x0000FF) + return DSPF_RGB24; + break; + + case 32: + if (format->Rmask == 0xFF0000 && + format->Gmask == 0x00FF00 && + format->Bmask == 0x0000FF) + { + if (format->Amask == 0xFF000000) + return DSPF_ARGB; + else + return DSPF_RGB32; + } + break; + } + } + else + { + switch (format->BitsPerPixel) + { + case 15: + return DSPF_RGB15; + case 16: + return DSPF_RGB16; + case 24: + return DSPF_RGB24; + case 32: + return DSPF_RGB32; + } + } + + return DSPF_UNKNOWN; +} + +static int DFBToSDLPixelFormat (DFBSurfacePixelFormat pixelformat, SDL_PixelFormat *format) +{ + format->BitsPerPixel = 0; + format->Amask = format->Rmask = format->Gmask = format->Bmask = 0; + + switch (pixelformat) + { + case DSPF_A8: + format->Amask = 0x000000FF; + break; + case DSPF_RGB15: + format->Rmask = 0x00007C00; + format->Gmask = 0x000003E0; + format->Bmask = 0x0000001F; + break; + case DSPF_RGB16: + format->Rmask = 0x0000F800; + format->Gmask = 0x000007E0; + format->Bmask = 0x0000001F; + break; + case DSPF_ARGB: + format->Amask = 0xFF000000; + /* fall through */ + case DSPF_RGB24: + case DSPF_RGB32: + format->Rmask = 0x00FF0000; + format->Gmask = 0x0000FF00; + format->Bmask = 0x000000FF; + break; + default: + return -1; + } + + format->BitsPerPixel = BITS_PER_PIXEL(pixelformat); + + return 0; +} + + +int DirectFB_VideoInit(_THIS, SDL_PixelFormat *vformat) +{ + int i, j; + DFBResult ret; + IDirectFB *dfb; + DFBCardCapabilities caps; + IDirectFBDisplayLayer *layer; + DFBDisplayLayerConfig dlc; + IDirectFBInputBuffer *inputbuffer; + + + ret = DirectFBInit (NULL, NULL); + if (ret) + { + SetDirectFBerror ("DirectFBInit", ret); + return -1; + } + + ret = DirectFBCreate (&dfb); + if (ret) + { + SetDirectFBerror ("DirectFBCreate", ret); + return -1; + } + + ret = dfb->GetDisplayLayer (dfb, DLID_PRIMARY, &layer); + if (ret) + { + SetDirectFBerror ("dfb->GetDisplayLayer", ret); + dfb->Release (dfb); + return -1; + } + + ret = dfb->CreateInputBuffer (dfb, DICAPS_BUTTONS | DICAPS_AXIS | DICAPS_KEYS, + &inputbuffer); + if (ret) + { + SetDirectFBerror ("dfb->CreateInputBuffer", ret); + layer->Release (layer); + dfb->Release (dfb); + return -1; + } + + layer->EnableCursor (layer, 1); + + /* Query layer configuration to determine the current mode and pixelformat */ + layer->GetConfiguration (layer, &dlc); + + if (DFBToSDLPixelFormat (dlc.pixelformat, vformat)) + { + SDL_SetError ("Unsupported pixelformat"); + layer->Release (layer); + dfb->Release (dfb); + return -1; + } + + /* Enumerate the available fullscreen modes */ + for ( i=0; i<NUM_MODELISTS; ++i ) + enumlists[i] = NULL; + + ret = dfb->EnumVideoModes (dfb, EnumModesCallback, this); + if (ret) + { + SetDirectFBerror ("dfb->EnumVideoModes", ret); + layer->Release (layer); + dfb->Release (dfb); + return(-1); + } + for ( i=0; i<NUM_MODELISTS; ++i ) + { + struct DirectFBEnumRect *rect; + HIDDEN->SDL_modelist[i] = (SDL_Rect **) malloc + ((HIDDEN->SDL_nummodes[i]+1)*sizeof(SDL_Rect *)); + if ( HIDDEN->SDL_modelist[i] == NULL ) + { + SDL_OutOfMemory(); + return(-1); + } + for ( j = 0, rect = enumlists[i]; rect; ++j, rect = rect->next ) + { + HIDDEN->SDL_modelist[i][j]=(SDL_Rect *)rect; + } + HIDDEN->SDL_modelist[i][j] = NULL; + } + + /* Query card capabilities to get the video memory size */ + dfb->GetCardCapabilities (dfb, &caps); + + this->info.wm_available = 1; + this->info.hw_available = 1; + this->info.blit_hw = 1; + this->info.blit_hw_CC = 1; + this->info.blit_hw_A = 1; + this->info.blit_fill = 1; + this->info.video_mem = caps.video_memory / 1024; + + HIDDEN->initialized = 1; + HIDDEN->dfb = dfb; + HIDDEN->layer = layer; + HIDDEN->inputbuffer = inputbuffer; + + return 0; +} + +static SDL_Rect **DirectFB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) +{ + if (flags & SDL_FULLSCREEN) + return HIDDEN->SDL_modelist[((format->BitsPerPixel + 7) / 8) - 1]; + else + if (SDLToDFBPixelFormat (format) != DSPF_UNKNOWN) + return (SDL_Rect**) -1; + + return NULL; +} + +SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) +{ + DFBResult ret; + DFBSurfaceDescription dsc; + DFBSurfacePixelFormat pixelformat; + + fprintf (stderr, "SDL DirectFB_SetVideoMode: %dx%d@%d, flags: 0x%08x\n", + width, height, bpp, flags); + + flags |= SDL_FULLSCREEN; + + /* Release previous primary surface */ + if (current->hwdata && current->hwdata->surface) + { + current->hwdata->surface->Release (current->hwdata->surface); + current->hwdata->surface = NULL; + } + else if (!current->hwdata) + { + /* Allocate the hardware acceleration data */ + current->hwdata = (struct private_hwdata *) malloc (sizeof(*current->hwdata)); + if (!current->hwdata) + { + SDL_OutOfMemory(); + return NULL; + } + memset (current->hwdata, 0, sizeof(*current->hwdata)); + } + + /* Set cooperative level depending on flag SDL_FULLSCREEN */ + if (flags & SDL_FULLSCREEN) + { + ret = HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_FULLSCREEN); + if (ret) + { + DirectFBError ("dfb->SetCooperativeLevel", ret); + flags &= ~SDL_FULLSCREEN; + } + } + else + HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_NORMAL); + + /* Set video mode */ + ret = HIDDEN->dfb->SetVideoMode (HIDDEN->dfb, width, height, bpp); + if (ret) + { + if (flags & SDL_FULLSCREEN) + { + flags &= ~SDL_FULLSCREEN; + HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_NORMAL); + ret = HIDDEN->dfb->SetVideoMode (HIDDEN->dfb, width, height, bpp); + } + + if (ret) + { + SetDirectFBerror ("dfb->SetVideoMode", ret); + return NULL; + } + } + + /* Create primary surface */ + dsc.flags = DSDESC_CAPS; + dsc.caps = DSCAPS_PRIMARY | ((flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0); + + ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, ¤t->hwdata->surface); + if (ret && (flags & SDL_DOUBLEBUF)) + { + /* Try without double buffering */ + dsc.caps &= ~DSCAPS_FLIPPING; + ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, ¤t->hwdata->surface); + } + if (ret) + { + SetDirectFBerror ("dfb->CreateSurface", ret); + current->hwdata->surface = NULL; + return NULL; + } + + current->w = width; + current->h = height; + current->flags = SDL_HWSURFACE | SDL_PREALLOC; + + if (flags & SDL_FULLSCREEN) + { + current->flags |= SDL_FULLSCREEN; + this->UpdateRects = DirectFB_DirectUpdate; + } + else + this->UpdateRects = DirectFB_WindowedUpdate; + + if (dsc.caps & DSCAPS_FLIPPING) + current->flags |= SDL_DOUBLEBUF; + + current->hwdata->surface->GetPixelFormat (current->hwdata->surface, &pixelformat); + DFBToSDLPixelFormat (pixelformat, current->format); + + return current; +} + +static int DirectFB_AllocHWSurface(_THIS, SDL_Surface *surface) +{ + DFBResult ret; + DFBSurfaceDescription dsc; + + /* fprintf(stderr, "SDL: DirectFB_AllocHWSurface (%dx%d@%d, flags: 0x%08x)\n", + surface->w, surface->h, surface->format->BitsPerPixel, surface->flags);*/ + + if (surface->w < 8 || surface->h < 8) + return -1; + + /* fill surface description */ + dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS; + dsc.width = surface->w; + dsc.height = surface->h; + dsc.caps = surface->flags & SDL_DOUBLEBUF ? DSCAPS_FLIPPING : 0; + + /* find the right pixelformat */ + dsc.pixelformat = SDLToDFBPixelFormat (surface->format); + if (dsc.pixelformat == DSPF_UNKNOWN) + return -1; + + /* Allocate the hardware acceleration data */ + surface->hwdata = (struct private_hwdata *) malloc (sizeof(*surface->hwdata)); + if (surface->hwdata == NULL) + { + SDL_OutOfMemory(); + return -1; + } + + /* Create the surface */ + ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &surface->hwdata->surface); + if (ret) + { + SetDirectFBerror ("dfb->CreateSurface", ret); + free (surface->hwdata); + surface->hwdata = NULL; + return -1; + } + + surface->flags |= SDL_HWSURFACE | SDL_PREALLOC; + + return 0; +} + +static void DirectFB_FreeHWSurface(_THIS, SDL_Surface *surface) +{ + if (surface->hwdata && HIDDEN->initialized) + { + surface->hwdata->surface->Release (surface->hwdata->surface); + free (surface->hwdata); + surface->hwdata = NULL; + } +} + +static int DirectFB_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst) +{ + /* fprintf(stderr, "SDL: DirectFB_CheckHWBlit (src->hwdata: %p, dst->hwdata: %p)\n", + src->hwdata, dst->hwdata);*/ + + if (!src->hwdata || !dst->hwdata) + return 0; + + src->flags |= SDL_HWACCEL; + src->map->hw_blit = DirectFB_HWAccelBlit; + + return 1; +} + +static int DirectFB_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) +{ + DFBRectangle sr, dr; + IDirectFBSurface *surface; + DFBSurfaceBlittingFlags flags = DSBLIT_NOFX; + + sr.x = srcrect->x; + sr.y = srcrect->y; + sr.w = srcrect->w; + sr.h = srcrect->h; + + dr.x = dstrect->x; + dr.y = dstrect->y; + dr.w = dstrect->w; + dr.h = dstrect->h; + + surface = dst->hwdata->surface; + + if (src->flags & SDL_SRCCOLORKEY) + { + flags |= DSBLIT_SRC_COLORKEY; + surface->SetSrcColorKey (surface, src->format->colorkey); + } + + if (src->flags & SDL_SRCALPHA) + { + flags |= DSBLIT_BLEND_COLORALPHA; + surface->SetColor (surface, 0xff, 0xff, 0xff, src->format->alpha); + } + + surface->SetBlittingFlags (surface, flags); + + if (sr.w == dr.w && sr.h == dr.h) + surface->Blit (surface, src->hwdata->surface, &sr, dr.x, dr.y); + else + surface->StretchBlit (surface, src->hwdata->surface, &sr, &dr); + + return 0; +} + +static int DirectFB_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color) +{ + SDL_PixelFormat *fmt = dst->format; + IDirectFBSurface *surface = dst->hwdata->surface; + + /* ugly */ + surface->SetColor (surface, + (color & fmt->Rmask) >> (fmt->Rshift - fmt->Rloss), + (color & fmt->Gmask) >> (fmt->Gshift - fmt->Gloss), + (color & fmt->Bmask) << (fmt->Bloss - fmt->Bshift), 0xFF); + surface->FillRectangle (surface, dstrect->x, dstrect->y, dstrect->w, dstrect->h); + + return 0; +} + +static int DirectFB_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key) +{ + return 0; +} + +static int DirectFB_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha) +{ + return 0; +} + +static int DirectFB_FlipHWSurface(_THIS, SDL_Surface *surface) +{ + return surface->hwdata->surface->Flip (surface->hwdata->surface, NULL, DSFLIP_WAITFORSYNC); +} + +static int DirectFB_LockHWSurface(_THIS, SDL_Surface *surface) +{ + DFBResult ret; + void *data; + int pitch; + + ret = surface->hwdata->surface->Lock (surface->hwdata->surface, + DSLF_WRITE, &data, &pitch); + if (ret) + { + SetDirectFBerror ("surface->Lock", ret); + return -1; + } + + surface->pixels = data; + surface->pitch = pitch; + + return 0; +} + +static void DirectFB_UnlockHWSurface(_THIS, SDL_Surface *surface) +{ + surface->hwdata->surface->Unlock (surface->hwdata->surface); + surface->pixels = NULL; +} + +static void DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects) +{ +} + +static void DirectFB_WindowedUpdate(_THIS, int numrects, SDL_Rect *rects) +{ + IDirectFBSurface *surface = this->screen->hwdata->surface; + DFBRegion region = { rects->x, rects->y, + rects->x + rects->w - 1, + rects->y + rects->h - 1 }; + + while (--numrects) + { + int x2, y2; + + rects++; + + if (rects->x < region.x1) + region.x1 = rects->x; + + if (rects->y < region.y1) + region.y1 = rects->y; + + x2 = rects->x + rects->w - 1; + y2 = rects->y + rects->h - 1; + + if (x2 > region.x2) + region.x2 = x2; + + if (y2 > region.y2) + region.y2 = y2; + } + + surface->Flip (surface, ®ion, DSFLIP_WAITFORSYNC); +} + +int DirectFB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) +{ + fprintf(stderr, "SDL: Unimplemented DirectFB_SetColors!\n"); + return 0; +} + +void DirectFB_VideoQuit(_THIS) +{ + int i, j; + + HIDDEN->inputbuffer->Release (HIDDEN->inputbuffer); + HIDDEN->layer->Release (HIDDEN->layer); + HIDDEN->dfb->Release (HIDDEN->dfb); + + /* Free video mode lists */ + for ( i=0; i<NUM_MODELISTS; ++i ) + { + if ( HIDDEN->SDL_modelist[i] != NULL ) + { + for ( j=0; HIDDEN->SDL_modelist[i][j]; ++j ) + free(HIDDEN->SDL_modelist[i][j]); + free(HIDDEN->SDL_modelist[i]); + HIDDEN->SDL_modelist[i] = NULL; + } + } + + HIDDEN->initialized = 0; +} + +void DirectFB_FinalQuit(void) +{ +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/directfb/SDL_DirectFB_video.h Tue Sep 04 22:53:46 2001 +0000 @@ -0,0 +1,55 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +#ifndef _SDL_DirectFB_video_h +#define _SDL_DirectFB_video_h + +#include <directfb.h> + +#include "SDL_mouse.h" +#include "SDL_sysvideo.h" + +#define _THIS SDL_VideoDevice *this + +/* Private display data */ + +struct SDL_PrivateVideoData +{ + int initialized; + + IDirectFB *dfb; + IDirectFBDisplayLayer *layer; + IDirectFBInputBuffer *inputbuffer; + +#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */ + int SDL_nummodes[NUM_MODELISTS]; + SDL_Rect **SDL_modelist[NUM_MODELISTS]; +}; + +#define HIDDEN (this->hidden) + +#endif /* _SDL_DirectFB_video_h */