Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / modules / plugin / sdk / samples / testevents / npevents.cpp
blobfa4e729b2f0cfdd78254533eb00073f9da26343b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
16 * The Original Code is mozilla.org Code.
18 * The Initial Developer of the Original Code is
19 * Netscape Communications Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 1998
21 * the Initial Developer. All Rights Reserved.
23 * Contributor(s):
24 * Neil Hodgson <nhodgson@bigpond.net.au>
25 * Mark Hammond <MarkH@ActiveState.com>
27 * Alternatively, the contents of this file may be used under the terms of
28 * either the GNU General Public License Version 2 or later (the "GPL"), or
29 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
41 // npevents.cxx
42 // Demonstration plugin for Mozilla that handles events, focus and keystrokes.
43 // See README.txt for more details.
45 #include "nsplugin.h"
46 #include "nsIServiceManager.h"
47 #include "nsISupports.h"
48 #include "nsIFactory.h"
49 #include "nsIGenericFactory.h"
50 #include "nsString.h"
51 #include "nsIAllocator.h"
53 #include "nsIEventsPluginInstance.h"
55 #include <stdio.h>
56 #include <string.h>
58 #if defined (XP_WIN)
60 #include <windows.h>
62 #elif defined (XP_UNIX)
64 #include <gdk/gdkprivate.h>
65 #include <gtk/gtk.h>
66 #include <gdk/gdkkeysyms.h>
67 #include <gtkmozbox.h>
69 #endif
71 #define EVENTSPLUGIN_DEBUG
73 /**
74 * {CB2EF72A-856A-4818-8E72-3439395E335F}
76 #define NS_EVENTSAMPLEPLUGIN_CID { 0xcb2ef72a, 0x856a, 0x4818, { 0x8e, 0x72, 0x34, 0x39, 0x39, 0x5e, 0x33, 0x5f } }
78 #if defined(XP_UNIX)
79 typedef struct _PlatformInstance {
80 GtkWidget *moz_box;
81 Display * display;
82 uint32 x, y;
83 uint32 width, height;
85 PlatformInstance;
87 typedef GtkWidget* WinID;
89 #endif // XP_UNIX
91 #if defined(XP_WIN)
92 typedef struct _PlatformInstance
94 WNDPROC fOldChildWindowProc; // The original WNDPROC of the edit control.
95 WNDPROC fParentWindowProc; // The Mozilla WNDPROC for main (parent) window.
96 } PlatformInstance;
98 // Unique string for associating a pointer with our WNDPROC
99 static const char* gInstanceLookupString = "instance->pdata";
101 typedef HWND WinID;
103 #endif // XP_WIN
105 static NS_DEFINE_CID(kPluginManagerCID, NS_PLUGINMANAGER_CID);
106 static NS_DEFINE_CID(kEventsPluginCID, NS_EVENTSAMPLEPLUGIN_CID);
108 const char *kPluginName = "Events Sample Plug-in";
109 const char *kPluginDescription = "Sample plugin that demonstrates events, focus and keystrokes.";
110 #define PLUGIN_MIME_TYPE "application/x-events-sample-plugin"
112 static const char* kMimeTypes[] = {
113 PLUGIN_MIME_TYPE
116 static const char* kMimeDescriptions[] = {
117 "Event Sample Plug-in"
120 static const char* kFileExtensions[] = {
121 "smpev"
124 static const PRInt32 kNumMimeTypes = sizeof(kMimeTypes) / sizeof(*kMimeTypes);
126 ////////////////////////////////////////////////////////////////////////////////
127 // EventsPluginInstance represents an instance of the EventsPlugin class.
129 class EventsPluginInstance :
130 public nsIPluginInstance,
131 public nsIEventsSampleInstance {
132 public:
133 ////////////////////////////////////////////////////////////////////////////
134 // for implementing a generic module
135 static NS_METHOD
136 Create(nsISupports* aOuter, REFNSIID aIID, void** aResult);
138 static NS_METHOD
139 RegisterSelf(nsIComponentManager* aCompMgr,
140 nsIFile* aPath,
141 const char* aRegistryLocation,
142 const char* aComponentType,
143 const nsModuleComponentInfo *info);
145 static NS_METHOD
146 UnregisterSelf(nsIComponentManager* aCompMgr,
147 nsIFile* aPath,
148 const char* aRegistryLocation,
149 const nsModuleComponentInfo *info);
152 NS_DECL_ISUPPORTS
153 NS_DECL_NSIEVENTSSAMPLEINSTANCE
155 ////////////////////////////////////////////////////////////////////////////
156 // from nsIEventHandler:
158 NS_IMETHOD HandleEvent(nsPluginEvent* event, PRBool* handled);
160 ////////////////////////////////////////////////////////////////////////////
161 // from nsIPluginInstance:
163 NS_IMETHOD Initialize(nsIPluginInstancePeer *peer);
165 // Required backpointer to the peer.
166 NS_IMETHOD GetPeer(nsIPluginInstancePeer **result);
168 NS_IMETHOD Start(void);
170 NS_IMETHOD Stop(void);
172 NS_IMETHOD Destroy(void);
174 NS_IMETHOD SetWindow(nsPluginWindow* window);
176 NS_IMETHOD NewStream(nsIPluginStreamListener** listener);
178 NS_IMETHOD Print(nsPluginPrint* platformPrint);
180 NS_IMETHOD GetValue(nsPluginInstanceVariable variable, void *value);
182 ////////////////////////////////////////////////////////////////////////////
183 // EventsPluginInstance specific methods:
185 EventsPluginInstance();
186 virtual ~EventsPluginInstance();
188 void PlatformNew(void);
189 nsresult PlatformDestroy(void);
190 void PlatformResetWindow();
191 PRInt16 PlatformHandleEvent(nsPluginEvent* event);
192 void PlatformResizeWindow(nsPluginWindow* window);
193 nsresult PlatformCreateWindow(nsPluginWindow* window);
195 void SetMode(nsPluginMode mode) { fMode = mode; }
197 protected:
198 ////////////////////////////////////////////////////////////////////////////
199 // Implementation methods
200 nsresult DoSetWindow(nsPluginWindow* window);
202 // Data
203 nsCOMPtr<nsIPluginInstancePeer> fPeer;
204 nsPluginWindow *fWindow; // no nsCOMPtr as not an interface!
205 nsPluginMode fMode;
206 PlatformInstance fPlatform;
208 WinID wMain; // The window created by Mozilla for us.
209 WinID wChild; // The window we create as a child of the nsWindow.
211 ////////////////////////////////////////////////////////////////////////////
212 // Platform specific helpers
213 #ifdef XP_WIN
214 static LRESULT CALLBACK WndProcChild(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
215 #endif
218 ////////////////////////////////////////////////////////////////////////////////
219 // EventsPluginStream represents the stream used by EvMozs
220 // to receive data from the browser.
222 class EventsPluginStreamListener : public nsIPluginStreamListener {
223 public:
225 NS_DECL_ISUPPORTS
227 ////////////////////////////////////////////////////////////////////////////
228 // from nsIPluginStreamListener:
230 // Notify the observer that the URL has started to load. This method is
231 // called only once, at the beginning of a URL load.
232 NS_IMETHOD OnStartBinding(nsIPluginStreamInfo* pluginInfo);
234 // Notify the client that data is available in the input stream. This method is
235 // called whenver data is written into the input stream by the networking library.
236 NS_IMETHOD OnDataAvailable(nsIPluginStreamInfo* pluginInfo,
237 nsIInputStream* input,
238 PRUint32 length);
240 NS_IMETHOD OnFileAvailable(nsIPluginStreamInfo* pluginInfo, const char* fileName);
242 // Notify the observer that the URL has finished loading. This method is
243 // called once when the networking library has finished processing the
244 // URL transaction initiatied via the nsINetService::Open(...) call.
245 NS_IMETHOD OnStopBinding(nsIPluginStreamInfo* pluginInfo, nsresult status);
247 NS_IMETHOD OnNotify(const char* url, nsresult status);
249 NS_IMETHOD GetStreamType(nsPluginStreamType *result);
251 ////////////////////////////////////////////////////////////////////////////
252 // EventsPluginStreamListener specific methods:
254 EventsPluginStreamListener(EventsPluginInstance *inst_, const char* url);
255 virtual ~EventsPluginStreamListener(void);
257 protected:
258 const char* fMessageName;
259 EventsPluginInstance *inst;
262 // The module loader information.
263 static const nsModuleComponentInfo gComponentInfo[] = {
264 { "Events Sample Plugin",
265 NS_EVENTSAMPLEPLUGIN_CID,
266 NS_INLINE_PLUGIN_CONTRACTID_PREFIX PLUGIN_MIME_TYPE,
267 EventsPluginInstance::Create,
268 EventsPluginInstance::RegisterSelf,
269 EventsPluginInstance::UnregisterSelf },
272 NS_IMPL_NSGETMODULE(EventsPlugin, gComponentInfo)
275 ////////////////////////////////////////////////////////////////////////////////
276 // EventsPluginInstance static Methods
277 ////////////////////////////////////////////////////////////////////////////////
279 NS_METHOD
280 EventsPluginInstance::Create(nsISupports* aOuter, REFNSIID aIID, void** aResult)
282 NS_PRECONDITION(aOuter == nsnull, "no aggregation");
283 if (aOuter)
284 return NS_ERROR_NO_AGGREGATION;
286 EventsPluginInstance* plugin = new EventsPluginInstance();
287 if (! plugin)
288 return NS_ERROR_OUT_OF_MEMORY;
290 nsresult rv;
291 NS_ADDREF(plugin);
292 rv = plugin->QueryInterface(aIID, aResult);
293 NS_RELEASE(plugin);
294 return rv;
297 NS_METHOD
298 EventsPluginInstance::RegisterSelf(nsIComponentManager* aCompMgr,
299 nsIFile* aPath,
300 const char* aRegistryLocation,
301 const char* aComponentType,
302 const nsModuleComponentInfo *info)
304 nsresult rv;
306 nsIServiceManager *svcMgr;
307 rv = aCompMgr->QueryInterface(NS_GET_IID(nsIServiceManager),
308 reinterpret_cast<void**>(&svcMgr));
309 if (NS_FAILED(rv))
310 return rv;
312 nsIPluginManager* pm;
313 rv = svcMgr->GetService(kPluginManagerCID,
314 NS_GET_IID(nsIPluginManager),
315 reinterpret_cast<void**>(&pm));
316 NS_RELEASE(svcMgr);
318 if (NS_SUCCEEDED(rv)) {
319 rv = pm->RegisterPlugin(kEventsPluginCID,
320 kPluginName,
321 kPluginDescription,
322 kMimeTypes,
323 kMimeDescriptions,
324 kFileExtensions,
325 kNumMimeTypes);
327 NS_RELEASE(pm);
330 return rv;
334 NS_METHOD
335 EventsPluginInstance::UnregisterSelf(nsIComponentManager* aCompMgr,
336 nsIFile* aPath,
337 const char* aRegistryLocation,
338 const nsModuleComponentInfo *info)
340 nsresult rv;
342 nsIServiceManager *svcMgr;
343 rv = aCompMgr->QueryInterface(NS_GET_IID(nsIServiceManager),
344 reinterpret_cast<void**>(&svcMgr));
345 if (NS_FAILED(rv))
346 return rv;
348 nsIPluginManager* pm;
349 rv = svcMgr->GetService(kPluginManagerCID,
350 NS_GET_IID(nsIPluginManager),
351 reinterpret_cast<void**>(&pm));
352 NS_RELEASE(svcMgr);
354 if (NS_SUCCEEDED(rv)) {
355 rv = pm->UnregisterPlugin(kEventsPluginCID);
356 NS_RELEASE(pm);
359 return rv;
362 ////////////////////////////////////////////////////////////////////////////////
363 // EventsPluginInstance Methods
364 ////////////////////////////////////////////////////////////////////////////////
366 // These macros produce simple version of QueryInterface and AddRef.
367 // See the nsISupports.h header file for details.
369 NS_IMPL_ISUPPORTS2(EventsPluginInstance, nsIPluginInstance, nsIEventsSampleInstance)
371 EventsPluginInstance::EventsPluginInstance() :
372 fPeer(NULL), fWindow(NULL), fMode(nsPluginMode_Embedded)
374 wChild = 0;
377 EventsPluginInstance::~EventsPluginInstance(void) {
381 NS_METHOD EventsPluginInstance::Initialize(nsIPluginInstancePeer *peer) {
382 #ifdef EVENTSPLUGIN_DEBUG
383 printf("EventsPluginInstance::Initialize\n");
384 #endif
386 NS_ASSERTION(peer != NULL, "null peer");
388 fPeer = peer;
389 nsCOMPtr<nsIPluginTagInfo> taginfo;
390 const char* const* names = nsnull;
391 const char* const* values = nsnull;
392 PRUint16 count = 0;
393 nsresult result;
395 peer->AddRef();
396 result = peer->GetMode(&fMode);
397 if (NS_FAILED(result)) return result;
399 taginfo = do_QueryInterface(peer, &result);
400 if (NS_SUCCEEDED(result)) {
401 taginfo->GetAttributes(count, names, values);
404 PlatformNew(); /* Call Platform-specific initializations */
405 return NS_OK;
408 NS_METHOD EventsPluginInstance::GetPeer(nsIPluginInstancePeer* *result) {
409 #ifdef EVENTSPLUGIN_DEBUG
410 printf("EventsPluginInstance::GetPeer\n");
411 #endif
413 *result = fPeer;
414 NS_IF_ADDREF(*result);
415 return NS_OK;
418 NS_METHOD EventsPluginInstance::Start(void) {
419 #ifdef EVENTSPLUGIN_DEBUG
420 printf("EventsPluginInstance::Start\n");
421 #endif
423 return NS_OK;
426 NS_METHOD EventsPluginInstance::Stop(void) {
427 #ifdef EVENTSPLUGIN_DEBUG
428 printf("EventsPluginInstance::Stop\n");
429 #endif
431 return NS_OK;
434 NS_METHOD EventsPluginInstance::Destroy(void) {
435 #ifdef EVENTSPLUGIN_DEBUG
436 printf("EventsPluginInstance::Destroy\n");
437 #endif
439 PlatformDestroy(); // Perform platform specific cleanup
440 return NS_OK;
443 /*+++++++++++++++++++++++++++++++++++++++++++++++++
444 * NPP_SetWindow:
445 * Sets the window in which a plug-in draws, and returns an error value.
447 * NPP_SetWindow informs the plug-in instance specified by instance of the
448 * the window denoted by window in which the instance draws. This nsPluginWindow
449 * pointer is valid for the life of the instance, or until NPP_SetWindow is called
450 * again with a different value. Subsequent calls to NPP_SetWindow for a given
451 * instance typically indicate that the window has been resized. If either window
452 * or window->window are NULL, the plug-in must not perform any additional
453 * graphics operations on the window and should free any resources associated
454 * with the window.
455 +++++++++++++++++++++++++++++++++++++++++++++++++*/
456 NS_METHOD EventsPluginInstance::SetWindow(nsPluginWindow* window) {
457 #ifdef EVENTSPLUGIN_DEBUG
458 printf("EventsPluginInstance::SetWindow\n");
459 #endif
461 nsresult result;
462 result = DoSetWindow(window);
463 fWindow = window;
464 return result;
467 nsresult EventsPluginInstance::DoSetWindow(nsPluginWindow* window) {
469 * PLUGIN DEVELOPERS:
470 * Before setting window to point to the
471 * new window, you may wish to compare the new window
472 * info to the previous window (if any) to note window
473 * size changes, etc.
475 nsresult result = NS_OK;
476 if ( fWindow != NULL ) {
477 // If we already have a window, clean it up
478 // before working with the new window
479 if ( window && window->window && wMain == (WinID)window->window ) {
480 /* The new window is the same as the old one. Exit now. */
481 PlatformResizeWindow(window);
482 return NS_OK;
484 // Otherwise, just reset the window ready for the new one.
485 PlatformResetWindow();
487 else if ( (window == NULL) || ( window->window == NULL ) ) {
488 /* We can just get out of here if there is no current
489 * window and there is no new window to use. */
490 return NS_OK;
492 if (window && window->window) {
493 // Remember our main parent window.
494 wMain = (WinID)window->window;
495 // And create the child window.
496 result = PlatformCreateWindow(window);
498 return result;
501 NS_METHOD EventsPluginInstance::NewStream(nsIPluginStreamListener** listener) {
502 #ifdef EVENTSPLUGIN_DEBUG
503 printf("EventsPluginInstance::NewStream\n");
504 #endif
506 if (listener != NULL) {
507 EventsPluginStreamListener* sl =
508 new EventsPluginStreamListener(this, "http://www.mozilla.org");
509 if (!sl)
510 return NS_ERROR_UNEXPECTED;
511 sl->AddRef();
512 *listener = sl;
515 return NS_OK;
518 NS_METHOD EventsPluginInstance::Print(nsPluginPrint* printInfo) {
519 #ifdef EVENTSPLUGIN_DEBUG
520 printf("EventsPluginInstance::Print\n");
521 #endif
523 if (printInfo == NULL)
524 return NS_ERROR_FAILURE;
526 if (printInfo->mode == nsPluginMode_Full) {
528 * PLUGIN DEVELOPERS:
529 * If your plugin would like to take over
530 * printing completely when it is in full-screen mode,
531 * set printInfo->pluginPrinted to TRUE and print your
532 * plugin as you see fit. If your plugin wants Netscape
533 * to handle printing in this case, set
534 * printInfo->pluginPrinted to FALSE (the default) and
535 * do nothing. If you do want to handle printing
536 * yourself, printOne is true if the print button
537 * (as opposed to the print menu) was clicked.
538 * On the Macintosh, platformPrint is a THPrint; on
539 * Windows, platformPrint is a structure
540 * (defined in npapi.h) containing the printer name, port,
541 * etc.
544 /* Do the default*/
545 printInfo->print.fullPrint.pluginPrinted = PR_FALSE;
546 } else { /* If not fullscreen, we must be embedded */
548 * PLUGIN DEVELOPERS:
549 * If your plugin is embedded, or is full-screen
550 * but you returned false in pluginPrinted above, NPP_Print
551 * will be called with mode == nsPluginMode_Embedded. The nsPluginWindow
552 * in the printInfo gives the location and dimensions of
553 * the embedded plugin on the printed page. On the
554 * Macintosh, platformPrint is the printer port; on
555 * Windows, platformPrint is the handle to the printing
556 * device context.
559 return NS_OK;
562 /*+++++++++++++++++++++++++++++++++++++++++++++++++
563 * NPP_HandleEvent:
564 * Mac-only, but stub must be present for Windows
565 * Delivers a platform-specific event to the instance.
567 * On the Macintosh, event is a pointer to a standard Macintosh EventRecord.
568 * All standard event types are passed to the instance as appropriate. In general,
569 * return TRUE if you handle the event and FALSE if you ignore the event.
570 +++++++++++++++++++++++++++++++++++++++++++++++++*/
572 NS_METHOD EventsPluginInstance::HandleEvent(nsPluginEvent* event, PRBool* handled) {
573 #ifdef EVENTSPLUGIN_DEBUG
574 printf("EventsPluginInstance::HandleEvent\n");
575 #endif
577 *handled = (PRBool)PlatformHandleEvent(event);
578 return NS_OK;
581 NS_METHOD EventsPluginInstance::GetValue(nsPluginInstanceVariable /*variable*/, void * /*value*/) {
582 #ifdef EVENTSPLUGIN_DEBUG
583 printf("EventsPluginInstance::GetValue\n");
584 #endif
586 return NS_ERROR_FAILURE;
589 ////////////////////////////////////////////////////////////////////////////////
590 // EventsPluginStreamListener Methods
591 ////////////////////////////////////////////////////////////////////////////////
593 EventsPluginStreamListener::EventsPluginStreamListener(EventsPluginInstance* inst_,
594 const char* msgName)
595 : fMessageName(msgName), inst(inst_) {
596 #ifdef EVENTSPLUGIN_DEBUG
597 printf("EventsPluginStreamListener: EventsPluginStreamListener for %s\n", fMessageName);
598 #endif
601 EventsPluginStreamListener::~EventsPluginStreamListener(void) {
604 // This macro produces a simple version of QueryInterface, AddRef and Release.
605 // See the nsISupports.h header file for details.
607 NS_IMPL_ISUPPORTS1(EventsPluginStreamListener, nsIPluginStreamListener)
609 NS_METHOD EventsPluginStreamListener::OnStartBinding(nsIPluginStreamInfo * /*pluginInfo*/) {
610 #ifdef EVENTSPLUGIN_DEBUG
611 printf("EventsPluginStreamListener::OnStartBinding\n");
612 printf("EventsPluginStreamListener: Opening plugin stream for %s\n", fMessageName);
613 #endif
614 return NS_OK;
617 NS_METHOD EventsPluginStreamListener::OnDataAvailable(
618 nsIPluginStreamInfo * /*pluginInfo*/,
619 nsIInputStream* input,
620 PRUint32 length) {
622 #ifdef EVENTSPLUGIN_DEBUG
623 printf("EventsPluginStreamListener::OnDataAvailable\n");
624 #endif
626 char* buffer = new char[length];
627 if (buffer) {
628 PRUint32 amountRead = 0;
629 nsresult rslt = input->Read(buffer, length, &amountRead);
630 if (rslt == NS_OK) {
631 char msg[256];
632 sprintf(msg, "### Received %d bytes for %s\n", length, fMessageName);
634 delete buffer;
636 return NS_OK;
639 NS_METHOD EventsPluginStreamListener::OnFileAvailable(
640 nsIPluginStreamInfo * /*pluginInfo*/,
641 const char* fileName) {
643 #ifdef EVENTSPLUGIN_DEBUG
644 printf("EventsPluginStreamListener::OnFileAvailable\n");
645 #endif
647 char msg[256];
648 sprintf(msg, "### File available for %s: %s\n", fMessageName, fileName);
649 return NS_OK;
652 NS_METHOD EventsPluginStreamListener::OnStopBinding(
653 nsIPluginStreamInfo * /*pluginInfo*/,
654 nsresult /*status*/) {
656 #ifdef EVENTSPLUGIN_DEBUG
657 printf("EventsPluginStreamListener::OnStopBinding\n");
658 #endif
660 char msg[256];
661 sprintf(msg, "### Closing plugin stream for %s\n", fMessageName);
662 return NS_OK;
665 NS_METHOD EventsPluginStreamListener::OnNotify(const char * /*url*/, nsresult /*status*/) {
666 #ifdef EVENTSPLUGIN_DEBUG
667 printf("EventsPluginStreamListener::OnNotify\n");
668 #endif
670 return NS_OK;
673 NS_METHOD EventsPluginStreamListener::GetStreamType(nsPluginStreamType *result) {
674 #ifdef EVENTSPLUGIN_DEBUG
675 printf("EventsPluginStreamListener::GetStreamType\n");
676 #endif
678 *result = nsPluginStreamType_Normal;
679 return NS_OK;
682 ///////////////////////////////////////////////////////////////////////////////
683 // Platform-Specific Implemenations
685 // UNIX Implementations
687 #ifdef XP_UNIX
689 void EventsPluginInstance::PlatformNew(void) {
690 fPlatform.moz_box = 0;
693 nsresult EventsPluginInstance::PlatformDestroy(void) {
694 // the mozbox will be destroyed by the native destruction of the
695 // widget's parent.
696 return NS_OK;
699 void EventsPluginInstance::PlatformResetWindow() {
700 #ifdef EVENTSPLUGIN_DEBUG
701 printf("EventsPluginInstance::PlatformResetWindow\n");
702 #endif
703 fPlatform.moz_box = 0;
706 nsresult EventsPluginInstance::PlatformCreateWindow(nsPluginWindow* window) {
707 #ifdef EVENTSPLUGIN_DEBUG
708 printf("EventsPluginInstance::PlatformCreateWindow %lx\n", (long)window);
709 #endif
711 Window x_window = (Window)window->window;
712 GdkWindow *gdk_window = (GdkWindow *)gdk_xid_table_lookup(x_window);
713 if (!gdk_window) {
714 fprintf(stderr, "NO WINDOW!!!\n");
715 return NS_ERROR_FAILURE;
717 fPlatform.moz_box = gtk_mozbox_new(gdk_window);
719 wChild = gtk_entry_new();
720 gtk_container_add(GTK_CONTAINER(fPlatform.moz_box), wChild);
721 gtk_widget_show_all(fPlatform.moz_box);
722 return NS_OK;
725 void EventsPluginInstance::PlatformResizeWindow(nsPluginWindow* window) {
726 NS_PRECONDITION(wChild, "Have no wChild!");
727 #ifdef EVENTSPLUGIN_DEBUG
728 printf("EventsPluginInstance::PlatformResizeWindow to size (%d,%d)\n", window->width, window->height);
729 #endif
730 // Mozilla has already sized the mozbox - we just need to handle the child.
731 gtk_widget_set_usize(wChild, window->width, window->height);
734 int16 EventsPluginInstance::PlatformHandleEvent(nsPluginEvent * /*event*/) {
735 /* UNIX Plugins do not use HandleEvent */
736 return 0;
739 /* attribute string text; */
740 NS_IMETHODIMP EventsPluginInstance::GetVal(char * *aText) {
741 #ifdef EVENTSPLUGIN_DEBUG
742 printf("EventsPluginInstance::GetVal\n");
743 #endif
744 char *text = gtk_entry_get_text(GTK_ENTRY(wChild));
745 *aText = reinterpret_cast<char*>(nsAllocator::Clone(text, strlen(text) + 1));
746 return (*aText) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
749 NS_IMETHODIMP EventsPluginInstance::SetVal(const char * aText) {
750 #ifdef EVENTSPLUGIN_DEBUG
751 printf("EventsPluginInstance::SetVal\n");
752 #endif
753 gtk_entry_set_text(GTK_ENTRY(wChild), aText);
754 return NS_OK;
756 #endif /* XP_UNIX */
758 // Windows Implementations
760 #if defined(XP_WIN)
762 void EventsPluginInstance::PlatformNew(void) {
763 // Nothing to do!
766 nsresult EventsPluginInstance::PlatformDestroy(void) {
767 wChild = 0;
768 return NS_OK;
771 nsresult EventsPluginInstance::PlatformCreateWindow(nsPluginWindow* window) {
772 // Remember parent wndproc.
773 fPlatform.fParentWindowProc = (WNDPROC)::GetWindowLong(wMain, GWL_WNDPROC);
774 NS_ABORT_IF_FALSE(fPlatform.fParentWindowProc!=NULL, "Couldn't get the parent WNDPROC");
776 // Create the child window that fills our nsWindow
777 RECT rc;
778 ::GetWindowRect(wMain, &rc);
780 wChild = ::CreateWindow("Edit", // class - standard Windows edit control.
781 "", // title
782 WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL, // style
783 0, 0, rc.right-rc.left, rc.bottom-rc.top,
784 wMain, // parent
785 (HMENU)1111, // window ID
786 0, // instance
787 NULL); //creation data.
788 NS_ABORT_IF_FALSE(wChild != NULL, "Failed to create the child window!");
789 if (!wChild)
790 return NS_ERROR_FAILURE;
791 // Stash away our "this" pointer so our WNDPROC can talk to us.
792 ::SetProp(wChild, gInstanceLookupString, (HANDLE)this);
793 fPlatform.fOldChildWindowProc =
794 (WNDPROC)::SetWindowLong( wChild,
795 GWL_WNDPROC,
796 (LONG)EventsPluginInstance::WndProcChild);
797 return NS_OK;
800 int16 EventsPluginInstance::PlatformHandleEvent(nsPluginEvent * /*event*/) {
801 return NS_OK;
804 void EventsPluginInstance::PlatformResetWindow() {
805 #ifdef EVENTSPLUGIN_DEBUG
806 printf("EventsPluginInstance::PlatformResetWindow\n");
807 #endif
808 fPlatform.fParentWindowProc = NULL;
809 ::SetWindowLong(wChild, GWL_WNDPROC, (LONG)fPlatform.fOldChildWindowProc);
810 fPlatform.fOldChildWindowProc = NULL;
811 wChild = NULL;
812 wMain = NULL;
815 void EventsPluginInstance::PlatformResizeWindow(nsPluginWindow* window) {
816 #ifdef EVENTSPLUGIN_DEBUG
817 printf("EventsPluginInstance::PlatformResizeWindow with new size (%d,%d)\n", window->width, window->height);
818 #endif
819 RECT rc;
820 NS_PRECONDITION(wMain != nsnull, "Must have a valid wMain to resize");
821 ::GetClientRect(wMain, &rc);
822 ::SetWindowPos(wChild, 0, rc.left, rc.top,
823 rc.right - rc.left, rc.bottom - rc.top, SWP_NOZORDER | SWP_NOACTIVATE);
826 /* attribute string text; */
827 NS_IMETHODIMP EventsPluginInstance::GetVal(char * *aText) {
828 #ifdef EVENTSPLUGIN_DEBUG
829 printf("EventsPluginInstance::GetVal\n");
830 #endif
831 static char *empty = "";
832 char *value = empty;
833 char buffer[256];
834 if (wChild) {
835 GetWindowText(wChild, buffer, sizeof(buffer)/sizeof(buffer[0]));
836 value = buffer;
838 *aText = reinterpret_cast<char*>(nsAllocator::Clone(value, strlen(value) + 1));
839 return (*aText) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
842 NS_IMETHODIMP EventsPluginInstance::SetVal(const char * aText) {
843 #ifdef EVENTSPLUGIN_DEBUG
844 printf("EventsPluginInstance::SetVal\n");
845 #endif
846 NS_ABORT_IF_FALSE(wChild != 0, "Don't have a window!");
847 SetWindowText(wChild, aText);
848 return NS_OK;
851 // This is the WndProc for our child window (the edit control)
852 LRESULT CALLBACK EventsPluginInstance::WndProcChild(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
853 EventsPluginInstance* inst = (EventsPluginInstance*) GetProp(hWnd, gInstanceLookupString);
854 NS_ABORT_IF_FALSE(inst, "Could not get the inst from the Window!!");
855 switch (Msg) {
856 // NOTE: We DON'T pass on DBLCLK messages, as both Scintilla and
857 // Mozilla have their own special logic, and they step on each other.
858 // (causing our child to see a double-click as a triple-click)
859 case WM_KEYDOWN:
860 case WM_SYSKEYDOWN:
861 case WM_KEYUP:
862 case WM_SYSKEYUP:
863 case WM_CHAR:
864 case WM_SYSCHAR:
865 case WM_LBUTTONDOWN:
866 case WM_LBUTTONUP:
867 case WM_MBUTTONDOWN:
868 case WM_MBUTTONUP:
869 case WM_RBUTTONDOWN:
870 case WM_RBUTTONUP:
871 case WM_MOUSEMOVE:
872 // pretend the message happened in our parent.
873 return ::CallWindowProc(inst->fPlatform.fParentWindowProc, (HWND)inst->wMain, Msg, wParam, lParam);
874 default:
875 // let our child's default handle it.
876 return ::CallWindowProc(inst->fPlatform.fOldChildWindowProc, hWnd, Msg, wParam, lParam);
878 /* not reached */
879 NS_ABORT_IF_FALSE(0, "not reached!");
883 #endif /* XP_WIN */