First public contribution.
1 // Copyright (c) 1995-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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // code for the Windows-dependent derived class
18 #include "../SERVER/w32cmd.h"
26 // static container for sharing data between Symbian & Windows threads
29 RSemaphore iStartSemaphore;
33 static struct TSharedMemory GSharedMemory;
36 enum TWindowsUserMessage
43 const int KMaxLogLines = 1000;
44 const int KAverageLogLineLength = 60;
45 const int KWinTimerId = 1;
48 EXPORT_C CDebugLogBase *CreateDebugLog(TBool aIsFirst, TDesC &aParams)
50 CDebugLogWin *device=new(ELeave) CDebugLogWin();
52 TRAPD(err,log=new(ELeave) CDebugLog(device));
58 TRAP(err,log->ConstructL(aIsFirst, aParams));
67 CDebugLogWin::CDebugLogWin() :iThreadCreated(EFalse)
70 CDebugLogWin::~CDebugLogWin()
74 if (GSharedMemory.iHwnd)
76 PostMessage(GSharedMemory.iHwnd, WM_CLOSE, 0, 0);
80 GSharedMemory.iStartSemaphore.Close();
84 void CDebugLogWin::ConstructL(TBool , TDesC &)
86 _LIT(KLog,"DebugLog");
87 GSharedMemory.iStartSemaphore.CreateLocal(0);
88 User::LeaveIfError(iThread.Create(KLog,logWinMain,KDefaultStackSize,KHeapSize,KHeapSize,(TAny *)123));
91 GSharedMemory.iStartSemaphore.Wait();
94 void CDebugLogWin::WriteToLogL(const TDesC &aDes, const TDesC &aDes2)
96 TBuf<LogTBufSize*2+1> bufPlusZero;
97 bufPlusZero.Copy(iTextBuf);
98 bufPlusZero.Append(aDes);
99 bufPlusZero.ZeroTerminate();
100 TInt32 bufferAddr = (TInt32)(bufPlusZero.Ptr());
101 // synchronously transfer string to debug window
103 SendMessage(GSharedMemory.iHwnd, WM_USER + EAppendText16, 0, bufferAddr);
105 iTextBuf.Copy(aDes2);
108 void CDebugLogWin::WriteToLog8L(const TDesC8 &aDes, const TDesC8 &aDes2)
110 TBuf8<LogTBufSize*2+1> bufPlusZero;
111 bufPlusZero.Copy(iTextBuf);
112 bufPlusZero.Append(aDes);
113 bufPlusZero.ZeroTerminate();
114 TInt32 bufferAddr = (TInt32)(bufPlusZero.Ptr());
115 // synchronously transfer string to debug window
117 SendMessage(GSharedMemory.iHwnd, WM_USER + EAppendText8, 0, bufferAddr);
119 iTextBuf.Copy(aDes2);
122 TInt32 __stdcall WndProc(struct HWND__ *aHwnd, TUint aMessage,
123 TUint wParam, TInt32 lParam)
125 static HWND hWndListBox;
127 static TBool timerSet = EFalse;
132 { // Disable Close menu option
133 HMENU menu = GetSystemMenu(aHwnd, FALSE);
134 EnableMenuItem(menu, SC_CLOSE, MF_BYCOMMAND|MF_GRAYED);
136 // create fixed pitch font for debug log
138 if (GetObject(hfont, sizeof(lf), &lf))
140 lf.lfPitchAndFamily = FIXED_PITCH;
141 lstrcpy(lf.lfFaceName, L"courier");
142 hfont = CreateFontIndirect(&lf);
146 hfont = CreateFont(16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
147 OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH, L"courier");
150 HINSTANCE hinstance = ((LPCREATESTRUCT) lParam) -> hInstance;
151 SendMessage(aHwnd, WM_SETFONT, (WPARAM) (hfont), 0);
153 GetClientRect(aHwnd, &clientRect);
155 hWndListBox = CreateWindowEx(WS_EX_CLIENTEDGE,
158 WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | WS_BORDER | LBS_NOINTEGRALHEIGHT,
160 clientRect.right, clientRect.bottom,
161 aHwnd, (HMENU) 1, hinstance, NULL);
162 SendMessage(hWndListBox, WM_SETFONT, (WPARAM) (hfont), 0);
164 // preallocate string memory
165 SendMessage(hWndListBox, LB_INITSTORAGE, KMaxLogLines + 20, KAverageLogLineLength);
169 case WM_USER+EAppendText16:
170 { // send wide char string to ListBox
171 int numRows = SendMessageW(hWndListBox, LB_ADDSTRING, 0, lParam);
172 // if too many lines set a timer to delete some lines
173 if (!timerSet && (numRows > KMaxLogLines) )
174 { // set a timer for 2s
175 SetTimer(aHwnd, KWinTimerId, 2000, NULL);
179 // scroll ListBox so that newest line is visible
180 SendMessage(hWndListBox, LB_SETTOPINDEX, numRows, 0);
184 case WM_USER+EAppendText8:
185 { // send narrow character string to ListBox
186 int numRows = SendMessageA(hWndListBox, LB_ADDSTRING, 0, lParam);
187 // if too many lines set a timer to delete some lines
188 if (!timerSet && (numRows > KMaxLogLines) )
189 { // set a timer for 2s
190 SetTimer(aHwnd, KWinTimerId, 2000, NULL);
194 // scroll ListBox so that newest line is visible
195 SendMessage(hWndListBox, LB_SETTOPINDEX, numRows, 0);
200 { // too many rows in listbox, release some memory
204 numRows = SendMessage(hWndListBox, LB_DELETESTRING, 0, 0);
206 while (numRows > KMaxLogLines);
207 KillTimer(aHwnd, KWinTimerId);
210 // ensure newest line is visible (delete moves focus to line 0)
211 SendMessage(hWndListBox, LB_SETTOPINDEX, numRows-1, 0);
216 // forward to the ListBox, and make it repaint
217 if ( (wParam == SIZE_MAXIMIZED) || (wParam == SIZE_RESTORED) )
219 int width = LOWORD(lParam);
220 int height = HIWORD(lParam);
221 MoveWindow(hWndListBox, 0, 0, width, height, TRUE);
231 if (wParam == SC_CLOSE)
232 { // do not allow window to be closed with ALT-F4 (this would close the emulator)
238 return DefWindowProc(aHwnd, aMessage, wParam, lParam);
241 TInt logWinMain(TAny *)
245 const TText *szAppName=_S("Window Server Log");
247 wndclass.style=CS_HREDRAW|CS_VREDRAW;
248 wndclass.lpfnWndProc=WndProc;
249 wndclass.cbClsExtra=0;
250 wndclass.cbWndExtra=0;
251 wndclass.hInstance=NULL;
252 wndclass.hIcon=LoadIcon(NULL, IDI_APPLICATION);
253 wndclass.hCursor=LoadCursor(NULL, IDC_ARROW);
254 wndclass.hbrBackground=(HBRUSH)GetSysColorBrush(COLOR_BTNFACE);
255 wndclass.lpszMenuName=NULL;
256 wndclass.lpszClassName=(LPCTSTR)szAppName;
258 RegisterClass(&wndclass);
260 GSharedMemory.iHwnd = CreateWindow((LPCTSTR)szAppName,
272 ShowWindow(GSharedMemory.iHwnd, SW_SHOWMINNOACTIVE);
274 GSharedMemory.iStartSemaphore.Signal(); // allows logging to start now that the window, etc. has been set up
276 // Must remove thread from Symbian scheduler before calling blocking Windows APIs (e.g. GetMessage)
278 while (GetMessage(&msg, NULL, 0, 0))
280 TranslateMessage(&msg);
281 DispatchMessage(&msg);
283 // return to Symbian Scheduler
285 GSharedMemory.iHwnd = NULL;