winemac: Rebuild key map when Mac keyboard layout changes.

This commit is contained in:
Ken Thomases 2013-02-03 17:20:15 -06:00 committed by Alexandre Julliard
parent b78eee3172
commit d0e1a02515
6 changed files with 89 additions and 0 deletions

View File

@ -177,6 +177,47 @@ int macdrv_err_on;
} }
} }
- (void) keyboardSelectionDidChange
{
TISInputSourceRef inputSource;
inputSource = TISCopyCurrentKeyboardLayoutInputSource();
if (inputSource)
{
CFDataRef uchr;
uchr = TISGetInputSourceProperty(inputSource,
kTISPropertyUnicodeKeyLayoutData);
if (uchr)
{
macdrv_event event;
WineEventQueue* queue;
event.type = KEYBOARD_CHANGED;
event.window = NULL;
event.keyboard_changed.keyboard_type = self.keyboardType;
event.keyboard_changed.iso_keyboard = (KBGetLayoutType(self.keyboardType) == kKeyboardISO);
event.keyboard_changed.uchr = CFDataCreateCopy(NULL, uchr);
if (event.keyboard_changed.uchr)
{
[eventQueuesLock lock];
for (queue in eventQueues)
{
CFRetain(event.keyboard_changed.uchr);
[queue postEvent:&event];
}
[eventQueuesLock unlock];
CFRelease(event.keyboard_changed.uchr);
}
}
CFRelease(inputSource);
}
}
/* /*
* ---------- NSApplicationDelegate methods ---------- * ---------- NSApplicationDelegate methods ----------
@ -218,6 +259,15 @@ int macdrv_err_on;
[keyWindows removeObjectIdenticalTo:window]; [keyWindows removeObjectIdenticalTo:window];
}]; }];
[nc addObserver:self
selector:@selector(keyboardSelectionDidChange)
name:NSTextInputContextKeyboardSelectionDidChangeNotification
object:nil];
/* The above notification isn't sent unless the NSTextInputContext
class has initialized itself. Poke it. */
[NSTextInputContext self];
self.keyboardType = LMGetKbdType(); self.keyboardType = LMGetKbdType();
} }

View File

@ -277,6 +277,9 @@ void macdrv_cleanup_event(macdrv_event *event)
switch (event->type) switch (event->type)
{ {
case KEYBOARD_CHANGED:
CFRelease(event->keyboard_changed.uchr);
break;
case WINDOW_GOT_FOCUS: case WINDOW_GOT_FOCUS:
[(NSMutableSet*)event->window_got_focus.tried_windows release]; [(NSMutableSet*)event->window_got_focus.tried_windows release];
break; break;

View File

@ -33,6 +33,7 @@ static const char *dbgstr_event(int type)
{ {
static const char * const event_names[] = { static const char * const event_names[] = {
"APP_DEACTIVATED", "APP_DEACTIVATED",
"KEYBOARD_CHANGED",
"MOUSE_BUTTON", "MOUSE_BUTTON",
"WINDOW_CLOSE_REQUESTED", "WINDOW_CLOSE_REQUESTED",
"WINDOW_DID_MINIMIZE", "WINDOW_DID_MINIMIZE",
@ -56,6 +57,9 @@ static macdrv_event_mask get_event_mask(DWORD mask)
if ((mask & QS_ALLINPUT) == QS_ALLINPUT) return -1; if ((mask & QS_ALLINPUT) == QS_ALLINPUT) return -1;
if (mask & QS_KEY)
event_mask |= event_mask_for_type(KEYBOARD_CHANGED);
if (mask & QS_MOUSEBUTTON) if (mask & QS_MOUSEBUTTON)
event_mask |= event_mask_for_type(MOUSE_BUTTON); event_mask |= event_mask_for_type(MOUSE_BUTTON);
@ -94,6 +98,9 @@ void macdrv_handle_event(macdrv_event *event)
case APP_DEACTIVATED: case APP_DEACTIVATED:
macdrv_app_deactivated(); macdrv_app_deactivated();
break; break;
case KEYBOARD_CHANGED:
macdrv_keyboard_changed(event);
break;
case MOUSE_BUTTON: case MOUSE_BUTTON:
macdrv_mouse_button(hwnd, event); macdrv_mouse_button(hwnd, event);
break; break;

View File

@ -661,3 +661,25 @@ void macdrv_compute_keyboard_layout(struct macdrv_thread_data *thread_data)
TRACE("keyc 0x%04x -> vkey 0x%04x (spare vkey)\n", keyc, vkey); TRACE("keyc 0x%04x -> vkey 0x%04x (spare vkey)\n", keyc, vkey);
} }
} }
/***********************************************************************
* macdrv_keyboard_changed
*
* Handler for KEYBOARD_CHANGED events.
*/
void macdrv_keyboard_changed(const macdrv_event *event)
{
struct macdrv_thread_data *thread_data = macdrv_thread_data();
TRACE("new keyboard layout uchr data %p, type %u, iso %d\n", event->keyboard_changed.uchr,
event->keyboard_changed.keyboard_type, event->keyboard_changed.iso_keyboard);
if (thread_data->keyboard_layout_uchr)
CFRelease(thread_data->keyboard_layout_uchr);
thread_data->keyboard_layout_uchr = CFDataCreateCopy(NULL, event->keyboard_changed.uchr);
thread_data->keyboard_type = event->keyboard_changed.keyboard_type;
thread_data->iso_keyboard = event->keyboard_changed.iso_keyboard;
macdrv_compute_keyboard_layout(thread_data);
}

View File

@ -134,5 +134,6 @@ extern void macdrv_window_did_unminimize(HWND hwnd) DECLSPEC_HIDDEN;
extern void macdrv_mouse_button(HWND hwnd, const macdrv_event *event) DECLSPEC_HIDDEN; extern void macdrv_mouse_button(HWND hwnd, const macdrv_event *event) DECLSPEC_HIDDEN;
extern void macdrv_compute_keyboard_layout(struct macdrv_thread_data *thread_data) DECLSPEC_HIDDEN; extern void macdrv_compute_keyboard_layout(struct macdrv_thread_data *thread_data) DECLSPEC_HIDDEN;
extern void macdrv_keyboard_changed(const macdrv_event *event) DECLSPEC_HIDDEN;
#endif /* __WINE_MACDRV_H */ #endif /* __WINE_MACDRV_H */

View File

@ -125,6 +125,7 @@ extern void macdrv_free_displays(struct macdrv_display* displays) DECLSPEC_HIDDE
/* event */ /* event */
enum { enum {
APP_DEACTIVATED, APP_DEACTIVATED,
KEYBOARD_CHANGED,
MOUSE_BUTTON, MOUSE_BUTTON,
WINDOW_CLOSE_REQUESTED, WINDOW_CLOSE_REQUESTED,
WINDOW_DID_MINIMIZE, WINDOW_DID_MINIMIZE,
@ -141,6 +142,11 @@ typedef struct macdrv_event {
int type; int type;
macdrv_window window; macdrv_window window;
union { union {
struct {
CFDataRef uchr;
CGEventSourceKeyboardType keyboard_type;
int iso_keyboard;
} keyboard_changed;
struct { struct {
int button; int button;
int pressed; int pressed;