RetroZilla/modules/plugin/samples/testevents/npevents.cpp
2015-10-20 23:03:22 -04:00

884 lines
27 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org Code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Neil Hodgson <nhodgson@bigpond.net.au>
* Mark Hammond <MarkH@ActiveState.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
// npevents.cxx
// Demonstration plugin for Mozilla that handles events, focus and keystrokes.
// See README.txt for more details.
#include "nsplugin.h"
#include "nsIServiceManager.h"
#include "nsISupports.h"
#include "nsIFactory.h"
#include "nsIGenericFactory.h"
#include "nsString.h"
#include "nsIAllocator.h"
#include "nsIEventsPluginInstance.h"
#include <stdio.h>
#include <string.h>
#if defined (XP_WIN)
#include <windows.h>
#elif defined (XP_UNIX)
#include <gdk/gdkprivate.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <gtkmozbox.h>
#endif
#define EVENTSPLUGIN_DEBUG
/**
* {CB2EF72A-856A-4818-8E72-3439395E335F}
*/
#define NS_EVENTSAMPLEPLUGIN_CID { 0xcb2ef72a, 0x856a, 0x4818, { 0x8e, 0x72, 0x34, 0x39, 0x39, 0x5e, 0x33, 0x5f } }
#if defined(XP_UNIX)
typedef struct _PlatformInstance {
GtkWidget *moz_box;
Display * display;
uint32 x, y;
uint32 width, height;
}
PlatformInstance;
typedef GtkWidget* WinID;
#endif // XP_UNIX
#if defined(XP_WIN)
typedef struct _PlatformInstance
{
WNDPROC fOldChildWindowProc; // The original WNDPROC of the edit control.
WNDPROC fParentWindowProc; // The Mozilla WNDPROC for main (parent) window.
} PlatformInstance;
// Unique string for associating a pointer with our WNDPROC
static const char* gInstanceLookupString = "instance->pdata";
typedef HWND WinID;
#endif // XP_WIN
static NS_DEFINE_CID(kPluginManagerCID, NS_PLUGINMANAGER_CID);
static NS_DEFINE_CID(kEventsPluginCID, NS_EVENTSAMPLEPLUGIN_CID);
const char *kPluginName = "Events Sample Plug-in";
const char *kPluginDescription = "Sample plugin that demonstrates events, focus and keystrokes.";
#define PLUGIN_MIME_TYPE "application/x-events-sample-plugin"
static const char* kMimeTypes[] = {
PLUGIN_MIME_TYPE
};
static const char* kMimeDescriptions[] = {
"Event Sample Plug-in"
};
static const char* kFileExtensions[] = {
"smpev"
};
static const PRInt32 kNumMimeTypes = sizeof(kMimeTypes) / sizeof(*kMimeTypes);
////////////////////////////////////////////////////////////////////////////////
// EventsPluginInstance represents an instance of the EventsPlugin class.
class EventsPluginInstance :
public nsIPluginInstance,
public nsIEventsSampleInstance {
public:
////////////////////////////////////////////////////////////////////////////
// for implementing a generic module
static NS_METHOD
Create(nsISupports* aOuter, REFNSIID aIID, void** aResult);
static NS_METHOD
RegisterSelf(nsIComponentManager* aCompMgr,
nsIFile* aPath,
const char* aRegistryLocation,
const char* aComponentType,
const nsModuleComponentInfo *info);
static NS_METHOD
UnregisterSelf(nsIComponentManager* aCompMgr,
nsIFile* aPath,
const char* aRegistryLocation,
const nsModuleComponentInfo *info);
NS_DECL_ISUPPORTS
NS_DECL_NSIEVENTSSAMPLEINSTANCE
////////////////////////////////////////////////////////////////////////////
// from nsIEventHandler:
NS_IMETHOD HandleEvent(nsPluginEvent* event, PRBool* handled);
////////////////////////////////////////////////////////////////////////////
// from nsIPluginInstance:
NS_IMETHOD Initialize(nsIPluginInstancePeer *peer);
// Required backpointer to the peer.
NS_IMETHOD GetPeer(nsIPluginInstancePeer **result);
NS_IMETHOD Start(void);
NS_IMETHOD Stop(void);
NS_IMETHOD Destroy(void);
NS_IMETHOD SetWindow(nsPluginWindow* window);
NS_IMETHOD NewStream(nsIPluginStreamListener** listener);
NS_IMETHOD Print(nsPluginPrint* platformPrint);
NS_IMETHOD GetValue(nsPluginInstanceVariable variable, void *value);
////////////////////////////////////////////////////////////////////////////
// EventsPluginInstance specific methods:
EventsPluginInstance();
virtual ~EventsPluginInstance();
void PlatformNew(void);
nsresult PlatformDestroy(void);
void PlatformResetWindow();
PRInt16 PlatformHandleEvent(nsPluginEvent* event);
void PlatformResizeWindow(nsPluginWindow* window);
nsresult PlatformCreateWindow(nsPluginWindow* window);
void SetMode(nsPluginMode mode) { fMode = mode; }
protected:
////////////////////////////////////////////////////////////////////////////
// Implementation methods
nsresult DoSetWindow(nsPluginWindow* window);
// Data
nsCOMPtr<nsIPluginInstancePeer> fPeer;
nsPluginWindow *fWindow; // no nsCOMPtr as not an interface!
nsPluginMode fMode;
PlatformInstance fPlatform;
WinID wMain; // The window created by Mozilla for us.
WinID wChild; // The window we create as a child of the nsWindow.
////////////////////////////////////////////////////////////////////////////
// Platform specific helpers
#ifdef XP_WIN
static LRESULT CALLBACK WndProcChild(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
#endif
};
////////////////////////////////////////////////////////////////////////////////
// EventsPluginStream represents the stream used by EvMozs
// to receive data from the browser.
class EventsPluginStreamListener : public nsIPluginStreamListener {
public:
NS_DECL_ISUPPORTS
////////////////////////////////////////////////////////////////////////////
// from nsIPluginStreamListener:
// Notify the observer that the URL has started to load. This method is
// called only once, at the beginning of a URL load.
NS_IMETHOD OnStartBinding(nsIPluginStreamInfo* pluginInfo);
// Notify the client that data is available in the input stream. This method is
// called whenver data is written into the input stream by the networking library.
NS_IMETHOD OnDataAvailable(nsIPluginStreamInfo* pluginInfo,
nsIInputStream* input,
PRUint32 length);
NS_IMETHOD OnFileAvailable(nsIPluginStreamInfo* pluginInfo, const char* fileName);
// Notify the observer that the URL has finished loading. This method is
// called once when the networking library has finished processing the
// URL transaction initiatied via the nsINetService::Open(...) call.
NS_IMETHOD OnStopBinding(nsIPluginStreamInfo* pluginInfo, nsresult status);
NS_IMETHOD OnNotify(const char* url, nsresult status);
NS_IMETHOD GetStreamType(nsPluginStreamType *result);
////////////////////////////////////////////////////////////////////////////
// EventsPluginStreamListener specific methods:
EventsPluginStreamListener(EventsPluginInstance *inst_, const char* url);
virtual ~EventsPluginStreamListener(void);
protected:
const char* fMessageName;
EventsPluginInstance *inst;
};
// The module loader information.
static const nsModuleComponentInfo gComponentInfo[] = {
{ "Events Sample Plugin",
NS_EVENTSAMPLEPLUGIN_CID,
NS_INLINE_PLUGIN_CONTRACTID_PREFIX PLUGIN_MIME_TYPE,
EventsPluginInstance::Create,
EventsPluginInstance::RegisterSelf,
EventsPluginInstance::UnregisterSelf },
};
NS_IMPL_NSGETMODULE(EventsPlugin, gComponentInfo)
////////////////////////////////////////////////////////////////////////////////
// EventsPluginInstance static Methods
////////////////////////////////////////////////////////////////////////////////
NS_METHOD
EventsPluginInstance::Create(nsISupports* aOuter, REFNSIID aIID, void** aResult)
{
NS_PRECONDITION(aOuter == nsnull, "no aggregation");
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
EventsPluginInstance* plugin = new EventsPluginInstance();
if (! plugin)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv;
NS_ADDREF(plugin);
rv = plugin->QueryInterface(aIID, aResult);
NS_RELEASE(plugin);
return rv;
}
NS_METHOD
EventsPluginInstance::RegisterSelf(nsIComponentManager* aCompMgr,
nsIFile* aPath,
const char* aRegistryLocation,
const char* aComponentType,
const nsModuleComponentInfo *info)
{
nsresult rv;
nsIServiceManager *svcMgr;
rv = aCompMgr->QueryInterface(NS_GET_IID(nsIServiceManager),
NS_REINTERPRET_CAST(void**, &svcMgr));
if (NS_FAILED(rv))
return rv;
nsIPluginManager* pm;
rv = svcMgr->GetService(kPluginManagerCID,
NS_GET_IID(nsIPluginManager),
NS_REINTERPRET_CAST(void**, &pm));
NS_RELEASE(svcMgr);
if (NS_SUCCEEDED(rv)) {
rv = pm->RegisterPlugin(kEventsPluginCID,
kPluginName,
kPluginDescription,
kMimeTypes,
kMimeDescriptions,
kFileExtensions,
kNumMimeTypes);
NS_RELEASE(pm);
}
return rv;
}
NS_METHOD
EventsPluginInstance::UnregisterSelf(nsIComponentManager* aCompMgr,
nsIFile* aPath,
const char* aRegistryLocation,
const nsModuleComponentInfo *info)
{
nsresult rv;
nsIServiceManager *svcMgr;
rv = aCompMgr->QueryInterface(NS_GET_IID(nsIServiceManager),
NS_REINTERPRET_CAST(void**, &svcMgr));
if (NS_FAILED(rv))
return rv;
nsIPluginManager* pm;
rv = svcMgr->GetService(kPluginManagerCID,
NS_GET_IID(nsIPluginManager),
NS_REINTERPRET_CAST(void**, &pm));
NS_RELEASE(svcMgr);
if (NS_SUCCEEDED(rv)) {
rv = pm->UnregisterPlugin(kEventsPluginCID);
NS_RELEASE(pm);
}
return rv;
}
////////////////////////////////////////////////////////////////////////////////
// EventsPluginInstance Methods
////////////////////////////////////////////////////////////////////////////////
// These macros produce simple version of QueryInterface and AddRef.
// See the nsISupports.h header file for details.
NS_IMPL_ISUPPORTS2(EventsPluginInstance, nsIPluginInstance, nsIEventsSampleInstance)
EventsPluginInstance::EventsPluginInstance() :
fPeer(NULL), fWindow(NULL), fMode(nsPluginMode_Embedded)
{
wChild = 0;
}
EventsPluginInstance::~EventsPluginInstance(void) {
}
NS_METHOD EventsPluginInstance::Initialize(nsIPluginInstancePeer *peer) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginInstance::Initialize\n");
#endif
NS_ASSERTION(peer != NULL, "null peer");
fPeer = peer;
nsCOMPtr<nsIPluginTagInfo> taginfo;
const char* const* names = nsnull;
const char* const* values = nsnull;
PRUint16 count = 0;
nsresult result;
peer->AddRef();
result = peer->GetMode(&fMode);
if (NS_FAILED(result)) return result;
taginfo = do_QueryInterface(peer, &result);
if (NS_SUCCEEDED(result)) {
taginfo->GetAttributes(count, names, values);
}
PlatformNew(); /* Call Platform-specific initializations */
return NS_OK;
}
NS_METHOD EventsPluginInstance::GetPeer(nsIPluginInstancePeer* *result) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginInstance::GetPeer\n");
#endif
*result = fPeer;
NS_IF_ADDREF(*result);
return NS_OK;
}
NS_METHOD EventsPluginInstance::Start(void) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginInstance::Start\n");
#endif
return NS_OK;
}
NS_METHOD EventsPluginInstance::Stop(void) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginInstance::Stop\n");
#endif
return NS_OK;
}
NS_METHOD EventsPluginInstance::Destroy(void) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginInstance::Destroy\n");
#endif
PlatformDestroy(); // Perform platform specific cleanup
return NS_OK;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++
* NPP_SetWindow:
* Sets the window in which a plug-in draws, and returns an error value.
*
* NPP_SetWindow informs the plug-in instance specified by instance of the
* the window denoted by window in which the instance draws. This nsPluginWindow
* pointer is valid for the life of the instance, or until NPP_SetWindow is called
* again with a different value. Subsequent calls to NPP_SetWindow for a given
* instance typically indicate that the window has been resized. If either window
* or window->window are NULL, the plug-in must not perform any additional
* graphics operations on the window and should free any resources associated
* with the window.
+++++++++++++++++++++++++++++++++++++++++++++++++*/
NS_METHOD EventsPluginInstance::SetWindow(nsPluginWindow* window) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginInstance::SetWindow\n");
#endif
nsresult result;
result = DoSetWindow(window);
fWindow = window;
return result;
}
nsresult EventsPluginInstance::DoSetWindow(nsPluginWindow* window) {
/*
* PLUGIN DEVELOPERS:
* Before setting window to point to the
* new window, you may wish to compare the new window
* info to the previous window (if any) to note window
* size changes, etc.
*/
nsresult result = NS_OK;
if ( fWindow != NULL ) {
// If we already have a window, clean it up
// before working with the new window
if ( window && window->window && wMain == (WinID)window->window ) {
/* The new window is the same as the old one. Exit now. */
PlatformResizeWindow(window);
return NS_OK;
}
// Otherwise, just reset the window ready for the new one.
PlatformResetWindow();
}
else if ( (window == NULL) || ( window->window == NULL ) ) {
/* We can just get out of here if there is no current
* window and there is no new window to use. */
return NS_OK;
}
if (window && window->window) {
// Remember our main parent window.
wMain = (WinID)window->window;
// And create the child window.
result = PlatformCreateWindow(window);
}
return result;
}
NS_METHOD EventsPluginInstance::NewStream(nsIPluginStreamListener** listener) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginInstance::NewStream\n");
#endif
if (listener != NULL) {
EventsPluginStreamListener* sl =
new EventsPluginStreamListener(this, "http://www.mozilla.org");
if (!sl)
return NS_ERROR_UNEXPECTED;
sl->AddRef();
*listener = sl;
}
return NS_OK;
}
NS_METHOD EventsPluginInstance::Print(nsPluginPrint* printInfo) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginInstance::Print\n");
#endif
if (printInfo == NULL)
return NS_ERROR_FAILURE;
if (printInfo->mode == nsPluginMode_Full) {
/*
* PLUGIN DEVELOPERS:
* If your plugin would like to take over
* printing completely when it is in full-screen mode,
* set printInfo->pluginPrinted to TRUE and print your
* plugin as you see fit. If your plugin wants Netscape
* to handle printing in this case, set
* printInfo->pluginPrinted to FALSE (the default) and
* do nothing. If you do want to handle printing
* yourself, printOne is true if the print button
* (as opposed to the print menu) was clicked.
* On the Macintosh, platformPrint is a THPrint; on
* Windows, platformPrint is a structure
* (defined in npapi.h) containing the printer name, port,
* etc.
*/
/* Do the default*/
printInfo->print.fullPrint.pluginPrinted = PR_FALSE;
} else { /* If not fullscreen, we must be embedded */
/*
* PLUGIN DEVELOPERS:
* If your plugin is embedded, or is full-screen
* but you returned false in pluginPrinted above, NPP_Print
* will be called with mode == nsPluginMode_Embedded. The nsPluginWindow
* in the printInfo gives the location and dimensions of
* the embedded plugin on the printed page. On the
* Macintosh, platformPrint is the printer port; on
* Windows, platformPrint is the handle to the printing
* device context.
*/
}
return NS_OK;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++
* NPP_HandleEvent:
* Mac-only, but stub must be present for Windows
* Delivers a platform-specific event to the instance.
*
* On the Macintosh, event is a pointer to a standard Macintosh EventRecord.
* All standard event types are passed to the instance as appropriate. In general,
* return TRUE if you handle the event and FALSE if you ignore the event.
+++++++++++++++++++++++++++++++++++++++++++++++++*/
NS_METHOD EventsPluginInstance::HandleEvent(nsPluginEvent* event, PRBool* handled) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginInstance::HandleEvent\n");
#endif
*handled = (PRBool)PlatformHandleEvent(event);
return NS_OK;
}
NS_METHOD EventsPluginInstance::GetValue(nsPluginInstanceVariable /*variable*/, void * /*value*/) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginInstance::GetValue\n");
#endif
return NS_ERROR_FAILURE;
}
////////////////////////////////////////////////////////////////////////////////
// EventsPluginStreamListener Methods
////////////////////////////////////////////////////////////////////////////////
EventsPluginStreamListener::EventsPluginStreamListener(EventsPluginInstance* inst_,
const char* msgName)
: fMessageName(msgName), inst(inst_) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginStreamListener: EventsPluginStreamListener for %s\n", fMessageName);
#endif
}
EventsPluginStreamListener::~EventsPluginStreamListener(void) {
}
// This macro produces a simple version of QueryInterface, AddRef and Release.
// See the nsISupports.h header file for details.
NS_IMPL_ISUPPORTS1(EventsPluginStreamListener, nsIPluginStreamListener)
NS_METHOD EventsPluginStreamListener::OnStartBinding(nsIPluginStreamInfo * /*pluginInfo*/) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginStreamListener::OnStartBinding\n");
printf("EventsPluginStreamListener: Opening plugin stream for %s\n", fMessageName);
#endif
return NS_OK;
}
NS_METHOD EventsPluginStreamListener::OnDataAvailable(
nsIPluginStreamInfo * /*pluginInfo*/,
nsIInputStream* input,
PRUint32 length) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginStreamListener::OnDataAvailable\n");
#endif
char* buffer = new char[length];
if (buffer) {
PRUint32 amountRead = 0;
nsresult rslt = input->Read(buffer, length, &amountRead);
if (rslt == NS_OK) {
char msg[256];
sprintf(msg, "### Received %d bytes for %s\n", length, fMessageName);
}
delete buffer;
}
return NS_OK;
}
NS_METHOD EventsPluginStreamListener::OnFileAvailable(
nsIPluginStreamInfo * /*pluginInfo*/,
const char* fileName) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginStreamListener::OnFileAvailable\n");
#endif
char msg[256];
sprintf(msg, "### File available for %s: %s\n", fMessageName, fileName);
return NS_OK;
}
NS_METHOD EventsPluginStreamListener::OnStopBinding(
nsIPluginStreamInfo * /*pluginInfo*/,
nsresult /*status*/) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginStreamListener::OnStopBinding\n");
#endif
char msg[256];
sprintf(msg, "### Closing plugin stream for %s\n", fMessageName);
return NS_OK;
}
NS_METHOD EventsPluginStreamListener::OnNotify(const char * /*url*/, nsresult /*status*/) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginStreamListener::OnNotify\n");
#endif
return NS_OK;
}
NS_METHOD EventsPluginStreamListener::GetStreamType(nsPluginStreamType *result) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginStreamListener::GetStreamType\n");
#endif
*result = nsPluginStreamType_Normal;
return NS_OK;
}
///////////////////////////////////////////////////////////////////////////////
// Platform-Specific Implemenations
// UNIX Implementations
#ifdef XP_UNIX
void EventsPluginInstance::PlatformNew(void) {
fPlatform.moz_box = 0;
}
nsresult EventsPluginInstance::PlatformDestroy(void) {
// the mozbox will be destroyed by the native destruction of the
// widget's parent.
return NS_OK;
}
void EventsPluginInstance::PlatformResetWindow() {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginInstance::PlatformResetWindow\n");
#endif
fPlatform.moz_box = 0;
}
nsresult EventsPluginInstance::PlatformCreateWindow(nsPluginWindow* window) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginInstance::PlatformCreateWindow %lx\n", (long)window);
#endif
Window x_window = (Window)window->window;
GdkWindow *gdk_window = (GdkWindow *)gdk_xid_table_lookup(x_window);
if (!gdk_window) {
fprintf(stderr, "NO WINDOW!!!\n");
return NS_ERROR_FAILURE;
}
fPlatform.moz_box = gtk_mozbox_new(gdk_window);
wChild = gtk_entry_new();
gtk_container_add(GTK_CONTAINER(fPlatform.moz_box), wChild);
gtk_widget_show_all(fPlatform.moz_box);
return NS_OK;
}
void EventsPluginInstance::PlatformResizeWindow(nsPluginWindow* window) {
NS_PRECONDITION(wChild, "Have no wChild!");
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginInstance::PlatformResizeWindow to size (%d,%d)\n", window->width, window->height);
#endif
// Mozilla has already sized the mozbox - we just need to handle the child.
gtk_widget_set_usize(wChild, window->width, window->height);
}
int16 EventsPluginInstance::PlatformHandleEvent(nsPluginEvent * /*event*/) {
/* UNIX Plugins do not use HandleEvent */
return 0;
}
/* attribute string text; */
NS_IMETHODIMP EventsPluginInstance::GetVal(char * *aText) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginInstance::GetVal\n");
#endif
char *text = gtk_entry_get_text(GTK_ENTRY(wChild));
*aText = reinterpret_cast<char*>(nsAllocator::Clone(text, strlen(text) + 1));
return (*aText) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP EventsPluginInstance::SetVal(const char * aText) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginInstance::SetVal\n");
#endif
gtk_entry_set_text(GTK_ENTRY(wChild), aText);
return NS_OK;
}
#endif /* XP_UNIX */
// Windows Implementations
#if defined(XP_WIN)
void EventsPluginInstance::PlatformNew(void) {
// Nothing to do!
}
nsresult EventsPluginInstance::PlatformDestroy(void) {
wChild = 0;
return NS_OK;
}
nsresult EventsPluginInstance::PlatformCreateWindow(nsPluginWindow* window) {
// Remember parent wndproc.
fPlatform.fParentWindowProc = (WNDPROC)::GetWindowLong(wMain, GWL_WNDPROC);
NS_ABORT_IF_FALSE(fPlatform.fParentWindowProc!=NULL, "Couldn't get the parent WNDPROC");
// Create the child window that fills our nsWindow
RECT rc;
::GetWindowRect(wMain, &rc);
wChild = ::CreateWindow("Edit", // class - standard Windows edit control.
"", // title
WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL, // style
0, 0, rc.right-rc.left, rc.bottom-rc.top,
wMain, // parent
(HMENU)1111, // window ID
0, // instance
NULL); //creation data.
NS_ABORT_IF_FALSE(wChild != NULL, "Failed to create the child window!");
if (!wChild)
return NS_ERROR_FAILURE;
// Stash away our "this" pointer so our WNDPROC can talk to us.
::SetProp(wChild, gInstanceLookupString, (HANDLE)this);
fPlatform.fOldChildWindowProc =
(WNDPROC)::SetWindowLong( wChild,
GWL_WNDPROC,
(LONG)EventsPluginInstance::WndProcChild);
return NS_OK;
}
int16 EventsPluginInstance::PlatformHandleEvent(nsPluginEvent * /*event*/) {
return NS_OK;
}
void EventsPluginInstance::PlatformResetWindow() {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginInstance::PlatformResetWindow\n");
#endif
fPlatform.fParentWindowProc = NULL;
::SetWindowLong(wChild, GWL_WNDPROC, (LONG)fPlatform.fOldChildWindowProc);
fPlatform.fOldChildWindowProc = NULL;
wChild = NULL;
wMain = NULL;
}
void EventsPluginInstance::PlatformResizeWindow(nsPluginWindow* window) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginInstance::PlatformResizeWindow with new size (%d,%d)\n", window->width, window->height);
#endif
RECT rc;
NS_PRECONDITION(wMain != nsnull, "Must have a valid wMain to resize");
::GetClientRect(wMain, &rc);
::SetWindowPos(wChild, 0, rc.left, rc.top,
rc.right - rc.left, rc.bottom - rc.top, SWP_NOZORDER | SWP_NOACTIVATE);
}
/* attribute string text; */
NS_IMETHODIMP EventsPluginInstance::GetVal(char * *aText) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginInstance::GetVal\n");
#endif
static char *empty = "";
char *value = empty;
char buffer[256];
if (wChild) {
GetWindowText(wChild, buffer, sizeof(buffer)/sizeof(buffer[0]));
value = buffer;
}
*aText = reinterpret_cast<char*>(nsAllocator::Clone(value, strlen(value) + 1));
return (*aText) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP EventsPluginInstance::SetVal(const char * aText) {
#ifdef EVENTSPLUGIN_DEBUG
printf("EventsPluginInstance::SetVal\n");
#endif
NS_ABORT_IF_FALSE(wChild != 0, "Don't have a window!");
SetWindowText(wChild, aText);
return NS_OK;
}
// This is the WndProc for our child window (the edit control)
LRESULT CALLBACK EventsPluginInstance::WndProcChild(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
EventsPluginInstance* inst = (EventsPluginInstance*) GetProp(hWnd, gInstanceLookupString);
NS_ABORT_IF_FALSE(inst, "Could not get the inst from the Window!!");
switch (Msg) {
// NOTE: We DONT pass on DBLCLK messages, as both Scintilla and
// Mozilla have their own special logic, and they step on each other.
// (causing our child to see a double-click as a triple-click)
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
case WM_KEYUP:
case WM_SYSKEYUP:
case WM_CHAR:
case WM_SYSCHAR:
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
case WM_MOUSEMOVE:
// pretend the message happened in our parent.
return ::CallWindowProc(inst->fPlatform.fParentWindowProc, (HWND)inst->wMain, Msg, wParam, lParam);
default:
// let our child's default handle it.
return ::CallWindowProc(inst->fPlatform.fOldChildWindowProc, hWnd, Msg, wParam, lParam);
}
/* not reached */
NS_ABORT_IF_FALSE(0, "not reached!");
}
#endif /* XP_WIN */