Finished X11 shaped-window functionality and removed ellipse+polygon rendering.
--- a/Makefile.in Mon Jun 21 23:08:10 2010 -0400
+++ b/Makefile.in Wed Jun 30 16:19:44 2010 -0400
@@ -44,7 +44,7 @@
DIST = acinclude autogen.sh Borland.html Borland.zip BUGS build-scripts configure configure.in COPYING CREDITS include INSTALL Makefile.minimal Makefile.in README* sdl-config.in sdl.m4 sdl.pc.in SDL.spec SDL.spec.in src test TODO VisualC.html VisualC VisualCE Watcom-Win32.zip WhatsNew Xcode Xcode-iPhoneOS
-HDRS = SDL.h SDL_assert.h SDL_atomic.h SDL_audio.h SDL_compat.h SDL_cpuinfo.h SDL_ellipse.h SDL_endian.h SDL_error.h SDL_events.h SDL_haptic.h SDL_joystick.h SDL_keyboard.h SDL_keysym.h SDL_loadso.h SDL_main.h SDL_mouse.h SDL_mutex.h SDL_name.h SDL_opengl.h SDL_opengles.h SDL_pixels.h SDL_platform.h SDL_poly.h SDL_power.h SDL_quit.h SDL_rect.h SDL_revision.h SDL_rwops.h SDL_scancode.h SDL_shape.h SDL_stdinc.h SDL_surface.h SDL_syswm.h SDL_thread.h SDL_timer.h SDL_types.h SDL_version.h SDL_video.h begin_code.h close_code.h
+HDRS = SDL.h SDL_assert.h SDL_atomic.h SDL_audio.h SDL_compat.h SDL_cpuinfo.h SDL_endian.h SDL_error.h SDL_events.h SDL_haptic.h SDL_joystick.h SDL_keyboard.h SDL_keysym.h SDL_loadso.h SDL_main.h SDL_mouse.h SDL_mutex.h SDL_name.h SDL_opengl.h SDL_opengles.h SDL_pixels.h SDL_platform.h SDL_power.h SDL_quit.h SDL_rect.h SDL_revision.h SDL_rwops.h SDL_scancode.h SDL_shape.h SDL_stdinc.h SDL_surface.h SDL_syswm.h SDL_thread.h SDL_timer.h SDL_types.h SDL_version.h SDL_video.h begin_code.h close_code.h
LT_AGE = @LT_AGE@
LT_CURRENT = @LT_CURRENT@
--- a/include/SDL_shape.h Mon Jun 21 23:08:10 2010 -0400
+++ b/include/SDL_shape.h Wed Jun 30 16:19:44 2010 -0400
@@ -114,10 +114,11 @@
* \brief Get the shape parameters of a shaped window.
*
* \param window The shaped window whose parameters should be retrieved.
- * \param shapeMode An empty shape-parameters structure to fill.
+ * \param shapeMode An empty shape-mode structure to fill, or NULL to check whether the window has a shape.
*
- * \return 0 on success, -1 on a null shapeMode, or -2 if the SDL_Window given is not a shaped window, or -3 if the
- * SDL_Window given is a window that can be shaped but isn't.
+ * \return 0 if the window has a shape and, provided shapeMode was not NULL, shapeMode has been filled with the mode
+ * data, -1 if the SDL_Window given is not a shaped window, or -2 if the SDL_Window* given is a shapeable
+ * window currently lacking a shape.
*
* \sa SDL_WindowShapeMode
* \sa SDL_SetWindowShape
--- a/include/SDL_video.h Mon Jun 21 23:08:10 2010 -0400
+++ b/include/SDL_video.h Wed Jun 30 16:19:44 2010 -0400
@@ -1240,82 +1240,6 @@
extern DECLSPEC int SDLCALL SDL_RenderFillRects(const SDL_Rect ** rect, int count);
/**
- * \brief Draw an ellipse on the current rendering target with the drawing color.
- *
- * \param ellipse The destination ellipse.
- *
- * \return 0 on success, or -1 if there is no rendering context current.
- */
-extern DECLSPEC int SDLCALL SDL_RenderDrawEllipse(const SDL_Ellipse ellipse);
-
-/**
- * \brief Draw some number of ellipses in the current rendering target with the drawing color.
- *
- * \param ellipse A pointer to an array of destination ellipses.
- * \param count The number of ellipses.
- *
- * \return 0 on success, or -1 if there is no rendering context current.
- */
-extern DECLSPEC int SDLCALL SDL_RenderDrawEllipses(const SDL_Ellipse * ellipse, int count);
-
-/**
- * \brief Fill an ellipse on the current rendering target with the drawing color.
- *
- * \param ellipse The destination ellipse
- *
- * \return 0 on success, or -1 if there is no rendering context current.
- */
-extern DECLSPEC int SDLCALL SDL_RenderFillEllipse(const SDL_Ellipse ellipse);
-
-/**
- * \brief Fill some number of ellipses in the current rendering target with the drawing color.
- *
- * \param ellipse A pointer to an array of destination ellipses.
- * \param count The number of ellipses.
- *
- * \return 0 on success, or -1 if there is no rendering context current.
- */
-extern DECLSPEC int SDLCALL SDL_RenderFillEllipses(const SDL_Ellipse *ellipse, int count);
-
-/**
- * \brief Draw a polygon on the current rendering target with the drawing color.
- *
- * \param poly The destination polygon.
- *
- * \return 0 on success, or -1 if there is no rendering context current.
- */
-extern DECLSPEC int SDLCALL SDL_RenderDrawPoly(const SDL_Poly poly);
-
-/**
- * \brief Draw some number of polygons in the current rendering target with the drawing color.
- *
- * \param poly A pointer to an array of destination polygons.
- * \param count The number of polygons.
- *
- * \return 0 on success, or -1 if there is no rendering context current.
- */
-extern DECLSPEC int SDLCALL SDL_RenderDrawPolys(const SDL_Poly *poly, int count);
-
-/**
- * \brief Fill a polygon on the current rendering target with the drawing color.
- *
- * \param poly The destination polygon
- *
- * \return 0 on success, or -1 if there is no rendering context current.
- */
-extern DECLSPEC int SDLCALL SDL_RenderFillPoly(const SDL_Poly poly);
-
-/**
- * \brief Fill some number of polygons in the current rendering target with the drawing color.
- *
- * \param poly A pointer to an array of destination polygons.
- * \param count The number of polygons.
- *
- * \return 0 on success, or -1 if there is no rendering context current.
- */
-extern DECLSPEC int SDLCALL SDL_RenderFillPolys(const SDL_Poly *poly, int count);
-
-/**
* \brief Copy a portion of the texture to the current rendering target.
*
* \param texture The source texture.
--- a/src/video/SDL_shape.c Mon Jun 21 23:08:10 2010 -0400
+++ b/src/video/SDL_shape.c Wed Jun 30 16:19:44 2010 -0400
@@ -24,28 +24,99 @@
#include "SDL.h"
#include "SDL_video.h"
#include "SDL_sysvideo.h"
+#include "SDL_pixels.h"
+#include "SDL_surface.h"
#include "SDL_shape.h"
SDL_Window* SDL_CreateShapedWindow(const char *title,unsigned int x,unsigned int y,unsigned int w,unsigned int h,Uint32 flags) {
- return NULL;
+ SDL_Window *result = SDL_CreateWindow(title,x,y,w,h,SDL_WINDOW_BORDERLESS | flags & !SDL_WINDOW_FULLSCREEN & !SDL_WINDOW_SHOWN);
+ result->shaper = result->display->device->shape_driver.CreateShaper(result);
+ result->shaper->usershownflag = flags & SDL_WINDOW_SHOWN;
+ result->shaper->alphacutoff = 1;
+ result->shaper->hasshape = SDL_FALSE;
+ return result;
}
SDL_bool SDL_IsShapedWindow(const SDL_Window *window) {
- return SDL_FALSE;
+ if(window == NULL)
+ return SDL_FALSE;
+ else
+ return window->shaper != NULL;
+}
+
+/* REQUIRES that bitmap point to a w-by-h bitmap with 1bpp. */
+void SDL_CalculateShapeBitmap(Uint8 alphacutoff,SDL_Surface *shape,Uint8* bitmap) {
+ if(SDL_MUSTLOCK(shape))
+ SDL_LockSurface(shape);
+ int x = 0,y = 0;
+ for(x = 0;x<shape->w;x++)
+ for(y = 0;y<shape->h;y++) {
+ void* pixel = shape->pixels + (y*shape->pitch) + (x*shape->format->BytesPerPixel);
+ Uint8 alpha = 0;
+ SDL_GetRGBA(*(Uint32*)pixel,shape->format,NULL,NULL,NULL,&alpha);
+ Uint32 bitmap_pixel = y*shape->w + x;
+ bitmap[bitmap_pixel / 8] |= (alpha >= alphacutoff ? 1 : 0) << (8 - (bitmap_pixel % 8));
+ }
+ if(SDL_MUSTLOCK(shape))
+ SDL_UnlockSurface(shape);
}
int SDL_SetWindowShape(SDL_Window *window,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode) {
if(window == NULL || !SDL_WindowIsShaped(window))
+ //The window given was not a shapeable window.
return -2;
if(shape == NULL)
+ //Invalid shape argument.
return -1;
- return -3;
+
+ if(shapeMode != NULL) {
+ switch(shapeMode->mode) {
+ case ShapeModeDefault: {
+ window->shaper->alphacutoff = 1;
+ break;
+ }
+ case ShapeModeBinarizeAlpha: {
+ window->shaper->alphacutoff = shapeMode->parameters.binarizationCutoff;
+ break;
+ }
+ }
+ }
+ //TODO: Platform-specific implementations of SetWindowShape. X11 is in-progress.
+ int result = window->display->device->shape_driver.SetWindowShape(window->shaper,shape,shapeMode);
+ window->shaper->hasshape = SDL_TRUE;
+ if(window->shaper->usershownflag & SDL_WINDOW_SHOWN == SDL_WINDOW_SHOWN) {
+ SDL_ShowWindow(window);
+ window->shaper->usershownflag &= !SDL_WINDOW_SHOWN;
+ }
+ return result;
+}
+
+SDL_bool SDL_WindowHasAShape(SDL_Window *window) {
+ assert(window != NULL && SDL_IsShapedWindow(window));
+ return window->shaper->hasshape;
}
int SDL_GetShapedWindowMode(SDL_Window *window,SDL_WindowShapeMode *shapeMode) {
- if(shapeMode == NULL)
+ if(window != NULL && SDL_IsShapedWindow(window)) {
+ if(shapeMode == NULL) {
+ if(SDL_WindowHasAShape(window))
+ //The window given has a shape.
+ return 0;
+ else
+ //The window given is shapeable but lacks a shape.
+ return -2;
+ }
+ else {
+ if(window->shaper->alphacutoff != 1) {
+ shapeMode->mode = ShapeModeBinarizeAlpha;
+ shapeMode->parameters.binarizationCutoff = window->shaper->alphacutoff;
+ }
+ else
+ shapeMode->mode = ShapeModeDefault;
+ return 0;
+ }
+ }
+ else
+ //The window given is not a valid shapeable window.
return -1;
- if(window == NULL || !SDL_WindowIsShaped(window))
- return -2;
- return -3;
}
--- a/src/video/SDL_sysvideo.h Mon Jun 21 23:08:10 2010 -0400
+++ b/src/video/SDL_sysvideo.h Wed Jun 30 16:19:44 2010 -0400
@@ -26,11 +26,14 @@
#include "SDL_mouse.h"
#include "SDL_keysym.h"
+#include "SDL_shape.h"
/* The SDL video driver */
typedef struct SDL_Renderer SDL_Renderer;
typedef struct SDL_RenderDriver SDL_RenderDriver;
+typedef struct SDL_WindowShaper SDL_WindowShaper;
+typedef struct SDL_ShapeDriver SDL_ShapeDriver;
typedef struct SDL_VideoDisplay SDL_VideoDisplay;
typedef struct SDL_VideoDevice SDL_VideoDevice;
@@ -97,10 +100,6 @@
int count);
int (*RenderFillRects) (SDL_Renderer * renderer, const SDL_Rect ** rects,
int count);
- int (*RenderDrawEllipse) (SDL_Renderer * renderer, int x, int y,
- int w, int h);
- int (*RenderFillEllipse) (SDL_Renderer * renderer, int x, int y,
- int w, int h);
int (*RenderCopy) (SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * dstrect);
int (*RenderReadPixels) (SDL_Renderer * renderer, const SDL_Rect * rect,
@@ -136,6 +135,33 @@
SDL_RendererInfo info;
};
+/* Define the SDL window-shaper structure */
+struct SDL_WindowShaper
+{
+ /* The window associated with the shaper */
+ SDL_Window *window;
+
+ /* The user's specified SDL_WINDOW_SHOWN flag, for use once the user gives the window a shape. */
+ Uint32 usershownflag;
+
+ /* The cutoff value for alpha-channel binarization. When alpha is greater-than-or-equal-to this value in the shape
+ image, the corresponding pixel of the actual window will be considered part of the window's shape. */
+ Uint8 alphacutoff;
+
+ /* Has this window been assigned a shape? */
+ SDL_bool hasshape;
+
+ void *driverdata;
+};
+
+/* Define the SDL shape driver structure */
+struct SDL_ShapeDriver
+{
+ SDL_WindowShaper *(*CreateShaper)(SDL_Window * window);
+ int (*SetWindowShape)(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode);
+ int (*ResizeWindowShape)(SDL_Window *window);
+};
+
/* Define the SDL window structure, corresponding to toplevel windows */
struct SDL_Window
{
@@ -150,6 +176,8 @@
SDL_Renderer *renderer;
SDL_DisplayMode fullscreen_mode;
+
+ SDL_WindowShaper *shaper;
void *userdata;
void *driverdata;
@@ -270,6 +298,12 @@
void (*RestoreWindow) (_THIS, SDL_Window * window);
void (*SetWindowGrab) (_THIS, SDL_Window * window);
void (*DestroyWindow) (_THIS, SDL_Window * window);
+
+ /* * * */
+ /*
+ * Shaped-window functions
+ */
+ SDL_ShapeDriver shape_driver;
/* Get some platform dependent window information */
SDL_bool(*GetWindowWMInfo) (_THIS, SDL_Window * window,
--- a/src/video/SDL_video.c Mon Jun 21 23:08:10 2010 -0400
+++ b/src/video/SDL_video.c Wed Jun 30 16:19:44 2010 -0400
@@ -2534,38 +2534,6 @@
return renderer->RenderFillRects(renderer, rects, count);
}
-int SDL_RenderDrawEllipse(const SDL_Ellipse ellipse) {
- return SDL_RenderDrawEllipses(&ellipse,1);
-}
-
-int SDL_RenderDrawEllipses(const SDL_Ellipse * ellipse, int count) {
- return -1;
-}
-
-int SDL_RenderFillEllipse(const SDL_Ellipse ellipse) {
- return SDL_RenderFillEllipses(&ellipse,1);
-}
-
-int SDL_RenderFillEllipses(const SDL_Ellipse * ellipse, int count) {
- return -1;
-}
-
-int SDL_RenderDrawPoly(const SDL_Poly poly) {
- return SDL_RenderDrawPolys(&poly,1);
-}
-
-int SDL_RenderDrawPolys(const SDL_Poly *poly, int count) {
- return -1;
-}
-
-int SDL_RenderFillPoly(const SDL_Poly poly) {
- return SDL_RenderFillPolys(&poly,1);
-}
-
-int SDL_RenderFillPolys(const SDL_Poly *poly, int count) {
- return -1;
-}
-
int
SDL_RenderCopy(SDL_Texture * texture, const SDL_Rect * srcrect,
const SDL_Rect * dstrect)
--- a/src/video/x11/SDL_x11shape.c Mon Jun 21 23:08:10 2010 -0400
+++ b/src/video/x11/SDL_x11shape.c Wed Jun 30 16:19:44 2010 -0400
@@ -20,6 +20,69 @@
eligottlieb@gmail.com
*/
-#include "SDL_shape.h"
+#include <X11/Xos.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xmu/Converters.h>
+#include <X11/extensions/shape.h>
+#include "SDL_x11shape.h"
+#include "SDL_x11window.h"
+#include "SDL_x11video.h"
+
+SDL_WindowShaper* X11_CreateShaper(SDL_Window* window) {
+ SDL_WindowShaper* result = malloc(sizeof(SDL_WindowShaper));
+ result->window = window;
+ result->alphacutoff = 0;
+ result->usershownflag = 0;
+ result->driverdata = malloc(sizeof(SDL_ShapeData));
+ window->shaper = result;
+ int resized_properly = X11ResizeWindowShape(window);
+ assert(resized_properly == 0);
+ return result;
+}
-/* Functions implementing shaped-window functionality for X Window System will be implemented when the API is decided. */
+int X11_ResizeWindowShape(SDL_Window* window) {
+ SDL_ShapeData* data = window->shaper->driverdata;
+ assert(data != NULL);
+
+ unsigned int bitmapsize = window->w / 8;
+ if(window->w % 8 > 0)
+ bitmapsize += 1;
+ bitmapsize *= window->h;
+ if(data->bitmapsize != bitmapsize || data->bitmap == NULL) {
+ data->bitmapsize = bitmapsize;
+ if(data->bitmap != NULL)
+ free(data->bitmap);
+ data->bitmap = malloc(data->bitmapsize);
+ if(data->bitmap == NULL) {
+ SDL_SetError("Could not allocate memory for shaped-window bitmap.");
+ return -1;
+ }
+ }
+
+ window->shaper->usershownflag = window->flags & SDL_WINDOW_SHOWN;
+
+ return 0;
+}
+
+int X11_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode) {
+ if(!SDL_ISPIXELFORMAT_ALPHA(SDL_MasksToPixelFormatEnum(shape->format->BitsPerPixel,shape->format->Rmask,shape->format->Gmask,shape->format->Bmask,shape->format->Amask)))
+ return -2;
+ if(shape->w != shaper->window->w || shape->h != shaper->window->h)
+ return -3;
+ SDL_ShapeData *data = shaper->driverdata;
+ assert(data != NULL);
+
+ /* Assume that shaper->alphacutoff already has a value. */
+ SDL_CalculateShapeBitmap(shaper->alphacutoff,shape,data->bitmap);
+
+ SDL_WindowData *windowdata = (SDL_WindowData*)(shaper->window->driverdata);
+ Pixmap shapemask = XCreateBitmapFromData(windowdata->videodata->display,windowdata->xwindow,data->bitmap,shaper->window->w,shaper->window->h);
+
+ XShapeCombineMask(windowdata->videodata->display,windowdata->xwindow, ShapeBounding, 0, 0,shapemask, ShapeSet);
+ XSync(windowdata->videodata->display,False);
+
+ XFreePixmap(windowdata->videodata->display,shapemask);
+
+ return 0;
+}
--- a/src/video/x11/SDL_x11video.c Mon Jun 21 23:08:10 2010 -0400
+++ b/src/video/x11/SDL_x11video.c Wed Jun 30 16:19:44 2010 -0400
@@ -28,6 +28,7 @@
#include "SDL_x11video.h"
#include "SDL_x11render.h"
+#include "SDL_x11shape.h"
#if SDL_VIDEO_DRIVER_PANDORA
#include "SDL_x11opengles.h"
@@ -202,6 +203,9 @@
device->SetWindowGrab = X11_SetWindowGrab;
device->DestroyWindow = X11_DestroyWindow;
device->GetWindowWMInfo = X11_GetWindowWMInfo;
+ device->shape_driver.CreateShaper = X11_CreateShaper;
+ device->shape_driver.SetWindowShape = X11_SetWindowShape;
+ device->shape_driver.ResizeWindowShape = X11_ResizeWindowShape;
#ifdef SDL_VIDEO_OPENGL_GLX
device->GL_LoadLibrary = X11_GL_LoadLibrary;
device->GL_GetProcAddress = X11_GL_GetProcAddress;
--- a/src/video/x11/SDL_x11window.c Mon Jun 21 23:08:10 2010 -0400
+++ b/src/video/x11/SDL_x11window.c Wed Jun 30 16:19:44 2010 -0400
@@ -28,6 +28,7 @@
#include "SDL_x11video.h"
#include "SDL_x11mouse.h"
#include "SDL_x11gamma.h"
+#include "SDL_x11shape.h"
#include "../Xext/extensions/StdCmap.h"
#ifdef SDL_VIDEO_DRIVER_PANDORA
@@ -897,6 +898,8 @@
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
Display *display = data->videodata->display;
+ if(SDL_IsShapedWindow(window))
+ X11_ResizeWindowShape(window);
XResizeWindow(display, data->xwindow, window->w, window->h);
}