1 // System.cpp: ActionScript "System" class, for Gnash.
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
4 // 2011 Free Software Foundation, Inc
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "System_as.h"
26 #include <boost/tuple/tuple.hpp>
28 #include "movie_root.h" // interface callback
31 #include "Global_as.h"
32 #include "NativeFunction.h"
33 #include "VM.h" // for getPlayerVersion()
34 #include "GnashAlgorithm.h"
35 #include "RunResources.h"
36 #include "HostInterface.h"
41 // Forward declarations.
44 inline char trueFalse(bool x
) { return x
? 't' : 'f'; }
46 std::string
systemLanguage(as_object
& proto
);
48 as_value
system_security_allowdomain(const fn_call
& fn
);
49 as_value
system_security_allowinsecuredomain(const fn_call
& fn
);
50 as_value
system_security_loadpolicyfile(const fn_call
& fn
);
51 as_value
system_setClipboard(const fn_call
& fn
);
52 as_value
system_showsettings(const fn_call
& fn
);
53 as_value
system_exactsettings(const fn_call
& fn
);
54 as_value
system_usecodepage(const fn_call
& fn
);
55 void attachSystemSecurityInterface(as_object
& o
);
56 void attachSystemCapabilitiesInterface(as_object
& o
);
57 void attachSystemInterface(as_object
& proto
);
61 system_class_init(as_object
& where
, const ObjectURI
& uri
)
63 registerBuiltinObject(where
, attachSystemInterface
, uri
);
68 registerSystemNative(as_object
& where
)
70 VM
& vm
= getVM(where
);
72 vm
.registerNative(system_security_allowdomain
, 12, 0);
73 vm
.registerNative(system_showsettings
, 2107, 0);
75 // From http://osflash.org/flashcoders/undocumented/asnative
77 // Run once in startup script then deleted...
78 // System.Capabilities.Query 11, 0
80 // System.Product.isRunning 2201, 0
81 // System.Product.isInstalled 2201, 1
82 // System.Product.launch 2201, 2
83 // System.Product.download 2201, 3
89 attachSystemSecurityInterface(as_object
& o
)
92 o
.init_member("allowDomain", vm
.getNative(12, 0));
94 Global_as
& gl
= getGlobal(o
);
95 o
.init_member("allowInsecureDomain",
96 gl
.createFunction(system_security_allowinsecuredomain
));
97 o
.init_member("loadPolicyFile",
98 gl
.createFunction(system_security_loadpolicyfile
));
102 attachSystemCapabilitiesInterface(as_object
& o
)
104 RcInitFile
& rcfile
= RcInitFile::getDefaultInstance();
107 // Filesystem, access, miscellaneous hardware information
110 // "Windows XP", "Windows 2000", "Windows NT", "Windows 98/ME",
111 // "Windows 95", "Windows CE", "Linux", "MacOS"
112 // Override in gnashrc
115 const std::string os
= vm
.getOSName();
117 const std::string language
= systemLanguage(o
);
119 // FIXME: these need to be implemented properly
120 // Does the NetStream object natively support SSL?
121 const bool hasTLS
= true;
123 // Microphone and camera access disabled
124 const bool avHardwareDisable
= false;
126 // Not sure: seems to be whether the movie can 'float' above web pages,
127 // and is useful for disabling certain annoying adverts.
128 const bool windowlessDisable
= false;
130 const bool hasPrinting
= true;
131 const bool hasAccessibility
= true;
132 const bool isDebugger
= false;
133 const bool localFileReadDisable
= false;
136 // Display information (needs active GUI)
139 const movie_root
& m
= vm
.getRoot();
144 boost::tie(resX
, resY
) = m
.callInterface
<std::pair
<int, int> >(
145 HostMessage(HostMessage::SCREEN_RESOLUTION
));
147 const double screenDPI
= m
.callInterface
<double>(HostMessage(
148 HostMessage::SCREEN_DPI
));
150 const double aspectRatio
= m
.callInterface
<double>(HostMessage(
151 HostMessage::PIXEL_ASPECT_RATIO
));
153 // Note that the pp uses the current locale to display the
154 // ratio (for the decimal separator).
155 std::ostringstream s
;
156 s
<< std::setprecision(7) << aspectRatio
;
157 const std::string pixelAspectRatio
= s
.str();
159 // "StandAlone", "External", "PlugIn", "ActiveX" (get from GUI)
160 const std::string playerType
= m
.callInterface
<std::string
>(HostMessage(
161 HostMessage::PLAYER_TYPE
));
163 const std::string screenColor
= m
.callInterface
<std::string
>(HostMessage(
164 HostMessage::SCREEN_COLOR
));
170 // Is audio available?
171 const bool hasAudio
= (vm
.getRoot().runResources().soundHandler());
173 // FIXME: these need to be implemented properly. They are mostly
175 const bool hasAudioEncoder
= true;
176 const bool hasEmbeddedVideo
= true;
177 const bool hasMP3
= true;
178 const bool hasScreenBroadcast
= true;
179 const bool hasScreenPlayback
= true;
180 const bool hasStreamingAudio
= true;
181 const bool hasStreamingVideo
= true;
182 const bool hasVideoEncoder
= true;
188 // "LNX 9,0,22,0", "MAC 8,0,99,0"
189 // Override in gnashrc
190 const std::string version
= vm
.getPlayerVersion();
192 // "Macromedia Windows", "Macromedia Linux", "Macromedia MacOS"
193 // Override in gnashrc
194 const std::string manufacturer
= rcfile
.getFlashSystemManufacturer();
197 // A URL-encoded string to send system info to a server.
198 // Boolean values are represented as t or f.
199 // Privacy concerns should probably be addressed by
200 // allowing this string to be sent or not; individual
201 // values that might affect privacy can be overridden
204 // hasIME seems not to be included in the server string, though
205 // it is documented to have a server string of IME.
206 // Linux player version 9 has no hasIME property (but no need
209 // TLS and hasTLS are documented for AS3, player version 9.
211 // WD is included in the server string for player version 9,
212 // but not documented. It corresponds to the equally undocumented
213 // windowlessDisable.
215 // This should be the standard order of parameters in the server
217 std::ostringstream serverString
;
218 serverString
<< "A=" << trueFalse(hasAudio
)
219 << "&SA=" << trueFalse(hasStreamingAudio
)
220 << "&SV=" << trueFalse(hasStreamingVideo
)
221 << "&EV=" << trueFalse(hasEmbeddedVideo
)
222 << "&MP3=" << trueFalse(hasMP3
)
223 << "&AE=" << trueFalse(hasAudioEncoder
)
224 << "&VE=" << trueFalse(hasVideoEncoder
)
225 << "&ACC=" << trueFalse(hasAccessibility
)
226 << "&PR=" << trueFalse(hasPrinting
)
227 << "&SP=" << trueFalse(hasScreenPlayback
)
228 << "&SB=" << trueFalse(hasScreenBroadcast
)
229 << "&DEB=" << trueFalse(isDebugger
)
230 << "&V=" << URL::encode(version
)
231 << "&M=" << URL::encode(manufacturer
)
232 << "&R=" << resX
<< "x" << resY
233 << "&DP=" << screenDPI
234 << "&COL=" << screenColor
235 << "&AR=" << pixelAspectRatio
236 << "&OS=" << URL::encode(os
)
238 << "&PT=" << playerType
239 << "&AVD=" << trueFalse(avHardwareDisable
)
240 << "&LFD=" << trueFalse(localFileReadDisable
)
241 << "&WD=" << trueFalse(windowlessDisable
)
242 << "&TLS=" << trueFalse(hasTLS
);
244 const int flags
= PropFlags::dontDelete
245 | PropFlags::dontEnum
| PropFlags::readOnly
;
247 o
.init_member("hasAccessibility", hasAccessibility
, flags
);
248 o
.init_member("pixelAspectRatio", pixelAspectRatio
, flags
);
249 o
.init_member("screenColor", screenColor
, flags
);
250 o
.init_member("screenDPI", screenDPI
, flags
);
251 o
.init_member("screenResolutionY", resY
, flags
);
252 o
.init_member("screenResolutionX", resX
, flags
);
253 o
.init_member("hasTLS", hasTLS
, flags
);
254 o
.init_member("hasVideoEncoder", hasVideoEncoder
, flags
);
255 o
.init_member("hasAudioEncoder", hasAudioEncoder
, flags
);
256 o
.init_member("hasMP3", hasMP3
, flags
);
257 o
.init_member("hasAudio", hasAudio
, flags
);
258 o
.init_member("serverString", serverString
.str(), flags
);
259 o
.init_member("version", version
, flags
);
260 o
.init_member("hasStreamingAudio", hasStreamingAudio
, flags
);
261 o
.init_member("hasStreamingVideo", hasStreamingVideo
, flags
);
262 o
.init_member("hasEmbeddedVideo", hasEmbeddedVideo
, flags
);
263 o
.init_member("hasPrinting", hasPrinting
, flags
);
264 o
.init_member("hasScreenPlayback", hasScreenPlayback
, flags
);
265 o
.init_member("hasScreenBroadcast", hasScreenBroadcast
, flags
);
266 o
.init_member("isDebugger", isDebugger
, flags
);
267 o
.init_member("playerType", playerType
, flags
);
268 o
.init_member("avHardwareDisable", avHardwareDisable
, flags
);
269 o
.init_member("localFileReadDisable", localFileReadDisable
, flags
);
270 o
.init_member("windowlessDisable", windowlessDisable
, flags
);
271 o
.init_member("os", os
, flags
);
272 o
.init_member("manufacturer", manufacturer
, flags
);
273 o
.init_member("language", language
, flags
);
277 attachSystemInterface(as_object
& proto
)
279 Global_as
& gl
= getGlobal(proto
);
281 VM
& vm
= getVM(proto
);
282 registerBuiltinObject(proto
, attachSystemSecurityInterface
,
283 getURI(vm
, "security"));
284 registerBuiltinObject(proto
, attachSystemCapabilitiesInterface
,
285 getURI(vm
, "capabilities"));
287 proto
.init_member("setClipboard",
288 gl
.createFunction(system_setClipboard
));
290 proto
.init_member("showSettings", vm
.getNative(2107, 0));
291 proto
.init_property("useCodepage", &system_usecodepage
,
292 &system_usecodepage
);
294 const int flags
= PropFlags::dontDelete
295 | PropFlags::dontEnum
296 | PropFlags::readOnly
297 | PropFlags::onlySWF6Up
;
299 proto
.init_property("exactSettings", &system_exactsettings
,
300 &system_exactsettings
, flags
);
304 // This function returns false if no arguments were passed, true if any
305 // arguments were passed at all, even if they are not strings. There is
306 // currently no known way of accessing the list of allowed domains.
308 system_security_allowdomain(const fn_call
& fn
)
310 LOG_ONCE(log_unimpl(_("System.security.allowDomain")));
312 return as_value(false);
314 return as_value(true);
319 system_security_allowinsecuredomain(const fn_call
& /*fn*/)
321 LOG_ONCE(log_unimpl(_("System.security.allowInsecureDomain")));
327 system_security_loadpolicyfile(const fn_call
& /*fn*/)
329 LOG_ONCE(log_unimpl(_("System.security.loadPolicyFile")));
334 system_setClipboard(const fn_call
& fn
)
340 const std::string
& s
= fn
.arg(0).to_string();
341 movie_root
& m
= getRoot(fn
);
342 m
.callInterface(HostMessage(HostMessage::SET_CLIPBOARD
, s
));
348 system_showsettings(const fn_call
& /*fn*/)
350 LOG_ONCE(log_unimpl(_("System.showSettings")));
354 // FIXME: should return true if shared object files
355 // are stored under an exact domain name (www.gnashdev.org or
356 // gnashdev.org); false if both are stored under gnashdev.org.
359 system_exactsettings(const fn_call
& fn
)
363 // Is always true until we implement it.
364 return as_value(true);
367 LOG_ONCE(log_unimpl(_("System.exactSettings")));
373 // FIXME: if true, SWF6+ should treat DisplayObjects as Latin
374 // charset variants. If false (default), as UtrueFalse-8.
377 system_usecodepage(const fn_call
& fn
)
381 // Is always false until we implement it.
382 return as_value(false);
385 LOG_ONCE(log_unimpl(_("System.useCodepage")));
391 systemLanguage(as_object
& proto
)
393 // Two-letter language code ('en', 'de') corresponding to ISO 639-1
394 // Chinese can be either zh-CN or zh-TW. English used to have a
395 // country (GB, US) qualifier, but that was dropped in version 7 of
397 // This method relies on getting a POSIX-style language code of the form
398 // "zh_TW.utf8", "zh_CN" or "it" from the VM.
399 // It is obviously very easy to extend support to all language codes, but
400 // some scripts rely on there being only 20 possible languages. It could
401 // be a run time option if it's important enough to care.
403 std::string lang
= getVM(proto
).getSystemLanguage();
405 const char* languages
[] = {"en", "fr", "ko", "ja", "sv",
406 "de", "es", "it", "zh", "pt",
407 "pl", "hu", "cs", "tr", "fi",
408 "da", "nl", "no", "ru"};
410 const size_t size
= arraySize(languages
);
412 if (std::find(languages
, languages
+ size
, lang
.substr(0, 2)) !=
414 if (lang
.substr(0, 2) == "zh") {
415 // Chinese is the only language since the pp version 7
416 // to need an additional qualifier.
417 if (lang
.substr(2, 3) == "_TW") lang
= "zh-TW";
418 else if (lang
.substr(2, 3) == "_CN") lang
= "zh-CN";
422 // All other matching cases: retain just the first
423 // two DisplayObjects.
428 // Unknown language. We also return this if
429 // getSystemLanguage() returns something unexpected.
436 } // anonymous namespace