Commit aba4b443 authored by Sam Lantinga's avatar Sam Lantinga

Date: Sat, 1 Jun 2002 17:56:45 -0500

From: Darrell Walisser <dwaliss1@purdue.edu>
Subject: mac patch

In this patch:

- yuv code
- links to QuickTime
- tabs -> 4 spaces
- mouse events fix
- SDLMain path parsing fix
- BUGS updates
- some miscellaneous docs/comments/code cleanup

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40391
parent 455d014f
......@@ -72,26 +72,20 @@ MacOS X:
Joystick code is not extensively tested yet.
Window may not close when unsetting video mode and resetting.
Resizeable windows aren't implemented yet.
Depth switching for windowed mode isn't implemented yet.
Palette handling isn't implemented in windowed mode yet.
Command-line arguments Dialog is not implemented yet.
Command-line arguments dialog is not implemented yet.
Fullscreen drawing has some artifacts.
Fullscreen window covers *all* other windows - even force quit.
Fullscreen OpenGL for the software renderer is broken.
Some OpenGL parameters are not accounted for, for example color bits customization.
Getting OpenGL context parameters is not implemented.
Continuous mouse motion perhaps is not as smooth as it should be.
SDL_WM_GrabInput() is implemented, but it "freezes" the hardware
......
......@@ -51,24 +51,25 @@ static BOOL gFinderLaunch;
/* Set the working directory to the .app's parent directory */
- (void) setupWorkingDirectory:(BOOL)shouldChdir
{
char parentdir[MAXPATHLEN];
char *c;
strncpy ( parentdir, gArgv[0], sizeof(parentdir) );
c = (char*) parentdir;
while (*c != '\0') /* go to end */
c++;
while (*c != '/') /* back up to parent */
c--;
*c++ = '\0'; /* cut off last part (binary name) */
if (shouldChdir)
{
assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */
assert ( chdir ("../../../") == 0 ); /* chdir to the .app's parent */
char parentdir[MAXPATHLEN];
char *c;
strncpy ( parentdir, gArgv[0], sizeof(parentdir) );
c = (char*) parentdir;
while (*c != '\0') /* go to end */
c++;
while (*c != '/') /* back up to parent */
c--;
*c++ = '\0'; /* cut off last part (binary name) */
assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */
assert ( chdir ("../../../") == 0 ); /* chdir to the .app's parent */
}
}
......
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
Sam Lantinga
slouken@libsdl.org
*/
#include <sys/time.h>
......@@ -27,479 +27,473 @@ static SDLKey keymap[256];
static unsigned int currentMods = 0; /* Current keyboard modifiers, to track modifier state */
static int last_virtual_button = 0; /* Last virtual mouse button pressed */
static void QZ_InitOSKeymap (_THIS) {
const void *KCHRPtr;
UInt32 state;
UInt32 value;
int i;
int world = SDLK_WORLD_0;
for ( i=0; i<SDL_TABLESIZE(keymap); ++i )
keymap[i] = SDLK_UNKNOWN;
/* This keymap is almost exactly the same as the OS 9 one */
keymap[QZ_ESCAPE] = SDLK_ESCAPE;
keymap[QZ_F1] = SDLK_F1;
keymap[QZ_F2] = SDLK_F2;
keymap[QZ_F3] = SDLK_F3;
keymap[QZ_F4] = SDLK_F4;
keymap[QZ_F5] = SDLK_F5;
keymap[QZ_F6] = SDLK_F6;
keymap[QZ_F7] = SDLK_F7;
keymap[QZ_F8] = SDLK_F8;
keymap[QZ_F9] = SDLK_F9;
keymap[QZ_F10] = SDLK_F10;
keymap[QZ_F11] = SDLK_F11;
keymap[QZ_F12] = SDLK_F12;
keymap[QZ_PRINT] = SDLK_PRINT;
keymap[QZ_SCROLLOCK] = SDLK_SCROLLOCK;
keymap[QZ_PAUSE] = SDLK_PAUSE;
keymap[QZ_POWER] = SDLK_POWER;
keymap[QZ_BACKQUOTE] = SDLK_BACKQUOTE;
keymap[QZ_1] = SDLK_1;
keymap[QZ_2] = SDLK_2;
keymap[QZ_3] = SDLK_3;
keymap[QZ_4] = SDLK_4;
keymap[QZ_5] = SDLK_5;
keymap[QZ_6] = SDLK_6;
keymap[QZ_7] = SDLK_7;
keymap[QZ_8] = SDLK_8;
keymap[QZ_9] = SDLK_9;
keymap[QZ_0] = SDLK_0;
keymap[QZ_MINUS] = SDLK_MINUS;
keymap[QZ_EQUALS] = SDLK_EQUALS;
keymap[QZ_BACKSPACE] = SDLK_BACKSPACE;
keymap[QZ_INSERT] = SDLK_INSERT;
keymap[QZ_HOME] = SDLK_HOME;
keymap[QZ_PAGEUP] = SDLK_PAGEUP;
keymap[QZ_NUMLOCK] = SDLK_NUMLOCK;
keymap[QZ_KP_EQUALS] = SDLK_KP_EQUALS;
keymap[QZ_KP_DIVIDE] = SDLK_KP_DIVIDE;
keymap[QZ_KP_MULTIPLY] = SDLK_KP_MULTIPLY;
keymap[QZ_TAB] = SDLK_TAB;
keymap[QZ_q] = SDLK_q;
keymap[QZ_w] = SDLK_w;
keymap[QZ_e] = SDLK_e;
keymap[QZ_r] = SDLK_r;
keymap[QZ_t] = SDLK_t;
keymap[QZ_y] = SDLK_y;
keymap[QZ_u] = SDLK_u;
keymap[QZ_i] = SDLK_i;
keymap[QZ_o] = SDLK_o;
keymap[QZ_p] = SDLK_p;
keymap[QZ_LEFTBRACKET] = SDLK_LEFTBRACKET;
keymap[QZ_RIGHTBRACKET] = SDLK_RIGHTBRACKET;
keymap[QZ_BACKSLASH] = SDLK_BACKSLASH;
keymap[QZ_DELETE] = SDLK_DELETE;
keymap[QZ_END] = SDLK_END;
keymap[QZ_PAGEDOWN] = SDLK_PAGEDOWN;
keymap[QZ_KP7] = SDLK_KP7;
keymap[QZ_KP8] = SDLK_KP8;
keymap[QZ_KP9] = SDLK_KP9;
keymap[QZ_KP_MINUS] = SDLK_KP_MINUS;
keymap[QZ_CAPSLOCK] = SDLK_CAPSLOCK;
keymap[QZ_a] = SDLK_a;
keymap[QZ_s] = SDLK_s;
keymap[QZ_d] = SDLK_d;
keymap[QZ_f] = SDLK_f;
keymap[QZ_g] = SDLK_g;
keymap[QZ_h] = SDLK_h;
keymap[QZ_j] = SDLK_j;
keymap[QZ_k] = SDLK_k;
keymap[QZ_l] = SDLK_l;
keymap[QZ_SEMICOLON] = SDLK_SEMICOLON;
keymap[QZ_QUOTE] = SDLK_QUOTE;
keymap[QZ_RETURN] = SDLK_RETURN;
keymap[QZ_KP4] = SDLK_KP4;
keymap[QZ_KP5] = SDLK_KP5;
keymap[QZ_KP6] = SDLK_KP6;
keymap[QZ_KP_PLUS] = SDLK_KP_PLUS;
keymap[QZ_LSHIFT] = SDLK_LSHIFT;
keymap[QZ_z] = SDLK_z;
keymap[QZ_x] = SDLK_x;
keymap[QZ_c] = SDLK_c;
keymap[QZ_v] = SDLK_v;
keymap[QZ_b] = SDLK_b;
keymap[QZ_n] = SDLK_n;
keymap[QZ_m] = SDLK_m;
keymap[QZ_COMMA] = SDLK_COMMA;
keymap[QZ_PERIOD] = SDLK_PERIOD;
keymap[QZ_SLASH] = SDLK_SLASH;
keymap[QZ_UP] = SDLK_UP;
keymap[QZ_KP1] = SDLK_KP1;
keymap[QZ_KP2] = SDLK_KP2;
keymap[QZ_KP3] = SDLK_KP3;
keymap[QZ_KP_ENTER] = SDLK_KP_ENTER;
keymap[QZ_LCTRL] = SDLK_LCTRL;
keymap[QZ_LALT] = SDLK_LALT;
keymap[QZ_LMETA] = SDLK_LMETA;
keymap[QZ_SPACE] = SDLK_SPACE;
keymap[QZ_LEFT] = SDLK_LEFT;
keymap[QZ_DOWN] = SDLK_DOWN;
keymap[QZ_RIGHT] = SDLK_RIGHT;
keymap[QZ_KP0] = SDLK_KP0;
keymap[QZ_KP_PERIOD] = SDLK_KP_PERIOD;
keymap[QZ_IBOOK_ENTER] = SDLK_KP_ENTER;
keymap[QZ_IBOOK_RIGHT] = SDLK_RIGHT;
keymap[QZ_IBOOK_DOWN] = SDLK_DOWN;
keymap[QZ_IBOOK_UP] = SDLK_UP;
keymap[QZ_IBOOK_LEFT] = SDLK_LEFT;
/* Up there we setup a static scancode->keysym map. However, it will not
* work very well on international keyboard. Hence we now query MacOS
* for its own keymap to adjust our own mapping table. However, this is
* bascially only useful for ascii char keys. This is also the reason
* why we keep the static table, too.
*/
/* Get a pointer to the systems cached KCHR */
KCHRPtr = (void *)GetScriptManagerVariable(smKCHRCache);
if (KCHRPtr)
{
/* Loop over all 127 possible scan codes */
for (i = 0; i < 0x7F; i++)
{
/* We pretend a clean start to begin with (i.e. no dead keys active */
state = 0;
/* Now translate the key code to a key value */
value = KeyTranslate(KCHRPtr, i, &state) & 0xff;
/* If the state become 0, it was a dead key. We need to translate again,
passing in the new state, to get the actual key value */
if (state != 0)
value = KeyTranslate(KCHRPtr, i, &state) & 0xff;
/* Now we should have an ascii value, or 0. Try to figure out to which SDL symbol it maps */
if (value >= 128) /* Some non-ASCII char, map it to SDLK_WORLD_* */
keymap[i] = world++;
else if (value >= 32) /* non-control ASCII char */
keymap[i] = value;
}
}
/* The keypad codes are re-setup here, because the loop above cannot
* distinguish between a key on the keypad and a regular key. We maybe
* could get around this problem in another fashion: NSEvent's flags
* include a "NSNumericPadKeyMask" bit; we could check that and modify
* the symbol we return on the fly. However, this flag seems to exhibit
* some weird behaviour related to the num lock key
*/
keymap[QZ_KP0] = SDLK_KP0;
keymap[QZ_KP1] = SDLK_KP1;
keymap[QZ_KP2] = SDLK_KP2;
keymap[QZ_KP3] = SDLK_KP3;
keymap[QZ_KP4] = SDLK_KP4;
keymap[QZ_KP5] = SDLK_KP5;
keymap[QZ_KP6] = SDLK_KP6;
keymap[QZ_KP7] = SDLK_KP7;
keymap[QZ_KP8] = SDLK_KP8;
keymap[QZ_KP9] = SDLK_KP9;
keymap[QZ_KP_MINUS] = SDLK_KP_MINUS;
keymap[QZ_KP_PLUS] = SDLK_KP_PLUS;
keymap[QZ_KP_PERIOD] = SDLK_KP_PERIOD;
keymap[QZ_KP_EQUALS] = SDLK_KP_EQUALS;
keymap[QZ_KP_DIVIDE] = SDLK_KP_DIVIDE;
keymap[QZ_KP_MULTIPLY] = SDLK_KP_MULTIPLY;
keymap[QZ_KP_ENTER] = SDLK_KP_ENTER;
static void QZ_InitOSKeymap (_THIS) {
const void *KCHRPtr;
UInt32 state;
UInt32 value;
int i;
int world = SDLK_WORLD_0;
for ( i=0; i<SDL_TABLESIZE(keymap); ++i )
keymap[i] = SDLK_UNKNOWN;
/* This keymap is almost exactly the same as the OS 9 one */
keymap[QZ_ESCAPE] = SDLK_ESCAPE;
keymap[QZ_F1] = SDLK_F1;
keymap[QZ_F2] = SDLK_F2;
keymap[QZ_F3] = SDLK_F3;
keymap[QZ_F4] = SDLK_F4;
keymap[QZ_F5] = SDLK_F5;
keymap[QZ_F6] = SDLK_F6;
keymap[QZ_F7] = SDLK_F7;
keymap[QZ_F8] = SDLK_F8;
keymap[QZ_F9] = SDLK_F9;
keymap[QZ_F10] = SDLK_F10;
keymap[QZ_F11] = SDLK_F11;
keymap[QZ_F12] = SDLK_F12;
keymap[QZ_PRINT] = SDLK_PRINT;
keymap[QZ_SCROLLOCK] = SDLK_SCROLLOCK;
keymap[QZ_PAUSE] = SDLK_PAUSE;
keymap[QZ_POWER] = SDLK_POWER;
keymap[QZ_BACKQUOTE] = SDLK_BACKQUOTE;
keymap[QZ_1] = SDLK_1;
keymap[QZ_2] = SDLK_2;
keymap[QZ_3] = SDLK_3;
keymap[QZ_4] = SDLK_4;
keymap[QZ_5] = SDLK_5;
keymap[QZ_6] = SDLK_6;
keymap[QZ_7] = SDLK_7;
keymap[QZ_8] = SDLK_8;
keymap[QZ_9] = SDLK_9;
keymap[QZ_0] = SDLK_0;
keymap[QZ_MINUS] = SDLK_MINUS;
keymap[QZ_EQUALS] = SDLK_EQUALS;
keymap[QZ_BACKSPACE] = SDLK_BACKSPACE;
keymap[QZ_INSERT] = SDLK_INSERT;
keymap[QZ_HOME] = SDLK_HOME;
keymap[QZ_PAGEUP] = SDLK_PAGEUP;
keymap[QZ_NUMLOCK] = SDLK_NUMLOCK;
keymap[QZ_KP_EQUALS] = SDLK_KP_EQUALS;
keymap[QZ_KP_DIVIDE] = SDLK_KP_DIVIDE;
keymap[QZ_KP_MULTIPLY] = SDLK_KP_MULTIPLY;
keymap[QZ_TAB] = SDLK_TAB;
keymap[QZ_q] = SDLK_q;
keymap[QZ_w] = SDLK_w;
keymap[QZ_e] = SDLK_e;
keymap[QZ_r] = SDLK_r;
keymap[QZ_t] = SDLK_t;
keymap[QZ_y] = SDLK_y;
keymap[QZ_u] = SDLK_u;
keymap[QZ_i] = SDLK_i;
keymap[QZ_o] = SDLK_o;
keymap[QZ_p] = SDLK_p;
keymap[QZ_LEFTBRACKET] = SDLK_LEFTBRACKET;
keymap[QZ_RIGHTBRACKET] = SDLK_RIGHTBRACKET;
keymap[QZ_BACKSLASH] = SDLK_BACKSLASH;
keymap[QZ_DELETE] = SDLK_DELETE;
keymap[QZ_END] = SDLK_END;
keymap[QZ_PAGEDOWN] = SDLK_PAGEDOWN;
keymap[QZ_KP7] = SDLK_KP7;
keymap[QZ_KP8] = SDLK_KP8;
keymap[QZ_KP9] = SDLK_KP9;
keymap[QZ_KP_MINUS] = SDLK_KP_MINUS;
keymap[QZ_CAPSLOCK] = SDLK_CAPSLOCK;
keymap[QZ_a] = SDLK_a;
keymap[QZ_s] = SDLK_s;
keymap[QZ_d] = SDLK_d;
keymap[QZ_f] = SDLK_f;
keymap[QZ_g] = SDLK_g;
keymap[QZ_h] = SDLK_h;
keymap[QZ_j] = SDLK_j;
keymap[QZ_k] = SDLK_k;
keymap[QZ_l] = SDLK_l;
keymap[QZ_SEMICOLON] = SDLK_SEMICOLON;
keymap[QZ_QUOTE] = SDLK_QUOTE;
keymap[QZ_RETURN] = SDLK_RETURN;
keymap[QZ_KP4] = SDLK_KP4;
keymap[QZ_KP5] = SDLK_KP5;
keymap[QZ_KP6] = SDLK_KP6;
keymap[QZ_KP_PLUS] = SDLK_KP_PLUS;
keymap[QZ_LSHIFT] = SDLK_LSHIFT;
keymap[QZ_z] = SDLK_z;
keymap[QZ_x] = SDLK_x;
keymap[QZ_c] = SDLK_c;
keymap[QZ_v] = SDLK_v;
keymap[QZ_b] = SDLK_b;
keymap[QZ_n] = SDLK_n;
keymap[QZ_m] = SDLK_m;
keymap[QZ_COMMA] = SDLK_COMMA;
keymap[QZ_PERIOD] = SDLK_PERIOD;
keymap[QZ_SLASH] = SDLK_SLASH;
keymap[QZ_UP] = SDLK_UP;
keymap[QZ_KP1] = SDLK_KP1;
keymap[QZ_KP2] = SDLK_KP2;
keymap[QZ_KP3] = SDLK_KP3;
keymap[QZ_KP_ENTER] = SDLK_KP_ENTER;
keymap[QZ_LCTRL] = SDLK_LCTRL;
keymap[QZ_LALT] = SDLK_LALT;
keymap[QZ_LMETA] = SDLK_LMETA;
keymap[QZ_SPACE] = SDLK_SPACE;
keymap[QZ_LEFT] = SDLK_LEFT;
keymap[QZ_DOWN] = SDLK_DOWN;
keymap[QZ_RIGHT] = SDLK_RIGHT;
keymap[QZ_KP0] = SDLK_KP0;
keymap[QZ_KP_PERIOD] = SDLK_KP_PERIOD;
keymap[QZ_IBOOK_ENTER] = SDLK_KP_ENTER;
keymap[QZ_IBOOK_RIGHT] = SDLK_RIGHT;
keymap[QZ_IBOOK_DOWN] = SDLK_DOWN;
keymap[QZ_IBOOK_UP] = SDLK_UP;
keymap[QZ_IBOOK_LEFT] = SDLK_LEFT;
/* Up there we setup a static scancode->keysym map. However, it will not
* work very well on international keyboard. Hence we now query MacOS
* for its own keymap to adjust our own mapping table. However, this is
* bascially only useful for ascii char keys. This is also the reason
* why we keep the static table, too.
*/
/* Get a pointer to the systems cached KCHR */
KCHRPtr = (void *)GetScriptManagerVariable(smKCHRCache);
if (KCHRPtr)
{
/* Loop over all 127 possible scan codes */
for (i = 0; i < 0x7F; i++)
{
/* We pretend a clean start to begin with (i.e. no dead keys active */
state = 0;
/* Now translate the key code to a key value */
value = KeyTranslate(KCHRPtr, i, &state) & 0xff;
/* If the state become 0, it was a dead key. We need to translate again,
passing in the new state, to get the actual key value */
if (state != 0)
value = KeyTranslate(KCHRPtr, i, &state) & 0xff;
/* Now we should have an ascii value, or 0. Try to figure out to which SDL symbol it maps */
if (value >= 128) /* Some non-ASCII char, map it to SDLK_WORLD_* */
keymap[i] = world++;
else if (value >= 32) /* non-control ASCII char */
keymap[i] = value;
}
}
/* The keypad codes are re-setup here, because the loop above cannot
* distinguish between a key on the keypad and a regular key. We maybe
* could get around this problem in another fashion: NSEvent's flags
* include a "NSNumericPadKeyMask" bit; we could check that and modify
* the symbol we return on the fly. However, this flag seems to exhibit
* some weird behaviour related to the num lock key
*/
keymap[QZ_KP0] = SDLK_KP0;
keymap[QZ_KP1] = SDLK_KP1;
keymap[QZ_KP2] = SDLK_KP2;
keymap[QZ_KP3] = SDLK_KP3;
keymap[QZ_KP4] = SDLK_KP4;
keymap[QZ_KP5] = SDLK_KP5;
keymap[QZ_KP6] = SDLK_KP6;
keymap[QZ_KP7] = SDLK_KP7;
keymap[QZ_KP8] = SDLK_KP8;
keymap[QZ_KP9] = SDLK_KP9;
keymap[QZ_KP_MINUS] = SDLK_KP_MINUS;
keymap[QZ_KP_PLUS] = SDLK_KP_PLUS;
keymap[QZ_KP_PERIOD] = SDLK_KP_PERIOD;
keymap[QZ_KP_EQUALS] = SDLK_KP_EQUALS;
keymap[QZ_KP_DIVIDE] = SDLK_KP_DIVIDE;
keymap[QZ_KP_MULTIPLY] = SDLK_KP_MULTIPLY;
keymap[QZ_KP_ENTER] = SDLK_KP_ENTER;
}
static void QZ_DoKey (int state, NSEvent *event) {
NSString *chars;
int i;
SDL_keysym key;
/* An event can contain multiple characters */
/* I'll ignore this fact for now, since there is only one virtual key code per event */
chars = [ event characters ];
for (i =0; i < 1 /*[ chars length ] */; i++) {
key.scancode = [ event keyCode ];
key.sym = keymap [ key.scancode ];
key.unicode = [ chars characterAtIndex:i];
key.mod = KMOD_NONE;
SDL_PrivateKeyboard (state, &key);
}
NSString *chars;
int i;
SDL_keysym key;
/* An event can contain multiple characters */
/* I'll ignore this fact for now, since there is only one virtual key code per event */
chars = [ event characters ];
for (i =0; i < 1 /*[ chars length ] */; i++) {
key.scancode = [ event keyCode ];
key.sym = keymap [ key.scancode ];
key.unicode = [ chars characterAtIndex:i];
key.mod = KMOD_NONE;
SDL_PrivateKeyboard (state, &key);
}
}
static void QZ_DoModifiers (unsigned int newMods) {
const int mapping[] = { SDLK_CAPSLOCK, SDLK_LSHIFT, SDLK_LCTRL, SDLK_LALT, SDLK_LMETA } ;
int i;
int bit;
SDL_keysym key;
key.scancode = 0;
key.sym = SDLK_UNKNOWN;
key.unicode = 0;
key.mod = KMOD_NONE;
/* Iterate through the bits, testing each against the current modifiers */
for (i = 0, bit = NSAlphaShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1, ++i) {
unsigned int currentMask, newMask;
currentMask = currentMods & bit;
newMask = newMods & bit;
if ( currentMask &&
currentMask != newMask ) { /* modifier up event */
key.sym = mapping[i];
/* If this was Caps Lock, we need some additional voodoo to make SDL happy */
if (bit == NSAlphaShiftKeyMask)
SDL_PrivateKeyboard (SDL_PRESSED, &key);
SDL_PrivateKeyboard (SDL_RELEASED, &key);
}
else
if ( newMask &&
currentMask != newMask ) { /* modifier down event */
key.sym = mapping[i];
SDL_PrivateKeyboard (SDL_PRESSED, &key);
/* If this was Caps Lock, we need some additional voodoo to make SDL happy */
if (bit == NSAlphaShiftKeyMask)
SDL_PrivateKeyboard (SDL_RELEASED, &key);
}
}
currentMods = newMods;
const int mapping[] = { SDLK_CAPSLOCK, SDLK_LSHIFT, SDLK_LCTRL, SDLK_LALT, SDLK_LMETA } ;
int i;
int bit;
SDL_keysym key;
key.scancode = 0;
key.sym = SDLK_UNKNOWN;
key.unicode = 0;
key.mod = KMOD_NONE;
/* Iterate through the bits, testing each against the current modifiers */
for (i = 0, bit = NSAlphaShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1, ++i) {
unsigned int currentMask, newMask;
currentMask = currentMods & bit;
newMask = newMods & bit;
if ( currentMask &&
currentMask != newMask ) { /* modifier up event */
key.sym = mapping[i];
/* If this was Caps Lock, we need some additional voodoo to make SDL happy */
if (bit == NSAlphaShiftKeyMask)
SDL_PrivateKeyboard (SDL_PRESSED, &key);
SDL_PrivateKeyboard (SDL_RELEASED, &key);
}
else if ( newMask &&
currentMask != newMask ) { /* modifier down event */
key.sym = mapping[i];
SDL_PrivateKeyboard (SDL_PRESSED, &key);
/* If this was Caps Lock, we need some additional voodoo to make SDL happy */
if (bit == NSAlphaShiftKeyMask)
SDL_PrivateKeyboard (SDL_RELEASED, &key);
}
}
currentMods = newMods;
}
static void QZ_DoActivate (_THIS)
{
inForeground = YES;
/* Regrab the mouse */
if (currentGrabMode == SDL_GRAB_ON) {
QZ_WarpWMCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2);
CGAssociateMouseAndMouseCursorPosition (0);
}
/* Hide the mouse cursor if inside the app window */
if (!QZ_cursor_visible) {
HideCursor ();
}
SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS);
inForeground = YES;
/* Regrab the mouse */
if (currentGrabMode == SDL_GRAB_ON) {
QZ_WarpWMCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2);
CGAssociateMouseAndMouseCursorPosition (0);
}
/* Hide the mouse cursor if inside the app window */
if (!QZ_cursor_visible) {
HideCursor ();
}
SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS);
}
static void QZ_DoDeactivate (_THIS) {
inForeground = NO;
/* Ungrab mouse if it is grabbed */
if (currentGrabMode == SDL_GRAB_ON) {
CGAssociateMouseAndMouseCursorPosition (1);
}
/* Show the mouse cursor */
if (!QZ_cursor_visible) {
ShowCursor ();
}
SDL_PrivateAppActive (0, SDL_APPINPUTFOCUS);
inForeground = NO;
/* Ungrab mouse if it is grabbed */
if (currentGrabMode == SDL_GRAB_ON) {
CGAssociateMouseAndMouseCursorPosition (1);
}
/* Show the mouse cursor */
if (!QZ_cursor_visible) {
ShowCursor ();
}
SDL_PrivateAppActive (0, SDL_APPINPUTFOCUS);
}
static void QZ_PumpEvents (_THIS)
{
static NSPoint lastMouse;
NSPoint mouse, saveMouse;
Point qdMouse;
CGMouseDelta dx, dy;
NSDate *distantPast;
NSEvent *event;
NSRect winRect;
NSRect titleBarRect;
NSAutoreleasePool *pool;
pool = [ [ NSAutoreleasePool alloc ] init ];
distantPast = [ NSDate distantPast ];
winRect = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
titleBarRect = NSMakeRect ( 0, SDL_VideoSurface->h, SDL_VideoSurface->w,
SDL_VideoSurface->h + 22 );
if (currentGrabMode != SDL_GRAB_ON) { /* if grabbed, the cursor can't move! (see fallback below) */
/* 1/2 second after a warp, the mouse cannot move (don't ask me why) */
/* So, approximate motion with CGGetLastMouseDelta, which still works, somehow */
if (! warp_flag) {
static NSPoint lastMouse;
NSPoint mouse, saveMouse;
Point qdMouse;
CGMouseDelta dx, dy;
NSDate *distantPast;
NSEvent *event;
NSRect winRect;
NSRect titleBarRect;
NSAutoreleasePool *pool;
pool = [ [ NSAutoreleasePool alloc ] init ];
distantPast = [ NSDate distantPast ];
winRect = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
titleBarRect = NSMakeRect ( 0, SDL_VideoSurface->h, SDL_VideoSurface->w,
SDL_VideoSurface->h + 22 );
if (currentGrabMode != SDL_GRAB_ON) { /* if grabbed, the cursor can't move! (see fallback below) */
/* 1/2 second after a warp, the mouse cannot move (don't ask me why) */
/* So, approximate motion with CGGetLastMouseDelta, which still works, somehow */
if (! warp_flag) {
GetGlobalMouse (&qdMouse); /* use Carbon since [ NSEvent mouseLocation ] is broken */
mouse = NSMakePoint (qdMouse.h, qdMouse.v);
saveMouse = mouse;
if (mouse.x != lastMouse.x || mouse.y != lastMouse.y) {
QZ_PrivateCGToSDL (this, &mouse);
/* -note- we now generate mouse motion events if the mouse isn't over the window */
if (inForeground /* && NSPointInRect (mouse, winRect)*/) {
//printf ("Mouse Loc: (%f, %f)\n", mouse.x, mouse.y);
SDL_PrivateMouseMotion (0, 0, mouse.x, mouse.y);
}
}
lastMouse = saveMouse;
}
}
/* accumulate any mouse events into one SDL mouse event */
dx = 0;
dy = 0;
do {
/* Poll for an event. This will not block */
event = [ NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:distantPast
inMode: NSDefaultRunLoopMode dequeue:YES ];
if (event != nil) {
unsigned int type;
BOOL isForGameWin;
#define DO_MOUSE_DOWN(button, sendToWindow) do { \
if ( inForeground ) { \
if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) || \
NSPointInRect([event locationInWindow], winRect) ) \
SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); \
} \
else { \
QZ_DoActivate (this); \
} \
[ NSApp sendEvent:event ]; \
} while(0)
#define DO_MOUSE_UP(button, sendToWindow) do { \
if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) || \
!NSPointInRect([event locationInWindow], titleBarRect) ) \
SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0); \
[ NSApp sendEvent:event ]; \
} while(0)
GetGlobalMouse (&qdMouse); /* use Carbon since [ NSEvent mouseLocation ] is broken */
mouse = NSMakePoint (qdMouse.h, qdMouse.v);
saveMouse = mouse;
type = [ event type ];
isForGameWin = (qz_window == [ event window ]);
switch (type) {
case NSLeftMouseDown:
if ( NSCommandKeyMask & currentMods ) {
last_virtual_button = 3;
DO_MOUSE_DOWN (3, 0);
}
else if ( NSAlternateKeyMask & currentMods ) {
last_virtual_button = 2;
DO_MOUSE_DOWN (2, 0);
}
else {
DO_MOUSE_DOWN (1, 1);
}
break;
case NSOtherMouseDown: DO_MOUSE_DOWN (2, 0); break;
case NSRightMouseDown: DO_MOUSE_DOWN (3, 0); break;
case NSLeftMouseUp:
if ( last_virtual_button != 0 ) {
DO_MOUSE_UP (last_virtual_button, 0);
last_virtual_button = 0;
}
else {
DO_MOUSE_UP (1, 1);
}
break;
case NSOtherMouseUp: DO_MOUSE_UP (2, 0); break;
case NSRightMouseUp: DO_MOUSE_UP (3, 0); break;
case NSSystemDefined:
//if ([event subtype] == 7) {
// unsigned int buttons; // up to 32 mouse button states!
// buttons = [ event data2 ];
//}
break;
case NSLeftMouseDragged:
case NSRightMouseDragged:
case 27:
case NSMouseMoved:
if (currentGrabMode == SDL_GRAB_ON) {
/**
* If input is grabbed, we'll wing it and try to send some mouse
* moved events with CGGetLastMouseDelta(). Not optimal, but better
* than nothing.
**/
CGMouseDelta dx1, dy1;
CGGetLastMouseDelta (&dx1, &dy1);
dx += dx1;
dy += dy1;
}
else if (warp_flag) {
Uint32 ticks;
ticks = SDL_GetTicks();
if (ticks - warp_ticks < 150) {
if (mouse.x != lastMouse.x || mouse.y != lastMouse.y) {
CGMouseDelta dx1, dy1;
CGGetLastMouseDelta (&dx1, &dy1);
dx += dx1;
dy += dy1;
}
else {
QZ_PrivateCGToSDL (this, &mouse);
if (inForeground && NSPointInRect (mouse, winRect)) {
//printf ("Mouse Loc: (%f, %f)\n", mouse.x, mouse.y);
SDL_PrivateMouseMotion (0, 0, mouse.x, mouse.y);
warp_flag = 0;
}
}
}
lastMouse = saveMouse;
break;
case NSScrollWheel:
if (NSPointInRect([ event locationInWindow ], winRect)) {
float dy;
dy = [ event deltaY ];
if ( dy > 0.0 ) /* Scroll up */
SDL_PrivateMouseButton (SDL_PRESSED, 4, 0, 0);
else /* Scroll down */
SDL_PrivateMouseButton (SDL_PRESSED, 5, 0, 0);
}
break;
case NSKeyUp:
QZ_DoKey (SDL_RELEASED, event);
break;
case NSKeyDown:
QZ_DoKey (SDL_PRESSED, event);
break;
case NSFlagsChanged:
QZ_DoModifiers( [ event modifierFlags ] );
break;
case NSAppKitDefined:
switch ( [ event subtype ] ) {
case NSApplicationActivatedEventType:
QZ_DoActivate (this);
break;
case NSApplicationDeactivatedEventType:
QZ_DoDeactivate (this);
break;
}
[ NSApp sendEvent:event ];
break;
/* case NSApplicationDefined: break; */
/* case NSPeriodic: break; */
/* case NSCursorUpdate: break; */
default:
[ NSApp sendEvent:event ];
}
}
/* accumulate any mouse events into one SDL mouse event */
dx = 0;
dy = 0;
do {
/* Poll for an event. This will not block */
event = [ NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:distantPast
inMode: NSDefaultRunLoopMode dequeue:YES ];
if (event != nil) {
unsigned int type;
BOOL isForGameWin;
#define DO_MOUSE_DOWN(button, sendToWindow) do { \
if ( inForeground ) { \
if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) || \
NSPointInRect([event locationInWindow], winRect) ) \
SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); \
} \
else { \
QZ_DoActivate (this); \
} \
[ NSApp sendEvent:event ]; \
} while(0)
#define DO_MOUSE_UP(button, sendToWindow) do { \
if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) || \
!NSPointInRect([event locationInWindow], titleBarRect) ) \
SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0); \
[ NSApp sendEvent:event ]; \
} while(0)
type = [ event type ];
isForGameWin = (qz_window == [ event window ]);
switch (type) {
case NSLeftMouseDown:
if ( NSCommandKeyMask & currentMods ) {
last_virtual_button = 3;
DO_MOUSE_DOWN (3, 0);
}
else if ( NSAlternateKeyMask & currentMods ) {
last_virtual_button = 2;
DO_MOUSE_DOWN (2, 0);
}
else {
DO_MOUSE_DOWN (1, 1);
}
break;
case NSOtherMouseDown: DO_MOUSE_DOWN (2, 0); break;
case NSRightMouseDown: DO_MOUSE_DOWN (3, 0); break;
case NSLeftMouseUp:
if ( last_virtual_button != 0 ) {
DO_MOUSE_UP (last_virtual_button, 0);
last_virtual_button = 0;
}
else {
DO_MOUSE_UP (1, 1);
}
break;
case NSOtherMouseUp: DO_MOUSE_UP (2, 0); break;
case NSRightMouseUp: DO_MOUSE_UP (3, 0); break;
case NSSystemDefined:
//if ([event subtype] == 7) {
// unsigned int buttons; // up to 32 mouse button states!
// buttons = [ event data2 ];
//}
break;
case NSLeftMouseDragged:
case NSRightMouseDragged:
case 27:
case NSMouseMoved:
if (currentGrabMode == SDL_GRAB_ON) {
/**
* If input is grabbed, we'll wing it and try to send some mouse
* moved events with CGGetLastMouseDelta(). Not optimal, but better
* than nothing.
**/
CGMouseDelta dx1, dy1;
CGGetLastMouseDelta (&dx1, &dy1);
dx += dx1;
dy += dy1;
}
else if (warp_flag) {
Uint32 ticks;
ticks = SDL_GetTicks();
if (ticks - warp_ticks < 150) {
CGMouseDelta dx1, dy1;
CGGetLastMouseDelta (&dx1, &dy1);
dx += dx1;
dy += dy1;
}
else {
warp_flag = 0;
}
}
break;
case NSScrollWheel:
{
if (NSPointInRect([ event locationInWindow ], winRect)) {
float dy;
dy = [ event deltaY ];
if ( dy > 0.0 ) /* Scroll up */
SDL_PrivateMouseButton (SDL_PRESSED, 4, 0, 0);
else /* Scroll down */
SDL_PrivateMouseButton (SDL_PRESSED, 5, 0, 0);
}
}
break;
case NSKeyUp:
QZ_DoKey (SDL_RELEASED, event);
break;
case NSKeyDown:
QZ_DoKey (SDL_PRESSED, event);
break;
case NSFlagsChanged:
QZ_DoModifiers( [ event modifierFlags ] );
break;
case NSAppKitDefined:
switch ( [ event subtype ] ) {
case NSApplicationActivatedEventType:
QZ_DoActivate (this);
break;
case NSApplicationDeactivatedEventType:
QZ_DoDeactivate (this);
break;
}
[ NSApp sendEvent:event ];
break;
/* case NSApplicationDefined: break; */
/* case NSPeriodic: break; */
/* case NSCursorUpdate: break; */
default:
[ NSApp sendEvent:event ];
}
}
} while (event != nil);
/* check for accumulated mouse events */
if (dx != 0 || dy != 0)
SDL_PrivateMouseMotion (0, 1, dx, dy);
[ pool release ];
} while (event != nil);
/* check for accumulated mouse events */
if (dx != 0 || dy != 0)
SDL_PrivateMouseMotion (0, 1, dx, dy);
[ pool release ];
}
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
*/
/* These are the Macintosh key scancode constants -- from Inside Macintosh */
......@@ -36,10 +36,10 @@
#define QZ_F11 0x67
#define QZ_F12 0x6F
#define QZ_PRINT 0x69
#define QZ_SCROLLOCK 0x6B
#define QZ_SCROLLOCK 0x6B
#define QZ_PAUSE 0x71
#define QZ_POWER 0x7F
#define QZ_BACKQUOTE 0x32
#define QZ_BACKQUOTE 0x32
#define QZ_1 0x12
#define QZ_2 0x13
#define QZ_3 0x14
......@@ -52,14 +52,14 @@
#define QZ_0 0x1D
#define QZ_MINUS 0x1B
#define QZ_EQUALS 0x18
#define QZ_BACKSPACE 0x33
#define QZ_BACKSPACE 0x33
#define QZ_INSERT 0x72
#define QZ_HOME 0x73
#define QZ_PAGEUP 0x74
#define QZ_NUMLOCK 0x47
#define QZ_KP_EQUALS 0x51
#define QZ_KP_DIVIDE 0x4B
#define QZ_KP_MULTIPLY 0x43
#define QZ_KP_EQUALS 0x51
#define QZ_KP_DIVIDE 0x4B
#define QZ_KP_MULTIPLY 0x43
#define QZ_TAB 0x30
#define QZ_q 0x0C
#define QZ_w 0x0D
......@@ -71,9 +71,9 @@
#define QZ_i 0x22
#define QZ_o 0x1F
#define QZ_p 0x23
#define QZ_LEFTBRACKET 0x21
#define QZ_RIGHTBRACKET 0x1E
#define QZ_BACKSLASH 0x2A
#define QZ_LEFTBRACKET 0x21
#define QZ_RIGHTBRACKET 0x1E
#define QZ_BACKSLASH 0x2A
#define QZ_DELETE 0x75
#define QZ_END 0x77
#define QZ_PAGEDOWN 0x79
......@@ -91,7 +91,7 @@
#define QZ_j 0x26
#define QZ_k 0x28
#define QZ_l 0x25
#define QZ_SEMICOLON 0x29
#define QZ_SEMICOLON 0x29
#define QZ_QUOTE 0x27
#define QZ_RETURN 0x24
#define QZ_KP4 0x56
......@@ -130,11 +130,11 @@
#define QZ_DOWN 0x7D
#define QZ_RIGHT 0x7C
#define QZ_KP0 0x52
#define QZ_KP_PERIOD 0x41
#define QZ_KP_PERIOD 0x41
/* Wierd, these keys are on my iBook under MacOS X */
#define QZ_IBOOK_ENTER 0x34
#define QZ_IBOOK_LEFT 0x3B
#define QZ_IBOOK_RIGHT 0x3C
#define QZ_IBOOK_DOWN 0x3D
#define QZ_IBOOK_UP 0x3E
#define QZ_IBOOK_UP 0x3E
......@@ -20,7 +20,7 @@
slouken@libsdl.org
*/
/*
/*
@file SDL_QuartzVideo.h
@author Darrell Walisser
......@@ -33,16 +33,15 @@
- Keyboard repeat/mouse speed adjust (if needed)
- Multiple monitor support (currently only main display)
- Accelerated blitting support
- Set the window icon (dock icon when API is available)
- Fix white OpenGL window on minimize
- Fix white OpenGL window on minimize (fixed)
- Find out what events should be sent/ignored if window is mimimized
- Find a better way to deal with resolution/depth switch while app is running
- Find a way to deal with external resolution/depth switch while app is running
- Resizeable windows
- Check accuracy of QZ_SetGamma()
Problems:
- OGL not working in full screen with software renderer
- SetColors sets palette correctly but clears framebuffer
- Crash in CG after several mode switches
- Crash in CG after several mode switches (I think this has been fixed)
- Retained windows don't draw their title bar quite right (OS Bug) (not using retained windows)
- Cursor in 8 bit modes is screwy (might just be Radeon PCI bug)
- Warping cursor delays mouse events for a fraction of a second,
......@@ -52,6 +51,7 @@
#include <Cocoa/Cocoa.h>
#include <OpenGL/OpenGL.h>
#include <Carbon/Carbon.h>
#include <QuickTime/QuickTime.h>
#include "SDL_video.h"
#include "SDL_error.h"
......@@ -102,10 +102,17 @@ typedef struct SDL_PrivateVideoData {
Uint32 warp_ticks; /* timestamp when the warp occured */
NSWindow *window; /* Cocoa window to implement the SDL window */
NSQuickDrawView *view; /* the window's view; draw 2D into this view */
ImageDescriptionHandle yuv_idh;
MatrixRecordPtr yuv_matrix;
DecompressorComponent yuv_codec;
ImageSequence yuv_seq;
PlanarPixmapInfoYUV420 *yuv_pixmap;
Sint16 yuv_width, yuv_height;
CGrafPtr yuv_port;
} SDL_PrivateVideoData ;
#define _THIS SDL_VideoDevice *this
#define _THIS SDL_VideoDevice *this
#define display_id (this->hidden->display)
#define mode (this->hidden->mode)
#define save_mode (this->hidden->save_mode)
......@@ -121,6 +128,15 @@ typedef struct SDL_PrivateVideoData {
#define video_set (this->hidden->video_set)
#define warp_ticks (this->hidden->warp_ticks)
#define warp_flag (this->hidden->warp_flag)
#define yuv_idh (this->hidden->yuv_idh)
#define yuv_matrix (this->hidden->yuv_matrix)
#define yuv_codec (this->hidden->yuv_codec)
#define yuv_seq (this->hidden->yuv_seq)
#define yuv_pixmap (this->hidden->yuv_pixmap)
#define yuv_data (this->hidden->yuv_data)
#define yuv_width (this->hidden->yuv_width)
#define yuv_height (this->hidden->yuv_height)
#define yuv_port (this->hidden->yuv_port)
/* Obscuring code: maximum number of windows above ours (inclusive) */
#define kMaxWindows 256
......@@ -144,16 +160,16 @@ typedef struct SDL_PrivateVideoData {
*/
typedef CGError CGSError;
typedef long CGSWindowCount;
typedef void * CGSConnectionID;
typedef int CGSWindowID;
typedef long CGSWindowCount;
typedef void * CGSConnectionID;
typedef int CGSWindowID;
typedef CGSWindowID* CGSWindowIDList;
typedef CGWindowLevel CGSWindowLevel;
typedef NSRect CGSRect;
extern CGSConnectionID _CGSDefaultConnection ();
extern CGSError CGSGetOnScreenWindowList (CGSConnectionID cid,
extern CGSError CGSGetOnScreenWindowList (CGSConnectionID cid,
CGSConnectionID owner,
CGSWindowCount listCapacity,
CGSWindowIDList list,
......@@ -166,9 +182,9 @@ extern CGSError CGSGetScreenRectForWindow (CGSConnectionID cid,
extern CGWindowLevel CGSGetWindowLevel (CGSConnectionID cid,
CGSWindowID wid,
CGSWindowLevel *level);
extern CGSError CGSDisplayHWFill (CGDirectDisplayID id, unsigned int x, unsigned int y,
unsigned int w, unsigned int h, unsigned int color);
extern CGSError CGSDisplayHWFill (CGDirectDisplayID id, unsigned int x, unsigned int y,
unsigned int w, unsigned int h, unsigned int color);
extern CGSError CGSDisplayCanHWFill (CGDirectDisplayID id);
......@@ -182,16 +198,16 @@ static void QZ_DeleteDevice (SDL_VideoDevice *device);
/* Initialization, Query, Setup, and Redrawing functions */
static int QZ_VideoInit (_THIS, SDL_PixelFormat *video_format);
static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format,
Uint32 flags);
static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format,
Uint32 flags);
static void QZ_UnsetVideoMode (_THIS);
static SDL_Surface* QZ_SetVideoMode (_THIS, SDL_Surface *current,
int width, int height, int bpp,
Uint32 flags);
static SDL_Surface* QZ_SetVideoMode (_THIS, SDL_Surface *current,
int width, int height, int bpp,
Uint32 flags);
static int QZ_ToggleFullScreen (_THIS, int on);
static int QZ_SetColors (_THIS, int first_color,
int num_colors, SDL_Color *colors);
static int QZ_SetColors (_THIS, int first_color,
int num_colors, SDL_Color *colors);
static void QZ_DirectUpdate (_THIS, int num_rects, SDL_Rect *rects);
static void QZ_UpdateRects (_THIS, int num_rects, SDL_Rect *rects);
static void QZ_VideoQuit (_THIS);
......@@ -223,8 +239,8 @@ static void QZ_PrivateWarpCursor (_THIS, int x, int y);
/* Cursor and Mouse functions */
static void QZ_FreeWMCursor (_THIS, WMcursor *cursor);
static WMcursor* QZ_CreateWMCursor (_THIS, Uint8 *data, Uint8 *mask,
int w, int h, int hot_x, int hot_y);
static WMcursor* QZ_CreateWMCursor (_THIS, Uint8 *data, Uint8 *mask,
int w, int h, int hot_x, int hot_y);
static int QZ_ShowWMCursor (_THIS, WMcursor *cursor);
static void QZ_WarpWMCursor (_THIS, Uint16 x, Uint16 y);
static void QZ_MoveWMCursor (_THIS, int x, int y);
......@@ -241,3 +257,7 @@ static int QZ_IconifyWindow (_THIS);
static SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode);
/*static int QZ_GetWMInfo (_THIS, SDL_SysWMinfo *info);*/
/* YUV functions */
static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
Uint32 format, SDL_Surface *display);
......@@ -32,7 +32,6 @@ static char QZ_Error[255]; /* Global error buffer to temporarily store more info
#include "SDL_QuartzEvents.m"
#include "SDL_QuartzWindow.m"
/* Bootstrap binding, enables entry point into the driver */
VideoBootStrap QZ_bootstrap = {
"Quartz", "Mac OS X CoreGraphics", QZ_Available, QZ_CreateDevice
......@@ -100,7 +99,9 @@ static SDL_VideoDevice* QZ_CreateDevice (int device_index) {
/*device->GetWMInfo = QZ_GetWMInfo;*/
device->GrabInput = QZ_GrabInput;
device->free = QZ_DeleteDevice;
device->CreateYUVOverlay = QZ_CreateYUVOverlay;
device->free = QZ_DeleteDevice;
return device;
}
......@@ -135,106 +136,106 @@ static int QZ_VideoInit (_THIS, SDL_PixelFormat *video_format) {
}
static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) {
CFIndex num_modes;
CFIndex i;
static SDL_Rect **list = NULL;
int list_size = 0;
/* Any windowed mode is acceptable */
if ( (flags & SDL_FULLSCREEN) == 0 )
return (SDL_Rect**)-1;
/* Free memory from previous call, if any */
if ( list != NULL ) {
int i;
int i;
for (i = 0; list[i] != NULL; i++)
free (list[i]);
for (i = 0; list[i] != NULL; i++)
free (list[i]);
free (list);
list = NULL;
free (list);
list = NULL;
}
num_modes = CFArrayGetCount (mode_list);
/* Build list of modes with the requested bpp */
for (i = 0; i < num_modes; i++) {
CFDictionaryRef onemode;
CFNumberRef number;
int bpp;
onemode = CFArrayGetValueAtIndex (mode_list, i);
number = CFDictionaryGetValue (onemode, kCGDisplayBitsPerPixel);
CFNumberGetValue (number, kCFNumberSInt32Type, &bpp);
if (bpp == format->BitsPerPixel) {
int intvalue;
int hasMode;
int width, height;
number = CFDictionaryGetValue (onemode, kCGDisplayWidth);
CFNumberGetValue (number, kCFNumberSInt32Type, &intvalue);
width = (Uint16) intvalue;
number = CFDictionaryGetValue (onemode, kCGDisplayHeight);
CFNumberGetValue (number, kCFNumberSInt32Type, &intvalue);
height = (Uint16) intvalue;
/* Check if mode is already in the list */
{
int i;
hasMode = SDL_FALSE;
for (i = 0; i < list_size; i++) {
if (list[i]->w == width && list[i]->h == height) {
hasMode = SDL_TRUE;
break;
int bpp;
onemode = CFArrayGetValueAtIndex (mode_list, i);
number = CFDictionaryGetValue (onemode, kCGDisplayBitsPerPixel);
CFNumberGetValue (number, kCFNumberSInt32Type, &bpp);
if (bpp == format->BitsPerPixel) {
int intvalue;
int hasMode;
int width, height;
number = CFDictionaryGetValue (onemode, kCGDisplayWidth);
CFNumberGetValue (number, kCFNumberSInt32Type, &intvalue);
width = (Uint16) intvalue;
number = CFDictionaryGetValue (onemode, kCGDisplayHeight);
CFNumberGetValue (number, kCFNumberSInt32Type, &intvalue);
height = (Uint16) intvalue;
/* Check if mode is already in the list */
{
int i;
hasMode = SDL_FALSE;
for (i = 0; i < list_size; i++) {
if (list[i]->w == width && list[i]->h == height) {
hasMode = SDL_TRUE;
break;
}
}
}
}
/* Grow the list and add mode to the list */
if ( ! hasMode ) {
SDL_Rect *rect;
list_size++;
if (list == NULL)
list = (SDL_Rect**) malloc (sizeof(*list) * (list_size+1) );
else
list = (SDL_Rect**) realloc (list, sizeof(*list) * (list_size+1));
rect = (SDL_Rect*) malloc (sizeof(**list));
if (list == NULL || rect == NULL) {
SDL_OutOfMemory ();
return NULL;
/* Grow the list and add mode to the list */
if ( ! hasMode ) {
SDL_Rect *rect;
list_size++;
if (list == NULL)
list = (SDL_Rect**) malloc (sizeof(*list) * (list_size+1) );
else
list = (SDL_Rect**) realloc (list, sizeof(*list) * (list_size+1));
rect = (SDL_Rect*) malloc (sizeof(**list));
if (list == NULL || rect == NULL) {
SDL_OutOfMemory ();
return NULL;
}
rect->w = width;
rect->h = height;
list[list_size-1] = rect;
list[list_size] = NULL;
}
rect->w = width;
rect->h = height;
list[list_size-1] = rect;
list[list_size] = NULL;
}
}
}
/* Sort list largest to smallest (by area) */
{
int i, j;
for (i = 0; i < list_size; i++) {
for (j = 0; j < list_size-1; j++) {
int area1, area2;
area1 = list[j]->w * list[j]->h;
area2 = list[j+1]->w * list[j+1]->h;
if (area1 < area2) {
SDL_Rect *tmp = list[j];
list[j] = list[j+1];
......@@ -299,8 +300,8 @@ static UInt32 QZ_FadeGammaOut (_THIS, SDL_QuartzGammaTable *table) {
static UInt32 QZ_FadeGammaIn (_THIS, SDL_QuartzGammaTable *table) {
CGGammaValue redTable[QZ_GAMMA_TABLE_SIZE],
greenTable[QZ_GAMMA_TABLE_SIZE],
blueTable[QZ_GAMMA_TABLE_SIZE];
greenTable[QZ_GAMMA_TABLE_SIZE],
blueTable[QZ_GAMMA_TABLE_SIZE];
float percent;
int j;
......@@ -308,7 +309,7 @@ static UInt32 QZ_FadeGammaIn (_THIS, SDL_QuartzGammaTable *table) {
memset (redTable, 0, sizeof(redTable));
memset (greenTable, 0, sizeof(greenTable));
memset (blueTable, 0, sizeof(greenTable));
for (percent = 0.0; percent <= 1.0; percent += 0.01) {
for (j = 0; j < QZ_GAMMA_TABLE_SIZE; j++) {
......@@ -338,7 +339,7 @@ static void QZ_UnsetVideoMode (_THIS) {
this->info.blit_fill = 0;
this->FillHWRect = NULL;
this->UpdateRects = NULL;
/* Release fullscreen resources */
if ( mode_flags & SDL_FULLSCREEN ) {
......@@ -351,7 +352,7 @@ static void QZ_UnsetVideoMode (_THIS) {
/* Do this first to avoid trash on the display before fade */
if ( mode_flags & SDL_OPENGL )
QZ_TearDownOpenGL (this);
if (mode_flags & SDL_OPENGL)
CGLSetFullScreen(NULL);
......@@ -359,12 +360,12 @@ static void QZ_UnsetVideoMode (_THIS) {
CGDisplaySwitchToMode (display_id, save_mode);
CGDisplayRelease (display_id);
ShowMenuBar ();
if (! gamma_error)
QZ_FadeGammaIn (this, &gamma_table);
}
/* Release window mode resources */
else {
else {
if ( (mode_flags & SDL_OPENGL) == 0 ) {
UnlockPortBits ( [ window_view qdPort ] );
[ window_view release ];
......@@ -373,7 +374,7 @@ static void QZ_UnsetVideoMode (_THIS) {
[ qz_window setDelegate:nil ];
[ qz_window close ];
[ qz_window release ];
qz_window = nil;
qz_window = nil;
/* Release the OpenGL context */
if ( mode_flags & SDL_OPENGL )
......@@ -382,15 +383,15 @@ static void QZ_UnsetVideoMode (_THIS) {
/* Restore gamma settings */
CGDisplayRestoreColorSyncSettings ();
/* Set pixels to null (so other code doesn't try to free it) */
if (this->screen != NULL)
this->screen->pixels = NULL;
/* Ensure the cursor will be visible and working when we quit */
CGDisplayShowCursor (display_id);
CGAssociateMouseAndMouseCursorPosition (1);
/* Signal successful teardown */
video_set = SDL_FALSE;
}
......@@ -400,11 +401,11 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt
int exact_match;
int gamma_error;
SDL_QuartzGammaTable gamma_table;
/* See if requested mode exists */
mode = CGDisplayBestModeForParameters (display_id, bpp, width,
height, &exact_match);
mode = CGDisplayBestModeForParameters (display_id, bpp, width,
height, &exact_match);
/* Require an exact match to the requested mode */
if ( ! exact_match ) {
sprintf (QZ_Error, "Failed to find display resolution: %dx%dx%d", width, height, bpp);
......@@ -421,7 +422,7 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt
goto ERR_NO_CAPTURE;
}
/* Do the physical switch */
if ( CGDisplayNoErr != CGDisplaySwitchToMode (display_id, mode) ) {
SDL_SetError ("Failed switching display resolution");
......@@ -434,45 +435,45 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt
current->flags = 0;
current->w = width;
current->h = height;
current->flags |= SDL_FULLSCREEN;
current->flags |= SDL_FULLSCREEN;
current->flags |= SDL_HWSURFACE;
this->UpdateRects = QZ_DirectUpdate;
/* Setup some mode-dependant info */
if ( CGSDisplayCanHWFill (display_id) ) {
this->info.blit_fill = 1;
this->FillHWRect = QZ_FillHWRect;
this->info.blit_fill = 1;
this->FillHWRect = QZ_FillHWRect;
}
if ( CGDisplayCanSetPalette (display_id) )
current->flags |= SDL_HWPALETTE;
/* Setup OpenGL for a fullscreen context */
if (flags & SDL_OPENGL) {
CGLError err;
CGLContextObj ctx;
if ( ! QZ_SetupOpenGL (this, bpp, flags) ) {
goto ERR_NO_GL;
}
ctx = [ gl_context cglContext ];
err = CGLSetFullScreen (ctx);
if (err) {
sprintf (QZ_Error, "Error setting OpenGL fullscreen: %s", CGLErrorString(err));
SDL_SetError (QZ_Error);
goto ERR_NO_GL;
}
[ gl_context makeCurrentContext];
glClear (GL_COLOR_BUFFER_BIT);
[ gl_context flushBuffer ];
current->flags |= SDL_OPENGL;
}
......@@ -482,23 +483,23 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt
/* Fade the display to original gamma */
if (! gamma_error )
QZ_FadeGammaIn (this, &gamma_table);
/* Save the flags to ensure correct tear-down */
mode_flags = current->flags;
return current;
/* Since the blanking window covers *all* windows (even force quit) correct recovery is crucial */
ERR_NO_GL: CGDisplaySwitchToMode (display_id, save_mode);
ERR_NO_SWITCH: CGDisplayRelease (display_id);
ERR_NO_CAPTURE: if (!gamma_error) { QZ_FadeGammaIn (this, &gamma_table); }
ERR_NO_MATCH: return NULL;
/* Since the blanking window covers *all* windows (even force quit) correct recovery is crucial */
ERR_NO_GL: CGDisplaySwitchToMode (display_id, save_mode);
ERR_NO_SWITCH: CGDisplayRelease (display_id);
ERR_NO_CAPTURE: if (!gamma_error) { QZ_FadeGammaIn (this, &gamma_table); }
ERR_NO_MATCH: return NULL;
}
static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,
int height, int bpp, Uint32 flags) {
int height, int bpp, Uint32 flags) {
unsigned int style;
NSRect rect;
NSRect rect;
rect = NSMakeRect (0, 0, width, height);
#if 1 // FIXME - the resize button doesn't show? Also need resize events...
......@@ -515,17 +516,17 @@ static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,
}
/* Manually create a window, avoids having a nib file resource */
qz_window = [ [ SDL_QuartzWindow alloc ] initWithContentRect:rect
styleMask:style backing:NSBackingStoreBuffered defer:NO ];
qz_window = [ [ SDL_QuartzWindow alloc ] initWithContentRect:rect
styleMask:style backing:NSBackingStoreBuffered defer:NO ];
if (qz_window == nil) {
SDL_SetError ("Could not create the Cocoa window");
return NULL;
}
current->flags = 0;
current->w = width;
current->h = height;
[ qz_window setReleasedWhenClosed:YES ];
QZ_SetCaption(this, this->wm_title, this->wm_icon);
[ qz_window setAcceptsMouseMovedEvents:YES ];
......@@ -533,14 +534,14 @@ static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,
[ qz_window center ];
[ qz_window setDelegate:
[ [ [ SDL_QuartzWindowDelegate alloc ] init ] autorelease ] ];
/* For OpenGL, we set the content view to a NSOpenGLView */
if ( flags & SDL_OPENGL ) {
if ( ! QZ_SetupOpenGL (this, bpp, flags) ) {
return NULL;
}
[ gl_context setView: [ qz_window contentView ] ];
[ gl_context makeCurrentContext];
[ qz_window makeKeyAndOrderFront:nil ];
......@@ -548,45 +549,45 @@ static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,
}
/* For 2D, we set the content view to a NSQuickDrawView */
else {
window_view = [ [ SDL_QuartzWindowView alloc ] init ];
[ qz_window setContentView:window_view ];
[ qz_window makeKeyAndOrderFront:nil ];
[ qz_window makeKeyAndOrderFront:nil ];
LockPortBits ( [ window_view qdPort ] );
current->pixels = GetPixBaseAddr ( GetPortPixMap ( [ window_view qdPort ] ) );
current->pitch = GetPixRowBytes ( GetPortPixMap ( [ window_view qdPort ] ) );
current->flags |= SDL_SWSURFACE;
current->flags |= SDL_PREALLOC;
if ( flags & SDL_NOFRAME )
current->flags |= SDL_NOFRAME;
if ( flags & SDL_RESIZABLE )
current->flags |= SDL_RESIZABLE;
if ( flags & SDL_NOFRAME )
current->flags |= SDL_NOFRAME;
if ( flags & SDL_RESIZABLE )
current->flags |= SDL_RESIZABLE;
/* Offset 22 pixels down to fill the full content region */
if ( ! (current->flags & SDL_NOFRAME) ) {
current->pixels += 22 * current->pitch;
}
if ( ! (current->flags & SDL_NOFRAME) ) {
current->pixels += 22 * current->pitch;
}
this->UpdateRects = QZ_UpdateRects;
}
/* Save flags to ensure correct teardown */
mode_flags = current->flags;
return current;
}
static SDL_Surface* QZ_SetVideoMode (_THIS, SDL_Surface *current, int width,
int height, int bpp, Uint32 flags) {
static SDL_Surface* QZ_SetVideoMode (_THIS, SDL_Surface *current, int width,
int height, int bpp, Uint32 flags) {
if (video_set == SDL_TRUE)
QZ_UnsetVideoMode (this);
current->flags = 0;
/* Setup full screen video */
if ( flags & SDL_FULLSCREEN ) {
current = QZ_SetVideoFullScreen (this, current, width, height, bpp, flags );
......@@ -601,17 +602,17 @@ static SDL_Surface* QZ_SetVideoMode (_THIS, SDL_Surface *current, int width,
if (current == NULL)
return NULL;
}
/* Setup the new pixel format */
{
int amask = 0,
rmask = 0,
gmask = 0,
bmask = 0;
int amask = 0,
rmask = 0,
gmask = 0,
bmask = 0;
switch (bpp) {
case 16: /* (1)-5-5-5 RGB */
amask = 0;
amask = 0;
rmask = 0x7C00;
gmask = 0x03E0;
bmask = 0x001F;
......@@ -626,212 +627,212 @@ static SDL_Surface* QZ_SetVideoMode (_THIS, SDL_Surface *current, int width,
bmask = 0x000000FF;
break;
}
if ( ! SDL_ReallocFormat (current, bpp,
rmask, gmask, bmask, amask ) ) {
SDL_SetError ("Couldn't reallocate pixel format");
return NULL;
}
SDL_SetError ("Couldn't reallocate pixel format");
return NULL;
}
}
/* Signal successful completion (used internally) */
video_set = SDL_TRUE;
return current;
}
static int QZ_ToggleFullScreen (_THIS, int on) {
static int QZ_ToggleFullScreen (_THIS, int on) {
return -1;
}
static int QZ_SetColors (_THIS, int first_color, int num_colors,
SDL_Color *colors) {
static int QZ_SetColors (_THIS, int first_color, int num_colors,
SDL_Color *colors) {
CGTableCount index;
CGDeviceColor color;
for (index = first_color; index < first_color+num_colors; index++) {
/* Clamp colors between 0.0 and 1.0 */
color.red = colors->r / 255.0;
color.blue = colors->b / 255.0;
color.green = colors->g / 255.0;
colors++;
CGPaletteSetColorAtIndex (palette, color, index);
}
if ( CGDisplayNoErr != CGDisplaySetPalette (display_id, palette) )
return 0;
return 1;
}
static void QZ_DirectUpdate (_THIS, int num_rects, SDL_Rect *rects) {
#pragma unused(this,num_rects,rects)
#pragma unused(this,num_rects,rects)
}
/**
/**
* The obscured code is based on work by Matt Slot fprefect@ambrosiasw.com,
* who supplied sample code for Carbon.
**/
static int QZ_IsWindowObscured (NSWindow *window) {
//#define TEST_OBSCURED 1
//#define TEST_OBSCURED 1
#if TEST_OBSCURED
/* In order to determine if a direct copy to the screen is possible,
we must figure out if there are any windows covering ours (including shadows).
This can be done by querying the window server about the on screen
windows for their screen rectangle and window level.
The procedure used below is puts accuracy before speed; however, it aims to call
the window server the fewest number of times possible to keep things reasonable.
In my testing on a 300mhz G3, this routine typically takes < 2 ms. -DW
we must figure out if there are any windows covering ours (including shadows).
This can be done by querying the window server about the on screen
windows for their screen rectangle and window level.
The procedure used below is puts accuracy before speed; however, it aims to call
the window server the fewest number of times possible to keep things reasonable.
In my testing on a 300mhz G3, this routine typically takes < 2 ms. -DW
Notes:
-Calls into the Window Server involve IPC which is slow.
-Getting a rectangle seems slower than getting the window level
-The window list we get back is in sorted order, top to bottom
-On average, I suspect, most windows above ours are dock icon windows (hence optimization)
-Some windows above ours are always there, and cannot move or obscure us (menu bar)
Bugs:
-no way (yet) to deactivate direct drawing when a window is dragged,
or suddenly obscured, so drawing continues and can produce garbage
We need some kind of locking mechanism on window movement to prevent this
-deactivated normal windows use activated normal
window shadows (slight inaccuraccy)
*/
Notes:
-Calls into the Window Server involve IPC which is slow.
-Getting a rectangle seems slower than getting the window level
-The window list we get back is in sorted order, top to bottom
-On average, I suspect, most windows above ours are dock icon windows (hence optimization)
-Some windows above ours are always there, and cannot move or obscure us (menu bar)
/* Cache the connection to the window server */
static CGSConnectionID cgsConnection = (CGSConnectionID) -1;
Bugs:
-no way (yet) to deactivate direct drawing when a window is dragged,
or suddenly obscured, so drawing continues and can produce garbage
We need some kind of locking mechanism on window movement to prevent this
-deactivated normal windows use activated normal
window shadows (slight inaccuraccy)
*/
/* Cache the connection to the window server */
static CGSConnectionID cgsConnection = (CGSConnectionID) -1;
/* Cache the dock icon windows */
static CGSWindowID dockIcons[kMaxWindows];
static int numCachedDockIcons = 0;
CGSWindowID windows[kMaxWindows];
CGSWindowCount i, count;
CGSWindowLevel winLevel;
CGSRect winRect;
CGSWindowID windows[kMaxWindows];
CGSWindowCount i, count;
CGSWindowLevel winLevel;
CGSRect winRect;
CGSRect contentRect;
int windowNumber;
//int isMainWindow;
int firstDockIcon;
int firstDockIcon;
int dockIconCacheMiss;
int windowContentOffset;
int obscured = SDL_TRUE;
if ( [ window isVisible ] ) {
/* walk the window list looking for windows over top of
(or casting a shadow on) ours */
/* walk the window list looking for windows over top of
(or casting a shadow on) ours */
/* Get a connection to the window server */
/* Should probably be moved out into SetVideoMode() or InitVideo() */
if (cgsConnection == (CGSConnectionID) -1) {
cgsConnection = (CGSConnectionID) 0;
cgsConnection = _CGSDefaultConnection ();
}
if (cgsConnection) {
if (cgsConnection) {
if ( ! [ window styleMask ] & NSBorderlessWindowMask )
windowContentOffset = 22;
else
windowContentOffset = 0;
windowNumber = [ window windowNumber ];
//isMainWindow = [ window isMainWindow ];
/* The window list is sorted according to order on the screen */
count = 0;
CGSGetOnScreenWindowList (cgsConnection, 0, kMaxWindows, windows, &count);
CGSGetScreenRectForWindow (cgsConnection, windowNumber, &contentRect);
/* adjust rect for window title bar (if present) */
contentRect.origin.y += windowContentOffset;
contentRect.size.height -= windowContentOffset;
firstDockIcon = -1;
dockIconCacheMiss = SDL_FALSE;
/* The first window is always an empty window with level kCGSWindowLevelTop
so start at index 1 */
/* The first window is always an empty window with level kCGSWindowLevelTop
so start at index 1 */
for (i = 1; i < count; i++) {
/* If we reach our window in the list, it cannot be obscured */
if (windows[i] == windowNumber) {
obscured = SDL_FALSE;
break;
}
else {
float shadowSide;
float shadowTop;
float shadowBottom;
CGSGetWindowLevel (cgsConnection, windows[i], &winLevel);
if (winLevel == kCGSWindowLevelDockIcon) {
int j;
if (firstDockIcon < 0) {
firstDockIcon = i;
if (numCachedDockIcons > 0) {
for (j = 0; j < numCachedDockIcons; j++) {
if (windows[i] == dockIcons[j])
i++;
else
break;
}
if (j != 0) {
i--;
if (j < numCachedDockIcons) {
dockIconCacheMiss = SDL_TRUE;
}
}
}
}
continue;
}
else if (winLevel == kCGSWindowLevelMenuIgnore
/* winLevel == kCGSWindowLevelTop */) {
continue; /* cannot obscure window */
}
else if (winLevel == kCGSWindowLevelDockMenu ||
winLevel == kCGSWindowLevelMenu) {
shadowSide = 18;
shadowTop = 4;
shadowBottom = 22;
shadowBottom = 22;
}
else if (winLevel == kCGSWindowLevelUtility) {
shadowSide = 8;
shadowTop = 4;
shadowBottom = 12;
}
else if (winLevel == kCGSWindowLevelNormal) {
/* These numbers are for foreground windows,
they are too big (but will work) for background windows */
shadowSide = 20;
......@@ -839,52 +840,52 @@ static int QZ_IsWindowObscured (NSWindow *window) {
shadowBottom = 24;
}
else if (winLevel == kCGSWindowLevelDock) {
/* Create dock icon cache */
if (numCachedDockIcons != (i-firstDockIcon) ||
dockIconCacheMiss) {
numCachedDockIcons = i - firstDockIcon;
memcpy (dockIcons, &(windows[firstDockIcon]),
memcpy (dockIcons, &(windows[firstDockIcon]),
numCachedDockIcons * sizeof(*windows));
}
/* no shadow */
shadowSide = 0;
shadowTop = 0;
shadowBottom = 0;
}
else {
/* kCGSWindowLevelDockLabel,
kCGSWindowLevelDock,
kOther??? */
kCGSWindowLevelDock,
kOther??? */
/* no shadow */
shadowSide = 0;
shadowTop = 0;
shadowBottom = 0;
}
CGSGetScreenRectForWindow (cgsConnection, windows[i], &winRect);
winRect.origin.x -= shadowSide;
winRect.origin.y -= shadowTop;
winRect.size.width += shadowSide;
winRect.size.height += shadowBottom;
if (NSIntersectsRect (contentRect, winRect)) {
obscured = SDL_TRUE;
break;
}
} /* window was not our window */
} /* window was not our window */
} /* iterate over windows */
} /* get cgsConnection */
} /* window is visible */
return obscured;
......@@ -893,86 +894,86 @@ static int QZ_IsWindowObscured (NSWindow *window) {
#endif
}
static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) {
static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) {
if (SDL_VideoSurface->flags & SDL_OPENGLBLIT) {
QZ_GL_SwapBuffers (this);
}
else if ( [ qz_window isMiniaturized ] &&
else if ( [ qz_window isMiniaturized ] &&
! (SDL_VideoSurface->flags & SDL_OPENGL)) {
/**
/**
* Set port alpha opaque so deminiaturize looks right
* This isn't so nice, but there is no
* This isn't so nice, but there is no
* initial deminatureize notification (before demini starts)
**/
QZ_SetPortAlphaOpaque ([ [ qz_window contentView ] qdPort],
[ qz_window styleMask ] & NSBorderlessWindowMask);
[ qz_window styleMask ] & NSBorderlessWindowMask);
}
else if ( ! QZ_IsWindowObscured (qz_window) ) {
/* Use direct copy to flush contents to the display */
CGrafPtr savePort;
CGrafPtr dstPort, srcPort;
const BitMap *dstBits, *srcBits;
Rect dstRect, srcRect;
Rect dstRect, srcRect;
Point offset;
int i;
GetPort (&savePort);
dstPort = CreateNewPortForCGDisplayID ((UInt32)display_id);
srcPort = [ window_view qdPort ];
offset.h = 0;
offset.v = 0;
SetPort (srcPort);
LocalToGlobal (&offset);
SetPort (dstPort);
LockPortBits (dstPort);
LockPortBits (srcPort);
dstBits = GetPortBitMapForCopyBits (dstPort);
srcBits = GetPortBitMapForCopyBits (srcPort);
for (i = 0; i < numRects; i++) {
SetRect (&srcRect, rects[i].x, rects[i].y,
rects[i].x + rects[i].w,
rects[i].y + rects[i].h);
SetRect (&dstRect,
rects[i].x + offset.h,
rects[i].x + offset.h,
rects[i].y + offset.v,
rects[i].x + rects[i].w + offset.h,
rects[i].y + rects[i].h + offset.v);
CopyBits (srcBits, dstBits,
&srcRect, &dstRect, srcCopy, NULL);
}
SetPort (savePort);
}
else {
/* Use QDFlushPortBuffer() to flush content to display */
int i;
RgnHandle dirty = NewRgn ();
RgnHandle temp = NewRgn ();
SetEmptyRgn (dirty);
/* Build the region of dirty rectangles */
for (i = 0; i < numRects; i++) {
MacSetRectRgn (temp, rects[i].x, rects[i].y,
rects[i].x + rects[i].w, rects[i].y + rects[i].h);
MacSetRectRgn (temp, rects[i].x, rects[i].y,
rects[i].x + rects[i].w, rects[i].y + rects[i].h);
MacUnionRgn (dirty, temp, dirty);
}
/* Flush the dirty region */
QDFlushPortBuffer ( [ window_view qdPort ], dirty );
DisposeRgn (dirty);
......@@ -993,7 +994,7 @@ static int QZ_FillHWRect (_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color
return 0;
}
static int QZ_LockHWSurface(_THIS, SDL_Surface *surface) {
static int QZ_LockHWSurface(_THIS, SDL_Surface *surface) {
return 1;
}
......@@ -1006,10 +1007,10 @@ static void QZ_FreeHWSurface (_THIS, SDL_Surface *surface) {
}
/*
int QZ_FlipHWSurface (_THIS, SDL_Surface *surface) {
return 0;
}
*/
int QZ_FlipHWSurface (_THIS, SDL_Surface *surface) {
return 0;
}
*/
/* Gamma functions */
static int QZ_SetGamma (_THIS, float red, float green, float blue) {
......@@ -1030,14 +1031,14 @@ static int QZ_SetGamma (_THIS, float red, float green, float blue) {
blue = FLT_MAX;
else
blue = 1.0 / blue;
if ( CGDisplayNoErr == CGSetDisplayTransferByFormula
(display_id, min, max, red, min, max, green, min, max, blue) ) {
if ( CGDisplayNoErr == CGSetDisplayTransferByFormula
(display_id, min, max, red, min, max, green, min, max, blue) ) {
return 0;
}
else {
return -1;
}
}
......@@ -1046,66 +1047,66 @@ static int QZ_GetGamma (_THIS, float *red, float *green, float *blue) {
CGGammaValue dummy;
if ( CGDisplayNoErr == CGGetDisplayTransferByFormula
(display_id, &dummy, &dummy, red,
&dummy, &dummy, green, &dummy, &dummy, blue) )
(display_id, &dummy, &dummy, red,
&dummy, &dummy, green, &dummy, &dummy, blue) )
return 0;
else
return -1;
}
static int QZ_SetGammaRamp (_THIS, Uint16 *ramp) {
const CGTableCount tableSize = 255;
CGGammaValue redTable[tableSize];
CGGammaValue greenTable[tableSize];
CGGammaValue blueTable[tableSize];
int i;
/* Extract gamma values into separate tables, convert to floats between 0.0 and 1.0 */
for (i = 0; i < 256; i++)
redTable[i % 256] = ramp[i] / 65535.0;
for (i=256; i < 512; i++)
greenTable[i % 256] = ramp[i] / 65535.0;
for (i=512; i < 768; i++)
blueTable[i % 256] = ramp[i] / 65535.0;
if ( CGDisplayNoErr == CGSetDisplayTransferByTable
(display_id, tableSize, redTable, greenTable, blueTable) )
const CGTableCount tableSize = 255;
CGGammaValue redTable[tableSize];
CGGammaValue greenTable[tableSize];
CGGammaValue blueTable[tableSize];
int i;
/* Extract gamma values into separate tables, convert to floats between 0.0 and 1.0 */
for (i = 0; i < 256; i++)
redTable[i % 256] = ramp[i] / 65535.0;
for (i=256; i < 512; i++)
greenTable[i % 256] = ramp[i] / 65535.0;
for (i=512; i < 768; i++)
blueTable[i % 256] = ramp[i] / 65535.0;
if ( CGDisplayNoErr == CGSetDisplayTransferByTable
(display_id, tableSize, redTable, greenTable, blueTable) )
return 0;
else
return -1;
}
static int QZ_GetGammaRamp (_THIS, Uint16 *ramp) {
const CGTableCount tableSize = 255;
CGGammaValue redTable[tableSize];
CGGammaValue greenTable[tableSize];
CGGammaValue blueTable[tableSize];
CGTableCount actual;
int i;
if ( CGDisplayNoErr != CGGetDisplayTransferByTable
(display_id, tableSize, redTable, greenTable, blueTable, &actual) ||
actual != tableSize)
if ( CGDisplayNoErr != CGGetDisplayTransferByTable
(display_id, tableSize, redTable, greenTable, blueTable, &actual) ||
actual != tableSize)
return -1;
/* Pack tables into one array, with values from 0 to 65535 */
for (i = 0; i < 256; i++)
ramp[i] = redTable[i % 256] * 65535.0;
for (i=256; i < 512; i++)
ramp[i] = greenTable[i % 256] * 65535.0;
for (i=512; i < 768; i++)
ramp[i] = blueTable[i % 256] * 65535.0;
return 0;
return 0;
}
/* OpenGL helper functions (used internally) */
......@@ -1118,53 +1119,53 @@ static int QZ_SetupOpenGL (_THIS, int bpp, Uint32 flags) {
int colorBits = bpp;
if ( flags & SDL_FULLSCREEN ) {
attr[i++] = NSOpenGLPFAFullScreen;
}
/* In windowed mode, the OpenGL pixel depth must match device pixel depth */
else if ( colorBits != device_bpp ) {
else if ( colorBits != device_bpp ) {
colorBits = device_bpp;
}
attr[i++] = NSOpenGLPFAColorSize;
attr[i++] = colorBits;
attr[i++] = NSOpenGLPFADepthSize;
attr[i++] = this->gl_config.depth_size;
if ( this->gl_config.double_buffer ) {
attr[i++] = NSOpenGLPFADoubleBuffer;
}
if ( this->gl_config.stencil_size != 0 ) {
attr[i++] = NSOpenGLPFAStencilSize;
attr[i++] = this->gl_config.stencil_size;
}
attr[i++] = NSOpenGLPFAScreenMask;
attr[i++] = CGDisplayIDToOpenGLDisplayMask (display_id);
attr[i] = 0;
fmt = [ [ NSOpenGLPixelFormat alloc ] initWithAttributes:attr ];
if (fmt == nil) {
SDL_SetError ("Failed creating OpenGL pixel format");
return 0;
}
gl_context = [ [ NSOpenGLContext alloc ] initWithFormat:fmt
shareContext:nil];
gl_context = [ [ NSOpenGLContext alloc ] initWithFormat:fmt
shareContext:nil];
if (gl_context == nil) {
SDL_SetError ("Failed creating OpenGL context");
return 0;
}
}
/* Convince SDL that the GL "driver" is loaded */
this->gl_config.driver_loaded = 1;
[ fmt release ];
return 1;
}
......@@ -1187,23 +1188,23 @@ static void* QZ_GL_GetProcAddress (_THIS, const char *proc) {
/* We may want to cache the bundleRef at some point */
CFBundleRef bundle;
CFURLRef bundleURL = CFURLCreateWithFileSystemPath (kCFAllocatorDefault,
CFSTR("/System/Library/Frameworks/OpenGL.framework"), kCFURLPOSIXPathStyle, true);
CFStringRef functionName = CFStringCreateWithCString
CFURLRef bundleURL = CFURLCreateWithFileSystemPath (kCFAllocatorDefault,
CFSTR("/System/Library/Frameworks/OpenGL.framework"), kCFURLPOSIXPathStyle, true);
CFStringRef functionName = CFStringCreateWithCString
(kCFAllocatorDefault, proc, kCFStringEncodingASCII);
void *function;
bundle = CFBundleCreate (kCFAllocatorDefault, bundleURL);
assert (bundle != NULL);
function = CFBundleGetFunctionPointerForName (bundle, functionName);
CFRelease ( bundleURL );
CFRelease ( functionName );
CFRelease ( bundle );
return function;
}
......@@ -1214,18 +1215,18 @@ static int QZ_GL_GetAttribute (_THIS, SDL_GLattr attrib, int* value) {
QZ_GL_MakeCurrent (this);
switch (attrib) {
case SDL_GL_RED_SIZE: attr = GL_RED_BITS; break;
case SDL_GL_BLUE_SIZE: attr = GL_BLUE_BITS; break;
case SDL_GL_GREEN_SIZE: attr = GL_GREEN_BITS; break;
case SDL_GL_ALPHA_SIZE: attr = GL_ALPHA_BITS; break;
case SDL_GL_DOUBLEBUFFER: attr = GL_DOUBLEBUFFER; break;
case SDL_GL_DEPTH_SIZE: attr = GL_DEPTH_BITS; break;
case SDL_GL_STENCIL_SIZE: attr = GL_STENCIL_BITS; break;
case SDL_GL_ACCUM_RED_SIZE: attr = GL_ACCUM_RED_BITS; break;
case SDL_GL_ACCUM_GREEN_SIZE: attr = GL_ACCUM_GREEN_BITS; break;
case SDL_GL_ACCUM_BLUE_SIZE: attr = GL_ACCUM_BLUE_BITS; break;
case SDL_GL_ACCUM_ALPHA_SIZE: attr = GL_ACCUM_ALPHA_BITS; break;
case SDL_GL_BUFFER_SIZE:
case SDL_GL_RED_SIZE: attr = GL_RED_BITS; break;
case SDL_GL_BLUE_SIZE: attr = GL_BLUE_BITS; break;
case SDL_GL_GREEN_SIZE: attr = GL_GREEN_BITS; break;
case SDL_GL_ALPHA_SIZE: attr = GL_ALPHA_BITS; break;
case SDL_GL_DOUBLEBUFFER: attr = GL_DOUBLEBUFFER; break;
case SDL_GL_DEPTH_SIZE: attr = GL_DEPTH_BITS; break;
case SDL_GL_STENCIL_SIZE: attr = GL_STENCIL_BITS; break;
case SDL_GL_ACCUM_RED_SIZE: attr = GL_ACCUM_RED_BITS; break;
case SDL_GL_ACCUM_GREEN_SIZE: attr = GL_ACCUM_GREEN_BITS; break;
case SDL_GL_ACCUM_BLUE_SIZE: attr = GL_ACCUM_BLUE_BITS; break;
case SDL_GL_ACCUM_ALPHA_SIZE: attr = GL_ACCUM_ALPHA_BITS; break;
case SDL_GL_BUFFER_SIZE:
{
GLint bits = 0;
GLint component;
......@@ -1254,4 +1255,298 @@ static void QZ_GL_SwapBuffers (_THIS) {
[ gl_context flushBuffer ];
}
static int QZ_LockYUV (_THIS, SDL_Overlay *overlay) {
return 0;
}
static void QZ_UnlockYUV (_THIS, SDL_Overlay *overlay) {
;
}
static int QZ_DisplayYUV (_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect) {
OSErr err;
CodecFlags flags;
if (dstrect->x != 0 || dstrect->y != 0) {
SDL_SetError ("Need a dstrect at (0,0)");
return -1;
}
if (dstrect->w != yuv_width || dstrect->h != yuv_height) {
Fixed scale_x, scale_y;
scale_x = FixDiv ( Long2Fix (dstrect->w), Long2Fix (overlay->w) );
scale_y = FixDiv ( Long2Fix (dstrect->h), Long2Fix (overlay->h) );
SetIdentityMatrix (yuv_matrix);
ScaleMatrix (yuv_matrix, scale_x, scale_y, Long2Fix (0), Long2Fix (0));
SetDSequenceMatrix (yuv_seq, yuv_matrix);
yuv_width = dstrect->w;
yuv_height = dstrect->h;
}
if( ( err = DecompressSequenceFrameS(
yuv_seq,
(void*)yuv_pixmap,
sizeof (PlanarPixmapInfoYUV420),
codecFlagUseImageBuffer, &flags, nil ) != noErr ) )
{
SDL_SetError ("DecompressSequenceFrameS failed");
}
return err == noErr;
}
static void QZ_FreeHWYUV (_THIS, SDL_Overlay *overlay) {
CDSequenceEnd (yuv_seq);
ExitMovies();
free (overlay->hwfuncs);
free (overlay->pitches);
free (overlay->pixels);
if (SDL_VideoSurface->flags & SDL_FULLSCREEN) {
[ qz_window close ];
qz_window = nil;
}
free (yuv_matrix);
DisposeHandle ((Handle)yuv_idh);
}
#include "SDL_yuvfuncs.h"
/**
* check for 16 byte alignment, bail otherwise
**/
#define CHECK_ALIGN(x) do { if ((Uint32)x & 15) { SDL_SetError("Alignment error"); return NULL; } } while(0)
/**
* align a byte offset, return how much to add to make it
* a multiple of 16
**/
#define ALIGN(x) ((16 - (x & 15)) & 15)
static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
Uint32 format, SDL_Surface *display) {
Uint32 codec;
OSStatus err;
CGrafPtr port;
SDL_Overlay *overlay;
if (format == SDL_YV12_OVERLAY ||
format == SDL_IYUV_OVERLAY) {
codec = kYUV420CodecType;
}
else {
SDL_SetError ("Hardware: unsupported video format");
return NULL;
}
yuv_idh = (ImageDescriptionHandle) NewHandleClear (sizeof(ImageDescription));
if (yuv_idh == NULL) {
SDL_OutOfMemory();
return NULL;
}
yuv_matrix = (MatrixRecordPtr) malloc (sizeof(MatrixRecord));
if (yuv_matrix == NULL) {
SDL_OutOfMemory();
return NULL;
}
if ( EnterMovies() != noErr ) {
SDL_SetError ("Could not init QuickTime for YUV playback");
return NULL;
}
err = FindCodec (codec, bestSpeedCodec, nil, &yuv_codec);
if (err != noErr) {
SDL_SetError ("Could not find QuickTime codec for format");
return NULL;
}
if (SDL_VideoSurface->flags & SDL_FULLSCREEN) {
/**
* Good acceleration requires a window to be present.
* A CGrafPtr that points to the screen isn't good enough
**/
NSRect content = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
qz_window = [ [ SDL_QuartzWindow alloc ]
initWithContentRect:content
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered defer:NO ];
if (qz_window == nil) {
SDL_SetError ("Could not create the Cocoa window");
return NULL;
}
[ qz_window setContentView:[ [ SDL_QuartzWindowView alloc ] init ] ];
[ qz_window setReleasedWhenClosed:YES ];
[ qz_window center ];
[ qz_window setAcceptsMouseMovedEvents:YES ];
[ qz_window setLevel:CGShieldingWindowLevel() ];
[ qz_window makeKeyAndOrderFront:nil ];
port = [ [ qz_window contentView ] qdPort ];
SetPort (port);
// BUG: would like to remove white flash when window kicks in
//{
// Rect r;
// SetRect (&r, 0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
// PaintRect (&r);
// QDFlushPortBuffer (port, nil);
//}
}
else {
port = [ [ qz_window contentView ] qdPort ];
SetPort (port);
}
SetIdentityMatrix (yuv_matrix);
HLock ((Handle)yuv_idh);
(**yuv_idh).idSize = sizeof(ImageDescription);
(**yuv_idh).cType = codec;
(**yuv_idh).version = 1;
(**yuv_idh).revisionLevel = 0;
(**yuv_idh).width = width;
(**yuv_idh).height = height;
(**yuv_idh).hRes = Long2Fix(72);
(**yuv_idh).vRes = Long2Fix(72);
(**yuv_idh).spatialQuality = codecLosslessQuality;
(**yuv_idh).frameCount = 1;
(**yuv_idh).clutID = -1;
(**yuv_idh).dataSize = 0;
(**yuv_idh).depth = 12;
HUnlock ((Handle)yuv_idh);
err = DecompressSequenceBeginS (
&yuv_seq,
yuv_idh,
NULL,
0,
port,
NULL,
NULL,
yuv_matrix,
0,
NULL,
codecFlagUseImageBuffer,
codecLosslessQuality,
yuv_codec);
if (err != noErr) {
SDL_SetError ("Error trying to start YUV codec.");
return NULL;
}
overlay = (SDL_Overlay*) malloc (sizeof(*overlay));
if (overlay == NULL) {
SDL_OutOfMemory();
return NULL;
}
overlay->format = format;
overlay->w = width;
overlay->h = height;
overlay->planes = 3;
overlay->hw_overlay = 1;
{
int offset;
Uint8 **pixels;
Uint16 *pitches;
int plane2, plane3;
if (format == SDL_IYUV_OVERLAY) {
plane2 = 1; /* Native codec format */
plane3 = 2;
}
else if (format == SDL_YV12_OVERLAY) {
/* switch the U and V planes */
plane2 = 2; /* U plane maps to plane 3 */
plane3 = 1; /* V plane maps to plane 2 */
}
else {
SDL_SetError("Unsupported YUV format");
return NULL;
}
pixels = (Uint8**) malloc (sizeof(*pixels) * 3);
pitches = (Uint16*) malloc (sizeof(*pitches) * 3);
if (pixels == NULL || pitches == NULL) {
SDL_OutOfMemory();
return NULL;
}
yuv_pixmap = (PlanarPixmapInfoYUV420*)
malloc (sizeof(PlanarPixmapInfoYUV420) +
(width * height * 2));
if (yuv_pixmap == NULL) {
SDL_OutOfMemory ();
return NULL;
}
//CHECK_ALIGN(yuv_pixmap);
offset = sizeof(PlanarPixmapInfoYUV420);
//offset += ALIGN(offset);
//CHECK_ALIGN(offset);
pixels[0] = (Uint8*)yuv_pixmap + offset;
//CHECK_ALIGN(pixels[0]);
pitches[0] = width;
yuv_pixmap->componentInfoY.offset = offset;
yuv_pixmap->componentInfoY.rowBytes = width;
offset += width * height;
pixels[plane2] = (Uint8*)yuv_pixmap + offset;
pitches[plane2] = width / 2;
yuv_pixmap->componentInfoCb.offset = offset;
yuv_pixmap->componentInfoCb.rowBytes = width / 2;
offset += (width * height / 4);
pixels[plane3] = (Uint8*)yuv_pixmap + offset;
pitches[plane3] = width / 2;
yuv_pixmap->componentInfoCr.offset = offset;
yuv_pixmap->componentInfoCr.rowBytes = width / 2;
overlay->pixels = pixels;
overlay->pitches = pitches;
}
overlay->hwfuncs = malloc (sizeof(*overlay->hwfuncs));
if (overlay->hwfuncs == NULL) {
SDL_OutOfMemory();
return NULL;
}
overlay->hwfuncs->Lock = QZ_LockYUV;
overlay->hwfuncs->Unlock = QZ_UnlockYUV;
overlay->hwfuncs->Display = QZ_DisplayYUV;
overlay->hwfuncs->FreeHW = QZ_FreeHWYUV;
yuv_width = overlay->w;
yuv_height = overlay->h;
return overlay;
}
......@@ -32,17 +32,17 @@ static void QZ_FreeWMCursor (_THIS, WMcursor *cursor) {
/* Use the Carbon cursor routines for now */
static WMcursor* QZ_CreateWMCursor (_THIS, Uint8 *data, Uint8 *mask,
int w, int h, int hot_x, int hot_y) {
WMcursor *cursor;
int row, bytes;
/* Allocate the cursor memory */
cursor = (WMcursor *)malloc(sizeof(WMcursor));
if ( cursor == NULL ) {
SDL_OutOfMemory();
return(NULL);
}
memset(cursor, 0, sizeof(*cursor));
int w, int h, int hot_x, int hot_y) {
WMcursor *cursor;
int row, bytes;
/* Allocate the cursor memory */
cursor = (WMcursor *)malloc(sizeof(WMcursor));
if ( cursor == NULL ) {
SDL_OutOfMemory();
return(NULL);
}
memset(cursor, 0, sizeof(*cursor));
if (w > 16)
w = 16;
......@@ -50,19 +50,19 @@ static WMcursor* QZ_CreateWMCursor (_THIS, Uint8 *data, Uint8 *mask,
if (h > 16)
h = 16;
bytes = (w+7)/8;
for ( row=0; row<h; ++row ) {
memcpy(&cursor->curs.data[row], data, bytes);
data += bytes;
}
for ( row=0; row<h; ++row ) {
memcpy(&cursor->curs.mask[row], mask, bytes);
mask += bytes;
}
cursor->curs.hotSpot.h = hot_x;
cursor->curs.hotSpot.v = hot_y;
bytes = (w+7)/8;
for ( row=0; row<h; ++row ) {
memcpy(&cursor->curs.data[row], data, bytes);
data += bytes;
}
for ( row=0; row<h; ++row ) {
memcpy(&cursor->curs.mask[row], mask, bytes);
mask += bytes;
}
cursor->curs.hotSpot.h = hot_x;
cursor->curs.hotSpot.v = hot_y;
return(cursor);
}
......@@ -246,18 +246,18 @@ static void QZ_SetIcon (_THIS, SDL_Surface *icon, Uint8 *mask)
#define ALPHASHIFT 3
for (i=0;i<masksize;i+=8)
for (j=0;j<8;j++)
surfPtr[ALPHASHIFT+((i+j)<<2)]=(mask[i>>3]&(1<<(7-j)))?0xFF:0x00;
surfPtr[ALPHASHIFT+((i+j)<<2)]=(mask[i>>3]&(1<<(7-j)))?0xFF:0x00;
}
imgrep = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:(unsigned char **)&mergedSurface->pixels
pixelsWide:icon->w pixelsHigh:icon->h bitsPerSample:8 samplesPerPixel:4
hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:icon->w<<2 bitsPerPixel:32];
img = [[NSImage alloc] initWithSize:imgSize];
[img addRepresentation: imgrep];
[NSApp setApplicationIconImage:img];
[img release];
[imgrep release];
imgrep = [ [ NSBitmapImageRep alloc]
initWithBitmapDataPlanes:(unsigned char **)&mergedSurface->pixels
pixelsWide:icon->w pixelsHigh:icon->h bitsPerSample:8 samplesPerPixel:4
hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:icon->w<<2 bitsPerPixel:32 ];
img = [ [ NSImage alloc ] initWithSize:imgSize ];
[ img addRepresentation: imgrep ];
[ NSApp setApplicationIconImage:img ];
[ img release ];
[ imgrep release ];
SDL_FreeSurface(mergedSurface);
freePool:
[pool release];
......@@ -285,19 +285,18 @@ static int QZ_GetWMInfo (_THIS, SDL_SysWMinfo *info) {
static SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode) {
switch (grab_mode) {
case SDL_GRAB_QUERY:
case SDL_GRAB_QUERY:
break;
case SDL_GRAB_OFF:
case SDL_GRAB_OFF:
CGAssociateMouseAndMouseCursorPosition (1);
currentGrabMode = SDL_GRAB_OFF;
break;
case SDL_GRAB_ON:
case SDL_GRAB_ON:
QZ_WarpWMCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2);
CGAssociateMouseAndMouseCursorPosition (0);
currentGrabMode = SDL_GRAB_ON;
break;
case SDL_GRAB_FULLSCREEN:
case SDL_GRAB_FULLSCREEN:
break;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment