src/video/mir/SDL_mirwindow.c
author bschaefer
Sun, 21 Feb 2016 15:19:35 -0800
changeset 10089 25fda20d0173
parent 9998 f67cf37e9cd4
child 10095 0897c3accd52
permissions -rw-r--r--
Fix API/ABI breakage in Mir 0.13/0.14.
     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 /*
    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 int
    50 MIR_CreateWindow(_THIS, SDL_Window* window)
    51 {
    52     MIR_Window* mir_window;
    53     MIR_Data* mir_data;
    54     MirPixelFormat pixel_format;
    55     MirBufferUsage buffer_usage;
    56 
    57     MirSurfaceSpec* spec;
    58 
    59     mir_window = SDL_calloc(1, sizeof(MIR_Window));
    60     if (!mir_window)
    61         return SDL_OutOfMemory();
    62 
    63     mir_data = _this->driverdata;
    64     window->driverdata = mir_window;
    65 
    66     if (window->x == SDL_WINDOWPOS_UNDEFINED)
    67         window->x = 0;
    68 
    69     if (window->y == SDL_WINDOWPOS_UNDEFINED)
    70         window->y = 0;
    71 
    72     mir_window->mir_data = mir_data;
    73     mir_window->sdl_window = window;
    74 
    75     pixel_format = MIR_mir_connection_get_egl_pixel_format(mir_data->connection,
    76                                                            _this->egl_data->egl_display,
    77                                                            _this->egl_data->egl_config);
    78 
    79     mir_data->pixel_format = pixel_format;
    80     if (pixel_format == mir_pixel_format_invalid) {
    81         return SDL_SetError("Failed to find a valid pixel format.");
    82     }
    83 
    84     buffer_usage = mir_buffer_usage_hardware;
    85     if (mir_data->software)
    86         buffer_usage = mir_buffer_usage_software;
    87 
    88     spec = MIR_mir_connection_create_spec_for_normal_surface(mir_data->connection,
    89                                                              window->w,
    90                                                              window->h,
    91                                                              pixel_format);
    92 
    93     MIR_mir_surface_spec_set_buffer_usage(spec, buffer_usage);
    94     MIR_mir_surface_spec_set_name(spec, "Mir surface");
    95 
    96     mir_window->surface = MIR_mir_surface_create_sync(spec);
    97     MIR_mir_surface_set_event_handler(mir_window->surface, MIR_HandleEvent, window);
    98 
    99     MIR_mir_surface_spec_release(spec);
   100 
   101     if (!MIR_mir_surface_is_valid(mir_window->surface)) {
   102         const char* error = MIR_mir_surface_get_error_message(mir_window->surface);
   103         return SDL_SetError("Failed to created a mir surface: %s", error);
   104     }
   105 
   106     if (window->flags & SDL_WINDOW_OPENGL) {
   107         EGLNativeWindowType egl_native_window =
   108                         (EGLNativeWindowType)MIR_mir_buffer_stream_get_egl_native_window(
   109                                                        MIR_mir_surface_get_buffer_stream(mir_window->surface));
   110 
   111         mir_window->egl_surface = SDL_EGL_CreateSurface(_this, egl_native_window);
   112 
   113         if (mir_window->egl_surface == EGL_NO_SURFACE) {
   114             return SDL_SetError("Failed to created a window surface %p",
   115                                 _this->egl_data->egl_display);
   116         }
   117     }
   118     else {
   119         mir_window->egl_surface = EGL_NO_SURFACE;
   120     }
   121 
   122     mir_data->current_window = mir_window;
   123 
   124     return 0;
   125 }
   126 
   127 void
   128 MIR_DestroyWindow(_THIS, SDL_Window* window)
   129 {
   130     MIR_Data* mir_data     = _this->driverdata;
   131     MIR_Window* mir_window = window->driverdata;
   132 
   133     if (mir_data) {
   134         SDL_EGL_DestroySurface(_this, mir_window->egl_surface);
   135         MIR_mir_surface_release_sync(mir_window->surface);
   136 
   137         mir_data->current_window = NULL;
   138 
   139         SDL_free(mir_window);
   140     }
   141     window->driverdata = NULL;
   142 }
   143 
   144 SDL_bool
   145 MIR_GetWindowWMInfo(_THIS, SDL_Window* window, SDL_SysWMinfo* info)
   146 {
   147     if (info->version.major == SDL_MAJOR_VERSION &&
   148         info->version.minor == SDL_MINOR_VERSION) {
   149         MIR_Window* mir_window = window->driverdata;
   150 
   151         info->subsystem = SDL_SYSWM_MIR;
   152         info->info.mir.connection = mir_window->mir_data->connection;
   153         info->info.mir.surface = mir_window->surface;
   154 
   155         return SDL_TRUE;
   156     }
   157 
   158     return SDL_FALSE;
   159 }
   160 
   161 void
   162 MIR_SetWindowFullscreen(_THIS, SDL_Window* window,
   163                         SDL_VideoDisplay* display,
   164                         SDL_bool fullscreen)
   165 {
   166     MIR_Data*   mir_data   = _this->driverdata;
   167     MIR_Window* mir_window = window->driverdata;
   168     MirSurfaceSpec* spec;
   169     MirSurfaceState state;
   170 
   171     if (IsSurfaceValid(mir_window) < 0)
   172         return;
   173 
   174     if (fullscreen) {
   175         state = mir_surface_state_fullscreen;
   176     } else {
   177         state = mir_surface_state_restored;
   178     }
   179 
   180     spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
   181     MIR_mir_surface_spec_set_state(spec, state);
   182 
   183     MIR_mir_surface_apply_spec(mir_window->surface, spec);
   184     MIR_mir_surface_spec_release(spec);
   185 }
   186 
   187 void
   188 MIR_MaximizeWindow(_THIS, SDL_Window* window)
   189 {
   190     MIR_Data*   mir_data   = _this->driverdata;
   191     MIR_Window* mir_window = window->driverdata;
   192     MirSurfaceSpec* spec;
   193 
   194     if (IsSurfaceValid(mir_window) < 0)
   195         return;
   196 
   197     spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
   198     MIR_mir_surface_spec_set_state(spec, mir_surface_state_maximized);
   199 
   200     MIR_mir_surface_apply_spec(mir_window->surface, spec);
   201     MIR_mir_surface_spec_release(spec);
   202 }
   203 
   204 void
   205 MIR_MinimizeWindow(_THIS, SDL_Window* window)
   206 {
   207     MIR_Data*   mir_data   = _this->driverdata;
   208     MIR_Window* mir_window = window->driverdata;
   209     MirSurfaceSpec* spec;
   210 
   211     if (IsSurfaceValid(mir_window) < 0)
   212         return;
   213 
   214     spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
   215     MIR_mir_surface_spec_set_state(spec, mir_surface_state_minimized);
   216 
   217     MIR_mir_surface_apply_spec(mir_window->surface, spec);
   218     MIR_mir_surface_spec_release(spec);
   219 }
   220 
   221 void
   222 MIR_RestoreWindow(_THIS, SDL_Window * window)
   223 {
   224     MIR_Data*   mir_data   = _this->driverdata;
   225     MIR_Window* mir_window = window->driverdata;
   226     MirSurfaceSpec* spec;
   227 
   228     if (IsSurfaceValid(mir_window) < 0)
   229         return;
   230 
   231     spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
   232     MIR_mir_surface_spec_set_state(spec, mir_surface_state_restored);
   233 
   234     MIR_mir_surface_apply_spec(mir_window->surface, spec);
   235     MIR_mir_surface_spec_release(spec);
   236 }
   237 
   238 void
   239 MIR_HideWindow(_THIS, SDL_Window* window)
   240 {
   241     MIR_Data*   mir_data   = _this->driverdata;
   242     MIR_Window* mir_window = window->driverdata;
   243     MirSurfaceSpec* spec;
   244 
   245     if (IsSurfaceValid(mir_window) < 0)
   246         return;
   247 
   248     spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
   249     MIR_mir_surface_spec_set_state(spec, mir_surface_state_hidden);
   250 
   251     MIR_mir_surface_apply_spec(mir_window->surface, spec);
   252     MIR_mir_surface_spec_release(spec);
   253 }
   254 
   255 void
   256 MIR_SetWindowSize(_THIS, SDL_Window* window)
   257 {
   258     MIR_Data*   mir_data   = _this->driverdata;
   259     MIR_Window* mir_window = window->driverdata;
   260     MirSurfaceSpec* spec;
   261 
   262     if (IsSurfaceValid(mir_window) < 0)
   263         return;
   264 
   265     /* You cannot set the x/y of a mir window! So only update w/h */
   266     spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
   267     MIR_mir_surface_spec_set_width (spec, window->w);
   268     MIR_mir_surface_spec_set_height(spec, window->h);
   269 
   270     MIR_mir_surface_apply_spec(mir_window->surface, spec);
   271     MIR_mir_surface_spec_release(spec);
   272 }
   273 
   274 void
   275 MIR_SetWindowMinimumSize(_THIS, SDL_Window* window)
   276 {
   277     MIR_Data*   mir_data   = _this->driverdata;
   278     MIR_Window* mir_window = window->driverdata;
   279     MirSurfaceSpec* spec;
   280 
   281     if (IsSurfaceValid(mir_window) < 0)
   282         return;
   283 
   284     spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
   285     MIR_mir_surface_spec_set_min_width (spec, window->min_w);
   286     MIR_mir_surface_spec_set_min_height(spec, window->min_h);
   287 
   288     MIR_mir_surface_apply_spec(mir_window->surface, spec);
   289     MIR_mir_surface_spec_release(spec);
   290 }
   291 
   292 void
   293 MIR_SetWindowMaximumSize(_THIS, SDL_Window* window)
   294 {
   295     MIR_Data*   mir_data   = _this->driverdata;
   296     MIR_Window* mir_window = window->driverdata;
   297     MirSurfaceSpec* spec;
   298 
   299     if (IsSurfaceValid(mir_window) < 0)
   300         return;
   301 
   302     spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
   303     MIR_mir_surface_spec_set_max_width (spec, window->max_w);
   304     MIR_mir_surface_spec_set_max_height(spec, window->max_h);
   305 
   306     MIR_mir_surface_apply_spec(mir_window->surface, spec);
   307     MIR_mir_surface_spec_release(spec);
   308 }
   309 
   310 void
   311 MIR_SetWindowTitle(_THIS, SDL_Window* window)
   312 {
   313     MIR_Data*   mir_data   = _this->driverdata;
   314     MIR_Window* mir_window = window->driverdata;
   315     char const* title = window->title ? window->title : "";
   316     MirSurfaceSpec* spec;
   317 
   318     if (IsSurfaceValid(mir_window) < 0)
   319         return;
   320 
   321     spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
   322     MIR_mir_surface_spec_set_name(spec, title);
   323 
   324     MIR_mir_surface_apply_spec(mir_window->surface, spec);
   325     MIR_mir_surface_spec_release(spec);
   326 }
   327 
   328 #endif /* SDL_VIDEO_DRIVER_MIR */
   329 
   330 /* vi: set ts=4 sw=4 expandtab: */