Index: trunk/Cocoa/AntiRSI/AUTHORS
===================================================================
--- trunk/Cocoa/AntiRSI/AUTHORS	(revision 327)
+++ trunk/Cocoa/AntiRSI/AUTHORS	(revision 327)
@@ -0,0 +1,1 @@
+Onne Gorter <o.gorter@student.utwente.nl>
Index: trunk/Cocoa/AntiRSI/AntiRSI.h
===================================================================
--- trunk/Cocoa/AntiRSI/AntiRSI.h	(revision 327)
+++ trunk/Cocoa/AntiRSI/AntiRSI.h	(revision 327)
@@ -0,0 +1,125 @@
+/*
+ author: Onne Gorter
+ 
+ This file is part of AntiRSI.
+ 
+ AntiRSI is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ 
+ AntiRSI is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with AntiRSI; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#import <Cocoa/Cocoa.h>
+#import "AntiRSIView.h"
+
+typedef enum _AntiRSIState {
+	s_normal = 0,
+	s_taking_micro_pause,
+	s_taking_work_break,
+} AntiRSIState;
+
+@interface AntiRSI : NSObject
+{
+	// views to display current status in
+	IBOutlet AntiRSIView *view;
+	IBOutlet NSLevelIndicator *progress;
+	IBOutlet NSButton *postpone;
+	IBOutlet NSTextField *time;
+	IBOutlet NSTextField *next_break;
+    IBOutlet NSTextField *status;
+    
+	// dock icon image
+	NSImage* dock_image;
+	NSImage* original_dock_image;
+	
+	// window to display the views in
+	NSWindow *main_window;
+	
+	// timer that ticks every second to update
+	NSTimer *mtimer;
+	
+	// various timers
+	double micro_pause_t;
+	double work_break_t;
+	double micro_pause_taking_t;
+	double work_break_taking_t;
+	double date;
+		
+	// various timing lengths
+	int micro_pause_period;
+	int micro_pause_duration;
+	int work_break_period;
+	int work_break_duration;
+	
+	double sample_interval;
+	
+	// verious other options
+	bool lock_focus;
+	bool draw_dock_image;
+	bool draw_dock_image_q;
+	
+	// various colors
+	NSColor* taking;
+	NSColor* elapsed;
+	NSColor* background;
+	NSColor* darkbackground;
+	
+	// state we are in
+	AntiRSIState state;
+	
+	// history filter
+	double h0;
+	double h1;
+	double h2;
+}
+
+//bindings
+- (void)setMicro_pause_duration:(float)f;
+- (void)setMicro_pause_period:(float)f;
+- (void)setWork_break_period:(float)f;
+- (void)setWork_break_period:(float)f;
+- (void)setSample_interval:(NSString *)s;
+- (void)setDraw_dock_image:(BOOL)b;
+- (void)setBackground:(NSColor *)c;
+
+
+// postpone button
+- (IBAction)postpone:(id)sender;
+
+// workbreak now menu item
+- (IBAction)breakNow:(id)sender;
+
+// one second ticks away ...
+- (void)tick:(NSTimer *)timer;
+
+// draw the dock icon
+- (void)drawDockImage;
+
+// run the micro pause window
+- (void)doMicroPause;
+
+// run the work break window
+- (void)doWorkBreak;
+
+// stop micro pause or work break
+- (void)endBreak;
+
+// time left string
+- (void)drawTimeLeft:(double)seconds;
+
+// time to next break string
+- (void)drawNextBreak:(int)seconds;
+
+@end
+
+
+
Index: trunk/Cocoa/AntiRSI/AntiRSI.m
===================================================================
--- trunk/Cocoa/AntiRSI/AntiRSI.m	(revision 327)
+++ trunk/Cocoa/AntiRSI/AntiRSI.m	(revision 327)
@@ -0,0 +1,601 @@
+/*
+ author: Onne Gorter
+ 
+ This file is part of AntiRSI.
+ 
+ AntiRSI is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ 
+ AntiRSI is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with AntiRSI; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#import "AntiRSI.h"
+
+#include <math.h>
+#include <ApplicationServices/ApplicationServices.h>
+
+extern double CGSSecondsSinceLastInputEvent(unsigned long eventType);
+
+@implementation AntiRSI
+
+// bindings methods
+- (void)setMicro_pause_duration:(float)f
+{
+	micro_pause_duration = round(f);
+	if (s_taking_micro_pause == state) {
+		[progress setMaxValue:micro_pause_duration];
+		[progress setDoubleValue:micro_pause_taking_t];
+	}
+}
+
+- (void)setMicro_pause_period:(float)f
+{	micro_pause_period = 60 * round(f); }
+
+- (void)setWork_break_duration:(float)f
+{   
+	work_break_duration = 60 * round(f); 
+	if (s_taking_work_break == state) {
+		[progress setMaxValue:work_break_duration / 60];
+		[progress setDoubleValue:work_break_taking_t / 60 - 0.5];
+	}
+}
+
+- (void)setWork_break_period:(float)f
+{	work_break_period = 60 * round(f); }
+
+- (void)installTimer:(double)interval
+{
+	if (mtimer != nil) {
+		[mtimer invalidate];
+		[mtimer autorelease];
+	}
+	mtimer = [[NSTimer scheduledTimerWithTimeInterval:interval target:self selector:@selector(tick:)
+                                             userInfo:nil repeats:YES] retain];
+}
+
+- (void)setSample_interval:(NSString *)s
+{
+	sample_interval = 1;
+	if ([s isEqualToString:@"Super Smooth"]) sample_interval = 0.1;
+	if ([s isEqualToString:@"Smooth"]) sample_interval = 0.33;
+	if ([s isEqualToString:@"Normal"]) sample_interval = 1;
+	if ([s isEqualToString:@"Low"]) sample_interval = 2;
+	
+	[self installTimer:sample_interval];
+}
+
+- (void)setDraw_dock_image:(BOOL)b 
+{
+	draw_dock_image=b;
+	if (!b) {
+		[NSApp setApplicationIconImage:[NSImage imageNamed:@"AntiRSI"]];
+	} else {
+		[self drawDockImage];
+	}
+}
+
+- (void)setBackground:(NSColor *)c
+{
+	[background autorelease];
+	background=[c retain];
+	
+	// make new darkbackground color
+	float r,g,b,a;
+	[background getRed:&r green:&g blue:&b alpha:&a];
+	[darkbackground autorelease];
+	darkbackground=[[NSColor colorWithCalibratedRed:r*0.35 green:g*0.35 blue:b*0.35 alpha:a+0.2] retain];
+	
+	[self drawDockImage];
+}
+
+- (void)setElapsed:(NSColor *)c
+{
+	[elapsed autorelease];
+	elapsed=[c retain];
+	[self drawDockImage];
+}
+
+- (void)setTaking:(NSColor *)c
+{
+	[taking autorelease];
+	taking=[c retain];
+	[self drawDockImage];
+}
+
+// end of bindings
+
+- (void)awakeFromNib
+{
+	// want transparancy
+	[NSColor setIgnoresAlpha:NO];
+	
+	// initial colors
+	elapsed = [[NSColor colorWithCalibratedRed:0.3 green:0.3 blue:0.9 alpha:0.95] retain];
+	taking = [[NSColor colorWithCalibratedRed:0.3 green:0.9 blue:0.3 alpha:0.90] retain];
+	background = [NSColor colorWithCalibratedRed:0.9 green:0.9 blue:0.9 alpha:0.7];
+	
+	//initial values
+	micro_pause_period = 4*60;
+	micro_pause_duration = 13;
+	work_break_period = 50*60;
+	work_break_duration = 8*60;
+	sample_interval = 1;
+	
+	// set current state
+	state = s_normal;
+	
+	// set timers to 0
+	micro_pause_t = 0;
+	work_break_t = 0;
+	micro_pause_taking_t = 0;
+	work_break_taking_t = 0;
+	
+	// setup images
+	micro_pause_image = [NSImage imageNamed:@"micro_pause"];
+	work_break_image = [NSImage imageNamed:@"work_break"];
+
+	// initialize dock image
+	dock_image = [[NSImage alloc] initWithSize:NSMakeSize(128,128)];
+	[dock_image setCacheMode:NSImageCacheNever];
+	original_dock_image = [NSImage imageNamed:@"AntiRSI"];
+	draw_dock_image_q = YES;
+	
+	// setup main window that will show either micropause or workbreak
+	main_window = [[NSWindow alloc] initWithContentRect:[view frame]
+											  styleMask:NSBorderlessWindowMask
+												backing:NSBackingStoreBuffered defer:YES];
+	[main_window setBackgroundColor:[NSColor clearColor]];
+	[main_window setLevel:NSStatusWindowLevel];
+	[main_window setAlphaValue:0.85];
+	[main_window setOpaque:NO];
+	[main_window setHasShadow:NO];
+	[main_window setMovableByWindowBackground:YES];
+	[main_window center];
+	[main_window setContentView:view];
+    [progress setEnabled:NO];
+	
+	// initialze history filter
+	h0 = 0;
+	h1 = 0;
+	h2 = 0;
+	
+	// initialize ticks
+	date = [NSDate timeIntervalSinceReferenceDate];
+	
+	// set background now
+	[self setBackground:background];
+	
+	// create initial values
+	NSMutableDictionary* initial = [NSMutableDictionary dictionaryWithCapacity:10];
+	[initial setObject:[NSNumber numberWithFloat:4] forKey:@"micro_pause_period"];
+	[initial setObject:[NSNumber numberWithFloat:13] forKey:@"micro_pause_duration"];
+	[initial setObject:[NSNumber numberWithFloat:50] forKey:@"work_break_period"];
+	[initial setObject:[NSNumber numberWithFloat:8] forKey:@"work_break_duration"];
+	[initial setObject:@"Normal" forKey:@"sample_interval"];
+	[initial setObject:[NSNumber numberWithBool:YES] forKey:@"draw_dock_image"];
+	[initial setObject:[NSNumber numberWithBool:NO] forKey:@"lock_focus"];
+	[initial setObject:[NSArchiver archivedDataWithRootObject:elapsed] forKey:@"elapsed"];
+	[initial setObject:[NSArchiver archivedDataWithRootObject:taking] forKey:@"taking"];
+	[initial setObject:[NSArchiver archivedDataWithRootObject:background] forKey:@"background"];
+	[[NSUserDefaultsController sharedUserDefaultsController] setInitialValues:initial];
+
+	// bind to defauls controller
+	id dc = [NSUserDefaultsController sharedUserDefaultsController];
+	[self bind:@"micro_pause_period" toObject:dc withKeyPath:@"values.micro_pause_period" options:nil];
+	[self bind:@"micro_pause_duration" toObject:dc withKeyPath:@"values.micro_pause_duration" options:nil];
+	[self bind:@"work_break_period" toObject:dc withKeyPath:@"values.work_break_period" options:nil];
+	[self bind:@"work_break_duration" toObject:dc withKeyPath:@"values.work_break_duration" options:nil];
+	[self bind:@"sample_interval" toObject:dc withKeyPath:@"values.sample_interval" options:nil];
+	[self bind:@"draw_dock_image" toObject:dc withKeyPath:@"values.draw_dock_image" options:nil];
+	[self bind:@"lock_focus" toObject:dc withKeyPath:@"values.lock_focus" options:nil];
+	NSDictionary* unarchive = [NSDictionary dictionaryWithObject:NSUnarchiveFromDataTransformerName forKey:@"NSValueTransformerName"];
+	[self bind:@"elapsed" toObject:dc withKeyPath:@"values.elapsed" options:unarchive];
+	[self bind:@"taking" toObject:dc withKeyPath:@"values.taking" options:unarchive];
+	[self bind:@"background" toObject:dc withKeyPath:@"values.background" options:unarchive];
+
+	// alert every binding
+	[[NSUserDefaultsController sharedUserDefaultsController] revert:self];
+
+	// start the timer
+	[self installTimer:sample_interval];
+}
+
+// tick every second and update status
+- (void)tick:(NSTimer *)timer
+{
+	// calculate time since last tick
+	double new_date = [NSDate timeIntervalSinceReferenceDate];
+	double tick_time = new_date - date;
+	date = new_date;
+	
+	// check if we are still on track of normal time, otherwise we might have slept or something
+	if (tick_time > work_break_duration) {
+		// set timers to 0
+		micro_pause_t = 0;
+		work_break_t = 0;
+		micro_pause_taking_t = micro_pause_duration;
+		work_break_taking_t = work_break_duration;
+		if (s_normal != state) {
+			[self endBreak];
+		}
+		// and do stuff on next tick
+		return;
+	}
+	
+	if (tick_time > micro_pause_duration && s_taking_work_break != state) {
+		// set micro_pause timers to 0
+		micro_pause_t = 0;
+		micro_pause_taking_t = micro_pause_duration;
+		if (s_normal != state) {
+			[self endBreak];
+		}
+		// and do stuff on next tick
+		return;
+	}
+	
+	// get idle time in seconds
+	double idle_time = CGSSecondsSinceLastInputEvent(kCGAnyInputEventType);
+    // double cgs_idle_time = idle_time;
+    // from other people's reverse engineering of this function, on MDD G4s this can return a large positive number when input is in progress
+    if (idle_time >= 18446744000.0) {
+        idle_time = 0.0;
+    } else if (CGEventSourceSecondsSinceLastEventType != NULL) {
+        // CGEventSourceSecondsSinceLastEventType in 10.4.2 returns a CGEventTimestamp of the last event, not a CFTimeInterval as is documented
+		CGEventType eventTypes[] = { kCGEventLeftMouseDown, kCGEventLeftMouseUp, kCGEventRightMouseDown, kCGEventRightMouseUp, kCGEventMouseMoved, kCGEventLeftMouseDragged, kCGEventRightMouseDragged, kCGEventKeyDown, kCGEventKeyUp, kCGEventFlagsChanged, kCGEventScrollWheel, kCGEventTabletPointer, kCGEventTabletProximity, kCGEventOtherMouseDown, kCGEventOtherMouseUp, kCGEventOtherMouseDragged, kCGEventNull };
+        double max_event_time = 0, event_time;
+        double current_time = CFAbsoluteTimeGetCurrent();
+        static double previous_time = 0;
+        for (CGEventType *eventType = eventTypes ; *eventType != kCGEventNull ; eventType++) {
+            event_time = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, *eventType);
+            if (event_time > max_event_time)
+                max_event_time = event_time;
+        }
+        const double NANOSECONDS = 1000000000;
+        static double event_time_offset = 0;
+        event_time = current_time - (max_event_time / NANOSECONDS) + event_time_offset;
+        if (fabs(previous_time - current_time) > 5) {
+            // calibrate offset for first time or after sleep/wake, etc.
+            UpdateSystemActivity(UsrActivity);
+            // despite what the docs say, kCGAnyInputEventType includes UpdateSystemActivity
+            event_time_offset = (CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGAnyInputEventType) / NANOSECONDS) - CFAbsoluteTimeGetCurrent(); 
+            // NSLog(@"reset offset to %.2f", event_time_offset);
+            idle_time = current_time - (max_event_time / NANOSECONDS) + event_time_offset;
+        } else {
+            idle_time = event_time;
+        }
+        previous_time = current_time;
+    }
+    // NSLog(@"CGEventSource %.2f, CGS %.2f", idle_time, cgs_idle_time);
+    
+	// calculate slack, this gives a sort of 3 history filtered idea.
+	BOOL slack = (h2 + h1 + h0 > 15);
+	
+	// if new event comes in history bumps up
+	if (h0 >= idle_time || idle_time < sample_interval) {
+		h2 = h1;
+		h1 = h0;
+	}
+	h0 = idle_time;
+	
+	switch (state) {
+		case s_normal:
+			// idle_time needs to be at least 0.3 * micro_pause_duration before kicking in
+			// but we cut the user some slack based on previous idle_times
+			if (idle_time <= micro_pause_duration * 0.3 && !slack) {
+				micro_pause_t += tick_time;
+				work_break_t += tick_time;
+				micro_pause_taking_t = 0;
+				work_break_taking_t = 0;
+			} else if (micro_pause_t > 0) {
+			// oke, leaway is over, increase micro_pause_taking_t unless micro_pause is already over
+				//micro_pause_t stays put
+				work_break_t += tick_time;
+				micro_pause_taking_t += tick_time;
+				work_break_taking_t = 0;
+			}
+			
+			// if micro_pause_taking_t is above micro_pause_duration, then micro pause is over, 
+			// if still idleing workbreak_taking_t kicks in unless it is already over
+			if (micro_pause_taking_t >= micro_pause_duration && work_break_t > 0) {
+				work_break_taking_t += tick_time;
+				micro_pause_t = 0;
+			}
+			
+			// if work_break_taking_t is above work_break_duration, then work break is over
+			if (work_break_taking_t >= work_break_duration) {
+				micro_pause_t = 0;
+				work_break_t = 0;
+				//micro_pause_taking_t stays put
+				// work_break_taking_t stays put
+			}
+		
+			// if user needs to take a micro pause
+			if (micro_pause_t >= micro_pause_period) {
+				// anticipate next workbreak by not issuing this micro_pause ...
+				if (work_break_t > work_break_period - (micro_pause_period / 2)) {
+					work_break_t = work_break_period;
+					[self doWorkBreak];
+				} else {
+					[self doMicroPause];
+				}
+			}
+			
+			// if user needs to take a work break
+			if (work_break_t >= work_break_period) {
+				// stop micro_pause stuff
+				micro_pause_t = 0;
+				micro_pause_taking_t = micro_pause_duration;
+				// and display window
+				[self doWorkBreak];
+			}
+		break;
+
+		// taking a micro pause with window
+		case s_taking_micro_pause:
+			// continue updating timers
+			micro_pause_taking_t += tick_time;
+			work_break_t += tick_time;
+			
+			// if we don't break, or interrupt the break, reset it
+			if (idle_time < 1 && !slack) {
+				micro_pause_taking_t = 0;
+			}
+				
+			// update window
+			[progress setDoubleValue:micro_pause_taking_t];
+			[self drawTimeLeft:micro_pause_duration - micro_pause_taking_t];
+			[self drawNextBreak:work_break_period - work_break_t];
+
+			// if user likes to be interrupted
+			if (lock_focus) {
+				[NSApp activateIgnoringOtherApps:YES];
+				[main_window makeKeyAndOrderFront:self];
+			}
+			
+			// check if we done enough
+			if (micro_pause_taking_t > micro_pause_duration) {
+				micro_pause_t = 0;
+				[self endBreak];
+			}
+		
+			// if workbreak must be run ...
+			if (work_break_t >= work_break_period) {
+				// stop micro_pause stuff
+				micro_pause_t = 0;
+				micro_pause_taking_t = micro_pause_duration;
+				// and display window
+				[self doWorkBreak];
+			} else {
+                double slip = (micro_pause_duration - micro_pause_taking_t) - (int)(micro_pause_duration - micro_pause_taking_t);
+                [self installTimer: slip < 0.1 ? 1 : slip];
+            }
+			break;
+		
+		// taking a work break with window
+		case s_taking_work_break:
+			// increase work_break_taking_t
+			if (idle_time >= 2 || work_break_taking_t < 3) {
+				work_break_taking_t += tick_time;
+			}
+			
+			// draw window
+			[progress setDoubleValue:work_break_taking_t / 60 - 0.5];
+			[self drawTimeLeft:work_break_duration - work_break_taking_t];
+			[self drawNextBreak:work_break_period + work_break_duration - work_break_taking_t];
+			
+			// if user likes to be interrupted
+			if (lock_focus) {
+				[NSApp activateIgnoringOtherApps:YES];
+				[main_window makeKeyAndOrderFront:self];
+			}
+
+			// and check if we done enough
+			if (work_break_taking_t > work_break_duration) {
+				micro_pause_t = 0;
+				micro_pause_taking_t = micro_pause_duration;
+				work_break_t = 0;
+				work_break_taking_t = work_break_duration;
+				[self endBreak];
+			} else {
+                double slip = (work_break_duration - work_break_taking_t) - (int)(work_break_duration - work_break_taking_t);
+                [self installTimer: slip < 0.1 ? 1 : slip];
+            }
+			break;
+	}
+	
+	// draw dock image
+	if (draw_dock_image) [self drawDockImage];
+}
+
+// draw the dock icon
+- (void)drawDockImage
+{
+	[dock_image lockFocus];
+	
+	// clear all
+	[[NSColor clearColor] set];  
+	NSRectFill(NSMakeRect(0,0,127,127));
+	
+	NSBezierPath* p;
+	float end;
+	
+	//draw background circle
+	[darkbackground set];
+	p =[NSBezierPath bezierPathWithOvalInRect:NSMakeRect(6,6,115,115)];
+	[p setLineWidth:4];
+	[p stroke];
+	
+	//fill
+	[background set];
+	[[NSBezierPath bezierPathWithOvalInRect:NSMakeRect(8,8,111,111)] fill];
+	
+	//put dot in middle
+	[darkbackground set];
+	[[NSBezierPath bezierPathWithOvalInRect:NSMakeRect(59,59,9,9)] fill];
+
+	// reuse this one
+	p = [NSBezierPath bezierPath];
+
+	// draw work_break
+	[elapsed set];
+	end = 360 - (360.0 / work_break_period * work_break_t - 90);
+	if (end <= 90) end=90.1;
+	[p appendBezierPathWithArcWithCenter:NSMakePoint(63.5, 63.5) radius:40 startAngle:90 endAngle:end clockwise:YES];
+	[p setLineWidth:22];
+	[p stroke];
+	
+	// draw work break taking
+	[taking set];
+	[p removeAllPoints];
+	end = 360 - (360.0 / work_break_duration * work_break_taking_t - 90);
+	if (end <= 90) end=90.1;
+	[p appendBezierPathWithArcWithCenter:NSMakePoint(63.5, 63.5) radius:40 startAngle:90 endAngle:end clockwise:YES];
+	[p setLineWidth:18];
+	[p stroke];
+	
+	// draw micro pause
+	[elapsed set];
+	[p removeAllPoints];
+	end = 360 - (360.0 / micro_pause_period * micro_pause_t - 90);
+	if (end <= 90) end = 90.1;
+	[p appendBezierPathWithArcWithCenter:NSMakePoint(63.5, 63.5) radius:17 startAngle:90 endAngle:end clockwise:YES];
+	[p setLineWidth:22];
+	[p stroke];
+	
+	// draw micro pause taking
+	[taking set];
+	[p removeAllPoints];
+	end = 360 - (360.0 / micro_pause_duration * micro_pause_taking_t - 90);
+	if (end <= 90) end = 90.1;
+	[p appendBezierPathWithArcWithCenter:NSMakePoint(63.5, 63.5) radius:17 startAngle:90 endAngle:end clockwise:YES];
+	[p setLineWidth:18];
+	[p stroke];
+	
+	[dock_image unlockFocus];
+
+	// and set it in the dock check draw_dock_image one last time ...
+	if (draw_dock_image_q) [NSApp setApplicationIconImage:dock_image];
+}
+
+// done with micro pause or work break
+- (void)endBreak
+{
+	[main_window orderOut:NULL];
+	state = s_normal;
+	// reset time interval to user's choice
+	[self installTimer:sample_interval];
+}
+
+// display micro_pause window with appropriate widgets and progress bar
+- (void)doMicroPause
+{
+	micro_pause_taking_t = 0;
+	[view setImage:micro_pause_image];
+	[progress setMaxValue:micro_pause_duration];
+	[progress setDoubleValue:micro_pause_taking_t];
+    [progress setWarningValue: 1];
+    [progress setCriticalValue: micro_pause_duration];
+	[postpone setHidden:YES];
+	state = s_taking_micro_pause;
+	[self tick: nil];
+	[main_window center];
+	[main_window orderFrontRegardless];
+}
+
+// display work_break window with appropriate widgets and progress bar
+- (void)doWorkBreak
+{
+	work_break_taking_t = 0;
+	[view setImage:work_break_image];
+	[progress setMaxValue:work_break_duration / 60];
+	[progress setDoubleValue:work_break_taking_t / 60 - 0.5];
+    [progress setWarningValue: 0];
+    [progress setCriticalValue: 0.4];
+	[postpone setHidden:NO];
+	state = s_taking_work_break;
+    [self tick: nil];
+	[main_window center];
+	[main_window orderFrontRegardless];
+}
+
+// diplays time left
+- (void)drawTimeLeft:(double)seconds
+{
+	[time setStringValue:[NSString stringWithFormat:@"%d:%02d", lrint(seconds) / 60, lrint(seconds) % 60]];
+}
+
+// displays next break
+- (void)drawNextBreak:(int)seconds
+{
+	int minutes = round(seconds / 60.0) ;
+	
+	// nice hours, minutes ... 
+	if (minutes > 60) {
+		[next_break setStringValue:[NSString stringWithFormat:@"next break in %d:%02d hours", 
+			minutes / 60, minutes % 60]];
+	} else {
+		[next_break setStringValue:[NSString stringWithFormat:@"next break in %d minutes", minutes]];
+	}
+}
+
+// stop work break and postpone by 10 minutes
+- (IBAction)postpone:(id)sender
+{
+	if (s_taking_work_break == state) {
+		micro_pause_t = 0;
+		micro_pause_taking_t = 0;
+		work_break_taking_t = 0;
+		work_break_t -= 10*60; // decrease with 10 minutes
+		if (work_break_t < 0) work_break_t = 0;
+		[self endBreak];
+	}
+}
+
+- (IBAction)breakNow:(id)sender
+{
+	[self doWorkBreak];
+}
+
+// validate menu items
+- (BOOL)validateMenuItem:(NSMenuItem *)anItem
+{
+	if ([[anItem title] isEqualToString:@"Take Break Now"] && state == s_normal) {
+		return YES;
+	}
+	
+	if ([[anItem title] isEqualToString:@"Postpone Break"] && state == s_taking_work_break) {
+		return YES;
+	}
+	
+	return NO;
+}
+
+// we are delegate of NSApplication, so we can restore the icon on quit.
+- (void)applicationWillTerminate:(NSNotification *)aNotification
+{
+	// make sure timer doesn't tick once more ...
+	draw_dock_image_q = NO;
+	[mtimer invalidate];
+	[mtimer autorelease];
+	mtimer = nil;
+	[dock_image release];
+	// stupid fix for icon beeing restored ... it is not my fault,
+	// the dock or NSImage or setApplicationIconImage seem to be caching or taking
+	// snapshot or something ... !
+	[NSApp setApplicationIconImage:original_dock_image];
+	[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
+	[NSApp setApplicationIconImage:original_dock_image];
+
+}
+
+@end
+
Index: trunk/Cocoa/AntiRSI/AntiRSI.xcodeproj/project.pbxproj
===================================================================
--- trunk/Cocoa/AntiRSI/AntiRSI.xcodeproj/project.pbxproj	(revision 327)
+++ trunk/Cocoa/AntiRSI/AntiRSI.xcodeproj/project.pbxproj	(revision 327)
@@ -0,0 +1,399 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 42;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		4DB6164E061B59EA002EF355 /* AntiRSI.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DB6164C061B59EA002EF355 /* AntiRSI.h */; };
+		4DB6164F061B59EA002EF355 /* AntiRSI.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DB6164D061B59EA002EF355 /* AntiRSI.m */; };
+		4DF73F67061E136200B0D9C9 /* AntiRSIView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DF73F65061E136200B0D9C9 /* AntiRSIView.m */; };
+		4DF73F68061E136200B0D9C9 /* AntiRSIView.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DF73F66061E136200B0D9C9 /* AntiRSIView.h */; };
+		4DF73F86061E155C00B0D9C9 /* AntiRSI.icns in Resources */ = {isa = PBXBuildFile; fileRef = 4DF73F85061E155C00B0D9C9 /* AntiRSI.icns */; };
+		8D1107280486CEB800E47090 /* AntiRSI_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 32CA4F630368D1EE00C91783 /* AntiRSI_Prefix.pch */; };
+		8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 29B97318FDCFA39411CA2CEA /* MainMenu.nib */; };
+		8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
+		8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
+		8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+		E1203BFC0894184900759E75 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E1203BFB0894184900759E75 /* ApplicationServices.framework */; };
+		E1F60361098592D800806C3B /* AntiRSILevelIndicator.m in Sources */ = {isa = PBXBuildFile; fileRef = E1F6035F098592D800806C3B /* AntiRSILevelIndicator.m */; };
+		E1F60362098592D800806C3B /* AntiRSILevelIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = E1F60360098592D800806C3B /* AntiRSILevelIndicator.h */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+		089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+		1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+		29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+		29B97319FDCFA39411CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = "<group>"; };
+		29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
+		29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
+		32CA4F630368D1EE00C91783 /* AntiRSI_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AntiRSI_Prefix.pch; sourceTree = "<group>"; };
+		4DB6164C061B59EA002EF355 /* AntiRSI.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AntiRSI.h; sourceTree = "<group>"; };
+		4DB6164D061B59EA002EF355 /* AntiRSI.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = AntiRSI.m; sourceTree = "<group>"; wrapsLines = 1; };
+		4DF73F65061E136200B0D9C9 /* AntiRSIView.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = AntiRSIView.m; sourceTree = "<group>"; };
+		4DF73F66061E136200B0D9C9 /* AntiRSIView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AntiRSIView.h; sourceTree = "<group>"; };
+		4DF73F85061E155C00B0D9C9 /* AntiRSI.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AntiRSI.icns; sourceTree = "<group>"; };
+		8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
+		8D1107320486CEB800E47090 /* AntiRSI.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AntiRSI.app; sourceTree = BUILT_PRODUCTS_DIR; };
+		E1203BFB0894184900759E75 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = "<absolute>"; };
+		E1F6035F098592D800806C3B /* AntiRSILevelIndicator.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = AntiRSILevelIndicator.m; sourceTree = "<group>"; };
+		E1F60360098592D800806C3B /* AntiRSILevelIndicator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AntiRSILevelIndicator.h; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		8D11072E0486CEB800E47090 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
+				E1203BFC0894184900759E75 /* ApplicationServices.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		080E96DDFE201D6D7F000001 /* Classes */ = {
+			isa = PBXGroup;
+			children = (
+				4DB6164C061B59EA002EF355 /* AntiRSI.h */,
+				4DB6164D061B59EA002EF355 /* AntiRSI.m */,
+				4DF73F66061E136200B0D9C9 /* AntiRSIView.h */,
+				4DF73F65061E136200B0D9C9 /* AntiRSIView.m */,
+				E1F6035F098592D800806C3B /* AntiRSILevelIndicator.m */,
+				E1F60360098592D800806C3B /* AntiRSILevelIndicator.h */,
+			);
+			name = Classes;
+			sourceTree = "<group>";
+		};
+		1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
+			);
+			name = "Linked Frameworks";
+			sourceTree = "<group>";
+		};
+		1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				E1203BFB0894184900759E75 /* ApplicationServices.framework */,
+				29B97325FDCFA39411CA2CEA /* Foundation.framework */,
+				29B97324FDCFA39411CA2CEA /* AppKit.framework */,
+			);
+			name = "Other Frameworks";
+			sourceTree = "<group>";
+		};
+		19C28FACFE9D520D11CA2CBB /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				8D1107320486CEB800E47090 /* AntiRSI.app */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		29B97314FDCFA39411CA2CEA /* AntiRSI */ = {
+			isa = PBXGroup;
+			children = (
+				080E96DDFE201D6D7F000001 /* Classes */,
+				29B97315FDCFA39411CA2CEA /* Other Sources */,
+				29B97317FDCFA39411CA2CEA /* Resources */,
+				29B97323FDCFA39411CA2CEA /* Frameworks */,
+				19C28FACFE9D520D11CA2CBB /* Products */,
+			);
+			name = AntiRSI;
+			sourceTree = "<group>";
+		};
+		29B97315FDCFA39411CA2CEA /* Other Sources */ = {
+			isa = PBXGroup;
+			children = (
+				32CA4F630368D1EE00C91783 /* AntiRSI_Prefix.pch */,
+				29B97316FDCFA39411CA2CEA /* main.m */,
+			);
+			name = "Other Sources";
+			sourceTree = "<group>";
+		};
+		29B97317FDCFA39411CA2CEA /* Resources */ = {
+			isa = PBXGroup;
+			children = (
+				4DF73F85061E155C00B0D9C9 /* AntiRSI.icns */,
+				8D1107310486CEB800E47090 /* Info.plist */,
+				089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
+				29B97318FDCFA39411CA2CEA /* MainMenu.nib */,
+			);
+			name = Resources;
+			sourceTree = "<group>";
+		};
+		29B97323FDCFA39411CA2CEA /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
+				1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+		8D1107270486CEB800E47090 /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				8D1107280486CEB800E47090 /* AntiRSI_Prefix.pch in Headers */,
+				4DB6164E061B59EA002EF355 /* AntiRSI.h in Headers */,
+				4DF73F68061E136200B0D9C9 /* AntiRSIView.h in Headers */,
+				E1F60362098592D800806C3B /* AntiRSILevelIndicator.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+		8D1107260486CEB800E47090 /* AntiRSI */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = E1203B7B0894152100759E75 /* Build configuration list for PBXNativeTarget "AntiRSI" */;
+			buildPhases = (
+				8D1107270486CEB800E47090 /* Headers */,
+				8D1107290486CEB800E47090 /* Resources */,
+				8D11072C0486CEB800E47090 /* Sources */,
+				8D11072E0486CEB800E47090 /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = AntiRSI;
+			productInstallPath = "$(HOME)/Applications";
+			productName = AntiRSI;
+			productReference = 8D1107320486CEB800E47090 /* AntiRSI.app */;
+			productType = "com.apple.product-type.application";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		29B97313FDCFA39411CA2CEA /* Project object */ = {
+			isa = PBXProject;
+			buildConfigurationList = E1203B7F0894152100759E75 /* Build configuration list for PBXProject "AntiRSI" */;
+			hasScannedForEncodings = 1;
+			knownRegions = (
+				English,
+				Japanese,
+				French,
+				German,
+				Spanish,
+			);
+			mainGroup = 29B97314FDCFA39411CA2CEA /* AntiRSI */;
+			projectDirPath = "";
+			targets = (
+				8D1107260486CEB800E47090 /* AntiRSI */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		8D1107290486CEB800E47090 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */,
+				8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */,
+				4DF73F86061E155C00B0D9C9 /* AntiRSI.icns in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		8D11072C0486CEB800E47090 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				8D11072D0486CEB800E47090 /* main.m in Sources */,
+				4DB6164F061B59EA002EF355 /* AntiRSI.m in Sources */,
+				4DF73F67061E136200B0D9C9 /* AntiRSIView.m in Sources */,
+				E1F60361098592D800806C3B /* AntiRSILevelIndicator.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+		089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = {
+			isa = PBXVariantGroup;
+			children = (
+				089C165DFE840E0CC02AAC07 /* English */,
+			);
+			name = InfoPlist.strings;
+			sourceTree = "<group>";
+		};
+		29B97318FDCFA39411CA2CEA /* MainMenu.nib */ = {
+			isa = PBXVariantGroup;
+			children = (
+				29B97319FDCFA39411CA2CEA /* English */,
+			);
+			name = MainMenu.nib;
+			sourceTree = "<group>";
+		};
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+		E1203B7C0894152100759E75 /* Development */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = (
+					ppc,
+					i386,
+				);
+				COPY_PHASE_STRIP = NO;
+				DEBUGGING_SYMBOLS = YES;
+				DEPLOYMENT_LOCATION = NO;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Versions/A/Frameworks\"";
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_ENABLE_TRIGRAPHS = NO;
+				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = AntiRSI_Prefix.pch;
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
+				GCC_WARN_UNKNOWN_PRAGMAS = NO;
+				HEADER_SEARCH_PATHS = "";
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = "$(HOME)/Applications";
+				LIBRARY_SEARCH_PATHS = "";
+				OPTIMIZATION_CFLAGS = "-O0";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				PRODUCT_NAME = AntiRSI;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = (
+					"-Wmost",
+					"-Wno-four-char-constants",
+					"-Wno-unknown-pragmas",
+				);
+				WRAPPER_EXTENSION = app;
+				ZERO_LINK = YES;
+			};
+			name = Development;
+		};
+		E1203B7D0894152100759E75 /* Deployment */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = (
+					ppc,
+					i386,
+				);
+				COPY_PHASE_STRIP = YES;
+				DEPLOYMENT_LOCATION = NO;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Versions/A/Frameworks\"";
+				GCC_ENABLE_FIX_AND_CONTINUE = NO;
+				GCC_ENABLE_TRIGRAPHS = NO;
+				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = AntiRSI_Prefix.pch;
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
+				GCC_WARN_UNKNOWN_PRAGMAS = NO;
+				HEADER_SEARCH_PATHS = "";
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = "$(HOME)/Applications";
+				LIBRARY_SEARCH_PATHS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				PRODUCT_NAME = AntiRSI;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = (
+					"-Wmost",
+					"-Wno-four-char-constants",
+					"-Wno-unknown-pragmas",
+				);
+				WRAPPER_EXTENSION = app;
+				ZERO_LINK = NO;
+			};
+			name = Deployment;
+		};
+		E1203B7E0894152100759E75 /* Default */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = (
+					ppc,
+					i386,
+				);
+				DEPLOYMENT_LOCATION = NO;
+				FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Versions/A/Frameworks\"";
+				GCC_ENABLE_TRIGRAPHS = NO;
+				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = AntiRSI_Prefix.pch;
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
+				GCC_WARN_UNKNOWN_PRAGMAS = NO;
+				HEADER_SEARCH_PATHS = "";
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = "$(HOME)/Applications";
+				LIBRARY_SEARCH_PATHS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				PRODUCT_NAME = AntiRSI;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = (
+					"-Wmost",
+					"-Wno-four-char-constants",
+					"-Wno-unknown-pragmas",
+				);
+				WRAPPER_EXTENSION = app;
+			};
+			name = Default;
+		};
+		E1203B800894152100759E75 /* Development */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				GCC_C_LANGUAGE_STANDARD = c99;
+			};
+			name = Development;
+		};
+		E1203B810894152100759E75 /* Deployment */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				GCC_C_LANGUAGE_STANDARD = c99;
+			};
+			name = Deployment;
+		};
+		E1203B820894152100759E75 /* Default */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				GCC_C_LANGUAGE_STANDARD = c99;
+			};
+			name = Default;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		E1203B7B0894152100759E75 /* Build configuration list for PBXNativeTarget "AntiRSI" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				E1203B7C0894152100759E75 /* Development */,
+				E1203B7D0894152100759E75 /* Deployment */,
+				E1203B7E0894152100759E75 /* Default */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Default;
+		};
+		E1203B7F0894152100759E75 /* Build configuration list for PBXProject "AntiRSI" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				E1203B800894152100759E75 /* Development */,
+				E1203B810894152100759E75 /* Deployment */,
+				E1203B820894152100759E75 /* Default */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Default;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
+}
Index: trunk/Cocoa/AntiRSI/AntiRSILevelIndicator.h
===================================================================
--- trunk/Cocoa/AntiRSI/AntiRSILevelIndicator.h	(revision 327)
+++ trunk/Cocoa/AntiRSI/AntiRSILevelIndicator.h	(revision 327)
@@ -0,0 +1,8 @@
+/* AntiRSILevelIndicator */
+
+#import <Cocoa/Cocoa.h>
+
+@interface AntiRSILevelIndicator : NSLevelIndicator
+{
+}
+@end
Index: trunk/Cocoa/AntiRSI/AntiRSILevelIndicator.m
===================================================================
--- trunk/Cocoa/AntiRSI/AntiRSILevelIndicator.m	(revision 327)
+++ trunk/Cocoa/AntiRSI/AntiRSILevelIndicator.m	(revision 327)
@@ -0,0 +1,10 @@
+#import "AntiRSILevelIndicator.h"
+
+@implementation AntiRSILevelIndicator
+
+- (BOOL)mouseDownCanMoveWindow;
+{
+    return true;
+}
+
+@end
Index: trunk/Cocoa/AntiRSI/AntiRSIView.h
===================================================================
--- trunk/Cocoa/AntiRSI/AntiRSIView.h	(revision 327)
+++ trunk/Cocoa/AntiRSI/AntiRSIView.h	(revision 327)
@@ -0,0 +1,27 @@
+/*
+ author: Onne Gorter
+ 
+ This file is part of AntiRSI.
+ 
+ AntiRSI is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ 
+ AntiRSI is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with AntiRSI; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#import <Cocoa/Cocoa.h>
+
+@interface AntiRSIView : NSView
+{
+}
+
+@end
Index: trunk/Cocoa/AntiRSI/AntiRSIView.m
===================================================================
--- trunk/Cocoa/AntiRSI/AntiRSIView.m	(revision 327)
+++ trunk/Cocoa/AntiRSI/AntiRSIView.m	(revision 327)
@@ -0,0 +1,69 @@
+/*
+ author: Onne Gorter
+ 
+ This file is part of AntiRSI.
+ 
+ AntiRSI is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ 
+ AntiRSI is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with AntiRSI; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#import "AntiRSIView.h"
+
+@implementation AntiRSIView
+
+- (void)drawRect:(NSRect)rect
+{
+    NSColor *bgColor = [NSColor colorWithCalibratedWhite:0.0 alpha:0.90];
+    NSRect bgRect = [self bounds];
+    int minX = NSMinX(bgRect);
+    int midX = NSMidX(bgRect);
+    int maxX = NSMaxX(bgRect);
+    int minY = NSMinY(bgRect);
+    int midY = NSMidY(bgRect);
+    int maxY = NSMaxY(bgRect);
+    float radius = 25.0; // correct value to duplicate Panther's App Switcher
+    NSBezierPath *bgPath = [NSBezierPath bezierPath];
+
+    /* XXX from Casey Marshall's version; does it help with the hole-in-window problem? */
+	[[NSColor clearColor] set];
+    NSRectFill(bgRect);
+    /* XXX end */
+    
+    // Bottom edge and bottom-right curve
+    [bgPath moveToPoint:NSMakePoint(midX, minY)];
+    [bgPath appendBezierPathWithArcFromPoint:NSMakePoint(maxX, minY) 
+                                     toPoint:NSMakePoint(maxX, midY) 
+                                      radius:radius];
+    
+    // Right edge and top-right curve
+    [bgPath appendBezierPathWithArcFromPoint:NSMakePoint(maxX, maxY) 
+                                     toPoint:NSMakePoint(midX, maxY) 
+                                      radius:radius];
+    
+    // Top edge and top-left curve
+    [bgPath appendBezierPathWithArcFromPoint:NSMakePoint(minX, maxY) 
+                                     toPoint:NSMakePoint(minX, midY) 
+                                      radius:radius];
+    
+    // Left edge and bottom-left curve
+    [bgPath appendBezierPathWithArcFromPoint:bgRect.origin 
+                                     toPoint:NSMakePoint(midX, minY) 
+                                      radius:radius];
+    [bgPath closePath];
+    
+    [bgColor set];
+    [bgPath fill];
+}
+
+@end
Index: trunk/Cocoa/AntiRSI/AntiRSI_Prefix.pch
===================================================================
--- trunk/Cocoa/AntiRSI/AntiRSI_Prefix.pch	(revision 327)
+++ trunk/Cocoa/AntiRSI/AntiRSI_Prefix.pch	(revision 327)
@@ -0,0 +1,7 @@
+//
+// Prefix header for all source files of the 'AntiRSI' target in the 'AntiRSI' project
+//
+
+#ifdef __OBJC__
+    #import <Cocoa/Cocoa.h>
+#endif
Index: trunk/Cocoa/AntiRSI/COPYING
===================================================================
--- trunk/Cocoa/AntiRSI/COPYING	(revision 327)
+++ trunk/Cocoa/AntiRSI/COPYING	(revision 327)
@@ -0,0 +1,345 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
Index: trunk/Cocoa/AntiRSI/English.lproj/MainMenu.nib/classes.nib
===================================================================
--- trunk/Cocoa/AntiRSI/English.lproj/MainMenu.nib/classes.nib	(revision 327)
+++ trunk/Cocoa/AntiRSI/English.lproj/MainMenu.nib/classes.nib	(revision 327)
@@ -0,0 +1,27 @@
+{
+    IBClasses = (
+        {
+            ACTIONS = {breakNow = id; postpone = id; }; 
+            CLASS = AntiRSI; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {
+                "next_break" = NSTextField; 
+                postpone = NSButton; 
+                progress = NSLevelIndicator; 
+                status = NSTextField; 
+                time = NSTextField; 
+                view = AntiRSIView; 
+            }; 
+            SUPERCLASS = NSObject; 
+        }, 
+        {
+            CLASS = AntiRSILevelIndicator; 
+            LANGUAGE = ObjC; 
+            SUPERCLASS = NSLevelIndicator; 
+        }, 
+        {CLASS = AntiRSIView; LANGUAGE = ObjC; SUPERCLASS = NSView; }, 
+        {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 
+        {CLASS = NSLevelIndicator; LANGUAGE = ObjC; SUPERCLASS = NSControl; }
+    ); 
+    IBVersion = 1; 
+}
Index: trunk/Cocoa/AntiRSI/English.lproj/MainMenu.nib/info.nib
===================================================================
--- trunk/Cocoa/AntiRSI/English.lproj/MainMenu.nib/info.nib	(revision 327)
+++ trunk/Cocoa/AntiRSI/English.lproj/MainMenu.nib/info.nib	(revision 327)
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IBDocumentLocation</key>
+	<string>35 305 441 309 0 0 1680 1028 </string>
+	<key>IBEditorPositions</key>
+	<dict>
+		<key>259</key>
+		<string>340 618 300 322 0 0 1680 1028 </string>
+		<key>29</key>
+		<string>142 885 330 44 0 0 1680 1028 </string>
+		<key>343</key>
+		<string>64 674 189 68 0 0 1680 1028 </string>
+	</dict>
+	<key>IBFramework Version</key>
+	<string>443.0</string>
+	<key>IBOpenObjects</key>
+	<array>
+		<integer>438</integer>
+		<integer>343</integer>
+		<integer>259</integer>
+		<integer>29</integer>
+	</array>
+	<key>IBSystem Version</key>
+	<string>8I127</string>
+</dict>
+</plist>
Index: trunk/Cocoa/AntiRSI/Info.plist
===================================================================
--- trunk/Cocoa/AntiRSI/Info.plist	(revision 327)
+++ trunk/Cocoa/AntiRSI/Info.plist	(revision 327)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>AntiRSI</string>
+	<key>CFBundleIconFile</key>
+	<string>AntiRSI.icns</string>
+	<key>CFBundleIdentifier</key>
+	<string>com.gorter.antirsi</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleSignature</key>
+	<string>ONNE</string>
+	<key>CFBundleVersion</key>
+	<string>1.3</string>
+	<key>NSMainNibFile</key>
+	<string>MainMenu</string>
+	<key>NSPrincipalClass</key>
+	<string>NSApplication</string>
+</dict>
+</plist>
Index: trunk/Cocoa/AntiRSI/main.m
===================================================================
--- trunk/Cocoa/AntiRSI/main.m	(revision 327)
+++ trunk/Cocoa/AntiRSI/main.m	(revision 327)
@@ -0,0 +1,26 @@
+/*
+ author: Onne Gorter
+ 
+ This file is part of AntiRSI.
+ 
+ AntiRSI is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ 
+ AntiRSI is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with AntiRSI; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#import <Cocoa/Cocoa.h>
+
+int main(int argc, const char *argv[])
+{
+    return NSApplicationMain(argc, argv);
+}
Index: trunk/Cocoa/AntiRSI/version.plist
===================================================================
--- trunk/Cocoa/AntiRSI/version.plist	(revision 327)
+++ trunk/Cocoa/AntiRSI/version.plist	(revision 327)
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>BuildVersion</key>
+	<string>17</string>
+	<key>CFBundleShortVersionString</key>
+	<string>0.1</string>
+	<key>CFBundleVersion</key>
+	<string>0.1</string>
+	<key>ProjectName</key>
+	<string>NibPBTemplates</string>
+	<key>SourceVersion</key>
+	<string>1150000</string>
+</dict>
+</plist>
