06bba82fb2d89c85f86ac615d851d924e5caecac
[reactos.git] / rosapps / taskmgr / graph.cpp
1 /*
2 * ReactOS Task Manager
3 *
4 * graph.cpp
5 *
6 * Copyright (C) 1999 - 2001 Brian Palmer <brianp@reactos.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program 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
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "stdafx.h"
24 #include "taskmgr.h"
25 #include "graph.h"
26 #include "font.h"
27 #include "perfdata.h"
28
29
30 LONG OldGraphWndProc;
31
32 void Graph_DrawCpuUsageGraph(HDC hDC, HWND hWnd);
33 void Graph_DrawMemUsageGraph(HDC hDC, HWND hWnd);
34 void Graph_DrawMemUsageHistoryGraph(HDC hDC, HWND hWnd);
35
36 LRESULT CALLBACK Graph_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
37 {
38 HDC hdc;
39 PAINTSTRUCT ps;
40 LONG WindowId;
41
42 switch (message)
43 {
44 case WM_ERASEBKGND:
45
46 return TRUE;
47
48 //
49 // Filter out mouse & keyboard messages
50 //
51 //case WM_APPCOMMAND:
52 case WM_CAPTURECHANGED:
53 case WM_LBUTTONDBLCLK:
54 case WM_LBUTTONDOWN:
55 case WM_LBUTTONUP:
56 case WM_MBUTTONDBLCLK:
57 case WM_MBUTTONDOWN:
58 case WM_MBUTTONUP:
59 case WM_MOUSEACTIVATE:
60 case WM_MOUSEHOVER:
61 case WM_MOUSELEAVE:
62 case WM_MOUSEMOVE:
63 //case WM_MOUSEWHEEL:
64 case WM_NCHITTEST:
65 case WM_NCLBUTTONDBLCLK:
66 case WM_NCLBUTTONDOWN:
67 case WM_NCLBUTTONUP:
68 case WM_NCMBUTTONDBLCLK:
69 case WM_NCMBUTTONDOWN:
70 case WM_NCMBUTTONUP:
71 //case WM_NCMOUSEHOVER:
72 //case WM_NCMOUSELEAVE:
73 case WM_NCMOUSEMOVE:
74 case WM_NCRBUTTONDBLCLK:
75 case WM_NCRBUTTONDOWN:
76 case WM_NCRBUTTONUP:
77 //case WM_NCXBUTTONDBLCLK:
78 //case WM_NCXBUTTONDOWN:
79 //case WM_NCXBUTTONUP:
80 case WM_RBUTTONDBLCLK:
81 case WM_RBUTTONDOWN:
82 case WM_RBUTTONUP:
83 //case WM_XBUTTONDBLCLK:
84 //case WM_XBUTTONDOWN:
85 //case WM_XBUTTONUP:
86 case WM_ACTIVATE:
87 case WM_CHAR:
88 case WM_DEADCHAR:
89 case WM_GETHOTKEY:
90 case WM_HOTKEY:
91 case WM_KEYDOWN:
92 case WM_KEYUP:
93 case WM_KILLFOCUS:
94 case WM_SETFOCUS:
95 case WM_SETHOTKEY:
96 case WM_SYSCHAR:
97 case WM_SYSDEADCHAR:
98 case WM_SYSKEYDOWN:
99 case WM_SYSKEYUP:
100
101 return 0;
102
103 case WM_PAINT:
104
105 hdc = BeginPaint(hWnd, &ps);
106
107 WindowId = GetWindowLong(hWnd, GWL_ID);
108
109 switch (WindowId)
110 {
111 case IDC_CPU_USAGE_GRAPH:
112 Graph_DrawCpuUsageGraph(hdc, hWnd);
113 break;
114 case IDC_MEM_USAGE_GRAPH:
115 Graph_DrawMemUsageGraph(hdc, hWnd);
116 break;
117 case IDC_MEM_USAGE_HISTORY_GRAPH:
118 Graph_DrawMemUsageHistoryGraph(hdc, hWnd);
119 break;
120 }
121
122 EndPaint(hWnd, &ps);
123
124 return 0;
125
126 }
127
128 //
129 // We pass on all non-handled messages
130 //
131 return CallWindowProc((WNDPROC)OldGraphWndProc, hWnd, message, wParam, lParam);
132 }
133
134 void Graph_DrawCpuUsageGraph(HDC hDC, HWND hWnd)
135 {
136 RECT rcClient;
137 RECT rcBarLeft;
138 RECT rcBarRight;
139 TCHAR Text[260];
140 ULONG CpuUsage;
141 ULONG CpuKernelUsage;
142 int nBars;
143 int nBarsUsed; // Bottom bars that are "used", i.e. are bright green, representing used cpu time
144 int nBarsUsedKernel; // Bottom bars that are "used", i.e. are bright green, representing used cpu kernel time
145 int nBarsFree; // Top bars that are "unused", i.e. are dark green, representing free cpu time
146 int i;
147
148 //
149 // Get the client area rectangle
150 //
151 GetClientRect(hWnd, &rcClient);
152
153 //
154 // Fill it with blackness
155 //
156 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));
157
158 //
159 // Get the CPU usage
160 //
161 CpuUsage = PerfDataGetProcessorUsage();
162 CpuKernelUsage = PerfDataGetProcessorSystemUsage();
163
164 //
165 // Check and see how many digits it will take
166 // so we get the indentation right every time.
167 //
168 if (CpuUsage == 100)
169 {
170 sprintf(Text, "%d%%", CpuUsage);
171 }
172 else if (CpuUsage < 10)
173 {
174 sprintf(Text, " %d%%", CpuUsage);
175 }
176 else
177 {
178 sprintf(Text, " %d%%", CpuUsage);
179 }
180
181 //
182 // Draw the font text onto the graph
183 // The bottom 20 pixels are reserved for the text
184 //
185 Font_DrawText(hDC, Text, ((rcClient.right - rcClient.left) - 32) / 2, rcClient.bottom - 11 - 5);
186
187 //
188 // Now we have to draw the graph
189 // So first find out how many bars we can fit
190 //
191 nBars = ((rcClient.bottom - rcClient.top) - 25) / 3;
192 nBarsUsed = (nBars * CpuUsage) / 100;
193 if ((CpuUsage) && (nBarsUsed == 0))
194 {
195 nBarsUsed = 1;
196 }
197 nBarsFree = nBars - nBarsUsed;
198 if (TaskManagerSettings.ShowKernelTimes)
199 {
200 nBarsUsedKernel = ((nBars * 2) * CpuKernelUsage) / 100;
201 nBarsUsed -= (nBarsUsedKernel / 2);
202 }
203 else
204 {
205 nBarsUsedKernel = 0;
206 }
207
208 //
209 // Now draw the bar graph
210 //
211 rcBarLeft.left = ((rcClient.right - rcClient.left) - 33) / 2;
212 rcBarLeft.right = rcBarLeft.left + 16;
213 rcBarRight.left = rcBarLeft.left + 17;
214 rcBarRight.right = rcBarLeft.right + 17;
215 rcBarLeft.top = rcBarRight.top = 5;
216 rcBarLeft.bottom = rcBarRight.bottom = 7;
217
218 //
219 // Draw the "free" bars
220 //
221 for (i=0; i<nBarsFree; i++)
222 {
223 FillSolidRect(hDC, &rcBarLeft, DARK_GREEN);
224 FillSolidRect(hDC, &rcBarRight, DARK_GREEN);
225
226 rcBarLeft.top += 3;
227 rcBarLeft.bottom += 3;
228
229 rcBarRight.top += 3;
230 rcBarRight.bottom += 3;
231 }
232
233 //
234 // Draw the "used" bars
235 //
236 for (i=0; i<nBarsUsed; i++)
237 {
238 FillSolidRect(hDC, &rcBarLeft, BRIGHT_GREEN);
239 FillSolidRect(hDC, &rcBarRight, BRIGHT_GREEN);
240
241 rcBarLeft.top += 3;
242 rcBarLeft.bottom += 3;
243
244 rcBarRight.top += 3;
245 rcBarRight.bottom += 3;
246 }
247
248 //
249 // Draw the "used" kernel bars
250 //
251 rcBarLeft.bottom--;
252 rcBarRight.bottom--;
253 if (nBarsUsedKernel % 2)
254 {
255 rcBarLeft.top -= 2;
256 rcBarLeft.bottom -= 2;
257
258 rcBarRight.top -= 2;
259 rcBarRight.bottom -= 2;
260
261 FillSolidRect(hDC, &rcBarLeft, RED);
262 FillSolidRect(hDC, &rcBarRight, RED);
263
264 rcBarLeft.top += 2;
265 rcBarLeft.bottom += 2;
266
267 rcBarRight.top += 2;
268 rcBarRight.bottom += 2;
269
270 nBarsUsedKernel--;
271 }
272 for (i=0; i<nBarsUsedKernel; i++)
273 {
274 FillSolidRect(hDC, &rcBarLeft, RED);
275 FillSolidRect(hDC, &rcBarRight, RED);
276
277 rcBarLeft.top++;
278 rcBarLeft.bottom++;
279
280 rcBarRight.top++;
281 rcBarRight.bottom++;
282
283 if (i % 2)
284 {
285 rcBarLeft.top++;
286 rcBarLeft.bottom++;
287
288 rcBarRight.top++;
289 rcBarRight.bottom++;
290 }
291 }
292 }
293
294 void Graph_DrawMemUsageGraph(HDC hDC, HWND hWnd)
295 {
296 RECT rcClient;
297 RECT rcBarLeft;
298 RECT rcBarRight;
299 TCHAR Text[260];
300 ULONGLONG CommitChargeTotal;
301 ULONGLONG CommitChargeLimit;
302 int nBars;
303 int nBarsUsed; // Bottom bars that are "used", i.e. are bright green, representing used memory
304 int nBarsFree; // Top bars that are "unused", i.e. are dark green, representing free memory
305 int i;
306
307 //
308 // Get the client area rectangle
309 //
310 GetClientRect(hWnd, &rcClient);
311
312 //
313 // Fill it with blackness
314 //
315 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));
316
317 //
318 // Get the memory usage
319 //
320 CommitChargeTotal = (ULONGLONG)PerfDataGetCommitChargeTotalK();
321 CommitChargeLimit = (ULONGLONG)PerfDataGetCommitChargeLimitK();
322
323 sprintf(Text, "%dK", CommitChargeTotal);
324
325 //
326 // Draw the font text onto the graph
327 // The bottom 20 pixels are reserved for the text
328 //
329 Font_DrawText(hDC, Text, ((rcClient.right - rcClient.left) - (strlen(Text) * 8)) / 2, rcClient.bottom - 11 - 5);
330
331 //
332 // Now we have to draw the graph
333 // So first find out how many bars we can fit
334 //
335 nBars = ((rcClient.bottom - rcClient.top) - 25) / 3;
336 nBarsUsed = (nBars * (int)((CommitChargeTotal * 100) / CommitChargeLimit)) / 100;
337 nBarsFree = nBars - nBarsUsed;
338
339 //
340 // Now draw the bar graph
341 //
342 rcBarLeft.left = ((rcClient.right - rcClient.left) - 33) / 2;
343 rcBarLeft.right = rcBarLeft.left + 16;
344 rcBarRight.left = rcBarLeft.left + 17;
345 rcBarRight.right = rcBarLeft.right + 17;
346 rcBarLeft.top = rcBarRight.top = 5;
347 rcBarLeft.bottom = rcBarRight.bottom = 7;
348
349 //
350 // Draw the "free" bars
351 //
352 for (i=0; i<nBarsFree; i++)
353 {
354 FillSolidRect(hDC, &rcBarLeft, DARK_GREEN);
355 FillSolidRect(hDC, &rcBarRight, DARK_GREEN);
356
357 rcBarLeft.top += 3;
358 rcBarLeft.bottom += 3;
359
360 rcBarRight.top += 3;
361 rcBarRight.bottom += 3;
362 }
363
364 //
365 // Draw the "used" bars
366 //
367 for (i=0; i<nBarsUsed; i++)
368 {
369 FillSolidRect(hDC, &rcBarLeft, BRIGHT_GREEN);
370 FillSolidRect(hDC, &rcBarRight, BRIGHT_GREEN);
371
372 rcBarLeft.top += 3;
373 rcBarLeft.bottom += 3;
374
375 rcBarRight.top += 3;
376 rcBarRight.bottom += 3;
377 }
378 }
379
380 void Graph_DrawMemUsageHistoryGraph(HDC hDC, HWND hWnd)
381 {
382 RECT rcClient;
383 ULONGLONG CommitChargeLimit;
384 int i;
385 static int offset = 0;
386
387 if (offset++ >= 10)
388 offset = 0;
389
390 //
391 // Get the client area rectangle
392 //
393 GetClientRect(hWnd, &rcClient);
394
395 //
396 // Fill it with blackness
397 //
398 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));
399
400 //
401 // Get the memory usage
402 //
403 CommitChargeLimit = (ULONGLONG)PerfDataGetCommitChargeLimitK();
404
405 //
406 // Draw the graph background
407 //
408 // Draw the horizontal bars
409 //
410 for (i=0; i<rcClient.bottom; i++)
411 {
412 if ((i % 11) == 0)
413 {
414 FillSolidRect(hDC, 0, i, rcClient.right, 1, DARK_GREEN);
415 }
416 }
417 //
418 // Draw the vertical bars
419 //
420 for (i=11; i<rcClient.right + offset; i++)
421 {
422 if ((i % 11) == 0)
423 {
424 FillSolidRect(hDC, i - offset, 0, 1, rcClient.bottom, DARK_GREEN);
425 }
426 }
427
428 //
429 // Draw the memory usage
430 //
431 for (i=rcClient.right; i>=0; i--)
432 {
433 }
434 }