3 classvar defaultStartupFile;
6 classvar <>makeServerWindowAction, <>makeSynthDescWindowAction, <>openHelpFileAction, <>openHTMLFileAction;
8 var <classLibraryDir, <helpDir, <>recordingsDir, features;
12 defaultStartupFile = this.userConfigDir +/+ "startup.scd"
16 classLibraryDir = thisMethod.filenameSymbol.asString.dirname.dirname;
17 helpDir = thisMethod.filenameSymbol.asString.dirname.dirname.dirname ++ "/Help";
18 features = IdentityDictionary.new;
19 recordingsDir = this.userAppSupportDir +/+ "Recordings";
22 name { ^this.subclassResponsibility }
24 recompile { _Recompile }
26 ^thisProcess.platform.name.switch(*cases)
30 *classLibraryDir { ^thisProcess.platform.classLibraryDir }
31 *helpDir { ^thisProcess.platform.helpDir }
33 systemAppSupportDir { _Platform_systemAppSupportDir }
34 *systemAppSupportDir { ^thisProcess.platform.systemAppSupportDir }
36 userAppSupportDir { _Platform_userAppSupportDir }
37 *userAppSupportDir { ^thisProcess.platform.userAppSupportDir }
39 systemExtensionDir { _Platform_systemExtensionDir }
40 *systemExtensionDir { ^thisProcess.platform.systemExtensionDir }
42 userExtensionDir { _Platform_userExtensionDir }
43 *userExtensionDir { ^thisProcess.platform.userExtensionDir }
45 userConfigDir { _Platform_userConfigDir }
46 *userConfigDir { ^thisProcess.platform.userConfigDir }
48 defaultTempDir { ^this.subclassResponsibility() }
49 *defaultTempDir { ^thisProcess.platform.defaultTempDir }
51 // The "ideName" is for ide-dependent compilation.
52 // From SC.app, the value is "scapp" meaning "scide_scapp" folders will be compiled and other "scide_*" ignored.
53 ideName { _Platform_ideName }
54 *ideName { ^thisProcess.platform.ideName }
56 platformDir { ^this.name.asString }
57 *platformDir { ^thisProcess.platform.platformDir }
59 pathSeparator { ^this.subclassResponsibility }
60 *pathSeparator { ^thisProcess.platform.pathSeparator }
62 isPathSeparator { |char| ^this.subclassResponsibility }
63 *isPathSeparator { |char| ^thisProcess.platform.isPathSeparator(char) }
65 clearMetadata { |path| ^this.subclassResponsibility }
66 *clearMetadata { |path| ^thisProcess.platform.clearMetadata(path) }
68 getMouseCoords { ^this.subclassResponsibility }
69 *getMouseCoords { ^thisProcess.platform.getMouseCoords }
71 // startup/shutdown hooks
76 ^[defaultStartupFile];
79 *deprecatedStartupFiles {|paths|
80 var postWarning = false;
82 if (File.exists(path.standardizePath)) {
83 warn("Deprecated startup file found: %\n".format(path));
88 postln("Please use % as startup file.\nDeprecated startup files will be ignored in future versions.\n".format(defaultStartupFile));
92 loadStartupFiles { this.startupFiles.do{|afile|
93 afile = afile.standardizePath;
94 if(File.exists(afile), {afile.load})
99 declareFeature { | aFeature |
100 var str = aFeature.asString;
101 if (str.first.isUpper) {
102 Error("cannot declare class name features").throw;
104 if (str.first == $_) {
105 Error("cannot declare primitive name features").throw;
107 features.put(aFeature, true);
109 hasFeature { | symbol |
110 if (features.includesKey(symbol).not) {
113 symbol.asSymbol.asClass.notNil or: { symbol.isPrimitive }
118 when { | features, ifFunction, elseFunction |
119 ^features.asArray.inject(true, { |v,x|
120 v and: { this.hasFeature(x) }
121 }).if(ifFunction, elseFunction)
123 *when { | features, ifFunction, elseFunction |
124 ^thisProcess.platform.when(features, ifFunction, elseFunction)
127 // Prefer qt but fall back to swing if qt not installed.
128 defaultGUIScheme { if (GUI.get(\qt).notNil) {^\qt} {^\swing} }
129 defaultHIDScheme { ^\none }
131 isSleeping { ^false } // unless defined otherwise
133 // used on systems to deduce a svn directory path, if system wide location is used for installed version. (tested on Linux).
136 if ( devpath.isNil ){ ^inpath };
137 outpath = inpath.copyToEnd( inpath.find( "SuperCollider") );
138 outpath = outpath.replace( "SuperCollider", devpath );
142 // hook for clients to write frontend.css
145 killAll { |cmdLineArgs|
146 ^this.subclassResponsibility(\killAll)
150 UnixPlatform : Platform
152 pathSeparator { ^$/ }
154 isPathSeparator { |char|
155 ^(char === this.pathSeparator)
158 clearMetadata { |path|
159 "rm -f %\.*meta".format(path.splitext[0].escapeChar($ )).systemCmd;
164 pipe = Pipe("arch", "r");
170 killAll { |cmdLineArgs|
171 ("killall -9 " ++ cmdLineArgs).unixCmd;
175 // +/+ "" looks funny but ensures trailing slash
176 ^["/tmp/", this.userAppSupportDir +/+ ""].detect({ |path|