src/video/x11/SDL_x11shape.c
author Eli Gottlieb <eligottlieb@gmail.com>
Mon, 26 Jul 2010 17:27:04 -0400
changeset 4809 329708ffe2a7
parent 4807 c9eb95f29770
child 4817 c68e7490e4cf
permissions -rw-r--r--
Rejiggering the way shaped windows are created as preparation for OS X implementation. Fixed overdrive bug in test program that appears to have been introduced by someone other than myself.
eligottlieb@4777
     1
/*
eligottlieb@4777
     2
    SDL - Simple DirectMedia Layer
eligottlieb@4777
     3
    Copyright (C) 2010 Eli Gottlieb
eligottlieb@4777
     4
eligottlieb@4777
     5
    This library is free software; you can redistribute it and/or
eligottlieb@4777
     6
    modify it under the terms of the GNU Lesser General Public
eligottlieb@4777
     7
    License as published by the Free Software Foundation; either
eligottlieb@4777
     8
    version 2.1 of the License, or (at your option) any later version.
eligottlieb@4777
     9
eligottlieb@4777
    10
    This library is distributed in the hope that it will be useful,
eligottlieb@4777
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
eligottlieb@4777
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
eligottlieb@4777
    13
    Lesser General Public License for more details.
eligottlieb@4777
    14
eligottlieb@4777
    15
    You should have received a copy of the GNU Lesser General Public
eligottlieb@4777
    16
    License along with this library; if not, write to the Free Software
eligottlieb@4777
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
eligottlieb@4777
    18
eligottlieb@4777
    19
    Eli Gottlieb
eligottlieb@4777
    20
    eligottlieb@gmail.com
eligottlieb@4777
    21
*/
eligottlieb@4777
    22
eligottlieb@4786
    23
#include <assert.h>
icculus@4794
    24
#include "SDL_x11video.h"
eligottlieb@4782
    25
#include "SDL_x11shape.h"
eligottlieb@4782
    26
#include "SDL_x11window.h"
eligottlieb@4777
    27
eligottlieb@4809
    28
SDL_Window* X11_CreateShapedWindow(const char *title,unsigned int x,unsigned int y,unsigned int w,unsigned int h,Uint32 flags) {
eligottlieb@4809
    29
	return SDL_CreateWindow(title,x,y,w,h,flags);
eligottlieb@4809
    30
}
eligottlieb@4809
    31
eligottlieb@4782
    32
SDL_WindowShaper* X11_CreateShaper(SDL_Window* window) {
icculus@4791
    33
	SDL_WindowShaper* result = NULL;
icculus@4794
    34
icculus@4794
    35
#if SDL_VIDEO_DRIVER_X11_XSHAPE
icculus@4791
    36
	if (SDL_X11_HAVE_XSHAPE) {  /* Make sure X server supports it. */
icculus@4791
    37
		result = malloc(sizeof(SDL_WindowShaper));
icculus@4791
    38
		result->window = window;
eligottlieb@4807
    39
		result->mode.mode = ShapeModeDefault;
eligottlieb@4807
    40
		result->mode.parameters.binarizationCutoff = 1;
icculus@4791
    41
		result->usershownflag = 0;
eligottlieb@4795
    42
		SDL_ShapeData* data = malloc(sizeof(SDL_ShapeData));
eligottlieb@4795
    43
		result->driverdata = data;
eligottlieb@4795
    44
		data->bitmapsize = 0;
eligottlieb@4795
    45
		data->bitmap = NULL;
icculus@4791
    46
		window->shaper = result;
icculus@4791
    47
		int resized_properly = X11_ResizeWindowShape(window);
icculus@4791
    48
		assert(resized_properly == 0);
icculus@4791
    49
	}
icculus@4794
    50
#endif
icculus@4791
    51
eligottlieb@4782
    52
	return result;
eligottlieb@4782
    53
}
eligottlieb@4782
    54
eligottlieb@4782
    55
int X11_ResizeWindowShape(SDL_Window* window) {
eligottlieb@4782
    56
	SDL_ShapeData* data = window->shaper->driverdata;
eligottlieb@4782
    57
	assert(data != NULL);
eligottlieb@4782
    58
	
eligottlieb@4782
    59
	unsigned int bitmapsize = window->w / 8;
eligottlieb@4782
    60
	if(window->w % 8 > 0)
eligottlieb@4782
    61
		bitmapsize += 1;
eligottlieb@4782
    62
	bitmapsize *= window->h;
eligottlieb@4782
    63
	if(data->bitmapsize != bitmapsize || data->bitmap == NULL) {
eligottlieb@4782
    64
		data->bitmapsize = bitmapsize;
eligottlieb@4782
    65
		if(data->bitmap != NULL)
eligottlieb@4782
    66
			free(data->bitmap);
eligottlieb@4782
    67
		data->bitmap = malloc(data->bitmapsize);
eligottlieb@4782
    68
		if(data->bitmap == NULL) {
eligottlieb@4782
    69
			SDL_SetError("Could not allocate memory for shaped-window bitmap.");
eligottlieb@4782
    70
			return -1;
eligottlieb@4782
    71
		}
eligottlieb@4782
    72
	}
eligottlieb@4807
    73
	else
eligottlieb@4807
    74
		memset(data->bitmap,0,data->bitmapsize);
eligottlieb@4782
    75
	
eligottlieb@4802
    76
	window->shaper->usershownflag |= window->flags & SDL_WINDOW_SHOWN;
eligottlieb@4782
    77
	
eligottlieb@4782
    78
	return 0;
eligottlieb@4782
    79
}
eligottlieb@4782
    80
	
eligottlieb@4782
    81
int X11_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode) {
eligottlieb@4787
    82
	if(shaper == NULL || shape == NULL || shaper->driverdata == NULL)
eligottlieb@4787
    83
		return -1;
icculus@4794
    84
icculus@4794
    85
#if SDL_VIDEO_DRIVER_X11_XSHAPE
eligottlieb@4782
    86
	if(!SDL_ISPIXELFORMAT_ALPHA(SDL_MasksToPixelFormatEnum(shape->format->BitsPerPixel,shape->format->Rmask,shape->format->Gmask,shape->format->Bmask,shape->format->Amask)))
eligottlieb@4782
    87
		return -2;
eligottlieb@4782
    88
	if(shape->w != shaper->window->w || shape->h != shaper->window->h)
eligottlieb@4782
    89
		return -3;
eligottlieb@4782
    90
	SDL_ShapeData *data = shaper->driverdata;
eligottlieb@4782
    91
	
eligottlieb@4785
    92
	/* Assume that shaper->alphacutoff already has a value, because SDL_SetWindowShape() should have given it one. */
eligottlieb@4807
    93
	SDL_CalculateShapeBitmap(shaper->mode,shape,data->bitmap,8,1);
eligottlieb@4782
    94
		
eligottlieb@4782
    95
	SDL_WindowData *windowdata = (SDL_WindowData*)(shaper->window->driverdata);
eligottlieb@4782
    96
	Pixmap shapemask = XCreateBitmapFromData(windowdata->videodata->display,windowdata->xwindow,data->bitmap,shaper->window->w,shaper->window->h);
eligottlieb@4782
    97
	
eligottlieb@4782
    98
	XShapeCombineMask(windowdata->videodata->display,windowdata->xwindow, ShapeBounding, 0, 0,shapemask, ShapeSet);
eligottlieb@4782
    99
	XSync(windowdata->videodata->display,False);
eligottlieb@4782
   100
eligottlieb@4782
   101
	XFreePixmap(windowdata->videodata->display,shapemask);
icculus@4794
   102
#endif
icculus@4794
   103
eligottlieb@4782
   104
	return 0;
eligottlieb@4782
   105
}