--- a/widget/src/windows/nsWindow.cpp
+++ b/widget/src/windows/nsWindow.cpp
@@ -190,16 +190,19 @@
// Windowless plugin support
#include "nsplugindefs.h"
#include "nsWindowDefs.h"
// For scroll wheel calculations
#include "nsITimer.h"
+#ifdef WINCE_WINDOWS_MOBILE
+#include "nsGfxCIID.h"
+#endif
/**************************************************************
*
* nsScrollPrefObserver Class for scroll acceleration prefs
*
**************************************************************/
class nsScrollPrefObserver : public nsIObserver
@@ -400,16 +403,19 @@ PRUint32 gLastInputEventTime
// Global user preference for disabling native theme. Used
// in NativeWindowTheme.
PRBool gDisableNativeTheme = PR_FALSE;
// Global used in Show window enumerations.
static PRBool gWindowsVisible = PR_FALSE;
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
+#ifdef WINCE_WINDOWS_MOBILE
+static NS_DEFINE_CID(kRegionCID, NS_REGION_CID);
+#endif
// Global scroll pref observer for scroll acceleration prefs
static nsScrollPrefObserver* gScrollPrefObserver = nsnull;
/**************************************************************
**************************************************************
**
** BLOCK: nsIWidget impl.
@@ -468,16 +474,21 @@ nsWindow::nsWindow() : nsBaseWidget()
#endif
mBackground = ::GetSysColor(COLOR_BTNFACE);
mBrush = ::CreateSolidBrush(NSRGB_2_COLOREF(mBackground));
mForeground = ::GetSysColor(COLOR_WINDOWTEXT);
// To be used for scroll acceleration
mScrollSeriesCounter = 0;
+#ifdef WINCE_WINDOWS_MOBILE
+ mInvalidatedRegion = do_CreateInstance(kRegionCID);
+ mInvalidatedRegion->Init();
+#endif
+
// Global initialization
if (!sInstanceCount) {
#if !defined(WINCE)
gKbdLayout.LoadLayout(::GetKeyboardLayout(0));
#endif
// Init IME handler
nsIMM32Handler::Initialize();
@@ -2061,30 +2072,42 @@ NS_IMETHODIMP nsWindow::HideWindowChrome
// Validate a visible area of a widget.
NS_METHOD nsWindow::Validate()
{
if (mWnd)
VERIFY(::ValidateRect(mWnd, NULL));
return NS_OK;
}
+#ifdef WINCE_WINDOWS_MOBILE
+static inline void AddRECTToRegion(const RECT& aRect, nsIRegion* aRegion)
+{
+ aRegion->Union(aRect.left, aRect.top, aRect.right - aRect.left, aRect.bottom - aRect.top);
+}
+#endif
+
// Invalidate this component visible area
NS_METHOD nsWindow::Invalidate(PRBool aIsSynchronous)
{
if (mWnd)
{
#ifdef WIDGET_DEBUG_OUTPUT
debug_DumpInvalidate(stdout,
this,
nsnull,
aIsSynchronous,
nsCAutoString("noname"),
(PRInt32) mWnd);
#endif // WIDGET_DEBUG_OUTPUT
-
+#ifdef WINCE_WINDOWS_MOBILE
+ // We need to keep track of our own invalidated region for Windows CE
+ RECT r;
+ GetClientRect(mWnd, &r);
+ AddRECTToRegion(r, mInvalidatedRegion);
+#endif
VERIFY(::InvalidateRect(mWnd, NULL, FALSE));
if (aIsSynchronous) {
VERIFY(::UpdateWindow(mWnd));
}
}
return NS_OK;
}
@@ -2105,16 +2128,20 @@ NS_METHOD nsWindow::Invalidate(const nsI
RECT rect;
rect.left = aRect.x;
rect.top = aRect.y;
rect.right = aRect.x + aRect.width;
rect.bottom = aRect.y + aRect.height;
+#ifdef WINCE_WINDOWS_MOBILE
+ // We need to keep track of our own invalidated region for Windows CE
+ AddRECTToRegion(rect, mInvalidatedRegion);
+#endif
VERIFY(::InvalidateRect(mWnd, &rect, FALSE));
if (aIsSynchronous) {
VERIFY(::UpdateWindow(mWnd));
}
}
return NS_OK;
}
--- a/widget/src/windows/nsWindow.h
+++ b/widget/src/windows/nsWindow.h
@@ -310,16 +310,17 @@ protected:
PRBool OnGesture(WPARAM wParam, LPARAM lParam);
PRBool OnHotKey(WPARAM wParam, LPARAM lParam);
BOOL OnInputLangChange(HKL aHKL);
void OnSettingsChange(WPARAM wParam, LPARAM lParam);
virtual PRBool OnPaint(HDC aDC = nsnull);
void OnWindowPosChanged(WINDOWPOS *wp, PRBool& aResult);
#if defined(CAIRO_HAS_DDRAW_SURFACE)
PRBool OnPaintImageDDraw16();
+ HRESULT PaintRectImageDDraw16(RECT aRect, nsPaintEvent* aEvent);
#endif // defined(CAIRO_HAS_DDRAW_SURFACE)
PRBool OnMouseWheel(UINT msg, WPARAM wParam, LPARAM lParam,
PRBool& result, PRBool& getWheelInfo,
LRESULT *aRetValue);
static void OnMouseWheelTimeout(nsITimer* aTimer, void* aClosure);
void UpdateMouseWheelSeriesCounter();
int ComputeMouseWheelDelta(int currentVDelta,
int iDeltaPerLine,
@@ -376,16 +377,18 @@ protected:
* Misc.
*/
UINT MapFromNativeToDOM(UINT aNativeKeyCode);
void StopFlashing();
static PRBool IsTopLevelMouseExit(HWND aWnd);
static void SetupKeyModifiersSequence(nsTArray<KeyPair>* aArray, PRUint32 aModifiers);
nsresult SetWindowClipRegion(const nsTArray<nsIntRect>& aRects,
PRBool aIntersectWithExisting);
+ nsCOMPtr<nsIRegion> GetRegionToPaint(PRBool aForceFullRepaint,
+ PAINTSTRUCT ps, HDC aDC);
#ifdef ACCESSIBILITY
static STDMETHODIMP_(LRESULT) LresultFromObject(REFIID riid, WPARAM wParam, LPUNKNOWN pAcc);
#endif // ACCESSIBILITY
protected:
nsIntSize mLastSize;
nsIntPoint mLastPoint;
@@ -409,17 +412,19 @@ protected:
DWORD_PTR mOldExStyle;
HIMC mOldIMC;
PRUint32 mIMEEnabled;
nsNativeDragTarget* mNativeDragTarget;
HKL mLastKeyboardLayout;
nsPopupType mPopupType;
int mScrollSeriesCounter;
PRPackedBool mDisplayPanFeedback;
-
+#ifdef WINCE_WINDOWS_MOBILE
+ nsCOMPtr<nsIRegion> mInvalidatedRegion;
+#endif
static PRUint32 sInstanceCount;
static TriStateBool sCanQuit;
static nsWindow* sCurrentWindow;
static BOOL sIsRegistered;
static BOOL sIsPopupClassRegistered;
static BOOL sIsOleInitialized;
static HCURSOR sHCursor;
static imgIContainer* sCursorImgContainer;
--- a/widget/src/windows/nsWindowGfx.cpp
+++ b/widget/src/windows/nsWindowGfx.cpp
@@ -247,16 +247,69 @@ void nsWindowGfx::OnSettingsChangeGfx(WP
void nsWindow::SetUpForPaint(HDC aHDC)
{
::SetBkColor (aHDC, NSRGB_2_COLOREF(mBackground));
::SetTextColor(aHDC, NSRGB_2_COLOREF(mForeground));
::SetBkMode (aHDC, TRANSPARENT);
}
+// GetRegionToPaint returns the invalidated region that needs to be painted
+// it's abstracted out because Windows XP/Vista/7 handles this for us, but
+// we need to keep track of it our selves for Windows CE and Windows Mobile
+
+nsCOMPtr<nsIRegion> nsWindow::GetRegionToPaint(PRBool aForceFullRepaint,
+ PAINTSTRUCT ps, HDC aDC)
+{
+ HRGN paintRgn = NULL;
+ nsCOMPtr<nsIRegion> paintRgnWin;
+ if (aForceFullRepaint) {
+ RECT paintRect;
+ ::GetClientRect(mWnd, &paintRect);
+ paintRgn = ::CreateRectRgn(paintRect.left, paintRect.top,
+ paintRect.right, paintRect.bottom);
+ if (paintRgn) {
+ paintRgnWin = nsWindowGfx::ConvertHRGNToRegion(paintRgn);
+ ::DeleteObject(paintRgn);
+ return paintRgnWin;
+ }
+ }
+#ifndef WINCE
+ paintRgn = ::CreateRectRgn(0, 0, 0, 0);
+ if (paintRgn != NULL) {
+ int result = GetRandomRgn(aDC, paintRgn, SYSRGN);
+ if (result == 1) {
+ POINT pt = {0,0};
+ ::MapWindowPoints(NULL, mWnd, &pt, 1);
+ ::OffsetRgn(paintRgn, pt.x, pt.y);
+ }
+ paintRgnWin = nsWindowGfx::ConvertHRGNToRegion(paintRgn);
+ ::DeleteObject(paintRgn);
+ }
+#else
+# ifdef WINCE_WINDOWS_MOBILE
+ if (!mInvalidatedRegion->IsEmpty()) {
+ // XXX: we may not recieve invalidates when an OS dialog obsures out window
+ // and dismisses, so mInvalidatedRegion may not be complete
+ paintRgnWin = mInvalidatedRegion.forget();
+ mInvalidatedRegion = do_CreateInstance(kRegionCID);
+ mInvalidatedRegion->Init();
+ return paintRgnWin;
+ }
+# endif
+ paintRgn = ::CreateRectRgn(ps.rcPaint.left, ps.rcPaint.top,
+ ps.rcPaint.right, ps.rcPaint.bottom);
+ if (paintRgn) {
+ paintRgnWin = nsWindowGfx::ConvertHRGNToRegion(paintRgn);
+ ::DeleteObject(paintRgn);
+ }
+#endif
+ return paintRgnWin;
+}
+
PRBool nsWindow::OnPaint(HDC aDC)
{
#ifdef CAIRO_HAS_DDRAW_SURFACE
if (IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_DDRAW16)) {
return OnPaintImageDDraw16();
}
#endif
@@ -291,50 +344,23 @@ PRBool nsWindow::OnPaint(HDC aDC)
debugPaintFlashRegion = ::CreateRectRgn(0, 0, 0, 0);
::GetUpdateRgn(mWnd, debugPaintFlashRegion, TRUE);
debugPaintFlashDC = ::GetDC(mWnd);
}
#endif // WIDGET_DEBUG_OUTPUT
HDC hDC = aDC ? aDC : (::BeginPaint(mWnd, &ps));
mPaintDC = hDC;
- HRGN paintRgn = NULL;
#ifdef MOZ_XUL
- if (aDC || (eTransparencyTransparent == mTransparencyMode)) {
+ PRBool forceRepaint = aDC || (eTransparencyTransparent == mTransparencyMode);
#else
- if (aDC) {
+ PRBool forceRepaint = NULL != aDC;
#endif
-
- RECT paintRect;
- ::GetClientRect(mWnd, &paintRect);
- paintRgn = ::CreateRectRgn(paintRect.left, paintRect.top, paintRect.right, paintRect.bottom);
- }
- else {
-#ifndef WINCE
- paintRgn = ::CreateRectRgn(0, 0, 0, 0);
- if (paintRgn != NULL) {
- int result = GetRandomRgn(hDC, paintRgn, SYSRGN);
- if (result == 1) {
- POINT pt = {0,0};
- ::MapWindowPoints(NULL, mWnd, &pt, 1);
- ::OffsetRgn(paintRgn, pt.x, pt.y);
- }
- }
-#else
- paintRgn = ::CreateRectRgn(ps.rcPaint.left, ps.rcPaint.top,
- ps.rcPaint.right, ps.rcPaint.bottom);
-#endif
- }
-
- nsCOMPtr<nsIRegion> paintRgnWin;
- if (paintRgn) {
- paintRgnWin = nsWindowGfx::ConvertHRGNToRegion(paintRgn);
- ::DeleteObject(paintRgn);
- }
+ nsCOMPtr<nsIRegion> paintRgnWin = GetRegionToPaint(forceRepaint, ps, hDC);
if (paintRgnWin &&
!paintRgnWin->IsEmpty() &&
mEventCallback)
{
// generate the event and call the event callback
nsPaintEvent event(PR_TRUE, NS_PAINT, this);
@@ -837,48 +863,150 @@ HBITMAP nsWindowGfx::DataToBitmap(PRUint
#else
return nsnull;
#endif
}
// Windows Mobile Special image/direct draw painting fun
#if defined(CAIRO_HAS_DDRAW_SURFACE)
+
+HRESULT nsWindow::PaintRectImageDDraw16(RECT rcPaint, nsPaintEvent* event){
+ HRESULT hr;
+ gfxIntSize surfaceSize;
+ nsRefPtr<gfxImageSurface> targetSurfaceImage;
+ nsRefPtr<gfxContext> thebesContext;
+ nsCOMPtr<nsIRenderingContext> rc;
+ nsEventStatus eventStatus = nsEventStatus_eIgnore;
+ RECT renderArea;
+
+ surfaceSize = gfxIntSize(rcPaint.right - rcPaint.left,
+ rcPaint.bottom - rcPaint.top);
+
+ targetSurfaceImage = new gfxImageSurface(sSharedSurfaceData.get(),
+ surfaceSize,
+ surfaceSize.width * 4,
+ gfxASurface::ImageFormatRGB24);
+
+ if (!targetSurfaceImage || targetSurfaceImage->CairoStatus()) {
+ NS_ERROR("Invalid targetSurfaceImage!");
+ return E_FAIL;
+ }
+
+ targetSurfaceImage->SetDeviceOffset(gfxPoint(-rcPaint.left, -rcPaint.top));
+
+ thebesContext = new gfxContext(targetSurfaceImage);
+ thebesContext->SetFlag(gfxContext::FLAG_DESTINED_FOR_SCREEN);
+ thebesContext->SetFlag(gfxContext::FLAG_SIMPLIFY_OPERATORS);
+
+ nsresult rv = mContext->CreateRenderingContextInstance (*getter_AddRefs(rc));
+ if (NS_FAILED(rv)) {
+ NS_WARNING("CreateRenderingContextInstance failed");
+ return E_FAIL;
+ }
+
+ rv = rc->Init(mContext, thebesContext);
+ if (NS_FAILED(rv)) {
+ NS_WARNING("RC::Init failed");
+ return E_FAIL;
+ }
+
+ event->renderingContext = rc;
+ nsresult result = DispatchWindowEvent(event, eventStatus);
+ event->renderingContext = nsnull;
+
+ if (!result) {
+ printf("result is null from dispatch\n");
+ return E_FAIL;
+ }
+
+
+ hr = glpDDSecondary->Lock(0, &gDDSDSecondary, DDLOCK_WAITNOTBUSY | DDLOCK_DISCARD, 0); /* should we wait here? */
+ if (FAILED(hr)) {
+#ifdef DEBUG
+ DDError("Failed to lock renderer", hr);
+#endif
+ return E_FAIL;
+ }
+
+ // Convert RGB24 -> RGB565
+ pixman_image_t *srcPixmanImage = pixman_image_create_bits(PIXMAN_x8r8g8b8,
+ surfaceSize.width,
+ surfaceSize.height,
+ (uint32_t*) sSharedSurfaceData.get(),
+ surfaceSize.width * 4);
+
+ pixman_image_t *dstPixmanImage = pixman_image_create_bits(PIXMAN_r5g6b5,
+ surfaceSize.width,
+ surfaceSize.height,
+ (uint32_t*) gDDSDSecondary.lpSurface,
+ gDDSDSecondary.dwWidth * 2);
+
+ pixman_image_composite(PIXMAN_OP_SRC,
+ srcPixmanImage,
+ NULL,
+ dstPixmanImage,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ surfaceSize.width,
+ surfaceSize.height);
+
+ pixman_image_unref(dstPixmanImage);
+ pixman_image_unref(srcPixmanImage);
+
+ hr = glpDDSecondary->Unlock(0);
+ if (FAILED(hr)) {
+#ifdef DEBUG
+ DDError("Failed to unlock renderer", hr);
+#endif
+ return E_FAIL;
+ }
+
+ hr = glpDDClipper->SetHWnd(0, mWnd);
+ if (FAILED(hr)) {
+#ifdef DEBUG
+ DDError("SetHWnd", hr);
+#endif
+ return E_FAIL;
+ }
+
+ // translate the paint region to screen coordinates
+ renderArea = rcPaint;
+ MapWindowPoints(mWnd, 0, (LPPOINT)&renderArea, 2);
+
+ // set the rect to be 0,0 based
+ rcPaint.right = surfaceSize.width;
+ rcPaint.bottom = surfaceSize.height;
+ rcPaint.left = rcPaint.top = 0;
+
+ return glpDDPrimary->Blt(&renderArea,
+ glpDDSecondary,
+ &rcPaint,
+ DDBLT_WAITNOTBUSY, /* should we really wait here? */
+ NULL);
+
+}
+
+
PRBool nsWindow::OnPaintImageDDraw16()
{
PRBool result = PR_TRUE;
PAINTSTRUCT ps;
- gfxIntSize surfaceSize;
nsPaintEvent event(PR_TRUE, NS_PAINT, this);
- RECT renderArea;
-
- nsEventStatus eventStatus = nsEventStatus_eIgnore;
- nsCOMPtr<nsIRenderingContext> rc;
- nsRefPtr<gfxImageSurface> targetSurfaceImage;
- nsRefPtr<gfxContext> thebesContext;
-
mPainting = PR_TRUE;
HDC hDC = ::BeginPaint(mWnd, &ps);
mPaintDC = hDC;
-
- HRGN paintRgn = ::CreateRectRgn(ps.rcPaint.left, ps.rcPaint.top,
- ps.rcPaint.right, ps.rcPaint.bottom);
-
- nsCOMPtr<nsIRegion> paintRgnWin;
- if (paintRgn) {
- paintRgnWin = nsWindowGfx::ConvertHRGNToRegion(paintRgn);
- ::DeleteObject(paintRgn);
- }
+ nsCOMPtr<nsIRegion> paintRgnWin = GetRegionToPaint(PR_FALSE, ps, hDC);
if (!paintRgnWin || paintRgnWin->IsEmpty() || !mEventCallback) {
printf("nothing to paint\n");
goto cleanup;
}
-
InitEvent(event);
event.region = paintRgnWin;
event.rect = nsnull;
if (!glpDD) {
if (!nsWindowGfx::InitDDraw()) {
NS_WARNING("DirectDraw init failed. Giving up.");
@@ -914,127 +1042,25 @@ PRBool nsWindow::OnPaintImageDDraw16()
HRESULT hr = glpDD->CreateSurface(&gDDSDSecondary, &glpDDSecondary, 0);
if (FAILED(hr)) {
#ifdef DEBUG
DDError("CreateSurface renderer", hr);
#endif
goto cleanup;
}
}
-
- surfaceSize = gfxIntSize(ps.rcPaint.right - ps.rcPaint.left,
- ps.rcPaint.bottom - ps.rcPaint.top);
-
- targetSurfaceImage = new gfxImageSurface(sSharedSurfaceData.get(),
- surfaceSize,
- surfaceSize.width * 4,
- gfxASurface::ImageFormatRGB24);
-
- if (!targetSurfaceImage || targetSurfaceImage->CairoStatus()) {
- NS_ERROR("Invalid targetSurfaceImage!");
- goto cleanup;
- }
-
- targetSurfaceImage->SetDeviceOffset(gfxPoint(-ps.rcPaint.left, -ps.rcPaint.top));
-
- thebesContext = new gfxContext(targetSurfaceImage);
- thebesContext->SetFlag(gfxContext::FLAG_DESTINED_FOR_SCREEN);
- thebesContext->SetFlag(gfxContext::FLAG_SIMPLIFY_OPERATORS);
-
- nsresult rv = mContext->CreateRenderingContextInstance (*getter_AddRefs(rc));
- if (NS_FAILED(rv)) {
- NS_WARNING("CreateRenderingContextInstance failed");
- goto cleanup;
- }
-
- rv = rc->Init(mContext, thebesContext);
- if (NS_FAILED(rv)) {
- NS_WARNING("RC::Init failed");
- goto cleanup;
- }
-
- event.renderingContext = rc;
- result = DispatchWindowEvent(&event, eventStatus);
- event.renderingContext = nsnull;
-
- if (!result) {
- printf("result is null from dispatch\n");
- goto cleanup;
- }
-
- HRESULT hr;
- hr = glpDDSecondary->Lock(0, &gDDSDSecondary, DDLOCK_WAITNOTBUSY | DDLOCK_DISCARD, 0); /* should we wait here? */
- if (FAILED(hr)) {
-#ifdef DEBUG
- DDError("Failed to lock renderer", hr);
-#endif
- goto cleanup;
- }
-
- // Convert RGB24 -> RGB565
- pixman_image_t *srcPixmanImage = pixman_image_create_bits(PIXMAN_x8r8g8b8,
- surfaceSize.width,
- surfaceSize.height,
- (uint32_t*) sSharedSurfaceData.get(),
- surfaceSize.width * 4);
-
- pixman_image_t *dstPixmanImage = pixman_image_create_bits(PIXMAN_r5g6b5,
- surfaceSize.width,
- surfaceSize.height,
- (uint32_t*) gDDSDSecondary.lpSurface,
- gDDSDSecondary.dwWidth * 2);
-
- pixman_image_composite(PIXMAN_OP_SRC,
- srcPixmanImage,
- NULL,
- dstPixmanImage,
- 0, 0,
- 0, 0,
- 0, 0,
- surfaceSize.width,
- surfaceSize.height);
-
- pixman_image_unref(dstPixmanImage);
- pixman_image_unref(srcPixmanImage);
-
- hr = glpDDSecondary->Unlock(0);
- if (FAILED(hr)) {
-#ifdef DEBUG
- DDError("Failed to unlock renderer", hr);
-#endif
- goto cleanup;
- }
-
- hr = glpDDClipper->SetHWnd(0, mWnd);
- if (FAILED(hr)) {
-#ifdef DEBUG
- DDError("SetHWnd", hr);
-#endif
- goto cleanup;
- }
-
- // translate the paint region to screen coordinates
- renderArea = ps.rcPaint;
- MapWindowPoints(mWnd, 0, (LPPOINT)&renderArea, 2);
-
- // set the rect to be 0,0 based
- ps.rcPaint.right = surfaceSize.width;
- ps.rcPaint.bottom = surfaceSize.height;
- ps.rcPaint.left = ps.rcPaint.top = 0;
-
- hr = glpDDPrimary->Blt(&renderArea,
- glpDDSecondary,
- &ps.rcPaint,
- DDBLT_WAITNOTBUSY, /* should we really wait here? */
- NULL);
- if (FAILED(hr)) {
-#ifdef DEBUG
- DDError("Blt", hr);
-#endif
- goto cleanup;
+ nsRegionRectSet *rects = nsnull;
+ RECT r;
+ paintRgnWin->GetRects(&rects);
+ for (int i = 0; i < rects->mNumRects; i++) {
+ r.left = rects->mRects[i].x;
+ r.top = rects->mRects[i].y;
+ r.right = rects->mRects[i].width + rects->mRects[i].x;
+ r.bottom = rects->mRects[i].height + rects->mRects[i].y;
+ PaintRectImageDDraw16(r, &event);
}
cleanup:
::EndPaint(mWnd, &ps);
mPaintDC = nsnull;
mPainting = PR_FALSE;
return result;