ShowOwnedPopups and WM_SHOWWINDOW should handle non-WS_POPUP style
[wine/multimedia.git] / programs / taskmgr / graph.c
blob4db1d8756dcf259dfc0b3485d8b2a47a2e548e18
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 LONG OldGraphWndProc;
43 void Graph_DrawCpuUsageGraph(HDC hDC, HWND hWnd);
44 void Graph_DrawMemUsageGraph(HDC hDC, HWND hWnd);
45 void Graph_DrawMemUsageHistoryGraph(HDC hDC, HWND hWnd);
47 LRESULT CALLBACK Graph_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
49 HDC hdc;
50 PAINTSTRUCT ps;
51 LONG WindowId;
53 switch (message)
55 case WM_ERASEBKGND:
56 return TRUE;
59 * Filter out mouse & keyboard messages
61 /* case WM_APPCOMMAND: */
62 case WM_CAPTURECHANGED:
63 case WM_LBUTTONDBLCLK:
64 case WM_LBUTTONDOWN:
65 case WM_LBUTTONUP:
66 case WM_MBUTTONDBLCLK:
67 case WM_MBUTTONDOWN:
68 case WM_MBUTTONUP:
69 case WM_MOUSEACTIVATE:
70 case WM_MOUSEHOVER:
71 case WM_MOUSELEAVE:
72 case WM_MOUSEMOVE:
73 /* case WM_MOUSEWHEEL: */
74 case WM_NCHITTEST:
75 case WM_NCLBUTTONDBLCLK:
76 case WM_NCLBUTTONDOWN:
77 case WM_NCLBUTTONUP:
78 case WM_NCMBUTTONDBLCLK:
79 case WM_NCMBUTTONDOWN:
80 case WM_NCMBUTTONUP:
81 /* case WM_NCMOUSEHOVER: */
82 /* case WM_NCMOUSELEAVE: */
83 case WM_NCMOUSEMOVE:
84 case WM_NCRBUTTONDBLCLK:
85 case WM_NCRBUTTONDOWN:
86 case WM_NCRBUTTONUP:
87 /* case WM_NCXBUTTONDBLCLK: */
88 /* case WM_NCXBUTTONDOWN: */
89 /* case WM_NCXBUTTONUP: */
90 case WM_RBUTTONDBLCLK:
91 case WM_RBUTTONDOWN:
92 case WM_RBUTTONUP:
93 /* case WM_XBUTTONDBLCLK: */
94 /* case WM_XBUTTONDOWN: */
95 /* case WM_XBUTTONUP: */
96 case WM_ACTIVATE:
97 case WM_CHAR:
98 case WM_DEADCHAR:
99 case WM_GETHOTKEY:
100 case WM_HOTKEY:
101 case WM_KEYDOWN:
102 case WM_KEYUP:
103 case WM_KILLFOCUS:
104 case WM_SETFOCUS:
105 case WM_SETHOTKEY:
106 case WM_SYSCHAR:
107 case WM_SYSDEADCHAR:
108 case WM_SYSKEYDOWN:
109 case WM_SYSKEYUP:
111 case WM_NCCALCSIZE:
112 return 0;
114 case WM_PAINT:
116 hdc = BeginPaint(hWnd, &ps);
118 WindowId = GetWindowLong(hWnd, GWL_ID);
120 switch (WindowId)
122 case IDC_CPU_USAGE_GRAPH:
123 Graph_DrawCpuUsageGraph(hdc, hWnd);
124 break;
125 case IDC_MEM_USAGE_GRAPH:
126 Graph_DrawMemUsageGraph(hdc, hWnd);
127 break;
128 case IDC_MEM_USAGE_HISTORY_GRAPH:
129 Graph_DrawMemUsageHistoryGraph(hdc, hWnd);
130 break;
133 EndPaint(hWnd, &ps);
135 return 0;
140 * We pass on all non-handled messages
142 return CallWindowProc((WNDPROC)OldGraphWndProc, hWnd, message, wParam, lParam);
145 void Graph_DrawCpuUsageGraph(HDC hDC, HWND hWnd)
147 RECT rcClient;
148 RECT rcBarLeft;
149 RECT rcBarRight;
150 TCHAR Text[260];
151 ULONG CpuUsage;
152 ULONG CpuKernelUsage;
153 int nBars;
154 int nBarsUsed;
155 /* Bottom bars that are "used", i.e. are bright green, representing used cpu time */
156 int nBarsUsedKernel;
157 /* Bottom bars that are "used", i.e. are bright green, representing used cpu kernel time */
158 int nBarsFree;
159 /* Top bars that are "unused", i.e. are dark green, representing free cpu time */
160 int i;
163 * Get the client area rectangle
165 GetClientRect(hWnd, &rcClient);
168 * Fill it with blackness
170 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));
173 * Get the CPU usage
175 CpuUsage = PerfDataGetProcessorUsage();
176 CpuKernelUsage = PerfDataGetProcessorSystemUsage();
177 if (CpuUsage < 0) CpuUsage = 0;
178 if (CpuUsage > 100) CpuUsage = 100;
179 if (CpuKernelUsage < 0) CpuKernelUsage = 0;
180 if (CpuKernelUsage > 100) CpuKernelUsage = 100;
183 * Check and see how many digits it will take
184 * so we get the indentation right every time.
186 if (CpuUsage == 100)
188 _stprintf(Text, _T("%d%%"), (int)CpuUsage);
190 else if (CpuUsage < 10)
192 _stprintf(Text, _T(" %d%%"), (int)CpuUsage);
194 else
196 _stprintf(Text, _T(" %d%%"), (int)CpuUsage);
200 * Draw the font text onto the graph
201 * The bottom 20 pixels are reserved for the text
203 Font_DrawText(hDC, Text, ((rcClient.right - rcClient.left) - 32) / 2, rcClient.bottom - 11 - 5);
206 * Now we have to draw the graph
207 * So first find out how many bars we can fit
209 nBars = ((rcClient.bottom - rcClient.top) - 25) / 3;
210 nBarsUsed = (nBars * CpuUsage) / 100;
211 if ((CpuUsage) && (nBarsUsed == 0))
213 nBarsUsed = 1;
215 nBarsFree = nBars - nBarsUsed;
216 if (TaskManagerSettings.ShowKernelTimes)
218 nBarsUsedKernel = ((nBars * 2) * CpuKernelUsage) / 100;
219 nBarsUsed -= (nBarsUsedKernel / 2);
221 else
223 nBarsUsedKernel = 0;
227 * Now draw the bar graph
229 rcBarLeft.left = ((rcClient.right - rcClient.left) - 33) / 2;
230 rcBarLeft.right = rcBarLeft.left + 16;
231 rcBarRight.left = rcBarLeft.left + 17;
232 rcBarRight.right = rcBarLeft.right + 17;
233 rcBarLeft.top = rcBarRight.top = 5;
234 rcBarLeft.bottom = rcBarRight.bottom = 7;
236 if (nBarsUsed < 0) nBarsUsed = 0;
237 if (nBarsUsed > nBars) nBarsUsed = nBars;
239 if (nBarsFree < 0) nBarsFree = 0;
240 if (nBarsFree > nBars) nBarsFree = nBars;
242 if (nBarsUsedKernel < 0) nBarsUsedKernel = 0;
243 if (nBarsUsedKernel > nBars) nBarsUsedKernel = nBars;
246 * Draw the "free" bars
248 for (i=0; i<nBarsFree; i++)
250 FillSolidRect(hDC, &rcBarLeft, DARK_GREEN);
251 FillSolidRect(hDC, &rcBarRight, DARK_GREEN);
253 rcBarLeft.top += 3;
254 rcBarLeft.bottom += 3;
256 rcBarRight.top += 3;
257 rcBarRight.bottom += 3;
261 * Draw the "used" bars
263 for (i=0; i<nBarsUsed; i++)
265 if (nBarsUsed > 5000) nBarsUsed = 5000;
267 FillSolidRect(hDC, &rcBarLeft, BRIGHT_GREEN);
268 FillSolidRect(hDC, &rcBarRight, BRIGHT_GREEN);
270 rcBarLeft.top += 3;
271 rcBarLeft.bottom += 3;
273 rcBarRight.top += 3;
274 rcBarRight.bottom += 3;
278 * Draw the "used" kernel bars
280 rcBarLeft.bottom--;
281 rcBarRight.bottom--;
282 if (nBarsUsedKernel && nBarsUsedKernel % 2)
284 rcBarLeft.top -= 2;
285 rcBarLeft.bottom -= 2;
287 rcBarRight.top -= 2;
288 rcBarRight.bottom -= 2;
290 FillSolidRect(hDC, &rcBarLeft, RED);
291 FillSolidRect(hDC, &rcBarRight, RED);
293 rcBarLeft.top += 2;
294 rcBarLeft.bottom += 2;
296 rcBarRight.top += 2;
297 rcBarRight.bottom += 2;
299 nBarsUsedKernel--;
301 for (i=0; i<nBarsUsedKernel; i++)
303 if (nBarsUsedKernel > 5000) nBarsUsedKernel = 5000;
305 FillSolidRect(hDC, &rcBarLeft, RED);
306 FillSolidRect(hDC, &rcBarRight, RED);
308 rcBarLeft.top++;
309 rcBarLeft.bottom++;
311 rcBarRight.top++;
312 rcBarRight.bottom++;
314 if (i % 2)
316 rcBarLeft.top++;
317 rcBarLeft.bottom++;
319 rcBarRight.top++;
320 rcBarRight.bottom++;
325 void Graph_DrawMemUsageGraph(HDC hDC, HWND hWnd)
327 RECT rcClient;
328 RECT rcBarLeft;
329 RECT rcBarRight;
330 TCHAR Text[260];
331 ULONGLONG CommitChargeTotal;
332 ULONGLONG CommitChargeLimit;
333 int nBars;
334 int nBarsUsed = 0;
335 /* Bottom bars that are "used", i.e. are bright green, representing used memory */
336 int nBarsFree;
337 /* Top bars that are "unused", i.e. are dark green, representing free memory */
338 int i;
341 * Get the client area rectangle
343 GetClientRect(hWnd, &rcClient);
346 * Fill it with blackness
348 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));
351 * Get the memory usage
353 CommitChargeTotal = (ULONGLONG)PerfDataGetCommitChargeTotalK();
354 CommitChargeLimit = (ULONGLONG)PerfDataGetCommitChargeLimitK();
356 _stprintf(Text, _T("%dK"), (int)CommitChargeTotal);
359 * Draw the font text onto the graph
360 * The bottom 20 pixels are reserved for the text
362 Font_DrawText(hDC, Text, ((rcClient.right - rcClient.left) - (_tcslen(Text) * 8)) / 2, rcClient.bottom - 11 - 5);
365 * Now we have to draw the graph
366 * So first find out how many bars we can fit
368 nBars = ((rcClient.bottom - rcClient.top) - 25) / 3;
369 if (CommitChargeLimit)
370 nBarsUsed = (nBars * (int)((CommitChargeTotal * 100) / CommitChargeLimit)) / 100;
371 nBarsFree = nBars - nBarsUsed;
373 if (nBarsUsed < 0) nBarsUsed = 0;
374 if (nBarsUsed > nBars) nBarsUsed = nBars;
376 if (nBarsFree < 0) nBarsFree = 0;
377 if (nBarsFree > nBars) nBarsFree = nBars;
380 * Now draw the bar graph
382 rcBarLeft.left = ((rcClient.right - rcClient.left) - 33) / 2;
383 rcBarLeft.right = rcBarLeft.left + 16;
384 rcBarRight.left = rcBarLeft.left + 17;
385 rcBarRight.right = rcBarLeft.right + 17;
386 rcBarLeft.top = rcBarRight.top = 5;
387 rcBarLeft.bottom = rcBarRight.bottom = 7;
390 * Draw the "free" bars
392 for (i=0; i<nBarsFree; i++)
394 FillSolidRect(hDC, &rcBarLeft, DARK_GREEN);
395 FillSolidRect(hDC, &rcBarRight, DARK_GREEN);
397 rcBarLeft.top += 3;
398 rcBarLeft.bottom += 3;
400 rcBarRight.top += 3;
401 rcBarRight.bottom += 3;
405 * Draw the "used" bars
407 for (i=0; i<nBarsUsed; i++)
409 FillSolidRect(hDC, &rcBarLeft, BRIGHT_GREEN);
410 FillSolidRect(hDC, &rcBarRight, BRIGHT_GREEN);
412 rcBarLeft.top += 3;
413 rcBarLeft.bottom += 3;
415 rcBarRight.top += 3;
416 rcBarRight.bottom += 3;
420 void Graph_DrawMemUsageHistoryGraph(HDC hDC, HWND hWnd)
422 RECT rcClient;
423 ULONGLONG CommitChargeLimit;
424 int i;
425 static int offset = 0;
427 if (offset++ >= 10)
428 offset = 0;
431 * Get the client area rectangle
433 GetClientRect(hWnd, &rcClient);
436 * Fill it with blackness
438 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));
441 * Get the memory usage
443 CommitChargeLimit = (ULONGLONG)PerfDataGetCommitChargeLimitK();
446 * Draw the graph background
448 * Draw the horizontal bars
450 for (i=0; i<rcClient.bottom; i++)
452 if ((i % 11) == 0)
454 /* FillSolidRect2(hDC, 0, i, rcClient.right, 1, DARK_GREEN); */
458 * Draw the vertical bars
460 for (i=11; i<rcClient.right + offset; i++)
462 if ((i % 11) == 0)
464 /* FillSolidRect2(hDC, i - offset, 0, 1, rcClient.bottom, DARK_GREEN); */
469 * Draw the memory usage
471 for (i=rcClient.right; i>=0; i--)