~woodrow-shen/totem/mybranch

« back to all changes in this revision

Viewing changes to browser-plugin/totemNPObject.cpp

Tags: 2.24.3-3
* totem-mozilla.docs: ship README.browser-plugin which explains how to 
  disable the plugin for some MIME types.
* rules: remove the hack that only let totem-xine support VCDs and 
  DVDs, now that GStreamer supports them. Closes: #370789.
* 01_fake_keypresses.patch: new patch. Completely disable the broken 
  XTEST code that generates fake keypresses. Closes: #500330.
* 90_autotools.patch: regenerated.
* Build-depend on nautilus 2.22 to be sure to build the extension for 
  the correct version.
* totem-xine depends on libxine1-x.
* Standards version is 3.8.1.
* Upload to unstable.
* 04_tracker_build.patch: new patch, stolen upstream. Fix build with 
  latest tracker version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2008 Christian Persch
 
3
 *
 
4
 * This library is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU Library General Public
 
6
 * License as published by the Free Software Foundation; either
 
7
 * version 2 of the License, or (at your option) any later version.
 
8
 *
 
9
 * This library is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
 * Library General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU Library General Public
 
15
 * License along with this library; if not, write to the
 
16
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
17
 * Boston, MA 02111-1307, USA.
 
18
 */
 
19
 
 
20
#include <config.h>
 
21
 
 
22
#include <string.h>
 
23
#include <stdio.h>
 
24
#include <stdarg.h>
 
25
 
 
26
#include <glib.h>
 
27
 
 
28
#include "totemNPClass.h"
 
29
#include "totemNPObject.h"
 
30
 
 
31
#ifdef DEBUG_PLUGIN
 
32
#define NOTE(x) x
 
33
#else
 
34
#define NOTE(x)
 
35
#endif
 
36
 
 
37
static const char *variantTypes[] = {
 
38
  "void",
 
39
  "null",
 
40
  "bool",
 
41
  "int32",
 
42
  "double",
 
43
  "string",
 
44
  "object",
 
45
  "unknown"
 
46
};
 
47
 
 
48
#define VARIANT_TYPE(type) (variantTypes[MIN (type, NPVariantType_Object + 1)])
 
49
 
 
50
void*
 
51
totemNPObject::operator new (size_t aSize) throw ()
 
52
{
 
53
  void *instance = ::operator new (aSize);
 
54
  if (instance) {
 
55
    memset (instance, 0, aSize);
 
56
  }
 
57
 
 
58
  return instance;
 
59
}
 
60
 
 
61
totemNPObject::totemNPObject (NPP aNPP)
 
62
  : mNPP (aNPP),
 
63
    mPlugin (reinterpret_cast<totemPlugin*>(aNPP->pdata))
 
64
{
 
65
  NOTE (g_print ("totemNPObject ctor [%p]\n", (void*) this));
 
66
}
 
67
 
 
68
totemNPObject::~totemNPObject ()
 
69
{
 
70
  NOTE (g_print ("totemNPObject dtor [%p]\n", (void*) this));
 
71
}
 
72
 
 
73
bool
 
74
totemNPObject::Throw (const char *aMessage)
 
75
{
 
76
  NOTE (g_print ("totemNPObject::Throw [%p] : %s\n", (void*) this, aMessage));
 
77
 
 
78
  NPN_SetException (this, aMessage);
 
79
  return false;
 
80
}
 
81
 
 
82
bool
 
83
totemNPObject::ThrowPropertyNotWritable ()
 
84
{
 
85
  return Throw ("Property not writable");
 
86
}
 
87
 
 
88
bool
 
89
totemNPObject::ThrowSecurityError ()
 
90
{
 
91
  return Throw ("Access denied");
 
92
}
 
93
 
 
94
bool
 
95
totemNPObject::CheckArgc (uint32_t argc,
 
96
                          uint32_t minArgc,
 
97
                          uint32_t maxArgc,
 
98
                          bool doThrow)
 
99
{
 
100
  if (argc >= minArgc && argc <= maxArgc)
 
101
    return true;
 
102
 
 
103
  if (argc < minArgc) {
 
104
    if (doThrow)
 
105
      return Throw ("Not enough arguments");
 
106
 
 
107
    return false;
 
108
  }
 
109
 
 
110
  if (doThrow)
 
111
    return Throw ("Too many arguments");
 
112
 
 
113
  return false;
 
114
}
 
115
 
 
116
bool
 
117
totemNPObject::CheckArgType (NPVariantType argType,
 
118
                             NPVariantType expectedType,
 
119
                             uint32_t argNum)
 
120
{
 
121
  bool conforms;
 
122
 
 
123
  switch (argType) {
 
124
    case NPVariantType_Void:
 
125
    case NPVariantType_Null:
 
126
      conforms = (argType == expectedType);
 
127
      break;
 
128
 
 
129
    case NPVariantType_Bool:
 
130
      conforms = (argType == NPVariantType_Bool ||
 
131
                  argType == NPVariantType_Int32 ||
 
132
                  argType == NPVariantType_Double);
 
133
      break;
 
134
 
 
135
    case NPVariantType_Int32:
 
136
    case NPVariantType_Double:
 
137
      /* FIXMEchpe: also accept NULL or VOID ? */
 
138
      conforms = (argType == NPVariantType_Int32 ||
 
139
                  argType == NPVariantType_Double);
 
140
      break;
 
141
 
 
142
    case NPVariantType_String:
 
143
    case NPVariantType_Object:
 
144
      conforms = (argType == expectedType ||
 
145
                  argType == NPVariantType_Null ||
 
146
                  argType == NPVariantType_Void);
 
147
      break;
 
148
    default:
 
149
      conforms = false;
 
150
  }
 
151
 
 
152
  if (!conforms) {
 
153
      char msg[128];
 
154
      g_snprintf (msg, sizeof (msg),
 
155
                  "Wrong type of argument %d: expected %s but got %s\n",
 
156
                  argNum, VARIANT_TYPE (expectedType), VARIANT_TYPE (argType));
 
157
 
 
158
      return Throw (msg);
 
159
  }
 
160
 
 
161
  return true;
 
162
}
 
163
 
 
164
bool
 
165
totemNPObject::CheckArg (const NPVariant *argv,
 
166
                         uint32_t argc,
 
167
                         uint32_t argNum,
 
168
                         NPVariantType type)
 
169
{
 
170
  if (!CheckArgc (argc, argNum + 1))
 
171
    return false;
 
172
 
 
173
  return CheckArgType (argv[argNum].type, type, argNum);
 
174
}
 
175
 
 
176
bool
 
177
totemNPObject::CheckArgv (const NPVariant* argv,
 
178
                          uint32_t argc,
 
179
                          uint32_t expectedArgc,
 
180
                          ...)
 
181
{
 
182
  if (!CheckArgc (argc, expectedArgc, expectedArgc))
 
183
    return false;
 
184
 
 
185
  va_list type_args;
 
186
  va_start (type_args, expectedArgc);
 
187
 
 
188
  for (uint32_t i = 0; i < argc; ++i) {
 
189
    NPVariantType type = NPVariantType (va_arg (type_args, int /* promotion */));
 
190
 
 
191
    if (!CheckArgType (argv[i].type, type)) {
 
192
      va_end (type_args);
 
193
      return false;
 
194
    }
 
195
  }
 
196
 
 
197
  va_end (type_args);
 
198
 
 
199
  return true;
 
200
}
 
201
 
 
202
bool
 
203
totemNPObject::GetBoolFromArguments (const NPVariant* argv,
 
204
                                     uint32_t argc,
 
205
                                     uint32_t argNum,
 
206
                                     bool& _result)
 
207
{
 
208
  if (!CheckArg (argv, argc, argNum, NPVariantType_Bool))
 
209
    return false;
 
210
 
 
211
  NPVariant arg = argv[argNum];
 
212
  if (NPVARIANT_IS_BOOLEAN (arg)) {
 
213
    _result = NPVARIANT_TO_BOOLEAN (arg);
 
214
  } else if (NPVARIANT_IS_INT32 (arg)) {
 
215
    _result = NPVARIANT_TO_INT32 (arg) != 0;
 
216
  } else if (NPVARIANT_IS_DOUBLE (arg)) {
 
217
    _result = NPVARIANT_TO_DOUBLE (arg) != 0.0;
 
218
  } else {
 
219
    /* void/null */
 
220
    _result = false;
 
221
  }
 
222
 
 
223
  return true;
 
224
}
 
225
 
 
226
bool
 
227
totemNPObject::GetInt32FromArguments (const NPVariant* argv,
 
228
                                      uint32_t argc,
 
229
                                      uint32_t argNum,
 
230
                                      int32_t& _result)
 
231
{
 
232
  if (!CheckArg (argv, argc, argNum, NPVariantType_Int32))
 
233
    return false;
 
234
 
 
235
  NPVariant arg = argv[argNum];
 
236
  if (NPVARIANT_IS_INT32 (arg)) {
 
237
    _result = NPVARIANT_TO_INT32 (arg);
 
238
  } else if (NPVARIANT_IS_DOUBLE (arg)) {
 
239
    _result = int32_t (NPVARIANT_TO_DOUBLE (arg));
 
240
    /* FIXMEchpe: overflow? */
 
241
  }
 
242
 
 
243
  return true;
 
244
}
 
245
 
 
246
bool
 
247
totemNPObject::GetDoubleFromArguments (const NPVariant* argv,
 
248
                                       uint32_t argc,
 
249
                                       uint32_t argNum,
 
250
                                       double& _result)
 
251
{
 
252
  if (!CheckArg (argv, argc, argNum, NPVariantType_Double))
 
253
    return false;
 
254
 
 
255
  NPVariant arg = argv[argNum];
 
256
  if (NPVARIANT_IS_DOUBLE (arg)) {
 
257
    _result = NPVARIANT_TO_DOUBLE (arg);
 
258
  } else if (NPVARIANT_IS_INT32 (arg)) {
 
259
    _result = double (NPVARIANT_TO_INT32 (arg));
 
260
  }
 
261
 
 
262
  return true;
 
263
}
 
264
 
 
265
bool
 
266
totemNPObject::GetStringFromArguments (const NPVariant* argv,
 
267
                                       uint32_t argc,
 
268
                                       uint32_t argNum,
 
269
                                       const char*& _result)
 
270
{
 
271
  if (!CheckArg (argv, argc, argNum, NPVariantType_String))
 
272
    return false;
 
273
 
 
274
  NPVariant arg = argv[argNum];
 
275
  if (NPVARIANT_IS_STRING (arg)) {
 
276
    NPString string = NPVARIANT_TO_STRING (arg);
 
277
    // FIXMEchpe this assumes it's 0-terminated, check that this holds!
 
278
    _result = string.UTF8Characters;
 
279
  } else if (NPVARIANT_IS_NULL (arg) ||
 
280
             NPVARIANT_IS_VOID (arg)) {
 
281
    _result = NULL;
 
282
  }
 
283
 
 
284
  return true;
 
285
}
 
286
 
 
287
bool
 
288
totemNPObject::DupStringFromArguments (const NPVariant* argv,
 
289
                                       uint32_t argc,
 
290
                                       uint32_t argNum,
 
291
                                       char*& _result)
 
292
{
 
293
  NPN_MemFree (_result);
 
294
  _result = NULL;
 
295
 
 
296
  const char *newValue;
 
297
  if (!GetStringFromArguments (argv, argc, argNum, newValue))
 
298
    return false;
 
299
 
 
300
  /* This assumes every NPString is 0-terminated. FIXMEchpe check that this holds! */
 
301
  _result = NPN_StrDup (newValue);
 
302
  return true;
 
303
}
 
304
 
 
305
bool
 
306
totemNPObject::GetObjectFromArguments (const NPVariant* argv,
 
307
                                        uint32_t argc,
 
308
                                        uint32_t argNum,
 
309
                                        NPObject*& _result)
 
310
{
 
311
  if (!CheckArg (argv, argc, argNum, NPVariantType_Object))
 
312
    return false;
 
313
 
 
314
  NPVariant arg = argv[argNum];
 
315
  if (NPVARIANT_IS_STRING (arg)) {
 
316
    _result = NPVARIANT_TO_OBJECT (arg);
 
317
  } else if (NPVARIANT_IS_NULL (arg) ||
 
318
             NPVARIANT_IS_VOID (arg)) {
 
319
    _result = NULL;
 
320
  }
 
321
 
 
322
  return true;
 
323
}
 
324
 
 
325
bool
 
326
totemNPObject::VoidVariant (NPVariant* _result)
 
327
{
 
328
  VOID_TO_NPVARIANT (*_result);
 
329
  return true;
 
330
}
 
331
 
 
332
bool
 
333
totemNPObject::NullVariant (NPVariant* _result)
 
334
{
 
335
  NULL_TO_NPVARIANT (*_result);
 
336
  return true;
 
337
}
 
338
 
 
339
bool
 
340
totemNPObject::BoolVariant (NPVariant* _result,
 
341
                            bool value)
 
342
{
 
343
  BOOLEAN_TO_NPVARIANT (value, *_result);
 
344
  return true;
 
345
}
 
346
 
 
347
bool
 
348
totemNPObject::Int32Variant (NPVariant* _result,
 
349
                             int32_t value)
 
350
{
 
351
  INT32_TO_NPVARIANT (value, *_result);
 
352
  return true;
 
353
}
 
354
 
 
355
bool
 
356
totemNPObject::DoubleVariant (NPVariant* _result,
 
357
                              double value)
 
358
{
 
359
  DOUBLE_TO_NPVARIANT (value, *_result);
 
360
  return true;
 
361
}
 
362
 
 
363
bool
 
364
totemNPObject::StringVariant (NPVariant* _result,
 
365
                              const char* value,
 
366
                              int32_t len)
 
367
{
 
368
  if (!value) {
 
369
    NULL_TO_NPVARIANT (*_result);
 
370
  } else {
 
371
    char *dup;
 
372
 
 
373
    if (len < 0) {
 
374
      len = strlen (value);
 
375
      dup = (char*) NPN_MemDup (value, len + 1);
 
376
    } else {
 
377
      dup = (char*) NPN_MemDup (value, len);
 
378
    }
 
379
 
 
380
    if (dup) {
 
381
      STRINGN_TO_NPVARIANT (dup, len, *_result);
 
382
    } else {
 
383
      NULL_TO_NPVARIANT (*_result);
 
384
    }
 
385
  }
 
386
 
 
387
  return true;
 
388
}
 
389
 
 
390
bool
 
391
totemNPObject::ObjectVariant (NPVariant* _result,
 
392
                              NPObject* object)
 
393
{
 
394
  if (object) {
 
395
    NPN_RetainObject (object);
 
396
    OBJECT_TO_NPVARIANT (object, *_result);
 
397
  } else {
 
398
    NULL_TO_NPVARIANT (*_result);
 
399
  }
 
400
 
 
401
  return true;
 
402
}
 
403
 
 
404
/* NPObject method default implementations */
 
405
 
 
406
void
 
407
totemNPObject::Invalidate ()
 
408
{
 
409
  NOTE (g_print ("totemNPObject %p invalidated\n", (void*) this));
 
410
 
 
411
  mNPP = NULL;
 
412
  mPlugin = NULL;
 
413
}
 
414
 
 
415
bool
 
416
totemNPObject::HasMethod (NPIdentifier aName)
 
417
{
 
418
  if (!IsValid ())
 
419
    return false;
 
420
 
 
421
  NOTE (g_print ("totemNPObject::HasMethod [%p] %s\n", (void*) this, NPN_UTF8FromIdentifier (aName)));
 
422
  if (GetClass()->GetMethodIndex (aName) >= 0)
 
423
    return true;
 
424
 
 
425
  if (aName == NPN_GetStringIdentifier ("__noSuchMethod__"))
 
426
    return true;
 
427
 
 
428
  return false;
 
429
}
 
430
 
 
431
bool
 
432
totemNPObject::Invoke (NPIdentifier aName,
 
433
                       const NPVariant *argv,
 
434
                       uint32_t argc,
 
435
                       NPVariant *_result)
 
436
{
 
437
  if (!IsValid ())
 
438
    return false;
 
439
 
 
440
  NOTE (g_print ("totemNPObject::Invoke [%p] %s\n", (void*) this, NPN_UTF8FromIdentifier (aName)));
 
441
  int methodIndex = GetClass()->GetMethodIndex (aName);
 
442
  if (methodIndex >= 0)
 
443
    return InvokeByIndex (methodIndex, argv, argc, _result);
 
444
 
 
445
  if (aName == NPN_GetStringIdentifier ("__noSuchMethod__")) {
 
446
    /* http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Object:_noSuchMethod */
 
447
    if (!CheckArgv (argv, argc, 2, NPVariantType_String, NPVariantType_Object))
 
448
      return false;
 
449
 
 
450
    const char *id = NPVARIANT_TO_STRING (argv[0]).UTF8Characters;
 
451
    g_message ("NOTE: site calls unknown function \"%s\" on totemNPObject %p\n", id ? id : "(null)", (void*) this);
 
452
 
 
453
    /* Silently ignore the invocation */
 
454
    VOID_TO_NPVARIANT (*_result);
 
455
    return true;
 
456
  }
 
457
 
 
458
  return Throw ("No method with this name exists.");
 
459
}
 
460
 
 
461
bool
 
462
totemNPObject::InvokeDefault (const NPVariant *argv,
 
463
                              uint32_t argc,
 
464
                              NPVariant *_result)
 
465
{
 
466
  if (!IsValid ())
 
467
    return false;
 
468
 
 
469
  NOTE (g_print ("totemNPObject::InvokeDefault [%p]\n", (void*) this));
 
470
  int defaultMethodIndex = GetClass()->GetDefaultMethodIndex ();
 
471
  if (defaultMethodIndex >= 0)
 
472
    return InvokeByIndex (defaultMethodIndex, argv, argc, _result);
 
473
 
 
474
  return false;
 
475
}
 
476
 
 
477
bool
 
478
totemNPObject::HasProperty (NPIdentifier aName)
 
479
{
 
480
  if (!IsValid ())
 
481
    return false;
 
482
 
 
483
  NOTE (g_print ("totemNPObject::HasProperty [%p] %s\n", (void*) this, NPN_UTF8FromIdentifier (aName)));
 
484
  if (GetClass()->GetPropertyIndex (aName) >= 0)
 
485
    return true;
 
486
 
 
487
  return false;
 
488
}
 
489
 
 
490
bool
 
491
totemNPObject::GetProperty (NPIdentifier aName,
 
492
                            NPVariant *_result)
 
493
{
 
494
  if (!IsValid ())
 
495
    return false;
 
496
 
 
497
  NOTE (g_print ("totemNPObject::GetProperty [%p] %s\n", (void*) this, NPN_UTF8FromIdentifier (aName)));
 
498
  int propertyIndex = GetClass()->GetPropertyIndex (aName);
 
499
  if (propertyIndex >= 0)
 
500
    return GetPropertyByIndex (propertyIndex, _result);
 
501
 
 
502
  return Throw ("No property with this name exists.");
 
503
}
 
504
 
 
505
bool
 
506
totemNPObject::SetProperty (NPIdentifier aName,
 
507
                            const NPVariant *aValue)
 
508
{
 
509
  if (!IsValid ())
 
510
    return false;
 
511
 
 
512
  NOTE (g_print ("totemNPObject::SetProperty [%p] %s\n", (void*) this, NPN_UTF8FromIdentifier (aName)));
 
513
  int propertyIndex = GetClass()->GetPropertyIndex (aName);
 
514
  if (propertyIndex >= 0)
 
515
    return SetPropertyByIndex (propertyIndex, aValue);
 
516
 
 
517
  return Throw ("No property with this name exists.");
 
518
}
 
519
 
 
520
bool
 
521
totemNPObject::RemoveProperty (NPIdentifier aName)
 
522
{
 
523
  if (!IsValid ())
 
524
    return false;
 
525
 
 
526
  NOTE (g_print ("totemNPObject::RemoveProperty [%p] %s\n", (void*) this, NPN_UTF8FromIdentifier (aName)));
 
527
  int propertyIndex = GetClass()->GetPropertyIndex (aName);
 
528
  if (propertyIndex >= 0)
 
529
    return RemovePropertyByIndex (propertyIndex);
 
530
 
 
531
  return Throw ("No property with this name exists.");
 
532
}
 
533
 
 
534
bool
 
535
totemNPObject::Enumerate (NPIdentifier **_result,
 
536
                          uint32_t *_count)
 
537
{
 
538
  if (!IsValid ())
 
539
    return false;
 
540
 
 
541
  NOTE (g_print ("totemNPObject::Enumerate [%p]\n", (void*) this));
 
542
  return GetClass()->EnumerateProperties (_result, _count);
 
543
}
 
544
 
 
545
bool
 
546
totemNPObject::Construct (const NPVariant *argv,
 
547
                          uint32_t argc,
 
548
                          NPVariant *_result)
 
549
{
 
550
  if (!IsValid ())
 
551
    return false;
 
552
 
 
553
  NOTE (g_print ("totemNPObject::Construct [%p]\n", (void*) this));
 
554
  return false; /* FIXMEchpe! */
 
555
}
 
556
 
 
557
/* by-index methods */
 
558
 
 
559
bool
 
560
totemNPObject::InvokeByIndex (int aIndex,
 
561
                              const NPVariant *argv,
 
562
                              uint32_t argc,
 
563
                              NPVariant *_result)
 
564
{
 
565
  return false;
 
566
}
 
567
 
 
568
bool
 
569
totemNPObject::GetPropertyByIndex (int aIndex,
 
570
                                   NPVariant *_result)
 
571
{
 
572
  return false;
 
573
}
 
574
 
 
575
bool
 
576
totemNPObject::SetPropertyByIndex (int aIndex,
 
577
                                   const NPVariant *aValue)
 
578
{
 
579
  return false;
 
580
}
 
581
 
 
582
bool
 
583
totemNPObject::RemovePropertyByIndex (int aIndex)
 
584
{
 
585
  return Throw ("Removing properties is not supported.");
 
586
}