src/video/quartz/SDL_QuartzVideo.h
author Sam Lantinga
Sat, 07 Dec 2002 06:48:49 +0000
changeset 555 2536446a92de
parent 501 74262d2647ca
child 561 4bcf7dd06c47
permissions -rw-r--r--
From: Darrell Walisser
Subject: Re: [SDL] OS X and power save

Here ya go. This works just fine. One might complain that it doesn't
generate the event until after wake as completed (there is about 5
seconds between the screen coming up and the expose event), but I think
that's OK.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Library General Public
     7     License as published by the Free Software Foundation; either
     8     version 2 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Library General Public License for more details.
    14 
    15     You should have received a copy of the GNU Library General Public
    16     License along with this library; if not, write to the Free
    17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 
    23 /*    
    24     @file   SDL_QuartzVideo.h
    25     @author Darrell Walisser, Max Horn, et al.
    26     
    27     @abstract SDL video driver for Mac OS X.
    28     
    29     @discussion
    30     
    31     TODO
    32         - Hardware Cursor support with NSCursor instead of Carbon
    33         - Keyboard repeat/mouse speed adjust (if needed)
    34         - Multiple monitor support (currently only main display)
    35         - Accelerated blitting support
    36         - Fix white OpenGL window on minimize (fixed) (update: broken again on 10.2)
    37         - Find out what events should be sent/ignored if window is minimized
    38         - Find a way to deal with external resolution/depth switch while app is running
    39         - Resizeable windows (done)
    40         - Check accuracy of QZ_SetGamma()
    41     Problems:
    42         - OGL not working in full screen with software renderer
    43         - SetColors sets palette correctly but clears framebuffer
    44         - Crash in CG after several mode switches (I think this has been fixed)
    45         - Retained windows don't draw their title bar quite right (OS Bug) (not using retained windows)
    46         - Cursor in 8 bit modes is screwy (might just be Radeon PCI bug) (update: not just Radeon)
    47         - Warping cursor delays mouse events for a fraction of a second,
    48           there is a hack around this that helps a bit
    49 */
    50 
    51 #include <Cocoa/Cocoa.h>
    52 #include <OpenGL/OpenGL.h>
    53 #include <Carbon/Carbon.h>
    54 #include <QuickTime/QuickTime.h>
    55 
    56 #include "SDL_video.h"
    57 #include "SDL_error.h"
    58 #include "SDL_timer.h"
    59 #include "SDL_syswm.h"
    60 #include "SDL_sysvideo.h"
    61 #include "SDL_pixels_c.h"
    62 #include "SDL_events_c.h"
    63 
    64 /* 
    65     Add methods to get at private members of NSScreen. 
    66     Since there is a bug in Apple's screen switching code
    67     that does not update this variable when switching
    68     to fullscreen, we'll set it manually (but only for the
    69     main screen).
    70 */
    71 @interface NSScreen (NSScreenAccess)
    72 - (void) setFrame:(NSRect)frame;
    73 @end
    74 
    75 @implementation NSScreen (NSScreenAccess)
    76 - (void) setFrame:(NSRect)frame;
    77 {
    78     _frame = frame;
    79 }
    80 @end
    81 
    82 /* 
    83     This is a workaround to directly access NSOpenGLContext's CGL context
    84     We need this to check for errors NSOpenGLContext doesn't support
    85 */
    86 @interface NSOpenGLContext (CGLContextAccess)
    87 - (CGLContextObj) cglContext;
    88 @end
    89 
    90 @implementation NSOpenGLContext (CGLContextAccess)
    91 - (CGLContextObj) cglContext;
    92 {
    93     return _contextAuxiliary;
    94 }
    95 @end
    96 
    97 /* 
    98     Structure for rez switch gamma fades
    99     We can hide the monitor flicker by setting the gamma tables to 0
   100 */
   101 #define QZ_GAMMA_TABLE_SIZE 256
   102 
   103 typedef struct {
   104 
   105     CGGammaValue red[QZ_GAMMA_TABLE_SIZE];
   106     CGGammaValue green[QZ_GAMMA_TABLE_SIZE];
   107     CGGammaValue blue[QZ_GAMMA_TABLE_SIZE];
   108 
   109 } SDL_QuartzGammaTable;
   110 
   111 /* Main driver structure to store required state information */
   112 typedef struct SDL_PrivateVideoData {
   113 
   114     CGDirectDisplayID  display;            /* 0 == main display (only support single display) */
   115     CFDictionaryRef    mode;               /* current mode of the display */
   116     CFDictionaryRef    save_mode;          /* original mode of the display */
   117     CFArrayRef         mode_list;          /* list of available fullscreen modes */
   118     CGDirectPaletteRef palette;            /* palette of an 8-bit display */
   119     NSOpenGLContext    *gl_context;        /* OpenGL rendering context */
   120     Uint32             width, height, bpp; /* frequently used data about the display */
   121     Uint32             flags;              /* flags for current mode, for teardown purposes */
   122     Uint32             video_set;          /* boolean; indicates if video was set correctly */
   123     Uint32             warp_flag;          /* boolean; notify to event loop that a warp just occured */
   124     Uint32             warp_ticks;         /* timestamp when the warp occured */
   125     NSWindow           *window;            /* Cocoa window to implement the SDL window */
   126     NSQuickDrawView    *view;              /* the window's view; draw 2D and OpenGL into this view */
   127     SDL_Surface        *resize_icon;       /* icon for the resize badge, we have to draw it by hand */
   128     SDL_GrabMode       current_grab_mode;  /* default value is SDL_GRAB_OFF */
   129     BOOL               in_foreground;      /* boolean; indicate if app is in foreground or not */
   130     SDL_Rect           **client_mode_list; /* resolution list to pass back to client */
   131     SDLKey             keymap[256];        /* Mac OS X to SDL key mapping */
   132     Uint32             current_mods;       /* current keyboard modifiers, to track modifier state */
   133     Uint32             last_virtual_button;/* last virtual mouse button pressed */
   134     io_connect_t       powerConnection;    /* used with IOKit to detect wake from sleep */
   135 
   136     ImageDescriptionHandle yuv_idh;
   137     MatrixRecordPtr        yuv_matrix;
   138     DecompressorComponent  yuv_codec;
   139     ImageSequence          yuv_seq;
   140     PlanarPixmapInfoYUV420 *yuv_pixmap;
   141     Sint16                  yuv_width, yuv_height;
   142     CGrafPtr                yuv_port;
   143 
   144 } SDL_PrivateVideoData ;
   145 
   146 #define _THIS    SDL_VideoDevice *this
   147 #define display_id (this->hidden->display)
   148 #define mode (this->hidden->mode)
   149 #define save_mode (this->hidden->save_mode)
   150 #define mode_list (this->hidden->mode_list)
   151 #define palette (this->hidden->palette)
   152 #define gl_context (this->hidden->gl_context)
   153 #define device_width (this->hidden->width)
   154 #define device_height (this->hidden->height)
   155 #define device_bpp (this->hidden->bpp)
   156 #define mode_flags (this->hidden->flags)
   157 #define qz_window (this->hidden->window)
   158 #define window_view (this->hidden->view)
   159 #define video_set (this->hidden->video_set)
   160 #define warp_ticks (this->hidden->warp_ticks)
   161 #define warp_flag (this->hidden->warp_flag)
   162 #define resize_icon (this->hidden->resize_icon)
   163 #define current_grab_mode (this->hidden->current_grab_mode)
   164 #define in_foreground (this->hidden->in_foreground)
   165 #define client_mode_list (this->hidden->client_mode_list)
   166 #define keymap (this->hidden->keymap)
   167 #define current_mods (this->hidden->current_mods)
   168 #define last_virtual_button (this->hidden->last_virtual_button)
   169 #define powerConnection (this->hidden->powerConnection)
   170 
   171 #define yuv_idh (this->hidden->yuv_idh)
   172 #define yuv_matrix (this->hidden->yuv_matrix)
   173 #define yuv_codec (this->hidden->yuv_codec)
   174 #define yuv_seq (this->hidden->yuv_seq)
   175 #define yuv_pixmap (this->hidden->yuv_pixmap)
   176 #define yuv_data (this->hidden->yuv_data)
   177 #define yuv_width (this->hidden->yuv_width)
   178 #define yuv_height (this->hidden->yuv_height)
   179 #define yuv_port (this->hidden->yuv_port)
   180 
   181 /* 
   182     Obscuring code: maximum number of windows above ours (inclusive) 
   183     
   184     Note: this doesn't work too well in practice and should be
   185     phased out when we add OpenGL 2D acceleration. It was never
   186     enabled in the first place, so this shouldn't be a problem ;-)
   187 */
   188 #define kMaxWindows 256
   189 
   190 /* Some of the Core Graphics Server API for obscuring code */
   191 #define kCGSWindowLevelTop          2147483632
   192 #define kCGSWindowLevelDockIconDrag 500
   193 #define kCGSWindowLevelDockMenu     101
   194 #define kCGSWindowLevelMenuIgnore    21
   195 #define kCGSWindowLevelMenu          20
   196 #define kCGSWindowLevelDockLabel     12
   197 #define kCGSWindowLevelDockIcon      11
   198 #define kCGSWindowLevelDock          10
   199 #define kCGSWindowLevelUtility        3
   200 #define kCGSWindowLevelNormal         0
   201 
   202 /* 
   203     For completeness; We never use these window levels, they are always below us
   204     #define kCGSWindowLevelMBarShadow -20
   205     #define kCGSWindowLevelDesktopPicture -2147483647
   206     #define kCGSWindowLevelDesktop        -2147483648
   207 */
   208 
   209 typedef CGError       CGSError;
   210 typedef long          CGSWindowCount;
   211 typedef void *        CGSConnectionID;
   212 typedef int           CGSWindowID;
   213 typedef CGSWindowID*  CGSWindowIDList;
   214 typedef CGWindowLevel CGSWindowLevel;
   215 typedef NSRect        CGSRect;
   216 
   217 extern CGSConnectionID _CGSDefaultConnection ();
   218 
   219 extern CGSError CGSGetOnScreenWindowList (CGSConnectionID cid,
   220                                           CGSConnectionID owner,
   221                                           CGSWindowCount listCapacity,
   222                                           CGSWindowIDList list,
   223                                           CGSWindowCount *listCount);
   224 
   225 extern CGSError CGSGetScreenRectForWindow (CGSConnectionID cid,
   226                                            CGSWindowID wid,
   227                                            CGSRect *rect);
   228 
   229 extern CGWindowLevel CGSGetWindowLevel (CGSConnectionID cid,
   230                                         CGSWindowID wid,
   231                                         CGSWindowLevel *level);
   232 
   233 extern CGSError CGSDisplayHWFill (CGDirectDisplayID id, unsigned int x, unsigned int y,
   234                                   unsigned int w, unsigned int h, unsigned int color);
   235 
   236 extern CGSError CGSDisplayCanHWFill (CGDirectDisplayID id);
   237 
   238 extern CGSError CGSGetMouseEnabledFlags (CGSConnectionID cid, CGSWindowID wid, int *flags);
   239 
   240 /* Bootstrap functions */
   241 static int              QZ_Available ();
   242 static SDL_VideoDevice* QZ_CreateDevice (int device_index);
   243 static void             QZ_DeleteDevice (SDL_VideoDevice *device);
   244 
   245 /* Initialization, Query, Setup, and Redrawing functions */
   246 static int          QZ_VideoInit        (_THIS, SDL_PixelFormat *video_format);
   247 
   248 static SDL_Rect**   QZ_ListModes        (_THIS, SDL_PixelFormat *format,
   249                                          Uint32 flags);
   250 static void         QZ_UnsetVideoMode   (_THIS);
   251 
   252 static SDL_Surface* QZ_SetVideoMode     (_THIS, SDL_Surface *current,
   253                                          int width, int height, int bpp,
   254                                          Uint32 flags);
   255 static int          QZ_ToggleFullScreen (_THIS, int on);
   256 static int          QZ_SetColors        (_THIS, int first_color,
   257                                          int num_colors, SDL_Color *colors);
   258 static void         QZ_DirectUpdate     (_THIS, int num_rects, SDL_Rect *rects);
   259 static int          QZ_LockWindow       (_THIS, SDL_Surface *surface);
   260 static void         QZ_UnlockWindow     (_THIS, SDL_Surface *surface);
   261 static void         QZ_UpdateRects      (_THIS, int num_rects, SDL_Rect *rects);
   262 static void         QZ_VideoQuit        (_THIS);
   263 
   264 /* Hardware surface functions (for fullscreen mode only) */
   265 static int  QZ_FillHWRect (_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color);
   266 static int  QZ_LockHWSurface(_THIS, SDL_Surface *surface);
   267 static void QZ_UnlockHWSurface(_THIS, SDL_Surface *surface);
   268 static void QZ_FreeHWSurface (_THIS, SDL_Surface *surface);
   269 /* static int  QZ_FlipHWSurface (_THIS, SDL_Surface *surface); */
   270 
   271 /* Gamma Functions */
   272 static int QZ_SetGamma     (_THIS, float red, float green, float blue);
   273 static int QZ_GetGamma     (_THIS, float *red, float *green, float *blue);
   274 static int QZ_SetGammaRamp (_THIS, Uint16 *ramp);
   275 static int QZ_GetGammaRamp (_THIS, Uint16 *ramp);
   276 
   277 /* OpenGL functions */
   278 static int    QZ_SetupOpenGL       (_THIS, int bpp, Uint32 flags);
   279 static void   QZ_TearDownOpenGL    (_THIS);
   280 static void*  QZ_GL_GetProcAddress (_THIS, const char *proc);
   281 static int    QZ_GL_GetAttribute   (_THIS, SDL_GLattr attrib, int* value);
   282 static int    QZ_GL_MakeCurrent    (_THIS);
   283 static void   QZ_GL_SwapBuffers    (_THIS);
   284 static int    QZ_GL_LoadLibrary    (_THIS, const char *location);
   285 
   286 /* Private function to warp the cursor (used internally) */
   287 static void  QZ_PrivateWarpCursor (_THIS, int x, int y);
   288 
   289 /* Cursor and Mouse functions */
   290 static void         QZ_FreeWMCursor     (_THIS, WMcursor *cursor);
   291 static WMcursor*    QZ_CreateWMCursor   (_THIS, Uint8 *data, Uint8 *mask,
   292                                          int w, int h, int hot_x, int hot_y);
   293 static int          QZ_ShowWMCursor     (_THIS, WMcursor *cursor);
   294 static void         QZ_WarpWMCursor     (_THIS, Uint16 x, Uint16 y);
   295 static void         QZ_MoveWMCursor     (_THIS, int x, int y);
   296 static void         QZ_CheckMouseMode   (_THIS);
   297 
   298 /* Event functions */
   299 static void         QZ_InitOSKeymap     (_THIS);
   300 static void         QZ_PumpEvents       (_THIS);
   301 
   302 /* Window Manager functions */
   303 static void QZ_SetCaption        (_THIS, const char *title, const char *icon);
   304 static void QZ_SetIcon           (_THIS, SDL_Surface *icon, Uint8 *mask);
   305 static int  QZ_IconifyWindow     (_THIS);
   306 static SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode);
   307 /*static int  QZ_GetWMInfo     (_THIS, SDL_SysWMinfo *info);*/
   308 
   309 /* YUV functions */
   310 static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
   311                                          Uint32 format, SDL_Surface *display);