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
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.
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
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
71 class ScriptablePluginObjectBase
: public NPObject
74 ScriptablePluginObjectBase(NPP npp
)
79 virtual ~ScriptablePluginObjectBase()
83 // Virtual NPObject hooks called through this base class. Override
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
,
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
,
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
,
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
,
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
,
116 static bool _Construct(NPObject
*npobj
, const NPVariant
*args
,
117 uint32_t argCount
, NPVariant
*result
);
123 #define DECLARE_NPOBJECT_CLASS_WITH_BASE(_class, ctor) \
124 static NPClass s##_class##_NPClass = { \
125 NP_CLASS_STRUCT_VERSION_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
143 ScriptablePluginObjectBase::Invalidate()
148 ScriptablePluginObjectBase::HasMethod(NPIdentifier name
)
154 ScriptablePluginObjectBase::Invoke(NPIdentifier name
, const NPVariant
*args
,
155 uint32_t argCount
, NPVariant
*result
)
161 ScriptablePluginObjectBase::InvokeDefault(const NPVariant
*args
,
162 uint32_t argCount
, NPVariant
*result
)
168 ScriptablePluginObjectBase::HasProperty(NPIdentifier name
)
174 ScriptablePluginObjectBase::GetProperty(NPIdentifier name
, NPVariant
*result
)
180 ScriptablePluginObjectBase::SetProperty(NPIdentifier name
,
181 const NPVariant
*value
)
183 if (name
== sBar_id
) {
184 printf ("bar set\n");
193 ScriptablePluginObjectBase::RemoveProperty(NPIdentifier name
)
199 ScriptablePluginObjectBase::Enumerate(NPIdentifier
**identifier
,
206 ScriptablePluginObjectBase::Construct(const NPVariant
*args
, uint32_t argCount
,
214 ScriptablePluginObjectBase::_Deallocate(NPObject
*npobj
)
216 // Call the virtual destructor.
217 delete (ScriptablePluginObjectBase
*)npobj
;
222 ScriptablePluginObjectBase::_Invalidate(NPObject
*npobj
)
224 ((ScriptablePluginObjectBase
*)npobj
)->Invalidate();
229 ScriptablePluginObjectBase::_HasMethod(NPObject
*npobj
, NPIdentifier name
)
231 return ((ScriptablePluginObjectBase
*)npobj
)->HasMethod(name
);
236 ScriptablePluginObjectBase::_Invoke(NPObject
*npobj
, NPIdentifier name
,
237 const NPVariant
*args
, uint32_t argCount
,
240 return ((ScriptablePluginObjectBase
*)npobj
)->Invoke(name
, args
, argCount
,
246 ScriptablePluginObjectBase::_InvokeDefault(NPObject
*npobj
,
247 const NPVariant
*args
,
251 return ((ScriptablePluginObjectBase
*)npobj
)->InvokeDefault(args
, argCount
,
257 ScriptablePluginObjectBase::_HasProperty(NPObject
* npobj
, NPIdentifier name
)
259 return ((ScriptablePluginObjectBase
*)npobj
)->HasProperty(name
);
264 ScriptablePluginObjectBase::_GetProperty(NPObject
*npobj
, NPIdentifier name
,
267 return ((ScriptablePluginObjectBase
*)npobj
)->GetProperty(name
, result
);
272 ScriptablePluginObjectBase::_SetProperty(NPObject
*npobj
, NPIdentifier name
,
273 const NPVariant
*value
)
275 return ((ScriptablePluginObjectBase
*)npobj
)->SetProperty(name
, value
);
280 ScriptablePluginObjectBase::_RemoveProperty(NPObject
*npobj
, NPIdentifier name
)
282 return ((ScriptablePluginObjectBase
*)npobj
)->RemoveProperty(name
);
287 ScriptablePluginObjectBase::_Enumerate(NPObject
*npobj
,
288 NPIdentifier
**identifier
,
291 return ((ScriptablePluginObjectBase
*)npobj
)->Enumerate(identifier
, count
);
296 ScriptablePluginObjectBase::_Construct(NPObject
*npobj
, const NPVariant
*args
,
297 uint32_t argCount
, NPVariant
*result
)
299 return ((ScriptablePluginObjectBase
*)npobj
)->Construct(args
, argCount
,
304 class ConstructablePluginObject
: public ScriptablePluginObjectBase
307 ConstructablePluginObject(NPP npp
)
308 : ScriptablePluginObjectBase(npp
)
312 virtual bool Construct(const NPVariant
*args
, uint32_t argCount
,
317 AllocateConstructablePluginObject(NPP npp
, NPClass
*aClass
)
319 return new ConstructablePluginObject(npp
);
322 DECLARE_NPOBJECT_CLASS_WITH_BASE(ConstructablePluginObject
,
323 AllocateConstructablePluginObject
);
326 ConstructablePluginObject::Construct(const NPVariant
*args
, uint32_t argCount
,
329 printf("Creating new ConstructablePluginObject!\n");
332 NPN_CreateObject(mNpp
, GET_NPOBJECT_CLASS(ConstructablePluginObject
));
336 OBJECT_TO_NPVARIANT(myobj
, *result
);
341 class ScriptablePluginObject
: public ScriptablePluginObjectBase
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
,
359 AllocateScriptablePluginObject(NPP npp
, NPClass
*aClass
)
361 return new ScriptablePluginObject(npp
);
364 DECLARE_NPOBJECT_CLASS_WITH_BASE(ScriptablePluginObject
,
365 AllocateScriptablePluginObject
);
368 ScriptablePluginObject::HasMethod(NPIdentifier name
)
370 return name
== sFoo_id
;
374 ScriptablePluginObject::HasProperty(NPIdentifier name
)
376 return (name
== sBar_id
||
377 name
== sPluginType_id
);
381 ScriptablePluginObject::GetProperty(NPIdentifier name
, NPVariant
*result
)
383 VOID_TO_NPVARIANT(*result
);
385 if (name
== sBar_id
) {
388 INT32_TO_NPVARIANT(a
, *result
);
395 if (name
== sPluginType_id
) {
397 NPN_CreateObject(mNpp
, GET_NPOBJECT_CLASS(ConstructablePluginObject
));
402 OBJECT_TO_NPVARIANT(myobj
, *result
);
411 ScriptablePluginObject::Invoke(NPIdentifier name
, const NPVariant
*args
,
412 uint32_t argCount
, NPVariant
*result
)
414 if (name
== sFoo_id
) {
415 printf ("foo called!\n");
418 NPN_GetProperty(mNpp
, sWindowObj
, sDocument_id
, &docv
);
420 NPObject
*doc
= NPVARIANT_TO_OBJECT(docv
);
423 STRINGZ_TO_NPVARIANT("div", strv
);
426 NPN_Invoke(mNpp
, doc
, sCreateElement_id
, &strv
, 1, &divv
);
428 STRINGZ_TO_NPVARIANT("I'm created by a plugin!", strv
);
431 NPN_Invoke(mNpp
, doc
, sCreateTextNode_id
, &strv
, 1, &textv
);
434 NPN_Invoke(mNpp
, NPVARIANT_TO_OBJECT(divv
), sAppendChild_id
, &textv
, 1,
436 NPN_ReleaseVariantValue(&v
);
438 NPN_ReleaseVariantValue(&textv
);
441 NPN_GetProperty(mNpp
, doc
, sBody_id
, &bodyv
);
443 NPN_Invoke(mNpp
, NPVARIANT_TO_OBJECT(bodyv
), sAppendChild_id
, &divv
, 1,
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
);
461 ScriptablePluginObject::InvokeDefault(const NPVariant
*args
, uint32_t argCount
,
464 printf ("ScriptablePluginObject default method called!\n");
466 STRINGZ_TO_NPVARIANT(strdup("default method return val"), *result
);
471 CPlugin::CPlugin(NPP pNPInstance
) :
472 m_pNPInstance(pNPInstance
),
474 m_bInitialized(false),
475 m_pScriptableObject(NULL
)
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");
495 INT32_TO_NPVARIANT(46, v
);
497 NPN_SetProperty(m_pNPInstance
, sWindowObj
, n
, &v
);
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
)) {
510 str
.UTF8Characters
= "alert('NPN_IdentifierIsString() test failed!');";
511 str
.UTF8Length
= strlen(str
.UTF8Characters
);
513 NPN_Evaluate(m_pNPInstance
, sWindowObj
, &str
, NULL
);
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
);
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
);
546 NPN_GetProperty(m_pNPInstance
, sWindowObj
, sBar_id
, &barval
);
549 OBJECT_TO_NPVARIANT(sWindowObj
, arg
);
551 NPN_InvokeDefault(m_pNPInstance
, NPVARIANT_TO_OBJECT(barval
), &arg
, 1,
554 if (NPVARIANT_IS_INT32(rval
) && NPVARIANT_TO_INT32(rval
) == 4) {
555 printf ("Default function call SUCCEEDED!\n");
557 printf ("Default function call FAILED!\n");
560 NPN_ReleaseVariantValue(&barval
);
561 NPN_ReleaseVariantValue(&rval
);
565 n
= NPN_GetStringIdentifier("prompt");
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
);
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");
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
);
610 NPN_ReleaseObject(sWindowObj
);
611 if (m_pScriptableObject
)
612 NPN_ReleaseObject(m_pScriptableObject
);
618 static LRESULT CALLBACK
PluginWinProc(HWND
, UINT
, WPARAM
, LPARAM
);
619 static WNDPROC lpOldProc
= NULL
;
622 NPBool
CPlugin::init(NPWindow
* pNPWindow
)
624 if(pNPWindow
== NULL
)
628 m_hWnd
= (HWND
)pNPWindow
->window
;
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);
641 m_Window
= pNPWindow
;
643 m_bInitialized
= true;
651 SubclassWindow(m_hWnd
, lpOldProc
);
655 m_bInitialized
= false;
658 NPBool
CPlugin::isInitialized()
660 return m_bInitialized
;
663 int16_t CPlugin::handleEvent(void* event
)
666 NPEvent
* ev
= (NPEvent
*)event
;
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
);
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
);
685 InvalidateRect(m_hWnd
, NULL
, true);
686 UpdateWindow(m_hWnd
);
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
, "");
707 InvalidateRect(m_hWnd
, NULL
, true);
708 UpdateWindow(m_hWnd
);
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
));
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
;
738 static LRESULT CALLBACK
PluginWinProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
743 // draw a frame and display the string
745 HDC hdc
= BeginPaint(hWnd
, &ps
);
747 GetClientRect(hWnd
, &rc
);
748 FrameRect(hdc
, &rc
, GetStockBrush(BLACK_BRUSH
));
749 CPlugin
* p
= (CPlugin
*)GetWindowLong(hWnd
, GWL_USERDATA
);
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
);
765 return DefWindowProc(hWnd
, msg
, wParam
, lParam
);