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