src/video/directfb/SDL_DirectFB_opengl.c
author Couriersud
Sun, 11 Jan 2009 23:49:23 +0000
changeset 3023 d72a0dd80e8b
parent 3013 8cc00819c8d6
child 3697 f7b03b6838cb
permissions -rw-r--r--
DirectFB cleanups & simple window manager

- use SDL_getenv, not getenv ...
- no more support for 0.9.25 - not even mentioned any longer on directfb.org
- fix fullscreen issues
- add a simple window manager unless the directfb team comes up with a working wm.

The driver has support for a very, very basic window manager you may
want to use when runnning with "wm=default". Use

export SDL_DIRECTFB_WM=1

to enable basic window borders including icon support. In order to have the window title rendered,
you need to have the following font installed:

/usr/share/fonts/truetype/freefont/FreeSans.ttf
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2009 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 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     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with _this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 #include "SDL_DirectFB_video.h"
    25 
    26 #if SDL_DIRECTFB_OPENGL
    27 
    28 struct SDL_GLDriverData
    29 {
    30     int gl_active;              /* to stop switching drivers while we have a valid context */
    31     int initialized;
    32     DirectFB_GLContext *firstgl;        /* linked list */
    33 };
    34 
    35 #define OPENGL_REQUIRS_DLOPEN
    36 #if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
    37 #include <dlfcn.h>
    38 #define GL_LoadObject(X)	dlopen(X, (RTLD_NOW|RTLD_GLOBAL))
    39 #define GL_LoadFunction		dlsym
    40 #define GL_UnloadObject		dlclose
    41 #else
    42 #define GL_LoadObject	SDL_LoadObject
    43 #define GL_LoadFunction	SDL_LoadFunction
    44 #define GL_UnloadObject	SDL_UnloadObject
    45 #endif
    46 
    47 static void DirectFB_GL_UnloadLibrary(_THIS);
    48 
    49 int
    50 DirectFB_GL_Initialize(_THIS)
    51 {
    52     if (_this->gl_data) {
    53         return 0;
    54     }
    55 
    56     _this->gl_data =
    57         (struct SDL_GLDriverData *) SDL_calloc(1,
    58                                                sizeof(struct
    59                                                       SDL_GLDriverData));
    60     if (!_this->gl_data) {
    61         SDL_OutOfMemory();
    62         return -1;
    63     }
    64     _this->gl_data->initialized = 0;
    65 
    66     ++_this->gl_data->initialized;
    67     _this->gl_data->firstgl = NULL;
    68 
    69     if (DirectFB_GL_LoadLibrary(_this, NULL) < 0) {
    70         return -1;
    71     }
    72 
    73     /* Initialize extensions */
    74     /* FIXME needed?
    75      * X11_GL_InitExtensions(_this);
    76      */
    77 
    78     return 0;
    79 }
    80 
    81 void
    82 DirectFB_GL_Shutdown(_THIS)
    83 {
    84     if (!_this->gl_data || (--_this->gl_data->initialized > 0)) {
    85         return;
    86     }
    87 
    88     DirectFB_GL_UnloadLibrary(_this);
    89 
    90     SDL_free(_this->gl_data);
    91     _this->gl_data = NULL;
    92 }
    93 
    94 int
    95 DirectFB_GL_LoadLibrary(_THIS, const char *path)
    96 {
    97     SDL_DFB_DEVICEDATA(_this);
    98 
    99     void *handle = NULL;
   100 
   101     SDL_DFB_DEBUG("Loadlibrary : %s\n", path);
   102 
   103     if (_this->gl_data->gl_active) {
   104         SDL_SetError("OpenGL context already created");
   105         return -1;
   106     }
   107 
   108 
   109     if (path == NULL) {
   110         path = SDL_getenv("SDL_VIDEO_GL_DRIVER");
   111         if (path == NULL) {
   112             path = "libGL.so";
   113         }
   114     }
   115 
   116     handle = GL_LoadObject(path);
   117     if (handle == NULL) {
   118         SDL_DFB_ERR("Library not found: %s\n", path);
   119         /* SDL_LoadObject() will call SDL_SetError() for us. */
   120         return -1;
   121     }
   122 
   123     SDL_DFB_DEBUG("Loaded library: %s\n", path);
   124 
   125     /* Unload the old driver and reset the pointers */
   126     DirectFB_GL_UnloadLibrary(_this);
   127 
   128     _this->gl_config.dll_handle = handle;
   129     _this->gl_config.driver_loaded = 1;
   130     if (path) {
   131         SDL_strlcpy(_this->gl_config.driver_path, path,
   132                     SDL_arraysize(_this->gl_config.driver_path));
   133     } else {
   134         *_this->gl_config.driver_path = '\0';
   135     }
   136 
   137     devdata->glFinish = DirectFB_GL_GetProcAddress(_this, "glFinish");
   138     devdata->glFlush = DirectFB_GL_GetProcAddress(_this, "glFlush");
   139 
   140     return 0;
   141 }
   142 
   143 static void
   144 DirectFB_GL_UnloadLibrary(_THIS)
   145 {
   146     int ret;
   147 
   148     if (_this->gl_config.driver_loaded) {
   149 
   150         ret = GL_UnloadObject(_this->gl_config.dll_handle);
   151         if (ret)
   152             SDL_DFB_ERR("Error #%d trying to unload library.\n", ret);
   153         _this->gl_config.dll_handle = NULL;
   154         _this->gl_config.driver_loaded = 0;
   155     }
   156 }
   157 
   158 void *
   159 DirectFB_GL_GetProcAddress(_THIS, const char *proc)
   160 {
   161     void *handle;
   162 
   163     handle = _this->gl_config.dll_handle;
   164     return GL_LoadFunction(handle, proc);
   165 }
   166 
   167 SDL_GLContext
   168 DirectFB_GL_CreateContext(_THIS, SDL_Window * window)
   169 {
   170     SDL_DFB_WINDOWDATA(window);
   171     DirectFB_GLContext *context;
   172     int ret;
   173 
   174     SDL_DFB_CALLOC(context, 1, sizeof(*context));
   175 
   176     SDL_DFB_CHECKERR(windata->surface->GetGL(windata->surface,
   177                                              &context->context));
   178 
   179     if (!context->context)
   180         return NULL;
   181 
   182     SDL_DFB_CHECKERR(context->context->Unlock(context->context));
   183 
   184     context->next = _this->gl_data->firstgl;
   185     _this->gl_data->firstgl = context;
   186 
   187     if (DirectFB_GL_MakeCurrent(_this, window, context) < 0) {
   188         DirectFB_GL_DeleteContext(_this, context);
   189         return NULL;
   190     }
   191 
   192     return context;
   193 
   194   error:
   195     return NULL;
   196 }
   197 
   198 int
   199 DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
   200 {
   201     SDL_DFB_WINDOWDATA(window);
   202     DirectFB_GLContext *ctx = (DirectFB_GLContext *) context;
   203     DirectFB_GLContext *p;
   204 
   205     int ret;
   206 
   207     for (p = _this->gl_data->firstgl; p; p = p->next)
   208         p->context->Unlock(p->context);
   209 
   210     if (windata) {
   211         windata->gl_context = NULL;
   212         /* Everything is unlocked, check for a resize */
   213         DirectFB_AdjustWindowSurface(window);
   214     }
   215 
   216     if (ctx != NULL) {
   217         SDL_DFB_CHECKERR(ctx->context->Lock(ctx->context));
   218     }
   219 
   220     if (windata)
   221         windata->gl_context = ctx;
   222 
   223     return 0;
   224   error:
   225     return -1;
   226 }
   227 
   228 int
   229 DirectFB_GL_SetSwapInterval(_THIS, int interval)
   230 {
   231     SDL_Unsupported();
   232     return -1;
   233 }
   234 
   235 int
   236 DirectFB_GL_GetSwapInterval(_THIS)
   237 {
   238     SDL_Unsupported();
   239     return -1;
   240 }
   241 
   242 void
   243 DirectFB_GL_SwapWindow(_THIS, SDL_Window * window)
   244 {
   245     SDL_DFB_DEVICEDATA(_this);
   246     SDL_DFB_WINDOWDATA(window);
   247     int ret;
   248     DFBRegion region;
   249 
   250     region.x1 = 0;
   251     region.y1 = 0;
   252     region.x2 = window->w;
   253     region.y2 = window->h;
   254 
   255     if (devdata->glFinish)
   256         devdata->glFinish();
   257     else if (devdata->glFlush)
   258         devdata->glFlush();
   259 
   260     if (1 || windata->gl_context) {
   261         /* SDL_DFB_CHECKERR(windata->gl_context->context->Unlock(windata->gl_context->context)); */
   262         SDL_DFB_CHECKERR(windata->surface->Flip(windata->surface, &region,
   263                                                 DSFLIP_ONSYNC));
   264         /* SDL_DFB_CHECKERR(windata->gl_context->context->Lock(windata->gl_context->context)); */
   265 
   266     }
   267 
   268     return;
   269   error:
   270     return;
   271 }
   272 
   273 void
   274 DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context)
   275 {
   276     DirectFB_GLContext *ctx = (DirectFB_GLContext *) context;
   277     DirectFB_GLContext *p;
   278 
   279     ctx->context->Unlock(ctx->context);
   280     ctx->context->Release(ctx->context);
   281 
   282     p = _this->gl_data->firstgl;
   283     while (p && p->next != ctx)
   284         p = p->next;
   285     if (p)
   286         p->next = ctx->next;
   287     else
   288         _this->gl_data->firstgl = ctx->next;
   289 
   290     SDL_DFB_FREE(ctx);
   291 
   292 }
   293 
   294 #endif
   295 
   296 /* vi: set ts=4 sw=4 expandtab: */