mpr: Tweak a label so it matches the one in wininet.
[wine/multimedia.git] / programs / taskmgr / graph.c
blob859624e44e92dd35999eb5524bab26e5d38c279f
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 <winnt.h>
31 #include "wine/unicode.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 WCHAR Text[256];
48 ULONG CpuUsage;
49 ULONG CpuKernelUsage;
50 int nBars;
51 int nBarsUsed;
52 /* Bottom bars that are "used", i.e. are bright green, representing used cpu time */
53 int nBarsUsedKernel;
54 /* Bottom bars that are "used", i.e. are bright green, representing used cpu kernel time */
55 int nBarsFree;
56 /* Top bars that are "unused", i.e. are dark green, representing free cpu time */
57 int i;
59 static const WCHAR wszFormatI[] = {'%','d','%','%',0};
60 static const WCHAR wszFormatII[] = {' ',' ','%','d','%','%',0};
61 static const WCHAR wszFormatIII[] = {' ','%','d','%','%',0};
64 * Get the client area rectangle
66 GetClientRect(hWnd, &rcClient);
69 * Fill it with blackness
71 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));
74 * Get the CPU usage
76 CpuUsage = PerfDataGetProcessorUsage();
77 CpuKernelUsage = PerfDataGetProcessorSystemUsage();
80 * Check and see how many digits it will take
81 * so we get the indentation right every time.
83 if (CpuUsage == 100)
85 sprintfW(Text, wszFormatI, (int)CpuUsage);
87 else if (CpuUsage < 10)
89 sprintfW(Text, wszFormatII, (int)CpuUsage);
91 else
93 sprintfW(Text, wszFormatIII, (int)CpuUsage);
97 * Draw the font text onto the graph
98 * The bottom 20 pixels are reserved for the text
100 Font_DrawText(hDC, Text, ((rcClient.right - rcClient.left) - 32) / 2, rcClient.bottom - 11 - 5);
103 * Now we have to draw the graph
104 * So first find out how many bars we can fit
106 nBars = ((rcClient.bottom - rcClient.top) - 25) / 3;
107 nBarsUsed = (nBars * CpuUsage) / 100;
108 if ((CpuUsage) && (nBarsUsed == 0))
110 nBarsUsed = 1;
112 nBarsFree = nBars - nBarsUsed;
113 if (TaskManagerSettings.ShowKernelTimes)
115 nBarsUsedKernel = ((nBars * 2) * CpuKernelUsage) / 100;
116 nBarsUsed -= (nBarsUsedKernel / 2);
118 else
120 nBarsUsedKernel = 0;
124 * Now draw the bar graph
126 rcBarLeft.left = ((rcClient.right - rcClient.left) - 33) / 2;
127 rcBarLeft.right = rcBarLeft.left + 16;
128 rcBarRight.left = rcBarLeft.left + 17;
129 rcBarRight.right = rcBarLeft.right + 17;
130 rcBarLeft.top = rcBarRight.top = 5;
131 rcBarLeft.bottom = rcBarRight.bottom = 7;
133 if (nBarsUsed < 0) nBarsUsed = 0;
134 if (nBarsUsed > nBars) nBarsUsed = nBars;
136 if (nBarsFree < 0) nBarsFree = 0;
137 if (nBarsFree > nBars) nBarsFree = nBars;
139 if (nBarsUsedKernel < 0) nBarsUsedKernel = 0;
140 if (nBarsUsedKernel > nBars) nBarsUsedKernel = nBars;
143 * Draw the "free" bars
145 for (i=0; i<nBarsFree; i++)
147 FillSolidRect(hDC, &rcBarLeft, DARK_GREEN);
148 FillSolidRect(hDC, &rcBarRight, DARK_GREEN);
150 rcBarLeft.top += 3;
151 rcBarLeft.bottom += 3;
153 rcBarRight.top += 3;
154 rcBarRight.bottom += 3;
158 * Draw the "used" bars
160 for (i=0; i<nBarsUsed; i++)
162 if (nBarsUsed > 5000) nBarsUsed = 5000;
164 FillSolidRect(hDC, &rcBarLeft, BRIGHT_GREEN);
165 FillSolidRect(hDC, &rcBarRight, BRIGHT_GREEN);
167 rcBarLeft.top += 3;
168 rcBarLeft.bottom += 3;
170 rcBarRight.top += 3;
171 rcBarRight.bottom += 3;
175 * Draw the "used" kernel bars
177 rcBarLeft.bottom--;
178 rcBarRight.bottom--;
179 if (nBarsUsedKernel && nBarsUsedKernel % 2)
181 rcBarLeft.top -= 2;
182 rcBarLeft.bottom -= 2;
184 rcBarRight.top -= 2;
185 rcBarRight.bottom -= 2;
187 FillSolidRect(hDC, &rcBarLeft, RED);
188 FillSolidRect(hDC, &rcBarRight, RED);
190 rcBarLeft.top += 2;
191 rcBarLeft.bottom += 2;
193 rcBarRight.top += 2;
194 rcBarRight.bottom += 2;
196 nBarsUsedKernel--;
198 for (i=0; i<nBarsUsedKernel; i++)
200 if (nBarsUsedKernel > 5000) nBarsUsedKernel = 5000;
202 FillSolidRect(hDC, &rcBarLeft, RED);
203 FillSolidRect(hDC, &rcBarRight, RED);
205 rcBarLeft.top++;
206 rcBarLeft.bottom++;
208 rcBarRight.top++;
209 rcBarRight.bottom++;
211 if (i % 2)
213 rcBarLeft.top++;
214 rcBarLeft.bottom++;
216 rcBarRight.top++;
217 rcBarRight.bottom++;
222 static void Graph_DrawMemUsageGraph(HDC hDC, HWND hWnd)
224 RECT rcClient;
225 RECT rcBarLeft;
226 RECT rcBarRight;
227 WCHAR Text[256];
228 ULONGLONG CommitChargeTotal;
229 ULONGLONG CommitChargeLimit;
230 int nBars;
231 int nBarsUsed = 0;
232 /* Bottom bars that are "used", i.e. are bright green, representing used memory */
233 int nBarsFree;
234 /* Top bars that are "unused", i.e. are dark green, representing free memory */
235 int i;
237 static const WCHAR wszFormat[] = {'%','d','K',0};
240 * Get the client area rectangle
242 GetClientRect(hWnd, &rcClient);
245 * Fill it with blackness
247 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));
250 * Get the memory usage
252 CommitChargeTotal = (ULONGLONG)PerfDataGetCommitChargeTotalK();
253 CommitChargeLimit = (ULONGLONG)PerfDataGetCommitChargeLimitK();
255 sprintfW(Text, wszFormat, (int)CommitChargeTotal);
258 * Draw the font text onto the graph
259 * The bottom 20 pixels are reserved for the text
261 Font_DrawText(hDC, Text, ((rcClient.right - rcClient.left) - (strlenW(Text) * 8)) / 2, rcClient.bottom - 11 - 5);
264 * Now we have to draw the graph
265 * So first find out how many bars we can fit
267 nBars = ((rcClient.bottom - rcClient.top) - 25) / 3;
268 if (CommitChargeLimit)
269 nBarsUsed = (nBars * (int)((CommitChargeTotal * 100) / CommitChargeLimit)) / 100;
270 nBarsFree = nBars - nBarsUsed;
272 if (nBarsUsed < 0) nBarsUsed = 0;
273 if (nBarsUsed > nBars) nBarsUsed = nBars;
275 if (nBarsFree < 0) nBarsFree = 0;
276 if (nBarsFree > nBars) nBarsFree = nBars;
279 * Now draw the bar graph
281 rcBarLeft.left = ((rcClient.right - rcClient.left) - 33) / 2;
282 rcBarLeft.right = rcBarLeft.left + 16;
283 rcBarRight.left = rcBarLeft.left + 17;
284 rcBarRight.right = rcBarLeft.right + 17;
285 rcBarLeft.top = rcBarRight.top = 5;
286 rcBarLeft.bottom = rcBarRight.bottom = 7;
289 * Draw the "free" bars
291 for (i=0; i<nBarsFree; i++)
293 FillSolidRect(hDC, &rcBarLeft, DARK_GREEN);
294 FillSolidRect(hDC, &rcBarRight, DARK_GREEN);
296 rcBarLeft.top += 3;
297 rcBarLeft.bottom += 3;
299 rcBarRight.top += 3;
300 rcBarRight.bottom += 3;
304 * Draw the "used" bars
306 for (i=0; i<nBarsUsed; i++)
308 FillSolidRect(hDC, &rcBarLeft, BRIGHT_GREEN);
309 FillSolidRect(hDC, &rcBarRight, BRIGHT_GREEN);
311 rcBarLeft.top += 3;
312 rcBarLeft.bottom += 3;
314 rcBarRight.top += 3;
315 rcBarRight.bottom += 3;
319 static void Graph_DrawMemUsageHistoryGraph(HDC hDC, HWND hWnd)
321 RECT rcClient;
322 int i;
323 static int offset = 0;
325 if (offset++ >= 10)
326 offset = 0;
329 * Get the client area rectangle
331 GetClientRect(hWnd, &rcClient);
334 * Fill it with blackness
336 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));
339 * Draw the graph background
341 * Draw the horizontal bars
343 for (i=0; i<rcClient.bottom; i++)
345 if ((i % 11) == 0)
347 /* FillSolidRect2(hDC, 0, i, rcClient.right, 1, DARK_GREEN); */
351 * Draw the vertical bars
353 for (i=11; i<rcClient.right + offset; i++)
355 if ((i % 11) == 0)
357 /* FillSolidRect2(hDC, i - offset, 0, 1, rcClient.bottom, DARK_GREEN); */
362 * Draw the memory usage
364 for (i=rcClient.right; i>=0; i--)
369 INT_PTR CALLBACK
370 Graph_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
372 HDC hdc;
373 PAINTSTRUCT ps;
374 LONG WindowId;
376 switch (message)
378 case WM_ERASEBKGND:
379 return TRUE;
382 * Filter out mouse & keyboard messages
384 /* case WM_APPCOMMAND: */
385 case WM_CAPTURECHANGED:
386 case WM_LBUTTONDBLCLK:
387 case WM_LBUTTONDOWN:
388 case WM_LBUTTONUP:
389 case WM_MBUTTONDBLCLK:
390 case WM_MBUTTONDOWN:
391 case WM_MBUTTONUP:
392 case WM_MOUSEACTIVATE:
393 case WM_MOUSEHOVER:
394 case WM_MOUSELEAVE:
395 case WM_MOUSEMOVE:
396 /* case WM_MOUSEWHEEL: */
397 case WM_NCHITTEST:
398 case WM_NCLBUTTONDBLCLK:
399 case WM_NCLBUTTONDOWN:
400 case WM_NCLBUTTONUP:
401 case WM_NCMBUTTONDBLCLK:
402 case WM_NCMBUTTONDOWN:
403 case WM_NCMBUTTONUP:
404 /* case WM_NCMOUSEHOVER: */
405 /* case WM_NCMOUSELEAVE: */
406 case WM_NCMOUSEMOVE:
407 case WM_NCRBUTTONDBLCLK:
408 case WM_NCRBUTTONDOWN:
409 case WM_NCRBUTTONUP:
410 /* case WM_NCXBUTTONDBLCLK: */
411 /* case WM_NCXBUTTONDOWN: */
412 /* case WM_NCXBUTTONUP: */
413 case WM_RBUTTONDBLCLK:
414 case WM_RBUTTONDOWN:
415 case WM_RBUTTONUP:
416 /* case WM_XBUTTONDBLCLK: */
417 /* case WM_XBUTTONDOWN: */
418 /* case WM_XBUTTONUP: */
419 case WM_ACTIVATE:
420 case WM_CHAR:
421 case WM_DEADCHAR:
422 case WM_GETHOTKEY:
423 case WM_HOTKEY:
424 case WM_KEYDOWN:
425 case WM_KEYUP:
426 case WM_KILLFOCUS:
427 case WM_SETFOCUS:
428 case WM_SETHOTKEY:
429 case WM_SYSCHAR:
430 case WM_SYSDEADCHAR:
431 case WM_SYSKEYDOWN:
432 case WM_SYSKEYUP:
434 case WM_NCCALCSIZE:
435 return 0;
437 case WM_PAINT:
439 hdc = BeginPaint(hWnd, &ps);
441 WindowId = GetWindowLongPtrW(hWnd, GWLP_ID);
443 switch (WindowId)
445 case IDC_CPU_USAGE_GRAPH:
446 Graph_DrawCpuUsageGraph(hdc, hWnd);
447 break;
448 case IDC_MEM_USAGE_GRAPH:
449 Graph_DrawMemUsageGraph(hdc, hWnd);
450 break;
451 case IDC_MEM_USAGE_HISTORY_GRAPH:
452 Graph_DrawMemUsageHistoryGraph(hdc, hWnd);
453 break;
456 EndPaint(hWnd, &ps);
458 return 0;
463 * We pass on all non-handled messages
465 return CallWindowProcW(OldGraphWndProc, hWnd, message, wParam, lParam);