diff src/video/x11/SDL_x11render.c @ 3559:5f26a7eb5ff0

Implemented read/write pixels for the X11 renderer
author Sam Lantinga <slouken@libsdl.org>
date Mon, 14 Dec 2009 06:52:17 +0000
parents c2154674c0c1
children f638ded38b8a
line wrap: on
line diff
--- a/src/video/x11/SDL_x11render.c	Mon Dec 14 06:35:59 2009 +0000
+++ b/src/video/x11/SDL_x11render.c	Mon Dec 14 06:52:17 2009 +0000
@@ -58,6 +58,10 @@
                            int count);
 static int X11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
                           const SDL_Rect * srcrect, const SDL_Rect * dstrect);
+static int X11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+                                Uint32 format, void * pixels, int pitch);
+static int X11_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+                                 Uint32 format, const void * pixels, int pitch);
 static void X11_RenderPresent(SDL_Renderer * renderer);
 static void X11_DestroyTexture(SDL_Renderer * renderer,
                                SDL_Texture * texture);
@@ -208,6 +212,8 @@
     renderer->RenderLines = X11_RenderLines;
     renderer->RenderRects = X11_RenderRects;
     renderer->RenderCopy = X11_RenderCopy;
+    renderer->RenderReadPixels = X11_RenderReadPixels;
+    renderer->RenderWritePixels = X11_RenderWritePixels;
     renderer->RenderPresent = X11_RenderPresent;
     renderer->DestroyTexture = X11_DestroyTexture;
     renderer->DestroyRenderer = X11_DestroyRenderer;
@@ -937,6 +943,70 @@
     return 0;
 }
 
+static int
+X11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+                     Uint32 format, void * pixels, int pitch)
+{
+    X11_RenderData *data = (X11_RenderData *) renderer->driverdata;
+    SDL_Window *window = SDL_GetWindowFromID(renderer->window);
+    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
+    Uint32 screen_format = display->current_mode.format;
+    XImage *image;
+
+    image = XGetImage(data->display, data->drawable, rect->x, rect->y,
+                      rect->w, rect->h, AllPlanes, ZPixmap);
+
+    SDL_ConvertPixels(rect->w, rect->h,
+                      screen_format, image->data, image->bytes_per_line,
+                      format, pixels, pitch);
+
+    XDestroyImage(image);
+    return 0;
+}
+
+static int
+X11_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+                      Uint32 format, const void * pixels, int pitch)
+{
+    X11_RenderData *data = (X11_RenderData *) renderer->driverdata;
+    SDL_Window *window = SDL_GetWindowFromID(renderer->window);
+    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
+    Uint32 screen_format = display->current_mode.format;
+    XImage *image;
+    void *image_pixels;
+    int image_pitch;
+
+    image_pitch = rect->w * SDL_BYTESPERPIXEL(screen_format);
+    image_pixels = SDL_malloc(rect->h * image_pitch);
+    if (!image_pixels) {
+        SDL_OutOfMemory();
+        return -1;
+    }
+
+    image = XCreateImage(data->display, data->visual,
+                         data->depth, ZPixmap, 0, image_pixels,
+                         rect->w, rect->h,
+                         SDL_BYTESPERPIXEL(screen_format) * 8,
+                         image_pitch);
+    if (!image) {
+        SDL_SetError("XCreateImage() failed");
+        return -1;
+    }
+
+    SDL_ConvertPixels(rect->w, rect->h,
+                      format, pixels, pitch,
+                      screen_format, image->data, image->bytes_per_line);
+
+    XPutImage(data->display, data->drawable, data->gc,
+              image, 0, 0, rect->x, rect->y, rect->w, rect->h);
+
+    image->data = NULL;
+    XDestroyImage(image);
+
+    SDL_free(image_pixels);
+    return 0;
+}
+
 static void
 X11_RenderPresent(SDL_Renderer * renderer)
 {