icculus@8153: /* icculus@8153: Simple DirectMedia Layer icculus@8157: Copyright (C) 1997-2014 Sam Lantinga icculus@8153: icculus@8153: This software is provided 'as-is', without any express or implied icculus@8153: warranty. In no event will the authors be held liable for any damages icculus@8153: arising from the use of this software. icculus@8153: icculus@8153: Permission is granted to anyone to use this software for any purpose, icculus@8153: including commercial applications, and to alter it and redistribute it icculus@8153: freely, subject to the following restrictions: icculus@8153: icculus@8153: 1. The origin of this software must not be misrepresented; you must not icculus@8153: claim that you wrote the original software. If you use this software icculus@8153: in a product, an acknowledgment in the product documentation would be icculus@8153: appreciated but is not required. icculus@8153: 2. Altered source versions must be plainly marked as such, and must not be icculus@8153: misrepresented as being the original software. icculus@8153: 3. This notice may not be removed or altered from any source distribution. icculus@8153: */ icculus@8153: icculus@8153: /* icculus@8153: Contributed by Brandon Schaefer, icculus@8153: */ icculus@8153: icculus@8154: #include "../../SDL_internal.h" icculus@8154: icculus@8154: #if SDL_VIDEO_DRIVER_MIR icculus@8154: icculus@8153: #include "SDL_mirevents.h" icculus@8153: #include "SDL_mirframebuffer.h" icculus@8153: #include "SDL_mirwindow.h" icculus@8153: icculus@8153: static const Uint32 mir_pixel_format_to_sdl_format[] = { icculus@8153: SDL_PIXELFORMAT_UNKNOWN, /* mir_pixel_format_invalid */ icculus@8153: SDL_PIXELFORMAT_ABGR8888, /* mir_pixel_format_abgr_8888 */ icculus@8153: SDL_PIXELFORMAT_BGR888, /* mir_pixel_format_xbgr_8888 */ icculus@8153: SDL_PIXELFORMAT_ARGB8888, /* mir_pixel_format_argb_8888 */ icculus@8153: SDL_PIXELFORMAT_RGB888, /* mir_pixel_format_xrgb_8888 */ icculus@8153: SDL_PIXELFORMAT_BGR24 /* mir_pixel_format_bgr_888 */ icculus@8153: }; icculus@8153: icculus@8153: Uint32 icculus@8153: MIR_GetSDLPixelFormat(MirPixelFormat format) icculus@8153: { icculus@8153: return mir_pixel_format_to_sdl_format[format]; icculus@8153: } icculus@8153: icculus@8153: int icculus@8153: MIR_CreateWindowFramebuffer(_THIS, SDL_Window* window, Uint32* format, icculus@8153: void** pixels, int* pitch) icculus@8153: { icculus@8153: MIR_Data* mir_data = _this->driverdata; icculus@8153: MIR_Window* mir_window; icculus@8153: MirSurfaceParameters surfaceparm; icculus@8153: icculus@8153: if (MIR_CreateWindow(_this, window) < 0) icculus@8153: return SDL_SetError("Failed to created a mir window."); icculus@8153: icculus@8153: mir_window = window->driverdata; icculus@8153: icculus@8153: mir_surface_get_parameters(mir_window->surface, &surfaceparm); icculus@8153: icculus@8153: *format = MIR_GetSDLPixelFormat(surfaceparm.pixel_format); icculus@8153: if (*format == SDL_PIXELFORMAT_UNKNOWN) icculus@8153: return SDL_SetError("Unknown pixel format"); icculus@8153: icculus@8153: *pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3); icculus@8153: icculus@8153: *pixels = SDL_malloc(window->h*(*pitch)); icculus@8153: if (*pixels == NULL) icculus@8153: return SDL_OutOfMemory(); icculus@8153: icculus@8153: mir_window->surface = mir_connection_create_surface_sync(mir_data->connection, &surfaceparm); icculus@8153: if (!mir_surface_is_valid(mir_window->surface)) { icculus@8153: const char* error = mir_surface_get_error_message(mir_window->surface); icculus@8153: return SDL_SetError("Failed to created a mir surface: %s", error); icculus@8153: } icculus@8153: icculus@8153: return 0; icculus@8153: } icculus@8153: icculus@8153: int icculus@8153: MIR_UpdateWindowFramebuffer(_THIS, SDL_Window* window, icculus@8153: const SDL_Rect* rects, int numrects) icculus@8153: { icculus@8153: MIR_Window* mir_window = window->driverdata; icculus@8153: icculus@8153: MirGraphicsRegion region; icculus@8153: int i, j, x, y, w, h, start; icculus@8153: int bytes_per_pixel, bytes_per_row, s_stride, d_stride; icculus@8153: icculus@8153: mir_surface_get_graphics_region(mir_window->surface, ®ion); icculus@8153: icculus@8153: char* s_dest = region.vaddr; icculus@8153: char* pixels = (char*)window->surface->pixels; icculus@8153: icculus@8153: s_stride = window->surface->pitch; icculus@8153: d_stride = region.stride; icculus@8153: bytes_per_pixel = window->surface->format->BytesPerPixel; icculus@8153: icculus@8153: for (i = 0; i < numrects; i++) { icculus@8153: s_dest = region.vaddr; icculus@8153: pixels = (char*)window->surface->pixels; icculus@8153: icculus@8153: x = rects[i].x; icculus@8153: y = rects[i].y; icculus@8153: w = rects[i].w; icculus@8153: h = rects[i].h; icculus@8153: icculus@8153: if (w <= 0 || h <= 0 || (x + w) <= 0 || (y + h) <= 0) icculus@8153: continue; icculus@8153: icculus@8153: if (x < 0) { icculus@8153: x += w; icculus@8153: w += rects[i].x; icculus@8153: } icculus@8153: icculus@8153: if (y < 0) { icculus@8153: y += h; icculus@8153: h += rects[i].y; icculus@8153: } icculus@8153: icculus@8153: if (x + w > window->w) icculus@8153: w = window->w - x; icculus@8153: if (y + h > window->h) icculus@8153: h = window->h - y; icculus@8153: icculus@8153: start = y * s_stride + x; icculus@8153: pixels += start; icculus@8153: s_dest += start; icculus@8153: icculus@8153: bytes_per_row = bytes_per_pixel * w; icculus@8153: for (j = 0; j < h; j++) { icculus@8153: memcpy(s_dest, pixels, bytes_per_row); icculus@8153: pixels += s_stride; icculus@8153: s_dest += d_stride; icculus@8153: } icculus@8153: } icculus@8153: icculus@8153: mir_surface_swap_buffers_sync(mir_window->surface); icculus@8153: icculus@8153: return 0; icculus@8153: } icculus@8153: icculus@8153: void icculus@8153: MIR_DestroyWindowFramebuffer(_THIS, SDL_Window* window) icculus@8153: { icculus@8153: } icculus@8154: icculus@8154: #endif /* SDL_VIDEO_DRIVER_MIR */ icculus@8154: icculus@8154: /* vi: set ts=4 sw=4 expandtab: */