src/video/quartz/SDL_QuartzVideo.h
author Sam Lantinga
Sat, 05 Oct 2002 05:07:57 +0000
changeset 501 74262d2647ca
parent 498 4b8ff8ac2c07
child 555 2536446a92de
permissions -rw-r--r--
Lots of cleanups by Darrell, added the ability to resize Cocoa windows.
     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     
   135     ImageDescriptionHandle yuv_idh;
   136     MatrixRecordPtr        yuv_matrix;
   137     DecompressorComponent  yuv_codec;
   138     ImageSequence          yuv_seq;
   139     PlanarPixmapInfoYUV420 *yuv_pixmap;
   140     Sint16                  yuv_width, yuv_height;
   141     CGrafPtr                yuv_port;
   142 
   143 } SDL_PrivateVideoData ;
   144 
   145 #define _THIS    SDL_VideoDevice *this
   146 #define display_id (this->hidden->display)
   147 #define mode (this->hidden->mode)
   148 #define save_mode (this->hidden->save_mode)
   149 #define mode_list (this->hidden->mode_list)
   150 #define palette (this->hidden->palette)
   151 #define gl_context (this->hidden->gl_context)
   152 #define device_width (this->hidden->width)
   153 #define device_height (this->hidden->height)
   154 #define device_bpp (this->hidden->bpp)
   155 #define mode_flags (this->hidden->flags)
   156 #define qz_window (this->hidden->window)
   157 #define window_view (this->hidden->view)
   158 #define video_set (this->hidden->video_set)
   159 #define warp_ticks (this->hidden->warp_ticks)
   160 #define warp_flag (this->hidden->warp_flag)
   161 #define resize_icon (this->hidden->resize_icon)
   162 #define current_grab_mode (this->hidden->current_grab_mode)
   163 #define in_foreground (this->hidden->in_foreground)
   164 #define client_mode_list (this->hidden->client_mode_list)
   165 #define keymap (this->hidden->keymap)
   166 #define current_mods (this->hidden->current_mods)
   167 #define last_virtual_button (this->hidden->last_virtual_button)
   168 
   169 #define yuv_idh (this->hidden->yuv_idh)
   170 #define yuv_matrix (this->hidden->yuv_matrix)
   171 #define yuv_codec (this->hidden->yuv_codec)
   172 #define yuv_seq (this->hidden->yuv_seq)
   173 #define yuv_pixmap (this->hidden->yuv_pixmap)
   174 #define yuv_data (this->hidden->yuv_data)
   175 #define yuv_width (this->hidden->yuv_width)
   176 #define yuv_height (this->hidden->yuv_height)
   177 #define yuv_port (this->hidden->yuv_port)
   178 
   179 /* 
   180     Obscuring code: maximum number of windows above ours (inclusive) 
   181     
   182     Note: this doesn't work too well in practice and should be
   183     phased out when we add OpenGL 2D acceleration. It was never
   184     enabled in the first place, so this shouldn't be a problem ;-)
   185 */
   186 #define kMaxWindows 256
   187 
   188 /* Some of the Core Graphics Server API for obscuring code */
   189 #define kCGSWindowLevelTop          2147483632
   190 #define kCGSWindowLevelDockIconDrag 500
   191 #define kCGSWindowLevelDockMenu     101
   192 #define kCGSWindowLevelMenuIgnore    21
   193 #define kCGSWindowLevelMenu          20
   194 #define kCGSWindowLevelDockLabel     12
   195 #define kCGSWindowLevelDockIcon      11
   196 #define kCGSWindowLevelDock          10
   197 #define kCGSWindowLevelUtility        3
   198 #define kCGSWindowLevelNormal         0
   199 
   200 /* 
   201     For completeness; We never use these window levels, they are always below us
   202     #define kCGSWindowLevelMBarShadow -20
   203     #define kCGSWindowLevelDesktopPicture -2147483647
   204     #define kCGSWindowLevelDesktop        -2147483648
   205 */
   206 
   207 typedef CGError       CGSError;
   208 typedef long          CGSWindowCount;
   209 typedef void *        CGSConnectionID;
   210 typedef int           CGSWindowID;
   211 typedef CGSWindowID*  CGSWindowIDList;
   212 typedef CGWindowLevel CGSWindowLevel;
   213 typedef NSRect        CGSRect;
   214 
   215 extern CGSConnectionID _CGSDefaultConnection ();
   216 
   217 extern CGSError CGSGetOnScreenWindowList (CGSConnectionID cid,
   218                                           CGSConnectionID owner,
   219                                           CGSWindowCount listCapacity,
   220                                           CGSWindowIDList list,
   221                                           CGSWindowCount *listCount);
   222 
   223 extern CGSError CGSGetScreenRectForWindow (CGSConnectionID cid,
   224                                            CGSWindowID wid,
   225                                            CGSRect *rect);
   226 
   227 extern CGWindowLevel CGSGetWindowLevel (CGSConnectionID cid,
   228                                         CGSWindowID wid,
   229                                         CGSWindowLevel *level);
   230 
   231 extern CGSError CGSDisplayHWFill (CGDirectDisplayID id, unsigned int x, unsigned int y,
   232                                   unsigned int w, unsigned int h, unsigned int color);
   233 
   234 extern CGSError CGSDisplayCanHWFill (CGDirectDisplayID id);
   235 
   236 extern CGSError CGSGetMouseEnabledFlags (CGSConnectionID cid, CGSWindowID wid, int *flags);
   237 
   238 /* Bootstrap functions */
   239 static int              QZ_Available ();
   240 static SDL_VideoDevice* QZ_CreateDevice (int device_index);
   241 static void             QZ_DeleteDevice (SDL_VideoDevice *device);
   242 
   243 /* Initialization, Query, Setup, and Redrawing functions */
   244 static int          QZ_VideoInit        (_THIS, SDL_PixelFormat *video_format);
   245 
   246 static SDL_Rect**   QZ_ListModes        (_THIS, SDL_PixelFormat *format,
   247                                          Uint32 flags);
   248 static void         QZ_UnsetVideoMode   (_THIS);
   249 
   250 static SDL_Surface* QZ_SetVideoMode     (_THIS, SDL_Surface *current,
   251                                          int width, int height, int bpp,
   252                                          Uint32 flags);
   253 static int          QZ_ToggleFullScreen (_THIS, int on);
   254 static int          QZ_SetColors        (_THIS, int first_color,
   255                                          int num_colors, SDL_Color *colors);
   256 static void         QZ_DirectUpdate     (_THIS, int num_rects, SDL_Rect *rects);
   257 static int          QZ_LockWindow       (_THIS, SDL_Surface *surface);
   258 static void         QZ_UnlockWindow     (_THIS, SDL_Surface *surface);
   259 static void         QZ_UpdateRects      (_THIS, int num_rects, SDL_Rect *rects);
   260 static void         QZ_VideoQuit        (_THIS);
   261 
   262 /* Hardware surface functions (for fullscreen mode only) */
   263 static int  QZ_FillHWRect (_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color);
   264 static int  QZ_LockHWSurface(_THIS, SDL_Surface *surface);
   265 static void QZ_UnlockHWSurface(_THIS, SDL_Surface *surface);
   266 static void QZ_FreeHWSurface (_THIS, SDL_Surface *surface);
   267 /* static int  QZ_FlipHWSurface (_THIS, SDL_Surface *surface); */
   268 
   269 /* Gamma Functions */
   270 static int QZ_SetGamma     (_THIS, float red, float green, float blue);
   271 static int QZ_GetGamma     (_THIS, float *red, float *green, float *blue);
   272 static int QZ_SetGammaRamp (_THIS, Uint16 *ramp);
   273 static int QZ_GetGammaRamp (_THIS, Uint16 *ramp);
   274 
   275 /* OpenGL functions */
   276 static int    QZ_SetupOpenGL       (_THIS, int bpp, Uint32 flags);
   277 static void   QZ_TearDownOpenGL    (_THIS);
   278 static void*  QZ_GL_GetProcAddress (_THIS, const char *proc);
   279 static int    QZ_GL_GetAttribute   (_THIS, SDL_GLattr attrib, int* value);
   280 static int    QZ_GL_MakeCurrent    (_THIS);
   281 static void   QZ_GL_SwapBuffers    (_THIS);
   282 static int    QZ_GL_LoadLibrary    (_THIS, const char *location);
   283 
   284 /* Private function to warp the cursor (used internally) */
   285 static void  QZ_PrivateWarpCursor (_THIS, int x, int y);
   286 
   287 /* Cursor and Mouse functions */
   288 static void         QZ_FreeWMCursor     (_THIS, WMcursor *cursor);
   289 static WMcursor*    QZ_CreateWMCursor   (_THIS, Uint8 *data, Uint8 *mask,
   290                                          int w, int h, int hot_x, int hot_y);
   291 static int          QZ_ShowWMCursor     (_THIS, WMcursor *cursor);
   292 static void         QZ_WarpWMCursor     (_THIS, Uint16 x, Uint16 y);
   293 static void         QZ_MoveWMCursor     (_THIS, int x, int y);
   294 static void         QZ_CheckMouseMode   (_THIS);
   295 
   296 /* Event functions */
   297 static void         QZ_InitOSKeymap     (_THIS);
   298 static void         QZ_PumpEvents       (_THIS);
   299 
   300 /* Window Manager functions */
   301 static void QZ_SetCaption        (_THIS, const char *title, const char *icon);
   302 static void QZ_SetIcon           (_THIS, SDL_Surface *icon, Uint8 *mask);
   303 static int  QZ_IconifyWindow     (_THIS);
   304 static SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode);
   305 /*static int  QZ_GetWMInfo     (_THIS, SDL_SysWMinfo *info);*/
   306 
   307 /* YUV functions */
   308 static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
   309                                          Uint32 format, SDL_Surface *display);