src/video/mir/SDL_mirvideo.c
author bschaefer
Sun, 21 Feb 2016 15:19:35 -0800
changeset 10089 25fda20d0173
parent 9998 f67cf37e9cd4
child 10181 b82c0f22d22a
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_mirwindow.h"
    31 #include "SDL_video.h"
    32 
    33 #include "SDL_mirframebuffer.h"
    34 #include "SDL_mirmouse.h"
    35 #include "SDL_miropengl.h"
    36 #include "SDL_mirvideo.h"
    37 
    38 #include "SDL_mirdyn.h"
    39 
    40 #define MIR_DRIVER_NAME "mir"
    41 
    42 static int
    43 MIR_VideoInit(_THIS);
    44 
    45 static void
    46 MIR_VideoQuit(_THIS);
    47 
    48 static int
    49 MIR_GetDisplayBounds(_THIS, SDL_VideoDisplay* display, SDL_Rect* rect);
    50 
    51 static void
    52 MIR_GetDisplayModes(_THIS, SDL_VideoDisplay* sdl_display);
    53 
    54 static int
    55 MIR_SetDisplayMode(_THIS, SDL_VideoDisplay* sdl_display, SDL_DisplayMode* mode);
    56 
    57 static SDL_WindowShaper*
    58 MIR_CreateShaper(SDL_Window* window)
    59 {
    60     /* FIXME Im not sure if mir support this atm, will have to come back to this */
    61     return NULL;
    62 }
    63 
    64 static int
    65 MIR_SetWindowShape(SDL_WindowShaper* shaper, SDL_Surface* shape, SDL_WindowShapeMode* shape_mode)
    66 {
    67     return SDL_Unsupported();
    68 }
    69 
    70 static int
    71 MIR_ResizeWindowShape(SDL_Window* window)
    72 {
    73     return SDL_Unsupported();
    74 }
    75 
    76 static int
    77 MIR_Available()
    78 {
    79     int available = 0;
    80 
    81     if (SDL_MIR_LoadSymbols()) {
    82         /* !!! FIXME: try to make a MirConnection here. */
    83         available = 1;
    84         SDL_MIR_UnloadSymbols();
    85     }
    86 
    87     return available;
    88 }
    89 
    90 static void
    91 MIR_DeleteDevice(SDL_VideoDevice* device)
    92 {
    93     SDL_free(device);
    94     SDL_MIR_UnloadSymbols();
    95 }
    96 
    97 void
    98 MIR_PumpEvents(_THIS)
    99 {
   100 }
   101 
   102 static SDL_VideoDevice*
   103 MIR_CreateDevice(int device_index)
   104 {
   105     MIR_Data* mir_data;
   106     SDL_VideoDevice* device = NULL;
   107 
   108     if (!SDL_MIR_LoadSymbols()) {
   109         return NULL;
   110     }
   111 
   112     device = SDL_calloc(1, sizeof(SDL_VideoDevice));
   113     if (!device) {
   114         SDL_MIR_UnloadSymbols();
   115         SDL_OutOfMemory();
   116         return NULL;
   117     }
   118 
   119     mir_data = SDL_calloc(1, sizeof(MIR_Data));
   120     if (!mir_data) {
   121         SDL_free(device);
   122         SDL_MIR_UnloadSymbols();
   123         SDL_OutOfMemory();
   124         return NULL;
   125     }
   126 
   127     device->driverdata = mir_data;
   128 
   129     /* mirvideo */
   130     device->VideoInit        = MIR_VideoInit;
   131     device->VideoQuit        = MIR_VideoQuit;
   132     device->GetDisplayBounds = MIR_GetDisplayBounds;
   133     device->GetDisplayModes  = MIR_GetDisplayModes;
   134     device->SetDisplayMode   = MIR_SetDisplayMode;
   135     device->free             = MIR_DeleteDevice;
   136 
   137     /* miropengles */
   138     device->GL_SwapWindow      = MIR_GL_SwapWindow;
   139     device->GL_MakeCurrent     = MIR_GL_MakeCurrent;
   140     device->GL_CreateContext   = MIR_GL_CreateContext;
   141     device->GL_DeleteContext   = MIR_GL_DeleteContext;
   142     device->GL_LoadLibrary     = MIR_GL_LoadLibrary;
   143     device->GL_UnloadLibrary   = MIR_GL_UnloadLibrary;
   144     device->GL_GetSwapInterval = MIR_GL_GetSwapInterval;
   145     device->GL_SetSwapInterval = MIR_GL_SetSwapInterval;
   146     device->GL_GetProcAddress  = MIR_GL_GetProcAddress;
   147 
   148     /* mirwindow */
   149     device->CreateWindow         = MIR_CreateWindow;
   150     device->DestroyWindow        = MIR_DestroyWindow;
   151     device->GetWindowWMInfo      = MIR_GetWindowWMInfo;
   152     device->SetWindowFullscreen  = MIR_SetWindowFullscreen;
   153     device->MaximizeWindow       = MIR_MaximizeWindow;
   154     device->MinimizeWindow       = MIR_MinimizeWindow;
   155     device->RestoreWindow        = MIR_RestoreWindow;
   156     device->ShowWindow           = MIR_RestoreWindow;
   157     device->HideWindow           = MIR_HideWindow;
   158     device->SetWindowSize        = MIR_SetWindowSize;
   159     device->SetWindowMinimumSize = MIR_SetWindowMinimumSize;
   160     device->SetWindowMaximumSize = MIR_SetWindowMaximumSize;
   161     device->SetWindowTitle       = MIR_SetWindowTitle;
   162 
   163     device->CreateWindowFrom     = NULL;
   164     device->SetWindowIcon        = NULL;
   165     device->RaiseWindow          = NULL;
   166     device->SetWindowBordered    = NULL;
   167     device->SetWindowGammaRamp   = NULL;
   168     device->GetWindowGammaRamp   = NULL;
   169     device->SetWindowGrab        = NULL;
   170     device->OnWindowEnter        = NULL;
   171     device->SetWindowPosition    = NULL;
   172 
   173     /* mirframebuffer */
   174     device->CreateWindowFramebuffer  = MIR_CreateWindowFramebuffer;
   175     device->UpdateWindowFramebuffer  = MIR_UpdateWindowFramebuffer;
   176     device->DestroyWindowFramebuffer = MIR_DestroyWindowFramebuffer;
   177 
   178     device->shape_driver.CreateShaper      = MIR_CreateShaper;
   179     device->shape_driver.SetWindowShape    = MIR_SetWindowShape;
   180     device->shape_driver.ResizeWindowShape = MIR_ResizeWindowShape;
   181 
   182     device->PumpEvents = MIR_PumpEvents;
   183 
   184     device->SuspendScreenSaver = NULL;
   185 
   186     device->StartTextInput   = NULL;
   187     device->StopTextInput    = NULL;
   188     device->SetTextInputRect = NULL;
   189 
   190     device->HasScreenKeyboardSupport = NULL;
   191     device->ShowScreenKeyboard       = NULL;
   192     device->HideScreenKeyboard       = NULL;
   193     device->IsScreenKeyboardShown    = NULL;
   194 
   195     device->SetClipboardText = NULL;
   196     device->GetClipboardText = NULL;
   197     device->HasClipboardText = NULL;
   198 
   199     device->ShowMessageBox = NULL;
   200 
   201     return device;
   202 }
   203 
   204 VideoBootStrap MIR_bootstrap = {
   205     MIR_DRIVER_NAME, "SDL Mir video driver",
   206     MIR_Available, MIR_CreateDevice
   207 };
   208 
   209 static void
   210 MIR_SetCurrentDisplayMode(MirDisplayOutput const* out, SDL_VideoDisplay* display)
   211 {
   212     SDL_DisplayMode mode = {
   213         .format = SDL_PIXELFORMAT_RGB888,
   214         .w = out->modes[out->current_mode].horizontal_resolution,
   215         .h = out->modes[out->current_mode].vertical_resolution,
   216         .refresh_rate = out->modes[out->current_mode].refresh_rate,
   217         .driverdata = NULL
   218     };
   219 
   220     display->desktop_mode = mode;
   221     display->current_mode = mode;
   222 }
   223 
   224 static void
   225 MIR_AddAllModesFromDisplay(MirDisplayOutput const* out, SDL_VideoDisplay* display)
   226 {
   227     int n_mode;
   228     for (n_mode = 0; n_mode < out->num_modes; ++n_mode) {
   229         SDL_DisplayMode mode = {
   230             .format = SDL_PIXELFORMAT_RGB888,
   231             .w = out->modes[n_mode].horizontal_resolution,
   232             .h = out->modes[n_mode].vertical_resolution,
   233             .refresh_rate = out->modes[n_mode].refresh_rate,
   234             .driverdata = NULL
   235         };
   236 
   237         SDL_AddDisplayMode(display, &mode);
   238     }
   239 }
   240 
   241 static void
   242 MIR_InitDisplays(_THIS)
   243 {
   244     MIR_Data* mir_data = _this->driverdata;
   245     int d;
   246 
   247     MirDisplayConfiguration* display_config = MIR_mir_connection_create_display_config(mir_data->connection);
   248 
   249     for (d = 0; d < display_config->num_outputs; d++) {
   250         MirDisplayOutput const* out = display_config->outputs + d;
   251 
   252         SDL_VideoDisplay display;
   253         SDL_zero(display);
   254 
   255         if (out->used &&
   256             out->connected &&
   257             out->num_modes &&
   258             out->current_mode < out->num_modes) {
   259 
   260             MIR_SetCurrentDisplayMode(out, &display);
   261             MIR_AddAllModesFromDisplay(out, &display);
   262 
   263             SDL_AddVideoDisplay(&display);
   264         }
   265     }
   266 
   267     MIR_mir_display_config_destroy(display_config);
   268 }
   269 
   270 int
   271 MIR_VideoInit(_THIS)
   272 {
   273     MIR_Data* mir_data = _this->driverdata;
   274 
   275     mir_data->connection     = MIR_mir_connect_sync(NULL, __PRETTY_FUNCTION__);
   276     mir_data->current_window = NULL;
   277     mir_data->software       = SDL_FALSE;
   278     mir_data->pixel_format   = mir_pixel_format_invalid;
   279 
   280     if (!MIR_mir_connection_is_valid(mir_data->connection))
   281         return SDL_SetError("Failed to connect to the Mir Server");
   282 
   283     MIR_InitDisplays(_this);
   284     MIR_InitMouse();
   285 
   286     return 0;
   287 }
   288 
   289 void
   290 MIR_VideoQuit(_THIS)
   291 {
   292     MIR_Data* mir_data = _this->driverdata;
   293 
   294     MIR_FiniMouse();
   295 
   296     MIR_GL_DeleteContext(_this, NULL);
   297     MIR_GL_UnloadLibrary(_this);
   298 
   299     MIR_mir_connection_release(mir_data->connection);
   300 
   301     SDL_free(mir_data);
   302     _this->driverdata = NULL;
   303 }
   304 
   305 static int
   306 MIR_GetDisplayBounds(_THIS, SDL_VideoDisplay* display, SDL_Rect* rect)
   307 {
   308     MIR_Data* mir_data = _this->driverdata;
   309     int d;
   310 
   311     MirDisplayConfiguration* display_config = MIR_mir_connection_create_display_config(mir_data->connection);
   312 
   313     for (d = 0; d < display_config->num_outputs; d++) {
   314         MirDisplayOutput const* out = display_config->outputs + d;
   315 
   316         if (out->used &&
   317             out->connected &&
   318             out->num_modes &&
   319             out->current_mode < out->num_modes) {
   320 
   321             rect->x = out->position_x;
   322             rect->y = out->position_y;
   323             rect->w = out->modes->horizontal_resolution;
   324             rect->h = out->modes->vertical_resolution;
   325         }
   326     }
   327 
   328     MIR_mir_display_config_destroy(display_config);
   329 
   330     return 0;
   331 }
   332 
   333 static void
   334 MIR_GetDisplayModes(_THIS, SDL_VideoDisplay* sdl_display)
   335 {
   336 }
   337 
   338 static int
   339 MIR_SetDisplayMode(_THIS, SDL_VideoDisplay* sdl_display, SDL_DisplayMode* mode)
   340 {
   341     return 0;
   342 }
   343 
   344 #endif /* SDL_VIDEO_DRIVER_MIR */
   345 
   346 /* vi: set ts=4 sw=4 expandtab: */
   347