зеркало из https://github.com/mozilla/pjs.git
Take 2 for bug 252067: Add support for translucent windows for Win32 (Windows 2000 and later)
Patch by Dainis Jonitis r=ere sr=roc
This commit is contained in:
Родитель
45c94413a9
Коммит
a323813f95
|
@ -387,6 +387,8 @@ NS_IMETHODIMP nsBlender::GetAlphas(const nsRect& aRect, nsIDrawingSurface* aBlac
|
||||||
} else {
|
} else {
|
||||||
result = NS_ERROR_FAILURE;
|
result = NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
result = NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
whiteSurface->Unlock();
|
whiteSurface->Unlock();
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
* Roy Yokoyama <yokoyama@netscape.com>
|
* Roy Yokoyama <yokoyama@netscape.com>
|
||||||
* Makoto Kato <m_kato@ga2.so-net.ne.jp>
|
* Makoto Kato <m_kato@ga2.so-net.ne.jp>
|
||||||
* Masayuki Nakano <masayuki@d-toybox.com>
|
* Masayuki Nakano <masayuki@d-toybox.com>
|
||||||
|
* Dainis Jonitis <Dainis_Jonitis@swh-t.lv>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
@ -66,6 +67,7 @@
|
||||||
#include "nsIDeviceContext.h"
|
#include "nsIDeviceContext.h"
|
||||||
#include "nsIScreenManager.h"
|
#include "nsIScreenManager.h"
|
||||||
#include "nsRect.h"
|
#include "nsRect.h"
|
||||||
|
#include "nsColor.h"
|
||||||
#include "nsTransform2D.h"
|
#include "nsTransform2D.h"
|
||||||
#include "nsIEventQueue.h"
|
#include "nsIEventQueue.h"
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -132,6 +134,19 @@ static const char *kMozHeapDumpMessageString = "MOZ_HeapDump";
|
||||||
#define SPI_GETWHEELSCROLLLINES 104
|
#define SPI_GETWHEELSCROLLLINES 104
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef AC_SRC_ALPHA
|
||||||
|
#define AC_SRC_ALPHA 0x01
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WS_EX_LAYERED
|
||||||
|
#define WS_EX_LAYERED 0x00080000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ULW_ALPHA
|
||||||
|
#define ULW_ALPHA 0x00000002
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Pick some random timer ID. Is there a better way?
|
// Pick some random timer ID. Is there a better way?
|
||||||
#define NS_FLASH_TIMER_ID 0x011231984
|
#define NS_FLASH_TIMER_ID 0x011231984
|
||||||
|
|
||||||
|
@ -544,6 +559,20 @@ static PRBool LangIDToCP(WORD aLangID, UINT& oCP)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HWND GetTopLevelHWND(HWND aWnd)
|
||||||
|
{
|
||||||
|
HWND curWnd = aWnd;
|
||||||
|
HWND topWnd = NULL;
|
||||||
|
|
||||||
|
while (curWnd)
|
||||||
|
{
|
||||||
|
topWnd = curWnd;
|
||||||
|
curWnd = ::GetParent(curWnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return topWnd;
|
||||||
|
}
|
||||||
|
|
||||||
/* This object maintains a correlation between attention timers and the
|
/* This object maintains a correlation between attention timers and the
|
||||||
windows to which they belong. It's lighter than a hashtable (expected usage
|
windows to which they belong. It's lighter than a hashtable (expected usage
|
||||||
is really just one at a time) and allows nsWindow::GetNSWindowPtr
|
is really just one at a time) and allows nsWindow::GetNSWindowPtr
|
||||||
|
@ -760,6 +789,12 @@ nsWindow::nsWindow() : nsBaseWidget()
|
||||||
mFont = nsnull;
|
mFont = nsnull;
|
||||||
mIsVisible = PR_FALSE;
|
mIsVisible = PR_FALSE;
|
||||||
mHas3DBorder = PR_FALSE;
|
mHas3DBorder = PR_FALSE;
|
||||||
|
#ifdef MOZ_XUL
|
||||||
|
mIsTranslucent = PR_FALSE;
|
||||||
|
mMemoryBitmap = NULL;
|
||||||
|
mMemoryDC = NULL;
|
||||||
|
mAlphaMask = nsnull;
|
||||||
|
#endif
|
||||||
mWindowType = eWindowType_child;
|
mWindowType = eWindowType_child;
|
||||||
mBorderStyle = eBorderStyle_default;
|
mBorderStyle = eBorderStyle_default;
|
||||||
mBorderlessParent = 0;
|
mBorderlessParent = 0;
|
||||||
|
@ -1396,6 +1431,8 @@ nsresult nsWindow::StandardWindowCreate(nsIWidget *aParent,
|
||||||
nsnull : aParent;
|
nsnull : aParent;
|
||||||
|
|
||||||
mIsTopWidgetWindow = (nsnull == baseParent);
|
mIsTopWidgetWindow = (nsnull == baseParent);
|
||||||
|
mBounds.width = aRect.width;
|
||||||
|
mBounds.height = aRect.height;
|
||||||
|
|
||||||
BaseCreate(baseParent, aRect, aHandleEventFunction, aContext,
|
BaseCreate(baseParent, aRect, aHandleEventFunction, aContext,
|
||||||
aAppShell, aToolkit, aInitData);
|
aAppShell, aToolkit, aInitData);
|
||||||
|
@ -1639,6 +1676,19 @@ NS_METHOD nsWindow::Destroy()
|
||||||
if (icon)
|
if (icon)
|
||||||
::DestroyIcon(icon);
|
::DestroyIcon(icon);
|
||||||
|
|
||||||
|
#ifdef MOZ_XUL
|
||||||
|
if (mIsTranslucent)
|
||||||
|
{
|
||||||
|
::DeleteDC(mMemoryDC);
|
||||||
|
::DeleteObject(mMemoryBitmap);
|
||||||
|
delete [] mAlphaMask;
|
||||||
|
|
||||||
|
mMemoryDC = NULL;
|
||||||
|
mMemoryBitmap = NULL;
|
||||||
|
mAlphaMask = nsnull;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
VERIFY(::DestroyWindow(mWnd));
|
VERIFY(::DestroyWindow(mWnd));
|
||||||
|
|
||||||
mWnd = NULL;
|
mWnd = NULL;
|
||||||
|
@ -2053,6 +2103,12 @@ NS_METHOD nsWindow::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
|
||||||
{
|
{
|
||||||
NS_ASSERTION((aWidth >=0 ) , "Negative width passed to nsWindow::Resize");
|
NS_ASSERTION((aWidth >=0 ) , "Negative width passed to nsWindow::Resize");
|
||||||
NS_ASSERTION((aHeight >=0 ), "Negative height passed to nsWindow::Resize");
|
NS_ASSERTION((aHeight >=0 ), "Negative height passed to nsWindow::Resize");
|
||||||
|
|
||||||
|
#ifdef MOZ_XUL
|
||||||
|
if (mIsTranslucent)
|
||||||
|
ResizeTranslucentWindow(aWidth, aHeight);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Set cached value for lightweight and printing
|
// Set cached value for lightweight and printing
|
||||||
mBounds.width = aWidth;
|
mBounds.width = aWidth;
|
||||||
mBounds.height = aHeight;
|
mBounds.height = aHeight;
|
||||||
|
@ -2103,6 +2159,11 @@ NS_METHOD nsWindow::Resize(PRInt32 aX,
|
||||||
NS_ASSERTION((aWidth >=0 ), "Negative width passed to nsWindow::Resize");
|
NS_ASSERTION((aWidth >=0 ), "Negative width passed to nsWindow::Resize");
|
||||||
NS_ASSERTION((aHeight >=0 ), "Negative height passed to nsWindow::Resize");
|
NS_ASSERTION((aHeight >=0 ), "Negative height passed to nsWindow::Resize");
|
||||||
|
|
||||||
|
#ifdef MOZ_XUL
|
||||||
|
if (mIsTranslucent)
|
||||||
|
ResizeTranslucentWindow(aWidth, aHeight);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Set cached value for lightweight and printing
|
// Set cached value for lightweight and printing
|
||||||
mBounds.x = aX;
|
mBounds.x = aX;
|
||||||
mBounds.y = aY;
|
mBounds.y = aY;
|
||||||
|
@ -2528,7 +2589,7 @@ NS_IMETHODIMP nsWindow::HideWindowChrome(PRBool aShouldHide)
|
||||||
DWORD tempExStyle = nsToolkit::mGetWindowLong(hwnd, GWL_EXSTYLE);
|
DWORD tempExStyle = nsToolkit::mGetWindowLong(hwnd, GWL_EXSTYLE);
|
||||||
|
|
||||||
style = WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
|
style = WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
|
||||||
exStyle = 0;
|
exStyle = tempExStyle & WS_EX_LAYERED;
|
||||||
|
|
||||||
mOldStyle = tempStyle;
|
mOldStyle = tempStyle;
|
||||||
mOldExStyle = tempExStyle;
|
mOldExStyle = tempExStyle;
|
||||||
|
@ -2580,12 +2641,18 @@ NS_METHOD nsWindow::Invalidate(PRBool aIsSynchronous)
|
||||||
(PRInt32) mWnd);
|
(PRInt32) mWnd);
|
||||||
#endif // NS_DEBUG
|
#endif // NS_DEBUG
|
||||||
|
|
||||||
|
#ifdef MOZ_XUL
|
||||||
|
if (mIsTranslucent)
|
||||||
|
OnPaint(mMemoryDC);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
VERIFY(::InvalidateRect(mWnd, NULL, TRUE));
|
VERIFY(::InvalidateRect(mWnd, NULL, TRUE));
|
||||||
if (aIsSynchronous) {
|
if (aIsSynchronous) {
|
||||||
VERIFY(::UpdateWindow(mWnd));
|
VERIFY(::UpdateWindow(mWnd));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2596,15 +2663,8 @@ NS_METHOD nsWindow::Invalidate(PRBool aIsSynchronous)
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
NS_METHOD nsWindow::Invalidate(const nsRect & aRect, PRBool aIsSynchronous)
|
NS_METHOD nsWindow::Invalidate(const nsRect & aRect, PRBool aIsSynchronous)
|
||||||
{
|
{
|
||||||
RECT rect;
|
|
||||||
|
|
||||||
if (mWnd)
|
if (mWnd)
|
||||||
{
|
{
|
||||||
rect.left = aRect.x;
|
|
||||||
rect.top = aRect.y;
|
|
||||||
rect.right = aRect.x + aRect.width;
|
|
||||||
rect.bottom = aRect.y + aRect.height;
|
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef NS_DEBUG
|
||||||
debug_DumpInvalidate(stdout,
|
debug_DumpInvalidate(stdout,
|
||||||
this,
|
this,
|
||||||
|
@ -2614,11 +2674,25 @@ NS_METHOD nsWindow::Invalidate(const nsRect & aRect, PRBool aIsSynchronous)
|
||||||
(PRInt32) mWnd);
|
(PRInt32) mWnd);
|
||||||
#endif // NS_DEBUG
|
#endif // NS_DEBUG
|
||||||
|
|
||||||
|
#ifdef MOZ_XUL
|
||||||
|
if (mIsTranslucent)
|
||||||
|
OnPaint(mMemoryDC);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
RECT rect;
|
||||||
|
|
||||||
|
rect.left = aRect.x;
|
||||||
|
rect.top = aRect.y;
|
||||||
|
rect.right = aRect.x + aRect.width;
|
||||||
|
rect.bottom = aRect.y + aRect.height;
|
||||||
|
|
||||||
VERIFY(::InvalidateRect(mWnd, &rect, TRUE));
|
VERIFY(::InvalidateRect(mWnd, &rect, TRUE));
|
||||||
if (aIsSynchronous) {
|
if (aIsSynchronous) {
|
||||||
VERIFY(::UpdateWindow(mWnd));
|
VERIFY(::UpdateWindow(mWnd));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2628,6 +2702,12 @@ nsWindow::InvalidateRegion(const nsIRegion *aRegion, PRBool aIsSynchronous)
|
||||||
{
|
{
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
if (mWnd) {
|
if (mWnd) {
|
||||||
|
#ifdef MOZ_XUL
|
||||||
|
if (mIsTranslucent)
|
||||||
|
OnPaint(mMemoryDC);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
HRGN nativeRegion;
|
HRGN nativeRegion;
|
||||||
rv = aRegion->GetNativeRegion((void *&)nativeRegion);
|
rv = aRegion->GetNativeRegion((void *&)nativeRegion);
|
||||||
if (nativeRegion) {
|
if (nativeRegion) {
|
||||||
|
@ -2642,6 +2722,7 @@ nsWindow::InvalidateRegion(const nsIRegion *aRegion, PRBool aIsSynchronous)
|
||||||
rv = NS_ERROR_FAILURE;
|
rv = NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2652,11 +2733,23 @@ nsWindow::InvalidateRegion(const nsIRegion *aRegion, PRBool aIsSynchronous)
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
NS_IMETHODIMP nsWindow::Update()
|
NS_IMETHODIMP nsWindow::Update()
|
||||||
{
|
{
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
|
||||||
// updates can come through for windows no longer holding an mWnd during
|
// updates can come through for windows no longer holding an mWnd during
|
||||||
// deletes triggered by JavaScript in buttons with mouse feedback
|
// deletes triggered by JavaScript in buttons with mouse feedback
|
||||||
if (mWnd)
|
if (mWnd)
|
||||||
|
{
|
||||||
|
#ifdef MOZ_XUL
|
||||||
|
if (mIsTranslucent)
|
||||||
|
{
|
||||||
|
// rv = UpdateTranslucentWindow();
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
VERIFY(::UpdateWindow(mWnd));
|
VERIFY(::UpdateWindow(mWnd));
|
||||||
return NS_OK;
|
}
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
@ -2673,7 +2766,11 @@ void* nsWindow::GetNativeData(PRUint32 aDataType)
|
||||||
return (void*)mWnd;
|
return (void*)mWnd;
|
||||||
case NS_NATIVE_GRAPHIC:
|
case NS_NATIVE_GRAPHIC:
|
||||||
// XXX: This is sleezy!! Remember to Release the DC after using it!
|
// XXX: This is sleezy!! Remember to Release the DC after using it!
|
||||||
|
#ifdef MOZ_XUL
|
||||||
|
return (void*)(!mIsTranslucent) ? ::GetDC(mWnd) : mMemoryDC;
|
||||||
|
#else
|
||||||
return (void*)::GetDC(mWnd);
|
return (void*)::GetDC(mWnd);
|
||||||
|
#endif
|
||||||
case NS_NATIVE_COLORMAP:
|
case NS_NATIVE_COLORMAP:
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -2688,7 +2785,13 @@ void nsWindow::FreeNativeData(void * data, PRUint32 aDataType)
|
||||||
switch(aDataType)
|
switch(aDataType)
|
||||||
{
|
{
|
||||||
case NS_NATIVE_GRAPHIC:
|
case NS_NATIVE_GRAPHIC:
|
||||||
|
#ifdef MOZ_XUL
|
||||||
|
if (!mIsTranslucent)
|
||||||
::ReleaseDC(mWnd, (HDC)data);
|
::ReleaseDC(mWnd, (HDC)data);
|
||||||
|
#else
|
||||||
|
::ReleaseDC(mWnd, (HDC)data);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
case NS_NATIVE_WIDGET:
|
case NS_NATIVE_WIDGET:
|
||||||
case NS_NATIVE_WINDOW:
|
case NS_NATIVE_WINDOW:
|
||||||
case NS_NATIVE_PLUGIN_PORT:
|
case NS_NATIVE_PLUGIN_PORT:
|
||||||
|
@ -4221,6 +4324,11 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
|
||||||
::RedrawWindow(mWnd, &drect, NULL,
|
::RedrawWindow(mWnd, &drect, NULL,
|
||||||
RDW_INVALIDATE | RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_ERASENOW | RDW_ALLCHILDREN);
|
RDW_INVALIDATE | RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_ERASENOW | RDW_ALLCHILDREN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MOZ_XUL
|
||||||
|
if (mIsTranslucent)
|
||||||
|
ResizeTranslucentWindow(newWidth, newHeight);
|
||||||
|
#endif
|
||||||
mBounds.width = newWidth;
|
mBounds.width = newWidth;
|
||||||
mBounds.height = newHeight;
|
mBounds.height = newHeight;
|
||||||
mLastSize.width = newWidth;
|
mLastSize.width = newWidth;
|
||||||
|
@ -5045,6 +5153,16 @@ PRBool nsWindow::OnPaint(HDC aDC)
|
||||||
event.renderingContext->Init(mContext, surf);
|
event.renderingContext->Init(mContext, surf);
|
||||||
result = DispatchWindowEvent(&event, eventStatus);
|
result = DispatchWindowEvent(&event, eventStatus);
|
||||||
event.renderingContext->DestroyDrawingSurface(surf);
|
event.renderingContext->DestroyDrawingSurface(surf);
|
||||||
|
|
||||||
|
#ifdef MOZ_XUL
|
||||||
|
if (mIsTranslucent)
|
||||||
|
{
|
||||||
|
// Data from offscreen drawing surface was copied to memory bitmap of transparent
|
||||||
|
// bitmap. Now it can be read from memory bitmap to apply alpha channel and after
|
||||||
|
// that displayed on the screen.
|
||||||
|
UpdateTranslucentWindow();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_RELEASE(winrc);
|
NS_RELEASE(winrc);
|
||||||
|
@ -7146,3 +7264,340 @@ STDMETHODIMP_(LRESULT) nsWindow::LresultFromObject(REFIID riid,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MOZ_XUL
|
||||||
|
|
||||||
|
typedef WINUSERAPI BOOL WINAPI UpdateLayeredWindowProc (HWND hWnd, HDC hdcDst, POINT *pptDst,
|
||||||
|
SIZE *psize, HDC hdcSrc, POINT *pptSrc,
|
||||||
|
COLORREF crKey, BLENDFUNCTION *pblend,
|
||||||
|
DWORD dwFlags);
|
||||||
|
|
||||||
|
|
||||||
|
static UpdateLayeredWindowProc* pUpdateLayeredWindow = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
static PRBool IsTranslucencySupported()
|
||||||
|
{
|
||||||
|
static PRBool firstTime = PR_TRUE;
|
||||||
|
|
||||||
|
if (firstTime)
|
||||||
|
{
|
||||||
|
firstTime = PR_FALSE;
|
||||||
|
|
||||||
|
HMODULE user32 = ::GetModuleHandle("user32.dll");
|
||||||
|
|
||||||
|
if (user32)
|
||||||
|
pUpdateLayeredWindow = (UpdateLayeredWindowProc*)::GetProcAddress(user32, "UpdateLayeredWindow");
|
||||||
|
}
|
||||||
|
|
||||||
|
return pUpdateLayeredWindow != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIWidget* nsWindow::GetTopLevelWidget()
|
||||||
|
{
|
||||||
|
nsIWidget* curWidget = this;
|
||||||
|
NS_ADDREF(curWidget);
|
||||||
|
|
||||||
|
while (PR_TRUE)
|
||||||
|
{
|
||||||
|
if (mIsTopWidgetWindow)
|
||||||
|
return curWidget;
|
||||||
|
|
||||||
|
nsIWidget* parentWidget = curWidget->GetParent();
|
||||||
|
|
||||||
|
if (parentWidget)
|
||||||
|
{
|
||||||
|
NS_RELEASE(curWidget);
|
||||||
|
curWidget = parentWidget;
|
||||||
|
} else
|
||||||
|
return curWidget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsWindow::ResizeTranslucentWindow(PRInt32 aNewWidth, PRInt32 aNewHeight)
|
||||||
|
{
|
||||||
|
if (aNewWidth == mBounds.width && aNewHeight == mBounds.height)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// resize the alpha mask
|
||||||
|
PRUint8* pBits;
|
||||||
|
|
||||||
|
if (aNewWidth > 0 && aNewHeight > 0)
|
||||||
|
{
|
||||||
|
pBits = new PRUint8 [aNewWidth * aNewHeight];
|
||||||
|
|
||||||
|
if (pBits)
|
||||||
|
{
|
||||||
|
PRInt32 copyWidth, copyHeight;
|
||||||
|
PRInt32 growWidth, growHeight;
|
||||||
|
|
||||||
|
if (aNewWidth > mBounds.width)
|
||||||
|
{
|
||||||
|
copyWidth = mBounds.width;
|
||||||
|
growWidth = aNewWidth - mBounds.width;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
copyWidth = aNewWidth;
|
||||||
|
growWidth = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aNewHeight > mBounds.height)
|
||||||
|
{
|
||||||
|
copyHeight = mBounds.height;
|
||||||
|
growHeight = aNewHeight - mBounds.height;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
copyHeight = aNewHeight;
|
||||||
|
growHeight = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRUint8* pSrc = mAlphaMask;
|
||||||
|
PRUint8* pDest = pBits;
|
||||||
|
|
||||||
|
for (PRInt32 cy = 0 ; cy < copyHeight ; cy++)
|
||||||
|
{
|
||||||
|
memcpy (pDest, pSrc, copyWidth);
|
||||||
|
memset (pDest + copyWidth, 255, growWidth);
|
||||||
|
pSrc += mBounds.width;
|
||||||
|
pDest += aNewWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (PRInt32 gy = 0 ; gy < growHeight ; gy++)
|
||||||
|
{
|
||||||
|
memset (pDest, 255, aNewWidth);
|
||||||
|
pDest += aNewWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
pBits = nsnull;
|
||||||
|
|
||||||
|
delete [] mAlphaMask;
|
||||||
|
mAlphaMask = pBits;
|
||||||
|
|
||||||
|
|
||||||
|
// resize the memory bitmap
|
||||||
|
HDC hScreenDC = ::GetDC(NULL);
|
||||||
|
mMemoryBitmap = ::CreateCompatibleBitmap(hScreenDC, aNewWidth, aNewHeight);
|
||||||
|
|
||||||
|
if (mMemoryBitmap)
|
||||||
|
{
|
||||||
|
HGDIOBJ oldBitmap = ::SelectObject(mMemoryDC, mMemoryBitmap);
|
||||||
|
::DeleteObject(oldBitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
::ReleaseDC(NULL, hScreenDC);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsWindow::GetWindowTranslucency(PRBool& aTranslucent)
|
||||||
|
{
|
||||||
|
if (IsTranslucencySupported())
|
||||||
|
{
|
||||||
|
nsWindow* topWindow = (nsWindow*)GetTopLevelWidget();
|
||||||
|
aTranslucent = topWindow->GetWindowTranslucencyInner();
|
||||||
|
NS_RELEASE(topWindow);
|
||||||
|
} else
|
||||||
|
aTranslucent = PR_FALSE;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsWindow::SetWindowTranslucency(PRBool aTranslucent)
|
||||||
|
{
|
||||||
|
if (!IsTranslucencySupported())
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
|
||||||
|
nsWindow* topWindow = (nsWindow*)GetTopLevelWidget();
|
||||||
|
nsresult rv = topWindow->SetWindowTranslucencyInner(aTranslucent);
|
||||||
|
NS_RELEASE(topWindow);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsWindow::UpdateTranslucentWindowAlpha(const nsRect& aRect, PRUint8* aAlphas)
|
||||||
|
{
|
||||||
|
if (!IsTranslucencySupported())
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
|
||||||
|
nsWindow* topWindow = (nsWindow*)GetTopLevelWidget();
|
||||||
|
topWindow->UpdateTranslucentWindowAlphaInner(aRect, aAlphas);
|
||||||
|
NS_RELEASE(topWindow);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsWindow::SetWindowTranslucencyInner(PRBool aTranslucent)
|
||||||
|
{
|
||||||
|
if (aTranslucent == mIsTranslucent)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
HWND hWnd = GetTopLevelHWND(mWnd);
|
||||||
|
LONG style;
|
||||||
|
LONG exStyle = nsToolkit::mGetWindowLong(hWnd, GWL_EXSTYLE);
|
||||||
|
if (aTranslucent)
|
||||||
|
{
|
||||||
|
style = nsToolkit::mGetWindowLong(hWnd, GWL_STYLE) & ~WS_CAPTION;
|
||||||
|
exStyle |= WS_EX_LAYERED;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
style = WindowStyle();
|
||||||
|
exStyle &= ~WS_EX_LAYERED;
|
||||||
|
}
|
||||||
|
nsToolkit::mSetWindowLong(hWnd, GWL_STYLE, style);
|
||||||
|
nsToolkit::mSetWindowLong(hWnd, GWL_EXSTYLE, exStyle);
|
||||||
|
|
||||||
|
nsresult rv = NS_ERROR_FAILURE;
|
||||||
|
mIsTranslucent = aTranslucent;
|
||||||
|
|
||||||
|
if (aTranslucent)
|
||||||
|
{
|
||||||
|
HDC hScreenDC = ::GetDC(NULL);
|
||||||
|
mMemoryDC = ::CreateCompatibleDC(hScreenDC);
|
||||||
|
|
||||||
|
if (mMemoryDC)
|
||||||
|
{
|
||||||
|
mMemoryBitmap = ::CreateCompatibleBitmap(hScreenDC, mBounds.width, mBounds.height);
|
||||||
|
|
||||||
|
if (mMemoryBitmap)
|
||||||
|
{
|
||||||
|
::SelectObject(mMemoryDC, mMemoryBitmap);
|
||||||
|
|
||||||
|
rv = NS_OK;
|
||||||
|
|
||||||
|
if (!mBounds.IsEmpty())
|
||||||
|
{
|
||||||
|
PRInt32 alphaBytes = mBounds.width * mBounds.height;
|
||||||
|
mAlphaMask = new PRUint8 [alphaBytes];
|
||||||
|
|
||||||
|
if (mAlphaMask)
|
||||||
|
memset (mAlphaMask, 255, alphaBytes);
|
||||||
|
else
|
||||||
|
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
} else
|
||||||
|
mAlphaMask = nsnull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::ReleaseDC(NULL, hScreenDC);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
::DeleteDC(mMemoryDC);
|
||||||
|
::DeleteObject(mMemoryBitmap);
|
||||||
|
delete [] mAlphaMask;
|
||||||
|
|
||||||
|
mMemoryDC = NULL;
|
||||||
|
mMemoryBitmap = NULL;
|
||||||
|
mAlphaMask = nsnull;
|
||||||
|
|
||||||
|
rv = NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsWindow::UpdateTranslucentWindowAlphaInner(const nsRect& aRect, PRUint8* aAlphas)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(mIsTranslucent, "Window is not transparent");
|
||||||
|
NS_ASSERTION(aRect.x >= 0 && aRect.y >= 0 &&
|
||||||
|
aRect.XMost() <= mBounds.width && aRect.YMost() <= mBounds.height,
|
||||||
|
"Rect is out of window bounds");
|
||||||
|
|
||||||
|
if (!aRect.IsEmpty())
|
||||||
|
{
|
||||||
|
PRUint8* pSrc = aAlphas;
|
||||||
|
PRUint8* pDest = mAlphaMask + aRect.y * mBounds.width + aRect.x;
|
||||||
|
|
||||||
|
for (PRInt32 y = 0 ; y < aRect.height ; y++)
|
||||||
|
{
|
||||||
|
memcpy (pDest, pSrc, aRect.width);
|
||||||
|
|
||||||
|
pSrc += aRect.width;
|
||||||
|
pDest += mBounds.width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The real screen update is performed in OnPaint() handler only after rendered
|
||||||
|
// bits from offscreen drawing surface are copied back to memory bitmap.
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsWindow::UpdateTranslucentWindow()
|
||||||
|
{
|
||||||
|
if (mBounds.IsEmpty())
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
nsresult rv = NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
// Memory bitmap with alpha channel
|
||||||
|
HDC hMemoryDC = ::CreateCompatibleDC(NULL);
|
||||||
|
|
||||||
|
if (hMemoryDC)
|
||||||
|
{
|
||||||
|
HBITMAP hAlphaBitmap = ::CreateBitmap(mBounds.width, mBounds.height, 1, 32, NULL);
|
||||||
|
|
||||||
|
if (hAlphaBitmap)
|
||||||
|
{
|
||||||
|
::SelectObject(hMemoryDC, hAlphaBitmap);
|
||||||
|
|
||||||
|
BITMAPINFO bi = { 0 };
|
||||||
|
bi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
|
||||||
|
bi.bmiHeader.biWidth = mBounds.width;
|
||||||
|
bi.bmiHeader.biHeight = -mBounds.height;
|
||||||
|
bi.bmiHeader.biPlanes = 1;
|
||||||
|
bi.bmiHeader.biBitCount = 32;
|
||||||
|
bi.bmiHeader.biCompression = BI_RGB;
|
||||||
|
|
||||||
|
PRUint8* pBits = new PRUint8 [4 * mBounds.width * mBounds.height];
|
||||||
|
|
||||||
|
if (pBits)
|
||||||
|
{
|
||||||
|
int lines = ::GetDIBits(mMemoryDC, mMemoryBitmap, 0, mBounds.height, pBits, &bi, DIB_RGB_COLORS);
|
||||||
|
|
||||||
|
if (lines == mBounds.height)
|
||||||
|
{
|
||||||
|
PRUint8* pPixel = pBits;
|
||||||
|
PRUint8* pAlpha = mAlphaMask;
|
||||||
|
|
||||||
|
for (PRInt32 cnt = 0 ; cnt < mBounds.width * mBounds.height ; cnt++)
|
||||||
|
{
|
||||||
|
// Each of the RGB components should be premultiplied with alpha and divided by 255
|
||||||
|
FAST_DIVIDE_BY_255(pPixel [0], *pAlpha * pPixel [0]);
|
||||||
|
FAST_DIVIDE_BY_255(pPixel [1], *pAlpha * pPixel [1]);
|
||||||
|
FAST_DIVIDE_BY_255(pPixel [2], *pAlpha * pPixel [2]);
|
||||||
|
pPixel [3] = *pAlpha;
|
||||||
|
|
||||||
|
pPixel +=4;
|
||||||
|
pAlpha++;
|
||||||
|
}
|
||||||
|
|
||||||
|
lines = ::SetDIBits (hMemoryDC, hAlphaBitmap, 0, mBounds.height, pBits, &bi, DIB_RGB_COLORS);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete [] pBits;
|
||||||
|
|
||||||
|
if (lines == mBounds.height)
|
||||||
|
{
|
||||||
|
BLENDFUNCTION bf = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
|
||||||
|
SIZE winSize = { mBounds.width, mBounds.height };
|
||||||
|
POINT srcPos = { 0, 0 };
|
||||||
|
HDC hScreenDC = ::GetDC(NULL);
|
||||||
|
HWND hWnd = GetTopLevelHWND(mWnd);
|
||||||
|
RECT winRect;
|
||||||
|
::GetWindowRect(hWnd, &winRect);
|
||||||
|
|
||||||
|
// perform the alpha blend
|
||||||
|
if (pUpdateLayeredWindow(hWnd, hScreenDC, (POINT*)&winRect, &winSize, hMemoryDC, &srcPos, 0, &bf, ULW_ALPHA))
|
||||||
|
rv = NS_OK;
|
||||||
|
|
||||||
|
::ReleaseDC(NULL, hScreenDC);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
::DeleteObject(hAlphaBitmap);
|
||||||
|
}
|
||||||
|
::DeleteDC(hMemoryDC);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
* Robert O'Callahan <roc+moz@cs.cmu.edu>
|
* Robert O'Callahan <roc+moz@cs.cmu.edu>
|
||||||
* Dean Tessman <dean_tessman@hotmail.com>
|
* Dean Tessman <dean_tessman@hotmail.com>
|
||||||
* Makoto Kato <m_kato@ga2.so-net.ne.jp>
|
* Makoto Kato <m_kato@ga2.so-net.ne.jp>
|
||||||
|
* Dainis Jonitis <Dainis_Jonitis@swh-t.lv>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
@ -391,6 +392,20 @@ public:
|
||||||
NS_IMETHOD GetAttention(PRInt32 aCycleCount);
|
NS_IMETHOD GetAttention(PRInt32 aCycleCount);
|
||||||
NS_IMETHOD GetLastInputEventTime(PRUint32& aTime);
|
NS_IMETHOD GetLastInputEventTime(PRUint32& aTime);
|
||||||
|
|
||||||
|
#ifdef MOZ_XUL
|
||||||
|
NS_IMETHOD SetWindowTranslucency(PRBool aTransparent);
|
||||||
|
NS_IMETHOD GetWindowTranslucency(PRBool& aTransparent);
|
||||||
|
NS_IMETHOD UpdateTranslucentWindowAlpha(const nsRect& aRect, PRUint8* aAlphas);
|
||||||
|
private:
|
||||||
|
nsresult SetWindowTranslucencyInner(PRBool aTransparent);
|
||||||
|
PRBool GetWindowTranslucencyInner() { return mIsTranslucent; }
|
||||||
|
void UpdateTranslucentWindowAlphaInner(const nsRect& aRect, PRUint8* aAlphas);
|
||||||
|
nsIWidget* GetTopLevelWidget();
|
||||||
|
void ResizeTranslucentWindow(PRInt32 aNewWidth, PRInt32 aNewHeight);
|
||||||
|
nsresult UpdateTranslucentWindow();
|
||||||
|
public:
|
||||||
|
#endif
|
||||||
|
|
||||||
// nsIKBStateControl interface
|
// nsIKBStateControl interface
|
||||||
|
|
||||||
NS_IMETHOD ResetInputState();
|
NS_IMETHOD ResetInputState();
|
||||||
|
@ -400,8 +415,6 @@ public:
|
||||||
PRBool HandleMouseActionOfIME(PRInt32 aAction, POINT* ptPos);
|
PRBool HandleMouseActionOfIME(PRInt32 aAction, POINT* ptPos);
|
||||||
void GetCompositionWindowPos(HIMC hIMC, PRUint32 aEventType, COMPOSITIONFORM *cpForm);
|
void GetCompositionWindowPos(HIMC hIMC, PRUint32 aEventType, COMPOSITIONFORM *cpForm);
|
||||||
|
|
||||||
HWND mBorderlessParent;
|
|
||||||
|
|
||||||
// nsSwitchToUIThread interface
|
// nsSwitchToUIThread interface
|
||||||
virtual BOOL CallMethod(MethodInfo *info);
|
virtual BOOL CallMethod(MethodInfo *info);
|
||||||
|
|
||||||
|
@ -522,12 +535,19 @@ protected:
|
||||||
static nsWindow* gCurrentWindow;
|
static nsWindow* gCurrentWindow;
|
||||||
nsPoint mLastPoint;
|
nsPoint mLastPoint;
|
||||||
HWND mWnd;
|
HWND mWnd;
|
||||||
|
HWND mBorderlessParent;
|
||||||
#if 0
|
#if 0
|
||||||
HPALETTE mPalette;
|
HPALETTE mPalette;
|
||||||
#endif
|
#endif
|
||||||
WNDPROC mPrevWndProc;
|
WNDPROC mPrevWndProc;
|
||||||
HBRUSH mBrush;
|
HBRUSH mBrush;
|
||||||
|
|
||||||
|
#ifdef MOZ_XUL
|
||||||
|
HBITMAP mMemoryBitmap;
|
||||||
|
HDC mMemoryDC;
|
||||||
|
PRUint8* mAlphaMask;
|
||||||
|
PRPackedBool mIsTranslucent;
|
||||||
|
#endif
|
||||||
PRPackedBool mIsTopWidgetWindow;
|
PRPackedBool mIsTopWidgetWindow;
|
||||||
PRPackedBool mHas3DBorder;
|
PRPackedBool mHas3DBorder;
|
||||||
PRPackedBool mIsShiftDown;
|
PRPackedBool mIsShiftDown;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче