├── Cartfile ├── Wineskin Winery ├── 7za ├── English.lproj │ └── InfoPlist.strings ├── cabextract ├── Winery.icns ├── WineskinBanner.jpg ├── main.m ├── Wineskin Winery.entitlements ├── Wineskin Winery.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── Wineskin Winery.xccheckout │ └── xcshareddata │ │ └── xcschemes │ │ └── Wineskin Winery.xcscheme ├── Wineskin_Winery_Prefix.pch ├── Wineskin.h ├── Wineskin.m ├── WineskinWineryUpdater ├── Wineskin_Winery-Info.plist ├── NSWineskinEngine.h └── Wineskin_WineryAppDelegate.h ├── WineskinApp ├── English.lproj │ └── InfoPlist.strings ├── WSGamma ├── fntoggle ├── Wineskin.icns ├── WineskinBanner.jpg ├── WineskinBanner2.jpg ├── main.m ├── CustomEXE.app │ └── Contents │ │ ├── Resources │ │ └── Wineskin.icns │ │ ├── _CodeSignature │ │ ├── CodeRequirements │ │ └── CodeResources │ │ ├── Info.plist │ │ ├── MacOS │ │ └── CustomEXE │ │ └── Info.plist.cexe ├── IconDragAndDrop.h ├── Wineskin.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── Wineskin.xccheckout │ │ │ └── Wineskin.xcscmblueprint │ └── xcshareddata │ │ └── xcschemes │ │ └── Wineskin.xcscheme ├── Defaults.plist ├── NSDropIconView.h ├── NSArray+Extension.h ├── IconDragAndDrop.m ├── NSExeSelection.h ├── NSWebUtilities.h ├── NSData+Extension.h ├── NSImage+Extension.h ├── NSSavePanel+Extension.h ├── NSMutableDictionary+Extension.h ├── NSUtilities.h ├── NSTask+Extension.h ├── NSThread+Extension.h ├── NSMutableDictionary+Extension.m ├── NSWineskinEngine.h ├── NSSavePanel+Extension.m ├── Command Line Wine Test ├── NSArray+Extension.m ├── NSData+Extension.m ├── NSPathUtilities.h ├── NSThread+Extension.m ├── NSFileManager+Extension.h ├── NSPortDataLoader.h ├── Download.h ├── NSProgressView.h ├── NSString+Extension.h ├── NSAlert+Extension.h ├── Wineskin-Info.plist ├── NSComputerInformation.h ├── NSWineskinPortDataWriter.h ├── NSWebUtilities.m ├── NSComputerInformation.m ├── NSPortManager.h ├── NSUtilities.m ├── NSProgressView.m ├── NSDropIconView.m ├── NSTask+Extension.m ├── NSFileManager+Extension.m ├── NSImage+Extension.m ├── NSString+Extension.m ├── Wineskin_Prefix.pch ├── remakedefaults.reg ├── NSAlert+Extension.m ├── NSWineskinPortDataWriter.m ├── Download.m └── NSPathUtilities.m ├── Cartfile.resolved ├── WineskinLauncher ├── Scripts │ ├── WineskinQuit.exe │ ├── WineskinShutdownScript │ ├── WineskinStartupScript │ └── WineskinQuitScript ├── WineskinLauncher.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── WineskinLauncher.xccheckout │ └── xcshareddata │ │ └── xcschemes │ │ └── WineskinLauncher.xcscheme ├── English.lproj │ └── InfoPlist.strings ├── main.m ├── NSExeSelection.h ├── NSPortDataLoader.h ├── NSPathUtilities.h ├── WineskinLauncher-Info.plist ├── WineStart.h ├── NSPortManager.h ├── WineStart.m ├── WineskinLauncher_Prefix.pch ├── NSPortDataLoader.m ├── WineskinLauncherAppDelegate.h └── NSPathUtilities.m ├── Wineskin.xcworkspace ├── xcshareddata │ └── IDEWorkspaceChecks.plist └── contents.xcworkspacedata ├── .travis.yml ├── .gitignore └── README.md /Cartfile: -------------------------------------------------------------------------------- 1 | github "WineskinCommunity/ObjectiveC_Extension" "carthage" 2 | -------------------------------------------------------------------------------- /Wineskin Winery/7za: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitor251093/wineskin/HEAD/Wineskin Winery/7za -------------------------------------------------------------------------------- /WineskinApp/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /WineskinApp/WSGamma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitor251093/wineskin/HEAD/WineskinApp/WSGamma -------------------------------------------------------------------------------- /WineskinApp/fntoggle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitor251093/wineskin/HEAD/WineskinApp/fntoggle -------------------------------------------------------------------------------- /Wineskin Winery/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Wineskin Winery/cabextract: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitor251093/wineskin/HEAD/Wineskin Winery/cabextract -------------------------------------------------------------------------------- /WineskinApp/Wineskin.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitor251093/wineskin/HEAD/WineskinApp/Wineskin.icns -------------------------------------------------------------------------------- /Cartfile.resolved: -------------------------------------------------------------------------------- 1 | github "WineskinCommunity/ObjectiveC_Extension" "9cda34929d17baf6c0a47a9a34e849fa09d255a7" 2 | -------------------------------------------------------------------------------- /Wineskin Winery/Winery.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitor251093/wineskin/HEAD/Wineskin Winery/Winery.icns -------------------------------------------------------------------------------- /WineskinApp/WineskinBanner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitor251093/wineskin/HEAD/WineskinApp/WineskinBanner.jpg -------------------------------------------------------------------------------- /WineskinApp/WineskinBanner2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitor251093/wineskin/HEAD/WineskinApp/WineskinBanner2.jpg -------------------------------------------------------------------------------- /Wineskin Winery/WineskinBanner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitor251093/wineskin/HEAD/Wineskin Winery/WineskinBanner.jpg -------------------------------------------------------------------------------- /WineskinLauncher/Scripts/WineskinQuit.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitor251093/wineskin/HEAD/WineskinLauncher/Scripts/WineskinQuit.exe -------------------------------------------------------------------------------- /WineskinApp/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | int main(int argc, char *argv[]) 4 | { 5 | return NSApplicationMain(argc, (const char **) argv); 6 | } 7 | -------------------------------------------------------------------------------- /Wineskin Winery/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | int main(int argc, char *argv[]) 4 | { 5 | return NSApplicationMain(argc, (const char **) argv); 6 | } 7 | -------------------------------------------------------------------------------- /WineskinApp/CustomEXE.app/Contents/Resources/Wineskin.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitor251093/wineskin/HEAD/WineskinApp/CustomEXE.app/Contents/Resources/Wineskin.icns -------------------------------------------------------------------------------- /WineskinApp/CustomEXE.app/Contents/_CodeSignature/CodeRequirements: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitor251093/wineskin/HEAD/WineskinApp/CustomEXE.app/Contents/_CodeSignature/CodeRequirements -------------------------------------------------------------------------------- /Wineskin Winery/Wineskin Winery.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /WineskinApp/IconDragAndDrop.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface IconDragAndDrop : NSImageView 4 | { 5 | IBOutlet id delegate; 6 | } 7 | 8 | //- (void)setImage:(NSImage *)newImage; 9 | 10 | //- (NSImage *)image; 11 | 12 | @end -------------------------------------------------------------------------------- /WineskinApp/Wineskin.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Wineskin Winery/Wineskin Winery.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WineskinLauncher/WineskinLauncher.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Wineskin Winery/Wineskin_Winery_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'Wineskin Winery' target in the 'Wineskin Winery' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #import 8 | #endif 9 | -------------------------------------------------------------------------------- /WineskinLauncher/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | NSHumanReadableCopyright = "This program is copyright by the Wineskin project (http://wineskin.doh123.com/), and is licensed under the terms of the LGPL (http://www.gnu.org/licenses/lgpl.html)"; 4 | -------------------------------------------------------------------------------- /Wineskin.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Wineskin Winery/Wineskin.h: -------------------------------------------------------------------------------- 1 | // 2 | // Wineskin.h 3 | // Wineskin Winery 4 | // 5 | // Created by doh123 on 10/24/10. 6 | // Copyright 2010 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface Wineskin : NSObject 13 | { 14 | 15 | } 16 | 17 | 18 | 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Wineskin Winery/Wineskin.m: -------------------------------------------------------------------------------- 1 | // 2 | // Wineskin.m 3 | // Wineskin Winery 4 | // 5 | // Created by doh123 on 10/24/10. 6 | // Copyright 2010 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "Wineskin.h" 10 | #import "Downloader.h" 11 | 12 | 13 | @implementation Wineskin 14 | 15 | 16 | 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /WineskinApp/Defaults.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | InstalledColumnShown 6 | 7 | DownloadedColumnShown 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Wineskin Winery/WineskinWineryUpdater: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | THEAPP="$1" 3 | TOREPLACE="$THEAPP/Contents" 4 | REPLACEFROM="/tmp/WineskinWinery.app/Contents" 5 | sleep 1 6 | rm -rf "$TOREPLACE" 7 | mv "$REPLACEFROM" "$TOREPLACE" 8 | rm -rf "/tmp/WineskinWinery.app" 9 | rm -rf "/tmp/WineskinWinery.app.tar" 10 | rm -rf "/tmp/WineskinWinery.app.tar.7z" 11 | open "$THEAPP" 12 | -------------------------------------------------------------------------------- /WineskinApp/NSDropIconView.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSCImageView.h 3 | // Porting Center 4 | // 5 | // Created by Vitor Marques de Miranda. 6 | // Copyright 2014 UFRJ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSDropIconView : NSImageView 12 | 13 | -(void)loadIconFromFile:(NSString*)arquivo; 14 | 15 | @property (nonatomic) BOOL squareImage; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /WineskinLauncher/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // WineskinLauncher 4 | // 5 | // Copyright 2011 by The Wineskin Project and doh123@doh123.com All rights reserved. 6 | // Licensed for use under the LGPL 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | return NSApplicationMain(argc, (const char **) argv); 14 | } 15 | -------------------------------------------------------------------------------- /WineskinApp/NSArray+Extension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+Extension.h 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 15/05/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSArray (PKArray) 12 | 13 | -(NSArray*)sortedDictionariesArrayWithKey:(NSString *)key orderingByValuesOrder:(NSArray*)value; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | osx_image: xcode9.3 2 | language: objective-c 3 | 4 | before_script: 5 | - carthage update 6 | 7 | script: 8 | - set -o pipefail 9 | - xcodebuild -workspace Wineskin.xcworkspace -scheme Wineskin build | xcpretty -c 10 | - xcodebuild -workspace Wineskin.xcworkspace -scheme "Wineskin Winery" build | xcpretty -c 11 | - xcodebuild -workspace Wineskin.xcworkspace -scheme WineskinLauncher build | xcpretty -c 12 | -------------------------------------------------------------------------------- /WineskinLauncher/Scripts/WineskinShutdownScript: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd "$(dirname "$0")/../../" 3 | CONTENTSFOLD="$PWD" 4 | #################################################### 5 | # this script will run when Wineskin is shutting down 6 | # before clean up 7 | # $CONTENTSFOLD is the full path to the current 8 | # contents folder in the wrapper. 9 | #################################################### 10 | 11 | # ENTER COMMANDS HERE 12 | -------------------------------------------------------------------------------- /WineskinLauncher/NSExeSelection.h: -------------------------------------------------------------------------------- 1 | // 2 | // SelectMainEXE.h 3 | // Porting Center 4 | // 5 | // Created by Vitor Marques de Miranda. 6 | // Copyright 2014 UFRJ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSExeSelection : NSObject 12 | 13 | +(NSString*)getAutorunPathFromFile:(NSString*)arquivo; 14 | 15 | +(NSString*)selectAsMainExe:(NSString*)arquivo forPort:(NSString*)wrapperUrl; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Wineskin.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /WineskinLauncher/Scripts/WineskinStartupScript: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd "$(dirname "$0")/../../" 3 | CONTENTSFOLD="$PWD" 4 | #################################################### 5 | # this script will run when Wineskin is starting up 6 | # before the X server or Wine starts 7 | # $CONTENTSFOLD is the full path to the current 8 | # contents folder in the wrapper. 9 | #################################################### 10 | 11 | # ENTER COMMANDS HERE 12 | -------------------------------------------------------------------------------- /WineskinApp/IconDragAndDrop.m: -------------------------------------------------------------------------------- 1 | // 2 | // IconDragAndDrop.m 3 | // Wineskin 4 | // 5 | // Created by doh123 on 11/16/10. 6 | // Copyright 2010 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "IconDragAndDrop.h" 10 | 11 | 12 | @implementation IconDragAndDrop 13 | 14 | - (void)concludeDragOperation:(id )sender 15 | { 16 | //re-draw the view with our new data 17 | [self setNeedsDisplay:YES]; 18 | } 19 | 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /WineskinApp/NSExeSelection.h: -------------------------------------------------------------------------------- 1 | // 2 | // SelectMainEXE.h 3 | // Porting Center 4 | // 5 | // Created by Vitor Marques de Miranda. 6 | // Copyright 2014 UFRJ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSExeSelection : NSObject 12 | 13 | +(NSString*)getAutorunPathFromFile:(NSString*)arquivo forPort:(NSString*)wrapperUrl; 14 | 15 | +(NSString*)selectAsMainExe:(NSString*)arquivo forPort:(NSString*)wrapperUrl; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /WineskinApp/NSWebUtilities.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSWebUtilities.h 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/02/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #ifndef NSWebUtilities_Class 10 | #define NSWebUtilities_Class 11 | 12 | #import 13 | 14 | @interface NSWebUtilities : NSObject 15 | 16 | +(NSString*)timeNeededToDownload:(long long int)needed withSpeed:(long long int)speed; 17 | 18 | @end 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /WineskinApp/NSData+Extension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+Extension.h 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/02/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #ifndef NSData_Extension_Class 10 | #define NSData_Extension_Class 11 | 12 | #import 13 | 14 | @interface NSData (PKData) 15 | 16 | +(NSData*)dataWithContentsOfURL:(NSURL *)url timeoutInterval:(long long int)timeoutInterval; 17 | 18 | @end 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /WineskinApp/NSImage+Extension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSImage+Extension.h 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 12/03/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #ifndef NSImage_Extension_Class 10 | #define NSImage_Extension_Class 11 | 12 | #import 13 | 14 | @interface NSImage (PKImage) 15 | 16 | -(NSImage*)imageByFramingImageResizing:(BOOL)willResize; 17 | 18 | -(BOOL)saveAsIcnsAtPath:(NSString*)icnsPath; 19 | 20 | @end 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /WineskinApp/NSSavePanel+Extension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSSavePanel+Extension.h 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/02/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #ifndef NSSavePanel_Extension_Class 10 | #define NSSavePanel_Extension_Class 11 | 12 | #import 13 | 14 | @interface NSSavePanel (PKSavePanel) 15 | 16 | -(void)setInitialDirectory:(NSString*)path; 17 | 18 | -(void)setWindowTitle:(NSString*)string; 19 | 20 | @end 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /WineskinApp/NSMutableDictionary+Extension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableDictionary+Extension.h 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/07/16. 6 | // Copyright © 2016 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #ifndef NSMutableDictionary_Extension_Class 10 | #define NSMutableDictionary_Extension_Class 11 | 12 | #import 13 | 14 | @interface NSMutableDictionary (PKMutableDictionary) 15 | 16 | +(instancetype)mutableDictionaryWithContentsOfFile:(NSString*)filePath; 17 | 18 | @end 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /WineskinApp/NSUtilities.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSUtilities.h 3 | // Gamma Board 4 | // 5 | // Created by Vitor Marques de Miranda on 27/04/14. 6 | // Copyright (c) 2014 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSUtilities : NSObject 12 | 13 | +(id)getPlistItem:(NSString*)item fromWrapper:(NSString*)wrapper; 14 | +(id)getPlistItem:(NSString*)item fromPlist:(NSString*)plist fromWrapper:(NSString*)wrapper; 15 | 16 | +(NSComparisonResult)compareVersionString:(NSString*)PK1 withVersionString:(NSString*)PK2; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /WineskinApp/NSTask+Extension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSTask+Extension.h 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/02/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #ifndef NSTask_Extension_Class 10 | #define NSTask_Extension_Class 11 | 12 | #import 13 | 14 | @interface NSTask (PKTask) 15 | 16 | +(NSString*)runProgram:(NSString*)program atRunPath:(NSString*)path withFlags:(NSArray*)flags wait:(BOOL)wait; 17 | +(NSString*)runProgram:(NSString*)program withEnvironment:(NSDictionary*)env withFlags:(NSArray*)flags; 18 | 19 | @end 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /WineskinLauncher/Scripts/WineskinQuitScript: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | wineskinAppChoice=1 3 | cd "$(dirname "$0")/../../" 4 | CONTENTSFOLD="$PWD" 5 | export PATH="$CONTENTSFOLD/Frameworks/bin:$CONTENTSFOLD/Frameworks/wswine.bundle/bin:$PATH" 6 | export WINEPREFIX="$CONTENTSFOLD/Resources" 7 | 8 | ################ 9 | # You may make a custom program or script and replace this one if you want 10 | # if you replace this, the Option in Wineskin.app for trying to have programs 11 | # give a warning prompt at shut down will not function 12 | 13 | if [ "$wineskinAppChoice" == "1" ] 14 | then 15 | wineserver -k 16 | else 17 | cd "$CONTENTSFOLD/Resources/Scripts" 18 | wine WineskinQuit.exe 19 | fi 20 | -------------------------------------------------------------------------------- /WineskinApp/NSThread+Extension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSThread+Extension.h 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/02/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #ifndef NSThread_Extension_Class 10 | #define NSThread_Extension_Class 11 | 12 | #import 13 | 14 | dispatch_queue_t queueWithNameAndPriority(const char* name, long priority, BOOL concurrent); 15 | 16 | @interface NSThread (PKThread) 17 | 18 | +(void)dispatchQueueWithName:(const char*)name priority:(long)priority concurrent:(BOOL)concurrent withBlock:(void (^)(void))thread; 19 | +(void)dispatchBlockInMainQueue:(void (^)(void))thread; 20 | 21 | @end 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /WineskinApp/NSMutableDictionary+Extension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSExtensions.m 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/07/16. 6 | // Copyright © 2016 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import "NSMutableDictionary+Extension.h" 10 | 11 | @implementation NSMutableDictionary (PKMutableDictionary) 12 | 13 | +(instancetype)mutableDictionaryWithContentsOfFile:(NSString*)filePath 14 | { 15 | NSMutableDictionary *dictionary; 16 | 17 | @try 18 | { 19 | dictionary = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath]; 20 | } 21 | @catch (NSException *exception) 22 | { 23 | return nil; 24 | } 25 | 26 | return dictionary; 27 | } 28 | 29 | @end 30 | 31 | -------------------------------------------------------------------------------- /WineskinLauncher/NSPortDataLoader.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSPortDataLoader.h 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 07/03/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "NSPortManager.h" 12 | 13 | @interface NSPortDataLoader : NSObject 14 | 15 | +(NSString*)engineOfPortAtPath:(NSString*)path; 16 | 17 | +(BOOL)macDriverIsEnabledAtPort:(NSPortManager*)port; 18 | 19 | +(BOOL)useXQuartzIsEnabledAtPort:(NSPortManager*)port; 20 | 21 | +(void)getValuesFromResolutionString:(NSString*)originalResolutionString 22 | inBlock:(void (^)(BOOL virtualDesktop, NSString* resolution, int colors, int sleep))resolutionValues; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /WineskinApp/NSWineskinEngine.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSWineskinEngine.h 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 23/02/15. 6 | // Copyright (c) 2015 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSWineskinEngine : NSObject 12 | 13 | +(NSMutableArray*)getListOfLocalEngines; 14 | 15 | +(BOOL)isMacDriverCompatibleWithEngine:(NSString*)engineString; 16 | +(BOOL)isCsmtCompatibleWithEngine:(NSString*)engineString; 17 | +(BOOL)csmtUsesNewRegistryWithEngine:(NSString*)engineString; 18 | +(BOOL)isHighQualityModeCompatibleWithEngine:(NSString*)engineString; 19 | 20 | +(NSString*)mostRecentVersionOfEngine:(NSString*)engine; 21 | 22 | +(NSString*)localPathForEngine:(NSString*)engine; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /WineskinApp/NSSavePanel+Extension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSSavePanel+Extension.m 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/02/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import "NSSavePanel+Extension.h" 10 | 11 | #import "NSComputerInformation.h" 12 | 13 | @implementation NSSavePanel (PKSavePanel) 14 | 15 | -(void)setInitialDirectory:(NSString*)path 16 | { 17 | [self setDirectoryURL:[NSURL fileURLWithPath:path isDirectory:YES]]; 18 | } 19 | 20 | -(void)setWindowTitle:(NSString*)string 21 | { 22 | if ([self isKindOfClass:[NSOpenPanel class]]) 23 | { 24 | if (IS_SYSTEM_MAC_OS_10_11_OR_SUPERIOR) [self setMessage:string]; 25 | else [self setTitle:string]; 26 | } 27 | else 28 | { 29 | [self setTitle:string]; 30 | } 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /WineskinApp/CustomEXE.app/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleIconFile 8 | Wineskin.icns 9 | CFBundleInfoDictionaryVersion 10 | 1.0 11 | CFBundlePackageType 12 | APPL 13 | CFBundleShortVersionString 14 | Wineskin CustomEXE.app 15 | CFBundleVersion 16 | Wineskin CustomEXE.app 17 | NSPrincipalClass 18 | NSApplication 19 | CFBundleExecutable 20 | CustomEXE 21 | LSUIElement 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /WineskinApp/Command Line Wine Test: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "";echo "" 3 | cd "$(dirname "$0")" 4 | export PATH="$PWD:$PATH" 5 | cd "../../../Contents/Frameworks/wswine.bundle/bin" 6 | export PATH="$PWD:$PATH" 7 | cd "../lib" 8 | export WINESKIN_LIB_PATH_FOR_FALLBACK="$PWD:/opt/X11/lib:/opt/local/lib" 9 | cd "../../" 10 | export WINESKIN_LIB_PATH_FOR_FALLBACK="$WINESKIN_LIB_PATH_FOR_FALLBACK:$PWD:/usr/lib:/usr/libexec:/usr/lib/system:/usr/X11/lib:/usr/X11R6/lib" 11 | export PS1="\nWineskin Command Line Wine Test\n\h:\W \u$ " 12 | cd "$HOME" 13 | echo "This is for testing normal Wine use only." 14 | echo "" 15 | echo "Default Wineprefix is ~/.wine and NOT the wrapper!" 16 | echo "" 17 | echo "If you are using a stock Wine engine then this is" 18 | echo " just like using normal command line Wine" 19 | echo "" 20 | echo "Winetricks should also be available" 21 | echo "" 22 | /bin/bash 23 | -------------------------------------------------------------------------------- /WineskinApp/CustomEXE.app/Contents/_CodeSignature/CodeResources: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | files 6 | 7 | Resources/Wineskin.icns 8 | 9 | UBpxhSgh3LiMn1F2KOP/AQZqw3w= 10 | 11 | 12 | rules 13 | 14 | ^Resources/ 15 | 16 | ^Resources/.*\.lproj/ 17 | 18 | optional 19 | 20 | weight 21 | 1000 22 | 23 | ^Resources/.*\.lproj/locversion.plist$ 24 | 25 | omit 26 | 27 | weight 28 | 1100 29 | 30 | ^version.plist$ 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /WineskinApp/NSArray+Extension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+Extension.m 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 15/05/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import "NSArray+Extension.h" 10 | 11 | @implementation NSArray (PKArray) 12 | 13 | -(NSArray*)sortedDictionariesArrayWithKey:(NSString *)key orderingByValuesOrder:(NSArray*)value 14 | { 15 | return [self sortedArrayUsingComparator:^NSComparisonResult(NSDictionary* obj1, NSDictionary* obj2) 16 | { 17 | NSUInteger obj1ValueIndex = [value indexOfObject:obj1[key]]; 18 | NSUInteger obj2ValueIndex = [value indexOfObject:obj2[key]]; 19 | 20 | if (obj1ValueIndex > obj2ValueIndex) return NSOrderedDescending; 21 | if (obj1ValueIndex < obj2ValueIndex) return NSOrderedAscending; 22 | return NSOrderedSame; 23 | }]; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /WineskinApp/CustomEXE.app/Contents/MacOS/CustomEXE: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ################################################### 3 | # CustomEXE code for Wineskin wrappers 4 | # Made by doh123@doh123.com 5 | # 6 | # Version 6.0 7 | # 8 | # This code is Open Source and licensed under the 9 | # terms of the GNU Lesser General Public License. 10 | # If the License file is not with this script, the 11 | # full license can be read at the following URL 12 | # 13 | # http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html 14 | # 15 | # For Wineskin information, see the project website at 16 | # http://wineskin.urgesoftware.com 17 | # 18 | #################################################### 19 | # Set all variables 20 | CMACOSFOLD="$(dirname "$0")" 21 | MACOSFOLD="$CMACOSFOLD/../../../Contents/MacOS" 22 | cd "$MACOSFOLD" 23 | MACOSFOLD="$(echo "$PWD")" 24 | CEXENAME="$(basename "${CMACOSFOLD%/Contents/MacOS}")" 25 | 26 | # Launch wrapper 27 | "$MACOSFOLD/WineskinLauncher" "CustomEXE" "$CEXENAME" 28 | -------------------------------------------------------------------------------- /WineskinApp/NSData+Extension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+Extension.m 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/02/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import "NSData+Extension.h" 10 | 11 | @implementation NSData (PKData) 12 | +(NSData*)dataWithContentsOfURL:(NSURL *)url timeoutInterval:(long long int)timeoutInterval 13 | { 14 | NSURLRequest* request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData 15 | timeoutInterval:timeoutInterval]; 16 | 17 | NSError *error = nil; 18 | NSHTTPURLResponse *response = nil; 19 | NSData* stringData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; 20 | 21 | if (error || response.statusCode < 200 || response.statusCode >= 300 || !stringData) 22 | { 23 | return nil; 24 | } 25 | 26 | return stringData; 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /WineskinApp/NSPathUtilities.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSPathUtilities.h 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/02/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #ifndef NSPathUtilities_Class 10 | #define NSPathUtilities_Class 11 | 12 | #import 13 | 14 | @interface NSPathUtilities : NSObject 15 | 16 | +(NSString*)wineskinAppBinaryForPortAtPath:(NSString*)path; 17 | +(NSString*)wineskinLauncherBinForPortAtPath:(NSString*)path; 18 | 19 | +(NSString*)getMacPathForWindowsDrive:(char)driveLetter ofWrapper:(NSString*)file; 20 | +(NSString*)getMacPathForWindowsPath:(NSString*)exePath ofWrapper:(NSString*)file; 21 | +(NSString*)getWindowsPathForMacPath:(NSString*)exePath ofWrapper:(NSString*)file; 22 | 23 | +(NSString*)getFileNameOfWindowsPath:(NSString*)exePath; 24 | +(NSString*)getFlagsOfWindowsPath:(NSString*)exePath; 25 | 26 | +(BOOL)isPath:(NSString*)path compatibleWithStruct:(NSString*)structure; 27 | +(NSArray*)filesCompatibleWithStructure:(NSString*)appPath insideFolder:(NSString*)folder; 28 | 29 | @end 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /WineskinLauncher/NSPathUtilities.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSPathUtilities.h 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/02/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #ifndef NSPathUtilities_Class 10 | #define NSPathUtilities_Class 11 | 12 | #import 13 | 14 | @interface NSPathUtilities : NSObject 15 | 16 | +(NSString*)wineskinAppBinaryForPortAtPath:(NSString*)path; 17 | +(NSString*)wineskinLauncherBinForPortAtPath:(NSString*)path; 18 | 19 | +(NSString*)getMacPathForWindowsDrive:(char)driveLetter ofWrapper:(NSString*)file; 20 | +(NSString*)getMacPathForWindowsPath:(NSString*)exePath ofWrapper:(NSString*)file; 21 | +(NSString*)getWindowsPathForMacPath:(NSString*)exePath ofWrapper:(NSString*)file; 22 | 23 | +(NSString*)getFileNameOfWindowsPath:(NSString*)exePath; 24 | +(NSString*)getFlagsOfWindowsPath:(NSString*)exePath; 25 | 26 | +(BOOL)isPath:(NSString*)path compatibleWithStruct:(NSString*)structure; 27 | +(NSArray*)filesCompatibleWithStructure:(NSString*)appPath insideFolder:(NSString*)folder; 28 | 29 | @end 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /WineskinLauncher/WineskinLauncher-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | ${MACOSX_DEPLOYMENT_TARGET} 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /WineskinApp/NSThread+Extension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSThread+Extension.m 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/02/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import "NSThread+Extension.h" 10 | 11 | dispatch_queue_t queueWithNameAndPriority(const char* name, long priority, BOOL concurrent) 12 | { 13 | dispatch_queue_t dispatchQueue = dispatch_queue_create(name, concurrent ? DISPATCH_QUEUE_CONCURRENT : DISPATCH_QUEUE_SERIAL); 14 | dispatch_queue_t priorityQueue = dispatch_get_global_queue(priority, 0); 15 | dispatch_set_target_queue(dispatchQueue, priorityQueue); 16 | return dispatchQueue; 17 | } 18 | 19 | @implementation NSThread (PKThread) 20 | 21 | +(void)dispatchQueueWithName:(const char*)name priority:(long)priority concurrent:(BOOL)concurrent withBlock:(void (^)(void))thread 22 | { 23 | dispatch_async(queueWithNameAndPriority(name, priority, concurrent), ^ 24 | { 25 | thread(); 26 | }); 27 | } 28 | +(void)dispatchBlockInMainQueue:(void (^)(void))thread 29 | { 30 | dispatch_async(dispatch_get_main_queue(), ^ 31 | { 32 | thread(); 33 | }); 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /WineskinApp/NSFileManager+Extension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSFileManager+Extension.h 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/02/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #ifndef NSFileManager_Extension_Class 10 | #define NSFileManager_Extension_Class 11 | 12 | #import 13 | 14 | @interface NSFileManager (PKFileManager) 15 | 16 | -(BOOL)createSymbolicLinkAtPath:(NSString *)path withDestinationPath:(NSString *)destPath; 17 | -(BOOL)createDirectoryAtPath:(NSString*)path withIntermediateDirectories:(BOOL)interDirs; 18 | -(BOOL)moveItemAtPath:(NSString*)path toPath:(NSString*)destination; 19 | -(BOOL)copyItemAtPath:(NSString*)path toPath:(NSString*)destination; 20 | -(BOOL)removeItemAtPath:(NSString*)path; 21 | -(BOOL)directoryExistsAtPath:(NSString*)path; 22 | -(BOOL)regularFileExistsAtPath:(NSString*)path; 23 | -(NSArray*)contentsOfDirectoryAtPath:(NSString*)path; 24 | -(NSString*)destinationOfSymbolicLinkAtPath:(NSString *)path; 25 | 26 | -(unsigned long long int)sizeOfRegularFileAtPath:(NSString*)path; 27 | -(unsigned long long int)sizeOfDirectoryAtPath:(NSString*)path; 28 | 29 | @end 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /WineskinApp/NSPortDataLoader.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSPortDataLoader.h 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 07/03/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "NSPortManager.h" 12 | 13 | @interface NSPortDataLoader : NSObject 14 | 15 | +(NSString*)wineskinEngineOfPortAtPath:(NSString*)path; 16 | +(NSString*)engineOfPortAtPath:(NSString*)path; 17 | 18 | +(BOOL)macDriverIsEnabledAtPort:(NSString*)path withEngine:(NSString*)engine; 19 | +(BOOL)winedbgIsDisabledAtPort:(NSString*)path; 20 | +(BOOL)decorateWindowIsEnabledAtPort:(NSString*)path; 21 | +(BOOL)direct3DBoostIsEnabledAtPort:(NSString*)path; 22 | +(BOOL)retinaModeIsEnabledAtPort:(NSString*)path withEngine:(NSString*)engine; 23 | 24 | +(void)getValuesFromResolutionString:(NSString*)originalResolutionString 25 | inBlock:(void (^)(BOOL virtualDesktop, NSString* resolution, int colors, int sleep))resolutionValues; 26 | 27 | +(NSImage*)getIconImageAtPort:(NSString*)path; 28 | 29 | +(BOOL)isCloseNicelyEnabledAtPort:(NSPortManager*)port; 30 | 31 | +(NSString*)pathForMainExeAtPort:(NSString*)port; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /WineskinApp/Download.h: -------------------------------------------------------------------------------- 1 | // 2 | // Download.h 3 | // Gamma Board 4 | // 5 | // Created by Vitor Marques de Miranda on 26/04/14. 6 | // Copyright (c) 2014 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "NSProgressView.h" 11 | 12 | @interface Download : NSObject 13 | 14 | #if IS_LEGACY_VERSION == TRUE 15 | 16 | #else 17 | 18 | #endif 19 | 20 | { 21 | NSString* _downloadPath; 22 | NSError* _error; 23 | 24 | NSMutableData *_responseData; 25 | long long int _percentage; 26 | long long int _fullSize; 27 | 28 | BOOL _isSilence; 29 | BOOL _promptingErrors; 30 | 31 | NSDate* _downloadStartMoment; 32 | long long int _downloadedAtSecond; 33 | } 34 | 35 | @property (nonatomic, strong) NSCondition *condition; 36 | @property (nonatomic) BOOL connectionDidFinishLoading; 37 | 38 | @property (nonatomic, retain) NSTimer *monitorTimer; 39 | 40 | @property (nonatomic, strong) IBOutlet NSProgressView* progressWindow; 41 | 42 | -(BOOL)downloadFile:(NSURL*)file to:(NSString*)path inSilence:(BOOL)silence promptingErrors:(BOOL)errors; 43 | -(void)finishDownload; 44 | -(void)terminateDownload; 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /WineskinApp/NSProgressView.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSProgressView.h 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 19/04/16. 6 | // Copyright © 2016 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define PRIORITY_WRAPPER_CREATION 64 12 | #define PRIORITY_APPLICATION_UPLOAD 32 13 | #define PRIORITY_NEEDED_RESOURCES 16 14 | #define PRIORITY_REORDERING_APPS 8 15 | #define PRIORITY_LOAD_APP_DESCRIPTION 4 16 | #define PRIORITY_LOCAL_APPS_LISTING 2 17 | #define PRIORITY_SERVER_APPS_LISTING 1 18 | #define PRIORITY_DEFAULT 0 19 | 20 | @interface NSProgressView : NSView 21 | { 22 | IBOutlet NSTextField* progressStatus; 23 | IBOutlet NSTextField* progressSubtitle; 24 | IBOutlet NSProgressIndicator* progressBar; 25 | } 26 | 27 | @property (nonatomic) int dialogPriority; 28 | 29 | @property (nonatomic) IBOutlet NSView* mainBackground; 30 | 31 | -(BOOL)showWithPriority:(int)priority; 32 | -(BOOL)setMessage:(NSString*)status withPriority:(int)priority; 33 | -(BOOL)setSubtitle:(NSString*)status withPriority:(int)priority; 34 | -(BOOL)closeWithPriority:(int)priority; 35 | 36 | -(void)setCurrentValue:(long long int)value; 37 | 38 | -(void)setIndeterminate:(BOOL)need; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /WineskinApp/NSString+Extension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Extension.h 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/02/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #ifndef NSString_Extension_Class 10 | #define NSString_Extension_Class 11 | 12 | #import 13 | 14 | @interface NSString (PKString) 15 | 16 | -(BOOL)contains:(NSString*)string; 17 | -(BOOL)matchesWithRegex:(NSString*)regexString; 18 | 19 | +(NSString*)humanReadableSizeForBytes:(long long int)bytes withDecimalMeasureSystem:(BOOL)measure; 20 | +(NSString*)stringWithHexString:(NSString*)string; 21 | +(NSString*)stringByRemovingEvenCharsFromString:(NSString*)text; 22 | 23 | -(NSRange)rangeAfterString:(NSString*)before andBeforeString:(NSString*)after; 24 | -(NSString*)getFragmentAfter:(NSString*)before andBefore:(NSString*)after; 25 | 26 | -(int)initialIntValue; 27 | 28 | +(NSString*)stringWithContentsOfFile:(NSString*)file encoding:(NSStringEncoding)enc; 29 | +(NSString*)stringWithContentsOfURL:(NSURL *)url encoding:(NSStringEncoding)enc timeoutInterval:(long long int)timeoutInterval; 30 | 31 | -(BOOL)writeToFile:(NSString*)path atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc; 32 | 33 | -(BOOL)isAValidURL; 34 | 35 | @end 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /WineskinApp/NSAlert+Extension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSAlert+Extension.h 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/02/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #ifndef NSAlert_Extension_Class 10 | #define NSAlert_Extension_Class 11 | 12 | #import 13 | 14 | typedef enum NSAlertType 15 | { 16 | NSAlertTypeSuccess, 17 | NSAlertTypeWarning, 18 | NSAlertTypeWinetricks, 19 | NSAlertTypeError, 20 | NSAlertTypeCritical, 21 | NSAlertTypeCustom 22 | } NSAlertType; 23 | 24 | @interface NSImage (PKImageForAlert) 25 | @end 26 | 27 | @interface NSAlert (PKAlert) 28 | 29 | +(void)showAlertMessageWithException:(NSException*)exception; 30 | +(void)showAlertOfType:(NSAlertType)alertType withMessage:(NSString*)message; 31 | +(void)showAlertMessage:(NSString*)message withTitle:(NSString*)title withSettings:(void (^)(NSAlert* alert))optionsForAlert; 32 | 33 | +(BOOL)showBooleanAlertMessage:(NSString*)message withTitle:(NSString*)title withDefault:(BOOL)yesDefault; 34 | +(BOOL)showBooleanAlertOfType:(NSAlertType)alertType withMessage:(NSString*)message withDefault:(BOOL)yesDefault; 35 | 36 | +(NSString*)inputDialogWithTitle:(NSString*)prompt message:(NSString*)message defaultValue:(NSString*)defaultValue; 37 | 38 | @end 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /WineskinApp/Wineskin-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | Wineskin.icns 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 3.0.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 3.0.0 25 | LSApplicationCategoryType 26 | public.app-category.developer-tools 27 | LSMinimumSystemVersion 28 | ${MACOSX_DEPLOYMENT_TARGET} 29 | NSAppTransportSecurity 30 | 31 | NSAllowsArbitraryLoads 32 | 33 | 34 | NSMainNibFile 35 | MainMenu 36 | NSPrincipalClass 37 | NSApplication 38 | 39 | 40 | -------------------------------------------------------------------------------- /WineskinApp/CustomEXE.app/Contents/Info.plist.cexe: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | WineskinX11 9 | CFBundleIconFile 10 | Wineskin.icns 11 | CFBundleIdentifier 12 | Wineskin.Wineskin.prefs 13 | CFBundleInfoDictionaryVersion 14 | 1.0 15 | CFBundleName 16 | Wineskin 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | Wineskin 2.0 21 | CFBundleVersion 22 | Wineskin 2.0 23 | CSResourcesFileMapped 24 | 25 | use start.exe 26 | 27 | Use RandR 28 | 29 | Fullscreen 30 | 31 | Gamma Correction 32 | default 33 | NSMainNibFile 34 | main 35 | NSPrincipalClass 36 | X11Application 37 | Program Flags 38 | 39 | Program Name and Path 40 | nothing.exe 41 | Resolution 42 | novdx24sleep0 43 | 44 | 45 | -------------------------------------------------------------------------------- /Wineskin Winery/Wineskin_Winery-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | Winery.icns 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | Wineskin-Winery-2.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | Wineskin-Winery-2.0 25 | LSApplicationCategoryType 26 | public.app-category.developer-tools 27 | LSMinimumSystemVersion 28 | ${MACOSX_DEPLOYMENT_TARGET} 29 | LSMinimumSystemVersionByArchitecture 30 | 31 | i386 32 | 10.5 33 | x86_64 34 | 10.6 35 | 36 | NSAppTransportSecurity 37 | 38 | NSAllowsArbitraryLoads 39 | 40 | 41 | NSMainNibFile 42 | MainMenu 43 | NSPrincipalClass 44 | NSApplication 45 | 46 | 47 | -------------------------------------------------------------------------------- /WineskinApp/NSComputerInformation.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSComputerInformation.h 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/02/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #ifndef NSComputerInformation_Class 10 | #define NSComputerInformation_Class 11 | 12 | #define IS_SYSTEM_MAC_OS_10_7_OR_SUPERIOR [NSComputerInformation isSystemMacOsEqualOrSuperiorTo:@"10.7"] // Lion 13 | #define IS_SYSTEM_MAC_OS_10_8_OR_SUPERIOR [NSComputerInformation isSystemMacOsEqualOrSuperiorTo:@"10.8"] // Mountain Lion 14 | #define IS_SYSTEM_MAC_OS_10_9_OR_SUPERIOR [NSComputerInformation isSystemMacOsEqualOrSuperiorTo:@"10.9"] // Mavericks 15 | #define IS_SYSTEM_MAC_OS_10_10_OR_SUPERIOR [NSComputerInformation isSystemMacOsEqualOrSuperiorTo:@"10.10"] // Yosemite 16 | #define IS_SYSTEM_MAC_OS_10_11_OR_SUPERIOR [NSComputerInformation isSystemMacOsEqualOrSuperiorTo:@"10.11"] // El Capitan 17 | #define IS_SYSTEM_MAC_OS_10_12_OR_SUPERIOR [NSComputerInformation isSystemMacOsEqualOrSuperiorTo:@"10.12"] // Sierra 18 | #define IS_SYSTEM_MAC_OS_10_13_OR_SUPERIOR [NSComputerInformation isSystemMacOsEqualOrSuperiorTo:@"10.13"] // High Sierra 19 | #define IS_SYSTEM_MAC_OS_10_14_OR_SUPERIOR [NSComputerInformation isSystemMacOsEqualOrSuperiorTo:@"10.14"] // Mojave 20 | 21 | #import 22 | 23 | @interface NSComputerInformation : NSObject 24 | 25 | +(NSString*)macOsVersion; 26 | +(BOOL)isSystemMacOsEqualOrSuperiorTo:(NSString*)version; 27 | 28 | +(BOOL)isUsingFnKeysFunctions; 29 | 30 | +(BOOL)isComputerMacDriverCompatible; 31 | 32 | @end 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /WineskinApp/NSWineskinPortDataWriter.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSWineskinPortDataWriter.h 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 08/06/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "NSPortManager.h" 12 | 13 | @interface NSWineskinPortDataWriter : NSObject 14 | 15 | //Saving registry changes instructions 16 | +(BOOL)removeFromRegistryAppsThatRunAutomaticallyOnWrapperStartupAtPort:(NSPortManager*)port; 17 | 18 | //Misc instructions 19 | +(void)setAutomaticScreenOptions:(BOOL)automatic fullscreen:(BOOL)fullscreen virtualDesktop:(BOOL)virtualDesktop resolution:(NSString*)resolution colors:(int)colors sleep:(int)sleep atPort:(NSPortManager*)port; 20 | 21 | //Saving Data instructions 22 | +(BOOL)saveCloseSafely:(NSNumber*)closeSafely atPort:(NSPortManager*)port; 23 | +(BOOL)saveCopyrightsAtPort:(NSPortManager*)port; 24 | +(BOOL)saveWinedbg:(BOOL)Debugged atPort:(NSPortManager*)port; 25 | +(BOOL)saveMacDriver:(BOOL)macdriver atPort:(NSPortManager*)port; 26 | +(BOOL)saveDirect3DBoost:(BOOL)direct3DBoost withEngine:(NSString*)engine atPort:(NSPortManager*)port; 27 | +(BOOL)saveDecorateWindow:(BOOL)decorate atPort:(NSPortManager*)port; 28 | +(BOOL)saveRetinaMode:(BOOL)retinaModeOn withEngine:(NSString*)engine atPort:(NSPortManager*)port; 29 | 30 | +(BOOL)setMainExeName:(NSString*)name version:(NSString*)version icon:(NSImage*)icon path:(NSString*)path atPort:(NSPortManager*)port; 31 | +(BOOL)addCustomExeWithName:(NSString*)name version:(NSString*)version icon:(NSImage*)icon path:(NSString*)path atPortAtPath:(NSString*)portPath; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Wineskin Winery/NSWineskinEngine.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSWineskinEngine.h 3 | // Porting Kit 4 | // 5 | // Created by Vitor Marques de Miranda on 23/02/15. 6 | // Copyright (c) 2015 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef enum { 12 | NSWineskinEngineWine, 13 | NSWineskinEngineWineStaging, 14 | NSWineskinEngineCrossOver, 15 | NSWineskinEngineCrossOverGames, 16 | NSWineskinEngineOther 17 | } NSWineskinEngineType; 18 | 19 | @interface NSWineskinEngine : NSObject 20 | 21 | @property (nonatomic, strong) NSString* engineIdentifier; 22 | @property (nonatomic) int engineVersion; 23 | @property (nonatomic, strong) NSString* wineVersion; 24 | @property (nonatomic, strong) NSString* complement; 25 | @property (nonatomic) NSWineskinEngineType engineType; 26 | @property (nonatomic) BOOL is64Bit; 27 | 28 | +(NSMutableArray*)getListOfAvailableEngines; 29 | 30 | +(NSWineskinEngine*)wineskinEngineWithString:(NSString*)engineString; 31 | 32 | +(NSWineskinEngine*)wineskinEngineOfType:(NSWineskinEngineType)engineType is64Bit:(BOOL)is64Bit ofVersion:(NSString*)version withComplement:(NSString*)complement; 33 | 34 | -(NSString*)engineName; 35 | -(NSString*)localPath; 36 | -(BOOL)isCompatibleWithMacDriver; 37 | -(BOOL)isCompatibleWithCsmt; 38 | -(BOOL)csmtUsesNewRegistry; 39 | -(BOOL)isCompatibleWithHighQualityMode; 40 | -(BOOL)isCompatibleWith16Bit; 41 | 42 | -(BOOL)isCompatibleWithSteam; 43 | -(BOOL)isCompatibleWithOrigin; 44 | -(BOOL)isCompatibleWithUplay; 45 | -(BOOL)isCompatibleWithGOGGalaxy; 46 | 47 | +(NSString*)localPathForEngine:(NSString*)engine; 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /WineskinLauncher/WineStart.h: -------------------------------------------------------------------------------- 1 | // 2 | // WineStart.h 3 | // WineskinLauncher 4 | // Data for starting Wine 5 | // Created by doh123 on 3/20/14. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface WineStart : NSObject 12 | { 13 | NSArray *filesToRun; 14 | NSString *wineRunLocation; 15 | NSString *programFlags; 16 | NSString *vdResolution; 17 | NSString *cliCustomCommands; 18 | BOOL runWithStartExe; 19 | BOOL nonStandardRun; 20 | BOOL openingFiles; 21 | NSString *wssCommand; 22 | NSString *uLimitNumber; 23 | NSString *wineDebugLine; 24 | NSArray *winetricksCommands; 25 | NSString *wineRunFile; 26 | } 27 | - (NSArray*)getFilesToRun; 28 | - (void)setFilesToRun:(NSArray*)input; 29 | - (NSString*)getWineRunLocation; 30 | - (void)setWineRunLocation:(NSString*)input; 31 | - (NSString*)getProgramFlags; 32 | - (void)setProgramFlags:(NSString*)input; 33 | - (NSString*)getVdResolution; 34 | - (void)setVdResolution:(NSString*)input; 35 | - (NSString*)getCliCustomCommands; 36 | - (void)setCliCustomCommands:(NSString*)input; 37 | - (BOOL)isRunWithStartExe; 38 | - (void)setRunWithStartExe:(BOOL)input; 39 | - (BOOL)isNonStandardRun; 40 | - (void)setNonStandardRun:(BOOL)input; 41 | - (BOOL)isOpeningFiles; 42 | - (void)setOpeningFiles:(BOOL)input; 43 | - (NSString*)getWssCommand; 44 | - (void)setWssCommand:(NSString*)input; 45 | - (NSString*)getULimitNumber; 46 | - (void)setULimitNumber:(NSString*)input; 47 | - (NSString*)getWineDebugLine; 48 | - (void)setWineDebugLine:(NSString*)input; 49 | - (NSArray*)getWinetricksCommands; 50 | - (void)setWinetricksCommands:(NSArray*)input; 51 | - (NSString*)getWineRunFile; 52 | - (void)setWineRunFile:(NSString*)input; 53 | @end 54 | -------------------------------------------------------------------------------- /WineskinApp/Wineskin.xcodeproj/project.xcworkspace/xcshareddata/Wineskin.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | DA31DD74-1A3E-418D-AD37-48548AA402A4 9 | IDESourceControlProjectName 10 | Wineskin 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 70588266-B22C-4900-BDC7-ED8B48BB01B0 14 | ssh://git.code.sf.net/p/wineskin/code 15 | 16 | IDESourceControlProjectPath 17 | WineskinApp/Wineskin.xcodeproj/project.xcworkspace 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 70588266-B22C-4900-BDC7-ED8B48BB01B0 21 | ../../.. 22 | 23 | IDESourceControlProjectURL 24 | ssh://git.code.sf.net/p/wineskin/code 25 | IDESourceControlProjectVersion 26 | 110 27 | IDESourceControlProjectWCCIdentifier 28 | 70588266-B22C-4900-BDC7-ED8B48BB01B0 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 70588266-B22C-4900-BDC7-ED8B48BB01B0 36 | IDESourceControlWCCName 37 | wineskin 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Wineskin Winery/Wineskin Winery.xcodeproj/project.xcworkspace/xcshareddata/Wineskin Winery.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 53229057-3195-4635-A47A-E9CB24647BA7 9 | IDESourceControlProjectName 10 | Wineskin Winery 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 2E2CA57C-0E08-4A03-A84E-8F34CD287B0D 14 | ssh://git.code.sf.net/p/wineskin/code 15 | 16 | IDESourceControlProjectPath 17 | Wineskin Winery/Wineskin Winery.xcodeproj/project.xcworkspace 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 2E2CA57C-0E08-4A03-A84E-8F34CD287B0D 21 | ../../.. 22 | 23 | IDESourceControlProjectURL 24 | ssh://git.code.sf.net/p/wineskin/code 25 | IDESourceControlProjectVersion 26 | 110 27 | IDESourceControlProjectWCCIdentifier 28 | 2E2CA57C-0E08-4A03-A84E-8F34CD287B0D 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 2E2CA57C-0E08-4A03-A84E-8F34CD287B0D 36 | IDESourceControlWCCName 37 | wineskin 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /WineskinLauncher/WineskinLauncher.xcodeproj/project.xcworkspace/xcshareddata/WineskinLauncher.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 0DAC104B-6906-4CA1-AD5C-CC38AF1EA8A2 9 | IDESourceControlProjectName 10 | WineskinLauncher 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 70588266-B22C-4900-BDC7-ED8B48BB01B0 14 | ssh://git.code.sf.net/p/wineskin/code 15 | 16 | IDESourceControlProjectPath 17 | WineskinLauncher/WineskinLauncher.xcodeproj/project.xcworkspace 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 70588266-B22C-4900-BDC7-ED8B48BB01B0 21 | ../../.. 22 | 23 | IDESourceControlProjectURL 24 | ssh://git.code.sf.net/p/wineskin/code 25 | IDESourceControlProjectVersion 26 | 110 27 | IDESourceControlProjectWCCIdentifier 28 | 70588266-B22C-4900-BDC7-ED8B48BB01B0 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 70588266-B22C-4900-BDC7-ED8B48BB01B0 36 | IDESourceControlWCCName 37 | wineskin 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /WineskinApp/Wineskin.xcodeproj/project.xcworkspace/xcshareddata/Wineskin.xcscmblueprint: -------------------------------------------------------------------------------- 1 | { 2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "121A670901F416B984980294338E127021538EA0", 3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { 4 | 5 | }, 6 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { 7 | "121A670901F416B984980294338E127021538EA0" : 0, 8 | "55EE576BCD41C77EE044492E6FAD2FDDF306522D" : 9223372036854775807 9 | }, 10 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "DA31DD74-1A3E-418D-AD37-48548AA402A4", 11 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { 12 | "121A670901F416B984980294338E127021538EA0" : "wineskin-code\/", 13 | "55EE576BCD41C77EE044492E6FAD2FDDF306522D" : "..\/..\/Porting%20Kit" 14 | }, 15 | "DVTSourceControlWorkspaceBlueprintNameKey" : "Wineskin", 16 | "DVTSourceControlWorkspaceBlueprintVersion" : 204, 17 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "WineskinApp\/Wineskin.xcodeproj", 18 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ 19 | { 20 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/git.code.sf.net\/p\/wineskin\/code", 21 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 22 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "121A670901F416B984980294338E127021538EA0" 23 | }, 24 | { 25 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/bitbucket.org\/VitorMMiranda\/portingkit.git", 26 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 27 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "55EE576BCD41C77EE044492E6FAD2FDDF306522D" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /WineskinApp/NSWebUtilities.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSWebUtilities.m 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/02/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import "NSWebUtilities.h" 10 | #import 11 | 12 | #import "NSString+Extension.h" 13 | 14 | #define SECONDS_IN_MINUTE 60 15 | #define MINUTES_IN_HOUR 60 16 | #define HOURS_IN_DAY 24 17 | 18 | #define WEBSITE_AVAILABLE_VERIFICATION_TIME_OUT 5.0 19 | 20 | @implementation NSWebUtilities 21 | 22 | +(NSString*)timeNeededToDownload:(long long int)needed withSpeed:(long long int)speed 23 | { 24 | NSString* result = @""; 25 | 26 | if (speed < 1) result = @" ∞"; 27 | else 28 | { 29 | int seconds, minutes, hours, days; 30 | needed = needed/speed; 31 | 32 | seconds = needed % SECONDS_IN_MINUTE; 33 | needed /= SECONDS_IN_MINUTE; 34 | if (seconds > 0 || (seconds==0 && needed==0)) result = [NSString stringWithFormat:@" %ds",seconds]; 35 | 36 | if (needed) 37 | { 38 | minutes = needed % MINUTES_IN_HOUR; 39 | needed /= MINUTES_IN_HOUR; 40 | if (minutes > 0) result = [NSString stringWithFormat:@" %dm%@",minutes,result]; 41 | 42 | if (needed) 43 | { 44 | hours = needed % HOURS_IN_DAY; 45 | needed /= HOURS_IN_DAY; 46 | if (hours > 0) result = [NSString stringWithFormat:@" %dh%@",hours,result]; 47 | 48 | if (needed) 49 | { 50 | days = (int)needed; 51 | result = [NSString stringWithFormat:@" %dd%@",days,result]; 52 | } 53 | } 54 | } 55 | } 56 | 57 | return [NSString stringWithFormat:NSLocalizedString(@"Time left:%@",nil),result]; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /WineskinApp/NSComputerInformation.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSComputerInformation.m 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/02/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import "NSComputerInformation.h" 10 | 11 | #import "NSUtilities.h" 12 | 13 | #import "NSTask+Extension.h" 14 | #import "NSArray+Extension.h" 15 | #import "NSString+Extension.h" 16 | 17 | #define STAFF_GROUP_MEMBER_CODE @"20" 18 | 19 | @implementation NSComputerInformation 20 | 21 | static NSString* _macOsVersion; 22 | 23 | +(NSString*)macOsVersion 24 | { 25 | @synchronized([self class]) 26 | { 27 | if (_macOsVersion) 28 | { 29 | return _macOsVersion; 30 | } 31 | 32 | NSString* plistFile = @"/System/Library/CoreServices/SystemVersion.plist"; 33 | NSDictionary *systemVersionDictionary = [NSDictionary dictionaryWithContentsOfFile:plistFile]; 34 | NSString* version = systemVersionDictionary[@"ProductVersion"]; 35 | 36 | if (!version) 37 | { 38 | _macOsVersion = [NSTask runProgram:@"sw_vers" atRunPath:nil withFlags:@[@"-productVersion"] wait:YES]; 39 | } 40 | 41 | if (!version) 42 | { 43 | version = @""; 44 | } 45 | 46 | _macOsVersion = version; 47 | 48 | return _macOsVersion; 49 | } 50 | return nil; 51 | } 52 | +(BOOL)isSystemMacOsEqualOrSuperiorTo:(NSString*)version 53 | { 54 | return [NSUtilities compareVersionString:version withVersionString:self.macOsVersion] != NSOrderedAscending; 55 | } 56 | 57 | +(BOOL)isUsingFnKeysFunctions 58 | { 59 | NSString* appReturn = [NSTask runProgram:@"defaults" atRunPath:nil 60 | withFlags:@[@"read",@"-g",@"com.apple.keyboard.fnState",@"-bool"] wait:YES]; 61 | return [appReturn boolValue]; 62 | } 63 | 64 | +(BOOL)isComputerMacDriverCompatible 65 | { 66 | // If the version is 10.7.5 or superior, it will work 67 | return [NSComputerInformation isSystemMacOsEqualOrSuperiorTo:@"10.7.5"]; 68 | } 69 | 70 | @end 71 | 72 | -------------------------------------------------------------------------------- /WineskinApp/NSPortManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSPortManager.h 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 01/09/16. 6 | // Copyright © 2016 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define SYSTEM_REG @"system" 12 | #define USER_REG @"user" 13 | 14 | @interface NSPortManager : NSObject 15 | 16 | @property (nonatomic) BOOL isCustomEXE; 17 | @property (nonatomic, strong) NSString* path; 18 | @property (nonatomic, strong) NSMutableDictionary* plist; 19 | 20 | +(NSPortManager*)managerWithPath:(NSString*)path; 21 | +(NSPortManager*)managerWithCustomExePath:(NSString*)path; 22 | 23 | -(void)setIconWithImage:(NSImage*)sourceImage; 24 | 25 | -(NSString*)runWithArguments:(NSArray*)args; 26 | -(NSString*)installWinetrick:(NSString*)winetrick; 27 | 28 | -(NSString*)runEXE:(NSString*)installerFile withFlags:(NSString*)flags; 29 | 30 | -(id)plistObjectForKey:(NSString*)item; 31 | -(void)setPlistObject:(id)object forKey:(NSString*)item; 32 | -(void)synchronizePlist; 33 | 34 | -(void)addToPortCreationLog:(NSString*)newLogs; 35 | 36 | -(BOOL)isWinetrickAvailableForInstalling:(NSString*)winetrickName; 37 | 38 | -(NSString*)completeWindowsPath:(NSString*)windowsPath; 39 | 40 | -(NSString*)programFilesPathFor64bitsApplication:(BOOL)is64bits; 41 | 42 | -(NSString*)getPathForRegistryFile:(NSString*)reg; 43 | -(BOOL)addRegistry:(NSString*)lines fromRegistryFileNamed:(NSString*)reg; 44 | -(BOOL)deleteRegistry:(NSString*)line fromRegistryFileNamed:(NSString*)reg; 45 | -(NSArray*)getRegistriesWithGramar:(NSString*)gramar fromRegistryFileNamed:(NSString*)reg; 46 | -(NSString*)getRegistryEntry:(NSString*)line fromRegistryFileNamed:(NSString*)reg; 47 | 48 | +(NSString*)getRegistryEntry:(NSString*)line fromRegistryString:(NSString*)text; 49 | 50 | -(void)setValue:(NSString*)value forKey:(NSString*)key atRegistryEntryString:(NSMutableString*)registry; 51 | -(void)setValues:(NSDictionary*)values atRegistryEntryString:(NSMutableString*)registry; 52 | -(BOOL)setValues:(NSDictionary*)values forEntry:(NSString*)registryEntry atRegistryFileNamed:(NSString*)regFileName; 53 | 54 | +(NSString*)getStringValueForKey:(NSString*)value fromRegistryString:(NSString*)registry; 55 | +(NSString*)getValueForKey:(NSString*)value fromRegistryString:(NSString*)registry; 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /WineskinApp/NSUtilities.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSUtilities.m 3 | // Gamma Board 4 | // 5 | // Created by Vitor Marques de Miranda on 27/04/14. 6 | // Copyright (c) 2014 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import "NSUtilities.h" 10 | 11 | #import "NSTask+Extension.h" 12 | #import "NSString+Extension.h" 13 | #import "NSThread+Extension.h" 14 | #import "NSFileManager+Extension.h" 15 | #import "NSMutableDictionary+Extension.h" 16 | 17 | #define SOURCE_DIALOG_VIEW_WIDTH_MODIFIER_LIMIT 3 18 | #define SOURCE_DIALOG_VIEW_WIDTH_MODIFIER_LESS -20 19 | #define SOURCE_DIALOG_VIEW_WIDTH_MODIFIER_MORE 30 20 | 21 | #define SOURCE_DIALOG_BUTTONS_LATERAL 0 22 | #define SOURCE_DIALOG_BUTTONS_SPACE 10 23 | #define SOURCE_DIALOG_ICON_WIDTH 80 24 | #define SOURCE_DIALOG_ICON_HEIGHT 80 25 | #define SOURCE_DIALOG_ICON_BORDER_WITH_TEXT 30 26 | #define SOURCE_DIALOG_ICON_BORDER 10 27 | #define SOURCE_DIALOG_ICON_IMAGE_BORDER 10 28 | #define SOURCE_DIALOG_ICONS_AT_X 3 29 | 30 | @implementation NSUtilities 31 | 32 | static NSAlert* _alertSources; 33 | 34 | //Plist functions 35 | +(id)getPlistItem:(NSString*)item fromWrapper:(NSString*)wrapper 36 | { 37 | return [self getPlistItem:item fromPlist:PLIST_PATH_WINESKIN_WRAPPER fromWrapper:wrapper]; 38 | } 39 | +(id)getPlistItem:(NSString*)item fromPlist:(NSString*)plist fromWrapper:(NSString*)wrapper 40 | { 41 | return [[NSMutableDictionary mutableDictionaryWithContentsOfFile:[NSString stringWithFormat:@"%@%@",wrapper,plist]] objectForKey:item]; 42 | } 43 | 44 | // NSOrderedSame: They are the same 45 | // NSOrderedAscending: The one in the left is bigger 46 | // NSOrderedDescending: The one in the right is bigger 47 | +(NSComparisonResult)compareVersionString:(NSString*)PK1 withVersionString:(NSString*)PK2 48 | { 49 | NSArray* PKArray1 = [PK1 componentsSeparatedByString:@"."]; 50 | NSArray* PKArray2 = [PK2 componentsSeparatedByString:@"."]; 51 | 52 | for (int x = 0; x < PKArray1.count && x < PKArray2.count; x++) 53 | { 54 | if ([PKArray1[x] initialIntValue] < [PKArray2[x] initialIntValue]) return NSOrderedDescending; 55 | if ([PKArray1[x] initialIntValue] > [PKArray2[x] initialIntValue]) return NSOrderedAscending; 56 | } 57 | 58 | if (PKArray1.count < PKArray2.count) return NSOrderedDescending; 59 | if (PKArray1.count > PKArray2.count) return NSOrderedAscending; 60 | 61 | if (PK1.length > PK2.length) return NSOrderedAscending; 62 | if (PK1.length < PK2.length) return NSOrderedDescending; 63 | 64 | return NSOrderedSame; 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /WineskinLauncher/NSPortManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSPortManager.h 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 01/09/16. 6 | // Copyright © 2016 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define SYSTEM_REG @"system" 12 | #define USER_REG @"user" 13 | #define USERDEF_REG @"userdef" 14 | 15 | @interface NSPortManager : NSObject 16 | { 17 | NSFileHandle *portTrackerFileHandle; 18 | NSString* portPathBackup; 19 | } 20 | 21 | typedef enum { 22 | NSPortManagerTypeWrapper, 23 | NSPortManagerTypeCustomExe 24 | } NSPortManagerType; 25 | 26 | @property (nonatomic) NSPortManagerType type; 27 | @property (nonatomic, strong) NSMutableDictionary* plist; 28 | 29 | +(NSPortManager*)managerForWrapperAtPath:(NSString*)path; 30 | +(NSPortManager*)managerForCustomExeAtPath:(NSString*)path; 31 | 32 | +(NSPortManager*)managerForPortAtPath:(NSString*)path;; 33 | 34 | -(BOOL)isWrapper; 35 | -(BOOL)isCustomEXE; 36 | 37 | -(NSString*)path; 38 | 39 | -(BOOL)mainExeHasInvalidPath; 40 | 41 | -(NSString*)runWithArguments:(NSArray*)args forcingLogReturn:(BOOL)returnLog; 42 | -(NSString*)installWinetrick:(NSString*)winetrick; 43 | 44 | -(NSString*)runEXE:(NSString*)installerFile withFlags:(NSString*)flags; 45 | 46 | -(id)plistObjectForKey:(NSString*)item; 47 | -(void)setPlistObject:(id)object forKey:(NSString*)item; 48 | -(BOOL)synchronizePlist; 49 | 50 | -(BOOL)isWinetrickAvailableForInstalling:(NSString*)winetrickName; 51 | 52 | -(NSString*)completeWindowsPath:(NSString*)windowsPath; 53 | 54 | -(NSString*)programFilesPathFor64bitsApplication:(BOOL)is64bits; 55 | 56 | -(NSString*)getPathForRegistryFile:(NSString*)reg; 57 | -(void)addRegistry:(NSString*)lines fromRegistryFileNamed:(NSString*)reg; 58 | -(void)deleteRegistry:(NSString*)line fromRegistryFileNamed:(NSString*)reg; 59 | -(NSArray*)getRegistriesWithGramar:(NSString*)gramar fromRegistryFileNamed:(NSString*)reg; 60 | -(NSString*)getRegistryEntry:(NSString*)line fromRegistryFileNamed:(NSString*)reg; 61 | 62 | +(NSString*)getRegistryEntry:(NSString*)line fromRegistryString:(NSString*)text; 63 | 64 | -(void)setValue:(NSString*)value forKey:(NSString*)key atRegistryEntryString:(NSMutableString*)registry; 65 | -(void)setValues:(NSDictionary*)values atRegistryEntryString:(NSMutableString*)registry; 66 | -(void)setValues:(NSDictionary*)values forEntry:(NSString*)registryEntry atRegistryFileNamed:(NSString*)regFileName; 67 | 68 | +(NSString*)getStringValueForKey:(NSString*)value fromRegistryString:(NSString*)registry; 69 | +(NSString*)getValueForKey:(NSString*)value fromRegistryString:(NSString*)registry; 70 | +(NSArray*)getKeysFromRegistryString:(NSString*)registry; 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /WineskinLauncher/WineStart.m: -------------------------------------------------------------------------------- 1 | // 2 | // WineStart.m 3 | // WineskinLauncher 4 | // 5 | // Created by doh123 on 3/20/14. 6 | // 7 | // 8 | 9 | #import "WineStart.h" 10 | 11 | @implementation WineStart 12 | 13 | - (NSArray*)getFilesToRun 14 | { 15 | return [NSArray arrayWithArray:filesToRun]; 16 | } 17 | 18 | - (void)setFilesToRun:(NSArray*)input 19 | { 20 | filesToRun = [NSArray arrayWithArray:input]; 21 | } 22 | - (NSString*)getWineRunLocation 23 | { 24 | return [wineRunLocation copy]; 25 | } 26 | 27 | - (void)setWineRunLocation:(NSString*)input 28 | { 29 | wineRunLocation = [input copy]; 30 | } 31 | - (NSString*)getProgramFlags 32 | { 33 | return [programFlags copy]; 34 | } 35 | 36 | - (void)setProgramFlags:(NSString*)input 37 | { 38 | programFlags = [input copy]; 39 | } 40 | - (NSString*)getVdResolution 41 | { 42 | return [vdResolution copy]; 43 | } 44 | 45 | - (void)setVdResolution:(NSString*)input 46 | { 47 | vdResolution = [input copy]; 48 | } 49 | - (NSString*)getCliCustomCommands 50 | { 51 | return [cliCustomCommands copy]; 52 | } 53 | 54 | - (void)setCliCustomCommands:(NSString*)input 55 | { 56 | cliCustomCommands = [input copy]; 57 | } 58 | - (BOOL)isRunWithStartExe 59 | { 60 | return runWithStartExe; 61 | } 62 | 63 | - (void)setRunWithStartExe:(BOOL)input 64 | { 65 | runWithStartExe = input; 66 | } 67 | - (BOOL)isNonStandardRun 68 | { 69 | return nonStandardRun; 70 | } 71 | 72 | - (void)setNonStandardRun:(BOOL)input 73 | { 74 | nonStandardRun = input; 75 | } 76 | - (BOOL)isOpeningFiles 77 | { 78 | return openingFiles; 79 | } 80 | 81 | - (void)setOpeningFiles:(BOOL)input 82 | { 83 | openingFiles = input; 84 | } 85 | - (NSString*)getWssCommand 86 | { 87 | return [wssCommand copy]; 88 | } 89 | 90 | - (void)setWssCommand:(NSString*)input 91 | { 92 | wssCommand = [input copy]; 93 | } 94 | - (NSString*)getULimitNumber 95 | { 96 | return [uLimitNumber copy]; 97 | } 98 | 99 | - (void)setULimitNumber:(NSString*)input 100 | { 101 | uLimitNumber = [input copy]; 102 | } 103 | - (NSString*)getWineDebugLine 104 | { 105 | return [wineDebugLine copy]; 106 | } 107 | 108 | - (void)setWineDebugLine:(NSString*)input 109 | { 110 | wineDebugLine = [input copy]; 111 | } 112 | - (NSArray*)getWinetricksCommands 113 | { 114 | return [NSArray arrayWithArray:winetricksCommands]; 115 | } 116 | 117 | - (void)setWinetricksCommands:(NSArray*)input 118 | { 119 | winetricksCommands = [NSArray arrayWithArray:input]; 120 | } 121 | - (NSString*)getWineRunFile 122 | { 123 | return [wineRunFile copy]; 124 | } 125 | 126 | - (void)setWineRunFile:(NSString*)input 127 | { 128 | wineRunFile = [input copy]; 129 | } 130 | @end 131 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #Folder view settings 2 | .DS_Store 3 | 4 | #Xcode3 build folders 5 | build/ 6 | 7 | #XCode4 build folders 8 | DerivedData/ 9 | 10 | #user-specific project settings: breakpoints, custom executables, etc.; files are inside the .xcodeproj bundle 11 | *.mode1v3 12 | 13 | #user-specific xcode workspace settings; files are inside the .xcodeproj bundle 14 | *.pbxuser 15 | 16 | #user-specific xcode data 17 | *.xcuserdatad/ 18 | 19 | #some merge tools or editors generate .bak files to store old versions backups 20 | *.bak 21 | 22 | #some merge tools or editors generate .orig files to store old versions backups 23 | *.orig 24 | 25 | #some merge tools or editors generate ~ files to store old versions backups 26 | *~ 27 | 28 | #ignore resource forks in non-HFS+ filesystems 29 | ._* 30 | 31 | #stuff that appears in non-HFS+ filesystems accessed through afp:// shares 32 | .Apple* 33 | 34 | #nasty windows xp thumbnail cache 35 | Thumbs.db 36 | 37 | #vim/MacVim temporary swap files 38 | .*.swp 39 | 40 | # Xcode 41 | # 42 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 43 | 44 | ## Build generated 45 | build/ 46 | DerivedData/ 47 | 48 | ## Various settings 49 | *.pbxuser 50 | !default.pbxuser 51 | *.mode1v3 52 | !default.mode1v3 53 | *.mode2v3 54 | !default.mode2v3 55 | *.perspectivev3 56 | !default.perspectivev3 57 | xcuserdata/ 58 | 59 | ## Other 60 | *.moved-aside 61 | *.xccheckout 62 | *.xcscmblueprint 63 | 64 | ## Obj-C/Swift specific 65 | *.hmap 66 | *.ipa 67 | *.dSYM.zip 68 | *.dSYM 69 | 70 | # CocoaPods 71 | # 72 | # We recommend against adding the Pods directory to your .gitignore. However 73 | # you should judge for yourself, the pros and cons are mentioned at: 74 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 75 | # 76 | # Pods/ 77 | 78 | # Carthage 79 | # 80 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 81 | 82 | Carthage/Checkouts 83 | Carthage/Build 84 | 85 | # fastlane 86 | # 87 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 88 | # screenshots whenever they are needed. 89 | # For more information about the recommended setup visit: 90 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 91 | 92 | fastlane/report.xml 93 | fastlane/Preview.html 94 | fastlane/screenshots 95 | fastlane/test_output 96 | 97 | # Code Injection 98 | # 99 | # After new code Injection tools there's a generated folder /iOSInjectionProject 100 | # https://github.com/johnno1962/injectionforxcode 101 | 102 | iOSInjectionProject/ 103 | 104 | # Avoiding replacement 105 | README.md 106 | -------------------------------------------------------------------------------- /WineskinApp/NSProgressView.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSProgressView.m 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 19/04/16. 6 | // Copyright © 2016 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import "NSProgressView.h" 10 | 11 | #import "NSThread+Extension.h" 12 | 13 | @implementation NSProgressView 14 | 15 | -(void)awakeFromNib 16 | { 17 | self.dialogPriority = PRIORITY_DEFAULT; 18 | 19 | [progressBar setMaxValue:PROGRESS_VIEW_BAR_PRECISION]; 20 | } 21 | 22 | -(BOOL)showWithPriority:(int)priority 23 | { 24 | [NSThread dispatchBlockInMainQueue:^ 25 | { 26 | BOOL showDialog = priority >= self.dialogPriority; 27 | 28 | if ((self.dialogPriority & priority) == 0 && priority != 0) self.dialogPriority += priority; 29 | 30 | if (showDialog) 31 | { 32 | [self setSubtitle:@"" withPriority:priority]; 33 | [self setIndeterminate:YES]; 34 | 35 | // Set view height to 111 36 | //[self setHeight:PROGRESS_VIEW_HEIGHT]; 37 | } 38 | }]; 39 | 40 | return TRUE; 41 | } 42 | -(BOOL)setMessage:(NSString*)status withPriority:(int)priority 43 | { 44 | NSDebugLog(@"%@",status); 45 | 46 | if (priority < self.dialogPriority) return FALSE; 47 | 48 | [NSThread dispatchBlockInMainQueue:^ 49 | { 50 | [progressStatus setStringValue:status ? status : @""]; 51 | }]; 52 | 53 | return TRUE; 54 | } 55 | -(BOOL)setSubtitle:(NSString*)status withPriority:(int)priority 56 | { 57 | if (priority < self.dialogPriority) return FALSE; 58 | 59 | [NSThread dispatchBlockInMainQueue:^ 60 | { 61 | [progressSubtitle setStringValue:status ? status : @""]; 62 | }]; 63 | 64 | return TRUE; 65 | } 66 | -(BOOL)closeWithPriority:(int)priority 67 | { 68 | [NSThread dispatchBlockInMainQueue:^ 69 | { 70 | BOOL hideDialog = (self.dialogPriority - priority) == 0; 71 | 72 | if ((self.dialogPriority & priority) != 0 && priority != 0) self.dialogPriority -= priority; 73 | 74 | if (hideDialog) 75 | { 76 | // Set view height to 0 77 | //[self setHeight:0]; 78 | } 79 | }]; 80 | return TRUE; 81 | } 82 | 83 | -(void)setCurrentValue:(long long int)value 84 | { 85 | [NSThread dispatchBlockInMainQueue:^ 86 | { 87 | [progressBar setIndeterminate:NO]; 88 | [progressBar setDoubleValue:[[NSNumber numberWithLongLong:value] doubleValue]]; 89 | 90 | #if IS_LEGACY_VERSION == TRUE 91 | [progressBar setNeedsDisplay:YES]; 92 | #endif 93 | }]; 94 | } 95 | 96 | -(void)setIndeterminate:(BOOL)need 97 | { 98 | [NSThread dispatchBlockInMainQueue:^ 99 | { 100 | [progressBar setIndeterminate:need]; 101 | }]; 102 | } 103 | 104 | @end 105 | -------------------------------------------------------------------------------- /WineskinApp/Wineskin.xcodeproj/xcshareddata/xcschemes/Wineskin.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 56 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 75 | 77 | 83 | 84 | 85 | 86 | 88 | 89 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /Wineskin Winery/Wineskin Winery.xcodeproj/xcshareddata/xcschemes/Wineskin Winery.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /WineskinLauncher/WineskinLauncher.xcodeproj/xcshareddata/xcschemes/WineskinLauncher.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /WineskinApp/NSDropIconView.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSCImageView.m 3 | // Porting Center 4 | // 5 | // Created by Vitor Marques de Miranda. 6 | // Copyright 2014 UFRJ. All rights reserved. 7 | // 8 | 9 | #import "NSDropIconView.h" 10 | 11 | #import "NSData+Extension.h" 12 | #import "NSTask+Extension.h" 13 | #import "NSImage+Extension.h" 14 | #import "NSString+Extension.h" 15 | #import "NSFileManager+Extension.h" 16 | 17 | #define MAX_ICON_SIZE 512 18 | 19 | @implementation NSDropIconView 20 | 21 | NSString* IconPath = @""; 22 | 23 | -(NSDragOperation)draggingEntered:(id )sender 24 | { 25 | if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) == NSDragOperationGeneric) 26 | return NSDragOperationGeneric; 27 | return NSDragOperationNone; 28 | } 29 | -(void)draggingExited:(id )sender 30 | { 31 | } 32 | -(NSDragOperation)draggingUpdated:(id)sender 33 | { 34 | return NSDragOperationCopy; 35 | } 36 | -(BOOL)performDragOperation:(id )sender 37 | { 38 | NSPasteboard *paste = [sender draggingPasteboard]; 39 | NSArray *fileArray = [paste propertyListForType:@"NSFilenamesPboardType"]; 40 | 41 | IconPath = [[fileArray firstObject] copy]; 42 | if (!IconPath) IconPath = [NSString stringWithFormat:@"%@",[NSURL URLFromPasteboard:paste]]; 43 | 44 | return YES; 45 | } 46 | -(void)concludeDragOperation:(id )sender 47 | { 48 | if (IconPath && [IconPath isKindOfClass:[NSString class]]) 49 | { 50 | if ([IconPath hasPrefix:@"/"]) [self loadIconFromFile:IconPath]; 51 | if ([IconPath isAValidURL]) [self loadIconFromWebLink:IconPath]; 52 | [[NSSound soundNamed:@"Pop"] play]; 53 | } 54 | } 55 | 56 | -(NSImage*)getQuickLookImageFromFileAtPath:(NSString*)arquivo 57 | { 58 | NSImage* img = [[NSWorkspace sharedWorkspace] iconForFile:arquivo]; 59 | BOOL isFile = [[NSFileManager defaultManager] regularFileExistsAtPath:BINARY_QLMANAGE]; 60 | if (isFile) 61 | { 62 | [NSTask runProgram:BINARY_QLMANAGE atRunPath:[arquivo stringByDeletingLastPathComponent] 63 | withFlags:@[@"-t", @"-s",[NSString stringWithFormat:@"%d",MAX_ICON_SIZE], @"-o.", arquivo] wait:YES]; 64 | 65 | NSString* newFile = [NSString stringWithFormat:@"%@.png",arquivo, nil]; 66 | isFile = [[NSFileManager defaultManager] regularFileExistsAtPath:newFile]; 67 | if (isFile) 68 | { 69 | img = [[NSImage alloc] initWithContentsOfFile:newFile]; 70 | [[NSFileManager defaultManager] removeItemAtPath:newFile]; 71 | } 72 | } 73 | return img; 74 | } 75 | -(NSImage*)getImageFromFile:(NSString*)arquivo 76 | { 77 | NSImage *img; 78 | 79 | NSString *loweredExtension = arquivo.pathExtension.lowercaseString; 80 | NSSet *validImageExtensions = [NSSet setWithArray:NSImage.imageFileTypes]; 81 | 82 | if ([validImageExtensions containsObject:loweredExtension]) 83 | img = [[NSImage alloc] initWithContentsOfFile:arquivo]; 84 | else img = [self getQuickLookImageFromFileAtPath:arquivo]; 85 | 86 | if (img) return img; 87 | return [[NSWorkspace sharedWorkspace] iconForFile:arquivo]; 88 | } 89 | 90 | -(void)loadIconFromWebLink:(NSString*)link 91 | { 92 | NSString *loweredExtension = link.pathExtension.lowercaseString; 93 | NSSet *validImageExtensions = [NSSet setWithArray:NSImage.imageFileTypes]; 94 | 95 | if ([validImageExtensions containsObject:loweredExtension]) 96 | { 97 | NSData* imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:link] timeoutInterval:5]; 98 | NSImage *img = [[NSImage alloc] initWithData:imageData]; 99 | [self loadImageIcon:img]; 100 | } 101 | } 102 | -(void)loadIconFromFile:(NSString*)arquivo 103 | { 104 | [self loadImageIcon:[self getImageFromFile:arquivo]]; 105 | } 106 | -(void)loadImageIcon:(NSImage*)image 107 | { 108 | if (self.squareImage) [image imageByFramingImageResizing:NO]; 109 | 110 | [self setImage:image]; 111 | } 112 | 113 | @end 114 | -------------------------------------------------------------------------------- /WineskinLauncher/WineskinLauncher_Prefix.pch: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************** 3 | * WineskinLauncher code for Wineskin and wrappers 4 | * Made by doh123 (doh123@doh123.com) 5 | * With the help of Syaoran of dotalux.com 6 | * 7 | * Version 1.0 8 | * Made for Wineskin 2.0 9 | * 10 | * This code is Open Source and licensed under the 11 | * terms of the GNU Lesser General Public License. 12 | * If the License file is not with this source, the 13 | * full license can be read at the following URL 14 | * 15 | * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html 16 | * 17 | * For Wineskin information, see the project website at 18 | * http://wineskin.doh123.com 19 | * 20 | **************************************************** 21 | */ 22 | // 23 | // Prefix header for all source files of the 'WineskinLauncher' target in the 'WineskinLauncher' project 24 | // 25 | 26 | #ifdef __OBJC__ 27 | #import 28 | #endif 29 | 30 | #define WINESKIN_APP_NAME @"Wineskin Launcher" 31 | #define WINESKIN_VERSION [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"] 32 | #define RETINA_SCALE [NSScreen mainScreen].userSpaceScaleFactor 33 | #define ALERT_ICON_SIZE 512 34 | 35 | #define NSTemporaryPath(p) [NSString stringWithFormat:@"%@%@",NSTemporaryDirectory(),p] 36 | 37 | #define WINDOWS_PATH_PROGRAM_FILES_PLACEHOLDER @"%ProgramFiles%" 38 | 39 | #define REGEX_WINESKIN_ENGINE @"WS[0-9]+Wine(CX|CXG|Staging)?(64Bit)?[0-9\\.]+[^\\n]*" 40 | 41 | // Wineskin Plist entries 42 | #define WINESKIN_WRAPPER_PLIST_KEY_NAME @"CFBundleName" 43 | #define WINESKIN_WRAPPER_PLIST_KEY_WINESKIN_VERSION @"CFBundleVersion" 44 | #define WINESKIN_WRAPPER_PLIST_KEY_VERSION @"CFBundleShortVersionString" 45 | #define WINESKIN_WRAPPER_PLIST_KEY_ICON_PATH @"CFBundleIconFile" 46 | #define WINESKIN_WRAPPER_PLIST_KEY_IDENTIFIER @"CFBundleIdentifier" 47 | #define WINESKIN_WRAPPER_PLIST_KEY_EXECUTABLE @"CFBundleExecutable" 48 | #define WINESKIN_WRAPPER_PLIST_KEY_SINGLE_CPU @"Disable CPUs" 49 | #define WINESKIN_WRAPPER_PLIST_KEY_MAX_OF_10240_FILES @"set max files" 50 | #define WINESKIN_WRAPPER_PLIST_KEY_ASSOCIATIONS @"Associations" 51 | #define WINESKIN_WRAPPER_PLIST_KEY_AUTOMATICALLY_DETECT_GPU @"Try To Use GPU Info" 52 | #define WINESKIN_WRAPPER_PLIST_KEY_RUN_PATH @"Program Name and Path" 53 | #define WINESKIN_WRAPPER_PLIST_KEY_RUN_PATH_IS_NOT_EXE @"use start.exe" 54 | #define WINESKIN_WRAPPER_PLIST_KEY_RUN_PATH_FLAGS @"Program Flags" 55 | #define WINESKIN_WRAPPER_PLIST_KEY_SCREEN_OPTIONS_ARE_AUTOMATIC @"Use RandR" 56 | #define WINESKIN_WRAPPER_PLIST_KEY_SCREEN_OPTIONS_IS_FULLSCREEN @"Fullscreen" 57 | #define WINESKIN_WRAPPER_PLIST_KEY_SCREEN_OPTIONS_CONFIGURATIONS @"Resolution" 58 | #define WINESKIN_WRAPPER_PLIST_KEY_DEBUG_MODE @"Debug Mode" 59 | #define WINESKIN_WRAPPER_PLIST_KEY_GAMMA_CORRECTION @"Gamma Correction" 60 | #define WINESKIN_WRAPPER_PLIST_KEY_INSTALLER_WITH_NORMAL_WINDOWS @"force Installer to normal windows" 61 | #define WINESKIN_WRAPPER_PLIST_KEY_WINETRICKS_SILENT @"Winetricks silent" 62 | #define WINESKIN_WRAPPER_PLIST_KEY_WINETRICKS_NOLOGS @"Winetricks disable logging" 63 | #define WINESKIN_WRAPPER_PLIST_KEY_ENABLE_FNTOGGLE @"IsFnToggleEnabled" 64 | #define WINESKIN_WRAPPER_PLIST_KEY_DISABLE_MONO_GECKO @"Skip Mono & Gecko" 65 | #define WINESKIN_WRAPPER_PLIST_KEY_ENABLE_FNTOGGLE @"IsFnToggleEnabled" 66 | 67 | // Wineskin Plist values 68 | #define WINESKIN_WRAPPER_PLIST_VALUE_SCREEN_OPTIONS_CURRENT_RESOLUTION @"Current Resolution" 69 | #define WINESKIN_WRAPPER_PLIST_VALUE_SCREEN_OPTIONS_NO_VIRTUAL_DESKTOP @"novd" 70 | 71 | // Plist files paths 72 | #define PLIST_PATH_WINESKIN_CUSTOM_EXE @"/Contents/Info.plist.cexe" 73 | #define PLIST_PATH_WINESKIN_WRAPPER @"/Contents/Info.plist" 74 | 75 | #define WINESKIN_LIBRARY_FOLDER [NSString stringWithFormat:@"%@/Library/Application Support/Wineskin",NSHomeDirectory()] 76 | 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Wineskin 2 | 3 | [![Build Status](https://travis-ci.org/vitor251093/wineskin.svg?branch=master)](https://travis-ci.org/vitor251093/wineskin) 4 | 5 | **Wineskin** is a user-friendly tool used to make ports of Microsoft Windows software to Apple's macOS/Mac OS X. 6 | 7 | ## How Does It Work? 8 | 9 | As described in the [original Wineskin's website](http://wineskin.urgesoftware.com/): 10 | 11 | > The ports are in the form of normal macOS application bundle wrappers. 12 | > It works like a wrapper around the Windows software, and you can share just the wrappers if you choose. 13 | > 14 | > Make ports/wrappers to share with others, make ports of your own open source, free, or commercial software, or just make a port for yourself! 15 | > Why install and use Windows if you don’t need to? 16 | 17 | Wineskin relies on [WINE](http://www.winehq.org/) ("WINE Is Not an Emulator") under the hood: 18 | 19 | > Instead of simulating internal Windows logic like a virtual machine or emulator, 20 | > Wine translates Windows API calls into POSIX calls on-the-fly, 21 | > eliminating the performance and memory penalties of other methods 22 | > and allowing you to cleanly integrate Windows applications into your desktop. 23 | 24 | ## Quick Start 25 | 26 | Install [Carthage](https://github.com/Carthage/Carthage) via [Homebrew](https://brew.sh/) to manage the build dependencies: 27 | 28 | ```bash 29 | $ brew install carthage 30 | ``` 31 | 32 | Clone the repository and build the dependencies: 33 | 34 | ```bash 35 | $ git clone https://github.com/vitor251093/wineskin.git 36 | $ cd wineskin/ 37 | $ carthage update 38 | ``` 39 | 40 | Open `Wineskin.xcworkspace` in Xcode and build: 41 | 42 | ```bash 43 | $ open Wineskin.xcworkspace 44 | ``` 45 | 46 | Or build via the command line: 47 | 48 | ```bash 49 | $ xcodebuild -workspace Wineskin.xcworkspace -scheme Wineskin build 50 | $ xcodebuild -workspace Wineskin.xcworkspace -scheme "Wineskin Winery" build 51 | $ xcodebuild -workspace Wineskin.xcworkspace -scheme WineskinLauncher build 52 | ``` 53 | 54 | ## Changes from the original project 55 | 56 | As you may have already noticed, this is not the [original Wineskin repository](https://sourceforge.net/p/wineskin/code/ci/master/tree/). 57 | This repository counts with changes to make Wineskin more stable and its source easier to maintain. 58 | Considering this, lots of changes were made in WineskinApp and WineskinLauncher, and now both of them use [ObjectiveC_Extension](https://github.com/vitor251093/ObjectiveC_Extension) and some new classes to perform most of their tasks. 59 | 60 | ### Changes in the Wineskin App (WineskinApp) 61 | 62 | - The Resolution property in Info.plist should never get corrupted (*(null)x24sleep0*); 63 | - The *Auto-detect GPU* feature should never cause malfunction in the port; 64 | - The *Auto-detect GPU* feature should have a much bigger accuracy and detect the memory size of integrated video cards as well; 65 | - Enabling *Mac Driver* and *Decorate window* checkboxes should not corrupt the wrapper registry; 66 | - The *Retina Mode* can be enabled from the Screen Options window; 67 | - *Kill Wineskin Processes* should kill ALL Wineskin processes. 68 | - Icons can be extracted directly from exe files; 69 | - Images (not .icns files) should also be accepted has wrapper icons; 70 | - LNK files should be able to be selected as a port's run path, so Wineskin can extract the path and flags from it; 71 | - Winetricks installation can be silent (with no windows) so it's much faster; 72 | - The first *Advanced* tab (*Configuration*) should be much more simple in the first section: 73 | - The *Windows EXE* should use Wineskin syntax, including the drive and the flags, (eg. *"C:/Program Files/temp.exe" --run*) instead of using a macOS reference path (eg. */Program Files/temp.exe*) and the flag apart (eg. *--run*). 74 | 75 | ### Changes in the Master Wrapper (WineskinLauncher) 76 | 77 | - Many fixes when dealing with newest engines. 78 | - WineskinX11 dropped. 79 | - Closes processes XQuartz on exit 80 | - Can use XQuartz installed via macports 81 | 82 | ### Roadmap of desired changes in the Master Wrapper (WineskinLauncher) 83 | 84 | - A different Master Wrapper for macOS 10.6 and 10.7; 85 | 86 | ## Licensing 87 | 88 | The license is kept the same as the original material as LGPL 2.1. 89 | You can find more details in the [LICENSE](LICENSE) file. 90 | 91 | ## Credits 92 | 93 | Special credits for this version go to doh123, for creating the original Wineskin 94 | [[website](http://wineskin.urgesoftware.com/)] [[code](https://sourceforge.net/projects/wineskin/)]. 95 | -------------------------------------------------------------------------------- /WineskinLauncher/NSPortDataLoader.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSPortDataLoader.m 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 07/03/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import "NSPortDataLoader.h" 10 | #import 11 | 12 | #import "NSPathUtilities.h" 13 | 14 | @implementation NSPortDataLoader 15 | 16 | +(NSString*)engineOfPortAtPath:(NSString*)path 17 | { 18 | NSString* wswineVersion = [NSString stringWithFormat:@"%@/Contents/Frameworks/wswine.bundle/version",path]; 19 | 20 | if ([[NSFileManager defaultManager] fileExistsAtPath:wswineVersion]) 21 | { 22 | return [[NSString stringWithContentsOfFile:wswineVersion encoding:NSASCIIStringEncoding] componentsSeparatedByString:@"\n"][0]; 23 | } 24 | 25 | return nil; 26 | } 27 | 28 | +(BOOL)macDriverIsEnabledAtPort:(NSPortManager*)port 29 | { 30 | NSString* driversVariable = [port getRegistryEntry:@"[Software\\\\Wine\\\\Drivers]" fromRegistryFileNamed:USER_REG]; 31 | if (driversVariable) 32 | { 33 | driversVariable = [NSPortManager getStringValueForKey:@"Graphics" fromRegistryString:driversVariable]; 34 | return driversVariable && [driversVariable isEqualToString:@"mac,x11"]; 35 | } 36 | else if (driversVariable) 37 | { 38 | driversVariable = [NSPortManager getStringValueForKey:@"Graphics" fromRegistryString:driversVariable]; 39 | return driversVariable && [driversVariable isEqualToString:@"mac"]; 40 | } 41 | 42 | return FALSE; 43 | } 44 | 45 | +(BOOL)useXQuartzIsEnabledAtPort:(NSPortManager*)port 46 | { 47 | NSString* driversVariable = [port getRegistryEntry:@"[Software\\\\Wine\\\\Drivers]" fromRegistryFileNamed:USER_REG]; 48 | if (driversVariable) 49 | { 50 | driversVariable = [NSPortManager getStringValueForKey:@"Graphics" fromRegistryString:driversVariable]; 51 | return driversVariable && [driversVariable isEqualToString:@"x11,mac"]; 52 | } 53 | else if (driversVariable) 54 | { 55 | driversVariable = [NSPortManager getStringValueForKey:@"Graphics" fromRegistryString:driversVariable]; 56 | return driversVariable && [driversVariable isEqualToString:@"x11"]; 57 | } 58 | 59 | return FALSE; 60 | } 61 | 62 | +(void)getValuesFromResolutionString:(NSString*)originalResolutionString 63 | inBlock:(void (^)(BOOL virtualDesktop, NSString* resolution, int colors, int sleep))resolutionValues 64 | { 65 | if (originalResolutionString.length < 12) 66 | { 67 | resolutionValues(NO, nil, 24, 0); 68 | return; 69 | } 70 | 71 | NSString* resolutionString = originalResolutionString; 72 | 73 | NSRange sleepRange = [resolutionString rangeOfString:@"sleep"]; 74 | if (sleepRange.location == NSNotFound) 75 | { 76 | resolutionValues(NO, nil, 24, 0); 77 | return; 78 | } 79 | 80 | NSUInteger sleepLocation = sleepRange.location + sleepRange.length; 81 | NSUInteger sleepLength = resolutionString.length - sleepLocation; 82 | int sleep = [[resolutionString substringWithRange:NSMakeRange(sleepLocation, sleepLength)] intValue]; 83 | 84 | NSRange xInEndOfResolution = [resolutionString rangeOfString:@"x" options:NSBackwardsSearch]; 85 | if (xInEndOfResolution.location == NSNotFound) 86 | { 87 | resolutionValues(NO, nil, 24, sleep); 88 | return; 89 | } 90 | 91 | NSUInteger colorsLocation = xInEndOfResolution.location + xInEndOfResolution.length; 92 | NSUInteger colorsLength = sleepRange.location - colorsLocation; 93 | if (colorsLocation + colorsLength > resolutionString.length) 94 | { 95 | resolutionValues(NO, nil, 24, sleep); 96 | return; 97 | } 98 | 99 | int colors = [[resolutionString substringWithRange:NSMakeRange(colorsLocation, colorsLength)] intValue]; 100 | 101 | 102 | BOOL virtualDesktop = false; 103 | NSString* resolution = nil; 104 | 105 | if ([resolutionString hasPrefix:WINESKIN_WRAPPER_PLIST_VALUE_SCREEN_OPTIONS_NO_VIRTUAL_DESKTOP] == false) 106 | { 107 | virtualDesktop = true; 108 | 109 | NSUInteger resolutionLength = xInEndOfResolution.location; 110 | resolution = [resolutionString substringWithRange:NSMakeRange(0, resolutionLength)]; 111 | } 112 | 113 | resolutionValues(virtualDesktop, resolution, colors, sleep); 114 | } 115 | 116 | @end 117 | -------------------------------------------------------------------------------- /WineskinApp/NSTask+Extension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSTask+Extension.m 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/02/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import "NSTask+Extension.h" 10 | 11 | #import "NSAlert+Extension.h" 12 | #import "NSFileManager+Extension.h" 13 | 14 | @implementation NSTask (PKTask) 15 | 16 | static NSMutableDictionary* binaryPaths; 17 | 18 | +(NSString*)runProgram:(NSString*)program atRunPath:(NSString*)path withFlags:(NSArray*)flags wait:(BOOL)wait 19 | { 20 | return [self runProgram:program atRunPath:path withEnvironment:nil withFlags:flags wait:wait]; 21 | } 22 | +(NSString*)runProgram:(NSString*)program withEnvironment:(NSDictionary*)env withFlags:(NSArray*)flags 23 | { 24 | return [self runProgram:program atRunPath:@"/" withEnvironment:env withFlags:flags wait:YES]; 25 | } 26 | +(NSString*)runProgram:(NSString*)program atRunPath:(NSString*)path withEnvironment:(NSDictionary*)env withFlags:(NSArray*)flags wait:(BOOL)wait 27 | { 28 | if (program && ![program hasPrefix:@"/"]) program = [self getPathOfProgram:program]; 29 | if (!program) 30 | { 31 | [NSAlert showAlertOfType:NSAlertTypeError withMessage:NSLocalizedString(@"Program couldn't be found.",nil)]; 32 | return @""; 33 | } 34 | 35 | if (path && flags) NSDebugLog(@"Running %@ at path %@ with flags %@",program,path,[flags componentsJoinedByString:@" "]); 36 | else if (path && !flags) NSDebugLog(@"Running %@ at path %@",program,path); 37 | else if (!path && flags) NSDebugLog(@"Running %@ with flags %@",program,[flags componentsJoinedByString:@" "]); 38 | else if (!path && !flags) NSDebugLog(@"Running %@",program); 39 | 40 | if (path && ![path hasSuffix:@"/"]) path = [path stringByAppendingString:@"/"]; 41 | 42 | if (![[NSFileManager defaultManager] fileExistsAtPath:program]) 43 | { 44 | [NSAlert showAlertOfType:NSAlertTypeError withMessage:[NSString stringWithFormat:NSLocalizedString(@"File %@ not found.",nil), program]]; 45 | return @""; 46 | } 47 | 48 | if (![[NSFileManager defaultManager] isExecutableFileAtPath:program]) 49 | { 50 | [NSAlert showAlertOfType:NSAlertTypeError withMessage:[NSString stringWithFormat:NSLocalizedString(@"File %@ not runnable.",nil), program]]; 51 | return @""; 52 | } 53 | 54 | @try 55 | { 56 | NSTask *server = [NSTask new]; 57 | [server setLaunchPath:program]; 58 | if (path) 59 | { 60 | if (![[NSFileManager defaultManager] directoryExistsAtPath:path]) 61 | { 62 | [NSAlert showAlertOfType:NSAlertTypeError withMessage:[NSString stringWithFormat:NSLocalizedString(@"Directory %@ does not exists.",nil), path]]; 63 | return @""; 64 | } 65 | [server setCurrentDirectoryPath:path]; 66 | } 67 | if (flags) [server setArguments:flags]; 68 | if (env) [server setEnvironment:env]; 69 | 70 | NSPipe *outputPipe = [NSPipe pipe]; 71 | [server setStandardInput:[NSPipe pipe]]; 72 | [server setStandardOutput:outputPipe]; 73 | [server launch]; 74 | 75 | if (wait) [server waitUntilExit]; 76 | NSData *outputData = [[outputPipe fileHandleForReading] readDataToEndOfFile]; 77 | 78 | NSDebugLog(@"Instruction finished"); 79 | 80 | if (wait==YES) return [[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding]; 81 | else return @""; 82 | } 83 | @catch (NSException* exception) 84 | { 85 | // Sometimes (very rarely) the app might fail to retrieve the output of a command; with that, PK won't stop 86 | 87 | NSDebugLog(@"Failed to retrieve instruction output"); 88 | 89 | return @""; 90 | } 91 | } 92 | 93 | +(NSString*)getPathOfProgram:(NSString*)programName 94 | { 95 | if (!programName) return nil; 96 | 97 | if (!binaryPaths) binaryPaths = [@{} mutableCopy]; 98 | else if (binaryPaths[programName]) return binaryPaths[programName]; 99 | 100 | NSString* programPath; 101 | programPath = [self runProgram:@"/usr/bin/type" atRunPath:nil withFlags:@[@"-a",programName] wait:YES]; 102 | if (!programPath) return nil; 103 | 104 | programPath = [[programPath componentsSeparatedByString:@" "] lastObject]; 105 | 106 | if (programPath.length > 0) programPath = [programPath substringToIndex:programPath.length-1]; 107 | else return nil; 108 | 109 | [binaryPaths setObject:programPath forKey:programName]; 110 | return programPath; 111 | } 112 | 113 | @end 114 | 115 | -------------------------------------------------------------------------------- /Wineskin Winery/Wineskin_WineryAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // Wineskin_WineryAppDelegate.h 3 | // Wineskin Winery 4 | // 5 | // Copyright 2011-2013 by The Wineskin Project and Urge Software LLC All rights reserved. 6 | // Licensed for use under the LGPL 7 | // 8 | 9 | #import 10 | 11 | #import "NSWineskinEngine.h" 12 | 13 | @interface Wineskin_WineryAppDelegate : NSObject 14 | { 15 | //main window 16 | IBOutlet NSWindow *__unsafe_unretained window; 17 | IBOutlet NSWindow *aboutWindow; 18 | IBOutlet NSTextField *aboutWindowVersionNumber; 19 | IBOutlet NSWindow *helpWindow; 20 | IBOutlet NSMenuItem *aboutWindowMenuItem; 21 | IBOutlet NSTextField *wrapperVersion; 22 | IBOutlet NSTableView *installedEngines; 23 | IBOutlet NSTextField *engineAvailableLabel; 24 | IBOutlet NSTextField *updateAvailableLabel; 25 | IBOutlet NSButton *hideXQuartzEnginesCheckBox; 26 | IBOutlet NSButton *updateButton; 27 | IBOutlet NSButton *createWrapperButton; 28 | NSMutableArray* installedEnginesList; 29 | NSMutableArray* installedMacDriverEnginesList; 30 | 31 | //downloading window 32 | IBOutlet NSWindow *downloadingWindow; 33 | IBOutlet NSTextField *urlInput; 34 | IBOutlet NSTextField *urlOutput; 35 | IBOutlet NSTextField *fileName; 36 | IBOutlet NSTextField *fileNameDestination; 37 | IBOutlet NSProgressIndicator *progressBar; 38 | IBOutlet NSButton *cancelButton; 39 | IBOutlet NSButton *downloadButton; 40 | NSURLConnection *connection; 41 | NSURLRequest *request; 42 | NSMutableData *payload; 43 | 44 | //add engine window 45 | IBOutlet NSWindow *addEngineWindow; 46 | IBOutlet NSButton *engineWindowDownloadAndInstallButton; 47 | IBOutlet NSButton *engineWindowViewWineReleaseNotesButton; 48 | IBOutlet NSButton *engineWindowDontPromptAsNewButton; 49 | IBOutlet NSPopUpButton *engineWindowEngineList; 50 | 51 | //engine build window 52 | IBOutlet NSWindow *wineskinEngineBuilderWindow; 53 | IBOutlet NSTextField *engineBuildWineSource; 54 | IBOutlet NSTextField *engineBuildConfigurationOptions; 55 | IBOutlet NSTextField *engineBuildEngineName; 56 | IBOutlet NSPopUpButton *engineBuildOSVersionToBuildEngineFor; 57 | IBOutlet NSTextField *engineBuildCurrentEngineBase; 58 | IBOutlet NSTextField *engineBuildUpdateAvailable; 59 | IBOutlet NSButton *engineBuildChooseButton; 60 | IBOutlet NSButton *engineBuildBuildButton; 61 | IBOutlet NSButton *engineBuildUpdateButton; 62 | 63 | //create wrapper window 64 | IBOutlet NSWindow *createWrapperWindow; 65 | IBOutlet NSTextField *createWrapperEngine; 66 | IBOutlet NSTextField *createWrapperName; 67 | 68 | //busy window 69 | IBOutlet NSWindow *busyWindow; 70 | IBOutlet NSProgressIndicator *waitWheel; 71 | 72 | } 73 | @property (unsafe_unretained) IBOutlet NSWindow *window; 74 | 75 | //main stuff 76 | - (void)runConverter; 77 | - (IBAction)aboutWindow:(id)sender; 78 | - (IBAction)helpWindow:(id)sender; 79 | - (void)makeFoldersAndFiles; 80 | - (void)checkForUpdates; 81 | - (IBAction)createNewBlankWrapperButtonPressed:(id)sender; 82 | - (IBAction)refreshButtonPressed:(id)sender; 83 | - (IBAction)downloadPackagesManuallyButtonPressed:(id)sender; 84 | - (IBAction)plusButtonPressed:(id)sender; 85 | - (void)showAvailableEngines:(NSString *)theFilter; 86 | - (IBAction)minusButtonPressed:(id)sender; 87 | - (IBAction)updateButtonPressed:(id)sender; 88 | - (IBAction)wineskinWebsiteButtonPressed:(id)sender; 89 | - (void)getInstalledEngines:(NSString *)theFilter; 90 | - (NSArray *)getEnginesToIgnore; 91 | - (NSMutableArray *)getAvailableEngines; 92 | - (NSString *)getCurrentWrapperVersion; 93 | - (void)setEnginesAvailablePrompt; 94 | - (void)setWrapperAvailablePrompt; 95 | - (IBAction)engineSearchFilter:(id)sender; 96 | - (IBAction)availEngineSearchFilter:(id)sender; 97 | 98 | //engine build window 99 | - (IBAction)engineBuildChooseButtonPressed:(id)sender; 100 | - (IBAction)engineBuildBuildButtonPressed:(id)sender; 101 | - (IBAction)engineBuildUpdateButtonPressed:(id)sender; 102 | - (IBAction)engineBuildCancelButtonPressed:(id)sender; 103 | - (NSString *)currentEngineBuildVersion; 104 | - (NSString *)availableEngineBuildVersion; 105 | 106 | //Engine Window (+ button) methods 107 | - (IBAction)engineWindowDownloadAndInstallButtonPressed:(id)sender; 108 | - (IBAction)engineWindowViewWineReleaseNotesButtonPressed:(id)sender; 109 | - (IBAction)engineWindowEngineListChanged:(id)sender; 110 | - (IBAction)engineWindowDontPromptAsNewButtonPressed:(id)sender; 111 | - (IBAction)engineWindowDontPromptAllEnginesAsNewButtonPressed:(id)sender; 112 | - (IBAction)engineWindowCustomBuildAnEngineButtonPressed:(id)sender; 113 | - (IBAction)engineWindowCancelButtonPressed:(id)sender; 114 | 115 | //Downloader methods 116 | - (IBAction) startDownload:(NSButton *)sender; 117 | - (IBAction) stopDownloading:(NSButton *)sender; 118 | - (void)downloadToggle:(BOOL)toggle; 119 | - (void)connection:(NSURLConnection *)conn didReceiveResponse:(NSURLResponse *)response; 120 | - (void)connection:(NSURLConnection *)conn didReceiveData:(NSData *)data; 121 | - (void)connectionDidFinishLoading:(NSURLConnection *)conn; 122 | - (void)connection:(NSURLConnection *)conn didFailWithError:(NSError *)error; 123 | 124 | //create wrapper window methods 125 | - (IBAction) createWrapperOkButtonPressed:(id)sender; 126 | - (IBAction) createWrapperCancelButtonPressed:(id)sender; 127 | 128 | //pass in a string to see it in a pop up, for devel testing string values. 129 | - (void)ds:(NSString *)input; 130 | 131 | @end 132 | -------------------------------------------------------------------------------- /WineskinApp/NSFileManager+Extension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSFileManager+Extension.m 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/02/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import "NSFileManager+Extension.h" 10 | 11 | #import "NSAlert+Extension.h" 12 | #import "NSTask+Extension.h" 13 | 14 | @implementation NSFileManager (PKFileManager) 15 | 16 | -(BOOL)createSymbolicLinkAtPath:(NSString *)path withDestinationPath:(NSString *)destPath 17 | { 18 | NSError* error; 19 | BOOL created = [self createSymbolicLinkAtPath:path withDestinationPath:destPath error:&error]; 20 | 21 | if (error) 22 | [NSAlert showAlertOfType:NSAlertTypeError withMessage:[NSString stringWithFormat:NSLocalizedString(@"Error while creating symbolic link: %@",nil), error.localizedDescription]]; 23 | 24 | return created; 25 | } 26 | -(BOOL)createDirectoryAtPath:(NSString*)path withIntermediateDirectories:(BOOL)interDirs 27 | { 28 | NSError* error; 29 | BOOL created = [self createDirectoryAtPath:path withIntermediateDirectories:interDirs attributes:nil error:&error]; 30 | 31 | if (error) 32 | [NSAlert showAlertOfType:NSAlertTypeError withMessage:[NSString stringWithFormat:NSLocalizedString(@"Error while creating folder: %@",nil), error.localizedDescription]]; 33 | 34 | return created; 35 | } 36 | -(BOOL)moveItemAtPath:(NSString*)path toPath:(NSString*)destination 37 | { 38 | NSError* error; 39 | BOOL created = [self moveItemAtPath:path toPath:destination error:&error]; 40 | 41 | if (error) 42 | [NSAlert showAlertOfType:NSAlertTypeError withMessage:[NSString stringWithFormat:NSLocalizedString(@"Error while moving file: %@",nil), 43 | error.localizedDescription]]; 44 | 45 | return created; 46 | } 47 | -(BOOL)copyItemAtPath:(NSString*)path toPath:(NSString*)destination 48 | { 49 | NSError* error; 50 | BOOL created = [self copyItemAtPath:path toPath:destination error:&error]; 51 | 52 | if (error) 53 | [NSAlert showAlertOfType:NSAlertTypeError withMessage:[NSString stringWithFormat:NSLocalizedString(@"Error while copying file: %@",nil), error.localizedDescription]]; 54 | 55 | return created; 56 | } 57 | -(BOOL)removeItemAtPath:(NSString*)path 58 | { 59 | if (![self fileExistsAtPath:path]) return YES; 60 | 61 | NSError* error; 62 | BOOL created = [self removeItemAtPath:path error:&error]; 63 | 64 | if (error) 65 | [NSAlert showAlertOfType:NSAlertTypeError withMessage:[NSString stringWithFormat:NSLocalizedString(@"Error while removing file: %@",nil), error.localizedDescription]]; 66 | 67 | return created; 68 | } 69 | -(BOOL)directoryExistsAtPath:(NSString*)path 70 | { 71 | BOOL isDir = NO; 72 | return [self fileExistsAtPath:path isDirectory:&isDir] && isDir; 73 | } 74 | -(BOOL)regularFileExistsAtPath:(NSString*)path 75 | { 76 | BOOL isDir = NO; 77 | return [self fileExistsAtPath:path isDirectory:&isDir] && !isDir; 78 | } 79 | -(NSArray*)contentsOfDirectoryAtPath:(NSString*)path 80 | { 81 | if (![self fileExistsAtPath:path]) 82 | { 83 | [NSAlert showAlertOfType:NSAlertTypeError withMessage:[NSString stringWithFormat:NSLocalizedString(@"Error while listing folder contents: %@ doesn't exist.",nil), path.lastPathComponent]]; 84 | return @[]; 85 | } 86 | 87 | if (![self directoryExistsAtPath:path]) 88 | { 89 | [NSAlert showAlertOfType:NSAlertTypeError withMessage:[NSString stringWithFormat:NSLocalizedString(@"Error while listing folder contents: %@ is not a folder.",nil), path.lastPathComponent]]; 90 | return @[]; 91 | } 92 | 93 | NSError* error; 94 | NSArray* created = [self contentsOfDirectoryAtPath:path error:&error]; 95 | 96 | if (error) 97 | { 98 | [NSAlert showAlertOfType:NSAlertTypeError withMessage:[NSString stringWithFormat:NSLocalizedString(@"Error while listing folder contents: %@",nil), error.localizedDescription]]; 99 | return @[]; 100 | } 101 | 102 | NSMutableArray* createdMutable = [created mutableCopy]; 103 | [createdMutable removeObject:@".DS_Store"]; 104 | 105 | return createdMutable; 106 | } 107 | -(NSString*)destinationOfSymbolicLinkAtPath:(NSString *)path 108 | { 109 | NSError* error; 110 | NSString* destination = [self destinationOfSymbolicLinkAtPath:path error:&error]; 111 | 112 | if (error) 113 | { 114 | [NSAlert showAlertOfType:NSAlertTypeError withMessage:[NSString stringWithFormat:NSLocalizedString(@"Error while retrieving symbolic link destination: %@",nil),error.localizedDescription]]; 115 | } 116 | 117 | return destination; 118 | } 119 | 120 | -(unsigned long long int)sizeOfRegularFileAtPath:(NSString*)path 121 | { 122 | NSDictionary *fileDictionary = [self attributesOfItemAtPath:path error:nil]; 123 | return fileDictionary ? [fileDictionary[NSFileSize] unsignedLongLongValue] : 0; 124 | } 125 | -(unsigned long long int)sizeOfDirectoryAtPath:(NSString*)path 126 | { 127 | NSArray *filesArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:path error:nil]; 128 | unsigned long long int fileSize = 0; 129 | 130 | for (NSString* file in filesArray) 131 | { 132 | NSString* filePath = [path stringByAppendingPathComponent:file]; 133 | 134 | if (![self destinationOfSymbolicLinkAtPath:filePath error:nil]) 135 | { 136 | fileSize += [self sizeOfRegularFileAtPath:filePath]; 137 | } 138 | } 139 | 140 | return fileSize; 141 | } 142 | 143 | @end 144 | -------------------------------------------------------------------------------- /WineskinApp/NSImage+Extension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSImage+Extension.m 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 12/03/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "NSImage+Extension.h" 12 | 13 | #import "NSComputerInformation.h" 14 | 15 | #import "NSTask+Extension.h" 16 | #import "NSString+Extension.h" 17 | #import "NSFileManager+Extension.h" 18 | 19 | #define INNER_GOG_ICON_SIDE 440 20 | #define INNER_GOG_ICON_X_MARGIN 36 21 | #define INNER_GOG_ICON_Y_MARGIN 35 22 | 23 | #define FULL_ICON_SIZE 512 24 | 25 | 26 | #define SMALLER_ICONSET_NEEDED_SIZE 16 27 | #define BIGGEST_ICONSET_NEEDED_SIZE 1024 28 | 29 | #define TIFF2ICNS_ICON_SIZE 512 30 | 31 | 32 | @implementation NSImage (PKImage) 33 | 34 | -(NSImage*)imageByFramingImageResizing:(BOOL)willResize 35 | { 36 | int MAX_ICON_SIZE = FULL_ICON_SIZE/RETINA_SCALE; 37 | 38 | if (self.size.width > self.size.height) 39 | { 40 | CGFloat newHeight = (MAX_ICON_SIZE / self.size.width) * self.size.height; 41 | [self setSize:NSMakeSize(MAX_ICON_SIZE,newHeight)]; 42 | 43 | NSRect dim = [self alignmentRect]; 44 | dim.size.height = MAX_ICON_SIZE; 45 | dim.origin.y = self.size.height/2 - MAX_ICON_SIZE/2; 46 | [self setAlignmentRect:dim]; 47 | } 48 | 49 | else if (self.size.width < self.size.height) 50 | { 51 | CGFloat newWidth = (MAX_ICON_SIZE / self.size.height) * self.size.width; 52 | [self setSize: NSMakeSize(newWidth,MAX_ICON_SIZE)]; 53 | 54 | NSRect dim = [self alignmentRect]; 55 | dim.size.width = MAX_ICON_SIZE; 56 | dim.origin.x = self.size.width/2 - MAX_ICON_SIZE/2; 57 | [self setAlignmentRect:dim]; 58 | } 59 | 60 | else [self setSize:NSMakeSize(MAX_ICON_SIZE,MAX_ICON_SIZE)]; 61 | 62 | if (willResize) 63 | { 64 | NSImage *resizedImage = [[NSImage alloc] initWithSize:NSMakeSize(MAX_ICON_SIZE,MAX_ICON_SIZE)]; 65 | [resizedImage lockFocus]; 66 | 67 | [self drawInRect:NSMakeRect(0,0,MAX_ICON_SIZE,MAX_ICON_SIZE) fromRect:self.alignmentRect operation:NSCompositeSourceOver fraction:1.0]; 68 | 69 | [resizedImage unlockFocus]; 70 | return resizedImage; 71 | } 72 | else return self; 73 | } 74 | 75 | -(BOOL)saveAsPngImageWithSize:(int)size atPath:(NSString*)pngPath 76 | { 77 | CIImage *ciimage = [CIImage imageWithData:[self TIFFRepresentation]]; 78 | CIFilter *scaleFilter = [CIFilter filterWithName:@"CILanczosScaleTransform"]; 79 | 80 | int originalWidth = [ciimage extent].size.width; 81 | float scale = (float)size / (float)originalWidth; 82 | 83 | [scaleFilter setValue:@(scale) forKey:@"inputScale"]; 84 | [scaleFilter setValue:@(1.0) forKey:@"inputAspectRatio"]; 85 | [scaleFilter setValue:ciimage forKey:@"inputImage"]; 86 | 87 | ciimage = [scaleFilter valueForKey:@"outputImage"]; 88 | if (!ciimage) return false; 89 | 90 | NSBitmapImageRep* rep; 91 | 92 | @try 93 | { 94 | rep = [[NSBitmapImageRep alloc] initWithCIImage:ciimage]; 95 | } 96 | @catch (NSException* exception) 97 | { 98 | return false; 99 | } 100 | 101 | NSData *data = [rep representationUsingType:NSPNGFileType properties:@{}]; 102 | [data writeToFile:pngPath atomically:YES]; 103 | 104 | return true; 105 | } 106 | -(BOOL)saveIconsetWithSize:(int)size atFolder:(NSString*)folder 107 | { 108 | BOOL result = [self saveAsPngImageWithSize:size atPath:[NSString stringWithFormat:@"%@/icon_%dx%d.png",folder,size,size]]; 109 | if (result == false) return false; 110 | 111 | result = [self saveAsPngImageWithSize:size*2 atPath:[NSString stringWithFormat:@"%@/icon_%dx%d@2x.png",folder,size,size]]; 112 | return result; 113 | } 114 | -(BOOL)saveAsIcnsAtPath:(NSString*)icnsPath 115 | { 116 | if (!icnsPath) return false; 117 | 118 | if (![icnsPath hasSuffix:@".icns"]) icnsPath = [icnsPath stringByAppendingString:@".icns"]; 119 | NSString* iconsetPath = [[icnsPath substringToIndex:icnsPath.length - 5] stringByAppendingString:@".iconset"]; 120 | 121 | [[NSFileManager defaultManager] createDirectoryAtPath:iconsetPath withIntermediateDirectories:NO]; 122 | for (int validSize = SMALLER_ICONSET_NEEDED_SIZE; validSize <= BIGGEST_ICONSET_NEEDED_SIZE; validSize=validSize*2) 123 | [self saveIconsetWithSize:validSize atFolder:iconsetPath]; 124 | 125 | [[NSFileManager defaultManager] removeItemAtPath:icnsPath]; 126 | [NSTask runProgram:@"iconutil" atRunPath:nil withFlags:@[@"-c", @"icns", iconsetPath] wait:YES]; 127 | [[NSFileManager defaultManager] removeItemAtPath:iconsetPath]; 128 | 129 | if ([[NSFileManager defaultManager] sizeOfRegularFileAtPath:icnsPath] > 10) 130 | { 131 | return true; 132 | } 133 | 134 | NSString *tiffPath = [NSString stringWithFormat:@"%@.tiff",icnsPath]; 135 | 136 | CGFloat correctIconSize = TIFF2ICNS_ICON_SIZE/RETINA_SCALE; 137 | NSImage *resizedImage = [[NSImage alloc] initWithSize:NSMakeSize(correctIconSize,correctIconSize)]; 138 | [resizedImage lockFocus]; 139 | [self drawInRect:NSMakeRect(0,0,correctIconSize, correctIconSize) fromRect:self.alignmentRect 140 | operation:NSCompositeSourceOver fraction:1.0]; 141 | [resizedImage unlockFocus]; 142 | 143 | [[resizedImage TIFFRepresentation] writeToFile:tiffPath atomically:YES]; 144 | [[NSFileManager defaultManager] removeItemAtPath:icnsPath]; 145 | [NSTask runProgram:@"tiff2icns" atRunPath:nil withFlags:@[@"-noLarge", tiffPath, icnsPath] wait:YES]; 146 | [[NSFileManager defaultManager] removeItemAtPath:tiffPath]; 147 | 148 | return [[NSFileManager defaultManager] regularFileExistsAtPath:icnsPath]; 149 | } 150 | 151 | @end 152 | -------------------------------------------------------------------------------- /WineskinApp/NSString+Extension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Extension.m 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/02/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import "NSString+Extension.h" 10 | 11 | #import "NSData+Extension.h" 12 | #import "NSTask+Extension.h" 13 | #import "NSAlert+Extension.h" 14 | 15 | #import "NSComputerInformation.h" 16 | 17 | @implementation NSString (PKString) 18 | 19 | -(BOOL)contains:(NSString*)string 20 | { 21 | return [self rangeOfString:string].location != NSNotFound; 22 | } 23 | -(BOOL)matchesWithRegex:(NSString*)regexString 24 | { 25 | NSPredicate* regex = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regexString]; 26 | return [regex evaluateWithObject:self]; 27 | } 28 | 29 | +(NSString*)humanReadableSizeForBytes:(long long int)bytes withDecimalMeasureSystem:(BOOL)measure 30 | { 31 | NSString* result = @""; 32 | int degree = 0; 33 | int minorBytes = 0; 34 | int divisor = measure ? 1000 : 1024; 35 | 36 | while (bytes/divisor && degree < 8) 37 | { 38 | minorBytes=bytes%divisor; 39 | bytes/=divisor; 40 | degree++; 41 | } 42 | 43 | switch (degree) 44 | { 45 | case 0: result = @"b"; break; 46 | case 1: result = @"Kb"; break; 47 | case 2: result = @"Mb"; break; 48 | case 3: result = @"Gb"; break; 49 | case 4: result = @"Tb"; break; 50 | case 5: result = @"Pb"; break; 51 | case 6: result = @"Eb"; break; 52 | case 7: result = @"Zb"; break; 53 | default: result = @"Yb"; break; 54 | } 55 | 56 | minorBytes = ((minorBytes*1000)/divisor)/100; 57 | if (minorBytes) result = [NSString stringWithFormat:@".%d%@",minorBytes,result]; 58 | 59 | return [NSString stringWithFormat:@"%lld%@",bytes,result]; 60 | } 61 | +(NSString*)stringWithHexString:(NSString*)string 62 | { 63 | NSMutableString * newString = [[NSMutableString alloc] init]; 64 | NSScanner *scanner = [[NSScanner alloc] initWithString:string]; 65 | unsigned value; 66 | while ([scanner scanHexInt:&value]) 67 | { 68 | if (value==0) [newString appendString:@"\0"]; 69 | else [newString appendFormat:@"%c",(char)(value & 0xFF)]; 70 | } 71 | return newString; 72 | } 73 | +(NSString*)stringByRemovingEvenCharsFromString:(NSString*)text 74 | { 75 | NSMutableString* text2 = [NSMutableString stringWithString:@""]; 76 | int x; 77 | for (x = 0; x < text.length; x = x+2) 78 | { 79 | [text2 appendString:[text substringWithRange:NSMakeRange(x,1)]]; 80 | } 81 | return text2; 82 | } 83 | 84 | -(NSRange)rangeAfterString:(NSString*)before andBeforeString:(NSString*)after 85 | { 86 | NSRange beforeRange = before ? [self rangeOfString:before] : NSMakeRange(0, 0); 87 | 88 | if (beforeRange.location == NSNotFound) 89 | { 90 | return NSMakeRange(NSNotFound, 0); 91 | } 92 | 93 | CGFloat afterBeforeRangeStart = beforeRange.location + beforeRange.length; 94 | NSRange afterBeforeRange = NSMakeRange(afterBeforeRangeStart, self.length - afterBeforeRangeStart); 95 | NSRange afterRange = after ? [self rangeOfString:after options:0 range:afterBeforeRange] : NSMakeRange(NSNotFound, 0); 96 | 97 | if (afterRange.location == NSNotFound) 98 | { 99 | return afterBeforeRange; 100 | } 101 | 102 | return NSMakeRange(afterBeforeRangeStart, afterRange.location - afterBeforeRangeStart); 103 | } 104 | -(NSString*)getFragmentAfter:(NSString*)before andBefore:(NSString*)after 105 | { 106 | NSRange range = [self rangeAfterString:before andBeforeString:after]; 107 | if (range.location != NSNotFound) return [self substringWithRange:range]; 108 | return nil; 109 | } 110 | 111 | -(int)initialIntValue 112 | { 113 | NSMutableString* originalString = [self mutableCopy]; 114 | NSMutableString* newString = [NSMutableString stringWithString:@""]; 115 | NSRange firstCharRange = NSMakeRange(0, 1); 116 | 117 | while (originalString.length > 0 && [originalString characterAtIndex:0] >= '0' && [originalString characterAtIndex:0] <= '9') 118 | { 119 | [newString appendString:[originalString substringWithRange:firstCharRange]]; 120 | [originalString deleteCharactersInRange:firstCharRange]; 121 | } 122 | 123 | return newString.intValue; 124 | } 125 | 126 | +(NSString*)stringWithContentsOfFile:(NSString*)file encoding:(NSStringEncoding)enc 127 | { 128 | if (![[NSFileManager defaultManager] fileExistsAtPath:file]) return nil; 129 | 130 | NSError* error; 131 | NSString* string = [self stringWithContentsOfFile:file encoding:enc error:&error]; 132 | 133 | if (error) 134 | { 135 | [NSAlert showAlertOfType:NSAlertTypeError withMessage:[NSString stringWithFormat:NSLocalizedString(@"Error while reading file: %@",nil), error.localizedDescription]]; 136 | } 137 | 138 | return string; 139 | } 140 | +(NSString*)stringWithContentsOfURL:(NSURL *)url encoding:(NSStringEncoding)enc timeoutInterval:(long long int)timeoutInterval 141 | { 142 | NSData* stringData = [NSData dataWithContentsOfURL:url timeoutInterval:timeoutInterval]; 143 | 144 | if (!stringData) 145 | { 146 | return nil; 147 | } 148 | 149 | return [[NSString alloc] initWithData:stringData encoding:enc]; 150 | } 151 | 152 | -(BOOL)writeToFile:(NSString*)path atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc 153 | { 154 | NSError* error; 155 | BOOL created = [self writeToFile:path atomically:useAuxiliaryFile encoding:enc error:&error]; 156 | 157 | if (error) 158 | { 159 | [NSAlert showAlertOfType:NSAlertTypeError withMessage:[NSString stringWithFormat:NSLocalizedString(@"Error while writting file: %@",nil), error.localizedDescription]]; 160 | } 161 | 162 | return created; 163 | } 164 | 165 | -(BOOL)isAValidURL 166 | { 167 | if (![self hasPrefix:@"http://"] && ![self hasPrefix:@"https://"] && ![self hasPrefix:@"ftp://"]) return false; 168 | 169 | NSURL *candidateURL = [NSURL URLWithString:self]; 170 | return candidateURL && candidateURL.scheme && candidateURL.host; 171 | } 172 | 173 | @end 174 | -------------------------------------------------------------------------------- /WineskinApp/Wineskin_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'Wineskin' target in the 'Wineskin' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | 9 | // That defines if the logs in the program will appear or not 10 | #ifdef DEBUG 11 | #define NSDebugLog NSLog 12 | #else 13 | #define NSDebugLog(...) 14 | #endif 15 | 16 | #define WINESKIN_APP_NAME @"Wineskin" 17 | #define WINESKIN_VERSION [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"] 18 | #define RETINA_SCALE [NSScreen mainScreen].userSpaceScaleFactor 19 | #define ALERT_ICON_SIZE 512 20 | 21 | #define NSTemporaryPath(p) [NSString stringWithFormat:@"%@%@",NSTemporaryDirectory(),p] 22 | 23 | // Other important values 24 | #define PROGRESS_VIEW_BAR_PRECISION 1000 25 | #define PROGRESS_VIEW_UPDATE_INTERVAL 1.0 26 | #define TIMEOUT_WINESKIN_CLIENT_REQUEST 5 27 | #define TIMEOUT_REGULAR_DOWNLOAD 120 28 | 29 | #define WINDOWS_PATH_PROGRAM_FILES_PLACEHOLDER @"%ProgramFiles%" 30 | 31 | #define TRUE_STRING @"true" 32 | #define FALSE_STRING @"false" 33 | 34 | #define BINARY_7ZA [NSString stringWithFormat:@"%@/7za",WINESKIN_LIBRARY_FOLDER] 35 | #define BINARY_QLMANAGE @"/System/Library/Frameworks/QuickLook.framework/Versions/A/Resources/quicklookd.app/Contents/MacOS/qlmanage" 36 | 37 | // Wineskin Plist entries 38 | #define WINESKIN_WRAPPER_PLIST_KEY_NAME @"CFBundleName" 39 | #define WINESKIN_WRAPPER_PLIST_KEY_WINESKIN_VERSION @"CFBundleVersion" 40 | #define WINESKIN_WRAPPER_PLIST_KEY_VERSION @"CFBundleShortVersionString" 41 | #define WINESKIN_WRAPPER_PLIST_KEY_ICON_PATH @"CFBundleIconFile" 42 | #define WINESKIN_WRAPPER_PLIST_KEY_IDENTIFIER @"CFBundleIdentifier" 43 | #define WINESKIN_WRAPPER_PLIST_KEY_EXECUTABLE @"CFBundleExecutable" 44 | #define WINESKIN_WRAPPER_PLIST_KEY_SINGLE_CPU @"Disable CPUs" 45 | #define WINESKIN_WRAPPER_PLIST_KEY_MAX_OF_10240_FILES @"set max files" 46 | #define WINESKIN_WRAPPER_PLIST_KEY_ASSOCIATIONS @"Associations" 47 | #define WINESKIN_WRAPPER_PLIST_KEY_AUTOMATICALLY_DETECT_GPU @"Try To Use GPU Info" 48 | #define WINESKIN_WRAPPER_PLIST_KEY_RUN_PATH @"Program Name and Path" 49 | #define WINESKIN_WRAPPER_PLIST_KEY_RUN_PATH_IS_NOT_EXE @"use start.exe" 50 | #define WINESKIN_WRAPPER_PLIST_KEY_RUN_PATH_FLAGS @"Program Flags" 51 | #define WINESKIN_WRAPPER_PLIST_KEY_SCREEN_OPTIONS_ARE_AUTOMATIC @"Use RandR" 52 | #define WINESKIN_WRAPPER_PLIST_KEY_SCREEN_OPTIONS_IS_FULLSCREEN @"Fullscreen" 53 | #define WINESKIN_WRAPPER_PLIST_KEY_SCREEN_OPTIONS_CONFIGURATIONS @"Resolution" 54 | #define WINESKIN_WRAPPER_PLIST_KEY_DEBUG_MODE @"Debug Mode" 55 | #define WINESKIN_WRAPPER_PLIST_KEY_GAMMA_CORRECTION @"Gamma Correction" 56 | #define WINESKIN_WRAPPER_PLIST_KEY_INSTALLER_WITH_NORMAL_WINDOWS @"force Installer to normal windows" 57 | #define WINESKIN_WRAPPER_PLIST_KEY_WINETRICKS_SILENT @"Winetricks silent" 58 | #define WINESKIN_WRAPPER_PLIST_KEY_WINETRICKS_NOLOGS @"Winetricks disable logging" 59 | #define WINESKIN_WRAPPER_PLIST_KEY_ENABLE_FNTOGGLE @"IsFnToggleEnabled" 60 | #define WINESKIN_WRAPPER_PLIST_KEY_DISABLE_MONO_GECKO @"Skip Mono & Gecko" 61 | #define WINESKIN_WRAPPER_PLIST_KEY_ENABLE_FNTOGGLE @"IsFnToggleEnabled" 62 | 63 | // Wineskin Plist values 64 | #define WINESKIN_WRAPPER_PLIST_VALUE_SCREEN_OPTIONS_CURRENT_RESOLUTION @"Current Resolution" 65 | #define WINESKIN_WRAPPER_PLIST_VALUE_SCREEN_OPTIONS_NO_VIRTUAL_DESKTOP @"novd" 66 | 67 | // These are Wineskin website URLs, which are used to download the Master Wrapper and the Engines 68 | #define WINESKIN_DOMAIN "wineskin.urgesoftware.com" 69 | #define WINESKIN_WEBSITE @"http://wineskin.urgesoftware.com/" 70 | #define WINESKIN_WEBSITE_WRAPPER_FOLDER [NSString stringWithFormat:@"%@Wrapper/",WINESKIN_WEBSITE] 71 | #define WINESKIN_WEBSITE_ENGINES_FOLDER [NSString stringWithFormat:@"%@Engines/",WINESKIN_WEBSITE] 72 | #define WINESKIN_WEBSITE_ENGINE_BASE_FOLDER [NSString stringWithFormat:@"%@EngineBase/",WINESKIN_WEBSITE] 73 | 74 | #define WINESKIN_WEBSITE_LATEST_WRAPPER_VERSION [NSString stringWithFormat:@"%@NewestVersion.txt",WINESKIN_WEBSITE_WRAPPER_FOLDER] 75 | #define WINESKIN_WEBSITE_ENGINES_LIST [NSString stringWithFormat:@"%@EngineList.txt",WINESKIN_WEBSITE_ENGINES_FOLDER] 76 | 77 | // These are local paths used multiple times during the wrapper creation process that are related with Wineskin only 78 | #define WINESKIN_LIBRARY_FOLDER [NSString stringWithFormat:@"%@/Library/Application Support/Wineskin",NSHomeDirectory()] 79 | #define WINESKIN_LIBRARY_WRAPPER_FOLDER [NSString stringWithFormat:@"%@/Wrapper",WINESKIN_LIBRARY_FOLDER] 80 | #define WINESKIN_LIBRARY_ENGINES_FOLDER [NSString stringWithFormat:@"%@/Engines",WINESKIN_LIBRARY_FOLDER] 81 | #define WINESKIN_LIBRARY_ENGINE_BASE_FOLDER [NSString stringWithFormat:@"%@/EngineBase",WINESKIN_LIBRARY_FOLDER] 82 | 83 | // Engines Regex 84 | #define REGEX_WINESKIN_ENGINE @"WS[0-9]+Wine(CX|CXG|Staging)?(64Bit)?[0-9\\.]+[^\\n]*" 85 | #define REGEX_WINESKIN_WINE_ENGINE @"WS[0-9]+Wine(64Bit)?[0-9\\.]+[^\\n]*" 86 | #define REGEX_WINESKIN_STAGING_ENGINE @"WS[0-9]+WineStaging(64Bit)?[0-9\\.]+[^\\n]*" 87 | #define REGEX_WINESKIN_CROSSOVER_ENGINE @"WS[0-9]+WineCX(64Bit)?[0-9\\.]+[^\\n]*" 88 | #define REGEX_WINESKIN_CROSSOVER_GAMES_ENGINE @"WS[0-9]+WineCXG(64Bit)?[0-9\\.]+[^\\n]*" 89 | #define REGEX_WINESKIN_CONVERTABLE_OLD_WINE_ENGINE @"WS(5|6|7)Wine[0-9\\.]+[^\\n]*" 90 | #define REGEX_WINE_VERSION @"[0-9]+(\\.[0-9]+)*([-\\.]{1}rc[0-9]+)?" 91 | 92 | #define EXTENSIONS_COMPATIBLE_WITH_WINESKIN_WRAPPER @[@"exe",@"EXE",@"bat",@"BAT",@"msi",@"MSI"] 93 | #define EXTENSIONS_COMPATIBLE_WITH_RUN_PATH @[@"exe",@"EXE",@"bat",@"BAT",@"msi",@"MSI",@"lnk",@"LNK", @"inf",@"INF",@"desktop",@"appref-ms",@"url"] 94 | 95 | #define EXTENSIONS_COMPATIBLE_WITH_7Z @[@"xz",@"wim",@"arj",@"chm",@"cramfs",@"dmg",@"fat",@"hfs",@"lzh",@"lzma",@"mbr", @"nsis",@"ntfs",@"rar",@"squashfs",@"udf",@"vhd",@"wim",@"xar",@"z"] 96 | #define EXTENSIONS_COMPATIBLE_WITH_7ZA @[@"7z",@"zip",@"cab",@"arj",@"gzip",@"bzip2",@"tar",@"cpio",@"rpm",@"deb"] 97 | #define EXTENSIONS_COMPATIBLE_WITH_7Z_AND_7ZA [EXTENSIONS_COMPATIBLE_WITH_7Z arrayByAddingObjectsFromArray:EXTENSIONS_COMPATIBLE_WITH_7ZA] 98 | 99 | // Plist files paths 100 | #define PLIST_PATH_WINESKIN_CUSTOM_EXE @"/Contents/Info.plist.cexe" 101 | #define PLIST_PATH_WINESKIN_WRAPPER @"/Contents/Info.plist" 102 | 103 | #define DRIVES_TYPE_VALUE_AUTO @"auto" 104 | #define DRIVES_TYPE_VALUE_HD @"hd" 105 | #define DRIVES_TYPE_VALUE_CDROM @"cdrom" 106 | #define DRIVES_TYPE_VALUE_SHARED @"ramdisk" 107 | #define DRIVES_TYPE_VALUE_FLOPPY @"floppy" 108 | -------------------------------------------------------------------------------- /WineskinLauncher/WineskinLauncherAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // WineskinAppDelegate.h 3 | // Wineskin 4 | // 5 | // Copyright 2014 by The Wineskin Project and Urge Software LLC All rights reserved. 6 | // Licensed for use under the LGPL 7 | // 8 | 9 | #import 10 | #import "WineStart.h" 11 | #import "NSPortManager.h" 12 | 13 | @interface WineskinLauncherAppDelegate : NSObject 14 | { 15 | NSPortManager* portManager; 16 | 17 | BOOL primaryRun; 18 | BOOL wrapperRunning; 19 | IBOutlet NSWindow *window; 20 | IBOutlet NSProgressIndicator *waitWheel; 21 | NSFileManager *fm; 22 | NSMutableArray *globalFilesToOpen; 23 | NSString *contentsFold; //Contents folder in the wrapper 24 | NSString *frameworksFold; //Frameworks folder in the wrapper 25 | NSString *appNameWithPath; //full path to and including the app name 26 | NSString *appName; //name of our app/wrapper 27 | NSString *lockfile; //lockfile being used to know if the app is already in use 28 | NSString *tmpFolder; //where tmp files can be made and used to be specific to just this wrapper 29 | NSString *tmpwineFolder; //wine makes its own tmp & wineserver uses it for each wine process 30 | NSString *winePrefix; //the $WINEPREFIX 31 | NSMutableString *theDisplayNumber; //the Display Number to use 32 | NSString *wineLogFile; //location of wine log file 33 | NSString *wineTempLogFile; //location of wine temp log file 34 | NSString *x11LogFile; //location of x11 log file 35 | BOOL fullScreenOption; //wether running fullscreen or rootless (RandR is rootless) 36 | BOOL useGamma; //wether or not gamma correction will be checked for 37 | BOOL useXQuartz; //YES if using XQuartz over Mac Driver 38 | NSMutableString *gammaCorrection; //added in gamma correction 39 | NSMutableString *fullScreenResolutionBitDepth; //fullscreen bit depth for X server 40 | NSString *currentResolution; //the resolution that was running when the wrapper was started 41 | NSString *wrapperBundlePID; //PID of running wrapper bundle 42 | NSMutableString *xQuartzX11BinPID; //PID of running XQuartz X11.bin (only needed for Override->Fullscreen) 43 | NSString *xQuartzBundlePID; //PID of running XQuartz bundle (only needed for Override->Fullscreen) 44 | BOOL debugEnabled; //set if debug mode is being run, to make logs 45 | BOOL isIce; //YES if ICE engine being used 46 | BOOL removeX11TraceFromLog; //YES if Wineskin added the X11 trace to winedebug to remove them from the output log 47 | NSString *dyldFallBackLibraryPath; //the path for DYLD_FALLBACK_LIBRARY_PATH 48 | NSString *fontFix; //force freetype into using rendering mode from pre 2.7 49 | BOOL useMacDriver; //YES if using Mac Driver over X11 50 | NSString *wineServerName; //the name of the Wineserver we'll be launching 51 | NSString *wineName; //the name of the Wine process we'll be launching 52 | NSString *wine64Name; //the name of the Wine64 process we'll be launching 53 | NSString *wineStagingName; //the name of the Wine-preloader process we'll be launching 54 | NSString *wineStaging64Name; //the name of the Wine64-preloader process we'll be launching 55 | int bundleRandomInt1; 56 | int bundleRandomInt2; 57 | 58 | } 59 | // if Fn or Alt held on run 60 | - (void) doSpecialStartup; 61 | 62 | //run system command with output returned 63 | - (NSString *)systemCommand:(NSString *)command; 64 | 65 | //the main running of the program... 66 | - (void)mainRun:(NSArray*)filesToOpen; 67 | 68 | //Any time its re-ran after its already running, for like opening extra files or Custom EXEs 69 | - (void)secondaryRun:(NSArray*)filesToOpen; 70 | 71 | //a second instance of program is launched, needs to pass into back to main so it can run. 72 | - (void)handleWineskinLauncherDirectSecondaryRun:(WineStart *)wineStart; 73 | 74 | //used to change the gamma setting since Xquartz cannot yet 75 | - (void)setGamma:(NSString *)inputValue; 76 | 77 | //used to change the global screen resolution for overriding randr 78 | - (void)setResolution:(NSString *)reso; 79 | 80 | //returns the current screen resolution 81 | - (NSString *)getScreenResolution; 82 | 83 | //Makes an Array with a list of PIDs that match the process name 84 | - (NSArray *)makePIDArray:(NSString *)processToLookFor; 85 | 86 | //returns PID of new process (after it appears) 87 | - (NSString *)getNewPid:(NSString *)processToLookFor from:(NSArray *)firstPIDlist confirm:(bool)confirm_pid; 88 | 89 | //sets the drive_c/user/Wineskin folder correctly for a run 90 | - (void)setUserFolders:(BOOL)doSymlinks; 91 | 92 | //Makes sure the current user owns the winepeefix, or Wine will not run 93 | - (void)fixWinePrefixForCurrentUser; 94 | 95 | //Tries to get the GPU info and enter it in the Wine Registry, use before starting Wine 96 | - (void)tryToUseGPUInfo; 97 | 98 | //remove GPU info from Registry 99 | - (void)removeGPUInfo; 100 | 101 | //returns the correct line needed for startXQuartz to get the right quartz-wm started 102 | - (NSString *)setWindowManager; 103 | 104 | //checks if Mac is set in Wine 105 | - (BOOL)checkToUseMacDriver; 106 | 107 | //check if XQuartz is installed 108 | -(BOOL)isXQuartzInstalled; 109 | 110 | //starts up XQuartz 111 | - (void)startXQuartz; 112 | 113 | //bring the app to the front most 114 | - (void)bringToFront:(NSString *)thePid; 115 | 116 | //installs ICE files 117 | - (void)installEngine; 118 | 119 | //Changes VD Desktop user.reg entries to a given virtual desktop 120 | - (void)setToVirtualDesktop:(NSString *)resolution; 121 | 122 | //Changes VD Desktop user.reg entires to not have a virtual desktop 123 | - (void)setToNoVirtualDesktop; 124 | 125 | //reads a file and passes back contents as an array of strings 126 | - (NSArray *)readFileToStringArray:(NSString *)theFile; 127 | 128 | //writes an array to a normal text file, each entry on a line. 129 | - (void)writeStringArray:(NSArray *)theArray toFile:(NSString *)theFile; 130 | 131 | //returns true if running PID has the specified name 132 | - (BOOL)isPID:(NSString *)pid named:(NSString *)name; 133 | 134 | //returns true if Wineserver for this wrapper is running 135 | - (BOOL)isWineserverRunning; 136 | 137 | //fix wine and wineserver names in engines to be unique for launch 138 | - (void)fixWineExecutableNames; 139 | 140 | //fix wine and wineserver names 141 | - (void)fixWine32ExecutableNames; 142 | 143 | //fix wine, wine64 and wineserver names 144 | - (void)fixWine64ExecutableNames; 145 | 146 | //fix wine-preloader and wineserver names 147 | - (void)fixWineStagingExecutableNames; 148 | 149 | //fix wine-preloader, wine64-preloader and wineserver names 150 | - (void)fixWineStaging64ExecutableNames; 151 | 152 | //start wine 153 | - (void)startWine:(WineStart *)wineStart; 154 | 155 | //background monitoring while Wine is running 156 | - (void)sleepAndMonitor; 157 | 158 | //run when shutting down 159 | - (void)cleanUpAndShutDown; 160 | 161 | @end 162 | -------------------------------------------------------------------------------- /WineskinApp/remakedefaults.reg: -------------------------------------------------------------------------------- 1 | REGEDIT4 2 | 3 | [HKEY_CURRENT_USER\Control Panel\Colors] 4 | "ActiveBorder"="212 212 212" 5 | "background"="0 0 0" 6 | "ButtonAlternateFace"="181 181 181" 7 | "ButtonFace"="212 212 212" 8 | "ButtonHilight"="255 255 255" 9 | "ButtonLight"="212 212 212" 10 | "ButtonShadow"="128 128 128" 11 | "ButtonText"="0 0 0" 12 | "GradientInactiveTitle"="192 192 192" 13 | "GrayText"="128 128 128" 14 | "HotTrackingColor"="0 0 200" 15 | "InactiveBorder"="212 212 212" 16 | "InactiveTitle"="128 128 128" 17 | "InactiveTitleText"="212 212 212" 18 | "Menu"="212 212 212" 19 | "MenuBar"="212 212 212" 20 | "Scrollbar"="212 212 212" 21 | "Window"="255 255 255" 22 | "WindowFrame"="0 0 0" 23 | 24 | [HKEY_CURRENT_USER\Control Panel\Desktop] 25 | "FontSmoothing"="1" 26 | 27 | [HKEY_CURRENT_USER\Software\Wine\Direct3D] 28 | 29 | [HKEY_CURRENT_USER\Software\Wine\Drivers] 30 | "Graphics"="mac,x11" 31 | "Audio"="coreaudio" 32 | 33 | [HKEY_CURRENT_USER\Software\Wine\Mac Driver] 34 | "CaptureDisplaysForFullscreen"="y" 35 | 36 | [HKEY_CLASSES_ROOT\htmlfile\shell\open\command] 37 | @="C:\\windows\\system32\\winebrowser.exe -nohome %1" 38 | 39 | [HKEY_CLASSES_ROOT\htmlfile\shell\opennew\command] 40 | @="C:\\windows\\system32\\winebrowser.exe -nohome %1" 41 | 42 | [HKEY_CLASSES_ROOT\http\shell\open\command] 43 | @="C:\\windows\\system32\\winebrowser.exe -nohome %1" 44 | 45 | [HKEY_CLASSES_ROOT\https\shell\open\command] 46 | @="C:\\windows\\system32\\winebrowser.exe -nohome %1" 47 | 48 | [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders] 49 | "AppData"="C:\\users\\Wineskin\\Application Data" 50 | "Cache"="C:\\users\\Wineskin\\Local Settings\\Temporary Internet Files" 51 | "Cookies"="C:\\users\\Wineskin\\Cookies" 52 | "Desktop"="C:\\users\\Wineskin\\Desktop" 53 | "Favorites"="C:\\users\\Wineskin\\Favorites" 54 | "Fonts"="C:\\windows\\Fonts" 55 | "History"="C:\\users\\Wineskin\\Local Settings\\History" 56 | "Local AppData"="C:\\users\\Wineskin\\Local Settings\\Application Data" 57 | "My Music"="C:\\users\\Wineskin\\My Music" 58 | "My Pictures"="C:\\users\\Wineskin\\My Pictures" 59 | "My Videos"="C:\\users\\Wineskin\\My Videos" 60 | "NetHood"="C:\\users\\Wineskin\\NetHood" 61 | "Personal"="C:\\users\\Wineskin\\My Documents" 62 | "PrintHood"="C:\\users\\Wineskin\\PrintHood" 63 | "Programs"="C:\\users\\Wineskin\\Start Menu\\Programs" 64 | "Recent"="C:\\users\\Wineskin\\Recent" 65 | "SendTo"="C:\\users\\Wineskin\\SendTo" 66 | "Start Menu"="C:\\users\\Wineskin\\Start Menu" 67 | "StartUp"="C:\\users\\Wineskin\\Start Menu\\Programs\\StartUp" 68 | "Templates"="C:\\users\\Wineskin\\Templates" 69 | 70 | [HKEY_CURRENT_USER\Environment] 71 | "TEMP"="C:\\users\\Wineskin\\Temp" 72 | "TMP"="C:\\users\\Wineskin\\Temp" 73 | 74 | [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders] 75 | "AppData"=str(2):"%USERPROFILE%\\Application Data" 76 | "Cache"=str(2):"%USERPROFILE%\\Local Settings\\Temporary Internet Files" 77 | "Cookies"=str(2):"%USERPROFILE%\\Cookies" 78 | "Desktop"=str(2):"%USERPROFILE%\\Desktop" 79 | "Favorites"=str(2):"%USERPROFILE%\\Favorites" 80 | "Fonts"=str(2):"C:\\windows\\Fonts" 81 | "History"=str(2):"%USERPROFILE%\\Local Settings\\History" 82 | "Local AppData"=str(2):"%USERPROFILE%\\Local Settings\\Application Data" 83 | "My Music"=str(2):"%USERPROFILE%\\My Music" 84 | "My Pictures"=str(2):"%USERPROFILE%\\My Pictures" 85 | "My Videos"=str(2):"%USERPROFILE%\\My Videos" 86 | "NetHood"=str(2):"%USERPROFILE%\\NetHood" 87 | "Personal"=str(2):"%USERPROFILE%\\My Documents" 88 | "PrintHood"=str(2):"%USERPROFILE%\\PrintHood" 89 | "Programs"=str(2):"%USERPROFILE%\\Start Menu\\Programs" 90 | "Recent"=str(2):"%USERPROFILE%\\Recent" 91 | "SendTo"=str(2):"%USERPROFILE%\\SendTo" 92 | "Start Menu"=str(2):"%USERPROFILE%\\Start Menu" 93 | "StartUp"=str(2):"%USERPROFILE%\\Start Menu\\Programs\\StartUp" 94 | "Templates"=str(2):"%USERPROFILE%\\Templates" 95 | 96 | [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders] 97 | "Common Administrative Tools"="C:\\users\\Public\\Start Menu\\Programs\\Administrative Tools" 98 | "Common AppData"="C:\\users\\Public\\Application Data" 99 | "Common Desktop"="C:\\users\\Public\\Desktop" 100 | "Common Documents"="C:\\users\\Public\\Documents" 101 | "Common Favorites"="C:\\users\\Public\\Favorites" 102 | "Common Programs"="C:\\users\\Public\\Start Menu\\Programs" 103 | "Common Start Menu"="C:\\users\\Public\\Start Menu" 104 | "Common StartUp"="C:\\users\\Public\\Start Menu\\Programs\\StartUp" 105 | "Common Templates"="C:\\users\\Public\\Templates" 106 | "CommonMusic"="C:\\users\\Public\\Music" 107 | "CommonPictures"="C:\\users\\Public\\Pictures" 108 | "CommonVideo"="C:\\users\\Public\\Videos" 109 | 110 | [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders] 111 | "Common Administrative Tools"=str(2):"%ALLUSERSPROFILE%\\Start Menu\\Programs\\Administrative Tools" 112 | "Common AppData"=str(2):"%ALLUSERSPROFILE%\\Application Data" 113 | "Common Desktop"=str(2):"%ALLUSERSPROFILE%\\Desktop" 114 | "Common Documents"=str(2):"%ALLUSERSPROFILE%\\Documents" 115 | "Common Favorites"=str(2):"%ALLUSERSPROFILE%\\Favorites" 116 | "Common Programs"=str(2):"%ALLUSERSPROFILE%\\Start Menu\\Programs" 117 | "Common Start Menu"=str(2):"%ALLUSERSPROFILE%\\Start Menu" 118 | "Common StartUp"=str(2):"%ALLUSERSPROFILE%\\Start Menu\\Programs\\StartUp" 119 | "Common Templates"=str(2):"%ALLUSERSPROFILE%\\Templates" 120 | "CommonMusic"=str(2):"%ALLUSERSPROFILE%\\Music" 121 | "CommonPictures"=str(2):"%ALLUSERSPROFILE%\\Pictures" 122 | "CommonVideo"=str(2):"%ALLUSERSPROFILE%\\Videos" 123 | 124 | [HKEY_USERS\.Default\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders] 125 | "AppData"="C:\\users\\Wineskin\\Application Data" 126 | "Cache"="C:\\users\\Wineskin\\Local Settings\\Temporary Internet Files" 127 | "Cookies"="C:\\users\\Wineskin\\Cookies" 128 | "Desktop"="C:\\users\\Wineskin\\Desktop" 129 | "Favorites"="C:\\users\\Wineskin\\Favorites" 130 | "Fonts"="C:\\windows\\Fonts" 131 | "History"="C:\\users\\Wineskin\\Local Settings\\History" 132 | "Local AppData"="C:\\users\\Wineskin\\Local Settings\\Application Data" 133 | "My Music"="C:\\users\\Wineskin\\My Music" 134 | "My Pictures"="C:\\users\\Wineskin\\My Pictures" 135 | "My Videos"="C:\\users\\Wineskin\\My Videos" 136 | "NetHood"="C:\\users\\Wineskin\\NetHood" 137 | "Personal"="C:\\users\\Wineskin\\My Documents" 138 | "PrintHood"="C:\\users\\Wineskin\\PrintHood" 139 | "Programs"="C:\\users\\Wineskin\\Start Menu\\Programs" 140 | "Recent"="C:\\users\\Wineskin\\Recent" 141 | "SendTo"="C:\\users\\Wineskin\\SendTo" 142 | "Start Menu"="C:\\users\\Wineskin\\Start Menu" 143 | "StartUp"="C:\\users\\Wineskin\\Start Menu\\Programs\\StartUp" 144 | "Templates"="C:\\users\\Wineskin\\Templates" 145 | 146 | [HKEY_USERS\.Default\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders] 147 | "AppData"=str(2):"%USERPROFILE%\\Application Data" 148 | "Cache"=str(2):"%USERPROFILE%\\Local Settings\\Temporary Internet Files" 149 | "Cookies"=str(2):"%USERPROFILE%\\Cookies" 150 | "Desktop"=str(2):"%USERPROFILE%\\Desktop" 151 | "Favorites"=str(2):"%USERPROFILE%\\Favorites" 152 | "Fonts"=str(2):"C:\\windows\\Fonts" 153 | "History"=str(2):"%USERPROFILE%\\Local Settings\\History" 154 | "Local AppData"=str(2):"%USERPROFILE%\\Local Settings\\Application Data" 155 | "My Music"=str(2):"%USERPROFILE%\\My Music" 156 | "My Pictures"=str(2):"%USERPROFILE%\\My Pictures" 157 | "My Videos"=str(2):"%USERPROFILE%\\My Videos" 158 | "NetHood"=str(2):"%USERPROFILE%\\NetHood" 159 | "Personal"=str(2):"%USERPROFILE%\\My Documents" 160 | "PrintHood"=str(2):"%USERPROFILE%\\PrintHood" 161 | "Programs"=str(2):"%USERPROFILE%\\Start Menu\\Programs" 162 | "Recent"=str(2):"%USERPROFILE%\\Recent" 163 | "SendTo"=str(2):"%USERPROFILE%\\SendTo" 164 | "Start Menu"=str(2):"%USERPROFILE%\\Start Menu" 165 | "StartUp"=str(2):"%USERPROFILE%\\Start Menu\\Programs\\StartUp" 166 | "Templates"=str(2):"%USERPROFILE%\\Templates" 167 | -------------------------------------------------------------------------------- /WineskinApp/NSAlert+Extension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSAlert+Extension.m 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/02/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import "NSAlert+Extension.h" 10 | 11 | #import "NSThread+Extension.h" 12 | 13 | #define INPUT_DIALOG_MESSAGE_FIELD_FRAME NSMakeRect(0, 0, 260, 24) 14 | 15 | @implementation NSImage (PKImageForAlert) 16 | -(NSImage*)getTintedImageWithColor:(NSColor*)color 17 | { 18 | NSImage* tinted = [[NSImage alloc] initWithSize:self.size]; 19 | [tinted lockFocus]; 20 | 21 | NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height); 22 | [self drawInRect:imageRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; 23 | 24 | [color set]; 25 | NSRectFillUsingOperation(imageRect, NSCompositeSourceAtop); 26 | 27 | [tinted unlockFocus]; 28 | return tinted; 29 | } 30 | +(NSImage*)stopProgressIcon 31 | { 32 | NSImage* icon = [NSImage imageNamed:NSImageNameStopProgressFreestandingTemplate]; 33 | [icon setSize:NSMakeSize(ALERT_ICON_SIZE, ALERT_ICON_SIZE)]; 34 | return [icon getTintedImageWithColor:[NSColor redColor]]; 35 | } 36 | +(NSImage*)cautionIcon 37 | { 38 | NSImage* icon = [NSImage imageNamed:NSImageNameCaution]; 39 | [icon setSize:NSMakeSize(ALERT_ICON_SIZE, ALERT_ICON_SIZE)]; 40 | return icon; 41 | } 42 | @end 43 | 44 | @implementation NSAlert (PKAlert) 45 | +(NSString*)titleForAlertType:(NSAlertType)alertType 46 | { 47 | switch (alertType) 48 | { 49 | case NSAlertTypeCustom: 50 | return WINESKIN_APP_NAME; 51 | 52 | case NSAlertTypeSuccess: 53 | return NSLocalizedString(@"Success",nil); 54 | 55 | case NSAlertTypeWarning: 56 | return NSLocalizedString(@"Warning",nil); 57 | 58 | case NSAlertTypeWinetricks: 59 | return NSLocalizedString(@"Winetricks No Logs Mode",nil); 60 | 61 | case NSAlertTypeError: 62 | return NSLocalizedString(@"Error",nil); 63 | 64 | case NSAlertTypeCritical: 65 | return NSLocalizedString(@"Error",nil); 66 | 67 | default: break; 68 | } 69 | 70 | return @""; 71 | } 72 | -(void)setIconWithAlertType:(NSAlertType)alertType 73 | { 74 | switch (alertType) 75 | { 76 | case NSAlertTypeWarning: 77 | [self setAlertStyle:NSCriticalAlertStyle]; 78 | break; 79 | case NSAlertTypeWinetricks: 80 | [self setAlertStyle:NSCriticalAlertStyle]; 81 | break; 82 | case NSAlertTypeError: 83 | [self setIcon:[NSImage cautionIcon]]; 84 | break; 85 | case NSAlertTypeCritical: 86 | [self setIcon:[NSImage stopProgressIcon]]; 87 | break; 88 | default: break; 89 | } 90 | } 91 | 92 | +(void)showAlertMessageWithException:(NSException*)exception 93 | { 94 | [self showAlertOfType:NSAlertTypeError withMessage:[NSString stringWithFormat:@"%@: %@", exception.name, exception.reason]]; 95 | } 96 | +(void)showAlertOfType:(NSAlertType)alertType withMessage:(NSString*)message 97 | { 98 | NSString* alertTitle = [self titleForAlertType:alertType]; 99 | 100 | [self showAlertMessage:message withTitle:alertTitle withSettings:^(NSAlert* alert) 101 | { 102 | [alert setIconWithAlertType:alertType]; 103 | }]; 104 | } 105 | +(void)showAlertMessage:(NSString*)message withTitle:(NSString*)title withSettings:(void (^)(NSAlert* alert))optionsForAlert 106 | { 107 | if ([NSThread isMainThread]) 108 | { 109 | NSAlert* msgBox = [[NSAlert alloc] init]; 110 | [msgBox setMessageText: title]; 111 | [msgBox addButtonWithTitle:NSLocalizedString(@"OK",nil)]; 112 | [msgBox setInformativeText: message]; 113 | 114 | optionsForAlert(msgBox); 115 | 116 | [msgBox runModal]; 117 | } 118 | else 119 | { 120 | NSCondition* lock = [[NSCondition alloc] init]; 121 | [NSThread dispatchBlockInMainQueue:^ 122 | { 123 | NSAlert* msgBox = [[NSAlert alloc] init]; 124 | [msgBox setMessageText: title]; 125 | [msgBox addButtonWithTitle:NSLocalizedString(@"OK",nil)]; 126 | [msgBox setInformativeText: message]; 127 | 128 | optionsForAlert(msgBox); 129 | 130 | [msgBox runModal]; 131 | [lock signal]; 132 | [lock unlock]; 133 | }]; 134 | [lock lock]; 135 | [lock wait]; 136 | [lock unlock]; 137 | } 138 | } 139 | 140 | +(BOOL)showBooleanAlertMessage:(NSString*)message withTitle:(NSString*)title withDefault:(BOOL)yesDefault 141 | { 142 | return [self showBooleanAlertMessage:message withTitle:title withDefault:yesDefault withSettings:^(NSAlert* alert) {}]; 143 | } 144 | +(BOOL)showBooleanAlertOfType:(NSAlertType)alertType withMessage:(NSString*)message withDefault:(BOOL)yesDefault 145 | { 146 | NSString* alertTitle = [self titleForAlertType:alertType]; 147 | 148 | return [self showBooleanAlertMessage:message withTitle:alertTitle withDefault:yesDefault withSettings:^(NSAlert* alert) 149 | { 150 | [alert setIconWithAlertType:alertType]; 151 | }]; 152 | } 153 | +(BOOL)showBooleanAlertMessage:(NSString*)message withTitle:(NSString*)title withDefault:(BOOL)yesDefault withSettings:(void (^)(NSAlert* alert))setAlertSettings 154 | { 155 | __block NSString* defaultButton; 156 | __block NSString* alternateButton; 157 | if (yesDefault) 158 | { 159 | defaultButton = NSLocalizedString(@"Yes",nil); 160 | alternateButton = NSLocalizedString(@"No",nil); 161 | } 162 | else 163 | { 164 | defaultButton = NSLocalizedString(@"No",nil); 165 | alternateButton = NSLocalizedString(@"Yes",nil); 166 | } 167 | 168 | if ([NSThread isMainThread]) 169 | { 170 | BOOL value = !yesDefault; 171 | 172 | NSAlert *alert = [NSAlert alertWithMessageText:title != nil ? title : @"" 173 | defaultButton:defaultButton 174 | alternateButton:alternateButton 175 | otherButton:nil 176 | informativeTextWithFormat:@"%@",message]; 177 | 178 | setAlertSettings(alert); 179 | 180 | NSInteger button = [alert runModal]; 181 | if (button == NSAlertDefaultReturn) value = yesDefault; 182 | 183 | return value; 184 | } 185 | else 186 | { 187 | NSCondition* lock = [[NSCondition alloc] init]; 188 | __block BOOL value = !yesDefault; 189 | [NSThread dispatchBlockInMainQueue:^ 190 | { 191 | NSAlert *alert = [NSAlert alertWithMessageText:title != nil ? title : @"" 192 | defaultButton:defaultButton 193 | alternateButton:alternateButton 194 | otherButton:nil 195 | informativeTextWithFormat:@"%@",message]; 196 | 197 | setAlertSettings(alert); 198 | 199 | NSInteger button = [alert runModal]; 200 | if (button == NSAlertDefaultReturn) value = yesDefault; 201 | 202 | [lock signal]; 203 | [lock unlock]; 204 | }]; 205 | 206 | [lock lock]; 207 | [lock wait]; 208 | [lock unlock]; 209 | return value; 210 | } 211 | } 212 | 213 | +(NSString*)inputDialogWithTitle:(NSString*)prompt message:(NSString*)message defaultValue:(NSString*)defaultValue 214 | { 215 | if ([NSThread isMainThread]) 216 | { 217 | NSAlert *alert = [NSAlert alertWithMessageText:prompt 218 | defaultButton:NSLocalizedString(@"OK",nil) 219 | alternateButton:NSLocalizedString(@"Cancel",nil) 220 | otherButton:nil 221 | informativeTextWithFormat:@"%@",message]; 222 | 223 | NSTextField *input = [[NSTextField alloc] initWithFrame:INPUT_DIALOG_MESSAGE_FIELD_FRAME]; 224 | if (defaultValue) [input setStringValue:defaultValue]; 225 | [alert setAccessoryView:input]; 226 | 227 | if ([alert runModal] == NSAlertDefaultReturn) 228 | { 229 | [input validateEditing]; 230 | return [input stringValue]; 231 | } 232 | 233 | return nil; 234 | } 235 | else 236 | { 237 | NSCondition* lock = [[NSCondition alloc] init]; 238 | __block NSString* value = nil; 239 | [NSThread dispatchBlockInMainQueue:^ 240 | { 241 | NSAlert *alert = [NSAlert alertWithMessageText:prompt 242 | defaultButton:NSLocalizedString(@"OK",nil) 243 | alternateButton:NSLocalizedString(@"Cancel",nil) 244 | otherButton:nil 245 | informativeTextWithFormat:@"%@",message]; 246 | 247 | NSTextField *input = [[NSTextField alloc] initWithFrame:INPUT_DIALOG_MESSAGE_FIELD_FRAME]; 248 | if (defaultValue) [input setStringValue:defaultValue]; 249 | [alert setAccessoryView:input]; 250 | 251 | if ([alert runModal] == NSAlertDefaultReturn) 252 | { 253 | [input validateEditing]; 254 | value = [input stringValue]; 255 | } 256 | [lock signal]; 257 | [lock unlock]; 258 | }]; 259 | [lock lock]; 260 | [lock wait]; 261 | [lock unlock]; 262 | 263 | return value; 264 | } 265 | } 266 | @end 267 | 268 | -------------------------------------------------------------------------------- /WineskinApp/NSWineskinPortDataWriter.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSWineskinPortDataWriter.m 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 08/06/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import "NSWineskinPortDataWriter.h" 10 | 11 | #import "NSPathUtilities.h" 12 | #import "NSWineskinEngine.h" 13 | 14 | #import "NSComputerInformation.h" 15 | 16 | #import "NSData+Extension.h" 17 | #import "NSTask+Extension.h" 18 | #import "NSString+Extension.h" 19 | #import "NSThread+Extension.h" 20 | #import "NSSavePanel+Extension.h" 21 | #import "NSFileManager+Extension.h" 22 | 23 | @implementation NSWineskinPortDataWriter 24 | 25 | //Saving registry changes instructions 26 | +(BOOL)removeFromRegistryAppsThatRunAutomaticallyOnWrapperStartupAtPort:(NSPortManager*)port 27 | { 28 | NSString* registry = @"[Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run]"; 29 | [port deleteRegistry:registry fromRegistryFileNamed:USER_REG]; 30 | return [port addRegistry:[NSString stringWithFormat:@"%@\n",registry] fromRegistryFileNamed:USER_REG]; 31 | } 32 | 33 | //Custom EXE Functions 34 | +(void)setMainExePath:(NSString*)exePath atPort:(NSPortManager*)port 35 | { 36 | if (!exePath) return; 37 | 38 | NSString* dictPath = [exePath stringByReplacingOccurrencesOfString:@"\n" withString:@""]; 39 | 40 | NSString* winPath = [NSPathUtilities getFileNameOfWindowsPath:dictPath]; 41 | NSString* flags = [NSPathUtilities getFlagsOfWindowsPath:dictPath]; 42 | 43 | if ([winPath contains:@"*"]) 44 | { 45 | NSString* newWinPath = [port completeWindowsPath:winPath]; 46 | if (newWinPath) winPath = newWinPath; 47 | } 48 | 49 | if ([[[winPath getFragmentAfter:nil andBefore:@":"] lowercaseString] isEqualToString:@"c"]) 50 | { 51 | [port setPlistObject:[winPath componentsSeparatedByString:@":"][1] forKey:WINESKIN_WRAPPER_PLIST_KEY_RUN_PATH]; 52 | [port setPlistObject:@(![winPath.lowercaseString hasSuffix:@".exe"]) forKey:WINESKIN_WRAPPER_PLIST_KEY_RUN_PATH_IS_NOT_EXE]; 53 | [port setPlistObject:flags forKey:WINESKIN_WRAPPER_PLIST_KEY_RUN_PATH_FLAGS]; 54 | } 55 | else 56 | { 57 | NSString* batFilePath = [NSString stringWithFormat:@"/exec%u.bat",arc4random()]; 58 | NSString* way = [NSPathUtilities getMacPathForWindowsPath:[NSString stringWithFormat:@"C:%@",batFilePath] ofWrapper:port.path]; 59 | 60 | [port setPlistObject:@TRUE forKey:WINESKIN_WRAPPER_PLIST_KEY_RUN_PATH_IS_NOT_EXE]; 61 | [port setPlistObject:batFilePath forKey:WINESKIN_WRAPPER_PLIST_KEY_RUN_PATH]; 62 | 63 | dictPath = [NSString stringWithFormat:@"\"%@\" %@",winPath,flags]; 64 | [dictPath writeToFile:way atomically:YES encoding:NSStringEncodingConversionAllowLossy]; 65 | } 66 | } 67 | +(void)setAutomaticScreenOptions:(BOOL)automatic fullscreen:(BOOL)fullscreen virtualDesktop:(BOOL)virtualDesktop resolution:(NSString*)resolution colors:(int)colors sleep:(int)sleep atPort:(NSPortManager*)port 68 | { 69 | [port setPlistObject:@(automatic) forKey:WINESKIN_WRAPPER_PLIST_KEY_SCREEN_OPTIONS_ARE_AUTOMATIC]; 70 | [port setPlistObject:@(fullscreen) forKey:WINESKIN_WRAPPER_PLIST_KEY_SCREEN_OPTIONS_IS_FULLSCREEN]; 71 | 72 | if (!automatic && virtualDesktop) 73 | { 74 | [port setPlistObject:[NSString stringWithFormat:@"%@x%dsleep%d", resolution,colors,sleep] 75 | forKey:WINESKIN_WRAPPER_PLIST_KEY_SCREEN_OPTIONS_CONFIGURATIONS]; 76 | } 77 | else 78 | { 79 | [port setPlistObject:[NSString stringWithFormat:@"novdx%dsleep%d",colors,sleep] 80 | forKey:WINESKIN_WRAPPER_PLIST_KEY_SCREEN_OPTIONS_CONFIGURATIONS]; 81 | } 82 | 83 | [port synchronizePlist]; 84 | } 85 | 86 | //Saving Data instructions 87 | +(BOOL)saveCloseSafely:(NSNumber*)closeSafely atPort:(NSPortManager*)port 88 | { 89 | NSString* wineskinQuitScriptPath = [NSString stringWithFormat:@"%@/Contents/Resources/Scripts/WineskinQuitScript", 90 | port.path]; 91 | NSString* text = [NSString stringWithContentsOfFile:wineskinQuitScriptPath encoding:NSASCIIStringEncoding]; 92 | NSArray* fragments = [text componentsSeparatedByString:@"wineskinAppChoice="]; 93 | NSString* part2; 94 | 95 | if ([closeSafely intValue] != 0) 96 | part2 = [fragments[1] stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:@"2"]; 97 | else part2 = [fragments[1] stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:@"1"]; 98 | 99 | text = [NSString stringWithFormat:@"%@wineskinAppChoice=%@",fragments[0],part2]; 100 | [text writeToFile:wineskinQuitScriptPath atomically:YES encoding:NSStringEncodingConversionAllowLossy]; 101 | 102 | return TRUE; 103 | } 104 | +(BOOL)saveCopyrightsAtPort:(NSPortManager*)port 105 | { 106 | NSString *companyFile = [NSString stringWithFormat:@"%@/Contents/Resources/English.lproj/InfoPlist.strings",port.path]; 107 | 108 | long year = (long)[[[NSCalendar currentCalendar] components:NSYearCalendarUnit fromDate:NSDate.date] year]; 109 | NSString* copyright = [NSString stringWithFormat:@"Copyright © 2014-%ld PortingKit.com. All rights reserved.", year]; 110 | 111 | NSString *companyContent = [NSString stringWithFormat:@"NSHumanReadableCopyright=\"%@\";",copyright]; 112 | [companyContent writeToFile:companyFile atomically:NO encoding:NSUTF8StringEncoding]; 113 | 114 | return TRUE; 115 | } 116 | +(BOOL)saveWinedbg:(BOOL)Debugger atPort:(NSPortManager*)port 117 | { 118 | NSString* key; 119 | NSString* value; 120 | NSString* winedbgRegistry = @"[Software\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\AeDebug]"; 121 | 122 | key = @"Debugger"; 123 | value = (Debugger ? @"\"false\"" : @"\"winedbg --auto %ld %ld\""); 124 | 125 | return [port setValues:@{key:value} forEntry:winedbgRegistry atRegistryFileNamed:SYSTEM_REG]; 126 | } 127 | +(BOOL)saveMacDriver:(BOOL)macdriver atPort:(NSPortManager*)port 128 | { 129 | NSString* driversRegistry = @"[Software\\\\Wine\\\\Drivers]"; 130 | NSString* graphicsValue = (macdriver ? @"\"mac,x11\"" : @"\"x11,mac\""); 131 | return [port setValues:@{@"Graphics":graphicsValue} forEntry:driversRegistry atRegistryFileNamed:USER_REG]; 132 | } 133 | +(BOOL)saveDirect3DBoost:(BOOL)direct3DBoost withEngine:(NSString*)engine atPort:(NSPortManager*)port 134 | { 135 | if (![NSWineskinEngine isCsmtCompatibleWithEngine:engine]) 136 | { 137 | return FALSE; 138 | } 139 | 140 | NSString* key; 141 | NSString* value; 142 | NSString* direct3DRegistry = @"[Software\\\\Wine\\\\Direct3D]"; 143 | 144 | if ([NSWineskinEngine csmtUsesNewRegistryWithEngine:engine]) 145 | { 146 | key = @"csmt"; 147 | value = (direct3DBoost ? @"dword:00000001" : @"dword:00000000"); 148 | } 149 | else 150 | { 151 | key = @"CSMT"; 152 | value = (direct3DBoost ? @"\"enabled\"" : @"\"disabled\""); 153 | } 154 | 155 | return [port setValues:@{key:value} forEntry:direct3DRegistry atRegistryFileNamed:USER_REG]; 156 | } 157 | +(BOOL)saveDecorateWindow:(BOOL)decorate atPort:(NSPortManager*)port 158 | { 159 | NSString* decorateValue = (decorate ? @"\"Y\"" : @"\"N\""); 160 | NSString* x11DriverRegistry = @"[Software\\\\Wine\\\\X11 Driver]"; 161 | 162 | return [port setValues:@{@"Managed" :decorateValue, 163 | @"Decorated":decorateValue} forEntry:x11DriverRegistry atRegistryFileNamed:USER_REG]; 164 | } 165 | +(BOOL)saveRetinaMode:(BOOL)retinaModeOn withEngine:(NSString*)engine atPort:(NSPortManager*)port 166 | { 167 | BOOL enableRetinaModeOn = retinaModeOn && [NSWineskinEngine isHighQualityModeCompatibleWithEngine:engine]; 168 | 169 | BOOL result = true; 170 | result = [port setValues:@{@"LogPixels": (enableRetinaModeOn ? @"dword:000000c0" : @"dword:00000060")} 171 | forEntry:@"[Control Panel\\\\Desktop]" atRegistryFileNamed:USER_REG]; 172 | if (!result) return false; 173 | 174 | result = [port setValues:@{@"RetinaMode": (enableRetinaModeOn ? @"\"Y\"" : @"\"N\"")} 175 | forEntry:@"[Software\\\\Wine\\\\Mac Driver]" atRegistryFileNamed:USER_REG]; 176 | return result; 177 | } 178 | 179 | +(BOOL)setMainExeName:(NSString*)name version:(NSString*)version icon:(NSImage*)icon path:(NSString*)path atPort:(NSPortManager*)port 180 | { 181 | [port setPlistObject:version forKey:WINESKIN_WRAPPER_PLIST_KEY_VERSION]; 182 | 183 | if (icon && [icon isKindOfClass:[NSImage class]]) 184 | { 185 | [port setIconWithImage:icon]; 186 | } 187 | 188 | [self setMainExePath:path atPort:port]; 189 | 190 | if (name) 191 | { 192 | [port setPlistObject:name forKey:WINESKIN_WRAPPER_PLIST_KEY_NAME]; 193 | [port setPlistObject:[NSString stringWithFormat:@"%@.Wineskin.prefs",name] forKey:WINESKIN_WRAPPER_PLIST_KEY_IDENTIFIER]; 194 | } 195 | 196 | [port synchronizePlist]; 197 | 198 | return YES; 199 | } 200 | +(BOOL)addCustomExeWithName:(NSString*)name version:(NSString*)version icon:(NSImage*)icon path:(NSString*)path atPortAtPath:(NSString*)portPath 201 | { 202 | NSString* customEXEapp = [NSString stringWithFormat:@"%@/Wineskin.app/Contents/Resources/CustomEXE.app",portPath]; 203 | NSString* customEXEPath = [NSString stringWithFormat:@"%@/%@.app",portPath,name]; 204 | [[NSFileManager defaultManager] copyItemAtPath:customEXEapp toPath:customEXEPath]; 205 | 206 | NSPortManager* activePort = [NSPortManager managerWithCustomExePath:customEXEPath]; 207 | 208 | [activePort setPlistObject:version forKey:WINESKIN_WRAPPER_PLIST_KEY_VERSION]; 209 | 210 | if (activePort && [activePort isKindOfClass:[NSImage class]]) 211 | { 212 | [activePort setIconWithImage:icon]; 213 | } 214 | 215 | [self setMainExePath:path atPort:activePort]; 216 | 217 | [activePort synchronizePlist]; 218 | 219 | return YES; 220 | } 221 | 222 | @end 223 | -------------------------------------------------------------------------------- /WineskinApp/Download.m: -------------------------------------------------------------------------------- 1 | // 2 | // Download.m 3 | // Gamma Board 4 | // 5 | // Created by Vitor Marques de Miranda on 26/04/14. 6 | // Copyright (c) 2014 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import "Download.h" 10 | 11 | #import "NSWebUtilities.h" 12 | 13 | #import "NSAlert+Extension.h" 14 | #import "NSString+Extension.h" 15 | #import "NSThread+Extension.h" 16 | #import "NSFileManager+Extension.h" 17 | 18 | @implementation Download 19 | 20 | -(void)dealloc 21 | { 22 | if (self.monitorTimer) [self stopChronometer]; 23 | } 24 | 25 | - (void)updateUI 26 | { 27 | if (_responseData) 28 | { 29 | NSString* downloadedAmount = [NSString humanReadableSizeForBytes:(long long int)[_responseData length] withDecimalMeasureSystem:NO]; 30 | NSString* downloadedSpeed = [NSString humanReadableSizeForBytes:_downloadedAtSecond withDecimalMeasureSystem:NO]; 31 | 32 | if (_fullSize) 33 | { 34 | if ((long long int)[_responseData length] != _fullSize) 35 | { 36 | NSString* fullSizeAmount = [NSString humanReadableSizeForBytes:_fullSize withDecimalMeasureSystem:NO]; 37 | 38 | double elapsedTime = [[NSDate date] timeIntervalSinceDate:_downloadStartMoment]; 39 | long long int downloadSpeed = elapsedTime ? (long long int)[_responseData length]/elapsedTime : 0; 40 | NSString* estimatedTime = [NSWebUtilities timeNeededToDownload:_fullSize-[_responseData length] withSpeed:downloadSpeed]; 41 | 42 | [self.progressWindow setSubtitle:[NSString stringWithFormat:NSLocalizedString(@"%@ of %@ (%@/s) - %@",nil), 43 | downloadedAmount,fullSizeAmount,downloadedSpeed,estimatedTime] 44 | withPriority:PRIORITY_WRAPPER_CREATION]; 45 | } 46 | } 47 | else 48 | { 49 | [self.progressWindow setSubtitle:[NSString stringWithFormat:NSLocalizedString(@"%@ (%@/s)",nil),downloadedAmount,downloadedSpeed] withPriority:PRIORITY_WRAPPER_CREATION]; 50 | } 51 | } 52 | } 53 | - (void)timerFireMethod:(NSTimer*)time 54 | { 55 | [self updateUI]; 56 | 57 | _downloadedAtSecond = 0; 58 | } 59 | - (void)startChronometer 60 | { 61 | [NSThread dispatchBlockInMainQueue:^ 62 | { 63 | self.monitorTimer = [NSTimer scheduledTimerWithTimeInterval:PROGRESS_VIEW_UPDATE_INTERVAL target:self 64 | selector:@selector(timerFireMethod:) userInfo:nil repeats:YES]; 65 | NSRunLoop* theRunLoop = [NSRunLoop currentRunLoop]; 66 | [theRunLoop addTimer:self.monitorTimer forMode:NSRunLoopCommonModes]; 67 | }]; 68 | } 69 | - (void)stopChronometer 70 | { 71 | [self.monitorTimer invalidate]; 72 | } 73 | 74 | - (BOOL)shouldCancelDownloadOfFile:(NSURL*)file to:(NSString*)path inSilence:(BOOL)silence 75 | { 76 | BOOL fileExistsAtPath = [[NSFileManager defaultManager] regularFileExistsAtPath:path]; 77 | 78 | if ((!file || !file.host || !file.path) && !fileExistsAtPath) 79 | { 80 | if (_promptingErrors) [NSAlert showAlertOfType:NSAlertTypeError withMessage:[NSString stringWithFormat:NSLocalizedString(@"The download link of %@ seems to be invalid.",nil), path.lastPathComponent]]; 81 | return TRUE; 82 | } 83 | 84 | return FALSE; 85 | } 86 | - (BOOL)shouldDownloadFile:(NSURL*)file to:(NSString*)path inSilence:(BOOL)silence 87 | { 88 | BOOL fileExistsAtPath = [[NSFileManager defaultManager] regularFileExistsAtPath:path]; 89 | 90 | if ((!file || !file.host || !file.path) && fileExistsAtPath) 91 | { 92 | if (!_promptingErrors) return FALSE; 93 | 94 | return ![NSAlert showBooleanAlertOfType:NSAlertTypeWarning withMessage:[NSString stringWithFormat:NSLocalizedString(@"The link seems to be invalid, but there is already a file called \"%@\" in the specified folder. Do you want to use it instead?",nil), [path lastPathComponent]] withDefault:YES]; 95 | } 96 | 97 | while ([[NSFileManager defaultManager] regularFileExistsAtPath:path]) 98 | { 99 | if (!_promptingErrors) [[NSFileManager defaultManager] removeItemAtPath:path]; 100 | else 101 | { 102 | if ([NSAlert showBooleanAlertOfType:NSAlertTypeWarning withMessage:[NSString stringWithFormat:NSLocalizedString(@"There is already a file called \"%@\" in the specified folder. Do you want to use it instead?",nil), [path lastPathComponent]] withDefault:YES]) 103 | { 104 | return FALSE; 105 | } 106 | else 107 | { 108 | if ([NSAlert showBooleanAlertOfType:NSAlertTypeWarning 109 | withMessage:NSLocalizedString(@"Do you want to override it?",nil) withDefault:NO]) 110 | { 111 | [[NSFileManager defaultManager] removeItemAtPath:path]; 112 | } 113 | else 114 | { 115 | [NSAlert showAlertOfType:NSAlertTypeWarning withMessage:NSLocalizedString(@"Move that file to a different folder and then press Ok.",nil)]; 116 | } 117 | } 118 | } 119 | } 120 | 121 | return TRUE; 122 | } 123 | 124 | - (BOOL)downloadFile:(NSURL*)file to:(NSString*)path inSilence:(BOOL)silence promptingErrors:(BOOL)errors 125 | { 126 | _isSilence = silence; 127 | _promptingErrors = errors; 128 | _downloadPath = path; 129 | _error = nil; 130 | 131 | if ([self shouldCancelDownloadOfFile:file to:path inSilence:silence]) 132 | { 133 | return FALSE; 134 | } 135 | 136 | if (![self shouldDownloadFile:file to:path inSilence:silence]) 137 | { 138 | return TRUE; 139 | } 140 | 141 | if (!_isSilence) 142 | { 143 | [self.progressWindow setIndeterminate:NO]; 144 | [self.progressWindow setCurrentValue:0]; 145 | } 146 | 147 | _percentage = 0; 148 | _fullSize = 0; 149 | _downloadedAtSecond = 0; 150 | _downloadStartMoment = [NSDate date]; 151 | 152 | self.connectionDidFinishLoading = NO; 153 | self.condition = [[NSCondition alloc] init]; 154 | _responseData = [[NSMutableData alloc] initWithLength:0]; 155 | if (!_isSilence) [self startChronometer]; 156 | 157 | NSMutableURLRequest* wineskinDownload = [[NSURLRequest requestWithURL:file cachePolicy:NSURLRequestReloadIgnoringLocalCacheData 158 | timeoutInterval:TIMEOUT_REGULAR_DOWNLOAD] mutableCopy]; 159 | 160 | NSURLConnection* connection = [[NSURLConnection alloc] initWithRequest:wineskinDownload delegate:self startImmediately:NO]; 161 | [connection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; 162 | [connection start]; 163 | 164 | [self waitForConnectionToFinishLoading]; 165 | return [self saveDownloadedFile:file atPath:path]; 166 | } 167 | 168 | - (void)waitForConnectionToFinishLoading 169 | { 170 | [self.condition lock]; 171 | while (!self.connectionDidFinishLoading) 172 | { 173 | [self.condition wait]; 174 | } 175 | [self.condition unlock]; 176 | } 177 | - (BOOL)saveDownloadedFile:(NSURL*)file atPath:(NSString*)path 178 | { 179 | if (!_promptingErrors) 180 | { 181 | if ([_responseData length] && !_error && [_responseData length] >= _fullSize) 182 | { 183 | [[NSFileManager defaultManager] createFileAtPath:path contents:_responseData attributes:nil]; 184 | return TRUE; 185 | } 186 | 187 | return FALSE; 188 | } 189 | 190 | if ([_responseData length]) 191 | { 192 | if (!_error && [_responseData length] >= _fullSize) 193 | { 194 | [[NSFileManager defaultManager] createFileAtPath:path contents:_responseData attributes:nil]; 195 | } 196 | else 197 | { 198 | if ([NSAlert showBooleanAlertOfType:NSAlertTypeError withMessage:[NSString stringWithFormat:NSLocalizedString(@"%@ Do you want to try again?",nil), _error ? _error.localizedDescription : NSLocalizedString(@"The download seems to have been corrupted.",nil)]withDefault:YES]) 199 | { 200 | return [self downloadFile:file to:_downloadPath inSilence:_isSilence promptingErrors:_promptingErrors]; 201 | } 202 | else 203 | { 204 | [[NSFileManager defaultManager] createFileAtPath:path contents:_responseData attributes:nil]; 205 | } 206 | } 207 | } 208 | else 209 | { 210 | if ([NSAlert showBooleanAlertOfType:NSAlertTypeError withMessage:NSLocalizedString(@"The informed file isn't available. Do you want to inform an updated link?",nil) withDefault:YES]) 211 | { 212 | NSString* newlink = [NSAlert inputDialogWithTitle:[NSString stringWithFormat:NSLocalizedString(@"%@ URL",nil),path.lastPathComponent] message:NSLocalizedString(@"Inform the updated link:",nil) defaultValue:@""]; 213 | return [self downloadFile:[NSURL URLWithString:newlink] to:_downloadPath inSilence:_isSilence promptingErrors:_promptingErrors]; 214 | } 215 | } 216 | 217 | return TRUE; 218 | } 219 | 220 | - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 221 | { 222 | _fullSize = [response expectedContentLength]; 223 | } 224 | - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 225 | { 226 | // That will avoid random crashes that might happen here 227 | if (_responseData && data && data.length > 0) [_responseData appendData:data]; 228 | else 229 | { 230 | [NSAlert showAlertOfType:NSAlertTypeError withMessage:NSLocalizedString(@"An unknown error happened during the download.",nil)]; 231 | [self finishDownload]; 232 | } 233 | 234 | if (!_isSilence) 235 | { 236 | _downloadedAtSecond += [data length]; 237 | 238 | if (_fullSize && _percentage != (PROGRESS_VIEW_BAR_PRECISION*[_responseData length])/_fullSize) 239 | { 240 | _percentage = (PROGRESS_VIEW_BAR_PRECISION*[_responseData length])/_fullSize; 241 | [self.progressWindow setCurrentValue:_percentage]; 242 | } 243 | } 244 | } 245 | - (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse*)cachedResponse 246 | { 247 | return nil; 248 | } 249 | - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)err 250 | { 251 | _error = [err copy]; 252 | [self finishDownload]; 253 | } 254 | - (void)connectionDidFinishLoading:(NSURLConnection *)connection 255 | { 256 | [self finishDownload]; 257 | } 258 | - (void)finishDownload 259 | { 260 | [self.condition lock]; 261 | self.connectionDidFinishLoading = YES; 262 | [self.condition signal]; 263 | [self.condition unlock]; 264 | if (!_isSilence) 265 | { 266 | [self.progressWindow setIndeterminate:YES]; 267 | [self.progressWindow setSubtitle:@"" withPriority:PRIORITY_WRAPPER_CREATION]; 268 | [self stopChronometer]; 269 | } 270 | } 271 | - (void)terminateDownload 272 | { 273 | _responseData = [[NSData data] mutableCopy]; 274 | _isSilence = true; 275 | _promptingErrors = false; 276 | [self finishDownload]; 277 | } 278 | 279 | @end 280 | -------------------------------------------------------------------------------- /WineskinApp/NSPathUtilities.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSPathUtilities.m 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/02/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import "NSPathUtilities.h" 10 | 11 | #import "NSString+Extension.h" 12 | #import "NSFileManager+Extension.h" 13 | 14 | @implementation NSPathUtilities 15 | 16 | +(NSString*)wineskinAppBinaryForPortAtPath:(NSString*)path 17 | { 18 | // Used to run the Wineskin App which resides inside Wineskin wrappers 19 | return [path stringByAppendingString:@"/Wineskin.app/Contents/MacOS/Wineskin"]; 20 | } 21 | +(NSString*)wineskinLauncherBinForPortAtPath:(NSString*)path 22 | { 23 | // Used to execute Wineskin instructions, like WSS-wineboot 24 | return [path stringByAppendingString:@"/Contents/MacOS/WineskinLauncher"]; 25 | } 26 | 27 | +(NSString*)getMacPathForWindowsDrive:(char)driveLetter ofWrapper:(NSString*)file 28 | { 29 | NSString* resourcesFolder = [NSString stringWithFormat:@"%@/Contents/Resources/",file]; 30 | NSString* cxResourcesFolder = [NSString stringWithFormat:@"%@/Contents/SharedSupport/CrossOverGames/support/default/",file]; 31 | if ([[NSFileManager defaultManager] directoryExistsAtPath:cxResourcesFolder]) resourcesFolder = cxResourcesFolder; 32 | 33 | NSString* drivePath = [NSString stringWithFormat:@"%@dosdevices/%c:",resourcesFolder,tolower(driveLetter)]; 34 | 35 | if (![[NSFileManager defaultManager] fileExistsAtPath:drivePath]) return nil; 36 | 37 | NSString* path = [[NSFileManager defaultManager] destinationOfSymbolicLinkAtPath:drivePath]; 38 | if ([path hasPrefix:@"../"]) path = [NSString stringWithFormat:@"%@%@",resourcesFolder,[path substringFromIndex:3]]; 39 | if ([path hasSuffix:@"/"] == false) path = [path stringByAppendingString:@"/"]; 40 | 41 | return path; 42 | } 43 | +(NSString*)getMacPathForWindowsPath:(NSString*)exePath ofWrapper:(NSString*)file 44 | { 45 | if (exePath.length < 2) return nil; 46 | 47 | exePath = [exePath stringByReplacingOccurrencesOfString:@"\\" withString:@"/"]; 48 | 49 | // Let's save time... if it starts with Z:, then it's your Mac root directory 50 | if ([exePath hasPrefix:@"Z:"]) return [exePath substringFromIndex:2]; 51 | 52 | NSString* path = [self getMacPathForWindowsDrive:[exePath characterAtIndex:0] ofWrapper:file]; 53 | 54 | return [[NSString stringWithFormat:@"%@%@",path,[exePath substringFromIndex:2]] 55 | stringByReplacingOccurrencesOfString:@"//" withString:@"/"]; 56 | } 57 | +(NSString*)getWindowsPathForMacPath:(NSString*)exePath ofWrapper:(NSString*)file 58 | { 59 | for (char x = 'C'; x <= 'Z'; x++) 60 | { 61 | NSString* driveRoot = [NSString stringWithFormat:@"%c:/",x]; 62 | 63 | if (file) 64 | { 65 | NSString* path = [self getMacPathForWindowsDrive:x ofWrapper:file]; 66 | if (path && [exePath hasPrefix:path]) 67 | { 68 | return [driveRoot stringByAppendingString:[exePath substringFromIndex:path.length]]; 69 | } 70 | } 71 | else 72 | { 73 | NSString* driveRootMac = [NSString stringWithFormat:@"drive_%c/",tolower(x)]; 74 | NSString* path = [exePath getFragmentAfter:driveRootMac andBefore:nil]; 75 | 76 | if (path) return [driveRoot stringByAppendingString:path]; 77 | } 78 | } 79 | 80 | return [NSString stringWithFormat:@"Z:%@",exePath]; 81 | } 82 | 83 | +(NSString*)getFileNameOfWindowsPath:(NSString*)exePath 84 | { 85 | exePath = [exePath stringByReplacingOccurrencesOfString:@"\\" withString:@"/"]; 86 | 87 | // Just to avoid problems with empty string before the first '"' 88 | while ([exePath hasPrefix:@" "]) exePath = [exePath substringFromIndex:1]; 89 | 90 | // If it doesn't start with '"', then it isn't a regular path 91 | if (![exePath hasPrefix:@"\""]) 92 | { 93 | // If it doesn't have a size bigger than 2, then it isn't even a valid path 94 | if (exePath.length > 2) 95 | { 96 | // Well, if it has a ':' then the path might be correct; we should give it a chance; otherwise, last check 97 | if (![exePath contains:@":"]) 98 | { 99 | // If it starts with '/', then the user might have used a Mac path; that should solve the problem 100 | if ([exePath hasPrefix:@"/"]) return [NSString stringWithFormat:@"Z:%@",exePath]; 101 | 102 | // Otherwise, that path might be batch commands; give it back like it is 103 | return exePath; 104 | } 105 | } 106 | else return @""; 107 | } 108 | 109 | // Considering that it start with ", that should work; first, split it with " 110 | NSArray* array = [exePath componentsSeparatedByString:@"\""]; 111 | 112 | // If it has 3 " or more, everything is according to the expected 113 | // If the block before the first " is empty, it returns the second block; otherwise, the first 114 | // That will avoid problems if the user removes the first " by mistake 115 | if (array.count>=3) return ([array[0] isEqualToString:@""]) ? array[1] : array[0]; 116 | 117 | // If it has only 2, then something is obviously wrong 118 | // If the first part is bigger than 0, probably the first " was skipped 119 | // Otherwise, the best option is obviously the second 120 | if (array.count==2) return ([array[0] length] > 0) ? array[0] : array[1]; 121 | 122 | // If it has only one... well, then it doesn't have " at all 123 | // Just return the only item of the array 124 | if (array.count==1) return array[0]; 125 | 126 | // Oh, that? That's just in case something unexpected happen like an empty array 127 | // The fact is: that function ALWAYS have to return something, even an empty string 128 | return @""; 129 | } 130 | +(NSString*)getFlagsOfWindowsPath:(NSString*)exePath 131 | { 132 | // Just to avoid problems with empty string before the first '"' 133 | while ([exePath hasPrefix:@" "]) exePath = [exePath substringFromIndex:1]; 134 | 135 | // If it doesn't start with '"', then it isn't a regular path 136 | if (![exePath hasPrefix:@"\""]) 137 | { 138 | // If it doesn't have a size bigger than 2, then it isn't even a valid string 139 | if (exePath.length>2) 140 | { 141 | // Well, if it has a ':' then the path might be correct; we should give it a chance; otherwise, last check 142 | if (![exePath contains:@":"]) 143 | { 144 | // If it starts with '/', then the user have used a Wineskin path; so no flags 145 | // Otherwise, that path might be batch commands; since we returned everything has the path, here we return nothing 146 | return @""; 147 | } 148 | } 149 | else return @""; 150 | } 151 | 152 | // Considering that it start with ", that should work; first, split it with " 153 | NSString* result = @""; 154 | NSMutableArray* array = [[exePath componentsSeparatedByString:@"\""] mutableCopy]; 155 | 156 | // If it has 3 " or more, everything is according to the expected 157 | if (array.count >= 3) 158 | { 159 | // If the block before the first " is empty, it removes the first block 160 | if ([array[0] isEqualToString:@""]) 161 | { 162 | [array removeObjectAtIndex:0]; 163 | } 164 | 165 | // Otherwise, the user might have removed the first " by mistake; in that case, we should skip that step 166 | [array removeObjectAtIndex:0]; 167 | 168 | // Flags have " too (paths don't), then we have to join everything else with them to recover the original flags 169 | result = [array componentsJoinedByString:@"\""]; 170 | } 171 | 172 | // If it has only 2, then something is obviously wrong 173 | // If the first part is bigger than 0, probably the first " was skipped and the flags are the second part 174 | // Otherwise, we will consider that there are no flags 175 | else if (array.count==2) return ([array[0] length] > 0) ? array[1] : @""; 176 | 177 | // Just to improve the flag quality, removing spaces from the beggining 178 | while ([result hasPrefix:@" "]) result = [result substringFromIndex:1]; 179 | 180 | // Now, just return the flags 181 | return result; 182 | } 183 | 184 | +(BOOL)isPath:(NSString*)path compatibleWithStruct:(NSString*)structure 185 | { 186 | if (![structure isEqualToString:@""]) 187 | { 188 | if ([structure contains:WINDOWS_PATH_PROGRAM_FILES_PLACEHOLDER]) 189 | { 190 | structure = [structure stringByReplacingOccurrencesOfString:WINDOWS_PATH_PROGRAM_FILES_PLACEHOLDER withString:@"C:/*"]; 191 | } 192 | 193 | NSArray* parts = [structure.lowercaseString componentsSeparatedByString:@"*"]; 194 | path = path.lowercaseString; 195 | 196 | if (parts.count < 1) return TRUE; 197 | if (parts.count == 1) return [path isEqualToString:parts[0]]; 198 | if (parts.count == 2) 199 | { 200 | BOOL hasPrefix = [path hasPrefix:parts[0]] || [parts[0] isEqualToString:@""]; 201 | BOOL hasSuffix = [path hasSuffix:parts[1]] || [parts[1] isEqualToString:@""]; 202 | return hasPrefix && hasSuffix; 203 | } 204 | 205 | for (int index = 0; index < parts.count; index++) 206 | { 207 | NSString* part = parts[index]; 208 | 209 | if (![part isEqualToString:@""]) 210 | { 211 | while (index!=0 && path.length>0 && ![path hasPrefix:part]) 212 | path = [path substringFromIndex:1]; 213 | 214 | if ([path hasPrefix:part]) path = [path substringFromIndex:part.length]; 215 | else return FALSE; 216 | } 217 | else if (index == parts.count-1) return TRUE; 218 | } 219 | 220 | return path.length == 0; 221 | } 222 | 223 | return TRUE; 224 | } 225 | +(NSArray*)filesCompatibleWithStructure:(NSString*)appPath insideFolder:(NSString*)folder 226 | { 227 | if (!folder) return @[]; 228 | 229 | NSString* fullFolder = [folder hasSuffix:@"/"] ? folder : [folder stringByAppendingString:@"/"]; 230 | NSMutableArray* pastas = [@[fullFolder] mutableCopy]; 231 | if (![[NSFileManager defaultManager] directoryExistsAtPath:fullFolder]) return @[]; 232 | 233 | if ([appPath contains:@"/"]) 234 | { 235 | NSMutableArray* partsOfPath = [[appPath componentsSeparatedByString:@"/"] mutableCopy]; 236 | appPath = [partsOfPath lastObject]; 237 | [partsOfPath removeLastObject]; 238 | 239 | pastas = [[self filesCompatibleWithStructure:[partsOfPath componentsJoinedByString:@"/"] insideFolder:fullFolder] mutableCopy]; 240 | 241 | if (pastas.count == 0) return pastas; 242 | } 243 | 244 | NSMutableArray* finalFilePaths = [[NSMutableArray alloc] init]; 245 | for (NSString* pasta in pastas) 246 | { 247 | if ([[NSFileManager defaultManager] directoryExistsAtPath:pasta]) 248 | { 249 | NSArray* downloadFolder = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:pasta]; 250 | 251 | for (NSString* downloadItem in downloadFolder) 252 | { 253 | if ([self isPath:downloadItem compatibleWithStruct:appPath]) 254 | { 255 | NSString* fullPasta = [pasta hasSuffix:@"/"] ? pasta : [pasta stringByAppendingString:@"/"]; 256 | [finalFilePaths addObject:[NSString stringWithFormat:@"%@%@",fullPasta,downloadItem]]; 257 | } 258 | } 259 | } 260 | } 261 | 262 | return finalFilePaths; 263 | } 264 | 265 | @end 266 | -------------------------------------------------------------------------------- /WineskinLauncher/NSPathUtilities.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSPathUtilities.m 3 | // Wineskin Navy 4 | // 5 | // Created by Vitor Marques de Miranda on 22/02/17. 6 | // Copyright © 2017 Vitor Marques de Miranda. All rights reserved. 7 | // 8 | 9 | #import "NSPathUtilities.h" 10 | #import 11 | 12 | @implementation NSPathUtilities 13 | 14 | +(NSString*)wineskinAppBinaryForPortAtPath:(NSString*)path 15 | { 16 | // Used to run the Wineskin App which resides inside Wineskin wrappers 17 | return [path stringByAppendingString:@"/Wineskin.app/Contents/MacOS/Wineskin"]; 18 | } 19 | +(NSString*)wineskinLauncherBinForPortAtPath:(NSString*)path 20 | { 21 | // Used to execute Wineskin instructions, like WSS-wineboot 22 | return [path stringByAppendingString:@"/Contents/MacOS/WineskinLauncher"]; 23 | } 24 | 25 | +(NSString*)getMacPathForWindowsDrive:(char)driveLetter ofWrapper:(NSString*)file 26 | { 27 | NSString* path; 28 | 29 | @autoreleasepool 30 | { 31 | NSString* resourcesFolder = [NSString stringWithFormat:@"%@/Contents/Resources/",file]; 32 | NSString* cxResourcesFolder = [NSString stringWithFormat:@"%@/Contents/SharedSupport/CrossOverGames/support/default/",file]; 33 | if ([[NSFileManager defaultManager] directoryExistsAtPath:cxResourcesFolder]) resourcesFolder = cxResourcesFolder; 34 | 35 | NSString* drivePath = [NSString stringWithFormat:@"%@dosdevices/%c:",resourcesFolder,tolower(driveLetter)]; 36 | if (![[NSFileManager defaultManager] fileExistsAtPath:drivePath]) return nil; 37 | 38 | path = [[NSFileManager defaultManager] destinationOfSymbolicLinkAtPath:drivePath]; 39 | if ([path hasPrefix:@"../"]) path = [NSString stringWithFormat:@"%@%@",resourcesFolder,[path substringFromIndex:3]]; 40 | if ([path hasSuffix:@"/"] == false) path = [path stringByAppendingString:@"/"]; 41 | } 42 | 43 | return path; 44 | } 45 | +(NSString*)getMacPathForWindowsPath:(NSString*)exePath ofWrapper:(NSString*)file 46 | { 47 | if (exePath.length < 2) return nil; 48 | 49 | NSString* path; 50 | 51 | @autoreleasepool 52 | { 53 | exePath = [exePath stringByReplacingOccurrencesOfString:@"\\" withString:@"/"]; 54 | 55 | // Let's save time... if it starts with Z:, then it's your Mac root directory 56 | if ([exePath hasPrefix:@"Z:"]) 57 | { 58 | return [exePath substringFromIndex:2]; 59 | } 60 | 61 | path = [self getMacPathForWindowsDrive:[exePath characterAtIndex:0] ofWrapper:file]; 62 | 63 | path = [[NSString stringWithFormat:@"%@%@",path,[exePath substringFromIndex:2]] 64 | stringByReplacingOccurrencesOfString:@"//" withString:@"/"]; 65 | } 66 | 67 | return path; 68 | } 69 | +(NSString*)getWindowsPathForMacPath:(NSString*)exePath ofWrapper:(NSString*)file 70 | { 71 | for (char x = 'C'; x <= 'Z'; x++) 72 | { 73 | NSString* driveRoot = [NSString stringWithFormat:@"%c:/",x]; 74 | 75 | if (file) 76 | { 77 | NSString* path = [self getMacPathForWindowsDrive:x ofWrapper:file]; 78 | if (path && [exePath hasPrefix:path]) 79 | { 80 | return [driveRoot stringByAppendingString:[exePath substringFromIndex:path.length]]; 81 | } 82 | } 83 | else 84 | { 85 | NSString* driveRootMac = [NSString stringWithFormat:@"drive_%c/",tolower(x)]; 86 | NSString* path = [exePath getFragmentAfter:driveRootMac andBefore:nil]; 87 | 88 | if (path) return [driveRoot stringByAppendingString:path]; 89 | } 90 | } 91 | 92 | return [NSString stringWithFormat:@"Z:%@",exePath]; 93 | } 94 | 95 | +(NSString*)getFileNameOfWindowsPath:(NSString*)exePath 96 | { 97 | exePath = [exePath stringByReplacingOccurrencesOfString:@"\\" withString:@"/"]; 98 | 99 | // Just to avoid problems with empty string before the first '"' 100 | while ([exePath hasPrefix:@" "]) exePath = [exePath substringFromIndex:1]; 101 | 102 | // If it doesn't start with '"', then it isn't a regular path 103 | if (![exePath hasPrefix:@"\""]) 104 | { 105 | // If it doesn't have a size bigger than 2, then it isn't even a valid path 106 | if (exePath.length <= 2) return @""; 107 | 108 | // Well, if it has a ':' then the path might be correct; we should give it a chance; otherwise, last check 109 | if (![exePath contains:@":"]) 110 | { 111 | // If it starts with '/', then the user might have used a Mac path; that should solve the problem 112 | if ([exePath hasPrefix:@"/"]) return [NSString stringWithFormat:@"Z:%@",exePath]; 113 | 114 | // Otherwise, that path might be batch commands; give it back like it is 115 | return exePath; 116 | } 117 | } 118 | 119 | // Considering that it start with ", that should work; first, split it with " 120 | NSArray* array = [exePath componentsSeparatedByString:@"\""]; 121 | 122 | // If it has 3 " or more, everything is according to the expected 123 | // If the block before the first " is empty, it returns the second block; otherwise, the first 124 | // That will avoid problems if the user removes the first " by mistake 125 | if (array.count>=3) return ([array[0] isEqualToString:@""]) ? array[1] : array[0]; 126 | 127 | // If it has only 2, then something is obviously wrong 128 | // If the first part is bigger than 0, probably the first " was skipped 129 | // Otherwise, the best option is obviously the second 130 | if (array.count==2) return ([array[0] length] > 0) ? array[0] : array[1]; 131 | 132 | // If it has only one... well, then it doesn't have " at all 133 | // Just return the only item of the array 134 | if (array.count==1) return array[0]; 135 | 136 | // Oh, that? That's just in case something unexpected happen like an empty array 137 | // The fact is: that function ALWAYS have to return something, even an empty string 138 | return @""; 139 | } 140 | +(NSString*)getFlagsOfWindowsPath:(NSString*)exePath 141 | { 142 | // Just to avoid problems with empty string before the first '"' 143 | while ([exePath hasPrefix:@" "]) exePath = [exePath substringFromIndex:1]; 144 | 145 | // If it doesn't start with '"', then it isn't a regular path 146 | if (![exePath hasPrefix:@"\""]) 147 | { 148 | // If it doesn't have a size bigger than 2, then it isn't even a valid string 149 | if (exePath.length <= 2) return @""; 150 | 151 | // Well, if it has a ':' then the path might be correct; we should give it a chance; otherwise, last check 152 | if (![exePath contains:@":"]) 153 | { 154 | // If it starts with '/', then the user have used a Wineskin path; so no flags 155 | // Otherwise, that path might be batch commands; since we returned everything has the path, here we return nothing 156 | return @""; 157 | } 158 | } 159 | 160 | // Considering that it start with ", that should work; first, split it with " 161 | NSString* result = @""; 162 | exePath = [exePath stringByReplacingOccurrencesOfString:@"\n" withString:@""]; 163 | NSMutableArray* array = [[exePath componentsSeparatedByString:@"\""] mutableCopy]; 164 | 165 | // If it has 3 " or more, everything is according to the expected 166 | if (array.count >= 3) 167 | { 168 | // If the block before the first " is empty, it removes the first block 169 | if ([array[0] isEqualToString:@""]) 170 | { 171 | [array removeObjectAtIndex:0]; 172 | } 173 | 174 | // Otherwise, the user might have removed the first " by mistake; in that case, we should skip that step 175 | [array removeObjectAtIndex:0]; 176 | 177 | // Flags have " too (paths don't), then we have to join everything else with them to recover the original flags 178 | result = [array componentsJoinedByString:@"\""]; 179 | } 180 | 181 | // If it has only 2, then something is obviously wrong 182 | // If the first part is bigger than 0, probably the first " was skipped and the flags are the second part 183 | // Otherwise, we will consider that there are no flags 184 | else if (array.count==2) return ([array[0] length] > 0) ? array[1] : @""; 185 | 186 | // Just to improve the flag quality, removing spaces from the beggining 187 | while ([result hasPrefix:@" "]) result = [result substringFromIndex:1]; 188 | 189 | // Now, just return the flags 190 | return result; 191 | } 192 | 193 | +(BOOL)isPath:(NSString*)path compatibleWithStruct:(NSString*)structure 194 | { 195 | if ([structure isEqualToString:@""]) return TRUE; 196 | 197 | if ([structure contains:WINDOWS_PATH_PROGRAM_FILES_PLACEHOLDER]) 198 | { 199 | structure = [structure stringByReplacingOccurrencesOfString:WINDOWS_PATH_PROGRAM_FILES_PLACEHOLDER withString:@"C:/*"]; 200 | } 201 | 202 | NSArray* parts = [structure.lowercaseString componentsSeparatedByString:@"*"]; 203 | path = path.lowercaseString; 204 | 205 | if (parts.count < 1) return TRUE; 206 | if (parts.count == 1) return [path isEqualToString:parts[0]]; 207 | if (parts.count == 2) 208 | { 209 | BOOL hasPrefix = [path hasPrefix:parts[0]] || [parts[0] isEqualToString:@""]; 210 | BOOL hasSuffix = [path hasSuffix:parts[1]] || [parts[1] isEqualToString:@""]; 211 | return hasPrefix && hasSuffix; 212 | } 213 | 214 | for (int index = 0; index < parts.count; index++) 215 | { 216 | NSString* part = parts[index]; 217 | 218 | if ([part isEqualToString:@""]) 219 | { 220 | if (index == parts.count-1) return TRUE; 221 | } 222 | else 223 | { 224 | while (index!=0 && path.length>0 && ![path hasPrefix:part]) 225 | { 226 | path = [path substringFromIndex:1]; 227 | } 228 | 229 | if (![path hasPrefix:part]) return FALSE; 230 | 231 | path = [path substringFromIndex:part.length]; 232 | } 233 | } 234 | 235 | return path.length == 0; 236 | } 237 | +(NSArray*)filesCompatibleWithStructure:(NSString*)appPath insideFolder:(NSString*)folder 238 | { 239 | if (!folder) return @[]; 240 | 241 | NSString* fullFolder = [folder hasSuffix:@"/"] ? folder : [folder stringByAppendingString:@"/"]; 242 | NSMutableArray* pastas = [@[fullFolder] mutableCopy]; 243 | if (![[NSFileManager defaultManager] directoryExistsAtPath:fullFolder]) return @[]; 244 | 245 | if ([appPath contains:@"/"]) 246 | { 247 | NSMutableArray* partsOfPath = [[appPath componentsSeparatedByString:@"/"] mutableCopy]; 248 | appPath = [partsOfPath lastObject]; 249 | [partsOfPath removeLastObject]; 250 | 251 | pastas = [[self filesCompatibleWithStructure:[partsOfPath componentsJoinedByString:@"/"] insideFolder:fullFolder] mutableCopy]; 252 | 253 | if (pastas.count == 0) return pastas; 254 | } 255 | 256 | NSMutableArray* finalFilePaths = [[NSMutableArray alloc] init]; 257 | for (NSString* pasta in pastas) 258 | { 259 | if ([[NSFileManager defaultManager] directoryExistsAtPath:pasta]) 260 | { 261 | NSArray* downloadFolder = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:pasta]; 262 | 263 | for (NSString* downloadItem in downloadFolder) 264 | { 265 | if ([self isPath:downloadItem compatibleWithStruct:appPath]) 266 | { 267 | NSString* fullPasta = [pasta hasSuffix:@"/"] ? pasta : [pasta stringByAppendingString:@"/"]; 268 | [finalFilePaths addObject:[NSString stringWithFormat:@"%@%@",fullPasta,downloadItem]]; 269 | } 270 | } 271 | } 272 | } 273 | 274 | return finalFilePaths; 275 | } 276 | 277 | @end 278 | --------------------------------------------------------------------------------