Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / modules / plugin / sdk / samples / npruntime / plugin.cpp
blobf1a249e5a7574d22ea1faf4d17d3704b69ddbdaa
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Netscape Public License
6 * Version 1.1 (the "License"); you may not use this file except in
7 * compliance with the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/NPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the NPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the NPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 //////////////////////////////////////////////////
40 // CPlugin class implementation
42 #ifdef XP_WIN
43 #include <windows.h>
44 #include <windowsx.h>
45 #endif
47 #ifdef XP_MAC
48 #include <TextEdit.h>
49 #endif
51 #ifdef XP_UNIX
52 #include <string.h>
53 #endif
55 #include "plugin.h"
56 #include "npfunctions.h"
58 static NPIdentifier sFoo_id;
59 static NPIdentifier sBar_id;
60 static NPIdentifier sDocument_id;
61 static NPIdentifier sBody_id;
62 static NPIdentifier sCreateElement_id;
63 static NPIdentifier sCreateTextNode_id;
64 static NPIdentifier sAppendChild_id;
65 static NPIdentifier sPluginType_id;
66 static NPObject *sWindowObj;
68 // Helper class that can be used to map calls to the NPObject hooks
69 // into virtual methods on instances of classes that derive from this
70 // class.
71 class ScriptablePluginObjectBase : public NPObject
73 public:
74 ScriptablePluginObjectBase(NPP npp)
75 : mNpp(npp)
79 virtual ~ScriptablePluginObjectBase()
83 // Virtual NPObject hooks called through this base class. Override
84 // as you see fit.
85 virtual void Invalidate();
86 virtual bool HasMethod(NPIdentifier name);
87 virtual bool Invoke(NPIdentifier name, const NPVariant *args,
88 uint32_t argCount, NPVariant *result);
89 virtual bool InvokeDefault(const NPVariant *args, uint32_t argCount,
90 NPVariant *result);
91 virtual bool HasProperty(NPIdentifier name);
92 virtual bool GetProperty(NPIdentifier name, NPVariant *result);
93 virtual bool SetProperty(NPIdentifier name, const NPVariant *value);
94 virtual bool RemoveProperty(NPIdentifier name);
95 virtual bool Enumerate(NPIdentifier **identifier, uint32_t *count);
96 virtual bool Construct(const NPVariant *args, uint32_t argCount,
97 NPVariant *result);
99 public:
100 static void _Deallocate(NPObject *npobj);
101 static void _Invalidate(NPObject *npobj);
102 static bool _HasMethod(NPObject *npobj, NPIdentifier name);
103 static bool _Invoke(NPObject *npobj, NPIdentifier name,
104 const NPVariant *args, uint32_t argCount,
105 NPVariant *result);
106 static bool _InvokeDefault(NPObject *npobj, const NPVariant *args,
107 uint32_t argCount, NPVariant *result);
108 static bool _HasProperty(NPObject * npobj, NPIdentifier name);
109 static bool _GetProperty(NPObject *npobj, NPIdentifier name,
110 NPVariant *result);
111 static bool _SetProperty(NPObject *npobj, NPIdentifier name,
112 const NPVariant *value);
113 static bool _RemoveProperty(NPObject *npobj, NPIdentifier name);
114 static bool _Enumerate(NPObject *npobj, NPIdentifier **identifier,
115 uint32_t *count);
116 static bool _Construct(NPObject *npobj, const NPVariant *args,
117 uint32_t argCount, NPVariant *result);
119 protected:
120 NPP mNpp;
123 #define DECLARE_NPOBJECT_CLASS_WITH_BASE(_class, ctor) \
124 static NPClass s##_class##_NPClass = { \
125 NP_CLASS_STRUCT_VERSION_CTOR, \
126 ctor, \
127 ScriptablePluginObjectBase::_Deallocate, \
128 ScriptablePluginObjectBase::_Invalidate, \
129 ScriptablePluginObjectBase::_HasMethod, \
130 ScriptablePluginObjectBase::_Invoke, \
131 ScriptablePluginObjectBase::_InvokeDefault, \
132 ScriptablePluginObjectBase::_HasProperty, \
133 ScriptablePluginObjectBase::_GetProperty, \
134 ScriptablePluginObjectBase::_SetProperty, \
135 ScriptablePluginObjectBase::_RemoveProperty, \
136 ScriptablePluginObjectBase::_Enumerate, \
137 ScriptablePluginObjectBase::_Construct \
140 #define GET_NPOBJECT_CLASS(_class) &s##_class##_NPClass
142 void
143 ScriptablePluginObjectBase::Invalidate()
147 bool
148 ScriptablePluginObjectBase::HasMethod(NPIdentifier name)
150 return false;
153 bool
154 ScriptablePluginObjectBase::Invoke(NPIdentifier name, const NPVariant *args,
155 uint32_t argCount, NPVariant *result)
157 return false;
160 bool
161 ScriptablePluginObjectBase::InvokeDefault(const NPVariant *args,
162 uint32_t argCount, NPVariant *result)
164 return false;
167 bool
168 ScriptablePluginObjectBase::HasProperty(NPIdentifier name)
170 return false;
173 bool
174 ScriptablePluginObjectBase::GetProperty(NPIdentifier name, NPVariant *result)
176 return false;
179 bool
180 ScriptablePluginObjectBase::SetProperty(NPIdentifier name,
181 const NPVariant *value)
183 if (name == sBar_id) {
184 printf ("bar set\n");
186 return true;
189 return false;
192 bool
193 ScriptablePluginObjectBase::RemoveProperty(NPIdentifier name)
195 return false;
198 bool
199 ScriptablePluginObjectBase::Enumerate(NPIdentifier **identifier,
200 uint32_t *count)
202 return false;
205 bool
206 ScriptablePluginObjectBase::Construct(const NPVariant *args, uint32_t argCount,
207 NPVariant *result)
209 return false;
212 // static
213 void
214 ScriptablePluginObjectBase::_Deallocate(NPObject *npobj)
216 // Call the virtual destructor.
217 delete (ScriptablePluginObjectBase *)npobj;
220 // static
221 void
222 ScriptablePluginObjectBase::_Invalidate(NPObject *npobj)
224 ((ScriptablePluginObjectBase *)npobj)->Invalidate();
227 // static
228 bool
229 ScriptablePluginObjectBase::_HasMethod(NPObject *npobj, NPIdentifier name)
231 return ((ScriptablePluginObjectBase *)npobj)->HasMethod(name);
234 // static
235 bool
236 ScriptablePluginObjectBase::_Invoke(NPObject *npobj, NPIdentifier name,
237 const NPVariant *args, uint32_t argCount,
238 NPVariant *result)
240 return ((ScriptablePluginObjectBase *)npobj)->Invoke(name, args, argCount,
241 result);
244 // static
245 bool
246 ScriptablePluginObjectBase::_InvokeDefault(NPObject *npobj,
247 const NPVariant *args,
248 uint32_t argCount,
249 NPVariant *result)
251 return ((ScriptablePluginObjectBase *)npobj)->InvokeDefault(args, argCount,
252 result);
255 // static
256 bool
257 ScriptablePluginObjectBase::_HasProperty(NPObject * npobj, NPIdentifier name)
259 return ((ScriptablePluginObjectBase *)npobj)->HasProperty(name);
262 // static
263 bool
264 ScriptablePluginObjectBase::_GetProperty(NPObject *npobj, NPIdentifier name,
265 NPVariant *result)
267 return ((ScriptablePluginObjectBase *)npobj)->GetProperty(name, result);
270 // static
271 bool
272 ScriptablePluginObjectBase::_SetProperty(NPObject *npobj, NPIdentifier name,
273 const NPVariant *value)
275 return ((ScriptablePluginObjectBase *)npobj)->SetProperty(name, value);
278 // static
279 bool
280 ScriptablePluginObjectBase::_RemoveProperty(NPObject *npobj, NPIdentifier name)
282 return ((ScriptablePluginObjectBase *)npobj)->RemoveProperty(name);
285 // static
286 bool
287 ScriptablePluginObjectBase::_Enumerate(NPObject *npobj,
288 NPIdentifier **identifier,
289 uint32_t *count)
291 return ((ScriptablePluginObjectBase *)npobj)->Enumerate(identifier, count);
294 // static
295 bool
296 ScriptablePluginObjectBase::_Construct(NPObject *npobj, const NPVariant *args,
297 uint32_t argCount, NPVariant *result)
299 return ((ScriptablePluginObjectBase *)npobj)->Construct(args, argCount,
300 result);
304 class ConstructablePluginObject : public ScriptablePluginObjectBase
306 public:
307 ConstructablePluginObject(NPP npp)
308 : ScriptablePluginObjectBase(npp)
312 virtual bool Construct(const NPVariant *args, uint32_t argCount,
313 NPVariant *result);
316 static NPObject *
317 AllocateConstructablePluginObject(NPP npp, NPClass *aClass)
319 return new ConstructablePluginObject(npp);
322 DECLARE_NPOBJECT_CLASS_WITH_BASE(ConstructablePluginObject,
323 AllocateConstructablePluginObject);
325 bool
326 ConstructablePluginObject::Construct(const NPVariant *args, uint32_t argCount,
327 NPVariant *result)
329 printf("Creating new ConstructablePluginObject!\n");
331 NPObject *myobj =
332 NPN_CreateObject(mNpp, GET_NPOBJECT_CLASS(ConstructablePluginObject));
333 if (!myobj)
334 return false;
336 OBJECT_TO_NPVARIANT(myobj, *result);
338 return true;
341 class ScriptablePluginObject : public ScriptablePluginObjectBase
343 public:
344 ScriptablePluginObject(NPP npp)
345 : ScriptablePluginObjectBase(npp)
349 virtual bool HasMethod(NPIdentifier name);
350 virtual bool HasProperty(NPIdentifier name);
351 virtual bool GetProperty(NPIdentifier name, NPVariant *result);
352 virtual bool Invoke(NPIdentifier name, const NPVariant *args,
353 uint32_t argCount, NPVariant *result);
354 virtual bool InvokeDefault(const NPVariant *args, uint32_t argCount,
355 NPVariant *result);
358 static NPObject *
359 AllocateScriptablePluginObject(NPP npp, NPClass *aClass)
361 return new ScriptablePluginObject(npp);
364 DECLARE_NPOBJECT_CLASS_WITH_BASE(ScriptablePluginObject,
365 AllocateScriptablePluginObject);
367 bool
368 ScriptablePluginObject::HasMethod(NPIdentifier name)
370 return name == sFoo_id;
373 bool
374 ScriptablePluginObject::HasProperty(NPIdentifier name)
376 return (name == sBar_id ||
377 name == sPluginType_id);
380 bool
381 ScriptablePluginObject::GetProperty(NPIdentifier name, NPVariant *result)
383 VOID_TO_NPVARIANT(*result);
385 if (name == sBar_id) {
386 static int a = 17;
388 INT32_TO_NPVARIANT(a, *result);
390 a += 5;
392 return true;
395 if (name == sPluginType_id) {
396 NPObject *myobj =
397 NPN_CreateObject(mNpp, GET_NPOBJECT_CLASS(ConstructablePluginObject));
398 if (!myobj) {
399 return false;
402 OBJECT_TO_NPVARIANT(myobj, *result);
404 return true;
407 return true;
410 bool
411 ScriptablePluginObject::Invoke(NPIdentifier name, const NPVariant *args,
412 uint32_t argCount, NPVariant *result)
414 if (name == sFoo_id) {
415 printf ("foo called!\n");
417 NPVariant docv;
418 NPN_GetProperty(mNpp, sWindowObj, sDocument_id, &docv);
420 NPObject *doc = NPVARIANT_TO_OBJECT(docv);
422 NPVariant strv;
423 STRINGZ_TO_NPVARIANT("div", strv);
425 NPVariant divv;
426 NPN_Invoke(mNpp, doc, sCreateElement_id, &strv, 1, &divv);
428 STRINGZ_TO_NPVARIANT("I'm created by a plugin!", strv);
430 NPVariant textv;
431 NPN_Invoke(mNpp, doc, sCreateTextNode_id, &strv, 1, &textv);
433 NPVariant v;
434 NPN_Invoke(mNpp, NPVARIANT_TO_OBJECT(divv), sAppendChild_id, &textv, 1,
435 &v);
436 NPN_ReleaseVariantValue(&v);
438 NPN_ReleaseVariantValue(&textv);
440 NPVariant bodyv;
441 NPN_GetProperty(mNpp, doc, sBody_id, &bodyv);
443 NPN_Invoke(mNpp, NPVARIANT_TO_OBJECT(bodyv), sAppendChild_id, &divv, 1,
444 &v);
445 NPN_ReleaseVariantValue(&v);
447 NPN_ReleaseVariantValue(&divv);
448 NPN_ReleaseVariantValue(&bodyv);
450 NPN_ReleaseVariantValue(&docv);
452 STRINGZ_TO_NPVARIANT(strdup("foo return val"), *result);
454 return true;
457 return false;
460 bool
461 ScriptablePluginObject::InvokeDefault(const NPVariant *args, uint32_t argCount,
462 NPVariant *result)
464 printf ("ScriptablePluginObject default method called!\n");
466 STRINGZ_TO_NPVARIANT(strdup("default method return val"), *result);
468 return true;
471 CPlugin::CPlugin(NPP pNPInstance) :
472 m_pNPInstance(pNPInstance),
473 m_pNPStream(NULL),
474 m_bInitialized(false),
475 m_pScriptableObject(NULL)
477 #ifdef XP_WIN
478 m_hWnd = NULL;
479 #endif
481 NPN_GetValue(m_pNPInstance, NPNVWindowNPObject, &sWindowObj);
483 NPIdentifier n = NPN_GetStringIdentifier("foof");
485 sFoo_id = NPN_GetStringIdentifier("foo");
486 sBar_id = NPN_GetStringIdentifier("bar");
487 sDocument_id = NPN_GetStringIdentifier("document");
488 sBody_id = NPN_GetStringIdentifier("body");
489 sCreateElement_id = NPN_GetStringIdentifier("createElement");
490 sCreateTextNode_id = NPN_GetStringIdentifier("createTextNode");
491 sAppendChild_id = NPN_GetStringIdentifier("appendChild");
492 sPluginType_id = NPN_GetStringIdentifier("PluginType");
494 NPVariant v;
495 INT32_TO_NPVARIANT(46, v);
497 NPN_SetProperty(m_pNPInstance, sWindowObj, n, &v);
499 NPVariant rval;
500 NPN_GetProperty(m_pNPInstance, sWindowObj, n, &rval);
502 if (NPVARIANT_IS_INT32(rval)) {
503 printf("rval = %d\n", NPVARIANT_TO_INT32(rval));
506 n = NPN_GetStringIdentifier("document");
508 if (!NPN_IdentifierIsString(n)) {
509 NPString str;
510 str.UTF8Characters = "alert('NPN_IdentifierIsString() test failed!');";
511 str.UTF8Length = strlen(str.UTF8Characters);
513 NPN_Evaluate(m_pNPInstance, sWindowObj, &str, NULL);
516 NPObject *doc;
518 NPN_GetProperty(m_pNPInstance, sWindowObj, n, &rval);
520 if (NPVARIANT_IS_OBJECT(rval) && (doc = NPVARIANT_TO_OBJECT(rval))) {
521 n = NPN_GetStringIdentifier("title");
523 NPN_GetProperty(m_pNPInstance, doc, n, &rval);
525 if (NPVARIANT_IS_STRING(rval)) {
526 printf ("title = %s\n", NPVARIANT_TO_STRING(rval).UTF8Characters);
528 NPN_ReleaseVariantValue(&rval);
531 n = NPN_GetStringIdentifier("plugindoc");
533 OBJECT_TO_NPVARIANT(doc, v);
534 NPN_SetProperty(m_pNPInstance, sWindowObj, n, &v);
536 NPString str;
537 str.UTF8Characters = "document.getElementById('result').innerHTML += '<p>' + 'NPN_Evaluate() test, document = ' + this + '</p>';";
538 str.UTF8Length = strlen(str.UTF8Characters);
540 NPN_Evaluate(m_pNPInstance, doc, &str, NULL);
542 NPN_ReleaseObject(doc);
545 NPVariant barval;
546 NPN_GetProperty(m_pNPInstance, sWindowObj, sBar_id, &barval);
548 NPVariant arg;
549 OBJECT_TO_NPVARIANT(sWindowObj, arg);
551 NPN_InvokeDefault(m_pNPInstance, NPVARIANT_TO_OBJECT(barval), &arg, 1,
552 &rval);
554 if (NPVARIANT_IS_INT32(rval) && NPVARIANT_TO_INT32(rval) == 4) {
555 printf ("Default function call SUCCEEDED!\n");
556 } else {
557 printf ("Default function call FAILED!\n");
560 NPN_ReleaseVariantValue(&barval);
561 NPN_ReleaseVariantValue(&rval);
564 #if 0
565 n = NPN_GetStringIdentifier("prompt");
567 NPVariant vars[3];
568 STRINGZ_TO_NPVARIANT("foo", vars[0]);
569 STRINGZ_TO_NPVARIANT("bar", vars[1]);
570 STRINGZ_TO_NPVARIANT("foof", vars[2]);
572 NPN_Invoke(sWindowObj, n, vars, 3, &rval);
574 if (NPVARIANT_IS_STRING(rval)) {
575 printf ("prompt returned '%s'\n", NPVARIANT_TO_STRING(rval).UTF8Characters);
578 NPN_ReleaseVariantValue(&rval);
579 #endif
581 NPObject *myobj =
582 NPN_CreateObject(m_pNPInstance,
583 GET_NPOBJECT_CLASS(ScriptablePluginObject));
585 n = NPN_GetStringIdentifier("pluginobj");
587 OBJECT_TO_NPVARIANT(myobj, v);
588 NPN_SetProperty(m_pNPInstance, sWindowObj, n, &v);
590 NPN_GetProperty(m_pNPInstance, sWindowObj, n, &rval);
592 printf ("Object set/get test ");
594 if (NPVARIANT_IS_OBJECT(rval) && NPVARIANT_TO_OBJECT(rval) == myobj) {
595 printf ("succeeded!\n");
596 } else {
597 printf ("FAILED!\n");
600 NPN_ReleaseVariantValue(&rval);
601 NPN_ReleaseObject(myobj);
603 const char *ua = NPN_UserAgent(m_pNPInstance);
604 strcpy(m_String, ua);
607 CPlugin::~CPlugin()
609 if (sWindowObj)
610 NPN_ReleaseObject(sWindowObj);
611 if (m_pScriptableObject)
612 NPN_ReleaseObject(m_pScriptableObject);
614 sWindowObj = 0;
617 #ifdef XP_WIN
618 static LRESULT CALLBACK PluginWinProc(HWND, UINT, WPARAM, LPARAM);
619 static WNDPROC lpOldProc = NULL;
620 #endif
622 NPBool CPlugin::init(NPWindow* pNPWindow)
624 if(pNPWindow == NULL)
625 return false;
627 #ifdef XP_WIN
628 m_hWnd = (HWND)pNPWindow->window;
629 if(m_hWnd == NULL)
630 return false;
632 // subclass window so we can intercept window messages and
633 // do our drawing to it
634 lpOldProc = SubclassWindow(m_hWnd, (WNDPROC)PluginWinProc);
636 // associate window with our CPlugin object so we can access
637 // it in the window procedure
638 SetWindowLong(m_hWnd, GWL_USERDATA, (LONG)this);
639 #endif
641 m_Window = pNPWindow;
643 m_bInitialized = true;
644 return true;
647 void CPlugin::shut()
649 #ifdef XP_WIN
650 // subclass it back
651 SubclassWindow(m_hWnd, lpOldProc);
652 m_hWnd = NULL;
653 #endif
655 m_bInitialized = false;
658 NPBool CPlugin::isInitialized()
660 return m_bInitialized;
663 int16_t CPlugin::handleEvent(void* event)
665 #ifdef XP_MAC
666 NPEvent* ev = (NPEvent*)event;
667 if (m_Window) {
668 Rect box = { m_Window->y, m_Window->x,
669 m_Window->y + m_Window->height, m_Window->x + m_Window->width };
670 if (ev->what == updateEvt) {
671 ::TETextBox(m_String, strlen(m_String), &box, teJustCenter);
674 #endif
675 return 0;
678 // this will force to draw a version string in the plugin window
679 void CPlugin::showVersion()
681 const char *ua = NPN_UserAgent(m_pNPInstance);
682 strcpy(m_String, ua);
684 #ifdef XP_WIN
685 InvalidateRect(m_hWnd, NULL, true);
686 UpdateWindow(m_hWnd);
687 #endif
689 if (m_Window) {
690 NPRect r =
692 (uint16_t)m_Window->y, (uint16_t)m_Window->x,
693 (uint16_t)(m_Window->y + m_Window->height),
694 (uint16_t)(m_Window->x + m_Window->width)
697 NPN_InvalidateRect(m_pNPInstance, &r);
701 // this will clean the plugin window
702 void CPlugin::clear()
704 strcpy(m_String, "");
706 #ifdef XP_WIN
707 InvalidateRect(m_hWnd, NULL, true);
708 UpdateWindow(m_hWnd);
709 #endif
712 void CPlugin::getVersion(char* *aVersion)
714 const char *ua = NPN_UserAgent(m_pNPInstance);
715 char*& version = *aVersion;
716 version = (char*)NPN_MemAlloc(1 + strlen(ua));
717 if (version)
718 strcpy(version, ua);
721 NPObject *
722 CPlugin::GetScriptableObject()
724 if (!m_pScriptableObject) {
725 m_pScriptableObject =
726 NPN_CreateObject(m_pNPInstance,
727 GET_NPOBJECT_CLASS(ScriptablePluginObject));
730 if (m_pScriptableObject) {
731 NPN_RetainObject(m_pScriptableObject);
734 return m_pScriptableObject;
737 #ifdef XP_WIN
738 static LRESULT CALLBACK PluginWinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
740 switch (msg) {
741 case WM_PAINT:
743 // draw a frame and display the string
744 PAINTSTRUCT ps;
745 HDC hdc = BeginPaint(hWnd, &ps);
746 RECT rc;
747 GetClientRect(hWnd, &rc);
748 FrameRect(hdc, &rc, GetStockBrush(BLACK_BRUSH));
749 CPlugin * p = (CPlugin *)GetWindowLong(hWnd, GWL_USERDATA);
750 if(p) {
751 if (p->m_String[0] == 0) {
752 strcpy("foo", p->m_String);
755 DrawText(hdc, p->m_String, strlen(p->m_String), &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
758 EndPaint(hWnd, &ps);
760 break;
761 default:
762 break;
765 return DefWindowProc(hWnd, msg, wParam, lParam);
767 #endif