~ubuntu-branches/ubuntu/saucy/gnash/saucy-proposed

« back to all changes in this revision

Viewing changes to libcore/asobj/flash/system/System_as.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Sindhudweep Narayan Sarkar
  • Date: 2009-10-07 00:06:10 UTC
  • mfrom: (1.1.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20091007000610-mj9rwqe774gizn1j
Tags: 0.8.6-0ubuntu1
new upstream release 0.8.6 (LP: #435897)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// System.cpp:  ActionScript "System" class, for Gnash.
 
2
//
 
3
//   Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
4
// 
 
5
// This program is free software; you can redistribute it and/or modify
 
6
// it under the terms of the GNU General Public License as published by
 
7
// the Free Software Foundation; either version 3 of the License, or
 
8
// (at your option) any later version.
 
9
// 
 
10
// This program is distributed in the hope that it will be useful,
 
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
// GNU General Public License for more details.
 
14
//
 
15
// You should have received a copy of the GNU General Public License
 
16
// along with this program; if not, write to the Free Software
 
17
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
18
//
 
19
 
 
20
#include "movie_root.h" // interface callback
 
21
#include "log.h"
 
22
#include "System_as.h"
 
23
#include "fn_call.h"
 
24
#include "smart_ptr.h" // for boost intrusive_ptr
 
25
#include "Global_as.h"
 
26
#include "builtin_function.h"
 
27
#include "NativeFunction.h" 
 
28
#include "VM.h" // for getPlayerVersion() 
 
29
#include "Object.h" // for getObjectInterface
 
30
 
 
31
#include <sstream>
 
32
 
 
33
namespace gnash {
 
34
 
 
35
 
 
36
// Forward declarations.
 
37
namespace {
 
38
 
 
39
    inline std::string trueFalse(bool x) { return x ? "t" : "f"; }
 
40
 
 
41
    template<typename T> inline void convertValue(const std::string& in,
 
42
            T& val);
 
43
 
 
44
    const std::string& systemLanguage(as_object& proto);
 
45
 
 
46
    as_value system_security_allowdomain(const fn_call& fn);
 
47
    as_value system_security_allowinsecuredomain(const fn_call& fn);
 
48
    as_value system_security_loadpolicyfile(const fn_call& fn);
 
49
    as_value system_setClipboard(const fn_call& fn);
 
50
    as_value system_showsettings(const fn_call& fn);
 
51
    as_value system_exactsettings(const fn_call& fn);
 
52
    as_value system_usecodepage(const fn_call& fn);
 
53
    void attachSystemSecurityInterface(as_object& o);
 
54
    void attachSystemCapabilitiesInterface(as_object& o);
 
55
    void attachSystemInterface(as_object& proto);
 
56
    
 
57
    // AS3 functions.
 
58
    as_value system_gc(const fn_call& fn);
 
59
    as_value system_pause(const fn_call& fn);
 
60
    as_value system_resume(const fn_call& fn);
 
61
 
 
62
        // List of domains that can access/modify local data
 
63
        std::vector<std::string> _allowDataAccess;
 
64
}
 
65
 
 
66
 
 
67
void
 
68
system_class_init(as_object& where, const ObjectURI& uri)
 
69
{
 
70
    registerBuiltinObject(where, attachSystemInterface, uri);
 
71
}
 
72
 
 
73
 
 
74
void
 
75
registerSystemNative(as_object& where)
 
76
{
 
77
    VM& vm = getVM(where);
 
78
    
 
79
    vm.registerNative(system_security_allowdomain, 12, 0);
 
80
    vm.registerNative(system_showsettings, 2107, 0);
 
81
    
 
82
    // From http://osflash.org/flashcoders/undocumented/asnative
 
83
    
 
84
    // Run once in startup script then deleted...
 
85
    // System.Capabilities.Query 11, 0    
 
86
    
 
87
    // System.Product.isRunning 2201, 0
 
88
    // System.Product.isInstalled 2201, 1
 
89
    // System.Product.launch 2201, 2
 
90
    // System.Product.download 2201, 3    
 
91
}
 
92
 
 
93
 
 
94
/// Get the current System.security allowDataAccess list of domains allowed to
 
95
/// access/modify local data
 
96
//
 
97
/// @return a std::vector of strings containing urls that can access local data
 
98
const std::vector<std::string>&
 
99
getAllowDataAccess()
 
100
{
 
101
        return _allowDataAccess;
 
102
}
 
103
 
 
104
 
 
105
/// Adds a string containing url or ip info to the allowDataAccess list of
 
106
/// domains that can access/modify local data
 
107
//
 
108
/// @param url a std::string containing the domain name
 
109
bool
 
110
addAllowDataAccess( const std::string& url )
 
111
{
 
112
        size_t s = _allowDataAccess.size();
 
113
        _allowDataAccess.push_back( url );      
 
114
 
 
115
        if( s+1 == _allowDataAccess.size()) return true;
 
116
 
 
117
        return false;
 
118
}
 
119
 
 
120
 
 
121
namespace {
 
122
 
 
123
void
 
124
attachSystemSecurityInterface(as_object& o)
 
125
{
 
126
    VM& vm = getVM(o);
 
127
    o.init_member("allowDomain", vm.getNative(12, 0));
 
128
 
 
129
    Global_as* gl = getGlobal(o);
 
130
    // TODO: only available when SWF >= 7 
 
131
    o.init_member("allowInsecureDomain",
 
132
            gl->createFunction(system_security_allowinsecuredomain));
 
133
    o.init_member("loadPolicyFile",
 
134
            gl->createFunction(system_security_loadpolicyfile));
 
135
}
 
136
 
 
137
void
 
138
attachSystemCapabilitiesInterface(as_object& o)
 
139
{
 
140
        RcInitFile& rcfile = RcInitFile::getDefaultInstance();
 
141
 
 
142
    //
 
143
    // Filesystem, access, miscellaneous hardware information
 
144
    //
 
145
 
 
146
    // "Windows XP", "Windows 2000", "Windows NT", "Windows 98/ME",
 
147
    // "Windows 95", "Windows CE", "Linux", "MacOS"
 
148
    // Override in gnashrc
 
149
    VM& vm = getVM(o);
 
150
    
 
151
    const std::string os = vm.getOSName();
 
152
 
 
153
    const std::string language = systemLanguage(o);
 
154
 
 
155
    // FIXME: these need to be implemented properly 
 
156
    // Does the NetStream object natively support SSL?
 
157
        const bool hasTLS = true;
 
158
 
 
159
    // Microphone and camera access disabled
 
160
        const bool avHardwareDisable = false;
 
161
        
 
162
        // Not sure: seems to be whether the movie can 'float' above web pages,
 
163
        // and is useful for disabling certain annoying adverts.
 
164
        const bool windowlessDisable = false;
 
165
 
 
166
        const bool hasPrinting = true;
 
167
        const bool hasAccessibility = true;
 
168
        const bool isDebugger = false;
 
169
        const bool localFileReadDisable = false;
 
170
 
 
171
    //
 
172
    // Display information (needs active GUI)
 
173
    //
 
174
 
 
175
    const movie_root& m = vm.getRoot();
 
176
 
 
177
    int screenResolutionX;
 
178
    convertValue(m.callInterface("System.capabilities.screenResolutionX"),
 
179
            screenResolutionX);
 
180
    int screenResolutionY;
 
181
    convertValue(m.callInterface("System.capabilities.screenResolutionY"),
 
182
            screenResolutionY);
 
183
    int screenDPI;
 
184
    convertValue(m.callInterface("System.capabilities.screenDPI"), screenDPI);
 
185
        
 
186
    // Documented to be a number, but is in fact a string.
 
187
    const std::string pixelAspectRatio = 
 
188
        m.callInterface("System.capabilities.pixelAspectRatio");
 
189
 
 
190
    // "StandAlone", "External", "PlugIn", "ActiveX" (get from GUI)
 
191
    const std::string playerType =
 
192
        m.callInterface("System.capabilities.playerType");
 
193
 
 
194
    const std::string screenColor =
 
195
        m.callInterface("System.capabilities.screenColor");
 
196
 
 
197
    //
 
198
    // Media
 
199
    //
 
200
        
 
201
    // Is audio available?
 
202
    const bool hasAudio = (vm.getRoot().runResources().soundHandler());
 
203
 
 
204
    // FIXME: these need to be implemented properly. They are mostly
 
205
    // self-explanatory.
 
206
    const bool hasAudioEncoder = true;
 
207
    const bool hasEmbeddedVideo = true;
 
208
    const bool hasIME = true;
 
209
    const bool hasMP3 = true;
 
210
    const bool hasScreenBroadcast = true;
 
211
    const bool hasScreenPlayback = true;
 
212
    const bool hasStreamingAudio = true;
 
213
    const bool hasStreamingVideo = true;
 
214
    const bool hasVideoEncoder = true;
 
215
 
 
216
    //
 
217
    // Player version
 
218
    //
 
219
 
 
220
    // "LNX 9,0,22,0", "MAC 8,0,99,0"
 
221
    // Override in gnashrc
 
222
    const std::string version = vm.getPlayerVersion();
 
223
 
 
224
    // "Macromedia Windows", "Macromedia Linux", "Macromedia MacOS"
 
225
    // Override in gnashrc
 
226
    const std::string manufacturer = rcfile.getFlashSystemManufacturer();
 
227
    
 
228
    // serverString
 
229
        // A URL-encoded string to send system info to a server.
 
230
        // Boolean values are represented as t or f.            
 
231
        // Privacy concerns should probably be addressed by     
 
232
        // allowing this string to be sent or not; individual   
 
233
        // values that might affect privacy can be overridden   
 
234
        // in gnashrc.
 
235
        
 
236
        // hasIME seems not to be included in the server string, though
 
237
        // it is documented to have a server string of IME.
 
238
        // Linux player version 9 has no hasIME property (but no need
 
239
        // to emulate that.)
 
240
        
 
241
        // TLS and hasTLS are documented for AS3, player version 9.
 
242
        //
 
243
        // WD is included in the server string for player version 9,
 
244
        // but not documented. It corresponds to the equally undocumented
 
245
        // windowlessDisable.
 
246
        
 
247
        // This should be the standard order of parameters in the server
 
248
        // string.
 
249
        std::ostringstream serverString;
 
250
        serverString << "A="    << trueFalse(hasAudio)
 
251
                        << "&SA="       << trueFalse(hasStreamingAudio)
 
252
                        << "&SV="       << trueFalse(hasStreamingVideo)
 
253
                        << "&EV="       << trueFalse(hasEmbeddedVideo)
 
254
                        << "&MP3="      << trueFalse(hasMP3)                                            
 
255
                        << "&AE="       << trueFalse(hasAudioEncoder)
 
256
                        << "&VE="       << trueFalse(hasVideoEncoder)
 
257
                        << "&ACC="      << trueFalse(hasAccessibility)
 
258
                        << "&PR="       << trueFalse(hasPrinting)
 
259
                        << "&SP="       << trueFalse(hasScreenPlayback) 
 
260
                        << "&SB="       << trueFalse(hasScreenBroadcast) 
 
261
                        << "&DEB="      << trueFalse(isDebugger)
 
262
                        << "&V="    << URL::encode(version)
 
263
                        << "&M="    << URL::encode(manufacturer)
 
264
                        << "&R="    << screenResolutionX << "x" << screenResolutionY
 
265
                        << "&DP="       << screenDPI
 
266
                        << "&COL="      << screenColor                                  
 
267
                        << "&AR="   << pixelAspectRatio
 
268
                        << "&OS="   << URL::encode(os)
 
269
                        << "&L="    << language                 
 
270
                        << "&PT="   << playerType
 
271
                        << "&AVD="      << trueFalse(avHardwareDisable) 
 
272
                        << "&LFD="      << trueFalse(localFileReadDisable)
 
273
                        << "&WD="   << trueFalse(windowlessDisable)
 
274
                        << "&TLS="      << trueFalse(hasTLS);
 
275
        
 
276
    const int flags = PropFlags::dontDelete
 
277
                    | PropFlags::dontEnum
 
278
                    | PropFlags::readOnly;
 
279
 
 
280
    o.init_member("version", version, flags);
 
281
    o.init_member("playerType", playerType, flags);
 
282
    o.init_member("os", os, flags);
 
283
    o.init_member("manufacturer", manufacturer, flags);
 
284
    o.init_member("language", language, flags);
 
285
    o.init_member("hasAudio", hasAudio, flags);
 
286
    o.init_member("screenResolutionX", screenResolutionX, flags);
 
287
    o.init_member("screenResolutionY", screenResolutionY, flags);
 
288
    o.init_member("screenColor", screenColor, flags);
 
289
    o.init_member("screenDPI", screenDPI, flags);
 
290
    o.init_member("pixelAspectRatio", pixelAspectRatio, flags);
 
291
    o.init_member("serverString", serverString.str(), flags);
 
292
    o.init_member("avHardwareDisable", avHardwareDisable, flags);
 
293
    o.init_member("hasAudioEncoder", hasAudioEncoder, flags);
 
294
    o.init_member("hasEmbeddedVideo", hasEmbeddedVideo, flags);
 
295
    o.init_member("hasIME", hasIME, flags);
 
296
    o.init_member("hasMP3", hasMP3, flags);
 
297
    o.init_member("hasPrinting", hasPrinting, flags);
 
298
    o.init_member("hasScreenBroadcast", hasScreenBroadcast, flags);
 
299
    o.init_member("hasScreenPlayback", hasScreenPlayback, flags);
 
300
    o.init_member("hasStreamingAudio", hasStreamingAudio, flags);
 
301
    o.init_member("hasStreamingVideo", hasStreamingVideo, flags);
 
302
    o.init_member("hasVideoEncoder", hasVideoEncoder, flags);
 
303
    o.init_member("hasAccessibility", hasAccessibility, flags);
 
304
    o.init_member("isDebugger", isDebugger, flags);
 
305
    o.init_member("localFileReadDisable", localFileReadDisable, flags);
 
306
    o.init_member("hasTLS", hasTLS, flags);
 
307
    o.init_member("windowlessDisable", windowlessDisable, flags);
 
308
}
 
309
 
 
310
/// Convert a string to the type passed in, making sure the target variable
 
311
/// is initialized.
 
312
template<typename T>
 
313
inline void
 
314
convertValue(const std::string& in, T& val)
 
315
{
 
316
    std::istringstream is(in);
 
317
    if (!(is >> val)) val = T();
 
318
 
319
 
 
320
void
 
321
attachSystemInterface(as_object& proto)
 
322
{
 
323
    Global_as* gl = getGlobal(proto);
 
324
 
 
325
    string_table& st = getStringTable(proto);
 
326
    registerBuiltinObject(proto, attachSystemSecurityInterface,
 
327
            ObjectURI(st.find("security"), 0));
 
328
    registerBuiltinObject(proto, attachSystemCapabilitiesInterface,
 
329
            ObjectURI(st.find("capabilities"), 0));
 
330
 
 
331
        proto.init_member("setClipboard", 
 
332
            gl->createFunction(system_setClipboard));
 
333
        
 
334
    VM& vm = getVM(proto);
 
335
        proto.init_member("showSettings", vm.getNative(2107, 0));
 
336
        proto.init_property("useCodepage", &system_usecodepage,
 
337
            &system_usecodepage);
 
338
 
 
339
    const int flags = PropFlags::dontDelete
 
340
                    | PropFlags::dontEnum
 
341
                    | PropFlags::readOnly
 
342
                    | PropFlags::onlySWF6Up;
 
343
 
 
344
    proto.init_property("exactSettings", &system_exactsettings,
 
345
            &system_exactsettings, flags);
 
346
 
 
347
}
 
348
 
 
349
// This function returns false if no arguments were passed, true if any
 
350
// arguments were passed at all, even if they are not strings. There is
 
351
// currently no known way of accessing the list of allowed domains.
 
352
as_value
 
353
system_security_allowdomain(const fn_call& fn)
 
354
{
 
355
        // NOTE: This is the AS2 version of allowDomain, the AS3 version is located
 
356
        // in Security_as.cpp
 
357
    if (!fn.nargs) {
 
358
        IF_VERBOSE_ASCODING_ERRORS(
 
359
            log_aserror("System.security.allowDomain requires at least one "
 
360
                "argument.");
 
361
        );
 
362
        return as_value(false);
 
363
    }
 
364
 
 
365
    LOG_ONCE(log_unimpl ("System.security.allowDomain currently stores "
 
366
                "domains but does nothing else.")); 
 
367
        for (unsigned int i = 0; i < fn.nargs; ++i) {
 
368
                addAllowDataAccess(fn.arg(i).to_string());
 
369
        }
 
370
    return as_value(true);
 
371
}
 
372
 
 
373
 
 
374
as_value
 
375
system_security_allowinsecuredomain(const fn_call& /*fn*/)
 
376
{
 
377
    LOG_ONCE(log_unimpl ("System.security.allowInsecureDomain") );
 
378
    return as_value();
 
379
}
 
380
 
 
381
 
 
382
as_value
 
383
system_security_loadpolicyfile(const fn_call& /*fn*/)
 
384
{
 
385
    LOG_ONCE(log_unimpl ("System.security.loadPolicyFile") );
 
386
    return as_value();
 
387
}
 
388
 
 
389
as_value
 
390
system_setClipboard(const fn_call& /*fn*/)
 
391
{
 
392
    LOG_ONCE(log_unimpl ("System.setClipboard") );
 
393
    return as_value();
 
394
}
 
395
 
 
396
as_value
 
397
system_showsettings(const fn_call& /*fn*/)
 
398
{
 
399
    LOG_ONCE(log_unimpl ("System.showSettings") );
 
400
    return as_value();
 
401
}
 
402
 
 
403
as_value
 
404
system_gc(const fn_call& /*fn*/)
 
405
{
 
406
    log_unimpl (__FUNCTION__);
 
407
    return as_value();
 
408
}
 
409
 
 
410
as_value
 
411
system_pause(const fn_call& /*fn*/)
 
412
{
 
413
    log_unimpl (__FUNCTION__);
 
414
    return as_value();
 
415
}
 
416
 
 
417
as_value
 
418
system_resume(const fn_call& /*fn*/)
 
419
{
 
420
    log_unimpl (__FUNCTION__);
 
421
    return as_value();
 
422
}
 
423
 
 
424
 
 
425
// FIXME: should return true if shared object files
 
426
// are stored under an exact domain name (www.gnashdev.org or
 
427
// gnashdev.org); false if both are stored under gnashdev.org.
 
428
// Can be set.
 
429
as_value
 
430
system_exactsettings(const fn_call& fn)
 
431
{
 
432
        boost::intrusive_ptr<as_object> obj = ensureType<as_object>(fn.this_ptr);
 
433
 
 
434
    // Getter
 
435
    if (fn.nargs == 0)
 
436
    {
 
437
        // Is always true until we implement it.
 
438
        return as_value(true);   
 
439
    }
 
440
    
 
441
    // Setter
 
442
    else 
 
443
    {
 
444
        LOG_ONCE(log_unimpl ("System.exactSettings") );
 
445
        return as_value();
 
446
    }
 
447
}
 
448
 
 
449
 
 
450
// FIXME: if true, SWF6+ should treat DisplayObjects as Latin
 
451
// charset variants. If false (default), as UtrueFalse-8.
 
452
// Can be set.
 
453
as_value
 
454
system_usecodepage(const fn_call& fn)
 
455
{
 
456
        boost::intrusive_ptr<as_object> obj = 
 
457
        ensureType<as_object>(fn.this_ptr);
 
458
 
 
459
    // Getter
 
460
    if (fn.nargs == 0)
 
461
    {
 
462
        // Is always false until we implement it.
 
463
        return as_value(false);   
 
464
    }
 
465
    
 
466
    // Setter
 
467
    else 
 
468
    {
 
469
        LOG_ONCE(log_unimpl ("System.useCodepage") );
 
470
        return as_value();
 
471
    }
 
472
}
 
473
 
 
474
 
 
475
 
 
476
const std::string&
 
477
systemLanguage(as_object& proto)
 
478
{
 
479
        // Two-letter language code ('en', 'de') corresponding to ISO 639-1
 
480
        // Chinese can be either zh-CN or zh-TW. English used to have a 
 
481
        // country (GB, US) qualifier, but that was dropped in version 7 of
 
482
    // the player.
 
483
        // This method relies on getting a POSIX-style language code of the form
 
484
        // "zh_TW.utf8", "zh_CN" or "it" from the VM.
 
485
        // It is obviously very easy to extend support to all language codes, but
 
486
        // some scripts rely on there being only 20 possible languages. It could
 
487
        // be a run time option if it's important enough to care.
 
488
 
 
489
        static std::string lang = getVM(proto).getSystemLanguage();
 
490
        
 
491
        const char* languages[] = {"en", "fr", "ko", "ja", "sv",
 
492
                                "de", "es", "it", "zh", "pt",
 
493
                                "pl", "hu", "cs", "tr", "fi",
 
494
                                "da", "nl", "no", "ru"};
 
495
        
 
496
        const unsigned int size = sizeof (languages) / sizeof (*languages);
 
497
        
 
498
        if (std::find(languages, languages + size, lang.substr(0,2)) != languages + size)
 
499
        {
 
500
                if (lang.substr(0,2) == "zh")
 
501
                {
 
502
                        // Chinese is the only language since the pp version 7
 
503
                        // to need an additional qualifier.
 
504
                        if (lang.substr(2, 3) == "_TW") lang = "zh-TW";
 
505
                        else if (lang.substr(2, 3) == "_CN") lang = "zh-CN";
 
506
                        else lang = "xu";
 
507
                }
 
508
                else
 
509
                {
 
510
                        // All other matching cases: retain just the first
 
511
                        // two DisplayObjects.
 
512
                        lang.erase(2);
 
513
                }
 
514
        }
 
515
        else
 
516
        {
 
517
                // Unknown language. We also return this if
 
518
                // getSystemLanguage() returns something unexpected. 
 
519
                lang = "xu";
 
520
        }
 
521
 
 
522
        return lang;
 
523
 
 
524
}
 
525
 
 
526
} // anonymous namespace
 
527
} // gnash namespace