comparison src/video/ggi/SDL_ggivideo.c @ 1662:782fd950bd46 SDL-1.3

Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API. WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid. The code is now run through a consistent indent format: indent -i4 -nut -nsc -br -ce The headers are being converted to automatically generate doxygen documentation.
author Sam Lantinga <slouken@libsdl.org>
date Sun, 28 May 2006 13:04:16 +0000
parents 8d9bb0cf2c2a
children 4da1ee79c9af
comparison
equal deleted inserted replaced
1661:281d3f4870e5 1662:782fd950bd46
41 #include "SDL_ggievents_c.h" 41 #include "SDL_ggievents_c.h"
42 42
43 43
44 struct private_hwdata 44 struct private_hwdata
45 { 45 {
46 ggi_visual_t vis; 46 ggi_visual_t vis;
47 }; 47 };
48 48
49 ggi_visual_t VIS; 49 ggi_visual_t VIS;
50 50
51 /* Initialization/Query functions */ 51 /* Initialization/Query functions */
52 static int GGI_VideoInit(_THIS, SDL_PixelFormat *vformat); 52 static int GGI_VideoInit (_THIS, SDL_PixelFormat * vformat);
53 static SDL_Rect **GGI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); 53 static SDL_Rect **GGI_ListModes (_THIS, SDL_PixelFormat * format,
54 static SDL_Surface *GGI_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); 54 Uint32 flags);
55 static int GGI_SetColors(_THIS, int firstcolor, int ncolors, 55 static SDL_Surface *GGI_SetVideoMode (_THIS, SDL_Surface * current, int width,
56 SDL_Color *colors); 56 int height, int bpp, Uint32 flags);
57 static void GGI_VideoQuit(_THIS); 57 static int GGI_SetColors (_THIS, int firstcolor, int ncolors,
58 SDL_Color * colors);
59 static void GGI_VideoQuit (_THIS);
58 60
59 /* Hardware surface functions */ 61 /* Hardware surface functions */
60 static int GGI_AllocHWSurface(_THIS, SDL_Surface *surface); 62 static int GGI_AllocHWSurface (_THIS, SDL_Surface * surface);
61 static int GGI_LockHWSurface(_THIS, SDL_Surface *surface); 63 static int GGI_LockHWSurface (_THIS, SDL_Surface * surface);
62 static void GGI_UnlockHWSurface(_THIS, SDL_Surface *surface); 64 static void GGI_UnlockHWSurface (_THIS, SDL_Surface * surface);
63 static void GGI_FreeHWSurface(_THIS, SDL_Surface *surface); 65 static void GGI_FreeHWSurface (_THIS, SDL_Surface * surface);
64 66
65 /* GGI driver bootstrap functions */ 67 /* GGI driver bootstrap functions */
66 68
67 static int GGI_Available(void) 69 static int
68 { 70 GGI_Available (void)
69 ggi_visual_t *vis; 71 {
70 72 ggi_visual_t *vis;
71 vis = NULL; 73
72 if (ggiInit() == 0) { 74 vis = NULL;
73 vis = ggiOpen(NULL); 75 if (ggiInit () == 0) {
74 if (vis != NULL) { 76 vis = ggiOpen (NULL);
75 ggiClose(vis); 77 if (vis != NULL) {
76 } 78 ggiClose (vis);
77 } 79 }
78 return (vis != NULL); 80 }
79 } 81 return (vis != NULL);
80 82 }
81 static void GGI_DeleteDevice(SDL_VideoDevice *device) 83
82 { 84 static void
83 SDL_free(device->hidden); 85 GGI_DeleteDevice (SDL_VideoDevice * device)
84 SDL_free(device); 86 {
85 } 87 SDL_free (device->hidden);
86 88 SDL_free (device);
87 static SDL_VideoDevice *GGI_CreateDevice(int devindex) 89 }
88 { 90
89 SDL_VideoDevice *device; 91 static SDL_VideoDevice *
90 92 GGI_CreateDevice (int devindex)
91 /* Initialize all variables that we clean on shutdown */ 93 {
92 device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); 94 SDL_VideoDevice *device;
93 if ( device ) { 95
94 SDL_memset(device, 0, (sizeof *device)); 96 /* Initialize all variables that we clean on shutdown */
95 device->hidden = (struct SDL_PrivateVideoData *) 97 device = (SDL_VideoDevice *) SDL_malloc (sizeof (SDL_VideoDevice));
96 SDL_malloc((sizeof *device->hidden)); 98 if (device) {
97 } 99 SDL_memset (device, 0, (sizeof *device));
98 if ( (device == NULL) || (device->hidden == NULL) ) { 100 device->hidden = (struct SDL_PrivateVideoData *)
99 SDL_OutOfMemory(); 101 SDL_malloc ((sizeof *device->hidden));
100 if ( device ) { 102 }
101 SDL_free(device); 103 if ((device == NULL) || (device->hidden == NULL)) {
102 } 104 SDL_OutOfMemory ();
103 return(0); 105 if (device) {
104 } 106 SDL_free (device);
105 SDL_memset(device->hidden, 0, (sizeof *device->hidden)); 107 }
106 108 return (0);
107 /* Set the function pointers */ 109 }
108 device->VideoInit = GGI_VideoInit; 110 SDL_memset (device->hidden, 0, (sizeof *device->hidden));
109 device->ListModes = GGI_ListModes; 111
110 device->SetVideoMode = GGI_SetVideoMode; 112 /* Set the function pointers */
111 device->SetColors = GGI_SetColors; 113 device->VideoInit = GGI_VideoInit;
112 device->UpdateRects = NULL; 114 device->ListModes = GGI_ListModes;
113 device->VideoQuit = GGI_VideoQuit; 115 device->SetVideoMode = GGI_SetVideoMode;
114 device->AllocHWSurface = GGI_AllocHWSurface; 116 device->SetColors = GGI_SetColors;
115 device->CheckHWBlit = NULL; 117 device->UpdateRects = NULL;
116 device->FillHWRect = NULL; 118 device->VideoQuit = GGI_VideoQuit;
117 device->SetHWColorKey = NULL; 119 device->AllocHWSurface = GGI_AllocHWSurface;
118 device->SetHWAlpha = NULL; 120 device->CheckHWBlit = NULL;
119 device->LockHWSurface = GGI_LockHWSurface; 121 device->FillHWRect = NULL;
120 device->UnlockHWSurface = GGI_UnlockHWSurface; 122 device->SetHWColorKey = NULL;
121 device->FlipHWSurface = NULL; 123 device->SetHWAlpha = NULL;
122 device->FreeHWSurface = GGI_FreeHWSurface; 124 device->LockHWSurface = GGI_LockHWSurface;
123 device->SetCaption = NULL; 125 device->UnlockHWSurface = GGI_UnlockHWSurface;
124 device->SetIcon = NULL; 126 device->FlipHWSurface = NULL;
125 device->IconifyWindow = NULL; 127 device->FreeHWSurface = GGI_FreeHWSurface;
126 device->GrabInput = NULL; 128 device->SetCaption = NULL;
127 device->GetWMInfo = NULL; 129 device->SetIcon = NULL;
128 device->InitOSKeymap = GGI_InitOSKeymap; 130 device->IconifyWindow = NULL;
129 device->PumpEvents = GGI_PumpEvents; 131 device->GrabInput = NULL;
130 132 device->GetWMInfo = NULL;
131 device->free = GGI_DeleteDevice; 133 device->InitOSKeymap = GGI_InitOSKeymap;
132 134 device->PumpEvents = GGI_PumpEvents;
133 return device; 135
136 device->free = GGI_DeleteDevice;
137
138 return device;
134 } 139 }
135 140
136 VideoBootStrap GGI_bootstrap = { 141 VideoBootStrap GGI_bootstrap = {
137 "ggi", "General Graphics Interface (GGI)", 142 "ggi", "General Graphics Interface (GGI)",
138 GGI_Available, GGI_CreateDevice 143 GGI_Available, GGI_CreateDevice
139 }; 144 };
140 145
141 146
142 static SDL_Rect video_mode; 147 static SDL_Rect video_mode;
143 static SDL_Rect *SDL_modelist[4] = { NULL, NULL, NULL, NULL }; 148 static SDL_Rect *SDL_modelist[4] = { NULL, NULL, NULL, NULL };
144 149
145 int GGI_VideoInit(_THIS, SDL_PixelFormat *vformat) 150 int
146 { 151 GGI_VideoInit (_THIS, SDL_PixelFormat * vformat)
147 ggi_mode mode = 152 {
148 { 153 ggi_mode mode = {
149 1, 154 1,
150 { GGI_AUTO, GGI_AUTO }, 155 {GGI_AUTO, GGI_AUTO},
151 { GGI_AUTO, GGI_AUTO }, 156 {GGI_AUTO, GGI_AUTO},
152 { 0, 0 }, 157 {0, 0},
153 GT_AUTO, 158 GT_AUTO,
154 { GGI_AUTO, GGI_AUTO } 159 {GGI_AUTO, GGI_AUTO}
155 }; 160 };
156 struct private_hwdata *priv; 161 struct private_hwdata *priv;
157 ggi_color pal[256], map[256]; 162 ggi_color pal[256], map[256];
158 const ggi_directbuffer *db; 163 const ggi_directbuffer *db;
159 int err, num_bufs; 164 int err, num_bufs;
160 ggi_pixel white, black; 165 ggi_pixel white, black;
161 166
162 priv = SDL_malloc(sizeof(struct private_hwdata)); 167 priv = SDL_malloc (sizeof (struct private_hwdata));
163 if (priv == NULL) 168 if (priv == NULL) {
164 { 169 SDL_SetError ("Unhandled GGI mode type!\n");
165 SDL_SetError("Unhandled GGI mode type!\n"); 170 GGI_VideoQuit (NULL);
166 GGI_VideoQuit(NULL); 171 }
167 } 172
168 173 if (ggiInit () != 0) {
169 if (ggiInit() != 0) 174 SDL_SetError ("Unable to initialize GGI!\n");
170 { 175 GGI_VideoQuit (NULL);
171 SDL_SetError("Unable to initialize GGI!\n"); 176 }
172 GGI_VideoQuit(NULL); 177
173 } 178 VIS = ggiOpen (NULL);
174 179 if (VIS == NULL) {
175 VIS = ggiOpen(NULL); 180 SDL_SetError ("Unable to open default GGI visual!\n");
176 if (VIS == NULL) 181 ggiExit ();
177 { 182 GGI_VideoQuit (NULL);
178 SDL_SetError("Unable to open default GGI visual!\n"); 183 }
179 ggiExit(); 184
180 GGI_VideoQuit(NULL); 185 ggiSetFlags (VIS, GGIFLAG_ASYNC);
181 } 186
182 187 /* Validate mode, autodetecting any GGI_AUTO or GT_AUTO fields */
183 ggiSetFlags(VIS, GGIFLAG_ASYNC); 188 ggiCheckMode (VIS, &mode);
184 189
185 /* Validate mode, autodetecting any GGI_AUTO or GT_AUTO fields */ 190 /* At this point we should have a valid mode - try to set it */
186 ggiCheckMode(VIS, &mode); 191 err = ggiSetMode (VIS, &mode);
187 192
188 /* At this point we should have a valid mode - try to set it */ 193 /* If we couldn't set _any_ modes, something is very wrong */
189 err = ggiSetMode(VIS, &mode); 194 if (err) {
190 195 SDL_SetError ("Can't set a mode!\n");
191 /* If we couldn't set _any_ modes, something is very wrong */ 196 ggiClose (VIS);
192 if (err) 197 ggiExit ();
193 { 198 GGI_VideoQuit (NULL);
194 SDL_SetError("Can't set a mode!\n"); 199 }
195 ggiClose(VIS); 200
196 ggiExit(); 201 /* Determine the current screen size */
197 GGI_VideoQuit(NULL); 202 this->info.current_w = mode.virt.x;
198 } 203 this->info.current_h = mode.virt.y;
199 204
200 /* Determine the current screen size */ 205 /* Set a palette for palletized modes */
201 this->info.current_w = mode.virt.x; 206 if (GT_SCHEME (mode.graphtype) == GT_PALETTE) {
202 this->info.current_h = mode.virt.y; 207 ggiSetColorfulPalette (VIS);
203 208 ggiGetPalette (VIS, 0, 1 << vformat->BitsPerPixel, pal);
204 /* Set a palette for palletized modes */ 209 }
205 if (GT_SCHEME(mode.graphtype) == GT_PALETTE) 210
206 { 211 /* Now we try to get the DirectBuffer info, which determines whether
207 ggiSetColorfulPalette(VIS); 212 * SDL can access hardware surfaces directly. */
208 ggiGetPalette(VIS, 0, 1 << vformat->BitsPerPixel, pal); 213
209 } 214 num_bufs = ggiDBGetNumBuffers (VIS);
210 215
211 /* Now we try to get the DirectBuffer info, which determines whether 216 if (num_bufs > 0) {
212 * SDL can access hardware surfaces directly. */ 217 db = ggiDBGetBuffer (VIS, 0); /* Only handle one DB for now */
213 218
214 num_bufs = ggiDBGetNumBuffers(VIS); 219 vformat->BitsPerPixel = db->buffer.plb.pixelformat->depth;
215 220
216 if (num_bufs > 0) 221 vformat->Rmask = db->buffer.plb.pixelformat->red_mask;
217 { 222 vformat->Gmask = db->buffer.plb.pixelformat->green_mask;
218 db = ggiDBGetBuffer(VIS, 0); /* Only handle one DB for now */ 223 vformat->Bmask = db->buffer.plb.pixelformat->blue_mask;
219 224
220 vformat->BitsPerPixel = db->buffer.plb.pixelformat->depth; 225 /* Fill in our hardware acceleration capabilities */
221 226
222 vformat->Rmask = db->buffer.plb.pixelformat->red_mask; 227 this->info.wm_available = 0;
223 vformat->Gmask = db->buffer.plb.pixelformat->green_mask; 228 this->info.hw_available = 1;
224 vformat->Bmask = db->buffer.plb.pixelformat->blue_mask; 229 this->info.video_mem = db->buffer.plb.stride * mode.virt.y;
225 230 }
226 /* Fill in our hardware acceleration capabilities */ 231
227 232 video_mode.x = 0;
228 this->info.wm_available = 0; 233 video_mode.y = 0;
229 this->info.hw_available = 1; 234 video_mode.w = mode.virt.x;
230 this->info.video_mem = db->buffer.plb.stride * mode.virt.y; 235 video_mode.h = mode.virt.y;
231 } 236 SDL_modelist[((vformat->BitsPerPixel + 7) / 8) - 1] = &video_mode;
232 237
233 video_mode.x = 0; 238 /* We're done! */
234 video_mode.y = 0; 239 return (0);
235 video_mode.w = mode.virt.x; 240 }
236 video_mode.h = mode.virt.y; 241
237 SDL_modelist[((vformat->BitsPerPixel + 7) / 8) - 1] = &video_mode; 242 static SDL_Rect **
238 243 GGI_ListModes (_THIS, SDL_PixelFormat * format, Uint32 flags)
239 /* We're done! */ 244 {
240 return(0); 245 return (&SDL_modelist[((format->BitsPerPixel + 7) / 8) - 1]);
241 }
242
243 static SDL_Rect **GGI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
244 {
245 return(&SDL_modelist[((format->BitsPerPixel + 7) / 8) - 1]);
246 } 246 }
247 247
248 /* Various screen update functions available */ 248 /* Various screen update functions available */
249 static void GGI_DirectUpdate(_THIS, int numrects, SDL_Rect *rects); 249 static void GGI_DirectUpdate (_THIS, int numrects, SDL_Rect * rects);
250 250
251 SDL_Surface *GGI_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) 251 SDL_Surface *
252 { 252 GGI_SetVideoMode (_THIS, SDL_Surface * current, int width, int height,
253 ggi_mode mode = 253 int bpp, Uint32 flags)
254 { 254 {
255 1, 255 ggi_mode mode = {
256 { GGI_AUTO, GGI_AUTO }, 256 1,
257 { GGI_AUTO, GGI_AUTO }, 257 {GGI_AUTO, GGI_AUTO},
258 { 0, 0 }, 258 {GGI_AUTO, GGI_AUTO},
259 GT_AUTO, 259 {0, 0},
260 { GGI_AUTO, GGI_AUTO } 260 GT_AUTO,
261 }; 261 {GGI_AUTO, GGI_AUTO}
262 const ggi_directbuffer *db; 262 };
263 ggi_color pal[256]; 263 const ggi_directbuffer *db;
264 int err; 264 ggi_color pal[256];
265 265 int err;
266 fprintf(stderr, "GGI_SetVideoMode()\n"); 266
267 267 fprintf (stderr, "GGI_SetVideoMode()\n");
268 mode.visible.x = mode.virt.x = width; 268
269 mode.visible.y = mode.virt.y = height; 269 mode.visible.x = mode.virt.x = width;
270 270 mode.visible.y = mode.virt.y = height;
271 /* Translate requested SDL bit depth into a GGI mode */ 271
272 switch (bpp) 272 /* Translate requested SDL bit depth into a GGI mode */
273 { 273 switch (bpp) {
274 case 1: mode.graphtype = GT_1BIT; break; 274 case 1:
275 case 2: mode.graphtype = GT_2BIT; break; 275 mode.graphtype = GT_1BIT;
276 case 4: mode.graphtype = GT_4BIT; break; 276 break;
277 case 8: mode.graphtype = GT_8BIT; break; 277 case 2:
278 case 15: mode.graphtype = GT_15BIT; break; 278 mode.graphtype = GT_2BIT;
279 case 16: mode.graphtype = GT_16BIT; break; 279 break;
280 case 24: mode.graphtype = GT_24BIT; break; 280 case 4:
281 case 32: mode.graphtype = GT_32BIT; break; 281 mode.graphtype = GT_4BIT;
282 default: 282 break;
283 SDL_SetError("Unknown SDL bit depth, using GT_AUTO....\n"); 283 case 8:
284 mode.graphtype = GT_AUTO; 284 mode.graphtype = GT_8BIT;
285 } 285 break;
286 286 case 15:
287 /* Validate mode, autodetecting any GGI_AUTO or GT_AUTO fields */ 287 mode.graphtype = GT_15BIT;
288 ggiCheckMode(VIS, &mode); 288 break;
289 289 case 16:
290 /* At this point we should have a valid mode - try to set it */ 290 mode.graphtype = GT_16BIT;
291 err = ggiSetMode(VIS, &mode); 291 break;
292 292 case 24:
293 /* If we couldn't set _any_ modes, something is very wrong */ 293 mode.graphtype = GT_24BIT;
294 if (err) 294 break;
295 { 295 case 32:
296 SDL_SetError("Can't set a mode!\n"); 296 mode.graphtype = GT_32BIT;
297 ggiClose(VIS); 297 break;
298 ggiExit(); 298 default:
299 GGI_VideoQuit(NULL); 299 SDL_SetError ("Unknown SDL bit depth, using GT_AUTO....\n");
300 } 300 mode.graphtype = GT_AUTO;
301 301 }
302 /* Set a palette for palletized modes */ 302
303 if (GT_SCHEME(mode.graphtype) == GT_PALETTE) 303 /* Validate mode, autodetecting any GGI_AUTO or GT_AUTO fields */
304 { 304 ggiCheckMode (VIS, &mode);
305 ggiSetColorfulPalette(VIS); 305
306 ggiGetPalette(VIS, 0, 1 << bpp, pal); 306 /* At this point we should have a valid mode - try to set it */
307 } 307 err = ggiSetMode (VIS, &mode);
308 308
309 db = ggiDBGetBuffer(VIS, 0); 309 /* If we couldn't set _any_ modes, something is very wrong */
310 310 if (err) {
311 /* Set up the new mode framebuffer */ 311 SDL_SetError ("Can't set a mode!\n");
312 current->flags = (SDL_FULLSCREEN | SDL_HWSURFACE); 312 ggiClose (VIS);
313 current->w = mode.virt.x; 313 ggiExit ();
314 current->h = mode.virt.y; 314 GGI_VideoQuit (NULL);
315 current->pitch = db->buffer.plb.stride; 315 }
316 current->pixels = db->read; 316
317 317 /* Set a palette for palletized modes */
318 /* Set the blit function */ 318 if (GT_SCHEME (mode.graphtype) == GT_PALETTE) {
319 this->UpdateRects = GGI_DirectUpdate; 319 ggiSetColorfulPalette (VIS);
320 320 ggiGetPalette (VIS, 0, 1 << bpp, pal);
321 /* We're done */ 321 }
322 return(current); 322
323 } 323 db = ggiDBGetBuffer (VIS, 0);
324 324
325 static int GGI_AllocHWSurface(_THIS, SDL_Surface *surface) 325 /* Set up the new mode framebuffer */
326 { 326 current->flags = (SDL_FULLSCREEN | SDL_HWSURFACE);
327 return(-1); 327 current->w = mode.virt.x;
328 } 328 current->h = mode.virt.y;
329 static void GGI_FreeHWSurface(_THIS, SDL_Surface *surface) 329 current->pitch = db->buffer.plb.stride;
330 { 330 current->pixels = db->read;
331 return; 331
332 } 332 /* Set the blit function */
333 static int GGI_LockHWSurface(_THIS, SDL_Surface *surface) 333 this->UpdateRects = GGI_DirectUpdate;
334 { 334
335 return(0); 335 /* We're done */
336 } 336 return (current);
337 static void GGI_UnlockHWSurface(_THIS, SDL_Surface *surface) 337 }
338 { 338
339 return; 339 static int
340 } 340 GGI_AllocHWSurface (_THIS, SDL_Surface * surface)
341 341 {
342 static void GGI_DirectUpdate(_THIS, int numrects, SDL_Rect *rects) 342 return (-1);
343 { 343 }
344 int i; 344 static void
345 345 GGI_FreeHWSurface (_THIS, SDL_Surface * surface)
346 {
347 return;
348 }
349 static int
350 GGI_LockHWSurface (_THIS, SDL_Surface * surface)
351 {
352 return (0);
353 }
354 static void
355 GGI_UnlockHWSurface (_THIS, SDL_Surface * surface)
356 {
357 return;
358 }
359
360 static void
361 GGI_DirectUpdate (_THIS, int numrects, SDL_Rect * rects)
362 {
363 int i;
364
346 /* ggiFlush(VIS); */ 365 /* ggiFlush(VIS); */
347 366
348 for (i = 0; i < numrects; i++) 367 for (i = 0; i < numrects; i++) {
349 { 368 ggiFlushRegion (VIS, rects[i].x, rects[i].y, rects[i].w, rects[i].h);
350 ggiFlushRegion(VIS, rects[i].x, rects[i].y, rects[i].w, rects[i].h); 369 }
351 } 370 return;
352 return; 371 }
353 } 372
354 373 int
355 int GGI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) 374 GGI_SetColors (_THIS, int firstcolor, int ncolors, SDL_Color * colors)
356 { 375 {
357 int i; 376 int i;
358 ggi_color pal[256]; 377 ggi_color pal[256];
359 378
360 /* Set up the colormap */ 379 /* Set up the colormap */
361 for (i = 0; i < ncolors; i++) 380 for (i = 0; i < ncolors; i++) {
362 { 381 pal[i].r = (colors[i].r << 8) | colors[i].r;
363 pal[i].r = (colors[i].r << 8) | colors[i].r; 382 pal[i].g = (colors[i].g << 8) | colors[i].g;
364 pal[i].g = (colors[i].g << 8) | colors[i].g; 383 pal[i].b = (colors[i].b << 8) | colors[i].b;
365 pal[i].b = (colors[i].b << 8) | colors[i].b; 384 }
366 } 385
367 386 ggiSetPalette (VIS, firstcolor, ncolors, pal);
368 ggiSetPalette(VIS, firstcolor, ncolors, pal); 387
369 388 return 1;
370 return 1; 389 }
371 } 390
372 391 void
373 void GGI_VideoQuit(_THIS) 392 GGI_VideoQuit (_THIS)
374 { 393 {
375 } 394 }
376 void GGI_FinalQuit(void) 395 void
377 { 396 GGI_FinalQuit (void)
378 } 397 {
398 }
399
400 /* vi: set ts=4 sw=4 expandtab: */