src/video/x11/SDL_x11shape.c
author Ryan C. Gordon <icculus@icculus.org>
Tue, 13 Jul 2010 02:43:49 -0400
changeset 4794 e562160a873f
parent 4791 e07cd9e86d7a
child 4795 6f0bc179771c
permissions -rw-r--r--
Check configure-defined macro before doing _anything_ with XShape.
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@4782
    28
SDL_WindowShaper* X11_CreateShaper(SDL_Window* window) {
icculus@4791
    29
	SDL_WindowShaper* result = NULL;
icculus@4794
    30
icculus@4794
    31
#if SDL_VIDEO_DRIVER_X11_XSHAPE
icculus@4791
    32
	if (SDL_X11_HAVE_XSHAPE) {  /* Make sure X server supports it. */
icculus@4791
    33
		result = malloc(sizeof(SDL_WindowShaper));
icculus@4791
    34
		result->window = window;
icculus@4791
    35
		result->alphacutoff = 0;
icculus@4791
    36
		result->usershownflag = 0;
icculus@4791
    37
		result->driverdata = malloc(sizeof(SDL_ShapeData));
icculus@4791
    38
		window->shaper = result;
icculus@4791
    39
		int resized_properly = X11_ResizeWindowShape(window);
icculus@4791
    40
		assert(resized_properly == 0);
icculus@4791
    41
	}
icculus@4794
    42
#endif
icculus@4791
    43
eligottlieb@4782
    44
	return result;
eligottlieb@4782
    45
}
eligottlieb@4782
    46
eligottlieb@4782
    47
int X11_ResizeWindowShape(SDL_Window* window) {
eligottlieb@4782
    48
	SDL_ShapeData* data = window->shaper->driverdata;
eligottlieb@4782
    49
	assert(data != NULL);
eligottlieb@4782
    50
	
eligottlieb@4782
    51
	unsigned int bitmapsize = window->w / 8;
eligottlieb@4782
    52
	if(window->w % 8 > 0)
eligottlieb@4782
    53
		bitmapsize += 1;
eligottlieb@4782
    54
	bitmapsize *= window->h;
eligottlieb@4782
    55
	if(data->bitmapsize != bitmapsize || data->bitmap == NULL) {
eligottlieb@4782
    56
		data->bitmapsize = bitmapsize;
eligottlieb@4782
    57
		if(data->bitmap != NULL)
eligottlieb@4782
    58
			free(data->bitmap);
eligottlieb@4782
    59
		data->bitmap = malloc(data->bitmapsize);
eligottlieb@4782
    60
		if(data->bitmap == NULL) {
eligottlieb@4782
    61
			SDL_SetError("Could not allocate memory for shaped-window bitmap.");
eligottlieb@4782
    62
			return -1;
eligottlieb@4782
    63
		}
eligottlieb@4782
    64
	}
eligottlieb@4782
    65
	
eligottlieb@4782
    66
	window->shaper->usershownflag = window->flags & SDL_WINDOW_SHOWN;
eligottlieb@4782
    67
	
eligottlieb@4782
    68
	return 0;
eligottlieb@4782
    69
}
eligottlieb@4782
    70
	
eligottlieb@4782
    71
int X11_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode) {
eligottlieb@4787
    72
	if(shaper == NULL || shape == NULL || shaper->driverdata == NULL)
eligottlieb@4787
    73
		return -1;
icculus@4794
    74
icculus@4794
    75
#if SDL_VIDEO_DRIVER_X11_XSHAPE
eligottlieb@4782
    76
	if(!SDL_ISPIXELFORMAT_ALPHA(SDL_MasksToPixelFormatEnum(shape->format->BitsPerPixel,shape->format->Rmask,shape->format->Gmask,shape->format->Bmask,shape->format->Amask)))
eligottlieb@4782
    77
		return -2;
eligottlieb@4782
    78
	if(shape->w != shaper->window->w || shape->h != shaper->window->h)
eligottlieb@4782
    79
		return -3;
eligottlieb@4782
    80
	SDL_ShapeData *data = shaper->driverdata;
eligottlieb@4782
    81
	
eligottlieb@4785
    82
	/* Assume that shaper->alphacutoff already has a value, because SDL_SetWindowShape() should have given it one. */
eligottlieb@4785
    83
	SDL_CalculateShapeBitmap(shaper->alphacutoff,shape,data->bitmap,8,1);
eligottlieb@4782
    84
		
eligottlieb@4782
    85
	SDL_WindowData *windowdata = (SDL_WindowData*)(shaper->window->driverdata);
eligottlieb@4782
    86
	Pixmap shapemask = XCreateBitmapFromData(windowdata->videodata->display,windowdata->xwindow,data->bitmap,shaper->window->w,shaper->window->h);
eligottlieb@4782
    87
	
eligottlieb@4782
    88
	XShapeCombineMask(windowdata->videodata->display,windowdata->xwindow, ShapeBounding, 0, 0,shapemask, ShapeSet);
eligottlieb@4782
    89
	XSync(windowdata->videodata->display,False);
eligottlieb@4782
    90
eligottlieb@4782
    91
	XFreePixmap(windowdata->videodata->display,shapemask);
icculus@4794
    92
#endif
icculus@4794
    93
eligottlieb@4782
    94
	return 0;
eligottlieb@4782
    95
}