~ubuntu-branches/ubuntu/natty/moon/natty

« back to all changes in this revision

Viewing changes to plugin/plugin-class.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2009-02-14 12:01:08 UTC
  • Revision ID: james.westby@ubuntu.com-20090214120108-06539vb25vhbd8bn
Tags: upstream-1.0
ImportĀ upstreamĀ versionĀ 1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 
2
/*
 
3
 * plugin-class.cpp: MoonLight browser plugin.
 
4
 *
 
5
 * Contact:
 
6
 *   Moonlight List (moonlight-list@lists.ximian.com)
 
7
 *
 
8
 * Copyright 2007 Novell, Inc. (http://www.novell.com)
 
9
 *
 
10
 * See the LICENSE file included with the distribution for details.
 
11
 *
 
12
 */
 
13
 
 
14
#ifdef HAVE_CONFIG_H
 
15
#include <config.h>
 
16
#endif
 
17
 
 
18
#include <ctype.h>
 
19
 
 
20
#include "plugin-class.h"
 
21
#include "browser-bridge.h"
 
22
#include "plugin.h"
 
23
 
 
24
#ifdef DEBUG
 
25
#define DEBUG_WARN_NOTIMPLEMENTED(x) printf ("not implemented: (%s)\n" G_STRLOC, x)
 
26
#define d(x) x
 
27
#else
 
28
#define DEBUG_WARN_NOTIMPLEMENTED(x)
 
29
#define d(x)
 
30
#endif
 
31
 
 
32
// debug scriptable object
 
33
#define ds(x)
 
34
 
 
35
// debug javascript
 
36
#define DEBUG_JAVASCRIPT 1
 
37
 
 
38
// warnings
 
39
#define w(x) x
 
40
 
 
41
#define IS_METHOD(id)         (((id) & 0x8000) != 0)
 
42
#define IS_PROPERTY(id)       (((id) & 0x4000) != 0)
 
43
 
 
44
enum PluginPropertyId {
 
45
        NoMapping = 0,
 
46
 
 
47
        // property names
 
48
        MoonId_ErrorCode = 0x4000,
 
49
        MoonId_ErrorType,
 
50
        MoonId_ErrorMessage,
 
51
        MoonId_LineNumber,
 
52
        MoonId_CharPosition,
 
53
        MoonId_XamlFile,
 
54
        MoonId_MethodName,
 
55
        MoonId_X,
 
56
        MoonId_Y,
 
57
        MoonId_Width,
 
58
        MoonId_Height,
 
59
        MoonId_Seconds,
 
60
        MoonId_Name,
 
61
        MoonId_Shift,
 
62
        MoonId_Ctrl,
 
63
        MoonId_Marker,
 
64
        MoonId_Key,
 
65
        MoonId_PlatformKeyCode,
 
66
        MoonId_Settings,
 
67
        MoonId_Content,
 
68
        MoonId_InitParams,
 
69
        MoonId_Id,
 
70
        MoonId_IsLoaded,
 
71
        MoonId_Source,
 
72
        MoonId_Background,
 
73
        MoonId_EnableFramerateCounter,
 
74
        MoonId_EnableRedrawRegions,
 
75
        MoonId_EnableHtmlAccess,
 
76
        MoonId_MaxFrameRate,
 
77
        MoonId_Version,
 
78
        MoonId_Windowless,
 
79
        MoonId_ActualHeight,
 
80
        MoonId_ActualWidth,
 
81
        MoonId_FullScreen,
 
82
        MoonId_Root,
 
83
        MoonId_Count,
 
84
        MoonId_ResponseText,
 
85
        MoonId_DeviceType,
 
86
        MoonId_IsInverted,
 
87
        MoonId_Handled,
 
88
 
 
89
        // event names (handled by the property setters)
 
90
        MoonId_BufferingProgressChanged,
 
91
        MoonId_Completed,
 
92
        MoonId_CurrentStateChanged,
 
93
        MoonId_DownloadProgressChanged,
 
94
        MoonId_GotFocus,
 
95
        MoonId_ImageFailed,
 
96
        MoonId_KeyDown,
 
97
        MoonId_KeyUp,
 
98
        MoonId_LostFocus,
 
99
        MoonId_Loaded,
 
100
        MoonId_MarkerReached,
 
101
        MoonId_MediaEnded,
 
102
        MoonId_MediaFailed,
 
103
        MoonId_MediaOpened,
 
104
        MoonId_MouseEnter,
 
105
        MoonId_MouseLeave,
 
106
        MoonId_MouseMove,
 
107
        MoonId_MouseLeftButtonDown,
 
108
        MoonId_MouseLeftButtonUp,
 
109
        MoonId_OnResize,
 
110
        MoonId_OnFullScreenChange,
 
111
        MoonId_OnError,
 
112
        MoonId_OnLoad,
 
113
 
 
114
        // method names
 
115
        MoonId_GetPosition = 0x8000,
 
116
        MoonId_CreateObject,
 
117
        MoonId_IsVersionSupported,
 
118
        MoonId_FindName,
 
119
        MoonId_CreateFromXaml,
 
120
        MoonId_CreateFromXamlDownloader,
 
121
        MoonId_Equals,
 
122
        MoonId_GetHost,
 
123
        MoonId_GetParent,
 
124
        MoonId_GetStylusInfo,
 
125
        MoonId_GetStylusPoints,
 
126
        MoonId_CaptureMouse,
 
127
        MoonId_ReleaseMouseCapture,
 
128
        MoonId_AddEventListener,
 
129
        MoonId_RemoveEventListener,
 
130
        MoonId_SetValue,
 
131
        MoonId_GetValue,
 
132
        MoonId_ToString,     
 
133
#if DEBUG_JAVASCRIPT
 
134
        MoonId_Printf,
 
135
        MoonId_DumpNameScope,
 
136
#endif
 
137
        MoonId_Add,
 
138
        MoonId_Remove,
 
139
        MoonId_RemoveAt,
 
140
        MoonId_Insert,
 
141
        MoonId_Clear,
 
142
        MoonId_GetItem,
 
143
        MoonId_GetItemByName,
 
144
        MoonId_Begin,
 
145
        MoonId_Pause,
 
146
        MoonId_Resume,
 
147
        MoonId_Seek,
 
148
        MoonId_Stop,
 
149
        MoonId_Play,
 
150
        MoonId_SetSource,
 
151
        MoonId_SetFontSource,
 
152
        MoonId_Abort,
 
153
        MoonId_Open,
 
154
        MoonId_GetResponseText,
 
155
        MoonId_Send,
 
156
        MoonId_AddStylusPoints,
 
157
        MoonId_GetBounds,
 
158
        MoonId_HitTest,
 
159
};
 
160
 
 
161
static char*
 
162
npidentifier_to_downstr (NPIdentifier id)
 
163
{
 
164
        if (!NPN_IdentifierIsString (id))
 
165
                return NULL;
 
166
 
 
167
        NPUTF8 *strname = NPN_UTF8FromIdentifier (id);
 
168
        char *p = strname;
 
169
        while (*p) {
 
170
                *p = g_ascii_tolower (*p);
 
171
                p++;
 
172
        }
 
173
 
 
174
        return strname;
 
175
}
 
176
 
 
177
enum MethodArgType {
 
178
        MethodArgTypeNone   = (0),
 
179
        MethodArgTypeVoid   = (1 << NPVariantType_Void),
 
180
        MethodArgTypeNull   = (1 << NPVariantType_Null),
 
181
        MethodArgTypeBool   = (1 << NPVariantType_Bool),
 
182
        MethodArgTypeInt32  = (1 << NPVariantType_Int32),
 
183
        MethodArgTypeDouble = (1 << NPVariantType_Double),
 
184
        MethodArgTypeString = (1 << NPVariantType_String),
 
185
        MethodArgTypeObject = (1 << NPVariantType_Object),
 
186
        MethodArgTypeAny    = (0xff)
 
187
};
 
188
 
 
189
static MethodArgType
 
190
decode_arg_ctype (char c)
 
191
{
 
192
        switch (c) {
 
193
        case 'v': return MethodArgTypeVoid;
 
194
        case 'n': return MethodArgTypeNull;
 
195
        case 'b': return MethodArgTypeBool;
 
196
        case 'i': return MethodArgTypeInt32;
 
197
        case 'd': return MethodArgTypeDouble;
 
198
        case 's': return MethodArgTypeString;
 
199
        case 'o': return MethodArgTypeObject;
 
200
        case '*': return MethodArgTypeAny;
 
201
        default:
 
202
                return MethodArgTypeNone;
 
203
        }
 
204
}
 
205
 
 
206
static MethodArgType
 
207
decode_arg_type (const char **in)
 
208
{
 
209
        MethodArgType t, type = MethodArgTypeNone;
 
210
        register const char *inptr = *in;
 
211
        
 
212
        if (*inptr == '(') {
 
213
                inptr++;
 
214
                while (*inptr && *inptr != ')') {
 
215
                        t = decode_arg_ctype (*inptr);
 
216
                        type = (MethodArgType) ((int) type | (int) t);
 
217
                        inptr++;
 
218
                }
 
219
        } else {
 
220
                type = decode_arg_ctype (*inptr);
 
221
        }
 
222
        
 
223
        inptr++;
 
224
        *in = inptr;
 
225
        
 
226
        return type;
 
227
}
 
228
 
 
229
/**
 
230
 * check_arg_list:
 
231
 * @arglist: a string representing an arg-list token (see grammar below)
 
232
 * @args: NPVariant argument count
 
233
 * @argv: NPVariant argument vector
 
234
 *
 
235
 * Checks that the NPVariant arguments satisfy the argument count and
 
236
 * types expected (provided via @typestr).
 
237
 *
 
238
 * The @typestr argument should follow the following syntax:
 
239
 *
 
240
 * simple-arg-type ::= "v" / "n" / "b" / "i" / "d" / "s" / "o" / "*"
 
241
 *                     ; each char represents one of the following
 
242
 *                     ; NPVariant types: Void, Null, Bool, Int32,
 
243
 *                     ; Double, String, Object and wildcard
 
244
 *
 
245
 * arg-type        ::= simple-arg-type / "(" 1*(simple-arg-type) ")"
 
246
 *
 
247
 * optional-args   ::= "[" *(arg-type) "]"
 
248
 *
 
249
 * arg-list        ::= *(arg-type) (optional-args)
 
250
 *
 
251
 *
 
252
 * Returns: %true if @argv matches the arg-list criteria specified in
 
253
 * @arglist or %false otherwise.
 
254
 **/
 
255
static bool
 
256
check_arg_list (const char *arglist, uint32_t argc, const NPVariant *argv)
 
257
{
 
258
        const char *inptr = arglist;
 
259
        MethodArgType mask;
 
260
        uint32_t i = 0;
 
261
        
 
262
        // check all of the required arguments
 
263
        while (*inptr && *inptr != '[' && i < argc) {
 
264
                mask = decode_arg_type (&inptr);
 
265
                if (!(mask & (1 << argv[i].type))) {
 
266
                        // argv[i] does not match any of the expected types
 
267
                        return false;
 
268
                }
 
269
                
 
270
                i++;
 
271
        }
 
272
        
 
273
        if (*inptr && *inptr != '[' && i < argc) {
 
274
                // we were not provided enough arguments
 
275
                return false;
 
276
        }
 
277
        
 
278
        // now check all of the optional arguments
 
279
        inptr++;
 
280
        while (*inptr && *inptr != ']' && i < argc) {
 
281
                mask = decode_arg_type (&inptr);
 
282
                if (!(mask & (1 << argv[i].type))) {
 
283
                        // argv[i] does not match any of the expected types
 
284
                        return false;
 
285
                }
 
286
                
 
287
                i++;
 
288
        }
 
289
        
 
290
        if (i < argc) {
 
291
                // we were provided too many arguments
 
292
                return false;
 
293
        }
 
294
        
 
295
        return true;
 
296
}
 
297
 
 
298
 
 
299
#define STRDUP_FROM_VARIANT(v) (g_strndup ((char *) NPVARIANT_TO_STRING (v).utf8characters, NPVARIANT_TO_STRING (v).utf8length))
 
300
#define STRLEN_FROM_VARIANT(v) ((size_t) NPVARIANT_TO_STRING (v).utf8length)
 
301
 
 
302
#define DEPENDENCY_OBJECT_FROM_VARIANT(obj) (((MoonlightDependencyObjectObject*) NPVARIANT_TO_OBJECT (obj))->GetDependencyObject ())
 
303
 
 
304
#define THROW_JS_EXCEPTION(meth)        \
 
305
        do {    \
 
306
                char *message = g_strdup_printf ("Error calling method: %s", meth);     \
 
307
                NPN_SetException (this, message);       \
 
308
                g_free (message);       \
 
309
                return true; \
 
310
        } while (0);    \
 
311
 
 
312
/* for use with bsearch & qsort */
 
313
static int
 
314
compare_mapping (const void *m1, const void *m2)
 
315
{
 
316
        MoonNameIdMapping *map1 = (MoonNameIdMapping*) m1;
 
317
        MoonNameIdMapping *map2 = (MoonNameIdMapping*) m2;
 
318
        return strcmp(map1->name, map2->name);
 
319
}
 
320
 
 
321
static int
 
322
map_name_to_id (NPIdentifier name, const MoonNameIdMapping mapping[], int count, bool include_silverlight2)
 
323
{
 
324
        char *strname = npidentifier_to_downstr (name);
 
325
        if (!strname)
 
326
                return NoMapping;
 
327
 
 
328
        MoonNameIdMapping key, *result;
 
329
 
 
330
        key.name = strname;
 
331
        result = (MoonNameIdMapping*)bsearch(&key, mapping, count,
 
332
                                             sizeof(MoonNameIdMapping), compare_mapping);
 
333
 
 
334
 
 
335
        NPN_MemFree (strname);
 
336
        if (!result)
 
337
                return NoMapping;
 
338
 
 
339
        if (result->flags != 0) {
 
340
                if (include_silverlight2) {
 
341
                        if ((result->flags & MAPPING_FLAG_SL2) == 0)
 
342
                                return NoMapping;
 
343
                }
 
344
                else {
 
345
                        if ((result->flags & MAPPING_FLAG_SL1) == 0)
 
346
                                return NoMapping;
 
347
                }
 
348
        }
 
349
 
 
350
        return result->id;
 
351
}
 
352
 
 
353
static const char *
 
354
map_moon_id_to_event_name (int moon_id)
 
355
{
 
356
        const char *name = NULL;
 
357
 
 
358
        switch (moon_id) {
 
359
        case MoonId_BufferingProgressChanged: name = "BufferingProgressChanged"; break;
 
360
        case MoonId_CurrentStateChanged:  name = "CurrentStateChanged"; break;
 
361
        case MoonId_DownloadProgressChanged: name = "DownloadProgressChanged"; break;
 
362
        case MoonId_GotFocus: name = "GotFocus"; break;
 
363
        case MoonId_KeyDown: name = "KeyDown"; break;
 
364
        case MoonId_KeyUp: name = "KeyUp"; break;
 
365
        case MoonId_LostFocus: name = "LostFocus"; break;
 
366
        case MoonId_Loaded: name = "Loaded"; break;
 
367
        case MoonId_MarkerReached: name = "MarkerReached"; break;
 
368
        case MoonId_MediaEnded: name = "MediaEnded"; break;
 
369
        case MoonId_MediaFailed: name = "MediaFailed"; break;
 
370
        case MoonId_MediaOpened: name = "MediaOpened"; break;
 
371
        case MoonId_MouseEnter: name = "MouseEnter"; break;
 
372
        case MoonId_MouseLeave: name = "MouseLeave"; break;
 
373
        case MoonId_MouseMove: name = "MouseMove"; break;
 
374
        case MoonId_MouseLeftButtonDown: name = "MouseLeftButtonDown"; break;
 
375
        case MoonId_MouseLeftButtonUp: name = "MouseLeftButtonUp"; break;
 
376
        case MoonId_OnResize: name = "Resize"; break;
 
377
        case MoonId_OnFullScreenChange: name = "FullScreenChange"; break;
 
378
        case MoonId_OnError: name = "Error"; break;
 
379
        case MoonId_OnLoad: name = "Load"; break;
 
380
        }
 
381
 
 
382
        return name;
 
383
}
 
384
 
 
385
 
 
386
void
 
387
string_to_npvariant (const char *value, NPVariant *result)
 
388
{
 
389
        char *retval;
 
390
 
 
391
        if (value)
 
392
                retval = NPN_strdup ((char *)value);
 
393
        else
 
394
                retval = NPN_strdup ("");
 
395
 
 
396
        STRINGZ_TO_NPVARIANT (retval, *result);
 
397
}
 
398
 
 
399
static void
 
400
value_to_variant (NPObject *npobj, Value *v, NPVariant *result, DependencyObject *parent_obj = NULL, DependencyProperty *parent_property = NULL)
 
401
{
 
402
        switch (v->GetKind ()) {
 
403
        case Type::BOOL:
 
404
                BOOLEAN_TO_NPVARIANT (v->AsBool(), *result);
 
405
                break;
 
406
        case Type::INT32:
 
407
                INT32_TO_NPVARIANT (v->AsInt32(), *result);
 
408
                break;
 
409
        case Type::DOUBLE:
 
410
                DOUBLE_TO_NPVARIANT (v->AsDouble(), *result);
 
411
                break;
 
412
        case Type::STRING:
 
413
                string_to_npvariant (v->AsString(), result);
 
414
                break;
 
415
        case Type::POINT: {
 
416
                MoonlightPoint *point = (MoonlightPoint *) NPN_CreateObject (((MoonlightObject *) npobj)->instance, MoonlightPointClass);
 
417
                point->point = *v->AsPoint ();
 
418
                OBJECT_TO_NPVARIANT (point, *result);
 
419
                break;
 
420
        }
 
421
        case Type::RECT: {
 
422
                MoonlightRect *rect = (MoonlightRect *) NPN_CreateObject (((MoonlightObject *) npobj)->instance, MoonlightRectClass);
 
423
                rect->rect = *v->AsRect ();
 
424
                OBJECT_TO_NPVARIANT (rect, *result);
 
425
                break;
 
426
        }
 
427
        case Type::DURATION: {
 
428
                MoonlightDuration *duration = (MoonlightDuration *) NPN_CreateObject (((MoonlightObject *) npobj)->instance, MoonlightDurationClass);
 
429
                duration->SetParentInfo (parent_obj, parent_property);
 
430
                OBJECT_TO_NPVARIANT (duration, *result);
 
431
                break;
 
432
        }
 
433
        case Type::TIMESPAN: {
 
434
                MoonlightTimeSpan *timespan = (MoonlightTimeSpan *) NPN_CreateObject (((MoonlightObject *) npobj)->instance, MoonlightTimeSpanClass);
 
435
                timespan->SetParentInfo (parent_obj, parent_property);
 
436
                OBJECT_TO_NPVARIANT (timespan, *result);
 
437
                break;
 
438
        }
 
439
        case Type::COLOR: {
 
440
                Color *c = v->AsColor ();
 
441
                gint32 color = ((((gint32)(c->a * 255.0)) << 24) | (((gint32)(c->r * 255.0)) << 16) | 
 
442
                        (((gint32)(c->g * 255.0)) << 8) | ((gint32)(c->b * 255.0)));
 
443
                INT32_TO_NPVARIANT (color, *result);
 
444
                break;
 
445
        }
 
446
        case Type::KEYTIME: {
 
447
                MoonlightKeyTime *keytime = (MoonlightKeyTime *) NPN_CreateObject (((MoonlightObject *) npobj)->instance, MoonlightKeyTimeClass);
 
448
                keytime->SetParentInfo (parent_obj, parent_property);
 
449
                OBJECT_TO_NPVARIANT (keytime, *result);
 
450
                break;
 
451
        }
 
452
        default:
 
453
                /* more builtins.. */
 
454
                if (v->Is (Type::DEPENDENCY_OBJECT)) {
 
455
                        MoonlightEventObjectObject *depobj =
 
456
                                EventObjectCreateWrapper (((MoonlightObject *) npobj)->instance, v->AsDependencyObject ());
 
457
                        OBJECT_TO_NPVARIANT (depobj, *result);
 
458
                }
 
459
                break;
 
460
        }
 
461
}
 
462
 
 
463
static void
 
464
variant_to_value (const NPVariant *v, Value **result)
 
465
{
 
466
        switch (v->type) {
 
467
        case NPVariantType_Bool:
 
468
                *result = new Value (NPVARIANT_TO_BOOLEAN (*v));
 
469
                break;
 
470
        case NPVariantType_Int32:
 
471
                *result = new Value ((int32_t) NPVARIANT_TO_INT32 (*v));
 
472
                break;
 
473
        case NPVariantType_Double:
 
474
                *result = new Value (NPVARIANT_TO_DOUBLE (*v));
 
475
                break;
 
476
        case NPVariantType_String: {
 
477
                char *value = STRDUP_FROM_VARIANT (*v);
 
478
                *result = new Value (value);
 
479
                g_free (value);
 
480
                break;
 
481
        }
 
482
        case NPVariantType_Void:
 
483
                DEBUG_WARN_NOTIMPLEMENTED ("void variant type");
 
484
                *result = NULL;
 
485
                break;
 
486
        case NPVariantType_Null:
 
487
                DEBUG_WARN_NOTIMPLEMENTED ("null variant type");
 
488
                *result = new Value (Type::DEPENDENCY_OBJECT);
 
489
                break;
 
490
        case NPVariantType_Object:
 
491
                // This should never happen, we should do type checking of the
 
492
                // arguments before this point and refuse arguments we don't understand.
 
493
                //d(printf ("Got invalid value from javascript.\n"));
 
494
                *result = new Value ();
 
495
                break;
 
496
        }
 
497
}
 
498
 
 
499
enum DependencyObjectClassNames {
 
500
        COLLECTION_CLASS,
 
501
        CONTROL_CLASS,
 
502
        DEPENDENCY_OBJECT_CLASS,
 
503
        DOWNLOADER_CLASS,
 
504
        IMAGE_BRUSH_CLASS,
 
505
        IMAGE_CLASS,
 
506
        MEDIA_ELEMENT_CLASS,
 
507
        STORYBOARD_CLASS,
 
508
        STYLUS_INFO_CLASS,
 
509
        STYLUS_POINT_COLLECTION_CLASS,
 
510
        STROKE_COLLECTION_CLASS,
 
511
        STROKE_CLASS,
 
512
        TEXT_BLOCK_CLASS,
 
513
        EVENT_ARGS_CLASS,
 
514
        ROUTED_EVENT_ARGS_CLASS,
 
515
        ERROR_EVENT_ARGS_CLASS,
 
516
        KEY_EVENT_ARGS_CLASS,
 
517
        MARKER_REACHED_EVENT_ARGS_CLASS,
 
518
        MOUSE_EVENT_ARGS_CLASS,
 
519
 
 
520
        DEPENDENCY_OBJECT_CLASS_NAMES_LAST
 
521
};
 
522
 
 
523
NPClass *dependency_object_classes[DEPENDENCY_OBJECT_CLASS_NAMES_LAST];
 
524
 
 
525
static bool
 
526
npobject_is_dependency_object (NPObject *obj)
 
527
{
 
528
        for (int i = 0; i < DEPENDENCY_OBJECT_CLASS_NAMES_LAST; i++) {
 
529
                if (dependency_object_classes [i] == obj->_class)
 
530
                        return true;
 
531
        }
 
532
        return false;
 
533
}
 
534
 
 
535
static bool
 
536
npvariant_is_dependency_object (NPVariant var)
 
537
{
 
538
        if (!NPVARIANT_IS_OBJECT (var))
 
539
                return false;
 
540
        
 
541
        return npobject_is_dependency_object (NPVARIANT_TO_OBJECT (var));
 
542
}
 
543
 
 
544
static bool
 
545
npvariant_is_object_class (NPVariant var, int type)
 
546
{
 
547
        NPObject *obj;
 
548
        
 
549
        if (type < 0 || type >= DEPENDENCY_OBJECT_CLASS_NAMES_LAST)
 
550
                return false;
 
551
        
 
552
        if (!NPVARIANT_IS_OBJECT (var))
 
553
                return false;
 
554
        
 
555
        obj = NPVARIANT_TO_OBJECT (var);
 
556
        
 
557
        return obj->_class == dependency_object_classes[type];
 
558
}
 
559
 
 
560
#define npvariant_is_downloader(v) npvariant_is_object_class (v, DOWNLOADER_CLASS)
 
561
 
 
562
static bool
 
563
npvariant_is_moonlight_object (NPVariant var)
 
564
{
 
565
        NPClass *moonlight_types[] = {
 
566
                MoonlightContentClass,
 
567
                MoonlightDurationClass,
 
568
                MoonlightObjectClass,
 
569
                MoonlightPointClass,
 
570
                MoonlightScriptableObjectClass,
 
571
                MoonlightScriptControlClass,
 
572
                MoonlightSettingsClass,
 
573
                MoonlightTimeSpanClass
 
574
        };
 
575
        NPObject *obj;
 
576
        guint i;
 
577
        
 
578
        if (!NPVARIANT_IS_OBJECT (var))
 
579
                return false;
 
580
        
 
581
        obj = NPVARIANT_TO_OBJECT (var);
 
582
        if (npobject_is_dependency_object (obj))
 
583
                return true;
 
584
        
 
585
        for (i = 0; i < G_N_ELEMENTS (moonlight_types); i++) {
 
586
                if (obj->_class == moonlight_types[i])
 
587
                        return true;
 
588
        }
 
589
        
 
590
        return false;
 
591
}
 
592
 
 
593
EventListenerProxy::EventListenerProxy (NPP instance, const char *event_name, const char *cb_name)
 
594
{
 
595
        this->instance = instance;
 
596
        this->event_name = g_strdup (event_name);
 
597
        this->event_id = -1;
 
598
        this->target_object = NULL;
 
599
        this->owner = NULL;
 
600
        this->one_shot = false;
 
601
        this->is_func = false;
 
602
        if (!strncmp (cb_name, "javascript:", strlen ("javascript:")))
 
603
                cb_name += strlen ("javascript:");
 
604
        this->callback = g_strdup (cb_name);
 
605
}
 
606
 
 
607
EventListenerProxy::EventListenerProxy (NPP instance, const char *event_name, const NPVariant *cb)
 
608
{
 
609
        this->instance = instance;
 
610
        this->event_name = g_strdup (event_name);
 
611
        this->event_id = -1;
 
612
        this->target_object = NULL;
 
613
        this->owner = NULL;
 
614
        this->one_shot = false;
 
615
 
 
616
        if (NPVARIANT_IS_OBJECT (*cb)) {
 
617
                this->is_func = true;
 
618
                this->callback = NPVARIANT_TO_OBJECT (*cb);
 
619
                NPN_RetainObject ((NPObject *) this->callback);
 
620
        } else {
 
621
                this->is_func = false;
 
622
                this->callback = STRDUP_FROM_VARIANT (*cb);
 
623
        }
 
624
}
 
625
 
 
626
EventListenerProxy::~EventListenerProxy ()
 
627
{
 
628
        if (is_func) {
 
629
// XXX we *want* to be able to do this, we really do, but we have no
 
630
// good means to invalidate EventListenerProxy, and thereby set the
 
631
// callback to NULL.
 
632
//
 
633
// instead we do it in ::RemoveHandler, which is only invoked via JS's removeEventListener
 
634
//
 
635
//              if (callback != NULL)
 
636
//                      NPN_ReleaseObject ((NPObject *) callback);
 
637
        }
 
638
        else {
 
639
                g_free (callback);
 
640
        }
 
641
        
 
642
        g_free (event_name);
 
643
}
 
644
        
 
645
const char *
 
646
EventListenerProxy::GetCallbackAsString ()
 
647
{
 
648
        if (is_func)
 
649
                return "";
 
650
        
 
651
        return (const char *)callback;
 
652
}
 
653
 
 
654
void
 
655
EventListenerProxy::SetOwner (MoonlightObject *owner)
 
656
{
 
657
        this->owner = owner;
 
658
}
 
659
 
 
660
int
 
661
EventListenerProxy::AddHandler (EventObject *obj)
 
662
{
 
663
        target_object = obj;
 
664
        
 
665
        event_id = obj->GetType()->LookupEvent (event_name);
 
666
 
 
667
        if (event_id == -1) {
 
668
                d(printf ("object of type `%s' does not provide an event named `%s'\n",
 
669
                          obj->GetTypeName(), event_name));
 
670
                return -1;
 
671
        }
 
672
 
 
673
        token = obj->AddHandler (event_id, proxy_listener_to_javascript, this, on_handler_removed);
 
674
        return token;
 
675
}
 
676
 
 
677
int
 
678
EventListenerProxy::AddXamlHandler (EventObject *obj)
 
679
{
 
680
        target_object = obj;
 
681
        
 
682
        event_id = obj->GetType()->LookupEvent (event_name);
 
683
        
 
684
        if (event_id == -1) {
 
685
                d(printf ("object of type `%s' does not provide an event named `%s'\n",
 
686
                          obj->GetTypeName(), event_name));
 
687
                return -1;
 
688
        }
 
689
        
 
690
        token = obj->AddXamlHandler (event_id, proxy_listener_to_javascript, this, on_handler_removed);
 
691
        
 
692
        return token;
 
693
}
 
694
 
 
695
void
 
696
EventListenerProxy::RemoveHandler ()
 
697
{
 
698
        if (target_object && event_id != -1) {
 
699
                target_object->RemoveHandler (event_id, token);
 
700
                if (callback != NULL)
 
701
                        NPN_ReleaseObject ((NPObject *) callback);
 
702
        }
 
703
        else {
 
704
                on_handler_removed (this);
 
705
        }
 
706
}
 
707
 
 
708
void
 
709
EventListenerProxy::on_handler_removed (gpointer closure)
 
710
{
 
711
        // by the time we get here, the target_object has disclaimed
 
712
        // all knowledge of this proxy.
 
713
 
 
714
        EventListenerProxy *proxy = (EventListenerProxy *) closure;
 
715
 
 
716
        if (proxy->owner) {
 
717
                proxy->owner->ClearEventProxy (proxy);
 
718
        }
 
719
        else {
 
720
                // we don't have an owner, so there's nothing special
 
721
                // for us to do here.
 
722
        }
 
723
 
 
724
        proxy->target_object = NULL;
 
725
        proxy->event_id = -1;
 
726
        proxy->unref_delayed();
 
727
}
 
728
 
 
729
void
 
730
EventListenerProxy::proxy_listener_to_javascript (EventObject *sender, EventArgs *calldata, gpointer closure)
 
731
{
 
732
        EventListenerProxy *proxy = (EventListenerProxy *) closure;
 
733
        EventObject *js_sender = sender;
 
734
        NPVariant args[2];
 
735
        NPVariant result;
 
736
        int argcount = 1;
 
737
        
 
738
        if (proxy->instance->pdata == NULL) {
 
739
                // Firefox can invalidate our NPObjects after the plugin itself
 
740
                // has been destroyed. During this invalidation our NPObjects call 
 
741
                // into the moonlight runtime, which then emits events.
 
742
                d(printf ("Moonlight: The plugin has been deleted, but we're still emitting events?\n"));
 
743
                return;
 
744
        }
 
745
 
 
746
        PluginInstance *plugin = (PluginInstance*) proxy->instance->pdata;
 
747
 
 
748
        if (js_sender->GetObjectType () == Type::SURFACE) {
 
749
                // This is somewhat hackish, but is required for
 
750
                // the FullScreenChanged event (js expects the
 
751
                // sender to be the toplevel canvas, not the surface,
 
752
                // nor the content).
 
753
                js_sender = ((Surface*) js_sender)->GetToplevel ();
 
754
        }
 
755
 
 
756
        MoonlightEventObjectObject *depobj = NULL; 
 
757
        if (js_sender) {
 
758
                depobj = EventObjectCreateWrapper (proxy->instance, js_sender);
 
759
                plugin->AddCleanupPointer (&depobj);
 
760
                OBJECT_TO_NPVARIANT (depobj, args[0]);
 
761
        } else {
 
762
                NULL_TO_NPVARIANT (args[0]);
 
763
        }
 
764
 
 
765
        //printf ("proxying event %s to javascript, sender = %p (%s)\n", proxy->event_name, sender, sender->GetTypeName ());
 
766
        MoonlightEventObjectObject *depargs = NULL; 
 
767
        if (calldata) {
 
768
                depargs = EventObjectCreateWrapper (proxy->instance, calldata);
 
769
                plugin->AddCleanupPointer (&depargs);
 
770
                OBJECT_TO_NPVARIANT (depargs, args[1]);
 
771
                argcount++;
 
772
        }
 
773
        
 
774
        if (proxy->is_func && proxy->callback) {
 
775
                /* the event listener was added with a JS function object */
 
776
                if (NPN_InvokeDefault (proxy->instance, (NPObject *) proxy->callback, args, argcount, &result))
 
777
                        NPN_ReleaseVariantValue (&result);
 
778
        } else {
 
779
                /* the event listener was added with a JS string (the function name) */
 
780
                NPObject *object = NULL;
 
781
                
 
782
                if (NPN_GetValue (proxy->instance, NPNVWindowNPObject, &object) == NPERR_NO_ERROR) {
 
783
                        if (NPN_Invoke (proxy->instance, object, NPID ((char *) proxy->callback), args, argcount, &result))
 
784
                                NPN_ReleaseVariantValue (&result);
 
785
                }
 
786
        }
 
787
 
 
788
        if (depobj) {
 
789
                plugin->RemoveCleanupPointer (&depobj);
 
790
                NPN_ReleaseObject (depobj);
 
791
        }
 
792
        if (depargs) {
 
793
                plugin->RemoveCleanupPointer (&depargs);
 
794
                NPN_ReleaseObject (depargs);
 
795
        }
 
796
        if (proxy->one_shot)
 
797
                proxy->RemoveHandler();
 
798
}
 
799
 
 
800
void
 
801
event_object_add_xaml_listener (EventObject *obj, PluginInstance *plugin, const char *event_name, const char *cb_name)
 
802
{
 
803
        EventListenerProxy *proxy = new EventListenerProxy (plugin->GetInstance (), event_name, cb_name);
 
804
        proxy->AddXamlHandler (obj);
 
805
}
 
806
 
 
807
class NamedProxyPredicate {
 
808
public:
 
809
        NamedProxyPredicate (char *name) { this->name = g_strdup (name); }
 
810
        ~NamedProxyPredicate () { g_free (name); }
 
811
 
 
812
        static bool matches (EventHandler cb_handler, gpointer cb_data, gpointer data)
 
813
        {
 
814
                if (cb_handler != EventListenerProxy::proxy_listener_to_javascript)
 
815
                        return false;
 
816
                if (cb_data == NULL)
 
817
                        return false;
 
818
                EventListenerProxy *proxy = (EventListenerProxy*)cb_data;
 
819
                NamedProxyPredicate *pred = (NamedProxyPredicate*)data;
 
820
 
 
821
                return !strcasecmp (proxy->GetCallbackAsString(), pred->name);
 
822
        }
 
823
private:
 
824
        char *name;
 
825
};
 
826
 
 
827
/*** EventArgs **/
 
828
 
 
829
static NPObject *
 
830
event_args_allocate (NPP instance, NPClass *klass)
 
831
{
 
832
        return new MoonlightEventArgs (instance);
 
833
}
 
834
 
 
835
MoonlightEventArgsType::MoonlightEventArgsType ()
 
836
{
 
837
        allocate = event_args_allocate;
 
838
}
 
839
 
 
840
MoonlightEventArgsType *MoonlightEventArgsClass;
 
841
 
 
842
/*** RoutedEventArgs ***/
 
843
static NPObject *
 
844
routedeventargs_allocate (NPP instance, NPClass *klass)
 
845
{
 
846
        return new MoonlightRoutedEventArgs (instance);
 
847
}
 
848
 
 
849
static const MoonNameIdMapping
 
850
routedeventargs_mapping[] = {
 
851
        { "source", MoonId_Source, MAPPING_FLAG_SL2 },
 
852
};
 
853
 
 
854
bool
 
855
MoonlightRoutedEventArgs::GetProperty (int id, NPIdentifier name, NPVariant *result)
 
856
{
 
857
        RoutedEventArgs *args = GetRoutedEventArgs ();
 
858
 
 
859
        switch (id) {
 
860
        case MoonId_Source: {
 
861
                DependencyObject *source = args->GetSource ();
 
862
                if (source) {
 
863
                        MoonlightEventObjectObject *source_obj = EventObjectCreateWrapper (instance, source);
 
864
                        OBJECT_TO_NPVARIANT (source_obj, *result);
 
865
                }
 
866
                else {
 
867
                        NULL_TO_NPVARIANT (*result);
 
868
                }
 
869
 
 
870
                return true;
 
871
        }
 
872
 
 
873
        default:
 
874
                return MoonlightEventArgs::GetProperty (id, name, result);
 
875
        }
 
876
}
 
877
 
 
878
MoonlightRoutedEventArgsType::MoonlightRoutedEventArgsType ()
 
879
{
 
880
        allocate = routedeventargs_allocate;
 
881
 
 
882
        AddMapping (routedeventargs_mapping, G_N_ELEMENTS (routedeventargs_mapping));
 
883
}
 
884
 
 
885
MoonlightRoutedEventArgsType *MoonlightRoutedEventArgsClass;
 
886
 
 
887
 
 
888
/*** ErrorEventArgs ***/
 
889
static NPObject *
 
890
erroreventargs_allocate (NPP instance, NPClass *klass)
 
891
{
 
892
        return new MoonlightErrorEventArgs (instance);
 
893
}
 
894
 
 
895
static const MoonNameIdMapping
 
896
erroreventargs_mapping[] = {
 
897
        { "charposition", MoonId_CharPosition },
 
898
        { "errorcode", MoonId_ErrorCode },
 
899
        { "errormessage", MoonId_ErrorMessage },
 
900
        { "errortype", MoonId_ErrorType },
 
901
        { "linenumber", MoonId_LineNumber },
 
902
        { "methodname", MoonId_MethodName },
 
903
        { "xamlfile", MoonId_XamlFile },
 
904
};
 
905
 
 
906
bool
 
907
MoonlightErrorEventArgs::GetProperty (int id, NPIdentifier name, NPVariant *result)
 
908
{
 
909
        ErrorEventArgs *args = GetErrorEventArgs ();
 
910
 
 
911
        switch (id) {
 
912
        case MoonId_ErrorCode:
 
913
                INT32_TO_NPVARIANT (args->error_code, *result);
 
914
                return true;
 
915
 
 
916
        case MoonId_ErrorType:
 
917
                switch (args->error_type) {
 
918
                case NoError:          string_to_npvariant ("NoError", result); break;
 
919
                case UnknownError:     string_to_npvariant ("UnknownError", result); break;
 
920
                case InitializeError:  string_to_npvariant ("InitializeError", result); break;
 
921
                case ParserError:      string_to_npvariant ("ParserError", result); break;
 
922
                case ObjectModelError: string_to_npvariant ("ObjectModelError", result); break;
 
923
                case RuntimeError:     string_to_npvariant ("RuntimeError", result); break;
 
924
                case DownloadError:    string_to_npvariant ("DownloadError", result); break;
 
925
                case MediaError:       string_to_npvariant ("MediaError", result); break;
 
926
                case ImageError:       string_to_npvariant ("ImageError", result); break;
 
927
                }
 
928
                return true;
 
929
        case MoonId_ErrorMessage:
 
930
                string_to_npvariant (args->error_message, result);
 
931
                return true;
 
932
        case MoonId_LineNumber:
 
933
                if (args->error_type == ParserError) {
 
934
                        INT32_TO_NPVARIANT (((ParserErrorEventArgs*)args)->line_number, *result);
 
935
                } else {
 
936
                        DEBUG_WARN_NOTIMPLEMENTED ("ErrorEventArgs.lineNumber");
 
937
                        INT32_TO_NPVARIANT (0, *result);
 
938
                }
 
939
                return true;
 
940
        case MoonId_CharPosition:
 
941
                if (args->error_type == ParserError) {
 
942
                        INT32_TO_NPVARIANT (((ParserErrorEventArgs*)args)->char_position, *result);
 
943
                } else {
 
944
                        DEBUG_WARN_NOTIMPLEMENTED ("ErrorEventArgs.charPosition");
 
945
                        INT32_TO_NPVARIANT (0, *result);
 
946
                }
 
947
                return true;
 
948
        case MoonId_MethodName:
 
949
                DEBUG_WARN_NOTIMPLEMENTED ("ErrorEventArgs.methodName");
 
950
                INT32_TO_NPVARIANT (0, *result);
 
951
                return true;
 
952
        case MoonId_XamlFile:
 
953
                if (args->error_type == ParserError) {
 
954
                        string_to_npvariant (((ParserErrorEventArgs*)args)->xaml_file, result);
 
955
                } else {
 
956
                        DEBUG_WARN_NOTIMPLEMENTED ("ErrorEventArgs.xamlFile");
 
957
                        NULL_TO_NPVARIANT (*result);
 
958
                }
 
959
                return true;
 
960
        default:
 
961
                return MoonlightEventArgs::GetProperty (id, name, result);
 
962
        }
 
963
}
 
964
 
 
965
MoonlightErrorEventArgsType::MoonlightErrorEventArgsType ()
 
966
{
 
967
        allocate = erroreventargs_allocate;
 
968
 
 
969
        AddMapping (erroreventargs_mapping, G_N_ELEMENTS (erroreventargs_mapping));
 
970
}
 
971
 
 
972
MoonlightErrorEventArgsType *MoonlightErrorEventArgsClass;
 
973
 
 
974
/*** Points ***/
 
975
static NPObject *
 
976
point_allocate (NPP instance, NPClass *klass)
 
977
{
 
978
        return new MoonlightPoint (instance);
 
979
}
 
980
 
 
981
static const MoonNameIdMapping
 
982
point_mapping[] = {
 
983
        { "x", MoonId_X },
 
984
        { "y", MoonId_Y }
 
985
};
 
986
 
 
987
 
 
988
bool
 
989
MoonlightPoint::GetProperty (int id, NPIdentifier name, NPVariant *result)
 
990
{
 
991
        switch (id) {
 
992
        case MoonId_X:
 
993
                DOUBLE_TO_NPVARIANT (point.x, *result);
 
994
                return true;
 
995
 
 
996
        case MoonId_Y:
 
997
                DOUBLE_TO_NPVARIANT (point.y, *result);
 
998
                return true;
 
999
 
 
1000
        default:
 
1001
                return MoonlightObject::GetProperty (id, name, result);
 
1002
        }
 
1003
}
 
1004
 
 
1005
bool
 
1006
MoonlightPoint::SetProperty (int id, NPIdentifier name, const NPVariant *value)
 
1007
{
 
1008
        switch (id) {
 
1009
        case MoonId_X:
 
1010
                point.x = NPVARIANT_TO_DOUBLE (*value);
 
1011
                return true;
 
1012
        case MoonId_Y:
 
1013
                point.y = NPVARIANT_TO_DOUBLE (*value);
 
1014
                return true;
 
1015
        default:
 
1016
                return MoonlightObject::SetProperty (id, name, value);
 
1017
        }
 
1018
}
 
1019
 
 
1020
MoonlightPointType::MoonlightPointType ()
 
1021
{
 
1022
        allocate = point_allocate;
 
1023
 
 
1024
        AddMapping (point_mapping, G_N_ELEMENTS (point_mapping));
 
1025
}
 
1026
 
 
1027
MoonlightPointType *MoonlightPointClass;
 
1028
 
 
1029
/*** Rects ***/
 
1030
static NPObject *
 
1031
rect_allocate (NPP instance, NPClass *klass)
 
1032
{
 
1033
        return new MoonlightRect (instance);
 
1034
}
 
1035
 
 
1036
static const MoonNameIdMapping
 
1037
rect_mapping[] = {
 
1038
        { "height", MoonId_Height },
 
1039
        { "width", MoonId_Width },
 
1040
        { "x", MoonId_X },
 
1041
        { "y", MoonId_Y },
 
1042
};
 
1043
 
 
1044
bool
 
1045
MoonlightRect::GetProperty (int id, NPIdentifier name, NPVariant *result)
 
1046
{
 
1047
        switch (id) {
 
1048
        case MoonId_X:
 
1049
                DOUBLE_TO_NPVARIANT (rect.x, *result);
 
1050
                return true;
 
1051
 
 
1052
        case MoonId_Y:
 
1053
                DOUBLE_TO_NPVARIANT (rect.y, *result);
 
1054
                return true;
 
1055
 
 
1056
        case MoonId_Width:
 
1057
                DOUBLE_TO_NPVARIANT (rect.width, *result);
 
1058
                return true;
 
1059
 
 
1060
        case MoonId_Height:
 
1061
                DOUBLE_TO_NPVARIANT (rect.height, *result);
 
1062
                return true;
 
1063
 
 
1064
        default:
 
1065
                return MoonlightObject::GetProperty (id, name, result);
 
1066
        }
 
1067
}
 
1068
 
 
1069
bool
 
1070
MoonlightRect::SetProperty (int id, NPIdentifier name, const NPVariant *value)
 
1071
{
 
1072
        switch (id) {
 
1073
        case MoonId_X:
 
1074
                rect.x = NPVARIANT_TO_DOUBLE (*value);
 
1075
                return true;
 
1076
 
 
1077
        case MoonId_Y:
 
1078
                rect.y = NPVARIANT_TO_DOUBLE (*value);
 
1079
                return true;
 
1080
 
 
1081
        case MoonId_Width:
 
1082
                rect.width = NPVARIANT_TO_DOUBLE (*value);
 
1083
                return true;
 
1084
 
 
1085
        case MoonId_Height:
 
1086
                rect.height = NPVARIANT_TO_DOUBLE (*value);
 
1087
                return true;
 
1088
 
 
1089
        default:
 
1090
                return MoonlightObject::SetProperty (id, name, value);;
 
1091
        }
 
1092
}
 
1093
 
 
1094
 
 
1095
MoonlightRectType::MoonlightRectType ()
 
1096
{
 
1097
        allocate = rect_allocate;
 
1098
 
 
1099
        AddMapping (rect_mapping, G_N_ELEMENTS (rect_mapping));
 
1100
}
 
1101
 
 
1102
MoonlightRectType *MoonlightRectClass;
 
1103
 
 
1104
 
 
1105
/*** Durations ***/
 
1106
static NPObject *
 
1107
duration_allocate (NPP instance, NPClass *klass)
 
1108
{
 
1109
        return new MoonlightDuration (instance);
 
1110
}
 
1111
 
 
1112
static const MoonNameIdMapping
 
1113
duration_mapping[] = {
 
1114
        { "name", MoonId_Name },
 
1115
        { "seconds", MoonId_Seconds }
 
1116
};
 
1117
 
 
1118
void
 
1119
MoonlightDuration::SetParentInfo (DependencyObject *parent_obj, DependencyProperty *parent_property)
 
1120
{
 
1121
        this->parent_obj = parent_obj;
 
1122
        this->parent_property = parent_property;
 
1123
        parent_obj->ref();
 
1124
}
 
1125
 
 
1126
double
 
1127
MoonlightDuration::GetValue()
 
1128
{
 
1129
        Value *v = parent_obj->GetValue (parent_property);
 
1130
        return v ? v->AsDuration()->ToSecondsFloat () : 0.0;
 
1131
}
 
1132
 
 
1133
bool
 
1134
MoonlightDuration::GetProperty (int id, NPIdentifier name, NPVariant *result)
 
1135
{
 
1136
        switch (id) {
 
1137
        case MoonId_Name:
 
1138
                string_to_npvariant ("", result);
 
1139
                return true;
 
1140
 
 
1141
        case MoonId_Seconds:
 
1142
                DOUBLE_TO_NPVARIANT (GetValue(), *result);
 
1143
                return true;
 
1144
 
 
1145
        default:
 
1146
                return MoonlightObject::GetProperty (id, name, result);
 
1147
        }
 
1148
}
 
1149
 
 
1150
bool
 
1151
MoonlightDuration::SetProperty (int id, NPIdentifier name, const NPVariant *value)
 
1152
{
 
1153
        switch (id) {
 
1154
        case MoonId_Name:
 
1155
                return true;
 
1156
 
 
1157
        case MoonId_Seconds:
 
1158
                parent_obj->SetValue (parent_property, Value(Duration::FromSecondsFloat (NPVARIANT_TO_DOUBLE (*value))));
 
1159
                return true;
 
1160
 
 
1161
        default:
 
1162
                return MoonlightObject::SetProperty (id, name, value);
 
1163
        }
 
1164
}
 
1165
 
 
1166
MoonlightDuration::~MoonlightDuration ()
 
1167
{
 
1168
        if (parent_obj)
 
1169
                parent_obj->unref();
 
1170
}
 
1171
 
 
1172
MoonlightDurationType::MoonlightDurationType ()
 
1173
{
 
1174
        allocate = duration_allocate;
 
1175
 
 
1176
        AddMapping (duration_mapping, G_N_ELEMENTS (duration_mapping));
 
1177
}
 
1178
 
 
1179
MoonlightDurationType *MoonlightDurationClass;
 
1180
 
 
1181
 
 
1182
/*** TimeSpans ***/
 
1183
static NPObject *
 
1184
timespan_allocate (NPP instance, NPClass *klass)
 
1185
{
 
1186
        return new MoonlightTimeSpan (instance);
 
1187
}
 
1188
 
 
1189
static const MoonNameIdMapping
 
1190
timespan_mapping[] = {
 
1191
        { "name", MoonId_Name },
 
1192
        { "seconds", MoonId_Seconds }
 
1193
};
 
1194
 
 
1195
void
 
1196
MoonlightTimeSpan::SetParentInfo (DependencyObject *parent_obj, DependencyProperty *parent_property)
 
1197
{
 
1198
        this->parent_obj = parent_obj;
 
1199
        this->parent_property = parent_property;
 
1200
        parent_obj->ref();
 
1201
}
 
1202
 
 
1203
TimeSpan
 
1204
MoonlightTimeSpan::GetValue()
 
1205
{
 
1206
        Value *v = parent_obj->GetValue (parent_property);
 
1207
        return v ? v->AsTimeSpan() : (TimeSpan)0;
 
1208
}
 
1209
 
 
1210
bool
 
1211
MoonlightTimeSpan::GetProperty (int id, NPIdentifier name, NPVariant *result)
 
1212
{
 
1213
        switch (id) {
 
1214
        case MoonId_Name:
 
1215
                string_to_npvariant ("", result);
 
1216
                return true;
 
1217
        case MoonId_Seconds:
 
1218
                DOUBLE_TO_NPVARIANT (TimeSpan_ToSecondsFloat (GetValue ()), *result);
 
1219
                return true;
 
1220
        default:
 
1221
                return MoonlightObject::GetProperty (id, name, result);
 
1222
        }
 
1223
}
 
1224
 
 
1225
bool
 
1226
MoonlightTimeSpan::SetProperty (int id, NPIdentifier name, const NPVariant *value)
 
1227
{
 
1228
        switch (id) {
 
1229
        case MoonId_Name:
 
1230
                return true;
 
1231
 
 
1232
        case MoonId_Seconds:
 
1233
                if (NPVARIANT_IS_INT32 (*value)) {
 
1234
                        parent_obj->SetValue (parent_property, Value(TimeSpan_FromSecondsFloat (NPVARIANT_TO_INT32 (*value)), Type::TIMESPAN));
 
1235
                } else if (NPVARIANT_IS_DOUBLE (*value)) {
 
1236
                        parent_obj->SetValue (parent_property, Value(TimeSpan_FromSecondsFloat (NPVARIANT_TO_DOUBLE (*value)), Type::TIMESPAN));
 
1237
                } else {
 
1238
                        return false;
 
1239
                }
 
1240
                return true;
 
1241
 
 
1242
        default:
 
1243
                return MoonlightObject::SetProperty (id, name, value);
 
1244
        }
 
1245
}
 
1246
 
 
1247
MoonlightTimeSpan::~MoonlightTimeSpan ()
 
1248
{
 
1249
        if (parent_obj)
 
1250
                parent_obj->unref ();
 
1251
}
 
1252
 
 
1253
MoonlightTimeSpanType::MoonlightTimeSpanType ()
 
1254
{
 
1255
        allocate = timespan_allocate;
 
1256
 
 
1257
        AddMapping (timespan_mapping, G_N_ELEMENTS (timespan_mapping));
 
1258
}
 
1259
 
 
1260
MoonlightTimeSpanType *MoonlightTimeSpanClass;
 
1261
 
 
1262
/*** KeyTime ***/
 
1263
static NPObject *
 
1264
keytime_allocate (NPP instance, NPClass *klass)
 
1265
{
 
1266
        return new MoonlightKeyTime (instance);
 
1267
}
 
1268
 
 
1269
static const MoonNameIdMapping
 
1270
keytime_mapping[] = {
 
1271
        { "name", MoonId_Name },
 
1272
        { "seconds", MoonId_Seconds }
 
1273
};
 
1274
 
 
1275
void
 
1276
MoonlightKeyTime::SetParentInfo (DependencyObject *parent_obj, DependencyProperty *parent_property)
 
1277
{
 
1278
        this->parent_obj = parent_obj;
 
1279
        this->parent_property = parent_property;
 
1280
        parent_obj->ref();
 
1281
}
 
1282
 
 
1283
KeyTime*
 
1284
MoonlightKeyTime::GetValue()
 
1285
{
 
1286
        Value *v = parent_obj->GetValue (parent_property);
 
1287
        return (v ? v->AsKeyTime() : NULL);
 
1288
}
 
1289
 
 
1290
bool
 
1291
MoonlightKeyTime::GetProperty (int id, NPIdentifier name, NPVariant *result)
 
1292
{
 
1293
        switch (id) {
 
1294
        case MoonId_Name:
 
1295
                string_to_npvariant ("", result);
 
1296
                return true;
 
1297
        case MoonId_Seconds:
 
1298
                DOUBLE_TO_NPVARIANT (TimeSpan_ToSecondsFloat (GetValue ()->GetTimeSpan ()), *result);
 
1299
                return true;
 
1300
        default:
 
1301
                return MoonlightObject::GetProperty (id, name, result);
 
1302
        }
 
1303
}
 
1304
 
 
1305
bool
 
1306
MoonlightKeyTime::SetProperty (int id, NPIdentifier name, const NPVariant *value)
 
1307
{
 
1308
        switch (id) {
 
1309
        case MoonId_Name:
 
1310
                return true;
 
1311
 
 
1312
        case MoonId_Seconds:
 
1313
                if (NPVARIANT_IS_INT32 (*value))
 
1314
                        parent_obj->SetValue (parent_property, Value(KeyTime::FromTimeSpan (TimeSpan_FromSecondsFloat (NPVARIANT_TO_INT32 (*value)))));
 
1315
                else if (NPVARIANT_IS_DOUBLE (*value)) 
 
1316
                        parent_obj->SetValue (parent_property, Value(KeyTime::FromTimeSpan (TimeSpan_FromSecondsFloat (NPVARIANT_TO_DOUBLE (*value)))));
 
1317
 
 
1318
                return true;
 
1319
        default:
 
1320
                return MoonlightObject::SetProperty (id, name, value);
 
1321
        }
 
1322
}
 
1323
 
 
1324
MoonlightKeyTime::~MoonlightKeyTime ()
 
1325
{
 
1326
        if (parent_obj)
 
1327
                parent_obj->unref ();
 
1328
}
 
1329
 
 
1330
MoonlightKeyTimeType::MoonlightKeyTimeType ()
 
1331
{
 
1332
        allocate = keytime_allocate;
 
1333
 
 
1334
        AddMapping (keytime_mapping, G_N_ELEMENTS (keytime_mapping));
 
1335
}
 
1336
 
 
1337
MoonlightKeyTimeType *MoonlightKeyTimeClass;
 
1338
 
 
1339
/*** MoonlightMouseEventArgsClass  **************************************************************/
 
1340
 
 
1341
static NPObject *
 
1342
mouse_event_allocate (NPP instance, NPClass *klass)
 
1343
{
 
1344
        return new MoonlightMouseEventArgsObject (instance);
 
1345
}
 
1346
 
 
1347
static const MoonNameIdMapping
 
1348
mouse_event_mapping[] = {
 
1349
        { "ctrl", MoonId_Ctrl },
 
1350
        { "handled", MoonId_Handled, MAPPING_FLAG_SL2 },
 
1351
        { "getposition", MoonId_GetPosition },
 
1352
        { "getstylusinfo", MoonId_GetStylusInfo },
 
1353
        { "getstyluspoints", MoonId_GetStylusPoints },
 
1354
        { "shift", MoonId_Shift },
 
1355
};
 
1356
 
 
1357
bool
 
1358
MoonlightMouseEventArgsObject::GetProperty (int id, NPIdentifier name, NPVariant *result)
 
1359
{
 
1360
        MouseEventArgs *event_args = GetMouseEventArgs ();
 
1361
        int state = event_args->GetState ();
 
1362
 
 
1363
        switch (id) {
 
1364
        case MoonId_Shift:
 
1365
                BOOLEAN_TO_NPVARIANT ((state & GDK_SHIFT_MASK) != 0, *result);
 
1366
                return true;
 
1367
 
 
1368
        case MoonId_Ctrl:
 
1369
                BOOLEAN_TO_NPVARIANT ((state & GDK_CONTROL_MASK) != 0, *result);
 
1370
                return true;
 
1371
 
 
1372
        case MoonId_Handled:
 
1373
                BOOLEAN_TO_NPVARIANT (event_args->GetHandled(), *result);
 
1374
                return true;
 
1375
 
 
1376
        default:
 
1377
                return MoonlightRoutedEventArgs::GetProperty (id, name, result);
 
1378
        }
 
1379
}
 
1380
 
 
1381
bool
 
1382
MoonlightMouseEventArgsObject::SetProperty (int id, NPIdentifier name, const NPVariant *value)
 
1383
{
 
1384
        MouseEventArgs *event_args = GetMouseEventArgs ();
 
1385
 
 
1386
        switch (id) {
 
1387
        case MoonId_Handled:
 
1388
                if (NPVARIANT_IS_BOOLEAN (*value))
 
1389
                        event_args->SetHandled (NPVARIANT_TO_BOOLEAN (*value));
 
1390
                return true;
 
1391
        default:
 
1392
                return MoonlightRoutedEventArgs::SetProperty (id, name, value);
 
1393
        }
 
1394
}
 
1395
 
 
1396
bool
 
1397
MoonlightMouseEventArgsObject::Invoke (int id, NPIdentifier name,
 
1398
                                       const NPVariant *args, uint32_t argCount,
 
1399
                                       NPVariant *result)
 
1400
{
 
1401
        MouseEventArgs *event_args = GetMouseEventArgs ();
 
1402
 
 
1403
        switch (id) {
 
1404
        case MoonId_GetPosition: {
 
1405
                if (!check_arg_list ("(no)", argCount, args) && (!NPVARIANT_IS_NULL(args[0]) || !npvariant_is_dependency_object (args[0])))
 
1406
                        return true;
 
1407
 
 
1408
                double x;
 
1409
                double y;
 
1410
 
 
1411
                // The argument is an element
 
1412
                // to calculate the position with respect to (or null
 
1413
                // for screen space)
 
1414
 
 
1415
                UIElement *el = NULL;
 
1416
 
 
1417
                if (npvariant_is_dependency_object (args[0])) {
 
1418
                        DependencyObject *dob = DEPENDENCY_OBJECT_FROM_VARIANT (args [0]);
 
1419
                        if (dob->Is (Type::UIELEMENT))
 
1420
                                el = (UIElement *)dob;
 
1421
                }
 
1422
 
 
1423
                event_args->GetPosition (el, &x, &y);
 
1424
 
 
1425
                MoonlightPoint *point = (MoonlightPoint*)NPN_CreateObject (instance, MoonlightPointClass);
 
1426
                point->point = Point (x, y);
 
1427
 
 
1428
                OBJECT_TO_NPVARIANT (point, *result);
 
1429
 
 
1430
                return true;
 
1431
        }
 
1432
        case MoonId_GetStylusInfo: {
 
1433
                if (argCount != 0)
 
1434
                        THROW_JS_EXCEPTION ("getStylusInfo");
 
1435
 
 
1436
                StylusInfo *info = event_args->GetStylusInfo ();
 
1437
                MoonlightEventObjectObject *info_obj = EventObjectCreateWrapper (instance, info);
 
1438
                info->unref ();
 
1439
                OBJECT_TO_NPVARIANT (info_obj, *result);
 
1440
                
 
1441
                return true;
 
1442
        }
 
1443
        case MoonId_GetStylusPoints: {
 
1444
                if (!check_arg_list ("o", argCount, args))
 
1445
                        THROW_JS_EXCEPTION ("getStylusPoints");
 
1446
 
 
1447
                if (npvariant_is_dependency_object (args[0])) {
 
1448
                        DependencyObject *dob = DEPENDENCY_OBJECT_FROM_VARIANT (args [0]);
 
1449
                        if (!dob->Is (Type::INKPRESENTER))
 
1450
                                THROW_JS_EXCEPTION ("getStylusPoints");
 
1451
                        
 
1452
                        StylusPointCollection *points = event_args->GetStylusPoints ((UIElement*)dob);
 
1453
                        MoonlightEventObjectObject *col_obj = EventObjectCreateWrapper (instance, points);
 
1454
                        points->unref ();
 
1455
                        OBJECT_TO_NPVARIANT (col_obj, *result);
 
1456
                }
 
1457
 
 
1458
                return true;
 
1459
        }
 
1460
        default:
 
1461
                return MoonlightRoutedEventArgs::Invoke (id, name, args, argCount, result);
 
1462
        }
 
1463
}
 
1464
 
 
1465
 
 
1466
MoonlightMouseEventArgsType::MoonlightMouseEventArgsType ()
 
1467
{
 
1468
        allocate = mouse_event_allocate;
 
1469
 
 
1470
        AddMapping (mouse_event_mapping, G_N_ELEMENTS (mouse_event_mapping));
 
1471
}
 
1472
 
 
1473
MoonlightMouseEventArgsType *MoonlightMouseEventArgsClass;
 
1474
 
 
1475
 
 
1476
/*** MoonlightMarkerReachedEventArgsClass  **************************************************************/
 
1477
 
 
1478
static NPObject *
 
1479
marker_reached_event_allocate (NPP instance, NPClass *klass)
 
1480
{
 
1481
        return new MoonlightMarkerReachedEventArgsObject (instance);
 
1482
}
 
1483
 
 
1484
static const MoonNameIdMapping
 
1485
marker_reached_event_mapping[] = {
 
1486
        { "marker", MoonId_Marker }
 
1487
};
 
1488
 
 
1489
bool
 
1490
MoonlightMarkerReachedEventArgsObject::GetProperty (int id, NPIdentifier name, NPVariant *result)
 
1491
{
 
1492
        MarkerReachedEventArgs *args = GetMarkerReachedEventArgs ();
 
1493
        TimelineMarker *marker = args ? args->GetMarker () : NULL;
 
1494
 
 
1495
        switch (id) {
 
1496
        case MoonId_Marker: {
 
1497
                MoonlightEventObjectObject *meoo = EventObjectCreateWrapper (instance, marker);
 
1498
                OBJECT_TO_NPVARIANT (meoo, *result);
 
1499
                return true;
 
1500
        }
 
1501
        default:
 
1502
                return MoonlightEventArgs::GetProperty (id, name, result);;
 
1503
        }
 
1504
}
 
1505
 
 
1506
MoonlightMarkerReachedEventArgsType::MoonlightMarkerReachedEventArgsType ()
 
1507
{
 
1508
        allocate = marker_reached_event_allocate;
 
1509
 
 
1510
        AddMapping (marker_reached_event_mapping, G_N_ELEMENTS (marker_reached_event_mapping));
 
1511
}
 
1512
 
 
1513
MoonlightMarkerReachedEventArgsType *MoonlightMarkerReachedEventArgsClass;
 
1514
 
 
1515
/*** MoonlightKeyEventArgsClass  **************************************************************/
 
1516
 
 
1517
static NPObject *
 
1518
keyboard_event_allocate (NPP instance, NPClass *klass)
 
1519
{
 
1520
        return new MoonlightKeyEventArgsObject (instance);
 
1521
}
 
1522
 
 
1523
static const MoonNameIdMapping
 
1524
keyboard_event_mapping[] = {
 
1525
        { "ctrl", MoonId_Ctrl },
 
1526
        { "handled", MoonId_Handled, MAPPING_FLAG_SL2 },
 
1527
        { "key", MoonId_Key },
 
1528
        { "platformkeycode", MoonId_PlatformKeyCode },
 
1529
        { "shift", MoonId_Shift },
 
1530
};
 
1531
 
 
1532
 
 
1533
bool
 
1534
MoonlightKeyEventArgsObject::GetProperty (int id, NPIdentifier name, NPVariant *result)
 
1535
{
 
1536
        KeyEventArgs *args = GetKeyEventArgs ();
 
1537
 
 
1538
        switch (id) {
 
1539
        case MoonId_Shift:
 
1540
                BOOLEAN_TO_NPVARIANT ((args->GetState () & GDK_SHIFT_MASK) != 0, *result);
 
1541
                return true;
 
1542
 
 
1543
        case MoonId_Ctrl:
 
1544
                BOOLEAN_TO_NPVARIANT ((args->GetState () & GDK_CONTROL_MASK) != 0, *result);
 
1545
                return true;
 
1546
 
 
1547
        case MoonId_Handled:
 
1548
                BOOLEAN_TO_NPVARIANT (args->GetHandled(), *result);
 
1549
                return true;
 
1550
 
 
1551
        case MoonId_Key:
 
1552
                INT32_TO_NPVARIANT (args->GetKey (), *result);
 
1553
                return true;
 
1554
 
 
1555
        case MoonId_PlatformKeyCode:
 
1556
                INT32_TO_NPVARIANT (args->GetPlatformKeyCode (), *result);
 
1557
                return true;
 
1558
 
 
1559
        default:
 
1560
                return MoonlightEventArgs::GetProperty (id, name, result);
 
1561
        }
 
1562
}
 
1563
 
 
1564
MoonlightKeyEventArgsType::MoonlightKeyEventArgsType ()
 
1565
{
 
1566
        allocate = keyboard_event_allocate;
 
1567
 
 
1568
        AddMapping (keyboard_event_mapping, G_N_ELEMENTS (keyboard_event_mapping));
 
1569
}
 
1570
 
 
1571
MoonlightKeyEventArgsType *MoonlightKeyEventArgsClass;
 
1572
 
 
1573
/*** our object base class */
 
1574
NPObject *
 
1575
_allocate (NPP instance, NPClass *klass)
 
1576
{
 
1577
        return new MoonlightObject (instance);
 
1578
}
 
1579
 
 
1580
static void
 
1581
_deallocate (NPObject *npobj)
 
1582
{
 
1583
        MoonlightObject *obj = (MoonlightObject *) npobj;
 
1584
        
 
1585
        delete obj;
 
1586
}
 
1587
 
 
1588
static void
 
1589
detach_xaml_proxy (gpointer key, gpointer value, gpointer closure)
 
1590
{
 
1591
        EventListenerProxy *proxy = (EventListenerProxy*)value;
 
1592
        proxy->SetOwner (NULL);
 
1593
}
 
1594
 
 
1595
MoonlightObject::~MoonlightObject ()
 
1596
{
 
1597
        if (event_listener_proxies) {
 
1598
                g_hash_table_foreach (event_listener_proxies, detach_xaml_proxy, NULL);
 
1599
                g_hash_table_destroy (event_listener_proxies);
 
1600
                event_listener_proxies = NULL;
 
1601
        }
 
1602
}
 
1603
 
 
1604
void
 
1605
MoonlightObject::destroy_proxy (gpointer data)
 
1606
{
 
1607
        EventListenerProxy *proxy = (EventListenerProxy*)data;
 
1608
        proxy->RemoveHandler ();
 
1609
}
 
1610
 
 
1611
bool
 
1612
MoonlightObject::HasProperty (NPIdentifier name)
 
1613
{
 
1614
        return IS_PROPERTY (LookupName (name));
 
1615
}
 
1616
 
 
1617
bool
 
1618
MoonlightObject::GetProperty (int id, NPIdentifier name, NPVariant *result)
 
1619
{
 
1620
        NULL_TO_NPVARIANT (*result);
 
1621
        THROW_JS_EXCEPTION ("AG_E_RUNTIME_GETVALUE");
 
1622
        return true;
 
1623
}
 
1624
 
 
1625
bool
 
1626
MoonlightObject::SetProperty (int id, NPIdentifier name, const NPVariant *value)
 
1627
{
 
1628
        THROW_JS_EXCEPTION ("AG_E_RUNTIME_SETVALUE");
 
1629
        return true;
 
1630
}
 
1631
 
 
1632
bool
 
1633
MoonlightObject::HasMethod (NPIdentifier name)
 
1634
{
 
1635
        return IS_METHOD (LookupName (name));
 
1636
}
 
1637
 
 
1638
bool
 
1639
MoonlightObject::Invoke (int id, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result)
 
1640
{
 
1641
        PluginInstance *plugin = (PluginInstance*) instance->pdata;
 
1642
 
 
1643
        switch (id) {
 
1644
        case MoonId_ToString:
 
1645
                if (argCount != 0)
 
1646
                        return false;
 
1647
 
 
1648
                if (moonlight_type != Type::INVALID) {
 
1649
                        if (plugin->IsSilverlight2 ()) {
 
1650
                                string_to_npvariant (Type::Find (moonlight_type)->name, result);
 
1651
                        } else {
 
1652
                                switch (moonlight_type) {
 
1653
                                        case Type::KEYEVENTARGS:
 
1654
                                                string_to_npvariant ("KeyboardEventArgs", result);
 
1655
                                                break;
 
1656
                                        default:
 
1657
                                                string_to_npvariant (Type::Find (moonlight_type)->name, result);
 
1658
                                                break;
 
1659
                                }
 
1660
                        }
 
1661
                        return true;
 
1662
                } else {
 
1663
                        //string_to_npvariant ("", result);
 
1664
                        NULL_TO_NPVARIANT (*result);
 
1665
                        return true;
 
1666
                }
 
1667
                break;
 
1668
        }
 
1669
 
 
1670
        return false;
 
1671
}
 
1672
 
 
1673
 
 
1674
EventListenerProxy *
 
1675
MoonlightObject::LookupEventProxy (int event_id)
 
1676
{
 
1677
        return (EventListenerProxy*)g_hash_table_lookup (event_listener_proxies, GINT_TO_POINTER (event_id));
 
1678
}
 
1679
 
 
1680
void
 
1681
MoonlightObject::SetEventProxy (EventListenerProxy *proxy)
 
1682
{
 
1683
        g_hash_table_insert (event_listener_proxies, GINT_TO_POINTER (proxy->GetEventId()), proxy);
 
1684
}
 
1685
 
 
1686
void
 
1687
MoonlightObject::ClearEventProxy (EventListenerProxy *proxy)
 
1688
{
 
1689
        proxy->SetOwner (NULL);
 
1690
 
 
1691
#if SANITY
 
1692
        EventListenerProxy *p = LookupEventProxy (proxy->GetEventId());
 
1693
        if (!p)
 
1694
                abort();
 
1695
#endif
 
1696
        g_hash_table_remove (event_listener_proxies, GINT_TO_POINTER (proxy->GetEventId()));
 
1697
}
 
1698
 
 
1699
 
 
1700
static void
 
1701
_invalidate (NPObject *npobj)
 
1702
{
 
1703
        MoonlightObject *obj = (MoonlightObject *) npobj;
 
1704
        
 
1705
        obj->Invalidate ();
 
1706
}
 
1707
 
 
1708
static bool
 
1709
_has_method (NPObject *npobj, NPIdentifier name)
 
1710
{
 
1711
        MoonlightObject *obj = (MoonlightObject *) npobj;
 
1712
        return obj->HasMethod (name);
 
1713
}
 
1714
 
 
1715
static bool
 
1716
_has_property (NPObject *npobj, NPIdentifier name)
 
1717
{
 
1718
        MoonlightObject *obj = (MoonlightObject *) npobj;
 
1719
        return obj->HasProperty (name);
 
1720
}
 
1721
 
 
1722
static bool
 
1723
_get_property (NPObject *npobj, NPIdentifier name, NPVariant *result)
 
1724
{
 
1725
        MoonlightObject *obj = (MoonlightObject *) npobj;
 
1726
        int id = obj->LookupName (name);
 
1727
        return obj->GetProperty (id, name, result);
 
1728
}
 
1729
 
 
1730
static bool
 
1731
_set_property (NPObject *npobj, NPIdentifier name, const NPVariant *value)
 
1732
{
 
1733
        MoonlightObject *obj = (MoonlightObject *) npobj;
 
1734
        int id = obj->LookupName (name);
 
1735
        return obj->SetProperty (id, name, value);
 
1736
}
 
1737
 
 
1738
static bool
 
1739
_remove_property (NPObject *npobj, NPIdentifier name)
 
1740
{
 
1741
        g_warning ("moonlight_object_remove_property reached");
 
1742
        return false;
 
1743
}
 
1744
 
 
1745
static bool
 
1746
_enumerate (NPObject *npobj, NPIdentifier **value, uint32_t *count)
 
1747
{
 
1748
        return ((MoonlightObjectType*)npobj->_class)->Enumerate (value, count);
 
1749
}
 
1750
 
 
1751
static bool
 
1752
_invoke (NPObject *npobj, NPIdentifier name,
 
1753
         const NPVariant *args, uint32_t argCount,
 
1754
         NPVariant *result)
 
1755
{
 
1756
        MoonlightObject *obj = (MoonlightObject *) npobj;
 
1757
        int id = obj->LookupName (name);
 
1758
        return obj->Invoke (id, name, args, argCount, result);
 
1759
}
 
1760
 
 
1761
static bool
 
1762
_invoke_default (NPObject *npobj,
 
1763
                 const NPVariant *args, uint32_t argCount,
 
1764
                 NPVariant *result)
 
1765
{
 
1766
        g_warning ("moonlight_object_invoke_default reached");
 
1767
        return false;
 
1768
}
 
1769
 
 
1770
static const MoonNameIdMapping
 
1771
object_mapping[] = {
 
1772
        { "tostring", MoonId_ToString },
 
1773
};
 
1774
 
 
1775
MoonlightObjectType::MoonlightObjectType ()
 
1776
{
 
1777
        allocate       = _allocate;
 
1778
        construct      = NULL;
 
1779
        deallocate     = _deallocate;
 
1780
        invalidate     = _invalidate;
 
1781
        hasMethod      = _has_method;
 
1782
        invoke         = _invoke;
 
1783
        invokeDefault  = _invoke_default;
 
1784
        hasProperty    = _has_property;
 
1785
        getProperty    = _get_property;
 
1786
        setProperty    = _set_property;
 
1787
        removeProperty = _remove_property;
 
1788
        enumerate      = _enumerate;
 
1789
 
 
1790
        mapping = NULL;
 
1791
        mapping_count = 0;
 
1792
 
 
1793
        AddMapping (object_mapping, G_N_ELEMENTS (object_mapping));
 
1794
 
 
1795
        last_lookup = NULL;
 
1796
        last_id = 0;
 
1797
}
 
1798
 
 
1799
bool
 
1800
MoonlightObjectType::Enumerate (NPIdentifier **value, uint32_t *count)
 
1801
{
 
1802
        if (mapping_count == 0) {
 
1803
                *value = NULL;
 
1804
                *count = 0;
 
1805
                return true;
 
1806
        }
 
1807
 
 
1808
        // caller frees this
 
1809
        NPIdentifier *ids = (NPIdentifier*)NPN_MemAlloc (sizeof (NPIdentifier) * mapping_count);
 
1810
 
 
1811
        for (int i = 0; i < mapping_count; i ++)
 
1812
                ids[i] = NPN_GetStringIdentifier (mapping[i].name);
 
1813
 
 
1814
        *count = mapping_count;
 
1815
        *value = ids;
 
1816
 
 
1817
        return true;
 
1818
}
 
1819
 
 
1820
void
 
1821
MoonlightObjectType::AddMapping (const MoonNameIdMapping *mapping, int count)
 
1822
{
 
1823
        if (this->mapping) {
 
1824
                MoonNameIdMapping *new_mapping = (MoonNameIdMapping *) g_new (MoonNameIdMapping, count + mapping_count);
 
1825
                
 
1826
                memmove (new_mapping, this->mapping, mapping_count * sizeof (MoonNameIdMapping));
 
1827
                memmove ((char *) new_mapping + (mapping_count * sizeof (MoonNameIdMapping)), mapping, count * sizeof (MoonNameIdMapping));
 
1828
                g_free (this->mapping);
 
1829
                this->mapping = new_mapping;
 
1830
                mapping_count += count;
 
1831
        } else {
 
1832
                this->mapping = (MoonNameIdMapping *) g_new (MoonNameIdMapping, count);
 
1833
                
 
1834
                memmove (this->mapping, mapping, count * sizeof (MoonNameIdMapping));
 
1835
                mapping_count = count;
 
1836
        }
 
1837
        
 
1838
        qsort (this->mapping, mapping_count, sizeof (MoonNameIdMapping), compare_mapping);
 
1839
}
 
1840
 
 
1841
int
 
1842
MoonlightObjectType::LookupName (NPIdentifier name, bool include_silverlight2)
 
1843
{
 
1844
        if (last_lookup == name)
 
1845
                return last_id;
 
1846
        
 
1847
        int id = map_name_to_id (name, mapping, mapping_count, include_silverlight2);
 
1848
        
 
1849
        if (id) {
 
1850
                /* only cache hits */
 
1851
                last_lookup = name;
 
1852
                last_id = id;
 
1853
        }
 
1854
        
 
1855
        return id;
 
1856
}
 
1857
 
 
1858
MoonlightObjectType *MoonlightObjectClass;
 
1859
 
 
1860
/*** MoonlightScriptControlClass **********************************************************/
 
1861
static NPObject *
 
1862
moonlight_scriptable_control_allocate (NPP instance, NPClass *klass)
 
1863
{
 
1864
        return new MoonlightScriptControlObject (instance);
 
1865
}
 
1866
 
 
1867
static const MoonNameIdMapping
 
1868
scriptable_control_mapping[] = {
 
1869
        { "content", MoonId_Content },
 
1870
        { "isloaded", MoonId_IsLoaded },
 
1871
        { "createobject", MoonId_CreateObject },
 
1872
        { "initparams", MoonId_InitParams },
 
1873
        { "id", MoonId_Id },
 
1874
        { "isversionsupported", MoonId_IsVersionSupported },
 
1875
        { "onerror", MoonId_OnError },
 
1876
        { "onload", MoonId_OnLoad },
 
1877
        { "settings", MoonId_Settings },
 
1878
        { "source", MoonId_Source },
 
1879
};
 
1880
 
 
1881
MoonlightScriptControlObject::~MoonlightScriptControlObject ()
 
1882
{
 
1883
        if (settings) {
 
1884
                NPN_ReleaseObject (settings);
 
1885
                settings = NULL;
 
1886
        }
 
1887
        
 
1888
        if (content) {
 
1889
                NPN_ReleaseObject (content);
 
1890
                content = NULL;
 
1891
        }
 
1892
}
 
1893
 
 
1894
void
 
1895
MoonlightScriptControlObject::Invalidate ()
 
1896
{
 
1897
        MoonlightObject::Invalidate ();
 
1898
 
 
1899
        settings = NULL;
 
1900
        content = NULL;
 
1901
}
 
1902
 
 
1903
bool
 
1904
MoonlightScriptControlObject::GetProperty (int id, NPIdentifier name, NPVariant *result)
 
1905
{
 
1906
        PluginInstance *plugin = (PluginInstance*) instance->pdata;
 
1907
        
 
1908
        switch (id) {
 
1909
        case MoonId_Settings:
 
1910
                NPN_RetainObject (settings);
 
1911
                OBJECT_TO_NPVARIANT (settings, *result);
 
1912
                return true;
 
1913
        case MoonId_Content:
 
1914
                NPN_RetainObject (content);
 
1915
                OBJECT_TO_NPVARIANT (content, *result);
 
1916
                return true;
 
1917
        case MoonId_InitParams:
 
1918
                string_to_npvariant (plugin->GetInitParams (), result);
 
1919
                return true;
 
1920
        case MoonId_IsLoaded:
 
1921
                if (!plugin->GetSurface ()) {
 
1922
                        BOOLEAN_TO_NPVARIANT (false, *result);
 
1923
                } else {
 
1924
                        BOOLEAN_TO_NPVARIANT (plugin->GetSurface()->IsLoaded(), *result);
 
1925
                }
 
1926
                return true;
 
1927
        case MoonId_OnError:
 
1928
        case MoonId_OnLoad: {
 
1929
                const char *event_name = map_moon_id_to_event_name (id);
 
1930
                EventObject *obj = plugin->GetSurface ();
 
1931
 
 
1932
                if (obj != NULL) {
 
1933
                        int event_id = obj->GetType()->LookupEvent (event_name);
 
1934
                        EventListenerProxy *proxy = LookupEventProxy (event_id);
 
1935
                        string_to_npvariant (proxy == NULL ? "" : proxy->GetCallbackAsString (), result);
 
1936
                } else {
 
1937
                        string_to_npvariant ("", result);
 
1938
                }
 
1939
                return true;
 
1940
        }
 
1941
        case MoonId_Source:
 
1942
                string_to_npvariant (plugin->GetSource (), result);
 
1943
                return true;
 
1944
 
 
1945
        case MoonId_Id: {
 
1946
                char *id = plugin->GetId ();
 
1947
                if (id)
 
1948
                        string_to_npvariant (id, result);
 
1949
                else 
 
1950
                        NULL_TO_NPVARIANT (*result);
 
1951
 
 
1952
                return true;
 
1953
        }
 
1954
        
 
1955
        default:
 
1956
                return MoonlightObject::GetProperty (id, name, result);
 
1957
        }
 
1958
}
 
1959
 
 
1960
bool
 
1961
MoonlightScriptControlObject::SetProperty (int id, NPIdentifier name, const NPVariant *value)
 
1962
{
 
1963
        PluginInstance *plugin = (PluginInstance*) instance->pdata;
 
1964
 
 
1965
        switch (id) {
 
1966
        case MoonId_Source: {
 
1967
                char *source = STRDUP_FROM_VARIANT (*value);
 
1968
                plugin->SetSource (source);
 
1969
                g_free (source);
 
1970
                return true;
 
1971
        }
 
1972
        case MoonId_OnError:
 
1973
        case MoonId_OnLoad: {
 
1974
                const char *event_name = map_moon_id_to_event_name (id);
 
1975
                EventObject *obj = plugin->GetSurface ();
 
1976
 
 
1977
                if (obj != NULL) {
 
1978
                        int event_id = obj->GetType()->LookupEvent (event_name);
 
1979
 
 
1980
                        if (event_id != -1) {
 
1981
                                EventListenerProxy *proxy = LookupEventProxy (event_id);
 
1982
                                if (proxy)
 
1983
                                        proxy->RemoveHandler ();
 
1984
 
 
1985
                                if (!NPVARIANT_IS_NULL (*value)) {
 
1986
                                        EventListenerProxy *proxy = new EventListenerProxy (instance,
 
1987
                                                                                            event_name,
 
1988
                                                                                            value);
 
1989
                                        proxy->SetOwner (this);
 
1990
                                        proxy->AddHandler (plugin->GetSurface());
 
1991
                                        // we only emit that event once, when
 
1992
                                        // the plugin is initialized, so don't
 
1993
                                        // leave it in the event list
 
1994
                                        // afterward.
 
1995
                                        if (id == MoonId_OnLoad)
 
1996
                                                proxy->SetOneShot ();
 
1997
                                        SetEventProxy (proxy);
 
1998
                                }
 
1999
 
 
2000
                                return true;
 
2001
                        }
 
2002
                }
 
2003
                return false;
 
2004
        }
 
2005
        default:
 
2006
                return MoonlightObject::SetProperty (id, name, value);
 
2007
        }
 
2008
}
 
2009
 
 
2010
bool
 
2011
MoonlightScriptControlObject::Invoke (int id, NPIdentifier name,
 
2012
                                      const NPVariant *args, uint32_t argCount,
 
2013
                                      NPVariant *result)
 
2014
{
 
2015
        switch (id) {
 
2016
        case MoonId_CreateObject: {
 
2017
                if (!check_arg_list ("s", argCount, args)) {
 
2018
                        NULL_TO_NPVARIANT (*result);
 
2019
                        return true;
 
2020
                }
 
2021
 
 
2022
                NPObject *obj = NULL;
 
2023
                char *object_type = STRDUP_FROM_VARIANT (args [0]);
 
2024
                if (!g_ascii_strcasecmp ("downloader", object_type)) {
 
2025
                        PluginInstance *plugin = (PluginInstance*) instance->pdata;
 
2026
                        Downloader *dl = PluginInstance::CreateDownloader (plugin);
 
2027
 
 
2028
                        obj = EventObjectCreateWrapper (instance, dl);
 
2029
                        dl->unref ();
 
2030
 
 
2031
                        OBJECT_TO_NPVARIANT (obj, *result);
 
2032
                        g_free (object_type);
 
2033
                        return true;
 
2034
                } else {
 
2035
                        NULL_TO_NPVARIANT (*result);
 
2036
                        g_free (object_type);
 
2037
 
 
2038
                        THROW_JS_EXCEPTION ("createObject");
 
2039
                        return true;
 
2040
                }
 
2041
        }
 
2042
 
 
2043
        case MoonId_IsVersionSupported: {
 
2044
                /* we support all 0.*, 1.0.* and 1.1.* versions. */
 
2045
                if (!check_arg_list ("s", argCount, args))
 
2046
                        return false;
 
2047
                
 
2048
                bool supported = true;
 
2049
                gchar *version_list = STRDUP_FROM_VARIANT (args [0]);
 
2050
                gchar **versions = g_strsplit (version_list, ".", 4);
 
2051
                char *version = NULL;
 
2052
                gint64 numbers [4];
 
2053
 
 
2054
                supported = versions [0] != NULL && versions [1] != NULL;
 
2055
 
 
2056
                if (supported) {
 
2057
                        for (int k = 0; k < 4; k++) {
 
2058
                                numbers [k] = 0;
 
2059
                                version = versions [k];
 
2060
                                
 
2061
                                if (version == NULL)
 
2062
                                        break;
 
2063
                                                        
 
2064
                                // Only allow ascii 0-9 characters in the numbers
 
2065
                                for (int i = 0; version [i] != 0; i++) {
 
2066
                                        if (version [i] < '0' || version [i] > '9') {
 
2067
                                                supported = false;
 
2068
                                                break;
 
2069
                                        }
 
2070
                                }
 
2071
                                
 
2072
                                numbers [k] = atoll (version);
 
2073
                        }
 
2074
                        
 
2075
                        switch (numbers [0]) {
 
2076
                        case 0: // We support all versions of the format "0.*"
 
2077
                                break;
 
2078
#if PLUGIN_SL_2_0
 
2079
                        case 1:
 
2080
                                supported &= numbers [1] <= 1; // 1.0* or 1.1*
 
2081
                                break;
 
2082
#else                           
 
2083
                        case 1:
 
2084
                                supported &= numbers [1] == 0; // 1.0*
 
2085
                                break;
 
2086
#endif
 
2087
                        default:
 
2088
                                supported = false;
 
2089
                                break;
 
2090
                        }
 
2091
                }
 
2092
                
 
2093
                //              d(printf ("version requested = '%s' (%s)\n", version_list, supported ? "yes" : "no"));
 
2094
                
 
2095
                BOOLEAN_TO_NPVARIANT (supported, *result);
 
2096
 
 
2097
                g_strfreev (versions);
 
2098
                g_free (version_list);
 
2099
 
 
2100
                return true;
 
2101
        }
 
2102
 
 
2103
        default:
 
2104
                return MoonlightObject::Invoke (id, name, args, argCount, result);
 
2105
        }
 
2106
}
 
2107
 
 
2108
MoonlightScriptControlType::MoonlightScriptControlType ()
 
2109
{
 
2110
        allocate = moonlight_scriptable_control_allocate;
 
2111
 
 
2112
        AddMapping (scriptable_control_mapping, G_N_ELEMENTS (scriptable_control_mapping));
 
2113
}
 
2114
 
 
2115
MoonlightScriptControlType *MoonlightScriptControlClass;
 
2116
 
 
2117
/*** MoonlightSettingsClass ***********************************************************/
 
2118
 
 
2119
static NPObject *
 
2120
moonlight_settings_allocate (NPP instance, NPClass *klass)
 
2121
{
 
2122
        return new MoonlightSettingsObject (instance);
 
2123
}
 
2124
 
 
2125
static const MoonNameIdMapping
 
2126
moonlight_settings_mapping [] = {
 
2127
        { "background", MoonId_Background },
 
2128
        { "enableframeratecounter", MoonId_EnableFramerateCounter },
 
2129
        { "enablehtmlaccess", MoonId_EnableHtmlAccess },
 
2130
        { "enableredrawregions", MoonId_EnableRedrawRegions },
 
2131
        { "maxframerate", MoonId_MaxFrameRate },
 
2132
        { "version", MoonId_Version },
 
2133
        { "windowless", MoonId_Windowless }
 
2134
};
 
2135
 
 
2136
bool
 
2137
MoonlightSettingsObject::GetProperty (int id, NPIdentifier name, NPVariant *result)
 
2138
{
 
2139
        PluginInstance *plugin = (PluginInstance*) instance->pdata;
 
2140
 
 
2141
        switch (id) {
 
2142
        case MoonId_Background:
 
2143
                string_to_npvariant (plugin->GetBackground (), result);
 
2144
                return true;
 
2145
 
 
2146
        case MoonId_EnableFramerateCounter:
 
2147
                BOOLEAN_TO_NPVARIANT (plugin->GetEnableFramerateCounter (), *result);
 
2148
                return true;
 
2149
 
 
2150
        case MoonId_EnableRedrawRegions:
 
2151
                BOOLEAN_TO_NPVARIANT (plugin->GetEnableRedrawRegions (), *result);
 
2152
                return true;
 
2153
 
 
2154
        case MoonId_EnableHtmlAccess:
 
2155
                BOOLEAN_TO_NPVARIANT (plugin->GetEnableHtmlAccess (), *result);
 
2156
                return true;
 
2157
 
 
2158
        // not implemented yet, just return 0.
 
2159
        case MoonId_MaxFrameRate:
 
2160
                INT32_TO_NPVARIANT (0, *result);
 
2161
                return true;
 
2162
 
 
2163
        case MoonId_Version:
 
2164
                string_to_npvariant (PLUGIN_VERSION, result);
 
2165
                return true;
 
2166
 
 
2167
        case MoonId_Windowless:
 
2168
                BOOLEAN_TO_NPVARIANT (plugin->GetWindowless (), *result);
 
2169
                return true;
 
2170
 
 
2171
        default:
 
2172
                return MoonlightObject::GetProperty (id, name, result);
 
2173
        }
 
2174
}
 
2175
 
 
2176
bool
 
2177
MoonlightSettingsObject::SetProperty (int id, NPIdentifier name, const NPVariant *value)
 
2178
{
 
2179
        PluginInstance *plugin = (PluginInstance*) instance->pdata;
 
2180
 
 
2181
        switch (id) {
 
2182
 
 
2183
        case MoonId_Background: {
 
2184
                char *color = STRDUP_FROM_VARIANT (*value);
 
2185
                if (!plugin->SetBackground (color)) {
 
2186
                        g_free (color);
 
2187
                        THROW_JS_EXCEPTION ("AG_E_RUNTIME_SETVALUE");
 
2188
                }
 
2189
                g_free (color);
 
2190
 
 
2191
                return true;
 
2192
        }
 
2193
        // Cant be set after initialization so return true
 
2194
        case MoonId_EnableFramerateCounter:
 
2195
                return true;
 
2196
 
 
2197
        case MoonId_EnableRedrawRegions:
 
2198
                plugin->SetEnableRedrawRegions (NPVARIANT_TO_BOOLEAN (*value));
 
2199
                return true;
 
2200
 
 
2201
        // Cant be set after initialization so return true
 
2202
        case MoonId_EnableHtmlAccess:
 
2203
                return true;
 
2204
 
 
2205
        // not implemented yet.
 
2206
        case MoonId_MaxFrameRate:
 
2207
                plugin->SetMaxFrameRate (NPVARIANT_TO_INT32 (*value));
 
2208
                return true;
 
2209
 
 
2210
        // Cant be set after initialization so return true
 
2211
        case MoonId_Windowless:
 
2212
                return true;
 
2213
        default:
 
2214
                return MoonlightObject::SetProperty (id, name, value);
 
2215
        }
 
2216
}
 
2217
 
 
2218
bool
 
2219
MoonlightSettingsObject::Invoke (int id, NPIdentifier name,
 
2220
                                 const NPVariant *args, uint32_t argCount, NPVariant *result)
 
2221
{
 
2222
        switch (id) {
 
2223
        case MoonId_ToString:
 
2224
                if (argCount != 0)
 
2225
                        return false;
 
2226
 
 
2227
                string_to_npvariant ("Settings", result);
 
2228
                return true;
 
2229
        default:
 
2230
                return MoonlightObject::Invoke (id, name, args, argCount, result);
 
2231
        }
 
2232
}
 
2233
 
 
2234
MoonlightSettingsType::MoonlightSettingsType ()
 
2235
{
 
2236
        allocate = moonlight_settings_allocate;
 
2237
        AddMapping (moonlight_settings_mapping, G_N_ELEMENTS (moonlight_settings_mapping));
 
2238
}
 
2239
 
 
2240
MoonlightSettingsType *MoonlightSettingsClass;
 
2241
 
 
2242
 
 
2243
/*** MoonlightContentClass ************************************************************/
 
2244
static NPObject *
 
2245
moonlight_content_allocate (NPP instance, NPClass *klass)
 
2246
{
 
2247
        return new MoonlightContentObject (instance);
 
2248
}
 
2249
 
 
2250
MoonlightContentObject::~MoonlightContentObject ()
 
2251
{
 
2252
        // FIXME: need to free registered scriptable objects
 
2253
        if (registered_scriptable_objects) {
 
2254
                g_hash_table_destroy (registered_scriptable_objects);
 
2255
                registered_scriptable_objects = NULL;
 
2256
        }
 
2257
}
 
2258
 
 
2259
static const MoonNameIdMapping
 
2260
moonlight_content_mapping[] = {
 
2261
        { "actualheight", MoonId_ActualHeight },
 
2262
        { "actualwidth", MoonId_ActualWidth },
 
2263
        { "createfromxaml", MoonId_CreateFromXaml },
 
2264
        { "createfromxamldownloader", MoonId_CreateFromXamlDownloader },
 
2265
        { "createobject", MoonId_CreateObject },
 
2266
        { "findname", MoonId_FindName },
 
2267
        { "fullscreen", MoonId_FullScreen },
 
2268
        { "onfullscreenchange", MoonId_OnFullScreenChange },
 
2269
        { "onresize", MoonId_OnResize },
 
2270
        { "root", MoonId_Root },
 
2271
};
 
2272
 
 
2273
bool
 
2274
MoonlightContentObject::HasProperty (NPIdentifier name)
 
2275
{
 
2276
        if (MoonlightObject::HasProperty (name))
 
2277
                return true;
 
2278
 
 
2279
        // FIXME: this is still case sensitive (uses a direct hash on the NPIdentifier)
 
2280
        return g_hash_table_lookup (registered_scriptable_objects, name) != NULL;
 
2281
}
 
2282
 
 
2283
bool
 
2284
MoonlightContentObject::GetProperty (int id, NPIdentifier name, NPVariant *result)
 
2285
{
 
2286
        PluginInstance *plugin = (PluginInstance*) instance->pdata;
 
2287
 
 
2288
        switch (id) {
 
2289
        case MoonId_ActualHeight:
 
2290
                INT32_TO_NPVARIANT (plugin->GetActualHeight (), *result);
 
2291
                return true;
 
2292
        case MoonId_ActualWidth:
 
2293
                INT32_TO_NPVARIANT (plugin->GetActualWidth (), *result);
 
2294
                return true;
 
2295
        case MoonId_FullScreen:
 
2296
                if (!plugin->GetSurface ()) {
 
2297
                        BOOLEAN_TO_NPVARIANT (false, *result);
 
2298
                } else {
 
2299
                        BOOLEAN_TO_NPVARIANT (plugin->GetSurface()->GetFullScreen (), *result);
 
2300
                }
 
2301
                return true;
 
2302
        case MoonId_OnResize:
 
2303
        case MoonId_OnFullScreenChange: {
 
2304
                Surface *surface = plugin->GetSurface ();
 
2305
                const char *event_name;
 
2306
                int event_id;
 
2307
        
 
2308
                if (surface == NULL) {
 
2309
                        string_to_npvariant ("", result);
 
2310
                } else {
 
2311
                        event_name = map_moon_id_to_event_name (id);
 
2312
                        event_id = surface->GetType()->LookupEvent (event_name);
 
2313
                        EventListenerProxy *proxy = LookupEventProxy (event_id);
 
2314
                        string_to_npvariant (proxy == NULL ? "" : proxy->GetCallbackAsString (), result);
 
2315
                }
 
2316
                return true;
 
2317
        }
 
2318
        case MoonId_Root: {
 
2319
                Surface *surface = plugin->GetSurface ();
 
2320
                DependencyObject *top;
 
2321
 
 
2322
                if (surface == NULL) {
 
2323
                        NULL_TO_NPVARIANT (*result);
 
2324
                } else if ((top = surface->GetToplevel ()) == NULL) {
 
2325
                        NULL_TO_NPVARIANT (*result);
 
2326
                } else {
 
2327
                        MoonlightEventObjectObject *topobj = EventObjectCreateWrapper (instance, top);
 
2328
 
 
2329
                        OBJECT_TO_NPVARIANT (topobj, *result);
 
2330
                }
 
2331
                return true;
 
2332
        }
 
2333
        case NoMapping: {
 
2334
                MoonlightScriptableObjectObject *obj;
 
2335
                gpointer val;
 
2336
                
 
2337
                if (!(val = g_hash_table_lookup (registered_scriptable_objects, name)))
 
2338
                        return false;
 
2339
                
 
2340
                obj = (MoonlightScriptableObjectObject *) val;
 
2341
                
 
2342
                NPN_RetainObject (obj);
 
2343
                OBJECT_TO_NPVARIANT (obj, *result);
 
2344
                return true;
 
2345
        }
 
2346
        default:
 
2347
                return MoonlightObject::GetProperty (id, name, result);
 
2348
        }
 
2349
}
 
2350
 
 
2351
bool
 
2352
MoonlightContentObject::SetProperty (int id, NPIdentifier name, const NPVariant *value)
 
2353
{
 
2354
        PluginInstance *plugin = (PluginInstance*) instance->pdata;
 
2355
        Surface *surface = NULL;
 
2356
 
 
2357
        switch (id) {
 
2358
        case MoonId_FullScreen:
 
2359
                surface = plugin->GetSurface ();
 
2360
                if (surface != NULL)
 
2361
                        surface->SetFullScreen (NPVARIANT_TO_BOOLEAN (*value));
 
2362
                return true;
 
2363
        case MoonId_OnFullScreenChange:
 
2364
        case MoonId_OnResize: {
 
2365
                const char *event_name = map_moon_id_to_event_name (id);
 
2366
                int event_id;
 
2367
 
 
2368
                surface = plugin->GetSurface ();
 
2369
                if (surface == NULL)
 
2370
                        return true;
 
2371
                        
 
2372
                event_id  = surface->GetType()->LookupEvent (event_name);
 
2373
 
 
2374
                if (event_id != -1) {
 
2375
                        EventListenerProxy *proxy = LookupEventProxy (event_id);
 
2376
                        if (proxy)
 
2377
                                proxy->RemoveHandler();
 
2378
 
 
2379
                        if (!NPVARIANT_IS_NULL (*value)) {
 
2380
                                EventListenerProxy *proxy = new EventListenerProxy (instance,
 
2381
                                                                                    event_name,
 
2382
                                                                                    value);
 
2383
                                proxy->SetOwner (this);
 
2384
                                proxy->AddHandler (plugin->GetSurface());
 
2385
                                SetEventProxy (proxy);
 
2386
                        }
 
2387
 
 
2388
                        return true;
 
2389
                }
 
2390
        }
 
2391
        default:
 
2392
                return MoonlightObject::SetProperty (id, name, value);
 
2393
        }
 
2394
}
 
2395
 
 
2396
bool
 
2397
MoonlightContentObject::Invoke (int id, NPIdentifier name,
 
2398
                                const NPVariant *args, uint32_t argCount, NPVariant *result)
 
2399
{
 
2400
        PluginInstance *plugin = (PluginInstance*) instance->pdata;
 
2401
        
 
2402
        switch (id) {
 
2403
        case MoonId_FindName: {
 
2404
                if (!check_arg_list ("s", argCount, args))
 
2405
                        THROW_JS_EXCEPTION ("AG_E_RUNTIME_FINDNAME");
 
2406
 
 
2407
                if (!plugin->GetSurface() || !plugin->GetSurface()->GetToplevel ())
 
2408
                        return true;
 
2409
 
 
2410
                char *name = STRDUP_FROM_VARIANT (args [0]);
 
2411
                DependencyObject *element = plugin->GetSurface()->GetToplevel ()->FindName (name);
 
2412
                g_free (name);
 
2413
 
 
2414
                if (!element) {
 
2415
                        NULL_TO_NPVARIANT (*result);
 
2416
                        return true;
 
2417
                }
 
2418
 
 
2419
                OBJECT_TO_NPVARIANT (EventObjectCreateWrapper (instance, element), *result);
 
2420
                return true;
 
2421
        }
 
2422
 
 
2423
        case MoonId_CreateObject:
 
2424
                // not implemented yet
 
2425
                DEBUG_WARN_NOTIMPLEMENTED ("content.createObject");
 
2426
                return true;
 
2427
 
 
2428
        case MoonId_CreateFromXaml: {
 
2429
                if (!check_arg_list ("s[b]", argCount, args))
 
2430
                        THROW_JS_EXCEPTION ("createFromXaml");
 
2431
                
 
2432
                bool create_namescope = argCount >= 2 ? NPVARIANT_TO_BOOLEAN (args[1]) : false;
 
2433
                char *xaml = STRDUP_FROM_VARIANT (args[0]);
 
2434
                
 
2435
                if (!xaml)
 
2436
                        THROW_JS_EXCEPTION ("createFromXaml");
 
2437
                
 
2438
                Type::Kind element_type;
 
2439
                XamlLoader *loader = PluginXamlLoader::FromStr (xaml, plugin, plugin->GetSurface());
 
2440
                DependencyObject *dep = loader->CreateFromString (xaml, create_namescope, &element_type);
 
2441
                delete loader;
 
2442
                g_free (xaml);
 
2443
                
 
2444
                if (!dep)
 
2445
                        THROW_JS_EXCEPTION ("createFromXaml");
 
2446
 
 
2447
                MoonlightEventObjectObject *depobj = EventObjectCreateWrapper (instance, dep);
 
2448
                dep->unref ();
 
2449
 
 
2450
                OBJECT_TO_NPVARIANT (depobj, *result);
 
2451
                return true;
 
2452
        }
 
2453
 
 
2454
        case MoonId_CreateFromXamlDownloader: {
 
2455
                if (!check_arg_list ("os", argCount, args))
 
2456
                        THROW_JS_EXCEPTION ("createFromXamlDownloader");
 
2457
                
 
2458
                Downloader *down = (Downloader*)((MoonlightDependencyObjectObject*) NPVARIANT_TO_OBJECT (args [0]))->GetDependencyObject ();
 
2459
                DependencyObject *dep = NULL;
 
2460
                Type::Kind element_type;
 
2461
                
 
2462
                char *path = STRDUP_FROM_VARIANT (args [1]);
 
2463
                char *fname = down->GetDownloadedFilename (path);
 
2464
                g_free (path);
 
2465
                
 
2466
                if (fname != NULL) {
 
2467
                        XamlLoader *loader = PluginXamlLoader::FromFilename (fname, plugin, plugin->GetSurface());
 
2468
                        dep = loader->CreateFromFile (fname, false, &element_type);
 
2469
                        delete loader;
 
2470
 
 
2471
                        g_free (fname);
 
2472
                }
 
2473
 
 
2474
                if (!dep)
 
2475
                        THROW_JS_EXCEPTION ("createFromXamlDownloader");
 
2476
 
 
2477
                OBJECT_TO_NPVARIANT (EventObjectCreateWrapper (instance, dep), *result);
 
2478
                dep->unref ();
 
2479
                return true;
 
2480
        }
 
2481
 
 
2482
        case MoonId_ToString: {
 
2483
                if (argCount != 0)
 
2484
                        return false;
 
2485
 
 
2486
                string_to_npvariant ("Content", result);
 
2487
                return true;
 
2488
        }
 
2489
 
 
2490
        default:
 
2491
                return MoonlightObject::Invoke (id, name, args, argCount, result);
 
2492
        }
 
2493
}
 
2494
 
 
2495
MoonlightContentType::MoonlightContentType ()
 
2496
{
 
2497
        allocate = moonlight_content_allocate;
 
2498
 
 
2499
        AddMapping (moonlight_content_mapping, G_N_ELEMENTS (moonlight_content_mapping));
 
2500
}
 
2501
 
 
2502
MoonlightContentType *MoonlightContentClass;
 
2503
 
 
2504
 
 
2505
 
 
2506
/*** MoonlightDependencyObjectClass ***************************************************/
 
2507
 
 
2508
static const MoonNameIdMapping
 
2509
moonlight_dependency_object_mapping [] = {
 
2510
        { "addeventlistener", MoonId_AddEventListener },
 
2511
        { "capturemouse", MoonId_CaptureMouse },
 
2512
#if DEBUG_JAVASCRIPT
 
2513
        { "dumpnamescope", MoonId_DumpNameScope },
 
2514
#endif
 
2515
        { "equals", MoonId_Equals },
 
2516
        { "findname", MoonId_FindName },
 
2517
        { "gethost", MoonId_GetHost },
 
2518
        { "getparent", MoonId_GetParent },
 
2519
        { "getvalue", MoonId_GetValue },
 
2520
        { "gotfocus", MoonId_GotFocus },
 
2521
        { "keydown", MoonId_KeyDown },
 
2522
        { "keyup", MoonId_KeyUp },
 
2523
        { "loaded", MoonId_Loaded },
 
2524
        { "lostfocus", MoonId_LostFocus },
 
2525
        { "mouseenter", MoonId_MouseEnter },
 
2526
        { "mouseleave", MoonId_MouseLeave },
 
2527
        { "mouseleftbuttondown", MoonId_MouseLeftButtonDown },
 
2528
        { "mouseleftbuttonup", MoonId_MouseLeftButtonUp },
 
2529
        { "mousemove", MoonId_MouseMove },
 
2530
#if DEBUG_JAVASCRIPT
 
2531
        { "printf", MoonId_Printf },
 
2532
#endif
 
2533
        { "releasemousecapture", MoonId_ReleaseMouseCapture },
 
2534
        { "removeeventlistener", MoonId_RemoveEventListener },
 
2535
        { "setvalue", MoonId_SetValue },
 
2536
};
 
2537
 
 
2538
static NPObject *
 
2539
moonlight_dependency_object_allocate (NPP instance, NPClass *klass)
 
2540
{
 
2541
        return new MoonlightDependencyObjectObject (instance);
 
2542
}
 
2543
 
 
2544
static DependencyProperty *
 
2545
_get_dependency_property (DependencyObject *obj, char *attrname)
 
2546
{
 
2547
        // don't need to downcase here since dependency property lookup is already case insensitive
 
2548
        DependencyProperty *p = obj->GetDependencyProperty (attrname);
 
2549
 
 
2550
        if (p)
 
2551
                return p;
 
2552
 
 
2553
        char *period = strchr (attrname, '.');
 
2554
        if (period) {
 
2555
                char *type_name = g_strndup (attrname, period-attrname);
 
2556
                attrname = period + 1;
 
2557
 
 
2558
                Type *type = Type::Find (type_name);
 
2559
 
 
2560
                if (type != NULL)
 
2561
                        p = DependencyProperty::GetDependencyProperty (type->type, attrname);
 
2562
 
 
2563
                g_free (type_name);
 
2564
        }
 
2565
 
 
2566
        return p;
 
2567
}
 
2568
 
 
2569
static bool
 
2570
_set_dependency_property_value (DependencyObject *dob, DependencyProperty *prop, const NPVariant *value, bool sl2)
 
2571
{
 
2572
        if (npvariant_is_moonlight_object (*value)) {
 
2573
                MoonlightObject *obj = (MoonlightObject *) NPVARIANT_TO_OBJECT (*value);
 
2574
                MoonlightDuration *duration;
 
2575
                MoonlightTimeSpan *ts;
 
2576
                MoonlightPoint *point;
 
2577
                MoonlightRect *rect;
 
2578
                
 
2579
                if (Type::IsSubclassOf (obj->moonlight_type, Type::DEPENDENCY_OBJECT) && obj->moonlight_type != Type::INVALID) {
 
2580
                        MoonlightDependencyObjectObject *depobj = (MoonlightDependencyObjectObject*) NPVARIANT_TO_OBJECT (*value);
 
2581
                        dob->SetValue (prop, Value (depobj->GetDependencyObject ()));
 
2582
                        
 
2583
                        return true;
 
2584
                }
 
2585
                
 
2586
                switch (obj->moonlight_type) {
 
2587
                case Type::TIMESPAN:
 
2588
                        ts = (MoonlightTimeSpan *) obj;
 
2589
                        dob->SetValue (prop, Value (ts->GetValue (), Type::TIMESPAN));
 
2590
                        break;
 
2591
                case Type::DURATION:
 
2592
                        duration = (MoonlightDuration *) obj;
 
2593
                        dob->SetValue (prop, Value (duration->GetValue ()));
 
2594
                        break;
 
2595
                case Type::RECT:
 
2596
                        rect = (MoonlightRect *) obj;
 
2597
                        dob->SetValue (prop, Value (rect->rect));
 
2598
                        break;
 
2599
                case Type::POINT:
 
2600
                        point = (MoonlightPoint *) obj;
 
2601
                        dob->SetValue (prop, Value (point->point));
 
2602
                        break;
 
2603
                default:
 
2604
                        d(printf ("unhandled object type %d - %s in do.set_property\n",
 
2605
                                  obj->moonlight_type, Type::Find (obj->moonlight_type)->name));
 
2606
                        w(printf ("unhandled object type in do.set_property\n"));
 
2607
                        return true;
 
2608
                }
 
2609
        } else {
 
2610
                char *strval = NULL;
 
2611
                char strbuf[64];
 
2612
                bool rv;
 
2613
                
 
2614
                if (NPVARIANT_IS_BOOLEAN (*value)) {
 
2615
                        if (NPVARIANT_TO_BOOLEAN (*value))
 
2616
                                strcpy (strbuf, "true");
 
2617
                        else
 
2618
                                strcpy (strbuf, "false");
 
2619
                        
 
2620
                        strval = strbuf;
 
2621
                } else if (NPVARIANT_IS_INT32 (*value)) {
 
2622
                        g_snprintf (strbuf, sizeof (strbuf), "%d", NPVARIANT_TO_INT32 (*value));
 
2623
                        
 
2624
                        strval = strbuf;
 
2625
                } else if (NPVARIANT_IS_DOUBLE (*value)) {
 
2626
                        g_snprintf (strbuf, sizeof (strbuf), "%g", NPVARIANT_TO_DOUBLE (*value));
 
2627
                        
 
2628
                        strval = strbuf;
 
2629
                } else if (NPVARIANT_IS_STRING (*value)) {
 
2630
                        strval = STRDUP_FROM_VARIANT (*value);
 
2631
                } else if (NPVARIANT_IS_NULL (*value)) {
 
2632
                        if (Type::IsSubclassOf (prop->GetPropertyType(), Type::DEPENDENCY_OBJECT)) {
 
2633
                                DependencyObject *val = NULL;
 
2634
                                
 
2635
                                dob->SetValue (prop, Value (val));
 
2636
                        } else if (prop->GetPropertyType() == Type::STRING) {
 
2637
                                char *val = NULL;
 
2638
                                
 
2639
                                dob->SetValue (prop, Value (val));
 
2640
                        } else 
 
2641
                                dob->SetValue (prop, NULL);
 
2642
                        
 
2643
                        return true;
 
2644
                } else if (NPVARIANT_IS_VOID (*value)) {
 
2645
                        d(printf ("unhandled variant type VOID in do.set_property for (%s::%s)\n",
 
2646
                                  dob->GetTypeName (), prop->GetName()));
 
2647
                        return true;
 
2648
                } else {
 
2649
                        d(printf ("unhandled variant type in do.set_property for (%s::%s)\n",
 
2650
                                  dob->GetTypeName (), prop->GetName()));
 
2651
                        return true;
 
2652
                }
 
2653
                
 
2654
                rv = xaml_set_property_from_str (dob, prop, strval, sl2);
 
2655
                
 
2656
                if (strval != strbuf)
 
2657
                        g_free (strval);
 
2658
                
 
2659
                return rv;
 
2660
        }
 
2661
        
 
2662
        return true;
 
2663
}
 
2664
 
 
2665
 
 
2666
bool
 
2667
MoonlightDependencyObjectObject::HasProperty (NPIdentifier name)
 
2668
{
 
2669
        if (MoonlightObject::HasProperty (name))
 
2670
                return true;
 
2671
 
 
2672
        DependencyObject *dob = GetDependencyObject ();
 
2673
 
 
2674
        // don't need to downcase here since dependency property lookup is already case insensitive
 
2675
        NPUTF8 *strname = NPN_UTF8FromIdentifier (name);
 
2676
        if (!strname)
 
2677
                return false;
 
2678
 
 
2679
        DependencyProperty *p = _get_dependency_property (dob, strname);
 
2680
        NPN_MemFree (strname);
 
2681
 
 
2682
        return (p != NULL);
 
2683
}
 
2684
 
 
2685
bool
 
2686
MoonlightDependencyObjectObject::GetProperty (int id, NPIdentifier name, NPVariant *result)
 
2687
{
 
2688
        // don't need to downcase here since dependency property lookup is already case insensitive
 
2689
        PluginInstance *plugin = (PluginInstance*) instance->pdata;
 
2690
        NPUTF8 *strname = NPN_UTF8FromIdentifier (name);
 
2691
        DependencyObject *dob = GetDependencyObject ();
 
2692
        DependencyProperty *prop;
 
2693
        const char *event_name;
 
2694
        int event_id;
 
2695
        Value *value;
 
2696
 
 
2697
        if (!strname)
 
2698
                return false;
 
2699
        
 
2700
        prop = _get_dependency_property (dob, strname);
 
2701
        NPN_MemFree (strname);
 
2702
        
 
2703
        if (prop) {
 
2704
                if (!(value = dob->GetValue (prop))) {
 
2705
                        // strings aren't null, they seem to just be empty strings
 
2706
                        if (prop->GetPropertyType() == Type::STRING) {
 
2707
                                string_to_npvariant ("", result);
 
2708
                                return true;
 
2709
                        }
 
2710
                        
 
2711
                        NULL_TO_NPVARIANT (*result);
 
2712
                        return true;
 
2713
                }
 
2714
                
 
2715
                if (value->GetKind () == Type::INT32) {
 
2716
                        const char *s = enums_int_to_str (prop->GetName(), value->AsInt32 (), plugin->IsSilverlight2());
 
2717
                        if (s)
 
2718
                                string_to_npvariant (s, result);
 
2719
                        else
 
2720
                                value_to_variant (this, value, result, dob, prop);
 
2721
                } else
 
2722
                        value_to_variant (this, value, result, dob, prop);
 
2723
                
 
2724
                return true;
 
2725
        }
 
2726
        
 
2727
        // it wasn't a dependency property.  let's see if it's an
 
2728
        // event, and hook it up if it is valid on this object.
 
2729
        if (!(event_name = map_moon_id_to_event_name (id)))
 
2730
                return MoonlightObject::GetProperty (id, name, result);
 
2731
        
 
2732
        if ((event_id = dob->GetType()->LookupEvent (event_name)) == -1) {
 
2733
#if false
 
2734
                EventListenerProxy *proxy = LookupEventProxy (event_id);
 
2735
                string_to_npvariant (proxy == NULL ? "" : proxy->GetCallbackAsString (), result);
 
2736
                return true;
 
2737
#else
 
2738
                // on silverlight, these seem to always return ""
 
2739
                // regardless of how we attempt to set them.
 
2740
                string_to_npvariant ("", result);
 
2741
                return true;
 
2742
#endif
 
2743
        }
 
2744
        
 
2745
        return MoonlightObject::GetProperty (id, name, result);
 
2746
}
 
2747
 
 
2748
bool
 
2749
MoonlightDependencyObjectObject::SetProperty (int id, NPIdentifier name, const NPVariant *value)
 
2750
{
 
2751
        // don't need to downcase here since dependency property lookup is already case insensitive
 
2752
        NPUTF8 *strname = NPN_UTF8FromIdentifier (name);
 
2753
        DependencyObject *dob = GetDependencyObject ();
 
2754
        DependencyProperty *prop;
 
2755
        
 
2756
        if (!strname)
 
2757
                return false;
 
2758
        
 
2759
        prop = _get_dependency_property (dob, strname);
 
2760
        NPN_MemFree (strname);
 
2761
        
 
2762
        if (prop) {
 
2763
                PluginInstance *plugin = (PluginInstance*) instance->pdata;
 
2764
                if (_set_dependency_property_value (dob, prop, value, plugin->IsSilverlight2())) {
 
2765
                        return true;
 
2766
                } else {
 
2767
                        THROW_JS_EXCEPTION ("AG_E_RUNTIME_SETVALUE");
 
2768
                }
 
2769
        }
 
2770
        
 
2771
        return MoonlightObject::SetProperty (id, name, value);
 
2772
}
 
2773
 
 
2774
bool
 
2775
MoonlightDependencyObjectObject::Invoke (int id, NPIdentifier name,
 
2776
                                         const NPVariant *args, uint32_t argCount,
 
2777
                                         NPVariant *result)
 
2778
{
 
2779
        DependencyObject *dob = GetDependencyObject ();
 
2780
 
 
2781
        switch (id) {
 
2782
#if DEBUG_JAVASCRIPT
 
2783
        // Some debug code...
 
2784
        // with this it is possible to do obj.printf ("msg") from js
 
2785
        case MoonId_Printf: {
 
2786
                char *message = STRDUP_FROM_VARIANT (args [0]);
 
2787
                fprintf (stderr, "JS message: %s\n", message);
 
2788
                g_free (message);
 
2789
                VOID_TO_NPVARIANT (*result);
 
2790
                return true;
 
2791
        }
 
2792
        case MoonId_DumpNameScope: {
 
2793
                fprintf (stderr, "dumping namescope for object %p (%s)\n", dob, dob->GetTypeName());
 
2794
                DependencyObject *ns_dob = dob;
 
2795
                NameScope *ns;
 
2796
                while (!(ns = NameScope::GetNameScope(ns_dob)))
 
2797
                        ns_dob = ns_dob->GetLogicalParent();
 
2798
                if (ns_dob == NULL)
 
2799
                        fprintf (stderr, " no namescope in logical hierarchy!\n");
 
2800
                else {
 
2801
                        if (ns_dob != dob)
 
2802
                                fprintf (stderr, "namescope is actually on object %p (%s)\n", ns_dob, ns_dob->GetTypeName());
 
2803
                        ns->Dump ();
 
2804
                }
 
2805
                return true;
 
2806
        }
 
2807
#endif
 
2808
        case MoonId_Equals: {
 
2809
                if (!check_arg_list ("o", argCount, args))
 
2810
                        THROW_JS_EXCEPTION ("equals");
 
2811
 
 
2812
                NPObject *o = NPVARIANT_TO_OBJECT (args[0]);
 
2813
                if (npobject_is_dependency_object (o)) {
 
2814
                        MoonlightDependencyObjectObject *obj = (MoonlightDependencyObjectObject *) o;
 
2815
                        
 
2816
                        BOOLEAN_TO_NPVARIANT (obj->GetDependencyObject() == dob, *result);
 
2817
                } else {
 
2818
                        BOOLEAN_TO_NPVARIANT (false, *result);
 
2819
                }
 
2820
                  
 
2821
                return true;
 
2822
        }
 
2823
 
 
2824
        case MoonId_SetValue: {
 
2825
                /* obj.setValue (prop, val) is another way of writing obj[prop] = val (or obj.prop = val) */
 
2826
                if (!check_arg_list ("s*", argCount, args))
 
2827
                        THROW_JS_EXCEPTION ("setValue");
 
2828
                
 
2829
                char *value = STRDUP_FROM_VARIANT (args [0]);
 
2830
                _class->setProperty (this, NPID (value), &args[1]);
 
2831
                g_free (value);
 
2832
 
 
2833
                VOID_TO_NPVARIANT (*result);
 
2834
                return true;
 
2835
        }
 
2836
 
 
2837
        case MoonId_GetValue: {
 
2838
                if (!check_arg_list ("s", argCount, args))
 
2839
                        THROW_JS_EXCEPTION ("getValue");
 
2840
 
 
2841
                char *value = STRDUP_FROM_VARIANT (args [0]);
 
2842
                _class->getProperty (this, NPID (value), result);
 
2843
                g_free (value);
 
2844
                
 
2845
                return true;
 
2846
        }
 
2847
 
 
2848
        case MoonId_FindName: {
 
2849
                if (!check_arg_list ("s", argCount, args))
 
2850
                        THROW_JS_EXCEPTION ("AG_E_RUNTIME_FINDNAME");
 
2851
 
 
2852
                char *name = STRDUP_FROM_VARIANT (args [0]);
 
2853
 
 
2854
                DependencyObject *element = dob->FindName (name);
 
2855
                g_free (name);
 
2856
                if (!element) {
 
2857
                        NULL_TO_NPVARIANT (*result);
 
2858
                        return true;
 
2859
                }
 
2860
 
 
2861
                OBJECT_TO_NPVARIANT (EventObjectCreateWrapper (instance, element), *result);
 
2862
                return true;
 
2863
        }
 
2864
 
 
2865
        case MoonId_GetHost: {
 
2866
                PluginInstance *plugin = (PluginInstance*) instance->pdata;
 
2867
                
 
2868
                if (argCount != 0)
 
2869
                        THROW_JS_EXCEPTION ("AG_E_RUNTIME_GETHOST");
 
2870
 
 
2871
                OBJECT_TO_NPVARIANT (plugin->GetHost (), *result);
 
2872
 
 
2873
                return true;
 
2874
        }
 
2875
 
 
2876
        case MoonId_GetParent: {
 
2877
                if (argCount != 0 || !dob->GetType ()->IsSubclassOf (Type::UIELEMENT))
 
2878
                        THROW_JS_EXCEPTION ("AG_E_RUNTIME_GETPARENT");
 
2879
                
 
2880
                DependencyObject *parent = dob->GetLogicalParent ();
 
2881
                if (parent)
 
2882
                        OBJECT_TO_NPVARIANT (EventObjectCreateWrapper (instance, parent), *result);
 
2883
                else
 
2884
                        NULL_TO_NPVARIANT (*result);
 
2885
 
 
2886
                return true;
 
2887
        }
 
2888
 
 
2889
        case MoonId_AddEventListener: {
 
2890
                /* FIXME: how do we check if args[1] is a function? */
 
2891
                if (!check_arg_list ("s(so)", argCount, args))
 
2892
                        THROW_JS_EXCEPTION ("addEventListener");
 
2893
                
 
2894
                char *name = STRDUP_FROM_VARIANT (args [0]);
 
2895
                name[0] = toupper(name[0]);
 
2896
 
 
2897
                EventListenerProxy *proxy = new EventListenerProxy (instance, name, &args[1]);
 
2898
                int token = proxy->AddHandler (dob);
 
2899
                g_free (name);
 
2900
 
 
2901
                if (token == -1)
 
2902
                        THROW_JS_EXCEPTION ("AG_E_RUNTIME_ADDEVENT");
 
2903
 
 
2904
                INT32_TO_NPVARIANT (token, *result);
 
2905
                return true;
 
2906
        }
 
2907
        case MoonId_RemoveEventListener: {
 
2908
                if (!check_arg_list ("s(is)", argCount, args))
 
2909
                        THROW_JS_EXCEPTION ("removeEventListener");
 
2910
                
 
2911
                char *event = STRDUP_FROM_VARIANT (args[0]);
 
2912
                int id = dob->GetType()->LookupEvent (event);
 
2913
                g_free (event);
 
2914
                
 
2915
                if (id == -1) {
 
2916
                        THROW_JS_EXCEPTION ("AG_E_RUNTIME_DELEVENT");
 
2917
                } else if (NPVARIANT_IS_INT32 (args [1])) {
 
2918
                        dob->RemoveHandler (id, NPVARIANT_TO_INT32 (args[1]));
 
2919
                } else if (NPVARIANT_IS_STRING (args[1])) {
 
2920
                        char *value = STRDUP_FROM_VARIANT (args[1]);
 
2921
                        NamedProxyPredicate predicate (value);
 
2922
                        g_free (value);
 
2923
                        
 
2924
                        dob->RemoveMatchingHandlers (id, NamedProxyPredicate::matches, &predicate);
 
2925
                }
 
2926
                
 
2927
                return true;
 
2928
        }
 
2929
 
 
2930
        // FIXME: these next two methods should live in a UIElement
 
2931
        // wrapper class, not in the DependencyObject wrapper.
 
2932
        case MoonId_CaptureMouse:
 
2933
                BOOLEAN_TO_NPVARIANT (((UIElement*)dob)->CaptureMouse (), *result);
 
2934
                return true;
 
2935
        case MoonId_ReleaseMouseCapture:
 
2936
                ((UIElement*)dob)->ReleaseMouseCapture ();
 
2937
 
 
2938
                VOID_TO_NPVARIANT (*result);
 
2939
                return true;
 
2940
        default:
 
2941
                return MoonlightObject::Invoke (id, name, args, argCount, result);
 
2942
        }
 
2943
}
 
2944
 
 
2945
 
 
2946
MoonlightDependencyObjectType::MoonlightDependencyObjectType ()
 
2947
{
 
2948
        allocate = moonlight_dependency_object_allocate;
 
2949
        
 
2950
        AddMapping (moonlight_dependency_object_mapping, G_N_ELEMENTS (moonlight_dependency_object_mapping));
 
2951
}
 
2952
 
 
2953
 
 
2954
 
 
2955
/*** MoonlightEventObjectClass ***************************************************/
 
2956
 
 
2957
static NPObject *
 
2958
moonlight_event_object_allocate (NPP instance, NPClass *klass)
 
2959
{
 
2960
        return new MoonlightEventObjectObject (instance);
 
2961
}
 
2962
 
 
2963
MoonlightEventObjectObject::~MoonlightEventObjectObject ()
 
2964
{
 
2965
        if (eo) {
 
2966
                PluginInstance *plugin;
 
2967
                if ((plugin = (PluginInstance *) instance->pdata))
 
2968
                        plugin->RemoveWrappedObject (eo);
 
2969
                
 
2970
                moonlight_type = Type::INVALID;
 
2971
                
 
2972
                eo->unref ();
 
2973
                eo = NULL;
 
2974
        }
 
2975
}
 
2976
 
 
2977
MoonlightEventObjectType::MoonlightEventObjectType ()
 
2978
{
 
2979
        allocate = moonlight_event_object_allocate;
 
2980
}
 
2981
 
 
2982
MoonlightEventObjectType *MoonlightEventObjectClass;
 
2983
 
 
2984
MoonlightEventObjectObject *
 
2985
EventObjectCreateWrapper (NPP instance, EventObject *obj)
 
2986
{
 
2987
        PluginInstance *plugin = (PluginInstance *) instance->pdata;
 
2988
        MoonlightEventObjectObject *depobj;
 
2989
        NPClass *np_class;
 
2990
        
 
2991
        depobj = (MoonlightEventObjectObject *) plugin->LookupWrappedObject (obj);
 
2992
        
 
2993
        if (depobj) {
 
2994
                NPN_RetainObject (depobj);
 
2995
                return depobj;
 
2996
        }
 
2997
        
 
2998
        /* for EventObject subclasses which have special plugin classes, check here */
 
2999
        Type::Kind kind = obj->GetObjectType ();
 
3000
        switch (kind) {
 
3001
        case Type::STORYBOARD:
 
3002
                np_class = dependency_object_classes [STORYBOARD_CLASS];
 
3003
                break;
 
3004
        case Type::MEDIAELEMENT:
 
3005
                np_class = dependency_object_classes [MEDIA_ELEMENT_CLASS];
 
3006
                break;
 
3007
        case Type::DOWNLOADER:
 
3008
                np_class = dependency_object_classes [DOWNLOADER_CLASS];
 
3009
                break;
 
3010
        case Type::CONTROL:
 
3011
                np_class = dependency_object_classes [CONTROL_CLASS];
 
3012
                break;
 
3013
        case Type::IMAGE:
 
3014
                np_class = dependency_object_classes [IMAGE_CLASS];
 
3015
                break;
 
3016
        case Type::IMAGEBRUSH:
 
3017
                np_class = dependency_object_classes [IMAGE_BRUSH_CLASS];
 
3018
                break;
 
3019
        case Type::TEXTBLOCK:
 
3020
                np_class = dependency_object_classes [TEXT_BLOCK_CLASS];
 
3021
                break;
 
3022
        case Type::EVENTOBJECT: 
 
3023
        case Type::SURFACE: 
 
3024
                np_class = MoonlightEventObjectClass;
 
3025
        case Type::STYLUSINFO:
 
3026
                np_class = dependency_object_classes [STYLUS_INFO_CLASS];
 
3027
                break;
 
3028
        case Type::STYLUSPOINT_COLLECTION:
 
3029
                np_class = dependency_object_classes [STYLUS_POINT_COLLECTION_CLASS];
 
3030
                break;
 
3031
        case Type::STROKE_COLLECTION:
 
3032
                np_class = dependency_object_classes [STROKE_COLLECTION_CLASS];
 
3033
                break;
 
3034
        case Type::STROKE:
 
3035
                np_class = dependency_object_classes [STROKE_CLASS];
 
3036
                break;
 
3037
        case Type::ROUTEDEVENTARGS:
 
3038
                np_class = dependency_object_classes [ROUTED_EVENT_ARGS_CLASS];
 
3039
                break;
 
3040
        case Type::MOUSEEVENTARGS:
 
3041
                np_class = dependency_object_classes [MOUSE_EVENT_ARGS_CLASS];
 
3042
                break;
 
3043
        case Type::KEYEVENTARGS:
 
3044
                np_class = dependency_object_classes [KEY_EVENT_ARGS_CLASS];
 
3045
                break;
 
3046
        case Type::MARKERREACHEDEVENTARGS:
 
3047
                np_class = dependency_object_classes [MARKER_REACHED_EVENT_ARGS_CLASS];
 
3048
                break;
 
3049
        case Type::ERROREVENTARGS:
 
3050
        case Type::PARSERERROREVENTARGS:
 
3051
        case Type::IMAGEERROREVENTARGS:
 
3052
        case Type::MEDIAERROREVENTARGS:
 
3053
                np_class = dependency_object_classes [ERROR_EVENT_ARGS_CLASS];
 
3054
                break;
 
3055
        default:
 
3056
                if (Type::Find (kind)->IsSubclassOf (Type::COLLECTION))
 
3057
                        np_class = dependency_object_classes [COLLECTION_CLASS];
 
3058
                else if (Type::Find (kind)->IsSubclassOf (Type::EVENTARGS)) 
 
3059
                        np_class = dependency_object_classes [EVENT_ARGS_CLASS];
 
3060
                else
 
3061
                        np_class = dependency_object_classes [DEPENDENCY_OBJECT_CLASS];
 
3062
        }
 
3063
        
 
3064
        depobj = (MoonlightEventObjectObject *) NPN_CreateObject (instance, np_class);
 
3065
        depobj->moonlight_type = obj->GetObjectType ();
 
3066
        depobj->eo = obj;
 
3067
        obj->ref ();
 
3068
        
 
3069
        plugin->AddWrappedObject (obj, depobj);
 
3070
        
 
3071
        return depobj;
 
3072
}
 
3073
 
 
3074
 
 
3075
 
 
3076
/*** MoonlightCollectionClass ***************************************************/
 
3077
 
 
3078
static NPObject *
 
3079
moonlight_collection_allocate (NPP instance, NPClass *klass)
 
3080
{
 
3081
        return new MoonlightCollectionObject (instance);
 
3082
}
 
3083
 
 
3084
static const MoonNameIdMapping
 
3085
moonlight_collection_mapping [] = {
 
3086
        { "add", MoonId_Add },
 
3087
        { "clear", MoonId_Clear },
 
3088
        { "count", MoonId_Count },
 
3089
        { "getitem", MoonId_GetItem },
 
3090
        { "getitembyname", MoonId_GetItemByName },
 
3091
        { "insert", MoonId_Insert },
 
3092
        { "remove", MoonId_Remove },
 
3093
        { "removeat", MoonId_RemoveAt },
 
3094
};
 
3095
 
 
3096
bool
 
3097
MoonlightCollectionObject::GetProperty (int id, NPIdentifier name, NPVariant *result)
 
3098
{
 
3099
        Collection *col = (Collection *) GetDependencyObject ();
 
3100
 
 
3101
        switch (id) {
 
3102
        case MoonId_Count:
 
3103
                INT32_TO_NPVARIANT (col->GetCount (), *result);
 
3104
                return true;
 
3105
        default:
 
3106
                return MoonlightDependencyObjectObject::GetProperty (id, name, result);
 
3107
        }
 
3108
}
 
3109
 
 
3110
bool
 
3111
MoonlightCollectionObject::Invoke (int id, NPIdentifier name,
 
3112
                                   const NPVariant *args, uint32_t argCount,
 
3113
                                   NPVariant *result)
 
3114
{
 
3115
        Collection *col = (Collection *) GetDependencyObject ();
 
3116
        
 
3117
        switch (id) {
 
3118
        case MoonId_Add: {
 
3119
                if (!check_arg_list ("o", argCount, args) ||
 
3120
                    !npvariant_is_dependency_object (args[0]))
 
3121
                        THROW_JS_EXCEPTION ("add");
 
3122
                
 
3123
                MoonlightDependencyObjectObject *el = (MoonlightDependencyObjectObject *) NPVARIANT_TO_OBJECT (args[0]);
 
3124
                int n = col->Add (Value (el->GetDependencyObject ()));
 
3125
                
 
3126
                if (n == -1)
 
3127
                        THROW_JS_EXCEPTION ("add");
 
3128
                
 
3129
                INT32_TO_NPVARIANT (n, *result);
 
3130
                
 
3131
                return true;
 
3132
        }
 
3133
        case MoonId_Remove: {
 
3134
                if (!check_arg_list ("o", argCount, args) ||
 
3135
                    !npvariant_is_dependency_object (args[0]))
 
3136
                        THROW_JS_EXCEPTION ("remove");
 
3137
                
 
3138
                MoonlightDependencyObjectObject *el = (MoonlightDependencyObjectObject *) NPVARIANT_TO_OBJECT (args[0]);
 
3139
                bool res = col->Remove (Value (el->GetDependencyObject ()));
 
3140
                
 
3141
                BOOLEAN_TO_NPVARIANT (res, *result);
 
3142
                
 
3143
                return true;
 
3144
        }
 
3145
        case MoonId_RemoveAt: {
 
3146
                if (!check_arg_list ("i", argCount, args))
 
3147
                        THROW_JS_EXCEPTION ("removeAt");
 
3148
                
 
3149
                int index = NPVARIANT_TO_INT32 (args [0]);
 
3150
                
 
3151
                if (index < 0 || index >= col->GetCount ())
 
3152
                        THROW_JS_EXCEPTION ("removeAt");
 
3153
                
 
3154
                DependencyObject *obj = col->GetValueAt (index)->AsDependencyObject ();
 
3155
                OBJECT_TO_NPVARIANT (EventObjectCreateWrapper (instance, obj), *result);
 
3156
                
 
3157
                col->RemoveAt (index);
 
3158
                
 
3159
                return true;
 
3160
        }
 
3161
        case MoonId_Insert: {
 
3162
                if (!check_arg_list ("i[o]", argCount, args))
 
3163
                        THROW_JS_EXCEPTION ("insert");
 
3164
                
 
3165
                if (argCount < 2) {
 
3166
                        VOID_TO_NPVARIANT (*result);
 
3167
                        return true;
 
3168
                }
 
3169
                
 
3170
                if (!npvariant_is_dependency_object (args[1]))
 
3171
                        THROW_JS_EXCEPTION ("insert");
 
3172
                
 
3173
                MoonlightDependencyObjectObject *el = (MoonlightDependencyObjectObject*) NPVARIANT_TO_OBJECT (args[1]);
 
3174
                int index = NPVARIANT_TO_INT32 (args[0]);
 
3175
                
 
3176
                if (!col->Insert (index, Value (el->GetDependencyObject ())))
 
3177
                        THROW_JS_EXCEPTION ("insert");
 
3178
                
 
3179
                VOID_TO_NPVARIANT (*result);
 
3180
                
 
3181
                return true;
 
3182
        }
 
3183
        case MoonId_Clear: {
 
3184
                if (argCount != 0)
 
3185
                        THROW_JS_EXCEPTION ("clear");
 
3186
                
 
3187
                col->Clear ();
 
3188
                
 
3189
                VOID_TO_NPVARIANT (*result);
 
3190
                
 
3191
                return true;
 
3192
        }
 
3193
        case MoonId_GetItem: {
 
3194
                if (!check_arg_list ("i", argCount, args))
 
3195
                        THROW_JS_EXCEPTION ("getItem");
 
3196
                
 
3197
                int index = NPVARIANT_TO_INT32 (args[0]);
 
3198
                
 
3199
                if (index < 0)
 
3200
                        THROW_JS_EXCEPTION ("getItem");
 
3201
                
 
3202
                if (index >= col->GetCount ()) {
 
3203
                        NULL_TO_NPVARIANT (*result);
 
3204
                        return true;
 
3205
                }
 
3206
                
 
3207
                DependencyObject *obj = col->GetValueAt (index)->AsDependencyObject ();
 
3208
                OBJECT_TO_NPVARIANT (EventObjectCreateWrapper (instance, obj), *result);
 
3209
                
 
3210
                return true;
 
3211
        }
 
3212
        case MoonId_GetItemByName: {
 
3213
                if (col->GetObjectType () != Type::MEDIAATTRIBUTE_COLLECTION ||
 
3214
                    !check_arg_list ("s", argCount, args))
 
3215
                        THROW_JS_EXCEPTION ("getItemByName");
 
3216
                
 
3217
                char *name = STRDUP_FROM_VARIANT (args[0]);
 
3218
                DependencyObject *obj = ((MediaAttributeCollection *) col)->GetItemByName (name);
 
3219
                g_free (name);
 
3220
                
 
3221
                OBJECT_TO_NPVARIANT (EventObjectCreateWrapper (instance, obj), *result);
 
3222
                
 
3223
                return true;
 
3224
        }
 
3225
        default:
 
3226
                return MoonlightDependencyObjectObject::Invoke (id, name, args, argCount, result);
 
3227
        }
 
3228
}
 
3229
 
 
3230
 
 
3231
MoonlightCollectionType::MoonlightCollectionType ()
 
3232
{
 
3233
        AddMapping (moonlight_collection_mapping, G_N_ELEMENTS (moonlight_collection_mapping));
 
3234
 
 
3235
        allocate = moonlight_collection_allocate;
 
3236
}
 
3237
 
 
3238
 
 
3239
/*** MoonlightStoryboardClass ***************************************************/
 
3240
 
 
3241
static NPObject *
 
3242
moonlight_storyboard_allocate (NPP instance, NPClass *klass)
 
3243
{
 
3244
        return new MoonlightStoryboardObject (instance);
 
3245
}
 
3246
 
 
3247
static const MoonNameIdMapping
 
3248
moonlight_storyboard_mapping [] = {
 
3249
        { "begin", MoonId_Begin },
 
3250
        { "completed", MoonId_Completed },
 
3251
        { "pause", MoonId_Pause },
 
3252
        { "resume", MoonId_Resume },
 
3253
        { "seek", MoonId_Seek },
 
3254
        { "stop", MoonId_Stop }
 
3255
};
 
3256
 
 
3257
bool
 
3258
MoonlightStoryboardObject::Invoke (int id, NPIdentifier name,
 
3259
                                   const NPVariant *args, uint32_t argCount,
 
3260
                                   NPVariant *result)
 
3261
{
 
3262
        Storyboard *sb = (Storyboard*)GetDependencyObject ();
 
3263
 
 
3264
        switch (id) {
 
3265
        case MoonId_Begin:
 
3266
                if (argCount != 0 || !sb->Begin ())
 
3267
                        THROW_JS_EXCEPTION ("begin");
 
3268
                
 
3269
                VOID_TO_NPVARIANT (*result);
 
3270
 
 
3271
                return true;
 
3272
        case MoonId_Pause:
 
3273
                if (argCount != 0)
 
3274
                        THROW_JS_EXCEPTION ("pause");
 
3275
 
 
3276
                sb->Pause ();
 
3277
 
 
3278
                VOID_TO_NPVARIANT (*result);
 
3279
 
 
3280
                return true;
 
3281
        case MoonId_Resume:
 
3282
                if (argCount != 0)
 
3283
                        THROW_JS_EXCEPTION ("resume");
 
3284
 
 
3285
                sb->Resume ();
 
3286
 
 
3287
                VOID_TO_NPVARIANT (*result);
 
3288
 
 
3289
                return true;
 
3290
        case MoonId_Seek: {
 
3291
                if (!check_arg_list ("(is)", argCount, args))
 
3292
                        THROW_JS_EXCEPTION ("seek");
 
3293
                
 
3294
                TimeSpan ts;
 
3295
                bool ok;
 
3296
                
 
3297
                if (NPVARIANT_IS_INT32 (args[0])) {
 
3298
                        ts = (TimeSpan) NPVARIANT_TO_INT32 (args[0]);
 
3299
                } else if (NPVARIANT_IS_STRING (args[0])) {
 
3300
                        char *span = STRDUP_FROM_VARIANT (args[0]);
 
3301
                        ok = time_span_from_str (span, &ts);
 
3302
                        g_free (span);
 
3303
                        
 
3304
                        if (!ok)
 
3305
                                THROW_JS_EXCEPTION ("seek");
 
3306
                }
 
3307
                
 
3308
                sb->Seek (ts);
 
3309
 
 
3310
                VOID_TO_NPVARIANT (*result);
 
3311
 
 
3312
                return true;
 
3313
        }
 
3314
        case MoonId_Stop:
 
3315
                if (argCount != 0)
 
3316
                        THROW_JS_EXCEPTION ("stop");
 
3317
 
 
3318
                sb->Stop ();
 
3319
 
 
3320
                VOID_TO_NPVARIANT (*result);
 
3321
 
 
3322
                return true;
 
3323
        default:
 
3324
                return MoonlightDependencyObjectObject::Invoke (id, name, args, argCount, result);
 
3325
        }
 
3326
}
 
3327
 
 
3328
MoonlightStoryboardType::MoonlightStoryboardType ()
 
3329
{
 
3330
        AddMapping (moonlight_storyboard_mapping, G_N_ELEMENTS (moonlight_storyboard_mapping));
 
3331
 
 
3332
        allocate = moonlight_storyboard_allocate;
 
3333
}
 
3334
 
 
3335
 
 
3336
/*** MoonlightMediaElementClass ***************************************************/
 
3337
 
 
3338
static NPObject *
 
3339
moonlight_media_element_allocate (NPP instance, NPClass *)
 
3340
{
 
3341
        return new MoonlightMediaElementObject (instance);
 
3342
}
 
3343
 
 
3344
static const MoonNameIdMapping
 
3345
moonlight_media_element_mapping [] = {
 
3346
        { "bufferingprogresschanged", MoonId_BufferingProgressChanged },
 
3347
        { "currentstatechanged", MoonId_CurrentStateChanged },
 
3348
        { "downloadprogresschanged", MoonId_DownloadProgressChanged },
 
3349
        { "markerreached", MoonId_MarkerReached },
 
3350
        { "mediaended", MoonId_MediaEnded },
 
3351
        { "mediafailed", MoonId_MediaFailed },
 
3352
        { "mediaopened", MoonId_MediaOpened },
 
3353
        { "pause", MoonId_Pause },
 
3354
        { "play", MoonId_Play },
 
3355
        { "setsource", MoonId_SetSource },
 
3356
        { "stop", MoonId_Stop },
 
3357
};
 
3358
 
 
3359
bool
 
3360
MoonlightMediaElementObject::Invoke (int id, NPIdentifier name,
 
3361
                                     const NPVariant *args, uint32_t argCount,
 
3362
                                     NPVariant *result)
 
3363
{
 
3364
        MediaElement *media = (MediaElement*)GetDependencyObject ();
 
3365
        
 
3366
        switch (id) {
 
3367
        case MoonId_Play:
 
3368
                if (argCount != 0)
 
3369
                        THROW_JS_EXCEPTION ("play");
 
3370
 
 
3371
                media->Play ();
 
3372
 
 
3373
                VOID_TO_NPVARIANT (*result);
 
3374
 
 
3375
                return true;
 
3376
 
 
3377
        case MoonId_Pause:
 
3378
                if (argCount != 0)
 
3379
                        THROW_JS_EXCEPTION ("pause");
 
3380
 
 
3381
                media->Pause ();
 
3382
 
 
3383
                VOID_TO_NPVARIANT (*result);
 
3384
 
 
3385
                return true;
 
3386
 
 
3387
        case MoonId_Stop:
 
3388
                if (argCount != 0)
 
3389
                        THROW_JS_EXCEPTION ("stop");
 
3390
 
 
3391
                media->Stop ();
 
3392
 
 
3393
                VOID_TO_NPVARIANT (*result);
 
3394
 
 
3395
                return true;
 
3396
 
 
3397
        case MoonId_SetSource: {
 
3398
                if (!check_arg_list ("os", argCount, args) ||
 
3399
                    !npvariant_is_downloader (args[0]))
 
3400
                        THROW_JS_EXCEPTION ("AG_E_RUNTIME_METHOD");
 
3401
                
 
3402
                DependencyObject *downloader = ((MoonlightDependencyObjectObject *) NPVARIANT_TO_OBJECT (args[0]))->GetDependencyObject ();
 
3403
 
 
3404
                char *part = STRDUP_FROM_VARIANT (args [1]);
 
3405
                media->SetSource ((Downloader *) downloader, part);
 
3406
                g_free (part);
 
3407
 
 
3408
                VOID_TO_NPVARIANT (*result);
 
3409
 
 
3410
                return true;
 
3411
        }
 
3412
 
 
3413
        default:
 
3414
                return MoonlightDependencyObjectObject::Invoke (id, name, args, argCount, result);
 
3415
        }
 
3416
}
 
3417
 
 
3418
MoonlightMediaElementType::MoonlightMediaElementType ()
 
3419
{
 
3420
        AddMapping (moonlight_media_element_mapping, G_N_ELEMENTS (moonlight_media_element_mapping));
 
3421
 
 
3422
        allocate = moonlight_media_element_allocate;
 
3423
}
 
3424
 
 
3425
 
 
3426
/*** MoonlightImageClass ***************************************************/
 
3427
 
 
3428
static NPObject *
 
3429
moonlight_image_allocate (NPP instance, NPClass *klass)
 
3430
{
 
3431
        return new MoonlightImageObject (instance);
 
3432
}
 
3433
 
 
3434
static const MoonNameIdMapping
 
3435
moonlight_image_mapping [] = {
 
3436
        { "downloadprogresschanged", MoonId_DownloadProgressChanged },
 
3437
        { "imagefailed", MoonId_ImageFailed },
 
3438
        { "setsource", MoonId_SetSource }
 
3439
};
 
3440
 
 
3441
 
 
3442
bool
 
3443
MoonlightImageObject::Invoke (int id, NPIdentifier name,
 
3444
                              const NPVariant *args, uint32_t argCount,
 
3445
                              NPVariant *result)
 
3446
{
 
3447
        Image *img = (Image *) GetDependencyObject ();
 
3448
        DependencyObject *downloader;
 
3449
        char *part;
 
3450
        
 
3451
        switch (id) {
 
3452
        case MoonId_SetSource:
 
3453
                if (!check_arg_list ("os", argCount, args) ||
 
3454
                    !npvariant_is_downloader (args[0]))
 
3455
                        THROW_JS_EXCEPTION ("AG_E_RUNTIME_METHOD");
 
3456
                
 
3457
                downloader = ((MoonlightDependencyObjectObject *) NPVARIANT_TO_OBJECT (args[0]))->GetDependencyObject ();
 
3458
 
 
3459
                part = STRDUP_FROM_VARIANT (args [1]);
 
3460
                img->SetSource ((Downloader *) downloader, part);
 
3461
                g_free (part);
 
3462
                
 
3463
                VOID_TO_NPVARIANT (*result);
 
3464
                
 
3465
                return true;
 
3466
        default:
 
3467
                return MoonlightDependencyObjectObject::Invoke (id, name, args, argCount, result);
 
3468
        }
 
3469
}
 
3470
 
 
3471
MoonlightImageType::MoonlightImageType ()
 
3472
{
 
3473
        AddMapping (moonlight_image_mapping, G_N_ELEMENTS (moonlight_image_mapping));
 
3474
 
 
3475
        allocate = moonlight_image_allocate;
 
3476
}
 
3477
 
 
3478
 
 
3479
/*** MoonlightImageBrushClass ***************************************************/
 
3480
 
 
3481
static NPObject *
 
3482
moonlight_image_brush_allocate (NPP instance, NPClass *klass)
 
3483
{
 
3484
        return new MoonlightImageBrushObject (instance);
 
3485
}
 
3486
 
 
3487
 
 
3488
static const MoonNameIdMapping
 
3489
moonlight_image_brush_mapping [] = {
 
3490
        { "downloadprogresschanged", MoonId_DownloadProgressChanged },
 
3491
        { "setsource", MoonId_SetSource }
 
3492
};
 
3493
 
 
3494
 
 
3495
bool
 
3496
MoonlightImageBrushObject::Invoke (int id, NPIdentifier name,
 
3497
                                   const NPVariant *args, uint32_t argCount,
 
3498
                                   NPVariant *result)
 
3499
{
 
3500
        ImageBrush *img = (ImageBrush *) GetDependencyObject ();
 
3501
        DependencyObject *downloader;
 
3502
        
 
3503
        switch (id) {
 
3504
        case MoonId_SetSource: {
 
3505
                if (!check_arg_list ("os", argCount, args) ||
 
3506
                    !npvariant_is_downloader (args[0]))
 
3507
                        THROW_JS_EXCEPTION ("setSource");
 
3508
                
 
3509
                downloader = ((MoonlightDependencyObjectObject *) NPVARIANT_TO_OBJECT (args[0]))->GetDependencyObject ();
 
3510
 
 
3511
                char *part = STRDUP_FROM_VARIANT (args [1]);
 
3512
                img->SetSource ((Downloader *) downloader, part);
 
3513
                g_free (part);
 
3514
                
 
3515
                VOID_TO_NPVARIANT (*result);
 
3516
                
 
3517
                return true;
 
3518
        }
 
3519
 
 
3520
        default:
 
3521
                return MoonlightDependencyObjectObject::Invoke (id, name, args, argCount, result);
 
3522
        }
 
3523
}
 
3524
 
 
3525
MoonlightImageBrushType::MoonlightImageBrushType ()
 
3526
{
 
3527
        AddMapping (moonlight_image_brush_mapping, G_N_ELEMENTS (moonlight_image_brush_mapping));
 
3528
 
 
3529
        allocate = moonlight_image_brush_allocate;
 
3530
}
 
3531
 
 
3532
 
 
3533
/*** MoonlightTextBlockClass ***************************************************/
 
3534
 
 
3535
static NPObject *
 
3536
moonlight_text_block_allocate (NPP instance, NPClass *klass)
 
3537
{
 
3538
        return new MoonlightTextBlockObject (instance);
 
3539
}
 
3540
 
 
3541
 
 
3542
static const MoonNameIdMapping moonlight_text_block_mapping[] = {
 
3543
        { "setfontsource", MoonId_SetFontSource }
 
3544
};
 
3545
 
 
3546
 
 
3547
bool
 
3548
MoonlightTextBlockObject::Invoke (int id, NPIdentifier name,
 
3549
                                  const NPVariant *args, uint32_t argCount,
 
3550
                                  NPVariant *result)
 
3551
{
 
3552
        TextBlock *tb = (TextBlock *) GetDependencyObject ();
 
3553
        DependencyObject *downloader = NULL;
 
3554
        
 
3555
        switch (id) {
 
3556
        case MoonId_SetFontSource:
 
3557
                if (!check_arg_list ("(no)", argCount, args) && (!NPVARIANT_IS_NULL(args[0]) || !npvariant_is_downloader (args[0])))
 
3558
                        THROW_JS_EXCEPTION ("setFontSource");
 
3559
                
 
3560
                if (NPVARIANT_IS_OBJECT (args[0]))
 
3561
                        downloader = ((MoonlightDependencyObjectObject *) NPVARIANT_TO_OBJECT (args[0]))->GetDependencyObject ();
 
3562
                
 
3563
                tb->SetFontSource ((Downloader *) downloader);
 
3564
                
 
3565
                VOID_TO_NPVARIANT (*result);
 
3566
                
 
3567
                return true;
 
3568
        default:
 
3569
                return MoonlightDependencyObjectObject::Invoke (id, name, args, argCount, result);
 
3570
        }
 
3571
}
 
3572
 
 
3573
MoonlightTextBlockType::MoonlightTextBlockType ()
 
3574
{
 
3575
        AddMapping (moonlight_text_block_mapping, G_N_ELEMENTS (moonlight_text_block_mapping));
 
3576
 
 
3577
        allocate = moonlight_text_block_allocate;
 
3578
}
 
3579
 
 
3580
 
 
3581
/*** MoonlightStylusInfoClass ***************************************************/
 
3582
 
 
3583
static NPObject *
 
3584
moonlight_stylus_info_allocate (NPP instance, NPClass *klass)
 
3585
{
 
3586
        return new MoonlightStylusInfoObject (instance);
 
3587
}
 
3588
 
 
3589
static const MoonNameIdMapping
 
3590
moonlight_stylus_info_mapping [] = {
 
3591
        { "devicetype", MoonId_DeviceType },
 
3592
        { "isinverted", MoonId_IsInverted },
 
3593
};
 
3594
 
 
3595
bool
 
3596
MoonlightStylusInfoObject::GetProperty (int id, NPIdentifier name, NPVariant *result)
 
3597
{
 
3598
        StylusInfo *info = (StylusInfo *) GetDependencyObject ();
 
3599
 
 
3600
        switch (id) {
 
3601
        case MoonId_DeviceType: {
 
3602
                switch (info->GetDeviceType ()) {
 
3603
                case TabletDeviceTypeMouse:
 
3604
                        string_to_npvariant ("Mouse", result);
 
3605
                        break;
 
3606
                case TabletDeviceTypeStylus:
 
3607
                        string_to_npvariant ("Stylus", result);
 
3608
                        break;
 
3609
                case TabletDeviceTypeTouch:
 
3610
                        string_to_npvariant ("Touch", result);
 
3611
                        break;
 
3612
                default:
 
3613
                        THROW_JS_EXCEPTION ("deviceType");
 
3614
                }
 
3615
                return true;
 
3616
        }
 
3617
        case MoonId_IsInverted: {
 
3618
                BOOLEAN_TO_NPVARIANT (info->GetIsInverted (), *result);
 
3619
                return true;
 
3620
        }
 
3621
 
 
3622
        default:
 
3623
                return MoonlightDependencyObjectObject::GetProperty (id, name, result);
 
3624
        }
 
3625
}
 
3626
 
 
3627
MoonlightStylusInfoType::MoonlightStylusInfoType ()
 
3628
{
 
3629
        AddMapping (moonlight_stylus_info_mapping, G_N_ELEMENTS (moonlight_stylus_info_mapping));
 
3630
 
 
3631
        allocate = moonlight_stylus_info_allocate;
 
3632
}
 
3633
 
 
3634
 
 
3635
/*** MoonlightStylusPointCollectionClass ****************************************/
 
3636
 
 
3637
static NPObject *
 
3638
moonlight_stylus_point_collection_allocate (NPP instance, NPClass *klass)
 
3639
{
 
3640
        return new MoonlightStylusPointCollectionObject (instance);
 
3641
}
 
3642
 
 
3643
static const MoonNameIdMapping
 
3644
moonlight_stylus_point_collection_mapping [] = {
 
3645
        { "addstyluspoints", MoonId_AddStylusPoints },
 
3646
};
 
3647
 
 
3648
bool
 
3649
MoonlightStylusPointCollectionObject::Invoke (int id, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result)
 
3650
{
 
3651
        StylusPointCollection *col = (StylusPointCollection *) GetDependencyObject ();
 
3652
        
 
3653
        switch (id) {
 
3654
        case MoonId_AddStylusPoints: {
 
3655
                if (!col || !check_arg_list ("o", argCount, args))
 
3656
                        return false;
 
3657
                
 
3658
                MoonlightStylusPointCollectionObject *spco = (MoonlightStylusPointCollectionObject*) NPVARIANT_TO_OBJECT(args[0]);
 
3659
                double ret = col->AddStylusPoints ((StylusPointCollection*) spco->GetDependencyObject ());
 
3660
                DOUBLE_TO_NPVARIANT (ret, *result);
 
3661
                return true;
 
3662
        }
 
3663
        default:
 
3664
                return MoonlightCollectionObject::Invoke (id, name, args, argCount, result);
 
3665
        }
 
3666
}
 
3667
 
 
3668
MoonlightStylusPointCollectionType::MoonlightStylusPointCollectionType ()
 
3669
{
 
3670
        AddMapping (moonlight_stylus_point_collection_mapping, G_N_ELEMENTS (moonlight_stylus_point_collection_mapping));
 
3671
 
 
3672
        allocate = moonlight_stylus_point_collection_allocate;
 
3673
}
 
3674
 
 
3675
 
 
3676
/*** MoonlightStrokeCollectionClass ****************************************/
 
3677
 
 
3678
static NPObject *
 
3679
moonlight_stroke_collection_allocate (NPP instance, NPClass *klass)
 
3680
{
 
3681
        return new MoonlightStrokeCollectionObject (instance);
 
3682
}
 
3683
 
 
3684
static const MoonNameIdMapping
 
3685
moonlight_stroke_collection_mapping [] = {
 
3686
        { "getbounds", MoonId_GetBounds },
 
3687
        { "hittest", MoonId_HitTest }
 
3688
};
 
3689
 
 
3690
bool
 
3691
MoonlightStrokeCollectionObject::Invoke (int id, NPIdentifier name,
 
3692
        const NPVariant *args, uint32_t argCount, NPVariant *result)
 
3693
{
 
3694
        StrokeCollection *col = (StrokeCollection *) GetDependencyObject ();
 
3695
 
 
3696
        switch (id) {
 
3697
        case MoonId_GetBounds: {
 
3698
                Rect r = col->GetBounds ();
 
3699
                Value v (r);
 
3700
                value_to_variant (this, &v, result);
 
3701
                return true;
 
3702
        }
 
3703
 
 
3704
        case MoonId_HitTest: {
 
3705
                if (!check_arg_list ("o", argCount, args) ||
 
3706
                    !npvariant_is_dependency_object (args[0]))
 
3707
                        THROW_JS_EXCEPTION ("hitTest");
 
3708
                
 
3709
                DependencyObject *dob = DEPENDENCY_OBJECT_FROM_VARIANT (args [0]);
 
3710
                if (!dob->Is (Type::STYLUSPOINT_COLLECTION))
 
3711
                        THROW_JS_EXCEPTION ("hitTest");
 
3712
 
 
3713
                StrokeCollection *hit_col = col->HitTest ((StylusPointCollection*)dob);
 
3714
 
 
3715
                OBJECT_TO_NPVARIANT (EventObjectCreateWrapper (instance, hit_col), *result);
 
3716
                hit_col->unref ();
 
3717
                return true;
 
3718
        }
 
3719
 
 
3720
        default:
 
3721
                return MoonlightCollectionObject::Invoke (id, name, args, argCount, result);
 
3722
        }
 
3723
}
 
3724
 
 
3725
MoonlightStrokeCollectionType::MoonlightStrokeCollectionType ()
 
3726
{
 
3727
        AddMapping (moonlight_stroke_collection_mapping, G_N_ELEMENTS (moonlight_stroke_collection_mapping));
 
3728
 
 
3729
        allocate = moonlight_stroke_collection_allocate;
 
3730
}
 
3731
 
 
3732
 
 
3733
/*** MoonlightStrokeClass ****************************************/
 
3734
 
 
3735
static NPObject *
 
3736
moonlight_stroke_allocate (NPP instance, NPClass *klass)
 
3737
{
 
3738
        return new MoonlightStrokeObject (instance);
 
3739
}
 
3740
 
 
3741
static const MoonNameIdMapping
 
3742
moonlight_stroke_mapping [] = {
 
3743
        { "getbounds", MoonId_GetBounds },
 
3744
        { "hittest", MoonId_HitTest }
 
3745
};
 
3746
 
 
3747
bool
 
3748
MoonlightStrokeObject::Invoke (int id, NPIdentifier name,
 
3749
        const NPVariant *args, uint32_t argCount, NPVariant *result)
 
3750
{
 
3751
        Stroke *stroke = (Stroke *) GetDependencyObject ();
 
3752
        
 
3753
        switch (id) {
 
3754
        case MoonId_GetBounds: {
 
3755
                Rect r = stroke->GetBounds ();
 
3756
                Value v (r);
 
3757
                value_to_variant (this, &v, result);
 
3758
                return true;
 
3759
        }
 
3760
 
 
3761
        case MoonId_HitTest: {
 
3762
                if (!check_arg_list ("o", argCount, args) ||
 
3763
                    !npvariant_is_dependency_object (args[0]))
 
3764
                        THROW_JS_EXCEPTION ("hitTest");
 
3765
                
 
3766
                DependencyObject *dob = DEPENDENCY_OBJECT_FROM_VARIANT (args [0]);
 
3767
                if (!dob->Is (Type::STYLUSPOINT_COLLECTION))
 
3768
                        THROW_JS_EXCEPTION ("hitTest");
 
3769
 
 
3770
                BOOLEAN_TO_NPVARIANT (stroke->HitTest ((StylusPointCollection*)dob), *result);
 
3771
                return true;
 
3772
        }
 
3773
 
 
3774
        default:
 
3775
                return MoonlightDependencyObjectObject::Invoke (id, name, args, argCount, result);
 
3776
        }
 
3777
}
 
3778
 
 
3779
MoonlightStrokeType::MoonlightStrokeType ()
 
3780
{
 
3781
        AddMapping (moonlight_stroke_mapping, G_N_ELEMENTS (moonlight_stroke_mapping));
 
3782
 
 
3783
        allocate = moonlight_stroke_allocate;
 
3784
}
 
3785
 
 
3786
 
 
3787
/*** MoonlightDownloaderClass ***************************************************/
 
3788
 
 
3789
static NPObject *
 
3790
moonlight_downloader_allocate (NPP instance, NPClass *klass)
 
3791
{
 
3792
        return new MoonlightDownloaderObject (instance);
 
3793
}
 
3794
 
 
3795
 
 
3796
static const MoonNameIdMapping
 
3797
moonlight_downloader_mapping [] = {
 
3798
        { "abort", MoonId_Abort },
 
3799
        { "completed", MoonId_Completed },
 
3800
        { "downloadprogresschanged", MoonId_DownloadProgressChanged },
 
3801
        { "getresponsetext", MoonId_GetResponseText },
 
3802
        { "open", MoonId_Open },
 
3803
        { "responsetext", MoonId_ResponseText },
 
3804
        { "send", MoonId_Send }
 
3805
};
 
3806
 
 
3807
bool
 
3808
MoonlightDownloaderObject::GetProperty (int id, NPIdentifier name, NPVariant *result)
 
3809
{
 
3810
        Downloader *downloader = (Downloader *) GetDependencyObject ();
 
3811
        guint64 size;
 
3812
        char *text;
 
3813
        
 
3814
        switch (id) {
 
3815
        case MoonId_ResponseText:
 
3816
                if ((text = downloader->GetResponseText (NULL, &size))) {
 
3817
                        char *s = (char *) NPN_MemAlloc (size + 1);
 
3818
                        memcpy (s, text, size + 1);
 
3819
                        g_free (text);
 
3820
                        
 
3821
                        STRINGN_TO_NPVARIANT (s, (uint32_t) size, *result);
 
3822
                } else {
 
3823
                        NULL_TO_NPVARIANT (*result);
 
3824
                }
 
3825
                
 
3826
                return true;
 
3827
        default:
 
3828
                return MoonlightDependencyObjectObject::GetProperty (id, name, result);
 
3829
        }
 
3830
}
 
3831
 
 
3832
bool
 
3833
MoonlightDownloaderObject::Invoke (int id, NPIdentifier name,
 
3834
                                   const NPVariant *args, uint32_t argCount,
 
3835
                                   NPVariant *result)
 
3836
{
 
3837
        Downloader *downloader = (Downloader *) GetDependencyObject ();
 
3838
        char *part, *verb, *uri, *text;
 
3839
        guint64 size;
 
3840
        
 
3841
        switch (id) {
 
3842
        case MoonId_Abort:
 
3843
                if (argCount != 0)
 
3844
                        THROW_JS_EXCEPTION ("abort");
 
3845
 
 
3846
                downloader->Abort ();
 
3847
                
 
3848
                VOID_TO_NPVARIANT (*result);
 
3849
                
 
3850
                return true;
 
3851
        case MoonId_Open:
 
3852
                if (!check_arg_list ("s(ns)", argCount, args))
 
3853
                        THROW_JS_EXCEPTION ("open");
 
3854
                
 
3855
                verb = STRDUP_FROM_VARIANT (args[0]);
 
3856
                
 
3857
                if (NPVARIANT_IS_STRING (args[1]))
 
3858
                        uri = STRDUP_FROM_VARIANT (args[1]);
 
3859
                else
 
3860
                        uri = NULL;
 
3861
                
 
3862
                downloader->Open (verb, uri, DownloaderPolicy);
 
3863
                g_free (verb);
 
3864
                g_free (uri);
 
3865
                
 
3866
                VOID_TO_NPVARIANT (*result);
 
3867
                
 
3868
                return true;
 
3869
        case MoonId_Send:
 
3870
                if (argCount != 0 || downloader->GetSurface () == NULL)
 
3871
                        THROW_JS_EXCEPTION ("send");
 
3872
                
 
3873
                downloader->Send ();
 
3874
                
 
3875
                VOID_TO_NPVARIANT (*result);
 
3876
                
 
3877
                return true;
 
3878
        case MoonId_GetResponseText:
 
3879
                if (!check_arg_list ("s", argCount, args))
 
3880
                        THROW_JS_EXCEPTION ("getResponseText");
 
3881
                
 
3882
                part = STRDUP_FROM_VARIANT (args[0]);
 
3883
                if ((text = downloader->GetResponseText (part, &size))) {
 
3884
                        char *s = (char *) NPN_MemAlloc (size + 1);
 
3885
                        memcpy (s, text, size + 1);
 
3886
                        g_free (text);
 
3887
                        
 
3888
                        STRINGN_TO_NPVARIANT (s, (uint32_t) size, *result);
 
3889
                } else {
 
3890
                        NULL_TO_NPVARIANT (*result);
 
3891
                }
 
3892
                g_free (part);
 
3893
 
 
3894
                return true;
 
3895
        default:
 
3896
                return MoonlightDependencyObjectObject::Invoke (id, name, args, argCount, result);
 
3897
        }
 
3898
}
 
3899
 
 
3900
MoonlightDownloaderType::MoonlightDownloaderType ()
 
3901
{
 
3902
        AddMapping (moonlight_downloader_mapping, G_N_ELEMENTS (moonlight_downloader_mapping));
 
3903
 
 
3904
        allocate = moonlight_downloader_allocate;
 
3905
}
 
3906
 
 
3907
 
 
3908
/*** MoonlightScriptableObjectClass ***************************************************/
 
3909
 
 
3910
// FIXME: the property/method hashes here are case sensitive
 
3911
 
 
3912
struct ScriptableProperty {
 
3913
        gpointer property_handle;
 
3914
        int property_type;
 
3915
        bool can_read;
 
3916
        bool can_write;
 
3917
};
 
3918
 
 
3919
struct ScriptableEvent {
 
3920
        gpointer event_handle;
 
3921
};
 
3922
 
 
3923
struct ScriptableMethod {
 
3924
        gpointer method_handle;
 
3925
        int method_return_type;
 
3926
        int *method_parameter_types;
 
3927
        int parameter_count;
 
3928
};
 
3929
 
 
3930
 
 
3931
static NPObject *
 
3932
moonlight_scriptable_object_allocate (NPP instance, NPClass *klass)
 
3933
{
 
3934
        return new MoonlightScriptableObjectObject (instance);
 
3935
}
 
3936
 
 
3937
MoonlightScriptableObjectObject::~MoonlightScriptableObjectObject ()
 
3938
{
 
3939
        if (managed_scriptable) {
 
3940
                // FIXME: unref the scriptable object however we need to.
 
3941
                managed_scriptable = NULL;
 
3942
        }
 
3943
        
 
3944
        // FIXME: free the properties, events, and methods hashes.
 
3945
}
 
3946
 
 
3947
bool
 
3948
MoonlightScriptableObjectObject::HasProperty (NPIdentifier name)
 
3949
{
 
3950
        return (g_hash_table_lookup (properties, name) != NULL
 
3951
                || g_hash_table_lookup (events, name)) || MoonlightObject::HasProperty (name);
 
3952
}
 
3953
 
 
3954
bool
 
3955
MoonlightScriptableObjectObject::GetProperty (int id, NPIdentifier name, NPVariant *result)
 
3956
{
 
3957
        ScriptableProperty *prop = (ScriptableProperty*)g_hash_table_lookup (properties, name);
 
3958
        if (!prop)
 
3959
                return MoonlightObject::GetProperty (id, name, result);
 
3960
 
 
3961
#if ds(!)0
 
3962
        NPUTF8 *strname = NPN_UTF8FromIdentifier (name);
 
3963
        printf ("getting scriptable object property %s\n", strname);
 
3964
        NPN_MemFree (strname);
 
3965
#endif
 
3966
 
 
3967
        Value v;
 
3968
 
 
3969
        getprop (managed_scriptable, prop->property_handle, &v);
 
3970
 
 
3971
        value_to_variant (this, &v, result);
 
3972
 
 
3973
        return true;
 
3974
}
 
3975
 
 
3976
bool
 
3977
MoonlightScriptableObjectObject::SetProperty (int id, NPIdentifier name, const NPVariant *value)
 
3978
{
 
3979
        ScriptableProperty *prop;
 
3980
        ScriptableEvent *event;
 
3981
        Value *v;
 
3982
        
 
3983
        // first we try the property hash
 
3984
        if ((prop = (ScriptableProperty *) g_hash_table_lookup (properties, name))) {
 
3985
#if ds(!)0
 
3986
                NPUTF8 *strname = NPN_UTF8FromIdentifier (name);
 
3987
                printf ("setting scriptable object property %s\n", strname);
 
3988
                NPN_MemFree (strname);
 
3989
#endif
 
3990
                
 
3991
                variant_to_value (value, &v);
 
3992
                setprop (managed_scriptable, prop->property_handle, v);
 
3993
                delete v;
 
3994
                
 
3995
                return true;
 
3996
        }
 
3997
        
 
3998
        // if that fails, look for the event of that name
 
3999
        if ((event = (ScriptableEvent *) g_hash_table_lookup (events, name))) {
 
4000
#if ds(!)0
 
4001
                NPUTF8 *strname = NPN_UTF8FromIdentifier (name);
 
4002
                printf ("adding scriptable object event %s\n", strname);
 
4003
                NPN_MemFree (strname);
 
4004
#endif
 
4005
                
 
4006
                if (NPVARIANT_IS_OBJECT (*value)) {
 
4007
                        NPObject *cb_obj = NPVARIANT_TO_OBJECT (*value);
 
4008
 
 
4009
                        NPN_RetainObject (cb_obj);
 
4010
 
 
4011
                        addevent (managed_scriptable, event->event_handle, this, cb_obj);
 
4012
                } else {
 
4013
                        DEBUG_WARN_NOTIMPLEMENTED ("scriptableobject.register_event (non-object)");
 
4014
                }
 
4015
                
 
4016
                return true;
 
4017
        }
 
4018
 
 
4019
        return MoonlightObject::SetProperty (id, name, value);
 
4020
}
 
4021
 
 
4022
bool
 
4023
MoonlightScriptableObjectObject::HasMethod (NPIdentifier name)
 
4024
{
 
4025
        return g_hash_table_lookup (methods, name) != NULL;
 
4026
}
 
4027
 
 
4028
bool
 
4029
MoonlightScriptableObjectObject::Invoke (int id, NPIdentifier name,
 
4030
                                         const NPVariant *args, uint32_t argCount,
 
4031
                                         NPVariant *result)
 
4032
{
 
4033
        ScriptableMethod *method = (ScriptableMethod*)g_hash_table_lookup (methods, name);
 
4034
        Value rv, **vargs = NULL;
 
4035
        uint32_t i;
 
4036
        
 
4037
        if (!method)
 
4038
                return MoonlightObject::Invoke (id, name, args, argCount, result);
 
4039
 
 
4040
#if ds(!)0
 
4041
        NPUTF8 *strname = NPN_UTF8FromIdentifier (name);
 
4042
        printf ("invoking scriptable object method %s\n", strname);
 
4043
        NPN_MemFree (strname);
 
4044
#endif
 
4045
        
 
4046
        if (argCount > 0) {
 
4047
                vargs = new Value*[argCount];
 
4048
                for (i = 0; i < argCount; i++)
 
4049
                        variant_to_value (&args[i], &vargs[i]);
 
4050
        }
 
4051
        
 
4052
        invoke (managed_scriptable, method->method_handle, vargs, argCount, &rv);
 
4053
        
 
4054
        if (argCount > 0) {
 
4055
                for (i = 0; i < argCount; i++)
 
4056
                        delete vargs[i];
 
4057
                
 
4058
                delete [] vargs;
 
4059
        }
 
4060
        
 
4061
        /* Note: this 1 is "void" */
 
4062
        if (method->method_return_type != 1)
 
4063
                value_to_variant (this, &rv, result);
 
4064
        
 
4065
        return true;
 
4066
}
 
4067
 
 
4068
 
 
4069
MoonlightScriptableObjectType::MoonlightScriptableObjectType ()
 
4070
{
 
4071
        allocate = moonlight_scriptable_object_allocate;
 
4072
}
 
4073
 
 
4074
MoonlightScriptableObjectType *MoonlightScriptableObjectClass;
 
4075
 
 
4076
MoonlightScriptableObjectObject *
 
4077
moonlight_scriptable_object_wrapper_create (PluginInstance *plugin, gpointer scriptable,
 
4078
                                            InvokeDelegate invoke_func,
 
4079
                                            SetPropertyDelegate setprop_func,
 
4080
                                            GetPropertyDelegate getprop_func,
 
4081
                                            EventHandlerDelegate addevent_func,
 
4082
                                            EventHandlerDelegate removeevent_func)
 
4083
 
 
4084
{
 
4085
        MoonlightScriptControlObject *root_object = plugin->GetRootObject ();
 
4086
 
 
4087
        MoonlightScriptableObjectObject *obj = (MoonlightScriptableObjectObject *)
 
4088
                NPN_CreateObject (((MoonlightObject *) root_object)->instance,
 
4089
                                  MoonlightScriptableObjectClass);
 
4090
 
 
4091
        obj->managed_scriptable = scriptable;
 
4092
        obj->invoke = invoke_func;
 
4093
        obj->setprop = setprop_func;
 
4094
        obj->getprop = getprop_func;
 
4095
        obj->addevent = addevent_func;
 
4096
        obj->removeevent = removeevent_func;
 
4097
        
 
4098
        ds(printf ("creating scriptable object wrapper => %p\n", obj));
 
4099
        
 
4100
        return obj;
 
4101
}
 
4102
 
 
4103
void
 
4104
moonlight_scriptable_object_add_property (PluginInstance *plugin,
 
4105
                                          MoonlightScriptableObjectObject *obj,
 
4106
                                          gpointer property_handle,
 
4107
                                          char *property_name,
 
4108
                                          int property_type,
 
4109
                                          bool can_read,
 
4110
                                          bool can_write)
 
4111
{
 
4112
        ds(printf ("adding property named %s to scriptable object %p\n", property_name, obj));
 
4113
        
 
4114
        ScriptableProperty *prop = new ScriptableProperty ();
 
4115
        prop->property_handle = property_handle;
 
4116
        prop->property_type = property_type;
 
4117
        prop->can_read = can_read;
 
4118
        prop->can_write = can_write;
 
4119
        
 
4120
        g_hash_table_insert (obj->properties, NPID(property_name), prop);
 
4121
}
 
4122
 
 
4123
void
 
4124
moonlight_scriptable_object_add_event (PluginInstance *plugin,
 
4125
                                       MoonlightScriptableObjectObject *obj,
 
4126
                                       gpointer event_handle,
 
4127
                                       char *event_name)
 
4128
{
 
4129
        ds(printf ("adding event named %s to scriptable object %p\n", event_name, obj));
 
4130
        
 
4131
        ScriptableEvent *event = new ScriptableEvent ();
 
4132
        event->event_handle = event_handle;
 
4133
 
 
4134
        g_hash_table_insert (obj->events, NPID(event_name), event);
 
4135
}
 
4136
 
 
4137
void
 
4138
moonlight_scriptable_object_add_method (PluginInstance *plugin,
 
4139
                                        MoonlightScriptableObjectObject *obj,
 
4140
                                        gpointer method_handle,
 
4141
                                        char *method_name,
 
4142
                                        int method_return_type,
 
4143
                                        int *method_parameter_types,
 
4144
                                        int parameter_count)
 
4145
 
 
4146
{
 
4147
        ds(printf ("adding method named %s (return type = %d) to scriptable object %p\n", method_name, method_return_type, obj));
 
4148
        
 
4149
        ScriptableMethod *method = new ScriptableMethod ();
 
4150
        method->method_handle = method_handle;
 
4151
        method->method_return_type = method_return_type;
 
4152
        method->method_parameter_types = new int[parameter_count];
 
4153
        memcpy (method->method_parameter_types, method_parameter_types, sizeof (int) * parameter_count);
 
4154
        method->parameter_count = parameter_count;
 
4155
 
 
4156
        g_hash_table_insert (obj->methods, NPID(method_name), method);
 
4157
}
 
4158
 
 
4159
void
 
4160
moonlight_scriptable_object_register (PluginInstance *plugin,
 
4161
                                      char *name,
 
4162
                                      MoonlightScriptableObjectObject *obj)
 
4163
{
 
4164
        ds(printf ("registering scriptable object '%s' => %p\n", name, obj));
 
4165
        
 
4166
        MoonlightContentObject *content = (MoonlightContentObject *) plugin->GetRootObject ()->content;
 
4167
        
 
4168
        g_hash_table_insert (content->registered_scriptable_objects, NPID (name), obj);
 
4169
        
 
4170
        ds(printf (" => done\n"));
 
4171
}
 
4172
 
 
4173
void
 
4174
moonlight_scriptable_object_emit_event (PluginInstance *plugin,
 
4175
                                        MoonlightScriptableObjectObject *sobj,
 
4176
                                        MoonlightScriptableObjectObject *event_args,
 
4177
                                        NPObject *cb_obj)
 
4178
{
 
4179
        NPVariant args[2];
 
4180
        NPVariant result;
 
4181
 
 
4182
        OBJECT_TO_NPVARIANT (sobj, args[0]);
 
4183
        OBJECT_TO_NPVARIANT (event_args, args[1]);
 
4184
 
 
4185
        if (NPN_InvokeDefault (plugin->GetInstance (), cb_obj, args, 2, &result))
 
4186
                NPN_ReleaseVariantValue (&result);
 
4187
}
 
4188
 
 
4189
 
 
4190
/****************************** HtmlObject *************************/
 
4191
 
 
4192
void
 
4193
html_object_get_property (PluginInstance *plugin, NPObject *npobj, char *name, Value *result)
 
4194
{
 
4195
        NPVariant npresult;
 
4196
        NPObject *window = NULL;
 
4197
        NPP npp = plugin->GetInstance ();
 
4198
        NPIdentifier identifier = NPN_GetStringIdentifier (name);
 
4199
 
 
4200
        if (npobj == NULL) {
 
4201
                NPN_GetValue (npp, NPNVWindowNPObject, &window);
 
4202
                npobj = window;
 
4203
        }
 
4204
 
 
4205
        NPN_GetProperty (npp, npobj, identifier, &npresult);
 
4206
 
 
4207
        Value *res = NULL;
 
4208
        if (!NPVARIANT_IS_VOID (npresult) && !NPVARIANT_IS_NULL (npresult)) {
 
4209
                variant_to_value (&npresult, &res);
 
4210
                *result = *res;
 
4211
        } else {
 
4212
                *result = Value (Type::INVALID);
 
4213
        }
 
4214
}
 
4215
 
 
4216
void
 
4217
html_object_set_property (PluginInstance *plugin, NPObject *npobj, char *name, Value *value)
 
4218
{
 
4219
        NPVariant npvalue;
 
4220
        NPObject *window = NULL;
 
4221
        NPP npp = plugin->GetInstance ();
 
4222
        NPIdentifier identifier = NPN_GetStringIdentifier (name);
 
4223
 
 
4224
        if (npobj == NULL) {
 
4225
                NPN_GetValue (npp, NPNVWindowNPObject, &window);
 
4226
                npobj = window;
 
4227
        }
 
4228
 
 
4229
        value_to_variant (npobj, value, &npvalue);
 
4230
 
 
4231
        NPN_SetProperty (npp, npobj, identifier, &npvalue);
 
4232
}
 
4233
 
 
4234
void
 
4235
html_object_invoke (PluginInstance *plugin, NPObject *npobj, char *name,
 
4236
                Value *args, uint32_t arg_count, Value *result)
 
4237
{
 
4238
        NPVariant npresult;
 
4239
        NPVariant *npargs = NULL;
 
4240
        NPObject *window = NULL;
 
4241
        NPP npp = plugin->GetInstance ();
 
4242
        NPIdentifier identifier = NPN_GetStringIdentifier (name);
 
4243
 
 
4244
        if (npobj == NULL) {
 
4245
                NPN_GetValue (npp, NPNVWindowNPObject, &window);
 
4246
                npobj = window;
 
4247
        }
 
4248
 
 
4249
        if (arg_count) {
 
4250
                npargs = new NPVariant [arg_count];
 
4251
                for (uint32_t i = 0; i < arg_count; i++)
 
4252
                        value_to_variant (npobj, &args [i], &npargs [i]);
 
4253
        }
 
4254
 
 
4255
        NPN_Invoke (npp, npobj, identifier, npargs, arg_count, &npresult);
 
4256
 
 
4257
        if (arg_count) {
 
4258
                for (uint32_t i = 0; i < arg_count; i++)
 
4259
                        NPN_ReleaseVariantValue (&npargs [i]);
 
4260
        }
 
4261
 
 
4262
        Value *res = NULL;
 
4263
        if (!NPVARIANT_IS_VOID (npresult) && !NPVARIANT_IS_NULL (npresult)) {
 
4264
                variant_to_value (&npresult, &res);
 
4265
                *result = *res;
 
4266
        } else {
 
4267
                *result = Value (Type::INVALID);
 
4268
        }
 
4269
}
 
4270
 
 
4271
const char *
 
4272
html_get_element_text (PluginInstance *plugin, const char *element_id)
 
4273
{
 
4274
        if (!plugin->GetBridge())
 
4275
                return NULL;
 
4276
        return plugin->GetBridge()->HtmlElementGetText(plugin->GetInstance(), element_id);
 
4277
}
 
4278
 
 
4279
gpointer
 
4280
html_object_attach_event (PluginInstance *plugin, NPObject *npobj, char *name, callback_dom_event *cb)
 
4281
{
 
4282
        if (!plugin->GetBridge())
 
4283
                return NULL;
 
4284
        return plugin->GetBridge()->HtmlObjectAttachEvent (plugin->GetInstance(), npobj, name, cb);
 
4285
}
 
4286
 
 
4287
void
 
4288
html_object_detach_event (PluginInstance *plugin, const char *name, gpointer listener_ptr)
 
4289
{
 
4290
        if (!plugin->GetBridge())
 
4291
                return;
 
4292
        plugin->GetBridge()->HtmlObjectDetachEvent (plugin->GetInstance(), name, listener_ptr);
 
4293
}
 
4294
 
 
4295
void
 
4296
html_object_release (PluginInstance *plugin, NPObject *npobj)
 
4297
{
 
4298
        NPN_ReleaseObject (npobj);
 
4299
}
 
4300
 
 
4301
void
 
4302
browser_do_alert (PluginInstance *plugin, char *msg)
 
4303
{
 
4304
        NPVariant npresult;
 
4305
        NPVariant *npargs = new NPVariant [1];
 
4306
        NPObject *window = NULL;
 
4307
        NPP npp = plugin->GetInstance ();
 
4308
        NPIdentifier identifier = NPN_GetStringIdentifier ("alert");
 
4309
 
 
4310
        NPN_GetValue (npp, NPNVWindowNPObject, &window);
 
4311
        string_to_npvariant (msg, &npargs [0]);
 
4312
 
 
4313
        NPN_Invoke (npp, window, identifier, npargs, 1, &npresult);
 
4314
}
 
4315
 
 
4316
 
 
4317
void
 
4318
plugin_init_classes (void)
 
4319
{
 
4320
        /*
 
4321
         * All classes that derive from MoonlightDependencyObject should be stored in the dependency_object_classes
 
4322
         * array, so that we can verify arguments passed from JS code are valid dependency objects, and not random
 
4323
         * JS objects.  ie element.children.add (new Array ())
 
4324
         */
 
4325
 
 
4326
        dependency_object_classes [COLLECTION_CLASS] = new MoonlightCollectionType ();
 
4327
        dependency_object_classes [DEPENDENCY_OBJECT_CLASS] = new MoonlightDependencyObjectType ();
 
4328
        dependency_object_classes [DOWNLOADER_CLASS] = new MoonlightDownloaderType ();
 
4329
        dependency_object_classes [IMAGE_BRUSH_CLASS] = new MoonlightImageBrushType ();
 
4330
        dependency_object_classes [IMAGE_CLASS] = new MoonlightImageType ();
 
4331
        dependency_object_classes [MEDIA_ELEMENT_CLASS] = new MoonlightMediaElementType ();
 
4332
        dependency_object_classes [STORYBOARD_CLASS] = new MoonlightStoryboardType ();
 
4333
        dependency_object_classes [STYLUS_INFO_CLASS] = new MoonlightStylusInfoType ();
 
4334
        dependency_object_classes [STYLUS_POINT_COLLECTION_CLASS] = new MoonlightStylusPointCollectionType ();
 
4335
        dependency_object_classes [STROKE_COLLECTION_CLASS] = new MoonlightStrokeCollectionType ();
 
4336
        dependency_object_classes [STROKE_CLASS] = new MoonlightStrokeType ();
 
4337
        dependency_object_classes [TEXT_BLOCK_CLASS] = new MoonlightTextBlockType ();
 
4338
        /* Event Arg Types */
 
4339
        dependency_object_classes [EVENT_ARGS_CLASS] = new MoonlightEventArgsType ();
 
4340
        dependency_object_classes [ROUTED_EVENT_ARGS_CLASS] = new MoonlightRoutedEventArgsType ();
 
4341
        dependency_object_classes [ERROR_EVENT_ARGS_CLASS] = new MoonlightErrorEventArgsType ();
 
4342
        dependency_object_classes [KEY_EVENT_ARGS_CLASS] = new MoonlightKeyEventArgsType ();
 
4343
        dependency_object_classes [MARKER_REACHED_EVENT_ARGS_CLASS] = new MoonlightMarkerReachedEventArgsType ();
 
4344
        dependency_object_classes [MOUSE_EVENT_ARGS_CLASS] = new MoonlightMouseEventArgsType ();
 
4345
        
 
4346
        MoonlightContentClass = new MoonlightContentType ();
 
4347
        MoonlightDurationClass = new MoonlightDurationType ();
 
4348
        MoonlightEventObjectClass = new MoonlightEventObjectType ();
 
4349
        MoonlightObjectClass = new MoonlightObjectType ();
 
4350
        MoonlightPointClass = new MoonlightPointType ();
 
4351
        MoonlightRectClass = new MoonlightRectType ();
 
4352
        MoonlightScriptableObjectClass = new MoonlightScriptableObjectType ();
 
4353
        MoonlightScriptControlClass = new MoonlightScriptControlType ();
 
4354
        MoonlightSettingsClass = new MoonlightSettingsType ();
 
4355
        MoonlightTimeSpanClass = new MoonlightTimeSpanType ();
 
4356
        MoonlightKeyTimeClass = new MoonlightKeyTimeType ();
 
4357
}
 
4358
 
 
4359
void
 
4360
plugin_destroy_classes (void)
 
4361
{
 
4362
        for (int i = 0; i < DEPENDENCY_OBJECT_CLASS_NAMES_LAST; i++) {
 
4363
                delete dependency_object_classes [i];
 
4364
                dependency_object_classes [i] = NULL;
 
4365
        }
 
4366
 
 
4367
        delete MoonlightContentClass; MoonlightContentClass = NULL;
 
4368
        delete MoonlightEventObjectClass; MoonlightEventObjectClass = NULL;
 
4369
        delete MoonlightErrorEventArgsClass; MoonlightErrorEventArgsClass = NULL;
 
4370
        delete MoonlightMouseEventArgsClass; MoonlightMouseEventArgsClass = NULL;
 
4371
        delete MoonlightKeyEventArgsClass; MoonlightKeyEventArgsClass = NULL;
 
4372
        delete MoonlightObjectClass; MoonlightObjectClass = NULL;
 
4373
        delete MoonlightScriptableObjectClass; MoonlightScriptableObjectClass = NULL;
 
4374
        delete MoonlightScriptControlClass; MoonlightScriptControlClass = NULL;
 
4375
        delete MoonlightSettingsClass; MoonlightSettingsClass = NULL;
 
4376
        delete MoonlightRectClass; MoonlightRectClass = NULL;
 
4377
        delete MoonlightPointClass; MoonlightPointClass = NULL;
 
4378
        delete MoonlightDurationClass; MoonlightDurationClass = NULL;
 
4379
        delete MoonlightTimeSpanClass; MoonlightTimeSpanClass = NULL;
 
4380
        delete MoonlightKeyTimeClass; MoonlightKeyTimeClass = NULL;
 
4381
        delete MoonlightMarkerReachedEventArgsClass; MoonlightMarkerReachedEventArgsClass = NULL;
 
4382
}