Add support for loading cfm plugins in OSX mach-o builds.

Changes backported from the CHIMERA_M1_0_1_BRANCH branch.
Bug #155256 r=peterl sr=sfraser
This commit is contained in:
seawood%netscape.com 2002-11-06 01:24:57 +00:00
parent a06b5d29ca
commit 555e341493
14 changed files with 718 additions and 417 deletions

View File

@ -96,6 +96,12 @@ ifdef MOZ_SVG
EXTRA_DSO_LDOPTS += $(MOZ_LIBART_LIBS)
endif
ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
EXTRA_DSO_LDOPTS += \
$(TK_LIBS) \
$(NULL)
endif
ifeq ($(MOZ_WIDGET_TOOLKIT),os2)
EXPORT_OBJS = 1
endif

View File

@ -309,7 +309,8 @@ public:
NS_DECL_NSITIMERCALLBACK
void CancelTimer();
void StartTimer();
// nsIScrollPositionListener interface
NS_IMETHOD ScrollPositionWillChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY);
NS_IMETHOD ScrollPositionDidChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY);
@ -323,9 +324,10 @@ public:
void SetPluginHost(nsIPluginHost* aHost);
#ifdef XP_MAC
void FixUpPluginWindow();
#if defined(XP_MAC) || defined(XP_MACOSX)
nsPluginPort* FixUpPluginWindow();
void GUItoMacEvent(const nsGUIEvent& anEvent, EventRecord& aMacEvent);
void Composite();
#endif
private:
@ -357,7 +359,7 @@ private:
static void ConvertTwipsToPixels(nsIPresContext& aPresContext, nsRect& aTwipsRect, nsRect& aPixelRect);
// Mac specific code to fix up port position and clip during paint
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
// get the absolute widget position and clip
static void GetWidgetPosClipAndVis(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY, nsRect& aClipRect, PRBool& aIsVisible);
// convert relative coordinates to absolute
@ -366,9 +368,7 @@ static void ConvertTwipsToPixels(nsIPresContext& aPresContext, nsRect& aTwipsRec
nsObjectFrame::~nsObjectFrame()
{
// beard: stop the timer explicitly to reduce reference count.
if (nsnull != mInstanceOwner) {
mInstanceOwner->CancelTimer();
mInstanceOwner->Destroy();
}
@ -796,7 +796,7 @@ nsObjectFrame::CreateWidget(nsIPresContext* aPresContext,
// Turn off double buffering on the Mac. This depends on bug 49743 and partially
// fixes 32327, 19931 amd 51787
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
nsCOMPtr<nsIPref> prefs(do_GetService(kPrefServiceCID));
PRBool doubleBuffer = PR_FALSE;
prefs ? prefs->GetBoolPref("plugin.enable_double_buffer", &doubleBuffer) : 0;
@ -1273,7 +1273,7 @@ nsObjectFrame::InstantiatePlugin(nsIPresContext* aPresContext,
// happen until we have finished the reflow process.
window->clipRect.top = 0;
window->clipRect.left = 0;
#ifndef XP_MAC
#if !(defined(XP_MAC) || defined(XP_MACOSX))
window->clipRect.bottom = NSTwipsToIntPixels(aMetrics.height, t2p);
window->clipRect.right = NSTwipsToIntPixels(aMetrics.width, t2p);
#else
@ -1349,7 +1349,7 @@ nsObjectFrame::ReinstantiatePlugin(nsIPresContext* aPresContext, nsHTMLReflowMet
// ignore this for now on the Mac because the widget is not properly positioned
// yet and won't be until we have finished the reflow process.
#ifndef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
window->clipRect.top = 0;
window->clipRect.left = 0;
window->clipRect.bottom = NSTwipsToIntPixels(aMetrics.height, t2p);
@ -1559,9 +1559,9 @@ nsObjectFrame::DidReflow(nsIPresContext* aPresContext,
nsPluginNativeWindow *window = (nsPluginNativeWindow *)win;
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
mInstanceOwner->FixUpPluginWindow();
#endif // XP_MAC
#endif // XP_MAC || XP_MACOSX
if (bHidden)
return rv;
@ -1717,7 +1717,7 @@ nsObjectFrame::Paint(nsIPresContext* aPresContext,
window.window = &port;
npprint.print.embedPrint.platformPrint = (void*)window.window;
#elif defined (XP_UNIX)
#elif defined (XP_UNIX) && !defined(XP_MACOSX)
// UNIX does things completely differently
PRUnichar *printfile = nsnull;
if (printSettings) {
@ -1748,7 +1748,6 @@ nsObjectFrame::Paint(nsIPresContext* aPresContext,
// send off print info to plugin
rv = pi->Print(&npprint);
#if defined(XP_MAC) && !TARGET_CARBON
// Clean-up on Mac
::SetOrigin(0,0);
@ -1766,7 +1765,7 @@ nsObjectFrame::Paint(nsIPresContext* aPresContext,
}
// Screen painting code
#if defined (XP_MAC)
#if defined (XP_MAC) || defined(XP_MACOSX)
// delegate all painting to the plugin instance.
if ((NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) && mInstanceOwner)
mInstanceOwner->Paint(aDirtyRect);
@ -2182,7 +2181,7 @@ nsPluginInstanceOwner::~nsPluginInstanceOwner()
NS_IF_RELEASE(mWidget);
mContext = nsnull;
#ifdef XP_UNIX
#if defined(XP_UNIX) && !defined(XP_MACOSX)
// the mem for this struct is allocated
// by PR_MALLOC in ns4xPluginInstance.cpp:ns4xPluginInstance::SetWindow()
if (mPluginWindow && mPluginWindow->ws_info) {
@ -3132,15 +3131,15 @@ nsresult nsPluginInstanceOwner::EnsureCachedAttrParamArrays()
// Here's where we forward events to plugins.
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
#if TARGET_CARBON
static void InitializeEventRecord(EventRecord* event)
{
memset(event, 0, sizeof(EventRecord));
GetGlobalMouse(&event->where);
event->when = TickCount();
event->modifiers = GetCurrentKeyModifiers();
::GetGlobalMouse(&event->where);
event->when = ::TickCount();
event->modifiers = ::GetCurrentKeyModifiers();
}
#else
inline void InitializeEventRecord(EventRecord* event) { ::OSEventAvail(0, event); }
@ -3182,17 +3181,19 @@ void nsPluginInstanceOwner::GUItoMacEvent(const nsGUIEvent& anEvent, EventRecord
nsresult nsPluginInstanceOwner::ScrollPositionWillChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY)
{
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
if (mInstance != NULL) {
EventRecord scrollEvent;
InitializeEventRecord(&scrollEvent);
scrollEvent.what = nsPluginEventType_ScrollingBeginsEvent;
nsPluginPort* pluginPort = GetPluginPort();
nsPluginEvent pluginEvent = { &scrollEvent, nsPluginPlatformWindowRef(pluginPort->port) };
if (pluginPort) {
nsPluginEvent pluginEvent = { &scrollEvent, nsPluginPlatformWindowRef(GetWindowFromPort(pluginPort->port)) };
PRBool eventHandled = PR_FALSE;
mInstance->HandleEvent(&pluginEvent, &eventHandled);
PRBool eventHandled = PR_FALSE;
mInstance->HandleEvent(&pluginEvent, &eventHandled);
}
}
#endif
return NS_OK;
@ -3200,20 +3201,28 @@ nsresult nsPluginInstanceOwner::ScrollPositionWillChange(nsIScrollableView* aScr
nsresult nsPluginInstanceOwner::ScrollPositionDidChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY)
{
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
if (mInstance != NULL) {
EventRecord scrollEvent;
InitializeEventRecord(&scrollEvent);
scrollEvent.what = nsPluginEventType_ScrollingEndsEvent;
nsPluginPort* pluginPort = GetPluginPort();
nsPluginEvent pluginEvent = { &scrollEvent, nsPluginPlatformWindowRef(pluginPort->port) };
PRBool eventHandled = PR_FALSE;
mInstance->HandleEvent(&pluginEvent, &eventHandled);
if (!eventHandled) {
nsPluginPort* pluginPort = FixUpPluginWindow();
if (pluginPort) {
nsPluginEvent pluginEvent = { &scrollEvent, nsPluginPlatformWindowRef(GetWindowFromPort(pluginPort->port)) };
PRBool eventHandled = PR_FALSE;
mInstance->HandleEvent(&pluginEvent, &eventHandled);
#if defined(XP_MACOSX)
// FIXME - Only invalidate the newly revealed amount.
// mWidget->Invalidate(PR_TRUE);
Composite();
#else
if (!eventHandled) {
nsRect bogus(0,0,0,0);
Paint(bogus, 0); // send an update event to the plugin
}
#endif
}
}
#endif
@ -3235,10 +3244,10 @@ nsresult nsPluginInstanceOwner::Blur(nsIDOMEvent * aFocusEvent)
nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent)
{
#ifndef XP_MAC
#if !(defined(XP_MAC) || defined(XP_MACOSX))
if (!mPluginWindow || nsPluginWindowType_Window == mPluginWindow->type)
return NS_ERROR_FAILURE; // means consume event
// continue only for cases without child window
// continue only for cases without child window
#endif
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(aFocusEvent));
@ -3370,7 +3379,7 @@ nsresult nsPluginInstanceOwner::KeyUp(nsIDOMEvent* aKeyEvent)
nsresult nsPluginInstanceOwner::KeyPress(nsIDOMEvent* aKeyEvent)
{
#ifdef XP_MAC // send KeyPress events only on Mac
#if defined(XP_MAC) || defined(XP_MACOSX) // send KeyPress events only on Mac
return DispatchKeyToPlugin(aKeyEvent);
#else
if (mInstance) {
@ -3389,7 +3398,7 @@ nsresult nsPluginInstanceOwner::KeyPress(nsIDOMEvent* aKeyEvent)
nsresult nsPluginInstanceOwner::DispatchKeyToPlugin(nsIDOMEvent* aKeyEvent)
{
#ifndef XP_MAC
#if !(defined(XP_MAC) || defined(XP_MACOSX))
if (!mPluginWindow || nsPluginWindowType_Window == mPluginWindow->type)
return NS_ERROR_FAILURE; // means consume event
// continue only for cases without child window
@ -3427,7 +3436,7 @@ nsresult nsPluginInstanceOwner::DispatchKeyToPlugin(nsIDOMEvent* aKeyEvent)
nsresult
nsPluginInstanceOwner::MouseMove(nsIDOMEvent* aMouseEvent)
{
#ifndef XP_MAC
#if !(defined(XP_MAC) || defined(XP_MACOSX))
if (!mPluginWindow || nsPluginWindowType_Window == mPluginWindow->type)
return NS_ERROR_FAILURE; // means consume event
// continue only for cases without child window
@ -3459,7 +3468,7 @@ nsPluginInstanceOwner::MouseMove(nsIDOMEvent* aMouseEvent)
nsresult
nsPluginInstanceOwner::MouseDown(nsIDOMEvent* aMouseEvent)
{
#ifndef XP_MAC
#if !(defined(XP_MAC) || defined(XP_MACOSX))
if (!mPluginWindow || nsPluginWindowType_Window == mPluginWindow->type)
return NS_ERROR_FAILURE; // means consume event
// continue only for cases without child window
@ -3523,7 +3532,7 @@ nsPluginInstanceOwner::MouseOut(nsIDOMEvent* aMouseEvent)
nsresult nsPluginInstanceOwner::DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent)
{
#ifndef XP_MAC
#if !(defined(XP_MAC) || defined(XP_MACOSX))
if (!mPluginWindow || nsPluginWindowType_Window == mPluginWindow->type)
return NS_ERROR_FAILURE; // means consume event
// continue only for cases without child window
@ -3572,7 +3581,7 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const nsGUIEvent& anEvent)
if (!mInstance) // if mInstance is null, we shouldn't be here
return rv;
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
if (mWidget != NULL) { // check for null mWidget
EventRecord* event = (EventRecord*)anEvent.nativeMsg;
if ((event == NULL) || (event->what == nullEvent) ||
@ -3585,10 +3594,12 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const nsGUIEvent& anEvent)
GUItoMacEvent(anEvent, macEvent);
event = &macEvent;
}
nsPluginPort* port = (nsPluginPort*)mWidget->GetNativeData(NS_NATIVE_PLUGIN_PORT);
nsPluginEvent pluginEvent = { event, nsPluginPlatformWindowRef(port->port) };
PRBool eventHandled = PR_FALSE;
mInstance->HandleEvent(&pluginEvent, &eventHandled);
nsPluginPort* pluginPort = FixUpPluginWindow();
if (pluginPort) {
nsPluginEvent pluginEvent = { event, nsPluginPlatformWindowRef(GetWindowFromPort(pluginPort->port)) };
mInstance->HandleEvent(&pluginEvent, &eventHandled);
}
if (eventHandled && !(anEvent.message == NS_MOUSE_LEFT_BUTTON_DOWN && !mContentFocused))
rv = nsEventStatus_eConsumeNoDefault;
}
@ -3615,6 +3626,9 @@ nsPluginInstanceOwner::Destroy()
nsCOMPtr<nsIContent> content;
mOwner->GetContent(getter_AddRefs(content));
// stop the timer explicitly to reduce reference count.
CancelTimer();
// unregister context menu listener
if (mCXMenuListener) {
mCXMenuListener->Destroy(mOwner);
@ -3724,9 +3738,7 @@ void nsPluginInstanceOwner::Paint(const nsRect& aDirtyRect, PRUint32 ndc)
if(!mInstance)
return;
#ifdef XP_MAC
nsPluginPort* pluginPort = GetPluginPort();
#if defined(XP_MAC) || defined(XP_MACOSX)
#ifdef DO_DIRTY_INTERSECT // aDirtyRect isn't always correct, see bug 56128
nsPoint rel(aDirtyRect.x, aDirtyRect.y);
nsPoint abs(0,0);
@ -3741,16 +3753,24 @@ void nsPluginInstanceOwner::Paint(const nsRect& aDirtyRect, PRUint32 ndc)
nsRect absDirtyRectInPixels;
ConvertTwipsToPixels(*mContext, absDirtyRect, absDirtyRectInPixels);
#endif
FixUpPluginWindow();
EventRecord updateEvent;
InitializeEventRecord(&updateEvent);
updateEvent.what = updateEvt;
updateEvent.message = UInt32(pluginPort->port);
nsPluginPort* pluginPort = FixUpPluginWindow();
if (pluginPort) {
EventRecord updateEvent;
InitializeEventRecord(&updateEvent);
updateEvent.what = updateEvt;
updateEvent.message = UInt32(GetWindowFromPort(pluginPort->port));
nsPluginEvent pluginEvent = { &updateEvent, nsPluginPlatformWindowRef(pluginPort->port) };
PRBool eventHandled = PR_FALSE;
mInstance->HandleEvent(&pluginEvent, &eventHandled);
GrafPtr oldPort;
::GetPort(&oldPort);
::SetPort((GrafPtr)pluginPort->port);
nsPluginEvent pluginEvent = { &updateEvent, nsPluginPlatformWindowRef(GetWindowFromPort(pluginPort->port)) };
PRBool eventHandled = PR_FALSE;
mInstance->HandleEvent(&pluginEvent, &eventHandled);
::SetPort(oldPort);
}
#endif
#ifdef XP_WIN
@ -3781,12 +3801,13 @@ void nsPluginInstanceOwner::Paint(const nsRect& aDirtyRect, PRUint32 ndc)
NS_IMETHODIMP nsPluginInstanceOwner::Notify(nsITimer* /* timer */)
{
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
// validate the plugin clipping information by syncing the plugin window info to
// reflect the current widget location. This makes sure that everything is updated
// correctly in the event of scrolling in the window.
FixUpPluginWindow();
if (mInstance != NULL) {
nsPluginPort* pluginPort = FixUpPluginWindow();
if (pluginPort) {
EventRecord idleEvent;
InitializeEventRecord(&idleEvent);
idleEvent.what = nullEvent;
@ -3796,23 +3817,28 @@ NS_IMETHODIMP nsPluginInstanceOwner::Notify(nsITimer* /* timer */)
if (!mWidgetVisible)
idleEvent.where.h = idleEvent.where.v = 20000;
nsPluginPort* pluginPort = GetPluginPort();
nsPluginEvent pluginEvent = { &idleEvent, nsPluginPlatformWindowRef(pluginPort->port) };
nsPluginEvent pluginEvent = { &idleEvent, nsPluginPlatformWindowRef(GetWindowFromPort(pluginPort->port)) };
PRBool eventHandled = PR_FALSE;
mInstance->HandleEvent(&pluginEvent, &eventHandled);
}
}
#endif
return NS_OK;
}
#ifndef REPEATING_TIMERS
// reprime the timer? currently have to create a new timer for each call, which is
// kind of wasteful. need to get periodic timers working on all platforms.
nsresult rv;
mPluginTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
if (NS_SUCCEEDED(rv))
mPluginTimer->InitWithCallback(this, 1020 / 60, nsITimer::TYPE_ONE_SHOT);
void nsPluginInstanceOwner::StartTimer()
{
#if defined(XP_MAC) || defined(XP_MACOSX)
nsresult rv;
// start a periodic timer to provide null events to the plugin instance.
if (!mPluginTimer) {
mPluginTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
if (rv == NS_OK)
rv = mPluginTimer->InitWithCallback(this, 1020 / 60, nsITimer::TYPE_REPEATING_SLACK);
}
#endif
return NS_OK;
}
void nsPluginInstanceOwner::CancelTimer()
@ -4024,13 +4050,8 @@ NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void)
mPluginWindow->type = nsPluginWindowType_Window;
mPluginWindow->window = GetPluginPort();
#if defined(XP_MAC)
// Is this needed in the windowless case ???
// start a periodic timer to provide null events to the plugin instance.
mPluginTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
if (rv == NS_OK)
rv = mPluginTimer->InitWithCallback(this, 1020 / 60, nsITimer::TYPE_REPEATING_SLACK);
#endif
// start the idle timer.
StartTimer();
}
}
}
@ -4059,7 +4080,7 @@ static void ConvertTwipsToPixels(nsIPresContext& aPresContext, nsRect& aTwipsRec
}
// Mac specific code to fix up the port location and clipping region
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
// calculate the absolute position and clip for a widget
// and use other windows in calculating the clip
static void GetWidgetPosClipAndVis(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY,
@ -4110,10 +4131,6 @@ static void GetWidgetPosClipAndVis(nsIWidget* aWidget,nscoord& aAbsX, nscoord& a
// if we are not visible, clear out the plugin's clip so it won't paint
if (!aIsVisible)
aClipRect.Empty();
//printf("--------------\n");
//printf("Widget clip X %d Y %d rect %d %d %d %d\n", aAbsX, aAbsY, aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height );
//printf("--------------\n");
}
#ifdef DO_DIRTY_INTERSECT
@ -4177,15 +4194,21 @@ inline PRUint16 COLOR8TOCOLOR16(PRUint8 color8)
return (color8 << 8) | color8; /* (color8 * 257) == (color8 * 0x0101) */
}
void nsPluginInstanceOwner::FixUpPluginWindow()
nsPluginPort* nsPluginInstanceOwner::FixUpPluginWindow()
{
if (!mWidget || !mPluginWindow)
return;
return nsnull;
nsPluginPort* pluginPort = GetPluginPort();
nscoord absWidgetX = 0;
nscoord absWidgetY = 0;
nsRect widgetClip(0,0,0,0);
#if defined(MOZ_WIDGET_COCOA)
if (!pluginPort)
return nsnull;
#endif
// first, check our view for CSS visibility style
nsIView *view;
mOwner->GetView(mContext, &view);
@ -4195,12 +4218,17 @@ void nsPluginInstanceOwner::FixUpPluginWindow()
GetWidgetPosClipAndVis(mWidget,absWidgetX,absWidgetY,widgetClip,isVisible);
if (mWidgetVisible != isVisible)
mWidgetVisible = isVisible;
#if defined(MOZ_WIDGET_COCOA)
// set the port coordinates
mPluginWindow->x = -pluginPort->portx;
mPluginWindow->y = -pluginPort->porty;
widgetClip.x += mPluginWindow->x - absWidgetX;
widgetClip.y += mPluginWindow->y - absWidgetY;
#else
// set the port coordinates
mPluginWindow->x = absWidgetX;
mPluginWindow->y = absWidgetY;
#endif
// fix up the clipping region
mPluginWindow->clipRect.top = widgetClip.y;
@ -4212,7 +4240,6 @@ void nsPluginInstanceOwner::FixUpPluginWindow()
// the background color needs to be set here on the plugin port
GrafPtr savePort;
::GetPort(&savePort); // save our current port
nsPluginPort* pluginPort = GetPluginPort();
::SetPort((GrafPtr)pluginPort->port);
nscolor color = mWidget->GetBackgroundColor();
@ -4222,7 +4249,46 @@ void nsPluginInstanceOwner::FixUpPluginWindow()
macColor.blue = COLOR8TOCOLOR16(NS_GET_B(color));
::RGBBackColor(&macColor);
::SetPort(savePort); // restore port
if (mWidgetVisible != isVisible) {
mWidgetVisible = isVisible;
// must do this to disable async Java Applet drawing
if (isVisible) {
mInstance->SetWindow(mPluginWindow);
} else {
mInstance->SetWindow(nsnull);
// switching states, do not draw
pluginPort = nsnull;
}
}
#if defined(MOZ_WIDGET_COCOA)
if (!mWidgetVisible) {
mPluginWindow->clipRect.right = mPluginWindow->clipRect.left;
mPluginWindow->clipRect.bottom = mPluginWindow->clipRect.top;
}
#endif
return pluginPort;
}
#endif // XP_MAC
void nsPluginInstanceOwner::Composite()
{
//no reference count on view
nsIView* view;
nsresult rv = mOwner->GetView(mContext, &view);
if (NS_SUCCEEDED(rv) && view) {
nsIViewManager* manager;
rv = view->GetViewManager(manager);
//set flags to not do a synchronous update, force update does the redraw
if (NS_SUCCEEDED(rv) && manager) {
rv = manager->UpdateView(view, NS_VMREFRESH_IMMEDIATE);
NS_RELEASE(manager);
}
}
}
#endif // XP_MAC || XP_MACOSX

View File

@ -309,7 +309,8 @@ public:
NS_DECL_NSITIMERCALLBACK
void CancelTimer();
void StartTimer();
// nsIScrollPositionListener interface
NS_IMETHOD ScrollPositionWillChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY);
NS_IMETHOD ScrollPositionDidChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY);
@ -323,9 +324,10 @@ public:
void SetPluginHost(nsIPluginHost* aHost);
#ifdef XP_MAC
void FixUpPluginWindow();
#if defined(XP_MAC) || defined(XP_MACOSX)
nsPluginPort* FixUpPluginWindow();
void GUItoMacEvent(const nsGUIEvent& anEvent, EventRecord& aMacEvent);
void Composite();
#endif
private:
@ -357,7 +359,7 @@ private:
static void ConvertTwipsToPixels(nsIPresContext& aPresContext, nsRect& aTwipsRect, nsRect& aPixelRect);
// Mac specific code to fix up port position and clip during paint
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
// get the absolute widget position and clip
static void GetWidgetPosClipAndVis(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY, nsRect& aClipRect, PRBool& aIsVisible);
// convert relative coordinates to absolute
@ -366,9 +368,7 @@ static void ConvertTwipsToPixels(nsIPresContext& aPresContext, nsRect& aTwipsRec
nsObjectFrame::~nsObjectFrame()
{
// beard: stop the timer explicitly to reduce reference count.
if (nsnull != mInstanceOwner) {
mInstanceOwner->CancelTimer();
mInstanceOwner->Destroy();
}
@ -796,7 +796,7 @@ nsObjectFrame::CreateWidget(nsIPresContext* aPresContext,
// Turn off double buffering on the Mac. This depends on bug 49743 and partially
// fixes 32327, 19931 amd 51787
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
nsCOMPtr<nsIPref> prefs(do_GetService(kPrefServiceCID));
PRBool doubleBuffer = PR_FALSE;
prefs ? prefs->GetBoolPref("plugin.enable_double_buffer", &doubleBuffer) : 0;
@ -1273,7 +1273,7 @@ nsObjectFrame::InstantiatePlugin(nsIPresContext* aPresContext,
// happen until we have finished the reflow process.
window->clipRect.top = 0;
window->clipRect.left = 0;
#ifndef XP_MAC
#if !(defined(XP_MAC) || defined(XP_MACOSX))
window->clipRect.bottom = NSTwipsToIntPixels(aMetrics.height, t2p);
window->clipRect.right = NSTwipsToIntPixels(aMetrics.width, t2p);
#else
@ -1349,7 +1349,7 @@ nsObjectFrame::ReinstantiatePlugin(nsIPresContext* aPresContext, nsHTMLReflowMet
// ignore this for now on the Mac because the widget is not properly positioned
// yet and won't be until we have finished the reflow process.
#ifndef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
window->clipRect.top = 0;
window->clipRect.left = 0;
window->clipRect.bottom = NSTwipsToIntPixels(aMetrics.height, t2p);
@ -1559,9 +1559,9 @@ nsObjectFrame::DidReflow(nsIPresContext* aPresContext,
nsPluginNativeWindow *window = (nsPluginNativeWindow *)win;
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
mInstanceOwner->FixUpPluginWindow();
#endif // XP_MAC
#endif // XP_MAC || XP_MACOSX
if (bHidden)
return rv;
@ -1717,7 +1717,7 @@ nsObjectFrame::Paint(nsIPresContext* aPresContext,
window.window = &port;
npprint.print.embedPrint.platformPrint = (void*)window.window;
#elif defined (XP_UNIX)
#elif defined (XP_UNIX) && !defined(XP_MACOSX)
// UNIX does things completely differently
PRUnichar *printfile = nsnull;
if (printSettings) {
@ -1748,7 +1748,6 @@ nsObjectFrame::Paint(nsIPresContext* aPresContext,
// send off print info to plugin
rv = pi->Print(&npprint);
#if defined(XP_MAC) && !TARGET_CARBON
// Clean-up on Mac
::SetOrigin(0,0);
@ -1766,7 +1765,7 @@ nsObjectFrame::Paint(nsIPresContext* aPresContext,
}
// Screen painting code
#if defined (XP_MAC)
#if defined (XP_MAC) || defined(XP_MACOSX)
// delegate all painting to the plugin instance.
if ((NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) && mInstanceOwner)
mInstanceOwner->Paint(aDirtyRect);
@ -2182,7 +2181,7 @@ nsPluginInstanceOwner::~nsPluginInstanceOwner()
NS_IF_RELEASE(mWidget);
mContext = nsnull;
#ifdef XP_UNIX
#if defined(XP_UNIX) && !defined(XP_MACOSX)
// the mem for this struct is allocated
// by PR_MALLOC in ns4xPluginInstance.cpp:ns4xPluginInstance::SetWindow()
if (mPluginWindow && mPluginWindow->ws_info) {
@ -3132,15 +3131,15 @@ nsresult nsPluginInstanceOwner::EnsureCachedAttrParamArrays()
// Here's where we forward events to plugins.
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
#if TARGET_CARBON
static void InitializeEventRecord(EventRecord* event)
{
memset(event, 0, sizeof(EventRecord));
GetGlobalMouse(&event->where);
event->when = TickCount();
event->modifiers = GetCurrentKeyModifiers();
::GetGlobalMouse(&event->where);
event->when = ::TickCount();
event->modifiers = ::GetCurrentKeyModifiers();
}
#else
inline void InitializeEventRecord(EventRecord* event) { ::OSEventAvail(0, event); }
@ -3182,17 +3181,19 @@ void nsPluginInstanceOwner::GUItoMacEvent(const nsGUIEvent& anEvent, EventRecord
nsresult nsPluginInstanceOwner::ScrollPositionWillChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY)
{
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
if (mInstance != NULL) {
EventRecord scrollEvent;
InitializeEventRecord(&scrollEvent);
scrollEvent.what = nsPluginEventType_ScrollingBeginsEvent;
nsPluginPort* pluginPort = GetPluginPort();
nsPluginEvent pluginEvent = { &scrollEvent, nsPluginPlatformWindowRef(pluginPort->port) };
if (pluginPort) {
nsPluginEvent pluginEvent = { &scrollEvent, nsPluginPlatformWindowRef(GetWindowFromPort(pluginPort->port)) };
PRBool eventHandled = PR_FALSE;
mInstance->HandleEvent(&pluginEvent, &eventHandled);
PRBool eventHandled = PR_FALSE;
mInstance->HandleEvent(&pluginEvent, &eventHandled);
}
}
#endif
return NS_OK;
@ -3200,20 +3201,28 @@ nsresult nsPluginInstanceOwner::ScrollPositionWillChange(nsIScrollableView* aScr
nsresult nsPluginInstanceOwner::ScrollPositionDidChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY)
{
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
if (mInstance != NULL) {
EventRecord scrollEvent;
InitializeEventRecord(&scrollEvent);
scrollEvent.what = nsPluginEventType_ScrollingEndsEvent;
nsPluginPort* pluginPort = GetPluginPort();
nsPluginEvent pluginEvent = { &scrollEvent, nsPluginPlatformWindowRef(pluginPort->port) };
PRBool eventHandled = PR_FALSE;
mInstance->HandleEvent(&pluginEvent, &eventHandled);
if (!eventHandled) {
nsPluginPort* pluginPort = FixUpPluginWindow();
if (pluginPort) {
nsPluginEvent pluginEvent = { &scrollEvent, nsPluginPlatformWindowRef(GetWindowFromPort(pluginPort->port)) };
PRBool eventHandled = PR_FALSE;
mInstance->HandleEvent(&pluginEvent, &eventHandled);
#if defined(XP_MACOSX)
// FIXME - Only invalidate the newly revealed amount.
// mWidget->Invalidate(PR_TRUE);
Composite();
#else
if (!eventHandled) {
nsRect bogus(0,0,0,0);
Paint(bogus, 0); // send an update event to the plugin
}
#endif
}
}
#endif
@ -3235,10 +3244,10 @@ nsresult nsPluginInstanceOwner::Blur(nsIDOMEvent * aFocusEvent)
nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent)
{
#ifndef XP_MAC
#if !(defined(XP_MAC) || defined(XP_MACOSX))
if (!mPluginWindow || nsPluginWindowType_Window == mPluginWindow->type)
return NS_ERROR_FAILURE; // means consume event
// continue only for cases without child window
// continue only for cases without child window
#endif
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(aFocusEvent));
@ -3370,7 +3379,7 @@ nsresult nsPluginInstanceOwner::KeyUp(nsIDOMEvent* aKeyEvent)
nsresult nsPluginInstanceOwner::KeyPress(nsIDOMEvent* aKeyEvent)
{
#ifdef XP_MAC // send KeyPress events only on Mac
#if defined(XP_MAC) || defined(XP_MACOSX) // send KeyPress events only on Mac
return DispatchKeyToPlugin(aKeyEvent);
#else
if (mInstance) {
@ -3389,7 +3398,7 @@ nsresult nsPluginInstanceOwner::KeyPress(nsIDOMEvent* aKeyEvent)
nsresult nsPluginInstanceOwner::DispatchKeyToPlugin(nsIDOMEvent* aKeyEvent)
{
#ifndef XP_MAC
#if !(defined(XP_MAC) || defined(XP_MACOSX))
if (!mPluginWindow || nsPluginWindowType_Window == mPluginWindow->type)
return NS_ERROR_FAILURE; // means consume event
// continue only for cases without child window
@ -3427,7 +3436,7 @@ nsresult nsPluginInstanceOwner::DispatchKeyToPlugin(nsIDOMEvent* aKeyEvent)
nsresult
nsPluginInstanceOwner::MouseMove(nsIDOMEvent* aMouseEvent)
{
#ifndef XP_MAC
#if !(defined(XP_MAC) || defined(XP_MACOSX))
if (!mPluginWindow || nsPluginWindowType_Window == mPluginWindow->type)
return NS_ERROR_FAILURE; // means consume event
// continue only for cases without child window
@ -3459,7 +3468,7 @@ nsPluginInstanceOwner::MouseMove(nsIDOMEvent* aMouseEvent)
nsresult
nsPluginInstanceOwner::MouseDown(nsIDOMEvent* aMouseEvent)
{
#ifndef XP_MAC
#if !(defined(XP_MAC) || defined(XP_MACOSX))
if (!mPluginWindow || nsPluginWindowType_Window == mPluginWindow->type)
return NS_ERROR_FAILURE; // means consume event
// continue only for cases without child window
@ -3523,7 +3532,7 @@ nsPluginInstanceOwner::MouseOut(nsIDOMEvent* aMouseEvent)
nsresult nsPluginInstanceOwner::DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent)
{
#ifndef XP_MAC
#if !(defined(XP_MAC) || defined(XP_MACOSX))
if (!mPluginWindow || nsPluginWindowType_Window == mPluginWindow->type)
return NS_ERROR_FAILURE; // means consume event
// continue only for cases without child window
@ -3572,7 +3581,7 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const nsGUIEvent& anEvent)
if (!mInstance) // if mInstance is null, we shouldn't be here
return rv;
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
if (mWidget != NULL) { // check for null mWidget
EventRecord* event = (EventRecord*)anEvent.nativeMsg;
if ((event == NULL) || (event->what == nullEvent) ||
@ -3585,10 +3594,12 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const nsGUIEvent& anEvent)
GUItoMacEvent(anEvent, macEvent);
event = &macEvent;
}
nsPluginPort* port = (nsPluginPort*)mWidget->GetNativeData(NS_NATIVE_PLUGIN_PORT);
nsPluginEvent pluginEvent = { event, nsPluginPlatformWindowRef(port->port) };
PRBool eventHandled = PR_FALSE;
mInstance->HandleEvent(&pluginEvent, &eventHandled);
nsPluginPort* pluginPort = FixUpPluginWindow();
if (pluginPort) {
nsPluginEvent pluginEvent = { event, nsPluginPlatformWindowRef(GetWindowFromPort(pluginPort->port)) };
mInstance->HandleEvent(&pluginEvent, &eventHandled);
}
if (eventHandled && !(anEvent.message == NS_MOUSE_LEFT_BUTTON_DOWN && !mContentFocused))
rv = nsEventStatus_eConsumeNoDefault;
}
@ -3615,6 +3626,9 @@ nsPluginInstanceOwner::Destroy()
nsCOMPtr<nsIContent> content;
mOwner->GetContent(getter_AddRefs(content));
// stop the timer explicitly to reduce reference count.
CancelTimer();
// unregister context menu listener
if (mCXMenuListener) {
mCXMenuListener->Destroy(mOwner);
@ -3724,9 +3738,7 @@ void nsPluginInstanceOwner::Paint(const nsRect& aDirtyRect, PRUint32 ndc)
if(!mInstance)
return;
#ifdef XP_MAC
nsPluginPort* pluginPort = GetPluginPort();
#if defined(XP_MAC) || defined(XP_MACOSX)
#ifdef DO_DIRTY_INTERSECT // aDirtyRect isn't always correct, see bug 56128
nsPoint rel(aDirtyRect.x, aDirtyRect.y);
nsPoint abs(0,0);
@ -3741,16 +3753,24 @@ void nsPluginInstanceOwner::Paint(const nsRect& aDirtyRect, PRUint32 ndc)
nsRect absDirtyRectInPixels;
ConvertTwipsToPixels(*mContext, absDirtyRect, absDirtyRectInPixels);
#endif
FixUpPluginWindow();
EventRecord updateEvent;
InitializeEventRecord(&updateEvent);
updateEvent.what = updateEvt;
updateEvent.message = UInt32(pluginPort->port);
nsPluginPort* pluginPort = FixUpPluginWindow();
if (pluginPort) {
EventRecord updateEvent;
InitializeEventRecord(&updateEvent);
updateEvent.what = updateEvt;
updateEvent.message = UInt32(GetWindowFromPort(pluginPort->port));
nsPluginEvent pluginEvent = { &updateEvent, nsPluginPlatformWindowRef(pluginPort->port) };
PRBool eventHandled = PR_FALSE;
mInstance->HandleEvent(&pluginEvent, &eventHandled);
GrafPtr oldPort;
::GetPort(&oldPort);
::SetPort((GrafPtr)pluginPort->port);
nsPluginEvent pluginEvent = { &updateEvent, nsPluginPlatformWindowRef(GetWindowFromPort(pluginPort->port)) };
PRBool eventHandled = PR_FALSE;
mInstance->HandleEvent(&pluginEvent, &eventHandled);
::SetPort(oldPort);
}
#endif
#ifdef XP_WIN
@ -3781,12 +3801,13 @@ void nsPluginInstanceOwner::Paint(const nsRect& aDirtyRect, PRUint32 ndc)
NS_IMETHODIMP nsPluginInstanceOwner::Notify(nsITimer* /* timer */)
{
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
// validate the plugin clipping information by syncing the plugin window info to
// reflect the current widget location. This makes sure that everything is updated
// correctly in the event of scrolling in the window.
FixUpPluginWindow();
if (mInstance != NULL) {
nsPluginPort* pluginPort = FixUpPluginWindow();
if (pluginPort) {
EventRecord idleEvent;
InitializeEventRecord(&idleEvent);
idleEvent.what = nullEvent;
@ -3796,23 +3817,28 @@ NS_IMETHODIMP nsPluginInstanceOwner::Notify(nsITimer* /* timer */)
if (!mWidgetVisible)
idleEvent.where.h = idleEvent.where.v = 20000;
nsPluginPort* pluginPort = GetPluginPort();
nsPluginEvent pluginEvent = { &idleEvent, nsPluginPlatformWindowRef(pluginPort->port) };
nsPluginEvent pluginEvent = { &idleEvent, nsPluginPlatformWindowRef(GetWindowFromPort(pluginPort->port)) };
PRBool eventHandled = PR_FALSE;
mInstance->HandleEvent(&pluginEvent, &eventHandled);
}
}
#endif
return NS_OK;
}
#ifndef REPEATING_TIMERS
// reprime the timer? currently have to create a new timer for each call, which is
// kind of wasteful. need to get periodic timers working on all platforms.
nsresult rv;
mPluginTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
if (NS_SUCCEEDED(rv))
mPluginTimer->InitWithCallback(this, 1020 / 60, nsITimer::TYPE_ONE_SHOT);
void nsPluginInstanceOwner::StartTimer()
{
#if defined(XP_MAC) || defined(XP_MACOSX)
nsresult rv;
// start a periodic timer to provide null events to the plugin instance.
if (!mPluginTimer) {
mPluginTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
if (rv == NS_OK)
rv = mPluginTimer->InitWithCallback(this, 1020 / 60, nsITimer::TYPE_REPEATING_SLACK);
}
#endif
return NS_OK;
}
void nsPluginInstanceOwner::CancelTimer()
@ -4024,13 +4050,8 @@ NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void)
mPluginWindow->type = nsPluginWindowType_Window;
mPluginWindow->window = GetPluginPort();
#if defined(XP_MAC)
// Is this needed in the windowless case ???
// start a periodic timer to provide null events to the plugin instance.
mPluginTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
if (rv == NS_OK)
rv = mPluginTimer->InitWithCallback(this, 1020 / 60, nsITimer::TYPE_REPEATING_SLACK);
#endif
// start the idle timer.
StartTimer();
}
}
}
@ -4059,7 +4080,7 @@ static void ConvertTwipsToPixels(nsIPresContext& aPresContext, nsRect& aTwipsRec
}
// Mac specific code to fix up the port location and clipping region
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
// calculate the absolute position and clip for a widget
// and use other windows in calculating the clip
static void GetWidgetPosClipAndVis(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY,
@ -4110,10 +4131,6 @@ static void GetWidgetPosClipAndVis(nsIWidget* aWidget,nscoord& aAbsX, nscoord& a
// if we are not visible, clear out the plugin's clip so it won't paint
if (!aIsVisible)
aClipRect.Empty();
//printf("--------------\n");
//printf("Widget clip X %d Y %d rect %d %d %d %d\n", aAbsX, aAbsY, aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height );
//printf("--------------\n");
}
#ifdef DO_DIRTY_INTERSECT
@ -4177,15 +4194,21 @@ inline PRUint16 COLOR8TOCOLOR16(PRUint8 color8)
return (color8 << 8) | color8; /* (color8 * 257) == (color8 * 0x0101) */
}
void nsPluginInstanceOwner::FixUpPluginWindow()
nsPluginPort* nsPluginInstanceOwner::FixUpPluginWindow()
{
if (!mWidget || !mPluginWindow)
return;
return nsnull;
nsPluginPort* pluginPort = GetPluginPort();
nscoord absWidgetX = 0;
nscoord absWidgetY = 0;
nsRect widgetClip(0,0,0,0);
#if defined(MOZ_WIDGET_COCOA)
if (!pluginPort)
return nsnull;
#endif
// first, check our view for CSS visibility style
nsIView *view;
mOwner->GetView(mContext, &view);
@ -4195,12 +4218,17 @@ void nsPluginInstanceOwner::FixUpPluginWindow()
GetWidgetPosClipAndVis(mWidget,absWidgetX,absWidgetY,widgetClip,isVisible);
if (mWidgetVisible != isVisible)
mWidgetVisible = isVisible;
#if defined(MOZ_WIDGET_COCOA)
// set the port coordinates
mPluginWindow->x = -pluginPort->portx;
mPluginWindow->y = -pluginPort->porty;
widgetClip.x += mPluginWindow->x - absWidgetX;
widgetClip.y += mPluginWindow->y - absWidgetY;
#else
// set the port coordinates
mPluginWindow->x = absWidgetX;
mPluginWindow->y = absWidgetY;
#endif
// fix up the clipping region
mPluginWindow->clipRect.top = widgetClip.y;
@ -4212,7 +4240,6 @@ void nsPluginInstanceOwner::FixUpPluginWindow()
// the background color needs to be set here on the plugin port
GrafPtr savePort;
::GetPort(&savePort); // save our current port
nsPluginPort* pluginPort = GetPluginPort();
::SetPort((GrafPtr)pluginPort->port);
nscolor color = mWidget->GetBackgroundColor();
@ -4222,7 +4249,46 @@ void nsPluginInstanceOwner::FixUpPluginWindow()
macColor.blue = COLOR8TOCOLOR16(NS_GET_B(color));
::RGBBackColor(&macColor);
::SetPort(savePort); // restore port
if (mWidgetVisible != isVisible) {
mWidgetVisible = isVisible;
// must do this to disable async Java Applet drawing
if (isVisible) {
mInstance->SetWindow(mPluginWindow);
} else {
mInstance->SetWindow(nsnull);
// switching states, do not draw
pluginPort = nsnull;
}
}
#if defined(MOZ_WIDGET_COCOA)
if (!mWidgetVisible) {
mPluginWindow->clipRect.right = mPluginWindow->clipRect.left;
mPluginWindow->clipRect.bottom = mPluginWindow->clipRect.top;
}
#endif
return pluginPort;
}
#endif // XP_MAC
void nsPluginInstanceOwner::Composite()
{
//no reference count on view
nsIView* view;
nsresult rv = mOwner->GetView(mContext, &view);
if (NS_SUCCEEDED(rv) && view) {
nsIViewManager* manager;
rv = view->GetViewManager(manager);
//set flags to not do a synchronous update, force update does the redraw
if (NS_SUCCEEDED(rv) && manager) {
rv = manager->UpdateView(view, NS_VMREFRESH_IMMEDIATE);
NS_RELEASE(manager);
}
}
}
#endif // XP_MAC || XP_MACOSX

View File

@ -38,7 +38,7 @@
/*
* npapi.h $Revision: 3.25 $
* npapi.h $Revision: 3.26 $
* Netscape client plug-in API spec
*/
@ -105,7 +105,7 @@
# endif /* XP_PC */
#endif /* __MWERKS__ */
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
#include <Quickdraw.h>
#include <Events.h>
#endif
@ -378,7 +378,7 @@ typedef struct _NPWindow
uint32 height;
NPRect clipRect; /* Clipping rectangle in port coordinates */
/* Used by MAC only. */
#ifdef XP_UNIX
#if defined(XP_UNIX) && !defined(XP_MACOSX)
void * ws_info; /* Platform-dependent additonal data */
#endif /* XP_UNIX */
NPWindowType type; /* Is this a window or a drawable? */
@ -408,7 +408,7 @@ typedef struct _NPPrint
} print;
} NPPrint;
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
typedef EventRecord NPEvent;
#elif defined(XP_WIN)
typedef struct _NPEvent
@ -430,7 +430,7 @@ typedef XEvent NPEvent;
typedef void* NPEvent;
#endif /* XP_MAC */
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
typedef RgnHandle NPRegion;
#elif defined(XP_WIN)
typedef HRGN NPRegion;
@ -440,7 +440,7 @@ typedef Region NPRegion;
typedef void *NPRegion;
#endif /* XP_MAC */
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
/*
* Mac-specific structures and definitions.
*/

View File

@ -38,7 +38,7 @@
/*
* npupp.h $Revision: 3.10 $
* npupp.h $Revision: 3.11 $
* function call mecahnics needed by platform specific glue code.
*/
@ -1127,7 +1127,7 @@ typedef struct _NPNetscapeFuncs {
#endif
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
/******************************************************************************************
* Mac platform-specific plugin glue stuff
*******************************************************************************************/

View File

@ -270,7 +270,7 @@ struct nsPluginWindow {
PRUint32 height;
nsPluginRect clipRect; /* Clipping rectangle in port coordinates */
/* Used by MAC only. */
#ifdef XP_UNIX
#if defined(XP_UNIX) && !defined(XP_MACOSX)
void* ws_info; /* Platform-dependent additonal data */
#endif /* XP_UNIX */
nsPluginWindowType type; /* Is this a window or a drawable? */

View File

@ -82,22 +82,28 @@ else
ifeq ($(MOZ_WIDGET_TOOLKIT),os2)
CPPSRCS += nsPluginsDirOS2.cpp
CPPSRCS += nsPluginNativeWindow.cpp
else
ifeq ($(OS_ARCH),Darwin)
CPPSRCS += nsPluginsDirDarwin.cpp
CPPSRCS += nsPluginNativeWindow.cpp
else
CPPSRCS += nsPluginsDirUnix.cpp
CPPSRCS += nsPluginNativeWindow.cpp
endif
endif
endif
endif
EXPORTS = \
nsPluginViewer.h \
$(NULL)
ifeq ($(OS_ARCH),WINNT)
ifneq (,$(filter WINNT Darwin,$(OS_ARCH)))
EXTRA_DSO_LIBS += gkgfx
endif
EXTRA_DSO_LDOPTS = \
$(LIBS_DIR) \
$(EXTRA_DSO_LIBS) \
$(MOZ_NECKO_UTIL_LIBS) \
$(MOZ_COMPONENT_LIBS) \

View File

@ -60,7 +60,7 @@
#include "nsIDocument.h"
#include "nsIScriptGlobalObject.h"
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
#include <Resources.h>
#endif
@ -204,6 +204,44 @@ PR_BEGIN_EXTERN_C
PR_END_EXTERN_C
#ifdef XP_MACOSX
static void* TV2FP(void *tvp)
{
static uint32 glue[6] = { 0x3D800000, 0x618C0000, 0x800C0000, 0x804C0004, 0x7C0903A6, 0x4E800420 };
uint32* newGlue = NULL;
if (tvp != NULL) {
newGlue = (uint32*) malloc(sizeof(glue));
if (newGlue != NULL) {
memcpy(newGlue, glue, sizeof(glue));
newGlue[0] |= ((UInt32)tvp >> 16);
newGlue[1] |= ((UInt32)tvp & 0xFFFF);
MakeDataExecutable(newGlue, sizeof(glue));
}
}
return newGlue;
}
static void* FP2TV(void *fp)
{
void **newGlue = NULL;
if (fp != NULL) {
newGlue = (void**) malloc(2 * sizeof(void *));
if (newGlue != NULL) {
newGlue[0] = fp;
newGlue[1] = NULL;
}
}
return newGlue;
}
#else
#define TV2FP(f) (f)
#define FP2TV(f) (f)
#endif /* XP_MACOSX */
////////////////////////////////////////////////////////////////////////
// Globals
@ -224,27 +262,27 @@ ns4xPlugin::CheckClassInitialized(void)
CALLBACKS.size = sizeof(CALLBACKS);
CALLBACKS.version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR;
CALLBACKS.geturl = NewNPN_GetURLProc(_geturl);
CALLBACKS.posturl = NewNPN_PostURLProc(_posturl);
CALLBACKS.requestread = NewNPN_RequestReadProc(_requestread);
CALLBACKS.newstream = NewNPN_NewStreamProc(_newstream);
CALLBACKS.write = NewNPN_WriteProc(_write);
CALLBACKS.destroystream = NewNPN_DestroyStreamProc(_destroystream);
CALLBACKS.status = NewNPN_StatusProc(_status);
CALLBACKS.uagent = NewNPN_UserAgentProc(_useragent);
CALLBACKS.memalloc = NewNPN_MemAllocProc(_memalloc);
CALLBACKS.memfree = NewNPN_MemFreeProc(_memfree);
CALLBACKS.memflush = NewNPN_MemFlushProc(_memflush);
CALLBACKS.reloadplugins = NewNPN_ReloadPluginsProc(_reloadplugins);
CALLBACKS.getJavaEnv = NewNPN_GetJavaEnvProc(_getJavaEnv);
CALLBACKS.getJavaPeer = NewNPN_GetJavaPeerProc(_getJavaPeer);
CALLBACKS.geturlnotify = NewNPN_GetURLNotifyProc(_geturlnotify);
CALLBACKS.posturlnotify = NewNPN_PostURLNotifyProc(_posturlnotify);
CALLBACKS.getvalue = NewNPN_GetValueProc(_getvalue);
CALLBACKS.setvalue = NewNPN_SetValueProc(_setvalue);
CALLBACKS.invalidaterect = NewNPN_InvalidateRectProc(_invalidaterect);
CALLBACKS.invalidateregion = NewNPN_InvalidateRegionProc(_invalidateregion);
CALLBACKS.forceredraw = NewNPN_ForceRedrawProc(_forceredraw);
CALLBACKS.geturl = NewNPN_GetURLProc(FP2TV(_geturl));
CALLBACKS.posturl = NewNPN_PostURLProc(FP2TV(_posturl));
CALLBACKS.requestread = NewNPN_RequestReadProc(FP2TV(_requestread));
CALLBACKS.newstream = NewNPN_NewStreamProc(FP2TV(_newstream));
CALLBACKS.write = NewNPN_WriteProc(FP2TV(_write));
CALLBACKS.destroystream = NewNPN_DestroyStreamProc(FP2TV(_destroystream));
CALLBACKS.status = NewNPN_StatusProc(FP2TV(_status));
CALLBACKS.uagent = NewNPN_UserAgentProc(FP2TV(_useragent));
CALLBACKS.memalloc = NewNPN_MemAllocProc(FP2TV(_memalloc));
CALLBACKS.memfree = NewNPN_MemFreeProc(FP2TV(_memfree));
CALLBACKS.memflush = NewNPN_MemFlushProc(FP2TV(_memflush));
CALLBACKS.reloadplugins = NewNPN_ReloadPluginsProc(FP2TV(_reloadplugins));
CALLBACKS.getJavaEnv = NewNPN_GetJavaEnvProc(FP2TV(_getJavaEnv));
CALLBACKS.getJavaPeer = NewNPN_GetJavaPeerProc(FP2TV(_getJavaPeer));
CALLBACKS.geturlnotify = NewNPN_GetURLNotifyProc(FP2TV(_geturlnotify));
CALLBACKS.posturlnotify = NewNPN_PostURLNotifyProc(FP2TV(_posturlnotify));
CALLBACKS.getvalue = NewNPN_GetValueProc(FP2TV(_getvalue));
CALLBACKS.setvalue = NewNPN_SetValueProc(FP2TV(_setvalue));
CALLBACKS.invalidaterect = NewNPN_InvalidateRectProc(FP2TV(_invalidaterect));
CALLBACKS.invalidateregion = NewNPN_InvalidateRegionProc(FP2TV(_invalidateregion));
CALLBACKS.forceredraw = NewNPN_ForceRedrawProc(FP2TV(_forceredraw));
initialized = TRUE;
@ -300,6 +338,52 @@ ns4xPlugin::ns4xPlugin(NPPluginFuncs* callbacks, PRLibrary* aLibrary, NP_PLUGINS
if(error != NPERR_NO_ERROR || ((fCallbacks.version >> 8) < NP_VERSION_MAJOR))
return;
#elif defined(XP_MACOSX) || (defined(XP_MAC) && TARGET_CARBON)
// call into the entry point
NP_MAIN pfnMain = (NP_MAIN) PR_FindSymbol(aLibrary, "main");
if(pfnMain == NULL)
return;
NPP_ShutdownUPP pfnShutdown;
NPPluginFuncs np_callbacks;
memset((void*) &np_callbacks, 0, sizeof(np_callbacks));
np_callbacks.size = sizeof(np_callbacks);
NPError error;
NS_TRY_SAFE_CALL_RETURN(error, CallNPP_MainEntryProc(pfnMain,
&(ns4xPlugin::CALLBACKS),
&np_callbacks,
&pfnShutdown), aLibrary, nsnull);
NPP_PLUGIN_LOG(PLUGIN_LOG_BASIC, ("NPP MainEntryProc called: return=%d\n",error));
if(error != NPERR_NO_ERROR)
return;
// version is a uint16 so cast to int to avoid an invalid
// comparison due to limited range of the data type
int cb_version = np_callbacks.version;
if ((cb_version >> 8) < NP_VERSION_MAJOR)
return;
// wrap all plugin entry points tvectors as mach-o callable function pointers.
fCallbacks.size = sizeof(fCallbacks);
fCallbacks.version = np_callbacks.version;
fCallbacks.newp = (NPP_NewUPP) TV2FP(np_callbacks.newp);
fCallbacks.destroy = (NPP_DestroyUPP) TV2FP(np_callbacks.destroy);
fCallbacks.setwindow = (NPP_SetWindowUPP) TV2FP(np_callbacks.setwindow);
fCallbacks.newstream = (NPP_NewStreamUPP) TV2FP(np_callbacks.newstream);
fCallbacks.destroystream = (NPP_DestroyStreamUPP) TV2FP(np_callbacks.destroystream);
fCallbacks.asfile = (NPP_StreamAsFileUPP) TV2FP(np_callbacks.asfile);
fCallbacks.writeready = (NPP_WriteReadyUPP) TV2FP(np_callbacks.writeready);
fCallbacks.write = (NPP_WriteUPP) TV2FP(np_callbacks.write);
fCallbacks.print = (NPP_PrintUPP) TV2FP(np_callbacks.print);
fCallbacks.event = (NPP_HandleEventUPP) TV2FP(np_callbacks.event);
fCallbacks.urlnotify = (NPP_URLNotifyUPP) TV2FP(np_callbacks.urlnotify);
fCallbacks.getvalue = (NPP_GetValueUPP) TV2FP(np_callbacks.getvalue);
fCallbacks.setvalue = (NPP_SetValueUPP) TV2FP(np_callbacks.setvalue);
fShutdownEntry = (NP_PLUGINSHUTDOWN) TV2FP(pfnShutdown);
#else // for everyone else
memcpy((void*) &fCallbacks, (void*) callbacks, sizeof(fCallbacks));
fShutdownEntry = aShutdown;
@ -313,6 +397,33 @@ ns4xPlugin::ns4xPlugin(NPPluginFuncs* callbacks, PRLibrary* aLibrary, NP_PLUGINS
ns4xPlugin::~ns4xPlugin(void)
{
//reset the callbacks list
#if defined(XP_MACOSX)
// release all wrapped plugin entry points.
if (fCallbacks.newp)
free(fCallbacks.newp);
if (fCallbacks.destroy)
free(fCallbacks.destroy);
if (fCallbacks.setwindow)
free(fCallbacks.setwindow);
if (fCallbacks.newstream)
free(fCallbacks.newstream);
if (fCallbacks.asfile)
free(fCallbacks.asfile);
if (fCallbacks.writeready)
free(fCallbacks.writeready);
if (fCallbacks.write)
free(fCallbacks.write);
if (fCallbacks.print)
free(fCallbacks.print);
if (fCallbacks.event)
free(fCallbacks.event);
if (fCallbacks.urlnotify)
free(fCallbacks.urlnotify);
if (fCallbacks.getvalue)
free(fCallbacks.getvalue);
if (fCallbacks.setvalue)
free(fCallbacks.setvalue);
#endif
memset((void*) &fCallbacks, 0, sizeof(fCallbacks));
}
@ -324,19 +435,7 @@ void ns4xPlugin::ReleaseStatics()
}
#ifdef XP_MAC
////////////////////////////////////////////////////////////////////////
static char* p2cstrdup(StringPtr pstr)
{
int len = pstr[0];
char* cstr = new char[len + 1];
if (cstr != NULL) {
::BlockMoveData(pstr + 1, cstr, len);
cstr[len] = '\0';
}
return cstr;
}
#if defined(XP_MAC) || defined(XP_MACOSX)
////////////////////////////////////////////////////////////////////////
void ns4xPlugin::SetPluginRefNum(short aRefNum)
{
@ -368,7 +467,7 @@ ns4xPlugin::CreatePlugin(nsIServiceManagerObsolete* aServiceMgr,
aServiceMgr->GetService(kMemoryCID, kIMemoryIID, (nsISupports**)&gMalloc);
}
#ifdef XP_UNIX
#if defined(XP_UNIX) && !defined(XP_MACOSX)
ns4xPlugin *plptr;
@ -549,7 +648,7 @@ ns4xPlugin::CreatePlugin(nsIServiceManagerObsolete* aServiceMgr,
}
#endif
#if defined(XP_MAC)
#if defined(XP_MAC) || defined(XP_MACOSX)
short appRefNum = ::CurResFile();
short pluginRefNum;
@ -559,37 +658,7 @@ ns4xPlugin::CreatePlugin(nsIServiceManagerObsolete* aServiceMgr,
if (pluginRefNum == -1)
return NS_ERROR_FAILURE;
#if TARGET_CARBON
// call into the entry point
NP_MAIN pfnMain = (NP_MAIN) PR_FindSymbol(aLibrary, "main");
if(pfnMain == NULL)
return NS_ERROR_FAILURE;
NPP_ShutdownUPP pfnShutdown;
NPPluginFuncs callbacks;
memset((void*) &callbacks, 0, sizeof(callbacks));
callbacks.size = sizeof(callbacks);
NPError error;
NS_TRY_SAFE_CALL_RETURN(error, CallNPP_MainEntryProc(pfnMain,
&(ns4xPlugin::CALLBACKS),
&callbacks,
&pfnShutdown), fLibrary, nsnull);
NPP_PLUGIN_LOG(PLUGIN_LOG_BASIC, ("NPP MainEntryProc called: return=%d\n",error));
if(error != NPERR_NO_ERROR)
return NS_ERROR_FAILURE;
if ((callbacks.version >> 8) < NP_VERSION_MAJOR)
return NS_ERROR_FAILURE;
// create the new plugin handler
ns4xPlugin* plugin = new ns4xPlugin(&callbacks, aLibrary, (NP_PLUGINSHUTDOWN)pfnShutdown, aServiceMgr);
#else // not carbon
ns4xPlugin* plugin = new ns4xPlugin(nsnull, aLibrary, nsnull, aServiceMgr);
#endif
if(plugin == NULL)
return NS_ERROR_OUT_OF_MEMORY;
@ -603,7 +672,7 @@ ns4xPlugin::CreatePlugin(nsIServiceManagerObsolete* aServiceMgr,
}
plugin->SetPluginRefNum(pluginRefNum);
#endif // XP_MAC
#endif // XP_MAC || XP_MACOSX
#ifdef XP_BEOS
// I just copied UNIX version.
@ -711,13 +780,17 @@ ns4xPlugin::Shutdown(void)
NPP_PLUGIN_LOG(PLUGIN_LOG_BASIC, ("NPP Shutdown to be called: this=%p\n",this));
if (nsnull != fShutdownEntry) {
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
CallNPP_ShutdownProc(fShutdownEntry);
::CloseResFile(fPluginRefNum);
#else
NS_TRY_SAFE_CALL_VOID(fShutdownEntry(), fLibrary, nsnull);
#endif
#if defined(XP_MACOSX)
// release the wrapped plugin function.
free(fShutdownEntry);
#endif
fShutdownEntry = nsnull;
}
@ -730,9 +803,9 @@ ns4xPlugin::Shutdown(void)
nsresult
ns4xPlugin::GetMIMEDescription(const char* *resultingDesc)
{
const char* (*npGetMIMEDescrpition)() = (const char* (*)()) PR_FindSymbol(fLibrary, "NP_GetMIMEDescription");
const char* (*npGetMIMEDescription)() = (const char* (*)()) PR_FindSymbol(fLibrary, "NP_GetMIMEDescription");
*resultingDesc = npGetMIMEDescrpition ? npGetMIMEDescrpition() : "";
*resultingDesc = npGetMIMEDescription ? npGetMIMEDescription() : "";
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("ns4xPlugin::GetMIMEDescription called: this=%p, result=%s\n",this, *resultingDesc));
@ -1148,7 +1221,7 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
nsresult res;
switch(variable) {
#ifdef XP_UNIX
#if defined(XP_UNIX) && !defined(XP_MACOSX)
case NPNVxDisplay : {
#if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_GTK2)
// adobe nppdf calls XtGetApplicationNameAndClass(display, &instance, &class)

View File

@ -79,7 +79,7 @@ typedef NS_4XPLUGIN_CALLBACK(NPError, NP_PLUGINUNIXINIT) (const NPNetscapeFuncs*
typedef NS_4XPLUGIN_CALLBACK(NPError, NP_PLUGINSHUTDOWN) (void);
#endif
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
typedef NS_4XPLUGIN_CALLBACK(NPError, NP_PLUGINSHUTDOWN) (void);
typedef NS_4XPLUGIN_CALLBACK(NPError, NP_MAIN) (NPNetscapeFuncs* nCallbacks, NPPluginFuncs* pCallbacks, NPP_ShutdownUPP* unloadUpp);
#endif
@ -151,7 +151,7 @@ public:
PRLibrary* aLibrary,
nsIPlugin** aResult);
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
void
SetPluginRefNum(short aRefNum);
#endif
@ -163,7 +163,7 @@ protected:
static void CheckClassInitialized(void);
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
short fPluginRefNum;
#endif

View File

@ -1024,6 +1024,7 @@ NS_IMETHODIMP ns4xPluginInstance::SetWindow(nsPluginWindow* window)
// XXX In the old code, we'd just ignore any errors coming
// back from the plugin's SetWindow(). Is this the correct
// behavior?!?
}
return NS_OK;
}
@ -1123,12 +1124,11 @@ NS_IMETHODIMP ns4xPluginInstance::HandleEvent(nsPluginEvent* event, PRBool* hand
PRInt16 result = 0;
if (fCallbacks->event)
{
#ifdef XP_MAC
result = CallNPP_HandleEventProc(fCallbacks->event,
&fNPP,
(void*) event->event);
if (fCallbacks->event) {
#if defined(XP_MAC) || defined(XP_MACOSX)
result = CallNPP_HandleEventProc(fCallbacks->event,
&fNPP,
(void*) event->event);
#endif
#if defined(XP_WIN) || defined(XP_OS2)
@ -1249,9 +1249,13 @@ NS_IMETHODIMP ns4xPluginInstance :: GetScriptablePeer(void * *aScriptablePeer)
/* readonly attribute nsIIDPtr scriptableInterface; */
NS_IMETHODIMP ns4xPluginInstance :: GetScriptableInterface(nsIID * *aScriptableInterface)
{
#if !defined(XP_MACOSX) // Workaround suspected bug
if (!aScriptableInterface)
return NS_ERROR_NULL_POINTER;
*aScriptableInterface = nsnull;
return GetValue(nsPluginInstanceVariable_ScriptableIID, (void*)aScriptableInterface);
#else
return NS_ERROR_NOT_IMPLEMENTED;
#endif
}

View File

@ -159,6 +159,10 @@
#include "nsIDocShell.h"
#include "nsPluginNativeWindow.h"
#if defined(XP_MAC) && TARGET_CARBON
#include "nsIClassicPluginFactory.h"
#endif
#ifdef XP_UNIX
#if defined(MOZ_WIDGET_GTK) || defined (MOZ_WIDGET_GTK2)
#include <gdk/gdkx.h> // for GDK_DISPLAY()
@ -169,10 +173,6 @@
#endif
#endif
#if defined(XP_MAC) && TARGET_CARBON
#include "nsIClassicPluginFactory.h"
#endif
#if defined(XP_MAC) || defined (XP_MACOSX)
#if TARGET_CARBON
#include <TextServices.h> // for ::UseInputWindow()
@ -3881,7 +3881,7 @@ NS_IMETHODIMP nsPluginHostImpl::TrySetUpPluginInstance(const char *aMimeType,
isJavaPlugin = PR_TRUE;
}
#if defined(XP_UNIX) || defined(XP_OS2)
#if (defined(XP_UNIX) && !defined(XP_MACOSX)) || defined(XP_OS2)
// This is a work-around on Unix for a LiveConnect problem (bug 83698).
// The problem:
// The proxy JNI needs to be created by the browser. If it is created by
@ -4346,7 +4346,7 @@ public:
{
// only show the full path if people have set the pref,
// the default should not reveal path information (bug 88183)
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
return DoCharsetConversion(mUnicodeDecoder, mPluginTag.mFullPath, aFilename);
#else
return DoCharsetConversion(mUnicodeDecoder, mPluginTag.mFileName, aFilename);
@ -4356,7 +4356,7 @@ public:
nsFileSpec spec;
if (mPluginTag.mFullPath)
{
#ifndef XP_MAC
#if !(defined(XP_MAC) || defined(XP_MACOSX))
NS_ERROR("Only MAC should be using nsPluginTag::mFullPath!");
#endif
spec = mPluginTag.mFullPath;
@ -4486,6 +4486,96 @@ nsPluginHostImpl::FindPluginEnabledForType(const char* aMimeType,
return NS_ERROR_FAILURE;
}
#if defined(XP_MACOSX)
/**
* The following code examines the format of a Mac OS X binary, and determines whether it
* is compatible with the current executable. One trick to make this portable might be
* to compare the headers of the main executable we are part of with the header of the
* binary in question, but for a quick and dirty solution, this just checks to see
* if the specified binary is itself a MACH-O binary with a 4 byte header of 0xFEEDFACE.
*/
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <unistd.h>
inline PRBool is_directory(const char* path)
{
struct stat sb;
if (stat(path, &sb) == 0 && (sb.st_mode & S_IFDIR)) {
return PR_TRUE;
}
return PR_FALSE;
}
static int open_executable(const char* path)
{
int fd = 0;
// if this is a directory, it must be a bundle, so get the true path using CFBundle...
if (is_directory(path)) {
CFBundleRef bundle = NULL;
CFStringRef pathRef = CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8);
if (pathRef) {
CFURLRef bundleURL = CFURLCreateWithFileSystemPath(NULL, pathRef, kCFURLPOSIXPathStyle, true);
CFRelease(pathRef);
if (bundleURL != NULL) {
bundle = CFBundleCreate(NULL, bundleURL);
CFRelease(bundleURL);
if (bundle) {
CFURLRef executableURL = CFBundleCopyExecutableURL(bundle);
if (executableURL) {
pathRef = CFURLCopyFileSystemPath(executableURL, kCFURLPOSIXPathStyle);
CFRelease(executableURL);
if (pathRef) {
CFIndex bufferSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(pathRef), kCFStringEncodingUTF8) + 1;
char* executablePath = new char[bufferSize];
if (executablePath && CFStringGetCString(pathRef, executablePath, bufferSize, kCFStringEncodingUTF8)) {
fd = open(executablePath, O_RDONLY, 0);
delete[] executablePath;
}
CFRelease(pathRef);
}
}
CFRelease(bundle);
}
}
}
} else {
fd = open(path, O_RDONLY, 0);
}
return fd;
}
static PRBool IsCompatibleExecutable(const char* path)
{
int fd = open_executable(path);
if (fd) {
// open the file, look at the header. if the first 8-bytes are "Joy!peff" then we have
// a CFM/PEFF library, which isn't compatible with MACH-O. If it is 0xfeedface, then it
// is MACH-O. Look in /etc/magic for other valid MACH-O header signatures. Should we
// just use the contents of /etc/magic like the "file" command does? man 1 file for more info.
char magic_cookie[8];
ssize_t n = read(fd, magic_cookie, sizeof(magic_cookie));
close(fd);
if (n == sizeof(magic_cookie)) {
const char mach_o_cookie[] = { 0xFE, 0xED, 0xFA, 0xCE };
if (memcmp(magic_cookie, mach_o_cookie, sizeof(mach_o_cookie)) == 0)
return PR_TRUE;
const char cfm_cookie[] = { 'J', 'o', 'y', '!', 'p', 'e', 'f', 'f' };
if (memcmp(magic_cookie, cfm_cookie, sizeof(cfm_cookie)) == 0)
return PR_FALSE;
}
}
return PR_FALSE;
}
#else
inline PRBool IsCompatibleExecutable(const char* path) { return PR_TRUE; }
#endif
////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP nsPluginHostImpl::GetPluginFactory(const char *aMimeType, nsIPlugin** aPlugin)
{
@ -4512,7 +4602,7 @@ NS_IMETHODIMP nsPluginHostImpl::GetPluginFactory(const char *aMimeType, nsIPlugi
if (nsnull == pluginTag->mLibrary) // if we haven't done this yet
{
#ifndef XP_MAC
#if !(defined(XP_MAC) || defined(XP_MACOSX))
nsFileSpec file(pluginTag->mFileName);
#else
if (nsnull == pluginTag->mFullPath)
@ -4565,7 +4655,7 @@ NS_IMETHODIMP nsPluginHostImpl::GetPluginFactory(const char *aMimeType, nsIPlugi
// need to get the plugin factory from this plugin.
nsFactoryProc nsGetFactory = nsnull;
nsGetFactory = (nsFactoryProc) PR_FindSymbol(pluginTag->mLibrary, "NSGetFactory");
if(nsGetFactory != nsnull)
if(nsGetFactory != nsnull && IsCompatibleExecutable(pluginTag->mFullPath))
{
rv = nsGetFactory(serviceManager, kPluginCID, nsnull, nsnull, // XXX fix ClassName/ContractID
(nsIFactory**)&pluginTag->mEntryPoint);

View File

@ -62,7 +62,7 @@ nsPluginNativeWindowPLATFORM::nsPluginNativeWindowPLATFORM() : nsPluginNativeWin
width = 0;
height = 0;
memset(&clipRect, 0, sizeof(clipRect));
#ifdef XP_UNIX
#if defined(XP_UNIX) && !defined(XP_MACOSX)
ws_info = nsnull;
#endif
type = nsPluginWindowType_Window;

View File

@ -156,12 +156,13 @@ public:
NS_DECL_NSITIMERCALLBACK
void CancelTimer();
void StartTimer();
nsPluginPort* GetPluginPort();
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
void GUItoMacEvent(const nsGUIEvent& anEvent, EventRecord& aMacEvent);
void FixUpPluginWindow();
nsPluginPort* FixUpPluginWindow();
#endif
private:
@ -173,7 +174,7 @@ private:
PRPackedBool mWidgetVisible; // used on Mac to store our widget's visible state
};
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
static void GetWidgetPosClipAndVis(nsIWidget* aWidget,nscoord& aAbsX, nscoord& aAbsY,
nsRect& aClipRect, PRBool& aIsVisible);
#endif
@ -228,7 +229,7 @@ NS_IMPL_QUERY_INTERFACE4(PluginViewerImpl,
PluginViewerImpl::~PluginViewerImpl()
{
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
if (mOwner) mOwner->CancelTimer();
#endif
@ -346,7 +347,7 @@ PluginViewerImpl::StartLoad(nsIRequest* request, nsIStreamListener*& aResult)
mWindow->GetClientBounds(r);
rv = CreatePlugin(request, host, nsRect(0, 0, r.width, r.height), aResult);
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
// On Mac, we need to initiate the intial invalidate for full-page plugins to ensure
// the entire window gets cleared. Otherwise, Acrobat won't initially repaint on top
// of our previous presentation and we may have garbage leftover
@ -376,9 +377,9 @@ PluginViewerImpl::CreatePlugin(nsIRequest* request, nsIPluginHost* aHost, const
win->clipRect.left = aBounds.x;
win->clipRect.bottom = aBounds.YMost();
win->clipRect.right = aBounds.XMost();
#ifdef XP_UNIX
#if defined(XP_UNIX) && !defined(XP_MACOSX)
win->ws_info = nsnull; //XXX need to figure out what this is. MMP
#endif
#endif
nsIURI* uri;
rv = mChannel->GetURI(&uri);
@ -456,6 +457,9 @@ PluginViewerImpl::Destroy(void)
// doing this in the destructor is too late.
if(mOwner != nsnull)
{
// stop the timer explicitly to reduce reference count.
mOwner->CancelTimer();
nsCOMPtr<nsIPluginInstance> inst;
if(NS_SUCCEEDED(mOwner->GetInstance(*getter_AddRefs(inst))))
{
@ -520,7 +524,7 @@ HandlePluginEvent(nsGUIEvent *aEvent)
// the Mac, and presumably others, send NS_MOUSE_ACTIVATE
if (aEvent->message == NS_MOUSE_ACTIVATE) {
(nsIWidget*)(aEvent->widget)->SetFocus(); // send focus to child window
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
// furthermore on the Mac nsMacEventHandler sends the NS_PLUGIN_ACTIVATE
// followed by the mouse down event, so we need to handle this
} else {
@ -614,7 +618,8 @@ PluginViewerImpl::SetBounds(const nsRect& aBounds)
win->clipRect.bottom = aBounds.YMost();
win->clipRect.right = aBounds.XMost();
#ifdef XP_MAC // On Mac we also need to add in the widget offset to the plugin window
#if defined(XP_MAC) || defined(XP_MACOSX)
// On Mac we also need to add in the widget offset to the plugin window
mOwner->FixUpPluginWindow();
#endif
((nsPluginNativeWindow *)win)->CallSetWindow(inst);
@ -641,7 +646,8 @@ PluginViewerImpl::Move(PRInt32 aX, PRInt32 aY)
win->clipRect.top = aY;
win->clipRect.left = aX;
#ifdef XP_MAC // On Mac we also need to add in the widget offset to the plugin window
#if defined(XP_MAC) || defined(XP_MACOSX)
// On Mac we also need to add in the widget offset to the plugin window
mOwner->FixUpPluginWindow();
#endif
((nsPluginNativeWindow *)win)->CallSetWindow(inst);
@ -1050,14 +1056,13 @@ pluginInstanceOwner :: pluginInstanceOwner()
pluginInstanceOwner :: ~pluginInstanceOwner()
{
// shut off the timer.
if (mPluginTimer != nsnull) {
CancelTimer();
}
CancelTimer();
NS_IF_RELEASE(mInstance);
mWindow = nsnull;
mViewer = nsnull;
mWidgetVisible = PR_TRUE;
// clean up plugin native window object
nsCOMPtr<nsIPluginHost> ph = do_GetService(kCPluginManagerCID);
@ -1108,41 +1113,27 @@ NS_IMETHODIMP pluginInstanceOwner :: CreateWidget(void)
NS_ENSURE_TRUE(mPluginWindow, NS_ERROR_NULL_POINTER);
PRBool windowless;
nsresult rv = NS_OK;
if (nsnull != mInstance)
{
#if defined(XP_MAC)
// start a periodic timer to provide null events to the plugin instance.
mPluginTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
if (rv == NS_OK)
rv = mPluginTimer->InitWithCallback(this, 1020 / 60, nsITimer::TYPE_REPEATING_SLACK);
#endif
if (nsnull != mInstance) {
mInstance->GetValue(nsPluginInstanceVariable_WindowlessBool, (void *)&windowless);
if (PR_TRUE == windowless)
{
if (PR_TRUE == windowless) {
mPluginWindow->window = nsnull; //XXX this needs to be a HDC
mPluginWindow->type = nsPluginWindowType_Drawable;
}
else if (nsnull != mWindow)
{
mPluginWindow->window = (nsPluginPort *)mWindow->GetNativeData(NS_NATIVE_PLUGIN_PORT);
} else if (nsnull != mWindow) {
mPluginWindow->type = nsPluginWindowType_Window;
}
else
mPluginWindow->window = (nsPluginPort *)mWindow->GetNativeData(NS_NATIVE_PLUGIN_PORT);
} else
return NS_ERROR_FAILURE;
}
else
return NS_ERROR_FAILURE;
#if defined(XP_MAC)
FixUpPluginWindow();
#if defined(XP_MAC) || defined(XP_MACOSX)
FixUpPluginWindow();
// start the idle timer.
StartTimer();
#endif
return rv;
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP pluginInstanceOwner::GetURL(const char *aURL, const char *aTarget, void *aPostData, PRUint32 aPostDataLen, void *aHeadersData,
@ -1256,15 +1247,15 @@ NS_IMETHODIMP pluginInstanceOwner :: Init(PluginViewerImpl *aViewer, nsIWidget *
// Here's where we forward events to plugins.
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
#if TARGET_CARBON
static void InitializeEventRecord(EventRecord* event)
{
memset(event, 0, sizeof(EventRecord));
GetGlobalMouse(&event->where);
event->when = TickCount();
event->modifiers = GetCurrentKeyModifiers();
::GetGlobalMouse(&event->where);
event->when = ::TickCount();
event->modifiers = ::GetCurrentKeyModifiers();
}
#else
inline void InitializeEventRecord(EventRecord* event) { ::OSEventAvail(0, event); }
@ -1307,7 +1298,7 @@ nsEventStatus pluginInstanceOwner::ProcessEvent(const nsGUIEvent& anEvent)
if (!mInstance || !mWindow || anEvent.message == NS_MENU_SELECTED)
return rv;
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
//if (mWidget != NULL) { // check for null mWidget
EventRecord* event = (EventRecord*)anEvent.nativeMsg;
if (event == NULL || event->what == nullEvent ||
@ -1316,19 +1307,19 @@ nsEventStatus pluginInstanceOwner::ProcessEvent(const nsGUIEvent& anEvent)
GUItoMacEvent(anEvent, macEvent);
event = &macEvent;
if (event->what == updateEvt) {
nsPluginPort* pluginPort = GetPluginPort();
// Add in child windows absolute position to get make the dirty rect
// relative to the top-level window.
FixUpPluginWindow();
EventRecord updateEvent;
InitializeEventRecord(&updateEvent);
updateEvent.what = updateEvt;
updateEvent.message = UInt32(pluginPort->port);
nsPluginEvent pluginEvent = { &updateEvent, nsPluginPlatformWindowRef(pluginPort->port) };
PRBool eventHandled = PR_FALSE;
mInstance->HandleEvent(&pluginEvent, &eventHandled);
nsPluginPort* pluginPort = FixUpPluginWindow();
if (pluginPort) {
EventRecord updateEvent;
InitializeEventRecord(&updateEvent);
updateEvent.what = updateEvt;
updateEvent.message = UInt32(pluginPort->port);
nsPluginEvent pluginEvent = { &updateEvent, nsPluginPlatformWindowRef(pluginPort->port) };
PRBool eventHandled = PR_FALSE;
mInstance->HandleEvent(&pluginEvent, &eventHandled);
}
}
return nsEventStatus_eConsumeNoDefault;
@ -1361,37 +1352,29 @@ nsEventStatus pluginInstanceOwner::ProcessEvent(const nsGUIEvent& anEvent)
NS_IMETHODIMP pluginInstanceOwner::Notify(nsITimer* /* timer */)
{
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
// validate the plugin clipping information by syncing the plugin window info to
// reflect the current widget location. This makes sure that everything is updated
// correctly in the event of scrolling in the window.
FixUpPluginWindow();
if (mInstance != NULL) {
EventRecord idleEvent;
InitializeEventRecord(&idleEvent);
idleEvent.what = nullEvent;
nsPluginPort* pluginPort = FixUpPluginWindow();
if (pluginPort) {
EventRecord idleEvent;
InitializeEventRecord(&idleEvent);
idleEvent.what = nullEvent;
// give a bogus 'where' field of our null event when hidden, so Flash
// won't respond to mouse moves in other tabs, see bug 120875
if (!mWidgetVisible)
idleEvent.where.h = idleEvent.where.v = 20000;
nsPluginPort* pluginPort = GetPluginPort();
nsPluginEvent pluginEvent = { &idleEvent, nsPluginPlatformWindowRef(pluginPort->port) };
PRBool eventHandled = PR_FALSE;
mInstance->HandleEvent(&pluginEvent, &eventHandled);
// give a bogus 'where' field of our null event when hidden, so Flash
// won't respond to mouse moves in other tabs, see bug 120875
if (!mWidgetVisible)
idleEvent.where.h = idleEvent.where.v = 20000;
nsPluginEvent pluginEvent = { &idleEvent, nsPluginPlatformWindowRef(pluginPort->port) };
PRBool eventHandled = PR_FALSE;
mInstance->HandleEvent(&pluginEvent, &eventHandled);
}
}
#ifndef REPEATING_TIMERS
// reprime the timer? currently have to create a new timer for each call, which is
// kind of wasteful. need to get periodic timers working on all platforms.
nsresult rv;
mPluginTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
if (NS_SUCCEEDED(rv))
mPluginTimer->InitWithCallback(this, 1020 / 60, nsITimer::TYPE_ONE_SHOT);
#endif // REPEATING_TIMERS
#endif // XP_MAC
#endif // XP_MAC || XP_MACOSX
return NS_OK;
}
@ -1404,6 +1387,21 @@ void pluginInstanceOwner::CancelTimer()
}
}
void pluginInstanceOwner::StartTimer()
{
#if defined(XP_MAC) || defined(XP_MACOSX)
nsresult rv;
// start a periodic timer to provide null events to the plugin instance.
if (!mPluginTimer) {
mPluginTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
if (rv == NS_OK)
rv = mPluginTimer->InitWithCallback(this, 1020 / 60, nsITimer::TYPE_REPEATING_SLACK);
}
#endif
}
nsPluginPort* pluginInstanceOwner::GetPluginPort()
{
//!!! Port must be released for windowless plugins on Windows, because it is HDC !!!
@ -1416,7 +1414,7 @@ nsPluginPort* pluginInstanceOwner::GetPluginPort()
return result;
}
#ifdef XP_MAC
#if defined(XP_MAC) || defined(XP_MACOSX)
// calculate the absolute position and clip for a widget
// and use other windows in calculating the clip
@ -1476,31 +1474,58 @@ static void GetWidgetPosClipAndVis(nsIWidget* aWidget,nscoord& aAbsX, nscoord& a
}
void pluginInstanceOwner::FixUpPluginWindow()
nsPluginPort* pluginInstanceOwner::FixUpPluginWindow()
{
if (!mPluginWindow)
return;
return nsnull;
if (mWindow) {
nsPluginPort* pluginPort = GetPluginPort();
nscoord absWidgetX = 0;
nscoord absWidgetY = 0;
nsRect widgetClip(0,0,0,0);
PRBool isVisible = PR_TRUE;
GetWidgetPosClipAndVis(mWindow,absWidgetX,absWidgetY,widgetClip,isVisible);
if (mWidgetVisible != isVisible)
mWidgetVisible = isVisible;
#if defined(MOZ_WIDGET_COCOA)
// set the port coordinates
mPluginWindow->x = -pluginPort->portx;
mPluginWindow->y = -pluginPort->porty;
widgetClip.x += mPluginWindow->x - absWidgetX;
widgetClip.y += mPluginWindow->y - absWidgetY;
#else
// set the port coordinates
mPluginWindow->x = absWidgetX;
mPluginWindow->y = absWidgetY;
#endif
// fix up the clipping region
mPluginWindow->clipRect.top = widgetClip.y;
mPluginWindow->clipRect.left = widgetClip.x;
mPluginWindow->clipRect.bottom = mPluginWindow->clipRect.top + widgetClip.height;
mPluginWindow->clipRect.right = mPluginWindow->clipRect.left + widgetClip.width;
if (mWidgetVisible != isVisible) {
mWidgetVisible = isVisible;
// must do this to disable async Java Applet drawing
if (isVisible) {
mInstance->SetWindow(mPluginWindow);
} else {
mInstance->SetWindow(nsnull);
// switching states, do not draw
pluginPort = nsnull;
}
}
#if defined(MOZ_WIDGET_COCOA)
if (!mWidgetVisible) {
mPluginWindow->clipRect.right = mPluginWindow->clipRect.left;
mPluginWindow->clipRect.bottom = mPluginWindow->clipRect.top;
}
#endif
return pluginPort;
}
return nsnull;
}
#endif

View File

@ -53,15 +53,7 @@
#include <TextUtils.h>
#include <Aliases.h>
#include <string.h>
#if TARGET_CARBON && (UNIVERSAL_INTERFACES_VERSION < 0x0340)
enum {
kLocalDomain = -32765, /* All users of a single machine have access to these resources.*/
kUserDomain = -32763, /* Read/write. Resources that are private to the user.*/
kClassicDomain = -32762 /* Domain referring to the currently configured Classic System Folder*/
};
#endif
#if TARGET_CARBON
#include <CFURL.h>
#include <CFBundle.h>
#include <CFString.h>
@ -71,53 +63,21 @@ enum {
** Returns a CFBundleRef if the FSSpec refers to a Mac OS X bundle directory.
** The caller is responsible for calling CFRelease() to deallocate.
*/
static CFBundleRef getPluginBundle(const FSSpec& spec)
static CFBundleRef getPluginBundle(const char* path)
{
CFBundleRef bundle = NULL;
FSRef ref;
OSErr err = FSpMakeFSRef(&spec, &ref);
char path[512];
if (err == noErr && (UInt32(FSRefMakePath) != kUnresolvedCFragSymbolAddress)) {
err = FSRefMakePath(&ref, (UInt8*)path, sizeof(path) - 1);
if (err == noErr) {
CFStringRef pathRef = CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8);
if (pathRef) {
CFURLRef bundleURL = CFURLCreateWithFileSystemPath(NULL, pathRef, kCFURLPOSIXPathStyle, true);
if (bundleURL != NULL) {
bundle = CFBundleCreate(NULL, bundleURL);
CFRelease(bundleURL);
}
CFRelease(pathRef);
}
CFStringRef pathRef = CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8);
if (pathRef) {
CFURLRef bundleURL = CFURLCreateWithFileSystemPath(NULL, pathRef, kCFURLPOSIXPathStyle, true);
if (bundleURL != NULL) {
bundle = CFBundleCreate(NULL, bundleURL);
CFRelease(bundleURL);
}
CFRelease(pathRef);
}
return bundle;
}
extern "C" {
// Not yet in Universal Interfaces that I'm using.
EXTERN_API_C( SInt16 )
CFBundleOpenBundleResourceMap(CFBundleRef bundle);
EXTERN_API_C( void )
CFBundleGetPackageInfo(CFBundleRef bundle, UInt32 * packageType, UInt32 * packageCreator);
}
#endif
static nsresult getApplicationSpec(FSSpec& outAppSpec)
{
// Use the process manager to get the application's FSSpec,
// then construct an nsFileSpec that encapsulates it.
ProcessInfoRec info;
info.processInfoLength = sizeof(info);
info.processName = NULL;
info.processAppSpec = &outAppSpec;
ProcessSerialNumber psn = { 0, kCurrentProcess };
OSErr result = GetProcessInformation(&psn, &info);
return (result == noErr ? NS_OK : NS_ERROR_FAILURE);
}
static OSErr toFSSpec(const nsFileSpec& inFileSpec, FSSpec& outSpec)
{
FSRef ref;
@ -127,11 +87,11 @@ static OSErr toFSSpec(const nsFileSpec& inFileSpec, FSSpec& outSpec)
return err;
}
#undef printf
PRBool nsPluginsDir::IsPluginFile(const nsFileSpec& fileSpec)
{
#ifdef DEBUG
printf("nsPluginsDir::IsPluginFile: checking %s\n", fileSpec.GetCString());
#endif
// look at file's creator/type and make sure it is a code fragment, etc.
FSSpec spec;
OSErr err = toFSSpec(fileSpec, spec);
@ -142,17 +102,18 @@ PRBool nsPluginsDir::IsPluginFile(const nsFileSpec& fileSpec)
err = FSpGetFInfo(&spec, &info);
if (err == noErr && ((info.fdType == 'shlb' && info.fdCreator == 'MOSS') ||
info.fdType == 'NSPL')) {
#ifdef DEBUG
printf("found plugin '%s'.\n", fileSpec.GetCString());
#endif
return PR_TRUE;
}
#if TARGET_CARBON
// Some additional plugin types for Carbon/Mac OS X
if (err == noErr && (info.fdType == 'BRPL' || info.fdType == 'IEPL'))
return PR_TRUE;
// for Mac OS X bundles.
CFBundleRef bundle = getPluginBundle(spec);
// for Mac OS X bundles.
CFBundleRef bundle = getPluginBundle(fileSpec.GetCString());
if (bundle) {
UInt32 packageType, packageCreator;
CFBundleGetPackageInfo(bundle, &packageType, &packageCreator);
@ -161,10 +122,12 @@ PRBool nsPluginsDir::IsPluginFile(const nsFileSpec& fileSpec)
case 'BRPL':
case 'IEPL':
case 'NSPL':
#ifdef DEBUG
printf("found bundled plugin '%s'.\n", fileSpec.GetCString());
#endif
return PR_TRUE;
}
}
#endif
return PR_FALSE;
}
@ -184,6 +147,12 @@ nsresult nsPluginFile::LoadPlugin(PRLibrary* &outLibrary)
{
const char* path = this->GetCString();
outLibrary = PR_LoadLibrary(path);
if (!outLibrary) {
return NS_ERROR_FAILURE;
}
#ifdef DEBUG
printf("[loaded plugin %s]\n", path);
#endif
return NS_OK;
}
@ -215,15 +184,13 @@ short nsPluginFile::OpenPluginResource()
err = ::ResolveAliasFile(&spec, true, &targetIsFolder, &wasAliased);
short refNum = ::FSpOpenResFile(&spec, fsRdPerm);
#if TARGET_CARBON
if (refNum == -1) {
CFBundleRef bundle = getPluginBundle(spec);
CFBundleRef bundle = getPluginBundle(this->GetCString());
if (bundle) {
refNum = CFBundleOpenBundleResourceMap(bundle);
CFRelease(bundle);
}
}
#endif
return refNum;
}
@ -264,14 +231,12 @@ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info)
info.fFileName = p2cstrdup(spec.name);
info.fFullPath = PL_strdup(this->GetCString());
#if TARGET_CARBON
CFBundleRef bundle = getPluginBundle(spec);
CFBundleRef bundle = getPluginBundle(this->GetCString());
if (bundle) {
info.fBundle = PR_TRUE;
CFRelease(bundle);
} else
info.fBundle = PR_FALSE;
#endif
short mimeIndex = 1, descriptionIndex = 1;
for (int i = 0; i < variantCount; i++) {