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