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 + }