Commit ea29eee8 authored by Eli Gottlieb's avatar Eli Gottlieb

Finished X11 shaped-window functionality and removed ellipse+polygon rendering.

parent 2c8b1ce8
......@@ -44,7 +44,7 @@ EMBEDSPU = @EMBEDSPU@
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@
......
......@@ -114,10 +114,11 @@ extern DECLSPEC int SDLCALL SDL_SetWindowShape(SDL_Window *window,SDL_Surface *s
* \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
......
......@@ -1239,82 +1239,6 @@ extern DECLSPEC int SDLCALL SDL_RenderFillRect(const SDL_Rect * rect);
*/
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.
*
......
......@@ -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;
}
......@@ -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 @@ struct SDL_Renderer
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 @@ struct SDL_RenderDriver
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 @@ struct SDL_Window
SDL_Renderer *renderer;
SDL_DisplayMode fullscreen_mode;
SDL_WindowShaper *shaper;
void *userdata;
void *driverdata;
......@@ -270,6 +298,12 @@ struct SDL_VideoDevice
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,
......
......@@ -2534,38 +2534,6 @@ SDL_RenderFillRects(const SDL_Rect ** rects, int count)
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)
......
......@@ -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"
/* Functions implementing shaped-window functionality for X Window System will be implemented when the API is decided. */
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;
}
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;
}
......@@ -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 @@ X11_CreateDevice(int devindex)
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;
......
......@@ -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 @@ X11_SetWindowSize(_THIS, SDL_Window * window)
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);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment