mirror of
https://github.com/X11Libre/xserver.git
synced 2026-10-28 02:21:08 +00:00
xquartz: add non-dispatch fallbacks for 10.5
Based on https://github.com/XQuartz/xorg-server/blob/server-1.20-legacy
This commit is contained in:
parent
bbdcb306d2
commit
0946eb14c5
7 changed files with 132 additions and 11 deletions
|
|
@ -6,8 +6,14 @@
|
|||
// Copyright (c) 2021 Apple Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NSUserDefaults+XQuartzDefaults.h"
|
||||
#import <dispatch/dispatch.h>
|
||||
#include "NSUserDefaults+XQuartzDefaults.h"
|
||||
#include "osxcompat.h"
|
||||
|
||||
#ifdef HAS_LIBDISPATCH
|
||||
#include <dispatch/dispatch.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
NSString * const XQuartzPrefKeyAppsMenu = @"apps_menu";
|
||||
NSString * const XQuartzPrefKeyFakeButtons = @"enable_fake_buttons";
|
||||
|
|
@ -128,32 +134,50 @@ xquartzDefaultsOnce(void *arg)
|
|||
[*defaults registerDefaults:systemDefaultsDict];
|
||||
}
|
||||
|
||||
#ifdef HAS_LIBDISPATCH
|
||||
typedef dispatch_once_t compat_once_t;
|
||||
#define COMPAT_ONCE_INIT 0
|
||||
#define compat_once_f dispatch_once_f
|
||||
#else
|
||||
typedef pthread_once_t compat_once_t;
|
||||
#define COMPAT_ONCE_INIT PTHREAD_ONCE_INIT
|
||||
static inline void compat_once_f(compat_once_t *once, void *context, void (*func)(void *)) {
|
||||
// pthread_once only takes a void(*)(void), so wrap context in a static
|
||||
static void *compat_context;
|
||||
static void (*compat_func)(void *);
|
||||
compat_context = context;
|
||||
compat_func = func;
|
||||
void wrapper(void) { compat_func(compat_context); }
|
||||
pthread_once(once, wrapper);
|
||||
}
|
||||
#endif
|
||||
|
||||
@implementation NSUserDefaults (XQuartzDefaults)
|
||||
|
||||
+ (NSUserDefaults *)globalDefaults
|
||||
{
|
||||
static dispatch_once_t once;
|
||||
static compat_once_t once = COMPAT_ONCE_INIT;
|
||||
static NSUserDefaults *defaults;
|
||||
|
||||
dispatch_once_f(&once, &defaults, globalDefaultsOnce);
|
||||
compat_once_f(&once, &defaults, globalDefaultsOnce);
|
||||
return defaults;
|
||||
}
|
||||
|
||||
+ (NSUserDefaults *)dockDefaults
|
||||
{
|
||||
static dispatch_once_t once;
|
||||
static compat_once_t once = COMPAT_ONCE_INIT;
|
||||
static NSUserDefaults *defaults;
|
||||
|
||||
dispatch_once_f(&once, &defaults, dockDefaultsOnce);
|
||||
compat_once_f(&once, &defaults, dockDefaultsOnce);
|
||||
return defaults;
|
||||
}
|
||||
|
||||
+ (NSUserDefaults *)xquartzDefaults
|
||||
{
|
||||
static dispatch_once_t once;
|
||||
static compat_once_t once = COMPAT_ONCE_INIT;
|
||||
static NSUserDefaults *defaults;
|
||||
|
||||
dispatch_once_f(&once, &defaults, xquartzDefaultsOnce);
|
||||
compat_once_f(&once, &defaults, xquartzDefaultsOnce);
|
||||
return defaults;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,9 +61,14 @@ xpbproxy_run(void);
|
|||
#define XSERVER_VERSION "?"
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LIBDISPATCH
|
||||
#include <dispatch/dispatch.h>
|
||||
|
||||
static dispatch_queue_t eventTranslationQueue;
|
||||
#else
|
||||
// aquaMenuBarHeight is just a proxy for initialization
|
||||
#define eventTranslationQueue aquaMenuBarHeight
|
||||
#endif
|
||||
|
||||
#ifndef __has_feature
|
||||
#define __has_feature(x) 0
|
||||
|
|
@ -483,8 +488,12 @@ sendX11NSEvent_fptr(void *e_ptr)
|
|||
}
|
||||
|
||||
if (for_x) {
|
||||
#ifdef HAS_LIBDISPATCH
|
||||
NSEvent *event_copy = [e retain];
|
||||
dispatch_async_f(eventTranslationQueue, event_copy, sendX11NSEvent_fptr);
|
||||
#else
|
||||
[self sendX11NSEvent:e];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -842,13 +851,20 @@ X11ApplicationMain(int argc, char **argv, char **envp)
|
|||
|
||||
/* Calculate the height of the menubar so we can avoid it. */
|
||||
aquaMenuBarHeight = [[NSApp mainMenu] menuBarHeight];
|
||||
#if ! __LP64__
|
||||
if (!aquaMenuBarHeight) {
|
||||
aquaMenuBarHeight = [NSMenuView menuBarHeight];
|
||||
}
|
||||
#endif
|
||||
if (!aquaMenuBarHeight) {
|
||||
NSScreen* primaryScreen = [[NSScreen screens] objectAtIndex:0];
|
||||
aquaMenuBarHeight = NSHeight(primaryScreen.frame) - NSMaxY(primaryScreen.visibleFrame);
|
||||
}
|
||||
|
||||
#ifdef HAS_LIBDISPATCH
|
||||
eventTranslationQueue = dispatch_queue_create(BUNDLE_ID_PREFIX ".X11.NSEventsToX11EventsQueue", NULL);
|
||||
assert(eventTranslationQueue != NULL);
|
||||
#endif
|
||||
|
||||
/* Set the key layout seed before we start the server */
|
||||
last_key_layout = TISCopyCurrentKeyboardLayoutInputSource();
|
||||
|
|
|
|||
|
|
@ -57,7 +57,9 @@
|
|||
#include "mach_startupServer.h"
|
||||
#include "osxcompat.h"
|
||||
|
||||
#ifdef HAS_LIBDISPATCH
|
||||
#include <dispatch/dispatch.h>
|
||||
#endif
|
||||
|
||||
#include <asl.h>
|
||||
|
||||
|
|
@ -116,6 +118,23 @@ static char *pref_app_to_run;
|
|||
static char *pref_login_shell;
|
||||
static char *pref_startx_script;
|
||||
|
||||
#ifndef HAS_LIBDISPATCH
|
||||
/*** Pthread Magics ***/
|
||||
static pthread_t
|
||||
create_thread(void *(*func)(void *), void *arg)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
pthread_t tid;
|
||||
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
pthread_create(&tid, &attr, func, arg);
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
return tid;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*** Mach-O IPC Stuffs ***/
|
||||
|
||||
|
|
@ -223,9 +242,16 @@ typedef struct {
|
|||
/* This thread accepts an incoming connection and hands off the file
|
||||
* descriptor for the new connection to accept_fd_handoff()
|
||||
*/
|
||||
#ifdef HAS_LIBDISPATCH
|
||||
static void
|
||||
socket_handoff(socket_handoff_t *handoff_data)
|
||||
{
|
||||
#else
|
||||
static void *
|
||||
socket_handoff_thread(void *arg)
|
||||
{
|
||||
socket_handoff_t *handoff_data = (socket_handoff_t *)arg;
|
||||
#endif
|
||||
|
||||
int launchd_fd = -1;
|
||||
int connected_fd;
|
||||
|
|
@ -260,6 +286,9 @@ socket_handoff(socket_handoff_t *handoff_data)
|
|||
launchd_fd);
|
||||
DarwinListenOnOpenFD(launchd_fd);
|
||||
|
||||
#ifndef HAS_LIBDISPATCH
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -347,9 +376,13 @@ do_request_fd_handoff_socket(mach_port_t port, string_t filename)
|
|||
|
||||
strlcpy(filename, handoff_data->filename, STRING_T_SIZE);
|
||||
|
||||
#ifdef HAS_LIBDISPATCH
|
||||
dispatch_async_f(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
|
||||
handoff_data,
|
||||
socketHandoff_fptr);
|
||||
#else
|
||||
create_thread(socket_handoff_thread, handoff_data);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
ErrorF(
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ libxquartz_defs = [
|
|||
]
|
||||
|
||||
if cc.has_function('dispatch_async')
|
||||
libxquartz_defs += '-DHAVE_LIBDISPATCH'
|
||||
libxquartz_defs += '-DHAS_LIBDISPATCH'
|
||||
endif
|
||||
|
||||
libXquartz = static_library('Xquartz',
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@
|
|||
#include "exevents.h"
|
||||
#include "X11/keysym.h"
|
||||
#include "keysym2ucs.h"
|
||||
#include "osxcompat.h"
|
||||
|
||||
extern void
|
||||
CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master);
|
||||
|
|
@ -771,11 +772,15 @@ QuartzReadSystemKeymap(darwinKeyboardInfo *info)
|
|||
KeySym *k;
|
||||
|
||||
/* This is an ugly ant-pattern, but it is more expedient to address the problem right now. */
|
||||
#ifdef HAS_LIBDISPATCH
|
||||
if (pthread_main_np()) {
|
||||
getKeyboardData(&ctx);
|
||||
} else {
|
||||
dispatch_sync_f(dispatch_get_main_queue(), &ctx, getKeyboardData);
|
||||
}
|
||||
#else
|
||||
getKeyboardData(&ctx);
|
||||
#endif
|
||||
|
||||
if (ctx.chr_data == NULL) {
|
||||
ErrorF("Couldn't get uchr or kchr resource\n");
|
||||
|
|
|
|||
|
|
@ -52,10 +52,13 @@
|
|||
#include "quartzKeyboard.h"
|
||||
#include "rootlessWindow.h"
|
||||
#include "xprEvent.h"
|
||||
#include "osxcompat.h"
|
||||
|
||||
#ifdef HAS_LIBDISPATCH
|
||||
#include <dispatch/dispatch.h>
|
||||
#endif
|
||||
|
||||
#if XPLUGIN_VERSION >= 6
|
||||
#include <dispatch/dispatch.h>
|
||||
|
||||
static void bringAllToFront(void *unused) {
|
||||
(void)unused; /* to silence the compiler warning */
|
||||
xp_window_bring_all_to_front();
|
||||
|
|
@ -76,7 +79,7 @@ bool QuartzModeEventHandler(int screenNum, XQuartzEvent *e, DeviceIntPtr dev) {
|
|||
|
||||
case kXquartzBringAllToFront:
|
||||
DEBUG_LOG("kXquartzBringAllToFront\n");
|
||||
#if XPLUGIN_VERSION >= 6
|
||||
#if defined(HAS_LIBDISPATCH) && (XPLUGIN_VERSION >= 6)
|
||||
dispatch_async_f(
|
||||
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), NULL,
|
||||
bringAllToFront);
|
||||
|
|
|
|||
|
|
@ -44,8 +44,13 @@
|
|||
#include <X11/Xatom.h>
|
||||
#include "windowstr.h"
|
||||
#include "quartz.h"
|
||||
#include "osxcompat.h"
|
||||
|
||||
#ifdef HAS_LIBDISPATCH
|
||||
#include <dispatch/dispatch.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#define DEFINE_ATOM_HELPER(func, atom_name) \
|
||||
static Atom func(void) { \
|
||||
|
|
@ -63,7 +68,11 @@ typedef struct _WindowHashInsertCtx {
|
|||
static x_hash_table * window_hash;
|
||||
|
||||
/* Need to guard window_hash since xprIsX11Window can be called from any thread. */
|
||||
#ifdef HAS_LIBDISPATCH
|
||||
static dispatch_queue_t window_hash_serial_q;
|
||||
#else
|
||||
static pthread_rwlock_t window_hash_rwlock;
|
||||
#endif
|
||||
|
||||
/* Prototypes for static functions */
|
||||
static Bool
|
||||
|
|
@ -206,6 +215,7 @@ xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef HAS_LIBDISPATCH
|
||||
WindowHashInsertCtx *ctx = malloc(sizeof(WindowHashInsertCtx));
|
||||
if (!ctx) return FALSE;
|
||||
|
||||
|
|
@ -213,6 +223,12 @@ xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
|
|||
ctx->frame = pFrame;
|
||||
|
||||
dispatch_async_f(window_hash_serial_q, ctx, windowHashInsert);
|
||||
#else
|
||||
pthread_rwlock_wrlock(&window_hash_rwlock);
|
||||
x_hash_table_insert(window_hash, pFrame->wid, pFrame);
|
||||
pthread_rwlock_unlock(&window_hash_rwlock);
|
||||
#endif
|
||||
|
||||
xprSetNativeProperty(pFrame);
|
||||
|
||||
return TRUE;
|
||||
|
|
@ -248,11 +264,18 @@ static void windowLookup(void *arg) {
|
|||
static void
|
||||
xprDestroyFrame(RootlessFrameID wid)
|
||||
{
|
||||
#ifdef HAS_LIBDISPATCH
|
||||
WindowHashRemoveCtx *ctx = malloc(sizeof(WindowHashRemoveCtx));
|
||||
if (!ctx) FatalError("Could not allocate memory for the hash removal context.");
|
||||
|
||||
ctx->wid = wid;
|
||||
|
||||
dispatch_async_f(window_hash_serial_q, ctx, windowHashRemove);
|
||||
#else
|
||||
pthread_rwlock_wrlock(&window_hash_rwlock);
|
||||
x_hash_table_remove(window_hash, wid);
|
||||
pthread_rwlock_unlock(&window_hash_rwlock);
|
||||
#endif
|
||||
|
||||
xp_error err = xp_destroy_window(x_cvt_vptr_to_uint(wid));
|
||||
if (err != Success)
|
||||
|
|
@ -324,7 +347,13 @@ xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid)
|
|||
wc.sibling = x_cvt_vptr_to_uint(nextWid);
|
||||
}
|
||||
|
||||
#ifdef HAS_LIBDISPATCH
|
||||
dispatch_sync_f(window_hash_serial_q, &ctx, windowLookup);
|
||||
#else
|
||||
pthread_rwlock_rdlock(&window_hash_rwlock);
|
||||
winRec = x_hash_table_lookup(window_hash, wid, NULL);
|
||||
pthread_rwlock_unlock(&window_hash_rwlock);
|
||||
#endif
|
||||
|
||||
if (winRec) {
|
||||
if (XQuartzIsRootless)
|
||||
|
|
@ -515,9 +544,13 @@ xprInit(ScreenPtr pScreen)
|
|||
rootless_CopyWindow_threshold = xp_scroll_area_threshold;
|
||||
|
||||
assert((window_hash = x_hash_table_new(NULL, NULL, NULL, NULL)));
|
||||
#ifdef HAS_LIBDISPATCH
|
||||
assert((window_hash_serial_q =
|
||||
dispatch_queue_create(BUNDLE_ID_PREFIX ".X11.xpr_window_hash",
|
||||
NULL)));
|
||||
#else
|
||||
assert(0 == pthread_rwlock_init(&window_hash_rwlock, NULL));
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -535,12 +568,19 @@ WindowPtr
|
|||
xprGetXWindow(xp_window_id wid)
|
||||
{
|
||||
RootlessWindowRec *winRec;
|
||||
#ifdef HAS_LIBDISPATCH
|
||||
WindowGetCtx ctx = {
|
||||
.wid = x_cvt_uint_to_vptr(wid),
|
||||
.winrec = &winRec
|
||||
};
|
||||
|
||||
dispatch_sync_f(window_hash_serial_q, &ctx, windowGet);
|
||||
#else
|
||||
RootlessWindowRec *winRec;
|
||||
pthread_rwlock_rdlock(&window_hash_rwlock);
|
||||
winRec = x_hash_table_lookup(window_hash, x_cvt_uint_to_vptr(wid), NULL);
|
||||
pthread_rwlock_unlock(&window_hash_rwlock);
|
||||
#endif
|
||||
|
||||
return winRec != NULL ? winRec->win : NULL;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue