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

📄 sdl_quartzvideo.m

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 M
📖 第 1 页 / 共 3 页
字号:
/*
    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
*/

#include "SDL_QuartzVideo.h"

/* Some variables to share among files, put in device structure eventually */
static SDL_GrabMode currentGrabMode = SDL_GRAB_OFF;
static BOOL   inForeground = YES;
static char QZ_Error[255]; /* Global error buffer to temporarily store more informative error messages */

/* Include files into one compile unit...break apart eventually */
#include "SDL_QuartzWM.m"
#include "SDL_QuartzEvents.m"
#include "SDL_QuartzWindow.m"


/* Bootstrap binding, enables entry point into the driver */
VideoBootStrap QZ_bootstrap = {
    "Quartz", "Mac OS X CoreGraphics", QZ_Available, QZ_CreateDevice
};

/* Bootstrap functions */
static int QZ_Available () {
    return 1;
}

static SDL_VideoDevice* QZ_CreateDevice (int device_index) {

#pragma unused (device_index)

    SDL_VideoDevice *device;
    SDL_PrivateVideoData *hidden;

    device = (SDL_VideoDevice*) malloc (sizeof (*device) );
    hidden = (SDL_PrivateVideoData*) malloc (sizeof (*hidden) );

    if (device == NULL || hidden == NULL)
        SDL_OutOfMemory ();

    memset (device, 0, sizeof (*device) );
    memset (hidden, 0, sizeof (*hidden) );

    device->hidden = hidden;

    device->VideoInit        = QZ_VideoInit;
    device->ListModes        = QZ_ListModes;
    device->SetVideoMode     = QZ_SetVideoMode;
    device->ToggleFullScreen = QZ_ToggleFullScreen;
    device->SetColors        = QZ_SetColors;
    /* device->UpdateRects      = QZ_UpdateRects; this is determined by SetVideoMode() */
    device->VideoQuit        = QZ_VideoQuit;

    device->LockHWSurface   = QZ_LockHWSurface;
    device->UnlockHWSurface = QZ_UnlockHWSurface;
    device->FreeHWSurface   = QZ_FreeHWSurface;
    /* device->FlipHWSurface   = QZ_FlipHWSurface */;

    device->SetGamma     = QZ_SetGamma;
    device->GetGamma     = QZ_GetGamma;
    device->SetGammaRamp = QZ_SetGammaRamp;
    device->GetGammaRamp = QZ_GetGammaRamp;

    device->GL_GetProcAddress = QZ_GL_GetProcAddress;
    device->GL_GetAttribute   = QZ_GL_GetAttribute;
    device->GL_MakeCurrent    = QZ_GL_MakeCurrent;
    device->GL_SwapBuffers    = QZ_GL_SwapBuffers;
    device->GL_LoadLibrary    = QZ_GL_LoadLibrary;

    device->FreeWMCursor   = QZ_FreeWMCursor;
    device->CreateWMCursor = QZ_CreateWMCursor;
    device->ShowWMCursor   = QZ_ShowWMCursor;
    device->WarpWMCursor   = QZ_WarpWMCursor;
    device->MoveWMCursor   = QZ_MoveWMCursor;
    device->CheckMouseMode = QZ_CheckMouseMode;
    device->InitOSKeymap   = QZ_InitOSKeymap;
    device->PumpEvents     = QZ_PumpEvents;

    device->SetCaption    = QZ_SetCaption;
    device->SetIcon       = QZ_SetIcon;
    device->IconifyWindow = QZ_IconifyWindow;
    /*device->GetWMInfo     = QZ_GetWMInfo;*/
    device->GrabInput     = QZ_GrabInput;

    device->free = QZ_DeleteDevice;

    return device;
}

static void QZ_DeleteDevice (SDL_VideoDevice *device) {

    free (device->hidden);
    free (device);
}

static int QZ_VideoInit (_THIS, SDL_PixelFormat *video_format) {

    /* Initialize the video settings; this data persists between mode switches */
    display_id = kCGDirectMainDisplay;
    save_mode  = CGDisplayCurrentMode    (display_id);
    mode_list  = CGDisplayAvailableModes (display_id);
    palette    = CGPaletteCreateDefaultColorPalette ();

    /* Gather some information that is useful to know about the display */
    CFNumberGetValue (CFDictionaryGetValue (save_mode, kCGDisplayBitsPerPixel),
                      kCFNumberSInt32Type, &device_bpp);

    CFNumberGetValue (CFDictionaryGetValue (save_mode, kCGDisplayWidth),
                      kCFNumberSInt32Type, &device_width);

    CFNumberGetValue (CFDictionaryGetValue (save_mode, kCGDisplayHeight),
                      kCFNumberSInt32Type, &device_height);

    video_format->BitsPerPixel = device_bpp;

    return 0;
}

static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) {
    
    CFIndex num_modes;
    CFIndex i;

    static SDL_Rect **list = NULL;
    int list_size = 0;
    
    /* Any windowed mode is acceptable */
    if ( (flags & SDL_FULLSCREEN) == 0 )
        return (SDL_Rect**)-1;
        
    /* Free memory from previous call, if any */
    if ( list != NULL ) {

      int i;

      for (i = 0; list[i] != NULL; i++)
	free (list[i]);

      free (list);
      list = NULL;
    }
    
    num_modes = CFArrayGetCount (mode_list);

    /* Build list of modes with the requested bpp */
    for (i = 0; i < num_modes; i++) {
   
        CFDictionaryRef onemode;
        CFNumberRef     number;
	int bpp;
	
        onemode = CFArrayGetValueAtIndex (mode_list, i); 
	number = CFDictionaryGetValue (onemode, kCGDisplayBitsPerPixel);
	CFNumberGetValue (number, kCFNumberSInt32Type, &bpp);

	if (bpp == format->BitsPerPixel) {
	  
	  int intvalue;
          int hasMode;
          int width, height;
          
	  number = CFDictionaryGetValue (onemode, kCGDisplayWidth);
	  CFNumberGetValue (number, kCFNumberSInt32Type, &intvalue);
	  width = (Uint16) intvalue;
	  
	  number = CFDictionaryGetValue (onemode, kCGDisplayHeight);
	  CFNumberGetValue (number, kCFNumberSInt32Type, &intvalue);
	  height = (Uint16) intvalue;
          
          /* Check if mode is already in the list */
          {
            int i;
            hasMode = SDL_FALSE;
            for (i = 0; i < list_size; i++) {
                if (list[i]->w == width && list[i]->h == height) {
                    hasMode = SDL_TRUE;
                    break;
                }
            }
          }
          
          /* Grow the list and add mode to the list */
          if ( ! hasMode ) {
	  
            SDL_Rect *rect;
            
            list_size++;

            if (list == NULL)
                list = (SDL_Rect**) malloc (sizeof(*list) * (list_size+1) );
            else
                list = (SDL_Rect**) realloc (list, sizeof(*list) * (list_size+1));
            
            rect = (SDL_Rect*) malloc (sizeof(**list));
            
            if (list == NULL || rect == NULL) {
                SDL_OutOfMemory ();
                return NULL;
            }
            
            rect->w = width;
            rect->h = height;
    
            list[list_size-1] = rect;
            list[list_size]   = NULL;
        }
      }
    }
    
    /* Sort list largest to smallest (by area) */
    {
        int i, j;
        for (i = 0; i < list_size; i++) {
            for (j = 0; j < list_size-1; j++) {
            
                int area1, area2;
                area1 = list[j]->w * list[j]->h;
                area2 = list[j+1]->w * list[j+1]->h;
                
                if (area1 < area2) {
                    SDL_Rect *tmp = list[j];
                    list[j] = list[j+1];
                    list[j+1] = tmp;
                }
            }
        }
    }
    return list;
}

/* Gamma functions to try to hide the flash from a rez switch */
/* Fade the display from normal to black */
/* Save gamma tables for fade back to normal */
static UInt32 QZ_FadeGammaOut (_THIS, SDL_QuartzGammaTable *table) {

    CGGammaValue redTable[QZ_GAMMA_TABLE_SIZE],
    greenTable[QZ_GAMMA_TABLE_SIZE],
    blueTable[QZ_GAMMA_TABLE_SIZE];

    float percent;
    int j;
    int actual;

    if ( (CGDisplayNoErr != CGGetDisplayTransferByTable
          (display_id, QZ_GAMMA_TABLE_SIZE,
           table->red, table->green, table->blue, &actual)) ||
         actual != QZ_GAMMA_TABLE_SIZE) {

        return 1;
    }

    memcpy (redTable, table->red, sizeof(redTable));
    memcpy (greenTable, table->green, sizeof(greenTable));
    memcpy (blueTable, table->blue, sizeof(greenTable));

    for (percent = 1.0; percent >= 0.0; percent -= 0.01) {

        for (j = 0; j < QZ_GAMMA_TABLE_SIZE; j++) {

            redTable[j]   = redTable[j]   * percent;
            greenTable[j] = greenTable[j] * percent;
            blueTable[j]  = blueTable[j]  * percent;
        }

        if (CGDisplayNoErr != CGSetDisplayTransferByTable
            (display_id, QZ_GAMMA_TABLE_SIZE,
             redTable, greenTable, blueTable)) {

            CGDisplayRestoreColorSyncSettings();
            return 1;
        }

        SDL_Delay (10);
    }

    return 0;
}

/* Fade the display from black to normal */
/* Restore previously saved gamma values */
static UInt32 QZ_FadeGammaIn (_THIS, SDL_QuartzGammaTable *table) {

    CGGammaValue redTable[QZ_GAMMA_TABLE_SIZE],
        greenTable[QZ_GAMMA_TABLE_SIZE],
        blueTable[QZ_GAMMA_TABLE_SIZE];

    float percent;
    int j;

    memset (redTable, 0, sizeof(redTable));
    memset (greenTable, 0, sizeof(greenTable));
    memset (blueTable, 0, sizeof(greenTable));
    
    for (percent = 0.0; percent <= 1.0; percent += 0.01) {

        for (j = 0; j < QZ_GAMMA_TABLE_SIZE; j++) {

            redTable[j]   = table->red[j]   * percent;
            greenTable[j] = table->green[j] * percent;
            blueTable[j]  = table->blue[j]  * percent;
        }

        if (CGDisplayNoErr != CGSetDisplayTransferByTable
            (display_id, QZ_GAMMA_TABLE_SIZE,
             redTable, greenTable, blueTable)) {

            CGDisplayRestoreColorSyncSettings();
            return 1;
        }

        SDL_Delay (10);
    }

    return 0;
}

static void QZ_UnsetVideoMode (_THIS) {

    /* Reset values that may change between switches */
    this->info.blit_fill = 0;
    this->FillHWRect     = NULL;
    this->UpdateRects    = NULL;
   
    /* Release fullscreen resources */
    if ( mode_flags & SDL_FULLSCREEN ) {

        SDL_QuartzGammaTable gamma_table;
        int gamma_error;

        gamma_error = QZ_FadeGammaOut (this, &gamma_table);

        /* Release the OpenGL context */
        /* Do this first to avoid trash on the display before fade */
        if ( mode_flags & SDL_OPENGL )
            QZ_TearDownOpenGL (this);
        
        if (mode_flags & SDL_OPENGL)
            CGLSetFullScreen(NULL);

        /* Restore original screen resolution/bpp */
        CGDisplaySwitchToMode (display_id, save_mode);
        CGDisplayRelease (display_id);
        ShowMenuBar ();
        
        if (! gamma_error)
            QZ_FadeGammaIn (this, &gamma_table);
    }
    /* Release window mode resources */
    else { 
        if ( (mode_flags & SDL_OPENGL) == 0 ) {
            UnlockPortBits ( [ window_view qdPort ] );
            [ window_view release  ];
        }
        [ qz_window setContentView:nil ];
        [ qz_window setDelegate:nil ];
        [ qz_window close ];
        [ qz_window release ];

        /* Release the OpenGL context */
        if ( mode_flags & SDL_OPENGL )
            QZ_TearDownOpenGL (this);
    }

    /* Restore gamma settings */
    CGDisplayRestoreColorSyncSettings ();
    
    /* Set pixels to null (so other code doesn't try to free it) */
    if (this->screen != NULL)
        this->screen->pixels = NULL;
        
    /* Ensure the cursor will be visible and working when we quit */
    CGDisplayShowCursor (display_id);
    CGAssociateMouseAndMouseCursorPosition (1);
    
    /* Signal successful teardown */
    video_set = SDL_FALSE;
}

static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int width,
                                           int height, int bpp, Uint32 flags) {
    int exact_match;
    int gamma_error;
    SDL_QuartzGammaTable gamma_table;
    
    /* See if requested mode exists */
    mode = CGDisplayBestModeForParameters (display_id, bpp, width, 
					   height, &exact_match);
    
    /* Require an exact match to the requested mode */
    if ( ! exact_match ) {
        sprintf (QZ_Error, "Failed to find display resolution: %dx%dx%d", width, height, bpp);
        SDL_SetError (QZ_Error);
        goto ERR_NO_MATCH;
    }

    /* Fade display to zero gamma */
    gamma_error = QZ_FadeGammaOut (this, &gamma_table);

    /* Put up the blanking window (a window above all other windows) */
    if ( CGDisplayNoErr != CGDisplayCapture (display_id) ) {
        SDL_SetError ("Failed capturing display");

⌨️ 快捷键说明

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