mirror of
https://github.com/fltk/fltk.git
synced 2026-06-04 23:42:15 +08:00
STR #2098: updated the keyboard handling for 10.5 to better handle composed keys. This now works at least for German and American keyboard mapping (I can finally type German text on my US keyboard again), but is still far from perfect. Also applied Ian's patch which I can't test due to missing OS. Thanks, Ian!
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6593 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
CHANGES IN FLTK 1.3.0
|
CHANGES IN FLTK 1.3.0
|
||||||
|
|
||||||
|
- Improved handling of composed keys in OS X 10.5 and up
|
||||||
- Updated the bundled libpng to v1.2.33.
|
- Updated the bundled libpng to v1.2.33.
|
||||||
- Fixed callback would not be called when shortcut was used with
|
- Fixed callback would not be called when shortcut was used with
|
||||||
radio and toggle buttons in default FL_RELEASE mode.
|
radio and toggle buttons in default FL_RELEASE mode.
|
||||||
|
|||||||
+69
-31
@@ -1096,13 +1096,15 @@ static unsigned short keycode_to_sym( UInt32 keyCode, UInt32 mods, unsigned shor
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
* keycode_function for post-10.5 systems, allows more sophisticated decoding of keys
|
||||||
*/
|
*/
|
||||||
static int keycodeToUnicode(
|
static int keycodeToUnicode(
|
||||||
char * uniChars, int maxChars,
|
char * uniChars, int maxChars,
|
||||||
EventKind eKind,
|
EventKind eKind,
|
||||||
UInt32 keycode, UInt32 modifiers,
|
UInt32 keycode, UInt32 modifiers,
|
||||||
UInt32 * deadKeyStatePtr)
|
UInt32 * deadKeyStatePtr,
|
||||||
|
unsigned char, // not used in this function
|
||||||
|
unsigned short) // not used in this function
|
||||||
{
|
{
|
||||||
// first get the keyboard mapping in a post 10.2 way
|
// first get the keyboard mapping in a post 10.2 way
|
||||||
|
|
||||||
@@ -1172,36 +1174,58 @@ static int keycodeToUnicode(
|
|||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UInt32 deadKeyState = *deadKeyStatePtr;
|
||||||
|
if ((action==kUCKeyActionUp)&&(*deadKeyStatePtr))
|
||||||
|
deadKeyStatePtr = &deadKeyState;
|
||||||
|
|
||||||
status = UCKeyTranslate(
|
status = UCKeyTranslate(
|
||||||
(const UCKeyboardLayout *) uchr,
|
(const UCKeyboardLayout *) uchr,
|
||||||
keycode, action, modifiers, keyboardType,
|
keycode, action, modifiers, keyboardType,
|
||||||
options, deadKeyStatePtr,
|
0, deadKeyStatePtr,
|
||||||
10, &actuallength, utext);
|
10, &actuallength, utext);
|
||||||
|
|
||||||
if ((0 == actuallength) && (0 != *deadKeyStatePtr)) {
|
|
||||||
/*
|
|
||||||
* More data later
|
|
||||||
*/
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
*deadKeyStatePtr = 0;
|
|
||||||
|
|
||||||
if (noErr != status) {
|
if (noErr != status) {
|
||||||
fprintf(stderr,"UCKeyTranslate failed: %d", (int) status);
|
fprintf(stderr,"UCKeyTranslate failed: %d\n", (int) status);
|
||||||
actuallength = 0;
|
actuallength = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// convert the list of unicode chars into utf8
|
||||||
// FIXME no bounds check (see maxchars)
|
// FIXME no bounds check (see maxchars)
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for (i=0; i<actuallength; ++i) {
|
for (i=0; i<actuallength; ++i) {
|
||||||
len += fl_utf8encode(utext[i], uniChars+len);
|
len += fl_utf8encode(utext[i], uniChars+len);
|
||||||
}
|
}
|
||||||
uniChars[len] = 0;
|
uniChars[len] = 0;
|
||||||
|
return len;
|
||||||
return actuallength;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* keycode_function for pre-10.5 systems, this is the "historic" fltk Mac key handling
|
||||||
|
*/
|
||||||
|
static int keycode_wrap_old(
|
||||||
|
char * buffer,
|
||||||
|
int, EventKind, UInt32, // not used in this function
|
||||||
|
UInt32, UInt32 *, // not used in this function
|
||||||
|
unsigned char key,
|
||||||
|
unsigned short sym)
|
||||||
|
{
|
||||||
|
if ( (sym >= FL_KP && sym <= FL_KP_Last) || !(sym & 0xff00) ||
|
||||||
|
sym == FL_Tab || sym == FL_Enter) {
|
||||||
|
buffer[0] = key;
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
buffer[0] = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} /* keycode_wrap_old */
|
||||||
|
/*
|
||||||
|
* Stub pointer to select appropriate keycode_function per operating system version. This function pointer
|
||||||
|
* is initialised in fl_open_display, based on the runtime identification of the host OS version. This is
|
||||||
|
* intended to allow us to utilise 10.5 services dynamically to improve Unicode handling, whilst still
|
||||||
|
* allowing code to run satisfactorily on older systems.
|
||||||
|
*/
|
||||||
|
static int (*keycode_function)(char*, int, EventKind, UInt32, UInt32, UInt32*, unsigned char, unsigned short) = keycode_wrap_old;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* handle carbon keyboard events
|
* handle carbon keyboard events
|
||||||
@@ -1234,7 +1258,7 @@ pascal OSStatus carbonKeyboardHandler(
|
|||||||
GetEventParameter( event, kEventParamKeyMacCharCodes, typeChar,
|
GetEventParameter( event, kEventParamKeyMacCharCodes, typeChar,
|
||||||
NULL, sizeof(char), NULL, &key );
|
NULL, sizeof(char), NULL, &key );
|
||||||
}
|
}
|
||||||
/* output a human readbale event identifier for debugging
|
/* output a human readable event identifier for debugging
|
||||||
const char *ev = "";
|
const char *ev = "";
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case kEventRawKeyDown: ev = "kEventRawKeyDown"; break;
|
case kEventRawKeyDown: ev = "kEventRawKeyDown"; break;
|
||||||
@@ -1249,6 +1273,8 @@ pascal OSStatus carbonKeyboardHandler(
|
|||||||
{
|
{
|
||||||
case kEventRawKeyDown:
|
case kEventRawKeyDown:
|
||||||
case kEventRawKeyRepeat:
|
case kEventRawKeyRepeat:
|
||||||
|
/*
|
||||||
|
// FIXME Matt: For 10.5, the keycode_function will handle all this. This is untested for ealier versions of OS X.
|
||||||
// When the user presses a "dead key", no information is send about
|
// When the user presses a "dead key", no information is send about
|
||||||
// which dead key symbol was created. So we need to trick Carbon into
|
// which dead key symbol was created. So we need to trick Carbon into
|
||||||
// giving us the code by sending a "space" after the "dead key".
|
// giving us the code by sending a "space" after the "dead key".
|
||||||
@@ -1263,6 +1289,7 @@ pascal OSStatus carbonKeyboardHandler(
|
|||||||
} else {
|
} else {
|
||||||
Fl::e_state &= 0xbfffffff; // clear the deadkey flag
|
Fl::e_state &= 0xbfffffff; // clear the deadkey flag
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
sendEvent = FL_KEYBOARD;
|
sendEvent = FL_KEYBOARD;
|
||||||
// fall through
|
// fall through
|
||||||
case kEventRawKeyUp:
|
case kEventRawKeyUp:
|
||||||
@@ -1287,22 +1314,14 @@ pascal OSStatus carbonKeyboardHandler(
|
|||||||
// Matt: to Carbon. The kEventKeyModifierNumLockMask is only set when
|
// Matt: to Carbon. The kEventKeyModifierNumLockMask is only set when
|
||||||
// Matt: a numeric keypad key is pressed and does not correspond with
|
// Matt: a numeric keypad key is pressed and does not correspond with
|
||||||
// Matt: the NumLock light in PowerBook keyboards.
|
// Matt: the NumLock light in PowerBook keyboards.
|
||||||
#if 1
|
|
||||||
if ( (sym >= FL_KP && sym <= FL_KP_Last) || !(sym & 0xff00) ||
|
// Matt: attempt to get the correct Unicode character(s) from our keycode
|
||||||
sym == FL_Tab || sym == FL_Enter) {
|
// imm: keycode_function function pointer added to allow us to use different functions
|
||||||
buffer[0] = key;
|
// imm: depending on which OS version we are running on (tested and set in fl_open_display)
|
||||||
Fl::e_length = 1;
|
|
||||||
} else {
|
|
||||||
buffer[0] = 0;
|
|
||||||
Fl::e_length = 0;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// Matt: attempt to get the correct Unicode character(S) from our keycode
|
|
||||||
static UInt32 deadKeyState = 0; // must be cleared when losing focus
|
static UInt32 deadKeyState = 0; // must be cleared when losing focus
|
||||||
Fl::e_length = keycodeToUnicode(buffer, 31, kind, keyCode, mods, &deadKeyState);
|
Fl::e_length = (*keycode_function)(buffer, 31, kind, keyCode, mods, &deadKeyState, key, sym);
|
||||||
#endif
|
|
||||||
Fl::e_text = buffer;
|
Fl::e_text = buffer;
|
||||||
// insert UnicodeHandling here!
|
buffer[Fl::e_length] = 0; // just in case...
|
||||||
break;
|
break;
|
||||||
case kEventRawKeyModifiersChanged: {
|
case kEventRawKeyModifiersChanged: {
|
||||||
UInt32 tMods = prevMods ^ mods;
|
UInt32 tMods = prevMods ^ mods;
|
||||||
@@ -1467,6 +1486,25 @@ void fl_open_display() {
|
|||||||
CFRelease(execUrl);
|
CFRelease(execUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// imm: keycode handler stub setting - use Gestalt to determine the running system version,
|
||||||
|
// then set the keycode_function pointer accordingly
|
||||||
|
SInt32 MacVersion;
|
||||||
|
if (Gestalt(gestaltSystemVersion, &MacVersion) == noErr)
|
||||||
|
{
|
||||||
|
// SInt32 maj, min, fix;
|
||||||
|
// Gestalt(gestaltSystemVersionMajor, &maj); // e.g. 10
|
||||||
|
// Gestalt(gestaltSystemVersionMinor, &min); // e.g. 4
|
||||||
|
// Gestalt(gestaltSystemVersionBugFix, &fix); // e.g. 11
|
||||||
|
if(MacVersion >= 0x1050) { // 10.5.0 or later
|
||||||
|
keycode_function = keycodeToUnicode;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
keycode_function = keycode_wrap_old; // pre-10.5 mechanism
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// else our default handler will be used (keycode_wrap_old)
|
||||||
|
|
||||||
|
|
||||||
if( !bundle )
|
if( !bundle )
|
||||||
{
|
{
|
||||||
// Earlier versions of this code tried to use weak linking, however it
|
// Earlier versions of this code tried to use weak linking, however it
|
||||||
|
|||||||
Reference in New Issue
Block a user