src/video/quartz/SDL_QuartzVideo.h
author Ryan C. Gordon
Mon, 02 Jan 2012 21:25:34 -0800
branchSDL-1.2
changeset 6157 8a1bc41db6bb
parent 6137 4720145f848b
child 7726 e9466ead70e5
permissions -rw-r--r--
Quartz: Restore 1.2.14 behaviour of letting apps draw from background thread.

Strictly speaking, this isn't encouraged, but it's a regression.
slouken@47
     1
/*
slouken@47
     2
    SDL - Simple DirectMedia Layer
slouken@6137
     3
    Copyright (C) 1997-2012  Sam Lantinga
slouken@47
     4
slouken@47
     5
    This library is free software; you can redistribute it and/or
slouken@47
     6
    modify it under the terms of the GNU Library General Public
slouken@47
     7
    License as published by the Free Software Foundation; either
slouken@47
     8
    version 2 of the License, or (at your option) any later version.
slouken@47
     9
slouken@47
    10
    This library is distributed in the hope that it will be useful,
slouken@47
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@47
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@47
    13
    Library General Public License for more details.
slouken@47
    14
slouken@47
    15
    You should have received a copy of the GNU Library General Public
slouken@47
    16
    License along with this library; if not, write to the Free
slouken@47
    17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
slouken@47
    18
slouken@47
    19
    Sam Lantinga
slouken@252
    20
    slouken@libsdl.org
slouken@47
    21
*/
slouken@1402
    22
#include "SDL_config.h"
slouken@47
    23
slouken@390
    24
/*    
slouken@47
    25
    @file   SDL_QuartzVideo.h
slouken@501
    26
    @author Darrell Walisser, Max Horn, et al.
slouken@47
    27
    
slouken@501
    28
    @abstract SDL video driver for Mac OS X.
slouken@47
    29
    
slouken@47
    30
    @discussion
slouken@47
    31
    
slouken@47
    32
    TODO
slouken@47
    33
        - Hardware Cursor support with NSCursor instead of Carbon
slouken@47
    34
        - Keyboard repeat/mouse speed adjust (if needed)
slouken@47
    35
        - Multiple monitor support (currently only main display)
slouken@47
    36
        - Accelerated blitting support
slouken@501
    37
        - Fix white OpenGL window on minimize (fixed) (update: broken again on 10.2)
slouken@501
    38
        - Find out what events should be sent/ignored if window is minimized
slouken@390
    39
        - Find a way to deal with external resolution/depth switch while app is running
slouken@272
    40
        - Check accuracy of QZ_SetGamma()
slouken@47
    41
    Problems:
slouken@47
    42
        - OGL not working in full screen with software renderer
icculus@5908
    43
        - SetColors sets palette correctly but clears framebuffer
slouken@390
    44
        - Crash in CG after several mode switches (I think this has been fixed)
slouken@272
    45
        - Retained windows don't draw their title bar quite right (OS Bug) (not using retained windows)
slouken@501
    46
        - Cursor in 8 bit modes is screwy (might just be Radeon PCI bug) (update: not just Radeon)
slouken@272
    47
        - Warping cursor delays mouse events for a fraction of a second,
slouken@272
    48
          there is a hack around this that helps a bit
slouken@47
    49
*/
slouken@47
    50
slouken@1483
    51
/* Needs to be first, so QuickTime.h doesn't include glext.h (10.4) */
slouken@1483
    52
#include "SDL_opengl.h"
slouken@1483
    53
slouken@272
    54
#include <Cocoa/Cocoa.h>
slouken@47
    55
#include <Carbon/Carbon.h>
slouken@3877
    56
#include <OpenGL/OpenGL.h>	/* For CGL functions and types */
slouken@1648
    57
#include <IOKit/IOKitLib.h>	/* For powersave handling */
slouken@588
    58
#include <pthread.h>
slouken@47
    59
slouken@588
    60
#include "SDL_thread.h"
slouken@47
    61
#include "SDL_video.h"
slouken@47
    62
#include "SDL_error.h"
slouken@272
    63
#include "SDL_timer.h"
slouken@1361
    64
#include "SDL_loadso.h"
slouken@47
    65
#include "SDL_syswm.h"
slouken@1361
    66
#include "../SDL_sysvideo.h"
slouken@1361
    67
#include "../SDL_pixels_c.h"
slouken@1361
    68
#include "../../events/SDL_events_c.h"
slouken@47
    69
icculus@4204
    70
icculus@4204
    71
#ifdef __powerpc__
slouken@770
    72
/* 
slouken@770
    73
    This is a workaround to directly access NSOpenGLContext's CGL context
slouken@770
    74
    We need this to check for errors NSOpenGLContext doesn't support
icculus@4204
    75
    Please note this is only used on PowerPC (Intel Macs are guaranteed to
icculus@4204
    76
    have a better API for this, since it showed up in Mac OS X 10.3).
slouken@770
    77
*/
slouken@770
    78
@interface NSOpenGLContext (CGLContextAccess)
slouken@770
    79
- (CGLContextObj) cglContext;
slouken@770
    80
@end
icculus@4204
    81
#endif
icculus@4204
    82
icculus@4204
    83
/* use this to get the CGLContext; it handles Cocoa interface changes. */
icculus@4204
    84
CGLContextObj QZ_GetCGLContextObj(NSOpenGLContext *nsctx);
slouken@770
    85
slouken@770
    86
slouken@272
    87
/* Main driver structure to store required state information */
slouken@47
    88
typedef struct SDL_PrivateVideoData {
icculus@5945
    89
    BOOL               use_new_mode_apis;  /* 1 == >= 10.6 APIs available */
icculus@3936
    90
    BOOL               allow_screensaver;  /* 0 == disable screensaver */
slouken@272
    91
    CGDirectDisplayID  display;            /* 0 == main display (only support single display) */
icculus@5628
    92
    const void         *mode;              /* current mode of the display */
icculus@5628
    93
    const void         *save_mode;         /* original mode of the display */
icculus@5908
    94
    CGDirectPaletteRef palette;            /* palette of an 8-bit display */
slouken@501
    95
    NSOpenGLContext    *gl_context;        /* OpenGL rendering context */
icculus@6157
    96
    NSGraphicsContext  *nsgfx_context;     /* Cocoa graphics context */
slouken@272
    97
    Uint32             width, height, bpp; /* frequently used data about the display */
slouken@501
    98
    Uint32             flags;              /* flags for current mode, for teardown purposes */
slouken@272
    99
    Uint32             video_set;          /* boolean; indicates if video was set correctly */
slouken@272
   100
    Uint32             warp_flag;          /* boolean; notify to event loop that a warp just occured */
slouken@272
   101
    Uint32             warp_ticks;         /* timestamp when the warp occured */
slouken@272
   102
    NSWindow           *window;            /* Cocoa window to implement the SDL window */
icculus@4204
   103
    NSView             *view;              /* the window's view; draw 2D and OpenGL into this view */
icculus@4204
   104
    CGContextRef       cg_context;         /* CoreGraphics rendering context */
slouken@501
   105
    SDL_Surface        *resize_icon;       /* icon for the resize badge, we have to draw it by hand */
slouken@501
   106
    SDL_GrabMode       current_grab_mode;  /* default value is SDL_GRAB_OFF */
slouken@501
   107
    SDL_Rect           **client_mode_list; /* resolution list to pass back to client */
slouken@501
   108
    SDLKey             keymap[256];        /* Mac OS X to SDL key mapping */
slouken@501
   109
    Uint32             current_mods;       /* current keyboard modifiers, to track modifier state */
slouken@4049
   110
    NSText             *field_edit;        /* a field editor for keyboard composition processing */
slouken@501
   111
    Uint32             last_virtual_button;/* last virtual mouse button pressed */
icculus@563
   112
    io_connect_t       power_connection;   /* used with IOKit to detect wake from sleep */
icculus@563
   113
    Uint8              expect_mouse_up;    /* used to determine when to send mouse up events */
icculus@563
   114
    Uint8              grab_state;         /* used to manage grab behavior */
icculus@563
   115
    NSPoint            cursor_loc;         /* saved cursor coords, for activate/deactivate when grabbed */
slouken@761
   116
    BOOL               cursor_should_be_visible;     /* tells if cursor is supposed to be visible (SDL_ShowCursor) */
slouken@761
   117
    BOOL               cursor_visible;     /* tells if cursor is *actually* visible or not */
slouken@588
   118
    Uint8*             sw_buffers[2];      /* pointers to the two software buffers for double-buffer emulation */
slouken@588
   119
    SDL_Thread         *thread;            /* thread for async updates to the screen */
slouken@588
   120
    SDL_sem            *sem1, *sem2;       /* synchronization for async screen updates */
slouken@588
   121
    Uint8              *current_buffer;    /* the buffer being copied to the screen */
slouken@588
   122
    BOOL               quit_thread;        /* used to quit the async blitting thread */
icculus@876
   123
    SInt32             system_version;     /* used to dis-/enable workarounds depending on the system version */
slouken@390
   124
icculus@1189
   125
    void *opengl_library;    /* dynamically loaded OpenGL library. */
slouken@761
   126
} SDL_PrivateVideoData;
slouken@47
   127
slouken@390
   128
#define _THIS    SDL_VideoDevice *this
slouken@47
   129
#define display_id (this->hidden->display)
slouken@47
   130
#define mode (this->hidden->mode)
slouken@47
   131
#define save_mode (this->hidden->save_mode)
icculus@5945
   132
#define use_new_mode_apis (this->hidden->use_new_mode_apis)
icculus@3936
   133
#define allow_screensaver (this->hidden->allow_screensaver)
icculus@5908
   134
#define palette (this->hidden->palette)
slouken@47
   135
#define gl_context (this->hidden->gl_context)
icculus@6157
   136
#define nsgfx_context (this->hidden->nsgfx_context)
slouken@47
   137
#define device_width (this->hidden->width)
slouken@47
   138
#define device_height (this->hidden->height)
slouken@47
   139
#define device_bpp (this->hidden->bpp)
slouken@47
   140
#define mode_flags (this->hidden->flags)
slouken@158
   141
#define qz_window (this->hidden->window)
slouken@272
   142
#define window_view (this->hidden->view)
icculus@4204
   143
#define cg_context (this->hidden->cg_context)
slouken@272
   144
#define video_set (this->hidden->video_set)
slouken@272
   145
#define warp_ticks (this->hidden->warp_ticks)
slouken@272
   146
#define warp_flag (this->hidden->warp_flag)
slouken@501
   147
#define resize_icon (this->hidden->resize_icon)
slouken@501
   148
#define current_grab_mode (this->hidden->current_grab_mode)
slouken@501
   149
#define client_mode_list (this->hidden->client_mode_list)
slouken@501
   150
#define keymap (this->hidden->keymap)
slouken@501
   151
#define current_mods (this->hidden->current_mods)
slouken@4049
   152
#define field_edit (this->hidden->field_edit)
slouken@501
   153
#define last_virtual_button (this->hidden->last_virtual_button)
icculus@563
   154
#define power_connection (this->hidden->power_connection)
icculus@563
   155
#define expect_mouse_up (this->hidden->expect_mouse_up)
icculus@563
   156
#define grab_state (this->hidden->grab_state)
icculus@563
   157
#define cursor_loc (this->hidden->cursor_loc)
slouken@761
   158
#define cursor_should_be_visible (this->hidden->cursor_should_be_visible)
icculus@563
   159
#define cursor_visible (this->hidden->cursor_visible)
slouken@588
   160
#define sw_buffers (this->hidden->sw_buffers)
icculus@4204
   161
#define sw_contexts (this->hidden->sw_contexts)
slouken@588
   162
#define thread (this->hidden->thread)
slouken@588
   163
#define sem1 (this->hidden->sem1)
slouken@588
   164
#define sem2 (this->hidden->sem2)
slouken@588
   165
#define current_buffer (this->hidden->current_buffer)
slouken@588
   166
#define quit_thread (this->hidden->quit_thread)
icculus@876
   167
#define system_version (this->hidden->system_version)
icculus@1189
   168
#define opengl_library (this->hidden->opengl_library)
slouken@501
   169
icculus@563
   170
/* grab states - the input is in one of these states */
icculus@563
   171
enum {
icculus@563
   172
    QZ_UNGRABBED = 0,
icculus@563
   173
    QZ_VISIBLE_GRAB,
icculus@563
   174
    QZ_INVISIBLE_GRAB
icculus@563
   175
};
icculus@563
   176
icculus@563
   177
/* grab actions - these can change the grabbed state */
icculus@563
   178
enum {
icculus@563
   179
    QZ_ENABLE_GRAB = 0,
icculus@563
   180
    QZ_DISABLE_GRAB,
icculus@563
   181
    QZ_HIDECURSOR,
icculus@563
   182
    QZ_SHOWCURSOR
icculus@563
   183
};
icculus@563
   184
slouken@47
   185
/* Gamma Functions */
slouken@761
   186
int    QZ_SetGamma          (_THIS, float red, float green, float blue);
slouken@761
   187
int    QZ_GetGamma          (_THIS, float *red, float *green, float *blue);
slouken@761
   188
int    QZ_SetGammaRamp      (_THIS, Uint16 *ramp);
slouken@761
   189
int    QZ_GetGammaRamp      (_THIS, Uint16 *ramp);
slouken@47
   190
slouken@47
   191
/* OpenGL functions */
slouken@761
   192
int    QZ_SetupOpenGL       (_THIS, int bpp, Uint32 flags);
slouken@761
   193
void   QZ_TearDownOpenGL    (_THIS);
slouken@761
   194
void*  QZ_GL_GetProcAddress (_THIS, const char *proc);
slouken@761
   195
int    QZ_GL_GetAttribute   (_THIS, SDL_GLattr attrib, int* value);
slouken@761
   196
int    QZ_GL_MakeCurrent    (_THIS);
slouken@761
   197
void   QZ_GL_SwapBuffers    (_THIS);
slouken@761
   198
int    QZ_GL_LoadLibrary    (_THIS, const char *location);
slouken@47
   199
slouken@47
   200
/* Cursor and Mouse functions */
slouken@761
   201
void         QZ_FreeWMCursor     (_THIS, WMcursor *cursor);
slouken@761
   202
WMcursor*    QZ_CreateWMCursor   (_THIS, Uint8 *data, Uint8 *mask,
slouken@761
   203
                                  int w, int h, int hot_x, int hot_y);
slouken@761
   204
int          QZ_ShowWMCursor     (_THIS, WMcursor *cursor);
slouken@761
   205
void         QZ_WarpWMCursor     (_THIS, Uint16 x, Uint16 y);
slouken@761
   206
void         QZ_MoveWMCursor     (_THIS, int x, int y);
slouken@761
   207
void         QZ_CheckMouseMode   (_THIS);
icculus@1212
   208
void         QZ_UpdateMouse      (_THIS);
slouken@47
   209
slouken@47
   210
/* Event functions */
slouken@761
   211
void         QZ_InitOSKeymap     (_THIS);
slouken@761
   212
void         QZ_PumpEvents       (_THIS);
slouken@47
   213
slouken@47
   214
/* Window Manager functions */
slouken@761
   215
void         QZ_SetCaption       (_THIS, const char *title, const char *icon);
slouken@761
   216
void         QZ_SetIcon          (_THIS, SDL_Surface *icon, Uint8 *mask);
slouken@761
   217
int          QZ_IconifyWindow    (_THIS);
slouken@761
   218
SDL_GrabMode QZ_GrabInput        (_THIS, SDL_GrabMode grab_mode);
slouken@761
   219
/*int          QZ_GetWMInfo        (_THIS, SDL_SysWMinfo *info);*/
slouken@272
   220
slouken@761
   221
/* Private functions (used internally) */
slouken@761
   222
void         QZ_PrivateWarpCursor (_THIS, int x, int y);
slouken@761
   223
void         QZ_ChangeGrabState (_THIS, int action);
slouken@761
   224
void         QZ_RegisterForSleepNotifications (_THIS);
slouken@761
   225
void         QZ_PrivateGlobalToLocal (_THIS, NSPoint *p);
slouken@761
   226
void         QZ_PrivateCocoaToSDL (_THIS, NSPoint *p);
slouken@779
   227
BOOL         QZ_IsMouseInWindow (_THIS);
slouken@1629
   228
void         QZ_DoActivate (_THIS);
slouken@1629
   229
void         QZ_DoDeactivate (_THIS);