windowing/windowserver/debuglog/osbwin.cpp
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 // Win32 dependent code for debugging wserv offscreenbuffer and UI surface on emulator
       
    17 //
       
    18 #include "osbwin.h"
       
    19 #include "_windows.h"
       
    20 
       
    21 TInt CDebugOsbWin::iId=0;
       
    22 const TInt KMaxBuffer=32;
       
    23 HBITMAP* TheBitmap[KMaxBuffer];
       
    24 HWND* TheWindow[KMaxBuffer];
       
    25 
       
    26 // Application window specific messages
       
    27 #define WMA_RESIZE		(WM_APP + 0)
       
    28 
       
    29 struct TWin32Info
       
    30 	{
       
    31 	HWND iHwnd;
       
    32 	HDC iHdc;
       
    33 	HBITMAP iHbitmap;
       
    34 	BITMAPINFO* iBitmapInfo;
       
    35 	};
       
    36 
       
    37 EXPORT_C CDebugOsbWin* CDebugOsbWin::NewL(const TDesC& aName, TSize aSize)
       
    38 	{
       
    39 	CDebugOsbWin* self = new(ELeave) CDebugOsbWin(aName, aSize);
       
    40 	CleanupStack::PushL(self);
       
    41 	self->ConstructL();
       
    42 	CleanupStack::Pop(self);
       
    43 	return self;
       
    44 	}
       
    45 
       
    46 CDebugOsbWin::CDebugOsbWin(const TDesC& aName, TSize aSize):
       
    47 	iThreadCreated(EFalse), iSize(aSize), iName(aName)
       
    48 	{}
       
    49 
       
    50 EXPORT_C CDebugOsbWin::~CDebugOsbWin()
       
    51 	{
       
    52 	iSem.Close();
       
    53 	if (iThreadCreated)
       
    54 		{
       
    55 		iThread.Terminate(0);
       
    56 		iThread.Close();
       
    57 		}
       
    58 	if (iWin32)
       
    59 		{
       
    60 		if (iWin32->iHbitmap)
       
    61 			DeleteObject(iWin32->iHbitmap);
       
    62 		if (iWin32->iBitmapInfo)
       
    63 			User::Free(iWin32->iBitmapInfo);
       
    64 		if (iWin32->iHwnd && iWin32->iHdc)
       
    65 			ReleaseDC(iWin32->iHwnd,iWin32->iHdc);
       
    66 		delete iWin32;
       
    67 		}
       
    68 	if (iPalette)
       
    69 		delete iPalette;
       
    70 	--CDebugOsbWin::iId;
       
    71 	}
       
    72 
       
    73 void CDebugOsbWin::ConstructL()
       
    74 	{
       
    75 	if (iId>=KMaxBuffer)
       
    76 		User::Leave(KErrNoMemory);
       
    77 	iPalette=CPalette::NewDefaultL(EColor256);
       
    78 	iWin32=new(ELeave) TWin32Info;
       
    79 	// store window handle and bitmap association to global table
       
    80 	TheWindow[iId]=&(iWin32->iHwnd);
       
    81 	TheBitmap[iId]=&(iWin32->iHbitmap);
       
    82 
       
    83 	_LIT(KIdFormat, " (%d)");
       
    84 	iName.AppendFormat(KIdFormat, iId);
       
    85 
       
    86 	++iId;
       
    87 	iSem.CreateLocal(0);
       
    88 	const TInt KHeapSize=0x4000;
       
    89 	User::LeaveIfError(iThread.Create(iName,CDebugOsbWin::ThreadMain,KDefaultStackSize,KHeapSize,KHeapSize,this));
       
    90 	iThread.SetPriority(EPriorityMuchLess);
       
    91 	iThread.Resume();
       
    92 	iThreadCreated=ETrue;
       
    93 	iSem.Wait();
       
    94 	// iHwnd initialized by WinMain
       
    95 	iWin32->iHdc=GetDC(iWin32->iHwnd);
       
    96 	SetMapMode(iWin32->iHdc,MM_TEXT);
       
    97 	SetROP2(iWin32->iHdc,R2_COPYPEN);
       
    98 	TInt byteSize=iSize.iWidth*iSize.iHeight*3;
       
    99 	iWin32->iBitmapInfo=(BITMAPINFO*)User::Alloc(sizeof(BITMAPINFO));
       
   100 	User::LeaveIfNull(iWin32->iBitmapInfo);
       
   101 	iWin32->iBitmapInfo->bmiHeader.biBitCount=24;
       
   102 	iWin32->iBitmapInfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
       
   103 	iWin32->iBitmapInfo->bmiHeader.biWidth=iSize.iWidth;
       
   104 	iWin32->iBitmapInfo->bmiHeader.biHeight=-iSize.iHeight;//top-down DIB
       
   105 	iWin32->iBitmapInfo->bmiHeader.biPlanes=1;
       
   106 	iWin32->iBitmapInfo->bmiHeader.biCompression=BI_RGB;
       
   107 	iWin32->iHbitmap=CreateDIBSection(iWin32->iHdc,iWin32->iBitmapInfo,DIB_RGB_COLORS,(TAny**)&iBitmapBits,NULL,0);
       
   108 	User::LeaveIfNull(iWin32->iHbitmap);
       
   109 	Mem::Fill(iBitmapBits,byteSize,0xff);
       
   110 	}
       
   111 
       
   112 EXPORT_C void CDebugOsbWin::Refresh(TSize aSize, TDisplayMode aDisplayMode, const TUint32* aDataAddress)
       
   113 	{
       
   114 	TBool hasResized = EFalse;
       
   115 
       
   116 	// When screen is rotated, the size can change as width and height are swapped.
       
   117 	if (iSize != aSize)
       
   118 		{
       
   119 		iSize = aSize;
       
   120 		iWin32->iBitmapInfo->bmiHeader.biWidth = aSize.iWidth;
       
   121 		iWin32->iBitmapInfo->bmiHeader.biHeight = -aSize.iHeight; //top-down DIB
       
   122 		hasResized = ETrue;
       
   123 		}
       
   124 
       
   125 	switch (aDisplayMode)
       
   126 		{
       
   127 		case EGray4:
       
   128 			Copy2Bpp(aDataAddress);
       
   129 			break;
       
   130 		case EColor256:
       
   131 			Copy8Bpp(aDataAddress);
       
   132 			break;
       
   133 		case EColor4K:
       
   134 			Copy12Bpp(aDataAddress);
       
   135 			break;
       
   136 		case EColor64K:
       
   137 			Copy16Bpp(aDataAddress);
       
   138 			break;
       
   139 		case EColor16M:
       
   140 			Copy24Bpp(aDataAddress);
       
   141 			break;
       
   142 		case EColor16MU:
       
   143 		case EColor16MA:
       
   144 		case EColor16MAP:	// Should really have alpha divided out
       
   145 			CopyU24Bpp(aDataAddress);
       
   146 			break;
       
   147 		default:
       
   148 			return;
       
   149 		}
       
   150 	SetDIBitsToDevice(iWin32->iHdc,0,0,iSize.iWidth,iSize.iHeight,0,0,0,iSize.iHeight,iBitmapBits,
       
   151 		((LPBITMAPINFO)iWin32->iBitmapInfo),DIB_RGB_COLORS);
       
   152 	if (hasResized)
       
   153 		{
       
   154 		// This will cause a redraw so no need to invalidate.
       
   155 		PostMessage(iWin32->iHwnd, WMA_RESIZE, iSize.iWidth + iHExtra, iSize.iHeight + iVExtra);
       
   156 		}
       
   157 	else
       
   158 		{
       
   159 		InvalidateRect(iWin32->iHwnd,NULL,FALSE);
       
   160 		}
       
   161 	}
       
   162 
       
   163 void CDebugOsbWin::Copy2Bpp(const TUint32* aDataAddress)
       
   164 	{
       
   165 	const TUint8 gray[]={0,85,170,255};
       
   166 	
       
   167 	const TUint8* src=(const TUint8*)aDataAddress;
       
   168 	TUint8* dest=iBitmapBits;
       
   169 	const TInt width=iSize.iWidth>>2;
       
   170 	for (TInt row=0;row<iSize.iHeight;++row)
       
   171 		{
       
   172 		for (TInt col=0;col<width;++col)
       
   173 			{
       
   174 			TUint8 p1=*src++;
       
   175 			TUint8 p2=TUint8((p1>>2) & 0x03);
       
   176 			TUint8 p3=TUint8((p1>>4) & 0x03);
       
   177 			TUint8 p4=TUint8((p1>>6) & 0x03);
       
   178 			p1&=0x03;
       
   179 			dest[0]=dest[1]=dest[2]=gray[p1];
       
   180 			dest[3]=dest[4]=dest[5]=gray[p2];
       
   181 			dest[6]=dest[7]=dest[8]=gray[p3];
       
   182 			dest[9]=dest[10]=dest[11]=gray[p4];
       
   183 			dest+=12; // 1 byte source equals to 4 destination pixels
       
   184 			}
       
   185 		}
       
   186 	}
       
   187 
       
   188 void CDebugOsbWin::Copy8Bpp(const TUint32* aDataAddress)
       
   189 	{
       
   190 	if (!iPalette)
       
   191 		return;
       
   192 	const TUint8* src=(const TUint8*)aDataAddress;
       
   193 	TUint8* dest=iBitmapBits;
       
   194 	for (TInt row=0;row<iSize.iHeight;++row)
       
   195 		{
       
   196 		for (TInt col=0;col<iSize.iWidth;++col)
       
   197 			{
       
   198 			const TRgb rgb(iPalette->GetEntry(*src++));
       
   199 			dest[0]=TUint8(rgb.Blue());
       
   200 			dest[1]=TUint8(rgb.Green());
       
   201 			dest[2]=TUint8(rgb.Red());
       
   202 			dest+=3;
       
   203 			}
       
   204 		}
       
   205 	}
       
   206 
       
   207 void CDebugOsbWin::Copy12Bpp(const TUint32* aDataAddress)
       
   208 	{
       
   209 
       
   210 	const TUint16* src=(const TUint16*)aDataAddress;
       
   211 	TUint8* dest=iBitmapBits;
       
   212 	for (TInt row=0;row<iSize.iHeight;++row)
       
   213 		{
       
   214 		for (TInt col=0;col<iSize.iWidth;++col)
       
   215 			{
       
   216 			dest[0]=TUint8((*src & 0x00f));
       
   217 			dest[0]|=dest[0] << 4;
       
   218 			dest[1]=TUint8((*src & 0x0f0));
       
   219 			dest[1]|=dest[1] >> 4;
       
   220 			dest[2]=TUint8((*src & 0xf00)>>4);
       
   221 			dest[2]|=dest[2] >> 4;
       
   222 			++src;
       
   223 			dest+=3;
       
   224 			}
       
   225 		}
       
   226 	}
       
   227 
       
   228 void CDebugOsbWin::Copy16Bpp(const TUint32* aDataAddress)
       
   229 	{
       
   230 	const TUint16* src=(const TUint16*)aDataAddress;
       
   231 	TUint8* dest=iBitmapBits;
       
   232 	for (TInt row=0;row<iSize.iHeight;++row)
       
   233 		{
       
   234 		for (TInt col=0;col<iSize.iWidth;++col)
       
   235 			{
       
   236 			dest[0]=TUint8((*src & 0x001f)<<3);
       
   237 			dest[0]=TUint8(dest[0]+(dest[0]>>5));
       
   238 			dest[1]=TUint8((*src & 0x07e0)>>3);
       
   239 			dest[1]=TUint8(dest[1]+(dest[1]>>6));
       
   240 			dest[2]=TUint8((*src & 0xf800)>>8);
       
   241 			dest[2]=TUint8(dest[2]+(dest[2]>>5));
       
   242 			++src;
       
   243 			dest+=3;
       
   244 			}
       
   245 		}
       
   246 	}
       
   247 
       
   248 void CDebugOsbWin::CopyU24Bpp(const TUint32* aDataAddress)
       
   249 	{
       
   250 	const TUint8* src=(const TUint8*)aDataAddress;
       
   251 	TUint8* dest=iBitmapBits;
       
   252 	for (TInt row=0;row<iSize.iHeight;++row)
       
   253 		{
       
   254 		for (TInt col=0;col<iSize.iWidth;++col)
       
   255 			{
       
   256 			dest[0]=*src++;
       
   257 			dest[1]=*src++;
       
   258 			dest[2]=*src++;
       
   259 			++src; // unpack, takes 4 bytes per pixel
       
   260 			dest+=3;
       
   261 			}
       
   262 		}
       
   263 	}
       
   264 
       
   265 void CDebugOsbWin::Copy24Bpp(const TUint32* aDataAddress)
       
   266 	{
       
   267 	const TUint8* src = (const TUint8*)aDataAddress;
       
   268 	Mem::Copy(iBitmapBits, src, 3 * iSize.iWidth * iSize.iHeight);
       
   269 	}
       
   270 
       
   271 HBITMAP* GetBitmap(HWND aHwnd)
       
   272 	{
       
   273 	TInt i;
       
   274 	for (i=0;i<CDebugOsbWin::iId;++i)
       
   275 		{
       
   276 		if (*(TheWindow[i])==aHwnd)
       
   277 			return TheBitmap[i];
       
   278 		}
       
   279 	return NULL;
       
   280 	}
       
   281 
       
   282 TInt32 APIENTRY WindowProc(HWND aHwnd,TUint aMsg,TUint aWparam,TInt32 aLparam)
       
   283 	{
       
   284 	switch (aMsg)
       
   285 		{
       
   286 		case WM_PAINT:
       
   287 			{
       
   288 			HBITMAP* hBitmap=GetBitmap(aHwnd);
       
   289 			if (hBitmap)
       
   290 				{
       
   291 				PAINTSTRUCT p;
       
   292 				BeginPaint(aHwnd,&p);
       
   293 		   		HDC hdcBits;
       
   294 				BITMAP bm;
       
   295 	    		hdcBits=CreateCompatibleDC(p.hdc);
       
   296 				GetObject(*hBitmap,sizeof(BITMAP),&bm);
       
   297 	    		SelectObject(hdcBits,*hBitmap);
       
   298 				RECT windowRect;
       
   299 				GetClientRect(aHwnd,&windowRect);
       
   300 				BitBlt(p.hdc,0,0,windowRect.right-windowRect.left,windowRect.bottom-windowRect.top,hdcBits,0,0,SRCCOPY);
       
   301 				DeleteDC(hdcBits);
       
   302 	 			EndPaint(aHwnd,&p);
       
   303 				}
       
   304 			}
       
   305 			return 0;
       
   306 		case WMA_RESIZE:
       
   307 			{
       
   308 			RECT rc;
       
   309 			GetWindowRect(aHwnd, &rc);
       
   310 			MoveWindow(aHwnd, rc.left, rc.top, aWparam, aLparam, TRUE);
       
   311 			}
       
   312 			break;
       
   313 		default:
       
   314 			return DefWindowProc(aHwnd,aMsg,aWparam,aLparam);
       
   315 		}
       
   316 	return 1;
       
   317 	}
       
   318 
       
   319 TInt CDebugOsbWin::ThreadMain(TAny* aArg)
       
   320     {
       
   321     CDebugOsbWin* self=(CDebugOsbWin*)aArg;
       
   322     if (!self || !self->iWin32)
       
   323     	return KErrArgument;
       
   324     TWin32Info* win32=self->iWin32;
       
   325     TSize size=self->iSize;
       
   326     WNDCLASS wndclass;
       
   327     const TText *szAppName=self->iName.Ptr();
       
   328     wndclass.style=CS_HREDRAW|CS_VREDRAW;
       
   329     wndclass.lpfnWndProc=WindowProc;
       
   330     wndclass.cbClsExtra=0;
       
   331     wndclass.cbWndExtra=0;
       
   332     wndclass.hInstance=NULL;
       
   333     wndclass.hIcon=LoadIcon(NULL, IDI_APPLICATION);
       
   334     wndclass.hCursor=LoadCursor(NULL, IDC_ARROW);
       
   335     wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
       
   336     wndclass.lpszMenuName=NULL;
       
   337     wndclass.lpszClassName=(LPCTSTR)szAppName;
       
   338 	self->iHExtra = GetSystemMetrics(SM_CXFIXEDFRAME) * 2;
       
   339 	self->iVExtra = GetSystemMetrics(SM_CYFIXEDFRAME) * 2 + GetSystemMetrics(SM_CYCAPTION);
       
   340     RegisterClass(&wndclass);
       
   341 	win32->iHwnd=CreateWindow((LPCTSTR)szAppName,
       
   342                     (LPCTSTR)szAppName,
       
   343                     WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
       
   344                     CW_USEDEFAULT,
       
   345                     (CDebugOsbWin::iId-1)*(size.iHeight+30),
       
   346                     size.iWidth+self->iHExtra,
       
   347                     size.iHeight+self->iVExtra,
       
   348                     NULL,
       
   349                     NULL,
       
   350                     NULL,
       
   351                     NULL);
       
   352     ShowWindow(win32->iHwnd, SW_SHOWNORMAL);
       
   353     UpdateWindow(win32->iHwnd);
       
   354 	// Now ConstructL can continue with ready to use HWND
       
   355 	self->iSem.Signal();
       
   356 	MSG msg;
       
   357 	// Can't use normal win32 loop. Theoritically, GetMessage with specific HWND param should do, but
       
   358 	// somehow it's still messing emulator main message loop.
       
   359 	// The standard win32 loop in debug log to window (deblogwn.cpp) doesn't  seem to work on 9.1
       
   360 	while (1)
       
   361 		{
       
   362 		if (PeekMessage(&msg,win32->iHwnd,0,0,PM_REMOVE))
       
   363 			DispatchMessage(&msg);
       
   364 		User::After(300*1000);
       
   365 		}
       
   366 	return KErrNone;
       
   367     }