Updated test code, updated win32 code a bit (still not complete, but hopefully tonight), and removed the last vestiges of ellipse and polygon drawing support.
authorEli Gottlieb <eligottlieb@gmail.com>
Tue, 06 Jul 2010 22:05:22 -0400
changeset 4785 ef8b32ef9793
parent 4784 2878650e0dc9
child 4786 175da36d1342
Updated test code, updated win32 code a bit (still not complete, but hopefully tonight), and removed the last vestiges of ellipse and polygon drawing support.
include/SDL_ellipse.h
include/SDL_poly.h
include/SDL_video.h
src/video/SDL_shape.c
src/video/win32/SDL_win32shape.c
src/video/x11/SDL_x11shape.c
test/testeyes.c
--- a/include/SDL_ellipse.h	Fri Jul 02 12:05:47 2010 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
-    SDL - Simple DirectMedia Layer
-    Copyright (C) 2010 Eli Gottlieb
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    Eli Gottlieb
-    eligottlieb@gmail.com
-*/
-
-/**
- *  \file SDL_ellipse.h
- *  
- *  Header file for SDL_ellipse definition and management functions.
- */
-
-#ifndef _SDL_ellipse_h
-#define _SDL_ellipse_h
-
-#include "SDL_stdinc.h"
-#include "SDL_error.h"
-#include "SDL_pixels.h"
-#include "SDL_rwops.h"
-
-#include "begin_code.h"
-/* Set up for C function definitions, even when using C++ */
-#ifdef __cplusplus
-/* *INDENT-OFF* */
-extern "C" {
-/* *INDENT-ON* */
-#endif
-
-/**
- *  \brief  The structure that defines an ellipse.
- *
- *  \sa SDL_EllipseEmpty
- *  \sa SDL_EllipseEquals
- *  \sa SDL_EllipsesIntersect
- *  \sa SDL_IntersectEllipseAndLine
- */
-typedef struct SDL_Ellipse {
-	int x,y;
-	int a,b;
-	int r;
-} SDL_Ellipse;
-
-/**
- *  \brief Returns true if the ellipse has no area.
- */
-#define SDL_EllipseEmpty(X)    ((X)->r <= 0)
-
-/**
- *  \brief Returns true if the two ellipses are equal.
- */
-#define SDL_EllipseEquals(A, B)   (((A)->x == (B)->x) && ((A)->y == (B)->y) && \
-                                ((A)->a == (B)->a) && ((A)->b == (B)->b) && ((A)->r == (B)->r))
-
-/**
- *  \brief Determine whether two ellipses intersect.
- *  
- *  \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
- */
-extern DECLSPEC SDL_bool SDLCALL SDL_EllipsesIntersect(const SDL_Ellipse * A,const SDL_Ellipse * B);
-
-/**
- *  \brief Calculate the intersection of an ellipse and line segment.
- *  
- *  \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
- */
-extern DECLSPEC SDL_bool SDLCALL SDL_IntersectEllipseAndLine(const SDL_Ellipse *ellipse,int *X1,int *Y1,int *X2,int *Y2);
-
-/* Ends C function definitions when using C++ */
-#ifdef __cplusplus
-/* *INDENT-OFF* */
-}
-/* *INDENT-ON* */
-#endif
-#include "close_code.h"
-
-#endif /* _SDL_ellipse_h */
--- a/include/SDL_poly.h	Fri Jul 02 12:05:47 2010 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-/*
-    SDL - Simple DirectMedia Layer
-    Copyright (C) 2010 Eli Gottlieb
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    Eli Gottlieb
-    eligottlieb@gmail.com
-*/
-
-/**
- *  \file SDL_poly.h
- *  
- *  Header file for SDL_poly definition and management functions.
- */
-
-#ifndef _SDL_poly_h
-#define _SDL_poly_h
-
-#include "SDL_stdinc.h"
-#include "SDL_error.h"
-#include "SDL_pixels.h"
-#include "SDL_rwops.h"
-#include "SDL_rect.h"
-
-#include "begin_code.h"
-/* Set up for C function definitions, even when using C++ */
-#ifdef __cplusplus
-/* *INDENT-OFF* */
-extern "C" {
-/* *INDENT-ON* */
-#endif
-
-/**
- *  \brief  The structure that defines an polygon.
- *
- *  \sa SDL_PolyEmpty
- *  \sa SDL_PolyEquals
- *  \sa SDL_PolysIntersect
- *  \sa SDL_IntersectPoly
- *  \sa SDL_WrapPoints
- *  \sa SDL_IntersectPolyAndLine
- */
-typedef struct SDL_Poly {
-	SDL_Point *vertices;
-	int count;
-} SDL_Poly;
-
-/**
- *  \brief Returns true if the polygon has no area.
- */
-#define SDL_PolyEmpty(X)    (((X)->vertices == NULL) || ((X)->count <= 2))
-
-/**
- *  \brief Determine whether two polygons are equal.
- *  
- *  \return SDL_TRUE if the polygons are equal, SDL_FALSE otherwise.
- */
-extern DECLSPEC SDL_bool SDLCALL SDL_PolyEquals(const SDL_Poly *A,const SDL_Poly *B);
-
-/**
- *  \brief Determine whether two rectangles intersect.
- *  
- *  \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
- */
-extern DECLSPEC SDL_bool SDLCALL SDL_PolysIntersect(const SDL_Poly * A,const SDL_Poly * B);
-
-/**
- *  \brief Calculate the intersection of two rectangles.
- *  
- *  \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
- */
-extern DECLSPEC SDL_bool SDLCALL SDL_IntersectPoly(const SDL_Poly * A,const SDL_Poly * B,SDL_Poly * result);
-
-/**
- *  \brief Calculate a minimal polygon wrapping a set of points
- *
- *  \return 0 on success, -1 if the parameters were invalid, and -2 if an insufficient number of points were supplied
- *          in the output polygon.
- */
-extern DECLSPEC int SDLCALL SDL_WrapPoints(const SDL_Point * points,int count,SDL_Poly *result);
-
-/**
- *  \brief Calculate the intersection of a polygon and line segment.
- *  
- *  \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
- */
-extern DECLSPEC SDL_bool SDLCALL SDL_IntersectPolyAndLine(const SDL_Poly *poly,int *X1,int *Y1,int *X2,int *Y2);
-                                                   
-/* Ends C function definitions when using C++ */
-#ifdef __cplusplus
-/* *INDENT-OFF* */
-}
-/* *INDENT-ON* */
-#endif
-#include "close_code.h"
-
-#endif /* _SDL_poly_h */
--- a/include/SDL_video.h	Fri Jul 02 12:05:47 2010 -0400
+++ b/include/SDL_video.h	Tue Jul 06 22:05:22 2010 -0400
@@ -32,8 +32,6 @@
 #include "SDL_stdinc.h"
 #include "SDL_pixels.h"
 #include "SDL_rect.h"
-#include "SDL_ellipse.h"
-#include "SDL_poly.h"
 #include "SDL_surface.h"
 
 #include "begin_code.h"
--- a/src/video/SDL_shape.c	Fri Jul 02 12:05:47 2010 -0400
+++ b/src/video/SDL_shape.c	Tue Jul 06 22:05:22 2010 -0400
@@ -45,7 +45,7 @@
 }
 
 /* REQUIRES that bitmap point to a w-by-h bitmap with 1bpp. */
-void SDL_CalculateShapeBitmap(Uint8 alphacutoff,SDL_Surface *shape,Uint8* bitmap) {
+void SDL_CalculateShapeBitmap(Uint8 alphacutoff,SDL_Surface *shape,Uint8* bitmap,Uint8 ppb,Uint8 value) {
 	if(SDL_MUSTLOCK(shape))
 		SDL_LockSurface(shape);
 	int x = 0,y = 0;
@@ -55,7 +55,7 @@
 			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));
+			bitmap[bitmap_pixel / ppb] |= (alpha >= alphacutoff ? value : 0) << ((ppb - 1) - (bitmap_pixel % ppb));
 		}
 	if(SDL_MUSTLOCK(shape))
 		SDL_UnlockSurface(shape);
@@ -81,7 +81,7 @@
 			}
 		}
 	}
-	//TODO: Platform-specific implementations of SetWindowShape.  X11 is in-progress.
+	//TODO: Platform-specific implementations of SetWindowShape.  X11 is finished.  Win32 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) {
--- a/src/video/win32/SDL_win32shape.c	Fri Jul 02 12:05:47 2010 -0400
+++ b/src/video/win32/SDL_win32shape.c	Tue Jul 06 22:05:22 2010 -0400
@@ -20,6 +20,65 @@
     eligottlieb@gmail.com
 */
 
-#include "SDL_shape.h"
+#include <windows.h>
+#include "SDL_win32shape.h"
+
+SDL_WindowShaper* Win32_CreateShaper(SDL_Window * window) {
+	SDL_WindowShaper* result = malloc(sizeof(SDL_WindowShaper));
+	result->window = window;
+	result->alphacutoff = 0;
+	result->usershownflag = 0;
+	//Put some driver-data here.
+	window->shaper = result;
+	int resized_properly = X11ResizeWindowShape(window);
+	assert(resized_properly == 0);
+	return result;
+}
 
-/* Functions implementing shaped windows for Win32 will be implemented when the API is set. */
+int Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode) {
+	assert(shaper != NULL && shape != NULL);
+	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;
+	
+	/* Assume that shaper->alphacutoff already has a value, because SDL_SetWindowShape() should have given it one. */
+	/*
+	 * Start with empty region 
+	 */
+	HRGN MaskRegion = CreateRectRgn(0, 0, 0, 0);
+	
+	unsigned int pitch = shape->pitch;
+	unsigned int width = shape->width;
+	unsigned int height = shape->height;
+	unsigned int dy = pitch - width;
+	
+	SDL_ShapeData *data = (SDL_ShapeData*)shaper->driverdata;
+	/*
+	 * Transfer binarized mask image into workbuffer 
+	 */
+	SDL_CalculateShapeBitmap(shaper->alphacutoff,shape,data->shapebuffer,1,0xff);
+	//Move code over to here from AW_windowShape.c
+	
+}
+
+int Win32_ResizeWindowShape(SDL_Window *window) {
+	SDL_ShapeData* data = window->shaper->driverdata;
+	assert(data != NULL);
+	
+	unsigned int buffersize = window->w * window->h;
+	if(data->buffersize != buffersize || data->shapebuffer == NULL) {
+		data->buffersize = buffersize;
+		if(data->shapebuffer != NULL)
+			free(data->shapebuffer);
+		data->shapebuffer = malloc(data->buffersize);
+		if(data->shapebuffer == NULL) {
+			SDL_SetError("Could not allocate memory for shaped-window bitmap.");
+			return -1;
+		}
+	}
+	
+	window->shaper->usershownflag = window->flags & SDL_WINDOW_SHOWN;
+	
+	return 0;
+}
--- a/src/video/x11/SDL_x11shape.c	Fri Jul 02 12:05:47 2010 -0400
+++ b/src/video/x11/SDL_x11shape.c	Tue Jul 06 22:05:22 2010 -0400
@@ -62,6 +62,7 @@
 }
 	
 int X11_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode) {
+	assert(shaper != NULL && shape != NULL);
 	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)
@@ -69,8 +70,8 @@
 	SDL_ShapeData *data = shaper->driverdata;
 	assert(data != NULL);
 	
-	/* Assume that shaper->alphacutoff already has a value. */
-	SDL_CalculateShapeBitmap(shaper->alphacutoff,shape,data->bitmap);
+	/* Assume that shaper->alphacutoff already has a value, because SDL_SetWindowShape() should have given it one. */
+	SDL_CalculateShapeBitmap(shaper->alphacutoff,shape,data->bitmap,8,1);
 		
 	SDL_WindowData *windowdata = (SDL_WindowData*)(shaper->window->driverdata);
 	Pixmap shapemask = XCreateBitmapFromData(windowdata->videodata->display,windowdata->xwindow,data->bitmap,shaper->window->w,shaper->window->h);
--- a/test/testeyes.c	Fri Jul 02 12:05:47 2010 -0400
+++ b/test/testeyes.c	Tue Jul 06 22:05:22 2010 -0400
@@ -143,7 +143,7 @@
 		exit(-3);
 	}
 	
-	SDL_Color bnw_palette[2] = {{0,0,0,0},{255,255,255,255}};
+	SDL_Color bnw_palette[2] = {{0,0,0,255},{255,255,255,255}};
 	SDL_Texture *eyes_texture = SDL_CreateTexture(SDL_PIXELFORMAT_INDEX1LSB,SDL_TEXTUREACCESS_STREAMING,eyes_width,eyes_height);
 	if(eyes_texture == NULL) {
 		SDL_DestroyRenderer(window);
@@ -162,8 +162,11 @@
 		memcpy(pixels+pitch*row,eyes_bits+(eyes_width/8)*row,eyes_width/8);
 	SDL_UnlockTexture(eyes_texture);
 	
-	SDL_Texture *mask_texture = SDL_CreateTexture(SDL_PIXELFORMAT_INDEX1LSB,SDL_TEXTUREACCESS_STREAMING,eyesmask_width,eyesmask_height);
-	if(mask_texture == NULL) {
+	int bpp = 0;
+	Uint32 r = 0,g = 0,b = 0,a = 0;
+	SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_ARGB4444,&bpp,&r,&g,&b,&a);
+	SDL_Surface *mask = SDL_CreateRGBSurface(0,eyesmask_width,eyesmask_height,bpp,r,g,b,a);
+	if(mask == NULL) {
 		SDL_DestroyTexture(eyes_texture);
 		SDL_DestroyRenderer(window);
 		SDL_DestroyWindow(window);
@@ -171,19 +174,20 @@
 		printf("Could not create shape mask texture.\n");
 		exit(-5);
 	}
-	SDL_SetTexturePalette(mask_texture,bnw_palette,0,2);
 	
-	rect.x = rect.y = 0;
-	rect.w = eyesmask_width;
-	rect.h = eyesmask_height;
-	SDL_LockTexture(mask_texture,&rect,1,&pixels,&pitch);
-	for(int row = 0;row<eyesmask_height;row++)
-		memcpy(pixels+pitch*row,eyesmask_bits+(eyesmask_width/8)*row,eyesmask_width/8);
-	SDL_UnlockTexture(mask_texture);
+	if(SDL_MUSTLOCK(mask))
+		SDL_LockSurface(mask);
+	pixels = mask->pixels;
+	for(int y=0;y<eyesmask_height;y++)
+		for(int x=0;x<eyesmask_width;x++) {
+			Uint8 alpha = *(Uint8*)(eyesmask_bits+(eyesmask_width/8)*y+(x/8)) & (1 << (7 - x % 8)) ? 1 : 0;
+			*(Uint16*)(pixels+pitch*y+x*bpp/8) = SDL_MapRGBA(mask->format,0,0,0,alpha);
+		}
+	if(SDL_MUSTLOCK(mask))
+		SDL_UnlockSurface(mask);
 	
-	SDL_SelectShapeRenderer(window);
-	SDL_RenderCopy(mask_texture,&rect,&rect);
-	SDL_RenderPresent();
+	SDL_WindowShapeMode mode = {ShapeModeDefault,1};
+	SDL_SetWindowShape(window,mask,&mode);
 	
 	SDL_Event event;
 	int event_pending = 0;
@@ -203,6 +207,9 @@
 		event_pending = SDL_PollEvent(&event);
 	}
 	
+	SDL_FreeSurface(mask);
+	SDL_DestroyTexture(eyes_texture);
+	SDL_DestroyWindow(window);
 	//Call SDL_VideoQuit() before quitting.
 	SDL_VideoQuit();
 }