Home | History | Annotate | Download | only in quartz
      1 /*
      2     SDL - Simple DirectMedia Layer
      3     Copyright (C) 1997-2003  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 (at) libsdl.org
     21 */
     22 #include "SDL_config.h"
     23 
     24 /*
     25     @file   SDL_QuartzVideo.h
     26     @author Darrell Walisser, Max Horn, et al.
     27 
     28     @abstract SDL video driver for Mac OS X.
     29 
     30     @discussion
     31 
     32     TODO
     33         - Hardware Cursor support with NSCursor instead of Carbon
     34         - Keyboard repeat/mouse speed adjust (if needed)
     35         - Multiple monitor support (currently only main display)
     36         - Accelerated blitting support
     37         - Fix white OpenGL window on minimize (fixed) (update: broken again on 10.2)
     38         - Find out what events should be sent/ignored if window is minimized
     39         - Find a way to deal with external resolution/depth switch while app is running
     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 /* Needs to be first, so QuickTime.h doesn't include glext.h (10.4) */
     52 #include "SDL_opengl.h"
     53 
     54 #include <Cocoa/Cocoa.h>
     55 #include <Carbon/Carbon.h>
     56 #include <QuickTime/QuickTime.h>
     57 #include <OpenGL/OpenGL.h>	/* For CGL functions and types */
     58 #include <IOKit/IOKitLib.h>	/* For powersave handling */
     59 #include <pthread.h>
     60 
     61 #include "SDL_thread.h"
     62 #include "SDL_video.h"
     63 #include "SDL_error.h"
     64 #include "SDL_timer.h"
     65 #include "SDL_loadso.h"
     66 #include "SDL_syswm.h"
     67 #include "../SDL_sysvideo.h"
     68 #include "../SDL_pixels_c.h"
     69 #include "../../events/SDL_events_c.h"
     70 
     71 /*
     72     This is a workaround to directly access NSOpenGLContext's CGL context
     73     We need this to check for errors NSOpenGLContext doesn't support
     74 */
     75 @interface NSOpenGLContext (CGLContextAccess)
     76 - (CGLContextObj) cglContext;
     77 @end
     78 
     79 
     80 /* Main driver structure to store required state information */
     81 typedef struct SDL_PrivateVideoData {
     82 
     83     BOOL               allow_screensaver;  /* 0 == disable screensaver */
     84     CGDirectDisplayID  display;            /* 0 == main display (only support single display) */
     85     CFDictionaryRef    mode;               /* current mode of the display */
     86     CFDictionaryRef    save_mode;          /* original mode of the display */
     87     CFArrayRef         mode_list;          /* list of available fullscreen modes */
     88     CGDirectPaletteRef palette;            /* palette of an 8-bit display */
     89     NSOpenGLContext    *gl_context;        /* OpenGL rendering context */
     90     Uint32             width, height, bpp; /* frequently used data about the display */
     91     Uint32             flags;              /* flags for current mode, for teardown purposes */
     92     Uint32             video_set;          /* boolean; indicates if video was set correctly */
     93     Uint32             warp_flag;          /* boolean; notify to event loop that a warp just occured */
     94     Uint32             warp_ticks;         /* timestamp when the warp occured */
     95     NSWindow           *window;            /* Cocoa window to implement the SDL window */
     96     NSQuickDrawView    *view;              /* the window's view; draw 2D and OpenGL into this view */
     97     SDL_Surface        *resize_icon;       /* icon for the resize badge, we have to draw it by hand */
     98     SDL_GrabMode       current_grab_mode;  /* default value is SDL_GRAB_OFF */
     99     SDL_Rect           **client_mode_list; /* resolution list to pass back to client */
    100     SDLKey             keymap[256];        /* Mac OS X to SDL key mapping */
    101     Uint32             current_mods;       /* current keyboard modifiers, to track modifier state */
    102     NSText             *field_edit;        /* a field editor for keyboard composition processing */
    103     Uint32             last_virtual_button;/* last virtual mouse button pressed */
    104     io_connect_t       power_connection;   /* used with IOKit to detect wake from sleep */
    105     Uint8              expect_mouse_up;    /* used to determine when to send mouse up events */
    106     Uint8              grab_state;         /* used to manage grab behavior */
    107     NSPoint            cursor_loc;         /* saved cursor coords, for activate/deactivate when grabbed */
    108     BOOL               cursor_should_be_visible;     /* tells if cursor is supposed to be visible (SDL_ShowCursor) */
    109     BOOL               cursor_visible;     /* tells if cursor is *actually* visible or not */
    110     Uint8*             sw_buffers[2];      /* pointers to the two software buffers for double-buffer emulation */
    111     SDL_Thread         *thread;            /* thread for async updates to the screen */
    112     SDL_sem            *sem1, *sem2;       /* synchronization for async screen updates */
    113     Uint8              *current_buffer;    /* the buffer being copied to the screen */
    114     BOOL               quit_thread;        /* used to quit the async blitting thread */
    115     SInt32             system_version;     /* used to dis-/enable workarounds depending on the system version */
    116 
    117     ImageDescriptionHandle yuv_idh;
    118     MatrixRecordPtr        yuv_matrix;
    119     DecompressorComponent  yuv_codec;
    120     ImageSequence          yuv_seq;
    121     PlanarPixmapInfoYUV420 *yuv_pixmap;
    122     Sint16                  yuv_width, yuv_height;
    123     CGrafPtr                yuv_port;
    124 
    125     void *opengl_library;    /* dynamically loaded OpenGL library. */
    126 } SDL_PrivateVideoData;
    127 
    128 #define _THIS    SDL_VideoDevice *this
    129 #define display_id (this->hidden->display)
    130 #define mode (this->hidden->mode)
    131 #define save_mode (this->hidden->save_mode)
    132 #define allow_screensaver (this->hidden->allow_screensaver)
    133 #define mode_list (this->hidden->mode_list)
    134 #define palette (this->hidden->palette)
    135 #define gl_context (this->hidden->gl_context)
    136 #define device_width (this->hidden->width)
    137 #define device_height (this->hidden->height)
    138 #define device_bpp (this->hidden->bpp)
    139 #define mode_flags (this->hidden->flags)
    140 #define qz_window (this->hidden->window)
    141 #define window_view (this->hidden->view)
    142 #define video_set (this->hidden->video_set)
    143 #define warp_ticks (this->hidden->warp_ticks)
    144 #define warp_flag (this->hidden->warp_flag)
    145 #define resize_icon (this->hidden->resize_icon)
    146 #define current_grab_mode (this->hidden->current_grab_mode)
    147 #define client_mode_list (this->hidden->client_mode_list)
    148 #define keymap (this->hidden->keymap)
    149 #define current_mods (this->hidden->current_mods)
    150 #define field_edit (this->hidden->field_edit)
    151 #define last_virtual_button (this->hidden->last_virtual_button)
    152 #define power_connection (this->hidden->power_connection)
    153 #define expect_mouse_up (this->hidden->expect_mouse_up)
    154 #define grab_state (this->hidden->grab_state)
    155 #define cursor_loc (this->hidden->cursor_loc)
    156 #define cursor_should_be_visible (this->hidden->cursor_should_be_visible)
    157 #define cursor_visible (this->hidden->cursor_visible)
    158 #define sw_buffers (this->hidden->sw_buffers)
    159 #define thread (this->hidden->thread)
    160 #define sem1 (this->hidden->sem1)
    161 #define sem2 (this->hidden->sem2)
    162 #define current_buffer (this->hidden->current_buffer)
    163 #define quit_thread (this->hidden->quit_thread)
    164 #define system_version (this->hidden->system_version)
    165 #define opengl_library (this->hidden->opengl_library)
    166 
    167 /* grab states - the input is in one of these states */
    168 enum {
    169     QZ_UNGRABBED = 0,
    170     QZ_VISIBLE_GRAB,
    171     QZ_INVISIBLE_GRAB
    172 };
    173 
    174 /* grab actions - these can change the grabbed state */
    175 enum {
    176     QZ_ENABLE_GRAB = 0,
    177     QZ_DISABLE_GRAB,
    178     QZ_HIDECURSOR,
    179     QZ_SHOWCURSOR
    180 };
    181 
    182 /* Gamma Functions */
    183 int    QZ_SetGamma          (_THIS, float red, float green, float blue);
    184 int    QZ_GetGamma          (_THIS, float *red, float *green, float *blue);
    185 int    QZ_SetGammaRamp      (_THIS, Uint16 *ramp);
    186 int    QZ_GetGammaRamp      (_THIS, Uint16 *ramp);
    187 
    188 /* OpenGL functions */
    189 int    QZ_SetupOpenGL       (_THIS, int bpp, Uint32 flags);
    190 void   QZ_TearDownOpenGL    (_THIS);
    191 void*  QZ_GL_GetProcAddress (_THIS, const char *proc);
    192 int    QZ_GL_GetAttribute   (_THIS, SDL_GLattr attrib, int* value);
    193 int    QZ_GL_MakeCurrent    (_THIS);
    194 void   QZ_GL_SwapBuffers    (_THIS);
    195 int    QZ_GL_LoadLibrary    (_THIS, const char *location);
    196 
    197 /* Cursor and Mouse functions */
    198 void         QZ_FreeWMCursor     (_THIS, WMcursor *cursor);
    199 WMcursor*    QZ_CreateWMCursor   (_THIS, Uint8 *data, Uint8 *mask,
    200                                   int w, int h, int hot_x, int hot_y);
    201 int          QZ_ShowWMCursor     (_THIS, WMcursor *cursor);
    202 void         QZ_WarpWMCursor     (_THIS, Uint16 x, Uint16 y);
    203 void         QZ_MoveWMCursor     (_THIS, int x, int y);
    204 void         QZ_CheckMouseMode   (_THIS);
    205 void         QZ_UpdateMouse      (_THIS);
    206 
    207 /* Event functions */
    208 void         QZ_InitOSKeymap     (_THIS);
    209 void         QZ_PumpEvents       (_THIS);
    210 
    211 /* Window Manager functions */
    212 void         QZ_SetCaption       (_THIS, const char *title, const char *icon);
    213 void         QZ_SetIcon          (_THIS, SDL_Surface *icon, Uint8 *mask);
    214 int          QZ_IconifyWindow    (_THIS);
    215 void         QZ_SetWindowPos     (_THIS, int  x, int  y);
    216 void         QZ_GetWindowPos     (_THIS, int  *px, int  *py);
    217 int          QZ_IsWindowVisible  (_THIS, int  recenter);
    218 int          QZ_GetMonitorDPI    (_THIS, int  *xDpi, int *yDpi);
    219 int          QZ_GetMonitorRect   (_THIS, SDL_Rect  *rect);
    220 
    221 SDL_GrabMode QZ_GrabInput        (_THIS, SDL_GrabMode grab_mode);
    222 int          QZ_GetWMInfo        (_THIS, SDL_SysWMinfo *info);
    223 
    224 /* YUV functions */
    225 SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
    226                                          Uint32 format, SDL_Surface *display);
    227 
    228 
    229 /* Private functions (used internally) */
    230 void         QZ_PrivateWarpCursor (_THIS, int x, int y);
    231 void         QZ_ChangeGrabState (_THIS, int action);
    232 void         QZ_RegisterForSleepNotifications (_THIS);
    233 void         QZ_PrivateGlobalToLocal (_THIS, NSPoint *p);
    234 void         QZ_PrivateCocoaToSDL (_THIS, NSPoint *p);
    235 BOOL         QZ_IsMouseInWindow (_THIS);
    236 void         QZ_DoActivate (_THIS);
    237 void         QZ_DoDeactivate (_THIS);
    238