2006-07-23 09:11:10 +00:00
/ *
SDL - Simple DirectMedia Layer
Copyright ( C ) 1997 -2006 Sam Lantinga
This library is free software ; you can redistribute it and / or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation ; either
version 2.1 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
Lesser General Public License for more details .
You should have received a copy of the GNU Lesser General Public
License along with this library ; if not , write to the Free Software
Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 -1301 USA
Sam Lantinga
slouken @ libsdl . org
* /
# include "SDL_config.h"
# include "SDL_cocoavideo.h"
2006-07-30 05:18:33 +00:00
# include "SDL_cocoakeys.h"
2006-07-23 09:11:10 +00:00
# include "../../events/SDL_keyboard_c.h"
Date: Thu, 05 Jul 2007 14:02:33 -0700
From: Sam Lantinga
Subject: SDL 1.3 keyboard plan
After lots of discussion with Christian, this is what we came up with:
> So, to sum up...
> SDLK_* become the physical keys, starting at > (1<<21)
> We create a macro SDLK_INDEX(X)
> We have two functions SDL_GetLayoutKey(SDLKey) and SDL_GetKeyName()
> SDL_GetLayoutKey maps to UCS4 for printable characters, and SDLK* for
non-printable characters
> and does so based on the OS's current keyboard layout
> SDL_GetKeyName() handles both SDLK_* and UCS4, converting UCS4 to UTF-8 and
converting SDLK_* into our names, which are UTF-8 for printable characters.
> WASD folks use SDLK_*, and 'I' folks use SDL_GetLayoutKey(SDLK_*)
Here is the patch he came up with, and his e-mail about it:
Date: Fri, 17 Aug 2007 19:50:28 +0200
From: Christian Walther
Subject: Re: SDL 1.3 keyboard plan
> Sounds great, go ahead and send me a patch.
Here goes! Thanks for having a look. Don't hesitate to comment if
anything does not conform to your ideas.
One caveat: Committing this now may break compilability of some video
drivers - specifically, if they use any of the SDLK_* codes that were
obsoleted and moved into SDL_compat.h. I only tried Cocoa (which did
break, but is already fixed) and X11 (which didn't, but then its key
handling is #iffed out). If that's a problem, it may need to go into
a branch.
-Christian
--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%402630
2007-08-19 14:52:52 +00:00
# include < Carbon / Carbon . h >
2006-07-30 05:18:33 +00:00
# ifndef NX_DEVICERCTLKEYMASK
# define NX_DEVICELCTLKEYMASK 0 x00000001
# endif
# ifndef NX_DEVICELSHIFTKEYMASK
# define NX_DEVICELSHIFTKEYMASK 0 x00000002
# endif
# ifndef NX_DEVICERSHIFTKEYMASK
# define NX_DEVICERSHIFTKEYMASK 0 x00000004
# endif
# ifndef NX_DEVICELCMDKEYMASK
# define NX_DEVICELCMDKEYMASK 0 x00000008
# endif
# ifndef NX_DEVICERCMDKEYMASK
# define NX_DEVICERCMDKEYMASK 0 x00000010
# endif
# ifndef NX_DEVICELALTKEYMASK
# define NX_DEVICELALTKEYMASK 0 x00000020
# endif
# ifndef NX_DEVICERALTKEYMASK
# define NX_DEVICERALTKEYMASK 0 x00000040
# endif
# ifndef NX_DEVICERCTLKEYMASK
# define NX_DEVICERCTLKEYMASK 0 x00002000
# endif
/ * This is the original behavior , before support was added for
* differentiating between left and right versions of the keys .
* /
static void
DoUnsidedModifiers ( int keyboard , unsigned short scancode ,
unsigned int oldMods , unsigned int newMods )
{
const int mapping [ ] = { SDLK_CAPSLOCK , SDLK_LSHIFT , SDLK_LCTRL , SDLK_LALT , SDLK_LMETA } ;
unsigned int i , bit ;
/ * Iterate through the bits , testing each against the current modifiers * /
for ( i = 0 , bit = NSAlphaShiftKeyMask ; bit <= NSCommandKeyMask ; bit < <= 1 , + + i ) {
unsigned int oldMask , newMask ;
oldMask = oldMods & bit ;
newMask = newMods & bit ;
if ( oldMask && oldMask ! = newMask ) { / * modifier up event * /
/ * If this was Caps Lock , we need some additional voodoo to make SDL happy * /
if ( bit = = NSAlphaShiftKeyMask ) {
SDL_SendKeyboardKey ( keyboard , SDL_PRESSED , ( Uint8 ) scancode , mapping [ i ] ) ;
}
SDL_SendKeyboardKey ( keyboard , SDL_RELEASED , ( Uint8 ) scancode , mapping [ i ] ) ;
} else if ( newMask && oldMask ! = newMask ) { / * modifier down event * /
SDL_SendKeyboardKey ( keyboard , SDL_PRESSED , ( Uint8 ) scancode , mapping [ i ] ) ;
/ * If this was Caps Lock , we need some additional voodoo to make SDL happy * /
if ( bit = = NSAlphaShiftKeyMask ) {
SDL_SendKeyboardKey ( keyboard , SDL_RELEASED , ( Uint8 ) scancode , mapping [ i ] ) ;
}
}
}
}
/ * This is a helper function for HandleModifierSide . This
* function reverts back to behavior before the distinction between
* sides was made .
* /
static void
HandleNonDeviceModifier ( int keyboard , unsigned short scancode ,
unsigned int device_independent _mask ,
unsigned int oldMods ,
unsigned int newMods ,
SDLKey key_sym )
{
unsigned int oldMask , newMask ;
/ * Isolate just the bits we care about in the depedent bits so we can
* figure out what changed
* /
oldMask = oldMods & device_independent _mask ;
newMask = newMods & device_independent _mask ;
if ( oldMask && oldMask ! = newMask ) {
SDL_SendKeyboardKey ( keyboard , SDL_RELEASED , ( Uint8 ) scancode , key_sym ) ;
} else if ( newMask && oldMask ! = newMask ) {
SDL_SendKeyboardKey ( keyboard , SDL_PRESSED , ( Uint8 ) scancode , key_sym ) ;
}
}
/ * This is a helper function for HandleModifierSide .
* This function sets the actual SDL_PrivateKeyboard event .
* /
static void
HandleModifierOneSide ( int keyboard , unsigned short scancode ,
unsigned int oldMods , unsigned int newMods ,
SDLKey key_sym ,
unsigned int sided_device _dependent _mask )
{
unsigned int old_dep _mask , new_dep _mask ;
/ * Isolate just the bits we care about in the depedent bits so we can
* figure out what changed
* /
old_dep _mask = oldMods & sided_device _dependent _mask ;
new_dep _mask = newMods & sided_device _dependent _mask ;
/ * We now know that this side bit flipped . But we don ' t know if
* it went pressed to released or released to pressed , so we must
* find out which it is .
* /
if ( new_dep _mask && old_dep _mask ! = new_dep _mask ) {
SDL_SendKeyboardKey ( keyboard , SDL_PRESSED , ( Uint8 ) scancode , key_sym ) ;
} else {
SDL_SendKeyboardKey ( keyboard , SDL_RELEASED , ( Uint8 ) scancode , key_sym ) ;
}
}
/ * This is a helper function for DoSidedModifiers .
* This function will figure out if the modifier key is the left or right side ,
* e . g . left - shift vs right - shift .
* /
static void
HandleModifierSide ( int keyboard , unsigned short scancode ,
int device_independent _mask ,
unsigned int oldMods , unsigned int newMods ,
SDLKey left_key _sym ,
SDLKey right_key _sym ,
unsigned int left_device _dependent _mask ,
unsigned int right_device _dependent _mask )
{
unsigned int device_dependent _mask = ( left_device _dependent _mask |
right_device _dependent _mask ) ;
unsigned int diff_mod ;
/ * On the basis that the device independent mask is set , but there are
* no device dependent flags set , we ' ll assume that we can ' t detect this
* keyboard and revert to the unsided behavior .
* /
if ( ( device_dependent _mask & newMods ) = = 0 ) {
/ * Revert to the old behavior * /
HandleNonDeviceModifier ( keyboard , scancode , device_independent _mask , oldMods , newMods , left_key _sym ) ;
return ;
}
/ * XOR the previous state against the new state to see if there ' s a change * /
diff_mod = ( device_dependent _mask & oldMods ) ^
( device_dependent _mask & newMods ) ;
if ( diff_mod ) {
/ * A change in state was found . Isolate the left and right bits
* to handle them separately just in case the values can simulataneously
* change or if the bits don ' t both exist .
* /
if ( left_device _dependent _mask & diff_mod ) {
HandleModifierOneSide ( keyboard , scancode , oldMods , newMods , left_key _sym , left_device _dependent _mask ) ;
}
if ( right_device _dependent _mask & diff_mod ) {
HandleModifierOneSide ( keyboard , scancode , oldMods , newMods , right_key _sym , right_device _dependent _mask ) ;
}
}
}
/ * This is a helper function for DoSidedModifiers .
* This function will release a key press in the case that
* it is clear that the modifier has been released ( i . e . one side
* can ' t still be down ) .
* /
static void
ReleaseModifierSide ( int keyboard , unsigned short scancode ,
unsigned int device_independent _mask ,
unsigned int oldMods , unsigned int newMods ,
SDLKey left_key _sym ,
SDLKey right_key _sym ,
unsigned int left_device _dependent _mask ,
unsigned int right_device _dependent _mask )
{
unsigned int device_dependent _mask = ( left_device _dependent _mask |
right_device _dependent _mask ) ;
/ * On the basis that the device independent mask is set , but there are
* no device dependent flags set , we ' ll assume that we can ' t detect this
* keyboard and revert to the unsided behavior .
* /
if ( ( device_dependent _mask & oldMods ) = = 0 ) {
/ * In this case , we can ' t detect the keyboard , so use the left side
* to represent both , and release it .
* /
SDL_SendKeyboardKey ( keyboard , SDL_RELEASED , ( Uint8 ) scancode , left_key _sym ) ;
return ;
}
/ *
* This could have been done in an if - else case because at this point ,
* we know that all keys have been released when calling this function .
* But I ' m being paranoid so I want to handle each separately ,
* so I hope this doesn ' t cause other problems .
* /
if ( left_device _dependent _mask & oldMods ) {
SDL_SendKeyboardKey ( keyboard , SDL_RELEASED , ( Uint8 ) scancode , left_key _sym ) ;
}
if ( right_device _dependent _mask & oldMods ) {
SDL_SendKeyboardKey ( keyboard , SDL_RELEASED , ( Uint8 ) scancode , right_key _sym ) ;
}
}
/ * This is a helper function for DoSidedModifiers .
* This function handles the CapsLock case .
* /
static void
HandleCapsLock ( int keyboard , unsigned short scancode ,
unsigned int oldMods , unsigned int newMods )
{
unsigned int oldMask , newMask ;
oldMask = oldMods & NSAlphaShiftKeyMask ;
newMask = newMods & NSAlphaShiftKeyMask ;
if ( oldMask ! = newMask ) {
SDL_SendKeyboardKey ( keyboard , SDL_PRESSED , ( Uint8 ) scancode , SDLK_CAPSLOCK ) ;
SDL_SendKeyboardKey ( keyboard , SDL_RELEASED , ( Uint8 ) scancode , SDLK_CAPSLOCK ) ;
}
2006-07-30 06:11:24 +00:00
oldMask = oldMods & NSNumericPadKeyMask ;
newMask = newMods & NSNumericPadKeyMask ;
if ( oldMask ! = newMask ) {
Date: Thu, 05 Jul 2007 14:02:33 -0700
From: Sam Lantinga
Subject: SDL 1.3 keyboard plan
After lots of discussion with Christian, this is what we came up with:
> So, to sum up...
> SDLK_* become the physical keys, starting at > (1<<21)
> We create a macro SDLK_INDEX(X)
> We have two functions SDL_GetLayoutKey(SDLKey) and SDL_GetKeyName()
> SDL_GetLayoutKey maps to UCS4 for printable characters, and SDLK* for
non-printable characters
> and does so based on the OS's current keyboard layout
> SDL_GetKeyName() handles both SDLK_* and UCS4, converting UCS4 to UTF-8 and
converting SDLK_* into our names, which are UTF-8 for printable characters.
> WASD folks use SDLK_*, and 'I' folks use SDL_GetLayoutKey(SDLK_*)
Here is the patch he came up with, and his e-mail about it:
Date: Fri, 17 Aug 2007 19:50:28 +0200
From: Christian Walther
Subject: Re: SDL 1.3 keyboard plan
> Sounds great, go ahead and send me a patch.
Here goes! Thanks for having a look. Don't hesitate to comment if
anything does not conform to your ideas.
One caveat: Committing this now may break compilability of some video
drivers - specifically, if they use any of the SDLK_* codes that were
obsoleted and moved into SDL_compat.h. I only tried Cocoa (which did
break, but is already fixed) and X11 (which didn't, but then its key
handling is #iffed out). If that's a problem, it may need to go into
a branch.
-Christian
--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%402630
2007-08-19 14:52:52 +00:00
SDL_SendKeyboardKey ( keyboard , SDL_PRESSED , ( Uint8 ) scancode , SDLK_KP _NUMLOCKCLEAR ) ;
SDL_SendKeyboardKey ( keyboard , SDL_RELEASED , ( Uint8 ) scancode , SDLK_KP _NUMLOCKCLEAR ) ;
2006-07-30 06:11:24 +00:00
}
2006-07-30 05:18:33 +00:00
}
/ * This function will handle the modifier keys and also determine the
* correct side of the key .
* /
static void
DoSidedModifiers ( int keyboard , unsigned short scancode ,
unsigned int oldMods , unsigned int newMods )
{
/ * Set up arrays for the key syms for the left and right side . * /
const SDLKey left_mapping [ ] = { SDLK_LSHIFT , SDLK_LCTRL , SDLK_LALT , SDLK_LMETA } ;
const SDLKey right_mapping [ ] = { SDLK_RSHIFT , SDLK_RCTRL , SDLK_RALT , SDLK_RMETA } ;
/ * Set up arrays for the device dependent masks with indices that
* correspond to the _mapping arrays
* /
const unsigned int left_device _mapping [ ] = { NX_DEVICELSHIFTKEYMASK , NX_DEVICELCTLKEYMASK , NX_DEVICELALTKEYMASK , NX_DEVICELCMDKEYMASK } ;
const unsigned int right_device _mapping [ ] = { NX_DEVICERSHIFTKEYMASK , NX_DEVICERCTLKEYMASK , NX_DEVICERALTKEYMASK , NX_DEVICERCMDKEYMASK } ;
unsigned int i , bit ;
/ * Handle CAPSLOCK separately because it doesn ' t have a left / right side * /
HandleCapsLock ( keyboard , scancode , oldMods , newMods ) ;
/ * Iterate through the bits , testing each against the old modifiers * /
for ( i = 0 , bit = NSShiftKeyMask ; bit <= NSCommandKeyMask ; bit < <= 1 , + + i ) {
unsigned int oldMask , newMask ;
oldMask = oldMods & bit ;
newMask = newMods & bit ;
/ * If the bit is set , we must always examine it because the left
* and right side keys may alternate or both may be pressed .
* /
if ( newMask ) {
HandleModifierSide ( keyboard , scancode , bit , oldMods , newMods ,
left_mapping [ i ] , right_mapping [ i ] ,
left_device _mapping [ i ] , right_device _mapping [ i ] ) ;
}
/ * If the state changed from pressed to unpressed , we must examine
* the device dependent bits to release the correct keys .
* /
else if ( oldMask && oldMask ! = newMask ) {
ReleaseModifierSide ( keyboard , scancode , bit , oldMods , newMods ,
left_mapping [ i ] , right_mapping [ i ] ,
left_device _mapping [ i ] , right_device _mapping [ i ] ) ;
}
}
}
static void
HandleModifiers ( _THIS , unsigned short scancode , unsigned int modifierFlags )
{
SDL_VideoData * data = ( SDL_VideoData * ) _this -> driverdata ;
if ( modifierFlags = = data -> modifierFlags ) {
return ;
}
/ *
* Starting with Panther ( 10.3 .0 ) , the ability to distinguish between
* left side and right side modifiers is available .
* /
if ( data -> osversion >= 0 x1030 ) {
DoSidedModifiers ( data -> keyboard , scancode , data -> modifierFlags , modifierFlags ) ;
} else {
DoUnsidedModifiers ( data -> keyboard , scancode , data -> modifierFlags , modifierFlags ) ;
}
data -> modifierFlags = modifierFlags ;
}
2006-07-23 09:11:10 +00:00
void
Cocoa_InitKeyboard ( _THIS )
{
SDL_VideoData * data = ( SDL_VideoData * ) _this -> driverdata ;
SDL_Keyboard keyboard ;
2007-07-11 14:44:28 +00:00
NSAutoreleasePool * pool ;
2006-07-23 09:11:10 +00:00
2007-07-11 14:44:28 +00:00
pool = [ [ NSAutoreleasePool alloc ] init ] ;
2007-07-11 08:09:20 +00:00
data -> fieldEdit = [ [ NSTextView alloc ] initWithFrame : NSMakeRect ( 0.0 , 0.0 , 0.0 , 0.0 ) ] ;
2007-07-11 14:44:28 +00:00
[ pool release ] ;
2007-07-11 08:09:20 +00:00
2006-07-23 09:11:10 +00:00
SDL_zero ( keyboard ) ;
data -> keyboard = SDL_AddKeyboard ( & keyboard , -1 ) ;
Date: Thu, 05 Jul 2007 14:02:33 -0700
From: Sam Lantinga
Subject: SDL 1.3 keyboard plan
After lots of discussion with Christian, this is what we came up with:
> So, to sum up...
> SDLK_* become the physical keys, starting at > (1<<21)
> We create a macro SDLK_INDEX(X)
> We have two functions SDL_GetLayoutKey(SDLKey) and SDL_GetKeyName()
> SDL_GetLayoutKey maps to UCS4 for printable characters, and SDLK* for
non-printable characters
> and does so based on the OS's current keyboard layout
> SDL_GetKeyName() handles both SDLK_* and UCS4, converting UCS4 to UTF-8 and
converting SDLK_* into our names, which are UTF-8 for printable characters.
> WASD folks use SDLK_*, and 'I' folks use SDL_GetLayoutKey(SDLK_*)
Here is the patch he came up with, and his e-mail about it:
Date: Fri, 17 Aug 2007 19:50:28 +0200
From: Christian Walther
Subject: Re: SDL 1.3 keyboard plan
> Sounds great, go ahead and send me a patch.
Here goes! Thanks for having a look. Don't hesitate to comment if
anything does not conform to your ideas.
One caveat: Committing this now may break compilability of some video
drivers - specifically, if they use any of the SDLK_* codes that were
obsoleted and moved into SDL_compat.h. I only tried Cocoa (which did
break, but is already fixed) and X11 (which didn't, but then its key
handling is #iffed out). If that's a problem, it may need to go into
a branch.
-Christian
--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%402630
2007-08-19 14:52:52 +00:00
/ * Set our own names for the platform - dependent but layout - independent keys * /
SDL_SetKeyName ( SDLK_KP _NUMLOCKCLEAR , "clear" ) ;
SDL_SetKeyName ( SDLK_LALT , "left option" ) ;
SDL_SetKeyName ( SDLK_LMETA , "left command" ) ;
SDL_SetKeyName ( SDLK_RALT , "right option" ) ;
SDL_SetKeyName ( SDLK_RMETA , "right command" ) ;
2006-07-23 09:11:10 +00:00
}
2006-07-30 05:18:33 +00:00
void
Cocoa_HandleKeyEvent ( _THIS , NSEvent * event )
{
SDL_VideoData * data = ( SDL_VideoData * ) _this -> driverdata ;
unsigned short scancode = [ event keyCode ] ;
Date: Thu, 05 Jul 2007 14:02:33 -0700
From: Sam Lantinga
Subject: SDL 1.3 keyboard plan
After lots of discussion with Christian, this is what we came up with:
> So, to sum up...
> SDLK_* become the physical keys, starting at > (1<<21)
> We create a macro SDLK_INDEX(X)
> We have two functions SDL_GetLayoutKey(SDLKey) and SDL_GetKeyName()
> SDL_GetLayoutKey maps to UCS4 for printable characters, and SDLK* for
non-printable characters
> and does so based on the OS's current keyboard layout
> SDL_GetKeyName() handles both SDLK_* and UCS4, converting UCS4 to UTF-8 and
converting SDLK_* into our names, which are UTF-8 for printable characters.
> WASD folks use SDLK_*, and 'I' folks use SDL_GetLayoutKey(SDLK_*)
Here is the patch he came up with, and his e-mail about it:
Date: Fri, 17 Aug 2007 19:50:28 +0200
From: Christian Walther
Subject: Re: SDL 1.3 keyboard plan
> Sounds great, go ahead and send me a patch.
Here goes! Thanks for having a look. Don't hesitate to comment if
anything does not conform to your ideas.
One caveat: Committing this now may break compilability of some video
drivers - specifically, if they use any of the SDLK_* codes that were
obsoleted and moved into SDL_compat.h. I only tried Cocoa (which did
break, but is already fixed) and X11 (which didn't, but then its key
handling is #iffed out). If that's a problem, it may need to go into
a branch.
-Christian
--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%402630
2007-08-19 14:52:52 +00:00
SDLKey physicalKey ;
2006-07-30 05:18:33 +00:00
const char * text ;
Date: Thu, 05 Jul 2007 14:02:33 -0700
From: Sam Lantinga
Subject: SDL 1.3 keyboard plan
After lots of discussion with Christian, this is what we came up with:
> So, to sum up...
> SDLK_* become the physical keys, starting at > (1<<21)
> We create a macro SDLK_INDEX(X)
> We have two functions SDL_GetLayoutKey(SDLKey) and SDL_GetKeyName()
> SDL_GetLayoutKey maps to UCS4 for printable characters, and SDLK* for
non-printable characters
> and does so based on the OS's current keyboard layout
> SDL_GetKeyName() handles both SDLK_* and UCS4, converting UCS4 to UTF-8 and
converting SDLK_* into our names, which are UTF-8 for printable characters.
> WASD folks use SDLK_*, and 'I' folks use SDL_GetLayoutKey(SDLK_*)
Here is the patch he came up with, and his e-mail about it:
Date: Fri, 17 Aug 2007 19:50:28 +0200
From: Christian Walther
Subject: Re: SDL 1.3 keyboard plan
> Sounds great, go ahead and send me a patch.
Here goes! Thanks for having a look. Don't hesitate to comment if
anything does not conform to your ideas.
One caveat: Committing this now may break compilability of some video
drivers - specifically, if they use any of the SDLK_* codes that were
obsoleted and moved into SDL_compat.h. I only tried Cocoa (which did
break, but is already fixed) and X11 (which didn't, but then its key
handling is #iffed out). If that's a problem, it may need to go into
a branch.
-Christian
--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%402630
2007-08-19 14:52:52 +00:00
if ( ( scancode = = 10 || scancode = = 50 ) && KBGetLayoutType ( LMGetKbdType ( ) ) = = kKeyboardISO ) {
/ * see comments in SDL_cocoakeys . h * /
scancode = 60 - scancode ;
}
if ( scancode < SDL_arraysize ( macToSDLKey ) ) {
physicalKey = macToSDLKey [ scancode ] ;
}
else {
2006-07-30 05:18:33 +00:00
/ * Hmm , does this ever happen ? If so , need to extend the keymap . . . * /
Date: Thu, 05 Jul 2007 14:02:33 -0700
From: Sam Lantinga
Subject: SDL 1.3 keyboard plan
After lots of discussion with Christian, this is what we came up with:
> So, to sum up...
> SDLK_* become the physical keys, starting at > (1<<21)
> We create a macro SDLK_INDEX(X)
> We have two functions SDL_GetLayoutKey(SDLKey) and SDL_GetKeyName()
> SDL_GetLayoutKey maps to UCS4 for printable characters, and SDLK* for
non-printable characters
> and does so based on the OS's current keyboard layout
> SDL_GetKeyName() handles both SDLK_* and UCS4, converting UCS4 to UTF-8 and
converting SDLK_* into our names, which are UTF-8 for printable characters.
> WASD folks use SDLK_*, and 'I' folks use SDL_GetLayoutKey(SDLK_*)
Here is the patch he came up with, and his e-mail about it:
Date: Fri, 17 Aug 2007 19:50:28 +0200
From: Christian Walther
Subject: Re: SDL 1.3 keyboard plan
> Sounds great, go ahead and send me a patch.
Here goes! Thanks for having a look. Don't hesitate to comment if
anything does not conform to your ideas.
One caveat: Committing this now may break compilability of some video
drivers - specifically, if they use any of the SDLK_* codes that were
obsoleted and moved into SDL_compat.h. I only tried Cocoa (which did
break, but is already fixed) and X11 (which didn't, but then its key
handling is #iffed out). If that's a problem, it may need to go into
a branch.
-Christian
--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%402630
2007-08-19 14:52:52 +00:00
physicalKey = SDLK_UNKNOWN ;
2006-07-30 05:18:33 +00:00
}
switch ( [ event type ] ) {
case NSKeyDown :
2007-06-16 15:32:04 +00:00
if ( ! [ event isARepeat ] ) {
Date: Thu, 05 Jul 2007 14:02:33 -0700
From: Sam Lantinga
Subject: SDL 1.3 keyboard plan
After lots of discussion with Christian, this is what we came up with:
> So, to sum up...
> SDLK_* become the physical keys, starting at > (1<<21)
> We create a macro SDLK_INDEX(X)
> We have two functions SDL_GetLayoutKey(SDLKey) and SDL_GetKeyName()
> SDL_GetLayoutKey maps to UCS4 for printable characters, and SDLK* for
non-printable characters
> and does so based on the OS's current keyboard layout
> SDL_GetKeyName() handles both SDLK_* and UCS4, converting UCS4 to UTF-8 and
converting SDLK_* into our names, which are UTF-8 for printable characters.
> WASD folks use SDLK_*, and 'I' folks use SDL_GetLayoutKey(SDLK_*)
Here is the patch he came up with, and his e-mail about it:
Date: Fri, 17 Aug 2007 19:50:28 +0200
From: Christian Walther
Subject: Re: SDL 1.3 keyboard plan
> Sounds great, go ahead and send me a patch.
Here goes! Thanks for having a look. Don't hesitate to comment if
anything does not conform to your ideas.
One caveat: Committing this now may break compilability of some video
drivers - specifically, if they use any of the SDLK_* codes that were
obsoleted and moved into SDL_compat.h. I only tried Cocoa (which did
break, but is already fixed) and X11 (which didn't, but then its key
handling is #iffed out). If that's a problem, it may need to go into
a branch.
-Christian
--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%402630
2007-08-19 14:52:52 +00:00
SDL_SendKeyboardKey ( data -> keyboard , SDL_PRESSED , ( Uint8 ) scancode , physicalKey ) ;
# if 1
if ( physicalKey = = SDLK_UNKNOWN ) {
fprintf ( stderr , "The key you just pressed is not recognized by SDL. To help get this fixed, report this to the SDL mailing list <sdl@libsdl.org> or to Christian Walther <cwalther@gmx.ch>. Mac virtual key code is %d.\n" , scancode ) ;
}
# endif
2006-07-30 05:18:33 +00:00
}
2007-06-16 15:32:04 +00:00
if ( SDL_EventState ( SDL_TEXTINPUT , SDL_QUERY ) ) {
Date: Thu, 05 Jul 2007 14:02:33 -0700
From: Sam Lantinga
Subject: SDL 1.3 keyboard plan
After lots of discussion with Christian, this is what we came up with:
> So, to sum up...
> SDLK_* become the physical keys, starting at > (1<<21)
> We create a macro SDLK_INDEX(X)
> We have two functions SDL_GetLayoutKey(SDLKey) and SDL_GetKeyName()
> SDL_GetLayoutKey maps to UCS4 for printable characters, and SDLK* for
non-printable characters
> and does so based on the OS's current keyboard layout
> SDL_GetKeyName() handles both SDLK_* and UCS4, converting UCS4 to UTF-8 and
converting SDLK_* into our names, which are UTF-8 for printable characters.
> WASD folks use SDLK_*, and 'I' folks use SDL_GetLayoutKey(SDLK_*)
Here is the patch he came up with, and his e-mail about it:
Date: Fri, 17 Aug 2007 19:50:28 +0200
From: Christian Walther
Subject: Re: SDL 1.3 keyboard plan
> Sounds great, go ahead and send me a patch.
Here goes! Thanks for having a look. Don't hesitate to comment if
anything does not conform to your ideas.
One caveat: Committing this now may break compilability of some video
drivers - specifically, if they use any of the SDLK_* codes that were
obsoleted and moved into SDL_compat.h. I only tried Cocoa (which did
break, but is already fixed) and X11 (which didn't, but then its key
handling is #iffed out). If that's a problem, it may need to go into
a branch.
-Christian
--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%402630
2007-08-19 14:52:52 +00:00
/ * FIXME CW 2007 -08 -16 : only send those events to the field editor for which we actually want text events , not e . g . esc or function keys . Arrow keys in particular seem to produce crashes sometimes . * /
2007-07-11 08:09:20 +00:00
[ data -> fieldEdit interpretKeyEvents : [ NSArray arrayWithObject : event ] ] ;
2007-06-16 15:32:04 +00:00
text = [ [ event characters ] UTF8String ] ;
if ( text && * text ) {
SDL_SendKeyboardText ( data -> keyboard , text ) ;
2007-08-21 06:54:07 +00:00
[ data -> fieldEdit setString : @ "" ] ;
2007-06-16 15:32:04 +00:00
}
2006-07-30 05:18:33 +00:00
}
break ;
case NSKeyUp :
Date: Thu, 05 Jul 2007 14:02:33 -0700
From: Sam Lantinga
Subject: SDL 1.3 keyboard plan
After lots of discussion with Christian, this is what we came up with:
> So, to sum up...
> SDLK_* become the physical keys, starting at > (1<<21)
> We create a macro SDLK_INDEX(X)
> We have two functions SDL_GetLayoutKey(SDLKey) and SDL_GetKeyName()
> SDL_GetLayoutKey maps to UCS4 for printable characters, and SDLK* for
non-printable characters
> and does so based on the OS's current keyboard layout
> SDL_GetKeyName() handles both SDLK_* and UCS4, converting UCS4 to UTF-8 and
converting SDLK_* into our names, which are UTF-8 for printable characters.
> WASD folks use SDLK_*, and 'I' folks use SDL_GetLayoutKey(SDLK_*)
Here is the patch he came up with, and his e-mail about it:
Date: Fri, 17 Aug 2007 19:50:28 +0200
From: Christian Walther
Subject: Re: SDL 1.3 keyboard plan
> Sounds great, go ahead and send me a patch.
Here goes! Thanks for having a look. Don't hesitate to comment if
anything does not conform to your ideas.
One caveat: Committing this now may break compilability of some video
drivers - specifically, if they use any of the SDLK_* codes that were
obsoleted and moved into SDL_compat.h. I only tried Cocoa (which did
break, but is already fixed) and X11 (which didn't, but then its key
handling is #iffed out). If that's a problem, it may need to go into
a branch.
-Christian
--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%402630
2007-08-19 14:52:52 +00:00
SDL_SendKeyboardKey ( data -> keyboard , SDL_RELEASED , ( Uint8 ) scancode , physicalKey ) ;
2006-07-30 05:18:33 +00:00
break ;
case NSFlagsChanged :
Date: Thu, 05 Jul 2007 14:02:33 -0700
From: Sam Lantinga
Subject: SDL 1.3 keyboard plan
After lots of discussion with Christian, this is what we came up with:
> So, to sum up...
> SDLK_* become the physical keys, starting at > (1<<21)
> We create a macro SDLK_INDEX(X)
> We have two functions SDL_GetLayoutKey(SDLKey) and SDL_GetKeyName()
> SDL_GetLayoutKey maps to UCS4 for printable characters, and SDLK* for
non-printable characters
> and does so based on the OS's current keyboard layout
> SDL_GetKeyName() handles both SDLK_* and UCS4, converting UCS4 to UTF-8 and
converting SDLK_* into our names, which are UTF-8 for printable characters.
> WASD folks use SDLK_*, and 'I' folks use SDL_GetLayoutKey(SDLK_*)
Here is the patch he came up with, and his e-mail about it:
Date: Fri, 17 Aug 2007 19:50:28 +0200
From: Christian Walther
Subject: Re: SDL 1.3 keyboard plan
> Sounds great, go ahead and send me a patch.
Here goes! Thanks for having a look. Don't hesitate to comment if
anything does not conform to your ideas.
One caveat: Committing this now may break compilability of some video
drivers - specifically, if they use any of the SDLK_* codes that were
obsoleted and moved into SDL_compat.h. I only tried Cocoa (which did
break, but is already fixed) and X11 (which didn't, but then its key
handling is #iffed out). If that's a problem, it may need to go into
a branch.
-Christian
--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%402630
2007-08-19 14:52:52 +00:00
/ * FIXME CW 2007 -08 -14 : check if this whole mess that takes up half of this file is really necessary * /
2006-07-30 05:18:33 +00:00
HandleModifiers ( _this , scancode , [ event modifierFlags ] ) ;
break ;
Date: Thu, 05 Jul 2007 14:02:33 -0700
From: Sam Lantinga
Subject: SDL 1.3 keyboard plan
After lots of discussion with Christian, this is what we came up with:
> So, to sum up...
> SDLK_* become the physical keys, starting at > (1<<21)
> We create a macro SDLK_INDEX(X)
> We have two functions SDL_GetLayoutKey(SDLKey) and SDL_GetKeyName()
> SDL_GetLayoutKey maps to UCS4 for printable characters, and SDLK* for
non-printable characters
> and does so based on the OS's current keyboard layout
> SDL_GetKeyName() handles both SDLK_* and UCS4, converting UCS4 to UTF-8 and
converting SDLK_* into our names, which are UTF-8 for printable characters.
> WASD folks use SDLK_*, and 'I' folks use SDL_GetLayoutKey(SDLK_*)
Here is the patch he came up with, and his e-mail about it:
Date: Fri, 17 Aug 2007 19:50:28 +0200
From: Christian Walther
Subject: Re: SDL 1.3 keyboard plan
> Sounds great, go ahead and send me a patch.
Here goes! Thanks for having a look. Don't hesitate to comment if
anything does not conform to your ideas.
One caveat: Committing this now may break compilability of some video
drivers - specifically, if they use any of the SDLK_* codes that were
obsoleted and moved into SDL_compat.h. I only tried Cocoa (which did
break, but is already fixed) and X11 (which didn't, but then its key
handling is #iffed out). If that's a problem, it may need to go into
a branch.
-Christian
--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%402630
2007-08-19 14:52:52 +00:00
default : / * just to avoid compiler warnings * /
break ;
}
}
SDLKey
Cocoa_GetLayoutKey ( _THIS , SDLKey physicalKey )
{
switch ( physicalKey ) {
/ * Many of these keys would generate a character in the translation by keyboard layout , but an inappropriate one , so we catch them before . * /
case SDLK_UNKNOWN :
case SDLK_RETURN :
case SDLK_ESCAPE :
case SDLK_BACKSPACE :
case SDLK_TAB :
case SDLK_SPACE :
case SDLK_CAPSLOCK :
case SDLK_F1 :
case SDLK_F2 :
case SDLK_F3 :
case SDLK_F4 :
case SDLK_F5 :
case SDLK_F6 :
case SDLK_F7 :
case SDLK_F8 :
case SDLK_F9 :
case SDLK_F10 :
case SDLK_F11 :
case SDLK_F12 :
case SDLK_PRINTSCREEN :
case SDLK_SCROLLLOCK :
case SDLK_PAUSE :
case SDLK_INSERT :
case SDLK_HOME :
case SDLK_PAGEUP :
case SDLK_DELETE :
case SDLK_END :
case SDLK_PAGEDOWN :
case SDLK_RIGHT :
case SDLK_LEFT :
case SDLK_DOWN :
case SDLK_UP :
case SDLK_KP _NUMLOCKCLEAR :
case SDLK_KP _ENTER :
case SDLK_APPLICATION :
case SDLK_POWER :
case SDLK_F13 :
case SDLK_F14 :
case SDLK_F15 :
case SDLK_F16 :
case SDLK_LCTRL :
case SDLK_LSHIFT :
case SDLK_LALT :
case SDLK_LMETA :
case SDLK_RCTRL :
case SDLK_RSHIFT :
case SDLK_RALT :
case SDLK_RMETA :
return physicalKey ;
/ * For the rest , we try the translation first . * /
default : {
UInt16 vkey = 0 ;
KeyboardLayoutRef layout ;
KeyboardLayoutKind kind ;
UInt32 keyboardType = LMGetKbdType ( ) ;
/ * Look up pkey to get a Mac virtual key code - linear search isn ' t terribly efficient , this might have to be optimized . * /
while ( vkey < 128 && physicalKey ! = macToSDLKey [ vkey ] ) vkey + + ;
if ( vkey = = 128 ) return physicalKey ;
if ( ( vkey = = 10 || vkey = = 50 ) && KBGetLayoutType ( keyboardType ) = = kKeyboardISO ) vkey = 60 - vkey ; / * see comments in SDL_cocoakeys . h * /
if ( KLGetCurrentKeyboardLayout ( & layout ) ! = noErr ) return physicalKey ;
if ( KLGetKeyboardLayoutProperty ( layout , kKLKind , ( const void * * ) & kind ) ! = noErr ) return physicalKey ;
if ( kind = = kKLKCHRuchrKind || kind = = kKLuchrKind ) {
UniChar utf16String [ 4 ] ;
UInt32 deadKeyState = 0 ;
UniCharCount actualStringLength ;
const UCKeyboardLayout * uchrData ;
if ( KLGetKeyboardLayoutProperty ( layout , kKLuchrData , ( const void * * ) & uchrData ) ! = noErr ) return physicalKey ;
if ( UCKeyTranslate ( uchrData , vkey , kUCKeyActionDisplay , 0 , keyboardType , 0 , & deadKeyState , 4 , & actualStringLength , utf16String ) ! = noErr ) return physicalKey ;
/ * kUCKeyActionDisplay ( instead of kUCKeyActionDown ) seems to take care of dead keys , so no need to check for that case and simulate a second key press * /
if ( actualStringLength = = 0 ) return physicalKey ;
/ * Decode the first character from UTF -16. I ' m not sure if this is appropriate for keyboard layouts that generate more than 1 character , or if we would have to use SDL_KEY _LAYOUT _SPECIAL _BIT in that case . * /
if ( utf16String [ 0 ] < 0 xD800 || utf16String [ 0 ] > 0 xDFFF ) {
return utf16String [ 0 ] ;
}
else if ( utf16String [ 0 ] > 0 xDBFF || utf16String [ 1 ] < 0 xDC00 || utf16String [ 1 ] > 0 xDFFF ) {
/ * invalid UTF -16 * /
return physicalKey ;
}
else {
return ( ( ( utf16String [ 0 ] & 0 x3FF ) < < 10 ) | ( utf16String [ 1 ] & 0 x3FF ) ) + 0 x10000 ;
}
}
else { / * kind = = kKLKCHRKind * /
const void * kchrData ;
UInt32 state = 0 ;
UInt8 charCode ;
SInt32 scriptCode ;
TextEncoding keyboardEncoding ;
CFStringRef conversionString ;
UniChar codepoint ;
if ( KLGetKeyboardLayoutProperty ( layout , kKLKCHRData , & kchrData ) ! = noErr ) return physicalKey ;
charCode = KeyTranslate ( kchrData , vkey , & state ) & 0 xFF ; / * Actually returns a UInt32 containing two character codes ( and two ' reserved ' bytes ) , but we ' re only interested in the second ( or only ) one * /
if ( charCode = = 0 ) {
/ * It ' s a dead key , so simulate a second key press * /
charCode = KeyTranslate ( kchrData , vkey , & state ) & 0 xFF ;
/ * Still zero ? Give up . * /
if ( charCode = = 0 ) return physicalKey ;
}
if ( KLGetKeyboardLayoutProperty ( layout , kKLGroupIdentifier , ( const void * * ) & scriptCode ) ! = noErr ) return physicalKey ; / * That the group identifier is actually a script code is not documented , but confirmed here : < http : // lists . apple . com / archives / carbon - dev / 2005 / Jan / msg00533 . html > * /
if ( UpgradeScriptInfoToTextEncoding ( scriptCode , kTextLanguageDontCare , kTextRegionDontCare , NULL , & keyboardEncoding ) ! = noErr ) return physicalKey ;
conversionString = CFStringCreateWithBytes ( kCFAllocatorDefault , & charCode , 1 , keyboardEncoding , FALSE ) ;
codepoint = CFStringGetCharacterAtIndex ( conversionString , 0 ) ;
CFRelease ( conversionString ) ;
return codepoint ;
}
}
2006-07-30 05:18:33 +00:00
}
}
2006-07-23 09:11:10 +00:00
void
Cocoa_QuitKeyboard ( _THIS )
{
SDL_VideoData * data = ( SDL_VideoData * ) _this -> driverdata ;
2007-08-19 16:36:51 +00:00
NSAutoreleasePool * pool ;
2006-07-23 09:11:10 +00:00
SDL_DelKeyboard ( data -> keyboard ) ;
2007-07-11 08:09:20 +00:00
2007-08-19 16:36:51 +00:00
pool = [ [ NSAutoreleasePool alloc ] init ] ;
2007-07-11 08:09:20 +00:00
[ data -> fieldEdit release ] ;
2007-08-19 16:36:51 +00:00
[ pool release ] ;
2006-07-23 09:11:10 +00:00
}
/ * vi : set ts = 4 sw = 4 expandtab : * /