src/video/mir/SDL_mirvideo.c
author Brandon Schaefer <brandon.schaefer@canonical.com>
Fri, 02 May 2014 12:33:19 -0700
changeset 8749 f34996d809b7
parent 8723 cfc134c9c369
child 9619 b94b6d0bff0f
permissions -rw-r--r--
Fix software rendering in the mir backend. The window assumed hardware buffer, which caused testdrawchessboard to fail to mmap a buffer.
     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_video.h"
    31 
    32 #include "SDL_mirframebuffer.h"
    33 #include "SDL_mirmouse.h"
    34 #include "SDL_miropengl.h"
    35 #include "SDL_mirvideo.h"
    36 #include "SDL_mirwindow.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 
   157     device->CreateWindowFrom     = NULL;
   158     device->SetWindowTitle       = NULL;
   159     device->SetWindowIcon        = NULL;
   160     device->SetWindowPosition    = NULL;
   161     device->SetWindowSize        = NULL;
   162     device->SetWindowMinimumSize = NULL;
   163     device->SetWindowMaximumSize = NULL;
   164     device->ShowWindow           = NULL;
   165     device->HideWindow           = NULL;
   166     device->RaiseWindow          = NULL;
   167     device->SetWindowBordered    = NULL;
   168     device->SetWindowGammaRamp   = NULL;
   169     device->GetWindowGammaRamp   = NULL;
   170     device->SetWindowGrab        = NULL;
   171     device->OnWindowEnter        = 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->software = SDL_FALSE;
   277 
   278     if (!MIR_mir_connection_is_valid(mir_data->connection))
   279         return SDL_SetError("Failed to connect to the Mir Server");
   280 
   281     MIR_InitDisplays(_this);
   282     MIR_InitMouse();
   283 
   284     return 0;
   285 }
   286 
   287 void
   288 MIR_VideoQuit(_THIS)
   289 {
   290     MIR_Data* mir_data = _this->driverdata;
   291 
   292     MIR_FiniMouse();
   293 
   294     MIR_GL_DeleteContext(_this, NULL);
   295     MIR_GL_UnloadLibrary(_this);
   296 
   297     MIR_mir_connection_release(mir_data->connection);
   298 
   299     SDL_free(mir_data);
   300     _this->driverdata = NULL;
   301 }
   302 
   303 static int
   304 MIR_GetDisplayBounds(_THIS, SDL_VideoDisplay* display, SDL_Rect* rect)
   305 {
   306     MIR_Data* mir_data = _this->driverdata;
   307     int d;
   308 
   309     MirDisplayConfiguration* display_config = MIR_mir_connection_create_display_config(mir_data->connection);
   310 
   311     for (d = 0; d < display_config->num_outputs; d++) {
   312         MirDisplayOutput const* out = display_config->outputs + d;
   313 
   314         if (out->used &&
   315             out->connected &&
   316             out->num_modes &&
   317             out->current_mode < out->num_modes) {
   318 
   319             rect->x = out->position_x;
   320             rect->y = out->position_y;
   321             rect->w = out->modes->horizontal_resolution;
   322             rect->h = out->modes->vertical_resolution;
   323         }
   324     }
   325 
   326     MIR_mir_display_config_destroy(display_config);
   327 
   328     return 0;
   329 }
   330 
   331 static void
   332 MIR_GetDisplayModes(_THIS, SDL_VideoDisplay* sdl_display)
   333 {
   334 }
   335 
   336 static int
   337 MIR_SetDisplayMode(_THIS, SDL_VideoDisplay* sdl_display, SDL_DisplayMode* mode)
   338 {
   339     return 0;
   340 }
   341 
   342 #endif /* SDL_VIDEO_DRIVER_MIR */
   343 
   344 /* vi: set ts=4 sw=4 expandtab: */
   345