diff options
Diffstat (limited to 'hw/darwin/quartz')
-rw-r--r-- | hw/darwin/quartz/Preferences.h | 107 | ||||
-rw-r--r-- | hw/darwin/quartz/Preferences.m | 530 | ||||
-rw-r--r-- | hw/darwin/quartz/XApplication.h | 47 | ||||
-rw-r--r-- | hw/darwin/quartz/XApplication.m | 47 | ||||
-rw-r--r-- | hw/darwin/quartz/XDarwin.pbproj/project.pbxproj | 1683 | ||||
-rw-r--r-- | hw/darwin/quartz/XDarwinStartup.c | 165 | ||||
-rw-r--r-- | hw/darwin/quartz/XDarwinStartup.man | 75 | ||||
-rw-r--r-- | hw/darwin/quartz/XServer.h | 112 | ||||
-rw-r--r-- | hw/darwin/quartz/XServer.m | 1029 | ||||
-rw-r--r-- | hw/darwin/quartz/pseudoramiX.c | 420 | ||||
-rw-r--r-- | hw/darwin/quartz/pseudoramiX.h | 10 | ||||
-rw-r--r-- | hw/darwin/quartz/quartz.c | 305 | ||||
-rw-r--r-- | hw/darwin/quartz/quartz.h | 50 | ||||
-rw-r--r-- | hw/darwin/quartz/quartzAudio.c | 342 | ||||
-rw-r--r-- | hw/darwin/quartz/quartzAudio.h | 41 | ||||
-rw-r--r-- | hw/darwin/quartz/quartzCocoa.m | 198 | ||||
-rw-r--r-- | hw/darwin/quartz/quartzCommon.h | 98 | ||||
-rw-r--r-- | hw/darwin/quartz/quartzCursor.c | 653 | ||||
-rw-r--r-- | hw/darwin/quartz/quartzCursor.h | 43 | ||||
-rw-r--r-- | hw/darwin/quartz/quartzPasteboard.c | 150 | ||||
-rw-r--r-- | hw/darwin/quartz/quartzPasteboard.h | 45 | ||||
-rw-r--r-- | hw/darwin/quartz/quartzStartup.c | 233 |
22 files changed, 6383 insertions, 0 deletions
diff --git a/hw/darwin/quartz/Preferences.h b/hw/darwin/quartz/Preferences.h new file mode 100644 index 000000000..2c0d6756b --- /dev/null +++ b/hw/darwin/quartz/Preferences.h @@ -0,0 +1,107 @@ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/Preferences.h,v 1.2 2003/01/15 02:34:05 torrey Exp $ */ + +#import <Cocoa/Cocoa.h> + +@interface Preferences : NSObject +{ + IBOutlet NSPanel *window; + IBOutlet id displayField; + IBOutlet id dockSwitchButton; + IBOutlet id fakeButton; + IBOutlet id button2ModifiersMatrix; + IBOutlet id button3ModifiersMatrix; + IBOutlet id switchKeyButton; + IBOutlet id keymapFileField; + IBOutlet id modeMatrix; + IBOutlet id modeWindowButton; + IBOutlet id startupHelpButton; + IBOutlet id systemBeepButton; + IBOutlet id mouseAccelChangeButton; + IBOutlet id useXineramaButton; + IBOutlet id addToPathButton; + IBOutlet id addToPathField; + IBOutlet id useDefaultShellMatrix; + IBOutlet id useOtherShellField; + IBOutlet id depthButton; + + BOOL isGettingKeyCode; + int keyCode; + int modifiers; + NSMutableString *switchString; +} + +- (IBAction)close:(id)sender; +- (IBAction)pickFile:(id)sender; +- (IBAction)saveChanges:(id)sender; +- (IBAction)setKey:(id)sender; + +- (BOOL)sendEvent:(NSEvent*)anEvent; + +- (void)awakeFromNib; +- (void)windowWillClose:(NSNotification *)aNotification; + ++ (void)setUseKeymapFile:(BOOL)newUseKeymapFile; ++ (void)setKeymapFile:(NSString*)newFile; ++ (void)setSwitchString:(NSString*)newString; ++ (void)setKeyCode:(int)newKeyCode; ++ (void)setModifiers:(int)newModifiers; ++ (void)setDisplay:(int)newDisplay; ++ (void)setDockSwitch:(BOOL)newDockSwitch; ++ (void)setFakeButtons:(BOOL)newFakeButtons; ++ (void)setButton2Mask:(int)newFakeMask; ++ (void)setButton3Mask:(int)newFakeMask; ++ (void)setMouseAccelChange:(BOOL)newMouseAccelChange; ++ (void)setUseQDCursor:(int)newUseQDCursor; ++ (void)setRootless:(BOOL)newRootless; ++ (void)setUseAGL:(BOOL)newUseAGL; ++ (void)setModeWindow:(BOOL)newModeWindow; ++ (void)setStartupHelp:(BOOL)newStartupHelp; ++ (void)setSystemBeep:(BOOL)newSystemBeep; ++ (void)setXinerama:(BOOL)newXinerama; ++ (void)setAddToPath:(BOOL)newAddToPath; ++ (void)setAddToPathString:(NSString*)newAddToPathString; ++ (void)setUseDefaultShell:(BOOL)newUseDefaultShell; ++ (void)setShellString:(NSString*)newShellString; ++ (void)setDepth:(int)newDepth; ++ (void)saveToDisk; + ++ (BOOL)useKeymapFile; ++ (NSString*)keymapFile; ++ (NSString*)switchString; ++ (unsigned int)keyCode; ++ (unsigned int)modifiers; ++ (int)display; ++ (BOOL)dockSwitch; ++ (BOOL)fakeButtons; ++ (int)button2Mask; ++ (int)button3Mask; ++ (BOOL)mouseAccelChange; ++ (int)useQDCursor; ++ (BOOL)rootless; ++ (BOOL)useAGL; ++ (BOOL)modeWindow; ++ (BOOL)startupHelp; ++ (BOOL)systemBeep; ++ (BOOL)xinerama; ++ (BOOL)addToPath; ++ (NSString*)addToPathString; ++ (BOOL)useDefaultShell; ++ (NSString*)shellString; ++ (int)depth; + +@end + +// Possible settings for useQDCursor +enum { + qdCursor_Never, // never use QuickDraw cursor + qdCursor_Not8Bit, // don't try to use QuickDraw with 8-bit depth + qdCursor_Always // always try to use QuickDraw cursor +}; + +// Possible settings for depth +enum { + depth_Current, + depth_8Bit, + depth_15Bit, + depth_24Bit +}; diff --git a/hw/darwin/quartz/Preferences.m b/hw/darwin/quartz/Preferences.m new file mode 100644 index 000000000..4f8dacbf0 --- /dev/null +++ b/hw/darwin/quartz/Preferences.m @@ -0,0 +1,530 @@ +// +// Preferences.m +// +// This class keeps track of the user preferences. +// +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/Preferences.m,v 1.2 2003/01/15 02:34:06 torrey Exp $ */ + +#import "Preferences.h" +#import "quartzCommon.h" +#include <IOKit/hidsystem/IOLLEvent.h> // for modifier masks + +// Macros to build the path name +#ifndef XBINDIR +#define XBINDIR /usr/X11R6/bin +#endif +#define STR(s) #s +#define XSTRPATH(s) STR(s) + + +@implementation Preferences + ++ (void)initialize +{ + // Provide user defaults if needed + NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithInt:0], @"Display", + @"YES", @"FakeButtons", + [NSNumber numberWithInt:NX_COMMANDMASK], @"Button2Mask", + [NSNumber numberWithInt:NX_ALTERNATEMASK], @"Button3Mask", + NSLocalizedString(@"USA.keymapping",@""), @"KeymappingFile", + @"YES", @"UseKeymappingFile", + NSLocalizedString(@"Cmd-Opt-a",@""), @"SwitchString", + @"YES", @"UseRootlessMode", + @"YES", @"UseAGLforGLX", + @"YES", @"ShowModePickWindow", + @"YES", @"ShowStartupHelp", + [NSNumber numberWithInt:0], @"SwitchKeyCode", + [NSNumber numberWithInt:(NSCommandKeyMask | NSAlternateKeyMask)], + @"SwitchModifiers", @"NO", @"UseSystemBeep", + @"YES", @"DockSwitch", + @"NO", @"AllowMouseAccelChange", + [NSNumber numberWithInt:qdCursor_Not8Bit], @"UseQDCursor", + @"YES", @"Xinerama", + @"YES", @"AddToPath", + [NSString stringWithCString:XSTRPATH(XBINDIR)], @"AddToPathString", + @"YES", @"UseDefaultShell", + @"/bin/tcsh", @"Shell", + [NSNumber numberWithInt:depth_Current], @"Depth", nil]; + + [super initialize]; + [[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults]; +} + +// Initialize internal state info of switch key button +- (void)initSwitchKey +{ + keyCode = [Preferences keyCode]; + modifiers = [Preferences modifiers]; + [switchString setString:[Preferences switchString]]; +} + +- (id)init +{ + self = [super init]; + + isGettingKeyCode=NO; + switchString=[[NSMutableString alloc] init]; + [self initSwitchKey]; + + return self; +} + +// Set a modifiers checkbox matrix to match a modifier mask +- (void)resetMatrix:(NSMatrix *)aMatrix withMask:(int)aMask +{ + [aMatrix setState:(aMask & NX_SHIFTMASK) atRow:0 column:0]; + [aMatrix setState:(aMask & NX_CONTROLMASK) atRow:1 column:0]; + [aMatrix setState:(aMask & NX_COMMANDMASK) atRow:2 column:0]; + [aMatrix setState:(aMask & NX_ALTERNATEMASK) atRow:3 column:0]; + [aMatrix setState:(aMask & NX_SECONDARYFNMASK) atRow:4 column:0]; +} + +// Generate a modifiers mask from a modifiers checkbox matrix +- (int)getMaskFromMatrix:(NSMatrix *)aMatrix +{ + int theMask = 0; + + if ([[aMatrix cellAtRow:0 column:0] state]) + theMask |= NX_SHIFTMASK; + if ([[aMatrix cellAtRow:1 column:0] state]) + theMask |= NX_CONTROLMASK; + if ([[aMatrix cellAtRow:2 column:0] state]) + theMask |= NX_COMMANDMASK; + if ([[aMatrix cellAtRow:3 column:0] state]) + theMask |= NX_ALTERNATEMASK; + if ([[aMatrix cellAtRow:4 column:0] state]) + theMask |= NX_SECONDARYFNMASK; + + return theMask; +} + +// Set the window controls to the state in user defaults +- (void)resetWindow +{ + if ([Preferences keymapFile] == nil) + [keymapFileField setStringValue:@" "]; + else + [keymapFileField setStringValue:[Preferences keymapFile]]; + + if ([Preferences switchString] == nil) + [switchKeyButton setTitle:@"--"]; + else + [switchKeyButton setTitle:[Preferences switchString]]; + + [displayField setIntValue:[Preferences display]]; + [dockSwitchButton setIntValue:[Preferences dockSwitch]]; + [fakeButton setIntValue:[Preferences fakeButtons]]; + [self resetMatrix:button2ModifiersMatrix + withMask:[Preferences button2Mask]]; + [self resetMatrix:button3ModifiersMatrix + withMask:[Preferences button3Mask]]; + [modeMatrix setState:[Preferences rootless] atRow:0 column:1]; + [startupHelpButton setIntValue:[Preferences startupHelp]]; + [modeWindowButton setIntValue:[Preferences modeWindow]]; + [systemBeepButton setIntValue:[Preferences systemBeep]]; + [mouseAccelChangeButton setIntValue:[Preferences mouseAccelChange]]; + [useXineramaButton setIntValue:[Preferences xinerama]]; + [addToPathButton setIntValue:[Preferences addToPath]]; + [addToPathField setStringValue:[Preferences addToPathString]]; + [useDefaultShellMatrix setState:![Preferences useDefaultShell] + atRow:1 column:0]; + [useOtherShellField setStringValue:[Preferences shellString]]; + [depthButton selectItemAtIndex:[Preferences depth]]; +} + +- (void)awakeFromNib +{ + [self resetWindow]; +} + +// Preference window delegate +- (void)windowWillClose:(NSNotification *)aNotification +{ + [self resetWindow]; + [self initSwitchKey]; +} + +// User cancelled the changes +- (IBAction)close:(id)sender +{ + [window orderOut:nil]; + [self resetWindow]; // reset window controls + [self initSwitchKey]; // reset switch key state +} + +// Pick keymapping file +- (IBAction)pickFile:(id)sender +{ + int result; + NSArray *fileTypes = [NSArray arrayWithObject:@"keymapping"]; + NSOpenPanel *oPanel = [NSOpenPanel openPanel]; + + [oPanel setAllowsMultipleSelection:NO]; + result = [oPanel runModalForDirectory:@"/System/Library/Keyboards" + file:nil types:fileTypes]; + if (result == NSOKButton) { + [keymapFileField setStringValue:[oPanel filename]]; + } +} + +// User saved changes +- (IBAction)saveChanges:(id)sender +{ + [Preferences setKeyCode:keyCode]; + [Preferences setModifiers:modifiers]; + [Preferences setSwitchString:switchString]; + [Preferences setKeymapFile:[keymapFileField stringValue]]; + [Preferences setUseKeymapFile:YES]; + [Preferences setDisplay:[displayField intValue]]; + [Preferences setDockSwitch:[dockSwitchButton intValue]]; + [Preferences setFakeButtons:[fakeButton intValue]]; + [Preferences setButton2Mask: + [self getMaskFromMatrix:button2ModifiersMatrix]]; + [Preferences setButton3Mask: + [self getMaskFromMatrix:button3ModifiersMatrix]]; + [Preferences setRootless:[[modeMatrix cellAtRow:0 column:1] state]]; + [Preferences setModeWindow:[modeWindowButton intValue]]; + [Preferences setStartupHelp:[startupHelpButton intValue]]; + [Preferences setSystemBeep:[systemBeepButton intValue]]; + [Preferences setMouseAccelChange:[mouseAccelChangeButton intValue]]; + [Preferences setXinerama:[useXineramaButton intValue]]; + [Preferences setAddToPath:[addToPathButton intValue]]; + [Preferences setAddToPathString:[addToPathField stringValue]]; + [Preferences setUseDefaultShell: + [[useDefaultShellMatrix cellAtRow:0 column:0] state]]; + [Preferences setShellString:[useOtherShellField stringValue]]; + [Preferences setDepth:[depthButton indexOfSelectedItem]]; + [Preferences saveToDisk]; + + [window orderOut:nil]; +} + +- (IBAction)setKey:(id)sender +{ + [switchKeyButton setTitle:NSLocalizedString(@"Press key",@"")]; + isGettingKeyCode=YES; + [switchString setString:@""]; +} + +- (BOOL)sendEvent:(NSEvent*)anEvent +{ + if(isGettingKeyCode) { + if([anEvent type]==NSKeyDown) // wait for keyup + return YES; + if([anEvent type]!=NSKeyUp) + return NO; + + if([anEvent modifierFlags] & NSCommandKeyMask) + [switchString appendString:@"Cmd-"]; + if([anEvent modifierFlags] & NSControlKeyMask) + [switchString appendString:@"Ctrl-"]; + if([anEvent modifierFlags] & NSAlternateKeyMask) + [switchString appendString:@"Opt-"]; + if([anEvent modifierFlags] & NSNumericPadKeyMask) // doesn't work + [switchString appendString:@"Num-"]; + if([anEvent modifierFlags] & NSHelpKeyMask) + [switchString appendString:@"Help-"]; + if([anEvent modifierFlags] & NSFunctionKeyMask) // powerbooks only + [switchString appendString:@"Fn-"]; + + [switchString appendString:[anEvent charactersIgnoringModifiers]]; + [switchKeyButton setTitle:switchString]; + + keyCode = [anEvent keyCode]; + modifiers = [anEvent modifierFlags]; + isGettingKeyCode=NO; + + return YES; + } + return NO; +} + ++ (void)setKeymapFile:(NSString*)newFile +{ + [[NSUserDefaults standardUserDefaults] setObject:newFile + forKey:@"KeymappingFile"]; +} + ++ (void)setUseKeymapFile:(BOOL)newUseKeymapFile +{ + [[NSUserDefaults standardUserDefaults] setBool:newUseKeymapFile + forKey:@"UseKeymappingFile"]; +} + ++ (void)setSwitchString:(NSString*)newString +{ + [[NSUserDefaults standardUserDefaults] setObject:newString + forKey:@"SwitchString"]; +} + ++ (void)setKeyCode:(int)newKeyCode +{ + [[NSUserDefaults standardUserDefaults] setInteger:newKeyCode + forKey:@"SwitchKeyCode"]; +} + ++ (void)setModifiers:(int)newModifiers +{ + [[NSUserDefaults standardUserDefaults] setInteger:newModifiers + forKey:@"SwitchModifiers"]; +} + ++ (void)setDisplay:(int)newDisplay +{ + [[NSUserDefaults standardUserDefaults] setInteger:newDisplay + forKey:@"Display"]; +} + ++ (void)setDockSwitch:(BOOL)newDockSwitch +{ + [[NSUserDefaults standardUserDefaults] setBool:newDockSwitch + forKey:@"DockSwitch"]; +} + ++ (void)setFakeButtons:(BOOL)newFakeButtons +{ + [[NSUserDefaults standardUserDefaults] setBool:newFakeButtons + forKey:@"FakeButtons"]; + // Update the setting used by the X server thread + darwinFakeButtons = newFakeButtons; +} + ++ (void)setButton2Mask:(int)newFakeMask +{ + [[NSUserDefaults standardUserDefaults] setInteger:newFakeMask + forKey:@"Button2Mask"]; + // Update the setting used by the X server thread + darwinFakeMouse2Mask = newFakeMask; +} + ++ (void)setButton3Mask:(int)newFakeMask +{ + [[NSUserDefaults standardUserDefaults] setInteger:newFakeMask + forKey:@"Button3Mask"]; + // Update the setting used by the X server thread + darwinFakeMouse3Mask = newFakeMask; +} + ++ (void)setMouseAccelChange:(BOOL)newMouseAccelChange +{ + [[NSUserDefaults standardUserDefaults] setBool:newMouseAccelChange + forKey:@"AllowMouseAccelChange"]; + // Update the setting used by the X server thread + quartzMouseAccelChange = newMouseAccelChange; +} + ++ (void)setUseQDCursor:(int)newUseQDCursor +{ + [[NSUserDefaults standardUserDefaults] setInteger:newUseQDCursor + forKey:@"UseQDCursor"]; +} + ++ (void)setModeWindow:(BOOL)newModeWindow +{ + [[NSUserDefaults standardUserDefaults] setBool:newModeWindow + forKey:@"ShowModePickWindow"]; +} + ++ (void)setRootless:(BOOL)newRootless +{ + [[NSUserDefaults standardUserDefaults] setBool:newRootless + forKey:@"UseRootlessMode"]; +} + ++ (void)setUseAGL:(BOOL)newUseAGL +{ + [[NSUserDefaults standardUserDefaults] setBool:newUseAGL + forKey:@"UseAGLforGLX"]; +} + ++ (void)setStartupHelp:(BOOL)newStartupHelp +{ + [[NSUserDefaults standardUserDefaults] setBool:newStartupHelp + forKey:@"ShowStartupHelp"]; +} + ++ (void)setSystemBeep:(BOOL)newSystemBeep +{ + [[NSUserDefaults standardUserDefaults] setBool:newSystemBeep + forKey:@"UseSystemBeep"]; + // Update the setting used by the X server thread + quartzUseSysBeep = newSystemBeep; +} + ++ (void)setXinerama:(BOOL)newXinerama +{ + [[NSUserDefaults standardUserDefaults] setBool:newXinerama + forKey:@"Xinerama"]; +} + ++ (void)setAddToPath:(BOOL)newAddToPath +{ + [[NSUserDefaults standardUserDefaults] setBool:newAddToPath + forKey:@"AddToPath"]; +} + ++ (void)setAddToPathString:(NSString*)newAddToPathString +{ + [[NSUserDefaults standardUserDefaults] setObject:newAddToPathString + forKey:@"AddToPathString"]; +} + ++ (void)setUseDefaultShell:(BOOL)newUseDefaultShell +{ + [[NSUserDefaults standardUserDefaults] setBool:newUseDefaultShell + forKey:@"UseDefaultShell"]; +} + ++ (void)setShellString:(NSString*)newShellString +{ + [[NSUserDefaults standardUserDefaults] setObject:newShellString + forKey:@"Shell"]; +} + ++ (void)setDepth:(int)newDepth +{ + [[NSUserDefaults standardUserDefaults] setInteger:newDepth + forKey:@"Depth"]; +} + ++ (void)saveToDisk +{ + [[NSUserDefaults standardUserDefaults] synchronize]; +} + ++ (BOOL)useKeymapFile +{ + return [[NSUserDefaults standardUserDefaults] + boolForKey:@"UseKeymappingFile"]; +} + ++ (NSString*)keymapFile +{ + return [[NSUserDefaults standardUserDefaults] + stringForKey:@"KeymappingFile"]; +} + ++ (NSString*)switchString +{ + return [[NSUserDefaults standardUserDefaults] + stringForKey:@"SwitchString"]; +} + ++ (unsigned int)keyCode +{ + return [[NSUserDefaults standardUserDefaults] + integerForKey:@"SwitchKeyCode"]; +} + ++ (unsigned int)modifiers +{ + return [[NSUserDefaults standardUserDefaults] + integerForKey:@"SwitchModifiers"]; +} + ++ (int)display +{ + return [[NSUserDefaults standardUserDefaults] + integerForKey:@"Display"]; +} + ++ (BOOL)dockSwitch +{ + return [[NSUserDefaults standardUserDefaults] boolForKey:@"DockSwitch"]; +} + ++ (BOOL)fakeButtons +{ + return [[NSUserDefaults standardUserDefaults] boolForKey:@"FakeButtons"]; +} + ++ (int)button2Mask +{ + return [[NSUserDefaults standardUserDefaults] + integerForKey:@"Button2Mask"]; +} + ++ (int)button3Mask +{ + return [[NSUserDefaults standardUserDefaults] + integerForKey:@"Button3Mask"]; +} + ++ (BOOL)mouseAccelChange +{ + return [[NSUserDefaults standardUserDefaults] + boolForKey:@"AllowMouseAccelChange"]; +} + ++ (int)useQDCursor +{ + return [[NSUserDefaults standardUserDefaults] + integerForKey:@"UseQDCursor"]; +} + ++ (BOOL)rootless +{ + return [[NSUserDefaults standardUserDefaults] + boolForKey:@"UseRootlessMode"]; +} + ++ (BOOL)useAGL +{ + return [[NSUserDefaults standardUserDefaults] + boolForKey:@"UseAGLforGLX"]; +} + ++ (BOOL)modeWindow +{ + return [[NSUserDefaults standardUserDefaults] + boolForKey:@"ShowModePickWindow"]; +} + ++ (BOOL)startupHelp +{ + return [[NSUserDefaults standardUserDefaults] + boolForKey:@"ShowStartupHelp"]; +} + ++ (BOOL)systemBeep +{ + return [[NSUserDefaults standardUserDefaults] boolForKey:@"UseSystemBeep"]; +} + ++ (BOOL)xinerama +{ + return [[NSUserDefaults standardUserDefaults] boolForKey:@"Xinerama"]; +} + ++ (BOOL)addToPath +{ + return [[NSUserDefaults standardUserDefaults] boolForKey:@"AddToPath"]; +} + ++ (NSString*)addToPathString +{ + return [[NSUserDefaults standardUserDefaults] + stringForKey:@"AddToPathString"]; +} + ++ (BOOL)useDefaultShell +{ + return [[NSUserDefaults standardUserDefaults] + boolForKey:@"UseDefaultShell"]; +} + ++ (NSString*)shellString +{ + return [[NSUserDefaults standardUserDefaults] + stringForKey:@"Shell"]; +} + ++ (int)depth +{ + return [[NSUserDefaults standardUserDefaults] + integerForKey:@"Depth"]; +} + + +@end diff --git a/hw/darwin/quartz/XApplication.h b/hw/darwin/quartz/XApplication.h new file mode 100644 index 000000000..3d3e96dab --- /dev/null +++ b/hw/darwin/quartz/XApplication.h @@ -0,0 +1,47 @@ +// +// XApplication.h +// +// Created by Andreas Monitzer on January 6, 2001. +// +/* + * Copyright (c) 2001 Andreas Monitzer. 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. + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/XApplication.h,v 1.2 2002/10/12 00:32:45 torrey Exp $ */ + +#import <Cocoa/Cocoa.h> + +#import "XServer.h" +#import "Preferences.h" + +@interface XApplication : NSApplication { + IBOutlet XServer *xserver; + IBOutlet Preferences *preferences; +} + +- (void)sendEvent:(NSEvent *)anEvent; + +@end diff --git a/hw/darwin/quartz/XApplication.m b/hw/darwin/quartz/XApplication.m new file mode 100644 index 000000000..9b81bbee0 --- /dev/null +++ b/hw/darwin/quartz/XApplication.m @@ -0,0 +1,47 @@ +// +// XApplication.m +// +// Created by Andreas Monitzer on January 6, 2001. +// +/* + * Copyright (c) 2001 Andreas Monitzer. 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. + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/XApplication.m,v 1.2 2002/10/12 00:32:45 torrey Exp $ */ + +#import "XApplication.h" + + +@implementation XApplication + +- (void)sendEvent:(NSEvent *)anEvent { + if (![xserver translateEvent:anEvent]) { + if (![preferences sendEvent:anEvent]) + [super sendEvent:anEvent]; + } +} + +@end diff --git a/hw/darwin/quartz/XDarwin.pbproj/project.pbxproj b/hw/darwin/quartz/XDarwin.pbproj/project.pbxproj new file mode 100644 index 000000000..574ce5f18 --- /dev/null +++ b/hw/darwin/quartz/XDarwin.pbproj/project.pbxproj @@ -0,0 +1,1683 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 38; + objects = { + 01279092000747AA0A000002 = { + fileEncoding = 30; + isa = PBXFileReference; + path = XServer.m; + refType = 4; + }; + 0127909600074AF60A000002 = { + fileEncoding = 30; + isa = PBXFileReference; + path = XApplication.m; + refType = 4; + }; + 0127909800074B1A0A000002 = { + fileEncoding = 30; + isa = PBXFileReference; + path = XApplication.h; + refType = 4; + }; + 014C68ED00ED6A9D7F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = XView.h; + refType = 4; + }; + 014C68EE00ED6A9D7F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = XView.m; + refType = 4; + }; + 014C68F200ED7AD67F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = fakeBoxRec.h; + refType = 4; + }; + 014C68F300EE5AB97F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = rootlessCommon.c; + refType = 4; + }; + 014C68F400EE5AB97F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = rootlessCommon.h; + refType = 4; + }; + 014C68F700EE678F7F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = rootlessWindow.c; + refType = 4; + }; + 014C68F800EE678F7F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = rootlessWindow.h; + refType = 4; + }; + 015698ED003DF345CE6F79C2 = { + isa = PBXFileReference; + path = XDarwin.icns; + refType = 4; + }; + 0157A37D002CF6D7CE6F79C2 = { + children = ( + F533214601A4B45401000001, + 0157A37E002CF6D7CE6F79C2, + F58D65DF018F79B101000001, + F533213D0193CBE001000001, + 43B962E200617B93416877C2, + F5ACD263C5BE031F01000001, + F51BF62E02026E3501000001, + F5ACD25CC5B5E96601000001, + F587E16401924C6901000001, + ); + isa = PBXVariantGroup; + name = Credits.rtf; + path = ""; + refType = 4; + }; + 0157A37E002CF6D7CE6F79C2 = { + isa = PBXFileReference; + name = English; + path = English.lproj/Credits.rtf; + refType = 4; + }; + 015EDCEA004203A8CE6F79C2 = { + isa = PBXFrameworkReference; + name = IOKit.framework; + path = /System/Library/Frameworks/IOKit.framework; + refType = 0; + }; + 017D6F4400E861FB7F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = rootlessGC.c; + refType = 4; + }; + 017D6F4500E861FB7F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = rootlessScreen.c; + refType = 4; + }; + 018F40F2003E1902CE6F79C2 = { + children = ( + 018F40F3003E1916CE6F79C2, + 021D6BA9003E1BACCE6F79C2, + 3E74E03600863F047F000001, + F5A94EF10314BAC70100011B, + 018F40F6003E1974CE6F79C2, + ); + isa = PBXGroup; + name = "X Server"; + path = ..; + refType = 4; + }; + 018F40F3003E1916CE6F79C2 = { + fileEncoding = 30; + isa = PBXFileReference; + path = darwin.c; + refType = 4; + }; + 018F40F6003E1974CE6F79C2 = { + fileEncoding = 30; + isa = PBXFileReference; + path = darwinKeyboard.c; + refType = 4; + }; + 018F40F8003E1979CE6F79C2 = { + fileEncoding = 30; + isa = PBXFileReference; + path = quartz.c; + refType = 4; + }; + 018F40FA003E197ECE6F79C2 = { + fileEncoding = 30; + isa = PBXFileReference; + path = quartz.h; + refType = 4; + }; + 018F40FC003E1983CE6F79C2 = { + fileEncoding = 30; + isa = PBXFileReference; + path = xfIOKit.c; + refType = 4; + }; + 018F40FE003E1988CE6F79C2 = { + fileEncoding = 30; + isa = PBXFileReference; + path = xfIOKit.h; + refType = 4; + }; + 018F4100003E19E4CE6F79C2 = { + fileEncoding = 30; + isa = PBXFileReference; + path = xfIOKitCursor.c; + refType = 4; + }; +//010 +//011 +//012 +//013 +//014 +//020 +//021 +//022 +//023 +//024 + 021D6BA9003E1BACCE6F79C2 = { + fileEncoding = 30; + isa = PBXFileReference; + path = darwin.h; + refType = 4; + }; + 02A1FEA6006D34BE416877C2 = { + fileEncoding = 30; + isa = PBXFileReference; + path = xfIOKitStartup.c; + refType = 4; + }; + 02A1FEA8006D38F0416877C2 = { + fileEncoding = 30; + isa = PBXFileReference; + path = quartzStartup.c; + refType = 4; + }; + 02E03CA000348209CE6F79C2 = { + children = ( + F533214701A4B48301000001, + 02E03CA100348209CE6F79C2, + F58D65E0018F79C001000001, + F533213E0193CBF401000001, + 43B962E300617B93416877C2, + F5ACD268C5BE046401000001, + F51BF62F02026E5C01000001, + F5ACD261C5B5EA2001000001, + F587E16501924C7401000001, + ); + isa = PBXVariantGroup; + name = XDarwinHelp.html; + path = ""; + refType = 4; + }; + 02E03CA100348209CE6F79C2 = { + fileEncoding = 30; + isa = PBXFileReference; + name = English; + path = English.lproj/XDarwinHelp.html; + refType = 4; + }; +//020 +//021 +//022 +//023 +//024 +//030 +//031 +//032 +//033 +//034 + 0338412F0083BFE57F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = quartzCursor.h; + refType = 4; + }; +//030 +//031 +//032 +//033 +//034 +//040 +//041 +//042 +//043 +//044 + 04329610000763920A000002 = { + fileEncoding = 30; + isa = PBXFileReference; + path = Preferences.m; + refType = 4; + }; + 04329611000763920A000002 = { + fileEncoding = 30; + isa = PBXFileReference; + path = Preferences.h; + refType = 4; + }; +//040 +//041 +//042 +//043 +//044 +//060 +//061 +//062 +//063 +//064 + 06EB6C3B004099E7CE6F79C2 = { + fileEncoding = 30; + isa = PBXFileReference; + path = quartzShared.h; + refType = 4; + }; +//060 +//061 +//062 +//063 +//064 +//080 +//081 +//082 +//083 +//084 + 080E96DDFE201D6D7F000001 = { + children = ( + 04329610000763920A000002, + 04329611000763920A000002, + 0127909600074AF60A000002, + 0127909800074B1A0A000002, + 01279092000747AA0A000002, + 1C4A3109004D8F24CE6F79C2, + 014C68EE00ED6A9D7F000001, + 014C68ED00ED6A9D7F000001, + ); + isa = PBXGroup; + name = Classes; + refType = 4; + }; + 089C165CFE840E0CC02AAC07 = { + children = ( + F533214301A4B3F001000001, + 089C165DFE840E0CC02AAC07, + F58D65DD018F798F01000001, + F533213A0193CBA201000001, + 43B962E100617B49416877C2, + F5ACD269C5BE049301000001, + F51BF62B02026DDA01000001, + F5ACD262C5B5EA4D01000001, + F587E16101924C2F01000001, + ); + isa = PBXVariantGroup; + name = InfoPlist.strings; + refType = 4; + }; + 089C165DFE840E0CC02AAC07 = { + fileEncoding = 30; + isa = PBXFileReference; + name = English; + path = English.lproj/InfoPlist.strings; + refType = 4; + }; +//080 +//081 +//082 +//083 +//084 +//0A0 +//0A1 +//0A2 +//0A3 +//0A4 + 0A79E19E004499A1CE6F79C2 = { + isa = PBXApplicationReference; + path = XDarwin.app; + refType = 3; + }; + 0A79E19F004499A1CE6F79C2 = { + buildPhases = ( + 0A79E1A0004499A1CE6F79C2, + 0A79E1A1004499A1CE6F79C2, + 0A79E1A2004499A1CE6F79C2, + 0A79E1A3004499A1CE6F79C2, + 0A79E1A4004499A1CE6F79C2, + ); + buildSettings = { + INSTALL_PATH = /; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = XDarwin; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; + WRAPPER_EXTENSION = app; + }; + dependencies = ( + 6EF065C903D4F0CA006877C2, + 6EF065C703D4EE19006877C2, + ); + isa = PBXApplicationTarget; + name = XDarwin; + productInstallPath = /; + productName = XDarwin; + productReference = 0A79E19E004499A1CE6F79C2; + productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> +<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"> +<plist version=\"1.0\"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleExecutable</key> + <string>XDarwin</string> + <key>CFBundleGetInfoString</key> + <string>XDarwin 1.2.0, ©2001-2003 XFree86 Project, Inc.</string> + <key>CFBundleIconFile</key> + <string>XDarwin.icns</string> + <key>CFBundleIdentifier</key> + <string>org.xfree86.XDarwin</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>XDarwin</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>XDarwin 1.2.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string></string> + <key>NSHelpFile</key> + <string>XDarwinHelp.html</string> + <key>NSMainNibFile</key> + <string>MainMenu</string> + <key>NSPrincipalClass</key> + <string>XApplication</string> +</dict> +</plist> +"; + }; + 0A79E1A0004499A1CE6F79C2 = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 0A79E1A1004499A1CE6F79C2 = { + buildActionMask = 2147483647; + files = ( + 0A79E1A600449EB2CE6F79C2, + 0A79E1A700449EB2CE6F79C2, + 0A79E1A800449EB2CE6F79C2, + 0A79E1A900449EB2CE6F79C2, + 0A79E1AA00449EB2CE6F79C2, + 1220774500712D2D416877C2, + F54BF6ED017D506E01000001, + ); + isa = PBXResourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 0A79E1A2004499A1CE6F79C2 = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 0A79E1A3004499A1CE6F79C2 = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 0A79E1A4004499A1CE6F79C2 = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXRezBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 0A79E1A600449EB2CE6F79C2 = { + fileRef = 29B97318FDCFA39411CA2CEA; + isa = PBXBuildFile; + settings = { + }; + }; + 0A79E1A700449EB2CE6F79C2 = { + fileRef = 089C165CFE840E0CC02AAC07; + isa = PBXBuildFile; + settings = { + }; + }; + 0A79E1A800449EB2CE6F79C2 = { + fileRef = 0157A37D002CF6D7CE6F79C2; + isa = PBXBuildFile; + settings = { + }; + }; + 0A79E1A900449EB2CE6F79C2 = { + fileRef = 02E03CA000348209CE6F79C2; + isa = PBXBuildFile; + settings = { + }; + }; + 0A79E1AA00449EB2CE6F79C2 = { + fileRef = 015698ED003DF345CE6F79C2; + isa = PBXBuildFile; + settings = { + }; + }; +//0A0 +//0A1 +//0A2 +//0A3 +//0A4 +//100 +//101 +//102 +//103 +//104 + 1058C7A0FEA54F0111CA2CBB = { + children = ( + F53321400193CCF001000001, + 1BE4F84D0006C9890A000002, + 1058C7A1FEA54F0111CA2CBB, + F53321410193CCF001000001, + 015EDCEA004203A8CE6F79C2, + ); + isa = PBXGroup; + name = "Linked Frameworks"; + refType = 4; + }; + 1058C7A1FEA54F0111CA2CBB = { + isa = PBXFrameworkReference; + name = Cocoa.framework; + path = /System/Library/Frameworks/Cocoa.framework; + refType = 0; + }; + 1058C7A2FEA54F0111CA2CBB = { + children = ( + 29B97325FDCFA39411CA2CEA, + 29B97324FDCFA39411CA2CEA, + ); + isa = PBXGroup; + name = "Other Frameworks"; + refType = 4; + }; +//100 +//101 +//102 +//103 +//104 +//120 +//121 +//122 +//123 +//124 + 1220774300712D2D416877C2 = { + children = ( + F533214501A4B42501000001, + 1220774400712D2D416877C2, + F58D65DE018F79A001000001, + F533213C0193CBC901000001, + 1220774600712D75416877C2, + F5ACD266C5BE03C501000001, + F51BF62D02026E1C01000001, + F5ACD25FC5B5E9AA01000001, + F587E16301924C5E01000001, + ); + isa = PBXVariantGroup; + name = Localizable.strings; + path = ""; + refType = 4; + }; + 1220774400712D2D416877C2 = { + fileEncoding = 30; + isa = PBXFileReference; + name = English; + path = English.lproj/Localizable.strings; + refType = 4; + }; + 1220774500712D2D416877C2 = { + fileRef = 1220774300712D2D416877C2; + isa = PBXBuildFile; + settings = { + }; + }; + 1220774600712D75416877C2 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Japanese; + path = Japanese.lproj/Localizable.strings; + refType = 4; + }; +//120 +//121 +//122 +//123 +//124 +//170 +//171 +//172 +//173 +//174 + 170DFAFF00729A35416877C2 = { + fileEncoding = 30; + isa = PBXFileReference; + path = XDarwinStartup.c; + refType = 4; + }; + 170DFB0000729C86416877C2 = { + children = ( + 018F40FC003E1983CE6F79C2, + 018F40FE003E1988CE6F79C2, + 018F4100003E19E4CE6F79C2, + 02A1FEA6006D34BE416877C2, + ); + isa = PBXGroup; + name = IOKit; + path = ..; + refType = 4; + }; +//170 +//171 +//172 +//173 +//174 +//190 +//191 +//192 +//193 +//194 + 19C28FACFE9D520D11CA2CBB = { + children = ( + 0A79E19E004499A1CE6F79C2, + 6EF7C58703D3BC6D00000104, + 6EF065C603D4EE19006877C2, + ); + isa = PBXGroup; + name = Products; + refType = 4; + }; +//190 +//191 +//192 +//193 +//194 +//1B0 +//1B1 +//1B2 +//1B3 +//1B4 + 1BD8DE4200B8A3567F000001 = { + children = ( + F533214401A4B40F01000001, + 1BD8DE4300B8A3567F000001, + F58D65DC018F794D01000001, + F533213B0193CBB401000001, + 1BD8DE4700B8A3C77F000001, + F5ACD264C5BE035B01000001, + F51BF62C02026E0601000001, + F5ACD25DC5B5E97701000001, + F587E16201924C5301000001, + ); + isa = PBXVariantGroup; + name = InfoPlist.strings.cpp; + path = ""; + refType = 4; + }; + 1BD8DE4300B8A3567F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = English; + path = English.lproj/InfoPlist.strings.cpp; + refType = 4; + }; + 1BD8DE4400B8A38E7F000001 = { + children = ( + F533214801A4B4D701000001, + 1BD8DE4500B8A38E7F000001, + F58D65E1018F79E001000001, + F533213F0193CC2501000001, + 1BD8DE4800B8A4167F000001, + F5ACD267C5BE03FC01000001, + F51BF63002026E8D01000001, + F5ACD260C5B5E9DF01000001, + F587E16601924C9D01000001, + ); + isa = PBXVariantGroup; + name = XDarwinHelp.html.cpp; + path = ""; + refType = 4; + }; + 1BD8DE4500B8A38E7F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = English; + path = English.lproj/XDarwinHelp.html.cpp; + refType = 4; + }; + 1BD8DE4700B8A3C77F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Japanese; + path = Japanese.lproj/InfoPlist.strings.cpp; + refType = 4; + }; + 1BD8DE4800B8A4167F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Japanese; + path = Japanese.lproj/XDarwinHelp.html.cpp; + refType = 4; + }; + 1BE4F84D0006C9890A000002 = { + isa = PBXFrameworkReference; + name = Carbon.framework; + path = /System/Library/Frameworks/Carbon.framework; + refType = 0; + }; +//1B0 +//1B1 +//1B2 +//1B3 +//1B4 +//1C0 +//1C1 +//1C2 +//1C3 +//1C4 + 1C4A3109004D8F24CE6F79C2 = { + fileEncoding = 30; + isa = PBXFileReference; + path = XServer.h; + refType = 4; + }; +//1C0 +//1C1 +//1C2 +//1C3 +//1C4 +//230 +//231 +//232 +//233 +//234 + 237A34C10076E37E7F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = quartzAudio.c; + refType = 4; + }; + 237A34C20076E37E7F000001 = { + buildRules = ( + ); + buildSettings = { + COPY_PHASE_STRIP = NO; + OPTIMIZATION_CFLAGS = "-O0"; + }; + isa = PBXBuildStyle; + name = Development; + }; + 237A34C30076E37E7F000001 = { + buildRules = ( + ); + buildSettings = { + COPY_PHASE_STRIP = YES; + }; + isa = PBXBuildStyle; + name = Deployment; + }; + 237A34C40076F4F07F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = quartzAudio.h; + refType = 4; + }; +//230 +//231 +//232 +//233 +//234 +//290 +//291 +//292 +//293 +//294 + 29B97313FDCFA39411CA2CEA = { + buildStyles = ( + 237A34C20076E37E7F000001, + 237A34C30076E37E7F000001, + ); + hasScannedForEncodings = 1; + isa = PBXProject; + knownRegions = ( + English, + Japanese, + French, + German, + Swedish, + Dutch, + Spanish, + ko, + Portuguese, + ); + mainGroup = 29B97314FDCFA39411CA2CEA; + projectDirPath = ""; + targets = ( + 0A79E19F004499A1CE6F79C2, + 6EF7C58603D3BC6D00000104, + 6EF065C503D4EE19006877C2, + ); + }; + 29B97314FDCFA39411CA2CEA = { + children = ( + 080E96DDFE201D6D7F000001, + 018F40F2003E1902CE6F79C2, + 170DFB0000729C86416877C2, + 43B962CE00617089416877C2, + F5614B3D025112D901000114, + 32FEE13C00E07C3E7F000001, + 29B97315FDCFA39411CA2CEA, + 29B97317FDCFA39411CA2CEA, + 29B97323FDCFA39411CA2CEA, + 19C28FACFE9D520D11CA2CBB, + ); + isa = PBXGroup; + name = "Xmaster-Cocoa"; + path = ""; + refType = 4; + }; + 29B97315FDCFA39411CA2CEA = { + children = ( + 170DFAFF00729A35416877C2, + ); + isa = PBXGroup; + name = "Other Sources"; + path = ""; + refType = 2; + }; + 29B97317FDCFA39411CA2CEA = { + children = ( + 29B97318FDCFA39411CA2CEA, + 089C165CFE840E0CC02AAC07, + 1BD8DE4200B8A3567F000001, + 1220774300712D2D416877C2, + 0157A37D002CF6D7CE6F79C2, + 02E03CA000348209CE6F79C2, + 1BD8DE4400B8A38E7F000001, + 015698ED003DF345CE6F79C2, + F54BF6EA017D500901000001, + F54BF6EC017D506E01000001, + ); + isa = PBXGroup; + name = Resources; + path = ../bundle; + refType = 4; + }; + 29B97318FDCFA39411CA2CEA = { + children = ( + F533214201A4B3CE01000001, + 29B97319FDCFA39411CA2CEA, + F58D65DB018F793801000001, + F53321390193CB6A01000001, + 43B962E000617B49416877C2, + F5ACD265C5BE038601000001, + F51BF62A02026DAF01000001, + F5ACD25EC5B5E98D01000001, + F587E16001924C1D01000001, + ); + isa = PBXVariantGroup; + name = MainMenu.nib; + path = ""; + refType = 4; + }; + 29B97319FDCFA39411CA2CEA = { + isa = PBXFileReference; + name = English; + path = English.lproj/MainMenu.nib; + refType = 4; + }; + 29B97323FDCFA39411CA2CEA = { + children = ( + 1058C7A0FEA54F0111CA2CBB, + 1058C7A2FEA54F0111CA2CBB, + ); + isa = PBXGroup; + name = Frameworks; + path = ""; + refType = 4; + }; + 29B97324FDCFA39411CA2CEA = { + isa = PBXFrameworkReference; + name = AppKit.framework; + path = /System/Library/Frameworks/AppKit.framework; + refType = 0; + }; + 29B97325FDCFA39411CA2CEA = { + isa = PBXFrameworkReference; + name = Foundation.framework; + path = /System/Library/Frameworks/Foundation.framework; + refType = 0; + }; +//290 +//291 +//292 +//293 +//294 +//320 +//321 +//322 +//323 +//324 + 32FEE13C00E07C3E7F000001 = { + children = ( + F56CBD0D02EB84A801129B8A, + F56CBD0E02EB84A801129B8A, + F56CBD0F02EBDCFC01129B8A, + 014C68F200ED7AD67F000001, + F5269C2D01D5BC3501000001, + F5269C2E01D5BC3501000001, + 32FEE13E00E07CBE7F000001, + 32FEE13F00E07CBE7F000001, + 32FEE14000E07CBE7F000001, + 32FEE14100E07CBE7F000001, + 32FEE14200E07CBE7F000001, + 014C68F300EE5AB97F000001, + 014C68F400EE5AB97F000001, + 017D6F4400E861FB7F000001, + 017D6F4500E861FB7F000001, + 014C68F700EE678F7F000001, + 014C68F800EE678F7F000001, + 32FEE14900E07D317F000001, + ); + isa = PBXGroup; + name = Rootless; + path = ""; + refType = 4; + }; + 32FEE13E00E07CBE7F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = rootless.h; + refType = 4; + }; + 32FEE13F00E07CBE7F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = rootlessAqua.h; + refType = 4; + }; + 32FEE14000E07CBE7F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = rootlessAquaGlue.c; + refType = 4; + }; + 32FEE14100E07CBE7F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = rootlessAquaImp.h; + refType = 4; + }; + 32FEE14200E07CBE7F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = rootlessAquaImp.m; + refType = 4; + }; + 32FEE14900E07D317F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = rootlessValTree.c; + refType = 4; + }; +//320 +//321 +//322 +//323 +//324 +//350 +//351 +//352 +//353 +//354 + 3576829A0077B8F17F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = quartzCursor.c; + refType = 4; + }; +//350 +//351 +//352 +//353 +//354 +//3E0 +//3E1 +//3E2 +//3E3 +//3E4 + 3E74E03600863F047F000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = darwinClut8.h; + refType = 4; + }; +//3E0 +//3E1 +//3E2 +//3E3 +//3E4 +//430 +//431 +//432 +//433 +//434 + 43B962CE00617089416877C2 = { + children = ( + 018F40F8003E1979CE6F79C2, + 018F40FA003E197ECE6F79C2, + 237A34C10076E37E7F000001, + 237A34C40076F4F07F000001, + 3576829A0077B8F17F000001, + 0338412F0083BFE57F000001, + 43B962D000617089416877C2, + 43B962D100617089416877C2, + 43B962CF00617089416877C2, + F5582948015DAD3B01000001, + 06EB6C3B004099E7CE6F79C2, + 02A1FEA8006D38F0416877C2, + ); + isa = PBXGroup; + name = Quartz; + path = ""; + refType = 4; + }; + 43B962CF00617089416877C2 = { + fileEncoding = 30; + isa = PBXFileReference; + path = quartzCocoa.m; + refType = 4; + }; + 43B962D000617089416877C2 = { + fileEncoding = 30; + isa = PBXFileReference; + path = quartzPasteboard.c; + refType = 4; + }; + 43B962D100617089416877C2 = { + fileEncoding = 30; + isa = PBXFileReference; + path = quartzPasteboard.h; + refType = 4; + }; + 43B962E000617B49416877C2 = { + isa = PBXFileReference; + name = Japanese; + path = Japanese.lproj/MainMenu.nib; + refType = 4; + }; + 43B962E100617B49416877C2 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Japanese; + path = Japanese.lproj/InfoPlist.strings; + refType = 4; + }; + 43B962E200617B93416877C2 = { + isa = PBXFileReference; + name = Japanese; + path = Japanese.lproj/Credits.rtf; + refType = 4; + }; + 43B962E300617B93416877C2 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Japanese; + path = Japanese.lproj/XDarwinHelp.html; + refType = 4; + }; +//430 +//431 +//432 +//433 +//434 +//6E0 +//6E1 +//6E2 +//6E3 +//6E4 + 6EF065C003D4EE19006877C2 = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 6EF065C103D4EE19006877C2 = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXResourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 6EF065C203D4EE19006877C2 = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 6EF065C303D4EE19006877C2 = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 6EF065C403D4EE19006877C2 = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXRezBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 6EF065C503D4EE19006877C2 = { + buildPhases = ( + 6EF065C003D4EE19006877C2, + 6EF065C103D4EE19006877C2, + 6EF065C203D4EE19006877C2, + 6EF065C303D4EE19006877C2, + 6EF065C403D4EE19006877C2, + ); + buildSettings = { + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = glxMesa; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; + WRAPPER_EXTENSION = bundle; + }; + dependencies = ( + ); + isa = PBXBundleTarget; + name = glxMesa; + productInstallPath = "$(USER_LIBRARY_DIR)/Bundles"; + productName = glxMesa; + productReference = 6EF065C603D4EE19006877C2; + productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> +<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"> +<plist version=\"1.0\"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleExecutable</key> + <string>glxMesa</string> + <key>CFBundleGetInfoString</key> + <string></string> + <key>CFBundleIconFile</key> + <string></string> + <key>CFBundleIdentifier</key> + <string></string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>GLX bundle with Mesa</string> + <key>CFBundlePackageType</key> + <string>BNDL</string> + <key>CFBundleShortVersionString</key> + <string>0.1</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>0.1</string> +</dict> +</plist> +"; + }; + 6EF065C603D4EE19006877C2 = { + isa = PBXBundleReference; + path = glxMesa.bundle; + refType = 3; + }; + 6EF065C703D4EE19006877C2 = { + isa = PBXTargetDependency; + target = 6EF065C503D4EE19006877C2; + }; + 6EF065C903D4F0CA006877C2 = { + isa = PBXTargetDependency; + target = 6EF7C58603D3BC6D00000104; + }; + 6EF7C58103D3BC6D00000104 = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 6EF7C58203D3BC6D00000104 = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXResourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 6EF7C58303D3BC6D00000104 = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 6EF7C58403D3BC6D00000104 = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 6EF7C58503D3BC6D00000104 = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXRezBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 6EF7C58603D3BC6D00000104 = { + buildPhases = ( + 6EF7C58103D3BC6D00000104, + 6EF7C58203D3BC6D00000104, + 6EF7C58303D3BC6D00000104, + 6EF7C58403D3BC6D00000104, + 6EF7C58503D3BC6D00000104, + ); + buildSettings = { + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = glxAGL; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; + WRAPPER_EXTENSION = bundle; + }; + dependencies = ( + ); + isa = PBXBundleTarget; + name = glxAGL; + productName = glxAqua; + productReference = 6EF7C58703D3BC6D00000104; + productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> +<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"> +<plist version=\"1.0\"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleExecutable</key> + <string>glxAGL</string> + <key>CFBundleGetInfoString</key> + <string></string> + <key>CFBundleIconFile</key> + <string></string> + <key>CFBundleIdentifier</key> + <string></string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>GLX bundle with AGL</string> + <key>CFBundlePackageType</key> + <string>BNDL</string> + <key>CFBundleShortVersionString</key> + <string>0.1</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>0.1</string> +</dict> +</plist> +"; + }; + 6EF7C58703D3BC6D00000104 = { + isa = PBXBundleReference; + path = glxAGL.bundle; + refType = 3; + }; +//6E0 +//6E1 +//6E2 +//6E3 +//6E4 +//F50 +//F51 +//F52 +//F53 +//F54 + F51BF62A02026DAF01000001 = { + isa = PBXFileReference; + name = Portuguese; + path = Portuguese.lproj/MainMenu.nib; + refType = 4; + }; + F51BF62B02026DDA01000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Portuguese; + path = Portuguese.lproj/InfoPlist.strings; + refType = 4; + }; + F51BF62C02026E0601000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Portuguese; + path = Portuguese.lproj/InfoPlist.strings.cpp; + refType = 4; + }; + F51BF62D02026E1C01000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Portuguese; + path = Portuguese.lproj/Localizable.strings; + refType = 4; + }; + F51BF62E02026E3501000001 = { + isa = PBXFileReference; + name = Portuguese; + path = Portuguese.lproj/Credits.rtf; + refType = 4; + }; + F51BF62F02026E5C01000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Portuguese; + path = Portuguese.lproj/XDarwinHelp.html; + refType = 4; + }; + F51BF63002026E8D01000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Portuguese; + path = Portuguese.lproj/XDarwinHelp.html.cpp; + refType = 4; + }; + F5269C2D01D5BC3501000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = pseudoramiX.c; + refType = 4; + }; + F5269C2E01D5BC3501000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = pseudoramiX.h; + refType = 4; + }; + F53321390193CB6A01000001 = { + isa = PBXFileReference; + name = German; + path = German.lproj/MainMenu.nib; + refType = 4; + }; + F533213A0193CBA201000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = German; + path = German.lproj/InfoPlist.strings; + refType = 4; + }; + F533213B0193CBB401000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = German; + path = German.lproj/InfoPlist.strings.cpp; + refType = 4; + }; + F533213C0193CBC901000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = German; + path = German.lproj/Localizable.strings; + refType = 4; + }; + F533213D0193CBE001000001 = { + isa = PBXFileReference; + name = German; + path = German.lproj/Credits.rtf; + refType = 4; + }; + F533213E0193CBF401000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = German; + path = German.lproj/XDarwinHelp.html; + refType = 4; + }; + F533213F0193CC2501000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = German; + path = German.lproj/XDarwinHelp.html.cpp; + refType = 4; + }; + F53321400193CCF001000001 = { + isa = PBXFrameworkReference; + name = ApplicationServices.framework; + path = /System/Library/Frameworks/ApplicationServices.framework; + refType = 0; + }; + F53321410193CCF001000001 = { + isa = PBXFrameworkReference; + name = CoreAudio.framework; + path = /System/Library/Frameworks/CoreAudio.framework; + refType = 0; + }; + F533214201A4B3CE01000001 = { + isa = PBXFileReference; + name = Dutch; + path = Dutch.lproj/MainMenu.nib; + refType = 4; + }; + F533214301A4B3F001000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Dutch; + path = Dutch.lproj/InfoPlist.strings; + refType = 4; + }; + F533214401A4B40F01000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Dutch; + path = Dutch.lproj/InfoPlist.strings.cpp; + refType = 4; + }; + F533214501A4B42501000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Dutch; + path = Dutch.lproj/Localizable.strings; + refType = 4; + }; + F533214601A4B45401000001 = { + isa = PBXFileReference; + name = Dutch; + path = Dutch.lproj/Credits.rtf; + refType = 4; + }; + F533214701A4B48301000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Dutch; + path = Dutch.lproj/XDarwinHelp.html; + refType = 4; + }; + F533214801A4B4D701000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Dutch; + path = Dutch.lproj/XDarwinHelp.html.cpp; + refType = 4; + }; + F54BF6EA017D500901000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = startXClients.cpp; + refType = 4; + }; + F54BF6EC017D506E01000001 = { + isa = PBXFileReference; + path = startXClients; + refType = 4; + }; + F54BF6ED017D506E01000001 = { + fileRef = F54BF6EC017D506E01000001; + isa = PBXBuildFile; + settings = { + }; + }; + F5582948015DAD3B01000001 = { + fileEncoding = 30; + isa = PBXFileReference; + path = quartzCommon.h; + refType = 4; + }; + F5614B3B0251124C01000114 = { + fileEncoding = 30; + isa = PBXFileReference; + path = fullscreen.c; + refType = 4; + }; + F5614B3C0251124C01000114 = { + fileEncoding = 30; + isa = PBXFileReference; + path = fullscreen.h; + refType = 4; + }; + F5614B3D025112D901000114 = { + children = ( + F5614B3B0251124C01000114, + F5614B3C0251124C01000114, + ); + isa = PBXGroup; + name = "Full Screen"; + path = ""; + refType = 4; + }; + F56CBD0D02EB84A801129B8A = { + fileEncoding = 30; + isa = PBXFileReference; + path = aqua.h; + refType = 4; + }; + F56CBD0E02EB84A801129B8A = { + fileEncoding = 30; + isa = PBXFileReference; + path = aquaPicture.c; + refType = 4; + }; + F56CBD0F02EBDCFC01129B8A = { + fileEncoding = 30; + isa = PBXFileReference; + path = aquaWindow.c; + refType = 4; + }; + F587E16001924C1D01000001 = { + isa = PBXFileReference; + name = Swedish; + path = Swedish.lproj/MainMenu.nib; + refType = 4; + }; + F587E16101924C2F01000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Swedish; + path = Swedish.lproj/InfoPlist.strings; + refType = 4; + }; + F587E16201924C5301000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Swedish; + path = Swedish.lproj/InfoPlist.strings.cpp; + refType = 4; + }; + F587E16301924C5E01000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Swedish; + path = Swedish.lproj/Localizable.strings; + refType = 4; + }; + F587E16401924C6901000001 = { + isa = PBXFileReference; + name = Swedish; + path = Swedish.lproj/Credits.rtf; + refType = 4; + }; + F587E16501924C7401000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Swedish; + path = Swedish.lproj/XDarwinHelp.html; + refType = 4; + }; + F587E16601924C9D01000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Swedish; + path = Swedish.lproj/XDarwinHelp.html.cpp; + refType = 4; + }; + F58D65DB018F793801000001 = { + isa = PBXFileReference; + name = French; + path = French.lproj/MainMenu.nib; + refType = 4; + }; + F58D65DC018F794D01000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = French; + path = French.lproj/InfoPlist.strings.cpp; + refType = 4; + }; + F58D65DD018F798F01000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = French; + path = French.lproj/InfoPlist.strings; + refType = 4; + }; + F58D65DE018F79A001000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = French; + path = French.lproj/Localizable.strings; + refType = 4; + }; + F58D65DF018F79B101000001 = { + isa = PBXFileReference; + name = French; + path = French.lproj/Credits.rtf; + refType = 4; + }; + F58D65E0018F79C001000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = French; + path = French.lproj/XDarwinHelp.html; + refType = 4; + }; + F58D65E1018F79E001000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = French; + path = French.lproj/XDarwinHelp.html.cpp; + refType = 4; + }; + F5A94EF10314BAC70100011B = { + fileEncoding = 30; + isa = PBXFileReference; + path = darwinEvents.c; + refType = 4; + }; + F5ACD25CC5B5E96601000001 = { + isa = PBXFileReference; + name = Spanish; + path = Spanish.lproj/Credits.rtf; + refType = 4; + }; + F5ACD25DC5B5E97701000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Spanish; + path = Spanish.lproj/InfoPlist.strings.cpp; + refType = 4; + }; + F5ACD25EC5B5E98D01000001 = { + isa = PBXFileReference; + name = Spanish; + path = Spanish.lproj/MainMenu.nib; + refType = 4; + }; + F5ACD25FC5B5E9AA01000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Spanish; + path = Spanish.lproj/Localizable.strings; + refType = 4; + }; + F5ACD260C5B5E9DF01000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Spanish; + path = Spanish.lproj/XDarwinHelp.html.cpp; + refType = 4; + }; + F5ACD261C5B5EA2001000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Spanish; + path = Spanish.lproj/XDarwinHelp.html; + refType = 4; + }; + F5ACD262C5B5EA4D01000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = Spanish; + path = Spanish.lproj/InfoPlist.strings; + refType = 4; + }; + F5ACD263C5BE031F01000001 = { + isa = PBXFileReference; + name = ko; + path = ko.lproj/Credits.rtf; + refType = 4; + }; + F5ACD264C5BE035B01000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = ko; + path = ko.lproj/InfoPlist.strings.cpp; + refType = 4; + }; + F5ACD265C5BE038601000001 = { + isa = PBXFileReference; + name = ko; + path = ko.lproj/MainMenu.nib; + refType = 4; + }; + F5ACD266C5BE03C501000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = ko; + path = ko.lproj/Localizable.strings; + refType = 4; + }; + F5ACD267C5BE03FC01000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = ko; + path = ko.lproj/XDarwinHelp.html.cpp; + refType = 4; + }; + F5ACD268C5BE046401000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = ko; + path = ko.lproj/XDarwinHelp.html; + refType = 4; + }; + F5ACD269C5BE049301000001 = { + fileEncoding = 30; + isa = PBXFileReference; + name = ko; + path = ko.lproj/InfoPlist.strings; + refType = 4; + }; + }; + rootObject = 29B97313FDCFA39411CA2CEA; +} diff --git a/hw/darwin/quartz/XDarwinStartup.c b/hw/darwin/quartz/XDarwinStartup.c new file mode 100644 index 000000000..53343aa1e --- /dev/null +++ b/hw/darwin/quartz/XDarwinStartup.c @@ -0,0 +1,165 @@ +/************************************************************** + * + * Startup program for Darwin X servers + * + * This program selects the appropriate X server to launch: + * XDarwin IOKit X server (default) + * XDarwinQuartz A soft link to the Quartz X server + * executable (-quartz etc. option) + * + * If told to idle, the program will simply pause and not + * launch any X server. This is to support startx being + * run by XDarwin.app. + * + **************************************************************/ +/* + * Copyright (c) 2001-2002 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 + * TORREY T. LYONS 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 of Torrey T. Lyons shall not + * be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from + * Torrey T. Lyons. + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/XDarwinStartup.c,v 1.1 2002/03/28 02:21:18 torrey Exp $ */ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/syslimits.h> +#include <ApplicationServices/ApplicationServices.h> + +extern int errno; + +// Macros to build the path name +#ifndef XBINDIR +#define XBINDIR /usr/X11R6/bin +#endif +#define STR(s) #s +#define XSTRPATH(s) STR(s) "/" +#define XPATH(file) XSTRPATH(XBINDIR) STR(file) + +int main( + int argc, + char *argv[] ) +{ + int i, j, quartzMode = -1; + char **newargv; + + // Check if we are going to run in Quartz mode or idle + // to support startx from the Quartz server. The last + // parameter in the list is the one used. + for (i = argc-1; i; i--) { + if (!strcmp(argv[i], "-idle")) { + pause(); + return 0; + + } else if (!strcmp(argv[i], "-quartz") || + !strcmp(argv[i], "-rootless") || + !strcmp(argv[i], "-fullscreen")) + { + quartzMode = 1; + break; + + } else if (!strcmp(argv[i], "-iokit")) { + quartzMode = 0; + break; + } + } + + if (quartzMode == -1) { +#ifdef HAS_CG_MACH_PORT + // Check if the CoreGraphics window server is running. + // Mike Paquette says this is the fastest way to determine if it is running. + CFMachPortRef cgMachPortRef = CGWindowServerCFMachPort(); + if (cgMachPortRef == NULL) + quartzMode = 0; + else + quartzMode = 1; +#else + // On older systems we assume IOKit mode. + quartzMode = 0; +#endif + } + + if (quartzMode) { + // Launch the X server for the quartz modes + + char quartzPath[PATH_MAX+1]; + int pathLength; + OSStatus theStatus; + CFURLRef appURL; + CFStringRef appPath; + Boolean success; + + // Build the new argument list + newargv = (char **) malloc((argc+2) * sizeof(char *)); + for (j = argc; j; j--) + newargv[j] = argv[j]; + newargv[argc] = "-nostartx"; + newargv[argc+1] = NULL; + + // Use the XDarwinQuartz soft link if it is valid + pathLength = readlink(XPATH(XDarwinQuartz), quartzPath, PATH_MAX); + if (pathLength != -1) { + quartzPath[pathLength] = '\0'; + newargv[0] = quartzPath; + execv(newargv[0], newargv); + } + + // Otherwise query LaunchServices for the location of the XDarwin application + theStatus = LSFindApplicationForInfo(kLSUnknownCreator, + CFSTR("org.xfree86.XDarwin"), + NULL, NULL, &appURL); + if (theStatus) { + fprintf(stderr, "Could not find the XDarwin application. (Error = 0x%lx)\n", theStatus); + fprintf(stderr, "Launch XDarwin once from the Finder.\n"); + return theStatus; + } + + appPath = CFURLCopyFileSystemPath (appURL, kCFURLPOSIXPathStyle); + success = CFStringGetCString(appPath, quartzPath, PATH_MAX, CFStringGetSystemEncoding()); + if (! success) { + fprintf(stderr, "Could not find path to XDarwin application.\n"); + return success; + } + + // Launch the XDarwin application + strncat(quartzPath, "/Contents/MacOS/XDarwin", PATH_MAX); + newargv[0] = quartzPath; + execv(newargv[0], newargv); + fprintf(stderr, "Could not start XDarwin application at %s.\n", newargv[0]); + return errno; + + } else { + + // Build the new argument list + newargv = (char **) malloc((argc+1) * sizeof(char *)); + for (j = argc; j; j--) + newargv[j] = argv[j]; + newargv[0] = "XDarwin"; + newargv[argc] = NULL; + + // Launch the IOKit X server + execvp(newargv[0], newargv); + fprintf(stderr, "Could not start XDarwin IOKit X server.\n"); + return errno; + } +} diff --git a/hw/darwin/quartz/XDarwinStartup.man b/hw/darwin/quartz/XDarwinStartup.man new file mode 100644 index 000000000..312f4b88b --- /dev/null +++ b/hw/darwin/quartz/XDarwinStartup.man @@ -0,0 +1,75 @@ +.\" $XFree86: xc/programs/Xserver/hw/darwin/quartz/XDarwinStartup.man,v 1.1 2002/03/28 02:21:18 torrey Exp $ +.TH XDarwinStartup 1 +.SH NAME +XDarwinStartup - Startup program for the XDarwin X window server +.SH SYNOPSIS +.B XDarwinStartup +[\fI-iokit\fP] +[\fI-fullscreen\fP] +[\fI-rootless\fP] +[\fI-quartz\fP] +[\fI-idle\fP] +[\fIoptions\fP] +.SH DESCRIPTION +The \fIXDarwin(1)\fP X window server can be run in a variety of different +modes and is actually two different executables. The IOKit X server, +XDarwin, is used when running from the console. It is most commonly +located in __XBinDir__. The Quartz X server, for running in parallel with +Aqua, is a full-fledged Mac OS X application that can be started from +the Finder. Its application bundle is XDarwin.app, which is typically +located in /Applications. +.I XDarwinStartup +allows easy switching between these X servers and auto-detection of the +appropriate one to use when launching from the command line. +When run without any arguments, +.I XDarwinStartup +will start the Quartz X server if the Core Graphics window server +is currently running. Otherwise it will start the IOKit X server. +.PP +To locate the Quartz X server, +.I XDarwinStartup +will try to read the soft link at __XBinDir__/XDarwinQuartz. +This is typically a soft link to the executable of the XDarwin.app +application. If this fails, +.I XDarwinStartup +will call Launch Services to locate XDarwin.app. +.PP +To start the IOKit X server, +.I XDarwinStartup +will run the XDarwin execuatable, which should be present in the +user's path. +.SH OPTIONS +.I XDarwinStartup +accepts and passes on all options to the X server it +launches. In addition the following options have specific effects: +.TP 8 +.B \-iokit +Launch the IOKit X server. +.TP 8 +.B \-fullscreen +Launch the Quartz X server to run in full screen mode. +.TP 8 +.B \-rootless +Launch the Quartz X server to run in rootless mode. +.TP 8 +.B \-quartz +Launch the Quartz X server. +.TP 8 +.B \-idle +Pause and do nothing. This option is used by XDarwin.app when it is +started from the Finder. +.SH FILES +.TP 30 +__XBinDir__/XDarwin +IOKit mode X server +.TP 30 +/Applications/XDarwin.app +Quartz mode X server +.TP 30 +__XBinDir__/XDarwinQuartz +Soft link to Quartz mode X server executable +.SH SEE ALSO +XDarwin(1) +.SH BUGS +The path to XDarwinQuartz should not be hard coded. + diff --git a/hw/darwin/quartz/XServer.h b/hw/darwin/quartz/XServer.h new file mode 100644 index 000000000..3eadd650e --- /dev/null +++ b/hw/darwin/quartz/XServer.h @@ -0,0 +1,112 @@ +// +// XServer.h +// +/* + * Copyright (c) 2001 Andreas Monitzer. All Rights Reserved. + * Copyright (c) 2002-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. + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/XServer.h,v 1.8 2003/01/23 00:34:26 torrey Exp $ */ + +#define BOOL xBOOL +#include "Xproto.h" +#undef BOOL + +#import <Cocoa/Cocoa.h> + +@interface XServer : NSObject { + // server state + int serverState; + NSRecursiveLock *serverLock; + BOOL serverVisible; + BOOL rootlessMenuBarVisible; + BOOL queueShowServer; + UInt32 mouseState; + Class windowClass; + + // server event queue + BOOL sendServerEvents; + int eventWriteFD; + + // Aqua interface + IBOutlet NSWindow *modeWindow; + IBOutlet NSButton *startupModeButton; + IBOutlet NSButton *startFullScreenButton; + IBOutlet NSButton *startRootlessButton; + IBOutlet NSWindow *helpWindow; + IBOutlet NSButton *startupHelpButton; + IBOutlet NSPanel *switchWindow; +} + +- (id)init; + +- (BOOL)translateEvent:(NSEvent *)anEvent; +- (BOOL)getMousePosition:(xEvent *)xe fromEvent:(NSEvent *)anEvent; + ++ (void)append:(NSString *)value toEnv:(NSString *)name; + +- (void)startX; +- (void)finishStartX; +- (BOOL)startXClients; +- (void)run; +- (void)toggle; +- (void)showServer:(BOOL)show; +- (void)forceShowServer:(BOOL)show; +- (void)setRootClip:(BOOL)enable; +- (void)readPasteboard; +- (void)writePasteboard; +- (void)quitServer; +- (void)sendXEvent:(xEvent *)xe; +- (void)sendShowHide:(BOOL)show; +- (void)clientProcessDone:(int)clientStatus; + +// Aqua interface actions +- (IBAction)startFullScreen:(id)sender; +- (IBAction)startRootless:(id)sender; +- (IBAction)closeHelpAndShow:(id)sender; +- (IBAction)showAction:(id)sender; + +// NSApplication delegate +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification; +- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag; +- (void)applicationWillResignActive:(NSNotification *)aNotification; +- (void)applicationWillBecomeActive:(NSNotification *)aNotification; + +// NSPort delegate +- (void)handlePortMessage:(NSPortMessage *)portMessage; + +@end + +// X server states +enum { + server_NotStarted, + server_Starting, + server_Running, + server_Quitting, + server_Done +}; + diff --git a/hw/darwin/quartz/XServer.m b/hw/darwin/quartz/XServer.m new file mode 100644 index 000000000..c57defd53 --- /dev/null +++ b/hw/darwin/quartz/XServer.m @@ -0,0 +1,1029 @@ +// +// XServer.m +// +// This class handles the interaction between the Cocoa front-end +// and the Darwin X server thread. +// +// Created by Andreas Monitzer on January 6, 2001. +// +/* + * Copyright (c) 2001 Andreas Monitzer. All Rights Reserved. + * Copyright (c) 2002-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. + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/XServer.m,v 1.8 2003/01/23 00:34:26 torrey Exp $ */ + +#include "quartzCommon.h" + +#define BOOL xBOOL +#include "X.h" +#include "Xproto.h" +#include "os.h" +#include "darwin.h" +#undef BOOL + +#import "XServer.h" +#import "Preferences.h" + +#include <unistd.h> +#include <stdio.h> +#include <sys/syslimits.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <pwd.h> +#include <signal.h> +#include <fcntl.h> + +// For power management notifications +#import <mach/mach_port.h> +#import <mach/mach_interface.h> +#import <mach/mach_init.h> +#import <IOKit/pwr_mgt/IOPMLib.h> +#import <IOKit/IOMessage.h> + +#define ENQUEUE(xe) \ +{ \ + char byte = 0; \ + DarwinEQEnqueue(xe); \ + /* signal there is an event ready to handle */ \ + write(eventWriteFD, &byte, 1); \ +} + +// Types of shells +enum { + shell_Unknown, + shell_Bourne, + shell_C +}; + +typedef struct { + char *name; + int type; +} shellList_t; + +static shellList_t const shellList[] = { + { "csh", shell_C }, // standard C shell + { "tcsh", shell_C }, // ... needs no introduction + { "sh", shell_Bourne }, // standard Bourne shell + { "zsh", shell_Bourne }, // Z shell + { "bash", shell_Bourne }, // GNU Bourne again shell + { NULL, shell_Unknown } +}; + +extern int argcGlobal; +extern char **argvGlobal; +extern char **envpGlobal; +extern int main(int argc, char *argv[], char *envp[]); +extern void HideMenuBar(void); +extern void ShowMenuBar(void); +extern void QuartzReallySetCursor(); +static void childDone(int sig); +static void powerDidChange(void *x, io_service_t y, natural_t messageType, + void *messageArgument); + +static NSPort *signalPort; +static NSPort *returnPort; +static NSPortMessage *signalMessage; +static pid_t clientPID; +static XServer *oneXServer; +static NSRect aquaMenuBarBox; +static io_connect_t root_port; + + +@implementation XServer + +- (id)init +{ + self = [super init]; + oneXServer = self; + + serverState = server_NotStarted; + serverLock = [[NSRecursiveLock alloc] init]; + clientPID = 0; + sendServerEvents = NO; + serverVisible = NO; + rootlessMenuBarVisible = YES; + queueShowServer = YES; + quartzServerQuitting = NO; + mouseState = 0; + eventWriteFD = quartzEventWriteFD; + windowClass = [NSWindow class]; + + // set up a port to safely send messages to main thread from server thread + signalPort = [[NSPort port] retain]; + returnPort = [[NSPort port] retain]; + signalMessage = [[NSPortMessage alloc] initWithSendPort:signalPort + receivePort:returnPort components:nil]; + + // set up receiving end + [signalPort setDelegate:self]; + [[NSRunLoop currentRunLoop] addPort:signalPort + forMode:NSDefaultRunLoopMode]; + [[NSRunLoop currentRunLoop] addPort:signalPort + forMode:NSModalPanelRunLoopMode]; + + return self; +} + +- (NSApplicationTerminateReply) + applicationShouldTerminate:(NSApplication *)sender +{ + // Quit if the X server is not running + if ([serverLock tryLock]) { + quartzServerQuitting = YES; + serverState = server_Done; + if (clientPID != 0) + kill(clientPID, SIGINT); + return NSTerminateNow; + } + + // Hide the X server and stop sending it events + [self showServer:NO]; + sendServerEvents = NO; + + if (clientPID != 0 || !quartzStartClients) { + int but; + + but = NSRunAlertPanel(NSLocalizedString(@"Quit X server?",@""), + NSLocalizedString(@"Quitting the X server will terminate any running X Window System programs.",@""), + NSLocalizedString(@"Quit",@""), + NSLocalizedString(@"Cancel",@""), + nil); + + switch (but) { + case NSAlertDefaultReturn: // quit + break; + case NSAlertAlternateReturn: // cancel + if (serverState == server_Running) + sendServerEvents = YES; + return NSTerminateCancel; + } + } + + quartzServerQuitting = YES; + if (clientPID != 0) + kill(clientPID, SIGINT); + + // At this point the X server is either running or starting. + if (serverState == server_Starting) { + // Quit will be queued later when server is running + return NSTerminateLater; + } else if (serverState == server_Running) { + [self quitServer]; + } + + return NSTerminateNow; +} + +// Ensure that everything has quit cleanly +- (void)applicationWillTerminate:(NSNotification *)aNotification +{ + // Make sure the client process has finished + if (clientPID != 0) { + NSLog(@"Waiting on client process..."); + sleep(2); + + // If the client process hasn't finished yet, kill it off + if (clientPID != 0) { + int clientStatus; + NSLog(@"Killing client process..."); + killpg(clientPID, SIGKILL); + waitpid(clientPID, &clientStatus, 0); + } + } + + // Wait until the X server thread quits + [serverLock lock]; +} + +// returns YES when event was handled +- (BOOL)translateEvent:(NSEvent *)anEvent +{ + xEvent xe; + static BOOL mouse1Pressed = NO; + NSEventType type; + unsigned int flags; + + if (!sendServerEvents) { + return NO; + } + + type = [anEvent type]; + flags = [anEvent modifierFlags]; + + if (!quartzRootless) { + // Check for switch keypress + if ((type == NSKeyDown) && (![anEvent isARepeat]) && + ([anEvent keyCode] == [Preferences keyCode])) + { + unsigned int switchFlags = [Preferences modifiers]; + + // Switch if all the switch modifiers are pressed, while none are + // pressed that should not be, except for caps lock. + if (((flags & switchFlags) == switchFlags) && + ((flags & ~(switchFlags | NSAlphaShiftKeyMask)) == 0)) + { + [self toggle]; + return YES; + } + } + + if (!serverVisible) + return NO; + } + + memset(&xe, 0, sizeof(xe)); + + switch (type) { + case NSLeftMouseUp: + [self getMousePosition:&xe fromEvent:anEvent]; + if (quartzRootless && !mouse1Pressed) { + // MouseUp after MouseDown in menu - ignore + return NO; + } + mouse1Pressed = NO; + xe.u.u.type = ButtonRelease; + xe.u.u.detail = 1; + break; + case NSLeftMouseDown: + [self getMousePosition:&xe fromEvent:anEvent]; + if (quartzRootless && + ! ([anEvent window] && + [[anEvent window] isKindOfClass:windowClass])) { + // Click in non X window - ignore + return NO; + } + mouse1Pressed = YES; + xe.u.u.type = ButtonPress; + xe.u.u.detail = 1; + break; + case NSMouseMoved: + case NSLeftMouseDragged: + case NSRightMouseDragged: + case NSOtherMouseDragged: + [self getMousePosition:&xe fromEvent:anEvent]; + xe.u.u.type = MotionNotify; + break; + case NSSystemDefined: + { + long hwButtons = [anEvent data2]; + + if (![anEvent subtype]==7) + return NO; // we only use multibutton mouse events + if (mouseState == hwButtons) + return NO; // ignore double events + mouseState = hwButtons; + + [self getMousePosition:&xe fromEvent:anEvent]; + xe.u.u.type = kXDarwinUpdateButtons; + xe.u.clientMessage.u.l.longs0 = [anEvent data1]; + xe.u.clientMessage.u.l.longs1 =[anEvent data2]; + break; + } + case NSScrollWheel: + [self getMousePosition:&xe fromEvent:anEvent]; + xe.u.u.type = kXDarwinScrollWheel; + xe.u.clientMessage.u.s.shorts0 = [anEvent deltaY]; + break; + case NSKeyDown: + case NSKeyUp: + // If the mouse is not on the valid X display area, + // we don't send the X server key events. + if (![self getMousePosition:&xe fromEvent:nil]) + return NO; + if (type == NSKeyDown) + xe.u.u.type = KeyPress; + else + xe.u.u.type = KeyRelease; + xe.u.u.detail = [anEvent keyCode]; + break; + case NSFlagsChanged: + [self getMousePosition:&xe fromEvent:nil]; + xe.u.u.type = kXDarwinUpdateModifiers; + xe.u.clientMessage.u.l.longs0 = flags; + break; + case NSOtherMouseDown: // undocumented MouseDown + case NSOtherMouseUp: // undocumented MouseUp + // Hide these from AppKit to avoid its log messages + return YES; + default: + return NO; + } + + [self sendXEvent:&xe]; + + // Rootless: Send first NSLeftMouseDown to windows and views so window + // ordering can be suppressed. + // Don't pass further events - they (incorrectly?) bring the window + // forward no matter what. + if (quartzRootless && + (type == NSLeftMouseDown || type == NSLeftMouseUp) && + [anEvent clickCount] == 1 && + [[anEvent window] isKindOfClass:windowClass]) + { + return NO; + } + + return YES; +} + +// Return mouse coordinates, inverting y coordinate. +// The coordinates are extracted from an event or the current mouse position. +// For rootless mode, the menu bar is treated as not part of the usable +// X display area and the cursor position is adjusted accordingly. +// Returns YES if the cursor is not in the menu bar. +- (BOOL)getMousePosition:(xEvent *)xe fromEvent:(NSEvent *)anEvent +{ + NSPoint pt; + + if (anEvent) { + NSWindow *eventWindow = [anEvent window]; + + if (eventWindow) { + pt = [anEvent locationInWindow]; + pt.x += [eventWindow frame].origin.x; + pt.y += [eventWindow frame].origin.y; + } else { + pt = [NSEvent mouseLocation]; + } + } else { + pt = [NSEvent mouseLocation]; + } + + xe->u.keyButtonPointer.rootX = (int)(pt.x); + + if (quartzRootless && NSMouseInRect(pt, aquaMenuBarBox, NO)) { + // mouse in menu bar - tell X11 that it's just below instead + xe->u.keyButtonPointer.rootY = aquaMenuBarHeight; + return NO; + } else { + xe->u.keyButtonPointer.rootY = + NSHeight([[NSScreen mainScreen] frame]) - (int)(pt.y); + return YES; + } +} + +// Append a string to the given enviroment variable ++ (void)append:(NSString*)value toEnv:(NSString*)name +{ + setenv([name cString], + [[[NSString stringWithCString:getenv([name cString])] + stringByAppendingString:value] cString],1); +} + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification +{ + // Block SIGPIPE + // SIGPIPE repeatably killed the (rootless) server when closing a + // dozen xterms in rapid succession. Those SIGPIPEs should have been + // sent to the X server thread, which ignores them, but somehow they + // ended up in this thread instead. + { + sigset_t set; + sigemptyset(&set); + sigaddset(&set, SIGPIPE); + // pthread_sigmask not implemented yet + // pthread_sigmask(SIG_BLOCK, &set, NULL); + sigprocmask(SIG_BLOCK, &set, NULL); + } + + if (quartzRootless == -1) { + // The display mode was not set from the command line. + // Show mode pick panel? + if ([Preferences modeWindow]) { + if ([Preferences rootless]) + [startRootlessButton setKeyEquivalent:@"\r"]; + else + [startFullScreenButton setKeyEquivalent:@"\r"]; + [modeWindow makeKeyAndOrderFront:nil]; + } else { + // Otherwise use default mode + quartzRootless = [Preferences rootless]; + [self startX]; + } + } else { + [self startX]; + } +} + +// Start the X server thread and the client process +- (void)startX +{ + NSDictionary *appDictionary; + NSString *appVersion; + + [modeWindow close]; + + // Calculate the height of the menu bar so rootless mode can avoid it + if (quartzRootless) { + aquaMenuBarHeight = NSHeight([[NSScreen mainScreen] frame]) - + NSMaxY([[NSScreen mainScreen] visibleFrame]) - 1; + aquaMenuBarBox = + NSMakeRect(0, NSMaxY([[NSScreen mainScreen] visibleFrame]) + 1, + NSWidth([[NSScreen mainScreen] frame]), + aquaMenuBarHeight); + } + + // Write the XDarwin version to the console log + appDictionary = [[NSBundle mainBundle] infoDictionary]; + appVersion = [appDictionary objectForKey:@"CFBundleShortVersionString"]; + if (appVersion) + NSLog(@"\n%@", appVersion); + else + NSLog(@"No version"); + + // Start the X server thread + serverState = server_Starting; + [NSThread detachNewThreadSelector:@selector(run) toTarget:self + withObject:nil]; + + // Start the X clients if started from GUI + if (quartzStartClients) { + [self startXClients]; + } + + if (quartzRootless) { + // There is no help window for rootless; just start + [helpWindow close]; + helpWindow = nil; + } else { + IONotificationPortRef notify; + io_object_t anIterator; + + // Register for system power notifications + root_port = IORegisterForSystemPower(0, ¬ify, powerDidChange, + &anIterator); + if (root_port) { + CFRunLoopAddSource([[NSRunLoop currentRunLoop] getCFRunLoop], + IONotificationPortGetRunLoopSource(notify), + kCFRunLoopDefaultMode); + } else { + NSLog(@"Failed to register for system power notifications."); + } + + // Show the X switch window if not using dock icon switching + if (![Preferences dockSwitch]) + [switchWindow orderFront:nil]; + + if ([Preferences startupHelp]) { + // display the full screen mode help + [helpWindow makeKeyAndOrderFront:nil]; + queueShowServer = NO; + } else { + // start running full screen and make sure X is visible + ShowMenuBar(); + [self closeHelpAndShow:nil]; + } + } +} + +// Finish starting the X server thread +// This includes anything that must be done after the X server is +// ready to process events. +- (void)finishStartX +{ + sendServerEvents = YES; + serverState = server_Running; + + if (quartzRootless) { + [self forceShowServer:[NSApp isActive]]; + } else { + [self forceShowServer:queueShowServer]; + } + + if (quartzServerQuitting) { + [self quitServer]; + [NSApp replyToApplicationShouldTerminate:YES]; + } +} + +// Start the first X clients in a separate process +- (BOOL)startXClients +{ + struct passwd *passwdUser; + NSString *shellPath, *dashShellName, *commandStr, *startXPath; + NSMutableString *safeStartXPath; + NSRange aRange; + NSBundle *thisBundle; + const char *shellPathStr, *newargv[3], *shellNameStr; + int fd[2], outFD, length, shellType, i; + + // Register to catch the signal when the client processs finishes + signal(SIGCHLD, childDone); + + // Get user's password database entry + passwdUser = getpwuid(getuid()); + + // Find the shell to use + if ([Preferences useDefaultShell]) + shellPath = [NSString stringWithCString:passwdUser->pw_shell]; + else + shellPath = [Preferences shellString]; + + dashShellName = [NSString stringWithFormat:@"-%@", + [shellPath lastPathComponent]]; + shellPathStr = [shellPath cString]; + shellNameStr = [[shellPath lastPathComponent] cString]; + + if (access(shellPathStr, X_OK)) { + NSLog(@"Shell %s is not valid!", shellPathStr); + return NO; + } + + // Find the type of shell + for (i = 0; shellList[i].name; i++) { + if (!strcmp(shellNameStr, shellList[i].name)) + break; + } + shellType = shellList[i].type; + + newargv[0] = [dashShellName cString]; + if (shellType == shell_Bourne) { + // Bourne shells need to be told they are interactive to make + // sure they read all their initialization files. + newargv[1] = "-i"; + newargv[2] = NULL; + } else { + newargv[1] = NULL; + } + + // Create a pipe to communicate with the X client process + NSAssert(pipe(fd) == 0, @"Could not create new pipe."); + + // Open a file descriptor for writing to stdout and stderr + outFD = open("/dev/console", O_WRONLY, 0); + if (outFD == -1) { + outFD = open("/dev/null", O_WRONLY, 0); + NSAssert(outFD != -1, @"Could not open shell output."); + } + + // Fork process to start X clients in user's default shell + // Sadly we can't use NSTask because we need to start a login shell. + // Login shells are started by passing "-" as the first character of + // argument 0. NSTask forces argument 0 to be the shell's name. + clientPID = vfork(); + if (clientPID == 0) { + + // Inside the new process: + if (fd[0] != STDIN_FILENO) { + dup2(fd[0], STDIN_FILENO); // Take stdin from pipe + close(fd[0]); + } + close(fd[1]); // Close write end of pipe + if (outFD == STDOUT_FILENO) { // Setup stdout and stderr + dup2(outFD, STDERR_FILENO); + } else if (outFD == STDERR_FILENO) { + dup2(outFD, STDOUT_FILENO); + } else { + dup2(outFD, STDERR_FILENO); + dup2(outFD, STDOUT_FILENO); + close(outFD); + } + + // Setup environment + setenv("HOME", passwdUser->pw_dir, 1); + setenv("SHELL", shellPathStr, 1); + setenv("LOGNAME", passwdUser->pw_name, 1); + setenv("USER", passwdUser->pw_name, 1); + setenv("TERM", "unknown", 1); + if (chdir(passwdUser->pw_dir)) // Change to user's home dir + NSLog(@"Could not change to user's home directory."); + + execv(shellPathStr, (char * const *)newargv); // Start user's shell + + NSLog(@"Could not start X client process with errno = %i.", errno); + _exit(127); + } + + // In parent process: + close(fd[0]); // Close read end of pipe + close(outFD); // Close output file descriptor + + thisBundle = [NSBundle bundleForClass:[self class]]; + startXPath = [thisBundle pathForResource:@"startXClients" ofType:nil]; + if (!startXPath) { + NSLog(@"Could not find startXClients in application bundle!"); + return NO; + } + + // We will run the startXClients script with the path in single quotes + // in case there are problematic characters in the path. We still have + // to worry about there being single quotes in the path. So, replace + // all instances of the ' character in startXPath with '\''. + safeStartXPath = [NSMutableString stringWithString:startXPath]; + aRange = NSMakeRange(0, [safeStartXPath length]); + while (aRange.length) { + aRange = [safeStartXPath rangeOfString:@"'" options:0 range:aRange]; + if (!aRange.length) + break; + [safeStartXPath replaceCharactersInRange:aRange + withString:@"\'\\'\'"]; + aRange.location += 4; + aRange.length = [safeStartXPath length] - aRange.location; + } + + if ([Preferences addToPath]) { + commandStr = [NSString stringWithFormat:@"'%@' :%d %@\n", + safeStartXPath, [Preferences display], + [Preferences addToPathString]]; + } else { + commandStr = [NSString stringWithFormat:@"'%@' :%d\n", + safeStartXPath, [Preferences display]]; + } + + length = [commandStr cStringLength]; + if (write(fd[1], [commandStr cString], length) != length) { + NSLog(@"Write to X client process failed."); + return NO; + } + + // Close the pipe so that shell will terminate when xinit quits + close(fd[1]); + + return YES; +} + +// Run the X server thread +- (void)run +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + [serverLock lock]; + main(argcGlobal, argvGlobal, envpGlobal); + serverVisible = NO; + [pool release]; + [serverLock unlock]; + QuartzMessageMainThread(kQuartzServerDied, nil, 0); +} + +// Full screen mode was picked in the mode pick panel +- (IBAction)startFullScreen:(id)sender +{ + [Preferences setModeWindow:[startupModeButton intValue]]; + [Preferences saveToDisk]; + quartzRootless = FALSE; + [self startX]; +} + +// Rootless mode was picked in the mode pick panel +- (IBAction)startRootless:(id)sender +{ + [Preferences setModeWindow:[startupModeButton intValue]]; + [Preferences saveToDisk]; + quartzRootless = TRUE; + [self startX]; +} + +// Close the help splash screen and show the X server +- (IBAction)closeHelpAndShow:(id)sender +{ + if (sender) { + int helpVal = [startupHelpButton intValue]; + [Preferences setStartupHelp:helpVal]; + [Preferences saveToDisk]; + } + [helpWindow close]; + helpWindow = nil; + + [self forceShowServer:YES]; + [NSApp activateIgnoringOtherApps:YES]; +} + +// Show the X server when sent message from GUI +- (IBAction)showAction:(id)sender +{ + [self forceShowServer:YES]; +} + +// Show or hide the X server or menu bar in rootless mode +- (void)toggle +{ + if (quartzRootless) { +#if 0 + // FIXME: Remove or add option to not dodge menubar + if (rootlessMenuBarVisible) + HideMenuBar(); + else + ShowMenuBar(); + rootlessMenuBarVisible = !rootlessMenuBarVisible; +#endif + } else { + [self showServer:!serverVisible]; + } +} + +// Show or hide the X server on screen +- (void)showServer:(BOOL)show +{ + // Do not show or hide multiple times in a row + if (serverVisible == show) + return; + + if (sendServerEvents) { + [self sendShowHide:show]; + } else if (serverState == server_Starting) { + queueShowServer = show; + } +} + +// Show or hide the X server irregardless of the current state +- (void)forceShowServer:(BOOL)show +{ + serverVisible = !show; + [self showServer:show]; +} + +// Tell the X server to show or hide itself. +// This ignores the current X server visible state. +// +// In full screen mode, the order we do things is important and must be +// preserved between the threads. X drawing operations have to be performed +// in the X server thread. It appears that we have the additional +// constraint that we must hide and show the menu bar in the main thread. +// +// To show the X server: +// 1. Capture the displays. (Main thread) +// 2. Hide the menu bar. (Must be in main thread) +// 3. Send event to X server thread to redraw X screen. +// 4. Redraw the X screen. (Must be in X server thread) +// +// To hide the X server: +// 1. Send event to X server thread to stop drawing. +// 2. Stop drawing to the X screen. (Must be in X server thread) +// 3. Message main thread that drawing is stopped. +// 4. If main thread still wants X server hidden: +// a. Release the displays. (Main thread) +// b. Unhide the menu bar. (Must be in main thread) +// Otherwise we have already queued an event to start drawing again. +// +- (void)sendShowHide:(BOOL)show +{ + xEvent xe; + + [self getMousePosition:&xe fromEvent:nil]; + + if (show) { + if (!quartzRootless) { + QuartzFSCapture(); + HideMenuBar(); + } + xe.u.u.type = kXDarwinShow; + [self sendXEvent:&xe]; + + // the mouse location will have moved; track it + xe.u.u.type = MotionNotify; + [self sendXEvent:&xe]; + + // inform the X server of the current modifier state + xe.u.u.type = kXDarwinUpdateModifiers; + xe.u.clientMessage.u.l.longs0 = [[NSApp currentEvent] modifierFlags]; + [self sendXEvent:&xe]; + + // put the pasteboard into the X cut buffer + [self readPasteboard]; + } else { + // put the X cut buffer on the pasteboard + [self writePasteboard]; + + xe.u.u.type = kXDarwinHide; + [self sendXEvent:&xe]; + } + + serverVisible = show; +} + +// Enable or disable rendering to the X screen +- (void)setRootClip:(BOOL)enable +{ + xEvent xe; + + xe.u.u.type = kXDarwinSetRootClip; + xe.u.clientMessage.u.l.longs0 = enable; + [self sendXEvent:&xe]; +} + +// Tell the X server to read from the pasteboard into the X cut buffer +- (void)readPasteboard +{ + xEvent xe; + + xe.u.u.type = kXDarwinReadPasteboard; + [self sendXEvent:&xe]; +} + +// Tell the X server to write the X cut buffer into the pasteboard +- (void)writePasteboard +{ + xEvent xe; + + xe.u.u.type = kXDarwinWritePasteboard; + [self sendXEvent:&xe]; +} + +- (void)quitServer +{ + xEvent xe; + + xe.u.u.type = kXDarwinQuit; + [self sendXEvent:&xe]; + + // Revert to the Mac OS X arrow cursor. The main thread sets the cursor + // and it won't be responding to future requests to change it. + [[NSCursor arrowCursor] set]; + + serverState = server_Quitting; +} + +- (void)sendXEvent:(xEvent *)xe +{ + // This field should be filled in for every event + xe->u.keyButtonPointer.time = GetTimeInMillis(); + +#if 0 + // FIXME: Really? + if (quartzRootless && + (ev->type == NSLeftMouseDown || ev->type == NSLeftMouseUp || + (ev->type == NSSystemDefined && ev->data.compound.subType == 7))) + { + // mouse button event - send mouseMoved to this position too + // X gets confused if it gets a click that isn't at the last + // reported mouse position. + xEvent moveEvent = *ev; + xe.u.u.type = NSMouseMoved; + [self sendXEvent:&moveEvent]; + } +#endif + + ENQUEUE(xe); +} + +// Handle messages from the X server thread +- (void)handlePortMessage:(NSPortMessage *)portMessage +{ + unsigned msg = [portMessage msgid]; + + switch(msg) { + case kQuartzServerHidden: + // Make sure the X server wasn't queued to be shown again while + // the hide was pending. + if (!quartzRootless && !serverVisible) { + QuartzFSRelease(); + ShowMenuBar(); + } + break; + + case kQuartzServerStarted: + [self finishStartX]; + break; + + case kQuartzServerDied: + sendServerEvents = NO; + serverState = server_Done; + if (!quartzServerQuitting) { + [NSApp terminate:nil]; // quit if we aren't already + } + break; + + case kQuartzCursorUpdate: + QuartzReallySetCursor(); + break; + + case kQuartzPostEvent: + { + const xEvent *xe = [[[portMessage components] lastObject] bytes]; + ENQUEUE(xe); + break; + } + + default: + NSLog(@"Unknown message from server thread."); + } +} + +// Quit the X server when the X client process finishes +- (void)clientProcessDone:(int)clientStatus +{ + if (WIFEXITED(clientStatus)) { + int exitStatus = WEXITSTATUS(clientStatus); + if (exitStatus != 0) + NSLog(@"X client process terminated with status %i.", exitStatus); + } else { + NSLog(@"X client process terminated abnormally."); + } + + if (!quartzServerQuitting) { + [NSApp terminate:nil]; // quit if we aren't already + } +} + +// Called when the user clicks the application icon, +// but not when Cmd-Tab is used. +// Rootless: Don't switch until applicationWillBecomeActive. +- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication + hasVisibleWindows:(BOOL)flag +{ + if ([Preferences dockSwitch] && !quartzRootless) { + [self showServer:YES]; + } + return NO; +} + +- (void)applicationWillResignActive:(NSNotification *)aNotification +{ + [self showServer:NO]; +} + +- (void)applicationWillBecomeActive:(NSNotification *)aNotification +{ + if (quartzRootless) + [self showServer:YES]; +} + +@end + + +// Send a message to the main thread, which calls handlePortMessage in +// response. Must only be called from the X server thread because +// NSPort is not thread safe. +void QuartzMessageMainThread(unsigned msg, void *data, unsigned length) +{ + if (msg == kQuartzPostEvent) { + NSData *eventData = [NSData dataWithBytes:data length:length]; + NSArray *eventArray = [NSArray arrayWithObject:eventData]; + NSPortMessage *newMessage = + [[NSPortMessage alloc] + initWithSendPort:signalPort + receivePort:returnPort components:eventArray]; + [newMessage setMsgid:msg]; + [newMessage sendBeforeDate:[NSDate distantPast]]; + [newMessage release]; + } else { + [signalMessage setMsgid:msg]; + [signalMessage sendBeforeDate:[NSDate distantPast]]; + } +} + +// Handle SIGCHLD signals +static void childDone(int sig) +{ + int clientStatus; + + if (clientPID == 0) + return; + + // Make sure it was the client task that finished + if (waitpid(clientPID, &clientStatus, WNOHANG) == clientPID) { + if (WIFSTOPPED(clientStatus)) + return; + clientPID = 0; + [oneXServer clientProcessDone:clientStatus]; + } +} + +static void powerDidChange( + void *x, + io_service_t y, + natural_t messageType, + void *messageArgument) +{ + switch (messageType) { + case kIOMessageSystemWillSleep: + if (!quartzRootless) { + [oneXServer setRootClip:FALSE]; + } + IOAllowPowerChange(root_port, (long)messageArgument); + break; + case kIOMessageCanSystemSleep: + IOAllowPowerChange(root_port, (long)messageArgument); + break; + case kIOMessageSystemHasPoweredOn: + if (!quartzRootless) { + [oneXServer setRootClip:TRUE]; + } + break; + } + +} diff --git a/hw/darwin/quartz/pseudoramiX.c b/hw/darwin/quartz/pseudoramiX.c new file mode 100644 index 000000000..e55aabd6f --- /dev/null +++ b/hw/darwin/quartz/pseudoramiX.c @@ -0,0 +1,420 @@ +/* + * Minimal implementation of PanoramiX/Xinerama + * + * This is used in rootless mode where the underlying window server + * already provides an abstracted view of multiple screens as one + * large screen area. + * + * This code is largely based on panoramiX.c, which contains the + * following copyright notice: + */ +/***************************************************************** +Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. +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. + +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 +DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, +BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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 of Digital Equipment Corporation +shall not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from Digital +Equipment Corporation. +******************************************************************/ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/pseudoramiX.c,v 1.2 2002/10/16 21:13:33 dawes Exp $ */ + +#include "pseudoramiX.h" + +#include "extnsionst.h" +#include "dixstruct.h" +#include "window.h" +#include "panoramiXproto.h" +#include "globals.h" + +extern int ProcPanoramiXQueryVersion (ClientPtr client); + +static void PseudoramiXResetProc(ExtensionEntry *extEntry); + +static int ProcPseudoramiXQueryVersion(ClientPtr client); +static int ProcPseudoramiXGetState(ClientPtr client); +static int ProcPseudoramiXGetScreenCount(ClientPtr client); +static int ProcPseudoramiXGetScreenSize(ClientPtr client); +static int ProcPseudoramiXIsActive(ClientPtr client); +static int ProcPseudoramiXQueryScreens(ClientPtr client); +static int ProcPseudoramiXDispatch(ClientPtr client); + +static int SProcPseudoramiXQueryVersion(ClientPtr client); +static int SProcPseudoramiXGetState(ClientPtr client); +static int SProcPseudoramiXGetScreenCount(ClientPtr client); +static int SProcPseudoramiXGetScreenSize(ClientPtr client); +static int SProcPseudoramiXIsActive(ClientPtr client); +static int SProcPseudoramiXQueryScreens(ClientPtr client); +static int SProcPseudoramiXDispatch(ClientPtr client); + + +typedef struct { + int x; + int y; + int w; + int h; +} PseudoramiXScreenRec; + +static PseudoramiXScreenRec *pseudoramiXScreens = NULL; +static int pseudoramiXScreensAllocated = 0; +static int pseudoramiXNumScreens = 0; +static unsigned long pseudoramiXGeneration = 0; + + +// Add a PseudoramiX screen. +// The rest of the X server will know nothing about this screen. +// Can be called before or after extension init. +// Screens must be re-added once per generation. +void +PseudoramiXAddScreen(int x, int y, int w, int h) +{ + PseudoramiXScreenRec *s; + + if (noPseudoramiXExtension) return; + + if (pseudoramiXNumScreens == pseudoramiXScreensAllocated) { + pseudoramiXScreensAllocated += pseudoramiXScreensAllocated + 1; + pseudoramiXScreens = xrealloc(pseudoramiXScreens, + pseudoramiXScreensAllocated * + sizeof(PseudoramiXScreenRec)); + } + + s = &pseudoramiXScreens[pseudoramiXNumScreens++]; + s->x = x; + s->y = y; + s->w = w; + s->h = h; +} + + +// Initialize PseudoramiX. +// Copied from PanoramiXExtensionInit +void PseudoramiXExtensionInit(int argc, char *argv[]) +{ + Bool success = FALSE; + ExtensionEntry *extEntry; + + if (noPseudoramiXExtension) return; + + if (pseudoramiXNumScreens == 1 || aquaNumScreens == 1) { + // Only one screen - disable Xinerama extension. + noPseudoramiXExtension = TRUE; + return; + } + + // The server must not run the PanoramiX operations. + noPanoramiXExtension = TRUE; + + if (pseudoramiXGeneration != serverGeneration) { + extEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0, 0, + ProcPseudoramiXDispatch, + SProcPseudoramiXDispatch, + PseudoramiXResetProc, + StandardMinorOpcode); + if (!extEntry) { + ErrorF("PseudoramiXExtensionInit(): AddExtension failed\n"); + } else { + pseudoramiXGeneration = serverGeneration; + success = TRUE; + } + } + + if (!success) { + ErrorF("%s Extension (PseudoramiX) failed to initialize\n", + PANORAMIX_PROTOCOL_NAME); + return; + } +} + + +static void PseudoramiXResetProc(ExtensionEntry *extEntry) +{ + pseudoramiXNumScreens = 0; +} + + +// was PanoramiX +static int ProcPseudoramiXQueryVersion(ClientPtr client) +{ + return ProcPanoramiXQueryVersion(client); +} + + +// was PanoramiX +static int ProcPseudoramiXGetState(ClientPtr client) +{ + REQUEST(xPanoramiXGetStateReq); + WindowPtr pWin; + xPanoramiXGetStateReply rep; + register int n; + + REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); + pWin = LookupWindow (stuff->window, client); + if (!pWin) + return BadWindow; + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.state = !noPseudoramiXExtension; + if (client->swapped) { + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swaps (&rep.state, n); + } + WriteToClient (client, sizeof (xPanoramiXGetStateReply), (char *) &rep); + return client->noClientException; +} + + +// was PanoramiX +static int ProcPseudoramiXGetScreenCount(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenCountReq); + WindowPtr pWin; + xPanoramiXGetScreenCountReply rep; + register int n; + + REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); + pWin = LookupWindow (stuff->window, client); + if (!pWin) + return BadWindow; + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.ScreenCount = pseudoramiXNumScreens; + if (client->swapped) { + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swaps (&rep.ScreenCount, n); + } + WriteToClient (client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep); + return client->noClientException; +} + + +// was PanoramiX +static int ProcPseudoramiXGetScreenSize(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenSizeReq); + WindowPtr pWin; + xPanoramiXGetScreenSizeReply rep; + register int n; + + REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); + pWin = LookupWindow (stuff->window, client); + if (!pWin) + return BadWindow; + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + /* screen dimensions */ + rep.width = pseudoramiXScreens[stuff->screen].w; + // was panoramiXdataPtr[stuff->screen].width; + rep.height = pseudoramiXScreens[stuff->screen].h; + // was panoramiXdataPtr[stuff->screen].height; + if (client->swapped) { + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swaps (&rep.width, n); + swaps (&rep.height, n); + } + WriteToClient (client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep); + return client->noClientException; +} + + +// was Xinerama +static int ProcPseudoramiXIsActive(ClientPtr client) +{ + /* REQUEST(xXineramaIsActiveReq); */ + xXineramaIsActiveReply rep; + + REQUEST_SIZE_MATCH(xXineramaIsActiveReq); + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.state = !noPseudoramiXExtension; + if (client->swapped) { + register int n; + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swapl (&rep.state, n); + } + WriteToClient (client, sizeof (xXineramaIsActiveReply), (char *) &rep); + return client->noClientException; +} + + +// was Xinerama +static int ProcPseudoramiXQueryScreens(ClientPtr client) +{ + /* REQUEST(xXineramaQueryScreensReq); */ + xXineramaQueryScreensReply rep; + + REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.number = noPseudoramiXExtension ? 0 : pseudoramiXNumScreens; + rep.length = rep.number * sz_XineramaScreenInfo >> 2; + if (client->swapped) { + register int n; + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swapl (&rep.number, n); + } + WriteToClient (client, sizeof (xXineramaQueryScreensReply), (char *) &rep); + + if (!noPseudoramiXExtension) { + xXineramaScreenInfo scratch; + int i; + + for(i = 0; i < pseudoramiXNumScreens; i++) { + scratch.x_org = pseudoramiXScreens[i].x; + scratch.y_org = pseudoramiXScreens[i].y; + scratch.width = pseudoramiXScreens[i].w; + scratch.height = pseudoramiXScreens[i].h; + + if(client->swapped) { + register int n; + swaps (&scratch.x_org, n); + swaps (&scratch.y_org, n); + swaps (&scratch.width, n); + swaps (&scratch.height, n); + } + WriteToClient (client, sz_XineramaScreenInfo, (char *) &scratch); + } + } + + return client->noClientException; +} + + +// was PanoramiX +static int ProcPseudoramiXDispatch (ClientPtr client) +{ REQUEST(xReq); + switch (stuff->data) + { + case X_PanoramiXQueryVersion: + return ProcPseudoramiXQueryVersion(client); + case X_PanoramiXGetState: + return ProcPseudoramiXGetState(client); + case X_PanoramiXGetScreenCount: + return ProcPseudoramiXGetScreenCount(client); + case X_PanoramiXGetScreenSize: + return ProcPseudoramiXGetScreenSize(client); + case X_XineramaIsActive: + return ProcPseudoramiXIsActive(client); + case X_XineramaQueryScreens: + return ProcPseudoramiXQueryScreens(client); + } + return BadRequest; +} + + + +static int +SProcPseudoramiXQueryVersion (ClientPtr client) +{ + REQUEST(xPanoramiXQueryVersionReq); + register int n; + + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq); + return ProcPseudoramiXQueryVersion(client); +} + +static int +SProcPseudoramiXGetState(ClientPtr client) +{ + REQUEST(xPanoramiXGetStateReq); + register int n; + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); + return ProcPseudoramiXGetState(client); +} + +static int +SProcPseudoramiXGetScreenCount(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenCountReq); + register int n; + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); + return ProcPseudoramiXGetScreenCount(client); +} + +static int +SProcPseudoramiXGetScreenSize(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenSizeReq); + register int n; + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); + return ProcPseudoramiXGetScreenSize(client); +} + + +static int +SProcPseudoramiXIsActive(ClientPtr client) +{ + REQUEST(xXineramaIsActiveReq); + register int n; + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXineramaIsActiveReq); + return ProcPseudoramiXIsActive(client); +} + + +static int +SProcPseudoramiXQueryScreens(ClientPtr client) +{ + REQUEST(xXineramaQueryScreensReq); + register int n; + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); + return ProcPseudoramiXQueryScreens(client); +} + + +static int +SProcPseudoramiXDispatch (ClientPtr client) +{ REQUEST(xReq); + switch (stuff->data) + { + case X_PanoramiXQueryVersion: + return SProcPseudoramiXQueryVersion(client); + case X_PanoramiXGetState: + return SProcPseudoramiXGetState(client); + case X_PanoramiXGetScreenCount: + return SProcPseudoramiXGetScreenCount(client); + case X_PanoramiXGetScreenSize: + return SProcPseudoramiXGetScreenSize(client); + case X_XineramaIsActive: + return SProcPseudoramiXIsActive(client); + case X_XineramaQueryScreens: + return SProcPseudoramiXQueryScreens(client); + } + return BadRequest; +} diff --git a/hw/darwin/quartz/pseudoramiX.h b/hw/darwin/quartz/pseudoramiX.h new file mode 100644 index 000000000..d0d596686 --- /dev/null +++ b/hw/darwin/quartz/pseudoramiX.h @@ -0,0 +1,10 @@ +/* + * Minimal implementation of PanoramiX/Xinerama + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/pseudoramiX.h,v 1.1 2002/03/28 02:21:18 torrey Exp $ */ + +extern int noPseudoramiXExtension; +extern int aquaNumScreens; + +void PseudoramiXAddScreen(int x, int y, int w, int h); +void PseudoramiXExtensionInit(int argc, char *argv[]); diff --git a/hw/darwin/quartz/quartz.c b/hw/darwin/quartz/quartz.c new file mode 100644 index 000000000..592a0e4a0 --- /dev/null +++ b/hw/darwin/quartz/quartz.c @@ -0,0 +1,305 @@ +/************************************************************** + * + * Quartz-specific support for 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. + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartz.c,v 1.7 2003/01/23 00:34:26 torrey Exp $ */ + +#include "quartzCommon.h" +#include "quartz.h" +#include "darwin.h" +#include "quartzAudio.h" +#include "quartzCursor.h" +#include "fullscreen.h" +#include "rootlessAqua.h" +#include "pseudoramiX.h" + +// X headers +#include "scrnintstr.h" +#include "colormapst.h" + +// System headers +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <IOKit/pwr_mgt/IOPMLib.h> + +// Shared global variables for Quartz modes +int quartzEventWriteFD = -1; +int quartzStartClients = 1; +int quartzRootless = -1; +int quartzUseSysBeep = 0; +int quartzUseAGL = 1; +int quartzServerVisible = TRUE; +int quartzServerQuitting = FALSE; +int quartzScreenIndex = 0; +int aquaMenuBarHeight = 0; +int noPseudoramiXExtension = TRUE; +int aquaNumScreens = 0; + + +/* +=========================================================================== + + Screen functions + +=========================================================================== +*/ + +/* + * QuartzAddScreen + * Do mode dependent initialization of each screen for Quartz. + */ +Bool QuartzAddScreen( + int index, + ScreenPtr pScreen) +{ + // allocate space for private per screen Quartz specific storage + QuartzScreenPtr displayInfo = xcalloc(sizeof(QuartzScreenRec), 1); + QUARTZ_PRIV(pScreen) = displayInfo; + + // do full screen or rootless specific initialization + if (quartzRootless) { + return AquaAddScreen(index, pScreen); + } else { + return QuartzFSAddScreen(index, pScreen); + } +} + + +/* + * QuartzSetupScreen + * Finalize mode specific setup of each screen. + */ +Bool QuartzSetupScreen( + int index, + ScreenPtr pScreen) +{ + // do full screen or rootless specific setup + if (quartzRootless) { + if (! AquaSetupScreen(index, pScreen)) + return FALSE; + } else { + if (! QuartzFSSetupScreen(index, pScreen)) + return FALSE; + } + + // setup cursor support + if (! QuartzInitCursor(pScreen)) + return FALSE; + + return TRUE; +} + + +/* + * QuartzInitOutput + * Quartz display initialization. + */ +void QuartzInitOutput( + int argc, + char **argv ) +{ + static unsigned long generation = 0; + + // Allocate private storage for each screen's Quartz specific info + if (generation != serverGeneration) { + quartzScreenIndex = AllocateScreenPrivateIndex(); + generation = serverGeneration; + } + + if (serverGeneration == 0) { + QuartzAudioInit(); + } + + if (!RegisterBlockAndWakeupHandlers(QuartzBlockHandler, + QuartzWakeupHandler, + NULL)) + { + FatalError("Could not register block and wakeup handlers."); + } + + if (quartzRootless) { + ErrorF("Display mode: Rootless Quartz\n"); + AquaDisplayInit(); + } else { + ErrorF("Display mode: Full screen Quartz\n"); + QuartzFSDisplayInit(); + } + + // Init PseudoramiX implementation of Xinerama. + // This should be in InitExtensions, but that causes link errors + // for servers that don't link in pseudoramiX.c. + if (!noPseudoramiXExtension) { + PseudoramiXExtensionInit(argc, argv); + } +} + + +/* + * QuartzInitInput + * Inform the main thread the X server is ready to handle events. + */ +void QuartzInitInput( + int argc, + char **argv ) +{ + QuartzMessageMainThread(kQuartzServerStarted, NULL, 0); +} + + +/* + * QuartzShow + * Show the X server on screen. Does nothing if already shown. + * Restore the X clip regions and the X server cursor state. + */ +static void QuartzShow( + int x, // cursor location + int y ) +{ + int i; + + if (!quartzServerVisible) { + quartzServerVisible = TRUE; + for (i = 0; i < screenInfo.numScreens; i++) { + if (screenInfo.screens[i]) { + QuartzResumeXCursor(screenInfo.screens[i], x, y); + if (!quartzRootless) + xf86SetRootClip(screenInfo.screens[i], TRUE); + } + } + } +} + + +/* + * QuartzHide + * Remove the X server display from the screen. Does nothing if already + * hidden. Set X clip regions to prevent drawing, and restore the Aqua + * cursor. + */ +static void QuartzHide(void) +{ + int i; + + if (quartzServerVisible) { + for (i = 0; i < screenInfo.numScreens; i++) { + if (screenInfo.screens[i]) { + QuartzSuspendXCursor(screenInfo.screens[i]); + if (!quartzRootless) + xf86SetRootClip(screenInfo.screens[i], FALSE); + } + } + } + quartzServerVisible = FALSE; + QuartzMessageMainThread(kQuartzServerHidden, NULL, 0); +} + + +/* + * QuartzSetRootClip + * Enable or disable rendering to the X screen. + */ +static void QuartzSetRootClip( + BOOL enable) +{ + int i; + + if (!quartzServerVisible) + return; + + for (i = 0; i < screenInfo.numScreens; i++) { + if (screenInfo.screens[i]) { + xf86SetRootClip(screenInfo.screens[i], enable); + } + } +} + + +/* + * QuartzProcessEvent + * Process Quartz specific events. + */ +void QuartzProcessEvent( + xEvent *xe) +{ + switch (xe->u.u.type) { + + case kXDarwinShow: + QuartzShow(xe->u.keyButtonPointer.rootX, + xe->u.keyButtonPointer.rootY); + break; + + case kXDarwinHide: + QuartzHide(); + break; + + case kXDarwinSetRootClip: + QuartzSetRootClip((BOOL)xe->u.clientMessage.u.l.longs0); + break; + + case kXDarwinQuit: + GiveUp(0); + break; + + case kXDarwinReadPasteboard: + QuartzReadPasteboard(); + break; + + case kXDarwinWritePasteboard: + QuartzWritePasteboard(); + break; + + default: + ErrorF("Unknown application defined event.\n"); + } +} + + +/* + * QuartzGiveUp + * Cleanup before X server shutdown + * Release the screen and restore the Aqua cursor. + */ +void QuartzGiveUp(void) +{ +#if 0 +// Trying to switch cursors when quitting causes deadlock + int i; + + for (i = 0; i < screenInfo.numScreens; i++) { + if (screenInfo.screens[i]) { + QuartzSuspendXCursor(screenInfo.screens[i]); + } + } +#endif + + if (!quartzRootless) + QuartzFSRelease(); +} diff --git a/hw/darwin/quartz/quartz.h b/hw/darwin/quartz/quartz.h new file mode 100644 index 000000000..cd4f732f3 --- /dev/null +++ b/hw/darwin/quartz/quartz.h @@ -0,0 +1,50 @@ +/* + * quartz.h + * + * External interface of the Quartz modes seen by the generic, mode + * independent parts of the Darwin X server. + */ +/* + * Copyright (c) 2001-2002 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. + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartz.h,v 1.4 2002/11/20 23:51:58 torrey Exp $ */ + +#ifndef _QUARTZ_H +#define _QUARTZ_H + +#include "screenint.h" +#include "Xproto.h" +#include "quartzPasteboard.h" + +int QuartzProcessArgument(int argc, char *argv[], int i); +void QuartzInitOutput(int argc, char **argv); +void QuartzInitInput(int argc, char **argv); +Bool QuartzAddScreen(int index, ScreenPtr pScreen); +Bool QuartzSetupScreen(int index, ScreenPtr pScreen); +void QuartzGiveUp(void); +void QuartzProcessEvent(xEvent *xe); + +#endif diff --git a/hw/darwin/quartz/quartzAudio.c b/hw/darwin/quartz/quartzAudio.c new file mode 100644 index 000000000..2dfb313b7 --- /dev/null +++ b/hw/darwin/quartz/quartzAudio.c @@ -0,0 +1,342 @@ +// +// 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. + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartzAudio.c,v 1.1 2002/03/28 02:21:18 torrey Exp $ */ + +#include "quartzCommon.h" +#include "quartzAudio.h" + +#include <CoreAudio/CoreAudio.h> +#include <pthread.h> + +#include "inputstr.h" +#include "extensions/XI.h" + +void NSBeep(); + +typedef struct QuartzAudioRec { + double frequency; + double amplitude; + + UInt32 curFrame; + UInt32 remainingFrames; + UInt32 totalFrames; + UInt32 bytesPerFrame; + 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 / data->bytesPerFrame; + + 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 + buffer += 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); + } + pthread_mutex_unlock(&data->lock); + return 0; +} + + +/* + * QuartzCoreAudioBell + * Play a tone using the CoreAudio API + */ +static void QuartzCoreAudioBell( + int volume, // volume is % of max + int pitch, // pitch is Hz + int duration ) // duration is milliseconds +{ + 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("QuartzAudioBell: AudioDeviceStart returned %d\n", status); + } else { + data.playing = TRUE; + } + } + pthread_mutex_unlock(&data.lock); +} + + +/* + * QuartzBell + * Ring the bell + */ +void QuartzBell( + int volume, // volume in percent of max + DeviceIntPtr pDevice, + pointer ctrl, + int class ) +{ + int pitch; // pitch in Hz + int duration; // duration in milliseconds + + if (class == BellFeedbackClass) { + pitch = ((BellCtrl*)ctrl)->pitch; + duration = ((BellCtrl*)ctrl)->duration; + } else if (class == KbdFeedbackClass) { + pitch = ((KeybdCtrl*)ctrl)->bell_pitch; + duration = ((KeybdCtrl*)ctrl)->bell_duration; + } else { + ErrorF("QuartzBell: bad bell class %d\n", class); + return; + } + + if (quartzUseSysBeep) { + if (volume) + NSBeep(); + } else { + QuartzCoreAudioBell(volume, pitch, duration); + } +} + + +/* + * QuartzAudioInit + * Prepare to play the bell with the CoreAudio API + */ +void QuartzAudioInit(void) +{ + UInt32 propertySize; + OSStatus status; + AudioDeviceID outputDevice; + AudioStreamBasicDescription outputStreamDescription; + double sampleRate; + + // Get the default output device + propertySize = sizeof(outputDevice); + status = AudioHardwareGetProperty( + kAudioHardwarePropertyDefaultOutputDevice, + &propertySize, &outputDevice); + if (status) { + ErrorF("QuartzAudioInit: AudioHardwareGetProperty returned %d\n", + status); + return; + } + if (outputDevice == kAudioDeviceUnknown) { + ErrorF("QuartzAudioInit: No audio output devices available.\n"); + return; + } + + // Get the basic device description + propertySize = sizeof(outputStreamDescription); + status = AudioDeviceGetProperty(outputDevice, 0, FALSE, + kAudioDevicePropertyStreamFormat, + &propertySize, &outputStreamDescription); + if (status) { + ErrorF("QuartzAudioInit: GetProperty(stream format) returned %d\n", + status); + return; + } + sampleRate = outputStreamDescription.mSampleRate; + + // Fill in the playback data + data.frequency = 0; + data.amplitude = 0; + data.curFrame = 0; + data.remainingFrames = 0; + data.bytesPerFrame = outputStreamDescription.mBytesPerFrame; + 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 + status = AudioDeviceAddIOProc(outputDevice, QuartzAudioIOProc, &data); + if (status) { + ErrorF("QuartzAudioInit: AddIOProc returned %d\n", status); + return; + } + + // success! + quartzAudioDevice = outputDevice; +} diff --git a/hw/darwin/quartz/quartzAudio.h b/hw/darwin/quartz/quartzAudio.h new file mode 100644 index 000000000..1d213e36a --- /dev/null +++ b/hw/darwin/quartz/quartzAudio.h @@ -0,0 +1,41 @@ +// +// QuartzAudio.h +// +// X Window bell support using CoreAudio or AppKit. +// Greg Parker gparker@cs.stanford.edu 19 Feb 2001 +/* + * Copyright (c) 2001 Greg Parker. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name(s) of the above copyright + * holders shall not be used in advertising or otherwise to promote the sale, + * use or other dealings in this Software without prior written authorization. + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartzAudio.h,v 1.1 2002/03/28 02:21:19 torrey Exp $ */ + +#ifndef _QUARTZAUDIO_H +#define _QUARTZAUDIO_H + +#include "input.h" + +void QuartzAudioInit(void); +void QuartzBell(int volume, DeviceIntPtr pDevice, pointer ctrl, int class); + +#endif diff --git a/hw/darwin/quartz/quartzCocoa.m b/hw/darwin/quartz/quartzCocoa.m new file mode 100644 index 000000000..d6d9bbe32 --- /dev/null +++ b/hw/darwin/quartz/quartzCocoa.m @@ -0,0 +1,198 @@ +/************************************************************** + * + * Quartz-specific support for the Darwin X Server + * that requires Cocoa and Objective-C. + * + * This file is separate from the parts of Quartz support + * that use X include files to avoid symbol collisions. + * + **************************************************************/ +/* + * Copyright (c) 2001-2003 Torrey T. Lyons and 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. + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartzCocoa.m,v 1.3 2003/01/19 06:52:54 torrey Exp $ */ + +#include <Cocoa/Cocoa.h> + +#import "Preferences.h" +#include "quartzCommon.h" +#include "pseudoramiX.h" + +extern void FatalError(const char *, ...); +extern char *display; +extern int noPanoramiXExtension; + + +/* + * QuartzReadPreferences + * Read the user preferences from the Cocoa front end. + */ +void QuartzReadPreferences(void) +{ + char *fileString; + + darwinFakeButtons = [Preferences fakeButtons]; + darwinFakeMouse2Mask = [Preferences button2Mask]; + darwinFakeMouse3Mask = [Preferences button3Mask]; + quartzMouseAccelChange = [Preferences mouseAccelChange]; + quartzUseSysBeep = [Preferences systemBeep]; + + // quartzRootless has already been set + if (quartzRootless) { + // Use PseudoramiX instead of Xinerama + noPanoramiXExtension = TRUE; + noPseudoramiXExtension = ![Preferences xinerama]; + + quartzUseAGL = [Preferences useAGL]; + } else { + noPanoramiXExtension = ![Preferences xinerama]; + noPseudoramiXExtension = TRUE; + + // Full screen can't use AGL for GLX + quartzUseAGL = FALSE; + } + + if ([Preferences useKeymapFile]) { + fileString = (char *) [[Preferences keymapFile] lossyCString]; + darwinKeymapFile = (char *) malloc(strlen(fileString)+1); + if (! darwinKeymapFile) + FatalError("malloc failed in QuartzReadPreferences()!\n"); + strcpy(darwinKeymapFile, fileString); + } + + display = (char *) malloc(8); + if (! display) + FatalError("malloc failed in QuartzReadPreferences()!\n"); + snprintf(display, 8, "%i", [Preferences display]); + + darwinDesiredDepth = [Preferences depth] - 1; +} + + +/* + * QuartzWriteCocoaPasteboard + * Write text to the Mac OS X pasteboard. + */ +void QuartzWriteCocoaPasteboard( + char *text) +{ + NSPasteboard *pasteboard; + NSArray *pasteboardTypes; + NSString *string; + + if (! text) return; + pasteboard = [NSPasteboard generalPasteboard]; + if (! pasteboard) return; + string = [NSString stringWithCString:text]; + if (! string) return; + pasteboardTypes = [NSArray arrayWithObject:NSStringPboardType]; + + // nil owner because we don't provide type translations + [pasteboard declareTypes:pasteboardTypes owner:nil]; + [pasteboard setString:string forType:NSStringPboardType]; +} + + +/* + * QuartzReadCocoaPasteboard + * Read text from the Mac OS X pasteboard and return it as a heap string. + * The caller must free the string. + */ +char *QuartzReadCocoaPasteboard(void) +{ + NSPasteboard *pasteboard; + NSArray *pasteboardTypes; + NSString *existingType; + char *text = NULL; + + pasteboardTypes = [NSArray arrayWithObject:NSStringPboardType]; + pasteboard = [NSPasteboard generalPasteboard]; + if (! pasteboard) return NULL; + + existingType = [pasteboard availableTypeFromArray:pasteboardTypes]; + if (existingType) { + NSString *string = [pasteboard stringForType:existingType]; + char *buffer; + + if (! string) return NULL; + buffer = (char *) [string lossyCString]; + text = (char *) malloc(strlen(buffer)+1); + if (text) + strcpy(text, buffer); + } + + return text; +} + + +/* + * QuartzFSUseQDCursor + * Return whether the screen should use a QuickDraw cursor. + */ +int QuartzFSUseQDCursor( + int depth) // screen depth +{ + switch ([Preferences useQDCursor]) { + case qdCursor_Always: + return TRUE; + case qdCursor_Never: + return FALSE; + case qdCursor_Not8Bit: + if (depth > 8) + return TRUE; + else + return FALSE; + } + return TRUE; +} + + +/* + * QuartzBlockHandler + * Clean out any autoreleased objects. + */ +void QuartzBlockHandler( + void *blockData, + void *pTimeout, + void *pReadmask) +{ + static NSAutoreleasePool *aPool = nil; + + [aPool release]; + aPool = [[NSAutoreleasePool alloc] init]; +} + + +/* + * QuartzWakeupHandler + */ +void QuartzWakeupHandler( + void *blockData, + int result, + void *pReadmask) +{ + // nothing here +} diff --git a/hw/darwin/quartz/quartzCommon.h b/hw/darwin/quartz/quartzCommon.h new file mode 100644 index 000000000..6c375bd04 --- /dev/null +++ b/hw/darwin/quartz/quartzCommon.h @@ -0,0 +1,98 @@ +/* + * quartzCommon.h + * + * Common definitions used internally by all Quartz modes + * + * This file should be included before any X11 or IOKit headers + * so that it can avoid symbol conflicts. + * + * Copyright (c) 2001-2003 Torrey T. Lyons and 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. + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartzCommon.h,v 1.8 2003/01/23 00:34:26 torrey Exp $ */ + +#ifndef _QUARTZCOMMON_H +#define _QUARTZCOMMON_H + +// QuickDraw in ApplicationServices has the following conflicts with +// the basic X server headers. Use QD_<name> to use the QuickDraw +// definition of any of these symbols, or the normal name for the +// X11 definition. +#define Cursor QD_Cursor +#define WindowPtr QD_WindowPtr +#define Picture QD_Picture +#include <ApplicationServices/ApplicationServices.h> +#undef Cursor +#undef WindowPtr +#undef Picture + +#include "quartzShared.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)pScreen->devPrivates[quartzScreenIndex].ptr) + +// Data stored at startup for Cocoa front end +extern int quartzEventWriteFD; +extern int quartzStartClients; + +// User preferences used by Quartz modes +extern int quartzRootless; +extern int quartzUseSysBeep; +extern int quartzUseAGL; + +// Other shared data +extern int quartzServerVisible; +extern int quartzServerQuitting; +extern int quartzScreenIndex; +extern int aquaMenuBarHeight; + +void QuartzReadPreferences(void); +void QuartzMessageMainThread(unsigned msg, void *data, unsigned length); +void QuartzFSCapture(void); +void QuartzFSRelease(void); +int QuartzFSUseQDCursor(int depth); +void QuartzBlockHandler(void *blockData, void *pTimeout, void *pReadmask); +void QuartzWakeupHandler(void *blockData, int result, void *pReadmask); + +// Messages that can be sent to the main thread. +enum { + kQuartzServerHidden, + kQuartzServerStarted, + kQuartzServerDied, + kQuartzCursorUpdate, + kQuartzPostEvent +}; + +#endif /* _QUARTZCOMMON_H */ diff --git a/hw/darwin/quartz/quartzCursor.c b/hw/darwin/quartz/quartzCursor.c new file mode 100644 index 000000000..8abce2318 --- /dev/null +++ b/hw/darwin/quartz/quartzCursor.c @@ -0,0 +1,653 @@ +/************************************************************** + * + * Support for using the Quartz Window Manager cursor + * + **************************************************************/ +/* + * Copyright (c) 2001-2003 Torrey T. Lyons and 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. + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartzCursor.c,v 1.5 2003/01/23 00:34:26 torrey Exp $ */ + +#include "quartzCommon.h" +#include "quartzCursor.h" +#include "darwin.h" + +#include <pthread.h> + +#include "mi.h" +#include "scrnintstr.h" +#include "cursorstr.h" +#include "mipointrst.h" +#include "globals.h" + +// Size of the QuickDraw cursor +#define CURSORWIDTH 16 +#define CURSORHEIGHT 16 + +typedef struct { + int qdCursorMode; + int qdCursorVisible; + int useQDCursor; + QueryBestSizeProcPtr QueryBestSize; + miPointerSpriteFuncPtr spriteFuncs; +} QuartzCursorScreenRec, *QuartzCursorScreenPtr; + +static int darwinCursorScreenIndex = -1; +static unsigned long darwinCursorGeneration = 0; +static CursorPtr quartzLatentCursor = NULL; +static QD_Cursor gQDArrow; // QuickDraw arrow cursor + +// Cursor for the main thread to set (NULL = arrow cursor). +static CCrsrHandle currentCursor = NULL; +static pthread_mutex_t cursorMutex; +static pthread_cond_t cursorCondition; + +#define CURSOR_PRIV(pScreen) \ + ((QuartzCursorScreenPtr)pScreen->devPrivates[darwinCursorScreenIndex].ptr) + +#define HIDE_QD_CURSOR(pScreen, visible) \ + if (visible) { \ + int ix; \ + for (ix = 0; ix < QUARTZ_PRIV(pScreen)->displayCount; ix++) { \ + CGDisplayHideCursor(QUARTZ_PRIV(pScreen)->displayIDs[ix]); \ + } \ + visible = FALSE; \ + } ((void)0) + +#define SHOW_QD_CURSOR(pScreen, visible) \ + { \ + int ix; \ + for (ix = 0; ix < QUARTZ_PRIV(pScreen)->displayCount; ix++) { \ + CGDisplayShowCursor(QUARTZ_PRIV(pScreen)->displayIDs[ix]); \ + } \ + visible = TRUE; \ + } ((void)0) + +#define CHANGE_QD_CURSOR(cursorH) \ + if (!quartzServerQuitting) { \ + /* Acquire lock and tell the main thread to change cursor */ \ + pthread_mutex_lock(&cursorMutex); \ + currentCursor = (CCrsrHandle) (cursorH); \ + QuartzMessageMainThread(kQuartzCursorUpdate, NULL, 0); \ + \ + /* Wait for the main thread to change the cursor */ \ + pthread_cond_wait(&cursorCondition, &cursorMutex); \ + pthread_mutex_unlock(&cursorMutex); \ + } ((void)0) + + +/* + * MakeQDCursor helpers: CTAB_ENTER, interleave + */ + +// Add a color entry to a ctab +#define CTAB_ENTER(ctab, index, r, g, b) \ + ctab->ctTable[index].value = index; \ + ctab->ctTable[index].rgb.red = r; \ + ctab->ctTable[index].rgb.green = g; \ + ctab->ctTable[index].rgb.blue = b + +// Make an unsigned short by interleaving the bits of bytes c1 and c2. +// High bit of c1 is first; low bit of c2 is last. +// Interleave is a built-in INTERCAL operator. +static unsigned short +interleave( + unsigned char c1, + unsigned char c2 ) +{ + return + ((c1 & 0x80) << 8) | ((c2 & 0x80) << 7) | + ((c1 & 0x40) << 7) | ((c2 & 0x40) << 6) | + ((c1 & 0x20) << 6) | ((c2 & 0x20) << 5) | + ((c1 & 0x10) << 5) | ((c2 & 0x10) << 4) | + ((c1 & 0x08) << 4) | ((c2 & 0x08) << 3) | + ((c1 & 0x04) << 3) | ((c2 & 0x04) << 2) | + ((c1 & 0x02) << 2) | ((c2 & 0x02) << 1) | + ((c1 & 0x01) << 1) | ((c2 & 0x01) << 0) ; +} + +/* + * MakeQDCursor + * Make a QuickDraw color cursor from the given X11 cursor. + * Warning: This code is nasty. Color cursors were meant to be read + * from resources; constructing the structures programmatically is messy. + */ +/* + QuickDraw cursor representation: + Our color cursor is a 2 bit per pixel pixmap. + Each pixel's bits are (source<<1 | mask) from the original X cursor pixel. + The cursor's color table maps the colors like this: + (2-bit value | X result | colortable | Mac result) + 00 | transparent | white | transparent (white outside mask) + 01 | back color | back color | back color + 10 | undefined | black | invert background (just for fun) + 11 | fore color | fore color | fore color +*/ +static CCrsrHandle +MakeQDCursor( + CursorPtr pCursor ) +{ + CCrsrHandle result; + CCrsrPtr curs; + int i, w, h; + unsigned short rowMask; + PixMap *pix; + ColorTable *ctab; + unsigned short *image; + + result = (CCrsrHandle) NewHandleClear(sizeof(CCrsr)); + if (!result) return NULL; + HLock((Handle)result); + curs = *result; + + // Initialize CCrsr + curs->crsrType = 0x8001; // 0x8000 = b&w, 0x8001 = color + curs->crsrMap = (PixMapHandle) NewHandleClear(sizeof(PixMap)); + if (!curs->crsrMap) goto pixAllocFailed; + HLock((Handle)curs->crsrMap); + pix = *curs->crsrMap; + curs->crsrData = NULL; // raw cursor image data (set below) + curs->crsrXData = NULL; // QD's processed data + curs->crsrXValid = 0; // zero means QD must re-process cursor data + curs->crsrXHandle = NULL; // reserved + memset(curs->crsr1Data, 0, CURSORWIDTH*CURSORHEIGHT/8); // b&w data + memset(curs->crsrMask, 0, CURSORWIDTH*CURSORHEIGHT/8); // b&w & color mask + curs->crsrHotSpot.h = min(CURSORWIDTH, pCursor->bits->xhot); // hot spot + curs->crsrHotSpot.v = min(CURSORHEIGHT, pCursor->bits->yhot); // hot spot + curs->crsrXTable = 0; // reserved + curs->crsrID = GetCTSeed(); // unique ID from Color Manager + + // Set the b&w data and mask + w = min(pCursor->bits->width, CURSORWIDTH); + h = min(pCursor->bits->height, CURSORHEIGHT); + rowMask = ~((1 << (CURSORWIDTH - w)) - 1); + for (i = 0; i < h; i++) { + curs->crsr1Data[i] = rowMask & + ((pCursor->bits->source[i*4]<<8) | pCursor->bits->source[i*4+1]); + curs->crsrMask[i] = rowMask & + ((pCursor->bits->mask[i*4]<<8) | pCursor->bits->mask[i*4+1]); + } + + // Set the color data and mask + // crsrMap: defines bit depth and size and colortable only + pix->rowBytes = (CURSORWIDTH * 2 / 8) | 0x8000; // last bit on means PixMap + SetRect(&pix->bounds, 0, 0, CURSORWIDTH, CURSORHEIGHT); // see TN 1020 + pix->pixelSize = 2; + pix->cmpCount = 1; + pix->cmpSize = 2; + // pix->pmTable set below + + // crsrData is the pixel data. crsrMap's baseAddr is not used. + curs->crsrData = NewHandleClear(CURSORWIDTH*CURSORHEIGHT * 2 / 8); + if (!curs->crsrData) goto imageAllocFailed; + HLock((Handle)curs->crsrData); + image = (unsigned short *) *curs->crsrData; + // Pixel data is just 1-bit data and mask interleaved (see above) + for (i = 0; i < h; i++) { + unsigned char s, m; + s = pCursor->bits->source[i*4] & (rowMask >> 8); + m = pCursor->bits->mask[i*4] & (rowMask >> 8); + image[2*i] = interleave(s, m); + s = pCursor->bits->source[i*4+1] & (rowMask & 0x00ff); + m = pCursor->bits->mask[i*4+1] & (rowMask & 0x00ff); + image[2*i+1] = interleave(s, m); + } + + // Build the color table (entries described above) + // NewPixMap allocates a color table handle. + pix->pmTable = (CTabHandle) NewHandleClear(sizeof(ColorTable) + 3 + * sizeof(ColorSpec)); + if (!pix->pmTable) goto ctabAllocFailed; + HLock((Handle)pix->pmTable); + ctab = *pix->pmTable; + ctab->ctSeed = GetCTSeed(); + ctab->ctFlags = 0; + ctab->ctSize = 3; // color count - 1 + CTAB_ENTER(ctab, 0, 0xffff, 0xffff, 0xffff); + CTAB_ENTER(ctab, 1, pCursor->backRed, pCursor->backGreen, + pCursor->backBlue); + CTAB_ENTER(ctab, 2, 0x0000, 0x0000, 0x0000); + CTAB_ENTER(ctab, 3, pCursor->foreRed, pCursor->foreGreen, + pCursor->foreBlue); + + HUnlock((Handle)pix->pmTable); // ctab + HUnlock((Handle)curs->crsrData); // image data + HUnlock((Handle)curs->crsrMap); // pix + HUnlock((Handle)result); // cursor + + return result; + + // "What we have here is a failure to allocate" +ctabAllocFailed: + HUnlock((Handle)curs->crsrData); + DisposeHandle((Handle)curs->crsrData); +imageAllocFailed: + HUnlock((Handle)curs->crsrMap); + DisposeHandle((Handle)curs->crsrMap); +pixAllocFailed: + HUnlock((Handle)result); + DisposeHandle((Handle)result); + return NULL; +} + + +/* + * FreeQDCursor + * Destroy a QuickDraw color cursor created with MakeQDCursor(). + * The cursor must not currently be on screen. + */ +static void FreeQDCursor(CCrsrHandle cursHandle) +{ + CCrsrPtr curs; + PixMap *pix; + + HLock((Handle)cursHandle); + curs = *cursHandle; + HLock((Handle)curs->crsrMap); + pix = *curs->crsrMap; + DisposeHandle((Handle)pix->pmTable); + HUnlock((Handle)curs->crsrMap); + DisposeHandle((Handle)curs->crsrMap); + DisposeHandle((Handle)curs->crsrData); + HUnlock((Handle)cursHandle); + DisposeHandle((Handle)cursHandle); +} + + +/* +=========================================================================== + + Pointer sprite functions + +=========================================================================== +*/ + +/* + * QuartzRealizeCursor + * Convert the X cursor representation to QuickDraw format if possible. + */ +Bool +QuartzRealizeCursor( + ScreenPtr pScreen, + CursorPtr pCursor ) +{ + CCrsrHandle qdCursor; + QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); + + if(!pCursor || !pCursor->bits) + return FALSE; + + // if the cursor is too big we use a software cursor + if ((pCursor->bits->height > CURSORHEIGHT) || + (pCursor->bits->width > CURSORWIDTH) || !ScreenPriv->useQDCursor) + { + if (quartzRootless) { + // rootless can't use a software cursor + return TRUE; + } else { + return (*ScreenPriv->spriteFuncs->RealizeCursor) + (pScreen, pCursor); + } + } + + // make new cursor image + qdCursor = MakeQDCursor(pCursor); + if (!qdCursor) return FALSE; + + // save the result + pCursor->devPriv[pScreen->myNum] = (pointer) qdCursor; + + return TRUE; +} + + +/* + * QuartzUnrealizeCursor + * Free the storage space associated with a realized cursor. + */ +Bool +QuartzUnrealizeCursor( + ScreenPtr pScreen, + CursorPtr pCursor ) +{ + QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); + + if ((pCursor->bits->height > CURSORHEIGHT) || + (pCursor->bits->width > CURSORWIDTH) || !ScreenPriv->useQDCursor) + { + if (quartzRootless) { + return TRUE; + } else { + return (*ScreenPriv->spriteFuncs->UnrealizeCursor) + (pScreen, pCursor); + } + } else { + CCrsrHandle oldCursor = (CCrsrHandle) pCursor->devPriv[pScreen->myNum]; + + if (currentCursor != oldCursor) { + // This should only fail when quitting, in which case we just leak. + FreeQDCursor(oldCursor); + } + pCursor->devPriv[pScreen->myNum] = NULL; + return TRUE; + } +} + + +/* + * QuartzSetCursor + * Set the cursor sprite and position. + * Use QuickDraw cursor if possible. + */ +static void +QuartzSetCursor( + ScreenPtr pScreen, + CursorPtr pCursor, + int x, + int y) +{ + QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); + + quartzLatentCursor = pCursor; + + // Don't touch Mac OS cursor if X is hidden! + if (!quartzServerVisible) + return; + + if (!pCursor) { + // Remove the cursor completely. + HIDE_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible); + if (! ScreenPriv->qdCursorMode) + (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, 0, x, y); + } + else if ((pCursor->bits->height <= CURSORHEIGHT) && + (pCursor->bits->width <= CURSORWIDTH) && ScreenPriv->useQDCursor) + { + // Cursor is small enough to use QuickDraw directly. + if (! ScreenPriv->qdCursorMode) // remove the X cursor + (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, 0, x, y); + ScreenPriv->qdCursorMode = TRUE; + + CHANGE_QD_CURSOR(pCursor->devPriv[pScreen->myNum]); + SHOW_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible); + } + else if (quartzRootless) { + // Rootless can't use a software cursor, so we just use Mac OS arrow. + CHANGE_QD_CURSOR(NULL); + SHOW_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible); + } + else { + // Cursor is too big for QuickDraw. Use X software cursor. + HIDE_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible); + ScreenPriv->qdCursorMode = FALSE; + (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, pCursor, x, y); + } +} + + +/* + * QuartzReallySetCursor + * Set the QuickDraw cursor. Called from the main thread since changing the + * cursor with QuickDraw is not thread safe on dual processor machines. + */ +void +QuartzReallySetCursor() +{ + pthread_mutex_lock(&cursorMutex); + + if (currentCursor) { + SetCCursor(currentCursor); + } else { + SetCursor(&gQDArrow); + } + + pthread_cond_signal(&cursorCondition); + pthread_mutex_unlock(&cursorMutex); +} + + +/* + * QuartzMoveCursor + * Move the cursor. This is a noop for QuickDraw. + */ +static void +QuartzMoveCursor( + ScreenPtr pScreen, + int x, + int y) +{ + QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); + + // only the X cursor needs to be explicitly moved + if (!ScreenPriv->qdCursorMode) + (*ScreenPriv->spriteFuncs->MoveCursor)(pScreen, x, y); +} + + +static miPointerSpriteFuncRec quartzSpriteFuncsRec = { + QuartzRealizeCursor, + QuartzUnrealizeCursor, + QuartzSetCursor, + QuartzMoveCursor +}; + + +/* +=========================================================================== + + Pointer screen functions + +=========================================================================== +*/ + +/* + * QuartzCursorOffScreen + */ +static Bool QuartzCursorOffScreen(ScreenPtr *pScreen, int *x, int *y) +{ + return FALSE; +} + + +/* + * QuartzCrossScreen + */ +static void QuartzCrossScreen(ScreenPtr pScreen, Bool entering) +{ + return; +} + + +/* + * QuartzWarpCursor + * Change the cursor position without generating an event or motion history. + * The input coordinates (x,y) are in pScreen-local X11 coordinates. + * + */ +static void +QuartzWarpCursor( + ScreenPtr pScreen, + int x, + int y) +{ + static int neverMoved = TRUE; + + if (neverMoved) { + // Don't move the cursor the first time. This is the jump-to-center + // initialization, and it's annoying because we may still be in MacOS. + neverMoved = FALSE; + return; + } + + if (quartzServerVisible) { + CGDisplayErr cgErr; + CGPoint cgPoint; + // Only need to do this for one display. Any display will do. + CGDirectDisplayID cgID = QUARTZ_PRIV(pScreen)->displayIDs[0]; + CGRect cgRect = CGDisplayBounds(cgID); + + // Convert (x,y) to CoreGraphics screen-local CG coordinates. + // This is necessary because the X11 screen and CG screen may not + // coincide. (e.g. X11 screen may be moved to dodge the menu bar) + + // Make point in X11 global coordinates + cgPoint = CGPointMake(x + dixScreenOrigins[pScreen->myNum].x, + y + dixScreenOrigins[pScreen->myNum].y); + // Shift to CoreGraphics global screen coordinates + cgPoint.x += darwinMainScreenX; + cgPoint.y += darwinMainScreenY; + // Shift to CoreGraphics screen-local coordinates + cgPoint.x -= cgRect.origin.x; + cgPoint.y -= cgRect.origin.y; + + cgErr = CGDisplayMoveCursorToPoint(cgID, cgPoint); + if (cgErr != CGDisplayNoErr) { + ErrorF("Could not set cursor position with error code 0x%x.\n", + cgErr); + } + } + + miPointerWarpCursor(pScreen, x, y); + miPointerUpdate(); +} + + +static miPointerScreenFuncRec quartzScreenFuncsRec = { + QuartzCursorOffScreen, + QuartzCrossScreen, + QuartzWarpCursor, + DarwinEQPointerPost, + DarwinEQSwitchScreen +}; + + +/* +=========================================================================== + + Other screen functions + +=========================================================================== +*/ + +/* + * QuartzCursorQueryBestSize + * Handle queries for best cursor size + */ +static void +QuartzCursorQueryBestSize( + int class, + unsigned short *width, + unsigned short *height, + ScreenPtr pScreen) +{ + QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); + + if (class == CursorShape) { + *width = CURSORWIDTH; + *height = CURSORHEIGHT; + } else { + (*ScreenPriv->QueryBestSize)(class, width, height, pScreen); + } +} + + +/* + * QuartzInitCursor + * Initialize cursor support + */ +Bool +QuartzInitCursor( + ScreenPtr pScreen ) +{ + QuartzCursorScreenPtr ScreenPriv; + miPointerScreenPtr PointPriv; + DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen); + + // initialize software cursor handling (always needed as backup) + if (!miDCInitialize(pScreen, &quartzScreenFuncsRec)) { + return FALSE; + } + + // allocate private storage for this screen's QuickDraw cursor info + if (darwinCursorGeneration != serverGeneration) { + if ((darwinCursorScreenIndex = AllocateScreenPrivateIndex()) < 0) + return FALSE; + darwinCursorGeneration = serverGeneration; + } + + ScreenPriv = xcalloc( 1, sizeof(QuartzCursorScreenRec) ); + if (!ScreenPriv) return FALSE; + + CURSOR_PRIV(pScreen) = ScreenPriv; + + // override some screen procedures + ScreenPriv->QueryBestSize = pScreen->QueryBestSize; + pScreen->QueryBestSize = QuartzCursorQueryBestSize; + + // initialize QuickDraw cursor handling + GetQDGlobalsArrow(&gQDArrow); + PointPriv = (miPointerScreenPtr) + pScreen->devPrivates[miPointerScreenIndex].ptr; + + ScreenPriv->spriteFuncs = PointPriv->spriteFuncs; + PointPriv->spriteFuncs = &quartzSpriteFuncsRec; + + if (!quartzRootless) + ScreenPriv->useQDCursor = QuartzFSUseQDCursor(dfb->colorBitsPerPixel); + else + ScreenPriv->useQDCursor = TRUE; + ScreenPriv->qdCursorMode = TRUE; + ScreenPriv->qdCursorVisible = TRUE; + + // initialize cursor mutex lock + pthread_mutex_init(&cursorMutex, NULL); + + // initialize condition for waiting + pthread_cond_init(&cursorCondition, NULL); + + return TRUE; +} + + +// X server is hiding. Restore the Aqua cursor. +void QuartzSuspendXCursor( + ScreenPtr pScreen ) +{ + QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); + + CHANGE_QD_CURSOR(NULL); + SHOW_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible); +} + + +// X server is showing. Restore the X cursor. +void QuartzResumeXCursor( + ScreenPtr pScreen, + int x, + int y ) +{ + QuartzSetCursor(pScreen, quartzLatentCursor, x, y); +} diff --git a/hw/darwin/quartz/quartzCursor.h b/hw/darwin/quartz/quartzCursor.h new file mode 100644 index 000000000..9710d4be2 --- /dev/null +++ b/hw/darwin/quartz/quartzCursor.h @@ -0,0 +1,43 @@ +/* + * quartzCursor.h + * + * External interface for Quartz hardware cursor + */ +/* + * Copyright (c) 2001 Torrey T. Lyons and 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. + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartzCursor.h,v 1.1 2002/03/28 02:21:19 torrey Exp $ */ + +#ifndef QUARTZCURSOR_H +#define QUARTZCURSOR_H + +#include "screenint.h" + +Bool QuartzInitCursor(ScreenPtr pScreen); +void QuartzSuspendXCursor(ScreenPtr pScreen); +void QuartzResumeXCursor(ScreenPtr pScreen, int x, int y); + +#endif diff --git a/hw/darwin/quartz/quartzPasteboard.c b/hw/darwin/quartz/quartzPasteboard.c new file mode 100644 index 000000000..658832aa1 --- /dev/null +++ b/hw/darwin/quartz/quartzPasteboard.c @@ -0,0 +1,150 @@ +/************************************************************** + * quartzPasteboard.c + * + * Aqua pasteboard <-> X cut buffer + * Greg Parker gparker@cs.stanford.edu March 8, 2001 + **************************************************************/ +/* + * Copyright (c) 2001 Greg Parker. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name(s) of the above copyright + * holders shall not be used in advertising or otherwise to promote the sale, + * use or other dealings in this Software without prior written authorization. + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartzPasteboard.c,v 1.1 2002/03/28 02:21:19 torrey Exp $ */ + +#include "quartzPasteboard.h" + +#include "Xatom.h" +#include "windowstr.h" +#include "propertyst.h" +#include "scrnintstr.h" +#include "selection.h" +#include "globals.h" + +extern Selection *CurrentSelections; +extern int NumCurrentSelections; + + +// Helper function to read the X11 cut buffer +// FIXME: What about multiple screens? Currently, this reads the first +// CUT_BUFFER0 from the first screen where the buffer content is a string. +// Returns a string on the heap that the caller must free. +// Returns NULL if there is no cut text or there is not enough memory. +static char * QuartzReadCutBuffer(void) +{ + int i; + char *text = NULL; + + for (i = 0; i < screenInfo.numScreens; i++) { + ScreenPtr pScreen = screenInfo.screens[i]; + PropertyPtr pProp; + + pProp = wUserProps (WindowTable[pScreen->myNum]); + while (pProp && pProp->propertyName != XA_CUT_BUFFER0) { + pProp = pProp->next; + } + if (! pProp) continue; + if (pProp->type != XA_STRING) continue; + if (pProp->format != 8) continue; + + text = xalloc(1 + pProp->size); + if (! text) continue; + memcpy(text, pProp->data, pProp->size); + text[pProp->size] = '\0'; + return text; + } + + // didn't find any text + return NULL; +} + +// Write X cut buffer to Mac OS X pasteboard +// Called by ProcessInputEvents() in response to request from X server thread. +void QuartzWritePasteboard(void) +{ + char *text; + text = QuartzReadCutBuffer(); + if (text) { + QuartzWriteCocoaPasteboard(text); + free(text); + } +} + +#define strequal(a, b) (0 == strcmp((a), (b))) + +// Read Mac OS X pasteboard into X cut buffer +// Called by ProcessInputEvents() in response to request from X server thread. +void QuartzReadPasteboard(void) +{ + char *oldText = QuartzReadCutBuffer(); + char *text = QuartzReadCocoaPasteboard(); + + // Compare text with current cut buffer contents. + // Change the buffer if both exist and are different + // OR if there is new text but no old text. + // Otherwise, don't clear the selection unnecessarily. + + if ((text && oldText && !strequal(text, oldText)) || + (text && !oldText)) { + int scrn, sel; + + for (scrn = 0; scrn < screenInfo.numScreens; scrn++) { + ScreenPtr pScreen = screenInfo.screens[scrn]; + // Set the cut buffers on each screen + // fixme really on each screen? + ChangeWindowProperty(WindowTable[pScreen->myNum], XA_CUT_BUFFER0, + XA_STRING, 8, PropModeReplace, + strlen(text), (pointer)text, TRUE); + } + + // Undo any current X selection (similar to code in dispatch.c) + // FIXME: what about secondary selection? + // FIXME: only touch first XA_PRIMARY selection? + sel = 0; + while ((sel < NumCurrentSelections) && + CurrentSelections[sel].selection != XA_PRIMARY) + sel++; + if (sel < NumCurrentSelections) { + // Notify client if necessary + if (CurrentSelections[sel].client) { + xEvent event; + + event.u.u.type = SelectionClear; + event.u.selectionClear.time = GetTimeInMillis(); + event.u.selectionClear.window = CurrentSelections[sel].window; + event.u.selectionClear.atom = CurrentSelections[sel].selection; + TryClientEvents(CurrentSelections[sel].client, &event, 1, + NoEventMask, NoEventMask /*CantBeFiltered*/, + NullGrab); + } + + // Erase it + // FIXME: need to erase .selection too? dispatch.c doesn't + CurrentSelections[sel].pWin = NullWindow; + CurrentSelections[sel].window = None; + CurrentSelections[sel].client = NullClient; + } + } + + if (text) free(text); + if (oldText) free(oldText); +} diff --git a/hw/darwin/quartz/quartzPasteboard.h b/hw/darwin/quartz/quartzPasteboard.h new file mode 100644 index 000000000..fef375493 --- /dev/null +++ b/hw/darwin/quartz/quartzPasteboard.h @@ -0,0 +1,45 @@ +/* + QuartzPasteboard.h + + Mac OS X pasteboard <-> X cut buffer + Greg Parker gparker@cs.stanford.edu March 8, 2001 +*/ +/* + * Copyright (c) 2001 Greg Parker. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name(s) of the above copyright + * holders shall not be used in advertising or otherwise to promote the sale, + * use or other dealings in this Software without prior written authorization. + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartzPasteboard.h,v 1.1 2002/03/28 02:21:19 torrey Exp $ */ + +#ifndef _QUARTZPASTEBOARD_H +#define _QUARTZPASTEBOARD_H + +// Aqua->X +void QuartzReadPasteboard(); +char * QuartzReadCocoaPasteboard(void); // caller must free string + +// X->Aqua +void QuartzWritePasteboard(); +void QuartzWriteCocoaPasteboard(char *text); + +#endif /* _QUARTZPASTEBOARD_H */
\ No newline at end of file diff --git a/hw/darwin/quartz/quartzStartup.c b/hw/darwin/quartz/quartzStartup.c new file mode 100644 index 000000000..dfa7b8166 --- /dev/null +++ b/hw/darwin/quartz/quartzStartup.c @@ -0,0 +1,233 @@ +/************************************************************** + * + * Startup code for the Quartz Darwin X Server + * + **************************************************************/ +/* + * Copyright (c) 2001-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. + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartzStartup.c,v 1.3 2003/01/19 06:35:13 torrey Exp $ */ + +#include <fcntl.h> +#include <unistd.h> +#include <CoreFoundation/CoreFoundation.h> +#include "quartzCommon.h" +#include "darwin.h" +#include "opaque.h" +#include "micmap.h" + +int NSApplicationMain(int argc, char *argv[]); + +char **envpGlobal; // argcGlobal and argvGlobal + // are from dix/globals.c + +// GLX bundle function pointers +typedef void (*GlxExtensionInitPtr)(void); +static GlxExtensionInitPtr GlxExtensionInit = NULL; + +typedef void (*GlxWrapInitVisualsPtr)(miInitVisualsProcPtr *); +static GlxWrapInitVisualsPtr GlxWrapInitVisuals = NULL; + + +/* + * DarwinHandleGUI + * This function is called first from main(). The first time + * it is called we start the Mac OS X front end. The front end + * will call main() again from another thread to run the X + * server. On the second call this function loads the user + * preferences set by the Mac OS X front end. + */ +void DarwinHandleGUI( + int argc, + char *argv[], + char *envp[] ) +{ + static Bool been_here = FALSE; + int main_exit, i; + int fd[2]; + + if (been_here) { + QuartzReadPreferences(); + return; + } + been_here = TRUE; + + // Make a pipe to pass events + assert( pipe(fd) == 0 ); + darwinEventFD = fd[0]; + quartzEventWriteFD = fd[1]; + fcntl(darwinEventFD, F_SETFL, O_NONBLOCK); + + // Store command line arguments to pass back to main() + argcGlobal = argc; + argvGlobal = argv; + envpGlobal = envp; + + // Determine if we need to start X clients + // and what display mode to use + quartzStartClients = 1; + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-nostartx")) { + quartzStartClients = 0; + } else if (!strcmp( argv[i], "-fullscreen")) { + quartzRootless = 0; + } else if (!strcmp( argv[i], "-rootless")) { + quartzRootless = 1; + } + } + + quartz = TRUE; + main_exit = NSApplicationMain(argc, argv); + exit(main_exit); +} + + +/* + * LoadGlxBundle + * The Quartz mode X server needs to dynamically load the appropriate + * bundle before initializing GLX. + */ +static void LoadGlxBundle(void) +{ + CFBundleRef mainBundle; + CFStringRef bundleName; + CFURLRef bundleURL; + CFBundleRef glxBundle; + + // Get the main bundle for the application + mainBundle = CFBundleGetMainBundle(); + + // Choose the bundle to load + ErrorF("Loading GLX bundle "); + if (quartzUseAGL) { + bundleName = CFSTR("glxAGL.bundle"); + ErrorF("glxAGL.bundle (using Apple's OpenGL)\n"); + } else { + bundleName = CFSTR("glxMesa.bundle"); + ErrorF("glxMesa.bundle (using Mesa)\n"); + } + + // Look for the appropriate GLX bundle in the main bundle by name + bundleURL = CFBundleCopyResourceURL(mainBundle, bundleName, + NULL, NULL); + if (!bundleURL) { + FatalError("Could not find GLX bundle."); + } + + // Make a bundle instance using the URLRef + glxBundle = CFBundleCreate(kCFAllocatorDefault, bundleURL); + + if (!CFBundleLoadExecutable(glxBundle)) { + FatalError("Could not load GLX bundle."); + } + + // Find the GLX init functions + GlxExtensionInit = (void *) CFBundleGetFunctionPointerForName( + glxBundle, CFSTR("GlxExtensionInit")); + + GlxWrapInitVisuals = (void *) CFBundleGetFunctionPointerForName( + glxBundle, CFSTR("GlxWrapInitVisuals")); + + if (!GlxExtensionInit || !GlxWrapInitVisuals) { + FatalError("Could not initialize GLX bundle."); + } + + // Release the CF objects + CFRelease(mainBundle); + CFRelease(bundleURL); +} + + +/* + * DarwinGlxExtensionInit + * Initialize the GLX extension. + */ +void DarwinGlxExtensionInit(void) +{ + if (!GlxExtensionInit) + LoadGlxBundle(); + + GlxExtensionInit(); +} + + +/* + * DarwinGlxWrapInitVisuals + */ +void DarwinGlxWrapInitVisuals( + miInitVisualsProcPtr *procPtr) +{ + if (!GlxWrapInitVisuals) + LoadGlxBundle(); + + GlxWrapInitVisuals(procPtr); +} + + +int QuartzProcessArgument( int argc, char *argv[], int i ) +{ + // fullscreen: CoreGraphics full-screen mode + // rootless: Cocoa rootless mode + // quartz: Default, either fullscreen or rootless + + if ( !strcmp( argv[i], "-fullscreen" ) ) { + ErrorF( "Running full screen in parallel with Mac OS X Quartz window server.\n" ); +#ifdef QUARTZ_SAFETY_DELAY + ErrorF( "Quitting in %d seconds if no controller is found.\n", + QUARTZ_SAFETY_DELAY ); +#endif + return 1; + } + + if ( !strcmp( argv[i], "-rootless" ) ) { + ErrorF( "Running rootless inside Mac OS X window server.\n" ); +#ifdef QUARTZ_SAFETY_DELAY + ErrorF( "Quitting in %d seconds if no controller is found.\n", + QUARTZ_SAFETY_DELAY ); +#endif + return 1; + } + + if ( !strcmp( argv[i], "-quartz" ) ) { + ErrorF( "Running in parallel with Mac OS X Quartz window server.\n" ); +#ifdef QUARTZ_SAFETY_DELAY + ErrorF( "Quitting in %d seconds if no controller is found.\n", + QUARTZ_SAFETY_DELAY ); +#endif + return 1; + } + + // The Mac OS X front end uses this argument, which we just ignore here. + if ( !strcmp( argv[i], "-nostartx" ) ) { + return 1; + } + + // This command line arg is passed when launched from the Aqua GUI. + if ( !strncmp( argv[i], "-psn_", 5 ) ) { + return 1; + } + + return 0; +}
\ No newline at end of file |