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