📄 sdl_quartzvideo.m
字号:
/* 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"/* 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->CreateYUVOverlay = QZ_CreateYUVOverlay; 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; /* Set misc globals */ current_grab_mode = SDL_GRAB_OFF; in_foreground = YES; return 0;}static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) { CFIndex num_modes; CFIndex i; 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 ( client_mode_list != NULL ) { int i; for (i = 0; client_mode_list[i] != NULL; i++) free (client_mode_list[i]); free (client_mode_list); client_mode_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 (client_mode_list[i]->w == width && client_mode_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 (client_mode_list == NULL) client_mode_list = (SDL_Rect**) malloc (sizeof(*client_mode_list) * (list_size+1) ); else client_mode_list = (SDL_Rect**) realloc (client_mode_list, sizeof(*client_mode_list) * (list_size+1)); rect = (SDL_Rect*) malloc (sizeof(**client_mode_list)); if (client_mode_list == NULL || rect == NULL) { SDL_OutOfMemory (); return NULL; } rect->w = width; rect->h = height; client_mode_list[list_size-1] = rect; client_mode_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 = client_mode_list[j]->w * client_mode_list[j]->h; area2 = client_mode_list[j+1]->w * client_mode_list[j+1]->h; if (area1 < area2) { SDL_Rect *tmp = client_mode_list[j]; client_mode_list[j] = client_mode_list[j+1]; client_mode_list[j+1] = tmp; } } } } return client_mode_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; this->LockHWSurface = NULL; this->UnlockHWSurface = NULL; /* Release fullscreen resources */ if ( mode_flags & SDL_FULLSCREEN ) { SDL_QuartzGammaTable gamma_table; int gamma_error; NSRect screen_rect; 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); CGLSetFullScreen (NULL); } /* Restore original screen resolution/bpp */ CGDisplaySwitchToMode (display_id, save_mode); CGDisplayRelease (display_id); ShowMenuBar (); /* Reset the main screen's rectangle See comment in QZ_SetVideoFullscreen for why we do this */ screen_rect = NSMakeRect(0,0,device_width,device_height); [ [ NSScreen mainScreen ] setFrame:screen_rect ]; if (! gamma_error) QZ_FadeGammaIn (this, &gamma_table); } /* Release window mode resources */ else { [ qz_window close ]; [ qz_window release ]; qz_window = nil; window_view = nil; /* Release the OpenGL context */ if ( mode_flags & SDL_OPENGL ) QZ_TearDownOpenGL (this); } /* Restore gamma settings */ CGDisplayRestoreColorSyncSettings (); /* 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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -