Ken Thomases : winemac: Rebuild key map when Mac keyboard layout changes.
Alexandre Julliard
julliard at winehq.org
Tue Feb 5 13:25:25 CST 2013
Module: wine
Branch: master
Commit: d0e1a0251583d5fb9ea199268d670b8f81b72abc
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d0e1a0251583d5fb9ea199268d670b8f81b72abc
Author: Ken Thomases <ken at codeweavers.com>
Date: Sun Feb 3 17:20:15 2013 -0600
winemac: Rebuild key map when Mac keyboard layout changes.
---
dlls/winemac.drv/cocoa_app.m | 50 +++++++++++++++++++++++++++++++++++++++
dlls/winemac.drv/cocoa_event.m | 3 ++
dlls/winemac.drv/event.c | 7 +++++
dlls/winemac.drv/keyboard.c | 22 +++++++++++++++++
dlls/winemac.drv/macdrv.h | 1 +
dlls/winemac.drv/macdrv_cocoa.h | 6 ++++
6 files changed, 89 insertions(+), 0 deletions(-)
diff --git a/dlls/winemac.drv/cocoa_app.m b/dlls/winemac.drv/cocoa_app.m
index 3751eef..a3a8cb5 100644
--- a/dlls/winemac.drv/cocoa_app.m
+++ b/dlls/winemac.drv/cocoa_app.m
@@ -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 ----------
@@ -218,6 +259,15 @@ int macdrv_err_on;
[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();
}
diff --git a/dlls/winemac.drv/cocoa_event.m b/dlls/winemac.drv/cocoa_event.m
index d5e927d..98b4445 100644
--- a/dlls/winemac.drv/cocoa_event.m
+++ b/dlls/winemac.drv/cocoa_event.m
@@ -277,6 +277,9 @@ void macdrv_cleanup_event(macdrv_event *event)
switch (event->type)
{
+ case KEYBOARD_CHANGED:
+ CFRelease(event->keyboard_changed.uchr);
+ break;
case WINDOW_GOT_FOCUS:
[(NSMutableSet*)event->window_got_focus.tried_windows release];
break;
diff --git a/dlls/winemac.drv/event.c b/dlls/winemac.drv/event.c
index 616f398..fb00260 100644
--- a/dlls/winemac.drv/event.c
+++ b/dlls/winemac.drv/event.c
@@ -33,6 +33,7 @@ static const char *dbgstr_event(int type)
{
static const char * const event_names[] = {
"APP_DEACTIVATED",
+ "KEYBOARD_CHANGED",
"MOUSE_BUTTON",
"WINDOW_CLOSE_REQUESTED",
"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_KEY)
+ event_mask |= event_mask_for_type(KEYBOARD_CHANGED);
+
if (mask & QS_MOUSEBUTTON)
event_mask |= event_mask_for_type(MOUSE_BUTTON);
@@ -94,6 +98,9 @@ void macdrv_handle_event(macdrv_event *event)
case APP_DEACTIVATED:
macdrv_app_deactivated();
break;
+ case KEYBOARD_CHANGED:
+ macdrv_keyboard_changed(event);
+ break;
case MOUSE_BUTTON:
macdrv_mouse_button(hwnd, event);
break;
diff --git a/dlls/winemac.drv/keyboard.c b/dlls/winemac.drv/keyboard.c
index d81cdd2..3591521 100644
--- a/dlls/winemac.drv/keyboard.c
+++ b/dlls/winemac.drv/keyboard.c
@@ -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);
}
}
+
+
+/***********************************************************************
+ * 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);
+}
diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h
index 6b50b3d..d30c7ae 100644
--- a/dlls/winemac.drv/macdrv.h
+++ b/dlls/winemac.drv/macdrv.h
@@ -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_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 */
diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h
index 61dae50..d49992f 100644
--- a/dlls/winemac.drv/macdrv_cocoa.h
+++ b/dlls/winemac.drv/macdrv_cocoa.h
@@ -125,6 +125,7 @@ extern void macdrv_free_displays(struct macdrv_display* displays) DECLSPEC_HIDDE
/* event */
enum {
APP_DEACTIVATED,
+ KEYBOARD_CHANGED,
MOUSE_BUTTON,
WINDOW_CLOSE_REQUESTED,
WINDOW_DID_MINIMIZE,
@@ -142,6 +143,11 @@ typedef struct macdrv_event {
macdrv_window window;
union {
struct {
+ CFDataRef uchr;
+ CGEventSourceKeyboardType keyboard_type;
+ int iso_keyboard;
+ } keyboard_changed;
+ struct {
int button;
int pressed;
int x;
More information about the wine-cvs
mailing list