src/video/SDL_shape.c
author Eli Gottlieb <eligottlieb@gmail.com>
Wed, 30 Jun 2010 16:19:44 -0400
changeset 4782 b6930aefd008
parent 4781 fc4c775b468a
child 4785 ef8b32ef9793
permissions -rw-r--r--
Finished X11 shaped-window functionality and removed ellipse+polygon rendering.
eligottlieb@4765
     1
/*
eligottlieb@4765
     2
    SDL - Simple DirectMedia Layer
eligottlieb@4765
     3
    Copyright (C) 2010 Eli Gottlieb
eligottlieb@4765
     4
eligottlieb@4765
     5
    This library is free software; you can redistribute it and/or
eligottlieb@4765
     6
    modify it under the terms of the GNU Lesser General Public
eligottlieb@4765
     7
    License as published by the Free Software Foundation; either
eligottlieb@4765
     8
    version 2.1 of the License, or (at your option) any later version.
eligottlieb@4765
     9
eligottlieb@4765
    10
    This library is distributed in the hope that it will be useful,
eligottlieb@4765
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
eligottlieb@4765
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
eligottlieb@4765
    13
    Lesser General Public License for more details.
eligottlieb@4765
    14
eligottlieb@4765
    15
    You should have received a copy of the GNU Lesser General Public
eligottlieb@4765
    16
    License along with this library; if not, write to the Free Software
eligottlieb@4765
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
eligottlieb@4765
    18
eligottlieb@4765
    19
    Eli Gottlieb
eligottlieb@4765
    20
    eligottlieb@gmail.com
eligottlieb@4765
    21
*/
eligottlieb@4769
    22
#include "SDL_config.h"
eligottlieb@4776
    23
eligottlieb@4769
    24
#include "SDL.h"
eligottlieb@4769
    25
#include "SDL_video.h"
eligottlieb@4769
    26
#include "SDL_sysvideo.h"
eligottlieb@4782
    27
#include "SDL_pixels.h"
eligottlieb@4782
    28
#include "SDL_surface.h"
eligottlieb@4765
    29
#include "SDL_shape.h"
eligottlieb@4766
    30
eligottlieb@4769
    31
SDL_Window* SDL_CreateShapedWindow(const char *title,unsigned int x,unsigned int y,unsigned int w,unsigned int h,Uint32 flags) {
eligottlieb@4782
    32
	SDL_Window *result = SDL_CreateWindow(title,x,y,w,h,SDL_WINDOW_BORDERLESS | flags & !SDL_WINDOW_FULLSCREEN & !SDL_WINDOW_SHOWN);
eligottlieb@4782
    33
	result->shaper = result->display->device->shape_driver.CreateShaper(result);
eligottlieb@4782
    34
	result->shaper->usershownflag = flags & SDL_WINDOW_SHOWN;
eligottlieb@4782
    35
	result->shaper->alphacutoff = 1;
eligottlieb@4782
    36
	result->shaper->hasshape = SDL_FALSE;
eligottlieb@4782
    37
	return result;
eligottlieb@4766
    38
}
eligottlieb@4766
    39
eligottlieb@4781
    40
SDL_bool SDL_IsShapedWindow(const SDL_Window *window) {
eligottlieb@4782
    41
	if(window == NULL)
eligottlieb@4782
    42
		return SDL_FALSE;
eligottlieb@4782
    43
	else
eligottlieb@4782
    44
		return window->shaper != NULL;
eligottlieb@4782
    45
}
eligottlieb@4782
    46
eligottlieb@4782
    47
/* REQUIRES that bitmap point to a w-by-h bitmap with 1bpp. */
eligottlieb@4782
    48
void SDL_CalculateShapeBitmap(Uint8 alphacutoff,SDL_Surface *shape,Uint8* bitmap) {
eligottlieb@4782
    49
	if(SDL_MUSTLOCK(shape))
eligottlieb@4782
    50
		SDL_LockSurface(shape);
eligottlieb@4782
    51
	int x = 0,y = 0;
eligottlieb@4782
    52
	for(x = 0;x<shape->w;x++)
eligottlieb@4782
    53
		for(y = 0;y<shape->h;y++) {
eligottlieb@4782
    54
			void* pixel = shape->pixels + (y*shape->pitch) + (x*shape->format->BytesPerPixel);
eligottlieb@4782
    55
			Uint8 alpha = 0;
eligottlieb@4782
    56
			SDL_GetRGBA(*(Uint32*)pixel,shape->format,NULL,NULL,NULL,&alpha);
eligottlieb@4782
    57
			Uint32 bitmap_pixel = y*shape->w + x;
eligottlieb@4782
    58
			bitmap[bitmap_pixel / 8] |= (alpha >= alphacutoff ? 1 : 0) << (8 - (bitmap_pixel % 8));
eligottlieb@4782
    59
		}
eligottlieb@4782
    60
	if(SDL_MUSTLOCK(shape))
eligottlieb@4782
    61
		SDL_UnlockSurface(shape);
eligottlieb@4769
    62
}
eligottlieb@4769
    63
eligottlieb@4781
    64
int SDL_SetWindowShape(SDL_Window *window,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode) {
eligottlieb@4778
    65
	if(window == NULL || !SDL_WindowIsShaped(window))
eligottlieb@4782
    66
		//The window given was not a shapeable window.
eligottlieb@4778
    67
		return -2;
eligottlieb@4780
    68
	if(shape == NULL)
eligottlieb@4782
    69
		//Invalid shape argument.
eligottlieb@4780
    70
		return -1;
eligottlieb@4782
    71
	
eligottlieb@4782
    72
	if(shapeMode != NULL) {
eligottlieb@4782
    73
		switch(shapeMode->mode) {
eligottlieb@4782
    74
			case ShapeModeDefault: {
eligottlieb@4782
    75
				window->shaper->alphacutoff = 1;
eligottlieb@4782
    76
				break;
eligottlieb@4782
    77
			}
eligottlieb@4782
    78
			case ShapeModeBinarizeAlpha: {
eligottlieb@4782
    79
				window->shaper->alphacutoff = shapeMode->parameters.binarizationCutoff;
eligottlieb@4782
    80
				break;
eligottlieb@4782
    81
			}
eligottlieb@4782
    82
		}
eligottlieb@4782
    83
	}
eligottlieb@4782
    84
	//TODO: Platform-specific implementations of SetWindowShape.  X11 is in-progress.
eligottlieb@4782
    85
	int result = window->display->device->shape_driver.SetWindowShape(window->shaper,shape,shapeMode);
eligottlieb@4782
    86
	window->shaper->hasshape = SDL_TRUE;
eligottlieb@4782
    87
	if(window->shaper->usershownflag & SDL_WINDOW_SHOWN == SDL_WINDOW_SHOWN) {
eligottlieb@4782
    88
		SDL_ShowWindow(window);
eligottlieb@4782
    89
		window->shaper->usershownflag &= !SDL_WINDOW_SHOWN;
eligottlieb@4782
    90
	}
eligottlieb@4782
    91
	return result;
eligottlieb@4782
    92
}
eligottlieb@4782
    93
eligottlieb@4782
    94
SDL_bool SDL_WindowHasAShape(SDL_Window *window) {
eligottlieb@4782
    95
	assert(window != NULL && SDL_IsShapedWindow(window));
eligottlieb@4782
    96
	return window->shaper->hasshape;
eligottlieb@4778
    97
}
eligottlieb@4778
    98
eligottlieb@4781
    99
int SDL_GetShapedWindowMode(SDL_Window *window,SDL_WindowShapeMode *shapeMode) {
eligottlieb@4782
   100
	if(window != NULL && SDL_IsShapedWindow(window)) {
eligottlieb@4782
   101
		if(shapeMode == NULL) {
eligottlieb@4782
   102
			if(SDL_WindowHasAShape(window))
eligottlieb@4782
   103
				//The window given has a shape.
eligottlieb@4782
   104
				return 0;
eligottlieb@4782
   105
			else
eligottlieb@4782
   106
				//The window given is shapeable but lacks a shape.
eligottlieb@4782
   107
				return -2;
eligottlieb@4782
   108
		}
eligottlieb@4782
   109
		else {
eligottlieb@4782
   110
			if(window->shaper->alphacutoff != 1) {
eligottlieb@4782
   111
				shapeMode->mode = ShapeModeBinarizeAlpha;
eligottlieb@4782
   112
				shapeMode->parameters.binarizationCutoff = window->shaper->alphacutoff;
eligottlieb@4782
   113
			}
eligottlieb@4782
   114
			else
eligottlieb@4782
   115
				shapeMode->mode = ShapeModeDefault;
eligottlieb@4782
   116
			return 0;
eligottlieb@4782
   117
		}
eligottlieb@4782
   118
	}
eligottlieb@4782
   119
	else
eligottlieb@4782
   120
		//The window given is not a valid shapeable window.
eligottlieb@4778
   121
		return -1;
eligottlieb@4778
   122
}