src/video/dga/SDL_dgavideo.c
changeset 1895 c121d94672cb
parent 1800 cc6bea4bb90d
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
    42 #include "../x11/SDL_x11dyn.h"
    42 #include "../x11/SDL_x11dyn.h"
    43 
    43 
    44 /*#define DGA_DEBUG*/
    44 /*#define DGA_DEBUG*/
    45 
    45 
    46 /* Heheh we're using X11 event code */
    46 /* Heheh we're using X11 event code */
    47 extern void X11_SaveScreenSaver(Display *display, int *saved_timeout, BOOL *dpms);
    47 extern void X11_SaveScreenSaver(Display * display, int *saved_timeout,
    48 extern void X11_DisableScreenSaver(Display *display);
    48                                 BOOL * dpms);
    49 extern void X11_RestoreScreenSaver(Display *display, int saved_timeout, BOOL dpms);
    49 extern void X11_DisableScreenSaver(Display * display);
       
    50 extern void X11_RestoreScreenSaver(Display * display, int saved_timeout,
       
    51                                    BOOL dpms);
    50 
    52 
    51 /* Initialization/Query functions */
    53 /* Initialization/Query functions */
    52 static int DGA_VideoInit(_THIS, SDL_PixelFormat *vformat);
    54 static int DGA_VideoInit(_THIS, SDL_PixelFormat * vformat);
    53 static SDL_Rect **DGA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
    55 static SDL_Rect **DGA_ListModes(_THIS, SDL_PixelFormat * format,
    54 static SDL_Surface *DGA_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
    56                                 Uint32 flags);
       
    57 static SDL_Surface *DGA_SetVideoMode(_THIS, SDL_Surface * current, int width,
       
    58                                      int height, int bpp, Uint32 flags);
    55 static int DGA_SetColors(_THIS, int firstcolor, int ncolors,
    59 static int DGA_SetColors(_THIS, int firstcolor, int ncolors,
    56 			 SDL_Color *colors);
    60                          SDL_Color * colors);
    57 static int DGA_SetGammaRamp(_THIS, Uint16 *ramp);
    61 static int DGA_SetGammaRamp(_THIS, Uint16 * ramp);
    58 static void DGA_VideoQuit(_THIS);
    62 static void DGA_VideoQuit(_THIS);
    59 
    63 
    60 /* Hardware surface functions */
    64 /* Hardware surface functions */
    61 static int DGA_InitHWSurfaces(_THIS, SDL_Surface *screen, Uint8 *base, int size);
    65 static int DGA_InitHWSurfaces(_THIS, SDL_Surface * screen, Uint8 * base,
       
    66                               int size);
    62 static void DGA_FreeHWSurfaces(_THIS);
    67 static void DGA_FreeHWSurfaces(_THIS);
    63 static int DGA_AllocHWSurface(_THIS, SDL_Surface *surface);
    68 static int DGA_AllocHWSurface(_THIS, SDL_Surface * surface);
    64 static int DGA_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color);
    69 static int DGA_FillHWRect(_THIS, SDL_Surface * dst, SDL_Rect * rect,
    65 static int DGA_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst);
    70                           Uint32 color);
    66 static int DGA_LockHWSurface(_THIS, SDL_Surface *surface);
    71 static int DGA_CheckHWBlit(_THIS, SDL_Surface * src, SDL_Surface * dst);
    67 static void DGA_UnlockHWSurface(_THIS, SDL_Surface *surface);
    72 static int DGA_LockHWSurface(_THIS, SDL_Surface * surface);
    68 static void DGA_FreeHWSurface(_THIS, SDL_Surface *surface);
    73 static void DGA_UnlockHWSurface(_THIS, SDL_Surface * surface);
    69 static int DGA_FlipHWSurface(_THIS, SDL_Surface *surface);
    74 static void DGA_FreeHWSurface(_THIS, SDL_Surface * surface);
       
    75 static int DGA_FlipHWSurface(_THIS, SDL_Surface * surface);
    70 
    76 
    71 /* DGA driver bootstrap functions */
    77 /* DGA driver bootstrap functions */
    72 
    78 
    73 static int DGA_Available(void)
    79 static int
    74 {
    80 DGA_Available(void)
    75 	const char *display = NULL;
    81 {
    76 	Display *dpy = NULL;
    82     const char *display = NULL;
    77 	int available = 0;
    83     Display *dpy = NULL;
    78 
    84     int available = 0;
    79 	/* The driver is available is available if the display is local
    85 
    80 	   and the DGA 2.0+ extension is available, and we can map mem.
    86     /* The driver is available is available if the display is local
    81 	*/
    87        and the DGA 2.0+ extension is available, and we can map mem.
    82 	if ( SDL_X11_LoadSymbols() ) {
    88      */
    83 		if ( (SDL_strncmp(XDisplayName(display), ":", 1) == 0) ||
    89     if (SDL_X11_LoadSymbols()) {
    84 		     (SDL_strncmp(XDisplayName(display), "unix:", 5) == 0) ) {
    90         if ((SDL_strncmp(XDisplayName(display), ":", 1) == 0) ||
    85 			dpy = XOpenDisplay(display);
    91             (SDL_strncmp(XDisplayName(display), "unix:", 5) == 0)) {
    86 			if ( dpy ) {
    92             dpy = XOpenDisplay(display);
    87 				int events, errors, major, minor;
    93             if (dpy) {
    88 
    94                 int events, errors, major, minor;
    89 				if ( SDL_NAME(XDGAQueryExtension)(dpy, &events, &errors) &&
    95 
    90 				     SDL_NAME(XDGAQueryVersion)(dpy, &major, &minor) ) {
    96                 if (SDL_NAME(XDGAQueryExtension)
    91 					int screen;
    97                     (dpy, &events, &errors)
    92 
    98                     && SDL_NAME(XDGAQueryVersion) (dpy, &major, &minor)) {
    93 					screen = DefaultScreen(dpy);
    99                     int screen;
    94 					if ( (major >= 2) && 
   100 
    95 					     SDL_NAME(XDGAOpenFramebuffer)(dpy, screen) ) {
   101                     screen = DefaultScreen(dpy);
    96 						available = 1;
   102                     if ((major >= 2) &&
    97 						SDL_NAME(XDGACloseFramebuffer)(dpy, screen);
   103                         SDL_NAME(XDGAOpenFramebuffer) (dpy, screen)) {
    98 					}
   104                         available = 1;
    99 				}
   105                         SDL_NAME(XDGACloseFramebuffer) (dpy, screen);
   100 				XCloseDisplay(dpy);
   106                     }
   101 			}
   107                 }
   102 		}
   108                 XCloseDisplay(dpy);
   103 		SDL_X11_UnloadSymbols();
   109             }
   104 	}
   110         }
   105 	return(available);
   111         SDL_X11_UnloadSymbols();
   106 }
   112     }
   107 
   113     return (available);
   108 static void DGA_DeleteDevice(SDL_VideoDevice *device)
   114 }
   109 {
   115 
   110 	if (device != NULL) {
   116 static void
   111 		SDL_free(device->hidden);
   117 DGA_DeleteDevice(SDL_VideoDevice * device)
   112 		SDL_free(device);
   118 {
   113 		SDL_X11_UnloadSymbols();
   119     if (device != NULL) {
   114 	}
   120         SDL_free(device->hidden);
   115 }
   121         SDL_free(device);
   116 
   122         SDL_X11_UnloadSymbols();
   117 static SDL_VideoDevice *DGA_CreateDevice(int devindex)
   123     }
   118 {
   124 }
   119 	SDL_VideoDevice *device = NULL;
   125 
   120 
   126 static SDL_VideoDevice *
   121 	/* Initialize all variables that we clean on shutdown */
   127 DGA_CreateDevice(int devindex)
   122 	if (SDL_X11_LoadSymbols()) {
   128 {
   123 		device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
   129     SDL_VideoDevice *device = NULL;
   124 		if ( device ) {
   130 
   125 			SDL_memset(device, 0, (sizeof *device));
   131     /* Initialize all variables that we clean on shutdown */
   126 			device->hidden = (struct SDL_PrivateVideoData *)
   132     if (SDL_X11_LoadSymbols()) {
   127 					SDL_malloc((sizeof *device->hidden));
   133         device = (SDL_VideoDevice *) SDL_malloc(sizeof(SDL_VideoDevice));
   128 		}
   134         if (device) {
   129 		if ( (device == NULL) || (device->hidden == NULL) ) {
   135             SDL_memset(device, 0, (sizeof *device));
   130 			SDL_OutOfMemory();
   136             device->hidden = (struct SDL_PrivateVideoData *)
   131 			if ( device ) {
   137                 SDL_malloc((sizeof *device->hidden));
   132 				SDL_free(device);
   138         }
   133 			}
   139         if ((device == NULL) || (device->hidden == NULL)) {
   134 			SDL_X11_UnloadSymbols();
   140             SDL_OutOfMemory();
   135 			return(0);
   141             if (device) {
   136 		}
   142                 SDL_free(device);
   137 		SDL_memset(device->hidden, 0, (sizeof *device->hidden));
   143             }
   138 
   144             SDL_X11_UnloadSymbols();
   139 		/* Set the function pointers */
   145             return (0);
   140 		device->VideoInit = DGA_VideoInit;
   146         }
   141 		device->ListModes = DGA_ListModes;
   147         SDL_memset(device->hidden, 0, (sizeof *device->hidden));
   142 		device->SetVideoMode = DGA_SetVideoMode;
   148 
   143 		device->SetColors = DGA_SetColors;
   149         /* Set the function pointers */
   144 		device->UpdateRects = NULL;
   150         device->VideoInit = DGA_VideoInit;
   145 		device->VideoQuit = DGA_VideoQuit;
   151         device->ListModes = DGA_ListModes;
   146 		device->AllocHWSurface = DGA_AllocHWSurface;
   152         device->SetVideoMode = DGA_SetVideoMode;
   147 		device->CheckHWBlit = DGA_CheckHWBlit;
   153         device->SetColors = DGA_SetColors;
   148 		device->FillHWRect = DGA_FillHWRect;
   154         device->UpdateRects = NULL;
   149 		device->SetHWColorKey = NULL;
   155         device->VideoQuit = DGA_VideoQuit;
   150 		device->SetHWAlpha = NULL;
   156         device->AllocHWSurface = DGA_AllocHWSurface;
   151 		device->LockHWSurface = DGA_LockHWSurface;
   157         device->CheckHWBlit = DGA_CheckHWBlit;
   152 		device->UnlockHWSurface = DGA_UnlockHWSurface;
   158         device->FillHWRect = DGA_FillHWRect;
   153 		device->FlipHWSurface = DGA_FlipHWSurface;
   159         device->SetHWColorKey = NULL;
   154 		device->FreeHWSurface = DGA_FreeHWSurface;
   160         device->SetHWAlpha = NULL;
   155 		device->SetGammaRamp = DGA_SetGammaRamp;
   161         device->LockHWSurface = DGA_LockHWSurface;
   156 		device->GetGammaRamp = NULL;
   162         device->UnlockHWSurface = DGA_UnlockHWSurface;
   157 		device->SetCaption = NULL;
   163         device->FlipHWSurface = DGA_FlipHWSurface;
   158 		device->SetIcon = NULL;
   164         device->FreeHWSurface = DGA_FreeHWSurface;
   159 		device->IconifyWindow = NULL;
   165         device->SetGammaRamp = DGA_SetGammaRamp;
   160 		device->GrabInput = NULL;
   166         device->GetGammaRamp = NULL;
   161 		device->GetWMInfo = NULL;
   167         device->SetCaption = NULL;
   162 		device->InitOSKeymap = DGA_InitOSKeymap;
   168         device->SetIcon = NULL;
   163 		device->PumpEvents = DGA_PumpEvents;
   169         device->IconifyWindow = NULL;
   164 
   170         device->GrabInput = NULL;
   165 		device->free = DGA_DeleteDevice;
   171         device->GetWMInfo = NULL;
   166 	}
   172         device->InitOSKeymap = DGA_InitOSKeymap;
   167 
   173         device->PumpEvents = DGA_PumpEvents;
   168 	return device;
   174 
       
   175         device->free = DGA_DeleteDevice;
       
   176     }
       
   177 
       
   178     return device;
   169 }
   179 }
   170 
   180 
   171 VideoBootStrap DGA_bootstrap = {
   181 VideoBootStrap DGA_bootstrap = {
   172 	"dga", "XFree86 DGA 2.0",
   182     "dga", "XFree86 DGA 2.0",
   173 	DGA_Available, DGA_CreateDevice
   183     DGA_Available, DGA_CreateDevice
   174 };
   184 };
   175 
   185 
   176 static int DGA_AddMode(_THIS, int bpp, int w, int h)
   186 static int
   177 {
   187 DGA_AddMode(_THIS, int bpp, int w, int h)
   178 	SDL_Rect *mode;
   188 {
   179 	int index;
   189     SDL_Rect *mode;
   180 	int next_mode;
   190     int index;
   181 
   191     int next_mode;
   182 	/* Check to see if we already have this mode */
   192 
   183 	if ( bpp < 8 ) {  /* Not supported */
   193     /* Check to see if we already have this mode */
   184 		return(0);
   194     if (bpp < 8) {              /* Not supported */
   185 	}
   195         return (0);
   186 	index = ((bpp+7)/8)-1;
   196     }
   187 	if ( SDL_nummodes[index] > 0 ) {
   197     index = ((bpp + 7) / 8) - 1;
   188 		mode = SDL_modelist[index][SDL_nummodes[index]-1];
   198     if (SDL_nummodes[index] > 0) {
   189 		if ( (mode->w == w) && (mode->h == h) ) {
   199         mode = SDL_modelist[index][SDL_nummodes[index] - 1];
   190 			return(0);
   200         if ((mode->w == w) && (mode->h == h)) {
   191 		}
   201             return (0);
   192 	}
   202         }
   193 
   203     }
   194 	/* Set up the new video mode rectangle */
   204 
   195 	mode = (SDL_Rect *)SDL_malloc(sizeof *mode);
   205     /* Set up the new video mode rectangle */
   196 	if ( mode == NULL ) {
   206     mode = (SDL_Rect *) SDL_malloc(sizeof *mode);
   197 		SDL_OutOfMemory();
   207     if (mode == NULL) {
   198 		return(-1);
   208         SDL_OutOfMemory();
   199 	}
   209         return (-1);
   200 	mode->x = 0;
   210     }
   201 	mode->y = 0;
   211     mode->x = 0;
   202 	mode->w = w;
   212     mode->y = 0;
   203 	mode->h = h;
   213     mode->w = w;
   204 
   214     mode->h = h;
   205 	/* Allocate the new list of modes, and fill in the new mode */
   215 
   206 	next_mode = SDL_nummodes[index];
   216     /* Allocate the new list of modes, and fill in the new mode */
   207 	SDL_modelist[index] = (SDL_Rect **)
   217     next_mode = SDL_nummodes[index];
   208 	       SDL_realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *));
   218     SDL_modelist[index] = (SDL_Rect **)
   209 	if ( SDL_modelist[index] == NULL ) {
   219         SDL_realloc(SDL_modelist[index],
   210 		SDL_OutOfMemory();
   220                     (1 + next_mode + 1) * sizeof(SDL_Rect *));
   211 		SDL_nummodes[index] = 0;
   221     if (SDL_modelist[index] == NULL) {
   212 		SDL_free(mode);
   222         SDL_OutOfMemory();
   213 		return(-1);
   223         SDL_nummodes[index] = 0;
   214 	}
   224         SDL_free(mode);
   215 	SDL_modelist[index][next_mode] = mode;
   225         return (-1);
   216 	SDL_modelist[index][next_mode+1] = NULL;
   226     }
   217 	SDL_nummodes[index]++;
   227     SDL_modelist[index][next_mode] = mode;
   218 
   228     SDL_modelist[index][next_mode + 1] = NULL;
   219 	return(0);
   229     SDL_nummodes[index]++;
       
   230 
       
   231     return (0);
   220 }
   232 }
   221 
   233 
   222 /* This whole function is a hack. :) */
   234 /* This whole function is a hack. :) */
   223 static Uint32 get_video_size(_THIS)
   235 static Uint32
   224 {
   236 get_video_size(_THIS)
   225 	/* This is a non-exported function from libXxf86dga.a */
   237 {
   226 	extern unsigned char *SDL_NAME(XDGAGetMappedMemory)(int screen);
   238     /* This is a non-exported function from libXxf86dga.a */
   227 	FILE *proc;
   239     extern unsigned char *SDL_NAME(XDGAGetMappedMemory) (int screen);
   228 	unsigned long mem;
   240     FILE *proc;
   229 	unsigned start, stop;
   241     unsigned long mem;
   230 	char line[BUFSIZ];
   242     unsigned start, stop;
   231 	Uint32 size;
   243     char line[BUFSIZ];
   232 
   244     Uint32 size;
   233 	mem = (unsigned long)SDL_NAME(XDGAGetMappedMemory)(DGA_Screen);
   245 
   234 	size = 0;
   246     mem = (unsigned long) SDL_NAME(XDGAGetMappedMemory) (DGA_Screen);
   235 	proc = fopen("/proc/self/maps", "r");
   247     size = 0;
   236 	if ( proc ) {
   248     proc = fopen("/proc/self/maps", "r");
   237 		while ( fgets(line, sizeof(line)-1, proc) ) {
   249     if (proc) {
   238 			SDL_sscanf(line, "%x-%x", &start, &stop);
   250         while (fgets(line, sizeof(line) - 1, proc)) {
   239 			if ( start == mem ) {
   251             SDL_sscanf(line, "%x-%x", &start, &stop);
   240 				size = (Uint32)((stop-start)/1024);
   252             if (start == mem) {
   241 				break;
   253                 size = (Uint32) ((stop - start) / 1024);
   242 			}
   254                 break;
   243 		}
   255             }
   244 		fclose(proc);
   256         }
   245 	}
   257         fclose(proc);
   246 	return(size);
   258     }
       
   259     return (size);
   247 }
   260 }
   248 
   261 
   249 #ifdef DGA_DEBUG
   262 #ifdef DGA_DEBUG
   250 static void PrintMode(SDL_NAME(XDGAMode) *mode)
   263 static void
   251 {
   264 PrintMode(SDL_NAME(XDGAMode) * mode)
   252 	printf("Mode: %s (%dx%d) at %d bpp (%f refresh, %d pitch) num: %d\n",
   265 {
   253 		mode->name,
   266     printf("Mode: %s (%dx%d) at %d bpp (%f refresh, %d pitch) num: %d\n",
   254 		mode->viewportWidth, mode->viewportHeight,
   267            mode->name,
   255 		mode->depth == 24 ? mode->bitsPerPixel : mode->depth,
   268            mode->viewportWidth, mode->viewportHeight,
   256 		mode->verticalRefresh, mode->bytesPerScanline, mode->num);
   269            mode->depth == 24 ? mode->bitsPerPixel : mode->depth,
   257 	printf("\tRGB: 0x%8.8x 0x%8.8x 0x%8.8x (%d - %s)\n",
   270            mode->verticalRefresh, mode->bytesPerScanline, mode->num);
   258 		mode->redMask, mode->greenMask, mode->blueMask,
   271     printf("\tRGB: 0x%8.8x 0x%8.8x 0x%8.8x (%d - %s)\n",
   259 		mode->visualClass,
   272            mode->redMask, mode->greenMask, mode->blueMask,
   260 		mode->visualClass == TrueColor ? "truecolor" :
   273            mode->visualClass,
   261 		mode->visualClass == DirectColor ? "directcolor" :
   274            mode->visualClass == TrueColor ? "truecolor" :
   262 		mode->visualClass == PseudoColor ? "pseudocolor" : "unknown");
   275            mode->visualClass == DirectColor ? "directcolor" :
   263 	printf("\tFlags: ");
   276            mode->visualClass == PseudoColor ? "pseudocolor" : "unknown");
   264 	if ( mode->flags & XDGAConcurrentAccess )
   277     printf("\tFlags: ");
   265 		printf(" XDGAConcurrentAccess");
   278     if (mode->flags & XDGAConcurrentAccess)
   266 	if ( mode->flags & XDGASolidFillRect )
   279         printf(" XDGAConcurrentAccess");
   267 		printf(" XDGASolidFillRect");
   280     if (mode->flags & XDGASolidFillRect)
   268 	if ( mode->flags & XDGABlitRect )
   281         printf(" XDGASolidFillRect");
   269 		printf(" XDGABlitRect");
   282     if (mode->flags & XDGABlitRect)
   270 	if ( mode->flags & XDGABlitTransRect )
   283         printf(" XDGABlitRect");
   271 		printf(" XDGABlitTransRect");
   284     if (mode->flags & XDGABlitTransRect)
   272 	if ( mode->flags & XDGAPixmap )
   285         printf(" XDGABlitTransRect");
   273 		printf(" XDGAPixmap");
   286     if (mode->flags & XDGAPixmap)
   274 	if ( mode->flags & XDGAInterlaced )
   287         printf(" XDGAPixmap");
   275 		printf(" XDGAInterlaced");
   288     if (mode->flags & XDGAInterlaced)
   276 	if ( mode->flags & XDGADoublescan )
   289         printf(" XDGAInterlaced");
   277 		printf(" XDGADoublescan");
   290     if (mode->flags & XDGADoublescan)
   278 	if ( mode->viewportFlags & XDGAFlipRetrace )
   291         printf(" XDGADoublescan");
   279 		printf(" XDGAFlipRetrace");
   292     if (mode->viewportFlags & XDGAFlipRetrace)
   280 	if ( mode->viewportFlags & XDGAFlipImmediate )
   293         printf(" XDGAFlipRetrace");
   281 		printf(" XDGAFlipImmediate");
   294     if (mode->viewportFlags & XDGAFlipImmediate)
   282 	printf("\n");
   295         printf(" XDGAFlipImmediate");
       
   296     printf("\n");
   283 }
   297 }
   284 #endif /* DGA_DEBUG */
   298 #endif /* DGA_DEBUG */
   285 
   299 
   286 static int cmpmodes(const void *va, const void *vb)
   300 static int
   287 {
   301 cmpmodes(const void *va, const void *vb)
   288     const SDL_NAME(XDGAMode) *a = (const SDL_NAME(XDGAMode) *)va;
   302 {
   289     const SDL_NAME(XDGAMode) *b = (const SDL_NAME(XDGAMode) *)vb;
   303     const SDL_NAME(XDGAMode) * a = (const SDL_NAME(XDGAMode) *) va;
   290 
   304     const SDL_NAME(XDGAMode) * b = (const SDL_NAME(XDGAMode) *) vb;
   291     if ( (a->viewportWidth == b->viewportWidth) &&
   305 
   292          (b->viewportHeight == a->viewportHeight) ) {
   306     if ((a->viewportWidth == b->viewportWidth) &&
       
   307         (b->viewportHeight == a->viewportHeight)) {
   293         /* Prefer 32 bpp over 24 bpp, 16 bpp over 15 bpp */
   308         /* Prefer 32 bpp over 24 bpp, 16 bpp over 15 bpp */
   294         int a_bpp = a->depth == 24 ? a->bitsPerPixel : a->depth;
   309         int a_bpp = a->depth == 24 ? a->bitsPerPixel : a->depth;
   295         int b_bpp = b->depth == 24 ? b->bitsPerPixel : b->depth;
   310         int b_bpp = b->depth == 24 ? b->bitsPerPixel : b->depth;
   296         if ( a_bpp != b_bpp ) {
   311         if (a_bpp != b_bpp) {
   297             return b_bpp - a_bpp;
   312             return b_bpp - a_bpp;
   298         }
   313         }
   299         /* Prefer DirectColor visuals, for gamma support */
   314         /* Prefer DirectColor visuals, for gamma support */
   300         if ( a->visualClass == DirectColor && b->visualClass != DirectColor )
   315         if (a->visualClass == DirectColor && b->visualClass != DirectColor)
   301             return -1;
   316             return -1;
   302         if ( b->visualClass == DirectColor && a->visualClass != DirectColor )
   317         if (b->visualClass == DirectColor && a->visualClass != DirectColor)
   303             return 1;
   318             return 1;
   304         /* Maintain server refresh rate sorting */
   319         /* Maintain server refresh rate sorting */
   305         return a->num - b->num;
   320         return a->num - b->num;
   306     } else if ( a->viewportWidth == b->viewportWidth ) {
   321     } else if (a->viewportWidth == b->viewportWidth) {
   307         return b->viewportHeight - a->viewportHeight;
   322         return b->viewportHeight - a->viewportHeight;
   308     } else {
   323     } else {
   309         return b->viewportWidth - a->viewportWidth;
   324         return b->viewportWidth - a->viewportWidth;
   310     }
   325     }
   311 }
   326 }
   312 static void UpdateHWInfo(_THIS, SDL_NAME(XDGAMode) *mode)
   327 static void
   313 {
   328 UpdateHWInfo(_THIS, SDL_NAME(XDGAMode) * mode)
   314 	this->info.wm_available = 0;
   329 {
   315 	this->info.hw_available = 1;
   330     this->info.wm_available = 0;
   316 	if ( mode->flags & XDGABlitRect ) {
   331     this->info.hw_available = 1;
   317 		this->info.blit_hw = 1;
   332     if (mode->flags & XDGABlitRect) {
   318 	} else {
   333         this->info.blit_hw = 1;
   319 		this->info.blit_hw = 0;
   334     } else {
   320 	}
   335         this->info.blit_hw = 0;
   321 	if ( mode->flags & XDGABlitTransRect ) {
   336     }
   322 		this->info.blit_hw_CC = 1;
   337     if (mode->flags & XDGABlitTransRect) {
   323 	} else {
   338         this->info.blit_hw_CC = 1;
   324 		this->info.blit_hw_CC = 0;
   339     } else {
   325 	}
   340         this->info.blit_hw_CC = 0;
   326 	if ( mode->flags & XDGASolidFillRect ) {
   341     }
   327 		this->info.blit_fill = 1;
   342     if (mode->flags & XDGASolidFillRect) {
   328 	} else {
   343         this->info.blit_fill = 1;
   329 		this->info.blit_fill = 0;
   344     } else {
   330 	}
   345         this->info.blit_fill = 0;
   331 	this->info.video_mem = get_video_size(this);
   346     }
   332 }
   347     this->info.video_mem = get_video_size(this);
   333 
   348 }
   334 static int DGA_VideoInit(_THIS, SDL_PixelFormat *vformat)
   349 
   335 {
   350 static int
   336 	const char *display;
   351 DGA_VideoInit(_THIS, SDL_PixelFormat * vformat)
   337 	int event_base, error_base;
   352 {
   338 	int major_version, minor_version;
   353     const char *display;
   339 	Visual *visual;
   354     int event_base, error_base;
   340 	SDL_NAME(XDGAMode) *modes;
   355     int major_version, minor_version;
   341 	int i, num_modes;
   356     Visual *visual;
   342 
   357     SDL_NAME(XDGAMode) * modes;
   343 	/* Open the X11 display */
   358     int i, num_modes;
   344 	display = NULL;		/* Get it from DISPLAY environment variable */
   359 
   345 
   360     /* Open the X11 display */
   346 	DGA_Display = XOpenDisplay(display);
   361     display = NULL;             /* Get it from DISPLAY environment variable */
   347 	if ( DGA_Display == NULL ) {
   362 
   348 		SDL_SetError("Couldn't open X11 display");
   363     DGA_Display = XOpenDisplay(display);
   349 		return(-1);
   364     if (DGA_Display == NULL) {
   350 	}
   365         SDL_SetError("Couldn't open X11 display");
   351 
   366         return (-1);
   352 	/* Check for the DGA extension */
   367     }
   353 	if ( ! SDL_NAME(XDGAQueryExtension)(DGA_Display, &event_base, &error_base) ||
   368 
   354 	     ! SDL_NAME(XDGAQueryVersion)(DGA_Display, &major_version, &minor_version) ) {
   369     /* Check for the DGA extension */
   355 		SDL_SetError("DGA extension not available");
   370     if (!SDL_NAME(XDGAQueryExtension) (DGA_Display, &event_base, &error_base)
   356 		XCloseDisplay(DGA_Display);
   371         || !SDL_NAME(XDGAQueryVersion) (DGA_Display, &major_version,
   357 		return(-1);
   372                                         &minor_version)) {
   358 	}
   373         SDL_SetError("DGA extension not available");
   359 	if ( major_version < 2 ) {
   374         XCloseDisplay(DGA_Display);
   360 		SDL_SetError("DGA driver requires DGA 2.0 or newer");
   375         return (-1);
   361 		XCloseDisplay(DGA_Display);
   376     }
   362 		return(-1);
   377     if (major_version < 2) {
   363 	}
   378         SDL_SetError("DGA driver requires DGA 2.0 or newer");
   364 	DGA_event_base = event_base;
   379         XCloseDisplay(DGA_Display);
   365 
   380         return (-1);
   366 	/* Determine the current screen size */
   381     }
   367 	this->info.current_w = DisplayWidth(DGA_Display, DGA_Screen);
   382     DGA_event_base = event_base;
   368 	this->info.current_h = DisplayHeight(DGA_Display, DGA_Screen);
   383 
   369 
   384     /* Determine the current screen size */
   370 	/* Determine the current screen depth */
   385     this->info.current_w = DisplayWidth(DGA_Display, DGA_Screen);
   371 	visual = DefaultVisual(DGA_Display, DGA_Screen);
   386     this->info.current_h = DisplayHeight(DGA_Display, DGA_Screen);
   372 	{
   387 
   373 		XPixmapFormatValues *pix_format;
   388     /* Determine the current screen depth */
   374 		int i, num_formats;
   389     visual = DefaultVisual(DGA_Display, DGA_Screen);
   375 
   390     {
   376 		vformat->BitsPerPixel = DefaultDepth(DGA_Display, DGA_Screen);
   391         XPixmapFormatValues *pix_format;
   377 		pix_format = XListPixmapFormats(DGA_Display, &num_formats);
   392         int i, num_formats;
   378 		if ( pix_format == NULL ) {
   393 
   379 			SDL_SetError("Couldn't determine screen formats");
   394         vformat->BitsPerPixel = DefaultDepth(DGA_Display, DGA_Screen);
   380 			XCloseDisplay(DGA_Display);
   395         pix_format = XListPixmapFormats(DGA_Display, &num_formats);
   381 			return(-1);
   396         if (pix_format == NULL) {
   382 		}
   397             SDL_SetError("Couldn't determine screen formats");
   383 		for ( i=0; i<num_formats; ++i ) {
   398             XCloseDisplay(DGA_Display);
   384 			if ( vformat->BitsPerPixel == pix_format[i].depth )
   399             return (-1);
   385 				break;
   400         }
   386 		}
   401         for (i = 0; i < num_formats; ++i) {
   387 		if ( i != num_formats )
   402             if (vformat->BitsPerPixel == pix_format[i].depth)
   388 			vformat->BitsPerPixel = pix_format[i].bits_per_pixel;
   403                 break;
   389 		XFree((char *)pix_format);
   404         }
   390 	}
   405         if (i != num_formats)
   391 	if ( vformat->BitsPerPixel > 8 ) {
   406             vformat->BitsPerPixel = pix_format[i].bits_per_pixel;
   392 		vformat->Rmask = visual->red_mask;
   407         XFree((char *) pix_format);
   393 		vformat->Gmask = visual->green_mask;
   408     }
   394 		vformat->Bmask = visual->blue_mask;
   409     if (vformat->BitsPerPixel > 8) {
   395 	}
   410         vformat->Rmask = visual->red_mask;
   396 
   411         vformat->Gmask = visual->green_mask;
   397 	/* Open access to the framebuffer */
   412         vformat->Bmask = visual->blue_mask;
   398 	if ( ! SDL_NAME(XDGAOpenFramebuffer)(DGA_Display, DGA_Screen) ) {
   413     }
   399 		SDL_SetError("Unable to map the video memory");
   414 
   400 		XCloseDisplay(DGA_Display);
   415     /* Open access to the framebuffer */
   401 		return(-1);
   416     if (!SDL_NAME(XDGAOpenFramebuffer) (DGA_Display, DGA_Screen)) {
   402 	}
   417         SDL_SetError("Unable to map the video memory");
   403 
   418         XCloseDisplay(DGA_Display);
   404 	/* Save DPMS and screensaver settings */
   419         return (-1);
   405 	X11_SaveScreenSaver(DGA_Display, &screensaver_timeout, &dpms_enabled);
   420     }
   406 	X11_DisableScreenSaver(DGA_Display);
   421 
   407 
   422     /* Save DPMS and screensaver settings */
   408 	/* Query for the list of available video modes */
   423     X11_SaveScreenSaver(DGA_Display, &screensaver_timeout, &dpms_enabled);
   409 	modes = SDL_NAME(XDGAQueryModes)(DGA_Display, DGA_Screen, &num_modes);
   424     X11_DisableScreenSaver(DGA_Display);
   410 	SDL_qsort(modes, num_modes, sizeof *modes, cmpmodes);
   425 
   411 	for ( i=0; i<num_modes; ++i ) {
   426     /* Query for the list of available video modes */
   412 		if ( ((modes[i].visualClass == PseudoColor) ||
   427     modes = SDL_NAME(XDGAQueryModes) (DGA_Display, DGA_Screen, &num_modes);
   413 		      (modes[i].visualClass == DirectColor) ||
   428     SDL_qsort(modes, num_modes, sizeof *modes, cmpmodes);
   414 		      (modes[i].visualClass == TrueColor)) && 
   429     for (i = 0; i < num_modes; ++i) {
   415 		     !(modes[i].flags & (XDGAInterlaced|XDGADoublescan)) ) {
   430         if (((modes[i].visualClass == PseudoColor) ||
       
   431              (modes[i].visualClass == DirectColor) ||
       
   432              (modes[i].visualClass == TrueColor)) &&
       
   433             !(modes[i].flags & (XDGAInterlaced | XDGADoublescan))) {
   416 #ifdef DGA_DEBUG
   434 #ifdef DGA_DEBUG
   417 			PrintMode(&modes[i]);
   435             PrintMode(&modes[i]);
   418 #endif
   436 #endif
   419 			DGA_AddMode(this, modes[i].bitsPerPixel,
   437             DGA_AddMode(this, modes[i].bitsPerPixel,
   420 			            modes[i].viewportWidth,
   438                         modes[i].viewportWidth, modes[i].viewportHeight);
   421 			            modes[i].viewportHeight);
   439         }
   422 		}
   440     }
   423 	}
   441     UpdateHWInfo(this, modes);
   424 	UpdateHWInfo(this, modes);
   442     XFree(modes);
   425 	XFree(modes);
   443 
   426 
   444     /* Create the hardware surface lock mutex */
   427 	/* Create the hardware surface lock mutex */
   445     hw_lock = SDL_CreateMutex();
   428 	hw_lock = SDL_CreateMutex();
   446     if (hw_lock == NULL) {
   429 	if ( hw_lock == NULL ) {
   447         SDL_SetError("Unable to create lock mutex");
   430 		SDL_SetError("Unable to create lock mutex");
   448         DGA_VideoQuit(this);
   431 		DGA_VideoQuit(this);
   449         return (-1);
   432 		return(-1);
   450     }
   433 	}
       
   434 
       
   435 #ifdef LOCK_DGA_DISPLAY
   451 #ifdef LOCK_DGA_DISPLAY
   436 	/* Create the event lock so we're thread-safe.. :-/ */
   452     /* Create the event lock so we're thread-safe.. :-/ */
   437 	event_lock = SDL_CreateMutex();
   453     event_lock = SDL_CreateMutex();
   438 #endif /* LOCK_DGA_DISPLAY */
   454 #endif /* LOCK_DGA_DISPLAY */
   439 
   455 
   440 	/* We're done! */
   456     /* We're done! */
   441 	return(0);
   457     return (0);
   442 }
   458 }
   443 
   459 
   444 SDL_Rect **DGA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
   460 SDL_Rect **
   445 {
   461 DGA_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags)
   446 	return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]);
   462 {
       
   463     return (SDL_modelist[((format->BitsPerPixel + 7) / 8) - 1]);
   447 }
   464 }
   448 
   465 
   449 /* Various screen update functions available */
   466 /* Various screen update functions available */
   450 static void DGA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
   467 static void DGA_DirectUpdate(_THIS, int numrects, SDL_Rect * rects);
   451 
   468 
   452 SDL_Surface *DGA_SetVideoMode(_THIS, SDL_Surface *current,
   469 SDL_Surface *
   453 				int width, int height, int bpp, Uint32 flags)
   470 DGA_SetVideoMode(_THIS, SDL_Surface * current,
   454 {
   471                  int width, int height, int bpp, Uint32 flags)
   455 	SDL_NAME(XDGAMode) *modes;
   472 {
   456 	int i, num_modes;
   473     SDL_NAME(XDGAMode) * modes;
   457 	SDL_NAME(XDGADevice) *mode;
   474     int i, num_modes;
   458 	int screen_len;
   475     SDL_NAME(XDGADevice) * mode;
   459 	Uint8 *surfaces_mem;
   476     int screen_len;
   460 	int surfaces_len;
   477     Uint8 *surfaces_mem;
   461 
   478     int surfaces_len;
   462 	/* Free any previous colormap */
   479 
   463 	if ( DGA_colormap ) {
   480     /* Free any previous colormap */
   464 		XFreeColormap(DGA_Display, DGA_colormap);
   481     if (DGA_colormap) {
   465 		DGA_colormap = 0;
   482         XFreeColormap(DGA_Display, DGA_colormap);
   466 	}
   483         DGA_colormap = 0;
   467 
   484     }
   468 	/* Search for a matching video mode */
   485 
   469 	modes = SDL_NAME(XDGAQueryModes)(DGA_Display, DGA_Screen, &num_modes);
   486     /* Search for a matching video mode */
   470 	SDL_qsort(modes, num_modes, sizeof *modes, cmpmodes);
   487     modes = SDL_NAME(XDGAQueryModes) (DGA_Display, DGA_Screen, &num_modes);
   471 	for ( i=0; i<num_modes; ++i ) {
   488     SDL_qsort(modes, num_modes, sizeof *modes, cmpmodes);
   472 		int depth;
   489     for (i = 0; i < num_modes; ++i) {
   473 
   490         int depth;
   474 		depth = modes[i].depth;
   491 
   475 		if ( depth == 24 ) { /* Distinguish between 24 and 32 bpp */
   492         depth = modes[i].depth;
   476 			depth = modes[i].bitsPerPixel;
   493         if (depth == 24) {      /* Distinguish between 24 and 32 bpp */
   477 		}
   494             depth = modes[i].bitsPerPixel;
   478 		if ( (depth == bpp) &&
   495         }
   479 		     (modes[i].viewportWidth == width) &&
   496         if ((depth == bpp) &&
   480 		     (modes[i].viewportHeight == height) &&
   497             (modes[i].viewportWidth == width) &&
   481 		     ((modes[i].visualClass == PseudoColor) ||
   498             (modes[i].viewportHeight == height) &&
   482 		      (modes[i].visualClass == DirectColor) ||
   499             ((modes[i].visualClass == PseudoColor) ||
   483 		      (modes[i].visualClass == TrueColor)) &&
   500              (modes[i].visualClass == DirectColor) ||
   484 		     !(modes[i].flags & (XDGAInterlaced|XDGADoublescan)) ) {
   501              (modes[i].visualClass == TrueColor)) &&
   485 			break;
   502             !(modes[i].flags & (XDGAInterlaced | XDGADoublescan))) {
   486 		}
   503             break;
   487 	}
   504         }
   488 	if ( i == num_modes ) {
   505     }
   489 		SDL_SetError("No matching video mode found");
   506     if (i == num_modes) {
   490 		return(NULL);
   507         SDL_SetError("No matching video mode found");
   491 	}
   508         return (NULL);
       
   509     }
   492 #ifdef DGA_DEBUG
   510 #ifdef DGA_DEBUG
   493 	PrintMode(&modes[i]);
   511     PrintMode(&modes[i]);
   494 #endif
   512 #endif
   495 
   513 
   496 	/* Set the video mode */
   514     /* Set the video mode */
   497 	mode = SDL_NAME(XDGASetMode)(DGA_Display, DGA_Screen, modes[i].num);
   515     mode = SDL_NAME(XDGASetMode) (DGA_Display, DGA_Screen, modes[i].num);
   498 	XFree(modes);
   516     XFree(modes);
   499 	if ( mode == NULL ) {
   517     if (mode == NULL) {
   500 		SDL_SetError("Unable to switch to requested mode");
   518         SDL_SetError("Unable to switch to requested mode");
   501 		return(NULL);
   519         return (NULL);
   502 	}
   520     }
   503 	DGA_visualClass = mode->mode.visualClass;
   521     DGA_visualClass = mode->mode.visualClass;
   504 	memory_base = (Uint8 *)mode->data;
   522     memory_base = (Uint8 *) mode->data;
   505 	memory_pitch = mode->mode.bytesPerScanline;
   523     memory_pitch = mode->mode.bytesPerScanline;
   506 
   524 
   507 	/* Set up the new mode framebuffer */
   525     /* Set up the new mode framebuffer */
   508 	current->flags = (SDL_FULLSCREEN|SDL_HWSURFACE);
   526     current->flags = (SDL_FULLSCREEN | SDL_HWSURFACE);
   509 	current->w = mode->mode.viewportWidth;
   527     current->w = mode->mode.viewportWidth;
   510 	current->h = mode->mode.viewportHeight;
   528     current->h = mode->mode.viewportHeight;
   511 	current->pitch = memory_pitch;
   529     current->pitch = memory_pitch;
   512 	current->pixels = memory_base;
   530     current->pixels = memory_base;
   513 	if ( ! SDL_ReallocFormat(current, mode->mode.bitsPerPixel,
   531     if (!SDL_ReallocFormat(current, mode->mode.bitsPerPixel,
   514 	                                  mode->mode.redMask,
   532                            mode->mode.redMask,
   515 	                                  mode->mode.greenMask,
   533                            mode->mode.greenMask, mode->mode.blueMask, 0)) {
   516 	                                  mode->mode.blueMask, 0) ) {
   534         return (NULL);
   517 		return(NULL);
   535     }
   518 	}
   536     screen_len = current->h * current->pitch;
   519 	screen_len = current->h*current->pitch;
   537 
   520 
   538     /* Create a colormap if necessary */
   521 	/* Create a colormap if necessary */
   539     if ((DGA_visualClass == PseudoColor) || (DGA_visualClass == DirectColor)) {
   522 	if ( (DGA_visualClass == PseudoColor) ||
   540         DGA_colormap =
   523              (DGA_visualClass == DirectColor) ) {
   541             SDL_NAME(XDGACreateColormap) (DGA_Display, DGA_Screen, mode,
   524 		DGA_colormap = SDL_NAME(XDGACreateColormap)(DGA_Display, DGA_Screen,
   542                                           AllocAll);
   525 							mode, AllocAll);
   543         if (DGA_visualClass == PseudoColor) {
   526 		if ( DGA_visualClass == PseudoColor ) {
   544             current->flags |= SDL_HWPALETTE;
   527 			current->flags |= SDL_HWPALETTE;
   545         } else {
   528 		} else {
   546             /* Initialize the colormap to the identity mapping */
   529 	    		/* Initialize the colormap to the identity mapping */
   547             SDL_GetGammaRamp(0, 0, 0);
   530 	    		SDL_GetGammaRamp(0, 0, 0);
   548             this->screen = current;
   531 	    		this->screen = current;
   549             DGA_SetGammaRamp(this, this->gamma);
   532 	    		DGA_SetGammaRamp(this, this->gamma);
   550             this->screen = NULL;
   533 			this->screen = NULL;
   551         }
   534 		}
   552     } else {
   535 	} else {
   553         DGA_colormap =
   536 		DGA_colormap = SDL_NAME(XDGACreateColormap)(DGA_Display, DGA_Screen,
   554             SDL_NAME(XDGACreateColormap) (DGA_Display, DGA_Screen, mode,
   537 							mode, AllocNone);
   555                                           AllocNone);
   538 	}
   556     }
   539 	SDL_NAME(XDGAInstallColormap)(DGA_Display, DGA_Screen, DGA_colormap);
   557     SDL_NAME(XDGAInstallColormap) (DGA_Display, DGA_Screen, DGA_colormap);
   540 
   558 
   541 	/* Update the hardware capabilities */
   559     /* Update the hardware capabilities */
   542 	UpdateHWInfo(this, &mode->mode);
   560     UpdateHWInfo(this, &mode->mode);
   543 
   561 
   544 	/* Set up the information for hardware surfaces */
   562     /* Set up the information for hardware surfaces */
   545 	surfaces_mem = (Uint8 *)current->pixels + screen_len;
   563     surfaces_mem = (Uint8 *) current->pixels + screen_len;
   546 	surfaces_len = (mode->mode.imageHeight*current->pitch - screen_len);
   564     surfaces_len = (mode->mode.imageHeight * current->pitch - screen_len);
   547 
   565 
   548 	/* Update for double-buffering, if we can */
   566     /* Update for double-buffering, if we can */
   549 	SDL_NAME(XDGASetViewport)(DGA_Display, DGA_Screen, 0, 0, XDGAFlipRetrace);
   567     SDL_NAME(XDGASetViewport) (DGA_Display, DGA_Screen, 0, 0,
   550 	if ( flags & SDL_DOUBLEBUF ) {
   568                                XDGAFlipRetrace);
   551 		if ( mode->mode.imageHeight >= (current->h*2) ) {
   569     if (flags & SDL_DOUBLEBUF) {
   552 			current->flags |= SDL_DOUBLEBUF;
   570         if (mode->mode.imageHeight >= (current->h * 2)) {
   553 			flip_page = 0;
   571             current->flags |= SDL_DOUBLEBUF;
   554 			flip_yoffset[0] = 0;
   572             flip_page = 0;
   555 			flip_yoffset[1] = current->h;
   573             flip_yoffset[0] = 0;
   556 			flip_address[0] = memory_base;
   574             flip_yoffset[1] = current->h;
   557 			flip_address[1] = memory_base+screen_len;
   575             flip_address[0] = memory_base;
   558 			surfaces_mem += screen_len;
   576             flip_address[1] = memory_base + screen_len;
   559 			surfaces_len -= screen_len;
   577             surfaces_mem += screen_len;
   560 		}
   578             surfaces_len -= screen_len;
   561 	}
   579         }
   562 
   580     }
   563 	/* Allocate memory tracking for hardware surfaces */
   581 
   564 	DGA_FreeHWSurfaces(this);
   582     /* Allocate memory tracking for hardware surfaces */
   565 	if ( surfaces_len < 0 ) {
   583     DGA_FreeHWSurfaces(this);
   566 		surfaces_len = 0;
   584     if (surfaces_len < 0) {
   567 	}
   585         surfaces_len = 0;
   568 	DGA_InitHWSurfaces(this, current, surfaces_mem, surfaces_len);
   586     }
   569 
   587     DGA_InitHWSurfaces(this, current, surfaces_mem, surfaces_len);
   570 	/* Expose the back buffer as surface memory */
   588 
   571 	if ( current->flags & SDL_DOUBLEBUF ) {
   589     /* Expose the back buffer as surface memory */
   572 		this->screen = current;
   590     if (current->flags & SDL_DOUBLEBUF) {
   573 		DGA_FlipHWSurface(this, current);
   591         this->screen = current;
   574 		this->screen = NULL;
   592         DGA_FlipHWSurface(this, current);
   575 	}
   593         this->screen = NULL;
   576 
   594     }
   577 	/* Set the update rectangle function */
   595 
   578 	this->UpdateRects = DGA_DirectUpdate;
   596     /* Set the update rectangle function */
   579 
   597     this->UpdateRects = DGA_DirectUpdate;
   580 	/* Enable mouse and keyboard support */
   598 
   581 	{ long input_mask;
   599     /* Enable mouse and keyboard support */
   582 	  input_mask = (KeyPressMask | KeyReleaseMask);
   600     {
   583 	  input_mask |= (ButtonPressMask | ButtonReleaseMask);
   601         long input_mask;
   584 	  input_mask |= PointerMotionMask;
   602         input_mask = (KeyPressMask | KeyReleaseMask);
   585 	  SDL_NAME(XDGASelectInput)(DGA_Display, DGA_Screen, input_mask);
   603         input_mask |= (ButtonPressMask | ButtonReleaseMask);
   586 	}
   604         input_mask |= PointerMotionMask;
   587 
   605         SDL_NAME(XDGASelectInput) (DGA_Display, DGA_Screen, input_mask);
   588 	/* We're done */
   606     }
   589 	return(current);
   607 
       
   608     /* We're done */
       
   609     return (current);
   590 }
   610 }
   591 
   611 
   592 #ifdef DGA_DEBUG
   612 #ifdef DGA_DEBUG
   593 static void DGA_DumpHWSurfaces(_THIS)
   613 static void
   594 {
   614 DGA_DumpHWSurfaces(_THIS)
   595 	vidmem_bucket *bucket;
   615 {
   596 
   616     vidmem_bucket *bucket;
   597 	printf("Memory left: %d (%d total)\n", surfaces_memleft, surfaces_memtotal);
   617 
   598 	printf("\n");
   618     printf("Memory left: %d (%d total)\n", surfaces_memleft,
   599 	printf("         Base  Size\n");
   619            surfaces_memtotal);
   600 	for ( bucket=&surfaces; bucket; bucket=bucket->next ) {
   620     printf("\n");
   601 		printf("Bucket:  %p, %d (%s)\n", bucket->base, bucket->size, bucket->used ? "used" : "free");
   621     printf("         Base  Size\n");
   602 		if ( bucket->prev ) {
   622     for (bucket = &surfaces; bucket; bucket = bucket->next) {
   603 			if ( bucket->base != bucket->prev->base+bucket->prev->size ) {
   623         printf("Bucket:  %p, %d (%s)\n", bucket->base, bucket->size,
   604 				printf("Warning, corrupt bucket list! (prev)\n");
   624                bucket->used ? "used" : "free");
   605 			}
   625         if (bucket->prev) {
   606 		} else {
   626             if (bucket->base != bucket->prev->base + bucket->prev->size) {
   607 			if ( bucket != &surfaces ) {
   627                 printf("Warning, corrupt bucket list! (prev)\n");
   608 				printf("Warning, corrupt bucket list! (!prev)\n");
   628             }
   609 			}
   629         } else {
   610 		}
   630             if (bucket != &surfaces) {
   611 		if ( bucket->next ) {
   631                 printf("Warning, corrupt bucket list! (!prev)\n");
   612 			if ( bucket->next->base != bucket->base+bucket->size ) {
   632             }
   613 				printf("Warning, corrupt bucket list! (next)\n");
   633         }
   614 			}
   634         if (bucket->next) {
   615 		}
   635             if (bucket->next->base != bucket->base + bucket->size) {
   616 	}
   636                 printf("Warning, corrupt bucket list! (next)\n");
   617 	printf("\n");
   637             }
       
   638         }
       
   639     }
       
   640     printf("\n");
   618 }
   641 }
   619 #endif
   642 #endif
   620 
   643 
   621 static int DGA_InitHWSurfaces(_THIS, SDL_Surface *screen, Uint8 *base, int size)
   644 static int
   622 {
   645 DGA_InitHWSurfaces(_THIS, SDL_Surface * screen, Uint8 * base, int size)
   623 	vidmem_bucket *bucket;
   646 {
   624 
   647     vidmem_bucket *bucket;
   625 	surfaces_memtotal = size;
   648 
   626 	surfaces_memleft = size;
   649     surfaces_memtotal = size;
   627 
   650     surfaces_memleft = size;
   628 	if ( surfaces_memleft > 0 ) {
   651 
   629 		bucket = (vidmem_bucket *)SDL_malloc(sizeof(*bucket));
   652     if (surfaces_memleft > 0) {
   630 		if ( bucket == NULL ) {
   653         bucket = (vidmem_bucket *) SDL_malloc(sizeof(*bucket));
   631 			SDL_OutOfMemory();
   654         if (bucket == NULL) {
   632 			return(-1);
   655             SDL_OutOfMemory();
   633 		}
   656             return (-1);
   634 		bucket->prev = &surfaces;
   657         }
   635 		bucket->used = 0;
   658         bucket->prev = &surfaces;
   636 		bucket->dirty = 0;
   659         bucket->used = 0;
   637 		bucket->base = base;
   660         bucket->dirty = 0;
   638 		bucket->size = size;
   661         bucket->base = base;
   639 		bucket->next = NULL;
   662         bucket->size = size;
   640 	} else {
   663         bucket->next = NULL;
   641 		bucket = NULL;
   664     } else {
   642 	}
   665         bucket = NULL;
   643 
   666     }
   644 	surfaces.prev = NULL;
   667 
   645 	surfaces.used = 1;
   668     surfaces.prev = NULL;
   646 	surfaces.dirty = 0;
   669     surfaces.used = 1;
   647 	surfaces.base = screen->pixels;
   670     surfaces.dirty = 0;
   648 	surfaces.size = (unsigned int)((long)base - (long)surfaces.base);
   671     surfaces.base = screen->pixels;
   649 	surfaces.next = bucket;
   672     surfaces.size = (unsigned int) ((long) base - (long) surfaces.base);
   650 	screen->hwdata = (struct private_hwdata *)&surfaces;
   673     surfaces.next = bucket;
   651 	return(0);
   674     screen->hwdata = (struct private_hwdata *) &surfaces;
   652 }
   675     return (0);
   653 static void DGA_FreeHWSurfaces(_THIS)
   676 }
   654 {
   677 static void
   655 	vidmem_bucket *bucket, *freeable;
   678 DGA_FreeHWSurfaces(_THIS)
   656 
   679 {
   657 	bucket = surfaces.next;
   680     vidmem_bucket *bucket, *freeable;
   658 	while ( bucket ) {
   681 
   659 		freeable = bucket;
   682     bucket = surfaces.next;
   660 		bucket = bucket->next;
   683     while (bucket) {
   661 		SDL_free(freeable);
   684         freeable = bucket;
   662 	}
   685         bucket = bucket->next;
   663 	surfaces.next = NULL;
   686         SDL_free(freeable);
   664 }
   687     }
   665 
   688     surfaces.next = NULL;
   666 static __inline__ void DGA_AddBusySurface(SDL_Surface *surface)
   689 }
   667 {
   690 
   668 	((vidmem_bucket *)surface->hwdata)->dirty = 1;
   691 static __inline__ void
   669 }
   692 DGA_AddBusySurface(SDL_Surface * surface)
   670 
   693 {
   671 static __inline__ int DGA_IsSurfaceBusy(SDL_Surface *surface)
   694     ((vidmem_bucket *) surface->hwdata)->dirty = 1;
   672 {
   695 }
   673 	return ((vidmem_bucket *)surface->hwdata)->dirty;
   696 
   674 }
   697 static __inline__ int
   675 
   698 DGA_IsSurfaceBusy(SDL_Surface * surface)
   676 static __inline__ void DGA_WaitBusySurfaces(_THIS)
   699 {
   677 {
   700     return ((vidmem_bucket *) surface->hwdata)->dirty;
   678 	vidmem_bucket *bucket;
   701 }
   679 
   702 
   680 	/* Wait for graphic operations to complete */
   703 static __inline__ void
   681 	SDL_NAME(XDGASync)(DGA_Display, DGA_Screen);
   704 DGA_WaitBusySurfaces(_THIS)
   682 
   705 {
   683 	/* Clear all surface dirty bits */
   706     vidmem_bucket *bucket;
   684 	for ( bucket=&surfaces; bucket; bucket=bucket->next ) {
   707 
   685 		bucket->dirty = 0;
   708     /* Wait for graphic operations to complete */
   686 	}
   709     SDL_NAME(XDGASync) (DGA_Display, DGA_Screen);
   687 }
   710 
   688 
   711     /* Clear all surface dirty bits */
   689 static int DGA_AllocHWSurface(_THIS, SDL_Surface *surface)
   712     for (bucket = &surfaces; bucket; bucket = bucket->next) {
   690 {
   713         bucket->dirty = 0;
   691 	vidmem_bucket *bucket;
   714     }
   692 	int size;
   715 }
   693 	int extra;
   716 
   694 	int retval = 0;
   717 static int
       
   718 DGA_AllocHWSurface(_THIS, SDL_Surface * surface)
       
   719 {
       
   720     vidmem_bucket *bucket;
       
   721     int size;
       
   722     int extra;
       
   723     int retval = 0;
   695 
   724 
   696 /* Temporarily, we only allow surfaces the same width as display.
   725 /* Temporarily, we only allow surfaces the same width as display.
   697    Some blitters require the pitch between two hardware surfaces
   726    Some blitters require the pitch between two hardware surfaces
   698    to be the same.  Others have interesting alignment restrictions.
   727    to be the same.  Others have interesting alignment restrictions.
   699 */
   728 */
   700 if ( surface->pitch > SDL_VideoSurface->pitch ) {
   729     if (surface->pitch > SDL_VideoSurface->pitch) {
   701 	SDL_SetError("Surface requested wider than screen");
   730         SDL_SetError("Surface requested wider than screen");
   702 	return(-1);
   731         return (-1);
   703 }
   732     }
   704 surface->pitch = SDL_VideoSurface->pitch;
   733     surface->pitch = SDL_VideoSurface->pitch;
   705 	size = surface->h * surface->pitch;
   734     size = surface->h * surface->pitch;
   706 #ifdef DGA_DEBUG
   735 #ifdef DGA_DEBUG
   707 	fprintf(stderr, "Allocating bucket of %d bytes\n", size);
   736     fprintf(stderr, "Allocating bucket of %d bytes\n", size);
   708 #endif
   737 #endif
   709 	LOCK_DISPLAY();
   738     LOCK_DISPLAY();
   710 
   739 
   711 	/* Quick check for available mem */
   740     /* Quick check for available mem */
   712 	if ( size > surfaces_memleft ) {
   741     if (size > surfaces_memleft) {
   713 		SDL_SetError("Not enough video memory");
   742         SDL_SetError("Not enough video memory");
   714 		retval = -1;
   743         retval = -1;
   715 		goto done;
   744         goto done;
   716 	}
   745     }
   717 
   746 
   718 	/* Search for an empty bucket big enough */
   747     /* Search for an empty bucket big enough */
   719 	for ( bucket=&surfaces; bucket; bucket=bucket->next ) {
   748     for (bucket = &surfaces; bucket; bucket = bucket->next) {
   720 		if ( ! bucket->used && (size <= bucket->size) ) {
   749         if (!bucket->used && (size <= bucket->size)) {
   721 			break;
   750             break;
   722 		}
   751         }
   723 	}
   752     }
   724 	if ( bucket == NULL ) {
   753     if (bucket == NULL) {
   725 		SDL_SetError("Video memory too fragmented");
   754         SDL_SetError("Video memory too fragmented");
   726 		retval = -1;
   755         retval = -1;
   727 		goto done;
   756         goto done;
   728 	}
   757     }
   729 
   758 
   730 	/* Create a new bucket for left-over memory */
   759     /* Create a new bucket for left-over memory */
   731 	extra = (bucket->size - size);
   760     extra = (bucket->size - size);
   732 	if ( extra ) {
   761     if (extra) {
   733 		vidmem_bucket *newbucket;
   762         vidmem_bucket *newbucket;
   734 
   763 
   735 #ifdef DGA_DEBUG
   764 #ifdef DGA_DEBUG
   736 	fprintf(stderr, "Adding new free bucket of %d bytes\n", extra);
   765         fprintf(stderr, "Adding new free bucket of %d bytes\n", extra);
   737 #endif
   766 #endif
   738 		newbucket = (vidmem_bucket *)SDL_malloc(sizeof(*newbucket));
   767         newbucket = (vidmem_bucket *) SDL_malloc(sizeof(*newbucket));
   739 		if ( newbucket == NULL ) {
   768         if (newbucket == NULL) {
   740 			SDL_OutOfMemory();
   769             SDL_OutOfMemory();
   741 			retval = -1;
   770             retval = -1;
   742 			goto done;
   771             goto done;
   743 		}
   772         }
   744 		newbucket->prev = bucket;
   773         newbucket->prev = bucket;
   745 		newbucket->used = 0;
   774         newbucket->used = 0;
   746 		newbucket->base = bucket->base+size;
   775         newbucket->base = bucket->base + size;
   747 		newbucket->size = extra;
   776         newbucket->size = extra;
   748 		newbucket->next = bucket->next;
   777         newbucket->next = bucket->next;
   749 		if ( bucket->next ) {
   778         if (bucket->next) {
   750 			bucket->next->prev = newbucket;
   779             bucket->next->prev = newbucket;
   751 		}
   780         }
   752 		bucket->next = newbucket;
   781         bucket->next = newbucket;
   753 	}
   782     }
   754 
   783 
   755 	/* Set the current bucket values and return it! */
   784     /* Set the current bucket values and return it! */
   756 	bucket->used = 1;
   785     bucket->used = 1;
   757 	bucket->size = size;
   786     bucket->size = size;
   758 	bucket->dirty = 0;
   787     bucket->dirty = 0;
   759 #ifdef DGA_DEBUG
   788 #ifdef DGA_DEBUG
   760 	fprintf(stderr, "Allocated %d bytes at %p\n", bucket->size, bucket->base);
   789     fprintf(stderr, "Allocated %d bytes at %p\n", bucket->size, bucket->base);
   761 #endif
   790 #endif
   762 	surfaces_memleft -= size;
   791     surfaces_memleft -= size;
   763 	surface->flags |= SDL_HWSURFACE;
   792     surface->flags |= SDL_HWSURFACE;
   764 	surface->pixels = bucket->base;
   793     surface->pixels = bucket->base;
   765 	surface->hwdata = (struct private_hwdata *)bucket;
   794     surface->hwdata = (struct private_hwdata *) bucket;
   766 done:
   795   done:
   767 	UNLOCK_DISPLAY();
   796     UNLOCK_DISPLAY();
   768 	return(retval);
   797     return (retval);
   769 }
   798 }
   770 static void DGA_FreeHWSurface(_THIS, SDL_Surface *surface)
   799 static void
   771 {
   800 DGA_FreeHWSurface(_THIS, SDL_Surface * surface)
   772 	vidmem_bucket *bucket, *freeable;
   801 {
   773 
   802     vidmem_bucket *bucket, *freeable;
   774 	/* Wait for any pending operations involving this surface */
   803 
   775 	if ( DGA_IsSurfaceBusy(surface) ) {
   804     /* Wait for any pending operations involving this surface */
   776 		LOCK_DISPLAY();
   805     if (DGA_IsSurfaceBusy(surface)) {
   777 		DGA_WaitBusySurfaces(this);
   806         LOCK_DISPLAY();
   778 		UNLOCK_DISPLAY();
   807         DGA_WaitBusySurfaces(this);
   779 	}
   808         UNLOCK_DISPLAY();
   780 
   809     }
   781 	/* Look for the bucket in the current list */
   810 
   782 	for ( bucket=&surfaces; bucket; bucket=bucket->next ) {
   811     /* Look for the bucket in the current list */
   783 		if ( bucket == (vidmem_bucket *)surface->hwdata ) {
   812     for (bucket = &surfaces; bucket; bucket = bucket->next) {
   784 			break;
   813         if (bucket == (vidmem_bucket *) surface->hwdata) {
   785 		}
   814             break;
   786 	}
   815         }
   787 	if ( bucket && bucket->used ) {
   816     }
   788 		/* Add the memory back to the total */
   817     if (bucket && bucket->used) {
       
   818         /* Add the memory back to the total */
   789 #ifdef DGA_DEBUG
   819 #ifdef DGA_DEBUG
   790 	printf("Freeing bucket of %d bytes\n", bucket->size);
   820         printf("Freeing bucket of %d bytes\n", bucket->size);
   791 #endif
   821 #endif
   792 		surfaces_memleft += bucket->size;
   822         surfaces_memleft += bucket->size;
   793 
   823 
   794 		/* Can we merge the space with surrounding buckets? */
   824         /* Can we merge the space with surrounding buckets? */
   795 		bucket->used = 0;
   825         bucket->used = 0;
   796 		if ( bucket->next && ! bucket->next->used ) {
   826         if (bucket->next && !bucket->next->used) {
   797 #ifdef DGA_DEBUG
   827 #ifdef DGA_DEBUG
   798 	printf("Merging with next bucket, for %d total bytes\n", bucket->size+bucket->next->size);
   828             printf("Merging with next bucket, for %d total bytes\n",
       
   829                    bucket->size + bucket->next->size);
   799 #endif
   830 #endif
   800 			freeable = bucket->next;
   831             freeable = bucket->next;
   801 			bucket->size += bucket->next->size;
   832             bucket->size += bucket->next->size;
   802 			bucket->next = bucket->next->next;
   833             bucket->next = bucket->next->next;
   803 			if ( bucket->next ) {
   834             if (bucket->next) {
   804 				bucket->next->prev = bucket;
   835                 bucket->next->prev = bucket;
   805 			}
   836             }
   806 			SDL_free(freeable);
   837             SDL_free(freeable);
   807 		}
   838         }
   808 		if ( bucket->prev && ! bucket->prev->used ) {
   839         if (bucket->prev && !bucket->prev->used) {
   809 #ifdef DGA_DEBUG
   840 #ifdef DGA_DEBUG
   810 	printf("Merging with previous bucket, for %d total bytes\n", bucket->prev->size+bucket->size);
   841             printf("Merging with previous bucket, for %d total bytes\n",
       
   842                    bucket->prev->size + bucket->size);
   811 #endif
   843 #endif
   812 			freeable = bucket;
   844             freeable = bucket;
   813 			bucket->prev->size += bucket->size;
   845             bucket->prev->size += bucket->size;
   814 			bucket->prev->next = bucket->next;
   846             bucket->prev->next = bucket->next;
   815 			if ( bucket->next ) {
   847             if (bucket->next) {
   816 				bucket->next->prev = bucket->prev;
   848                 bucket->next->prev = bucket->prev;
   817 			}
   849             }
   818 			SDL_free(freeable);
   850             SDL_free(freeable);
   819 		}
   851         }
   820 	}
   852     }
   821 	surface->pixels = NULL;
   853     surface->pixels = NULL;
   822 	surface->hwdata = NULL;
   854     surface->hwdata = NULL;
   823 }
   855 }
   824 
   856 
   825 static __inline__ void DGA_dst_to_xy(_THIS, SDL_Surface *dst, int *x, int *y)
   857 static __inline__ void
   826 {
   858 DGA_dst_to_xy(_THIS, SDL_Surface * dst, int *x, int *y)
   827 	*x = (long)((Uint8 *)dst->pixels - memory_base)%memory_pitch;
   859 {
   828 	*y = (long)((Uint8 *)dst->pixels - memory_base)/memory_pitch;
   860     *x = (long) ((Uint8 *) dst->pixels - memory_base) % memory_pitch;
   829 }
   861     *y = (long) ((Uint8 *) dst->pixels - memory_base) / memory_pitch;
   830 
   862 }
   831 static int DGA_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color)
   863 
   832 {
   864 static int
   833 	int x, y;
   865 DGA_FillHWRect(_THIS, SDL_Surface * dst, SDL_Rect * rect, Uint32 color)
   834 	unsigned int w, h;
   866 {
   835 
   867     int x, y;
   836 	/* Don't fill the visible part of the screen, wait until flipped */
   868     unsigned int w, h;
   837 	LOCK_DISPLAY();
   869 
   838 	if ( was_flipped && (dst == this->screen) ) {
   870     /* Don't fill the visible part of the screen, wait until flipped */
   839 		while ( SDL_NAME(XDGAGetViewportStatus)(DGA_Display, DGA_Screen) )
   871     LOCK_DISPLAY();
   840 			/* Keep waiting for the hardware ... */ ;
   872     if (was_flipped && (dst == this->screen)) {
   841 		was_flipped = 0;
   873         while (SDL_NAME(XDGAGetViewportStatus) (DGA_Display, DGA_Screen))
   842 	}
   874             /* Keep waiting for the hardware ... */ ;
   843 	DGA_dst_to_xy(this, dst, &x, &y);
   875         was_flipped = 0;
   844 	x += rect->x;
   876     }
   845 	y += rect->y;
   877     DGA_dst_to_xy(this, dst, &x, &y);
   846 	w = rect->w;
   878     x += rect->x;
   847 	h = rect->h;
   879     y += rect->y;
       
   880     w = rect->w;
       
   881     h = rect->h;
   848 #if 0
   882 #if 0
   849   printf("Hardware accelerated rectangle fill: %dx%d at %d,%d\n", w, h, x, y);
   883     printf("Hardware accelerated rectangle fill: %dx%d at %d,%d\n", w, h, x,
       
   884            y);
   850 #endif
   885 #endif
   851 	SDL_NAME(XDGAFillRectangle)(DGA_Display, DGA_Screen, x, y, w, h, color);
   886     SDL_NAME(XDGAFillRectangle) (DGA_Display, DGA_Screen, x, y, w, h, color);
   852 	if ( !(this->screen->flags & SDL_DOUBLEBUF) ) {
   887     if (!(this->screen->flags & SDL_DOUBLEBUF)) {
   853 		XFlush(DGA_Display);
   888         XFlush(DGA_Display);
   854 	}
   889     }
   855 	DGA_AddBusySurface(dst);
   890     DGA_AddBusySurface(dst);
   856 	UNLOCK_DISPLAY();
   891     UNLOCK_DISPLAY();
   857 	return(0);
   892     return (0);
   858 }
   893 }
   859 
   894 
   860 static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
   895 static int
   861                        SDL_Surface *dst, SDL_Rect *dstrect)
   896 HWAccelBlit(SDL_Surface * src, SDL_Rect * srcrect,
   862 {
   897             SDL_Surface * dst, SDL_Rect * dstrect)
   863 	SDL_VideoDevice *this;
   898 {
   864 	int srcx, srcy;
   899     SDL_VideoDevice *this;
   865 	int dstx, dsty;
   900     int srcx, srcy;
   866 	unsigned int w, h;
   901     int dstx, dsty;
   867 
   902     unsigned int w, h;
   868 	this = current_video;
   903 
   869 	/* Don't blit to the visible part of the screen, wait until flipped */
   904     this = current_video;
   870 	LOCK_DISPLAY();
   905     /* Don't blit to the visible part of the screen, wait until flipped */
   871 	if ( was_flipped && (dst == this->screen) ) {
   906     LOCK_DISPLAY();
   872 		while ( SDL_NAME(XDGAGetViewportStatus)(DGA_Display, DGA_Screen) )
   907     if (was_flipped && (dst == this->screen)) {
   873 			/* Keep waiting for the hardware ... */ ;
   908         while (SDL_NAME(XDGAGetViewportStatus) (DGA_Display, DGA_Screen))
   874 		was_flipped = 0;
   909             /* Keep waiting for the hardware ... */ ;
   875 	}
   910         was_flipped = 0;
   876 	DGA_dst_to_xy(this, src, &srcx, &srcy);
   911     }
   877 	srcx += srcrect->x;
   912     DGA_dst_to_xy(this, src, &srcx, &srcy);
   878 	srcy += srcrect->y;
   913     srcx += srcrect->x;
   879 	DGA_dst_to_xy(this, dst, &dstx, &dsty);
   914     srcy += srcrect->y;
   880 	dstx += dstrect->x;
   915     DGA_dst_to_xy(this, dst, &dstx, &dsty);
   881 	dsty += dstrect->y;
   916     dstx += dstrect->x;
   882 	w = srcrect->w;
   917     dsty += dstrect->y;
   883 	h = srcrect->h;
   918     w = srcrect->w;
       
   919     h = srcrect->h;
   884 #if 0
   920 #if 0
   885   printf("Blitting %dx%d from %d,%d to %d,%d\n", w, h, srcx, srcy, dstx, dsty);
   921     printf("Blitting %dx%d from %d,%d to %d,%d\n", w, h, srcx, srcy, dstx,
       
   922            dsty);
   886 #endif
   923 #endif
   887 	if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
   924     if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
   888 		SDL_NAME(XDGACopyTransparentArea)(DGA_Display, DGA_Screen,
   925         SDL_NAME(XDGACopyTransparentArea) (DGA_Display, DGA_Screen,
   889 			srcx, srcy, w, h, dstx, dsty, src->format->colorkey);
   926                                            srcx, srcy, w, h, dstx, dsty,
   890 	} else {
   927                                            src->format->colorkey);
   891 		SDL_NAME(XDGACopyArea)(DGA_Display, DGA_Screen,
   928     } else {
   892 			srcx, srcy, w, h, dstx, dsty);
   929         SDL_NAME(XDGACopyArea) (DGA_Display, DGA_Screen,
   893 	}
   930                                 srcx, srcy, w, h, dstx, dsty);
   894 	if ( !(this->screen->flags & SDL_DOUBLEBUF) ) {
   931     }
   895 		XFlush(DGA_Display);
   932     if (!(this->screen->flags & SDL_DOUBLEBUF)) {
   896 	}
   933         XFlush(DGA_Display);
   897 	DGA_AddBusySurface(src);
   934     }
   898 	DGA_AddBusySurface(dst);
   935     DGA_AddBusySurface(src);
   899 	UNLOCK_DISPLAY();
   936     DGA_AddBusySurface(dst);
   900 	return(0);
   937     UNLOCK_DISPLAY();
   901 }
   938     return (0);
   902 
   939 }
   903 static int DGA_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst)
   940 
   904 {
   941 static int
   905 	int accelerated;
   942 DGA_CheckHWBlit(_THIS, SDL_Surface * src, SDL_Surface * dst)
   906 
   943 {
   907 	/* Set initial acceleration on */
   944     int accelerated;
   908 	src->flags |= SDL_HWACCEL;
   945 
   909 
   946     /* Set initial acceleration on */
   910 	/* Set the surface attributes */
   947     src->flags |= SDL_HWACCEL;
   911 	if ( (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
   948 
   912 		if ( ! this->info.blit_hw_A ) {
   949     /* Set the surface attributes */
   913 			src->flags &= ~SDL_HWACCEL;
   950     if ((src->flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
   914 		}
   951         if (!this->info.blit_hw_A) {
   915 	}
   952             src->flags &= ~SDL_HWACCEL;
   916 	if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
   953         }
   917 		if ( ! this->info.blit_hw_CC ) {
   954     }
   918 			src->flags &= ~SDL_HWACCEL;
   955     if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
   919 		}
   956         if (!this->info.blit_hw_CC) {
   920 	}
   957             src->flags &= ~SDL_HWACCEL;
   921 
   958         }
   922 	/* Check to see if final surface blit is accelerated */
   959     }
   923 	accelerated = !!(src->flags & SDL_HWACCEL);
   960 
   924 	if ( accelerated ) {
   961     /* Check to see if final surface blit is accelerated */
   925 		src->map->hw_blit = HWAccelBlit;
   962     accelerated = !!(src->flags & SDL_HWACCEL);
   926 	}
   963     if (accelerated) {
   927 	return(accelerated);
   964         src->map->hw_blit = HWAccelBlit;
   928 }
   965     }
   929 
   966     return (accelerated);
   930 static __inline__ void DGA_WaitFlip(_THIS)
   967 }
   931 {
   968 
   932 	if ( was_flipped ) {
   969 static __inline__ void
   933 		while ( SDL_NAME(XDGAGetViewportStatus)(DGA_Display, DGA_Screen) )
   970 DGA_WaitFlip(_THIS)
   934 			/* Keep waiting for the hardware ... */ ;
   971 {
   935 		was_flipped = 0;
   972     if (was_flipped) {
   936 	}
   973         while (SDL_NAME(XDGAGetViewportStatus) (DGA_Display, DGA_Screen))
   937 }
   974             /* Keep waiting for the hardware ... */ ;
   938 
   975         was_flipped = 0;
   939 static int DGA_LockHWSurface(_THIS, SDL_Surface *surface)
   976     }
   940 {
   977 }
   941 	if ( surface == this->screen ) {
   978 
   942 		SDL_mutexP(hw_lock);
   979 static int
   943 		LOCK_DISPLAY();
   980 DGA_LockHWSurface(_THIS, SDL_Surface * surface)
   944 		if ( DGA_IsSurfaceBusy(surface) ) {
   981 {
   945 			DGA_WaitBusySurfaces(this);
   982     if (surface == this->screen) {
   946 		}
   983         SDL_mutexP(hw_lock);
   947 		DGA_WaitFlip(this);
   984         LOCK_DISPLAY();
   948 		UNLOCK_DISPLAY();
   985         if (DGA_IsSurfaceBusy(surface)) {
   949 	} else {
   986             DGA_WaitBusySurfaces(this);
   950 		if ( DGA_IsSurfaceBusy(surface) ) {
   987         }
   951 			LOCK_DISPLAY();
   988         DGA_WaitFlip(this);
   952 			DGA_WaitBusySurfaces(this);
   989         UNLOCK_DISPLAY();
   953 			UNLOCK_DISPLAY();
   990     } else {
   954 		}
   991         if (DGA_IsSurfaceBusy(surface)) {
   955 	}
   992             LOCK_DISPLAY();
   956 	return(0);
   993             DGA_WaitBusySurfaces(this);
   957 }
   994             UNLOCK_DISPLAY();
   958 static void DGA_UnlockHWSurface(_THIS, SDL_Surface *surface)
   995         }
   959 {
   996     }
   960 	if ( surface == this->screen ) {
   997     return (0);
   961 		SDL_mutexV(hw_lock);
   998 }
   962 	}
   999 static void
   963 }
  1000 DGA_UnlockHWSurface(_THIS, SDL_Surface * surface)
   964 
  1001 {
   965 static int DGA_FlipHWSurface(_THIS, SDL_Surface *surface)
  1002     if (surface == this->screen) {
   966 {
  1003         SDL_mutexV(hw_lock);
   967 	/* Wait for vertical retrace and then flip display */
  1004     }
   968 	LOCK_DISPLAY();
  1005 }
   969 	if ( DGA_IsSurfaceBusy(this->screen) ) {
  1006 
   970 		DGA_WaitBusySurfaces(this);
  1007 static int
   971 	}
  1008 DGA_FlipHWSurface(_THIS, SDL_Surface * surface)
   972 	DGA_WaitFlip(this);
  1009 {
   973 	SDL_NAME(XDGASetViewport)(DGA_Display, DGA_Screen,
  1010     /* Wait for vertical retrace and then flip display */
   974 	                0, flip_yoffset[flip_page], XDGAFlipRetrace);
  1011     LOCK_DISPLAY();
   975 	XFlush(DGA_Display);
  1012     if (DGA_IsSurfaceBusy(this->screen)) {
   976 	UNLOCK_DISPLAY();
  1013         DGA_WaitBusySurfaces(this);
   977 	was_flipped = 1;
  1014     }
   978 	flip_page = !flip_page;
  1015     DGA_WaitFlip(this);
   979 
  1016     SDL_NAME(XDGASetViewport) (DGA_Display, DGA_Screen,
   980 	surface->pixels = flip_address[flip_page];
  1017                                0, flip_yoffset[flip_page], XDGAFlipRetrace);
   981 	return(0);
  1018     XFlush(DGA_Display);
   982 }
  1019     UNLOCK_DISPLAY();
   983 
  1020     was_flipped = 1;
   984 static void DGA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
  1021     flip_page = !flip_page;
   985 {
  1022 
   986 	/* The application is already updating the visible video memory */
  1023     surface->pixels = flip_address[flip_page];
   987 	return;
  1024     return (0);
   988 }
  1025 }
   989 
  1026 
   990 static int DGA_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
  1027 static void
   991 {
  1028 DGA_DirectUpdate(_THIS, int numrects, SDL_Rect * rects)
   992         int i;
  1029 {
   993 	XColor  *xcmap;
  1030     /* The application is already updating the visible video memory */
   994 
  1031     return;
   995 	/* This happens on initialization */
  1032 }
   996 	if ( ! DGA_colormap ) {
  1033 
   997 		return(0);
  1034 static int
   998 	}
  1035 DGA_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color * colors)
   999 	xcmap = SDL_stack_alloc(XColor, ncolors);
  1036 {
  1000 	for ( i=0; i<ncolors; ++i ) {
  1037     int i;
  1001 		xcmap[i].pixel = firstcolor + i;
  1038     XColor *xcmap;
  1002 		xcmap[i].red   = (colors[i].r<<8)|colors[i].r;
  1039 
  1003 		xcmap[i].green = (colors[i].g<<8)|colors[i].g;
  1040     /* This happens on initialization */
  1004 		xcmap[i].blue  = (colors[i].b<<8)|colors[i].b;
  1041     if (!DGA_colormap) {
  1005 		xcmap[i].flags = (DoRed|DoGreen|DoBlue);
  1042         return (0);
  1006 	}
  1043     }
  1007 	LOCK_DISPLAY();
  1044     xcmap = SDL_stack_alloc(XColor, ncolors);
  1008 	XStoreColors(DGA_Display, DGA_colormap, xcmap, ncolors);
  1045     for (i = 0; i < ncolors; ++i) {
  1009 	XSync(DGA_Display, False);
  1046         xcmap[i].pixel = firstcolor + i;
  1010 	UNLOCK_DISPLAY();
  1047         xcmap[i].red = (colors[i].r << 8) | colors[i].r;
  1011 	SDL_stack_free(xcmap);
  1048         xcmap[i].green = (colors[i].g << 8) | colors[i].g;
  1012 
  1049         xcmap[i].blue = (colors[i].b << 8) | colors[i].b;
  1013 	/* That was easy. :) */
  1050         xcmap[i].flags = (DoRed | DoGreen | DoBlue);
  1014 	return(1);
  1051     }
  1015 }
  1052     LOCK_DISPLAY();
  1016 
  1053     XStoreColors(DGA_Display, DGA_colormap, xcmap, ncolors);
  1017 int DGA_SetGammaRamp(_THIS, Uint16 *ramp)
  1054     XSync(DGA_Display, False);
  1018 {
  1055     UNLOCK_DISPLAY();
  1019 	int i, ncolors;
  1056     SDL_stack_free(xcmap);
  1020 	XColor xcmap[256];
  1057 
  1021 
  1058     /* That was easy. :) */
  1022 	/* See if actually setting the gamma is supported */
  1059     return (1);
  1023 	if ( DGA_visualClass != DirectColor ) {
  1060 }
  1024 	    SDL_SetError("Gamma correction not supported on this visual");
  1061 
  1025 	    return(-1);
  1062 int
  1026 	}
  1063 DGA_SetGammaRamp(_THIS, Uint16 * ramp)
  1027 
  1064 {
  1028 	/* Calculate the appropriate palette for the given gamma ramp */
  1065     int i, ncolors;
  1029 	if ( this->screen->format->BitsPerPixel <= 16 ) {
  1066     XColor xcmap[256];
  1030 		ncolors = 64; /* Is this right? */
  1067 
  1031 	} else {
  1068     /* See if actually setting the gamma is supported */
  1032 		ncolors = 256;
  1069     if (DGA_visualClass != DirectColor) {
  1033 	}
  1070         SDL_SetError("Gamma correction not supported on this visual");
  1034 	for ( i=0; i<ncolors; ++i ) {
  1071         return (-1);
  1035 		Uint8 c = (256 * i / ncolors);
  1072     }
  1036 		xcmap[i].pixel = SDL_MapRGB(this->screen->format, c, c, c);
  1073 
  1037 		xcmap[i].red   = ramp[0*256+c];
  1074     /* Calculate the appropriate palette for the given gamma ramp */
  1038 		xcmap[i].green = ramp[1*256+c];
  1075     if (this->screen->format->BitsPerPixel <= 16) {
  1039 		xcmap[i].blue  = ramp[2*256+c];
  1076         ncolors = 64;           /* Is this right? */
  1040 		xcmap[i].flags = (DoRed|DoGreen|DoBlue);
  1077     } else {
  1041 	}
  1078         ncolors = 256;
  1042 	LOCK_DISPLAY();
  1079     }
  1043 	XStoreColors(DGA_Display, DGA_colormap, xcmap, ncolors);
  1080     for (i = 0; i < ncolors; ++i) {
  1044 	XSync(DGA_Display, False);
  1081         Uint8 c = (256 * i / ncolors);
  1045 	UNLOCK_DISPLAY();
  1082         xcmap[i].pixel = SDL_MapRGB(this->screen->format, c, c, c);
  1046 	return(0);
  1083         xcmap[i].red = ramp[0 * 256 + c];
  1047 }
  1084         xcmap[i].green = ramp[1 * 256 + c];
  1048 
  1085         xcmap[i].blue = ramp[2 * 256 + c];
  1049 void DGA_VideoQuit(_THIS)
  1086         xcmap[i].flags = (DoRed | DoGreen | DoBlue);
  1050 {
  1087     }
  1051 	int i, j;
  1088     LOCK_DISPLAY();
  1052 
  1089     XStoreColors(DGA_Display, DGA_colormap, xcmap, ncolors);
  1053 	if ( DGA_Display ) {
  1090     XSync(DGA_Display, False);
  1054 		/* Free colormap, if necessary */
  1091     UNLOCK_DISPLAY();
  1055 		if ( DGA_colormap ) {
  1092     return (0);
  1056 			XFreeColormap(DGA_Display, DGA_colormap);
  1093 }
  1057 			DGA_colormap = 0;
  1094 
  1058 		}
  1095 void
  1059 
  1096 DGA_VideoQuit(_THIS)
  1060 		/* Unmap memory and reset video mode */
  1097 {
  1061 		SDL_NAME(XDGACloseFramebuffer)(DGA_Display, DGA_Screen);
  1098     int i, j;
  1062 		if ( this->screen ) {
  1099 
  1063 			/* Tell SDL not to free the pixels */
  1100     if (DGA_Display) {
  1064 			DGA_FreeHWSurface(this, this->screen);
  1101         /* Free colormap, if necessary */
  1065 		}
  1102         if (DGA_colormap) {
  1066 		SDL_NAME(XDGASetMode)(DGA_Display, DGA_Screen, 0);
  1103             XFreeColormap(DGA_Display, DGA_colormap);
  1067 
  1104             DGA_colormap = 0;
  1068 		/* Clear the lock mutex */
  1105         }
  1069 		if ( hw_lock != NULL ) {
  1106 
  1070 			SDL_DestroyMutex(hw_lock);
  1107         /* Unmap memory and reset video mode */
  1071 			hw_lock = NULL;
  1108         SDL_NAME(XDGACloseFramebuffer) (DGA_Display, DGA_Screen);
  1072 		}
  1109         if (this->screen) {
       
  1110             /* Tell SDL not to free the pixels */
       
  1111             DGA_FreeHWSurface(this, this->screen);
       
  1112         }
       
  1113         SDL_NAME(XDGASetMode) (DGA_Display, DGA_Screen, 0);
       
  1114 
       
  1115         /* Clear the lock mutex */
       
  1116         if (hw_lock != NULL) {
       
  1117             SDL_DestroyMutex(hw_lock);
       
  1118             hw_lock = NULL;
       
  1119         }
  1073 #ifdef LOCK_DGA_DISPLAY
  1120 #ifdef LOCK_DGA_DISPLAY
  1074 		if ( event_lock != NULL ) {
  1121         if (event_lock != NULL) {
  1075 			SDL_DestroyMutex(event_lock);
  1122             SDL_DestroyMutex(event_lock);
  1076 			event_lock = NULL;
  1123             event_lock = NULL;
  1077 		}
  1124         }
  1078 #endif /* LOCK_DGA_DISPLAY */
  1125 #endif /* LOCK_DGA_DISPLAY */
  1079 
  1126 
  1080 		/* Clean up defined video modes */
  1127         /* Clean up defined video modes */
  1081 		for ( i=0; i<NUM_MODELISTS; ++i ) {
  1128         for (i = 0; i < NUM_MODELISTS; ++i) {
  1082 			if ( SDL_modelist[i] != NULL ) {
  1129             if (SDL_modelist[i] != NULL) {
  1083 				for ( j=0; SDL_modelist[i][j]; ++j ) {
  1130                 for (j = 0; SDL_modelist[i][j]; ++j) {
  1084 					SDL_free(SDL_modelist[i][j]);
  1131                     SDL_free(SDL_modelist[i][j]);
  1085 				}
  1132                 }
  1086 				SDL_free(SDL_modelist[i]);
  1133                 SDL_free(SDL_modelist[i]);
  1087 				SDL_modelist[i] = NULL;
  1134                 SDL_modelist[i] = NULL;
  1088 			}
  1135             }
  1089 		}
  1136         }
  1090 
  1137 
  1091 		/* Clean up the memory bucket list */
  1138         /* Clean up the memory bucket list */
  1092 		DGA_FreeHWSurfaces(this);
  1139         DGA_FreeHWSurfaces(this);
  1093 
  1140 
  1094 		/* Restore DPMS and screensaver settings */
  1141         /* Restore DPMS and screensaver settings */
  1095 		X11_RestoreScreenSaver(DGA_Display, screensaver_timeout, dpms_enabled);
  1142         X11_RestoreScreenSaver(DGA_Display, screensaver_timeout,
  1096 
  1143                                dpms_enabled);
  1097 		/* Close up the display */
  1144 
  1098 		XCloseDisplay(DGA_Display);
  1145         /* Close up the display */
  1099 	}
  1146         XCloseDisplay(DGA_Display);
  1100 }
  1147     }
       
  1148 }
       
  1149 
       
  1150 /* vi: set ts=4 sw=4 expandtab: */