diff --git a/2Term.xcodeproj/project.pbxproj b/2Term.xcodeproj/project.pbxproj index 43192e7..a3c5e67 100644 --- a/2Term.xcodeproj/project.pbxproj +++ b/2Term.xcodeproj/project.pbxproj @@ -53,6 +53,7 @@ B6C704F015CCC64100CC0401 /* titlebar-left@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B6C704ED15CCC64100CC0401 /* titlebar-left@2x.png */; }; B6C704F115CCC64100CC0401 /* titlebar-right@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B6C704EE15CCC64100CC0401 /* titlebar-right@2x.png */; }; B6EBE2B511E0EA9100EA0458 /* CharacterGenerator.m in Sources */ = {isa = PBXBuildFile; fileRef = B6EBE2B411E0EA9100EA0458 /* CharacterGenerator.m */; }; + B6ECFF271D2EEA2B00871A81 /* TextLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = B6ECFF261D2EEA2B00871A81 /* TextLabel.m */; }; /* End PBXBuildFile section */ /* Begin PBXBuildRule section */ @@ -155,6 +156,8 @@ B6C704EE15CCC64100CC0401 /* titlebar-right@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "titlebar-right@2x.png"; sourceTree = ""; }; B6EBE2B311E0EA9100EA0458 /* CharacterGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CharacterGenerator.h; sourceTree = ""; }; B6EBE2B411E0EA9100EA0458 /* CharacterGenerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CharacterGenerator.m; sourceTree = ""; }; + B6ECFF251D2EEA2B00871A81 /* TextLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextLabel.h; sourceTree = ""; }; + B6ECFF261D2EEA2B00871A81 /* TextLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TextLabel.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -317,6 +320,8 @@ B612870D1480B4F6002E04DF /* TermContentView.m */, B61EF7CA14815E07008C1891 /* TitleBarView.h */, B61EF7CB14815E07008C1891 /* TitleBarView.m */, + B6ECFF251D2EEA2B00871A81 /* TextLabel.h */, + B6ECFF261D2EEA2B00871A81 /* TextLabel.m */, B638188014A179D60027D007 /* ColorView.h */, B638188114A179D60027D007 /* ColorView.m */, ); @@ -428,6 +433,7 @@ B60EBDE311E90FC300C1974F /* ScanLineFilter.m in Sources */, B61D0D60125B7ACA001C713B /* NewTerminalWindowController.m in Sources */, B61D0D69125B8E06001C713B /* Defaults.m in Sources */, + B6ECFF271D2EEA2B00871A81 /* TextLabel.m in Sources */, B612F45012DD5DAD005D1B77 /* iGeometry.cpp in Sources */, B612F45112DD5DAD005D1B77 /* Lock.cpp in Sources */, B612F45212DD5DAD005D1B77 /* OutputChannel.cpp in Sources */, diff --git a/English.lproj/TermWindow.xib b/English.lproj/TermWindow.xib index 25743bb..7166af7 100644 --- a/English.lproj/TermWindow.xib +++ b/English.lproj/TermWindow.xib @@ -1,19 +1,18 @@ - - + - + @@ -21,19 +20,17 @@ - + - - + + - - - - - - + + + + @@ -44,26 +41,8 @@ - + - - - - - - - - - - - - - - - - - - diff --git a/TermWindowController.h b/TermWindowController.h index 04f1a1c..f96e3e1 100644 --- a/TermWindowController.h +++ b/TermWindowController.h @@ -10,7 +10,7 @@ @class EmulatorView; -@class CurveView; +@class ColorView; @protocol Emulator; @@ -19,14 +19,12 @@ NSDictionary *_parameters; EmulatorView *_emulatorView; - CurveView *_curveView; + ColorView *_colorView; NSObject *_emulator; - int _child; - int _fd; pid_t _pid; @@ -38,7 +36,7 @@ @property (nonatomic, retain) NSDictionary *parameters; @property (nonatomic, retain) IBOutlet EmulatorView *emulatorView; -@property (nonatomic, retain) IBOutlet CurveView *curveView; +@property (nonatomic, retain) IBOutlet ColorView *colorView; @property (nonatomic, retain) NSObject *emulator; diff --git a/TermWindowController.mm b/TermWindowController.mm index 200509a..a3a083b 100644 --- a/TermWindowController.mm +++ b/TermWindowController.mm @@ -9,6 +9,7 @@ #import "TermWindowController.h" #import "EmulatorView.h" #import "CurveView.h" +#import "EmulatorWindow.h" #import "VT52.h" #import "PTSE.h" @@ -31,7 +32,7 @@ @synthesize emulator = _emulator; @synthesize emulatorView = _emulatorView; -@synthesize curveView = _curveView; +@synthesize colorView = _colorView; @synthesize parameters = _parameters; @@ -44,7 +45,7 @@ { [_emulator release]; [_emulatorView release]; - [_curveView release]; + [_colorView release]; [_parameters release]; @@ -61,6 +62,8 @@ -(void)initPTY { + static std::string username; + struct termios term; struct winsize ws = [_emulator defaultSize]; @@ -83,6 +86,11 @@ [_emulator initTerm: &term]; + // getlogin() sometimes returns crap. + if (username.empty()) { + username = [NSUserName() UTF8String]; + } + //NSLog(@"%@ %s %s", NSUserName(), getlogin(), getpwent()->pw_name); _pid = forkpty(&_fd, NULL, &term, &ws); if (_pid < 0) @@ -131,9 +139,9 @@ // TODO -- option for localhost, telnet, ssh, etc. - execle("/usr/bin/login", "login", "-pf", getlogin(), NULL, &environ[0]); + execle("/usr/bin/login", "login", "-pf", username.c_str(), NULL, &environ[0]); - fprintf(stderr, "execle failed\n"); + fprintf(stderr, "execle failed: %s\n", strerror(errno)); fflush(stderr); // should not call exit. @@ -194,8 +202,13 @@ dispatch_source_set_event_handler(_wait_source, ^{ int status = 0; - waitpid(pid, &status, WNOHANG); - + int ok; + for(;;) { + ok = waitpid(pid, &status, WNOHANG); + if (ok >= 0) break; + if (errno == EINTR) continue; + break; + } _pid = 0; //dispatch_async(dispatch_get_main_queue(), ^(){ [_emulatorView childFinished: status]; @@ -229,7 +242,13 @@ for (;;) { actual = read(fd, buffer, (estimated)); if (actual < 0) { - if (errno == EINTR || errno == EAGAIN) return; + if (errno == EINTR) continue; + + if (errno == EAGAIN) { + if (buffer != sbuffer) free(buffer); + return; + } + NSLog(@"read: %s", strerror(errno)); dispatch_source_cancel(_read_source); dispatch_release(_read_source); @@ -242,7 +261,8 @@ if (buffer != sbuffer) free(buffer); - if (actual == 0 && _pid == 0) { + if (actual == 0) { + NSLog(@"closing fd"); dispatch_source_cancel(_read_source); dispatch_release(_read_source); _read_source = nullptr; @@ -308,69 +328,21 @@ [self didChangeValueForKey: @"emulator"]; [window setBackgroundColor: backgroundColor]; + [(EmulatorWindow *)window setTitleTextColor: foregroundColor]; [_emulatorView setEmulator: _emulator]; [_emulatorView setForegroundColor: foregroundColor]; [_emulatorView setBackgroundColor: backgroundColor]; //[_emulatorView setScanLines: scanLines]; - [_curveView setColor: backgroundColor]; + [_colorView setColor: backgroundColor]; o = [_parameters objectForKey: kContentFilters]; if (o) { - //CALayer *layer; - [_curveView setWantsLayer: YES]; - - /* - CGColorRef color; - - color = CGColorCreateGenericRGB(1.0, 0.0, 0.0, 1.0); - - layer = [_curveView layer]; - [layer setCornerRadius: 20.0]; - [layer setBorderWidth: 4.0]; - [layer setBorderColor: color]; - [layer setBackgroundColor: color]; - - [layer setBackgroundFilters: (NSArray *)o]; - - CGColorRelease(color); - */ - [_curveView setContentFilters: (NSArray *)o]; - - /* - CALayer *layer; - CGColorRef color; - - color = CGColorCreateGenericRGB(1.0, 0.0, 0.0, 1.0); - layer = [CALayer layer]; - [layer setFrame: CGRectMake(100, 100, 100, 100)]; - [layer setBackgroundColor: color]; - [layer setBackgroundFilters: nil]; - - CGColorRelease(color); - - [[_curveView layer] addSublayer: layer]; - - NSLog(@"%@", [layer backgroundFilters]); - NSLog(@"%@", [[_curveView layer] backgroundFilters]); - */ + [_colorView setWantsLayer: YES]; + [_colorView setContentFilters: (NSArray *)o]; } - - /* - NSShadow *shadow; - shadow = [[NSShadow alloc] init]; - [shadow setShadowColor:[NSColor blackColor]]; - [shadow setShadowOffset: NSZeroSize]; - [shadow setShadowBlurRadius: 10.0]; - - [_curveView setShadow: shadow]; - [shadow release]; - */ - - //[_curveView initScanLines]; - //[_curveView setColor: [NSColor blueColor]]; [self initPTY]; @@ -378,6 +350,8 @@ -(void)windowWillClose:(NSNotification *)notification { + + if (_wait_source) { dispatch_source_cancel(_wait_source); dispatch_release(_wait_source); @@ -388,7 +362,18 @@ dispatch_release(_read_source); } - if (_pid) kill(_pid, 9); + int status; + int ok; + if (_pid) { + kill(_pid, 9); + for(;;) { + ok = waitpid(_pid, &status, 0); + if (ok >= 0) break; + if (errno == EINTR) continue; + perror("waitpid: "); + break; + } + } [self autorelease]; } diff --git a/Views/EmulatorView.mm b/Views/EmulatorView.mm index d92e507..1dd937b 100644 --- a/Views/EmulatorView.mm +++ b/Views/EmulatorView.mm @@ -153,7 +153,7 @@ _charHeight = 16; _paddingLeft = 8; - _paddingTop = 24; + _paddingTop = 8; _paddingBottom = 8; @@ -252,6 +252,9 @@ return YES; } +-(BOOL)isOpaque { + return NO; +} -(void)viewDidMoveToWindow { @@ -497,7 +500,7 @@ // called from other thread. - NSLog(@"[process complete]"); + //NSLog(@"[process complete]"); dispatch_async(dispatch_get_main_queue(), ^(){ diff --git a/Views/EmulatorWindow.h b/Views/EmulatorWindow.h index e28299c..0aaba33 100644 --- a/Views/EmulatorWindow.h +++ b/Views/EmulatorWindow.h @@ -7,16 +7,13 @@ // #import -@class TitleBarView; +@class TextLabel; @interface EmulatorWindow : NSWindow { - TitleBarView *_titleBarView; } -@property (nonatomic, retain) IBOutlet TitleBarView *titleBarView; - --(void)adjustTitleBar; +@property (assign) IBOutlet TextLabel *textLabel; -(void)setTitleTextColor: (NSColor *)color; diff --git a/Views/EmulatorWindow.m b/Views/EmulatorWindow.m index 15cb667..f58b449 100644 --- a/Views/EmulatorWindow.m +++ b/Views/EmulatorWindow.m @@ -7,13 +7,26 @@ // #import "EmulatorWindow.h" -#import "TitleBarView.h" +#import "TextLabel.h" @implementation EmulatorWindow -@synthesize titleBarView = _titleBarView; +@synthesize textLabel = _textLabel; --(id)initWithContentRect:(NSRect)contentRect +-(void)commonInit { + + [self setTitleVisibility: NSWindowTitleHidden]; + [self setTitlebarAppearsTransparent: YES]; + + [self setOpaque: NO]; + [self setAlphaValue: 1.0]; + + // resize in 2.0 height increments to prevent jittering the scan lines. + [self setResizeIncrements: NSMakeSize(1.0, 2.0)]; + [self setMovableByWindowBackground: YES]; +} + +-(id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag @@ -24,21 +37,7 @@ backing: bufferingType defer: flag])) { - - [self setOpaque: NO]; - [self setAlphaValue: 1.0]; - - [self setTitleVisibility: NSWindowTitleVisible]; - - // resize in 2.0 height increments to prevent jittering the scan lines. - [self setResizeIncrements: NSMakeSize(1.0, 2.0)]; - [self setMovableByWindowBackground: YES]; - - - //[self setBackgroundColor: [NSColor clearColor]]; - //[self setHasShadow: NO]; - //[self setHasShadow: YES]; - + [self commonInit]; } return self; @@ -58,19 +57,7 @@ defer: flag screen: screen])) { - - [self setTitleVisibility: NSWindowTitleVisible]; - - - [self setOpaque: NO]; - [self setAlphaValue: 1.0]; - [self setResizeIncrements: NSMakeSize(1.0, 2.0)]; - [self setMovableByWindowBackground: YES]; - - //[self setBackgroundColor: [NSColor clearColor]]; - //[self setHasShadow: NO]; - //[self setHasShadow: YES]; - + [self commonInit]; } return self; @@ -79,83 +66,29 @@ -(void)dealloc { - [_titleBarView release]; [super dealloc]; } -(void)setTitle:(NSString *)aString { [super setTitle: aString]; - [_titleBarView setTitle: aString]; + [_textLabel setText: aString]; + } -(void)setTitleTextColor: (NSColor *)color { - [_titleBarView setTextColor: color]; + [_textLabel setColor: color]; } -(void)setBackgroundColor:(NSColor *)color { - //NSLog(@"%@", color); [super setBackgroundColor: color]; - [_titleBarView setBackgroundColor: color]; - [_titleBarView setTextColor: [NSColor greenColor]]; } -(void)awakeFromNib { - //[self adjustTitleBar]; - [self setAppearance: [NSAppearance appearanceNamed: NSAppearanceNameVibrantDark]]; - [self setTitleVisibility: NSWindowTitleVisible]; - [self setTitlebarAppearsTransparent: YES]; - //[NSApp addWindowsItem: self title: @"Window Title" filename: NO]; - //[self setHasShadow: YES]; -} -/* --(BOOL)canBecomeKeyWindow { - return YES; -} - --(BOOL)canBecomeMainWindow { - return YES; -} - --(BOOL)isExcludedFromWindowsMenu { - return NO; -} -*/ - --(void)adjustTitleBar -{ - - NSView *themeView; - NSArray *array; - - themeView = [[self contentView] superview]; - - NSLog(@"%@", themeView); - - NSLog(@"%u", (int)[_titleBarView retainCount]); - - [_titleBarView setBackgroundColor: [NSColor blackColor]]; - - [_titleBarView setFrame: [themeView bounds]]; - [_titleBarView setTitle: [self title]]; - - NSLog(@"%@", [self title]); - - array = [themeView subviews]; - - NSLog(@"%@", array); - - [themeView addSubview: _titleBarView - positioned: NSWindowBelow - relativeTo: [array objectAtIndex: 0]]; - - - array = [themeView subviews]; - - NSLog(@"%@", array); + [_textLabel setText: [self title]]; } diff --git a/Views/TextLabel.h b/Views/TextLabel.h new file mode 100644 index 0000000..c56993c --- /dev/null +++ b/Views/TextLabel.h @@ -0,0 +1,19 @@ +// +// TextLabel.h +// 2Term +// +// Created by Kelvin Sherlock on 7/7/2016. +// +// + +#import + +@interface TextLabel : NSView +{ + NSString *_text; + NSColor *_color; +} +@property (nonatomic, retain) NSString *text; +@property (nonatomic, retain) NSColor *color; + +@end diff --git a/Views/TextLabel.m b/Views/TextLabel.m new file mode 100644 index 0000000..ed898fa --- /dev/null +++ b/Views/TextLabel.m @@ -0,0 +1,89 @@ +// +// TextLabel.m +// 2Term +// +// Created by Kelvin Sherlock on 7/7/2016. +// +// + +#import "TextLabel.h" + +#import "CharacterGenerator.h" + +@implementation TextLabel + +@synthesize text = _text; +@synthesize color = _color; + +-(void) setText:(NSString *)text { + if (_text == text) return; + [_text release]; + _text = [text retain]; + [self setNeedsDisplay: YES]; +} + +-(void) setColor:(NSColor *)color { + if (_color == color) return; + [_color release]; + _color = [color retain]; + [self setNeedsDisplay: YES]; +} + +/* +-(BOOL)isFlipped { + return YES; +} +*/ +-(BOOL)isOpaque { + return NO; +} + + +- (void)drawRect:(NSRect)dirtyRect { + [super drawRect:dirtyRect]; + + [[NSColor clearColor] setFill]; + NSRectFill(dirtyRect); + + NSUInteger length = [_text length]; + if (!length) return; + if (!_color) return; + + CharacterGenerator *gen = [CharacterGenerator generator]; + + NSSize sz = [gen characterSize]; + + NSRect frame = [self frame]; + + CGFloat width = sz.width * length; + + NSPoint point = NSZeroPoint; + + if (width < NSWidth(frame)) { + point.x = (NSWidth(frame) - width) * 0.5; + } + + point.x = floor(point.x); + + [_color setFill]; + for (unsigned i = 0; i < length; ++i) { + unichar c = [_text characterAtIndex: i]; + + [gen drawCharacter: c atPoint: point]; + point.x += sz.width; + if (point.x > NSWidth(frame)) break; + } +} + +-(void)awakeFromNib { + + [super awakeFromNib]; + + //[self setWantsLayer: YES]; + + if (!_text) _text = [@"Testing!" retain]; + if (!_color) _color = [[NSColor greenColor] retain]; + +} + +@end diff --git a/Views/TitleBarView.m b/Views/TitleBarView.m index cd1f12a..b6b1cc7 100644 --- a/Views/TitleBarView.m +++ b/Views/TitleBarView.m @@ -147,7 +147,7 @@ return YES; } - +#if 0 -(void)drawRect:(NSRect)dirtyRect { NSRect bounds; @@ -179,6 +179,7 @@ YES); } +#endif -(void)fadeIn { diff --git a/cpp/iGeometry.h b/cpp/iGeometry.h index f50fa44..4b041a0 100644 --- a/cpp/iGeometry.h +++ b/cpp/iGeometry.h @@ -11,18 +11,23 @@ #define __IGEOMETRY_H__ - +#ifdef __cplusplus +#define equal_zero = 0 +#else +#define equal_zero +#endif typedef struct iSize { - int width; - int height; + int width equal_zero; + int height equal_zero; #ifdef __cplusplus - iSize() : width(0), height(0) {} - iSize(const iSize &aSize) : width(aSize.width), height(aSize.height) {} + iSize() = default; + iSize(const iSize &) = default; iSize(int w, int h) : width(w), height(h) {} + iSize &operator=(const iSize &) = default; bool operator==(const iSize &aSize) { return width == aSize.width && height == aSize.height; } @@ -36,14 +41,16 @@ typedef struct iSize { typedef struct iPoint { - int x; - int y; + int x equal_zero; + int y equal_zero; #ifdef __cplusplus - iPoint() : x(0), y(0) {} - iPoint(const iPoint &aPoint) : x(aPoint.x), y(aPoint.y) {} + iPoint() = default; + iPoint(const iPoint &aPoint) = default; iPoint(int xx, int yy) : x(xx), y(yy) {} + iPoint &operator=(const iPoint &) = default; + bool operator==(const iPoint &aPoint) { return x == aPoint.x && y == aPoint.y; } @@ -67,11 +74,13 @@ typedef struct iRect { iSize size; #ifdef __cplusplus - iRect() {} - iRect(const iRect &aRect) : origin(aRect.origin), size(aRect.size) {} + iRect() = default; + iRect(const iRect &aRect) = default; iRect(const iPoint &aPoint, const iSize &aSize) : origin(aPoint), size(aSize) {} iRect(int x, int y, int width, int height) : origin(iPoint(x, y)), size(iSize(width, height)) {} + iRect &operator=(const iRect &) = default; + bool contains(const iPoint aPoint) const; bool contains(const iRect aRect) const; @@ -101,4 +110,6 @@ typedef struct iRect { } iRect; +#undef equal_zero + #endif