From 058a299912da56e79a2ab898dcc6879cda0ebc9d Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 14 Dec 2009 06:52:17 +0000 Subject: [PATCH] Implemented read/write pixels for the X11 renderer --- src/video/x11/SDL_x11render.c | 70 +++++++++++++++++++++++++++++++++++ src/video/x11/SDL_x11sym.h | 1 + 2 files changed, 71 insertions(+) diff --git a/src/video/x11/SDL_x11render.c b/src/video/x11/SDL_x11render.c index 4b75d0c82..314bc7785 100644 --- a/src/video/x11/SDL_x11render.c +++ b/src/video/x11/SDL_x11render.c @@ -58,6 +58,10 @@ static int X11_RenderRects(SDL_Renderer * renderer, const SDL_Rect ** rects, 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 @@ X11_CreateRenderer(SDL_Window * window, Uint32 flags) 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 @@ X11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 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) { diff --git a/src/video/x11/SDL_x11sym.h b/src/video/x11/SDL_x11sym.h index c529f5ef7..bce182eff 100644 --- a/src/video/x11/SDL_x11sym.h +++ b/src/video/x11/SDL_x11sym.h @@ -63,6 +63,7 @@ SDL_X11_SYM(int,XFreeGC,(Display* a,GC b),(a,b),return) SDL_X11_SYM(int,XFreeModifiermap,(XModifierKeymap* a),(a),return) SDL_X11_SYM(int,XFreePixmap,(Display* a,Pixmap b),(a,b),return) SDL_X11_SYM(int,XGetErrorDatabaseText,(Display* a,_Xconst char* b,_Xconst char* c,_Xconst char* d,char* e,int f),(a,b,c,d,e,f),return) +SDL_X11_SYM(XImage*,XGetImage,(Display* a,Drawable b,int c,int d,unsigned int e,unsigned int f,unsigned long g, int h),(a,b,c,d,e,f,g,h),return) SDL_X11_SYM(XModifierKeymap*,XGetModifierMapping,(Display* a),(a),return) SDL_X11_SYM(int,XGetPointerControl,(Display* a,int* b,int* c,int* d),(a,b,c,d),return) SDL_X11_SYM(int,XGetRGBColormaps,(Display* a,Window b,XStandardColormap **c,int *d,Atom e),(a,b,c,d,e),return)