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