Merge last green changeset on mozilla-inbound to mozilla-central

This commit is contained in:
Ed Morley 2011-09-18 20:23:17 +01:00
Родитель 4139d2e44d 8d8b113f0b
Коммит 729d791e2f
50 изменённых файлов: 4849 добавлений и 34 удалений

Просмотреть файл

@ -99,6 +99,11 @@ CPPSRCS = \
nsPluginInstanceOwner.cpp \
$(NULL)
ifeq ($(MOZ_WIDGET_TOOLKIT),android)
DIRS += android
LOCAL_INCLUDES += -I$(topsrcdir)/dom/plugins/base/android
endif
ifeq ($(OS_ARCH),WINNT)
CPPSRCS += nsPluginsDirWin.cpp
CPPSRCS += nsPluginNativeWindowWin.cpp
@ -127,7 +132,7 @@ endif
endif
endif
LOCAL_INCLUDES = \
LOCAL_INCLUDES += \
-I$(topsrcdir)/xpcom/base/ \
$(MOZ_CAIRO_CFLAGS) \
$(NULL)

Просмотреть файл

@ -37,7 +37,6 @@
* ***** END LICENSE BLOCK ***** */
#include "mozilla/PluginPRLibrary.h"
// Some plugins on Windows, notably Quake Live, implement NP_Initialize using
// cdecl instead of the documented stdcall. In order to work around this,
// we force the caller to use a frame pointer.
@ -52,9 +51,38 @@ static int gNotOptimized;
#define CALLING_CONVENTION_HACK
#endif
namespace mozilla {
#ifdef ANDROID
#include "AndroidBridge.h"
#include "android_npapi.h"
#include <android/log.h>
#define ALOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoJavaEnv", ## args)
#endif
#if defined(XP_UNIX) && !defined(XP_MACOSX)
namespace mozilla {
#ifdef ANDROID
nsresult
PluginPRLibrary::NP_Initialize(NPNetscapeFuncs* bFuncs,
NPPluginFuncs* pFuncs, NPError* error)
{
if (mNP_Initialize) {
*error = mNP_Initialize(bFuncs, pFuncs, GetJNIForThread());
} else {
NP_InitializeFunc pfNP_Initialize = (NP_InitializeFunc)
PR_FindFunctionSymbol(mLibrary, "NP_Initialize");
if (!pfNP_Initialize)
return NS_ERROR_FAILURE;
*error = pfNP_Initialize(bFuncs, pFuncs, GetJNIForThread());
}
// Save pointers to functions that get called through PluginLibrary itself.
mNPP_New = pFuncs->newp;
mNPP_GetValue = pFuncs->getvalue;
mNPP_ClearSiteData = pFuncs->clearsitedata;
mNPP_GetSitesWithData = pFuncs->getsiteswithdata;
return NS_OK;
}
#elif defined(XP_UNIX) && !defined(XP_MACOSX)
nsresult
PluginPRLibrary::NP_Initialize(NPNetscapeFuncs* bFuncs,
NPPluginFuncs* pFuncs, NPError* error)

Просмотреть файл

@ -63,9 +63,11 @@ public:
mNP_GetEntryPoints(nsnull),
#endif
mNPP_New(nsnull),
mNPP_GetValue(nsnull),
mNPP_ClearSiteData(nsnull),
mNPP_GetSitesWithData(nsnull),
mLibrary(aLibrary)
mLibrary(aLibrary),
mFilePath(aFilePath)
{
NS_ASSERTION(mLibrary, "need non-null lib");
// addref here??
@ -159,6 +161,8 @@ public:
const nsGUIEvent& anEvent, bool* handled);
#endif
virtual void GetLibraryPath(nsACString& aPath) { aPath.Assign(mFilePath); }
private:
NP_InitializeFunc mNP_Initialize;
NP_ShutdownFunc mNP_Shutdown;
@ -170,9 +174,11 @@ private:
NP_GetEntryPointsFunc mNP_GetEntryPoints;
#endif
NPP_NewProcPtr mNPP_New;
NPP_GetValueProcPtr mNPP_GetValue;
NPP_ClearSiteDataPtr mNPP_ClearSiteData;
NPP_GetSitesWithDataPtr mNPP_GetSitesWithData;
PRLibrary* mLibrary;
nsCString mFilePath;
};

Просмотреть файл

@ -0,0 +1,361 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android NPAPI support code
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Doug Turner <dougt@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "base/basictypes.h"
#include "AndroidBridge.h"
#include <android/log.h>
#include <stdlib.h>
#include <time.h>
#include "assert.h"
#include "ANPBase.h"
#include "nsIThread.h"
#include "nsThreadUtils.h"
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPluginsAudio" , ## args)
#define ASSIGN(obj, name) (obj)->name = anp_audio_##name
/* android.media.AudioTrack */
struct AudioTrack {
jclass at_class;
jmethodID constructor;
jmethodID flush;
jmethodID pause;
jmethodID play;
jmethodID setvol;
jmethodID stop;
jmethodID write;
jmethodID getpos;
};
enum AudioTrackMode {
MODE_STATIC = 0,
MODE_STREAM = 1
};
/* android.media.AudioManager */
enum AudioManagerStream {
STREAM_VOICE_CALL = 0,
STREAM_SYSTEM = 1,
STREAM_RING = 2,
STREAM_MUSIC = 3,
STREAM_ALARM = 4,
STREAM_NOTIFICATION = 5,
STREAM_DTMF = 8
};
/* android.media.AudioFormat */
enum AudioFormatChannel {
CHANNEL_OUT_MONO = 4,
CHANNEL_OUT_STEREO = 12
};
enum AudioFormatEncoding {
ENCODING_PCM_16BIT = 2,
ENCODING_PCM_8BIT = 3
};
static struct AudioTrack at;
static jclass
init_jni_bindings(JNIEnv *jenv) {
jclass jc = jenv->FindClass("android/media/AudioTrack");
at.constructor = jenv->GetMethodID(jc, "<init>", "(IIIIII)V");
at.flush = jenv->GetMethodID(jc, "flush", "()V");
at.pause = jenv->GetMethodID(jc, "pause", "()V");
at.play = jenv->GetMethodID(jc, "play", "()V");
at.setvol = jenv->GetMethodID(jc, "setStereoVolume", "(FF)I");
at.stop = jenv->GetMethodID(jc, "stop", "()V");
at.write = jenv->GetMethodID(jc, "write", "([BII)I");
at.getpos = jenv->GetMethodID(jc, "getPlaybackHeadPosition", "()I");
return jc;
}
struct ANPAudioTrack {
jobject output_unit;
jclass at_class;
unsigned int rate;
unsigned int channels;
unsigned int bufferSize;
unsigned int isStopped;
unsigned int keepGoing;
void* user;
ANPAudioCallbackProc proc;
ANPSampleFormat format;
};
class AudioRunnable : public nsRunnable
{
public:
NS_DECL_NSIRUNNABLE
AudioRunnable(ANPAudioTrack* aAudioTrack) {
mTrack = aAudioTrack;
}
ANPAudioTrack* mTrack;
};
NS_IMETHODIMP
AudioRunnable::Run()
{
JNIEnv* jenv = GetJNIForThread();
if (jenv->PushLocalFrame(128)) {
return NS_ERROR_FAILURE;
}
jbyteArray bytearray = jenv->NewByteArray(mTrack->bufferSize);
if (!bytearray) {
LOG("AudioRunnable:: Run. Could not create bytearray");
return NS_ERROR_FAILURE;
}
jbyte *byte = jenv->GetByteArrayElements(bytearray, NULL);
if (!byte) {
LOG("AudioRunnable:: Run. Could not create bytearray");
return NS_ERROR_FAILURE;
}
ANPAudioBuffer buffer;
buffer.channelCount = mTrack->channels;
buffer.format = mTrack->format;
buffer.bufferData = (void*) byte;
while (mTrack->keepGoing)
{
// reset the buffer size
buffer.size = mTrack->bufferSize;
// Get data from the plugin
mTrack->proc(kMoreData_ANPAudioEvent, mTrack->user, &buffer);
if (buffer.size == 0) {
LOG("%p - kMoreData_ANPAudioEvent", mTrack);
continue;
}
size_t wroteSoFar = 0;
jint retval;
do {
retval = jenv->CallIntMethod(mTrack->output_unit,
at.write,
bytearray,
wroteSoFar,
buffer.size - wroteSoFar);
if (retval < 0) {
LOG("%p - Write failed %d", mTrack, retval);
break;
}
wroteSoFar += retval;
} while(wroteSoFar < buffer.size);
}
jenv->DeleteGlobalRef(mTrack->output_unit);
jenv->DeleteGlobalRef(mTrack->at_class);
free(mTrack);
jenv->ReleaseByteArrayElements(bytearray, byte, 0);
jenv->PopLocalFrame(NULL);
return NS_OK;
}
ANPAudioTrack*
anp_audio_newTrack(uint32_t sampleRate, // sampling rate in Hz
ANPSampleFormat format,
int channelCount, // MONO=1, STEREO=2
ANPAudioCallbackProc proc,
void* user)
{
ANPAudioTrack *s = (ANPAudioTrack*) malloc(sizeof(ANPAudioTrack));
if (s == NULL) {
return NULL;
}
JNIEnv *jenv = GetJNIForThread();
if (!jenv)
return NULL;
s->at_class = init_jni_bindings(jenv);
s->rate = sampleRate;
s->channels = channelCount;
s->bufferSize = s->rate * s->channels;
s->isStopped = true;
s->keepGoing = false;
s->user = user;
s->proc = proc;
s->format = format;
int jformat;
switch (format) {
case kPCM16Bit_ANPSampleFormat:
jformat = ENCODING_PCM_16BIT;
break;
case kPCM8Bit_ANPSampleFormat:
jformat = ENCODING_PCM_8BIT;
break;
default:
LOG("Unknown audio format. defaulting to 16bit.");
jformat = ENCODING_PCM_16BIT;
break;
}
int jChannels;
switch (channelCount) {
case 1:
jChannels = CHANNEL_OUT_MONO;
break;
case 2:
jChannels = CHANNEL_OUT_STEREO;
break;
default:
LOG("Unknown channel count. defaulting to mono.");
jChannels = CHANNEL_OUT_MONO;
break;
}
jobject obj = jenv->NewObject(s->at_class,
at.constructor,
STREAM_MUSIC,
s->rate,
jChannels,
jformat,
s->bufferSize,
MODE_STREAM);
jthrowable exception = jenv->ExceptionOccurred();
if (exception) {
LOG("%s fAILED ", __PRETTY_FUNCTION__);
jenv->ExceptionDescribe();
jenv->ExceptionClear();
jenv->DeleteGlobalRef(s->at_class);
free(s);
return NULL;
}
s->output_unit = jenv->NewGlobalRef(obj);
return s;
}
void
anp_audio_deleteTrack(ANPAudioTrack* s)
{
if (s == NULL) {
return;
}
s->keepGoing = false;
// deallocation happens in the AudioThread. There is a
// potential leak if anp_audio_start is never called, but
// we do not see that from flash.
}
void
anp_audio_start(ANPAudioTrack* s)
{
if (s == NULL || s->output_unit == NULL) {
return;
}
if (s->keepGoing) {
// we are already playing. Ignore.
LOG("anp_audio_start called twice!");
return;
}
JNIEnv *jenv = GetJNIForThread();
jenv->CallVoidMethod(s->output_unit, at.play);
s->isStopped = false;
s->keepGoing = true;
// AudioRunnable now owns the ANPAudioTrack
nsRefPtr<AudioRunnable> runnable = new AudioRunnable(s);
nsCOMPtr<nsIThread> thread;
NS_NewThread(getter_AddRefs(thread), runnable);
}
void
anp_audio_pause(ANPAudioTrack* s)
{
if (s == NULL || s->output_unit == NULL) {
return;
}
JNIEnv *jenv = GetJNIForThread();
jenv->CallVoidMethod(s->output_unit, at.pause);
}
void
anp_audio_stop(ANPAudioTrack* s)
{
if (s == NULL || s->output_unit == NULL) {
return;
}
s->isStopped = true;
JNIEnv *jenv = GetJNIForThread();
jenv->CallVoidMethod(s->output_unit, at.stop);
}
bool
anp_audio_isStopped(ANPAudioTrack* s)
{
return s->isStopped;
}
void InitAudioTrackInterface(ANPAudioTrackInterfaceV0 *i) {
_assert(i->inSize == sizeof(*i));
ASSIGN(i, newTrack);
ASSIGN(i, deleteTrack);
ASSIGN(i, start);
ASSIGN(i, pause);
ASSIGN(i, stop);
ASSIGN(i, isStopped);
}

Просмотреть файл

@ -0,0 +1,90 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android NPAPI support code
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Doug Turner <dougt@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "android_npapi.h"
#include <stdlib.h>
#include "nsAutoPtr.h"
#include "gfxFont.h"
#define NOT_IMPLEMENTED_FATAL() do { \
__android_log_print(ANDROID_LOG_ERROR, "GeckoPlugins", \
"%s not implemented %s, %d", \
__PRETTY_FUNCTION__, __FILE__, __LINE__); \
abort(); \
} while(0)
#define NOT_IMPLEMENTED() \
__android_log_print(ANDROID_LOG_ERROR, "GeckoPlugins", \
"!!!!!!!!!!!!!! %s not implemented %s, %d", \
__PRETTY_FUNCTION__, __FILE__, __LINE__); \
class gfxFont;
void InitAudioTrackInterface(ANPAudioTrackInterfaceV0 *i);
void InitBitmapInterface(ANPBitmapInterfaceV0 *i);
void InitCanvasInterface(ANPCanvasInterfaceV0 *i);
void InitEventInterface(ANPEventInterfaceV0 *i);
void InitLogInterface(ANPLogInterfaceV0 *i);
void InitMatrixInterface(ANPMatrixInterfaceV0 *i);
void InitPaintInterface(ANPPaintInterfaceV0 *i);
void InitPathInterface(ANPPathInterfaceV0 *i);
void InitSurfaceInterface(ANPSurfaceInterfaceV0 *i);
void InitSystemInterface(ANPSystemInterfaceV0 *i);
void InitTypeFaceInterface(ANPTypefaceInterfaceV0 *i);
void InitWindowInterface(ANPWindowInterfaceV0 *i);
struct ANPTypeface {
nsRefPtr<gfxFont> mFont;
};
typedef struct {
ANPMatrixFlag flags;
ANPColor color;
ANPPaintStyle style;
float strokeWidth;
float strokeMiter;
ANPPaintCap paintCap;
ANPPaintJoin paintJoin;
ANPTextEncoding textEncoding;
ANPPaintAlign paintAlign;
float textSize;
float textScaleX;
float textSkewX;
ANPTypeface typeface;
} ANPPaintPrivate;

Просмотреть файл

@ -0,0 +1,118 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android NPAPI support code
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Doug Turner <dougt@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "assert.h"
#include "ANPBase.h"
#include <android/log.h>
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
#define ASSIGN(obj, name) (obj)->name = anp_bitmap_##name
#define SK_A32_BITS 8
#define SK_R32_BITS 8
#define SK_G32_BITS 8
#define SK_B32_BITS 8
#ifdef IS_BIG_ENDIAN
#define SK_R32_SHIFT 24
#define SK_G32_SHIFT 16
#define SK_B32_SHIFT 8
#define SK_A32_SHIFT 0
#else
#define SK_R32_SHIFT 0
#define SK_G32_SHIFT 8
#define SK_B32_SHIFT 16
#define SK_A32_SHIFT 24
#endif
#define SK_A32_MASK ((1 << SK_A32_BITS) - 1)
#define SK_R32_MASK ((1 << SK_R32_BITS) - 1)
#define SK_G32_MASK ((1 << SK_G32_BITS) - 1)
#define SK_B32_MASK ((1 << SK_B32_BITS) - 1)
#define SK_R16_BITS 5
#define SK_G16_BITS 6
#define SK_B16_BITS 5
#define SK_R16_SHIFT (SK_B16_BITS + SK_G16_BITS)
#define SK_G16_SHIFT (SK_B16_BITS)
#define SK_B16_SHIFT 0
#define SK_R16_MASK ((1 << SK_R16_BITS) - 1)
#define SK_G16_MASK ((1 << SK_G16_BITS) - 1)
#define SK_B16_MASK ((1 << SK_B16_BITS) - 1)
bool
anp_bitmap_getPixelPacking(ANPBitmapFormat fmt, ANPPixelPacking* packing) {
LOG("%s", __PRETTY_FUNCTION__);
switch (fmt) {
case kRGBA_8888_ANPBitmapFormat:
if (packing) {
packing->AShift = SK_A32_SHIFT;
packing->ABits = SK_A32_BITS;
packing->RShift = SK_R32_SHIFT;
packing->RBits = SK_R32_BITS;
packing->GShift = SK_G32_SHIFT;
packing->GBits = SK_G32_BITS;
packing->BShift = SK_B32_SHIFT;
packing->BBits = SK_B32_BITS;
}
return true;
case kRGB_565_ANPBitmapFormat:
if (packing) {
packing->AShift = 0;
packing->ABits = 0;
packing->RShift = SK_R16_SHIFT;
packing->RBits = SK_R16_BITS;
packing->GShift = SK_G16_SHIFT;
packing->GBits = SK_G16_BITS;
packing->BShift = SK_B16_SHIFT;
packing->BBits = SK_B16_BITS;
}
return true;
default:
break;
}
return false;
}
void InitBitmapInterface(ANPBitmapInterfaceV0 *i) {
_assert(i->inSize == sizeof(*i));
ASSIGN(i, getPixelPacking);
}

Просмотреть файл

@ -0,0 +1,373 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android NPAPI support code
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Doug Turner <dougt@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "assert.h"
#include "ANPBase.h"
#include <android/log.h>
#include "cairo.h"
#include "gfxPlatform.h"
#include "gfxASurface.h"
#include "gfxImageSurface.h"
#include "gfxUtils.h"
#include "gfxContext.h"
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
#define ASSIGN(obj, name) (obj)->name = anp_canvas_##name
ANPCanvas*
anp_canvas_newCanvas(const ANPBitmap* bitmap)
{
PRUint32 stride;
gfxASurface::gfxImageFormat format;
if (bitmap->format == ANPBitmapFormats::kRGBA_8888_ANPBitmapFormat) {
stride = bitmap->width * 4;
format = gfxImageSurface::ImageFormatARGB32;
}
else if (bitmap->format == ANPBitmapFormats::kRGB_565_ANPBitmapFormat) {
stride = bitmap->width * 2;
format = gfxImageSurface::ImageFormatRGB16_565;
}
else {
LOG("%s -- Unknown format", __PRETTY_FUNCTION__);
return nsnull;
}
gfxImageSurface* pluginSurface = new gfxImageSurface(static_cast<unsigned char*>(bitmap->baseAddr),
gfxIntSize(bitmap->width, bitmap->height),
stride,
format);
if (pluginSurface->CairoStatus()) {
LOG("%s -- %d x %d FAILED to create gfxImageSurface", __PRETTY_FUNCTION__, bitmap->width, bitmap->height);
return nsnull;
}
gfxContext *pluginContext = new gfxContext(pluginSurface);
NS_ADDREF(pluginContext);
return (ANPCanvas*) pluginContext;
}
void
anp_canvas_deleteCanvas(ANPCanvas* canvas)
{
if (!canvas)
return;
gfxContext *ctx = (gfxContext*)canvas;
NS_RELEASE( ctx );
}
void
anp_canvas_save(ANPCanvas* canvas)
{
if (!canvas)
return;
gfxContext* ctx = (gfxContext*)canvas;
ctx->Save();
}
void
anp_canvas_restore(ANPCanvas* canvas)
{
if (!canvas)
return;
gfxContext* ctx = (gfxContext*)canvas;
ctx->Restore();
}
void
anp_canvas_translate(ANPCanvas* canvas, float tx, float ty)
{
if (!canvas)
return;
gfxContext* ctx = (gfxContext*)canvas;
ctx->Translate(gfxPoint(tx,ty));
}
void
anp_canvas_scale(ANPCanvas* canvas, float sx, float sy)
{
if (!canvas)
return;
gfxContext* ctx = (gfxContext*)canvas;
ctx->Scale(sx, sy);
}
void
anp_canvas_rotate(ANPCanvas* canvas, float degrees)
{
if (!canvas)
return;
gfxContext* ctx = (gfxContext*)canvas;
ctx->Rotate(degrees);
}
void
anp_canvas_skew(ANPCanvas* canvas, float kx, float ky)
{
if (!canvas)
return;
gfxContext* ctx = (gfxContext*)canvas;
LOG("%s is not impl.", __PRETTY_FUNCTION__);
}
void
anp_canvas_concat(ANPCanvas* canvas, const ANPMatrix*)
{
if (!canvas)
return;
gfxContext* ctx = (gfxContext*)canvas;
LOG("%s is not impl.", __PRETTY_FUNCTION__);
}
void
anp_canvas_clipRect(ANPCanvas* canvas, const ANPRectF* r)
{
if (!canvas)
return;
gfxContext* ctx = (gfxContext*)canvas;
ctx->Clip(gfxRect(r->left,
r->top,
r->right - r->left,
r->bottom - r->top));
}
void
anp_canvas_clipPath(ANPCanvas* canvas, const ANPPath*)
{
if (!canvas)
return;
gfxContext* ctx = (gfxContext*)canvas;
LOG("%s is not impl.", __PRETTY_FUNCTION__);
}
void
anp_canvas_getTotalMatrix(ANPCanvas* canvas, ANPMatrix*)
{
if (!canvas)
return;
gfxContext* ctx = (gfxContext*)canvas;
LOG("%s is not impl.", __PRETTY_FUNCTION__);
}
bool
anp_canvas_getLocalClipBounds(ANPCanvas* canvas, ANPRectF* bounds, bool aa)
{
if (!canvas)
return false;
gfxContext* ctx = (gfxContext*)canvas;
LOG("%s is not impl.", __PRETTY_FUNCTION__);
return false;
}
bool
anp_canvas_getDeviceClipBounds(ANPCanvas* canvas, ANPRectI* bounds)
{
if (!canvas)
return false;
gfxContext* ctx = (gfxContext*)canvas;
LOG("%s is not impl.", __PRETTY_FUNCTION__);
return false;
}
void
anp_canvas_drawColor(ANPCanvas* canvas, ANPColor c)
{
if (!canvas)
return;
gfxContext* ctx = (gfxContext*)canvas;
ctx->SetDeviceColor(gfxRGBA(c, gfxRGBA::PACKED_ARGB));
LOG("returning from %s", __PRETTY_FUNCTION__);
}
void
anp_canvas_drawPaint(ANPCanvas* canvas, const ANPPaint* paint)
{
if (!canvas)
return;
gfxContext* ctx = (gfxContext*)canvas;
LOG("%s", " ************** NOT IMPLEMENTED!!!");
}
void
anp_canvas_drawLine(ANPCanvas* canvas, float x0, float y0, float x1, float y1,
const ANPPaint* paint)
{
if (!canvas)
return;
gfxContext* ctx = (gfxContext*)canvas;
ctx->NewPath();
ctx->SetColor(((ANPPaintPrivate*)paint)->color);
ctx->Line(gfxPoint(x0, y0), gfxPoint(x1, y1));
ctx->Fill();
}
void
anp_canvas_drawRect(ANPCanvas* canvas, const ANPRectF* r, const ANPPaint* paint)
{
if (!canvas)
return;
gfxContext* ctx = (gfxContext*)canvas;
ctx->NewPath();
ctx->SetColor(((ANPPaintPrivate*)paint)->color);
ctx->Rectangle(gfxRect(r->left,
r->top,
r->right - r->left,
r->bottom - r->top));
ctx->Fill();
}
void
anp_canvas_drawOval(ANPCanvas* canvas, const ANPRectF* r, const ANPPaint* paint)
{
if (!canvas)
return;
gfxContext* ctx = (gfxContext*)canvas;
ctx->NewPath();
ctx->SetColor(((ANPPaintPrivate*)paint)->color);
float sizeX = (r->right - r->left);
float sizeY = (r->bottom - r->top);
ctx->Ellipse(gfxPoint(r->left + ( sizeX / 2), r->top + ( sizeY / 2)),
gfxSize(sizeX, sizeY));
ctx->Fill();
}
void
anp_canvas_drawPath(ANPCanvas* canvas, const ANPPath*, const ANPPaint* paint)
{
if (!canvas)
return;
gfxContext* ctx = (gfxContext*)canvas;
LOG("%s is not impl.", __PRETTY_FUNCTION__);
}
void
anp_canvas_drawText(ANPCanvas* canvas, const void* text, uint32_t byteLength,
float x, float y, const ANPPaint* paint)
{
if (!canvas)
return;
gfxContext* ctx = (gfxContext*)canvas;
LOG("%s is not impl.", __PRETTY_FUNCTION__);
}
void
anp_canvas_drawPosText(ANPCanvas* canvas, const void* text, uint32_t byteLength,
const float xy[], const ANPPaint* paint)
{
if (!canvas)
return;
gfxContext* ctx = (gfxContext*)canvas;
LOG("%s is not impl.", __PRETTY_FUNCTION__);
}
void
anp_canvas_drawBitmap(ANPCanvas* canvas, const ANPBitmap*, float x, float y,
const ANPPaint* paint)
{
if (!canvas)
return;
gfxContext* ctx = (gfxContext*)canvas;
LOG("%s is not impl.", __PRETTY_FUNCTION__);
}
void
anp_canvas_drawBitmapRect(ANPCanvas* canvas, const ANPBitmap*,
const ANPRectI* src, const ANPRectF* dst,
const ANPPaint* paint)
{
if (!canvas)
return;
gfxContext* ctx = (gfxContext*)canvas;
LOG("%s is not impl.", __PRETTY_FUNCTION__);
}
void InitCanvasInterface(ANPCanvasInterfaceV0 *i) {
_assert(i->inSize == sizeof(*i));
ASSIGN(i, newCanvas);
ASSIGN(i, deleteCanvas);
ASSIGN(i, save);
ASSIGN(i, restore);
ASSIGN(i, translate);
ASSIGN(i, scale);
ASSIGN(i, rotate);
ASSIGN(i, skew);
ASSIGN(i, concat);
ASSIGN(i, clipRect);
ASSIGN(i, clipPath);
ASSIGN(i, getTotalMatrix);
ASSIGN(i, getLocalClipBounds);
ASSIGN(i, getDeviceClipBounds);
ASSIGN(i, drawColor);
ASSIGN(i, drawPaint);
ASSIGN(i, drawLine);
ASSIGN(i, drawRect);
ASSIGN(i, drawOval);
ASSIGN(i, drawPath);
ASSIGN(i, drawText);
ASSIGN(i, drawPosText);
ASSIGN(i, drawBitmap);
ASSIGN(i, drawBitmapRect);
}

Просмотреть файл

@ -0,0 +1,84 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android NPAPI support code
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Doug Turner <dougt@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "assert.h"
#include "ANPBase.h"
#include <android/log.h>
#include "nsThreadUtils.h"
#include "nsNPAPIPluginInstance.h"
#include "AndroidBridge.h"
#include "nsNPAPIPlugin.h"
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
#define ASSIGN(obj, name) (obj)->name = anp_event_##name
class PluginEventRunnable : public nsRunnable
{
public:
PluginEventRunnable(NPP inst, ANPEvent* event, NPPluginFuncs* aFuncs)
: mInstance(inst), mEvent(*event), mFuncs(aFuncs) {}
virtual nsresult Run() {
(*mFuncs->event)(mInstance, &mEvent);
return NS_OK;
}
private:
NPP mInstance;
ANPEvent mEvent;
NPPluginFuncs* mFuncs;
};
void
anp_event_postEvent(NPP inst, const ANPEvent* event)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!mozilla::AndroidBridge::Bridge()) {
LOG("no bridge in %s!!!!", __PRETTY_FUNCTION__);
return;
}
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(inst->ndata);
NPPluginFuncs* pluginFunctions = pinst->GetPlugin()->PluginFuncs();
mozilla::AndroidBridge::Bridge()->PostToJavaThread(
new PluginEventRunnable(inst, const_cast<ANPEvent*>(event), pluginFunctions), PR_TRUE);
LOG("returning from %s", __PRETTY_FUNCTION__);
}
void InitEventInterface(ANPEventInterfaceV0 *i) {
_assert(i->inSize == sizeof(*i));
ASSIGN(i, postEvent);
}

Просмотреть файл

@ -0,0 +1,152 @@
/*
* 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 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.
*/
#ifndef ANPKeyCodes_DEFINED
#define ANPKeyCodes_DEFINED
/* List the key codes that are set to a plugin in the ANPKeyEvent.
These exactly match the values in android/view/KeyEvent.java and the
corresponding .h file android/keycodes.h.
*/
enum ANPKeyCodes {
kUnknown_ANPKeyCode = 0,
kSoftLeft_ANPKeyCode = 1,
kSoftRight_ANPKeyCode = 2,
kHome_ANPKeyCode = 3,
kBack_ANPKeyCode = 4,
kCall_ANPKeyCode = 5,
kEndCall_ANPKeyCode = 6,
k0_ANPKeyCode = 7,
k1_ANPKeyCode = 8,
k2_ANPKeyCode = 9,
k3_ANPKeyCode = 10,
k4_ANPKeyCode = 11,
k5_ANPKeyCode = 12,
k6_ANPKeyCode = 13,
k7_ANPKeyCode = 14,
k8_ANPKeyCode = 15,
k9_ANPKeyCode = 16,
kStar_ANPKeyCode = 17,
kPound_ANPKeyCode = 18,
kDpadUp_ANPKeyCode = 19,
kDpadDown_ANPKeyCode = 20,
kDpadLeft_ANPKeyCode = 21,
kDpadRight_ANPKeyCode = 22,
kDpadCenter_ANPKeyCode = 23,
kVolumeUp_ANPKeyCode = 24,
kVolumeDown_ANPKeyCode = 25,
kPower_ANPKeyCode = 26,
kCamera_ANPKeyCode = 27,
kClear_ANPKeyCode = 28,
kA_ANPKeyCode = 29,
kB_ANPKeyCode = 30,
kC_ANPKeyCode = 31,
kD_ANPKeyCode = 32,
kE_ANPKeyCode = 33,
kF_ANPKeyCode = 34,
kG_ANPKeyCode = 35,
kH_ANPKeyCode = 36,
kI_ANPKeyCode = 37,
kJ_ANPKeyCode = 38,
kK_ANPKeyCode = 39,
kL_ANPKeyCode = 40,
kM_ANPKeyCode = 41,
kN_ANPKeyCode = 42,
kO_ANPKeyCode = 43,
kP_ANPKeyCode = 44,
kQ_ANPKeyCode = 45,
kR_ANPKeyCode = 46,
kS_ANPKeyCode = 47,
kT_ANPKeyCode = 48,
kU_ANPKeyCode = 49,
kV_ANPKeyCode = 50,
kW_ANPKeyCode = 51,
kX_ANPKeyCode = 52,
kY_ANPKeyCode = 53,
kZ_ANPKeyCode = 54,
kComma_ANPKeyCode = 55,
kPeriod_ANPKeyCode = 56,
kAltLeft_ANPKeyCode = 57,
kAltRight_ANPKeyCode = 58,
kShiftLeft_ANPKeyCode = 59,
kShiftRight_ANPKeyCode = 60,
kTab_ANPKeyCode = 61,
kSpace_ANPKeyCode = 62,
kSym_ANPKeyCode = 63,
kExplorer_ANPKeyCode = 64,
kEnvelope_ANPKeyCode = 65,
kNewline_ANPKeyCode = 66,
kDel_ANPKeyCode = 67,
kGrave_ANPKeyCode = 68,
kMinus_ANPKeyCode = 69,
kEquals_ANPKeyCode = 70,
kLeftBracket_ANPKeyCode = 71,
kRightBracket_ANPKeyCode = 72,
kBackslash_ANPKeyCode = 73,
kSemicolon_ANPKeyCode = 74,
kApostrophe_ANPKeyCode = 75,
kSlash_ANPKeyCode = 76,
kAt_ANPKeyCode = 77,
kNum_ANPKeyCode = 78,
kHeadSetHook_ANPKeyCode = 79,
kFocus_ANPKeyCode = 80,
kPlus_ANPKeyCode = 81,
kMenu_ANPKeyCode = 82,
kNotification_ANPKeyCode = 83,
kSearch_ANPKeyCode = 84,
kMediaPlayPause_ANPKeyCode = 85,
kMediaStop_ANPKeyCode = 86,
kMediaNext_ANPKeyCode = 87,
kMediaPrevious_ANPKeyCode = 88,
kMediaRewind_ANPKeyCode = 89,
kMediaFastForward_ANPKeyCode = 90,
kMute_ANPKeyCode = 91,
kPageUp_ANPKeyCode = 92,
kPageDown_ANPKeyCode = 93,
kPictsymbols_ANPKeyCode = 94,
kSwitchCharset_ANPKeyCode = 95,
kButtonA_ANPKeyCode = 96,
kButtonB_ANPKeyCode = 97,
kButtonC_ANPKeyCode = 98,
kButtonX_ANPKeyCode = 99,
kButtonY_ANPKeyCode = 100,
kButtonZ_ANPKeyCode = 101,
kButtonL1_ANPKeyCode = 102,
kButtonR1_ANPKeyCode = 103,
kButtonL2_ANPKeyCode = 104,
kButtonR2_ANPKeyCode = 105,
kButtonThumbL_ANPKeyCode = 106,
kButtonThumbR_ANPKeyCode = 107,
kButtonStart_ANPKeyCode = 108,
kButtonSelect_ANPKeyCode = 109,
kButtonMode_ANPKeyCode = 110,
// NOTE: If you add a new keycode here you must also add it to several other files.
// Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
};
#endif

Просмотреть файл

@ -0,0 +1,59 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android NPAPI support code
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Doug Turner <dougt@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "assert.h"
#include "ANPBase.h"
#include <android/log.h>
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
#define ASSIGN(obj, name) (obj)->name = anp_log_##name
void
anp_log_log(ANPLogType type, const char format[], ...) {
va_list argp;
va_start(argp,format);
__android_log_vprint(type == kError_ANPLogType ? ANDROID_LOG_ERROR : type == kWarning_ANPLogType ?
ANDROID_LOG_WARN : ANDROID_LOG_INFO, "GeckoPluginLog", format, argp);
va_end(argp);
}
void InitLogInterface(ANPLogInterfaceV0 *i) {
_assert(i->inSize == sizeof(*i));
ASSIGN(i, log);
}

Просмотреть файл

@ -0,0 +1,197 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android NPAPI support code
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Doug Turner <dougt@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "assert.h"
#include "ANPBase.h"
#include <android/log.h>
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
#define ASSIGN(obj, name) (obj)->name = anp_matrix_##name
/** Return a new identity matrix
*/
ANPMatrix*
anp_matrix_newMatrix()
{
NOT_IMPLEMENTED();
return 0;
}
/** Delete a matrix previously allocated by newMatrix()
*/
void
anp_matrix_deleteMatrix(ANPMatrix*)
{
NOT_IMPLEMENTED();
}
ANPMatrixFlag
anp_matrix_getFlags(const ANPMatrix*)
{
NOT_IMPLEMENTED();
return 0;
}
void
anp_matrix_copy(ANPMatrix* dst, const ANPMatrix* src)
{
NOT_IMPLEMENTED();
}
void
anp_matrix_get3x3(const ANPMatrix*, float[9])
{
NOT_IMPLEMENTED();
}
void
anp_matrix_set3x3(ANPMatrix*, const float[9])
{
NOT_IMPLEMENTED();
}
void
anp_matrix_setIdentity(ANPMatrix*)
{
NOT_IMPLEMENTED();
}
void
anp_matrix_preTranslate(ANPMatrix*, float tx, float ty)
{
NOT_IMPLEMENTED();
}
void
anp_matrix_postTranslate(ANPMatrix*, float tx, float ty)
{
NOT_IMPLEMENTED();
}
void
anp_matrix_preScale(ANPMatrix*, float sx, float sy)
{
NOT_IMPLEMENTED();
}
void
anp_matrix_postScale(ANPMatrix*, float sx, float sy)
{
NOT_IMPLEMENTED();
}
void
anp_matrix_preSkew(ANPMatrix*, float kx, float ky)
{
NOT_IMPLEMENTED();
}
void
anp_matrix_postSkew(ANPMatrix*, float kx, float ky)
{
NOT_IMPLEMENTED();
}
void
anp_matrix_preRotate(ANPMatrix*, float degrees)
{
NOT_IMPLEMENTED();
}
void
anp_matrix_postRotate(ANPMatrix*, float degrees)
{
NOT_IMPLEMENTED();
}
void
anp_matrix_preConcat(ANPMatrix*, const ANPMatrix*)
{
NOT_IMPLEMENTED();
}
void
anp_matrix_postConcat(ANPMatrix*, const ANPMatrix*)
{
NOT_IMPLEMENTED();
}
bool
anp_matrix_invert(ANPMatrix* dst, const ANPMatrix* src)
{
NOT_IMPLEMENTED();
return false;
}
void
anp_matrix_mapPoints(ANPMatrix*, float dst[], const float src[],
int32_t count)
{
NOT_IMPLEMENTED();
}
void InitMatrixInterface(ANPMatrixInterfaceV0 *i) {
_assert(i->inSize == sizeof(*i));
ASSIGN(i, newMatrix);
ASSIGN(i, deleteMatrix);
ASSIGN(i, getFlags);
ASSIGN(i, copy);
ASSIGN(i, get3x3);
ASSIGN(i, set3x3);
ASSIGN(i, setIdentity);
ASSIGN(i, preTranslate);
ASSIGN(i, postTranslate);
ASSIGN(i, preScale);
ASSIGN(i, postScale);
ASSIGN(i, preSkew);
ASSIGN(i, postSkew);
ASSIGN(i, preRotate);
ASSIGN(i, postRotate);
ASSIGN(i, preConcat);
ASSIGN(i, postConcat);
ASSIGN(i, invert);
ASSIGN(i, mapPoints);
}

Просмотреть файл

@ -0,0 +1,454 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android NPAPI support code
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Doug Turner <dougt@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <stdlib.h>
#include <assert.h>
#include <android/log.h>
#include "ANPBase.h"
#define LOG(args...)
//__android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
#define ASSIGN(obj, name) (obj)->name = anp_paint_##name
ANPPaint*
anp_paint_newPaint()
{
LOG("%s", __PRETTY_FUNCTION__);
ANPPaintPrivate* p = (ANPPaintPrivate*) calloc(1, sizeof(ANPPaintPrivate));
return (ANPPaint*) p;
}
void
anp_paint_deletePaint(ANPPaint* paint)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
free((void*)p);
}
ANPPaintFlags
anp_paint_getFlags(const ANPPaint* paint)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return kAntiAlias_ANPPaintFlag;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
return p->flags;
}
void
anp_paint_setFlags(ANPPaint* paint, ANPPaintFlags flags)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
p->flags = flags;
}
ANPColor
anp_paint_getColor(const ANPPaint* paint)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return ANP_MAKE_COLOR(1, 255, 255, 255);
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
return p->color;
}
void
anp_paint_setColor(ANPPaint* paint, ANPColor color)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
p->color = color;
}
ANPPaintStyle
anp_paint_getStyle(const ANPPaint* paint)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return kFill_ANPPaintStyle;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
return p->style;
}
void
anp_paint_setStyle(ANPPaint* paint, ANPPaintStyle style)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
p->style = style;
}
float
anp_paint_getStrokeWidth(const ANPPaint* paint)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return 0;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
return p->strokeWidth;
}
float
anp_paint_getStrokeMiter(const ANPPaint* paint)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return 0;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
return p->strokeMiter;
}
ANPPaintCap
anp_paint_getStrokeCap(const ANPPaint* paint)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return kButt_ANPPaintCap;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
return p->paintCap;
}
ANPPaintJoin
anp_paint_getStrokeJoin(const ANPPaint* paint)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return kMiter_ANPPaintJoin;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
return p->paintJoin;
}
void
anp_paint_setStrokeWidth(ANPPaint* paint, float width)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
p->strokeWidth = width;
}
void
anp_paint_setStrokeMiter(ANPPaint* paint, float miter)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
p->strokeMiter = miter;
}
void
anp_paint_setStrokeCap(ANPPaint* paint, ANPPaintCap cap)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
p->paintCap = cap;
}
void
anp_paint_setStrokeJoin(ANPPaint* paint, ANPPaintJoin join)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
p->paintJoin = join;
}
ANPTextEncoding
anp_paint_getTextEncoding(const ANPPaint* paint)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return kUTF8_ANPTextEncoding;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
return p->textEncoding;
}
ANPPaintAlign
anp_paint_getTextAlign(const ANPPaint* paint)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return kLeft_ANPPaintAlign;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
return p->paintAlign;
}
float
anp_paint_getTextSize(const ANPPaint* paint)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return 0;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
return p->textSize;
}
float
anp_paint_getTextScaleX(const ANPPaint* paint)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return 0;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
return p->textScaleX;
}
float
anp_paint_getTextSkewX(const ANPPaint* paint)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return 0;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
return p->textSkewX;
}
void
anp_paint_setTextEncoding(ANPPaint* paint, ANPTextEncoding encoding)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
p->textEncoding = encoding;
}
void
anp_paint_setTextAlign(ANPPaint* paint, ANPPaintAlign align)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
p->paintAlign = align;
}
void
anp_paint_setTextSize(ANPPaint* paint, float size)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
p->textSize = size;
}
void
anp_paint_setTextScaleX(ANPPaint* paint, float scale)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
p->textScaleX = scale;
}
void
anp_paint_setTextSkewX(ANPPaint* paint, float skew)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
p->textSkewX = skew;
}
/** Return the typeface in paint, or null if there is none. This does not
modify the owner count of the returned typeface.
*/
ANPTypeface*
anp_paint_getTypeface(const ANPPaint* paint)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return NULL;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
return &p->typeface;
}
/** Set the paint's typeface. If the paint already had a non-null typeface,
its owner count is decremented. If the new typeface is non-null, its
owner count is incremented.
*/
void
anp_paint_setTypeface(ANPPaint* paint, ANPTypeface* typeface)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
LOG("%s is not impl.", __PRETTY_FUNCTION__);
}
/** Return the width of the text. If bounds is not null, return the bounds
of the text in that rectangle.
*/
float
anp_paint_measureText(ANPPaint* paint, const void* text, uint32_t byteLength,
ANPRectF* bounds)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return 0;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
LOG("%s is not impl.", __PRETTY_FUNCTION__);
return 0;
}
/** Return the number of unichars specifed by the text.
If widths is not null, returns the array of advance widths for each
unichar.
If bounds is not null, returns the array of bounds for each unichar.
*/
int
anp_paint_getTextWidths(ANPPaint* paint, const void* text, uint32_t byteLength,
float widths[], ANPRectF bounds[])
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return 0;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
LOG("%s is not impl.", __PRETTY_FUNCTION__);
return 0;
}
/** Return in metrics the spacing values for text, respecting the paint's
typeface and pointsize, and return the spacing between lines
(descent - ascent + leading). If metrics is NULL, it will be ignored.
*/
float
anp_paint_getFontMetrics(ANPPaint* paint, ANPFontMetrics* metrics)
{
LOG("%s", __PRETTY_FUNCTION__);
if (!paint)
return 0;
ANPPaintPrivate* p = (ANPPaintPrivate*) paint;
LOG("%s is not impl.", __PRETTY_FUNCTION__);
return 0;
}
void InitPaintInterface(ANPPaintInterfaceV0 *i) {
_assert(i->inSize == sizeof(*i));
ASSIGN(i, newPaint);
ASSIGN(i, deletePaint);
ASSIGN(i, getFlags);
ASSIGN(i, setFlags);
ASSIGN(i, getColor);
ASSIGN(i, setColor);
ASSIGN(i, getStyle);
ASSIGN(i, setStyle);
ASSIGN(i, getStrokeWidth);
ASSIGN(i, getStrokeMiter);
ASSIGN(i, getStrokeCap);
ASSIGN(i, getStrokeJoin);
ASSIGN(i, setStrokeWidth);
ASSIGN(i, setStrokeMiter);
ASSIGN(i, setStrokeCap);
ASSIGN(i, setStrokeJoin);
ASSIGN(i, getTextEncoding);
ASSIGN(i, getTextAlign);
ASSIGN(i, getTextSize);
ASSIGN(i, getTextScaleX);
ASSIGN(i, getTextSkewX);
ASSIGN(i, setTextEncoding);
ASSIGN(i, setTextAlign);
ASSIGN(i, setTextSize);
ASSIGN(i, setTextScaleX);
ASSIGN(i, setTextSkewX);
ASSIGN(i, getTypeface);
ASSIGN(i, setTypeface);
ASSIGN(i, measureText);
ASSIGN(i, getTextWidths);
ASSIGN(i, getFontMetrics);
}

Просмотреть файл

@ -0,0 +1,171 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android NPAPI support code
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Doug Turner <dougt@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "assert.h"
#include "ANPBase.h"
#include <android/log.h>
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
#define ASSIGN(obj, name) (obj)->name = anp_path_##name
// maybe this should store a list of actions (lineTo,
// moveTo), and when canvas_drawPath() we apply all of these
// actions to the gfxContext.
ANPPath*
anp_path_newPath()
{
LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
return 0;
}
void
anp_path_deletePath(ANPPath* p)
{
LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
}
void
anp_path_copy(ANPPath* dst, const ANPPath* src)
{
LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
}
bool
anp_path_equal(const ANPPath* path0, const ANPPath* path1)
{
LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
return false;
}
void
anp_path_reset(ANPPath* p)
{
LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
}
bool
anp_path_isEmpty(const ANPPath* p)
{
LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
return false;
}
void
anp_path_getBounds(const ANPPath* p, ANPRectF* bounds)
{
LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
bounds->left = 0;
bounds->top = 0;
bounds->right = 1000;
bounds->left = 1000;
}
void
anp_path_moveTo(ANPPath* p, float x, float y)
{
LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
}
void
anp_path_lineTo(ANPPath* p, float x, float y)
{
LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
}
void
anp_path_quadTo(ANPPath* p, float x0, float y0, float x1, float y1)
{
LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
}
void
anp_path_cubicTo(ANPPath* p, float x0, float y0, float x1, float y1,
float x2, float y2)
{
LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
}
void
anp_path_close(ANPPath* p)
{
LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
}
void
anp_path_offset(ANPPath* src, float dx, float dy, ANPPath* dst)
{
LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
}
void
anp_path_transform(ANPPath* src, const ANPMatrix*, ANPPath* dst)
{
LOG("%s - NOT IMPL.", __PRETTY_FUNCTION__);
}
void InitPathInterface(ANPPathInterfaceV0 *i) {
_assert(i->inSize == sizeof(*i));
ASSIGN(i, newPath);
ASSIGN(i, deletePath);
ASSIGN(i, copy);
ASSIGN(i, equal);
ASSIGN(i, reset);
ASSIGN(i, isEmpty);
ASSIGN(i, getBounds);
ASSIGN(i, moveTo);
ASSIGN(i, lineTo);
ASSIGN(i, quadTo);
ASSIGN(i, cubicTo);
ASSIGN(i, close);
ASSIGN(i, offset);
ASSIGN(i, transform);
}

Просмотреть файл

@ -0,0 +1,189 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android NPAPI support code
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Doug Turner <dougt@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "assert.h"
#include "ANPBase.h"
#include <android/log.h>
#include "AndroidBridge.h"
#include "gfxImageSurface.h"
#include "gfxContext.h"
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
#define ASSIGN(obj, name) (obj)->name = anp_surface_##name
// used to cache JNI method and field IDs for Surface Objects
static struct ANPSurfaceInterfaceJavaGlue {
bool initialized;
jclass geckoAppShellClass;
jclass lockInfoCls;
jmethodID lockSurfaceANP;
jmethodID jUnlockSurfaceANP;
jfieldID jDirtyTop;
jfieldID jDirtyLeft;
jfieldID jDirtyBottom;
jfieldID jDirtyRight;
jfieldID jFormat;
jfieldID jWidth ;
jfieldID jHeight;
jfieldID jBuffer;
} gSurfaceJavaGlue;
#define getClassGlobalRef(env, cname) \
(jClass = jclass(env->NewGlobalRef(env->FindClass(cname))))
static void init(JNIEnv* env) {
if (gSurfaceJavaGlue.initialized)
return;
gSurfaceJavaGlue.geckoAppShellClass = mozilla::AndroidBridge::GetGeckoAppShellClass();
jmethodID getClass = env->GetStaticMethodID(gSurfaceJavaGlue.geckoAppShellClass,
"getSurfaceLockInfoClass",
"()Ljava/lang/Class;");
gSurfaceJavaGlue.lockInfoCls = (jclass) env->NewGlobalRef(env->CallStaticObjectMethod(gSurfaceJavaGlue.geckoAppShellClass, getClass));
gSurfaceJavaGlue.jDirtyTop = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "dirtyTop", "I");
gSurfaceJavaGlue.jDirtyLeft = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "dirtyLeft", "I");
gSurfaceJavaGlue.jDirtyBottom = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "dirtyBottom", "I");
gSurfaceJavaGlue.jDirtyRight = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "dirtyRight", "I");
gSurfaceJavaGlue.jFormat = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "format", "I");
gSurfaceJavaGlue.jWidth = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "width", "I");
gSurfaceJavaGlue.jHeight = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "height", "I");
gSurfaceJavaGlue.jBuffer = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "buffer", "Ljava/nio/Buffer;");
gSurfaceJavaGlue.lockSurfaceANP = env->GetStaticMethodID(gSurfaceJavaGlue.geckoAppShellClass, "lockSurfaceANP", "(Landroid/view/SurfaceView;IIII)Lorg/mozilla/gecko/SurfaceLockInfo;");
gSurfaceJavaGlue.jUnlockSurfaceANP = env->GetStaticMethodID(gSurfaceJavaGlue.geckoAppShellClass, "unlockSurfaceANP", "(Landroid/view/SurfaceView;)V");
gSurfaceJavaGlue.initialized = true;
}
static bool anp_lock(JNIEnv* env, jobject surfaceView, ANPBitmap* bitmap, ANPRectI* dirtyRect) {
LOG("%s", __PRETTY_FUNCTION__);
if (!bitmap || !surfaceView) {
LOG("%s, null bitmap or surface, exiting", __PRETTY_FUNCTION__);
return false;
}
init(env);
jvalue args[5];
args[0].l = surfaceView;
if (dirtyRect) {
args[1].i = dirtyRect->top;
args[2].i = dirtyRect->left;
args[3].i = dirtyRect->bottom;
args[4].i = dirtyRect->right;
LOG("dirty rect: %d, %d, %d, %d", dirtyRect->top, dirtyRect->left, dirtyRect->bottom, dirtyRect->right);
} else {
args[1].i = args[2].i = args[3].i = args[4].i = 0;
}
jobject info = env->CallStaticObjectMethod(gSurfaceJavaGlue.geckoAppShellClass,
gSurfaceJavaGlue.lockSurfaceANP,
surfaceView, args[1].i, args[2].i, args[3].i, args[4].i);
LOG("info: %p", info);
if (!info)
return false;
// the surface may have expanded the dirty region so we must to pass that
// information back to the plugin.
if (dirtyRect) {
dirtyRect->left = env->GetIntField(info, gSurfaceJavaGlue.jDirtyLeft);
dirtyRect->right = env->GetIntField(info, gSurfaceJavaGlue.jDirtyRight);
dirtyRect->top = env->GetIntField(info, gSurfaceJavaGlue.jDirtyTop);
dirtyRect->bottom = env->GetIntField(info, gSurfaceJavaGlue.jDirtyBottom);
LOG("dirty rect: %d, %d, %d, %d", dirtyRect->top, dirtyRect->left, dirtyRect->bottom, dirtyRect->right);
}
bitmap->width = env->GetIntField(info, gSurfaceJavaGlue.jWidth);
bitmap->height = env->GetIntField(info, gSurfaceJavaGlue.jHeight);
int format = env->GetIntField(info, gSurfaceJavaGlue.jFormat);
// format is PixelFormat
if (format & 0x00000001) {
bitmap->format = kRGBA_8888_ANPBitmapFormat;
bitmap->rowBytes = bitmap->width * 4;
}
else if (format & 0x00000004) {
bitmap->format = kRGB_565_ANPBitmapFormat;
bitmap->rowBytes = bitmap->width * 2;
}
else {
LOG("format from glue is unknown %d\n", format);
return false;
}
jobject buf = env->GetObjectField(info, gSurfaceJavaGlue.jBuffer);
bitmap->baseAddr = env->GetDirectBufferAddress(buf);
LOG("format: %d, width: %d, height: %d", bitmap->format, bitmap->width, bitmap->height);
env->DeleteLocalRef(info);
env->DeleteLocalRef(buf);
return ( bitmap->width > 0 && bitmap->height > 0 );
}
static void anp_unlock(JNIEnv* env, jobject surfaceView) {
LOG("%s", __PRETTY_FUNCTION__);
if (!surfaceView) {
LOG("null surface, exiting %s", __PRETTY_FUNCTION__);
return;
}
init(env);
env->CallStaticVoidMethod(gSurfaceJavaGlue.geckoAppShellClass, gSurfaceJavaGlue.jUnlockSurfaceANP, surfaceView);
LOG("returning from %s", __PRETTY_FUNCTION__);
}
///////////////////////////////////////////////////////////////////////////////
#define ASSIGN(obj, name) (obj)->name = anp_##name
void InitSurfaceInterface(ANPSurfaceInterfaceV0 *i) {
ASSIGN(i, lock);
ASSIGN(i, unlock);
// setup the java glue struct
gSurfaceJavaGlue.initialized = false;
}

Просмотреть файл

@ -0,0 +1,86 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android NPAPI support code
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Doug Turner <dougt@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "base/basictypes.h"
#include "assert.h"
#include "ANPBase.h"
#include <android/log.h>
#include "nsNPAPIPluginInstance.h"
#include "AndroidBridge.h"
#include "nsNPAPIPlugin.h"
#include "PluginPRLibrary.h"
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
#define ASSIGN(obj, name) (obj)->name = anp_system_##name
const char*
anp_system_getApplicationDataDirectory()
{
LOG("getApplicationDataDirectory return /data/data/org.mozilla.%s", MOZ_APP_NAME);
return "/data/data/org.mozilla." MOZ_APP_NAME;
}
jclass anp_system_loadJavaClass(NPP instance, const char* className)
{
LOG("%s", __PRETTY_FUNCTION__);
JNIEnv* env = GetJNIForThread();
jclass cls = env->FindClass("org/mozilla/gecko/GeckoAppShell");
jmethodID method = env->GetStaticMethodID(cls,
"loadPluginClass",
"(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Class;");
// pass libname and classname, gotta create java strings
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
mozilla::PluginPRLibrary* lib = static_cast<mozilla::PluginPRLibrary*>(pinst->GetPlugin()->GetLibrary());
nsCString libName;
lib->GetLibraryPath(libName);
jstring jclassName = env->NewStringUTF(className);
jstring jlibName = env->NewStringUTF(libName.get());
jobject obj = env->CallStaticObjectMethod(cls, method, jclassName, jlibName);
return reinterpret_cast<jclass>(obj);
}
void InitSystemInterface(ANPSystemInterfaceV0 *i) {
_assert(i->inSize == sizeof(*i));
ASSIGN(i, getApplicationDataDirectory);
ASSIGN(i, loadJavaClass);
}

Просмотреть файл

@ -0,0 +1,151 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android NPAPI support code
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Doug Turner <dougt@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "assert.h"
#include "ANPBase.h"
#include <android/log.h>
#include "gfxAndroidPlatform.h"
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
#define ASSIGN(obj, name) (obj)->name = anp_typeface_##name
ANPTypeface*
anp_typeface_createFromName(const char name[], ANPTypefaceStyle aStyle)
{
LOG("%s - %s\n", __PRETTY_FUNCTION__, name);
gfxFontStyle style (aStyle == kItalic_ANPTypefaceStyle ? FONT_STYLE_ITALIC :
FONT_STYLE_NORMAL,
NS_FONT_STRETCH_NORMAL,
aStyle == kBold_ANPTypefaceStyle ? 700 : 400,
16.0,
NS_NewPermanentAtom(NS_LITERAL_STRING("en")),
0.0,
PR_FALSE, PR_FALSE,
NS_LITERAL_STRING(""),
NS_LITERAL_STRING(""));
ANPTypeface* tf = new ANPTypeface;
gfxAndroidPlatform * p = (gfxAndroidPlatform*)gfxPlatform::GetPlatform();
tf->mFont = gfxFT2Font::GetOrMakeFont(NS_ConvertASCIItoUTF16(name), &style);
return tf;
}
ANPTypeface*
anp_typeface_createFromTypeface(const ANPTypeface* family,
ANPTypefaceStyle)
{
NOT_IMPLEMENTED();
return 0;
}
int32_t
anp_typeface_getRefCount(const ANPTypeface*)
{
NOT_IMPLEMENTED();
return 0;
}
void
anp_typeface_ref(ANPTypeface* tf)
{
LOG("%s\n", __PRETTY_FUNCTION__);
if (tf->mFont)
tf->mFont->AddRef();
}
void
anp_typeface_unref(ANPTypeface* tf)
{
LOG("%s\n", __PRETTY_FUNCTION__);
if (tf->mFont)
tf->mFont->Release();
}
ANPTypefaceStyle
anp_typeface_getStyle(const ANPTypeface* ft)
{
LOG("%s\n", __PRETTY_FUNCTION__);
return kBold_ANPTypefaceStyle;
}
int32_t
anp_typeface_getFontPath(const ANPTypeface*, char path[], int32_t length,
int32_t* index)
{
NOT_IMPLEMENTED();
return 0;
}
static const char* gFontDir;
#define FONT_DIR_SUFFIX "/fonts/"
const char*
anp_typeface_getFontDirectoryPath()
{
LOG("%s\n", __PRETTY_FUNCTION__);
if (NULL == gFontDir) {
const char* root = getenv("ANDROID_ROOT");
size_t len = strlen(root);
char* storage = (char*)malloc(len + sizeof(FONT_DIR_SUFFIX));
if (NULL == storage) {
return NULL;
}
memcpy(storage, root, len);
memcpy(storage + len, FONT_DIR_SUFFIX, sizeof(FONT_DIR_SUFFIX));
// save this assignment for last, so that if multiple threads call us
// (which should never happen), we never return an incomplete global.
// At worst, we would allocate storage for the path twice.
gFontDir = storage;
}
return 0;
}
void InitTypeFaceInterface(ANPTypefaceInterfaceV0 *i) {
_assert(i->inSize == sizeof(*i));
ASSIGN(i, createFromName);
ASSIGN(i, createFromTypeface);
ASSIGN(i, getRefCount);
ASSIGN(i, ref);
ASSIGN(i, unref);
ASSIGN(i, getStyle);
ASSIGN(i, getFontPath);
ASSIGN(i, getFontDirectoryPath);
}

Просмотреть файл

@ -0,0 +1,91 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Android NPAPI support code
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Doug Turner <dougt@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "assert.h"
#include "ANPBase.h"
#include <android/log.h>
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
#define ASSIGN(obj, name) (obj)->name = anp_window_##name
void
anp_window_setVisibleRects(NPP instance, const ANPRectI rects[], int32_t count)
{
NOT_IMPLEMENTED();
}
void
anp_window_clearVisibleRects(NPP instance)
{
NOT_IMPLEMENTED();
}
void
anp_window_showKeyboard(NPP instance, bool value)
{
NOT_IMPLEMENTED();
}
void
anp_window_requestFullScreen(NPP instance)
{
NOT_IMPLEMENTED();
}
void
anp_window_exitFullScreen(NPP instance)
{
NOT_IMPLEMENTED();
}
void
anp_window_requestCenterFitZoom(NPP instance)
{
NOT_IMPLEMENTED();
}
void InitWindowInterface(ANPWindowInterfaceV0 *i) {
_assert(i->inSize == sizeof(*i));
ASSIGN(i, setVisibleRects);
ASSIGN(i, clearVisibleRects);
ASSIGN(i, showKeyboard);
ASSIGN(i, requestFullScreen);
ASSIGN(i, exitFullScreen);
ASSIGN(i, requestCenterFitZoom);
}

Просмотреть файл

@ -0,0 +1,81 @@
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# Netscape Communications Corporation.
# Portions created by the Initial Developer are Copyright (C) 1998
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = plugin
LIBRARY_NAME = gkpluginandroid_s
LIBXUL_LIBRARY = 1
FORCE_STATIC_LIB = 1
EXPORT_LIBRARY = 1
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk
EXPORTS = \
android_npapi.h \
$(NULL)
CPPSRCS += ANPAudio.cpp \
ANPCanvas.cpp \
ANPEvent.cpp \
ANPMatrix.cpp \
ANPPath.cpp \
ANPSystem.cpp \
ANPWindow.cpp \
ANPBitmap.cpp \
ANPLog.cpp \
ANPPaint.cpp \
ANPSurface.cpp \
ANPTypeface.cpp \
$(NULL)
LOCAL_INCLUDES += \
-I$(topsrcdir)/dom/plugins/base \
$(MOZ_CAIRO_CFLAGS) \
$(NULL)
DEFINES += -DMOZ_APP_NAME='"$(MOZ_APP_NAME)"'
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -0,0 +1,979 @@
/*
* 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.
*/
/* Defines the android-specific types and functions as part of npapi
In particular, defines the window and event types that are passed to
NPN_GetValue, NPP_SetWindow and NPP_HandleEvent.
To minimize what native libraries the plugin links against, some
functionality is provided via function-ptrs (e.g. time, sound)
*/
#ifndef android_npapi_H
#define android_npapi_H
#include <stdint.h>
#include "npapi.h"
#include <jni.h>
///////////////////////////////////////////////////////////////////////////////
// General types
enum ANPBitmapFormats {
kUnknown_ANPBitmapFormat = 0,
kRGBA_8888_ANPBitmapFormat = 1,
kRGB_565_ANPBitmapFormat = 2
};
typedef int32_t ANPBitmapFormat;
struct ANPPixelPacking {
uint8_t AShift;
uint8_t ABits;
uint8_t RShift;
uint8_t RBits;
uint8_t GShift;
uint8_t GBits;
uint8_t BShift;
uint8_t BBits;
};
struct ANPBitmap {
void* baseAddr;
ANPBitmapFormat format;
int32_t width;
int32_t height;
int32_t rowBytes;
};
struct ANPRectF {
float left;
float top;
float right;
float bottom;
};
struct ANPRectI {
int32_t left;
int32_t top;
int32_t right;
int32_t bottom;
};
struct ANPCanvas;
struct ANPMatrix;
struct ANPPaint;
struct ANPPath;
struct ANPRegion;
struct ANPTypeface;
enum ANPMatrixFlags {
kIdentity_ANPMatrixFlag = 0,
kTranslate_ANPMatrixFlag = 0x01,
kScale_ANPMatrixFlag = 0x02,
kAffine_ANPMatrixFlag = 0x04,
kPerspective_ANPMatrixFlag = 0x08,
};
typedef uint32_t ANPMatrixFlag;
///////////////////////////////////////////////////////////////////////////////
// NPN_GetValue
/** queries for a specific ANPInterface.
Maybe called with NULL for the NPP instance
NPN_GetValue(inst, interface_enum, ANPInterface*)
*/
#define kLogInterfaceV0_ANPGetValue ((NPNVariable)1000)
#define kAudioTrackInterfaceV0_ANPGetValue ((NPNVariable)1001)
#define kCanvasInterfaceV0_ANPGetValue ((NPNVariable)1002)
#define kMatrixInterfaceV0_ANPGetValue ((NPNVariable)1003)
#define kPaintInterfaceV0_ANPGetValue ((NPNVariable)1004)
#define kPathInterfaceV0_ANPGetValue ((NPNVariable)1005)
#define kTypefaceInterfaceV0_ANPGetValue ((NPNVariable)1006)
#define kWindowInterfaceV0_ANPGetValue ((NPNVariable)1007)
#define kBitmapInterfaceV0_ANPGetValue ((NPNVariable)1008)
#define kSurfaceInterfaceV0_ANPGetValue ((NPNVariable)1009)
#define kSystemInterfaceV0_ANPGetValue ((NPNVariable)1010)
#define kEventInterfaceV0_ANPGetValue ((NPNVariable)1011)
/** queries for the drawing models supported on this device.
NPN_GetValue(inst, kSupportedDrawingModel_ANPGetValue, uint32_t* bits)
*/
#define kSupportedDrawingModel_ANPGetValue ((NPNVariable)2000)
/** queries for the context (android.content.Context) of the plugin. If no
instance is specified the application's context is returned. If the instance
is given then the context returned is identical to the context used to
create the webview in which that instance resides.
NOTE: Holding onto a non-application context after your instance has been
destroyed will cause a memory leak. Refer to the android documentation to
determine what context is best suited for your particular scenario.
NPN_GetValue(inst, kJavaContext_ANPGetValue, jobject context)
*/
#define kJavaContext_ANPGetValue ((NPNVariable)2001)
///////////////////////////////////////////////////////////////////////////////
// NPN_SetValue
/** Request to set the drawing model. SetValue will return false if the drawing
model is not supported or has insufficient information for configuration.
NPN_SetValue(inst, kRequestDrawingModel_ANPSetValue, (void*)foo_ANPDrawingModel)
*/
#define kRequestDrawingModel_ANPSetValue ((NPPVariable)1000)
/** These are used as bitfields in ANPSupportedDrawingModels_EnumValue,
and as-is in ANPRequestDrawingModel_EnumValue. The drawing model determines
how to interpret the ANPDrawingContext provided in the Draw event and how
to interpret the NPWindow->window field.
*/
enum ANPDrawingModels {
/** Draw into a bitmap from the browser thread in response to a Draw event.
NPWindow->window is reserved (ignore)
*/
kBitmap_ANPDrawingModel = 1 << 0,
/** Draw into a surface (e.g. raster, openGL, etc.) using the Java surface
interface. When this model is used the browser will invoke the Java
class specified in the plugin's apk manifest. From that class the browser
will invoke the appropriate method to return an an instance of a android
Java View. The instance is then embedded in the html. The plugin can then
manipulate the view as it would any normal Java View in android.
Unlike the bitmap model, a surface model is opaque so no html content
behind the plugin will be visible. Unless the plugin needs to be
transparent the surface model should be chosen over the bitmap model as
it will have better performance.
Further, a plugin can manipulate some surfaces in native code using the
ANPSurfaceInterface. This interface can be used to manipulate Java
objects that extend Surface.class by allowing them to access the
surface's underlying bitmap in native code. For instance, if a raster
surface is used the plugin can lock, draw directly into the bitmap, and
unlock the surface in native code without making JNI calls to the Java
surface object.
*/
kSurface_ANPDrawingModel = 1 << 1,
};
typedef int32_t ANPDrawingModel;
/** Request to receive/disable events. If the pointer is NULL then all flags will
be disabled. Otherwise, the event type will be enabled iff its corresponding
bit in the EventFlags bit field is set.
NPN_SetValue(inst, ANPAcceptEvents, (void*)EventFlags)
*/
#define kAcceptEvents_ANPSetValue ((NPPVariable)1001)
/** The EventFlags are a set of bits used to determine which types of events the
plugin wishes to receive. For example, if the value is 0x03 then both key
and touch events will be provided to the plugin.
*/
enum ANPEventFlag {
kKey_ANPEventFlag = 0x01,
kTouch_ANPEventFlag = 0x02,
};
typedef uint32_t ANPEventFlags;
///////////////////////////////////////////////////////////////////////////////
// NPP_GetValue
/** Requests that the plugin return a java surface to be displayed. This will
only be used if the plugin has choosen the kSurface_ANPDrawingModel.
NPP_GetValue(inst, kJavaSurface_ANPGetValue, jobject surface)
*/
#define kJavaSurface_ANPGetValue ((NPPVariable)2000)
///////////////////////////////////////////////////////////////////////////////
// ANDROID INTERFACE DEFINITIONS
/** Interfaces provide additional functionality to the plugin via function ptrs.
Once an interface is retrieved, it is valid for the lifetime of the plugin
(just like browserfuncs).
All ANPInterfaces begin with an inSize field, which must be set by the
caller (plugin) with the number of bytes allocated for the interface.
e.g. SomeInterface si; si.inSize = sizeof(si); browser->getvalue(..., &si);
*/
struct ANPInterface {
uint32_t inSize; // size (in bytes) of this struct
};
enum ANPLogTypes {
kError_ANPLogType = 0, // error
kWarning_ANPLogType = 1, // warning
kDebug_ANPLogType = 2 // debug only (informational)
};
typedef int32_t ANPLogType;
struct ANPLogInterfaceV0 : ANPInterface {
/** dumps printf messages to the log file
e.g. interface->log(instance, kWarning_ANPLogType, "value is %d", value);
*/
void (*log)(ANPLogType, const char format[], ...);
};
struct ANPBitmapInterfaceV0 : ANPInterface {
/** Returns true if the specified bitmap format is supported, and if packing
is non-null, sets it to the packing info for that format.
*/
bool (*getPixelPacking)(ANPBitmapFormat, ANPPixelPacking* packing);
};
struct ANPMatrixInterfaceV0 : ANPInterface {
/** Return a new identity matrix
*/
ANPMatrix* (*newMatrix)();
/** Delete a matrix previously allocated by newMatrix()
*/
void (*deleteMatrix)(ANPMatrix*);
ANPMatrixFlag (*getFlags)(const ANPMatrix*);
void (*copy)(ANPMatrix* dst, const ANPMatrix* src);
/** Return the matrix values in a float array (allcoated by the caller),
where the values are treated as follows:
w = x * [6] + y * [7] + [8];
x' = (x * [0] + y * [1] + [2]) / w;
y' = (x * [3] + y * [4] + [5]) / w;
*/
void (*get3x3)(const ANPMatrix*, float[9]);
/** Initialize the matrix from values in a float array,
where the values are treated as follows:
w = x * [6] + y * [7] + [8];
x' = (x * [0] + y * [1] + [2]) / w;
y' = (x * [3] + y * [4] + [5]) / w;
*/
void (*set3x3)(ANPMatrix*, const float[9]);
void (*setIdentity)(ANPMatrix*);
void (*preTranslate)(ANPMatrix*, float tx, float ty);
void (*postTranslate)(ANPMatrix*, float tx, float ty);
void (*preScale)(ANPMatrix*, float sx, float sy);
void (*postScale)(ANPMatrix*, float sx, float sy);
void (*preSkew)(ANPMatrix*, float kx, float ky);
void (*postSkew)(ANPMatrix*, float kx, float ky);
void (*preRotate)(ANPMatrix*, float degrees);
void (*postRotate)(ANPMatrix*, float degrees);
void (*preConcat)(ANPMatrix*, const ANPMatrix*);
void (*postConcat)(ANPMatrix*, const ANPMatrix*);
/** Return true if src is invertible, and if so, return its inverse in dst.
If src is not invertible, return false and ignore dst.
*/
bool (*invert)(ANPMatrix* dst, const ANPMatrix* src);
/** Transform the x,y pairs in src[] by this matrix, and store the results
in dst[]. The count parameter is treated as the number of pairs in the
array. It is legal for src and dst to point to the same memory, but
illegal for the two arrays to partially overlap.
*/
void (*mapPoints)(ANPMatrix*, float dst[], const float src[],
int32_t count);
};
struct ANPPathInterfaceV0 : ANPInterface {
/** Return a new path */
ANPPath* (*newPath)();
/** Delete a path previously allocated by ANPPath() */
void (*deletePath)(ANPPath*);
/** Make a deep copy of the src path, into the dst path (already allocated
by the caller).
*/
void (*copy)(ANPPath* dst, const ANPPath* src);
/** Returns true if the two paths are the same (i.e. have the same points)
*/
bool (*equal)(const ANPPath* path0, const ANPPath* path1);
/** Remove any previous points, initializing the path back to empty. */
void (*reset)(ANPPath*);
/** Return true if the path is empty (has no lines, quads or cubics). */
bool (*isEmpty)(const ANPPath*);
/** Return the path's bounds in bounds. */
void (*getBounds)(const ANPPath*, ANPRectF* bounds);
void (*moveTo)(ANPPath*, float x, float y);
void (*lineTo)(ANPPath*, float x, float y);
void (*quadTo)(ANPPath*, float x0, float y0, float x1, float y1);
void (*cubicTo)(ANPPath*, float x0, float y0, float x1, float y1,
float x2, float y2);
void (*close)(ANPPath*);
/** Offset the src path by [dx, dy]. If dst is null, apply the
change directly to the src path. If dst is not null, write the
changed path into dst, and leave the src path unchanged. In that case
dst must have been previously allocated by the caller.
*/
void (*offset)(ANPPath* src, float dx, float dy, ANPPath* dst);
/** Transform the path by the matrix. If dst is null, apply the
change directly to the src path. If dst is not null, write the
changed path into dst, and leave the src path unchanged. In that case
dst must have been previously allocated by the caller.
*/
void (*transform)(ANPPath* src, const ANPMatrix*, ANPPath* dst);
};
/** ANPColor is always defined to have the same packing on all platforms, and
it is always unpremultiplied.
This is in contrast to 32bit format(s) in bitmaps, which are premultiplied,
and their packing may vary depending on the platform, hence the need for
ANPBitmapInterface::getPixelPacking()
*/
typedef uint32_t ANPColor;
#define ANPColor_ASHIFT 24
#define ANPColor_RSHIFT 16
#define ANPColor_GSHIFT 8
#define ANPColor_BSHIFT 0
#define ANP_MAKE_COLOR(a, r, g, b) \
(((a) << ANPColor_ASHIFT) | \
((r) << ANPColor_RSHIFT) | \
((g) << ANPColor_GSHIFT) | \
((b) << ANPColor_BSHIFT))
enum ANPPaintFlag {
kAntiAlias_ANPPaintFlag = 1 << 0,
kFilterBitmap_ANPPaintFlag = 1 << 1,
kDither_ANPPaintFlag = 1 << 2,
kUnderlineText_ANPPaintFlag = 1 << 3,
kStrikeThruText_ANPPaintFlag = 1 << 4,
kFakeBoldText_ANPPaintFlag = 1 << 5,
};
typedef uint32_t ANPPaintFlags;
enum ANPPaintStyles {
kFill_ANPPaintStyle = 0,
kStroke_ANPPaintStyle = 1,
kFillAndStroke_ANPPaintStyle = 2
};
typedef int32_t ANPPaintStyle;
enum ANPPaintCaps {
kButt_ANPPaintCap = 0,
kRound_ANPPaintCap = 1,
kSquare_ANPPaintCap = 2
};
typedef int32_t ANPPaintCap;
enum ANPPaintJoins {
kMiter_ANPPaintJoin = 0,
kRound_ANPPaintJoin = 1,
kBevel_ANPPaintJoin = 2
};
typedef int32_t ANPPaintJoin;
enum ANPPaintAligns {
kLeft_ANPPaintAlign = 0,
kCenter_ANPPaintAlign = 1,
kRight_ANPPaintAlign = 2
};
typedef int32_t ANPPaintAlign;
enum ANPTextEncodings {
kUTF8_ANPTextEncoding = 0,
kUTF16_ANPTextEncoding = 1,
};
typedef int32_t ANPTextEncoding;
enum ANPTypefaceStyles {
kBold_ANPTypefaceStyle = 1 << 0,
kItalic_ANPTypefaceStyle = 1 << 1
};
typedef uint32_t ANPTypefaceStyle;
typedef uint32_t ANPFontTableTag;
struct ANPFontMetrics {
/** The greatest distance above the baseline for any glyph (will be <= 0) */
float fTop;
/** The recommended distance above the baseline (will be <= 0) */
float fAscent;
/** The recommended distance below the baseline (will be >= 0) */
float fDescent;
/** The greatest distance below the baseline for any glyph (will be >= 0) */
float fBottom;
/** The recommended distance to add between lines of text (will be >= 0) */
float fLeading;
};
struct ANPTypefaceInterfaceV0 : ANPInterface {
/** Return a new reference to the typeface that most closely matches the
requested name and style. Pass null as the name to return
the default font for the requested style. Will never return null
The 5 generic font names "serif", "sans-serif", "monospace", "cursive",
"fantasy" are recognized, and will be mapped to their logical font
automatically by this call.
@param name May be NULL. The name of the font family.
@param style The style (normal, bold, italic) of the typeface.
@return reference to the closest-matching typeface. Caller must call
unref() when they are done with the typeface.
*/
ANPTypeface* (*createFromName)(const char name[], ANPTypefaceStyle);
/** Return a new reference to the typeface that most closely matches the
requested typeface and specified Style. Use this call if you want to
pick a new style from the same family of the existing typeface.
If family is NULL, this selects from the default font's family.
@param family May be NULL. The name of the existing type face.
@param s The style (normal, bold, italic) of the type face.
@return reference to the closest-matching typeface. Call must call
unref() when they are done.
*/
ANPTypeface* (*createFromTypeface)(const ANPTypeface* family,
ANPTypefaceStyle);
/** Return the owner count of the typeface. A newly created typeface has an
owner count of 1. When the owner count is reaches 0, the typeface is
deleted.
*/
int32_t (*getRefCount)(const ANPTypeface*);
/** Increment the owner count on the typeface
*/
void (*ref)(ANPTypeface*);
/** Decrement the owner count on the typeface. When the count goes to 0,
the typeface is deleted.
*/
void (*unref)(ANPTypeface*);
/** Return the style bits for the specified typeface
*/
ANPTypefaceStyle (*getStyle)(const ANPTypeface*);
/** Some fonts are stored in files. If that is true for the fontID, then
this returns the byte length of the full file path. If path is not null,
then the full path is copied into path (allocated by the caller), up to
length bytes. If index is not null, then it is set to the truetype
collection index for this font, or 0 if the font is not in a collection.
Note: getFontPath does not assume that path is a null-terminated string,
so when it succeeds, it only copies the bytes of the file name and
nothing else (i.e. it copies exactly the number of bytes returned by the
function. If the caller wants to treat path[] as a C string, it must be
sure that it is allocated at least 1 byte larger than the returned size,
and it must copy in the terminating 0.
If the fontID does not correspond to a file, then the function returns
0, and the path and index parameters are ignored.
@param fontID The font whose file name is being queried
@param path Either NULL, or storage for receiving up to length bytes
of the font's file name. Allocated by the caller.
@param length The maximum space allocated in path (by the caller).
Ignored if path is NULL.
@param index Either NULL, or receives the TTC index for this font.
If the font is not a TTC, then will be set to 0.
@return The byte length of th font's file name, or 0 if the font is not
baked by a file.
*/
int32_t (*getFontPath)(const ANPTypeface*, char path[], int32_t length,
int32_t* index);
/** Return a UTF8 encoded path name for the font directory, or NULL if not
supported. If returned, this string address will be valid for the life
of the plugin instance. It will always end with a '/' character.
*/
const char* (*getFontDirectoryPath)();
};
struct ANPPaintInterfaceV0 : ANPInterface {
/** Return a new paint object, which holds all of the color and style
attributes that affect how things (geometry, text, bitmaps) are drawn
in a ANPCanvas.
The paint that is returned is not tied to any particular plugin
instance, but it must only be accessed from one thread at a time.
*/
ANPPaint* (*newPaint)();
void (*deletePaint)(ANPPaint*);
ANPPaintFlags (*getFlags)(const ANPPaint*);
void (*setFlags)(ANPPaint*, ANPPaintFlags);
ANPColor (*getColor)(const ANPPaint*);
void (*setColor)(ANPPaint*, ANPColor);
ANPPaintStyle (*getStyle)(const ANPPaint*);
void (*setStyle)(ANPPaint*, ANPPaintStyle);
float (*getStrokeWidth)(const ANPPaint*);
float (*getStrokeMiter)(const ANPPaint*);
ANPPaintCap (*getStrokeCap)(const ANPPaint*);
ANPPaintJoin (*getStrokeJoin)(const ANPPaint*);
void (*setStrokeWidth)(ANPPaint*, float);
void (*setStrokeMiter)(ANPPaint*, float);
void (*setStrokeCap)(ANPPaint*, ANPPaintCap);
void (*setStrokeJoin)(ANPPaint*, ANPPaintJoin);
ANPTextEncoding (*getTextEncoding)(const ANPPaint*);
ANPPaintAlign (*getTextAlign)(const ANPPaint*);
float (*getTextSize)(const ANPPaint*);
float (*getTextScaleX)(const ANPPaint*);
float (*getTextSkewX)(const ANPPaint*);
void (*setTextEncoding)(ANPPaint*, ANPTextEncoding);
void (*setTextAlign)(ANPPaint*, ANPPaintAlign);
void (*setTextSize)(ANPPaint*, float);
void (*setTextScaleX)(ANPPaint*, float);
void (*setTextSkewX)(ANPPaint*, float);
/** Return the typeface ine paint, or null if there is none. This does not
modify the owner count of the returned typeface.
*/
ANPTypeface* (*getTypeface)(const ANPPaint*);
/** Set the paint's typeface. If the paint already had a non-null typeface,
its owner count is decremented. If the new typeface is non-null, its
owner count is incremented.
*/
void (*setTypeface)(ANPPaint*, ANPTypeface*);
/** Return the width of the text. If bounds is not null, return the bounds
of the text in that rectangle.
*/
float (*measureText)(ANPPaint*, const void* text, uint32_t byteLength,
ANPRectF* bounds);
/** Return the number of unichars specifed by the text.
If widths is not null, returns the array of advance widths for each
unichar.
If bounds is not null, returns the array of bounds for each unichar.
*/
int (*getTextWidths)(ANPPaint*, const void* text, uint32_t byteLength,
float widths[], ANPRectF bounds[]);
/** Return in metrics the spacing values for text, respecting the paint's
typeface and pointsize, and return the spacing between lines
(descent - ascent + leading). If metrics is NULL, it will be ignored.
*/
float (*getFontMetrics)(ANPPaint*, ANPFontMetrics* metrics);
};
struct ANPCanvasInterfaceV0 : ANPInterface {
/** Return a canvas that will draw into the specified bitmap. Note: the
canvas copies the fields of the bitmap, so it need not persist after
this call, but the canvas DOES point to the same pixel memory that the
bitmap did, so the canvas should not be used after that pixel memory
goes out of scope. In the case of creating a canvas to draw into the
pixels provided by kDraw_ANPEventType, those pixels are only while
handling that event.
The canvas that is returned is not tied to any particular plugin
instance, but it must only be accessed from one thread at a time.
*/
ANPCanvas* (*newCanvas)(const ANPBitmap*);
void (*deleteCanvas)(ANPCanvas*);
void (*save)(ANPCanvas*);
void (*restore)(ANPCanvas*);
void (*translate)(ANPCanvas*, float tx, float ty);
void (*scale)(ANPCanvas*, float sx, float sy);
void (*rotate)(ANPCanvas*, float degrees);
void (*skew)(ANPCanvas*, float kx, float ky);
void (*concat)(ANPCanvas*, const ANPMatrix*);
void (*clipRect)(ANPCanvas*, const ANPRectF*);
void (*clipPath)(ANPCanvas*, const ANPPath*);
/** Return the current matrix on the canvas
*/
void (*getTotalMatrix)(ANPCanvas*, ANPMatrix*);
/** Return the current clip bounds in local coordinates, expanding it to
account for antialiasing edge effects if aa is true. If the
current clip is empty, return false and ignore the bounds argument.
*/
bool (*getLocalClipBounds)(ANPCanvas*, ANPRectF* bounds, bool aa);
/** Return the current clip bounds in device coordinates in bounds. If the
current clip is empty, return false and ignore the bounds argument.
*/
bool (*getDeviceClipBounds)(ANPCanvas*, ANPRectI* bounds);
void (*drawColor)(ANPCanvas*, ANPColor);
void (*drawPaint)(ANPCanvas*, const ANPPaint*);
void (*drawLine)(ANPCanvas*, float x0, float y0, float x1, float y1,
const ANPPaint*);
void (*drawRect)(ANPCanvas*, const ANPRectF*, const ANPPaint*);
void (*drawOval)(ANPCanvas*, const ANPRectF*, const ANPPaint*);
void (*drawPath)(ANPCanvas*, const ANPPath*, const ANPPaint*);
void (*drawText)(ANPCanvas*, const void* text, uint32_t byteLength,
float x, float y, const ANPPaint*);
void (*drawPosText)(ANPCanvas*, const void* text, uint32_t byteLength,
const float xy[], const ANPPaint*);
void (*drawBitmap)(ANPCanvas*, const ANPBitmap*, float x, float y,
const ANPPaint*);
void (*drawBitmapRect)(ANPCanvas*, const ANPBitmap*,
const ANPRectI* src, const ANPRectF* dst,
const ANPPaint*);
};
struct ANPWindowInterfaceV0 : ANPInterface {
/** Registers a set of rectangles that the plugin would like to keep on
screen. The rectangles are listed in order of priority with the highest
priority rectangle in location rects[0]. The browser will attempt to keep
as many of the rectangles on screen as possible and will scroll them into
view in response to the invocation of this method and other various events.
The count specifies how many rectangles are in the array. If the count is
zero it signals the browser that any existing rectangles should be cleared
and no rectangles will be tracked.
*/
void (*setVisibleRects)(NPP instance, const ANPRectI rects[], int32_t count);
/** Clears any rectangles that are being tracked as a result of a call to
setVisibleRects. This call is equivalent to setVisibleRect(inst, NULL, 0).
*/
void (*clearVisibleRects)(NPP instance);
/** Given a boolean value of true the device will be requested to provide
a keyboard. A value of false will result in a request to hide the
keyboard. Further, the on-screen keyboard will not be displayed if a
physical keyboard is active.
*/
void (*showKeyboard)(NPP instance, bool value);
/** Called when a plugin wishes to enter into full screen mode. The plugin's
Java class (defined in the plugin's apk manifest) will be called
asynchronously to provide a View object to be displayed full screen.
*/
void (*requestFullScreen)(NPP instance);
/** Called when a plugin wishes to exit from full screen mode. As a result,
the plugin's full screen view will be discarded by the view system.
*/
void (*exitFullScreen)(NPP instance);
/** Called when a plugin wishes to be zoomed and centered in the current view.
*/
void (*requestCenterFitZoom)(NPP instance);
};
///////////////////////////////////////////////////////////////////////////////
enum ANPSampleFormats {
kUnknown_ANPSamleFormat = 0,
kPCM16Bit_ANPSampleFormat = 1,
kPCM8Bit_ANPSampleFormat = 2
};
typedef int32_t ANPSampleFormat;
/** The audio buffer is passed to the callback proc to request more samples.
It is owned by the system, and the callback may read it, but should not
maintain a pointer to it outside of the scope of the callback proc.
*/
struct ANPAudioBuffer {
// RO - repeat what was specified in newTrack()
int32_t channelCount;
// RO - repeat what was specified in newTrack()
ANPSampleFormat format;
/** This buffer is owned by the caller. Inside the callback proc, up to
"size" bytes of sample data should be written into this buffer. The
address is only valid for the scope of a single invocation of the
callback proc.
*/
void* bufferData;
/** On input, specifies the maximum number of bytes that can be written
to "bufferData". On output, specifies the actual number of bytes that
the callback proc wrote into "bufferData".
*/
uint32_t size;
};
enum ANPAudioEvents {
/** This event is passed to the callback proc when the audio-track needs
more sample data written to the provided buffer parameter.
*/
kMoreData_ANPAudioEvent = 0,
/** This event is passed to the callback proc if the audio system runs out
of sample data. In this event, no buffer parameter will be specified
(i.e. NULL will be passed to the 3rd parameter).
*/
kUnderRun_ANPAudioEvent = 1
};
typedef int32_t ANPAudioEvent;
/** Called to feed sample data to the track. This will be called in a separate
thread. However, you may call trackStop() from the callback (but you
cannot delete the track).
For example, when you have written the last chunk of sample data, you can
immediately call trackStop(). This will take effect after the current
buffer has been played.
The "user" parameter is the same value that was passed to newTrack()
*/
typedef void (*ANPAudioCallbackProc)(ANPAudioEvent event, void* user,
ANPAudioBuffer* buffer);
struct ANPAudioTrack; // abstract type for audio tracks
struct ANPAudioTrackInterfaceV0 : ANPInterface {
/** Create a new audio track, or NULL on failure. The track is initially in
the stopped state and therefore ANPAudioCallbackProc will not be called
until the track is started.
*/
ANPAudioTrack* (*newTrack)(uint32_t sampleRate, // sampling rate in Hz
ANPSampleFormat,
int channelCount, // MONO=1, STEREO=2
ANPAudioCallbackProc,
void* user);
/** Deletes a track that was created using newTrack. The track can be
deleted in any state and it waits for the ANPAudioCallbackProc thread
to exit before returning.
*/
void (*deleteTrack)(ANPAudioTrack*);
void (*start)(ANPAudioTrack*);
void (*pause)(ANPAudioTrack*);
void (*stop)(ANPAudioTrack*);
/** Returns true if the track is not playing (e.g. pause or stop was called,
or start was never called.
*/
bool (*isStopped)(ANPAudioTrack*);
};
///////////////////////////////////////////////////////////////////////////////
// DEFINITION OF VALUES PASSED THROUGH NPP_HandleEvent
enum ANPEventTypes {
kNull_ANPEventType = 0,
kKey_ANPEventType = 1,
/** Mouse events are triggered by either clicking with the navigational pad
or by tapping the touchscreen (if the kDown_ANPTouchAction is handled by
the plugin then no mouse event is generated). The kKey_ANPEventFlag has
to be set to true in order to receive these events.
*/
kMouse_ANPEventType = 2,
/** Touch events are generated when the user touches on the screen. The
kTouch_ANPEventFlag has to be set to true in order to receive these
events.
*/
kTouch_ANPEventType = 3,
/** Only triggered by a plugin using the kBitmap_ANPDrawingModel. This event
signals that the plugin needs to redraw itself into the provided bitmap.
*/
kDraw_ANPEventType = 4,
kLifecycle_ANPEventType = 5,
/** This event type is completely defined by the plugin.
When creating an event, the caller must always set the first
two fields, the remaining data is optional.
ANPEvent evt;
evt.inSize = sizeof(ANPEvent);
evt.eventType = kCustom_ANPEventType
// other data slots are optional
evt.other[] = ...;
To post a copy of the event, call
eventInterface->postEvent(myNPPInstance, &evt);
That call makes a copy of the event struct, and post that on the event
queue for the plugin.
*/
kCustom_ANPEventType = 6,
};
typedef int32_t ANPEventType;
enum ANPKeyActions {
kDown_ANPKeyAction = 0,
kUp_ANPKeyAction = 1,
};
typedef int32_t ANPKeyAction;
#include "ANPKeyCodes.h"
typedef int32_t ANPKeyCode;
enum ANPKeyModifiers {
kAlt_ANPKeyModifier = 1 << 0,
kShift_ANPKeyModifier = 1 << 1,
};
// bit-field containing some number of ANPKeyModifier bits
typedef uint32_t ANPKeyModifier;
enum ANPMouseActions {
kDown_ANPMouseAction = 0,
kUp_ANPMouseAction = 1,
};
typedef int32_t ANPMouseAction;
enum ANPTouchActions {
/** This occurs when the user first touches on the screen. As such, this
action will always occur prior to any of the other touch actions. If
the plugin chooses to not handle this action then no other events
related to that particular touch gesture will be generated.
*/
kDown_ANPTouchAction = 0,
kUp_ANPTouchAction = 1,
kMove_ANPTouchAction = 2,
kCancel_ANPTouchAction = 3,
// The web view will ignore the return value from the following actions
kLongPress_ANPTouchAction = 4,
kDoubleTap_ANPTouchAction = 5,
};
typedef int32_t ANPTouchAction;
enum ANPLifecycleActions {
/** The web view containing this plugin has been paused. See documentation
on the android activity lifecycle for more information.
*/
kPause_ANPLifecycleAction = 0,
/** The web view containing this plugin has been resumed. See documentation
on the android activity lifecycle for more information.
*/
kResume_ANPLifecycleAction = 1,
/** The plugin has focus and is now the recipient of input events (e.g. key,
touch, etc.)
*/
kGainFocus_ANPLifecycleAction = 2,
/** The plugin has lost focus and will not receive any input events until it
regains focus. This event is always preceded by a GainFocus action.
*/
kLoseFocus_ANPLifecycleAction = 3,
/** The browser is running low on available memory and is requesting that
the plugin free any unused/inactive resources to prevent a performance
degradation.
*/
kFreeMemory_ANPLifecycleAction = 4,
/** The page has finished loading. This happens when the page's top level
frame reports that it has completed loading.
*/
kOnLoad_ANPLifecycleAction = 5,
/** The browser is honoring the plugin's request to go full screen. Upon
returning from this event the browser will resize the plugin's java
surface to full-screen coordinates.
*/
kEnterFullScreen_ANPLifecycleAction = 6,
/** The browser has exited from full screen mode. Immediately prior to
sending this event the browser has resized the plugin's java surface to
its original coordinates.
*/
kExitFullScreen_ANPLifecycleAction = 7,
/** The plugin is visible to the user on the screen. This event will always
occur after a kOffScreen_ANPLifecycleAction event.
*/
kOnScreen_ANPLifecycleAction = 8,
/** The plugin is no longer visible to the user on the screen. This event
will always occur prior to an kOnScreen_ANPLifecycleAction event.
*/
kOffScreen_ANPLifecycleAction = 9,
};
typedef uint32_t ANPLifecycleAction;
/* This is what is passed to NPP_HandleEvent() */
struct ANPEvent {
uint32_t inSize; // size of this struct in bytes
ANPEventType eventType;
// use based on the value in eventType
union {
struct {
ANPKeyAction action;
ANPKeyCode nativeCode;
int32_t virtualCode; // windows virtual key code
ANPKeyModifier modifiers;
int32_t repeatCount; // 0 for initial down (or up)
int32_t unichar; // 0 if there is no value
} key;
struct {
ANPMouseAction action;
int32_t x; // relative to your "window" (0...width)
int32_t y; // relative to your "window" (0...height)
} mouse;
struct {
ANPTouchAction action;
ANPKeyModifier modifiers;
int32_t x; // relative to your "window" (0...width)
int32_t y; // relative to your "window" (0...height)
} touch;
struct {
ANPLifecycleAction action;
} lifecycle;
struct {
ANPDrawingModel model;
// relative to (0,0) in top-left of your plugin
ANPRectI clip;
// use based on the value in model
union {
ANPBitmap bitmap;
} data;
} draw;
int32_t other[8];
} data;
};
struct ANPEventInterfaceV0 : ANPInterface {
/** Post a copy of the specified event to the plugin. The event will be
delivered to the plugin in its main thread (the thread that receives
other ANPEvents). If, after posting before delivery, the NPP instance
is torn down, the event will be discarded.
*/
void (*postEvent)(NPP inst, const ANPEvent* event);
};
struct ANPSystemInterfaceV0 : ANPInterface {
/** Return the path name for the current Application's plugin data directory,
or NULL if not supported
*/
const char* (*getApplicationDataDirectory)();
/** A helper function to load java classes from the plugin's apk. The
function looks for a class given the fully qualified and null terminated
string representing the className. For example,
const char* className = "com.android.mypackage.MyClass";
If the class cannot be found or there is a problem loading the class
NULL will be returned.
*/
jclass (*loadJavaClass)(NPP instance, const char* className);
};
struct ANPSurfaceInterfaceV0 : ANPInterface {
/** Locks the surface from manipulation by other threads and provides a bitmap
to be written to. The dirtyRect param specifies which portion of the
bitmap will be written to. If the dirtyRect is NULL then the entire
surface will be considered dirty. If the lock was successful the function
will return true and the bitmap will be set to point to a valid bitmap.
If not the function will return false and the bitmap will be set to NULL.
*/
bool (*lock)(JNIEnv* env, jobject surface, ANPBitmap* bitmap, ANPRectI* dirtyRect);
/** Given a locked surface handle (i.e. result of a successful call to lock)
the surface is unlocked and the contents of the bitmap, specifically
those inside the dirtyRect are written to the screen.
*/
void (*unlock)(JNIEnv* env, jobject surface);
};
typedef int32_t int32;
typedef uint32_t uint32;
typedef int16_t int16;
typedef uint16_t uint16;
#endif

Просмотреть файл

Просмотреть файл

@ -48,6 +48,10 @@
#include "npapi.h"
#include "npruntime.h"
#ifdef ANDROID
#include <jni.h>
#endif
typedef NPError (* NP_LOADDS NPP_NewProcPtr)(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved);
typedef NPError (* NP_LOADDS NPP_DestroyProcPtr)(NPP instance, NPSavedData** save);
typedef NPError (* NP_LOADDS NPP_SetWindowProcPtr)(NPP instance, NPWindow* window);
@ -307,9 +311,14 @@ NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs);
typedef NPError (*NP_GetEntryPointsFunc)(NPPluginFuncs*);
NP_EXPORT(NPError) NP_GetEntryPoints(NPPluginFuncs* pFuncs);
#else
#ifdef ANDROID
typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*, NPPluginFuncs*, JNIEnv* pEnv);
NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, JNIEnv* pEnv);
#else
typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*, NPPluginFuncs*);
NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs);
#endif
#endif
typedef NPError (*NP_ShutdownFunc)(void);
NP_EXPORT(NPError) NP_Shutdown(void);
typedef NPError (*NP_GetValueFunc)(void *, NPPVariable, void *);

Просмотреть файл

@ -127,6 +127,13 @@ using mozilla::plugins::PluginModuleParent;
#include <windows.h>
#endif
#ifdef ANDROID
#include "ANPBase.h"
#include "AndroidBridge.h"
#include <android/log.h>
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
#endif
using namespace mozilla;
using namespace mozilla::plugins::parent;
@ -477,7 +484,7 @@ nsNPAPIPlugin::CreatePlugin(nsPluginTag *aPluginTag, nsNPAPIPlugin** aResult)
return NS_ERROR_FAILURE;
}
#ifdef XP_MACOSX
#if defined(XP_MACOSX) || defined(ANDROID)
if (!pluginLib->HasRequiredFunctions()) {
NS_WARNING("Not all necessary functions exposed by plugin, it will not load.");
return NS_ERROR_FAILURE;
@ -2264,6 +2271,112 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
}
#endif
#ifdef ANDROID
case kLogInterfaceV0_ANPGetValue: {
LOG("get log interface");
ANPLogInterfaceV0 *i = (ANPLogInterfaceV0 *) result;
InitLogInterface(i);
return NPERR_NO_ERROR;
}
case kBitmapInterfaceV0_ANPGetValue: {
LOG("get bitmap interface");
ANPBitmapInterfaceV0 *i = (ANPBitmapInterfaceV0 *) result;
InitBitmapInterface(i);
return NPERR_NO_ERROR;
}
case kMatrixInterfaceV0_ANPGetValue: {
LOG("get matrix interface");
ANPMatrixInterfaceV0 *i = (ANPMatrixInterfaceV0 *) result;
InitMatrixInterface(i);
return NPERR_NO_ERROR;
}
case kPathInterfaceV0_ANPGetValue: {
LOG("get path interface");
ANPPathInterfaceV0 *i = (ANPPathInterfaceV0 *) result;
InitPathInterface(i);
return NPERR_NO_ERROR;
}
case kTypefaceInterfaceV0_ANPGetValue: {
LOG("get typeface interface");
ANPTypefaceInterfaceV0 *i = (ANPTypefaceInterfaceV0 *) result;
InitTypeFaceInterface(i);
return NPERR_NO_ERROR;
}
case kPaintInterfaceV0_ANPGetValue: {
LOG("get paint interface");
ANPPaintInterfaceV0 *i = (ANPPaintInterfaceV0 *) result;
InitPaintInterface(i);
return NPERR_NO_ERROR;
}
case kCanvasInterfaceV0_ANPGetValue: {
LOG("get canvas interface");
ANPCanvasInterfaceV0 *i = (ANPCanvasInterfaceV0 *) result;
InitCanvasInterface(i);
return NPERR_NO_ERROR;
}
case kWindowInterfaceV0_ANPGetValue: {
LOG("get window interface");
ANPWindowInterfaceV0 *i = (ANPWindowInterfaceV0 *) result;
InitWindowInterface(i);
return NPERR_NO_ERROR;
}
case kAudioTrackInterfaceV0_ANPGetValue: {
LOG("get audio interface");
ANPAudioTrackInterfaceV0 *i = (ANPAudioTrackInterfaceV0 *) result;
InitAudioTrackInterface(i);
return NPERR_NO_ERROR;
}
case kEventInterfaceV0_ANPGetValue: {
LOG("get event interface");
ANPEventInterfaceV0 *i = (ANPEventInterfaceV0 *) result;
InitEventInterface(i);
return NPERR_NO_ERROR;
}
case kSystemInterfaceV0_ANPGetValue: {
LOG("get system interface");
ANPSystemInterfaceV0* i = reinterpret_cast<ANPSystemInterfaceV0*>(result);
InitSystemInterface(i);
LOG("done system interface");
return NPERR_NO_ERROR;
}
case kSurfaceInterfaceV0_ANPGetValue: {
LOG("get surface interface");
ANPSurfaceInterfaceV0 *i = (ANPSurfaceInterfaceV0 *) result;
InitSurfaceInterface(i);
return NPERR_NO_ERROR;
}
case kSupportedDrawingModel_ANPGetValue: {
LOG("get supported drawing model");
uint32_t* bits = reinterpret_cast<uint32_t*>(result);
*bits = kBitmap_ANPDrawingModel && kSurface_ANPDrawingModel;
return NPERR_NO_ERROR;
}
case kJavaContext_ANPGetValue: {
LOG("get context");
JNIEnv* env = GetJNIForThread();
jclass cls = env->FindClass("org/mozilla/gecko/GeckoApp");
jfieldID field = env->GetStaticFieldID(cls, "mAppContext",
"Lorg/mozilla/gecko/GeckoApp;");
jobject ret = env->GetStaticObjectField(cls, field);
int32_t* i = reinterpret_cast<int32_t*>(result);
*i = reinterpret_cast<int32_t>(ret);
return NPERR_NO_ERROR;
}
#endif
// we no longer hand out any XPCOM objects
case NPNVDOMElement:
// fall through
@ -2275,6 +2388,7 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
*(nsISupports**)result = nsnull;
// fall through
default:
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_getvalue unhandled get value: %d\n", variable));
return NPERR_GENERIC_ERROR;
}
}
@ -2374,7 +2488,14 @@ _setvalue(NPP npp, NPPVariable variable, void *result)
}
}
#endif
#ifdef ANDROID
case kRequestDrawingModel_ANPSetValue:
if (inst)
inst->SetDrawingModel(NS_PTR_TO_INT32(result));
return NPERR_NO_ERROR;
case kAcceptEvents_ANPSetValue:
return NPERR_NO_ERROR;
#endif
default:
return NPERR_GENERIC_ERROR;
}

Просмотреть файл

@ -61,13 +61,22 @@
#include "nsNetCID.h"
#include "nsIContent.h"
#ifdef ANDROID
#include "ANPBase.h"
#include <android/log.h>
#include "android_npapi.h"
#include "mozilla/Mutex.h"
#include "mozilla/CondVar.h"
#include "AndroidBridge.h"
#endif
using namespace mozilla;
using namespace mozilla::plugins::parent;
static NS_DEFINE_IID(kIOutputStreamIID, NS_IOUTPUTSTREAM_IID);
static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID);
NS_IMPL_ISUPPORTS0(nsNPAPIPluginInstance)
NS_IMPL_THREADSAFE_ISUPPORTS0(nsNPAPIPluginInstance)
nsNPAPIPluginInstance::nsNPAPIPluginInstance(nsNPAPIPlugin* plugin)
:
@ -77,6 +86,10 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance(nsNPAPIPlugin* plugin)
#else
mDrawingModel(NPDrawingModelQuickDraw),
#endif
#endif
#ifdef ANDROID
mSurface(nsnull),
mDrawingModel(0),
#endif
mRunning(NOT_STARTED),
mWindowless(PR_FALSE),
@ -684,7 +697,7 @@ nsNPAPIPluginInstance::UsesDOMForCursor()
return mUsesDOMForCursor;
}
#ifdef XP_MACOSX
#if defined(XP_MACOSX)
void nsNPAPIPluginInstance::SetDrawingModel(NPDrawingModel aModel)
{
mDrawingModel = aModel;
@ -702,12 +715,69 @@ void nsNPAPIPluginInstance::SetEventModel(NPEventModel aModel)
owner->SetEventModel(aModel);
}
#endif
#if defined(ANDROID)
void nsNPAPIPluginInstance::SetDrawingModel(PRUint32 aModel)
{
mDrawingModel = aModel;
}
class SurfaceGetter : public nsRunnable {
public:
SurfaceGetter(NPPluginFuncs* aPluginFunctions, NPP_t aNPP) :
mHaveSurface(PR_FALSE), mPluginFunctions(aPluginFunctions), mNPP(aNPP) {
mLock = new Mutex("SurfaceGetter::Lock");
mCondVar = new CondVar(*mLock, "SurfaceGetter::CondVar");
}
~SurfaceGetter() {
delete mLock;
delete mCondVar;
}
nsresult Run() {
MutexAutoLock lock(*mLock);
(*mPluginFunctions->getvalue)(&mNPP, kJavaSurface_ANPGetValue, &mSurface);
mHaveSurface = PR_TRUE;
mCondVar->Notify();
return NS_OK;
}
void* GetSurface() {
MutexAutoLock lock(*mLock);
mHaveSurface = PR_FALSE;
AndroidBridge::Bridge()->PostToJavaThread(this);
while (!mHaveSurface)
mCondVar->Wait();
return mSurface;
}
private:
NPP_t mNPP;
void* mSurface;
Mutex* mLock;
CondVar* mCondVar;
PRBool mHaveSurface;
NPPluginFuncs* mPluginFunctions;
};
void* nsNPAPIPluginInstance::GetJavaSurface()
{
if (mDrawingModel != kSurface_ANPDrawingModel)
return nsnull;
if (mSurface)
return mSurface;
nsCOMPtr<SurfaceGetter> sg = new SurfaceGetter(mPlugin->PluginFuncs(), mNPP);
mSurface = sg->GetSurface();
return mSurface;
}
#endif
nsresult nsNPAPIPluginInstance::GetDrawingModel(PRInt32* aModel)
{
#ifdef XP_MACOSX
#if defined(XP_MACOSX) || defined(ANDROID)
*aModel = (PRInt32)mDrawingModel;
return NS_OK;
#else
@ -806,7 +876,12 @@ nsNPAPIPluginInstance::DefineJavaProperties()
nsresult
nsNPAPIPluginInstance::IsWindowless(PRBool* isWindowless)
{
#ifdef ANDROID
// On android, pre-honeycomb, all plugins are treated as windowless.
*isWindowless = PR_TRUE;
#else
*isWindowless = mWindowless;
#endif
return NS_OK;
}
@ -1066,6 +1141,28 @@ nsNPAPIPluginInstance::PrivateModeStateChanged()
return NS_ERROR_FAILURE;
}
class DelayUnscheduleEvent : public nsRunnable {
public:
nsRefPtr<nsNPAPIPluginInstance> mInstance;
uint32_t mTimerID;
DelayUnscheduleEvent(nsNPAPIPluginInstance* aInstance, uint32_t aTimerId)
: mInstance(aInstance)
, mTimerID(aTimerId)
{}
~DelayUnscheduleEvent() {}
NS_IMETHOD Run();
};
NS_IMETHODIMP
DelayUnscheduleEvent::Run()
{
mInstance->UnscheduleTimer(mTimerID);
return NS_OK;
}
static void
PluginTimerCallback(nsITimer *aTimer, void *aClosure)
{
@ -1073,7 +1170,11 @@ PluginTimerCallback(nsITimer *aTimer, void *aClosure)
NPP npp = t->npp;
uint32_t id = t->id;
// Some plugins (Flash on Android) calls unscheduletimer
// from this callback.
t->inCallback = PR_TRUE;
(*(t->callback))(npp, id);
t->inCallback = PR_FALSE;
// Make sure we still have an instance and the timer is still alive
// after the callback.
@ -1107,6 +1208,7 @@ nsNPAPIPluginInstance::ScheduleTimer(uint32_t interval, NPBool repeat, void (*ti
{
nsNPAPITimer *newTimer = new nsNPAPITimer();
newTimer->inCallback = PR_FALSE;
newTimer->npp = &mNPP;
// generate ID that is unique to this instance
@ -1144,6 +1246,12 @@ nsNPAPIPluginInstance::UnscheduleTimer(uint32_t timerID)
if (!t)
return;
if (t->inCallback) {
nsCOMPtr<nsIRunnable> e = new DelayUnscheduleEvent(this, timerID);
NS_DispatchToCurrentThread(e);
return;
}
// cancel the timer
t->timer->Cancel();

Просмотреть файл

@ -68,6 +68,7 @@ public:
uint32_t id;
nsCOMPtr<nsITimer> timer;
void (*callback)(NPP npp, uint32_t timerID);
PRBool inCallback;
};
class nsNPAPIPluginInstance : public nsISupports
@ -85,6 +86,9 @@ public:
nsresult NewStreamToPlugin(nsIPluginStreamListener** listener);
nsresult NewStreamFromPlugin(const char* type, const char* target, nsIOutputStream* *result);
nsresult Print(NPPrint* platformPrint);
#ifdef ANDROID
nsresult PostEvent(void* event) { return 0; };
#endif
nsresult HandleEvent(void* event, PRInt16* result);
nsresult GetValueFromPlugin(NPPVariable variable, void* value);
nsresult GetDrawingModel(PRInt32* aModel);
@ -141,6 +145,11 @@ public:
void SetEventModel(NPEventModel aModel);
#endif
#ifdef ANDROID
void SetDrawingModel(PRUint32 aModel);
void* GetJavaSurface();
#endif
nsresult NewStreamListener(const char* aURL, void* notifyData,
nsIPluginStreamListener** listener);
@ -207,6 +216,10 @@ protected:
NPDrawingModel mDrawingModel;
#endif
#ifdef ANDROID
PRUint32 mDrawingModel;
#endif
enum {
NOT_STARTED,
RUNNING,
@ -250,6 +263,9 @@ private:
nsCOMPtr<nsIURI> mURI;
PRPackedBool mUsePluginLayersPref;
#ifdef ANDROID
void* mSurface;
#endif
};
#endif // nsNPAPIPluginInstance_h_

Просмотреть файл

@ -159,6 +159,11 @@
#include "winbase.h"
#endif
#ifdef ANDROID
#include <android/log.h>
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
#endif
using namespace mozilla;
using mozilla::TimeStamp;
@ -2324,6 +2329,10 @@ nsresult nsPluginHost::FindPlugins(PRBool aCreatePluginList, PRBool * aPluginsCh
NS_ITERATIVE_UNREF_LIST(nsRefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
return NS_OK;
}
} else {
#ifdef ANDROID
LOG("getting plugins dir failed");
#endif
}
mPluginsLoaded = PR_TRUE; // at this point 'some' plugins have been loaded,

Просмотреть файл

@ -118,6 +118,16 @@ static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
#include "gfxXlibNativeRenderer.h"
#endif
#ifdef ANDROID
#include "ANPBase.h"
#include "android_npapi.h"
#include "AndroidBridge.h"
using namespace mozilla::dom;
#include <android/log.h>
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
#endif
using namespace mozilla;
// special class for handeling DOM context menu events because for
@ -1255,7 +1265,12 @@ nsresult nsPluginInstanceOwner::EnsureCachedAttrParamArrays()
// Add PARAM and null separator.
mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(NS_LITERAL_STRING("PARAM"));
#ifdef ANDROID
// Flash expects an empty string on android
mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(NS_LITERAL_STRING(""));
#else
mCachedAttrParamValues[nextAttrParamIndex] = nsnull;
#endif
nextAttrParamIndex++;
// Add PARAM name/value pairs.
@ -1640,8 +1655,48 @@ void nsPluginInstanceOwner::ScrollPositionDidChange(nscoord aX, nscoord aY)
#endif
}
#ifdef ANDROID
void nsPluginInstanceOwner::RemovePluginView()
{
if (mInstance && mObjectFrame) {
void* surface = mInstance->GetJavaSurface();
if (surface) {
JNIEnv* env = GetJNIForThread();
if (env) {
jclass cls = env->FindClass("org/mozilla/gecko/GeckoAppShell");
jmethodID method = env->GetStaticMethodID(cls,
"removePluginView",
"(Landroid/view/View;)V");
env->CallStaticVoidMethod(cls, method, surface);
}
}
}
}
#endif
nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent)
{
#ifdef ANDROID
{
ANPEvent event;
event.inSize = sizeof(ANPEvent);
event.eventType = kLifecycle_ANPEventType;
nsAutoString eventType;
aFocusEvent->GetType(eventType);
if (eventType.EqualsLiteral("focus")) {
event.data.lifecycle.action = kGainFocus_ANPLifecycleAction;
}
else if (eventType.EqualsLiteral("blur")) {
event.data.lifecycle.action = kLoseFocus_ANPLifecycleAction;
}
else {
NS_ASSERTION(PR_FALSE, "nsPluginInstanceOwner::DispatchFocusToPlugin, wierd eventType");
}
mInstance->HandleEvent(&event, nsnull);
}
#endif
#ifndef XP_MACOSX
if (!mPluginWindow || (mPluginWindow->type == NPWindowTypeWindow)) {
// continue only for cases without child window
@ -1912,8 +1967,6 @@ static unsigned int XInputEventState(const nsInputEvent& anEvent)
nsEventStatus nsPluginInstanceOwner::ProcessEvent(const nsGUIEvent& anEvent)
{
// printf("nsGUIEvent.message: %d\n", anEvent.message);
nsEventStatus rv = nsEventStatus_eIgnore;
if (!mInstance || !mObjectFrame) // if mInstance is null, we shouldn't be here
@ -2436,6 +2489,107 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const nsGUIEvent& anEvent)
rv = nsEventStatus_eConsumeNoDefault;
#endif
#ifdef ANDROID
// this code supports windowless plugins
{
// The plugin needs focus to receive keyboard and touch events
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
if (fm) {
nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(mContent);
fm->SetFocus(elem, 0);
}
}
switch(anEvent.eventStructType)
{
case NS_MOUSE_EVENT:
{
switch (anEvent.message)
{
case NS_MOUSE_CLICK:
case NS_MOUSE_DOUBLECLICK:
// Button up/down events sent instead.
return rv;
}
// Get reference point relative to plugin origin.
const nsPresContext* presContext = mObjectFrame->PresContext();
nsPoint appPoint =
nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mObjectFrame) -
mObjectFrame->GetContentRectRelativeToSelf().TopLeft();
nsIntPoint pluginPoint(presContext->AppUnitsToDevPixels(appPoint.x),
presContext->AppUnitsToDevPixels(appPoint.y));
switch (anEvent.message)
{
case NS_MOUSE_MOVE:
{
// are these going to be touch events?
// pluginPoint.x;
// pluginPoint.y;
}
break;
case NS_MOUSE_BUTTON_DOWN:
{
ANPEvent event;
event.inSize = sizeof(ANPEvent);
event.eventType = kMouse_ANPEventType;
event.data.mouse.action = kDown_ANPMouseAction;
event.data.mouse.x = pluginPoint.x;
event.data.mouse.y = pluginPoint.y;
mInstance->HandleEvent(&event, nsnull);
}
break;
case NS_MOUSE_BUTTON_UP:
{
ANPEvent event;
event.inSize = sizeof(ANPEvent);
event.eventType = kMouse_ANPEventType;
event.data.mouse.action = kUp_ANPMouseAction;
event.data.mouse.x = pluginPoint.x;
event.data.mouse.y = pluginPoint.y;
mInstance->HandleEvent(&event, nsnull);
}
break;
}
}
break;
case NS_KEY_EVENT:
{
const nsKeyEvent& keyEvent = static_cast<const nsKeyEvent&>(anEvent);
LOG("Firing NS_KEY_EVENT %d %d\n", keyEvent.keyCode, keyEvent.charCode);
int modifiers = 0;
if (keyEvent.isShift)
modifiers |= kShift_ANPKeyModifier;
if (keyEvent.isAlt)
modifiers |= kAlt_ANPKeyModifier;
ANPEvent event;
event.inSize = sizeof(ANPEvent);
event.eventType = kKey_ANPEventType;
event.data.key.nativeCode = keyEvent.keyCode;
event.data.key.virtualCode = keyEvent.charCode;
event.data.key.modifiers = modifiers;
event.data.key.repeatCount = 0;
event.data.key.unichar = 0;
switch (anEvent.message)
{
case NS_KEY_DOWN:
event.data.key.action = kDown_ANPKeyAction;
mInstance->HandleEvent(&event, nsnull);
break;
case NS_KEY_UP:
event.data.key.action = kUp_ANPKeyAction;
mInstance->HandleEvent(&event, nsnull);
break;
}
}
}
rv = nsEventStatus_eConsumeNoDefault;
#endif
return rv;
}
@ -2541,6 +2695,10 @@ nsPluginInstanceOwner::PrepareToStop(PRBool aDelayedStop)
}
#endif
#ifdef ANDROID
RemovePluginView();
#endif
// Unregister scroll position listeners
for (nsIFrame* f = mObjectFrame; f; f = nsLayoutUtils::GetCrossDocParentFrame(f)) {
nsIScrollableFrame* sf = do_QueryFrame(f);
@ -2637,6 +2795,138 @@ void nsPluginInstanceOwner::Paint(const nsRect& aDirtyRect, HPS aHPS)
}
#endif
#ifdef ANDROID
class AndroidPaintEventRunnable : public nsRunnable
{
public:
AndroidPaintEventRunnable(void* aSurface, nsNPAPIPluginInstance* inst, const gfxRect& aFrameRect)
: mSurface(aSurface), mInstance(inst), mFrameRect(aFrameRect) {
}
~AndroidPaintEventRunnable() {
}
NS_IMETHOD Run()
{
LOG("%p - AndroidPaintEventRunnable::Run\n", this);
if (!mInstance || !mSurface)
return NS_OK;
// This needs to happen on the gecko main thread.
JNIEnv* env = GetJNIForThread();
jclass cls = env->FindClass("org/mozilla/gecko/GeckoAppShell");
jmethodID method = env->GetStaticMethodID(cls,
"addPluginView",
"(Landroid/view/View;DDDD)V");
env->CallStaticVoidMethod(cls,
method,
mSurface,
mFrameRect.x,
mFrameRect.y,
mFrameRect.width,
mFrameRect.height);
return NS_OK;
}
private:
void* mSurface;
nsCOMPtr<nsNPAPIPluginInstance> mInstance;
gfxRect mFrameRect;
};
void nsPluginInstanceOwner::Paint(gfxContext* aContext,
const gfxRect& aFrameRect,
const gfxRect& aDirtyRect)
{
if (!mInstance || !mObjectFrame)
return;
PRInt32 model;
mInstance->GetDrawingModel(&model);
if (model == kSurface_ANPDrawingModel) {
{
ANPEvent event;
event.inSize = sizeof(ANPEvent);
event.eventType = kLifecycle_ANPEventType;
event.data.lifecycle.action = kOnScreen_ANPLifecycleAction;
mInstance->HandleEvent(&event, nsnull);
}
/*
gfxMatrix currentMatrix = aContext->CurrentMatrix();
gfxSize scale = currentMatrix.ScaleFactors(PR_TRUE);
printf_stderr("!!!!!!!! scale!!: %f x %f\n", scale.width, scale.height);
*/
JNIEnv* env = GetJNIForThread();
jclass cls = env->FindClass("org/mozilla/gecko/GeckoAppShell");
jmethodID method = env->GetStaticMethodID(cls,
"addPluginView",
"(Landroid/view/View;DDDD)V");
env->CallStaticVoidMethod(cls,
method,
mInstance->GetJavaSurface(),
aFrameRect.x,
aFrameRect.y,
aFrameRect.width,
aFrameRect.height);
return;
}
if (model != kBitmap_ANPDrawingModel)
return;
#ifdef ANP_BITMAP_DRAWING_MODEL
static nsRefPtr<gfxImageSurface> pluginSurface;
if (pluginSurface == nsnull ||
aFrameRect.width != pluginSurface->Width() ||
aFrameRect.height != pluginSurface->Height()) {
pluginSurface = new gfxImageSurface(gfxIntSize(aFrameRect.width, aFrameRect.height),
gfxImageSurface::ImageFormatARGB32);
if (!pluginSurface)
return;
}
// Clears buffer. I think this is needed.
nsRefPtr<gfxContext> ctx = new gfxContext(pluginSurface);
ctx->SetOperator(gfxContext::OPERATOR_CLEAR);
ctx->Paint();
ANPEvent event;
event.inSize = sizeof(ANPEvent);
event.eventType = 4;
event.data.draw.model = 1;
event.data.draw.clip.top = 0;
event.data.draw.clip.left = 0;
event.data.draw.clip.bottom = aFrameRect.width;
event.data.draw.clip.right = aFrameRect.height;
event.data.draw.data.bitmap.format = kRGBA_8888_ANPBitmapFormat;
event.data.draw.data.bitmap.width = aFrameRect.width;
event.data.draw.data.bitmap.height = aFrameRect.height;
event.data.draw.data.bitmap.baseAddr = pluginSurface->Data();
event.data.draw.data.bitmap.rowBytes = aFrameRect.width * 4;
if (!mInstance)
return;
mInstance->HandleEvent(&event, nsnull);
aContext->SetOperator(gfxContext::OPERATOR_SOURCE);
aContext->SetSource(pluginSurface, gfxPoint(aFrameRect.x, aFrameRect.y));
aContext->Clip(aFrameRect);
aContext->Paint();
#endif
}
#endif
#if defined(MOZ_X11)
void nsPluginInstanceOwner::Paint(gfxContext* aContext,
const gfxRect& aFrameRect,
@ -3274,9 +3564,28 @@ void nsPluginInstanceOwner::UpdateWindowPositionAndClipRect(PRBool aSetWindow)
if (mPluginWindowVisible && mPluginDocumentActiveState) {
mPluginWindow->clipRect.right = mPluginWindow->width;
mPluginWindow->clipRect.bottom = mPluginWindow->height;
#ifdef ANDROID
if (mInstance) {
ANPEvent event;
event.inSize = sizeof(ANPEvent);
event.eventType = kLifecycle_ANPEventType;
event.data.lifecycle.action = kOnScreen_ANPLifecycleAction;
mInstance->HandleEvent(&event, nsnull);
}
#endif
} else {
mPluginWindow->clipRect.right = 0;
mPluginWindow->clipRect.bottom = 0;
#ifdef ANDROID
if (mInstance) {
ANPEvent event;
event.inSize = sizeof(ANPEvent);
event.eventType = kLifecycle_ANPEventType;
event.data.lifecycle.action = kOffScreen_ANPLifecycleAction;
mInstance->HandleEvent(&event, nsnull);
}
RemovePluginView();
#endif
}
if (!aSetWindow)

Просмотреть файл

@ -144,7 +144,7 @@ public:
void Paint(const gfxRect& aDirtyRect, CGContextRef cgContext);
void RenderCoreAnimation(CGContextRef aCGContext, int aWidth, int aHeight);
void DoCocoaEventDrawRect(const gfxRect& aDrawRect, CGContextRef cgContext);
#elif defined(MOZ_X11)
#elif defined(MOZ_X11) || defined(ANDROID)
void Paint(gfxContext* aContext,
const gfxRect& aFrameRect,
const gfxRect& aDirtyRect);
@ -308,6 +308,9 @@ private:
}
void FixUpURLS(const nsString &name, nsAString &value);
#ifdef ANDROID
void RemovePluginView();
#endif
nsPluginNativeWindow *mPluginWindow;
nsRefPtr<nsNPAPIPluginInstance> mInstance;

Просмотреть файл

@ -184,8 +184,7 @@ static PRBool ProcessFlashMessageDelayed(nsPluginNativeWindowWin * aWin, nsNPAPI
if (msg == sWM_FLASHBOUNCEMSG) {
// See PluginWindowEvent::Run() below.
NS_ASSERTION((sWM_FLASHBOUNCEMSG != 0), "RegisterWindowMessage failed in flash plugin WM_USER message handling!");
NS_TRY_SAFE_CALL_VOID(::CallWindowProc((WNDPROC)aWin->GetWindowProc(), hWnd, WM_USER_FLASH, wParam, lParam),
aInst);
::CallWindowProc((WNDPROC)aWin->GetWindowProc(), hWnd, WM_USER_FLASH, wParam, lParam);
return TRUE;
}
@ -577,12 +576,11 @@ NS_IMETHODIMP PluginWindowEvent::Run()
else {
// Currently not used, but added so that processing events here
// is more generic.
NS_TRY_SAFE_CALL_VOID(::CallWindowProc(win->GetWindowProc(),
::CallWindowProc(win->GetWindowProc(),
hWnd,
GetMsg(),
GetWParam(),
GetLParam()),
inst);
GetLParam());
}
Clear();

Просмотреть файл

@ -247,6 +247,16 @@ PRBool nsPluginsDir::IsPluginFile(nsIFile* file)
if (NS_FAILED(file->GetNativeLeafName(filename)))
return PR_FALSE;
#ifdef ANDROID
// It appears that if you load
// 'libstagefright_honeycomb.so' on froyo, or
// 'libstagefright_froyo.so' on honeycomb, we will abort.
// Since these are just helper libs, we can ignore.
const char *cFile = filename.get();
if (strstr(cFile, "libstagefright") != NULL)
return PR_FALSE;
#endif
NS_NAMED_LITERAL_CSTRING(dllSuffix, LOCAL_PLUGIN_DLL_SUFFIX);
if (filename.Length() > dllSuffix.Length() &&
StringEndsWith(filename, dllSuffix))

Просмотреть файл

@ -19,6 +19,13 @@
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
<uses-permission android:name="android.permission.READ_LOGS"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-feature android:name="android.hardware.location" android:required="false"/>
<uses-feature android:name="android.hardware.location.gps" android:required="false"/>
<uses-feature android:name="android.hardware.touchscreen"/>

Просмотреть файл

@ -45,6 +45,7 @@ import java.util.zip.*;
import java.nio.*;
import java.nio.channels.FileChannel;
import java.util.concurrent.*;
import java.lang.reflect.*;
import android.os.*;
import android.app.*;
@ -62,6 +63,9 @@ import android.net.*;
import android.database.*;
import android.provider.*;
import android.telephony.*;
import android.content.pm.*;
import android.content.pm.PackageManager.*;
import dalvik.system.*;
abstract public class GeckoApp
extends Activity
@ -74,7 +78,7 @@ abstract public class GeckoApp
public static final String ACTION_DEBUG = "org.mozilla.gecko.DEBUG";
public static final String ACTION_BOOKMARK = "org.mozilla.gecko.BOOKMARK";
public static FrameLayout mainLayout;
public static AbsoluteLayout mainLayout;
public static GeckoSurfaceView surfaceView;
public static GeckoApp mAppContext;
public static boolean mFullscreen = false;
@ -130,6 +134,151 @@ abstract public class GeckoApp
}).show();
}
public static final String PLUGIN_ACTION = "android.webkit.PLUGIN";
/**
* A plugin that wish to be loaded in the WebView must provide this permission
* in their AndroidManifest.xml.
*/
public static final String PLUGIN_PERMISSION = "android.webkit.permission.PLUGIN";
private static final String LOGTAG = "PluginManager";
private static final String PLUGIN_SYSTEM_LIB = "/system/lib/plugins/";
private static final String PLUGIN_TYPE = "type";
private static final String TYPE_NATIVE = "native";
public ArrayList<PackageInfo> mPackageInfoCache = new ArrayList<PackageInfo>();
String[] getPluginDirectories() {
ArrayList<String> directories = new ArrayList<String>();
PackageManager pm = this.mAppContext.getPackageManager();
List<ResolveInfo> plugins = pm.queryIntentServices(new Intent(PLUGIN_ACTION),
PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
synchronized(mPackageInfoCache) {
// clear the list of existing packageInfo objects
mPackageInfoCache.clear();
for (ResolveInfo info : plugins) {
// retrieve the plugin's service information
ServiceInfo serviceInfo = info.serviceInfo;
if (serviceInfo == null) {
Log.w(LOGTAG, "Ignore bad plugin");
continue;
}
Log.w(LOGTAG, "Loading plugin: " + serviceInfo.packageName);
// retrieve information from the plugin's manifest
PackageInfo pkgInfo;
try {
pkgInfo = pm.getPackageInfo(serviceInfo.packageName,
PackageManager.GET_PERMISSIONS
| PackageManager.GET_SIGNATURES);
} catch (Exception e) {
Log.w(LOGTAG, "Can't find plugin: " + serviceInfo.packageName);
continue;
}
if (pkgInfo == null) {
Log.w(LOGTAG, "Loading plugin: " + serviceInfo.packageName + ". Could not load package information.");
continue;
}
/*
* find the location of the plugin's shared library. The default
* is to assume the app is either a user installed app or an
* updated system app. In both of these cases the library is
* stored in the app's data directory.
*/
String directory = pkgInfo.applicationInfo.dataDir + "/lib";
final int appFlags = pkgInfo.applicationInfo.flags;
final int updatedSystemFlags = ApplicationInfo.FLAG_SYSTEM |
ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
// preloaded system app with no user updates
if ((appFlags & updatedSystemFlags) == ApplicationInfo.FLAG_SYSTEM) {
directory = PLUGIN_SYSTEM_LIB + pkgInfo.packageName;
}
// check if the plugin has the required permissions
String permissions[] = pkgInfo.requestedPermissions;
if (permissions == null) {
Log.w(LOGTAG, "Loading plugin: " + serviceInfo.packageName + ". Does not have required permission.");
continue;
}
boolean permissionOk = false;
for (String permit : permissions) {
if (PLUGIN_PERMISSION.equals(permit)) {
permissionOk = true;
break;
}
}
if (!permissionOk) {
Log.w(LOGTAG, "Loading plugin: " + serviceInfo.packageName + ". Does not have required permission (2).");
continue;
}
// check to ensure the plugin is properly signed
Signature signatures[] = pkgInfo.signatures;
if (signatures == null) {
Log.w(LOGTAG, "Loading plugin: " + serviceInfo.packageName + ". Not signed.");
continue;
}
// determine the type of plugin from the manifest
if (serviceInfo.metaData == null) {
Log.e(LOGTAG, "The plugin '" + serviceInfo.name + "' has no type defined");
continue;
}
String pluginType = serviceInfo.metaData.getString(PLUGIN_TYPE);
if (!TYPE_NATIVE.equals(pluginType)) {
Log.e(LOGTAG, "Unrecognized plugin type: " + pluginType);
continue;
}
try {
Class<?> cls = getPluginClass(serviceInfo.packageName, serviceInfo.name);
//TODO implement any requirements of the plugin class here!
boolean classFound = true;
if (!classFound) {
Log.e(LOGTAG, "The plugin's class' " + serviceInfo.name + "' does not extend the appropriate class.");
continue;
}
} catch (NameNotFoundException e) {
Log.e(LOGTAG, "Can't find plugin: " + serviceInfo.packageName);
continue;
} catch (ClassNotFoundException e) {
Log.e(LOGTAG, "Can't find plugin's class: " + serviceInfo.name);
continue;
}
// if all checks have passed then make the plugin available
mPackageInfoCache.add(pkgInfo);
directories.add(directory);
}
}
return directories.toArray(new String[directories.size()]);
}
Class<?> getPluginClass(String packageName, String className)
throws NameNotFoundException, ClassNotFoundException {
Context pluginContext = this.mAppContext.createPackageContext(packageName,
Context.CONTEXT_INCLUDE_CODE |
Context.CONTEXT_IGNORE_SECURITY);
ClassLoader pluginCL = pluginContext.getClassLoader();
return pluginCL.loadClass(className);
}
// Returns true when the intent is going to be handled by gecko launch
boolean launch(Intent intent)
{
@ -229,13 +378,14 @@ abstract public class GeckoApp
if (surfaceView == null)
surfaceView = new GeckoSurfaceView(this);
else
mainLayout.removeView(surfaceView);
mainLayout.removeAllViews();
mainLayout = new FrameLayout(this);
mainLayout = new AbsoluteLayout(this);
mainLayout.addView(surfaceView,
new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT,
FrameLayout.LayoutParams.FILL_PARENT));
new AbsoluteLayout.LayoutParams(AbsoluteLayout.LayoutParams.MATCH_PARENT, // level 8
AbsoluteLayout.LayoutParams.MATCH_PARENT,
0,
0));
setContentView(mainLayout,
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT));

Просмотреть файл

@ -308,6 +308,19 @@ public class GeckoAppShell
if (intHome != null && intProf != null && intProf.exists())
moveDir(intProf, profileDir);
}
try {
String[] dirs = GeckoApp.mAppContext.getPluginDirectories();
StringBuffer pluginSearchPath = new StringBuffer();
for (int i = 0; i < dirs.length; i++) {
Log.i("GeckoPlugins", "dir: " + dirs[i]);
pluginSearchPath.append(dirs[i]);
pluginSearchPath.append(":");
}
GeckoAppShell.putenv("MOZ_PLUGIN_PATH="+pluginSearchPath);
} catch (Exception ex) {
Log.i("GeckoPlugins", "exception getting plugin dirs", ex);
}
GeckoAppShell.putenv("HOME=" + homeDir);
GeckoAppShell.putenv("GRE_HOME=" + GeckoApp.sGREDir.getPath());
Intent i = geckoApp.getIntent();
@ -395,6 +408,7 @@ public class GeckoAppShell
combinedArgs += " " + args;
if (url != null)
combinedArgs += " " + url;
// and go
GeckoAppShell.nativeRun(combinedArgs);
}
@ -1385,4 +1399,187 @@ public class GeckoAppShell
return false;
}
}
public static void addPluginView(final View view,
final double x, final double y,
final double w, final double h) {
Log.i("GeckoAppShell", "addPluginView:" + view + " @ x:" + x + " y:" + y + " w:" + w + " h:" + h ) ;
getMainHandler().post(new Runnable() {
public void run() {
AbsoluteLayout.LayoutParams lp = new AbsoluteLayout.LayoutParams((int)w,
(int)h,
(int)x,
(int)y);
if (GeckoApp.mainLayout.indexOfChild(view) == -1) {
view.setWillNotDraw(false);
if(view instanceof SurfaceView)
((SurfaceView)view).setZOrderOnTop(true);
GeckoApp.mainLayout.addView(view, lp);
}
else
{
try {
GeckoApp.mainLayout.updateViewLayout(view, lp);
} catch (IllegalArgumentException e) {
Log.i("updateViewLayout - IllegalArgumentException", "e:" + e);
// it can be the case where we
// get an update before the view
// is actually attached.
}
}
}
});
}
public static void removePluginView(final View view) {
Log.i("GeckoAppShell", "remove view:" + view);
getMainHandler().post(new Runnable() {
public void run() {
try {
GeckoApp.mainLayout.removeView(view);
} catch (Exception e) {}
}
});
}
public static Class<?> loadPluginClass(String className, String libName) {
Log.i("GeckoAppShell", "in loadPluginClass... attempting to access className, then libName.....");
Log.i("GeckoAppShell", "className: " + className);
Log.i("GeckoAppShell", "libName: " + libName);
try {
String[] split = libName.split("/");
String packageName = split[split.length - 3];
Log.i("GeckoAppShell", "load \"" + className + "\" from \"" + packageName +
"\" for \"" + libName + "\"");
Context pluginContext =
GeckoApp.mAppContext.createPackageContext(packageName,
Context.CONTEXT_INCLUDE_CODE |
Context.CONTEXT_IGNORE_SECURITY);
ClassLoader pluginCL = pluginContext.getClassLoader();
return pluginCL.loadClass(className);
} catch (java.lang.ClassNotFoundException cnfe) {
Log.i("GeckoAppShell", "class not found", cnfe);
} catch (android.content.pm.PackageManager.NameNotFoundException nnfe) {
Log.i("GeckoAppShell", "package not found", nnfe);
}
Log.e("GeckoAppShell", "couldn't find class");
return null;
}
static HashMap<SurfaceView, SurfaceLockInfo> sSufaceMap = new HashMap<SurfaceView, SurfaceLockInfo>();
public static void lockSurfaceANP()
{
Log.i("GeckoAppShell", "other lockSurfaceANP");
}
public static org.mozilla.gecko.SurfaceLockInfo lockSurfaceANP(android.view.SurfaceView sview, int top, int left, int bottom, int right)
{
Log.i("GeckoAppShell", "real lockSurfaceANP " + sview + ", " + top + ", " + left + ", " + bottom + ", " + right);
if (sview == null)
return null;
int format = -1;
try {
Field privateFormatField = SurfaceView.class.getDeclaredField("mFormat");
privateFormatField.setAccessible(true);
format = privateFormatField.getInt(sview);
} catch (Exception e) {
Log.i("GeckoAppShell", "mFormat is not a field of sview: ", e);
}
int n = 0;
if (format == PixelFormat.RGB_565)
n = 2;
else if (format == PixelFormat.RGBA_8888)
n = 4;
if (n == 0)
return null;
SurfaceLockInfo info = sSufaceMap.get(sview);
if (info == null) {
info = new SurfaceLockInfo();
sSufaceMap.put(sview, info);
}
Rect r = new Rect(left, top, right, bottom);
info.canvas = sview.getHolder().lockCanvas(r);
int bufSizeRequired = info.canvas.getWidth() * info.canvas.getHeight() * n;
Log.i("GeckoAppShell", "lockSurfaceANP - bufSizeRequired: " + n + " " + info.canvas.getHeight() + " " + info.canvas.getWidth());
if (info.width != info.canvas.getWidth() || info.height != info.canvas.getHeight() || info.buffer == null || info.buffer.capacity() < bufSizeRequired) {
info.width = info.canvas.getWidth();
info.height = info.canvas.getHeight();
// XXX Bitmaps instead of ByteBuffer
info.buffer = ByteBuffer.allocateDirect(bufSizeRequired); //leak
Log.i("GeckoAppShell", "!!!!!!!!!!! lockSurfaceANP - Allocating buffer! " + bufSizeRequired);
}
info.canvas.drawColor(Color.WHITE, PorterDuff.Mode.CLEAR);
info.format = format;
info.dirtyTop = top;
info.dirtyBottom = bottom;
info.dirtyLeft = left;
info.dirtyRight = right;
return info;
}
public static void unlockSurfaceANP(SurfaceView sview) {
SurfaceLockInfo info = sSufaceMap.get(sview);
int n = 0;
Bitmap.Config config;
if (info.format == PixelFormat.RGB_565) {
n = 2;
config = Bitmap.Config.RGB_565;
} else {
n = 4;
config = Bitmap.Config.ARGB_8888;
}
Log.i("GeckoAppShell", "unlockSurfaceANP: " + (info.width * info.height * n));
Bitmap bm = Bitmap.createBitmap(info.width, info.height, config);
bm.copyPixelsFromBuffer(info.buffer);
info.canvas.drawBitmap(bm, 0, 0, null);
sview.getHolder().unlockCanvasAndPost(info.canvas);
}
public static Class getSurfaceLockInfoClass() {
Log.i("GeckoAppShell", "class name: " + SurfaceLockInfo.class.getName());
return SurfaceLockInfo.class;
}
public static Method getSurfaceLockMethod() {
Method[] m = GeckoAppShell.class.getMethods();
for (int i = 0; i < m.length; i++) {
if (m[i].getName().equals("lockSurfaceANP"))
return m[i];
}
return null;
}
static native void executeNextRunnable();
static class GeckoRunnableCallback implements Runnable {
public void run() {
Log.i("GeckoShell", "run GeckoRunnableCallback");
GeckoAppShell.executeNextRunnable();
}
}
public static void postToJavaThread(boolean mainThread) {
Log.i("GeckoShell", "post to " + (mainThread ? "main " : "") + "java thread");
getMainHandler().post(new GeckoRunnableCallback());
}
}

Просмотреть файл

@ -54,6 +54,7 @@ JAVAFILES = \
GeckoInputConnection.java \
GeckoPhoneStateListener.java \
AlertNotification.java \
SurfaceLockInfo.java \
$(NULL)
PROCESSEDJAVAFILES = \

Просмотреть файл

@ -0,0 +1,18 @@
package org.mozilla.gecko;
import android.graphics.Canvas;
import java.nio.Buffer;
public class SurfaceLockInfo {
public int dirtyTop;
public int dirtyLeft;
public int dirtyRight;
public int dirtyBottom;
public int bpr;
public int format;
public int width;
public int height;
public Buffer buffer;
public Canvas canvas;
}

Просмотреть файл

@ -135,6 +135,7 @@ LOCAL_INCLUDES += \
else ifneq (,$(filter android,$(MOZ_WIDGET_TOOLKIT)))
SHARED_LIBRARY_LIBS += \
$(DEPTH)/dom/system/android/$(LIB_PREFIX)domsystemandroid_s.$(LIB_SUFFIX) \
$(DEPTH)/dom/plugins/base/android/$(LIB_PREFIX)gkpluginandroid_s.$(LIB_SUFFIX) \
$(NULL)
LOCAL_INCLUDES += \
-I$(topsrcdir)/dom/system/android \

Просмотреть файл

@ -1683,6 +1683,22 @@ nsObjectFrame::PaintPlugin(nsDisplayListBuilder* aBuilder,
nsRenderingContext& aRenderingContext,
const nsRect& aDirtyRect, const nsRect& aPluginRect)
{
#if defined(ANDROID)
if (mInstanceOwner) {
NPWindow *window;
mInstanceOwner->GetWindow(window);
gfxRect frameGfxRect =
PresContext()->AppUnitsToGfxUnits(aPluginRect);
gfxRect dirtyGfxRect =
PresContext()->AppUnitsToGfxUnits(aDirtyRect);
gfxContext* ctx = aRenderingContext.ThebesContext();
mInstanceOwner->Paint(ctx, frameGfxRect, dirtyGfxRect);
return;
}
#endif
// Screen painting code
#if defined(XP_MACOSX)
// delegate all painting to the plugin instance.

Просмотреть файл

@ -0,0 +1,24 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Testcase for checking that filter bounds include stroke width</title>
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=647687 -->
<defs>
<filter id="f1" filterUnits="userSpaceOnUse" x="150" y="150" width="200" height="200">
<feOffset in="SourceGraphic"/>
</filter>
</defs>
<rect height="100%" width="100%" fill="lime"/>
<rect x="150" y="150" height="200" width="200" fill="red"/>
<rect x="200" y="200" height="100" width="100" stroke-width="100"
fill="none" stroke="lime" filter="url(#f1)"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 779 B

Просмотреть файл

@ -0,0 +1,25 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Testcase for checking that filter bounds include stroke width</title>
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=647687 -->
<defs>
<filter id="f1" filterUnits="objectBoundingBox">
<feFlood flood-color="red"/>
</filter>
</defs>
<rect height="100%" width="100%" fill="lime"/>
<polygon points="200,200 300,200 300,300 200,300" stroke-width="100"
fill="none" stroke="lime" filter="url(#f1)"/>
<rect x="150" y="150" height="200" width="200" fill="lime"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 744 B

Просмотреть файл

@ -111,6 +111,8 @@ random == dynamic-use-nested-01.svg dynamic-use-nested-01-ref.svg # bug 467498
== filter-basic-01.svg pass.svg
== filter-basic-02.svg pass.svg
== filter-basic-03.svg pass.svg
== filter-bounds-01.svg pass.svg
== filter-bounds-02.svg pass.svg
== filter-foreignObject-01.svg pass.svg
== filter-invalidation-01.svg pass.svg
== filter-scaled-01.svg pass.svg

Просмотреть файл

@ -206,11 +206,19 @@ nsAutoFilterInstance::nsAutoFilterInstance(nsIFrame *aTarget,
MapDeviceRectToFilterSpace(deviceToFilterSpace, filterRes, aDirtyOutputRect);
nsIntRect dirtyInputRect =
MapDeviceRectToFilterSpace(deviceToFilterSpace, filterRes, aDirtyInputRect);
nsIntRect targetBoundsDeviceSpace;
nsISVGChildFrame* svgTarget = do_QueryFrame(aTarget);
if (svgTarget) {
targetBoundsDeviceSpace.UnionRect(targetBoundsDeviceSpace,
svgTarget->GetCoveredRegion().ToOutsidePixels(aTarget->PresContext()->AppUnitsPerDevPixel()));
}
nsIntRect targetBoundsFilterSpace =
MapDeviceRectToFilterSpace(deviceToFilterSpace, filterRes, &targetBoundsDeviceSpace);
// Setup instance data
mInstance = new nsSVGFilterInstance(aTarget, aPaint, filter, bbox, filterRegion,
nsIntSize(filterRes.width, filterRes.height),
filterToDeviceSpace,
filterToDeviceSpace, targetBoundsFilterSpace,
dirtyOutputRect, dirtyInputRect,
primitiveUnits);
}

Просмотреть файл

@ -189,6 +189,7 @@ nsSVGFilterInstance::BuildSources()
// Detect possible float->int overflow
if (!gfxUtils::GfxRectToIntRect(sourceBounds, &sourceBoundsInt))
return NS_ERROR_FAILURE;
sourceBoundsInt.UnionRect(sourceBoundsInt, mTargetBounds);
mSourceColorAlpha.mResultBoundingBox = sourceBoundsInt;
mSourceAlpha.mResultBoundingBox = sourceBoundsInt;

Просмотреть файл

@ -70,6 +70,7 @@ public:
const gfxRect& aFilterRect,
const nsIntSize& aFilterSpaceSize,
const gfxMatrix &aFilterSpaceToDeviceSpaceTransform,
const nsIntRect& aTargetBounds,
const nsIntRect& aDirtyOutputRect,
const nsIntRect& aDirtyInputRect,
PRUint16 aPrimitiveUnits) :
@ -80,6 +81,7 @@ public:
mFilterSpaceToDeviceSpaceTransform(aFilterSpaceToDeviceSpaceTransform),
mFilterRect(aFilterRect),
mFilterSpaceSize(aFilterSpaceSize),
mTargetBounds(aTargetBounds),
mDirtyOutputRect(aDirtyOutputRect),
mDirtyInputRect(aDirtyInputRect),
mSurfaceRect(nsIntPoint(0, 0), aFilterSpaceSize),
@ -209,6 +211,8 @@ private:
gfxMatrix mFilterSpaceToDeviceSpaceTransform;
gfxRect mFilterRect;
nsIntSize mFilterSpaceSize;
// Filter-space bounds of the target image (SourceAlpha/SourceGraphic)
nsIntRect mTargetBounds;
nsIntRect mDirtyOutputRect;
nsIntRect mDirtyInputRect;
nsIntRect mSurfaceRect;

Просмотреть файл

@ -66,6 +66,7 @@
#include "nsChannelClassifier.h"
#include "nsIRedirectResultListener.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/Telemetry.h"
// True if the local cache should be bypassed when processing a request.
#define BYPASS_LOCAL_CACHE(loadFlags) \
@ -128,6 +129,7 @@ nsHttpChannel::nsHttpChannel()
, mFallingBack(PR_FALSE)
, mWaitingForRedirectCallback(PR_FALSE)
, mRequestTimeInitialized(PR_FALSE)
, mDidReval(false)
{
LOG(("Creating nsHttpChannel [this=%p]\n", this));
mChannelCreationTime = PR_Now();
@ -267,6 +269,8 @@ nsHttpChannel::Connect(PRBool firstTime)
if (NS_FAILED(rv) && event) {
event->Revoke();
}
mozilla::Telemetry::Accumulate(
mozilla::Telemetry::HTTP_CACHE_DISPOSITION, kCacheHit);
return rv;
}
else if (mLoadFlags & LOAD_ONLY_FROM_CACHE) {
@ -974,6 +978,8 @@ nsHttpChannel::ProcessResponse()
LOG((" continuation state has been reset"));
}
bool successfulReval = false;
// handle different server response categories. Note that we handle
// caching or not caching of error pages in
// nsHttpResponseHead::MustValidate; if you change this switch, update that
@ -1025,6 +1031,9 @@ nsHttpChannel::ProcessResponse()
LOG(("ProcessNotModified failed [rv=%x]\n", rv));
rv = ProcessNormal();
}
else {
successfulReval = true;
}
break;
case 401:
case 407:
@ -1060,6 +1069,17 @@ nsHttpChannel::ProcessResponse()
break;
}
if (!mDidReval)
mozilla::Telemetry::Accumulate(
mozilla::Telemetry::HTTP_CACHE_DISPOSITION, kCacheMissed);
else if (successfulReval)
mozilla::Telemetry::Accumulate(
mozilla::Telemetry::HTTP_CACHE_DISPOSITION, kCacheHitViaReval);
else
mozilla::Telemetry::Accumulate(
mozilla::Telemetry::HTTP_CACHE_DISPOSITION,
kCacheMissedViaReval);
return rv;
}
@ -2666,6 +2686,7 @@ nsHttpChannel::CheckCache()
if (val)
mRequestHead.SetHeader(nsHttp::If_None_Match,
nsDependentCString(val));
mDidReval = true;
}
}

Просмотреть файл

@ -366,6 +366,15 @@ private:
protected:
virtual void DoNotifyListenerCleanup();
private: // cache telemetry
enum {
kCacheHit = 1,
kCacheHitViaReval = 2,
kCacheMissedViaReval = 3,
kCacheMissed = 4
};
bool mDidReval;
};
#endif // nsHttpChannel_h__

Просмотреть файл

@ -241,6 +241,7 @@ SHELL_WRAPPER3(callObserver, jstring, jstring, jstring)
SHELL_WRAPPER1(removeObserver, jstring)
SHELL_WRAPPER2(onChangeNetworkLinkStatus, jstring, jstring)
SHELL_WRAPPER1(reportJavaCrash, jstring)
SHELL_WRAPPER0(executeNextRunnable)
static void * xul_handle = NULL;
static time_t apk_mtime = 0;
@ -667,6 +668,7 @@ loadLibs(const char *apkName)
GETFUNC(removeObserver);
GETFUNC(onChangeNetworkLinkStatus);
GETFUNC(reportJavaCrash);
GETFUNC(executeNextRunnable);
#undef GETFUNC
gettimeofday(&t1, 0);
struct rusage usage2;

Просмотреть файл

@ -132,6 +132,9 @@ HTTP_HISTOGRAMS(SUB, "subitem: ")
#undef _HTTP_HIST
#undef HTTP_HISTOGRAMS
HISTOGRAM(HTTP_CACHE_DISPOSITION, 1, 5, 5, LINEAR, "HTTP Cache Hit, Reval, Failed-Reval, Miss")
HISTOGRAM(FIND_PLUGINS, 1, 3000, 10, EXPONENTIAL, "Time spent scanning filesystem for plugins (ms)")
HISTOGRAM(CHECK_JAVA_ENABLED, 1, 3000, 10, EXPONENTIAL, "Time spent checking if Java is enabled (ms)")

Просмотреть файл

@ -149,6 +149,7 @@ AndroidBridge::Init(JNIEnv *jEnv,
jGetIconForExtension = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getIconForExtension", "(Ljava/lang/String;I)[B");
jCreateShortcut = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "createShortcut", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
jGetShowPasswordSetting = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getShowPasswordSetting", "()Z");
jPostToJavaThread = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "postToJavaThread", "(Z)V");
jEGLContextClass = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("javax/microedition/khronos/egl/EGLContext"));
jEGL10Class = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("javax/microedition/khronos/egl/EGL10"));
@ -169,8 +170,14 @@ AndroidBridge::Init(JNIEnv *jEnv,
JNIEnv *
AndroidBridge::AttachThread(PRBool asDaemon)
{
// If we already have a env, return it
JNIEnv *jEnv = NULL;
mJavaVM->GetEnv((void**) &jEnv, JNI_VERSION_1_2);
if (jEnv)
return jEnv;
ALOG_BRIDGE("AndroidBridge::AttachThread");
JNIEnv *jEnv = (JNIEnv*) PR_GetThreadPrivate(sJavaEnvThreadIndex);
jEnv = (JNIEnv*) PR_GetThreadPrivate(sJavaEnvThreadIndex);
if (jEnv)
return jEnv;
@ -195,6 +202,8 @@ AndroidBridge::AttachThread(PRBool asDaemon)
PR_SetThreadPrivate(sJavaEnvThreadIndex, jEnv);
PR_NewThreadPrivateIndex(&sJavaEnvThreadIndex, JavaThreadDetachFunc);
return jEnv;
}
@ -926,6 +935,45 @@ AndroidBridge::CreateShortcut(const nsAString& aTitle, const nsAString& aURI, co
mJNIEnv->CallStaticVoidMethod(mGeckoAppShellClass, jCreateShortcut, jstrTitle, jstrURI, jstrIconData, jstrIntent);
}
void
AndroidBridge::PostToJavaThread(nsIRunnable* aRunnable, PRBool aMainThread)
{
__android_log_print(ANDROID_LOG_INFO, "GeckoBridge", "%s", __PRETTY_FUNCTION__);
JNIEnv* env = AndroidBridge::AttachThread(false);
if (!env) {
__android_log_print(ANDROID_LOG_INFO, "GeckoBridge", "no jni env in %s!!", __PRETTY_FUNCTION__);
return;
}
mRunnableQueue.AppendObject(aRunnable);
env->CallStaticVoidMethod(mGeckoAppShellClass, jPostToJavaThread, (jboolean)aMainThread);
jthrowable ex = env->ExceptionOccurred();
if (ex) {
env->ExceptionDescribe();
env->ExceptionClear();
}
__android_log_print(ANDROID_LOG_INFO, "GeckoBridge", "leaving %s", __PRETTY_FUNCTION__);
}
void
AndroidBridge::ExecuteNextRunnable()
{
__android_log_print(ANDROID_LOG_INFO, "GeckoBridge", "%s", __PRETTY_FUNCTION__);
JNIEnv* env = AndroidBridge::AttachThread(false);
if (!env) {
__android_log_print(ANDROID_LOG_INFO, "GeckoBridge", "no jni env in %s!!", __PRETTY_FUNCTION__);
return;
}
if (mRunnableQueue.Count() > 0) {
nsIRunnable* r = mRunnableQueue[0];
__android_log_print(ANDROID_LOG_INFO, "GeckoBridge", "going to run %p", r);
r->Run();
mRunnableQueue.RemoveObjectAt(0);
}
__android_log_print(ANDROID_LOG_INFO, "GeckoBridge", "leaving %s", __PRETTY_FUNCTION__);
}
bool
AndroidBridge::HasNativeBitmapAccess()
{

Просмотреть файл

@ -42,6 +42,7 @@
#include <android/log.h>
#include "nsCOMPtr.h"
#include "nsCOMArray.h"
#include "nsIRunnable.h"
#include "nsIObserver.h"
@ -262,6 +263,10 @@ public:
void UnlockBitmap(jobject bitmap);
void PostToJavaThread(nsIRunnable* aRunnable, PRBool aMainThread = PR_FALSE);
void ExecuteNextRunnable();
protected:
static AndroidBridge *sBridge;
@ -286,6 +291,8 @@ protected:
bool mOpenedBitmapLibrary;
bool mHasNativeBitmapAccess;
nsCOMArray<nsIRunnable> mRunnableQueue;
// other things
jmethodID jNotifyIME;
jmethodID jNotifyIMEEnabled;
@ -325,6 +332,7 @@ protected:
jmethodID jGetIconForExtension;
jmethodID jCreateShortcut;
jmethodID jGetShowPasswordSetting;
jmethodID jPostToJavaThread;
// stuff we need for CallEglCreateWindowSurface
jclass jEGLSurfaceImplClass;

Просмотреть файл

@ -72,6 +72,7 @@ extern "C" {
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_removeObserver(JNIEnv *jenv, jclass, jstring jObserverKey);
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_onChangeNetworkLinkStatus(JNIEnv *, jclass, jstring status, jstring type);
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_reportJavaCrash(JNIEnv *, jclass, jstring stack);
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_executeNextRunnable(JNIEnv *, jclass);
}
@ -179,3 +180,15 @@ Java_org_mozilla_gecko_GeckoAppShell_reportJavaCrash(JNIEnv *jenv, jclass, jstri
#endif
abort();
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoAppShell_executeNextRunnable(JNIEnv *, jclass)
{
__android_log_print(ANDROID_LOG_INFO, "GeckoJNI", "%s", __PRETTY_FUNCTION__);
if (!AndroidBridge::Bridge()) {
__android_log_print(ANDROID_LOG_INFO, "GeckoJNI", "no bridge in %s!!!!", __PRETTY_FUNCTION__);
return;
}
AndroidBridge::Bridge()->ExecuteNextRunnable();
__android_log_print(ANDROID_LOG_INFO, "GeckoJNI", "leaving %s", __PRETTY_FUNCTION__);
}

Просмотреть файл

@ -558,7 +558,6 @@ PuppetWidget::DispatchPaintEvent()
nsCAutoString("PuppetWidget"), nsnull);
#endif
LayerManager* lm = GetLayerManager();
if (LayerManager::LAYERS_D3D10 == mLayerManager->GetBackendType()) {
DispatchEvent(&event, status);
} else {