Added mPluginPort, which is either the assigned port, or an empty one shared among all plugin instances. This should inhibit drawing when an applet leaves the current page. Added explicit releaseFrames(), called by MRJContext's destructor, so that any frames owned by the applet will be disconnected from the C++ objects before the objects go away.

This commit is contained in:
beard%netscape.com 1998-12-17 18:22:22 +00:00
Родитель 5a297e3119
Коммит 8070285bc2
1 изменённых файлов: 68 добавлений и 8 удалений

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

@ -76,7 +76,7 @@ void LocalPort::Exit()
MRJContext::MRJContext(MRJSession* session, MRJPluginInstance* instance) MRJContext::MRJContext(MRJSession* session, MRJPluginInstance* instance)
: mPluginInstance(instance), mSession(session), mSessionRef(session->getSessionRef()), mPeer(NULL), : mPluginInstance(instance), mSession(session), mSessionRef(session->getSessionRef()), mPeer(NULL),
mLocator(NULL), mContext(NULL), mViewer(NULL), mViewerFrame(NULL), mIsActive(false), mLocator(NULL), mContext(NULL), mViewer(NULL), mViewerFrame(NULL), mIsActive(false),
mPluginWindow(NULL), mPluginClipping(NULL), mCodeBase(NULL), mPage(NULL) mPluginWindow(NULL), mPluginClipping(NULL), mPluginPort(NULL), mCodeBase(NULL), mPage(NULL)
{ {
instance->GetPeer(&mPeer); instance->GetPeer(&mPeer);
@ -93,6 +93,7 @@ MRJContext::MRJContext(MRJSession* session, MRJPluginInstance* instance)
/* Is this a window or a drawable? */ /* Is this a window or a drawable? */
mPluginClipping = ::NewRgn(); mPluginClipping = ::NewRgn();
mPluginPort = getEmptyPort();
} }
MRJContext::~MRJContext() MRJContext::~MRJContext()
@ -107,11 +108,16 @@ MRJContext::~MRJContext()
mViewer = NULL; mViewer = NULL;
} }
#if 0
// hack: see if this allows the applet viewer to terminate gracefully. // hack: see if this allows the applet viewer to terminate gracefully.
for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++)
::JMIdle(mSessionRef, kDefaultJMTime); ::JMIdle(mSessionRef, kDefaultJMTime);
#endif
if (mContext != NULL) { if (mContext != NULL) {
// hack: release any frames that we still see in the AWT context, before tossing it.
releaseFrames();
::JMDisposeAWTContext(mContext); ::JMDisposeAWTContext(mContext);
mContext = NULL; mContext = NULL;
} }
@ -801,10 +807,9 @@ void MRJContext::drawApplet()
// We assume the proper coordinate system for the frame has // We assume the proper coordinate system for the frame has
// already been set up. // already been set up.
if (appletLoaded()) { if (appletLoaded()) {
#if DEBUG_CLIPPING
nsPluginPort* npPort = (nsPluginPort*) mCache.window; nsPluginPort* npPort = (nsPluginPort*) mCache.window;
GrafPtr framePort = GrafPtr(npPort->port); GrafPtr framePort = GrafPtr(npPort->port);
#if DEBUG_CLIPPING
RgnHandle oldClip = NewRgn(); RgnHandle oldClip = NewRgn();
if (oldClip != NULL) { if (oldClip != NULL) {
CopyRgn(framePort->clipRgn, oldClip); CopyRgn(framePort->clipRgn, oldClip);
@ -908,6 +913,12 @@ void MRJContext::setWindow(nsPluginWindow* pluginWindow)
mPluginWindow = pluginWindow; mPluginWindow = pluginWindow;
mCache.window = NULL; mCache.window = NULL;
// establish the GrafPort the plugin will draw in.
mPluginPort = pluginWindow->window->port;
// set up the clipping region based on width & height.
::SetRectRgn(mPluginClipping, 0, 0, pluginWindow->width, pluginWindow->height);
if (! appletLoaded()) if (! appletLoaded())
loadApplet(); loadApplet();
@ -917,6 +928,10 @@ void MRJContext::setWindow(nsPluginWindow* pluginWindow)
// tell MRJ the window has gone away. // tell MRJ the window has gone away.
mPluginWindow = NULL; mPluginWindow = NULL;
// use a single, 0x0, empty port for all future drawing.
mPluginPort = getEmptyPort();
// perhaps we should set the port to something quite innocuous, no? say a 0x0, empty port?
::SetEmptyRgn(mPluginClipping); ::SetEmptyRgn(mPluginClipping);
setVisibility(); setVisibility();
} }
@ -999,11 +1014,15 @@ MRJFrame* MRJContext::findFrame(WindowRef window)
GrafPtr MRJContext::getPort() GrafPtr MRJContext::getPort()
{ {
#if 0
if (mPluginWindow != NULL) { if (mPluginWindow != NULL) {
nsPluginPort* npPort = (nsPluginPort*) mPluginWindow->window; nsPluginPort* npPort = (nsPluginPort*) mPluginWindow->window;
return GrafPtr(npPort->port); return GrafPtr(npPort->port);
} }
return NULL; return NULL;
#endif
return GrafPtr(mPluginPort);
} }
void MRJContext::localToFrame(Point* pt) void MRJContext::localToFrame(Point* pt)
@ -1020,8 +1039,9 @@ void MRJContext::ensureValidPort()
{ {
if (mPluginWindow != NULL) { if (mPluginWindow != NULL) {
nsPluginPort* npPort = (nsPluginPort*) mPluginWindow->window; nsPluginPort* npPort = (nsPluginPort*) mPluginWindow->window;
if (npPort != NULL) if (npPort == NULL)
::SetPort(GrafPtr(npPort->port)); mPluginPort = getEmptyPort();
::SetPort(GrafPtr(mPluginPort));
} }
} }
@ -1043,13 +1063,12 @@ void MRJContext::setVisibility()
nsPluginWindow* npWindow = &mCache; nsPluginWindow* npWindow = &mCache;
// compute the frame's origin and clipping. // compute the frame's origin and clipping.
nsPluginPort* npPort = (nsPluginPort*) npWindow->window;
// JManager wants the origin expressed in window coordinates. // JManager wants the origin expressed in window coordinates.
Point frameOrigin = { npWindow->y, npWindow->x }; Point frameOrigin = { npWindow->y, npWindow->x };
// The clipping region is now maintained by a new browser event. // The clipping region is now maintained by a new browser event.
OSStatus status = ::JMSetFrameVisibility(mViewerFrame, GrafPtr(npPort->port), OSStatus status = ::JMSetFrameVisibility(mViewerFrame, GrafPtr(mPluginPort),
frameOrigin, mPluginClipping); frameOrigin, mPluginClipping);
} }
} }
@ -1091,6 +1110,25 @@ void MRJContext::hideFrames()
} }
} }
/**
* Ensure that any frames Java still has a reference to are no longer valid, so that we won't crash
* after a plugin instance gets shut down. This is called by the destructor just in case, to avoid
* some hard freeze crashes I've seen.
*/
void MRJContext::releaseFrames()
{
UInt32 frameCount;
OSStatus status = ::JMCountAWTContextFrames(mContext, &frameCount);
if (status == noErr) {
for (UInt32 frameIndex = 0; frameIndex < frameCount; frameIndex++) {
JMFrameRef frameRef = NULL;
status = ::JMGetAWTContextFrame(mContext, frameIndex, &frameRef);
if (status == noErr)
releaseFrame(mContext, frameRef);
}
}
}
const char* MRJContext::getCodeBase() const char* MRJContext::getCodeBase()
{ {
return mCodeBase; return mCodeBase;
@ -1115,3 +1153,25 @@ MRJPage* MRJContext::findPage(const MRJPageAttributes& attributes)
page->AddRef(); page->AddRef();
return page; return page;
} }
struct EmptyPort : public CGrafPort {
EmptyPort() {
GrafPtr oldPort;
::GetPort(&oldPort);
::OpenCPort(this);
::PortSize(0, 0);
::SetEmptyRgn(this->visRgn);
::SetEmptyRgn(this->clipRgn);
::SetPort(oldPort);
}
~EmptyPort() {
::CloseCPort(this);
}
};
CGrafPtr MRJContext::getEmptyPort()
{
static EmptyPort emptyPort;
return &emptyPort;
}