fix Mac input to work with the character palette and CJK input
svn: r4624
This commit is contained in:
parent
8798784bd5
commit
a9ab05d0f5
|
@ -41,6 +41,9 @@ static void MrDequeue(MrQueueElem *q);
|
||||||
WindowPtr MrEdMouseWindow(Point where);
|
WindowPtr MrEdMouseWindow(Point where);
|
||||||
WindowPtr MrEdKeyWindow();
|
WindowPtr MrEdKeyWindow();
|
||||||
|
|
||||||
|
extern int wxTranslateRawKey(int key);
|
||||||
|
extern short wxMacDisableMods;
|
||||||
|
|
||||||
typedef MrQueueElem *MrQueueRef;
|
typedef MrQueueElem *MrQueueRef;
|
||||||
|
|
||||||
typedef int (*Checker_Func)(EventRecord *evt, MrQueueRef q, int check_only,
|
typedef int (*Checker_Func)(EventRecord *evt, MrQueueRef q, int check_only,
|
||||||
|
@ -276,9 +279,15 @@ static int pending_self_ae;
|
||||||
|
|
||||||
static void EnsureWNEReturn()
|
static void EnsureWNEReturn()
|
||||||
{
|
{
|
||||||
/* Generate an event that WaitNextEvent will return, but
|
/* Generate an event that WaitNextEvent() will return, but that we can
|
||||||
that we can recognize and ignore. An AppleEvent is a
|
recognize and ignore. (Note that window handlers can run nested
|
||||||
heavyweight but reliable way to do that. */
|
event handlers, such as the resize handler for the little
|
||||||
|
OS-provided window to implement Chinese text via pinyin. We need
|
||||||
|
something that doesn't break those loops.) An AppleEvent is a
|
||||||
|
heavyweight(?) but apparently reliable way to get WaitNextEvent() to
|
||||||
|
return. Of course, don't install the standard handlers that are put
|
||||||
|
in place by RunApplicationEventLoop(), because they'll dispatch the
|
||||||
|
dummy AppleEvent and defeat the purpose. */
|
||||||
if (!pending_self_ae) {
|
if (!pending_self_ae) {
|
||||||
ProcessSerialNumber psn;
|
ProcessSerialNumber psn;
|
||||||
AEAddressDesc target;
|
AEAddressDesc target;
|
||||||
|
@ -332,20 +341,34 @@ void wxSmuggleOutEvent(EventRef ref)
|
||||||
&& (GetEventKind(ref) == kEventTextInputUnicodeForKeyEvent)) {
|
&& (GetEventKind(ref) == kEventTextInputUnicodeForKeyEvent)) {
|
||||||
UniChar *text;
|
UniChar *text;
|
||||||
UInt32 actualSize;
|
UInt32 actualSize;
|
||||||
|
EventRef kref;
|
||||||
|
|
||||||
GetEventParameter(ref, kEventParamTextInputSendText,
|
GetEventParameter(ref, kEventParamTextInputSendKeyboardEvent,
|
||||||
typeUnicodeText, NULL, 0, &actualSize, NULL);
|
typeEventRef, NULL, sizeof(EventRef), NULL, &kref);
|
||||||
if (actualSize) {
|
if (ConvertEventRefToEventRecord(kref, &e)) {
|
||||||
text = (UniChar*)scheme_malloc_atomic(actualSize);
|
ok = TRUE;
|
||||||
GetEventParameter(ref, kEventParamTextInputSendText,
|
} else {
|
||||||
typeUnicodeText, NULL, actualSize, NULL, text);
|
|
||||||
|
|
||||||
e.what = unicodeEvt;
|
|
||||||
e.message = text[0];
|
|
||||||
e.modifiers = 0;
|
e.modifiers = 0;
|
||||||
|
e.message = 0;
|
||||||
e.where.h = 0;
|
e.where.h = 0;
|
||||||
e.where.v = 0;
|
e.where.v = 0;
|
||||||
ok = TRUE;
|
}
|
||||||
|
|
||||||
|
if ((e.modifiers & (wxMacDisableMods | cmdKey))
|
||||||
|
|| wxTranslateRawKey((e.message & keyCodeMask) >> 8)) {
|
||||||
|
/* keep the raw event */
|
||||||
|
} else {
|
||||||
|
GetEventParameter(ref, kEventParamTextInputSendText,
|
||||||
|
typeUnicodeText, NULL, 0, &actualSize, NULL);
|
||||||
|
if (actualSize) {
|
||||||
|
text = (UniChar*)scheme_malloc_atomic(actualSize);
|
||||||
|
GetEventParameter(ref, kEventParamTextInputSendText,
|
||||||
|
typeUnicodeText, NULL, actualSize, NULL, text);
|
||||||
|
|
||||||
|
e.what = unicodeEvt;
|
||||||
|
e.message = text[0];
|
||||||
|
ok = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ok = ConvertEventRefToEventRecord(ref, &e);
|
ok = ConvertEventRefToEventRecord(ref, &e);
|
||||||
|
@ -379,7 +402,7 @@ static pascal OSErr HandleSmug(const AppleEvent *evt, AppleEvent *rae, long k)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WNE: a small wrapper for WaitNextEvent, mostly to manage
|
/* WNE: a small wrapper for WaitNextEvent(), mostly to manage
|
||||||
wake-up activities.
|
wake-up activities.
|
||||||
It's tempting to try to use ReceiveNextEvent() to filter
|
It's tempting to try to use ReceiveNextEvent() to filter
|
||||||
the raw events. Don't do that, because WaitNextEvent() is
|
the raw events. Don't do that, because WaitNextEvent() is
|
||||||
|
@ -424,7 +447,7 @@ int WNE(EventRecord *e, double sleep_secs)
|
||||||
|
|
||||||
::InstallEventHandler(GetEventDispatcherTarget(),
|
::InstallEventHandler(GetEventDispatcherTarget(),
|
||||||
smuggle_handler,
|
smuggle_handler,
|
||||||
2,
|
3,
|
||||||
evts,
|
evts,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
@ -465,7 +488,7 @@ static int TransferQueue(int all)
|
||||||
int sleep_time = 0;
|
int sleep_time = 0;
|
||||||
int delay_time = 0;
|
int delay_time = 0;
|
||||||
|
|
||||||
/* Don't call WaitNextEvent too often. */
|
/* Don't call WaitNextEvent() too often. */
|
||||||
static unsigned long lastTime;
|
static unsigned long lastTime;
|
||||||
if (TickCount() <= lastTime + delay_time)
|
if (TickCount() <= lastTime + delay_time)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -726,6 +749,7 @@ static int CheckForMouseOrKey(EventRecord *e, MrQueueRef osq, int check_only,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case wheelEvt:
|
case wheelEvt:
|
||||||
|
case unicodeEvt:
|
||||||
case keyDown:
|
case keyDown:
|
||||||
case autoKey:
|
case autoKey:
|
||||||
case keyUp:
|
case keyUp:
|
||||||
|
@ -754,10 +778,6 @@ static int CheckForActivate(EventRecord *evt, MrQueueRef q, int check_only,
|
||||||
WindowPtr window;
|
WindowPtr window;
|
||||||
|
|
||||||
switch (evt->what) {
|
switch (evt->what) {
|
||||||
#ifndef OS_X
|
|
||||||
// OS X does not support the diskEvt event.
|
|
||||||
case diskEvt:
|
|
||||||
#endif
|
|
||||||
case kHighLevelEvent:
|
case kHighLevelEvent:
|
||||||
{
|
{
|
||||||
MrEdContext *fc;
|
MrEdContext *fc;
|
||||||
|
@ -904,6 +924,7 @@ int MrEdGetNextEvent(int check_only, int current_only,
|
||||||
case mouseMenuDown:
|
case mouseMenuDown:
|
||||||
case mouseDown:
|
case mouseDown:
|
||||||
case wheelEvt:
|
case wheelEvt:
|
||||||
|
case unicodeEvt:
|
||||||
case keyDown:
|
case keyDown:
|
||||||
case keyUp:
|
case keyUp:
|
||||||
case autoKey:
|
case autoKey:
|
||||||
|
@ -1071,14 +1092,12 @@ int MrEdCheckForBreak(void)
|
||||||
/* sleep */
|
/* sleep */
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
#ifdef OS_X
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
static volatile int thread_running;
|
static volatile int thread_running;
|
||||||
static volatile int need_post; /* 0=>1 transition has a benign race condition, an optimization */
|
static volatile int need_post; /* 0=>1 transition has a benign race condition, an optimization */
|
||||||
static SLEEP_PROC_PTR mzsleep;
|
static SLEEP_PROC_PTR mzsleep;
|
||||||
static pthread_t watcher;
|
static pthread_t watcher;
|
||||||
static volatile float sleep_secs;
|
static volatile float sleep_secs;
|
||||||
static ProcessSerialNumber psn;
|
|
||||||
|
|
||||||
/* These file descriptors act as semaphores: */
|
/* These file descriptors act as semaphores: */
|
||||||
static int watch_read_fd, watch_write_fd;
|
static int watch_read_fd, watch_write_fd;
|
||||||
|
@ -1103,7 +1122,6 @@ static void *do_watch(void *fds)
|
||||||
mzsleep(sleep_secs, fds);
|
mzsleep(sleep_secs, fds);
|
||||||
if (need_post) {
|
if (need_post) {
|
||||||
need_post = 0;
|
need_post = 0;
|
||||||
WakeUpProcess(&psn);
|
|
||||||
if (cb_socket_ready) {
|
if (cb_socket_ready) {
|
||||||
/* Sometimes WakeUpProcess() doesn't work.
|
/* Sometimes WakeUpProcess() doesn't work.
|
||||||
Try a notification socket as a backup.
|
Try a notification socket as a backup.
|
||||||
|
@ -1145,7 +1163,6 @@ static int StartFDWatcher(void (*mzs)(float secs, void *fds), float secs, void *
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!watcher) {
|
if (!watcher) {
|
||||||
GetCurrentProcess(&psn);
|
|
||||||
if (pthread_create(&watcher, NULL, do_watch, fds)) {
|
if (pthread_create(&watcher, NULL, do_watch, fds)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1175,32 +1192,26 @@ static void EndFDWatcher(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See ARGH below. */
|
|
||||||
void socket_callback(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info)
|
void socket_callback(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info)
|
||||||
{
|
{
|
||||||
WakeUpProcess(&psn);
|
EnsureWNEReturn();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See ARGH below. */
|
|
||||||
static const void *sock_retain(const void *info)
|
static const void *sock_retain(const void *info)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See ARGH below. */
|
|
||||||
static void sock_release(const void *info)
|
static void sock_release(const void *info)
|
||||||
{
|
{
|
||||||
/* do nothing */
|
/* do nothing */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See ARGH below. */
|
|
||||||
static CFStringRef sock_copy_desc(const void *info)
|
static CFStringRef sock_copy_desc(const void *info)
|
||||||
{
|
{
|
||||||
return CFSTR("sock");
|
return CFSTR("sock");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int going, reported_recursive_sleep;
|
static int going, reported_recursive_sleep;
|
||||||
|
|
||||||
void MrEdMacSleep(float secs, void *fds, SLEEP_PROC_PTR mzsleep)
|
void MrEdMacSleep(float secs, void *fds, SLEEP_PROC_PTR mzsleep)
|
||||||
|
@ -1215,24 +1226,24 @@ void MrEdMacSleep(float secs, void *fds, SLEEP_PROC_PTR mzsleep)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we're asked to sleep less than 1/60 of a second, then don't
|
/* If we're asked to sleep less than 1/60 of a second, then don't
|
||||||
bother with WaitNextEvent. */
|
bother with WaitNextEvent(). */
|
||||||
if ((secs > 0) && (secs < 1.0/60)) {
|
if ((secs > 0) && (secs < 1.0/60)) {
|
||||||
mzsleep(secs, fds);
|
mzsleep(secs, fds);
|
||||||
} else {
|
} else {
|
||||||
EventRecord e;
|
EventRecord e;
|
||||||
|
|
||||||
if (!cb_socket_ready) {
|
if (!cb_socket_ready) {
|
||||||
/* ARGH: We set up a pipe for the purpose of breaking the Carbon
|
/* We set up a pipe for the purpose of breaking the Carbon
|
||||||
event manager out of its loop. When the watcher thread sees
|
event manager out of its loop. When the watcher thread sees
|
||||||
that an fd is ready, it writes to write_sock_ready, which
|
that an fd is ready, it writes to write_sock_ready, which
|
||||||
means that sock_ready is ready to read, which means that
|
means that sock_ready is ready to read, which means that
|
||||||
socket_callback is invoked, and it calls WakeUpProcess().
|
socket_callback is invoked, and it calls EnsureWNEReturn().
|
||||||
|
|
||||||
None of this would be necessary if WakeUpProcess() worked
|
With the current implementation of EnsureWNEReturn(), this is
|
||||||
correctly, because the watcher thread also calls
|
probably overkill. I think the watcher thread could call
|
||||||
WakeUpProcess(). It seems to have become broken in OS X 10.2,
|
EnsureWNEReturn() directly. Doing it this way moves the call
|
||||||
where WakeUpprocess() doesn't work when called before the WNE
|
into this thread, though, which seems more robust in the long
|
||||||
starts (reminiscent of OS 7.1.2 or so). */
|
run (i.e., if EnsureWNEReturn() changes). */
|
||||||
int fds[2];
|
int fds[2];
|
||||||
if (!pipe(fds)) {
|
if (!pipe(fds)) {
|
||||||
CFRunLoopRef rl;
|
CFRunLoopRef rl;
|
||||||
|
|
|
@ -46,6 +46,8 @@ extern WindowPtr MrEdKeyWindow();
|
||||||
|
|
||||||
extern void wxCheckRootFrame(WindowPtr w);
|
extern void wxCheckRootFrame(WindowPtr w);
|
||||||
|
|
||||||
|
int wxTranslateRawKey(int key);
|
||||||
|
|
||||||
int wxMenuBarHeight;
|
int wxMenuBarHeight;
|
||||||
|
|
||||||
extern wxApp *wxTheApp;
|
extern wxApp *wxTheApp;
|
||||||
|
@ -649,232 +651,141 @@ void wxApp::doMacKeyUpDown(Bool down)
|
||||||
} else if (cCurrentEvent.what == unicodeEvt) {
|
} else if (cCurrentEvent.what == unicodeEvt) {
|
||||||
key = cCurrentEvent.message;
|
key = cCurrentEvent.message;
|
||||||
} else {
|
} else {
|
||||||
|
int newkey;
|
||||||
|
|
||||||
key = (cCurrentEvent.message & keyCodeMask) >> 8;
|
key = (cCurrentEvent.message & keyCodeMask) >> 8;
|
||||||
/* Better way than to use hard-wired key codes? */
|
newkey = wxTranslateRawKey(key);
|
||||||
switch (key) {
|
|
||||||
# define wxFKEY(code, wxk) case code: key = wxk; break
|
|
||||||
wxFKEY(122, WXK_F1);
|
|
||||||
wxFKEY(120, WXK_F2);
|
|
||||||
wxFKEY(99, WXK_F3);
|
|
||||||
wxFKEY(118, WXK_F4);
|
|
||||||
wxFKEY(96, WXK_F5);
|
|
||||||
wxFKEY(97, WXK_F6);
|
|
||||||
wxFKEY(98, WXK_F7);
|
|
||||||
wxFKEY(100, WXK_F8);
|
|
||||||
wxFKEY(101, WXK_F9);
|
|
||||||
wxFKEY(109, WXK_F10);
|
|
||||||
wxFKEY(103, WXK_F11);
|
|
||||||
wxFKEY(111, WXK_F12);
|
|
||||||
wxFKEY(105, WXK_F13);
|
|
||||||
wxFKEY(107, WXK_F14);
|
|
||||||
wxFKEY(113, WXK_F15);
|
|
||||||
case 0x7e:
|
|
||||||
case 0x3e:
|
|
||||||
key = WXK_UP;
|
|
||||||
break;
|
|
||||||
case 0x7d:
|
|
||||||
case 0x3d:
|
|
||||||
key = WXK_DOWN;
|
|
||||||
break;
|
|
||||||
case 0x7b:
|
|
||||||
case 0x3b:
|
|
||||||
key = WXK_LEFT;
|
|
||||||
break;
|
|
||||||
case 0x7c:
|
|
||||||
case 0x3c:
|
|
||||||
key = WXK_RIGHT;
|
|
||||||
break;
|
|
||||||
case 0x24:
|
|
||||||
key = WXK_RETURN;
|
|
||||||
break;
|
|
||||||
case 0x30:
|
|
||||||
key = WXK_TAB;
|
|
||||||
break;
|
|
||||||
case 0x33:
|
|
||||||
key = WXK_BACK;
|
|
||||||
break;
|
|
||||||
case 0x75:
|
|
||||||
key = WXK_DELETE;
|
|
||||||
break;
|
|
||||||
case 0x73:
|
|
||||||
key = WXK_HOME;
|
|
||||||
break;
|
|
||||||
case 0x77:
|
|
||||||
key = WXK_END;
|
|
||||||
break;
|
|
||||||
case 0x74:
|
|
||||||
key = WXK_PRIOR;
|
|
||||||
break;
|
|
||||||
case 0x79:
|
|
||||||
key = WXK_NEXT;
|
|
||||||
break;
|
|
||||||
case 0x45:
|
|
||||||
key = WXK_ADD;
|
|
||||||
break;
|
|
||||||
case 78:
|
|
||||||
key = WXK_SUBTRACT;
|
|
||||||
break;
|
|
||||||
case 0x43:
|
|
||||||
key = WXK_MULTIPLY;
|
|
||||||
break;
|
|
||||||
case 0x4B:
|
|
||||||
key = WXK_DIVIDE;
|
|
||||||
break;
|
|
||||||
case 71:
|
|
||||||
key = WXK_SEPARATOR;
|
|
||||||
break;
|
|
||||||
case 65:
|
|
||||||
key = WXK_DECIMAL;
|
|
||||||
break;
|
|
||||||
case 76:
|
|
||||||
key = 3; /* numpad enter */
|
|
||||||
break;
|
|
||||||
case 82:
|
|
||||||
case 83:
|
|
||||||
case 84:
|
|
||||||
case 85:
|
|
||||||
case 86:
|
|
||||||
case 87:
|
|
||||||
case 88:
|
|
||||||
case 89:
|
|
||||||
key = WXK_NUMPAD0 + (key - 82);
|
|
||||||
break;
|
|
||||||
case 91:
|
|
||||||
key = WXK_NUMPAD8;
|
|
||||||
break;
|
|
||||||
case 92:
|
|
||||||
key = WXK_NUMPAD9;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
int iter, akey, orig_key = key;
|
|
||||||
|
|
||||||
key = 0; /* let compiler know that key is assigned */
|
if (newkey) {
|
||||||
for (iter = 0; iter < ((cCurrentEvent.modifiers & cmdKey) ? 2 : 1); iter++) {
|
key = newkey;
|
||||||
char cstr[3];
|
} else {
|
||||||
int from_str = 0;
|
int iter, akey, orig_key = key;
|
||||||
|
|
||||||
akey = orig_key;
|
key = 0; /* let compiler know that key is assigned */
|
||||||
|
for (iter = 0; iter < ((cCurrentEvent.modifiers & cmdKey) ? 2 : 1); iter++) {
|
||||||
|
char cstr[3];
|
||||||
|
int from_str = 0;
|
||||||
|
|
||||||
if (cCurrentEvent.modifiers & (wxMacDisableMods | cmdKey)) {
|
akey = orig_key;
|
||||||
/* The following code manually translates the virtual key event
|
|
||||||
into a character. We'd use this code all the time, except
|
|
||||||
that dead keys have already been filtered before we get here,
|
|
||||||
which means that option-e-e doesn't produce an accented e.
|
|
||||||
So, instead, we only use this code to find out what would
|
|
||||||
happen if the control/option key wasn't pressed. */
|
|
||||||
int mods;
|
|
||||||
OSStatus status;
|
|
||||||
UniCharCount len;
|
|
||||||
UniChar keys[1];
|
|
||||||
SInt16 currentKeyLayoutID;
|
|
||||||
static UCKeyboardLayout *key_layout;
|
|
||||||
|
|
||||||
mods = cCurrentEvent.modifiers;
|
if (cCurrentEvent.modifiers & (wxMacDisableMods | cmdKey)) {
|
||||||
if (mods & cmdKey) {
|
/* The following code manually translates the virtual key event
|
||||||
/* Strip control and option modifiers when command is pressed: */
|
into a character. We'd use this code all the time, except
|
||||||
mods -= (mods & (optionKey | controlKey | cmdKey | shiftKey));
|
that dead keys have already been filtered before we get here,
|
||||||
/* On second iteration, set the shift key: */
|
which means that option-e-e doesn't produce an accented e.
|
||||||
if (iter)
|
So, instead, we only use this code to find out what would
|
||||||
mods |= shiftKey;
|
happen if the control/option key wasn't pressed. */
|
||||||
} else {
|
int mods;
|
||||||
/* Remove effect of anything in wxMacDisableMods: */
|
OSStatus status;
|
||||||
mods -= (mods & wxMacDisableMods);
|
UniCharCount len;
|
||||||
}
|
UniChar keys[1];
|
||||||
|
SInt16 currentKeyLayoutID;
|
||||||
|
static UCKeyboardLayout *key_layout;
|
||||||
|
|
||||||
currentKeyLayoutID = GetScriptVariable(GetScriptManagerVariable(smKeyScript), smScriptKeys);
|
mods = cCurrentEvent.modifiers;
|
||||||
if (!keyLayoutSet || (currentKeyLayoutID != lastKeyLayoutID)) {
|
if (mods & cmdKey) {
|
||||||
KeyboardLayoutRef kl;
|
/* Strip control and option modifiers when command is pressed: */
|
||||||
key_state = 0;
|
mods -= (mods & (optionKey | controlKey | cmdKey | shiftKey));
|
||||||
if (KLGetCurrentKeyboardLayout(&kl) == noErr) {
|
/* On second iteration, set the shift key: */
|
||||||
void *p;
|
if (iter)
|
||||||
if (KLGetKeyboardLayoutProperty(kl, kKLKCHRData, (const void **)&p) == noErr) {
|
mods |= shiftKey;
|
||||||
KCHRPtr = p;
|
} else {
|
||||||
} else
|
/* Remove effect of anything in wxMacDisableMods: */
|
||||||
KCHRPtr = NULL;
|
mods -= (mods & wxMacDisableMods);
|
||||||
if (KLGetKeyboardLayoutProperty(kl, kKLuchrData, (const void **)&p) == noErr)
|
}
|
||||||
uchrPtr = p;
|
|
||||||
else
|
|
||||||
uchrPtr = NULL;
|
|
||||||
}
|
|
||||||
lastKeyLayoutID = currentKeyLayoutID;
|
|
||||||
keyLayoutSet = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!uchrPtr) {
|
currentKeyLayoutID = GetScriptVariable(GetScriptManagerVariable(smKeyScript), smScriptKeys);
|
||||||
if (!KCHRPtr) {
|
if (!keyLayoutSet || (currentKeyLayoutID != lastKeyLayoutID)) {
|
||||||
akey = '?';
|
KeyboardLayoutRef kl;
|
||||||
} else {
|
key_state = 0;
|
||||||
int trans;
|
if (KLGetCurrentKeyboardLayout(&kl) == noErr) {
|
||||||
trans = KeyTranslate(KCHRPtr, akey | mods, &key_state);
|
void *p;
|
||||||
if (trans & 0xFF0000) {
|
if (KLGetKeyboardLayoutProperty(kl, kKLKCHRData, (const void **)&p) == noErr) {
|
||||||
/* 2-byte result */
|
KCHRPtr = p;
|
||||||
cstr[0] = (trans & 0xFF0000) >> 16;
|
} else
|
||||||
cstr[1] = trans & 0xFF;
|
KCHRPtr = NULL;
|
||||||
cstr[2] = 0;
|
if (KLGetKeyboardLayoutProperty(kl, kKLuchrData, (const void **)&p) == noErr)
|
||||||
} else {
|
uchrPtr = p;
|
||||||
/* 1-byte result */
|
else
|
||||||
cstr[0] = trans & 0xFF;
|
uchrPtr = NULL;
|
||||||
cstr[1] = 0;
|
}
|
||||||
}
|
lastKeyLayoutID = currentKeyLayoutID;
|
||||||
|
keyLayoutSet = 1;
|
||||||
|
}
|
||||||
|
|
||||||
akey = '?'; /* temporary */
|
if (!uchrPtr) {
|
||||||
from_str = 1;
|
if (!KCHRPtr) {
|
||||||
}
|
akey = '?';
|
||||||
} else {
|
} else {
|
||||||
key_layout = (UCKeyboardLayout *)uchrPtr;
|
int trans;
|
||||||
|
trans = KeyTranslate(KCHRPtr, akey | mods, &key_state);
|
||||||
|
if (trans & 0xFF0000) {
|
||||||
|
/* 2-byte result */
|
||||||
|
cstr[0] = (trans & 0xFF0000) >> 16;
|
||||||
|
cstr[1] = trans & 0xFF;
|
||||||
|
cstr[2] = 0;
|
||||||
|
} else {
|
||||||
|
/* 1-byte result */
|
||||||
|
cstr[0] = trans & 0xFF;
|
||||||
|
cstr[1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
status = UCKeyTranslate(key_layout,
|
akey = '?'; /* temporary */
|
||||||
akey,
|
from_str = 1;
|
||||||
cCurrentEvent.what - keyDown,
|
}
|
||||||
mods >> 8,
|
} else {
|
||||||
LMGetKbdType(),
|
key_layout = (UCKeyboardLayout *)uchrPtr;
|
||||||
0 /* options */,
|
|
||||||
&key_state,
|
|
||||||
1,
|
|
||||||
&len,
|
|
||||||
keys);
|
|
||||||
|
|
||||||
if (status == noErr)
|
status = UCKeyTranslate(key_layout,
|
||||||
akey = keys[0];
|
akey,
|
||||||
else
|
cCurrentEvent.what - keyDown,
|
||||||
akey = '?';
|
mods >> 8,
|
||||||
}
|
LMGetKbdType(),
|
||||||
} else {
|
0 /* options */,
|
||||||
akey = '?'; /* temporary */
|
&key_state,
|
||||||
cstr[0] = cCurrentEvent.message & charCodeMask;
|
1,
|
||||||
cstr[1] = 0;
|
&len,
|
||||||
from_str = 1;
|
keys);
|
||||||
}
|
|
||||||
|
|
||||||
if (from_str) {
|
if (status == noErr)
|
||||||
CFStringRef str;
|
akey = keys[0];
|
||||||
UniChar keys[1];
|
else
|
||||||
|
akey = '?';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
akey = '?'; /* temporary */
|
||||||
|
cstr[0] = cCurrentEvent.message & charCodeMask;
|
||||||
|
cstr[1] = 0;
|
||||||
|
from_str = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (from_str) {
|
||||||
|
CFStringRef str;
|
||||||
|
UniChar keys[1];
|
||||||
|
|
||||||
str = CFStringCreateWithCStringNoCopy(NULL, cstr,
|
str = CFStringCreateWithCStringNoCopy(NULL, cstr,
|
||||||
GetScriptManagerVariable(smKeyScript),
|
GetScriptManagerVariable(smKeyScript),
|
||||||
kCFAllocatorNull);
|
kCFAllocatorNull);
|
||||||
if (str) {
|
if (str) {
|
||||||
if (CFStringGetLength(str) > 0) {
|
if (CFStringGetLength(str) > 0) {
|
||||||
GC_CAN_IGNORE CFRange rng;
|
GC_CAN_IGNORE CFRange rng;
|
||||||
rng = CFRangeMake(0, 1);
|
rng = CFRangeMake(0, 1);
|
||||||
CFStringGetCharacters(str, rng, keys);
|
CFStringGetCharacters(str, rng, keys);
|
||||||
} else
|
} else
|
||||||
keys[0] = '?';
|
keys[0] = '?';
|
||||||
CFRelease(str);
|
CFRelease(str);
|
||||||
} else
|
} else
|
||||||
keys[0] = '?';
|
keys[0] = '?';
|
||||||
|
|
||||||
akey = keys[0];
|
akey = keys[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!iter)
|
if (!iter)
|
||||||
key = akey;
|
key = akey;
|
||||||
else
|
else
|
||||||
otherKey = akey;
|
otherKey = akey;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} // end switch
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (down) {
|
if (down) {
|
||||||
|
@ -915,6 +826,111 @@ void wxApp::doMacAutoKey(void)
|
||||||
doMacKeyUpDown(true);
|
doMacKeyUpDown(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int wxTranslateRawKey(int key)
|
||||||
|
{
|
||||||
|
/* Better way than to use hard-wired key codes? */
|
||||||
|
switch (key) {
|
||||||
|
# define wxFKEY(code, wxk) case code: key = wxk; break
|
||||||
|
wxFKEY(122, WXK_F1);
|
||||||
|
wxFKEY(120, WXK_F2);
|
||||||
|
wxFKEY(99, WXK_F3);
|
||||||
|
wxFKEY(118, WXK_F4);
|
||||||
|
wxFKEY(96, WXK_F5);
|
||||||
|
wxFKEY(97, WXK_F6);
|
||||||
|
wxFKEY(98, WXK_F7);
|
||||||
|
wxFKEY(100, WXK_F8);
|
||||||
|
wxFKEY(101, WXK_F9);
|
||||||
|
wxFKEY(109, WXK_F10);
|
||||||
|
wxFKEY(103, WXK_F11);
|
||||||
|
wxFKEY(111, WXK_F12);
|
||||||
|
wxFKEY(105, WXK_F13);
|
||||||
|
wxFKEY(107, WXK_F14);
|
||||||
|
wxFKEY(113, WXK_F15);
|
||||||
|
case 0x7e:
|
||||||
|
case 0x3e:
|
||||||
|
key = WXK_UP;
|
||||||
|
break;
|
||||||
|
case 0x7d:
|
||||||
|
case 0x3d:
|
||||||
|
key = WXK_DOWN;
|
||||||
|
break;
|
||||||
|
case 0x7b:
|
||||||
|
case 0x3b:
|
||||||
|
key = WXK_LEFT;
|
||||||
|
break;
|
||||||
|
case 0x7c:
|
||||||
|
case 0x3c:
|
||||||
|
key = WXK_RIGHT;
|
||||||
|
break;
|
||||||
|
case 0x24:
|
||||||
|
key = WXK_RETURN;
|
||||||
|
break;
|
||||||
|
case 0x30:
|
||||||
|
key = WXK_TAB;
|
||||||
|
break;
|
||||||
|
case 0x33:
|
||||||
|
key = WXK_BACK;
|
||||||
|
break;
|
||||||
|
case 0x75:
|
||||||
|
key = WXK_DELETE;
|
||||||
|
break;
|
||||||
|
case 0x73:
|
||||||
|
key = WXK_HOME;
|
||||||
|
break;
|
||||||
|
case 0x77:
|
||||||
|
key = WXK_END;
|
||||||
|
break;
|
||||||
|
case 0x74:
|
||||||
|
key = WXK_PRIOR;
|
||||||
|
break;
|
||||||
|
case 0x79:
|
||||||
|
key = WXK_NEXT;
|
||||||
|
break;
|
||||||
|
case 0x45:
|
||||||
|
key = WXK_ADD;
|
||||||
|
break;
|
||||||
|
case 78:
|
||||||
|
key = WXK_SUBTRACT;
|
||||||
|
break;
|
||||||
|
case 0x43:
|
||||||
|
key = WXK_MULTIPLY;
|
||||||
|
break;
|
||||||
|
case 0x4B:
|
||||||
|
key = WXK_DIVIDE;
|
||||||
|
break;
|
||||||
|
case 71:
|
||||||
|
key = WXK_SEPARATOR;
|
||||||
|
break;
|
||||||
|
case 65:
|
||||||
|
key = WXK_DECIMAL;
|
||||||
|
break;
|
||||||
|
case 76:
|
||||||
|
key = 3; /* numpad enter */
|
||||||
|
break;
|
||||||
|
case 82:
|
||||||
|
case 83:
|
||||||
|
case 84:
|
||||||
|
case 85:
|
||||||
|
case 86:
|
||||||
|
case 87:
|
||||||
|
case 88:
|
||||||
|
case 89:
|
||||||
|
key = WXK_NUMPAD0 + (key - 82);
|
||||||
|
break;
|
||||||
|
case 91:
|
||||||
|
key = WXK_NUMPAD8;
|
||||||
|
break;
|
||||||
|
case 92:
|
||||||
|
key = WXK_NUMPAD9;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
key = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void wxApp::doMacActivateEvt(void)
|
void wxApp::doMacActivateEvt(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -263,6 +263,12 @@ wxFrame::wxFrame // Constructor (for frame window)
|
||||||
spec[2].eventKind = kEventWindowBoundsChanging;
|
spec[2].eventKind = kEventWindowBoundsChanging;
|
||||||
InstallEventHandler(GetWindowEventTarget(theMacWindow), window_evt_handler, 3, spec, refcon, NULL);
|
InstallEventHandler(GetWindowEventTarget(theMacWindow), window_evt_handler, 3, spec, refcon, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
/* In case we need to recognize MrEd windows: */
|
||||||
|
UInt32 val = 1;
|
||||||
|
SetWindowProperty (theMacWindow, 'mReD', 'Ello', sizeof(UInt32), &val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void userPaneDrawFunction(ControlRef controlRef, SInt16 thePart)
|
static void userPaneDrawFunction(ControlRef controlRef, SInt16 thePart)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user