diff options
Diffstat (limited to 'xorg-server/hw/xquartz')
-rw-r--r-- | xorg-server/hw/xquartz/Makefile.am | 110 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/X11Application.h | 223 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/X11Application.m | 44 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/X11Controller.m | 1688 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/applewm.c | 56 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/darwinEvents.c | 22 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/quartz.c | 201 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/quartz.h | 281 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/quartzAudio.c | 658 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/quartzCommon.h | 19 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/quartzKeyboard.c | 6 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/quartzRandR.c | 560 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/quartzRandR.h | 80 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/xpr/appledri.c | 43 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/xpr/xprAppleWM.c | 320 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/xpr/xprCursor.c | 6 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/xpr/xprFrame.c | 4 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/xpr/xprScreen.c | 12 |
18 files changed, 2465 insertions, 1868 deletions
diff --git a/xorg-server/hw/xquartz/Makefile.am b/xorg-server/hw/xquartz/Makefile.am index 96b139f97..23bf04c2e 100644 --- a/xorg-server/hw/xquartz/Makefile.am +++ b/xorg-server/hw/xquartz/Makefile.am @@ -1,54 +1,56 @@ -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 \ - 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 \ - 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 \
+ 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
diff --git a/xorg-server/hw/xquartz/X11Application.h b/xorg-server/hw/xquartz/X11Application.h index ce19e034a..71a593b40 100644 --- a/xorg-server/hw/xquartz/X11Application.h +++ b/xorg-server/hw/xquartz/X11Application.h @@ -1,113 +1,110 @@ -/* 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); - -extern int X11EnableKeyEquivalents; -extern int quartzHasRoot, quartzEnableRootless, quartzFullscreenMenu; - -#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_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 */
diff --git a/xorg-server/hw/xquartz/X11Application.m b/xorg-server/hw/xquartz/X11Application.m index fcd6b3eef..3d972cf2c 100644 --- a/xorg-server/hw/xquartz/X11Application.m +++ b/xorg-server/hw/xquartz/X11Application.m @@ -38,6 +38,7 @@ #import "X11Application.h"
#include "darwin.h"
+#include "quartz.h"
#include "darwinEvents.h"
#include "quartzKeyboard.h"
#include "quartz.h"
@@ -63,9 +64,6 @@ extern int xpbproxy_run (void); /* Stuck modifier / button state... force release when we context switch */
static NSEventType keyState[NUM_KEYCODES];
-int X11EnableKeyEquivalents = TRUE, quartzFullscreenMenu = FALSE;
-int quartzHasRoot = FALSE, quartzEnableRootless = TRUE;
-
extern Bool noTestExtensions;
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
@@ -287,23 +285,23 @@ static void message_kit_thread (SEL selector, NSObject *arg) { do_swallow = YES;
for_x = NO;
#if XPLUGIN_VERSION >= 1
- } else if(X11EnableKeyEquivalents &&
+ } else if(XQuartzEnableKeyEquivalents &&
xp_is_symbolic_hotkey_event([e eventRef])) {
swallow_keycode = [e keyCode];
do_swallow = YES;
for_x = NO;
#endif
- } else if(X11EnableKeyEquivalents &&
+ } else if(XQuartzEnableKeyEquivalents &&
[[self mainMenu] performKeyEquivalent:e]) {
swallow_keycode = [e keyCode];
do_swallow = YES;
for_appkit = NO;
for_x = NO;
- } else if(!quartzEnableRootless
+ } 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 X11EnableKeyEquivalents is disabled */
+ * toggle even if XQuartzEnableKeyEquivalents is disabled */
swallow_keycode = [e keyCode];
do_swallow = YES;
for_x = NO;
@@ -372,7 +370,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) { break;
case 18: /* ApplicationDidReactivate */
- if (quartzHasRoot) for_appkit = NO;
+ if (XQuartzFullscreenVisible) for_appkit = NO;
break;
case NSApplicationDeactivatedEventType:
@@ -422,7 +420,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) { if ([state boolValue])
SetSystemUIMode(kUIModeNormal, 0);
else
- SetSystemUIMode(kUIModeAllHidden, quartzFullscreenMenu ? kUIOptionAutoShowMenuBar : 0); // kUIModeAllSuppressed or kUIOptionAutoShowMenuBar can be used to allow "mouse-activation"
+ SetSystemUIMode(kUIModeAllHidden, XQuartzFullscreenMenu ? kUIOptionAutoShowMenuBar : 0); // kUIModeAllSuppressed or kUIOptionAutoShowMenuBar can be used to allow "mouse-activation"
}
- (void) launch_client:(NSString *)cmd {
@@ -720,18 +718,18 @@ static NSMutableArray * cfarray_to_nsarray (CFArrayRef in) { NSString *nsstr;
const char *tem;
- quartzUseSysBeep = [self prefs_get_boolean:@PREFS_SYSBEEP
- default:quartzUseSysBeep];
- quartzEnableRootless = [self prefs_get_boolean:@PREFS_ROOTLESS
- default:quartzEnableRootless];
- quartzFullscreenMenu = [self prefs_get_boolean:@PREFS_FULLSCREEN_MENU
- default:quartzFullscreenMenu];
- quartzFullscreenDisableHotkeys = ![self prefs_get_boolean:@PREFS_FULLSCREEN_HOTKEYS
- default:!quartzFullscreenDisableHotkeys];
+ 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];
- quartzOptionSendsAlt = [self prefs_get_boolean:@PREFS_OPTION_SENDS_ALT
- default:quartzOptionSendsAlt];
+ XQuartzOptionSendsAlt = [self prefs_get_boolean:@PREFS_OPTION_SENDS_ALT
+ default:XQuartzOptionSendsAlt];
if (darwinFakeButtons) {
const char *fake2, *fake3;
@@ -759,8 +757,8 @@ static NSMutableArray * cfarray_to_nsarray (CFArrayRef in) { }
}
- X11EnableKeyEquivalents = [self prefs_get_boolean:@PREFS_KEYEQUIVS
- default:X11EnableKeyEquivalents];
+ XQuartzEnableKeyEquivalents = [self prefs_get_boolean:@PREFS_KEYEQUIVS
+ default:XQuartzEnableKeyEquivalents];
darwinSyncKeymap = [self prefs_get_boolean:@PREFS_SYNC_KEYMAP
default:darwinSyncKeymap];
@@ -1158,7 +1156,7 @@ static inline int ensure_flag(int flags, int device_independent, int device_depe pDev = darwinTabletCurrent;
}
- if(!quartzServerVisible && noTestExtensions) {
+ 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;
@@ -1218,7 +1216,7 @@ static inline int ensure_flag(int flags, int device_independent, int device_depe /* 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(!quartzServerVisible && noTestExtensions) {
+ if(!XQuartzServerVisible && noTestExtensions) {
bgMouseLocationUpdated = FALSE;
DarwinSendPointerEvents(darwinPointer, MotionNotify, 0, location.x,
location.y, pressure, tilt.x, tilt.y);
diff --git a/xorg-server/hw/xquartz/X11Controller.m b/xorg-server/hw/xquartz/X11Controller.m index d66d039b0..5502999e3 100644 --- a/xorg-server/hw/xquartz/X11Controller.m +++ b/xorg-server/hw/xquartz/X11Controller.m @@ -1,844 +1,844 @@ -/* 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 { - int value = ![enable_fullscreen intValue]; - - [enable_fullscreen_menu setEnabled:!value]; - - DarwinSendDDXEvent(kXquartzSetRootless, 1, value); - - [NSApp prefs_set_boolean:@PREFS_ROOTLESS value:value]; - [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) { - quartzUseSysBeep = [use_sysbeep intValue]; - [NSApp prefs_set_boolean:@PREFS_SYSBEEP value:quartzUseSysBeep]; - } else if(sender == enable_keyequivs) { - X11EnableKeyEquivalents = [enable_keyequivs intValue]; - [NSApp prefs_set_boolean:@PREFS_KEYEQUIVS value:X11EnableKeyEquivalents]; - } else if(sender == sync_keymap) { - darwinSyncKeymap = [sync_keymap intValue]; - [NSApp prefs_set_boolean:@PREFS_SYNC_KEYMAP value:darwinSyncKeymap]; - } else if(sender == enable_fullscreen_menu) { - quartzFullscreenMenu = [enable_fullscreen_menu intValue]; - [NSApp prefs_set_boolean:@PREFS_FULLSCREEN_MENU value:quartzFullscreenMenu]; - } else if(sender == option_sends_alt) { - BOOL prev_opt_sends_alt = quartzOptionSendsAlt; - - quartzOptionSendsAlt = [option_sends_alt intValue]; - [NSApp prefs_set_boolean:@PREFS_OPTION_SENDS_ALT value:quartzOptionSendsAlt]; - - if(prev_opt_sends_alt != quartzOptionSendsAlt) - 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:quartzUseSysBeep]; - [enable_keyequivs setIntValue:X11EnableKeyEquivalents]; - [sync_keymap setIntValue:darwinSyncKeymap]; - [option_sends_alt setIntValue:quartzOptionSendsAlt]; - [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:!quartzEnableRootless]; - [enable_fullscreen_menu setEnabled:!quartzEnableRootless]; - [enable_fullscreen_menu setIntValue:quartzFullscreenMenu]; - - [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 !quartzEnableRootless; - 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 == 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);
+}
diff --git a/xorg-server/hw/xquartz/applewm.c b/xorg-server/hw/xquartz/applewm.c index 054fff776..d81032aa9 100644 --- a/xorg-server/hw/xquartz/applewm.c +++ b/xorg-server/hw/xquartz/applewm.c @@ -70,8 +70,6 @@ static AppleWMProcsPtr appleWMProcs; static int WMErrorBase;
-static DISPATCH_PROC(ProcAppleWMDispatch);
-static DISPATCH_PROC(SProcAppleWMDispatch);
static unsigned char WMReqCode = 0;
static int WMEventBase = 0;
@@ -105,33 +103,6 @@ make_box (int x, int y, int w, int h) return r;
}
-void
-AppleWMExtensionInit(
- AppleWMProcsPtr procsPtr)
-{
- ExtensionEntry* extEntry;
-
- ClientType = CreateNewResourceType(WMFreeClient, "WMClient");
- EventType = CreateNewResourceType(WMFreeEvents, "WMEvent");
- eventResource = FakeClientID(0);
-
- if (ClientType && EventType &&
- (extEntry = AddExtension(APPLEWMNAME,
- AppleWMNumberEvents,
- AppleWMNumberErrors,
- ProcAppleWMDispatch,
- SProcAppleWMDispatch,
- NULL,
- StandardMinorOpcode)))
- {
- WMReqCode = (unsigned char)extEntry->base;
- WMErrorBase = extEntry->errorBase;
- WMEventBase = extEntry->eventBase;
- EventSwapVector[WMEventBase] = (EventSwapPtr) SNotifyEvent;
- appleWMProcs = procsPtr;
- }
-}
-
/* Updates the _NATIVE_SCREEN_ORIGIN property on the given root window. */
void
AppleWMSetScreenOrigin(
@@ -736,3 +707,30 @@ SProcAppleWMDispatch ( return BadRequest;
}
}
+
+void
+AppleWMExtensionInit(
+ AppleWMProcsPtr procsPtr)
+{
+ ExtensionEntry* extEntry;
+
+ ClientType = CreateNewResourceType(WMFreeClient, "WMClient");
+ EventType = CreateNewResourceType(WMFreeEvents, "WMEvent");
+ eventResource = FakeClientID(0);
+
+ if (ClientType && EventType &&
+ (extEntry = AddExtension(APPLEWMNAME,
+ AppleWMNumberEvents,
+ AppleWMNumberErrors,
+ ProcAppleWMDispatch,
+ SProcAppleWMDispatch,
+ NULL,
+ StandardMinorOpcode)))
+ {
+ WMReqCode = (unsigned char)extEntry->base;
+ WMErrorBase = extEntry->errorBase;
+ WMEventBase = extEntry->eventBase;
+ EventSwapVector[WMEventBase] = (EventSwapPtr) SNotifyEvent;
+ appleWMProcs = procsPtr;
+ }
+}
diff --git a/xorg-server/hw/xquartz/darwinEvents.c b/xorg-server/hw/xquartz/darwinEvents.c index 663087d74..a00c89ecd 100644 --- a/xorg-server/hw/xquartz/darwinEvents.c +++ b/xorg-server/hw/xquartz/darwinEvents.c @@ -52,6 +52,7 @@ in this Software without prior written authorization from The Open Group. #include "darwin.h"
#include "quartz.h"
#include "quartzKeyboard.h"
+#include "quartzRandR.h"
#include "darwinEvents.h"
#include <sys/types.h>
@@ -238,19 +239,19 @@ static void DarwinEventHandler(int screenNum, InternalEvent *ie, DeviceIntPtr de case kXquartzToggleFullscreen:
DEBUG_LOG("kXquartzToggleFullscreen\n");
- if(quartzEnableRootless)
+ if(XQuartzIsRootless)
ErrorF("Ignoring kXquartzToggleFullscreen because of rootless mode.");
- else if (quartzHasRoot)
- QuartzHide();
- else
- QuartzShow();
+ else
+ QuartzRandRToggleFullscreen();
break;
case kXquartzSetRootless:
DEBUG_LOG("kXquartzSetRootless\n");
- QuartzSetRootless(e->data[0]);
- if (!quartzEnableRootless && !quartzHasRoot)
- QuartzHide();
+ if(e->data[0]) {
+ QuartzRandRSetFakeRootless();
+ } else {
+ QuartzRandRSetFakeFullscreen(FALSE);
+ }
break;
case kXquartzSetRootClip:
@@ -276,7 +277,12 @@ static void DarwinEventHandler(int screenNum, InternalEvent *ie, DeviceIntPtr de break;
case kXquartzDisplayChanged:
+ DEBUG_LOG("kXquartzDisplayChanged\n");
QuartzUpdateScreens();
+#ifdef RANDR
+ /* Update our RandR info */
+ QuartzRandRUpdateFakeModes(TRUE);
+#endif
break;
default:
diff --git a/xorg-server/hw/xquartz/quartz.c b/xorg-server/hw/xquartz/quartz.c index 3aa234e09..7a92755c7 100644 --- a/xorg-server/hw/xquartz/quartz.c +++ b/xorg-server/hw/xquartz/quartz.c @@ -35,6 +35,7 @@ #endif
#include "quartzCommon.h"
+#include "quartzRandR.h"
#include "inputstr.h"
#include "quartz.h"
#include "darwin.h"
@@ -46,7 +47,6 @@ #include "X11Application.h"
#include <X11/extensions/applewmconst.h>
-#include <X11/extensions/randr.h>
// X headers
#include "scrnintstr.h"
@@ -56,6 +56,8 @@ #include "mi.h"
// System headers
+#include <stdlib.h>
+#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -64,41 +66,20 @@ #include <rootlessCommon.h>
#include <Xplugin.h>
-#define FAKE_RANDR 1
-
-// Shared global variables for Quartz modes
-int quartzUseSysBeep = 0;
-int quartzServerVisible = FALSE;
DevPrivateKeyRec quartzScreenKeyRec;
int aquaMenuBarHeight = 0;
QuartzModeProcsPtr quartzProcs = NULL;
const char *quartzOpenGLBundle = NULL;
-int quartzFullscreenDisableHotkeys = TRUE;
-int quartzOptionSendsAlt = FALSE;
-
-#if defined(RANDR) && !defined(FAKE_RANDR)
-Bool QuartzRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) {
- return FALSE;
-}
-
-Bool QuartzRandRSetConfig (ScreenPtr pScreen,
- Rotation randr,
- int rate,
- RRScreenSizePtr pSize) {
- return FALSE;
-}
-Bool QuartzRandRInit (ScreenPtr pScreen) {
- rrScrPrivPtr pScrPriv;
-
- if (!RRScreenInit (pScreen)) return FALSE;
-
- pScrPriv = rrGetScrPriv(pScreen);
- pScrPriv->rrGetInfo = QuartzRandRGetInfo;
- pScrPriv->rrSetConfig = QuartzRandRSetConfig;
- return TRUE;
-}
-#endif
+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;
/*
===========================================================================
@@ -143,6 +124,13 @@ Bool QuartzSetupScreen( 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;
}
@@ -165,11 +153,6 @@ void QuartzInitOutput( if (!dixRegisterPrivateKey(&quartzScreenKeyRec, PRIVATE_SCREEN, 0))
FatalError("Failed to alloc quartz screen private.\n");
-#if defined(RANDR) && !defined(FAKE_RANDR)
- if(!QuartzRandRInit(pScreen))
- FatalError("Failed to init RandR extension.\n");
-#endif
-
// Do display mode specific initialization
quartzProcs->DisplayInit();
}
@@ -191,50 +174,6 @@ void QuartzInitInput( }
-#ifdef FAKE_RANDR
-
-static const int padlength[4] = {0, 3, 2, 1};
-
-static void
-RREditConnectionInfo (ScreenPtr pScreen)
-{
- xConnSetup *connSetup;
- char *vendor;
- xPixmapFormat *formats;
- xWindowRoot *root;
- xDepth *depth;
- xVisualType *visual;
- int screen = 0;
- int d;
-
- connSetup = (xConnSetup *) ConnectionInfo;
- vendor = (char *) connSetup + sizeof (xConnSetup);
- formats = (xPixmapFormat *) ((char *) vendor +
- connSetup->nbytesVendor +
- padlength[connSetup->nbytesVendor & 3]);
- root = (xWindowRoot *) ((char *) formats +
- sizeof (xPixmapFormat) * screenInfo.numPixmapFormats);
- while (screen != pScreen->myNum)
- {
- depth = (xDepth *) ((char *) root +
- sizeof (xWindowRoot));
- for (d = 0; d < root->nDepths; d++)
- {
- visual = (xVisualType *) ((char *) depth +
- sizeof (xDepth));
- depth = (xDepth *) ((char *) visual +
- depth->nVisuals * sizeof (xVisualType));
- }
- root = (xWindowRoot *) ((char *) depth);
- screen++;
- }
- root->pixWidth = pScreen->width;
- root->pixHeight = pScreen->height;
- root->mmWidth = pScreen->mmWidth;
- root->mmHeight = pScreen->mmHeight;
-}
-#endif
-
void QuartzUpdateScreens(void) {
ScreenPtr pScreen;
WindowPtr pRoot;
@@ -255,7 +194,7 @@ void QuartzUpdateScreens(void) { pScreen = screenInfo.screens[0];
PseudoramiXResetScreens();
- quartzProcs->AddPseudoramiXScreens(&x, &y, &width, &height);
+ quartzProcs->AddPseudoramiXScreens(&x, &y, &width, &height, pScreen);
pScreen->x = x;
pScreen->y = y;
@@ -305,71 +244,78 @@ void QuartzUpdateScreens(void) { DeliverEvents(pRoot, &e, 1, NullWindow);
quartzProcs->UpdateScreen(pScreen);
-
-#ifdef FAKE_RANDR
- RREditConnectionInfo(pScreen);
-#endif
}
-void QuartzSetFullscreen(Bool state) {
+void QuartzShowFullscreen(int state) {
+ int i;
- DEBUG_LOG("QuartzSetFullscreen: state=%d\n", state);
+ DEBUG_LOG("QuartzShowFullscreen: state=%d\n", state);
- if(quartzHasRoot == state)
+ if(XQuartzIsRootless) {
+ ErrorF("QuartzShowFullscreen called while in rootless mode.\n");
+ return;
+ }
+
+ if(XQuartzFullscreenVisible == state)
return;
- quartzHasRoot = state;
+ XQuartzFullscreenVisible = state;
xp_disable_update ();
- if (!quartzHasRoot && !quartzEnableRootless)
+ if (!XQuartzFullscreenVisible)
RootlessHideAllWindows();
- RootlessUpdateRooted(quartzHasRoot);
+ RootlessUpdateRooted(XQuartzFullscreenVisible);
- if (quartzHasRoot && !quartzEnableRootless)
+ if (XQuartzFullscreenVisible) {
RootlessShowAllWindows ();
-
- if (quartzHasRoot || quartzEnableRootless) {
- RootlessRepositionWindows(screenInfo.screens[0]);
+ 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(!quartzHasRoot);
+ X11ApplicationShowHideMenubar(!XQuartzFullscreenVisible);
xp_reenable_update ();
- if (quartzFullscreenDisableHotkeys)
- xp_disable_hot_keys(quartzHasRoot);
+ if (XQuartzFullscreenDisableHotkeys)
+ xp_disable_hot_keys(XQuartzFullscreenVisible);
}
-void QuartzSetRootless(Bool state) {
- if(quartzEnableRootless == state)
+void QuartzSetRootless(Bool state) {
+ DEBUG_LOG("QuartzSetRootless state=%d\n", state);
+
+ if(XQuartzIsRootless == state)
return;
- quartzEnableRootless = state;
+ 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(!quartzHasRoot) {
- if(!quartzEnableRootless) {
- RootlessHideAllWindows();
- } else {
- RootlessShowAllWindows();
- }
+ if(XQuartzIsRootless) {
+ RootlessShowAllWindows();
+ } else {
+ RootlessHideAllWindows();
}
- X11ApplicationShowHideMenubar(!quartzHasRoot);
+ X11ApplicationShowHideMenubar(TRUE);
xp_reenable_update();
- if (!quartzEnableRootless && quartzFullscreenDisableHotkeys)
- xp_disable_hot_keys(quartzHasRoot);
+ xp_disable_hot_keys(FALSE);
}
/*
@@ -381,18 +327,18 @@ void QuartzSetRootless(Bool state) { void QuartzShow(void) {
int i;
- if (quartzServerVisible)
+ if (XQuartzServerVisible)
return;
- quartzServerVisible = TRUE;
+ XQuartzServerVisible = TRUE;
for (i = 0; i < screenInfo.numScreens; i++) {
if (screenInfo.screens[i]) {
quartzProcs->ResumeScreen(screenInfo.screens[i]);
}
}
- if (!quartzEnableRootless)
- QuartzSetFullscreen(TRUE);
+ if (!XQuartzIsRootless)
+ QuartzShowFullscreen(TRUE);
}
@@ -406,16 +352,17 @@ void QuartzHide(void) {
int i;
- if (quartzServerVisible) {
+ if (XQuartzServerVisible) {
for (i = 0; i < screenInfo.numScreens; i++) {
if (screenInfo.screens[i]) {
quartzProcs->SuspendScreen(screenInfo.screens[i]);
}
}
}
-
- QuartzSetFullscreen(FALSE);
- quartzServerVisible = FALSE;
+
+ if(!XQuartzIsRootless)
+ QuartzShowFullscreen(FALSE);
+ XQuartzServerVisible = FALSE;
}
@@ -428,7 +375,7 @@ void QuartzSetRootClip( {
int i;
- if (!quartzServerVisible)
+ if (!XQuartzServerVisible)
return;
for (i = 0; i < screenInfo.numScreens; i++) {
@@ -446,3 +393,19 @@ 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;
+}
diff --git a/xorg-server/hw/xquartz/quartz.h b/xorg-server/hw/xquartz/quartz.h index b1a3f3183..f0b519e21 100644 --- a/xorg-server/hw/xquartz/quartz.h +++ b/xorg-server/hw/xquartz/quartz.h @@ -1,135 +1,146 @@ -/* - * 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" - -/*------------------------------------------ - 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); -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 int quartzHasRoot, quartzEnableRootless; - -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 QuartzSetFullscreen(Bool state); -void QuartzSetRootless(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? */
+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
diff --git a/xorg-server/hw/xquartz/quartzAudio.c b/xorg-server/hw/xquartz/quartzAudio.c index 708202b5b..d17d65808 100644 --- a/xorg-server/hw/xquartz/quartzAudio.c +++ b/xorg-server/hw/xquartz/quartzAudio.c @@ -1,329 +1,329 @@ -// -// 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 "quartzCommon.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 (quartzUseSysBeep) { - 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; -} +//
+// 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/quartzCommon.h b/xorg-server/hw/xquartz/quartzCommon.h index 8c7b14faa..ac089ac71 100644 --- a/xorg-server/hw/xquartz/quartzCommon.h +++ b/xorg-server/hw/xquartz/quartzCommon.h @@ -38,26 +38,7 @@ #include <X11/Xdefs.h>
#include "privates.h"
-// Quartz specific per screen storage structure
-typedef struct {
- // List of CoreGraphics displays that this X11 screen covers.
- // This is more than one CG display for video mirroring and
- // rootless PseudoramiX mode.
- // No CG display will be covered by more than one X11 screen.
- int displayCount;
- CGDirectDisplayID *displayIDs;
-} QuartzScreenRec, *QuartzScreenPtr;
-
-#define QUARTZ_PRIV(pScreen) \
- ((QuartzScreenPtr)dixLookupPrivate(&pScreen->devPrivates, quartzScreenKey))
-
-// User preferences used by Quartz modes
-extern int quartzUseSysBeep;
-extern int quartzFullscreenDisableHotkeys;
-extern int quartzOptionSendsAlt;
-
// Other shared data
-extern int quartzServerVisible;
extern DevPrivateKeyRec quartzScreenKeyRec;
#define quartzScreenKey (&quartzScreenKeyRec)
extern int aquaMenuBarHeight;
diff --git a/xorg-server/hw/xquartz/quartzKeyboard.c b/xorg-server/hw/xquartz/quartzKeyboard.c index 8ea198cd5..cd73ec5bd 100644 --- a/xorg-server/hw/xquartz/quartzKeyboard.c +++ b/xorg-server/hw/xquartz/quartzKeyboard.c @@ -48,7 +48,7 @@ #include <sys/stat.h>
#include <AvailabilityMacros.h>
-#include "quartzCommon.h"
+#include "quartz.h"
#include "darwin.h"
#include "darwinEvents.h"
@@ -262,7 +262,7 @@ static void DarwinBuildModifierMaps(darwinKeyboardInfo *info) { case XK_Alt_L:
info->modifierKeycodes[NX_MODIFIERKEY_ALTERNATE][0] = i;
info->modMap[MIN_KEYCODE + i] = Mod1Mask;
- if(!quartzOptionSendsAlt)
+ 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;
@@ -272,7 +272,7 @@ static void DarwinBuildModifierMaps(darwinKeyboardInfo *info) { #else
info->modifierKeycodes[NX_MODIFIERKEY_ALTERNATE][0] = i;
#endif
- if(!quartzOptionSendsAlt)
+ 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;
diff --git a/xorg-server/hw/xquartz/quartzRandR.c b/xorg-server/hw/xquartz/quartzRandR.c new file mode 100644 index 000000000..bc58e2341 --- /dev/null +++ b/xorg-server/hw/xquartz/quartzRandR.c @@ -0,0 +1,560 @@ +/*
+ * Quartz-specific support for the XRandR extension
+ *
+ * Copyright (c) 2001-2004 Greg Parker and Torrey T. Lyons,
+ * 2010 Jan Hauffa.
+ * 2010 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"
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "quartzCommon.h"
+#include "quartzRandR.h"
+#include "quartz.h"
+#include "darwin.h"
+
+#include <AvailabilityMacros.h>
+
+#include <X11/extensions/randr.h>
+#include <randrstr.h>
+#include <IOKit/graphics/IOGraphicsTypes.h>
+
+/* TODO: UGLY, find a better way!
+ * We want to ignore kXquartzDisplayChanged which are generated by us
+ */
+static Bool ignore_next_fake_mode_update = FALSE;
+
+#define FAKE_REFRESH_ROOTLESS 1
+#define FAKE_REFRESH_FULLSCREEN 2
+
+#define DEFAULT_REFRESH 60
+#define kDisplayModeUsableFlags (kDisplayModeValidFlag | kDisplayModeSafeFlag)
+
+#define CALLBACK_SUCCESS 0
+#define CALLBACK_CONTINUE 1
+#define CALLBACK_ERROR -1
+
+typedef int (*QuartzModeCallback)
+ (ScreenPtr, QuartzModeInfoPtr, void *);
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+
+static long getDictLong (CFDictionaryRef dictRef, CFStringRef key) {
+ long value;
+
+ CFNumberRef numRef = (CFNumberRef) CFDictionaryGetValue(dictRef, key);
+ if (!numRef)
+ return 0;
+
+ if (!CFNumberGetValue(numRef, kCFNumberLongType, &value))
+ return 0;
+ return value;
+}
+
+static double getDictDouble (CFDictionaryRef dictRef, CFStringRef key) {
+ double value;
+
+ CFNumberRef numRef = (CFNumberRef) CFDictionaryGetValue(dictRef, key);
+ if (!numRef)
+ return 0.0;
+
+ if (!CFNumberGetValue(numRef, kCFNumberDoubleType, &value))
+ return 0.0;
+ return value;
+}
+
+static void QuartzRandRGetModeInfo (CFDictionaryRef modeRef,
+ QuartzModeInfoPtr pMode) {
+ pMode->width = (size_t) getDictLong(modeRef, kCGDisplayWidth);
+ pMode->height = (size_t) getDictLong(modeRef, kCGDisplayHeight);
+ pMode->refresh = (int)(getDictDouble(modeRef, kCGDisplayRefreshRate) + 0.5);
+ if (pMode->refresh == 0)
+ pMode->refresh = DEFAULT_REFRESH;
+ pMode->ref = NULL;
+ pMode->pSize = NULL;
+}
+
+static Bool QuartzRandRCopyCurrentModeInfo (CGDirectDisplayID screenId,
+ QuartzModeInfoPtr pMode) {
+ CFDictionaryRef curModeRef = CGDisplayCurrentMode(screenId);
+ if (!curModeRef)
+ return FALSE;
+
+ QuartzRandRGetModeInfo(curModeRef, pMode);
+ pMode->ref = (void *)curModeRef;
+ CFRetain(pMode->ref);
+ return TRUE;
+}
+
+static Bool QuartzRandRSetCGMode (CGDirectDisplayID screenId,
+ QuartzModeInfoPtr pMode) {
+ CFDictionaryRef modeRef = (CFDictionaryRef) pMode->ref;
+ return (CGDisplaySwitchToMode(screenId, modeRef) == kCGErrorSuccess);
+}
+
+static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
+ QuartzModeCallback callback,
+ void *data) {
+ CFDictionaryRef curModeRef, modeRef;
+ long curBpp;
+ CFArrayRef modes;
+ QuartzModeInfo modeInfo;
+ int i;
+ BOOL retval = FALSE;
+ QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
+ CGDirectDisplayID screenId = pQuartzScreen->displayIDs[0];
+
+ curModeRef = CGDisplayCurrentMode(screenId);
+ if (!curModeRef)
+ return FALSE;
+ curBpp = getDictLong(curModeRef, kCGDisplayBitsPerPixel);
+
+ modes = CGDisplayAvailableModes(screenId);
+ if (!modes)
+ return FALSE;
+ for (i = 0; i < CFArrayGetCount(modes); i++) {
+ int cb;
+ modeRef = (CFDictionaryRef) CFArrayGetValueAtIndex(modes, i);
+
+ /* Skip modes that are not usable on the current display or have a
+ different pixel encoding than the current mode. */
+ if (((unsigned long) getDictLong(modeRef, kCGDisplayIOFlags) &
+ kDisplayModeUsableFlags) != kDisplayModeUsableFlags)
+ continue;
+ if (getDictLong(modeRef, kCGDisplayBitsPerPixel) != curBpp)
+ continue;
+
+ QuartzRandRGetModeInfo(modeRef, &modeInfo);
+ modeInfo.ref = (void *)modeRef;
+ cb = callback(pScreen, &modeInfo, data);
+ if (cb == CALLBACK_CONTINUE)
+ retval = TRUE;
+ else if (cb == CALLBACK_SUCCESS)
+ return TRUE;
+ else if (cb == CALLBACK_ERROR)
+ return FALSE;
+ }
+
+ switch(callback(pScreen, &pQuartzScreen->rootlessMode, data)) {
+ case CALLBACK_SUCCESS:
+ return TRUE;
+ case CALLBACK_ERROR:
+ return FALSE;
+ case CALLBACK_CONTINUE:
+ retval = TRUE;
+ default:
+ break;
+ }
+
+ switch(callback(pScreen, &pQuartzScreen->fullscreenMode, data)) {
+ case CALLBACK_SUCCESS:
+ return TRUE;
+ case CALLBACK_ERROR:
+ return FALSE;
+ case CALLBACK_CONTINUE:
+ retval = TRUE;
+ default:
+ break;
+ }
+
+ return retval;
+}
+
+#else /* we have the new CG APIs from Snow Leopard */
+
+static void QuartzRandRGetModeInfo (CGDisplayModeRef modeRef,
+ QuartzModeInfoPtr pMode) {
+ pMode->width = CGDisplayModeGetWidth(modeRef);
+ pMode->height = CGDisplayModeGetHeight(modeRef);
+ pMode->refresh = (int) (CGDisplayModeGetRefreshRate(modeRef) + 0.5);
+ if (pMode->refresh == 0)
+ pMode->refresh = DEFAULT_REFRESH;
+ pMode->ref = NULL;
+ pMode->pSize = NULL;
+}
+
+static Bool QuartzRandRCopyCurrentModeInfo (CGDirectDisplayID screenId,
+ QuartzModeInfoPtr pMode) {
+ CGDisplayModeRef curModeRef = CGDisplayCopyDisplayMode(screenId);
+ if (!curModeRef)
+ return FALSE;
+
+ QuartzRandRGetModeInfo(curModeRef, pMode);
+ pMode->ref = curModeRef;
+ return TRUE;
+}
+
+static Bool QuartzRandRSetCGMode (CGDirectDisplayID screenId,
+ QuartzModeInfoPtr pMode) {
+ CGDisplayModeRef modeRef = (CGDisplayModeRef) pMode->ref;
+ if (!modeRef)
+ return FALSE;
+
+ return (CGDisplaySetDisplayMode(screenId, modeRef, NULL) == kCGErrorSuccess);
+}
+
+static Bool QuartzRandREnumerateModes (ScreenPtr pScreen,
+ QuartzModeCallback callback,
+ void *data) {
+ CGDisplayModeRef curModeRef, modeRef;
+ CFStringRef curPixelEnc, pixelEnc;
+ CFComparisonResult pixelEncEqual;
+ CFArrayRef modes;
+ QuartzModeInfo modeInfo;
+ int i;
+ Bool retval = FALSE;
+
+ QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
+ CGDirectDisplayID screenId = pQuartzScreen->displayIDs[0];
+
+ curModeRef = CGDisplayCopyDisplayMode(screenId);
+ if (!curModeRef)
+ return FALSE;
+ curPixelEnc = CGDisplayModeCopyPixelEncoding(curModeRef);
+ CGDisplayModeRelease(curModeRef);
+
+ modes = CGDisplayCopyAllDisplayModes(screenId, NULL);
+ if (!modes) {
+ CFRelease(curPixelEnc);
+ return FALSE;
+ }
+ for (i = 0; i < CFArrayGetCount(modes); i++) {
+ int cb;
+ modeRef = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
+
+ /* Skip modes that are not usable on the current display or have a
+ different pixel encoding than the current mode. */
+ if ((CGDisplayModeGetIOFlags(modeRef) & kDisplayModeUsableFlags) !=
+ kDisplayModeUsableFlags)
+ continue;
+ pixelEnc = CGDisplayModeCopyPixelEncoding(modeRef);
+ pixelEncEqual = CFStringCompare(pixelEnc, curPixelEnc, 0);
+ CFRelease(pixelEnc);
+ if (pixelEncEqual != kCFCompareEqualTo)
+ continue;
+
+ QuartzRandRGetModeInfo(modeRef, &modeInfo);
+ modeInfo.ref = modeRef;
+ cb = callback(pScreen, &modeInfo, data);
+ if (cb == CALLBACK_CONTINUE) {
+ retval = TRUE;
+ } else if (cb == CALLBACK_SUCCESS) {
+ CFRelease(modes);
+ CFRelease(curPixelEnc);
+ return TRUE;
+ } else if (cb == CALLBACK_ERROR) {
+ CFRelease(modes);
+ CFRelease(curPixelEnc);
+ return FALSE;
+ }
+ }
+
+ CFRelease(modes);
+ CFRelease(curPixelEnc);
+
+ switch(callback(pScreen, &pQuartzScreen->rootlessMode, data)) {
+ case CALLBACK_SUCCESS:
+ return TRUE;
+ case CALLBACK_ERROR:
+ return FALSE;
+ case CALLBACK_CONTINUE:
+ retval = TRUE;
+ default:
+ break;
+ }
+
+ switch(callback(pScreen, &pQuartzScreen->fullscreenMode, data)) {
+ case CALLBACK_SUCCESS:
+ return TRUE;
+ case CALLBACK_ERROR:
+ return FALSE;
+ case CALLBACK_CONTINUE:
+ retval = TRUE;
+ default:
+ break;
+ }
+
+ return retval;
+}
+
+#endif /* Snow Leopard CoreGraphics APIs */
+
+
+static Bool QuartzRandRModesEqual (QuartzModeInfoPtr pMode1,
+ QuartzModeInfoPtr pMode2) {
+ return (pMode1->width == pMode2->width) &&
+ (pMode1->height == pMode2->height) &&
+ (pMode1->refresh == pMode2->refresh);
+}
+
+static Bool QuartzRandRRegisterMode (ScreenPtr pScreen,
+ QuartzModeInfoPtr pMode) {
+ QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
+ Bool isCurrentMode = QuartzRandRModesEqual(&pQuartzScreen->currentMode, pMode);
+
+ /* TODO: DPI */
+ pMode->pSize = RRRegisterSize(pScreen, pMode->width, pMode->height, pScreen->mmWidth, pScreen->mmHeight);
+ if (pMode->pSize) {
+ //DEBUG_LOG("registering: %d x %d @ %d %s\n", (int)pMode->width, (int)pMode->height, (int)pMode->refresh, isCurrentMode ? "*" : "");
+ RRRegisterRate(pScreen, pMode->pSize, pMode->refresh);
+
+ if (isCurrentMode)
+ RRSetCurrentConfig(pScreen, RR_Rotate_0, pMode->refresh, pMode->pSize);
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static int QuartzRandRRegisterModeCallback (ScreenPtr pScreen,
+ QuartzModeInfoPtr pMode,
+ void *data __unused) {
+ if(QuartzRandRRegisterMode(pScreen, pMode)) {
+ return CALLBACK_CONTINUE;
+ } else {
+ return CALLBACK_ERROR;
+ }
+}
+
+static Bool QuartzRandRSetMode(ScreenPtr pScreen, QuartzModeInfoPtr pMode, BOOL doRegister) {
+ QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
+ CGDirectDisplayID screenId = pQuartzScreen->displayIDs[0];
+
+ if (pQuartzScreen->currentMode.ref && CFEqual(pMode->ref, pQuartzScreen->currentMode.ref)) {
+ DEBUG_LOG("Requested RandR resolution matches current CG mode\n");
+ } if (QuartzRandRSetCGMode(screenId, pMode)) {
+ ignore_next_fake_mode_update = TRUE;
+ } else {
+ DEBUG_LOG("Error while requesting CG resolution change.\n");
+ return FALSE;
+ }
+
+ /* If the client requested the fake rootless mode, switch to rootless.
+ * Otherwise, force fullscreen mode.
+ */
+ QuartzSetRootless(pMode->refresh == FAKE_REFRESH_ROOTLESS);
+ if (pMode->refresh != FAKE_REFRESH_ROOTLESS) {
+ QuartzShowFullscreen(TRUE);
+ }
+
+ if(pQuartzScreen->currentMode.ref)
+ CFRelease(pQuartzScreen->currentMode.ref);
+ pQuartzScreen->currentMode = *pMode;
+ CFRetain(pQuartzScreen->currentMode.ref);
+
+ return TRUE;
+}
+
+static int QuartzRandRSetModeCallback (ScreenPtr pScreen,
+ QuartzModeInfoPtr pMode,
+ void *data) {
+ QuartzModeInfoPtr pReqMode = (QuartzModeInfoPtr) data;
+
+ if (!QuartzRandRModesEqual(pMode, pReqMode))
+ return CALLBACK_CONTINUE; /* continue enumeration */
+
+ DEBUG_LOG("Found a match for requested RandR resolution (%dx%d@%d).\n", (int)pMode->width, (int)pMode->height, (int)pMode->refresh);
+
+ if(QuartzRandRSetMode(pScreen, pMode, FALSE))
+ return CALLBACK_SUCCESS;
+ else
+ return CALLBACK_ERROR;
+}
+
+static Bool QuartzRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) {
+ QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
+
+ *rotations = RR_Rotate_0; /* TODO: support rotation */
+
+ if (pQuartzScreen->displayCount == 0)
+ return FALSE;
+
+ if (pQuartzScreen->displayCount > 1) {
+ /* RandR operations are not well-defined for an X11 screen spanning
+ multiple CG displays. Create two entries for the current virtual
+ resolution including/excluding the menu bar. */
+
+ QuartzRandRRegisterMode(pScreen, &pQuartzScreen->rootlessMode);
+ QuartzRandRRegisterMode(pScreen, &pQuartzScreen->fullscreenMode);
+ return TRUE;
+ }
+
+ return QuartzRandREnumerateModes(pScreen, QuartzRandRRegisterModeCallback, NULL);
+}
+
+static Bool QuartzRandRSetConfig (ScreenPtr pScreen,
+ Rotation randr,
+ int rate,
+ RRScreenSizePtr pSize) {
+ QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
+ QuartzModeInfo reqMode;
+
+ reqMode.width = pSize->width;
+ reqMode.height = pSize->height;
+ reqMode.refresh = rate;
+
+ if (pQuartzScreen->displayCount == 0)
+ return FALSE;
+
+ /* Do not switch modes if requested mode is equal to current mode. */
+ if (QuartzRandRModesEqual(&reqMode, &pQuartzScreen->currentMode))
+ return TRUE;
+
+ if (QuartzRandREnumerateModes(pScreen, QuartzRandRSetModeCallback, &reqMode)) {
+ return TRUE;
+ }
+
+ DEBUG_LOG("Unable to find a matching config: %d x %d @ %d\n", (int)reqMode.width, (int)reqMode.height, (int)reqMode.refresh);
+ return FALSE;
+}
+
+static Bool _QuartzRandRUpdateFakeModes (ScreenPtr pScreen) {
+ QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
+
+ if (pQuartzScreen->displayCount == 1) {
+ if(pQuartzScreen->fullscreenMode.ref)
+ CFRelease(pQuartzScreen->fullscreenMode.ref);
+ if(pQuartzScreen->currentMode.ref)
+ CFRelease(pQuartzScreen->currentMode.ref);
+
+ if (!QuartzRandRCopyCurrentModeInfo(pQuartzScreen->displayIDs[0],
+ &pQuartzScreen->fullscreenMode))
+ return FALSE;
+
+ CFRetain(pQuartzScreen->fullscreenMode.ref); /* This extra retain is for currentMode's copy */
+ } else {
+ pQuartzScreen->fullscreenMode.width = pScreen->width;
+ pQuartzScreen->fullscreenMode.height = pScreen->height;
+ if(XQuartzIsRootless)
+ pQuartzScreen->fullscreenMode.height += aquaMenuBarHeight;
+ }
+
+ pQuartzScreen->fullscreenMode.refresh = FAKE_REFRESH_FULLSCREEN;
+
+ pQuartzScreen->rootlessMode = pQuartzScreen->fullscreenMode;
+ pQuartzScreen->rootlessMode.refresh = FAKE_REFRESH_ROOTLESS;
+ pQuartzScreen->rootlessMode.height -= aquaMenuBarHeight;
+
+ if(XQuartzIsRootless) {
+ pQuartzScreen->currentMode = pQuartzScreen->rootlessMode;
+ } else {
+ pQuartzScreen->currentMode = pQuartzScreen->fullscreenMode;
+ }
+
+ DEBUG_LOG("rootlessMode: %d x %d\n", (int)pQuartzScreen->rootlessMode.width, (int)pQuartzScreen->rootlessMode.height);
+ DEBUG_LOG("fullscreenMode: %d x %d\n", (int)pQuartzScreen->fullscreenMode.width, (int)pQuartzScreen->fullscreenMode.height);
+ DEBUG_LOG("currentMode: %d x %d\n", (int)pQuartzScreen->currentMode.width, (int)pQuartzScreen->currentMode.height);
+
+ return TRUE;
+}
+
+Bool QuartzRandRUpdateFakeModes (BOOL force_update) {
+ ScreenPtr pScreen = screenInfo.screens[0];
+
+ if(ignore_next_fake_mode_update) {
+ DEBUG_LOG("Ignoring update request caused by RandR resolution change.\n");
+ ignore_next_fake_mode_update = FALSE;
+ return TRUE;
+ }
+
+ if(!_QuartzRandRUpdateFakeModes(pScreen))
+ return FALSE;
+
+ if(force_update)
+ RRGetInfo(pScreen, TRUE);
+
+ return TRUE;
+}
+
+Bool QuartzRandRInit (ScreenPtr pScreen) {
+ rrScrPrivPtr pScrPriv;
+
+ if (!RRScreenInit (pScreen)) return FALSE;
+ if (!_QuartzRandRUpdateFakeModes (pScreen)) return FALSE;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+ pScrPriv->rrGetInfo = QuartzRandRGetInfo;
+ pScrPriv->rrSetConfig = QuartzRandRSetConfig;
+ return TRUE;
+}
+
+void QuartzRandRSetFakeRootless (void) {
+ int i;
+
+ DEBUG_LOG("QuartzRandRSetFakeRootless called.\n");
+
+ for (i=0; i < screenInfo.numScreens; i++) {
+ ScreenPtr pScreen = screenInfo.screens[i];
+ QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
+
+ QuartzRandRSetMode(pScreen, &pQuartzScreen->rootlessMode, TRUE);
+ }
+}
+
+void QuartzRandRSetFakeFullscreen (BOOL state) {
+ int i;
+
+ DEBUG_LOG("QuartzRandRSetFakeFullscreen called.\n");
+
+ for (i=0; i < screenInfo.numScreens; i++) {
+ ScreenPtr pScreen = screenInfo.screens[i];
+ QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
+
+ QuartzRandRSetMode(pScreen, &pQuartzScreen->fullscreenMode, TRUE);
+ }
+
+ QuartzShowFullscreen(state);
+}
+
+/* Toggle fullscreen mode. If "fake" fullscreen is the current mode,
+ * this will just show/hide the X11 windows. If we are in a RandR fullscreen
+ * mode, this will toggles us to the default fake mode and hide windows if
+ * it is fullscreen
+ */
+void QuartzRandRToggleFullscreen (void) {
+ ScreenPtr pScreen = screenInfo.screens[0];
+ QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);
+
+ if (pQuartzScreen->currentMode.ref == NULL) {
+ ErrorF("Ignoring QuartzRandRToggleFullscreen because don't have a current mode set.\n");
+ } else if (pQuartzScreen->currentMode.refresh == FAKE_REFRESH_ROOTLESS) {
+ ErrorF("Ignoring QuartzRandRToggleFullscreen because we are in rootless mode.\n");
+ } else if (pQuartzScreen->currentMode.refresh == FAKE_REFRESH_FULLSCREEN) {
+ /* Legacy fullscreen mode. Hide/Show */
+ QuartzShowFullscreen(!XQuartzFullscreenVisible);
+ } else {
+ /* RandR fullscreen mode. Return to default mode and hide if it is fullscreen. */
+ if(XQuartzRootlessDefault) {
+ QuartzRandRSetFakeRootless();
+ } else {
+ QuartzRandRSetFakeFullscreen(FALSE);
+ }
+ }
+}
diff --git a/xorg-server/hw/xquartz/quartzRandR.h b/xorg-server/hw/xquartz/quartzRandR.h new file mode 100644 index 000000000..ce7f055d1 --- /dev/null +++ b/xorg-server/hw/xquartz/quartzRandR.h @@ -0,0 +1,80 @@ +/*
+ * quartzRandR.h
+ *
+ * Copyright (c) 2010 Jan Hauffa.
+ * 2010 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 _QUARTZRANDR_H_
+#define _QUARTZRANDR_H_
+
+#include "randrstr.h"
+
+typedef struct {
+ size_t width, height;
+ int refresh;
+ RRScreenSizePtr pSize;
+ void *ref; /* CGDisplayModeRef or CFDictionaryRef */
+} QuartzModeInfo, *QuartzModeInfoPtr;
+
+// Quartz specific per screen storage structure
+typedef struct {
+ // List of CoreGraphics displays that this X11 screen covers.
+ // This is more than one CG display for video mirroring and
+ // rootless PseudoramiX mode.
+ // No CG display will be covered by more than one X11 screen.
+ int displayCount;
+ CGDirectDisplayID *displayIDs;
+ QuartzModeInfo rootlessMode, fullscreenMode, currentMode;
+} QuartzScreenRec, *QuartzScreenPtr;
+
+#define QUARTZ_PRIV(pScreen) \
+ ((QuartzScreenPtr)dixLookupPrivate(&pScreen->devPrivates, quartzScreenKey))
+
+void QuartzCopyDisplayIDs(ScreenPtr pScreen,
+ int displayCount, CGDirectDisplayID *displayIDs);
+
+Bool QuartzRandRUpdateFakeModes (BOOL force_update);
+Bool QuartzRandRInit (ScreenPtr pScreen);
+
+/* These two functions provide functionality expected by the legacy
+ * mode switching. They are equivalent to a client requesting one
+ * of the modes corresponding to these "fake" modes.
+ * QuartzRandRSetFakeFullscreen takes an argument which is used to determine
+ * the visibility of the windows after the change.
+ */
+void QuartzRandRSetFakeRootless (void);
+void QuartzRandRSetFakeFullscreen (BOOL state);
+
+
+/* Toggle fullscreen mode. If "fake" fullscreen is the current mode,
+ * this will just show/hide the X11 windows. If we are in a RandR fullscreen
+ * mode, this will toggles us to the default fake mode and hide windows if
+ * it is fullscreen
+ */
+void QuartzRandRToggleFullscreen (void);
+
+#endif
diff --git a/xorg-server/hw/xquartz/xpr/appledri.c b/xorg-server/hw/xquartz/xpr/appledri.c index 1fceb525c..d42661c22 100644 --- a/xorg-server/hw/xquartz/xpr/appledri.c +++ b/xorg-server/hw/xquartz/xpr/appledri.c @@ -59,8 +59,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. static int DRIErrorBase = 0;
-static DISPATCH_PROC(ProcAppleDRIDispatch);
-static DISPATCH_PROC(SProcAppleDRIDispatch);
static void AppleDRIResetProc(ExtensionEntry* extEntry);
static int ProcAppleDRICreatePixmap(ClientPtr client);
@@ -78,27 +76,6 @@ typedef struct _DRIEvent { unsigned int mask;
} DRIEventRec;
-
-void
-AppleDRIExtensionInit(void)
-{
- ExtensionEntry* extEntry;
-
- if (DRIExtensionInit() &&
- (extEntry = AddExtension(APPLEDRINAME,
- AppleDRINumberEvents,
- AppleDRINumberErrors,
- ProcAppleDRIDispatch,
- SProcAppleDRIDispatch,
- AppleDRIResetProc,
- StandardMinorOpcode))) {
- DRIReqCode = (unsigned char)extEntry->base;
- DRIErrorBase = extEntry->errorBase;
- DRIEventBase = extEntry->eventBase;
- EventSwapVector[DRIEventBase] = (EventSwapPtr) SNotifyEvent;
- }
-}
-
/*ARGSUSED*/
static void
AppleDRIResetProc (
@@ -421,3 +398,23 @@ SProcAppleDRIDispatch ( return BadRequest;
}
}
+
+void
+AppleDRIExtensionInit(void)
+{
+ ExtensionEntry* extEntry;
+
+ if (DRIExtensionInit() &&
+ (extEntry = AddExtension(APPLEDRINAME,
+ AppleDRINumberEvents,
+ AppleDRINumberErrors,
+ ProcAppleDRIDispatch,
+ SProcAppleDRIDispatch,
+ AppleDRIResetProc,
+ StandardMinorOpcode))) {
+ DRIReqCode = (unsigned char)extEntry->base;
+ DRIErrorBase = extEntry->errorBase;
+ DRIEventBase = extEntry->eventBase;
+ EventSwapVector[DRIEventBase] = (EventSwapPtr) SNotifyEvent;
+ }
+}
diff --git a/xorg-server/hw/xquartz/xpr/xprAppleWM.c b/xorg-server/hw/xquartz/xpr/xprAppleWM.c index 4b31e3a11..59ce6375e 100644 --- a/xorg-server/hw/xquartz/xpr/xprAppleWM.c +++ b/xorg-server/hw/xquartz/xpr/xprAppleWM.c @@ -1,160 +1,160 @@ -/* - * Xplugin rootless implementation functions for AppleWM extension - * - * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. - * Copyright (c) 2003 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. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include "xpr.h" - -#include <X11/extensions/applewmproto.h> - -#include "applewmExt.h" -#include "rootless.h" -#include "rootlessCommon.h" -#include <Xplugin.h> -#include <X11/X.h> -#include "quartz.h" -#include "x-hash.h" - -static int xprSetWindowLevel( - WindowPtr pWin, - int level) -{ - xp_window_id wid; - xp_window_changes wc; - RootlessWindowRec *winRec; - - // AppleWMNumWindowLevels is allowed, but is only set by the server - // for the root window. - if (level < 0 || level >= AppleWMNumWindowLevels) { - return BadValue; - } - - wid = x_cvt_vptr_to_uint(RootlessFrameForWindow (pWin, TRUE)); - if (wid == 0) - return BadWindow; - - RootlessStopDrawing (pWin, FALSE); - winRec = WINREC(pWin); - - if(!winRec) - return BadWindow; - - if(quartzEnableRootless) - wc.window_level = normal_window_levels[level]; - else - wc.window_level = rooted_window_levels[level]; - - if (xp_configure_window (wid, XP_WINDOW_LEVEL, &wc) != Success) { - return BadValue; - } - - winRec->level = level; - - return Success; -} - -#if defined(XPLUGIN_VERSION) && XPLUGIN_VERSION >= 3 -static int xprAttachTransient(WindowPtr pWinChild, WindowPtr pWinParent) { - xp_window_id child_wid, parent_wid; - xp_window_changes wc; - - child_wid = x_cvt_vptr_to_uint(RootlessFrameForWindow(pWinChild, TRUE)); - if (child_wid == 0) - return BadWindow; - - if(pWinParent) { - parent_wid = x_cvt_vptr_to_uint(RootlessFrameForWindow(pWinParent, TRUE)); - if (parent_wid == 0) - return BadWindow; - } else { - parent_wid = 0; - } - - wc.transient_for = parent_wid; - - RootlessStopDrawing (pWinChild, FALSE); - - if (xp_configure_window(child_wid, XP_ATTACH_TRANSIENT, &wc) != Success) { - return BadValue; - } - - return Success; -} -#endif - -static int xprFrameDraw( - WindowPtr pWin, - int class, - unsigned int attr, - const BoxRec *outer, - const BoxRec *inner, - unsigned int title_len, - const unsigned char *title_bytes) -{ - xp_window_id wid; - - wid = x_cvt_vptr_to_uint(RootlessFrameForWindow (pWin, FALSE)); - if (wid == 0) - return BadWindow; - - if (xp_frame_draw (wid, class, attr, outer, inner, - title_len, title_bytes) != Success) - { - return BadValue; - } - - return Success; -} - -static AppleWMProcsRec xprAppleWMProcs = { - xp_disable_update, - xp_reenable_update, - xprSetWindowLevel, - xp_frame_get_rect, - xp_frame_hit_test, - xprFrameDraw, -#if defined(XPLUGIN_VERSION) && XPLUGIN_VERSION >= 3 - xp_set_dock_proxy, - xprAttachTransient -#elif defined(XPLUGIN_VERSION) && XPLUGIN_VERSION >= 2 - xp_set_dock_proxy, - NULL -#else - NULL, - NULL -#endif -}; - - -void xprAppleWMInit(void) -{ - AppleWMExtensionInit(&xprAppleWMProcs); -} +/*
+ * Xplugin rootless implementation functions for AppleWM extension
+ *
+ * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2003 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "xpr.h"
+
+#include <X11/extensions/applewmproto.h>
+
+#include "applewmExt.h"
+#include "rootless.h"
+#include "rootlessCommon.h"
+#include <Xplugin.h>
+#include <X11/X.h>
+#include "quartz.h"
+#include "x-hash.h"
+
+static int xprSetWindowLevel(
+ WindowPtr pWin,
+ int level)
+{
+ xp_window_id wid;
+ xp_window_changes wc;
+ RootlessWindowRec *winRec;
+
+ // AppleWMNumWindowLevels is allowed, but is only set by the server
+ // for the root window.
+ if (level < 0 || level >= AppleWMNumWindowLevels) {
+ return BadValue;
+ }
+
+ wid = x_cvt_vptr_to_uint(RootlessFrameForWindow (pWin, TRUE));
+ if (wid == 0)
+ return BadWindow;
+
+ RootlessStopDrawing (pWin, FALSE);
+ winRec = WINREC(pWin);
+
+ if(!winRec)
+ return BadWindow;
+
+ if(XQuartzIsRootless)
+ wc.window_level = normal_window_levels[level];
+ else
+ wc.window_level = rooted_window_levels[level];
+
+ if (xp_configure_window (wid, XP_WINDOW_LEVEL, &wc) != Success) {
+ return BadValue;
+ }
+
+ winRec->level = level;
+
+ return Success;
+}
+
+#if defined(XPLUGIN_VERSION) && XPLUGIN_VERSION >= 3
+static int xprAttachTransient(WindowPtr pWinChild, WindowPtr pWinParent) {
+ xp_window_id child_wid, parent_wid;
+ xp_window_changes wc;
+
+ child_wid = x_cvt_vptr_to_uint(RootlessFrameForWindow(pWinChild, TRUE));
+ if (child_wid == 0)
+ return BadWindow;
+
+ if(pWinParent) {
+ parent_wid = x_cvt_vptr_to_uint(RootlessFrameForWindow(pWinParent, TRUE));
+ if (parent_wid == 0)
+ return BadWindow;
+ } else {
+ parent_wid = 0;
+ }
+
+ wc.transient_for = parent_wid;
+
+ RootlessStopDrawing (pWinChild, FALSE);
+
+ if (xp_configure_window(child_wid, XP_ATTACH_TRANSIENT, &wc) != Success) {
+ return BadValue;
+ }
+
+ return Success;
+}
+#endif
+
+static int xprFrameDraw(
+ WindowPtr pWin,
+ int class,
+ unsigned int attr,
+ const BoxRec *outer,
+ const BoxRec *inner,
+ unsigned int title_len,
+ const unsigned char *title_bytes)
+{
+ xp_window_id wid;
+
+ wid = x_cvt_vptr_to_uint(RootlessFrameForWindow (pWin, FALSE));
+ if (wid == 0)
+ return BadWindow;
+
+ if (xp_frame_draw (wid, class, attr, outer, inner,
+ title_len, title_bytes) != Success)
+ {
+ return BadValue;
+ }
+
+ return Success;
+}
+
+static AppleWMProcsRec xprAppleWMProcs = {
+ xp_disable_update,
+ xp_reenable_update,
+ xprSetWindowLevel,
+ xp_frame_get_rect,
+ xp_frame_hit_test,
+ xprFrameDraw,
+#if defined(XPLUGIN_VERSION) && XPLUGIN_VERSION >= 3
+ xp_set_dock_proxy,
+ xprAttachTransient
+#elif defined(XPLUGIN_VERSION) && XPLUGIN_VERSION >= 2
+ xp_set_dock_proxy,
+ NULL
+#else
+ NULL,
+ NULL
+#endif
+};
+
+
+void xprAppleWMInit(void)
+{
+ AppleWMExtensionInit(&xprAppleWMProcs);
+}
diff --git a/xorg-server/hw/xquartz/xpr/xprCursor.c b/xorg-server/hw/xquartz/xpr/xprCursor.c index 07dd5c8fb..4a789cef4 100644 --- a/xorg-server/hw/xquartz/xpr/xprCursor.c +++ b/xorg-server/hw/xquartz/xpr/xprCursor.c @@ -35,7 +35,7 @@ #include <dix-config.h>
#endif
-#include "quartzCommon.h"
+#include "quartz.h"
#include "xpr.h"
#include "darwin.h"
#include "darwinEvents.h"
@@ -226,7 +226,7 @@ QuartzSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, {
QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
- if (!quartzServerVisible)
+ if (!XQuartzServerVisible)
return;
if (pCursor == NULL)
@@ -295,7 +295,7 @@ QuartzCrossScreen(ScreenPtr pScreen, Bool entering) static void
QuartzWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
{
- if (quartzServerVisible)
+ if (XQuartzServerVisible)
{
int sx, sy;
diff --git a/xorg-server/hw/xquartz/xpr/xprFrame.c b/xorg-server/hw/xquartz/xpr/xprFrame.c index 121f1de3d..fecae5a1b 100644 --- a/xorg-server/hw/xquartz/xpr/xprFrame.c +++ b/xorg-server/hw/xquartz/xpr/xprFrame.c @@ -171,7 +171,7 @@ xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen, pFrame->level = !IsRoot (pWin) ? AppleWMWindowLevelNormal : AppleWMNumWindowLevels;
- if(quartzEnableRootless)
+ if(XQuartzIsRootless)
wc.window_level = normal_window_levels[pFrame->level];
else
wc.window_level = rooted_window_levels[pFrame->level];
@@ -285,7 +285,7 @@ static void xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid) { RootlessWindowRec *winRec = x_hash_table_lookup(window_hash, wid, NULL);
if(winRec) {
- if(quartzEnableRootless)
+ if(XQuartzIsRootless)
wc.window_level = normal_window_levels[winRec->level];
else
wc.window_level = rooted_window_levels[winRec->level];
diff --git a/xorg-server/hw/xquartz/xpr/xprScreen.c b/xorg-server/hw/xquartz/xpr/xprScreen.c index 260bfee89..bd877d97c 100644 --- a/xorg-server/hw/xquartz/xpr/xprScreen.c +++ b/xorg-server/hw/xquartz/xpr/xprScreen.c @@ -36,6 +36,7 @@ #include "quartzCommon.h"
#include "inputstr.h"
#include "quartz.h"
+#include "quartzRandR.h"
#include "xpr.h"
#include "xprEvent.h"
#include "pseudoramiX.h"
@@ -157,7 +158,7 @@ displayScreenBounds(CGDirectDisplayID id) (int)frame.origin.x, (int)frame.origin.y);
/* Remove menubar to help standard X11 window managers. */
- if (quartzEnableRootless &&
+ if (XQuartzIsRootless &&
frame.origin.x == 0 && frame.origin.y == 0) {
frame.origin.y += aquaMenuBarHeight;
frame.size.height -= aquaMenuBarHeight;
@@ -176,7 +177,7 @@ displayScreenBounds(CGDirectDisplayID id) * with PseudoramiX.
*/
static void
-xprAddPseudoramiXScreens(int *x, int *y, int *width, int *height)
+xprAddPseudoramiXScreens(int *x, int *y, int *width, int *height, ScreenPtr pScreen)
{
CGDisplayCount i, displayCount;
CGDirectDisplayID *displayList = NULL;
@@ -199,6 +200,7 @@ xprAddPseudoramiXScreens(int *x, int *y, int *width, int *height) if(!displayList)
FatalError("Unable to allocate memory for list of displays.\n");
CGGetActiveDisplayList(displayCount, displayList, &displayCount);
+ QuartzCopyDisplayIDs(pScreen, displayCount, displayList);
/* Get the union of all screens */
for (i = 0; i < displayCount; i++) {
@@ -272,7 +274,8 @@ xprDisplayInit(void) AppleDRIExtensionInit();
xprAppleWMInit();
- if (!quartzEnableRootless)
+ XQuartzIsRootless = XQuartzRootlessDefault;
+ if (!XQuartzIsRootless)
RootlessHideAllWindows();
}
@@ -336,6 +339,7 @@ xprAddScreen(int index, ScreenPtr pScreen) ErrorF("Warning: noPseudoramiXExtension!\n");
dpy = displayAtIndex(index);
+ QuartzCopyDisplayIDs(pScreen, 1, &dpy);
frame = displayScreenBounds(dpy);
@@ -346,7 +350,7 @@ xprAddScreen(int index, ScreenPtr pScreen) }
else
{
- xprAddPseudoramiXScreens(&dfb->x, &dfb->y, &dfb->width, &dfb->height);
+ xprAddPseudoramiXScreens(&dfb->x, &dfb->y, &dfb->width, &dfb->height, pScreen);
}
/* Passing zero width (pitch) makes miCreateScreenResources set the
|