Mercurial > sdl-ios-xcode
comparison src/video/vgl/SDL_vglvideo.c @ 75:b0ae59d0f3ee
Added patches from FreeBSD ports
author | Sam Lantinga <slouken@lokigames.com> |
---|---|
date | Tue, 19 Jun 2001 13:33:54 +0000 |
parents | |
children | e8157fcb3114 |
comparison
equal
deleted
inserted
replaced
74:6e28dae59e3b | 75:b0ae59d0f3ee |
---|---|
1 /* | |
2 SDL - Simple DirectMedia Layer | |
3 Copyright (C) 1997, 1998, 1999, 2000 Sam Lantinga | |
4 | |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Library General Public License for more details. | |
14 | |
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 | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
20 slouken@devolution.com | |
21 */ | |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* libvga based SDL video driver implementation. | |
29 */ | |
30 | |
31 #include <err.h> | |
32 #include <osreldate.h> | |
33 #include <stdlib.h> | |
34 #include <stdio.h> | |
35 #include <unistd.h> | |
36 #include <sys/stat.h> | |
37 | |
38 #include <sys/fbio.h> | |
39 #include <sys/consio.h> | |
40 #include <sys/kbio.h> | |
41 #include <vgl.h> | |
42 | |
43 #include "SDL.h" | |
44 #include "SDL_error.h" | |
45 #include "SDL_video.h" | |
46 #include "SDL_mouse.h" | |
47 #include "SDL_sysvideo.h" | |
48 #include "SDL_pixels_c.h" | |
49 #include "SDL_events_c.h" | |
50 #include "SDL_vglvideo.h" | |
51 #include "SDL_vglevents_c.h" | |
52 #include "SDL_vglmouse_c.h" | |
53 | |
54 | |
55 /* Initialization/Query functions */ | |
56 static int VGL_VideoInit(_THIS, SDL_PixelFormat *vformat); | |
57 static SDL_Rect **VGL_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); | |
58 static SDL_Surface *VGL_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | |
59 static int VGL_SetColors(_THIS, int firstcolor, int ncolors, | |
60 SDL_Color *colors); | |
61 static void VGL_VideoQuit(_THIS); | |
62 | |
63 /* Hardware surface functions */ | |
64 static int VGL_AllocHWSurface(_THIS, SDL_Surface *surface); | |
65 static int VGL_LockHWSurface(_THIS, SDL_Surface *surface); | |
66 static int VGL_FlipHWSurface(_THIS, SDL_Surface *surface); | |
67 static void VGL_UnlockHWSurface(_THIS, SDL_Surface *surface); | |
68 static void VGL_FreeHWSurface(_THIS, SDL_Surface *surface); | |
69 | |
70 /* Misc function */ | |
71 static VGLMode ** VGLListModes(int depth, int mem_model); | |
72 static void VGLWaitRetrace(void); | |
73 | |
74 /* VGL driver bootstrap functions */ | |
75 | |
76 static int VGL_Available(void) | |
77 { | |
78 /* | |
79 * Check to see if we are root and stdin is a | |
80 * virtual console. Also try to ensure that | |
81 * modes other than 320x200 are available | |
82 */ | |
83 int console, hires_available, i; | |
84 VGLMode **modes; | |
85 | |
86 console = STDIN_FILENO; | |
87 if ( console >= 0 ) { | |
88 struct stat sb; | |
89 struct vt_mode dummy; | |
90 | |
91 if ( (fstat(console, &sb) < 0) || | |
92 (ioctl(console, VT_GETMODE, &dummy) < 0) ) { | |
93 console = -1; | |
94 } | |
95 } | |
96 if (geteuid() != 0 && console == -1) | |
97 return 0; | |
98 | |
99 modes = VGLListModes(8, V_INFO_MM_DIRECT | V_INFO_MM_PACKED); | |
100 hires_available = 0; | |
101 for (i = 0; modes[i] != NULL; i++) { | |
102 if ((modes[i]->ModeInfo.Xsize > 320) && | |
103 (modes[i]->ModeInfo.Ysize > 200) && | |
104 ((modes[i]->ModeInfo.Type == VIDBUF8) || | |
105 (modes[i]->ModeInfo.Type == VIDBUF16) || | |
106 (modes[i]->ModeInfo.Type == VIDBUF32))) { | |
107 hires_available = 1; | |
108 break; | |
109 } | |
110 } | |
111 return hires_available; | |
112 } | |
113 | |
114 static void VGL_DeleteDevice(SDL_VideoDevice *device) | |
115 { | |
116 free(device->hidden); | |
117 free(device); | |
118 } | |
119 | |
120 static SDL_VideoDevice *VGL_CreateDevice(int devindex) | |
121 { | |
122 SDL_VideoDevice *device; | |
123 | |
124 /* Initialize all variables that we clean on shutdown */ | |
125 device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice)); | |
126 if ( device ) { | |
127 memset(device, 0, (sizeof *device)); | |
128 device->hidden = (struct SDL_PrivateVideoData *) | |
129 malloc((sizeof *device->hidden)); | |
130 } | |
131 if ( (device == NULL) || (device->hidden == NULL) ) { | |
132 SDL_OutOfMemory(); | |
133 if ( device ) { | |
134 free(device); | |
135 } | |
136 return(0); | |
137 } | |
138 memset(device->hidden, 0, (sizeof *device->hidden)); | |
139 | |
140 /* Set the function pointers */ | |
141 device->VideoInit = VGL_VideoInit; | |
142 device->ListModes = VGL_ListModes; | |
143 device->SetVideoMode = VGL_SetVideoMode; | |
144 device->SetColors = VGL_SetColors; | |
145 device->UpdateRects = NULL; | |
146 device->VideoQuit = VGL_VideoQuit; | |
147 device->AllocHWSurface = VGL_AllocHWSurface; | |
148 device->CheckHWBlit = NULL; | |
149 device->FillHWRect = NULL; | |
150 device->SetHWColorKey = NULL; | |
151 device->SetHWAlpha = NULL; | |
152 device->LockHWSurface = VGL_LockHWSurface; | |
153 device->UnlockHWSurface = VGL_UnlockHWSurface; | |
154 device->FlipHWSurface = VGL_FlipHWSurface; | |
155 device->FreeHWSurface = VGL_FreeHWSurface; | |
156 device->SetIcon = NULL; | |
157 device->SetCaption = NULL; | |
158 device->GetWMInfo = NULL; | |
159 device->FreeWMCursor = VGL_FreeWMCursor; | |
160 device->CreateWMCursor = VGL_CreateWMCursor; | |
161 device->ShowWMCursor = VGL_ShowWMCursor; | |
162 device->WarpWMCursor = VGL_WarpWMCursor; | |
163 device->InitOSKeymap = VGL_InitOSKeymap; | |
164 device->PumpEvents = VGL_PumpEvents; | |
165 | |
166 device->free = VGL_DeleteDevice; | |
167 | |
168 return device; | |
169 } | |
170 | |
171 VideoBootStrap VGL_bootstrap = { | |
172 "vgl", "FreeBSD libVGL", | |
173 VGL_Available, VGL_CreateDevice | |
174 }; | |
175 | |
176 static int VGL_AddMode(_THIS, VGLMode *inmode) | |
177 { | |
178 SDL_Rect *mode; | |
179 | |
180 int i, index; | |
181 int next_mode; | |
182 | |
183 /* Check to see if we already have this mode */ | |
184 if (inmode->Depth < 8) { /* Not supported */ | |
185 return 0; | |
186 } | |
187 index = ((inmode->Depth + 7) / 8) - 1; | |
188 for (i=0; i<SDL_nummodes[index]; ++i) { | |
189 mode = SDL_modelist[index][i]; | |
190 if ((mode->w == inmode->ModeInfo.Xsize) && | |
191 (mode->h == inmode->ModeInfo.Ysize)) | |
192 return 0; | |
193 } | |
194 | |
195 /* Set up the new video mode rectangle */ | |
196 mode = (SDL_Rect *)malloc(sizeof *mode); | |
197 if (mode == NULL) { | |
198 SDL_OutOfMemory(); | |
199 return -1; | |
200 } | |
201 mode->x = 0; | |
202 mode->y = 0; | |
203 mode->w = inmode->ModeInfo.Xsize; | |
204 mode->h = inmode->ModeInfo.Ysize; | |
205 | |
206 /* Allocate the new list of modes, and fill in the new mode */ | |
207 next_mode = SDL_nummodes[index]; | |
208 SDL_modelist[index] = (SDL_Rect **) | |
209 realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *)); | |
210 if (SDL_modelist[index] == NULL) { | |
211 SDL_OutOfMemory(); | |
212 SDL_nummodes[index] = 0; | |
213 free(mode); | |
214 return -1; | |
215 } | |
216 SDL_modelist[index][next_mode] = mode; | |
217 SDL_modelist[index][next_mode+1] = NULL; | |
218 SDL_nummodes[index]++; | |
219 | |
220 return 0; | |
221 } | |
222 | |
223 static void VGL_UpdateVideoInfo(_THIS) | |
224 { | |
225 this->info.wm_available = 0; | |
226 this->info.hw_available = 1; | |
227 this->info.video_mem = 0; | |
228 if (VGLCurMode == NULL) { | |
229 return; | |
230 } | |
231 if (VGLCurMode->ModeInfo.PixelBytes > 0) { | |
232 this->info.video_mem = VGLCurMode->ModeInfo.PixelBytes * | |
233 VGLCurMode->ModeInfo.Xsize * | |
234 VGLCurMode->ModeInfo.Ysize; | |
235 } | |
236 } | |
237 | |
238 int VGL_VideoInit(_THIS, SDL_PixelFormat *vformat) | |
239 { | |
240 int i; | |
241 int total_modes; | |
242 VGLMode **modes; | |
243 | |
244 /* Initialize all variables that we clean on shutdown */ | |
245 for ( i=0; i<NUM_MODELISTS; ++i ) { | |
246 SDL_nummodes[i] = 0; | |
247 SDL_modelist[i] = NULL; | |
248 } | |
249 | |
250 /* Enable mouse and keyboard support */ | |
251 if (getenv("SDL_NO_RAWKBD") == NULL) { | |
252 if (VGLKeyboardInit(VGL_CODEKEYS) != 0) { | |
253 SDL_SetError("Unable to initialize keyboard"); | |
254 return -1; | |
255 } | |
256 } else { | |
257 warnx("Requiest to put keyboard into a raw mode ignored"); | |
258 } | |
259 if (VGL_initkeymaps(STDIN_FILENO) != 0) { | |
260 SDL_SetError("Unable to initialize keymap"); | |
261 return -1; | |
262 } | |
263 if (VGL_initmouse(STDIN_FILENO) != 0) { | |
264 SDL_SetError("Unable to initialize mouse"); | |
265 return -1; | |
266 } | |
267 | |
268 /* Determine the screen depth */ | |
269 if (VGLCurMode != NULL) | |
270 vformat->BitsPerPixel = VGLCurMode->Depth; | |
271 else | |
272 vformat->BitsPerPixel = 16; /* Good default */ | |
273 | |
274 /* Query for the list of available video modes */ | |
275 total_modes = 0; | |
276 modes = VGLListModes(-1, V_INFO_MM_DIRECT | V_INFO_MM_PACKED); | |
277 for (i = 0; modes[i] != NULL; i++) { | |
278 if ((modes[i]->ModeInfo.Type == VIDBUF8) || | |
279 (modes[i]->ModeInfo.Type == VIDBUF16) || | |
280 (modes[i]->ModeInfo.Type == VIDBUF32)) { | |
281 VGL_AddMode(this, modes[i]); | |
282 total_modes++; | |
283 } | |
284 } | |
285 if (total_modes == 0) { | |
286 SDL_SetError("No linear video modes available"); | |
287 return -1; | |
288 } | |
289 | |
290 /* Fill in our hardware acceleration capabilities */ | |
291 VGL_UpdateVideoInfo(this); | |
292 | |
293 /* Create the hardware surface lock mutex */ | |
294 hw_lock = SDL_CreateMutex(); | |
295 if (hw_lock == NULL) { | |
296 SDL_SetError("Unable to create lock mutex"); | |
297 VGL_VideoQuit(this); | |
298 return -1; | |
299 } | |
300 | |
301 /* We're done! */ | |
302 return 0; | |
303 } | |
304 | |
305 SDL_Rect **VGL_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) | |
306 { | |
307 return SDL_modelist[((format->BitsPerPixel+7)/8)-1]; | |
308 } | |
309 | |
310 /* Various screen update functions available */ | |
311 static void VGL_DirectUpdate(_THIS, int numrects, SDL_Rect *rects); | |
312 static void VGL_BankedUpdate(_THIS, int numrects, SDL_Rect *rects); | |
313 | |
314 SDL_Surface *VGL_SetVideoMode(_THIS, SDL_Surface *current, | |
315 int width, int height, int bpp, Uint32 flags) | |
316 { | |
317 int mode_found; | |
318 int i; | |
319 VGLMode **modes; | |
320 | |
321 modes = VGLListModes(bpp, V_INFO_MM_DIRECT | V_INFO_MM_PACKED); | |
322 mode_found = 0; | |
323 for (i = 0; modes[i] != NULL; i++) { | |
324 if ((modes[i]->ModeInfo.Xsize == width) && | |
325 (modes[i]->ModeInfo.Ysize == height) && | |
326 ((modes[i]->ModeInfo.Type == VIDBUF8) || | |
327 (modes[i]->ModeInfo.Type == VIDBUF16) || | |
328 (modes[i]->ModeInfo.Type == VIDBUF32))) { | |
329 mode_found = 1; | |
330 break; | |
331 } | |
332 } | |
333 if (mode_found == 0) { | |
334 SDL_SetError("No matching video mode found"); | |
335 return NULL; | |
336 } | |
337 | |
338 /* Shutdown previous videomode (if any) */ | |
339 if (VGLCurMode != NULL) | |
340 VGLEnd(); | |
341 | |
342 /* Try to set the requested linear video mode */ | |
343 if (VGLInit(modes[i]->ModeId) != 0) { | |
344 SDL_SetError("Unable to switch to requested mode"); | |
345 return NULL; | |
346 } | |
347 | |
348 VGLCurMode = realloc(VGLCurMode, sizeof(VGLMode)); | |
349 VGLCurMode->ModeInfo = *VGLDisplay; | |
350 VGLCurMode->Depth = modes[i]->Depth; | |
351 VGLCurMode->ModeId = modes[i]->ModeId; | |
352 VGLCurMode->Rmask = modes[i]->Rmask; | |
353 VGLCurMode->Gmask = modes[i]->Gmask; | |
354 VGLCurMode->Bmask = modes[i]->Bmask; | |
355 | |
356 /* Workaround a bug in libvgl */ | |
357 if (VGLCurMode->ModeInfo.PixelBytes == 0) | |
358 (VGLCurMode->ModeInfo.PixelBytes = 1); | |
359 | |
360 current->w = VGLCurMode->ModeInfo.Xsize; | |
361 current->h = VGLCurMode->ModeInfo.Ysize; | |
362 current->pixels = VGLCurMode->ModeInfo.Bitmap; | |
363 current->pitch = VGLCurMode->ModeInfo.Xsize * | |
364 VGLCurMode->ModeInfo.PixelBytes; | |
365 current->flags = (SDL_FULLSCREEN | SDL_HWSURFACE); | |
366 | |
367 /* Check if we are in a pseudo-color mode */ | |
368 if (VGLCurMode->ModeInfo.Type == VIDBUF8) | |
369 current->flags |= SDL_HWPALETTE; | |
370 | |
371 /* Check if we can do doublebuffering */ | |
372 if (flags & SDL_DOUBLEBUF) { | |
373 if (VGLCurMode->ModeInfo.Xsize * 2 <= | |
374 VGLCurMode->ModeInfo.VYsize) { | |
375 current->flags |= SDL_DOUBLEBUF; | |
376 flip_page = 0; | |
377 flip_address[0] = (byte *)current->pixels; | |
378 flip_address[1] = (byte *)current->pixels + | |
379 current->h * current->pitch; | |
380 VGL_FlipHWSurface(this, current); | |
381 } | |
382 } | |
383 | |
384 if (! SDL_ReallocFormat(current, modes[i]->Depth, VGLCurMode->Rmask, | |
385 VGLCurMode->Gmask, VGLCurMode->Bmask, 0)) { | |
386 return NULL; | |
387 } | |
388 | |
389 /* Update hardware acceleration info */ | |
390 VGL_UpdateVideoInfo(this); | |
391 | |
392 /* Set the blit function */ | |
393 this->UpdateRects = VGL_DirectUpdate; | |
394 | |
395 /* We're done */ | |
396 return current; | |
397 } | |
398 | |
399 /* We don't actually allow hardware surfaces other than the main one */ | |
400 static int VGL_AllocHWSurface(_THIS, SDL_Surface *surface) | |
401 { | |
402 return -1; | |
403 } | |
404 static void VGL_FreeHWSurface(_THIS, SDL_Surface *surface) | |
405 { | |
406 return; | |
407 } | |
408 | |
409 /* We need to wait for vertical retrace on page flipped displays */ | |
410 static int VGL_LockHWSurface(_THIS, SDL_Surface *surface) | |
411 { | |
412 if (surface == SDL_VideoSurface) { | |
413 SDL_mutexP(hw_lock); | |
414 } | |
415 return 0; | |
416 } | |
417 static void VGL_UnlockHWSurface(_THIS, SDL_Surface *surface) | |
418 { | |
419 if (surface == SDL_VideoSurface) { | |
420 SDL_mutexV(hw_lock); | |
421 } | |
422 } | |
423 | |
424 static int VGL_FlipHWSurface(_THIS, SDL_Surface *surface) | |
425 { | |
426 // VGLWaitRetrace(); | |
427 if (VGLPanScreen(VGLDisplay, 0, flip_page * surface->h) < 0) { | |
428 SDL_SetError("VGLPanSreen() failed"); | |
429 return -1; | |
430 } | |
431 | |
432 flip_page = !flip_page; | |
433 surface->pixels = flip_address[flip_page]; | |
434 | |
435 return 0; | |
436 } | |
437 | |
438 static void VGL_DirectUpdate(_THIS, int numrects, SDL_Rect *rects) | |
439 { | |
440 return; | |
441 } | |
442 | |
443 static void VGL_BankedUpdate(_THIS, int numrects, SDL_Rect *rects) | |
444 { | |
445 return; | |
446 } | |
447 | |
448 int VGL_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) | |
449 { | |
450 int i; | |
451 | |
452 for(i = 0; i < ncolors; i++) { | |
453 VGLSetPaletteIndex(firstcolor + i, | |
454 colors[i].r>>2, | |
455 colors[i].g>>2, | |
456 colors[i].b>>2); | |
457 } | |
458 return 1; | |
459 } | |
460 | |
461 /* Note: If we are terminated, this could be called in the middle of | |
462 another SDL video routine -- notably UpdateRects. | |
463 */ | |
464 void VGL_VideoQuit(_THIS) | |
465 { | |
466 int i, j; | |
467 | |
468 /* Return the keyboard to the normal state */ | |
469 VGLKeyboardEnd(); | |
470 | |
471 /* Reset the console video mode if we actually initialised one */ | |
472 if (VGLCurMode != NULL) { | |
473 VGLEnd(); | |
474 free(VGLCurMode); | |
475 VGLCurMode = NULL; | |
476 } | |
477 | |
478 /* Clear the lock mutex */ | |
479 if (hw_lock != NULL) { | |
480 SDL_DestroyMutex(hw_lock); | |
481 hw_lock = NULL; | |
482 } | |
483 | |
484 /* Free video mode lists */ | |
485 for (i = 0; i < NUM_MODELISTS; i++) { | |
486 if (SDL_modelist[i] != NULL) { | |
487 for (j = 0; SDL_modelist[i][j] != NULL; ++j) { | |
488 free(SDL_modelist[i][j]); | |
489 } | |
490 free(SDL_modelist[i]); | |
491 SDL_modelist[i] = NULL; | |
492 } | |
493 } | |
494 | |
495 if ( this->screen && (this->screen->flags & SDL_HWSURFACE) ) { | |
496 /* Direct screen access, not a memory buffer */ | |
497 this->screen->pixels = NULL; | |
498 } | |
499 } | |
500 | |
501 #define VGL_RED_INDEX 0 | |
502 #define VGL_GREEN_INDEX 1 | |
503 #define VGL_BLUE_INDEX 2 | |
504 | |
505 static VGLMode ** | |
506 VGLListModes(int depth, int mem_model) | |
507 { | |
508 static VGLMode **modes = NULL; | |
509 | |
510 VGLBitmap *vminfop; | |
511 VGLMode **modesp, *modescp; | |
512 video_info_t minfo; | |
513 int adptype, i, modenum; | |
514 | |
515 if (modes == NULL) { | |
516 modes = malloc(sizeof(VGLMode *) * M_VESA_MODE_MAX); | |
517 bzero(modes, sizeof(VGLMode *) * M_VESA_MODE_MAX); | |
518 } | |
519 modesp = modes; | |
520 | |
521 for (modenum = 0; modenum < M_VESA_MODE_MAX; modenum++) { | |
522 minfo.vi_mode = modenum; | |
523 if (ioctl(0, CONS_MODEINFO, &minfo) || ioctl(0, CONS_CURRENT, &adptype)) | |
524 continue; | |
525 if (minfo.vi_mode != modenum) | |
526 continue; | |
527 if ((minfo.vi_flags & V_INFO_GRAPHICS) == 0) | |
528 continue; | |
529 if ((mem_model != -1) && ((minfo.vi_mem_model & mem_model) == 0)) | |
530 continue; | |
531 if ((depth > 1) && (minfo.vi_depth != depth)) | |
532 continue; | |
533 | |
534 /* reallocf can fail */ | |
535 if ((*modesp = reallocf(*modesp, sizeof(VGLMode))) == NULL) | |
536 return NULL; | |
537 modescp = *modesp; | |
538 | |
539 vminfop = &(modescp->ModeInfo); | |
540 bzero(vminfop, sizeof(VGLBitmap)); | |
541 | |
542 vminfop->Type = NOBUF; | |
543 | |
544 vminfop->PixelBytes = 1; /* Good default value */ | |
545 switch (minfo.vi_mem_model) { | |
546 case V_INFO_MM_PLANAR: | |
547 /* we can handle EGA/VGA planar modes only */ | |
548 if (!(minfo.vi_depth != 4 || minfo.vi_planes != 4 | |
549 || (adptype != KD_EGA && adptype != KD_VGA))) | |
550 vminfop->Type = VIDBUF4; | |
551 break; | |
552 case V_INFO_MM_PACKED: | |
553 /* we can do only 256 color packed modes */ | |
554 if (minfo.vi_depth == 8) | |
555 vminfop->Type = VIDBUF8; | |
556 break; | |
557 case V_INFO_MM_VGAX: | |
558 vminfop->Type = VIDBUF8X; | |
559 break; | |
560 #if defined(__FreeBSD_version) && __FreeBSD_version >= 500000 | |
561 case V_INFO_MM_DIRECT: | |
562 vminfop->PixelBytes = minfo.vi_pixel_size; | |
563 switch (vminfop->PixelBytes) { | |
564 case 2: | |
565 vminfop->Type = VIDBUF16; | |
566 break; | |
567 #if notyet | |
568 case 3: | |
569 vminfop->Type = VIDBUF24; | |
570 break; | |
571 #endif | |
572 case 4: | |
573 vminfop->Type = VIDBUF32; | |
574 break; | |
575 default: | |
576 break; | |
577 } | |
578 #endif | |
579 default: | |
580 break; | |
581 } | |
582 if (vminfop->Type == NOBUF) | |
583 continue; | |
584 | |
585 switch (vminfop->Type) { | |
586 case VIDBUF16: | |
587 case VIDBUF32: | |
588 modescp->Rmask = ((1 << minfo.vi_pixel_fsizes[VGL_RED_INDEX]) - 1) << | |
589 minfo.vi_pixel_fields[VGL_RED_INDEX]; | |
590 modescp->Gmask = ((1 << minfo.vi_pixel_fsizes[VGL_GREEN_INDEX]) - 1) << | |
591 minfo.vi_pixel_fields[VGL_GREEN_INDEX]; | |
592 modescp->Bmask = ((1 << minfo.vi_pixel_fsizes[VGL_BLUE_INDEX]) - 1) << | |
593 minfo.vi_pixel_fields[VGL_BLUE_INDEX]; | |
594 break; | |
595 | |
596 default: | |
597 break; | |
598 } | |
599 | |
600 vminfop->Xsize = minfo.vi_width; | |
601 vminfop->Ysize = minfo.vi_height; | |
602 modescp->Depth = minfo.vi_depth; | |
603 | |
604 /* XXX */ | |
605 if (minfo.vi_mode >= M_VESA_BASE) | |
606 modescp->ModeId = _IO('V', minfo.vi_mode - M_VESA_BASE); | |
607 else | |
608 modescp->ModeId = _IO('S', minfo.vi_mode); | |
609 | |
610 /* Sort list */ | |
611 for (i = 0; modes + i < modesp ; i++) { | |
612 if (modes[i]->ModeInfo.Xsize * modes[i]->ModeInfo.Ysize > | |
613 vminfop->Xsize * modes[i]->ModeInfo.Ysize) | |
614 continue; | |
615 if ((modes[i]->ModeInfo.Xsize * modes[i]->ModeInfo.Ysize == | |
616 vminfop->Xsize * vminfop->Ysize) && | |
617 (modes[i]->Depth >= modescp->Depth)) | |
618 continue; | |
619 *modesp = modes[i]; | |
620 modes[i] = modescp; | |
621 modescp = *modesp; | |
622 vminfop = &(modescp->ModeInfo); | |
623 } | |
624 | |
625 modesp++; | |
626 } | |
627 | |
628 if (*modesp != NULL) { | |
629 free(*modesp); | |
630 *modesp = NULL; | |
631 } | |
632 | |
633 return modes; | |
634 } | |
635 | |
636 static void | |
637 VGLWaitRetrace(void) | |
638 { | |
639 while (!(inb(0x3DA) & 8)); | |
640 while (inb(0x3DA) & 8); | |
641 } | |
642 |