summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorJeremy Huddleston <jeremyhu@freedesktop.org>2008-09-24 22:51:03 -0700
committerJeremy Huddleston <jeremyhu@freedesktop.org>2008-09-26 12:31:21 -0700
commit12a59c44cb68843a60fc43257930d1cbeb971b7a (patch)
treeb27f4c93a99cd669605aa93ffdfea0f8ea705b16 /hw
parentee87c9b02401a7a08b396884ba412a503b078bbd (diff)
XQuartz: Fixed threading issue with TSM.
(cherry picked from commit 93ab4e0071670bb80bfa1170dd97ed9d6d51c67a)
Diffstat (limited to 'hw')
-rw-r--r--hw/xquartz/X11Application.h1
-rw-r--r--hw/xquartz/X11Application.m78
-rw-r--r--hw/xquartz/darwinEvents.c13
-rw-r--r--hw/xquartz/quartzKeyboard.c75
-rw-r--r--hw/xquartz/quartzKeyboard.h4
5 files changed, 90 insertions, 81 deletions
diff --git a/hw/xquartz/X11Application.h b/hw/xquartz/X11Application.h
index ce3fa7bda..0caaba83f 100644
--- a/hw/xquartz/X11Application.h
+++ b/hw/xquartz/X11Application.h
@@ -56,7 +56,6 @@
- (void) prefs_synchronize;
- (OSX_BOOL) x_active;
-
@end
extern X11Application *X11App;
diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m
index 213d9ed1d..0436db8f9 100644
--- a/hw/xquartz/X11Application.m
+++ b/hw/xquartz/X11Application.m
@@ -39,6 +39,7 @@
#include "darwin.h"
#include "darwinEvents.h"
+#include "quartzKeyboard.h"
#include "quartz.h"
#define _APPLEWM_SERVER_
#include "X11/extensions/applewm.h"
@@ -61,6 +62,8 @@
int X11EnableKeyEquivalents = TRUE;
int quartzHasRoot = FALSE, quartzEnableRootless = TRUE;
+static TISInputSourceRef last_key_layout;
+
extern int darwinFakeButtons;
extern Bool enable_stereo;
@@ -163,8 +166,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) {
- (void) activateX:(OSX_BOOL)state {
/* Create a TSM document that supports full Unicode input, and
- have it activated while X is active (unless using the old
- keymapping files) */
+ have it activated while X is active */
static TSMDocumentID x11_document;
DEBUG_LOG("state=%d, _x_active=%d, \n", state, _x_active)
if (state) {
@@ -589,8 +591,8 @@ static NSMutableArray * cfarray_to_nsarray (CFArrayRef in) {
- (void) prefs_set_boolean:(NSString *)key value:(int)value {
CFPreferencesSetValue ((CFStringRef) key,
- (CFTypeRef) value ? kCFBooleanTrue
- : kCFBooleanFalse, CFSTR (APP_PREFS),
+ (CFTypeRef) (value ? kCFBooleanTrue
+ : kCFBooleanFalse), CFSTR (APP_PREFS),
kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
}
@@ -847,9 +849,21 @@ void X11ApplicationMain (int argc, char **argv, char **envp) {
aquaMenuBarHeight = NSHeight([[NSScreen mainScreen] frame]) -
NSMaxY([[NSScreen mainScreen] visibleFrame]);
+ /* Set the key layout seed before we start the server */
+ last_key_layout = TISCopyCurrentKeyboardLayoutInputSource();
+
+ if(!last_key_layout) {
+ fprintf(stderr, "X11ApplicationMain: Unable to determine TISCopyCurrentKeyboardLayoutInputSource() at startup.\n");
+ }
+
+ memset(keyInfo.keyMap, 0, sizeof(keyInfo.keyMap));
+ if (!QuartzReadSystemKeymap(&keyInfo)) {
+ fprintf(stderr, "X11ApplicationMain: Could not build a valid keymap.\n");
+ }
+
/* Tell the server thread that it can proceed */
QuartzInitServer(argc, argv, envp);
-
+
[NSApp run];
/* not reached */
}
@@ -880,12 +894,12 @@ static void send_nsevent(NSEvent *e) {
NSWindow *window;
int pointer_x, pointer_y, ev_button, ev_type;
float pressure, tilt_x, tilt_y;
-
+
/* convert location to be relative to top-left of primary display */
location = [e locationInWindow];
window = [e window];
screen = [[[NSScreen screens] objectAtIndex:0] frame];
-
+
if (window != nil) {
NSRect frame = [window frame];
pointer_x = location.x + frame.origin.x;
@@ -895,18 +909,18 @@ static void send_nsevent(NSEvent *e) {
pointer_x = location.x;
pointer_y = (screen.origin.y + screen.size.height) - location.y;
}
-
+
pressure = 0; // for tablets
tilt_x = 0;
tilt_y = 0;
-
+
/* We don't receive modifier key events while out of focus, and 3button
* emulation mucks this up, so we need to check our modifier flag state
* on every event... ugg
*/
if(darwin_modifier_flags != [e modifierFlags])
DarwinUpdateModKeys([e modifierFlags]);
-
+
switch ([e type]) {
case NSLeftMouseDown: ev_button=1; ev_type=ButtonPress; goto handle_mouse;
case NSOtherMouseDown: ev_button=2; ev_type=ButtonPress; goto handle_mouse;
@@ -919,7 +933,7 @@ static void send_nsevent(NSEvent *e) {
case NSRightMouseDragged: ev_button=3; ev_type=MotionNotify; goto handle_mouse;
case NSMouseMoved: ev_button=0; ev_type=MotionNotify; goto handle_mouse;
case NSTabletPoint: ev_button=0; ev_type=MotionNotify; goto handle_mouse;
-
+
handle_mouse:
if ([e type] == NSTabletPoint || [e subtype] == NSTabletPointEventSubtype) {
pressure = [e pressure];
@@ -941,16 +955,16 @@ static void send_nsevent(NSEvent *e) {
darwinTabletCurrent=darwinTabletCursor;
break;
}
-
+
DarwinSendProximityEvents([e isEnteringProximity]?ProximityIn:ProximityOut,
pointer_x, pointer_y);
}
-
+
DarwinSendPointerEvents(ev_type, ev_button, pointer_x, pointer_y,
pressure, tilt_x, tilt_y);
-
+
break;
-
+
case NSTabletProximity:
switch([e pointingDeviceType]) {
case NSEraserPointingDevice:
@@ -965,20 +979,44 @@ static void send_nsevent(NSEvent *e) {
darwinTabletCurrent=darwinTabletCursor;
break;
}
-
+
DarwinSendProximityEvents([e isEnteringProximity]?ProximityIn:ProximityOut,
pointer_x, pointer_y);
break;
-
+
case NSScrollWheel:
DarwinSendScrollEvents([e deltaX], [e deltaY], pointer_x, pointer_y,
pressure, tilt_x, tilt_y);
break;
-
- case NSKeyDown: case NSKeyUp:
+
+ case NSKeyDown: case NSKeyUp:
+ if(darwinSyncKeymap) {
+ TISInputSourceRef key_layout = TISCopyCurrentKeyboardLayoutInputSource();
+ TISInputSourceRef clear;
+ if (CFEqual(key_layout, last_key_layout)) {
+ CFRelease(key_layout);
+ } else {
+ /* Swap/free thread-safely */
+ clear = last_key_layout;
+ last_key_layout = key_layout;
+ CFRelease(clear);
+
+ /* Update keyInfo */
+ pthread_mutex_lock(&keyInfo_mutex);
+ memset(keyInfo.keyMap, 0, sizeof(keyInfo.keyMap));
+ if (!QuartzReadSystemKeymap(&keyInfo)) {
+ fprintf(stderr, "sendX11NSEvent: Could not build a valid keymap.\n");
+ }
+ pthread_mutex_unlock(&keyInfo_mutex);
+
+ /* Tell server thread to deal with new keyInfo */
+ DarwinSendDDXEvent(kXquartzReloadKeymap, 0);
+ }
+ }
+
DarwinSendKeyboardEvents(([e type] == NSKeyDown) ? KeyPress : KeyRelease, [e keyCode]);
break;
-
+
default: break; /* for gcc */
}
}
diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c
index 1db61d9e4..729cc9a4d 100644
--- a/hw/xquartz/darwinEvents.c
+++ b/hw/xquartz/darwinEvents.c
@@ -473,19 +473,6 @@ void DarwinSendKeyboardEvents(int ev_type, int keycode) {
return;
}
- if (darwinSyncKeymap) {
- /* See if keymap has changed. */
-
- static unsigned int last_seed;
- unsigned int this_seed;
-
- this_seed = QuartzSystemKeymapSeed();
- if (this_seed != last_seed) {
- last_seed = this_seed;
- DarwinSendDDXEvent(kXquartzReloadKeymap, 0);
- }
- }
-
darwinEvents_lock(); {
num_events = GetKeyboardEvents(darwinEvents, darwinKeyboard, ev_type, keycode + MIN_KEYCODE);
for(i=0; i<num_events; i++) mieqEnqueue(darwinKeyboard,&darwinEvents[i]);
diff --git a/hw/xquartz/quartzKeyboard.c b/hw/xquartz/quartzKeyboard.c
index cee582bbe..cd46fb2d9 100644
--- a/hw/xquartz/quartzKeyboard.c
+++ b/hw/xquartz/quartzKeyboard.c
@@ -52,6 +52,8 @@
#include "quartzKeyboard.h"
#include "quartzAudio.h"
+#include "threadSafety.h"
+
#ifdef NDEBUG
#undef NDEBUG
#include <assert.h>
@@ -59,6 +61,7 @@
#else
#include <assert.h>
#endif
+#include <pthread.h>
#include "xkbsrv.h"
#include "exevents.h"
@@ -304,6 +307,7 @@ const static struct {
};
darwinKeyboardInfo keyInfo;
+pthread_mutex_t keyInfo_mutex = PTHREAD_MUTEX_INITIALIZER;
static void DarwinChangeKeyboardControl( DeviceIntPtr device, KeybdCtrl *ctrl )
{
@@ -411,18 +415,16 @@ static void DarwinBuildModifierMaps(darwinKeyboardInfo *info) {
* it to an equivalent X keyboard map and modifier map.
*/
static void DarwinLoadKeyboardMapping(KeySymsRec *keySyms) {
- memset(keyInfo.keyMap, 0, sizeof(keyInfo.keyMap));
-
- if (!QuartzReadSystemKeymap(&keyInfo)) {
- FatalError("Could not build a valid keymap.");
- }
-
+ pthread_mutex_lock(&keyInfo_mutex);
+
DarwinBuildModifierMaps(&keyInfo);
keySyms->map = keyInfo.keyMap;
keySyms->mapWidth = GLYPHS_PER_KEY;
keySyms->minKeyCode = MIN_KEYCODE;
keySyms->maxKeyCode = MAX_KEYCODE;
+
+ pthread_mutex_unlock(&keyInfo_mutex);
}
void QuartzXkbUpdate(DeviceIntPtr pDev) {
@@ -450,27 +452,27 @@ void DarwinKeyboardInit(DeviceIntPtr pDev) {
assert( darwinParamConnect = NXOpenEventStatus() );
DarwinLoadKeyboardMapping(&keySyms);
- /* Initialize the seed, so we don't reload the keymap unnecessarily
- (and possibly overwrite xinitrc changes) */
- QuartzSystemKeymapSeed();
-
#ifdef XQUARTZ_USE_XKB
XkbComponentNamesRec names;
bzero(&names, sizeof(names));
/* We need to really have rules... or something... */
XkbSetRulesDflts("base", "pc105", "us", NULL, NULL);
+ pthread_mutex_lock(&keyInfo_mutex);
assert(XkbInitKeyboardDeviceStruct(pDev, &names, &keySyms, keyInfo.modMap,
QuartzBell, DarwinChangeKeyboardControl));
assert(SetKeySymsMap(&pDev->key->curKeySyms, &keySyms));
assert(keyInfo.modMap!=NULL);
assert(pDev->key->modifierMap!=NULL);
memcpy(pDev->key->modifierMap, keyInfo.modMap, sizeof(keyInfo.modMap));
+ pthread_mutex_unlock(&keyInfo_mutex);
QuartzXkbUpdate(pDev);
#else
+ pthread_mutex_lock(&keyInfo_mutex);
assert( InitKeyboardDeviceStruct( (DevicePtr)pDev, &keySyms,
keyInfo.modMap, QuartzBell,
DarwinChangeKeyboardControl ));
+ pthread_mutex_unlock(&keyInfo_mutex);
SwitchCoreKeyboard(pDev);
#endif
}
@@ -492,11 +494,14 @@ void DarwinKeyboardReloadHandler(int screenNum, xEventPtr xe, DeviceIntPtr pDev,
if (pDev->key->modifierKeyMap) xfree(pDev->key->modifierKeyMap);
xfree(pDev->key);
}
-
+
+ pthread_mutex_lock(&keyInfo_mutex);
if (!InitKeyClassDeviceStruct(pDev, &keySyms, keyInfo.modMap)) {
DEBUG_LOG("InitKeyClassDeviceStruct failed\n");
+ pthread_mutex_unlock(&keyInfo_mutex);
return;
}
+ pthread_mutex_unlock(&keyInfo_mutex);
SendMappingNotify(MappingKeyboard, MIN_KEYCODE, NUM_KEYCODES, 0);
SendMappingNotify(MappingModifier, 0, 0, 0);
@@ -521,7 +526,12 @@ void DarwinKeyboardReloadHandler(int screenNum, xEventPtr xe, DeviceIntPtr pDev,
* Returns 0 if key+side is not a known modifier.
*/
int DarwinModifierNXKeyToNXKeycode(int key, int side) {
- return keyInfo.modifierKeycodes[key][side];
+ int retval;
+ pthread_mutex_lock(&keyInfo_mutex);
+ retval = keyInfo.modifierKeycodes[key][side];
+ pthread_mutex_unlock(&keyInfo_mutex);
+
+ return retval;
}
/*
@@ -532,6 +542,7 @@ int DarwinModifierNXKeyToNXKeycode(int key, int side) {
int DarwinModifierNXKeycodeToNXKey(unsigned char keycode, int *outSide) {
int key, side;
+ pthread_mutex_lock(&keyInfo_mutex);
keycode += MIN_KEYCODE;
// search modifierKeycodes for this keycode+side
for (key = 0; key < NX_NUMMODIFIERS; key++) {
@@ -539,8 +550,13 @@ int DarwinModifierNXKeycodeToNXKey(unsigned char keycode, int *outSide) {
if (keyInfo.modifierKeycodes[key][side] == keycode) break;
}
}
- if (key == NX_NUMMODIFIERS) return -1;
+ if (key == NX_NUMMODIFIERS) {
+ pthread_mutex_unlock(&keyInfo_mutex);
+ return -1;
+ }
if (outSide) *outSide = side;
+
+ pthread_mutex_unlock(&keyInfo_mutex);
return key;
}
@@ -666,39 +682,6 @@ Bool LegalModifier(unsigned int key, DeviceIntPtr pDev)
return 1;
}
-/* TODO: Not thread safe */
-unsigned int QuartzSystemKeymapSeed(void) {
- static unsigned int seed = 0;
-//#if defined(__x86_64__) || defined(__ppc64__)
-#if 1
- static TISInputSourceRef last_key_layout = NULL;
- TISInputSourceRef key_layout;
-
- key_layout = TISCopyCurrentKeyboardLayoutInputSource();
-
- if(last_key_layout) {
- if (CFEqual(key_layout, last_key_layout)) {
- CFRelease(key_layout);
- } else {
- seed++;
- CFRelease(last_key_layout);
- last_key_layout = key_layout;
- }
- } else {
- last_key_layout = key_layout;
- }
-#else
- static KeyboardLayoutRef last_key_layout;
- KeyboardLayoutRef key_layout;
-
- KLGetCurrentKeyboardLayout (&key_layout);
- if (key_layout != last_key_layout)
- seed++;
- last_key_layout = key_layout;
-#endif
- return seed;
-}
-
static inline UniChar macroman2ucs(unsigned char c) {
/* Precalculated table mapping MacRoman-128 to Unicode. Generated
by creating single element CFStringRefs then extracting the
diff --git a/hw/xquartz/quartzKeyboard.h b/hw/xquartz/quartzKeyboard.h
index d62a79d8e..eb7936662 100644
--- a/hw/xquartz/quartzKeyboard.h
+++ b/hw/xquartz/quartzKeyboard.h
@@ -32,6 +32,8 @@
#include "X11/keysym.h"
#include "inputstr.h"
+#include <pthread.h>
+
// Each key can generate 4 glyphs. They are, in order:
// unshifted, shifted, modeswitch unshifted, modeswitch shifted
#define GLYPHS_PER_KEY 4
@@ -47,10 +49,10 @@ typedef struct darwinKeyboardInfo_struct {
/* These functions need to be implemented by Xquartz, XDarwin, etc. */
Bool QuartzReadSystemKeymap(darwinKeyboardInfo *info);
-unsigned int QuartzSystemKeymapSeed(void);
/* Provided for darwinEvents.c */
extern darwinKeyboardInfo keyInfo;
+extern pthread_mutex_t keyInfo_mutex;
void DarwinKeyboardReloadHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents);
void DarwinKeyboardInit(DeviceIntPtr pDev);
int DarwinModifierNXKeycodeToNXKey(unsigned char keycode, int *outSide);