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

📄 sdl_quartzvideo.m

📁 SDL库 在进行视频显示程序spcaview安装时必须的库文件
💻 M
📖 第 1 页 / 共 4 页
字号:
        }        this->UpdateRects     = QZ_UpdateRects;        this->LockHWSurface   = QZ_LockWindow;        this->UnlockHWSurface = QZ_UnlockWindow;    }    /* Save flags to ensure correct teardown */    mode_flags = current->flags;    /* Fade in again (asynchronously) if we came from a fullscreen mode and faded to black */    if (fade_token != kCGDisplayFadeReservationInvalidToken) {        CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);        CGReleaseDisplayFadeReservation (fade_token);    }    return current;}static SDL_Surface* QZ_SetVideoMode (_THIS, SDL_Surface *current, int width,                                     int height, int bpp, Uint32 flags) {    current->flags = 0;    current->pixels = NULL;    /* Setup full screen video */    if ( flags & SDL_FULLSCREEN ) {        current = QZ_SetVideoFullScreen (this, current, width, height, bpp, flags );        if (current == NULL)            return NULL;    }    /* Setup windowed video */    else {        /* Force bpp to the device's bpp */        bpp = device_bpp;        current = QZ_SetVideoWindowed (this, current, width, height, &bpp, flags);        if (current == NULL)            return NULL;    }    /* Setup the new pixel format */    {        int amask = 0,        rmask = 0,        gmask = 0,        bmask = 0;        switch (bpp) {            case 16:   /* (1)-5-5-5 RGB */                amask = 0;                rmask = 0x7C00;                gmask = 0x03E0;                bmask = 0x001F;                break;            case 24:                SDL_SetError ("24bpp is not available");                return NULL;            case 32:   /* (8)-8-8-8 ARGB */                amask = 0x00000000;                rmask = 0x00FF0000;                gmask = 0x0000FF00;                bmask = 0x000000FF;                break;        }        if ( ! SDL_ReallocFormat (current, bpp,                                  rmask, gmask, bmask, amask ) ) {            SDL_SetError ("Couldn't reallocate pixel format");            return NULL;           }    }    /* Signal successful completion (used internally) */    video_set = SDL_TRUE;    return current;}static int QZ_ToggleFullScreen (_THIS, int on) {    return 0;}static int QZ_SetColors (_THIS, int first_color, int num_colors,                         SDL_Color *colors) {    CGTableCount  index;    CGDeviceColor color;    for (index = first_color; index < first_color+num_colors; index++) {        /* Clamp colors between 0.0 and 1.0 */        color.red   = colors->r / 255.0;        color.blue  = colors->b / 255.0;        color.green = colors->g / 255.0;        colors++;        CGPaletteSetColorAtIndex (palette, color, index);    }    if ( CGDisplayNoErr != CGDisplaySetPalette (display_id, palette) )        return 0;    return 1;}static int QZ_LockDoubleBuffer (_THIS, SDL_Surface *surface) {    return 1;}static void QZ_UnlockDoubleBuffer (_THIS, SDL_Surface *surface) {} /* The VBL delay is based on code by Ian R Ollmann's RezLib <iano@cco.caltech.edu> */ static AbsoluteTime QZ_SecondsToAbsolute ( double seconds ) {        union    {        UInt64 i;        Nanoseconds ns;    } temp;            temp.i = seconds * 1000000000.0;        return NanosecondsToAbsolute ( temp.ns );}static int QZ_ThreadFlip (_THIS) {    Uint8 *src, *dst;    int skip, len, h;        /*        Give this thread the highest scheduling priority possible,        in the hopes that it will immediately run after the VBL delay    */    {        pthread_t current_thread;        int policy;        struct sched_param param;                current_thread = pthread_self ();        pthread_getschedparam (current_thread, &policy, &param);        policy = SCHED_RR;        param.sched_priority = sched_get_priority_max (policy);        pthread_setschedparam (current_thread, policy, &param);    }        while (1) {            SDL_SemWait (sem1);        if (quit_thread)            return 0;                        /*         * We have to add SDL_VideoSurface->offset here, since we might be a         *  smaller surface in the center of the framebuffer (you asked for         *  a fullscreen resolution smaller than the hardware could supply         *  so SDL is centering it in a bigger resolution)...         */        dst = (Uint8 *)CGDisplayBaseAddress (display_id) + SDL_VideoSurface->offset;        src = current_buffer + SDL_VideoSurface->offset;        len = SDL_VideoSurface->w * SDL_VideoSurface->format->BytesPerPixel;        h = SDL_VideoSurface->h;        skip = SDL_VideoSurface->pitch;            /* Wait for the VBL to occur (estimated since we don't have a hardware interrupt) */        {                        /* The VBL delay is based on Ian Ollmann's RezLib <iano@cco.caltech.edu> */            double refreshRate;            double linesPerSecond;            double target;            double position;            double adjustment;            AbsoluteTime nextTime;                    CFNumberRef refreshRateCFNumber;                        refreshRateCFNumber = CFDictionaryGetValue (mode, kCGDisplayRefreshRate);            if ( NULL == refreshRateCFNumber ) {                SDL_SetError ("Mode has no refresh rate");                goto ERROR;            }                        if ( 0 == CFNumberGetValue (refreshRateCFNumber, kCFNumberDoubleType, &refreshRate) ) {                SDL_SetError ("Error getting refresh rate");                goto ERROR;            }                        if ( 0 == refreshRate ) {                              SDL_SetError ("Display has no refresh rate, using 60hz");                                /* ok, for LCD's we'll emulate a 60hz refresh, which may or may not look right */                refreshRate = 60.0;            }                        linesPerSecond = refreshRate * h;            target = h;                    /* Figure out the first delay so we start off about right */            position = CGDisplayBeamPosition (display_id);            if (position > target)                position = 0;                        adjustment = (target - position) / linesPerSecond;                         nextTime = AddAbsoluteToAbsolute (UpTime (), QZ_SecondsToAbsolute (adjustment));                    MPDelayUntil (&nextTime);        }                        /* On error, skip VBL delay */        ERROR:                while ( h-- ) {                    SDL_memcpy (dst, src, len);            src += skip;            dst += skip;        }                /* signal flip completion */        SDL_SemPost (sem2);    }        return 0;}        static int QZ_FlipDoubleBuffer (_THIS, SDL_Surface *surface) {    /* wait for previous flip to complete */    SDL_SemWait (sem2);        current_buffer = surface->pixels;            if (surface->pixels == sw_buffers[0])        surface->pixels = sw_buffers[1];    else        surface->pixels = sw_buffers[0];        /* signal worker thread to do the flip */    SDL_SemPost (sem1);        return 0;}static void QZ_DoubleBufferUpdate (_THIS, int num_rects, SDL_Rect *rects) {    /* perform a flip if someone calls updaterects on a doublebuferred surface */    this->FlipHWSurface (this, SDL_VideoSurface);}static void QZ_DirectUpdate (_THIS, int num_rects, SDL_Rect *rects) {#pragma unused(this,num_rects,rects)}/*    The obscured code is based on work by Matt Slot fprefect@ambrosiasw.com,    who supplied sample code for Carbon.*//*#define TEST_OBSCURED 1*/#if TEST_OBSCURED#include "CGS.h"#endifstatic int QZ_IsWindowObscured (NSWindow *window) {#if TEST_OBSCURED    /*          In order to determine if a direct copy to the screen is possible,        we must figure out if there are any windows covering ours (including shadows).        This can be done by querying the window server about the on screen        windows for their screen rectangle and window level.        The procedure used below is puts accuracy before speed; however, it aims to call        the window server the fewest number of times possible to keep things reasonable.        In my testing on a 300mhz G3, this routine typically takes < 2 ms. -DW        Notes:        -Calls into the Window Server involve IPC which is slow.        -Getting a rectangle seems slower than getting the window level        -The window list we get back is in sorted order, top to bottom        -On average, I suspect, most windows above ours are dock icon windows (hence optimization)        -Some windows above ours are always there, and cannot move or obscure us (menu bar)        Bugs:        -no way (yet) to deactivate direct drawing when a window is dragged,        or suddenly obscured, so drawing continues and can produce garbage        We need some kind of locking mechanism on window movement to prevent this            -deactivated normal windows use activated normal        window shadows (slight inaccuraccy)    */    /* Cache the connection to the window server */    static CGSConnectionID    cgsConnection = (CGSConnectionID) -1;    /* Cache the dock icon windows */    static CGSWindowID          dockIcons[kMaxWindows];    static int                  numCachedDockIcons = 0;    CGSWindowID                windows[kMaxWindows];    CGSWindowCount             i, count;    CGSWindowLevel             winLevel;    CGSRect                    winRect;    CGSRect contentRect;    int     windowNumber;    int     firstDockIcon;    int     dockIconCacheMiss;    int     windowContentOffset;    int     obscured = SDL_TRUE;    if ( [ window isVisible ] ) {        /*              walk the window list looking for windows over top of            (or casting a shadow on) ours         */        /*            Get a connection to the window server           Should probably be moved out into SetVideoMode() or InitVideo()        */        if (cgsConnection == (CGSConnectionID) -1) {            cgsConnection = (CGSConnectionID) 0;            cgsConnection = _CGSDefaultConnection ();        }        if (cgsConnection) {            if ( ! [ window styleMask ] & NSBorderlessWindowMask )                windowContentOffset = 22;            else                windowContentOffset = 0;            windowNumber = [ window windowNumber ];            /* The window list is sorted according to order on the screen */            count = 0;            CGSGetOnScreenWindowList (cgsConnection, 0, kMaxWindows, windows, &count);            CGSGetScreenRectForWindow (cgsConnection, windowNumber, &contentRect);            /* adjust rect for window title bar (if present) */            contentRect.origin.y    += windowContentOffset;            contentRect.size.height -= windowContentOffset;            firstDockIcon = -1;            dockIconCacheMiss = SDL_FALSE;            /*                 The first window is always an empty window with level kCGSWindowLevelTop                so start at index 1            */            for (i = 1; i < count; i++) {                /* If we reach our window in the list, it cannot be obscured */                if (windows[i] == windowNumber) {                    obscured = SDL_FALSE;                    break;                }                else {                    float shadowSide;                    float shadowTop;                    float shadowBottom;                    CGSGetWindowLevel (cgsConnection, windows[i], &winLevel);                    if (winLevel == kCGSWindowLevelDockIcon) {                        int j;                        if (firstDockIcon < 0) {                            firstDockIcon = i;                            if (numCachedDockIcons > 0) {                                for (j = 0; j < numCachedDockIcons; j++) {                                    if (windows[i] == dockIcons[j])                                        i++;                                    else                                        break;                                }                                if (j != 0) {                                    i--;                                    if (j < numCachedDockIcons) {                                        dockIconCacheMiss = SDL_TRUE;                                    }                                }                            }                        }                        continue;                    }                    else if (winLevel == kCGSWindowLevelMenuIgnore                             /* winLevel == kCGSWindowLevelTop */) {                        continue; /* cannot obscure window */                    }                    else if (winLevel == kCGSWindowLevelDockMenu ||                             winLevel == kCGSWindowLevelMenu) {

⌨️ 快捷键说明

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