diff options
author | marha <marha@users.sourceforge.net> | 2010-12-16 16:13:08 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2010-12-16 16:13:08 +0000 |
commit | f851244b9298d88c29331ab285c2839d8bee6925 (patch) | |
tree | f64f1405d89f3ca071001860110f5638bcb286c7 /xorg-server/hw/xquartz | |
parent | fa61692edfc99e13bd2f0bc761590bfeefcfc07a (diff) | |
download | vcxsrv-f851244b9298d88c29331ab285c2839d8bee6925.tar.gz vcxsrv-f851244b9298d88c29331ab285c2839d8bee6925.tar.bz2 vcxsrv-f851244b9298d88c29331ab285c2839d8bee6925.zip |
xserver libXdmcp git update 16-12-2010
Diffstat (limited to 'xorg-server/hw/xquartz')
-rw-r--r-- | xorg-server/hw/xquartz/GL/Makefile.am | 2 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/Makefile.am | 110 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/X11Application.h | 219 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/X11Application.m | 2642 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/X11Controller.h | 1 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/X11Controller.m | 1684 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/bundle/Resources/English.lproj/main.nib/designable.nib | 320 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/bundle/Resources/English.lproj/main.nib/keyedobjects.nib | bin | 45258 -> 44012 bytes | |||
-rw-r--r-- | xorg-server/hw/xquartz/quartz.c | 905 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/quartz.h | 291 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/quartzAudio.c | 329 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/quartzAudio.h | 37 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/quartzKeyboard.c | 1715 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/quartzStartup.c | 4 |
14 files changed, 3996 insertions, 4263 deletions
diff --git a/xorg-server/hw/xquartz/GL/Makefile.am b/xorg-server/hw/xquartz/GL/Makefile.am index af890776e..736c94b4a 100644 --- a/xorg-server/hw/xquartz/GL/Makefile.am +++ b/xorg-server/hw/xquartz/GL/Makefile.am @@ -1,5 +1,5 @@ noinst_LTLIBRARIES = libCGLCore.la -AM_CFLAGS = $(DIX_CFLAGS) +AM_CFLAGS = $(DIX_CFLAGS) $(GL_CFLAGS) AM_CPPFLAGS = \ -I$(top_srcdir) \ -I$(top_srcdir)/glx \ diff --git a/xorg-server/hw/xquartz/Makefile.am b/xorg-server/hw/xquartz/Makefile.am index 23bf04c2e..96b1fb0c5 100644 --- a/xorg-server/hw/xquartz/Makefile.am +++ b/xorg-server/hw/xquartz/Makefile.am @@ -1,56 +1,54 @@ -noinst_LTLIBRARIES = libXquartz.la
-AM_CFLAGS = $(DIX_CFLAGS)
-AM_OBJCFLAGS = $(DIX_CFLAGS)
-AM_CPPFLAGS = \
- -DBUILD_DATE=\"$(BUILD_DATE)\" \
- -DXSERVER_VERSION=\"$(VERSION)\" \
- -DINXQUARTZ \
- -DUSE_NEW_CLUT \
- -DXFree86Server \
- -I$(top_srcdir)/miext/rootless \
- -DX11LIBDIR=\"$(libdir)\"
-
-if GLX
-GL_DIR = GL
-endif
-
-SUBDIRS = bundle . $(GL_DIR) xpr pbproxy mach-startup doc
-
-DIST_SUBDIRS = bundle . GL xpr pbproxy mach-startup doc
-
-libXquartz_la_SOURCES = \
- $(top_srcdir)/fb/fbcmap_mi.c \
- $(top_srcdir)/mi/miinitext.c \
- X11Application.m \
- X11Controller.m \
- applewm.c \
- darwin.c \
- darwinEvents.c \
- darwinXinput.c \
- keysym2ucs.c \
- pseudoramiX.c \
- quartz.c \
- quartzAudio.c \
- quartzCocoa.m \
- quartzKeyboard.c \
- quartzStartup.c \
- quartzRandR.c \
- threadSafety.c
-
-EXTRA_DIST = \
- X11Application.h \
- X11Controller.h \
- applewmExt.h \
- darwin.h \
- darwinfb.h \
- darwinEvents.h \
- keysym2ucs.h \
- pseudoramiX.h \
- quartz.h \
- quartzAudio.h \
- quartzCommon.h \
- quartzKeyboard.h \
- quartzRandR.h \
- sanitizedCarbon.h \
- sanitizedCocoa.h \
- threadSafety.h
+noinst_LTLIBRARIES = libXquartz.la +AM_CFLAGS = $(DIX_CFLAGS) +AM_OBJCFLAGS = $(DIX_CFLAGS) +AM_CPPFLAGS = \ + -DBUILD_DATE=\"$(BUILD_DATE)\" \ + -DXSERVER_VERSION=\"$(VERSION)\" \ + -DINXQUARTZ \ + -DUSE_NEW_CLUT \ + -DXFree86Server \ + -I$(top_srcdir)/miext/rootless \ + -DX11LIBDIR=\"$(libdir)\" + +if GLX +GL_DIR = GL +endif + +SUBDIRS = bundle . $(GL_DIR) xpr pbproxy mach-startup doc + +DIST_SUBDIRS = bundle . GL xpr pbproxy mach-startup doc + +libXquartz_la_SOURCES = \ + $(top_srcdir)/fb/fbcmap_mi.c \ + $(top_srcdir)/mi/miinitext.c \ + X11Application.m \ + X11Controller.m \ + applewm.c \ + darwin.c \ + darwinEvents.c \ + darwinXinput.c \ + keysym2ucs.c \ + pseudoramiX.c \ + quartz.c \ + quartzCocoa.m \ + quartzKeyboard.c \ + quartzStartup.c \ + quartzRandR.c \ + threadSafety.c + +EXTRA_DIST = \ + X11Application.h \ + X11Controller.h \ + applewmExt.h \ + darwin.h \ + darwinfb.h \ + darwinEvents.h \ + keysym2ucs.h \ + pseudoramiX.h \ + quartz.h \ + quartzCommon.h \ + quartzKeyboard.h \ + quartzRandR.h \ + sanitizedCarbon.h \ + sanitizedCocoa.h \ + threadSafety.h diff --git a/xorg-server/hw/xquartz/X11Application.h b/xorg-server/hw/xquartz/X11Application.h index 71a593b40..b3ad19b53 100644 --- a/xorg-server/hw/xquartz/X11Application.h +++ b/xorg-server/hw/xquartz/X11Application.h @@ -1,110 +1,109 @@ -/* X11Application.h -- subclass of NSApplication to multiplex events
-
- Copyright (c) 2002-2007 Apple Inc. All rights reserved.
-
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation files
- (the "Software"), to deal in the Software without restriction,
- including without limitation the rights to use, copy, modify, merge,
- publish, distribute, sublicense, and/or sell copies of the Software,
- and to permit persons to whom the Software is furnished to do so,
- subject to the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
- HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
-
- Except as contained in this notice, the name(s) of the above
- copyright holders shall not be used in advertising or otherwise to
- promote the sale, use or other dealings in this Software without
- prior written authorization. */
-
-#ifndef X11APPLICATION_H
-#define X11APPLICATION_H 1
-
-#if __OBJC__
-
-#import "X11Controller.h"
-
-@interface X11Application : NSApplication {
- X11Controller *_controller;
-
- unsigned int _x_active :1;
-}
-
-- (void) set_controller:controller;
-- (void) set_window_menu:(NSArray *)list;
-
-- (int) prefs_get_integer:(NSString *)key default:(int)def;
-- (const char *) prefs_get_string:(NSString *)key default:(const char *)def;
-- (float) prefs_get_float:(NSString *)key default:(float)def;
-- (int) prefs_get_boolean:(NSString *)key default:(int)def;
-- (NSURL *) prefs_copy_url:(NSString *)key default:(NSURL *)def;
-- (NSArray *) prefs_get_array:(NSString *)key;
-- (void) prefs_set_integer:(NSString *)key value:(int)value;
-- (void) prefs_set_float:(NSString *)key value:(float)value;
-- (void) prefs_set_boolean:(NSString *)key value:(int)value;
-- (void) prefs_set_array:(NSString *)key value:(NSArray *)value;
-- (void) prefs_set_string:(NSString *)key value:(NSString *)value;
-- (void) prefs_synchronize;
-
-- (X11Controller *) controller;
-- (OSX_BOOL) x_active;
-@end
-
-extern X11Application *X11App;
-
-#endif /* __OBJC__ */
-
-void X11ApplicationSetWindowMenu (int nitems, const char **items,
- const char *shortcuts);
-void X11ApplicationSetWindowMenuCheck (int idx);
-void X11ApplicationSetFrontProcess (void);
-void X11ApplicationSetCanQuit (int state);
-void X11ApplicationServerReady (void);
-void X11ApplicationShowHideMenubar (int state);
-void X11ApplicationLaunchClient (const char *cmd);
-
-void X11ApplicationMain(int argc, char **argv, char **envp);
-
-#define PREFS_APPSMENU "apps_menu"
-#define PREFS_FAKEBUTTONS "enable_fake_buttons"
-#define PREFS_SYSBEEP "enable_system_beep"
-#define PREFS_KEYEQUIVS "enable_key_equivalents"
-#define PREFS_FULLSCREEN_HOTKEYS "fullscreen_hotkeys"
-#define PREFS_FULLSCREEN_MENU "fullscreen_menu"
-#define PREFS_SYNC_KEYMAP "sync_keymap"
-#define PREFS_DEPTH "depth"
-#define PREFS_NO_AUTH "no_auth"
-#define PREFS_NO_TCP "nolisten_tcp"
-#define PREFS_DONE_XINIT_CHECK "done_xinit_check"
-#define PREFS_NO_QUIT_ALERT "no_quit_alert"
-#define PREFS_OPTION_SENDS_ALT "option_sends_alt"
-#define PREFS_FAKE_BUTTON2 "fake_button2"
-#define PREFS_FAKE_BUTTON3 "fake_button3"
-#define PREFS_APPKIT_MODIFIERS "appkit_modifiers"
-#define PREFS_WINDOW_ITEM_MODIFIERS "window_item_modifiers"
-#define PREFS_ROOTLESS "rootless"
-#define PREFS_TEST_EXTENSIONS "enable_test_extensions"
-#define PREFS_XP_OPTIONS "xp_options"
-#define PREFS_LOGIN_SHELL "login_shell"
-#define PREFS_UPDATE_FEED "update_feed"
-#define PREFS_CLICK_THROUGH "wm_click_through"
-#define PREFS_FFM "wm_ffm"
-#define PREFS_FOCUS_ON_NEW_WINDOW "wm_focus_on_new_window"
-
-#define PREFS_SYNC_PB "sync_pasteboard"
-#define PREFS_SYNC_PB_TO_CLIPBOARD "sync_pasteboard_to_clipboard"
-#define PREFS_SYNC_PB_TO_PRIMARY "sync_pasteboard_to_primary"
-#define PREFS_SYNC_CLIPBOARD_TO_PB "sync_clipboard_to_pasteboard"
-#define PREFS_SYNC_PRIMARY_ON_SELECT "sync_primary_on_select"
-
-#endif /* X11APPLICATION_H */
+/* X11Application.h -- subclass of NSApplication to multiplex events + + Copyright (c) 2002-2007 Apple Inc. All rights reserved. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT + HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name(s) of the above + copyright holders shall not be used in advertising or otherwise to + promote the sale, use or other dealings in this Software without + prior written authorization. */ + +#ifndef X11APPLICATION_H +#define X11APPLICATION_H 1 + +#if __OBJC__ + +#import "X11Controller.h" + +@interface X11Application : NSApplication { + X11Controller *_controller; + + unsigned int _x_active :1; +} + +- (void) set_controller:controller; +- (void) set_window_menu:(NSArray *)list; + +- (int) prefs_get_integer:(NSString *)key default:(int)def; +- (const char *) prefs_get_string:(NSString *)key default:(const char *)def; +- (float) prefs_get_float:(NSString *)key default:(float)def; +- (int) prefs_get_boolean:(NSString *)key default:(int)def; +- (NSURL *) prefs_copy_url:(NSString *)key default:(NSURL *)def; +- (NSArray *) prefs_get_array:(NSString *)key; +- (void) prefs_set_integer:(NSString *)key value:(int)value; +- (void) prefs_set_float:(NSString *)key value:(float)value; +- (void) prefs_set_boolean:(NSString *)key value:(int)value; +- (void) prefs_set_array:(NSString *)key value:(NSArray *)value; +- (void) prefs_set_string:(NSString *)key value:(NSString *)value; +- (void) prefs_synchronize; + +- (X11Controller *) controller; +- (OSX_BOOL) x_active; +@end + +extern X11Application *X11App; + +#endif /* __OBJC__ */ + +void X11ApplicationSetWindowMenu (int nitems, const char **items, + const char *shortcuts); +void X11ApplicationSetWindowMenuCheck (int idx); +void X11ApplicationSetFrontProcess (void); +void X11ApplicationSetCanQuit (int state); +void X11ApplicationServerReady (void); +void X11ApplicationShowHideMenubar (int state); +void X11ApplicationLaunchClient (const char *cmd); + +void X11ApplicationMain(int argc, char **argv, char **envp); + +#define PREFS_APPSMENU "apps_menu" +#define PREFS_FAKEBUTTONS "enable_fake_buttons" +#define PREFS_KEYEQUIVS "enable_key_equivalents" +#define PREFS_FULLSCREEN_HOTKEYS "fullscreen_hotkeys" +#define PREFS_FULLSCREEN_MENU "fullscreen_menu" +#define PREFS_SYNC_KEYMAP "sync_keymap" +#define PREFS_DEPTH "depth" +#define PREFS_NO_AUTH "no_auth" +#define PREFS_NO_TCP "nolisten_tcp" +#define PREFS_DONE_XINIT_CHECK "done_xinit_check" +#define PREFS_NO_QUIT_ALERT "no_quit_alert" +#define PREFS_OPTION_SENDS_ALT "option_sends_alt" +#define PREFS_FAKE_BUTTON2 "fake_button2" +#define PREFS_FAKE_BUTTON3 "fake_button3" +#define PREFS_APPKIT_MODIFIERS "appkit_modifiers" +#define PREFS_WINDOW_ITEM_MODIFIERS "window_item_modifiers" +#define PREFS_ROOTLESS "rootless" +#define PREFS_TEST_EXTENSIONS "enable_test_extensions" +#define PREFS_XP_OPTIONS "xp_options" +#define PREFS_LOGIN_SHELL "login_shell" +#define PREFS_UPDATE_FEED "update_feed" +#define PREFS_CLICK_THROUGH "wm_click_through" +#define PREFS_FFM "wm_ffm" +#define PREFS_FOCUS_ON_NEW_WINDOW "wm_focus_on_new_window" + +#define PREFS_SYNC_PB "sync_pasteboard" +#define PREFS_SYNC_PB_TO_CLIPBOARD "sync_pasteboard_to_clipboard" +#define PREFS_SYNC_PB_TO_PRIMARY "sync_pasteboard_to_primary" +#define PREFS_SYNC_CLIPBOARD_TO_PB "sync_clipboard_to_pasteboard" +#define PREFS_SYNC_PRIMARY_ON_SELECT "sync_primary_on_select" + +#endif /* X11APPLICATION_H */ diff --git a/xorg-server/hw/xquartz/X11Application.m b/xorg-server/hw/xquartz/X11Application.m index 264c1fbea..b855c8358 100644 --- a/xorg-server/hw/xquartz/X11Application.m +++ b/xorg-server/hw/xquartz/X11Application.m @@ -1,1322 +1,1320 @@ -/* X11Application.m -- subclass of NSApplication to multiplex events
-
- Copyright (c) 2002-2008 Apple Inc.
-
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation files
- (the "Software"), to deal in the Software without restriction,
- including without limitation the rights to use, copy, modify, merge,
- publish, distribute, sublicense, and/or sell copies of the Software,
- and to permit persons to whom the Software is furnished to do so,
- subject to the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
- HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
-
- Except as contained in this notice, the name(s) of the above
- copyright holders shall not be used in advertising or otherwise to
- promote the sale, use or other dealings in this Software without
- prior written authorization. */
-
-#include "sanitizedCarbon.h"
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "quartzCommon.h"
-
-#import "X11Application.h"
-
-#include "darwin.h"
-#include "quartz.h"
-#include "darwinEvents.h"
-#include "quartzKeyboard.h"
-#include "quartz.h"
-#include <X11/extensions/applewmconst.h>
-#include "micmap.h"
-#include "exglobals.h"
-
-#include <mach/mach.h>
-#include <unistd.h>
-#include <AvailabilityMacros.h>
-
-#include <Xplugin.h>
-
-// pbproxy/pbproxy.h
-extern int xpbproxy_run (void);
-
-#define DEFAULTS_FILE X11LIBDIR"/X11/xserver/Xquartz.plist"
-
-#ifndef XSERVER_VERSION
-#define XSERVER_VERSION "?"
-#endif
-
-/* Stuck modifier / button state... force release when we context switch */
-static NSEventType keyState[NUM_KEYCODES];
-
-extern Bool noTestExtensions;
-
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
-static TISInputSourceRef last_key_layout;
-#else
-static KeyboardLayoutRef last_key_layout;
-#endif
-
-extern int darwinFakeButtons;
-
-/* Store the mouse location while in the background, and update X11's pointer
- * location when we become the foreground application
- */
-static NSPoint bgMouseLocation;
-static BOOL bgMouseLocationUpdated = FALSE;
-
-X11Application *X11App;
-
-CFStringRef app_prefs_domain_cfstr = NULL;
-
-#define ALL_KEY_MASKS (NSShiftKeyMask | NSControlKeyMask | NSAlternateKeyMask | NSCommandKeyMask)
-
-@interface X11Application (Private)
-- (void) sendX11NSEvent:(NSEvent *)e;
-@end
-
-@implementation X11Application
-
-typedef struct message_struct message;
-struct message_struct {
- mach_msg_header_t hdr;
- SEL selector;
- NSObject *arg;
-};
-
-static mach_port_t _port;
-
-/* Quartz mode initialization routine. This is often dynamically loaded
- but is statically linked into this X server. */
-Bool QuartzModeBundleInit(void);
-
-static void init_ports (void) {
- kern_return_t r;
- NSPort *p;
-
- if (_port != MACH_PORT_NULL) return;
-
- r = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &_port);
- if (r != KERN_SUCCESS) return;
-
- p = [NSMachPort portWithMachPort:_port];
- [p setDelegate:NSApp];
- [p scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
-}
-
-static void message_kit_thread (SEL selector, NSObject *arg) {
- message msg;
- kern_return_t r;
-
- msg.hdr.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_MAKE_SEND, 0);
- msg.hdr.msgh_size = sizeof (msg);
- msg.hdr.msgh_remote_port = _port;
- msg.hdr.msgh_local_port = MACH_PORT_NULL;
- msg.hdr.msgh_reserved = 0;
- msg.hdr.msgh_id = 0;
-
- msg.selector = selector;
- msg.arg = [arg retain];
-
- r = mach_msg (&msg.hdr, MACH_SEND_MSG, msg.hdr.msgh_size,
- 0, MACH_PORT_NULL, 0, MACH_PORT_NULL);
- if (r != KERN_SUCCESS)
- ErrorF("%s: mach_msg failed: %x\n", __FUNCTION__, r);
-}
-
-- (void) handleMachMessage:(void *)_msg {
- message *msg = _msg;
-
- [self performSelector:msg->selector withObject:msg->arg];
- [msg->arg release];
-}
-
-- (void) set_controller:obj {
- if (_controller == nil) _controller = [obj retain];
-}
-
-- (void) dealloc {
- if (_controller != nil) [_controller release];
-
- if (_port != MACH_PORT_NULL)
- mach_port_deallocate (mach_task_self (), _port);
-
- [super dealloc];
-}
-
-- (void) orderFrontStandardAboutPanel: (id) sender {
- NSMutableDictionary *dict;
- NSDictionary *infoDict;
- NSString *tem;
-
- dict = [NSMutableDictionary dictionaryWithCapacity:3];
- infoDict = [[NSBundle mainBundle] infoDictionary];
-
- [dict setObject: NSLocalizedString (@"The X Window System", @"About panel")
- forKey:@"ApplicationName"];
-
- tem = [infoDict objectForKey:@"CFBundleShortVersionString"];
-
- [dict setObject:[NSString stringWithFormat:@"XQuartz %@", tem]
- forKey:@"ApplicationVersion"];
-
- [dict setObject:[NSString stringWithFormat:@"xorg-server %s", XSERVER_VERSION]
- forKey:@"Version"];
-
- [self orderFrontStandardAboutPanelWithOptions: dict];
-}
-
-- (void) activateX:(OSX_BOOL)state {
- size_t i;
- DEBUG_LOG("state=%d, _x_active=%d, \n", state, _x_active)
- if (state) {
- if(bgMouseLocationUpdated) {
- DarwinSendPointerEvents(darwinPointer, MotionNotify, 0, bgMouseLocation.x, bgMouseLocation.y, 0.0, 0.0, 0.0);
- bgMouseLocationUpdated = FALSE;
- }
- DarwinSendDDXEvent(kXquartzActivate, 0);
- } else {
-
- if(darwin_all_modifier_flags)
- DarwinUpdateModKeys(0);
- for(i=0; i < NUM_KEYCODES; i++) {
- if(keyState[i] == NSKeyDown) {
- DarwinSendKeyboardEvents(KeyRelease, i);
- keyState[i] = NSKeyUp;
- }
- }
-
- DarwinSendDDXEvent(kXquartzDeactivate, 0);
- }
-
- _x_active = state;
-}
-
-- (void) became_key:(NSWindow *)win {
- [self activateX:NO];
-}
-
-- (void) sendEvent:(NSEvent *)e {
- OSX_BOOL for_appkit, for_x;
-
- /* By default pass down the responder chain and to X. */
- for_appkit = YES;
- for_x = YES;
-
- switch ([e type]) {
- case NSLeftMouseDown: case NSRightMouseDown: case NSOtherMouseDown:
- case NSLeftMouseUp: case NSRightMouseUp: case NSOtherMouseUp:
- if ([e window] != nil) {
- /* Pointer event has an (AppKit) window. Probably something for the kit. */
- for_x = NO;
- if (_x_active) [self activateX:NO];
- } else if ([self modalWindow] == nil) {
- /* Must be an X window. Tell appkit it doesn't have focus. */
- for_appkit = NO;
-
- if ([self isActive]) {
- [self deactivate];
- if (!_x_active && quartzProcs->IsX11Window([e window],
- [e windowNumber]))
- [self activateX:YES];
- }
- }
-
- /* We want to force sending to appkit if we're over the menu bar */
- if(!for_appkit) {
- NSPoint NSlocation = [e locationInWindow];
- NSWindow *window = [e window];
- NSRect NSframe, NSvisibleFrame;
- CGRect CGframe, CGvisibleFrame;
- CGPoint CGlocation;
-
- if (window != nil) {
- NSRect frame = [window frame];
- NSlocation.x += frame.origin.x;
- NSlocation.y += frame.origin.y;
- }
-
- NSframe = [[NSScreen mainScreen] frame];
- NSvisibleFrame = [[NSScreen mainScreen] visibleFrame];
-
- CGframe = CGRectMake(NSframe.origin.x, NSframe.origin.y,
- NSframe.size.width, NSframe.size.height);
- CGvisibleFrame = CGRectMake(NSvisibleFrame.origin.x,
- NSvisibleFrame.origin.y,
- NSvisibleFrame.size.width,
- NSvisibleFrame.size.height);
- CGlocation = CGPointMake(NSlocation.x, NSlocation.y);
-
- if(CGRectContainsPoint(CGframe, CGlocation) &&
- !CGRectContainsPoint(CGvisibleFrame, CGlocation))
- for_appkit = YES;
- }
-
- break;
-
- case NSKeyDown: case NSKeyUp:
-
- if(_x_active) {
- static BOOL do_swallow = NO;
- static int swallow_keycode;
-
- if([e type] == NSKeyDown) {
- /* Before that though, see if there are any global
- * shortcuts bound to it. */
-
- if(darwinAppKitModMask & [e modifierFlags]) {
- /* Override to force sending to Appkit */
- swallow_keycode = [e keyCode];
- do_swallow = YES;
- for_x = NO;
-#if XPLUGIN_VERSION >= 1
- } else if(XQuartzEnableKeyEquivalents &&
- xp_is_symbolic_hotkey_event([e eventRef])) {
- swallow_keycode = [e keyCode];
- do_swallow = YES;
- for_x = NO;
-#endif
- } else if(XQuartzEnableKeyEquivalents &&
- [[self mainMenu] performKeyEquivalent:e]) {
- swallow_keycode = [e keyCode];
- do_swallow = YES;
- for_appkit = NO;
- for_x = NO;
- } else if(!XQuartzIsRootless
- && ([e modifierFlags] & ALL_KEY_MASKS) == (NSCommandKeyMask | NSAlternateKeyMask)
- && ([e keyCode] == 0 /*a*/ || [e keyCode] == 53 /*Esc*/)) {
- /* We have this here to force processing fullscreen
- * toggle even if XQuartzEnableKeyEquivalents is disabled */
- swallow_keycode = [e keyCode];
- do_swallow = YES;
- for_x = NO;
- for_appkit = NO;
- DarwinSendDDXEvent(kXquartzToggleFullscreen, 0);
- } else {
- /* No kit window is focused, so send it to X. */
- for_appkit = NO;
- }
- } else { /* KeyUp */
- /* If we saw a key equivalent on the down, don't pass
- * the up through to X. */
- if (do_swallow && [e keyCode] == swallow_keycode) {
- do_swallow = NO;
- for_x = NO;
- }
- }
- } else { /* !_x_active */
- for_x = NO;
- }
- break;
-
- case NSFlagsChanged:
- /* Don't tell X11 about modifiers changing while it's not active */
- if (!_x_active)
- for_x = NO;
- break;
-
- case NSAppKitDefined:
- switch ([e subtype]) {
- case NSApplicationActivatedEventType:
- for_x = NO;
- if ([self modalWindow] == nil) {
- BOOL order_all_windows = YES, workspaces, ok;
- for_appkit = NO;
-
- /* FIXME: hack to avoid having to pass the event to appkit,
- which would cause it to raise one of its windows. */
- _appFlags._active = YES;
-
- [self activateX:YES];
-
- /* Get the Spaces preference for SwitchOnActivate */
- (void)CFPreferencesAppSynchronize(CFSTR("com.apple.dock"));
- workspaces = CFPreferencesGetAppBooleanValue(CFSTR("workspaces"), CFSTR("com.apple.dock"), &ok);
- if (!ok)
- workspaces = NO;
-
- if (workspaces) {
- (void)CFPreferencesAppSynchronize(CFSTR(".GlobalPreferences"));
- order_all_windows = CFPreferencesGetAppBooleanValue(CFSTR("AppleSpacesSwitchOnActivate"), CFSTR(".GlobalPreferences"), &ok);
- if (!ok)
- order_all_windows = YES;
- }
-
- /* TODO: In the workspaces && !AppleSpacesSwitchOnActivate case, the windows are ordered
- * correctly, but we need to activate the top window on this space if there is
- * none active.
- *
- * If there are no active windows, and there are minimized windows, we should
- * be restoring one of them.
- */
- if ([e data2] & 0x10) // 0x10 is set when we use cmd-tab or the dock icon
- DarwinSendDDXEvent(kXquartzBringAllToFront, 1, order_all_windows);
- }
- break;
-
- case 18: /* ApplicationDidReactivate */
- if (XQuartzFullscreenVisible) for_appkit = NO;
- break;
-
- case NSApplicationDeactivatedEventType:
- for_x = NO;
- [self activateX:NO];
- break;
- }
- break;
-
- default: break; /* for gcc */
- }
-
- if (for_appkit) [super sendEvent:e];
-
- if (for_x) [self sendX11NSEvent:e];
-}
-
-- (void) set_window_menu:(NSArray *)list {
- [_controller set_window_menu:list];
-}
-
-- (void) set_window_menu_check:(NSNumber *)n {
- [_controller set_window_menu_check:n];
-}
-
-- (void) set_apps_menu:(NSArray *)list {
- [_controller set_apps_menu:list];
-}
-
-- (void) set_front_process:unused {
- [NSApp activateIgnoringOtherApps:YES];
-
- if ([self modalWindow] == nil)
- [self activateX:YES];
-}
-
-- (void) set_can_quit:(NSNumber *)state {
- [_controller set_can_quit:[state boolValue]];
-}
-
-- (void) server_ready:unused {
- [_controller server_ready];
-}
-
-- (void) show_hide_menubar:(NSNumber *)state {
- /* Also shows/hides the dock */
- if ([state boolValue])
- SetSystemUIMode(kUIModeNormal, 0);
- else
- SetSystemUIMode(kUIModeAllHidden, XQuartzFullscreenMenu ? kUIOptionAutoShowMenuBar : 0); // kUIModeAllSuppressed or kUIOptionAutoShowMenuBar can be used to allow "mouse-activation"
-}
-
-- (void) launch_client:(NSString *)cmd {
- (void)[_controller application:self openFile:cmd];
-}
-
-/* user preferences */
-
-/* Note that these functions only work for arrays whose elements
- can be toll-free-bridged between NS and CF worlds. */
-
-static const void *cfretain (CFAllocatorRef a, const void *b) {
- return CFRetain (b);
-}
-
-static void cfrelease (CFAllocatorRef a, const void *b) {
- CFRelease (b);
-}
-
-static CFMutableArrayRef nsarray_to_cfarray (NSArray *in) {
- CFMutableArrayRef out;
- CFArrayCallBacks cb;
- NSObject *ns;
- const CFTypeRef *cf;
- int i, count;
-
- memset (&cb, 0, sizeof (cb));
- cb.version = 0;
- cb.retain = cfretain;
- cb.release = cfrelease;
-
- count = [in count];
- out = CFArrayCreateMutable (NULL, count, &cb);
-
- for (i = 0; i < count; i++) {
- ns = [in objectAtIndex:i];
-
- if ([ns isKindOfClass:[NSArray class]])
- cf = (CFTypeRef) nsarray_to_cfarray ((NSArray *) ns);
- else
- cf = CFRetain ((CFTypeRef) ns);
-
- CFArrayAppendValue (out, cf);
- CFRelease (cf);
- }
-
- return out;
-}
-
-static NSMutableArray * cfarray_to_nsarray (CFArrayRef in) {
- NSMutableArray *out;
- const CFTypeRef *cf;
- NSObject *ns;
- int i, count;
-
- count = CFArrayGetCount (in);
- out = [[NSMutableArray alloc] initWithCapacity:count];
-
- for (i = 0; i < count; i++) {
- cf = CFArrayGetValueAtIndex (in, i);
-
- if (CFGetTypeID (cf) == CFArrayGetTypeID ())
- ns = cfarray_to_nsarray ((CFArrayRef) cf);
- else
- ns = [(id)cf retain];
-
- [out addObject:ns];
- [ns release];
- }
-
- return out;
-}
-
-- (CFPropertyListRef) prefs_get_copy:(NSString *)key {
- CFPropertyListRef value;
-
- value = CFPreferencesCopyAppValue ((CFStringRef) key, app_prefs_domain_cfstr);
-
- if (value == NULL) {
- static CFDictionaryRef defaults;
-
- if (defaults == NULL) {
- CFStringRef error = NULL;
- CFDataRef data;
- CFURLRef url;
- SInt32 error_code;
-
- url = (CFURLCreateFromFileSystemRepresentation
- (NULL, (unsigned char *)DEFAULTS_FILE, strlen (DEFAULTS_FILE), false));
- if (CFURLCreateDataAndPropertiesFromResource (NULL, url, &data,
- NULL, NULL, &error_code)) {
- defaults = (CFPropertyListCreateFromXMLData
- (NULL, data, kCFPropertyListMutableContainersAndLeaves, &error));
- if (error != NULL) CFRelease (error);
- CFRelease (data);
- }
- CFRelease (url);
-
- if (defaults != NULL) {
- NSMutableArray *apps, *elt;
- int count, i;
- NSString *name, *nname;
-
- /* Localize the names in the default apps menu. */
-
- apps = [(NSDictionary *)defaults objectForKey:@PREFS_APPSMENU];
- if (apps != nil) {
- count = [apps count];
- for (i = 0; i < count; i++) {
- elt = [apps objectAtIndex:i];
- if (elt != nil && [elt isKindOfClass:[NSArray class]]) {
- name = [elt objectAtIndex:0];
- if (name != nil) {
- nname = NSLocalizedString (name, nil);
- if (nname != nil && nname != name)
- [elt replaceObjectAtIndex:0 withObject:nname];
- }
- }
- }
- }
- }
- }
-
- if (defaults != NULL) value = CFDictionaryGetValue (defaults, key);
- if (value != NULL) CFRetain (value);
- }
-
- return value;
-}
-
-- (int) prefs_get_integer:(NSString *)key default:(int)def {
- CFPropertyListRef value;
- int ret;
-
- value = [self prefs_get_copy:key];
-
- if (value != NULL && CFGetTypeID (value) == CFNumberGetTypeID ())
- CFNumberGetValue (value, kCFNumberIntType, &ret);
- else if (value != NULL && CFGetTypeID (value) == CFStringGetTypeID ())
- ret = CFStringGetIntValue (value);
- else
- ret = def;
-
- if (value != NULL) CFRelease (value);
-
- return ret;
-}
-
-- (const char *) prefs_get_string:(NSString *)key default:(const char *)def {
- CFPropertyListRef value;
- const char *ret = NULL;
-
- value = [self prefs_get_copy:key];
-
- if (value != NULL && CFGetTypeID (value) == CFStringGetTypeID ()) {
- NSString *s = (NSString *) value;
-
- ret = [s UTF8String];
- }
-
- if (value != NULL) CFRelease (value);
-
- return ret != NULL ? ret : def;
-}
-
-- (NSURL *) prefs_copy_url:(NSString *)key default:(NSURL *)def {
- CFPropertyListRef value;
- NSURL *ret = NULL;
-
- value = [self prefs_get_copy:key];
-
- if (value != NULL && CFGetTypeID (value) == CFStringGetTypeID ()) {
- NSString *s = (NSString *) value;
-
- ret = [NSURL URLWithString:s];
- [ret retain];
- }
-
- if (value != NULL) CFRelease (value);
-
- return ret != NULL ? ret : def;
-}
-
-- (float) prefs_get_float:(NSString *)key default:(float)def {
- CFPropertyListRef value;
- float ret = def;
-
- value = [self prefs_get_copy:key];
-
- if (value != NULL
- && CFGetTypeID (value) == CFNumberGetTypeID ()
- && CFNumberIsFloatType (value))
- CFNumberGetValue (value, kCFNumberFloatType, &ret);
- else if (value != NULL && CFGetTypeID (value) == CFStringGetTypeID ())
- ret = CFStringGetDoubleValue (value);
-
- if (value != NULL) CFRelease (value);
-
- return ret;
-}
-
-- (int) prefs_get_boolean:(NSString *)key default:(int)def {
- CFPropertyListRef value;
- int ret = def;
-
- value = [self prefs_get_copy:key];
-
- if (value != NULL) {
- if (CFGetTypeID (value) == CFNumberGetTypeID ())
- CFNumberGetValue (value, kCFNumberIntType, &ret);
- else if (CFGetTypeID (value) == CFBooleanGetTypeID ())
- ret = CFBooleanGetValue (value);
- else if (CFGetTypeID (value) == CFStringGetTypeID ()) {
- const char *tem = [(NSString *) value UTF8String];
- if (strcasecmp (tem, "true") == 0 || strcasecmp (tem, "yes") == 0)
- ret = YES;
- else
- ret = NO;
- }
-
- CFRelease (value);
- }
- return ret;
-}
-
-- (NSArray *) prefs_get_array:(NSString *)key {
- NSArray *ret = nil;
- CFPropertyListRef value;
-
- value = [self prefs_get_copy:key];
-
- if (value != NULL) {
- if (CFGetTypeID (value) == CFArrayGetTypeID ())
- ret = [cfarray_to_nsarray (value) autorelease];
-
- CFRelease (value);
- }
-
- return ret;
-}
-
-- (void) prefs_set_integer:(NSString *)key value:(int)value {
- CFNumberRef x;
-
- x = CFNumberCreate (NULL, kCFNumberIntType, &value);
-
- CFPreferencesSetValue ((CFStringRef) key, (CFTypeRef) x, app_prefs_domain_cfstr,
- kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
-
- CFRelease (x);
-}
-
-- (void) prefs_set_float:(NSString *)key value:(float)value {
- CFNumberRef x;
-
- x = CFNumberCreate (NULL, kCFNumberFloatType, &value);
-
- CFPreferencesSetValue ((CFStringRef) key, (CFTypeRef) x, app_prefs_domain_cfstr,
- kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
-
- CFRelease (x);
-}
-
-- (void) prefs_set_boolean:(NSString *)key value:(int)value {
- CFPreferencesSetValue ((CFStringRef) key,
- (CFTypeRef) (value ? kCFBooleanTrue
- : kCFBooleanFalse), app_prefs_domain_cfstr,
- kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
-
-}
-
-- (void) prefs_set_array:(NSString *)key value:(NSArray *)value {
- CFArrayRef cfarray;
-
- cfarray = nsarray_to_cfarray (value);
- CFPreferencesSetValue ((CFStringRef) key,
- (CFTypeRef) cfarray,
- app_prefs_domain_cfstr,
- kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
- CFRelease (cfarray);
-}
-
-- (void) prefs_set_string:(NSString *)key value:(NSString *)value {
- CFPreferencesSetValue ((CFStringRef) key, (CFTypeRef) value,
- app_prefs_domain_cfstr, kCFPreferencesCurrentUser,
- kCFPreferencesAnyHost);
-}
-
-- (void) prefs_synchronize {
- CFPreferencesAppSynchronize (kCFPreferencesCurrentApplication);
-}
-
-- (void) read_defaults
-{
- NSString *nsstr;
- const char *tem;
-
- XQuartzUseSysBeep = [self prefs_get_boolean:@PREFS_SYSBEEP
- default:XQuartzUseSysBeep];
- XQuartzRootlessDefault = [self prefs_get_boolean:@PREFS_ROOTLESS
- default:XQuartzRootlessDefault];
- XQuartzFullscreenMenu = [self prefs_get_boolean:@PREFS_FULLSCREEN_MENU
- default:XQuartzFullscreenMenu];
- XQuartzFullscreenDisableHotkeys = ![self prefs_get_boolean:@PREFS_FULLSCREEN_HOTKEYS
- default:!XQuartzFullscreenDisableHotkeys];
- darwinFakeButtons = [self prefs_get_boolean:@PREFS_FAKEBUTTONS
- default:darwinFakeButtons];
- XQuartzOptionSendsAlt = [self prefs_get_boolean:@PREFS_OPTION_SENDS_ALT
- default:XQuartzOptionSendsAlt];
-
- if (darwinFakeButtons) {
- const char *fake2, *fake3;
-
- fake2 = [self prefs_get_string:@PREFS_FAKE_BUTTON2 default:NULL];
- fake3 = [self prefs_get_string:@PREFS_FAKE_BUTTON3 default:NULL];
-
- if (fake2 != NULL) darwinFakeMouse2Mask = DarwinParseModifierList(fake2, TRUE);
- if (fake3 != NULL) darwinFakeMouse3Mask = DarwinParseModifierList(fake3, TRUE);
- }
-
- tem = [self prefs_get_string:@PREFS_APPKIT_MODIFIERS default:NULL];
- if (tem != NULL) darwinAppKitModMask = DarwinParseModifierList(tem, TRUE);
-
- tem = [self prefs_get_string:@PREFS_WINDOW_ITEM_MODIFIERS default:NULL];
- if (tem != NULL) {
- windowItemModMask = DarwinParseModifierList(tem, FALSE);
- } else {
- nsstr = NSLocalizedString (@"window item modifiers", @"window item modifiers");
- if(nsstr != NULL) {
- tem = [nsstr UTF8String];
- if((tem != NULL) && strcmp(tem, "window item modifiers")) {
- windowItemModMask = DarwinParseModifierList(tem, FALSE);
- }
- }
- }
-
- XQuartzEnableKeyEquivalents = [self prefs_get_boolean:@PREFS_KEYEQUIVS
- default:XQuartzEnableKeyEquivalents];
-
- darwinSyncKeymap = [self prefs_get_boolean:@PREFS_SYNC_KEYMAP
- default:darwinSyncKeymap];
-
- darwinDesiredDepth = [self prefs_get_integer:@PREFS_DEPTH
- default:darwinDesiredDepth];
-
- noTestExtensions = ![self prefs_get_boolean:@PREFS_TEST_EXTENSIONS
- default:FALSE];
-
-#if XQUARTZ_SPARKLE
- NSURL *url = [self prefs_copy_url:@PREFS_UPDATE_FEED default:nil];
- if(url) {
- [[SUUpdater sharedUpdater] setFeedURL:url];
- [url release];
- }
-#endif
-}
-
-/* This will end up at the end of the responder chain. */
-- (void) copy:sender {
- DarwinSendDDXEvent(kXquartzPasteboardNotify, 1,
- AppleWMCopyToPasteboard);
-}
-
-- (X11Controller *) controller {
- return _controller;
-}
-
-- (OSX_BOOL) x_active {
- return _x_active;
-}
-
-@end
-
-static NSArray *
-array_with_strings_and_numbers (int nitems, const char **items,
- const char *numbers) {
- NSMutableArray *array, *subarray;
- NSString *string, *number;
- int i;
-
- /* (Can't autorelease on the X server thread) */
-
- array = [[NSMutableArray alloc] initWithCapacity:nitems];
-
- for (i = 0; i < nitems; i++) {
- subarray = [[NSMutableArray alloc] initWithCapacity:2];
-
- string = [[NSString alloc] initWithUTF8String:items[i]];
- [subarray addObject:string];
- [string release];
-
- if (numbers[i] != 0) {
- number = [[NSString alloc] initWithFormat:@"%d", numbers[i]];
- [subarray addObject:number];
- [number release];
- } else
- [subarray addObject:@""];
-
- [array addObject:subarray];
- [subarray release];
- }
-
- return array;
-}
-
-void X11ApplicationSetWindowMenu (int nitems, const char **items,
- const char *shortcuts) {
- NSArray *array;
- array = array_with_strings_and_numbers (nitems, items, shortcuts);
-
- /* Send the array of strings over to the appkit thread */
-
- message_kit_thread (@selector (set_window_menu:), array);
- [array release];
-}
-
-void X11ApplicationSetWindowMenuCheck (int idx) {
- NSNumber *n;
-
- n = [[NSNumber alloc] initWithInt:idx];
-
- message_kit_thread (@selector (set_window_menu_check:), n);
-
- [n release];
-}
-
-void X11ApplicationSetFrontProcess (void) {
- message_kit_thread (@selector (set_front_process:), nil);
-}
-
-void X11ApplicationSetCanQuit (int state) {
- NSNumber *n;
-
- n = [[NSNumber alloc] initWithBool:state];
-
- message_kit_thread (@selector (set_can_quit:), n);
-
- [n release];
-}
-
-void X11ApplicationServerReady (void) {
- message_kit_thread (@selector (server_ready:), nil);
-}
-
-void X11ApplicationShowHideMenubar (int state) {
- NSNumber *n;
-
- n = [[NSNumber alloc] initWithBool:state];
-
- message_kit_thread (@selector (show_hide_menubar:), n);
-
- [n release];
-}
-
-void X11ApplicationLaunchClient (const char *cmd) {
- NSString *string;
-
- string = [[NSString alloc] initWithUTF8String:cmd];
-
- message_kit_thread (@selector (launch_client:), string);
-
- [string release];
-}
-
-static void check_xinitrc (void) {
- char *tem, buf[1024];
- NSString *msg;
-
- if ([X11App prefs_get_boolean:@PREFS_DONE_XINIT_CHECK default:NO])
- return;
-
- tem = getenv ("HOME");
- if (tem == NULL) goto done;
-
- snprintf (buf, sizeof (buf), "%s/.xinitrc", tem);
- if (access (buf, F_OK) != 0)
- goto done;
-
- msg = NSLocalizedString (@"You have an existing ~/.xinitrc file.\n\n\
-Windows displayed by X11 applications may not have titlebars, or may look \
-different to windows displayed by native applications.\n\n\
-Would you like to move aside the existing file and use the standard X11 \
-environment the next time you start X11?", @"Startup xinitrc dialog");
-
- if(NSAlertDefaultReturn == NSRunAlertPanel (nil, msg, NSLocalizedString (@"Yes", @""),
- NSLocalizedString (@"No", @""), nil)) {
- char buf2[1024];
- int i = -1;
-
- snprintf (buf2, sizeof (buf2), "%s.old", buf);
-
- for(i = 1; access (buf2, F_OK) == 0; i++)
- snprintf (buf2, sizeof (buf2), "%s.old.%d", buf, i);
-
- rename (buf, buf2);
- }
-
- done:
- [X11App prefs_set_boolean:@PREFS_DONE_XINIT_CHECK value:YES];
- [X11App prefs_synchronize];
-}
-
-static inline pthread_t create_thread(void *func, 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;
-}
-
-static void *xpbproxy_x_thread(void *args) {
- xpbproxy_run();
-
- fprintf(stderr, "xpbproxy thread is terminating unexpectedly.\n");
- return NULL;
-}
-
-void X11ApplicationMain (int argc, char **argv, char **envp) {
- NSAutoreleasePool *pool;
-
-#ifdef DEBUG
- while (access ("/tmp/x11-block", F_OK) == 0) sleep (1);
-#endif
-
- pool = [[NSAutoreleasePool alloc] init];
- X11App = (X11Application *) [X11Application sharedApplication];
- init_ports ();
-
- app_prefs_domain_cfstr = (CFStringRef)[[NSBundle mainBundle] bundleIdentifier];
-
- [NSApp read_defaults];
- [NSBundle loadNibNamed:@"main" owner:NSApp];
- [[NSNotificationCenter defaultCenter] addObserver:NSApp
- selector:@selector (became_key:)
- name:NSWindowDidBecomeKeyNotification object:nil];
-
- /*
- * The xpr Quartz mode is statically linked into this server.
- * Initialize all the Quartz functions.
- */
- QuartzModeBundleInit();
-
- /* Calculate the height of the menubar so we can avoid it. */
- aquaMenuBarHeight = NSHeight([[NSScreen mainScreen] frame]) -
- NSMaxY([[NSScreen mainScreen] visibleFrame]);
-
- /* Set the key layout seed before we start the server */
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
- last_key_layout = TISCopyCurrentKeyboardLayoutInputSource();
-
- if(!last_key_layout)
- fprintf(stderr, "X11ApplicationMain: Unable to determine TISCopyCurrentKeyboardLayoutInputSource() at startup.\n");
-#else
- KLGetCurrentKeyboardLayout(&last_key_layout);
- if(!last_key_layout)
- fprintf(stderr, "X11ApplicationMain: Unable to determine KLGetCurrentKeyboardLayout() at startup.\n");
-#endif
-
- if (!QuartsResyncKeymap(FALSE)) {
- fprintf(stderr, "X11ApplicationMain: Could not build a valid keymap.\n");
- }
-
- /* Tell the server thread that it can proceed */
- QuartzInitServer(argc, argv, envp);
-
- /* This must be done after QuartzInitServer because it can result in
- * an mieqEnqueue() - <rdar://problem/6300249>
- */
- check_xinitrc();
-
- create_thread(xpbproxy_x_thread, NULL);
-
-#if XQUARTZ_SPARKLE
- [[X11App controller] setup_sparkle];
- [[SUUpdater sharedUpdater] resetUpdateCycle];
-// [[SUUpdater sharedUpdater] checkForUpdates:X11App];
-#endif
-
- [pool release];
- [NSApp run];
- /* not reached */
-}
-
-@implementation X11Application (Private)
-
-#ifdef NX_DEVICELCMDKEYMASK
-/* This is to workaround a bug in the VNC server where we sometimes see the L
- * modifier and sometimes see no "side"
- */
-static inline int ensure_flag(int flags, int device_independent, int device_dependents, int device_dependent_default) {
- if( (flags & device_independent) &&
- !(flags & device_dependents))
- flags |= device_dependent_default;
- return flags;
-}
-#endif
-
-#ifdef DEBUG_UNTRUSTED_POINTER_DELTA
-static const char *untrusted_str(NSEvent *e) {
- switch([e type]) {
- case NSScrollWheel:
- return "NSScrollWheel";
- case NSTabletPoint:
- return "NSTabletPoint";
- case NSOtherMouseDown:
- return "NSOtherMouseDown";
- case NSOtherMouseUp:
- return "NSOtherMouseUp";
- case NSLeftMouseDown:
- return "NSLeftMouseDown";
- case NSLeftMouseUp:
- return "NSLeftMouseUp";
- default:
- switch([e subtype]) {
- case NSTabletPointEventSubtype:
- return "NSTabletPointEventSubtype";
- case NSTabletProximityEventSubtype:
- return "NSTabletProximityEventSubtype";
- default:
- return "Other";
- }
- }
-}
-#endif
-
-- (void) sendX11NSEvent:(NSEvent *)e {
- NSPoint location = NSZeroPoint, tilt = NSZeroPoint;
- int ev_button, ev_type;
- float pressure = 0.0;
- DeviceIntPtr pDev;
- int modifierFlags;
- BOOL isMouseOrTabletEvent, isTabletEvent;
-
- isMouseOrTabletEvent = [e type] == NSLeftMouseDown || [e type] == NSOtherMouseDown || [e type] == NSRightMouseDown ||
- [e type] == NSLeftMouseUp || [e type] == NSOtherMouseUp || [e type] == NSRightMouseUp ||
- [e type] == NSLeftMouseDragged || [e type] == NSOtherMouseDragged || [e type] == NSRightMouseDragged ||
- [e type] == NSMouseMoved || [e type] == NSTabletPoint || [e type] == NSScrollWheel;
-
- isTabletEvent = ([e type] == NSTabletPoint) ||
- (isMouseOrTabletEvent && ([e subtype] == NSTabletPointEventSubtype || [e subtype] == NSTabletProximityEventSubtype));
-
- if(isMouseOrTabletEvent) {
- static NSPoint lastpt;
- NSWindow *window = [e window];
- NSRect screen = [[[NSScreen screens] objectAtIndex:0] frame];
- BOOL hasUntrustedPointerDelta;
-
- // NSEvents for tablets are not consistent wrt deltaXY between events, so we cannot rely on that
- // Thus tablets will be subject to the warp-pointer bug worked around by the delta, but tablets
- // are not normally used in cases where that bug would present itself, so this is a fair tradeoff
- // <rdar://problem/7111003> deltaX and deltaY are incorrect for NSMouseMoved, NSTabletPointEventSubtype
- // http://xquartz.macosforge.org/trac/ticket/288
- hasUntrustedPointerDelta = isTabletEvent;
-
- // The deltaXY for middle click events also appear erroneous after fast user switching
- // <rdar://problem/7979468> deltaX and deltaY are incorrect for NSOtherMouseDown and NSOtherMouseUp after FUS
- // http://xquartz.macosforge.org/trac/ticket/389
- hasUntrustedPointerDelta = hasUntrustedPointerDelta || [e type] == NSOtherMouseDown || [e type] == NSOtherMouseUp;
-
- // The deltaXY for scroll events correspond to the scroll delta, not the pointer delta
- // <rdar://problem/7989690> deltaXY for wheel events are being sent as mouse movement
- hasUntrustedPointerDelta = hasUntrustedPointerDelta || [e type] == NSScrollWheel;
-
-#ifdef DEBUG_UNTRUSTED_POINTER_DELTA
- hasUntrustedPointerDelta = hasUntrustedPointerDelta || [e type] == NSLeftMouseDown || [e type] == NSLeftMouseUp;
-#endif
-
- if (window != nil) {
- NSRect frame = [window frame];
- location = [e locationInWindow];
- location.x += frame.origin.x;
- location.y += frame.origin.y;
- lastpt = location;
- } else if(hasUntrustedPointerDelta) {
-#ifdef DEBUG_UNTRUSTED_POINTER_DELTA
- ErrorF("--- Begin Event Debug ---\n");
- ErrorF("Event type: %s\n", untrusted_str(e));
- ErrorF("old lastpt: (%0.2f, %0.2f)\n", lastpt.x, lastpt.y);
- ErrorF(" delta: (%0.2f, %0.2f)\n", [e deltaX], -[e deltaY]);
- ErrorF(" location: (%0.2f, %0.2f)\n", lastpt.x + [e deltaX], lastpt.y - [e deltaY]);
- ErrorF("workaround: (%0.2f, %0.2f)\n", [e locationInWindow].x, [e locationInWindow].y);
- ErrorF("--- End Event Debug ---\n");
-
- location.x = lastpt.x + [e deltaX];
- location.y = lastpt.y - [e deltaY];
- lastpt = [e locationInWindow];
-#else
- location = [e locationInWindow];
- lastpt = location;
-#endif
- } else {
- location.x = lastpt.x + [e deltaX];
- location.y = lastpt.y - [e deltaY];
- lastpt = [e locationInWindow];
- }
-
- /* Convert coordinate system */
- location.y = (screen.origin.y + screen.size.height) - location.y;
- }
-
- modifierFlags = [e modifierFlags];
-
-#ifdef NX_DEVICELCMDKEYMASK
- /* This is to workaround a bug in the VNC server where we sometimes see the L
- * modifier and sometimes see no "side"
- */
- modifierFlags = ensure_flag(modifierFlags, NX_CONTROLMASK, NX_DEVICELCTLKEYMASK | NX_DEVICERCTLKEYMASK, NX_DEVICELCTLKEYMASK);
- modifierFlags = ensure_flag(modifierFlags, NX_SHIFTMASK, NX_DEVICELSHIFTKEYMASK | NX_DEVICERSHIFTKEYMASK, NX_DEVICELSHIFTKEYMASK);
- modifierFlags = ensure_flag(modifierFlags, NX_COMMANDMASK, NX_DEVICELCMDKEYMASK | NX_DEVICERCMDKEYMASK, NX_DEVICELCMDKEYMASK);
- modifierFlags = ensure_flag(modifierFlags, NX_ALTERNATEMASK, NX_DEVICELALTKEYMASK | NX_DEVICERALTKEYMASK, NX_DEVICELALTKEYMASK);
-#endif
-
- modifierFlags &= darwin_all_modifier_mask;
-
- /* 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_all_modifier_flags != modifierFlags)
- DarwinUpdateModKeys(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;
- case NSRightMouseDown: ev_button=3; ev_type=ButtonPress; goto handle_mouse;
- case NSLeftMouseUp: ev_button=1; ev_type=ButtonRelease; goto handle_mouse;
- case NSOtherMouseUp: ev_button=2; ev_type=ButtonRelease; goto handle_mouse;
- case NSRightMouseUp: ev_button=3; ev_type=ButtonRelease; goto handle_mouse;
- case NSLeftMouseDragged: ev_button=1; ev_type=MotionNotify; goto handle_mouse;
- case NSOtherMouseDragged: ev_button=2; ev_type=MotionNotify; goto handle_mouse;
- 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:
- pDev = darwinPointer;
-
- /* NSTabletPoint can have no subtype */
- if([e type] != NSTabletPoint &&
- [e subtype] == NSTabletProximityEventSubtype) {
- switch([e pointingDeviceType]) {
- case NSEraserPointingDevice:
- darwinTabletCurrent=darwinTabletEraser;
- break;
- case NSPenPointingDevice:
- darwinTabletCurrent=darwinTabletStylus;
- break;
- case NSCursorPointingDevice:
- case NSUnknownPointingDevice:
- default:
- darwinTabletCurrent=darwinTabletCursor;
- break;
- }
-
- /* NSTabletProximityEventSubtype doesn't encode pressure ant tilt
- * So we just pretend the motion was caused by the mouse. Hopefully
- * we'll have a better solution for this in the future (like maybe
- * NSTabletProximityEventSubtype will come from NSTabletPoint
- * rather than NSMouseMoved.
- pressure = [e pressure];
- tilt = [e tilt];
- pDev = darwinTabletCurrent;
- */
-
- DarwinSendProximityEvents([e isEnteringProximity] ? ProximityIn : ProximityOut,
- location.x, location.y);
- }
-
- if ([e type] == NSTabletPoint || [e subtype] == NSTabletPointEventSubtype) {
- pressure = [e pressure];
- tilt = [e tilt];
-
- pDev = darwinTabletCurrent;
- }
-
- if(!XQuartzServerVisible && noTestExtensions) {
-#if defined(XPLUGIN_VERSION) && XPLUGIN_VERSION > 0
-/* Older libXplugin (Tiger/"Stock" Leopard) aren't thread safe, so we can't call xp_find_window from the Appkit thread */
- xp_window_id wid = 0;
- xp_error e;
-
- /* Sigh. Need to check that we're really over one of
- * our windows. (We need to receive pointer events while
- * not in the foreground, but we don't want to receive them
- * when another window is over us or we might show a tooltip)
- */
-
- e = xp_find_window(location.x, location.y, 0, &wid);
-
- if (e != XP_Success || (e == XP_Success && wid == 0))
-#endif
- {
- bgMouseLocation = location;
- bgMouseLocationUpdated = TRUE;
- return;
- }
- }
-
- if(bgMouseLocationUpdated) {
- if(!(ev_type == MotionNotify && ev_button == 0)) {
- DarwinSendPointerEvents(pDev, MotionNotify, 0, location.x,
- location.y, pressure, tilt.x, tilt.y);
- }
- bgMouseLocationUpdated = FALSE;
- }
-
- DarwinSendPointerEvents(pDev, ev_type, ev_button, location.x, location.y,
- pressure, tilt.x, tilt.y);
-
- break;
-
- case NSTabletProximity:
- switch([e pointingDeviceType]) {
- case NSEraserPointingDevice:
- darwinTabletCurrent=darwinTabletEraser;
- break;
- case NSPenPointingDevice:
- darwinTabletCurrent=darwinTabletStylus;
- break;
- case NSCursorPointingDevice:
- case NSUnknownPointingDevice:
- default:
- darwinTabletCurrent=darwinTabletCursor;
- break;
- }
-
- DarwinSendProximityEvents([e isEnteringProximity] ? ProximityIn : ProximityOut,
- location.x, location.y);
- break;
-
- case NSScrollWheel:
-#if !defined(XPLUGIN_VERSION) || XPLUGIN_VERSION == 0
- /* If we're in the background, we need to send a MotionNotify event
- * first, since we aren't getting them on background mouse motion
- */
- if(!XQuartzServerVisible && noTestExtensions) {
- bgMouseLocationUpdated = FALSE;
- DarwinSendPointerEvents(darwinPointer, MotionNotify, 0, location.x,
- location.y, pressure, tilt.x, tilt.y);
- }
-#endif
- DarwinSendScrollEvents([e deltaX], [e deltaY], location.x, location.y,
- pressure, tilt.x, tilt.y);
- break;
-
- case NSKeyDown: case NSKeyUp:
- {
- /* XKB clobbers our keymap at startup, so we need to force it on the first keypress.
- * TODO: Make this less of a kludge.
- */
- static int force_resync_keymap = YES;
- if(force_resync_keymap) {
- DarwinSendDDXEvent(kXquartzReloadKeymap, 0);
- force_resync_keymap = NO;
- }
- }
-
- if(darwinSyncKeymap) {
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
- 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);
-#else
- KeyboardLayoutRef key_layout;
- KLGetCurrentKeyboardLayout(&key_layout);
- if(key_layout != last_key_layout) {
- last_key_layout = key_layout;
-#endif
- /* Update keyInfo */
- if (!QuartsResyncKeymap(TRUE)) {
- fprintf(stderr, "sendX11NSEvent: Could not build a valid keymap.\n");
- }
- }
- }
-
- /* Avoid stuck keys on context switch */
- if(keyState[[e keyCode]] == [e type])
- return;
- keyState[[e keyCode]] = [e type];
-
- DarwinSendKeyboardEvents(([e type] == NSKeyDown) ? KeyPress : KeyRelease, [e keyCode]);
- break;
-
- default: break; /* for gcc */
- }
-}
-@end
+/* X11Application.m -- subclass of NSApplication to multiplex events + + Copyright (c) 2002-2008 Apple Inc. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT + HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name(s) of the above + copyright holders shall not be used in advertising or otherwise to + promote the sale, use or other dealings in this Software without + prior written authorization. */ + +#include "sanitizedCarbon.h" + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "quartzCommon.h" + +#import "X11Application.h" + +#include "darwin.h" +#include "quartz.h" +#include "darwinEvents.h" +#include "quartzKeyboard.h" +#include "quartz.h" +#include <X11/extensions/applewmconst.h> +#include "micmap.h" +#include "exglobals.h" + +#include <mach/mach.h> +#include <unistd.h> +#include <AvailabilityMacros.h> + +#include <Xplugin.h> + +// pbproxy/pbproxy.h +extern int xpbproxy_run (void); + +#define DEFAULTS_FILE X11LIBDIR"/X11/xserver/Xquartz.plist" + +#ifndef XSERVER_VERSION +#define XSERVER_VERSION "?" +#endif + +/* Stuck modifier / button state... force release when we context switch */ +static NSEventType keyState[NUM_KEYCODES]; + +extern Bool noTestExtensions; + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 +static TISInputSourceRef last_key_layout; +#else +static KeyboardLayoutRef last_key_layout; +#endif + +extern int darwinFakeButtons; + +/* Store the mouse location while in the background, and update X11's pointer + * location when we become the foreground application + */ +static NSPoint bgMouseLocation; +static BOOL bgMouseLocationUpdated = FALSE; + +X11Application *X11App; + +CFStringRef app_prefs_domain_cfstr = NULL; + +#define ALL_KEY_MASKS (NSShiftKeyMask | NSControlKeyMask | NSAlternateKeyMask | NSCommandKeyMask) + +@interface X11Application (Private) +- (void) sendX11NSEvent:(NSEvent *)e; +@end + +@implementation X11Application + +typedef struct message_struct message; +struct message_struct { + mach_msg_header_t hdr; + SEL selector; + NSObject *arg; +}; + +static mach_port_t _port; + +/* Quartz mode initialization routine. This is often dynamically loaded + but is statically linked into this X server. */ +Bool QuartzModeBundleInit(void); + +static void init_ports (void) { + kern_return_t r; + NSPort *p; + + if (_port != MACH_PORT_NULL) return; + + r = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &_port); + if (r != KERN_SUCCESS) return; + + p = [NSMachPort portWithMachPort:_port]; + [p setDelegate:NSApp]; + [p scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; +} + +static void message_kit_thread (SEL selector, NSObject *arg) { + message msg; + kern_return_t r; + + msg.hdr.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_MAKE_SEND, 0); + msg.hdr.msgh_size = sizeof (msg); + msg.hdr.msgh_remote_port = _port; + msg.hdr.msgh_local_port = MACH_PORT_NULL; + msg.hdr.msgh_reserved = 0; + msg.hdr.msgh_id = 0; + + msg.selector = selector; + msg.arg = [arg retain]; + + r = mach_msg (&msg.hdr, MACH_SEND_MSG, msg.hdr.msgh_size, + 0, MACH_PORT_NULL, 0, MACH_PORT_NULL); + if (r != KERN_SUCCESS) + ErrorF("%s: mach_msg failed: %x\n", __FUNCTION__, r); +} + +- (void) handleMachMessage:(void *)_msg { + message *msg = _msg; + + [self performSelector:msg->selector withObject:msg->arg]; + [msg->arg release]; +} + +- (void) set_controller:obj { + if (_controller == nil) _controller = [obj retain]; +} + +- (void) dealloc { + if (_controller != nil) [_controller release]; + + if (_port != MACH_PORT_NULL) + mach_port_deallocate (mach_task_self (), _port); + + [super dealloc]; +} + +- (void) orderFrontStandardAboutPanel: (id) sender { + NSMutableDictionary *dict; + NSDictionary *infoDict; + NSString *tem; + + dict = [NSMutableDictionary dictionaryWithCapacity:3]; + infoDict = [[NSBundle mainBundle] infoDictionary]; + + [dict setObject: NSLocalizedString (@"The X Window System", @"About panel") + forKey:@"ApplicationName"]; + + tem = [infoDict objectForKey:@"CFBundleShortVersionString"]; + + [dict setObject:[NSString stringWithFormat:@"XQuartz %@", tem] + forKey:@"ApplicationVersion"]; + + [dict setObject:[NSString stringWithFormat:@"xorg-server %s", XSERVER_VERSION] + forKey:@"Version"]; + + [self orderFrontStandardAboutPanelWithOptions: dict]; +} + +- (void) activateX:(OSX_BOOL)state { + size_t i; + DEBUG_LOG("state=%d, _x_active=%d, \n", state, _x_active) + if (state) { + if(bgMouseLocationUpdated) { + DarwinSendPointerEvents(darwinPointer, MotionNotify, 0, bgMouseLocation.x, bgMouseLocation.y, 0.0, 0.0, 0.0); + bgMouseLocationUpdated = FALSE; + } + DarwinSendDDXEvent(kXquartzActivate, 0); + } else { + + if(darwin_all_modifier_flags) + DarwinUpdateModKeys(0); + for(i=0; i < NUM_KEYCODES; i++) { + if(keyState[i] == NSKeyDown) { + DarwinSendKeyboardEvents(KeyRelease, i); + keyState[i] = NSKeyUp; + } + } + + DarwinSendDDXEvent(kXquartzDeactivate, 0); + } + + _x_active = state; +} + +- (void) became_key:(NSWindow *)win { + [self activateX:NO]; +} + +- (void) sendEvent:(NSEvent *)e { + OSX_BOOL for_appkit, for_x; + + /* By default pass down the responder chain and to X. */ + for_appkit = YES; + for_x = YES; + + switch ([e type]) { + case NSLeftMouseDown: case NSRightMouseDown: case NSOtherMouseDown: + case NSLeftMouseUp: case NSRightMouseUp: case NSOtherMouseUp: + if ([e window] != nil) { + /* Pointer event has an (AppKit) window. Probably something for the kit. */ + for_x = NO; + if (_x_active) [self activateX:NO]; + } else if ([self modalWindow] == nil) { + /* Must be an X window. Tell appkit it doesn't have focus. */ + for_appkit = NO; + + if ([self isActive]) { + [self deactivate]; + if (!_x_active && quartzProcs->IsX11Window([e window], + [e windowNumber])) + [self activateX:YES]; + } + } + + /* We want to force sending to appkit if we're over the menu bar */ + if(!for_appkit) { + NSPoint NSlocation = [e locationInWindow]; + NSWindow *window = [e window]; + NSRect NSframe, NSvisibleFrame; + CGRect CGframe, CGvisibleFrame; + CGPoint CGlocation; + + if (window != nil) { + NSRect frame = [window frame]; + NSlocation.x += frame.origin.x; + NSlocation.y += frame.origin.y; + } + + NSframe = [[NSScreen mainScreen] frame]; + NSvisibleFrame = [[NSScreen mainScreen] visibleFrame]; + + CGframe = CGRectMake(NSframe.origin.x, NSframe.origin.y, + NSframe.size.width, NSframe.size.height); + CGvisibleFrame = CGRectMake(NSvisibleFrame.origin.x, + NSvisibleFrame.origin.y, + NSvisibleFrame.size.width, + NSvisibleFrame.size.height); + CGlocation = CGPointMake(NSlocation.x, NSlocation.y); + + if(CGRectContainsPoint(CGframe, CGlocation) && + !CGRectContainsPoint(CGvisibleFrame, CGlocation)) + for_appkit = YES; + } + + break; + + case NSKeyDown: case NSKeyUp: + + if(_x_active) { + static BOOL do_swallow = NO; + static int swallow_keycode; + + if([e type] == NSKeyDown) { + /* Before that though, see if there are any global + * shortcuts bound to it. */ + + if(darwinAppKitModMask & [e modifierFlags]) { + /* Override to force sending to Appkit */ + swallow_keycode = [e keyCode]; + do_swallow = YES; + for_x = NO; +#if XPLUGIN_VERSION >= 1 + } else if(XQuartzEnableKeyEquivalents && + xp_is_symbolic_hotkey_event([e eventRef])) { + swallow_keycode = [e keyCode]; + do_swallow = YES; + for_x = NO; +#endif + } else if(XQuartzEnableKeyEquivalents && + [[self mainMenu] performKeyEquivalent:e]) { + swallow_keycode = [e keyCode]; + do_swallow = YES; + for_appkit = NO; + for_x = NO; + } else if(!XQuartzIsRootless + && ([e modifierFlags] & ALL_KEY_MASKS) == (NSCommandKeyMask | NSAlternateKeyMask) + && ([e keyCode] == 0 /*a*/ || [e keyCode] == 53 /*Esc*/)) { + /* We have this here to force processing fullscreen + * toggle even if XQuartzEnableKeyEquivalents is disabled */ + swallow_keycode = [e keyCode]; + do_swallow = YES; + for_x = NO; + for_appkit = NO; + DarwinSendDDXEvent(kXquartzToggleFullscreen, 0); + } else { + /* No kit window is focused, so send it to X. */ + for_appkit = NO; + } + } else { /* KeyUp */ + /* If we saw a key equivalent on the down, don't pass + * the up through to X. */ + if (do_swallow && [e keyCode] == swallow_keycode) { + do_swallow = NO; + for_x = NO; + } + } + } else { /* !_x_active */ + for_x = NO; + } + break; + + case NSFlagsChanged: + /* Don't tell X11 about modifiers changing while it's not active */ + if (!_x_active) + for_x = NO; + break; + + case NSAppKitDefined: + switch ([e subtype]) { + case NSApplicationActivatedEventType: + for_x = NO; + if ([self modalWindow] == nil) { + BOOL order_all_windows = YES, workspaces, ok; + for_appkit = NO; + + /* FIXME: hack to avoid having to pass the event to appkit, + which would cause it to raise one of its windows. */ + _appFlags._active = YES; + + [self activateX:YES]; + + /* Get the Spaces preference for SwitchOnActivate */ + (void)CFPreferencesAppSynchronize(CFSTR("com.apple.dock")); + workspaces = CFPreferencesGetAppBooleanValue(CFSTR("workspaces"), CFSTR("com.apple.dock"), &ok); + if (!ok) + workspaces = NO; + + if (workspaces) { + (void)CFPreferencesAppSynchronize(CFSTR(".GlobalPreferences")); + order_all_windows = CFPreferencesGetAppBooleanValue(CFSTR("AppleSpacesSwitchOnActivate"), CFSTR(".GlobalPreferences"), &ok); + if (!ok) + order_all_windows = YES; + } + + /* TODO: In the workspaces && !AppleSpacesSwitchOnActivate case, the windows are ordered + * correctly, but we need to activate the top window on this space if there is + * none active. + * + * If there are no active windows, and there are minimized windows, we should + * be restoring one of them. + */ + if ([e data2] & 0x10) // 0x10 is set when we use cmd-tab or the dock icon + DarwinSendDDXEvent(kXquartzBringAllToFront, 1, order_all_windows); + } + break; + + case 18: /* ApplicationDidReactivate */ + if (XQuartzFullscreenVisible) for_appkit = NO; + break; + + case NSApplicationDeactivatedEventType: + for_x = NO; + [self activateX:NO]; + break; + } + break; + + default: break; /* for gcc */ + } + + if (for_appkit) [super sendEvent:e]; + + if (for_x) [self sendX11NSEvent:e]; +} + +- (void) set_window_menu:(NSArray *)list { + [_controller set_window_menu:list]; +} + +- (void) set_window_menu_check:(NSNumber *)n { + [_controller set_window_menu_check:n]; +} + +- (void) set_apps_menu:(NSArray *)list { + [_controller set_apps_menu:list]; +} + +- (void) set_front_process:unused { + [NSApp activateIgnoringOtherApps:YES]; + + if ([self modalWindow] == nil) + [self activateX:YES]; +} + +- (void) set_can_quit:(NSNumber *)state { + [_controller set_can_quit:[state boolValue]]; +} + +- (void) server_ready:unused { + [_controller server_ready]; +} + +- (void) show_hide_menubar:(NSNumber *)state { + /* Also shows/hides the dock */ + if ([state boolValue]) + SetSystemUIMode(kUIModeNormal, 0); + else + SetSystemUIMode(kUIModeAllHidden, XQuartzFullscreenMenu ? kUIOptionAutoShowMenuBar : 0); // kUIModeAllSuppressed or kUIOptionAutoShowMenuBar can be used to allow "mouse-activation" +} + +- (void) launch_client:(NSString *)cmd { + (void)[_controller application:self openFile:cmd]; +} + +/* user preferences */ + +/* Note that these functions only work for arrays whose elements + can be toll-free-bridged between NS and CF worlds. */ + +static const void *cfretain (CFAllocatorRef a, const void *b) { + return CFRetain (b); +} + +static void cfrelease (CFAllocatorRef a, const void *b) { + CFRelease (b); +} + +static CFMutableArrayRef nsarray_to_cfarray (NSArray *in) { + CFMutableArrayRef out; + CFArrayCallBacks cb; + NSObject *ns; + const CFTypeRef *cf; + int i, count; + + memset (&cb, 0, sizeof (cb)); + cb.version = 0; + cb.retain = cfretain; + cb.release = cfrelease; + + count = [in count]; + out = CFArrayCreateMutable (NULL, count, &cb); + + for (i = 0; i < count; i++) { + ns = [in objectAtIndex:i]; + + if ([ns isKindOfClass:[NSArray class]]) + cf = (CFTypeRef) nsarray_to_cfarray ((NSArray *) ns); + else + cf = CFRetain ((CFTypeRef) ns); + + CFArrayAppendValue (out, cf); + CFRelease (cf); + } + + return out; +} + +static NSMutableArray * cfarray_to_nsarray (CFArrayRef in) { + NSMutableArray *out; + const CFTypeRef *cf; + NSObject *ns; + int i, count; + + count = CFArrayGetCount (in); + out = [[NSMutableArray alloc] initWithCapacity:count]; + + for (i = 0; i < count; i++) { + cf = CFArrayGetValueAtIndex (in, i); + + if (CFGetTypeID (cf) == CFArrayGetTypeID ()) + ns = cfarray_to_nsarray ((CFArrayRef) cf); + else + ns = [(id)cf retain]; + + [out addObject:ns]; + [ns release]; + } + + return out; +} + +- (CFPropertyListRef) prefs_get_copy:(NSString *)key { + CFPropertyListRef value; + + value = CFPreferencesCopyAppValue ((CFStringRef) key, app_prefs_domain_cfstr); + + if (value == NULL) { + static CFDictionaryRef defaults; + + if (defaults == NULL) { + CFStringRef error = NULL; + CFDataRef data; + CFURLRef url; + SInt32 error_code; + + url = (CFURLCreateFromFileSystemRepresentation + (NULL, (unsigned char *)DEFAULTS_FILE, strlen (DEFAULTS_FILE), false)); + if (CFURLCreateDataAndPropertiesFromResource (NULL, url, &data, + NULL, NULL, &error_code)) { + defaults = (CFPropertyListCreateFromXMLData + (NULL, data, kCFPropertyListMutableContainersAndLeaves, &error)); + if (error != NULL) CFRelease (error); + CFRelease (data); + } + CFRelease (url); + + if (defaults != NULL) { + NSMutableArray *apps, *elt; + int count, i; + NSString *name, *nname; + + /* Localize the names in the default apps menu. */ + + apps = [(NSDictionary *)defaults objectForKey:@PREFS_APPSMENU]; + if (apps != nil) { + count = [apps count]; + for (i = 0; i < count; i++) { + elt = [apps objectAtIndex:i]; + if (elt != nil && [elt isKindOfClass:[NSArray class]]) { + name = [elt objectAtIndex:0]; + if (name != nil) { + nname = NSLocalizedString (name, nil); + if (nname != nil && nname != name) + [elt replaceObjectAtIndex:0 withObject:nname]; + } + } + } + } + } + } + + if (defaults != NULL) value = CFDictionaryGetValue (defaults, key); + if (value != NULL) CFRetain (value); + } + + return value; +} + +- (int) prefs_get_integer:(NSString *)key default:(int)def { + CFPropertyListRef value; + int ret; + + value = [self prefs_get_copy:key]; + + if (value != NULL && CFGetTypeID (value) == CFNumberGetTypeID ()) + CFNumberGetValue (value, kCFNumberIntType, &ret); + else if (value != NULL && CFGetTypeID (value) == CFStringGetTypeID ()) + ret = CFStringGetIntValue (value); + else + ret = def; + + if (value != NULL) CFRelease (value); + + return ret; +} + +- (const char *) prefs_get_string:(NSString *)key default:(const char *)def { + CFPropertyListRef value; + const char *ret = NULL; + + value = [self prefs_get_copy:key]; + + if (value != NULL && CFGetTypeID (value) == CFStringGetTypeID ()) { + NSString *s = (NSString *) value; + + ret = [s UTF8String]; + } + + if (value != NULL) CFRelease (value); + + return ret != NULL ? ret : def; +} + +- (NSURL *) prefs_copy_url:(NSString *)key default:(NSURL *)def { + CFPropertyListRef value; + NSURL *ret = NULL; + + value = [self prefs_get_copy:key]; + + if (value != NULL && CFGetTypeID (value) == CFStringGetTypeID ()) { + NSString *s = (NSString *) value; + + ret = [NSURL URLWithString:s]; + [ret retain]; + } + + if (value != NULL) CFRelease (value); + + return ret != NULL ? ret : def; +} + +- (float) prefs_get_float:(NSString *)key default:(float)def { + CFPropertyListRef value; + float ret = def; + + value = [self prefs_get_copy:key]; + + if (value != NULL + && CFGetTypeID (value) == CFNumberGetTypeID () + && CFNumberIsFloatType (value)) + CFNumberGetValue (value, kCFNumberFloatType, &ret); + else if (value != NULL && CFGetTypeID (value) == CFStringGetTypeID ()) + ret = CFStringGetDoubleValue (value); + + if (value != NULL) CFRelease (value); + + return ret; +} + +- (int) prefs_get_boolean:(NSString *)key default:(int)def { + CFPropertyListRef value; + int ret = def; + + value = [self prefs_get_copy:key]; + + if (value != NULL) { + if (CFGetTypeID (value) == CFNumberGetTypeID ()) + CFNumberGetValue (value, kCFNumberIntType, &ret); + else if (CFGetTypeID (value) == CFBooleanGetTypeID ()) + ret = CFBooleanGetValue (value); + else if (CFGetTypeID (value) == CFStringGetTypeID ()) { + const char *tem = [(NSString *) value UTF8String]; + if (strcasecmp (tem, "true") == 0 || strcasecmp (tem, "yes") == 0) + ret = YES; + else + ret = NO; + } + + CFRelease (value); + } + return ret; +} + +- (NSArray *) prefs_get_array:(NSString *)key { + NSArray *ret = nil; + CFPropertyListRef value; + + value = [self prefs_get_copy:key]; + + if (value != NULL) { + if (CFGetTypeID (value) == CFArrayGetTypeID ()) + ret = [cfarray_to_nsarray (value) autorelease]; + + CFRelease (value); + } + + return ret; +} + +- (void) prefs_set_integer:(NSString *)key value:(int)value { + CFNumberRef x; + + x = CFNumberCreate (NULL, kCFNumberIntType, &value); + + CFPreferencesSetValue ((CFStringRef) key, (CFTypeRef) x, app_prefs_domain_cfstr, + kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + + CFRelease (x); +} + +- (void) prefs_set_float:(NSString *)key value:(float)value { + CFNumberRef x; + + x = CFNumberCreate (NULL, kCFNumberFloatType, &value); + + CFPreferencesSetValue ((CFStringRef) key, (CFTypeRef) x, app_prefs_domain_cfstr, + kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + + CFRelease (x); +} + +- (void) prefs_set_boolean:(NSString *)key value:(int)value { + CFPreferencesSetValue ((CFStringRef) key, + (CFTypeRef) (value ? kCFBooleanTrue + : kCFBooleanFalse), app_prefs_domain_cfstr, + kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + +} + +- (void) prefs_set_array:(NSString *)key value:(NSArray *)value { + CFArrayRef cfarray; + + cfarray = nsarray_to_cfarray (value); + CFPreferencesSetValue ((CFStringRef) key, + (CFTypeRef) cfarray, + app_prefs_domain_cfstr, + kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + CFRelease (cfarray); +} + +- (void) prefs_set_string:(NSString *)key value:(NSString *)value { + CFPreferencesSetValue ((CFStringRef) key, (CFTypeRef) value, + app_prefs_domain_cfstr, kCFPreferencesCurrentUser, + kCFPreferencesAnyHost); +} + +- (void) prefs_synchronize { + CFPreferencesAppSynchronize (kCFPreferencesCurrentApplication); +} + +- (void) read_defaults +{ + NSString *nsstr; + const char *tem; + + XQuartzRootlessDefault = [self prefs_get_boolean:@PREFS_ROOTLESS + default:XQuartzRootlessDefault]; + XQuartzFullscreenMenu = [self prefs_get_boolean:@PREFS_FULLSCREEN_MENU + default:XQuartzFullscreenMenu]; + XQuartzFullscreenDisableHotkeys = ![self prefs_get_boolean:@PREFS_FULLSCREEN_HOTKEYS + default:!XQuartzFullscreenDisableHotkeys]; + darwinFakeButtons = [self prefs_get_boolean:@PREFS_FAKEBUTTONS + default:darwinFakeButtons]; + XQuartzOptionSendsAlt = [self prefs_get_boolean:@PREFS_OPTION_SENDS_ALT + default:XQuartzOptionSendsAlt]; + + if (darwinFakeButtons) { + const char *fake2, *fake3; + + fake2 = [self prefs_get_string:@PREFS_FAKE_BUTTON2 default:NULL]; + fake3 = [self prefs_get_string:@PREFS_FAKE_BUTTON3 default:NULL]; + + if (fake2 != NULL) darwinFakeMouse2Mask = DarwinParseModifierList(fake2, TRUE); + if (fake3 != NULL) darwinFakeMouse3Mask = DarwinParseModifierList(fake3, TRUE); + } + + tem = [self prefs_get_string:@PREFS_APPKIT_MODIFIERS default:NULL]; + if (tem != NULL) darwinAppKitModMask = DarwinParseModifierList(tem, TRUE); + + tem = [self prefs_get_string:@PREFS_WINDOW_ITEM_MODIFIERS default:NULL]; + if (tem != NULL) { + windowItemModMask = DarwinParseModifierList(tem, FALSE); + } else { + nsstr = NSLocalizedString (@"window item modifiers", @"window item modifiers"); + if(nsstr != NULL) { + tem = [nsstr UTF8String]; + if((tem != NULL) && strcmp(tem, "window item modifiers")) { + windowItemModMask = DarwinParseModifierList(tem, FALSE); + } + } + } + + XQuartzEnableKeyEquivalents = [self prefs_get_boolean:@PREFS_KEYEQUIVS + default:XQuartzEnableKeyEquivalents]; + + darwinSyncKeymap = [self prefs_get_boolean:@PREFS_SYNC_KEYMAP + default:darwinSyncKeymap]; + + darwinDesiredDepth = [self prefs_get_integer:@PREFS_DEPTH + default:darwinDesiredDepth]; + + noTestExtensions = ![self prefs_get_boolean:@PREFS_TEST_EXTENSIONS + default:FALSE]; + +#if XQUARTZ_SPARKLE + NSURL *url = [self prefs_copy_url:@PREFS_UPDATE_FEED default:nil]; + if(url) { + [[SUUpdater sharedUpdater] setFeedURL:url]; + [url release]; + } +#endif +} + +/* This will end up at the end of the responder chain. */ +- (void) copy:sender { + DarwinSendDDXEvent(kXquartzPasteboardNotify, 1, + AppleWMCopyToPasteboard); +} + +- (X11Controller *) controller { + return _controller; +} + +- (OSX_BOOL) x_active { + return _x_active; +} + +@end + +static NSArray * +array_with_strings_and_numbers (int nitems, const char **items, + const char *numbers) { + NSMutableArray *array, *subarray; + NSString *string, *number; + int i; + + /* (Can't autorelease on the X server thread) */ + + array = [[NSMutableArray alloc] initWithCapacity:nitems]; + + for (i = 0; i < nitems; i++) { + subarray = [[NSMutableArray alloc] initWithCapacity:2]; + + string = [[NSString alloc] initWithUTF8String:items[i]]; + [subarray addObject:string]; + [string release]; + + if (numbers[i] != 0) { + number = [[NSString alloc] initWithFormat:@"%d", numbers[i]]; + [subarray addObject:number]; + [number release]; + } else + [subarray addObject:@""]; + + [array addObject:subarray]; + [subarray release]; + } + + return array; +} + +void X11ApplicationSetWindowMenu (int nitems, const char **items, + const char *shortcuts) { + NSArray *array; + array = array_with_strings_and_numbers (nitems, items, shortcuts); + + /* Send the array of strings over to the appkit thread */ + + message_kit_thread (@selector (set_window_menu:), array); + [array release]; +} + +void X11ApplicationSetWindowMenuCheck (int idx) { + NSNumber *n; + + n = [[NSNumber alloc] initWithInt:idx]; + + message_kit_thread (@selector (set_window_menu_check:), n); + + [n release]; +} + +void X11ApplicationSetFrontProcess (void) { + message_kit_thread (@selector (set_front_process:), nil); +} + +void X11ApplicationSetCanQuit (int state) { + NSNumber *n; + + n = [[NSNumber alloc] initWithBool:state]; + + message_kit_thread (@selector (set_can_quit:), n); + + [n release]; +} + +void X11ApplicationServerReady (void) { + message_kit_thread (@selector (server_ready:), nil); +} + +void X11ApplicationShowHideMenubar (int state) { + NSNumber *n; + + n = [[NSNumber alloc] initWithBool:state]; + + message_kit_thread (@selector (show_hide_menubar:), n); + + [n release]; +} + +void X11ApplicationLaunchClient (const char *cmd) { + NSString *string; + + string = [[NSString alloc] initWithUTF8String:cmd]; + + message_kit_thread (@selector (launch_client:), string); + + [string release]; +} + +static void check_xinitrc (void) { + char *tem, buf[1024]; + NSString *msg; + + if ([X11App prefs_get_boolean:@PREFS_DONE_XINIT_CHECK default:NO]) + return; + + tem = getenv ("HOME"); + if (tem == NULL) goto done; + + snprintf (buf, sizeof (buf), "%s/.xinitrc", tem); + if (access (buf, F_OK) != 0) + goto done; + + msg = NSLocalizedString (@"You have an existing ~/.xinitrc file.\n\n\ +Windows displayed by X11 applications may not have titlebars, or may look \ +different to windows displayed by native applications.\n\n\ +Would you like to move aside the existing file and use the standard X11 \ +environment the next time you start X11?", @"Startup xinitrc dialog"); + + if(NSAlertDefaultReturn == NSRunAlertPanel (nil, msg, NSLocalizedString (@"Yes", @""), + NSLocalizedString (@"No", @""), nil)) { + char buf2[1024]; + int i = -1; + + snprintf (buf2, sizeof (buf2), "%s.old", buf); + + for(i = 1; access (buf2, F_OK) == 0; i++) + snprintf (buf2, sizeof (buf2), "%s.old.%d", buf, i); + + rename (buf, buf2); + } + + done: + [X11App prefs_set_boolean:@PREFS_DONE_XINIT_CHECK value:YES]; + [X11App prefs_synchronize]; +} + +static inline pthread_t create_thread(void *func, 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; +} + +static void *xpbproxy_x_thread(void *args) { + xpbproxy_run(); + + fprintf(stderr, "xpbproxy thread is terminating unexpectedly.\n"); + return NULL; +} + +void X11ApplicationMain (int argc, char **argv, char **envp) { + NSAutoreleasePool *pool; + +#ifdef DEBUG + while (access ("/tmp/x11-block", F_OK) == 0) sleep (1); +#endif + + pool = [[NSAutoreleasePool alloc] init]; + X11App = (X11Application *) [X11Application sharedApplication]; + init_ports (); + + app_prefs_domain_cfstr = (CFStringRef)[[NSBundle mainBundle] bundleIdentifier]; + + [NSApp read_defaults]; + [NSBundle loadNibNamed:@"main" owner:NSApp]; + [[NSNotificationCenter defaultCenter] addObserver:NSApp + selector:@selector (became_key:) + name:NSWindowDidBecomeKeyNotification object:nil]; + + /* + * The xpr Quartz mode is statically linked into this server. + * Initialize all the Quartz functions. + */ + QuartzModeBundleInit(); + + /* Calculate the height of the menubar so we can avoid it. */ + aquaMenuBarHeight = NSHeight([[NSScreen mainScreen] frame]) - + NSMaxY([[NSScreen mainScreen] visibleFrame]); + + /* Set the key layout seed before we start the server */ +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 + last_key_layout = TISCopyCurrentKeyboardLayoutInputSource(); + + if(!last_key_layout) + fprintf(stderr, "X11ApplicationMain: Unable to determine TISCopyCurrentKeyboardLayoutInputSource() at startup.\n"); +#else + KLGetCurrentKeyboardLayout(&last_key_layout); + if(!last_key_layout) + fprintf(stderr, "X11ApplicationMain: Unable to determine KLGetCurrentKeyboardLayout() at startup.\n"); +#endif + + if (!QuartsResyncKeymap(FALSE)) { + fprintf(stderr, "X11ApplicationMain: Could not build a valid keymap.\n"); + } + + /* Tell the server thread that it can proceed */ + QuartzInitServer(argc, argv, envp); + + /* This must be done after QuartzInitServer because it can result in + * an mieqEnqueue() - <rdar://problem/6300249> + */ + check_xinitrc(); + + create_thread(xpbproxy_x_thread, NULL); + +#if XQUARTZ_SPARKLE + [[X11App controller] setup_sparkle]; + [[SUUpdater sharedUpdater] resetUpdateCycle]; +// [[SUUpdater sharedUpdater] checkForUpdates:X11App]; +#endif + + [pool release]; + [NSApp run]; + /* not reached */ +} + +@implementation X11Application (Private) + +#ifdef NX_DEVICELCMDKEYMASK +/* This is to workaround a bug in the VNC server where we sometimes see the L + * modifier and sometimes see no "side" + */ +static inline int ensure_flag(int flags, int device_independent, int device_dependents, int device_dependent_default) { + if( (flags & device_independent) && + !(flags & device_dependents)) + flags |= device_dependent_default; + return flags; +} +#endif + +#ifdef DEBUG_UNTRUSTED_POINTER_DELTA +static const char *untrusted_str(NSEvent *e) { + switch([e type]) { + case NSScrollWheel: + return "NSScrollWheel"; + case NSTabletPoint: + return "NSTabletPoint"; + case NSOtherMouseDown: + return "NSOtherMouseDown"; + case NSOtherMouseUp: + return "NSOtherMouseUp"; + case NSLeftMouseDown: + return "NSLeftMouseDown"; + case NSLeftMouseUp: + return "NSLeftMouseUp"; + default: + switch([e subtype]) { + case NSTabletPointEventSubtype: + return "NSTabletPointEventSubtype"; + case NSTabletProximityEventSubtype: + return "NSTabletProximityEventSubtype"; + default: + return "Other"; + } + } +} +#endif + +- (void) sendX11NSEvent:(NSEvent *)e { + NSPoint location = NSZeroPoint, tilt = NSZeroPoint; + int ev_button, ev_type; + float pressure = 0.0; + DeviceIntPtr pDev; + int modifierFlags; + BOOL isMouseOrTabletEvent, isTabletEvent; + + isMouseOrTabletEvent = [e type] == NSLeftMouseDown || [e type] == NSOtherMouseDown || [e type] == NSRightMouseDown || + [e type] == NSLeftMouseUp || [e type] == NSOtherMouseUp || [e type] == NSRightMouseUp || + [e type] == NSLeftMouseDragged || [e type] == NSOtherMouseDragged || [e type] == NSRightMouseDragged || + [e type] == NSMouseMoved || [e type] == NSTabletPoint || [e type] == NSScrollWheel; + + isTabletEvent = ([e type] == NSTabletPoint) || + (isMouseOrTabletEvent && ([e subtype] == NSTabletPointEventSubtype || [e subtype] == NSTabletProximityEventSubtype)); + + if(isMouseOrTabletEvent) { + static NSPoint lastpt; + NSWindow *window = [e window]; + NSRect screen = [[[NSScreen screens] objectAtIndex:0] frame]; + BOOL hasUntrustedPointerDelta; + + // NSEvents for tablets are not consistent wrt deltaXY between events, so we cannot rely on that + // Thus tablets will be subject to the warp-pointer bug worked around by the delta, but tablets + // are not normally used in cases where that bug would present itself, so this is a fair tradeoff + // <rdar://problem/7111003> deltaX and deltaY are incorrect for NSMouseMoved, NSTabletPointEventSubtype + // http://xquartz.macosforge.org/trac/ticket/288 + hasUntrustedPointerDelta = isTabletEvent; + + // The deltaXY for middle click events also appear erroneous after fast user switching + // <rdar://problem/7979468> deltaX and deltaY are incorrect for NSOtherMouseDown and NSOtherMouseUp after FUS + // http://xquartz.macosforge.org/trac/ticket/389 + hasUntrustedPointerDelta = hasUntrustedPointerDelta || [e type] == NSOtherMouseDown || [e type] == NSOtherMouseUp; + + // The deltaXY for scroll events correspond to the scroll delta, not the pointer delta + // <rdar://problem/7989690> deltaXY for wheel events are being sent as mouse movement + hasUntrustedPointerDelta = hasUntrustedPointerDelta || [e type] == NSScrollWheel; + +#ifdef DEBUG_UNTRUSTED_POINTER_DELTA + hasUntrustedPointerDelta = hasUntrustedPointerDelta || [e type] == NSLeftMouseDown || [e type] == NSLeftMouseUp; +#endif + + if (window != nil) { + NSRect frame = [window frame]; + location = [e locationInWindow]; + location.x += frame.origin.x; + location.y += frame.origin.y; + lastpt = location; + } else if(hasUntrustedPointerDelta) { +#ifdef DEBUG_UNTRUSTED_POINTER_DELTA + ErrorF("--- Begin Event Debug ---\n"); + ErrorF("Event type: %s\n", untrusted_str(e)); + ErrorF("old lastpt: (%0.2f, %0.2f)\n", lastpt.x, lastpt.y); + ErrorF(" delta: (%0.2f, %0.2f)\n", [e deltaX], -[e deltaY]); + ErrorF(" location: (%0.2f, %0.2f)\n", lastpt.x + [e deltaX], lastpt.y - [e deltaY]); + ErrorF("workaround: (%0.2f, %0.2f)\n", [e locationInWindow].x, [e locationInWindow].y); + ErrorF("--- End Event Debug ---\n"); + + location.x = lastpt.x + [e deltaX]; + location.y = lastpt.y - [e deltaY]; + lastpt = [e locationInWindow]; +#else + location = [e locationInWindow]; + lastpt = location; +#endif + } else { + location.x = lastpt.x + [e deltaX]; + location.y = lastpt.y - [e deltaY]; + lastpt = [e locationInWindow]; + } + + /* Convert coordinate system */ + location.y = (screen.origin.y + screen.size.height) - location.y; + } + + modifierFlags = [e modifierFlags]; + +#ifdef NX_DEVICELCMDKEYMASK + /* This is to workaround a bug in the VNC server where we sometimes see the L + * modifier and sometimes see no "side" + */ + modifierFlags = ensure_flag(modifierFlags, NX_CONTROLMASK, NX_DEVICELCTLKEYMASK | NX_DEVICERCTLKEYMASK, NX_DEVICELCTLKEYMASK); + modifierFlags = ensure_flag(modifierFlags, NX_SHIFTMASK, NX_DEVICELSHIFTKEYMASK | NX_DEVICERSHIFTKEYMASK, NX_DEVICELSHIFTKEYMASK); + modifierFlags = ensure_flag(modifierFlags, NX_COMMANDMASK, NX_DEVICELCMDKEYMASK | NX_DEVICERCMDKEYMASK, NX_DEVICELCMDKEYMASK); + modifierFlags = ensure_flag(modifierFlags, NX_ALTERNATEMASK, NX_DEVICELALTKEYMASK | NX_DEVICERALTKEYMASK, NX_DEVICELALTKEYMASK); +#endif + + modifierFlags &= darwin_all_modifier_mask; + + /* 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_all_modifier_flags != modifierFlags) + DarwinUpdateModKeys(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; + case NSRightMouseDown: ev_button=3; ev_type=ButtonPress; goto handle_mouse; + case NSLeftMouseUp: ev_button=1; ev_type=ButtonRelease; goto handle_mouse; + case NSOtherMouseUp: ev_button=2; ev_type=ButtonRelease; goto handle_mouse; + case NSRightMouseUp: ev_button=3; ev_type=ButtonRelease; goto handle_mouse; + case NSLeftMouseDragged: ev_button=1; ev_type=MotionNotify; goto handle_mouse; + case NSOtherMouseDragged: ev_button=2; ev_type=MotionNotify; goto handle_mouse; + 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: + pDev = darwinPointer; + + /* NSTabletPoint can have no subtype */ + if([e type] != NSTabletPoint && + [e subtype] == NSTabletProximityEventSubtype) { + switch([e pointingDeviceType]) { + case NSEraserPointingDevice: + darwinTabletCurrent=darwinTabletEraser; + break; + case NSPenPointingDevice: + darwinTabletCurrent=darwinTabletStylus; + break; + case NSCursorPointingDevice: + case NSUnknownPointingDevice: + default: + darwinTabletCurrent=darwinTabletCursor; + break; + } + + /* NSTabletProximityEventSubtype doesn't encode pressure ant tilt + * So we just pretend the motion was caused by the mouse. Hopefully + * we'll have a better solution for this in the future (like maybe + * NSTabletProximityEventSubtype will come from NSTabletPoint + * rather than NSMouseMoved. + pressure = [e pressure]; + tilt = [e tilt]; + pDev = darwinTabletCurrent; + */ + + DarwinSendProximityEvents([e isEnteringProximity] ? ProximityIn : ProximityOut, + location.x, location.y); + } + + if ([e type] == NSTabletPoint || [e subtype] == NSTabletPointEventSubtype) { + pressure = [e pressure]; + tilt = [e tilt]; + + pDev = darwinTabletCurrent; + } + + if(!XQuartzServerVisible && noTestExtensions) { +#if defined(XPLUGIN_VERSION) && XPLUGIN_VERSION > 0 +/* Older libXplugin (Tiger/"Stock" Leopard) aren't thread safe, so we can't call xp_find_window from the Appkit thread */ + xp_window_id wid = 0; + xp_error e; + + /* Sigh. Need to check that we're really over one of + * our windows. (We need to receive pointer events while + * not in the foreground, but we don't want to receive them + * when another window is over us or we might show a tooltip) + */ + + e = xp_find_window(location.x, location.y, 0, &wid); + + if (e != XP_Success || (e == XP_Success && wid == 0)) +#endif + { + bgMouseLocation = location; + bgMouseLocationUpdated = TRUE; + return; + } + } + + if(bgMouseLocationUpdated) { + if(!(ev_type == MotionNotify && ev_button == 0)) { + DarwinSendPointerEvents(pDev, MotionNotify, 0, location.x, + location.y, pressure, tilt.x, tilt.y); + } + bgMouseLocationUpdated = FALSE; + } + + DarwinSendPointerEvents(pDev, ev_type, ev_button, location.x, location.y, + pressure, tilt.x, tilt.y); + + break; + + case NSTabletProximity: + switch([e pointingDeviceType]) { + case NSEraserPointingDevice: + darwinTabletCurrent=darwinTabletEraser; + break; + case NSPenPointingDevice: + darwinTabletCurrent=darwinTabletStylus; + break; + case NSCursorPointingDevice: + case NSUnknownPointingDevice: + default: + darwinTabletCurrent=darwinTabletCursor; + break; + } + + DarwinSendProximityEvents([e isEnteringProximity] ? ProximityIn : ProximityOut, + location.x, location.y); + break; + + case NSScrollWheel: +#if !defined(XPLUGIN_VERSION) || XPLUGIN_VERSION == 0 + /* If we're in the background, we need to send a MotionNotify event + * first, since we aren't getting them on background mouse motion + */ + if(!XQuartzServerVisible && noTestExtensions) { + bgMouseLocationUpdated = FALSE; + DarwinSendPointerEvents(darwinPointer, MotionNotify, 0, location.x, + location.y, pressure, tilt.x, tilt.y); + } +#endif + DarwinSendScrollEvents([e deltaX], [e deltaY], location.x, location.y, + pressure, tilt.x, tilt.y); + break; + + case NSKeyDown: case NSKeyUp: + { + /* XKB clobbers our keymap at startup, so we need to force it on the first keypress. + * TODO: Make this less of a kludge. + */ + static int force_resync_keymap = YES; + if(force_resync_keymap) { + DarwinSendDDXEvent(kXquartzReloadKeymap, 0); + force_resync_keymap = NO; + } + } + + if(darwinSyncKeymap) { +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 + 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); +#else + KeyboardLayoutRef key_layout; + KLGetCurrentKeyboardLayout(&key_layout); + if(key_layout != last_key_layout) { + last_key_layout = key_layout; +#endif + /* Update keyInfo */ + if (!QuartsResyncKeymap(TRUE)) { + fprintf(stderr, "sendX11NSEvent: Could not build a valid keymap.\n"); + } + } + } + + /* Avoid stuck keys on context switch */ + if(keyState[[e keyCode]] == [e type]) + return; + keyState[[e keyCode]] = [e type]; + + DarwinSendKeyboardEvents(([e type] == NSKeyDown) ? KeyPress : KeyRelease, [e keyCode]); + break; + + default: break; /* for gcc */ + } +} +@end diff --git a/xorg-server/hw/xquartz/X11Controller.h b/xorg-server/hw/xquartz/X11Controller.h index 65a09b8d5..9edaacdd5 100644 --- a/xorg-server/hw/xquartz/X11Controller.h +++ b/xorg-server/hw/xquartz/X11Controller.h @@ -65,7 +65,6 @@ typedef unsigned int NSUInteger; IBOutlet NSButton *fake_buttons; IBOutlet NSButton *enable_fullscreen; IBOutlet NSButton *enable_fullscreen_menu; - IBOutlet NSButton *use_sysbeep; IBOutlet NSButton *enable_keyequivs; IBOutlet NSButton *sync_keymap; IBOutlet NSButton *option_sends_alt; diff --git a/xorg-server/hw/xquartz/X11Controller.m b/xorg-server/hw/xquartz/X11Controller.m index 5502999e3..2edfb185e 100644 --- a/xorg-server/hw/xquartz/X11Controller.m +++ b/xorg-server/hw/xquartz/X11Controller.m @@ -1,844 +1,840 @@ -/* X11Controller.m -- connect the IB ui, also the NSApp delegate
-
- Copyright (c) 2002-2008 Apple Inc. All rights reserved.
-
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation files
- (the "Software"), to deal in the Software without restriction,
- including without limitation the rights to use, copy, modify, merge,
- publish, distribute, sublicense, and/or sell copies of the Software,
- and to permit persons to whom the Software is furnished to do so,
- subject to the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
- HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
-
- Except as contained in this notice, the name(s) of the above
- copyright holders shall not be used in advertising or otherwise to
- promote the sale, use or other dealings in this Software without
- prior written authorization. */
-
-#include "sanitizedCarbon.h"
-#include <AvailabilityMacros.h>
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "quartzCommon.h"
-
-#import "X11Controller.h"
-#import "X11Application.h"
-
-#include "opaque.h"
-#include "darwin.h"
-#include "darwinEvents.h"
-#include "quartz.h"
-#include "quartzKeyboard.h"
-#include <X11/extensions/applewmconst.h>
-#include "applewmExt.h"
-
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-@implementation X11Controller
-
-- (void) awakeFromNib
-{
- X11Application *xapp = NSApp;
- NSArray *array;
-
- /* Point X11Application at ourself. */
- [xapp set_controller:self];
-
- array = [xapp prefs_get_array:@PREFS_APPSMENU];
- if (array != nil)
- {
- int count;
-
- /* convert from [TITLE1 COMMAND1 TITLE2 COMMAND2 ...]
- to [[TITLE1 COMMAND1] [TITLE2 COMMAND2] ...] format. */
-
- count = [array count];
- if (count > 0
- && ![[array objectAtIndex:0] isKindOfClass:[NSArray class]])
- {
- int i;
- NSMutableArray *copy, *sub;
-
- copy = [NSMutableArray arrayWithCapacity:(count / 2)];
-
- for (i = 0; i < count / 2; i++)
- {
- sub = [[NSMutableArray alloc] initWithCapacity:3];
- [sub addObject:[array objectAtIndex:i*2]];
- [sub addObject:[array objectAtIndex:i*2+1]];
- [sub addObject:@""];
- [copy addObject:sub];
- [sub release];
- }
-
- array = copy;
- }
-
- [self set_apps_menu:array];
- }
-
- [[NSNotificationCenter defaultCenter]
- addObserver: self
- selector: @selector(apps_table_done:)
- name: NSWindowWillCloseNotification
- object: [apps_table window]];
-
- // Setup data about our Windows menu
- if(window_separator) {
- [[window_separator menu] removeItem:window_separator];
- window_separator = nil;
- }
-
- windows_menu_start = [[X11App windowsMenu] numberOfItems];
-}
-
-- (void) item_selected:sender
-{
- [NSApp activateIgnoringOtherApps:YES];
-
- DarwinSendDDXEvent(kXquartzControllerNotify, 2,
- AppleWMWindowMenuItem, [sender tag]);
-}
-
-- (void) remove_window_menu
-{
- NSMenu *menu;
- int count, i;
-
- /* Work backwards so we don't mess up the indices */
- menu = [X11App windowsMenu];
- count = [menu numberOfItems];
- for (i = count - 1; i >= windows_menu_start; i--)
- [menu removeItemAtIndex:i];
-
- count = [dock_menu indexOfItem:dock_window_separator];
- for (i = 0; i < count; i++)
- [dock_menu removeItemAtIndex:0];
-}
-
-- (void) install_window_menu:(NSArray *)list
-{
- NSMenu *menu;
- NSMenuItem *item;
- int first, count, i;
-
- menu = [X11App windowsMenu];
- first = windows_menu_start + 1;
- count = [list count];
-
- // Push a Separator
- if(count) {
- [menu addItem:[NSMenuItem separatorItem]];
- }
-
- for (i = 0; i < count; i++)
- {
- NSString *name, *shortcut;
-
- name = [[list objectAtIndex:i] objectAtIndex:0];
- shortcut = [[list objectAtIndex:i] objectAtIndex:1];
-
- if(windowItemModMask == 0 || windowItemModMask == -1)
- shortcut = @"";
-
- item = (NSMenuItem *) [menu addItemWithTitle:name action:@selector
- (item_selected:) keyEquivalent:shortcut];
- [item setKeyEquivalentModifierMask:(NSUInteger) windowItemModMask];
- [item setTarget:self];
- [item setTag:i];
- [item setEnabled:YES];
-
- item = (NSMenuItem *) [dock_menu insertItemWithTitle:name
- action:@selector
- (item_selected:) keyEquivalent:shortcut
- atIndex:i];
- [item setKeyEquivalentModifierMask:(NSUInteger) windowItemModMask];
- [item setTarget:self];
- [item setTag:i];
- [item setEnabled:YES];
- }
-
- if (checked_window_item >= 0 && checked_window_item < count)
- {
- item = (NSMenuItem *) [menu itemAtIndex:first + checked_window_item];
- [item setState:NSOnState];
- item = (NSMenuItem *) [dock_menu itemAtIndex:checked_window_item];
- [item setState:NSOnState];
- }
-}
-
-- (void) remove_apps_menu
-{
- NSMenu *menu;
- NSMenuItem *item;
- int i;
-
- if (apps == nil || apps_separator == nil) return;
-
- menu = [apps_separator menu];
-
- if (menu != nil)
- {
- for (i = [menu numberOfItems] - 1; i >= 0; i--)
- {
- item = (NSMenuItem *) [menu itemAtIndex:i];
- if ([item tag] != 0)
- [menu removeItemAtIndex:i];
- }
- }
-
- if (dock_apps_menu != nil)
- {
- for (i = [dock_apps_menu numberOfItems] - 1; i >= 0; i--)
- {
- item = (NSMenuItem *) [dock_apps_menu itemAtIndex:i];
- if ([item tag] != 0)
- [dock_apps_menu removeItemAtIndex:i];
- }
- }
-
- [apps release];
- apps = nil;
-}
-
-- (void) prepend_apps_item:(NSArray *)list index:(int)i menu:(NSMenu *)menu
-{
- NSString *title, *shortcut = @"";
- NSArray *group;
- NSMenuItem *item;
-
- group = [list objectAtIndex:i];
- title = [group objectAtIndex:0];
- if ([group count] >= 3)
- shortcut = [group objectAtIndex:2];
-
- if ([title length] != 0)
- {
- item = (NSMenuItem *) [menu insertItemWithTitle:title
- action:@selector (app_selected:)
- keyEquivalent:shortcut atIndex:0];
- [item setTarget:self];
- [item setEnabled:YES];
- }
- else
- {
- item = (NSMenuItem *) [NSMenuItem separatorItem];
- [menu insertItem:item atIndex:0];
- }
-
- [item setTag:i+1]; /* can't be zero, so add one */
-}
-
-- (void) install_apps_menu:(NSArray *)list
-{
- NSMenu *menu;
- int i, count;
-
- count = [list count];
-
- if (count == 0 || apps_separator == nil) return;
-
- menu = [apps_separator menu];
-
- for (i = count - 1; i >= 0; i--)
- {
- if (menu != nil)
- [self prepend_apps_item:list index:i menu:menu];
- if (dock_apps_menu != nil)
- [self prepend_apps_item:list index:i menu:dock_apps_menu];
- }
-
- apps = [list retain];
-}
-
-- (void) set_window_menu:(NSArray *)list
-{
- [self remove_window_menu];
- [self install_window_menu:list];
-
- DarwinSendDDXEvent(kXquartzControllerNotify, 1,
- AppleWMWindowMenuNotify);
-}
-
-- (void) set_window_menu_check:(NSNumber *)nn
-{
- NSMenu *menu;
- NSMenuItem *item;
- int first, count;
- int n = [nn intValue];
-
- menu = [X11App windowsMenu];
- first = windows_menu_start + 1;
- count = [menu numberOfItems] - first;
-
- if (checked_window_item >= 0 && checked_window_item < count)
- {
- item = (NSMenuItem *) [menu itemAtIndex:first + checked_window_item];
- [item setState:NSOffState];
- item = (NSMenuItem *) [dock_menu itemAtIndex:checked_window_item];
- [item setState:NSOffState];
- }
- if (n >= 0 && n < count)
- {
- item = (NSMenuItem *) [menu itemAtIndex:first + n];
- [item setState:NSOnState];
- item = (NSMenuItem *) [dock_menu itemAtIndex:n];
- [item setState:NSOnState];
- }
- checked_window_item = n;
-}
-
-- (void) set_apps_menu:(NSArray *)list
-{
- [self remove_apps_menu];
- [self install_apps_menu:list];
-}
-
-#ifdef XQUARTZ_SPARKLE
-- (void) setup_sparkle {
- if(check_for_updates_item)
- return; // already did it...
-
- NSMenu *menu = [x11_about_item menu];
-
- check_for_updates_item = [menu insertItemWithTitle:NSLocalizedString(@"Check for X11 Updates...", @"Check for X11 Updates...")
- action:@selector (checkForUpdates:)
- keyEquivalent:@""
- atIndex:1];
- [check_for_updates_item setTarget:[SUUpdater sharedUpdater]];
- [check_for_updates_item setEnabled:YES];
-
- // Set X11Controller as the delegate for the updater.
- [[SUUpdater sharedUpdater] setDelegate:self];
-}
-
-// Sent immediately before installing the specified update.
-- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)update {
- //[self set_can_quit:YES];
-}
-
-#endif
-
-- (void) launch_client:(NSString *)filename
-{
- int child1, child2 = 0;
- int status;
- const char *newargv[4];
- char buf[128];
- char *s;
-
- newargv[0] = [X11App prefs_get_string:@PREFS_LOGIN_SHELL default:"/bin/sh"];
- newargv[1] = "-c";
- newargv[2] = [filename UTF8String];
- newargv[3] = NULL;
-
- s = getenv("DISPLAY");
- if (s == NULL || s[0] == 0) {
- snprintf(buf, sizeof(buf), ":%s", display);
- setenv("DISPLAY", buf, TRUE);
- }
-
- /* Do the fork-twice trick to avoid having to reap zombies */
- child1 = fork();
- switch (child1) {
- case -1: /* error */
- break;
-
- case 0: /* child1 */
- child2 = fork();
-
- switch (child2) {
- int max_files, i;
-
- case -1: /* error */
- _exit(1);
-
- case 0: /* child2 */
- /* close all open files except for standard streams */
- max_files = sysconf(_SC_OPEN_MAX);
- for(i = 3; i < max_files; i++)
- close(i);
-
- /* ensure stdin is on /dev/null */
- close(0);
- open("/dev/null", O_RDONLY);
-
- execvp(newargv[0], (char **const) newargv);
- _exit(2);
-
- default: /* parent (child1) */
- _exit(0);
- }
- break;
-
- default: /* parent */
- waitpid(child1, &status, 0);
- }
-}
-
-- (void) app_selected:sender
-{
- int tag;
- NSString *item;
-
- tag = [sender tag] - 1;
- if (apps == nil || tag < 0 || tag >= [apps count])
- return;
-
- item = [[apps objectAtIndex:tag] objectAtIndex:1];
-
- [self launch_client:item];
-}
-
-- (IBAction) apps_table_show:sender
-{
- NSArray *columns;
- NSMutableArray *oldapps = nil;
-
- if (table_apps != nil)
- oldapps = table_apps;
-
- table_apps = [[NSMutableArray alloc] initWithCapacity:1];
- if(apps != nil)
- [table_apps addObjectsFromArray:apps];
-
- columns = [apps_table tableColumns];
- [[columns objectAtIndex:0] setIdentifier:@"0"];
- [[columns objectAtIndex:1] setIdentifier:@"1"];
- [[columns objectAtIndex:2] setIdentifier:@"2"];
-
- [apps_table setDataSource:self];
- [apps_table selectRowIndexes:[NSIndexSet indexSetWithIndex:0] byExtendingSelection:NO];
-
- [[apps_table window] makeKeyAndOrderFront:sender];
- [apps_table reloadData];
- if(oldapps != nil)
- [oldapps release];
-}
-
-- (IBAction) apps_table_done:sender
-{
- [apps_table deselectAll:sender]; /* flush edits? */
-
- [self remove_apps_menu];
- [self install_apps_menu:table_apps];
-
- [NSApp prefs_set_array:@PREFS_APPSMENU value:table_apps];
- [NSApp prefs_synchronize];
-
- [[apps_table window] orderOut:sender];
-
- [table_apps release];
- table_apps = nil;
-}
-
-- (IBAction) apps_table_new:sender
-{
- NSMutableArray *item;
-
- int row = [apps_table selectedRow], i;
-
- if (row < 0) row = 0;
- else row = row + 1;
-
- i = row;
- if (i > [table_apps count])
- return; /* avoid exceptions */
-
- [apps_table deselectAll:sender];
-
- item = [[NSMutableArray alloc] initWithCapacity:3];
- [item addObject:@""];
- [item addObject:@""];
- [item addObject:@""];
-
- [table_apps insertObject:item atIndex:i];
- [item release];
-
- [apps_table reloadData];
- [apps_table selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
-}
-
-- (IBAction) apps_table_duplicate:sender
-{
- int row = [apps_table selectedRow], i;
- NSObject *item;
-
- if (row < 0) {
- [self apps_table_new:sender];
- return;
- }
-
- i = row;
- if (i > [table_apps count] - 1) return; /* avoid exceptions */
-
- [apps_table deselectAll:sender];
-
- item = [[table_apps objectAtIndex:i] mutableCopy];
- [table_apps insertObject:item atIndex:i];
- [item release];
-
- [apps_table reloadData];
- [apps_table selectRowIndexes:[NSIndexSet indexSetWithIndex:row+1] byExtendingSelection:NO];
-}
-
-- (IBAction) apps_table_delete:sender
-{
- int row = [apps_table selectedRow];
-
- if (row >= 0)
- {
- int i = row;
-
- if (i > [table_apps count] - 1) return; /* avoid exceptions */
-
- [apps_table deselectAll:sender];
-
- [table_apps removeObjectAtIndex:i];
- }
-
- [apps_table reloadData];
-
- row = MIN (row, [table_apps count] - 1);
- if (row >= 0)
- [apps_table selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
-}
-
-- (NSInteger) numberOfRowsInTableView:(NSTableView *)tableView
-{
- if (table_apps == nil) return 0;
-
- return [table_apps count];
-}
-
-- (id) tableView:(NSTableView *)tableView
-objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
-{
- NSArray *item;
- int col;
-
- if (table_apps == nil) return nil;
-
- col = [[tableColumn identifier] intValue];
-
- item = [table_apps objectAtIndex:row];
- if ([item count] > col)
- return [item objectAtIndex:col];
- else
- return @"";
-}
-
-- (void) tableView:(NSTableView *)tableView setObjectValue:(id)object
- forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
-{
- NSMutableArray *item;
- int col;
-
- if (table_apps == nil) return;
-
- col = [[tableColumn identifier] intValue];
-
- item = [table_apps objectAtIndex:row];
- [item replaceObjectAtIndex:col withObject:object];
-}
-
-- (void) hide_window:sender
-{
- if ([X11App x_active])
- DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMHideWindow);
- else
- NSBeep (); /* FIXME: something here */
-}
-
-- (IBAction)bring_to_front:sender
-{
- DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMBringAllToFront);
-}
-
-- (IBAction)close_window:sender
-{
- if ([X11App x_active])
- DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMCloseWindow);
- else
- [[NSApp keyWindow] performClose:sender];
-}
-
-- (IBAction)minimize_window:sender
-{
- if ([X11App x_active])
- DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMMinimizeWindow);
- else
- [[NSApp keyWindow] performMiniaturize:sender];
-}
-
-- (IBAction)zoom_window:sender
-{
- if ([X11App x_active])
- DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMZoomWindow);
- else
- [[NSApp keyWindow] performZoom:sender];
-}
-
-- (IBAction) next_window:sender
-{
- DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMNextWindow);
-}
-
-- (IBAction) previous_window:sender
-{
- DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMPreviousWindow);
-}
-
-- (IBAction) enable_fullscreen_changed:sender {
- XQuartzRootlessDefault = ![enable_fullscreen intValue];
-
- [enable_fullscreen_menu setEnabled:!XQuartzRootlessDefault];
-
- DarwinSendDDXEvent(kXquartzSetRootless, 1, XQuartzRootlessDefault);
-
- [NSApp prefs_set_boolean:@PREFS_ROOTLESS value:XQuartzRootlessDefault];
- [NSApp prefs_synchronize];
-}
-
-- (IBAction) toggle_fullscreen:sender
-{
- DarwinSendDDXEvent(kXquartzToggleFullscreen, 0);
-}
-
-- (void) set_can_quit:(OSX_BOOL)state
-{
- can_quit = state;
-}
-
-- (IBAction)prefs_changed:sender
-{
- if(!sender)
- return;
-
- if(sender == fake_buttons) {
- darwinFakeButtons = [fake_buttons intValue];
- [NSApp prefs_set_boolean:@PREFS_FAKEBUTTONS value:darwinFakeButtons];
- } else if(sender == use_sysbeep) {
- XQuartzUseSysBeep = [use_sysbeep intValue];
- [NSApp prefs_set_boolean:@PREFS_SYSBEEP value:XQuartzUseSysBeep];
- } else if(sender == enable_keyequivs) {
- XQuartzEnableKeyEquivalents = [enable_keyequivs intValue];
- [NSApp prefs_set_boolean:@PREFS_KEYEQUIVS value:XQuartzEnableKeyEquivalents];
- } else if(sender == sync_keymap) {
- darwinSyncKeymap = [sync_keymap intValue];
- [NSApp prefs_set_boolean:@PREFS_SYNC_KEYMAP value:darwinSyncKeymap];
- } else if(sender == enable_fullscreen_menu) {
- XQuartzFullscreenMenu = [enable_fullscreen_menu intValue];
- [NSApp prefs_set_boolean:@PREFS_FULLSCREEN_MENU value:XQuartzFullscreenMenu];
- } else if(sender == option_sends_alt) {
- BOOL prev_opt_sends_alt = XQuartzOptionSendsAlt;
-
- XQuartzOptionSendsAlt = [option_sends_alt intValue];
- [NSApp prefs_set_boolean:@PREFS_OPTION_SENDS_ALT value:XQuartzOptionSendsAlt];
-
- if(prev_opt_sends_alt != XQuartzOptionSendsAlt)
- QuartsResyncKeymap(TRUE);
- } else if(sender == click_through) {
- [NSApp prefs_set_boolean:@PREFS_CLICK_THROUGH value:[click_through intValue]];
- } else if(sender == focus_follows_mouse) {
- [NSApp prefs_set_boolean:@PREFS_FFM value:[focus_follows_mouse intValue]];
- } else if(sender == focus_on_new_window) {
- [NSApp prefs_set_boolean:@PREFS_FOCUS_ON_NEW_WINDOW value:[focus_on_new_window intValue]];
- } else if(sender == enable_auth) {
- [NSApp prefs_set_boolean:@PREFS_NO_AUTH value:![enable_auth intValue]];
- } else if(sender == enable_tcp) {
- [NSApp prefs_set_boolean:@PREFS_NO_TCP value:![enable_tcp intValue]];
- } else if(sender == depth) {
- [NSApp prefs_set_integer:@PREFS_DEPTH value:[depth selectedTag]];
- } else if(sender == sync_pasteboard) {
- BOOL pbproxy_active = [sync_pasteboard intValue];
- [NSApp prefs_set_boolean:@PREFS_SYNC_PB value:pbproxy_active];
-
- [sync_pasteboard_to_clipboard setEnabled:pbproxy_active];
- [sync_pasteboard_to_primary setEnabled:pbproxy_active];
- [sync_clipboard_to_pasteboard setEnabled:pbproxy_active];
- [sync_primary_immediately setEnabled:pbproxy_active];
-
- // setEnabled doesn't do this...
- [sync_text1 setTextColor:pbproxy_active ? [NSColor controlTextColor] : [NSColor disabledControlTextColor]];
- [sync_text2 setTextColor:pbproxy_active ? [NSColor controlTextColor] : [NSColor disabledControlTextColor]];
- } else if(sender == sync_pasteboard_to_clipboard) {
- [NSApp prefs_set_boolean:@PREFS_SYNC_PB_TO_CLIPBOARD value:[sync_pasteboard_to_clipboard intValue]];
- } else if(sender == sync_pasteboard_to_primary) {
- [NSApp prefs_set_boolean:@PREFS_SYNC_PB_TO_PRIMARY value:[sync_pasteboard_to_primary intValue]];
- } else if(sender == sync_clipboard_to_pasteboard) {
- [NSApp prefs_set_boolean:@PREFS_SYNC_CLIPBOARD_TO_PB value:[sync_clipboard_to_pasteboard intValue]];
- } else if(sender == sync_primary_immediately) {
- [NSApp prefs_set_boolean:@PREFS_SYNC_PRIMARY_ON_SELECT value:[sync_primary_immediately intValue]];
- }
-
- [NSApp prefs_synchronize];
-
- DarwinSendDDXEvent(kXquartzReloadPreferences, 0);
-}
-
-- (IBAction) prefs_show:sender
-{
- BOOL pbproxy_active = [NSApp prefs_get_boolean:@PREFS_SYNC_PB default:YES];
-
- [fake_buttons setIntValue:darwinFakeButtons];
- [use_sysbeep setIntValue:XQuartzUseSysBeep];
- [enable_keyequivs setIntValue:XQuartzEnableKeyEquivalents];
- [sync_keymap setIntValue:darwinSyncKeymap];
- [option_sends_alt setIntValue:XQuartzOptionSendsAlt];
- [click_through setIntValue:[NSApp prefs_get_boolean:@PREFS_CLICK_THROUGH default:NO]];
- [focus_follows_mouse setIntValue:[NSApp prefs_get_boolean:@PREFS_FFM default:NO]];
- [focus_on_new_window setIntValue:[NSApp prefs_get_boolean:@PREFS_FOCUS_ON_NEW_WINDOW default:YES]];
-
- [enable_auth setIntValue:![NSApp prefs_get_boolean:@PREFS_NO_AUTH default:NO]];
- [enable_tcp setIntValue:![NSApp prefs_get_boolean:@PREFS_NO_TCP default:NO]];
-
- [depth selectItemAtIndex:[depth indexOfItemWithTag:[NSApp prefs_get_integer:@PREFS_DEPTH default:-1]]];
-
- [sync_pasteboard setIntValue:pbproxy_active];
- [sync_pasteboard_to_clipboard setIntValue:[NSApp prefs_get_boolean:@PREFS_SYNC_PB_TO_CLIPBOARD default:YES]];
- [sync_pasteboard_to_primary setIntValue:[NSApp prefs_get_boolean:@PREFS_SYNC_PB_TO_PRIMARY default:YES]];
- [sync_clipboard_to_pasteboard setIntValue:[NSApp prefs_get_boolean:@PREFS_SYNC_CLIPBOARD_TO_PB default:YES]];
- [sync_primary_immediately setIntValue:[NSApp prefs_get_boolean:@PREFS_SYNC_PRIMARY_ON_SELECT default:NO]];
-
- [sync_pasteboard_to_clipboard setEnabled:pbproxy_active];
- [sync_pasteboard_to_primary setEnabled:pbproxy_active];
- [sync_clipboard_to_pasteboard setEnabled:pbproxy_active];
- [sync_primary_immediately setEnabled:pbproxy_active];
-
- // setEnabled doesn't do this...
- [sync_text1 setTextColor:pbproxy_active ? [NSColor controlTextColor] : [NSColor disabledControlTextColor]];
- [sync_text2 setTextColor:pbproxy_active ? [NSColor controlTextColor] : [NSColor disabledControlTextColor]];
-
- [enable_fullscreen setIntValue:!XQuartzRootlessDefault];
- [enable_fullscreen_menu setEnabled:!XQuartzRootlessDefault];
- [enable_fullscreen_menu setIntValue:XQuartzFullscreenMenu];
-
- [prefs_panel makeKeyAndOrderFront:sender];
-}
-
-- (IBAction) quit:sender {
- DarwinSendDDXEvent(kXquartzQuit, 0);
-}
-
-- (IBAction) x11_help:sender {
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
- AHLookupAnchor((CFStringRef)NSLocalizedString(@"Mac Help", no comment), CFSTR("mchlp2276"));
-#else
- AHLookupAnchor(CFSTR("com.apple.machelp"), CFSTR("mchlp2276"));
-#endif
-}
-
-- (OSX_BOOL) validateMenuItem:(NSMenuItem *)item {
- NSMenu *menu = [item menu];
-
- if (item == toggle_fullscreen_item)
- return !XQuartzIsRootless;
- else if (menu == [X11App windowsMenu] || menu == dock_menu
- || (menu == [x11_about_item menu] && [item tag] == 42))
- return (AppleWMSelectedEvents () & AppleWMControllerNotifyMask) != 0;
- else
- return TRUE;
-}
-
-- (void) applicationDidHide:(NSNotification *)notify
-{
- DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMHideAll);
-}
-
-- (void) applicationDidUnhide:(NSNotification *)notify
-{
- DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMShowAll);
-}
-
-- (NSApplicationTerminateReply) applicationShouldTerminate:sender {
- NSString *msg;
- NSString *title;
-
- if (can_quit || [X11App prefs_get_boolean:@PREFS_NO_QUIT_ALERT default:NO])
- return NSTerminateNow;
-
- /* Make sure we're frontmost. */
- [NSApp activateIgnoringOtherApps:YES];
-
- title = NSLocalizedString(@"Do you really want to quit X11?", @"Dialog title when quitting");
- msg = NSLocalizedString(@"Any open X11 applications will stop immediately, and you will lose any unsaved changes.", @"Dialog when quitting");
-
- /* FIXME: safe to run the alert in here? Or should we return Later
- * and then run the alert on a timer? It seems to work here, so..
- */
-
- return (NSRunAlertPanel (title, msg, NSLocalizedString (@"Quit", @""),
- NSLocalizedString (@"Cancel", @""), nil)
- == NSAlertDefaultReturn) ? NSTerminateNow : NSTerminateCancel;
-}
-
-- (void) applicationWillTerminate:(NSNotification *)aNotification
-{
- unsigned remain;
- [X11App prefs_synchronize];
-
- /* shutdown the X server, it will exit () for us. */
- DarwinSendDDXEvent(kXquartzQuit, 0);
-
- /* In case it doesn't, exit anyway after a while. */
- remain = 10000000;
- while((remain = usleep(remain)) > 0);
-
- exit (1);
-}
-
-- (void) server_ready
-{
- x_list *node;
-
- finished_launching = YES;
-
- for (node = pending_apps; node != NULL; node = node->next)
- {
- NSString *filename = node->data;
- [self launch_client:filename];
- [filename release];
- }
-
- x_list_free (pending_apps);
- pending_apps = NULL;
-}
-
-- (OSX_BOOL) application:(NSApplication *)app openFile:(NSString *)filename
-{
- const char *name = [filename UTF8String];
-
- if (finished_launching)
- [self launch_client:filename];
- else if (name[0] != ':') /* ignore display names */
- pending_apps = x_list_prepend (pending_apps, [filename retain]);
-
- /* FIXME: report failures. */
- return YES;
-}
-
-@end
-
-void X11ControllerMain(int argc, char **argv, char **envp) {
- X11ApplicationMain (argc, argv, envp);
-}
+/* X11Controller.m -- connect the IB ui, also the NSApp delegate + + Copyright (c) 2002-2008 Apple Inc. All rights reserved. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT + HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name(s) of the above + copyright holders shall not be used in advertising or otherwise to + promote the sale, use or other dealings in this Software without + prior written authorization. */ + +#include "sanitizedCarbon.h" +#include <AvailabilityMacros.h> + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "quartzCommon.h" + +#import "X11Controller.h" +#import "X11Application.h" + +#include "opaque.h" +#include "darwin.h" +#include "darwinEvents.h" +#include "quartz.h" +#include "quartzKeyboard.h" +#include <X11/extensions/applewmconst.h> +#include "applewmExt.h" + +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/wait.h> + +@implementation X11Controller + +- (void) awakeFromNib +{ + X11Application *xapp = NSApp; + NSArray *array; + + /* Point X11Application at ourself. */ + [xapp set_controller:self]; + + array = [xapp prefs_get_array:@PREFS_APPSMENU]; + if (array != nil) + { + int count; + + /* convert from [TITLE1 COMMAND1 TITLE2 COMMAND2 ...] + to [[TITLE1 COMMAND1] [TITLE2 COMMAND2] ...] format. */ + + count = [array count]; + if (count > 0 + && ![[array objectAtIndex:0] isKindOfClass:[NSArray class]]) + { + int i; + NSMutableArray *copy, *sub; + + copy = [NSMutableArray arrayWithCapacity:(count / 2)]; + + for (i = 0; i < count / 2; i++) + { + sub = [[NSMutableArray alloc] initWithCapacity:3]; + [sub addObject:[array objectAtIndex:i*2]]; + [sub addObject:[array objectAtIndex:i*2+1]]; + [sub addObject:@""]; + [copy addObject:sub]; + [sub release]; + } + + array = copy; + } + + [self set_apps_menu:array]; + } + + [[NSNotificationCenter defaultCenter] + addObserver: self + selector: @selector(apps_table_done:) + name: NSWindowWillCloseNotification + object: [apps_table window]]; + + // Setup data about our Windows menu + if(window_separator) { + [[window_separator menu] removeItem:window_separator]; + window_separator = nil; + } + + windows_menu_start = [[X11App windowsMenu] numberOfItems]; +} + +- (void) item_selected:sender +{ + [NSApp activateIgnoringOtherApps:YES]; + + DarwinSendDDXEvent(kXquartzControllerNotify, 2, + AppleWMWindowMenuItem, [sender tag]); +} + +- (void) remove_window_menu +{ + NSMenu *menu; + int count, i; + + /* Work backwards so we don't mess up the indices */ + menu = [X11App windowsMenu]; + count = [menu numberOfItems]; + for (i = count - 1; i >= windows_menu_start; i--) + [menu removeItemAtIndex:i]; + + count = [dock_menu indexOfItem:dock_window_separator]; + for (i = 0; i < count; i++) + [dock_menu removeItemAtIndex:0]; +} + +- (void) install_window_menu:(NSArray *)list +{ + NSMenu *menu; + NSMenuItem *item; + int first, count, i; + + menu = [X11App windowsMenu]; + first = windows_menu_start + 1; + count = [list count]; + + // Push a Separator + if(count) { + [menu addItem:[NSMenuItem separatorItem]]; + } + + for (i = 0; i < count; i++) + { + NSString *name, *shortcut; + + name = [[list objectAtIndex:i] objectAtIndex:0]; + shortcut = [[list objectAtIndex:i] objectAtIndex:1]; + + if(windowItemModMask == 0 || windowItemModMask == -1) + shortcut = @""; + + item = (NSMenuItem *) [menu addItemWithTitle:name action:@selector + (item_selected:) keyEquivalent:shortcut]; + [item setKeyEquivalentModifierMask:(NSUInteger) windowItemModMask]; + [item setTarget:self]; + [item setTag:i]; + [item setEnabled:YES]; + + item = (NSMenuItem *) [dock_menu insertItemWithTitle:name + action:@selector + (item_selected:) keyEquivalent:shortcut + atIndex:i]; + [item setKeyEquivalentModifierMask:(NSUInteger) windowItemModMask]; + [item setTarget:self]; + [item setTag:i]; + [item setEnabled:YES]; + } + + if (checked_window_item >= 0 && checked_window_item < count) + { + item = (NSMenuItem *) [menu itemAtIndex:first + checked_window_item]; + [item setState:NSOnState]; + item = (NSMenuItem *) [dock_menu itemAtIndex:checked_window_item]; + [item setState:NSOnState]; + } +} + +- (void) remove_apps_menu +{ + NSMenu *menu; + NSMenuItem *item; + int i; + + if (apps == nil || apps_separator == nil) return; + + menu = [apps_separator menu]; + + if (menu != nil) + { + for (i = [menu numberOfItems] - 1; i >= 0; i--) + { + item = (NSMenuItem *) [menu itemAtIndex:i]; + if ([item tag] != 0) + [menu removeItemAtIndex:i]; + } + } + + if (dock_apps_menu != nil) + { + for (i = [dock_apps_menu numberOfItems] - 1; i >= 0; i--) + { + item = (NSMenuItem *) [dock_apps_menu itemAtIndex:i]; + if ([item tag] != 0) + [dock_apps_menu removeItemAtIndex:i]; + } + } + + [apps release]; + apps = nil; +} + +- (void) prepend_apps_item:(NSArray *)list index:(int)i menu:(NSMenu *)menu +{ + NSString *title, *shortcut = @""; + NSArray *group; + NSMenuItem *item; + + group = [list objectAtIndex:i]; + title = [group objectAtIndex:0]; + if ([group count] >= 3) + shortcut = [group objectAtIndex:2]; + + if ([title length] != 0) + { + item = (NSMenuItem *) [menu insertItemWithTitle:title + action:@selector (app_selected:) + keyEquivalent:shortcut atIndex:0]; + [item setTarget:self]; + [item setEnabled:YES]; + } + else + { + item = (NSMenuItem *) [NSMenuItem separatorItem]; + [menu insertItem:item atIndex:0]; + } + + [item setTag:i+1]; /* can't be zero, so add one */ +} + +- (void) install_apps_menu:(NSArray *)list +{ + NSMenu *menu; + int i, count; + + count = [list count]; + + if (count == 0 || apps_separator == nil) return; + + menu = [apps_separator menu]; + + for (i = count - 1; i >= 0; i--) + { + if (menu != nil) + [self prepend_apps_item:list index:i menu:menu]; + if (dock_apps_menu != nil) + [self prepend_apps_item:list index:i menu:dock_apps_menu]; + } + + apps = [list retain]; +} + +- (void) set_window_menu:(NSArray *)list +{ + [self remove_window_menu]; + [self install_window_menu:list]; + + DarwinSendDDXEvent(kXquartzControllerNotify, 1, + AppleWMWindowMenuNotify); +} + +- (void) set_window_menu_check:(NSNumber *)nn +{ + NSMenu *menu; + NSMenuItem *item; + int first, count; + int n = [nn intValue]; + + menu = [X11App windowsMenu]; + first = windows_menu_start + 1; + count = [menu numberOfItems] - first; + + if (checked_window_item >= 0 && checked_window_item < count) + { + item = (NSMenuItem *) [menu itemAtIndex:first + checked_window_item]; + [item setState:NSOffState]; + item = (NSMenuItem *) [dock_menu itemAtIndex:checked_window_item]; + [item setState:NSOffState]; + } + if (n >= 0 && n < count) + { + item = (NSMenuItem *) [menu itemAtIndex:first + n]; + [item setState:NSOnState]; + item = (NSMenuItem *) [dock_menu itemAtIndex:n]; + [item setState:NSOnState]; + } + checked_window_item = n; +} + +- (void) set_apps_menu:(NSArray *)list +{ + [self remove_apps_menu]; + [self install_apps_menu:list]; +} + +#ifdef XQUARTZ_SPARKLE +- (void) setup_sparkle { + if(check_for_updates_item) + return; // already did it... + + NSMenu *menu = [x11_about_item menu]; + + check_for_updates_item = [menu insertItemWithTitle:NSLocalizedString(@"Check for X11 Updates...", @"Check for X11 Updates...") + action:@selector (checkForUpdates:) + keyEquivalent:@"" + atIndex:1]; + [check_for_updates_item setTarget:[SUUpdater sharedUpdater]]; + [check_for_updates_item setEnabled:YES]; + + // Set X11Controller as the delegate for the updater. + [[SUUpdater sharedUpdater] setDelegate:self]; +} + +// Sent immediately before installing the specified update. +- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)update { + //[self set_can_quit:YES]; +} + +#endif + +- (void) launch_client:(NSString *)filename +{ + int child1, child2 = 0; + int status; + const char *newargv[4]; + char buf[128]; + char *s; + + newargv[0] = [X11App prefs_get_string:@PREFS_LOGIN_SHELL default:"/bin/sh"]; + newargv[1] = "-c"; + newargv[2] = [filename UTF8String]; + newargv[3] = NULL; + + s = getenv("DISPLAY"); + if (s == NULL || s[0] == 0) { + snprintf(buf, sizeof(buf), ":%s", display); + setenv("DISPLAY", buf, TRUE); + } + + /* Do the fork-twice trick to avoid having to reap zombies */ + child1 = fork(); + switch (child1) { + case -1: /* error */ + break; + + case 0: /* child1 */ + child2 = fork(); + + switch (child2) { + int max_files, i; + + case -1: /* error */ + _exit(1); + + case 0: /* child2 */ + /* close all open files except for standard streams */ + max_files = sysconf(_SC_OPEN_MAX); + for(i = 3; i < max_files; i++) + close(i); + + /* ensure stdin is on /dev/null */ + close(0); + open("/dev/null", O_RDONLY); + + execvp(newargv[0], (char **const) newargv); + _exit(2); + + default: /* parent (child1) */ + _exit(0); + } + break; + + default: /* parent */ + waitpid(child1, &status, 0); + } +} + +- (void) app_selected:sender +{ + int tag; + NSString *item; + + tag = [sender tag] - 1; + if (apps == nil || tag < 0 || tag >= [apps count]) + return; + + item = [[apps objectAtIndex:tag] objectAtIndex:1]; + + [self launch_client:item]; +} + +- (IBAction) apps_table_show:sender +{ + NSArray *columns; + NSMutableArray *oldapps = nil; + + if (table_apps != nil) + oldapps = table_apps; + + table_apps = [[NSMutableArray alloc] initWithCapacity:1]; + if(apps != nil) + [table_apps addObjectsFromArray:apps]; + + columns = [apps_table tableColumns]; + [[columns objectAtIndex:0] setIdentifier:@"0"]; + [[columns objectAtIndex:1] setIdentifier:@"1"]; + [[columns objectAtIndex:2] setIdentifier:@"2"]; + + [apps_table setDataSource:self]; + [apps_table selectRowIndexes:[NSIndexSet indexSetWithIndex:0] byExtendingSelection:NO]; + + [[apps_table window] makeKeyAndOrderFront:sender]; + [apps_table reloadData]; + if(oldapps != nil) + [oldapps release]; +} + +- (IBAction) apps_table_done:sender +{ + [apps_table deselectAll:sender]; /* flush edits? */ + + [self remove_apps_menu]; + [self install_apps_menu:table_apps]; + + [NSApp prefs_set_array:@PREFS_APPSMENU value:table_apps]; + [NSApp prefs_synchronize]; + + [[apps_table window] orderOut:sender]; + + [table_apps release]; + table_apps = nil; +} + +- (IBAction) apps_table_new:sender +{ + NSMutableArray *item; + + int row = [apps_table selectedRow], i; + + if (row < 0) row = 0; + else row = row + 1; + + i = row; + if (i > [table_apps count]) + return; /* avoid exceptions */ + + [apps_table deselectAll:sender]; + + item = [[NSMutableArray alloc] initWithCapacity:3]; + [item addObject:@""]; + [item addObject:@""]; + [item addObject:@""]; + + [table_apps insertObject:item atIndex:i]; + [item release]; + + [apps_table reloadData]; + [apps_table selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO]; +} + +- (IBAction) apps_table_duplicate:sender +{ + int row = [apps_table selectedRow], i; + NSObject *item; + + if (row < 0) { + [self apps_table_new:sender]; + return; + } + + i = row; + if (i > [table_apps count] - 1) return; /* avoid exceptions */ + + [apps_table deselectAll:sender]; + + item = [[table_apps objectAtIndex:i] mutableCopy]; + [table_apps insertObject:item atIndex:i]; + [item release]; + + [apps_table reloadData]; + [apps_table selectRowIndexes:[NSIndexSet indexSetWithIndex:row+1] byExtendingSelection:NO]; +} + +- (IBAction) apps_table_delete:sender +{ + int row = [apps_table selectedRow]; + + if (row >= 0) + { + int i = row; + + if (i > [table_apps count] - 1) return; /* avoid exceptions */ + + [apps_table deselectAll:sender]; + + [table_apps removeObjectAtIndex:i]; + } + + [apps_table reloadData]; + + row = MIN (row, [table_apps count] - 1); + if (row >= 0) + [apps_table selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO]; +} + +- (NSInteger) numberOfRowsInTableView:(NSTableView *)tableView +{ + if (table_apps == nil) return 0; + + return [table_apps count]; +} + +- (id) tableView:(NSTableView *)tableView +objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row +{ + NSArray *item; + int col; + + if (table_apps == nil) return nil; + + col = [[tableColumn identifier] intValue]; + + item = [table_apps objectAtIndex:row]; + if ([item count] > col) + return [item objectAtIndex:col]; + else + return @""; +} + +- (void) tableView:(NSTableView *)tableView setObjectValue:(id)object + forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row +{ + NSMutableArray *item; + int col; + + if (table_apps == nil) return; + + col = [[tableColumn identifier] intValue]; + + item = [table_apps objectAtIndex:row]; + [item replaceObjectAtIndex:col withObject:object]; +} + +- (void) hide_window:sender +{ + if ([X11App x_active]) + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMHideWindow); + else + NSBeep (); /* FIXME: something here */ +} + +- (IBAction)bring_to_front:sender +{ + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMBringAllToFront); +} + +- (IBAction)close_window:sender +{ + if ([X11App x_active]) + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMCloseWindow); + else + [[NSApp keyWindow] performClose:sender]; +} + +- (IBAction)minimize_window:sender +{ + if ([X11App x_active]) + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMMinimizeWindow); + else + [[NSApp keyWindow] performMiniaturize:sender]; +} + +- (IBAction)zoom_window:sender +{ + if ([X11App x_active]) + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMZoomWindow); + else + [[NSApp keyWindow] performZoom:sender]; +} + +- (IBAction) next_window:sender +{ + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMNextWindow); +} + +- (IBAction) previous_window:sender +{ + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMPreviousWindow); +} + +- (IBAction) enable_fullscreen_changed:sender { + XQuartzRootlessDefault = ![enable_fullscreen intValue]; + + [enable_fullscreen_menu setEnabled:!XQuartzRootlessDefault]; + + DarwinSendDDXEvent(kXquartzSetRootless, 1, XQuartzRootlessDefault); + + [NSApp prefs_set_boolean:@PREFS_ROOTLESS value:XQuartzRootlessDefault]; + [NSApp prefs_synchronize]; +} + +- (IBAction) toggle_fullscreen:sender +{ + DarwinSendDDXEvent(kXquartzToggleFullscreen, 0); +} + +- (void) set_can_quit:(OSX_BOOL)state +{ + can_quit = state; +} + +- (IBAction)prefs_changed:sender +{ + if(!sender) + return; + + if(sender == fake_buttons) { + darwinFakeButtons = [fake_buttons intValue]; + [NSApp prefs_set_boolean:@PREFS_FAKEBUTTONS value:darwinFakeButtons]; + } else if(sender == enable_keyequivs) { + XQuartzEnableKeyEquivalents = [enable_keyequivs intValue]; + [NSApp prefs_set_boolean:@PREFS_KEYEQUIVS value:XQuartzEnableKeyEquivalents]; + } else if(sender == sync_keymap) { + darwinSyncKeymap = [sync_keymap intValue]; + [NSApp prefs_set_boolean:@PREFS_SYNC_KEYMAP value:darwinSyncKeymap]; + } else if(sender == enable_fullscreen_menu) { + XQuartzFullscreenMenu = [enable_fullscreen_menu intValue]; + [NSApp prefs_set_boolean:@PREFS_FULLSCREEN_MENU value:XQuartzFullscreenMenu]; + } else if(sender == option_sends_alt) { + BOOL prev_opt_sends_alt = XQuartzOptionSendsAlt; + + XQuartzOptionSendsAlt = [option_sends_alt intValue]; + [NSApp prefs_set_boolean:@PREFS_OPTION_SENDS_ALT value:XQuartzOptionSendsAlt]; + + if(prev_opt_sends_alt != XQuartzOptionSendsAlt) + QuartsResyncKeymap(TRUE); + } else if(sender == click_through) { + [NSApp prefs_set_boolean:@PREFS_CLICK_THROUGH value:[click_through intValue]]; + } else if(sender == focus_follows_mouse) { + [NSApp prefs_set_boolean:@PREFS_FFM value:[focus_follows_mouse intValue]]; + } else if(sender == focus_on_new_window) { + [NSApp prefs_set_boolean:@PREFS_FOCUS_ON_NEW_WINDOW value:[focus_on_new_window intValue]]; + } else if(sender == enable_auth) { + [NSApp prefs_set_boolean:@PREFS_NO_AUTH value:![enable_auth intValue]]; + } else if(sender == enable_tcp) { + [NSApp prefs_set_boolean:@PREFS_NO_TCP value:![enable_tcp intValue]]; + } else if(sender == depth) { + [NSApp prefs_set_integer:@PREFS_DEPTH value:[depth selectedTag]]; + } else if(sender == sync_pasteboard) { + BOOL pbproxy_active = [sync_pasteboard intValue]; + [NSApp prefs_set_boolean:@PREFS_SYNC_PB value:pbproxy_active]; + + [sync_pasteboard_to_clipboard setEnabled:pbproxy_active]; + [sync_pasteboard_to_primary setEnabled:pbproxy_active]; + [sync_clipboard_to_pasteboard setEnabled:pbproxy_active]; + [sync_primary_immediately setEnabled:pbproxy_active]; + + // setEnabled doesn't do this... + [sync_text1 setTextColor:pbproxy_active ? [NSColor controlTextColor] : [NSColor disabledControlTextColor]]; + [sync_text2 setTextColor:pbproxy_active ? [NSColor controlTextColor] : [NSColor disabledControlTextColor]]; + } else if(sender == sync_pasteboard_to_clipboard) { + [NSApp prefs_set_boolean:@PREFS_SYNC_PB_TO_CLIPBOARD value:[sync_pasteboard_to_clipboard intValue]]; + } else if(sender == sync_pasteboard_to_primary) { + [NSApp prefs_set_boolean:@PREFS_SYNC_PB_TO_PRIMARY value:[sync_pasteboard_to_primary intValue]]; + } else if(sender == sync_clipboard_to_pasteboard) { + [NSApp prefs_set_boolean:@PREFS_SYNC_CLIPBOARD_TO_PB value:[sync_clipboard_to_pasteboard intValue]]; + } else if(sender == sync_primary_immediately) { + [NSApp prefs_set_boolean:@PREFS_SYNC_PRIMARY_ON_SELECT value:[sync_primary_immediately intValue]]; + } + + [NSApp prefs_synchronize]; + + DarwinSendDDXEvent(kXquartzReloadPreferences, 0); +} + +- (IBAction) prefs_show:sender +{ + BOOL pbproxy_active = [NSApp prefs_get_boolean:@PREFS_SYNC_PB default:YES]; + + [fake_buttons setIntValue:darwinFakeButtons]; + [enable_keyequivs setIntValue:XQuartzEnableKeyEquivalents]; + [sync_keymap setIntValue:darwinSyncKeymap]; + [option_sends_alt setIntValue:XQuartzOptionSendsAlt]; + [click_through setIntValue:[NSApp prefs_get_boolean:@PREFS_CLICK_THROUGH default:NO]]; + [focus_follows_mouse setIntValue:[NSApp prefs_get_boolean:@PREFS_FFM default:NO]]; + [focus_on_new_window setIntValue:[NSApp prefs_get_boolean:@PREFS_FOCUS_ON_NEW_WINDOW default:YES]]; + + [enable_auth setIntValue:![NSApp prefs_get_boolean:@PREFS_NO_AUTH default:NO]]; + [enable_tcp setIntValue:![NSApp prefs_get_boolean:@PREFS_NO_TCP default:NO]]; + + [depth selectItemAtIndex:[depth indexOfItemWithTag:[NSApp prefs_get_integer:@PREFS_DEPTH default:-1]]]; + + [sync_pasteboard setIntValue:pbproxy_active]; + [sync_pasteboard_to_clipboard setIntValue:[NSApp prefs_get_boolean:@PREFS_SYNC_PB_TO_CLIPBOARD default:YES]]; + [sync_pasteboard_to_primary setIntValue:[NSApp prefs_get_boolean:@PREFS_SYNC_PB_TO_PRIMARY default:YES]]; + [sync_clipboard_to_pasteboard setIntValue:[NSApp prefs_get_boolean:@PREFS_SYNC_CLIPBOARD_TO_PB default:YES]]; + [sync_primary_immediately setIntValue:[NSApp prefs_get_boolean:@PREFS_SYNC_PRIMARY_ON_SELECT default:NO]]; + + [sync_pasteboard_to_clipboard setEnabled:pbproxy_active]; + [sync_pasteboard_to_primary setEnabled:pbproxy_active]; + [sync_clipboard_to_pasteboard setEnabled:pbproxy_active]; + [sync_primary_immediately setEnabled:pbproxy_active]; + + // setEnabled doesn't do this... + [sync_text1 setTextColor:pbproxy_active ? [NSColor controlTextColor] : [NSColor disabledControlTextColor]]; + [sync_text2 setTextColor:pbproxy_active ? [NSColor controlTextColor] : [NSColor disabledControlTextColor]]; + + [enable_fullscreen setIntValue:!XQuartzRootlessDefault]; + [enable_fullscreen_menu setEnabled:!XQuartzRootlessDefault]; + [enable_fullscreen_menu setIntValue:XQuartzFullscreenMenu]; + + [prefs_panel makeKeyAndOrderFront:sender]; +} + +- (IBAction) quit:sender { + DarwinSendDDXEvent(kXquartzQuit, 0); +} + +- (IBAction) x11_help:sender { +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 + AHLookupAnchor((CFStringRef)NSLocalizedString(@"Mac Help", no comment), CFSTR("mchlp2276")); +#else + AHLookupAnchor(CFSTR("com.apple.machelp"), CFSTR("mchlp2276")); +#endif +} + +- (OSX_BOOL) validateMenuItem:(NSMenuItem *)item { + NSMenu *menu = [item menu]; + + if (item == toggle_fullscreen_item) + return !XQuartzIsRootless; + else if (menu == [X11App windowsMenu] || menu == dock_menu + || (menu == [x11_about_item menu] && [item tag] == 42)) + return (AppleWMSelectedEvents () & AppleWMControllerNotifyMask) != 0; + else + return TRUE; +} + +- (void) applicationDidHide:(NSNotification *)notify +{ + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMHideAll); +} + +- (void) applicationDidUnhide:(NSNotification *)notify +{ + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMShowAll); +} + +- (NSApplicationTerminateReply) applicationShouldTerminate:sender { + NSString *msg; + NSString *title; + + if (can_quit || [X11App prefs_get_boolean:@PREFS_NO_QUIT_ALERT default:NO]) + return NSTerminateNow; + + /* Make sure we're frontmost. */ + [NSApp activateIgnoringOtherApps:YES]; + + title = NSLocalizedString(@"Do you really want to quit X11?", @"Dialog title when quitting"); + msg = NSLocalizedString(@"Any open X11 applications will stop immediately, and you will lose any unsaved changes.", @"Dialog when quitting"); + + /* FIXME: safe to run the alert in here? Or should we return Later + * and then run the alert on a timer? It seems to work here, so.. + */ + + return (NSRunAlertPanel (title, msg, NSLocalizedString (@"Quit", @""), + NSLocalizedString (@"Cancel", @""), nil) + == NSAlertDefaultReturn) ? NSTerminateNow : NSTerminateCancel; +} + +- (void) applicationWillTerminate:(NSNotification *)aNotification +{ + unsigned remain; + [X11App prefs_synchronize]; + + /* shutdown the X server, it will exit () for us. */ + DarwinSendDDXEvent(kXquartzQuit, 0); + + /* In case it doesn't, exit anyway after a while. */ + remain = 10000000; + while((remain = usleep(remain)) > 0); + + exit (1); +} + +- (void) server_ready +{ + x_list *node; + + finished_launching = YES; + + for (node = pending_apps; node != NULL; node = node->next) + { + NSString *filename = node->data; + [self launch_client:filename]; + [filename release]; + } + + x_list_free (pending_apps); + pending_apps = NULL; +} + +- (OSX_BOOL) application:(NSApplication *)app openFile:(NSString *)filename +{ + const char *name = [filename UTF8String]; + + if (finished_launching) + [self launch_client:filename]; + else if (name[0] != ':') /* ignore display names */ + pending_apps = x_list_prepend (pending_apps, [filename retain]); + + /* FIXME: report failures. */ + return YES; +} + +@end + +void X11ControllerMain(int argc, char **argv, char **envp) { + X11ApplicationMain (argc, argv, envp); +} diff --git a/xorg-server/hw/xquartz/bundle/Resources/English.lproj/main.nib/designable.nib b/xorg-server/hw/xquartz/bundle/Resources/English.lproj/main.nib/designable.nib index 7609393ba..bbf7eda62 100644 --- a/xorg-server/hw/xquartz/bundle/Resources/English.lproj/main.nib/designable.nib +++ b/xorg-server/hw/xquartz/bundle/Resources/English.lproj/main.nib/designable.nib @@ -2,19 +2,22 @@ <archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00"> <data> <int key="IBDocument.SystemTarget">1040</int> - <string key="IBDocument.SystemVersion">10D573</string> - <string key="IBDocument.InterfaceBuilderVersion">761</string> - <string key="IBDocument.AppKitVersion">1038.29</string> - <string key="IBDocument.HIToolboxVersion">460.00</string> + <string key="IBDocument.SystemVersion">10J541</string> + <string key="IBDocument.InterfaceBuilderVersion">850</string> + <string key="IBDocument.AppKitVersion">1038.35</string> + <string key="IBDocument.HIToolboxVersion">462.00</string> <object class="NSMutableDictionary" key="IBDocument.PluginVersions"> <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string> - <string key="NS.object.0">761</string> + <string key="NS.object.0">850</string> </object> <array class="NSMutableArray" key="IBDocument.EditedObjectIDs"/> <array key="IBDocument.PluginDependencies"> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> </array> - <dictionary class="NSMutableDictionary" key="IBDocument.Metadata"/> + <object class="NSMutableDictionary" key="IBDocument.Metadata"> + <string key="NS.key.0">PluginDependencyRecalculationVersion</string> + <integer value="1" key="NS.object.0"/> + </object> <array class="NSMutableArray" key="IBDocument.RootObjects" id="904585544"> <object class="NSCustomObject" id="815810918"> <object class="NSMutableString" key="NSClassName"> @@ -388,7 +391,7 @@ <characters key="NS.bytes">1</characters> </object> <object class="NSView" key="NSView" id="596750588"> - <reference key="NSNextResponder" ref="448510093"/> + <nil key="NSNextResponder"/> <int key="NSvFlags">256</int> <array class="NSMutableArray" key="NSSubviews"> <object class="NSButton" id="119157981"> @@ -396,7 +399,6 @@ <int key="NSvFlags">256</int> <string key="NSFrame">{{18, 210}, {402, 18}}</string> <reference key="NSSuperview" ref="596750588"/> - <reference key="NSWindow"/> <bool key="NSEnabled">YES</bool> <object class="NSButtonCell" key="NSCell" id="990762273"> <int key="NSCellFlags">67239424</int> @@ -424,7 +426,6 @@ <int key="NSvFlags">256</int> <string key="NSFrame">{{36, 60}, {385, 31}}</string> <reference key="NSSuperview" ref="596750588"/> - <reference key="NSWindow"/> <bool key="NSEnabled">YES</bool> <object class="NSTextFieldCell" key="NSCell" id="391919450"> <int key="NSCellFlags">67239424</int> @@ -461,7 +462,6 @@ <int key="NSvFlags">256</int> <string key="NSFrame">{{36, 162}, {385, 42}}</string> <reference key="NSSuperview" ref="596750588"/> - <reference key="NSWindow"/> <bool key="NSEnabled">YES</bool> <object class="NSTextFieldCell" key="NSCell" id="649334366"> <int key="NSCellFlags">67239424</int> @@ -479,7 +479,6 @@ IG9yIHJpZ2h0IG1vdXNlIGJ1dHRvbnMuCg</string> <int key="NSvFlags">256</int> <string key="NSFrame">{{18, 97}, {402, 18}}</string> <reference key="NSSuperview" ref="596750588"/> - <reference key="NSWindow"/> <bool key="NSEnabled">YES</bool> <object class="NSButtonCell" key="NSCell" id="940564599"> <int key="NSCellFlags">67239424</int> @@ -501,7 +500,6 @@ IG9yIHJpZ2h0IG1vdXNlIGJ1dHRvbnMuCg</string> <int key="NSvFlags">256</int> <string key="NSFrame">{{36, 126}, {385, 14}}</string> <reference key="NSSuperview" ref="596750588"/> - <reference key="NSWindow"/> <bool key="NSEnabled">YES</bool> <object class="NSTextFieldCell" key="NSCell" id="666057093"> <int key="NSCellFlags">67239424</int> @@ -518,7 +516,6 @@ IG9yIHJpZ2h0IG1vdXNlIGJ1dHRvbnMuCg</string> <int key="NSvFlags">256</int> <string key="NSFrame">{{18, 146}, {402, 18}}</string> <reference key="NSSuperview" ref="596750588"/> - <reference key="NSWindow"/> <bool key="NSEnabled">YES</bool> <object class="NSButtonCell" key="NSCell" id="967619578"> <int key="NSCellFlags">67239424</int> @@ -540,7 +537,6 @@ IG9yIHJpZ2h0IG1vdXNlIGJ1dHRvbnMuCg</string> <int key="NSvFlags">256</int> <string key="NSFrame">{{36, -1}, {385, 31}}</string> <reference key="NSSuperview" ref="596750588"/> - <reference key="NSWindow"/> <bool key="NSEnabled">YES</bool> <object class="NSTextFieldCell" key="NSCell" id="617441821"> <int key="NSCellFlags">67239424</int> @@ -557,7 +553,6 @@ IG9yIHJpZ2h0IG1vdXNlIGJ1dHRvbnMuCg</string> <int key="NSvFlags">256</int> <string key="NSFrame">{{18, 36}, {402, 18}}</string> <reference key="NSSuperview" ref="596750588"/> - <reference key="NSWindow"/> <bool key="NSEnabled">YES</bool> <object class="NSButtonCell" key="NSCell" id="67728988"> <int key="NSCellFlags">67239424</int> @@ -576,8 +571,6 @@ IG9yIHJpZ2h0IG1vdXNlIGJ1dHRvbnMuCg</string> </object> </array> <string key="NSFrame">{{10, 33}, {438, 246}}</string> - <reference key="NSSuperview" ref="448510093"/> - <reference key="NSWindow"/> </object> <string key="NSLabel">Input</string> <reference key="NSColor" ref="57160303"/> @@ -588,51 +581,15 @@ IG9yIHJpZ2h0IG1vdXNlIGJ1dHRvbnMuCg</string> <characters key="NS.bytes">2</characters> </object> <object class="NSView" key="NSView" id="515308735"> - <nil key="NSNextResponder"/> + <reference key="NSNextResponder" ref="448510093"/> <int key="NSvFlags">256</int> <array class="NSMutableArray" key="NSSubviews"> - <object class="NSButton" id="418227126"> - <reference key="NSNextResponder" ref="515308735"/> - <int key="NSvFlags">256</int> - <string key="NSFrame">{{18, 63}, {402, 18}}</string> - <reference key="NSSuperview" ref="515308735"/> - <bool key="NSEnabled">YES</bool> - <object class="NSButtonCell" key="NSCell" id="1016069354"> - <int key="NSCellFlags">67239424</int> - <int key="NSCellFlags2">0</int> - <string key="NSContents">Use system alert effect</string> - <reference key="NSSupport" ref="463863101"/> - <reference key="NSControlView" ref="418227126"/> - <int key="NSButtonFlags">1211912703</int> - <int key="NSButtonFlags2">2</int> - <reference key="NSAlternateImage" ref="391434389"/> - <string key="NSAlternateContents"/> - <string key="NSKeyEquivalent"/> - <int key="NSPeriodicDelay">200</int> - <int key="NSPeriodicInterval">25</int> - </object> - </object> - <object class="NSTextField" id="1039016593"> - <reference key="NSNextResponder" ref="515308735"/> - <int key="NSvFlags">256</int> - <string key="NSFrame">{{36, 29}, {385, 28}}</string> - <reference key="NSSuperview" ref="515308735"/> - <bool key="NSEnabled">YES</bool> - <object class="NSTextFieldCell" key="NSCell" id="624655599"> - <int key="NSCellFlags">67239424</int> - <int key="NSCellFlags2">4194304</int> - <string key="NSContents">X11 beeps will use the standard system alert, as defined in the Sound Effects system preferences panel.</string> - <reference key="NSSupport" ref="26"/> - <reference key="NSControlView" ref="1039016593"/> - <reference key="NSBackgroundColor" ref="57160303"/> - <reference key="NSTextColor" ref="930815747"/> - </object> - </object> <object class="NSPopUpButton" id="709074847"> <reference key="NSNextResponder" ref="515308735"/> <int key="NSvFlags">256</int> <string key="NSFrame">{{74, 202}, {128, 26}}</string> <reference key="NSSuperview" ref="515308735"/> + <reference key="NSWindow"/> <bool key="NSEnabled">YES</bool> <object class="NSPopUpButtonCell" key="NSCell" id="633115429"> <int key="NSCellFlags">-2076049856</int> @@ -723,6 +680,7 @@ IG9yIHJpZ2h0IG1vdXNlIGJ1dHRvbnMuCg</string> <int key="NSvFlags">256</int> <string key="NSFrame">{{17, 205}, {55, 20}}</string> <reference key="NSSuperview" ref="515308735"/> + <reference key="NSWindow"/> <bool key="NSEnabled">YES</bool> <object class="NSTextFieldCell" key="NSCell" id="930265681"> <int key="NSCellFlags">67239424</int> @@ -739,6 +697,7 @@ IG9yIHJpZ2h0IG1vdXNlIGJ1dHRvbnMuCg</string> <int key="NSvFlags">256</int> <string key="NSFrame">{{36, 183}, {392, 14}}</string> <reference key="NSSuperview" ref="515308735"/> + <reference key="NSWindow"/> <bool key="NSEnabled">YES</bool> <object class="NSTextFieldCell" key="NSCell" id="311969422"> <int key="NSCellFlags">67239424</int> @@ -755,6 +714,7 @@ IG9yIHJpZ2h0IG1vdXNlIGJ1dHRvbnMuCg</string> <int key="NSvFlags">256</int> <string key="NSFrame">{{18, 149}, {409, 23}}</string> <reference key="NSSuperview" ref="515308735"/> + <reference key="NSWindow"/> <bool key="NSEnabled">YES</bool> <object class="NSButtonCell" key="NSCell" id="631531164"> <int key="NSCellFlags">67239424</int> @@ -776,6 +736,7 @@ IG9yIHJpZ2h0IG1vdXNlIGJ1dHRvbnMuCg</string> <int key="NSvFlags">256</int> <string key="NSFrame">{{37, 83}, {409, 23}}</string> <reference key="NSSuperview" ref="515308735"/> + <reference key="NSWindow"/> <bool key="NSEnabled">YES</bool> <object class="NSButtonCell" key="NSCell" id="917248662"> <int key="NSCellFlags">67239424</int> @@ -797,6 +758,7 @@ IG9yIHJpZ2h0IG1vdXNlIGJ1dHRvbnMuCg</string> <int key="NSvFlags">256</int> <string key="NSFrame">{{36, 112}, {385, 31}}</string> <reference key="NSSuperview" ref="515308735"/> + <reference key="NSWindow"/> <bool key="NSEnabled">YES</bool> <object class="NSTextFieldCell" key="NSCell" id="761107402"> <int key="NSCellFlags">67239424</int> @@ -810,6 +772,8 @@ IG9yIHJpZ2h0IG1vdXNlIGJ1dHRvbnMuCg</string> </object> </array> <string key="NSFrame">{{10, 33}, {438, 246}}</string> + <reference key="NSSuperview" ref="448510093"/> + <reference key="NSWindow"/> </object> <string key="NSLabel">Output</string> <reference key="NSColor" ref="57160303"/> @@ -1212,13 +1176,13 @@ IG9yIHJpZ2h0IG1vdXNlIGJ1dHRvbnMuCg</string> <reference key="NSTabView" ref="448510093"/> </object> </array> - <reference key="NSSelectedTabViewItem" ref="287591690"/> + <reference key="NSSelectedTabViewItem" ref="960678392"/> <reference key="NSFont" ref="463863101"/> <int key="NSTvFlags">0</int> <bool key="NSAllowTruncatedLabels">YES</bool> <bool key="NSDrawsBackground">YES</bool> <array class="NSMutableArray" key="NSSubviews"> - <reference ref="596750588"/> + <reference ref="515308735"/> </array> </object> </array> @@ -1734,14 +1698,6 @@ IG9yIHJpZ2h0IG1vdXNlIGJ1dHRvbnMuCg</string> </object> <object class="IBConnectionRecord"> <object class="IBOutletConnection" key="connection"> - <string key="label">use_sysbeep</string> - <reference key="source" ref="485884620"/> - <reference key="destination" ref="418227126"/> - </object> - <int key="connectionID">390</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBOutletConnection" key="connection"> <string key="label">fake_buttons</string> <reference key="source" ref="485884620"/> <reference key="destination" ref="119157981"/> @@ -1792,14 +1748,6 @@ IG9yIHJpZ2h0IG1vdXNlIGJ1dHRvbnMuCg</string> <object class="IBActionConnection" key="connection"> <string key="label">prefs_changed:</string> <reference key="source" ref="485884620"/> - <reference key="destination" ref="418227126"/> - </object> - <int key="connectionID">397</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">prefs_changed:</string> - <reference key="source" ref="485884620"/> <reference key="destination" ref="709074847"/> </object> <int key="connectionID">398</int> @@ -2547,28 +2495,10 @@ IG9yIHJpZ2h0IG1vdXNlIGJ1dHRvbnMuCg</string> <reference ref="477203622"/> <reference ref="57246850"/> <reference ref="298603383"/> - <reference ref="418227126"/> - <reference ref="1039016593"/> </array> <reference key="parent" ref="960678392"/> </object> <object class="IBObjectRecord"> - <int key="objectID">371</int> - <reference key="object" ref="418227126"/> - <array class="NSMutableArray" key="children"> - <reference ref="1016069354"/> - </array> - <reference key="parent" ref="515308735"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">372</int> - <reference key="object" ref="1039016593"/> - <array class="NSMutableArray" key="children"> - <reference ref="624655599"/> - </array> - <reference key="parent" ref="515308735"/> - </object> - <object class="IBObjectRecord"> <int key="objectID">382</int> <reference key="object" ref="709074847"/> <array class="NSMutableArray" key="children"> @@ -2761,16 +2691,6 @@ IG9yIHJpZ2h0IG1vdXNlIGJ1dHRvbnMuCg</string> <reference key="parent" ref="179949713"/> </object> <object class="IBObjectRecord"> - <int key="objectID">100371</int> - <reference key="object" ref="1016069354"/> - <reference key="parent" ref="418227126"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">100372</int> - <reference key="object" ref="624655599"/> - <reference key="parent" ref="1039016593"/> - </object> - <object class="IBObjectRecord"> <int key="objectID">100382</int> <reference key="object" ref="633115429"/> <array class="NSMutableArray" key="children"> @@ -3249,8 +3169,6 @@ IG9yIHJpZ2h0IG1vdXNlIGJ1dHRvbnMuCg</string> <string key="100368.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="100369.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="100370.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <string key="100371.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <string key="100372.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="100374.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="100375.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="100376.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> @@ -3443,10 +3361,6 @@ IG9yIHJpZ2h0IG1vdXNlIGJ1dHRvbnMuCg</string> <integer value="1" key="369.ImportedFromIB2"/> <string key="370.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1" key="370.ImportedFromIB2"/> - <string key="371.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1" key="371.ImportedFromIB2"/> - <string key="372.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <integer value="1" key="372.ImportedFromIB2"/> <string key="374.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1" key="374.ImportedFromIB2"/> <string key="375.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> @@ -3582,6 +3496,76 @@ IG9yIHJpZ2h0IG1vdXNlIGJ1dHRvbnMuCg</string> <string key="x11_help:">id</string> <string key="zoom_window:">id</string> </dictionary> + <dictionary class="NSMutableDictionary" key="actionInfosByName"> + <object class="IBActionInfo" key="apps_table_delete:"> + <string key="name">apps_table_delete:</string> + <string key="candidateClassName">id</string> + </object> + <object class="IBActionInfo" key="apps_table_done:"> + <string key="name">apps_table_done:</string> + <string key="candidateClassName">id</string> + </object> + <object class="IBActionInfo" key="apps_table_duplicate:"> + <string key="name">apps_table_duplicate:</string> + <string key="candidateClassName">id</string> + </object> + <object class="IBActionInfo" key="apps_table_new:"> + <string key="name">apps_table_new:</string> + <string key="candidateClassName">id</string> + </object> + <object class="IBActionInfo" key="apps_table_show:"> + <string key="name">apps_table_show:</string> + <string key="candidateClassName">id</string> + </object> + <object class="IBActionInfo" key="bring_to_front:"> + <string key="name">bring_to_front:</string> + <string key="candidateClassName">id</string> + </object> + <object class="IBActionInfo" key="close_window:"> + <string key="name">close_window:</string> + <string key="candidateClassName">id</string> + </object> + <object class="IBActionInfo" key="enable_fullscreen_changed:"> + <string key="name">enable_fullscreen_changed:</string> + <string key="candidateClassName">id</string> + </object> + <object class="IBActionInfo" key="minimize_window:"> + <string key="name">minimize_window:</string> + <string key="candidateClassName">id</string> + </object> + <object class="IBActionInfo" key="next_window:"> + <string key="name">next_window:</string> + <string key="candidateClassName">id</string> + </object> + <object class="IBActionInfo" key="prefs_changed:"> + <string key="name">prefs_changed:</string> + <string key="candidateClassName">id</string> + </object> + <object class="IBActionInfo" key="prefs_show:"> + <string key="name">prefs_show:</string> + <string key="candidateClassName">id</string> + </object> + <object class="IBActionInfo" key="previous_window:"> + <string key="name">previous_window:</string> + <string key="candidateClassName">id</string> + </object> + <object class="IBActionInfo" key="quit:"> + <string key="name">quit:</string> + <string key="candidateClassName">id</string> + </object> + <object class="IBActionInfo" key="toggle_fullscreen:"> + <string key="name">toggle_fullscreen:</string> + <string key="candidateClassName">id</string> + </object> + <object class="IBActionInfo" key="x11_help:"> + <string key="name">x11_help:</string> + <string key="candidateClassName">id</string> + </object> + <object class="IBActionInfo" key="zoom_window:"> + <string key="name">zoom_window:</string> + <string key="candidateClassName">id</string> + </object> + </dictionary> <dictionary class="NSMutableDictionary" key="outlets"> <string key="apps_separator">NSMenuItem</string> <string key="apps_table">NSTableView</string> @@ -3614,6 +3598,128 @@ IG9yIHJpZ2h0IG1vdXNlIGJ1dHRvbnMuCg</string> <string key="window_separator">NSMenuItem</string> <string key="x11_about_item">NSMenuItem</string> </dictionary> + <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName"> + <object class="IBToOneOutletInfo" key="apps_separator"> + <string key="name">apps_separator</string> + <string key="candidateClassName">NSMenuItem</string> + </object> + <object class="IBToOneOutletInfo" key="apps_table"> + <string key="name">apps_table</string> + <string key="candidateClassName">NSTableView</string> + </object> + <object class="IBToOneOutletInfo" key="click_through"> + <string key="name">click_through</string> + <string key="candidateClassName">NSButton</string> + </object> + <object class="IBToOneOutletInfo" key="copy_menu_item"> + <string key="name">copy_menu_item</string> + <string key="candidateClassName">NSMenuItem</string> + </object> + <object class="IBToOneOutletInfo" key="depth"> + <string key="name">depth</string> + <string key="candidateClassName">NSPopUpButton</string> + </object> + <object class="IBToOneOutletInfo" key="dock_apps_menu"> + <string key="name">dock_apps_menu</string> + <string key="candidateClassName">NSMenu</string> + </object> + <object class="IBToOneOutletInfo" key="dock_menu"> + <string key="name">dock_menu</string> + <string key="candidateClassName">NSMenu</string> + </object> + <object class="IBToOneOutletInfo" key="dock_window_separator"> + <string key="name">dock_window_separator</string> + <string key="candidateClassName">NSMenuItem</string> + </object> + <object class="IBToOneOutletInfo" key="enable_auth"> + <string key="name">enable_auth</string> + <string key="candidateClassName">NSButton</string> + </object> + <object class="IBToOneOutletInfo" key="enable_fullscreen"> + <string key="name">enable_fullscreen</string> + <string key="candidateClassName">NSButton</string> + </object> + <object class="IBToOneOutletInfo" key="enable_fullscreen_menu"> + <string key="name">enable_fullscreen_menu</string> + <string key="candidateClassName">NSButton</string> + </object> + <object class="IBToOneOutletInfo" key="enable_keyequivs"> + <string key="name">enable_keyequivs</string> + <string key="candidateClassName">NSButton</string> + </object> + <object class="IBToOneOutletInfo" key="enable_tcp"> + <string key="name">enable_tcp</string> + <string key="candidateClassName">NSButton</string> + </object> + <object class="IBToOneOutletInfo" key="fake_buttons"> + <string key="name">fake_buttons</string> + <string key="candidateClassName">NSButton</string> + </object> + <object class="IBToOneOutletInfo" key="focus_follows_mouse"> + <string key="name">focus_follows_mouse</string> + <string key="candidateClassName">NSButton</string> + </object> + <object class="IBToOneOutletInfo" key="focus_on_new_window"> + <string key="name">focus_on_new_window</string> + <string key="candidateClassName">NSButton</string> + </object> + <object class="IBToOneOutletInfo" key="option_sends_alt"> + <string key="name">option_sends_alt</string> + <string key="candidateClassName">NSButton</string> + </object> + <object class="IBToOneOutletInfo" key="prefs_panel"> + <string key="name">prefs_panel</string> + <string key="candidateClassName">NSPanel</string> + </object> + <object class="IBToOneOutletInfo" key="sync_clipboard_to_pasteboard"> + <string key="name">sync_clipboard_to_pasteboard</string> + <string key="candidateClassName">NSButton</string> + </object> + <object class="IBToOneOutletInfo" key="sync_keymap"> + <string key="name">sync_keymap</string> + <string key="candidateClassName">NSButton</string> + </object> + <object class="IBToOneOutletInfo" key="sync_pasteboard"> + <string key="name">sync_pasteboard</string> + <string key="candidateClassName">NSButton</string> + </object> + <object class="IBToOneOutletInfo" key="sync_pasteboard_to_clipboard"> + <string key="name">sync_pasteboard_to_clipboard</string> + <string key="candidateClassName">NSButton</string> + </object> + <object class="IBToOneOutletInfo" key="sync_pasteboard_to_primary"> + <string key="name">sync_pasteboard_to_primary</string> + <string key="candidateClassName">NSButton</string> + </object> + <object class="IBToOneOutletInfo" key="sync_primary_immediately"> + <string key="name">sync_primary_immediately</string> + <string key="candidateClassName">NSButton</string> + </object> + <object class="IBToOneOutletInfo" key="sync_text1"> + <string key="name">sync_text1</string> + <string key="candidateClassName">NSTextField</string> + </object> + <object class="IBToOneOutletInfo" key="sync_text2"> + <string key="name">sync_text2</string> + <string key="candidateClassName">NSTextField</string> + </object> + <object class="IBToOneOutletInfo" key="toggle_fullscreen_item"> + <string key="name">toggle_fullscreen_item</string> + <string key="candidateClassName">NSMenuItem</string> + </object> + <object class="IBToOneOutletInfo" key="use_sysbeep"> + <string key="name">use_sysbeep</string> + <string key="candidateClassName">NSButton</string> + </object> + <object class="IBToOneOutletInfo" key="window_separator"> + <string key="name">window_separator</string> + <string key="candidateClassName">NSMenuItem</string> + </object> + <object class="IBToOneOutletInfo" key="x11_about_item"> + <string key="name">x11_about_item</string> + <string key="candidateClassName">NSMenuItem</string> + </object> + </dictionary> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBDocumentRelativeSource</string> <string key="minorKey">../../../X11Controller.h</string> diff --git a/xorg-server/hw/xquartz/bundle/Resources/English.lproj/main.nib/keyedobjects.nib b/xorg-server/hw/xquartz/bundle/Resources/English.lproj/main.nib/keyedobjects.nib Binary files differindex 888424dfc..836d59532 100644 --- a/xorg-server/hw/xquartz/bundle/Resources/English.lproj/main.nib/keyedobjects.nib +++ b/xorg-server/hw/xquartz/bundle/Resources/English.lproj/main.nib/keyedobjects.nib diff --git a/xorg-server/hw/xquartz/quartz.c b/xorg-server/hw/xquartz/quartz.c index aed063489..6c185a8eb 100644 --- a/xorg-server/hw/xquartz/quartz.c +++ b/xorg-server/hw/xquartz/quartz.c @@ -1,448 +1,457 @@ -/*
- *
- * Quartz-specific support for the Darwin X Server
- *
- * Copyright (c) 2001-2004 Greg Parker and Torrey T. Lyons.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name(s) of the above copyright
- * holders shall not be used in advertising or otherwise to promote the sale,
- * use or other dealings in this Software without prior written authorization.
- */
-
-#include "sanitizedCarbon.h"
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "quartzCommon.h"
-#include "quartzRandR.h"
-#include "inputstr.h"
-#include "quartz.h"
-#include "darwin.h"
-#include "darwinEvents.h"
-#include "pseudoramiX.h"
-#define _APPLEWM_SERVER_
-#include "applewmExt.h"
-
-#include "X11Application.h"
-
-#include <X11/extensions/applewmconst.h>
-
-// X headers
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "colormapst.h"
-#include "globals.h"
-#include "mi.h"
-
-// System headers
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <IOKit/pwr_mgt/IOPMLib.h>
-#include <pthread.h>
-
-#include <rootlessCommon.h>
-#include <Xplugin.h>
-
-DevPrivateKeyRec quartzScreenKeyRec;
-int aquaMenuBarHeight = 0;
-QuartzModeProcsPtr quartzProcs = NULL;
-const char *quartzOpenGLBundle = NULL;
-
-Bool XQuartzFullscreenDisableHotkeys = TRUE;
-Bool XQuartzOptionSendsAlt = FALSE;
-Bool XQuartzEnableKeyEquivalents = TRUE;
-Bool XQuartzFullscreenVisible = FALSE;
-Bool XQuartzRootlessDefault = TRUE;
-Bool XQuartzIsRootless = TRUE;
-Bool XQuartzServerVisible = FALSE;
-Bool XQuartzFullscreenMenu = FALSE;
-Bool XQuartzUseSysBeep = FALSE;
-
-/*
-===========================================================================
-
- Screen functions
-
-===========================================================================
-*/
-
-/*
- * QuartzAddScreen
- * Do mode dependent initialization of each screen for Quartz.
- */
-Bool QuartzAddScreen(
- int index,
- ScreenPtr pScreen)
-{
- // allocate space for private per screen Quartz specific storage
- QuartzScreenPtr displayInfo = calloc(sizeof(QuartzScreenRec), 1);
-
- // QUARTZ_PRIV(pScreen) = displayInfo;
- dixSetPrivate(&pScreen->devPrivates, quartzScreenKey, displayInfo);
-
- // do Quartz mode specific initialization
- return quartzProcs->AddScreen(index, pScreen);
-}
-
-
-/*
- * QuartzSetupScreen
- * Finalize mode specific setup of each screen.
- */
-Bool QuartzSetupScreen(
- int index,
- ScreenPtr pScreen)
-{
- // do Quartz mode specific setup
- if (! quartzProcs->SetupScreen(index, pScreen))
- return FALSE;
-
- // setup cursor support
- if (! quartzProcs->InitCursor(pScreen))
- return FALSE;
-
-#if defined(RANDR)
- if(!QuartzRandRInit(pScreen)) {
- DEBUG_LOG("Failed to init RandR extension.\n");
- return FALSE;
- }
-#endif
-
- return TRUE;
-}
-
-
-/*
- * QuartzInitOutput
- * Quartz display initialization.
- */
-void QuartzInitOutput(
- int argc,
- char **argv )
-{
- if (!RegisterBlockAndWakeupHandlers(QuartzBlockHandler,
- QuartzWakeupHandler,
- NULL))
- {
- FatalError("Could not register block and wakeup handlers.");
- }
-
- if (!dixRegisterPrivateKey(&quartzScreenKeyRec, PRIVATE_SCREEN, 0))
- FatalError("Failed to alloc quartz screen private.\n");
-
- // Do display mode specific initialization
- quartzProcs->DisplayInit();
-}
-
-
-/*
- * QuartzInitInput
- * Inform the main thread the X server is ready to handle events.
- */
-void QuartzInitInput(
- int argc,
- char **argv )
-{
- X11ApplicationSetCanQuit(0);
- X11ApplicationServerReady();
- // Do final display mode specific initialization before handling events
- if (quartzProcs->InitInput)
- quartzProcs->InitInput(argc, argv);
-}
-
-
-void QuartzUpdateScreens(void) {
- ScreenPtr pScreen;
- WindowPtr pRoot;
- int x, y, width, height, sx, sy;
- xEvent e;
- BoxRec bounds;
-
- if (noPseudoramiXExtension || screenInfo.numScreens != 1)
- {
- /* FIXME: if not using Xinerama, we have multiple screens, and
- to do this properly may need to add or remove screens. Which
- isn't possible. So don't do anything. Another reason why
- we default to running with Xinerama. */
-
- return;
- }
-
- pScreen = screenInfo.screens[0];
-
- PseudoramiXResetScreens();
- quartzProcs->AddPseudoramiXScreens(&x, &y, &width, &height, pScreen);
-
- pScreen->x = x;
- pScreen->y = y;
- pScreen->mmWidth = pScreen->mmWidth * ((double) width / pScreen->width);
- pScreen->mmHeight = pScreen->mmHeight * ((double) height / pScreen->height);
- pScreen->width = width;
- pScreen->height = height;
-
- DarwinAdjustScreenOrigins(&screenInfo);
-
- /* DarwinAdjustScreenOrigins or UpdateScreen may change pScreen->x/y,
- * so use it rather than x/y
- */
- sx = pScreen->x + darwinMainScreenX;
- sy = pScreen->y + darwinMainScreenY;
-
- /* Adjust the root window. */
- pRoot = pScreen->root;
- AppleWMSetScreenOrigin(pRoot);
- pScreen->ResizeWindow(pRoot, x - sx, y - sy, width, height, NULL);
-
- miPaintWindow(pRoot, &pRoot->borderClip, PW_BACKGROUND);
-
- /* <rdar://problem/7770779> pointer events are clipped to old display region after display reconfiguration
- * http://xquartz.macosforge.org/trac/ticket/346
- */
- bounds.x1 = 0;
- bounds.x2 = width;
- bounds.y1 = 0;
- bounds.y2 = height;
- pScreen->ConstrainCursor(inputInfo.pointer, pScreen, &bounds);
- inputInfo.pointer->spriteInfo->sprite->physLimits = bounds;
- inputInfo.pointer->spriteInfo->sprite->hotLimits = bounds;
-
- DEBUG_LOG("Root Window: %dx%d @ (%d, %d) darwinMainScreen (%d, %d) xy (%d, %d) dixScreenOrigins (%d, %d)\n", width, height, x - sx, y - sy, darwinMainScreenX, darwinMainScreenY, x, y, pScreen->x, pScreen->y);
-
- /* Send an event for the root reconfigure */
- e.u.u.type = ConfigureNotify;
- e.u.configureNotify.window = pRoot->drawable.id;
- e.u.configureNotify.aboveSibling = None;
- e.u.configureNotify.x = x - sx;
- e.u.configureNotify.y = y - sy;
- e.u.configureNotify.width = width;
- e.u.configureNotify.height = height;
- e.u.configureNotify.borderWidth = wBorderWidth(pRoot);
- e.u.configureNotify.override = pRoot->overrideRedirect;
- DeliverEvents(pRoot, &e, 1, NullWindow);
-
- quartzProcs->UpdateScreen(pScreen);
-}
-
-static void pokeActivityCallback(CFRunLoopTimerRef timer, void *info) {
- UpdateSystemActivity(OverallAct);
-}
-
-static void QuartzScreenSaver(int state) {
- static CFRunLoopTimerRef pokeActivityTimer = NULL;
- static CFRunLoopTimerContext pokeActivityContext = { 0, NULL, NULL, NULL, NULL };
- static pthread_mutex_t pokeActivityMutex = PTHREAD_MUTEX_INITIALIZER;
-
- pthread_mutex_lock(&pokeActivityMutex);
-
- if(state) {
- if(pokeActivityTimer == NULL)
- goto QuartzScreenSaverEnd;
-
- CFRunLoopTimerInvalidate(pokeActivityTimer);
- CFRelease(pokeActivityTimer);
- pokeActivityTimer = NULL;
- } else {
- if(pokeActivityTimer != NULL)
- goto QuartzScreenSaverEnd;
-
- pokeActivityTimer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent(), 30, 0, 0, pokeActivityCallback, &pokeActivityContext);
- if(pokeActivityTimer == NULL) {
- ErrorF("Unable to create pokeActivityTimer.\n");
- goto QuartzScreenSaverEnd;
- }
-
- CFRunLoopAddTimer(CFRunLoopGetMain(), pokeActivityTimer, kCFRunLoopCommonModes);
- }
-QuartzScreenSaverEnd:
- pthread_mutex_unlock(&pokeActivityMutex);
-}
-
-void QuartzShowFullscreen(int state) {
- int i;
-
- DEBUG_LOG("QuartzShowFullscreen: state=%d\n", state);
-
- if(XQuartzIsRootless) {
- ErrorF("QuartzShowFullscreen called while in rootless mode.\n");
- return;
- }
-
- QuartzScreenSaver(!state);
-
- if(XQuartzFullscreenVisible == state)
- return;
-
- XQuartzFullscreenVisible = state;
-
- xp_disable_update ();
-
- if (!XQuartzFullscreenVisible)
- RootlessHideAllWindows();
-
- RootlessUpdateRooted(XQuartzFullscreenVisible);
-
- if (XQuartzFullscreenVisible) {
- RootlessShowAllWindows ();
- for (i=0; i < screenInfo.numScreens; i++) {
- ScreenPtr pScreen = screenInfo.screens[i];
- RootlessRepositionWindows(pScreen);
- // JH: I don't think this is necessary, but keeping it here as a reminder
- //RootlessUpdateScreenPixmap(pScreen);
- }
- }
-
- /* Somehow the menubar manages to interfere with our event stream
- * in fullscreen mode, even though it's not visible.
- */
- X11ApplicationShowHideMenubar(!XQuartzFullscreenVisible);
-
- xp_reenable_update ();
-
- if (XQuartzFullscreenDisableHotkeys)
- xp_disable_hot_keys(XQuartzFullscreenVisible);
-}
-
-void QuartzSetRootless(Bool state) {
- DEBUG_LOG("QuartzSetRootless state=%d\n", state);
-
- if(XQuartzIsRootless == state)
- return;
-
- if(state)
- QuartzShowFullscreen(FALSE);
-
- XQuartzIsRootless = state;
-
- xp_disable_update();
-
- /* When in rootless, the menubar is not part of the screen, so we need to update our screens on toggle */
- QuartzUpdateScreens();
-
- if(XQuartzIsRootless) {
- RootlessShowAllWindows();
- } else {
- RootlessHideAllWindows();
- }
-
- X11ApplicationShowHideMenubar(TRUE);
-
- xp_reenable_update();
-
- xp_disable_hot_keys(FALSE);
-}
-
-/*
- * QuartzShow
- * Show the X server on screen. Does nothing if already shown.
- * Calls mode specific screen resume to restore the X clip regions
- * (if needed) and the X server cursor state.
- */
-void QuartzShow(void) {
- int i;
-
- if (XQuartzServerVisible)
- return;
-
- XQuartzServerVisible = TRUE;
- for (i = 0; i < screenInfo.numScreens; i++) {
- if (screenInfo.screens[i]) {
- quartzProcs->ResumeScreen(screenInfo.screens[i]);
- }
- }
-
- if (!XQuartzIsRootless)
- QuartzShowFullscreen(TRUE);
-}
-
-
-/*
- * QuartzHide
- * Remove the X server display from the screen. Does nothing if already
- * hidden. Calls mode specific screen suspend to set X clip regions to
- * prevent drawing (if needed) and restore the Aqua cursor.
- */
-void QuartzHide(void)
-{
- int i;
-
- if (XQuartzServerVisible) {
- for (i = 0; i < screenInfo.numScreens; i++) {
- if (screenInfo.screens[i]) {
- quartzProcs->SuspendScreen(screenInfo.screens[i]);
- }
- }
- }
-
- if(!XQuartzIsRootless)
- QuartzShowFullscreen(FALSE);
- XQuartzServerVisible = FALSE;
-}
-
-
-/*
- * QuartzSetRootClip
- * Enable or disable rendering to the X screen.
- */
-void QuartzSetRootClip(
- BOOL enable)
-{
- int i;
-
- if (!XQuartzServerVisible)
- return;
-
- for (i = 0; i < screenInfo.numScreens; i++) {
- if (screenInfo.screens[i]) {
- xf86SetRootClip(screenInfo.screens[i], enable);
- }
- }
-}
-
-/*
- * QuartzSpaceChanged
- * Unmap offscreen windows, map onscreen windows
- */
-void QuartzSpaceChanged(uint32_t space_id) {
- /* Do something special here, so we don't depend on quartz-wm for spaces to work... */
- DEBUG_LOG("Space Changed (%u) ... do something interesting...\n", space_id);
-}
-
-/*
- * QuartzCopyDisplayIDs
- * Associate an X11 screen with one or more CoreGraphics display IDs by copying
- * the list into a private array. Free the previously copied array, if present.
- */
-void QuartzCopyDisplayIDs(ScreenPtr pScreen,
- int displayCount, CGDirectDisplayID *displayIDs) {
- QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
- int size = displayCount * sizeof(CGDirectDisplayID);
-
- free(pQuartzScreen->displayIDs);
- pQuartzScreen->displayIDs = malloc(size);
- memcpy(pQuartzScreen->displayIDs, displayIDs, size);
- pQuartzScreen->displayCount = displayCount;
-}
+/* + * + * Quartz-specific support for the Darwin X Server + * + * Copyright (c) 2001-2004 Greg Parker and Torrey T. Lyons. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name(s) of the above copyright + * holders shall not be used in advertising or otherwise to promote the sale, + * use or other dealings in this Software without prior written authorization. + */ + +#include "sanitizedCarbon.h" + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "quartzCommon.h" +#include "quartzRandR.h" +#include "inputstr.h" +#include "quartz.h" +#include "darwin.h" +#include "darwinEvents.h" +#include "pseudoramiX.h" +#define _APPLEWM_SERVER_ +#include "applewmExt.h" + +#include "X11Application.h" + +#include <X11/extensions/applewmconst.h> + +// X headers +#include "scrnintstr.h" +#include "windowstr.h" +#include "colormapst.h" +#include "globals.h" +#include "mi.h" + +// System headers +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <IOKit/pwr_mgt/IOPMLib.h> +#include <pthread.h> + +#include <rootlessCommon.h> +#include <Xplugin.h> + +DevPrivateKeyRec quartzScreenKeyRec; +int aquaMenuBarHeight = 0; +QuartzModeProcsPtr quartzProcs = NULL; +const char *quartzOpenGLBundle = NULL; + +Bool XQuartzFullscreenDisableHotkeys = TRUE; +Bool XQuartzOptionSendsAlt = FALSE; +Bool XQuartzEnableKeyEquivalents = TRUE; +Bool XQuartzFullscreenVisible = FALSE; +Bool XQuartzRootlessDefault = TRUE; +Bool XQuartzIsRootless = TRUE; +Bool XQuartzServerVisible = FALSE; +Bool XQuartzFullscreenMenu = FALSE; + +/* +=========================================================================== + + Screen functions + +=========================================================================== +*/ + +/* + * QuartzAddScreen + * Do mode dependent initialization of each screen for Quartz. + */ +Bool QuartzAddScreen( + int index, + ScreenPtr pScreen) +{ + // allocate space for private per screen Quartz specific storage + QuartzScreenPtr displayInfo = calloc(sizeof(QuartzScreenRec), 1); + + // QUARTZ_PRIV(pScreen) = displayInfo; + dixSetPrivate(&pScreen->devPrivates, quartzScreenKey, displayInfo); + + // do Quartz mode specific initialization + return quartzProcs->AddScreen(index, pScreen); +} + + +/* + * QuartzSetupScreen + * Finalize mode specific setup of each screen. + */ +Bool QuartzSetupScreen( + int index, + ScreenPtr pScreen) +{ + // do Quartz mode specific setup + if (! quartzProcs->SetupScreen(index, pScreen)) + return FALSE; + + // setup cursor support + if (! quartzProcs->InitCursor(pScreen)) + return FALSE; + +#if defined(RANDR) + if(!QuartzRandRInit(pScreen)) { + DEBUG_LOG("Failed to init RandR extension.\n"); + return FALSE; + } +#endif + + return TRUE; +} + + +/* + * QuartzInitOutput + * Quartz display initialization. + */ +void QuartzInitOutput( + int argc, + char **argv ) +{ + if (!RegisterBlockAndWakeupHandlers(QuartzBlockHandler, + QuartzWakeupHandler, + NULL)) + { + FatalError("Could not register block and wakeup handlers."); + } + + if (!dixRegisterPrivateKey(&quartzScreenKeyRec, PRIVATE_SCREEN, 0)) + FatalError("Failed to alloc quartz screen private.\n"); + + // Do display mode specific initialization + quartzProcs->DisplayInit(); +} + + +/* + * QuartzInitInput + * Inform the main thread the X server is ready to handle events. + */ +void QuartzInitInput( + int argc, + char **argv ) +{ + X11ApplicationSetCanQuit(0); + X11ApplicationServerReady(); + // Do final display mode specific initialization before handling events + if (quartzProcs->InitInput) + quartzProcs->InitInput(argc, argv); +} + + +void QuartzUpdateScreens(void) { + ScreenPtr pScreen; + WindowPtr pRoot; + int x, y, width, height, sx, sy; + xEvent e; + BoxRec bounds; + + if (noPseudoramiXExtension || screenInfo.numScreens != 1) + { + /* FIXME: if not using Xinerama, we have multiple screens, and + to do this properly may need to add or remove screens. Which + isn't possible. So don't do anything. Another reason why + we default to running with Xinerama. */ + + return; + } + + pScreen = screenInfo.screens[0]; + + PseudoramiXResetScreens(); + quartzProcs->AddPseudoramiXScreens(&x, &y, &width, &height, pScreen); + + pScreen->x = x; + pScreen->y = y; + pScreen->mmWidth = pScreen->mmWidth * ((double) width / pScreen->width); + pScreen->mmHeight = pScreen->mmHeight * ((double) height / pScreen->height); + pScreen->width = width; + pScreen->height = height; + + DarwinAdjustScreenOrigins(&screenInfo); + + /* DarwinAdjustScreenOrigins or UpdateScreen may change pScreen->x/y, + * so use it rather than x/y + */ + sx = pScreen->x + darwinMainScreenX; + sy = pScreen->y + darwinMainScreenY; + + /* Adjust the root window. */ + pRoot = pScreen->root; + AppleWMSetScreenOrigin(pRoot); + pScreen->ResizeWindow(pRoot, x - sx, y - sy, width, height, NULL); + + miPaintWindow(pRoot, &pRoot->borderClip, PW_BACKGROUND); + + /* <rdar://problem/7770779> pointer events are clipped to old display region after display reconfiguration + * http://xquartz.macosforge.org/trac/ticket/346 + */ + bounds.x1 = 0; + bounds.x2 = width; + bounds.y1 = 0; + bounds.y2 = height; + pScreen->ConstrainCursor(inputInfo.pointer, pScreen, &bounds); + inputInfo.pointer->spriteInfo->sprite->physLimits = bounds; + inputInfo.pointer->spriteInfo->sprite->hotLimits = bounds; + + DEBUG_LOG("Root Window: %dx%d @ (%d, %d) darwinMainScreen (%d, %d) xy (%d, %d) dixScreenOrigins (%d, %d)\n", width, height, x - sx, y - sy, darwinMainScreenX, darwinMainScreenY, x, y, pScreen->x, pScreen->y); + + /* Send an event for the root reconfigure */ + e.u.u.type = ConfigureNotify; + e.u.configureNotify.window = pRoot->drawable.id; + e.u.configureNotify.aboveSibling = None; + e.u.configureNotify.x = x - sx; + e.u.configureNotify.y = y - sy; + e.u.configureNotify.width = width; + e.u.configureNotify.height = height; + e.u.configureNotify.borderWidth = wBorderWidth(pRoot); + e.u.configureNotify.override = pRoot->overrideRedirect; + DeliverEvents(pRoot, &e, 1, NullWindow); + + quartzProcs->UpdateScreen(pScreen); +} + +static void pokeActivityCallback(CFRunLoopTimerRef timer, void *info) { + UpdateSystemActivity(OverallAct); +} + +static void QuartzScreenSaver(int state) { + static CFRunLoopTimerRef pokeActivityTimer = NULL; + static CFRunLoopTimerContext pokeActivityContext = { 0, NULL, NULL, NULL, NULL }; + static pthread_mutex_t pokeActivityMutex = PTHREAD_MUTEX_INITIALIZER; + + pthread_mutex_lock(&pokeActivityMutex); + + if(state) { + if(pokeActivityTimer == NULL) + goto QuartzScreenSaverEnd; + + CFRunLoopTimerInvalidate(pokeActivityTimer); + CFRelease(pokeActivityTimer); + pokeActivityTimer = NULL; + } else { + if(pokeActivityTimer != NULL) + goto QuartzScreenSaverEnd; + + pokeActivityTimer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent(), 30, 0, 0, pokeActivityCallback, &pokeActivityContext); + if(pokeActivityTimer == NULL) { + ErrorF("Unable to create pokeActivityTimer.\n"); + goto QuartzScreenSaverEnd; + } + + CFRunLoopAddTimer(CFRunLoopGetMain(), pokeActivityTimer, kCFRunLoopCommonModes); + } +QuartzScreenSaverEnd: + pthread_mutex_unlock(&pokeActivityMutex); +} + +void QuartzShowFullscreen(int state) { + int i; + + DEBUG_LOG("QuartzShowFullscreen: state=%d\n", state); + + if(XQuartzIsRootless) { + ErrorF("QuartzShowFullscreen called while in rootless mode.\n"); + return; + } + + QuartzScreenSaver(!state); + + if(XQuartzFullscreenVisible == state) + return; + + XQuartzFullscreenVisible = state; + + xp_disable_update (); + + if (!XQuartzFullscreenVisible) + RootlessHideAllWindows(); + + RootlessUpdateRooted(XQuartzFullscreenVisible); + + if (XQuartzFullscreenVisible) { + RootlessShowAllWindows (); + for (i=0; i < screenInfo.numScreens; i++) { + ScreenPtr pScreen = screenInfo.screens[i]; + RootlessRepositionWindows(pScreen); + // JH: I don't think this is necessary, but keeping it here as a reminder + //RootlessUpdateScreenPixmap(pScreen); + } + } + + /* Somehow the menubar manages to interfere with our event stream + * in fullscreen mode, even though it's not visible. + */ + X11ApplicationShowHideMenubar(!XQuartzFullscreenVisible); + + xp_reenable_update (); + + if (XQuartzFullscreenDisableHotkeys) + xp_disable_hot_keys(XQuartzFullscreenVisible); +} + +void QuartzSetRootless(Bool state) { + DEBUG_LOG("QuartzSetRootless state=%d\n", state); + + if(XQuartzIsRootless == state) + return; + + if(state) + QuartzShowFullscreen(FALSE); + + XQuartzIsRootless = state; + + xp_disable_update(); + + /* When in rootless, the menubar is not part of the screen, so we need to update our screens on toggle */ + QuartzUpdateScreens(); + + if(XQuartzIsRootless) { + RootlessShowAllWindows(); + } else { + RootlessHideAllWindows(); + } + + X11ApplicationShowHideMenubar(TRUE); + + xp_reenable_update(); + + xp_disable_hot_keys(FALSE); +} + +/* + * QuartzShow + * Show the X server on screen. Does nothing if already shown. + * Calls mode specific screen resume to restore the X clip regions + * (if needed) and the X server cursor state. + */ +void QuartzShow(void) { + int i; + + if (XQuartzServerVisible) + return; + + XQuartzServerVisible = TRUE; + for (i = 0; i < screenInfo.numScreens; i++) { + if (screenInfo.screens[i]) { + quartzProcs->ResumeScreen(screenInfo.screens[i]); + } + } + + if (!XQuartzIsRootless) + QuartzShowFullscreen(TRUE); +} + + +/* + * QuartzHide + * Remove the X server display from the screen. Does nothing if already + * hidden. Calls mode specific screen suspend to set X clip regions to + * prevent drawing (if needed) and restore the Aqua cursor. + */ +void QuartzHide(void) +{ + int i; + + if (XQuartzServerVisible) { + for (i = 0; i < screenInfo.numScreens; i++) { + if (screenInfo.screens[i]) { + quartzProcs->SuspendScreen(screenInfo.screens[i]); + } + } + } + + if(!XQuartzIsRootless) + QuartzShowFullscreen(FALSE); + XQuartzServerVisible = FALSE; +} + + +/* + * QuartzSetRootClip + * Enable or disable rendering to the X screen. + */ +void QuartzSetRootClip( + BOOL enable) +{ + int i; + + if (!XQuartzServerVisible) + return; + + for (i = 0; i < screenInfo.numScreens; i++) { + if (screenInfo.screens[i]) { + xf86SetRootClip(screenInfo.screens[i], enable); + } + } +} + +/* + * QuartzSpaceChanged + * Unmap offscreen windows, map onscreen windows + */ +void QuartzSpaceChanged(uint32_t space_id) { + /* Do something special here, so we don't depend on quartz-wm for spaces to work... */ + DEBUG_LOG("Space Changed (%u) ... do something interesting...\n", space_id); +} + +/* + * QuartzCopyDisplayIDs + * Associate an X11 screen with one or more CoreGraphics display IDs by copying + * the list into a private array. Free the previously copied array, if present. + */ +void QuartzCopyDisplayIDs(ScreenPtr pScreen, + int displayCount, CGDirectDisplayID *displayIDs) { + QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen); + int size = displayCount * sizeof(CGDirectDisplayID); + + free(pQuartzScreen->displayIDs); + pQuartzScreen->displayIDs = malloc(size); + memcpy(pQuartzScreen->displayIDs, displayIDs, size); + pQuartzScreen->displayCount = displayCount; +} + +void NSBeep(void); +void DDXRingBell( + int volume, // volume is % of max + int pitch, // pitch is Hz + int duration) // duration is milliseconds +{ + if (volume) + NSBeep(); +} diff --git a/xorg-server/hw/xquartz/quartz.h b/xorg-server/hw/xquartz/quartz.h index f0b519e21..b83391db9 100644 --- a/xorg-server/hw/xquartz/quartz.h +++ b/xorg-server/hw/xquartz/quartz.h @@ -1,146 +1,145 @@ -/*
- * quartz.h
- *
- * External interface of the Quartz display modes seen by the generic, mode
- * independent parts of the Darwin X server.
- *
- * Copyright (c) 2001-2003 Greg Parker and Torrey T. Lyons.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name(s) of the above copyright
- * holders shall not be used in advertising or otherwise to promote the sale,
- * use or other dealings in this Software without prior written authorization.
- */
-
-#ifndef _QUARTZ_H
-#define _QUARTZ_H
-
-#include "screenint.h"
-#include "window.h"
-#include "pixmap.h"
-
-/*------------------------------------------
- Quartz display mode function types
- ------------------------------------------*/
-
-/*
- * Display mode initialization
- */
-typedef void (*DisplayInitProc)(void);
-typedef Bool (*AddScreenProc)(int index, ScreenPtr pScreen);
-typedef Bool (*SetupScreenProc)(int index, ScreenPtr pScreen);
-typedef void (*InitInputProc)(int argc, char **argv);
-
-/*
- * Cursor functions
- */
-typedef Bool (*InitCursorProc)(ScreenPtr pScreen);
-
-/*
- * Suspend and resume X11 activity
- */
-typedef void (*SuspendScreenProc)(ScreenPtr pScreen);
-typedef void (*ResumeScreenProc)(ScreenPtr pScreen);
-
-/*
- * Screen state change support
- */
-typedef void (*AddPseudoramiXScreensProc)
- (int *x, int *y, int *width, int *height, ScreenPtr pScreen);
-typedef void (*UpdateScreenProc)(ScreenPtr pScreen);
-
-/*
- * Rootless helper functions
- */
-typedef Bool (*IsX11WindowProc)(void *nsWindow, int windowNumber);
-typedef void (*HideWindowsProc)(Bool hide);
-
-/*
- * Rootless functions for optional export to GLX layer
- */
-typedef void * (*FrameForWindowProc)(WindowPtr pWin, Bool create);
-typedef WindowPtr (*TopLevelParentProc)(WindowPtr pWindow);
-typedef Bool (*CreateSurfaceProc)
- (ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable,
- unsigned int client_id, unsigned int *surface_id,
- unsigned int key[2], void (*notify) (void *arg, void *data),
- void *notify_data);
-typedef Bool (*DestroySurfaceProc)
- (ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable,
- void (*notify) (void *arg, void *data), void *notify_data);
-
-/*
- * Quartz display mode function list
- */
-typedef struct _QuartzModeProcs {
- DisplayInitProc DisplayInit;
- AddScreenProc AddScreen;
- SetupScreenProc SetupScreen;
- InitInputProc InitInput;
-
- InitCursorProc InitCursor;
-
- SuspendScreenProc SuspendScreen;
- ResumeScreenProc ResumeScreen;
-
- AddPseudoramiXScreensProc AddPseudoramiXScreens;
- UpdateScreenProc UpdateScreen;
-
- IsX11WindowProc IsX11Window;
- HideWindowsProc HideWindows;
-
- FrameForWindowProc FrameForWindow;
- TopLevelParentProc TopLevelParent;
- CreateSurfaceProc CreateSurface;
- DestroySurfaceProc DestroySurface;
-} QuartzModeProcsRec, *QuartzModeProcsPtr;
-
-extern QuartzModeProcsPtr quartzProcs;
-
-extern Bool XQuartzFullscreenVisible; /* Are the windows visible (predicated on !rootless) */
-extern Bool XQuartzServerVisible; /* Is the server visible ... TODO: Refactor to "active" */
-extern Bool XQuartzEnableKeyEquivalents;
-extern Bool XQuartzRootlessDefault; /* Is our default mode rootless? */
-extern Bool XQuartzIsRootless; /* Is our current mode rootless (or FS)? */
-extern Bool XQuartzFullscreenMenu; /* Show the menu bar (autohide) while in FS */
-extern Bool XQuartzFullscreenDisableHotkeys;
-extern Bool XQuartzOptionSendsAlt; /* Alt or Mode_switch? */
-extern Bool XQuartzUseSysBeep; /* Sys beep or our own? */
-
-Bool QuartzAddScreen(int index, ScreenPtr pScreen);
-Bool QuartzSetupScreen(int index, ScreenPtr pScreen);
-void QuartzInitOutput(int argc,char **argv);
-void QuartzInitInput(int argc, char **argv);
-void QuartzInitServer(int argc, char **argv, char **envp);
-void QuartzGiveUp(void);
-void QuartzProcessEvent(xEvent *xe);
-void QuartzUpdateScreens(void);
-
-void QuartzShow(void);
-void QuartzHide(void);
-void QuartzSetRootClip(BOOL enable);
-void QuartzSpaceChanged(uint32_t space_id);
-
-void QuartzSetRootless(Bool state);
-void QuartzShowFullscreen(Bool state);
-
-int server_main(int argc, char **argv, char **envp);
-#endif
+/* + * quartz.h + * + * External interface of the Quartz display modes seen by the generic, mode + * independent parts of the Darwin X server. + * + * Copyright (c) 2001-2003 Greg Parker and Torrey T. Lyons. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name(s) of the above copyright + * holders shall not be used in advertising or otherwise to promote the sale, + * use or other dealings in this Software without prior written authorization. + */ + +#ifndef _QUARTZ_H +#define _QUARTZ_H + +#include "screenint.h" +#include "window.h" +#include "pixmap.h" + +/*------------------------------------------ + Quartz display mode function types + ------------------------------------------*/ + +/* + * Display mode initialization + */ +typedef void (*DisplayInitProc)(void); +typedef Bool (*AddScreenProc)(int index, ScreenPtr pScreen); +typedef Bool (*SetupScreenProc)(int index, ScreenPtr pScreen); +typedef void (*InitInputProc)(int argc, char **argv); + +/* + * Cursor functions + */ +typedef Bool (*InitCursorProc)(ScreenPtr pScreen); + +/* + * Suspend and resume X11 activity + */ +typedef void (*SuspendScreenProc)(ScreenPtr pScreen); +typedef void (*ResumeScreenProc)(ScreenPtr pScreen); + +/* + * Screen state change support + */ +typedef void (*AddPseudoramiXScreensProc) + (int *x, int *y, int *width, int *height, ScreenPtr pScreen); +typedef void (*UpdateScreenProc)(ScreenPtr pScreen); + +/* + * Rootless helper functions + */ +typedef Bool (*IsX11WindowProc)(void *nsWindow, int windowNumber); +typedef void (*HideWindowsProc)(Bool hide); + +/* + * Rootless functions for optional export to GLX layer + */ +typedef void * (*FrameForWindowProc)(WindowPtr pWin, Bool create); +typedef WindowPtr (*TopLevelParentProc)(WindowPtr pWindow); +typedef Bool (*CreateSurfaceProc) + (ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable, + unsigned int client_id, unsigned int *surface_id, + unsigned int key[2], void (*notify) (void *arg, void *data), + void *notify_data); +typedef Bool (*DestroySurfaceProc) + (ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable, + void (*notify) (void *arg, void *data), void *notify_data); + +/* + * Quartz display mode function list + */ +typedef struct _QuartzModeProcs { + DisplayInitProc DisplayInit; + AddScreenProc AddScreen; + SetupScreenProc SetupScreen; + InitInputProc InitInput; + + InitCursorProc InitCursor; + + SuspendScreenProc SuspendScreen; + ResumeScreenProc ResumeScreen; + + AddPseudoramiXScreensProc AddPseudoramiXScreens; + UpdateScreenProc UpdateScreen; + + IsX11WindowProc IsX11Window; + HideWindowsProc HideWindows; + + FrameForWindowProc FrameForWindow; + TopLevelParentProc TopLevelParent; + CreateSurfaceProc CreateSurface; + DestroySurfaceProc DestroySurface; +} QuartzModeProcsRec, *QuartzModeProcsPtr; + +extern QuartzModeProcsPtr quartzProcs; + +extern Bool XQuartzFullscreenVisible; /* Are the windows visible (predicated on !rootless) */ +extern Bool XQuartzServerVisible; /* Is the server visible ... TODO: Refactor to "active" */ +extern Bool XQuartzEnableKeyEquivalents; +extern Bool XQuartzRootlessDefault; /* Is our default mode rootless? */ +extern Bool XQuartzIsRootless; /* Is our current mode rootless (or FS)? */ +extern Bool XQuartzFullscreenMenu; /* Show the menu bar (autohide) while in FS */ +extern Bool XQuartzFullscreenDisableHotkeys; +extern Bool XQuartzOptionSendsAlt; /* Alt or Mode_switch? */ + +Bool QuartzAddScreen(int index, ScreenPtr pScreen); +Bool QuartzSetupScreen(int index, ScreenPtr pScreen); +void QuartzInitOutput(int argc,char **argv); +void QuartzInitInput(int argc, char **argv); +void QuartzInitServer(int argc, char **argv, char **envp); +void QuartzGiveUp(void); +void QuartzProcessEvent(xEvent *xe); +void QuartzUpdateScreens(void); + +void QuartzShow(void); +void QuartzHide(void); +void QuartzSetRootClip(BOOL enable); +void QuartzSpaceChanged(uint32_t space_id); + +void QuartzSetRootless(Bool state); +void QuartzShowFullscreen(Bool state); + +int server_main(int argc, char **argv, char **envp); +#endif diff --git a/xorg-server/hw/xquartz/quartzAudio.c b/xorg-server/hw/xquartz/quartzAudio.c deleted file mode 100644 index d17d65808..000000000 --- a/xorg-server/hw/xquartz/quartzAudio.c +++ /dev/null @@ -1,329 +0,0 @@ -//
-// QuartzAudio.m
-//
-// X Window bell support using CoreAudio or AppKit.
-// Greg Parker gparker@cs.stanford.edu 19 Feb 2001
-//
-// Info about sine wave sound playback:
-// CoreAudio code derived from macosx-dev posting by Tim Wood
-// http://www.omnigroup.com/mailman/archive/macosx-dev/2000-May/002004.html
-// Smoothing transitions between sounds
-// http://www.wam.umd.edu/~mphoenix/dss/dss.html
-//
-/*
- * Copyright (c) 2001 Greg Parker. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name(s) of the above copyright
- * holders shall not be used in advertising or otherwise to promote the sale,
- * use or other dealings in this Software without prior written authorization.
- */
-
-#include "sanitizedCarbon.h"
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "quartz.h"
-#include "quartzAudio.h"
-
-#include <CoreAudio/CoreAudio.h>
-#include <pthread.h>
-#include <AvailabilityMacros.h>
-
-#include "inputstr.h"
-#include <X11/extensions/XI.h>
-#include <assert.h>
-
-void NSBeep(void);
-
-typedef struct QuartzAudioRec {
- double frequency;
- double amplitude;
-
- UInt32 curFrame;
- UInt32 remainingFrames;
- UInt32 totalFrames;
- double sampleRate;
- UInt32 fadeLength;
-
- UInt32 bufferByteCount;
- Boolean playing;
- pthread_mutex_t lock;
-
- // used to fade out interrupted sound and avoid 'pop'
- double prevFrequency;
- double prevAmplitude;
- UInt32 prevFrame;
-} QuartzAudioRec;
-
-static AudioDeviceID quartzAudioDevice = kAudioDeviceUnknown;
-static QuartzAudioRec data;
-
-
-/*
- * QuartzAudioEnvelope
- * Fade sound in and out to avoid pop.
- * Sounds with shorter duration will never reach full amplitude. Deal.
- */
-static double QuartzAudioEnvelope(
- UInt32 curFrame,
- UInt32 totalFrames,
- UInt32 fadeLength )
-{
- double fadeFrames = min(fadeLength, totalFrames / 2);
- if (fadeFrames < 1) return 0;
-
- if (curFrame < fadeFrames) {
- return curFrame / fadeFrames;
- } else if (curFrame > totalFrames - fadeFrames) {
- return (totalFrames-curFrame) / fadeFrames;
- } else {
- return 1.0;
- }
-}
-
-
-/*
- * QuartzFillBuffer
- * Fill this buffer with data and update the data position.
- * FIXME: this is ugly
- */
-static void QuartzFillBuffer(
- AudioBuffer *audiobuffer,
- QuartzAudioRec *data )
-{
- float *buffer, *b;
- unsigned int frame, frameCount;
- unsigned int bufferFrameCount;
- float multiplier, v;
- int i;
-
- buffer = (float *)audiobuffer->mData;
- bufferFrameCount = audiobuffer->mDataByteSize / (sizeof(float) * audiobuffer->mNumberChannels);
-
- frameCount = min(bufferFrameCount, data->remainingFrames);
-
- // Fade out previous sine wave, if any.
- b = buffer;
- if (data->prevFrame) {
- multiplier = 2*M_PI*(data->prevFrequency/data->sampleRate);
- for (frame = 0; frame < data->fadeLength; frame++) {
- v = data->prevAmplitude *
- QuartzAudioEnvelope(frame+data->fadeLength,
- 2*data->fadeLength,
- data->fadeLength) *
- sin(multiplier * (data->prevFrame+frame));
- for (i = 0; i < audiobuffer->mNumberChannels; i++) {
- *b++ = v;
- }
- }
- // no more prev fade
- data->prevFrame = 0;
-
- // adjust for space eaten by prev fade
- b += audiobuffer->mNumberChannels*frame;
- bufferFrameCount -= frame;
- frameCount = min(bufferFrameCount, data->remainingFrames);
- }
-
- // Write a sine wave with the specified frequency and amplitude
- multiplier = 2*M_PI*(data->frequency/data->sampleRate);
- for (frame = 0; frame < frameCount; frame++) {
- v = data->amplitude *
- QuartzAudioEnvelope(data->curFrame+frame, data->totalFrames,
- data->fadeLength) *
- sin(multiplier * (data->curFrame+frame));
- for (i = 0; i < audiobuffer->mNumberChannels; i++) {
- *b++ = v;
- }
- }
-
- // Zero out the rest of the buffer, if any
- memset(b, 0, sizeof(float) * audiobuffer->mNumberChannels *
- (bufferFrameCount-frame));
-
- data->curFrame += frameCount;
- data->remainingFrames -= frameCount;
- if (data->remainingFrames == 0) {
- data->playing = FALSE;
- data->curFrame = 0;
- }
-}
-
-
-/*
- * QuartzAudioIOProc
- * Callback function for audio playback.
- * FIXME: use inOutputTime to correct for skipping
- */
-static OSStatus
-QuartzAudioIOProc(
- AudioDeviceID inDevice,
- const AudioTimeStamp *inNow,
- const AudioBufferList *inInputData,
- const AudioTimeStamp *inInputTime,
- AudioBufferList *outOutputData,
- const AudioTimeStamp *inOutputTime,
- void *inClientData )
-{
- QuartzAudioRec *data = (QuartzAudioRec *)inClientData;
- int i;
- Boolean wasPlaying;
-
- pthread_mutex_lock(&data->lock);
- wasPlaying = data->playing;
- for (i = 0; i < outOutputData->mNumberBuffers; i++) {
- if (data->playing) {
- QuartzFillBuffer(outOutputData->mBuffers+i, data);
- }
- else {
- memset(outOutputData->mBuffers[i].mData, 0,
- outOutputData->mBuffers[i].mDataByteSize);
- }
- }
- if (wasPlaying && !data->playing) {
- OSStatus err;
- err = AudioDeviceStop(inDevice, QuartzAudioIOProc);
- if(err != noErr)
- fprintf(stderr, "Error stopping audio device: %ld\n", (long int)err);
- }
- pthread_mutex_unlock(&data->lock);
- return 0;
-}
-
-
-/*
- * DDXRingBell
- * Play a tone using the CoreAudio API
- */
-void DDXRingBell(
- int volume, // volume is % of max
- int pitch, // pitch is Hz
- int duration ) // duration is milliseconds
-{
- if (XQuartzUseSysBeep) {
- if (volume)
- NSBeep();
- return;
- }
-
- if (quartzAudioDevice == kAudioDeviceUnknown) return;
-
- pthread_mutex_lock(&data.lock);
-
- // fade previous sound, if any
- data.prevFrequency = data.frequency;
- data.prevAmplitude = data.amplitude;
- data.prevFrame = data.curFrame;
-
- // set new sound
- data.frequency = pitch;
- data.amplitude = volume / 100.0;
- data.curFrame = 0;
- data.totalFrames = (int)(data.sampleRate * duration / 1000.0);
- data.remainingFrames = data.totalFrames;
-
- if (! data.playing) {
- OSStatus status;
- status = AudioDeviceStart(quartzAudioDevice, QuartzAudioIOProc);
- if (status) {
- ErrorF("DDXRingBell: AudioDeviceStart returned %ld\n", (long)status);
- } else {
- data.playing = TRUE;
- }
- }
- pthread_mutex_unlock(&data.lock);
-}
-
-/*
- * QuartzAudioInit
- * Prepare to play the bell with the CoreAudio API
- */
-void QuartzAudioInit(void)
-{
- UInt32 propertySize;
- OSStatus status;
- AudioDeviceID outputDevice;
- double sampleRate;
- AudioObjectPropertyAddress devicePropertyAddress = { kAudioHardwarePropertyDefaultOutputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
- AudioObjectPropertyAddress sampleRatePropertyAddress = { kAudioDevicePropertyNominalSampleRate, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster };
-
- // Get the default output device
- propertySize = sizeof(outputDevice);
- status = AudioObjectGetPropertyData(kAudioObjectSystemObject, &devicePropertyAddress,
- 0, NULL,
- &propertySize, &outputDevice);
- if (status) {
- ErrorF("QuartzAudioInit: AudioObjectGetPropertyData(output device) returned %ld\n",
- (long)status);
- return;
- }
- if (outputDevice == kAudioDeviceUnknown) {
- ErrorF("QuartzAudioInit: No audio output devices available.\n");
- return;
- }
-
- // Get the basic device description
- sampleRate = 0.;
- propertySize = sizeof(sampleRate);
- status = AudioObjectGetPropertyData(outputDevice, &sampleRatePropertyAddress,
- 0, NULL,
- &propertySize, &sampleRate);
- if (status) {
- ErrorF("QuartzAudioInit: AudioObjectGetPropertyData(sample rate) returned %ld\n",
- (long)status);
- return;
- }
-
- // Fill in the playback data
- data.frequency = 0;
- data.amplitude = 0;
- data.curFrame = 0;
- data.remainingFrames = 0;
- data.sampleRate = sampleRate;
- // data.bufferByteCount = bufferByteCount;
- data.playing = FALSE;
- data.prevAmplitude = 0;
- data.prevFrame = 0;
- data.prevFrequency = 0;
- data.fadeLength = data.sampleRate / 200;
- pthread_mutex_init(&data.lock, NULL); // fixme error check
-
- // fixme assert fadeLength<framesPerBuffer
-
- // Prepare for playback
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
- {
- AudioDeviceIOProcID sInputIOProcID = NULL;
- status = AudioDeviceCreateIOProcID( outputDevice, QuartzAudioIOProc, &data, &sInputIOProcID );
- }
-#else
- status = AudioDeviceAddIOProc(outputDevice, QuartzAudioIOProc, &data);
-#endif
- if (status) {
- ErrorF("QuartzAudioInit: AddIOProc returned %ld\n", (long)status);
- return;
- }
-
- // success!
- quartzAudioDevice = outputDevice;
-}
diff --git a/xorg-server/hw/xquartz/quartzAudio.h b/xorg-server/hw/xquartz/quartzAudio.h deleted file mode 100644 index 2a78b3957..000000000 --- a/xorg-server/hw/xquartz/quartzAudio.h +++ /dev/null @@ -1,37 +0,0 @@ -// -// QuartzAudio.h -// -// X Window bell support using CoreAudio or AppKit. -// Greg Parker gparker@cs.stanford.edu 19 Feb 2001 -/* - * Copyright (c) 2001 Greg Parker. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name(s) of the above copyright - * holders shall not be used in advertising or otherwise to promote the sale, - * use or other dealings in this Software without prior written authorization. - */ - -#ifndef _QUARTZAUDIO_H -#define _QUARTZAUDIO_H - -void QuartzAudioInit(void); - -#endif diff --git a/xorg-server/hw/xquartz/quartzKeyboard.c b/xorg-server/hw/xquartz/quartzKeyboard.c index cd73ec5bd..54f709a8b 100644 --- a/xorg-server/hw/xquartz/quartzKeyboard.c +++ b/xorg-server/hw/xquartz/quartzKeyboard.c @@ -1,858 +1,857 @@ -/*
- quartzKeyboard.c: Keyboard support for Xquartz
-
- Copyright (c) 2003-2008 Apple Inc.
- Copyright (c) 2001-2004 Torrey T. Lyons. All Rights Reserved.
- Copyright 2004 Kaleb S. KEITHLEY. All Rights Reserved.
-
- Copyright (C) 1999,2000 by Eric Sunshine <sunshine@sunshineco.com>
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include "sanitizedCarbon.h"
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#define HACK_MISSING 1
-#define HACK_KEYPAD 1
-#define HACK_BLACKLIST 1
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <AvailabilityMacros.h>
-
-#include "quartz.h"
-#include "darwin.h"
-#include "darwinEvents.h"
-
-#include "quartzKeyboard.h"
-#include "quartzAudio.h"
-
-#include "X11Application.h"
-
-#include "threadSafety.h"
-
-#ifdef NDEBUG
-#undef NDEBUG
-#include <assert.h>
-#define NDEBUG 1
-#else
-#include <assert.h>
-#endif
-#include <pthread.h>
-
-#include "xkbsrv.h"
-#include "exevents.h"
-#include "X11/keysym.h"
-#include "keysym2ucs.h"
-
-extern void
-CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master);
-
-enum {
- MOD_COMMAND = 256,
- MOD_SHIFT = 512,
- MOD_OPTION = 2048,
- MOD_CONTROL = 4096,
-};
-
-#define UKEYSYM(u) ((u) | 0x01000000)
-
-#if HACK_MISSING
-/* Table of keycode->keysym mappings we use to fallback on for important
- keys that are often not in the Unicode mapping. */
-
-const static struct {
- unsigned short keycode;
- KeySym keysym;
-} known_keys[] = {
- {55, XK_Meta_L},
- {56, XK_Shift_L},
- {57, XK_Caps_Lock},
- {58, XK_Alt_L},
- {59, XK_Control_L},
-
- {60, XK_Shift_R},
- {61, XK_Alt_R},
- {62, XK_Control_R},
- {63, XK_Meta_R},
-
- {122, XK_F1},
- {120, XK_F2},
- {99, XK_F3},
- {118, XK_F4},
- {96, XK_F5},
- {97, XK_F6},
- {98, XK_F7},
- {100, XK_F8},
- {101, XK_F9},
- {109, XK_F10},
- {103, XK_F11},
- {111, XK_F12},
- {105, XK_F13},
- {107, XK_F14},
- {113, XK_F15},
-};
-#endif
-
-#if HACK_KEYPAD
-/* Table of keycode->old,new-keysym mappings we use to fixup the numeric
- keypad entries. */
-
-const static struct {
- unsigned short keycode;
- KeySym normal, keypad;
-} known_numeric_keys[] = {
- {65, XK_period, XK_KP_Decimal},
- {67, XK_asterisk, XK_KP_Multiply},
- {69, XK_plus, XK_KP_Add},
- {75, XK_slash, XK_KP_Divide},
- {76, 0x01000003, XK_KP_Enter},
- {78, XK_minus, XK_KP_Subtract},
- {81, XK_equal, XK_KP_Equal},
- {82, XK_0, XK_KP_0},
- {83, XK_1, XK_KP_1},
- {84, XK_2, XK_KP_2},
- {85, XK_3, XK_KP_3},
- {86, XK_4, XK_KP_4},
- {87, XK_5, XK_KP_5},
- {88, XK_6, XK_KP_6},
- {89, XK_7, XK_KP_7},
- {91, XK_8, XK_KP_8},
- {92, XK_9, XK_KP_9},
-};
-#endif
-
-#if HACK_BLACKLIST
-/* <rdar://problem/7824370> wine notepad produces wrong characters on shift+arrow
- * http://xquartz.macosforge.org/trac/ticket/295
- * http://developer.apple.com/legacy/mac/library/documentation/mac/Text/Text-579.html
- *
- * legacy Mac keycodes for arrow keys that shift-modify to math symbols
- */
-const static unsigned short keycode_blacklist[] = {66, 70, 72, 77};
-#endif
-
-/* Table mapping normal keysyms to their dead equivalents.
- FIXME: all the unicode keysyms (apart from circumflex) were guessed. */
-
-const static struct {
- KeySym normal, dead;
-} dead_keys[] = {
- {XK_grave, XK_dead_grave},
- {XK_apostrophe, XK_dead_acute}, /* US:"=" on a Czech keyboard */
- {XK_acute, XK_dead_acute},
- {UKEYSYM (0x384), XK_dead_acute}, /* US:";" on a Greek keyboard */
-// {XK_Greek_accentdieresis, XK_dead_diaeresis}, /* US:"opt+;" on a Greek keyboard ... replace with dead_accentdieresis if there is one */
- {XK_asciicircum, XK_dead_circumflex},
- {UKEYSYM (0x2c6), XK_dead_circumflex}, /* MODIFIER LETTER CIRCUMFLEX ACCENT */
- {XK_asciitilde, XK_dead_tilde},
- {UKEYSYM (0x2dc), XK_dead_tilde}, /* SMALL TILDE */
- {XK_macron, XK_dead_macron},
- {XK_breve, XK_dead_breve},
- {XK_abovedot, XK_dead_abovedot},
- {XK_diaeresis, XK_dead_diaeresis},
- {UKEYSYM (0x2da), XK_dead_abovering}, /* DOT ABOVE */
- {XK_doubleacute, XK_dead_doubleacute},
- {XK_caron, XK_dead_caron},
- {XK_cedilla, XK_dead_cedilla},
- {XK_ogonek, XK_dead_ogonek},
- {UKEYSYM (0x269), XK_dead_iota}, /* LATIN SMALL LETTER IOTA */
- {UKEYSYM (0x2ec), XK_dead_voiced_sound}, /* MODIFIER LETTER VOICING */
-/* {XK_semivoiced_sound, XK_dead_semivoiced_sound}, */
- {UKEYSYM (0x323), XK_dead_belowdot}, /* COMBINING DOT BELOW */
- {UKEYSYM (0x309), XK_dead_hook}, /* COMBINING HOOK ABOVE */
- {UKEYSYM (0x31b), XK_dead_horn}, /* COMBINING HORN */
-};
-
-typedef struct darwinKeyboardInfo_struct {
- CARD8 modMap[MAP_LENGTH];
- KeySym keyMap[MAP_LENGTH * GLYPHS_PER_KEY];
- unsigned char modifierKeycodes[32][2];
-} darwinKeyboardInfo;
-
-darwinKeyboardInfo keyInfo;
-pthread_mutex_t keyInfo_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-static void DarwinChangeKeyboardControl(DeviceIntPtr device, KeybdCtrl *ctrl) {
- // FIXME: to be implemented
- // keyclick, bell volume / pitch, autorepead, LED's
-}
-
-//-----------------------------------------------------------------------------
-// Utility functions to help parse Darwin keymap
-//-----------------------------------------------------------------------------
-
-/*
- * DarwinBuildModifierMaps
- * Use the keyMap field of keyboard info structure to populate
- * the modMap and modifierKeycodes fields.
- */
-static void DarwinBuildModifierMaps(darwinKeyboardInfo *info) {
- int i;
- KeySym *k;
-
- memset(info->modMap, NoSymbol, sizeof(info->modMap));
- memset(info->modifierKeycodes, 0, sizeof(info->modifierKeycodes));
-
- for (i = 0; i < NUM_KEYCODES; i++) {
- k = info->keyMap + i * GLYPHS_PER_KEY;
-
- switch (*k) {
- case XK_Shift_L:
- info->modifierKeycodes[NX_MODIFIERKEY_SHIFT][0] = i;
- info->modMap[MIN_KEYCODE + i] = ShiftMask;
- break;
-
- case XK_Shift_R:
-#ifdef NX_MODIFIERKEY_RSHIFT
- info->modifierKeycodes[NX_MODIFIERKEY_RSHIFT][0] = i;
-#else
- info->modifierKeycodes[NX_MODIFIERKEY_SHIFT][0] = i;
-#endif
- info->modMap[MIN_KEYCODE + i] = ShiftMask;
- break;
-
- case XK_Control_L:
- info->modifierKeycodes[NX_MODIFIERKEY_CONTROL][0] = i;
- info->modMap[MIN_KEYCODE + i] = ControlMask;
- break;
-
- case XK_Control_R:
-#ifdef NX_MODIFIERKEY_RCONTROL
- info->modifierKeycodes[NX_MODIFIERKEY_RCONTROL][0] = i;
-#else
- info->modifierKeycodes[NX_MODIFIERKEY_CONTROL][0] = i;
-#endif
- info->modMap[MIN_KEYCODE + i] = ControlMask;
- break;
-
- case XK_Caps_Lock:
- info->modifierKeycodes[NX_MODIFIERKEY_ALPHALOCK][0] = i;
- info->modMap[MIN_KEYCODE + i] = LockMask;
- break;
-
- case XK_Alt_L:
- info->modifierKeycodes[NX_MODIFIERKEY_ALTERNATE][0] = i;
- info->modMap[MIN_KEYCODE + i] = Mod1Mask;
- if(!XQuartzOptionSendsAlt)
- *k = XK_Mode_switch; // Yes, this is ugly. This needs to be cleaned up when we integrate quartzKeyboard with this code and refactor.
- break;
-
- case XK_Alt_R:
-#ifdef NX_MODIFIERKEY_RALTERNATE
- info->modifierKeycodes[NX_MODIFIERKEY_RALTERNATE][0] = i;
-#else
- info->modifierKeycodes[NX_MODIFIERKEY_ALTERNATE][0] = i;
-#endif
- if(!XQuartzOptionSendsAlt)
- *k = XK_Mode_switch; // Yes, this is ugly. This needs to be cleaned up when we integrate quartzKeyboard with this code and refactor.
- info->modMap[MIN_KEYCODE + i] = Mod1Mask;
- break;
-
- case XK_Mode_switch:
- ErrorF("DarwinBuildModifierMaps: XK_Mode_switch encountered, unable to determine side.\n");
- info->modifierKeycodes[NX_MODIFIERKEY_ALTERNATE][0] = i;
-#ifdef NX_MODIFIERKEY_RALTERNATE
- info->modifierKeycodes[NX_MODIFIERKEY_RALTERNATE][0] = i;
-#endif
- info->modMap[MIN_KEYCODE + i] = Mod1Mask;
- break;
-
- case XK_Meta_L:
- info->modifierKeycodes[NX_MODIFIERKEY_COMMAND][0] = i;
- info->modMap[MIN_KEYCODE + i] = Mod2Mask;
- break;
-
- case XK_Meta_R:
-#ifdef NX_MODIFIERKEY_RCOMMAND
- info->modifierKeycodes[NX_MODIFIERKEY_RCOMMAND][0] = i;
-#else
- info->modifierKeycodes[NX_MODIFIERKEY_COMMAND][0] = i;
-#endif
- info->modMap[MIN_KEYCODE + i] = Mod2Mask;
- break;
-
- case XK_Num_Lock:
- info->modMap[MIN_KEYCODE + i] = Mod3Mask;
- break;
- }
- }
-}
-
-/*
- * DarwinKeyboardInit
- * Get the Darwin keyboard map and compute an equivalent
- * X keyboard map and modifier map. Set the new keyboard
- * device structure.
- */
-void DarwinKeyboardInit(DeviceIntPtr pDev) {
- // Open a shared connection to the HID System.
- // Note that the Event Status Driver is really just a wrapper
- // for a kIOHIDParamConnectType connection.
- assert(darwinParamConnect = NXOpenEventStatus());
-
- InitKeyboardDeviceStruct(pDev, NULL, NULL, DarwinChangeKeyboardControl);
-
- DarwinKeyboardReloadHandler();
-
- CopyKeyClass(pDev, inputInfo.keyboard);
-}
-
-/* Set the repeat rates based on global preferences and keycodes for modifiers.
- * Precondition: Has the keyInfo_mutex lock.
- */
-static void DarwinKeyboardSetRepeat(DeviceIntPtr pDev, int initialKeyRepeatValue, int keyRepeatValue) {
- if(initialKeyRepeatValue == 300000) { // off
- /* Turn off repeats globally */
- XkbSetRepeatKeys(pDev, -1, AutoRepeatModeOff);
- } else {
- int i;
- XkbControlsPtr ctrl;
- XkbControlsRec old;
-
- /* Turn on repeats globally */
- XkbSetRepeatKeys(pDev, -1, AutoRepeatModeOn);
-
- /* Setup the bit mask for individual key repeats */
- ctrl = pDev->key->xkbInfo->desc->ctrls;
- old= *ctrl;
-
- ctrl->repeat_delay = initialKeyRepeatValue * 15;
- ctrl->repeat_interval = keyRepeatValue * 15;
-
- /* Turn off key-repeat for modifier keys, on for others */
- /* First set them all on */
- for(i=0; i < XkbPerKeyBitArraySize; i++)
- ctrl->per_key_repeat[i] = -1;
-
- /* Now turn off the modifiers */
- for(i=0; i < 32; i++) {
- unsigned char keycode;
-
- keycode = keyInfo.modifierKeycodes[i][0];
- if(keycode)
- ClearBit(ctrl->per_key_repeat, keycode + MIN_KEYCODE);
-
- keycode = keyInfo.modifierKeycodes[i][1];
- if(keycode)
- ClearBit(ctrl->per_key_repeat, keycode + MIN_KEYCODE);
- }
-
- /* Hurray for data duplication */
- if (pDev->kbdfeed)
- memcpy(pDev->kbdfeed->ctrl.autoRepeats, ctrl->per_key_repeat, XkbPerKeyBitArraySize);
-
- //fprintf(stderr, "per_key_repeat =\n");
- //for(i=0; i < XkbPerKeyBitArraySize; i++)
- // fprintf(stderr, "%02x%s", ctrl->per_key_repeat[i], (i + 1) & 7 ? "" : "\n");
-
- /* And now we notify the puppies about the changes */
- XkbDDXChangeControls(pDev, &old, ctrl);
- }
-}
-
-void DarwinKeyboardReloadHandler(void) {
- KeySymsRec keySyms;
- CFIndex initialKeyRepeatValue, keyRepeatValue;
- BOOL ok;
- DeviceIntPtr pDev;
- const char *xmodmap = PROJECTROOT "/bin/xmodmap";
- const char *sysmodmap = PROJECTROOT "/lib/X11/xinit/.Xmodmap";
- const char *homedir = getenv("HOME");
- char usermodmap[PATH_MAX], cmd[PATH_MAX];
-
- DEBUG_LOG("DarwinKeyboardReloadHandler\n");
-
- /* Get our key repeat settings from GlobalPreferences */
- (void)CFPreferencesAppSynchronize(CFSTR(".GlobalPreferences"));
-
- initialKeyRepeatValue = CFPreferencesGetAppIntegerValue(CFSTR("InitialKeyRepeat"), CFSTR(".GlobalPreferences"), &ok);
- if(!ok)
- initialKeyRepeatValue = 35;
-
- keyRepeatValue = CFPreferencesGetAppIntegerValue(CFSTR("KeyRepeat"), CFSTR(".GlobalPreferences"), &ok);
- if(!ok)
- keyRepeatValue = 6;
-
- pthread_mutex_lock(&keyInfo_mutex); {
- /* Initialize our keySyms */
- keySyms.map = keyInfo.keyMap;
- keySyms.mapWidth = GLYPHS_PER_KEY;
- keySyms.minKeyCode = MIN_KEYCODE;
- keySyms.maxKeyCode = MAX_KEYCODE;
-
- // TODO: We should build the entire XkbDescRec and use XkbCopyKeymap
- /* Apply the mappings to darwinKeyboard */
- XkbApplyMappingChange(darwinKeyboard, &keySyms, keySyms.minKeyCode,
- keySyms.maxKeyCode - keySyms.minKeyCode + 1,
- keyInfo.modMap, serverClient);
- DarwinKeyboardSetRepeat(darwinKeyboard, initialKeyRepeatValue, keyRepeatValue);
-
- /* Apply the mappings to the core keyboard */
- for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
- if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) {
- XkbApplyMappingChange(pDev, &keySyms, keySyms.minKeyCode,
- keySyms.maxKeyCode - keySyms.minKeyCode + 1,
- keyInfo.modMap, serverClient);
- DarwinKeyboardSetRepeat(pDev, initialKeyRepeatValue, keyRepeatValue);
- }
- }
- } pthread_mutex_unlock(&keyInfo_mutex);
-
- /* Modify with xmodmap */
- if (access(xmodmap, F_OK) == 0) {
- /* Check for system .Xmodmap */
- if (access(sysmodmap, F_OK) == 0) {
- if(snprintf (cmd, sizeof(cmd), "%s %s", xmodmap, sysmodmap) < sizeof(cmd)) {
- X11ApplicationLaunchClient(cmd);
- } else {
- ErrorF("X11.app: Unable to create / execute xmodmap command line");
- }
- }
-
- /* Check for user's local .Xmodmap */
- if ((homedir != NULL) && (snprintf (usermodmap, sizeof(usermodmap), "%s/.Xmodmap", homedir) < sizeof(usermodmap))) {
- if (access(usermodmap, F_OK) == 0) {
- if(snprintf (cmd, sizeof(cmd), "%s %s", xmodmap, usermodmap) < sizeof(cmd)) {
- X11ApplicationLaunchClient(cmd);
- } else {
- ErrorF("X11.app: Unable to create / execute xmodmap command line");
- }
- }
- } else {
- ErrorF("X11.app: Unable to determine path to user's .Xmodmap");
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Modifier translation functions
-//
-// There are three different ways to specify a Mac modifier key:
-// keycode - specifies hardware key, read from keymapping
-// key - NX_MODIFIERKEY_*, really an index
-// mask - NX_*MASK, mask for modifier flags in event record
-// Left and right side have different keycodes but the same key and mask.
-//-----------------------------------------------------------------------------
-
-/*
- * DarwinModifierNXKeyToNXKeycode
- * Return the keycode for an NX_MODIFIERKEY_* modifier.
- * side = 0 for left or 1 for right.
- * Returns 0 if key+side is not a known modifier.
- */
-int DarwinModifierNXKeyToNXKeycode(int key, int side) {
- int retval;
- pthread_mutex_lock(&keyInfo_mutex);
- retval = keyInfo.modifierKeycodes[key][side];
- pthread_mutex_unlock(&keyInfo_mutex);
-
- return retval;
-}
-
-/*
- * DarwinModifierNXKeycodeToNXKey
- * Returns -1 if keycode+side is not a modifier key
- * outSide may be NULL, else it gets 0 for left and 1 for right.
- */
-int DarwinModifierNXKeycodeToNXKey(unsigned char keycode, int *outSide) {
- int key, side;
-
- keycode += MIN_KEYCODE;
-
- // search modifierKeycodes for this keycode+side
- pthread_mutex_lock(&keyInfo_mutex);
- for (key = 0; key < NX_NUMMODIFIERS; key++) {
- for (side = 0; side <= 1; side++) {
- if (keyInfo.modifierKeycodes[key][side] == keycode) break;
- }
- }
- pthread_mutex_unlock(&keyInfo_mutex);
-
- if (key == NX_NUMMODIFIERS) {
- return -1;
- }
- if (outSide) *outSide = side;
-
- return key;
-}
-
-/*
- * DarwinModifierNXMaskToNXKey
- * Returns -1 if mask is not a known modifier mask.
- */
-int DarwinModifierNXMaskToNXKey(int mask) {
- switch (mask) {
- case NX_ALPHASHIFTMASK: return NX_MODIFIERKEY_ALPHALOCK;
- case NX_SHIFTMASK: return NX_MODIFIERKEY_SHIFT;
-#ifdef NX_DEVICELSHIFTKEYMASK
- case NX_DEVICELSHIFTKEYMASK: return NX_MODIFIERKEY_SHIFT;
- case NX_DEVICERSHIFTKEYMASK: return NX_MODIFIERKEY_RSHIFT;
-#endif
- case NX_CONTROLMASK: return NX_MODIFIERKEY_CONTROL;
-#ifdef NX_DEVICELCTLKEYMASK
- case NX_DEVICELCTLKEYMASK: return NX_MODIFIERKEY_CONTROL;
- case NX_DEVICERCTLKEYMASK: return NX_MODIFIERKEY_RCONTROL;
-#endif
- case NX_ALTERNATEMASK: return NX_MODIFIERKEY_ALTERNATE;
-#ifdef NX_DEVICELALTKEYMASK
- case NX_DEVICELALTKEYMASK: return NX_MODIFIERKEY_ALTERNATE;
- case NX_DEVICERALTKEYMASK: return NX_MODIFIERKEY_RALTERNATE;
-#endif
- case NX_COMMANDMASK: return NX_MODIFIERKEY_COMMAND;
-#ifdef NX_DEVICELCMDKEYMASK
- case NX_DEVICELCMDKEYMASK: return NX_MODIFIERKEY_COMMAND;
- case NX_DEVICERCMDKEYMASK: return NX_MODIFIERKEY_RCOMMAND;
-#endif
- case NX_NUMERICPADMASK: return NX_MODIFIERKEY_NUMERICPAD;
- case NX_HELPMASK: return NX_MODIFIERKEY_HELP;
- case NX_SECONDARYFNMASK: return NX_MODIFIERKEY_SECONDARYFN;
- }
- return -1;
-}
-
-/*
- * DarwinModifierNXKeyToNXMask
- * Returns 0 if key is not a known modifier key.
- */
-int DarwinModifierNXKeyToNXMask(int key) {
- switch (key) {
- case NX_MODIFIERKEY_ALPHALOCK: return NX_ALPHASHIFTMASK;
-#ifdef NX_DEVICELSHIFTKEYMASK
- case NX_MODIFIERKEY_SHIFT: return NX_DEVICELSHIFTKEYMASK;
- case NX_MODIFIERKEY_RSHIFT: return NX_DEVICERSHIFTKEYMASK;
- case NX_MODIFIERKEY_CONTROL: return NX_DEVICELCTLKEYMASK;
- case NX_MODIFIERKEY_RCONTROL: return NX_DEVICERCTLKEYMASK;
- case NX_MODIFIERKEY_ALTERNATE: return NX_DEVICELALTKEYMASK;
- case NX_MODIFIERKEY_RALTERNATE: return NX_DEVICERALTKEYMASK;
- case NX_MODIFIERKEY_COMMAND: return NX_DEVICELCMDKEYMASK;
- case NX_MODIFIERKEY_RCOMMAND: return NX_DEVICERCMDKEYMASK;
-#else
- case NX_MODIFIERKEY_SHIFT: return NX_SHIFTMASK;
- case NX_MODIFIERKEY_CONTROL: return NX_CONTROLMASK;
- case NX_MODIFIERKEY_ALTERNATE: return NX_ALTERNATEMASK;
- case NX_MODIFIERKEY_COMMAND: return NX_COMMANDMASK;
-#endif
- case NX_MODIFIERKEY_NUMERICPAD: return NX_NUMERICPADMASK;
- case NX_MODIFIERKEY_HELP: return NX_HELPMASK;
- case NX_MODIFIERKEY_SECONDARYFN: return NX_SECONDARYFNMASK;
- }
- return 0;
-}
-
-/*
- * DarwinModifierStringToNXMask
- * Returns 0 if string is not a known modifier.
- */
-int DarwinModifierStringToNXMask(const char *str, int separatelr) {
-#ifdef NX_DEVICELSHIFTKEYMASK
- if(separatelr) {
- if (!strcasecmp(str, "shift")) return NX_DEVICELSHIFTKEYMASK | NX_DEVICERSHIFTKEYMASK;
- if (!strcasecmp(str, "control")) return NX_DEVICELCTLKEYMASK | NX_DEVICERCTLKEYMASK;
- if (!strcasecmp(str, "option")) return NX_DEVICELALTKEYMASK | NX_DEVICERALTKEYMASK;
- if (!strcasecmp(str, "alt")) return NX_DEVICELALTKEYMASK | NX_DEVICERALTKEYMASK;
- if (!strcasecmp(str, "command")) return NX_DEVICELCMDKEYMASK | NX_DEVICERCMDKEYMASK;
- if (!strcasecmp(str, "lshift")) return NX_DEVICELSHIFTKEYMASK;
- if (!strcasecmp(str, "rshift")) return NX_DEVICERSHIFTKEYMASK;
- if (!strcasecmp(str, "lcontrol")) return NX_DEVICELCTLKEYMASK;
- if (!strcasecmp(str, "rcontrol")) return NX_DEVICERCTLKEYMASK;
- if (!strcasecmp(str, "loption")) return NX_DEVICELALTKEYMASK;
- if (!strcasecmp(str, "roption")) return NX_DEVICERALTKEYMASK;
- if (!strcasecmp(str, "lalt")) return NX_DEVICELALTKEYMASK;
- if (!strcasecmp(str, "ralt")) return NX_DEVICERALTKEYMASK;
- if (!strcasecmp(str, "lcommand")) return NX_DEVICELCMDKEYMASK;
- if (!strcasecmp(str, "rcommand")) return NX_DEVICERCMDKEYMASK;
- } else {
-#endif
- if (!strcasecmp(str, "shift")) return NX_SHIFTMASK;
- if (!strcasecmp(str, "control")) return NX_CONTROLMASK;
- if (!strcasecmp(str, "option")) return NX_ALTERNATEMASK;
- if (!strcasecmp(str, "alt")) return NX_ALTERNATEMASK;
- if (!strcasecmp(str, "command")) return NX_COMMANDMASK;
- if (!strcasecmp(str, "lshift")) return NX_SHIFTMASK;
- if (!strcasecmp(str, "rshift")) return NX_SHIFTMASK;
- if (!strcasecmp(str, "lcontrol")) return NX_CONTROLMASK;
- if (!strcasecmp(str, "rcontrol")) return NX_CONTROLMASK;
- if (!strcasecmp(str, "loption")) return NX_ALTERNATEMASK;
- if (!strcasecmp(str, "roption")) return NX_ALTERNATEMASK;
- if (!strcasecmp(str, "lalt")) return NX_ALTERNATEMASK;
- if (!strcasecmp(str, "ralt")) return NX_ALTERNATEMASK;
- if (!strcasecmp(str, "lcommand")) return NX_COMMANDMASK;
- if (!strcasecmp(str, "rcommand")) return NX_COMMANDMASK;
-#ifdef NX_DEVICELSHIFTKEYMASK
- }
-#endif
- if (!strcasecmp(str, "lock")) return NX_ALPHASHIFTMASK;
- if (!strcasecmp(str, "fn")) return NX_SECONDARYFNMASK;
- if (!strcasecmp(str, "help")) return NX_HELPMASK;
- if (!strcasecmp(str, "numlock")) return NX_NUMERICPADMASK;
- return 0;
-}
-
-/*
- * LegalModifier
- * This allows the ddx layer to prevent some keys from being remapped
- * as modifier keys.
- */
-Bool LegalModifier(unsigned int key, DeviceIntPtr pDev)
-{
- return 1;
-}
-
-static inline UniChar macroman2ucs(unsigned char c) {
- /* Precalculated table mapping MacRoman-128 to Unicode. Generated
- by creating single element CFStringRefs then extracting the
- first character. */
-
- static const unsigned short table[128] = {
- 0xc4, 0xc5, 0xc7, 0xc9, 0xd1, 0xd6, 0xdc, 0xe1,
- 0xe0, 0xe2, 0xe4, 0xe3, 0xe5, 0xe7, 0xe9, 0xe8,
- 0xea, 0xeb, 0xed, 0xec, 0xee, 0xef, 0xf1, 0xf3,
- 0xf2, 0xf4, 0xf6, 0xf5, 0xfa, 0xf9, 0xfb, 0xfc,
- 0x2020, 0xb0, 0xa2, 0xa3, 0xa7, 0x2022, 0xb6, 0xdf,
- 0xae, 0xa9, 0x2122, 0xb4, 0xa8, 0x2260, 0xc6, 0xd8,
- 0x221e, 0xb1, 0x2264, 0x2265, 0xa5, 0xb5, 0x2202, 0x2211,
- 0x220f, 0x3c0, 0x222b, 0xaa, 0xba, 0x3a9, 0xe6, 0xf8,
- 0xbf, 0xa1, 0xac, 0x221a, 0x192, 0x2248, 0x2206, 0xab,
- 0xbb, 0x2026, 0xa0, 0xc0, 0xc3, 0xd5, 0x152, 0x153,
- 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0xf7, 0x25ca,
- 0xff, 0x178, 0x2044, 0x20ac, 0x2039, 0x203a, 0xfb01, 0xfb02,
- 0x2021, 0xb7, 0x201a, 0x201e, 0x2030, 0xc2, 0xca, 0xc1,
- 0xcb, 0xc8, 0xcd, 0xce, 0xcf, 0xcc, 0xd3, 0xd4,
- 0xf8ff, 0xd2, 0xda, 0xdb, 0xd9, 0x131, 0x2c6, 0x2dc,
- 0xaf, 0x2d8, 0x2d9, 0x2da, 0xb8, 0x2dd, 0x2db, 0x2c7,
- };
-
- if (c < 128) return c;
- else return table[c - 128];
-}
-
-static KeySym make_dead_key(KeySym in) {
- int i;
-
- for (i = 0; i < sizeof (dead_keys) / sizeof (dead_keys[0]); i++)
- if (dead_keys[i].normal == in) return dead_keys[i].dead;
-
- return in;
-}
-
-static Bool QuartzReadSystemKeymap(darwinKeyboardInfo *info) {
-#if !defined(__LP64__) || MAC_OS_X_VERSION_MIN_REQUIRED < 1050
- KeyboardLayoutRef key_layout;
- int is_uchr = 1;
-#endif
- const void *chr_data = NULL;
- int num_keycodes = NUM_KEYCODES;
- UInt32 keyboard_type = LMGetKbdType();
- int i, j;
- OSStatus err;
- KeySym *k;
- CFDataRef currentKeyLayoutDataRef = NULL;
-
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
- TISInputSourceRef currentKeyLayoutRef = TISCopyCurrentKeyboardLayoutInputSource();
-
- if (currentKeyLayoutRef) {
- currentKeyLayoutDataRef = (CFDataRef )TISGetInputSourceProperty(currentKeyLayoutRef, kTISPropertyUnicodeKeyLayoutData);
- if (currentKeyLayoutDataRef)
- chr_data = CFDataGetBytePtr(currentKeyLayoutDataRef);
- }
-#endif
-
-#if !defined(__LP64__) || MAC_OS_X_VERSION_MIN_REQUIRED < 1050
- if (chr_data == NULL) {
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
- ErrorF("X11.app: Error detected in determining keyboard layout. If you are using an Apple-provided keyboard layout, please report this error at http://xquartz.macosforge.org and http://bugreport.apple.com\n");
- ErrorF("X11.app: Debug Info: keyboard_type=%u, currentKeyLayoutRef=%p, currentKeyLayoutDataRef=%p, chr_data=%p\n",
- (unsigned)keyboard_type, currentKeyLayoutRef, currentKeyLayoutDataRef, chr_data);
-#endif
-
- KLGetCurrentKeyboardLayout (&key_layout);
- KLGetKeyboardLayoutProperty (key_layout, kKLuchrData, &chr_data);
-
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
- if(chr_data != NULL) {
- ErrorF("X11.app: Fallback succeeded, but this is still a bug. Please report the above information.\n");
- }
-#endif
- }
-
- if (chr_data == NULL) {
- ErrorF("X11.app: Debug Info: kKLuchrData failed, trying kKLKCHRData.\n");
- ErrorF("If you are using a 3rd party keyboard layout, please see http://xquartz.macosforge.org/trac/ticket/154\n");
- KLGetKeyboardLayoutProperty (key_layout, kKLKCHRData, &chr_data);
- is_uchr = 0;
- num_keycodes = 128;
-
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
- if(chr_data != NULL) {
- ErrorF("X11.app: Fallback succeeded, but this is still a bug. Please report the above information.\n");
- }
-#endif
- }
-#endif
-
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
- if(currentKeyLayoutRef)
- CFRelease(currentKeyLayoutRef);
-#endif
-
- if (chr_data == NULL) {
- ErrorF ( "Couldn't get uchr or kchr resource\n");
- return FALSE;
- }
-
- /* Scan the keycode range for the Unicode character that each
- key produces in the four shift states. Then convert that to
- an X11 keysym (which may just the bit that says "this is
- Unicode" if it can't find the real symbol.) */
-
- /* KeyTranslate is not available on 64-bit platforms; UCKeyTranslate
- must be used instead. */
-
- for (i = 0; i < num_keycodes; i++) {
- static const int mods[4] = {0, MOD_SHIFT, MOD_OPTION,
- MOD_OPTION | MOD_SHIFT};
-
- k = info->keyMap + i * GLYPHS_PER_KEY;
-
- for (j = 0; j < 4; j++) {
-#if !defined(__LP64__) || MAC_OS_X_VERSION_MIN_REQUIRED < 1050
- if (is_uchr) {
-#endif
- UniChar s[8];
- UniCharCount len;
- UInt32 dead_key_state = 0, extra_dead = 0;
-
- err = UCKeyTranslate (chr_data, i, kUCKeyActionDown,
- mods[j] >> 8, keyboard_type, 0,
- &dead_key_state, 8, &len, s);
- if (err != noErr) continue;
-
- if (len == 0 && dead_key_state != 0) {
- /* Found a dead key. Work out which one it is, but
- remembering that it's dead. */
- err = UCKeyTranslate (chr_data, i, kUCKeyActionDown,
- mods[j] >> 8, keyboard_type,
- kUCKeyTranslateNoDeadKeysMask,
- &extra_dead, 8, &len, s);
- if (err != noErr) continue;
- }
-
- /* Not sure why 0x0010 is there.
- * 0x0000 - <rdar://problem/7793566> 'Unicode Hex Input' ...
- */
- if (len > 0 && s[0] != 0x0010 && s[0] != 0x0000) {
- k[j] = ucs2keysym (s[0]);
- if (dead_key_state != 0) k[j] = make_dead_key (k[j]);
- }
-#if !defined(__LP64__) || MAC_OS_X_VERSION_MIN_REQUIRED < 1050
- } else { // kchr
- UInt32 c, state = 0, state2 = 0;
- UInt16 code;
-
- code = i | mods[j];
- c = KeyTranslate (chr_data, code, &state);
-
- /* Dead keys are only processed on key-down, so ask
- to translate those events. When we find a dead key,
- translating the matching key up event will give
- us the actual dead character. */
-
- if (state != 0)
- c = KeyTranslate (chr_data, code | 128, &state2);
-
- /* Characters seem to be in MacRoman encoding. */
-
- if (c != 0 && c != 0x0010) {
- k[j] = ucs2keysym (macroman2ucs (c & 255));
-
- if (state != 0) k[j] = make_dead_key (k[j]);
- }
- }
-#endif
- }
-
- if (k[3] == k[2]) k[3] = NoSymbol;
- if (k[1] == k[0]) k[1] = NoSymbol;
- if (k[0] == k[2] && k[1] == k[3]) k[2] = k[3] = NoSymbol;
- if (k[3] == k[0] && k[2] == k[1] && k[2] == NoSymbol) k[3] = NoSymbol;
- }
-
-#if HACK_MISSING
- /* Fix up some things that are normally missing.. */
-
- for (i = 0; i < sizeof (known_keys) / sizeof (known_keys[0]); i++) {
- k = info->keyMap + known_keys[i].keycode * GLYPHS_PER_KEY;
-
- if ( k[0] == NoSymbol && k[1] == NoSymbol
- && k[2] == NoSymbol && k[3] == NoSymbol)
- k[0] = known_keys[i].keysym;
- }
-#endif
-
-#if HACK_KEYPAD
- /* And some more things. We find the right symbols for the numeric
- keypad, but not the KP_ keysyms. So try to convert known keycodes. */
- for (i = 0; i < sizeof (known_numeric_keys) / sizeof (known_numeric_keys[0]); i++) {
- k = info->keyMap + known_numeric_keys[i].keycode * GLYPHS_PER_KEY;
-
- if (k[0] == known_numeric_keys[i].normal)
- k[0] = known_numeric_keys[i].keypad;
- }
-#endif
-
-#if HACK_BLACKLIST
- for (i = 0; i < sizeof (keycode_blacklist) / sizeof (keycode_blacklist[0]); i++) {
- k = info->keyMap + keycode_blacklist[i] * GLYPHS_PER_KEY;
- k[0] = k[1] = k[2] = k[3] = NoSymbol;
- }
-#endif
-
- DarwinBuildModifierMaps(info);
-
- return TRUE;
-}
-
-Bool QuartsResyncKeymap(Bool sendDDXEvent) {
- Bool retval;
- /* Update keyInfo */
- pthread_mutex_lock(&keyInfo_mutex);
- memset(keyInfo.keyMap, 0, sizeof(keyInfo.keyMap));
- retval = QuartzReadSystemKeymap(&keyInfo);
- pthread_mutex_unlock(&keyInfo_mutex);
-
- /* Tell server thread to deal with new keyInfo */
- if(sendDDXEvent)
- DarwinSendDDXEvent(kXquartzReloadKeymap, 0);
-
- return retval;
-}
+/* + quartzKeyboard.c: Keyboard support for Xquartz + + Copyright (c) 2003-2008 Apple Inc. + Copyright (c) 2001-2004 Torrey T. Lyons. All Rights Reserved. + Copyright 2004 Kaleb S. KEITHLEY. All Rights Reserved. + + Copyright (C) 1999,2000 by Eric Sunshine <sunshine@sunshineco.com> + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "sanitizedCarbon.h" + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#define HACK_MISSING 1 +#define HACK_KEYPAD 1 +#define HACK_BLACKLIST 1 + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/stat.h> +#include <AvailabilityMacros.h> + +#include "quartz.h" +#include "darwin.h" +#include "darwinEvents.h" + +#include "quartzKeyboard.h" + +#include "X11Application.h" + +#include "threadSafety.h" + +#ifdef NDEBUG +#undef NDEBUG +#include <assert.h> +#define NDEBUG 1 +#else +#include <assert.h> +#endif +#include <pthread.h> + +#include "xkbsrv.h" +#include "exevents.h" +#include "X11/keysym.h" +#include "keysym2ucs.h" + +extern void +CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master); + +enum { + MOD_COMMAND = 256, + MOD_SHIFT = 512, + MOD_OPTION = 2048, + MOD_CONTROL = 4096, +}; + +#define UKEYSYM(u) ((u) | 0x01000000) + +#if HACK_MISSING +/* Table of keycode->keysym mappings we use to fallback on for important + keys that are often not in the Unicode mapping. */ + +const static struct { + unsigned short keycode; + KeySym keysym; +} known_keys[] = { + {55, XK_Meta_L}, + {56, XK_Shift_L}, + {57, XK_Caps_Lock}, + {58, XK_Alt_L}, + {59, XK_Control_L}, + + {60, XK_Shift_R}, + {61, XK_Alt_R}, + {62, XK_Control_R}, + {63, XK_Meta_R}, + + {122, XK_F1}, + {120, XK_F2}, + {99, XK_F3}, + {118, XK_F4}, + {96, XK_F5}, + {97, XK_F6}, + {98, XK_F7}, + {100, XK_F8}, + {101, XK_F9}, + {109, XK_F10}, + {103, XK_F11}, + {111, XK_F12}, + {105, XK_F13}, + {107, XK_F14}, + {113, XK_F15}, +}; +#endif + +#if HACK_KEYPAD +/* Table of keycode->old,new-keysym mappings we use to fixup the numeric + keypad entries. */ + +const static struct { + unsigned short keycode; + KeySym normal, keypad; +} known_numeric_keys[] = { + {65, XK_period, XK_KP_Decimal}, + {67, XK_asterisk, XK_KP_Multiply}, + {69, XK_plus, XK_KP_Add}, + {75, XK_slash, XK_KP_Divide}, + {76, 0x01000003, XK_KP_Enter}, + {78, XK_minus, XK_KP_Subtract}, + {81, XK_equal, XK_KP_Equal}, + {82, XK_0, XK_KP_0}, + {83, XK_1, XK_KP_1}, + {84, XK_2, XK_KP_2}, + {85, XK_3, XK_KP_3}, + {86, XK_4, XK_KP_4}, + {87, XK_5, XK_KP_5}, + {88, XK_6, XK_KP_6}, + {89, XK_7, XK_KP_7}, + {91, XK_8, XK_KP_8}, + {92, XK_9, XK_KP_9}, +}; +#endif + +#if HACK_BLACKLIST +/* <rdar://problem/7824370> wine notepad produces wrong characters on shift+arrow + * http://xquartz.macosforge.org/trac/ticket/295 + * http://developer.apple.com/legacy/mac/library/documentation/mac/Text/Text-579.html + * + * legacy Mac keycodes for arrow keys that shift-modify to math symbols + */ +const static unsigned short keycode_blacklist[] = {66, 70, 72, 77}; +#endif + +/* Table mapping normal keysyms to their dead equivalents. + FIXME: all the unicode keysyms (apart from circumflex) were guessed. */ + +const static struct { + KeySym normal, dead; +} dead_keys[] = { + {XK_grave, XK_dead_grave}, + {XK_apostrophe, XK_dead_acute}, /* US:"=" on a Czech keyboard */ + {XK_acute, XK_dead_acute}, + {UKEYSYM (0x384), XK_dead_acute}, /* US:";" on a Greek keyboard */ +// {XK_Greek_accentdieresis, XK_dead_diaeresis}, /* US:"opt+;" on a Greek keyboard ... replace with dead_accentdieresis if there is one */ + {XK_asciicircum, XK_dead_circumflex}, + {UKEYSYM (0x2c6), XK_dead_circumflex}, /* MODIFIER LETTER CIRCUMFLEX ACCENT */ + {XK_asciitilde, XK_dead_tilde}, + {UKEYSYM (0x2dc), XK_dead_tilde}, /* SMALL TILDE */ + {XK_macron, XK_dead_macron}, + {XK_breve, XK_dead_breve}, + {XK_abovedot, XK_dead_abovedot}, + {XK_diaeresis, XK_dead_diaeresis}, + {UKEYSYM (0x2da), XK_dead_abovering}, /* DOT ABOVE */ + {XK_doubleacute, XK_dead_doubleacute}, + {XK_caron, XK_dead_caron}, + {XK_cedilla, XK_dead_cedilla}, + {XK_ogonek, XK_dead_ogonek}, + {UKEYSYM (0x269), XK_dead_iota}, /* LATIN SMALL LETTER IOTA */ + {UKEYSYM (0x2ec), XK_dead_voiced_sound}, /* MODIFIER LETTER VOICING */ +/* {XK_semivoiced_sound, XK_dead_semivoiced_sound}, */ + {UKEYSYM (0x323), XK_dead_belowdot}, /* COMBINING DOT BELOW */ + {UKEYSYM (0x309), XK_dead_hook}, /* COMBINING HOOK ABOVE */ + {UKEYSYM (0x31b), XK_dead_horn}, /* COMBINING HORN */ +}; + +typedef struct darwinKeyboardInfo_struct { + CARD8 modMap[MAP_LENGTH]; + KeySym keyMap[MAP_LENGTH * GLYPHS_PER_KEY]; + unsigned char modifierKeycodes[32][2]; +} darwinKeyboardInfo; + +darwinKeyboardInfo keyInfo; +pthread_mutex_t keyInfo_mutex = PTHREAD_MUTEX_INITIALIZER; + +static void DarwinChangeKeyboardControl(DeviceIntPtr device, KeybdCtrl *ctrl) { + // FIXME: to be implemented + // keyclick, bell volume / pitch, autorepead, LED's +} + +//----------------------------------------------------------------------------- +// Utility functions to help parse Darwin keymap +//----------------------------------------------------------------------------- + +/* + * DarwinBuildModifierMaps + * Use the keyMap field of keyboard info structure to populate + * the modMap and modifierKeycodes fields. + */ +static void DarwinBuildModifierMaps(darwinKeyboardInfo *info) { + int i; + KeySym *k; + + memset(info->modMap, NoSymbol, sizeof(info->modMap)); + memset(info->modifierKeycodes, 0, sizeof(info->modifierKeycodes)); + + for (i = 0; i < NUM_KEYCODES; i++) { + k = info->keyMap + i * GLYPHS_PER_KEY; + + switch (*k) { + case XK_Shift_L: + info->modifierKeycodes[NX_MODIFIERKEY_SHIFT][0] = i; + info->modMap[MIN_KEYCODE + i] = ShiftMask; + break; + + case XK_Shift_R: +#ifdef NX_MODIFIERKEY_RSHIFT + info->modifierKeycodes[NX_MODIFIERKEY_RSHIFT][0] = i; +#else + info->modifierKeycodes[NX_MODIFIERKEY_SHIFT][0] = i; +#endif + info->modMap[MIN_KEYCODE + i] = ShiftMask; + break; + + case XK_Control_L: + info->modifierKeycodes[NX_MODIFIERKEY_CONTROL][0] = i; + info->modMap[MIN_KEYCODE + i] = ControlMask; + break; + + case XK_Control_R: +#ifdef NX_MODIFIERKEY_RCONTROL + info->modifierKeycodes[NX_MODIFIERKEY_RCONTROL][0] = i; +#else + info->modifierKeycodes[NX_MODIFIERKEY_CONTROL][0] = i; +#endif + info->modMap[MIN_KEYCODE + i] = ControlMask; + break; + + case XK_Caps_Lock: + info->modifierKeycodes[NX_MODIFIERKEY_ALPHALOCK][0] = i; + info->modMap[MIN_KEYCODE + i] = LockMask; + break; + + case XK_Alt_L: + info->modifierKeycodes[NX_MODIFIERKEY_ALTERNATE][0] = i; + info->modMap[MIN_KEYCODE + i] = Mod1Mask; + if(!XQuartzOptionSendsAlt) + *k = XK_Mode_switch; // Yes, this is ugly. This needs to be cleaned up when we integrate quartzKeyboard with this code and refactor. + break; + + case XK_Alt_R: +#ifdef NX_MODIFIERKEY_RALTERNATE + info->modifierKeycodes[NX_MODIFIERKEY_RALTERNATE][0] = i; +#else + info->modifierKeycodes[NX_MODIFIERKEY_ALTERNATE][0] = i; +#endif + if(!XQuartzOptionSendsAlt) + *k = XK_Mode_switch; // Yes, this is ugly. This needs to be cleaned up when we integrate quartzKeyboard with this code and refactor. + info->modMap[MIN_KEYCODE + i] = Mod1Mask; + break; + + case XK_Mode_switch: + ErrorF("DarwinBuildModifierMaps: XK_Mode_switch encountered, unable to determine side.\n"); + info->modifierKeycodes[NX_MODIFIERKEY_ALTERNATE][0] = i; +#ifdef NX_MODIFIERKEY_RALTERNATE + info->modifierKeycodes[NX_MODIFIERKEY_RALTERNATE][0] = i; +#endif + info->modMap[MIN_KEYCODE + i] = Mod1Mask; + break; + + case XK_Meta_L: + info->modifierKeycodes[NX_MODIFIERKEY_COMMAND][0] = i; + info->modMap[MIN_KEYCODE + i] = Mod2Mask; + break; + + case XK_Meta_R: +#ifdef NX_MODIFIERKEY_RCOMMAND + info->modifierKeycodes[NX_MODIFIERKEY_RCOMMAND][0] = i; +#else + info->modifierKeycodes[NX_MODIFIERKEY_COMMAND][0] = i; +#endif + info->modMap[MIN_KEYCODE + i] = Mod2Mask; + break; + + case XK_Num_Lock: + info->modMap[MIN_KEYCODE + i] = Mod3Mask; + break; + } + } +} + +/* + * DarwinKeyboardInit + * Get the Darwin keyboard map and compute an equivalent + * X keyboard map and modifier map. Set the new keyboard + * device structure. + */ +void DarwinKeyboardInit(DeviceIntPtr pDev) { + // Open a shared connection to the HID System. + // Note that the Event Status Driver is really just a wrapper + // for a kIOHIDParamConnectType connection. + assert(darwinParamConnect = NXOpenEventStatus()); + + InitKeyboardDeviceStruct(pDev, NULL, NULL, DarwinChangeKeyboardControl); + + DarwinKeyboardReloadHandler(); + + CopyKeyClass(pDev, inputInfo.keyboard); +} + +/* Set the repeat rates based on global preferences and keycodes for modifiers. + * Precondition: Has the keyInfo_mutex lock. + */ +static void DarwinKeyboardSetRepeat(DeviceIntPtr pDev, int initialKeyRepeatValue, int keyRepeatValue) { + if(initialKeyRepeatValue == 300000) { // off + /* Turn off repeats globally */ + XkbSetRepeatKeys(pDev, -1, AutoRepeatModeOff); + } else { + int i; + XkbControlsPtr ctrl; + XkbControlsRec old; + + /* Turn on repeats globally */ + XkbSetRepeatKeys(pDev, -1, AutoRepeatModeOn); + + /* Setup the bit mask for individual key repeats */ + ctrl = pDev->key->xkbInfo->desc->ctrls; + old= *ctrl; + + ctrl->repeat_delay = initialKeyRepeatValue * 15; + ctrl->repeat_interval = keyRepeatValue * 15; + + /* Turn off key-repeat for modifier keys, on for others */ + /* First set them all on */ + for(i=0; i < XkbPerKeyBitArraySize; i++) + ctrl->per_key_repeat[i] = -1; + + /* Now turn off the modifiers */ + for(i=0; i < 32; i++) { + unsigned char keycode; + + keycode = keyInfo.modifierKeycodes[i][0]; + if(keycode) + ClearBit(ctrl->per_key_repeat, keycode + MIN_KEYCODE); + + keycode = keyInfo.modifierKeycodes[i][1]; + if(keycode) + ClearBit(ctrl->per_key_repeat, keycode + MIN_KEYCODE); + } + + /* Hurray for data duplication */ + if (pDev->kbdfeed) + memcpy(pDev->kbdfeed->ctrl.autoRepeats, ctrl->per_key_repeat, XkbPerKeyBitArraySize); + + //fprintf(stderr, "per_key_repeat =\n"); + //for(i=0; i < XkbPerKeyBitArraySize; i++) + // fprintf(stderr, "%02x%s", ctrl->per_key_repeat[i], (i + 1) & 7 ? "" : "\n"); + + /* And now we notify the puppies about the changes */ + XkbDDXChangeControls(pDev, &old, ctrl); + } +} + +void DarwinKeyboardReloadHandler(void) { + KeySymsRec keySyms; + CFIndex initialKeyRepeatValue, keyRepeatValue; + BOOL ok; + DeviceIntPtr pDev; + const char *xmodmap = PROJECTROOT "/bin/xmodmap"; + const char *sysmodmap = PROJECTROOT "/lib/X11/xinit/.Xmodmap"; + const char *homedir = getenv("HOME"); + char usermodmap[PATH_MAX], cmd[PATH_MAX]; + + DEBUG_LOG("DarwinKeyboardReloadHandler\n"); + + /* Get our key repeat settings from GlobalPreferences */ + (void)CFPreferencesAppSynchronize(CFSTR(".GlobalPreferences")); + + initialKeyRepeatValue = CFPreferencesGetAppIntegerValue(CFSTR("InitialKeyRepeat"), CFSTR(".GlobalPreferences"), &ok); + if(!ok) + initialKeyRepeatValue = 35; + + keyRepeatValue = CFPreferencesGetAppIntegerValue(CFSTR("KeyRepeat"), CFSTR(".GlobalPreferences"), &ok); + if(!ok) + keyRepeatValue = 6; + + pthread_mutex_lock(&keyInfo_mutex); { + /* Initialize our keySyms */ + keySyms.map = keyInfo.keyMap; + keySyms.mapWidth = GLYPHS_PER_KEY; + keySyms.minKeyCode = MIN_KEYCODE; + keySyms.maxKeyCode = MAX_KEYCODE; + + // TODO: We should build the entire XkbDescRec and use XkbCopyKeymap + /* Apply the mappings to darwinKeyboard */ + XkbApplyMappingChange(darwinKeyboard, &keySyms, keySyms.minKeyCode, + keySyms.maxKeyCode - keySyms.minKeyCode + 1, + keyInfo.modMap, serverClient); + DarwinKeyboardSetRepeat(darwinKeyboard, initialKeyRepeatValue, keyRepeatValue); + + /* Apply the mappings to the core keyboard */ + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { + if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) { + XkbApplyMappingChange(pDev, &keySyms, keySyms.minKeyCode, + keySyms.maxKeyCode - keySyms.minKeyCode + 1, + keyInfo.modMap, serverClient); + DarwinKeyboardSetRepeat(pDev, initialKeyRepeatValue, keyRepeatValue); + } + } + } pthread_mutex_unlock(&keyInfo_mutex); + + /* Modify with xmodmap */ + if (access(xmodmap, F_OK) == 0) { + /* Check for system .Xmodmap */ + if (access(sysmodmap, F_OK) == 0) { + if(snprintf (cmd, sizeof(cmd), "%s %s", xmodmap, sysmodmap) < sizeof(cmd)) { + X11ApplicationLaunchClient(cmd); + } else { + ErrorF("X11.app: Unable to create / execute xmodmap command line"); + } + } + + /* Check for user's local .Xmodmap */ + if ((homedir != NULL) && (snprintf (usermodmap, sizeof(usermodmap), "%s/.Xmodmap", homedir) < sizeof(usermodmap))) { + if (access(usermodmap, F_OK) == 0) { + if(snprintf (cmd, sizeof(cmd), "%s %s", xmodmap, usermodmap) < sizeof(cmd)) { + X11ApplicationLaunchClient(cmd); + } else { + ErrorF("X11.app: Unable to create / execute xmodmap command line"); + } + } + } else { + ErrorF("X11.app: Unable to determine path to user's .Xmodmap"); + } + } +} + +//----------------------------------------------------------------------------- +// Modifier translation functions +// +// There are three different ways to specify a Mac modifier key: +// keycode - specifies hardware key, read from keymapping +// key - NX_MODIFIERKEY_*, really an index +// mask - NX_*MASK, mask for modifier flags in event record +// Left and right side have different keycodes but the same key and mask. +//----------------------------------------------------------------------------- + +/* + * DarwinModifierNXKeyToNXKeycode + * Return the keycode for an NX_MODIFIERKEY_* modifier. + * side = 0 for left or 1 for right. + * Returns 0 if key+side is not a known modifier. + */ +int DarwinModifierNXKeyToNXKeycode(int key, int side) { + int retval; + pthread_mutex_lock(&keyInfo_mutex); + retval = keyInfo.modifierKeycodes[key][side]; + pthread_mutex_unlock(&keyInfo_mutex); + + return retval; +} + +/* + * DarwinModifierNXKeycodeToNXKey + * Returns -1 if keycode+side is not a modifier key + * outSide may be NULL, else it gets 0 for left and 1 for right. + */ +int DarwinModifierNXKeycodeToNXKey(unsigned char keycode, int *outSide) { + int key, side; + + keycode += MIN_KEYCODE; + + // search modifierKeycodes for this keycode+side + pthread_mutex_lock(&keyInfo_mutex); + for (key = 0; key < NX_NUMMODIFIERS; key++) { + for (side = 0; side <= 1; side++) { + if (keyInfo.modifierKeycodes[key][side] == keycode) break; + } + } + pthread_mutex_unlock(&keyInfo_mutex); + + if (key == NX_NUMMODIFIERS) { + return -1; + } + if (outSide) *outSide = side; + + return key; +} + +/* + * DarwinModifierNXMaskToNXKey + * Returns -1 if mask is not a known modifier mask. + */ +int DarwinModifierNXMaskToNXKey(int mask) { + switch (mask) { + case NX_ALPHASHIFTMASK: return NX_MODIFIERKEY_ALPHALOCK; + case NX_SHIFTMASK: return NX_MODIFIERKEY_SHIFT; +#ifdef NX_DEVICELSHIFTKEYMASK + case NX_DEVICELSHIFTKEYMASK: return NX_MODIFIERKEY_SHIFT; + case NX_DEVICERSHIFTKEYMASK: return NX_MODIFIERKEY_RSHIFT; +#endif + case NX_CONTROLMASK: return NX_MODIFIERKEY_CONTROL; +#ifdef NX_DEVICELCTLKEYMASK + case NX_DEVICELCTLKEYMASK: return NX_MODIFIERKEY_CONTROL; + case NX_DEVICERCTLKEYMASK: return NX_MODIFIERKEY_RCONTROL; +#endif + case NX_ALTERNATEMASK: return NX_MODIFIERKEY_ALTERNATE; +#ifdef NX_DEVICELALTKEYMASK + case NX_DEVICELALTKEYMASK: return NX_MODIFIERKEY_ALTERNATE; + case NX_DEVICERALTKEYMASK: return NX_MODIFIERKEY_RALTERNATE; +#endif + case NX_COMMANDMASK: return NX_MODIFIERKEY_COMMAND; +#ifdef NX_DEVICELCMDKEYMASK + case NX_DEVICELCMDKEYMASK: return NX_MODIFIERKEY_COMMAND; + case NX_DEVICERCMDKEYMASK: return NX_MODIFIERKEY_RCOMMAND; +#endif + case NX_NUMERICPADMASK: return NX_MODIFIERKEY_NUMERICPAD; + case NX_HELPMASK: return NX_MODIFIERKEY_HELP; + case NX_SECONDARYFNMASK: return NX_MODIFIERKEY_SECONDARYFN; + } + return -1; +} + +/* + * DarwinModifierNXKeyToNXMask + * Returns 0 if key is not a known modifier key. + */ +int DarwinModifierNXKeyToNXMask(int key) { + switch (key) { + case NX_MODIFIERKEY_ALPHALOCK: return NX_ALPHASHIFTMASK; +#ifdef NX_DEVICELSHIFTKEYMASK + case NX_MODIFIERKEY_SHIFT: return NX_DEVICELSHIFTKEYMASK; + case NX_MODIFIERKEY_RSHIFT: return NX_DEVICERSHIFTKEYMASK; + case NX_MODIFIERKEY_CONTROL: return NX_DEVICELCTLKEYMASK; + case NX_MODIFIERKEY_RCONTROL: return NX_DEVICERCTLKEYMASK; + case NX_MODIFIERKEY_ALTERNATE: return NX_DEVICELALTKEYMASK; + case NX_MODIFIERKEY_RALTERNATE: return NX_DEVICERALTKEYMASK; + case NX_MODIFIERKEY_COMMAND: return NX_DEVICELCMDKEYMASK; + case NX_MODIFIERKEY_RCOMMAND: return NX_DEVICERCMDKEYMASK; +#else + case NX_MODIFIERKEY_SHIFT: return NX_SHIFTMASK; + case NX_MODIFIERKEY_CONTROL: return NX_CONTROLMASK; + case NX_MODIFIERKEY_ALTERNATE: return NX_ALTERNATEMASK; + case NX_MODIFIERKEY_COMMAND: return NX_COMMANDMASK; +#endif + case NX_MODIFIERKEY_NUMERICPAD: return NX_NUMERICPADMASK; + case NX_MODIFIERKEY_HELP: return NX_HELPMASK; + case NX_MODIFIERKEY_SECONDARYFN: return NX_SECONDARYFNMASK; + } + return 0; +} + +/* + * DarwinModifierStringToNXMask + * Returns 0 if string is not a known modifier. + */ +int DarwinModifierStringToNXMask(const char *str, int separatelr) { +#ifdef NX_DEVICELSHIFTKEYMASK + if(separatelr) { + if (!strcasecmp(str, "shift")) return NX_DEVICELSHIFTKEYMASK | NX_DEVICERSHIFTKEYMASK; + if (!strcasecmp(str, "control")) return NX_DEVICELCTLKEYMASK | NX_DEVICERCTLKEYMASK; + if (!strcasecmp(str, "option")) return NX_DEVICELALTKEYMASK | NX_DEVICERALTKEYMASK; + if (!strcasecmp(str, "alt")) return NX_DEVICELALTKEYMASK | NX_DEVICERALTKEYMASK; + if (!strcasecmp(str, "command")) return NX_DEVICELCMDKEYMASK | NX_DEVICERCMDKEYMASK; + if (!strcasecmp(str, "lshift")) return NX_DEVICELSHIFTKEYMASK; + if (!strcasecmp(str, "rshift")) return NX_DEVICERSHIFTKEYMASK; + if (!strcasecmp(str, "lcontrol")) return NX_DEVICELCTLKEYMASK; + if (!strcasecmp(str, "rcontrol")) return NX_DEVICERCTLKEYMASK; + if (!strcasecmp(str, "loption")) return NX_DEVICELALTKEYMASK; + if (!strcasecmp(str, "roption")) return NX_DEVICERALTKEYMASK; + if (!strcasecmp(str, "lalt")) return NX_DEVICELALTKEYMASK; + if (!strcasecmp(str, "ralt")) return NX_DEVICERALTKEYMASK; + if (!strcasecmp(str, "lcommand")) return NX_DEVICELCMDKEYMASK; + if (!strcasecmp(str, "rcommand")) return NX_DEVICERCMDKEYMASK; + } else { +#endif + if (!strcasecmp(str, "shift")) return NX_SHIFTMASK; + if (!strcasecmp(str, "control")) return NX_CONTROLMASK; + if (!strcasecmp(str, "option")) return NX_ALTERNATEMASK; + if (!strcasecmp(str, "alt")) return NX_ALTERNATEMASK; + if (!strcasecmp(str, "command")) return NX_COMMANDMASK; + if (!strcasecmp(str, "lshift")) return NX_SHIFTMASK; + if (!strcasecmp(str, "rshift")) return NX_SHIFTMASK; + if (!strcasecmp(str, "lcontrol")) return NX_CONTROLMASK; + if (!strcasecmp(str, "rcontrol")) return NX_CONTROLMASK; + if (!strcasecmp(str, "loption")) return NX_ALTERNATEMASK; + if (!strcasecmp(str, "roption")) return NX_ALTERNATEMASK; + if (!strcasecmp(str, "lalt")) return NX_ALTERNATEMASK; + if (!strcasecmp(str, "ralt")) return NX_ALTERNATEMASK; + if (!strcasecmp(str, "lcommand")) return NX_COMMANDMASK; + if (!strcasecmp(str, "rcommand")) return NX_COMMANDMASK; +#ifdef NX_DEVICELSHIFTKEYMASK + } +#endif + if (!strcasecmp(str, "lock")) return NX_ALPHASHIFTMASK; + if (!strcasecmp(str, "fn")) return NX_SECONDARYFNMASK; + if (!strcasecmp(str, "help")) return NX_HELPMASK; + if (!strcasecmp(str, "numlock")) return NX_NUMERICPADMASK; + return 0; +} + +/* + * LegalModifier + * This allows the ddx layer to prevent some keys from being remapped + * as modifier keys. + */ +Bool LegalModifier(unsigned int key, DeviceIntPtr pDev) +{ + return 1; +} + +static inline UniChar macroman2ucs(unsigned char c) { + /* Precalculated table mapping MacRoman-128 to Unicode. Generated + by creating single element CFStringRefs then extracting the + first character. */ + + static const unsigned short table[128] = { + 0xc4, 0xc5, 0xc7, 0xc9, 0xd1, 0xd6, 0xdc, 0xe1, + 0xe0, 0xe2, 0xe4, 0xe3, 0xe5, 0xe7, 0xe9, 0xe8, + 0xea, 0xeb, 0xed, 0xec, 0xee, 0xef, 0xf1, 0xf3, + 0xf2, 0xf4, 0xf6, 0xf5, 0xfa, 0xf9, 0xfb, 0xfc, + 0x2020, 0xb0, 0xa2, 0xa3, 0xa7, 0x2022, 0xb6, 0xdf, + 0xae, 0xa9, 0x2122, 0xb4, 0xa8, 0x2260, 0xc6, 0xd8, + 0x221e, 0xb1, 0x2264, 0x2265, 0xa5, 0xb5, 0x2202, 0x2211, + 0x220f, 0x3c0, 0x222b, 0xaa, 0xba, 0x3a9, 0xe6, 0xf8, + 0xbf, 0xa1, 0xac, 0x221a, 0x192, 0x2248, 0x2206, 0xab, + 0xbb, 0x2026, 0xa0, 0xc0, 0xc3, 0xd5, 0x152, 0x153, + 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0xf7, 0x25ca, + 0xff, 0x178, 0x2044, 0x20ac, 0x2039, 0x203a, 0xfb01, 0xfb02, + 0x2021, 0xb7, 0x201a, 0x201e, 0x2030, 0xc2, 0xca, 0xc1, + 0xcb, 0xc8, 0xcd, 0xce, 0xcf, 0xcc, 0xd3, 0xd4, + 0xf8ff, 0xd2, 0xda, 0xdb, 0xd9, 0x131, 0x2c6, 0x2dc, + 0xaf, 0x2d8, 0x2d9, 0x2da, 0xb8, 0x2dd, 0x2db, 0x2c7, + }; + + if (c < 128) return c; + else return table[c - 128]; +} + +static KeySym make_dead_key(KeySym in) { + int i; + + for (i = 0; i < sizeof (dead_keys) / sizeof (dead_keys[0]); i++) + if (dead_keys[i].normal == in) return dead_keys[i].dead; + + return in; +} + +static Bool QuartzReadSystemKeymap(darwinKeyboardInfo *info) { +#if !defined(__LP64__) || MAC_OS_X_VERSION_MIN_REQUIRED < 1050 + KeyboardLayoutRef key_layout; + int is_uchr = 1; +#endif + const void *chr_data = NULL; + int num_keycodes = NUM_KEYCODES; + UInt32 keyboard_type = LMGetKbdType(); + int i, j; + OSStatus err; + KeySym *k; + CFDataRef currentKeyLayoutDataRef = NULL; + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 + TISInputSourceRef currentKeyLayoutRef = TISCopyCurrentKeyboardLayoutInputSource(); + + if (currentKeyLayoutRef) { + currentKeyLayoutDataRef = (CFDataRef )TISGetInputSourceProperty(currentKeyLayoutRef, kTISPropertyUnicodeKeyLayoutData); + if (currentKeyLayoutDataRef) + chr_data = CFDataGetBytePtr(currentKeyLayoutDataRef); + } +#endif + +#if !defined(__LP64__) || MAC_OS_X_VERSION_MIN_REQUIRED < 1050 + if (chr_data == NULL) { +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 + ErrorF("X11.app: Error detected in determining keyboard layout. If you are using an Apple-provided keyboard layout, please report this error at http://xquartz.macosforge.org and http://bugreport.apple.com\n"); + ErrorF("X11.app: Debug Info: keyboard_type=%u, currentKeyLayoutRef=%p, currentKeyLayoutDataRef=%p, chr_data=%p\n", + (unsigned)keyboard_type, currentKeyLayoutRef, currentKeyLayoutDataRef, chr_data); +#endif + + KLGetCurrentKeyboardLayout (&key_layout); + KLGetKeyboardLayoutProperty (key_layout, kKLuchrData, &chr_data); + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 + if(chr_data != NULL) { + ErrorF("X11.app: Fallback succeeded, but this is still a bug. Please report the above information.\n"); + } +#endif + } + + if (chr_data == NULL) { + ErrorF("X11.app: Debug Info: kKLuchrData failed, trying kKLKCHRData.\n"); + ErrorF("If you are using a 3rd party keyboard layout, please see http://xquartz.macosforge.org/trac/ticket/154\n"); + KLGetKeyboardLayoutProperty (key_layout, kKLKCHRData, &chr_data); + is_uchr = 0; + num_keycodes = 128; + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 + if(chr_data != NULL) { + ErrorF("X11.app: Fallback succeeded, but this is still a bug. Please report the above information.\n"); + } +#endif + } +#endif + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 + if(currentKeyLayoutRef) + CFRelease(currentKeyLayoutRef); +#endif + + if (chr_data == NULL) { + ErrorF ( "Couldn't get uchr or kchr resource\n"); + return FALSE; + } + + /* Scan the keycode range for the Unicode character that each + key produces in the four shift states. Then convert that to + an X11 keysym (which may just the bit that says "this is + Unicode" if it can't find the real symbol.) */ + + /* KeyTranslate is not available on 64-bit platforms; UCKeyTranslate + must be used instead. */ + + for (i = 0; i < num_keycodes; i++) { + static const int mods[4] = {0, MOD_SHIFT, MOD_OPTION, + MOD_OPTION | MOD_SHIFT}; + + k = info->keyMap + i * GLYPHS_PER_KEY; + + for (j = 0; j < 4; j++) { +#if !defined(__LP64__) || MAC_OS_X_VERSION_MIN_REQUIRED < 1050 + if (is_uchr) { +#endif + UniChar s[8]; + UniCharCount len; + UInt32 dead_key_state = 0, extra_dead = 0; + + err = UCKeyTranslate (chr_data, i, kUCKeyActionDown, + mods[j] >> 8, keyboard_type, 0, + &dead_key_state, 8, &len, s); + if (err != noErr) continue; + + if (len == 0 && dead_key_state != 0) { + /* Found a dead key. Work out which one it is, but + remembering that it's dead. */ + err = UCKeyTranslate (chr_data, i, kUCKeyActionDown, + mods[j] >> 8, keyboard_type, + kUCKeyTranslateNoDeadKeysMask, + &extra_dead, 8, &len, s); + if (err != noErr) continue; + } + + /* Not sure why 0x0010 is there. + * 0x0000 - <rdar://problem/7793566> 'Unicode Hex Input' ... + */ + if (len > 0 && s[0] != 0x0010 && s[0] != 0x0000) { + k[j] = ucs2keysym (s[0]); + if (dead_key_state != 0) k[j] = make_dead_key (k[j]); + } +#if !defined(__LP64__) || MAC_OS_X_VERSION_MIN_REQUIRED < 1050 + } else { // kchr + UInt32 c, state = 0, state2 = 0; + UInt16 code; + + code = i | mods[j]; + c = KeyTranslate (chr_data, code, &state); + + /* Dead keys are only processed on key-down, so ask + to translate those events. When we find a dead key, + translating the matching key up event will give + us the actual dead character. */ + + if (state != 0) + c = KeyTranslate (chr_data, code | 128, &state2); + + /* Characters seem to be in MacRoman encoding. */ + + if (c != 0 && c != 0x0010) { + k[j] = ucs2keysym (macroman2ucs (c & 255)); + + if (state != 0) k[j] = make_dead_key (k[j]); + } + } +#endif + } + + if (k[3] == k[2]) k[3] = NoSymbol; + if (k[1] == k[0]) k[1] = NoSymbol; + if (k[0] == k[2] && k[1] == k[3]) k[2] = k[3] = NoSymbol; + if (k[3] == k[0] && k[2] == k[1] && k[2] == NoSymbol) k[3] = NoSymbol; + } + +#if HACK_MISSING + /* Fix up some things that are normally missing.. */ + + for (i = 0; i < sizeof (known_keys) / sizeof (known_keys[0]); i++) { + k = info->keyMap + known_keys[i].keycode * GLYPHS_PER_KEY; + + if ( k[0] == NoSymbol && k[1] == NoSymbol + && k[2] == NoSymbol && k[3] == NoSymbol) + k[0] = known_keys[i].keysym; + } +#endif + +#if HACK_KEYPAD + /* And some more things. We find the right symbols for the numeric + keypad, but not the KP_ keysyms. So try to convert known keycodes. */ + for (i = 0; i < sizeof (known_numeric_keys) / sizeof (known_numeric_keys[0]); i++) { + k = info->keyMap + known_numeric_keys[i].keycode * GLYPHS_PER_KEY; + + if (k[0] == known_numeric_keys[i].normal) + k[0] = known_numeric_keys[i].keypad; + } +#endif + +#if HACK_BLACKLIST + for (i = 0; i < sizeof (keycode_blacklist) / sizeof (keycode_blacklist[0]); i++) { + k = info->keyMap + keycode_blacklist[i] * GLYPHS_PER_KEY; + k[0] = k[1] = k[2] = k[3] = NoSymbol; + } +#endif + + DarwinBuildModifierMaps(info); + + return TRUE; +} + +Bool QuartsResyncKeymap(Bool sendDDXEvent) { + Bool retval; + /* Update keyInfo */ + pthread_mutex_lock(&keyInfo_mutex); + memset(keyInfo.keyMap, 0, sizeof(keyInfo.keyMap)); + retval = QuartzReadSystemKeymap(&keyInfo); + pthread_mutex_unlock(&keyInfo_mutex); + + /* Tell server thread to deal with new keyInfo */ + if(sendDDXEvent) + DarwinSendDDXEvent(kXquartzReloadKeymap, 0); + + return retval; +} diff --git a/xorg-server/hw/xquartz/quartzStartup.c b/xorg-server/hw/xquartz/quartzStartup.c index ba92ecef6..36c8182ae 100644 --- a/xorg-server/hw/xquartz/quartzStartup.c +++ b/xorg-server/hw/xquartz/quartzStartup.c @@ -40,7 +40,6 @@ #include "X11Controller.h" #include "darwin.h" #include "darwinEvents.h" -#include "quartzAudio.h" #include "quartz.h" #include "opaque.h" #include "micmap.h" @@ -117,9 +116,6 @@ int server_main(int argc, char **argv, char **envp) { } } - /* Create the audio mutex */ - QuartzAudioInit(); - X11ControllerMain(argc, argv, envp); exit(0); } |