3 * Christopher Bowns, 2008
5 * Formerly: Memory Monitor, by Bernhard Baehr
7 * Copyright © 2001-2003 Bernhard Baehr
9 * MainController.m - Main Application Controller Class
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #import "MainController.h"
30 #define GRAPH_SIZE 128
31 // define GRAPH_WIDTH 8
33 @implementation MainController
36 - (void)drawImageOnWindow
38 [displayImage drawInRect:NSMakeRect(0, 0, NSWidth([window frame]), NSHeight([window frame]))
39 fromRect:NSMakeRect(0, 0, GRAPH_SIZE, GRAPH_SIZE) operation:NSCompositeCopy
44 - (void)showHideWindow
48 if ([[preferences objectForKey:SHOW_GRAPH_WINDOW_KEY] boolValue]) {
49 size = [[preferences objectForKey:GRAPH_WINDOW_SIZE_KEY] floatValue];
50 [window setContentSize:NSMakeSize(size, size)];
51 [window orderWindow:NSWindowBelow relativeTo:[preferences windowNumber]];
52 [window setLevel:([[preferences objectForKey:GRAPH_WINDOW_ON_TOP_KEY] boolValue] ?
53 NSFloatingWindowLevel : NSNormalWindowLevel)];
55 [window orderOut:self];
60 // completely redraw graphImage, put graph into displayImage
67 int barWidth = (int)[[preferences objectForKey:BAR_WIDTH_SIZE_KEY] floatValue];
68 // double interval = 0.1 * [[preferences objectForKey:UPDATE_FREQUENCY_KEY] floatValue];
70 [graphImage lockFocus];
72 // draw the cpu usage graph
73 [cpuInfo startIterate];
74 // for (x = 0; [memInfo getNext:&vmdata]; x++) {
75 for (x = 0; [cpuInfo getNext:&cpudata]; x+=barWidth) {
77 // y += vmdata.active * GRAPH_SIZE;
78 y = cpudata.sys * GRAPH_SIZE;
79 [[preferences objectForKey:SYS_COLOR_KEY] set];
80 NSRectFill (NSMakeRect(x - barWidth, 0.0, x, y));
82 // y += vmdata.inactive * GRAPH_SIZE;
83 y += cpudata.nice * GRAPH_SIZE;
84 [[preferences objectForKey:NICE_COLOR_KEY] set];
85 NSRectFill (NSMakeRect(x - barWidth, yy, x, y));
86 // y = vmdata.wired * GRAPH_SIZE;
89 y += cpudata.user * GRAPH_SIZE;
90 [[preferences objectForKey:USER_COLOR_KEY] set];
91 NSRectFill (NSMakeRect(x - barWidth, yy, x, y));
94 [[preferences objectForKey:IDLE_COLOR_KEY] set];
95 NSRectFill (NSMakeRect(x - barWidth, y, x, GRAPH_SIZE));
98 // transfer graph image to icon image
99 [graphImage unlockFocus];
100 [displayImage lockFocus];
101 [graphImage compositeToPoint:NSMakePoint(0.0, 0.0) operation:NSCompositeCopy];
103 [displayImage unlockFocus];
108 // update graphImage (based on previous graphImage), put graph into displayImage
110 // VMData vmdata, vmdata0;
111 CPUData cpudata, cpudata0;
112 int barWidth = (int)[[preferences objectForKey:BAR_WIDTH_SIZE_KEY] floatValue];
115 // double interval = 0.1 * [[preferences objectForKey:UPDATE_FREQUENCY_KEY] floatValue];
117 [graphImage lockFocus];
119 // offset the old graph image
120 [graphImage compositeToPoint:NSMakePoint(-barWidth, 0) operation:NSCompositeCopy];
122 // [memInfo getLast:&vmdata0];
123 [cpuInfo getLast:&cpudata0];
124 // [memInfo getCurrent:&vmdata];
125 [cpuInfo getCurrent:&cpudata];
127 // draw chronological graph into graph image
129 // y += vmdata.active * GRAPH_SIZE;
130 y = cpudata.sys * GRAPH_SIZE;
131 [[preferences objectForKey:SYS_COLOR_KEY] set];
132 NSRectFill (NSMakeRect(GRAPH_SIZE - barWidth, 0.0, GRAPH_SIZE - barWidth, y));
135 // y += vmdata.inactive * GRAPH_SIZE;
136 y += cpudata.nice * GRAPH_SIZE;
137 [[preferences objectForKey:NICE_COLOR_KEY] set];
138 NSRectFill (NSMakeRect(GRAPH_SIZE - barWidth, yy, GRAPH_SIZE - barWidth, y));
141 // y = vmdata.wired * GRAPH_SIZE;
142 y += cpudata.user * GRAPH_SIZE;
143 [[preferences objectForKey:USER_COLOR_KEY] set];
144 NSRectFill (NSMakeRect(GRAPH_SIZE - barWidth, yy, GRAPH_SIZE - barWidth, y));
147 [[preferences objectForKey:IDLE_COLOR_KEY] set];
148 NSRectFill (NSMakeRect(GRAPH_SIZE - barWidth, y, GRAPH_SIZE - barWidth, GRAPH_SIZE));
151 // transfer graph image to icon image
152 [graphImage unlockFocus];
153 [displayImage lockFocus];
154 [graphImage compositeToPoint:NSMakePoint(0.0, 0.0) operation:NSCompositeCopy];
156 [displayImage unlockFocus];
160 - (void)setApplicationIcon
161 // set the (scaled) application icon
163 float inc = GRAPH_SIZE * (1.0 - [[preferences objectForKey:DOCK_ICON_SIZE_KEY] floatValue]); // icon scaling
164 [iconImage lockFocus];
165 [displayImage drawInRect:NSMakeRect(inc, inc, GRAPH_SIZE - 2 * inc, GRAPH_SIZE - 2 * inc) fromRect:NSMakeRect(0, 0, GRAPH_SIZE, GRAPH_SIZE) operation:NSCompositeCopy fraction:1.0];
166 [iconImage unlockFocus];
167 [NSApp setApplicationIconImage:iconImage];
172 // get a new sample and refresh the graph
174 // [memInfo refresh];
177 [self setApplicationIcon];
179 if ([[preferences objectForKey:SHOW_GRAPH_WINDOW_KEY] boolValue]) {
180 [window disableFlushWindow];
182 [window enableFlushWindow];
183 [window flushWindow];
189 // completely redraw the graph (to show new preferences settings)
192 [iconImage lockFocus];
193 [[NSColor clearColor] set];
194 NSRectFill (NSMakeRect(0, 0, GRAPH_SIZE, GRAPH_SIZE));
195 [iconImage unlockFocus];
196 [self setApplicationIcon];
198 if ([[preferences objectForKey:SHOW_GRAPH_WINDOW_KEY] boolValue]) {
199 [window disableFlushWindow];
201 [window enableFlushWindow];
202 [window flushWindow];
209 double newInterval = 0.1 * [[preferences objectForKey:UPDATE_FREQUENCY_KEY] floatValue];
212 if (fabs([timer timeInterval] - newInterval) < 0.001)
213 return; /* frequency not changed */
217 timer = [NSTimer scheduledTimerWithTimeInterval:newInterval
218 target:self selector:@selector(refreshGraph) userInfo:nil repeats:YES];
223 - (void)showPreferences:(id)sender
225 [NSApp activateIgnoringOtherApps:YES]; /* activate application when called from Dock menu */
226 [preferences showPreferences:self];
230 - (void)showAboutBox:(id)sender
232 [NSApp activateIgnoringOtherApps:YES]; /* activate application when called from Dock menu */
233 [NSApp orderFrontStandardAboutPanel:sender];
241 NSString *cpuHistoryPath = [[NSBundle mainBundle] bundlePath];
242 NSDictionary *loginItemDict = [NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"%@/Library/Preferences/loginwindow.plist", NSHomeDirectory()]];
243 NSEnumerator *loginItemEnumerator = [[loginItemDict objectForKey:@"AutoLaunchedApplicationDictionary"] objectEnumerator];
245 while ((obj = [loginItemEnumerator nextObject])) {
246 if ([[obj objectForKey:@"Path"] isEqualTo:cpuHistoryPath])
253 - (BOOL)updateFrameName
254 // calculate the frameName used to save the window position; return TRUE iff the name changed,
255 // i. e. the display configuration changed since last call of this method
261 NSString *string = @"CHWL"; // CPUHistoryWindowLocation
262 NSEnumerator *enumerator = [[NSScreen screens] objectEnumerator];
264 while ((screen = [enumerator nextObject])) {
265 rect = [screen frame];
267 stringByAppendingString:[NSString stringWithFormat:@"%.0f%.0f%.0f%.0f",
268 rect.origin.x, rect.origin.y, rect.size.width, rect.size.height]];
270 nameDidChange = ! [string isEqualToString:frameName];
274 return (nameDidChange);
278 - (void)applicationDidFinishLaunching:(NSNotification *)notification
280 [NSApp setApplicationIconImage:[NSImage imageNamed:@"CPUHistory.icns"]];
282 preferences = [[Preferences alloc] init];
283 // memInfo = [[MemInfo alloc] initWithCapacity:GRAPH_SIZE];
284 cpuInfo = [[CPUInfo alloc] initWithCapacity:GRAPH_SIZE];
285 if (nil == cpuInfo) //then we need to bomb out. We can't do anything else.
287 NSLog(@"%s failed to create CPUInfo object!", _cmd);
288 NSString *errorStr = [[NSString alloc] initWithFormat:@"There's not enough memory to allocate the CPU data array. Sorry, but I have to quit now."];
289 /* now display error dialog and quit */
290 NSRunAlertPanel(@"Error", errorStr, @"OK", nil, nil);
293 [preferences release];
294 [NSApp terminate:nil];
297 displayImage = [[NSImage allocWithZone:[self zone]] initWithSize:NSMakeSize(GRAPH_SIZE, GRAPH_SIZE)];
298 graphImage = [[NSImage allocWithZone:[self zone]] initWithSize:NSMakeSize(GRAPH_SIZE, GRAPH_SIZE)];
299 iconImage = [[NSImage allocWithZone:[self zone]] initWithSize:NSMakeSize(GRAPH_SIZE, GRAPH_SIZE)];
302 window = [[TranslucentWindow allocWithZone:[self zone]]
303 initWithContentRect:NSMakeRect(0.0, 0.0, GRAPH_SIZE, GRAPH_SIZE)
304 styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
305 [window setReleasedWhenClosed:NO];
306 [window setBackgroundColor:[NSColor clearColor]];
307 [self updateFrameName];
308 [window setDelegate:self];
310 view = [[TranslucentView allocWithZone:[self zone]] initWithFrame:NSMakeRect(0.0, 0.0, GRAPH_SIZE, GRAPH_SIZE)];
311 [window setContentView:view];
312 [view setContentDrawer:self method:@selector(drawImageOnWindow)];
313 [view setAutoresizingMask:(NSViewHeightSizable | NSViewWidthSizable)];
314 [view setToolTip:@"CPU History"];
317 [self showHideWindow];
319 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(showHideWindow) name:PREFERENCES_CHANGED object:nil];
320 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateGraph) name:PREFERENCES_CHANGED object:nil];
321 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setTimer) name:PREFERENCES_CHANGED object:nil];
323 /* if ([self systemVersion] < 0x1010 && [self isLoginItem])
324 [NSTimer scheduledTimerWithTimeInterval:30 target:self selector:@selector(setTimer) userInfo:nil repeats:NO];
326 */ // We can stop supporting 10.1 now. Welcome to 2003, people.
331 - (void)applicationWillTerminate:(NSNotification *)aNotification
338 [preferences savePreferences];
339 [NSApp setApplicationIconImage:[NSImage imageNamed:@"CPUHistory.icns"]];
343 - (void)applicationDidChangeScreenParameters:(NSNotification *)aNotification
345 [self updateFrameName];
346 [window setFrameUsingName:frameName];
350 - (void)windowDidMove:(NSNotification *)aNotification
352 if (! [self updateFrameName])
353 [window saveFrameUsingName:frameName];