From 19c2cb3408f5a1304dc4d83c81b6cf1775f2cc7c Mon Sep 17 00:00:00 2001 From: Dean M Greer <38226388+Gcenx@users.noreply.github.com> Date: Mon, 29 Jul 2024 09:15:27 -0400 Subject: [PATCH] WineskinApp: Imported at 3.0.6 --- WineskinApp/Base.lproj/MainMenu.xib | 296 ++-- .../CustomEXE.app/Contents/MacOS/CustomEXE | 2 +- WineskinApp/NSComputerInformation.h | 23 +- WineskinApp/NSComputerInformation.m | 12 + WineskinApp/NSDropIconView.m | 1 + WineskinApp/NSExeSelection.m | 3 + WineskinApp/NSFileManager+Extension.m | 1 + WineskinApp/NSPathUtilities.m | 3 +- WineskinApp/NSPortDataLoader.h | 1 + WineskinApp/NSPortDataLoader.m | 2 + WineskinApp/NSPortManager.m | 2 +- WineskinApp/NSProgressView.m | 1 + WineskinApp/NSSavePanel+Extension.m | 1 + WineskinApp/NSString+Extension.m | 2 + WineskinApp/NSTask+Extension.m | 1 + WineskinApp/NSUtilities.m | 1 + WineskinApp/NSWebUtilities.m | 1 + WineskinApp/NSWineskinEngine.m | 1 + WineskinApp/NSWineskinPortDataWriter.h | 1 + WineskinApp/NSWineskinPortDataWriter.m | 18 +- WineskinApp/Wineskin.entitlements | 10 - .../Wineskin.xcodeproj/project.pbxproj | 14 +- WineskinApp/WineskinAppDelegate.h | 18 +- WineskinApp/WineskinAppDelegate.m | 1344 +++++++++-------- WineskinApp/Wineskin_Prefix.pch | 9 +- WineskinApp/curl | 2 +- WineskinApp/wine | 21 +- WineskinApp/wine64 | 21 +- WineskinApp/winehelp | 22 +- WineskinApp/wineserver | 25 +- 30 files changed, 1004 insertions(+), 855 deletions(-) delete mode 100644 WineskinApp/Wineskin.entitlements diff --git a/WineskinApp/Base.lproj/MainMenu.xib b/WineskinApp/Base.lproj/MainMenu.xib index c26db47..8eeff7a 100644 --- a/WineskinApp/Base.lproj/MainMenu.xib +++ b/WineskinApp/Base.lproj/MainMenu.xib @@ -1,8 +1,8 @@ - + - + @@ -308,7 +308,7 @@ - + @@ -385,7 +385,7 @@ Gw - + @@ -411,7 +411,7 @@ DQ - + @@ -420,7 +420,7 @@ DQ - + @@ -452,7 +452,7 @@ DQ - + @@ -474,7 +474,7 @@ DQ - + @@ -514,7 +514,7 @@ Gw - + @@ -598,7 +598,7 @@ Gw - + @@ -607,7 +607,7 @@ Gw - + @@ -773,7 +773,7 @@ Gw - + @@ -863,7 +863,7 @@ Gw - + @@ -890,7 +890,7 @@ Gw - + @@ -903,7 +903,7 @@ Gw - + @@ -912,7 +912,7 @@ Gw - + @@ -921,7 +921,7 @@ Gw - + @@ -934,7 +934,7 @@ Gw - + @@ -957,7 +957,7 @@ Gw - + @@ -966,7 +966,7 @@ Gw - + @@ -975,7 +975,7 @@ Gw - + @@ -984,7 +984,7 @@ Gw - @@ -1295,7 +1298,7 @@ Gw - + @@ -1304,7 +1307,7 @@ Gw - + @@ -1313,7 +1316,7 @@ Gw - + @@ -1372,7 +1375,7 @@ Gw - - - - @@ -1467,7 +1473,7 @@ Gw + + + @@ -1538,7 +1577,7 @@ Gw - - - - - - + + + + + - + diff --git a/WineskinApp/CustomEXE.app/Contents/MacOS/CustomEXE b/WineskinApp/CustomEXE.app/Contents/MacOS/CustomEXE index a41f322..77513d5 100755 --- a/WineskinApp/CustomEXE.app/Contents/MacOS/CustomEXE +++ b/WineskinApp/CustomEXE.app/Contents/MacOS/CustomEXE @@ -18,7 +18,7 @@ #################################################### # Set all variables CMACOSFOLD="$(dirname "$0")" -MACOSFOLD="$CMACOSFOLD/../../../Contents/MacOS" +MACOSFOLD="$CMACOSFOLD/../../../MacOS" cd "$MACOSFOLD" MACOSFOLD="$(echo "$PWD")" CEXENAME="$(basename "${CMACOSFOLD%/Contents/MacOS}")" diff --git a/WineskinApp/NSComputerInformation.h b/WineskinApp/NSComputerInformation.h index 2c5de0e..7763331 100755 --- a/WineskinApp/NSComputerInformation.h +++ b/WineskinApp/NSComputerInformation.h @@ -20,9 +20,28 @@ #define IS_SYSTEM_MAC_OS_10_14_OR_SUPERIOR [NSComputerInformation isSystemMacOsEqualOrSuperiorTo:@"10.14"] // Mojave #define IS_SYSTEM_MAC_OS_10_15_OR_SUPERIOR [NSComputerInformation isSystemMacOsEqualOrSuperiorTo:@"10.15"] // Catalina #define IS_SYSTEM_MAC_OS_10_15_4_OR_SUPERIOR [NSComputerInformation isSystemMacOsEqualOrSuperiorTo:@"10.15.4"] // Catalina ldtset -#define IS_SYSTEM_MAC_OS_11_0_OR_SUPERIOR [NSComputerInformation isSystemMacOsEqualOrSuperiorTo:@"11.00"] // Big Sur +#define IS_SYSTEM_MAC_OS_11_0_OR_SUPERIOR [NSComputerInformation isSystemMacOsEqualOrSuperiorTo:@"11.00"] // Big Sur #define IS_SYSTEM_MAC_OS_12_0_OR_SUPERIOR [NSComputerInformation isSystemMacOsEqualOrSuperiorTo:@"12.0"] // Monterey #define IS_SYSTEM_MAC_OS_13_0_OR_SUPERIOR [NSComputerInformation isSystemMacOsEqualOrSuperiorTo:@"13.0"] // Ventura +#define IS_SYSTEM_MAC_OS_14_0_OR_SUPERIOR [NSComputerInformation isSystemMacOsEqualOrSuperiorTo:@"14.0"] // Sonoma + +#define IS_SYSTEM_MAC_OS_SNOW_LEOPARD_OR_SUPERIOR IS_SYSTEM_MAC_OS_10_6_OR_SUPERIOR +#define IS_SYSTEM_MAC_OS_LION_OR_SUPERIOR IS_SYSTEM_MAC_OS_10_7_OR_SUPERIOR +#define IS_SYSTEM_MAC_OS_MOUNTAIN_LION_OR_SUPERIOR IS_SYSTEM_MAC_OS_10_8_OR_SUPERIOR +#define IS_SYSTEM_MAC_OS_MAVERICKS_OR_SUPERIOR IS_SYSTEM_MAC_OS_10_9_OR_SUPERIOR +#define IS_SYSTEM_MAC_OS_YOSEMITE_OR_SUPERIOR IS_SYSTEM_MAC_OS_10_10_OR_SUPERIOR +#define IS_SYSTEM_MAC_OS_EL_CAPITAN_OR_SUPERIOR IS_SYSTEM_MAC_OS_10_11_OR_SUPERIOR +#define IS_SYSTEM_MAC_OS_SIERRA_OR_SUPERIOR IS_SYSTEM_MAC_OS_10_12_OR_SUPERIOR +#define IS_SYSTEM_MAC_OS_HIGH_SIERRA_OR_SUPERIOR IS_SYSTEM_MAC_OS_10_13_OR_SUPERIOR +#define IS_SYSTEM_MAC_OS_MOJAVE_OR_SUPERIOR IS_SYSTEM_MAC_OS_10_14_OR_SUPERIOR +#define IS_SYSTEM_MAC_OS_CATALINA_OR_SUPERIOR IS_SYSTEM_MAC_OS_10_15_OR_SUPERIOR +#define IS_SYSTEM_MAC_OS_BIG_SUR_OR_SUPERIOR IS_SYSTEM_MAC_OS_11_0_OR_SUPERIOR +#define IS_SYSTEM_MAC_OS_MONTRREY_OR_SUPERIOR IS_SYSTEM_MAC_OS_12_0_OR_SUPERIOR +#define IS_SYSTEM_MAC_OS_VENTURA_OR_SUPERIOR IS_SYSTEM_MAC_OS_13_0_OR_SUPERIOR +#define IS_SYSTEM_MAC_OS_SONOMA_OR_SUPERIOR IS_SYSTEM_MAC_OS_14_0_OR_SUPERIOR + +#define IsSetLdtSupported [NSComputerInformation isSystemMacOsEqualOrSuperiorTo:@"10.15.4"] // Allow setting i386_set_ldt without entitlement +#define IsProcessTranslated [NSComputerInformation isProcessTranslated] // Check if running under Rosetta2 #import @@ -35,6 +54,8 @@ +(BOOL)isComputerMacDriverCompatible; ++(BOOL)isProcessTranslated; + @end #endif diff --git a/WineskinApp/NSComputerInformation.m b/WineskinApp/NSComputerInformation.m index be4abee..6e26cd6 100755 --- a/WineskinApp/NSComputerInformation.m +++ b/WineskinApp/NSComputerInformation.m @@ -7,6 +7,7 @@ // #import "NSComputerInformation.h" + #import "NSUtilities.h" #import "VMMVersion.h" #import "NSTask+Extension.h" @@ -66,5 +67,16 @@ +(BOOL)isComputerMacDriverCompatible return [NSComputerInformation isSystemMacOsEqualOrSuperiorTo:@"10.6.8"]; } ++(BOOL)isProcessTranslated +{ + // Starting with macOS Big Sur 11.0.1 with Apple Silicon systems + if ([self isSystemMacOsEqualOrSuperiorTo:@"11.0.1"]) { + NSString* appReturn = [NSTask runProgram:@"sysctl" atRunPath:nil withFlags:@[@"-in", @"sysctl.proc_translated"] wait:YES]; + return [appReturn boolValue]; + } else { + return false; + } +} + @end diff --git a/WineskinApp/NSDropIconView.m b/WineskinApp/NSDropIconView.m index eb1d7ed..dd1c6a8 100755 --- a/WineskinApp/NSDropIconView.m +++ b/WineskinApp/NSDropIconView.m @@ -7,6 +7,7 @@ // #import "NSDropIconView.h" + #import "NSData+Extension.h" #import "NSTask+Extension.h" #import "NSImage+Extension.h" diff --git a/WineskinApp/NSExeSelection.m b/WineskinApp/NSExeSelection.m index a2304a9..496e912 100755 --- a/WineskinApp/NSExeSelection.m +++ b/WineskinApp/NSExeSelection.m @@ -7,8 +7,11 @@ // #import "NSExeSelection.h" + #import "NSPortManager.h" + #import "NSPathUtilities.h" + #import "NSString+Extension.h" #import "NSFileManager+Extension.h" diff --git a/WineskinApp/NSFileManager+Extension.m b/WineskinApp/NSFileManager+Extension.m index f4315c7..b240071 100755 --- a/WineskinApp/NSFileManager+Extension.m +++ b/WineskinApp/NSFileManager+Extension.m @@ -7,6 +7,7 @@ // #import "NSFileManager+Extension.h" + #import "NSAlert+Extension.h" #import "NSTask+Extension.h" diff --git a/WineskinApp/NSPathUtilities.m b/WineskinApp/NSPathUtilities.m index 409039f..75291a2 100755 --- a/WineskinApp/NSPathUtilities.m +++ b/WineskinApp/NSPathUtilities.m @@ -7,6 +7,7 @@ // #import "NSPathUtilities.h" + #import "NSString+Extension.h" #import "NSFileManager+Extension.h" @@ -15,7 +16,7 @@ @implementation NSPathUtilities +(NSString*)wineskinAppBinaryForPortAtPath:(NSString*)path { // Used to run the Wineskin App which resides inside Wineskin wrappers - return [path stringByAppendingString:@"/Wineskin.app/Contents/MacOS/Wineskin"]; + return [path stringByAppendingString:@"/Contents/Wineskin.app/Contents/MacOS/Wineskin"]; } +(NSString*)wineskinLauncherBinForPortAtPath:(NSString*)path { diff --git a/WineskinApp/NSPortDataLoader.h b/WineskinApp/NSPortDataLoader.h index 5698816..c71317f 100755 --- a/WineskinApp/NSPortDataLoader.h +++ b/WineskinApp/NSPortDataLoader.h @@ -7,6 +7,7 @@ // #import + #import "NSPortManager.h" #import "NSWineskinEngine.h" diff --git a/WineskinApp/NSPortDataLoader.m b/WineskinApp/NSPortDataLoader.m index 7b13045..64b71f3 100644 --- a/WineskinApp/NSPortDataLoader.m +++ b/WineskinApp/NSPortDataLoader.m @@ -9,7 +9,9 @@ #import "NSPortDataLoader.h" #import "NSUtilities.h" #import "NSPathUtilities.h" + #import "NSDropIconView.h" + #import "NSAlert+Extension.h" #import "NSImage+Extension.h" #import "NSString+Extension.h" diff --git a/WineskinApp/NSPortManager.m b/WineskinApp/NSPortManager.m index 1b13fa7..9324436 100644 --- a/WineskinApp/NSPortManager.m +++ b/WineskinApp/NSPortManager.m @@ -209,7 +209,7 @@ -(NSMutableDictionary*)getFunctionFromDescription:(NSString*)description } -(NSArray*)getAvailableWinetricksList { - NSString* winetricksPath = [NSString stringWithFormat:@"%@/Wineskin.app/Contents/Resources/winetricks",[[NSBundle mainBundle] bundlePath]]; + NSString* winetricksPath = [NSString stringWithFormat:@"%@/Contents/Wineskin.app/Contents/Resources/winetricks",[[NSBundle mainBundle] bundlePath]]; NSString* winetricksRaw = [[NSString alloc] initWithContentsOfFile:winetricksPath encoding:NSASCIIStringEncoding error:nil]; NSMutableArray* newList = [[NSMutableArray alloc] init]; diff --git a/WineskinApp/NSProgressView.m b/WineskinApp/NSProgressView.m index 46fe06d..fd3333d 100755 --- a/WineskinApp/NSProgressView.m +++ b/WineskinApp/NSProgressView.m @@ -7,6 +7,7 @@ // #import "NSProgressView.h" + #import "NSThread+Extension.h" @implementation NSProgressView diff --git a/WineskinApp/NSSavePanel+Extension.m b/WineskinApp/NSSavePanel+Extension.m index e0b188b..03230b1 100755 --- a/WineskinApp/NSSavePanel+Extension.m +++ b/WineskinApp/NSSavePanel+Extension.m @@ -7,6 +7,7 @@ // #import "NSSavePanel+Extension.h" + #import "NSComputerInformation.h" @implementation NSSavePanel (PKSavePanel) diff --git a/WineskinApp/NSString+Extension.m b/WineskinApp/NSString+Extension.m index 7247dd5..2507e51 100755 --- a/WineskinApp/NSString+Extension.m +++ b/WineskinApp/NSString+Extension.m @@ -7,9 +7,11 @@ // #import "NSString+Extension.h" + #import "NSData+Extension.h" #import "NSTask+Extension.h" #import "NSAlert+Extension.h" + #import "NSComputerInformation.h" @implementation NSString (PKString) diff --git a/WineskinApp/NSTask+Extension.m b/WineskinApp/NSTask+Extension.m index f4a312a..7eeec39 100755 --- a/WineskinApp/NSTask+Extension.m +++ b/WineskinApp/NSTask+Extension.m @@ -7,6 +7,7 @@ // #import "NSTask+Extension.h" + #import "NSAlert+Extension.h" #import "NSFileManager+Extension.h" diff --git a/WineskinApp/NSUtilities.m b/WineskinApp/NSUtilities.m index 55df1a8..31cec87 100755 --- a/WineskinApp/NSUtilities.m +++ b/WineskinApp/NSUtilities.m @@ -7,6 +7,7 @@ // #import "NSUtilities.h" + #import "NSTask+Extension.h" #import "NSString+Extension.h" #import "NSThread+Extension.h" diff --git a/WineskinApp/NSWebUtilities.m b/WineskinApp/NSWebUtilities.m index a2b0c33..32bf30a 100755 --- a/WineskinApp/NSWebUtilities.m +++ b/WineskinApp/NSWebUtilities.m @@ -8,6 +8,7 @@ #import "NSWebUtilities.h" #import + #import "NSString+Extension.h" #define SECONDS_IN_MINUTE 60 diff --git a/WineskinApp/NSWineskinEngine.m b/WineskinApp/NSWineskinEngine.m index e2231a2..7716182 100755 --- a/WineskinApp/NSWineskinEngine.m +++ b/WineskinApp/NSWineskinEngine.m @@ -7,6 +7,7 @@ // #import "NSWineskinEngine.h" + #import "NSTask+Extension.h" #import "NSAlert+Extension.h" #import "NSString+Extension.h" diff --git a/WineskinApp/NSWineskinPortDataWriter.h b/WineskinApp/NSWineskinPortDataWriter.h index 2a875de..a8d2ada 100644 --- a/WineskinApp/NSWineskinPortDataWriter.h +++ b/WineskinApp/NSWineskinPortDataWriter.h @@ -7,6 +7,7 @@ // #import + #import "NSPortManager.h" @interface NSWineskinPortDataWriter : NSObject diff --git a/WineskinApp/NSWineskinPortDataWriter.m b/WineskinApp/NSWineskinPortDataWriter.m index 3f7eff0..233df0b 100644 --- a/WineskinApp/NSWineskinPortDataWriter.m +++ b/WineskinApp/NSWineskinPortDataWriter.m @@ -7,9 +7,12 @@ // #import "NSWineskinPortDataWriter.h" + #import "NSPathUtilities.h" #import "NSWineskinEngine.h" + #import "NSComputerInformation.h" + #import "NSData+Extension.h" #import "NSTask+Extension.h" #import "NSString+Extension.h" @@ -49,17 +52,6 @@ +(void)setMainExePath:(NSString*)exePath atPort:(NSPortManager*)port //TODO: some 32bit exe files need to use this when launched via wine64 [port setPlistObject:@(![winPath.lowercaseString hasSuffix:@".exe"]) forKey:WINESKIN_WRAPPER_PLIST_KEY_RUN_PATH_IS_NOT_EXE]; [port setPlistObject:flags forKey:WINESKIN_WRAPPER_PLIST_KEY_RUN_PATH_FLAGS]; - - //TODO: Origin.exe needs to use Start.exe - if ([winPath contains:@"Origin.exe"]) - { - [port setPlistObject:@TRUE forKey:WINESKIN_WRAPPER_PLIST_KEY_RUN_PATH_IS_NOT_EXE]; - } - //TODO: Steam.exe needs to use Start.exe - if ([winPath contains:@"Steam.exe"]) - { - [port setPlistObject:@TRUE forKey:WINESKIN_WRAPPER_PLIST_KEY_RUN_PATH_IS_NOT_EXE]; - } } else { @@ -240,8 +232,8 @@ +(BOOL)setMainExeName:(NSString*)name version:(NSString*)version icon:(NSImage*) } +(BOOL)addCustomExeWithName:(NSString*)name version:(NSString*)version icon:(NSImage*)icon path:(NSString*)path atPortAtPath:(NSString*)portPath { - NSString* customEXEapp = [NSString stringWithFormat:@"%@/Wineskin.app/Contents/Resources/CustomEXE.app",portPath]; - NSString* customEXEPath = [NSString stringWithFormat:@"%@/%@.app",portPath,name]; + NSString* customEXEapp = [NSString stringWithFormat:@"%@/Contents/Wineskin.app/Contents/Resources/CustomEXE.app",portPath]; + NSString* customEXEPath = [NSString stringWithFormat:@"%@/Contents/%@.app",portPath,name]; [[NSFileManager defaultManager] copyItemAtPath:customEXEapp toPath:customEXEPath]; NSPortManager* activePort = [NSPortManager managerWithCustomExePath:customEXEPath]; diff --git a/WineskinApp/Wineskin.entitlements b/WineskinApp/Wineskin.entitlements deleted file mode 100644 index 74342d2..0000000 --- a/WineskinApp/Wineskin.entitlements +++ /dev/null @@ -1,10 +0,0 @@ - - - - - com.apple.security.automation.apple-events - - com.apple.security.cs.allow-unsigned-executable-memory - - - diff --git a/WineskinApp/Wineskin.xcodeproj/project.pbxproj b/WineskinApp/Wineskin.xcodeproj/project.pbxproj index 2e90816..de226f6 100644 --- a/WineskinApp/Wineskin.xcodeproj/project.pbxproj +++ b/WineskinApp/Wineskin.xcodeproj/project.pbxproj @@ -152,7 +152,6 @@ A14ED61426E1021B0022EC36 /* winefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = winefile; sourceTree = ""; }; A14ED61526E1021B0022EC36 /* notepad */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = notepad; sourceTree = ""; }; A14ED61626E1021B0022EC36 /* winemine */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = winemine; sourceTree = ""; }; - A184191824946DD7008FDFC7 /* Wineskin.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Wineskin.entitlements; sourceTree = ""; }; A1902F272897500F0085F0C9 /* realpath */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = realpath; sourceTree = ""; }; A1938A2C278168F700B99A8F /* wineserver */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = wineserver; sourceTree = ""; }; A1942B2D28C674B600332F75 /* wineskin7z */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = wineskin7z; sourceTree = ""; }; @@ -227,7 +226,6 @@ 29B97314FDCFA39411CA2CEA /* Wineskin */ = { isa = PBXGroup; children = ( - A184191824946DD7008FDFC7 /* Wineskin.entitlements */, 080E96DDFE201D6D7F000001 /* Classes */, 29B97315FDCFA39411CA2CEA /* Other Sources */, 29B97317FDCFA39411CA2CEA /* Resources */, @@ -571,7 +569,7 @@ COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; CREATE_INFOPLIST_SECTION_IN_BINARY = NO; - CURRENT_PROJECT_VERSION = 2.9.2.1; + CURRENT_PROJECT_VERSION = 3.0.6; DEVELOPMENT_TEAM = ""; ENABLE_HARDENED_RUNTIME = NO; GCC_DYNAMIC_NO_PIC = NO; @@ -588,8 +586,8 @@ GCC_WARN_UNUSED_PARAMETER = NO; INFOPLIST_FILE = "Wineskin-Info.plist"; INSTALL_PATH = "$(HOME)/Applications"; - MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 2.9.2.1; + MACOSX_DEPLOYMENT_TARGET = 10.15.4; + MARKETING_VERSION = 3.0.6; ONLY_ACTIVE_ARCH = NO; PRODUCT_BUNDLE_IDENTIFIER = com.unofficial.wineskin; PRODUCT_NAME = Wineskin; @@ -610,7 +608,7 @@ CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; CREATE_INFOPLIST_SECTION_IN_BINARY = NO; - CURRENT_PROJECT_VERSION = 2.9.2.1; + CURRENT_PROJECT_VERSION = 3.0.6; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ""; ENABLE_HARDENED_RUNTIME = NO; @@ -626,8 +624,8 @@ GCC_WARN_UNUSED_PARAMETER = NO; INFOPLIST_FILE = "Wineskin-Info.plist"; INSTALL_PATH = "$(HOME)/Applications"; - MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 2.9.2.1; + MACOSX_DEPLOYMENT_TARGET = 10.15.4; + MARKETING_VERSION = 3.0.6; PRODUCT_BUNDLE_IDENTIFIER = com.unofficial.wineskin; PRODUCT_NAME = Wineskin; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/WineskinApp/WineskinAppDelegate.h b/WineskinApp/WineskinAppDelegate.h index 3b1b88e..d2e5216 100644 --- a/WineskinApp/WineskinAppDelegate.h +++ b/WineskinApp/WineskinAppDelegate.h @@ -53,7 +53,8 @@ IBOutlet NSButton *extEditButton; IBOutlet NSButton *extPlusButton; IBOutlet NSButton *extMinusButton; - + IBOutlet NSButton *gptkCheckBoxButton; + //advanced menu - Tools Tab IBOutlet NSButton *winecfgButton; IBOutlet NSButton *regeditButton; @@ -72,13 +73,14 @@ //advanced menu - Options Tab IBOutlet NSButton *alwaysMakeLogFilesCheckBoxButton; - IBOutlet NSButton *setMaxFilesCheckBoxButton; IBOutlet NSButton *mapUserFoldersCheckBoxButton; IBOutlet NSButton *modifyMappingsButton; IBOutlet NSButton *confirmQuitCheckBoxButton; IBOutlet NSButton *fntoggleCheckBoxButton; IBOutlet NSButton *commandCheckBoxButton; IBOutlet NSButton *optionCheckBoxButton; + IBOutlet NSButton *esyncCheckBoxButton; + IBOutlet NSButton *msyncCheckBoxButton; //advanced menu - Advanced Tab IBOutlet NSButton *WinetricksNoLogsButton; @@ -86,7 +88,10 @@ IBOutlet NSButton *winedbgDisabledButton; IBOutlet NSButton *geckoCheckBoxButton; IBOutlet NSButtonCell *monoCheckBoxButton; - + IBOutlet NSButton *metalhudCheckBoxButton; + IBOutlet NSButton *fastmathCheckBoxButton; + IBOutlet NSButton *cxmoltenvkCheckBoxButton; + //change engine window IBOutlet NSWindow *changeEngineWindow; IBOutlet NSPopUpButton *changeEngineWindowPopUpButton; @@ -178,6 +183,9 @@ - (IBAction)installWindowsSoftwareButtonPressed:(id)sender; - (IBAction)chooseExeOKButtonPressed:(id)sender; - (IBAction)advancedButtonPressed:(id)sender; +- (IBAction)esyncButtonPressed:(id)sender; +- (IBAction)msyncButtonPressed:(id)sender; + //Installer window methods - (IBAction)chooseSetupExecutableButtonPressed:(id)sender; - (IBAction)copyAFolderInsideButtonPressed:(id)sender; @@ -221,7 +229,6 @@ //advanced menu - Options Tab - (IBAction)alwaysMakeLogFilesCheckBoxButtonPressed:(id)sender; -- (IBAction)setMaxFilesCheckBoxButtonPressed:(id)sender; - (IBAction)mapUserFoldersCheckBoxButtonPressed:(id)sender; - (IBAction)confirmQuitCheckBoxButtonPressed:(id)sender; - (IBAction)modifyMappingsButtonPressed:(id)sender; @@ -235,6 +242,9 @@ - (IBAction)winedbgDisabledButtonPressed:(id)sender; - (IBAction)geckoButtonPressed:(id)sender; - (IBAction)monoButtonPressed:(id)sender; +- (IBAction)metahudButtonPress:(id)sender; +- (IBAction)fastmathButtonPress:(id)sender; +- (IBAction)cxmoltenvkButtonPress:(id)sender; //Winetricks - (IBAction)winetricksButtonPressed:(id)sender; diff --git a/WineskinApp/WineskinAppDelegate.m b/WineskinApp/WineskinAppDelegate.m index a19b56d..47632dc 100644 --- a/WineskinApp/WineskinAppDelegate.m +++ b/WineskinApp/WineskinAppDelegate.m @@ -14,6 +14,7 @@ #import "NSString+Extension.h" #import "NSSavePanel+Extension.h" #import "NSFileManager+Extension.h" +#import "NSThread+Extension.h" #import "NSMutableArray+Extension.h" #import "NSMutableDictionary+Extension.h" @@ -37,7 +38,7 @@ @implementation WineskinAppDelegate -(NSString*)wrapperPath { - return [[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent]; + return [[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByDeletingLastPathComponent]; } -(NSString*)wineskinPath { @@ -51,12 +52,12 @@ -(NSString*)wswineBundlePath { return [NSString stringWithFormat:@"%@/Contents/SharedSupport/wine",self.wrapperPath]; } + - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { fm = [NSFileManager defaultManager]; portManager = [NSPortManager managerWithPath:self.wrapperPath]; - if (!portManager) - { + if (!portManager) { [NSApp terminate:nil]; } @@ -65,7 +66,7 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification [self setWinetricksSelectedList:[NSMutableDictionary dictionary]]; [self setWinetricksList:[NSDictionary dictionary]]; [self setWinetricksFilteredList:[self winetricksList]]; - + [waitWheel startAnimation:self]; [busyWindow makeKeyAndOrderFront:self]; shPIDs = [[NSMutableArray alloc] init]; @@ -74,121 +75,141 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification disableButtonCounter=0; disableXButton=NO; usingAdvancedWindow=NO; - + [self installEngine]; [self loadAllData]; - + NSImage *theImage = [[NSImage alloc] initByReferencingFile:[NSString stringWithFormat:@"%@/Contents/Resources/Wineskin.icns",self.wrapperPath]]; [iconImageView setImage:theImage]; - + [window makeKeyAndOrderFront:self]; [busyWindow orderOut:self]; - + [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Defaults" ofType:@"plist"]]]; } + - (void)sleepWithRunLoopForSeconds:(NSInteger)seconds { // Sleep while still running the run loop if (![[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:seconds]]) sleep(seconds); // Fallback, should never happen } + - (void)setButtonsState:(BOOL)state { - NSString* engineString = [NSPortDataLoader engineOfPortAtPath:self.wrapperPath]; - NSWineskinEngine* engine = [NSWineskinEngine wineskinEngineWithString:engineString]; - - - [confirmQuitCheckBoxButton setEnabled:state]; - [advancedInstallSoftwareButton setEnabled:state]; - [winetricksButton setEnabled:state]; - [testRunButton setEnabled:state]; - - - // ****Configure**** - [windowsExeTextField setEnabled:state]; - [exeBrowseButton setEnabled:state]; - [customCommandsTextField setEnabled:state]; - [menubarNameTextField setEnabled:state]; - [versionTextField setEnabled:state]; - [wineDebugTextField setEnabled:state]; - [extPopUpButton setEnabled:state]; - [extEditButton setEnabled:NO]; - [extPlusButton setEnabled:state]; - [extMinusButton setEnabled:state]; - [iconImageView setEditable:state]; - [iconBrowseButton setEnabled:state]; - - - // ****Tools**** - //winecfg - //regedit - //taskmgr - //cmd - //controll - //BLANK - [customExeButton setEnabled:state]; - //last run log - [logsButtonPressed setEnabled:state]; - [commandLineWineTestButton setEnabled:state]; - //kill wineskin processes - [refreshWrapperButton setEnabled:state]; - [rebuildWrapperButton setEnabled:state]; - [updateWrapperButton setEnabled:state]; - [changeEngineButton setEnabled:state]; - //BLANK - - - // ****Options**** - [alwaysMakeLogFilesCheckBoxButton setEnabled:state]; - [setMaxFilesCheckBoxButton setEnabled:state]; - [mapUserFoldersCheckBoxButton setEnabled:state]; - [modifyMappingsButton setEnabled:state]; - [fntoggleCheckBoxButton setEnabled:state]; - - if (engine.isCompatibleWithCommandCtrl) - { - [commandCheckBoxButton setEnabled:state]; - } else { - [commandCheckBoxButton setEnabled:NO]; - } - - if (engine.isCompatibleWithOptionAlt) - { - [optionCheckBoxButton setEnabled:state]; - } else { - [optionCheckBoxButton setEnabled:NO]; - } - - // Option does not work above 10.8 so disable it - if (IS_SYSTEM_MAC_OS_10_9_OR_SUPERIOR) - { - [disableCPUsCheckBoxButton setEnabled:NO]; - } - else - { - //TODO change option to be disabled by default but enabled if 10.8 and below - [disableCPUsCheckBoxButton setEnabled:state]; - } - - - // ****Advanced**** - [WinetricksNoLogsButton setEnabled:state]; - [winedbgDisabledButton setEnabled:state]; - [geckoCheckBoxButton setEnabled:state]; - [monoCheckBoxButton setEnabled:state]; - - - // TODO: The code below seems to be causing a crash sometimes. Remove? - if (state) { - [toolRunningPI stopAnimation:self]; - } - else { - [toolRunningPI startAnimation:self]; - } - - [toolRunningPIText setHidden:state]; - disableXButton = !state; + [NSThread dispatchBlockInMainQueue:^{ + NSString* engineString = [NSPortDataLoader engineOfPortAtPath:self.wrapperPath]; + NSWineskinEngine* engine = [NSWineskinEngine wineskinEngineWithString:engineString]; + + [confirmQuitCheckBoxButton setEnabled:state]; + [advancedInstallSoftwareButton setEnabled:state]; + [winetricksButton setEnabled:state]; + [testRunButton setEnabled:state]; + + // ****Configure**** + [windowsExeTextField setEnabled:state]; + [exeBrowseButton setEnabled:state]; + [customCommandsTextField setEnabled:state]; + [menubarNameTextField setEnabled:state]; + [versionTextField setEnabled:state]; + [wineDebugTextField setEnabled:state]; + [extPopUpButton setEnabled:state]; + [extEditButton setEnabled:NO]; + [extPlusButton setEnabled:state]; + [extMinusButton setEnabled:state]; + [iconImageView setEditable:state]; + [iconBrowseButton setEnabled:state]; + + if (IS_SYSTEM_MAC_OS_SONOMA_OR_SUPERIOR && IsProcessTranslated) { + if ([fm fileExistsAtPath:[NSString stringWithFormat:@"%@/d3dmetal_force",self.wswineBundlePath]]) { + [gptkCheckBoxButton setEnabled:NO]; + [gptkCheckBoxButton setState:YES]; + } else { + [gptkCheckBoxButton setEnabled:state]; + } + } else { + [gptkCheckBoxButton setEnabled:NO]; + } + + // ****Tools**** + //winecfg + //regedit + //taskmgr + //cmd + //controll + //BLANK + [customExeButton setEnabled:state]; + //last run log + [logsButtonPressed setEnabled:state]; + [commandLineWineTestButton setEnabled:state]; + //kill wineskin processes + [refreshWrapperButton setEnabled:state]; + [rebuildWrapperButton setEnabled:state]; + [updateWrapperButton setEnabled:state]; + [changeEngineButton setEnabled:state]; + //BLANK + + // ****Options**** + [alwaysMakeLogFilesCheckBoxButton setEnabled:state]; + [mapUserFoldersCheckBoxButton setEnabled:state]; + [modifyMappingsButton setEnabled:state]; + [fntoggleCheckBoxButton setEnabled:state]; + + if (engine.isCompatibleWithCommandCtrl) { + [commandCheckBoxButton setEnabled:state]; + } else { + [commandCheckBoxButton setEnabled:NO]; + } + + if (engine.isCompatibleWithOptionAlt) { + [optionCheckBoxButton setEnabled:state]; + } else { + [optionCheckBoxButton setEnabled:NO]; + } + + [esyncCheckBoxButton setEnabled:state]; + [msyncCheckBoxButton setEnabled:state]; + + // Option does not work above 10.8 so disable it + if (IS_SYSTEM_MAC_OS_MAVERICKS_OR_SUPERIOR) { + [disableCPUsCheckBoxButton setEnabled:NO]; + } else { + //TODO change option to be disabled by default but enabled if 10.8 and below + [disableCPUsCheckBoxButton setEnabled:state]; + } + + // ****Advanced**** + [WinetricksNoLogsButton setEnabled:state]; + [winedbgDisabledButton setEnabled:state]; + [geckoCheckBoxButton setEnabled:state]; + [monoCheckBoxButton setEnabled:state]; + [metalhudCheckBoxButton setEnabled:state]; + + if ([fm fileExistsAtPath:[NSString stringWithFormat:@"%@/d3dmetal_force",self.wswineBundlePath]]) { + [cxmoltenvkCheckBoxButton setEnabled:NO]; + [cxmoltenvkCheckBoxButton setState:NO]; + [fastmathCheckBoxButton setEnabled:NO]; + } else { + if ([[self->portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_D3DMETAL] intValue] == 1) { + [cxmoltenvkCheckBoxButton setEnabled:NO]; + } else { + [cxmoltenvkCheckBoxButton setEnabled:state]; + [fastmathCheckBoxButton setEnabled:state]; + } + [fastmathCheckBoxButton setEnabled:state]; + } + + if (state) { + [toolRunningPI stopAnimation:self]; + } else { + [toolRunningPI startAnimation:self]; + } + + [toolRunningPIText setHidden:state]; + disableXButton = !state; + }]; } + - (void)enableButtons { [self loadAllData]; @@ -196,15 +217,18 @@ - (void)enableButtons if (disableButtonCounter >= 1) return; [self setButtonsState:YES]; } + - (void)disableButtons { [self setButtonsState:NO]; disableButtonCounter++; } + - (void)systemCommand:(NSString *)commandToRun withArgs:(NSArray *)args { [[NSTask launchedTaskWithLaunchPath:commandToRun arguments:args] waitUntilExit]; } + - (NSString *)systemCommandWithOutputReturned:(NSString *)command { FILE *fp; @@ -219,10 +243,12 @@ - (NSString *)systemCommandWithOutputReturned:(NSString *)command returnString = [returnString substringToIndex:[returnString rangeOfString:@"\n" options:NSBackwardsSearch].location]; return returnString; } + - (IBAction)topMenuHelpSelected:(id)sender { [helpWindow makeKeyAndOrderFront:self]; } + - (IBAction)aboutWindow:(id)sender { [aboutWindowVersionNumber setStringValue:WINESKIN_VERSION]; @@ -236,27 +262,27 @@ - (NSArray*)runnableSubpathsInWrapperCDrive { NSArray *filesTEMP1 = [fm subpathsOfDirectoryAtPath:self.cDrivePathForWrapper error:nil]; NSMutableArray *files1 = [[NSMutableArray alloc] init]; - for (NSString *item in filesTEMP1) - { + for (NSString *item in filesTEMP1) { if ([[item lowercaseString] hasSuffix:@".exe"] || [[item lowercaseString] hasSuffix:@".bat"] || - [[item lowercaseString] hasSuffix:@".msi"]) - { + [[item lowercaseString] hasSuffix:@".msi"]) { [files1 addObject:item]; } } - return files1; } + - (IBAction)wineskinWebsiteButtonPressed:(id)sender { [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://github.com/Gcenx/WineskinServer/"]]; } + - (IBAction)installWindowsSoftwareButtonPressed:(id)sender { [window orderOut:self]; [advancedWindow orderOut:self]; [installerWindow makeKeyAndOrderFront:self]; } + - (IBAction)chooseSetupExecutableButtonPressed:(id)sender { // have user choose install program @@ -269,205 +295,189 @@ - (IBAction)chooseSetupExecutableButtonPressed:(id)sender [panel setAllowsMultipleSelection:NO]; [panel setInitialDirectory:@"/"]; [panel setAllowedFileTypes:EXTENSIONS_COMPATIBLE_WITH_WINESKIN_WRAPPER]; - - if ([panel runModal] == 0) - { + + if ([panel runModal] == 0) { return; } - + NSString* selectedInstaller = [[[panel URLs] objectAtIndex:0] path]; - + //show busy window [busyWindow makeKeyAndOrderFront:self]; // get rid of main window [installerWindow orderOut:self]; [advancedWindow orderOut:self]; - + NSString* wrapperPath = self.wrapperPath; - + //make 1st array of .exe, .msi, and .bat files NSArray *files1 = self.runnableSubpathsInWrapperCDrive; - + //run install in Wine [self systemCommand:[NSPathUtilities wineskinLauncherBinForPortAtPath:wrapperPath] withArgs:@[@"WSS-installer",selectedInstaller]]; - + //make 2nd array of .exe, .msi, and .bat files NSArray *files2 = self.runnableSubpathsInWrapperCDrive; - + NSMutableArray *finalList = [[NSMutableArray alloc] init]; //fill new array of new .exe, .msi, and .bat files - for (NSString *item2 in files2) - { - if (![files1 containsObject:item2]) - { - if (![item2 hasPrefix:@"users/Wineskin"] && ![item2 hasPrefix:@"windows/Installer"] && ![item2 isEqualToString:@"nothing.exe"]) - { + for (NSString *item2 in files2) { + if (![files1 containsObject:item2]) { + if (![item2 hasPrefix:@"users/Wineskin"] && ![item2 hasPrefix:@"windows/Installer"] && ![item2 isEqualToString:@"nothing.exe"]) { [finalList addObject:[NSString stringWithFormat:@"\"C:/%@\"",item2]]; } } } - + //display warning if final array is 0 length and exit method - if (finalList.count == 0) - { + if (finalList.count == 0) { //close busy window [busyWindow orderOut:self]; - + [NSAlert showAlertOfType:NSAlertTypeWarning withMessage:@"No new executables found!\n\nMaybe the installer failed...?\n\nIf you tried to install somewhere other than C: drive (drive_c in the wrapper) then you will get this message too. All software must be installed in C: drive."]; - + [installerWindow makeKeyAndOrderFront:self]; return; } - + // populate choose exe list [exeChoicePopUp removeAllItems]; - for (NSString *item in finalList) - { + for (NSString *item in finalList) { [exeChoicePopUp addItemWithTitle:item]; } //if set EXE is not located inside of the wrapper,show choose exe window NSString* mainExeWindowsPath = [NSString stringWithFormat:@"C:%@",[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_RUN_PATH]]; NSString* mainExePath = [NSPathUtilities getMacPathForWindowsPath:mainExeWindowsPath ofWrapper:wrapperPath]; - - if ([fm fileExistsAtPath:mainExePath]) - { - if (usingAdvancedWindow) - { + + if ([fm fileExistsAtPath:mainExePath]) { + if (usingAdvancedWindow) { [advancedWindow makeKeyAndOrderFront:self]; - } - else - { + } else { [window makeKeyAndOrderFront:self]; } - } - else - { + } else { [chooseExeWindow makeKeyAndOrderFront:self]; } - + //close busy window [busyWindow orderOut:self]; } + - (IBAction)copyAFolderInsideButtonPressed:(id)sender { [self copyFolderRemovingOriginal:NO]; } + - (IBAction)moveAFolderInsideButtonPressed:(id)sender { [self copyFolderRemovingOriginal:YES]; } + - (void)copyFolderRemovingOriginal:(BOOL)removeOriginal { NSOpenPanel *panel = [[NSOpenPanel alloc] init]; - if (removeOriginal) - [panel setWindowTitle:NSLocalizedString(@"Please choose the Folder to MOVE in",nil)]; - else + if (removeOriginal) { + [panel setWindowTitle:NSLocalizedString(@"Please choose the Folder to MOVE in",nil)]; + } else { [panel setWindowTitle:NSLocalizedString(@"Please choose the Folder to COPY in",nil)]; + } [panel setPrompt:NSLocalizedString(@"Choose",nil)]; [panel setCanChooseDirectories:YES]; [panel setCanChooseFiles:NO]; [panel setAllowsMultipleSelection:NO]; [panel setInitialDirectory:@"/"]; - - if ([panel runModal] == 0) - { + + if ([panel runModal] == 0) { return; } - + //show busy window [busyWindow makeKeyAndOrderFront:self]; // get rid of installer window [installerWindow orderOut:self]; - + //make 1st array of .exe, .msi, and .bat files NSArray *files1 = self.runnableSubpathsInWrapperCDrive; - + //copy or move the folder to Program Files NSString *theFileNamePath = [[[panel URLs] objectAtIndex:0] path]; NSString *theFileName = [theFileNamePath substringFromIndex:[theFileNamePath rangeOfString:@"/" options:NSBackwardsSearch].location]; BOOL success; - if (removeOriginal) - { + if (removeOriginal) { success = [fm moveItemAtPath:theFileNamePath toPath:[NSString stringWithFormat:@"%@Program Files%@",self.cDrivePathForWrapper,theFileName]]; - } - else - { + } else { success = [fm copyItemAtPath:theFileNamePath toPath:[NSString stringWithFormat:@"%@Program Files%@",self.cDrivePathForWrapper,theFileName]]; } - - if (!success) - { + + if (!success) { [installerWindow makeKeyAndOrderFront:self]; [busyWindow orderOut:self]; return; } - + //make 2nd array of .exe, .msi, and .bat files NSArray *files2 = self.runnableSubpathsInWrapperCDrive; - + NSMutableArray *finalList = [[NSMutableArray alloc] init]; //fill new array of new .exe, .msi, and .bat files - for (NSString *item2 in files2) - { - if (![files1 containsObject:item2]) - { - if (![item2 hasPrefix:@"users/Wineskin"] && ![item2 hasPrefix:@"windows/Installer"] && ![item2 isEqualToString:@"nothing.exe"]) - { + for (NSString *item2 in files2) { + if (![files1 containsObject:item2]) { + if (![item2 hasPrefix:@"users/Wineskin"] && ![item2 hasPrefix:@"windows/Installer"] && ![item2 isEqualToString:@"nothing.exe"]) { [finalList addObject:[NSString stringWithFormat:@"\"C:/%@\"",item2]]; } } } - + //display warning if final array is 0 length and exit method - if (finalList.count == 0) - { - if (removeOriginal) - { + if (finalList.count == 0) { + if (removeOriginal) { [NSAlert showAlertOfType:NSAlertTypeWarning withMessage:@"No new executables found after moving the selected folder inside the wrapper!"]; - } - else - { + } else { [NSAlert showAlertOfType:NSAlertTypeWarning withMessage:@"No new executables found after copying the selected folder inside the wrapper!"]; } - - if (usingAdvancedWindow) - [advancedWindow makeKeyAndOrderFront:self]; - else - [window makeKeyAndOrderFront:self]; + + if (usingAdvancedWindow) { + [advancedWindow makeKeyAndOrderFront:self]; + } else { + [window makeKeyAndOrderFront:self]; [busyWindow orderOut:self]; + } return; } // populate choose exe list [exeChoicePopUp removeAllItems]; for (NSString *item in finalList) [exeChoicePopUp addItemWithTitle:item]; - + NSString* mainExeWindowsPath = [NSString stringWithFormat:@"C:%@",[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_RUN_PATH]]; NSString* mainExePath = [NSPathUtilities getMacPathForWindowsPath:mainExeWindowsPath ofWrapper:self.wrapperPath]; - - if ([fm fileExistsAtPath:mainExePath]) - { - if (usingAdvancedWindow) - [advancedWindow makeKeyAndOrderFront:self]; - else - [window makeKeyAndOrderFront:self]; - } - else - [chooseExeWindow makeKeyAndOrderFront:self]; + + if ([fm fileExistsAtPath:mainExePath]) { + if (usingAdvancedWindow) { + [advancedWindow makeKeyAndOrderFront:self]; + } else { + [window makeKeyAndOrderFront:self]; + } + } else { + [chooseExeWindow makeKeyAndOrderFront:self]; [busyWindow orderOut:self]; + } } + - (IBAction)installerCancelButtonPressed:(id)sender { - if (usingAdvancedWindow) - [advancedWindow makeKeyAndOrderFront:self]; - else - [window makeKeyAndOrderFront:self]; + if (usingAdvancedWindow) { + [advancedWindow makeKeyAndOrderFront:self]; + } else { + [window makeKeyAndOrderFront:self]; + } [installerWindow orderOut:self]; } + - (IBAction)chooseExeOKButtonPressed:(id)sender { //use standard entry from Config tab automatically. @@ -475,12 +485,14 @@ - (IBAction)chooseExeOKButtonPressed:(id)sender [windowsExeTextField setStringValue:[[exeChoicePopUp selectedItem] title]]; [self saveAllData]; //show main menu - if (usingAdvancedWindow) - [advancedWindow makeKeyAndOrderFront:self]; - else - [window makeKeyAndOrderFront:self]; + if (usingAdvancedWindow) { + [advancedWindow makeKeyAndOrderFront:self]; + } else { + [window makeKeyAndOrderFront:self]; + } [chooseExeWindow orderOut:self]; } + - (IBAction)advancedButtonPressed:(id)sender { [self loadAllData]; @@ -497,15 +509,14 @@ - (IBAction)testRunButtonPressed:(id)sender [self saveAllData]; [NSThread detachNewThreadSelector:@selector(runATestRun) toTarget:self withObject:nil]; } + - (void)runATestRun { - //TODO: disableButtons causes testrun to crash for some reason - //[self disableButtons]; + [self disableButtons]; [self systemCommand:[NSPathUtilities wineskinLauncherBinForPortAtPath:self.wrapperPath] withArgs:@[@"debug"]]; - //[self enableButtons]; - - if ([NSAlert showBooleanAlertOfType:NSAlertTypeSuccess withMessage:@"Do you wish to view the Test Run Log?" withDefault:YES]) - { + [self enableButtons]; + + if ([NSAlert showBooleanAlertOfType:NSAlertTypeSuccess withMessage:@"Do you wish to view the Test Run Log?" withDefault:YES]) { NSString* logsFolderPath = [NSString stringWithFormat:@"%@/Contents/SharedSupport/Logs",self.wrapperPath]; [self systemCommand:@"/usr/bin/open" withArgs:@[@"-a", @"Console",[NSString stringWithFormat:@"%@/LastRunWine.log",logsFolderPath]]]; } @@ -520,64 +531,47 @@ - (IBAction)commandLineWineTestButtonPressed:(id)sender - (void)runACommandLineTestRun { // Check for winetricks, if missing download - if (![fm fileExistsAtPath:[NSString stringWithFormat:@"%@/Contents/Resources/winetricks",[[NSBundle mainBundle] bundlePath]]]) - { + if (![fm fileExistsAtPath:[NSString stringWithFormat:@"%@/Contents/Resources/winetricks",[[NSBundle mainBundle] bundlePath]]]) { //Get the URL where winetricks is located NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://raw.githubusercontent.com/Gcenx/WineskinServer/master/WineskinWinetricks/Location.txt?%@",[[NSNumber numberWithLong:rand()] stringValue]]]; NSString *urlWhereWinetricksIs = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding timeoutInterval:5]; urlWhereWinetricksIs = [urlWhereWinetricksIs stringByReplacingOccurrencesOfString:@"\n" withString:@""]; //remove \n - + //Use downloader to download NSData *newVersion = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlWhereWinetricksIs] timeoutInterval:5]; //if new version looks messed up, prompt the download failed, and exit. - if (newVersion.length < 50) - { + if (newVersion.length < 50) { [NSAlert showAlertOfType:NSAlertTypeError withMessage:@"Connection to the website failed. The site is either down currently, or there is a problem with your internet connection."]; - + [winetricksWindow makeKeyAndOrderFront:self]; [busyWindow orderOut:self]; return; } - + NSString* winetricksFilePath = [NSString stringWithFormat:@"%@/Contents/Resources/winetricks",[[NSBundle mainBundle] bundlePath]]; [fm removeItemAtPath:winetricksFilePath]; [newVersion writeToFile:winetricksFilePath atomically:YES]; [self systemCommand:@"/bin/chmod" withArgs:[NSArray arrayWithObjects:@"777",winetricksFilePath,nil]]; } - + @autoreleasepool { - //NSBundle *bundle = [NSBundle mainBundle]; - - /* If no arguments have been passed, start a terminal */ - //NSString *start_bin_dir = [NSString stringWithFormat:@"%@/Contents/Resources", bundle.resourcePath]; - //NSString *wine_bin_dir = [NSString stringWithFormat:@"%@/SharedSupport/wine/bin", bundle.resourcePath]; - - - //NSString *theScript = [NSString stringWithFormat: - //@"tell application \"Terminal\" to do script \ - // \"setenv PATH \\\"%@:%@:$PATH\\\"; winehelp --clear\"", start_bin_dir, wine_bin_dir]; - //NSAppleScript *bringToFrontScript = [[NSAppleScript alloc] initWithSource:theScript]; - //[bringToFrontScript executeAndReturnError:nil]; - - system([[NSString stringWithFormat: @"export PATH=\"%@/bin:$PATH\";open -a Terminal.app \"%@/Contents/Resources/winehelp\"",self.wswineBundlePath,[[NSBundle mainBundle] bundlePath]] UTF8String]); + system([[NSString stringWithFormat: @"open -a Terminal.app \"%@/Contents/Resources/winehelp\"",[[NSBundle mainBundle] bundlePath]] UTF8String]); } } - (IBAction)killWineskinProcessesButtonPressed:(id)sender { //give warning message - if ([NSAlert showBooleanAlertOfType:NSAlertTypeWarning withMessage:[NSString stringWithFormat:@"This will kill all processes from this wrapper...\nAre you sure that you want to continue?"] withDefault:NO]) - { + if ([NSAlert showBooleanAlertOfType:NSAlertTypeWarning withMessage:[NSString stringWithFormat:@"This will kill all processes from this wrapper...\nAre you sure that you want to continue?"] withDefault:NO]) { //sends kill command to winesever, this then cause winesever to kill everything without causing registry corruption [self runWineskinLauncherWithDisabledButtonsWithFlag:@"WSS-wineserverkill"]; - + //kill WineskinLauncher NSMutableArray *pidsToKill = [[NSMutableArray alloc] init]; [pidsToKill addObjectsFromArray:[[self systemCommand:[NSString stringWithFormat:@"ps ax | grep \"%@\" | grep WineskinLauncher | awk \"{print \\$1}\"",self.wrapperPath]] componentsSeparatedByString:@"\n"]]; - - for (NSString *pid in pidsToKill) - { + + for (NSString *pid in pidsToKill) { [self systemCommand:[NSString stringWithFormat:@"kill -9 %@",pid]]; } } @@ -586,11 +580,9 @@ - (IBAction)killWineskinProcessesButtonPressed:(id)sender NSString *wrapperName = [[wrapperPath substringFromIndex:[wrapperPath rangeOfString:@"/" options:NSBackwardsSearch].location+1] stringByDeletingPathExtension]; NSString *results = [self systemCommand:[NSString stringWithFormat:@"launchctl list | grep \"%@\"",wrapperName]]; NSArray *resultArray = [results componentsSeparatedByString:@"\n"]; - for (NSString *result in resultArray) - { + for (NSString *result in resultArray) { NSRange theDash = [result rangeOfString:@"-"]; - if (theDash.location != NSNotFound) - { + if (theDash.location != NSNotFound) { // clear in front of - in case launchd has it as anonymous, then clear after first [ NSString *entryToRemove = [[result substringFromIndex:theDash.location+1] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; NSRange theBracket = [entryToRemove rangeOfString:@"["]; @@ -620,8 +612,8 @@ - (void)saveAllData icon:nil path:windowsExeTextField.stringValue atPort:portManager]; - - [portManager setPlistObject:customCommandsTextField.stringValue forKey:@"CLI Custom Commands"]; + + [portManager setPlistObject:customCommandsTextField.stringValue forKey:WINESKIN_WRAPPER_PLIST_KEY_UNIX_COMMANDS]; [portManager setPlistObject:wineDebugTextField.stringValue forKey:WINESKIN_WRAPPER_PLIST_KEY_WINEDEBUG]; [portManager synchronizePlist]; } @@ -629,76 +621,103 @@ - (void)saveAllData - (void)loadAllData { //get wrapper version and put on Advanced Page wrapperVersionText - [wrapperVersionText setStringValue:[NSString stringWithFormat:@"Wineskin %@",WINESKIN_VERSION]]; - + [wrapperVersionText setStringValue:[NSString stringWithFormat:@"%@",WINESKIN_VERSION]]; + //get current engine and put it on Advanced Page engineVersionText [engineVersionText setStringValue:[NSPortDataLoader engineOfPortAtPath:self.wrapperPath]]; - + //set info from Info.plist [windowsExeTextField setStringValue:[NSPortDataLoader pathForMainExeAtPort:self.wrapperPath]]; [versionTextField setStringValue:[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_VERSION]]; [menubarNameTextField setStringValue:[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_NAME]]; - - if ([[portManager plistObjectForKey:@"CLI Custom Commands"] length] > 0) - { - [customCommandsTextField setStringValue:[portManager plistObjectForKey:@"CLI Custom Commands"]]; + + if ([[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_UNIX_COMMANDS] length] > 0) { + [customCommandsTextField setStringValue:[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_UNIX_COMMANDS]]; } - + [wineDebugTextField setStringValue:[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_WINEDEBUG]]; NSArray *assArray = [[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_ASSOCIATIONS] componentsSeparatedByString:@" "]; [extPopUpButton removeAllItems]; - - for (NSString *item in assArray) - { + + for (NSString *item in assArray) { [extPopUpButton addItemWithTitle:item]; } - + + if (IS_SYSTEM_MAC_OS_SONOMA_OR_SUPERIOR && IsProcessTranslated) { + if ([fm fileExistsAtPath:[NSString stringWithFormat:@"%@/d3dmetal_force",self.wswineBundlePath]]) { + [gptkCheckBoxButton setEnabled:NO]; + [gptkCheckBoxButton setState:YES]; + [portManager setPlistObject:@([gptkCheckBoxButton state]) forKey:WINESKIN_WRAPPER_PLIST_KEY_D3DMETAL]; + [portManager setPlistObject:@([gptkCheckBoxButton state]) forKey:WINESKIN_WRAPPER_PLIST_KEY_D3DMETAL_FORCE]; + [portManager setPlistObject:@([gptkCheckBoxButton state]) forKey:WINESKIN_WRAPPER_PLIST_KEY_MOLTENVK_CX]; + } else { + [gptkCheckBoxButton setState:[[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_D3DMETAL] intValue]]; + } + } else { + [gptkCheckBoxButton setEnabled:NO]; + } + BOOL validExtension = ![[[extPopUpButton selectedItem] title] isEqualToString:@""]; [extMinusButton setEnabled:validExtension]; [extEditButton setEnabled:validExtension]; - + [mapUserFoldersCheckBoxButton setState:[[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_SYMLINK_USERS] intValue]]; [modifyMappingsButton setEnabled:[mapUserFoldersCheckBoxButton state]]; [enableWinetricksSilentButton setState:[[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_WINETRICKS_SILENT] intValue]]; [WinetricksNoLogsButton setState:[[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_WINETRICKS_NOLOGS] intValue]]; [geckoCheckBoxButton setState:[[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_DISABLE_GECKO] intValue]]; [monoCheckBoxButton setState:[[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_DISABLE_MONO] intValue]]; + [metalhudCheckBoxButton setState:[[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_METAL_HUD] intValue]]; + + if ([fm fileExistsAtPath:[NSString stringWithFormat:@"%@/d3dmetal_force",self.wswineBundlePath]]) { + [cxmoltenvkCheckBoxButton setEnabled:NO]; + [cxmoltenvkCheckBoxButton setState:NO]; + [fastmathCheckBoxButton setEnabled:NO]; + [fastmathCheckBoxButton setState:NO]; + } else { + [cxmoltenvkCheckBoxButton setState:[[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_MOLTENVK_CX] intValue]]; + if ([[self->portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_D3DMETAL] intValue] == 1) { + [cxmoltenvkCheckBoxButton setEnabled:NO]; + } else { + [cxmoltenvkCheckBoxButton setEnabled:YES]; + } + [fastmathCheckBoxButton setState:[[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_MOLTENVK_FASTMATH] intValue]]; + } + + [fntoggleCheckBoxButton setState:[[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_ENABLE_FNTOGGLE] intValue]]; - + [esyncCheckBoxButton setState:[[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_ESYNC] intValue]]; + [msyncCheckBoxButton setState:[[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_MSYNC] intValue]]; + // Option does not work above 10.8 so disable it - if (IS_SYSTEM_MAC_OS_10_9_OR_SUPERIOR) - { + if (IS_SYSTEM_MAC_OS_MAVERICKS_OR_SUPERIOR) { [disableCPUsCheckBoxButton setEnabled:NO]; - } - else - { + } else { [disableCPUsCheckBoxButton setState:[[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_SINGLE_CPU] intValue]]; } - + [alwaysMakeLogFilesCheckBoxButton setState:[[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_DEBUG_MODE] intValue]]; - [setMaxFilesCheckBoxButton setState:[[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_MAX_OF_10240_FILES] intValue]]; - + // change if better way to do this / state does not update if changed again via winetricks BOOL winedbg = [NSPortDataLoader winedbgIsDisabledAtPort:self.wrapperPath]; [winedbgDisabledButton setState:winedbg]; - + NSString* engineString = [NSPortDataLoader engineOfPortAtPath:self.wrapperPath]; NSWineskinEngine* engine = [NSWineskinEngine wineskinEngineWithString:engineString]; - + BOOL commandMode = [NSPortDataLoader CommandModeIsEnabledAtPort:self.wrapperPath withEngine:engine]; [commandCheckBoxButton setState:commandMode]; - [commandCheckBoxButton setEnabled:engine.isCompatibleWithCommandCtrl]; BOOL optionMode = [NSPortDataLoader OptionModeIsEnabledAtPort:self.wrapperPath withEngine:engine]; [optionCheckBoxButton setState:optionMode]; - [optionCheckBoxButton setEnabled:engine.isCompatibleWithOptionAlt]; - + [confirmQuitCheckBoxButton setState:[NSPortDataLoader isCloseNicelyEnabledAtPort:portManager]]; } + - (IBAction)windowsExeBrowseButtonPressed:(id)sender { NSString* cDrivePath = self.cDrivePathForWrapper; - + NSOpenPanel *panel = [NSOpenPanel openPanel]; [panel setWindowTitle:NSLocalizedString(@"Please choose the file that should run",nil)]; [panel setPrompt:NSLocalizedString(@"Choose",nil)]; @@ -709,17 +728,17 @@ - (IBAction)windowsExeBrowseButtonPressed:(id)sender [panel setTreatsFilePackagesAsDirectories:YES]; [panel setAllowedFileTypes:EXTENSIONS_COMPATIBLE_WITH_RUN_PATH]; [panel setInitialDirectory:cDrivePath]; - + //open browse window to get .exe choice - if ([panel runModal] == 0) - { + if ([panel runModal] == 0) { return; } - + NSString* selectedMainExe = [[[panel URLs] objectAtIndex:0] path]; NSString* windowsPath = [NSExeSelection selectAsMainExe:selectedMainExe forPort:self.wrapperPath]; [windowsExeTextField setStringValue:windowsPath]; } + - (IBAction)extPlusButtonPressed:(id)sender { [self saveAllData]; @@ -728,61 +747,61 @@ - (IBAction)extPlusButtonPressed:(id)sender [extAddEditWindow makeKeyAndOrderFront:self]; [advancedWindow orderOut:self]; } + - (IBAction)extMinusButtonPressed:(id)sender { - if ([NSAlert showBooleanAlertOfType:NSAlertTypeWarning withMessage:@"Are you sure that you want to remove that entry? This will remove the file association." withDefault:NO] == false) - { + if ([NSAlert showBooleanAlertOfType:NSAlertTypeWarning withMessage:@"Are you sure that you want to remove that entry? This will remove the file association." withDefault:NO] == false) { return; } - + NSString* extension = [[extPopUpButton selectedItem] title]; if (!extension) return; - + [self saveAllData]; [busyWindow makeKeyAndOrderFront:self]; [advancedWindow orderOut:self]; - + NSString* regSoftwareClassesExtension = [NSString stringWithFormat:@"[Software\\\\Classes\\\\.%@]",extension]; NSString* regSoftwareClassesExtensionShellOpenCommand = [NSString stringWithFormat:@"[Software\\\\Classes\\\\%@file\\\\shell\\\\open\\\\command]",extension]; - + [portManager deleteRegistry:regSoftwareClassesExtension fromRegistryFileNamed:SYSTEM_REG]; [portManager deleteRegistry:regSoftwareClassesExtensionShellOpenCommand fromRegistryFileNamed:SYSTEM_REG]; - - + //remove entry from Info.plist NSMutableArray *assArray = [[[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_ASSOCIATIONS] componentsSeparatedByString:@" "] mutableCopy]; [assArray removeObject:extension]; [portManager setPlistObject:[assArray componentsJoinedByString:@" "] forKey:WINESKIN_WRAPPER_PLIST_KEY_ASSOCIATIONS]; [portManager synchronizePlist]; - + [self loadAllData]; [advancedWindow makeKeyAndOrderFront:self]; [busyWindow orderOut:self]; } + - (IBAction)extEditButtonPressed:(id)sender { [self saveAllData]; - + // get selected extension NSString* extension = [[extPopUpButton selectedItem] title]; [extExtensionTextField setStringValue:extension]; - + NSString* regSoftwareClassesExtensionShellOpenCommand = [NSString stringWithFormat:@"[Software\\\\Classes\\\\%@file\\\\shell\\\\open\\\\command]",extension]; - + // read system.reg and find command line for that extension NSString* commandReg = [portManager getRegistryEntry:regSoftwareClassesExtensionShellOpenCommand fromRegistryFileNamed:SYSTEM_REG]; if (!commandReg) return; - + NSString* atValue = [NSPortManager getStringValueForKey:nil fromRegistryString:commandReg]; if (!atValue) return; - + [extCommandTextField setStringValue:atValue]; - - + [extAddEditWindow makeKeyAndOrderFront:self]; [advancedWindow orderOut:self]; } + - (IBAction)iconToUseBrowseButtonPressed:(id)sender { NSOpenPanel *panel = [[NSOpenPanel alloc] init]; @@ -794,24 +813,24 @@ - (IBAction)iconToUseBrowseButtonPressed:(id)sender [panel setExtensionHidden:NO]; [panel setTreatsFilePackagesAsDirectories:YES]; [panel setInitialDirectory:@"/"]; - - if ([panel runModal] == 0) - { + + if ([panel runModal] == 0) { return; } - + NSString* newIconPath = [[[panel URLs] objectAtIndex:0] path]; [iconImageView loadIconFromFile:newIconPath]; - + NSString* wrapperRealPath = self.wrapperPath; NSString* wrapperIconPath = [NSString stringWithFormat:@"%@/Contents/Resources/Wineskin.icns",wrapperRealPath]; NSString* wrapperTemporaryPath = [NSString stringWithFormat:@"%@WineskinTempRenamer",wrapperRealPath]; - + [[NSFileManager defaultManager] removeItemAtPath:wrapperIconPath]; [iconImageView.image saveAsIcnsAtPath:wrapperIconPath]; [[NSFileManager defaultManager] moveItemAtPath:wrapperRealPath toPath:wrapperTemporaryPath]; [[NSFileManager defaultManager] moveItemAtPath:wrapperTemporaryPath toPath:wrapperRealPath]; } + //************************************************************* //**************** Advanced Menu - Tools Tab ****************** //************************************************************* @@ -819,6 +838,7 @@ - (IBAction)winecfgButtonPressed:(id)sender { [NSThread detachNewThreadSelector:@selector(runWinecfg) toTarget:self withObject:nil]; } + - (void)runWineskinLauncherWithDisabledButtonsWithFlag:(NSString*)flag { @autoreleasepool @@ -828,34 +848,42 @@ - (void)runWineskinLauncherWithDisabledButtonsWithFlag:(NSString*)flag [self enableButtons]; // This doesn't work on Apple Silicon } } + - (void)runWinecfg { [self runWineskinLauncherWithDisabledButtonsWithFlag:@"WSS-winecfg"]; } + - (IBAction)uninstallerButtonPressed:(id)sender { [NSThread detachNewThreadSelector:@selector(runUninstaller) toTarget:self withObject:nil]; } + - (void)runUninstaller { [self runWineskinLauncherWithDisabledButtonsWithFlag:@"WSS-control"]; } + - (IBAction)regeditButtonPressed:(id)sender { [NSThread detachNewThreadSelector:@selector(runRegedit) toTarget:self withObject:nil]; } + - (void)runRegedit { [self runWineskinLauncherWithDisabledButtonsWithFlag:@"WSS-regedit"]; } + - (IBAction)taskmgrButtonPressed:(id)sender { [NSThread detachNewThreadSelector:@selector(runTaskmgr) toTarget:self withObject:nil]; } + - (void)runTaskmgr { [self runWineskinLauncherWithDisabledButtonsWithFlag:@"WSS-taskmgr"]; } + - (IBAction)rebuildWrapperButtonPressed:(id)sender { //issue warning @@ -893,6 +921,10 @@ - (IBAction)rebuildWrapperButtonPressed:(id)sender //TODO: Doesn't always work on Apple Silicon usleep(3000000); //Maybe a usleep before and after will help? //refresh + + // Workaround explorer.exe hang with CX24.x + system([[NSString stringWithFormat:@"/usr/bin/xattr -drs com.apple.quarantine \"%@/Contents/SharedSupport/wine\"",self.wrapperPath] UTF8String]); + [self systemCommand:[NSPathUtilities wineskinLauncherBinForPortAtPath:self.wrapperPath] withArgs:@[@"WSS-wineprefixcreate"]]; usleep(6000000); @@ -901,16 +933,16 @@ - (IBAction)rebuildWrapperButtonPressed:(id)sender [self loadAllData]; } } + - (IBAction)refreshWrapperButtonPressed:(id)sender { [busyWindow makeKeyAndOrderFront:self]; [advancedWindow orderOut:self]; - [self systemCommand:[NSPathUtilities wineskinLauncherBinForPortAtPath:self.wrapperPath] withArgs:@[@"WSS-wineprefixcreatenoregs"]]; - [advancedWindow makeKeyAndOrderFront:self]; [busyWindow orderOut:self]; } + //************************************************************* //*************** Advanced Menu - Options Tab ***************** //************************************************************* @@ -919,11 +951,6 @@ - (IBAction)alwaysMakeLogFilesCheckBoxButtonPressed:(id)sender [portManager setPlistObject:@([alwaysMakeLogFilesCheckBoxButton state]) forKey:WINESKIN_WRAPPER_PLIST_KEY_DEBUG_MODE]; [portManager synchronizePlist]; } -- (IBAction)setMaxFilesCheckBoxButtonPressed:(id)sender -{ - [portManager setPlistObject:@([setMaxFilesCheckBoxButton state]) forKey:WINESKIN_WRAPPER_PLIST_KEY_MAX_OF_10240_FILES]; - [portManager synchronizePlist]; -} - (IBAction)mapUserFoldersCheckBoxButtonPressed:(id)sender { BOOL symlinksInUserFolder = [mapUserFoldersCheckBoxButton state]; @@ -963,6 +990,42 @@ - (IBAction)optionCheckBoxButton:(id)sender NSString* engine = [NSPortDataLoader engineOfPortAtPath:self.wrapperPath]; [NSWineskinPortDataWriter saveOptionMode:[optionCheckBoxButton state] withEngine:engine atPort:portManager]; } +- (IBAction)esyncButtonPressed:(id)sender +{ + [portManager setPlistObject:@([esyncCheckBoxButton state]) forKey:WINESKIN_WRAPPER_PLIST_KEY_ESYNC]; + [portManager synchronizePlist]; +} +- (IBAction)msyncButtonPressed:(id)sender +{ + [portManager setPlistObject:@([msyncCheckBoxButton state]) forKey:WINESKIN_WRAPPER_PLIST_KEY_MSYNC]; + [portManager synchronizePlist]; +} + +//TODO: Add D3DMetal checkbox/toggle +//Need to refresh the wineprefix to install D3DMetal wine stubs +- (IBAction)d3dmetalButtonPressed:(id)sender +{ + [busyWindow makeKeyAndOrderFront:self]; + [advancedWindow orderOut:self]; + [portManager setPlistObject:@([gptkCheckBoxButton state]) forKey:WINESKIN_WRAPPER_PLIST_KEY_D3DMETAL]; + + //TODO: Set WINESKIN_WRAPPER_PLIST_KEY_D3DMETAL_FORCE if not already set + if ([[self->portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_D3DMETAL_FORCE] intValue] != 1) { + [portManager setPlistObject:@([gptkCheckBoxButton state]) forKey:WINESKIN_WRAPPER_PLIST_KEY_D3DMETAL_FORCE]; + } + + //TODO: Set WINESKIN_WRAPPER_PLIST_KEY_MOLTENVK_CX if not already set + if ([[self->portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_MOLTENVK_CX] intValue] != 1) { + [portManager setPlistObject:@([gptkCheckBoxButton state]) forKey:WINESKIN_WRAPPER_PLIST_KEY_MOLTENVK_CX]; + } + + [portManager synchronizePlist]; + [self systemCommand:[NSPathUtilities wineskinLauncherBinForPortAtPath:self.wrapperPath] withArgs:@[@"WSS-wineboot"]]; + [advancedWindow makeKeyAndOrderFront:self]; + [busyWindow orderOut:self]; + [self loadAllData]; +} + //**************************************************************** //**************** Advanced Menu - Advanced Tab ****************** //**************************************************************** @@ -971,52 +1034,56 @@ - (IBAction)WinetricksNoLogsButtonPressed:(id)sender [portManager setPlistObject:@([WinetricksNoLogsButton state]) forKey:WINESKIN_WRAPPER_PLIST_KEY_WINETRICKS_NOLOGS]; [portManager synchronizePlist]; } + - (IBAction)disableCPUsButtonPressed:(id)sender { [portManager setPlistObject:@([disableCPUsCheckBoxButton state]) forKey:WINESKIN_WRAPPER_PLIST_KEY_SINGLE_CPU]; [portManager synchronizePlist]; } + - (IBAction)winedbgDisabledButtonPressed:(id)sender { [NSWineskinPortDataWriter saveWinedbg:[winedbgDisabledButton state] atPort:portManager]; } + - (IBAction)geckoButtonPressed:(id)sender { [portManager setPlistObject:@([geckoCheckBoxButton state]) forKey:WINESKIN_WRAPPER_PLIST_KEY_DISABLE_GECKO]; [portManager synchronizePlist]; } - - (IBAction)monoButtonPressed:(id)sender { [portManager setPlistObject:@([monoCheckBoxButton state]) forKey:WINESKIN_WRAPPER_PLIST_KEY_DISABLE_MONO]; [portManager synchronizePlist]; } +- (IBAction)metalhudButtonPressed:(id)sender +{ + [portManager setPlistObject:@([metalhudCheckBoxButton state]) forKey:WINESKIN_WRAPPER_PLIST_KEY_METAL_HUD]; + [portManager synchronizePlist]; +} + +- (IBAction)fastmathButtonPressed:(id)sender +{ + [portManager setPlistObject:@([fastmathCheckBoxButton state]) forKey:WINESKIN_WRAPPER_PLIST_KEY_MOLTENVK_FASTMATH]; + [portManager synchronizePlist]; +} + +- (IBAction)cxmoltenvkButtonPressed:(id)sender +{ + [portManager setPlistObject:@([cxmoltenvkCheckBoxButton state]) forKey:WINESKIN_WRAPPER_PLIST_KEY_MOLTENVK_CX]; + [portManager synchronizePlist]; +} //************************************************************* //*********************** Winetricks ************************** //************************************************************* - (IBAction)winetricksButtonPressed:(id)sender { - NSString* engineString = [NSPortDataLoader engineOfPortAtPath:self.wrapperPath]; - NSWineskinEngine* engine = [NSWineskinEngine wineskinEngineWithString:engineString]; - - //TODO: Add engine check logic into - //Workaround winetricks disabling some verbs for CX21 - if (engine.isForceWinetricksNeeded) - { - [portManager setPlistObject:@TRUE forKey:WINESKIN_WRAPPER_PLIST_KEY_WINETRICKS_FORCE]; - [portManager synchronizePlist]; - } - else - { - [portManager setPlistObject:@FALSE forKey:WINESKIN_WRAPPER_PLIST_KEY_WINETRICKS_FORCE]; - [portManager synchronizePlist]; - } - [self winetricksRefreshButtonPressed:self]; } + - (IBAction)enableWinetricksSilentButtonPressed:(id)sender { [portManager setPlistObject:@([enableWinetricksSilentButton state]) forKey:WINESKIN_WRAPPER_PLIST_KEY_WINETRICKS_SILENT]; @@ -1026,17 +1093,18 @@ - (IBAction)enableWinetricksSilentButtonPressed:(id)sender //TODO: winetricks button now correctly goes back to the prior opened window - (IBAction)winetricksDoneButtonPressed:(id)sender { - if (usingAdvancedWindow) + if (usingAdvancedWindow) { [advancedWindow makeKeyAndOrderFront:self]; - else + } else { [window makeKeyAndOrderFront:self]; + } [winetricksWindow orderOut:self]; } + - (IBAction)winetricksRefreshButtonPressed:(id)sender { // Check for winetricks file, if missing download - if (![fm fileExistsAtPath:[NSString stringWithFormat:@"%@/Contents/Resources/winetricks",[[NSBundle mainBundle] bundlePath]]]) - { + if (![fm fileExistsAtPath:[NSString stringWithFormat:@"%@/Contents/Resources/winetricks",[[NSBundle mainBundle] bundlePath]]]) { [self winetricksUpdateButtonPressed:self]; } NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; @@ -1054,7 +1122,7 @@ - (IBAction)winetricksRefreshButtonPressed:(id)sender [winetricksShowDownloadedColumn setState:([defaults boolForKey:@"DownloadedColumnShown"] ? NSOnState : NSOffState)]; [winetricksShowInstalledColumn setState:([defaults boolForKey:@"InstalledColumnShown"] ? NSOnState : NSOffState)]; [winetricksOutlineView setOutlineTableColumn:winetricksTableColumnName]; - + [self setWinetricksBusy:YES]; // Run the possibly lenghty operation in a separate thread so that it won't beachball @@ -1068,79 +1136,74 @@ - (IBAction)winetricksRefreshButtonPressed:(id)sender [self setWinetricksBusy:NO]; [winetricksOutlineView reloadData]; } + - (IBAction)winetricksUpdateButtonPressed:(id)sender { //Get the URL where winetricks is located NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://raw.githubusercontent.com/Gcenx/WineskinServer/master/WineskinWinetricks/Location.txt?%@",[[NSNumber numberWithLong:rand()] stringValue]]]; NSString *urlWhereWinetricksIs = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding timeoutInterval:5]; - + urlWhereWinetricksIs = [urlWhereWinetricksIs stringByReplacingOccurrencesOfString:@"\n" withString:@""]; //remove \n - + // Only show Warning if winetricks is already installed - if ([fm fileExistsAtPath:[NSString stringWithFormat:@"%@/Contents/Resources/winetricks",[[NSBundle mainBundle] bundlePath]]]) - { + if ([fm fileExistsAtPath:[NSString stringWithFormat:@"%@/Contents/Resources/winetricks",[[NSBundle mainBundle] bundlePath]]]) { //confirm update - if ([NSAlert showBooleanAlertOfType:NSAlertTypeWarning withMessage:[NSString stringWithFormat:@"Are you sure you want to update to the latest version of Winetricks?\n\nThe latest version from...\n\t%@\nwill be downloaded and installed for this wrapper.",urlWhereWinetricksIs] withDefault:NO] == false) - { + if ([NSAlert showBooleanAlertOfType:NSAlertTypeWarning withMessage:[NSString stringWithFormat:@"Are you sure you want to update to the latest version of Winetricks?\n\nThe latest version from...\n\t%@\nwill be downloaded and installed for this wrapper.",urlWhereWinetricksIs] withDefault:NO] == false) { return; } } - + //show busy window [busyWindow makeKeyAndOrderFront:self]; //hide Winetricks window [winetricksWindow orderOut:self]; - + //Use downloader to download NSData *newVersion = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlWhereWinetricksIs] timeoutInterval:5]; //if new version looks messed up, prompt the download failed, and exit. - if (newVersion.length < 50) - { + if (newVersion.length < 50) { [NSAlert showAlertOfType:NSAlertTypeError withMessage:@"Connection to the website failed. The site is either down currently, or there is a problem with your internet connection."]; - + [winetricksWindow makeKeyAndOrderFront:self]; [busyWindow orderOut:self]; return; } - + NSString* winetricksFilePath = [NSString stringWithFormat:@"%@/Contents/Resources/winetricks",[[NSBundle mainBundle] bundlePath]]; [fm removeItemAtPath:winetricksFilePath]; [newVersion writeToFile:winetricksFilePath atomically:YES]; [self systemCommand:@"/bin/chmod" withArgs:[NSArray arrayWithObjects:@"777",winetricksFilePath,nil]]; - + //remove old list of packages and descriptions (it'll be rebuilt when refreshing the list) [fm removeItemAtPath:[NSString stringWithFormat:@"%@/Contents/Resources/winetricksHelpList.plist",[[NSBundle mainBundle] bundlePath]]]; //refresh window [self winetricksRefreshButtonPressed:self]; } + - (IBAction)winetricksRunButtonPressed:(id)sender { // Clean list from unselected entries - for (NSString *eachPackage in [[self winetricksSelectedList] allKeys]) - { + for (NSString *eachPackage in [[self winetricksSelectedList] allKeys]) { NSNumber* winetrickWasSelected = [[self winetricksSelectedList] objectForKey:eachPackage]; if (!winetrickWasSelected || ![winetrickWasSelected boolValue]) // Cleanup [[self winetricksSelectedList] removeObjectForKey:eachPackage]; } - + NSString* winetricks; - if ([winetricksCustomCheckbox state]) // Don't run if there are no selected packages to install - { + // Don't run if there are no selected packages to install + if ([winetricksCustomCheckbox state]) { winetricks = [[winetricksCustomLine stringValue] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; if (winetricks.length == 0) return; - } - else - { + } else { winetricks = [[[self winetricksSelectedList] allKeys] componentsJoinedByString:@" "]; if ([[self winetricksSelectedList] count] == 0) return; } - - if ([NSAlert showBooleanAlertOfType:NSAlertTypeSuccess withMessage:[NSString stringWithFormat:@"Do you wish to run the following command?\nwinetricks %@", winetricks] withDefault:YES] == false) - { + + if ([NSAlert showBooleanAlertOfType:NSAlertTypeSuccess withMessage:[NSString stringWithFormat:@"Do you wish to run the following command?\nwinetricks %@", winetricks] withDefault:YES] == false) { return; } - + winetricksDone = NO; winetricksCanceled = NO; [self setWinetricksBusy:YES]; @@ -1159,14 +1222,12 @@ - (IBAction)winetricksRunButtonPressed:(id)sender [shPIDs removeAllObjects]; //loop though a second list and matching pids several times to try and get all the correct "sh" processes. Sadly this may get stray other processes on the system if people are multitasking a lot... not sure how else to handle it. int i; - for (i=0;i<3;i++) - { + for (i=0;i<3;i++) { //get second list of running "sh" processes NSArray *secondPIDlist = [self makePIDArray:@"sh"]; //compare first and second list, and ones in second list are the Winetricks ones, if cancel button pressed these are the ones to kill BOOL match = YES; - for (NSString *secondPIDlistItem in secondPIDlist) - { + for (NSString *secondPIDlistItem in secondPIDlist) { match = NO; for (NSString *firstPIDlistItem in firstPIDlist) if ([secondPIDlistItem isEqualToString:firstPIDlistItem]) match = YES; @@ -1175,25 +1236,25 @@ - (IBAction)winetricksRunButtonPressed:(id)sender usleep(1000000); } } + - (IBAction)winetricksCancelButtonPressed:(id)sender { //confirm to kill with big warning window - if ([NSAlert showBooleanAlertOfType:NSAlertTypeWarning withMessage:@"Are you sure you want to cancel Winetricks?\n\nThis will kill the running Winetricks process, but has a chance to accidently leave \"sh\" processes running until you manually end them or reboot\n\nIt could also mess up the wrapper where you may need to do a full rebuild to get it working right again (this will not usually be a problem)." withDefault:NO] == false) - { + if ([NSAlert showBooleanAlertOfType:NSAlertTypeWarning withMessage:@"Are you sure you want to cancel Winetricks?\n\nThis will kill the running Winetricks process, but has a chance to accidently leave \"sh\" processes running until you manually end them or reboot\n\nIt could also mess up the wrapper where you may need to do a full rebuild to get it working right again (this will not usually be a problem)." withDefault:NO] == false) { return; } - + [winetricksCancelButton setHidden:YES]; [winetricksCancelButton setEnabled:NO]; - + //kill shPIDs winetricksCanceled = YES; char *tmp; - for (NSString *item in shPIDs) - { + for (NSString *item in shPIDs) { kill((pid_t)(strtoimax([item UTF8String], &tmp, 10)), 9); } } + - (IBAction)winetricksSelectAllButtonPressed:(id)sender { for (NSDictionary *eachCategoryList in [[self winetricksFilteredList] allValues]) @@ -1201,18 +1262,19 @@ - (IBAction)winetricksSelectAllButtonPressed:(id)sender [[self winetricksSelectedList] setValue:[NSNumber numberWithBool:YES] forKey:eachPackage]; [winetricksOutlineView setNeedsDisplay]; } + - (IBAction)winetricksSelectNoneButtonPressed:(id)sender { [[self winetricksSelectedList] removeAllObjects]; [winetricksOutlineView setNeedsDisplay]; } + - (IBAction)winetricksSearchFilter:(id)sender { NSString *searchString = [[sender stringValue] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; - if ([searchString length] == 0) - [self setWinetricksFilteredList:[self winetricksList]]; - else - { + if ([searchString length] == 0) { + [self setWinetricksFilteredList:[self winetricksList]]; + } else { NSMutableDictionary *list = [[NSMutableDictionary alloc] init]; for (NSString *eachCategory in [self winetricksList]) { @@ -1234,80 +1296,69 @@ - (IBAction)winetricksSearchFilter:(id)sender } [winetricksOutlineView reloadData]; } + - (IBAction)winetricksCustomCommandToggled:(id)sender { BOOL useCustomLine = [sender state]; BOOL hideCustomLine = !useCustomLine; - + [enableWinetricksSilentButton setHidden:useCustomLine]; [winetricksCustomLine setEnabled:useCustomLine]; [winetricksCustomLine setHidden:hideCustomLine]; [winetricksCustomLineLabel setHidden:hideCustomLine]; [winetricksOutlineView setEnabled:hideCustomLine]; [winetricksSearchField setEnabled:hideCustomLine]; - - if (useCustomLine) - { + + if (useCustomLine) { [winetricksCustomLine becomeFirstResponder]; - } - else - { + } else { [winetricksRunButton becomeFirstResponder]; } } + - (IBAction)winetricksToggleColumn:(id)sender { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; BOOL newState = !([sender state] == NSOnState); - if (sender == winetricksShowInstalledColumn) - { + if (sender == winetricksShowInstalledColumn) { [sender setState:(newState ? NSOnState : NSOffState)]; [defaults setBool:newState forKey:@"InstalledColumnShown"]; - } - else if (sender == winetricksShowDownloadedColumn) - { + } else if (sender == winetricksShowDownloadedColumn) { [sender setState:(newState ? NSOnState : NSOffState)]; [defaults setBool:newState forKey:@"DownloadedColumnShown"]; } [defaults synchronize]; [self winetricksRefreshButtonPressed:self]; } + - (void)winetricksLoadPackageLists { @autoreleasepool { NSDictionary *list = nil; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - + // List of all winetricks list = [NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"%@/Contents/Resources/winetricksHelpList.plist",[[NSBundle mainBundle] bundlePath]]]; BOOL needsListRebuild = NO; - if (list == nil) - { + if (list == nil) { // This only happens in case of a winetricks update needsListRebuild = YES; - } - else - { - for (NSString *eachCategory in [list allKeys]) - { - if ([list valueForKey:eachCategory] == nil || ![[list valueForKey:eachCategory] isKindOfClass:[NSDictionary class]]) - { + } else { + for (NSString *eachCategory in [list allKeys]) { + if ([list valueForKey:eachCategory] == nil || ![[list valueForKey:eachCategory] isKindOfClass:[NSDictionary class]]) { needsListRebuild = YES; break; } NSDictionary *thisCategory = list[eachCategory]; - for (NSString *eachPackage in [thisCategory allKeys]) - { - if ([thisCategory valueForKey:eachPackage] == nil || ![[thisCategory valueForKey:eachPackage] isKindOfClass:[NSDictionary class]]) - { + for (NSString *eachPackage in [thisCategory allKeys]) { + if ([thisCategory valueForKey:eachPackage] == nil || ![[thisCategory valueForKey:eachPackage] isKindOfClass:[NSDictionary class]]) { needsListRebuild = YES; break; } NSDictionary *thisPackage = [thisCategory valueForKey:eachPackage]; if (!thisPackage[WINETRICK_NAME] || ![thisPackage[WINETRICK_NAME] isKindOfClass:[NSString class]] || - !thisPackage[WINETRICK_DESCRIPTION] || ![thisPackage[WINETRICK_DESCRIPTION] isKindOfClass:[NSString class]]) - { + !thisPackage[WINETRICK_DESCRIPTION] || ![thisPackage[WINETRICK_DESCRIPTION] isKindOfClass:[NSString class]]) { needsListRebuild = YES; break; } @@ -1320,28 +1371,22 @@ - (void)winetricksLoadPackageLists NSMutableArray *linesToCheck = [[NSMutableArray alloc] init]; NSArray *winetricksCategories; int i; - for (i=0; i < [winetricksFile count]; ++i) - { + for (i=0; i < [winetricksFile count]; ++i) { NSMutableString *fixedLine = [[NSMutableString alloc] init]; [fixedLine setString:[[winetricksFile objectAtIndex:i] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]]; - if ([fixedLine hasPrefix:@"WINETRICKS_CATEGORIES="]) - { + if ([fixedLine hasPrefix:@"WINETRICKS_CATEGORIES="]) { [fixedLine replaceOccurrencesOfString:@"WINETRICKS_CATEGORIES=" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [fixedLine length])]; [fixedLine replaceOccurrencesOfString:@"\"" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [fixedLine length])]; winetricksCategories = [fixedLine componentsSeparatedByString:@" "]; - } - else if ([fixedLine hasPrefix:@"w_metadata"]) - { + } else if ([fixedLine hasPrefix:@"w_metadata"]) { [fixedLine replaceOccurrencesOfString:@"\\" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [fixedLine length])]; [fixedLine replaceOccurrencesOfString:@"w_metadata" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [fixedLine length])]; [fixedLine appendString:@" "]; NSMutableString *descriptionLine = [[NSMutableString alloc] initWithString:@"No Description Found"]; //check next few lines for title int counter = 1; - for (counter = 1; counter < 10; ++counter) - { - if ([[winetricksFile objectAtIndex:i+counter] rangeOfString:@"title="].location != NSNotFound) - { + for (counter = 1; counter < 10; ++counter){ + if ([[winetricksFile objectAtIndex:i+counter] rangeOfString:@"title="].location != NSNotFound) { //this is the title! [descriptionLine setString:[winetricksFile objectAtIndex:i+counter]]; break; @@ -1355,23 +1400,18 @@ - (void)winetricksLoadPackageLists } } list = [[NSMutableDictionary alloc] init]; - for (NSString *category in winetricksCategories) - { + for (NSString *category in winetricksCategories) { NSMutableArray *winetricksTempList = [[NSMutableArray alloc] init]; - for (NSString *line in linesToCheck) - { + for (NSString *line in linesToCheck) { NSMutableString *fixedLine = [[NSMutableString alloc] init]; [fixedLine setString:line]; //fix multiple space issue - while ([fixedLine rangeOfString:@" "].location != NSNotFound) - { + while ([fixedLine rangeOfString:@" "].location != NSNotFound) { [fixedLine replaceOccurrencesOfString:@" " withString:@" " options:NSCaseInsensitiveSearch range:NSMakeRange(0, [fixedLine length])]; } NSArray *splitLine = [fixedLine componentsSeparatedByString:@" "]; - if ([[splitLine objectAtIndex:1] isEqualToString:category]) - { + if ([[splitLine objectAtIndex:1] isEqualToString:category]) { //[fixedLine replaceOccurrencesOfString:category withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [fixedLine length])]; - while ([fixedLine rangeOfString:@" "].location != NSNotFound) - { + while ([fixedLine rangeOfString:@" "].location != NSNotFound) { [fixedLine replaceOccurrencesOfString:@" " withString:@" " options:NSCaseInsensitiveSearch range:NSMakeRange(0, [fixedLine length])]; } [winetricksTempList addObject:[fixedLine stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]]; @@ -1379,8 +1419,7 @@ - (void)winetricksLoadPackageLists } [winetricksTempList sortUsingSelector:(@selector(caseInsensitiveCompare:))]; NSMutableDictionary *winetricksThisCategoryList = [[NSMutableDictionary alloc] init]; - for (NSString *eachPackage in winetricksTempList) - { + for (NSString *eachPackage in winetricksTempList) { NSRange position = [eachPackage rangeOfString:@" "]; if (position.location == NSNotFound) continue;// Skip invalid entries NSString *packageName = [eachPackage substringToIndex:position.location]; @@ -1397,49 +1436,40 @@ - (void)winetricksLoadPackageLists } [list writeToFile:[NSString stringWithFormat:@"%@/Contents/Resources/winetricksHelpList.plist",[[NSBundle mainBundle] bundlePath]] atomically:YES]; } - + //Fix the permissions just to be safe here NSString* winetricksHelpList = [NSString stringWithFormat:@"%@/Contents/Resources/winetricksHelpList.plist",[[NSBundle mainBundle] bundlePath]]; [self systemCommand:@"/bin/chmod" withArgs:[NSArray arrayWithObjects:@"777",winetricksHelpList,nil]]; - + [self setWinetricksList:list]; [self setWinetricksFilteredList:list]; - - if ([defaults boolForKey:@"InstalledColumnShown"]) - { + + if ([defaults boolForKey:@"InstalledColumnShown"]) { // List of installed winetricks list = [NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"%@/Contents/Resources/winetricksInstalled.plist",[[NSBundle mainBundle] bundlePath]]]; - if (!list[WINETRICK_INSTALLED] || ![list[WINETRICK_INSTALLED] isKindOfClass:[NSArray class]]) - { + if (!list[WINETRICK_INSTALLED] || ![list[WINETRICK_INSTALLED] isKindOfClass:[NSArray class]]) { // Invalid or missing list. Rebuild it (it only happens on a newly created wrapper or after a wrapper rebuild [self systemCommand:[NSPathUtilities wineskinLauncherBinForPortAtPath:self.wrapperPath] withArgs:[NSArray arrayWithObjects:@"WSS-winetricks", @"list-installed", nil]]; - + //TODO: Handle generating winetricksInstalled.plist better - if ([fm fileExistsAtPath:[NSString stringWithFormat:@"%@/Contents/SharedSupport/prefix/winetricks.log", self.wrapperPath]]) - { + if ([fm fileExistsAtPath:[NSString stringWithFormat:@"%@/Contents/SharedSupport/prefix/winetricks.log", self.wrapperPath]]) { NSArray *tempList = [[[NSString stringWithContentsOfFile:[NSString stringWithFormat:@"%@/Contents/SharedSupport/prefix/winetricks.log", self.wrapperPath] encoding:NSUTF8StringEncoding] componentsSeparatedByString:@"\n"] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; list = @{WINETRICK_INSTALLED: tempList}; [list writeToFile:[NSString stringWithFormat:@"%@/Contents/Resources/winetricksInstalled.plist",[[NSBundle mainBundle] bundlePath]] atomically:YES]; - } - else - { + } else { NSArray *tempList = [[[NSString stringWithContentsOfFile:[NSString stringWithFormat:@"%@/Contents/SharedSupport/Logs/WinetricksTemp.log", self.wrapperPath] encoding:NSUTF8StringEncoding] componentsSeparatedByString:@"\n"] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; list = @{WINETRICK_INSTALLED: tempList}; [list writeToFile:[NSString stringWithFormat:@"%@/Contents/Resources/winetricksInstalled.plist",[[NSBundle mainBundle] bundlePath]] atomically:YES]; } } [self setWinetricksInstalledList:list[WINETRICK_INSTALLED]]; - } - else - { + } else { [self setWinetricksInstalledList:[NSArray array]]; } - if ([defaults boolForKey:@"DownloadedColumnShown"]) - { + if ([defaults boolForKey:@"DownloadedColumnShown"]) { // List of downloaded winetricks list = [NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"%@/winetricks/winetricksCached.plist", [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0]]]; - if (!list[WINETRICK_CACHED] || ![list[WINETRICK_CACHED] isKindOfClass:[NSArray class]]) - { + if (!list[WINETRICK_CACHED] || ![list[WINETRICK_CACHED] isKindOfClass:[NSArray class]]) { // Invalid or missing list. Rebuild it (it only happens when the user first runs wineetricks on their system (from any wrapper) or after wiping ~/Caches/winetricks [self systemCommand:[NSPathUtilities wineskinLauncherBinForPortAtPath:self.wrapperPath] withArgs:[NSArray arrayWithObjects:@"WSS-winetricks",@"list-cached",nil]]; NSArray *tempList = [[[NSString stringWithContentsOfFile:[NSString stringWithFormat:@"%@/Contents/SharedSupport/Logs/WinetricksTemp.log", self.wrapperPath] encoding:NSUTF8StringEncoding] componentsSeparatedByString:@"\n"] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; @@ -1447,19 +1477,18 @@ - (void)winetricksLoadPackageLists [list writeToFile:[NSString stringWithFormat:@"%@/winetricks/winetricksCached.plist", [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0]] atomically:YES]; } [self setWinetricksCachedList:list[WINETRICK_CACHED]]; - } - else - { + } else { [self setWinetricksCachedList:[NSArray array]]; } } } + //TODO: This does correctly lock on Apple Silicon - (void)setWinetricksBusy:(BOOL)isBusy; { // disable X button disableXButton = isBusy; - + // disable all buttons on Winetricks window [winetricksRunButton setEnabled:!isBusy]; [winetricksUpdateButton setEnabled:!isBusy]; @@ -1469,58 +1498,57 @@ - (void)setWinetricksBusy:(BOOL)isBusy; [enableWinetricksSilentButton setEnabled:!isBusy]; [winetricksCustomCheckbox setEnabled:!isBusy]; [winetricksActionPopup setEnabled:!isBusy]; - + //enable cancel button [winetricksCancelButton setHidden:!isBusy]; [winetricksCancelButton setEnabled:isBusy]; - - if (isBusy) - { + + if (isBusy) { //TODO: winetricksWaitWheel might cause crashing? [winetricksWaitWheel startAnimation:self]; [winetricksOutlineView setEnabled:NO]; [winetricksCustomLine setEnabled:NO]; - } - else - { + } else { [winetricksWaitWheel stopAnimation:self]; - + // Set the correct state for elements that depend on the Custom checkbox [self winetricksCustomCommandToggled:winetricksCustomCheckbox]; } } + - (void)runWinetrick { @autoreleasepool { NSString* wineskinLauncherPath = [NSPathUtilities wineskinLauncherBinForPortAtPath:self.wrapperPath]; - + winetricksDone = NO; // loop while winetricksDone is NO NSMutableArray* winetricksArgs = [@[@"WSS-winetricks"] mutableCopy]; - if ([winetricksCustomCheckbox state]) - { + if ([winetricksCustomCheckbox state]) { NSCharacterSet* separators = [NSCharacterSet whitespaceAndNewlineCharacterSet]; NSArray* winetricksCommands = [[winetricksCustomLine stringValue] componentsSeparatedByCharactersInSet:separators]; [winetricksArgs addObjectsFromArray:winetricksCommands]; [winetricksArgs removeObject:@""]; - } - else - { + } else { [winetricksArgs addObjectsFromArray:[[self winetricksSelectedList] allKeys]]; } [self systemCommand:wineskinLauncherPath withArgs:winetricksArgs]; winetricksDone = YES; - + // Remove installed and cached packages lists since they need to be rebuilt [fm removeItemAtPath:[NSString stringWithFormat:@"%@/Contents/Resources/winetricksInstalled.plist",[[NSBundle mainBundle] bundlePath]]]; [fm removeItemAtPath:[NSString stringWithFormat:@"%@/winetricks/winetricksCached.plist", [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0]]]; usleep(500000); // Wait just a little, to make sure logs aren't overwritten before updateWinetrickOutput is done - [self winetricksRefreshButtonPressed:self]; - [self winetricksSelectNoneButtonPressed:self]; + + [NSThread dispatchBlockInMainQueue:^{ + [self winetricksRefreshButtonPressed:self]; + [self winetricksSelectNoneButtonPressed:self]; + }]; return; } } + - (void)doTheDangUpdate { @autoreleasepool @@ -1535,19 +1563,20 @@ - (void)doTheDangUpdate [winetricksOutputText setEditable:NO]; } } + - (void)winetricksWriteFinished { @autoreleasepool { [winetricksOutputText setEditable:YES]; - if (winetricksCanceled) - { + if (winetricksCanceled) { [winetricksOutputText insertText:@"\n\n Winetricks CANCELED!!\nIt is possible that there are now problems with the wrapper, or other shell processes may have accidently been affected as well. Usually its best to not cancel Winetricks, but in many cases it will not hurt. You may need to refresh the wrapper, or in bad cases do a rebuild.\n\n"]; } [winetricksOutputText insertText:@"\n\n Winetricks Commands Finished!!\n\n"]; [winetricksOutputText setEditable:NO]; } } + - (void)updateWinetrickOutput { @autoreleasepool @@ -1565,6 +1594,7 @@ - (void)updateWinetrickOutput [self setWinetricksBusy:NO]; } } + - (NSArray *)makePIDArray:(NSString *)processToLookFor { NSString *resultString = [NSString stringWithFormat:@"00000\n%@",[self systemCommandWithOutputReturned:[NSString stringWithFormat:@"ps axc|awk \"{if (\\$5==\\\"%@\\\") print \\$1}\"",processToLookFor]]]; @@ -1580,6 +1610,7 @@ - (IBAction)createCustomExeLauncherButtonPressed:(id)sender [cEXEWindow makeKeyAndOrderFront:self]; [advancedWindow orderOut:self]; } + - (IBAction)cEXESaveButtonPressed:(id)sender { //make sure name and exe fields are not blank @@ -1587,66 +1618,60 @@ - (IBAction)cEXESaveButtonPressed:(id)sender NSString* filename = cEXENameToUseTextField.stringValue; filename = [filename stringByReplacingOccurrencesOfString:@"&" withString:@"and"]; filename = [filename stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"!#$%%^*()+=|\\?<>;:@"]]; - - if (filename.length == 0) - { - if (cEXENameToUseTextField.stringValue.length > 0) - { + + if (filename.length == 0) { + if (cEXENameToUseTextField.stringValue.length > 0) { [NSAlert showAlertOfType:NSAlertTypeError withMessage:@"Your name contains only invalid characters!"]; - } - else - { + } else { [NSAlert showAlertOfType:NSAlertTypeError withMessage:@"You must type in a name to use!"]; } - return; } - + [cEXENameToUseTextField setStringValue:filename]; - - - if ([[cEXEWindowsExeTextField stringValue] isEqualToString:@""]) - { + + if ([[cEXEWindowsExeTextField stringValue] isEqualToString:@""]) { [NSAlert showAlertOfType:NSAlertTypeError withMessage:@"You must choose an executable to run!"]; return; } - + //make sure file doesn't exist, if it does, error and return - if ([fm fileExistsAtPath:[NSString stringWithFormat:@"%@/%@.app",self.wrapperPath,[cEXENameToUseTextField stringValue]]]) - { + if ([fm fileExistsAtPath:[NSString stringWithFormat:@"%@/%@.app",self.wrapperPath,[cEXENameToUseTextField stringValue]]]) { [NSAlert showAlertOfType:NSAlertTypeError withMessage:@"That name is already in use, please choose a different name."]; - return; - } - + return; + } + //show busy window [busyWindow makeKeyAndOrderFront:self]; //hide cEXE window [cEXEWindow orderOut:self]; - + NSString* customExeName = cEXENameToUseTextField.stringValue; [NSWineskinPortDataWriter addCustomExeWithName:customExeName version:@"1.0" icon:cEXEIconImageView.image path:cEXEWindowsExeTextField.stringValue atPortAtPath:self.wrapperPath]; - + NSString* customExePath = [NSString stringWithFormat:@"%@/%@.app",self.wrapperPath,customExeName]; NSPortManager* customExePortManager = [NSPortManager managerWithCustomExePath:customExePath]; [customExePortManager synchronizePlist]; - + //give done message [NSAlert showAlertOfType:NSAlertTypeSuccess withMessage:@"The Custom Exe Launcher has been made and can be found just inside the wrapper along with Wineskin.app.\n\nIf you want to be able to access it from outside of the app, just make and use an alias to it."]; - + //show advanced window [advancedWindow makeKeyAndOrderFront:self]; //hide busy window [busyWindow orderOut:self]; } + - (IBAction)cEXECancelButtonPressed:(id)sender { [advancedWindow makeKeyAndOrderFront:self]; [cEXEWindow orderOut:self]; } + - (IBAction)cEXEBrowseButtonPressed:(id)sender { //NSOpenPanel *panel = [NSOpenPanel openPanel]; @@ -1660,17 +1685,17 @@ - (IBAction)cEXEBrowseButtonPressed:(id)sender [panel setTreatsFilePackagesAsDirectories:YES]; [panel setAllowedFileTypes:EXTENSIONS_COMPATIBLE_WITH_WINESKIN_WRAPPER]; [panel setInitialDirectory:self.cDrivePathForWrapper]; - + //open browse window to get .exe choice - if ([panel runModal] == 0) - { + if ([panel runModal] == 0) { return; } - + NSString* selectedMainExe = [[[panel URLs] objectAtIndex:0] path]; NSString* windowsPath = [NSExeSelection selectAsMainExe:selectedMainExe forPort:self.wrapperPath]; [cEXEWindowsExeTextField setStringValue:windowsPath]; } + - (IBAction)cEXEIconBrowseButtonPressed:(id)sender { //NSOpenPanel *panel = [NSOpenPanel openPanel]; @@ -1683,25 +1708,27 @@ - (IBAction)cEXEIconBrowseButtonPressed:(id)sender [panel setExtensionHidden:NO]; [panel setTreatsFilePackagesAsDirectories:YES]; [panel setInitialDirectory:@"/"]; - - if ([panel runModal] == 0) - { + + if ([panel runModal] == 0) { return; } - + NSString* newIconPath = [[[panel URLs] objectAtIndex:0] path]; [cEXEIconImageView loadIconFromFile:newIconPath]; } + - (IBAction)cEXEAutomaticButtonPressed:(id)sender { [cEXEColorDepth setEnabled:NO]; [cEXESwitchPause setEnabled:NO]; } + - (IBAction)cEXEOverrideButtonPressed:(id)sender { [cEXEColorDepth setEnabled:YES]; [cEXESwitchPause setEnabled:YES]; } + - (IBAction)changeEngineUsedButtonPressed:(id)sender { //set the list of engines @@ -1711,6 +1738,7 @@ - (IBAction)changeEngineUsedButtonPressed:(id)sender //order out advanced window [advancedWindow orderOut:self]; } + - (void)setEngineList:(NSString *)theFilter { //get installed engines @@ -1718,48 +1746,47 @@ - (void)setEngineList:(NSString *)theFilter [installedEnginesList replaceObjectsWithVariation:^NSString* _Nullable(NSWineskinEngine* _Nonnull object, NSUInteger index) { return object.engineName; }]; - + //update engine list in change engine window [changeEngineWindowPopUpButton removeAllItems]; [changeEngineWindowPopUpButton addItemsWithTitles:installedEnginesList]; - + //disable/enable OK button depending if any engines in the list [engineWindowOkButton setEnabled:installedEnginesList.count > 0]; - + //** Show current installed engine version // read in current engine name from first line of version file in wswine.bundle NSString* versionFilePath = [NSString stringWithFormat:@"%@/version",self.wswineBundlePath]; - if ([fm fileExistsAtPath:versionFilePath]) - { + if ([fm fileExistsAtPath:versionFilePath]) { NSString *currentEngineVersion = [NSString stringWithContentsOfFile:versionFilePath encoding:NSUTF8StringEncoding]; - + //change currentVersionTextField to engine name [currentVersionTextField setStringValue:[currentEngineVersion getFragmentAfter:nil andBefore:@"\n"]]; } } + - (IBAction)changeEngineUsedOkButtonPressed:(id)sender { //make sure 7za exists,if not prompt error and exit... - if (!([fm fileExistsAtPath:BINARY_7ZA])) - { + if (!([fm fileExistsAtPath:BINARY_7ZA])) { [NSAlert showAlertOfType:NSAlertTypeError withMessage:@"Cannot continue... files missing. Please try reinstalling an engine manually, or running Wineskin Winery. Either should attempt to fix the problem."]; - + //order in advanced window [advancedWindow makeKeyAndOrderFront:self]; //order out change engine window [changeEngineWindow orderOut:self]; return; } - + //show busy window [busyWindow makeKeyAndOrderFront:self]; //hide change engine window [changeEngineWindow orderOut:self]; - + //uncompress engine NSString* newEngineName = [[changeEngineWindowPopUpButton selectedItem] title]; NSString* wswineBundlePath = self.wswineBundlePath; - + system([[NSString stringWithFormat:@"\"%@\" x \"%@/%@.tar.7z\" \"-o/%@\"", BINARY_7ZA,WINESKIN_LIBRARY_ENGINES_FOLDER,newEngineName,WINESKIN_LIBRARY_ENGINES_FOLDER] UTF8String]); system([[NSString stringWithFormat:@"/usr/bin/tar -C \"%@\" -xf \"%@/%@.tar\"",WINESKIN_LIBRARY_ENGINES_FOLDER,WINESKIN_LIBRARY_ENGINES_FOLDER,newEngineName] UTF8String]); //remove tar @@ -1770,16 +1797,20 @@ - (IBAction)changeEngineUsedOkButtonPressed:(id)sender [fm moveItemAtPath:[NSString stringWithFormat:@"%@/wswine.bundle",WINESKIN_LIBRARY_ENGINES_FOLDER] toPath:wswineBundlePath]; [self systemCommand:@"/bin/chmod" withArgs:@[@"777",wswineBundlePath]]; [self installEngine]; - + + // Workaround explorer.exe hang with CX24.x + system([[NSString stringWithFormat:@"/usr/bin/xattr -drs com.apple.quarantine \"%@\"",wswineBundlePath] UTF8String]); + //refresh wrapper [self systemCommand:[NSPathUtilities wineskinLauncherBinForPortAtPath:self.wrapperPath] withArgs:@[@"WSS-wineboot"]]; [self loadAllData]; - + //order in advanced window [advancedWindow makeKeyAndOrderFront:self]; //hide busy window [busyWindow orderOut:self]; } + - (IBAction)changeEngineUsedCancelButtonPressed:(id)sender { //order in advanced window @@ -1787,10 +1818,12 @@ - (IBAction)changeEngineUsedCancelButtonPressed:(id)sender //order out change engine window [changeEngineWindow orderOut:self]; } + - (IBAction)changeEngineSearchFilter:(id)sender { [self setEngineList:[[sender stringValue] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]]; } + -(void)replaceFile:(NSString*)filePath withVersionFromMasterWrapper:(NSString*)masterWrapperName { NSString* copyFrom = [NSString stringWithFormat:@"%@/%@%@",WINESKIN_LIBRARY_WRAPPER_FOLDER,masterWrapperName,filePath]; @@ -1798,46 +1831,43 @@ -(void)replaceFile:(NSString*)filePath withVersionFromMasterWrapper:(NSString*)m if ([fm fileExistsAtPath:copyTo]) [fm removeItemAtPath:copyTo]; [fm copyItemAtPath:copyFrom toPath:copyTo]; } + - (IBAction)updateWrapperButtonPressed:(id)sender { //get current version from Info.plist, change spaces to - to it matches master wrapper naming NSString *currentWrapperVersion = [portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_WINESKIN_VERSION]; currentWrapperVersion = [currentWrapperVersion stringByReplacingOccurrencesOfString:@" " withString:@"-"]; currentWrapperVersion = [NSString stringWithFormat:@"%@.app",currentWrapperVersion]; - + //get new master wrapper name NSArray *files = [fm contentsOfDirectoryAtPath:WINESKIN_LIBRARY_WRAPPER_FOLDER]; - - if (files.count != 1) - { + + if (files.count != 1) { [NSAlert showAlertOfType:NSAlertTypeError withMessage:@"There is an error with the installation of your Master Wrapper. Please update your Wrapper in Wineskin Winery (a manual install of a wrapper for Wineskin Winery will work too)."]; return; } - + //if master wrapper and current wrapper have same versions, prompt its already updated and return NSString *masterWrapperName = [files firstObject]; - if ([currentWrapperVersion isEqualToString:masterWrapperName]) - { - if ([NSAlert showBooleanAlertOfType:NSAlertTypeWarning withMessage:@"Your wrapper version matches the master wrapper version... no update needed. Do you want to force an update?" withDefault:NO] == false) - { + if ([currentWrapperVersion isEqualToString:masterWrapperName]) { + if ([NSAlert showBooleanAlertOfType:NSAlertTypeWarning withMessage:@"Your wrapper version matches the master wrapper version... no update needed. Do you want to force an update?" withDefault:NO] == false) { return; } } - + //confirm wrapper change - if ([NSAlert showBooleanAlertOfType:NSAlertTypeWarning withMessage:@"Are you sure you want to do this update? It will change out the wrappers main Wineskin files with newer copies from whatever Master Wrapper you have installed with Wineskin Winery. The following files/folders will be replaced in the wrapper:\nWineskin.app\nContents/MacOS\nContents/Frameworks\nContents/Resources/Base.lproj\nContents/Resources/en.lproj" withDefault:NO] == false) - { + if ([NSAlert showBooleanAlertOfType:NSAlertTypeWarning withMessage:@"Are you sure you want to do this update? It will change out the wrappers main Wineskin files with newer copies from whatever Master Wrapper you have installed with Wineskin Winery. The following files/folders will be replaced in the wrapper:\nContents/Wineskin.app\nContents/MacOS\nContents/Frameworks\nContents/Resources/Base.lproj\nContents/Resources/en.lproj" withDefault:NO] == false) { return; } - + //show busy window [busyWindow makeKeyAndOrderFront:self]; //hide advanced window [advancedWindow orderOut:self]; - + //delete old MacOS, and copy in new [self replaceFile:@"/Contents/MacOS" withVersionFromMasterWrapper:masterWrapperName]; - + //delete old WineskinLauncher.nib NSString* oldNibPath = [NSString stringWithFormat:@"%@/Contents/Resources/WineskinLauncher.nib",self.wrapperPath]; if ([fm fileExistsAtPath:oldNibPath]) [fm removeItemAtPath:oldNibPath]; @@ -1845,76 +1875,79 @@ - (IBAction)updateWrapperButtonPressed:(id)sender //delete winetricks NSString* oldwinetricks = [NSString stringWithFormat:@"%@/Contents/Resources/winetricks",self.wrapperPath]; if ([fm fileExistsAtPath:oldwinetricks]) [fm removeItemAtPath:oldwinetricks]; - + //delete winetricksHelpList.plist NSString* oldwinetricksHelpList = [NSString stringWithFormat:@"%@/Contents/Resources/winetricksHelpList.plist",self.wrapperPath]; if ([fm fileExistsAtPath:oldwinetricksHelpList]) [fm removeItemAtPath:oldwinetricksHelpList]; - + //delete old WineskinMenuScripts folder NSString* oldWineskinMenuScriptsPath = [NSString stringWithFormat:@"%@/Contents/Resources/WineskinMenuScripts",self.wrapperPath]; if ([fm fileExistsAtPath:oldWineskinMenuScriptsPath]) [fm removeItemAtPath:oldWineskinMenuScriptsPath]; - + //delete old WineskinShutdownScript NSString* WineskinShutdownScriptPath = [NSString stringWithFormat:@"%@/Contents/Resources/WineskinShutdownScript",self.wrapperPath]; if ([fm fileExistsAtPath:WineskinShutdownScriptPath]) [fm removeItemAtPath:WineskinShutdownScriptPath]; - + //delete old WineskinStartupScript NSString* WineskinStartupScriptPath = [NSString stringWithFormat:@"%@/Contents/Resources/WineskinStartupScript",self.wrapperPath]; if ([fm fileExistsAtPath:WineskinStartupScriptPath]) [fm removeItemAtPath:WineskinStartupScriptPath]; - + //delete old English.lproj NSString* oldEnglishMenu = [NSString stringWithFormat:@"%@/Contents/Resources/English.lproj",self.wrapperPath]; if ([fm fileExistsAtPath:oldEnglishMenu]) [fm removeItemAtPath:oldEnglishMenu]; //copy new Base.lproj, and copy in new [self replaceFile:@"/Contents/Resources/Base.lproj" withVersionFromMasterWrapper:masterWrapperName]; - + //copy new en.lproj, and copy in new [self replaceFile:@"/Contents/Resources/en.lproj" withVersionFromMasterWrapper:masterWrapperName]; - + //copy new Scripts folder NSString* ScriptsPath = [NSString stringWithFormat:@"%@/Contents/Resources/Scripts",self.wrapperPath]; if (![fm fileExistsAtPath:ScriptsPath]) [self replaceFile:@"/Contents/Resources/Scripts" withVersionFromMasterWrapper:masterWrapperName]; - + //edit Info.plist to new wrapper version, replace - with spaces, and dump .app [portManager setPlistObject:[[masterWrapperName stringByReplacingOccurrencesOfString:@".app" withString:@""] stringByReplacingOccurrencesOfString:@"-" withString:@" "] forKey:WINESKIN_WRAPPER_PLIST_KEY_WINESKIN_VERSION]; - + //Make sure new keys are added to the old Info.plist NSMutableDictionary *newPlistDictionary = [NSMutableDictionary mutableDictionaryWithContentsOfFile:[NSString stringWithFormat:@"%@/%@/Contents/Info.plist",WINESKIN_LIBRARY_WRAPPER_FOLDER,masterWrapperName]]; [newPlistDictionary addEntriesFromDictionary:portManager.plist]; [portManager setPlist:newPlistDictionary]; [portManager synchronizePlist]; [self systemCommand:@"/bin/chmod" withArgs:@[@"777",[NSString stringWithFormat:@"%@/Contents/Info.plist",self.wrapperPath]]]; - + //force delete Wineskin.app and copy in new - [self replaceFile:@"/Wineskin.app" withVersionFromMasterWrapper:masterWrapperName]; - + [self replaceFile:@"/Contents/Wineskin.app" withVersionFromMasterWrapper:masterWrapperName]; + //move wswine.bundle out of Frameworks //NSString* wswineBundleOriginalPath = self.wswineBundlePath; //NSString* wswineBundleTempPath = @"/tmp/wswineWSTEMP.bundle"; //[fm moveItemAtPath:wswineBundleOriginalPath toPath:wswineBundleTempPath]; - + //replace Frameworks [self replaceFile:@"/Contents/Frameworks" withVersionFromMasterWrapper:masterWrapperName]; - + //move wswine.bundle back into Frameworks //[fm moveItemAtPath:wswineBundleTempPath toPath:wswineBundleOriginalPath]; - + //open new Wineskin.app - [self systemCommand:@"/usr/bin/open" withArgs:@[@"-n",[NSString stringWithFormat:@"%@/Wineskin.app",self.wrapperPath]]]; - + [self systemCommand:@"/usr/bin/open" withArgs:@[@"-n",self.wineskinPath]]; + //close program [NSApp terminate:sender]; } + - (IBAction)logsButtonPressed:(id)sender { NSString* logsFolder = [NSString stringWithFormat:@"%@/Contents/SharedSupport/Logs",self.wrapperPath]; [self systemCommand:@"/usr/bin/open" withArgs:@[@"-a", @"Console",[NSString stringWithFormat:@"%@/LastRunWine.log",logsFolder]]]; } + - (IBAction)commandLineShellButtonPressed:(id)sender { [NSThread detachNewThreadSelector:@selector(runCmd) toTarget:self withObject:nil]; } + - (void)runCmd { @autoreleasepool @@ -1924,6 +1957,7 @@ - (void)runCmd [self enableButtons]; } } + //************************************************************* //*********************** OVERRIDES *************************** //************************************************************* @@ -1931,94 +1965,90 @@ - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theAppl { return YES; } + - (BOOL)windowShouldClose:(id)sender { - if (disableXButton) - { + if (disableXButton) { return NO; - } - else if (sender==window) - { + } else if (sender==window) { //don't do anything... yet - } - else if (sender==advancedWindow) - { + } else if (sender==advancedWindow) { [self saveAllData]; - } - else if (sender==winetricksWindow) - { + } else if (sender==winetricksWindow) { [self winetricksDoneButtonPressed:sender]; return NO; - } - else if (sender==installerWindow) - { - if (usingAdvancedWindow) - [advancedWindow makeKeyAndOrderFront:self]; - else - [window makeKeyAndOrderFront:self]; + } else if (sender==installerWindow) { + if (usingAdvancedWindow) { + [advancedWindow makeKeyAndOrderFront:self]; + } else { + [window makeKeyAndOrderFront:self]; + } } [sender orderOut:self]; return NO; } + - (NSApplicationTerminateReply)applicationShouldTerminate:(id)sender { [self saveAllData]; return YES; } + - (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem { [self saveAllData]; } + //************************************************************* //******************* Extensions Window *********************** //************************************************************* - (IBAction)extSaveButtonPressed:(id)sender { - if ([[extExtensionTextField stringValue] isEqualToString:@""] || [[extCommandTextField stringValue] isEqualToString:@""]) - { + if ([[extExtensionTextField stringValue] isEqualToString:@""] || [[extCommandTextField stringValue] isEqualToString:@""]) { [NSAlert showAlertOfType:NSAlertTypeError withMessage:@"You left an entry field blank..."]; return; } - + [busyWindow makeKeyAndOrderFront:self]; [extAddEditWindow orderOut:self]; - + //edit the system.reg to make sure Associations exist correctly, and add them if they do not. //make sure the extension doesn't have dots NSString* extension = [[extExtensionTextField stringValue] stringByReplacingOccurrencesOfString:@"." withString:@""]; - + //fix stringToWrite to escape quotes and backslashes before writing NSString *stringToWrite = [extCommandTextField stringValue]; stringToWrite = [stringToWrite stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"]; stringToWrite = [stringToWrite stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; - + NSString* regSoftwareClassesExtension = [NSString stringWithFormat:@"[Software\\\\Classes\\\\.%@]",extension]; NSString* regSoftwareClassesExtensionShellOpenCommand = [NSString stringWithFormat:@"[Software\\\\Classes\\\\%@file\\\\shell\\\\open\\\\command]",extension]; - + NSMutableString* registry1 = [[portManager getRegistryEntry:regSoftwareClassesExtension fromRegistryFileNamed:SYSTEM_REG] mutableCopy]; NSMutableString* registry2 = [[portManager getRegistryEntry:regSoftwareClassesExtensionShellOpenCommand fromRegistryFileNamed:SYSTEM_REG] mutableCopy]; - + [portManager setValue:[NSString stringWithFormat:@"\"%@file\"",extension] forKey:nil atRegistryEntryString:registry1]; [portManager setValue:[NSString stringWithFormat:@"\"%@\"",stringToWrite] forKey:nil atRegistryEntryString:registry2]; - + [portManager deleteRegistry:regSoftwareClassesExtension fromRegistryFileNamed:SYSTEM_REG]; [portManager deleteRegistry:regSoftwareClassesExtensionShellOpenCommand fromRegistryFileNamed:SYSTEM_REG]; - + [portManager addRegistry:[NSString stringWithFormat:@"%@\n%@\n",regSoftwareClassesExtension,registry1] fromRegistryFileNamed:SYSTEM_REG]; [portManager addRegistry:[NSString stringWithFormat:@"%@\n%@\n",regSoftwareClassesExtensionShellOpenCommand,registry2] fromRegistryFileNamed:SYSTEM_REG]; - + //add to Info.plist NSMutableArray *assArray = [[[portManager plistObjectForKey:WINESKIN_WRAPPER_PLIST_KEY_ASSOCIATIONS] componentsSeparatedByString:@" "] mutableCopy]; if (![assArray containsObject:extension]) [assArray addObject:extension]; NSString *newExtString = [assArray componentsJoinedByString:@" "]; [portManager setPlistObject:newExtString forKey:WINESKIN_WRAPPER_PLIST_KEY_ASSOCIATIONS]; [portManager synchronizePlist]; - + [self loadAllData]; [advancedWindow makeKeyAndOrderFront:self]; [busyWindow orderOut:self]; } + - (IBAction)extCancelButtonPressed:(id)sender { [self loadAllData]; @@ -2039,7 +2069,7 @@ - (IBAction)modifyMappingsSaveButtonPressed:(id)sender [portManager setPlistObject:[modifyMappingsDownloadsTextField stringValue] forKey:@"Symlink Downloads"]; [portManager setPlistObject:[modifyMappingsTemplatesTextField stringValue] forKey:@"Symlink Templates"]; [portManager synchronizePlist]; - + [advancedWindow makeKeyAndOrderFront:self]; [modifyMappingsWindow orderOut:self]; } @@ -2072,21 +2102,19 @@ -(NSString*)newPathForMappingOfFolder:(NSString*)folder [panel setTreatsFilePackagesAsDirectories:YES]; [panel setShowsHiddenFiles:YES]; [panel setInitialDirectory:@"/"]; - - if ([panel runModal] == 0) - { + + if ([panel runModal] == 0) { return nil; } - + return [[[[panel URLs] objectAtIndex:0] path] stringByReplacingOccurrencesOfString:NSHomeDirectory() withString:@"$HOME"]; } - (IBAction)modifyMappingsMyDocumentsBrowseButtonPressed:(id)sender { - NSString* newPath = [self newPathForMappingOfFolder:@"My Documents"]; - - if (newPath) - { + NSString* newPath = [self newPathForMappingOfFolder:@"Documents"]; + + if (newPath) { [modifyMappingsMyDocumentsTextField setStringValue:newPath]; } } @@ -2094,39 +2122,35 @@ - (IBAction)modifyMappingsMyDocumentsBrowseButtonPressed:(id)sender - (IBAction)modifyMappingsMyDesktopBrowseButtonPressed:(id)sender { NSString* newPath = [self newPathForMappingOfFolder:@"Desktop"]; - - if (newPath) - { + + if (newPath) { [modifyMappingsDesktopTextField setStringValue:newPath]; } } - (IBAction)modifyMappingsMyVideosBrowseButtonPressed:(id)sender { - NSString* newPath = [self newPathForMappingOfFolder:@"My Videos"]; - - if (newPath) - { + NSString* newPath = [self newPathForMappingOfFolder:@"Videos"]; + + if (newPath) { [modifyMappingsMyVideosTextField setStringValue:newPath]; } } - (IBAction)modifyMappingsMyMusicBrowseButtonPressed:(id)sender { - NSString* newPath = [self newPathForMappingOfFolder:@"My Music"]; - - if (newPath) - { + NSString* newPath = [self newPathForMappingOfFolder:@"Music"]; + + if (newPath) { [modifyMappingsMyMusicTextField setStringValue:newPath]; } } - (IBAction)modifyMappingsMyPicturesBrowseButtonPressed:(id)sender { - NSString* newPath = [self newPathForMappingOfFolder:@"My Pictures"]; - - if (newPath) - { + NSString* newPath = [self newPathForMappingOfFolder:@"Pictures"]; + + if (newPath) { [modifyMappingsMyPicturesTextField setStringValue:newPath]; } } @@ -2134,9 +2158,8 @@ - (IBAction)modifyMappingsMyPicturesBrowseButtonPressed:(id)sender - (IBAction)modifyMappingsDownloadsBrowseButtonPressed:(id)sender { NSString* newPath = [self newPathForMappingOfFolder:@"Downloads"]; - - if (newPath) - { + + if (newPath) { [modifyMappingsDownloadsTextField setStringValue:newPath]; } } @@ -2144,9 +2167,8 @@ - (IBAction)modifyMappingsDownloadsBrowseButtonPressed:(id)sender - (IBAction)modifyMappingsTemplatesBrowseButtonPressed:(id)sender { NSString* newPath = [self newPathForMappingOfFolder:@"Templates"]; - - if (newPath) - { + + if (newPath) { [modifyMappingsTemplatesTextField setStringValue:newPath]; } } @@ -2157,14 +2179,12 @@ - (NSString *)systemCommand:(NSString *)command char buff[512]; NSMutableString *returnString = [[NSMutableString alloc] init]; fp = popen([command cStringUsingEncoding:NSUTF8StringEncoding], "r"); - while (fgets( buff, sizeof buff, fp)) - { + while (fgets( buff, sizeof buff, fp)) { [returnString appendString:[NSString stringWithCString:buff encoding:NSUTF8StringEncoding]]; } pclose(fp); //cut out trailing new line - if ([returnString hasSuffix:@"\n"]) - { + if ([returnString hasSuffix:@"\n"]) { [returnString deleteCharactersInRange:NSMakeRange([returnString length]-1,1)]; } return [NSString stringWithString:returnString]; @@ -2179,113 +2199,129 @@ - (void)installEngine [NSPathUtilities wineskinLauncherBinForPortAtPath:self.wrapperPath]]; system([theSystemCommand UTF8String]); } + //************************************************************* //***** NSOutlineViewDataSource (winetricks) ****************** //************************************************************* /* Required methods */ - (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)childIndex ofItem:(id)item { - if (!winetricksDone) - return nil; - if (outlineView != winetricksOutlineView) - return nil; - if (!item) - item = winetricksFilteredList; + if (!winetricksDone) { + return nil; + } + if (outlineView != winetricksOutlineView) { + return nil; + } + if (!item) { + item = winetricksFilteredList; + } NSUInteger count = ([item valueForKey:WINETRICK_NAME] == nil ? [item count] : 0); // Set count to zero if the item is a package - if (count <= childIndex) - return nil; + if (count <= childIndex) { + return nil; + } return [item objectForKey:[[[item allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] objectAtIndex:childIndex]]; } - (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item { - if (!winetricksDone) - return NO; - if (outlineView != winetricksOutlineView) - return NO; - if ([item valueForKey:WINETRICK_NAME] != nil) - return NO; + if (!winetricksDone) { + return NO; + } + if (outlineView != winetricksOutlineView) { + return NO; + } + if ([item valueForKey:WINETRICK_NAME] != nil) { + return NO; + } return YES; } - (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item { - if (!winetricksDone) - return 0; - if (outlineView != winetricksOutlineView) - return 0; - if ([item valueForKey:WINETRICK_NAME] != nil) - return 0; + if (!winetricksDone) { + return 0; + } + if (outlineView != winetricksOutlineView) { + return 0; + } + if ([item valueForKey:WINETRICK_NAME] != nil) { + return 0; + } return [(item ? item : [self winetricksFilteredList]) count]; } - (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item { - if (!winetricksDone) - return nil; + if (!winetricksDone) { + return nil; + } if (outlineView != winetricksOutlineView) return nil; if ((tableColumn == winetricksTableColumnRun || tableColumn == winetricksTableColumnInstalled || tableColumn == winetricksTableColumnDownloaded) - && [item valueForKey:WINETRICK_NAME] == nil) - return @""; - if (tableColumn == winetricksTableColumnRun) - { + && [item valueForKey:WINETRICK_NAME] == nil) { + return @""; + } + if (tableColumn == winetricksTableColumnRun) { NSNumber *thisEntry = [[self winetricksSelectedList] valueForKey:[item valueForKey:WINETRICK_NAME]]; if (thisEntry == nil) return [NSNumber numberWithBool:NO]; return thisEntry; - } - else if (tableColumn == winetricksTableColumnInstalled) - { + } else if (tableColumn == winetricksTableColumnInstalled) { for (NSString *eachEntry in [self winetricksInstalledList]) - if ([eachEntry isEqualToString:[item valueForKey:WINETRICK_NAME]]) - return @"\u2713"; // Check mark character + if ([eachEntry isEqualToString:[item valueForKey:WINETRICK_NAME]]) { + return @"\u2713"; // Check mark character + } return @""; - } - else if (tableColumn == winetricksTableColumnDownloaded) - { + } else if (tableColumn == winetricksTableColumnDownloaded) { for (NSString *eachEntry in [self winetricksCachedList]) if ([eachEntry isEqualToString:[item valueForKey:WINETRICK_NAME]]) return @"\u2713"; // Check mark character return @""; - } - else if (tableColumn == winetricksTableColumnName) - { - if ([item valueForKey:WINETRICK_NAME] != nil) - return [item valueForKey:WINETRICK_NAME]; + } else if (tableColumn == winetricksTableColumnName) { + if ([item valueForKey:WINETRICK_NAME] != nil) { + return [item valueForKey:WINETRICK_NAME]; + } NSDictionary *parentDict = [outlineView parentForItem:item]; return [[(parentDict ? parentDict : [self winetricksFilteredList]) allKeysForObject:item] objectAtIndex:0]; - } - else if (tableColumn == winetricksTableColumnDescription) - { - if ([item valueForKey:WINETRICK_DESCRIPTION] != nil) - return [item valueForKey:WINETRICK_DESCRIPTION]; + } else if (tableColumn == winetricksTableColumnDescription) { + if ([item valueForKey:WINETRICK_DESCRIPTION] != nil) { + return [item valueForKey:WINETRICK_DESCRIPTION]; + } return @""; } return nil; } + /* Optional Methods */ - (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item { - if (!winetricksDone) - return; - if (outlineView != winetricksOutlineView) - return; - if (tableColumn != winetricksTableColumnRun) - return; - if ([item valueForKey:WINETRICK_NAME] == nil) - return; + if (!winetricksDone) { + return; + } + if (outlineView != winetricksOutlineView) { + return; + } + if (tableColumn != winetricksTableColumnRun) { + return; + } + if ([item valueForKey:WINETRICK_NAME] == nil) { + return; + } [[self winetricksSelectedList] setValue:object forKey:[item valueForKey:WINETRICK_NAME]]; } + /* Delegate */ - (NSCell *)outlineView:(NSOutlineView *)outlineView dataCellForTableColumn:(NSTableColumn *)tableColumn item:(id)item { - if (!winetricksDone) - return nil; - if (tableColumn == winetricksTableColumnRun && [item valueForKey:WINETRICK_NAME] == nil) - return [[NSTextFieldCell alloc] init]; + if (!winetricksDone) { + return nil; + } + if (tableColumn == winetricksTableColumnRun && [item valueForKey:WINETRICK_NAME] == nil) { + return [[NSTextFieldCell alloc] init]; + } return [tableColumn dataCellForRow:[outlineView rowForItem:item]]; } + @end diff --git a/WineskinApp/Wineskin_Prefix.pch b/WineskinApp/Wineskin_Prefix.pch index ef1ceed..5af163e 100644 --- a/WineskinApp/Wineskin_Prefix.pch +++ b/WineskinApp/Wineskin_Prefix.pch @@ -42,7 +42,6 @@ #define WINESKIN_WRAPPER_PLIST_KEY_IDENTIFIER @"CFBundleIdentifier" #define WINESKIN_WRAPPER_PLIST_KEY_EXECUTABLE @"CFBundleExecutable" #define WINESKIN_WRAPPER_PLIST_KEY_SINGLE_CPU @"Disable CPUs" -#define WINESKIN_WRAPPER_PLIST_KEY_MAX_OF_10240_FILES @"set max files" #define WINESKIN_WRAPPER_PLIST_KEY_ASSOCIATIONS @"Associations" #define WINESKIN_WRAPPER_PLIST_KEY_AUTOMATICALLY_DETECT_GPU @"Try To Use GPU Info" #define WINESKIN_WRAPPER_PLIST_KEY_RUN_PATH @"Program Name and Path" @@ -62,6 +61,14 @@ #define WINESKIN_WRAPPER_PLIST_KEY_DISABLE_MONO @"Skip Mono" #define WINESKIN_WRAPPER_PLIST_KEY_SYMLINK_USERS @"Symlinks In User Folder" #define WINESKIN_WRAPPER_PLIST_KEY_WINEDEBUG @"WINEDEBUG" +#define WINESKIN_WRAPPER_PLIST_KEY_ESYNC @"WINEESYNC" +#define WINESKIN_WRAPPER_PLIST_KEY_MSYNC @"WINEMSYNC" +#define WINESKIN_WRAPPER_PLIST_KEY_D3DMETAL @"D3DMETAL" +#define WINESKIN_WRAPPER_PLIST_KEY_D3DMETAL_FORCE @"D3DMETAL_FORCE" +#define WINESKIN_WRAPPER_PLIST_KEY_METAL_HUD @"METAL_HUD" +#define WINESKIN_WRAPPER_PLIST_KEY_UNIX_COMMANDS @"CLI Custom Commands" +#define WINESKIN_WRAPPER_PLIST_KEY_MOLTENVK_FASTMATH @"FASTMATH" +#define WINESKIN_WRAPPER_PLIST_KEY_MOLTENVK_CX @"MOLTENVKCX" // Wineskin Plist values #define WINESKIN_WRAPPER_PLIST_VALUE_SCREEN_OPTIONS_CURRENT_RESOLUTION @"Current Resolution" diff --git a/WineskinApp/curl b/WineskinApp/curl index 8c8b790..575ca0d 100755 --- a/WineskinApp/curl +++ b/WineskinApp/curl @@ -2,7 +2,7 @@ # # Wrapper script for winetricks compatability # -# Copyright (C) 2019-2023 Dean M Greer +# Copyright (C) 2019-2024 Dean M Greer # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public diff --git a/WineskinApp/wine b/WineskinApp/wine index 19de9e1..99c558b 100755 --- a/WineskinApp/wine +++ b/WineskinApp/wine @@ -2,7 +2,7 @@ # # Wrapper script for winetricks compatability # -# Copyright (C) 2018-2023 Dean M Greer +# Copyright (C) 2018-2024 Dean M Greer # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -21,10 +21,23 @@ # workaround SIP DYLD_stripping # see https://support.apple.com/en-us/HT204899 -export WINETRICKS_FALLBACK_LIBRARY_PATH="${WINETRICKS_FALLBACK_LIBRARY_PATH:-$(dirname "$0")/../../../Contents/Frameworks}" +export WINETRICKS_FALLBACK_LIBRARY_PATH="$(dirname "$0")/../../../Frameworks:$(dirname "$0")/../../../Frameworks/GStreamer.framework/Libraries" + +export GST_PLUGIN_PATH="$(dirname "$0")/../../../Frameworks/GStreamer.framework/Libraries/gstreamer-1.0" +export WINESKINPATH="$(dirname "$0")/../../../SharedSupport/wine/bin" +export WINEPREFIX="${WINEPREFIX:-$(dirname "$0")/../../../SharedSupport/prefix}" + +if [[ ${OSTYPE:6} -ge 23 && "$(/usr/bin/env arch -x86_64 /usr/sbin/sysctl -in sysctl.proc_translated)" = "1" && -n "${WINED3DMETAL}" ]]; then + export D3DMETALPATH="$(dirname "$0")/../../../Frameworks/d3dmetal/wine" + export WINETRICKS_FALLBACK_LIBRARY_PATH="$(dirname "$0")/../../../Frameworks/moltenvkcx:${WINETRICKS_FALLBACK_LIBRARY_PATH}" + export WINEDLLOVERRIDES="*dxgi,*d3d10core,*d3d11,*d3d12=b" +fi + export DYLD_FALLBACK_LIBRARY_PATH="${WINETRICKS_FALLBACK_LIBRARY_PATH}" -export WINESKINPATH="$(dirname "$0")/../../../Contents/SharedSupport/wine/bin" -export WINEPREFIX="${WINEPREFIX:-$(dirname "$0")/../../../Contents/SharedSupport/prefix}" + +# .Net 7 and later segfault under Rosetta2 +# https://github.com/dotnet/runtime/issues/94909 +export DOTNET="DOTNET_EnableWriteXorExecute=0" # Pre macOS Catalina check for wine and use if found if [[ ${OSTYPE:6} -lt 19 && -x "$(command -v "$WINESKINPATH"/wine)" ]]; then exec "$WINESKINPATH/wine" "${@}"; fi diff --git a/WineskinApp/wine64 b/WineskinApp/wine64 index 9f10f29..0dba346 100755 --- a/WineskinApp/wine64 +++ b/WineskinApp/wine64 @@ -2,7 +2,7 @@ # # Wrapper script for winetricks compatability # -# Copyright (C) 2018-2023 Dean M Greer +# Copyright (C) 2018-2024 Dean M Greer # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -21,10 +21,23 @@ # workaround SIP DYLD_stripping # see https://support.apple.com/en-us/HT204899 -export WINETRICKS_FALLBACK_LIBRARY_PATH="${WINETRICKS_FALLBACK_LIBRARY_PATH:-$(dirname "$0")/../../../Contents/Frameworks}" +export WINETRICKS_FALLBACK_LIBRARY_PATH="$(dirname "$0")/../../../Frameworks:$(dirname "$0")/../../../Frameworks/GStreamer.framework/Libraries" + +export GST_PLUGIN_PATH="$(dirname "$0")/../../../Frameworks/GStreamer.framework/Libraries/gstreamer-1.0" +export WINESKINPATH="$(dirname "$0")/../../../SharedSupport/wine/bin" +export WINEPREFIX="${WINEPREFIX:-$(dirname "$0")/../../../SharedSupport/prefix}" + +if [[ ${OSTYPE:6} -ge 23 && "$(/usr/bin/env arch -x86_64 /usr/sbin/sysctl -in sysctl.proc_translated)" = "1" && -n "${WINED3DMETAL}" ]]; then + export D3DMETALPATH="$(dirname "$0")/../../../Frameworks/d3dmetal/wine" + export WINETRICKS_FALLBACK_LIBRARY_PATH="$(dirname "$0")/../../../Frameworks/moltenvkcx:${WINETRICKS_FALLBACK_LIBRARY_PATH}" + export WINEDLLOVERRIDES="*dxgi,*d3d10core,*d3d11,*d3d12=b" +fi + export DYLD_FALLBACK_LIBRARY_PATH="${WINETRICKS_FALLBACK_LIBRARY_PATH}" -export WINESKINPATH="$(dirname "$0")/../../../Contents/SharedSupport/wine/bin" -export WINEPREFIX="${WINEPREFIX:-$(dirname "$0")/../../../Contents/SharedSupport/prefix}" + +# .Net 7 and later segfault under Rosetta2 +# https://github.com/dotnet/runtime/issues/94909 +export DOTNET="DOTNET_EnableWriteXorExecute=0" # Check for wine64 and use if found if [[ -x "$(command -v "$WINESKINPATH"/wine64)" ]]; then exec "$WINESKINPATH/wine64" "${@}"; fi diff --git a/WineskinApp/winehelp b/WineskinApp/winehelp index dcb6332..3088b84 100755 --- a/WineskinApp/winehelp +++ b/WineskinApp/winehelp @@ -2,7 +2,7 @@ # # Wrapper script for using a Wineskin Engine like Winehq wine bundle # -# Copyright (C) 2018-2023 Dean M Greer +# Copyright (C) 2018-2024 Dean M Greer # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -24,11 +24,8 @@ cd "$(dirname "$0")" # wine wrappers, winetricks, 7z, cabextract & unrar export WINESKIN_APP="${PWD}" -# WINEPREFIX location -cd "../../../Contents/SharedSupport/prefix"; export WINEPREFIX="${PWD}" - # Wrappers wine PATH -cd "../wine"; export WINEPATH="${PWD}" +cd "../../../SharedSupport/wine"; export WINEPATH="${PWD}" # Wrappes wine/bin PATH export WINEBINPATH="${WINEPATH}/bin" @@ -36,19 +33,14 @@ export WINEBINPATH="${WINEPATH}/bin" # Set $PATH export PATH="${WINESKIN_APP}:${WINEBINPATH}:${PATH}" -# Wineskins "RUNTIME" -cd "../../Frameworks"; export WINESKIN_RUNTIME="${PWD}" - -# Custom export to workaround SIP DYLD_ stripping -export WINETRICKS_FALLBACK_LIBRARY_PATH="${WINESKIN_RUNTIME}:${HOME}/Library/Application Support/Wineskin/Runtime:/opt/local/lib:${WINEPATH}/lib:${WINEPATH}/lib64:/usr/lib:/usr/libexec:/usr/lib/system:/opt/X11/lib" - # Set Wineskin default WINEDEBUG options -export WINEDEBUG="-esync,-plugplay" +export WINEDEBUG="-plugplay" # Set required MoltenVK setting -export MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE=1 # XXX Required by DXVK for AMD500/Intel GPUs -export MVK_ALLOW_METAL_FENCES=1 # XXX Required by DXVK for Apple/NVidia GPUs (better FPS than CPU Emulation) -export MVK_CONFIG_RESUME_LOST_DEVICE=1 # XXX Required by WINE (doesn't handle VK_ERROR_DEVICE_LOST correctly) +export MVK_ALLOW_METAL_FENCES=1 +export MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE=1 +export MVK_CONFIG_RESUME_LOST_DEVICE=1 +export MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE=MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE # Default directory location "should" be $HOME cd "${HOME}" diff --git a/WineskinApp/wineserver b/WineskinApp/wineserver index d27cc3c..b94c745 100755 --- a/WineskinApp/wineserver +++ b/WineskinApp/wineserver @@ -21,20 +21,23 @@ # workaround SIP DYLD_stripping # see https://support.apple.com/en-us/HT204899 -if [[ -n ${WINETRICKS_FALLBACK_LIBRARY_PATH} ]]; then - export DYLD_FALLBACK_LIBRARY_PATH="${WINETRICKS_FALLBACK_LIBRARY_PATH}" -else - export WINETRICKS_FALLBACK_LIBRARY_PATH="$(dirname "$0")"/../../../Contents/Frameworks - export DYLD_FALLBACK_LIBRARY_PATH="${WINETRICKS_FALLBACK_LIBRARY_PATH}" -fi +export WINETRICKS_FALLBACK_LIBRARY_PATH="$(dirname "$0")/../../../Frameworks:$(dirname "$0")/../../../Frameworks/GStreamer.framework/Libraries" + +export GST_PLUGIN_PATH="$(dirname "$0")/../../../Frameworks/GStreamer.framework/Libraries/gstreamer-1.0" +export WINESKINPATH="$(dirname "$0")/../../../SharedSupport/wine/bin" +export WINEPREFIX="${WINEPREFIX:-$(dirname "$0")/../../../SharedSupport/prefix}" -if [[ -n ${WINEPREFIX} ]]; then - export WINEPREFIX="${WINEPREFIX}" -else - export WINEPREFIX="$(dirname "$0")"/../../../Contents/SharedSupport/prefix +if [[ ${OSTYPE:6} -ge 23 && "$(/usr/bin/env arch -x86_64 /usr/sbin/sysctl -in sysctl.proc_translated)" = "1" && -n "${WINED3DMETAL}" ]]; then + export D3DMETALPATH="$(dirname "$0")/../../../Frameworks/d3dmetal/wine" + export WINETRICKS_FALLBACK_LIBRARY_PATH="$(dirname "$0")/../../../Frameworks/moltenvkcx:${WINETRICKS_FALLBACK_LIBRARY_PATH}" + export WINEDLLOVERRIDES="*dxgi,*d3d10core,*d3d11,*d3d12=b" fi -export WINESKINPATH="$(dirname "$0")"/../../../Contents/SharedSupport/wine/bin +export DYLD_FALLBACK_LIBRARY_PATH="${WINETRICKS_FALLBACK_LIBRARY_PATH}" + +# .Net 7 and later segfault under Rosetta2 +# https://github.com/dotnet/runtime/issues/94909 +export DOTNET="DOTNET_EnableWriteXorExecute=0" # Check for wineserver and use if found if [[ -x "$(command -v "$WINESKINPATH"/wineserver)" ]]; then exec "$WINESKINPATH/wineserver" "$@"; fi