1 /**
2 * Cursor and app icon mask tests
3
4 * Copyright (C) 2007 Sylvain Beucler
5
6 * This file is part of GNU FreeDink
7
8 * GNU FreeDink is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 3 of the
11 * License, or (at your option) any later version.
12
13 * GNU FreeDink is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see
20 * <http://www.gnu.org/licenses/>.
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <math.h>
26 #include "SDL.h"
27
28 /* Cursor part based on
29 http://www.libsdl.org/docs/html/sdlcreatecursor.html */
30
31 static const char *arrow[] = {
32 /* width height num_colors chars_per_pixel */
33 " 32 32 3 1",
34 /* colors */
35 "X c #000000",
36 ". c #ffffff",
37 " c Transparent",
38 "I c Invereted",
39 /* pixels */
40 "X ",
41 "XX ",
42 "X.X ",
43 "X..X ",
44 "X...X ",
45 "X.I..X ",
46 "X.II..X ",
47 "X.III..X ",
48 "X.IIII..X ",
49 "X.I......X ",
50 "X.....XXXXX ",
51 "X..X..X ",
52 "X.X X..X ",
53 "XX X..X ",
54 "X X..X ",
55 " X..X ",
56 " X..X ",
57 " X..X ",
58 " XX ",
59 " ",
60 " ",
61 " ",
62 " ",
63 " ",
64 " ",
65 " ",
66 " ",
67 " ",
68 " ",
69 " ",
70 " ",
71 " ",
72 "0,0"
73 };
74
init_system_cursor(const char * image[])75 static SDL_Cursor *init_system_cursor(const char *image[])
76 {
77 int i, row, col;
78 Uint8 data[4*32];
79 Uint8 mask[4*32];
80 int hot_x, hot_y;
81
82 i = -1;
83 for ( row=0; row<32; ++row ) {
84 for ( col=0; col<32; ++col ) {
85 if ( col % 8 ) {
86 data[i] <<= 1;
87 mask[i] <<= 1;
88 } else {
89 ++i;
90 data[i] = mask[i] = 0;
91 }
92 switch (image[5+row][col]) {
93 case 'X':
94 data[i] |= 0x01;
95 mask[i] |= 0x01;
96 break;
97 case '.':
98 mask[i] |= 0x01;
99 break;
100 case 'I':
101 data[i] |= 0x01;
102 break;
103 case ' ':
104 break;
105 }
106 }
107 }
108 sscanf(image[5+row], "%d,%d", &hot_x, &hot_y);
109 return SDL_CreateCursor(data, mask, 32, 32, hot_x, hot_y);
110 }
111
112
113 /* Create a mask in MSB for using r,g,b as the transparent color */
create_mask_msb(SDL_Surface * source,Uint8 r,Uint8 g,Uint8 b)114 Uint8 *create_mask_msb(SDL_Surface *source, Uint8 r, Uint8 g, Uint8 b) {
115 Uint32 transparent;
116 Uint32 *pixels;
117 SDL_Surface *surface;
118 Uint8 *mask;
119
120 /* Convert surface to 32bit to ease parsing the pixel data */
121 surface = SDL_CreateRGBSurface(SDL_SWSURFACE, source->w, source->h, 32,
122 0xff000000, 0x00ff0000, 0x0000ff00, 0x00000000);
123 if(surface == NULL) {
124 fprintf(stderr, "Could not convert surface to 32bit: %s", SDL_GetError());
125 return NULL;
126 }
127
128 SDL_BlitSurface(source, NULL, surface, NULL);
129
130 transparent = SDL_MapRGB(surface->format, r, g, b);
131
132 if (SDL_MUSTLOCK(surface))
133 SDL_LockSurface(surface);
134 pixels = (Uint32*) surface->pixels;
135 if (SDL_MUSTLOCK(surface))
136 SDL_UnlockSurface(surface);
137
138 /* 8 bits per Uint8 */
139 mask = malloc(ceil(surface->w / 8.0) * surface->h);
140
141 {
142 int i, row, col;
143 i = -1;
144 for (row = 0; row < surface->h; row++)
145 {
146 for (col = 0; col < surface->w; col++)
147 {
148 /* Shift to the next mask bit */
149 if (col % 8 == 0)
150 {
151 i++;
152 mask[i] = 0;
153 }
154 else
155 {
156 mask[i] <<= 1;
157 }
158
159 /* Set the current mask bit */
160 if (pixels[row*surface->w + col] != transparent)
161 mask[i] |= 0x01;
162 }
163 }
164 }
165 SDL_FreeSurface(surface);
166 return mask;
167 }
168
169
main(void)170 int main(void)
171 {
172 SDL_Surface *screen;
173
174 if (SDL_InitSubSystem(SDL_INIT_VIDEO) == -1)
175 {
176 fprintf(stderr, "SDL_Init: %s\n", SDL_GetError());
177 return 1;
178 }
179
180 SDL_WM_SetCaption("Cursor test", NULL);
181 SDL_SetCursor(init_system_cursor(arrow));
182
183 {
184 SDL_Surface *icon;
185 Uint8 *mask;
186
187 icon = SDL_LoadBMP("../../share/freedink/dink.bmp");
188
189 mask = create_mask_msb(icon, 255, 255, 0); /* Yellow */
190 if (mask != NULL)
191 {
192 SDL_WM_SetIcon(icon, mask);
193 SDL_FreeSurface(icon);
194 free(mask);
195 }
196 }
197
198 screen = SDL_SetVideoMode(640, 480, 0, SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF);
199 SDL_FillRect(screen, NULL,
200 SDL_MapRGB(screen->format, 0, 255, 255));
201 SDL_Flip(screen);
202
203 {
204 SDL_Event event;
205 int quit = 0;
206 while (SDL_WaitEvent(&event) && !quit)
207 {
208 switch(event.type)
209 {
210 case SDL_QUIT:
211 quit = 1;
212 break;
213 case SDL_KEYDOWN:
214 if (event.key.keysym.sym == 'q'
215 || event.key.keysym.sym == SDLK_ESCAPE)
216 quit = 1;
217 break;
218 }
219 }
220 }
221 return 0;
222 }
223