diff options
author | Morten Sorvig <morten.sorvig@nokia.com> | 2010-02-03 18:57:08 +0100 |
---|---|---|
committer | Morten Sorvig <morten.sorvig@nokia.com> | 2010-02-03 18:57:08 +0100 |
commit | f87f468c0b29a9e99c2575867d30fc711811d0a5 (patch) | |
tree | bbe99c20b186c6f7a4d26a42eacecd6cd6e18717 | |
parent | ead3fba59d0c89130ddaca8e3ef49e26e11ee79c (diff) |
Start work on pepper support.
Add the pepper example from NaCl, which I`ll use as bootstrapping code.
I`m not sure exactly how much of this we need to implement in Qt.
-rw-r--r-- | src/gui/gui.pro | 1 | ||||
-rw-r--r-- | src/gui/kernel/kernel.pri | 6 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_lite.cpp | 6 | ||||
-rw-r--r-- | src/gui/kernel/qeventdispatcher_pepper.cpp | 137 | ||||
-rw-r--r-- | src/gui/kernel/qeventdispatcher_pepper_p.h | 89 | ||||
-rwxr-xr-x | src/gui/pepper/command_buffer_pepper.cc | 173 | ||||
-rwxr-xr-x | src/gui/pepper/command_buffer_pepper.h | 57 | ||||
-rw-r--r-- | src/gui/pepper/event_handler.cc | 204 | ||||
-rw-r--r-- | src/gui/pepper/event_handler.h | 55 | ||||
-rw-r--r-- | src/gui/pepper/main.cc | 216 | ||||
-rw-r--r-- | src/gui/pepper/pepper.pri | 8 | ||||
-rw-r--r-- | src/gui/pepper/plugin_object.cc | 297 | ||||
-rw-r--r-- | src/gui/pepper/plugin_object.h | 59 | ||||
-rw-r--r-- | src/gui/pepper/test_object.cc | 227 | ||||
-rw-r--r-- | src/gui/pepper/test_object.h | 41 |
15 files changed, 1573 insertions, 3 deletions
diff --git a/src/gui/gui.pro b/src/gui/gui.pro index 6949e39653..9a0a1a35a6 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -39,6 +39,7 @@ include(util/util.pri) include(statemachine/statemachine.pri) include(math3d/math3d.pri) include(effects/effects.pri) +include(pepper/pepper.pri) contains(QT_CONFIG, egl): include(egl/egl.pri) diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index 81e3520d32..9bd4e3662e 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -212,8 +212,10 @@ embedded_lite { } nacl { - HEADERS += kernel/qeventdispatcher_nacl_p.h - SOURCES += kernel/qeventdispatcher_nacl.cpp + HEADERS += kernel/qeventdispatcher_nacl_p.h \ + kernel/qeventdispatcher_pepper_p.h + SOURCES += kernel/qeventdispatcher_nacl.cpp \ + kernel/qeventdispatcher_pepper.cpp } !embedded:!embedded_lite:!x11:mac { diff --git a/src/gui/kernel/qapplication_lite.cpp b/src/gui/kernel/qapplication_lite.cpp index 108edc12d1..341217c3f5 100644 --- a/src/gui/kernel/qapplication_lite.cpp +++ b/src/gui/kernel/qapplication_lite.cpp @@ -47,6 +47,7 @@ #endif #ifdef Q_OS_NACL #include "private/qeventdispatcher_nacl_p.h" +#include "private/qeventdispatcher_pepper_p.h" #endif #include "private/qeventdispatcher_unix_p.h" #ifndef QT_NO_CURSOR @@ -91,7 +92,10 @@ void QApplicationPrivate::createEventDispatcher() eventDispatcher = new QEventDispatcherGlib(q); else #elif defined(Q_OS_NACL) - eventDispatcher = new QEventDispatcherNaCl(q); + if (QEventDispatcherPepper::hasPepperSupport()) + eventDispatcher = new QEventDispatcherPepper(); + else + eventDispatcher = new QEventDispatcherNaCl(q); #else eventDispatcher = new QEventDispatcherUNIX(q); #endif diff --git a/src/gui/kernel/qeventdispatcher_pepper.cpp b/src/gui/kernel/qeventdispatcher_pepper.cpp new file mode 100644 index 0000000000..cd68295d84 --- /dev/null +++ b/src/gui/kernel/qeventdispatcher_pepper.cpp @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeventdispatcher_pepper_p.h" + +#include "qplatformdefs.h" +#include "qapplication.h" +#include "qwaitcondition.h" +#include "qevent.h" +#include "qmutex.h" +#include "qobject.h" +#include <errno.h> +#include <stdio.h> + +#include <private/qapplication_p.h> +#include <time.h> + +#include <nacl/nacl_npapi.h> +#include <nacl/npapi_extensions.h> +#include <nacl/npruntime.h> +#include <nacl/npupp.h> + + +QT_BEGIN_NAMESPACE + +QT_USE_NAMESPACE + +class QEventDispatcherPepperPrivate : public QEventDispatcherUNIXPrivate +{ + Q_DECLARE_PUBLIC(QEventDispatcherPepper) +public: + inline QEventDispatcherPepperPrivate() + { } + +}; + +bool QEventDispatcherPepper::hasPepperSupport() +{ + bool hasSupport = false; + fprintf(stderr, "hasPepperSupport %b\n", hasSupport); + return hasSupport; +} + +QEventDispatcherPepper::QEventDispatcherPepper(QObject *parent) + : QEventDispatcherUNIX(*new QEventDispatcherPepperPrivate, parent) +{ } + +QEventDispatcherPepper::~QEventDispatcherPepper() +{ } + + +bool QEventDispatcherPepper::processEvents(QEventLoop::ProcessEventsFlags flags) +{ +} + + +bool QEventDispatcherPepper::hasPendingEvents() +{ + extern uint qGlobalPostedEventsCount(); // from qapplication.cpp + return qGlobalPostedEventsCount(); +} + +void QEventDispatcherPepper::registerSocketNotifier(QSocketNotifier *notifier) +{ + +} + +void QEventDispatcherPepper::unregisterSocketNotifier(QSocketNotifier *notifier) +{ + +} + +void QEventDispatcherPepper::startingUp() +{ + +} + +void QEventDispatcherPepper::closingDown() +{ + +} + +void QEventDispatcherPepper::wakeUp() +{ + +} + +void QEventDispatcherPepper::interrupt() +{ + +} + +void QEventDispatcherPepper::flush() +{ + if(qApp) + qApp->sendPostedEvents(); +} + +QT_END_NAMESPACE diff --git a/src/gui/kernel/qeventdispatcher_pepper_p.h b/src/gui/kernel/qeventdispatcher_pepper_p.h new file mode 100644 index 0000000000..2a724e821b --- /dev/null +++ b/src/gui/kernel/qeventdispatcher_pepper_p.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEVENTDISPATCHER_PEPPER_P_H +#define QEVENTDISPATCHER_PEPPER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "private/qeventdispatcher_unix_p.h" + +QT_BEGIN_NAMESPACE + +class QEventDispatcherPepperPrivate; + +class QEventDispatcherPepper : public QEventDispatcherUNIX +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QEventDispatcherPepper) + +public: + static bool hasPepperSupport(); + + explicit QEventDispatcherPepper(QObject *parent = 0); + ~QEventDispatcherPepper(); + + bool processEvents(QEventLoop::ProcessEventsFlags flags); + bool hasPendingEvents(); + + void registerSocketNotifier(QSocketNotifier *notifier); + void unregisterSocketNotifier(QSocketNotifier *notifier); + + void wakeUp(); + void interrupt(); + void flush(); + + void startingUp(); + void closingDown(); +}; + +QT_END_NAMESPACE + +#endif // QEVENTDISPATCHER_PEPPER_P_H diff --git a/src/gui/pepper/command_buffer_pepper.cc b/src/gui/pepper/command_buffer_pepper.cc new file mode 100755 index 0000000000..0ad5220483 --- /dev/null +++ b/src/gui/pepper/command_buffer_pepper.cc @@ -0,0 +1,173 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "command_buffer_pepper.h" + +using gpu::Buffer; + +CommandBufferPepper::CommandBufferPepper(NPP npp, NPNetscapeFuncs* browser) + : npp_(npp), + browser_(browser), + extensions_(NULL), + device_(NULL) { +} + +CommandBufferPepper::~CommandBufferPepper() { + if (device_) { + device_->destroyContext(npp_, &context_); + device_ = NULL; + } +} + +bool CommandBufferPepper::Initialize(int32 size) { + if (device_) + return false; + + // Get the pepper extensions. + browser_->getvalue(npp_, + NPNVPepperExtensions, + reinterpret_cast<void*>(&extensions_)); + CHECK(extensions_); + + // Acquire a 3D device. + device_ = extensions_->acquireDevice(npp_, NPPepper3DDevice); + if (device_) { + NPDeviceContext3DConfig config; + config.commandBufferEntries = size; + if (NPERR_NO_ERROR == device_->initializeContext(npp_, + &config, + &context_)) { + return true; + } + } + + return false; +} + +Buffer CommandBufferPepper::GetRingBuffer() { + Buffer buffer; + buffer.ptr = context_.commandBuffer; + buffer.size = context_.commandBufferEntries * sizeof(int32); + return buffer; +} + +int32 CommandBufferPepper::GetSize() { + return context_.commandBufferEntries; +} + +int32 CommandBufferPepper::SyncOffsets(int32 put_offset) { + context_.putOffset = put_offset; + if (NPERR_NO_ERROR != device_->flushContext(npp_, &context_, NULL, NULL)) + return -1; + + return context_.getOffset; +} + +int32 CommandBufferPepper::GetGetOffset() { + int32 value; + if (NPERR_NO_ERROR != device_->getStateContext( + npp_, + &context_, + NPDeviceContext3DState_GetOffset, + &value)) { + return -1; + } + + return value; +} + +void CommandBufferPepper::SetGetOffset(int32 get_offset) { + // Not implemented by proxy. + NOTREACHED(); +} + +int32 CommandBufferPepper::GetPutOffset() { + int32 value; + if (NPERR_NO_ERROR != device_->getStateContext( + npp_, + &context_, + NPDeviceContext3DState_PutOffset, + &value)) { + return -1; + } + + return value; +} + +int32 CommandBufferPepper::CreateTransferBuffer(size_t size) { + int32 id; + if (NPERR_NO_ERROR != device_->createBuffer(npp_, &context_, size, &id)) + return -1; + + return id; +} + +void CommandBufferPepper::DestroyTransferBuffer(int32 id) { + device_->destroyBuffer(npp_, &context_, id); +} + +Buffer CommandBufferPepper::GetTransferBuffer(int32 id) { + NPDeviceBuffer np_buffer; + if (NPERR_NO_ERROR != device_->mapBuffer(npp_, &context_, id, &np_buffer)) + return Buffer(); + + Buffer buffer; + buffer.ptr = np_buffer.ptr; + buffer.size = np_buffer.size; + return buffer; +} + +int32 CommandBufferPepper::GetToken() { + int32 value; + if (NPERR_NO_ERROR != device_->getStateContext( + npp_, + &context_, + NPDeviceContext3DState_Token, + &value)) { + return -1; + } + + return value; +} + +void CommandBufferPepper::SetToken(int32 token) { + // Not implemented by proxy. + NOTREACHED(); +} + +int32 CommandBufferPepper::ResetParseError() { + int32 value; + if (NPERR_NO_ERROR != device_->getStateContext( + npp_, + &context_, + NPDeviceContext3DState_ParseError, + &value)) { + return -1; + } + + return value; +} + +void CommandBufferPepper::SetParseError(int32 parse_error) { + // Not implemented by proxy. + NOTREACHED(); +} + +bool CommandBufferPepper::GetErrorStatus() { + int32 value; + if (NPERR_NO_ERROR != device_->getStateContext( + npp_, + &context_, + NPDeviceContext3DState_ErrorStatus, + &value)) { + return value != 0; + } + + return true; +} + +void CommandBufferPepper::RaiseErrorStatus() { + // Not implemented by proxy. + NOTREACHED(); +} diff --git a/src/gui/pepper/command_buffer_pepper.h b/src/gui/pepper/command_buffer_pepper.h new file mode 100755 index 0000000000..6ae8ce6847 --- /dev/null +++ b/src/gui/pepper/command_buffer_pepper.h @@ -0,0 +1,57 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NATIVE_CLIENT_TESTS_PEPPER_PLUGIN_COMMAND_BUFFER_PEPPER_H_ +#define NATIVE_CLIENT_TESTS_PEPPER_PLUGIN_COMMAND_BUFFER_PEPPER_H_ + +// Temporary workarounds for missing NaCl definitions of base macros. +#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&); +#define CHECK(Expression) +#define NOTREACHED() + +#include <nacl/npapi.h> +#include <nacl/npapi_extensions.h> +#include <nacl/npruntime.h> +#include <nacl/npupp.h> +#include <nacl/command_buffer.h> + +// A CommandBuffer proxy implementation that uses the Pepper API to access +// the command buffer. +// TODO(apatrick): move this into a library that can be used by any pepper +// plugin. + +class CommandBufferPepper : public gpu::CommandBuffer { + public: + CommandBufferPepper(NPP npp, NPNetscapeFuncs* browser); + virtual ~CommandBufferPepper(); + + // CommandBuffer implementation. + virtual bool Initialize(int32 size); + virtual gpu::Buffer GetRingBuffer(); + virtual int32 GetSize(); + virtual int32 SyncOffsets(int32 put_offset); + virtual int32 GetGetOffset(); + virtual void SetGetOffset(int32 get_offset); + virtual int32 GetPutOffset(); + virtual int32 CreateTransferBuffer(size_t size); + virtual void DestroyTransferBuffer(int32 id); + virtual gpu::Buffer GetTransferBuffer(int32 handle); + virtual int32 GetToken(); + virtual void SetToken(int32 token); + virtual int32 ResetParseError(); + virtual void SetParseError(int32 parse_error); + virtual bool GetErrorStatus(); + virtual void RaiseErrorStatus(); + + private: + NPP npp_; + NPNetscapeFuncs* browser_; + NPExtensions* extensions_; + NPDevice* device_; + NPDeviceContext3D context_; +}; + +#endif // NATIVE_CLIENT_TESTS_PEPPER_PLUGIN_COMMAND_BUFFER_PEPPER_H_ diff --git a/src/gui/pepper/event_handler.cc b/src/gui/pepper/event_handler.cc new file mode 100644 index 0000000000..e9a900a5bf --- /dev/null +++ b/src/gui/pepper/event_handler.cc @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "event_handler.h" + +#include <stdarg.h> +#include <stdio.h> +#include <string.h> +#include <string> + +#include "native_client/src/include/nacl_macros.h" +#include "plugin_object.h" + +// Utility methods. +std::string DoubleToString(double d) { + char buf[2048]; + const size_t kBufSize = sizeof(buf); + snprintf(buf, kBufSize, "%f", d); + return buf; +} + +std::string StringPrintf(const char* format, ...) { + char buf[2048]; + const size_t kBufSize = sizeof(buf); + va_list ap; + va_start(ap, format); + vsnprintf(buf, kBufSize, format, ap); + va_end(ap); + return buf; +} + +EventHandler* event_handler = NULL; + +// EventHandler ---------------------------------------------------------------- + +EventHandler::EventHandler(NPP npp) + : npp_(npp), + text_box_(NULL) { +} + +EventHandler::~EventHandler() { +} + +void EventHandler::addText(const char* cstr) { + NPVariant variant; + // Create a a string variant to be set for the innerText. + MakeNPVariant(cstr, &variant); + // Report the string to the div. + NPVariant result; + browser->invokeDefault(npp_, text_box_, &variant, 1, &result); + // Release the variant. + browser->releasevariantvalue(&variant); + browser->releasevariantvalue(&result); +} + +std::string EventHandler::EventName(double timestamp, int32 type) { + std::string str = DoubleToString(timestamp) + ": "; + switch (type) { + case NPEventType_MouseDown: + return str + "MouseDown"; + case NPEventType_MouseUp: + return str + "MouseUp"; + case NPEventType_MouseMove: + return str + "MouseMove"; + case NPEventType_MouseEnter: + return str + "MouseEnter"; + case NPEventType_MouseLeave: + return str + "MouseLeave"; + case NPEventType_MouseWheel: + return str + "MouseWheel"; + case NPEventType_RawKeyDown: + return str + "RawKeyDown"; + case NPEventType_KeyDown: + return str + "KeyDown"; + case NPEventType_KeyUp: + return str + "KeyUp"; + case NPEventType_Char: + return str + "Char"; + case NPEventType_Minimize: + return str + "Minimize"; + case NPEventType_Focus: + return str + "Focus"; + case NPEventType_Device: + return str + "Device"; + case NPEventType_Undefined: + default: + return str + "Undefined"; + } +} + +int EventHandler::handle(void* event) { + NPPepperEvent* npevent = reinterpret_cast<NPPepperEvent*>(event); + std::string str = EventName(npevent->timeStampSeconds, npevent->type); + switch (npevent->type) { + case NPEventType_MouseDown: + case NPEventType_MouseUp: + case NPEventType_MouseMove: + case NPEventType_MouseEnter: + case NPEventType_MouseLeave: + str += StringPrintf(": mod %x, but: %x, x: %d, y: %d, click: %d", + npevent->u.mouse.modifier, + npevent->u.mouse.button, + npevent->u.mouse.x, + npevent->u.mouse.y, + npevent->u.mouse.clickCount); + break; + case NPEventType_MouseWheel: + str += StringPrintf(": mod %x, dx: %f, dy: %f, wtx: %f, wty: %d: sbp %d", + npevent->u.wheel.modifier, + npevent->u.wheel.deltaX, + npevent->u.wheel.deltaY, + npevent->u.wheel.wheelTicksX, + npevent->u.wheel.wheelTicksY, + npevent->u.wheel.scrollByPage); + break; + case NPEventType_RawKeyDown: + case NPEventType_KeyDown: + case NPEventType_KeyUp: + str += StringPrintf(": mod %x, key: %x", + npevent->u.key.modifier, + npevent->u.key.normalizedKeyCode); + break; + case NPEventType_Char: + str += StringPrintf(": mod %x, text: ", + npevent->u.character.modifier); + size_t i; + for (i = 0; i < NACL_ARRAY_SIZE(npevent->u.character.text); ++i) { + str += StringPrintf("%x ", npevent->u.character.text[i]); + } + str += ", unmod: "; + for (i = 0; + i < NACL_ARRAY_SIZE(npevent->u.character.unmodifiedText); + ++i) { + str += StringPrintf("%x ", npevent->u.character.unmodifiedText[i]); + } + break; + case NPEventType_Minimize: + case NPEventType_Focus: + case NPEventType_Device: + // TODO(sehr): add prints as we support these. + break; + case NPEventType_Undefined: + default: + return 0; + } + addText(str.c_str()); + return 1; +} + +bool EventHandler::set_text_box(NPObject* text_box_object) { + text_box_ = text_box_object; + // Keep a reference to the text box update object. + browser->retainobject(text_box_object); + // Announce that we are alive. + addText("Set the callback for text\n"); + return true; +} + +char* EventHandler::string_duplicate(const char* cstr, size_t* len) { + *len = strlen(cstr); + char* str = reinterpret_cast<char*>(browser->memalloc(*len + 1)); + if (NULL == str) { + *len = 0; + return NULL; + } + memcpy(str, cstr, *len + 1); + return str; +} + +void EventHandler::MakeNPVariant(const char* cstr, NPVariant* var) { + if (NULL == cstr) { + STRINGN_TO_NPVARIANT(NULL, 0, *var); + return; + } + size_t len; + char* name = string_duplicate(cstr, &len); + if (NULL == name) { + STRINGN_TO_NPVARIANT(NULL, 0, *var); + return; + } + STRINGN_TO_NPVARIANT(name, len, *var); +} diff --git a/src/gui/pepper/event_handler.h b/src/gui/pepper/event_handler.h new file mode 100644 index 0000000000..fd06f6156c --- /dev/null +++ b/src/gui/pepper/event_handler.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NATIVE_CLIENT_TESTS_PEPPER_PLUGIN_EVENT_HANDLER_H_ +#define NATIVE_CLIENT_TESTS_PEPPER_PLUGIN_EVENT_HANDLER_H_ + +#include <nacl/npapi.h> +#include <nacl/npruntime.h> +#define size_t int // #### why? +#include <nacl/npapi_extensions.h> +#undef size_t +#include <string> + +class EventHandler { + public: + explicit EventHandler(NPP npp); + ~EventHandler(); + int handle(void* event); + bool set_text_box(NPObject* text_box_object); + + private: + void addText(const char* cstr); + static char* string_duplicate(const char* cstr, size_t* len); + static void MakeNPVariant(const char* cstr, NPVariant* var); + std::string EventName(double timestamp, int32 type); + + NPP npp_; + NPObject* text_box_; +}; + +extern EventHandler* event_handler; + +#endif // NATIVE_CLIENT_TESTS_PEPPER_PLUGIN_EVENT_HANDLER_H_ diff --git a/src/gui/pepper/main.cc b/src/gui/pepper/main.cc new file mode 100644 index 0000000000..b56336860a --- /dev/null +++ b/src/gui/pepper/main.cc @@ -0,0 +1,216 @@ +/* + IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. + ("Apple") in consideration of your agreement to the following terms, and + your use, installation, modification or redistribution of this Apple software + constitutes acceptance of these terms. If you do not agree with these terms, + please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive license, + under Apple's copyrights in this original Apple software + (the "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following text and + disclaimers in all such redistributions of the Apple Software. Neither the + name, trademarks, service marks or logos of Apple Computer, Inc. may be used + to endorse or promote products derived from the Apple Software without + specific prior written permission from Apple. Except as expressly stated in + this notice, no other rights or licenses, express or implied, are granted by + Apple herein, including but not limited to any patent rights that may be + infringed by your derivative works or by other works in which the Apple + Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED + WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN + COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION + AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER + THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR + OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <nacl/nacl_npapi.h> + +#include "plugin_object.h" +#include "event_handler.h" + +#ifdef WIN32 +#define NPAPI WINAPI +#else +#define NPAPI +#endif + +// Plugin entry points +extern "C" { +NPError NPAPI NP_Initialize(NPNetscapeFuncs* browser_funcs, + NPPluginFuncs* plugin_funcs); +NPError NPAPI NP_GetEntryPoints(NPPluginFuncs* plugin_funcs); + +NPError NPAPI NP_Shutdown() { + return NPERR_NO_ERROR; +} + +NPError NP_GetValue(void* instance, NPPVariable variable, void* value); +char* NP_GetMIMEDescription(); +} // extern "C" + +// Plugin entry points + +NPError NPAPI NP_Initialize(NPNetscapeFuncs* browser_funcs, + NPPluginFuncs* plugin_funcs) { + printf("NP_Initialize... %p %p\n", + reinterpret_cast<void*>(browser_funcs), + reinterpret_cast<void*>(plugin_funcs)); + browser = browser_funcs; + return NP_GetEntryPoints(plugin_funcs); +} + +// Entrypoints ----------------------------------------------------------------- + +NPError NPAPI NP_GetEntryPoints(NPPluginFuncs* plugin_funcs) { + plugin_funcs->version = 11; + plugin_funcs->size = sizeof(plugin_funcs); + plugin_funcs->newp = NPP_New; + plugin_funcs->destroy = NPP_Destroy; + plugin_funcs->setwindow = NPP_SetWindow; + plugin_funcs->newstream = NPP_NewStream; + plugin_funcs->destroystream = NPP_DestroyStream; + plugin_funcs->asfile = NPP_StreamAsFile; + plugin_funcs->writeready = NPP_WriteReady; + plugin_funcs->write = (NPP_WriteUPP)NPP_Write; + plugin_funcs->print = NPP_Print; + plugin_funcs->event = NPP_HandleEvent; + plugin_funcs->urlnotify = NPP_URLNotify; + plugin_funcs->getvalue = NPP_GetValue; + plugin_funcs->setvalue = NPP_SetValue; + + return NPERR_NO_ERROR; +} + +NPError NPP_New(NPMIMEType pluginType, + NPP instance, + uint16 mode, + int16 argc, char* argn[], char* argv[], + NPSavedData* saved) { + if (browser->version >= 14) { + NPObject* obj = NPP_GetScriptableInstance(instance); + instance->pdata = obj; + event_handler = new EventHandler(instance); + } + + return NPERR_NO_ERROR; +} + +NPError NPP_Destroy(NPP instance, NPSavedData** save) { + PluginObject* obj = static_cast<PluginObject*>(instance->pdata); + if (obj) + NPN_ReleaseObject(obj->header()); + + fflush(stdout); + return NPERR_NO_ERROR; +} + +NPError NPP_SetWindow(NPP instance, NPWindow* window) { + PluginObject* obj = static_cast<PluginObject*>(instance->pdata); + if (obj) + obj->SetWindow(*window); + return NPERR_NO_ERROR; +} + +NPError NPP_NewStream(NPP instance, + NPMIMEType type, + NPStream* stream, + NPBool seekable, + uint16* stype) { + *stype = NP_ASFILEONLY; + return NPERR_NO_ERROR; +} + +NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason) { + return NPERR_NO_ERROR; +} + +void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname) { +} + +int32 NPP_Write(NPP instance, + NPStream* stream, + int32 offset, + int32 len, + void* buffer) { + return 0; +} + +int32 NPP_WriteReady(NPP instance, NPStream* stream) { + return 0; +} + +void NPP_Print(NPP instance, NPPrint* platformPrint) { +} + +int16 NPP_HandleEvent(NPP instance, void* event) { + return event_handler->handle(event); +} + +void NPP_URLNotify(NPP instance, + const char* url, + NPReason reason, + void* notify_data) { + // PluginObject* obj = static_cast<PluginObject*>(instance->pdata); +} + +NPError NPP_GetValue(NPP instance, NPPVariable variable, void* value) { + NPError err = NPERR_NO_ERROR; + + switch (variable) { + case NPPVpluginNameString: + *(reinterpret_cast<const char**>(value)) = "Pepper Test PlugIn"; + break; + case NPPVpluginDescriptionString: + *(reinterpret_cast<const char**>(value)) = + "Simple Pepper plug-in for manual testing."; + break; + case NPPVpluginNeedsXEmbed: + *(reinterpret_cast<NPBool*>(value)) = TRUE; + break; + case NPPVpluginScriptableNPObject: { + void** v = reinterpret_cast<void**>(value); + PluginObject* obj = static_cast<PluginObject*>(instance->pdata); + // Return value is expected to be retained. + browser->retainobject(reinterpret_cast<NPObject*>(obj)); + *v = obj; + break; + } + default: + fprintf(stderr, "Unhandled variable to NPP_GetValue\n"); + err = NPERR_GENERIC_ERROR; + break; + } + + return err; +} + +NPError NPP_SetValue(NPP instance, NPNVariable variable, void* value) { + return NPERR_GENERIC_ERROR; +} + +NPObject *NPP_GetScriptableInstance(NPP instance) { + return browser->createobject(instance, PluginObject::GetPluginClass()); +} + +NPError NP_GetValue(void* instance, NPPVariable variable, void* value) { + return NPP_GetValue(reinterpret_cast<NPP>(instance), variable, value); +} + +char* NP_GetMIMEDescription() { + return const_cast<char*>("pepper-application/x-pepper-test-plugin;"); +} diff --git a/src/gui/pepper/pepper.pri b/src/gui/pepper/pepper.pri new file mode 100644 index 0000000000..ed089cc981 --- /dev/null +++ b/src/gui/pepper/pepper.pri @@ -0,0 +1,8 @@ + +INCLUDEDIR =+ $$PWD +DEPENDIR += $$PWD +SOURCES += $$PWD/event_handler.cc \ + $$PWD/plugin_object.cc \ + $$PWD/test_object.cc \ + $$PWD/main.cc + diff --git a/src/gui/pepper/plugin_object.cc b/src/gui/pepper/plugin_object.cc new file mode 100644 index 0000000000..934695ce47 --- /dev/null +++ b/src/gui/pepper/plugin_object.cc @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "plugin_object.h" + +#include <assert.h> +#include <math.h> +#include <stdio.h> +#include <string> + +#include "event_handler.h" +#include "test_object.h" + +NPNetscapeFuncs* browser; + +namespace { + +// Properties ------------------------------------------------------------------ + +enum { + ID_PROPERTY_PROPERTY = 0, + ID_PROPERTY_TEST_OBJECT, + NUM_PROPERTY_IDENTIFIERS +}; + +static NPIdentifier plugin_property_identifiers[NUM_PROPERTY_IDENTIFIERS]; +static const NPUTF8* + plugin_property_identifier_names[NUM_PROPERTY_IDENTIFIERS] = { + "property", + "testObject", +}; + +// Methods --------------------------------------------------------------------- + +enum { + ID_TEST_GET_PROPERTY = 0, + ID_SET_TEXT_BOX, + ID_MODULE_READY, + NUM_METHOD_IDENTIFIERS +}; + +static NPIdentifier plugin_method_identifiers[NUM_METHOD_IDENTIFIERS]; +static const NPUTF8* plugin_method_identifier_names[NUM_METHOD_IDENTIFIERS] = { + "testGetProperty", + "setTextBox", + "moduleReady", +}; + +void EnsureIdentifiersInitialized() { + static bool identifiers_initialized = false; + if (identifiers_initialized) + return; + + browser->getstringidentifiers(plugin_property_identifier_names, + NUM_PROPERTY_IDENTIFIERS, + plugin_property_identifiers); + browser->getstringidentifiers(plugin_method_identifier_names, + NUM_METHOD_IDENTIFIERS, + plugin_method_identifiers); + identifiers_initialized = true; +} + +// Helper functions ------------------------------------------------------------ + +std::string CreateStringFromNPVariant(const NPVariant& variant) { + return std::string(NPVARIANT_TO_STRING(variant).UTF8Characters, + NPVARIANT_TO_STRING(variant).UTF8Length); +} + +bool TestGetProperty(PluginObject* obj, + const NPVariant* args, uint32 arg_count, + NPVariant* result) { + if (arg_count == 0) + return false; + + NPObject *object; + browser->getvalue(obj->npp(), NPNVWindowNPObject, &object); + + for (uint32 i = 0; i < arg_count; i++) { + assert(NPVARIANT_IS_STRING(args[i])); + std::string property_string = CreateStringFromNPVariant(args[i]); + NPIdentifier property_identifier = + browser->getstringidentifier(property_string.c_str()); + + NPVariant variant; + bool retval = browser->getproperty(obj->npp(), object, property_identifier, + &variant); + browser->releaseobject(object); + + if (!retval) + break; + + if (i + 1 < arg_count) { + assert(NPVARIANT_IS_OBJECT(variant)); + object = NPVARIANT_TO_OBJECT(variant); + } else { + *result = variant; + return true; + } + } + + VOID_TO_NPVARIANT(*result); + return false; +} + +// Plugin class functions ------------------------------------------------------ + +NPObject* PluginAllocate(NPP npp, NPClass* the_class) { + EnsureIdentifiersInitialized(); + PluginObject* newInstance = new PluginObject(npp); + return reinterpret_cast<NPObject*>(newInstance); +} + +void PluginDeallocate(NPObject* header) { + PluginObject* plugin = reinterpret_cast<PluginObject*>(header); + delete plugin; +} + +void PluginInvalidate(NPObject* obj) { +} + +bool PluginHasMethod(NPObject* obj, NPIdentifier name) { + for (int i = 0; i < NUM_METHOD_IDENTIFIERS; i++) { + if (name == plugin_method_identifiers[i]) + return true; + } + return false; +} + +bool PluginInvoke(NPObject* header, + NPIdentifier name, + const NPVariant* args, uint32 arg_count, + NPVariant* result) { + PluginObject* plugin = reinterpret_cast<PluginObject*>(header); + if (name == plugin_method_identifiers[ID_TEST_GET_PROPERTY]) { + return TestGetProperty(plugin, args, arg_count, result); + } else if (name == plugin_method_identifiers[ID_SET_TEXT_BOX]) { + if (1 == arg_count && NPVARIANT_IS_OBJECT(args[0])) { + return event_handler->set_text_box(NPVARIANT_TO_OBJECT(args[0])); + } + } else if (name == plugin_method_identifiers[ID_MODULE_READY]) { + INT32_TO_NPVARIANT(1, *result); + return true; + } + + return false; +} + +bool PluginInvokeDefault(NPObject* obj, + const NPVariant* args, uint32 arg_count, + NPVariant* result) { + INT32_TO_NPVARIANT(1, *result); + return true; +} + +bool PluginHasProperty(NPObject* obj, NPIdentifier name) { + for (int i = 0; i < NUM_PROPERTY_IDENTIFIERS; i++) { + if (name == plugin_property_identifiers[i]) + return true; + } + return false; +} + +bool PluginGetProperty(NPObject* obj, + NPIdentifier name, + NPVariant* result) { + return false; +} + +bool PluginSetProperty(NPObject* obj, + NPIdentifier name, + const NPVariant* variant) { + return false; +} + +NPClass plugin_class = { + NP_CLASS_STRUCT_VERSION, + PluginAllocate, + PluginDeallocate, + PluginInvalidate, + PluginHasMethod, + PluginInvoke, + PluginInvokeDefault, + PluginHasProperty, + PluginGetProperty, + PluginSetProperty, +}; + +// Bitmap painting ------------------------------------------------------------- + +// Ugly gradient filled rectangle. +void DrawSampleBitmap(NPDeviceContext2D* context, int width, int height) { + int stride = context->stride; + unsigned char* buffer = reinterpret_cast<unsigned char*>(context->region); + static const int kPixelStride = 4; + + if (0 == height || 0 == width) + return; + + static const float kVStep = 1.0 / static_cast<float>(height); + static const float kHStep = 1.0 / static_cast<float>(width); + static const float kAlphaStep = 1.0 / static_cast<float>(width + height); + for (int i = 0; i < height; ++i) { + for (int j = 0; j < width; ++j) { + int index = i * stride + j * kPixelStride; + float alpha = 1.0 - (i + j) * kAlphaStep; + float red = i * kVStep; + float green = j * kHStep; + // BGRA, premultiplied alpha. + buffer[index + 0] = 0x00; + buffer[index + 1] = static_cast<unsigned char>(green * alpha * 255); + buffer[index + 2] = static_cast<unsigned char>(red * alpha * 255); + buffer[index + 3] = static_cast<unsigned char>(alpha * 255); + } + } +} + +void FlushCallback(NPP instance, NPDeviceContext* context, + NPError err, void* user_data) { +} + +NPExtensions* extensions = NULL; + +} // namespace + + +// PluginObject ---------------------------------------------------------------- + +PluginObject::PluginObject(NPP npp) + : npp_(npp), + test_object_(browser->createobject(npp, GetTestClass())), + device2d_(NULL) { + if (!extensions) { + browser->getvalue(npp_, NPNVPepperExtensions, + reinterpret_cast<void*>(&extensions)); + assert(NULL != extensions); + } + device2d_ = extensions->acquireDevice(npp, NPPepper2DDevice); + assert(NULL != device2d_); + + NPDeviceContext2DConfig config; + NPDeviceContext2D context; + device2d_->initializeContext(npp_, &config, &context); + + DrawSampleBitmap(&context, 400, 400); + + // TODO(brettw) figure out why this cast is necessary, the functions seem to + // match. Could be a calling convention mismatch? + NPDeviceFlushContextCallbackPtr callback = + reinterpret_cast<NPDeviceFlushContextCallbackPtr>(&FlushCallback); + device2d_->flushContext(npp_, &context, callback, NULL); +} + +PluginObject::~PluginObject() { + browser->releaseobject(test_object_); +} + +// static +NPClass* PluginObject::GetPluginClass() { + return &plugin_class; +} + +void PluginObject::SetWindow(const NPWindow& window) { + NPDeviceContext2DConfig config; + NPDeviceContext2D context; + device2d_->initializeContext(npp_, &config, &context); + + DrawSampleBitmap(&context, window.width, window.height); + + // TODO(brettw) figure out why this cast is necessary, the functions seem to + // match. Could be a calling convention mismatch? + NPDeviceFlushContextCallbackPtr callback = + reinterpret_cast<NPDeviceFlushContextCallbackPtr>(&FlushCallback); + device2d_->flushContext(npp_, &context, callback, NULL); +} diff --git a/src/gui/pepper/plugin_object.h b/src/gui/pepper/plugin_object.h new file mode 100644 index 0000000000..787ed421a3 --- /dev/null +++ b/src/gui/pepper/plugin_object.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NATIVE_CLIENT_TESTS_PEPPER_PLUGIN_PLUGIN_OBJECT_H_ +#define NATIVE_CLIENT_TESTS_PEPPER_PLUGIN_PLUGIN_OBJECT_H_ + +#include <nacl/npapi.h> +#include <nacl/npruntime.h> +#define size_t int // #### why? +#include <nacl/npapi_extensions.h> +#undef size_t +#include <nacl/npupp.h> + +extern NPNetscapeFuncs* browser; + +class PluginObject { + public: + explicit PluginObject(NPP npp); + ~PluginObject(); + + static NPClass* GetPluginClass(); + + NPObject* header() { return &header_; } + NPP npp() const { return npp_; } + + void SetWindow(const NPWindow& window); + + private: + NPObject header_; + NPP npp_; + NPObject* test_object_; + + NPDevice* device2d_; +}; + + +#endif // NATIVE_CLIENT_TESTS_PEPPER_PLUGIN_PLUGIN_OBJECT_H_ diff --git a/src/gui/pepper/test_object.cc b/src/gui/pepper/test_object.cc new file mode 100644 index 0000000000..e42c149cd2 --- /dev/null +++ b/src/gui/pepper/test_object.cc @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "test_object.h" + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "plugin_object.h" + +static bool testEnumerate(NPObject*, NPIdentifier **value, uint32_t *count); +static bool testHasMethod(NPObject*, NPIdentifier name); +static bool testInvoke(NPObject* header, + NPIdentifier name, + const NPVariant* args, + uint32_t argCount, + NPVariant* result); +static bool testInvokeDefault(NPObject*, + const NPVariant *args, + uint32_t argCount, + NPVariant *result); +static bool testHasProperty(NPObject*, NPIdentifier name); +static bool testGetProperty(NPObject*, NPIdentifier name, NPVariant *variant); +static NPObject *testAllocate(NPP npp, NPClass *theClass); +static void testDeallocate(NPObject* obj); +static bool testConstruct(NPObject* npobj, + const NPVariant* args, + uint32_t argCount, + NPVariant* result); + +static NPClass testClass = { + NP_CLASS_STRUCT_VERSION, + testAllocate, + testDeallocate, + 0, + testHasMethod, + testInvoke, + testInvokeDefault, + testHasProperty, + testGetProperty, + 0, + 0, + testEnumerate, + testConstruct +}; + +NPClass* GetTestClass() { + return &testClass; +} + +int testObjectCount = 0; + +int GetTestObjectCount() { + return testObjectCount; +} + +static bool identifiersInitialized = false; + +#define NUM_ENUMERABLE_TEST_IDENTIFIERS 4 +#define NUM_TEST_IDENTIFIERS 5 + +#define ID_PROPERTY_FOO 0 +#define ID_PROPERTY_BAR 1 +#define ID_PROPERTY_TEST_OBJECT 2 +#define ID_PROPERTY_REF_COUNT 3 +#define ID_PROPERTY_OBJECT_POINTER 4 + +static NPIdentifier testIdentifiers[NUM_TEST_IDENTIFIERS]; +static const NPUTF8 *testIdentifierNames[NUM_TEST_IDENTIFIERS] = { + "foo", + "bar", + "testObject", + "refCount", + "objectPointer", +}; + +#define ID_THROW_EXCEPTION_METHOD 0 +#define NUM_METHOD_IDENTIFIERS 1 + +static NPIdentifier testMethodIdentifiers[NUM_METHOD_IDENTIFIERS]; +static const NPUTF8 *testMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = { + "throwException", +}; + +static void initializeIdentifiers(void) { + browser->getstringidentifiers(testIdentifierNames, + NUM_TEST_IDENTIFIERS, + testIdentifiers); + browser->getstringidentifiers(testMethodIdentifierNames, + NUM_METHOD_IDENTIFIERS, + testMethodIdentifiers); +} + +static NPObject *testAllocate(NPP npp, NPClass *theClass) { + TestObject *newInstance = + static_cast<TestObject*>(malloc(sizeof(TestObject))); + newInstance->test_object = NULL; + ++testObjectCount; + + if (!identifiersInitialized) { + identifiersInitialized = true; + initializeIdentifiers(); + } + + return reinterpret_cast<NPObject*>(newInstance); +} + +static void testDeallocate(NPObject *obj) { + TestObject *testObject = reinterpret_cast<TestObject*>(obj); + if (testObject->test_object) + browser->releaseobject(testObject->test_object); + --testObjectCount; + free(obj); +} + +static bool testHasMethod(NPObject*, NPIdentifier name) { + for (unsigned i = 0; i < NUM_METHOD_IDENTIFIERS; i++) { + if (testMethodIdentifiers[i] == name) + return true; + } + return false; +} + +static bool testInvoke(NPObject* header, + NPIdentifier name, + const NPVariant* args, + uint32_t argCount, + NPVariant* result) { + if (name == testMethodIdentifiers[ID_THROW_EXCEPTION_METHOD]) { + browser->setexception(header, "test object throwException SUCCESS"); + return true; + } + return false; +} + +static bool testInvokeDefault(NPObject *obj, + const NPVariant *args, + uint32_t argCount, + NPVariant *result) { + INT32_TO_NPVARIANT(2, *result); + return true; +} + +static bool testHasProperty(NPObject*, NPIdentifier name) { + for (unsigned i = 0; i < NUM_TEST_IDENTIFIERS; i++) { + if (testIdentifiers[i] == name) + return true; + } + return false; +} + +static bool testGetProperty(NPObject *obj, + NPIdentifier name, + NPVariant *variant) { + if (name == testIdentifiers[ID_PROPERTY_FOO]) { + const size_t kFooLength = 4; + char* mem = static_cast<char*>(browser->memalloc(kFooLength)); + snprintf(mem, kFooLength, "foo"); + STRINGZ_TO_NPVARIANT(mem, *variant); + return true; + } else if (name == testIdentifiers[ID_PROPERTY_BAR]) { + BOOLEAN_TO_NPVARIANT(true, *variant); + return true; + } else if (name == testIdentifiers[ID_PROPERTY_TEST_OBJECT]) { + TestObject* testObject = reinterpret_cast<TestObject*>(obj); + if (testObject->test_object == NULL) + testObject->test_object = browser->createobject(NULL, &testClass); + browser->retainobject(testObject->test_object); + OBJECT_TO_NPVARIANT(testObject->test_object, *variant); + return true; + } else if (name == testIdentifiers[ID_PROPERTY_REF_COUNT]) { + INT32_TO_NPVARIANT(obj->referenceCount, *variant); + return true; + } else if (name == testIdentifiers[ID_PROPERTY_OBJECT_POINTER]) { + int32_t objectPointer = + static_cast<int32_t>(reinterpret_cast<uintptr_t>(obj)); + INT32_TO_NPVARIANT(objectPointer, *variant); + return true; + } + return false; +} + +static bool testEnumerate(NPObject *npobj, + NPIdentifier **value, + uint32_t *count) { + *count = NUM_ENUMERABLE_TEST_IDENTIFIERS; + const size_t kTotalSize = *count * sizeof(NPIdentifier); + + *value = reinterpret_cast<NPIdentifier*>(browser->memalloc(kTotalSize)); + memcpy(*value, testIdentifiers, kTotalSize); + + return true; +} + +static bool testConstruct(NPObject* npobj, + const NPVariant* args, + uint32_t argCount, + NPVariant* result) { + browser->retainobject(npobj); + + // Just return the same object. + OBJECT_TO_NPVARIANT(npobj, *result); + return true; +} diff --git a/src/gui/pepper/test_object.h b/src/gui/pepper/test_object.h new file mode 100644 index 0000000000..24555adbf8 --- /dev/null +++ b/src/gui/pepper/test_object.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NATIVE_CLIENT_TESTS_PEPPER_PLUGIN_TEST_OBJECT_H_ +#define NATIVE_CLIENT_TESTS_PEPPER_PLUGIN_TEST_OBJECT_H_ + +#include "third_party/npapi/bindings/npapi.h" +#include "third_party/npapi/bindings/npruntime.h" + + +struct TestObject { + NPObject header; + NPObject* test_object; +}; + +NPClass* GetTestClass(); +int GetTestObjectCount(); + +#endif // NATIVE_CLIENT_TESTS_PEPPER_PLUGIN_TEST_OBJECT_H_ |