src/video/mir/SDL_mirwindow.c
author Philipp Wiesemann
Sun, 02 Apr 2017 21:33:42 +0200
changeset 10959 97e629557346
parent 10940 10118eaebdfd
child 10971 94f32f14e377
permissions -rw-r--r--
Mir: Changed two internal functions to be static.
icculus@8153
     1
/*
icculus@8153
     2
  Simple DirectMedia Layer
slouken@10737
     3
  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
icculus@8153
     4
icculus@8153
     5
  This software is provided 'as-is', without any express or implied
icculus@8153
     6
  warranty.  In no event will the authors be held liable for any damages
icculus@8153
     7
  arising from the use of this software.
icculus@8153
     8
icculus@8153
     9
  Permission is granted to anyone to use this software for any purpose,
icculus@8153
    10
  including commercial applications, and to alter it and redistribute it
icculus@8153
    11
  freely, subject to the following restrictions:
icculus@8153
    12
icculus@8153
    13
  1. The origin of this software must not be misrepresented; you must not
icculus@8153
    14
     claim that you wrote the original software. If you use this software
icculus@8153
    15
     in a product, an acknowledgment in the product documentation would be
icculus@8153
    16
     appreciated but is not required.
icculus@8153
    17
  2. Altered source versions must be plainly marked as such, and must not be
icculus@8153
    18
     misrepresented as being the original software.
icculus@8153
    19
  3. This notice may not be removed or altered from any source distribution.
icculus@8153
    20
*/
icculus@8153
    21
icculus@8153
    22
/*
icculus@8153
    23
  Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
icculus@8153
    24
*/
icculus@8153
    25
icculus@8154
    26
#include "../../SDL_internal.h"
icculus@8154
    27
icculus@8154
    28
#if SDL_VIDEO_DRIVER_MIR
icculus@8153
    29
icculus@8153
    30
#include "../SDL_egl_c.h"
icculus@8153
    31
#include "../SDL_sysvideo.h"
brandon@10299
    32
#include "../../events/SDL_keyboard_c.h"
icculus@8153
    33
icculus@8153
    34
#include "SDL_mirevents.h"
icculus@8153
    35
#include "SDL_mirwindow.h"
icculus@8153
    36
icculus@8159
    37
#include "SDL_mirdyn.h"
icculus@8159
    38
philipp@10959
    39
static int
brandon@10923
    40
IsMirWindowValid(MIR_Window* mir_window)
icculus@8153
    41
{
brandon@10921
    42
    if (!MIR_mir_window_is_valid(mir_window->window)) {
brandon@10921
    43
        const char* error = MIR_mir_window_get_error_message(mir_window->window);
icculus@8153
    44
        return SDL_SetError("Failed to created a mir surface: %s", error);
icculus@8153
    45
    }
icculus@8153
    46
brandon@10923
    47
    return 1;
icculus@8153
    48
}
icculus@8153
    49
philipp@10959
    50
static MirPixelFormat
brandon@10095
    51
FindValidPixelFormat(MIR_Data* mir_data)
brandon@10095
    52
{
brandon@10095
    53
    unsigned int pf_size = 32;
brandon@10095
    54
    unsigned int valid_formats;
brandon@10095
    55
    unsigned int f;
brandon@10095
    56
brandon@10095
    57
    MirPixelFormat formats[pf_size];
brandon@10095
    58
    MIR_mir_connection_get_available_surface_formats(mir_data->connection, formats,
brandon@10095
    59
                                                     pf_size, &valid_formats);
brandon@10095
    60
brandon@10095
    61
    for (f = 0; f < valid_formats; f++) {
brandon@10095
    62
        MirPixelFormat cur_pf = formats[f];
brandon@10095
    63
brandon@10095
    64
        if (cur_pf == mir_pixel_format_abgr_8888 ||
brandon@10095
    65
            cur_pf == mir_pixel_format_xbgr_8888 ||
brandon@10095
    66
            cur_pf == mir_pixel_format_argb_8888 ||
brandon@10095
    67
            cur_pf == mir_pixel_format_xrgb_8888) {
brandon@10095
    68
brandon@10095
    69
            return cur_pf;
brandon@10095
    70
        }
brandon@10095
    71
    }
brandon@10095
    72
brandon@10095
    73
    return mir_pixel_format_invalid;
brandon@10095
    74
}
brandon@10095
    75
icculus@8153
    76
int
icculus@8153
    77
MIR_CreateWindow(_THIS, SDL_Window* window)
icculus@8153
    78
{
icculus@8153
    79
    MIR_Window* mir_window;
icculus@8153
    80
    MIR_Data* mir_data;
bschaefer@10089
    81
    MirPixelFormat pixel_format;
bschaefer@10089
    82
    MirBufferUsage buffer_usage;
icculus@8153
    83
brandon@10921
    84
    MirWindowSpec* spec;
icculus@8153
    85
icculus@8153
    86
    mir_window = SDL_calloc(1, sizeof(MIR_Window));
icculus@8153
    87
    if (!mir_window)
icculus@8153
    88
        return SDL_OutOfMemory();
icculus@8153
    89
icculus@8153
    90
    mir_data = _this->driverdata;
icculus@8153
    91
    window->driverdata = mir_window;
icculus@8153
    92
icculus@8153
    93
    if (window->x == SDL_WINDOWPOS_UNDEFINED)
icculus@8153
    94
        window->x = 0;
icculus@8153
    95
icculus@8153
    96
    if (window->y == SDL_WINDOWPOS_UNDEFINED)
icculus@8153
    97
        window->y = 0;
icculus@8153
    98
icculus@8153
    99
    mir_window->mir_data = mir_data;
icculus@8153
   100
    mir_window->sdl_window = window;
icculus@8153
   101
brandon@10095
   102
    if (window->flags & SDL_WINDOW_OPENGL) {
brandon@10095
   103
        pixel_format = MIR_mir_connection_get_egl_pixel_format(mir_data->connection,
brandon@10095
   104
                                                               _this->egl_data->egl_display,
brandon@10095
   105
                                                               _this->egl_data->egl_config);
brandon@10095
   106
    }
brandon@10095
   107
    else {
brandon@10095
   108
        pixel_format = FindValidPixelFormat(mir_data);
brandon@10095
   109
    }
bschaefer@10089
   110
bschaefer@10089
   111
    mir_data->pixel_format = pixel_format;
bschaefer@10089
   112
    if (pixel_format == mir_pixel_format_invalid) {
icculus@8153
   113
        return SDL_SetError("Failed to find a valid pixel format.");
icculus@8153
   114
    }
icculus@8153
   115
bschaefer@10089
   116
    buffer_usage = mir_buffer_usage_hardware;
bschaefer@10089
   117
    if (mir_data->software)
bschaefer@10089
   118
        buffer_usage = mir_buffer_usage_software;
bschaefer@10089
   119
brandon@10921
   120
    spec = MIR_mir_create_normal_window_spec(mir_data->connection,
brandon@10921
   121
                                             window->w,
brandon@10921
   122
                                             window->h);
bschaefer@10089
   123
brandon@10921
   124
    MIR_mir_window_spec_set_buffer_usage(spec, buffer_usage);
brandon@10921
   125
    MIR_mir_window_spec_set_name(spec, "Mir surface");
brandon@10921
   126
    MIR_mir_window_spec_set_pixel_format(spec, pixel_format);
bschaefer@10089
   127
brandon@10299
   128
    if (window->flags & SDL_WINDOW_INPUT_FOCUS)
brandon@10299
   129
        SDL_SetKeyboardFocus(window);
brandon@10299
   130
brandon@10921
   131
    mir_window->window = MIR_mir_create_window_sync(spec);
brandon@10921
   132
    MIR_mir_window_set_event_handler(mir_window->window, MIR_HandleEvent, window);
bschaefer@10089
   133
brandon@10921
   134
    MIR_mir_window_spec_release(spec);
bschaefer@10089
   135
brandon@10921
   136
    if (!MIR_mir_window_is_valid(mir_window->window)) {
brandon@10181
   137
        return SDL_SetError("Failed to created a mir surface: %s",
brandon@10921
   138
            MIR_mir_window_get_error_message(mir_window->window));
icculus@8153
   139
    }
icculus@8153
   140
icculus@8153
   141
    if (window->flags & SDL_WINDOW_OPENGL) {
icculus@8153
   142
        EGLNativeWindowType egl_native_window =
bschaefer@10089
   143
                        (EGLNativeWindowType)MIR_mir_buffer_stream_get_egl_native_window(
brandon@10921
   144
                                                       MIR_mir_window_get_buffer_stream(mir_window->window));
icculus@8153
   145
icculus@8153
   146
        mir_window->egl_surface = SDL_EGL_CreateSurface(_this, egl_native_window);
icculus@8153
   147
icculus@8153
   148
        if (mir_window->egl_surface == EGL_NO_SURFACE) {
icculus@8153
   149
            return SDL_SetError("Failed to created a window surface %p",
icculus@8153
   150
                                _this->egl_data->egl_display);
icculus@8153
   151
        }
icculus@8153
   152
    }
icculus@8153
   153
    else {
icculus@8153
   154
        mir_window->egl_surface = EGL_NO_SURFACE;
icculus@8153
   155
    }
icculus@8153
   156
bschaefer@10089
   157
    mir_data->current_window = mir_window;
icculus@8153
   158
icculus@8153
   159
    return 0;
icculus@8153
   160
}
icculus@8153
   161
icculus@8153
   162
void
icculus@8153
   163
MIR_DestroyWindow(_THIS, SDL_Window* window)
icculus@8153
   164
{
bschaefer@10089
   165
    MIR_Data* mir_data     = _this->driverdata;
icculus@8153
   166
    MIR_Window* mir_window = window->driverdata;
icculus@8153
   167
icculus@8153
   168
    if (mir_data) {
icculus@8153
   169
        SDL_EGL_DestroySurface(_this, mir_window->egl_surface);
brandon@10921
   170
        MIR_mir_window_release_sync(mir_window->window);
icculus@8153
   171
bschaefer@10089
   172
        mir_data->current_window = NULL;
bschaefer@10089
   173
icculus@8153
   174
        SDL_free(mir_window);
icculus@8153
   175
    }
slouken@8978
   176
    window->driverdata = NULL;
icculus@8153
   177
}
icculus@8153
   178
icculus@8153
   179
SDL_bool
icculus@8153
   180
MIR_GetWindowWMInfo(_THIS, SDL_Window* window, SDL_SysWMinfo* info)
icculus@8153
   181
{
icculus@8153
   182
    if (info->version.major == SDL_MAJOR_VERSION &&
icculus@8153
   183
        info->version.minor == SDL_MINOR_VERSION) {
icculus@8155
   184
        MIR_Window* mir_window = window->driverdata;
icculus@8153
   185
icculus@8153
   186
        info->subsystem = SDL_SYSWM_MIR;
icculus@8155
   187
        info->info.mir.connection = mir_window->mir_data->connection;
brandon@10921
   188
        // Cannot change this to window due to it being in the public API
brandon@10921
   189
        info->info.mir.surface = mir_window->window;
icculus@8155
   190
icculus@8153
   191
        return SDL_TRUE;
icculus@8153
   192
    }
icculus@8153
   193
icculus@8153
   194
    return SDL_FALSE;
icculus@8153
   195
}
icculus@8153
   196
brandon@10923
   197
static void
brandon@10923
   198
UpdateMirWindowState(MIR_Data* mir_data, MIR_Window* mir_window, MirWindowState window_state)
brandon@10923
   199
{
brandon@10923
   200
    if (IsMirWindowValid(mir_window)) {
brandon@10923
   201
        MirWindowSpec* spec = MIR_mir_create_window_spec(mir_data->connection);
brandon@10923
   202
        MIR_mir_window_spec_set_state(spec, window_state);
brandon@10923
   203
brandon@10923
   204
        MIR_mir_window_apply_spec(mir_window->window, spec);
brandon@10923
   205
        MIR_mir_window_spec_release(spec);
brandon@10923
   206
    }
brandon@10923
   207
}
brandon@10923
   208
icculus@8153
   209
void
icculus@8153
   210
MIR_SetWindowFullscreen(_THIS, SDL_Window* window,
icculus@8153
   211
                        SDL_VideoDisplay* display,
icculus@8153
   212
                        SDL_bool fullscreen)
icculus@8153
   213
{
brandon@10923
   214
    if (IsMirWindowValid(window->driverdata)) {
brandon@10923
   215
        MirWindowState state;
icculus@8153
   216
brandon@10923
   217
        if (fullscreen) {
brandon@10923
   218
            state = mir_window_state_fullscreen;
brandon@10923
   219
        }
brandon@10923
   220
        else {
brandon@10923
   221
            state = mir_window_state_restored;
brandon@10923
   222
        }
bschaefer@10089
   223
brandon@10923
   224
        UpdateMirWindowState(_this->driverdata, window->driverdata, state);
brandon@10923
   225
    }
icculus@8153
   226
}
icculus@8153
   227
icculus@8153
   228
void
icculus@8153
   229
MIR_MaximizeWindow(_THIS, SDL_Window* window)
icculus@8153
   230
{
brandon@10923
   231
    UpdateMirWindowState(_this->driverdata, window->driverdata, mir_window_state_maximized);
icculus@8153
   232
}
icculus@8153
   233
icculus@8153
   234
void
icculus@8153
   235
MIR_MinimizeWindow(_THIS, SDL_Window* window)
icculus@8153
   236
{
brandon@10923
   237
    UpdateMirWindowState(_this->driverdata, window->driverdata, mir_window_state_minimized);
icculus@8153
   238
}
icculus@8153
   239
icculus@8153
   240
void
icculus@8153
   241
MIR_RestoreWindow(_THIS, SDL_Window * window)
icculus@8153
   242
{
brandon@10923
   243
    UpdateMirWindowState(_this->driverdata, window->driverdata, mir_window_state_restored);
bschaefer@10089
   244
}
bschaefer@10089
   245
bschaefer@10089
   246
void
bschaefer@10089
   247
MIR_HideWindow(_THIS, SDL_Window* window)
bschaefer@10089
   248
{
brandon@10923
   249
    UpdateMirWindowState(_this->driverdata, window->driverdata, mir_window_state_hidden);
brandon@10923
   250
}
bschaefer@10089
   251
bschaefer@10089
   252
void
bschaefer@10089
   253
MIR_SetWindowSize(_THIS, SDL_Window* window)
bschaefer@10089
   254
{
brandon@10940
   255
    MIR_Data* mir_data     = _this->driverdata;
brandon@10940
   256
    MIR_Window* mir_window = window->driverdata;
brandon@10940
   257
brandon@10940
   258
    if (IsMirWindowValid(mir_window)) {
brandon@10940
   259
        MirWindowSpec* spec = MIR_mir_create_window_spec(mir_data->connection);
brandon@10940
   260
        MIR_mir_window_spec_set_width (spec, window->w);
brandon@10940
   261
        MIR_mir_window_spec_set_height(spec, window->h);
brandon@10940
   262
brandon@10940
   263
        MIR_mir_window_apply_spec(mir_window->window, spec);
brandon@10940
   264
    }
bschaefer@10089
   265
}
bschaefer@10089
   266
bschaefer@10089
   267
void
bschaefer@10089
   268
MIR_SetWindowMinimumSize(_THIS, SDL_Window* window)
bschaefer@10089
   269
{
brandon@10940
   270
    MIR_Data* mir_data     = _this->driverdata;
brandon@10940
   271
    MIR_Window* mir_window = window->driverdata;
brandon@10940
   272
brandon@10940
   273
    if (IsMirWindowValid(mir_window)) {
brandon@10940
   274
        MirWindowSpec* spec = MIR_mir_create_window_spec(mir_data->connection);
brandon@10940
   275
        MIR_mir_window_spec_set_min_width (spec, window->min_w);
brandon@10940
   276
        MIR_mir_window_spec_set_min_height(spec, window->min_h);
brandon@10940
   277
brandon@10940
   278
        MIR_mir_window_apply_spec(mir_window->window, spec);
brandon@10940
   279
    }
bschaefer@10089
   280
}
bschaefer@10089
   281
bschaefer@10089
   282
void
bschaefer@10089
   283
MIR_SetWindowMaximumSize(_THIS, SDL_Window* window)
bschaefer@10089
   284
{
brandon@10940
   285
    MIR_Data* mir_data     = _this->driverdata;
brandon@10940
   286
    MIR_Window* mir_window = window->driverdata;
brandon@10940
   287
brandon@10940
   288
    if (IsMirWindowValid(mir_window)) {
brandon@10940
   289
        MirWindowSpec* spec = MIR_mir_create_window_spec(mir_data->connection);
brandon@10940
   290
        MIR_mir_window_spec_set_max_width (spec, window->max_w);
brandon@10940
   291
        MIR_mir_window_spec_set_max_height(spec, window->max_h);
brandon@10940
   292
brandon@10940
   293
        MIR_mir_window_apply_spec(mir_window->window, spec);
brandon@10940
   294
    }
bschaefer@10089
   295
}
bschaefer@10089
   296
bschaefer@10089
   297
void
bschaefer@10089
   298
MIR_SetWindowTitle(_THIS, SDL_Window* window)
bschaefer@10089
   299
{
bschaefer@10089
   300
    MIR_Data*   mir_data   = _this->driverdata;
bschaefer@10089
   301
    MIR_Window* mir_window = window->driverdata;
bschaefer@10089
   302
    char const* title = window->title ? window->title : "";
brandon@10921
   303
    MirWindowSpec* spec;
bschaefer@10089
   304
brandon@10923
   305
    if (IsMirWindowValid(mir_window) < 0)
bschaefer@10089
   306
        return;
bschaefer@10089
   307
brandon@10921
   308
    spec = MIR_mir_create_window_spec(mir_data->connection);
brandon@10921
   309
    MIR_mir_window_spec_set_name(spec, title);
bschaefer@10089
   310
brandon@10921
   311
    MIR_mir_window_apply_spec(mir_window->window, spec);
brandon@10921
   312
    MIR_mir_window_spec_release(spec);
icculus@8153
   313
}
icculus@8154
   314
brandon@10299
   315
void
brandon@10299
   316
MIR_SetWindowGrab(_THIS, SDL_Window* window, SDL_bool grabbed)
brandon@10299
   317
{
brandon@10299
   318
    MIR_Data*   mir_data   = _this->driverdata;
brandon@10299
   319
    MIR_Window* mir_window = window->driverdata;
brandon@10299
   320
    MirPointerConfinementState confined = mir_pointer_unconfined;
brandon@10921
   321
    MirWindowSpec* spec;
brandon@10299
   322
brandon@10299
   323
    if (grabbed)
brandon@10921
   324
        confined = mir_pointer_confined_to_window;
brandon@10299
   325
brandon@10921
   326
    spec = MIR_mir_create_window_spec(mir_data->connection);
brandon@10921
   327
    MIR_mir_window_spec_set_pointer_confinement(spec, confined);
brandon@10299
   328
brandon@10921
   329
    MIR_mir_window_apply_spec(mir_window->window, spec);
brandon@10921
   330
    MIR_mir_window_spec_release(spec);
brandon@10364
   331
}
brandon@10299
   332
brandon@10364
   333
int
brandon@10364
   334
MIR_SetWindowGammaRamp(_THIS, SDL_Window* window, Uint16 const* ramp)
brandon@10364
   335
{
brandon@10364
   336
    MirOutput* output = SDL_GetDisplayForWindow(window)->driverdata;
brandon@10364
   337
    Uint32 ramp_size = 256;
brandon@10364
   338
brandon@10364
   339
    // FIXME Need to apply the changes to the output, once that public API function is around
brandon@10364
   340
    if (MIR_mir_output_is_gamma_supported(output) == mir_output_gamma_supported) {
brandon@10364
   341
        MIR_mir_output_set_gamma(output,
brandon@10364
   342
                                 ramp + ramp_size * 0,
brandon@10364
   343
                                 ramp + ramp_size * 1,
brandon@10364
   344
                                 ramp + ramp_size * 2,
brandon@10364
   345
                                 ramp_size);
brandon@10364
   346
        return 0;
brandon@10364
   347
    }
brandon@10364
   348
brandon@10364
   349
    return -1;
brandon@10364
   350
}
brandon@10364
   351
brandon@10364
   352
int
brandon@10364
   353
MIR_GetWindowGammaRamp(_THIS, SDL_Window* window, Uint16* ramp)
brandon@10364
   354
{
brandon@10364
   355
    MirOutput* output = SDL_GetDisplayForWindow(window)->driverdata;
brandon@10364
   356
    Uint32 ramp_size = 256;
brandon@10364
   357
brandon@10364
   358
    if (MIR_mir_output_is_gamma_supported(output) == mir_output_gamma_supported) {
brandon@10364
   359
        if (MIR_mir_output_get_gamma_size(output) == ramp_size) {
brandon@10364
   360
            MIR_mir_output_get_gamma(output,
brandon@10364
   361
                                     ramp + ramp_size * 0,
brandon@10364
   362
                                     ramp + ramp_size * 1,
brandon@10364
   363
                                     ramp + ramp_size * 2,
brandon@10364
   364
                                     ramp_size);
brandon@10364
   365
            return 0;
brandon@10364
   366
        }
brandon@10364
   367
    }
brandon@10364
   368
brandon@10364
   369
    return -1;
brandon@10299
   370
}
brandon@10299
   371
icculus@8154
   372
#endif /* SDL_VIDEO_DRIVER_MIR */
icculus@8154
   373
icculus@8154
   374
/* vi: set ts=4 sw=4 expandtab: */