From fa06e11f972e2a75c84b2f1586997ffc1239cbd9 Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Mon, 26 Feb 2007 17:06:53 -0800 Subject: [PATCH] added hw/darwin/apple directory, which contains source and data files to build a version of the X11.app shipped with Mac OS X, using the X.org server. --- .../apple/English.lproj/InfoPlist.strings | Bin 0 -> 276 bytes .../apple/English.lproj/main.nib/.svn/entries | 65 + .../apple/English.lproj/main.nib/.svn/format | 1 + .../.svn/prop-base/keyedobjects.nib.svn-base | 5 + .../.svn/text-base/classes.nib.svn-base | 318 +++++ .../main.nib/.svn/text-base/info.nib.svn-base | 18 + .../.svn/text-base/keyedobjects.nib.svn-base | Bin 0 -> 30865 bytes .../apple/English.lproj/main.nib/classes.nib | 318 +++++ .../apple/English.lproj/main.nib/info.nib | 18 + .../English.lproj/main.nib/keyedobjects.nib | Bin 0 -> 30865 bytes hw/darwin/apple/Info.plist | 71 + hw/darwin/apple/X11.icns | Bin 0 -> 28104 bytes hw/darwin/apple/X11.xcodeproj/project.pbxproj | 329 +++++ hw/darwin/apple/X11Application.h | 104 ++ hw/darwin/apple/X11Application.m | 1138 +++++++++++++++++ hw/darwin/apple/X11Controller.h | 86 ++ hw/darwin/apple/X11Controller.m | 752 +++++++++++ hw/darwin/apple/Xquartz.man | 158 +++ hw/darwin/apple/bundle-main.c | 911 +++++++++++++ 19 files changed, 4292 insertions(+) create mode 100644 hw/darwin/apple/English.lproj/InfoPlist.strings create mode 100644 hw/darwin/apple/English.lproj/main.nib/.svn/entries create mode 100644 hw/darwin/apple/English.lproj/main.nib/.svn/format create mode 100644 hw/darwin/apple/English.lproj/main.nib/.svn/prop-base/keyedobjects.nib.svn-base create mode 100644 hw/darwin/apple/English.lproj/main.nib/.svn/text-base/classes.nib.svn-base create mode 100644 hw/darwin/apple/English.lproj/main.nib/.svn/text-base/info.nib.svn-base create mode 100644 hw/darwin/apple/English.lproj/main.nib/.svn/text-base/keyedobjects.nib.svn-base create mode 100644 hw/darwin/apple/English.lproj/main.nib/classes.nib create mode 100644 hw/darwin/apple/English.lproj/main.nib/info.nib create mode 100644 hw/darwin/apple/English.lproj/main.nib/keyedobjects.nib create mode 100644 hw/darwin/apple/Info.plist create mode 100644 hw/darwin/apple/X11.icns create mode 100644 hw/darwin/apple/X11.xcodeproj/project.pbxproj create mode 100644 hw/darwin/apple/X11Application.h create mode 100644 hw/darwin/apple/X11Application.m create mode 100644 hw/darwin/apple/X11Controller.h create mode 100644 hw/darwin/apple/X11Controller.m create mode 100644 hw/darwin/apple/Xquartz.man create mode 100644 hw/darwin/apple/bundle-main.c diff --git a/hw/darwin/apple/English.lproj/InfoPlist.strings b/hw/darwin/apple/English.lproj/InfoPlist.strings new file mode 100644 index 0000000000000000000000000000000000000000..88e1f04ac78e9f0b14a2b6fa57a4a02ae91d8edd GIT binary patch literal 276 zcmZwCK}!Nr6o%nv?XNhvlo&@hEuuvUMG$S;v=zPDpv@heDX<@3;SE|y`}gBK=j+?l zM0k{~EbTQuC2QeBa?opJtzO7B!h_aER_RLL8-$(YSgMJsk&%Tvx8AkZ_L3({Z<25= zjJ=qd8N2$Yy_XDsm!1s{8m;Zw`dk_2Dzyt?A?qB=a_hAy=W4Y};YL^dC(r4lmFm~> E0}i$=GXMYp literal 0 HcmV?d00001 diff --git a/hw/darwin/apple/English.lproj/main.nib/.svn/entries b/hw/darwin/apple/English.lproj/main.nib/.svn/entries new file mode 100644 index 000000000..95a15f220 --- /dev/null +++ b/hw/darwin/apple/English.lproj/main.nib/.svn/entries @@ -0,0 +1,65 @@ +8 + +dir +29110 +svn+ssh://src.apple.com/svn/BSD/X11server/trunk/darwin/apple/English.lproj/main.nib +svn+ssh://src.apple.com/svn/BSD + + + +2007-02-03T03:06:20.842932Z +28761 +bbyer + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +e92bca22-270c-0410-9cea-e3f1106b6a1c + +info.nib +file + + + + +2007-02-27T01:00:07.000000Z +456347804c516786b1d1339ce2ef50a2 +2007-02-03T03:06:20.842932Z +28761 +bbyer + +keyedobjects.nib +file + + + + +2007-02-27T01:00:07.000000Z +eb3010372b09768c846df0d996cfdd8d +2007-02-03T03:06:20.842932Z +28761 +bbyer +has-props + +classes.nib +file + + + + +2007-02-27T01:00:07.000000Z +0ae2660c3afabbd5aa02fc34712c96e6 +2007-02-03T03:06:20.842932Z +28761 +bbyer + diff --git a/hw/darwin/apple/English.lproj/main.nib/.svn/format b/hw/darwin/apple/English.lproj/main.nib/.svn/format new file mode 100644 index 000000000..45a4fb75d --- /dev/null +++ b/hw/darwin/apple/English.lproj/main.nib/.svn/format @@ -0,0 +1 @@ +8 diff --git a/hw/darwin/apple/English.lproj/main.nib/.svn/prop-base/keyedobjects.nib.svn-base b/hw/darwin/apple/English.lproj/main.nib/.svn/prop-base/keyedobjects.nib.svn-base new file mode 100644 index 000000000..5e9587e65 --- /dev/null +++ b/hw/darwin/apple/English.lproj/main.nib/.svn/prop-base/keyedobjects.nib.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/hw/darwin/apple/English.lproj/main.nib/.svn/text-base/classes.nib.svn-base b/hw/darwin/apple/English.lproj/main.nib/.svn/text-base/classes.nib.svn-base new file mode 100644 index 000000000..a82159bd5 --- /dev/null +++ b/hw/darwin/apple/English.lproj/main.nib/.svn/text-base/classes.nib.svn-base @@ -0,0 +1,318 @@ + + + + + IBClasses + + + CLASS + IBLibraryObjectTemplate + LANGUAGE + ObjC + OUTLETS + + draggedView + NSView + representedObject + NSObject + + SUPERCLASS + NSView + + + CLASS + IBInspector + LANGUAGE + ObjC + OUTLETS + + inspectorView + NSView + + SUPERCLASS + NSObject + + + CLASS + NSDateFormatter + LANGUAGE + ObjC + SUPERCLASS + NSFormatter + + + ACTIONS + + apps_table_cancel + id + apps_table_delete + id + apps_table_done + id + apps_table_duplicate + id + apps_table_new + id + apps_table_show + id + bring_to_front + id + close_window + id + enable_fullscreen_changed + id + minimize_window + id + next_window + id + prefs_changed + id + prefs_show + id + previous_window + id + toggle_fullscreen + id + x11_help + id + zoom_window + id + + CLASS + X11Controller + LANGUAGE + ObjC + OUTLETS + + apps_separator + id + apps_table + id + depth + id + dock_apps_menu + id + dock_menu + id + dock_window_separator + id + enable_auth + id + enable_fullscreen + id + enable_keyequivs + id + enable_tcp + id + fake_buttons + id + prefs_panel + id + sync_keymap + id + toggle_fullscreen_item + id + use_sysbeep + id + window_separator + id + x11_about_item + id + + SUPERCLASS + NSObject + + + CLASS + NSNumberFormatter + LANGUAGE + ObjC + SUPERCLASS + NSFormatter + + + CLASS + NSFormatter + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + ACTIONS + + alignCenter: + id + alignJustified: + id + alignLeft: + id + alignRight: + id + arrangeInFront: + id + centerSelectionInVisibleArea: + id + changeFont: + id + checkSpelling: + id + clear: + id + clearRecentDocuments: + id + complete: + id + copy: + id + copyFont: + id + copyRuler: + id + cut: + id + delete: + id + deminiaturize: + id + fax: + id + hide: + id + hideOtherApplications: + id + loosenKerning: + id + lowerBaseline: + id + makeKeyAndOrderFront: + id + miniaturize: + id + newDocument: + id + openDocument: + id + orderBack: + id + orderFront: + id + orderFrontColorPanel: + id + orderFrontHelpPanel: + id + orderOut: + id + outline: + id + paste: + id + pasteAsPlainText: + id + pasteAsRichText: + id + pasteFont: + id + pasteRuler: + id + pause: + id + performClose: + id + performFindPanelAction: + id + performMiniaturize: + id + performZoom: + id + play: + id + print: + id + printDocument: + id + raiseBaseline: + id + record: + id + redo: + id + resume: + id + revertDocumentToSaved: + id + run: + id + runPageLayout: + id + runToolbarCustomizationPalette: + id + saveAllDocuments: + id + saveDocument: + id + saveDocumentAs: + id + saveDocumentTo: + id + selectAll: + id + selectText: + id + showGuessPanel: + id + showHelp: + id + start: + id + startSpeaking: + id + stop: + id + stopSpeaking: + id + subscript: + id + superscript: + id + terminate: + id + tightenKerning: + id + toggleContinuousSpellChecking: + id + toggleRuler: + id + toggleToolbarShown: + id + turnOffKerning: + id + turnOffLigatures: + id + underline: + id + undo: + id + unhideAllApplications: + id + unscript: + id + useAllLigatures: + id + useStandardKerning: + id + useStandardLigatures: + id + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + IBVersion + 1 + + diff --git a/hw/darwin/apple/English.lproj/main.nib/.svn/text-base/info.nib.svn-base b/hw/darwin/apple/English.lproj/main.nib/.svn/text-base/info.nib.svn-base new file mode 100644 index 000000000..88bc6260d --- /dev/null +++ b/hw/darwin/apple/English.lproj/main.nib/.svn/text-base/info.nib.svn-base @@ -0,0 +1,18 @@ + + + + + IBFramework Version + 588 + IBOpenObjects + + 244 + 29 + 423 + + IBSystem Version + 9A356 + targetFramework + IBCocoaFramework + + diff --git a/hw/darwin/apple/English.lproj/main.nib/.svn/text-base/keyedobjects.nib.svn-base b/hw/darwin/apple/English.lproj/main.nib/.svn/text-base/keyedobjects.nib.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..8b31450ff5c9a6357f70baf56268899dee194109 GIT binary patch literal 30865 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 + + + + IBClasses + + + CLASS + IBLibraryObjectTemplate + LANGUAGE + ObjC + OUTLETS + + draggedView + NSView + representedObject + NSObject + + SUPERCLASS + NSView + + + CLASS + IBInspector + LANGUAGE + ObjC + OUTLETS + + inspectorView + NSView + + SUPERCLASS + NSObject + + + CLASS + NSDateFormatter + LANGUAGE + ObjC + SUPERCLASS + NSFormatter + + + ACTIONS + + apps_table_cancel + id + apps_table_delete + id + apps_table_done + id + apps_table_duplicate + id + apps_table_new + id + apps_table_show + id + bring_to_front + id + close_window + id + enable_fullscreen_changed + id + minimize_window + id + next_window + id + prefs_changed + id + prefs_show + id + previous_window + id + toggle_fullscreen + id + x11_help + id + zoom_window + id + + CLASS + X11Controller + LANGUAGE + ObjC + OUTLETS + + apps_separator + id + apps_table + id + depth + id + dock_apps_menu + id + dock_menu + id + dock_window_separator + id + enable_auth + id + enable_fullscreen + id + enable_keyequivs + id + enable_tcp + id + fake_buttons + id + prefs_panel + id + sync_keymap + id + toggle_fullscreen_item + id + use_sysbeep + id + window_separator + id + x11_about_item + id + + SUPERCLASS + NSObject + + + CLASS + NSNumberFormatter + LANGUAGE + ObjC + SUPERCLASS + NSFormatter + + + CLASS + NSFormatter + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + ACTIONS + + alignCenter: + id + alignJustified: + id + alignLeft: + id + alignRight: + id + arrangeInFront: + id + centerSelectionInVisibleArea: + id + changeFont: + id + checkSpelling: + id + clear: + id + clearRecentDocuments: + id + complete: + id + copy: + id + copyFont: + id + copyRuler: + id + cut: + id + delete: + id + deminiaturize: + id + fax: + id + hide: + id + hideOtherApplications: + id + loosenKerning: + id + lowerBaseline: + id + makeKeyAndOrderFront: + id + miniaturize: + id + newDocument: + id + openDocument: + id + orderBack: + id + orderFront: + id + orderFrontColorPanel: + id + orderFrontHelpPanel: + id + orderOut: + id + outline: + id + paste: + id + pasteAsPlainText: + id + pasteAsRichText: + id + pasteFont: + id + pasteRuler: + id + pause: + id + performClose: + id + performFindPanelAction: + id + performMiniaturize: + id + performZoom: + id + play: + id + print: + id + printDocument: + id + raiseBaseline: + id + record: + id + redo: + id + resume: + id + revertDocumentToSaved: + id + run: + id + runPageLayout: + id + runToolbarCustomizationPalette: + id + saveAllDocuments: + id + saveDocument: + id + saveDocumentAs: + id + saveDocumentTo: + id + selectAll: + id + selectText: + id + showGuessPanel: + id + showHelp: + id + start: + id + startSpeaking: + id + stop: + id + stopSpeaking: + id + subscript: + id + superscript: + id + terminate: + id + tightenKerning: + id + toggleContinuousSpellChecking: + id + toggleRuler: + id + toggleToolbarShown: + id + turnOffKerning: + id + turnOffLigatures: + id + underline: + id + undo: + id + unhideAllApplications: + id + unscript: + id + useAllLigatures: + id + useStandardKerning: + id + useStandardLigatures: + id + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + IBVersion + 1 + + diff --git a/hw/darwin/apple/English.lproj/main.nib/info.nib b/hw/darwin/apple/English.lproj/main.nib/info.nib new file mode 100644 index 000000000..88bc6260d --- /dev/null +++ b/hw/darwin/apple/English.lproj/main.nib/info.nib @@ -0,0 +1,18 @@ + + + + + IBFramework Version + 588 + IBOpenObjects + + 244 + 29 + 423 + + IBSystem Version + 9A356 + targetFramework + IBCocoaFramework + + diff --git a/hw/darwin/apple/English.lproj/main.nib/keyedobjects.nib b/hw/darwin/apple/English.lproj/main.nib/keyedobjects.nib new file mode 100644 index 0000000000000000000000000000000000000000..8b31450ff5c9a6357f70baf56268899dee194109 GIT binary patch literal 30865 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 + + + + CFBundleDevelopmentRegion + English + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + x11app + + CFBundleTypeIconFile + X11.icns + CFBundleTypeName + X11 Application + CFBundleTypeOSTypes + + **** + + CFBundleTypeRole + Viewer + LSIsAppleDefaultForType + + + + CFBundleTypeExtensions + + tool + * + + CFBundleTypeName + UNIX Application + CFBundleTypeOSTypes + + **** + + CFBundleTypeRole + Viewer + + + CFBundleExecutable + X11 + CFBundleGetInfoString + X11 + CFBundleIconFile + X11.icns + CFBundleIdentifier + org.x.X11 + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + X11 + CFBundlePackageType + APPL + CFBundleShortVersionString + 2.0 + CFBundleSignature + ???? + CSResourcesFileMapped + + NSHumanReadableCopyright + Copyright © 2003-2007, Apple Inc. +Copyright © 2003, XFree86 Project, Inc. + NSMainNibFile + main + NSPrincipalClass + X11Application + + diff --git a/hw/darwin/apple/X11.icns b/hw/darwin/apple/X11.icns new file mode 100644 index 0000000000000000000000000000000000000000..4c4717726399030db37efe54e4d95f3d746855ec GIT binary patch literal 28104 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 literal 0 HcmV?d00001 diff --git a/hw/darwin/apple/X11.xcodeproj/project.pbxproj b/hw/darwin/apple/X11.xcodeproj/project.pbxproj new file mode 100644 index 000000000..7ca75d498 --- /dev/null +++ b/hw/darwin/apple/X11.xcodeproj/project.pbxproj @@ -0,0 +1,329 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 527F24190B5D938C007840A7 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */; }; + 527F241A0B5D938C007840A7 /* main.nib in Resources */ = {isa = PBXBuildFile; fileRef = 02345980000FD03B11CA0E72 /* main.nib */; }; + 527F241B0B5D938C007840A7 /* X11.icns in Resources */ = {isa = PBXBuildFile; fileRef = 50459C5F038587C60ECA21EC /* X11.icns */; }; + 527F241D0B5D938C007840A7 /* bundle-main.c in Sources */ = {isa = PBXBuildFile; fileRef = 50EE2AB703849F0B0ECA21EC /* bundle-main.c */; }; + 527F241F0B5D938C007840A7 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F4F0A7039D6ACA0E82C0CB /* CoreFoundation.framework */; }; + 527F24200B5D938C007840A7 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 570C5748047186C400ACF82F /* SystemConfiguration.framework */; }; + 527F24370B5D9D89007840A7 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 527F24260B5D938C007840A7 /* Info.plist */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 0867D6ABFE840B52C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; + 1870340FFE93FCAF11CA0CD7 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/main.nib; sourceTree = ""; }; + 50459C5F038587C60ECA21EC /* X11.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = X11.icns; sourceTree = ""; }; + 50EE2AB703849F0B0ECA21EC /* bundle-main.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = "bundle-main.c"; sourceTree = ""; }; + 50F4F0A7039D6ACA0E82C0CB /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = ""; }; + 527F24260B5D938C007840A7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = Info.plist; sourceTree = ""; }; + 527F24270B5D938C007840A7 /* X11.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = X11.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 570C5748047186C400ACF82F /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = /System/Library/Frameworks/SystemConfiguration.framework; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 527F241E0B5D938C007840A7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 527F241F0B5D938C007840A7 /* CoreFoundation.framework in Frameworks */, + 527F24200B5D938C007840A7 /* SystemConfiguration.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 195DF8CFFE9D517E11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 527F24270B5D938C007840A7 /* X11.app */, + ); + name = Products; + sourceTree = ""; + }; + 20286C29FDCF999611CA2CEA /* X11 */ = { + isa = PBXGroup; + children = ( + 20286C2AFDCF999611CA2CEA /* Sources */, + 20286C2CFDCF999611CA2CEA /* Resources */, + 20286C32FDCF999611CA2CEA /* External Frameworks and Libraries */, + 195DF8CFFE9D517E11CA2CBB /* Products */, + 527F24260B5D938C007840A7 /* Info.plist */, + ); + name = X11; + sourceTree = ""; + }; + 20286C2AFDCF999611CA2CEA /* Sources */ = { + isa = PBXGroup; + children = ( + 50EE2AB703849F0B0ECA21EC /* bundle-main.c */, + ); + name = Sources; + sourceTree = ""; + }; + 20286C2CFDCF999611CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 50459C5F038587C60ECA21EC /* X11.icns */, + 0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */, + 02345980000FD03B11CA0E72 /* main.nib */, + ); + name = Resources; + sourceTree = ""; + }; + 20286C32FDCF999611CA2CEA /* External Frameworks and Libraries */ = { + isa = PBXGroup; + children = ( + 50F4F0A7039D6ACA0E82C0CB /* CoreFoundation.framework */, + 570C5748047186C400ACF82F /* SystemConfiguration.framework */, + ); + name = "External Frameworks and Libraries"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 527F24170B5D938C007840A7 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 527F24160B5D938C007840A7 /* X11 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 527F24220B5D938C007840A7 /* Build configuration list for PBXNativeTarget "X11" */; + buildPhases = ( + 527F24170B5D938C007840A7 /* Headers */, + 527F24180B5D938C007840A7 /* Resources */, + 527F241C0B5D938C007840A7 /* Sources */, + 527F241E0B5D938C007840A7 /* Frameworks */, + 527F24210B5D938C007840A7 /* Rez */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = X11; + productName = X11; + productReference = 527F24270B5D938C007840A7 /* X11.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 20286C28FDCF999611CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 527F24080B5D8FFC007840A7 /* Build configuration list for PBXProject "X11" */; + compatibilityVersion = "Xcode 2.4"; + hasScannedForEncodings = 1; + mainGroup = 20286C29FDCF999611CA2CEA /* X11 */; + projectDirPath = ""; + projectRoot = ""; + shouldCheckCompatibility = 1; + targets = ( + 527F24160B5D938C007840A7 /* X11 */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 527F24180B5D938C007840A7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 527F24370B5D9D89007840A7 /* Info.plist in Resources */, + 527F24190B5D938C007840A7 /* InfoPlist.strings in Resources */, + 527F241A0B5D938C007840A7 /* main.nib in Resources */, + 527F241B0B5D938C007840A7 /* X11.icns in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXRezBuildPhase section */ + 527F24210B5D938C007840A7 /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXRezBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 527F241C0B5D938C007840A7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 527F241D0B5D938C007840A7 /* bundle-main.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 02345980000FD03B11CA0E72 /* main.nib */ = { + isa = PBXVariantGroup; + children = ( + 1870340FFE93FCAF11CA0CD7 /* English */, + ); + name = main.nib; + sourceTree = ""; + }; + 0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 0867D6ABFE840B52C02AAC07 /* English */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 527F24090B5D8FFC007840A7 /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + DSTROOT = "$(DSTROOT)"; + SKIP_INSTALL = YES; + }; + name = Development; + }; + 527F240A0B5D8FFC007840A7 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + DSTROOT = "$(DSTROOT)"; + SKIP_INSTALL = YES; + }; + name = Deployment; + }; + 527F240B0B5D8FFC007840A7 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + DSTROOT = "$(DSTROOT)"; + SKIP_INSTALL = YES; + }; + name = Default; + }; + 527F24230B5D938C007840A7 /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(NATIVE_ARCH_32_BIT)"; + COPY_PHASE_STRIP = NO; + DSTROOT = "$(DSTROOT)"; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + HEADER_SEARCH_PATHS = /usr/X11/include; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = $DSTROOT/Applications/Utilties; + LIBRARY_SEARCH_PATHS = /usr/X11/lib; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-lXau", + "-lX11", + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = X11; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + WRAPPER_EXTENSION = app; + }; + name = Development; + }; + 527F24240B5D938C007840A7 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DSTROOT = "$(DSTROOT)"; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + HEADER_SEARCH_PATHS = /usr/X11/include; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = $DSTROOT/Applications/Utilties; + LIBRARY_SEARCH_PATHS = /usr/X11/lib; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-lXau", + "-lX11", + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = X11; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + WRAPPER_EXTENSION = app; + }; + name = Deployment; + }; + 527F24250B5D938C007840A7 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + DSTROOT = "$(DSTROOT)"; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + HEADER_SEARCH_PATHS = /usr/X11/include; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = $DSTROOT/Applications/Utilties; + LIBRARY_SEARCH_PATHS = /usr/X11/lib; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-lXau", + "-lX11", + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = X11; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + WRAPPER_EXTENSION = app; + }; + name = Default; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 527F24080B5D8FFC007840A7 /* Build configuration list for PBXProject "X11" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 527F24090B5D8FFC007840A7 /* Development */, + 527F240A0B5D8FFC007840A7 /* Deployment */, + 527F240B0B5D8FFC007840A7 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; + 527F24220B5D938C007840A7 /* Build configuration list for PBXNativeTarget "X11" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 527F24230B5D938C007840A7 /* Development */, + 527F24240B5D938C007840A7 /* Deployment */, + 527F24250B5D938C007840A7 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; +/* End XCConfigurationList section */ + }; + rootObject = 20286C28FDCF999611CA2CEA /* Project object */; +} diff --git a/hw/darwin/apple/X11Application.h b/hw/darwin/apple/X11Application.h new file mode 100644 index 000000000..b9d2af8bf --- /dev/null +++ b/hw/darwin/apple/X11Application.h @@ -0,0 +1,104 @@ +/* X11Application.h -- subclass of NSApplication to multiplex events + $Id: X11Application.h,v 1.26 2003/08/08 19:16:13 jharper Exp $ + + Copyright (c) 2002-2007 Apple Inc. All rights reserved. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT + HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name(s) of the above + copyright holders shall not be used in advertising or otherwise to + promote the sale, use or other dealings in this Software without + prior written authorization. */ + +#ifndef X11APPLICATION_H +#define X11APPLICATION_H 1 + +#if __OBJC__ + +#import +#import "X11Controller.h" + +@interface X11Application : NSApplication { + X11Controller *_controller; + + unsigned int _x_active :1; +} + +- (void) set_controller:controller; +- (void) set_window_menu:(NSArray *)list; + +- (int) prefs_get_integer:(NSString *)key default:(int)def; +- (const char *) prefs_get_string:(NSString *)key default:(const char *)def; +- (float) prefs_get_float:(NSString *)key default:(float)def; +- (int) prefs_get_boolean:(NSString *)key default:(int)def; +- (NSArray *) prefs_get_array:(NSString *)key; +- (void) prefs_set_integer:(NSString *)key value:(int)value; +- (void) prefs_set_float:(NSString *)key value:(float)value; +- (void) prefs_set_boolean:(NSString *)key value:(int)value; +- (void) prefs_set_array:(NSString *)key value:(NSArray *)value; +- (void) prefs_set_string:(NSString *)key value:(NSString *)value; +- (void) prefs_synchronize; + +- (BOOL) x_active; + +@end + +extern X11Application *X11App; + +#endif /* __OBJC__ */ + +extern void X11ApplicationSetWindowMenu (int nitems, const char **items, + const char *shortcuts); +extern void X11ApplicationSetWindowMenuCheck (int idx); +extern void X11ApplicationSetFrontProcess (void); +extern void X11ApplicationSetCanQuit (int state); +extern void X11ApplicationServerReady (void); +extern void X11ApplicationShowHideMenubar (int state); + +extern void X11ApplicationMain (int argc, const char *argv[], + void (*server_thread) (void *), + void *server_arg); + +extern int X11EnableKeyEquivalents; +extern int quartzHasRoot, quartzEnableRootless; + +#define APP_PREFS "com.apple.x11" + +#define PREFS_APPSMENU "apps_menu" +#define PREFS_FAKEBUTTONS "enable_fake_buttons" +#define PREFS_SYSBEEP "enable_system_beep" +#define PREFS_KEYEQUIVS "enable_key_equivalents" +#define PREFS_KEYMAP_FILE "keymap_file" +#define PREFS_SYNC_KEYMAP "sync_keymap" +#define PREFS_DEPTH "depth" +#define PREFS_NO_AUTH "no_auth" +#define PREFS_NO_TCP "nolisten_tcp" +#define PREFS_DONE_XINIT_CHECK "done_xinit_check" +#define PREFS_NO_QUIT_ALERT "no_quit_alert" +#define PREFS_FAKE_BUTTON2 "fake_button2" +#define PREFS_FAKE_BUTTON3 "fake_button3" +#define PREFS_ROOTLESS "rootless" +#define PREFS_FULLSCREEN_HOTKEYS "fullscreen_hotkeys" +#define PREFS_SWAP_ALT_META "swap_alt_meta" +#define PREFS_XP_OPTIONS "xp_options" +#define PREFS_ENABLE_STEREO "enable_stereo" + +#endif /* X11APPLICATION_H */ diff --git a/hw/darwin/apple/X11Application.m b/hw/darwin/apple/X11Application.m new file mode 100644 index 000000000..5da057469 --- /dev/null +++ b/hw/darwin/apple/X11Application.m @@ -0,0 +1,1138 @@ +/* X11Application.m -- subclass of NSApplication to multiplex events + $Id: X11Application.m,v 1.59 2006/09/06 21:19:32 jharper Exp $ + + Copyright (c) 2002-2007 Apple Inc. All rights reserved. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT + HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name(s) of the above + copyright holders shall not be used in advertising or otherwise to + promote the sale, use or other dealings in this Software without + prior written authorization. */ + +#include "../quartz/quartzCommon.h" + +#import "X11Application.h" +#include + +/* ouch! */ +#define BOOL X_BOOL +//# include "Xproto.h" +# include "darwin.h" +# include "../quartz/quartz.h" +# define _APPLEWM_SERVER_ +# include "X11/extensions/applewm.h" +//# include "X.h" +# include "micmap.h" +#undef BOOL + +#include "xf86Version.h" + +#include +#include +#include + +#define DEFAULTS_FILE "/etc/X11/xserver/Xquartz.plist" + +int X11EnableKeyEquivalents = TRUE; +int quartzHasRoot = FALSE, quartzEnableRootless = TRUE; + +extern int darwinFakeButtons; +// extern Bool enable_stereo; +Bool enable_stereo; //<-- this needs to go back to being an extern once glxCGL is fixed + + +X11Application *X11App; + +#define ALL_KEY_MASKS (NSShiftKeyMask | NSControlKeyMask \ +| NSAlternateKeyMask | NSCommandKeyMask) + +@implementation X11Application + +typedef struct message_struct message; +struct message_struct { + mach_msg_header_t hdr; + SEL selector; + NSObject *arg; +}; + +static mach_port_t _port; + +static void send_nsevent (NSEventType type, NSEvent *e); + +/* Quartz mode initialization routine. This is often dynamically loaded + but is statically linked into this X server. */ +extern Bool QuartzModeBundleInit(void); + +static void +init_ports (void) +{ + kern_return_t r; + NSPort *p; + + if (_port != MACH_PORT_NULL) + return; + + r = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &_port); + if (r != KERN_SUCCESS) + return; + + p = [NSMachPort portWithMachPort:_port]; + [p setDelegate:NSApp]; + [p scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; +} + +static void +message_kit_thread (SEL selector, NSObject *arg) +{ + message msg; + kern_return_t r; + + msg.hdr.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_MAKE_SEND, 0); + msg.hdr.msgh_size = sizeof (msg); + msg.hdr.msgh_remote_port = _port; + msg.hdr.msgh_local_port = MACH_PORT_NULL; + msg.hdr.msgh_reserved = 0; + msg.hdr.msgh_id = 0; + + msg.selector = selector; + msg.arg = [arg retain]; + + r = mach_msg (&msg.hdr, MACH_SEND_MSG, msg.hdr.msgh_size, + 0, MACH_PORT_NULL, 0, MACH_PORT_NULL); + if (r != KERN_SUCCESS) + fprintf (stderr, "%s: mach_msg failed: %x\n", __FUNCTION__, r); +} + +- (void) handleMachMessage:(void *)_msg +{ + message *msg = _msg; + + [self performSelector:msg->selector withObject:msg->arg]; + [msg->arg release]; +} + +- (void) set_controller:obj +{ + if (_controller == nil) + _controller = [obj retain]; +} + +- (void) dealloc +{ + if (_controller != nil) + [_controller release]; + + if (_port != MACH_PORT_NULL) + mach_port_deallocate (mach_task_self (), _port); + + [super dealloc]; +} + +- (void) orderFrontStandardAboutPanel: (id) sender +{ + NSMutableDictionary *dict; + NSDictionary *infoDict; + NSString *tem; + + dict = [NSMutableDictionary dictionaryWithCapacity:2]; + infoDict = [[NSBundle mainBundle] infoDictionary]; + + [dict setObject: NSLocalizedString (@"The X Window System", @"About panel") + forKey:@"ApplicationName"]; + + tem = [infoDict objectForKey:@"CFBundleShortVersionString"]; + + [dict setObject:[NSString stringWithFormat:@"X11.app %@ - X.org X11R7.1", + tem] forKey:@"ApplicationVersion"]; + + [self orderFrontStandardAboutPanelWithOptions: dict]; +} + +- (void) activateX:(BOOL)state +{ + /* Create a TSM document that supports full Unicode input, and + have it activated while X is active (unless using the old + keymapping files) */ + static TSMDocumentID x11_document; + + if (state) + { + QuartzMessageServerThread (kXDarwinActivate, 0); + + if (!_x_active) + { + if (x11_document == 0 && darwinKeymapFile == NULL) + { + OSType types[1]; + types[0] = kUnicodeDocument; + NewTSMDocument (1, types, &x11_document, 0); + } + + if (x11_document != 0) + ActivateTSMDocument (x11_document); + } + } + else + { + QuartzMessageServerThread (kXDarwinDeactivate, 0); + + if (_x_active) + { + if (x11_document != 0) + DeactivateTSMDocument (x11_document); + } + } + + _x_active = state; +} + +- (void) became_key:(NSWindow *)win +{ + [self activateX:NO]; +} + +- (void) sendEvent:(NSEvent *)e +{ + NSEventType type; + BOOL for_appkit, for_x; + + type = [e type]; + + /* By default pass down the responder chain and to X. */ + for_appkit = YES; + for_x = YES; + + switch (type) + { + case NSLeftMouseDown: case NSRightMouseDown: case NSOtherMouseDown: + case NSLeftMouseUp: case NSRightMouseUp: case NSOtherMouseUp: + if ([e window] != nil) + { + /* Pointer event has a window. Probably something for the kit. */ + + for_x = NO; + + if (_x_active) + [self activateX:NO]; + } + else if ([self modalWindow] == nil) + { + /* Must be an X window. Tell appkit it doesn't have focus. */ + + for_appkit = NO; + + if ([self isActive]) + { + [self deactivate]; + + if (!_x_active && quartzProcs->IsX11Window([e window], + [e windowNumber])) + [self activateX:YES]; + } + } + break; + + case NSKeyDown: case NSKeyUp: + if (_x_active) + { + static int swallow_up; + + /* No kit window is focused, so send it to X. */ + + for_appkit = NO; + + if (type == NSKeyDown) + { + /* Before that though, see if there are any global + shortcuts bound to it. */ + + if (X11EnableKeyEquivalents + && [[self mainMenu] performKeyEquivalent:e]) + { + swallow_up = [e keyCode]; + for_x = NO; + } + else if (!quartzEnableRootless + && ([e modifierFlags] & ALL_KEY_MASKS) + == (NSCommandKeyMask | NSAlternateKeyMask) + && ([e keyCode] == 0 /*a*/ + || [e keyCode] == 53 /*Esc*/)) + { + swallow_up = 0; + for_x = NO; +#ifdef DARWIN_DDX_MISSING + QuartzMessageServerThread (kXDarwinToggleFullscreen, 0); +#endif + } + } + else + { + /* If we saw a key equivalent on the down, don't pass + the up through to X. */ + + if (swallow_up != 0 && [e keyCode] == swallow_up) + { + swallow_up = 0; + for_x = NO; + } + } + } + else + { + for_x = NO; + } + break; + + case NSFlagsChanged: + /* For the l33t X users who remap modifier keys to normal keysyms. */ + if (!_x_active) + for_x = NO; + break; + + case NSAppKitDefined: + switch ([e subtype]) + { + case NSApplicationActivatedEventType: + for_x = NO; + if ([self modalWindow] == nil) + { + for_appkit = NO; + + /* FIXME: hack to avoid having to pass the event to appkit, + which would cause it to raise one of its windows. */ + _appFlags._active = YES; + + [self activateX:YES]; +#ifdef DARWIN_DDX_MISSING + if ([e data2] & 0x10) QuartzMessageServerThread (kXDarwinBringAllToFront, 0); +#endif + } + break; + + case 18: /* ApplicationDidReactivate */ + if (quartzHasRoot) + for_appkit = NO; + break; + + case NSApplicationDeactivatedEventType: + for_x = NO; + [self activateX:NO]; + break; + } + break; + + default: break; /* for gcc */ + } + + if (for_appkit) + { + [super sendEvent:e]; + } + + if (for_x) + { + send_nsevent (type, e); + } +} + +- (void) set_window_menu:(NSArray *)list +{ + [_controller set_window_menu:list]; +} + +- (void) set_window_menu_check:(NSNumber *)n +{ + [_controller set_window_menu_check:n]; +} + +- (void) set_apps_menu:(NSArray *)list +{ + [_controller set_apps_menu:list]; +} + +- (void) set_front_process:unused +{ + [NSApp activateIgnoringOtherApps:YES]; + + if ([self modalWindow] == nil) + [self activateX:YES]; +} + +- (void) set_can_quit:(NSNumber *)state +{ + [_controller set_can_quit:[state boolValue]]; +} + +- (void) server_ready:unused +{ + [_controller server_ready]; +} + +- (void) show_hide_menubar:(NSNumber *)state +{ + if ([state boolValue]) + ShowMenuBar (); + else + HideMenuBar (); +} + + +/* user preferences */ + +/* Note that these functions only work for arrays whose elements + can be toll-free-bridged between NS and CF worlds. */ + +static const void *cfretain (CFAllocatorRef a, const void *b) { + return CFRetain (b); +} +static void cfrelease (CFAllocatorRef a, const void *b) { + CFRelease (b); +} +static CFMutableArrayRef +nsarray_to_cfarray (NSArray *in) +{ + CFMutableArrayRef out; + CFArrayCallBacks cb; + NSObject *ns; + const CFTypeRef *cf; + int i, count; + + memset (&cb, 0, sizeof (cb)); + cb.version = 0; + cb.retain = cfretain; + cb.release = cfrelease; + + count = [in count]; + out = CFArrayCreateMutable (NULL, count, &cb); + + for (i = 0; i < count; i++) + { + ns = [in objectAtIndex:i]; + + if ([ns isKindOfClass:[NSArray class]]) + cf = (CFTypeRef) nsarray_to_cfarray ((NSArray *) ns); + else + cf = CFRetain ((CFTypeRef) ns); + + CFArrayAppendValue (out, cf); + CFRelease (cf); + } + + return out; +} +static NSMutableArray * +cfarray_to_nsarray (CFArrayRef in) +{ + NSMutableArray *out; + const CFTypeRef *cf; + NSObject *ns; + int i, count; + + count = CFArrayGetCount (in); + out = [[NSMutableArray alloc] initWithCapacity:count]; + + for (i = 0; i < count; i++) + { + cf = CFArrayGetValueAtIndex (in, i); + + if (CFGetTypeID (cf) == CFArrayGetTypeID ()) + ns = cfarray_to_nsarray ((CFArrayRef) cf); + else + ns = [(id)cf retain]; + + [out addObject:ns]; + [ns release]; + } + + return out; +} + +- (CFPropertyListRef) prefs_get:(NSString *)key +{ + CFPropertyListRef value; + + value = CFPreferencesCopyAppValue ((CFStringRef) key, CFSTR (APP_PREFS)); + + if (value == NULL) + { + static CFDictionaryRef defaults; + + if (defaults == NULL) + { + CFStringRef error = NULL; + CFDataRef data; + CFURLRef url; + SInt32 error_code; + + url = (CFURLCreateFromFileSystemRepresentation + (NULL, (unsigned char *)DEFAULTS_FILE, strlen (DEFAULTS_FILE), false)); + if (CFURLCreateDataAndPropertiesFromResource (NULL, url, &data, + NULL, NULL, + &error_code)) + { + defaults = (CFPropertyListCreateFromXMLData + (NULL, data, kCFPropertyListMutableContainersAndLeaves, &error)); + if (error != NULL) + CFRelease (error); + CFRelease (data); + } + CFRelease (url); + + if (defaults != NULL) + { + NSMutableArray *apps, *elt; + int count, i; + NSString *name, *nname; + + /* Localize the names in the default apps menu. */ + + apps = [(NSDictionary *)defaults objectForKey:@PREFS_APPSMENU]; + if (apps != nil) + { + count = [apps count]; + for (i = 0; i < count; i++) + { + elt = [apps objectAtIndex:i]; + if (elt != nil && [elt isKindOfClass:[NSArray class]]) + { + name = [elt objectAtIndex:0]; + if (name != nil) + { + nname = NSLocalizedString (name, nil); + if (nname != nil && nname != name) + [elt replaceObjectAtIndex:0 withObject:nname]; + } + } + } + } + } + } + + if (defaults != NULL) + value = CFDictionaryGetValue (defaults, key); + + if (value != NULL) + CFRetain (value); + } + + return value; +} + +- (int) prefs_get_integer:(NSString *)key default:(int)def +{ + CFPropertyListRef value; + int ret; + + value = [self prefs_get:key]; + + if (value != NULL && CFGetTypeID (value) == CFNumberGetTypeID ()) + CFNumberGetValue (value, kCFNumberIntType, &ret); + else if (value != NULL && CFGetTypeID (value) == CFStringGetTypeID ()) + ret = CFStringGetIntValue (value); + else + ret = def; + + if (value != NULL) + CFRelease (value); + + return ret; +} + +- (const char *) prefs_get_string:(NSString *)key default:(const char *)def +{ + CFPropertyListRef value; + const char *ret = NULL; + + value = [self prefs_get:key]; + + if (value != NULL && CFGetTypeID (value) == CFStringGetTypeID ()) + { + NSString *s = (NSString *) value; + + ret = [s UTF8String]; + } + + if (value != NULL) + CFRelease (value); + + return ret != NULL ? ret : def; +} + +- (float) prefs_get_float:(NSString *)key default:(float)def +{ + CFPropertyListRef value; + float ret = def; + + value = [self prefs_get:key]; + + if (value != NULL + && CFGetTypeID (value) == CFNumberGetTypeID () + && CFNumberIsFloatType (value)) + { + CFNumberGetValue (value, kCFNumberFloatType, &ret); + } + else if (value != NULL && CFGetTypeID (value) == CFStringGetTypeID ()) + { + ret = CFStringGetDoubleValue (value); + } + + if (value != NULL) + CFRelease (value); + + return ret; +} + +- (int) prefs_get_boolean:(NSString *)key default:(int)def +{ + CFPropertyListRef value; + int ret = def; + + value = [self prefs_get:key]; + + if (value != NULL) + { + if (CFGetTypeID (value) == CFNumberGetTypeID ()) + CFNumberGetValue (value, kCFNumberIntType, &ret); + else if (CFGetTypeID (value) == CFBooleanGetTypeID ()) + ret = CFBooleanGetValue (value); + else if (CFGetTypeID (value) == CFStringGetTypeID ()) + { + const char *tem = [(NSString *) value lossyCString]; + if (strcasecmp (tem, "true") == 0 || strcasecmp (tem, "yes") == 0) + ret = YES; + else + ret = NO; + } + + CFRelease (value); + } + + return ret; +} + +- (NSArray *) prefs_get_array:(NSString *)key +{ + NSArray *ret = nil; + CFPropertyListRef value; + + value = [self prefs_get:key]; + + if (value != NULL) + { + if (CFGetTypeID (value) == CFArrayGetTypeID ()) + ret = [cfarray_to_nsarray (value) autorelease]; + + CFRelease (value); + } + + return ret; +} + +- (void) prefs_set_integer:(NSString *)key value:(int)value +{ + CFNumberRef x; + + x = CFNumberCreate (NULL, kCFNumberIntType, &value); + + CFPreferencesSetValue ((CFStringRef) key, (CFTypeRef) x, CFSTR (APP_PREFS), + kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + + CFRelease (x); +} + +- (void) prefs_set_float:(NSString *)key value:(float)value +{ + CFNumberRef x; + + x = CFNumberCreate (NULL, kCFNumberFloatType, &value); + + CFPreferencesSetValue ((CFStringRef) key, (CFTypeRef) x, CFSTR (APP_PREFS), + kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + + CFRelease (x); +} + +- (void) prefs_set_boolean:(NSString *)key value:(int)value +{ + CFPreferencesSetValue ((CFStringRef) key, + (CFTypeRef) value ? kCFBooleanTrue + : kCFBooleanFalse, CFSTR (APP_PREFS), + kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + +} + +- (void) prefs_set_array:(NSString *)key value:(NSArray *)value +{ + CFArrayRef cfarray; + + cfarray = nsarray_to_cfarray (value); + CFPreferencesSetValue ((CFStringRef) key, + (CFTypeRef) cfarray, + CFSTR (APP_PREFS), + kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + CFRelease (cfarray); +} + +- (void) prefs_set_string:(NSString *)key value:(NSString *)value +{ + CFPreferencesSetValue ((CFStringRef) key, (CFTypeRef) value, + CFSTR (APP_PREFS), kCFPreferencesCurrentUser, + kCFPreferencesAnyHost); +} + +- (void) prefs_synchronize +{ + CFPreferencesAppSynchronize (kCFPreferencesCurrentApplication); +} + +- (void) read_defaults +{ + const char *tem; + + quartzUseSysBeep = [self prefs_get_boolean:@PREFS_SYSBEEP + default:quartzUseSysBeep]; + quartzEnableRootless = [self prefs_get_boolean:@PREFS_ROOTLESS + default:quartzEnableRootless]; +#ifdef DARWIN_DDX_MISSING + quartzFullscreenDisableHotkeys = ![self prefs_get_boolean: + @PREFS_FULLSCREEN_HOTKEYS default: + !quartzFullscreenDisableHotkeys]; + quartzXpluginOptions = [self prefs_get_integer:@PREFS_XP_OPTIONS + default:quartzXpluginOptions]; +#endif + + darwinSwapAltMeta = [self prefs_get_boolean:@PREFS_SWAP_ALT_META + default:darwinSwapAltMeta]; + darwinFakeButtons = [self prefs_get_boolean:@PREFS_FAKEBUTTONS + default:darwinFakeButtons]; + if (darwinFakeButtons) + { + const char *fake2, *fake3; + + fake2 = [self prefs_get_string:@PREFS_FAKE_BUTTON2 default:NULL]; + fake3 = [self prefs_get_string:@PREFS_FAKE_BUTTON3 default:NULL]; + + if (fake2 != NULL) darwinFakeMouse2Mask = DarwinParseModifierList(fake2); + if (fake3 != NULL) darwinFakeMouse3Mask = DarwinParseModifierList(fake3); + + } + + X11EnableKeyEquivalents = [self prefs_get_boolean:@PREFS_KEYEQUIVS + default:X11EnableKeyEquivalents]; + + darwinSyncKeymap = [self prefs_get_boolean:@PREFS_SYNC_KEYMAP + default:darwinSyncKeymap]; + + tem = [self prefs_get_string:@PREFS_KEYMAP_FILE default:NULL]; + if (tem != NULL) + darwinKeymapFile = strdup (tem); + else + darwinKeymapFile = NULL; + + darwinDesiredDepth = [self prefs_get_integer:@PREFS_DEPTH + default:darwinDesiredDepth]; + + enable_stereo = [self prefs_get_boolean:@PREFS_ENABLE_STEREO + default:false]; +} + +/* This will end up at the end of the responder chain. */ +- (void) copy:sender +{ + QuartzMessageServerThread (kXDarwinPasteboardNotify, 1, + AppleWMCopyToPasteboard); +} + +- (BOOL) x_active +{ + return _x_active; +} + +@end + +static NSArray * +array_with_strings_and_numbers (int nitems, const char **items, + const char *numbers) +{ + NSMutableArray *array, *subarray; + NSString *string; + NSString *number; + int i; + + /* (Can't autorelease on the X server thread) */ + + array = [[NSMutableArray alloc] initWithCapacity:nitems]; + + for (i = 0; i < nitems; i++) + { + subarray = [[NSMutableArray alloc] initWithCapacity:2]; + + string = [[NSString alloc] initWithUTF8String:items[i]]; + [subarray addObject:string]; + [string release]; + + if (numbers[i] != 0) + { + number = [[NSString alloc] initWithFormat:@"%d", numbers[i]]; + [subarray addObject:number]; + [number release]; + } + else + [subarray addObject:@""]; + + [array addObject:subarray]; + [subarray release]; + } + + return array; +} + +void +X11ApplicationSetWindowMenu (int nitems, const char **items, + const char *shortcuts) +{ + NSArray *array; + array = array_with_strings_and_numbers (nitems, items, shortcuts); + + /* Send the array of strings over to the appkit thread */ + + message_kit_thread (@selector (set_window_menu:), array); + [array release]; +} + +void +X11ApplicationSetWindowMenuCheck (int idx) +{ + NSNumber *n; + + n = [[NSNumber alloc] initWithInt:idx]; + + message_kit_thread (@selector (set_window_menu_check:), n); + + [n release]; +} + +void +X11ApplicationSetFrontProcess (void) +{ + message_kit_thread (@selector (set_front_process:), nil); +} + +void +X11ApplicationSetCanQuit (int state) +{ + NSNumber *n; + + n = [[NSNumber alloc] initWithBool:state]; + + message_kit_thread (@selector (set_can_quit:), n); + + [n release]; +} + +void +X11ApplicationServerReady (void) +{ + message_kit_thread (@selector (server_ready:), nil); +} + +void +X11ApplicationShowHideMenubar (int state) +{ + NSNumber *n; + + n = [[NSNumber alloc] initWithBool:state]; + + message_kit_thread (@selector (show_hide_menubar:), n); + + [n release]; +} + +static void * +create_thread (void *func, void *arg) +{ + pthread_attr_t attr; + pthread_t tid; + + pthread_attr_init (&attr); + + pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM); + pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); + + pthread_create (&tid, &attr, func, arg); + + pthread_attr_destroy (&attr); + + return (void *) tid; +} + +static void +check_xinitrc (void) +{ + char *tem, buf[1024]; + NSString *msg; + + if ([X11App prefs_get_boolean:@PREFS_DONE_XINIT_CHECK default:NO]) + return; + + tem = getenv ("HOME"); + if (tem == NULL) + goto done; + + snprintf (buf, sizeof (buf), "%s/.xinitrc", tem); + if (access (buf, F_OK) != 0) + goto done; + + /* FIXME: put localized strings into Resources/English.lproj */ + + msg = NSLocalizedString ( + @"You have an existing ~/.xinitrc file.\n\n\ + Windows displayed by X11 applications may not have titlebars, or may look \ + different to windows displayed by native applications.\n\n\ + Would you like to move aside the existing file and use the standard X11 \ + environment?", @"Startup xinitrc dialog"); + + if (NSRunAlertPanel (nil, msg, NSLocalizedString (@"Yes", @""), + NSLocalizedString (@"No", @""), nil) + == NSAlertDefaultReturn) + { + char buf2[1024]; + int i = -1; + + snprintf (buf2, sizeof (buf2), "%s.old", buf); + + for (i = 1; access (buf2, F_OK) == 0; i++) + snprintf (buf2, sizeof (buf2), "%s.old.%d", buf, i); + + rename (buf, buf2); + } + + done: + [X11App prefs_set_boolean:@PREFS_DONE_XINIT_CHECK value:YES]; + [X11App prefs_synchronize]; +} + +void +X11ApplicationMain (int argc, const char *argv[], + void (*server_thread) (void *), void *server_arg) +{ + NSAutoreleasePool *pool; + +#ifdef DEBUG + while (access ("/tmp/x11-block", F_OK) == 0) + sleep (1); +#endif + + pool = [[NSAutoreleasePool alloc] init]; + + X11App = (X11Application *) [X11Application sharedApplication]; + + init_ports (); + + [NSApp read_defaults]; + + [NSBundle loadNibNamed:@"main" owner:NSApp]; + + [[NSNotificationCenter defaultCenter] addObserver:NSApp + selector:@selector (became_key:) + name:NSWindowDidBecomeKeyNotification object:nil]; + + check_xinitrc (); + + /* + * The xpr Quartz mode is statically linked into this server. + * Initialize all the Quartz functions. + */ + QuartzModeBundleInit(); + + /* Calculate the height of the menubar so we can avoid it. */ + aquaMenuBarHeight = NSHeight([[NSScreen mainScreen] frame]) - + NSMaxY([[NSScreen mainScreen] visibleFrame]) - 1; + + if (!create_thread (server_thread, server_arg)) + { + fprintf (stderr, "can't create secondary thread\n"); + exit (1); + } + + [NSApp run]; + + /* not reached */ +} + + +/* event conversion */ + +static inline unsigned short +convert_flags (unsigned int nsflags) +{ + unsigned int xflags; + + if (nsflags == ~0) return 0xffff; + + xflags = 0; + + if (nsflags & NSAlphaShiftKeyMask) xflags |= LockMask; + if (nsflags & NSShiftKeyMask) xflags |= ShiftMask; + if (nsflags & NSControlKeyMask) xflags |= ControlMask; + if (nsflags & NSAlternateKeyMask) xflags |= Mod1Mask; + if (nsflags & NSCommandKeyMask) xflags |= Mod2Mask; + /* FIXME: secondaryfn? */ + + return xflags; +} + +static void +send_nsevent (NSEventType type, NSEvent *e) +{ + static unsigned int button_state = 0; + NSRect screen; + NSPoint location; + NSWindow *window; + int pointer_x, pointer_y; + xEvent xe; + + memset (&xe, 0, sizeof (xe)); + + /* This field should be filled in for every event */ + xe.u.keyButtonPointer.time = GetTimeInMillis(); + + /* convert location to global top-left coordinates */ + location = [e locationInWindow]; + window = [e window]; + screen = [[[NSScreen screens] objectAtIndex:0] frame]; + + if (window != nil) { + NSRect frame = [window frame]; + pointer_x = location.x + frame.origin.x; + pointer_y = (((screen.origin.y + screen.size.height) + - location.y) - frame.origin.y); + } else { + pointer_x = location.x; + pointer_y = (screen.origin.y + screen.size.height) - location.y; + } + + xe.u.keyButtonPointer.rootX = pointer_x; + xe.u.keyButtonPointer.rootY = pointer_y; + + switch (type) { + float count; + + case NSLeftMouseDown: + xe.u.u.type = ButtonPress; + xe.u.u.detail = 1; + goto do_press_event; + + case NSRightMouseDown: + xe.u.u.type = ButtonPress; + xe.u.u.detail = 3; + goto do_press_event; + + case NSOtherMouseDown: + xe.u.u.type = ButtonPress; + xe.u.u.detail = 2; /* FIXME? */ + goto do_press_event; + +do_press_event: + if (!quartzProcs->IsX11Window([e window], [e windowNumber])) { + /* X server doesn't grok this window, drop the event. + + Note: theoretically this isn't necessary, but if I click + on the menubar, we get sent a LeftMouseDown when the + release happens, but no LeftMouseUp is ever seen! */ + + break; + } + goto do_event; + + case NSLeftMouseUp: + xe.u.u.type = ButtonRelease; + xe.u.u.detail = 1; + goto do_release_event; + + case NSRightMouseUp: + xe.u.u.type = ButtonRelease; + xe.u.u.detail = 3; + goto do_release_event; + + case NSOtherMouseUp: + xe.u.u.type = ButtonRelease; + xe.u.u.detail = 2; /* FIXME? */ + goto do_release_event; + +do_release_event: + if ((button_state & (1 << xe.u.u.detail)) == 0) + { + /* X didn't see the button press for this release, so skip it */ + break; + } + goto do_event; + + case NSMouseMoved: + case NSLeftMouseDragged: + case NSRightMouseDragged: + case NSOtherMouseDragged: + xe.u.u.type = MotionNotify; + goto do_event; + + case NSKeyDown: + xe.u.u.type = KeyPress; + xe.u.u.detail = [e keyCode]; + goto do_event; + + case NSKeyUp: + xe.u.u.type = KeyRelease; + xe.u.u.detail = [e keyCode]; + goto do_event; + + case NSScrollWheel: + xe.u.keyButtonPointer.state = convert_flags ([e modifierFlags]); + count = [e deltaY]; + xe.u.u.detail = count > 0.0f ? 4 : 5; + for (count = fabs(count); count > 0.0; count = count - 1.0f) { + xe.u.u.type = ButtonPress; + DarwinEQEnqueue(&xe); + xe.u.u.type = ButtonRelease; + DarwinEQEnqueue(&xe); + } + xe.u.u.type = 0; + break; + + case NSFlagsChanged: + xe.u.u.type = kXDarwinUpdateModifiers; + xe.u.clientMessage.u.l.longs0 = [e modifierFlags]; + DarwinEQEnqueue (&xe); + break; + +do_event: + // xe.u.keyButtonPointer.state = convert_flags ([e modifierFlags]); + DarwinEQEnqueue (&xe); + break; + + default: break; /* for gcc */ + } + + if (xe.u.u.type == ButtonPress) + button_state |= (1 << xe.u.u.detail); + else if (xe.u.u.type == ButtonRelease) + button_state &= ~(1 << xe.u.u.detail); +} diff --git a/hw/darwin/apple/X11Controller.h b/hw/darwin/apple/X11Controller.h new file mode 100644 index 000000000..954d0abb9 --- /dev/null +++ b/hw/darwin/apple/X11Controller.h @@ -0,0 +1,86 @@ +/* X11Controller.h -- connect the IB ui + $Id: X11Controller.h,v 1.21 2003/07/24 17:52:29 jharper Exp $ + + Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT + HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name(s) of the above + copyright holders shall not be used in advertising or otherwise to + promote the sale, use or other dealings in this Software without + prior written authorization. */ + +#ifndef X11CONTROLLER_H +#define X11CONTROLLER_H 1 + +#if __OBJC__ + +#import +#include "../quartz/xpr/x-list.h" + +@interface X11Controller : NSObject +{ + NSPanel *prefs_panel; + + NSButton *fake_buttons; + NSButton *enable_fullscreen; + NSButton *use_sysbeep; + NSButton *enable_keyequivs; + NSButton *sync_keymap; + NSButton *enable_auth; + NSButton *enable_tcp; + NSPopUpButton *depth; + + NSMenuItem *x11_about_item; + NSMenuItem *window_separator; + NSMenuItem *dock_window_separator; + NSMenuItem *apps_separator; + NSMenuItem *toggle_fullscreen_item; + NSMenu *dock_apps_menu; + NSTableView *apps_table; + + NSArray *apps; + NSMutableArray *table_apps; + + NSMenu *dock_menu; + + int checked_window_item; + x_list *pending_apps; + + BOOL finished_launching; + BOOL can_quit; +} + +- (void) set_window_menu:(NSArray *)list; +- (void) set_window_menu_check:(NSNumber *)n; +- (void) set_apps_menu:(NSArray *)list; +- (void) set_can_quit:(BOOL)state; +- (void) server_ready; + +@end + +#endif /* __OBJC__ */ + +extern void X11ControllerMain (int argc, const char *argv[], + void (*server_thread) (void *), + void *server_arg); + +#endif /* X11CONTROLLER_H */ diff --git a/hw/darwin/apple/X11Controller.m b/hw/darwin/apple/X11Controller.m new file mode 100644 index 000000000..3dc965b69 --- /dev/null +++ b/hw/darwin/apple/X11Controller.m @@ -0,0 +1,752 @@ +/* X11Controller.m -- connect the IB ui, also the NSApp delegate + $Id: X11Controller.m,v 1.40 2006/09/06 21:19:32 jharper Exp $ + + Copyright (c) 2002-2007 Apple Inc. All rights reserved. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT + HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name(s) of the above + copyright holders shall not be used in advertising or otherwise to + promote the sale, use or other dealings in this Software without + prior written authorization. */ + +#define DEFAULT_PATH "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/X11/bin" + +#include "../quartz/quartzCommon.h" + +#import "X11Controller.h" +#import "X11Application.h" +#import + +/* ouch! */ +#define BOOL X_BOOL +//# include "Xproto.h" +#include "opaque.h" +# include "darwin.h" +# include "../quartz/quartz.h" +# define _APPLEWM_SERVER_ +# include "X11/extensions/applewm.h" +# include "../quartz/applewmExt.h" +//# include "X.h" +#undef BOOL + +#include +#include +#include +#include +#include + +#define TRACE() fprintf (stderr, "%s\n", __FUNCTION__) + +@implementation X11Controller + +- (void) awakeFromNib +{ + X11Application *xapp = NSApp; + NSArray *array; + + /* Point X11Application at ourself. */ + [xapp set_controller:self]; + + array = [xapp prefs_get_array:@PREFS_APPSMENU]; + if (array != nil) + { + int count; + + /* convert from [TITLE1 COMMAND1 TITLE2 COMMAND2 ...] + to [[TITLE1 COMMAND1] [TITLE2 COMMAND2] ...] format. */ + + count = [array count]; + if (count > 0 + && ![[array objectAtIndex:0] isKindOfClass:[NSArray class]]) + { + int i; + NSMutableArray *copy, *sub; + + copy = [NSMutableArray arrayWithCapacity:(count / 2)]; + + for (i = 0; i < count / 2; i++) + { + sub = [[NSMutableArray alloc] initWithCapacity:3]; + [sub addObject:[array objectAtIndex:i*2]]; + [sub addObject:[array objectAtIndex:i*2+1]]; + [sub addObject:@""]; + [copy addObject:sub]; + [sub release]; + } + + array = copy; + } + + [self set_apps_menu:array]; + } +} + +- (void) item_selected:sender +{ + [NSApp activateIgnoringOtherApps:YES]; + + QuartzMessageServerThread (kXDarwinControllerNotify, 2, + AppleWMWindowMenuItem, [sender tag]); +} + +- (void) remove_window_menu +{ + NSMenu *menu; + int first, count, i; + + /* Work backwards so we don't mess up the indices */ + menu = [window_separator menu]; + first = [menu indexOfItem:window_separator] + 1; + count = [menu numberOfItems]; + for (i = count - 1; i >= first; i--) + [menu removeItemAtIndex:i]; + + menu = [dock_window_separator menu]; + count = [menu indexOfItem:dock_window_separator]; + for (i = 0; i < count; i++) + [dock_menu removeItemAtIndex:0]; +} + +- (void) install_window_menu:(NSArray *)list +{ + NSMenu *menu; + NSMenuItem *item; + int first, count, i; + + menu = [window_separator menu]; + first = [menu indexOfItem:window_separator] + 1; + count = [list count]; + for (i = 0; i < count; i++) + { + NSString *name, *shortcut; + + name = [[list objectAtIndex:i] objectAtIndex:0]; + shortcut = [[list objectAtIndex:i] objectAtIndex:1]; + + item = (NSMenuItem *) [menu addItemWithTitle:name action:@selector + (item_selected:) keyEquivalent:shortcut]; + [item setTarget:self]; + [item setTag:i]; + [item setEnabled:YES]; + + item = (NSMenuItem *) [dock_menu insertItemWithTitle:name + action:@selector + (item_selected:) keyEquivalent:shortcut + atIndex:i]; + [item setTarget:self]; + [item setTag:i]; + [item setEnabled:YES]; + } + + if (checked_window_item >= 0 && checked_window_item < count) + { + item = (NSMenuItem *) [menu itemAtIndex:first + checked_window_item]; + [item setState:NSOnState]; + item = (NSMenuItem *) [dock_menu itemAtIndex:checked_window_item]; + [item setState:NSOnState]; + } +} + +- (void) remove_apps_menu +{ + NSMenu *menu; + NSMenuItem *item; + int i; + + if (apps == nil || apps_separator == nil) return; + + menu = [apps_separator menu]; + + if (menu != nil) + { + for (i = [menu numberOfItems] - 1; i >= 0; i--) + { + item = (NSMenuItem *) [menu itemAtIndex:i]; + if ([item tag] != 0) + [menu removeItemAtIndex:i]; + } + } + + if (dock_apps_menu != nil) + { + for (i = [dock_apps_menu numberOfItems] - 1; i >= 0; i--) + { + item = (NSMenuItem *) [dock_apps_menu itemAtIndex:i]; + if ([item tag] != 0) + [dock_apps_menu removeItemAtIndex:i]; + } + } + + [apps release]; + apps = nil; +} + +- (void) prepend_apps_item:(NSArray *)list index:(int)i menu:(NSMenu *)menu +{ + NSString *title, *shortcut = @""; + NSArray *group; + NSMenuItem *item; + + group = [list objectAtIndex:i]; + title = [group objectAtIndex:0]; + if ([group count] >= 3) + shortcut = [group objectAtIndex:2]; + + if ([title length] != 0) + { + item = (NSMenuItem *) [menu insertItemWithTitle:title + action:@selector (app_selected:) + keyEquivalent:shortcut atIndex:0]; + [item setTarget:self]; + [item setEnabled:YES]; + } + else + { + item = (NSMenuItem *) [NSMenuItem separatorItem]; + [menu insertItem:item atIndex:0]; + } + + [item setTag:i+1]; /* can't be zero, so add one */ +} + +- (void) install_apps_menu:(NSArray *)list +{ + NSMenu *menu; + int i, count; + + count = [list count]; + + if (count == 0 || apps_separator == nil) return; + + menu = [apps_separator menu]; + + for (i = count - 1; i >= 0; i--) + { + if (menu != nil) + [self prepend_apps_item:list index:i menu:menu]; + if (dock_apps_menu != nil) + [self prepend_apps_item:list index:i menu:dock_apps_menu]; + } + + apps = [list retain]; +} + +- (void) set_window_menu:(NSArray *)list +{ + [self remove_window_menu]; + [self install_window_menu:list]; + + QuartzMessageServerThread (kXDarwinControllerNotify, 1, + AppleWMWindowMenuNotify); +} + +- (void) set_window_menu_check:(NSNumber *)nn +{ + NSMenu *menu; + NSMenuItem *item; + int first, count; + int n = [nn intValue]; + + menu = [window_separator menu]; + first = [menu indexOfItem:window_separator] + 1; + count = [menu numberOfItems] - first; + + if (checked_window_item >= 0 && checked_window_item < count) + { + item = (NSMenuItem *) [menu itemAtIndex:first + checked_window_item]; + [item setState:NSOffState]; + item = (NSMenuItem *) [dock_menu itemAtIndex:checked_window_item]; + [item setState:NSOffState]; + } + if (n >= 0 && n < count) + { + item = (NSMenuItem *) [menu itemAtIndex:first + n]; + [item setState:NSOnState]; + item = (NSMenuItem *) [dock_menu itemAtIndex:n]; + [item setState:NSOnState]; + } + checked_window_item = n; +} + +- (void) set_apps_menu:(NSArray *)list +{ + [self remove_apps_menu]; + [self install_apps_menu:list]; +} + +- (void) launch_client:(NSString *)filename +{ + const char *command = [filename UTF8String]; + const char *shell; + const char *argv[5]; + int child1, child2 = 0; + int status; + + shell = getenv("SHELL"); + if (shell == NULL) shell = "/bin/bash"; + + argv[0] = shell; + argv[1] = "-l"; + argv[2] = "-c"; + argv[3] = command; + argv[4] = NULL; + + /* Do the fork-twice trick to avoid having to reap zombies */ + + child1 = fork(); + + switch (child1) { + case -1: /* error */ + break; + + case 0: /* child1 */ + child2 = fork(); + + switch (child2) { + int max_files, i; + char buf[1024], *temp; + + case -1: /* error */ + _exit(1); + + case 0: /* child2 */ + /* close all open files except for standard streams */ + max_files = sysconf(_SC_OPEN_MAX); + for (i = 3; i < max_files; i++) close(i); + + /* ensure stdin is on /dev/null */ + close(0); + open("/dev/null", O_RDONLY); + + /* Setup environment */ + temp = getenv("DISPLAY"); + if (temp == NULL || temp[0] == 0) { + snprintf(buf, sizeof(buf), ":%s", display); + setenv("DISPLAY", buf, TRUE); + } + + temp = getenv("PATH"); + if (temp == NULL || temp[0] == 0) + setenv ("PATH", DEFAULT_PATH, TRUE); + else if (strnstr(temp, "/usr/X11/bin", sizeof(temp)) == NULL) { + snprintf(buf, sizeof(buf), "%s:/usr/X11/bin", temp); + setenv("PATH", buf, TRUE); + } + /* cd $HOME */ + temp = getenv("HOME"); + if (temp != NULL && temp[0]!=0) chdir(temp); + + execvp(argv[0], (char **const) argv); + + _exit(2); + + default: /* parent (child1) */ + _exit(0); + } + break; + + default: /* parent */ + waitpid(child1, &status, 0); + } +} + +- (void) app_selected:sender +{ + int tag; + NSString *item; + + tag = [sender tag] - 1; + if (apps == nil || tag < 0 || tag >= [apps count]) + return; + + item = [[apps objectAtIndex:tag] objectAtIndex:1]; + + [self launch_client:item]; +} + +- (IBAction) apps_table_show:sender +{ + NSArray *columns; + + if (table_apps == nil) { + table_apps = [[NSMutableArray alloc] initWithCapacity:1]; + + if (apps != nil)[table_apps addObjectsFromArray:apps]; + } + + columns = [apps_table tableColumns]; + [[columns objectAtIndex:0] setIdentifier:@"0"]; + [[columns objectAtIndex:1] setIdentifier:@"1"]; + [[columns objectAtIndex:2] setIdentifier:@"2"]; + + [apps_table setDataSource:self]; + [apps_table selectRow:0 byExtendingSelection:NO]; + + [[apps_table window] makeKeyAndOrderFront:sender]; +} + +- (IBAction) apps_table_cancel:sender +{ + [[apps_table window] orderOut:sender]; + [apps_table reloadData]; + + [table_apps release]; + table_apps = nil; +} + +- (IBAction) apps_table_done:sender +{ + [apps_table deselectAll:sender]; /* flush edits? */ + + [self remove_apps_menu]; + [self install_apps_menu:table_apps]; + + [NSApp prefs_set_array:@PREFS_APPSMENU value:table_apps]; + [NSApp prefs_synchronize]; + + [[apps_table window] orderOut:sender]; + + [table_apps release]; + table_apps = nil; +} + +- (IBAction) apps_table_new:sender +{ + NSMutableArray *item; + + int row = [apps_table selectedRow], i; + + if (row < 0) row = 0; + else row = row + 1; + + i = row; + if (i > [table_apps count]) + return; /* avoid exceptions */ + + [apps_table deselectAll:sender]; + + item = [[NSMutableArray alloc] initWithCapacity:3]; + [item addObject:@""]; + [item addObject:@""]; + [item addObject:@""]; + + [table_apps insertObject:item atIndex:i]; + [item release]; + + [apps_table reloadData]; + [apps_table selectRow:row byExtendingSelection:NO]; +} + +- (IBAction) apps_table_duplicate:sender +{ + int row = [apps_table selectedRow], i; + NSObject *item; + + if (row < 0) { + [self apps_table_new:sender]; + return; + } + + i = row; + if (i > [table_apps count] - 1) return; /* avoid exceptions */ + + [apps_table deselectAll:sender]; + + item = [[table_apps objectAtIndex:i] mutableCopy]; + [table_apps insertObject:item atIndex:i]; + [item release]; + + [apps_table reloadData]; + [apps_table selectRow:row+1 byExtendingSelection:NO]; +} + +- (IBAction) apps_table_delete:sender +{ + int row = [apps_table selectedRow]; + + if (row >= 0) + { + int i = row; + + if (i > [table_apps count] - 1) return; /* avoid exceptions */ + + [apps_table deselectAll:sender]; + + [table_apps removeObjectAtIndex:i]; + } + + [apps_table reloadData]; + + row = MIN (row, [table_apps count] - 1); + if (row >= 0) + [apps_table selectRow:row byExtendingSelection:NO]; +} + +- (int) numberOfRowsInTableView:(NSTableView *)tableView +{ + if (table_apps == nil) return 0; + + return [table_apps count]; +} + +- (id) tableView:(NSTableView *)tableView +objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row +{ + NSArray *item; + int col; + + if (table_apps == nil) return nil; + + col = [[tableColumn identifier] intValue]; + + item = [table_apps objectAtIndex:row]; + if ([item count] > col) + return [item objectAtIndex:col]; + else + return @""; +} + +- (void) tableView:(NSTableView *)tableView setObjectValue:(id)object + forTableColumn:(NSTableColumn *)tableColumn row:(int)row +{ + NSMutableArray *item; + int col; + + if (table_apps == nil) return; + + col = [[tableColumn identifier] intValue]; + + item = [table_apps objectAtIndex:row]; + [item replaceObjectAtIndex:col withObject:object]; +} + +- (void) hide_window:sender +{ + if ([X11App x_active]) + QuartzMessageServerThread (kXDarwinControllerNotify, 1, AppleWMHideWindow); + else + NSBeep (); /* FIXME: something here */ +} + +- (IBAction)bring_to_front:sender +{ + QuartzMessageServerThread(kXDarwinControllerNotify, 1, AppleWMBringAllToFront); +} + +- (IBAction)close_window:sender +{ + if ([X11App x_active]) + QuartzMessageServerThread (kXDarwinControllerNotify, 1, AppleWMCloseWindow); + else + [[NSApp keyWindow] performClose:sender]; +} + +- (IBAction)minimize_window:sender +{ + if ([X11App x_active]) + QuartzMessageServerThread (kXDarwinControllerNotify, 1, AppleWMMinimizeWindow); + else + [[NSApp keyWindow] performMiniaturize:sender]; +} + +- (IBAction)zoom_window:sender +{ + if ([X11App x_active]) + QuartzMessageServerThread (kXDarwinControllerNotify, 1, AppleWMZoomWindow); + else + [[NSApp keyWindow] performZoom:sender]; +} + +- (IBAction) next_window:sender +{ + QuartzMessageServerThread (kXDarwinControllerNotify, 1, AppleWMNextWindow); +} + +- (IBAction) previous_window:sender +{ + QuartzMessageServerThread (kXDarwinControllerNotify, 1, AppleWMPreviousWindow); +} + +- (IBAction) enable_fullscreen_changed:sender +{ + int value = ![enable_fullscreen intValue]; + +#ifdef DARWIN_DDX_MISSING + QuartzMessageServerThread (kXDarwinSetRootless, 1, value); +#endif + + [NSApp prefs_set_boolean:@PREFS_ROOTLESS value:value]; + [NSApp prefs_synchronize]; +} + +- (IBAction) toggle_fullscreen:sender +{ +#ifdef DARWIN_DDX_MISSING + QuartzMessageServerThread (kXDarwinToggleFullscreen, 0); +#endif +} + +- (void) set_can_quit:(BOOL)state +{ + can_quit = state; +} + +- (IBAction)prefs_changed:sender +{ + darwinFakeButtons = [fake_buttons intValue]; + quartzUseSysBeep = [use_sysbeep intValue]; + X11EnableKeyEquivalents = [enable_keyequivs intValue]; + darwinSyncKeymap = [sync_keymap intValue]; + + /* after adding prefs here, also add to [X11Application read_defaults] + and below */ + + [NSApp prefs_set_boolean:@PREFS_FAKEBUTTONS value:darwinFakeButtons]; + [NSApp prefs_set_boolean:@PREFS_SYSBEEP value:quartzUseSysBeep]; + [NSApp prefs_set_boolean:@PREFS_KEYEQUIVS value:X11EnableKeyEquivalents]; + [NSApp prefs_set_boolean:@PREFS_SYNC_KEYMAP value:darwinSyncKeymap]; + [NSApp prefs_set_boolean:@PREFS_NO_AUTH value:![enable_auth intValue]]; + [NSApp prefs_set_boolean:@PREFS_NO_TCP value:![enable_tcp intValue]]; + [NSApp prefs_set_integer:@PREFS_DEPTH value:[depth selectedTag]]; + + [NSApp prefs_synchronize]; +} + +- (IBAction) prefs_show:sender +{ + [fake_buttons setIntValue:darwinFakeButtons]; + [use_sysbeep setIntValue:quartzUseSysBeep]; + [enable_keyequivs setIntValue:X11EnableKeyEquivalents]; + [sync_keymap setIntValue:darwinSyncKeymap]; + [sync_keymap setEnabled:darwinKeymapFile == NULL]; + + [enable_auth setIntValue:![NSApp prefs_get_boolean:@PREFS_NO_AUTH default:NO]]; + [enable_tcp setIntValue:![NSApp prefs_get_boolean:@PREFS_NO_TCP default:NO]]; + [depth selectItemAtIndex:[depth indexOfItemWithTag:[NSApp prefs_get_integer:@PREFS_DEPTH default:-1]]]; + + [enable_fullscreen setIntValue:!quartzEnableRootless]; + + [prefs_panel makeKeyAndOrderFront:sender]; +} + +- (IBAction) quit:sender +{ + QuartzMessageServerThread (kXDarwinQuit, 0); +} + +- (IBAction) x11_help:sender +{ + AHLookupAnchor (CFSTR ("Mac Help"), CFSTR ("mchlp2276")); +} + +- (BOOL) validateMenuItem:(NSMenuItem *)item +{ + NSMenu *menu = [item menu]; + + if (item == toggle_fullscreen_item) + return !quartzEnableRootless; + else if (menu == [window_separator menu] || menu == dock_menu + || (menu == [x11_about_item menu] && [item tag] == 42)) + return (AppleWMSelectedEvents () & AppleWMControllerNotifyMask) != 0; + else + return TRUE; +} + +- (void) applicationDidHide:(NSNotification *)notify +{ + QuartzMessageServerThread (kXDarwinControllerNotify, 1, AppleWMHideAll); +} + +- (void) applicationDidUnhide:(NSNotification *)notify +{ + QuartzMessageServerThread (kXDarwinControllerNotify, 1, AppleWMShowAll); +} + +- (NSApplicationTerminateReply) applicationShouldTerminate:sender +{ + NSString *msg; + + if (can_quit || [X11App prefs_get_boolean:@PREFS_NO_QUIT_ALERT default:NO]) + return NSTerminateNow; + + /* Make sure we're frontmost. */ + [NSApp activateIgnoringOtherApps:YES]; + + msg = NSLocalizedString (@"Are you sure you want to quit X11?\n\nIf you quit X11, any X11 applications you are running will stop immediately and you will lose any changes you have not saved.", @"Dialog when quitting"); + + /* FIXME: safe to run the alert in here? Or should we return Later + and then run the alert on a timer? It seems to work here, so.. */ + + return (NSRunAlertPanel (nil, msg, NSLocalizedString (@"Quit", @""), + NSLocalizedString (@"Cancel", @""), nil) + == NSAlertDefaultReturn) ? NSTerminateNow : NSTerminateCancel; +} + +- (void) applicationWillTerminate:(NSNotification *)aNotification +{ + [X11App prefs_synchronize]; + + /* shutdown the X server, it will exit () for us. */ + QuartzMessageServerThread (kXDarwinQuit, 0); + + /* In case it doesn't, exit anyway after a while. */ + while (sleep (10) != 0) ; + exit (1); +} + +- (void) server_ready +{ + x_list *node; + + finished_launching = YES; + + for (node = pending_apps; node != NULL; node = node->next) + { + NSString *filename = node->data; + [self launch_client:filename]; + [filename release]; + } + + x_list_free (pending_apps); + pending_apps = NULL; +} + +- (BOOL) application:(NSApplication *)app openFile:(NSString *)filename +{ + const char *name = [filename UTF8String]; + + if (finished_launching) + [self launch_client:filename]; + else if (name[0] != ':') /* ignore display names */ + pending_apps = x_list_prepend (pending_apps, [filename retain]); + + /* FIXME: report failures. */ + return YES; +} + +@end + +void X11ControllerMain (int argc, const char *argv[], + void (*server_thread) (void *), void *server_arg) +{ + X11ApplicationMain (argc, argv, server_thread, server_arg); +} diff --git a/hw/darwin/apple/Xquartz.man b/hw/darwin/apple/Xquartz.man new file mode 100644 index 000000000..edac30ee9 --- /dev/null +++ b/hw/darwin/apple/Xquartz.man @@ -0,0 +1,158 @@ +.\" $XFree86: xc/programs/Xserver/hw/darwin/XDarwin.man,v 1.4 2002/01/09 18:01:58 torrey Exp $ +.\" +.TH XQUARTZ 1 __vendorversion__ +.SH NAME +Xquartz \- X window system server for Quartz operating system +.SH SYNOPSIS +.B Xquartz +[ options ] ... +.SH DESCRIPTION +.I Xquartz +is the X window server for Mac OS X provided by Apple. +.I Xquartz +runs in parallel with Aqua in rootless mode. In rootless mode, the X +window system and Mac OS X share your display. The root window of the +X11 display is the size of the screen and contains all the other +windows. The X11 root window is not displayed in rootless mode as Mac +OS X handles the desktop background. +.SH OPTIONS +.PP +In addition to the normal server options described in the \fIXserver(1)\fP +manual page, \fIXquartz\fP accepts the following command line switches: +.TP 8 +.B \-fakebuttons +Emulates a 3 button mouse using modifier keys. By default, the Command modifier +is used to emulate button 2 and Option is used for button 3. Thus, clicking the +first mouse button while holding down Command will act like clicking +button 2. Holding down Option will simulate button 3. +.TP 8 +.B \-nofakebuttons +Do not emulate a 3 button mouse. This is the default. +.TP 8 +.B "\-fakemouse2 \fImodifiers\fP" +Change the modifier keys used to emulate the second mouse button. By default, +Command is used to emulate the second button. Any combination of the following +modifier names may be used: Shift, Option, Control, Command, Fn. For example, +.B \-fakemouse2 """Option,Shift"" +will set holding Option, Shift and clicking on button one as equivalent to +clicking the second mouse button. +.TP 8 +.B "\-fakemouse3 \fImodifiers\fP" +Change the modifier keys used to emulate the third mouse button. By default, +Option is used to emulate the third button. Any combination of the following +modifier names may be used: Shift, Option, Control, Command, Fn. For example, +.B \-fakemouse3 """Control,Shift"" +will set holding Control, Shift and clicking on button one as equivalent to +clicking the third mouse button. +.TP 8 +.B "\-swapAltMeta" +Swaps the meaning of the Alt and Meta modifier keys. +.TP 8 +.B "\-keymap \fIfile\fP" +On startup \fIXquartz\fP translates a Darwin keymapping into an X keymap. +The default is to read this keymapping from USA.keymapping. With this option +the keymapping will be read from \fIfile\fP instead. If the file's path is +not specified, it will be searched for in Library/Keyboards/ underneath the +following directories (in order): ~, /, /Network, /System. +.TP 8 +.B \-nokeymap +On startup \fIXquartz\fP translates a Darwin keymapping into an X keymap. +With this option \fIXquartz\fP queries the kernel for the current keymapping +instead of reading it from a file. This will often fail on newer kernels. +.TP 8 +.B "\-depth \fIdepth\fP" +Specifies the color bit depth to use. Currently only 15, and 24 color +bits per pixel are supported. If not specified, defaults to the depth +of the main display. +.SH CUSTOMIZATION +\fIXquartz\fP can also be customized using the defaults(1) command. The available options are: +.TP 8 +.B defaults write com.apple.x11 enable_fake_buttons -boolean true +Equivalent to the \fB-fakebuttons\fP command line option. +.TP 8 +.B defaults write com.apple.x11 fake_button2 \fImodifiers\fP +Equivalent to the \fB-fakemouse2\fP option. +.TP 8 +.B defaults write com.apple.x11 fake_button3 \fImodifiers\fP +Equivalent to the \fB-fakemouse3\fP option. +.TP 8 +.B defaults write com.apple.x11 swap_alt_meta -boolean true +Equivalent to the \fB-swapAltMeta\fP option. +.TP 8 +.B defaults write com.apple.x11 keymap_file \fIfilename\fP +Equivalent to the \fB-keymap\fP option. +.TP 8 +.B defaults write com.apple.x11 no_quit_alert -boolean true +Disables the alert dialog displayed when attempting to quit X11. +.TP 8 +.B defaults write com.apple.x11 no_auth -boolean true +Stops the X server requiring that clients authenticate themselves when +connecting. See Xsecurity(__miscmansuffix__). +.TP 8 +.B defaults write com.apple.x11 nolisten_tcp -boolean true +Prevents the X server accepting remote connections. +.TP 8 +.B defaults write com.apple.x11 xinit_kills_server -boolean false +Stops the X server exiting when the xinitrc script terminates. +.TP 8 +.B defaults write com.apple.x11 fullscreen_hotkeys -boolean false +Allows system hotkeys to be handled while in X11 fullscreen mode. +.TP 8 +.B defaults write com.apple.x11 enable_system_beep -boolean false +Don't use the standard system beep effect for X11 alerts. +.TP 8 +.B defaults write com.apple.x11 enable_key_equivalents -boolean false +Disable menu keyboard equivalents while X11 windows are focused. +.TP 8 +.B defaults write com.apple.x11 depth \fIdepth\fP +Equivalent to the \fB-depth\fP option. +.SH "SEE ALSO" +.PP +X(__miscmansuffix__), XFree86(1), Xserver(1), xdm(1), xinit(1) +.PP +.SH AUTHORS +XFree86 was originally ported to Mac OS X Server by John Carmack. Dave +Zarzycki used this as the basis of his port of XFree86 4.0 to Darwin 1.0. +Torrey T. Lyons improved and integrated this code into the XFree86 +Project's mainline for the 4.0.2 release. +.PP +The following members of the XonX Team contributed to the following +releases (in alphabetical order): +.TP 4 +XFree86 4.1.0: +.br +Rob Braun - Darwin x86 support +.br +Torrey T. Lyons - Project Lead +.br +Andreas Monitzer - Cocoa version of XDarwin front end +.br +Gregory Robert Parker - Original Quartz implementation +.br +Christoph Pfisterer - Dynamic shared X libraries +.br +Toshimitsu Tanaka - Japanese localization +.TP 4 +XFree86 4.2.0: +.br +Rob Braun - Darwin x86 support +.br +Pablo Di Noto - Spanish localization +.br +Paul Edens - Dutch localization +.br +Kyunghwan Kim - Korean localization +.br +Mario Klebsch - Non-US keyboard support +.br +Torrey T. Lyons - Project Lead +.br +Andreas Monitzer - German localization +.br +Patrik Montgomery - Swedish localization +.br +Greg Parker - Rootless support +.br +Toshimitsu Tanaka - Japanese localization +.br +Olivier Verdier - French localization diff --git a/hw/darwin/apple/bundle-main.c b/hw/darwin/apple/bundle-main.c new file mode 100644 index 000000000..12fb1bf54 --- /dev/null +++ b/hw/darwin/apple/bundle-main.c @@ -0,0 +1,911 @@ +/* bundle-main.c -- X server launcher + $Id: bundle-main.c,v 1.17 2003/09/11 00:17:10 jharper Exp $ + + Copyright (c) 2002-2007 Apple Inc. All rights reserved. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT + HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name(s) of the above + copyright holders shall not be used in advertising or otherwise to + promote the sale, use or other dealings in this Software without + prior written authorization. + + Parts of this file are derived from xdm, which has this copyright: + + Copyright 1988, 1998 The Open Group + + Permission to use, copy, modify, distribute, and sell this software + and its documentation for any purpose is hereby granted without fee, + provided that the above copyright notice appear in all copies and + that both that copyright notice and this permission notice appear in + supporting documentation. + + 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 OPEN GROUP 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 The Open Group shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from The Open Group. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#define X_SERVER "/usr/X11/bin/Xquartz" +#define XTERM_PATH "/usr/X11/bin/xterm" +#define WM_PATH "/usr/X11/bin/quartz-wm" +#define DEFAULT_XINITRC "/etc/X11/xinit/xinitrc" +#define DEFAULT_PATH "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/X11/bin" + +/* what xinit does */ +#ifndef SHELL +# define SHELL "sh" +#endif + +#undef FALSE +#define FALSE 0 +#undef TRUE +#define TRUE 1 + +#define MAX_DISPLAYS 64 + +static int server_pid = -1, client_pid = -1; +static int xinit_kills_server = FALSE; +static jmp_buf exit_continuation; +static const char *server_name = NULL; +static Display *server_dpy; + +static char *auth_file; + +typedef struct addr_list_struct addr_list; + +struct addr_list_struct { + addr_list *next; + Xauth auth; +}; + +static addr_list *addresses; + + +/* Utility functions. */ + +/* Return the current host name. Matches what Xlib does. */ +static char * +host_name (void) +{ +#ifdef NEED_UTSNAME + static struct utsname name; + + uname(&name); + + return name.nodename; +#else + static char buf[100]; + + gethostname(buf, sizeof(buf)); + + return buf; +#endif +} + +static int +read_boolean_pref (CFStringRef name, int default_) +{ + int value; + Boolean ok; + + value = CFPreferencesGetAppBooleanValue (name, + CFSTR ("com.apple.x11"), &ok); + return ok ? value : default_; +} + +static inline int +binary_equal (const void *a, const void *b, int length) +{ + return memcmp (a, b, length) == 0; +} + +static inline void * +binary_dup (const void *a, int length) +{ + void *b = malloc (length); + if (b != NULL) + memcpy (b, a, length); + return b; +} + +static inline void +binary_free (void *data, int length) +{ + if (data != NULL) + free (data); +} + + +/* Functions for managing the authentication entries. */ + +/* Returns true if something matching AUTH is in our list of auth items */ +static int +check_auth_item (Xauth *auth) +{ + addr_list *a; + + for (a = addresses; a != NULL; a = a->next) + { + if (a->auth.family == auth->family + && a->auth.address_length == auth->address_length + && binary_equal (a->auth.address, auth->address, auth->address_length) + && a->auth.number_length == auth->number_length + && binary_equal (a->auth.number, auth->number, auth->number_length) + && a->auth.name_length == auth->name_length + && binary_equal (a->auth.name, auth->name, auth->name_length)) + { + return TRUE; + } + } + + return FALSE; +} + +/* Add one item to our list of auth items. */ +static void +add_auth_item (Xauth *auth) +{ + addr_list *a = malloc (sizeof (addr_list)); + + a->auth.family = auth->family; + a->auth.address_length = auth->address_length; + a->auth.address = binary_dup (auth->address, auth->address_length); + a->auth.number_length = auth->number_length; + a->auth.number = binary_dup (auth->number, auth->number_length); + a->auth.name_length = auth->name_length; + a->auth.name = binary_dup (auth->name, auth->name_length); + a->auth.data_length = auth->data_length; + a->auth.data = binary_dup (auth->data, auth->data_length); + + a->next = addresses; + addresses = a; +} + +/* Free all allocated auth items. */ +static void +free_auth_items (void) +{ + addr_list *a; + + while ((a = addresses) != NULL) + { + addresses = a->next; + + binary_free (a->auth.address, a->auth.address_length); + binary_free (a->auth.number, a->auth.number_length); + binary_free (a->auth.name, a->auth.name_length); + binary_free (a->auth.data, a->auth.data_length); + free (a); + } +} + +/* Add the unix domain auth item. */ +static void +define_local (Xauth *auth) +{ + char *host = host_name (); + +#ifdef DEBUG + fprintf (stderr, "x11: hostname is %s\n", host); +#endif + + auth->family = FamilyLocal; + auth->address_length = strlen (host); + auth->address = host; + + add_auth_item (auth); +} + +/* Add the tcp auth item. */ +static void +define_named (Xauth *auth, const char *name) +{ + struct ifaddrs *addrs, *ptr; + + if (getifaddrs (&addrs) != 0) + return; + + for (ptr = addrs; ptr != NULL; ptr = ptr->ifa_next) + { + if (ptr->ifa_addr->sa_family != AF_INET) + continue; + + auth->family = FamilyInternet; + auth->address_length = sizeof (struct in_addr); + auth->address = (char *) &(((struct sockaddr_in *) ptr->ifa_addr)->sin_addr); + +#ifdef DEBUG + fprintf (stderr, "x11: ipaddr is %d.%d.%d.%d\n", + (unsigned char) auth->address[0], + (unsigned char) auth->address[1], + (unsigned char) auth->address[2], + (unsigned char) auth->address[3]); +#endif + + add_auth_item (auth); + } + + freeifaddrs (addrs); +} + +/* Parse the display number from NAME and add it to AUTH. */ +static void +set_auth_number (Xauth *auth, const char *name) +{ + char *colon; + char *dot, *number; + + colon = strrchr(name, ':'); + if (colon != NULL) + { + colon++; + dot = strchr(colon, '.'); + + if (dot != NULL) + auth->number_length = dot - colon; + else + auth->number_length = strlen (colon); + + number = malloc (auth->number_length + 1); + if (number != NULL) + { + strncpy (number, colon, auth->number_length); + number[auth->number_length] = '\0'; + } + else + { + auth->number_length = 0; + } + + auth->number = number; + } +} + +/* Put 128 bits of random data into DATA. If possible, it will be "high + quality" */ +static int +generate_mit_magic_cookie (char data[16]) +{ + int fd, ret, i; + long *ldata = (long *) data; + + fd = open ("/dev/random", O_RDONLY); + if (fd > 0) { + ret = read (fd, data, 16); + close (fd); + if (ret == 16) return TRUE; + } + + /* fall back to the usual crappy rng */ + + srand48 (getpid () ^ time (NULL)); + + for (i = 0; i < 4; i++) + ldata[i] = lrand48 (); + + return TRUE; +} + +/* Create the keys we'll be using for the display named NAME. */ +static int +make_auth_keys (const char *name) +{ + Xauth auth; + char key[16]; + + if (auth_file == NULL) + return FALSE; + + auth.name = "MIT-MAGIC-COOKIE-1"; + auth.name_length = strlen (auth.name); + + if (!generate_mit_magic_cookie (key)) + { + auth_file = NULL; + return FALSE; + } + + auth.data = key; + auth.data_length = 16; + + set_auth_number (&auth, name); + + define_named (&auth, host_name ()); + define_local (&auth); + + free (auth.number); + + return TRUE; +} + +/* If ADD-ENTRIES is true, merge our auth entries into the existing + Xauthority file. If ADD-ENTRIES is false, remove our entries. */ +static int +write_auth_file (int add_entries) +{ + char *home, newname[1024]; + int fd, ret; + FILE *new_fh, *old_fh; + addr_list *addr; + Xauth *auth; + + if (auth_file == NULL) + return FALSE; + + home = getenv ("HOME"); + if (home == NULL) + { + auth_file = NULL; + return FALSE; + } + + snprintf (newname, sizeof (newname), "%s/.XauthorityXXXXXX", home); + mktemp (newname); + + if (XauLockAuth (auth_file, 1, 2, 10) != LOCK_SUCCESS) + { + /* FIXME: do something here? */ + + auth_file = NULL; + return FALSE; + } + + fd = open (newname, O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (fd >= 0) + { + new_fh = fdopen (fd, "w"); + if (new_fh != NULL) + { + if (add_entries) + { + for (addr = addresses; addr != NULL; addr = addr->next) + { + XauWriteAuth (new_fh, &addr->auth); + } + } + + old_fh = fopen (auth_file, "r"); + if (old_fh != NULL) + { + while ((auth = XauReadAuth (old_fh)) != NULL) + { + if (!check_auth_item (auth)) + XauWriteAuth (new_fh, auth); + XauDisposeAuth (auth); + } + fclose (old_fh); + } + + fclose (new_fh); + unlink (auth_file); + + ret = rename (newname, auth_file); + + if (ret != 0) + auth_file = NULL; + + XauUnlockAuth (auth_file); + return ret == 0; + } + + close (fd); + } + + XauUnlockAuth (auth_file); + auth_file = NULL; + return FALSE; +} + + +/* Subprocess management functions. */ + +static int +start_server (char **xargv) +{ + int child; + + child = fork (); + + switch (child) + { + case -1: /* error */ + perror ("fork"); + return FALSE; + + case 0: /* child */ + execv (X_SERVER, xargv); + perror ("Couldn't exec " X_SERVER); + _exit (1); + + default: /* parent */ + server_pid = child; + return TRUE; + } +} + +static int +wait_for_server (void) +{ + int count = 100; + + while (count-- > 0) + { + int status; + + server_dpy = XOpenDisplay (server_name); + if (server_dpy != NULL) + return TRUE; + + if (waitpid (server_pid, &status, WNOHANG) == server_pid) + return FALSE; + + sleep (1); + } + + return FALSE; +} + +static int +start_client (void) +{ + int child; + + child = fork(); + + switch (child) { + char *temp, buf[1024]; + + case -1: /* error */ + perror("fork"); + return FALSE; + + case 0: /* child */ + /* Setup environment */ + temp = getenv("DISPLAY"); + if (temp != NULL && temp[0] != 0) + setenv("DISPLAY", server_name, TRUE); + + temp = getenv("PATH"); + if (temp == NULL || temp[0] == 0) + setenv ("PATH", DEFAULT_PATH, TRUE); + else if (strnstr(temp, "/usr/X11/bin", sizeof(temp)) == NULL) { + snprintf(buf, sizeof(buf), "%s:/usr/X11/bin", temp); + setenv("PATH", buf, TRUE); + } + + /* First try value of $XINITRC, if set. */ + temp = getenv("XINITRC"); + if (temp != NULL && temp[0] != 0 && access(temp, R_OK) == 0) + execlp (SHELL, SHELL, temp, NULL); + + /* Then look for .xinitrc in user's home directory. */ + temp = getenv("HOME"); + if (temp != NULL && temp[0] != 0) { + chdir(temp); + snprintf (buf, sizeof (buf), "%s/.xinitrc", temp); + if (access(buf, R_OK) == 0) + execlp(SHELL, SHELL, buf, NULL); + } + + /* Then try the default xinitrc in the lib directory. */ + + if (access(DEFAULT_XINITRC, R_OK) == 0) + execlp(SHELL, SHELL, DEFAULT_XINITRC, NULL); + + /* Then fallback to hardcoding an xterm and the window manager. */ + + // system(XTERM_PATH " &"); + execl(WM_PATH, WM_PATH, NULL); + + perror("exec"); + _exit(1); + + default: /* parent */ + client_pid = child; + return TRUE; + } +} + +static void +sigchld_handler (int sig) +{ + int pid, status; + + again: + pid = waitpid (WAIT_ANY, &status, WNOHANG); + + if (pid > 0) + { + if (pid == server_pid) + { + server_pid = -1; + + if (client_pid >= 0) + kill (client_pid, SIGTERM); + } + else if (pid == client_pid) + { + client_pid = -1; + + if (server_pid >= 0 && xinit_kills_server) + kill (server_pid, SIGTERM); + } + goto again; + } + + if (server_pid == -1 && client_pid == -1) + longjmp (exit_continuation, 1); + + signal (SIGCHLD, sigchld_handler); +} + + +/* Server utilities. */ + +static Boolean +display_exists_p (int number) +{ + char buf[64]; + void *conn; + char *fullname = NULL; + int idisplay, iscreen; + char *conn_auth_name, *conn_auth_data; + int conn_auth_namelen, conn_auth_datalen; + + extern void *_X11TransConnectDisplay (); + extern void _XDisconnectDisplay (); + + /* Since connecting to the display waits for a few seconds if the + display doesn't exist, check for trivial non-existence - if the + socket in /tmp exists or not.. (note: if the socket exists, the + server may still not, so we need to try to connect in that case..) */ + + sprintf (buf, "/tmp/.X11-unix/X%d", number); + if (access (buf, F_OK) != 0) + return FALSE; + + /* This is a private function that we shouldn't really be calling, + but it's the best way to see if the server exists (without + needing to hold the necessary authentication to use it) */ + + sprintf (buf, ":%d", number); + conn = _X11TransConnectDisplay (buf, &fullname, &idisplay, &iscreen, + &conn_auth_name, &conn_auth_namelen, + &conn_auth_data, &conn_auth_datalen); + if (conn == NULL) + return FALSE; + + _XDisconnectDisplay (conn); + return TRUE; +} + + +/* Monitoring when the system's ip addresses change. */ + +static Boolean pending_timer; + +static void +timer_callback (CFRunLoopTimerRef timer, void *info) +{ + pending_timer = FALSE; + + /* Update authentication names. Need to write .Xauthority file first + without the existing entries, then again with the new entries.. */ + + write_auth_file (FALSE); + + free_auth_items (); + make_auth_keys (server_name); + + write_auth_file (TRUE); +} + +/* This function is called when the system's ip addresses may have changed. */ +static void +ipaddr_callback (SCDynamicStoreRef store, CFArrayRef changed_keys, void *info) +{ +#if DEBUG + if (changed_keys != NULL) { + fprintf (stderr, "x11: changed sc keys: "); + CFShow (changed_keys); + } +#endif + + if (auth_file != NULL && !pending_timer) + { + CFRunLoopTimerRef timer; + + timer = CFRunLoopTimerCreate (NULL, CFAbsoluteTimeGetCurrent () + 1.0, + 0.0, 0, 0, timer_callback, NULL); + CFRunLoopAddTimer (CFRunLoopGetCurrent (), timer, + kCFRunLoopDefaultMode); + CFRelease (timer); + + pending_timer = TRUE; + } +} + +/* This code adapted from "Living in a Dynamic TCP/IP Environment" technote. */ +static Boolean +install_ipaddr_source (void) +{ + CFRunLoopSourceRef source = NULL; + + SCDynamicStoreContext context = {0}; + SCDynamicStoreRef ref; + + ref = SCDynamicStoreCreate (NULL, + CFSTR ("AddIPAddressListChangeCallbackSCF"), + ipaddr_callback, &context); + + if (ref != NULL) + { + const void *keys[4], *patterns[2]; + int i; + + keys[0] = SCDynamicStoreKeyCreateNetworkGlobalEntity (NULL, kSCDynamicStoreDomainState, kSCEntNetIPv4); + keys[1] = SCDynamicStoreKeyCreateNetworkGlobalEntity (NULL, kSCDynamicStoreDomainState, kSCEntNetIPv6); + keys[2] = SCDynamicStoreKeyCreateComputerName (NULL); + keys[3] = SCDynamicStoreKeyCreateHostNames (NULL); + + patterns[0] = SCDynamicStoreKeyCreateNetworkInterfaceEntity (NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv4); + patterns[1] = SCDynamicStoreKeyCreateNetworkInterfaceEntity (NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv6); + + if (keys[0] != NULL && keys[1] != NULL && keys[2] != NULL + && keys[3] != NULL && patterns[0] != NULL && patterns[1] != NULL) + { + CFArrayRef key_array, pattern_array; + + key_array = CFArrayCreate (NULL, keys, 4, &kCFTypeArrayCallBacks); + pattern_array = CFArrayCreate (NULL, patterns, 2, &kCFTypeArrayCallBacks); + + if (key_array != NULL || pattern_array != NULL) + { + SCDynamicStoreSetNotificationKeys (ref, key_array, pattern_array); + source = SCDynamicStoreCreateRunLoopSource (NULL, ref, 0); + } + + if (key_array != NULL) + CFRelease (key_array); + if (pattern_array != NULL) + CFRelease (pattern_array); + } + + + for (i = 0; i < 4; i++) + if (keys[i] != NULL) + CFRelease (keys[i]); + for (i = 0; i < 2; i++) + if (patterns[i] != NULL) + CFRelease (patterns[i]); + + CFRelease (ref); + } + + if (source != NULL) + { + CFRunLoopAddSource (CFRunLoopGetCurrent (), + source, kCFRunLoopDefaultMode); + CFRelease (source); + } + + return source != NULL; +} + + +/* Entrypoint. */ + +void +termination_signal_handler (int unused_sig) +{ + signal (SIGTERM, SIG_DFL); + signal (SIGHUP, SIG_DFL); + signal (SIGINT, SIG_DFL); + signal (SIGQUIT, SIG_DFL); + + longjmp (exit_continuation, 1); +} + +int +main (int argc, char **argv) +{ + char **xargv; + int i, j; + int fd; + + xargv = alloca (sizeof (char *) * (argc + 32)); + + if (!read_boolean_pref (CFSTR ("no_auth"), FALSE)) + auth_file = XauFileName (); + + /* The standard X11 behaviour is for the server to quit when the first + client exits. But it can be useful for debugging (and to mimic our + behaviour in the beta releases) to not do that. */ + + xinit_kills_server = read_boolean_pref (CFSTR ("xinit_kills_server"), TRUE); + + for (i = 1; i < argc; i++) + { + if (argv[i][0] == ':') + server_name = argv[i]; + } + + if (server_name == NULL) + { + static char name[8]; + + /* No display number specified, so search for the first unused. + + There's a big old race condition here if two servers start at + the same time, but that's fairly unlikely. We could create + lockfiles or something, but that's seems more likely to cause + problems than the race condition itself.. */ + + for (i = 0; i < MAX_DISPLAYS; i++) + { + if (!display_exists_p (i)) + break; + } + + if (i == MAX_DISPLAYS) + { + fprintf (stderr, "%s: couldn't allocate a display number", argv[0]); + exit (1); + } + + sprintf (name, ":%d", i); + server_name = name; + } + + if (auth_file != NULL) + { + /* Create new Xauth keys and add them to the .Xauthority file */ + + make_auth_keys (server_name); + write_auth_file (TRUE); + } + + /* Construct our new argv */ + + i = j = 0; + + xargv[i++] = argv[j++]; + + if (auth_file != NULL) + { + xargv[i++] = "-auth"; + xargv[i++] = auth_file; + } + + /* By default, don't listen on tcp sockets if Xauth is disabled. */ + + if (read_boolean_pref (CFSTR ("nolisten_tcp"), auth_file == NULL)) + { + xargv[i++] = "-nolisten"; + xargv[i++] = "tcp"; + } + + while (j < argc) + { + if (argv[j++][0] != ':') + xargv[i++] = argv[j-1]; + } + + xargv[i++] = (char *) server_name; + xargv[i++] = NULL; + + /* Detach from any controlling terminal and connect stdin to /dev/null */ + +#ifdef TIOCNOTTY + fd = open ("/dev/tty", O_RDONLY); + if (fd != -1) + { + ioctl (fd, TIOCNOTTY, 0); + close (fd); + } +#endif + + fd = open ("/dev/null", O_RDWR, 0); + if (fd >= 0) + { + dup2 (fd, 0); + if (fd > 0) + close (fd); + } + + if (!start_server (xargv)) + return 1; + + if (!wait_for_server ()) + { + kill (server_pid, SIGTERM); + return 1; + } + + if (!start_client ()) + { + kill (server_pid, SIGTERM); + return 1; + } + + signal (SIGCHLD, sigchld_handler); + + signal (SIGTERM, termination_signal_handler); + signal (SIGHUP, termination_signal_handler); + signal (SIGINT, termination_signal_handler); + signal (SIGQUIT, termination_signal_handler); + + if (setjmp (exit_continuation) == 0) + { + if (install_ipaddr_source ()) + CFRunLoopRun (); + else + while (1) pause (); + } + + signal (SIGCHLD, SIG_IGN); + + if (client_pid >= 0) kill (client_pid, SIGTERM); + if (server_pid >= 0) kill (server_pid, SIGTERM); + + if (auth_file != NULL) + { + /* Remove our Xauth keys */ + + write_auth_file (FALSE); + } + + free_auth_items (); + + return 0; +}