winewayland.drv: Implement vkEnumerateInstanceExtensionProperties.
[wine.git] / programs / taskmgr / graph.c
blob44522ddf3074a13fa50a076f924c0ff78bc3dd95
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)
38 #define BLACK RGB(0, 0, 0)
41 WNDPROC OldGraphWndProc;
43 static void Graph_DrawCpuUsageGraph(HDC hDC, HWND hWnd)
45 RECT rcClient;
46 RECT rcBarLeft;
47 RECT rcBarRight;
48 RECT rcText;
49 WCHAR Text[256];
50 ULONG CpuUsage;
51 ULONG CpuKernelUsage;
52 int nBars;
53 int nBarsUsed;
54 /* Bottom bars that are "used", i.e. are bright green, representing used cpu time */
55 int nBarsUsedKernel;
56 /* Bottom bars that are "used", i.e. are bright green, representing used cpu kernel time */
57 int nBarsFree;
58 /* Top bars that are "unused", i.e. are dark green, representing free cpu time */
59 int i;
61 static const WCHAR wszFormatI[] = {'%','d','%','%',0};
62 static const WCHAR wszFormatII[] = {' ',' ','%','d','%','%',0};
63 static const WCHAR wszFormatIII[] = {' ','%','d','%','%',0};
66 * Get the client area rectangle
68 GetClientRect(hWnd, &rcClient);
71 * Fill it with blackness
73 FillSolidRect(hDC, &rcClient, BLACK);
76 * Get the CPU usage
78 CpuUsage = PerfDataGetProcessorUsage();
79 CpuKernelUsage = PerfDataGetProcessorSystemUsage();
82 * Check and see how many digits it will take
83 * so we get the indentation right every time.
85 if (CpuUsage == 100)
87 swprintf(Text, ARRAY_SIZE(Text), wszFormatI, (int)CpuUsage);
89 else if (CpuUsage < 10)
91 swprintf(Text, ARRAY_SIZE(Text), wszFormatII, (int)CpuUsage);
93 else
95 swprintf(Text, ARRAY_SIZE(Text), wszFormatIII, (int)CpuUsage);
99 * Draw the font text onto the graph
100 * The bottom 20 pixels are reserved for the text
102 CopyRect(&rcText, &rcClient);
103 rcText.top = rcText.bottom - 19;
105 SetTextColor(hDC, BRIGHT_GREEN);
106 DrawTextW(hDC, Text, -1, &rcText, DT_CENTER);
109 * Now we have to draw the graph
110 * So first find out how many bars we can fit
112 nBars = ((rcClient.bottom - rcClient.top) - 25) / 3;
113 nBarsUsed = (nBars * CpuUsage) / 100;
114 if ((CpuUsage) && (nBarsUsed == 0))
116 nBarsUsed = 1;
118 nBarsFree = nBars - nBarsUsed;
119 if (TaskManagerSettings.ShowKernelTimes)
121 nBarsUsedKernel = ((nBars * 2) * CpuKernelUsage) / 100;
122 nBarsUsed -= (nBarsUsedKernel / 2);
124 else
126 nBarsUsedKernel = 0;
130 * Now draw the bar graph
132 rcBarLeft.left = ((rcClient.right - rcClient.left) - 33) / 2;
133 rcBarLeft.right = rcBarLeft.left + 16;
134 rcBarRight.left = rcBarLeft.left + 17;
135 rcBarRight.right = rcBarLeft.right + 17;
136 rcBarLeft.top = rcBarRight.top = 5;
137 rcBarLeft.bottom = rcBarRight.bottom = 7;
139 if (nBarsUsed < 0) nBarsUsed = 0;
140 if (nBarsUsed > nBars) nBarsUsed = nBars;
142 if (nBarsFree < 0) nBarsFree = 0;
143 if (nBarsFree > nBars) nBarsFree = nBars;
145 if (nBarsUsedKernel < 0) nBarsUsedKernel = 0;
146 if (nBarsUsedKernel > nBars) nBarsUsedKernel = nBars;
149 * Draw the "free" bars
151 for (i=0; i<nBarsFree; i++)
153 FillSolidRect(hDC, &rcBarLeft, DARK_GREEN);
154 FillSolidRect(hDC, &rcBarRight, DARK_GREEN);
156 rcBarLeft.top += 3;
157 rcBarLeft.bottom += 3;
159 rcBarRight.top += 3;
160 rcBarRight.bottom += 3;
164 * Draw the "used" bars
166 for (i=0; i<nBarsUsed; i++)
168 if (nBarsUsed > 5000) nBarsUsed = 5000;
170 FillSolidRect(hDC, &rcBarLeft, BRIGHT_GREEN);
171 FillSolidRect(hDC, &rcBarRight, BRIGHT_GREEN);
173 rcBarLeft.top += 3;
174 rcBarLeft.bottom += 3;
176 rcBarRight.top += 3;
177 rcBarRight.bottom += 3;
181 * Draw the "used" kernel bars
183 rcBarLeft.bottom--;
184 rcBarRight.bottom--;
185 if (nBarsUsedKernel && nBarsUsedKernel % 2)
187 rcBarLeft.top -= 2;
188 rcBarLeft.bottom -= 2;
190 rcBarRight.top -= 2;
191 rcBarRight.bottom -= 2;
193 FillSolidRect(hDC, &rcBarLeft, RED);
194 FillSolidRect(hDC, &rcBarRight, RED);
196 rcBarLeft.top += 2;
197 rcBarLeft.bottom += 2;
199 rcBarRight.top += 2;
200 rcBarRight.bottom += 2;
202 nBarsUsedKernel--;
204 for (i=0; i<nBarsUsedKernel; i++)
206 if (nBarsUsedKernel > 5000) nBarsUsedKernel = 5000;
208 FillSolidRect(hDC, &rcBarLeft, RED);
209 FillSolidRect(hDC, &rcBarRight, RED);
211 rcBarLeft.top++;
212 rcBarLeft.bottom++;
214 rcBarRight.top++;
215 rcBarRight.bottom++;
217 if (i % 2)
219 rcBarLeft.top++;
220 rcBarLeft.bottom++;
222 rcBarRight.top++;
223 rcBarRight.bottom++;
228 static void Graph_DrawMemUsageGraph(HDC hDC, HWND hWnd)
230 RECT rcClient;
231 RECT rcBarLeft;
232 RECT rcBarRight;
233 RECT rcText;
234 WCHAR Text[256];
235 ULONGLONG CommitChargeTotal;
236 ULONGLONG CommitChargeLimit;
237 int nBars;
238 int nBarsUsed = 0;
239 /* Bottom bars that are "used", i.e. are bright green, representing used memory */
240 int nBarsFree;
241 /* Top bars that are "unused", i.e. are dark green, representing free memory */
242 int i;
245 * Get the client area rectangle
247 GetClientRect(hWnd, &rcClient);
250 * Fill it with blackness
252 FillSolidRect(hDC, &rcClient, BLACK);
255 * Get the memory usage
257 CommitChargeTotal = (ULONGLONG)PerfDataGetCommitChargeTotalK() << 10;
258 CommitChargeLimit = (ULONGLONG)PerfDataGetCommitChargeLimitK() << 10;
260 if (CommitChargeTotal < 1024)
261 StrFormatKBSizeW(CommitChargeTotal, Text, ARRAY_SIZE(Text));
262 else
263 StrFormatByteSizeW(CommitChargeTotal, Text, ARRAY_SIZE(Text));
266 * Draw the font text onto the graph
267 * The bottom 20 pixels are reserved for the text
269 CopyRect(&rcText, &rcClient);
270 rcText.top = rcText.bottom - 19;
272 SetTextColor(hDC, BRIGHT_GREEN);
273 DrawTextW(hDC, Text, -1, &rcText, DT_CENTER);
276 * Now we have to draw the graph
277 * So first find out how many bars we can fit
279 nBars = ((rcClient.bottom - rcClient.top) - 25) / 3;
280 if (CommitChargeLimit)
281 nBarsUsed = (nBars * (int)((CommitChargeTotal * 100) / CommitChargeLimit)) / 100;
282 nBarsFree = nBars - nBarsUsed;
284 if (nBarsUsed < 0) nBarsUsed = 0;
285 if (nBarsUsed > nBars) nBarsUsed = nBars;
287 if (nBarsFree < 0) nBarsFree = 0;
288 if (nBarsFree > nBars) nBarsFree = nBars;
291 * Now draw the bar graph
293 rcBarLeft.left = ((rcClient.right - rcClient.left) - 33) / 2;
294 rcBarLeft.right = rcBarLeft.left + 16;
295 rcBarRight.left = rcBarLeft.left + 17;
296 rcBarRight.right = rcBarLeft.right + 17;
297 rcBarLeft.top = rcBarRight.top = 5;
298 rcBarLeft.bottom = rcBarRight.bottom = 7;
301 * Draw the "free" bars
303 for (i=0; i<nBarsFree; i++)
305 FillSolidRect(hDC, &rcBarLeft, DARK_GREEN);
306 FillSolidRect(hDC, &rcBarRight, DARK_GREEN);
308 rcBarLeft.top += 3;
309 rcBarLeft.bottom += 3;
311 rcBarRight.top += 3;
312 rcBarRight.bottom += 3;
316 * Draw the "used" bars
318 for (i=0; i<nBarsUsed; i++)
320 FillSolidRect(hDC, &rcBarLeft, BRIGHT_GREEN);
321 FillSolidRect(hDC, &rcBarRight, BRIGHT_GREEN);
323 rcBarLeft.top += 3;
324 rcBarLeft.bottom += 3;
326 rcBarRight.top += 3;
327 rcBarRight.bottom += 3;
331 static void Graph_DrawMemUsageHistoryGraph(HDC hDC, HWND hWnd)
333 RECT rcClient;
334 int i;
335 static int offset = 0;
337 if (offset++ >= 10)
338 offset = 0;
341 * Get the client area rectangle
343 GetClientRect(hWnd, &rcClient);
346 * Fill it with blackness
348 FillSolidRect(hDC, &rcClient, BLACK);
351 * Draw the graph background
353 * Draw the horizontal bars
355 for (i=0; i<rcClient.bottom; i++)
357 if ((i % 11) == 0)
359 /* FillSolidRect2(hDC, 0, i, rcClient.right, 1, DARK_GREEN); */
363 * Draw the vertical bars
365 for (i=11; i<rcClient.right + offset; i++)
367 if ((i % 11) == 0)
369 /* FillSolidRect2(hDC, i - offset, 0, 1, rcClient.bottom, DARK_GREEN); */
374 * Draw the memory usage
376 for (i=rcClient.right; i>=0; i--)
381 INT_PTR CALLBACK
382 Graph_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
384 HDC hdc;
385 PAINTSTRUCT ps;
386 LONG WindowId;
388 switch (message)
390 case WM_ERASEBKGND:
391 return TRUE;
394 * Filter out mouse & keyboard messages
396 /* case WM_APPCOMMAND: */
397 case WM_CAPTURECHANGED:
398 case WM_LBUTTONDBLCLK:
399 case WM_LBUTTONDOWN:
400 case WM_LBUTTONUP:
401 case WM_MBUTTONDBLCLK:
402 case WM_MBUTTONDOWN:
403 case WM_MBUTTONUP:
404 case WM_MOUSEACTIVATE:
405 case WM_MOUSEHOVER:
406 case WM_MOUSELEAVE:
407 case WM_MOUSEMOVE:
408 /* case WM_MOUSEWHEEL: */
409 case WM_NCHITTEST:
410 case WM_NCLBUTTONDBLCLK:
411 case WM_NCLBUTTONDOWN:
412 case WM_NCLBUTTONUP:
413 case WM_NCMBUTTONDBLCLK:
414 case WM_NCMBUTTONDOWN:
415 case WM_NCMBUTTONUP:
416 /* case WM_NCMOUSEHOVER: */
417 /* case WM_NCMOUSELEAVE: */
418 case WM_NCMOUSEMOVE:
419 case WM_NCRBUTTONDBLCLK:
420 case WM_NCRBUTTONDOWN:
421 case WM_NCRBUTTONUP:
422 /* case WM_NCXBUTTONDBLCLK: */
423 /* case WM_NCXBUTTONDOWN: */
424 /* case WM_NCXBUTTONUP: */
425 case WM_RBUTTONDBLCLK:
426 case WM_RBUTTONDOWN:
427 case WM_RBUTTONUP:
428 /* case WM_XBUTTONDBLCLK: */
429 /* case WM_XBUTTONDOWN: */
430 /* case WM_XBUTTONUP: */
431 case WM_ACTIVATE:
432 case WM_CHAR:
433 case WM_DEADCHAR:
434 case WM_GETHOTKEY:
435 case WM_HOTKEY:
436 case WM_KEYDOWN:
437 case WM_KEYUP:
438 case WM_KILLFOCUS:
439 case WM_SETFOCUS:
440 case WM_SETHOTKEY:
441 case WM_SYSCHAR:
442 case WM_SYSDEADCHAR:
443 case WM_SYSKEYDOWN:
444 case WM_SYSKEYUP:
446 case WM_NCCALCSIZE:
447 return 0;
449 case WM_PAINT:
451 hdc = BeginPaint(hWnd, &ps);
453 WindowId = GetWindowLongPtrW(hWnd, GWLP_ID);
455 switch (WindowId)
457 case IDC_CPU_USAGE_GRAPH:
458 Graph_DrawCpuUsageGraph(hdc, hWnd);
459 break;
460 case IDC_MEM_USAGE_GRAPH:
461 Graph_DrawMemUsageGraph(hdc, hWnd);
462 break;
463 case IDC_MEM_USAGE_HISTORY_GRAPH:
464 Graph_DrawMemUsageHistoryGraph(hdc, hWnd);
465 break;
468 EndPaint(hWnd, &ps);
470 return 0;
475 * We pass on all non-handled messages
477 return CallWindowProcW(OldGraphWndProc, hWnd, message, wParam, lParam);