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

📄 sdl_quartzvideo.m

📁 网络MPEG4IP流媒体开发源代码
💻 M
📖 第 1 页 / 共 4 页
字号:
                                           int height, int bpp, Uint32 flags) {    int exact_match;    int gamma_error;    SDL_QuartzGammaTable gamma_table;    NSRect screen_rect;        /* Destroy any previous mode */    if (video_set == SDL_TRUE)        QZ_UnsetVideoMode (this);    /* 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 ) {        SDL_SetError ("Failed to find display resolution: %dx%dx%d", width, height, bpp);        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");        goto ERR_NO_CAPTURE;    }    /* Do the physical switch */    if ( CGDisplayNoErr != CGDisplaySwitchToMode (display_id, mode) ) {        SDL_SetError ("Failed switching display resolution");        goto ERR_NO_SWITCH;    }    current->pixels = (Uint32*) CGDisplayBaseAddress (display_id);    current->pitch  = CGDisplayBytesPerRow (display_id);    current->flags = 0;    current->w = width;    current->h = height;    current->flags |= SDL_FULLSCREEN;    current->flags |= SDL_HWSURFACE;    current->flags |= SDL_PREALLOC;        this->UpdateRects     = QZ_DirectUpdate;    this->LockHWSurface   = QZ_LockHWSurface;    this->UnlockHWSurface = QZ_UnlockHWSurface;        /* Setup some mode-dependant info */    if ( CGSDisplayCanHWFill (display_id) ) {        this->info.blit_fill = 1;        this->FillHWRect = QZ_FillHWRect;    }    if ( CGDisplayCanSetPalette (display_id) )        current->flags |= SDL_HWPALETTE;    /* Setup OpenGL for a fullscreen context */    if (flags & SDL_OPENGL) {        CGLError err;        CGLContextObj ctx;        if ( ! QZ_SetupOpenGL (this, bpp, flags) ) {            goto ERR_NO_GL;        }        ctx = [ gl_context cglContext ];        err = CGLSetFullScreen (ctx);        if (err) {            SDL_SetError ("Error setting OpenGL fullscreen: %s", CGLErrorString(err));            goto ERR_NO_GL;        }        [ gl_context makeCurrentContext];        glClear (GL_COLOR_BUFFER_BIT);        [ gl_context flushBuffer ];        current->flags |= SDL_OPENGL;    }    /* If we don't hide menu bar, it will get events and interrupt the program */    HideMenuBar ();    /* Fade the display to original gamma */    if (! gamma_error )        QZ_FadeGammaIn (this, &gamma_table);    /*         There is a bug in Cocoa where NSScreen doesn't synchronize        with CGDirectDisplay, so the main screen's frame is wrong.        As a result, coordinate translation produces incorrect results.        We can hack around this bug by setting the screen rect        ourselves. This hack should be removed if/when the bug is fixed.    */    screen_rect = NSMakeRect(0,0,width,height);    [ [ NSScreen mainScreen ] setFrame:screen_rect ];     /* Save the flags to ensure correct tear-down */    mode_flags = current->flags;    return current;    /* Since the blanking window covers *all* windows (even force quit) correct recovery is crucial */ERR_NO_GL:      CGDisplaySwitchToMode (display_id, save_mode);ERR_NO_SWITCH:  CGDisplayRelease (display_id);ERR_NO_CAPTURE: if (!gamma_error) { QZ_FadeGammaIn (this, &gamma_table); }ERR_NO_MATCH:    return NULL;}static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,                                         int height, int bpp, Uint32 flags) {    unsigned int style;    NSRect contentRect;    current->flags = 0;    current->w = width;    current->h = height;        contentRect = NSMakeRect (0, 0, width, height);        /*        Check if we should completely destroy the previous mode         - If it is fullscreen        - If it has different noframe or resizable attribute        - If it is OpenGL (since gl attributes could be different)        - If new mode is OpenGL, but previous mode wasn't    */    if (video_set == SDL_TRUE)        if ( (mode_flags & SDL_FULLSCREEN) ||             ((mode_flags ^ flags) & (SDL_NOFRAME|SDL_RESIZABLE)) ||             (mode_flags & SDL_OPENGL) ||              (flags & SDL_OPENGL) )            QZ_UnsetVideoMode (this);            /* Check if we should recreate the window */    if (qz_window == nil) {            /* Set the window style based on input flags */        if ( flags & SDL_NOFRAME ) {            style = NSBorderlessWindowMask;            current->flags |= SDL_NOFRAME;        } else {            style = NSTitledWindowMask;            style |= (NSMiniaturizableWindowMask | NSClosableWindowMask);            if ( flags & SDL_RESIZABLE ) {                style |= NSResizableWindowMask;                current->flags |= SDL_RESIZABLE;            }        }                        /* Manually create a window, avoids having a nib file resource */        qz_window = [ [ SDL_QuartzWindow alloc ]             initWithContentRect:contentRect                styleMask:style                     backing:NSBackingStoreBuffered                        defer:NO ];                                  if (qz_window == nil) {            SDL_SetError ("Could not create the Cocoa window");            return NULL;        }            [ qz_window setReleasedWhenClosed:YES ];        QZ_SetCaption(this, this->wm_title, this->wm_icon);        [ qz_window setAcceptsMouseMovedEvents:YES ];        [ qz_window setViewsNeedDisplay:NO ];        [ qz_window center ];        [ qz_window setDelegate:            [ [ [ SDL_QuartzWindowDelegate alloc ] init ] autorelease ] ];    }    /* We already have a window, just change its size */    else {            [ qz_window setContentSize:contentRect.size ];        current->flags |= (SDL_NOFRAME|SDL_RESIZABLE) & mode_flags;    }    /* For OpenGL, we bind the context to a subview */    if ( flags & SDL_OPENGL ) {        if ( ! QZ_SetupOpenGL (this, bpp, flags) ) {            return NULL;        }        window_view = [ [ NSView alloc ] initWithFrame:contentRect ];        [ window_view setAutoresizingMask: NSViewMinYMargin ];        [ [ qz_window contentView ] addSubview:window_view ];        [ gl_context setView: window_view ];        [ window_view release ];        [ gl_context makeCurrentContext];        [ qz_window makeKeyAndOrderFront:nil ];        current->flags |= SDL_OPENGL;    }    /* For 2D, we set the subview to an NSQuickDrawView */    else {        /* Only recreate the view if it doesn't already exist */        if (window_view == nil) {                    window_view = [ [ SDL_QuartzWindowView alloc ] initWithFrame:contentRect ];            [ window_view setAutoresizingMask: NSViewMinYMargin ];            [ [ qz_window contentView ] addSubview:window_view ];            [ window_view release ];            [ qz_window makeKeyAndOrderFront:nil ];        }                LockPortBits ( [ window_view qdPort ] );        current->pixels = GetPixBaseAddr ( GetPortPixMap ( [ window_view qdPort ] ) );        current->pitch  = GetPixRowBytes ( GetPortPixMap ( [ window_view qdPort ] ) );        UnlockPortBits ( [ window_view qdPort ] );        current->flags |= SDL_SWSURFACE;        current->flags |= SDL_PREALLOC;        current->flags |= SDL_ASYNCBLIT;                /* Offset below the title bar to fill the full content region */        current->pixels += ((int)([ qz_window frame ].size.height) - height) * current->pitch;        this->UpdateRects     = QZ_UpdateRects;        this->LockHWSurface   = QZ_LockWindow;        this->UnlockHWSurface = QZ_UnlockWindow;    }    /* Save flags to ensure correct teardown */    mode_flags = current->flags;    return current;}static SDL_Surface* QZ_SetVideoMode (_THIS, SDL_Surface *current, int width,                                     int height, int bpp, Uint32 flags) {    current->flags = 0;    /* 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 -1;}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 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.*/static int QZ_IsWindowObscured (NSWindow *window) {    //#define TEST_OBSCURED 1#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     isMainWindow;    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 ];            //isMainWindow = [ window isMainWindow ];            /* The window list is sorted according to order on the screen */            count = 0;

⌨️ 快捷键说明

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