1 /*
2   Copyright (C) 1997-2016 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 event_pending = 0;
52     int should_exit = 0;
53     unsigned int current_picture;
54     int button_down;
55     Uint32 pixelFormat = 0;
56     int access = 0;
57     SDL_Rect texture_dimensions;
58 
59     /* Enable standard application logging */
60     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
61 
62     if(argc < 2) {
63         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Shape requires at least one bitmap file as argument.");
64         exit(-1);
65     }
66 
67     if(SDL_VideoInit(NULL) == -1) {
68         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not initialize SDL video.");
69         exit(-2);
70     }
71 
72     num_pictures = argc - 1;
73     pictures = (LoadedPicture *)SDL_malloc(sizeof(LoadedPicture)*num_pictures);
74     if (!pictures) {
75         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not allocate memory.");
76         exit(1);
77     }
78     for(i=0;i<num_pictures;i++)
79         pictures[i].surface = NULL;
80     for(i=0;i<num_pictures;i++) {
81         pictures[i].surface = SDL_LoadBMP(argv[i+1]);
82         pictures[i].name = argv[i+1];
83         if(pictures[i].surface == NULL) {
84             j = 0;
85             for(j=0;j<num_pictures;j++)
86                 SDL_FreeSurface(pictures[j].surface);
87             SDL_free(pictures);
88             SDL_VideoQuit();
89             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not load surface from named bitmap file: %s", argv[i+1]);
90             exit(-3);
91         }
92 
93         format = pictures[i].surface->format;
94         if(SDL_ISPIXELFORMAT_ALPHA(format->format)) {
95             pictures[i].mode.mode = ShapeModeBinarizeAlpha;
96             pictures[i].mode.parameters.binarizationCutoff = 255;
97         }
98         else {
99             pictures[i].mode.mode = ShapeModeColorKey;
100             pictures[i].mode.parameters.colorKey = black;
101         }
102     }
103 
104     window = SDL_CreateShapedWindow("SDL_Shape test",
105         SHAPED_WINDOW_X, SHAPED_WINDOW_Y,
106         SHAPED_WINDOW_DIMENSION,SHAPED_WINDOW_DIMENSION,
107         0);
108     SDL_SetWindowPosition(window, SHAPED_WINDOW_X, SHAPED_WINDOW_Y);
109     if(window == NULL) {
110         for(i=0;i<num_pictures;i++)
111             SDL_FreeSurface(pictures[i].surface);
112         SDL_free(pictures);
113         SDL_VideoQuit();
114         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not create shaped window for SDL_Shape.");
115         exit(-4);
116     }
117     renderer = SDL_CreateRenderer(window,-1,0);
118     if (!renderer) {
119         SDL_DestroyWindow(window);
120         for(i=0;i<num_pictures;i++)
121             SDL_FreeSurface(pictures[i].surface);
122         SDL_free(pictures);
123         SDL_VideoQuit();
124         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not create rendering context for SDL_Shape window.");
125         exit(-5);
126     }
127 
128     for(i=0;i<num_pictures;i++)
129         pictures[i].texture = NULL;
130     for(i=0;i<num_pictures;i++) {
131         pictures[i].texture = SDL_CreateTextureFromSurface(renderer,pictures[i].surface);
132         if(pictures[i].texture == NULL) {
133             j = 0;
134             for(j=0;j<num_pictures;i++)
135                 if(pictures[i].texture != NULL)
136                     SDL_DestroyTexture(pictures[i].texture);
137             for(i=0;i<num_pictures;i++)
138                 SDL_FreeSurface(pictures[i].surface);
139             SDL_free(pictures);
140             SDL_DestroyRenderer(renderer);
141             SDL_DestroyWindow(window);
142             SDL_VideoQuit();
143             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not create texture for SDL_shape.");
144             exit(-6);
145         }
146     }
147 
148     event_pending = 0;
149     should_exit = 0;
150     event_pending = SDL_PollEvent(&event);
151     current_picture = 0;
152     button_down = 0;
153     texture_dimensions.h = 0;
154     texture_dimensions.w = 0;
155     texture_dimensions.x = 0;
156     texture_dimensions.y = 0;
157     SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Changing to shaped bmp: %s", pictures[current_picture].name);
158     SDL_QueryTexture(pictures[current_picture].texture,(Uint32 *)&pixelFormat,(int *)&access,&texture_dimensions.w,&texture_dimensions.h);
159     SDL_SetWindowSize(window,texture_dimensions.w,texture_dimensions.h);
160     SDL_SetWindowShape(window,pictures[current_picture].surface,&pictures[current_picture].mode);
161     while(should_exit == 0) {
162         event_pending = SDL_PollEvent(&event);
163         if(event_pending == 1) {
164             if(event.type == SDL_KEYDOWN) {
165                 button_down = 1;
166                 if(event.key.keysym.sym == SDLK_ESCAPE) {
167                     should_exit = 1;
168                     break;
169                 }
170             }
171             if(button_down && event.type == SDL_KEYUP) {
172                 button_down = 0;
173                 current_picture += 1;
174                 if(current_picture >= num_pictures)
175                     current_picture = 0;
176                 SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Changing to shaped bmp: %s", pictures[current_picture].name);
177                 SDL_QueryTexture(pictures[current_picture].texture,(Uint32 *)&pixelFormat,(int *)&access,&texture_dimensions.w,&texture_dimensions.h);
178                 SDL_SetWindowSize(window,texture_dimensions.w,texture_dimensions.h);
179                 SDL_SetWindowShape(window,pictures[current_picture].surface,&pictures[current_picture].mode);
180             }
181             if(event.type == SDL_QUIT)
182                 should_exit = 1;
183             event_pending = 0;
184         }
185         render(renderer,pictures[current_picture].texture,texture_dimensions);
186         SDL_Delay(10);
187     }
188 
189     /* Free the textures. */
190     for(i=0;i<num_pictures;i++)
191         SDL_DestroyTexture(pictures[i].texture);
192     SDL_DestroyRenderer(renderer);
193     /* Destroy the window. */
194     SDL_DestroyWindow(window);
195     /* Free the original surfaces backing the textures. */
196     for(i=0;i<num_pictures;i++)
197         SDL_FreeSurface(pictures[i].surface);
198     SDL_free(pictures);
199     /* Call SDL_VideoQuit() before quitting. */
200     SDL_VideoQuit();
201 
202     return 0;
203 }
204 
205 /* vi: set ts=4 sw=4 expandtab: */
206