src/video/quartz/SDL_QuartzVideo.h
author Sam Lantinga
Sun, 15 Dec 2002 09:09:31 +0000
changeset 561 4bcf7dd06c47
parent 555 2536446a92de
child 563 04dcaf3da918
permissions -rw-r--r--
Date: Sat, 14 Dec 2002 13:33:05 -0500
From: Darrell Walisser
Subject: Re: crash in SDL / OSX

> Yes, compose keys and other "dead" keys should have unicode 0.
> As a hack, if you get multiple composed characters, you can send the
> sequence with a valid unicode and a keysym of 0. It's because of
> things like this that I'm separating the key and char events in SDL 2.0

I've done this and here's the patch.
     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 #include <IOKit/IOKitLib.h>	/* For powersave handling */
    56 
    57 #include "SDL_video.h"
    58 #include "SDL_error.h"
    59 #include "SDL_timer.h"
    60 #include "SDL_syswm.h"
    61 #include "SDL_sysvideo.h"
    62 #include "SDL_pixels_c.h"
    63 #include "SDL_events_c.h"
    64 
    65 /* 
    66     Add methods to get at private members of NSScreen. 
    67     Since there is a bug in Apple's screen switching code
    68     that does not update this variable when switching
    69     to fullscreen, we'll set it manually (but only for the
    70     main screen).
    71 */
    72 @interface NSScreen (NSScreenAccess)
    73 - (void) setFrame:(NSRect)frame;
    74 @end
    75 
    76 @implementation NSScreen (NSScreenAccess)
    77 - (void) setFrame:(NSRect)frame;
    78 {
    79     _frame = frame;
    80 }
    81 @end
    82 
    83 /* 
    84     This is a workaround to directly access NSOpenGLContext's CGL context
    85     We need this to check for errors NSOpenGLContext doesn't support
    86 */
    87 @interface NSOpenGLContext (CGLContextAccess)
    88 - (CGLContextObj) cglContext;
    89 @end
    90 
    91 @implementation NSOpenGLContext (CGLContextAccess)
    92 - (CGLContextObj) cglContext;
    93 {
    94     return _contextAuxiliary;
    95 }
    96 @end
    97 
    98 /* 
    99     Structure for rez switch gamma fades
   100     We can hide the monitor flicker by setting the gamma tables to 0
   101 */
   102 #define QZ_GAMMA_TABLE_SIZE 256
   103 
   104 typedef struct {
   105 
   106     CGGammaValue red[QZ_GAMMA_TABLE_SIZE];
   107     CGGammaValue green[QZ_GAMMA_TABLE_SIZE];
   108     CGGammaValue blue[QZ_GAMMA_TABLE_SIZE];
   109 
   110 } SDL_QuartzGammaTable;
   111 
   112 /* Main driver structure to store required state information */
   113 typedef struct SDL_PrivateVideoData {
   114 
   115     CGDirectDisplayID  display;            /* 0 == main display (only support single display) */
   116     CFDictionaryRef    mode;               /* current mode of the display */
   117     CFDictionaryRef    save_mode;          /* original mode of the display */
   118     CFArrayRef         mode_list;          /* list of available fullscreen modes */
   119     CGDirectPaletteRef palette;            /* palette of an 8-bit display */
   120     NSOpenGLContext    *gl_context;        /* OpenGL rendering context */
   121     Uint32             width, height, bpp; /* frequently used data about the display */
   122     Uint32             flags;              /* flags for current mode, for teardown purposes */
   123     Uint32             video_set;          /* boolean; indicates if video was set correctly */
   124     Uint32             warp_flag;          /* boolean; notify to event loop that a warp just occured */
   125     Uint32             warp_ticks;         /* timestamp when the warp occured */
   126     NSWindow           *window;            /* Cocoa window to implement the SDL window */
   127     NSQuickDrawView    *view;              /* the window's view; draw 2D and OpenGL into this view */
   128     SDL_Surface        *resize_icon;       /* icon for the resize badge, we have to draw it by hand */
   129     SDL_GrabMode       current_grab_mode;  /* default value is SDL_GRAB_OFF */
   130     BOOL               in_foreground;      /* boolean; indicate if app is in foreground or not */
   131     SDL_Rect           **client_mode_list; /* resolution list to pass back to client */
   132     SDLKey             keymap[256];        /* Mac OS X to SDL key mapping */
   133     Uint32             current_mods;       /* current keyboard modifiers, to track modifier state */
   134     Uint32             last_virtual_button;/* last virtual mouse button pressed */
   135     io_connect_t       powerConnection;    /* used with IOKit to detect wake from sleep */
   136 
   137     ImageDescriptionHandle yuv_idh;
   138     MatrixRecordPtr        yuv_matrix;
   139     DecompressorComponent  yuv_codec;
   140     ImageSequence          yuv_seq;
   141     PlanarPixmapInfoYUV420 *yuv_pixmap;
   142     Sint16                  yuv_width, yuv_height;
   143     CGrafPtr                yuv_port;
   144 
   145 } SDL_PrivateVideoData ;
   146 
   147 #define _THIS    SDL_VideoDevice *this
   148 #define display_id (this->hidden->display)
   149 #define mode (this->hidden->mode)
   150 #define save_mode (this->hidden->save_mode)
   151 #define mode_list (this->hidden->mode_list)
   152 #define palette (this->hidden->palette)
   153 #define gl_context (this->hidden->gl_context)
   154 #define device_width (this->hidden->width)
   155 #define device_height (this->hidden->height)
   156 #define device_bpp (this->hidden->bpp)
   157 #define mode_flags (this->hidden->flags)
   158 #define qz_window (this->hidden->window)
   159 #define window_view (this->hidden->view)
   160 #define video_set (this->hidden->video_set)
   161 #define warp_ticks (this->hidden->warp_ticks)
   162 #define warp_flag (this->hidden->warp_flag)
   163 #define resize_icon (this->hidden->resize_icon)
   164 #define current_grab_mode (this->hidden->current_grab_mode)
   165 #define in_foreground (this->hidden->in_foreground)
   166 #define client_mode_list (this->hidden->client_mode_list)
   167 #define keymap (this->hidden->keymap)
   168 #define current_mods (this->hidden->current_mods)
   169 #define last_virtual_button (this->hidden->last_virtual_button)
   170 #define powerConnection (this->hidden->powerConnection)
   171 
   172 #define yuv_idh (this->hidden->yuv_idh)
   173 #define yuv_matrix (this->hidden->yuv_matrix)
   174 #define yuv_codec (this->hidden->yuv_codec)
   175 #define yuv_seq (this->hidden->yuv_seq)
   176 #define yuv_pixmap (this->hidden->yuv_pixmap)
   177 #define yuv_data (this->hidden->yuv_data)
   178 #define yuv_width (this->hidden->yuv_width)
   179 #define yuv_height (this->hidden->yuv_height)
   180 #define yuv_port (this->hidden->yuv_port)
   181 
   182 /* 
   183     Obscuring code: maximum number of windows above ours (inclusive) 
   184     
   185     Note: this doesn't work too well in practice and should be
   186     phased out when we add OpenGL 2D acceleration. It was never
   187     enabled in the first place, so this shouldn't be a problem ;-)
   188 */
   189 #define kMaxWindows 256
   190 
   191 /* Some of the Core Graphics Server API for obscuring code */
   192 #define kCGSWindowLevelTop          2147483632
   193 #define kCGSWindowLevelDockIconDrag 500
   194 #define kCGSWindowLevelDockMenu     101
   195 #define kCGSWindowLevelMenuIgnore    21
   196 #define kCGSWindowLevelMenu          20
   197 #define kCGSWindowLevelDockLabel     12
   198 #define kCGSWindowLevelDockIcon      11
   199 #define kCGSWindowLevelDock          10
   200 #define kCGSWindowLevelUtility        3
   201 #define kCGSWindowLevelNormal         0
   202 
   203 /* 
   204     For completeness; We never use these window levels, they are always below us
   205     #define kCGSWindowLevelMBarShadow -20
   206     #define kCGSWindowLevelDesktopPicture -2147483647
   207     #define kCGSWindowLevelDesktop        -2147483648
   208 */
   209 
   210 typedef CGError       CGSError;
   211 typedef long          CGSWindowCount;
   212 typedef void *        CGSConnectionID;
   213 typedef int           CGSWindowID;
   214 typedef CGSWindowID*  CGSWindowIDList;
   215 typedef CGWindowLevel CGSWindowLevel;
   216 typedef NSRect        CGSRect;
   217 
   218 extern CGSConnectionID _CGSDefaultConnection ();
   219 
   220 extern CGSError CGSGetOnScreenWindowList (CGSConnectionID cid,
   221                                           CGSConnectionID owner,
   222                                           CGSWindowCount listCapacity,
   223                                           CGSWindowIDList list,
   224                                           CGSWindowCount *listCount);
   225 
   226 extern CGSError CGSGetScreenRectForWindow (CGSConnectionID cid,
   227                                            CGSWindowID wid,
   228                                            CGSRect *rect);
   229 
   230 extern CGWindowLevel CGSGetWindowLevel (CGSConnectionID cid,
   231                                         CGSWindowID wid,
   232                                         CGSWindowLevel *level);
   233 
   234 extern CGSError CGSDisplayHWFill (CGDirectDisplayID id, unsigned int x, unsigned int y,
   235                                   unsigned int w, unsigned int h, unsigned int color);
   236 
   237 extern CGSError CGSDisplayCanHWFill (CGDirectDisplayID id);
   238 
   239 extern CGSError CGSGetMouseEnabledFlags (CGSConnectionID cid, CGSWindowID wid, int *flags);
   240 
   241 /* Bootstrap functions */
   242 static int              QZ_Available ();
   243 static SDL_VideoDevice* QZ_CreateDevice (int device_index);
   244 static void             QZ_DeleteDevice (SDL_VideoDevice *device);
   245 
   246 /* Initialization, Query, Setup, and Redrawing functions */
   247 static int          QZ_VideoInit        (_THIS, SDL_PixelFormat *video_format);
   248 
   249 static SDL_Rect**   QZ_ListModes        (_THIS, SDL_PixelFormat *format,
   250                                          Uint32 flags);
   251 static void         QZ_UnsetVideoMode   (_THIS);
   252 
   253 static SDL_Surface* QZ_SetVideoMode     (_THIS, SDL_Surface *current,
   254                                          int width, int height, int bpp,
   255                                          Uint32 flags);
   256 static int          QZ_ToggleFullScreen (_THIS, int on);
   257 static int          QZ_SetColors        (_THIS, int first_color,
   258                                          int num_colors, SDL_Color *colors);
   259 static void         QZ_DirectUpdate     (_THIS, int num_rects, SDL_Rect *rects);
   260 static int          QZ_LockWindow       (_THIS, SDL_Surface *surface);
   261 static void         QZ_UnlockWindow     (_THIS, SDL_Surface *surface);
   262 static void         QZ_UpdateRects      (_THIS, int num_rects, SDL_Rect *rects);
   263 static void         QZ_VideoQuit        (_THIS);
   264 
   265 /* Hardware surface functions (for fullscreen mode only) */
   266 static int  QZ_FillHWRect (_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color);
   267 static int  QZ_LockHWSurface(_THIS, SDL_Surface *surface);
   268 static void QZ_UnlockHWSurface(_THIS, SDL_Surface *surface);
   269 static void QZ_FreeHWSurface (_THIS, SDL_Surface *surface);
   270 /* static int  QZ_FlipHWSurface (_THIS, SDL_Surface *surface); */
   271 
   272 /* Gamma Functions */
   273 static int QZ_SetGamma     (_THIS, float red, float green, float blue);
   274 static int QZ_GetGamma     (_THIS, float *red, float *green, float *blue);
   275 static int QZ_SetGammaRamp (_THIS, Uint16 *ramp);
   276 static int QZ_GetGammaRamp (_THIS, Uint16 *ramp);
   277 
   278 /* OpenGL functions */
   279 static int    QZ_SetupOpenGL       (_THIS, int bpp, Uint32 flags);
   280 static void   QZ_TearDownOpenGL    (_THIS);
   281 static void*  QZ_GL_GetProcAddress (_THIS, const char *proc);
   282 static int    QZ_GL_GetAttribute   (_THIS, SDL_GLattr attrib, int* value);
   283 static int    QZ_GL_MakeCurrent    (_THIS);
   284 static void   QZ_GL_SwapBuffers    (_THIS);
   285 static int    QZ_GL_LoadLibrary    (_THIS, const char *location);
   286 
   287 /* Private function to warp the cursor (used internally) */
   288 static void  QZ_PrivateWarpCursor (_THIS, int x, int y);
   289 
   290 /* Cursor and Mouse functions */
   291 static void         QZ_FreeWMCursor     (_THIS, WMcursor *cursor);
   292 static WMcursor*    QZ_CreateWMCursor   (_THIS, Uint8 *data, Uint8 *mask,
   293                                          int w, int h, int hot_x, int hot_y);
   294 static int          QZ_ShowWMCursor     (_THIS, WMcursor *cursor);
   295 static void         QZ_WarpWMCursor     (_THIS, Uint16 x, Uint16 y);
   296 static void         QZ_MoveWMCursor     (_THIS, int x, int y);
   297 static void         QZ_CheckMouseMode   (_THIS);
   298 
   299 /* Event functions */
   300 static void         QZ_InitOSKeymap     (_THIS);
   301 static void         QZ_PumpEvents       (_THIS);
   302 
   303 /* Window Manager functions */
   304 static void QZ_SetCaption        (_THIS, const char *title, const char *icon);
   305 static void QZ_SetIcon           (_THIS, SDL_Surface *icon, Uint8 *mask);
   306 static int  QZ_IconifyWindow     (_THIS);
   307 static SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode);
   308 /*static int  QZ_GetWMInfo     (_THIS, SDL_SysWMinfo *info);*/
   309 
   310 /* YUV functions */
   311 static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
   312                                          Uint32 format, SDL_Surface *display);