mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-29 20:07:30 +09:00
parent
470a6e4401
commit
13fcc4a046
949 changed files with 95662 additions and 444 deletions
|
|
@ -24,7 +24,7 @@ static int gNotOptimized;
|
|||
using namespace mozilla::layers;
|
||||
|
||||
namespace mozilla {
|
||||
#if defined(XP_UNIX)
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
nsresult
|
||||
PluginPRLibrary::NP_Initialize(NPNetscapeFuncs* bFuncs,
|
||||
NPPluginFuncs* pFuncs, NPError* error)
|
||||
|
|
@ -110,7 +110,7 @@ nsresult
|
|||
PluginPRLibrary::NP_GetValue(void *future, NPPVariable aVariable,
|
||||
void *aValue, NPError* error)
|
||||
{
|
||||
#if defined(XP_UNIX)
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
if (mNP_GetValue) {
|
||||
*error = mNP_GetValue(future, aVariable, aValue);
|
||||
} else {
|
||||
|
|
@ -125,7 +125,7 @@ PluginPRLibrary::NP_GetValue(void *future, NPPVariable aVariable,
|
|||
#endif
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX)
|
||||
nsresult
|
||||
PluginPRLibrary::NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error)
|
||||
{
|
||||
|
|
@ -231,7 +231,17 @@ PluginPRLibrary::GetImageContainer(NPP instance, ImageContainer** aContainer)
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_MACOSX)
|
||||
nsresult
|
||||
PluginPRLibrary::IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing)
|
||||
{
|
||||
nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
|
||||
NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
|
||||
*aDrawing = false;
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
nsresult
|
||||
PluginPRLibrary::ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,17 +17,17 @@ class PluginPRLibrary : public PluginLibrary
|
|||
{
|
||||
public:
|
||||
PluginPRLibrary(const char* aFilePath, PRLibrary* aLibrary) :
|
||||
#if defined(XP_UNIX)
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
mNP_Initialize(nullptr),
|
||||
#else
|
||||
mNP_Initialize(nullptr),
|
||||
#endif
|
||||
mNP_Shutdown(nullptr),
|
||||
mNP_GetMIMEDescription(nullptr),
|
||||
#if defined(XP_UNIX)
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
mNP_GetValue(nullptr),
|
||||
#endif
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX)
|
||||
mNP_GetEntryPoints(nullptr),
|
||||
#endif
|
||||
mNPP_New(nullptr),
|
||||
|
|
@ -60,17 +60,19 @@ public:
|
|||
|
||||
mNP_GetMIMEDescription = (NP_GetMIMEDescriptionFunc)
|
||||
PR_FindFunctionSymbol(mLibrary, "NP_GetMIMEDescription");
|
||||
#ifndef XP_MACOSX
|
||||
if (!mNP_GetMIMEDescription)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
mNP_GetValue = (NP_GetValueFunc)
|
||||
PR_FindFunctionSymbol(mLibrary, "NP_GetValue");
|
||||
if (!mNP_GetValue)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX)
|
||||
mNP_GetEntryPoints = (NP_GetEntryPointsFunc)
|
||||
PR_FindFunctionSymbol(mLibrary, "NP_GetEntryPoints");
|
||||
if (!mNP_GetEntryPoints)
|
||||
|
|
@ -79,7 +81,7 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
virtual nsresult NP_Initialize(NPNetscapeFuncs* aNetscapeFuncs,
|
||||
NPPluginFuncs* aFuncs, NPError* aError) override;
|
||||
#else
|
||||
|
|
@ -93,7 +95,7 @@ public:
|
|||
virtual nsresult NP_GetValue(void* aFuture, NPPVariable aVariable,
|
||||
void* aValue, NPError* aError) override;
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX)
|
||||
virtual nsresult NP_GetEntryPoints(NPPluginFuncs* aFuncs, NPError* aError) override;
|
||||
#endif
|
||||
|
||||
|
|
@ -110,7 +112,10 @@ public:
|
|||
virtual nsresult GetImageContainer(NPP aInstance, mozilla::layers::ImageContainer** aContainer) override;
|
||||
virtual nsresult GetImageSize(NPP aInstance, nsIntSize* aSize) override;
|
||||
virtual bool IsOOP() override { return false; }
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_MACOSX)
|
||||
virtual nsresult IsRemoteDrawingCoreAnimation(NPP aInstance, bool* aDrawing) override;
|
||||
#endif
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
virtual nsresult ContentsScaleFactorChanged(NPP aInstance, double aContentsScaleFactor) override;
|
||||
#endif
|
||||
virtual nsresult SetBackgroundUnknown(NPP instance) override;
|
||||
|
|
@ -134,10 +139,10 @@ private:
|
|||
NP_InitializeFunc mNP_Initialize;
|
||||
NP_ShutdownFunc mNP_Shutdown;
|
||||
NP_GetMIMEDescriptionFunc mNP_GetMIMEDescription;
|
||||
#if defined(XP_UNIX)
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
NP_GetValueFunc mNP_GetValue;
|
||||
#endif
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX)
|
||||
NP_GetEntryPointsFunc mNP_GetEntryPoints;
|
||||
#endif
|
||||
NPP_NewProcPtr mNPP_New;
|
||||
|
|
|
|||
|
|
@ -56,6 +56,11 @@ if CONFIG['OS_ARCH'] == 'WINNT':
|
|||
'nsPluginNativeWindowWin.cpp',
|
||||
'nsPluginsDirWin.cpp',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
SOURCES += [
|
||||
'nsPluginNativeWindow.cpp',
|
||||
'nsPluginsDirDarwin.cpp',
|
||||
]
|
||||
else:
|
||||
SOURCES += [
|
||||
'nsPluginsDirUnix.cpp',
|
||||
|
|
@ -77,6 +82,7 @@ LOCAL_INCLUDES += [
|
|||
'/layout/xul',
|
||||
'/netwerk/base',
|
||||
'/widget',
|
||||
'/widget/cocoa',
|
||||
'/xpcom/base',
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,25 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE_CC__) && !defined(XP_UNIX)
|
||||
#ifndef XP_MACOSX
|
||||
#define XP_MACOSX 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(XP_MACOSX) && defined(__LP64__)
|
||||
#define NP_NO_QUICKDRAW
|
||||
#define NP_NO_CARBON
|
||||
#endif
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#ifndef NP_NO_CARBON
|
||||
#include <Carbon/Carbon.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
#include <stdio.h>
|
||||
#if defined(MOZ_X11)
|
||||
|
|
@ -98,6 +117,12 @@ typedef char* NPMIMEType;
|
|||
/* Structures and definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#if !defined(__LP64__)
|
||||
#if defined(XP_MACOSX)
|
||||
#pragma options align=mac68k
|
||||
#endif
|
||||
#endif /* __LP64__ */
|
||||
|
||||
/*
|
||||
* NPP is a plug-in's opaque instance handle
|
||||
*/
|
||||
|
|
@ -255,6 +280,15 @@ typedef struct _NPAudioDeviceChangeDetails
|
|||
|
||||
typedef enum {
|
||||
NPDrawingModelDUMMY
|
||||
#if defined(XP_MACOSX)
|
||||
#ifndef NP_NO_QUICKDRAW
|
||||
, NPDrawingModelQuickDraw = 0
|
||||
#endif
|
||||
, NPDrawingModelCoreGraphics = 1
|
||||
, NPDrawingModelOpenGL = 2
|
||||
, NPDrawingModelCoreAnimation = 3
|
||||
, NPDrawingModelInvalidatingCoreAnimation = 4
|
||||
#endif
|
||||
#if defined(XP_WIN)
|
||||
, NPDrawingModelSyncWin = 5
|
||||
#endif
|
||||
|
|
@ -267,6 +301,15 @@ typedef enum {
|
|||
#endif
|
||||
} NPDrawingModel;
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
typedef enum {
|
||||
#ifndef NP_NO_CARBON
|
||||
NPEventModelCarbon = 0,
|
||||
#endif
|
||||
NPEventModelCocoa = 1
|
||||
} NPEventModel;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The following masks are applied on certain platforms to NPNV and
|
||||
* NPPV selectors that pass around pointers to COM interfaces. Newer
|
||||
|
|
@ -294,7 +337,12 @@ typedef enum {
|
|||
#define _NP_ABI_MIXIN_FOR_GCC3 0
|
||||
#endif
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
#define NP_ABI_MACHO_MASK 0x01000000
|
||||
#define _NP_ABI_MIXIN_FOR_MACHO NP_ABI_MACHO_MASK
|
||||
#else
|
||||
#define _NP_ABI_MIXIN_FOR_MACHO 0
|
||||
#endif
|
||||
|
||||
#define NP_ABI_MASK (_NP_ABI_MIXIN_FOR_GCC3 | _NP_ABI_MIXIN_FOR_MACHO)
|
||||
|
||||
|
|
@ -345,6 +393,12 @@ typedef enum {
|
|||
|
||||
/* Used for negotiating drawing models */
|
||||
NPPVpluginDrawingModel = 1000
|
||||
#if defined(XP_MACOSX)
|
||||
/* Used for negotiating event models */
|
||||
, NPPVpluginEventModel = 1001
|
||||
/* In the NPDrawingModelCoreAnimation drawing model, the browser asks the plug-in for a Core Animation layer. */
|
||||
, NPPVpluginCoreAnimationLayer = 1003
|
||||
#endif
|
||||
/* Notification that the plugin just started or stopped playing audio */
|
||||
, NPPVpluginIsPlayingAudio = 4000
|
||||
#if defined(XP_WIN)
|
||||
|
|
@ -388,18 +442,39 @@ typedef enum {
|
|||
NPNVCSSZoomFactor = 23,
|
||||
|
||||
NPNVpluginDrawingModel = 1000 /* Get the current drawing model (NPDrawingModel) */
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
, NPNVcontentsScaleFactor = 1001
|
||||
#endif
|
||||
#if defined(XP_MACOSX)
|
||||
#ifndef NP_NO_QUICKDRAW
|
||||
, NPNVsupportsQuickDrawBool = 2000
|
||||
#endif
|
||||
, NPNVsupportsCoreGraphicsBool = 2001
|
||||
, NPNVsupportsOpenGLBool = 2002
|
||||
, NPNVsupportsCoreAnimationBool = 2003
|
||||
, NPNVsupportsInvalidatingCoreAnimationBool = 2004
|
||||
#endif
|
||||
, NPNVsupportsAsyncBitmapSurfaceBool = 2007
|
||||
#if defined(XP_WIN)
|
||||
, NPNVsupportsAsyncWindowsDXGISurfaceBool = 2008
|
||||
, NPNVpreferredDXGIAdapter = 2009
|
||||
#endif
|
||||
#if defined(XP_MACOSX)
|
||||
#ifndef NP_NO_CARBON
|
||||
, NPNVsupportsCarbonBool = 3000 /* TRUE if the browser supports the Carbon event model */
|
||||
#endif
|
||||
, NPNVsupportsCocoaBool = 3001 /* TRUE if the browser supports the Cocoa event model */
|
||||
, NPNVsupportsUpdatedCocoaTextInputBool = 3002 /* TRUE if the browser supports the updated
|
||||
Cocoa text input specification. */
|
||||
#endif
|
||||
, NPNVmuteAudioBool = 4000 /* Request that the browser wants to mute or unmute the plugin */
|
||||
#if defined(XP_WIN)
|
||||
, NPNVaudioDeviceChangeDetails = 4001 /* Provides information about the new default audio device */
|
||||
#endif
|
||||
#if defined(XP_MACOSX)
|
||||
, NPNVsupportsCompositingCoreAnimationPluginsBool = 74656 /* TRUE if the browser supports
|
||||
CA model compositing */
|
||||
#endif
|
||||
} NPNVariable;
|
||||
|
||||
typedef enum {
|
||||
|
|
@ -434,7 +509,7 @@ typedef struct _NPWindow
|
|||
uint32_t width; /* Maximum window size */
|
||||
uint32_t height;
|
||||
NPRect clipRect; /* Clipping rectangle in port coordinates */
|
||||
#if defined(XP_UNIX) || defined(XP_SYMBIAN)
|
||||
#if (defined(XP_UNIX) || defined(XP_SYMBIAN)) && !defined(XP_MACOSX)
|
||||
void * ws_info; /* Platform-dependent additional data */
|
||||
#endif /* XP_UNIX */
|
||||
NPWindowType type; /* Is this a window or a drawable? */
|
||||
|
|
@ -480,7 +555,11 @@ typedef struct _NPPrint
|
|||
} print;
|
||||
} NPPrint;
|
||||
|
||||
#if defined(XP_SYMBIAN)
|
||||
#if defined(XP_MACOSX)
|
||||
#ifndef NP_NO_CARBON
|
||||
typedef EventRecord NPEvent;
|
||||
#endif
|
||||
#elif defined(XP_SYMBIAN)
|
||||
typedef QEvent NPEvent;
|
||||
#elif defined(XP_WIN)
|
||||
typedef struct _NPEvent
|
||||
|
|
@ -495,7 +574,13 @@ typedef XEvent NPEvent;
|
|||
typedef void* NPEvent;
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_MACOSX)
|
||||
typedef void* NPRegion;
|
||||
#ifndef NP_NO_QUICKDRAW
|
||||
typedef RgnHandle NPQDRegion;
|
||||
#endif
|
||||
typedef CGPathRef NPCGRegion;
|
||||
#elif defined(XP_WIN)
|
||||
typedef HRGN NPRegion;
|
||||
#elif defined(XP_UNIX) && defined(MOZ_X11)
|
||||
typedef Region NPRegion;
|
||||
|
|
@ -509,7 +594,11 @@ typedef struct _NPNSString NPNSString;
|
|||
typedef struct _NPNSWindow NPNSWindow;
|
||||
typedef struct _NPNSMenu NPNSMenu;
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
typedef NPNSMenu NPMenu;
|
||||
#else
|
||||
typedef void *NPMenu;
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
NPCoordinateSpacePlugin = 1,
|
||||
|
|
@ -519,6 +608,112 @@ typedef enum {
|
|||
NPCoordinateSpaceFlippedScreen
|
||||
} NPCoordinateSpace;
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
|
||||
#ifndef NP_NO_QUICKDRAW
|
||||
typedef struct NP_Port
|
||||
{
|
||||
CGrafPtr port;
|
||||
int32_t portx; /* position inside the topmost window */
|
||||
int32_t porty;
|
||||
} NP_Port;
|
||||
#endif /* NP_NO_QUICKDRAW */
|
||||
|
||||
/*
|
||||
* NP_CGContext is the type of the NPWindow's 'window' when the plugin specifies NPDrawingModelCoreGraphics
|
||||
* as its drawing model.
|
||||
*/
|
||||
|
||||
typedef struct NP_CGContext
|
||||
{
|
||||
CGContextRef context;
|
||||
void *window; /* A WindowRef under the Carbon event model. */
|
||||
} NP_CGContext;
|
||||
|
||||
/*
|
||||
* NP_GLContext is the type of the NPWindow's 'window' when the plugin specifies NPDrawingModelOpenGL as its
|
||||
* drawing model.
|
||||
*/
|
||||
|
||||
typedef struct NP_GLContext
|
||||
{
|
||||
CGLContextObj context;
|
||||
#ifdef NP_NO_CARBON
|
||||
NPNSWindow *window;
|
||||
#else
|
||||
void *window; /* Can be either an NSWindow or a WindowRef depending on the event model */
|
||||
#endif
|
||||
} NP_GLContext;
|
||||
|
||||
typedef enum {
|
||||
NPCocoaEventDrawRect = 1,
|
||||
NPCocoaEventMouseDown,
|
||||
NPCocoaEventMouseUp,
|
||||
NPCocoaEventMouseMoved,
|
||||
NPCocoaEventMouseEntered,
|
||||
NPCocoaEventMouseExited,
|
||||
NPCocoaEventMouseDragged,
|
||||
NPCocoaEventKeyDown,
|
||||
NPCocoaEventKeyUp,
|
||||
NPCocoaEventFlagsChanged,
|
||||
NPCocoaEventFocusChanged,
|
||||
NPCocoaEventWindowFocusChanged,
|
||||
NPCocoaEventScrollWheel,
|
||||
NPCocoaEventTextInput
|
||||
} NPCocoaEventType;
|
||||
|
||||
typedef struct _NPCocoaEvent {
|
||||
NPCocoaEventType type;
|
||||
uint32_t version;
|
||||
union {
|
||||
struct {
|
||||
uint32_t modifierFlags;
|
||||
double pluginX;
|
||||
double pluginY;
|
||||
int32_t buttonNumber;
|
||||
int32_t clickCount;
|
||||
double deltaX;
|
||||
double deltaY;
|
||||
double deltaZ;
|
||||
} mouse;
|
||||
struct {
|
||||
uint32_t modifierFlags;
|
||||
NPNSString *characters;
|
||||
NPNSString *charactersIgnoringModifiers;
|
||||
NPBool isARepeat;
|
||||
uint16_t keyCode;
|
||||
} key;
|
||||
struct {
|
||||
CGContextRef context;
|
||||
double x;
|
||||
double y;
|
||||
double width;
|
||||
double height;
|
||||
} draw;
|
||||
struct {
|
||||
NPBool hasFocus;
|
||||
} focus;
|
||||
struct {
|
||||
NPNSString *text;
|
||||
} text;
|
||||
} data;
|
||||
} NPCocoaEvent;
|
||||
|
||||
#ifndef NP_NO_CARBON
|
||||
/* Non-standard event types that can be passed to HandleEvent */
|
||||
enum NPEventType {
|
||||
NPEventType_GetFocusEvent = (osEvt + 16),
|
||||
NPEventType_LoseFocusEvent,
|
||||
NPEventType_AdjustCursorEvent,
|
||||
NPEventType_MenuCommandEvent,
|
||||
NPEventType_ClippingChangedEvent,
|
||||
NPEventType_ScrollingBeginsEvent = 1000,
|
||||
NPEventType_ScrollingEndsEvent
|
||||
};
|
||||
#endif /* NP_NO_CARBON */
|
||||
|
||||
#endif /* XP_MACOSX */
|
||||
|
||||
/*
|
||||
* Values for mode passed to NPP_New:
|
||||
*/
|
||||
|
|
@ -541,6 +736,12 @@ typedef enum {
|
|||
#define NP_CLEAR_ALL 0
|
||||
#define NP_CLEAR_CACHE (1 << 0)
|
||||
|
||||
#if !defined(__LP64__)
|
||||
#if defined(XP_MACOSX)
|
||||
#pragma options align=reset
|
||||
#endif
|
||||
#endif /* __LP64__ */
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Error and Reason Code definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -182,6 +182,31 @@ typedef struct _NPNetscapeFuncs {
|
|||
NPN_SetCurrentAsyncSurfacePtr setcurrentasyncsurface;
|
||||
} NPNetscapeFuncs;
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
/*
|
||||
* Mac OS X version(s) of NP_GetMIMEDescription(const char *)
|
||||
* These can be called to retreive MIME information from the plugin dynamically
|
||||
*
|
||||
* Note: For compatibility with Quicktime, BPSupportedMIMEtypes is another way
|
||||
* to get mime info from the plugin only on OSX and may not be supported
|
||||
* in furture version -- use NP_GetMIMEDescription instead
|
||||
*/
|
||||
enum
|
||||
{
|
||||
kBPSupportedMIMETypesStructVers_1 = 1
|
||||
};
|
||||
typedef struct _BPSupportedMIMETypes
|
||||
{
|
||||
SInt32 structVersion; /* struct version */
|
||||
Handle typeStrings; /* STR# formated handle, allocated by plug-in */
|
||||
Handle infoStrings; /* STR# formated handle, allocated by plug-in */
|
||||
} BPSupportedMIMETypes;
|
||||
OSErr BP_GetSupportedMIMETypes(BPSupportedMIMETypes *mimeInfo, UInt32 flags);
|
||||
#define NP_GETMIMEDESCRIPTION_NAME "NP_GetMIMEDescription"
|
||||
typedef const char* (*NP_GetMIMEDescriptionProcPtr)(void);
|
||||
typedef OSErr (*BP_GetSupportedMIMETypesProcPtr)(BPSupportedMIMETypes*, UInt32);
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define OSCALL WINAPI
|
||||
#else
|
||||
|
|
@ -226,8 +251,15 @@ typedef char* (*NP_GetPluginVersionFunc)(void);
|
|||
NP_EXPORT(char*) NP_GetPluginVersion(void);
|
||||
typedef const char* (*NP_GetMIMEDescriptionFunc)(void);
|
||||
NP_EXPORT(const char*) NP_GetMIMEDescription(void);
|
||||
#ifdef XP_MACOSX
|
||||
typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*);
|
||||
NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs);
|
||||
typedef NPError (*NP_GetEntryPointsFunc)(NPPluginFuncs*);
|
||||
NP_EXPORT(NPError) NP_GetEntryPoints(NPPluginFuncs* pFuncs);
|
||||
#else
|
||||
typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*, NPPluginFuncs*);
|
||||
NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs);
|
||||
#endif
|
||||
typedef NPError (*NP_ShutdownFunc)(void);
|
||||
NP_EXPORT(NPError) NP_Shutdown(void);
|
||||
typedef NPError (*NP_GetValueFunc)(void *, NPPVariable, void *);
|
||||
|
|
|
|||
|
|
@ -269,6 +269,14 @@ nsNPAPIPlugin::CreatePlugin(nsPluginTag *aPluginTag, nsNPAPIPlugin** aResult)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (!pluginLib->HasRequiredFunctions()) {
|
||||
NS_WARNING("Not all necessary functions exposed by plugin, it will not load.");
|
||||
delete pluginLib;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
plugin->mLibrary = pluginLib;
|
||||
pluginLib->SetPlugin(plugin);
|
||||
|
||||
|
|
@ -286,6 +294,19 @@ nsNPAPIPlugin::CreatePlugin(nsPluginTag *aPluginTag, nsNPAPIPlugin** aResult)
|
|||
if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#elif defined(XP_MACOSX)
|
||||
// NP_Initialize must be called before NP_GetEntryPoints on Mac OS X.
|
||||
// We need to match WebKit's behavior.
|
||||
NPError pluginCallError;
|
||||
nsresult rv = pluginLib->NP_Initialize(&sBrowserFuncs, &pluginCallError);
|
||||
if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
rv = pluginLib->NP_GetEntryPoints(&plugin->mPluginFuncs, &pluginCallError);
|
||||
if (rv != NS_OK || pluginCallError != NPERR_NO_ERROR) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#else
|
||||
NPError pluginCallError;
|
||||
nsresult rv = pluginLib->NP_Initialize(&sBrowserFuncs, &plugin->mPluginFuncs, &pluginCallError);
|
||||
|
|
@ -1708,7 +1729,7 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
|
|||
// cases for android_npapi.h's non-standard ANPInterface values.
|
||||
switch (static_cast<int>(variable)) {
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
case NPNVxDisplay : {
|
||||
#if defined(MOZ_X11)
|
||||
if (npp) {
|
||||
|
|
@ -1833,7 +1854,8 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
|
|||
}
|
||||
|
||||
case NPNVSupportsWindowless: {
|
||||
#if defined(XP_WIN) || (defined(MOZ_X11) && defined(MOZ_WIDGET_GTK))
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || \
|
||||
(defined(MOZ_X11) && defined(MOZ_WIDGET_GTK))
|
||||
*(NPBool*)result = true;
|
||||
#else
|
||||
*(NPBool*)result = false;
|
||||
|
|
@ -1901,7 +1923,72 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
|
|||
return *(char**)result ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#ifdef XP_MACOSX
|
||||
case NPNVpluginDrawingModel: {
|
||||
if (npp) {
|
||||
nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance*)npp->ndata;
|
||||
if (inst) {
|
||||
NPDrawingModel drawingModel;
|
||||
inst->GetDrawingModel((int32_t*)&drawingModel);
|
||||
*(NPDrawingModel*)result = drawingModel;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
}
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
#ifndef NP_NO_QUICKDRAW
|
||||
case NPNVsupportsQuickDrawBool: {
|
||||
*(NPBool*)result = false;
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
case NPNVsupportsCoreGraphicsBool: {
|
||||
*(NPBool*)result = true;
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
case NPNVsupportsCoreAnimationBool: {
|
||||
*(NPBool*)result = true;
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
case NPNVsupportsInvalidatingCoreAnimationBool: {
|
||||
*(NPBool*)result = true;
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
case NPNVsupportsCompositingCoreAnimationPluginsBool: {
|
||||
*(NPBool*)result = PR_TRUE;
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
#ifndef NP_NO_CARBON
|
||||
case NPNVsupportsCarbonBool: {
|
||||
*(NPBool*)result = false;
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
#endif
|
||||
case NPNVsupportsCocoaBool: {
|
||||
*(NPBool*)result = true;
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
case NPNVsupportsUpdatedCocoaTextInputBool: {
|
||||
*(NPBool*)result = true;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
case NPNVcontentsScaleFactor: {
|
||||
nsNPAPIPluginInstance *inst =
|
||||
(nsNPAPIPluginInstance *) (npp ? npp->ndata : nullptr);
|
||||
|
|
@ -1964,8 +2051,16 @@ _setvalue(NPP npp, NPPVariable variable, void *result)
|
|||
// actual pointer value is checked rather than its content
|
||||
// when passing booleans
|
||||
case NPPVpluginWindowBool: {
|
||||
#ifdef XP_MACOSX
|
||||
// This setting doesn't apply to OS X (only to Windows and Unix/Linux).
|
||||
// See https://developer.mozilla.org/En/NPN_SetValue#section_5. Return
|
||||
// NPERR_NO_ERROR here to conform to other browsers' behavior on OS X
|
||||
// (e.g. Safari and Opera).
|
||||
return NPERR_NO_ERROR;
|
||||
#else
|
||||
NPBool bWindowless = (result == nullptr);
|
||||
return inst->SetWindowless(bWindowless);
|
||||
#endif
|
||||
}
|
||||
case NPPVpluginTransparentBool: {
|
||||
NPBool bTransparent = (result != nullptr);
|
||||
|
|
@ -2050,6 +2145,18 @@ _setvalue(NPP npp, NPPVariable variable, void *result)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
case NPPVpluginEventModel: {
|
||||
if (inst) {
|
||||
inst->SetEventModel((NPEventModel)NS_PTR_TO_INT32(result));
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
else {
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
default:
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,10 @@ public:
|
|||
// PluginFuncs() can't fail but results are only valid if GetLibrary() succeeds
|
||||
NPPluginFuncs* PluginFuncs();
|
||||
|
||||
#if defined(XP_MACOSX) && !defined(__LP64__)
|
||||
void SetPluginRefNum(short aRefNum);
|
||||
#endif
|
||||
|
||||
// The IPC mechanism notifies the nsNPAPIPlugin if the plugin
|
||||
// crashes and is no longer usable. pluginDumpID/browserDumpID are
|
||||
// the IDs of respective minidumps that were written, or empty if no
|
||||
|
|
|
|||
|
|
@ -60,6 +60,9 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance()
|
|||
, mPlugin(nullptr)
|
||||
, mMIMEType(nullptr)
|
||||
, mOwner(nullptr)
|
||||
#ifdef XP_MACOSX
|
||||
, mCurrentPluginEvent(nullptr)
|
||||
#endif
|
||||
, mHaveJavaC2PJSObjectQuirk(false)
|
||||
, mCachedParamLength(0)
|
||||
, mCachedParamNames(nullptr)
|
||||
|
|
@ -500,6 +503,9 @@ nsresult nsNPAPIPluginInstance::HandleEvent(void* event, int16_t* result,
|
|||
int16_t tmpResult = kNPEventNotHandled;
|
||||
|
||||
if (pluginFunctions->event) {
|
||||
#ifdef XP_MACOSX
|
||||
mCurrentPluginEvent = event;
|
||||
#endif
|
||||
#if defined(XP_WIN)
|
||||
NS_TRY_SAFE_CALL_RETURN(tmpResult, (*pluginFunctions->event)(&mNPP, event), this,
|
||||
aSafeToReenterGecko);
|
||||
|
|
@ -513,6 +519,9 @@ nsresult nsNPAPIPluginInstance::HandleEvent(void* event, int16_t* result,
|
|||
|
||||
if (result)
|
||||
*result = tmpResult;
|
||||
#ifdef XP_MACOSX
|
||||
mCurrentPluginEvent = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
@ -608,6 +617,19 @@ void nsNPAPIPluginInstance::RedrawPlugin()
|
|||
mOwner->RedrawPlugin();
|
||||
}
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
void nsNPAPIPluginInstance::SetEventModel(NPEventModel aModel)
|
||||
{
|
||||
// the event model needs to be set for the object frame immediately
|
||||
if (!mOwner) {
|
||||
NS_WARNING("Trying to set event model without a plugin instance owner!");
|
||||
return;
|
||||
}
|
||||
|
||||
mOwner->SetEventModel(aModel);
|
||||
}
|
||||
#endif
|
||||
|
||||
nsresult nsNPAPIPluginInstance::GetDrawingModel(int32_t* aModel)
|
||||
{
|
||||
*aModel = (int32_t)mDrawingModel;
|
||||
|
|
@ -616,14 +638,24 @@ nsresult nsNPAPIPluginInstance::GetDrawingModel(int32_t* aModel)
|
|||
|
||||
nsresult nsNPAPIPluginInstance::IsRemoteDrawingCoreAnimation(bool* aDrawing)
|
||||
{
|
||||
/** Mac Stub **/
|
||||
#ifdef XP_MACOSX
|
||||
if (!mPlugin)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PluginLibrary* library = mPlugin->GetLibrary();
|
||||
if (!library)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return library->IsRemoteDrawingCoreAnimation(&mNPP, aDrawing);
|
||||
#else
|
||||
return NS_ERROR_FAILURE;
|
||||
#endif
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNPAPIPluginInstance::ContentsScaleFactorChanged(double aContentsScaleFactor)
|
||||
{
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
if (!mPlugin)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
|
@ -700,7 +732,12 @@ nsNPAPIPluginInstance::ShouldCache()
|
|||
nsresult
|
||||
nsNPAPIPluginInstance::IsWindowless(bool* isWindowless)
|
||||
{
|
||||
#ifdef XP_MACOSX
|
||||
// All OS X plugins are windowless.
|
||||
*isWindowless = true;
|
||||
#else
|
||||
*isWindowless = mWindowless;
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,12 @@ class nsPluginInstanceOwner;
|
|||
const NPDrawingModel kDefaultDrawingModel = NPDrawingModelSyncWin;
|
||||
#elif defined(MOZ_X11)
|
||||
const NPDrawingModel kDefaultDrawingModel = NPDrawingModelSyncX;
|
||||
#elif defined(XP_MACOSX)
|
||||
#ifndef NP_NO_QUICKDRAW
|
||||
const NPDrawingModel kDefaultDrawingModel = NPDrawingModelQuickDraw; // Not supported
|
||||
#else
|
||||
const NPDrawingModel kDefaultDrawingModel = NPDrawingModelCoreGraphics;
|
||||
#endif
|
||||
#else
|
||||
const NPDrawingModel kDefaultDrawingModel = static_cast<NPDrawingModel>(0);
|
||||
#endif
|
||||
|
|
@ -140,6 +146,13 @@ public:
|
|||
|
||||
void SetDrawingModel(NPDrawingModel aModel);
|
||||
void RedrawPlugin();
|
||||
#ifdef XP_MACOSX
|
||||
void SetEventModel(NPEventModel aModel);
|
||||
|
||||
void* GetCurrentEvent() {
|
||||
return mCurrentPluginEvent;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsresult NewStreamListener(const char* aURL, void* notifyData,
|
||||
nsNPAPIPluginStreamListener** listener);
|
||||
|
|
@ -278,6 +291,11 @@ private:
|
|||
|
||||
nsTArray<nsNPAPITimer*> mTimers;
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// non-null during a HandleEvent call
|
||||
void* mCurrentPluginEvent;
|
||||
#endif
|
||||
|
||||
// Timestamp for the last time this plugin was stopped.
|
||||
// This is only valid when the plugin is actually stopped!
|
||||
mozilla::TimeStamp mStopTime;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@
|
|||
#include "nsProtocolProxyService.h"
|
||||
#include "nsIStreamConverterService.h"
|
||||
#include "nsIFile.h"
|
||||
#if defined(XP_MACOSX)
|
||||
#include "nsILocalFileMac.h"
|
||||
#endif
|
||||
#include "nsISeekableStream.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIFileStreams.h"
|
||||
|
|
@ -1921,7 +1924,19 @@ int64_t GetPluginLastModifiedTime(const nsCOMPtr<nsIFile>& localfile)
|
|||
{
|
||||
PRTime fileModTime = 0;
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
// On OS X the date of a bundle's "contents" (i.e. of its Info.plist file)
|
||||
// is a much better guide to when it was last modified than the date of
|
||||
// its package directory. See bug 313700.
|
||||
nsCOMPtr<nsILocalFileMac> localFileMac = do_QueryInterface(localfile);
|
||||
if (localFileMac) {
|
||||
localFileMac->GetBundleContentsLastModifiedTime(&fileModTime);
|
||||
} else {
|
||||
localfile->GetLastModifiedTime(&fileModTime);
|
||||
}
|
||||
#else
|
||||
localfile->GetLastModifiedTime(&fileModTime);
|
||||
#endif
|
||||
|
||||
return fileModTime;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -19,6 +19,11 @@
|
|||
#include "nsWeakReference.h"
|
||||
#include "gfxRect.h"
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include "mozilla/gfx/QuartzSupport.h"
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#endif
|
||||
|
||||
class nsIInputStream;
|
||||
class nsPluginDOMContextMenuListener;
|
||||
class nsPluginFrame;
|
||||
|
|
@ -99,6 +104,10 @@ public:
|
|||
|
||||
#ifdef XP_WIN
|
||||
void Paint(const RECT& aDirty, HDC aDC);
|
||||
#elif defined(XP_MACOSX)
|
||||
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)
|
||||
void Paint(gfxContext* aContext,
|
||||
const gfxRect& aFrameRect,
|
||||
|
|
@ -123,11 +132,33 @@ public:
|
|||
nsresult SetNetscapeWindowAsParent(HWND aWindowToAdopt);
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
enum { ePluginPaintEnable, ePluginPaintDisable };
|
||||
|
||||
void WindowFocusMayHaveChanged();
|
||||
|
||||
bool WindowIsActive();
|
||||
void SendWindowFocusChanged(bool aIsActive);
|
||||
NPDrawingModel GetDrawingModel();
|
||||
bool IsRemoteDrawingCoreAnimation();
|
||||
|
||||
NPEventModel GetEventModel();
|
||||
static void CARefresh(nsITimer *aTimer, void *aClosure);
|
||||
void AddToCARefreshTimer();
|
||||
void RemoveFromCARefreshTimer();
|
||||
// This calls into the plugin (NPP_SetWindow) and can run script.
|
||||
void FixUpPluginWindow(int32_t inPaintState);
|
||||
void HidePluginWindow();
|
||||
// Set plugin port info in the plugin (in the 'window' member of the
|
||||
// NPWindow structure passed to the plugin by SetWindow()).
|
||||
void SetPluginPort();
|
||||
#else // XP_MACOSX
|
||||
void UpdateWindowPositionAndClipRect(bool aSetWindow);
|
||||
void UpdateWindowVisibility(bool aVisible);
|
||||
#endif // XP_MACOSX
|
||||
|
||||
void ResolutionMayHaveChanged();
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
nsresult ContentsScaleFactorChanged(double aContentsScaleFactor);
|
||||
#endif
|
||||
|
||||
|
|
@ -183,7 +214,7 @@ public:
|
|||
return mPluginWindow->type == NPWindowTypeDrawable &&
|
||||
(MatchPluginName("Shockwave Flash") ||
|
||||
MatchPluginName("Test Plug-in"));
|
||||
#elif defined(MOZ_X11)
|
||||
#elif defined(MOZ_X11) || defined(XP_MACOSX)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
|
|
@ -280,6 +311,15 @@ private:
|
|||
nsCOMPtr<nsIWidget> mWidget;
|
||||
RefPtr<nsPluginHost> mPluginHost;
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
static nsCOMPtr<nsITimer> *sCATimer;
|
||||
static nsTArray<nsPluginInstanceOwner*> *sCARefreshListeners;
|
||||
bool mSentInitialTopLevelWindowEvent;
|
||||
bool mLastWindowIsActive;
|
||||
bool mLastContentFocused;
|
||||
// True if, the next time the window is activated, we should blur ourselves.
|
||||
bool mShouldBlurOnActivate;
|
||||
#endif
|
||||
double mLastScaleFactor;
|
||||
double mLastCSSZoomFactor;
|
||||
// Initially, the event loop nesting level we were created on, it's updated
|
||||
|
|
@ -295,6 +335,15 @@ private:
|
|||
bool mPluginWindowVisible;
|
||||
bool mPluginDocumentActiveState;
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
NPEventModel mEventModel;
|
||||
// This is a hack! UseAsyncRendering() can incorrectly return false
|
||||
// when we don't have an object frame (possible as of bug 90268).
|
||||
// We hack around this by always returning true if we've ever
|
||||
// returned true.
|
||||
bool mUseAsyncRendering;
|
||||
#endif
|
||||
|
||||
// pointer to wrapper for nsIDOMContextMenuListener
|
||||
RefPtr<nsPluginDOMContextMenuListener> mCXMenuListener;
|
||||
|
||||
|
|
@ -308,6 +357,16 @@ private:
|
|||
void CallDefaultProc(const mozilla::WidgetGUIEvent* aEvent);
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
static NPBool ConvertPointPuppet(PuppetWidget *widget, nsPluginFrame* pluginFrame,
|
||||
double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
|
||||
double *destX, double *destY, NPCoordinateSpace destSpace);
|
||||
static NPBool ConvertPointNoPuppet(nsIWidget *widget, nsPluginFrame* pluginFrame,
|
||||
double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
|
||||
double *destX, double *destY, NPCoordinateSpace destSpace);
|
||||
void PerformDelayedBlurs();
|
||||
#endif // XP_MACOSX
|
||||
|
||||
int mLastMouseDownButtonType;
|
||||
|
||||
#ifdef MOZ_X11
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ nsPluginNativeWindowPLATFORM::nsPluginNativeWindowPLATFORM() : nsPluginNativeWin
|
|||
width = 0;
|
||||
height = 0;
|
||||
memset(&clipRect, 0, sizeof(clipRect));
|
||||
#if defined(XP_UNIX)
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
ws_info = nullptr;
|
||||
#endif
|
||||
type = NPWindowTypeWindow;
|
||||
|
|
|
|||
|
|
@ -424,7 +424,7 @@ void nsPluginTag::InitMime(const char* const* aMimeTypes,
|
|||
}
|
||||
}
|
||||
|
||||
#if !defined(XP_WIN)
|
||||
#if !defined(XP_WIN) && !defined(XP_MACOSX)
|
||||
static nsresult ConvertToUTF8(nsIUnicodeDecoder *aUnicodeDecoder,
|
||||
nsAFlatCString& aString)
|
||||
{
|
||||
|
|
@ -448,7 +448,7 @@ static nsresult ConvertToUTF8(nsIUnicodeDecoder *aUnicodeDecoder,
|
|||
|
||||
nsresult nsPluginTag::EnsureMembersAreUTF8()
|
||||
{
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX)
|
||||
return NS_OK;
|
||||
#else
|
||||
nsresult rv;
|
||||
|
|
|
|||
572
dom/plugins/base/nsPluginsDirDarwin.cpp
Normal file
572
dom/plugins/base/nsPluginsDirDarwin.cpp
Normal file
|
|
@ -0,0 +1,572 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
nsPluginsDirDarwin.cpp
|
||||
|
||||
Mac OS X implementation of the nsPluginsDir/nsPluginsFile classes.
|
||||
|
||||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#include "GeckoChildProcessHost.h"
|
||||
#include "base/process_util.h"
|
||||
|
||||
#include "prlink.h"
|
||||
#include "prnetdb.h"
|
||||
#include "nsXPCOM.h"
|
||||
|
||||
#include "nsPluginsDir.h"
|
||||
#include "nsNPAPIPlugin.h"
|
||||
#include "nsPluginsDirUtils.h"
|
||||
|
||||
#include "nsILocalFileMac.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#include "nsCocoaFeatures.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#include <mach-o/loader.h>
|
||||
#include <mach-o/fat.h>
|
||||
|
||||
typedef NS_NPAPIPLUGIN_CALLBACK(const char *, NP_GETMIMEDESCRIPTION) ();
|
||||
typedef NS_NPAPIPLUGIN_CALLBACK(OSErr, BP_GETSUPPORTEDMIMETYPES) (BPSupportedMIMETypes *mimeInfo, UInt32 flags);
|
||||
|
||||
/*
|
||||
** Returns a CFBundleRef if the path refers to a Mac OS X bundle directory.
|
||||
** The caller is responsible for calling CFRelease() to deallocate.
|
||||
*/
|
||||
static CFBundleRef getPluginBundle(const char* path)
|
||||
{
|
||||
CFBundleRef bundle = nullptr;
|
||||
CFStringRef pathRef = ::CFStringCreateWithCString(nullptr, path,
|
||||
kCFStringEncodingUTF8);
|
||||
if (pathRef) {
|
||||
CFURLRef bundleURL = ::CFURLCreateWithFileSystemPath(nullptr, pathRef,
|
||||
kCFURLPOSIXPathStyle,
|
||||
true);
|
||||
if (bundleURL) {
|
||||
bundle = ::CFBundleCreate(nullptr, bundleURL);
|
||||
::CFRelease(bundleURL);
|
||||
}
|
||||
::CFRelease(pathRef);
|
||||
}
|
||||
return bundle;
|
||||
}
|
||||
|
||||
static nsresult toCFURLRef(nsIFile* file, CFURLRef& outURL)
|
||||
{
|
||||
nsCOMPtr<nsILocalFileMac> lfm = do_QueryInterface(file);
|
||||
if (!lfm)
|
||||
return NS_ERROR_FAILURE;
|
||||
CFURLRef url;
|
||||
nsresult rv = lfm->GetCFURL(&url);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
outURL = url;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool nsPluginsDir::IsPluginFile(nsIFile* file)
|
||||
{
|
||||
nsCString fileName;
|
||||
file->GetNativeLeafName(fileName);
|
||||
/*
|
||||
* Don't load the VDP fake plugin, to avoid tripping a bad bug in OS X
|
||||
* 10.5.3 (see bug 436575).
|
||||
*/
|
||||
if (!strcmp(fileName.get(), "VerifiedDownloadPlugin.plugin")) {
|
||||
NS_WARNING("Preventing load of VerifiedDownloadPlugin.plugin (see bug 436575)");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Caller is responsible for freeing returned buffer.
|
||||
static char* CFStringRefToUTF8Buffer(CFStringRef cfString)
|
||||
{
|
||||
const char* buffer = ::CFStringGetCStringPtr(cfString, kCFStringEncodingUTF8);
|
||||
if (buffer) {
|
||||
return PL_strdup(buffer);
|
||||
}
|
||||
|
||||
int bufferLength =
|
||||
::CFStringGetMaximumSizeForEncoding(::CFStringGetLength(cfString),
|
||||
kCFStringEncodingUTF8) + 1;
|
||||
char* newBuffer = static_cast<char*>(moz_xmalloc(bufferLength));
|
||||
if (!newBuffer) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!::CFStringGetCString(cfString, newBuffer, bufferLength,
|
||||
kCFStringEncodingUTF8)) {
|
||||
free(newBuffer);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
newBuffer = static_cast<char*>(moz_xrealloc(newBuffer,
|
||||
strlen(newBuffer) + 1));
|
||||
return newBuffer;
|
||||
}
|
||||
|
||||
class AutoCFTypeObject {
|
||||
public:
|
||||
explicit AutoCFTypeObject(CFTypeRef aObject)
|
||||
{
|
||||
mObject = aObject;
|
||||
}
|
||||
~AutoCFTypeObject()
|
||||
{
|
||||
::CFRelease(mObject);
|
||||
}
|
||||
private:
|
||||
CFTypeRef mObject;
|
||||
};
|
||||
|
||||
static Boolean MimeTypeEnabled(CFDictionaryRef mimeDict) {
|
||||
if (!mimeDict) {
|
||||
return true;
|
||||
}
|
||||
|
||||
CFTypeRef value;
|
||||
if (::CFDictionaryGetValueIfPresent(mimeDict, CFSTR("WebPluginTypeEnabled"), &value)) {
|
||||
if (value && ::CFGetTypeID(value) == ::CFBooleanGetTypeID()) {
|
||||
return ::CFBooleanGetValue(static_cast<CFBooleanRef>(value));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static CFDictionaryRef ParsePlistForMIMETypesFilename(CFBundleRef bundle)
|
||||
{
|
||||
CFTypeRef mimeFileName = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginMIMETypesFilename"));
|
||||
if (!mimeFileName || ::CFGetTypeID(mimeFileName) != ::CFStringGetTypeID()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FSRef homeDir;
|
||||
if (::FSFindFolder(kUserDomain, kCurrentUserFolderType, kDontCreateFolder, &homeDir) != noErr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CFURLRef userDirURL = ::CFURLCreateFromFSRef(kCFAllocatorDefault, &homeDir);
|
||||
if (!userDirURL) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AutoCFTypeObject userDirURLAutorelease(userDirURL);
|
||||
CFStringRef mimeFilePath = ::CFStringCreateWithFormat(kCFAllocatorDefault, nullptr, CFSTR("Library/Preferences/%@"), static_cast<CFStringRef>(mimeFileName));
|
||||
if (!mimeFilePath) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AutoCFTypeObject mimeFilePathAutorelease(mimeFilePath);
|
||||
CFURLRef mimeFileURL = ::CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorDefault, mimeFilePath, kCFURLPOSIXPathStyle, false, userDirURL);
|
||||
if (!mimeFileURL) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AutoCFTypeObject mimeFileURLAutorelease(mimeFileURL);
|
||||
SInt32 errorCode = 0;
|
||||
CFDataRef mimeFileData = nullptr;
|
||||
Boolean result = ::CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, mimeFileURL, &mimeFileData, nullptr, nullptr, &errorCode);
|
||||
if (!result) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AutoCFTypeObject mimeFileDataAutorelease(mimeFileData);
|
||||
if (errorCode != 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CFPropertyListRef propertyList = ::CFPropertyListCreateFromXMLData(kCFAllocatorDefault, mimeFileData, kCFPropertyListImmutable, nullptr);
|
||||
if (!propertyList) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AutoCFTypeObject propertyListAutorelease(propertyList);
|
||||
if (::CFGetTypeID(propertyList) != ::CFDictionaryGetTypeID()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CFTypeRef mimeTypes = ::CFDictionaryGetValue(static_cast<CFDictionaryRef>(propertyList), CFSTR("WebPluginMIMETypes"));
|
||||
if (!mimeTypes || ::CFGetTypeID(mimeTypes) != ::CFDictionaryGetTypeID() || ::CFDictionaryGetCount(static_cast<CFDictionaryRef>(mimeTypes)) == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return static_cast<CFDictionaryRef>(::CFRetain(mimeTypes));
|
||||
}
|
||||
|
||||
static void ParsePlistPluginInfo(nsPluginInfo& info, CFBundleRef bundle)
|
||||
{
|
||||
CFDictionaryRef mimeDict = ParsePlistForMIMETypesFilename(bundle);
|
||||
|
||||
if (!mimeDict) {
|
||||
CFTypeRef mimeTypes = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginMIMETypes"));
|
||||
if (!mimeTypes || ::CFGetTypeID(mimeTypes) != ::CFDictionaryGetTypeID() || ::CFDictionaryGetCount(static_cast<CFDictionaryRef>(mimeTypes)) == 0)
|
||||
return;
|
||||
mimeDict = static_cast<CFDictionaryRef>(::CFRetain(mimeTypes));
|
||||
}
|
||||
|
||||
AutoCFTypeObject mimeDictAutorelease(mimeDict);
|
||||
int mimeDictKeyCount = ::CFDictionaryGetCount(mimeDict);
|
||||
|
||||
// Allocate memory for mime data
|
||||
int mimeDataArraySize = mimeDictKeyCount * sizeof(char*);
|
||||
info.fMimeTypeArray = static_cast<char**>(moz_xmalloc(mimeDataArraySize));
|
||||
if (!info.fMimeTypeArray)
|
||||
return;
|
||||
memset(info.fMimeTypeArray, 0, mimeDataArraySize);
|
||||
info.fExtensionArray = static_cast<char**>(moz_xmalloc(mimeDataArraySize));
|
||||
if (!info.fExtensionArray)
|
||||
return;
|
||||
memset(info.fExtensionArray, 0, mimeDataArraySize);
|
||||
info.fMimeDescriptionArray = static_cast<char**>(moz_xmalloc(mimeDataArraySize));
|
||||
if (!info.fMimeDescriptionArray)
|
||||
return;
|
||||
memset(info.fMimeDescriptionArray, 0, mimeDataArraySize);
|
||||
|
||||
// Allocate memory for mime dictionary keys and values
|
||||
mozilla::UniquePtr<CFTypeRef[]> keys(new CFTypeRef[mimeDictKeyCount]);
|
||||
if (!keys)
|
||||
return;
|
||||
mozilla::UniquePtr<CFTypeRef[]> values(new CFTypeRef[mimeDictKeyCount]);
|
||||
if (!values)
|
||||
return;
|
||||
|
||||
info.fVariantCount = 0;
|
||||
|
||||
::CFDictionaryGetKeysAndValues(mimeDict, keys.get(), values.get());
|
||||
for (int i = 0; i < mimeDictKeyCount; i++) {
|
||||
CFTypeRef mimeString = keys[i];
|
||||
if (!mimeString || ::CFGetTypeID(mimeString) != ::CFStringGetTypeID()) {
|
||||
continue;
|
||||
}
|
||||
CFTypeRef mimeDict = values[i];
|
||||
if (mimeDict && ::CFGetTypeID(mimeDict) == ::CFDictionaryGetTypeID()) {
|
||||
if (!MimeTypeEnabled(static_cast<CFDictionaryRef>(mimeDict))) {
|
||||
continue;
|
||||
}
|
||||
info.fMimeTypeArray[info.fVariantCount] = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(mimeString));
|
||||
if (!info.fMimeTypeArray[info.fVariantCount]) {
|
||||
continue;
|
||||
}
|
||||
CFTypeRef extensions = ::CFDictionaryGetValue(static_cast<CFDictionaryRef>(mimeDict), CFSTR("WebPluginExtensions"));
|
||||
if (extensions && ::CFGetTypeID(extensions) == ::CFArrayGetTypeID()) {
|
||||
int extensionCount = ::CFArrayGetCount(static_cast<CFArrayRef>(extensions));
|
||||
CFMutableStringRef extensionList = ::CFStringCreateMutable(kCFAllocatorDefault, 0);
|
||||
for (int j = 0; j < extensionCount; j++) {
|
||||
CFTypeRef extension = ::CFArrayGetValueAtIndex(static_cast<CFArrayRef>(extensions), j);
|
||||
if (extension && ::CFGetTypeID(extension) == ::CFStringGetTypeID()) {
|
||||
if (j > 0)
|
||||
::CFStringAppend(extensionList, CFSTR(","));
|
||||
::CFStringAppend(static_cast<CFMutableStringRef>(extensionList), static_cast<CFStringRef>(extension));
|
||||
}
|
||||
}
|
||||
info.fExtensionArray[info.fVariantCount] = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(extensionList));
|
||||
::CFRelease(extensionList);
|
||||
}
|
||||
CFTypeRef description = ::CFDictionaryGetValue(static_cast<CFDictionaryRef>(mimeDict), CFSTR("WebPluginTypeDescription"));
|
||||
if (description && ::CFGetTypeID(description) == ::CFStringGetTypeID())
|
||||
info.fMimeDescriptionArray[info.fVariantCount] = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(description));
|
||||
}
|
||||
info.fVariantCount++;
|
||||
}
|
||||
}
|
||||
|
||||
nsPluginFile::nsPluginFile(nsIFile *spec)
|
||||
: mPlugin(spec)
|
||||
{
|
||||
}
|
||||
|
||||
nsPluginFile::~nsPluginFile() {}
|
||||
|
||||
nsresult nsPluginFile::LoadPlugin(PRLibrary **outLibrary)
|
||||
{
|
||||
if (!mPlugin)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
// 64-bit NSPR does not (yet) support bundles. So in 64-bit builds we need
|
||||
// (for now) to load the bundle's executable. However this can cause
|
||||
// problems: CFBundleCreate() doesn't run the bundle's executable's
|
||||
// initialization code, while NSAddImage() and dlopen() do run it. So using
|
||||
// NSPR's dyld loading mechanisms here (NSAddImage() or dlopen()) can cause
|
||||
// a bundle's initialization code to run earlier than expected, and lead to
|
||||
// crashes. See bug 577967.
|
||||
#ifdef __LP64__
|
||||
char executablePath[PATH_MAX];
|
||||
executablePath[0] = '\0';
|
||||
nsAutoCString bundlePath;
|
||||
mPlugin->GetNativePath(bundlePath);
|
||||
CFStringRef pathRef = ::CFStringCreateWithCString(nullptr, bundlePath.get(),
|
||||
kCFStringEncodingUTF8);
|
||||
if (pathRef) {
|
||||
CFURLRef bundleURL = ::CFURLCreateWithFileSystemPath(nullptr, pathRef,
|
||||
kCFURLPOSIXPathStyle,
|
||||
true);
|
||||
if (bundleURL) {
|
||||
CFBundleRef bundle = ::CFBundleCreate(nullptr, bundleURL);
|
||||
if (bundle) {
|
||||
CFURLRef executableURL = ::CFBundleCopyExecutableURL(bundle);
|
||||
if (executableURL) {
|
||||
if (!::CFURLGetFileSystemRepresentation(executableURL, true, (UInt8*)&executablePath, PATH_MAX))
|
||||
executablePath[0] = '\0';
|
||||
::CFRelease(executableURL);
|
||||
}
|
||||
::CFRelease(bundle);
|
||||
}
|
||||
::CFRelease(bundleURL);
|
||||
}
|
||||
::CFRelease(pathRef);
|
||||
}
|
||||
#else
|
||||
nsAutoCString bundlePath;
|
||||
mPlugin->GetNativePath(bundlePath);
|
||||
const char *executablePath = bundlePath.get();
|
||||
#endif
|
||||
|
||||
*outLibrary = PR_LoadLibrary(executablePath);
|
||||
pLibrary = *outLibrary;
|
||||
if (!pLibrary) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("[loaded plugin %s]\n", bundlePath.get());
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static char* p2cstrdup(StringPtr pstr)
|
||||
{
|
||||
int len = pstr[0];
|
||||
char* cstr = static_cast<char*>(moz_xmalloc(len + 1));
|
||||
if (cstr) {
|
||||
memmove(cstr, pstr + 1, len);
|
||||
cstr[len] = '\0';
|
||||
}
|
||||
return cstr;
|
||||
}
|
||||
|
||||
static char* GetNextPluginStringFromHandle(Handle h, short *index)
|
||||
{
|
||||
char *ret = p2cstrdup((unsigned char*)(*h + *index));
|
||||
*index += (ret ? strlen(ret) : 0) + 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool IsCompatibleArch(nsIFile *file)
|
||||
{
|
||||
CFURLRef pluginURL = nullptr;
|
||||
if (NS_FAILED(toCFURLRef(file, pluginURL)))
|
||||
return false;
|
||||
|
||||
bool isPluginFile = false;
|
||||
|
||||
CFBundleRef pluginBundle = ::CFBundleCreate(kCFAllocatorDefault, pluginURL);
|
||||
if (pluginBundle) {
|
||||
UInt32 packageType, packageCreator;
|
||||
::CFBundleGetPackageInfo(pluginBundle, &packageType, &packageCreator);
|
||||
if (packageType == 'BRPL' || packageType == 'IEPL' || packageType == 'NSPL') {
|
||||
// Get path to plugin as a C string.
|
||||
char executablePath[PATH_MAX];
|
||||
executablePath[0] = '\0';
|
||||
if (!::CFURLGetFileSystemRepresentation(pluginURL, true, (UInt8*)&executablePath, PATH_MAX)) {
|
||||
executablePath[0] = '\0';
|
||||
}
|
||||
|
||||
uint32_t pluginLibArchitectures;
|
||||
nsresult rv = mozilla::ipc::GeckoChildProcessHost::GetArchitecturesForBinary(executablePath, &pluginLibArchitectures);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t supportedArchitectures =
|
||||
#ifdef __LP64__
|
||||
mozilla::ipc::GeckoChildProcessHost::GetSupportedArchitecturesForProcessType(GeckoProcessType_Plugin);
|
||||
#else
|
||||
base::GetCurrentProcessArchitecture();
|
||||
#endif
|
||||
|
||||
// Consider the plugin architecture valid if there is any overlap in the masks.
|
||||
isPluginFile = !!(supportedArchitectures & pluginLibArchitectures);
|
||||
}
|
||||
::CFRelease(pluginBundle);
|
||||
}
|
||||
|
||||
::CFRelease(pluginURL);
|
||||
return isPluginFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains all of the information currently available for this plugin.
|
||||
*/
|
||||
nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary)
|
||||
{
|
||||
*outLibrary = nullptr;
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (!IsCompatibleArch(mPlugin)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// clear out the info, except for the first field.
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
// Try to get a bundle reference.
|
||||
nsAutoCString path;
|
||||
if (NS_FAILED(rv = mPlugin->GetNativePath(path)))
|
||||
return rv;
|
||||
CFBundleRef bundle = getPluginBundle(path.get());
|
||||
|
||||
// fill in full path
|
||||
info.fFullPath = PL_strdup(path.get());
|
||||
|
||||
// fill in file name
|
||||
nsAutoCString fileName;
|
||||
if (NS_FAILED(rv = mPlugin->GetNativeLeafName(fileName)))
|
||||
return rv;
|
||||
info.fFileName = PL_strdup(fileName.get());
|
||||
|
||||
// Get fName
|
||||
if (bundle) {
|
||||
CFTypeRef name = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginName"));
|
||||
if (name && ::CFGetTypeID(name) == ::CFStringGetTypeID())
|
||||
info.fName = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(name));
|
||||
}
|
||||
|
||||
// Get fDescription
|
||||
if (bundle) {
|
||||
CFTypeRef description = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginDescription"));
|
||||
if (description && ::CFGetTypeID(description) == ::CFStringGetTypeID())
|
||||
info.fDescription = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(description));
|
||||
}
|
||||
|
||||
// Get fVersion
|
||||
if (bundle) {
|
||||
// Look for the release version first
|
||||
CFTypeRef version = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("CFBundleShortVersionString"));
|
||||
if (!version) // try the build version
|
||||
version = ::CFBundleGetValueForInfoDictionaryKey(bundle, kCFBundleVersionKey);
|
||||
if (version && ::CFGetTypeID(version) == ::CFStringGetTypeID())
|
||||
info.fVersion = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(version));
|
||||
}
|
||||
|
||||
// The last thing we need to do is get MIME data
|
||||
// fVariantCount, fMimeTypeArray, fExtensionArray, fMimeDescriptionArray
|
||||
|
||||
// First look for data in a bundle plist
|
||||
if (bundle) {
|
||||
ParsePlistPluginInfo(info, bundle);
|
||||
::CFRelease(bundle);
|
||||
if (info.fVariantCount > 0)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Don't load "fbplugin" or any plugins whose name starts with "fbplugin_"
|
||||
// (Facebook plugins) if we're running on OS X 10.10 (Yosemite) or later.
|
||||
// A "fbplugin" file crashes on load, in the call to LoadPlugin() below.
|
||||
// See bug 1086977.
|
||||
if (nsCocoaFeatures::OnYosemiteOrLater()) {
|
||||
if (fileName.EqualsLiteral("fbplugin") ||
|
||||
StringBeginsWith(fileName, NS_LITERAL_CSTRING("fbplugin_"))) {
|
||||
nsAutoCString msg;
|
||||
msg.AppendPrintf("Preventing load of %s (see bug 1086977)",
|
||||
fileName.get());
|
||||
NS_WARNING(msg.get());
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// It's possible that our plugin has 2 entry points that'll give us mime type
|
||||
// info. Quicktime does this to get around the need of having admin rights to
|
||||
// change mime info in the resource fork. We need to use this info instead of
|
||||
// the resource. See bug 113464.
|
||||
|
||||
// Sadly we have to load the library for this to work.
|
||||
rv = LoadPlugin(outLibrary);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// Try to get data from NP_GetMIMEDescription
|
||||
if (pLibrary) {
|
||||
NP_GETMIMEDESCRIPTION pfnGetMimeDesc = (NP_GETMIMEDESCRIPTION)PR_FindFunctionSymbol(pLibrary, NP_GETMIMEDESCRIPTION_NAME);
|
||||
if (pfnGetMimeDesc)
|
||||
ParsePluginMimeDescription(pfnGetMimeDesc(), info);
|
||||
if (info.fVariantCount)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We'll fill this in using BP_GetSupportedMIMETypes and/or resource fork data
|
||||
BPSupportedMIMETypes mi = {kBPSupportedMIMETypesStructVers_1, nullptr, nullptr};
|
||||
|
||||
// Try to get data from BP_GetSupportedMIMETypes
|
||||
if (pLibrary) {
|
||||
BP_GETSUPPORTEDMIMETYPES pfnMime = (BP_GETSUPPORTEDMIMETYPES)PR_FindFunctionSymbol(pLibrary, "BP_GetSupportedMIMETypes");
|
||||
if (pfnMime && noErr == pfnMime(&mi, 0) && mi.typeStrings) {
|
||||
info.fVariantCount = (**(short**)mi.typeStrings) / 2;
|
||||
::HLock(mi.typeStrings);
|
||||
if (mi.infoStrings) // it's possible some plugins have infoStrings missing
|
||||
::HLock(mi.infoStrings);
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in the info struct based on the data in the BPSupportedMIMETypes struct
|
||||
int variantCount = info.fVariantCount;
|
||||
info.fMimeTypeArray = static_cast<char**>(moz_xmalloc(variantCount * sizeof(char*)));
|
||||
if (!info.fMimeTypeArray)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
info.fExtensionArray = static_cast<char**>(moz_xmalloc(variantCount * sizeof(char*)));
|
||||
if (!info.fExtensionArray)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
if (mi.infoStrings) {
|
||||
info.fMimeDescriptionArray = static_cast<char**>(moz_xmalloc(variantCount * sizeof(char*)));
|
||||
if (!info.fMimeDescriptionArray)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
short mimeIndex = 2;
|
||||
short descriptionIndex = 2;
|
||||
for (int i = 0; i < variantCount; i++) {
|
||||
info.fMimeTypeArray[i] = GetNextPluginStringFromHandle(mi.typeStrings, &mimeIndex);
|
||||
info.fExtensionArray[i] = GetNextPluginStringFromHandle(mi.typeStrings, &mimeIndex);
|
||||
if (mi.infoStrings)
|
||||
info.fMimeDescriptionArray[i] = GetNextPluginStringFromHandle(mi.infoStrings, &descriptionIndex);
|
||||
}
|
||||
|
||||
::HUnlock(mi.typeStrings);
|
||||
::DisposeHandle(mi.typeStrings);
|
||||
if (mi.infoStrings) {
|
||||
::HUnlock(mi.infoStrings);
|
||||
::DisposeHandle(mi.infoStrings);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsPluginFile::FreePluginInfo(nsPluginInfo& info)
|
||||
{
|
||||
free(info.fName);
|
||||
free(info.fDescription);
|
||||
int variantCount = info.fVariantCount;
|
||||
for (int i = 0; i < variantCount; i++) {
|
||||
free(info.fMimeTypeArray[i]);
|
||||
free(info.fExtensionArray[i]);
|
||||
free(info.fMimeDescriptionArray[i]);
|
||||
}
|
||||
free(info.fMimeTypeArray);
|
||||
free(info.fMimeDescriptionArray);
|
||||
free(info.fExtensionArray);
|
||||
free(info.fFileName);
|
||||
free(info.fFullPath);
|
||||
free(info.fVersion);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
193
dom/plugins/ipc/NPEventOSX.h
Normal file
193
dom/plugins/ipc/NPEventOSX.h
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_plugins_NPEventOSX_h
|
||||
#define mozilla_dom_plugins_NPEventOSX_h 1
|
||||
|
||||
|
||||
#include "npapi.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace plugins {
|
||||
|
||||
struct NPRemoteEvent {
|
||||
NPCocoaEvent event;
|
||||
double contentsScaleFactor;
|
||||
};
|
||||
|
||||
} // namespace plugins
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
namespace IPC {
|
||||
|
||||
template <>
|
||||
struct ParamTraits<mozilla::plugins::NPRemoteEvent>
|
||||
{
|
||||
typedef mozilla::plugins::NPRemoteEvent paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
aMsg->WriteInt(aParam.event.type);
|
||||
aMsg->WriteUInt32(aParam.event.version);
|
||||
switch (aParam.event.type) {
|
||||
case NPCocoaEventMouseDown:
|
||||
case NPCocoaEventMouseUp:
|
||||
case NPCocoaEventMouseMoved:
|
||||
case NPCocoaEventMouseEntered:
|
||||
case NPCocoaEventMouseExited:
|
||||
case NPCocoaEventMouseDragged:
|
||||
case NPCocoaEventScrollWheel:
|
||||
aMsg->WriteUInt32(aParam.event.data.mouse.modifierFlags);
|
||||
aMsg->WriteDouble(aParam.event.data.mouse.pluginX);
|
||||
aMsg->WriteDouble(aParam.event.data.mouse.pluginY);
|
||||
aMsg->WriteInt32(aParam.event.data.mouse.buttonNumber);
|
||||
aMsg->WriteInt32(aParam.event.data.mouse.clickCount);
|
||||
aMsg->WriteDouble(aParam.event.data.mouse.deltaX);
|
||||
aMsg->WriteDouble(aParam.event.data.mouse.deltaY);
|
||||
aMsg->WriteDouble(aParam.event.data.mouse.deltaZ);
|
||||
break;
|
||||
case NPCocoaEventKeyDown:
|
||||
case NPCocoaEventKeyUp:
|
||||
case NPCocoaEventFlagsChanged:
|
||||
aMsg->WriteUInt32(aParam.event.data.key.modifierFlags);
|
||||
WriteParam(aMsg, aParam.event.data.key.characters);
|
||||
WriteParam(aMsg, aParam.event.data.key.charactersIgnoringModifiers);
|
||||
aMsg->WriteUnsignedChar(aParam.event.data.key.isARepeat);
|
||||
aMsg->WriteUInt16(aParam.event.data.key.keyCode);
|
||||
break;
|
||||
case NPCocoaEventFocusChanged:
|
||||
case NPCocoaEventWindowFocusChanged:
|
||||
aMsg->WriteUnsignedChar(aParam.event.data.focus.hasFocus);
|
||||
break;
|
||||
case NPCocoaEventDrawRect:
|
||||
// We don't write out the context pointer, it would always be
|
||||
// nullptr and is just filled in as such on the read.
|
||||
aMsg->WriteDouble(aParam.event.data.draw.x);
|
||||
aMsg->WriteDouble(aParam.event.data.draw.y);
|
||||
aMsg->WriteDouble(aParam.event.data.draw.width);
|
||||
aMsg->WriteDouble(aParam.event.data.draw.height);
|
||||
break;
|
||||
case NPCocoaEventTextInput:
|
||||
WriteParam(aMsg, aParam.event.data.text.text);
|
||||
break;
|
||||
default:
|
||||
NS_NOTREACHED("Attempted to serialize unknown event type.");
|
||||
return;
|
||||
}
|
||||
aMsg->WriteDouble(aParam.contentsScaleFactor);
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
|
||||
{
|
||||
int type = 0;
|
||||
if (!aMsg->ReadInt(aIter, &type)) {
|
||||
return false;
|
||||
}
|
||||
aResult->event.type = static_cast<NPCocoaEventType>(type);
|
||||
|
||||
if (!aMsg->ReadUInt32(aIter, &aResult->event.version)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (aResult->event.type) {
|
||||
case NPCocoaEventMouseDown:
|
||||
case NPCocoaEventMouseUp:
|
||||
case NPCocoaEventMouseMoved:
|
||||
case NPCocoaEventMouseEntered:
|
||||
case NPCocoaEventMouseExited:
|
||||
case NPCocoaEventMouseDragged:
|
||||
case NPCocoaEventScrollWheel:
|
||||
if (!aMsg->ReadUInt32(aIter, &aResult->event.data.mouse.modifierFlags)) {
|
||||
return false;
|
||||
}
|
||||
if (!aMsg->ReadDouble(aIter, &aResult->event.data.mouse.pluginX)) {
|
||||
return false;
|
||||
}
|
||||
if (!aMsg->ReadDouble(aIter, &aResult->event.data.mouse.pluginY)) {
|
||||
return false;
|
||||
}
|
||||
if (!aMsg->ReadInt32(aIter, &aResult->event.data.mouse.buttonNumber)) {
|
||||
return false;
|
||||
}
|
||||
if (!aMsg->ReadInt32(aIter, &aResult->event.data.mouse.clickCount)) {
|
||||
return false;
|
||||
}
|
||||
if (!aMsg->ReadDouble(aIter, &aResult->event.data.mouse.deltaX)) {
|
||||
return false;
|
||||
}
|
||||
if (!aMsg->ReadDouble(aIter, &aResult->event.data.mouse.deltaY)) {
|
||||
return false;
|
||||
}
|
||||
if (!aMsg->ReadDouble(aIter, &aResult->event.data.mouse.deltaZ)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case NPCocoaEventKeyDown:
|
||||
case NPCocoaEventKeyUp:
|
||||
case NPCocoaEventFlagsChanged:
|
||||
if (!aMsg->ReadUInt32(aIter, &aResult->event.data.key.modifierFlags)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadParam(aMsg, aIter, &aResult->event.data.key.characters)) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadParam(aMsg, aIter, &aResult->event.data.key.charactersIgnoringModifiers)) {
|
||||
return false;
|
||||
}
|
||||
if (!aMsg->ReadUnsignedChar(aIter, &aResult->event.data.key.isARepeat)) {
|
||||
return false;
|
||||
}
|
||||
if (!aMsg->ReadUInt16(aIter, &aResult->event.data.key.keyCode)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case NPCocoaEventFocusChanged:
|
||||
case NPCocoaEventWindowFocusChanged:
|
||||
if (!aMsg->ReadUnsignedChar(aIter, &aResult->event.data.focus.hasFocus)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case NPCocoaEventDrawRect:
|
||||
aResult->event.data.draw.context = nullptr;
|
||||
if (!aMsg->ReadDouble(aIter, &aResult->event.data.draw.x)) {
|
||||
return false;
|
||||
}
|
||||
if (!aMsg->ReadDouble(aIter, &aResult->event.data.draw.y)) {
|
||||
return false;
|
||||
}
|
||||
if (!aMsg->ReadDouble(aIter, &aResult->event.data.draw.width)) {
|
||||
return false;
|
||||
}
|
||||
if (!aMsg->ReadDouble(aIter, &aResult->event.data.draw.height)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case NPCocoaEventTextInput:
|
||||
if (!ReadParam(aMsg, aIter, &aResult->event.data.text.text)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NS_NOTREACHED("Attempted to de-serialize unknown event type.");
|
||||
return false;
|
||||
}
|
||||
if (!aMsg->ReadDouble(aIter, &aResult->contentsScaleFactor)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void Log(const paramType& aParam, std::wstring* aLog)
|
||||
{
|
||||
aLog->append(L"(NPCocoaEvent)");
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace IPC
|
||||
|
||||
#endif // ifndef mozilla_dom_plugins_NPEventOSX_h
|
||||
|
|
@ -103,7 +103,11 @@ using mozilla::gfx::SharedDIB;
|
|||
const int kFlashWMUSERMessageThrottleDelayMs = 5;
|
||||
|
||||
static const TCHAR kPluginIgnoreSubclassProperty[] = TEXT("PluginIgnoreSubclassProperty");
|
||||
#endif
|
||||
|
||||
#elif defined(XP_MACOSX)
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#include "PluginUtilsOSX.h"
|
||||
#endif // defined(XP_MACOSX)
|
||||
|
||||
/**
|
||||
* We can't use gfxPlatform::CreateDrawTargetForSurface() because calling
|
||||
|
|
@ -137,7 +141,7 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface,
|
|||
, mMode(aMode)
|
||||
, mNames(aNames)
|
||||
, mValues(aValues)
|
||||
#if defined (XP_WIN)
|
||||
#if defined(XP_DARWIN) || defined (XP_WIN)
|
||||
, mContentsScaleFactor(1.0)
|
||||
#endif
|
||||
, mPostingKeyEvents(0)
|
||||
|
|
@ -194,7 +198,7 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface,
|
|||
mWindow.type = NPWindowTypeWindow;
|
||||
mData.ndata = (void*) this;
|
||||
mData.pdata = nullptr;
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX)
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
mWindow.ws_info = &mWsInfo;
|
||||
memset(&mWsInfo, 0, sizeof(mWsInfo));
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
|
|
@ -203,7 +207,7 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface,
|
|||
#else
|
||||
mWsInfo.display = DefaultXDisplay();
|
||||
#endif
|
||||
#endif // MOZ_X11 && XP_UNIX
|
||||
#endif // MOZ_X11 && XP_UNIX && !XP_MACOSX
|
||||
#if defined(OS_WIN)
|
||||
InitPopupMenuHook();
|
||||
if (GetQuirks() & QUIRK_UNITY_FIXUP_MOUSE_CAPTURE) {
|
||||
|
|
@ -270,6 +274,23 @@ PluginInstanceChild::DoNPP_New()
|
|||
|
||||
Initialize();
|
||||
|
||||
#if defined(XP_MACOSX) && defined(__i386__)
|
||||
// If an i386 Mac OS X plugin has selected the Carbon event model then
|
||||
// we have to fail. We do not support putting Carbon event model plugins
|
||||
// out of process. Note that Carbon is the default model so out of process
|
||||
// plugins need to actively negotiate something else in order to work
|
||||
// out of process.
|
||||
if (EventModel() == NPEventModelCarbon) {
|
||||
// Send notification that a plugin tried to negotiate Carbon NPAPI so that
|
||||
// users can be notified that restarting the browser in i386 mode may allow
|
||||
// them to use the plugin.
|
||||
SendNegotiatedCarbon();
|
||||
|
||||
// Fail to instantiate.
|
||||
rv = NPERR_MODULE_LOAD_FAILED_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
@ -477,12 +498,58 @@ PluginInstanceChild::NPN_GetValue(NPNVariable aVar,
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#ifdef XP_MACOSX
|
||||
case NPNVsupportsCoreGraphicsBool: {
|
||||
*((NPBool*)aValue) = true;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
case NPNVsupportsCoreAnimationBool: {
|
||||
*((NPBool*)aValue) = true;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
case NPNVsupportsInvalidatingCoreAnimationBool: {
|
||||
*((NPBool*)aValue) = true;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
case NPNVsupportsCompositingCoreAnimationPluginsBool: {
|
||||
*((NPBool*)aValue) = true;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
case NPNVsupportsCocoaBool: {
|
||||
*((NPBool*)aValue) = true;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
#ifndef NP_NO_CARBON
|
||||
case NPNVsupportsCarbonBool: {
|
||||
*((NPBool*)aValue) = false;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
case NPNVsupportsUpdatedCocoaTextInputBool: {
|
||||
*static_cast<NPBool*>(aValue) = true;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
#ifndef NP_NO_QUICKDRAW
|
||||
case NPNVsupportsQuickDrawBool: {
|
||||
*((NPBool*)aValue) = false;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
#endif /* NP_NO_QUICKDRAW */
|
||||
#endif /* XP_MACOSX */
|
||||
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
case NPNVcontentsScaleFactor: {
|
||||
*static_cast<double*>(aValue) = mContentsScaleFactor;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
#endif /* defined(XP_WIN) */
|
||||
#endif /* defined(XP_MACOSX) || defined(XP_WIN) */
|
||||
|
||||
case NPNVCSSZoomFactor: {
|
||||
*static_cast<double*>(aValue) = mCSSZoomFactor;
|
||||
|
|
@ -587,12 +654,36 @@ PluginInstanceChild::NPN_SetValue(NPPVariable aVar, void* aValue)
|
|||
|
||||
mDrawingModel = drawingModel;
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (drawingModel == NPDrawingModelCoreAnimation) {
|
||||
mCARefreshTimer = ScheduleTimer(DEFAULT_REFRESH_MS, true, CAUpdate);
|
||||
}
|
||||
#endif
|
||||
|
||||
PLUGIN_LOG_DEBUG((" Plugin requested drawing model id #%i\n",
|
||||
mDrawingModel));
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
case NPPVpluginEventModel: {
|
||||
NPError rv;
|
||||
int eventModel = (int16_t) (intptr_t) aValue;
|
||||
|
||||
if (!CallNPN_SetValue_NPPVpluginEventModel(eventModel, &rv))
|
||||
return NPERR_GENERIC_ERROR;
|
||||
#if defined(__i386__)
|
||||
mEventModel = static_cast<NPEventModel>(eventModel);
|
||||
#endif
|
||||
|
||||
PLUGIN_LOG_DEBUG((" Plugin requested event model id # %i\n",
|
||||
eventModel));
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
case NPPVpluginIsPlayingAudio: {
|
||||
NPError rv = NPERR_GENERIC_ERROR;
|
||||
if (!CallNPN_SetValue_NPPVpluginIsPlayingAudio((NPBool)(intptr_t)aValue, &rv)) {
|
||||
|
|
@ -816,10 +907,21 @@ PluginInstanceChild::AnswerNPP_HandleEvent(const NPRemoteEvent& event,
|
|||
event.event.xgraphicsexpose.drawable));
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// Mac OS X does not define an NPEvent structure. It defines more specific types.
|
||||
NPCocoaEvent evcopy = event.event;
|
||||
|
||||
// Make sure we reset mCurrentEvent in case of an exception
|
||||
AutoRestore<const NPCocoaEvent*> savePreviousEvent(mCurrentEvent);
|
||||
|
||||
// Track the current event for NPN_PopUpContextMenu.
|
||||
mCurrentEvent = &event.event;
|
||||
#else
|
||||
// Make a copy since we may modify values.
|
||||
NPEvent evcopy = event.event;
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
// event.contentsScaleFactor <= 0 is a signal we shouldn't use it,
|
||||
// for example when AnswerNPP_HandleEvent() is called from elsewhere
|
||||
// in the child process (not via rpc code from the parent process).
|
||||
|
|
@ -845,6 +947,18 @@ PluginInstanceChild::AnswerNPP_HandleEvent(const NPRemoteEvent& event,
|
|||
else
|
||||
*handled = mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy));
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// Release any reference counted objects created in the child process.
|
||||
if (evcopy.type == NPCocoaEventKeyDown ||
|
||||
evcopy.type == NPCocoaEventKeyUp) {
|
||||
::CFRelease((CFStringRef)evcopy.data.key.characters);
|
||||
::CFRelease((CFStringRef)evcopy.data.key.charactersIgnoringModifiers);
|
||||
}
|
||||
else if (evcopy.type == NPCocoaEventTextInput) {
|
||||
::CFRelease((CFStringRef)evcopy.data.text.text);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_X11
|
||||
if (GraphicsExpose == event.event.type) {
|
||||
// Make sure the X server completes the drawing before the parent
|
||||
|
|
@ -861,6 +975,73 @@ PluginInstanceChild::AnswerNPP_HandleEvent(const NPRemoteEvent& event,
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
|
||||
bool
|
||||
PluginInstanceChild::AnswerNPP_HandleEvent_Shmem(const NPRemoteEvent& event,
|
||||
Shmem&& mem,
|
||||
int16_t* handled,
|
||||
Shmem* rtnmem)
|
||||
{
|
||||
PLUGIN_LOG_DEBUG_FUNCTION;
|
||||
AssertPluginThread();
|
||||
AutoStackHelper guard(this);
|
||||
|
||||
PaintTracker pt;
|
||||
|
||||
NPCocoaEvent evcopy = event.event;
|
||||
mContentsScaleFactor = event.contentsScaleFactor;
|
||||
|
||||
if (evcopy.type == NPCocoaEventDrawRect) {
|
||||
int scaleFactor = ceil(mContentsScaleFactor);
|
||||
if (!mShColorSpace) {
|
||||
mShColorSpace = CreateSystemColorSpace();
|
||||
if (!mShColorSpace) {
|
||||
PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
|
||||
*handled = false;
|
||||
*rtnmem = mem;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!mShContext) {
|
||||
void* cgContextByte = mem.get<char>();
|
||||
mShContext = ::CGBitmapContextCreate(cgContextByte,
|
||||
mWindow.width * scaleFactor,
|
||||
mWindow.height * scaleFactor, 8,
|
||||
mWindow.width * 4 * scaleFactor, mShColorSpace,
|
||||
kCGImageAlphaPremultipliedFirst |
|
||||
kCGBitmapByteOrder32Host);
|
||||
|
||||
if (!mShContext) {
|
||||
PLUGIN_LOG_DEBUG(("Could not allocate CGBitmapContext."));
|
||||
*handled = false;
|
||||
*rtnmem = mem;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
CGRect clearRect = ::CGRectMake(0, 0, mWindow.width, mWindow.height);
|
||||
::CGContextClearRect(mShContext, clearRect);
|
||||
evcopy.data.draw.context = mShContext;
|
||||
} else {
|
||||
PLUGIN_LOG_DEBUG(("Invalid event type for AnswerNNP_HandleEvent_Shmem."));
|
||||
*handled = false;
|
||||
*rtnmem = mem;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!mPluginIface->event) {
|
||||
*handled = false;
|
||||
} else {
|
||||
::CGContextSaveGState(evcopy.data.draw.context);
|
||||
*handled = mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy));
|
||||
::CGContextRestoreGState(evcopy.data.draw.context);
|
||||
}
|
||||
|
||||
*rtnmem = mem;
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
bool
|
||||
PluginInstanceChild::AnswerNPP_HandleEvent_Shmem(const NPRemoteEvent& event,
|
||||
Shmem&& mem,
|
||||
|
|
@ -871,7 +1052,101 @@ PluginInstanceChild::AnswerNPP_HandleEvent_Shmem(const NPRemoteEvent& event,
|
|||
*rtnmem = mem;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
|
||||
void CallCGDraw(CGContextRef ref, void* aPluginInstance, nsIntRect aUpdateRect) {
|
||||
PluginInstanceChild* pluginInstance = (PluginInstanceChild*)aPluginInstance;
|
||||
|
||||
pluginInstance->CGDraw(ref, aUpdateRect);
|
||||
}
|
||||
|
||||
bool
|
||||
PluginInstanceChild::CGDraw(CGContextRef ref, nsIntRect aUpdateRect) {
|
||||
|
||||
NPCocoaEvent drawEvent;
|
||||
drawEvent.type = NPCocoaEventDrawRect;
|
||||
drawEvent.version = 0;
|
||||
drawEvent.data.draw.x = aUpdateRect.x;
|
||||
drawEvent.data.draw.y = aUpdateRect.y;
|
||||
drawEvent.data.draw.width = aUpdateRect.width;
|
||||
drawEvent.data.draw.height = aUpdateRect.height;
|
||||
drawEvent.data.draw.context = ref;
|
||||
|
||||
NPRemoteEvent remoteDrawEvent = {drawEvent};
|
||||
// Signal to AnswerNPP_HandleEvent() not to use this value
|
||||
remoteDrawEvent.contentsScaleFactor = -1.0;
|
||||
|
||||
int16_t handled;
|
||||
AnswerNPP_HandleEvent(remoteDrawEvent, &handled);
|
||||
return handled == true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginInstanceChild::AnswerNPP_HandleEvent_IOSurface(const NPRemoteEvent& event,
|
||||
const uint32_t &surfaceid,
|
||||
int16_t* handled)
|
||||
{
|
||||
PLUGIN_LOG_DEBUG_FUNCTION;
|
||||
AssertPluginThread();
|
||||
AutoStackHelper guard(this);
|
||||
|
||||
PaintTracker pt;
|
||||
|
||||
NPCocoaEvent evcopy = event.event;
|
||||
mContentsScaleFactor = event.contentsScaleFactor;
|
||||
RefPtr<MacIOSurface> surf = MacIOSurface::LookupSurface(surfaceid,
|
||||
mContentsScaleFactor);
|
||||
if (!surf) {
|
||||
NS_ERROR("Invalid IOSurface.");
|
||||
*handled = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mCARenderer) {
|
||||
mCARenderer = new nsCARenderer();
|
||||
}
|
||||
|
||||
if (evcopy.type == NPCocoaEventDrawRect) {
|
||||
mCARenderer->AttachIOSurface(surf);
|
||||
if (!mCARenderer->isInit()) {
|
||||
void *caLayer = nullptr;
|
||||
NPError result = mPluginIface->getvalue(GetNPP(),
|
||||
NPPVpluginCoreAnimationLayer,
|
||||
&caLayer);
|
||||
|
||||
if (result != NPERR_NO_ERROR || !caLayer) {
|
||||
PLUGIN_LOG_DEBUG(("Plugin requested CoreAnimation but did not "
|
||||
"provide CALayer."));
|
||||
*handled = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
mCARenderer->SetupRenderer(caLayer, mWindow.width, mWindow.height,
|
||||
mContentsScaleFactor,
|
||||
GetQuirks() & QUIRK_ALLOW_OFFLINE_RENDERER ?
|
||||
ALLOW_OFFLINE_RENDERER : DISALLOW_OFFLINE_RENDERER);
|
||||
|
||||
// Flash needs to have the window set again after this step
|
||||
if (mPluginIface->setwindow)
|
||||
(void) mPluginIface->setwindow(&mData, &mWindow);
|
||||
}
|
||||
} else {
|
||||
PLUGIN_LOG_DEBUG(("Invalid event type for "
|
||||
"AnswerNNP_HandleEvent_IOSurface."));
|
||||
*handled = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
mCARenderer->Render(mWindow.width, mWindow.height,
|
||||
mContentsScaleFactor, nullptr);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
bool
|
||||
PluginInstanceChild::AnswerNPP_HandleEvent_IOSurface(const NPRemoteEvent& event,
|
||||
const uint32_t &surfaceid,
|
||||
|
|
@ -880,6 +1155,7 @@ PluginInstanceChild::AnswerNPP_HandleEvent_IOSurface(const NPRemoteEvent& event,
|
|||
NS_RUNTIMEABORT("NPP_HandleEvent_IOSurface is a OSX-only message");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
PluginInstanceChild::RecvWindowPosChanged(const NPRemoteEvent& event)
|
||||
|
|
@ -899,16 +1175,24 @@ PluginInstanceChild::RecvWindowPosChanged(const NPRemoteEvent& event)
|
|||
bool
|
||||
PluginInstanceChild::RecvContentsScaleFactorChanged(const double& aContentsScaleFactor)
|
||||
{
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
mContentsScaleFactor = aContentsScaleFactor;
|
||||
#if defined(XP_MACOSX)
|
||||
if (mShContext) {
|
||||
// Release the shared context so that it is reallocated
|
||||
// with the new size.
|
||||
::CGContextRelease(mShContext);
|
||||
mShContext = nullptr;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
#else
|
||||
NS_RUNTIMEABORT("ContentsScaleFactorChanged is a Windows-only message");
|
||||
NS_RUNTIMEABORT("ContentsScaleFactorChanged is an Windows or OSX only message");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX)
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
// Create a new window from NPWindow
|
||||
bool PluginInstanceChild::CreateWindow(const NPRemoteWindow& aWindow)
|
||||
{
|
||||
|
|
@ -1006,7 +1290,7 @@ PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow)
|
|||
AssertPluginThread();
|
||||
AutoStackHelper guard(this);
|
||||
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX)
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
NS_ASSERTION(mWsInfo.display, "We should have a valid display!");
|
||||
|
||||
// The minimum info is sent over IPC to allow this
|
||||
|
|
@ -1123,6 +1407,26 @@ PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow)
|
|||
break;
|
||||
}
|
||||
|
||||
#elif defined(XP_MACOSX)
|
||||
|
||||
mWindow.x = aWindow.x;
|
||||
mWindow.y = aWindow.y;
|
||||
mWindow.width = aWindow.width;
|
||||
mWindow.height = aWindow.height;
|
||||
mWindow.clipRect = aWindow.clipRect;
|
||||
mWindow.type = aWindow.type;
|
||||
mContentsScaleFactor = aWindow.contentsScaleFactor;
|
||||
|
||||
if (mShContext) {
|
||||
// Release the shared context so that it is reallocated
|
||||
// with the new size.
|
||||
::CGContextRelease(mShContext);
|
||||
mShContext = nullptr;
|
||||
}
|
||||
|
||||
if (mPluginIface->setwindow)
|
||||
(void) mPluginIface->setwindow(&mData, &mWindow);
|
||||
|
||||
#elif defined(MOZ_WIDGET_UIKIT)
|
||||
// Don't care
|
||||
#else
|
||||
|
|
@ -3068,7 +3372,7 @@ PluginInstanceChild::DoAsyncSetWindow(const gfxSurfaceType& aSurfaceType,
|
|||
mWindow.height = aWindow.height;
|
||||
mWindow.clipRect = aWindow.clipRect;
|
||||
mWindow.type = aWindow.type;
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
mContentsScaleFactor = aWindow.contentsScaleFactor;
|
||||
#endif
|
||||
|
||||
|
|
@ -3216,6 +3520,7 @@ PluginInstanceChild::MaybeCreatePlatformHelperSurface(void)
|
|||
bool
|
||||
PluginInstanceChild::EnsureCurrentBuffer(void)
|
||||
{
|
||||
#ifndef XP_DARWIN
|
||||
nsIntRect toInvalidate(0, 0, 0, 0);
|
||||
IntSize winSize = IntSize(mWindow.width, mWindow.height);
|
||||
|
||||
|
|
@ -3259,6 +3564,61 @@ PluginInstanceChild::EnsureCurrentBuffer(void)
|
|||
NS_ERROR("Cannot create helper surface");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
#elif defined(XP_MACOSX)
|
||||
|
||||
if (!mDoubleBufferCARenderer.HasCALayer()) {
|
||||
void *caLayer = nullptr;
|
||||
if (mDrawingModel == NPDrawingModelCoreGraphics) {
|
||||
if (!mCGLayer) {
|
||||
caLayer = mozilla::plugins::PluginUtilsOSX::GetCGLayer(CallCGDraw,
|
||||
this,
|
||||
mContentsScaleFactor);
|
||||
|
||||
if (!caLayer) {
|
||||
PLUGIN_LOG_DEBUG(("GetCGLayer failed."));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
mCGLayer = caLayer;
|
||||
} else {
|
||||
NPError result = mPluginIface->getvalue(GetNPP(),
|
||||
NPPVpluginCoreAnimationLayer,
|
||||
&caLayer);
|
||||
if (result != NPERR_NO_ERROR || !caLayer) {
|
||||
PLUGIN_LOG_DEBUG(("Plugin requested CoreAnimation but did not "
|
||||
"provide CALayer."));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
mDoubleBufferCARenderer.SetCALayer(caLayer);
|
||||
}
|
||||
|
||||
if (mDoubleBufferCARenderer.HasFrontSurface() &&
|
||||
(mDoubleBufferCARenderer.GetFrontSurfaceWidth() != mWindow.width ||
|
||||
mDoubleBufferCARenderer.GetFrontSurfaceHeight() != mWindow.height ||
|
||||
mDoubleBufferCARenderer.GetContentsScaleFactor() != mContentsScaleFactor)) {
|
||||
mDoubleBufferCARenderer.ClearFrontSurface();
|
||||
}
|
||||
|
||||
if (!mDoubleBufferCARenderer.HasFrontSurface()) {
|
||||
bool allocSurface = mDoubleBufferCARenderer.InitFrontSurface(
|
||||
mWindow.width, mWindow.height, mContentsScaleFactor,
|
||||
GetQuirks() & QUIRK_ALLOW_OFFLINE_RENDERER ?
|
||||
ALLOW_OFFLINE_RENDERER : DISALLOW_OFFLINE_RENDERER);
|
||||
if (!allocSurface) {
|
||||
PLUGIN_LOG_DEBUG(("Fail to allocate front IOSurface"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mPluginIface->setwindow)
|
||||
(void) mPluginIface->setwindow(&mData, &mWindow);
|
||||
|
||||
nsIntRect toInvalidate(0, 0, mWindow.width, mWindow.height);
|
||||
mAccumulatedInvalidRect.UnionRect(mAccumulatedInvalidRect, toInvalidate);
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -3302,6 +3662,8 @@ PluginInstanceChild::UpdateWindowAttributes(bool aForceSetWindow)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifndef XP_MACOSX
|
||||
// Adjusting the window isn't needed for OSX
|
||||
#ifndef XP_WIN
|
||||
// On Windows, we translate the device context, in order for the window
|
||||
// origin to be correct.
|
||||
|
|
@ -3322,6 +3684,7 @@ PluginInstanceChild::UpdateWindowAttributes(bool aForceSetWindow)
|
|||
mWindow.clipRect.right = clipRect.XMost();
|
||||
mWindow.clipRect.bottom = clipRect.YMost();
|
||||
}
|
||||
#endif // XP_MACOSX
|
||||
|
||||
#ifdef XP_WIN
|
||||
// Windowless plugins on Windows need a WM_WINDOWPOSCHANGED event to update
|
||||
|
|
@ -4292,7 +4655,7 @@ PluginInstanceChild::Destroy()
|
|||
xt_client_xloop_destroy();
|
||||
}
|
||||
#endif
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX)
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
DeleteWindow();
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ protected:
|
|||
virtual bool
|
||||
RecvNPP_DidComposite() override;
|
||||
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX)
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
bool CreateWindow(const NPRemoteWindow& aWindow);
|
||||
void DeleteWindow();
|
||||
#endif
|
||||
|
|
@ -414,7 +414,7 @@ private:
|
|||
InfallibleTArray<nsCString> mValues;
|
||||
NPP_t mData;
|
||||
NPWindow mWindow;
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_DARWIN) || defined(XP_WIN)
|
||||
double mContentsScaleFactor;
|
||||
#endif
|
||||
double mCSSZoomFactor;
|
||||
|
|
@ -456,7 +456,7 @@ private:
|
|||
PluginScriptableObjectChild* mCachedWindowActor;
|
||||
PluginScriptableObjectChild* mCachedElementActor;
|
||||
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX)
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
NPSetWindowCallbackStruct mWsInfo;
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
bool mXEmbed;
|
||||
|
|
@ -520,10 +520,15 @@ private:
|
|||
bool CanPaintOnBackground();
|
||||
|
||||
bool IsVisible() {
|
||||
#ifdef XP_MACOSX
|
||||
return mWindow.clipRect.top != mWindow.clipRect.bottom &&
|
||||
mWindow.clipRect.left != mWindow.clipRect.right;
|
||||
#else
|
||||
return mWindow.clipRect.top != 0 ||
|
||||
mWindow.clipRect.left != 0 ||
|
||||
mWindow.clipRect.bottom != 0 ||
|
||||
mWindow.clipRect.right != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ShowPluginFrame - in general does four things:
|
||||
|
|
@ -604,6 +609,12 @@ private:
|
|||
// surface which is on ParentProcess side
|
||||
RefPtr<gfxASurface> mBackSurface;
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// Current IOSurface available for rendering
|
||||
// We can't use thebes gfxASurface like other platforms.
|
||||
PluginUtilsOSX::nsDoubleBufferCARenderer mDoubleBufferCARenderer;
|
||||
#endif
|
||||
|
||||
// (Not to be confused with mBackSurface). This is a recent copy
|
||||
// of the opaque pixels under our object frame, if
|
||||
// |mIsTransparent|. We ask the plugin render directly onto a
|
||||
|
|
|
|||
|
|
@ -50,6 +50,10 @@
|
|||
# include "mozilla/layers/TextureD3D11.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include "MacIOSurfaceImage.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <windowsx.h>
|
||||
#include "gfxWindowsPlatform.h"
|
||||
|
|
@ -63,7 +67,9 @@ extern const wchar_t* kFlashFullscreenClass;
|
|||
#elif defined(MOZ_WIDGET_GTK)
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include <gdk/gdk.h>
|
||||
#endif
|
||||
#elif defined(XP_MACOSX)
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#endif // defined(XP_MACOSX)
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::plugins;
|
||||
|
|
@ -128,6 +134,11 @@ PluginInstanceParent::PluginInstanceParent(PluginModuleParent* parent,
|
|||
, mPluginWndProc(nullptr)
|
||||
, mNestedEventState(false)
|
||||
#endif // defined(XP_WIN)
|
||||
#if defined(XP_MACOSX)
|
||||
, mShWidth(0)
|
||||
, mShHeight(0)
|
||||
, mShColorSpace(nullptr)
|
||||
#endif
|
||||
{
|
||||
#if defined(OS_WIN)
|
||||
if (!sPluginInstanceList) {
|
||||
|
|
@ -256,6 +267,8 @@ PluginInstanceParent::AnswerNPN_GetValue_NPNVnetscapeWindow(NativeWindowHandle*
|
|||
HWND id;
|
||||
#elif defined(MOZ_X11)
|
||||
XID id;
|
||||
#elif defined(XP_DARWIN)
|
||||
intptr_t id;
|
||||
#else
|
||||
#warning Implement me
|
||||
#endif
|
||||
|
|
@ -445,7 +458,14 @@ PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginDrawingModel(
|
|||
bool allowed = false;
|
||||
|
||||
switch (drawingModel) {
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_MACOSX)
|
||||
case NPDrawingModelCoreAnimation:
|
||||
case NPDrawingModelInvalidatingCoreAnimation:
|
||||
case NPDrawingModelOpenGL:
|
||||
case NPDrawingModelCoreGraphics:
|
||||
allowed = true;
|
||||
break;
|
||||
#elif defined(XP_WIN)
|
||||
case NPDrawingModelSyncWin:
|
||||
allowed = true;
|
||||
break;
|
||||
|
|
@ -474,6 +494,16 @@ PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginDrawingModel(
|
|||
|
||||
int requestModel = drawingModel;
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (drawingModel == NPDrawingModelCoreAnimation ||
|
||||
drawingModel == NPDrawingModelInvalidatingCoreAnimation) {
|
||||
// We need to request CoreGraphics otherwise
|
||||
// the nsPluginFrame will try to draw a CALayer
|
||||
// that can not be shared across process.
|
||||
requestModel = NPDrawingModelCoreGraphics;
|
||||
}
|
||||
#endif
|
||||
|
||||
*result = mNPNIface->setvalue(mNPP, NPPVpluginDrawingModel,
|
||||
(void*)(intptr_t)requestModel);
|
||||
|
||||
|
|
@ -484,8 +514,14 @@ bool
|
|||
PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginEventModel(
|
||||
const int& eventModel, NPError* result)
|
||||
{
|
||||
#ifdef XP_MACOSX
|
||||
*result = mNPNIface->setvalue(mNPP, NPPVpluginEventModel,
|
||||
(void*)(intptr_t)eventModel);
|
||||
return true;
|
||||
#else
|
||||
*result = NPERR_GENERIC_ERROR;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -839,6 +875,35 @@ PluginInstanceParent::RecvShow(const NPRect& updatedRect,
|
|||
}
|
||||
surface = gfxSharedImageSurface::Open(newSurface.get_Shmem());
|
||||
}
|
||||
#ifdef XP_MACOSX
|
||||
else if (newSurface.type() == SurfaceDescriptor::TIOSurfaceDescriptor) {
|
||||
IOSurfaceDescriptor iodesc = newSurface.get_IOSurfaceDescriptor();
|
||||
|
||||
RefPtr<MacIOSurface> newIOSurface =
|
||||
MacIOSurface::LookupSurface(iodesc.surfaceId(),
|
||||
iodesc.contentsScaleFactor());
|
||||
|
||||
if (!newIOSurface) {
|
||||
NS_WARNING("Got bad IOSurfaceDescriptor in RecvShow");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mFrontIOSurface)
|
||||
*prevSurface = IOSurfaceDescriptor(mFrontIOSurface->GetIOSurfaceID(),
|
||||
mFrontIOSurface->GetContentsScaleFactor());
|
||||
else
|
||||
*prevSurface = null_t();
|
||||
|
||||
mFrontIOSurface = newIOSurface;
|
||||
|
||||
RecvNPN_InvalidateRect(updatedRect);
|
||||
|
||||
PLUGIN_LOG_DEBUG((" (RecvShow invalidated for surface %p)",
|
||||
mFrontSurface.get()));
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#ifdef MOZ_X11
|
||||
else if (newSurface.type() == SurfaceDescriptor::TSurfaceDescriptorX11) {
|
||||
surface = newSurface.get_SurfaceDescriptorX11().OpenForeign();
|
||||
|
|
@ -920,7 +985,7 @@ PluginInstanceParent::AsyncSetWindow(NPWindow* aWindow)
|
|||
window.height = aWindow->height;
|
||||
window.clipRect = aWindow->clipRect;
|
||||
window.type = aWindow->type;
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
double scaleFactor = 1.0;
|
||||
mNPNIface->getvalue(mNPP, NPNVcontentsScaleFactor, &scaleFactor);
|
||||
window.contentsScaleFactor = scaleFactor;
|
||||
|
|
@ -950,7 +1015,19 @@ PluginInstanceParent::GetImageContainer(ImageContainer** aContainer)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
MacIOSurface* ioSurface = nullptr;
|
||||
|
||||
if (mFrontIOSurface) {
|
||||
ioSurface = mFrontIOSurface;
|
||||
} else if (mIOSurface) {
|
||||
ioSurface = mIOSurface;
|
||||
}
|
||||
|
||||
if (!mFrontSurface && !ioSurface)
|
||||
#else
|
||||
if (!mFrontSurface)
|
||||
#endif
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
ImageContainer *container = GetImageContainer();
|
||||
|
|
@ -959,6 +1036,17 @@ PluginInstanceParent::GetImageContainer(ImageContainer** aContainer)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (ioSurface) {
|
||||
RefPtr<Image> image = new MacIOSurfaceImage(ioSurface);
|
||||
container->SetCurrentImageInTransaction(image);
|
||||
|
||||
NS_IF_ADDREF(container);
|
||||
*aContainer = container;
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IF_ADDREF(container);
|
||||
*aContainer = container;
|
||||
return NS_OK;
|
||||
|
|
@ -981,6 +1069,16 @@ PluginInstanceParent::GetImageSize(nsIntSize* aSize)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (mFrontIOSurface) {
|
||||
*aSize = nsIntSize(mFrontIOSurface->GetWidth(), mFrontIOSurface->GetHeight());
|
||||
return NS_OK;
|
||||
} else if (mIOSurface) {
|
||||
*aSize = nsIntSize(mIOSurface->GetWidth(), mIOSurface->GetHeight());
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
|
|
@ -993,14 +1091,23 @@ PluginInstanceParent::DidComposite()
|
|||
Unused << SendNPP_DidComposite();
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#ifdef XP_MACOSX
|
||||
nsresult
|
||||
PluginInstanceParent::IsRemoteDrawingCoreAnimation(bool *aDrawing)
|
||||
{
|
||||
*aDrawing = (NPDrawingModelCoreAnimation == (NPDrawingModel)mDrawingModel ||
|
||||
NPDrawingModelInvalidatingCoreAnimation == (NPDrawingModel)mDrawingModel);
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
nsresult
|
||||
PluginInstanceParent::ContentsScaleFactorChanged(double aContentsScaleFactor)
|
||||
{
|
||||
bool rv = SendContentsScaleFactorChanged(aContentsScaleFactor);
|
||||
return rv ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
#endif // #ifdef XP_WIN
|
||||
#endif // #ifdef XP_MACOSX
|
||||
|
||||
nsresult
|
||||
PluginInstanceParent::SetBackgroundUnknown()
|
||||
|
|
@ -1252,14 +1359,40 @@ PluginInstanceParent::NPP_SetWindow(const NPWindow* aWindow)
|
|||
window.type = aWindow->type;
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
double floatScaleFactor = 1.0;
|
||||
mNPNIface->getvalue(mNPP, NPNVcontentsScaleFactor, &floatScaleFactor);
|
||||
int scaleFactor = ceil(floatScaleFactor);
|
||||
window.contentsScaleFactor = floatScaleFactor;
|
||||
#endif
|
||||
#if defined(XP_MACOSX)
|
||||
if (mShWidth != window.width * scaleFactor || mShHeight != window.height * scaleFactor) {
|
||||
if (mDrawingModel == NPDrawingModelCoreAnimation ||
|
||||
mDrawingModel == NPDrawingModelInvalidatingCoreAnimation) {
|
||||
mIOSurface = MacIOSurface::CreateIOSurface(window.width, window.height,
|
||||
floatScaleFactor);
|
||||
} else if (uint32_t(mShWidth * mShHeight) !=
|
||||
window.width * scaleFactor * window.height * scaleFactor) {
|
||||
if (mShWidth != 0 && mShHeight != 0) {
|
||||
DeallocShmem(mShSurface);
|
||||
mShWidth = 0;
|
||||
mShHeight = 0;
|
||||
}
|
||||
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX)
|
||||
if (window.width != 0 && window.height != 0) {
|
||||
if (!AllocShmem(window.width * scaleFactor * window.height*4 * scaleFactor,
|
||||
SharedMemory::TYPE_BASIC, &mShSurface)) {
|
||||
PLUGIN_LOG_DEBUG(("Shared memory could not be allocated."));
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
mShWidth = window.width * scaleFactor;
|
||||
mShHeight = window.height * scaleFactor;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
const NPSetWindowCallbackStruct* ws_info =
|
||||
static_cast<NPSetWindowCallbackStruct*>(aWindow->ws_info);
|
||||
window.visualID = ws_info->visual ? ws_info->visual->visualid : 0;
|
||||
|
|
@ -1419,10 +1552,14 @@ PluginInstanceParent::NPP_HandleEvent(void* event)
|
|||
{
|
||||
PLUGIN_LOG_DEBUG_FUNCTION;
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
NPCocoaEvent* npevent = reinterpret_cast<NPCocoaEvent*>(event);
|
||||
#else
|
||||
NPEvent* npevent = reinterpret_cast<NPEvent*>(event);
|
||||
#endif
|
||||
NPRemoteEvent npremoteevent;
|
||||
npremoteevent.event = *npevent;
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
double scaleFactor = 1.0;
|
||||
mNPNIface->getvalue(mNPP, NPNVcontentsScaleFactor, &scaleFactor);
|
||||
npremoteevent.contentsScaleFactor = scaleFactor;
|
||||
|
|
@ -1512,6 +1649,111 @@ PluginInstanceParent::NPP_HandleEvent(void* event)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (npevent->type == NPCocoaEventDrawRect) {
|
||||
if (mDrawingModel == NPDrawingModelCoreAnimation ||
|
||||
mDrawingModel == NPDrawingModelInvalidatingCoreAnimation) {
|
||||
if (!mIOSurface) {
|
||||
NS_ERROR("No IOSurface allocated.");
|
||||
return false;
|
||||
}
|
||||
if (!CallNPP_HandleEvent_IOSurface(npremoteevent,
|
||||
mIOSurface->GetIOSurfaceID(),
|
||||
&handled))
|
||||
return false; // no good way to handle errors here...
|
||||
|
||||
CGContextRef cgContext = npevent->data.draw.context;
|
||||
if (!mShColorSpace) {
|
||||
mShColorSpace = CreateSystemColorSpace();
|
||||
}
|
||||
if (!mShColorSpace) {
|
||||
PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
|
||||
return false;
|
||||
}
|
||||
if (cgContext) {
|
||||
nsCARenderer::DrawSurfaceToCGContext(cgContext, mIOSurface,
|
||||
mShColorSpace,
|
||||
npevent->data.draw.x,
|
||||
npevent->data.draw.y,
|
||||
npevent->data.draw.width,
|
||||
npevent->data.draw.height);
|
||||
}
|
||||
return true;
|
||||
} else if (mFrontIOSurface) {
|
||||
CGContextRef cgContext = npevent->data.draw.context;
|
||||
if (!mShColorSpace) {
|
||||
mShColorSpace = CreateSystemColorSpace();
|
||||
}
|
||||
if (!mShColorSpace) {
|
||||
PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
|
||||
return false;
|
||||
}
|
||||
if (cgContext) {
|
||||
nsCARenderer::DrawSurfaceToCGContext(cgContext, mFrontIOSurface,
|
||||
mShColorSpace,
|
||||
npevent->data.draw.x,
|
||||
npevent->data.draw.y,
|
||||
npevent->data.draw.width,
|
||||
npevent->data.draw.height);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
if (mShWidth == 0 && mShHeight == 0) {
|
||||
PLUGIN_LOG_DEBUG(("NPCocoaEventDrawRect on window of size 0."));
|
||||
return false;
|
||||
}
|
||||
if (!mShSurface.IsReadable()) {
|
||||
PLUGIN_LOG_DEBUG(("Shmem is not readable."));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CallNPP_HandleEvent_Shmem(npremoteevent, mShSurface,
|
||||
&handled, &mShSurface))
|
||||
return false; // no good way to handle errors here...
|
||||
|
||||
if (!mShSurface.IsReadable()) {
|
||||
PLUGIN_LOG_DEBUG(("Shmem not returned. Either the plugin crashed "
|
||||
"or we have a bug."));
|
||||
return false;
|
||||
}
|
||||
|
||||
char* shContextByte = mShSurface.get<char>();
|
||||
|
||||
if (!mShColorSpace) {
|
||||
mShColorSpace = CreateSystemColorSpace();
|
||||
}
|
||||
if (!mShColorSpace) {
|
||||
PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
|
||||
return false;
|
||||
}
|
||||
CGContextRef shContext = ::CGBitmapContextCreate(shContextByte,
|
||||
mShWidth, mShHeight, 8,
|
||||
mShWidth*4, mShColorSpace,
|
||||
kCGImageAlphaPremultipliedFirst |
|
||||
kCGBitmapByteOrder32Host);
|
||||
if (!shContext) {
|
||||
PLUGIN_LOG_DEBUG(("Could not allocate CGBitmapContext."));
|
||||
return false;
|
||||
}
|
||||
|
||||
CGImageRef shImage = ::CGBitmapContextCreateImage(shContext);
|
||||
if (shImage) {
|
||||
CGContextRef cgContext = npevent->data.draw.context;
|
||||
|
||||
::CGContextDrawImage(cgContext,
|
||||
CGRectMake(0,0,mShWidth,mShHeight),
|
||||
shImage);
|
||||
::CGImageRelease(shImage);
|
||||
} else {
|
||||
::CGContextRelease(shContext);
|
||||
return false;
|
||||
}
|
||||
::CGContextRelease(shContext);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!CallNPP_HandleEvent(npremoteevent, &handled))
|
||||
return 0; // no good way to handle errors here...
|
||||
|
||||
|
|
|
|||
|
|
@ -321,7 +321,10 @@ public:
|
|||
nsresult AsyncSetWindow(NPWindow* window);
|
||||
nsresult GetImageContainer(mozilla::layers::ImageContainer** aContainer);
|
||||
nsresult GetImageSize(nsIntSize* aSize);
|
||||
#if defined(XP_WIN)
|
||||
#ifdef XP_MACOSX
|
||||
nsresult IsRemoteDrawingCoreAnimation(bool *aDrawing);
|
||||
#endif
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
nsresult ContentsScaleFactorChanged(double aContentsScaleFactor);
|
||||
#endif
|
||||
nsresult SetBackgroundUnknown();
|
||||
|
|
|
|||
137
dom/plugins/ipc/PluginInterposeOSX.h
Normal file
137
dom/plugins/ipc/PluginInterposeOSX.h
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
// vim:set ts=2 sts=2 sw=2 et cin:
|
||||
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
|
||||
//
|
||||
// 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.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "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 DOM_PLUGINS_IPC_PLUGININTERPOSEOSX_H
|
||||
#define DOM_PLUGINS_IPC_PLUGININTERPOSEOSX_H
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "nsPoint.h"
|
||||
#include "npapi.h"
|
||||
|
||||
// Make this includable from non-Objective-C code.
|
||||
#ifndef __OBJC__
|
||||
class NSCursor;
|
||||
#else
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
|
||||
// The header file QuickdrawAPI.h is missing on OS X 10.7 and up (though the
|
||||
// QuickDraw APIs defined in it are still present) -- so we need to supply the
|
||||
// relevant parts of its contents here. It's likely that Apple will eventually
|
||||
// remove the APIs themselves (probably in OS X 10.8), so we need to make them
|
||||
// weak imports, and test for their presence before using them.
|
||||
#if !defined(__QUICKDRAWAPI__)
|
||||
|
||||
typedef short Bits16[16];
|
||||
struct Cursor {
|
||||
Bits16 data;
|
||||
Bits16 mask;
|
||||
Point hotSpot;
|
||||
};
|
||||
typedef struct Cursor Cursor;
|
||||
|
||||
#endif /* __QUICKDRAWAPI__ */
|
||||
|
||||
namespace mac_plugin_interposing {
|
||||
|
||||
// Class used to serialize NSCursor objects over IPC between processes.
|
||||
class NSCursorInfo {
|
||||
public:
|
||||
enum Type {
|
||||
TypeCustom,
|
||||
TypeArrow,
|
||||
TypeClosedHand,
|
||||
TypeContextualMenu, // Only supported on OS X 10.6 and up
|
||||
TypeCrosshair,
|
||||
TypeDisappearingItem,
|
||||
TypeDragCopy, // Only supported on OS X 10.6 and up
|
||||
TypeDragLink, // Only supported on OS X 10.6 and up
|
||||
TypeIBeam,
|
||||
TypeNotAllowed, // Only supported on OS X 10.6 and up
|
||||
TypeOpenHand,
|
||||
TypePointingHand,
|
||||
TypeResizeDown,
|
||||
TypeResizeLeft,
|
||||
TypeResizeLeftRight,
|
||||
TypeResizeRight,
|
||||
TypeResizeUp,
|
||||
TypeResizeUpDown,
|
||||
TypeTransparent // Special type
|
||||
};
|
||||
|
||||
NSCursorInfo();
|
||||
explicit NSCursorInfo(NSCursor* aCursor);
|
||||
explicit NSCursorInfo(const Cursor* aCursor);
|
||||
~NSCursorInfo();
|
||||
|
||||
NSCursor* GetNSCursor() const;
|
||||
Type GetType() const;
|
||||
const char* GetTypeName() const;
|
||||
nsPoint GetHotSpot() const;
|
||||
uint8_t* GetCustomImageData() const;
|
||||
uint32_t GetCustomImageDataLength() const;
|
||||
|
||||
void SetType(Type aType);
|
||||
void SetHotSpot(nsPoint aHotSpot);
|
||||
void SetCustomImageData(uint8_t* aData, uint32_t aDataLength);
|
||||
|
||||
static bool GetNativeCursorsSupported();
|
||||
|
||||
private:
|
||||
NSCursor* GetTransparentCursor() const;
|
||||
|
||||
Type mType;
|
||||
// The hot spot's coordinate system is the cursor's coordinate system, and
|
||||
// has an upper-left origin (in both Cocoa and pre-Cocoa systems).
|
||||
nsPoint mHotSpot;
|
||||
uint8_t* mCustomImageData;
|
||||
uint32_t mCustomImageDataLength;
|
||||
static int32_t mNativeCursorsSupported;
|
||||
};
|
||||
|
||||
namespace parent {
|
||||
|
||||
void OnPluginShowWindow(uint32_t window_id, CGRect window_bounds, bool modal);
|
||||
void OnPluginHideWindow(uint32_t window_id, pid_t aPluginPid);
|
||||
void OnSetCursor(const NSCursorInfo& cursorInfo);
|
||||
void OnShowCursor(bool show);
|
||||
void OnPushCursor(const NSCursorInfo& cursorInfo);
|
||||
void OnPopCursor();
|
||||
|
||||
} // namespace parent
|
||||
|
||||
namespace child {
|
||||
|
||||
void SetUpCocoaInterposing();
|
||||
|
||||
} // namespace child
|
||||
|
||||
} // namespace mac_plugin_interposing
|
||||
|
||||
#endif /* DOM_PLUGINS_IPC_PLUGININTERPOSEOSX_H */
|
||||
1158
dom/plugins/ipc/PluginInterposeOSX.mm
Normal file
1158
dom/plugins/ipc/PluginInterposeOSX.mm
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -57,7 +57,7 @@ public:
|
|||
|
||||
virtual bool HasRequiredFunctions() = 0;
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, NPError* error) = 0;
|
||||
#else
|
||||
virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error) = 0;
|
||||
|
|
@ -66,7 +66,7 @@ public:
|
|||
virtual nsresult NP_GetMIMEDescription(const char** mimeDesc) = 0;
|
||||
virtual nsresult NP_GetValue(void *future, NPPVariable aVariable,
|
||||
void *aValue, NPError* error) = 0;
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX)
|
||||
virtual nsresult NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error) = 0;
|
||||
#endif
|
||||
virtual nsresult NPP_New(NPMIMEType pluginType, NPP instance,
|
||||
|
|
@ -83,7 +83,10 @@ public:
|
|||
virtual nsresult GetImageSize(NPP instance, nsIntSize* aSize) = 0;
|
||||
virtual void DidComposite(NPP instance) = 0;
|
||||
virtual bool IsOOP() = 0;
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_MACOSX)
|
||||
virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing) = 0;
|
||||
#endif
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
virtual nsresult ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor) = 0;
|
||||
#endif
|
||||
#if defined(XP_WIN)
|
||||
|
|
|
|||
|
|
@ -49,10 +49,13 @@ namespace plugins {
|
|||
|
||||
NPRemoteWindow::NPRemoteWindow() :
|
||||
window(0), x(0), y(0), width(0), height(0), type(NPWindowTypeDrawable)
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX)
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
, visualID(0)
|
||||
, colormap(0)
|
||||
#endif /* XP_UNIX */
|
||||
#if defined(XP_MACOSX)
|
||||
,contentsScaleFactor(1.0)
|
||||
#endif
|
||||
{
|
||||
clipRect.top = 0;
|
||||
clipRect.left = 0;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=4 ts=4 et :
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
|
@ -22,7 +23,11 @@
|
|||
#include "nsTArray.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "nsHashKeys.h"
|
||||
#ifdef XP_MACOSX
|
||||
#include "PluginInterposeOSX.h"
|
||||
#else
|
||||
namespace mac_plugin_interposing { class NSCursorInfo { }; }
|
||||
#endif
|
||||
using mac_plugin_interposing::NSCursorInfo;
|
||||
|
||||
namespace mozilla {
|
||||
|
|
@ -82,11 +87,11 @@ struct NPRemoteWindow
|
|||
uint32_t height;
|
||||
NPRect clipRect;
|
||||
NPWindowType type;
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX)
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
VisualID visualID;
|
||||
Colormap colormap;
|
||||
#endif /* XP_UNIX */
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
double contentsScaleFactor;
|
||||
#endif
|
||||
};
|
||||
|
|
@ -106,6 +111,8 @@ struct NPAudioDeviceChangeDetailsIPC
|
|||
typedef HWND NativeWindowHandle;
|
||||
#elif defined(MOZ_X11)
|
||||
typedef XID NativeWindowHandle;
|
||||
#elif defined(XP_DARWIN)
|
||||
typedef intptr_t NativeWindowHandle; // never actually used, will always be 0
|
||||
#else
|
||||
#error Need NativeWindowHandle for this platform
|
||||
#endif
|
||||
|
|
@ -149,6 +156,11 @@ NPPVariableToString(NPPVariable aVar)
|
|||
|
||||
VARSTR(NPPVpluginWantsAllNetworkStreams);
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
VARSTR(NPPVpluginDrawingModel);
|
||||
VARSTR(NPPVpluginEventModel);
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
VARSTR(NPPVpluginRequiresAudioDeviceChanges);
|
||||
#endif
|
||||
|
|
@ -345,11 +357,11 @@ struct ParamTraits<mozilla::plugins::NPRemoteWindow>
|
|||
WriteParam(aMsg, aParam.height);
|
||||
WriteParam(aMsg, aParam.clipRect);
|
||||
WriteParam(aMsg, aParam.type);
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX)
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
aMsg->WriteULong(aParam.visualID);
|
||||
aMsg->WriteULong(aParam.colormap);
|
||||
#endif
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
aMsg->WriteDouble(aParam.contentsScaleFactor);
|
||||
#endif
|
||||
}
|
||||
|
|
@ -370,7 +382,7 @@ struct ParamTraits<mozilla::plugins::NPRemoteWindow>
|
|||
ReadParam(aMsg, aIter, &type)))
|
||||
return false;
|
||||
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX)
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
unsigned long visualID;
|
||||
unsigned long colormap;
|
||||
if (!(aMsg->ReadULong(aIter, &visualID) &&
|
||||
|
|
@ -378,7 +390,7 @@ struct ParamTraits<mozilla::plugins::NPRemoteWindow>
|
|||
return false;
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
double contentsScaleFactor;
|
||||
if (!aMsg->ReadDouble(aIter, &contentsScaleFactor))
|
||||
return false;
|
||||
|
|
@ -391,11 +403,11 @@ struct ParamTraits<mozilla::plugins::NPRemoteWindow>
|
|||
aResult->height = height;
|
||||
aResult->clipRect = clipRect;
|
||||
aResult->type = type;
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX)
|
||||
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
aResult->visualID = visualID;
|
||||
aResult->colormap = colormap;
|
||||
#endif
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
aResult->contentsScaleFactor = contentsScaleFactor;
|
||||
#endif
|
||||
return true;
|
||||
|
|
@ -410,6 +422,161 @@ struct ParamTraits<mozilla::plugins::NPRemoteWindow>
|
|||
}
|
||||
};
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
template <>
|
||||
struct ParamTraits<NPNSString*>
|
||||
{
|
||||
typedef NPNSString* paramType;
|
||||
|
||||
// Empty string writes a length of 0 and no buffer.
|
||||
// We don't write a nullptr terminating character in buffers.
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
CFStringRef cfString = (CFStringRef)aParam;
|
||||
|
||||
// Write true if we have a string, false represents nullptr.
|
||||
aMsg->WriteBool(!!cfString);
|
||||
if (!cfString) {
|
||||
return;
|
||||
}
|
||||
|
||||
long length = ::CFStringGetLength(cfString);
|
||||
WriteParam(aMsg, length);
|
||||
if (length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Attempt to get characters without any allocation/conversion.
|
||||
if (::CFStringGetCharactersPtr(cfString)) {
|
||||
aMsg->WriteBytes(::CFStringGetCharactersPtr(cfString), length * sizeof(UniChar));
|
||||
} else {
|
||||
UniChar *buffer = (UniChar*)moz_xmalloc(length * sizeof(UniChar));
|
||||
::CFStringGetCharacters(cfString, ::CFRangeMake(0, length), buffer);
|
||||
aMsg->WriteBytes(buffer, length * sizeof(UniChar));
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
|
||||
{
|
||||
bool haveString = false;
|
||||
if (!aMsg->ReadBool(aIter, &haveString)) {
|
||||
return false;
|
||||
}
|
||||
if (!haveString) {
|
||||
*aResult = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
long length;
|
||||
if (!ReadParam(aMsg, aIter, &length)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Avoid integer multiplication overflow.
|
||||
if (length > INT_MAX / static_cast<long>(sizeof(UniChar))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto chars = mozilla::MakeUnique<UniChar[]>(length);
|
||||
if (length != 0) {
|
||||
if (!aMsg->ReadBytesInto(aIter, chars.get(), length * sizeof(UniChar))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*aResult = (NPNSString*)::CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8*)chars.get(),
|
||||
length * sizeof(UniChar),
|
||||
kCFStringEncodingUTF16, false);
|
||||
if (!*aResult) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
template <>
|
||||
struct ParamTraits<NSCursorInfo>
|
||||
{
|
||||
typedef NSCursorInfo paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
NSCursorInfo::Type type = aParam.GetType();
|
||||
|
||||
aMsg->WriteInt(type);
|
||||
|
||||
nsPoint hotSpot = aParam.GetHotSpot();
|
||||
WriteParam(aMsg, hotSpot.x);
|
||||
WriteParam(aMsg, hotSpot.y);
|
||||
|
||||
uint32_t dataLength = aParam.GetCustomImageDataLength();
|
||||
WriteParam(aMsg, dataLength);
|
||||
if (dataLength == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t* buffer = (uint8_t*)moz_xmalloc(dataLength);
|
||||
memcpy(buffer, aParam.GetCustomImageData(), dataLength);
|
||||
aMsg->WriteBytes(buffer, dataLength);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
|
||||
{
|
||||
NSCursorInfo::Type type;
|
||||
if (!aMsg->ReadInt(aIter, (int*)&type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nscoord hotSpotX, hotSpotY;
|
||||
if (!ReadParam(aMsg, aIter, &hotSpotX) ||
|
||||
!ReadParam(aMsg, aIter, &hotSpotY)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t dataLength;
|
||||
if (!ReadParam(aMsg, aIter, &dataLength)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto data = mozilla::MakeUnique<uint8_t[]>(dataLength);
|
||||
if (dataLength != 0) {
|
||||
if (!aMsg->ReadBytesInto(aIter, data.get(), dataLength)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
aResult->SetType(type);
|
||||
aResult->SetHotSpot(nsPoint(hotSpotX, hotSpotY));
|
||||
aResult->SetCustomImageData(data.get(), dataLength);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void Log(const paramType& aParam, std::wstring* aLog)
|
||||
{
|
||||
const char* typeName = aParam.GetTypeName();
|
||||
nsPoint hotSpot = aParam.GetHotSpot();
|
||||
int hotSpotX, hotSpotY;
|
||||
#ifdef NS_COORD_IS_FLOAT
|
||||
hotSpotX = rint(hotSpot.x);
|
||||
hotSpotY = rint(hotSpot.y);
|
||||
#else
|
||||
hotSpotX = hotSpot.x;
|
||||
hotSpotY = hotSpot.y;
|
||||
#endif
|
||||
uint32_t dataLength = aParam.GetCustomImageDataLength();
|
||||
uint8_t* data = aParam.GetCustomImageData();
|
||||
|
||||
aLog->append(StringPrintf(L"[%s, (%i %i), %u, %p]",
|
||||
typeName, hotSpotX, hotSpotY, dataLength, data));
|
||||
}
|
||||
};
|
||||
#else
|
||||
template<>
|
||||
struct ParamTraits<NSCursorInfo>
|
||||
{
|
||||
|
|
@ -422,6 +589,7 @@ struct ParamTraits<NSCursorInfo>
|
|||
return false;
|
||||
}
|
||||
};
|
||||
#endif // #ifdef XP_MACOSX
|
||||
|
||||
template <>
|
||||
struct ParamTraits<mozilla::plugins::IPCByteRange>
|
||||
|
|
@ -564,7 +732,9 @@ struct ParamTraits<mozilla::plugins::NPAudioDeviceChangeDetailsIPC>
|
|||
//
|
||||
// NB: these guards are based on those where struct NPEvent is defined
|
||||
// in npapi.h. They should be kept in sync.
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_MACOSX)
|
||||
# include "mozilla/plugins/NPEventOSX.h"
|
||||
#elif defined(XP_WIN)
|
||||
# include "mozilla/plugins/NPEventWindows.h"
|
||||
#elif defined(XP_UNIX)
|
||||
# include "mozilla/plugins/NPEventUnix.h"
|
||||
|
|
|
|||
|
|
@ -132,6 +132,12 @@ PluginModuleChild::PluginModuleChild(bool aIsChrome)
|
|||
MOZ_ASSERT(!gChromeInstance);
|
||||
gChromeInstance = this;
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (aIsChrome) {
|
||||
mac_plugin_interposing::child::SetUpCocoaInterposing();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
PluginModuleChild::~PluginModuleChild()
|
||||
|
|
@ -253,9 +259,15 @@ PluginModuleChild::InitForChrome(const std::string& aPluginFilename,
|
|||
if (StringBeginsWith(nsDependentCString(info.fDescription), flash10Head)) {
|
||||
AddQuirk(QUIRK_FLASH_EXPOSE_COORD_TRANSLATION);
|
||||
}
|
||||
#endif
|
||||
#if defined(XP_MACOSX)
|
||||
const char* namePrefix = "Plugin Content";
|
||||
char nameBuffer[80];
|
||||
SprintfLiteral(nameBuffer, "%s (%s)", namePrefix, info.fName);
|
||||
mozilla::plugins::PluginUtilsOSX::SetProcessName(nameBuffer);
|
||||
#endif
|
||||
pluginFile.FreePluginInfo(info);
|
||||
#if defined(MOZ_X11)
|
||||
#if defined(MOZ_X11) || defined(XP_MACOSX)
|
||||
if (!mLibrary)
|
||||
#endif
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: sw=4 ts=4 et :
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
|
@ -47,6 +48,9 @@
|
|||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
#include <glib.h>
|
||||
#elif XP_MACOSX
|
||||
#include "PluginInterposeOSX.h"
|
||||
#include "PluginUtilsOSX.h"
|
||||
#endif
|
||||
|
||||
using base::KillProcess;
|
||||
|
|
@ -504,7 +508,7 @@ PluginModuleChromeParent::OnProcessLaunched(const bool aSucceeded)
|
|||
if (NS_SUCCEEDED(mAsyncInitRv))
|
||||
#endif
|
||||
{
|
||||
#if defined(XP_UNIX)
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
mAsyncInitRv = NP_Initialize(mNPNIface,
|
||||
mNPPIface,
|
||||
&mAsyncInitError);
|
||||
|
|
@ -513,6 +517,13 @@ PluginModuleChromeParent::OnProcessLaunched(const bool aSucceeded)
|
|||
&mAsyncInitError);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
if (NS_SUCCEEDED(mAsyncInitRv)) {
|
||||
mAsyncInitRv = NP_GetEntryPoints(mNPPIface,
|
||||
&mAsyncInitError);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1657,8 +1668,13 @@ PluginModuleParent::GetSettings(PluginSettings* aSettings)
|
|||
aSettings->supportsWindowless() = GetSetting(NPNVSupportsWindowless);
|
||||
aSettings->userAgent() = NullableString(mNPNIface->uagent(nullptr));
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
aSettings->nativeCursorsSupported() =
|
||||
Preferences::GetBool("dom.ipc.plugins.nativeCursorSupport", false);
|
||||
#else
|
||||
// Need to initialize this to satisfy IPDL.
|
||||
aSettings->nativeCursorsSupported() = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1676,7 +1692,7 @@ PluginModuleChromeParent::CachedSettingChanged(const char* aPref, void* aModule)
|
|||
module->CachedSettingChanged();
|
||||
}
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
nsresult
|
||||
PluginModuleParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, NPError* error)
|
||||
{
|
||||
|
|
@ -1814,7 +1830,7 @@ PluginModuleParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX)
|
||||
|
||||
nsresult
|
||||
PluginModuleContentParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error)
|
||||
|
|
@ -1837,10 +1853,20 @@ PluginModuleChromeParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error)
|
|||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
if (!mSubprocess->IsConnected()) {
|
||||
// The subprocess isn't connected yet. Defer NP_Initialize until
|
||||
// OnProcessLaunched is invoked.
|
||||
mInitOnAsyncConnect = true;
|
||||
*error = NPERR_NO_ERROR;
|
||||
return NS_OK;
|
||||
}
|
||||
#else
|
||||
if (mInitOnAsyncConnect) {
|
||||
*error = NPERR_NO_ERROR;
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
PluginSettings settings;
|
||||
GetSettings(&settings);
|
||||
|
|
@ -2032,7 +2058,7 @@ PluginModuleParent::NP_GetValue(void *future, NPPVariable aVariable,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX)
|
||||
nsresult
|
||||
PluginModuleParent::NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error)
|
||||
{
|
||||
|
|
@ -2041,7 +2067,16 @@ PluginModuleParent::NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error)
|
|||
*error = NPERR_NO_ERROR;
|
||||
if (mIsStartingAsync && !IsChrome()) {
|
||||
mNPPIface = pFuncs;
|
||||
#if defined(XP_MACOSX)
|
||||
if (mNPInitialized) {
|
||||
SetPluginFuncs(pFuncs);
|
||||
InitAsyncSurrogates();
|
||||
} else {
|
||||
PluginAsyncSurrogate::NP_GetEntryPoints(pFuncs);
|
||||
}
|
||||
#else
|
||||
PluginAsyncSurrogate::NP_GetEntryPoints(pFuncs);
|
||||
#endif
|
||||
} else {
|
||||
SetPluginFuncs(pFuncs);
|
||||
}
|
||||
|
|
@ -2052,6 +2087,14 @@ PluginModuleParent::NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error)
|
|||
nsresult
|
||||
PluginModuleChromeParent::NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error)
|
||||
{
|
||||
#if defined(XP_MACOSX)
|
||||
if (mInitOnAsyncConnect) {
|
||||
PluginAsyncSurrogate::NP_GetEntryPoints(pFuncs);
|
||||
mNPPIface = pFuncs;
|
||||
*error = NPERR_NO_ERROR;
|
||||
return NS_OK;
|
||||
}
|
||||
#else
|
||||
if (mIsStartingAsync) {
|
||||
PluginAsyncSurrogate::NP_GetEntryPoints(pFuncs);
|
||||
}
|
||||
|
|
@ -2061,6 +2104,7 @@ PluginModuleChromeParent::NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* erro
|
|||
*error = NPERR_NO_ERROR;
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
// We need to have the plugin process update its function table here by
|
||||
// actually calling NP_GetEntryPoints. The parent's function table will
|
||||
|
|
@ -2281,7 +2325,18 @@ PluginModuleParent::NPP_GetSitesWithData(nsCOMPtr<nsIGetSitesWithDataCallback> c
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_MACOSX)
|
||||
nsresult
|
||||
PluginModuleParent::IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing)
|
||||
{
|
||||
PluginInstanceParent* i = PluginInstanceParent::Cast(instance);
|
||||
if (!i)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return i->IsRemoteDrawingCoreAnimation(aDrawing);
|
||||
}
|
||||
#endif
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
nsresult
|
||||
PluginModuleParent::ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor)
|
||||
{
|
||||
|
|
@ -2291,9 +2346,17 @@ PluginModuleParent::ContentsScaleFactorChanged(NPP instance, double aContentsSca
|
|||
|
||||
return i->ContentsScaleFactorChanged(aContentsScaleFactor);
|
||||
}
|
||||
#endif // #if defined(XP_WIN)
|
||||
#endif // #if defined(XP_MACOSX)
|
||||
|
||||
#if !defined(MOZ_WIDGET_GTK)
|
||||
#if defined(XP_MACOSX)
|
||||
bool
|
||||
PluginModuleParent::AnswerProcessSomeEvents()
|
||||
{
|
||||
mozilla::plugins::PluginUtilsOSX::InvokeNativeEventLoop();
|
||||
return true;
|
||||
}
|
||||
|
||||
#elif !defined(MOZ_WIDGET_GTK)
|
||||
bool
|
||||
PluginModuleParent::AnswerProcessSomeEvents()
|
||||
{
|
||||
|
|
@ -2351,54 +2414,85 @@ PluginModuleParent::RecvPluginShowWindow(const uint32_t& aWindowId, const bool&
|
|||
const size_t& aWidth, const size_t& aHeight)
|
||||
{
|
||||
PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
|
||||
#if defined(XP_MACOSX)
|
||||
CGRect windowBound = ::CGRectMake(aX, aY, aWidth, aHeight);
|
||||
mac_plugin_interposing::parent::OnPluginShowWindow(aWindowId, windowBound, aModal);
|
||||
return true;
|
||||
#else
|
||||
NS_NOTREACHED(
|
||||
"PluginInstanceParent::RecvPluginShowWindow not implemented!");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
PluginModuleParent::RecvPluginHideWindow(const uint32_t& aWindowId)
|
||||
{
|
||||
PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
|
||||
#if defined(XP_MACOSX)
|
||||
mac_plugin_interposing::parent::OnPluginHideWindow(aWindowId, OtherPid());
|
||||
return true;
|
||||
#else
|
||||
NS_NOTREACHED(
|
||||
"PluginInstanceParent::RecvPluginHideWindow not implemented!");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
PluginModuleParent::RecvSetCursor(const NSCursorInfo& aCursorInfo)
|
||||
{
|
||||
PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
|
||||
#if defined(XP_MACOSX)
|
||||
mac_plugin_interposing::parent::OnSetCursor(aCursorInfo);
|
||||
return true;
|
||||
#else
|
||||
NS_NOTREACHED(
|
||||
"PluginInstanceParent::RecvSetCursor not implemented!");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
PluginModuleParent::RecvShowCursor(const bool& aShow)
|
||||
{
|
||||
PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
|
||||
#if defined(XP_MACOSX)
|
||||
mac_plugin_interposing::parent::OnShowCursor(aShow);
|
||||
return true;
|
||||
#else
|
||||
NS_NOTREACHED(
|
||||
"PluginInstanceParent::RecvShowCursor not implemented!");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
PluginModuleParent::RecvPushCursor(const NSCursorInfo& aCursorInfo)
|
||||
{
|
||||
PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
|
||||
#if defined(XP_MACOSX)
|
||||
mac_plugin_interposing::parent::OnPushCursor(aCursorInfo);
|
||||
return true;
|
||||
#else
|
||||
NS_NOTREACHED(
|
||||
"PluginInstanceParent::RecvPushCursor not implemented!");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
PluginModuleParent::RecvPopCursor()
|
||||
{
|
||||
PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
|
||||
#if defined(XP_MACOSX)
|
||||
mac_plugin_interposing::parent::OnPopCursor();
|
||||
return true;
|
||||
#else
|
||||
NS_NOTREACHED(
|
||||
"PluginInstanceParent::RecvPopCursor not implemented!");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ protected:
|
|||
const mozilla::NativeEventData& aNativeKeyData,
|
||||
bool aIsConsumed) override;
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, NPError* error) override;
|
||||
#else
|
||||
virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error) override;
|
||||
|
|
@ -257,7 +257,7 @@ protected:
|
|||
virtual nsresult NP_GetMIMEDescription(const char** mimeDesc) override;
|
||||
virtual nsresult NP_GetValue(void *future, NPPVariable aVariable,
|
||||
void *aValue, NPError* error) override;
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX)
|
||||
virtual nsresult NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error) override;
|
||||
#endif
|
||||
virtual nsresult NPP_New(NPMIMEType pluginType, NPP instance,
|
||||
|
|
@ -278,7 +278,10 @@ private:
|
|||
|
||||
public:
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_MACOSX)
|
||||
virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing) override;
|
||||
#endif
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
virtual nsresult ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor) override;
|
||||
#endif
|
||||
|
||||
|
|
@ -352,7 +355,7 @@ class PluginModuleContentParent : public PluginModuleParent
|
|||
|
||||
virtual ~PluginModuleContentParent();
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX)
|
||||
nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error) override;
|
||||
#endif
|
||||
|
||||
|
|
@ -476,13 +479,13 @@ private:
|
|||
PluginProcessParent* Process() const { return mSubprocess; }
|
||||
base::ProcessHandle ChildProcessHandle() { return mSubprocess->GetChildProcessHandle(); }
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, NPError* error) override;
|
||||
#else
|
||||
virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error) override;
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX)
|
||||
virtual nsresult NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error) override;
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: sw=4 ts=4 et :
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
|
@ -12,6 +13,13 @@
|
|||
#include "base/string_util.h"
|
||||
#include "nsDebugImpl.h"
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
#include "nsCocoaFeatures.h"
|
||||
// An undocumented CoreGraphics framework method, present in the same form
|
||||
// since at least OS X 10.5.
|
||||
extern "C" CGError CGSSetDebugOptions(int options);
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
bool ShouldProtectPluginCurrentDirectory(char16ptr_t pluginFilePath);
|
||||
#endif
|
||||
|
|
@ -32,6 +40,42 @@ PluginProcessChild::Init()
|
|||
{
|
||||
nsDebugImpl::SetMultiprocessMode("NPAPI");
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
// Remove the trigger for "dyld interposing" that we added in
|
||||
// GeckoChildProcessHost::PerformAsyncLaunchInternal(), in the host
|
||||
// process just before we were launched. Dyld interposing will still
|
||||
// happen in our process (the plugin child process). But we don't want
|
||||
// it to happen in any processes that the plugin might launch from our
|
||||
// process.
|
||||
nsCString interpose(PR_GetEnv("DYLD_INSERT_LIBRARIES"));
|
||||
if (!interpose.IsEmpty()) {
|
||||
// If we added the path to libplugin_child_interpose.dylib to an
|
||||
// existing DYLD_INSERT_LIBRARIES, we appended it to the end, after a
|
||||
// ":" path seperator.
|
||||
int32_t lastSeparatorPos = interpose.RFind(":");
|
||||
int32_t lastTriggerPos = interpose.RFind("libplugin_child_interpose.dylib");
|
||||
bool needsReset = false;
|
||||
if (lastTriggerPos != -1) {
|
||||
if (lastSeparatorPos == -1) {
|
||||
interpose.Truncate();
|
||||
needsReset = true;
|
||||
} else if (lastTriggerPos > lastSeparatorPos) {
|
||||
interpose.SetLength(lastSeparatorPos);
|
||||
needsReset = true;
|
||||
}
|
||||
}
|
||||
if (needsReset) {
|
||||
nsCString setInterpose("DYLD_INSERT_LIBRARIES=");
|
||||
if (!interpose.IsEmpty()) {
|
||||
setInterpose.Append(interpose);
|
||||
}
|
||||
// Values passed to PR_SetEnv() must be seperately allocated.
|
||||
char* setInterposePtr = strdup(setInterpose.get());
|
||||
PR_SetEnv(setInterposePtr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Certain plugins, such as flash, steal the unhandled exception filter
|
||||
// thus we never get crash reports when they fault. This call fixes it.
|
||||
message_loop()->set_exception_restoration(true);
|
||||
|
|
@ -71,6 +115,17 @@ PluginProcessChild::Init()
|
|||
bool retval = mPlugin.InitForChrome(pluginFilename, ParentPid(),
|
||||
IOThreadChild::message_loop(),
|
||||
IOThreadChild::channel());
|
||||
#if defined(XP_MACOSX)
|
||||
if (nsCocoaFeatures::OnYosemiteOrLater()) {
|
||||
// Explicitly turn off CGEvent logging. This works around bug 1092855.
|
||||
// If there are already CGEvents in the log, turning off logging also
|
||||
// causes those events to be written to disk. But at this point no
|
||||
// CGEvents have yet been processed. CGEvents are events (usually
|
||||
// input events) pulled from the WindowServer. An option of 0x80000008
|
||||
// turns on CGEvent logging.
|
||||
CGSSetDebugOptions(0x80000007);
|
||||
}
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,13 @@ PluginProcessParent::Launch(mozilla::UniquePtr<LaunchCompleteTask> aLaunchComple
|
|||
uint32_t containerArchitectures = GetSupportedArchitecturesForProcessType(GeckoProcessType_Plugin);
|
||||
|
||||
uint32_t pluginLibArchitectures = currentArchitecture;
|
||||
#ifdef XP_MACOSX
|
||||
nsresult rv = GetArchitecturesForBinary(mPluginFilePath.c_str(), &pluginLibArchitectures);
|
||||
if (NS_FAILED(rv)) {
|
||||
// If the call failed just assume that we want the current architecture.
|
||||
pluginLibArchitectures = currentArchitecture;
|
||||
}
|
||||
#endif
|
||||
|
||||
ProcessArchitecture selectedArchitecture = currentArchitecture;
|
||||
if (!(pluginLibArchitectures & containerArchitectures & currentArchitecture)) {
|
||||
|
|
|
|||
|
|
@ -49,6 +49,16 @@ int GetQuirksFromMimeTypeAndFilename(const nsCString& aMimeType,
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// Whitelist Flash and Quicktime to support offline renderer
|
||||
NS_NAMED_LITERAL_CSTRING(quicktime, "QuickTime Plugin.plugin");
|
||||
if (specialType == nsPluginHost::eSpecialType_Flash) {
|
||||
quirks |= QUIRK_ALLOW_OFFLINE_RENDERER;
|
||||
} else if (FindInReadable(quicktime, aPluginFilename)) {
|
||||
quirks |= QUIRK_ALLOW_OFFLINE_RENDERER;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef OS_WIN
|
||||
if (specialType == nsPluginHost::eSpecialType_Unity) {
|
||||
quirks |= QUIRK_UNITY_FIXUP_MOUSE_CAPTURE;
|
||||
|
|
|
|||
92
dom/plugins/ipc/PluginUtilsOSX.h
Normal file
92
dom/plugins/ipc/PluginUtilsOSX.h
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
// vim:set ts=2 sts=2 sw=2 et cin:
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef dom_plugins_PluginUtilsOSX_h
|
||||
#define dom_plugins_PluginUtilsOSX_h 1
|
||||
|
||||
#include "npapi.h"
|
||||
#include "mozilla/gfx/QuartzSupport.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
namespace PluginUtilsOSX {
|
||||
|
||||
// Need to call back into the browser's message loop to process event.
|
||||
typedef void (*RemoteProcessEvents) (void*);
|
||||
|
||||
NPError ShowCocoaContextMenu(void* aMenu, int aX, int aY, void* pluginModule, RemoteProcessEvents remoteEvent);
|
||||
|
||||
void InvokeNativeEventLoop();
|
||||
|
||||
// Need to call back and send a cocoa draw event to the plugin.
|
||||
typedef void (*DrawPluginFunc) (CGContextRef, void*, nsIntRect aUpdateRect);
|
||||
|
||||
void* GetCGLayer(DrawPluginFunc aFunc, void* aPluginInstance, double aContentsScaleFactor);
|
||||
void ReleaseCGLayer(void* cgLayer);
|
||||
void Repaint(void* cgLayer, nsIntRect aRect);
|
||||
|
||||
bool SetProcessName(const char* aProcessName);
|
||||
|
||||
/*
|
||||
* Provides a wrapper around nsCARenderer to manage double buffering
|
||||
* without having to unbind nsCARenderer on every surface swaps.
|
||||
*
|
||||
* The double buffer renderer begins with no initialize surfaces.
|
||||
* The buffers can be initialized and cleared individually.
|
||||
* Swapping still occurs regardless if the buffers are initialized.
|
||||
*/
|
||||
class nsDoubleBufferCARenderer {
|
||||
public:
|
||||
nsDoubleBufferCARenderer() : mCALayer(nullptr), mContentsScaleFactor(1.0) {}
|
||||
// Returns width in "display pixels". A "display pixel" is the smallest
|
||||
// fully addressable part of a display. But in HiDPI modes each "display
|
||||
// pixel" corresponds to more than one device pixel. Multiply display pixels
|
||||
// by mContentsScaleFactor to get device pixels.
|
||||
size_t GetFrontSurfaceWidth();
|
||||
// Returns height in "display pixels". Multiply by
|
||||
// mContentsScaleFactor to get device pixels.
|
||||
size_t GetFrontSurfaceHeight();
|
||||
double GetFrontSurfaceContentsScaleFactor();
|
||||
// Returns width in "display pixels". Multiply by
|
||||
// mContentsScaleFactor to get device pixels.
|
||||
size_t GetBackSurfaceWidth();
|
||||
// Returns height in "display pixels". Multiply by
|
||||
// mContentsScaleFactor to get device pixels.
|
||||
size_t GetBackSurfaceHeight();
|
||||
double GetBackSurfaceContentsScaleFactor();
|
||||
IOSurfaceID GetFrontSurfaceID();
|
||||
|
||||
bool HasBackSurface();
|
||||
bool HasFrontSurface();
|
||||
bool HasCALayer();
|
||||
|
||||
void SetCALayer(void *aCALayer);
|
||||
// aWidth and aHeight are in "display pixels". Multiply by
|
||||
// aContentsScaleFactor to get device pixels.
|
||||
bool InitFrontSurface(size_t aWidth, size_t aHeight,
|
||||
double aContentsScaleFactor,
|
||||
AllowOfflineRendererEnum aAllowOfflineRenderer);
|
||||
void Render();
|
||||
void SwapSurfaces();
|
||||
void ClearFrontSurface();
|
||||
void ClearBackSurface();
|
||||
|
||||
double GetContentsScaleFactor() { return mContentsScaleFactor; }
|
||||
|
||||
private:
|
||||
void *mCALayer;
|
||||
RefPtr<nsCARenderer> mCARenderer;
|
||||
RefPtr<MacIOSurface> mFrontSurface;
|
||||
RefPtr<MacIOSurface> mBackSurface;
|
||||
double mContentsScaleFactor;
|
||||
};
|
||||
|
||||
} // namespace PluginUtilsOSX
|
||||
} // namespace plugins
|
||||
} // namespace mozilla
|
||||
|
||||
#endif //dom_plugins_PluginUtilsOSX_h
|
||||
462
dom/plugins/ipc/PluginUtilsOSX.mm
Normal file
462
dom/plugins/ipc/PluginUtilsOSX.mm
Normal file
|
|
@ -0,0 +1,462 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
// vim:set ts=2 sts=2 sw=2 et cin:
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <dlfcn.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
#include "PluginUtilsOSX.h"
|
||||
|
||||
// Remove definitions for try/catch interfering with ObjCException macros.
|
||||
#include "nsObjCExceptions.h"
|
||||
#include "nsCocoaUtils.h"
|
||||
|
||||
#include "nsDebug.h"
|
||||
|
||||
#include "mozilla/Sprintf.h"
|
||||
|
||||
@interface CALayer (ContentsScale)
|
||||
- (double)contentsScale;
|
||||
- (void)setContentsScale:(double)scale;
|
||||
@end
|
||||
|
||||
using namespace mozilla::plugins::PluginUtilsOSX;
|
||||
|
||||
@interface CGBridgeLayer : CALayer {
|
||||
DrawPluginFunc mDrawFunc;
|
||||
void* mPluginInstance;
|
||||
nsIntRect mUpdateRect;
|
||||
}
|
||||
- (void)setDrawFunc:(DrawPluginFunc)aFunc
|
||||
pluginInstance:(void*)aPluginInstance;
|
||||
- (void)updateRect:(nsIntRect)aRect;
|
||||
|
||||
@end
|
||||
|
||||
// CGBitmapContextSetData() is an undocumented function present (with
|
||||
// the same signature) since at least OS X 10.5. As the name suggests,
|
||||
// it's used to replace the "data" in a bitmap context that was
|
||||
// originally specified in a call to CGBitmapContextCreate() or
|
||||
// CGBitmapContextCreateWithData().
|
||||
typedef void (*CGBitmapContextSetDataFunc) (CGContextRef c,
|
||||
size_t x,
|
||||
size_t y,
|
||||
size_t width,
|
||||
size_t height,
|
||||
void* data,
|
||||
size_t bitsPerComponent,
|
||||
size_t bitsPerPixel,
|
||||
size_t bytesPerRow);
|
||||
CGBitmapContextSetDataFunc CGBitmapContextSetDataPtr = NULL;
|
||||
|
||||
@implementation CGBridgeLayer
|
||||
- (void) updateRect:(nsIntRect)aRect
|
||||
{
|
||||
mUpdateRect.UnionRect(mUpdateRect, aRect);
|
||||
}
|
||||
|
||||
- (void) setDrawFunc:(DrawPluginFunc)aFunc
|
||||
pluginInstance:(void*)aPluginInstance
|
||||
{
|
||||
mDrawFunc = aFunc;
|
||||
mPluginInstance = aPluginInstance;
|
||||
}
|
||||
|
||||
- (void)drawInContext:(CGContextRef)aCGContext
|
||||
{
|
||||
::CGContextSaveGState(aCGContext);
|
||||
::CGContextTranslateCTM(aCGContext, 0, self.bounds.size.height);
|
||||
::CGContextScaleCTM(aCGContext, (CGFloat) 1, (CGFloat) -1);
|
||||
|
||||
mUpdateRect = nsIntRect::Truncate(0, 0, self.bounds.size.width, self.bounds.size.height);
|
||||
|
||||
mDrawFunc(aCGContext, mPluginInstance, mUpdateRect);
|
||||
|
||||
::CGContextRestoreGState(aCGContext);
|
||||
|
||||
mUpdateRect.SetEmpty();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
void* mozilla::plugins::PluginUtilsOSX::GetCGLayer(DrawPluginFunc aFunc,
|
||||
void* aPluginInstance,
|
||||
double aContentsScaleFactor) {
|
||||
CGBridgeLayer *bridgeLayer = [[CGBridgeLayer alloc] init];
|
||||
|
||||
// We need to make bridgeLayer behave properly when its superlayer changes
|
||||
// size (in nsCARenderer::SetBounds()).
|
||||
bridgeLayer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
|
||||
bridgeLayer.needsDisplayOnBoundsChange = YES;
|
||||
NSNull *nullValue = [NSNull null];
|
||||
NSDictionary *actions = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
nullValue, @"bounds",
|
||||
nullValue, @"contents",
|
||||
nullValue, @"contentsRect",
|
||||
nullValue, @"position",
|
||||
nil];
|
||||
[bridgeLayer setStyle:[NSDictionary dictionaryWithObject:actions forKey:@"actions"]];
|
||||
|
||||
// For reasons that aren't clear (perhaps one or more OS bugs), we can only
|
||||
// use full HiDPI resolution here if the tree is built with the 10.7 SDK or
|
||||
// up. If we build with the 10.6 SDK, changing the contentsScale property
|
||||
// of bridgeLayer (even to the same value) causes it to stop working (go
|
||||
// blank). This doesn't happen with objects that are members of the CALayer
|
||||
// class (as opposed to one of its subclasses).
|
||||
#if defined(MAC_OS_X_VERSION_10_7) && \
|
||||
MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
|
||||
if ([bridgeLayer respondsToSelector:@selector(setContentsScale:)]) {
|
||||
bridgeLayer.contentsScale = aContentsScaleFactor;
|
||||
}
|
||||
#endif
|
||||
|
||||
[bridgeLayer setDrawFunc:aFunc
|
||||
pluginInstance:aPluginInstance];
|
||||
return bridgeLayer;
|
||||
}
|
||||
|
||||
void mozilla::plugins::PluginUtilsOSX::ReleaseCGLayer(void *cgLayer) {
|
||||
CGBridgeLayer *bridgeLayer = (CGBridgeLayer*)cgLayer;
|
||||
[bridgeLayer release];
|
||||
}
|
||||
|
||||
void mozilla::plugins::PluginUtilsOSX::Repaint(void *caLayer, nsIntRect aRect) {
|
||||
CGBridgeLayer *bridgeLayer = (CGBridgeLayer*)caLayer;
|
||||
[CATransaction begin];
|
||||
[bridgeLayer updateRect:aRect];
|
||||
[bridgeLayer setNeedsDisplay];
|
||||
[bridgeLayer displayIfNeeded];
|
||||
[CATransaction commit];
|
||||
}
|
||||
|
||||
@interface EventProcessor : NSObject {
|
||||
RemoteProcessEvents aRemoteEvents;
|
||||
void *aPluginModule;
|
||||
}
|
||||
- (void)setRemoteEvents:(RemoteProcessEvents) remoteEvents pluginModule:(void*) pluginModule;
|
||||
- (void)onTick;
|
||||
@end
|
||||
|
||||
@implementation EventProcessor
|
||||
- (void) onTick
|
||||
{
|
||||
aRemoteEvents(aPluginModule);
|
||||
}
|
||||
|
||||
- (void)setRemoteEvents:(RemoteProcessEvents) remoteEvents pluginModule:(void*) pluginModule
|
||||
{
|
||||
aRemoteEvents = remoteEvents;
|
||||
aPluginModule = pluginModule;
|
||||
}
|
||||
@end
|
||||
|
||||
#define EVENT_PROCESS_DELAY 0.05 // 50 ms
|
||||
|
||||
NPError mozilla::plugins::PluginUtilsOSX::ShowCocoaContextMenu(void* aMenu, int aX, int aY, void* pluginModule, RemoteProcessEvents remoteEvent)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
// Set the native cursor to the OS default (an arrow) before displaying the
|
||||
// context menu. Otherwise (if the plugin has changed the cursor) it may
|
||||
// stay as the plugin has set it -- which means it may be invisible. We
|
||||
// need to do this because we display the context menu without making the
|
||||
// plugin process the foreground process. If we did, the cursor would
|
||||
// change to an arrow cursor automatically -- as it does in Chrome.
|
||||
[[NSCursor arrowCursor] set];
|
||||
|
||||
EventProcessor* eventProcessor = nullptr;
|
||||
NSTimer *eventTimer = nullptr;
|
||||
if (pluginModule) {
|
||||
// Create a timer to process browser events while waiting
|
||||
// on the menu. This prevents the browser from hanging
|
||||
// during the lifetime of the menu.
|
||||
eventProcessor = [[EventProcessor alloc] init];
|
||||
[eventProcessor setRemoteEvents:remoteEvent pluginModule:pluginModule];
|
||||
eventTimer = [NSTimer timerWithTimeInterval:EVENT_PROCESS_DELAY
|
||||
target:eventProcessor selector:@selector(onTick)
|
||||
userInfo:nil repeats:TRUE];
|
||||
// Use NSEventTrackingRunLoopMode otherwise the timer will
|
||||
// not fire during the right click menu.
|
||||
[[NSRunLoop currentRunLoop] addTimer:eventTimer
|
||||
forMode:NSEventTrackingRunLoopMode];
|
||||
}
|
||||
|
||||
NSMenu* nsmenu = reinterpret_cast<NSMenu*>(aMenu);
|
||||
NSPoint screen_point = ::NSMakePoint(aX, aY);
|
||||
|
||||
[nsmenu popUpMenuPositioningItem:nil atLocation:screen_point inView:nil];
|
||||
|
||||
if (pluginModule) {
|
||||
[eventTimer invalidate];
|
||||
[eventProcessor release];
|
||||
}
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NPERR_GENERIC_ERROR);
|
||||
}
|
||||
|
||||
void mozilla::plugins::PluginUtilsOSX::InvokeNativeEventLoop()
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
::CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.0, true);
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
|
||||
#define UNDOCUMENTED_SESSION_CONSTANT ((int)-2)
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
namespace PluginUtilsOSX {
|
||||
static void *sApplicationASN = NULL;
|
||||
static void *sApplicationInfoItem = NULL;
|
||||
} // namespace PluginUtilsOSX
|
||||
} // namespace plugins
|
||||
} // namespace mozilla
|
||||
|
||||
bool mozilla::plugins::PluginUtilsOSX::SetProcessName(const char* aProcessName) {
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
nsAutoreleasePool localPool;
|
||||
|
||||
if (!aProcessName || strcmp(aProcessName, "") == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NSString *currentName = [[[NSBundle mainBundle] localizedInfoDictionary]
|
||||
objectForKey:(NSString *)kCFBundleNameKey];
|
||||
|
||||
char formattedName[1024];
|
||||
SprintfLiteral(formattedName, "%s %s", [currentName UTF8String], aProcessName);
|
||||
|
||||
aProcessName = formattedName;
|
||||
|
||||
// This function is based on Chrome/Webkit's and relies on potentially dangerous SPI.
|
||||
typedef CFTypeRef (*LSGetASNType)();
|
||||
typedef OSStatus (*LSSetInformationItemType)(int, CFTypeRef,
|
||||
CFStringRef,
|
||||
CFStringRef,
|
||||
CFDictionaryRef*);
|
||||
|
||||
CFBundleRef launchServices = ::CFBundleGetBundleWithIdentifier(
|
||||
CFSTR("com.apple.LaunchServices"));
|
||||
if (!launchServices) {
|
||||
NS_WARNING("Failed to set process name: Could not open LaunchServices bundle");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sApplicationASN) {
|
||||
sApplicationASN = ::CFBundleGetFunctionPointerForName(launchServices,
|
||||
CFSTR("_LSGetCurrentApplicationASN"));
|
||||
}
|
||||
|
||||
LSGetASNType getASNFunc = reinterpret_cast<LSGetASNType>
|
||||
(sApplicationASN);
|
||||
|
||||
if (!sApplicationInfoItem) {
|
||||
sApplicationInfoItem = ::CFBundleGetFunctionPointerForName(launchServices,
|
||||
CFSTR("_LSSetApplicationInformationItem"));
|
||||
}
|
||||
|
||||
LSSetInformationItemType setInformationItemFunc
|
||||
= reinterpret_cast<LSSetInformationItemType>
|
||||
(sApplicationInfoItem);
|
||||
|
||||
void * displayNameKeyAddr = ::CFBundleGetDataPointerForName(launchServices,
|
||||
CFSTR("_kLSDisplayNameKey"));
|
||||
|
||||
CFStringRef displayNameKey = nil;
|
||||
if (displayNameKeyAddr) {
|
||||
displayNameKey = reinterpret_cast<CFStringRef>(*(CFStringRef*)displayNameKeyAddr);
|
||||
}
|
||||
|
||||
// Rename will fail without this
|
||||
ProcessSerialNumber psn;
|
||||
if (::GetCurrentProcess(&psn) != noErr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CFTypeRef currentAsn = getASNFunc();
|
||||
|
||||
if (!getASNFunc || !setInformationItemFunc ||
|
||||
!displayNameKey || !currentAsn) {
|
||||
NS_WARNING("Failed to set process name: Accessing launchServices failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
CFStringRef processName = ::CFStringCreateWithCString(nil,
|
||||
aProcessName,
|
||||
kCFStringEncodingASCII);
|
||||
if (!processName) {
|
||||
NS_WARNING("Failed to set process name: Could not create CFStringRef");
|
||||
return false;
|
||||
}
|
||||
|
||||
OSErr err = setInformationItemFunc(UNDOCUMENTED_SESSION_CONSTANT, currentAsn,
|
||||
displayNameKey, processName,
|
||||
nil); // Optional out param
|
||||
::CFRelease(processName);
|
||||
if (err != noErr) {
|
||||
NS_WARNING("Failed to set process name: LSSetInformationItemType err");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(false);
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
namespace PluginUtilsOSX {
|
||||
|
||||
size_t nsDoubleBufferCARenderer::GetFrontSurfaceWidth() {
|
||||
if (!HasFrontSurface()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return mFrontSurface->GetWidth();
|
||||
}
|
||||
|
||||
size_t nsDoubleBufferCARenderer::GetFrontSurfaceHeight() {
|
||||
if (!HasFrontSurface()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return mFrontSurface->GetHeight();
|
||||
}
|
||||
|
||||
double nsDoubleBufferCARenderer::GetFrontSurfaceContentsScaleFactor() {
|
||||
if (!HasFrontSurface()) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
return mFrontSurface->GetContentsScaleFactor();
|
||||
}
|
||||
|
||||
size_t nsDoubleBufferCARenderer::GetBackSurfaceWidth() {
|
||||
if (!HasBackSurface()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return mBackSurface->GetWidth();
|
||||
}
|
||||
|
||||
size_t nsDoubleBufferCARenderer::GetBackSurfaceHeight() {
|
||||
if (!HasBackSurface()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return mBackSurface->GetHeight();
|
||||
}
|
||||
|
||||
double nsDoubleBufferCARenderer::GetBackSurfaceContentsScaleFactor() {
|
||||
if (!HasBackSurface()) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
return mBackSurface->GetContentsScaleFactor();
|
||||
}
|
||||
|
||||
IOSurfaceID nsDoubleBufferCARenderer::GetFrontSurfaceID() {
|
||||
if (!HasFrontSurface()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return mFrontSurface->GetIOSurfaceID();
|
||||
}
|
||||
|
||||
bool nsDoubleBufferCARenderer::HasBackSurface() {
|
||||
return !!mBackSurface;
|
||||
}
|
||||
|
||||
bool nsDoubleBufferCARenderer::HasFrontSurface() {
|
||||
return !!mFrontSurface;
|
||||
}
|
||||
|
||||
bool nsDoubleBufferCARenderer::HasCALayer() {
|
||||
return !!mCALayer;
|
||||
}
|
||||
|
||||
void nsDoubleBufferCARenderer::SetCALayer(void *aCALayer) {
|
||||
mCALayer = aCALayer;
|
||||
}
|
||||
|
||||
bool nsDoubleBufferCARenderer::InitFrontSurface(size_t aWidth, size_t aHeight,
|
||||
double aContentsScaleFactor,
|
||||
AllowOfflineRendererEnum aAllowOfflineRenderer) {
|
||||
if (!mCALayer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mContentsScaleFactor = aContentsScaleFactor;
|
||||
mFrontSurface = MacIOSurface::CreateIOSurface(aWidth, aHeight, mContentsScaleFactor);
|
||||
if (!mFrontSurface) {
|
||||
mCARenderer = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mCARenderer) {
|
||||
mCARenderer = new nsCARenderer();
|
||||
if (!mCARenderer) {
|
||||
mFrontSurface = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
mCARenderer->AttachIOSurface(mFrontSurface);
|
||||
|
||||
nsresult result = mCARenderer->SetupRenderer(mCALayer,
|
||||
mFrontSurface->GetWidth(),
|
||||
mFrontSurface->GetHeight(),
|
||||
mContentsScaleFactor,
|
||||
aAllowOfflineRenderer);
|
||||
|
||||
if (result != NS_OK) {
|
||||
mCARenderer = nullptr;
|
||||
mFrontSurface = nullptr;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
mCARenderer->AttachIOSurface(mFrontSurface);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void nsDoubleBufferCARenderer::Render() {
|
||||
if (!HasFrontSurface() || !mCARenderer) {
|
||||
return;
|
||||
}
|
||||
|
||||
mCARenderer->Render(GetFrontSurfaceWidth(), GetFrontSurfaceHeight(),
|
||||
mContentsScaleFactor, nullptr);
|
||||
}
|
||||
|
||||
void nsDoubleBufferCARenderer::SwapSurfaces() {
|
||||
RefPtr<MacIOSurface> prevFrontSurface = mFrontSurface;
|
||||
mFrontSurface = mBackSurface;
|
||||
mBackSurface = prevFrontSurface;
|
||||
|
||||
if (mFrontSurface) {
|
||||
mCARenderer->AttachIOSurface(mFrontSurface);
|
||||
}
|
||||
}
|
||||
|
||||
void nsDoubleBufferCARenderer::ClearFrontSurface() {
|
||||
mFrontSurface = nullptr;
|
||||
if (!mFrontSurface && !mBackSurface) {
|
||||
mCARenderer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void nsDoubleBufferCARenderer::ClearBackSurface() {
|
||||
mBackSurface = nullptr;
|
||||
if (!mFrontSurface && !mBackSurface) {
|
||||
mCARenderer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace PluginUtilsOSX
|
||||
} // namespace plugins
|
||||
} // namespace mozilla
|
||||
|
||||
12
dom/plugins/ipc/interpose/moz.build
Normal file
12
dom/plugins/ipc/interpose/moz.build
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
SharedLibrary('plugin_child_interpose')
|
||||
|
||||
SOURCES += [ "%s.mm" % (LIBRARY_NAME) ]
|
||||
|
||||
OS_LIBS += ['-framework Carbon']
|
||||
|
||||
DIST_INSTALL = True
|
||||
134
dom/plugins/ipc/interpose/plugin_child_interpose.mm
Normal file
134
dom/plugins/ipc/interpose/plugin_child_interpose.mm
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Use "dyld interposing" to hook methods imported from other libraries in the
|
||||
// plugin child process. The basic technique is described at
|
||||
// http://books.google.com/books?id=K8vUkpOXhN4C&pg=PA73&lpg=PA73&dq=__interpose&source=bl&ots=OJnnXZYpZC&sig=o7I3lXvoduUi13SrPfOON7o3do4&hl=en&ei=AoehS9brCYGQNrvsmeUM&sa=X&oi=book_result&ct=result&resnum=6&ved=0CBsQ6AEwBQ#v=onepage&q=__interpose&f=false.
|
||||
// The idea of doing it for the plugin child process comes from Chromium code,
|
||||
// particularly from plugin_carbon_interpose_mac.cc
|
||||
// (http://codesearch.google.com/codesearch/p?hl=en#OAMlx_jo-ck/src/chrome/browser/plugin_carbon_interpose_mac.cc&q=nscursor&exact_package=chromium&d=1&l=168)
|
||||
// and from PluginProcessHost::Init() in plugin_process_host.cc
|
||||
// (http://codesearch.google.com/codesearch/p?hl=en#OAMlx_jo-ck/src/content/browser/plugin_process_host.cc&q=nscursor&exact_package=chromium&d=1&l=222).
|
||||
|
||||
// These hooks are needed to make certain OS calls work from the child process
|
||||
// (a background process) that would normally only work when called in the
|
||||
// parent process (the foreground process). They allow us to serialize
|
||||
// information from the child process to the parent process, so that the same
|
||||
// (or equivalent) calls can be made from the parent process.
|
||||
|
||||
// This file lives in a seperate module (libplugin_child_interpose.dylib),
|
||||
// which will get loaded by the OS before any other modules when the plugin
|
||||
// child process is launched (from GeckoChildProcessHost::
|
||||
// PerformAsyncLaunchInternal()). For this reason it shouldn't link in other
|
||||
// browser modules when loaded. Instead it should use dlsym() to load
|
||||
// pointers to the methods it wants to call in other modules.
|
||||
|
||||
#if !defined(__LP64__)
|
||||
|
||||
#include <dlfcn.h>
|
||||
#import <Carbon/Carbon.h>
|
||||
|
||||
// The header file QuickdrawAPI.h is missing on OS X 10.7 and up (though the
|
||||
// QuickDraw APIs defined in it are still present) -- so we need to supply the
|
||||
// relevant parts of its contents here. It's likely that Apple will eventually
|
||||
// remove the APIs themselves (probably in OS X 10.8), so we need to make them
|
||||
// weak imports, and test for their presence before using them.
|
||||
#if !defined(__QUICKDRAWAPI__)
|
||||
|
||||
struct Cursor;
|
||||
extern "C" void SetCursor(const Cursor * crsr) __attribute__((weak_import));
|
||||
|
||||
#endif /* __QUICKDRAWAPI__ */
|
||||
|
||||
BOOL (*OnSetThemeCursorPtr) (ThemeCursor) = NULL;
|
||||
BOOL (*OnSetCursorPtr) (const Cursor*) = NULL;
|
||||
BOOL (*OnHideCursorPtr) () = NULL;
|
||||
BOOL (*OnShowCursorPtr) () = NULL;
|
||||
|
||||
static BOOL loadXULPtrs()
|
||||
{
|
||||
if (!OnSetThemeCursorPtr) {
|
||||
// mac_plugin_interposing_child_OnSetThemeCursor(ThemeCursor cursor) is in
|
||||
// PluginInterposeOSX.mm
|
||||
OnSetThemeCursorPtr = (BOOL(*)(ThemeCursor))
|
||||
dlsym(RTLD_DEFAULT, "mac_plugin_interposing_child_OnSetThemeCursor");
|
||||
}
|
||||
if (!OnSetCursorPtr) {
|
||||
// mac_plugin_interposing_child_OnSetCursor(const Cursor* cursor) is in
|
||||
// PluginInterposeOSX.mm
|
||||
OnSetCursorPtr = (BOOL(*)(const Cursor*))
|
||||
dlsym(RTLD_DEFAULT, "mac_plugin_interposing_child_OnSetCursor");
|
||||
}
|
||||
if (!OnHideCursorPtr) {
|
||||
// mac_plugin_interposing_child_OnHideCursor() is in PluginInterposeOSX.mm
|
||||
OnHideCursorPtr = (BOOL(*)())
|
||||
dlsym(RTLD_DEFAULT, "mac_plugin_interposing_child_OnHideCursor");
|
||||
}
|
||||
if (!OnShowCursorPtr) {
|
||||
// mac_plugin_interposing_child_OnShowCursor() is in PluginInterposeOSX.mm
|
||||
OnShowCursorPtr = (BOOL(*)())
|
||||
dlsym(RTLD_DEFAULT, "mac_plugin_interposing_child_OnShowCursor");
|
||||
}
|
||||
return (OnSetCursorPtr && OnSetThemeCursorPtr && OnHideCursorPtr && OnShowCursorPtr);
|
||||
}
|
||||
|
||||
static OSStatus MacPluginChildSetThemeCursor(ThemeCursor cursor)
|
||||
{
|
||||
if (loadXULPtrs()) {
|
||||
OnSetThemeCursorPtr(cursor);
|
||||
}
|
||||
return ::SetThemeCursor(cursor);
|
||||
}
|
||||
|
||||
static void MacPluginChildSetCursor(const Cursor* cursor)
|
||||
{
|
||||
if (::SetCursor) {
|
||||
if (loadXULPtrs()) {
|
||||
OnSetCursorPtr(cursor);
|
||||
}
|
||||
::SetCursor(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
static CGError MacPluginChildCGDisplayHideCursor(CGDirectDisplayID display)
|
||||
{
|
||||
if (loadXULPtrs()) {
|
||||
OnHideCursorPtr();
|
||||
}
|
||||
return ::CGDisplayHideCursor(display);
|
||||
}
|
||||
|
||||
static CGError MacPluginChildCGDisplayShowCursor(CGDirectDisplayID display)
|
||||
{
|
||||
if (loadXULPtrs()) {
|
||||
OnShowCursorPtr();
|
||||
}
|
||||
return ::CGDisplayShowCursor(display);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
struct interpose_substitution {
|
||||
const void* replacement;
|
||||
const void* original;
|
||||
};
|
||||
|
||||
#define INTERPOSE_FUNCTION(function) \
|
||||
{ reinterpret_cast<const void*>(MacPluginChild##function), \
|
||||
reinterpret_cast<const void*>(function) }
|
||||
|
||||
__attribute__((used)) static const interpose_substitution substitutions[]
|
||||
__attribute__((section("__DATA, __interpose"))) = {
|
||||
INTERPOSE_FUNCTION(SetThemeCursor),
|
||||
INTERPOSE_FUNCTION(CGDisplayHideCursor),
|
||||
INTERPOSE_FUNCTION(CGDisplayShowCursor),
|
||||
// SetCursor() and other QuickDraw APIs will probably be removed in OS X
|
||||
// 10.8. But this will make 'SetCursor' NULL, which will just stop the OS
|
||||
// from interposing it (tested using an INTERPOSE_FUNCTION_BROKEN macro
|
||||
// that just sets the second address of each tuple to NULL).
|
||||
INTERPOSE_FUNCTION(SetCursor),
|
||||
};
|
||||
|
||||
#endif // !__LP64__
|
||||
|
|
@ -3,6 +3,9 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
DIRS += ['interpose']
|
||||
|
||||
EXPORTS.mozilla += [
|
||||
'PluginLibrary.h',
|
||||
]
|
||||
|
|
@ -13,6 +16,7 @@ EXPORTS.mozilla.plugins += [
|
|||
'BrowserStreamParent.h',
|
||||
'ChildAsyncCall.h',
|
||||
'ChildTimer.h',
|
||||
'NPEventOSX.h',
|
||||
'NPEventUnix.h',
|
||||
'NPEventWindows.h',
|
||||
'PluginAsyncSurrogate.h',
|
||||
|
|
@ -32,6 +36,7 @@ EXPORTS.mozilla.plugins += [
|
|||
'PluginScriptableObjectUtils.h',
|
||||
'PluginStreamChild.h',
|
||||
'PluginStreamParent.h',
|
||||
'PluginUtilsOSX.h',
|
||||
'PluginWidgetChild.h',
|
||||
'PluginWidgetParent.h',
|
||||
'StreamNotifyChild.h',
|
||||
|
|
@ -53,6 +58,11 @@ if CONFIG['OS_ARCH'] == 'WINNT':
|
|||
'hangui',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
EXPORTS.mozilla.plugins += [
|
||||
'PluginInterposeOSX.h',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
'BrowserStreamChild.cpp',
|
||||
'BrowserStreamParent.cpp',
|
||||
|
|
@ -76,6 +86,12 @@ SOURCES += [
|
|||
'PluginWidgetParent.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
SOURCES += [
|
||||
'PluginInterposeOSX.mm',
|
||||
'PluginUtilsOSX.mm',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
SOURCES += [
|
||||
'D3D11SurfaceHolder.cpp',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue