src/video/kmsdrm/SDL_kmsdrmvideo.c
changeset 11175 cbc6a8a5b701
child 11176 9397a2d41d6b
equal deleted inserted replaced
11174:3767cdd2d64b 11175:cbc6a8a5b701
       
     1 /*
       
     2   Simple DirectMedia Layer
       
     3   Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
       
     4 
       
     5   This software is provided 'as-is', without any express or implied
       
     6   warranty.  In no event will the authors be held liable for any damages
       
     7   arising from the use of this software.
       
     8 
       
     9   Permission is granted to anyone to use this software for any purpose,
       
    10   including commercial applications, and to alter it and redistribute it
       
    11   freely, subject to the following restrictions:
       
    12 
       
    13   1. The origin of this software must not be misrepresented; you must not
       
    14      claim that you wrote the original software. If you use this software
       
    15      in a product, an acknowledgment in the product documentation would be
       
    16      appreciated but is not required.
       
    17   2. Altered source versions must be plainly marked as such, and must not be
       
    18      misrepresented as being the original software.
       
    19   3. This notice may not be removed or altered from any source distribution.
       
    20 */
       
    21 
       
    22 #include "../../SDL_internal.h"
       
    23 
       
    24 #if SDL_VIDEO_DRIVER_KMSDRM
       
    25 
       
    26 /* SDL internals */
       
    27 #include "../SDL_sysvideo.h"
       
    28 #include "SDL_version.h"
       
    29 #include "SDL_syswm.h"
       
    30 #include "SDL_loadso.h"
       
    31 #include "SDL_events.h"
       
    32 #include "SDL_log.h"
       
    33 #include "../../events/SDL_mouse_c.h"
       
    34 #include "../../events/SDL_keyboard_c.h"
       
    35 
       
    36 #ifdef SDL_INPUT_LINUXEV
       
    37 #include "../../core/linux/SDL_evdev.h"
       
    38 #endif
       
    39 
       
    40 /* KMS/DRM declarations */
       
    41 #include "SDL_kmsdrmvideo.h"
       
    42 #include "SDL_kmsdrmevents_c.h"
       
    43 #include "SDL_kmsdrmopengles.h"
       
    44 #include "SDL_kmsdrmmouse.h"
       
    45 #include "SDL_kmsdrmdyn.h"
       
    46 
       
    47 #define KMSDRM_DRI_CARD_0 "/dev/dri/card0"
       
    48 
       
    49 static int
       
    50 KMSDRM_Available(void)
       
    51 {
       
    52     int available = 0;
       
    53 
       
    54     int drm_fd = open(KMSDRM_DRI_CARD_0, O_RDWR | O_CLOEXEC);
       
    55     if (drm_fd >= 0) {
       
    56         if (SDL_KMSDRM_LoadSymbols()) {
       
    57             drmModeRes *resources = KMSDRM_drmModeGetResources(drm_fd);
       
    58             if (resources != NULL) {
       
    59                 available = 1;
       
    60                 KMSDRM_drmModeFreeResources(resources);
       
    61             }
       
    62             SDL_KMSDRM_UnloadSymbols();
       
    63         }
       
    64         close(drm_fd);
       
    65     }
       
    66 
       
    67     return available;
       
    68 }
       
    69 
       
    70 static void
       
    71 KMSDRM_Destroy(SDL_VideoDevice * device)
       
    72 {
       
    73     if (device->driverdata != NULL) {
       
    74         SDL_free(device->driverdata);
       
    75         device->driverdata = NULL;
       
    76     }
       
    77     SDL_KMSDRM_UnloadSymbols();
       
    78 }
       
    79 
       
    80 static SDL_VideoDevice *
       
    81 KMSDRM_Create(int devindex)
       
    82 {
       
    83     SDL_VideoDevice *device;
       
    84     SDL_VideoData *vdata;
       
    85 
       
    86     if (devindex < 0 || devindex > 99) {
       
    87         SDL_SetError("devindex (%d) must be between 0 and 99.\n", devindex);
       
    88         return NULL;
       
    89     }
       
    90 
       
    91     if (!SDL_KMSDRM_LoadSymbols()) {
       
    92         return NULL;
       
    93     }
       
    94 
       
    95     /* Initialize SDL_VideoDevice structure */
       
    96     device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
       
    97     if (device == NULL) {
       
    98         SDL_OutOfMemory();
       
    99         goto cleanup;
       
   100     }
       
   101 
       
   102     /* Initialize internal data */
       
   103     vdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
       
   104     if (vdata == NULL) {
       
   105         SDL_OutOfMemory();
       
   106         goto cleanup;
       
   107     }
       
   108     vdata->devindex = devindex;
       
   109     vdata->drm_fd = -1;
       
   110 
       
   111     device->driverdata = vdata;
       
   112 
       
   113     /* Setup amount of available displays and current display */
       
   114     device->num_displays = 0;
       
   115 
       
   116     /* Set device free function */
       
   117     device->free = KMSDRM_Destroy;
       
   118 
       
   119     /* Setup all functions which we can handle */
       
   120     device->VideoInit = KMSDRM_VideoInit;
       
   121     device->VideoQuit = KMSDRM_VideoQuit;
       
   122     device->GetDisplayModes = KMSDRM_GetDisplayModes;
       
   123     device->SetDisplayMode = KMSDRM_SetDisplayMode;
       
   124     device->CreateWindow = KMSDRM_CreateWindow;
       
   125     device->CreateWindowFrom = KMSDRM_CreateWindowFrom;
       
   126     device->SetWindowTitle = KMSDRM_SetWindowTitle;
       
   127     device->SetWindowIcon = KMSDRM_SetWindowIcon;
       
   128     device->SetWindowPosition = KMSDRM_SetWindowPosition;
       
   129     device->SetWindowSize = KMSDRM_SetWindowSize;
       
   130     device->ShowWindow = KMSDRM_ShowWindow;
       
   131     device->HideWindow = KMSDRM_HideWindow;
       
   132     device->RaiseWindow = KMSDRM_RaiseWindow;
       
   133     device->MaximizeWindow = KMSDRM_MaximizeWindow;
       
   134     device->MinimizeWindow = KMSDRM_MinimizeWindow;
       
   135     device->RestoreWindow = KMSDRM_RestoreWindow;
       
   136     device->SetWindowGrab = KMSDRM_SetWindowGrab;
       
   137     device->DestroyWindow = KMSDRM_DestroyWindow;
       
   138     device->GetWindowWMInfo = KMSDRM_GetWindowWMInfo;
       
   139     device->GL_LoadLibrary = KMSDRM_GLES_LoadLibrary;
       
   140     device->GL_GetProcAddress = KMSDRM_GLES_GetProcAddress;
       
   141     device->GL_UnloadLibrary = KMSDRM_GLES_UnloadLibrary;
       
   142     device->GL_CreateContext = KMSDRM_GLES_CreateContext;
       
   143     device->GL_MakeCurrent = KMSDRM_GLES_MakeCurrent;
       
   144     device->GL_SetSwapInterval = KMSDRM_GLES_SetSwapInterval;
       
   145     device->GL_GetSwapInterval = KMSDRM_GLES_GetSwapInterval;
       
   146     device->GL_SwapWindow = KMSDRM_GLES_SwapWindow;
       
   147     device->GL_DeleteContext = KMSDRM_GLES_DeleteContext;
       
   148 
       
   149     device->PumpEvents = KMSDRM_PumpEvents;
       
   150 
       
   151     return device;
       
   152 
       
   153 cleanup:
       
   154     if (device != NULL)
       
   155         SDL_free(device);
       
   156     if (vdata != NULL)
       
   157         SDL_free(vdata);
       
   158     return NULL;
       
   159 }
       
   160 
       
   161 VideoBootStrap KMSDRM_bootstrap = {
       
   162     "KMSDRM",
       
   163     "KMS/DRM Video Driver",
       
   164     KMSDRM_Available,
       
   165     KMSDRM_Create
       
   166 };
       
   167 
       
   168 
       
   169 static void
       
   170 KMSDRM_FBDestroyCallback(struct gbm_bo *bo, void *data)
       
   171 {
       
   172     KMSDRM_FBInfo *fb_info = (KMSDRM_FBInfo *)data;
       
   173 
       
   174     if (fb_info && fb_info->drm_fd > 0 && fb_info->fb_id != 0) {
       
   175         KMSDRM_drmModeRmFB(fb_info->drm_fd, fb_info->fb_id);
       
   176         SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Delete DRM FB %u", fb_info->fb_id);
       
   177     }
       
   178 
       
   179     free(fb_info);
       
   180 }
       
   181 
       
   182 KMSDRM_FBInfo *
       
   183 KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo)
       
   184 {
       
   185     uint32_t w, h, stride, handle;
       
   186     int ret;
       
   187     SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
       
   188     KMSDRM_FBInfo *fb_info;
       
   189 
       
   190     fb_info = (KMSDRM_FBInfo *)KMSDRM_gbm_bo_get_user_data(bo);
       
   191     if (fb_info != NULL) {
       
   192         /* Have a previously used framebuffer, return it */
       
   193         return fb_info;
       
   194     }
       
   195 
       
   196     /* Here a new DRM FB must be created */
       
   197     fb_info = (KMSDRM_FBInfo *)SDL_calloc(1, sizeof(KMSDRM_FBInfo));
       
   198     fb_info->drm_fd = vdata->drm_fd;
       
   199 
       
   200     w  = KMSDRM_gbm_bo_get_width(bo);
       
   201     h = KMSDRM_gbm_bo_get_height(bo);
       
   202     stride = KMSDRM_gbm_bo_get_stride(bo);
       
   203     handle = KMSDRM_gbm_bo_get_handle(bo).u32;
       
   204 
       
   205     ret = KMSDRM_drmModeAddFB(vdata->drm_fd, w, h, 24, 32, stride, handle, &fb_info->fb_id);
       
   206     if (ret < 0) {
       
   207        free(fb_info);
       
   208        return NULL;
       
   209     }
       
   210     SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "New DRM FB (%u): %ux%u, stride %u from BO %p", fb_info->fb_id, w, h, stride, (void *)bo);
       
   211 
       
   212     /* Associate our DRM framebuffer with this buffer object */
       
   213     KMSDRM_gbm_bo_set_user_data(bo, fb_info, KMSDRM_FBDestroyCallback);
       
   214     return fb_info;
       
   215 }
       
   216 
       
   217 SDL_bool
       
   218 KMSDRM_WaitPageFlip(_THIS, SDL_WindowData *wdata, int timeout) {
       
   219     SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
       
   220 
       
   221     while (wdata->waiting_for_flip) {
       
   222         vdata->drm_pollfd.revents = 0;
       
   223         if (poll(&vdata->drm_pollfd, 1, timeout) < 0) {
       
   224             SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll error");
       
   225             return SDL_FALSE;
       
   226         }
       
   227 
       
   228         if (vdata->drm_pollfd.revents & (POLLHUP | POLLERR)) {
       
   229             SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll hup or error");
       
   230             return SDL_FALSE;
       
   231         }
       
   232 
       
   233         if (vdata->drm_pollfd.revents & POLLIN) {
       
   234             /* Page flip? If so, drmHandleEvent will unset wdata->waiting_for_flip */
       
   235             KMSDRM_drmHandleEvent(vdata->drm_fd, &vdata->drm_evctx);
       
   236         } else {
       
   237             /* Timed out and page flip didn't happen */
       
   238             SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Dropping frame while waiting_for_flip");
       
   239             return SDL_FALSE;
       
   240         }
       
   241     }
       
   242     return SDL_TRUE;
       
   243 }
       
   244 
       
   245 static void
       
   246 KMSDRM_FlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data)
       
   247 {
       
   248     *((SDL_bool *) data) = SDL_FALSE;
       
   249 }
       
   250 
       
   251 
       
   252 /*****************************************************************************/
       
   253 /* SDL Video and Display initialization/handling functions                   */
       
   254 /* _this is a SDL_VideoDevice *                                              */
       
   255 /*****************************************************************************/
       
   256 int
       
   257 KMSDRM_VideoInit(_THIS)
       
   258 {
       
   259     int i;
       
   260     int ret = 0;
       
   261     char *devname;
       
   262     SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
       
   263     drmModeRes *resources = NULL;
       
   264     drmModeConnector *connector = NULL;
       
   265     drmModeEncoder *encoder = NULL;
       
   266     SDL_DisplayMode current_mode;
       
   267     SDL_VideoDisplay display;
       
   268 
       
   269     /* Allocate display internal data */
       
   270     SDL_DisplayData *data = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData));
       
   271     if (data == NULL) {
       
   272         return SDL_OutOfMemory();
       
   273     }
       
   274 
       
   275     SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoInit()");
       
   276 
       
   277     /* Open /dev/dri/cardNN */
       
   278     devname = (char *) SDL_calloc(1, 16);
       
   279     SDL_snprintf(devname, 16, "/dev/dri/card%d", vdata->devindex);
       
   280     vdata->drm_fd = open(devname, O_RDWR | O_CLOEXEC);
       
   281     SDL_free(devname);
       
   282 
       
   283     if (vdata->drm_fd < 0) {
       
   284         ret = SDL_SetError("Could not open /dev/dri/card%d.", vdata->devindex);
       
   285         goto cleanup;
       
   286     }
       
   287     SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opened DRM FD (%d)", vdata->drm_fd);
       
   288 
       
   289     vdata->gbm = KMSDRM_gbm_create_device(vdata->drm_fd);
       
   290     if (vdata->gbm == NULL) {
       
   291         ret = SDL_SetError("Couldn't create gbm device.");
       
   292         goto cleanup;
       
   293     }
       
   294 
       
   295     /* Find the first available connector with modes */
       
   296     resources = KMSDRM_drmModeGetResources(vdata->drm_fd);
       
   297     if (!resources) {
       
   298         ret = SDL_SetError("drmModeGetResources(%d) failed", vdata->drm_fd);
       
   299         goto cleanup;
       
   300     }
       
   301 
       
   302     for (i = 0; i < resources->count_connectors; i++) {
       
   303         connector = KMSDRM_drmModeGetConnector(vdata->drm_fd, resources->connectors[i]);
       
   304         if (connector == NULL)
       
   305             continue;
       
   306 
       
   307         if (connector->connection == DRM_MODE_CONNECTED &&
       
   308             connector->count_modes > 0) {
       
   309             SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found connector %d with %d modes.",
       
   310                          connector->connector_id, connector->count_modes);
       
   311             vdata->saved_conn_id = connector->connector_id;
       
   312             break;
       
   313         }
       
   314 
       
   315         KMSDRM_drmModeFreeConnector(connector);
       
   316     }
       
   317 
       
   318     if (i == resources->count_connectors) {
       
   319         ret = SDL_SetError("No currently active connector found.");
       
   320         goto cleanup;
       
   321     }
       
   322 
       
   323     for (i = 0; i < resources->count_encoders; i++) {
       
   324         encoder = KMSDRM_drmModeGetEncoder(vdata->drm_fd, resources->encoders[i]);
       
   325 
       
   326         if (encoder == NULL)
       
   327             continue;
       
   328 
       
   329         if (encoder->encoder_id == connector->encoder_id) {
       
   330             SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found encoder %d.", encoder->encoder_id);
       
   331             data->encoder_id = encoder->encoder_id;
       
   332             break;
       
   333         }
       
   334 
       
   335         KMSDRM_drmModeFreeEncoder(encoder);
       
   336     }
       
   337 
       
   338     if (i == resources->count_encoders) {
       
   339         ret = SDL_SetError("No connected encoder found.");
       
   340         goto cleanup;
       
   341     }
       
   342 
       
   343     vdata->saved_crtc = KMSDRM_drmModeGetCrtc(vdata->drm_fd, encoder->crtc_id);
       
   344     if (vdata->saved_crtc == NULL) {
       
   345         ret = SDL_SetError("No CRTC found.");
       
   346         goto cleanup;
       
   347     }
       
   348     SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Saved crtc_id %u, fb_id %u, (%u,%u), %ux%u",
       
   349                  vdata->saved_crtc->crtc_id, vdata->saved_crtc->buffer_id, vdata->saved_crtc->x,
       
   350                  vdata->saved_crtc->y, vdata->saved_crtc->width, vdata->saved_crtc->height);
       
   351     data->crtc_id = encoder->crtc_id;
       
   352     data->cur_mode = vdata->saved_crtc->mode;
       
   353 
       
   354     SDL_zero(current_mode);
       
   355 
       
   356     current_mode.w = vdata->saved_crtc->mode.hdisplay;
       
   357     current_mode.h = vdata->saved_crtc->mode.vdisplay;
       
   358     current_mode.refresh_rate = vdata->saved_crtc->mode.vrefresh;
       
   359 
       
   360     /* FIXME ?
       
   361     drmModeFB *fb = drmModeGetFB(vdata->drm_fd, vdata->saved_crtc->buffer_id);
       
   362     current_mode.format = drmToSDLPixelFormat(fb->bpp, fb->depth);
       
   363     drmModeFreeFB(fb);
       
   364     */
       
   365     current_mode.format = SDL_PIXELFORMAT_ARGB8888;
       
   366 
       
   367     current_mode.driverdata = NULL;
       
   368 
       
   369     SDL_zero(display);
       
   370     display.desktop_mode = current_mode;
       
   371     display.current_mode = current_mode;
       
   372 
       
   373     display.driverdata = data;
       
   374     /* SDL_VideoQuit will later SDL_free(display.driverdata) */
       
   375     SDL_AddVideoDisplay(&display);
       
   376 
       
   377     /* Setup page flip handler */
       
   378     vdata->drm_pollfd.fd = vdata->drm_fd;
       
   379     vdata->drm_pollfd.events = POLLIN;
       
   380     vdata->drm_evctx.version = DRM_EVENT_CONTEXT_VERSION;
       
   381     vdata->drm_evctx.page_flip_handler = KMSDRM_FlipHandler;
       
   382 
       
   383 #ifdef SDL_INPUT_LINUXEV
       
   384     SDL_EVDEV_Init();
       
   385 #endif
       
   386 
       
   387     KMSDRM_InitMouse(_this);
       
   388 
       
   389 cleanup:
       
   390     if (encoder != NULL)
       
   391         KMSDRM_drmModeFreeEncoder(encoder);
       
   392     if (connector != NULL)
       
   393         KMSDRM_drmModeFreeConnector(connector);
       
   394     if (resources != NULL)
       
   395         KMSDRM_drmModeFreeResources(resources);
       
   396 
       
   397     if (ret != 0) {
       
   398         /* Error (complete) cleanup */
       
   399         SDL_free(data);
       
   400         if(vdata->saved_crtc != NULL) {
       
   401             KMSDRM_drmModeFreeCrtc(vdata->saved_crtc);
       
   402             vdata->saved_crtc = NULL;
       
   403         }
       
   404         if (vdata->gbm != NULL) {
       
   405             KMSDRM_gbm_device_destroy(vdata->gbm);
       
   406             vdata->gbm = NULL;
       
   407         }
       
   408         if (vdata->drm_fd >= 0) {
       
   409             close(vdata->drm_fd);
       
   410             vdata->drm_fd = -1;
       
   411         }
       
   412     }
       
   413     return ret;
       
   414 }
       
   415 
       
   416 void
       
   417 KMSDRM_VideoQuit(_THIS)
       
   418 {
       
   419     SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
       
   420 
       
   421     SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoQuit()");
       
   422 
       
   423     if (_this->gl_config.driver_loaded) {
       
   424         SDL_GL_UnloadLibrary();
       
   425     }
       
   426 
       
   427     if(vdata->saved_crtc != NULL) {
       
   428         if(vdata->drm_fd > 0 && vdata->saved_conn_id > 0) {
       
   429             /* Restore saved CRTC settings */
       
   430             drmModeCrtc *crtc = vdata->saved_crtc;
       
   431             if(KMSDRM_drmModeSetCrtc(vdata->drm_fd, crtc->crtc_id, crtc->buffer_id,
       
   432                                      crtc->x, crtc->y, &vdata->saved_conn_id, 1,
       
   433                                      &crtc->mode) != 0) {
       
   434                 SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Could not restore original CRTC mode");
       
   435             }
       
   436         }
       
   437         KMSDRM_drmModeFreeCrtc(vdata->saved_crtc);
       
   438         vdata->saved_crtc = NULL;
       
   439     }
       
   440     if (vdata->gbm != NULL) {
       
   441         KMSDRM_gbm_device_destroy(vdata->gbm);
       
   442         vdata->gbm = NULL;
       
   443     }
       
   444     if (vdata->drm_fd >= 0) {
       
   445         close(vdata->drm_fd);
       
   446         SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Closed DRM FD %d", vdata->drm_fd);
       
   447         vdata->drm_fd = -1;
       
   448     }
       
   449 #ifdef SDL_INPUT_LINUXEV
       
   450     SDL_EVDEV_Quit();
       
   451 #endif
       
   452 }
       
   453 
       
   454 void
       
   455 KMSDRM_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
       
   456 {
       
   457     /* Only one display mode available, the current one */
       
   458     SDL_AddDisplayMode(display, &display->current_mode);
       
   459 }
       
   460 
       
   461 int
       
   462 KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
       
   463 {
       
   464     return 0;
       
   465 }
       
   466 
       
   467 int
       
   468 KMSDRM_CreateWindow(_THIS, SDL_Window * window)
       
   469 {
       
   470     SDL_WindowData *wdata;
       
   471     SDL_VideoDisplay *display;
       
   472     SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
       
   473     Uint32 surface_fmt, surface_flags;
       
   474 
       
   475     /* Allocate window internal data */
       
   476     wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
       
   477     if (wdata == NULL) {
       
   478         return SDL_OutOfMemory();
       
   479     }
       
   480 
       
   481     wdata->waiting_for_flip = SDL_FALSE;
       
   482     display = SDL_GetDisplayForWindow(window);
       
   483 
       
   484     /* Windows have one size for now */
       
   485     window->w = display->desktop_mode.w;
       
   486     window->h = display->desktop_mode.h;
       
   487 
       
   488     /* Maybe you didn't ask for a fullscreen OpenGL window, but that's what you get */
       
   489     window->flags |= (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL);
       
   490 
       
   491     surface_fmt = GBM_BO_FORMAT_XRGB8888;
       
   492     surface_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
       
   493 
       
   494     if (!KMSDRM_gbm_device_is_format_supported(vdata->gbm, surface_fmt, surface_flags)) {
       
   495         SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "GBM surface format not supported. Trying anyway.");
       
   496     }
       
   497     wdata->gs = KMSDRM_gbm_surface_create(vdata->gbm, window->w, window->h, surface_fmt, surface_flags);
       
   498 
       
   499 #if SDL_VIDEO_OPENGL_EGL
       
   500     if (!_this->egl_data) {
       
   501         if (SDL_GL_LoadLibrary(NULL) < 0) {
       
   502             goto error;
       
   503         }
       
   504     }
       
   505     wdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wdata->gs);
       
   506 
       
   507     if (wdata->egl_surface == EGL_NO_SURFACE) {
       
   508         SDL_SetError("Could not create EGL window surface");
       
   509         goto error;
       
   510     }
       
   511 #endif /* SDL_VIDEO_OPENGL_EGL */
       
   512 
       
   513     /* Setup driver data for this window */
       
   514     window->driverdata = wdata;
       
   515 
       
   516     /* One window, it always has focus */
       
   517     SDL_SetMouseFocus(window);
       
   518     SDL_SetKeyboardFocus(window);
       
   519 
       
   520     /* Window has been successfully created */
       
   521     return 0;
       
   522 
       
   523 error:
       
   524     if (wdata != NULL) {
       
   525 #if SDL_VIDEO_OPENGL_EGL
       
   526         if (wdata->egl_surface != EGL_NO_SURFACE)
       
   527             SDL_EGL_DestroySurface(_this, wdata->egl_surface);
       
   528 #endif /* SDL_VIDEO_OPENGL_EGL */
       
   529         if (wdata->gs != NULL)
       
   530             KMSDRM_gbm_surface_destroy(wdata->gs);
       
   531         SDL_free(wdata);
       
   532     }
       
   533     return -1;
       
   534 }
       
   535 
       
   536 void
       
   537 KMSDRM_DestroyWindow(_THIS, SDL_Window * window)
       
   538 {
       
   539     SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
       
   540     if(data) {
       
   541         /* Wait for any pending page flips and unlock buffer */
       
   542         KMSDRM_WaitPageFlip(_this, data, -1);
       
   543         if (data->locked_bo != NULL) {
       
   544             KMSDRM_gbm_surface_release_buffer(data->gs, data->locked_bo);
       
   545             data->locked_bo = NULL;
       
   546         }
       
   547 #if SDL_VIDEO_OPENGL_EGL
       
   548         SDL_EGL_MakeCurrent(_this, EGL_NO_SURFACE, EGL_NO_CONTEXT);
       
   549         if (data->egl_surface != EGL_NO_SURFACE) {
       
   550             SDL_EGL_DestroySurface(_this, data->egl_surface);
       
   551         }
       
   552 #endif /* SDL_VIDEO_OPENGL_EGL */
       
   553         if (data->gs != NULL) {
       
   554             KMSDRM_gbm_surface_destroy(data->gs);
       
   555             data->gs = NULL;
       
   556         }
       
   557         SDL_free(data);
       
   558         window->driverdata = NULL;
       
   559     }
       
   560 }
       
   561 
       
   562 int
       
   563 KMSDRM_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
       
   564 {
       
   565     return -1;
       
   566 }
       
   567 
       
   568 void
       
   569 KMSDRM_SetWindowTitle(_THIS, SDL_Window * window)
       
   570 {
       
   571 }
       
   572 void
       
   573 KMSDRM_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
       
   574 {
       
   575 }
       
   576 void
       
   577 KMSDRM_SetWindowPosition(_THIS, SDL_Window * window)
       
   578 {
       
   579 }
       
   580 void
       
   581 KMSDRM_SetWindowSize(_THIS, SDL_Window * window)
       
   582 {
       
   583 }
       
   584 void
       
   585 KMSDRM_ShowWindow(_THIS, SDL_Window * window)
       
   586 {
       
   587 }
       
   588 void
       
   589 KMSDRM_HideWindow(_THIS, SDL_Window * window)
       
   590 {
       
   591 }
       
   592 void
       
   593 KMSDRM_RaiseWindow(_THIS, SDL_Window * window)
       
   594 {
       
   595 }
       
   596 void
       
   597 KMSDRM_MaximizeWindow(_THIS, SDL_Window * window)
       
   598 {
       
   599 }
       
   600 void
       
   601 KMSDRM_MinimizeWindow(_THIS, SDL_Window * window)
       
   602 {
       
   603 }
       
   604 void
       
   605 KMSDRM_RestoreWindow(_THIS, SDL_Window * window)
       
   606 {
       
   607 }
       
   608 void
       
   609 KMSDRM_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
       
   610 {
       
   611 
       
   612 }
       
   613 
       
   614 /*****************************************************************************/
       
   615 /* SDL Window Manager function                                               */
       
   616 /*****************************************************************************/
       
   617 SDL_bool
       
   618 KMSDRM_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
       
   619 {
       
   620     if (info->version.major <= SDL_MAJOR_VERSION) {
       
   621         return SDL_TRUE;
       
   622     } else {
       
   623         SDL_SetError("application not compiled with SDL %d.%d\n",
       
   624                      SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
       
   625         return SDL_FALSE;
       
   626     }
       
   627 
       
   628     /* Failed to get window manager information */
       
   629     return SDL_FALSE;
       
   630 }
       
   631 
       
   632 #endif /* SDL_VIDEO_DRIVER_KMSDRM */
       
   633 
       
   634 /* vi: set ts=4 sw=4 expandtab: */