src/video/kmsdrm/SDL_kmsdrmvideo.c
author Fabrice Fontaine <fontaine.fabrice@gmail.com>
Wed, 25 Mar 2020 09:38:45 -0700
changeset 13672 389ce8cfa2a3
parent 13592 3ff45857428d
child 13696 ea20a7434b98
permissions -rw-r--r--
src/video/kmsdrm/SDL_kmsdrmvideo.c: fix build
Build is broken without EGL since version 2.0.12 and
https://hg.libsdl.org/SDL/rev/9761858bd6a3:

/home/giuliobenetti/autobuild/run/instance-1/output-1/build/sdl2-2.0.12/src/video/kmsdrm/SDL_kmsdrmvideo.c: In function 'KMSDRM_CreateSurfaces':
/home/giuliobenetti/autobuild/run/instance-1/output-1/build/sdl2-2.0.12/src/video/kmsdrm/SDL_kmsdrmvideo.c:394:5: error: unknown type name 'EGLContext'
EGLContext egl_context;
^

Fixes:
- http://autobuild.buildroot.org/results/fafd20a01591032662f9ca025fcea3478239cf3c

Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
slouken@11175
     1
/*
slouken@11175
     2
  Simple DirectMedia Layer
slouken@13422
     3
  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
slouken@11175
     4
slouken@11175
     5
  This software is provided 'as-is', without any express or implied
slouken@11175
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@11175
     7
  arising from the use of this software.
slouken@11175
     8
slouken@11175
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@11175
    10
  including commercial applications, and to alter it and redistribute it
slouken@11175
    11
  freely, subject to the following restrictions:
slouken@11175
    12
slouken@11175
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@11175
    14
     claim that you wrote the original software. If you use this software
slouken@11175
    15
     in a product, an acknowledgment in the product documentation would be
slouken@11175
    16
     appreciated but is not required.
slouken@11175
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@11175
    18
     misrepresented as being the original software.
slouken@11175
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@11175
    20
*/
slouken@11175
    21
slouken@11175
    22
#include "../../SDL_internal.h"
slouken@11175
    23
slouken@11175
    24
#if SDL_VIDEO_DRIVER_KMSDRM
slouken@11175
    25
slouken@11175
    26
/* SDL internals */
slouken@11175
    27
#include "../SDL_sysvideo.h"
slouken@11175
    28
#include "SDL_syswm.h"
slouken@11175
    29
#include "SDL_log.h"
brandon@11658
    30
#include "SDL_hints.h"
slouken@13496
    31
#include "../../events/SDL_events_c.h"
slouken@11175
    32
#include "../../events/SDL_mouse_c.h"
slouken@11175
    33
#include "../../events/SDL_keyboard_c.h"
slouken@11175
    34
slouken@11175
    35
#ifdef SDL_INPUT_LINUXEV
slouken@11175
    36
#include "../../core/linux/SDL_evdev.h"
slouken@11175
    37
#endif
slouken@11175
    38
slouken@11175
    39
/* KMS/DRM declarations */
slouken@11175
    40
#include "SDL_kmsdrmvideo.h"
brandon@11342
    41
#include "SDL_kmsdrmevents.h"
slouken@11175
    42
#include "SDL_kmsdrmopengles.h"
slouken@11175
    43
#include "SDL_kmsdrmmouse.h"
slouken@11175
    44
#include "SDL_kmsdrmdyn.h"
icculus@12310
    45
#include <sys/stat.h>
icculus@12310
    46
#include <dirent.h>
icculus@12310
    47
#include <errno.h>
slouken@13496
    48
#include <poll.h>
slouken@11175
    49
icculus@12310
    50
#define KMSDRM_DRI_PATH "/dev/dri/"
slouken@11175
    51
slouken@11175
    52
static int
icculus@12310
    53
check_modestting(int devindex)
slouken@11175
    54
{
icculus@12310
    55
    SDL_bool available = SDL_FALSE;
icculus@12310
    56
    char device[512];
icculus@12310
    57
    int drm_fd;
slouken@11175
    58
icculus@12310
    59
    SDL_snprintf(device, sizeof (device), "%scard%d", KMSDRM_DRI_PATH, devindex);
icculus@12310
    60
icculus@12310
    61
    drm_fd = open(device, O_RDWR | O_CLOEXEC);
slouken@11175
    62
    if (drm_fd >= 0) {
slouken@11175
    63
        if (SDL_KMSDRM_LoadSymbols()) {
slouken@11175
    64
            drmModeRes *resources = KMSDRM_drmModeGetResources(drm_fd);
slouken@13496
    65
            if (resources) {
zhurxx@12441
    66
                SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "%scard%d connector, encoder and CRTC counts are: %d %d %d",
zhurxx@12441
    67
                             KMSDRM_DRI_PATH, devindex,
zhurxx@12441
    68
                             resources->count_connectors, resources->count_encoders, resources->count_crtcs);
zhurxx@12441
    69
zhurxx@12441
    70
                if (resources->count_connectors > 0 && resources->count_encoders > 0 && resources->count_crtcs > 0) {
zhurxx@12441
    71
                    available = SDL_TRUE;
zhurxx@12441
    72
                }
slouken@11175
    73
                KMSDRM_drmModeFreeResources(resources);
slouken@11175
    74
            }
slouken@11175
    75
            SDL_KMSDRM_UnloadSymbols();
slouken@11175
    76
        }
slouken@11175
    77
        close(drm_fd);
slouken@11175
    78
    }
slouken@11175
    79
slouken@11175
    80
    return available;
slouken@11175
    81
}
slouken@11175
    82
icculus@12310
    83
static int get_dricount(void)
icculus@12310
    84
{
icculus@12310
    85
    int devcount = 0;
icculus@12310
    86
    struct dirent *res;
icculus@12310
    87
    struct stat sb;
icculus@12310
    88
    DIR *folder;
icculus@12310
    89
icculus@12310
    90
    if (!(stat(KMSDRM_DRI_PATH, &sb) == 0
icculus@12310
    91
                && S_ISDIR(sb.st_mode))) {
icculus@12310
    92
        printf("The path %s cannot be opened or is not available\n",
icculus@12310
    93
               KMSDRM_DRI_PATH);
icculus@12310
    94
        return 0;
icculus@12310
    95
    }
icculus@12310
    96
icculus@12310
    97
    if (access(KMSDRM_DRI_PATH, F_OK) == -1) {
icculus@12310
    98
        printf("The path %s cannot be opened\n",
icculus@12310
    99
               KMSDRM_DRI_PATH);
icculus@12310
   100
        return 0;
icculus@12310
   101
    }
icculus@12310
   102
icculus@12310
   103
    folder = opendir(KMSDRM_DRI_PATH);
icculus@12310
   104
    if (folder) {
icculus@12310
   105
        while ((res = readdir(folder))) {
sylvain@12891
   106
            int len = SDL_strlen(res->d_name);
slouken@12892
   107
            if (len > 4 && SDL_strncmp(res->d_name, "card", 4) == 0) {
icculus@12310
   108
                devcount++;
icculus@12310
   109
            }
icculus@12310
   110
        }
icculus@12310
   111
        closedir(folder);
icculus@12310
   112
    }
icculus@12310
   113
icculus@12310
   114
    return devcount;
icculus@12310
   115
}
icculus@12310
   116
icculus@12310
   117
static int
icculus@12310
   118
get_driindex(void)
icculus@12310
   119
{
icculus@12310
   120
    const int devcount = get_dricount();
icculus@12310
   121
    int i;
icculus@12310
   122
icculus@12310
   123
    for (i = 0; i < devcount; i++) {
icculus@12310
   124
        if (check_modestting(i)) {
icculus@12310
   125
            return i;
icculus@12310
   126
        }
icculus@12310
   127
    }
icculus@12310
   128
icculus@12310
   129
    return -ENOENT;
icculus@12310
   130
}
icculus@12310
   131
icculus@12310
   132
static int
icculus@12310
   133
KMSDRM_Available(void)
icculus@12310
   134
{
icculus@12310
   135
    int ret = -ENOENT;
icculus@12310
   136
icculus@12310
   137
    ret = get_driindex();
icculus@12310
   138
    if (ret >= 0)
icculus@12310
   139
        return 1;
icculus@12310
   140
icculus@12310
   141
    return ret;
icculus@12310
   142
}
icculus@12310
   143
slouken@11175
   144
static void
slouken@13496
   145
KMSDRM_DeleteDevice(SDL_VideoDevice * device)
slouken@11175
   146
{
slouken@13496
   147
    if (device->driverdata) {
slouken@11175
   148
        SDL_free(device->driverdata);
slouken@11175
   149
        device->driverdata = NULL;
slouken@11175
   150
    }
brandon@11179
   151
brandon@11179
   152
    SDL_free(device);
slouken@13496
   153
slouken@11175
   154
    SDL_KMSDRM_UnloadSymbols();
slouken@11175
   155
}
slouken@11175
   156
slouken@11175
   157
static SDL_VideoDevice *
slouken@13496
   158
KMSDRM_CreateDevice(int devindex)
slouken@11175
   159
{
slouken@11175
   160
    SDL_VideoDevice *device;
slouken@13496
   161
    SDL_VideoData *viddata;
slouken@11175
   162
icculus@12310
   163
    if (!devindex || (devindex > 99)) {
icculus@12310
   164
        devindex = get_driindex();
icculus@12310
   165
    }
icculus@12310
   166
icculus@12310
   167
    if (devindex < 0) {
slouken@11175
   168
        SDL_SetError("devindex (%d) must be between 0 and 99.\n", devindex);
slouken@11175
   169
        return NULL;
slouken@11175
   170
    }
slouken@11175
   171
slouken@11175
   172
    if (!SDL_KMSDRM_LoadSymbols()) {
slouken@11175
   173
        return NULL;
slouken@11175
   174
    }
slouken@11175
   175
slouken@11175
   176
    device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
slouken@13496
   177
    if (!device) {
slouken@11175
   178
        SDL_OutOfMemory();
slouken@11176
   179
        return NULL;
slouken@11175
   180
    }
slouken@11175
   181
slouken@13496
   182
    viddata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
slouken@13496
   183
    if (!viddata) {
slouken@11175
   184
        SDL_OutOfMemory();
slouken@11175
   185
        goto cleanup;
slouken@11175
   186
    }
slouken@13496
   187
    viddata->devindex = devindex;
slouken@13496
   188
    viddata->drm_fd = -1;
slouken@11175
   189
slouken@13496
   190
    device->driverdata = viddata;
slouken@11175
   191
slouken@11175
   192
    /* Setup all functions which we can handle */
slouken@11175
   193
    device->VideoInit = KMSDRM_VideoInit;
slouken@11175
   194
    device->VideoQuit = KMSDRM_VideoQuit;
slouken@11175
   195
    device->GetDisplayModes = KMSDRM_GetDisplayModes;
slouken@11175
   196
    device->SetDisplayMode = KMSDRM_SetDisplayMode;
slouken@11383
   197
    device->CreateSDLWindow = KMSDRM_CreateWindow;
slouken@11383
   198
    device->CreateSDLWindowFrom = KMSDRM_CreateWindowFrom;
slouken@11175
   199
    device->SetWindowTitle = KMSDRM_SetWindowTitle;
slouken@11175
   200
    device->SetWindowIcon = KMSDRM_SetWindowIcon;
slouken@11175
   201
    device->SetWindowPosition = KMSDRM_SetWindowPosition;
slouken@11175
   202
    device->SetWindowSize = KMSDRM_SetWindowSize;
slouken@11175
   203
    device->ShowWindow = KMSDRM_ShowWindow;
slouken@11175
   204
    device->HideWindow = KMSDRM_HideWindow;
slouken@11175
   205
    device->RaiseWindow = KMSDRM_RaiseWindow;
slouken@11175
   206
    device->MaximizeWindow = KMSDRM_MaximizeWindow;
slouken@11175
   207
    device->MinimizeWindow = KMSDRM_MinimizeWindow;
slouken@11175
   208
    device->RestoreWindow = KMSDRM_RestoreWindow;
slouken@11175
   209
    device->SetWindowGrab = KMSDRM_SetWindowGrab;
slouken@11175
   210
    device->DestroyWindow = KMSDRM_DestroyWindow;
slouken@11175
   211
    device->GetWindowWMInfo = KMSDRM_GetWindowWMInfo;
philipp@11186
   212
#if SDL_VIDEO_OPENGL_EGL
slouken@11175
   213
    device->GL_LoadLibrary = KMSDRM_GLES_LoadLibrary;
slouken@11175
   214
    device->GL_GetProcAddress = KMSDRM_GLES_GetProcAddress;
slouken@11175
   215
    device->GL_UnloadLibrary = KMSDRM_GLES_UnloadLibrary;
slouken@11175
   216
    device->GL_CreateContext = KMSDRM_GLES_CreateContext;
slouken@11175
   217
    device->GL_MakeCurrent = KMSDRM_GLES_MakeCurrent;
slouken@11175
   218
    device->GL_SetSwapInterval = KMSDRM_GLES_SetSwapInterval;
slouken@11175
   219
    device->GL_GetSwapInterval = KMSDRM_GLES_GetSwapInterval;
slouken@11175
   220
    device->GL_SwapWindow = KMSDRM_GLES_SwapWindow;
slouken@11175
   221
    device->GL_DeleteContext = KMSDRM_GLES_DeleteContext;
philipp@11186
   222
#endif
slouken@11175
   223
    device->PumpEvents = KMSDRM_PumpEvents;
slouken@13496
   224
    device->free = KMSDRM_DeleteDevice;
slouken@11175
   225
slouken@11175
   226
    return device;
slouken@11175
   227
slouken@11175
   228
cleanup:
slouken@13496
   229
    if (device)
slouken@11175
   230
        SDL_free(device);
slouken@13496
   231
    if (viddata)
slouken@13496
   232
        SDL_free(viddata);
slouken@11175
   233
    return NULL;
slouken@11175
   234
}
slouken@11175
   235
slouken@11175
   236
VideoBootStrap KMSDRM_bootstrap = {
slouken@11175
   237
    "KMSDRM",
slouken@11175
   238
    "KMS/DRM Video Driver",
slouken@11175
   239
    KMSDRM_Available,
slouken@13496
   240
    KMSDRM_CreateDevice
slouken@11175
   241
};
slouken@11175
   242
slouken@11175
   243
slouken@11175
   244
static void
slouken@11175
   245
KMSDRM_FBDestroyCallback(struct gbm_bo *bo, void *data)
slouken@11175
   246
{
slouken@11175
   247
    KMSDRM_FBInfo *fb_info = (KMSDRM_FBInfo *)data;
slouken@11175
   248
sylvain@12629
   249
    if (fb_info && fb_info->drm_fd >= 0 && fb_info->fb_id != 0) {
slouken@11175
   250
        KMSDRM_drmModeRmFB(fb_info->drm_fd, fb_info->fb_id);
slouken@11175
   251
        SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Delete DRM FB %u", fb_info->fb_id);
slouken@11175
   252
    }
slouken@11175
   253
sylvain@12618
   254
    SDL_free(fb_info);
slouken@11175
   255
}
slouken@11175
   256
slouken@11175
   257
KMSDRM_FBInfo *
slouken@11175
   258
KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo)
slouken@11175
   259
{
slouken@13496
   260
    SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
slouken@13524
   261
    unsigned w,h;
slouken@13524
   262
    int ret;
slouken@13524
   263
    Uint32 stride, handle;
slouken@11175
   264
slouken@13496
   265
    /* Check for an existing framebuffer */
slouken@13496
   266
    KMSDRM_FBInfo *fb_info = (KMSDRM_FBInfo *)KMSDRM_gbm_bo_get_user_data(bo);
slouken@13496
   267
slouken@13496
   268
    if (fb_info) {
slouken@11175
   269
        return fb_info;
slouken@11175
   270
    }
slouken@11175
   271
slouken@13496
   272
    /* Create a structure that contains enough info to remove the framebuffer
slouken@13496
   273
       when the backing buffer is destroyed */
slouken@11175
   274
    fb_info = (KMSDRM_FBInfo *)SDL_calloc(1, sizeof(KMSDRM_FBInfo));
slouken@13496
   275
slouken@13496
   276
    if (!fb_info) {
philipp@11190
   277
        SDL_OutOfMemory();
philipp@11190
   278
        return NULL;
philipp@11190
   279
    }
slouken@11175
   280
slouken@13496
   281
    fb_info->drm_fd = viddata->drm_fd;
slouken@11175
   282
slouken@13496
   283
    /* Create framebuffer object for the buffer */
slouken@13524
   284
    w = KMSDRM_gbm_bo_get_width(bo);
slouken@13524
   285
    h = KMSDRM_gbm_bo_get_height(bo);
slouken@13524
   286
    stride = KMSDRM_gbm_bo_get_stride(bo);
slouken@13524
   287
    handle = KMSDRM_gbm_bo_get_handle(bo).u32;
slouken@13524
   288
    ret = KMSDRM_drmModeAddFB(viddata->drm_fd, w, h, 24, 32, stride, handle,
slouken@13496
   289
                                  &fb_info->fb_id);
slouken@13496
   290
    if (ret) {
slouken@13496
   291
      SDL_free(fb_info);
slouken@13496
   292
      return NULL;
slouken@11175
   293
    }
slouken@13496
   294
slouken@13496
   295
    SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "New DRM FB (%u): %ux%u, stride %u from BO %p",
slouken@13496
   296
                 fb_info->fb_id, w, h, stride, (void *)bo);
slouken@11175
   297
slouken@11175
   298
    /* Associate our DRM framebuffer with this buffer object */
slouken@11175
   299
    KMSDRM_gbm_bo_set_user_data(bo, fb_info, KMSDRM_FBDestroyCallback);
slouken@13496
   300
slouken@11175
   301
    return fb_info;
slouken@11175
   302
}
slouken@11175
   303
slouken@11175
   304
static void
slouken@11175
   305
KMSDRM_FlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data)
slouken@11175
   306
{
slouken@11175
   307
    *((SDL_bool *) data) = SDL_FALSE;
slouken@11175
   308
}
slouken@11175
   309
slouken@13496
   310
SDL_bool
slouken@13496
   311
KMSDRM_WaitPageFlip(_THIS, SDL_WindowData *windata, int timeout) {
slouken@13496
   312
    SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
slouken@13524
   313
    drmEventContext ev = {0};
slouken@13524
   314
    struct pollfd pfd = {0};
slouken@13496
   315
slouken@13496
   316
    ev.version = DRM_EVENT_CONTEXT_VERSION;
slouken@13496
   317
    ev.page_flip_handler = KMSDRM_FlipHandler;
slouken@13496
   318
slouken@13496
   319
    pfd.fd = viddata->drm_fd;
slouken@13496
   320
    pfd.events = POLLIN;
slouken@13496
   321
slouken@13496
   322
    while (windata->waiting_for_flip) {
slouken@13496
   323
        pfd.revents = 0;
slouken@13496
   324
slouken@13496
   325
        if (poll(&pfd, 1, timeout) < 0) {
slouken@13496
   326
            SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll error");
slouken@13496
   327
            return SDL_FALSE;
slouken@13496
   328
        }
slouken@13496
   329
slouken@13496
   330
        if (pfd.revents & (POLLHUP | POLLERR)) {
slouken@13496
   331
            SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll hup or error");
slouken@13496
   332
            return SDL_FALSE;
slouken@13496
   333
        }
slouken@13496
   334
slouken@13496
   335
        if (pfd.revents & POLLIN) {
slouken@13496
   336
            /* Page flip? If so, drmHandleEvent will unset windata->waiting_for_flip */
slouken@13496
   337
            KMSDRM_drmHandleEvent(viddata->drm_fd, &ev);
slouken@13496
   338
        } else {
slouken@13496
   339
            /* Timed out and page flip didn't happen */
slouken@13496
   340
            SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Dropping frame while waiting_for_flip");
slouken@13496
   341
            return SDL_FALSE;
slouken@13496
   342
        }
slouken@13496
   343
    }
slouken@13496
   344
slouken@13496
   345
    return SDL_TRUE;
slouken@13496
   346
}
slouken@11175
   347
slouken@11175
   348
/*****************************************************************************/
slouken@11175
   349
/* SDL Video and Display initialization/handling functions                   */
slouken@11175
   350
/* _this is a SDL_VideoDevice *                                              */
slouken@11175
   351
/*****************************************************************************/
slouken@13555
   352
static void
slouken@13496
   353
KMSDRM_DestroySurfaces(_THIS, SDL_Window * window)
slouken@13496
   354
{
slouken@13496
   355
    SDL_WindowData *windata = (SDL_WindowData *)window->driverdata;
slouken@13496
   356
slouken@13496
   357
    KMSDRM_WaitPageFlip(_this, windata, -1);
slouken@13496
   358
slouken@13496
   359
    if (windata->curr_bo) {
slouken@13496
   360
        KMSDRM_gbm_surface_release_buffer(windata->gs, windata->curr_bo);
slouken@13496
   361
        windata->curr_bo = NULL;
slouken@13496
   362
    }
slouken@13496
   363
slouken@13496
   364
    if (windata->next_bo) {
slouken@13496
   365
        KMSDRM_gbm_surface_release_buffer(windata->gs, windata->next_bo);
slouken@13496
   366
        windata->next_bo = NULL;
slouken@13496
   367
    }
slouken@13496
   368
slouken@13496
   369
#if SDL_VIDEO_OPENGL_EGL
slouken@13496
   370
    SDL_EGL_MakeCurrent(_this, EGL_NO_SURFACE, EGL_NO_CONTEXT);
slouken@13496
   371
slouken@13496
   372
    if (windata->egl_surface != EGL_NO_SURFACE) {
slouken@13496
   373
        SDL_EGL_DestroySurface(_this, windata->egl_surface);
slouken@13496
   374
        windata->egl_surface = EGL_NO_SURFACE;
slouken@13496
   375
    }
slouken@13496
   376
#endif
slouken@13496
   377
slouken@13496
   378
    if (windata->gs) {
slouken@13496
   379
        KMSDRM_gbm_surface_destroy(windata->gs);
slouken@13496
   380
        windata->gs = NULL;
slouken@13496
   381
    }
slouken@13496
   382
}
slouken@13496
   383
slouken@13496
   384
int
slouken@13496
   385
KMSDRM_CreateSurfaces(_THIS, SDL_Window * window)
slouken@13496
   386
{
slouken@13496
   387
    SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
slouken@13496
   388
    SDL_WindowData *windata = (SDL_WindowData *)window->driverdata;
slouken@13496
   389
    SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
slouken@13496
   390
    Uint32 width = dispdata->mode.hdisplay;
slouken@13496
   391
    Uint32 height = dispdata->mode.vdisplay;
slouken@13496
   392
    Uint32 surface_fmt = GBM_FORMAT_XRGB8888;
slouken@13496
   393
    Uint32 surface_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
fontaine@13672
   394
#if SDL_VIDEO_OPENGL_EGL
slouken@13524
   395
    EGLContext egl_context;
fontaine@13672
   396
#endif
slouken@13496
   397
slouken@13496
   398
    if (!KMSDRM_gbm_device_is_format_supported(viddata->gbm, surface_fmt, surface_flags)) {
slouken@13496
   399
        SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "GBM surface format not supported. Trying anyway.");
slouken@13496
   400
    }
slouken@13496
   401
slouken@13496
   402
#if SDL_VIDEO_OPENGL_EGL
slouken@13496
   403
    SDL_EGL_SetRequiredVisualId(_this, surface_fmt);
slouken@13524
   404
    egl_context = (EGLContext)SDL_GL_GetCurrentContext();
slouken@13496
   405
#endif
slouken@13496
   406
slouken@13496
   407
    KMSDRM_DestroySurfaces(_this, window);
slouken@13496
   408
slouken@13496
   409
    windata->gs = KMSDRM_gbm_surface_create(viddata->gbm, width, height, surface_fmt, surface_flags);
slouken@13496
   410
slouken@13496
   411
    if (!windata->gs) {
slouken@13496
   412
        return SDL_SetError("Could not create GBM surface");
slouken@13496
   413
    }
slouken@13496
   414
slouken@13496
   415
#if SDL_VIDEO_OPENGL_EGL
slouken@13496
   416
    windata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType)windata->gs);
slouken@13496
   417
slouken@13496
   418
    if (windata->egl_surface == EGL_NO_SURFACE) {
slouken@13496
   419
        return SDL_SetError("Could not create EGL window surface");
slouken@13496
   420
    }
slouken@13496
   421
slouken@13496
   422
    SDL_EGL_MakeCurrent(_this, windata->egl_surface, egl_context);
slouken@13496
   423
slouken@13496
   424
    windata->egl_surface_dirty = 0;
slouken@13496
   425
#endif
slouken@13496
   426
slouken@13496
   427
    return 0;
slouken@13496
   428
}
slouken@13496
   429
slouken@11175
   430
int
slouken@11175
   431
KMSDRM_VideoInit(_THIS)
slouken@11175
   432
{
slouken@11175
   433
    int ret = 0;
slouken@13496
   434
    SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
slouken@13496
   435
    SDL_DisplayData *dispdata = NULL;
slouken@11175
   436
    drmModeRes *resources = NULL;
slouken@11175
   437
    drmModeEncoder *encoder = NULL;
slouken@13524
   438
    char devname[32];
slouken@13524
   439
    SDL_VideoDisplay display = {0};
slouken@11175
   440
slouken@13496
   441
    dispdata = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData));
slouken@13496
   442
slouken@13496
   443
    if (!dispdata) {
slouken@11175
   444
        return SDL_OutOfMemory();
slouken@11175
   445
    }
slouken@11175
   446
slouken@11175
   447
    SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoInit()");
slouken@11175
   448
slouken@11175
   449
    /* Open /dev/dri/cardNN */
slouken@13496
   450
    SDL_snprintf(devname, sizeof(devname), "/dev/dri/card%d", viddata->devindex);
slouken@13496
   451
slouken@13496
   452
    SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opening device %s", devname);
slouken@13496
   453
    viddata->drm_fd = open(devname, O_RDWR | O_CLOEXEC);
slouken@13496
   454
slouken@13496
   455
    if (viddata->drm_fd < 0) {
slouken@13496
   456
        ret = SDL_SetError("Could not open %s", devname);
philipp@11190
   457
        goto cleanup;
philipp@11190
   458
    }
slouken@13496
   459
slouken@13496
   460
    SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opened DRM FD (%d)", viddata->drm_fd);
slouken@11175
   461
slouken@13496
   462
    viddata->gbm = KMSDRM_gbm_create_device(viddata->drm_fd);
slouken@13496
   463
    if (!viddata->gbm) {
slouken@11175
   464
        ret = SDL_SetError("Couldn't create gbm device.");
slouken@11175
   465
        goto cleanup;
slouken@11175
   466
    }
slouken@11175
   467
slouken@13496
   468
    /* Get all of the available connectors / devices / crtcs */
slouken@13496
   469
    resources = KMSDRM_drmModeGetResources(viddata->drm_fd);
slouken@11175
   470
    if (!resources) {
slouken@13496
   471
        ret = SDL_SetError("drmModeGetResources(%d) failed", viddata->drm_fd);
slouken@11175
   472
        goto cleanup;
slouken@11175
   473
    }
slouken@11175
   474
slouken@13496
   475
    for (int i = 0; i < resources->count_connectors; i++) {
slouken@13496
   476
        drmModeConnector *conn = KMSDRM_drmModeGetConnector(viddata->drm_fd, resources->connectors[i]);
slouken@11175
   477
slouken@13496
   478
        if (!conn) {
slouken@13496
   479
            continue;
slouken@13496
   480
        }
slouken@13496
   481
slouken@13496
   482
        if (conn->connection == DRM_MODE_CONNECTED && conn->count_modes) {
slouken@11175
   483
            SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found connector %d with %d modes.",
slouken@13496
   484
                         conn->connector_id, conn->count_modes);
slouken@13496
   485
            dispdata->conn = conn;
slouken@11175
   486
            break;
slouken@11175
   487
        }
slouken@11175
   488
slouken@13496
   489
        KMSDRM_drmModeFreeConnector(conn);
slouken@11175
   490
    }
slouken@11175
   491
slouken@13496
   492
    if (!dispdata->conn) {
slouken@11175
   493
        ret = SDL_SetError("No currently active connector found.");
slouken@11175
   494
        goto cleanup;
slouken@11175
   495
    }
slouken@11175
   496
slouken@13496
   497
    /* Try to find the connector's current encoder */
slouken@13496
   498
    for (int i = 0; i < resources->count_encoders; i++) {
slouken@13496
   499
        encoder = KMSDRM_drmModeGetEncoder(viddata->drm_fd, resources->encoders[i]);
slouken@11175
   500
slouken@13496
   501
        if (!encoder) {
slouken@13496
   502
          continue;
zhurxx@12440
   503
        }
zhurxx@12440
   504
slouken@13496
   505
        if (encoder->encoder_id == dispdata->conn->encoder_id) {
slouken@13496
   506
            SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found encoder %d.", encoder->encoder_id);
slouken@11175
   507
            break;
slouken@11175
   508
        }
slouken@11175
   509
slouken@11175
   510
        KMSDRM_drmModeFreeEncoder(encoder);
slouken@11217
   511
        encoder = NULL;
slouken@11175
   512
    }
slouken@11175
   513
slouken@13496
   514
    if (!encoder) {
slouken@13496
   515
        /* No encoder was connected, find the first supported one */
slouken@13496
   516
        for (int i = 0, j; i < resources->count_encoders; i++) {
slouken@13496
   517
            encoder = KMSDRM_drmModeGetEncoder(viddata->drm_fd, resources->encoders[i]);
slouken@13496
   518
slouken@13496
   519
            if (!encoder) {
slouken@13496
   520
              continue;
slouken@13496
   521
            }
slouken@13496
   522
slouken@13496
   523
            for (j = 0; j < dispdata->conn->count_encoders; j++) {
slouken@13496
   524
                if (dispdata->conn->encoders[j] == encoder->encoder_id) {
slouken@13496
   525
                    break;
slouken@13496
   526
                }
slouken@13496
   527
            }
slouken@13496
   528
slouken@13496
   529
            if (j != dispdata->conn->count_encoders) {
slouken@13496
   530
              break;
slouken@13496
   531
            }
slouken@13496
   532
slouken@13496
   533
            KMSDRM_drmModeFreeEncoder(encoder);
slouken@13496
   534
            encoder = NULL;
slouken@13496
   535
        }
slouken@13496
   536
    }
slouken@13496
   537
slouken@13496
   538
    if (!encoder) {
slouken@11175
   539
        ret = SDL_SetError("No connected encoder found.");
slouken@11175
   540
        goto cleanup;
slouken@11175
   541
    }
slouken@11175
   542
slouken@13496
   543
    SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found encoder %d.", encoder->encoder_id);
zhurxx@12440
   544
slouken@13496
   545
    /* Try to find a CRTC connected to this encoder */
slouken@13496
   546
    dispdata->saved_crtc = KMSDRM_drmModeGetCrtc(viddata->drm_fd, encoder->crtc_id);
slouken@13496
   547
slouken@13496
   548
    if (!dispdata->saved_crtc) {
slouken@13496
   549
        /* No CRTC was connected, find the first CRTC that can be connected */
slouken@13496
   550
        for (int i = 0; i < resources->count_crtcs; i++) {
zhurxx@12440
   551
            if (encoder->possible_crtcs & (1 << i)) {
zhurxx@12440
   552
                encoder->crtc_id = resources->crtcs[i];
slouken@13496
   553
                dispdata->saved_crtc = KMSDRM_drmModeGetCrtc(viddata->drm_fd, encoder->crtc_id);
zhurxx@12440
   554
                break;
zhurxx@12440
   555
            }
zhurxx@12440
   556
        }
zhurxx@12440
   557
    }
zhurxx@12440
   558
slouken@13496
   559
    if (!dispdata->saved_crtc) {
slouken@11175
   560
        ret = SDL_SetError("No CRTC found.");
slouken@11175
   561
        goto cleanup;
slouken@11175
   562
    }
slouken@13496
   563
slouken@11175
   564
    SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Saved crtc_id %u, fb_id %u, (%u,%u), %ux%u",
slouken@13496
   565
                 dispdata->saved_crtc->crtc_id, dispdata->saved_crtc->buffer_id, dispdata->saved_crtc->x,
slouken@13496
   566
                 dispdata->saved_crtc->y, dispdata->saved_crtc->width, dispdata->saved_crtc->height);
slouken@13496
   567
slouken@13496
   568
    dispdata->crtc_id = encoder->crtc_id;
slouken@11175
   569
slouken@13496
   570
    /* Figure out the default mode to be set. If the current CRTC's mode isn't
slouken@13496
   571
       valid, select the first mode supported by the connector
slouken@13496
   572
slouken@13496
   573
       FIXME find first mode that specifies DRM_MODE_TYPE_PREFERRED */
slouken@13496
   574
    dispdata->mode = dispdata->saved_crtc->mode;
slouken@13496
   575
slouken@13496
   576
    if (dispdata->saved_crtc->mode_valid == 0) {
zhurxx@12440
   577
        SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO,
zhurxx@12440
   578
            "Current mode is invalid, selecting connector's mode #0.");
slouken@13496
   579
        dispdata->mode = dispdata->conn->modes[0];
zhurxx@12440
   580
    }
zhurxx@12440
   581
slouken@13496
   582
    /* Setup the single display that's available */
slouken@13524
   583
slouken@13496
   584
    display.desktop_mode.w = dispdata->mode.hdisplay;
slouken@13496
   585
    display.desktop_mode.h = dispdata->mode.vdisplay;
slouken@13496
   586
    display.desktop_mode.refresh_rate = dispdata->mode.vrefresh;
slouken@13496
   587
#if 1
slouken@13496
   588
    display.desktop_mode.format = SDL_PIXELFORMAT_ARGB8888;
slouken@13496
   589
#else
slouken@13496
   590
    /* FIXME */
slouken@13496
   591
    drmModeFB *fb = drmModeGetFB(viddata->drm_fd, dispdata->saved_crtc->buffer_id);
slouken@13496
   592
    display.desktop_mode.format = drmToSDLPixelFormat(fb->bpp, fb->depth);
slouken@11175
   593
    drmModeFreeFB(fb);
slouken@13496
   594
#endif
slouken@13496
   595
    display.current_mode = display.desktop_mode;
slouken@13496
   596
    display.driverdata = dispdata;
slouken@11175
   597
    SDL_AddVideoDisplay(&display);
slouken@11175
   598
slouken@11175
   599
#ifdef SDL_INPUT_LINUXEV
slouken@11175
   600
    SDL_EVDEV_Init();
slouken@11175
   601
#endif
slouken@11175
   602
slouken@11175
   603
    KMSDRM_InitMouse(_this);
slouken@11175
   604
sylvain@12619
   605
    return ret;
sylvain@12619
   606
slouken@11175
   607
cleanup:
slouken@13496
   608
    if (encoder)
slouken@11175
   609
        KMSDRM_drmModeFreeEncoder(encoder);
slouken@13496
   610
    if (resources)
slouken@11175
   611
        KMSDRM_drmModeFreeResources(resources);
slouken@11175
   612
slouken@11175
   613
    if (ret != 0) {
slouken@11175
   614
        /* Error (complete) cleanup */
slouken@13496
   615
        if (dispdata->conn) {
slouken@13496
   616
            KMSDRM_drmModeFreeConnector(dispdata->conn);
slouken@13496
   617
            dispdata->conn = NULL;
slouken@13496
   618
        }
slouken@13496
   619
        if (dispdata->saved_crtc) {
slouken@13496
   620
            KMSDRM_drmModeFreeCrtc(dispdata->saved_crtc);
slouken@13496
   621
            dispdata->saved_crtc = NULL;
slouken@11175
   622
        }
slouken@13496
   623
        if (viddata->gbm) {
slouken@13496
   624
            KMSDRM_gbm_device_destroy(viddata->gbm);
slouken@13496
   625
            viddata->gbm = NULL;
slouken@11175
   626
        }
slouken@13496
   627
        if (viddata->drm_fd >= 0) {
slouken@13496
   628
            close(viddata->drm_fd);
slouken@13496
   629
            viddata->drm_fd = -1;
slouken@11175
   630
        }
slouken@13496
   631
        SDL_free(dispdata);
slouken@11175
   632
    }
slouken@11175
   633
    return ret;
slouken@11175
   634
}
slouken@11175
   635
slouken@11175
   636
void
slouken@11175
   637
KMSDRM_VideoQuit(_THIS)
slouken@11175
   638
{
slouken@13496
   639
    SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
slouken@13496
   640
    SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
slouken@11175
   641
slouken@11175
   642
    SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoQuit()");
slouken@11175
   643
slouken@11175
   644
    if (_this->gl_config.driver_loaded) {
slouken@11175
   645
        SDL_GL_UnloadLibrary();
slouken@11175
   646
    }
slouken@11175
   647
slouken@13496
   648
    /* Clear out the window list */
slouken@13496
   649
    SDL_free(viddata->windows);
slouken@13496
   650
    viddata->windows = NULL;
slouken@13496
   651
    viddata->max_windows = 0;
slouken@13496
   652
    viddata->num_windows = 0;
slouken@13496
   653
slouken@13496
   654
    /* Restore saved CRTC settings */
slouken@13577
   655
    if (viddata->drm_fd >= 0 && dispdata && dispdata->conn && dispdata->saved_crtc) {
slouken@13496
   656
        drmModeConnector *conn = dispdata->conn;
slouken@13496
   657
        drmModeCrtc *crtc = dispdata->saved_crtc;
slouken@13496
   658
slouken@13496
   659
        int ret = KMSDRM_drmModeSetCrtc(viddata->drm_fd, crtc->crtc_id, crtc->buffer_id,
slouken@13496
   660
                                        crtc->x, crtc->y, &conn->connector_id, 1, &crtc->mode);
slouken@13496
   661
slouken@13496
   662
        if (ret != 0) {
slouken@13496
   663
            SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Could not restore original CRTC mode");
slouken@11175
   664
        }
slouken@13496
   665
    }
slouken@13577
   666
    if (dispdata && dispdata->conn) {
slouken@13496
   667
        KMSDRM_drmModeFreeConnector(dispdata->conn);
slouken@13496
   668
        dispdata->conn = NULL;
slouken@13496
   669
    }
slouken@13577
   670
    if (dispdata && dispdata->saved_crtc) {
slouken@13496
   671
        KMSDRM_drmModeFreeCrtc(dispdata->saved_crtc);
slouken@13496
   672
        dispdata->saved_crtc = NULL;
slouken@11175
   673
    }
slouken@13496
   674
    if (viddata->gbm) {
slouken@13496
   675
        KMSDRM_gbm_device_destroy(viddata->gbm);
slouken@13496
   676
        viddata->gbm = NULL;
slouken@11175
   677
    }
slouken@13496
   678
    if (viddata->drm_fd >= 0) {
slouken@13496
   679
        close(viddata->drm_fd);
slouken@13496
   680
        SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Closed DRM FD %d", viddata->drm_fd);
slouken@13496
   681
        viddata->drm_fd = -1;
slouken@11175
   682
    }
slouken@11175
   683
#ifdef SDL_INPUT_LINUXEV
slouken@11175
   684
    SDL_EVDEV_Quit();
slouken@11175
   685
#endif
slouken@11175
   686
}
slouken@11175
   687
slouken@11175
   688
void
slouken@11175
   689
KMSDRM_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
slouken@11175
   690
{
slouken@13496
   691
    SDL_DisplayData *dispdata = display->driverdata;
slouken@13496
   692
    drmModeConnector *conn = dispdata->conn;
slouken@13524
   693
    SDL_DisplayMode mode;
slouken@13496
   694
slouken@13496
   695
    for (int i = 0; i < conn->count_modes; i++) {
slouken@13496
   696
        SDL_DisplayModeData *modedata = SDL_calloc(1, sizeof(SDL_DisplayModeData));
slouken@13496
   697
slouken@13496
   698
        if (modedata) {
slouken@13496
   699
          modedata->mode_index = i;
slouken@13496
   700
        }
slouken@13496
   701
slouken@13496
   702
        mode.w = conn->modes[i].hdisplay;
slouken@13496
   703
        mode.h = conn->modes[i].vdisplay;
slouken@13496
   704
        mode.refresh_rate = conn->modes[i].vrefresh;
slouken@13496
   705
        mode.format = SDL_PIXELFORMAT_ARGB8888;
slouken@13496
   706
        mode.driverdata = modedata;
slouken@13496
   707
slouken@13496
   708
        if (!SDL_AddDisplayMode(display, &mode)) {
slouken@13496
   709
            SDL_free(modedata);
slouken@13496
   710
        }
slouken@13496
   711
    }
slouken@11175
   712
}
slouken@11175
   713
slouken@11175
   714
int
slouken@11175
   715
KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
slouken@11175
   716
{
slouken@13496
   717
    SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata;
slouken@13496
   718
    SDL_DisplayData *dispdata = (SDL_DisplayData *)display->driverdata;
slouken@13496
   719
    SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
slouken@13524
   720
    drmModeConnector *conn = dispdata->conn;
slouken@13496
   721
slouken@13496
   722
    if (!modedata) {
slouken@13496
   723
        return SDL_SetError("Mode doesn't have an associated index");
slouken@13496
   724
    }
slouken@13496
   725
slouken@13496
   726
    dispdata->mode = conn->modes[modedata->mode_index];
slouken@13496
   727
slouken@13496
   728
    for (int i = 0; i < viddata->num_windows; i++) {
slouken@13496
   729
        SDL_Window *window = viddata->windows[i];
slouken@13496
   730
        SDL_WindowData *windata = (SDL_WindowData *)window->driverdata;
slouken@13496
   731
slouken@13496
   732
#if SDL_VIDEO_OPENGL_EGL
slouken@13496
   733
        /* Can't recreate EGL surfaces right now, need to wait until SwapWindow
slouken@13496
   734
           so the correct thread-local surface and context state are available */
slouken@13496
   735
        windata->egl_surface_dirty = 1;
slouken@13496
   736
#else
slouken@13496
   737
        if (KMSDRM_CreateSurfaces(_this, window)) {
slouken@13496
   738
            return -1;
slouken@13496
   739
        }
slouken@13496
   740
#endif
slouken@13496
   741
slouken@13496
   742
        /* Tell app about the resize */
slouken@13496
   743
        SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, mode->w, mode->h);
slouken@13496
   744
    }
slouken@13496
   745
slouken@11175
   746
    return 0;
slouken@11175
   747
}
slouken@11175
   748
slouken@11175
   749
int
slouken@11175
   750
KMSDRM_CreateWindow(_THIS, SDL_Window * window)
slouken@11175
   751
{
slouken@13496
   752
    SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata;
slouken@13524
   753
    SDL_WindowData *windata;
slouken@13524
   754
    SDL_VideoDisplay *display;
slouken@11175
   755
slouken@11175
   756
#if SDL_VIDEO_OPENGL_EGL
slouken@11175
   757
    if (!_this->egl_data) {
slouken@11175
   758
        if (SDL_GL_LoadLibrary(NULL) < 0) {
slouken@11175
   759
            goto error;
slouken@11175
   760
        }
slouken@11175
   761
    }
slouken@13496
   762
#endif
slouken@11175
   763
slouken@13496
   764
    /* Allocate window internal data */
slouken@13524
   765
    windata = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData));
slouken@13496
   766
slouken@13496
   767
    if (!windata) {
slouken@13496
   768
        SDL_OutOfMemory();
slouken@11175
   769
        goto error;
slouken@11175
   770
    }
slouken@13496
   771
slouken@13496
   772
    /* Windows have one size for now */
slouken@13524
   773
    display = SDL_GetDisplayForWindow(window);
slouken@13496
   774
    window->w = display->desktop_mode.w;
slouken@13496
   775
    window->h = display->desktop_mode.h;
slouken@13496
   776
slouken@13496
   777
    /* Maybe you didn't ask for a fullscreen OpenGL window, but that's what you get */
slouken@13496
   778
    window->flags |= (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL);
slouken@11175
   779
brandon@11658
   780
    /* In case we want low-latency, double-buffer video, we take note here */
slouken@13496
   781
    windata->double_buffer = SDL_FALSE;
slouken@13496
   782
brandontschaefer@11694
   783
    if (SDL_GetHintBoolean(SDL_HINT_VIDEO_DOUBLE_BUFFER, SDL_FALSE)) {
slouken@13496
   784
        windata->double_buffer = SDL_TRUE;
brandon@11658
   785
    }
brandon@11658
   786
slouken@13496
   787
    /* Setup driver data for this window */
slouken@13496
   788
    window->driverdata = windata;
slouken@13496
   789
slouken@13496
   790
    if (KMSDRM_CreateSurfaces(_this, window)) {
slouken@13496
   791
      goto error;
slouken@13496
   792
    }
slouken@13496
   793
slouken@13496
   794
    /* Add window to the internal list of tracked windows. Note, while it may
slouken@13496
   795
       seem odd to support multiple fullscreen windows, some apps create an
slouken@13496
   796
       extra window as a dummy surface when working with multiple contexts */
slouken@13496
   797
    windata->viddata = viddata;
slouken@11643
   798
slouken@13496
   799
    if (viddata->num_windows >= viddata->max_windows) {
slouken@13496
   800
        int new_max_windows = viddata->max_windows + 1;
slouken@13496
   801
        viddata->windows = (SDL_Window **)SDL_realloc(viddata->windows,
slouken@13496
   802
              new_max_windows * sizeof(SDL_Window *));
slouken@13496
   803
        viddata->max_windows = new_max_windows;
slouken@11175
   804
slouken@13496
   805
        if (!viddata->windows) {
slouken@13496
   806
            SDL_OutOfMemory();
slouken@13496
   807
            goto error;
slouken@13496
   808
        }
slouken@13496
   809
    }
slouken@11175
   810
slouken@13496
   811
    viddata->windows[viddata->num_windows++] = window;
slouken@13496
   812
slouken@13592
   813
    /* Focus on the newly created window */
slouken@13592
   814
    SDL_SetMouseFocus(window);
slouken@13592
   815
    SDL_SetKeyboardFocus(window);
slouken@13592
   816
slouken@11175
   817
    return 0;
slouken@11175
   818
slouken@11175
   819
error:
slouken@13496
   820
    KMSDRM_DestroyWindow(_this, window);
slouken@13496
   821
slouken@11175
   822
    return -1;
slouken@11175
   823
}
slouken@11175
   824
slouken@11175
   825
void
slouken@11175
   826
KMSDRM_DestroyWindow(_THIS, SDL_Window * window)
slouken@11175
   827
{
slouken@13496
   828
    SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
slouken@13524
   829
    SDL_VideoData *viddata;
slouken@13496
   830
    if (!windata) {
slouken@13496
   831
        return;
slouken@13496
   832
    }
slouken@13496
   833
slouken@13496
   834
    /* Remove from the internal window list */
slouken@13524
   835
    viddata = windata->viddata;
slouken@13496
   836
slouken@13496
   837
    for (int i = 0; i < viddata->num_windows; i++) {
slouken@13496
   838
        if (viddata->windows[i] == window) {
slouken@13496
   839
            viddata->num_windows--;
slouken@13496
   840
slouken@13496
   841
            for (int j = i; j < viddata->num_windows; j++) {
slouken@13496
   842
                viddata->windows[j] = viddata->windows[j + 1];
slouken@13496
   843
            }
slouken@13496
   844
slouken@13496
   845
            break;
brandon@11181
   846
        }
slouken@11175
   847
    }
slouken@13496
   848
slouken@13496
   849
    KMSDRM_DestroySurfaces(_this, window);
slouken@13496
   850
slouken@13496
   851
    window->driverdata = NULL;
slouken@13496
   852
slouken@13496
   853
    SDL_free(windata);
slouken@11175
   854
}
slouken@11175
   855
slouken@11175
   856
int
slouken@11175
   857
KMSDRM_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
slouken@11175
   858
{
slouken@11175
   859
    return -1;
slouken@11175
   860
}
slouken@11175
   861
slouken@11175
   862
void
slouken@11175
   863
KMSDRM_SetWindowTitle(_THIS, SDL_Window * window)
slouken@11175
   864
{
slouken@11175
   865
}
slouken@11175
   866
void
slouken@11175
   867
KMSDRM_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
slouken@11175
   868
{
slouken@11175
   869
}
slouken@11175
   870
void
slouken@11175
   871
KMSDRM_SetWindowPosition(_THIS, SDL_Window * window)
slouken@11175
   872
{
slouken@11175
   873
}
slouken@11175
   874
void
slouken@11175
   875
KMSDRM_SetWindowSize(_THIS, SDL_Window * window)
slouken@11175
   876
{
slouken@11175
   877
}
slouken@11175
   878
void
slouken@11175
   879
KMSDRM_ShowWindow(_THIS, SDL_Window * window)
slouken@11175
   880
{
slouken@11175
   881
}
slouken@11175
   882
void
slouken@11175
   883
KMSDRM_HideWindow(_THIS, SDL_Window * window)
slouken@11175
   884
{
slouken@11175
   885
}
slouken@11175
   886
void
slouken@11175
   887
KMSDRM_RaiseWindow(_THIS, SDL_Window * window)
slouken@11175
   888
{
slouken@11175
   889
}
slouken@11175
   890
void
slouken@11175
   891
KMSDRM_MaximizeWindow(_THIS, SDL_Window * window)
slouken@11175
   892
{
slouken@11175
   893
}
slouken@11175
   894
void
slouken@11175
   895
KMSDRM_MinimizeWindow(_THIS, SDL_Window * window)
slouken@11175
   896
{
slouken@11175
   897
}
slouken@11175
   898
void
slouken@11175
   899
KMSDRM_RestoreWindow(_THIS, SDL_Window * window)
slouken@11175
   900
{
slouken@11175
   901
}
slouken@11175
   902
void
slouken@11175
   903
KMSDRM_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
slouken@11175
   904
{
slouken@11175
   905
slouken@11175
   906
}
slouken@11175
   907
slouken@11175
   908
/*****************************************************************************/
slouken@11175
   909
/* SDL Window Manager function                                               */
slouken@11175
   910
/*****************************************************************************/
slouken@11175
   911
SDL_bool
slouken@11175
   912
KMSDRM_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
slouken@11175
   913
{
slouken@11175
   914
    if (info->version.major <= SDL_MAJOR_VERSION) {
slouken@11175
   915
        return SDL_TRUE;
slouken@11175
   916
    } else {
slouken@11175
   917
        SDL_SetError("application not compiled with SDL %d.%d\n",
slouken@11175
   918
                     SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
slouken@11175
   919
        return SDL_FALSE;
slouken@11175
   920
    }
slouken@11175
   921
slouken@11175
   922
    /* Failed to get window manager information */
slouken@11175
   923
    return SDL_FALSE;
slouken@11175
   924
}
slouken@11175
   925
slouken@11175
   926
#endif /* SDL_VIDEO_DRIVER_KMSDRM */
slouken@11175
   927
slouken@11175
   928
/* vi: set ts=4 sw=4 expandtab: */