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 resourceDir { _Platform_resourceDir }
49 *resourceDir { ^thisProcess.platform.resourceDir }
51 defaultTempDir { ^this.subclassResponsibility() }
52 *defaultTempDir { ^thisProcess.platform.defaultTempDir }
54 // The "ideName" is for ide-dependent compilation.
55 // From SC.app, the value is "scapp" meaning "scide_scapp" folders will be compiled and other "scide_*" ignored.
56 ideName { _Platform_ideName }
57 *ideName { ^thisProcess.platform.ideName }
59 platformDir { ^this.name.asString }
60 *platformDir { ^thisProcess.platform.platformDir }
62 pathSeparator { ^this.subclassResponsibility }
63 *pathSeparator { ^thisProcess.platform.pathSeparator }
65 isPathSeparator { |char| ^this.subclassResponsibility }
66 *isPathSeparator { |char| ^thisProcess.platform.isPathSeparator(char) }
68 clearMetadata { |path| ^this.subclassResponsibility }
69 *clearMetadata { |path| ^thisProcess.platform.clearMetadata(path) }
71 getMouseCoords { ^this.subclassResponsibility }
72 *getMouseCoords { ^thisProcess.platform.getMouseCoords }
74 // startup/shutdown hooks
79 ^[defaultStartupFile];
82 *deprecatedStartupFiles {|paths|
83 var postWarning = false;
85 if (File.exists(path.standardizePath)) {
86 warn("Deprecated startup file found: %\n".format(path));
91 postln("Please use % as startup file.\nDeprecated startup files will be ignored in future versions.\n".format(defaultStartupFile));
95 loadStartupFiles { this.startupFiles.do{|afile|
96 afile = afile.standardizePath;
97 if(File.exists(afile), {afile.load})
102 declareFeature { | aFeature |
103 var str = aFeature.asString;
104 if (str.first.isUpper) {
105 Error("cannot declare class name features").throw;
107 if (str.first == $_) {
108 Error("cannot declare primitive name features").throw;
110 features.put(aFeature, true);
112 hasFeature { | symbol |
113 if (features.includesKey(symbol).not) {
116 symbol.asSymbol.asClass.notNil or: { symbol.isPrimitive }
121 when { | features, ifFunction, elseFunction |
122 ^features.asArray.inject(true, { |v,x|
123 v and: { this.hasFeature(x) }
124 }).if(ifFunction, elseFunction)
126 *when { | features, ifFunction, elseFunction |
127 ^thisProcess.platform.when(features, ifFunction, elseFunction)
130 // Prefer qt but fall back to swing if qt not installed.
131 defaultGUIScheme { if (GUI.get(\qt).notNil) {^\qt} {^\swing} }
132 defaultHIDScheme { ^\none }
134 isSleeping { ^false } // unless defined otherwise
136 // used on systems to deduce a svn directory path, if system wide location is used for installed version. (tested on Linux).
139 if ( devpath.isNil ){ ^inpath };
140 outpath = inpath.copyToEnd( inpath.find( "SuperCollider") );
141 outpath = outpath.replace( "SuperCollider", devpath );
145 // hook for clients to write frontend.css
148 killAll { |cmdLineArgs|
149 ^this.subclassResponsibility(\killAll)
153 UnixPlatform : Platform
155 pathSeparator { ^$/ }
157 isPathSeparator { |char|
158 ^(char === this.pathSeparator)
161 clearMetadata { |path|
162 "rm -f %\.*meta".format(path.splitext[0].escapeChar($ )).systemCmd;
167 pipe = Pipe("arch", "r");
173 killAll { |cmdLineArgs|
174 ("killall -9 " ++ cmdLineArgs).unixCmd;
178 // +/+ "" looks funny but ensures trailing slash
179 ^["/tmp/", this.userAppSupportDir +/+ ""].detect({ |path|