src/video/pandora/SDL_pandora.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 31 May 2009 11:53:12 +0000
changeset 3161 494559cc723b
child 3235 d35b649858e0
permissions -rw-r--r--
OpenPandora support added by David Carré
     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     Open Pandora SDL driver
    23     Copyright (C) 2009 David Carré
    24     (cpasjuste@gmail.com)
    25 */
    26 
    27 /* SDL internals */
    28 #include "SDL_config.h"
    29 #include "../SDL_sysvideo.h"
    30 #include "SDL_version.h"
    31 #include "SDL_syswm.h"
    32 #include "SDL_loadso.h"
    33 #include "SDL_events.h"
    34 #include "../../events/SDL_mouse_c.h"
    35 #include "../../events/SDL_keyboard_c.h"
    36 
    37 /* PND declarations */
    38 #include "SDL_pandora.h"
    39 #include "SDL_pandora_events.h"
    40 
    41 static SDL_bool PND_initialized = SDL_FALSE;
    42 
    43 static int
    44 PND_available(void)
    45 {
    46     return 1;
    47 }
    48 
    49 static void
    50 PND_destroy(SDL_VideoDevice * device)
    51 {
    52     SDL_VideoData *phdata = (SDL_VideoData *) device->driverdata;
    53 
    54     if (device->driverdata != NULL) {
    55         device->driverdata = NULL;
    56     }
    57 }
    58 
    59 static SDL_VideoDevice *
    60 PND_create()
    61 {
    62     SDL_VideoDevice *device;
    63     SDL_VideoData *phdata;
    64     int status;
    65 
    66     /* Check if pandora could be initialized */
    67     status = PND_available();
    68     if (status == 0) {
    69         /* PND could not be used */
    70         return NULL;
    71     }
    72 
    73     /* Initialize SDL_VideoDevice structure */
    74     device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
    75     if (device == NULL) {
    76         SDL_OutOfMemory();
    77         return NULL;
    78     }
    79 
    80     /* Initialize internal Pandora specific data */
    81     phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
    82     if (phdata == NULL) {
    83         SDL_OutOfMemory();
    84         SDL_free(device);
    85         return NULL;
    86     }
    87 
    88     device->driverdata = phdata;
    89 
    90     phdata->egl_initialized = SDL_TRUE;
    91 
    92 
    93     /* Setup amount of available displays and current display */
    94     device->num_displays = 1;
    95     device->current_display = 1;
    96 
    97     /* Set device free function */
    98     device->free = PND_destroy;
    99 
   100     /* Setup all functions which we can handle */
   101     device->VideoInit = PND_videoinit;
   102     device->VideoQuit = PND_videoquit;
   103     device->GetDisplayModes = PND_getdisplaymodes;
   104     device->SetDisplayMode = PND_setdisplaymode;
   105     device->SetDisplayPalette = PND_setdisplaypalette;
   106     device->GetDisplayPalette = PND_getdisplaypalette;
   107     device->SetDisplayGammaRamp = PND_setdisplaygammaramp;
   108     device->GetDisplayGammaRamp = PND_getdisplaygammaramp;
   109     device->CreateWindow = PND_createwindow;
   110     device->CreateWindowFrom = PND_createwindowfrom;
   111     device->SetWindowTitle = PND_setwindowtitle;
   112     device->SetWindowIcon = PND_setwindowicon;
   113     device->SetWindowPosition = PND_setwindowposition;
   114     device->SetWindowSize = PND_setwindowsize;
   115     device->ShowWindow = PND_showwindow;
   116     device->HideWindow = PND_hidewindow;
   117     device->RaiseWindow = PND_raisewindow;
   118     device->MaximizeWindow = PND_maximizewindow;
   119     device->MinimizeWindow = PND_minimizewindow;
   120     device->RestoreWindow = PND_restorewindow;
   121     device->SetWindowGrab = PND_setwindowgrab;
   122     device->DestroyWindow = PND_destroywindow;
   123     device->GetWindowWMInfo = PND_getwindowwminfo;
   124     device->GL_LoadLibrary = PND_gl_loadlibrary;
   125     device->GL_GetProcAddress = PND_gl_getprocaddres;
   126     device->GL_UnloadLibrary = PND_gl_unloadlibrary;
   127     device->GL_CreateContext = PND_gl_createcontext;
   128     device->GL_MakeCurrent = PND_gl_makecurrent;
   129     device->GL_SetSwapInterval = PND_gl_setswapinterval;
   130     device->GL_GetSwapInterval = PND_gl_getswapinterval;
   131     device->GL_SwapWindow = PND_gl_swapwindow;
   132     device->GL_DeleteContext = PND_gl_deletecontext;
   133     device->PumpEvents = PND_PumpEvents;
   134 
   135     return device;
   136 }
   137 
   138 VideoBootStrap PND_bootstrap = {
   139     "pandora",
   140     "SDL Pandora Video Driver",
   141     PND_available,
   142     PND_create
   143 };
   144 
   145 /*****************************************************************************/
   146 /* SDL Video and Display initialization/handling functions                   */
   147 /*****************************************************************************/
   148 int
   149 PND_videoinit(_THIS)
   150 {
   151     SDL_VideoDisplay display;
   152     SDL_DisplayMode current_mode;
   153 
   154     SDL_zero(current_mode);
   155     current_mode.w = 800;
   156     current_mode.h = 480;
   157     current_mode.refresh_rate = 60;
   158     current_mode.format = SDL_PIXELFORMAT_RGB565;
   159     current_mode.driverdata = NULL;
   160 
   161     SDL_zero(display);
   162     display.desktop_mode = current_mode;
   163     display.current_mode = current_mode;
   164     display.driverdata = NULL;
   165 
   166     SDL_AddVideoDisplay(&display);
   167 
   168     return 1;
   169 }
   170 
   171 void
   172 PND_videoquit(_THIS)
   173 {
   174 
   175 }
   176 
   177 void
   178 PND_getdisplaymodes(_THIS)
   179 {
   180 
   181 }
   182 
   183 int
   184 PND_setdisplaymode(_THIS, SDL_DisplayMode * mode)
   185 {
   186     return 0;
   187 }
   188 
   189 int
   190 PND_setdisplaypalette(_THIS, SDL_Palette * palette)
   191 {
   192     SDL_DisplayData *didata =
   193         (SDL_DisplayData *) SDL_CurrentDisplay.driverdata;
   194 
   195     /* Setting display palette operation has been failed */
   196     return -1;
   197 }
   198 
   199 int
   200 PND_getdisplaypalette(_THIS, SDL_Palette * palette)
   201 {
   202     SDL_DisplayData *didata =
   203         (SDL_DisplayData *) SDL_CurrentDisplay.driverdata;
   204 
   205     /* Getting display palette operation has been failed */
   206     return -1;
   207 }
   208 
   209 int
   210 PND_setdisplaygammaramp(_THIS, Uint16 * ramp)
   211 {
   212     SDL_DisplayData *didata =
   213         (SDL_DisplayData *) SDL_CurrentDisplay.driverdata;
   214 
   215     /* Setting display gamma ramp operation has been failed */
   216     return -1;
   217 }
   218 
   219 int
   220 PND_getdisplaygammaramp(_THIS, Uint16 * ramp)
   221 {
   222     /* Getting display gamma ramp operation has been failed */
   223     return -1;
   224 }
   225 
   226 int
   227 PND_createwindow(_THIS, SDL_Window * window)
   228 {
   229     SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
   230 
   231     SDL_WindowData *wdata;
   232 
   233     uint32_t winargc = 0;
   234     int32_t status;
   235 
   236 
   237     /* Allocate window internal data */
   238     wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
   239     if (wdata == NULL) {
   240         SDL_OutOfMemory();
   241         return -1;
   242     }
   243 
   244     /* Setup driver data for this window */
   245     window->driverdata = wdata;
   246 
   247     /* Check if window must support OpenGL ES rendering */
   248     if ((window->flags & SDL_WINDOW_OPENGL) == SDL_WINDOW_OPENGL) {
   249 
   250         EGLBoolean initstatus;
   251 
   252         /* Mark this window as OpenGL ES compatible */
   253         wdata->uses_gles = SDL_TRUE;
   254 
   255         /* Create connection to OpenGL ES */
   256         if (phdata->egl_display == EGL_NO_DISPLAY) {
   257             phdata->egl_display = eglGetDisplay((NativeDisplayType) 0);
   258             if (phdata->egl_display == EGL_NO_DISPLAY) {
   259                 SDL_SetError("PND: Can't get connection to OpenGL ES");
   260                 return -1;
   261             }
   262 
   263             initstatus = eglInitialize(phdata->egl_display, NULL, NULL);
   264             if (initstatus != EGL_TRUE) {
   265                 SDL_SetError("PND: Can't init OpenGL ES library");
   266                 return -1;
   267             }
   268         }
   269 
   270         phdata->egl_refcount++;
   271     }
   272 
   273     /* Window has been successfully created */
   274     return 0;
   275 }
   276 
   277 int
   278 PND_createwindowfrom(_THIS, SDL_Window * window, const void *data)
   279 {
   280     return -1;
   281 }
   282 
   283 void
   284 PND_setwindowtitle(_THIS, SDL_Window * window)
   285 {
   286 }
   287 void
   288 PND_setwindowicon(_THIS, SDL_Window * window, SDL_Surface * icon)
   289 {
   290 }
   291 void
   292 PND_setwindowposition(_THIS, SDL_Window * window)
   293 {
   294 }
   295 void
   296 PND_setwindowsize(_THIS, SDL_Window * window)
   297 {
   298 }
   299 void
   300 PND_showwindow(_THIS, SDL_Window * window)
   301 {
   302 }
   303 void
   304 PND_hidewindow(_THIS, SDL_Window * window)
   305 {
   306 }
   307 void
   308 PND_raisewindow(_THIS, SDL_Window * window)
   309 {
   310 }
   311 void
   312 PND_maximizewindow(_THIS, SDL_Window * window)
   313 {
   314 }
   315 void
   316 PND_minimizewindow(_THIS, SDL_Window * window)
   317 {
   318 }
   319 void
   320 PND_restorewindow(_THIS, SDL_Window * window)
   321 {
   322 }
   323 void
   324 PND_setwindowgrab(_THIS, SDL_Window * window)
   325 {
   326 }
   327 void
   328 PND_destroywindow(_THIS, SDL_Window * window)
   329 {
   330 }
   331 
   332 /*****************************************************************************/
   333 /* SDL Window Manager function                                               */
   334 /*****************************************************************************/
   335 SDL_bool
   336 PND_getwindowwminfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
   337 {
   338     if (info->version.major <= SDL_MAJOR_VERSION) {
   339         return SDL_TRUE;
   340     } else {
   341         SDL_SetError("application not compiled with SDL %d.%d\n",
   342                      SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
   343         return SDL_FALSE;
   344     }
   345 
   346     /* Failed to get window manager information */
   347     return SDL_FALSE;
   348 }
   349 
   350 /*****************************************************************************/
   351 /* SDL OpenGL/OpenGL ES functions                                            */
   352 /*****************************************************************************/
   353 int
   354 PND_gl_loadlibrary(_THIS, const char *path)
   355 {
   356     SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
   357 
   358     /* Check if OpenGL ES library is specified for GF driver */
   359     if (path == NULL) {
   360         path = SDL_getenv("SDL_OPENGL_LIBRARY");
   361         if (path == NULL) {
   362             path = SDL_getenv("SDL_OPENGLES_LIBRARY");
   363         }
   364     }
   365 
   366     /* Check if default library loading requested */
   367     if (path == NULL) {
   368         /* Already linked with GF library which provides egl* subset of  */
   369         /* functions, use Common profile of OpenGL ES library by default */
   370         path = "/usr/lib/libGLES_CM.so";
   371     }
   372 
   373     /* Load dynamic library */
   374     _this->gl_config.dll_handle = SDL_LoadObject(path);
   375     if (!_this->gl_config.dll_handle) {
   376         /* Failed to load new GL ES library */
   377         SDL_SetError("PND: Failed to locate OpenGL ES library");
   378         return -1;
   379     }
   380 
   381     /* Store OpenGL ES library path and name */
   382     SDL_strlcpy(_this->gl_config.driver_path, path,
   383                 SDL_arraysize(_this->gl_config.driver_path));
   384 
   385     /* New OpenGL ES library is loaded */
   386     return 0;
   387 }
   388 
   389 void *
   390 PND_gl_getprocaddres(_THIS, const char *proc)
   391 {
   392     SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
   393     void *function_address;
   394 
   395     /* Try to get function address through the egl interface */
   396     function_address = eglGetProcAddress(proc);
   397     if (function_address != NULL) {
   398         return function_address;
   399     }
   400 
   401     /* Then try to get function in the OpenGL ES library */
   402     if (_this->gl_config.dll_handle) {
   403         function_address =
   404             SDL_LoadFunction(_this->gl_config.dll_handle, proc);
   405         if (function_address != NULL) {
   406             return function_address;
   407         }
   408     }
   409 
   410     /* Failed to get GL ES function address pointer */
   411     SDL_SetError("PND: Cannot locate OpenGL ES function name");
   412     return NULL;
   413 }
   414 
   415 void
   416 PND_gl_unloadlibrary(_THIS)
   417 {
   418     SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
   419 
   420     if (phdata->egl_initialized == SDL_TRUE) {
   421         /* Unload OpenGL ES library */
   422         if (_this->gl_config.dll_handle) {
   423             SDL_UnloadObject(_this->gl_config.dll_handle);
   424             _this->gl_config.dll_handle = NULL;
   425         }
   426     } else {
   427         SDL_SetError("PND: GF initialization failed, no OpenGL ES support");
   428     }
   429 }
   430 
   431 SDL_GLContext
   432 PND_gl_createcontext(_THIS, SDL_Window * window)
   433 {
   434     SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
   435     SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
   436     SDL_DisplayData *didata =
   437         (SDL_DisplayData *) SDL_CurrentDisplay.driverdata;
   438     EGLBoolean status;
   439     int32_t gfstatus;
   440     EGLint configs;
   441     uint32_t attr_pos;
   442     EGLint attr_value;
   443     EGLint cit;
   444 
   445     /* Check if EGL was initialized */
   446     if (phdata->egl_initialized != SDL_TRUE) {
   447         SDL_SetError("PND: EGL initialization failed, no OpenGL ES support");
   448         return NULL;
   449     }
   450 
   451     /* Prepare attributes list to pass them to OpenGL ES */
   452     attr_pos = 0;
   453     wdata->gles_attributes[attr_pos++] = EGL_SURFACE_TYPE;
   454     wdata->gles_attributes[attr_pos++] = EGL_WINDOW_BIT;
   455     wdata->gles_attributes[attr_pos++] = EGL_RED_SIZE;
   456     wdata->gles_attributes[attr_pos++] = _this->gl_config.red_size;
   457     wdata->gles_attributes[attr_pos++] = EGL_GREEN_SIZE;
   458     wdata->gles_attributes[attr_pos++] = _this->gl_config.green_size;
   459     wdata->gles_attributes[attr_pos++] = EGL_BLUE_SIZE;
   460     wdata->gles_attributes[attr_pos++] = _this->gl_config.blue_size;
   461     wdata->gles_attributes[attr_pos++] = EGL_ALPHA_SIZE;
   462 
   463     /* Setup alpha size in bits */
   464     if (_this->gl_config.alpha_size) {
   465         wdata->gles_attributes[attr_pos++] = _this->gl_config.alpha_size;
   466     } else {
   467         wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
   468     }
   469 
   470     /* Setup color buffer size */
   471     if (_this->gl_config.buffer_size) {
   472         wdata->gles_attributes[attr_pos++] = EGL_BUFFER_SIZE;
   473         wdata->gles_attributes[attr_pos++] = _this->gl_config.buffer_size;
   474     } else {
   475         wdata->gles_attributes[attr_pos++] = EGL_BUFFER_SIZE;
   476         wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
   477     }
   478 
   479     /* Setup depth buffer bits */
   480     wdata->gles_attributes[attr_pos++] = EGL_DEPTH_SIZE;
   481     wdata->gles_attributes[attr_pos++] = _this->gl_config.depth_size;
   482 
   483     /* Setup stencil bits */
   484     if (_this->gl_config.stencil_size) {
   485         wdata->gles_attributes[attr_pos++] = EGL_STENCIL_SIZE;
   486         wdata->gles_attributes[attr_pos++] = _this->gl_config.buffer_size;
   487     } else {
   488         wdata->gles_attributes[attr_pos++] = EGL_STENCIL_SIZE;
   489         wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
   490     }
   491 
   492     /* Set number of samples in multisampling */
   493     if (_this->gl_config.multisamplesamples) {
   494         wdata->gles_attributes[attr_pos++] = EGL_SAMPLES;
   495         wdata->gles_attributes[attr_pos++] =
   496             _this->gl_config.multisamplesamples;
   497     }
   498 
   499     /* Multisample buffers, OpenGL ES 1.0 spec defines 0 or 1 buffer */
   500     if (_this->gl_config.multisamplebuffers) {
   501         wdata->gles_attributes[attr_pos++] = EGL_SAMPLE_BUFFERS;
   502         wdata->gles_attributes[attr_pos++] =
   503             _this->gl_config.multisamplebuffers;
   504     }
   505 
   506     /* Finish attributes list */
   507     wdata->gles_attributes[attr_pos] = EGL_NONE;
   508 
   509     /* Request first suitable framebuffer configuration */
   510     status = eglChooseConfig(phdata->egl_display, wdata->gles_attributes,
   511                              wdata->gles_configs, 1, &configs);
   512     if (status != EGL_TRUE) {
   513         SDL_SetError("PND: Can't find closest configuration for OpenGL ES");
   514         return NULL;
   515     }
   516 
   517     /* Check if nothing has been found, try "don't care" settings */
   518     if (configs == 0) {
   519         int32_t it;
   520         int32_t jt;
   521         GLint depthbits[4] = { 32, 24, 16, EGL_DONT_CARE };
   522 
   523         for (it = 0; it < 4; it++) {
   524             for (jt = 16; jt >= 0; jt--) {
   525                 /* Don't care about color buffer bits, use what exist */
   526                 /* Replace previous set data with EGL_DONT_CARE       */
   527                 attr_pos = 0;
   528                 wdata->gles_attributes[attr_pos++] = EGL_SURFACE_TYPE;
   529                 wdata->gles_attributes[attr_pos++] = EGL_WINDOW_BIT;
   530                 wdata->gles_attributes[attr_pos++] = EGL_RED_SIZE;
   531                 wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
   532                 wdata->gles_attributes[attr_pos++] = EGL_GREEN_SIZE;
   533                 wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
   534                 wdata->gles_attributes[attr_pos++] = EGL_BLUE_SIZE;
   535                 wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
   536                 wdata->gles_attributes[attr_pos++] = EGL_ALPHA_SIZE;
   537                 wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
   538                 wdata->gles_attributes[attr_pos++] = EGL_BUFFER_SIZE;
   539                 wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
   540 
   541                 /* Try to find requested or smallest depth */
   542                 if (_this->gl_config.depth_size) {
   543                     wdata->gles_attributes[attr_pos++] = EGL_DEPTH_SIZE;
   544                     wdata->gles_attributes[attr_pos++] = depthbits[it];
   545                 } else {
   546                     wdata->gles_attributes[attr_pos++] = EGL_DEPTH_SIZE;
   547                     wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
   548                 }
   549 
   550                 if (_this->gl_config.stencil_size) {
   551                     wdata->gles_attributes[attr_pos++] = EGL_STENCIL_SIZE;
   552                     wdata->gles_attributes[attr_pos++] = jt;
   553                 } else {
   554                     wdata->gles_attributes[attr_pos++] = EGL_STENCIL_SIZE;
   555                     wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
   556                 }
   557 
   558                 wdata->gles_attributes[attr_pos++] = EGL_SAMPLES;
   559                 wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
   560                 wdata->gles_attributes[attr_pos++] = EGL_SAMPLE_BUFFERS;
   561                 wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
   562                 wdata->gles_attributes[attr_pos] = EGL_NONE;
   563 
   564                 /* Request first suitable framebuffer configuration */
   565                 status =
   566                     eglChooseConfig(phdata->egl_display,
   567                                     wdata->gles_attributes,
   568                                     wdata->gles_configs, 1, &configs);
   569 
   570                 if (status != EGL_TRUE) {
   571                     SDL_SetError
   572                         ("PND: Can't find closest configuration for OpenGL ES");
   573                     return NULL;
   574                 }
   575                 if (configs != 0) {
   576                     break;
   577                 }
   578             }
   579             if (configs != 0) {
   580                 break;
   581             }
   582         }
   583 
   584         /* No available configs */
   585         if (configs == 0) {
   586             SDL_SetError("PND: Can't find any configuration for OpenGL ES");
   587             return NULL;
   588         }
   589     }
   590 
   591     /* Initialize config index */
   592     wdata->gles_config = 0;
   593 
   594     /* Now check each configuration to find out the best */
   595     for (cit = 0; cit < configs; cit++) {
   596         uint32_t stencil_found;
   597         uint32_t depth_found;
   598 
   599         stencil_found = 0;
   600         depth_found = 0;
   601 
   602         if (_this->gl_config.stencil_size) {
   603             status =
   604                 eglGetConfigAttrib(phdata->egl_display,
   605                                    wdata->gles_configs[cit], EGL_STENCIL_SIZE,
   606                                    &attr_value);
   607             if (status == EGL_TRUE) {
   608                 if (attr_value != 0) {
   609                     stencil_found = 1;
   610                 }
   611             }
   612         } else {
   613             stencil_found = 1;
   614         }
   615 
   616         if (_this->gl_config.depth_size) {
   617             status =
   618                 eglGetConfigAttrib(phdata->egl_display,
   619                                    wdata->gles_configs[cit], EGL_DEPTH_SIZE,
   620                                    &attr_value);
   621             if (status == EGL_TRUE) {
   622                 if (attr_value != 0) {
   623                     depth_found = 1;
   624                 }
   625             }
   626         } else {
   627             depth_found = 1;
   628         }
   629 
   630         /* Exit from loop if found appropriate configuration */
   631         if ((depth_found != 0) && (stencil_found != 0)) {
   632             break;
   633         }
   634     }
   635 
   636     /* If best could not be found, use first */
   637     if (cit == configs) {
   638         cit = 0;
   639     }
   640     wdata->gles_config = cit;
   641 
   642     /* Create OpenGL ES context */
   643     wdata->gles_context =
   644         eglCreateContext(phdata->egl_display,
   645                          wdata->gles_configs[wdata->gles_config], NULL, NULL);
   646     if (wdata->gles_context == EGL_NO_CONTEXT) {
   647         SDL_SetError("PND: OpenGL ES context creation has been failed");
   648         return NULL;
   649     }
   650 
   651     wdata->gles_surface =
   652         eglCreateWindowSurface(phdata->egl_display,
   653                                wdata->gles_configs[wdata->gles_config],
   654                                (NativeWindowType) 0, NULL);
   655     if (wdata->gles_surface == 0) {
   656         SDL_SetError("Error : eglCreateWindowSurface failed;\n");
   657         return NULL;
   658     }
   659 
   660     /* Make just created context current */
   661     status =
   662         eglMakeCurrent(phdata->egl_display, wdata->gles_surface,
   663                        wdata->gles_surface, wdata->gles_context);
   664     if (status != EGL_TRUE) {
   665         /* Destroy OpenGL ES surface */
   666         eglDestroySurface(phdata->egl_display, wdata->gles_surface);
   667         eglDestroyContext(phdata->egl_display, wdata->gles_context);
   668         wdata->gles_context = EGL_NO_CONTEXT;
   669         SDL_SetError("PND: Can't set OpenGL ES context on creation");
   670         return NULL;
   671     }
   672 
   673     _this->gl_config.accelerated = 1;
   674 
   675     /* Always clear stereo enable, since OpenGL ES do not supports stereo */
   676     _this->gl_config.stereo = 0;
   677 
   678     /* Get back samples and samplebuffers configurations. Rest framebuffer */
   679     /* parameters could be obtained through the OpenGL ES API              */
   680     status =
   681         eglGetConfigAttrib(phdata->egl_display,
   682                            wdata->gles_configs[wdata->gles_config],
   683                            EGL_SAMPLES, &attr_value);
   684     if (status == EGL_TRUE) {
   685         _this->gl_config.multisamplesamples = attr_value;
   686     }
   687     status =
   688         eglGetConfigAttrib(phdata->egl_display,
   689                            wdata->gles_configs[wdata->gles_config],
   690                            EGL_SAMPLE_BUFFERS, &attr_value);
   691     if (status == EGL_TRUE) {
   692         _this->gl_config.multisamplebuffers = attr_value;
   693     }
   694 
   695     /* Get back stencil and depth buffer sizes */
   696     status =
   697         eglGetConfigAttrib(phdata->egl_display,
   698                            wdata->gles_configs[wdata->gles_config],
   699                            EGL_DEPTH_SIZE, &attr_value);
   700     if (status == EGL_TRUE) {
   701         _this->gl_config.depth_size = attr_value;
   702     }
   703     status =
   704         eglGetConfigAttrib(phdata->egl_display,
   705                            wdata->gles_configs[wdata->gles_config],
   706                            EGL_STENCIL_SIZE, &attr_value);
   707     if (status == EGL_TRUE) {
   708         _this->gl_config.stencil_size = attr_value;
   709     }
   710 
   711     /* Under PND OpenGL ES output can't be double buffered */
   712     _this->gl_config.double_buffer = 0;
   713 
   714     /* GL ES context was successfully created */
   715     return wdata->gles_context;
   716 }
   717 
   718 int
   719 PND_gl_makecurrent(_THIS, SDL_Window * window, SDL_GLContext context)
   720 {
   721     SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
   722     SDL_WindowData *wdata;
   723     EGLBoolean status;
   724 
   725     if (phdata->egl_initialized != SDL_TRUE) {
   726         SDL_SetError("PND: GF initialization failed, no OpenGL ES support");
   727         return -1;
   728     }
   729 
   730     if ((window == NULL) && (context == NULL)) {
   731         status =
   732             eglMakeCurrent(phdata->egl_display, EGL_NO_SURFACE,
   733                            EGL_NO_SURFACE, EGL_NO_CONTEXT);
   734         if (status != EGL_TRUE) {
   735             /* Failed to set current GL ES context */
   736             SDL_SetError("PND: Can't set OpenGL ES context");
   737             return -1;
   738         }
   739     } else {
   740         wdata = (SDL_WindowData *) window->driverdata;
   741         if (wdata->gles_surface == EGL_NO_SURFACE) {
   742             SDL_SetError
   743                 ("PND: OpenGL ES surface is not initialized for this window");
   744             return -1;
   745         }
   746         if (wdata->gles_context == EGL_NO_CONTEXT) {
   747             SDL_SetError
   748                 ("PND: OpenGL ES context is not initialized for this window");
   749             return -1;
   750         }
   751         if (wdata->gles_context != context) {
   752             SDL_SetError
   753                 ("PND: OpenGL ES context is not belong to this window");
   754             return -1;
   755         }
   756         status =
   757             eglMakeCurrent(phdata->egl_display, wdata->gles_surface,
   758                            wdata->gles_surface, wdata->gles_context);
   759         if (status != EGL_TRUE) {
   760             /* Failed to set current GL ES context */
   761             SDL_SetError("PND: Can't set OpenGL ES context");
   762             return -1;
   763         }
   764     }
   765     return 0;
   766 }
   767 
   768 int
   769 PND_gl_setswapinterval(_THIS, int interval)
   770 {
   771     SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
   772     EGLBoolean status;
   773 
   774     if (phdata->egl_initialized != SDL_TRUE) {
   775         SDL_SetError("PND: EGL initialization failed, no OpenGL ES support");
   776         return -1;
   777     }
   778 
   779     /* Check if OpenGL ES connection has been initialized */
   780     if (phdata->egl_display != EGL_NO_DISPLAY) {
   781         /* Set swap OpenGL ES interval */
   782         status = eglSwapInterval(phdata->egl_display, interval);
   783         if (status == EGL_TRUE) {
   784             /* Return success to upper level */
   785             phdata->swapinterval = interval;
   786             return 0;
   787         }
   788     }
   789 
   790     /* Failed to set swap interval */
   791     SDL_SetError("PND: Cannot set swap interval");
   792     return -1;
   793 }
   794 
   795 int
   796 PND_gl_getswapinterval(_THIS)
   797 {
   798     SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
   799 
   800     if (phdata->egl_initialized != SDL_TRUE) {
   801         SDL_SetError("PND: GLES initialization failed, no OpenGL ES support");
   802         return -1;
   803     }
   804 
   805     /* Return default swap interval value */
   806     return phdata->swapinterval;
   807 }
   808 
   809 void
   810 PND_gl_swapwindow(_THIS, SDL_Window * window)
   811 {
   812     SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
   813     SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
   814     SDL_DisplayData *didata =
   815         (SDL_DisplayData *) SDL_CurrentDisplay.driverdata;
   816 
   817 
   818     if (phdata->egl_initialized != SDL_TRUE) {
   819         SDL_SetError("PND: GLES initialization failed, no OpenGL ES support");
   820         return;
   821     }
   822 
   823     /* Many applications do not uses glFinish(), so we call it for them */
   824     glFinish();
   825 
   826     /* Wait until OpenGL ES rendering is completed */
   827     eglWaitGL();
   828 
   829     eglSwapBuffers(phdata->egl_display, wdata->gles_surface);
   830 }
   831 
   832 void
   833 PND_gl_deletecontext(_THIS, SDL_GLContext context)
   834 {
   835     SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
   836     EGLBoolean status;
   837 
   838     if (phdata->egl_initialized != SDL_TRUE) {
   839         SDL_SetError("PND: GLES initialization failed, no OpenGL ES support");
   840         return;
   841     }
   842 
   843     /* Check if OpenGL ES connection has been initialized */
   844     if (phdata->egl_display != EGL_NO_DISPLAY) {
   845         if (context != EGL_NO_CONTEXT) {
   846             status = eglDestroyContext(phdata->egl_display, context);
   847             if (status != EGL_TRUE) {
   848                 /* Error during OpenGL ES context destroying */
   849                 SDL_SetError("PND: OpenGL ES context destroy error");
   850                 return;
   851             }
   852         }
   853     }
   854 
   855     return;
   856 }
   857 
   858 /* vi: set ts=4 sw=4 expandtab: */