diff --git a/modules/plugin/base/src/ns4xPluginStream.cpp b/modules/plugin/base/src/ns4xPluginStream.cpp index 434a662e62ac..5a1c52a9fcb4 100644 --- a/modules/plugin/base/src/ns4xPluginStream.cpp +++ b/modules/plugin/base/src/ns4xPluginStream.cpp @@ -157,6 +157,7 @@ NS_IMETHODIMP ns4xPluginStream::Write(const char* buffer, PRInt32 offset, PRInt3 { const NPPluginFuncs *callbacks; NPP npp; + PRInt32 remaining = len; fInstance->GetCallbacks(&callbacks); fInstance->GetNPP(&npp); @@ -164,12 +165,31 @@ NS_IMETHODIMP ns4xPluginStream::Write(const char* buffer, PRInt32 offset, PRInt3 if (callbacks->write == NULL) return NS_OK; - *aWriteCount = CallNPP_WriteProc(callbacks->write, - npp, - &fNPStream, - fPosition, - len, - (void *)buffer); + while (remaining > 0) + { + PRInt32 numtowrite; + + if (callbacks->writeready != NULL) + { + numtowrite = CallNPP_WriteReadyProc(callbacks->writeready, + npp, + &fNPStream); + + if (numtowrite > remaining) + numtowrite = remaining; + } + else + numtowrite = len; + + *aWriteCount = CallNPP_WriteProc(callbacks->write, + npp, + &fNPStream, + fPosition, + numtowrite, + (void *)buffer); + + remaining -= numtowrite; + } fPosition += len; diff --git a/modules/plugin/base/src/nsIPluginHost.h b/modules/plugin/base/src/nsIPluginHost.h index 650bf516da1e..690a24fca509 100644 --- a/modules/plugin/base/src/nsIPluginHost.h +++ b/modules/plugin/base/src/nsIPluginHost.h @@ -24,6 +24,8 @@ #include "nsIFactory.h" #include "nsString.h" +class nsIURL; + #define NS_IPLUGINHOST_IID \ { 0x264c0640, 0x1c31, 0x11d2, \ { 0xa8, 0x2e, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } } @@ -39,7 +41,7 @@ public: LoadPlugins(void) = 0; NS_IMETHOD - InstantiatePlugin(const char *aMimeType, nsIPluginInstance ** aPluginInst) = 0; + InstantiatePlugin(const char *aMimeType, nsIURL *aURL, nsIPluginInstance ** aPluginInst) = 0; NS_IMETHOD InstantiatePlugin(const char *aMimeType, nsIPluginInstance ** aPluginInst, diff --git a/modules/plugin/base/src/nsPluginHostImpl.cpp b/modules/plugin/base/src/nsPluginHostImpl.cpp index 7238f1ec5d2b..b6aa5d235ad4 100644 --- a/modules/plugin/base/src/nsPluginHostImpl.cpp +++ b/modules/plugin/base/src/nsPluginHostImpl.cpp @@ -164,6 +164,8 @@ private: void *mNotifyData; nsPluginWindow *mWindow; nsIPluginHost *mHost; + PRInt32 mLength; + PRBool mGotProgress; }; nsPluginStreamListener :: nsPluginStreamListener() @@ -180,6 +182,8 @@ nsPluginStreamListener :: nsPluginStreamListener() mNotifyData = nsnull; mWindow = nsnull; mHost = nsnull; + mLength = 0; + mGotProgress = PR_FALSE; } nsPluginStreamListener :: ~nsPluginStreamListener() @@ -291,9 +295,9 @@ NS_IMETHODIMP nsPluginStreamListener :: OnStartBinding(nsIURL* aURL, const char //to load a plugin... if ((nsnull == mInstance) && (nsnull != mFarInstance) && - (nsnull != mHost) && (nsnull != mWindow) && (nsnull != mMIMEType)) + (nsnull != mHost) && (nsnull != mWindow)) { - rv = mHost->InstantiatePlugin(mMIMEType, mFarInstance); + rv = mHost->InstantiatePlugin(aContentType, aURL, mFarInstance); if (NS_OK == rv) { @@ -305,6 +309,19 @@ NS_IMETHODIMP nsPluginStreamListener :: OnStartBinding(nsIURL* aURL, const char } } + if ((PR_TRUE == mGotProgress) && (nsnull == mPeer) && + (nsnull != mInstance) && (PR_FALSE == mBound)) + { + //need to create new peer and and tell plugin that we have new stream... + + mPeer = (nsPluginStreamPeer *)new nsPluginStreamPeer(); + + NS_ADDREF(mPeer); + + mPeer->Initialize(aURL, mLength, 0, aContentType, mNotifyData); + mInstance->NewStream(mPeer, &mStream); + } + mBound = PR_TRUE; return rv; @@ -312,9 +329,7 @@ NS_IMETHODIMP nsPluginStreamListener :: OnStartBinding(nsIURL* aURL, const char NS_IMETHODIMP nsPluginStreamListener :: OnProgress(nsIURL* aURL, PRInt32 aProgress, PRInt32 aProgressMax) { - NS_ASSERTION(!(mBound == PR_FALSE), "ack, got progress without start binding"); - - if ((PR_TRUE == mBound) && (nsnull == mPeer)) + if ((aProgress == 0) && (nsnull == mPeer) && (nsnull != mInstance)) { //need to create new peer and and tell plugin that we have new stream... @@ -326,6 +341,9 @@ NS_IMETHODIMP nsPluginStreamListener :: OnProgress(nsIURL* aURL, PRInt32 aProgre mInstance->NewStream(mPeer, &mStream); } + mLength = aProgressMax; + mGotProgress = PR_TRUE; + return NS_OK; } @@ -836,25 +854,101 @@ printf("plugin %s added to list %s\n", plugintag->mName, (plugintag->mFlags & NS return NS_OK; } -nsresult nsPluginHostImpl :: InstantiatePlugin(const char *aMimeType, nsIPluginInstance ** aPluginInst) +nsresult nsPluginHostImpl :: InstantiatePlugin(const char *aMimeType, nsIURL *aURL, + nsIPluginInstance ** aPluginInst) { - nsPluginTag *plugins = mPlugins; + nsPluginTag *plugins = nsnull; PRInt32 variants, cnt; - while (nsnull != plugins) + if (nsnull != aMimeType) { - variants = plugins->mVariants; + plugins = mPlugins; - for (cnt = 0; cnt < variants; cnt++) + while (nsnull != plugins) { - if (0 == strcmp(plugins->mMimeTypeArray[cnt], aMimeType)) + variants = plugins->mVariants; + + for (cnt = 0; cnt < variants; cnt++) + { + if (0 == strcmp(plugins->mMimeTypeArray[cnt], aMimeType)) + break; + } + + if (cnt < variants) break; + + plugins = plugins->mNext; } + } - if (cnt < variants) - break; + if ((nsnull == plugins) && (nsnull != aURL)) + { + const char *name = aURL->GetSpec(); + PRInt32 len = strlen(name); - plugins = plugins->mNext; + //find the plugin by filename extension. + + if ((nsnull != name) && (len > 1)) + { + len--; + + while ((name[len] != 0) && (name[len] != '.')) + len--; + + if (name[len] == '.') + { + const char *ext = name + len + 1; + + len = strlen(ext); + + plugins = mPlugins; + + while (nsnull != plugins) + { + variants = plugins->mVariants; + + for (cnt = 0; cnt < variants; cnt++) + { + char *extensions = plugins->mExtensionsArray[cnt]; + char *nextexten; + PRInt32 extlen; + + while (nsnull != extensions) + { + nextexten = strchr(extensions, ','); + + if (nsnull != nextexten) + extlen = nextexten - extensions; + else + extlen = strlen(extensions); + + if (extlen == len) + { + if (strnicmp(extensions, ext, extlen) == 0) + break; + } + + if (nsnull != nextexten) + extensions = nextexten + 1; + else + extensions = nsnull; + } + + if (nsnull != extensions) + break; + } + + if (cnt < variants) + { + aMimeType = plugins->mMimeTypeArray[cnt]; +printf("found plugin via extension %s\n", ext); + break; + } + + plugins = plugins->mNext; + } + } + } } if (nsnull != plugins) @@ -895,7 +989,6 @@ printf("result of creating plugin adapter: %d\n", rv); if (NS_OK == plugins->mEntryPoint->CreateInstance(nsnull, kIPluginInstanceIID, (void **)aPluginInst)) { printf("successfully created plugin instance\n"); - nsPluginInstancePeerImpl *peer = new nsPluginInstancePeerImpl(); peer->Initialize(*aPluginInst); //this will not add a ref to the instance. MMP @@ -910,38 +1003,41 @@ printf("successfully created plugin instance\n"); } else { -printf("unable to find plugin to handle %s\n", aMimeType); + if ((nsnull != aURL) || (nsnull != aMimeType)) +printf("unable to find plugin to handle %s\n", aMimeType ? aMimeType : "(mime type unspecified)"); return NS_ERROR_FAILURE; } } nsresult nsPluginHostImpl :: InstantiatePlugin(const char *aMimeType, nsIPluginInstance ** aPluginInst, - nsPluginWindow *aWindow, nsString& aURL) + nsPluginWindow *aWindow, nsString& aURLSpec) { nsresult rv; - if (nsnull == aMimeType) + rv = InstantiatePlugin(aMimeType, nsnull, aPluginInst); + + if ((rv != NS_OK) || (nsnull == aMimeType)) { - if (aURL.Length() > 0) + //either the plugin could not be identified based + //on the mime type or there was no mime type + + if (aURLSpec.Length() > 0) { //we need to stream in enough to get the mime type... - rv = NewPluginStream(aURL, aPluginInst, aWindow); + rv = NewPluginStream(aURLSpec, aPluginInst, aWindow); } else rv = NS_ERROR_FAILURE; } else { - rv = InstantiatePlugin(aMimeType, aPluginInst); + //we got a plugin built, now stream - if (NS_OK == rv) - { - (*aPluginInst)->Start(); - (*aPluginInst)->SetWindow(aWindow); - NewPluginStream(aURL, *aPluginInst, nsnull); - } + (*aPluginInst)->Start(); + (*aPluginInst)->SetWindow(aWindow); + NewPluginStream(aURLSpec, *aPluginInst, nsnull); } return rv; diff --git a/modules/plugin/base/src/nsPluginHostImpl.h b/modules/plugin/base/src/nsPluginHostImpl.h index 71d5d99d00cd..8dd27edfd3e7 100644 --- a/modules/plugin/base/src/nsPluginHostImpl.h +++ b/modules/plugin/base/src/nsPluginHostImpl.h @@ -107,7 +107,7 @@ public: LoadPlugins(void); NS_IMETHOD - InstantiatePlugin(const char *aMimeType, nsIPluginInstance ** aPluginInst); + InstantiatePlugin(const char *aMimeType, nsIURL *aURL, nsIPluginInstance ** aPluginInst); NS_IMETHOD InstantiatePlugin(const char *aMimeType, nsIPluginInstance ** aPluginInst, diff --git a/modules/plugin/nglsrc/ns4xPluginStream.cpp b/modules/plugin/nglsrc/ns4xPluginStream.cpp index 434a662e62ac..5a1c52a9fcb4 100644 --- a/modules/plugin/nglsrc/ns4xPluginStream.cpp +++ b/modules/plugin/nglsrc/ns4xPluginStream.cpp @@ -157,6 +157,7 @@ NS_IMETHODIMP ns4xPluginStream::Write(const char* buffer, PRInt32 offset, PRInt3 { const NPPluginFuncs *callbacks; NPP npp; + PRInt32 remaining = len; fInstance->GetCallbacks(&callbacks); fInstance->GetNPP(&npp); @@ -164,12 +165,31 @@ NS_IMETHODIMP ns4xPluginStream::Write(const char* buffer, PRInt32 offset, PRInt3 if (callbacks->write == NULL) return NS_OK; - *aWriteCount = CallNPP_WriteProc(callbacks->write, - npp, - &fNPStream, - fPosition, - len, - (void *)buffer); + while (remaining > 0) + { + PRInt32 numtowrite; + + if (callbacks->writeready != NULL) + { + numtowrite = CallNPP_WriteReadyProc(callbacks->writeready, + npp, + &fNPStream); + + if (numtowrite > remaining) + numtowrite = remaining; + } + else + numtowrite = len; + + *aWriteCount = CallNPP_WriteProc(callbacks->write, + npp, + &fNPStream, + fPosition, + numtowrite, + (void *)buffer); + + remaining -= numtowrite; + } fPosition += len; diff --git a/modules/plugin/nglsrc/nsIPluginHost.h b/modules/plugin/nglsrc/nsIPluginHost.h index 650bf516da1e..690a24fca509 100644 --- a/modules/plugin/nglsrc/nsIPluginHost.h +++ b/modules/plugin/nglsrc/nsIPluginHost.h @@ -24,6 +24,8 @@ #include "nsIFactory.h" #include "nsString.h" +class nsIURL; + #define NS_IPLUGINHOST_IID \ { 0x264c0640, 0x1c31, 0x11d2, \ { 0xa8, 0x2e, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } } @@ -39,7 +41,7 @@ public: LoadPlugins(void) = 0; NS_IMETHOD - InstantiatePlugin(const char *aMimeType, nsIPluginInstance ** aPluginInst) = 0; + InstantiatePlugin(const char *aMimeType, nsIURL *aURL, nsIPluginInstance ** aPluginInst) = 0; NS_IMETHOD InstantiatePlugin(const char *aMimeType, nsIPluginInstance ** aPluginInst, diff --git a/modules/plugin/nglsrc/nsPluginHostImpl.cpp b/modules/plugin/nglsrc/nsPluginHostImpl.cpp index 7238f1ec5d2b..b6aa5d235ad4 100644 --- a/modules/plugin/nglsrc/nsPluginHostImpl.cpp +++ b/modules/plugin/nglsrc/nsPluginHostImpl.cpp @@ -164,6 +164,8 @@ private: void *mNotifyData; nsPluginWindow *mWindow; nsIPluginHost *mHost; + PRInt32 mLength; + PRBool mGotProgress; }; nsPluginStreamListener :: nsPluginStreamListener() @@ -180,6 +182,8 @@ nsPluginStreamListener :: nsPluginStreamListener() mNotifyData = nsnull; mWindow = nsnull; mHost = nsnull; + mLength = 0; + mGotProgress = PR_FALSE; } nsPluginStreamListener :: ~nsPluginStreamListener() @@ -291,9 +295,9 @@ NS_IMETHODIMP nsPluginStreamListener :: OnStartBinding(nsIURL* aURL, const char //to load a plugin... if ((nsnull == mInstance) && (nsnull != mFarInstance) && - (nsnull != mHost) && (nsnull != mWindow) && (nsnull != mMIMEType)) + (nsnull != mHost) && (nsnull != mWindow)) { - rv = mHost->InstantiatePlugin(mMIMEType, mFarInstance); + rv = mHost->InstantiatePlugin(aContentType, aURL, mFarInstance); if (NS_OK == rv) { @@ -305,6 +309,19 @@ NS_IMETHODIMP nsPluginStreamListener :: OnStartBinding(nsIURL* aURL, const char } } + if ((PR_TRUE == mGotProgress) && (nsnull == mPeer) && + (nsnull != mInstance) && (PR_FALSE == mBound)) + { + //need to create new peer and and tell plugin that we have new stream... + + mPeer = (nsPluginStreamPeer *)new nsPluginStreamPeer(); + + NS_ADDREF(mPeer); + + mPeer->Initialize(aURL, mLength, 0, aContentType, mNotifyData); + mInstance->NewStream(mPeer, &mStream); + } + mBound = PR_TRUE; return rv; @@ -312,9 +329,7 @@ NS_IMETHODIMP nsPluginStreamListener :: OnStartBinding(nsIURL* aURL, const char NS_IMETHODIMP nsPluginStreamListener :: OnProgress(nsIURL* aURL, PRInt32 aProgress, PRInt32 aProgressMax) { - NS_ASSERTION(!(mBound == PR_FALSE), "ack, got progress without start binding"); - - if ((PR_TRUE == mBound) && (nsnull == mPeer)) + if ((aProgress == 0) && (nsnull == mPeer) && (nsnull != mInstance)) { //need to create new peer and and tell plugin that we have new stream... @@ -326,6 +341,9 @@ NS_IMETHODIMP nsPluginStreamListener :: OnProgress(nsIURL* aURL, PRInt32 aProgre mInstance->NewStream(mPeer, &mStream); } + mLength = aProgressMax; + mGotProgress = PR_TRUE; + return NS_OK; } @@ -836,25 +854,101 @@ printf("plugin %s added to list %s\n", plugintag->mName, (plugintag->mFlags & NS return NS_OK; } -nsresult nsPluginHostImpl :: InstantiatePlugin(const char *aMimeType, nsIPluginInstance ** aPluginInst) +nsresult nsPluginHostImpl :: InstantiatePlugin(const char *aMimeType, nsIURL *aURL, + nsIPluginInstance ** aPluginInst) { - nsPluginTag *plugins = mPlugins; + nsPluginTag *plugins = nsnull; PRInt32 variants, cnt; - while (nsnull != plugins) + if (nsnull != aMimeType) { - variants = plugins->mVariants; + plugins = mPlugins; - for (cnt = 0; cnt < variants; cnt++) + while (nsnull != plugins) { - if (0 == strcmp(plugins->mMimeTypeArray[cnt], aMimeType)) + variants = plugins->mVariants; + + for (cnt = 0; cnt < variants; cnt++) + { + if (0 == strcmp(plugins->mMimeTypeArray[cnt], aMimeType)) + break; + } + + if (cnt < variants) break; + + plugins = plugins->mNext; } + } - if (cnt < variants) - break; + if ((nsnull == plugins) && (nsnull != aURL)) + { + const char *name = aURL->GetSpec(); + PRInt32 len = strlen(name); - plugins = plugins->mNext; + //find the plugin by filename extension. + + if ((nsnull != name) && (len > 1)) + { + len--; + + while ((name[len] != 0) && (name[len] != '.')) + len--; + + if (name[len] == '.') + { + const char *ext = name + len + 1; + + len = strlen(ext); + + plugins = mPlugins; + + while (nsnull != plugins) + { + variants = plugins->mVariants; + + for (cnt = 0; cnt < variants; cnt++) + { + char *extensions = plugins->mExtensionsArray[cnt]; + char *nextexten; + PRInt32 extlen; + + while (nsnull != extensions) + { + nextexten = strchr(extensions, ','); + + if (nsnull != nextexten) + extlen = nextexten - extensions; + else + extlen = strlen(extensions); + + if (extlen == len) + { + if (strnicmp(extensions, ext, extlen) == 0) + break; + } + + if (nsnull != nextexten) + extensions = nextexten + 1; + else + extensions = nsnull; + } + + if (nsnull != extensions) + break; + } + + if (cnt < variants) + { + aMimeType = plugins->mMimeTypeArray[cnt]; +printf("found plugin via extension %s\n", ext); + break; + } + + plugins = plugins->mNext; + } + } + } } if (nsnull != plugins) @@ -895,7 +989,6 @@ printf("result of creating plugin adapter: %d\n", rv); if (NS_OK == plugins->mEntryPoint->CreateInstance(nsnull, kIPluginInstanceIID, (void **)aPluginInst)) { printf("successfully created plugin instance\n"); - nsPluginInstancePeerImpl *peer = new nsPluginInstancePeerImpl(); peer->Initialize(*aPluginInst); //this will not add a ref to the instance. MMP @@ -910,38 +1003,41 @@ printf("successfully created plugin instance\n"); } else { -printf("unable to find plugin to handle %s\n", aMimeType); + if ((nsnull != aURL) || (nsnull != aMimeType)) +printf("unable to find plugin to handle %s\n", aMimeType ? aMimeType : "(mime type unspecified)"); return NS_ERROR_FAILURE; } } nsresult nsPluginHostImpl :: InstantiatePlugin(const char *aMimeType, nsIPluginInstance ** aPluginInst, - nsPluginWindow *aWindow, nsString& aURL) + nsPluginWindow *aWindow, nsString& aURLSpec) { nsresult rv; - if (nsnull == aMimeType) + rv = InstantiatePlugin(aMimeType, nsnull, aPluginInst); + + if ((rv != NS_OK) || (nsnull == aMimeType)) { - if (aURL.Length() > 0) + //either the plugin could not be identified based + //on the mime type or there was no mime type + + if (aURLSpec.Length() > 0) { //we need to stream in enough to get the mime type... - rv = NewPluginStream(aURL, aPluginInst, aWindow); + rv = NewPluginStream(aURLSpec, aPluginInst, aWindow); } else rv = NS_ERROR_FAILURE; } else { - rv = InstantiatePlugin(aMimeType, aPluginInst); + //we got a plugin built, now stream - if (NS_OK == rv) - { - (*aPluginInst)->Start(); - (*aPluginInst)->SetWindow(aWindow); - NewPluginStream(aURL, *aPluginInst, nsnull); - } + (*aPluginInst)->Start(); + (*aPluginInst)->SetWindow(aWindow); + NewPluginStream(aURLSpec, *aPluginInst, nsnull); } return rv; diff --git a/modules/plugin/nglsrc/nsPluginHostImpl.h b/modules/plugin/nglsrc/nsPluginHostImpl.h index 71d5d99d00cd..8dd27edfd3e7 100644 --- a/modules/plugin/nglsrc/nsPluginHostImpl.h +++ b/modules/plugin/nglsrc/nsPluginHostImpl.h @@ -107,7 +107,7 @@ public: LoadPlugins(void); NS_IMETHOD - InstantiatePlugin(const char *aMimeType, nsIPluginInstance ** aPluginInst); + InstantiatePlugin(const char *aMimeType, nsIURL *aURL, nsIPluginInstance ** aPluginInst); NS_IMETHOD InstantiatePlugin(const char *aMimeType, nsIPluginInstance ** aPluginInst, diff --git a/view/src/nsScrollingView.cpp b/view/src/nsScrollingView.cpp index 45019e158be1..bafda07e3c22 100644 --- a/view/src/nsScrollingView.cpp +++ b/view/src/nsScrollingView.cpp @@ -67,9 +67,8 @@ nsEventStatus ScrollBarView :: HandleEvent(nsGUIEvent *aEvent, PRUint32 aEventFl case NS_SCROLLBAR_LINE_NEXT: case NS_SCROLLBAR_LINE_PREV: NS_ASSERTION((nsnull != mScrollingView), "HandleEvent() called after the ScrollingView has been destroyed."); - if (nsnull != mScrollingView) { + if (nsnull != mScrollingView) mScrollingView->HandleScrollEvent(aEvent, aEventFlags); - } retval = nsEventStatus_eConsumeNoDefault; break; @@ -603,48 +602,44 @@ PRBool nsScrollingView :: Paint(nsIRenderingContext& rc, const nsRect& rect, void nsScrollingView :: HandleScrollEvent(nsGUIEvent *aEvent, PRUint32 aEventFlags) { - static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID); - - // Get the view that owns the widget - nsIView* scview = nsView::GetViewFor(aEvent->widget); - + nsIView *scview = nsView::GetViewFor(aEvent->widget); nsIPresContext *px = mViewManager->GetPresContext(); float scale = px->GetTwipsToPixels(); nscoord dx = 0, dy = 0; + nsRect bounds; + + GetBounds(bounds); if ((nsnull != mVScrollBarView) && (scview == mVScrollBarView)) { - nscoord oy; - - oy = mOffsetY; + nscoord oy = mOffsetY; + nscoord newpos; //now, this horrible thing makes sure that as we scroll //the document a pixel at a time, we keep the logical position of //our scroll bar at the top edge of the same pixel that //is displayed. - mOffsetY = NSIntPixelsToTwips(NSTwipsToIntPixels(((nsScrollbarEvent *)aEvent)->position, scale), px->GetPixelsToTwips()); + newpos = ((nsScrollbarEvent *)aEvent)->position; + + if ((newpos + bounds.height) > mSizeY) + newpos = mSizeY - bounds.height; + + mOffsetY = NSIntPixelsToTwips(NSTwipsToIntPixels(newpos, scale), px->GetPixelsToTwips()); dy = NSTwipsToIntPixels((oy - mOffsetY), scale); if (dy != 0) { - nsRect clip; nscoord sx, sy; mVScrollBarView->GetDimensions(&sx, &sy); - clip.x = 0; - clip.y = 0; - clip.width = NSTwipsToIntPixels((mBounds.width - sx), scale); - if ((nsnull != mHScrollBarView) && (mHScrollBarView->GetVisibility() == nsViewVisibility_kShow)) mHScrollBarView->GetDimensions(&sx, &sy); else sy = 0; - clip.height = NSTwipsToIntPixels((mBounds.height - sy), scale); - mViewManager->ClearDirtyRegion(); nsIWidget *thiswin = GetWidget(); @@ -664,10 +659,7 @@ void nsScrollingView :: HandleScrollEvent(nsGUIEvent *aEvent, PRUint32 aEventFla if (dy != 0) { -// AdjustChildWidgets(this, this, 0, 0, px->GetTwipsToPixels()); - if (nsnull != mWindow) -// mWindow->Scroll(0, dy, &clip); mWindow->Scroll(0, dy, nsnull); else mViewManager->UpdateView(this, nsnull, 0); @@ -682,38 +674,34 @@ void nsScrollingView :: HandleScrollEvent(nsGUIEvent *aEvent, PRUint32 aEventFla } else if ((nsnull != mHScrollBarView) && (scview == mHScrollBarView)) { - nscoord ox; - - ox = mOffsetX; + nscoord ox = mOffsetX; + nscoord newpos; //now, this horrible thing makes sure that as we scroll //the document a pixel at a time, we keep the logical position of //our scroll bar at the top edge of the same pixel that //is displayed. - mOffsetX = NSIntPixelsToTwips(NSTwipsToIntPixels(((nsScrollbarEvent *)aEvent)->position, scale), px->GetPixelsToTwips()); + newpos = ((nsScrollbarEvent *)aEvent)->position; + + if ((newpos + bounds.width) > mSizeX) + newpos = mSizeX - bounds.width; + + mOffsetX = NSIntPixelsToTwips(NSTwipsToIntPixels(newpos, scale), px->GetPixelsToTwips()); dx = NSTwipsToIntPixels((ox - mOffsetX), scale); if (dx != 0) { - nsRect clip; nscoord sx, sy; - clip.x = 0; - clip.y = 0; - if ((nsnull != mVScrollBarView) && (mVScrollBarView->GetVisibility() == nsViewVisibility_kShow)) mVScrollBarView->GetDimensions(&sx, &sy); else sx = 0; - clip.width = NSTwipsToIntPixels((mBounds.width - sx), scale); - mHScrollBarView->GetDimensions(&sx, &sy); - clip.height = NSTwipsToIntPixels((mBounds.height - sy), scale); - mViewManager->ClearDirtyRegion(); nsIWidget *thiswin = GetWidget(); @@ -733,10 +721,7 @@ void nsScrollingView :: HandleScrollEvent(nsGUIEvent *aEvent, PRUint32 aEventFla if (dx != 0) { -// AdjustChildWidgets(this, this, 0, 0, px->GetTwipsToPixels()); - if (nsnull != mWindow) -// mWindow->Scroll(dx, 0, &clip); mWindow->Scroll(dx, 0, nsnull); else mViewManager->UpdateView(this, nsnull, 0); @@ -753,23 +738,24 @@ void nsScrollingView :: HandleScrollEvent(nsGUIEvent *aEvent, PRUint32 aEventFla NS_RELEASE(px); } - void nsScrollingView :: Notify(nsITimer * aTimer) { nscoord xoff, yoff; nsIView *view = GetScrolledView(); // First do the scrolling of the view + view->GetScrollOffset(&xoff, &yoff); - nscoord newPos = yoff+mScrollingDelta; - if (newPos < 0) { + nscoord newPos = yoff + mScrollingDelta; + + if (newPos < 0) newPos = 0; - } + ScrollTo(0, newPos, 0); - // Now fake a mouse event so the frames can process the selection event + nsRect rect; nsGUIEvent event; nsEventStatus retval; @@ -779,35 +765,37 @@ void nsScrollingView :: Notify(nsITimer * aTimer) nsIPresContext *cx = mViewManager->GetPresContext(); GetBounds(rect); + event.point.x = rect.x; - event.point.y = mScrollingDelta > 0 ?rect.height - rect.y - 1 : 135; + event.point.y = (mScrollingDelta > 0) ? (rect.height - rect.y - 1) : 135; //printf("timer %d %d\n", event.point.x, event.point.y); mFrame->HandleEvent(*cx, &event, retval); NS_RELEASE(cx); - NS_RELEASE(mScrollingTimer); - NS_NewTimer(&mScrollingTimer); - - mScrollingTimer->Init(this, 25); + if (NS_OK == NS_NewTimer(&mScrollingTimer)) + mScrollingTimer->Init(this, 25); } nsEventStatus nsScrollingView :: HandleEvent(nsGUIEvent *aEvent, PRUint32 aEventFlags) { - switch (aEvent->message) { + switch (aEvent->message) + { case NS_MOUSE_LEFT_BUTTON_DOWN: case NS_MOUSE_MIDDLE_BUTTON_DOWN: case NS_MOUSE_RIGHT_BUTTON_DOWN: { nsIWidget *win = GetWidget(); + if (nsnull != win) { win->SetFocus(); NS_RELEASE(win); } + break; } @@ -826,17 +814,23 @@ nsEventStatus nsScrollingView :: HandleEvent(nsGUIEvent *aEvent, PRUint32 aEvent //printf("%d %d %d\n", trect.y, trect.height, yoff); //printf("mouse %d %d \n", aEvent->point.x, aEvent->point.y); - if (!trect.Contains(lx, ly)) { - if (mScrollingTimer == nsnull) { - if (nsnull != mFrame) { - if (ly < 0 || ly > trect.y) { + if (!trect.Contains(lx, ly)) + { + if (mScrollingTimer == nsnull) + { + if (nsnull != mFrame) + { + if (ly < 0 || ly > trect.y) + { mScrollingDelta = ly < 0 ? -100 : 100; NS_NewTimer(&mScrollingTimer); mScrollingTimer->Init(this, 25); } } } - } else if (mScrollingTimer != nsnull) { + } + else if (mScrollingTimer != nsnull) + { mScrollingTimer->Cancel(); NS_RELEASE(mScrollingTimer); } @@ -847,7 +841,8 @@ nsEventStatus nsScrollingView :: HandleEvent(nsGUIEvent *aEvent, PRUint32 aEvent case NS_MOUSE_MIDDLE_BUTTON_UP: case NS_MOUSE_RIGHT_BUTTON_UP: { - if (mScrollingTimer != nsnull) { + if (mScrollingTimer != nsnull) + { mScrollingTimer->Cancel(); NS_RELEASE(mScrollingTimer); mScrollingTimer = nsnull; @@ -861,8 +856,10 @@ nsEventStatus nsScrollingView :: HandleEvent(nsGUIEvent *aEvent, PRUint32 aEvent lx = aEvent->point.x - trect.x; ly = aEvent->point.y - trect.y; - if (!trect.Contains(lx, ly)) { + if (!trect.Contains(lx, ly)) + { nsEventStatus retval; + if (nsnull != mFrame) { nsIPresContext *cx = mViewManager->GetPresContext(); @@ -887,6 +884,7 @@ nsEventStatus nsScrollingView :: HandleEvent(nsGUIEvent *aEvent, PRUint32 aEvent default: break; } + return nsView::HandleEvent(aEvent, aEventFlags); } @@ -1050,8 +1048,8 @@ void nsScrollingView :: ComputeContainerSize() NS_IF_RELEASE(scrollv); - if ((dx != 0) || (dy != 0)) - AdjustChildWidgets(this, this, 0, 0, px->GetTwipsToPixels()); +// if ((dx != 0) || (dy != 0)) +// AdjustChildWidgets(this, this, 0, 0, px->GetTwipsToPixels()); NS_RELEASE(px); } @@ -1172,13 +1170,21 @@ nsScrollingView :: ScrollTo(nscoord aX, nscoord aY, PRUint32 aUpdateFlags) } // Move the scrollbar's thumb + + PRUint32 oldpos = mOffsetY; + nscoord dy; + PRUint32 newpos = NSIntPixelsToTwips(NSTwipsToIntPixels(aY, t2p), p2t); scrollv->SetPosition(newpos); + dy = oldpos - newpos; + // Update offsets SetVisibleOffset(aX, aY); + AdjustChildWidgets(this, this, 0, 0, t2p); + // Damage the updated area r.x = 0; r.y = aY; diff --git a/view/src/nsView.cpp b/view/src/nsView.cpp index f5bfb003bcf0..34e668ea511f 100644 --- a/view/src/nsView.cpp +++ b/view/src/nsView.cpp @@ -705,8 +705,8 @@ void nsView :: SetPosition(nscoord x, nscoord y) pwidget = GetOffsetFromWidget(&parx, &pary); NS_IF_RELEASE(pwidget); - mWindow->Move(NSTwipsToIntPixels((x + parx + offx), scale), - NSTwipsToIntPixels((y + pary + offy), scale)); + mWindow->Move(NSTwipsToIntPixels((x + parx - offx), scale), + NSTwipsToIntPixels((y + pary - offy), scale)); NS_RELEASE(px); }