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

📄 video.c

📁 linux下的图形界面开发minigui最新源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***  $Id: video.c,v 1.12 2003/09/04 06:02:53 weiym Exp $**  **  Port to MiniGUI by Wei Yongming (2001/10/03).**  Copyright (C) 2001 ~ 2002 Wei Yongming.**  Copyright (C) 2003 Feynman Software.****  SDL - Simple DirectMedia Layer**  Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga*//*** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program 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 General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*//* The high-level video driver subsystem */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "common.h"#include "minigui.h"#include "newgal.h"#include "sysvideo.h"#include "blit.h"#include "pixels_c.h"/* Available video drivers */static VideoBootStrap *bootstrap[] = {#ifdef ENABLE_X11    &X11_bootstrap,#endif#ifdef ENABLE_DGA    &DGA_bootstrap,#endif#ifdef ENABLE_FBCON    &FBCON_bootstrap,#endif#ifdef ENABLE_QVFB    &QVFB_bootstrap,#endif#ifdef ENABLE_GGI    &GGI_bootstrap,#endif#ifdef ENABLE_SVGALIB    &SVGALIB_bootstrap,#endif    NULL};GAL_VideoDevice *current_video = NULL;/* Various local functions */int GAL_VideoInit(const char *driver_name, Uint32 flags);void GAL_VideoQuit(void);/* * Initialize the video subsystems -- determine native pixel format */int GAL_VideoInit (const char *driver_name, Uint32 flags){    GAL_VideoDevice *video;    int index;    int i;    GAL_PixelFormat vformat;    Uint32 video_flags;    /* Check to make sure we don't overwrite 'current_video' */    if ( current_video != NULL ) {        GAL_VideoQuit();    }    /* Select the proper video driver */    index = 0;    video = NULL;    if ( driver_name != NULL ) {        for ( i=0; bootstrap[i]; ++i ) {            if ( strncmp(bootstrap[i]->name, driver_name,                         strlen(bootstrap[i]->name)) == 0 ) {                if ( bootstrap[i]->available() ) {                    video = bootstrap[i]->create(index);                    break;                }            }        }    } else {        for ( i=0; bootstrap[i]; ++i ) {            if ( bootstrap[i]->available() ) {                video = bootstrap[i]->create(index);                if ( video != NULL ) {                    break;                }            }        }    }    if ( video == NULL ) {        GAL_SetError("No available video device.\n");        return(-1);    }    current_video = video;    current_video->name = bootstrap[i]->name;    /* Do some basic variable initialization */    video->screen = NULL;#if 0    video->shadow = NULL;    video->visible = NULL;#endif    video->physpal = NULL;    video->offset_x = 0;    video->offset_y = 0;    memset(&video->info, 0, (sizeof video->info));    /* Initialize the video subsystem */    memset(&vformat, 0, sizeof(vformat));    if ( video->VideoInit(video, &vformat) < 0 ) {        GAL_VideoQuit();        return(-1);    }    /* Create a zero sized video surface of the appropriate format */    video_flags = GAL_SWSURFACE;    GAL_VideoSurface = GAL_CreateRGBSurface(video_flags, 0, 0,                vformat.BitsPerPixel,                vformat.Rmask, vformat.Gmask, vformat.Bmask, 0);    if ( GAL_VideoSurface == NULL ) {        GAL_VideoQuit();        return(-1);    }    video->info.vfmt = GAL_VideoSurface->format;    /* We're ready to go! */    return(0);}char *GAL_VideoDriverName(char *namebuf, int maxlen){    if ( current_video != NULL ) {        strncpy(namebuf, current_video->name, maxlen-1);        namebuf[maxlen-1] = '\0';        return(namebuf);    }    return(NULL);}/* * Get the current display surface */GAL_Surface *GAL_GetVideoSurface(void){    GAL_Surface *visible;    visible = NULL;    if ( current_video ) {#if 0        visible = current_video->visible;#else        visible = current_video->screen;#endif    }    return(visible);}/* * Get the current information about the video hardware */const GAL_VideoInfo *GAL_GetVideoInfo(void){    const GAL_VideoInfo *info;    info = NULL;    if ( current_video ) {        info = &current_video->info;    }    return(info);}/* * Return a pointer to an array of available screen dimensions for the * given format, sorted largest to smallest.  Returns NULL if there are * no dimensions available for a particular format, or (GAL_Rect **)-1 * if any dimension is okay for the given format.  If 'format' is NULL, * the mode list will be for the format given by GAL_GetVideoInfo()->vfmt */GAL_Rect ** GAL_ListModes (GAL_PixelFormat *format, Uint32 flags){    GAL_VideoDevice *video = current_video;    GAL_VideoDevice *this  = current_video;    GAL_Rect **modes;    modes = NULL;    if ( GAL_VideoSurface ) {        if ( format == NULL ) {            format = GAL_VideoSurface->format;        }        modes = video->ListModes(this, format, flags);    }    return(modes);}/* * Check to see if a particular video mode is supported. * It returns 0 if the requested mode is not supported under any bit depth, * or returns the bits-per-pixel of the closest available mode with the * given width and height.  If this bits-per-pixel is different from the * one used when setting the video mode, GAL_SetVideoMode() will succeed, * but will emulate the requested bits-per-pixel with a shadow surface. */static Uint8 GAL_closest_depths[4][8] = {    /* 8 bit closest depth ordering */    { 0, 8, 16, 15, 32, 24, 0, 0 },    /* 15,16 bit closest depth ordering */    { 0, 16, 15, 32, 24, 8, 0, 0 },    /* 24 bit closest depth ordering */    { 0, 24, 32, 16, 15, 8, 0, 0 },    /* 32 bit closest depth ordering */    { 0, 32, 16, 15, 24, 8, 0, 0 }};int GAL_VideoModeOK (int width, int height, int bpp, Uint32 flags) {    int table, b, i;    int supported;    GAL_PixelFormat format;    GAL_Rect **sizes;    /* Currently 1 and 4 bpp are not supported */    if ( bpp < 8 || bpp > 32 ) {        return(0);    }    if ( (width == 0) || (height == 0) ) {        return(0);    }    /* Search through the list valid of modes */    memset(&format, 0, sizeof(format));    supported = 0;    table = ((bpp+7)/8)-1;    GAL_closest_depths[table][0] = bpp;    GAL_closest_depths[table][7] = 0;    for ( b = 0; !supported && GAL_closest_depths[table][b]; ++b ) {        format.BitsPerPixel = GAL_closest_depths[table][b];        sizes = GAL_ListModes(&format, flags);        if ( sizes == (GAL_Rect **)0 ) {            /* No sizes supported at this bit-depth */            continue;        } else         if ( (sizes == (GAL_Rect **)-1) ||             current_video->handles_any_size ) {            /* Any size supported at this bit-depth */            supported = 1;            continue;        } else        for ( i=0; sizes[i]; ++i ) {            if ((sizes[i]->w == width) && (sizes[i]->h == height)) {                supported = 1;                break;            }        }    }    if ( supported ) {        --b;        return(GAL_closest_depths[table][b]);    } else {        return(0);    }}/* * Get the closest non-emulated video mode to the one requested */static int GAL_GetVideoMode (int *w, int *h, int *BitsPerPixel, Uint32 flags){    int table, b, i;    int supported;    int native_bpp;    GAL_PixelFormat format;    GAL_Rect **sizes;    /* Try the original video mode, get the closest depth */    native_bpp = GAL_VideoModeOK(*w, *h, *BitsPerPixel, flags);    if ( native_bpp == *BitsPerPixel ) {        return(1);    }    if ( native_bpp > 0 ) {        *BitsPerPixel = native_bpp;        return(1);    }    /* No exact size match at any depth, look for closest match */    memset(&format, 0, sizeof(format));    supported = 0;    table = ((*BitsPerPixel+7)/8)-1;    GAL_closest_depths[table][0] = *BitsPerPixel;    GAL_closest_depths[table][7] = GAL_VideoSurface->format->BitsPerPixel;    for ( b = 0; !supported && GAL_closest_depths[table][b]; ++b ) {        format.BitsPerPixel = GAL_closest_depths[table][b];        sizes = GAL_ListModes(&format, flags);        if ( sizes == (GAL_Rect **)0 ) {            /* No sizes supported at this bit-depth */            continue;        }        for ( i=0; sizes[i]; ++i ) {            if ((sizes[i]->w < *w) || (sizes[i]->h < *h)) {                if ( i > 0 ) {                    --i;                    *w = sizes[i]->w;                    *h = sizes[i]->h;                    *BitsPerPixel = GAL_closest_depths[table][b];                    supported = 1;                } else {                    /* Largest mode too small... */;                }                break;            }        }        if ( (i > 0) && ! sizes[i] ) {            /* The smallest mode was larger than requested, OK */            --i;            *w = sizes[i]->w;            *h = sizes[i]->h;            *BitsPerPixel = GAL_closest_depths[table][b];            supported = 1;        }    }    if ( ! supported ) {        GAL_SetError("No video mode large enough for the resolution specified.\n");    }    return(supported);}/* This should probably go somewhere else -- like GAL_surface.c */static void GAL_ClearSurface(GAL_Surface *surface){    Uint32 black;    black = GAL_MapRGB(surface->format, 0, 0, 0);    GAL_FillRect(surface, NULL, black);#if 0    if ((surface->flags&GAL_HWSURFACE) && (surface->flags&GAL_DOUBLEBUF)) {        GAL_Flip(surface);        GAL_FillRect(surface, NULL, black);    }    GAL_Flip(surface);#endif}#if 0/* * Create a shadow surface suitable for fooling the app. :-) */static void GAL_CreateShadowSurface(int depth){    Uint32 Rmask, Gmask, Bmask;    /* Allocate the shadow surface */    if ( depth == (GAL_VideoSurface->format)->BitsPerPixel ) {        Rmask = (GAL_VideoSurface->format)->Rmask;        Gmask = (GAL_VideoSurface->format)->Gmask;        Bmask = (GAL_VideoSurface->format)->Bmask;    } else {        Rmask = Gmask = Bmask = 0;    }    GAL_ShadowSurface = GAL_CreateRGBSurface(GAL_SWSURFACE,                GAL_VideoSurface->w, GAL_VideoSurface->h,                        depth, Rmask, Gmask, Bmask, 0);    if ( GAL_ShadowSurface == NULL ) {        return;    }    /* 8-bit shadow surfaces report that they have exclusive palette */    if ( GAL_ShadowSurface->format->palette ) {        GAL_ShadowSurface->flags |= GAL_HWPALETTE;        if ( depth == (GAL_VideoSurface->format)->BitsPerPixel ) {            memcpy(GAL_ShadowSurface->format->palette->colors,                GAL_VideoSurface->format->palette->colors,                GAL_VideoSurface->format->palette->ncolors*                            sizeof(GAL_Color));        } else {            GAL_DitherColors(            GAL_ShadowSurface->format->palette->colors, depth);        }    }    /* If the video surface is fullscreen, the shadow should say so */    if ( (GAL_VideoSurface->flags & GAL_FULLSCREEN) == GAL_FULLSCREEN ) {        GAL_ShadowSurface->flags |= GAL_FULLSCREEN;    }    /* If the video surface is flippable, the shadow should say so */    if ( (GAL_VideoSurface->flags & GAL_DOUBLEBUF) == GAL_DOUBLEBUF ) {        GAL_ShadowSurface->flags |= GAL_DOUBLEBUF;    }    return;}#endif/* * Set the requested video mode, allocating a shadow buffer if necessary. */GAL_Surface * GAL_SetVideoMode (int width, int height, int bpp, Uint32 flags){    GAL_VideoDevice *video, *this;    GAL_Surface *prev_mode, *mode;    int video_w;    int video_h;    int video_bpp;    this = video = current_video;    /* Default to the current video bpp */    if ( bpp == 0 ) {        flags |= GAL_ANYFORMAT;        bpp = GAL_VideoSurface->format->BitsPerPixel;    }    /* Get a good video mode, the closest one possible */    video_w = width;    video_h = height;    video_bpp = bpp;#if defined(_LITE_VERSION) && !defined(_STAND_ALONE)    if ( mgIsServer && !GAL_GetVideoMode(&video_w, &video_h, &video_bpp, flags) ) {#else    if ( !GAL_GetVideoMode(&video_w, &video_h, &video_bpp, flags) ) {#endif        return(NULL);    }    /* Check the requested flags */    /* There's no palette in > 8 bits-per-pixel mode */    if ( video_bpp > 8 ) {        flags &= ~GAL_HWPALETTE;    }#if 0    if ( (flags&GAL_DOUBLEBUF) == GAL_DOUBLEBUF ) {        /* Use hardware surfaces when double-buffering */        flags |= GAL_HWSURFACE;    }    /* Clean up any previous video mode */    if ( GAL_PublicSurface != NULL ) {        GAL_PublicSurface = NULL;    }    if ( GAL_ShadowSurface != NULL ) {        GAL_Surface *ready_to_go;        ready_to_go = GAL_ShadowSurface;        GAL_ShadowSurface = NULL;        GAL_FreeSurface(ready_to_go);    }#endif    if ( video->physpal ) {        free(video->physpal->colors);        free(video->physpal);        video->physpal = NULL;    }    /* Try to set the video mode, along with offset and clipping */    prev_mode = GAL_VideoSurface;    GAL_VideoSurface = NULL;    /* In case it's freed by driver */    mode = video->SetVideoMode(this, prev_mode,video_w,video_h,video_bpp,flags);    /*     * rcg11292000     * If you try to set an GAL_OPENGL surface, and fail to find a     * matching  visual, then the next call to GAL_SetVideoMode()     * will segfault, since  we no longer point to a dummy surface,     * but rather NULL.     * Sam 11/29/00     * WARNING, we need to make sure that the previous mode hasn't     * already been freed by the video driver.  What do we do in     * that case?  Should we call GAL_VideoInit() again?     */    GAL_VideoSurface = (mode != NULL) ? mode : prev_mode;    if ((mode != NULL)) {        /* Sanity check */        if ( (mode->w < width) || (mode->h < height) ) {            GAL_SetError("Video mode smaller than requested");            return(NULL);        }        /* If we have a palettized surface, create a default palette */

⌨️ 快捷键说明

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