XQuartz: Fixed threading issue with TSM.
(cherry picked from commit 93ab4e0071670bb80bfa1170dd97ed9d6d51c67a)
This commit is contained in:
parent
ee87c9b024
commit
12a59c44cb
|
@ -56,7 +56,6 @@
|
||||||
- (void) prefs_synchronize;
|
- (void) prefs_synchronize;
|
||||||
|
|
||||||
- (OSX_BOOL) x_active;
|
- (OSX_BOOL) x_active;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
extern X11Application *X11App;
|
extern X11Application *X11App;
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
|
|
||||||
#include "darwin.h"
|
#include "darwin.h"
|
||||||
#include "darwinEvents.h"
|
#include "darwinEvents.h"
|
||||||
|
#include "quartzKeyboard.h"
|
||||||
#include "quartz.h"
|
#include "quartz.h"
|
||||||
#define _APPLEWM_SERVER_
|
#define _APPLEWM_SERVER_
|
||||||
#include "X11/extensions/applewm.h"
|
#include "X11/extensions/applewm.h"
|
||||||
|
@ -61,6 +62,8 @@
|
||||||
int X11EnableKeyEquivalents = TRUE;
|
int X11EnableKeyEquivalents = TRUE;
|
||||||
int quartzHasRoot = FALSE, quartzEnableRootless = TRUE;
|
int quartzHasRoot = FALSE, quartzEnableRootless = TRUE;
|
||||||
|
|
||||||
|
static TISInputSourceRef last_key_layout;
|
||||||
|
|
||||||
extern int darwinFakeButtons;
|
extern int darwinFakeButtons;
|
||||||
extern Bool enable_stereo;
|
extern Bool enable_stereo;
|
||||||
|
|
||||||
|
@ -163,8 +166,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) {
|
||||||
|
|
||||||
- (void) activateX:(OSX_BOOL)state {
|
- (void) activateX:(OSX_BOOL)state {
|
||||||
/* Create a TSM document that supports full Unicode input, and
|
/* Create a TSM document that supports full Unicode input, and
|
||||||
have it activated while X is active (unless using the old
|
have it activated while X is active */
|
||||||
keymapping files) */
|
|
||||||
static TSMDocumentID x11_document;
|
static TSMDocumentID x11_document;
|
||||||
DEBUG_LOG("state=%d, _x_active=%d, \n", state, _x_active)
|
DEBUG_LOG("state=%d, _x_active=%d, \n", state, _x_active)
|
||||||
if (state) {
|
if (state) {
|
||||||
|
@ -589,8 +591,8 @@ static NSMutableArray * cfarray_to_nsarray (CFArrayRef in) {
|
||||||
|
|
||||||
- (void) prefs_set_boolean:(NSString *)key value:(int)value {
|
- (void) prefs_set_boolean:(NSString *)key value:(int)value {
|
||||||
CFPreferencesSetValue ((CFStringRef) key,
|
CFPreferencesSetValue ((CFStringRef) key,
|
||||||
(CFTypeRef) value ? kCFBooleanTrue
|
(CFTypeRef) (value ? kCFBooleanTrue
|
||||||
: kCFBooleanFalse, CFSTR (APP_PREFS),
|
: kCFBooleanFalse), CFSTR (APP_PREFS),
|
||||||
kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
|
kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -847,6 +849,18 @@ void X11ApplicationMain (int argc, char **argv, char **envp) {
|
||||||
aquaMenuBarHeight = NSHeight([[NSScreen mainScreen] frame]) -
|
aquaMenuBarHeight = NSHeight([[NSScreen mainScreen] frame]) -
|
||||||
NSMaxY([[NSScreen mainScreen] visibleFrame]);
|
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 */
|
/* Tell the server thread that it can proceed */
|
||||||
QuartzInitServer(argc, argv, envp);
|
QuartzInitServer(argc, argv, envp);
|
||||||
|
|
||||||
|
@ -976,6 +990,30 @@ static void send_nsevent(NSEvent *e) {
|
||||||
break;
|
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]);
|
DarwinSendKeyboardEvents(([e type] == NSKeyDown) ? KeyPress : KeyRelease, [e keyCode]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -473,19 +473,6 @@ void DarwinSendKeyboardEvents(int ev_type, int keycode) {
|
||||||
return;
|
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(); {
|
darwinEvents_lock(); {
|
||||||
num_events = GetKeyboardEvents(darwinEvents, darwinKeyboard, ev_type, keycode + MIN_KEYCODE);
|
num_events = GetKeyboardEvents(darwinEvents, darwinKeyboard, ev_type, keycode + MIN_KEYCODE);
|
||||||
for(i=0; i<num_events; i++) mieqEnqueue(darwinKeyboard,&darwinEvents[i]);
|
for(i=0; i<num_events; i++) mieqEnqueue(darwinKeyboard,&darwinEvents[i]);
|
||||||
|
|
|
@ -52,6 +52,8 @@
|
||||||
#include "quartzKeyboard.h"
|
#include "quartzKeyboard.h"
|
||||||
#include "quartzAudio.h"
|
#include "quartzAudio.h"
|
||||||
|
|
||||||
|
#include "threadSafety.h"
|
||||||
|
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
#undef NDEBUG
|
#undef NDEBUG
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -59,6 +61,7 @@
|
||||||
#else
|
#else
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#include "xkbsrv.h"
|
#include "xkbsrv.h"
|
||||||
#include "exevents.h"
|
#include "exevents.h"
|
||||||
|
@ -304,6 +307,7 @@ const static struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
darwinKeyboardInfo keyInfo;
|
darwinKeyboardInfo keyInfo;
|
||||||
|
pthread_mutex_t keyInfo_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
static void DarwinChangeKeyboardControl( DeviceIntPtr device, KeybdCtrl *ctrl )
|
static void DarwinChangeKeyboardControl( DeviceIntPtr device, KeybdCtrl *ctrl )
|
||||||
{
|
{
|
||||||
|
@ -411,11 +415,7 @@ static void DarwinBuildModifierMaps(darwinKeyboardInfo *info) {
|
||||||
* it to an equivalent X keyboard map and modifier map.
|
* it to an equivalent X keyboard map and modifier map.
|
||||||
*/
|
*/
|
||||||
static void DarwinLoadKeyboardMapping(KeySymsRec *keySyms) {
|
static void DarwinLoadKeyboardMapping(KeySymsRec *keySyms) {
|
||||||
memset(keyInfo.keyMap, 0, sizeof(keyInfo.keyMap));
|
pthread_mutex_lock(&keyInfo_mutex);
|
||||||
|
|
||||||
if (!QuartzReadSystemKeymap(&keyInfo)) {
|
|
||||||
FatalError("Could not build a valid keymap.");
|
|
||||||
}
|
|
||||||
|
|
||||||
DarwinBuildModifierMaps(&keyInfo);
|
DarwinBuildModifierMaps(&keyInfo);
|
||||||
|
|
||||||
|
@ -423,6 +423,8 @@ static void DarwinLoadKeyboardMapping(KeySymsRec *keySyms) {
|
||||||
keySyms->mapWidth = GLYPHS_PER_KEY;
|
keySyms->mapWidth = GLYPHS_PER_KEY;
|
||||||
keySyms->minKeyCode = MIN_KEYCODE;
|
keySyms->minKeyCode = MIN_KEYCODE;
|
||||||
keySyms->maxKeyCode = MAX_KEYCODE;
|
keySyms->maxKeyCode = MAX_KEYCODE;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&keyInfo_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuartzXkbUpdate(DeviceIntPtr pDev) {
|
void QuartzXkbUpdate(DeviceIntPtr pDev) {
|
||||||
|
@ -450,27 +452,27 @@ void DarwinKeyboardInit(DeviceIntPtr pDev) {
|
||||||
assert( darwinParamConnect = NXOpenEventStatus() );
|
assert( darwinParamConnect = NXOpenEventStatus() );
|
||||||
|
|
||||||
DarwinLoadKeyboardMapping(&keySyms);
|
DarwinLoadKeyboardMapping(&keySyms);
|
||||||
/* Initialize the seed, so we don't reload the keymap unnecessarily
|
|
||||||
(and possibly overwrite xinitrc changes) */
|
|
||||||
QuartzSystemKeymapSeed();
|
|
||||||
|
|
||||||
#ifdef XQUARTZ_USE_XKB
|
#ifdef XQUARTZ_USE_XKB
|
||||||
XkbComponentNamesRec names;
|
XkbComponentNamesRec names;
|
||||||
bzero(&names, sizeof(names));
|
bzero(&names, sizeof(names));
|
||||||
/* We need to really have rules... or something... */
|
/* We need to really have rules... or something... */
|
||||||
XkbSetRulesDflts("base", "pc105", "us", NULL, NULL);
|
XkbSetRulesDflts("base", "pc105", "us", NULL, NULL);
|
||||||
|
pthread_mutex_lock(&keyInfo_mutex);
|
||||||
assert(XkbInitKeyboardDeviceStruct(pDev, &names, &keySyms, keyInfo.modMap,
|
assert(XkbInitKeyboardDeviceStruct(pDev, &names, &keySyms, keyInfo.modMap,
|
||||||
QuartzBell, DarwinChangeKeyboardControl));
|
QuartzBell, DarwinChangeKeyboardControl));
|
||||||
assert(SetKeySymsMap(&pDev->key->curKeySyms, &keySyms));
|
assert(SetKeySymsMap(&pDev->key->curKeySyms, &keySyms));
|
||||||
assert(keyInfo.modMap!=NULL);
|
assert(keyInfo.modMap!=NULL);
|
||||||
assert(pDev->key->modifierMap!=NULL);
|
assert(pDev->key->modifierMap!=NULL);
|
||||||
memcpy(pDev->key->modifierMap, keyInfo.modMap, sizeof(keyInfo.modMap));
|
memcpy(pDev->key->modifierMap, keyInfo.modMap, sizeof(keyInfo.modMap));
|
||||||
|
pthread_mutex_unlock(&keyInfo_mutex);
|
||||||
|
|
||||||
QuartzXkbUpdate(pDev);
|
QuartzXkbUpdate(pDev);
|
||||||
#else
|
#else
|
||||||
|
pthread_mutex_lock(&keyInfo_mutex);
|
||||||
assert( InitKeyboardDeviceStruct( (DevicePtr)pDev, &keySyms,
|
assert( InitKeyboardDeviceStruct( (DevicePtr)pDev, &keySyms,
|
||||||
keyInfo.modMap, QuartzBell,
|
keyInfo.modMap, QuartzBell,
|
||||||
DarwinChangeKeyboardControl ));
|
DarwinChangeKeyboardControl ));
|
||||||
|
pthread_mutex_unlock(&keyInfo_mutex);
|
||||||
SwitchCoreKeyboard(pDev);
|
SwitchCoreKeyboard(pDev);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -493,10 +495,13 @@ void DarwinKeyboardReloadHandler(int screenNum, xEventPtr xe, DeviceIntPtr pDev,
|
||||||
xfree(pDev->key);
|
xfree(pDev->key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&keyInfo_mutex);
|
||||||
if (!InitKeyClassDeviceStruct(pDev, &keySyms, keyInfo.modMap)) {
|
if (!InitKeyClassDeviceStruct(pDev, &keySyms, keyInfo.modMap)) {
|
||||||
DEBUG_LOG("InitKeyClassDeviceStruct failed\n");
|
DEBUG_LOG("InitKeyClassDeviceStruct failed\n");
|
||||||
|
pthread_mutex_unlock(&keyInfo_mutex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
pthread_mutex_unlock(&keyInfo_mutex);
|
||||||
|
|
||||||
SendMappingNotify(MappingKeyboard, MIN_KEYCODE, NUM_KEYCODES, 0);
|
SendMappingNotify(MappingKeyboard, MIN_KEYCODE, NUM_KEYCODES, 0);
|
||||||
SendMappingNotify(MappingModifier, 0, 0, 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.
|
* Returns 0 if key+side is not a known modifier.
|
||||||
*/
|
*/
|
||||||
int DarwinModifierNXKeyToNXKeycode(int key, int side) {
|
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 DarwinModifierNXKeycodeToNXKey(unsigned char keycode, int *outSide) {
|
||||||
int key, side;
|
int key, side;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&keyInfo_mutex);
|
||||||
keycode += MIN_KEYCODE;
|
keycode += MIN_KEYCODE;
|
||||||
// search modifierKeycodes for this keycode+side
|
// search modifierKeycodes for this keycode+side
|
||||||
for (key = 0; key < NX_NUMMODIFIERS; key++) {
|
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 (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;
|
if (outSide) *outSide = side;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&keyInfo_mutex);
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -666,39 +682,6 @@ Bool LegalModifier(unsigned int key, DeviceIntPtr pDev)
|
||||||
return 1;
|
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) {
|
static inline UniChar macroman2ucs(unsigned char c) {
|
||||||
/* Precalculated table mapping MacRoman-128 to Unicode. Generated
|
/* Precalculated table mapping MacRoman-128 to Unicode. Generated
|
||||||
by creating single element CFStringRefs then extracting the
|
by creating single element CFStringRefs then extracting the
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
#include "X11/keysym.h"
|
#include "X11/keysym.h"
|
||||||
#include "inputstr.h"
|
#include "inputstr.h"
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
// Each key can generate 4 glyphs. They are, in order:
|
// Each key can generate 4 glyphs. They are, in order:
|
||||||
// unshifted, shifted, modeswitch unshifted, modeswitch shifted
|
// unshifted, shifted, modeswitch unshifted, modeswitch shifted
|
||||||
#define GLYPHS_PER_KEY 4
|
#define GLYPHS_PER_KEY 4
|
||||||
|
@ -47,10 +49,10 @@ typedef struct darwinKeyboardInfo_struct {
|
||||||
|
|
||||||
/* These functions need to be implemented by Xquartz, XDarwin, etc. */
|
/* These functions need to be implemented by Xquartz, XDarwin, etc. */
|
||||||
Bool QuartzReadSystemKeymap(darwinKeyboardInfo *info);
|
Bool QuartzReadSystemKeymap(darwinKeyboardInfo *info);
|
||||||
unsigned int QuartzSystemKeymapSeed(void);
|
|
||||||
|
|
||||||
/* Provided for darwinEvents.c */
|
/* Provided for darwinEvents.c */
|
||||||
extern darwinKeyboardInfo keyInfo;
|
extern darwinKeyboardInfo keyInfo;
|
||||||
|
extern pthread_mutex_t keyInfo_mutex;
|
||||||
void DarwinKeyboardReloadHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents);
|
void DarwinKeyboardReloadHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents);
|
||||||
void DarwinKeyboardInit(DeviceIntPtr pDev);
|
void DarwinKeyboardInit(DeviceIntPtr pDev);
|
||||||
int DarwinModifierNXKeycodeToNXKey(unsigned char keycode, int *outSide);
|
int DarwinModifierNXKeycodeToNXKey(unsigned char keycode, int *outSide);
|
||||||
|
|
Loading…
Reference in New Issue