Subversion Repositories Kolibri OS

Rev

Rev 8210 | Rev 9561 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 8210 Rev 8218
1
/*
1
/*
2
    SDL - Simple DirectMedia Layer
2
    SDL - Simple DirectMedia Layer
3
    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
3
    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
4
 
4
 
5
    This library is free software; you can redistribute it and/or
5
    This library is free software; you can redistribute it and/or
6
    modify it under the terms of the GNU Library General Public
6
    modify it under the terms of the GNU Library General Public
7
    License as published by the Free Software Foundation; either
7
    License as published by the Free Software Foundation; either
8
    version 2 of the License, or (at your option) any later version.
8
    version 2 of the License, or (at your option) any later version.
9
 
9
 
10
    This library is distributed in the hope that it will be useful,
10
    This library is distributed in the hope that it will be useful,
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
    Library General Public License for more details.
13
    Library General Public License for more details.
14
 
14
 
15
    You should have received a copy of the GNU Library General Public
15
    You should have received a copy of the GNU Library General Public
16
    License along with this library; if not, write to the Free
16
    License along with this library; if not, write to the Free
17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 
18
 
19
    Sam Lantinga
19
    Sam Lantinga
20
    slouken@devolution.com
20
    slouken@devolution.com
21
*/
21
*/
22
 
22
 
23
 
23
 
24
/* The high-level video driver subsystem */
24
/* The high-level video driver subsystem */
25
 
25
 
26
#include 
26
#include 
27
#include 
27
#include 
28
#include 
28
#include 
29
 
29
 
30
#include "SDL.h"
30
#include "SDL.h"
31
#include "SDL_error.h"
31
#include "SDL_error.h"
32
#include "SDL_video.h"
32
#include "SDL_video.h"
33
#include "SDL_events.h"
33
#include "SDL_events.h"
34
#include "SDL_mutex.h"
34
#include "SDL_mutex.h"
35
#include "SDL_sysvideo.h"
35
#include "SDL_sysvideo.h"
36
#include "SDL_sysevents.h"
36
#include "SDL_sysevents.h"
37
#include "SDL_blit.h"
37
#include "SDL_blit.h"
38
#include "SDL_pixels_c.h"
38
#include "SDL_pixels_c.h"
39
#include "SDL_events_c.h"
39
#include "SDL_events_c.h"
40
#include "SDL_cursor_c.h"
40
#include "SDL_cursor_c.h"
41
 
41
 
42
/* Available video drivers */
42
/* Available video drivers */
43
static VideoBootStrap *bootstrap[] = {
43
static VideoBootStrap *bootstrap[] = {
44
#ifdef ENABLE_X11
44
#ifdef ENABLE_X11
45
	&X11_bootstrap,
45
	&X11_bootstrap,
46
#endif
46
#endif
47
#ifdef ENABLE_DGA
47
#ifdef ENABLE_DGA
48
	&DGA_bootstrap,
48
	&DGA_bootstrap,
49
#endif
49
#endif
50
#ifdef ENABLE_NANOX
50
#ifdef ENABLE_NANOX
51
	&NX_bootstrap,
51
	&NX_bootstrap,
52
#endif
52
#endif
53
#ifdef ENABLE_FBCON
53
#ifdef ENABLE_FBCON
54
	&FBCON_bootstrap,
54
	&FBCON_bootstrap,
55
#endif
55
#endif
56
#ifdef ENABLE_PS2GS
56
#ifdef ENABLE_PS2GS
57
	&PS2GS_bootstrap,
57
	&PS2GS_bootstrap,
58
#endif
58
#endif
59
#ifdef ENABLE_GGI
59
#ifdef ENABLE_GGI
60
	&GGI_bootstrap,
60
	&GGI_bootstrap,
61
#endif
61
#endif
62
#ifdef ENABLE_VGL
62
#ifdef ENABLE_VGL
63
	&VGL_bootstrap,
63
	&VGL_bootstrap,
64
#endif
64
#endif
65
#ifdef ENABLE_SVGALIB
65
#ifdef ENABLE_SVGALIB
66
	&SVGALIB_bootstrap,
66
	&SVGALIB_bootstrap,
67
#endif
67
#endif
68
#ifdef ENABLE_AALIB
68
#ifdef ENABLE_AALIB
69
    &AALIB_bootstrap,
69
    &AALIB_bootstrap,
70
#endif
70
#endif
71
#ifdef ENABLE_DIRECTX
71
#ifdef ENABLE_DIRECTX
72
	&DIRECTX_bootstrap,
72
	&DIRECTX_bootstrap,
73
#endif
73
#endif
74
#ifdef ENABLE_WINDIB
74
#ifdef ENABLE_WINDIB
75
	&WINDIB_bootstrap,
75
	&WINDIB_bootstrap,
76
#endif
76
#endif
77
#ifdef ENABLE_BWINDOW
77
#ifdef ENABLE_BWINDOW
78
	&BWINDOW_bootstrap,
78
	&BWINDOW_bootstrap,
79
#endif
79
#endif
80
#ifdef ENABLE_TOOLBOX
80
#ifdef ENABLE_TOOLBOX
81
	&TOOLBOX_bootstrap,
81
	&TOOLBOX_bootstrap,
82
#endif
82
#endif
83
#ifdef ENABLE_DRAWSPROCKET
83
#ifdef ENABLE_DRAWSPROCKET
84
	&DSp_bootstrap,
84
	&DSp_bootstrap,
85
#endif
85
#endif
86
#ifdef ENABLE_QUARTZ
86
#ifdef ENABLE_QUARTZ
87
	&QZ_bootstrap,
87
	&QZ_bootstrap,
88
#endif
88
#endif
89
#ifdef ENABLE_CYBERGRAPHICS
89
#ifdef ENABLE_CYBERGRAPHICS
90
	&CGX_bootstrap,
90
	&CGX_bootstrap,
91
#endif
91
#endif
92
#ifdef ENABLE_DUMMYVIDEO
92
#ifdef ENABLE_DUMMYVIDEO
93
	&DUMMY_bootstrap,
93
	&DUMMY_bootstrap,
94
#endif
94
#endif
95
#ifdef ENABLE_PHOTON
95
#ifdef ENABLE_PHOTON
96
	&ph_bootstrap,
96
	&ph_bootstrap,
97
#endif
97
#endif
98
#ifdef ENABLE_MENUETOS
98
#ifdef ENABLE_KOLIBRIOS
99
	&mosvideo_bootstrab,
99
	&mosvideo_bootstrab,
100
#endif
100
#endif
101
	NULL
101
	NULL
102
};
102
};
103
 
103
 
104
SDL_VideoDevice *current_video = NULL;
104
SDL_VideoDevice *current_video = NULL;
105
 
105
 
106
/* Various local functions */
106
/* Various local functions */
107
int SDL_VideoInit(const char *driver_name, Uint32 flags);
107
int SDL_VideoInit(const char *driver_name, Uint32 flags);
108
void SDL_VideoQuit(void);
108
void SDL_VideoQuit(void);
109
void SDL_GL_UpdateRectsLock(SDL_VideoDevice* this, int numrects, SDL_Rect* rects);
109
void SDL_GL_UpdateRectsLock(SDL_VideoDevice* this, int numrects, SDL_Rect* rects);
110
 
110
 
111
static SDL_GrabMode SDL_WM_GrabInputOff(void);
111
static SDL_GrabMode SDL_WM_GrabInputOff(void);
112
#ifdef HAVE_OPENGL
112
#ifdef HAVE_OPENGL
113
static int lock_count = 0;
113
static int lock_count = 0;
114
#endif
114
#endif
115
 
115
 
116
 
116
 
117
/*
117
/*
118
 * Initialize the video and event subsystems -- determine native pixel format
118
 * Initialize the video and event subsystems -- determine native pixel format
119
 */
119
 */
120
int SDL_VideoInit (const char *driver_name, Uint32 flags)
120
int SDL_VideoInit (const char *driver_name, Uint32 flags)
121
{
121
{
122
	SDL_VideoDevice *video;
122
	SDL_VideoDevice *video;
123
	int index;
123
	int index;
124
	int i;
124
	int i;
125
	SDL_PixelFormat vformat;
125
	SDL_PixelFormat vformat;
126
	Uint32 video_flags;
126
	Uint32 video_flags;
127
 
127
 
128
	/* Toggle the event thread flags, based on OS requirements */
128
	/* Toggle the event thread flags, based on OS requirements */
129
#if defined(MUST_THREAD_EVENTS)
129
#if defined(MUST_THREAD_EVENTS)
130
	flags |= SDL_INIT_EVENTTHREAD;
130
	flags |= SDL_INIT_EVENTTHREAD;
131
#elif defined(CANT_THREAD_EVENTS)
131
#elif defined(CANT_THREAD_EVENTS)
132
	if ( (flags & SDL_INIT_EVENTTHREAD) == SDL_INIT_EVENTTHREAD ) {
132
	if ( (flags & SDL_INIT_EVENTTHREAD) == SDL_INIT_EVENTTHREAD ) {
133
		SDL_SetError("OS doesn't support threaded events");
133
		SDL_SetError("OS doesn't support threaded events");
134
		return(-1);
134
		return(-1);
135
	}
135
	}
136
#endif
136
#endif
137
 
137
 
138
	/* Check to make sure we don't overwrite 'current_video' */
138
	/* Check to make sure we don't overwrite 'current_video' */
139
	if ( current_video != NULL ) {
139
	if ( current_video != NULL ) {
140
		SDL_VideoQuit();
140
		SDL_VideoQuit();
141
	}
141
	}
142
 
142
 
143
	/* Select the proper video driver */
143
	/* Select the proper video driver */
144
	index = 0;
144
	index = 0;
145
	video = NULL;
145
	video = NULL;
146
	if ( driver_name != NULL ) {
146
	if ( driver_name != NULL ) {
147
		for ( i=0; bootstrap[i]; ++i ) {
147
		for ( i=0; bootstrap[i]; ++i ) {
148
			if ( strncmp(bootstrap[i]->name, driver_name,
148
			if ( strncmp(bootstrap[i]->name, driver_name,
149
			             strlen(bootstrap[i]->name)) == 0 ) {
149
			             strlen(bootstrap[i]->name)) == 0 ) {
150
				if ( bootstrap[i]->available() ) {
150
				if ( bootstrap[i]->available() ) {
151
					video = bootstrap[i]->create(index);
151
					video = bootstrap[i]->create(index);
152
					break;
152
					break;
153
				}
153
				}
154
			}
154
			}
155
		}
155
		}
156
	} else {
156
	} else {
157
		for ( i=0; bootstrap[i]; ++i ) {
157
		for ( i=0; bootstrap[i]; ++i ) {
158
			if ( bootstrap[i]->available() ) {
158
			if ( bootstrap[i]->available() ) {
159
				video = bootstrap[i]->create(index);
159
				video = bootstrap[i]->create(index);
160
				if ( video != NULL ) {
160
				if ( video != NULL ) {
161
					break;
161
					break;
162
				}
162
				}
163
			}
163
			}
164
		}
164
		}
165
	}
165
	}
166
	if ( video == NULL ) {
166
	if ( video == NULL ) {
167
		SDL_SetError("No available video device");
167
		SDL_SetError("No available video device");
168
		return(-1);
168
		return(-1);
169
	}
169
	}
170
	current_video = video;
170
	current_video = video;
171
	current_video->name = bootstrap[i]->name;
171
	current_video->name = bootstrap[i]->name;
172
 
172
 
173
	/* Do some basic variable initialization */
173
	/* Do some basic variable initialization */
174
	video->screen = NULL;
174
	video->screen = NULL;
175
	video->shadow = NULL;
175
	video->shadow = NULL;
176
	video->visible = NULL;
176
	video->visible = NULL;
177
	video->physpal = NULL;
177
	video->physpal = NULL;
178
	video->gammacols = NULL;
178
	video->gammacols = NULL;
179
	video->gamma = NULL;
179
	video->gamma = NULL;
180
	video->wm_title = NULL;
180
	video->wm_title = NULL;
181
	video->wm_icon  = NULL;
181
	video->wm_icon  = NULL;
182
	video->offset_x = 0;
182
	video->offset_x = 0;
183
	video->offset_y = 0;
183
	video->offset_y = 0;
184
	memset(&video->info, 0, (sizeof video->info));
184
	memset(&video->info, 0, (sizeof video->info));
185
 
185
 
186
	/* Set some very sane GL defaults */
186
	/* Set some very sane GL defaults */
187
	video->gl_config.driver_loaded = 0;
187
	video->gl_config.driver_loaded = 0;
188
	video->gl_config.dll_handle = NULL;
188
	video->gl_config.dll_handle = NULL;
189
	video->gl_config.red_size = 5;
189
	video->gl_config.red_size = 5;
190
#if 1 /* This seems to work on more video cards, as a default */
190
#if 1 /* This seems to work on more video cards, as a default */
191
	video->gl_config.green_size = 5;
191
	video->gl_config.green_size = 5;
192
#else
192
#else
193
	video->gl_config.green_size = 6;
193
	video->gl_config.green_size = 6;
194
#endif
194
#endif
195
	video->gl_config.blue_size = 5;
195
	video->gl_config.blue_size = 5;
196
	video->gl_config.alpha_size = 0;
196
	video->gl_config.alpha_size = 0;
197
	video->gl_config.buffer_size = 0;
197
	video->gl_config.buffer_size = 0;
198
	video->gl_config.depth_size = 16;
198
	video->gl_config.depth_size = 16;
199
	video->gl_config.stencil_size = 0;
199
	video->gl_config.stencil_size = 0;
200
	video->gl_config.double_buffer = 1;
200
	video->gl_config.double_buffer = 1;
201
	video->gl_config.accum_red_size = 0;
201
	video->gl_config.accum_red_size = 0;
202
	video->gl_config.accum_green_size = 0;
202
	video->gl_config.accum_green_size = 0;
203
	video->gl_config.accum_blue_size = 0;
203
	video->gl_config.accum_blue_size = 0;
204
	video->gl_config.accum_alpha_size = 0;
204
	video->gl_config.accum_alpha_size = 0;
205
	
205
	
206
	/* Initialize the video subsystem */
206
	/* Initialize the video subsystem */
207
	memset(&vformat, 0, sizeof(vformat));
207
	memset(&vformat, 0, sizeof(vformat));
208
	if ( video->VideoInit(video, &vformat) < 0 ) {
208
	if ( video->VideoInit(video, &vformat) < 0 ) {
209
		SDL_VideoQuit();
209
		SDL_VideoQuit();
210
		return(-1);
210
		return(-1);
211
	}
211
	}
212
 
212
 
213
	/* Create a zero sized video surface of the appropriate format */
213
	/* Create a zero sized video surface of the appropriate format */
214
	video_flags = SDL_SWSURFACE;
214
	video_flags = SDL_SWSURFACE;
215
	SDL_VideoSurface = SDL_CreateRGBSurface(video_flags, 0, 0,
215
	SDL_VideoSurface = SDL_CreateRGBSurface(video_flags, 0, 0,
216
				vformat.BitsPerPixel,
216
				vformat.BitsPerPixel,
217
				vformat.Rmask, vformat.Gmask, vformat.Bmask, 0);
217
				vformat.Rmask, vformat.Gmask, vformat.Bmask, 0);
218
	if ( SDL_VideoSurface == NULL ) {
218
	if ( SDL_VideoSurface == NULL ) {
219
		SDL_VideoQuit();
219
		SDL_VideoQuit();
220
		return(-1);
220
		return(-1);
221
	}
221
	}
222
	SDL_PublicSurface = NULL;	/* Until SDL_SetVideoMode() */
222
	SDL_PublicSurface = NULL;	/* Until SDL_SetVideoMode() */
223
 
223
 
224
#if 0 /* Don't change the current palette - may be used by other programs.
224
#if 0 /* Don't change the current palette - may be used by other programs.
225
       * The application can't do anything with the display surface until
225
       * The application can't do anything with the display surface until
226
       * a video mode has been set anyway. :)
226
       * a video mode has been set anyway. :)
227
       */
227
       */
228
	/* If we have a palettized surface, create a default palette */
228
	/* If we have a palettized surface, create a default palette */
229
	if ( SDL_VideoSurface->format->palette ) {
229
	if ( SDL_VideoSurface->format->palette ) {
230
	        SDL_PixelFormat *vf = SDL_VideoSurface->format;
230
	        SDL_PixelFormat *vf = SDL_VideoSurface->format;
231
		SDL_DitherColors(vf->palette->colors, vf->BitsPerPixel);
231
		SDL_DitherColors(vf->palette->colors, vf->BitsPerPixel);
232
		video->SetColors(video,
232
		video->SetColors(video,
233
				 0, vf->palette->ncolors, vf->palette->colors);
233
				 0, vf->palette->ncolors, vf->palette->colors);
234
	}
234
	}
235
#endif
235
#endif
236
	video->info.vfmt = SDL_VideoSurface->format;
236
	video->info.vfmt = SDL_VideoSurface->format;
237
 
237
 
238
	/* Start the event loop */
238
	/* Start the event loop */
239
	if ( SDL_StartEventLoop(flags) < 0 ) {
239
	if ( SDL_StartEventLoop(flags) < 0 ) {
240
		SDL_VideoQuit();
240
		SDL_VideoQuit();
241
		return(-1);
241
		return(-1);
242
	}
242
	}
243
	SDL_CursorInit(flags & SDL_INIT_EVENTTHREAD);
243
	SDL_CursorInit(flags & SDL_INIT_EVENTTHREAD);
244
 
244
 
245
	/* We're ready to go! */
245
	/* We're ready to go! */
246
	return(0);
246
	return(0);
247
}
247
}
248
 
248
 
249
char *SDL_VideoDriverName(char *namebuf, int maxlen)
249
char *SDL_VideoDriverName(char *namebuf, int maxlen)
250
{
250
{
251
	if ( current_video != NULL ) {
251
	if ( current_video != NULL ) {
252
		strncpy(namebuf, current_video->name, maxlen-1);
252
		strncpy(namebuf, current_video->name, maxlen-1);
253
		namebuf[maxlen-1] = '\0';
253
		namebuf[maxlen-1] = '\0';
254
		return(namebuf);
254
		return(namebuf);
255
	}
255
	}
256
	return(NULL);
256
	return(NULL);
257
}
257
}
258
 
258
 
259
/*
259
/*
260
 * Get the current display surface
260
 * Get the current display surface
261
 */
261
 */
262
SDL_Surface *SDL_GetVideoSurface(void)
262
SDL_Surface *SDL_GetVideoSurface(void)
263
{
263
{
264
	SDL_Surface *visible;
264
	SDL_Surface *visible;
265
 
265
 
266
	visible = NULL;
266
	visible = NULL;
267
	if ( current_video ) {
267
	if ( current_video ) {
268
		visible = current_video->visible;
268
		visible = current_video->visible;
269
	}
269
	}
270
	return(visible);
270
	return(visible);
271
}
271
}
272
 
272
 
273
/*
273
/*
274
 * Get the current information about the video hardware
274
 * Get the current information about the video hardware
275
 */
275
 */
276
const SDL_VideoInfo *SDL_GetVideoInfo(void)
276
const SDL_VideoInfo *SDL_GetVideoInfo(void)
277
{
277
{
278
	const SDL_VideoInfo *info;
278
	const SDL_VideoInfo *info;
279
 
279
 
280
	info = NULL;
280
	info = NULL;
281
	if ( current_video ) {
281
	if ( current_video ) {
282
		info = ¤t_video->info;
282
		info = ¤t_video->info;
283
	}
283
	}
284
	return(info);
284
	return(info);
285
}
285
}
286
 
286
 
287
/*
287
/*
288
 * Return a pointer to an array of available screen dimensions for the
288
 * Return a pointer to an array of available screen dimensions for the
289
 * given format, sorted largest to smallest.  Returns NULL if there are
289
 * given format, sorted largest to smallest.  Returns NULL if there are
290
 * no dimensions available for a particular format, or (SDL_Rect **)-1
290
 * no dimensions available for a particular format, or (SDL_Rect **)-1
291
 * if any dimension is okay for the given format.  If 'format' is NULL,
291
 * if any dimension is okay for the given format.  If 'format' is NULL,
292
 * the mode list will be for the format given by SDL_GetVideoInfo()->vfmt
292
 * the mode list will be for the format given by SDL_GetVideoInfo()->vfmt
293
 */
293
 */
294
SDL_Rect ** SDL_ListModes (SDL_PixelFormat *format, Uint32 flags)
294
SDL_Rect ** SDL_ListModes (SDL_PixelFormat *format, Uint32 flags)
295
{
295
{
296
	SDL_VideoDevice *video = current_video;
296
	SDL_VideoDevice *video = current_video;
297
	SDL_VideoDevice *this  = current_video;
297
	SDL_VideoDevice *this  = current_video;
298
	SDL_Rect **modes;
298
	SDL_Rect **modes;
299
 
299
 
300
	modes = NULL;
300
	modes = NULL;
301
	if ( SDL_VideoSurface ) {
301
	if ( SDL_VideoSurface ) {
302
		if ( format == NULL ) {
302
		if ( format == NULL ) {
303
			format = SDL_VideoSurface->format;
303
			format = SDL_VideoSurface->format;
304
		}
304
		}
305
		modes = video->ListModes(this, format, flags);
305
		modes = video->ListModes(this, format, flags);
306
	}
306
	}
307
	return(modes);
307
	return(modes);
308
}
308
}
309
 
309
 
310
/*
310
/*
311
 * Check to see if a particular video mode is supported.
311
 * Check to see if a particular video mode is supported.
312
 * It returns 0 if the requested mode is not supported under any bit depth,
312
 * It returns 0 if the requested mode is not supported under any bit depth,
313
 * or returns the bits-per-pixel of the closest available mode with the
313
 * or returns the bits-per-pixel of the closest available mode with the
314
 * given width and height.  If this bits-per-pixel is different from the
314
 * given width and height.  If this bits-per-pixel is different from the
315
 * one used when setting the video mode, SDL_SetVideoMode() will succeed,
315
 * one used when setting the video mode, SDL_SetVideoMode() will succeed,
316
 * but will emulate the requested bits-per-pixel with a shadow surface.
316
 * but will emulate the requested bits-per-pixel with a shadow surface.
317
 */
317
 */
318
static Uint8 SDL_closest_depths[4][8] = {
318
static Uint8 SDL_closest_depths[4][8] = {
319
	/* 8 bit closest depth ordering */
319
	/* 8 bit closest depth ordering */
320
	{ 0, 8, 16, 15, 32, 24, 0, 0 },
320
	{ 0, 8, 16, 15, 32, 24, 0, 0 },
321
	/* 15,16 bit closest depth ordering */
321
	/* 15,16 bit closest depth ordering */
322
	{ 0, 16, 15, 32, 24, 8, 0, 0 },
322
	{ 0, 16, 15, 32, 24, 8, 0, 0 },
323
	/* 24 bit closest depth ordering */
323
	/* 24 bit closest depth ordering */
324
	{ 0, 24, 32, 16, 15, 8, 0, 0 },
324
	{ 0, 24, 32, 16, 15, 8, 0, 0 },
325
	/* 32 bit closest depth ordering */
325
	/* 32 bit closest depth ordering */
326
	{ 0, 32, 16, 15, 24, 8, 0, 0 }
326
	{ 0, 32, 16, 15, 24, 8, 0, 0 }
327
};
327
};
328
 
328
 
329
int SDL_VideoModeOK (int width, int height, int bpp, Uint32 flags) 
329
int SDL_VideoModeOK (int width, int height, int bpp, Uint32 flags) 
330
{
330
{
331
	int table, b, i;
331
	int table, b, i;
332
	int supported;
332
	int supported;
333
	SDL_PixelFormat format;
333
	SDL_PixelFormat format;
334
	SDL_Rect **sizes;
334
	SDL_Rect **sizes;
335
 
335
 
336
	/* Currently 1 and 4 bpp are not supported */
336
	/* Currently 1 and 4 bpp are not supported */
337
	if ( bpp < 8 || bpp > 32 ) {
337
	if ( bpp < 8 || bpp > 32 ) {
338
		return(0);
338
		return(0);
339
	}
339
	}
340
	if ( (width == 0) || (height == 0) ) {
340
	if ( (width == 0) || (height == 0) ) {
341
		return(0);
341
		return(0);
342
	}
342
	}
343
 
343
 
344
	/* Search through the list valid of modes */
344
	/* Search through the list valid of modes */
345
	memset(&format, 0, sizeof(format));
345
	memset(&format, 0, sizeof(format));
346
	supported = 0;
346
	supported = 0;
347
	table = ((bpp+7)/8)-1;
347
	table = ((bpp+7)/8)-1;
348
	SDL_closest_depths[table][0] = bpp;
348
	SDL_closest_depths[table][0] = bpp;
349
	SDL_closest_depths[table][7] = 0;
349
	SDL_closest_depths[table][7] = 0;
350
	for ( b = 0; !supported && SDL_closest_depths[table][b]; ++b ) {
350
	for ( b = 0; !supported && SDL_closest_depths[table][b]; ++b ) {
351
		format.BitsPerPixel = SDL_closest_depths[table][b];
351
		format.BitsPerPixel = SDL_closest_depths[table][b];
352
		sizes = SDL_ListModes(&format, flags);
352
		sizes = SDL_ListModes(&format, flags);
353
		if ( sizes == (SDL_Rect **)0 ) {
353
		if ( sizes == (SDL_Rect **)0 ) {
354
			/* No sizes supported at this bit-depth */
354
			/* No sizes supported at this bit-depth */
355
			continue;
355
			continue;
356
		} else 
356
		} else 
357
#ifdef macintosh /* MPW optimization bug? */
357
#ifdef macintosh /* MPW optimization bug? */
358
		if ( (sizes == (SDL_Rect **)0xFFFFFFFF) ||
358
		if ( (sizes == (SDL_Rect **)0xFFFFFFFF) ||
359
#else
359
#else
360
		if ( (sizes == (SDL_Rect **)-1) ||
360
		if ( (sizes == (SDL_Rect **)-1) ||
361
#endif
361
#endif
362
		     current_video->handles_any_size ) {
362
		     current_video->handles_any_size ) {
363
			/* Any size supported at this bit-depth */
363
			/* Any size supported at this bit-depth */
364
			supported = 1;
364
			supported = 1;
365
			continue;
365
			continue;
366
		} else
366
		} else
367
		for ( i=0; sizes[i]; ++i ) {
367
		for ( i=0; sizes[i]; ++i ) {
368
			if ((sizes[i]->w == width) && (sizes[i]->h == height)) {
368
			if ((sizes[i]->w == width) && (sizes[i]->h == height)) {
369
				supported = 1;
369
				supported = 1;
370
				break;
370
				break;
371
			}
371
			}
372
		}
372
		}
373
	}
373
	}
374
	if ( supported ) {
374
	if ( supported ) {
375
		--b;
375
		--b;
376
		return(SDL_closest_depths[table][b]);
376
		return(SDL_closest_depths[table][b]);
377
	} else {
377
	} else {
378
		return(0);
378
		return(0);
379
	}
379
	}
380
}
380
}
381
 
381
 
382
/*
382
/*
383
 * Get the closest non-emulated video mode to the one requested
383
 * Get the closest non-emulated video mode to the one requested
384
 */
384
 */
385
static int SDL_GetVideoMode (int *w, int *h, int *BitsPerPixel, Uint32 flags)
385
static int SDL_GetVideoMode (int *w, int *h, int *BitsPerPixel, Uint32 flags)
386
{
386
{
387
	int table, b, i;
387
	int table, b, i;
388
	int supported;
388
	int supported;
389
	int native_bpp;
389
	int native_bpp;
390
	SDL_PixelFormat format;
390
	SDL_PixelFormat format;
391
	SDL_Rect **sizes;
391
	SDL_Rect **sizes;
392
 
392
 
393
	/* Try the original video mode, get the closest depth */
393
	/* Try the original video mode, get the closest depth */
394
	native_bpp = SDL_VideoModeOK(*w, *h, *BitsPerPixel, flags);
394
	native_bpp = SDL_VideoModeOK(*w, *h, *BitsPerPixel, flags);
395
	if ( native_bpp == *BitsPerPixel ) {
395
	if ( native_bpp == *BitsPerPixel ) {
396
		return(1);
396
		return(1);
397
	}
397
	}
398
	if ( native_bpp > 0 ) {
398
	if ( native_bpp > 0 ) {
399
		*BitsPerPixel = native_bpp;
399
		*BitsPerPixel = native_bpp;
400
		return(1);
400
		return(1);
401
	}
401
	}
402
 
402
 
403
	/* No exact size match at any depth, look for closest match */
403
	/* No exact size match at any depth, look for closest match */
404
	memset(&format, 0, sizeof(format));
404
	memset(&format, 0, sizeof(format));
405
	supported = 0;
405
	supported = 0;
406
	table = ((*BitsPerPixel+7)/8)-1;
406
	table = ((*BitsPerPixel+7)/8)-1;
407
	SDL_closest_depths[table][0] = *BitsPerPixel;
407
	SDL_closest_depths[table][0] = *BitsPerPixel;
408
	SDL_closest_depths[table][7] = SDL_VideoSurface->format->BitsPerPixel;
408
	SDL_closest_depths[table][7] = SDL_VideoSurface->format->BitsPerPixel;
409
	for ( b = 0; !supported && SDL_closest_depths[table][b]; ++b ) {
409
	for ( b = 0; !supported && SDL_closest_depths[table][b]; ++b ) {
410
		format.BitsPerPixel = SDL_closest_depths[table][b];
410
		format.BitsPerPixel = SDL_closest_depths[table][b];
411
		sizes = SDL_ListModes(&format, flags);
411
		sizes = SDL_ListModes(&format, flags);
412
		if ( sizes == (SDL_Rect **)0 ) {
412
		if ( sizes == (SDL_Rect **)0 ) {
413
			/* No sizes supported at this bit-depth */
413
			/* No sizes supported at this bit-depth */
414
			continue;
414
			continue;
415
		}
415
		}
416
		for ( i=0; sizes[i]; ++i ) {
416
		for ( i=0; sizes[i]; ++i ) {
417
			if ((sizes[i]->w < *w) || (sizes[i]->h < *h)) {
417
			if ((sizes[i]->w < *w) || (sizes[i]->h < *h)) {
418
				if ( i > 0 ) {
418
				if ( i > 0 ) {
419
					--i;
419
					--i;
420
					*w = sizes[i]->w;
420
					*w = sizes[i]->w;
421
					*h = sizes[i]->h;
421
					*h = sizes[i]->h;
422
					*BitsPerPixel = SDL_closest_depths[table][b];
422
					*BitsPerPixel = SDL_closest_depths[table][b];
423
					supported = 1;
423
					supported = 1;
424
				} else {
424
				} else {
425
					/* Largest mode too small... */;
425
					/* Largest mode too small... */;
426
				}
426
				}
427
				break;
427
				break;
428
			}
428
			}
429
		}
429
		}
430
		if ( (i > 0) && ! sizes[i] ) {
430
		if ( (i > 0) && ! sizes[i] ) {
431
			/* The smallest mode was larger than requested, OK */
431
			/* The smallest mode was larger than requested, OK */
432
			--i;
432
			--i;
433
			*w = sizes[i]->w;
433
			*w = sizes[i]->w;
434
			*h = sizes[i]->h;
434
			*h = sizes[i]->h;
435
			*BitsPerPixel = SDL_closest_depths[table][b];
435
			*BitsPerPixel = SDL_closest_depths[table][b];
436
			supported = 1;
436
			supported = 1;
437
		}
437
		}
438
	}
438
	}
439
	if ( ! supported ) {
439
	if ( ! supported ) {
440
		SDL_SetError("No video mode large enough for %dx%d", *w, *h);
440
		SDL_SetError("No video mode large enough for %dx%d", *w, *h);
441
	}
441
	}
442
	return(supported);
442
	return(supported);
443
}
443
}
444
 
444
 
445
/* This should probably go somewhere else -- like SDL_surface.c */
445
/* This should probably go somewhere else -- like SDL_surface.c */
446
static void SDL_ClearSurface(SDL_Surface *surface)
446
static void SDL_ClearSurface(SDL_Surface *surface)
447
{
447
{
448
	Uint32 black;
448
	Uint32 black;
449
 
449
 
450
	black = SDL_MapRGB(surface->format, 0, 0, 0);
450
	black = SDL_MapRGB(surface->format, 0, 0, 0);
451
	SDL_FillRect(surface, NULL, black);
451
	SDL_FillRect(surface, NULL, black);
452
	if ((surface->flags&SDL_HWSURFACE) && (surface->flags&SDL_DOUBLEBUF)) {
452
	if ((surface->flags&SDL_HWSURFACE) && (surface->flags&SDL_DOUBLEBUF)) {
453
		SDL_Flip(surface);
453
		SDL_Flip(surface);
454
		SDL_FillRect(surface, NULL, black);
454
		SDL_FillRect(surface, NULL, black);
455
	}
455
	}
456
	SDL_Flip(surface);
456
	SDL_Flip(surface);
457
}
457
}
458
 
458
 
459
/*
459
/*
460
 * Create a shadow surface suitable for fooling the app. :-)
460
 * Create a shadow surface suitable for fooling the app. :-)
461
 */
461
 */
462
static void SDL_CreateShadowSurface(int depth)
462
static void SDL_CreateShadowSurface(int depth)
463
{
463
{
464
	Uint32 Rmask, Gmask, Bmask;
464
	Uint32 Rmask, Gmask, Bmask;
465
 
465
 
466
	/* Allocate the shadow surface */
466
	/* Allocate the shadow surface */
467
	if ( depth == (SDL_VideoSurface->format)->BitsPerPixel ) {
467
	if ( depth == (SDL_VideoSurface->format)->BitsPerPixel ) {
468
		Rmask = (SDL_VideoSurface->format)->Rmask;
468
		Rmask = (SDL_VideoSurface->format)->Rmask;
469
		Gmask = (SDL_VideoSurface->format)->Gmask;
469
		Gmask = (SDL_VideoSurface->format)->Gmask;
470
		Bmask = (SDL_VideoSurface->format)->Bmask;
470
		Bmask = (SDL_VideoSurface->format)->Bmask;
471
	} else {
471
	} else {
472
		Rmask = Gmask = Bmask = 0;
472
		Rmask = Gmask = Bmask = 0;
473
	}
473
	}
474
	SDL_ShadowSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,
474
	SDL_ShadowSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,
475
				SDL_VideoSurface->w, SDL_VideoSurface->h,
475
				SDL_VideoSurface->w, SDL_VideoSurface->h,
476
						depth, Rmask, Gmask, Bmask, 0);
476
						depth, Rmask, Gmask, Bmask, 0);
477
	if ( SDL_ShadowSurface == NULL ) {
477
	if ( SDL_ShadowSurface == NULL ) {
478
		return;
478
		return;
479
	}
479
	}
480
 
480
 
481
	/* 8-bit shadow surfaces report that they have exclusive palette */
481
	/* 8-bit shadow surfaces report that they have exclusive palette */
482
	if ( SDL_ShadowSurface->format->palette ) {
482
	if ( SDL_ShadowSurface->format->palette ) {
483
		SDL_ShadowSurface->flags |= SDL_HWPALETTE;
483
		SDL_ShadowSurface->flags |= SDL_HWPALETTE;
484
		if ( depth == (SDL_VideoSurface->format)->BitsPerPixel ) {
484
		if ( depth == (SDL_VideoSurface->format)->BitsPerPixel ) {
485
			memcpy(SDL_ShadowSurface->format->palette->colors,
485
			memcpy(SDL_ShadowSurface->format->palette->colors,
486
				SDL_VideoSurface->format->palette->colors,
486
				SDL_VideoSurface->format->palette->colors,
487
				SDL_VideoSurface->format->palette->ncolors*
487
				SDL_VideoSurface->format->palette->ncolors*
488
							sizeof(SDL_Color));
488
							sizeof(SDL_Color));
489
		} else {
489
		} else {
490
			SDL_DitherColors(
490
			SDL_DitherColors(
491
			SDL_ShadowSurface->format->palette->colors, depth);
491
			SDL_ShadowSurface->format->palette->colors, depth);
492
		}
492
		}
493
	}
493
	}
494
 
494
 
495
	/* If the video surface is resizable, the shadow should say so */
495
	/* If the video surface is resizable, the shadow should say so */
496
	if ( (SDL_VideoSurface->flags & SDL_RESIZABLE) == SDL_RESIZABLE ) {
496
	if ( (SDL_VideoSurface->flags & SDL_RESIZABLE) == SDL_RESIZABLE ) {
497
		SDL_ShadowSurface->flags |= SDL_RESIZABLE;
497
		SDL_ShadowSurface->flags |= SDL_RESIZABLE;
498
	}
498
	}
499
	/* If the video surface has no frame, the shadow should say so */
499
	/* If the video surface has no frame, the shadow should say so */
500
	if ( (SDL_VideoSurface->flags & SDL_NOFRAME) == SDL_NOFRAME ) {
500
	if ( (SDL_VideoSurface->flags & SDL_NOFRAME) == SDL_NOFRAME ) {
501
		SDL_ShadowSurface->flags |= SDL_NOFRAME;
501
		SDL_ShadowSurface->flags |= SDL_NOFRAME;
502
	}
502
	}
503
	/* If the video surface is fullscreen, the shadow should say so */
503
	/* If the video surface is fullscreen, the shadow should say so */
504
	if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
504
	if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
505
		SDL_ShadowSurface->flags |= SDL_FULLSCREEN;
505
		SDL_ShadowSurface->flags |= SDL_FULLSCREEN;
506
	}
506
	}
507
	/* If the video surface is flippable, the shadow should say so */
507
	/* If the video surface is flippable, the shadow should say so */
508
	if ( (SDL_VideoSurface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
508
	if ( (SDL_VideoSurface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
509
		SDL_ShadowSurface->flags |= SDL_DOUBLEBUF;
509
		SDL_ShadowSurface->flags |= SDL_DOUBLEBUF;
510
	}
510
	}
511
	return;
511
	return;
512
}
512
}
513
 
513
 
514
/*
514
/*
515
 * Set the requested video mode, allocating a shadow buffer if necessary.
515
 * Set the requested video mode, allocating a shadow buffer if necessary.
516
 */
516
 */
517
SDL_Surface * SDL_SetVideoMode (int width, int height, int bpp, Uint32 flags)
517
SDL_Surface * SDL_SetVideoMode (int width, int height, int bpp, Uint32 flags)
518
{
518
{
519
	SDL_VideoDevice *video, *this;
519
	SDL_VideoDevice *video, *this;
520
	SDL_Surface *prev_mode, *mode;
520
	SDL_Surface *prev_mode, *mode;
521
	int video_w;
521
	int video_w;
522
	int video_h;
522
	int video_h;
523
	int video_bpp;
523
	int video_bpp;
524
	int is_opengl;
524
	int is_opengl;
525
	SDL_GrabMode saved_grab;
525
	SDL_GrabMode saved_grab;
526
 
526
 
527
	/* Start up the video driver, if necessary..
527
	/* Start up the video driver, if necessary..
528
	   WARNING: This is the only function protected this way!
528
	   WARNING: This is the only function protected this way!
529
	 */
529
	 */
530
	if ( ! current_video ) {
530
	if ( ! current_video ) {
531
		if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE) < 0 ) {
531
		if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE) < 0 ) {
532
			return(NULL);
532
			return(NULL);
533
		}
533
		}
534
	}
534
	}
535
	this = video = current_video;
535
	this = video = current_video;
536
 
536
 
537
	/* Default to the current video bpp */
537
	/* Default to the current video bpp */
538
	if ( bpp == 0 ) {
538
	if ( bpp == 0 ) {
539
		flags |= SDL_ANYFORMAT;
539
		flags |= SDL_ANYFORMAT;
540
		bpp = SDL_VideoSurface->format->BitsPerPixel;
540
		bpp = SDL_VideoSurface->format->BitsPerPixel;
541
	}
541
	}
542
 
542
 
543
	/* Get a good video mode, the closest one possible */
543
	/* Get a good video mode, the closest one possible */
544
	video_w = width;
544
	video_w = width;
545
	video_h = height;
545
	video_h = height;
546
	video_bpp = bpp;
546
	video_bpp = bpp;
547
	if ( ! SDL_GetVideoMode(&video_w, &video_h, &video_bpp, flags) ) {
547
	if ( ! SDL_GetVideoMode(&video_w, &video_h, &video_bpp, flags) ) {
548
		return(NULL);
548
		return(NULL);
549
	}
549
	}
550
 
550
 
551
	/* Check the requested flags */
551
	/* Check the requested flags */
552
	/* There's no palette in > 8 bits-per-pixel mode */
552
	/* There's no palette in > 8 bits-per-pixel mode */
553
	if ( video_bpp > 8 ) {
553
	if ( video_bpp > 8 ) {
554
		flags &= ~SDL_HWPALETTE;
554
		flags &= ~SDL_HWPALETTE;
555
	}
555
	}
556
#if 0
556
#if 0
557
	if ( (flags&SDL_FULLSCREEN) != SDL_FULLSCREEN ) {
557
	if ( (flags&SDL_FULLSCREEN) != SDL_FULLSCREEN ) {
558
		/* There's no windowed double-buffering */
558
		/* There's no windowed double-buffering */
559
		flags &= ~SDL_DOUBLEBUF;
559
		flags &= ~SDL_DOUBLEBUF;
560
	}
560
	}
561
#endif
561
#endif
562
	if ( (flags&SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
562
	if ( (flags&SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
563
		/* Use hardware surfaces when double-buffering */
563
		/* Use hardware surfaces when double-buffering */
564
		flags |= SDL_HWSURFACE;
564
		flags |= SDL_HWSURFACE;
565
	}
565
	}
566
 
566
 
567
	is_opengl = ( ( flags & SDL_OPENGL ) == SDL_OPENGL );
567
	is_opengl = ( ( flags & SDL_OPENGL ) == SDL_OPENGL );
568
	if ( is_opengl ) {
568
	if ( is_opengl ) {
569
		/* These flags are for 2D video modes only */
569
		/* These flags are for 2D video modes only */
570
		flags &= ~(SDL_HWSURFACE|SDL_DOUBLEBUF);
570
		flags &= ~(SDL_HWSURFACE|SDL_DOUBLEBUF);
571
	}
571
	}
572
 
572
 
573
	/* Reset the keyboard here so event callbacks can run */
573
	/* Reset the keyboard here so event callbacks can run */
574
	SDL_ResetKeyboard();
574
	SDL_ResetKeyboard();
575
 
575
 
576
	/* Clean up any previous video mode */
576
	/* Clean up any previous video mode */
577
	if ( SDL_PublicSurface != NULL ) {
577
	if ( SDL_PublicSurface != NULL ) {
578
		SDL_PublicSurface = NULL;
578
		SDL_PublicSurface = NULL;
579
	}
579
	}
580
	if ( SDL_ShadowSurface != NULL ) {
580
	if ( SDL_ShadowSurface != NULL ) {
581
		SDL_Surface *ready_to_go;
581
		SDL_Surface *ready_to_go;
582
		ready_to_go = SDL_ShadowSurface;
582
		ready_to_go = SDL_ShadowSurface;
583
		SDL_ShadowSurface = NULL;
583
		SDL_ShadowSurface = NULL;
584
		SDL_FreeSurface(ready_to_go);
584
		SDL_FreeSurface(ready_to_go);
585
	}
585
	}
586
	if ( video->physpal ) {
586
	if ( video->physpal ) {
587
		free(video->physpal->colors);
587
		free(video->physpal->colors);
588
		free(video->physpal);
588
		free(video->physpal);
589
		video->physpal = NULL;
589
		video->physpal = NULL;
590
	}
590
	}
591
	if( video->gammacols) {
591
	if( video->gammacols) {
592
	        free(video->gammacols);
592
	        free(video->gammacols);
593
		video->gammacols = NULL;
593
		video->gammacols = NULL;
594
	}
594
	}
595
 
595
 
596
	/* Save the previous grab state and turn off grab for mode switch */
596
	/* Save the previous grab state and turn off grab for mode switch */
597
	saved_grab = SDL_WM_GrabInputOff();
597
	saved_grab = SDL_WM_GrabInputOff();
598
 
598
 
599
	/* Try to set the video mode, along with offset and clipping */
599
	/* Try to set the video mode, along with offset and clipping */
600
	prev_mode = SDL_VideoSurface;
600
	prev_mode = SDL_VideoSurface;
601
	SDL_LockCursor();
601
	SDL_LockCursor();
602
	SDL_VideoSurface = NULL;	/* In case it's freed by driver */
602
	SDL_VideoSurface = NULL;	/* In case it's freed by driver */
603
	mode = video->SetVideoMode(this, prev_mode,video_w,video_h,video_bpp,flags);
603
	mode = video->SetVideoMode(this, prev_mode,video_w,video_h,video_bpp,flags);
604
	if ( mode ) { /* Prevent resize events from mode change */
604
	if ( mode ) { /* Prevent resize events from mode change */
605
	    SDL_PrivateResize(mode->w, mode->h);
605
	    SDL_PrivateResize(mode->w, mode->h);
606
        }
606
        }
607
	/*
607
	/*
608
	 * rcg11292000
608
	 * rcg11292000
609
	 * If you try to set an SDL_OPENGL surface, and fail to find a
609
	 * If you try to set an SDL_OPENGL surface, and fail to find a
610
	 * matching  visual, then the next call to SDL_SetVideoMode()
610
	 * matching  visual, then the next call to SDL_SetVideoMode()
611
	 * will segfault, since  we no longer point to a dummy surface,
611
	 * will segfault, since  we no longer point to a dummy surface,
612
	 * but rather NULL.
612
	 * but rather NULL.
613
	 * Sam 11/29/00
613
	 * Sam 11/29/00
614
	 * WARNING, we need to make sure that the previous mode hasn't
614
	 * WARNING, we need to make sure that the previous mode hasn't
615
	 * already been freed by the video driver.  What do we do in
615
	 * already been freed by the video driver.  What do we do in
616
	 * that case?  Should we call SDL_VideoInit() again?
616
	 * that case?  Should we call SDL_VideoInit() again?
617
	 */
617
	 */
618
	SDL_VideoSurface = (mode != NULL) ? mode : prev_mode;
618
	SDL_VideoSurface = (mode != NULL) ? mode : prev_mode;
619
 
619
 
620
	if ( (mode != NULL) && (!is_opengl) ) {
620
	if ( (mode != NULL) && (!is_opengl) ) {
621
		/* Sanity check */
621
		/* Sanity check */
622
		if ( (mode->w < width) || (mode->h < height) ) {
622
		if ( (mode->w < width) || (mode->h < height) ) {
623
			SDL_SetError("Video mode smaller than requested");
623
			SDL_SetError("Video mode smaller than requested");
624
			return(NULL);
624
			return(NULL);
625
		}
625
		}
626
 
626
 
627
		/* If we have a palettized surface, create a default palette */
627
		/* If we have a palettized surface, create a default palette */
628
		if ( mode->format->palette ) {
628
		if ( mode->format->palette ) {
629
	        	SDL_PixelFormat *vf = mode->format;
629
	        	SDL_PixelFormat *vf = mode->format;
630
			SDL_DitherColors(vf->palette->colors, vf->BitsPerPixel);
630
			SDL_DitherColors(vf->palette->colors, vf->BitsPerPixel);
631
			video->SetColors(this, 0, vf->palette->ncolors,
631
			video->SetColors(this, 0, vf->palette->ncolors,
632
			                           vf->palette->colors);
632
			                           vf->palette->colors);
633
		}
633
		}
634
 
634
 
635
		/* Clear the surface to black */
635
		/* Clear the surface to black */
636
		video->offset_x = 0;
636
		video->offset_x = 0;
637
		video->offset_y = 0;
637
		video->offset_y = 0;
638
		mode->offset = 0;
638
		mode->offset = 0;
639
		SDL_SetClipRect(mode, NULL);
639
		SDL_SetClipRect(mode, NULL);
640
		SDL_ClearSurface(mode);
640
		SDL_ClearSurface(mode);
641
 
641
 
642
		/* Now adjust the offsets to match the desired mode */
642
		/* Now adjust the offsets to match the desired mode */
643
		video->offset_x = (mode->w-width)/2;
643
		video->offset_x = (mode->w-width)/2;
644
		video->offset_y = (mode->h-height)/2;
644
		video->offset_y = (mode->h-height)/2;
645
		mode->offset = video->offset_y*mode->pitch +
645
		mode->offset = video->offset_y*mode->pitch +
646
				video->offset_x*mode->format->BytesPerPixel;
646
				video->offset_x*mode->format->BytesPerPixel;
647
#ifdef DEBUG_VIDEO
647
#ifdef DEBUG_VIDEO
648
 SDL_printf("Requested mode: %dx%dx%d, obtained mode %dx%dx%d (offset %d)\n",
648
 SDL_printf("Requested mode: %dx%dx%d, obtained mode %dx%dx%d (offset %d)\n",
649
		width, height, bpp,
649
		width, height, bpp,
650
		mode->w, mode->h, mode->format->BitsPerPixel, mode->offset);
650
		mode->w, mode->h, mode->format->BitsPerPixel, mode->offset);
651
#endif
651
#endif
652
		mode->w = width;
652
		mode->w = width;
653
		mode->h = height;
653
		mode->h = height;
654
		SDL_SetClipRect(mode, NULL);
654
		SDL_SetClipRect(mode, NULL);
655
	}
655
	}
656
	SDL_ResetCursor();
656
	SDL_ResetCursor();
657
	SDL_UnlockCursor();
657
	SDL_UnlockCursor();
658
 
658
 
659
	/* If we failed setting a video mode, return NULL... (Uh Oh!) */
659
	/* If we failed setting a video mode, return NULL... (Uh Oh!) */
660
	if ( mode == NULL ) {
660
	if ( mode == NULL ) {
661
		return(NULL);
661
		return(NULL);
662
	}
662
	}
663
 
663
 
664
	/* If there is no window manager, set the SDL_NOFRAME flag */
664
	/* If there is no window manager, set the SDL_NOFRAME flag */
665
	if ( ! video->info.wm_available ) {
665
	if ( ! video->info.wm_available ) {
666
		mode->flags |= SDL_NOFRAME;
666
		mode->flags |= SDL_NOFRAME;
667
	}
667
	}
668
 
668
 
669
	/* Reset the mouse cursor and grab for new video mode */
669
	/* Reset the mouse cursor and grab for new video mode */
670
	SDL_SetCursor(NULL);
670
	SDL_SetCursor(NULL);
671
	if ( video->UpdateMouse ) {
671
	if ( video->UpdateMouse ) {
672
		video->UpdateMouse(this);
672
		video->UpdateMouse(this);
673
	}
673
	}
674
	SDL_WM_GrabInput(saved_grab);
674
	SDL_WM_GrabInput(saved_grab);
675
	SDL_GetRelativeMouseState(NULL, NULL); /* Clear first large delta */
675
	SDL_GetRelativeMouseState(NULL, NULL); /* Clear first large delta */
676
 
676
 
677
	/* If we're running OpenGL, make the context current */
677
	/* If we're running OpenGL, make the context current */
678
	if ( (video->screen->flags & SDL_OPENGL) &&
678
	if ( (video->screen->flags & SDL_OPENGL) &&
679
	      video->GL_MakeCurrent ) {
679
	      video->GL_MakeCurrent ) {
680
		if ( video->GL_MakeCurrent(this) < 0 ) {
680
		if ( video->GL_MakeCurrent(this) < 0 ) {
681
			return(NULL);
681
			return(NULL);
682
		}
682
		}
683
	}
683
	}
684
 
684
 
685
	/* Set up a fake SDL surface for OpenGL "blitting" */
685
	/* Set up a fake SDL surface for OpenGL "blitting" */
686
	if ( (flags & SDL_OPENGLBLIT) == SDL_OPENGLBLIT ) {
686
	if ( (flags & SDL_OPENGLBLIT) == SDL_OPENGLBLIT ) {
687
		/* Load GL functions for performing the texture updates */
687
		/* Load GL functions for performing the texture updates */
688
#ifdef HAVE_OPENGL
688
#ifdef HAVE_OPENGL
689
#define SDL_PROC(ret,func,params) \
689
#define SDL_PROC(ret,func,params) \
690
do { \
690
do { \
691
	video->func = SDL_GL_GetProcAddress(#func); \
691
	video->func = SDL_GL_GetProcAddress(#func); \
692
	if ( ! video->func ) { \
692
	if ( ! video->func ) { \
693
		SDL_SetError("Couldn't load GL function: %s\n", #func); \
693
		SDL_SetError("Couldn't load GL function: %s\n", #func); \
694
		return(NULL); \
694
		return(NULL); \
695
	} \
695
	} \
696
} while ( 0 );
696
} while ( 0 );
697
#include "SDL_glfuncs.h"
697
#include "SDL_glfuncs.h"
698
#undef SDL_PROC	
698
#undef SDL_PROC	
699
 
699
 
700
		/* Create a software surface for blitting */
700
		/* Create a software surface for blitting */
701
#ifdef GL_VERSION_1_2
701
#ifdef GL_VERSION_1_2
702
		/* If the implementation either supports the packed pixels
702
		/* If the implementation either supports the packed pixels
703
		   extension, or implements the core OpenGL 1.2 API, it will
703
		   extension, or implements the core OpenGL 1.2 API, it will
704
		   support the GL_UNSIGNED_SHORT_5_6_5 texture format.
704
		   support the GL_UNSIGNED_SHORT_5_6_5 texture format.
705
		 */
705
		 */
706
		if ( (bpp == 16) &&
706
		if ( (bpp == 16) &&
707
		     (strstr((const char *)video->glGetString(GL_EXTENSIONS),
707
		     (strstr((const char *)video->glGetString(GL_EXTENSIONS),
708
		                           "GL_EXT_packed_pixels") ||
708
		                           "GL_EXT_packed_pixels") ||
709
		     (strncmp((const char *)video->glGetString(GL_VERSION),
709
		     (strncmp((const char *)video->glGetString(GL_VERSION),
710
		              "1.2", 3) == 0)) )
710
		              "1.2", 3) == 0)) )
711
		{
711
		{
712
			video->is_32bit = 0;
712
			video->is_32bit = 0;
713
			SDL_VideoSurface = SDL_CreateRGBSurface(
713
			SDL_VideoSurface = SDL_CreateRGBSurface(
714
				flags, 
714
				flags, 
715
				width, 
715
				width, 
716
				height,  
716
				height,  
717
				16,
717
				16,
718
				31 << 11,
718
				31 << 11,
719
				63 << 5,
719
				63 << 5,
720
				31,
720
				31,
721
				0
721
				0
722
				);
722
				);
723
		}
723
		}
724
		else
724
		else
725
#endif /* OpenGL 1.2 */
725
#endif /* OpenGL 1.2 */
726
		{
726
		{
727
			video->is_32bit = 1;
727
			video->is_32bit = 1;
728
			SDL_VideoSurface = SDL_CreateRGBSurface(
728
			SDL_VideoSurface = SDL_CreateRGBSurface(
729
				flags, 
729
				flags, 
730
				width, 
730
				width, 
731
				height, 
731
				height, 
732
				32, 
732
				32, 
733
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
733
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
734
				0x000000FF,
734
				0x000000FF,
735
				0x0000FF00,
735
				0x0000FF00,
736
				0x00FF0000,
736
				0x00FF0000,
737
				0xFF000000
737
				0xFF000000
738
#else
738
#else
739
				0xFF000000,
739
				0xFF000000,
740
				0x00FF0000,
740
				0x00FF0000,
741
				0x0000FF00,
741
				0x0000FF00,
742
				0x000000FF
742
				0x000000FF
743
#endif
743
#endif
744
				);
744
				);
745
		}
745
		}
746
		if ( ! SDL_VideoSurface ) {
746
		if ( ! SDL_VideoSurface ) {
747
			return(NULL);
747
			return(NULL);
748
		}
748
		}
749
		SDL_VideoSurface->flags = mode->flags | SDL_OPENGLBLIT;
749
		SDL_VideoSurface->flags = mode->flags | SDL_OPENGLBLIT;
750
 
750
 
751
		/* Free the original video mode surface (is this safe?) */
751
		/* Free the original video mode surface (is this safe?) */
752
		SDL_FreeSurface(mode);
752
		SDL_FreeSurface(mode);
753
 
753
 
754
                /* Set the surface completely opaque & white by default */
754
                /* Set the surface completely opaque & white by default */
755
		memset( SDL_VideoSurface->pixels, 255, SDL_VideoSurface->h * SDL_VideoSurface->pitch );
755
		memset( SDL_VideoSurface->pixels, 255, SDL_VideoSurface->h * SDL_VideoSurface->pitch );
756
		video->glGenTextures( 1, &video->texture );
756
		video->glGenTextures( 1, &video->texture );
757
		video->glBindTexture( GL_TEXTURE_2D, video->texture );
757
		video->glBindTexture( GL_TEXTURE_2D, video->texture );
758
		video->glTexImage2D(
758
		video->glTexImage2D(
759
			GL_TEXTURE_2D,
759
			GL_TEXTURE_2D,
760
			0,
760
			0,
761
			video->is_32bit ? GL_RGBA : GL_RGB,
761
			video->is_32bit ? GL_RGBA : GL_RGB,
762
			256,
762
			256,
763
			256,
763
			256,
764
			0,
764
			0,
765
			video->is_32bit ? GL_RGBA : GL_RGB,
765
			video->is_32bit ? GL_RGBA : GL_RGB,
766
#ifdef GL_VERSION_1_2
766
#ifdef GL_VERSION_1_2
767
			video->is_32bit ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5,
767
			video->is_32bit ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5,
768
#else
768
#else
769
			GL_UNSIGNED_BYTE,
769
			GL_UNSIGNED_BYTE,
770
#endif
770
#endif
771
			NULL);
771
			NULL);
772
 
772
 
773
		video->UpdateRects = SDL_GL_UpdateRectsLock;
773
		video->UpdateRects = SDL_GL_UpdateRectsLock;
774
#else
774
#else
775
		SDL_SetError("Somebody forgot to #define HAVE_OPENGL");
775
		SDL_SetError("Somebody forgot to #define HAVE_OPENGL");
776
		return(NULL);
776
		return(NULL);
777
#endif
777
#endif
778
	}
778
	}
779
 
779
 
780
	/* Create a shadow surface if necessary */
780
	/* Create a shadow surface if necessary */
781
	/* There are three conditions under which we create a shadow surface:
781
	/* There are three conditions under which we create a shadow surface:
782
		1.  We need a particular bits-per-pixel that we didn't get.
782
		1.  We need a particular bits-per-pixel that we didn't get.
783
		2.  We need a hardware palette and didn't get one.
783
		2.  We need a hardware palette and didn't get one.
784
		3.  We need a software surface and got a hardware surface.
784
		3.  We need a software surface and got a hardware surface.
785
	*/
785
	*/
786
	if ( !(SDL_VideoSurface->flags & SDL_OPENGL) &&
786
	if ( !(SDL_VideoSurface->flags & SDL_OPENGL) &&
787
	     (
787
	     (
788
	     (  !(flags&SDL_ANYFORMAT) &&
788
	     (  !(flags&SDL_ANYFORMAT) &&
789
			(SDL_VideoSurface->format->BitsPerPixel != bpp)) ||
789
			(SDL_VideoSurface->format->BitsPerPixel != bpp)) ||
790
	     (   (flags&SDL_HWPALETTE) && 
790
	     (   (flags&SDL_HWPALETTE) && 
791
				!(SDL_VideoSurface->flags&SDL_HWPALETTE)) ||
791
				!(SDL_VideoSurface->flags&SDL_HWPALETTE)) ||
792
		/* If the surface is in hardware, video writes are visible
792
		/* If the surface is in hardware, video writes are visible
793
		   as soon as they are performed, so we need to buffer them
793
		   as soon as they are performed, so we need to buffer them
794
		 */
794
		 */
795
	     (   ((flags&SDL_HWSURFACE) == SDL_SWSURFACE) &&
795
	     (   ((flags&SDL_HWSURFACE) == SDL_SWSURFACE) &&
796
				(SDL_VideoSurface->flags&SDL_HWSURFACE))
796
				(SDL_VideoSurface->flags&SDL_HWSURFACE))
797
	     ) ) {
797
	     ) ) {
798
		SDL_CreateShadowSurface(bpp);
798
		SDL_CreateShadowSurface(bpp);
799
		if ( SDL_ShadowSurface == NULL ) {
799
		if ( SDL_ShadowSurface == NULL ) {
800
			SDL_SetError("Couldn't create shadow surface");
800
			SDL_SetError("Couldn't create shadow surface");
801
			return(NULL);
801
			return(NULL);
802
		}
802
		}
803
		SDL_PublicSurface = SDL_ShadowSurface;
803
		SDL_PublicSurface = SDL_ShadowSurface;
804
	} else {
804
	} else {
805
		SDL_PublicSurface = SDL_VideoSurface;
805
		SDL_PublicSurface = SDL_VideoSurface;
806
	}
806
	}
807
	video->info.vfmt = SDL_VideoSurface->format;
807
	video->info.vfmt = SDL_VideoSurface->format;
808
 
808
 
809
	/* We're done! */
809
	/* We're done! */
810
	return(SDL_PublicSurface);
810
	return(SDL_PublicSurface);
811
}
811
}
812
 
812
 
813
/* 
813
/* 
814
 * Convert a surface into the video pixel format.
814
 * Convert a surface into the video pixel format.
815
 */
815
 */
816
SDL_Surface * SDL_DisplayFormat (SDL_Surface *surface)
816
SDL_Surface * SDL_DisplayFormat (SDL_Surface *surface)
817
{
817
{
818
	Uint32 flags;
818
	Uint32 flags;
819
 
819
 
820
	if ( ! SDL_PublicSurface ) {
820
	if ( ! SDL_PublicSurface ) {
821
		SDL_SetError("No video mode has been set");
821
		SDL_SetError("No video mode has been set");
822
		return(NULL);
822
		return(NULL);
823
	}
823
	}
824
	/* Set the flags appropriate for copying to display surface */
824
	/* Set the flags appropriate for copying to display surface */
825
	flags  = (SDL_PublicSurface->flags&SDL_HWSURFACE);
825
	flags  = (SDL_PublicSurface->flags&SDL_HWSURFACE);
826
#ifdef AUTORLE_DISPLAYFORMAT
826
#ifdef AUTORLE_DISPLAYFORMAT
827
	flags |= (surface->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA));
827
	flags |= (surface->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA));
828
	flags |= SDL_RLEACCELOK;
828
	flags |= SDL_RLEACCELOK;
829
#else
829
#else
830
	flags |= surface->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA|SDL_RLEACCELOK);
830
	flags |= surface->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA|SDL_RLEACCELOK);
831
#endif
831
#endif
832
	return(SDL_ConvertSurface(surface, SDL_PublicSurface->format, flags));
832
	return(SDL_ConvertSurface(surface, SDL_PublicSurface->format, flags));
833
}
833
}
834
 
834
 
835
/*
835
/*
836
 * Convert a surface into a format that's suitable for blitting to
836
 * Convert a surface into a format that's suitable for blitting to
837
 * the screen, but including an alpha channel.
837
 * the screen, but including an alpha channel.
838
 */
838
 */
839
SDL_Surface *SDL_DisplayFormatAlpha(SDL_Surface *surface)
839
SDL_Surface *SDL_DisplayFormatAlpha(SDL_Surface *surface)
840
{
840
{
841
	SDL_PixelFormat *vf;
841
	SDL_PixelFormat *vf;
842
	SDL_PixelFormat *format;
842
	SDL_PixelFormat *format;
843
	SDL_Surface *converted;
843
	SDL_Surface *converted;
844
	Uint32 flags;
844
	Uint32 flags;
845
	/* default to ARGB8888 */
845
	/* default to ARGB8888 */
846
	Uint32 amask = 0xff000000;
846
	Uint32 amask = 0xff000000;
847
	Uint32 rmask = 0x00ff0000;
847
	Uint32 rmask = 0x00ff0000;
848
	Uint32 gmask = 0x0000ff00;
848
	Uint32 gmask = 0x0000ff00;
849
	Uint32 bmask = 0x000000ff;
849
	Uint32 bmask = 0x000000ff;
850
 
850
 
851
	if ( ! SDL_PublicSurface ) {
851
	if ( ! SDL_PublicSurface ) {
852
		SDL_SetError("No video mode has been set");
852
		SDL_SetError("No video mode has been set");
853
		return(NULL);
853
		return(NULL);
854
	}
854
	}
855
	vf = SDL_PublicSurface->format;
855
	vf = SDL_PublicSurface->format;
856
 
856
 
857
	switch(vf->BytesPerPixel) {
857
	switch(vf->BytesPerPixel) {
858
	    case 2:
858
	    case 2:
859
		/* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}.
859
		/* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}.
860
		   For anything else (like ARGB4444) it doesn't matter
860
		   For anything else (like ARGB4444) it doesn't matter
861
		   since we have no special code for it anyway */
861
		   since we have no special code for it anyway */
862
		if ( (vf->Rmask == 0x1f) &&
862
		if ( (vf->Rmask == 0x1f) &&
863
		     (vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) {
863
		     (vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) {
864
			rmask = 0xff;
864
			rmask = 0xff;
865
			bmask = 0xff0000;
865
			bmask = 0xff0000;
866
		}
866
		}
867
		break;
867
		break;
868
 
868
 
869
	    case 3:
869
	    case 3:
870
	    case 4:
870
	    case 4:
871
		/* Keep the video format, as long as the high 8 bits are
871
		/* Keep the video format, as long as the high 8 bits are
872
		   unused or alpha */
872
		   unused or alpha */
873
		if ( (vf->Rmask == 0xff) && (vf->Bmask == 0xff0000) ) {
873
		if ( (vf->Rmask == 0xff) && (vf->Bmask == 0xff0000) ) {
874
			rmask = 0xff;
874
			rmask = 0xff;
875
			bmask = 0xff0000;
875
			bmask = 0xff0000;
876
		}
876
		}
877
		break;
877
		break;
878
 
878
 
879
	    default:
879
	    default:
880
		/* We have no other optimised formats right now. When/if a new
880
		/* We have no other optimised formats right now. When/if a new
881
		   optimised alpha format is written, add the converter here */
881
		   optimised alpha format is written, add the converter here */
882
		break;
882
		break;
883
	}
883
	}
884
	format = SDL_AllocFormat(32, rmask, gmask, bmask, amask);
884
	format = SDL_AllocFormat(32, rmask, gmask, bmask, amask);
885
	flags = SDL_PublicSurface->flags & SDL_HWSURFACE;
885
	flags = SDL_PublicSurface->flags & SDL_HWSURFACE;
886
	flags |= surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
886
	flags |= surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
887
	converted = SDL_ConvertSurface(surface, format, flags);
887
	converted = SDL_ConvertSurface(surface, format, flags);
888
	SDL_FreeFormat(format);
888
	SDL_FreeFormat(format);
889
	return(converted);
889
	return(converted);
890
}
890
}
891
 
891
 
892
/*
892
/*
893
 * Update a specific portion of the physical screen
893
 * Update a specific portion of the physical screen
894
 */
894
 */
895
void SDL_UpdateRect(SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h)
895
void SDL_UpdateRect(SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h)
896
{
896
{
897
	if ( screen ) {
897
	if ( screen ) {
898
		SDL_Rect rect;
898
		SDL_Rect rect;
899
 
899
 
900
		/* Perform some checking */
900
		/* Perform some checking */
901
		if ( w == 0 )
901
		if ( w == 0 )
902
			w = screen->w;
902
			w = screen->w;
903
		if ( h == 0 )
903
		if ( h == 0 )
904
			h = screen->h;
904
			h = screen->h;
905
		if ( (int)(x+w) > screen->w )
905
		if ( (int)(x+w) > screen->w )
906
			return;
906
			return;
907
		if ( (int)(y+h) > screen->h )
907
		if ( (int)(y+h) > screen->h )
908
			return;
908
			return;
909
 
909
 
910
		/* Fill the rectangle */
910
		/* Fill the rectangle */
911
		rect.x = x;
911
		rect.x = x;
912
		rect.y = y;
912
		rect.y = y;
913
		rect.w = w;
913
		rect.w = w;
914
		rect.h = h;
914
		rect.h = h;
915
		SDL_UpdateRects(screen, 1, &rect);
915
		SDL_UpdateRects(screen, 1, &rect);
916
	}
916
	}
917
}
917
}
918
void SDL_UpdateRects (SDL_Surface *screen, int numrects, SDL_Rect *rects)
918
void SDL_UpdateRects (SDL_Surface *screen, int numrects, SDL_Rect *rects)
919
{
919
{
920
	int i;
920
	int i;
921
	SDL_VideoDevice *video = current_video;
921
	SDL_VideoDevice *video = current_video;
922
	SDL_VideoDevice *this = current_video;
922
	SDL_VideoDevice *this = current_video;
923
 
923
 
924
	if ( screen == SDL_ShadowSurface ) {
924
	if ( screen == SDL_ShadowSurface ) {
925
		/* Blit the shadow surface using saved mapping */
925
		/* Blit the shadow surface using saved mapping */
926
	        SDL_Palette *pal = screen->format->palette;
926
	        SDL_Palette *pal = screen->format->palette;
927
		SDL_Color *saved_colors = NULL;
927
		SDL_Color *saved_colors = NULL;
928
	        if ( pal && !(SDL_VideoSurface->flags & SDL_HWPALETTE) ) {
928
	        if ( pal && !(SDL_VideoSurface->flags & SDL_HWPALETTE) ) {
929
			/* simulated 8bpp, use correct physical palette */
929
			/* simulated 8bpp, use correct physical palette */
930
			saved_colors = pal->colors;
930
			saved_colors = pal->colors;
931
			if ( video->gammacols ) {
931
			if ( video->gammacols ) {
932
				/* gamma-corrected palette */
932
				/* gamma-corrected palette */
933
				pal->colors = video->gammacols;
933
				pal->colors = video->gammacols;
934
			} else if ( video->physpal ) {
934
			} else if ( video->physpal ) {
935
				/* physical palette different from logical */
935
				/* physical palette different from logical */
936
				pal->colors = video->physpal->colors;
936
				pal->colors = video->physpal->colors;
937
			}
937
			}
938
		}
938
		}
939
		if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) {
939
		if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) {
940
			SDL_LockCursor();
940
			SDL_LockCursor();
941
			SDL_DrawCursor(SDL_ShadowSurface);
941
			SDL_DrawCursor(SDL_ShadowSurface);
942
			for ( i=0; i
942
			for ( i=0; i
943
				SDL_LowerBlit(SDL_ShadowSurface, &rects[i], 
943
				SDL_LowerBlit(SDL_ShadowSurface, &rects[i], 
944
						SDL_VideoSurface, &rects[i]);
944
						SDL_VideoSurface, &rects[i]);
945
			}
945
			}
946
			SDL_EraseCursor(SDL_ShadowSurface);
946
			SDL_EraseCursor(SDL_ShadowSurface);
947
			SDL_UnlockCursor();
947
			SDL_UnlockCursor();
948
		} else {
948
		} else {
949
			for ( i=0; i
949
			for ( i=0; i
950
				SDL_LowerBlit(SDL_ShadowSurface, &rects[i], 
950
				SDL_LowerBlit(SDL_ShadowSurface, &rects[i], 
951
						SDL_VideoSurface, &rects[i]);
951
						SDL_VideoSurface, &rects[i]);
952
			}
952
			}
953
		}
953
		}
954
		if ( saved_colors )
954
		if ( saved_colors )
955
			pal->colors = saved_colors;
955
			pal->colors = saved_colors;
956
 
956
 
957
		/* Fall through to video surface update */
957
		/* Fall through to video surface update */
958
		screen = SDL_VideoSurface;
958
		screen = SDL_VideoSurface;
959
	}
959
	}
960
	if ( screen == SDL_VideoSurface ) {
960
	if ( screen == SDL_VideoSurface ) {
961
		/* Update the video surface */
961
		/* Update the video surface */
962
		if ( screen->offset ) {
962
		if ( screen->offset ) {
963
			for ( i=0; i
963
			for ( i=0; i
964
				rects[i].x += video->offset_x;
964
				rects[i].x += video->offset_x;
965
				rects[i].y += video->offset_y;
965
				rects[i].y += video->offset_y;
966
			}
966
			}
967
			video->UpdateRects(this, numrects, rects);
967
			video->UpdateRects(this, numrects, rects);
968
			for ( i=0; i
968
			for ( i=0; i
969
				rects[i].x -= video->offset_x;
969
				rects[i].x -= video->offset_x;
970
				rects[i].y -= video->offset_y;
970
				rects[i].y -= video->offset_y;
971
			}
971
			}
972
		} else {
972
		} else {
973
			video->UpdateRects(this, numrects, rects);
973
			video->UpdateRects(this, numrects, rects);
974
		}
974
		}
975
	}
975
	}
976
}
976
}
977
 
977
 
978
/*
978
/*
979
 * Performs hardware double buffering, if possible, or a full update if not.
979
 * Performs hardware double buffering, if possible, or a full update if not.
980
 */
980
 */
981
int SDL_Flip(SDL_Surface *screen)
981
int SDL_Flip(SDL_Surface *screen)
982
{
982
{
983
	SDL_VideoDevice *video = current_video;
983
	SDL_VideoDevice *video = current_video;
984
	/* Copy the shadow surface to the video surface */
984
	/* Copy the shadow surface to the video surface */
985
	if ( screen == SDL_ShadowSurface ) {
985
	if ( screen == SDL_ShadowSurface ) {
986
		SDL_Rect rect;
986
		SDL_Rect rect;
987
	        SDL_Palette *pal = screen->format->palette;
987
	        SDL_Palette *pal = screen->format->palette;
988
		SDL_Color *saved_colors = NULL;
988
		SDL_Color *saved_colors = NULL;
989
	        if ( pal && !(SDL_VideoSurface->flags & SDL_HWPALETTE) ) {
989
	        if ( pal && !(SDL_VideoSurface->flags & SDL_HWPALETTE) ) {
990
			/* simulated 8bpp, use correct physical palette */
990
			/* simulated 8bpp, use correct physical palette */
991
			saved_colors = pal->colors;
991
			saved_colors = pal->colors;
992
			if ( video->gammacols ) {
992
			if ( video->gammacols ) {
993
				/* gamma-corrected palette */
993
				/* gamma-corrected palette */
994
				pal->colors = video->gammacols;
994
				pal->colors = video->gammacols;
995
			} else if ( video->physpal ) {
995
			} else if ( video->physpal ) {
996
				/* physical palette different from logical */
996
				/* physical palette different from logical */
997
				pal->colors = video->physpal->colors;
997
				pal->colors = video->physpal->colors;
998
			}
998
			}
999
		}
999
		}
1000
 
1000
 
1001
		rect.x = 0;
1001
		rect.x = 0;
1002
		rect.y = 0;
1002
		rect.y = 0;
1003
		rect.w = screen->w;
1003
		rect.w = screen->w;
1004
		rect.h = screen->h;
1004
		rect.h = screen->h;
1005
		SDL_LowerBlit(SDL_ShadowSurface,&rect, SDL_VideoSurface,&rect);
1005
		SDL_LowerBlit(SDL_ShadowSurface,&rect, SDL_VideoSurface,&rect);
1006
 
1006
 
1007
		if ( saved_colors )
1007
		if ( saved_colors )
1008
			pal->colors = saved_colors;
1008
			pal->colors = saved_colors;
1009
		screen = SDL_VideoSurface;
1009
		screen = SDL_VideoSurface;
1010
	}
1010
	}
1011
	if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
1011
	if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
1012
		SDL_VideoDevice *this  = current_video;
1012
		SDL_VideoDevice *this  = current_video;
1013
		return(video->FlipHWSurface(this, SDL_VideoSurface));
1013
		return(video->FlipHWSurface(this, SDL_VideoSurface));
1014
	} else {
1014
	} else {
1015
		SDL_UpdateRect(screen, 0, 0, 0, 0);
1015
		SDL_UpdateRect(screen, 0, 0, 0, 0);
1016
	}
1016
	}
1017
	return(0);
1017
	return(0);
1018
}
1018
}
1019
 
1019
 
1020
static void SetPalette_logical(SDL_Surface *screen, SDL_Color *colors,
1020
static void SetPalette_logical(SDL_Surface *screen, SDL_Color *colors,
1021
			       int firstcolor, int ncolors)
1021
			       int firstcolor, int ncolors)
1022
{
1022
{
1023
        SDL_Palette *pal = screen->format->palette;
1023
        SDL_Palette *pal = screen->format->palette;
1024
	SDL_Palette *vidpal;
1024
	SDL_Palette *vidpal;
1025
 
1025
 
1026
	if ( colors != (pal->colors + firstcolor) ) {
1026
	if ( colors != (pal->colors + firstcolor) ) {
1027
	        memcpy(pal->colors + firstcolor, colors,
1027
	        memcpy(pal->colors + firstcolor, colors,
1028
		       ncolors * sizeof(*colors));
1028
		       ncolors * sizeof(*colors));
1029
	}
1029
	}
1030
 
1030
 
1031
	vidpal = SDL_VideoSurface->format->palette;
1031
	vidpal = SDL_VideoSurface->format->palette;
1032
	if ( (screen == SDL_ShadowSurface) && vidpal ) {
1032
	if ( (screen == SDL_ShadowSurface) && vidpal ) {
1033
	        /*
1033
	        /*
1034
		 * This is a shadow surface, and the physical
1034
		 * This is a shadow surface, and the physical
1035
		 * framebuffer is also indexed. Propagate the
1035
		 * framebuffer is also indexed. Propagate the
1036
		 * changes to its logical palette so that
1036
		 * changes to its logical palette so that
1037
		 * updates are always identity blits
1037
		 * updates are always identity blits
1038
		 */
1038
		 */
1039
		memcpy(vidpal->colors + firstcolor, colors,
1039
		memcpy(vidpal->colors + firstcolor, colors,
1040
		       ncolors * sizeof(*colors));
1040
		       ncolors * sizeof(*colors));
1041
	}
1041
	}
1042
	SDL_FormatChanged(screen);
1042
	SDL_FormatChanged(screen);
1043
}
1043
}
1044
 
1044
 
1045
static int SetPalette_physical(SDL_Surface *screen,
1045
static int SetPalette_physical(SDL_Surface *screen,
1046
                               SDL_Color *colors, int firstcolor, int ncolors)
1046
                               SDL_Color *colors, int firstcolor, int ncolors)
1047
{
1047
{
1048
	SDL_VideoDevice *video = current_video;
1048
	SDL_VideoDevice *video = current_video;
1049
	int gotall = 1;
1049
	int gotall = 1;
1050
 
1050
 
1051
	if ( video->physpal ) {
1051
	if ( video->physpal ) {
1052
		/* We need to copy the new colors, since we haven't
1052
		/* We need to copy the new colors, since we haven't
1053
		 * already done the copy in the logical set above.
1053
		 * already done the copy in the logical set above.
1054
		 */
1054
		 */
1055
		memcpy(video->physpal->colors + firstcolor,
1055
		memcpy(video->physpal->colors + firstcolor,
1056
		       colors, ncolors * sizeof(*colors));
1056
		       colors, ncolors * sizeof(*colors));
1057
	}
1057
	}
1058
	if ( screen == SDL_ShadowSurface ) {
1058
	if ( screen == SDL_ShadowSurface ) {
1059
		if ( SDL_VideoSurface->flags & SDL_HWPALETTE ) {
1059
		if ( SDL_VideoSurface->flags & SDL_HWPALETTE ) {
1060
			/*
1060
			/*
1061
			 * The real screen is also indexed - set its physical
1061
			 * The real screen is also indexed - set its physical
1062
			 * palette. The physical palette does not include the
1062
			 * palette. The physical palette does not include the
1063
			 * gamma modification, we apply it directly instead,
1063
			 * gamma modification, we apply it directly instead,
1064
			 * but this only happens if we have hardware palette.
1064
			 * but this only happens if we have hardware palette.
1065
			 */
1065
			 */
1066
			screen = SDL_VideoSurface;
1066
			screen = SDL_VideoSurface;
1067
		} else {
1067
		} else {
1068
			/*
1068
			/*
1069
			 * The video surface is not indexed - invalidate any
1069
			 * The video surface is not indexed - invalidate any
1070
			 * active shadow-to-video blit mappings.
1070
			 * active shadow-to-video blit mappings.
1071
			 */
1071
			 */
1072
			if ( screen->map->dst == SDL_VideoSurface ) {
1072
			if ( screen->map->dst == SDL_VideoSurface ) {
1073
				SDL_InvalidateMap(screen->map);
1073
				SDL_InvalidateMap(screen->map);
1074
			}
1074
			}
1075
			if ( video->gamma ) {
1075
			if ( video->gamma ) {
1076
				if( ! video->gammacols ) {
1076
				if( ! video->gammacols ) {
1077
					SDL_Palette *pp = video->physpal;
1077
					SDL_Palette *pp = video->physpal;
1078
					if(!pp)
1078
					if(!pp)
1079
						pp = screen->format->palette;
1079
						pp = screen->format->palette;
1080
					video->gammacols = malloc(pp->ncolors
1080
					video->gammacols = malloc(pp->ncolors
1081
							  * sizeof(SDL_Color));
1081
							  * sizeof(SDL_Color));
1082
					SDL_ApplyGamma(video->gamma,
1082
					SDL_ApplyGamma(video->gamma,
1083
						       pp->colors,
1083
						       pp->colors,
1084
						       video->gammacols,
1084
						       video->gammacols,
1085
						       pp->ncolors);
1085
						       pp->ncolors);
1086
				} else {
1086
				} else {
1087
					SDL_ApplyGamma(video->gamma, colors,
1087
					SDL_ApplyGamma(video->gamma, colors,
1088
						       video->gammacols
1088
						       video->gammacols
1089
						       + firstcolor,
1089
						       + firstcolor,
1090
						       ncolors);
1090
						       ncolors);
1091
				}
1091
				}
1092
			}
1092
			}
1093
			SDL_UpdateRect(screen, 0, 0, 0, 0);
1093
			SDL_UpdateRect(screen, 0, 0, 0, 0);
1094
		}
1094
		}
1095
	}
1095
	}
1096
 
1096
 
1097
	if ( screen == SDL_VideoSurface ) {
1097
	if ( screen == SDL_VideoSurface ) {
1098
		SDL_Color gcolors[256];
1098
		SDL_Color gcolors[256];
1099
 
1099
 
1100
	        if ( video->gamma ) {
1100
	        if ( video->gamma ) {
1101
		        SDL_ApplyGamma(video->gamma, colors, gcolors, ncolors);
1101
		        SDL_ApplyGamma(video->gamma, colors, gcolors, ncolors);
1102
			colors = gcolors;
1102
			colors = gcolors;
1103
		}
1103
		}
1104
		gotall = video->SetColors(video, firstcolor, ncolors, colors);
1104
		gotall = video->SetColors(video, firstcolor, ncolors, colors);
1105
		if ( ! gotall ) {
1105
		if ( ! gotall ) {
1106
			/* The video flags shouldn't have SDL_HWPALETTE, and
1106
			/* The video flags shouldn't have SDL_HWPALETTE, and
1107
			   the video driver is responsible for copying back the
1107
			   the video driver is responsible for copying back the
1108
			   correct colors into the video surface palette.
1108
			   correct colors into the video surface palette.
1109
			*/
1109
			*/
1110
			;
1110
			;
1111
		}
1111
		}
1112
		SDL_CursorPaletteChanged();
1112
		SDL_CursorPaletteChanged();
1113
	}
1113
	}
1114
	return gotall;
1114
	return gotall;
1115
}
1115
}
1116
 
1116
 
1117
/*
1117
/*
1118
 * Set the physical and/or logical colormap of a surface:
1118
 * Set the physical and/or logical colormap of a surface:
1119
 * Only the screen has a physical colormap. It determines what is actually
1119
 * Only the screen has a physical colormap. It determines what is actually
1120
 * sent to the display.
1120
 * sent to the display.
1121
 * The logical colormap is used to map blits to/from the surface.
1121
 * The logical colormap is used to map blits to/from the surface.
1122
 * 'which' is one or both of SDL_LOGPAL, SDL_PHYSPAL
1122
 * 'which' is one or both of SDL_LOGPAL, SDL_PHYSPAL
1123
 *
1123
 *
1124
 * Return nonzero if all colours were set as requested, or 0 otherwise.
1124
 * Return nonzero if all colours were set as requested, or 0 otherwise.
1125
 */
1125
 */
1126
int SDL_SetPalette(SDL_Surface *screen, int which,
1126
int SDL_SetPalette(SDL_Surface *screen, int which,
1127
		   SDL_Color *colors, int firstcolor, int ncolors)
1127
		   SDL_Color *colors, int firstcolor, int ncolors)
1128
{
1128
{
1129
        SDL_Palette *pal;
1129
        SDL_Palette *pal;
1130
	int gotall;
1130
	int gotall;
1131
	int palsize;
1131
	int palsize;
1132
 
1132
 
1133
	if ( ! current_video ) {
1133
	if ( ! current_video ) {
1134
		return 0;
1134
		return 0;
1135
	}
1135
	}
1136
	if ( screen != SDL_PublicSurface ) {
1136
	if ( screen != SDL_PublicSurface ) {
1137
	        /* only screens have physical palettes */
1137
	        /* only screens have physical palettes */
1138
	        which &= ~SDL_PHYSPAL;
1138
	        which &= ~SDL_PHYSPAL;
1139
	} else if( (screen->flags & SDL_HWPALETTE) != SDL_HWPALETTE ) {
1139
	} else if( (screen->flags & SDL_HWPALETTE) != SDL_HWPALETTE ) {
1140
	        /* hardware palettes required for split colormaps */
1140
	        /* hardware palettes required for split colormaps */
1141
	        which |= SDL_PHYSPAL | SDL_LOGPAL;
1141
	        which |= SDL_PHYSPAL | SDL_LOGPAL;
1142
	}
1142
	}
1143
 
1143
 
1144
	/* Verify the parameters */
1144
	/* Verify the parameters */
1145
	pal = screen->format->palette;
1145
	pal = screen->format->palette;
1146
	if( !pal ) {
1146
	if( !pal ) {
1147
	        return 0;	/* not a palettized surface */
1147
	        return 0;	/* not a palettized surface */
1148
	}
1148
	}
1149
	gotall = 1;
1149
	gotall = 1;
1150
	palsize = 1 << screen->format->BitsPerPixel;
1150
	palsize = 1 << screen->format->BitsPerPixel;
1151
	if ( ncolors > (palsize - firstcolor) ) {
1151
	if ( ncolors > (palsize - firstcolor) ) {
1152
	        ncolors = (palsize - firstcolor);
1152
	        ncolors = (palsize - firstcolor);
1153
		gotall = 0;
1153
		gotall = 0;
1154
	}
1154
	}
1155
 
1155
 
1156
	if ( which & SDL_LOGPAL ) {
1156
	if ( which & SDL_LOGPAL ) {
1157
		/*
1157
		/*
1158
		 * Logical palette change: The actual screen isn't affected,
1158
		 * Logical palette change: The actual screen isn't affected,
1159
		 * but the internal colormap is altered so that the
1159
		 * but the internal colormap is altered so that the
1160
		 * interpretation of the pixel values (for blits etc) is
1160
		 * interpretation of the pixel values (for blits etc) is
1161
		 * changed.
1161
		 * changed.
1162
		 */
1162
		 */
1163
	        SetPalette_logical(screen, colors, firstcolor, ncolors);
1163
	        SetPalette_logical(screen, colors, firstcolor, ncolors);
1164
	}
1164
	}
1165
	if ( which & SDL_PHYSPAL ) {
1165
	if ( which & SDL_PHYSPAL ) {
1166
		SDL_VideoDevice *video = current_video;
1166
		SDL_VideoDevice *video = current_video;
1167
	        /*
1167
	        /*
1168
		 * Physical palette change: This doesn't affect the
1168
		 * Physical palette change: This doesn't affect the
1169
		 * program's idea of what the screen looks like, but changes
1169
		 * program's idea of what the screen looks like, but changes
1170
		 * its actual appearance.
1170
		 * its actual appearance.
1171
		 */
1171
		 */
1172
	        if(!video)
1172
	        if(!video)
1173
		        return gotall;	/* video not yet initialized */
1173
		        return gotall;	/* video not yet initialized */
1174
		if(!video->physpal && !(which & SDL_LOGPAL) ) {
1174
		if(!video->physpal && !(which & SDL_LOGPAL) ) {
1175
			/* Lazy physical palette allocation */
1175
			/* Lazy physical palette allocation */
1176
		        int size;
1176
		        int size;
1177
			SDL_Palette *pp = malloc(sizeof(*pp));
1177
			SDL_Palette *pp = malloc(sizeof(*pp));
1178
			current_video->physpal = pp;
1178
			current_video->physpal = pp;
1179
			pp->ncolors = pal->ncolors;
1179
			pp->ncolors = pal->ncolors;
1180
			size = pp->ncolors * sizeof(SDL_Color);
1180
			size = pp->ncolors * sizeof(SDL_Color);
1181
			pp->colors = malloc(size);
1181
			pp->colors = malloc(size);
1182
			memcpy(pp->colors, pal->colors, size);
1182
			memcpy(pp->colors, pal->colors, size);
1183
		}
1183
		}
1184
		if ( ! SetPalette_physical(screen,
1184
		if ( ! SetPalette_physical(screen,
1185
		                           colors, firstcolor, ncolors) ) {
1185
		                           colors, firstcolor, ncolors) ) {
1186
			gotall = 0;
1186
			gotall = 0;
1187
		}
1187
		}
1188
	}
1188
	}
1189
	return gotall;
1189
	return gotall;
1190
}
1190
}
1191
 
1191
 
1192
int SDL_SetColors(SDL_Surface *screen, SDL_Color *colors, int firstcolor,
1192
int SDL_SetColors(SDL_Surface *screen, SDL_Color *colors, int firstcolor,
1193
		  int ncolors)
1193
		  int ncolors)
1194
{
1194
{
1195
        return SDL_SetPalette(screen, SDL_LOGPAL | SDL_PHYSPAL,
1195
        return SDL_SetPalette(screen, SDL_LOGPAL | SDL_PHYSPAL,
1196
			      colors, firstcolor, ncolors);
1196
			      colors, firstcolor, ncolors);
1197
}
1197
}
1198
 
1198
 
1199
/*
1199
/*
1200
 * Clean up the video subsystem
1200
 * Clean up the video subsystem
1201
 */
1201
 */
1202
void SDL_VideoQuit (void)
1202
void SDL_VideoQuit (void)
1203
{
1203
{
1204
	SDL_Surface *ready_to_go;
1204
	SDL_Surface *ready_to_go;
1205
 
1205
 
1206
	if ( current_video ) {
1206
	if ( current_video ) {
1207
		SDL_VideoDevice *video = current_video;
1207
		SDL_VideoDevice *video = current_video;
1208
		SDL_VideoDevice *this  = current_video;
1208
		SDL_VideoDevice *this  = current_video;
1209
 
1209
 
1210
		/* Halt event processing before doing anything else */
1210
		/* Halt event processing before doing anything else */
1211
		SDL_StopEventLoop();
1211
		SDL_StopEventLoop();
1212
 
1212
 
1213
		/* Clean up allocated window manager items */
1213
		/* Clean up allocated window manager items */
1214
		if ( SDL_PublicSurface ) {
1214
		if ( SDL_PublicSurface ) {
1215
			SDL_PublicSurface = NULL;
1215
			SDL_PublicSurface = NULL;
1216
		}
1216
		}
1217
		SDL_CursorQuit();
1217
		SDL_CursorQuit();
1218
 
1218
 
1219
		/* Just in case... */
1219
		/* Just in case... */
1220
		SDL_WM_GrabInputOff();
1220
		SDL_WM_GrabInputOff();
1221
 
1221
 
1222
		/* Clean up the system video */
1222
		/* Clean up the system video */
1223
		video->VideoQuit(this);
1223
		video->VideoQuit(this);
1224
 
1224
 
1225
		/* Free any lingering surfaces */
1225
		/* Free any lingering surfaces */
1226
		ready_to_go = SDL_ShadowSurface;
1226
		ready_to_go = SDL_ShadowSurface;
1227
		SDL_ShadowSurface = NULL;
1227
		SDL_ShadowSurface = NULL;
1228
		SDL_FreeSurface(ready_to_go);
1228
		SDL_FreeSurface(ready_to_go);
1229
		if ( SDL_VideoSurface != NULL ) {
1229
		if ( SDL_VideoSurface != NULL ) {
1230
			ready_to_go = SDL_VideoSurface;
1230
			ready_to_go = SDL_VideoSurface;
1231
			SDL_VideoSurface = NULL;
1231
			SDL_VideoSurface = NULL;
1232
			SDL_FreeSurface(ready_to_go);
1232
			SDL_FreeSurface(ready_to_go);
1233
		}
1233
		}
1234
		SDL_PublicSurface = NULL;
1234
		SDL_PublicSurface = NULL;
1235
 
1235
 
1236
		/* Clean up miscellaneous memory */
1236
		/* Clean up miscellaneous memory */
1237
		if ( video->physpal ) {
1237
		if ( video->physpal ) {
1238
			free(video->physpal->colors);
1238
			free(video->physpal->colors);
1239
			free(video->physpal);
1239
			free(video->physpal);
1240
			video->physpal = NULL;
1240
			video->physpal = NULL;
1241
		}
1241
		}
1242
		if ( video->gammacols ) {
1242
		if ( video->gammacols ) {
1243
			free(video->gammacols);
1243
			free(video->gammacols);
1244
			video->gammacols = NULL;
1244
			video->gammacols = NULL;
1245
		}
1245
		}
1246
		if ( video->gamma ) {
1246
		if ( video->gamma ) {
1247
			free(video->gamma);
1247
			free(video->gamma);
1248
			video->gamma = NULL;
1248
			video->gamma = NULL;
1249
		}
1249
		}
1250
		if ( video->wm_title != NULL ) {
1250
		if ( video->wm_title != NULL ) {
1251
			free(video->wm_title);
1251
			free(video->wm_title);
1252
			video->wm_title = NULL;
1252
			video->wm_title = NULL;
1253
		}
1253
		}
1254
		if ( video->wm_icon != NULL ) {
1254
		if ( video->wm_icon != NULL ) {
1255
			free(video->wm_icon);
1255
			free(video->wm_icon);
1256
			video->wm_icon = NULL;
1256
			video->wm_icon = NULL;
1257
		}
1257
		}
1258
 
1258
 
1259
		/* Finish cleaning up video subsystem */
1259
		/* Finish cleaning up video subsystem */
1260
		video->free(this);
1260
		video->free(this);
1261
		current_video = NULL;
1261
		current_video = NULL;
1262
	}
1262
	}
1263
	return;
1263
	return;
1264
}
1264
}
1265
 
1265
 
1266
/* Load the GL driver library */
1266
/* Load the GL driver library */
1267
int SDL_GL_LoadLibrary(const char *path)
1267
int SDL_GL_LoadLibrary(const char *path)
1268
{
1268
{
1269
	SDL_VideoDevice *video = current_video;
1269
	SDL_VideoDevice *video = current_video;
1270
	SDL_VideoDevice *this = current_video;
1270
	SDL_VideoDevice *this = current_video;
1271
	int retval;
1271
	int retval;
1272
 
1272
 
1273
	retval = -1;
1273
	retval = -1;
1274
	if ( video && video->GL_LoadLibrary ) {
1274
	if ( video && video->GL_LoadLibrary ) {
1275
		retval = video->GL_LoadLibrary(this, path);
1275
		retval = video->GL_LoadLibrary(this, path);
1276
	} else {
1276
	} else {
1277
		SDL_SetError("No dynamic GL support in video driver");
1277
		SDL_SetError("No dynamic GL support in video driver");
1278
	}
1278
	}
1279
	return(retval);
1279
	return(retval);
1280
}
1280
}
1281
 
1281
 
1282
void *SDL_GL_GetProcAddress(const char* proc)
1282
void *SDL_GL_GetProcAddress(const char* proc)
1283
{
1283
{
1284
	SDL_VideoDevice *video = current_video;
1284
	SDL_VideoDevice *video = current_video;
1285
	SDL_VideoDevice *this = current_video;
1285
	SDL_VideoDevice *this = current_video;
1286
	void *func;
1286
	void *func;
1287
 
1287
 
1288
	func = NULL;
1288
	func = NULL;
1289
	if ( video->GL_GetProcAddress ) {
1289
	if ( video->GL_GetProcAddress ) {
1290
		if ( video->gl_config.driver_loaded ) {
1290
		if ( video->gl_config.driver_loaded ) {
1291
			func = video->GL_GetProcAddress(this, proc);
1291
			func = video->GL_GetProcAddress(this, proc);
1292
		} else {
1292
		} else {
1293
			SDL_SetError("No GL driver has been loaded");
1293
			SDL_SetError("No GL driver has been loaded");
1294
		}
1294
		}
1295
	} else {
1295
	} else {
1296
		SDL_SetError("No dynamic GL support in video driver");
1296
		SDL_SetError("No dynamic GL support in video driver");
1297
	}
1297
	}
1298
	return func;
1298
	return func;
1299
}
1299
}
1300
 
1300
 
1301
/* Set the specified GL attribute for setting up a GL video mode */
1301
/* Set the specified GL attribute for setting up a GL video mode */
1302
int SDL_GL_SetAttribute( SDL_GLattr attr, int value )
1302
int SDL_GL_SetAttribute( SDL_GLattr attr, int value )
1303
{
1303
{
1304
	int retval;
1304
	int retval;
1305
	SDL_VideoDevice *video = current_video;
1305
	SDL_VideoDevice *video = current_video;
1306
 
1306
 
1307
	retval = 0;
1307
	retval = 0;
1308
	switch (attr) {
1308
	switch (attr) {
1309
		case SDL_GL_RED_SIZE:
1309
		case SDL_GL_RED_SIZE:
1310
			video->gl_config.red_size = value;
1310
			video->gl_config.red_size = value;
1311
			break;
1311
			break;
1312
		case SDL_GL_GREEN_SIZE:
1312
		case SDL_GL_GREEN_SIZE:
1313
			video->gl_config.green_size = value;
1313
			video->gl_config.green_size = value;
1314
			break;
1314
			break;
1315
		case SDL_GL_BLUE_SIZE:
1315
		case SDL_GL_BLUE_SIZE:
1316
			video->gl_config.blue_size = value;
1316
			video->gl_config.blue_size = value;
1317
			break;
1317
			break;
1318
		case SDL_GL_ALPHA_SIZE:
1318
		case SDL_GL_ALPHA_SIZE:
1319
			video->gl_config.alpha_size = value;
1319
			video->gl_config.alpha_size = value;
1320
			break;
1320
			break;
1321
		case SDL_GL_DOUBLEBUFFER:
1321
		case SDL_GL_DOUBLEBUFFER:
1322
			video->gl_config.double_buffer = value;
1322
			video->gl_config.double_buffer = value;
1323
			break;
1323
			break;
1324
        	case SDL_GL_BUFFER_SIZE:
1324
        	case SDL_GL_BUFFER_SIZE:
1325
	        	video->gl_config.buffer_size = value;
1325
	        	video->gl_config.buffer_size = value;
1326
			break;
1326
			break;
1327
		case SDL_GL_DEPTH_SIZE:
1327
		case SDL_GL_DEPTH_SIZE:
1328
			video->gl_config.depth_size = value;
1328
			video->gl_config.depth_size = value;
1329
			break;
1329
			break;
1330
		case SDL_GL_STENCIL_SIZE:
1330
		case SDL_GL_STENCIL_SIZE:
1331
			video->gl_config.stencil_size = value;
1331
			video->gl_config.stencil_size = value;
1332
			break;
1332
			break;
1333
	        case SDL_GL_ACCUM_RED_SIZE:
1333
	        case SDL_GL_ACCUM_RED_SIZE:
1334
			video->gl_config.accum_red_size = value;
1334
			video->gl_config.accum_red_size = value;
1335
			break;
1335
			break;
1336
	        case SDL_GL_ACCUM_GREEN_SIZE:
1336
	        case SDL_GL_ACCUM_GREEN_SIZE:
1337
			video->gl_config.accum_green_size = value;
1337
			video->gl_config.accum_green_size = value;
1338
			break;
1338
			break;
1339
	        case SDL_GL_ACCUM_BLUE_SIZE:
1339
	        case SDL_GL_ACCUM_BLUE_SIZE:
1340
			video->gl_config.accum_blue_size = value;
1340
			video->gl_config.accum_blue_size = value;
1341
			break;
1341
			break;
1342
	        case SDL_GL_ACCUM_ALPHA_SIZE:
1342
	        case SDL_GL_ACCUM_ALPHA_SIZE:
1343
			video->gl_config.accum_alpha_size = value;
1343
			video->gl_config.accum_alpha_size = value;
1344
			break;
1344
			break;
1345
		default:
1345
		default:
1346
			SDL_SetError("Unknown OpenGL attribute");
1346
			SDL_SetError("Unknown OpenGL attribute");
1347
			retval = -1;
1347
			retval = -1;
1348
			break;
1348
			break;
1349
	}
1349
	}
1350
	return(retval);
1350
	return(retval);
1351
}
1351
}
1352
 
1352
 
1353
/* Retrieve an attribute value from the windowing system. */
1353
/* Retrieve an attribute value from the windowing system. */
1354
int SDL_GL_GetAttribute(SDL_GLattr attr, int* value)
1354
int SDL_GL_GetAttribute(SDL_GLattr attr, int* value)
1355
{
1355
{
1356
	int retval = -1;
1356
	int retval = -1;
1357
	SDL_VideoDevice* video = current_video;
1357
	SDL_VideoDevice* video = current_video;
1358
	SDL_VideoDevice* this = current_video;
1358
	SDL_VideoDevice* this = current_video;
1359
 
1359
 
1360
	if ( video->GL_GetAttribute ) {
1360
	if ( video->GL_GetAttribute ) {
1361
		retval = this->GL_GetAttribute(this, attr, value);
1361
		retval = this->GL_GetAttribute(this, attr, value);
1362
	} else {
1362
	} else {
1363
		*value = 0;
1363
		*value = 0;
1364
		SDL_SetError("GL_GetAttribute not supported");
1364
		SDL_SetError("GL_GetAttribute not supported");
1365
	}
1365
	}
1366
	return retval;
1366
	return retval;
1367
}
1367
}
1368
 
1368
 
1369
/* Perform a GL buffer swap on the current GL context */
1369
/* Perform a GL buffer swap on the current GL context */
1370
void SDL_GL_SwapBuffers(void)
1370
void SDL_GL_SwapBuffers(void)
1371
{
1371
{
1372
	SDL_VideoDevice *video = current_video;
1372
	SDL_VideoDevice *video = current_video;
1373
	SDL_VideoDevice *this = current_video;
1373
	SDL_VideoDevice *this = current_video;
1374
 
1374
 
1375
	if ( video->screen->flags & SDL_OPENGL ) {
1375
	if ( video->screen->flags & SDL_OPENGL ) {
1376
		video->GL_SwapBuffers( this );
1376
		video->GL_SwapBuffers( this );
1377
	}
1377
	}
1378
}
1378
}
1379
 
1379
 
1380
/* Update rects with locking */
1380
/* Update rects with locking */
1381
void SDL_GL_UpdateRectsLock(SDL_VideoDevice* this, int numrects, SDL_Rect *rects)
1381
void SDL_GL_UpdateRectsLock(SDL_VideoDevice* this, int numrects, SDL_Rect *rects)
1382
{
1382
{
1383
	SDL_GL_Lock();
1383
	SDL_GL_Lock();
1384
 	SDL_GL_UpdateRects(numrects, rects);
1384
 	SDL_GL_UpdateRects(numrects, rects);
1385
	SDL_GL_Unlock();
1385
	SDL_GL_Unlock();
1386
}
1386
}
1387
 
1387
 
1388
/* Update rects without state setting and changing (the caller is responsible for it) */
1388
/* Update rects without state setting and changing (the caller is responsible for it) */
1389
void SDL_GL_UpdateRects(int numrects, SDL_Rect *rects)
1389
void SDL_GL_UpdateRects(int numrects, SDL_Rect *rects)
1390
{
1390
{
1391
#ifdef HAVE_OPENGL
1391
#ifdef HAVE_OPENGL
1392
	SDL_VideoDevice *this = current_video;
1392
	SDL_VideoDevice *this = current_video;
1393
	SDL_Rect update, tmp;
1393
	SDL_Rect update, tmp;
1394
	int x, y, i;
1394
	int x, y, i;
1395
 
1395
 
1396
	for ( i = 0; i < numrects; i++ )
1396
	for ( i = 0; i < numrects; i++ )
1397
	{
1397
	{
1398
		tmp.y = rects[i].y;
1398
		tmp.y = rects[i].y;
1399
		tmp.h = rects[i].h;
1399
		tmp.h = rects[i].h;
1400
		for ( y = 0; y <= rects[i].h / 256; y++ )
1400
		for ( y = 0; y <= rects[i].h / 256; y++ )
1401
		{
1401
		{
1402
			tmp.x = rects[i].x;
1402
			tmp.x = rects[i].x;
1403
			tmp.w = rects[i].w;
1403
			tmp.w = rects[i].w;
1404
			for ( x = 0; x <= rects[i].w / 256; x++ )
1404
			for ( x = 0; x <= rects[i].w / 256; x++ )
1405
			{
1405
			{
1406
				update.x = tmp.x;
1406
				update.x = tmp.x;
1407
				update.y = tmp.y;
1407
				update.y = tmp.y;
1408
				update.w = tmp.w;
1408
				update.w = tmp.w;
1409
				update.h = tmp.h;
1409
				update.h = tmp.h;
1410
 
1410
 
1411
				if ( update.w > 256 )
1411
				if ( update.w > 256 )
1412
					update.w = 256;
1412
					update.w = 256;
1413
 
1413
 
1414
				if ( update.h > 256 )
1414
				if ( update.h > 256 )
1415
					update.h = 256;
1415
					update.h = 256;
1416
			
1416
			
1417
				this->glFlush();
1417
				this->glFlush();
1418
				this->glTexSubImage2D( 
1418
				this->glTexSubImage2D( 
1419
					GL_TEXTURE_2D, 
1419
					GL_TEXTURE_2D, 
1420
					0, 
1420
					0, 
1421
					0, 
1421
					0, 
1422
					0, 
1422
					0, 
1423
					update.w, 
1423
					update.w, 
1424
					update.h, 
1424
					update.h, 
1425
					this->is_32bit? GL_RGBA : GL_RGB,
1425
					this->is_32bit? GL_RGBA : GL_RGB,
1426
#ifdef GL_VERSION_1_2
1426
#ifdef GL_VERSION_1_2
1427
					this->is_32bit ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5,
1427
					this->is_32bit ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5,
1428
#else
1428
#else
1429
					GL_UNSIGNED_BYTE,
1429
					GL_UNSIGNED_BYTE,
1430
#endif
1430
#endif
1431
					(Uint8 *)this->screen->pixels + 
1431
					(Uint8 *)this->screen->pixels + 
1432
						this->screen->format->BytesPerPixel * update.x + 
1432
						this->screen->format->BytesPerPixel * update.x + 
1433
						update.y * this->screen->pitch );
1433
						update.y * this->screen->pitch );
1434
	
1434
	
1435
				this->glFlush();
1435
				this->glFlush();
1436
				/*
1436
				/*
1437
				* Note the parens around the function name:
1437
				* Note the parens around the function name:
1438
				* This is because some OpenGL implementations define glTexCoord etc 
1438
				* This is because some OpenGL implementations define glTexCoord etc 
1439
				* as macros, and we don't want them expanded here.
1439
				* as macros, and we don't want them expanded here.
1440
				*/
1440
				*/
1441
				this->glBegin(GL_TRIANGLE_STRIP);
1441
				this->glBegin(GL_TRIANGLE_STRIP);
1442
					(this->glTexCoord2f)( 0.0, 0.0 );	
1442
					(this->glTexCoord2f)( 0.0, 0.0 );	
1443
					(this->glVertex2i)( update.x, update.y );
1443
					(this->glVertex2i)( update.x, update.y );
1444
					(this->glTexCoord2f)( (float)(update.w / 256.0), 0.0 );	
1444
					(this->glTexCoord2f)( (float)(update.w / 256.0), 0.0 );	
1445
					(this->glVertex2i)( update.x + update.w, update.y );
1445
					(this->glVertex2i)( update.x + update.w, update.y );
1446
					(this->glTexCoord2f)( 0.0, (float)(update.h / 256.0) );
1446
					(this->glTexCoord2f)( 0.0, (float)(update.h / 256.0) );
1447
					(this->glVertex2i)( update.x, update.y + update.h );
1447
					(this->glVertex2i)( update.x, update.y + update.h );
1448
					(this->glTexCoord2f)( (float)(update.w / 256.0), (float)(update.h / 256.0) );	
1448
					(this->glTexCoord2f)( (float)(update.w / 256.0), (float)(update.h / 256.0) );	
1449
					(this->glVertex2i)( update.x + update.w	, update.y + update.h );
1449
					(this->glVertex2i)( update.x + update.w	, update.y + update.h );
1450
				this->glEnd();	
1450
				this->glEnd();	
1451
			
1451
			
1452
				tmp.x += 256;
1452
				tmp.x += 256;
1453
				tmp.w -= 256;
1453
				tmp.w -= 256;
1454
			}
1454
			}
1455
			tmp.y += 256;
1455
			tmp.y += 256;
1456
			tmp.h -= 256;
1456
			tmp.h -= 256;
1457
		}
1457
		}
1458
	}
1458
	}
1459
#endif
1459
#endif
1460
}
1460
}
1461
 
1461
 
1462
/* Lock == save current state */
1462
/* Lock == save current state */
1463
void SDL_GL_Lock()
1463
void SDL_GL_Lock()
1464
{
1464
{
1465
#ifdef HAVE_OPENGL
1465
#ifdef HAVE_OPENGL
1466
	lock_count--;
1466
	lock_count--;
1467
	if (lock_count==-1)
1467
	if (lock_count==-1)
1468
	{
1468
	{
1469
		SDL_VideoDevice *this = current_video;
1469
		SDL_VideoDevice *this = current_video;
1470
 
1470
 
1471
		this->glPushAttrib( GL_ALL_ATTRIB_BITS );	/* TODO: narrow range of what is saved */
1471
		this->glPushAttrib( GL_ALL_ATTRIB_BITS );	/* TODO: narrow range of what is saved */
1472
		this->glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT );
1472
		this->glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT );
1473
 
1473
 
1474
		this->glEnable(GL_TEXTURE_2D);
1474
		this->glEnable(GL_TEXTURE_2D);
1475
		this->glEnable(GL_BLEND);
1475
		this->glEnable(GL_BLEND);
1476
		this->glDisable(GL_FOG);
1476
		this->glDisable(GL_FOG);
1477
		this->glDisable(GL_ALPHA_TEST);
1477
		this->glDisable(GL_ALPHA_TEST);
1478
		this->glDisable(GL_DEPTH_TEST);
1478
		this->glDisable(GL_DEPTH_TEST);
1479
		this->glDisable(GL_SCISSOR_TEST);	
1479
		this->glDisable(GL_SCISSOR_TEST);	
1480
		this->glDisable(GL_STENCIL_TEST);
1480
		this->glDisable(GL_STENCIL_TEST);
1481
		this->glDisable(GL_CULL_FACE);
1481
		this->glDisable(GL_CULL_FACE);
1482
 
1482
 
1483
		this->glBindTexture( GL_TEXTURE_2D, this->texture );
1483
		this->glBindTexture( GL_TEXTURE_2D, this->texture );
1484
		this->glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
1484
		this->glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
1485
		this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
1485
		this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
1486
		this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
1486
		this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
1487
		this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
1487
		this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
1488
		this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
1488
		this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
1489
 
1489
 
1490
		this->glPixelStorei( GL_UNPACK_ROW_LENGTH, this->screen->pitch / this->screen->format->BytesPerPixel );
1490
		this->glPixelStorei( GL_UNPACK_ROW_LENGTH, this->screen->pitch / this->screen->format->BytesPerPixel );
1491
		this->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1491
		this->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1492
		(this->glColor4f)(1.0, 1.0, 1.0, 1.0);		/* Solaris workaround */
1492
		(this->glColor4f)(1.0, 1.0, 1.0, 1.0);		/* Solaris workaround */
1493
 
1493
 
1494
		this->glViewport(0, 0, this->screen->w, this->screen->h);
1494
		this->glViewport(0, 0, this->screen->w, this->screen->h);
1495
		this->glMatrixMode(GL_PROJECTION);
1495
		this->glMatrixMode(GL_PROJECTION);
1496
		this->glPushMatrix();
1496
		this->glPushMatrix();
1497
		this->glLoadIdentity();
1497
		this->glLoadIdentity();
1498
 
1498
 
1499
		this->glOrtho(0.0, (GLdouble) this->screen->w, (GLdouble) this->screen->h, 0.0, 0.0, 1.0);
1499
		this->glOrtho(0.0, (GLdouble) this->screen->w, (GLdouble) this->screen->h, 0.0, 0.0, 1.0);
1500
 
1500
 
1501
		this->glMatrixMode(GL_MODELVIEW);
1501
		this->glMatrixMode(GL_MODELVIEW);
1502
		this->glPushMatrix();
1502
		this->glPushMatrix();
1503
		this->glLoadIdentity();
1503
		this->glLoadIdentity();
1504
	}
1504
	}
1505
#endif
1505
#endif
1506
}
1506
}
1507
 
1507
 
1508
/* Unlock == restore saved state */
1508
/* Unlock == restore saved state */
1509
void SDL_GL_Unlock()
1509
void SDL_GL_Unlock()
1510
{
1510
{
1511
#ifdef HAVE_OPENGL
1511
#ifdef HAVE_OPENGL
1512
	lock_count++;
1512
	lock_count++;
1513
	if (lock_count==0)
1513
	if (lock_count==0)
1514
	{
1514
	{
1515
		SDL_VideoDevice *this = current_video;
1515
		SDL_VideoDevice *this = current_video;
1516
 
1516
 
1517
		this->glPopMatrix();
1517
		this->glPopMatrix();
1518
		this->glMatrixMode(GL_PROJECTION);
1518
		this->glMatrixMode(GL_PROJECTION);
1519
		this->glPopMatrix();
1519
		this->glPopMatrix();
1520
 
1520
 
1521
		this->glPopClientAttrib();
1521
		this->glPopClientAttrib();
1522
		this->glPopAttrib();
1522
		this->glPopAttrib();
1523
	}
1523
	}
1524
#endif
1524
#endif
1525
}
1525
}
1526
 
1526
 
1527
/*
1527
/*
1528
 * Sets/Gets the title and icon text of the display window, if any.
1528
 * Sets/Gets the title and icon text of the display window, if any.
1529
 */
1529
 */
1530
void SDL_WM_SetCaption (const char *title, const char *icon)
1530
void SDL_WM_SetCaption (const char *title, const char *icon)
1531
{
1531
{
1532
	SDL_VideoDevice *video = current_video;
1532
	SDL_VideoDevice *video = current_video;
1533
	SDL_VideoDevice *this  = current_video;
1533
	SDL_VideoDevice *this  = current_video;
1534
 
1534
 
1535
	if ( video ) {
1535
	if ( video ) {
1536
		if ( title ) {
1536
		if ( title ) {
1537
			if ( video->wm_title ) {
1537
			if ( video->wm_title ) {
1538
				free(video->wm_title);
1538
				free(video->wm_title);
1539
			}
1539
			}
1540
			video->wm_title = (char *)malloc(strlen(title)+1);
1540
			video->wm_title = (char *)malloc(strlen(title)+1);
1541
			if ( video->wm_title != NULL ) {
1541
			if ( video->wm_title != NULL ) {
1542
				strcpy(video->wm_title, title);
1542
				strcpy(video->wm_title, title);
1543
			}
1543
			}
1544
		}
1544
		}
1545
		if ( icon ) {
1545
		if ( icon ) {
1546
			if ( video->wm_icon ) {
1546
			if ( video->wm_icon ) {
1547
				free(video->wm_icon);
1547
				free(video->wm_icon);
1548
			}
1548
			}
1549
			video->wm_icon = (char *)malloc(strlen(icon)+1);
1549
			video->wm_icon = (char *)malloc(strlen(icon)+1);
1550
			if ( video->wm_icon != NULL ) {
1550
			if ( video->wm_icon != NULL ) {
1551
				strcpy(video->wm_icon, icon);
1551
				strcpy(video->wm_icon, icon);
1552
			}
1552
			}
1553
		}
1553
		}
1554
		if ( (title || icon) && (video->SetCaption != NULL) ) {
1554
		if ( (title || icon) && (video->SetCaption != NULL) ) {
1555
			video->SetCaption(this, video->wm_title,video->wm_icon);
1555
			video->SetCaption(this, video->wm_title,video->wm_icon);
1556
		}
1556
		}
1557
	}
1557
	}
1558
}
1558
}
1559
void SDL_WM_GetCaption (char **title, char **icon)
1559
void SDL_WM_GetCaption (char **title, char **icon)
1560
{
1560
{
1561
	SDL_VideoDevice *video = current_video;
1561
	SDL_VideoDevice *video = current_video;
1562
 
1562
 
1563
	if ( video ) {
1563
	if ( video ) {
1564
		if ( title ) {
1564
		if ( title ) {
1565
			*title = video->wm_title;
1565
			*title = video->wm_title;
1566
		}
1566
		}
1567
		if ( icon ) {
1567
		if ( icon ) {
1568
			*icon = video->wm_icon;
1568
			*icon = video->wm_icon;
1569
		}
1569
		}
1570
	}
1570
	}
1571
}
1571
}
1572
 
1572
 
1573
/* Utility function used by SDL_WM_SetIcon() */
1573
/* Utility function used by SDL_WM_SetIcon() */
1574
static void CreateMaskFromColorKey(SDL_Surface *icon, Uint8 *mask)
1574
static void CreateMaskFromColorKey(SDL_Surface *icon, Uint8 *mask)
1575
{
1575
{
1576
	int x, y;
1576
	int x, y;
1577
	Uint32 colorkey;
1577
	Uint32 colorkey;
1578
#define SET_MASKBIT(icon, x, y, mask) \
1578
#define SET_MASKBIT(icon, x, y, mask) \
1579
	mask[(y*((icon->w+7)/8))+(x/8)] &= ~(0x01<<(7-(x%8)))
1579
	mask[(y*((icon->w+7)/8))+(x/8)] &= ~(0x01<<(7-(x%8)))
1580
 
1580
 
1581
	colorkey = icon->format->colorkey;
1581
	colorkey = icon->format->colorkey;
1582
	switch (icon->format->BytesPerPixel) {
1582
	switch (icon->format->BytesPerPixel) {
1583
		case 1: { Uint8 *pixels;
1583
		case 1: { Uint8 *pixels;
1584
			for ( y=0; yh; ++y ) {
1584
			for ( y=0; yh; ++y ) {
1585
				pixels = (Uint8 *)icon->pixels + y*icon->pitch;
1585
				pixels = (Uint8 *)icon->pixels + y*icon->pitch;
1586
				for ( x=0; xw; ++x ) {
1586
				for ( x=0; xw; ++x ) {
1587
					if ( *pixels++ == colorkey ) {
1587
					if ( *pixels++ == colorkey ) {
1588
						SET_MASKBIT(icon, x, y, mask);
1588
						SET_MASKBIT(icon, x, y, mask);
1589
					}
1589
					}
1590
				}
1590
				}
1591
			}
1591
			}
1592
		}
1592
		}
1593
		break;
1593
		break;
1594
 
1594
 
1595
		case 2: { Uint16 *pixels;
1595
		case 2: { Uint16 *pixels;
1596
			for ( y=0; yh; ++y ) {
1596
			for ( y=0; yh; ++y ) {
1597
				pixels = (Uint16 *)icon->pixels +
1597
				pixels = (Uint16 *)icon->pixels +
1598
				                   y*icon->pitch/2;
1598
				                   y*icon->pitch/2;
1599
				for ( x=0; xw; ++x ) {
1599
				for ( x=0; xw; ++x ) {
1600
					if ( *pixels++ == colorkey ) {
1600
					if ( *pixels++ == colorkey ) {
1601
						SET_MASKBIT(icon, x, y, mask);
1601
						SET_MASKBIT(icon, x, y, mask);
1602
					}
1602
					}
1603
				}
1603
				}
1604
			}
1604
			}
1605
		}
1605
		}
1606
		break;
1606
		break;
1607
 
1607
 
1608
		case 4: { Uint32 *pixels;
1608
		case 4: { Uint32 *pixels;
1609
			for ( y=0; yh; ++y ) {
1609
			for ( y=0; yh; ++y ) {
1610
				pixels = (Uint32 *)icon->pixels +
1610
				pixels = (Uint32 *)icon->pixels +
1611
				                   y*icon->pitch/4;
1611
				                   y*icon->pitch/4;
1612
				for ( x=0; xw; ++x ) {
1612
				for ( x=0; xw; ++x ) {
1613
					if ( *pixels++ == colorkey ) {
1613
					if ( *pixels++ == colorkey ) {
1614
						SET_MASKBIT(icon, x, y, mask);
1614
						SET_MASKBIT(icon, x, y, mask);
1615
					}
1615
					}
1616
				}
1616
				}
1617
			}
1617
			}
1618
		}
1618
		}
1619
		break;
1619
		break;
1620
	}
1620
	}
1621
}
1621
}
1622
 
1622
 
1623
/*
1623
/*
1624
 * Sets the window manager icon for the display window.
1624
 * Sets the window manager icon for the display window.
1625
 */
1625
 */
1626
void SDL_WM_SetIcon (SDL_Surface *icon, Uint8 *mask)
1626
void SDL_WM_SetIcon (SDL_Surface *icon, Uint8 *mask)
1627
{
1627
{
1628
	SDL_VideoDevice *video = current_video;
1628
	SDL_VideoDevice *video = current_video;
1629
	SDL_VideoDevice *this  = current_video;
1629
	SDL_VideoDevice *this  = current_video;
1630
 
1630
 
1631
	if ( icon && video->SetIcon ) {
1631
	if ( icon && video->SetIcon ) {
1632
		/* Generate a mask if necessary, and create the icon! */
1632
		/* Generate a mask if necessary, and create the icon! */
1633
		if ( mask == NULL ) {
1633
		if ( mask == NULL ) {
1634
			int mask_len = icon->h*(icon->w+7)/8;
1634
			int mask_len = icon->h*(icon->w+7)/8;
1635
			mask = (Uint8 *)malloc(mask_len);
1635
			mask = (Uint8 *)malloc(mask_len);
1636
			if ( mask == NULL ) {
1636
			if ( mask == NULL ) {
1637
				return;
1637
				return;
1638
			}
1638
			}
1639
			memset(mask, ~0, mask_len);
1639
			memset(mask, ~0, mask_len);
1640
			if ( icon->flags & SDL_SRCCOLORKEY ) {
1640
			if ( icon->flags & SDL_SRCCOLORKEY ) {
1641
				CreateMaskFromColorKey(icon, mask);
1641
				CreateMaskFromColorKey(icon, mask);
1642
			}
1642
			}
1643
			video->SetIcon(video, icon, mask);
1643
			video->SetIcon(video, icon, mask);
1644
			free(mask);
1644
			free(mask);
1645
		} else {
1645
		} else {
1646
			video->SetIcon(this, icon, mask);
1646
			video->SetIcon(this, icon, mask);
1647
		}
1647
		}
1648
	}
1648
	}
1649
}
1649
}
1650
 
1650
 
1651
/*
1651
/*
1652
 * Grab or ungrab the keyboard and mouse input.
1652
 * Grab or ungrab the keyboard and mouse input.
1653
 * This function returns the final grab mode after calling the
1653
 * This function returns the final grab mode after calling the
1654
 * driver dependent function.
1654
 * driver dependent function.
1655
 */
1655
 */
1656
static SDL_GrabMode SDL_WM_GrabInputRaw(SDL_GrabMode mode)
1656
static SDL_GrabMode SDL_WM_GrabInputRaw(SDL_GrabMode mode)
1657
{
1657
{
1658
	SDL_VideoDevice *video = current_video;
1658
	SDL_VideoDevice *video = current_video;
1659
	SDL_VideoDevice *this  = current_video;
1659
	SDL_VideoDevice *this  = current_video;
1660
 
1660
 
1661
	/* Only do something if we have support for grabs */
1661
	/* Only do something if we have support for grabs */
1662
	/*if ( video->GrabInput == NULL ) {
1662
	/*if ( video->GrabInput == NULL ) {
1663
		return(video->input_grab);
1663
		return(video->input_grab);
1664
	}*/
1664
	}*/
1665
 
1665
 
1666
	/* If the final grab mode if off, only then do we actually grab */
1666
	/* If the final grab mode if off, only then do we actually grab */
1667
#ifdef DEBUG_GRAB
1667
#ifdef DEBUG_GRAB
1668
  SDL_printf("SDL_WM_GrabInputRaw(%d) ... ", mode);
1668
  SDL_printf("SDL_WM_GrabInputRaw(%d) ... ", mode);
1669
#endif
1669
#endif
1670
	/*if ( mode == SDL_GRAB_OFF ) {
1670
	/*if ( mode == SDL_GRAB_OFF ) {
1671
		if ( video->input_grab != SDL_GRAB_OFF ) {
1671
		if ( video->input_grab != SDL_GRAB_OFF ) {
1672
			mode = video->GrabInput(this, mode);
1672
			mode = video->GrabInput(this, mode);
1673
		}
1673
		}
1674
	} else {
1674
	} else {
1675
		if ( video->input_grab == SDL_GRAB_OFF ) {
1675
		if ( video->input_grab == SDL_GRAB_OFF ) {
1676
			mode = video->GrabInput(this, mode);
1676
			mode = video->GrabInput(this, mode);
1677
		}
1677
		}
1678
	}*/
1678
	}*/
1679
	if ( mode != video->input_grab ) {
1679
	if ( mode != video->input_grab ) {
1680
		video->input_grab = mode;
1680
		video->input_grab = mode;
1681
		if ( video->CheckMouseMode ) {
1681
		if ( video->CheckMouseMode ) {
1682
			video->CheckMouseMode(this);
1682
			video->CheckMouseMode(this);
1683
		}
1683
		}
1684
	}
1684
	}
1685
#ifdef DEBUG_GRAB
1685
#ifdef DEBUG_GRAB
1686
  SDL_printf("Final mode %d\n", video->input_grab);
1686
  SDL_printf("Final mode %d\n", video->input_grab);
1687
#endif
1687
#endif
1688
 
1688
 
1689
	/* Return the final grab state */
1689
	/* Return the final grab state */
1690
	if ( mode >= SDL_GRAB_FULLSCREEN ) {
1690
	if ( mode >= SDL_GRAB_FULLSCREEN ) {
1691
		mode -= SDL_GRAB_FULLSCREEN;
1691
		mode -= SDL_GRAB_FULLSCREEN;
1692
	}
1692
	}
1693
	return(mode);
1693
	return(mode);
1694
}
1694
}
1695
SDL_GrabMode SDL_WM_GrabInput(SDL_GrabMode mode)
1695
SDL_GrabMode SDL_WM_GrabInput(SDL_GrabMode mode)
1696
{
1696
{
1697
	SDL_VideoDevice *video = current_video;
1697
	SDL_VideoDevice *video = current_video;
1698
 
1698
 
1699
	/* If the video isn't initialized yet, we can't do anything */
1699
	/* If the video isn't initialized yet, we can't do anything */
1700
	if ( ! video ) {
1700
	if ( ! video ) {
1701
		return SDL_GRAB_OFF;
1701
		return SDL_GRAB_OFF;
1702
	}
1702
	}
1703
 
1703
 
1704
	/* Return the current mode on query */
1704
	/* Return the current mode on query */
1705
	if ( mode == SDL_GRAB_QUERY ) {
1705
	if ( mode == SDL_GRAB_QUERY ) {
1706
		mode = video->input_grab;
1706
		mode = video->input_grab;
1707
		if ( mode >= SDL_GRAB_FULLSCREEN ) {
1707
		if ( mode >= SDL_GRAB_FULLSCREEN ) {
1708
			mode -= SDL_GRAB_FULLSCREEN;
1708
			mode -= SDL_GRAB_FULLSCREEN;
1709
		}
1709
		}
1710
		return(mode);
1710
		return(mode);
1711
	}
1711
	}
1712
 
1712
 
1713
#ifdef DEBUG_GRAB
1713
#ifdef DEBUG_GRAB
1714
  SDL_printf("SDL_WM_GrabInput(%d) ... ", mode);
1714
  SDL_printf("SDL_WM_GrabInput(%d) ... ", mode);
1715
#endif
1715
#endif
1716
	/* If the video surface is fullscreen, we always grab */
1716
	/* If the video surface is fullscreen, we always grab */
1717
	if ( mode >= SDL_GRAB_FULLSCREEN ) {
1717
	if ( mode >= SDL_GRAB_FULLSCREEN ) {
1718
		mode -= SDL_GRAB_FULLSCREEN;
1718
		mode -= SDL_GRAB_FULLSCREEN;
1719
	}
1719
	}
1720
	if ( SDL_VideoSurface && (SDL_VideoSurface->flags & SDL_FULLSCREEN) ) {
1720
	if ( SDL_VideoSurface && (SDL_VideoSurface->flags & SDL_FULLSCREEN) ) {
1721
		mode += SDL_GRAB_FULLSCREEN;
1721
		mode += SDL_GRAB_FULLSCREEN;
1722
	}
1722
	}
1723
	return(SDL_WM_GrabInputRaw(mode));
1723
	return(SDL_WM_GrabInputRaw(mode));
1724
}
1724
}
1725
static SDL_GrabMode SDL_WM_GrabInputOff(void)
1725
static SDL_GrabMode SDL_WM_GrabInputOff(void)
1726
{
1726
{
1727
	SDL_GrabMode mode;
1727
	SDL_GrabMode mode;
1728
 
1728
 
1729
	/* First query the current grab state */
1729
	/* First query the current grab state */
1730
	mode = SDL_WM_GrabInput(SDL_GRAB_QUERY);
1730
	mode = SDL_WM_GrabInput(SDL_GRAB_QUERY);
1731
 
1731
 
1732
	/* Now explicitly turn off input grab */
1732
	/* Now explicitly turn off input grab */
1733
	SDL_WM_GrabInputRaw(SDL_GRAB_OFF);
1733
	SDL_WM_GrabInputRaw(SDL_GRAB_OFF);
1734
 
1734
 
1735
	/* Return the old state */
1735
	/* Return the old state */
1736
	return(mode);
1736
	return(mode);
1737
}
1737
}
1738
 
1738
 
1739
/*
1739
/*
1740
 * Iconify the window in window managed environments.
1740
 * Iconify the window in window managed environments.
1741
 * A successful iconification will result in an SDL_APPACTIVE loss event.
1741
 * A successful iconification will result in an SDL_APPACTIVE loss event.
1742
 */
1742
 */
1743
int SDL_WM_IconifyWindow(void)
1743
int SDL_WM_IconifyWindow(void)
1744
{
1744
{
1745
	SDL_VideoDevice *video = current_video;
1745
	SDL_VideoDevice *video = current_video;
1746
	SDL_VideoDevice *this  = current_video;
1746
	SDL_VideoDevice *this  = current_video;
1747
	int retval;
1747
	int retval;
1748
 
1748
 
1749
	retval = 0;
1749
	retval = 0;
1750
	if ( video->IconifyWindow ) {
1750
	if ( video->IconifyWindow ) {
1751
		retval = video->IconifyWindow(this);
1751
		retval = video->IconifyWindow(this);
1752
	}
1752
	}
1753
	return(retval);
1753
	return(retval);
1754
}
1754
}
1755
 
1755
 
1756
/*
1756
/*
1757
 * Toggle fullscreen mode
1757
 * Toggle fullscreen mode
1758
 */
1758
 */
1759
int SDL_WM_ToggleFullScreen(SDL_Surface *surface)
1759
int SDL_WM_ToggleFullScreen(SDL_Surface *surface)
1760
{
1760
{
1761
	SDL_VideoDevice *video = current_video;
1761
	SDL_VideoDevice *video = current_video;
1762
	SDL_VideoDevice *this  = current_video;
1762
	SDL_VideoDevice *this  = current_video;
1763
	int toggled;
1763
	int toggled;
1764
 
1764
 
1765
	toggled = 0;
1765
	toggled = 0;
1766
	if ( SDL_PublicSurface && (surface == SDL_PublicSurface) &&
1766
	if ( SDL_PublicSurface && (surface == SDL_PublicSurface) &&
1767
	     video->ToggleFullScreen ) {
1767
	     video->ToggleFullScreen ) {
1768
		if ( surface->flags & SDL_FULLSCREEN ) {
1768
		if ( surface->flags & SDL_FULLSCREEN ) {
1769
			toggled = video->ToggleFullScreen(this, 0);
1769
			toggled = video->ToggleFullScreen(this, 0);
1770
			if ( toggled ) {
1770
			if ( toggled ) {
1771
				SDL_VideoSurface->flags &= ~SDL_FULLSCREEN;
1771
				SDL_VideoSurface->flags &= ~SDL_FULLSCREEN;
1772
				SDL_PublicSurface->flags &= ~SDL_FULLSCREEN;
1772
				SDL_PublicSurface->flags &= ~SDL_FULLSCREEN;
1773
			}
1773
			}
1774
		} else {
1774
		} else {
1775
			toggled = video->ToggleFullScreen(this, 1);
1775
			toggled = video->ToggleFullScreen(this, 1);
1776
			if ( toggled ) {
1776
			if ( toggled ) {
1777
				SDL_VideoSurface->flags |= SDL_FULLSCREEN;
1777
				SDL_VideoSurface->flags |= SDL_FULLSCREEN;
1778
				SDL_PublicSurface->flags |= SDL_FULLSCREEN;
1778
				SDL_PublicSurface->flags |= SDL_FULLSCREEN;
1779
			}
1779
			}
1780
		}
1780
		}
1781
		/* Double-check the grab state inside SDL_WM_GrabInput() */
1781
		/* Double-check the grab state inside SDL_WM_GrabInput() */
1782
		if ( toggled ) {
1782
		if ( toggled ) {
1783
			SDL_WM_GrabInput(video->input_grab);
1783
			SDL_WM_GrabInput(video->input_grab);
1784
		}
1784
		}
1785
	}
1785
	}
1786
	return(toggled);
1786
	return(toggled);
1787
}
1787
}
1788
 
1788
 
1789
/*
1789
/*
1790
 * Get some platform dependent window manager information
1790
 * Get some platform dependent window manager information
1791
 */
1791
 */
1792
int SDL_GetWMInfo (SDL_SysWMinfo *info)
1792
int SDL_GetWMInfo (SDL_SysWMinfo *info)
1793
{
1793
{
1794
	SDL_VideoDevice *video = current_video;
1794
	SDL_VideoDevice *video = current_video;
1795
	SDL_VideoDevice *this  = current_video;
1795
	SDL_VideoDevice *this  = current_video;
1796
 
1796
 
1797
	if ( video && video->GetWMInfo ) {
1797
	if ( video && video->GetWMInfo ) {
1798
		return(video->GetWMInfo(this, info));
1798
		return(video->GetWMInfo(this, info));
1799
	} else {
1799
	} else {
1800
		return(0);
1800
		return(0);
1801
	}
1801
	}
1802
}
1802
}
1803
 
1803
 
1804
>
1804
>
1805
 
1805
 
1806
>
1806
>