Mercurial > sdl-ios-xcode
annotate src/video/aalib/SDL_aavideo.c @ 4355:9b464226e541 SDL-1.2
Fixed bug #855
Ludwig Nussel 2009-10-18 06:31:52 PDT
an mprotect call was added to fix bug 528. However that results in a buffer
that allows writing and code execution. Ie the no-execute security features of
modern operating systems are defeated this way. Two mprotect calls are needed.
One to make the buffer executable but not writeable when done and another one
to make the buffer writeable again if the content needs to be changed.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 18 Oct 2009 17:31:37 +0000 |
parents | a1b03ba2fcd0 |
children |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
4159 | 3 Copyright (C) 1997-2009 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
6 modify it under the terms of the GNU Lesser General Public |
0 | 7 License as published by the Free Software Foundation; either |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
8 version 2.1 of the License, or (at your option) any later version. |
0 | 9 |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
13 Lesser General Public License for more details. |
0 | 14 |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
15 You should have received a copy of the GNU Lesser General Public |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
16 License along with this library; if not, write to the Free Software |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 18 |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
1402
d910939febfa
Use consistent identifiers for the various platforms we support.
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
22 #include "SDL_config.h" |
0 | 23 |
24 /* AAlib based SDL video driver implementation. | |
25 */ | |
26 | |
27 #include <unistd.h> | |
28 #include <sys/stat.h> | |
29 | |
30 | |
31 #include "SDL_video.h" | |
32 #include "SDL_mouse.h" | |
1361
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1358
diff
changeset
|
33 #include "../SDL_sysvideo.h" |
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1358
diff
changeset
|
34 #include "../SDL_pixels_c.h" |
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1358
diff
changeset
|
35 #include "../../events/SDL_events_c.h" |
0 | 36 |
37 #include "SDL_aavideo.h" | |
38 #include "SDL_aaevents_c.h" | |
39 #include "SDL_aamouse_c.h" | |
40 | |
41 #include <aalib.h> | |
42 | |
43 /* Initialization/Query functions */ | |
44 static int AA_VideoInit(_THIS, SDL_PixelFormat *vformat); | |
45 static SDL_Rect **AA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); | |
46 static SDL_Surface *AA_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | |
47 static int AA_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); | |
48 static void AA_VideoQuit(_THIS); | |
49 | |
50 /* Hardware surface functions */ | |
51 static int AA_AllocHWSurface(_THIS, SDL_Surface *surface); | |
52 static int AA_LockHWSurface(_THIS, SDL_Surface *surface); | |
53 static int AA_FlipHWSurface(_THIS, SDL_Surface *surface); | |
54 static void AA_UnlockHWSurface(_THIS, SDL_Surface *surface); | |
55 static void AA_FreeHWSurface(_THIS, SDL_Surface *surface); | |
56 | |
57 /* Cache the VideoDevice struct */ | |
58 static struct SDL_VideoDevice *local_this; | |
59 | |
60 /* AAlib driver bootstrap functions */ | |
61 | |
62 static int AA_Available(void) | |
63 { | |
64 return 1; /* Always available ! */ | |
65 } | |
66 | |
67 static void AA_DeleteDevice(SDL_VideoDevice *device) | |
68 { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1320
diff
changeset
|
69 SDL_free(device->hidden); |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1320
diff
changeset
|
70 SDL_free(device); |
0 | 71 } |
72 | |
73 static SDL_VideoDevice *AA_CreateDevice(int devindex) | |
74 { | |
75 SDL_VideoDevice *device; | |
76 | |
77 /* Initialize all variables that we clean on shutdown */ | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1320
diff
changeset
|
78 device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); |
0 | 79 if ( device ) { |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1320
diff
changeset
|
80 SDL_memset(device, 0, (sizeof *device)); |
0 | 81 device->hidden = (struct SDL_PrivateVideoData *) |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1320
diff
changeset
|
82 SDL_malloc((sizeof *device->hidden)); |
0 | 83 } |
84 if ( (device == NULL) || (device->hidden == NULL) ) { | |
85 SDL_OutOfMemory(); | |
86 if ( device ) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1320
diff
changeset
|
87 SDL_free(device); |
0 | 88 } |
89 return(0); | |
90 } | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1320
diff
changeset
|
91 SDL_memset(device->hidden, 0, (sizeof *device->hidden)); |
0 | 92 |
93 /* Set the function pointers */ | |
94 device->VideoInit = AA_VideoInit; | |
95 device->ListModes = AA_ListModes; | |
96 device->SetVideoMode = AA_SetVideoMode; | |
97 device->CreateYUVOverlay = NULL; | |
98 device->SetColors = AA_SetColors; | |
99 device->UpdateRects = NULL; | |
100 device->VideoQuit = AA_VideoQuit; | |
101 device->AllocHWSurface = AA_AllocHWSurface; | |
102 device->CheckHWBlit = NULL; | |
103 device->FillHWRect = NULL; | |
104 device->SetHWColorKey = NULL; | |
105 device->SetHWAlpha = NULL; | |
106 device->LockHWSurface = AA_LockHWSurface; | |
107 device->UnlockHWSurface = AA_UnlockHWSurface; | |
108 device->FlipHWSurface = NULL; | |
109 device->FreeHWSurface = AA_FreeHWSurface; | |
110 device->SetCaption = NULL; | |
111 device->SetIcon = NULL; | |
112 device->IconifyWindow = NULL; | |
113 device->GrabInput = NULL; | |
114 device->GetWMInfo = NULL; | |
115 device->InitOSKeymap = AA_InitOSKeymap; | |
116 device->PumpEvents = AA_PumpEvents; | |
117 | |
118 device->free = AA_DeleteDevice; | |
119 | |
120 return device; | |
121 } | |
122 | |
123 VideoBootStrap AALIB_bootstrap = { | |
124 "aalib", "ASCII Art Library", | |
125 AA_Available, AA_CreateDevice | |
126 }; | |
127 | |
128 static void AA_ResizeHandler(aa_context *); | |
129 | |
130 int AA_VideoInit(_THIS, SDL_PixelFormat *vformat) | |
131 { | |
132 int keyboard; | |
133 int i; | |
134 | |
135 /* Initialize all variables that we clean on shutdown */ | |
136 for ( i=0; i<SDL_NUMMODES; ++i ) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1320
diff
changeset
|
137 SDL_modelist[i] = SDL_malloc(sizeof(SDL_Rect)); |
0 | 138 SDL_modelist[i]->x = SDL_modelist[i]->y = 0; |
139 } | |
140 /* Modes sorted largest to smallest */ | |
141 SDL_modelist[0]->w = 1024; SDL_modelist[0]->h = 768; | |
142 SDL_modelist[1]->w = 800; SDL_modelist[1]->h = 600; | |
143 SDL_modelist[2]->w = 640; SDL_modelist[2]->h = 480; | |
144 SDL_modelist[3]->w = 320; SDL_modelist[3]->h = 400; | |
145 SDL_modelist[4]->w = 320; SDL_modelist[4]->h = 240; | |
146 SDL_modelist[5]->w = 320; SDL_modelist[5]->h = 200; | |
147 SDL_modelist[6] = NULL; | |
148 | |
149 /* Initialize the library */ | |
150 | |
151 AA_mutex = SDL_CreateMutex(); | |
152 | |
153 aa_parseoptions (NULL, NULL, NULL, NULL); | |
154 | |
155 AA_context = aa_autoinit(&aa_defparams); | |
156 if ( ! AA_context ) { | |
157 SDL_SetError("Unable to initialize AAlib"); | |
158 return(-1); | |
159 } | |
160 | |
161 /* Enable mouse and keyboard support */ | |
162 | |
163 if ( ! aa_autoinitkbd (AA_context, AA_SENDRELEASE) ) { | |
164 SDL_SetError("Unable to initialize AAlib keyboard"); | |
165 return(-1); | |
166 } | |
167 if ( ! aa_autoinitmouse (AA_context, AA_SENDRELEASE) ) { | |
168 fprintf(stderr,"Warning: Unable to initialize AAlib mouse"); | |
169 } | |
170 AA_rparams = aa_getrenderparams(); | |
171 | |
172 local_this = this; | |
173 | |
174 aa_resizehandler(AA_context, AA_ResizeHandler); | |
175 | |
176 fprintf(stderr,"Using AAlib driver: %s (%s)\n", AA_context->driver->name, AA_context->driver->shortname); | |
177 | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1320
diff
changeset
|
178 AA_in_x11 = (SDL_strcmp(AA_context->driver->shortname,"X11") == 0); |
0 | 179 /* Determine the screen depth (use default 8-bit depth) */ |
180 vformat->BitsPerPixel = 8; | |
181 vformat->BytesPerPixel = 1; | |
182 | |
183 /* We're done! */ | |
184 return(0); | |
185 } | |
186 | |
187 SDL_Rect **AA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) | |
188 { | |
189 if(format->BitsPerPixel != 8) | |
190 return NULL; | |
191 | |
192 if ( flags & SDL_FULLSCREEN ) { | |
193 return SDL_modelist; | |
194 } else { | |
195 return (SDL_Rect **) -1; | |
196 } | |
197 } | |
198 | |
199 /* From aavga.c | |
200 AAlib does not give us the choice of the actual resolution, thus we have to simulate additional | |
201 resolution by scaling down manually each frame | |
202 */ | |
203 static void fastscale (register char *b1, register char *b2, int x1, int x2, int y1, int y2) | |
204 { | |
205 register int ex, spx = 0, ddx, ddx1; | |
206 int ddy1, ddy, spy = 0, ey; | |
207 int x; | |
208 char *bb1 = b1; | |
209 if (!x1 || !x2 || !y1 || !y2) | |
210 return; | |
211 ddx = x1 + x1; | |
212 ddx1 = x2 + x2; | |
213 if (ddx1 < ddx) | |
214 spx = ddx / ddx1, ddx %= ddx1; | |
215 ddy = y1 + y1; | |
216 ddy1 = y2 + y2; | |
217 if (ddy1 < ddy) | |
218 spy = (ddy / ddy1) * x1, ddy %= ddy1; | |
219 ey = -ddy1; | |
220 for (; y2; y2--) { | |
221 ex = -ddx1; | |
222 for (x = x2; x; x--) { | |
223 *b2 = *b1; | |
224 b2++; | |
225 b1 += spx; | |
226 ex += ddx; | |
227 if (ex > 0) { | |
228 b1++; | |
229 ex -= ddx1; | |
230 } | |
231 } | |
232 bb1 += spy; | |
233 ey += ddy; | |
234 if (ey > 0) { | |
235 bb1 += x1; | |
236 ey -= ddy1; | |
237 } | |
238 b1 = bb1; | |
239 } | |
240 } | |
241 | |
242 /* Various screen update functions available */ | |
243 static void AA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects); | |
244 | |
245 SDL_Surface *AA_SetVideoMode(_THIS, SDL_Surface *current, | |
246 int width, int height, int bpp, Uint32 flags) | |
247 { | |
248 int mode; | |
249 | |
250 if ( AA_buffer ) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1320
diff
changeset
|
251 SDL_free( AA_buffer ); |
0 | 252 } |
253 | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1320
diff
changeset
|
254 AA_buffer = SDL_malloc(width * height); |
0 | 255 if ( ! AA_buffer ) { |
256 SDL_SetError("Couldn't allocate buffer for requested mode"); | |
257 return(NULL); | |
258 } | |
259 | |
260 /* printf("Setting mode %dx%d\n", width, height); */ | |
261 | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1320
diff
changeset
|
262 SDL_memset(aa_image(AA_context), 0, aa_imgwidth(AA_context) * aa_imgheight(AA_context)); |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1320
diff
changeset
|
263 SDL_memset(AA_buffer, 0, width * height); |
0 | 264 |
265 /* Allocate the new pixel format for the screen */ | |
266 if ( ! SDL_ReallocFormat(current, 8, 0, 0, 0, 0) ) { | |
267 return(NULL); | |
268 } | |
269 | |
270 /* Set up the new mode framebuffer */ | |
271 current->flags = SDL_FULLSCREEN; | |
272 AA_w = current->w = width; | |
273 AA_h = current->h = height; | |
274 current->pitch = current->w; | |
275 current->pixels = AA_buffer; | |
276 | |
277 AA_x_ratio = ((double)aa_imgwidth(AA_context)) / ((double)width); | |
278 AA_y_ratio = ((double)aa_imgheight(AA_context)) / ((double)height); | |
279 | |
280 /* Set the blit function */ | |
281 this->UpdateRects = AA_DirectUpdate; | |
282 | |
283 /* We're done */ | |
284 return(current); | |
285 } | |
286 | |
287 static void AA_ResizeHandler(aa_context *context) | |
288 { | |
289 aa_resize(context); | |
290 local_this->hidden->x_ratio = ((double)aa_imgwidth(context)) / ((double)local_this->screen->w); | |
291 local_this->hidden->y_ratio = ((double)aa_imgheight(context)) / ((double)local_this->screen->h); | |
292 | |
293 fastscale (local_this->hidden->buffer, aa_image(context), local_this->hidden->w, aa_imgwidth (context), local_this->hidden->h, aa_imgheight (context)); | |
294 aa_renderpalette(context, local_this->hidden->palette, local_this->hidden->rparams, 0, 0, aa_scrwidth(context), aa_scrheight(context)); | |
295 aa_flush(context); | |
296 } | |
297 | |
298 /* We don't actually allow hardware surfaces other than the main one */ | |
299 static int AA_AllocHWSurface(_THIS, SDL_Surface *surface) | |
300 { | |
301 return(-1); | |
302 } | |
303 static void AA_FreeHWSurface(_THIS, SDL_Surface *surface) | |
304 { | |
305 return; | |
306 } | |
307 | |
308 /* We need to wait for vertical retrace on page flipped displays */ | |
309 static int AA_LockHWSurface(_THIS, SDL_Surface *surface) | |
310 { | |
311 /* TODO ? */ | |
312 return(0); | |
313 } | |
314 static void AA_UnlockHWSurface(_THIS, SDL_Surface *surface) | |
315 { | |
316 return; | |
317 } | |
318 | |
319 /* FIXME: How is this done with AAlib? */ | |
320 static int AA_FlipHWSurface(_THIS, SDL_Surface *surface) | |
321 { | |
322 SDL_mutexP(AA_mutex); | |
323 aa_flush(AA_context); | |
324 SDL_mutexV(AA_mutex); | |
325 return(0); | |
326 } | |
327 | |
328 static void AA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects) | |
329 { | |
330 int i; | |
331 SDL_Rect *rect; | |
332 | |
333 fastscale (AA_buffer, aa_image(AA_context), AA_w, aa_imgwidth (AA_context), AA_h, aa_imgheight (AA_context)); | |
334 #if 1 | |
335 aa_renderpalette(AA_context, AA_palette, AA_rparams, 0, 0, aa_scrwidth(AA_context), aa_scrheight(AA_context)); | |
336 #else | |
337 /* Render only the rectangles in the list */ | |
338 printf("Update rects : "); | |
339 for ( i=0; i < numrects; ++i ) { | |
340 rect = &rects[i]; | |
341 printf("(%d,%d-%d,%d)", rect->x, rect->y, rect->w, rect->h); | |
342 aa_renderpalette(AA_context, AA_palette, AA_rparams, rect->x * AA_x_ratio, rect->y * AA_y_ratio, rect->w * AA_x_ratio, rect->h * AA_y_ratio); | |
343 } | |
344 printf("\n"); | |
345 #endif | |
346 SDL_mutexP(AA_mutex); | |
347 aa_flush(AA_context); | |
348 SDL_mutexV(AA_mutex); | |
349 return; | |
350 } | |
351 | |
352 int AA_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) | |
353 { | |
354 int i; | |
355 | |
356 for ( i=0; i < ncolors; i++ ) { | |
357 aa_setpalette(AA_palette, firstcolor + i, | |
358 colors[i].r>>2, | |
359 colors[i].g>>2, | |
360 colors[i].b>>2); | |
361 } | |
362 return(1); | |
363 } | |
364 | |
365 /* Note: If we are terminated, this could be called in the middle of | |
366 another SDL video routine -- notably UpdateRects. | |
367 */ | |
368 void AA_VideoQuit(_THIS) | |
369 { | |
370 int i; | |
371 | |
372 aa_uninitkbd(AA_context); | |
373 aa_uninitmouse(AA_context); | |
374 | |
375 /* Free video mode lists */ | |
376 for ( i=0; i<SDL_NUMMODES; ++i ) { | |
377 if ( SDL_modelist[i] != NULL ) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1320
diff
changeset
|
378 SDL_free(SDL_modelist[i]); |
0 | 379 SDL_modelist[i] = NULL; |
380 } | |
381 } | |
382 | |
383 aa_close(AA_context); | |
384 | |
385 SDL_DestroyMutex(AA_mutex); | |
386 | |
387 this->screen->pixels = NULL; | |
388 } |