⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdl_dgavideo.c

📁 SDL库 在进行视频显示程序spcaview安装时必须的库文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    SDL - Simple DirectMedia Layer    Copyright (C) 1997-2006 Sam Lantinga    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Lesser General Public    License as published by the Free Software Foundation; either    version 2.1 of the License, or (at your option) any later version.    This library is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    Lesser General Public License for more details.    You should have received a copy of the GNU Lesser General Public    License along with this library; if not, write to the Free Software    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA    Sam Lantinga    slouken@libsdl.org*/#include "SDL_config.h"/* DGA 2.0 based SDL video driver implementation.*/#include <stdio.h>#include <X11/Xlib.h>#include "../Xext/extensions/xf86dga.h"#include "SDL_video.h"#include "SDL_mouse.h"#include "../SDL_sysvideo.h"#include "../SDL_pixels_c.h"#include "../../events/SDL_events_c.h"#include "SDL_dgavideo.h"#include "SDL_dgamouse_c.h"#include "SDL_dgaevents_c.h"/* get function pointers... */#include "../x11/SDL_x11dyn.h"/*#define DGA_DEBUG*//* Heheh we're using X11 event code */extern void X11_SaveScreenSaver(Display *display, int *saved_timeout, BOOL *dpms);extern void X11_DisableScreenSaver(Display *display);extern void X11_RestoreScreenSaver(Display *display, int saved_timeout, BOOL dpms);/* Initialization/Query functions */static int DGA_VideoInit(_THIS, SDL_PixelFormat *vformat);static SDL_Rect **DGA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);static SDL_Surface *DGA_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);static int DGA_SetColors(_THIS, int firstcolor, int ncolors,			 SDL_Color *colors);static int DGA_SetGammaRamp(_THIS, Uint16 *ramp);static void DGA_VideoQuit(_THIS);/* Hardware surface functions */static int DGA_InitHWSurfaces(_THIS, SDL_Surface *screen, Uint8 *base, int size);static void DGA_FreeHWSurfaces(_THIS);static int DGA_AllocHWSurface(_THIS, SDL_Surface *surface);static int DGA_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color);static int DGA_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst);static int DGA_LockHWSurface(_THIS, SDL_Surface *surface);static void DGA_UnlockHWSurface(_THIS, SDL_Surface *surface);static void DGA_FreeHWSurface(_THIS, SDL_Surface *surface);static int DGA_FlipHWSurface(_THIS, SDL_Surface *surface);/* DGA driver bootstrap functions */static int DGA_Available(void){	const char *display = NULL;	Display *dpy = NULL;	int available = 0;	/* The driver is available is available if the display is local	   and the DGA 2.0+ extension is available, and we can map mem.	*/	if ( SDL_X11_LoadSymbols() ) {		if ( (SDL_strncmp(XDisplayName(display), ":", 1) == 0) ||		     (SDL_strncmp(XDisplayName(display), "unix:", 5) == 0) ) {			dpy = XOpenDisplay(display);			if ( dpy ) {				int events, errors, major, minor;				if ( SDL_NAME(XDGAQueryExtension)(dpy, &events, &errors) &&				     SDL_NAME(XDGAQueryVersion)(dpy, &major, &minor) ) {					int screen;					screen = DefaultScreen(dpy);					if ( (major >= 2) && 					     SDL_NAME(XDGAOpenFramebuffer)(dpy, screen) ) {						available = 1;						SDL_NAME(XDGACloseFramebuffer)(dpy, screen);					}				}				XCloseDisplay(dpy);			}		}		SDL_X11_UnloadSymbols();	}	return(available);}static void DGA_DeleteDevice(SDL_VideoDevice *device){	if (device != NULL) {		SDL_free(device->hidden);		SDL_free(device);		SDL_X11_UnloadSymbols();	}}static SDL_VideoDevice *DGA_CreateDevice(int devindex){	SDL_VideoDevice *device = NULL;	/* Initialize all variables that we clean on shutdown */	if (SDL_X11_LoadSymbols()) {		device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));		if ( device ) {			SDL_memset(device, 0, (sizeof *device));			device->hidden = (struct SDL_PrivateVideoData *)					SDL_malloc((sizeof *device->hidden));		}		if ( (device == NULL) || (device->hidden == NULL) ) {			SDL_OutOfMemory();			if ( device ) {				SDL_free(device);			}			SDL_X11_UnloadSymbols();			return(0);		}		SDL_memset(device->hidden, 0, (sizeof *device->hidden));		/* Set the function pointers */		device->VideoInit = DGA_VideoInit;		device->ListModes = DGA_ListModes;		device->SetVideoMode = DGA_SetVideoMode;		device->SetColors = DGA_SetColors;		device->UpdateRects = NULL;		device->VideoQuit = DGA_VideoQuit;		device->AllocHWSurface = DGA_AllocHWSurface;		device->CheckHWBlit = DGA_CheckHWBlit;		device->FillHWRect = DGA_FillHWRect;		device->SetHWColorKey = NULL;		device->SetHWAlpha = NULL;		device->LockHWSurface = DGA_LockHWSurface;		device->UnlockHWSurface = DGA_UnlockHWSurface;		device->FlipHWSurface = DGA_FlipHWSurface;		device->FreeHWSurface = DGA_FreeHWSurface;		device->SetGammaRamp = DGA_SetGammaRamp;		device->GetGammaRamp = NULL;		device->SetCaption = NULL;		device->SetIcon = NULL;		device->IconifyWindow = NULL;		device->GrabInput = NULL;		device->GetWMInfo = NULL;		device->InitOSKeymap = DGA_InitOSKeymap;		device->PumpEvents = DGA_PumpEvents;		device->free = DGA_DeleteDevice;	}	return device;}VideoBootStrap DGA_bootstrap = {	"dga", "XFree86 DGA 2.0",	DGA_Available, DGA_CreateDevice};static int DGA_AddMode(_THIS, int bpp, int w, int h){	SDL_Rect *mode;	int index;	int next_mode;	/* Check to see if we already have this mode */	if ( bpp < 8 ) {  /* Not supported */		return(0);	}	index = ((bpp+7)/8)-1;	if ( SDL_nummodes[index] > 0 ) {		mode = SDL_modelist[index][SDL_nummodes[index]-1];		if ( (mode->w == w) && (mode->h == h) ) {			return(0);		}	}	/* Set up the new video mode rectangle */	mode = (SDL_Rect *)SDL_malloc(sizeof *mode);	if ( mode == NULL ) {		SDL_OutOfMemory();		return(-1);	}	mode->x = 0;	mode->y = 0;	mode->w = w;	mode->h = h;	/* Allocate the new list of modes, and fill in the new mode */	next_mode = SDL_nummodes[index];	SDL_modelist[index] = (SDL_Rect **)	       SDL_realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *));	if ( SDL_modelist[index] == NULL ) {		SDL_OutOfMemory();		SDL_nummodes[index] = 0;		SDL_free(mode);		return(-1);	}	SDL_modelist[index][next_mode] = mode;	SDL_modelist[index][next_mode+1] = NULL;	SDL_nummodes[index]++;	return(0);}/* This whole function is a hack. :) */static Uint32 get_video_size(_THIS){	/* This is a non-exported function from libXxf86dga.a */	extern unsigned char *SDL_NAME(XDGAGetMappedMemory)(int screen);	FILE *proc;	unsigned long mem;	unsigned start, stop;	char line[BUFSIZ];	Uint32 size;	mem = (unsigned long)SDL_NAME(XDGAGetMappedMemory)(DGA_Screen);	size = 0;	proc = fopen("/proc/self/maps", "r");	if ( proc ) {		while ( fgets(line, sizeof(line)-1, proc) ) {			SDL_sscanf(line, "%x-%x", &start, &stop);			if ( start == mem ) {				size = (Uint32)((stop-start)/1024);				break;			}		}		fclose(proc);	}	return(size);}#ifdef DGA_DEBUGstatic void PrintMode(SDL_NAME(XDGAMode) *mode){	printf("Mode: %s (%dx%d) at %d bpp (%f refresh, %d pitch) num: %d\n",		mode->name,		mode->viewportWidth, mode->viewportHeight,		mode->depth == 24 ? mode->bitsPerPixel : mode->depth,		mode->verticalRefresh, mode->bytesPerScanline, mode->num);	printf("\tRGB: 0x%8.8x 0x%8.8x 0x%8.8x (%d - %s)\n",		mode->redMask, mode->greenMask, mode->blueMask,		mode->visualClass,		mode->visualClass == TrueColor ? "truecolor" :		mode->visualClass == DirectColor ? "directcolor" :		mode->visualClass == PseudoColor ? "pseudocolor" : "unknown");	printf("\tFlags: ");	if ( mode->flags & XDGAConcurrentAccess )		printf(" XDGAConcurrentAccess");	if ( mode->flags & XDGASolidFillRect )		printf(" XDGASolidFillRect");	if ( mode->flags & XDGABlitRect )		printf(" XDGABlitRect");	if ( mode->flags & XDGABlitTransRect )		printf(" XDGABlitTransRect");	if ( mode->flags & XDGAPixmap )		printf(" XDGAPixmap");	if ( mode->flags & XDGAInterlaced )		printf(" XDGAInterlaced");	if ( mode->flags & XDGADoublescan )		printf(" XDGADoublescan");	if ( mode->viewportFlags & XDGAFlipRetrace )		printf(" XDGAFlipRetrace");	if ( mode->viewportFlags & XDGAFlipImmediate )		printf(" XDGAFlipImmediate");	printf("\n");}#endif /* DGA_DEBUG */static int cmpmodes(const void *va, const void *vb){    const SDL_NAME(XDGAMode) *a = (const SDL_NAME(XDGAMode) *)va;    const SDL_NAME(XDGAMode) *b = (const SDL_NAME(XDGAMode) *)vb;    if ( (a->viewportWidth == b->viewportWidth) &&         (b->viewportHeight == a->viewportHeight) ) {        /* Prefer 32 bpp over 24 bpp, 16 bpp over 15 bpp */        int a_bpp = a->depth == 24 ? a->bitsPerPixel : a->depth;        int b_bpp = b->depth == 24 ? b->bitsPerPixel : b->depth;        if ( a_bpp != b_bpp ) {            return b_bpp - a_bpp;        }        /* Prefer DirectColor visuals, for gamma support */        if ( a->visualClass == DirectColor && b->visualClass != DirectColor )            return -1;        if ( b->visualClass == DirectColor && a->visualClass != DirectColor )            return 1;        /* Maintain server refresh rate sorting */        return a->num - b->num;    } else if ( a->viewportWidth == b->viewportWidth ) {        return b->viewportHeight - a->viewportHeight;    } else {        return b->viewportWidth - a->viewportWidth;    }}static void UpdateHWInfo(_THIS, SDL_NAME(XDGAMode) *mode){	this->info.wm_available = 0;	this->info.hw_available = 1;	if ( mode->flags & XDGABlitRect ) {		this->info.blit_hw = 1;	} else {		this->info.blit_hw = 0;	}	if ( mode->flags & XDGABlitTransRect ) {		this->info.blit_hw_CC = 1;	} else {		this->info.blit_hw_CC = 0;	}	if ( mode->flags & XDGASolidFillRect ) {		this->info.blit_fill = 1;	} else {		this->info.blit_fill = 0;	}	this->info.video_mem = get_video_size(this);}static int DGA_VideoInit(_THIS, SDL_PixelFormat *vformat){	const char *display;	int event_base, error_base;	int major_version, minor_version;	Visual *visual;	SDL_NAME(XDGAMode) *modes;	int i, num_modes;	/* Open the X11 display */	display = NULL;		/* Get it from DISPLAY environment variable */	DGA_Display = XOpenDisplay(display);	if ( DGA_Display == NULL ) {		SDL_SetError("Couldn't open X11 display");		return(-1);	}	/* Check for the DGA extension */	if ( ! SDL_NAME(XDGAQueryExtension)(DGA_Display, &event_base, &error_base) ||	     ! SDL_NAME(XDGAQueryVersion)(DGA_Display, &major_version, &minor_version) ) {		SDL_SetError("DGA extension not available");		XCloseDisplay(DGA_Display);		return(-1);	}	if ( major_version < 2 ) {		SDL_SetError("DGA driver requires DGA 2.0 or newer");		XCloseDisplay(DGA_Display);		return(-1);	}	DGA_event_base = event_base;	/* Determine the current screen size */	this->info.current_w = DisplayWidth(DGA_Display, DGA_Screen);	this->info.current_h = DisplayHeight(DGA_Display, DGA_Screen);	/* Determine the current screen depth */	visual = DefaultVisual(DGA_Display, DGA_Screen);	{		XPixmapFormatValues *pix_format;		int i, num_formats;		vformat->BitsPerPixel = DefaultDepth(DGA_Display, DGA_Screen);		pix_format = XListPixmapFormats(DGA_Display, &num_formats);		if ( pix_format == NULL ) {			SDL_SetError("Couldn't determine screen formats");			XCloseDisplay(DGA_Display);			return(-1);		}		for ( i=0; i<num_formats; ++i ) {			if ( vformat->BitsPerPixel == pix_format[i].depth )				break;		}		if ( i != num_formats )			vformat->BitsPerPixel = pix_format[i].bits_per_pixel;		XFree((char *)pix_format);	}	if ( vformat->BitsPerPixel > 8 ) {		vformat->Rmask = visual->red_mask;		vformat->Gmask = visual->green_mask;		vformat->Bmask = visual->blue_mask;	}	/* Open access to the framebuffer */	if ( ! SDL_NAME(XDGAOpenFramebuffer)(DGA_Display, DGA_Screen) ) {		SDL_SetError("Unable to map the video memory");		XCloseDisplay(DGA_Display);		return(-1);	}	/* Save DPMS and screensaver settings */	X11_SaveScreenSaver(DGA_Display, &screensaver_timeout, &dpms_enabled);	X11_DisableScreenSaver(DGA_Display);	/* Query for the list of available video modes */	modes = SDL_NAME(XDGAQueryModes)(DGA_Display, DGA_Screen, &num_modes);	SDL_qsort(modes, num_modes, sizeof *modes, cmpmodes);	for ( i=0; i<num_modes; ++i ) {		if ( ((modes[i].visualClass == PseudoColor) ||		      (modes[i].visualClass == DirectColor) ||		      (modes[i].visualClass == TrueColor)) && 		     !(modes[i].flags & (XDGAInterlaced|XDGADoublescan)) ) {#ifdef DGA_DEBUG			PrintMode(&modes[i]);#endif			DGA_AddMode(this, modes[i].bitsPerPixel,			            modes[i].viewportWidth,			            modes[i].viewportHeight);		}	}	UpdateHWInfo(this, modes);	XFree(modes);	/* Create the hardware surface lock mutex */	hw_lock = SDL_CreateMutex();	if ( hw_lock == NULL ) {		SDL_SetError("Unable to create lock mutex");		DGA_VideoQuit(this);		return(-1);	}#ifdef LOCK_DGA_DISPLAY	/* Create the event lock so we're thread-safe.. :-/ */	event_lock = SDL_CreateMutex();#endif /* LOCK_DGA_DISPLAY */	/* We're done! */	return(0);}SDL_Rect **DGA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags){	return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]);}/* Various screen update functions available */static void DGA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);SDL_Surface *DGA_SetVideoMode(_THIS, SDL_Surface *current,				int width, int height, int bpp, Uint32 flags){	SDL_NAME(XDGAMode) *modes;	int i, num_modes;	SDL_NAME(XDGADevice) *mode;	int screen_len;	Uint8 *surfaces_mem;	int surfaces_len;	/* Free any previous colormap */	if ( DGA_colormap ) {		XFreeColormap(DGA_Display, DGA_colormap);		DGA_colormap = 0;	}	/* Search for a matching video mode */	modes = SDL_NAME(XDGAQueryModes)(DGA_Display, DGA_Screen, &num_modes);	SDL_qsort(modes, num_modes, sizeof *modes, cmpmodes);	for ( i=0; i<num_modes; ++i ) {		int depth;		depth = modes[i].depth;		if ( depth == 24 ) { /* Distinguish between 24 and 32 bpp */			depth = modes[i].bitsPerPixel;		}		if ( (depth == bpp) &&		     (modes[i].viewportWidth == width) &&		     (modes[i].viewportHeight == height) &&		     ((modes[i].visualClass == PseudoColor) ||		      (modes[i].visualClass == DirectColor) ||		      (modes[i].visualClass == TrueColor)) &&		     !(modes[i].flags & (XDGAInterlaced|XDGADoublescan)) ) {			break;		}	}	if ( i == num_modes ) {		SDL_SetError("No matching video mode found");		return(NULL);	}#ifdef DGA_DEBUG	PrintMode(&modes[i]);#endif	/* Set the video mode */	mode = SDL_NAME(XDGASetMode)(DGA_Display, DGA_Screen, modes[i].num);	XFree(modes);	if ( mode == NULL ) {		SDL_SetError("Unable to switch to requested mode");		return(NULL);	}	DGA_visualClass = mode->mode.visualClass;	memory_base = (Uint8 *)mode->data;	memory_pitch = mode->mode.bytesPerScanline;	/* Set up the new mode framebuffer */	current->flags = (SDL_FULLSCREEN|SDL_HWSURFACE);	current->w = mode->mode.viewportWidth;	current->h = mode->mode.viewportHeight;	current->pitch = memory_pitch;	current->pixels = memory_base;	if ( ! SDL_ReallocFormat(current, mode->mode.bitsPerPixel,	                                  mode->mode.redMask,	                                  mode->mode.greenMask,	                                  mode->mode.blueMask, 0) ) {		return(NULL);	}	screen_len = current->h*current->pitch;	/* Create a colormap if necessary */	if ( (DGA_visualClass == PseudoColor) ||             (DGA_visualClass == DirectColor) ) {		DGA_colormap = SDL_NAME(XDGACreateColormap)(DGA_Display, DGA_Screen,							mode, AllocAll);		if ( DGA_visualClass == PseudoColor ) {			current->flags |= SDL_HWPALETTE;		} else {	    		/* Initialize the colormap to the identity mapping */	    		SDL_GetGammaRamp(0, 0, 0);	    		this->screen = current;	    		DGA_SetGammaRamp(this, this->gamma);			this->screen = NULL;		}	} else {		DGA_colormap = SDL_NAME(XDGACreateColormap)(DGA_Display, DGA_Screen,							mode, AllocNone);	}	SDL_NAME(XDGAInstallColormap)(DGA_Display, DGA_Screen, DGA_colormap);	/* Update the hardware capabilities */	UpdateHWInfo(this, &mode->mode);	/* Set up the information for hardware surfaces */	surfaces_mem = (Uint8 *)current->pixels + screen_len;	surfaces_len = (mode->mode.imageHeight*current->pitch - screen_len);	/* Update for double-buffering, if we can */	SDL_NAME(XDGASetViewport)(DGA_Display, DGA_Screen, 0, 0, XDGAFlipRetrace);	if ( flags & SDL_DOUBLEBUF ) {		if ( mode->mode.imageHeight >= (current->h*2) ) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -