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

📄 sdl_dgavideo.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	SDL - Simple DirectMedia Layer	Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga	This library is free software; you can redistribute it and/or	modify it under the terms of the GNU Library General Public	License as published by the Free Software Foundation; either	version 2 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	Library General Public License for more details.	You should have received a copy of the GNU Library General Public	License along with this library; if not, write to the Free	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA	Sam Lantinga	slouken@libsdl.org*/#ifdef SAVE_RCSIDstatic char rcsid = "@(#) $Id$";#endif/* DGA 2.0 based SDL video driver implementation.*/#include <stdlib.h>#include <string.h>#include <X11/Xlib.h>#include <XFree86/extensions/xf86dga.h>#ifdef HAVE_ALLOCA_H#include <alloca.h>#endif#include "SDL.h"#include "SDL_error.h"#include "SDL_video.h"#include "SDL_mouse.h"#include "SDL_sysvideo.h"#include "SDL_pixels_c.h"#include "SDL_events_c.h"#include "SDL_dgavideo.h"#include "SDL_dgamouse_c.h"#include "SDL_dgaevents_c.h"/* 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;	Display *dpy;	int available;	/* The driver is available is available if the display is local	   and the DGA 2.0+ extension is available, and we can map mem.	*/	available = 0;	display = NULL;	if ( (strncmp(XDisplayName(display), ":", 1) == 0) ||	     (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);		}	}	return(available);}static void DGA_DeleteDevice(SDL_VideoDevice *device){	free(device->hidden);	free(device);}static SDL_VideoDevice *DGA_CreateDevice(int devindex){	SDL_VideoDevice *device;	/* Initialize all variables that we clean on shutdown */	device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));	if ( device ) {		memset(device, 0, (sizeof *device));		device->hidden = (struct SDL_PrivateVideoData *)				malloc((sizeof *device->hidden));	}	if ( (device == NULL) || (device->hidden == NULL) ) {		SDL_OutOfMemory();		if ( device ) {			free(device);		}		return(0);	}	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 i, 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;	for ( i=0; i<SDL_nummodes[index]; ++i ) {		mode = SDL_modelist[index][i];		if ( (mode->w == w) && (mode->h == h) ) {			return(0);		}	}	/* Set up the new video mode rectangle */	mode = (SDL_Rect *)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 **)	       realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *));	if ( SDL_modelist[index] == NULL ) {		SDL_OutOfMemory();		SDL_nummodes[index] = 0;		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) ) {			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;    /* Prefer DirectColor visuals for otherwise equal modes */    if ( (a->viewportWidth == b->viewportWidth) &&         (b->viewportHeight == a->viewportHeight) ) {         if ( a->visualClass == DirectColor )             return -1;         if ( b->visualClass == DirectColor )             return 1;         return 0;    } else {        if(a->viewportWidth > b->viewportWidth)            return -1;        return b->viewportHeight - a->viewportHeight;    }}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 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);	}	/* Query for the list of available video modes */	modes = SDL_NAME(XDGAQueryModes)(DGA_Display, DGA_Screen, &num_modes);	qsort(modes, num_modes, sizeof *modes, cmpmodes);	for ( i=0; i<num_modes; ++i ) {#ifdef DGA_DEBUG		PrintMode(&modes[i]);#endif		if ( (modes[i].visualClass == PseudoColor) ||		     (modes[i].visualClass == DirectColor) ||		     (modes[i].visualClass == TrueColor) ) {			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);	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)) ) {			break;		}	}	if ( i == num_modes ) {		SDL_SetError("No matching video mode found");		return(NULL);	}	/* 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 = modes[i].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) ) {			current->flags |= SDL_DOUBLEBUF;			flip_page = 0;			flip_yoffset[0] = 0;			flip_yoffset[1] = current->h;			flip_address[0] = memory_base;			flip_address[1] = memory_base+screen_len;

⌨️ 快捷键说明

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