Delete browserplugin sample. do not merge
It doesn't build in all environments. Change-Id: I96fbb28e1bea44656ff6cfb9002eedfd5471612e
This commit is contained in:
@@ -1,38 +0,0 @@
|
||||
# Copyright (C) 2009 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
TOP_LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
# Build application
|
||||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
|
||||
LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
||||
|
||||
LOCAL_PROGUARD_ENABLED := disabled
|
||||
|
||||
LOCAL_PACKAGE_NAME := SampleBrowserPlugin
|
||||
|
||||
LOCAL_JNI_SHARED_LIBRARIES := libsampleplugin
|
||||
|
||||
include $(BUILD_PACKAGE)
|
||||
|
||||
# ============================================================
|
||||
|
||||
# Also build all of the sub-targets under this one: the shared library.
|
||||
include $(call all-makefiles-under,$(LOCAL_PATH))
|
||||
@@ -1,36 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2009 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.sampleplugin"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
|
||||
<uses-permission android:name="android.webkit.permission.PLUGIN"/>
|
||||
|
||||
<uses-sdk android:minSdkVersion="3" />
|
||||
|
||||
<application android:icon="@drawable/sample_browser_plugin"
|
||||
android:label="@string/sample_browser_plugin">
|
||||
<service android:name=".SamplePlugin">
|
||||
<intent-filter>
|
||||
<action android:name="android.webkit.PLUGIN" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="type" android:value="native" />
|
||||
</service>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -1,190 +0,0 @@
|
||||
|
||||
Copyright (c) 2005-2008, The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
@@ -1,177 +0,0 @@
|
||||
# Copyright (C) 2009 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################
|
||||
######### CONTENTS ###########
|
||||
A. INTRODUCTION
|
||||
B. PLUGIN STRUCTURE
|
||||
C. HOW TO DEPLOY
|
||||
D. SUB-PLUGINS
|
||||
1. ANIMATION
|
||||
2. AUDIO
|
||||
3. BACKGROUND
|
||||
4. FORM
|
||||
5. PAINT
|
||||
|
||||
|
||||
##############################
|
||||
## (A) INTRODUCTION ##########
|
||||
|
||||
The sample plugin is intended to give plugin developers a point of reference to
|
||||
see how an android browser plugin is created and how to use the available APIs.
|
||||
A plugin is packaged like a standard apk and can be installed either via the
|
||||
market or adb. The sample plugin attempts to exercise as many of the APIs as
|
||||
possible but unfortunately not all are covered.
|
||||
|
||||
Trying to have a single plugin demonstrate all possible API interactions on one
|
||||
screen was not practical. On the other hand we also didn't want a separate
|
||||
plugin for each interction, as that would result in many separate apk's that
|
||||
would need to be maintained. To solve this problem we developed the idea to use
|
||||
"sub-plugins". With a sub-plugin only one specific feature of the plugin would
|
||||
be active at a time, but they would all share as much common code as possible.
|
||||
A detailed description of each sub-plugin and its function can be found in the
|
||||
sub-plugins section.
|
||||
|
||||
##############################
|
||||
## (B) PLUGIN STRUCTURE ######
|
||||
|
||||
The sample plugin is packaged as one plugin but contains many unique sub-plugins
|
||||
(e.g. audio and paint). The package consists of two pieces: (1) Java code
|
||||
containing the config; (2) C++ shared library containing the brower/plugin
|
||||
bindings and the sub-plugin classes.
|
||||
|
||||
~~~~ (1) JAVA ~~~~~
|
||||
Android.mk: specifies the name of the APK (SampleBrowserPlugin) as well as which
|
||||
shared libraries to include.
|
||||
|
||||
AndroidManifest.xml: similar to a standard android manifest file, except that it
|
||||
must contain the "uses-permission" and "service"
|
||||
elements that are plugin specific. The "service" element
|
||||
contains sub-elements that describe the java component of
|
||||
the service.
|
||||
|
||||
src/*: location of the java source files. This contains the SamplePlugin.class
|
||||
which is the java component of our plugin. The component must exist and
|
||||
implement the required interfaces, though simply returning null is valid.
|
||||
|
||||
res/*: location of the static resources (e.g. an icon for the plugin)
|
||||
|
||||
~~~~ (2) C++ ~~~~~
|
||||
jni/Android.mk: specifies the build parameters for the shared library that is to
|
||||
be included with the apk. The library contains all the bindings
|
||||
between the plugin and the browser.
|
||||
|
||||
jni/main.*: this code is the binding point between the plugin and the browser.
|
||||
It supports all of the functions required for a standard netscape
|
||||
style plugin as well as all the android specific APIs. The initial
|
||||
starting point for the plugin is the NP_Initialize function. The
|
||||
NPP_New function is responsible for reading the input args and
|
||||
selecting the appropriate sub-plugin to instantiate. Most other
|
||||
functions either return fixed values or pass their inputs to the
|
||||
sub-plugin for processing.
|
||||
|
||||
jni/PluginObject.*: The pluginObject provides a convenient container in which to
|
||||
store variables (the plugin's state). This objects two main
|
||||
responsibilities are (1) to construct and store the NPClass
|
||||
object (done using code provided by Apple) and (2) provide
|
||||
the abstract class for the sub-plugin objects and a place to
|
||||
store the sub-plugin after it is instantiated.
|
||||
|
||||
jni/*/*: Each of the sub-plugins has a folder that contains its class definition
|
||||
and logic. The sub-plugin receives events from the browser and it can
|
||||
also communicate with the browser using the netscape plugin functions
|
||||
as well as the specialized android interfaces.
|
||||
|
||||
|
||||
##############################
|
||||
## (C) HOW TO DEPLOY #########
|
||||
|
||||
To compile and install a plugin on a device/emulator simply...
|
||||
|
||||
1. run "make SampleBrowserPlugin" (compiles libsampleplugin.so and builds the apk)
|
||||
2. the previous command produces an apk file so record its location
|
||||
3. run "adb install [apk_file]" to install it on a device/emulator
|
||||
4. the browser will auto recognize the plugin is available
|
||||
|
||||
Now that the plugin is installed you can manage it just like you would any other
|
||||
application via Settings -> Applications -> Manage applications. To execute the
|
||||
plugin you need to include an html snippet (similar to the one found below) in
|
||||
a document that is accessible by the browser. The mime-type cannot change but
|
||||
you can change the width, height, and parameters. The parameters are used to
|
||||
notify the plugin which sub-plugin to execute and which drawing model to use.
|
||||
|
||||
<object type="application/x-testbrowserplugin" height=50 width=250>
|
||||
<param name="DrawingModel" value="Surface" />
|
||||
<param name="PluginType" value="Background" />
|
||||
</object>
|
||||
|
||||
|
||||
##############################
|
||||
## (D) SUB-PLUGINS ###########
|
||||
|
||||
Each sub-plugin corresponds to exactly one plugin type and can support one or
|
||||
more drawing models. In the subsections below there are descriptions of each of
|
||||
the sub-plugins as well as the information required to create the html snippets.
|
||||
|
||||
#######################
|
||||
## (D1) ANIMATION #####
|
||||
|
||||
PLUGIN TYPE: Animation
|
||||
DRAWING MODEL: Bitmap
|
||||
|
||||
This plugin draws a ball bouncing around the screen. If the plugin is not entirely
|
||||
on the screen and it it touched, then it will attempt to center itself on screen.
|
||||
|
||||
#######################
|
||||
## (D2) AUDIO #########
|
||||
|
||||
PLUGIN TYPE: Audio
|
||||
DRAWING MODEL: Bitmap
|
||||
|
||||
This plugin plays a raw audio file located at /sdcard/sample.raw (need to supply
|
||||
your own). It uses touch to trigger the play, pause, and stop buttons.
|
||||
|
||||
#######################
|
||||
## (D3) BACKGROUND ####
|
||||
|
||||
PLUGIN TYPE: Background
|
||||
DRAWING MODEL: Surface
|
||||
|
||||
This plugin has minimal visual components but mainly runs API tests in the
|
||||
background. The plugin handles scaling its own bitmap on zoom which in this
|
||||
case is a simple string of text. The output of this plugin is found in the logs
|
||||
as it prints errors if it detects any API failures. Some of the API's tested are
|
||||
timers, javascript access, and bitmap formatting.
|
||||
|
||||
#######################
|
||||
## (D4) FORM ##########
|
||||
|
||||
PLUGIN TYPE: Form
|
||||
DRAWING MODEL: Bitmap
|
||||
|
||||
This plugin mimics a simple username/password form. You can select a textbox by
|
||||
either touching it or using the navigation keys. Once selected the box will
|
||||
highlight and the keyboard will appear. If the textbox selected is not fully
|
||||
in view then the plugin will ensure it is centered on the screen.
|
||||
|
||||
#######################
|
||||
## (D5) PAINT #########
|
||||
|
||||
PLUGIN TYPE: Paint
|
||||
DRAWING MODEL: Surface
|
||||
|
||||
This plugin provides a surface that the user can "paint" on. The inputs method
|
||||
can be toggled between mouse (dots) and touch (lines). This plugin has a fixed
|
||||
surface and allows the browser to scale the surface when zooming.
|
||||
@@ -1,68 +0,0 @@
|
||||
##
|
||||
##
|
||||
## Copyright 2008, The Android Open Source Project
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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.
|
||||
##
|
||||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
main.cpp \
|
||||
PluginObject.cpp \
|
||||
animation/AnimationPlugin.cpp \
|
||||
audio/AudioPlugin.cpp \
|
||||
background/BackgroundPlugin.cpp \
|
||||
form/FormPlugin.cpp \
|
||||
navigation/NavigationPlugin.cpp \
|
||||
paint/PaintPlugin.cpp \
|
||||
video/VideoPlugin.cpp \
|
||||
jni-bridge.cpp \
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(JNI_H_INCLUDE) \
|
||||
$(LOCAL_PATH) \
|
||||
$(LOCAL_PATH)/animation \
|
||||
$(LOCAL_PATH)/audio \
|
||||
$(LOCAL_PATH)/background \
|
||||
$(LOCAL_PATH)/form \
|
||||
$(LOCAL_PATH)/navigation \
|
||||
$(LOCAL_PATH)/paint \
|
||||
$(LOCAL_PATH)/video \
|
||||
external/webkit/WebCore/bridge \
|
||||
external/webkit/WebCore/plugins \
|
||||
external/webkit/WebCore/platform/android/JavaVM \
|
||||
external/webkit/WebKit/android/plugins
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libnativehelper
|
||||
|
||||
LOCAL_CFLAGS += -fvisibility=hidden
|
||||
LOCAL_PRELINK_MODULE:=false
|
||||
|
||||
LOCAL_MODULE:= libsampleplugin
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
@@ -1,211 +0,0 @@
|
||||
/*
|
||||
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 "main.h"
|
||||
#include "PluginObject.h"
|
||||
|
||||
int SubPlugin::getPluginWidth() {
|
||||
PluginObject *obj = (PluginObject*) inst()->pdata;
|
||||
return obj->window->width;
|
||||
}
|
||||
|
||||
int SubPlugin::getPluginHeight() {
|
||||
PluginObject *obj = (PluginObject*) inst()->pdata;
|
||||
return obj->window->height;
|
||||
}
|
||||
|
||||
bool SurfaceSubPlugin::supportsDrawingModel(ANPDrawingModel model) {
|
||||
return (model == kSurface_ANPDrawingModel);
|
||||
}
|
||||
|
||||
void SurfaceSubPlugin::setContext(jobject context) {
|
||||
JNIEnv* env = NULL;
|
||||
if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
|
||||
|
||||
// if one exists then free its global reference
|
||||
if (m_context) {
|
||||
env->DeleteGlobalRef(m_context);
|
||||
m_context = NULL;
|
||||
}
|
||||
|
||||
// create a new global ref
|
||||
if (context) {
|
||||
context = env->NewGlobalRef(context);
|
||||
}
|
||||
|
||||
// set the value
|
||||
m_context = context;
|
||||
}
|
||||
}
|
||||
|
||||
static void pluginInvalidate(NPObject *obj);
|
||||
static bool pluginHasProperty(NPObject *obj, NPIdentifier name);
|
||||
static bool pluginHasMethod(NPObject *obj, NPIdentifier name);
|
||||
static bool pluginGetProperty(NPObject *obj, NPIdentifier name, NPVariant *variant);
|
||||
static bool pluginSetProperty(NPObject *obj, NPIdentifier name, const NPVariant *variant);
|
||||
static bool pluginInvoke(NPObject *obj, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result);
|
||||
static bool pluginInvokeDefault(NPObject *obj, const NPVariant *args, uint32_t argCount, NPVariant *result);
|
||||
static NPObject *pluginAllocate(NPP npp, NPClass *theClass);
|
||||
static void pluginDeallocate(NPObject *obj);
|
||||
static bool pluginRemoveProperty(NPObject *npobj, NPIdentifier name);
|
||||
static bool pluginEnumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count);
|
||||
|
||||
|
||||
|
||||
static NPClass pluginClass = {
|
||||
NP_CLASS_STRUCT_VERSION,
|
||||
pluginAllocate,
|
||||
pluginDeallocate,
|
||||
pluginInvalidate,
|
||||
pluginHasMethod,
|
||||
pluginInvoke,
|
||||
pluginInvokeDefault,
|
||||
pluginHasProperty,
|
||||
pluginGetProperty,
|
||||
pluginSetProperty,
|
||||
pluginRemoveProperty,
|
||||
pluginEnumerate
|
||||
};
|
||||
|
||||
NPClass *getPluginClass(void)
|
||||
{
|
||||
return &pluginClass;
|
||||
}
|
||||
|
||||
static bool identifiersInitialized = false;
|
||||
|
||||
#define ID_TESTFILE_PROPERTY 0
|
||||
#define NUM_PROPERTY_IDENTIFIERS 1
|
||||
|
||||
static NPIdentifier pluginPropertyIdentifiers[NUM_PROPERTY_IDENTIFIERS];
|
||||
static const NPUTF8 *pluginPropertyIdentifierNames[NUM_PROPERTY_IDENTIFIERS] = {
|
||||
"testfile"
|
||||
};
|
||||
|
||||
#define ID_GETTESTFILE_METHOD 0
|
||||
#define NUM_METHOD_IDENTIFIERS 1
|
||||
|
||||
static NPIdentifier pluginMethodIdentifiers[NUM_METHOD_IDENTIFIERS];
|
||||
static const NPUTF8 *pluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
|
||||
"getTestFile"
|
||||
};
|
||||
|
||||
static void initializeIdentifiers(void)
|
||||
{
|
||||
browser->getstringidentifiers(pluginPropertyIdentifierNames, NUM_PROPERTY_IDENTIFIERS, pluginPropertyIdentifiers);
|
||||
browser->getstringidentifiers(pluginMethodIdentifierNames, NUM_METHOD_IDENTIFIERS, pluginMethodIdentifiers);
|
||||
}
|
||||
|
||||
static bool pluginHasProperty(NPObject *obj, NPIdentifier name)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < NUM_PROPERTY_IDENTIFIERS; i++)
|
||||
if (name == pluginPropertyIdentifiers[i])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool pluginHasMethod(NPObject *obj, NPIdentifier name)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < NUM_METHOD_IDENTIFIERS; i++)
|
||||
if (name == pluginMethodIdentifiers[i])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool pluginGetProperty(NPObject *obj, NPIdentifier name, NPVariant *variant)
|
||||
{
|
||||
PluginObject *plugin = (PluginObject *)obj;
|
||||
if (name == pluginPropertyIdentifiers[ID_TESTFILE_PROPERTY]) {
|
||||
BOOLEAN_TO_NPVARIANT(true, *variant);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool pluginSetProperty(NPObject *obj, NPIdentifier name, const NPVariant *variant)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool pluginInvoke(NPObject *obj, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result)
|
||||
{
|
||||
PluginObject *plugin = (PluginObject *)obj;
|
||||
if (name == pluginMethodIdentifiers[ID_GETTESTFILE_METHOD]) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool pluginInvokeDefault(NPObject *obj, const NPVariant *args, uint32_t argCount, NPVariant *result)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static void pluginInvalidate(NPObject *obj)
|
||||
{
|
||||
// Release any remaining references to JavaScript objects.
|
||||
}
|
||||
|
||||
static NPObject *pluginAllocate(NPP npp, NPClass *theClass)
|
||||
{
|
||||
PluginObject *newInstance = (PluginObject*) malloc(sizeof(PluginObject));
|
||||
newInstance->header._class = theClass;
|
||||
newInstance->header.referenceCount = 1;
|
||||
|
||||
if (!identifiersInitialized) {
|
||||
identifiersInitialized = true;
|
||||
initializeIdentifiers();
|
||||
}
|
||||
|
||||
newInstance->npp = npp;
|
||||
|
||||
return &newInstance->header;
|
||||
}
|
||||
|
||||
static void pluginDeallocate(NPObject *obj)
|
||||
{
|
||||
free(obj);
|
||||
}
|
||||
|
||||
static bool pluginRemoveProperty(NPObject *npobj, NPIdentifier name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool pluginEnumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
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<6C>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.
|
||||
*/
|
||||
|
||||
#ifndef PluginObject__DEFINED
|
||||
#define PluginObject__DEFINED
|
||||
|
||||
#include "main.h"
|
||||
#include <jni.h>
|
||||
|
||||
enum CustomEventTypes {
|
||||
kSurfaceCreated_CustomEvent = 0,
|
||||
kSurfaceChanged_CustomEvent = 1,
|
||||
kSurfaceDestroyed_CustomEvent = 2,
|
||||
};
|
||||
typedef int32_t CustomEventType;
|
||||
|
||||
class SubPlugin {
|
||||
public:
|
||||
SubPlugin(NPP inst) : m_inst(inst) {}
|
||||
virtual ~SubPlugin() {}
|
||||
virtual int16 handleEvent(const ANPEvent* evt) = 0;
|
||||
virtual bool supportsDrawingModel(ANPDrawingModel) = 0;
|
||||
|
||||
int getPluginWidth();
|
||||
int getPluginHeight();
|
||||
|
||||
NPP inst() const { return m_inst; }
|
||||
|
||||
private:
|
||||
NPP m_inst;
|
||||
};
|
||||
|
||||
class SurfaceSubPlugin : public SubPlugin {
|
||||
public:
|
||||
SurfaceSubPlugin(NPP inst) : SubPlugin(inst) { m_context = NULL; }
|
||||
virtual ~SurfaceSubPlugin() {}
|
||||
virtual jobject getSurface() = 0;
|
||||
virtual bool supportsDrawingModel(ANPDrawingModel);
|
||||
|
||||
void setContext(jobject context);
|
||||
|
||||
jobject m_context;
|
||||
};
|
||||
|
||||
enum PluginTypes {
|
||||
kAnimation_PluginType = 1,
|
||||
kAudio_PluginType = 2,
|
||||
kBackground_PluginType = 3,
|
||||
kForm_PluginType = 4,
|
||||
kText_PluginType = 5,
|
||||
kPaint_PluginType = 6,
|
||||
kVideo_PluginType = 7,
|
||||
kNavigation_PluginType = 8,
|
||||
};
|
||||
typedef uint32_t PluginType;
|
||||
|
||||
typedef struct PluginObject {
|
||||
NPObject header;
|
||||
NPP npp;
|
||||
NPWindow* window;
|
||||
|
||||
PluginType pluginType;
|
||||
SubPlugin* activePlugin;
|
||||
|
||||
} PluginObject;
|
||||
|
||||
NPClass *getPluginClass(void);
|
||||
|
||||
#endif // PluginObject__DEFINED
|
||||
@@ -1,197 +0,0 @@
|
||||
/*
|
||||
* Copyright 2008, The Android Open Source Project
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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 "AnimationPlugin.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
extern NPNetscapeFuncs* browser;
|
||||
extern ANPLogInterfaceV0 gLogI;
|
||||
extern ANPCanvasInterfaceV0 gCanvasI;
|
||||
extern ANPPaintInterfaceV0 gPaintI;
|
||||
extern ANPPathInterfaceV0 gPathI;
|
||||
extern ANPWindowInterfaceV0 gWindowI;
|
||||
|
||||
static uint16 rnd16(float x, int inset) {
|
||||
int ix = (int)roundf(x) + inset;
|
||||
if (ix < 0) {
|
||||
ix = 0;
|
||||
}
|
||||
return static_cast<uint16>(ix);
|
||||
}
|
||||
|
||||
static void inval(NPP instance, const ANPRectF& r, bool doAA) {
|
||||
const int inset = doAA ? -1 : 0;
|
||||
|
||||
NPRect inval;
|
||||
inval.left = rnd16(r.left, inset);
|
||||
inval.top = rnd16(r.top, inset);
|
||||
inval.right = rnd16(r.right, -inset);
|
||||
inval.bottom = rnd16(r.bottom, -inset);
|
||||
browser->invalidaterect(instance, &inval);
|
||||
}
|
||||
|
||||
static void bounce(float* x, float* dx, const float max) {
|
||||
*x += *dx;
|
||||
if (*x < 0) {
|
||||
*x = 0;
|
||||
if (*dx < 0) {
|
||||
*dx = -*dx;
|
||||
}
|
||||
} else if (*x > max) {
|
||||
*x = max;
|
||||
if (*dx > 0) {
|
||||
*dx = -*dx;
|
||||
}
|
||||
}
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BallAnimation::BallAnimation(NPP inst) : SubPlugin(inst) {
|
||||
m_x = m_y = 0;
|
||||
m_dx = 7 * SCALE;
|
||||
m_dy = 5 * SCALE;
|
||||
|
||||
memset(&m_oval, 0, sizeof(m_oval));
|
||||
|
||||
m_paint = gPaintI.newPaint();
|
||||
gPaintI.setFlags(m_paint, gPaintI.getFlags(m_paint) | kAntiAlias_ANPPaintFlag);
|
||||
gPaintI.setColor(m_paint, 0xFFFF0000);
|
||||
|
||||
//register for touch events
|
||||
ANPEventFlags flags = kTouch_ANPEventFlag;
|
||||
NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
|
||||
if (err != NPERR_NO_ERROR) {
|
||||
gLogI.log(kError_ANPLogType, "Error selecting input events.");
|
||||
}
|
||||
}
|
||||
|
||||
BallAnimation::~BallAnimation() {
|
||||
gPaintI.deletePaint(m_paint);
|
||||
}
|
||||
|
||||
bool BallAnimation::supportsDrawingModel(ANPDrawingModel model) {
|
||||
return (model == kBitmap_ANPDrawingModel);
|
||||
}
|
||||
|
||||
void BallAnimation::drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip) {
|
||||
|
||||
// create a canvas
|
||||
ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
|
||||
|
||||
// clip the canvas
|
||||
ANPRectF clipR;
|
||||
clipR.left = clip.left;
|
||||
clipR.top = clip.top;
|
||||
clipR.right = clip.right;
|
||||
clipR.bottom = clip.bottom;
|
||||
gCanvasI.clipRect(canvas, &clipR);
|
||||
|
||||
// setup variables
|
||||
PluginObject *obj = (PluginObject*) inst()->pdata;
|
||||
const float OW = 20;
|
||||
const float OH = 20;
|
||||
const int W = obj->window->width;
|
||||
const int H = obj->window->height;
|
||||
|
||||
// paint the canvas (using the path API)
|
||||
gCanvasI.drawColor(canvas, 0xFFFFFFFF);
|
||||
{
|
||||
ANPPath* path = gPathI.newPath();
|
||||
|
||||
float cx = W * 0.5f;
|
||||
float cy = H * 0.5f;
|
||||
gPathI.moveTo(path, 0, 0);
|
||||
gPathI.quadTo(path, cx, cy, W, 0);
|
||||
gPathI.quadTo(path, cx, cy, W, H);
|
||||
gPathI.quadTo(path, cx, cy, 0, H);
|
||||
gPathI.quadTo(path, cx, cy, 0, 0);
|
||||
|
||||
gPaintI.setColor(m_paint, 0xFF0000FF);
|
||||
gCanvasI.drawPath(canvas, path, m_paint);
|
||||
|
||||
ANPRectF bounds;
|
||||
memset(&bounds, 0, sizeof(bounds));
|
||||
gPathI.getBounds(path, &bounds);
|
||||
gPathI.deletePath(path);
|
||||
}
|
||||
|
||||
// draw the oval
|
||||
inval(inst(), m_oval, true); // inval the old
|
||||
m_oval.left = m_x;
|
||||
m_oval.top = m_y;
|
||||
m_oval.right = m_x + OW;
|
||||
m_oval.bottom = m_y + OH;
|
||||
inval(inst(), m_oval, true); // inval the new
|
||||
gPaintI.setColor(m_paint, 0xFFFF0000);
|
||||
gCanvasI.drawOval(canvas, &m_oval, m_paint);
|
||||
|
||||
// update the coordinates of the oval
|
||||
bounce(&m_x, &m_dx, obj->window->width - OW);
|
||||
bounce(&m_y, &m_dy, obj->window->height - OH);
|
||||
|
||||
// delete the canvas
|
||||
gCanvasI.deleteCanvas(canvas);
|
||||
}
|
||||
|
||||
void BallAnimation::showEntirePluginOnScreen() {
|
||||
NPP instance = this->inst();
|
||||
PluginObject *obj = (PluginObject*) instance->pdata;
|
||||
NPWindow *window = obj->window;
|
||||
|
||||
ANPRectI visibleRects[1];
|
||||
|
||||
visibleRects[0].left = 0;
|
||||
visibleRects[0].top = 0;
|
||||
visibleRects[0].right = window->width;
|
||||
visibleRects[0].bottom = window->height;
|
||||
|
||||
gWindowI.setVisibleRects(instance, visibleRects, 1);
|
||||
gWindowI.clearVisibleRects(instance);
|
||||
}
|
||||
|
||||
int16 BallAnimation::handleEvent(const ANPEvent* evt) {
|
||||
NPP instance = this->inst();
|
||||
|
||||
switch (evt->eventType) {
|
||||
case kDraw_ANPEventType:
|
||||
switch (evt->data.draw.model) {
|
||||
case kBitmap_ANPDrawingModel:
|
||||
drawPlugin(evt->data.draw.data.bitmap, evt->data.draw.clip);
|
||||
return 1;
|
||||
default:
|
||||
break; // unknown drawing model
|
||||
}
|
||||
case kTouch_ANPEventType:
|
||||
if (kDown_ANPTouchAction == evt->data.touch.action) {
|
||||
showEntirePluginOnScreen();
|
||||
}
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0; // unknown or unhandled event
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright 2008, The Android Open Source Project
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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 "PluginObject.h"
|
||||
|
||||
#ifndef pluginGraphics__DEFINED
|
||||
#define pluginGraphics__DEFINED
|
||||
|
||||
class BallAnimation : public SubPlugin {
|
||||
public:
|
||||
BallAnimation(NPP inst);
|
||||
virtual ~BallAnimation();
|
||||
virtual bool supportsDrawingModel(ANPDrawingModel);
|
||||
virtual int16 handleEvent(const ANPEvent* evt);
|
||||
private:
|
||||
void drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip);
|
||||
void showEntirePluginOnScreen();
|
||||
|
||||
float m_x;
|
||||
float m_y;
|
||||
float m_dx;
|
||||
float m_dy;
|
||||
|
||||
ANPRectF m_oval;
|
||||
ANPPaint* m_paint;
|
||||
|
||||
static const float SCALE = 0.1;
|
||||
};
|
||||
|
||||
#endif // pluginGraphics__DEFINED
|
||||
@@ -1,382 +0,0 @@
|
||||
/*
|
||||
* Copyright 2008, The Android Open Source Project
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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 "AudioPlugin.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
extern NPNetscapeFuncs* browser;
|
||||
extern ANPLogInterfaceV0 gLogI;
|
||||
extern ANPCanvasInterfaceV0 gCanvasI;
|
||||
extern ANPPaintInterfaceV0 gPaintI;
|
||||
extern ANPAudioTrackInterfaceV0 gSoundI;
|
||||
extern ANPTypefaceInterfaceV0 gTypefaceI;
|
||||
|
||||
|
||||
static void inval(NPP instance) {
|
||||
browser->invalidaterect(instance, NULL);
|
||||
}
|
||||
|
||||
static uint16 rnd16(float x, int inset) {
|
||||
int ix = (int)roundf(x) + inset;
|
||||
if (ix < 0) {
|
||||
ix = 0;
|
||||
}
|
||||
return static_cast<uint16>(ix);
|
||||
}
|
||||
|
||||
static void inval(NPP instance, const ANPRectF& r, bool doAA) {
|
||||
const int inset = doAA ? -1 : 0;
|
||||
|
||||
PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
|
||||
NPRect inval;
|
||||
inval.left = rnd16(r.left, inset);
|
||||
inval.top = rnd16(r.top, inset);
|
||||
inval.right = rnd16(r.right, -inset);
|
||||
inval.bottom = rnd16(r.bottom, -inset);
|
||||
browser->invalidaterect(instance, &inval);
|
||||
}
|
||||
|
||||
static void audioCallback(ANPAudioEvent evt, void* user, ANPAudioBuffer* buffer) {
|
||||
switch (evt) {
|
||||
case kMoreData_ANPAudioEvent: {
|
||||
SoundPlay* play = reinterpret_cast<SoundPlay*>(user);
|
||||
size_t amount = fread(buffer->bufferData, 1, buffer->size, play->file);
|
||||
buffer->size = amount;
|
||||
if (amount == 0) {
|
||||
gSoundI.stop(play->track);
|
||||
fclose(play->file);
|
||||
play->file = NULL;
|
||||
// TODO need to notify our main thread to delete the track now
|
||||
}
|
||||
|
||||
if (play->fileSize > 0) {
|
||||
// TODO we need to properly update the progress value
|
||||
play->progress = 1;
|
||||
inval(play->instance);
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AudioPlugin::AudioPlugin(NPP inst) : SubPlugin(inst) {
|
||||
|
||||
const char path[] = "/sdcard/sample.raw";
|
||||
|
||||
// open a file stream
|
||||
FILE* f = fopen(path, "r");
|
||||
gLogI.log(kDebug_ANPLogType, "--- path %s FILE %p", path, f);
|
||||
|
||||
// setup our private audio struct's default values
|
||||
m_soundPlay = new SoundPlay;
|
||||
m_soundPlay->instance = inst;
|
||||
m_soundPlay->progress = 0;
|
||||
m_soundPlay->fileSize = 0;
|
||||
m_soundPlay->file = f;
|
||||
m_soundPlay->track = NULL;
|
||||
|
||||
// create the audio track
|
||||
if (f) {
|
||||
m_soundPlay->track = gSoundI.newTrack(44100, kPCM16Bit_ANPSampleFormat, 2, audioCallback, m_soundPlay);
|
||||
if (!m_soundPlay->track) {
|
||||
fclose(f);
|
||||
m_soundPlay->file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// get the audio file's size
|
||||
int fileDescriptor = open(path, O_RDONLY);
|
||||
struct stat fileStatus;
|
||||
|
||||
if(fileDescriptor <= 0) {
|
||||
gLogI.log(kError_ANPLogType, "fopen error");
|
||||
}
|
||||
else if (fstat(fileDescriptor, &fileStatus) != 0) {
|
||||
gLogI.log(kDebug_ANPLogType, "File Size: %d", fileStatus.st_size);
|
||||
m_soundPlay->fileSize = fileStatus.st_size;
|
||||
} else {
|
||||
gLogI.log(kError_ANPLogType, "fstat error");
|
||||
}
|
||||
|
||||
// configure the UI elements
|
||||
m_activeTouch = false;
|
||||
|
||||
memset(&m_trackRect, 0, sizeof(m_trackRect));
|
||||
memset(&m_playRect, 0, sizeof(m_playRect));
|
||||
memset(&m_pauseRect, 0, sizeof(m_pauseRect));
|
||||
memset(&m_stopRect, 0, sizeof(m_stopRect));
|
||||
|
||||
m_paintTrack = gPaintI.newPaint();
|
||||
gPaintI.setFlags(m_paintTrack, gPaintI.getFlags(m_paintTrack) | kAntiAlias_ANPPaintFlag);
|
||||
gPaintI.setColor(m_paintTrack, 0xFFC0C0C0);
|
||||
|
||||
m_paintRect = gPaintI.newPaint();
|
||||
gPaintI.setFlags(m_paintRect, gPaintI.getFlags(m_paintRect) | kAntiAlias_ANPPaintFlag);
|
||||
gPaintI.setColor(m_paintRect, 0xFFA8A8A8);
|
||||
|
||||
m_paintText = gPaintI.newPaint();
|
||||
gPaintI.setFlags(m_paintText, gPaintI.getFlags(m_paintText) | kAntiAlias_ANPPaintFlag);
|
||||
gPaintI.setColor(m_paintText, 0xFF2F4F4F);
|
||||
gPaintI.setTextSize(m_paintText, 18);
|
||||
|
||||
m_paintTrackProgress = gPaintI.newPaint();
|
||||
gPaintI.setFlags(m_paintTrackProgress, gPaintI.getFlags(m_paintTrackProgress) | kAntiAlias_ANPPaintFlag);
|
||||
gPaintI.setColor(m_paintTrackProgress, 0xFF545454);
|
||||
|
||||
m_paintActiveRect = gPaintI.newPaint();
|
||||
gPaintI.setFlags(m_paintActiveRect, gPaintI.getFlags(m_paintActiveRect) | kAntiAlias_ANPPaintFlag);
|
||||
gPaintI.setColor(m_paintActiveRect, 0xFF545454);
|
||||
|
||||
ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
|
||||
gPaintI.setTypeface(m_paintText, tf);
|
||||
gTypefaceI.unref(tf);
|
||||
|
||||
//register for touch events
|
||||
ANPEventFlags flags = kTouch_ANPEventFlag;
|
||||
NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
|
||||
if (err != NPERR_NO_ERROR) {
|
||||
gLogI.log(kError_ANPLogType, "Error selecting input events.");
|
||||
}
|
||||
}
|
||||
|
||||
AudioPlugin::~AudioPlugin() {
|
||||
gPaintI.deletePaint(m_paintTrack);
|
||||
gPaintI.deletePaint(m_paintRect);
|
||||
gPaintI.deletePaint(m_paintText);
|
||||
gPaintI.deletePaint(m_paintTrackProgress);
|
||||
gPaintI.deletePaint(m_paintActiveRect);
|
||||
if(m_soundPlay->track)
|
||||
gSoundI.deleteTrack(m_soundPlay->track);
|
||||
delete m_soundPlay;
|
||||
}
|
||||
|
||||
bool AudioPlugin::supportsDrawingModel(ANPDrawingModel model) {
|
||||
return (model == kBitmap_ANPDrawingModel);
|
||||
}
|
||||
|
||||
void AudioPlugin::drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip) {
|
||||
ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
|
||||
|
||||
ANPRectF clipR;
|
||||
clipR.left = clip.left;
|
||||
clipR.top = clip.top;
|
||||
clipR.right = clip.right;
|
||||
clipR.bottom = clip.bottom;
|
||||
gCanvasI.clipRect(canvas, &clipR);
|
||||
|
||||
draw(canvas);
|
||||
gCanvasI.deleteCanvas(canvas);
|
||||
}
|
||||
|
||||
void AudioPlugin::draw(ANPCanvas* canvas) {
|
||||
|
||||
PluginObject *obj = (PluginObject*) this->inst()->pdata;
|
||||
|
||||
gLogI.log(kError_ANPLogType, "Drawing");
|
||||
|
||||
const float trackHeight = 30;
|
||||
const float buttonWidth = 60;
|
||||
const float buttonHeight = 30;
|
||||
const int W = obj->window->width;
|
||||
const int H = obj->window->height;
|
||||
|
||||
// color the plugin canvas
|
||||
gCanvasI.drawColor(canvas, 0xFFCDCDCD);
|
||||
|
||||
// get font metrics
|
||||
ANPFontMetrics fontMetrics;
|
||||
gPaintI.getFontMetrics(m_paintText, &fontMetrics);
|
||||
|
||||
// draw the track box (1 px from the edge)
|
||||
m_trackRect.left = 1;
|
||||
m_trackRect.top = 1;
|
||||
m_trackRect.right = W - 2;
|
||||
m_trackRect.bottom = 1 + trackHeight;
|
||||
gCanvasI.drawRect(canvas, &m_trackRect, m_paintTrack);
|
||||
|
||||
// draw the progress bar
|
||||
if (m_soundPlay->progress > 0) {
|
||||
// TODO need to draw progress bar to cover the proper percentage of the track bar
|
||||
gCanvasI.drawRect(canvas, &m_trackRect, m_paintTrackProgress);
|
||||
}
|
||||
|
||||
// draw the play box (under track box)
|
||||
m_playRect.left = m_trackRect.left + 5;
|
||||
m_playRect.top = m_trackRect.bottom + 10;
|
||||
m_playRect.right = m_playRect.left + buttonWidth;
|
||||
m_playRect.bottom = m_playRect.top + buttonHeight;
|
||||
gCanvasI.drawRect(canvas, &m_playRect, getPaint(&m_playRect));
|
||||
// draw the play box (under track box)
|
||||
const char playText[] = "Play";
|
||||
gCanvasI.drawText(canvas, playText, sizeof(playText)-1, m_playRect.left + 5,
|
||||
m_playRect.top - fontMetrics.fTop, m_paintText);
|
||||
|
||||
// draw the pause box (under track box)
|
||||
m_pauseRect.left = m_playRect.right + 20;
|
||||
m_pauseRect.top = m_trackRect.bottom + 10;
|
||||
m_pauseRect.right = m_pauseRect.left + buttonWidth;
|
||||
m_pauseRect.bottom = m_pauseRect.top + buttonHeight;
|
||||
gCanvasI.drawRect(canvas, &m_pauseRect, getPaint(&m_pauseRect));
|
||||
// draw the text in the pause box
|
||||
const char pauseText[] = "Pause";
|
||||
gCanvasI.drawText(canvas, pauseText, sizeof(pauseText)-1, m_pauseRect.left + 5,
|
||||
m_pauseRect.top - fontMetrics.fTop, m_paintText);
|
||||
|
||||
// draw the stop box (under track box)
|
||||
m_stopRect.left = m_pauseRect.right + 20;
|
||||
m_stopRect.top = m_trackRect.bottom + 10;
|
||||
m_stopRect.right = m_stopRect.left + buttonWidth;
|
||||
m_stopRect.bottom = m_stopRect.top + buttonHeight;
|
||||
gCanvasI.drawRect(canvas, &m_stopRect, getPaint(&m_stopRect));
|
||||
// draw the text in the pause box
|
||||
const char stopText[] = "Stop";
|
||||
gCanvasI.drawText(canvas, stopText, sizeof(stopText)-1, m_stopRect.left + 5,
|
||||
m_stopRect.top - fontMetrics.fTop, m_paintText);
|
||||
}
|
||||
|
||||
ANPPaint* AudioPlugin::getPaint(ANPRectF* input) {
|
||||
return (input == m_activeRect) ? m_paintActiveRect : m_paintRect;
|
||||
}
|
||||
|
||||
int16 AudioPlugin::handleEvent(const ANPEvent* evt) {
|
||||
NPP instance = this->inst();
|
||||
|
||||
switch (evt->eventType) {
|
||||
case kDraw_ANPEventType:
|
||||
switch (evt->data.draw.model) {
|
||||
case kBitmap_ANPDrawingModel:
|
||||
drawPlugin(evt->data.draw.data.bitmap, evt->data.draw.clip);
|
||||
return 1;
|
||||
default:
|
||||
break; // unknown drawing model
|
||||
}
|
||||
|
||||
case kTouch_ANPEventType: {
|
||||
int x = evt->data.touch.x;
|
||||
int y = evt->data.touch.y;
|
||||
if (kDown_ANPTouchAction == evt->data.touch.action) {
|
||||
|
||||
m_activeTouchRect = validTouch(x,y);
|
||||
if(m_activeTouchRect) {
|
||||
m_activeTouch = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
} else if (kUp_ANPTouchAction == evt->data.touch.action && m_activeTouch) {
|
||||
handleTouch(x, y);
|
||||
m_activeTouch = false;
|
||||
return 1;
|
||||
} else if (kCancel_ANPTouchAction == evt->data.touch.action) {
|
||||
m_activeTouch = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0; // unknown or unhandled event
|
||||
}
|
||||
|
||||
void AudioPlugin::invalActiveRect() {
|
||||
|
||||
}
|
||||
|
||||
ANPRectF* AudioPlugin::validTouch(int x, int y) {
|
||||
|
||||
if (m_playRect.left && x < m_playRect.right && y > m_playRect.top && y < m_playRect.bottom)
|
||||
return &m_playRect;
|
||||
else if (m_pauseRect.left && x < m_pauseRect.right && y > m_pauseRect.top && y < m_pauseRect.bottom)
|
||||
return &m_pauseRect;
|
||||
else if (x > m_stopRect.left && x < m_stopRect.right && y > m_stopRect.top && y < m_stopRect.bottom)
|
||||
return &m_stopRect;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void AudioPlugin::handleTouch(int x, int y) {
|
||||
NPP instance = this->inst();
|
||||
|
||||
// if the track is null then return
|
||||
if (NULL == m_soundPlay->track) {
|
||||
gLogI.log(kError_ANPLogType, "---- %p unable to create track",
|
||||
instance);
|
||||
return;
|
||||
}
|
||||
|
||||
// check to make sure the currentRect matches the activeRect
|
||||
ANPRectF* currentRect = validTouch(x,y);
|
||||
if (m_activeTouchRect != currentRect)
|
||||
return;
|
||||
|
||||
if (currentRect == &m_playRect) {
|
||||
|
||||
gLogI.log(kDebug_ANPLogType, "---- %p starting track (%d)",
|
||||
m_soundPlay->track, gSoundI.isStopped(m_soundPlay->track));
|
||||
|
||||
if (gSoundI.isStopped(m_soundPlay->track)) {
|
||||
gSoundI.start(m_soundPlay->track);
|
||||
}
|
||||
}
|
||||
else if (currentRect == &m_pauseRect) {
|
||||
|
||||
gLogI.log(kDebug_ANPLogType, "---- %p pausing track (%d)",
|
||||
m_soundPlay->track, gSoundI.isStopped(m_soundPlay->track));
|
||||
|
||||
if (!gSoundI.isStopped(m_soundPlay->track)) {
|
||||
gSoundI.pause(m_soundPlay->track);
|
||||
}
|
||||
}
|
||||
else if (currentRect == &m_stopRect) {
|
||||
|
||||
gLogI.log(kDebug_ANPLogType, "---- %p stopping track (%d)",
|
||||
m_soundPlay->track, gSoundI.isStopped(m_soundPlay->track));
|
||||
|
||||
if (!gSoundI.isStopped(m_soundPlay->track)) {
|
||||
gSoundI.stop(m_soundPlay->track);
|
||||
}
|
||||
if (m_soundPlay->file) {
|
||||
fseek(m_soundPlay->file, 0, SEEK_SET);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
|
||||
// set the currentRect to be the activeRect
|
||||
m_activeRect = currentRect;
|
||||
inval(instance);
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright 2008, The Android Open Source Project
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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 "PluginObject.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef audioPlugin__DEFINED
|
||||
#define audioPlugin__DEFINED
|
||||
|
||||
struct SoundPlay {
|
||||
NPP instance;
|
||||
ANPAudioTrack* track;
|
||||
FILE* file;
|
||||
int fileSize;
|
||||
int progress; // value between 0 and 100
|
||||
};
|
||||
|
||||
class AudioPlugin : public SubPlugin {
|
||||
public:
|
||||
AudioPlugin(NPP inst);
|
||||
virtual ~AudioPlugin();
|
||||
virtual bool supportsDrawingModel(ANPDrawingModel);
|
||||
virtual int16 handleEvent(const ANPEvent* evt);
|
||||
private:
|
||||
void draw(ANPCanvas*);
|
||||
void drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip);
|
||||
|
||||
void handleTouch(int x, int y);
|
||||
void invalActiveRect();
|
||||
ANPPaint* getPaint(ANPRectF*);
|
||||
ANPRectF* validTouch(int x, int y);
|
||||
|
||||
ANPRectF m_trackRect;
|
||||
ANPRectF m_playRect;
|
||||
ANPRectF m_pauseRect;
|
||||
ANPRectF m_stopRect;
|
||||
|
||||
ANPPaint* m_paintTrack;
|
||||
ANPPaint* m_paintRect;
|
||||
ANPPaint* m_paintText;
|
||||
|
||||
ANPPaint* m_paintTrackProgress;
|
||||
ANPPaint* m_paintActiveRect;
|
||||
|
||||
SoundPlay* m_soundPlay;
|
||||
|
||||
bool m_activeTouch;
|
||||
ANPRectF* m_activeTouchRect;
|
||||
ANPRectF* m_activeRect;
|
||||
};
|
||||
|
||||
#endif // audioPlugin__DEFINED
|
||||
@@ -1,499 +0,0 @@
|
||||
/*
|
||||
* Copyright 2008, The Android Open Source Project
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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 "BackgroundPlugin.h"
|
||||
#include "android_npapi.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
extern NPNetscapeFuncs* browser;
|
||||
extern ANPBitmapInterfaceV0 gBitmapI;
|
||||
extern ANPCanvasInterfaceV0 gCanvasI;
|
||||
extern ANPLogInterfaceV0 gLogI;
|
||||
extern ANPPaintInterfaceV0 gPaintI;
|
||||
extern ANPSurfaceInterfaceV0 gSurfaceI;
|
||||
extern ANPSystemInterfaceV0 gSystemI;
|
||||
extern ANPTypefaceInterfaceV0 gTypefaceI;
|
||||
extern ANPWindowInterfaceV0 gWindowI;
|
||||
|
||||
#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
|
||||
|
||||
static uint32_t getMSecs() {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return (uint32_t) (tv.tv_sec * 1000 + tv.tv_usec / 1000 ); // microseconds to milliseconds
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BackgroundPlugin::BackgroundPlugin(NPP inst) : SurfaceSubPlugin(inst) {
|
||||
|
||||
// initialize the drawing surface
|
||||
m_surface = NULL;
|
||||
|
||||
//initialize bitmap transparency variables
|
||||
mFinishedStageOne = false;
|
||||
mFinishedStageTwo = false;
|
||||
mFinishedStageThree = false;
|
||||
|
||||
// test basic plugin functionality
|
||||
test_logging(); // android logging
|
||||
test_timers(); // plugin timers
|
||||
test_bitmaps(); // android bitmaps
|
||||
test_domAccess();
|
||||
test_javascript();
|
||||
test_loadJavaClass();
|
||||
|
||||
//register for touch events
|
||||
ANPEventFlags flags = kTouch_ANPEventFlag;
|
||||
NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
|
||||
if (err != NPERR_NO_ERROR) {
|
||||
gLogI.log(kError_ANPLogType, "Error selecting input events.");
|
||||
}
|
||||
}
|
||||
|
||||
BackgroundPlugin::~BackgroundPlugin() {
|
||||
setContext(NULL);
|
||||
destroySurface();
|
||||
}
|
||||
|
||||
jobject BackgroundPlugin::getSurface() {
|
||||
|
||||
if (m_surface) {
|
||||
return m_surface;
|
||||
}
|
||||
|
||||
// load the appropriate java class and instantiate it
|
||||
JNIEnv* env = NULL;
|
||||
if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
|
||||
gLogI.log(kError_ANPLogType, " ---- getSurface: failed to get env");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* className = "com.android.sampleplugin.BackgroundSurface";
|
||||
jclass backgroundClass = gSystemI.loadJavaClass(inst(), className);
|
||||
|
||||
if(!backgroundClass) {
|
||||
gLogI.log(kError_ANPLogType, " ---- getSurface: failed to load class");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jmethodID constructor = env->GetMethodID(backgroundClass, "<init>", "(Landroid/content/Context;)V");
|
||||
jobject backgroundSurface = env->NewObject(backgroundClass, constructor, m_context);
|
||||
|
||||
if(!backgroundSurface) {
|
||||
gLogI.log(kError_ANPLogType, " ---- getSurface: failed to construct object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m_surface = env->NewGlobalRef(backgroundSurface);
|
||||
return m_surface;
|
||||
}
|
||||
|
||||
void BackgroundPlugin::destroySurface() {
|
||||
JNIEnv* env = NULL;
|
||||
if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
|
||||
env->DeleteGlobalRef(m_surface);
|
||||
m_surface = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void BackgroundPlugin::drawPlugin(int surfaceWidth, int surfaceHeight) {
|
||||
|
||||
// get the plugin's dimensions according to the DOM
|
||||
PluginObject *obj = (PluginObject*) inst()->pdata;
|
||||
const int W = obj->window->width;
|
||||
const int H = obj->window->height;
|
||||
|
||||
// compute the current zoom level
|
||||
const float zoomFactorW = static_cast<float>(surfaceWidth) / W;
|
||||
const float zoomFactorH = static_cast<float>(surfaceHeight) / H;
|
||||
|
||||
// check to make sure the zoom level is uniform
|
||||
if (zoomFactorW + .01 < zoomFactorH && zoomFactorW - .01 > zoomFactorH)
|
||||
gLogI.log(kError_ANPLogType, " ------ %p zoom is out of sync (%f,%f)",
|
||||
inst(), zoomFactorW, zoomFactorH);
|
||||
|
||||
// scale the variables based on the zoom level
|
||||
const int fontSize = (int)(zoomFactorW * 16);
|
||||
const int leftMargin = (int)(zoomFactorW * 10);
|
||||
|
||||
// lock the surface
|
||||
ANPBitmap bitmap;
|
||||
JNIEnv* env = NULL;
|
||||
if (!m_surface || gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK ||
|
||||
!gSurfaceI.lock(env, m_surface, &bitmap, NULL)) {
|
||||
gLogI.log(kError_ANPLogType, " ------ %p unable to lock the plugin", inst());
|
||||
return;
|
||||
}
|
||||
|
||||
// create a canvas
|
||||
ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
|
||||
gCanvasI.drawColor(canvas, 0xFFFFFFFF);
|
||||
|
||||
ANPPaint* paint = gPaintI.newPaint();
|
||||
gPaintI.setFlags(paint, gPaintI.getFlags(paint) | kAntiAlias_ANPPaintFlag);
|
||||
gPaintI.setColor(paint, 0xFFFF0000);
|
||||
gPaintI.setTextSize(paint, fontSize);
|
||||
|
||||
ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
|
||||
gPaintI.setTypeface(paint, tf);
|
||||
gTypefaceI.unref(tf);
|
||||
|
||||
ANPFontMetrics fm;
|
||||
gPaintI.getFontMetrics(paint, &fm);
|
||||
|
||||
gPaintI.setColor(paint, 0xFF0000FF);
|
||||
const char c[] = "This is a background plugin.";
|
||||
gCanvasI.drawText(canvas, c, sizeof(c)-1, leftMargin, -fm.fTop, paint);
|
||||
|
||||
// clean up variables and unlock the surface
|
||||
gPaintI.deletePaint(paint);
|
||||
gCanvasI.deleteCanvas(canvas);
|
||||
gSurfaceI.unlock(env, m_surface);
|
||||
}
|
||||
|
||||
int16 BackgroundPlugin::handleEvent(const ANPEvent* evt) {
|
||||
switch (evt->eventType) {
|
||||
case kDraw_ANPEventType:
|
||||
gLogI.log(kError_ANPLogType, " ------ %p the plugin did not request draw events", inst());
|
||||
break;
|
||||
case kLifecycle_ANPEventType:
|
||||
switch (evt->data.lifecycle.action) {
|
||||
case kOnLoad_ANPLifecycleAction:
|
||||
gLogI.log(kDebug_ANPLogType, " ------ %p onLoad", inst());
|
||||
return 1;
|
||||
case kOnScreen_ANPLifecycleAction:
|
||||
gLogI.log(kDebug_ANPLogType, " ------ %p onScreen", inst());
|
||||
return 1;
|
||||
case kOffScreen_ANPLifecycleAction:
|
||||
gLogI.log(kDebug_ANPLogType, " ------ %p offScreen", inst());
|
||||
return 1;
|
||||
}
|
||||
break; // end kLifecycle_ANPEventType
|
||||
case kTouch_ANPEventType:
|
||||
if (kLongPress_ANPTouchAction == evt->data.touch.action) {
|
||||
browser->geturl(inst(), "javascript:alert('Detected long press event.')", 0);
|
||||
gWindowI.requestFullScreen(inst());
|
||||
}
|
||||
else if (kDoubleTap_ANPTouchAction == evt->data.touch.action)
|
||||
browser->geturl(inst(), "javascript:alert('Detected double tap event.')", 0);
|
||||
break;
|
||||
case kKey_ANPEventType:
|
||||
gLogI.log(kError_ANPLogType, " ------ %p the plugin did not request key events", inst());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0; // unknown or unhandled event
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// LOGGING TESTS
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void BackgroundPlugin::test_logging() {
|
||||
NPP instance = this->inst();
|
||||
|
||||
//LOG_ERROR(instance, " ------ %p Testing Log Error", instance);
|
||||
gLogI.log(kError_ANPLogType, " ------ %p Testing Log Error", instance);
|
||||
gLogI.log(kWarning_ANPLogType, " ------ %p Testing Log Warning", instance);
|
||||
gLogI.log(kDebug_ANPLogType, " ------ %p Testing Log Debug", instance);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// TIMER TESTS
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TIMER_INTERVAL 50
|
||||
static void timer_oneshot(NPP instance, uint32 timerID);
|
||||
static void timer_repeat(NPP instance, uint32 timerID);
|
||||
static void timer_neverfires(NPP instance, uint32 timerID);
|
||||
static void timer_latency(NPP instance, uint32 timerID);
|
||||
|
||||
void BackgroundPlugin::test_timers() {
|
||||
NPP instance = this->inst();
|
||||
|
||||
//Setup the testing counters
|
||||
mTimerRepeatCount = 5;
|
||||
mTimerLatencyCount = 5;
|
||||
|
||||
// test for bogus timerID
|
||||
browser->unscheduletimer(instance, 999999);
|
||||
// test one-shot
|
||||
browser->scheduletimer(instance, 100, false, timer_oneshot);
|
||||
// test repeat
|
||||
browser->scheduletimer(instance, 50, true, timer_repeat);
|
||||
// test timer latency
|
||||
browser->scheduletimer(instance, TIMER_INTERVAL, true, timer_latency);
|
||||
mStartTime = mPrevTime = getMSecs();
|
||||
// test unschedule immediately
|
||||
uint32 id = browser->scheduletimer(instance, 100, false, timer_neverfires);
|
||||
browser->unscheduletimer(instance, id);
|
||||
// test double unschedule (should be no-op)
|
||||
browser->unscheduletimer(instance, id);
|
||||
|
||||
}
|
||||
|
||||
static void timer_oneshot(NPP instance, uint32 timerID) {
|
||||
gLogI.log(kDebug_ANPLogType, "-------- oneshot timer\n");
|
||||
}
|
||||
|
||||
static void timer_repeat(NPP instance, uint32 timerID) {
|
||||
BackgroundPlugin *obj = ((BackgroundPlugin*) ((PluginObject*) instance->pdata)->activePlugin);
|
||||
|
||||
gLogI.log(kDebug_ANPLogType, "-------- repeat timer %d\n",
|
||||
obj->mTimerRepeatCount);
|
||||
if (--obj->mTimerRepeatCount == 0) {
|
||||
browser->unscheduletimer(instance, timerID);
|
||||
}
|
||||
}
|
||||
|
||||
static void timer_neverfires(NPP instance, uint32 timerID) {
|
||||
gLogI.log(kError_ANPLogType, "-------- timer_neverfires!!!\n");
|
||||
}
|
||||
|
||||
static void timer_latency(NPP instance, uint32 timerID) {
|
||||
BackgroundPlugin *obj = ((BackgroundPlugin*) ((PluginObject*) instance->pdata)->activePlugin);
|
||||
|
||||
obj->mTimerLatencyCurrentCount += 1;
|
||||
|
||||
uint32_t now = getMSecs();
|
||||
uint32_t interval = now - obj->mPrevTime;
|
||||
uint32_t dur = now - obj->mStartTime;
|
||||
uint32_t expectedDur = obj->mTimerLatencyCurrentCount * TIMER_INTERVAL;
|
||||
int32_t drift = dur - expectedDur;
|
||||
int32_t avgDrift = drift / obj->mTimerLatencyCurrentCount;
|
||||
|
||||
obj->mPrevTime = now;
|
||||
|
||||
gLogI.log(kDebug_ANPLogType,
|
||||
"-------- latency test: [%3d] interval %d expected %d, total %d expected %d, drift %d avg %d\n",
|
||||
obj->mTimerLatencyCurrentCount, interval, TIMER_INTERVAL, dur,
|
||||
expectedDur, drift, avgDrift);
|
||||
|
||||
if (--obj->mTimerLatencyCount == 0) {
|
||||
browser->unscheduletimer(instance, timerID);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// BITMAP TESTS
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void test_formats(NPP instance);
|
||||
|
||||
void BackgroundPlugin::test_bitmaps() {
|
||||
test_formats(this->inst());
|
||||
}
|
||||
|
||||
static void test_formats(NPP instance) {
|
||||
|
||||
// TODO pull names from enum in npapi instead of hardcoding them
|
||||
static const struct {
|
||||
ANPBitmapFormat fFormat;
|
||||
const char* fName;
|
||||
} gRecs[] = {
|
||||
{ kUnknown_ANPBitmapFormat, "unknown" },
|
||||
{ kRGBA_8888_ANPBitmapFormat, "8888" },
|
||||
{ kRGB_565_ANPBitmapFormat, "565" },
|
||||
};
|
||||
|
||||
ANPPixelPacking packing;
|
||||
for (size_t i = 0; i < ARRAY_COUNT(gRecs); i++) {
|
||||
if (gBitmapI.getPixelPacking(gRecs[i].fFormat, &packing)) {
|
||||
gLogI.log(kDebug_ANPLogType,
|
||||
"pixel format [%d] %s has packing ARGB [%d %d] [%d %d] [%d %d] [%d %d]\n",
|
||||
gRecs[i].fFormat, gRecs[i].fName,
|
||||
packing.AShift, packing.ABits,
|
||||
packing.RShift, packing.RBits,
|
||||
packing.GShift, packing.GBits,
|
||||
packing.BShift, packing.BBits);
|
||||
} else {
|
||||
gLogI.log(kDebug_ANPLogType,
|
||||
"pixel format [%d] %s has no packing\n",
|
||||
gRecs[i].fFormat, gRecs[i].fName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BackgroundPlugin::test_bitmap_transparency(const ANPEvent* evt) {
|
||||
NPP instance = this->inst();
|
||||
|
||||
// check default & set transparent
|
||||
if (!mFinishedStageOne) {
|
||||
|
||||
gLogI.log(kDebug_ANPLogType, "BEGIN: testing bitmap transparency");
|
||||
|
||||
//check to make sure it is not transparent
|
||||
if (evt->data.draw.data.bitmap.format == kRGBA_8888_ANPBitmapFormat) {
|
||||
gLogI.log(kError_ANPLogType, "bitmap default format is transparent");
|
||||
}
|
||||
|
||||
//make it transparent (any non-null value will set it to true)
|
||||
bool value = true;
|
||||
NPError err = browser->setvalue(instance, NPPVpluginTransparentBool, &value);
|
||||
if (err != NPERR_NO_ERROR) {
|
||||
gLogI.log(kError_ANPLogType, "Error setting transparency.");
|
||||
}
|
||||
|
||||
mFinishedStageOne = true;
|
||||
browser->invalidaterect(instance, NULL);
|
||||
}
|
||||
// check transparent & set opaque
|
||||
else if (!mFinishedStageTwo) {
|
||||
|
||||
//check to make sure it is transparent
|
||||
if (evt->data.draw.data.bitmap.format != kRGBA_8888_ANPBitmapFormat) {
|
||||
gLogI.log(kError_ANPLogType, "bitmap did not change to transparent format");
|
||||
}
|
||||
|
||||
//make it opaque
|
||||
NPError err = browser->setvalue(instance, NPPVpluginTransparentBool, NULL);
|
||||
if (err != NPERR_NO_ERROR) {
|
||||
gLogI.log(kError_ANPLogType, "Error setting transparency.");
|
||||
}
|
||||
|
||||
mFinishedStageTwo = true;
|
||||
}
|
||||
// check opaque
|
||||
else if (!mFinishedStageThree) {
|
||||
|
||||
//check to make sure it is not transparent
|
||||
if (evt->data.draw.data.bitmap.format == kRGBA_8888_ANPBitmapFormat) {
|
||||
gLogI.log(kError_ANPLogType, "bitmap default format is transparent");
|
||||
}
|
||||
|
||||
gLogI.log(kDebug_ANPLogType, "END: testing bitmap transparency");
|
||||
|
||||
mFinishedStageThree = true;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// DOM TESTS
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void BackgroundPlugin::test_domAccess() {
|
||||
NPP instance = this->inst();
|
||||
|
||||
gLogI.log(kDebug_ANPLogType, " ------ %p Testing DOM Access", instance);
|
||||
|
||||
// Get the plugin's DOM object
|
||||
NPObject* windowObject = NULL;
|
||||
browser->getvalue(instance, NPNVWindowNPObject, &windowObject);
|
||||
|
||||
if (!windowObject)
|
||||
gLogI.log(kError_ANPLogType, " ------ %p Unable to retrieve DOM Window", instance);
|
||||
|
||||
// Retrieve a property from the plugin's DOM object
|
||||
NPIdentifier topIdentifier = browser->getstringidentifier("top");
|
||||
NPVariant topObjectVariant;
|
||||
browser->getproperty(instance, windowObject, topIdentifier, &topObjectVariant);
|
||||
|
||||
if (topObjectVariant.type != NPVariantType_Object)
|
||||
gLogI.log(kError_ANPLogType, " ------ %p Invalid Variant type for DOM Property: %d,%d", instance, topObjectVariant.type, NPVariantType_Object);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// JAVASCRIPT TESTS
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void BackgroundPlugin::test_javascript() {
|
||||
NPP instance = this->inst();
|
||||
|
||||
gLogI.log(kDebug_ANPLogType, " ------ %p Testing JavaScript Access", instance);
|
||||
|
||||
// Get the plugin's DOM object
|
||||
NPObject* windowObject = NULL;
|
||||
browser->getvalue(instance, NPNVWindowNPObject, &windowObject);
|
||||
|
||||
if (!windowObject)
|
||||
gLogI.log(kError_ANPLogType, " ------ %p Unable to retrieve DOM Window", instance);
|
||||
|
||||
// create a string (JS code) that is stored in memory allocated by the browser
|
||||
const char* jsString = "1200 + 34";
|
||||
void* stringMem = browser->memalloc(strlen(jsString));
|
||||
memcpy(stringMem, jsString, strlen(jsString));
|
||||
|
||||
// execute the javascript in the plugin's DOM object
|
||||
NPString script = { (char*)stringMem, strlen(jsString) };
|
||||
NPVariant scriptVariant;
|
||||
if (!browser->evaluate(instance, windowObject, &script, &scriptVariant))
|
||||
gLogI.log(kError_ANPLogType, " ------ %p Unable to eval the JS.", instance);
|
||||
|
||||
if (scriptVariant.type == NPVariantType_Int32) {
|
||||
if (scriptVariant.value.intValue != 1234)
|
||||
gLogI.log(kError_ANPLogType, " ------ %p Invalid Value for JS Return: %d,1234", instance, scriptVariant.value.intValue);
|
||||
} else {
|
||||
gLogI.log(kError_ANPLogType, " ------ %p Invalid Variant type for JS Return: %d,%d", instance, scriptVariant.type, NPVariantType_Int32);
|
||||
}
|
||||
|
||||
// free the memory allocated within the browser
|
||||
browser->memfree(stringMem);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Load Java Classes Tests
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void BackgroundPlugin::test_loadJavaClass() {
|
||||
|
||||
JNIEnv* env = NULL;
|
||||
if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
|
||||
gLogI.log(kError_ANPLogType, " ---- LoadJavaTest: failed to get env");
|
||||
return;
|
||||
}
|
||||
|
||||
const char* className = "com.android.sampleplugin.BackgroundTest";
|
||||
jclass backgroundClass = gSystemI.loadJavaClass(inst(), className);
|
||||
|
||||
if(!backgroundClass) {
|
||||
gLogI.log(kError_ANPLogType, " ---- LoadJavaTest: failed to load class");
|
||||
return;
|
||||
}
|
||||
|
||||
jmethodID constructor = env->GetMethodID(backgroundClass, "<init>", "()V");
|
||||
jmethodID addMethod = env->GetMethodID(backgroundClass, "addInt", "(II)I");
|
||||
jobject backgroundObject = env->NewObject(backgroundClass, constructor);
|
||||
|
||||
if(!backgroundObject) {
|
||||
gLogI.log(kError_ANPLogType, " ---- LoadJavaTest: failed to construct object");
|
||||
return;
|
||||
}
|
||||
|
||||
jint result = env->CallIntMethod(backgroundObject, addMethod, 2, 2);
|
||||
|
||||
if (result != 4) {
|
||||
gLogI.log(kError_ANPLogType, " ---- LoadJavaTest: invalid result (%d != 4)", result);
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright 2008, The Android Open Source Project
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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 "PluginObject.h"
|
||||
|
||||
#ifndef backgroundPlugin__DEFINED
|
||||
#define backgroundPlugin__DEFINED
|
||||
|
||||
class BackgroundPlugin : public SurfaceSubPlugin {
|
||||
public:
|
||||
BackgroundPlugin(NPP inst);
|
||||
virtual ~BackgroundPlugin();
|
||||
virtual int16 handleEvent(const ANPEvent* evt);
|
||||
virtual jobject getSurface();
|
||||
|
||||
// Timer Testing Variables
|
||||
uint32_t mStartTime;
|
||||
uint32_t mPrevTime;
|
||||
int mTimerRepeatCount;
|
||||
int mTimerLatencyCount;
|
||||
int mTimerLatencyCurrentCount;
|
||||
|
||||
// Bitmap Transparency Variables
|
||||
bool mFinishedStageOne; // check default & set transparent
|
||||
bool mFinishedStageTwo; // check transparent & set opaque
|
||||
bool mFinishedStageThree; // check opaque
|
||||
|
||||
private:
|
||||
void drawPlugin(int surfaceWidth, int surfaceHeight);
|
||||
void destroySurface();
|
||||
|
||||
jobject m_surface;
|
||||
|
||||
void test_logging();
|
||||
void test_timers();
|
||||
void test_bitmaps();
|
||||
void test_bitmap_transparency(const ANPEvent* evt);
|
||||
void test_domAccess();
|
||||
void test_javascript();
|
||||
void test_loadJavaClass();
|
||||
|
||||
};
|
||||
|
||||
#endif // backgroundPlugin__DEFINED
|
||||
@@ -1,381 +0,0 @@
|
||||
/*
|
||||
* Copyright 2008, The Android Open Source Project
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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 "FormPlugin.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
extern NPNetscapeFuncs* browser;
|
||||
extern ANPLogInterfaceV0 gLogI;
|
||||
extern ANPCanvasInterfaceV0 gCanvasI;
|
||||
extern ANPPaintInterfaceV0 gPaintI;
|
||||
extern ANPTypefaceInterfaceV0 gTypefaceI;
|
||||
extern ANPWindowInterfaceV0 gWindowI;
|
||||
|
||||
|
||||
static void inval(NPP instance) {
|
||||
browser->invalidaterect(instance, NULL);
|
||||
}
|
||||
|
||||
static uint16 rnd16(float x, int inset) {
|
||||
int ix = (int)roundf(x) + inset;
|
||||
if (ix < 0) {
|
||||
ix = 0;
|
||||
}
|
||||
return static_cast<uint16>(ix);
|
||||
}
|
||||
|
||||
static void inval(NPP instance, const ANPRectF& r, bool doAA) {
|
||||
const int inset = doAA ? -1 : 0;
|
||||
|
||||
PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
|
||||
NPRect inval;
|
||||
inval.left = rnd16(r.left, inset);
|
||||
inval.top = rnd16(r.top, inset);
|
||||
inval.right = rnd16(r.right, -inset);
|
||||
inval.bottom = rnd16(r.bottom, -inset);
|
||||
browser->invalidaterect(instance, &inval);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FormPlugin::FormPlugin(NPP inst) : SubPlugin(inst) {
|
||||
|
||||
m_hasFocus = false;
|
||||
m_activeInput = NULL;
|
||||
|
||||
memset(&m_usernameInput, 0, sizeof(m_usernameInput));
|
||||
memset(&m_passwordInput, 0, sizeof(m_passwordInput));
|
||||
|
||||
m_usernameInput.text[0] = '\0';
|
||||
m_usernameInput.charPtr = 0;
|
||||
|
||||
m_passwordInput.text[0] = '\0';
|
||||
m_passwordInput.charPtr = 0;
|
||||
|
||||
m_paintInput = gPaintI.newPaint();
|
||||
gPaintI.setFlags(m_paintInput, gPaintI.getFlags(m_paintInput) | kAntiAlias_ANPPaintFlag);
|
||||
gPaintI.setColor(m_paintInput, 0xFFFFFFFF);
|
||||
|
||||
m_paintActive = gPaintI.newPaint();
|
||||
gPaintI.setFlags(m_paintActive, gPaintI.getFlags(m_paintActive) | kAntiAlias_ANPPaintFlag);
|
||||
gPaintI.setColor(m_paintActive, 0xFFFFFF00);
|
||||
|
||||
m_paintText = gPaintI.newPaint();
|
||||
gPaintI.setFlags(m_paintText, gPaintI.getFlags(m_paintText) | kAntiAlias_ANPPaintFlag);
|
||||
gPaintI.setColor(m_paintText, 0xFF000000);
|
||||
gPaintI.setTextSize(m_paintText, 18);
|
||||
|
||||
ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
|
||||
gPaintI.setTypeface(m_paintText, tf);
|
||||
gTypefaceI.unref(tf);
|
||||
|
||||
//register for key and visibleRect events
|
||||
ANPEventFlags flags = kKey_ANPEventFlag;
|
||||
NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
|
||||
if (err != NPERR_NO_ERROR) {
|
||||
gLogI.log(kError_ANPLogType, "Error selecting input events.");
|
||||
}
|
||||
}
|
||||
|
||||
FormPlugin::~FormPlugin() {
|
||||
gPaintI.deletePaint(m_paintInput);
|
||||
gPaintI.deletePaint(m_paintActive);
|
||||
gPaintI.deletePaint(m_paintText);
|
||||
}
|
||||
|
||||
bool FormPlugin::supportsDrawingModel(ANPDrawingModel model) {
|
||||
return (model == kBitmap_ANPDrawingModel);
|
||||
}
|
||||
|
||||
void FormPlugin::drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip) {
|
||||
ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
|
||||
|
||||
ANPRectF clipR;
|
||||
clipR.left = clip.left;
|
||||
clipR.top = clip.top;
|
||||
clipR.right = clip.right;
|
||||
clipR.bottom = clip.bottom;
|
||||
gCanvasI.clipRect(canvas, &clipR);
|
||||
|
||||
draw(canvas);
|
||||
gCanvasI.deleteCanvas(canvas);
|
||||
}
|
||||
|
||||
void FormPlugin::draw(ANPCanvas* canvas) {
|
||||
NPP instance = this->inst();
|
||||
PluginObject *obj = (PluginObject*) instance->pdata;
|
||||
|
||||
const float inputWidth = 60;
|
||||
const float inputHeight = 30;
|
||||
const int W = obj->window->width;
|
||||
const int H = obj->window->height;
|
||||
|
||||
// color the plugin canvas
|
||||
gCanvasI.drawColor(canvas, (m_hasFocus) ? 0xFFCDCDCD : 0xFF545454);
|
||||
|
||||
// draw the username box (5 px from the top edge)
|
||||
m_usernameInput.rect.left = 5;
|
||||
m_usernameInput.rect.top = 5;
|
||||
m_usernameInput.rect.right = W - 5;
|
||||
m_usernameInput.rect.bottom = m_usernameInput.rect.top + inputHeight;
|
||||
gCanvasI.drawRect(canvas, &m_usernameInput.rect, getPaint(&m_usernameInput));
|
||||
drawText(canvas, m_usernameInput);
|
||||
|
||||
// draw the password box (5 px from the bottom edge)
|
||||
m_passwordInput.rect.left = 5;
|
||||
m_passwordInput.rect.top = H - (inputHeight + 5);
|
||||
m_passwordInput.rect.right = W - 5;
|
||||
m_passwordInput.rect.bottom = m_passwordInput.rect.top + inputHeight;
|
||||
gCanvasI.drawRect(canvas, &m_passwordInput.rect, getPaint(&m_passwordInput));
|
||||
drawPassword(canvas, m_passwordInput);
|
||||
|
||||
//invalidate the canvas
|
||||
//inval(instance);
|
||||
}
|
||||
|
||||
ANPPaint* FormPlugin::getPaint(TextInput* input) {
|
||||
return (input == m_activeInput) ? m_paintActive : m_paintInput;
|
||||
}
|
||||
|
||||
void FormPlugin::drawText(ANPCanvas* canvas, TextInput textInput) {
|
||||
|
||||
// get font metrics
|
||||
ANPFontMetrics fontMetrics;
|
||||
gPaintI.getFontMetrics(m_paintText, &fontMetrics);
|
||||
|
||||
gCanvasI.drawText(canvas, textInput.text, textInput.charPtr,
|
||||
textInput.rect.left + 5,
|
||||
textInput.rect.bottom - fontMetrics.fBottom, m_paintText);
|
||||
}
|
||||
|
||||
void FormPlugin::drawPassword(ANPCanvas* canvas, TextInput passwordInput) {
|
||||
|
||||
// get font metrics
|
||||
ANPFontMetrics fontMetrics;
|
||||
gPaintI.getFontMetrics(m_paintText, &fontMetrics);
|
||||
|
||||
// comput the circle dimensions and initial location
|
||||
float initialX = passwordInput.rect.left + 5;
|
||||
float ovalBottom = passwordInput.rect.bottom - 2;
|
||||
float ovalTop = ovalBottom - (fontMetrics.fBottom - fontMetrics.fTop);
|
||||
float ovalWidth = ovalBottom - ovalTop;
|
||||
float ovalSpacing = 3;
|
||||
|
||||
// draw circles instead of the actual text
|
||||
for (uint32_t x = 0; x < passwordInput.charPtr; x++) {
|
||||
ANPRectF oval;
|
||||
oval.left = initialX + ((ovalWidth + ovalSpacing) * (float) x);
|
||||
oval.right = oval.left + ovalWidth;
|
||||
oval.top = ovalTop;
|
||||
oval.bottom = ovalBottom;
|
||||
gCanvasI.drawOval(canvas, &oval, m_paintText);
|
||||
}
|
||||
}
|
||||
|
||||
int16 FormPlugin::handleEvent(const ANPEvent* evt) {
|
||||
NPP instance = this->inst();
|
||||
|
||||
switch (evt->eventType) {
|
||||
case kDraw_ANPEventType:
|
||||
switch (evt->data.draw.model) {
|
||||
case kBitmap_ANPDrawingModel:
|
||||
drawPlugin(evt->data.draw.data.bitmap, evt->data.draw.clip);
|
||||
return 1;
|
||||
default:
|
||||
break; // unknown drawing model
|
||||
}
|
||||
break;
|
||||
|
||||
case kLifecycle_ANPEventType:
|
||||
if (evt->data.lifecycle.action == kLoseFocus_ANPLifecycleAction) {
|
||||
gLogI.log(kDebug_ANPLogType, "----%p Loosing Focus", instance);
|
||||
|
||||
if (m_activeInput) {
|
||||
// hide the keyboard
|
||||
gWindowI.showKeyboard(instance, false);
|
||||
|
||||
//reset the activeInput
|
||||
m_activeInput = NULL;
|
||||
}
|
||||
|
||||
m_hasFocus = false;
|
||||
inval(instance);
|
||||
return 1;
|
||||
}
|
||||
else if (evt->data.lifecycle.action == kGainFocus_ANPLifecycleAction) {
|
||||
gLogI.log(kDebug_ANPLogType, "----%p Gaining Focus", instance);
|
||||
m_hasFocus = true;
|
||||
inval(instance);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case kMouse_ANPEventType: {
|
||||
|
||||
int x = evt->data.mouse.x;
|
||||
int y = evt->data.mouse.y;
|
||||
if (kDown_ANPMouseAction == evt->data.mouse.action) {
|
||||
|
||||
TextInput* currentInput = validTap(x,y);
|
||||
|
||||
if (currentInput)
|
||||
gWindowI.showKeyboard(instance, true);
|
||||
else if (m_activeInput)
|
||||
gWindowI.showKeyboard(instance, false);
|
||||
|
||||
if (currentInput != m_activeInput)
|
||||
switchActiveInput(currentInput);
|
||||
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kKey_ANPEventType:
|
||||
if (evt->data.key.action == kDown_ANPKeyAction) {
|
||||
|
||||
//handle navigation keys
|
||||
if (evt->data.key.nativeCode >= kDpadUp_ANPKeyCode
|
||||
&& evt->data.key.nativeCode <= kDpadCenter_ANPKeyCode) {
|
||||
return handleNavigation(evt->data.key.nativeCode) ? 1 : 0;
|
||||
}
|
||||
|
||||
if (m_activeInput) {
|
||||
handleTextInput(m_activeInput, evt->data.key.nativeCode,
|
||||
evt->data.key.unichar);
|
||||
inval(instance, m_activeInput->rect, true);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0; // unknown or unhandled event
|
||||
}
|
||||
|
||||
void FormPlugin::switchActiveInput(TextInput* newInput) {
|
||||
NPP instance = this->inst();
|
||||
|
||||
if (m_activeInput) {
|
||||
inval(instance, m_activeInput->rect, true); // inval the old
|
||||
gWindowI.clearVisibleRects(instance);
|
||||
}
|
||||
|
||||
m_activeInput = newInput; // set the new active input
|
||||
|
||||
if (m_activeInput) {
|
||||
inval(instance, m_activeInput->rect, true); // inval the new
|
||||
scrollIntoView(m_activeInput);
|
||||
}
|
||||
}
|
||||
|
||||
bool FormPlugin::handleNavigation(ANPKeyCode keyCode) {
|
||||
NPP instance = this->inst();
|
||||
|
||||
gLogI.log(kDebug_ANPLogType, "----%p Recvd Nav Key %d", instance, keyCode);
|
||||
|
||||
if (!m_activeInput) {
|
||||
gWindowI.showKeyboard(instance, true);
|
||||
switchActiveInput(&m_usernameInput);
|
||||
}
|
||||
else if (m_activeInput == &m_usernameInput) {
|
||||
if (keyCode == kDpadDown_ANPKeyCode) {
|
||||
switchActiveInput(&m_passwordInput);
|
||||
}
|
||||
else if (keyCode == kDpadCenter_ANPKeyCode)
|
||||
gWindowI.showKeyboard(instance, false);
|
||||
else if (keyCode == kDpadUp_ANPKeyCode)
|
||||
return false;
|
||||
}
|
||||
else if (m_activeInput == &m_passwordInput) {
|
||||
if (keyCode == kDpadUp_ANPKeyCode) {
|
||||
switchActiveInput(&m_usernameInput);
|
||||
}
|
||||
else if (keyCode == kDpadCenter_ANPKeyCode)
|
||||
gWindowI.showKeyboard(instance, false);
|
||||
else if (keyCode == kDpadDown_ANPKeyCode)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FormPlugin::handleTextInput(TextInput* input, ANPKeyCode keyCode, int32_t unichar) {
|
||||
NPP instance = this->inst();
|
||||
|
||||
//make sure the input field is in view
|
||||
scrollIntoView(input);
|
||||
|
||||
//handle the delete operation
|
||||
if (keyCode == kDel_ANPKeyCode) {
|
||||
if (input->charPtr > 0) {
|
||||
input->charPtr--;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//check to see that the input is not full
|
||||
if (input->charPtr >= (sizeof(input->text) - 1))
|
||||
return;
|
||||
|
||||
//add the character
|
||||
input->text[input->charPtr] = static_cast<char>(unichar);
|
||||
input->charPtr++;
|
||||
|
||||
gLogI.log(kDebug_ANPLogType, "----%p Text: %c", instance, unichar);
|
||||
}
|
||||
|
||||
void FormPlugin::scrollIntoView(TextInput* input) {
|
||||
NPP instance = this->inst();
|
||||
PluginObject *obj = (PluginObject*) instance->pdata;
|
||||
NPWindow *window = obj->window;
|
||||
|
||||
// find the textInput's global rect coordinates
|
||||
ANPRectI visibleRects[1];
|
||||
visibleRects[0].left = input->rect.left;
|
||||
visibleRects[0].top = input->rect.top;
|
||||
visibleRects[0].right = input->rect.right;
|
||||
visibleRects[0].bottom = input->rect.bottom;
|
||||
|
||||
gWindowI.setVisibleRects(instance, visibleRects, 1);
|
||||
}
|
||||
|
||||
TextInput* FormPlugin::validTap(int x, int y) {
|
||||
|
||||
if (x > m_usernameInput.rect.left && x < m_usernameInput.rect.right &&
|
||||
y > m_usernameInput.rect.top && y < m_usernameInput.rect.bottom)
|
||||
return &m_usernameInput;
|
||||
else if (x >m_passwordInput.rect.left && x < m_passwordInput.rect.right &&
|
||||
y > m_passwordInput.rect.top && y < m_passwordInput.rect.bottom)
|
||||
return &m_passwordInput;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright 2008, The Android Open Source Project
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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 "PluginObject.h"
|
||||
|
||||
#ifndef formPlugin__DEFINED
|
||||
#define formPlugin__DEFINED
|
||||
|
||||
struct TextInput {
|
||||
ANPRectF rect;
|
||||
char text[30];
|
||||
uint32_t charPtr;
|
||||
};
|
||||
|
||||
class FormPlugin : public SubPlugin {
|
||||
public:
|
||||
FormPlugin(NPP inst);
|
||||
virtual ~FormPlugin();
|
||||
virtual bool supportsDrawingModel(ANPDrawingModel);
|
||||
virtual int16 handleEvent(const ANPEvent* evt);
|
||||
private:
|
||||
void draw(ANPCanvas*);
|
||||
void drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip);
|
||||
|
||||
bool m_hasFocus;
|
||||
|
||||
TextInput* m_activeInput;
|
||||
TextInput m_usernameInput;
|
||||
TextInput m_passwordInput;
|
||||
|
||||
ANPPaint* m_paintInput;
|
||||
ANPPaint* m_paintActive;
|
||||
ANPPaint* m_paintText;
|
||||
|
||||
ANPRectI m_visibleRect;
|
||||
|
||||
void drawText(ANPCanvas*, TextInput);
|
||||
void drawPassword(ANPCanvas*, TextInput);
|
||||
|
||||
bool handleNavigation(ANPKeyCode keyCode);
|
||||
void handleTextInput(TextInput* input, ANPKeyCode keyCode, int32_t unichar);
|
||||
void scrollIntoView(TextInput* input);
|
||||
void switchActiveInput(TextInput* input);
|
||||
|
||||
ANPPaint* getPaint(TextInput*);
|
||||
TextInput* validTap(int x, int y);
|
||||
|
||||
};
|
||||
|
||||
#endif // formPlugin__DEFINED
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <jni.h>
|
||||
#include <JNIHelp.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include "PluginObject.h"
|
||||
|
||||
#define EXPORT __attribute__((visibility("default")))
|
||||
|
||||
extern ANPEventInterfaceV0 gEventI;
|
||||
|
||||
static void surfaceCreated(JNIEnv* env, jobject thiz, jint npp, jobject surface) {
|
||||
|
||||
// send custom event
|
||||
ANPEvent event;
|
||||
event.inSize = sizeof(ANPEvent);
|
||||
event.eventType = kCustom_ANPEventType;
|
||||
event.data.other[0] = kSurfaceCreated_CustomEvent;
|
||||
|
||||
gEventI.postEvent((NPP)npp, &event);
|
||||
}
|
||||
|
||||
static void surfaceChanged(JNIEnv* env, jobject thiz, jint npp, jint format, jint width, jint height) {
|
||||
// send custom event
|
||||
ANPEvent event;
|
||||
event.inSize = sizeof(ANPEvent);
|
||||
event.eventType = kCustom_ANPEventType;
|
||||
event.data.other[0] = kSurfaceChanged_CustomEvent;
|
||||
event.data.other[1] = width;
|
||||
event.data.other[2] = height;
|
||||
|
||||
gEventI.postEvent((NPP)npp, &event);
|
||||
}
|
||||
|
||||
static void surfaceDestroyed(JNIEnv* env, jobject thiz, jint npp) {
|
||||
// send custom event
|
||||
ANPEvent event;
|
||||
event.inSize = sizeof(ANPEvent);
|
||||
event.eventType = kCustom_ANPEventType;
|
||||
event.data.other[0] = kSurfaceDestroyed_CustomEvent;
|
||||
|
||||
gEventI.postEvent((NPP)npp, &event);
|
||||
}
|
||||
|
||||
/*
|
||||
* JNI registration.
|
||||
*/
|
||||
static JNINativeMethod gPaintSurfaceMethods[] = {
|
||||
{ "nativeSurfaceCreated", "(I)V", (void*) surfaceCreated },
|
||||
{ "nativeSurfaceChanged", "(IIII)V", (void*) surfaceChanged },
|
||||
{ "nativeSurfaceDestroyed", "(I)V", (void*) surfaceDestroyed },
|
||||
};
|
||||
|
||||
EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
|
||||
JNIEnv* env = NULL;
|
||||
|
||||
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
jniRegisterNativeMethods(env, "com/android/sampleplugin/PaintSurface",
|
||||
gPaintSurfaceMethods, NELEM(gPaintSurfaceMethods));
|
||||
|
||||
return JNI_VERSION_1_4;
|
||||
}
|
||||
@@ -1,457 +0,0 @@
|
||||
/*
|
||||
* Copyright 2008, The Android Open Source Project
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "main.h"
|
||||
#include "PluginObject.h"
|
||||
#include "AnimationPlugin.h"
|
||||
#include "AudioPlugin.h"
|
||||
#include "BackgroundPlugin.h"
|
||||
#include "FormPlugin.h"
|
||||
#include "NavigationPlugin.h"
|
||||
#include "PaintPlugin.h"
|
||||
#include "VideoPlugin.h"
|
||||
|
||||
NPNetscapeFuncs* browser;
|
||||
JavaVM* gVM;
|
||||
|
||||
#define EXPORT __attribute__((visibility("default")))
|
||||
|
||||
NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
|
||||
char* argn[], char* argv[], NPSavedData* saved);
|
||||
NPError NPP_Destroy(NPP instance, NPSavedData** save);
|
||||
NPError NPP_SetWindow(NPP instance, NPWindow* window);
|
||||
NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream,
|
||||
NPBool seekable, uint16* stype);
|
||||
NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason);
|
||||
int32 NPP_WriteReady(NPP instance, NPStream* stream);
|
||||
int32 NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len,
|
||||
void* buffer);
|
||||
void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname);
|
||||
void NPP_Print(NPP instance, NPPrint* platformPrint);
|
||||
int16 NPP_HandleEvent(NPP instance, void* event);
|
||||
void NPP_URLNotify(NPP instance, const char* URL, NPReason reason,
|
||||
void* notifyData);
|
||||
NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value);
|
||||
NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value);
|
||||
|
||||
extern "C" {
|
||||
EXPORT NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env);
|
||||
EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value);
|
||||
EXPORT const char* NP_GetMIMEDescription(void);
|
||||
EXPORT void NP_Shutdown(void);
|
||||
};
|
||||
|
||||
ANPAudioTrackInterfaceV0 gSoundI;
|
||||
ANPBitmapInterfaceV0 gBitmapI;
|
||||
ANPCanvasInterfaceV0 gCanvasI;
|
||||
ANPEventInterfaceV0 gEventI;
|
||||
ANPLogInterfaceV0 gLogI;
|
||||
ANPPaintInterfaceV0 gPaintI;
|
||||
ANPPathInterfaceV0 gPathI;
|
||||
ANPSurfaceInterfaceV0 gSurfaceI;
|
||||
ANPSystemInterfaceV0 gSystemI;
|
||||
ANPTypefaceInterfaceV0 gTypefaceI;
|
||||
ANPWindowInterfaceV0 gWindowI;
|
||||
|
||||
#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
|
||||
#define DEBUG_PLUGIN_EVENTS 0
|
||||
|
||||
NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env)
|
||||
{
|
||||
// Make sure we have a function table equal or larger than we are built against.
|
||||
if (browserFuncs->size < sizeof(NPNetscapeFuncs)) {
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
// Copy the function table (structure)
|
||||
browser = (NPNetscapeFuncs*) malloc(sizeof(NPNetscapeFuncs));
|
||||
memcpy(browser, browserFuncs, sizeof(NPNetscapeFuncs));
|
||||
|
||||
// Build the plugin function table
|
||||
pluginFuncs->version = 11;
|
||||
pluginFuncs->size = sizeof(pluginFuncs);
|
||||
pluginFuncs->newp = NPP_New;
|
||||
pluginFuncs->destroy = NPP_Destroy;
|
||||
pluginFuncs->setwindow = NPP_SetWindow;
|
||||
pluginFuncs->newstream = NPP_NewStream;
|
||||
pluginFuncs->destroystream = NPP_DestroyStream;
|
||||
pluginFuncs->asfile = NPP_StreamAsFile;
|
||||
pluginFuncs->writeready = NPP_WriteReady;
|
||||
pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
|
||||
pluginFuncs->print = NPP_Print;
|
||||
pluginFuncs->event = NPP_HandleEvent;
|
||||
pluginFuncs->urlnotify = NPP_URLNotify;
|
||||
pluginFuncs->getvalue = NPP_GetValue;
|
||||
pluginFuncs->setvalue = NPP_SetValue;
|
||||
|
||||
static const struct {
|
||||
NPNVariable v;
|
||||
uint32_t size;
|
||||
ANPInterface* i;
|
||||
} gPairs[] = {
|
||||
{ kAudioTrackInterfaceV0_ANPGetValue, sizeof(gSoundI), &gSoundI },
|
||||
{ kBitmapInterfaceV0_ANPGetValue, sizeof(gBitmapI), &gBitmapI },
|
||||
{ kCanvasInterfaceV0_ANPGetValue, sizeof(gCanvasI), &gCanvasI },
|
||||
{ kEventInterfaceV0_ANPGetValue, sizeof(gEventI), &gEventI },
|
||||
{ kLogInterfaceV0_ANPGetValue, sizeof(gLogI), &gLogI },
|
||||
{ kPaintInterfaceV0_ANPGetValue, sizeof(gPaintI), &gPaintI },
|
||||
{ kPathInterfaceV0_ANPGetValue, sizeof(gPathI), &gPathI },
|
||||
{ kSurfaceInterfaceV0_ANPGetValue, sizeof(gSurfaceI), &gSurfaceI },
|
||||
{ kSystemInterfaceV0_ANPGetValue, sizeof(gSystemI), &gSystemI },
|
||||
{ kTypefaceInterfaceV0_ANPGetValue, sizeof(gTypefaceI), &gTypefaceI },
|
||||
{ kWindowInterfaceV0_ANPGetValue, sizeof(gWindowI), &gWindowI },
|
||||
};
|
||||
for (size_t i = 0; i < ARRAY_COUNT(gPairs); i++) {
|
||||
gPairs[i].i->inSize = gPairs[i].size;
|
||||
NPError err = browser->getvalue(NULL, gPairs[i].v, gPairs[i].i);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
// store the JavaVM for the plugin
|
||||
JNIEnv* env = (JNIEnv*)java_env;
|
||||
env->GetJavaVM(&gVM);
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
void NP_Shutdown(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const char *NP_GetMIMEDescription(void)
|
||||
{
|
||||
return "application/x-testbrowserplugin:tst:Test plugin mimetype is application/x-testbrowserplugin";
|
||||
}
|
||||
|
||||
NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
|
||||
char* argn[], char* argv[], NPSavedData* saved)
|
||||
{
|
||||
|
||||
/* BEGIN: STANDARD PLUGIN FRAMEWORK */
|
||||
PluginObject *obj = NULL;
|
||||
|
||||
// Scripting functions appeared in NPAPI version 14
|
||||
if (browser->version >= 14) {
|
||||
instance->pdata = browser->createobject (instance, getPluginClass());
|
||||
obj = static_cast<PluginObject*>(instance->pdata);
|
||||
}
|
||||
/* END: STANDARD PLUGIN FRAMEWORK */
|
||||
|
||||
// select the drawing model based on user input
|
||||
ANPDrawingModel model = kBitmap_ANPDrawingModel;
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (!strcmp(argn[i], "DrawingModel")) {
|
||||
if (!strcmp(argv[i], "Bitmap")) {
|
||||
model = kBitmap_ANPDrawingModel;
|
||||
}
|
||||
else if (!strcmp(argv[i], "Surface")) {
|
||||
model = kSurface_ANPDrawingModel;
|
||||
}
|
||||
gLogI.log(kDebug_ANPLogType, "------ %p DrawingModel is %d", instance, model);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// notify the plugin API of the drawing model we wish to use. This must be
|
||||
// done prior to creating certain subPlugin objects (e.g. surfaceViews)
|
||||
NPError err = browser->setvalue(instance, kRequestDrawingModel_ANPSetValue,
|
||||
reinterpret_cast<void*>(model));
|
||||
if (err) {
|
||||
gLogI.log(kError_ANPLogType, "request model %d err %d", model, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
const char* path = gSystemI.getApplicationDataDirectory();
|
||||
if (path) {
|
||||
gLogI.log(kDebug_ANPLogType, "Application data dir is %s", path);
|
||||
} else {
|
||||
gLogI.log(kError_ANPLogType, "Can't find Application data dir");
|
||||
}
|
||||
|
||||
// select the pluginType
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (!strcmp(argn[i], "PluginType")) {
|
||||
if (!strcmp(argv[i], "Animation")) {
|
||||
obj->pluginType = kAnimation_PluginType;
|
||||
obj->activePlugin = new BallAnimation(instance);
|
||||
}
|
||||
else if (!strcmp(argv[i], "Audio")) {
|
||||
obj->pluginType = kAudio_PluginType;
|
||||
obj->activePlugin = new AudioPlugin(instance);
|
||||
}
|
||||
else if (!strcmp(argv[i], "Background")) {
|
||||
obj->pluginType = kBackground_PluginType;
|
||||
obj->activePlugin = new BackgroundPlugin(instance);
|
||||
}
|
||||
else if (!strcmp(argv[i], "Form")) {
|
||||
obj->pluginType = kForm_PluginType;
|
||||
obj->activePlugin = new FormPlugin(instance);
|
||||
}
|
||||
else if (!strcmp(argv[i], "Navigation")) {
|
||||
obj->pluginType = kNavigation_PluginType;
|
||||
obj->activePlugin = new NavigationPlugin(instance);
|
||||
}
|
||||
else if (!strcmp(argv[i], "Paint")) {
|
||||
obj->pluginType = kPaint_PluginType;
|
||||
obj->activePlugin = new PaintPlugin(instance);
|
||||
}
|
||||
else if (!strcmp(argv[i], "Video")) {
|
||||
obj->pluginType = kVideo_PluginType;
|
||||
obj->activePlugin = new VideoPlugin(instance);
|
||||
}
|
||||
gLogI.log(kDebug_ANPLogType, "------ %p PluginType is %d", instance, obj->pluginType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if no pluginType is specified then default to Animation
|
||||
if (!obj->pluginType) {
|
||||
gLogI.log(kError_ANPLogType, "------ %p No PluginType attribute was found", instance);
|
||||
obj->pluginType = kAnimation_PluginType;
|
||||
obj->activePlugin = new BallAnimation(instance);
|
||||
}
|
||||
|
||||
// check to ensure the pluginType supports the model
|
||||
if (!obj->activePlugin->supportsDrawingModel(model)) {
|
||||
gLogI.log(kError_ANPLogType, "------ %p Unsupported DrawingModel (%d)", instance, model);
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
// if the plugin uses the surface drawing model then set the java context
|
||||
if (model == kSurface_ANPDrawingModel) {
|
||||
SurfaceSubPlugin* surfacePlugin = static_cast<SurfaceSubPlugin*>(obj->activePlugin);
|
||||
|
||||
jobject context;
|
||||
NPError err = browser->getvalue(instance, kJavaContext_ANPGetValue,
|
||||
static_cast<void*>(&context));
|
||||
if (err) {
|
||||
gLogI.log(kError_ANPLogType, "request context err: %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
surfacePlugin->setContext(context);
|
||||
}
|
||||
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
NPError NPP_Destroy(NPP instance, NPSavedData** save)
|
||||
{
|
||||
PluginObject *obj = (PluginObject*) instance->pdata;
|
||||
if (obj) {
|
||||
delete obj->activePlugin;
|
||||
browser->releaseobject(&obj->header);
|
||||
}
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
NPError NPP_SetWindow(NPP instance, NPWindow* window)
|
||||
{
|
||||
PluginObject *obj = (PluginObject*) instance->pdata;
|
||||
|
||||
// Do nothing if browser didn't support NPN_CreateObject which would have created the PluginObject.
|
||||
if (obj != NULL) {
|
||||
obj->window = window;
|
||||
}
|
||||
|
||||
browser->invalidaterect(instance, NULL);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int32 NPP_WriteReady(NPP instance, NPStream* stream)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
|
||||
{
|
||||
}
|
||||
|
||||
void NPP_Print(NPP instance, NPPrint* platformPrint)
|
||||
{
|
||||
}
|
||||
|
||||
int16 NPP_HandleEvent(NPP instance, void* event)
|
||||
{
|
||||
PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
|
||||
const ANPEvent* evt = reinterpret_cast<const ANPEvent*>(event);
|
||||
|
||||
#if DEBUG_PLUGIN_EVENTS
|
||||
switch (evt->eventType) {
|
||||
case kDraw_ANPEventType:
|
||||
|
||||
if (evt->data.draw.model == kBitmap_ANPDrawingModel) {
|
||||
|
||||
static ANPBitmapFormat currentFormat = -1;
|
||||
if (evt->data.draw.data.bitmap.format != currentFormat) {
|
||||
currentFormat = evt->data.draw.data.bitmap.format;
|
||||
gLogI.log(kDebug_ANPLogType, "---- %p Draw (bitmap)"
|
||||
" clip=%d,%d,%d,%d format=%d", instance,
|
||||
evt->data.draw.clip.left,
|
||||
evt->data.draw.clip.top,
|
||||
evt->data.draw.clip.right,
|
||||
evt->data.draw.clip.bottom,
|
||||
evt->data.draw.data.bitmap.format);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kKey_ANPEventType:
|
||||
gLogI.log(kDebug_ANPLogType, "---- %p Key action=%d"
|
||||
" code=%d vcode=%d unichar=%d repeat=%d mods=%x", instance,
|
||||
evt->data.key.action,
|
||||
evt->data.key.nativeCode,
|
||||
evt->data.key.virtualCode,
|
||||
evt->data.key.unichar,
|
||||
evt->data.key.repeatCount,
|
||||
evt->data.key.modifiers);
|
||||
break;
|
||||
|
||||
case kLifecycle_ANPEventType:
|
||||
gLogI.log(kDebug_ANPLogType, "---- %p Lifecycle action=%d",
|
||||
instance, evt->data.lifecycle.action);
|
||||
break;
|
||||
|
||||
case kTouch_ANPEventType:
|
||||
gLogI.log(kDebug_ANPLogType, "---- %p Touch action=%d [%d %d]",
|
||||
instance, evt->data.touch.action, evt->data.touch.x,
|
||||
evt->data.touch.y);
|
||||
break;
|
||||
|
||||
case kMouse_ANPEventType:
|
||||
gLogI.log(kDebug_ANPLogType, "---- %p Mouse action=%d [%d %d]",
|
||||
instance, evt->data.mouse.action, evt->data.mouse.x,
|
||||
evt->data.mouse.y);
|
||||
break;
|
||||
|
||||
case kVisibleRect_ANPEventType:
|
||||
gLogI.log(kDebug_ANPLogType, "---- %p VisibleRect [%d %d %d %d]",
|
||||
instance, evt->data.visibleRect.rect.left, evt->data.visibleRect.rect.top,
|
||||
evt->data.visibleRect.rect.right, evt->data.visibleRect.rect.bottom);
|
||||
break;
|
||||
|
||||
default:
|
||||
gLogI.log(kError_ANPLogType, "---- %p Unknown Event [%d]",
|
||||
instance, evt->eventType);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!obj->activePlugin) {
|
||||
gLogI.log(kError_ANPLogType, "the active plugin is null.");
|
||||
return 0; // unknown or unhandled event
|
||||
}
|
||||
else {
|
||||
return obj->activePlugin->handleEvent(evt);
|
||||
}
|
||||
}
|
||||
|
||||
void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value) {
|
||||
|
||||
if (variable == NPPVpluginNameString) {
|
||||
const char **str = (const char **)value;
|
||||
*str = "Test Plugin";
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
if (variable == NPPVpluginDescriptionString) {
|
||||
const char **str = (const char **)value;
|
||||
*str = "Description of Test Plugin";
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
NPError NPP_GetValue(NPP instance, NPPVariable variable, void* value)
|
||||
{
|
||||
if (variable == NPPVpluginScriptableNPObject) {
|
||||
void **v = (void **)value;
|
||||
PluginObject *obj = (PluginObject*) instance->pdata;
|
||||
|
||||
if (obj)
|
||||
browser->retainobject(&obj->header);
|
||||
|
||||
*v = &(obj->header);
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
if (variable == kJavaSurface_ANPGetValue) {
|
||||
//get the surface sub-plugin
|
||||
PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
|
||||
if (obj && obj->activePlugin) {
|
||||
|
||||
if(obj->activePlugin->supportsDrawingModel(kSurface_ANPDrawingModel)) {
|
||||
SurfaceSubPlugin* plugin = static_cast<SurfaceSubPlugin*>(obj->activePlugin);
|
||||
jobject* surface = static_cast<jobject*>(value);
|
||||
*surface = plugin->getSurface();
|
||||
return NPERR_NO_ERROR;
|
||||
} else {
|
||||
gLogI.log(kError_ANPLogType,
|
||||
"-- %p Tried to retrieve surface for non-surface plugin",
|
||||
instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value)
|
||||
{
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2008, The Android Open Source Project
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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 <npapi.h>
|
||||
#include <npfunctions.h>
|
||||
#include <npruntime.h>
|
||||
#include "android_npapi.h"
|
||||
#include "ANPSurface_npapi.h"
|
||||
#include "ANPSystem_npapi.h"
|
||||
|
||||
extern NPNetscapeFuncs* browser;
|
||||
extern JavaVM* gVM;
|
||||
@@ -1,242 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010, The Android Open Source Project
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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 "NavigationPlugin.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
extern NPNetscapeFuncs* browser;
|
||||
extern ANPLogInterfaceV0 gLogI;
|
||||
extern ANPCanvasInterfaceV0 gCanvasI;
|
||||
extern ANPPaintInterfaceV0 gPaintI;
|
||||
extern ANPTypefaceInterfaceV0 gTypefaceI;
|
||||
extern ANPWindowInterfaceV0 gWindowI;
|
||||
|
||||
|
||||
static void inval(NPP instance) {
|
||||
browser->invalidaterect(instance, NULL);
|
||||
}
|
||||
|
||||
static uint16 rnd16(float x, int inset) {
|
||||
int ix = (int)roundf(x) + inset;
|
||||
if (ix < 0) {
|
||||
ix = 0;
|
||||
}
|
||||
return static_cast<uint16>(ix);
|
||||
}
|
||||
|
||||
static void inval(NPP instance, const ANPRectF& r, bool doAA) {
|
||||
const int inset = doAA ? -1 : 0;
|
||||
|
||||
PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
|
||||
NPRect inval;
|
||||
inval.left = rnd16(r.left, inset);
|
||||
inval.top = rnd16(r.top, inset);
|
||||
inval.right = rnd16(r.right, -inset);
|
||||
inval.bottom = rnd16(r.bottom, -inset);
|
||||
browser->invalidaterect(instance, &inval);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NavigationPlugin::NavigationPlugin(NPP inst) : SubPlugin(inst) {
|
||||
|
||||
m_hasFocus = false;
|
||||
m_activeNav = NULL;
|
||||
|
||||
m_paintDisabled = gPaintI.newPaint();
|
||||
gPaintI.setFlags(m_paintDisabled, gPaintI.getFlags(m_paintDisabled) | kAntiAlias_ANPPaintFlag);
|
||||
gPaintI.setColor(m_paintDisabled, 0xFFFFFFFF);
|
||||
|
||||
m_paintActive = gPaintI.newPaint();
|
||||
gPaintI.setFlags(m_paintActive, gPaintI.getFlags(m_paintActive) | kAntiAlias_ANPPaintFlag);
|
||||
gPaintI.setColor(m_paintActive, 0xFFFFFF00);
|
||||
|
||||
//register for key events
|
||||
ANPEventFlags flags = kKey_ANPEventFlag;
|
||||
NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
|
||||
if (err != NPERR_NO_ERROR) {
|
||||
gLogI.log(kError_ANPLogType, "Error selecting input events.");
|
||||
}
|
||||
}
|
||||
|
||||
NavigationPlugin::~NavigationPlugin() {
|
||||
gPaintI.deletePaint(m_paintDisabled);
|
||||
gPaintI.deletePaint(m_paintActive);
|
||||
}
|
||||
|
||||
bool NavigationPlugin::supportsDrawingModel(ANPDrawingModel model) {
|
||||
return (model == kBitmap_ANPDrawingModel);
|
||||
}
|
||||
|
||||
void NavigationPlugin::drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip) {
|
||||
ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
|
||||
|
||||
ANPRectF clipR;
|
||||
clipR.left = clip.left;
|
||||
clipR.top = clip.top;
|
||||
clipR.right = clip.right;
|
||||
clipR.bottom = clip.bottom;
|
||||
gCanvasI.clipRect(canvas, &clipR);
|
||||
|
||||
draw(canvas);
|
||||
gCanvasI.deleteCanvas(canvas);
|
||||
}
|
||||
|
||||
void NavigationPlugin::draw(ANPCanvas* canvas) {
|
||||
NPP instance = this->inst();
|
||||
PluginObject *obj = (PluginObject*) instance->pdata;
|
||||
|
||||
const int W = obj->window->width;
|
||||
const int H = obj->window->height;
|
||||
const int Wm = W/2;
|
||||
const int Hm = H/2;
|
||||
|
||||
// color the plugin canvas
|
||||
gCanvasI.drawColor(canvas, (m_hasFocus) ? 0xFFCDCDCD : 0xFF545454);
|
||||
|
||||
// draw the nav up box (5 px from the top edge)
|
||||
m_navUp.left = Wm - 15;
|
||||
m_navUp.top = 5;
|
||||
m_navUp.right = m_navUp.left + 30;
|
||||
m_navUp.bottom = m_navUp.top + 30;
|
||||
gCanvasI.drawRect(canvas, &m_navUp, getPaint(&m_navUp));
|
||||
|
||||
// draw the nav down box (5 px from the bottom edge)
|
||||
m_navDown.left = Wm - 15;
|
||||
m_navDown.top = H - (30 + 5);
|
||||
m_navDown.right = m_navDown.left + 30;
|
||||
m_navDown.bottom = m_navDown.top + 30;
|
||||
gCanvasI.drawRect(canvas, &m_navDown, getPaint(&m_navDown));
|
||||
|
||||
// draw the nav left box (5 px from the left edge)
|
||||
m_navLeft.left = 5;
|
||||
m_navLeft.top = Hm - 15;
|
||||
m_navLeft.right = m_navLeft.left + 30;
|
||||
m_navLeft.bottom = m_navLeft.top + 30;
|
||||
gCanvasI.drawRect(canvas, &m_navLeft, getPaint(&m_navLeft));
|
||||
|
||||
// draw the nav right box (5 px from the right edge)
|
||||
m_navRight.left = W - (30 + 5);
|
||||
m_navRight.top = Hm - 15;
|
||||
m_navRight.right = m_navRight.left + 30;
|
||||
m_navRight.bottom = m_navRight.top + 30;
|
||||
gCanvasI.drawRect(canvas, &m_navRight, getPaint(&m_navRight));
|
||||
|
||||
// draw the nav center box
|
||||
m_navCenter.left = Wm - 15;
|
||||
m_navCenter.top = Hm - 15;
|
||||
m_navCenter.right = m_navCenter.left + 30;
|
||||
m_navCenter.bottom = m_navCenter.top + 30;
|
||||
gCanvasI.drawRect(canvas, &m_navCenter, getPaint(&m_navCenter));
|
||||
|
||||
gLogI.log(kDebug_ANPLogType, "----%p Drawing Plugin", inst());
|
||||
}
|
||||
|
||||
ANPPaint* NavigationPlugin::getPaint(ANPRectF* input) {
|
||||
return (input == m_activeNav) ? m_paintActive : m_paintDisabled;
|
||||
}
|
||||
|
||||
int16 NavigationPlugin::handleEvent(const ANPEvent* evt) {
|
||||
NPP instance = this->inst();
|
||||
|
||||
switch (evt->eventType) {
|
||||
case kDraw_ANPEventType:
|
||||
switch (evt->data.draw.model) {
|
||||
case kBitmap_ANPDrawingModel:
|
||||
drawPlugin(evt->data.draw.data.bitmap, evt->data.draw.clip);
|
||||
return 1;
|
||||
default:
|
||||
break; // unknown drawing model
|
||||
}
|
||||
break;
|
||||
|
||||
case kLifecycle_ANPEventType:
|
||||
if (evt->data.lifecycle.action == kLoseFocus_ANPLifecycleAction) {
|
||||
gLogI.log(kDebug_ANPLogType, "----%p Loosing Focus", instance);
|
||||
m_hasFocus = false;
|
||||
inval(instance);
|
||||
return 1;
|
||||
}
|
||||
else if (evt->data.lifecycle.action == kGainFocus_ANPLifecycleAction) {
|
||||
gLogI.log(kDebug_ANPLogType, "----%p Gaining Focus", instance);
|
||||
m_hasFocus = true;
|
||||
inval(instance);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case kMouse_ANPEventType:
|
||||
return 1;
|
||||
|
||||
case kKey_ANPEventType:
|
||||
if (evt->data.key.action == kDown_ANPKeyAction) {
|
||||
bool result = handleNavigation(evt->data.key.nativeCode);
|
||||
inval(instance);
|
||||
return result;
|
||||
}
|
||||
return 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0; // unknown or unhandled event
|
||||
}
|
||||
|
||||
bool NavigationPlugin::handleNavigation(ANPKeyCode keyCode) {
|
||||
NPP instance = this->inst();
|
||||
|
||||
gLogI.log(kDebug_ANPLogType, "----%p Received Key %d", instance, keyCode);
|
||||
|
||||
switch (keyCode) {
|
||||
case kDpadUp_ANPKeyCode:
|
||||
m_activeNav = &m_navUp;
|
||||
break;
|
||||
case kDpadDown_ANPKeyCode:
|
||||
m_activeNav = &m_navDown;
|
||||
break;
|
||||
case kDpadLeft_ANPKeyCode:
|
||||
m_activeNav = &m_navLeft;
|
||||
break;
|
||||
case kDpadRight_ANPKeyCode:
|
||||
m_activeNav = &m_navRight;
|
||||
break;
|
||||
case kDpadCenter_ANPKeyCode:
|
||||
m_activeNav = &m_navCenter;
|
||||
break;
|
||||
case kQ_ANPKeyCode:
|
||||
case kDel_ANPKeyCode:
|
||||
m_activeNav = NULL;
|
||||
return false;
|
||||
default:
|
||||
m_activeNav = NULL;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010, The Android Open Source Project
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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 "PluginObject.h"
|
||||
|
||||
#ifndef navigationPlugin__DEFINED
|
||||
#define navigationPlugin__DEFINED
|
||||
|
||||
class NavigationPlugin : public SubPlugin {
|
||||
public:
|
||||
NavigationPlugin(NPP inst);
|
||||
virtual ~NavigationPlugin();
|
||||
virtual bool supportsDrawingModel(ANPDrawingModel);
|
||||
virtual int16 handleEvent(const ANPEvent* evt);
|
||||
private:
|
||||
void draw(ANPCanvas*);
|
||||
void drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip);
|
||||
|
||||
bool m_hasFocus;
|
||||
|
||||
ANPRectF* m_activeNav;
|
||||
ANPRectF m_navUp;
|
||||
ANPRectF m_navDown;
|
||||
ANPRectF m_navLeft;
|
||||
ANPRectF m_navRight;
|
||||
ANPRectF m_navCenter;
|
||||
|
||||
ANPPaint* m_paintDisabled;
|
||||
ANPPaint* m_paintActive;
|
||||
|
||||
bool handleNavigation(ANPKeyCode keyCode);
|
||||
ANPPaint* getPaint(ANPRectF*);
|
||||
};
|
||||
|
||||
#endif // navigationPlugin__DEFINED
|
||||
@@ -1,462 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009, The Android Open Source Project
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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 "PaintPlugin.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
extern NPNetscapeFuncs* browser;
|
||||
extern ANPLogInterfaceV0 gLogI;
|
||||
extern ANPCanvasInterfaceV0 gCanvasI;
|
||||
extern ANPPaintInterfaceV0 gPaintI;
|
||||
extern ANPPathInterfaceV0 gPathI;
|
||||
extern ANPSurfaceInterfaceV0 gSurfaceI;
|
||||
extern ANPSystemInterfaceV0 gSystemI;
|
||||
extern ANPTypefaceInterfaceV0 gTypefaceI;
|
||||
extern ANPWindowInterfaceV0 gWindowI;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PaintPlugin::PaintPlugin(NPP inst) : SurfaceSubPlugin(inst) {
|
||||
|
||||
m_isTouchActive = false;
|
||||
m_isTouchCurrentInput = true;
|
||||
m_activePaintColor = s_redColor;
|
||||
|
||||
memset(&m_drawingSurface, 0, sizeof(m_drawingSurface));
|
||||
memset(&m_inputToggle, 0, sizeof(m_inputToggle));
|
||||
memset(&m_colorToggle, 0, sizeof(m_colorToggle));
|
||||
memset(&m_fullScreenToggle, 0, sizeof(m_fullScreenToggle));
|
||||
memset(&m_clearSurface, 0, sizeof(m_clearSurface));
|
||||
|
||||
// initialize the drawing surface
|
||||
m_surface = NULL;
|
||||
|
||||
// initialize the path
|
||||
m_touchPath = gPathI.newPath();
|
||||
if(!m_touchPath)
|
||||
gLogI.log(kError_ANPLogType, "----%p Unable to create the touch path", inst);
|
||||
|
||||
// initialize the paint colors
|
||||
m_paintSurface = gPaintI.newPaint();
|
||||
gPaintI.setFlags(m_paintSurface, gPaintI.getFlags(m_paintSurface) | kAntiAlias_ANPPaintFlag);
|
||||
gPaintI.setColor(m_paintSurface, 0xFFC0C0C0);
|
||||
gPaintI.setTextSize(m_paintSurface, 18);
|
||||
|
||||
m_paintButton = gPaintI.newPaint();
|
||||
gPaintI.setFlags(m_paintButton, gPaintI.getFlags(m_paintButton) | kAntiAlias_ANPPaintFlag);
|
||||
gPaintI.setColor(m_paintButton, 0xFFA8A8A8);
|
||||
|
||||
// initialize the typeface (set the colors)
|
||||
ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
|
||||
gPaintI.setTypeface(m_paintSurface, tf);
|
||||
gTypefaceI.unref(tf);
|
||||
|
||||
//register for touch events
|
||||
ANPEventFlags flags = kTouch_ANPEventFlag;
|
||||
NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
|
||||
if (err != NPERR_NO_ERROR) {
|
||||
gLogI.log(kError_ANPLogType, "Error selecting input events.");
|
||||
}
|
||||
}
|
||||
|
||||
PaintPlugin::~PaintPlugin() {
|
||||
gPathI.deletePath(m_touchPath);
|
||||
gPaintI.deletePaint(m_paintSurface);
|
||||
gPaintI.deletePaint(m_paintButton);
|
||||
|
||||
setContext(NULL);
|
||||
destroySurface();
|
||||
}
|
||||
|
||||
ANPCanvas* PaintPlugin::getCanvas(ANPRectI* dirtyRect) {
|
||||
|
||||
ANPBitmap bitmap;
|
||||
JNIEnv* env = NULL;
|
||||
if (!m_surface || gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK ||
|
||||
!gSurfaceI.lock(env, m_surface, &bitmap, dirtyRect)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
|
||||
|
||||
// clip the canvas to the dirty rect b/c the surface is only required to
|
||||
// copy a minimum of the dirty rect and may copy more. The clipped canvas
|
||||
// however will never write to pixels outside of the clipped area.
|
||||
if (dirtyRect) {
|
||||
ANPRectF clipR;
|
||||
clipR.left = dirtyRect->left;
|
||||
clipR.top = dirtyRect->top;
|
||||
clipR.right = dirtyRect->right;
|
||||
clipR.bottom = dirtyRect->bottom;
|
||||
gCanvasI.clipRect(canvas, &clipR);
|
||||
}
|
||||
|
||||
return canvas;
|
||||
}
|
||||
|
||||
ANPCanvas* PaintPlugin::getCanvas(ANPRectF* dirtyRect) {
|
||||
|
||||
ANPRectI newRect;
|
||||
newRect.left = (int) dirtyRect->left;
|
||||
newRect.top = (int) dirtyRect->top;
|
||||
newRect.right = (int) dirtyRect->right;
|
||||
newRect.bottom = (int) dirtyRect->bottom;
|
||||
|
||||
return getCanvas(&newRect);
|
||||
}
|
||||
|
||||
void PaintPlugin::releaseCanvas(ANPCanvas* canvas) {
|
||||
JNIEnv* env = NULL;
|
||||
if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
|
||||
gSurfaceI.unlock(env, m_surface);
|
||||
}
|
||||
gCanvasI.deleteCanvas(canvas);
|
||||
}
|
||||
|
||||
void PaintPlugin::drawCleanPlugin(ANPCanvas* canvas) {
|
||||
NPP instance = this->inst();
|
||||
PluginObject *obj = (PluginObject*) instance->pdata;
|
||||
|
||||
// if no canvas get a locked canvas
|
||||
if (!canvas)
|
||||
canvas = getCanvas();
|
||||
|
||||
if (!canvas)
|
||||
return;
|
||||
|
||||
const float buttonWidth = 60;
|
||||
const float buttonHeight = 30;
|
||||
const int W = obj->window->width;
|
||||
const int H = obj->window->height;
|
||||
|
||||
// color the plugin canvas
|
||||
gCanvasI.drawColor(canvas, 0xFFCDCDCD);
|
||||
|
||||
// get font metrics
|
||||
ANPFontMetrics fontMetrics;
|
||||
gPaintI.getFontMetrics(m_paintSurface, &fontMetrics);
|
||||
|
||||
// draw the input toggle button
|
||||
m_inputToggle.left = 5;
|
||||
m_inputToggle.top = H - buttonHeight - 5;
|
||||
m_inputToggle.right = m_inputToggle.left + buttonWidth;
|
||||
m_inputToggle.bottom = m_inputToggle.top + buttonHeight;
|
||||
gCanvasI.drawRect(canvas, &m_inputToggle, m_paintButton);
|
||||
const char* inputText = m_isTouchCurrentInput ? "Touch" : "Mouse";
|
||||
gCanvasI.drawText(canvas, inputText, strlen(inputText), m_inputToggle.left + 5,
|
||||
m_inputToggle.top - fontMetrics.fTop, m_paintSurface);
|
||||
|
||||
// draw the color selector button
|
||||
m_colorToggle.left = (W/3) - (buttonWidth/2);
|
||||
m_colorToggle.top = H - buttonHeight - 5;
|
||||
m_colorToggle.right = m_colorToggle.left + buttonWidth;
|
||||
m_colorToggle.bottom = m_colorToggle.top + buttonHeight;
|
||||
gCanvasI.drawRect(canvas, &m_colorToggle, m_paintButton);
|
||||
const char* colorText = getColorText();
|
||||
gCanvasI.drawText(canvas, colorText, strlen(colorText), m_colorToggle.left + 5,
|
||||
m_colorToggle.top - fontMetrics.fTop, m_paintSurface);
|
||||
|
||||
// draw the full-screen toggle button
|
||||
m_fullScreenToggle.left = ((W*2)/3) - (buttonWidth/2);
|
||||
m_fullScreenToggle.top = H - buttonHeight - 5;
|
||||
m_fullScreenToggle.right = m_fullScreenToggle.left + buttonWidth;
|
||||
m_fullScreenToggle.bottom = m_fullScreenToggle.top + buttonHeight;
|
||||
gCanvasI.drawRect(canvas, &m_fullScreenToggle, m_paintButton);
|
||||
const char* fullScreenText = "Full";
|
||||
gCanvasI.drawText(canvas, fullScreenText, strlen(fullScreenText),
|
||||
m_fullScreenToggle.left + 5,
|
||||
m_fullScreenToggle.top - fontMetrics.fTop, m_paintSurface);
|
||||
|
||||
// draw the clear canvas button
|
||||
m_clearSurface.left = W - buttonWidth - 5;
|
||||
m_clearSurface.top = H - buttonHeight - 5;
|
||||
m_clearSurface.right = m_clearSurface.left + buttonWidth;
|
||||
m_clearSurface.bottom = m_clearSurface.top + buttonHeight;
|
||||
gCanvasI.drawRect(canvas, &m_clearSurface, m_paintButton);
|
||||
const char* clearText = "Clear";
|
||||
gCanvasI.drawText(canvas, clearText, strlen(clearText), m_clearSurface.left + 5,
|
||||
m_clearSurface.top - fontMetrics.fTop, m_paintSurface);
|
||||
|
||||
// draw the drawing surface box (5 px from the edge)
|
||||
m_drawingSurface.left = 5;
|
||||
m_drawingSurface.top = 5;
|
||||
m_drawingSurface.right = W - 5;
|
||||
m_drawingSurface.bottom = m_colorToggle.top - 5;
|
||||
gCanvasI.drawRect(canvas, &m_drawingSurface, m_paintSurface);
|
||||
|
||||
// release the canvas
|
||||
releaseCanvas(canvas);
|
||||
}
|
||||
|
||||
const char* PaintPlugin::getColorText() {
|
||||
|
||||
if (m_activePaintColor == s_blueColor)
|
||||
return "Blue";
|
||||
else if (m_activePaintColor == s_greenColor)
|
||||
return "Green";
|
||||
else
|
||||
return "Red";
|
||||
}
|
||||
|
||||
jobject PaintPlugin::getSurface() {
|
||||
if (m_surface) {
|
||||
return m_surface;
|
||||
}
|
||||
|
||||
// load the appropriate java class and instantiate it
|
||||
JNIEnv* env = NULL;
|
||||
if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
|
||||
gLogI.log(kError_ANPLogType, " ---- getSurface: failed to get env");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* className = "com.android.sampleplugin.PaintSurface";
|
||||
jclass paintClass = gSystemI.loadJavaClass(inst(), className);
|
||||
|
||||
if(!paintClass) {
|
||||
gLogI.log(kError_ANPLogType, " ---- getSurface: failed to load class");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PluginObject *obj = (PluginObject*) inst()->pdata;
|
||||
const int pW = obj->window->width;
|
||||
const int pH = obj->window->height;
|
||||
|
||||
jmethodID constructor = env->GetMethodID(paintClass, "<init>", "(Landroid/content/Context;III)V");
|
||||
jobject paintSurface = env->NewObject(paintClass, constructor, m_context, (int)inst(), pW, pH);
|
||||
|
||||
if(!paintSurface) {
|
||||
gLogI.log(kError_ANPLogType, " ---- getSurface: failed to construct object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m_surface = env->NewGlobalRef(paintSurface);
|
||||
return m_surface;
|
||||
}
|
||||
|
||||
void PaintPlugin::destroySurface() {
|
||||
JNIEnv* env = NULL;
|
||||
if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
|
||||
|
||||
// detach the native code from the object
|
||||
jclass javaClass = env->GetObjectClass(m_surface);
|
||||
jmethodID invalMethod = env->GetMethodID(javaClass, "invalidateNPP", "()V");
|
||||
env->CallVoidMethod(m_surface, invalMethod);
|
||||
|
||||
env->DeleteGlobalRef(m_surface);
|
||||
m_surface = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int16 PaintPlugin::handleEvent(const ANPEvent* evt) {
|
||||
switch (evt->eventType) {
|
||||
case kTouch_ANPEventType: {
|
||||
float x = (float) evt->data.touch.x;
|
||||
float y = (float) evt->data.touch.y;
|
||||
if (kDown_ANPTouchAction == evt->data.touch.action && m_isTouchCurrentInput) {
|
||||
|
||||
ANPRectF* rect = validTouch(evt->data.touch.x, evt->data.touch.y);
|
||||
if(rect == &m_drawingSurface) {
|
||||
m_isTouchActive = true;
|
||||
gPathI.moveTo(m_touchPath, x, y);
|
||||
paintTouch();
|
||||
return 1;
|
||||
}
|
||||
|
||||
} else if (kMove_ANPTouchAction == evt->data.touch.action && m_isTouchActive) {
|
||||
gPathI.lineTo(m_touchPath, x, y);
|
||||
paintTouch();
|
||||
return 1;
|
||||
} else if (kUp_ANPTouchAction == evt->data.touch.action && m_isTouchActive) {
|
||||
gPathI.lineTo(m_touchPath, x, y);
|
||||
paintTouch();
|
||||
m_isTouchActive = false;
|
||||
gPathI.reset(m_touchPath);
|
||||
return 1;
|
||||
} else if (kCancel_ANPTouchAction == evt->data.touch.action) {
|
||||
m_isTouchActive = false;
|
||||
gPathI.reset(m_touchPath);
|
||||
return 1;
|
||||
} else if (kDoubleTap_ANPTouchAction == evt->data.touch.action) {
|
||||
gWindowI.requestCenterFitZoom(inst());
|
||||
return 1;
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kMouse_ANPEventType: {
|
||||
|
||||
if (m_isTouchActive)
|
||||
gLogI.log(kError_ANPLogType, "----%p Received unintended mouse event", inst());
|
||||
|
||||
if (kDown_ANPMouseAction == evt->data.mouse.action) {
|
||||
ANPRectF* rect = validTouch(evt->data.mouse.x, evt->data.mouse.y);
|
||||
if (rect == &m_drawingSurface)
|
||||
paintMouse(evt->data.mouse.x, evt->data.mouse.y);
|
||||
else if (rect == &m_inputToggle)
|
||||
toggleInputMethod();
|
||||
else if (rect == &m_colorToggle)
|
||||
togglePaintColor();
|
||||
else if (rect == &m_fullScreenToggle)
|
||||
gWindowI.requestFullScreen(inst());
|
||||
else if (rect == &m_clearSurface)
|
||||
drawCleanPlugin();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
case kCustom_ANPEventType: {
|
||||
|
||||
switch (evt->data.other[0]) {
|
||||
case kSurfaceCreated_CustomEvent:
|
||||
gLogI.log(kDebug_ANPLogType, " ---- customEvent: surfaceCreated");
|
||||
/* The second draw call is added to cover up a problem in this
|
||||
plugin and is not a recommended usage pattern. This plugin
|
||||
does not correctly make partial updates to the double
|
||||
buffered surface and this second call hides that problem.
|
||||
*/
|
||||
drawCleanPlugin();
|
||||
drawCleanPlugin();
|
||||
break;
|
||||
case kSurfaceChanged_CustomEvent: {
|
||||
gLogI.log(kDebug_ANPLogType, " ---- customEvent: surfaceChanged");
|
||||
|
||||
int width = evt->data.other[1];
|
||||
int height = evt->data.other[2];
|
||||
|
||||
PluginObject *obj = (PluginObject*) inst()->pdata;
|
||||
const int pW = obj->window->width;
|
||||
const int pH = obj->window->height;
|
||||
// compare to the plugin's surface dimensions
|
||||
if (pW != width || pH != height)
|
||||
gLogI.log(kError_ANPLogType,
|
||||
"----%p Invalid Surface Dimensions (%d,%d):(%d,%d)",
|
||||
inst(), pW, pH, width, height);
|
||||
break;
|
||||
}
|
||||
case kSurfaceDestroyed_CustomEvent:
|
||||
gLogI.log(kDebug_ANPLogType, " ---- customEvent: surfaceDestroyed");
|
||||
break;
|
||||
}
|
||||
break; // end KCustom_ANPEventType
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0; // unknown or unhandled event
|
||||
}
|
||||
|
||||
ANPRectF* PaintPlugin::validTouch(int x, int y) {
|
||||
|
||||
//convert to float
|
||||
float fx = (int) x;
|
||||
float fy = (int) y;
|
||||
|
||||
if (fx > m_drawingSurface.left && fx < m_drawingSurface.right && fy > m_drawingSurface.top && fy < m_drawingSurface.bottom)
|
||||
return &m_drawingSurface;
|
||||
else if (fx > m_inputToggle.left && fx < m_inputToggle.right && fy > m_inputToggle.top && fy < m_inputToggle.bottom)
|
||||
return &m_inputToggle;
|
||||
else if (fx > m_colorToggle.left && fx < m_colorToggle.right && fy > m_colorToggle.top && fy < m_colorToggle.bottom)
|
||||
return &m_colorToggle;
|
||||
else if (fx > m_fullScreenToggle.left && fx < m_fullScreenToggle.right && fy > m_fullScreenToggle.top && fy < m_fullScreenToggle.bottom)
|
||||
return &m_fullScreenToggle;
|
||||
else if (fx > m_clearSurface.left && fx < m_clearSurface.right && fy > m_clearSurface.top && fy < m_clearSurface.bottom)
|
||||
return &m_clearSurface;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void PaintPlugin::toggleInputMethod() {
|
||||
m_isTouchCurrentInput = !m_isTouchCurrentInput;
|
||||
|
||||
// lock only the input toggle and redraw the canvas
|
||||
ANPCanvas* lockedCanvas = getCanvas(&m_inputToggle);
|
||||
drawCleanPlugin(lockedCanvas);
|
||||
}
|
||||
|
||||
void PaintPlugin::togglePaintColor() {
|
||||
if (m_activePaintColor == s_blueColor)
|
||||
m_activePaintColor = s_redColor;
|
||||
else if (m_activePaintColor == s_greenColor)
|
||||
m_activePaintColor = s_blueColor;
|
||||
else
|
||||
m_activePaintColor = s_greenColor;
|
||||
|
||||
// lock only the color toggle and redraw the canvas
|
||||
ANPCanvas* lockedCanvas = getCanvas(&m_colorToggle);
|
||||
drawCleanPlugin(lockedCanvas);
|
||||
}
|
||||
|
||||
void PaintPlugin::paintMouse(int x, int y) {
|
||||
//TODO do not paint outside the drawing surface
|
||||
|
||||
//create the paint color
|
||||
ANPPaint* fillPaint = gPaintI.newPaint();
|
||||
gPaintI.setFlags(fillPaint, gPaintI.getFlags(fillPaint) | kAntiAlias_ANPPaintFlag);
|
||||
gPaintI.setStyle(fillPaint, kFill_ANPPaintStyle);
|
||||
gPaintI.setColor(fillPaint, m_activePaintColor);
|
||||
|
||||
// handle the simple "mouse" paint (draw a point)
|
||||
ANPRectF point;
|
||||
point.left = (float) x-3;
|
||||
point.top = (float) y-3;
|
||||
point.right = (float) x+3;
|
||||
point.bottom = (float) y+3;
|
||||
|
||||
// get a canvas that is only locked around the point and draw it
|
||||
ANPCanvas* canvas = getCanvas(&point);
|
||||
gCanvasI.drawOval(canvas, &point, fillPaint);
|
||||
|
||||
// clean up
|
||||
releaseCanvas(canvas);
|
||||
gPaintI.deletePaint(fillPaint);
|
||||
}
|
||||
|
||||
void PaintPlugin::paintTouch() {
|
||||
//TODO do not paint outside the drawing surface
|
||||
|
||||
//create the paint color
|
||||
ANPPaint* strokePaint = gPaintI.newPaint();
|
||||
gPaintI.setFlags(strokePaint, gPaintI.getFlags(strokePaint) | kAntiAlias_ANPPaintFlag);
|
||||
gPaintI.setColor(strokePaint, m_activePaintColor);
|
||||
gPaintI.setStyle(strokePaint, kStroke_ANPPaintStyle);
|
||||
gPaintI.setStrokeWidth(strokePaint, 6.0);
|
||||
gPaintI.setStrokeCap(strokePaint, kRound_ANPPaintCap);
|
||||
gPaintI.setStrokeJoin(strokePaint, kRound_ANPPaintJoin);
|
||||
|
||||
// handle the complex "touch" paint (draw a line)
|
||||
ANPRectF bounds;
|
||||
gPathI.getBounds(m_touchPath, &bounds);
|
||||
|
||||
// get a canvas that is only locked around the point and draw the path
|
||||
ANPCanvas* canvas = getCanvas(&bounds);
|
||||
gCanvasI.drawPath(canvas, m_touchPath, strokePaint);
|
||||
|
||||
// clean up
|
||||
releaseCanvas(canvas);
|
||||
gPaintI.deletePaint(strokePaint);
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009, The Android Open Source Project
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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 "PluginObject.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef paintPlugin__DEFINED
|
||||
#define paintPlugin__DEFINED
|
||||
|
||||
class PaintPlugin : public SurfaceSubPlugin {
|
||||
public:
|
||||
PaintPlugin(NPP inst);
|
||||
virtual ~PaintPlugin();
|
||||
virtual int16 handleEvent(const ANPEvent* evt);
|
||||
virtual jobject getSurface();
|
||||
|
||||
private:
|
||||
void drawCleanPlugin(ANPCanvas* canvas = NULL);
|
||||
ANPCanvas* getCanvas(ANPRectI* dirtyRect = NULL);
|
||||
ANPCanvas* getCanvas(ANPRectF* dirtyRect);
|
||||
const char* getColorText();
|
||||
void destroySurface();
|
||||
void paintMouse(int x, int y);
|
||||
void paintTouch();
|
||||
void releaseCanvas(ANPCanvas*);
|
||||
void toggleInputMethod();
|
||||
void togglePaintColor();
|
||||
ANPRectF* validTouch(int x, int y);
|
||||
|
||||
bool m_isTouchActive;
|
||||
bool m_isTouchCurrentInput;
|
||||
|
||||
jobject m_surface;
|
||||
ANPPath* m_touchPath;
|
||||
|
||||
ANPRectF m_drawingSurface;
|
||||
ANPRectF m_inputToggle;
|
||||
ANPRectF m_colorToggle;
|
||||
ANPRectF m_fullScreenToggle;
|
||||
ANPRectF m_clearSurface;
|
||||
|
||||
ANPPaint* m_paintSurface;
|
||||
ANPPaint* m_paintButton;
|
||||
|
||||
ANPColor m_activePaintColor;
|
||||
static const ANPColor s_redColor = 0xFFFF0000;
|
||||
static const ANPColor s_greenColor = 0xFF00FF00;
|
||||
static const ANPColor s_blueColor = 0xFF0000FF;
|
||||
};
|
||||
|
||||
#endif // paintPlugin__DEFINED
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009, The Android Open Source Project
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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 "VideoPlugin.h"
|
||||
#include "android_npapi.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
extern NPNetscapeFuncs* browser;
|
||||
extern ANPBitmapInterfaceV0 gBitmapI;
|
||||
extern ANPCanvasInterfaceV0 gCanvasI;
|
||||
extern ANPLogInterfaceV0 gLogI;
|
||||
extern ANPPaintInterfaceV0 gPaintI;
|
||||
extern ANPSurfaceInterfaceV0 gSurfaceI;
|
||||
extern ANPSystemInterfaceV0 gSystemI;
|
||||
extern ANPTypefaceInterfaceV0 gTypefaceI;
|
||||
extern ANPWindowInterfaceV0 gWindowI;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
VideoPlugin::VideoPlugin(NPP inst) : SurfaceSubPlugin(inst) {
|
||||
|
||||
// initialize the drawing surface
|
||||
m_surface = NULL;
|
||||
|
||||
//register for touch events
|
||||
ANPEventFlags flags = kTouch_ANPEventFlag;
|
||||
NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
|
||||
if (err != NPERR_NO_ERROR) {
|
||||
gLogI.log(kError_ANPLogType, "Error selecting input events.");
|
||||
}
|
||||
}
|
||||
|
||||
VideoPlugin::~VideoPlugin() {
|
||||
setContext(NULL);
|
||||
destroySurface();
|
||||
}
|
||||
|
||||
jobject VideoPlugin::getSurface() {
|
||||
|
||||
if (m_surface) {
|
||||
return m_surface;
|
||||
}
|
||||
|
||||
// load the appropriate java class and instantiate it
|
||||
JNIEnv* env = NULL;
|
||||
if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
|
||||
gLogI.log(kError_ANPLogType, " ---- getSurface: failed to get env");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* className = "com.android.sampleplugin.VideoSurface";
|
||||
jclass videoClass = gSystemI.loadJavaClass(inst(), className);
|
||||
|
||||
if(!videoClass) {
|
||||
gLogI.log(kError_ANPLogType, " ---- getSurface: failed to load class");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jmethodID constructor = env->GetMethodID(videoClass, "<init>", "(Landroid/content/Context;)V");
|
||||
jobject videoSurface = env->NewObject(videoClass, constructor, m_context);
|
||||
|
||||
if(!videoSurface) {
|
||||
gLogI.log(kError_ANPLogType, " ---- getSurface: failed to construct object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m_surface = env->NewGlobalRef(videoSurface);
|
||||
return m_surface;
|
||||
}
|
||||
|
||||
void VideoPlugin::destroySurface() {
|
||||
JNIEnv* env = NULL;
|
||||
if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
|
||||
env->DeleteGlobalRef(m_surface);
|
||||
m_surface = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int16 VideoPlugin::handleEvent(const ANPEvent* evt) {
|
||||
switch (evt->eventType) {
|
||||
case kLifecycle_ANPEventType: {
|
||||
switch (evt->data.lifecycle.action) {
|
||||
case kEnterFullScreen_ANPLifecycleAction:
|
||||
gLogI.log(kDebug_ANPLogType, " ---- %p entering fullscreen", inst());
|
||||
break;
|
||||
case kExitFullScreen_ANPLifecycleAction:
|
||||
gLogI.log(kDebug_ANPLogType, " ---- %p exiting fullscreen", inst());
|
||||
break;
|
||||
}
|
||||
break; // end kLifecycle_ANPEventType
|
||||
}
|
||||
case kDraw_ANPEventType:
|
||||
gLogI.log(kError_ANPLogType, " ------ %p the plugin did not request draw events", inst());
|
||||
break;
|
||||
case kTouch_ANPEventType:
|
||||
if (kDown_ANPTouchAction == evt->data.touch.action) {
|
||||
gLogI.log(kDebug_ANPLogType, " ------ %p requesting fullscreen mode", inst());
|
||||
gWindowI.requestFullScreen(inst());
|
||||
}
|
||||
return 1;
|
||||
case kKey_ANPEventType:
|
||||
gLogI.log(kError_ANPLogType, " ------ %p the plugin did not request key events", inst());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0; // unknown or unhandled event
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009, The Android Open Source Project
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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 "PluginObject.h"
|
||||
|
||||
#ifndef videoPlugin__DEFINED
|
||||
#define videoPlugin__DEFINED
|
||||
|
||||
class VideoPlugin : public SurfaceSubPlugin {
|
||||
public:
|
||||
VideoPlugin(NPP inst);
|
||||
virtual ~VideoPlugin();
|
||||
virtual int16 handleEvent(const ANPEvent* evt);
|
||||
virtual jobject getSurface();
|
||||
|
||||
private:
|
||||
void destroySurface();
|
||||
|
||||
jobject m_surface;
|
||||
};
|
||||
|
||||
#endif // videoPlugin__DEFINED
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 5.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 3.5 KiB |
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="sample_browser_plugin">Sample Browser Plugin</string>
|
||||
</resources>
|
||||
@@ -1,19 +0,0 @@
|
||||
package com.android.sampleplugin;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class BackgroundSurface extends TextView {
|
||||
|
||||
public BackgroundSurface(Context context) {
|
||||
super(context);
|
||||
|
||||
this.setBackgroundColor(Color.BLACK);
|
||||
this.setTextColor(Color.WHITE);
|
||||
this.setText("This is a java background plugin");
|
||||
|
||||
// ensure that the view system is aware that we will be drawing
|
||||
this.setWillNotDraw(false);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.android.sampleplugin;
|
||||
|
||||
public class BackgroundTest {
|
||||
|
||||
public BackgroundTest() {}
|
||||
|
||||
public int addInt(int x, int y) {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009, The Android Open Source Project
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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 THE COPYRIGHT HOLDERS ``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 THE COPYRIGHT OWNER 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.
|
||||
*/
|
||||
package com.android.sampleplugin;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.SurfaceHolder.Callback;
|
||||
|
||||
public class PaintSurface extends SurfaceView {
|
||||
|
||||
static {
|
||||
//needed for jni calls
|
||||
System.loadLibrary("sampleplugin");
|
||||
}
|
||||
|
||||
private final int npp;
|
||||
|
||||
private boolean validNPP = true;
|
||||
private Object nppLock = new Object();
|
||||
|
||||
public PaintSurface(Context context, int NPP, int width, int height) {
|
||||
super(context);
|
||||
|
||||
this.npp = NPP;
|
||||
|
||||
this.getHolder().setFormat(PixelFormat.RGBA_8888);
|
||||
this.getHolder().addCallback(new Callback() {
|
||||
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||
synchronized (nppLock) {
|
||||
if (validNPP) {
|
||||
nativeSurfaceChanged(npp, format, width, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
synchronized (nppLock) {
|
||||
if (validNPP) {
|
||||
nativeSurfaceCreated(npp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
synchronized (nppLock) {
|
||||
if (validNPP) {
|
||||
nativeSurfaceDestroyed(npp);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// sets the plugin's surface to a fixed size
|
||||
this.getHolder().setFixedSize(width, height);
|
||||
|
||||
// ensure that the view system is aware that we will be drawing
|
||||
this.setWillNotDraw(false);
|
||||
}
|
||||
|
||||
// called by JNI
|
||||
private void invalidateNPP() {
|
||||
synchronized (nppLock) {
|
||||
validNPP = false;
|
||||
}
|
||||
}
|
||||
|
||||
private native void nativeSurfaceCreated(int npp);
|
||||
private native void nativeSurfaceChanged(int npp, int format, int width, int height);
|
||||
private native void nativeSurfaceDestroyed(int npp);
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009, The Android Open Source Project
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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 THE COPYRIGHT HOLDERS ``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 THE COPYRIGHT OWNER 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.
|
||||
*/
|
||||
package com.android.sampleplugin;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
|
||||
public class SamplePlugin extends Service {
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009, The Android Open Source Project
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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 THE COPYRIGHT HOLDERS ``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 THE COPYRIGHT OWNER 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.
|
||||
*/
|
||||
package com.android.sampleplugin;
|
||||
|
||||
import com.android.sampleplugin.graphics.CubeRenderer;
|
||||
|
||||
import android.content.Context;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.MediaController;
|
||||
import android.widget.VideoView;
|
||||
|
||||
public class VideoSurface extends FrameLayout {
|
||||
|
||||
public VideoSurface(Context context) {
|
||||
super(context);
|
||||
|
||||
LayoutParams fp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
|
||||
this.setLayoutParams(fp);
|
||||
|
||||
// VideoView video = new VideoView(context);
|
||||
// LayoutParams vp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
|
||||
// vp.setLayoutParams(vp);
|
||||
|
||||
GLSurfaceView gl = new GLSurfaceView(context);
|
||||
LayoutParams gp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
|
||||
gl.setLayoutParams(gp);
|
||||
|
||||
this.addView(gl);
|
||||
// this.addView(video);
|
||||
|
||||
// Tell the cube renderer that we want to render a translucent version
|
||||
// of the cube:
|
||||
gl.setRenderer(new CubeRenderer(false));
|
||||
gl.setWindowType(WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY);
|
||||
|
||||
// video.setVideoPath("/sdcard/test_video.3gp");
|
||||
// video.setMediaController(new MediaController(context));
|
||||
// video.requestFocus();
|
||||
|
||||
// ensure that the view system is aware that we will be drawing
|
||||
this.setWillNotDraw(false);
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.sampleplugin.graphics;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
/**
|
||||
* A vertex shaded cube.
|
||||
*/
|
||||
class Cube
|
||||
{
|
||||
public Cube()
|
||||
{
|
||||
int one = 0x10000;
|
||||
int vertices[] = {
|
||||
-one, -one, -one,
|
||||
one, -one, -one,
|
||||
one, one, -one,
|
||||
-one, one, -one,
|
||||
-one, -one, one,
|
||||
one, -one, one,
|
||||
one, one, one,
|
||||
-one, one, one,
|
||||
};
|
||||
|
||||
int colors[] = {
|
||||
0, 0, 0, one,
|
||||
one, 0, 0, one,
|
||||
one, one, 0, one,
|
||||
0, one, 0, one,
|
||||
0, 0, one, one,
|
||||
one, 0, one, one,
|
||||
one, one, one, one,
|
||||
0, one, one, one,
|
||||
};
|
||||
|
||||
byte indices[] = {
|
||||
0, 4, 5, 0, 5, 1,
|
||||
1, 5, 6, 1, 6, 2,
|
||||
2, 6, 7, 2, 7, 3,
|
||||
3, 7, 4, 3, 4, 0,
|
||||
4, 7, 6, 4, 6, 5,
|
||||
3, 0, 1, 3, 1, 2
|
||||
};
|
||||
|
||||
// Buffers to be passed to gl*Pointer() functions
|
||||
// must be direct, i.e., they must be placed on the
|
||||
// native heap where the garbage collector cannot
|
||||
// move them.
|
||||
//
|
||||
// Buffers with multi-byte datatypes (e.g., short, int, float)
|
||||
// must have their byte order set to native order
|
||||
|
||||
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
|
||||
vbb.order(ByteOrder.nativeOrder());
|
||||
mVertexBuffer = vbb.asIntBuffer();
|
||||
mVertexBuffer.put(vertices);
|
||||
mVertexBuffer.position(0);
|
||||
|
||||
ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);
|
||||
cbb.order(ByteOrder.nativeOrder());
|
||||
mColorBuffer = cbb.asIntBuffer();
|
||||
mColorBuffer.put(colors);
|
||||
mColorBuffer.position(0);
|
||||
|
||||
mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
|
||||
mIndexBuffer.put(indices);
|
||||
mIndexBuffer.position(0);
|
||||
}
|
||||
|
||||
public void draw(GL10 gl)
|
||||
{
|
||||
gl.glFrontFace(gl.GL_CW);
|
||||
gl.glVertexPointer(3, gl.GL_FIXED, 0, mVertexBuffer);
|
||||
gl.glColorPointer(4, gl.GL_FIXED, 0, mColorBuffer);
|
||||
gl.glDrawElements(gl.GL_TRIANGLES, 36, gl.GL_UNSIGNED_BYTE, mIndexBuffer);
|
||||
}
|
||||
|
||||
private IntBuffer mVertexBuffer;
|
||||
private IntBuffer mColorBuffer;
|
||||
private ByteBuffer mIndexBuffer;
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.sampleplugin.graphics;
|
||||
|
||||
import javax.microedition.khronos.egl.EGL10;
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
import android.opengl.GLSurfaceView;
|
||||
|
||||
/**
|
||||
* Render a pair of tumbling cubes.
|
||||
*/
|
||||
|
||||
public class CubeRenderer implements GLSurfaceView.Renderer {
|
||||
public CubeRenderer(boolean useTranslucentBackground) {
|
||||
mTranslucentBackground = useTranslucentBackground;
|
||||
mCube = new Cube();
|
||||
}
|
||||
|
||||
public void onDrawFrame(GL10 gl) {
|
||||
/*
|
||||
* Usually, the first thing one might want to do is to clear
|
||||
* the screen. The most efficient way of doing this is to use
|
||||
* glClear().
|
||||
*/
|
||||
|
||||
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
/*
|
||||
* Now we're ready to draw some 3D objects
|
||||
*/
|
||||
|
||||
gl.glMatrixMode(GL10.GL_MODELVIEW);
|
||||
gl.glLoadIdentity();
|
||||
gl.glTranslatef(0, 0, -3.0f);
|
||||
gl.glRotatef(mAngle, 0, 1, 0);
|
||||
gl.glRotatef(mAngle*0.25f, 1, 0, 0);
|
||||
|
||||
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
|
||||
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
|
||||
|
||||
mCube.draw(gl);
|
||||
|
||||
gl.glRotatef(mAngle*2.0f, 0, 1, 1);
|
||||
gl.glTranslatef(0.5f, 0.5f, 0.5f);
|
||||
|
||||
mCube.draw(gl);
|
||||
|
||||
mAngle += 1.2f;
|
||||
}
|
||||
|
||||
public void onSurfaceChanged(GL10 gl, int width, int height) {
|
||||
gl.glViewport(0, 0, width, height);
|
||||
|
||||
/*
|
||||
* Set our projection matrix. This doesn't have to be done
|
||||
* each time we draw, but usually a new projection needs to
|
||||
* be set when the viewport is resized.
|
||||
*/
|
||||
|
||||
float ratio = (float) width / height;
|
||||
gl.glMatrixMode(GL10.GL_PROJECTION);
|
||||
gl.glLoadIdentity();
|
||||
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
|
||||
}
|
||||
|
||||
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
||||
/*
|
||||
* By default, OpenGL enables features that improve quality
|
||||
* but reduce performance. One might want to tweak that
|
||||
* especially on software renderer.
|
||||
*/
|
||||
gl.glDisable(GL10.GL_DITHER);
|
||||
|
||||
/*
|
||||
* Some one-time OpenGL initialization can be made here
|
||||
* probably based on features of this particular context
|
||||
*/
|
||||
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
|
||||
GL10.GL_FASTEST);
|
||||
|
||||
if (mTranslucentBackground) {
|
||||
gl.glClearColor(0,0,0,0);
|
||||
} else {
|
||||
gl.glClearColor(1,1,1,1);
|
||||
}
|
||||
gl.glEnable(GL10.GL_CULL_FACE);
|
||||
gl.glShadeModel(GL10.GL_SMOOTH);
|
||||
gl.glEnable(GL10.GL_DEPTH_TEST);
|
||||
}
|
||||
private boolean mTranslucentBackground;
|
||||
private Cube mCube;
|
||||
private float mAngle;
|
||||
}
|
||||
Reference in New Issue
Block a user