ntdll: Move the keyed event functions to the Unix library.
[wine.git] / programs / taskmgr / graph.c
blob12f2214566495032a5ddcdb7a2a07960908e79c2
1 /*
2 * ReactOS Task Manager
4 * graph.c
6 * Copyright (C) 1999 - 2001 Brian Palmer <brianp@reactos.org>
7 * Copyright (C) 2008 Vladimir Pankratov
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include <stdio.h>
25 #include <stdlib.h>
27 #include <windows.h>
28 #include <commctrl.h>
29 #include <shlwapi.h>
30 #include <winnt.h>
32 #include "taskmgr.h"
33 #include "perfdata.h"
35 #define BRIGHT_GREEN RGB(0, 255, 0)
36 #define DARK_GREEN RGB(0, 130, 0)
37 #define RED RGB(255, 0, 0)
40 WNDPROC OldGraphWndProc;
42 static void Graph_DrawCpuUsageGraph(HDC hDC, HWND hWnd)
44 RECT rcClient;
45 RECT rcBarLeft;
46 RECT rcBarRight;
47 RECT rcText;
48 WCHAR Text[256];
49 ULONG CpuUsage;
50 ULONG CpuKernelUsage;
51 int nBars;
52 int nBarsUsed;
53 /* Bottom bars that are "used", i.e. are bright green, representing used cpu time */
54 int nBarsUsedKernel;
55 /* Bottom bars that are "used", i.e. are bright green, representing used cpu kernel time */
56 int nBarsFree;
57 /* Top bars that are "unused", i.e. are dark green, representing free cpu time */
58 int i;
60 static const WCHAR wszFormatI[] = {'%','d','%','%',0};
61 static const WCHAR wszFormatII[] = {' ',' ','%','d','%','%',0};
62 static const WCHAR wszFormatIII[] = {' ','%','d','%','%',0};
65 * Get the client area rectangle
67 GetClientRect(hWnd, &rcClient);
70 * Fill it with blackness
72 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));
75 * Get the CPU usage
77 CpuUsage = PerfDataGetProcessorUsage();
78 CpuKernelUsage = PerfDataGetProcessorSystemUsage();
81 * Check and see how many digits it will take
82 * so we get the indentation right every time.
84 if (CpuUsage == 100)
86 swprintf(Text, ARRAY_SIZE(Text), wszFormatI, (int)CpuUsage);
88 else if (CpuUsage < 10)
90 swprintf(Text, ARRAY_SIZE(Text), wszFormatII, (int)CpuUsage);
92 else
94 swprintf(Text, ARRAY_SIZE(Text), wszFormatIII, (int)CpuUsage);
98 * Draw the font text onto the graph
99 * The bottom 20 pixels are reserved for the text
101 CopyRect(&rcText, &rcClient);
102 rcText.top = rcText.bottom - 19;
104 SetTextColor(hDC, BRIGHT_GREEN);
105 DrawTextW(hDC, Text, -1, &rcText, DT_CENTER);
108 * Now we have to draw the graph
109 * So first find out how many bars we can fit
111 nBars = ((rcClient.bottom - rcClient.top) - 25) / 3;
112 nBarsUsed = (nBars * CpuUsage) / 100;
113 if ((CpuUsage) && (nBarsUsed == 0))
115 nBarsUsed = 1;
117 nBarsFree = nBars - nBarsUsed;
118 if (TaskManagerSettings.ShowKernelTimes)
120 nBarsUsedKernel = ((nBars * 2) * CpuKernelUsage) / 100;
121 nBarsUsed -= (nBarsUsedKernel / 2);
123 else
125 nBarsUsedKernel = 0;
129 * Now draw the bar graph
131 rcBarLeft.left = ((rcClient.right - rcClient.left) - 33) / 2;
132 rcBarLeft.right = rcBarLeft.left + 16;
133 rcBarRight.left = rcBarLeft.left + 17;
134 rcBarRight.right = rcBarLeft.right + 17;
135 rcBarLeft.top = rcBarRight.top = 5;
136 rcBarLeft.bottom = rcBarRight.bottom = 7;
138 if (nBarsUsed < 0) nBarsUsed = 0;
139 if (nBarsUsed > nBars) nBarsUsed = nBars;
141 if (nBarsFree < 0) nBarsFree = 0;
142 if (nBarsFree > nBars) nBarsFree = nBars;
144 if (nBarsUsedKernel < 0) nBarsUsedKernel = 0;
145 if (nBarsUsedKernel > nBars) nBarsUsedKernel = nBars;
148 * Draw the "free" bars
150 for (i=0; i<nBarsFree; i++)
152 FillSolidRect(hDC, &rcBarLeft, DARK_GREEN);
153 FillSolidRect(hDC, &rcBarRight, DARK_GREEN);
155 rcBarLeft.top += 3;
156 rcBarLeft.bottom += 3;
158 rcBarRight.top += 3;
159 rcBarRight.bottom += 3;
163 * Draw the "used" bars
165 for (i=0; i<nBarsUsed; i++)
167 if (nBarsUsed > 5000) nBarsUsed = 5000;
169 FillSolidRect(hDC, &rcBarLeft, BRIGHT_GREEN);
170 FillSolidRect(hDC, &rcBarRight, BRIGHT_GREEN);
172 rcBarLeft.top += 3;
173 rcBarLeft.bottom += 3;
175 rcBarRight.top += 3;
176 rcBarRight.bottom += 3;
180 * Draw the "used" kernel bars
182 rcBarLeft.bottom--;
183 rcBarRight.bottom--;
184 if (nBarsUsedKernel && nBarsUsedKernel % 2)
186 rcBarLeft.top -= 2;
187 rcBarLeft.bottom -= 2;
189 rcBarRight.top -= 2;
190 rcBarRight.bottom -= 2;
192 FillSolidRect(hDC, &rcBarLeft, RED);
193 FillSolidRect(hDC, &rcBarRight, RED);
195 rcBarLeft.top += 2;
196 rcBarLeft.bottom += 2;
198 rcBarRight.top += 2;
199 rcBarRight.bottom += 2;
201 nBarsUsedKernel--;
203 for (i=0; i<nBarsUsedKernel; i++)
205 if (nBarsUsedKernel > 5000) nBarsUsedKernel = 5000;
207 FillSolidRect(hDC, &rcBarLeft, RED);
208 FillSolidRect(hDC, &rcBarRight, RED);
210 rcBarLeft.top++;
211 rcBarLeft.bottom++;
213 rcBarRight.top++;
214 rcBarRight.bottom++;
216 if (i % 2)
218 rcBarLeft.top++;
219 rcBarLeft.bottom++;
221 rcBarRight.top++;
222 rcBarRight.bottom++;
227 static void Graph_DrawMemUsageGraph(HDC hDC, HWND hWnd)
229 RECT rcClient;
230 RECT rcBarLeft;
231 RECT rcBarRight;
232 RECT rcText;
233 WCHAR Text[256];
234 ULONGLONG CommitChargeTotal;
235 ULONGLONG CommitChargeLimit;
236 int nBars;
237 int nBarsUsed = 0;
238 /* Bottom bars that are "used", i.e. are bright green, representing used memory */
239 int nBarsFree;
240 /* Top bars that are "unused", i.e. are dark green, representing free memory */
241 int i;
244 * Get the client area rectangle
246 GetClientRect(hWnd, &rcClient);
249 * Fill it with blackness
251 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));
254 * Get the memory usage
256 CommitChargeTotal = (ULONGLONG)PerfDataGetCommitChargeTotalK();
257 CommitChargeLimit = (ULONGLONG)PerfDataGetCommitChargeLimitK();
259 if (CommitChargeTotal < 1024)
260 StrFormatKBSizeW(CommitChargeTotal, Text, ARRAY_SIZE(Text));
261 else
262 StrFormatByteSizeW(CommitChargeTotal, Text, ARRAY_SIZE(Text));
265 * Draw the font text onto the graph
266 * The bottom 20 pixels are reserved for the text
268 CopyRect(&rcText, &rcClient);
269 rcText.top = rcText.bottom - 19;
271 SetTextColor(hDC, BRIGHT_GREEN);
272 DrawTextW(hDC, Text, -1, &rcText, DT_CENTER);
275 * Now we have to draw the graph
276 * So first find out how many bars we can fit
278 nBars = ((rcClient.bottom - rcClient.top) - 25) / 3;
279 if (CommitChargeLimit)
280 nBarsUsed = (nBars * (int)((CommitChargeTotal * 100) / CommitChargeLimit)) / 100;
281 nBarsFree = nBars - nBarsUsed;
283 if (nBarsUsed < 0) nBarsUsed = 0;
284 if (nBarsUsed > nBars) nBarsUsed = nBars;
286 if (nBarsFree < 0) nBarsFree = 0;
287 if (nBarsFree > nBars) nBarsFree = nBars;
290 * Now draw the bar graph
292 rcBarLeft.left = ((rcClient.right - rcClient.left) - 33) / 2;
293 rcBarLeft.right = rcBarLeft.left + 16;
294 rcBarRight.left = rcBarLeft.left + 17;
295 rcBarRight.right = rcBarLeft.right + 17;
296 rcBarLeft.top = rcBarRight.top = 5;
297 rcBarLeft.bottom = rcBarRight.bottom = 7;
300 * Draw the "free" bars
302 for (i=0; i<nBarsFree; i++)
304 FillSolidRect(hDC, &rcBarLeft, DARK_GREEN);
305 FillSolidRect(hDC, &rcBarRight, DARK_GREEN);
307 rcBarLeft.top += 3;
308 rcBarLeft.bottom += 3;
310 rcBarRight.top += 3;
311 rcBarRight.bottom += 3;
315 * Draw the "used" bars
317 for (i=0; i<nBarsUsed; i++)
319 FillSolidRect(hDC, &rcBarLeft, BRIGHT_GREEN);
320 FillSolidRect(hDC, &rcBarRight, BRIGHT_GREEN);
322 rcBarLeft.top += 3;
323 rcBarLeft.bottom += 3;
325 rcBarRight.top += 3;
326 rcBarRight.bottom += 3;
330 static void Graph_DrawMemUsageHistoryGraph(HDC hDC, HWND hWnd)
332 RECT rcClient;
333 int i;
334 static int offset = 0;
336 if (offset++ >= 10)
337 offset = 0;
340 * Get the client area rectangle
342 GetClientRect(hWnd, &rcClient);
345 * Fill it with blackness
347 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));
350 * Draw the graph background
352 * Draw the horizontal bars
354 for (i=0; i<rcClient.bottom; i++)
356 if ((i % 11) == 0)
358 /* FillSolidRect2(hDC, 0, i, rcClient.right, 1, DARK_GREEN); */
362 * Draw the vertical bars
364 for (i=11; i<rcClient.right + offset; i++)
366 if ((i % 11) == 0)
368 /* FillSolidRect2(hDC, i - offset, 0, 1, rcClient.bottom, DARK_GREEN); */
373 * Draw the memory usage
375 for (i=rcClient.right; i>=0; i--)
380 INT_PTR CALLBACK
381 Graph_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
383 HDC hdc;
384 PAINTSTRUCT ps;
385 LONG WindowId;
387 switch (message)
389 case WM_ERASEBKGND:
390 return TRUE;
393 * Filter out mouse & keyboard messages
395 /* case WM_APPCOMMAND: */
396 case WM_CAPTURECHANGED:
397 case WM_LBUTTONDBLCLK:
398 case WM_LBUTTONDOWN:
399 case WM_LBUTTONUP:
400 case WM_MBUTTONDBLCLK:
401 case WM_MBUTTONDOWN:
402 case WM_MBUTTONUP:
403 case WM_MOUSEACTIVATE:
404 case WM_MOUSEHOVER:
405 case WM_MOUSELEAVE:
406 case WM_MOUSEMOVE:
407 /* case WM_MOUSEWHEEL: */
408 case WM_NCHITTEST:
409 case WM_NCLBUTTONDBLCLK:
410 case WM_NCLBUTTONDOWN:
411 case WM_NCLBUTTONUP:
412 case WM_NCMBUTTONDBLCLK:
413 case WM_NCMBUTTONDOWN:
414 case WM_NCMBUTTONUP:
415 /* case WM_NCMOUSEHOVER: */
416 /* case WM_NCMOUSELEAVE: */
417 case WM_NCMOUSEMOVE:
418 case WM_NCRBUTTONDBLCLK:
419 case WM_NCRBUTTONDOWN:
420 case WM_NCRBUTTONUP:
421 /* case WM_NCXBUTTONDBLCLK: */
422 /* case WM_NCXBUTTONDOWN: */
423 /* case WM_NCXBUTTONUP: */
424 case WM_RBUTTONDBLCLK:
425 case WM_RBUTTONDOWN:
426 case WM_RBUTTONUP:
427 /* case WM_XBUTTONDBLCLK: */
428 /* case WM_XBUTTONDOWN: */
429 /* case WM_XBUTTONUP: */
430 case WM_ACTIVATE:
431 case WM_CHAR:
432 case WM_DEADCHAR:
433 case WM_GETHOTKEY:
434 case WM_HOTKEY:
435 case WM_KEYDOWN:
436 case WM_KEYUP:
437 case WM_KILLFOCUS:
438 case WM_SETFOCUS:
439 case WM_SETHOTKEY:
440 case WM_SYSCHAR:
441 case WM_SYSDEADCHAR:
442 case WM_SYSKEYDOWN:
443 case WM_SYSKEYUP:
445 case WM_NCCALCSIZE:
446 return 0;
448 case WM_PAINT:
450 hdc = BeginPaint(hWnd, &ps);
452 WindowId = GetWindowLongPtrW(hWnd, GWLP_ID);
454 switch (WindowId)
456 case IDC_CPU_USAGE_GRAPH:
457 Graph_DrawCpuUsageGraph(hdc, hWnd);
458 break;
459 case IDC_MEM_USAGE_GRAPH:
460 Graph_DrawMemUsageGraph(hdc, hWnd);
461 break;
462 case IDC_MEM_USAGE_HISTORY_GRAPH:
463 Graph_DrawMemUsageHistoryGraph(hdc, hWnd);
464 break;
467 EndPaint(hWnd, &ps);
469 return 0;
474 * We pass on all non-handled messages
476 return CallWindowProcW(OldGraphWndProc, hWnd, message, wParam, lParam);