diff src/video/SDL_shape.c @ 4782:b6930aefd008

Finished X11 shaped-window functionality and removed ellipse+polygon rendering.
author Eli Gottlieb <eligottlieb@gmail.com>
date Wed, 30 Jun 2010 16:19:44 -0400
parents fc4c775b468a
children ef8b32ef9793
line wrap: on
line diff
--- 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;
 }