gdi/tests: Don't use sizeof in ok() to avoid printf format warnings.
[wine.git] / programs / taskmgr / graph.c
blob1797010392942382fca15e8dd35795dd68c64231
1 /*
2 * ReactOS Task Manager
4 * graph.c
6 * Copyright (C) 1999 - 2001 Brian Palmer <brianp@reactos.org>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */
24 #include <windows.h>
25 #include <commctrl.h>
26 #include <stdlib.h>
27 #include <malloc.h>
28 #include <memory.h>
29 #include <tchar.h>
30 #include <stdio.h>
31 #include <winnt.h>
33 #include "taskmgr.h"
34 #include "perfdata.h"
36 #define BRIGHT_GREEN RGB(0, 255, 0)
37 #define DARK_GREEN RGB(0, 130, 0)
38 #define RED RGB(255, 0, 0)
41 WNDPROC OldGraphWndProc;
43 static void Graph_DrawCpuUsageGraph(HDC hDC, HWND hWnd)
45 RECT rcClient;
46 RECT rcBarLeft;
47 RECT rcBarRight;
48 TCHAR Text[260];
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;
61 * Get the client area rectangle
63 GetClientRect(hWnd, &rcClient);
66 * Fill it with blackness
68 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));
71 * Get the CPU usage
73 CpuUsage = PerfDataGetProcessorUsage();
74 CpuKernelUsage = PerfDataGetProcessorSystemUsage();
75 if (CpuUsage < 0) CpuUsage = 0;
76 if (CpuUsage > 100) CpuUsage = 100;
77 if (CpuKernelUsage < 0) CpuKernelUsage = 0;
78 if (CpuKernelUsage > 100) CpuKernelUsage = 100;
81 * Check and see how many digits it will take
82 * so we get the indentation right every time.
84 if (CpuUsage == 100)
86 _stprintf(Text, _T("%d%%"), (int)CpuUsage);
88 else if (CpuUsage < 10)
90 _stprintf(Text, _T(" %d%%"), (int)CpuUsage);
92 else
94 _stprintf(Text, _T(" %d%%"), (int)CpuUsage);
98 * Draw the font text onto the graph
99 * The bottom 20 pixels are reserved for the text
101 Font_DrawText(hDC, Text, ((rcClient.right - rcClient.left) - 32) / 2, rcClient.bottom - 11 - 5);
104 * Now we have to draw the graph
105 * So first find out how many bars we can fit
107 nBars = ((rcClient.bottom - rcClient.top) - 25) / 3;
108 nBarsUsed = (nBars * CpuUsage) / 100;
109 if ((CpuUsage) && (nBarsUsed == 0))
111 nBarsUsed = 1;
113 nBarsFree = nBars - nBarsUsed;
114 if (TaskManagerSettings.ShowKernelTimes)
116 nBarsUsedKernel = ((nBars * 2) * CpuKernelUsage) / 100;
117 nBarsUsed -= (nBarsUsedKernel / 2);
119 else
121 nBarsUsedKernel = 0;
125 * Now draw the bar graph
127 rcBarLeft.left = ((rcClient.right - rcClient.left) - 33) / 2;
128 rcBarLeft.right = rcBarLeft.left + 16;
129 rcBarRight.left = rcBarLeft.left + 17;
130 rcBarRight.right = rcBarLeft.right + 17;
131 rcBarLeft.top = rcBarRight.top = 5;
132 rcBarLeft.bottom = rcBarRight.bottom = 7;
134 if (nBarsUsed < 0) nBarsUsed = 0;
135 if (nBarsUsed > nBars) nBarsUsed = nBars;
137 if (nBarsFree < 0) nBarsFree = 0;
138 if (nBarsFree > nBars) nBarsFree = nBars;
140 if (nBarsUsedKernel < 0) nBarsUsedKernel = 0;
141 if (nBarsUsedKernel > nBars) nBarsUsedKernel = nBars;
144 * Draw the "free" bars
146 for (i=0; i<nBarsFree; i++)
148 FillSolidRect(hDC, &rcBarLeft, DARK_GREEN);
149 FillSolidRect(hDC, &rcBarRight, DARK_GREEN);
151 rcBarLeft.top += 3;
152 rcBarLeft.bottom += 3;
154 rcBarRight.top += 3;
155 rcBarRight.bottom += 3;
159 * Draw the "used" bars
161 for (i=0; i<nBarsUsed; i++)
163 if (nBarsUsed > 5000) nBarsUsed = 5000;
165 FillSolidRect(hDC, &rcBarLeft, BRIGHT_GREEN);
166 FillSolidRect(hDC, &rcBarRight, BRIGHT_GREEN);
168 rcBarLeft.top += 3;
169 rcBarLeft.bottom += 3;
171 rcBarRight.top += 3;
172 rcBarRight.bottom += 3;
176 * Draw the "used" kernel bars
178 rcBarLeft.bottom--;
179 rcBarRight.bottom--;
180 if (nBarsUsedKernel && nBarsUsedKernel % 2)
182 rcBarLeft.top -= 2;
183 rcBarLeft.bottom -= 2;
185 rcBarRight.top -= 2;
186 rcBarRight.bottom -= 2;
188 FillSolidRect(hDC, &rcBarLeft, RED);
189 FillSolidRect(hDC, &rcBarRight, RED);
191 rcBarLeft.top += 2;
192 rcBarLeft.bottom += 2;
194 rcBarRight.top += 2;
195 rcBarRight.bottom += 2;
197 nBarsUsedKernel--;
199 for (i=0; i<nBarsUsedKernel; i++)
201 if (nBarsUsedKernel > 5000) nBarsUsedKernel = 5000;
203 FillSolidRect(hDC, &rcBarLeft, RED);
204 FillSolidRect(hDC, &rcBarRight, RED);
206 rcBarLeft.top++;
207 rcBarLeft.bottom++;
209 rcBarRight.top++;
210 rcBarRight.bottom++;
212 if (i % 2)
214 rcBarLeft.top++;
215 rcBarLeft.bottom++;
217 rcBarRight.top++;
218 rcBarRight.bottom++;
223 static void Graph_DrawMemUsageGraph(HDC hDC, HWND hWnd)
225 RECT rcClient;
226 RECT rcBarLeft;
227 RECT rcBarRight;
228 TCHAR Text[260];
229 ULONGLONG CommitChargeTotal;
230 ULONGLONG CommitChargeLimit;
231 int nBars;
232 int nBarsUsed = 0;
233 /* Bottom bars that are "used", i.e. are bright green, representing used memory */
234 int nBarsFree;
235 /* Top bars that are "unused", i.e. are dark green, representing free memory */
236 int i;
239 * Get the client area rectangle
241 GetClientRect(hWnd, &rcClient);
244 * Fill it with blackness
246 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));
249 * Get the memory usage
251 CommitChargeTotal = (ULONGLONG)PerfDataGetCommitChargeTotalK();
252 CommitChargeLimit = (ULONGLONG)PerfDataGetCommitChargeLimitK();
254 _stprintf(Text, _T("%dK"), (int)CommitChargeTotal);
257 * Draw the font text onto the graph
258 * The bottom 20 pixels are reserved for the text
260 Font_DrawText(hDC, Text, ((rcClient.right - rcClient.left) - (_tcslen(Text) * 8)) / 2, rcClient.bottom - 11 - 5);
263 * Now we have to draw the graph
264 * So first find out how many bars we can fit
266 nBars = ((rcClient.bottom - rcClient.top) - 25) / 3;
267 if (CommitChargeLimit)
268 nBarsUsed = (nBars * (int)((CommitChargeTotal * 100) / CommitChargeLimit)) / 100;
269 nBarsFree = nBars - nBarsUsed;
271 if (nBarsUsed < 0) nBarsUsed = 0;
272 if (nBarsUsed > nBars) nBarsUsed = nBars;
274 if (nBarsFree < 0) nBarsFree = 0;
275 if (nBarsFree > nBars) nBarsFree = nBars;
278 * Now draw the bar graph
280 rcBarLeft.left = ((rcClient.right - rcClient.left) - 33) / 2;
281 rcBarLeft.right = rcBarLeft.left + 16;
282 rcBarRight.left = rcBarLeft.left + 17;
283 rcBarRight.right = rcBarLeft.right + 17;
284 rcBarLeft.top = rcBarRight.top = 5;
285 rcBarLeft.bottom = rcBarRight.bottom = 7;
288 * Draw the "free" bars
290 for (i=0; i<nBarsFree; i++)
292 FillSolidRect(hDC, &rcBarLeft, DARK_GREEN);
293 FillSolidRect(hDC, &rcBarRight, DARK_GREEN);
295 rcBarLeft.top += 3;
296 rcBarLeft.bottom += 3;
298 rcBarRight.top += 3;
299 rcBarRight.bottom += 3;
303 * Draw the "used" bars
305 for (i=0; i<nBarsUsed; i++)
307 FillSolidRect(hDC, &rcBarLeft, BRIGHT_GREEN);
308 FillSolidRect(hDC, &rcBarRight, BRIGHT_GREEN);
310 rcBarLeft.top += 3;
311 rcBarLeft.bottom += 3;
313 rcBarRight.top += 3;
314 rcBarRight.bottom += 3;
318 static void Graph_DrawMemUsageHistoryGraph(HDC hDC, HWND hWnd)
320 RECT rcClient;
321 ULONGLONG CommitChargeLimit;
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 * Get the memory usage
341 CommitChargeLimit = (ULONGLONG)PerfDataGetCommitChargeLimitK();
344 * Draw the graph background
346 * Draw the horizontal bars
348 for (i=0; i<rcClient.bottom; i++)
350 if ((i % 11) == 0)
352 /* FillSolidRect2(hDC, 0, i, rcClient.right, 1, DARK_GREEN); */
356 * Draw the vertical bars
358 for (i=11; i<rcClient.right + offset; i++)
360 if ((i % 11) == 0)
362 /* FillSolidRect2(hDC, i - offset, 0, 1, rcClient.bottom, DARK_GREEN); */
367 * Draw the memory usage
369 for (i=rcClient.right; i>=0; i--)
374 INT_PTR CALLBACK
375 Graph_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
377 HDC hdc;
378 PAINTSTRUCT ps;
379 LONG WindowId;
381 switch (message)
383 case WM_ERASEBKGND:
384 return TRUE;
387 * Filter out mouse & keyboard messages
389 /* case WM_APPCOMMAND: */
390 case WM_CAPTURECHANGED:
391 case WM_LBUTTONDBLCLK:
392 case WM_LBUTTONDOWN:
393 case WM_LBUTTONUP:
394 case WM_MBUTTONDBLCLK:
395 case WM_MBUTTONDOWN:
396 case WM_MBUTTONUP:
397 case WM_MOUSEACTIVATE:
398 case WM_MOUSEHOVER:
399 case WM_MOUSELEAVE:
400 case WM_MOUSEMOVE:
401 /* case WM_MOUSEWHEEL: */
402 case WM_NCHITTEST:
403 case WM_NCLBUTTONDBLCLK:
404 case WM_NCLBUTTONDOWN:
405 case WM_NCLBUTTONUP:
406 case WM_NCMBUTTONDBLCLK:
407 case WM_NCMBUTTONDOWN:
408 case WM_NCMBUTTONUP:
409 /* case WM_NCMOUSEHOVER: */
410 /* case WM_NCMOUSELEAVE: */
411 case WM_NCMOUSEMOVE:
412 case WM_NCRBUTTONDBLCLK:
413 case WM_NCRBUTTONDOWN:
414 case WM_NCRBUTTONUP:
415 /* case WM_NCXBUTTONDBLCLK: */
416 /* case WM_NCXBUTTONDOWN: */
417 /* case WM_NCXBUTTONUP: */
418 case WM_RBUTTONDBLCLK:
419 case WM_RBUTTONDOWN:
420 case WM_RBUTTONUP:
421 /* case WM_XBUTTONDBLCLK: */
422 /* case WM_XBUTTONDOWN: */
423 /* case WM_XBUTTONUP: */
424 case WM_ACTIVATE:
425 case WM_CHAR:
426 case WM_DEADCHAR:
427 case WM_GETHOTKEY:
428 case WM_HOTKEY:
429 case WM_KEYDOWN:
430 case WM_KEYUP:
431 case WM_KILLFOCUS:
432 case WM_SETFOCUS:
433 case WM_SETHOTKEY:
434 case WM_SYSCHAR:
435 case WM_SYSDEADCHAR:
436 case WM_SYSKEYDOWN:
437 case WM_SYSKEYUP:
439 case WM_NCCALCSIZE:
440 return 0;
442 case WM_PAINT:
444 hdc = BeginPaint(hWnd, &ps);
446 WindowId = GetWindowLongPtr(hWnd, GWLP_ID);
448 switch (WindowId)
450 case IDC_CPU_USAGE_GRAPH:
451 Graph_DrawCpuUsageGraph(hdc, hWnd);
452 break;
453 case IDC_MEM_USAGE_GRAPH:
454 Graph_DrawMemUsageGraph(hdc, hWnd);
455 break;
456 case IDC_MEM_USAGE_HISTORY_GRAPH:
457 Graph_DrawMemUsageHistoryGraph(hdc, hWnd);
458 break;
461 EndPaint(hWnd, &ps);
463 return 0;
468 * We pass on all non-handled messages
470 return CallWindowProc((WNDPROC)OldGraphWndProc, hWnd, message, wParam, lParam);