os/graphics/windowing/windowserver/debuglog/osbwin.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/graphics/windowing/windowserver/debuglog/osbwin.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,367 @@
     1.4 +// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +// Win32 dependent code for debugging wserv offscreenbuffer and UI surface on emulator
    1.20 +//
    1.21 +#include "osbwin.h"
    1.22 +#include "_windows.h"
    1.23 +
    1.24 +TInt CDebugOsbWin::iId=0;
    1.25 +const TInt KMaxBuffer=32;
    1.26 +HBITMAP* TheBitmap[KMaxBuffer];
    1.27 +HWND* TheWindow[KMaxBuffer];
    1.28 +
    1.29 +// Application window specific messages
    1.30 +#define WMA_RESIZE		(WM_APP + 0)
    1.31 +
    1.32 +struct TWin32Info
    1.33 +	{
    1.34 +	HWND iHwnd;
    1.35 +	HDC iHdc;
    1.36 +	HBITMAP iHbitmap;
    1.37 +	BITMAPINFO* iBitmapInfo;
    1.38 +	};
    1.39 +
    1.40 +EXPORT_C CDebugOsbWin* CDebugOsbWin::NewL(const TDesC& aName, TSize aSize)
    1.41 +	{
    1.42 +	CDebugOsbWin* self = new(ELeave) CDebugOsbWin(aName, aSize);
    1.43 +	CleanupStack::PushL(self);
    1.44 +	self->ConstructL();
    1.45 +	CleanupStack::Pop(self);
    1.46 +	return self;
    1.47 +	}
    1.48 +
    1.49 +CDebugOsbWin::CDebugOsbWin(const TDesC& aName, TSize aSize):
    1.50 +	iThreadCreated(EFalse), iSize(aSize), iName(aName)
    1.51 +	{}
    1.52 +
    1.53 +EXPORT_C CDebugOsbWin::~CDebugOsbWin()
    1.54 +	{
    1.55 +	iSem.Close();
    1.56 +	if (iThreadCreated)
    1.57 +		{
    1.58 +		iThread.Terminate(0);
    1.59 +		iThread.Close();
    1.60 +		}
    1.61 +	if (iWin32)
    1.62 +		{
    1.63 +		if (iWin32->iHbitmap)
    1.64 +			DeleteObject(iWin32->iHbitmap);
    1.65 +		if (iWin32->iBitmapInfo)
    1.66 +			User::Free(iWin32->iBitmapInfo);
    1.67 +		if (iWin32->iHwnd && iWin32->iHdc)
    1.68 +			ReleaseDC(iWin32->iHwnd,iWin32->iHdc);
    1.69 +		delete iWin32;
    1.70 +		}
    1.71 +	if (iPalette)
    1.72 +		delete iPalette;
    1.73 +	--CDebugOsbWin::iId;
    1.74 +	}
    1.75 +
    1.76 +void CDebugOsbWin::ConstructL()
    1.77 +	{
    1.78 +	if (iId>=KMaxBuffer)
    1.79 +		User::Leave(KErrNoMemory);
    1.80 +	iPalette=CPalette::NewDefaultL(EColor256);
    1.81 +	iWin32=new(ELeave) TWin32Info;
    1.82 +	// store window handle and bitmap association to global table
    1.83 +	TheWindow[iId]=&(iWin32->iHwnd);
    1.84 +	TheBitmap[iId]=&(iWin32->iHbitmap);
    1.85 +
    1.86 +	_LIT(KIdFormat, " (%d)");
    1.87 +	iName.AppendFormat(KIdFormat, iId);
    1.88 +
    1.89 +	++iId;
    1.90 +	iSem.CreateLocal(0);
    1.91 +	const TInt KHeapSize=0x4000;
    1.92 +	User::LeaveIfError(iThread.Create(iName,CDebugOsbWin::ThreadMain,KDefaultStackSize,KHeapSize,KHeapSize,this));
    1.93 +	iThread.SetPriority(EPriorityMuchLess);
    1.94 +	iThread.Resume();
    1.95 +	iThreadCreated=ETrue;
    1.96 +	iSem.Wait();
    1.97 +	// iHwnd initialized by WinMain
    1.98 +	iWin32->iHdc=GetDC(iWin32->iHwnd);
    1.99 +	SetMapMode(iWin32->iHdc,MM_TEXT);
   1.100 +	SetROP2(iWin32->iHdc,R2_COPYPEN);
   1.101 +	TInt byteSize=iSize.iWidth*iSize.iHeight*3;
   1.102 +	iWin32->iBitmapInfo=(BITMAPINFO*)User::Alloc(sizeof(BITMAPINFO));
   1.103 +	User::LeaveIfNull(iWin32->iBitmapInfo);
   1.104 +	iWin32->iBitmapInfo->bmiHeader.biBitCount=24;
   1.105 +	iWin32->iBitmapInfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
   1.106 +	iWin32->iBitmapInfo->bmiHeader.biWidth=iSize.iWidth;
   1.107 +	iWin32->iBitmapInfo->bmiHeader.biHeight=-iSize.iHeight;//top-down DIB
   1.108 +	iWin32->iBitmapInfo->bmiHeader.biPlanes=1;
   1.109 +	iWin32->iBitmapInfo->bmiHeader.biCompression=BI_RGB;
   1.110 +	iWin32->iHbitmap=CreateDIBSection(iWin32->iHdc,iWin32->iBitmapInfo,DIB_RGB_COLORS,(TAny**)&iBitmapBits,NULL,0);
   1.111 +	User::LeaveIfNull(iWin32->iHbitmap);
   1.112 +	Mem::Fill(iBitmapBits,byteSize,0xff);
   1.113 +	}
   1.114 +
   1.115 +EXPORT_C void CDebugOsbWin::Refresh(TSize aSize, TDisplayMode aDisplayMode, const TUint32* aDataAddress)
   1.116 +	{
   1.117 +	TBool hasResized = EFalse;
   1.118 +
   1.119 +	// When screen is rotated, the size can change as width and height are swapped.
   1.120 +	if (iSize != aSize)
   1.121 +		{
   1.122 +		iSize = aSize;
   1.123 +		iWin32->iBitmapInfo->bmiHeader.biWidth = aSize.iWidth;
   1.124 +		iWin32->iBitmapInfo->bmiHeader.biHeight = -aSize.iHeight; //top-down DIB
   1.125 +		hasResized = ETrue;
   1.126 +		}
   1.127 +
   1.128 +	switch (aDisplayMode)
   1.129 +		{
   1.130 +		case EGray4:
   1.131 +			Copy2Bpp(aDataAddress);
   1.132 +			break;
   1.133 +		case EColor256:
   1.134 +			Copy8Bpp(aDataAddress);
   1.135 +			break;
   1.136 +		case EColor4K:
   1.137 +			Copy12Bpp(aDataAddress);
   1.138 +			break;
   1.139 +		case EColor64K:
   1.140 +			Copy16Bpp(aDataAddress);
   1.141 +			break;
   1.142 +		case EColor16M:
   1.143 +			Copy24Bpp(aDataAddress);
   1.144 +			break;
   1.145 +		case EColor16MU:
   1.146 +		case EColor16MA:
   1.147 +		case EColor16MAP:	// Should really have alpha divided out
   1.148 +			CopyU24Bpp(aDataAddress);
   1.149 +			break;
   1.150 +		default:
   1.151 +			return;
   1.152 +		}
   1.153 +	SetDIBitsToDevice(iWin32->iHdc,0,0,iSize.iWidth,iSize.iHeight,0,0,0,iSize.iHeight,iBitmapBits,
   1.154 +		((LPBITMAPINFO)iWin32->iBitmapInfo),DIB_RGB_COLORS);
   1.155 +	if (hasResized)
   1.156 +		{
   1.157 +		// This will cause a redraw so no need to invalidate.
   1.158 +		PostMessage(iWin32->iHwnd, WMA_RESIZE, iSize.iWidth + iHExtra, iSize.iHeight + iVExtra);
   1.159 +		}
   1.160 +	else
   1.161 +		{
   1.162 +		InvalidateRect(iWin32->iHwnd,NULL,FALSE);
   1.163 +		}
   1.164 +	}
   1.165 +
   1.166 +void CDebugOsbWin::Copy2Bpp(const TUint32* aDataAddress)
   1.167 +	{
   1.168 +	const TUint8 gray[]={0,85,170,255};
   1.169 +	
   1.170 +	const TUint8* src=(const TUint8*)aDataAddress;
   1.171 +	TUint8* dest=iBitmapBits;
   1.172 +	const TInt width=iSize.iWidth>>2;
   1.173 +	for (TInt row=0;row<iSize.iHeight;++row)
   1.174 +		{
   1.175 +		for (TInt col=0;col<width;++col)
   1.176 +			{
   1.177 +			TUint8 p1=*src++;
   1.178 +			TUint8 p2=TUint8((p1>>2) & 0x03);
   1.179 +			TUint8 p3=TUint8((p1>>4) & 0x03);
   1.180 +			TUint8 p4=TUint8((p1>>6) & 0x03);
   1.181 +			p1&=0x03;
   1.182 +			dest[0]=dest[1]=dest[2]=gray[p1];
   1.183 +			dest[3]=dest[4]=dest[5]=gray[p2];
   1.184 +			dest[6]=dest[7]=dest[8]=gray[p3];
   1.185 +			dest[9]=dest[10]=dest[11]=gray[p4];
   1.186 +			dest+=12; // 1 byte source equals to 4 destination pixels
   1.187 +			}
   1.188 +		}
   1.189 +	}
   1.190 +
   1.191 +void CDebugOsbWin::Copy8Bpp(const TUint32* aDataAddress)
   1.192 +	{
   1.193 +	if (!iPalette)
   1.194 +		return;
   1.195 +	const TUint8* src=(const TUint8*)aDataAddress;
   1.196 +	TUint8* dest=iBitmapBits;
   1.197 +	for (TInt row=0;row<iSize.iHeight;++row)
   1.198 +		{
   1.199 +		for (TInt col=0;col<iSize.iWidth;++col)
   1.200 +			{
   1.201 +			const TRgb rgb(iPalette->GetEntry(*src++));
   1.202 +			dest[0]=TUint8(rgb.Blue());
   1.203 +			dest[1]=TUint8(rgb.Green());
   1.204 +			dest[2]=TUint8(rgb.Red());
   1.205 +			dest+=3;
   1.206 +			}
   1.207 +		}
   1.208 +	}
   1.209 +
   1.210 +void CDebugOsbWin::Copy12Bpp(const TUint32* aDataAddress)
   1.211 +	{
   1.212 +
   1.213 +	const TUint16* src=(const TUint16*)aDataAddress;
   1.214 +	TUint8* dest=iBitmapBits;
   1.215 +	for (TInt row=0;row<iSize.iHeight;++row)
   1.216 +		{
   1.217 +		for (TInt col=0;col<iSize.iWidth;++col)
   1.218 +			{
   1.219 +			dest[0]=TUint8((*src & 0x00f));
   1.220 +			dest[0]|=dest[0] << 4;
   1.221 +			dest[1]=TUint8((*src & 0x0f0));
   1.222 +			dest[1]|=dest[1] >> 4;
   1.223 +			dest[2]=TUint8((*src & 0xf00)>>4);
   1.224 +			dest[2]|=dest[2] >> 4;
   1.225 +			++src;
   1.226 +			dest+=3;
   1.227 +			}
   1.228 +		}
   1.229 +	}
   1.230 +
   1.231 +void CDebugOsbWin::Copy16Bpp(const TUint32* aDataAddress)
   1.232 +	{
   1.233 +	const TUint16* src=(const TUint16*)aDataAddress;
   1.234 +	TUint8* dest=iBitmapBits;
   1.235 +	for (TInt row=0;row<iSize.iHeight;++row)
   1.236 +		{
   1.237 +		for (TInt col=0;col<iSize.iWidth;++col)
   1.238 +			{
   1.239 +			dest[0]=TUint8((*src & 0x001f)<<3);
   1.240 +			dest[0]=TUint8(dest[0]+(dest[0]>>5));
   1.241 +			dest[1]=TUint8((*src & 0x07e0)>>3);
   1.242 +			dest[1]=TUint8(dest[1]+(dest[1]>>6));
   1.243 +			dest[2]=TUint8((*src & 0xf800)>>8);
   1.244 +			dest[2]=TUint8(dest[2]+(dest[2]>>5));
   1.245 +			++src;
   1.246 +			dest+=3;
   1.247 +			}
   1.248 +		}
   1.249 +	}
   1.250 +
   1.251 +void CDebugOsbWin::CopyU24Bpp(const TUint32* aDataAddress)
   1.252 +	{
   1.253 +	const TUint8* src=(const TUint8*)aDataAddress;
   1.254 +	TUint8* dest=iBitmapBits;
   1.255 +	for (TInt row=0;row<iSize.iHeight;++row)
   1.256 +		{
   1.257 +		for (TInt col=0;col<iSize.iWidth;++col)
   1.258 +			{
   1.259 +			dest[0]=*src++;
   1.260 +			dest[1]=*src++;
   1.261 +			dest[2]=*src++;
   1.262 +			++src; // unpack, takes 4 bytes per pixel
   1.263 +			dest+=3;
   1.264 +			}
   1.265 +		}
   1.266 +	}
   1.267 +
   1.268 +void CDebugOsbWin::Copy24Bpp(const TUint32* aDataAddress)
   1.269 +	{
   1.270 +	const TUint8* src = (const TUint8*)aDataAddress;
   1.271 +	Mem::Copy(iBitmapBits, src, 3 * iSize.iWidth * iSize.iHeight);
   1.272 +	}
   1.273 +
   1.274 +HBITMAP* GetBitmap(HWND aHwnd)
   1.275 +	{
   1.276 +	TInt i;
   1.277 +	for (i=0;i<CDebugOsbWin::iId;++i)
   1.278 +		{
   1.279 +		if (*(TheWindow[i])==aHwnd)
   1.280 +			return TheBitmap[i];
   1.281 +		}
   1.282 +	return NULL;
   1.283 +	}
   1.284 +
   1.285 +TInt32 APIENTRY WindowProc(HWND aHwnd,TUint aMsg,TUint aWparam,TInt32 aLparam)
   1.286 +	{
   1.287 +	switch (aMsg)
   1.288 +		{
   1.289 +		case WM_PAINT:
   1.290 +			{
   1.291 +			HBITMAP* hBitmap=GetBitmap(aHwnd);
   1.292 +			if (hBitmap)
   1.293 +				{
   1.294 +				PAINTSTRUCT p;
   1.295 +				BeginPaint(aHwnd,&p);
   1.296 +		   		HDC hdcBits;
   1.297 +				BITMAP bm;
   1.298 +	    		hdcBits=CreateCompatibleDC(p.hdc);
   1.299 +				GetObject(*hBitmap,sizeof(BITMAP),&bm);
   1.300 +	    		SelectObject(hdcBits,*hBitmap);
   1.301 +				RECT windowRect;
   1.302 +				GetClientRect(aHwnd,&windowRect);
   1.303 +				BitBlt(p.hdc,0,0,windowRect.right-windowRect.left,windowRect.bottom-windowRect.top,hdcBits,0,0,SRCCOPY);
   1.304 +				DeleteDC(hdcBits);
   1.305 +	 			EndPaint(aHwnd,&p);
   1.306 +				}
   1.307 +			}
   1.308 +			return 0;
   1.309 +		case WMA_RESIZE:
   1.310 +			{
   1.311 +			RECT rc;
   1.312 +			GetWindowRect(aHwnd, &rc);
   1.313 +			MoveWindow(aHwnd, rc.left, rc.top, aWparam, aLparam, TRUE);
   1.314 +			}
   1.315 +			break;
   1.316 +		default:
   1.317 +			return DefWindowProc(aHwnd,aMsg,aWparam,aLparam);
   1.318 +		}
   1.319 +	return 1;
   1.320 +	}
   1.321 +
   1.322 +TInt CDebugOsbWin::ThreadMain(TAny* aArg)
   1.323 +    {
   1.324 +    CDebugOsbWin* self=(CDebugOsbWin*)aArg;
   1.325 +    if (!self || !self->iWin32)
   1.326 +    	return KErrArgument;
   1.327 +    TWin32Info* win32=self->iWin32;
   1.328 +    TSize size=self->iSize;
   1.329 +    WNDCLASS wndclass;
   1.330 +    const TText *szAppName=self->iName.Ptr();
   1.331 +    wndclass.style=CS_HREDRAW|CS_VREDRAW;
   1.332 +    wndclass.lpfnWndProc=WindowProc;
   1.333 +    wndclass.cbClsExtra=0;
   1.334 +    wndclass.cbWndExtra=0;
   1.335 +    wndclass.hInstance=NULL;
   1.336 +    wndclass.hIcon=LoadIcon(NULL, IDI_APPLICATION);
   1.337 +    wndclass.hCursor=LoadCursor(NULL, IDC_ARROW);
   1.338 +    wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
   1.339 +    wndclass.lpszMenuName=NULL;
   1.340 +    wndclass.lpszClassName=(LPCTSTR)szAppName;
   1.341 +	self->iHExtra = GetSystemMetrics(SM_CXFIXEDFRAME) * 2;
   1.342 +	self->iVExtra = GetSystemMetrics(SM_CYFIXEDFRAME) * 2 + GetSystemMetrics(SM_CYCAPTION);
   1.343 +    RegisterClass(&wndclass);
   1.344 +	win32->iHwnd=CreateWindow((LPCTSTR)szAppName,
   1.345 +                    (LPCTSTR)szAppName,
   1.346 +                    WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
   1.347 +                    CW_USEDEFAULT,
   1.348 +                    (CDebugOsbWin::iId-1)*(size.iHeight+30),
   1.349 +                    size.iWidth+self->iHExtra,
   1.350 +                    size.iHeight+self->iVExtra,
   1.351 +                    NULL,
   1.352 +                    NULL,
   1.353 +                    NULL,
   1.354 +                    NULL);
   1.355 +    ShowWindow(win32->iHwnd, SW_SHOWNORMAL);
   1.356 +    UpdateWindow(win32->iHwnd);
   1.357 +	// Now ConstructL can continue with ready to use HWND
   1.358 +	self->iSem.Signal();
   1.359 +	MSG msg;
   1.360 +	// Can't use normal win32 loop. Theoritically, GetMessage with specific HWND param should do, but
   1.361 +	// somehow it's still messing emulator main message loop.
   1.362 +	// The standard win32 loop in debug log to window (deblogwn.cpp) doesn't  seem to work on 9.1
   1.363 +	while (1)
   1.364 +		{
   1.365 +		if (PeekMessage(&msg,win32->iHwnd,0,0,PM_REMOVE))
   1.366 +			DispatchMessage(&msg);
   1.367 +		User::After(300*1000);
   1.368 +		}
   1.369 +	return KErrNone;
   1.370 +    }