📄 sdl_quartzvideo.m
字号:
}
else if (winLevel == kCGSWindowLevelDock) {
/* Create dock icon cache */
if (numCachedDockIcons != (i-firstDockIcon) ||
dockIconCacheMiss) {
numCachedDockIcons = i - firstDockIcon;
memcpy (dockIcons, &(windows[firstDockIcon]),
numCachedDockIcons * sizeof(*windows));
}
/* no shadow */
shadowSide = 0;
shadowTop = 0;
shadowBottom = 0;
}
else {
/* kCGSWindowLevelDockLabel,
kCGSWindowLevelDock,
kOther??? */
/* no shadow */
shadowSide = 0;
shadowTop = 0;
shadowBottom = 0;
}
CGSGetScreenRectForWindow (cgsConnection, windows[i], &winRect);
winRect.origin.x -= shadowSide;
winRect.origin.y -= shadowTop;
winRect.size.width += shadowSide;
winRect.size.height += shadowBottom;
if (NSIntersectsRect (contentRect, winRect)) {
obscured = SDL_TRUE;
break;
}
} /* window was not our window */
} /* iterate over windows */
} /* get cgsConnection */
} /* window is visible */
return obscured;
#else
return SDL_TRUE;
#endif
}
static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) {
if (SDL_VideoSurface->flags & SDL_OPENGLBLIT) {
QZ_GL_SwapBuffers (this);
}
else if ( [ qz_window isMiniaturized ] &&
! (SDL_VideoSurface->flags & SDL_OPENGL)) {
/**
* Set port alpha opaque so deminiaturize looks right
* This isn't so nice, but there is no
* initial deminatureize notification (before demini starts)
**/
QZ_SetPortAlphaOpaque ([ [ qz_window contentView ] qdPort],
[ qz_window styleMask ] & NSBorderlessWindowMask);
}
else if ( ! QZ_IsWindowObscured (qz_window) ) {
/* Use direct copy to flush contents to the display */
CGrafPtr savePort;
CGrafPtr dstPort, srcPort;
const BitMap *dstBits, *srcBits;
Rect dstRect, srcRect;
Point offset;
int i;
GetPort (&savePort);
dstPort = CreateNewPortForCGDisplayID ((UInt32)display_id);
srcPort = [ window_view qdPort ];
offset.h = 0;
offset.v = 0;
SetPort (srcPort);
LocalToGlobal (&offset);
SetPort (dstPort);
LockPortBits (dstPort);
LockPortBits (srcPort);
dstBits = GetPortBitMapForCopyBits (dstPort);
srcBits = GetPortBitMapForCopyBits (srcPort);
for (i = 0; i < numRects; i++) {
SetRect (&srcRect, rects[i].x, rects[i].y,
rects[i].x + rects[i].w,
rects[i].y + rects[i].h);
SetRect (&dstRect,
rects[i].x + offset.h,
rects[i].y + offset.v,
rects[i].x + rects[i].w + offset.h,
rects[i].y + rects[i].h + offset.v);
CopyBits (srcBits, dstBits,
&srcRect, &dstRect, srcCopy, NULL);
}
SetPort (savePort);
}
else {
/* Use QDFlushPortBuffer() to flush content to display */
int i;
RgnHandle dirty = NewRgn ();
RgnHandle temp = NewRgn ();
SetEmptyRgn (dirty);
/* Build the region of dirty rectangles */
for (i = 0; i < numRects; i++) {
MacSetRectRgn (temp, rects[i].x, rects[i].y,
rects[i].x + rects[i].w, rects[i].y + rects[i].h);
MacUnionRgn (dirty, temp, dirty);
}
/* Flush the dirty region */
QDFlushPortBuffer ( [ window_view qdPort ], dirty );
DisposeRgn (dirty);
DisposeRgn (temp);
}
}
static void QZ_VideoQuit (_THIS) {
QZ_UnsetVideoMode (this);
CGPaletteRelease (palette);
}
static int QZ_FillHWRect (_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color) {
CGSDisplayHWFill (display_id, rect->x, rect->y, rect->w, rect->h, color);
return 0;
}
static int QZ_LockHWSurface(_THIS, SDL_Surface *surface) {
return 1;
}
static void QZ_UnlockHWSurface(_THIS, SDL_Surface *surface) {
}
static void QZ_FreeHWSurface (_THIS, SDL_Surface *surface) {
}
/*
int QZ_FlipHWSurface (_THIS, SDL_Surface *surface) {
return 0;
}
*/
/* Gamma functions */
static int QZ_SetGamma (_THIS, float red, float green, float blue) {
const CGGammaValue min = 0.0, max = 1.0;
if (red == 0.0)
red = FLT_MAX;
else
red = 1.0 / red;
if (green == 0.0)
green = FLT_MAX;
else
green = 1.0 / green;
if (blue == 0.0)
blue = FLT_MAX;
else
blue = 1.0 / blue;
if ( CGDisplayNoErr == CGSetDisplayTransferByFormula
(display_id, min, max, red, min, max, green, min, max, blue) ) {
return 0;
}
else {
return -1;
}
}
static int QZ_GetGamma (_THIS, float *red, float *green, float *blue) {
CGGammaValue dummy;
if ( CGDisplayNoErr == CGGetDisplayTransferByFormula
(display_id, &dummy, &dummy, red,
&dummy, &dummy, green, &dummy, &dummy, blue) )
return 0;
else
return -1;
}
static int QZ_SetGammaRamp (_THIS, Uint16 *ramp) {
const CGTableCount tableSize = 255;
CGGammaValue redTable[tableSize];
CGGammaValue greenTable[tableSize];
CGGammaValue blueTable[tableSize];
int i;
/* Extract gamma values into separate tables, convert to floats between 0.0 and 1.0 */
for (i = 0; i < 256; i++)
redTable[i % 256] = ramp[i] / 65535.0;
for (i=256; i < 512; i++)
greenTable[i % 256] = ramp[i] / 65535.0;
for (i=512; i < 768; i++)
blueTable[i % 256] = ramp[i] / 65535.0;
if ( CGDisplayNoErr == CGSetDisplayTransferByTable
(display_id, tableSize, redTable, greenTable, blueTable) )
return 0;
else
return -1;
}
static int QZ_GetGammaRamp (_THIS, Uint16 *ramp) {
const CGTableCount tableSize = 255;
CGGammaValue redTable[tableSize];
CGGammaValue greenTable[tableSize];
CGGammaValue blueTable[tableSize];
CGTableCount actual;
int i;
if ( CGDisplayNoErr != CGGetDisplayTransferByTable
(display_id, tableSize, redTable, greenTable, blueTable, &actual) ||
actual != tableSize)
return -1;
/* Pack tables into one array, with values from 0 to 65535 */
for (i = 0; i < 256; i++)
ramp[i] = redTable[i % 256] * 65535.0;
for (i=256; i < 512; i++)
ramp[i] = greenTable[i % 256] * 65535.0;
for (i=512; i < 768; i++)
ramp[i] = blueTable[i % 256] * 65535.0;
return 0;
}
/* OpenGL helper functions (used internally) */
static int QZ_SetupOpenGL (_THIS, int bpp, Uint32 flags) {
NSOpenGLPixelFormatAttribute attr[32];
NSOpenGLPixelFormat *fmt;
int i = 0;
int colorBits = bpp;
if ( flags & SDL_FULLSCREEN ) {
attr[i++] = NSOpenGLPFAFullScreen;
}
/* In windowed mode, the OpenGL pixel depth must match device pixel depth */
else if ( colorBits != device_bpp ) {
colorBits = device_bpp;
}
attr[i++] = NSOpenGLPFAColorSize;
attr[i++] = colorBits;
attr[i++] = NSOpenGLPFADepthSize;
attr[i++] = this->gl_config.depth_size;
if ( this->gl_config.double_buffer ) {
attr[i++] = NSOpenGLPFADoubleBuffer;
}
if ( this->gl_config.stencil_size != 0 ) {
attr[i++] = NSOpenGLPFAStencilSize;
attr[i++] = this->gl_config.stencil_size;
}
attr[i++] = NSOpenGLPFAScreenMask;
attr[i++] = CGDisplayIDToOpenGLDisplayMask (display_id);
attr[i] = 0;
fmt = [ [ NSOpenGLPixelFormat alloc ] initWithAttributes:attr ];
if (fmt == nil) {
SDL_SetError ("Failed creating OpenGL pixel format");
return 0;
}
gl_context = [ [ NSOpenGLContext alloc ] initWithFormat:fmt
shareContext:nil];
if (gl_context == nil) {
SDL_SetError ("Failed creating OpenGL context");
return 0;
}
/* Convince SDL that the GL "driver" is loaded */
this->gl_config.driver_loaded = 1;
[ fmt release ];
return 1;
}
static void QZ_TearDownOpenGL (_THIS) {
[ NSOpenGLContext clearCurrentContext ];
[ gl_context clearDrawable ];
[ gl_context release ];
}
/* SDL OpenGL functions */
static int QZ_GL_LoadLibrary (_THIS, const char *location) {
this->gl_config.driver_loaded = 1;
return 1;
}
static void* QZ_GL_GetProcAddress (_THIS, const char *proc) {
/* We may want to cache the bundleRef at some point */
CFBundleRef bundle;
CFURLRef bundleURL = CFURLCreateWithFileSystemPath (kCFAllocatorDefault,
CFSTR("/System/Library/Frameworks/OpenGL.framework"), kCFURLPOSIXPathStyle, true);
CFStringRef functionName = CFStringCreateWithCString
(kCFAllocatorDefault, proc, kCFStringEncodingASCII);
void *function;
bundle = CFBundleCreate (kCFAllocatorDefault, bundleURL);
assert (bundle != NULL);
function = CFBundleGetFunctionPointerForName (bundle, functionName);
CFRelease ( bundleURL );
CFRelease ( functionName );
CFRelease ( bundle );
return function;
}
static int QZ_GL_GetAttribute (_THIS, SDL_GLattr attrib, int* value) {
GLenum attr = 0;
QZ_GL_MakeCurrent (this);
switch (attrib) {
case SDL_GL_RED_SIZE: attr = GL_RED_BITS; break;
case SDL_GL_BLUE_SIZE: attr = GL_BLUE_BITS; break;
case SDL_GL_GREEN_SIZE: attr = GL_GREEN_BITS; break;
case SDL_GL_ALPHA_SIZE: attr = GL_ALPHA_BITS; break;
case SDL_GL_DOUBLEBUFFER: attr = GL_DOUBLEBUFFER; break;
case SDL_GL_DEPTH_SIZE: attr = GL_DEPTH_BITS; break;
case SDL_GL_STENCIL_SIZE: attr = GL_STENCIL_BITS; break;
case SDL_GL_ACCUM_RED_SIZE: attr = GL_ACCUM_RED_BITS; break;
case SDL_GL_ACCUM_GREEN_SIZE: attr = GL_ACCUM_GREEN_BITS; break;
case SDL_GL_ACCUM_BLUE_SIZE: attr = GL_ACCUM_BLUE_BITS; break;
case SDL_GL_ACCUM_ALPHA_SIZE: attr = GL_ACCUM_ALPHA_BITS; break;
case SDL_GL_BUFFER_SIZE:
{
GLint bits = 0;
GLint component;
/* there doesn't seem to be a single flag in OpenGL for this! */
glGetIntegerv (GL_RED_BITS, &component); bits += component;
glGetIntegerv (GL_GREEN_BITS,&component); bits += component;
glGetIntegerv (GL_BLUE_BITS, &component); bits += component;
glGetIntegerv (GL_ALPHA_BITS, &component); bits += component;
*value = bits;
}
return 0;
}
glGetIntegerv (attr, (GLint *)value);
return 0;
}
static int QZ_GL_MakeCurrent (_THIS) {
[ gl_context makeCurrentContext ];
return 0;
}
static void QZ_GL_SwapBuffers (_THIS) {
[ gl_context flushBuffer ];
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -