Declare ExecuteCab and TranslateInfString.
[wine/multimedia.git] / programs / taskmgr / graph.c
blob003ebfe56c8b89d33993398d6afee2eadbc3dc13
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 WNDPROC 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 INT_PTR CALLBACK
48 Graph_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
50 HDC hdc;
51 PAINTSTRUCT ps;
52 LONG WindowId;
54 switch (message)
56 case WM_ERASEBKGND:
57 return TRUE;
60 * Filter out mouse & keyboard messages
62 /* case WM_APPCOMMAND: */
63 case WM_CAPTURECHANGED:
64 case WM_LBUTTONDBLCLK:
65 case WM_LBUTTONDOWN:
66 case WM_LBUTTONUP:
67 case WM_MBUTTONDBLCLK:
68 case WM_MBUTTONDOWN:
69 case WM_MBUTTONUP:
70 case WM_MOUSEACTIVATE:
71 case WM_MOUSEHOVER:
72 case WM_MOUSELEAVE:
73 case WM_MOUSEMOVE:
74 /* case WM_MOUSEWHEEL: */
75 case WM_NCHITTEST:
76 case WM_NCLBUTTONDBLCLK:
77 case WM_NCLBUTTONDOWN:
78 case WM_NCLBUTTONUP:
79 case WM_NCMBUTTONDBLCLK:
80 case WM_NCMBUTTONDOWN:
81 case WM_NCMBUTTONUP:
82 /* case WM_NCMOUSEHOVER: */
83 /* case WM_NCMOUSELEAVE: */
84 case WM_NCMOUSEMOVE:
85 case WM_NCRBUTTONDBLCLK:
86 case WM_NCRBUTTONDOWN:
87 case WM_NCRBUTTONUP:
88 /* case WM_NCXBUTTONDBLCLK: */
89 /* case WM_NCXBUTTONDOWN: */
90 /* case WM_NCXBUTTONUP: */
91 case WM_RBUTTONDBLCLK:
92 case WM_RBUTTONDOWN:
93 case WM_RBUTTONUP:
94 /* case WM_XBUTTONDBLCLK: */
95 /* case WM_XBUTTONDOWN: */
96 /* case WM_XBUTTONUP: */
97 case WM_ACTIVATE:
98 case WM_CHAR:
99 case WM_DEADCHAR:
100 case WM_GETHOTKEY:
101 case WM_HOTKEY:
102 case WM_KEYDOWN:
103 case WM_KEYUP:
104 case WM_KILLFOCUS:
105 case WM_SETFOCUS:
106 case WM_SETHOTKEY:
107 case WM_SYSCHAR:
108 case WM_SYSDEADCHAR:
109 case WM_SYSKEYDOWN:
110 case WM_SYSKEYUP:
112 case WM_NCCALCSIZE:
113 return 0;
115 case WM_PAINT:
117 hdc = BeginPaint(hWnd, &ps);
119 WindowId = GetWindowLongPtr(hWnd, GWLP_ID);
121 switch (WindowId)
123 case IDC_CPU_USAGE_GRAPH:
124 Graph_DrawCpuUsageGraph(hdc, hWnd);
125 break;
126 case IDC_MEM_USAGE_GRAPH:
127 Graph_DrawMemUsageGraph(hdc, hWnd);
128 break;
129 case IDC_MEM_USAGE_HISTORY_GRAPH:
130 Graph_DrawMemUsageHistoryGraph(hdc, hWnd);
131 break;
134 EndPaint(hWnd, &ps);
136 return 0;
141 * We pass on all non-handled messages
143 return CallWindowProc((WNDPROC)OldGraphWndProc, hWnd, message, wParam, lParam);
146 void Graph_DrawCpuUsageGraph(HDC hDC, HWND hWnd)
148 RECT rcClient;
149 RECT rcBarLeft;
150 RECT rcBarRight;
151 TCHAR Text[260];
152 ULONG CpuUsage;
153 ULONG CpuKernelUsage;
154 int nBars;
155 int nBarsUsed;
156 /* Bottom bars that are "used", i.e. are bright green, representing used cpu time */
157 int nBarsUsedKernel;
158 /* Bottom bars that are "used", i.e. are bright green, representing used cpu kernel time */
159 int nBarsFree;
160 /* Top bars that are "unused", i.e. are dark green, representing free cpu time */
161 int i;
164 * Get the client area rectangle
166 GetClientRect(hWnd, &rcClient);
169 * Fill it with blackness
171 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));
174 * Get the CPU usage
176 CpuUsage = PerfDataGetProcessorUsage();
177 CpuKernelUsage = PerfDataGetProcessorSystemUsage();
178 if (CpuUsage < 0) CpuUsage = 0;
179 if (CpuUsage > 100) CpuUsage = 100;
180 if (CpuKernelUsage < 0) CpuKernelUsage = 0;
181 if (CpuKernelUsage > 100) CpuKernelUsage = 100;
184 * Check and see how many digits it will take
185 * so we get the indentation right every time.
187 if (CpuUsage == 100)
189 _stprintf(Text, _T("%d%%"), (int)CpuUsage);
191 else if (CpuUsage < 10)
193 _stprintf(Text, _T(" %d%%"), (int)CpuUsage);
195 else
197 _stprintf(Text, _T(" %d%%"), (int)CpuUsage);
201 * Draw the font text onto the graph
202 * The bottom 20 pixels are reserved for the text
204 Font_DrawText(hDC, Text, ((rcClient.right - rcClient.left) - 32) / 2, rcClient.bottom - 11 - 5);
207 * Now we have to draw the graph
208 * So first find out how many bars we can fit
210 nBars = ((rcClient.bottom - rcClient.top) - 25) / 3;
211 nBarsUsed = (nBars * CpuUsage) / 100;
212 if ((CpuUsage) && (nBarsUsed == 0))
214 nBarsUsed = 1;
216 nBarsFree = nBars - nBarsUsed;
217 if (TaskManagerSettings.ShowKernelTimes)
219 nBarsUsedKernel = ((nBars * 2) * CpuKernelUsage) / 100;
220 nBarsUsed -= (nBarsUsedKernel / 2);
222 else
224 nBarsUsedKernel = 0;
228 * Now draw the bar graph
230 rcBarLeft.left = ((rcClient.right - rcClient.left) - 33) / 2;
231 rcBarLeft.right = rcBarLeft.left + 16;
232 rcBarRight.left = rcBarLeft.left + 17;
233 rcBarRight.right = rcBarLeft.right + 17;
234 rcBarLeft.top = rcBarRight.top = 5;
235 rcBarLeft.bottom = rcBarRight.bottom = 7;
237 if (nBarsUsed < 0) nBarsUsed = 0;
238 if (nBarsUsed > nBars) nBarsUsed = nBars;
240 if (nBarsFree < 0) nBarsFree = 0;
241 if (nBarsFree > nBars) nBarsFree = nBars;
243 if (nBarsUsedKernel < 0) nBarsUsedKernel = 0;
244 if (nBarsUsedKernel > nBars) nBarsUsedKernel = nBars;
247 * Draw the "free" bars
249 for (i=0; i<nBarsFree; i++)
251 FillSolidRect(hDC, &rcBarLeft, DARK_GREEN);
252 FillSolidRect(hDC, &rcBarRight, DARK_GREEN);
254 rcBarLeft.top += 3;
255 rcBarLeft.bottom += 3;
257 rcBarRight.top += 3;
258 rcBarRight.bottom += 3;
262 * Draw the "used" bars
264 for (i=0; i<nBarsUsed; i++)
266 if (nBarsUsed > 5000) nBarsUsed = 5000;
268 FillSolidRect(hDC, &rcBarLeft, BRIGHT_GREEN);
269 FillSolidRect(hDC, &rcBarRight, BRIGHT_GREEN);
271 rcBarLeft.top += 3;
272 rcBarLeft.bottom += 3;
274 rcBarRight.top += 3;
275 rcBarRight.bottom += 3;
279 * Draw the "used" kernel bars
281 rcBarLeft.bottom--;
282 rcBarRight.bottom--;
283 if (nBarsUsedKernel && nBarsUsedKernel % 2)
285 rcBarLeft.top -= 2;
286 rcBarLeft.bottom -= 2;
288 rcBarRight.top -= 2;
289 rcBarRight.bottom -= 2;
291 FillSolidRect(hDC, &rcBarLeft, RED);
292 FillSolidRect(hDC, &rcBarRight, RED);
294 rcBarLeft.top += 2;
295 rcBarLeft.bottom += 2;
297 rcBarRight.top += 2;
298 rcBarRight.bottom += 2;
300 nBarsUsedKernel--;
302 for (i=0; i<nBarsUsedKernel; i++)
304 if (nBarsUsedKernel > 5000) nBarsUsedKernel = 5000;
306 FillSolidRect(hDC, &rcBarLeft, RED);
307 FillSolidRect(hDC, &rcBarRight, RED);
309 rcBarLeft.top++;
310 rcBarLeft.bottom++;
312 rcBarRight.top++;
313 rcBarRight.bottom++;
315 if (i % 2)
317 rcBarLeft.top++;
318 rcBarLeft.bottom++;
320 rcBarRight.top++;
321 rcBarRight.bottom++;
326 void Graph_DrawMemUsageGraph(HDC hDC, HWND hWnd)
328 RECT rcClient;
329 RECT rcBarLeft;
330 RECT rcBarRight;
331 TCHAR Text[260];
332 ULONGLONG CommitChargeTotal;
333 ULONGLONG CommitChargeLimit;
334 int nBars;
335 int nBarsUsed = 0;
336 /* Bottom bars that are "used", i.e. are bright green, representing used memory */
337 int nBarsFree;
338 /* Top bars that are "unused", i.e. are dark green, representing free memory */
339 int i;
342 * Get the client area rectangle
344 GetClientRect(hWnd, &rcClient);
347 * Fill it with blackness
349 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));
352 * Get the memory usage
354 CommitChargeTotal = (ULONGLONG)PerfDataGetCommitChargeTotalK();
355 CommitChargeLimit = (ULONGLONG)PerfDataGetCommitChargeLimitK();
357 _stprintf(Text, _T("%dK"), (int)CommitChargeTotal);
360 * Draw the font text onto the graph
361 * The bottom 20 pixels are reserved for the text
363 Font_DrawText(hDC, Text, ((rcClient.right - rcClient.left) - (_tcslen(Text) * 8)) / 2, rcClient.bottom - 11 - 5);
366 * Now we have to draw the graph
367 * So first find out how many bars we can fit
369 nBars = ((rcClient.bottom - rcClient.top) - 25) / 3;
370 if (CommitChargeLimit)
371 nBarsUsed = (nBars * (int)((CommitChargeTotal * 100) / CommitChargeLimit)) / 100;
372 nBarsFree = nBars - nBarsUsed;
374 if (nBarsUsed < 0) nBarsUsed = 0;
375 if (nBarsUsed > nBars) nBarsUsed = nBars;
377 if (nBarsFree < 0) nBarsFree = 0;
378 if (nBarsFree > nBars) nBarsFree = nBars;
381 * Now draw the bar graph
383 rcBarLeft.left = ((rcClient.right - rcClient.left) - 33) / 2;
384 rcBarLeft.right = rcBarLeft.left + 16;
385 rcBarRight.left = rcBarLeft.left + 17;
386 rcBarRight.right = rcBarLeft.right + 17;
387 rcBarLeft.top = rcBarRight.top = 5;
388 rcBarLeft.bottom = rcBarRight.bottom = 7;
391 * Draw the "free" bars
393 for (i=0; i<nBarsFree; i++)
395 FillSolidRect(hDC, &rcBarLeft, DARK_GREEN);
396 FillSolidRect(hDC, &rcBarRight, DARK_GREEN);
398 rcBarLeft.top += 3;
399 rcBarLeft.bottom += 3;
401 rcBarRight.top += 3;
402 rcBarRight.bottom += 3;
406 * Draw the "used" bars
408 for (i=0; i<nBarsUsed; i++)
410 FillSolidRect(hDC, &rcBarLeft, BRIGHT_GREEN);
411 FillSolidRect(hDC, &rcBarRight, BRIGHT_GREEN);
413 rcBarLeft.top += 3;
414 rcBarLeft.bottom += 3;
416 rcBarRight.top += 3;
417 rcBarRight.bottom += 3;
421 void Graph_DrawMemUsageHistoryGraph(HDC hDC, HWND hWnd)
423 RECT rcClient;
424 ULONGLONG CommitChargeLimit;
425 int i;
426 static int offset = 0;
428 if (offset++ >= 10)
429 offset = 0;
432 * Get the client area rectangle
434 GetClientRect(hWnd, &rcClient);
437 * Fill it with blackness
439 FillSolidRect(hDC, &rcClient, RGB(0, 0, 0));
442 * Get the memory usage
444 CommitChargeLimit = (ULONGLONG)PerfDataGetCommitChargeLimitK();
447 * Draw the graph background
449 * Draw the horizontal bars
451 for (i=0; i<rcClient.bottom; i++)
453 if ((i % 11) == 0)
455 /* FillSolidRect2(hDC, 0, i, rcClient.right, 1, DARK_GREEN); */
459 * Draw the vertical bars
461 for (i=11; i<rcClient.right + offset; i++)
463 if ((i % 11) == 0)
465 /* FillSolidRect2(hDC, i - offset, 0, 1, rcClient.bottom, DARK_GREEN); */
470 * Draw the memory usage
472 for (i=rcClient.right; i>=0; i--)