src/video/mir/SDL_mirwindow.c
author Ryan C. Gordon <icculus@icculus.org>
Mon, 03 Feb 2014 11:52:54 -0500
changeset 8159 427e8fdf6f69
parent 8157 f5d262613ed2
child 8749 f34996d809b7
permissions -rw-r--r--
Hooked up dynamic loading for Mir.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2014 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 /*
    23   Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
    24 */
    25 
    26 #include "../../SDL_internal.h"
    27 
    28 #if SDL_VIDEO_DRIVER_MIR
    29 
    30 #include "../SDL_egl_c.h"
    31 #include "../SDL_sysvideo.h"
    32 
    33 #include "SDL_mirevents.h"
    34 #include "SDL_mirwindow.h"
    35 
    36 #include "SDL_mirdyn.h"
    37 
    38 int
    39 IsSurfaceValid(MIR_Window* mir_window)
    40 {
    41     if (!MIR_mir_surface_is_valid(mir_window->surface)) {
    42         const char* error = MIR_mir_surface_get_error_message(mir_window->surface);
    43         return SDL_SetError("Failed to created a mir surface: %s", error);
    44     }
    45 
    46     return 0;
    47 }
    48 
    49 MirPixelFormat
    50 FindValidPixelFormat(MIR_Data* mir_data)
    51 {
    52     unsigned int pf_size = 32;
    53     unsigned int valid_formats;
    54     unsigned int f;
    55 
    56     MirPixelFormat formats[pf_size];
    57     MIR_mir_connection_get_available_surface_formats(mir_data->connection, formats,
    58                                                  pf_size, &valid_formats);
    59 
    60     for (f = 0; f < valid_formats; f++) {
    61         MirPixelFormat cur_pf = formats[f];
    62 
    63         if (cur_pf == mir_pixel_format_abgr_8888 ||
    64             cur_pf == mir_pixel_format_xbgr_8888 ||
    65             cur_pf == mir_pixel_format_argb_8888 ||
    66             cur_pf == mir_pixel_format_xrgb_8888) {
    67 
    68             return cur_pf;
    69         }
    70     }
    71 
    72     return mir_pixel_format_invalid;
    73 }
    74 
    75 int
    76 MIR_CreateWindow(_THIS, SDL_Window* window)
    77 {
    78     MIR_Window* mir_window;
    79     MIR_Data* mir_data;
    80 
    81     MirSurfaceParameters surfaceparm =
    82     {
    83         .name = "MirSurface",
    84         .width = window->w,
    85         .height = window->h,
    86         .pixel_format = mir_pixel_format_invalid,
    87         .buffer_usage = mir_buffer_usage_hardware
    88     };
    89 
    90     MirEventDelegate delegate = {
    91         MIR_HandleInput,
    92         window
    93     };
    94 
    95     mir_window = SDL_calloc(1, sizeof(MIR_Window));
    96     if (!mir_window)
    97         return SDL_OutOfMemory();
    98 
    99     mir_data = _this->driverdata;
   100     window->driverdata = mir_window;
   101 
   102     if (window->x == SDL_WINDOWPOS_UNDEFINED)
   103         window->x = 0;
   104 
   105     if (window->y == SDL_WINDOWPOS_UNDEFINED)
   106         window->y = 0;
   107 
   108     mir_window->mir_data = mir_data;
   109     mir_window->sdl_window = window;
   110 
   111     surfaceparm.pixel_format = FindValidPixelFormat(mir_data);
   112     if (surfaceparm.pixel_format == mir_pixel_format_invalid) {
   113         return SDL_SetError("Failed to find a valid pixel format.");
   114     }
   115 
   116     mir_window->surface = MIR_mir_connection_create_surface_sync(mir_data->connection, &surfaceparm);
   117     if (!MIR_mir_surface_is_valid(mir_window->surface)) {
   118         const char* error = MIR_mir_surface_get_error_message(mir_window->surface);
   119         return SDL_SetError("Failed to created a mir surface: %s", error);
   120     }
   121 
   122     if (window->flags & SDL_WINDOW_OPENGL) {
   123         EGLNativeWindowType egl_native_window =
   124                         (EGLNativeWindowType)MIR_mir_surface_get_egl_native_window(mir_window->surface);
   125 
   126         mir_window->egl_surface = SDL_EGL_CreateSurface(_this, egl_native_window);
   127 
   128         if (mir_window->egl_surface == EGL_NO_SURFACE) {
   129             return SDL_SetError("Failed to created a window surface %p",
   130                                 _this->egl_data->egl_display);
   131         }
   132     }
   133     else {
   134         mir_window->egl_surface = EGL_NO_SURFACE;
   135     }
   136 
   137     MIR_mir_surface_set_event_handler(mir_window->surface, &delegate);
   138 
   139     return 0;
   140 }
   141 
   142 void
   143 MIR_DestroyWindow(_THIS, SDL_Window* window)
   144 {
   145     MIR_Data* mir_data = _this->driverdata;
   146     MIR_Window* mir_window = window->driverdata;
   147 
   148     window->driverdata = NULL;
   149 
   150     if (mir_data) {
   151         SDL_EGL_DestroySurface(_this, mir_window->egl_surface);
   152         MIR_mir_surface_release_sync(mir_window->surface);
   153 
   154         SDL_free(mir_window);
   155     }
   156 }
   157 
   158 SDL_bool
   159 MIR_GetWindowWMInfo(_THIS, SDL_Window* window, SDL_SysWMinfo* info)
   160 {
   161     if (info->version.major == SDL_MAJOR_VERSION &&
   162         info->version.minor == SDL_MINOR_VERSION) {
   163         MIR_Window* mir_window = window->driverdata;
   164 
   165         info->subsystem = SDL_SYSWM_MIR;
   166         info->info.mir.connection = mir_window->mir_data->connection;
   167         info->info.mir.surface = mir_window->surface;
   168 
   169         return SDL_TRUE;
   170     }
   171 
   172     return SDL_FALSE;
   173 }
   174 
   175 void
   176 MIR_SetWindowFullscreen(_THIS, SDL_Window* window,
   177                         SDL_VideoDisplay* display,
   178                         SDL_bool fullscreen)
   179 {
   180     MIR_Window* mir_window = window->driverdata;
   181 
   182     if (IsSurfaceValid(mir_window) < 0)
   183         return;
   184 
   185     if (fullscreen) {
   186         MIR_mir_surface_set_type(mir_window->surface, mir_surface_state_fullscreen);
   187     } else {
   188         MIR_mir_surface_set_type(mir_window->surface, mir_surface_state_restored);
   189     }
   190 }
   191 
   192 void
   193 MIR_MaximizeWindow(_THIS, SDL_Window* window)
   194 {
   195     MIR_Window* mir_window = window->driverdata;
   196 
   197     if (IsSurfaceValid(mir_window) < 0)
   198         return;
   199 
   200     MIR_mir_surface_set_type(mir_window->surface, mir_surface_state_maximized);
   201 }
   202 
   203 void
   204 MIR_MinimizeWindow(_THIS, SDL_Window* window)
   205 {
   206     MIR_Window* mir_window = window->driverdata;
   207 
   208     if (IsSurfaceValid(mir_window) < 0)
   209         return;
   210 
   211     MIR_mir_surface_set_type(mir_window->surface, mir_surface_state_minimized);
   212 }
   213 
   214 void
   215 MIR_RestoreWindow(_THIS, SDL_Window * window)
   216 {
   217     MIR_Window* mir_window = window->driverdata;
   218 
   219     if (IsSurfaceValid(mir_window) < 0)
   220         return;
   221 
   222     MIR_mir_surface_set_type(mir_window->surface, mir_surface_state_restored);
   223 }
   224 
   225 #endif /* SDL_VIDEO_DRIVER_MIR */
   226 
   227 /* vi: set ts=4 sw=4 expandtab: */