1 | /* |
2 | Simple DirectMedia Layer |
3 | Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org> |
4 | |
5 | This software is provided 'as-is', without any express or implied |
6 | warranty. In no event will the authors be held liable for any damages |
7 | arising from the use of this software. |
8 | |
9 | Permission is granted to anyone to use this software for any purpose, |
10 | including commercial applications, and to alter it and redistribute it |
11 | freely, subject to the following restrictions: |
12 | |
13 | 1. The origin of this software must not be misrepresented; you must not |
14 | claim that you wrote the original software. If you use this software |
15 | in a product, an acknowledgment in the product documentation would be |
16 | appreciated but is not required. |
17 | 2. Altered source versions must be plainly marked as such, and must not be |
18 | misrepresented as being the original software. |
19 | 3. This notice may not be removed or altered from any source distribution. |
20 | */ |
21 | #include "../../SDL_internal.h" |
22 | |
23 | #if SDL_VIDEO_DRIVER_X11 |
24 | |
25 | #include "SDL_x11video.h" |
26 | #include "SDL_x11shape.h" |
27 | #include "SDL_x11window.h" |
28 | #include "../SDL_shape_internals.h" |
29 | |
30 | SDL_WindowShaper* |
31 | X11_CreateShaper(SDL_Window* window) { |
32 | SDL_WindowShaper* result = NULL; |
33 | SDL_ShapeData* data = NULL; |
34 | int resized_properly; |
35 | |
36 | #if SDL_VIDEO_DRIVER_X11_XSHAPE |
37 | if (SDL_X11_HAVE_XSHAPE) { /* Make sure X server supports it. */ |
38 | result = malloc(sizeof(SDL_WindowShaper)); |
39 | result->window = window; |
40 | result->mode.mode = ShapeModeDefault; |
41 | result->mode.parameters.binarizationCutoff = 1; |
42 | result->userx = result->usery = 0; |
43 | data = SDL_malloc(sizeof(SDL_ShapeData)); |
44 | result->driverdata = data; |
45 | data->bitmapsize = 0; |
46 | data->bitmap = NULL; |
47 | window->shaper = result; |
48 | resized_properly = X11_ResizeWindowShape(window); |
49 | SDL_assert(resized_properly == 0); |
50 | } |
51 | #endif |
52 | |
53 | return result; |
54 | } |
55 | |
56 | int |
57 | X11_ResizeWindowShape(SDL_Window* window) { |
58 | SDL_ShapeData* data = window->shaper->driverdata; |
59 | unsigned int bitmapsize = window->w / 8; |
60 | SDL_assert(data != NULL); |
61 | |
62 | if(window->w % 8 > 0) |
63 | bitmapsize += 1; |
64 | bitmapsize *= window->h; |
65 | if(data->bitmapsize != bitmapsize || data->bitmap == NULL) { |
66 | data->bitmapsize = bitmapsize; |
67 | if(data->bitmap != NULL) |
68 | free(data->bitmap); |
69 | data->bitmap = malloc(data->bitmapsize); |
70 | if(data->bitmap == NULL) { |
71 | return SDL_SetError("Could not allocate memory for shaped-window bitmap." ); |
72 | } |
73 | } |
74 | memset(data->bitmap,0,data->bitmapsize); |
75 | |
76 | window->shaper->userx = window->x; |
77 | window->shaper->usery = window->y; |
78 | SDL_SetWindowPosition(window,-1000,-1000); |
79 | |
80 | return 0; |
81 | } |
82 | |
83 | int |
84 | X11_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode) { |
85 | SDL_ShapeData *data = NULL; |
86 | SDL_WindowData *windowdata = NULL; |
87 | Pixmap shapemask; |
88 | |
89 | if(shaper == NULL || shape == NULL || shaper->driverdata == NULL) |
90 | return -1; |
91 | |
92 | #if SDL_VIDEO_DRIVER_X11_XSHAPE |
93 | if(shape->format->Amask == 0 && SDL_SHAPEMODEALPHA(shape_mode->mode)) |
94 | return -2; |
95 | if(shape->w != shaper->window->w || shape->h != shaper->window->h) |
96 | return -3; |
97 | data = shaper->driverdata; |
98 | |
99 | /* Assume that shaper->alphacutoff already has a value, because SDL_SetWindowShape() should have given it one. */ |
100 | SDL_CalculateShapeBitmap(shaper->mode,shape,data->bitmap,8); |
101 | |
102 | windowdata = (SDL_WindowData*)(shaper->window->driverdata); |
103 | shapemask = X11_XCreateBitmapFromData(windowdata->videodata->display,windowdata->xwindow,data->bitmap,shaper->window->w,shaper->window->h); |
104 | |
105 | X11_XShapeCombineMask(windowdata->videodata->display,windowdata->xwindow, ShapeBounding, 0, 0,shapemask, ShapeSet); |
106 | X11_XSync(windowdata->videodata->display,False); |
107 | |
108 | X11_XFreePixmap(windowdata->videodata->display,shapemask); |
109 | #endif |
110 | |
111 | return 0; |
112 | } |
113 | |
114 | #endif /* SDL_VIDEO_DRIVER_X11 */ |
115 | |