1 /*
2   Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
3 
4   This software is provided 'as-is', without any express or implied
5   warranty.  In no event will the authors be held liable for any damages
6   arising from the use of this software.
7 
8   Permission is granted to anyone to use this software for any purpose,
9   including commercial applications, and to alter it and redistribute it
10   freely.
11 */
12 #include <stdlib.h>
13 #include <math.h>
14 #include <stdio.h>
15 #include "SDL.h"
16 #include "SDL_shape.h"
17 
18 #define SHAPED_WINDOW_X 150
19 #define SHAPED_WINDOW_Y 150
20 #define SHAPED_WINDOW_DIMENSION 640
21 
22 typedef struct LoadedPicture {
23     SDL_Surface *surface;
24     SDL_Texture *texture;
25     SDL_WindowShapeMode mode;
26     const char* name;
27 } LoadedPicture;
28 
render(SDL_Renderer * renderer,SDL_Texture * texture,SDL_Rect texture_dimensions)29 void render(SDL_Renderer *renderer,SDL_Texture *texture,SDL_Rect texture_dimensions)
30 {
31     /* Clear render-target to blue. */
32     SDL_SetRenderDrawColor(renderer,0x00,0x00,0xff,0xff);
33     SDL_RenderClear(renderer);
34 
35     /* Render the texture. */
36     SDL_RenderCopy(renderer,texture,&texture_dimensions,&texture_dimensions);
37 
38     SDL_RenderPresent(renderer);
39 }
40 
main(int argc,char ** argv)41 int main(int argc,char** argv)
42 {
43     Uint8 num_pictures;
44     LoadedPicture* pictures;
45     int i, j;
46     SDL_PixelFormat* format = NULL;
47     SDL_Window *window;
48     SDL_Renderer *renderer;
49     SDL_Color black = {0,0,0,0xff};
50     SDL_Event event;
51     int should_exit = 0;
52     unsigned int current_picture;
53     int button_down;
54     Uint32 pixelFormat = 0;
55     int access = 0;
56     SDL_Rect texture_dimensions;
57 
58     /* Enable standard application logging */
59     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
60 
61     if(argc < 2) {
62         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Shape requires at least one bitmap file as argument.");
63         exit(-1);
64     }
65 
66     if(SDL_VideoInit(NULL) == -1) {
67         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not initialize SDL video.");
68         exit(-2);
69     }
70 
71     num_pictures = argc - 1;
72     pictures = (LoadedPicture *)SDL_malloc(sizeof(LoadedPicture)*num_pictures);
73     if (!pictures) {
74         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not allocate memory.");
75         exit(1);
76     }
77     for(i=0;i<num_pictures;i++)
78         pictures[i].surface = NULL;
79     for(i=0;i<num_pictures;i++) {
80         pictures[i].surface = SDL_LoadBMP(argv[i+1]);
81         pictures[i].name = argv[i+1];
82         if(pictures[i].surface == NULL) {
83             for(j=0;j<num_pictures;j++)
84                 SDL_FreeSurface(pictures[j].surface);
85             SDL_free(pictures);
86             SDL_VideoQuit();
87             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not load surface from named bitmap file: %s", argv[i+1]);
88             exit(-3);
89         }
90 
91         format = pictures[i].surface->format;
92         if(SDL_ISPIXELFORMAT_ALPHA(format->format)) {
93             pictures[i].mode.mode = ShapeModeBinarizeAlpha;
94             pictures[i].mode.parameters.binarizationCutoff = 255;
95         }
96         else {
97             pictures[i].mode.mode = ShapeModeColorKey;
98             pictures[i].mode.parameters.colorKey = black;
99         }
100     }
101 
102     window = SDL_CreateShapedWindow("SDL_Shape test",
103         SHAPED_WINDOW_X, SHAPED_WINDOW_Y,
104         SHAPED_WINDOW_DIMENSION,SHAPED_WINDOW_DIMENSION,
105         0);
106     SDL_SetWindowPosition(window, SHAPED_WINDOW_X, SHAPED_WINDOW_Y);
107     if(window == NULL) {
108         for(i=0;i<num_pictures;i++)
109             SDL_FreeSurface(pictures[i].surface);
110         SDL_free(pictures);
111         SDL_VideoQuit();
112         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not create shaped window for SDL_Shape.");
113         exit(-4);
114     }
115     renderer = SDL_CreateRenderer(window,-1,0);
116     if (!renderer) {
117         SDL_DestroyWindow(window);
118         for(i=0;i<num_pictures;i++)
119             SDL_FreeSurface(pictures[i].surface);
120         SDL_free(pictures);
121         SDL_VideoQuit();
122         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not create rendering context for SDL_Shape window.");
123         exit(-5);
124     }
125 
126     for(i=0;i<num_pictures;i++)
127         pictures[i].texture = NULL;
128     for(i=0;i<num_pictures;i++) {
129         pictures[i].texture = SDL_CreateTextureFromSurface(renderer,pictures[i].surface);
130         if(pictures[i].texture == NULL) {
131             for(i=0;i<num_pictures;i++)
132                 if(pictures[i].texture != NULL)
133                     SDL_DestroyTexture(pictures[i].texture);
134             for(i=0;i<num_pictures;i++)
135                 SDL_FreeSurface(pictures[i].surface);
136             SDL_free(pictures);
137             SDL_DestroyRenderer(renderer);
138             SDL_DestroyWindow(window);
139             SDL_VideoQuit();
140             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not create texture for SDL_shape.");
141             exit(-6);
142         }
143     }
144 
145     should_exit = 0;
146     current_picture = 0;
147     button_down = 0;
148     texture_dimensions.h = 0;
149     texture_dimensions.w = 0;
150     texture_dimensions.x = 0;
151     texture_dimensions.y = 0;
152     SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Changing to shaped bmp: %s", pictures[current_picture].name);
153     SDL_QueryTexture(pictures[current_picture].texture,(Uint32 *)&pixelFormat,(int *)&access,&texture_dimensions.w,&texture_dimensions.h);
154     SDL_SetWindowSize(window,texture_dimensions.w,texture_dimensions.h);
155     SDL_SetWindowShape(window,pictures[current_picture].surface,&pictures[current_picture].mode);
156     while(should_exit == 0) {
157         while (SDL_PollEvent(&event)) {
158             if(event.type == SDL_KEYDOWN) {
159                 button_down = 1;
160                 if(event.key.keysym.sym == SDLK_ESCAPE) {
161                     should_exit = 1;
162                     break;
163                 }
164             }
165             if(button_down && event.type == SDL_KEYUP) {
166                 button_down = 0;
167                 current_picture += 1;
168                 if(current_picture >= num_pictures)
169                     current_picture = 0;
170                 SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Changing to shaped bmp: %s", pictures[current_picture].name);
171                 SDL_QueryTexture(pictures[current_picture].texture,(Uint32 *)&pixelFormat,(int *)&access,&texture_dimensions.w,&texture_dimensions.h);
172                 SDL_SetWindowSize(window,texture_dimensions.w,texture_dimensions.h);
173                 SDL_SetWindowShape(window,pictures[current_picture].surface,&pictures[current_picture].mode);
174             }
175             if (event.type == SDL_QUIT) {
176                 should_exit = 1;
177                 break;
178             }
179         }
180         render(renderer,pictures[current_picture].texture,texture_dimensions);
181         SDL_Delay(10);
182     }
183 
184     /* Free the textures. */
185     for(i=0;i<num_pictures;i++)
186         SDL_DestroyTexture(pictures[i].texture);
187     SDL_DestroyRenderer(renderer);
188     /* Destroy the window. */
189     SDL_DestroyWindow(window);
190     /* Free the original surfaces backing the textures. */
191     for(i=0;i<num_pictures;i++)
192         SDL_FreeSurface(pictures[i].surface);
193     SDL_free(pictures);
194     /* Call SDL_VideoQuit() before quitting. */
195     SDL_VideoQuit();
196 
197     return 0;
198 }
199 
200 /* vi: set ts=4 sw=4 expandtab: */
201