9 Commits
r2 ... r4

Author SHA1 Message Date
Kelvin Sherlock
dc097da462 version bump 2018-02-09 22:58:49 -05:00
Kelvin Sherlock
41c311fb8a Squashed commit of the following:
commit b9723cf13690c3a6ecefeee81b1d95a23bde0422
Author: Kelvin Sherlock <ksherlock@gmail.com>
Date:   Fri Feb 9 22:41:59 2018 -0500

    remove most gui config stuff from new window.

commit c690c5ebd99d6268f605094f429114a39ab3c180
Author: Kelvin Sherlock <ksherlock@gmail.com>
Date:   Thu Feb 8 11:48:29 2018 -0500

    crosshatch cursor, push/pop cursor state when no longer key window.

commit ebaa0e535ee52a85a514efbaa872f891f7e817f1
Author: Kelvin Sherlock <ksherlock@gmail.com>
Date:   Thu Feb 8 11:47:20 2018 -0500

    child monitor - removeAll

commit e591630339f3cd22ca461f2006f4c360fa43d026
Author: Kelvin Sherlock <ksherlock@gmail.com>
Date:   Thu Feb 8 11:46:19 2018 -0500

    add config popup for the term window.
2018-02-09 22:47:20 -05:00
Kelvin Sherlock
4507998f1d version bump 2018-01-31 22:54:46 -05:00
Kelvin Sherlock
9fcf9f333f fix (?) some bugs with IIe/gsos high-bit characters. 2018-01-31 22:37:52 -05:00
Kelvin Sherlock
6a117c7b8a include the a2-terminfo database 2018-01-31 22:37:23 -05:00
Kelvin Sherlock
5bd035e33e add terminfo submodule 2018-01-31 22:02:21 -05:00
Kelvin Sherlock
66040a8366 add ChildMonitor sources to xcode project. 2018-01-31 21:19:31 -05:00
Kelvin Sherlock
b63b60826d set TERMINFO_DIRS to bundle/Resources/terminfo. 2018-01-31 21:19:05 -05:00
Kelvin Sherlock
e0bc21d663 move all the child/fd/kevent monitoring to a dedicated thread / class. 2018-01-31 21:17:31 -05:00
20 changed files with 990 additions and 799 deletions

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "a2-terminfo"]
path = a2-terminfo
url = https://github.com/ksherlock/a2-terminfo

21
ChildMonitor.h Normal file
View File

@@ -0,0 +1,21 @@
//
// ChildMonitor.h
// TwoTerm
//
// Created by Kelvin Sherlock on 1/31/2018.
//
#import <Foundation/Foundation.h>
@class TermWindowController;
@interface ChildMonitor : NSObject {
}
+(id)monitor;
-(void)removeController: (TermWindowController *)controller;
-(void)addController: (TermWindowController *)controller pid: (pid_t)pid fd: (int)fd;
-(void)removeAll;
@end

255
ChildMonitor.mm Normal file
View File

@@ -0,0 +1,255 @@
//
// ChildMonitor.m
// TwoTerm
//
// Created by Kelvin Sherlock on 1/31/2018.
//
#import "ChildMonitor.h"
#import "TermWindowController.h"
#include "Lock.h"
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <vector>
#include <algorithm>
namespace {
struct entry {
pid_t pid;
int fd;
TermWindowController *controller;
};
typedef std::vector<entry> entry_vector;
entry_vector::iterator find_controller(entry_vector &table, TermWindowController *controller) {
return std::find_if(table.begin(), table.end(), [=](const entry &e){
return e.controller == controller;
});
}
entry_vector::iterator find_pid(entry_vector &table, pid_t pid) {
return std::find_if(table.begin(), table.end(), [=](const entry &e){
return e.pid == pid;
});
}
entry_vector::iterator find_fd(entry_vector &table, int fd) {
return std::find_if(table.begin(), table.end(), [=](const entry &e){
return e.fd == fd;
});
}
/* return NO on EOF */
BOOL read(int fd, TermWindowController *controller) {
size_t total = 0;
for (;;) {
uint8_t buffer[2048];
ssize_t ok = ::read(fd, buffer, sizeof(buffer));
if (ok == 0) return total > 0;
if (ok < 1) {
if (errno == EINTR) continue;
if (errno == EAGAIN) return YES;
return YES;
}
[controller processData: buffer size: ok];
if (ok < sizeof(buffer)) return YES;
total += ok;
}
}
}
@interface ChildMonitor() {
std::vector<entry> _table;
int _kq;
Lock _lock;
}
@end
@implementation ChildMonitor
+(id)monitor {
static ChildMonitor *me = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
me = [ChildMonitor new];
[NSThread detachNewThreadSelector: @selector(run) toTarget: me withObject: nil];
});
return me;
}
-(id)init {
if ((self = [super init])) {
_kq = kqueue();
}
return self;
}
-(void)dealloc {
_lock.lock();
close(_kq);
for (const auto &e : _table) {
if (e.fd >= 0) close(e.fd);
if (e.pid > 0) kill(e.pid, SIGHUP);
if (e.controller) [e.controller release];
}
_lock.unlock();
[super dealloc];
}
-(void)removeAll {
Locker l(_lock);
for (auto &e : _table) {
if (e.controller) {
[e.controller release];
e.controller = nil;
}
if (e.pid > 0) {
kill(e.pid, SIGHUP);
e.pid = -1;
}
}
}
-(void)removeController: (TermWindowController *)controller {
if (!controller) return;
Locker l(_lock);
auto iter = find_controller(_table, controller);
if (iter != _table.end()) {
[iter->controller release];
iter->controller = nil;
if (iter->pid > 0) kill(iter->pid, SIGHUP);
}
}
-(void)addController: (TermWindowController *)controller pid: (pid_t)pid fd: (int)fd {
NSLog(@"Adding pid: %d fd: %d", pid, fd);
int flags;
// non-blocking io.
if (fcntl(fd, F_GETFL, &flags) < 0) flags = 0;
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
Locker l(_lock);
_table.emplace_back(entry{pid, fd, [controller retain]});
struct kevent events[2] = {};
EV_SET(&events[0], fd, EVFILT_READ, EV_ADD | EV_RECEIPT, 0, 0, NULL);
EV_SET(&events[1], pid, EVFILT_PROC, EV_ADD | EV_ONESHOT | EV_RECEIPT, NOTE_EXIT | NOTE_EXITSTATUS, 0, NULL);
kevent(_kq, events, 2, NULL, 0, NULL);
}
-(void) run {
struct kevent events[16] = {};
for(;;) {
@autoreleasepool {
int n = kevent(_kq, NULL, 0, events, 2, NULL);
if (n < 0) {
NSLog(@"kevent: %s", strerror(errno));
continue;
}
if (n == 0) {
continue;
}
Locker l(_lock);
// should process twice, first for reading, second for dead children.
std::for_each(events, events + n, [&](const struct kevent &e){
if (e.filter != EVFILT_READ) return;
int fd = (int)e.ident;
if (e.flags & EV_EOF) {
NSLog(@"EV_EOF %d", fd);
return;
}
if (e.flags & EV_ERROR) {
NSLog(@"EV_ERROR %d", fd);
return;
}
auto iter = find_fd(_table, fd);
if (iter == _table.end() || iter->controller == nil) {
NSLog(@"Closing fd %d (not found)", fd);
close(fd); // should automatically remove itself from kevent
iter->fd = -1;
} else {
BOOL ok = read(fd, iter->controller);
if (!ok) {
NSLog(@"Closing fd %d (eof)", fd);
close(fd); // should automatically remove itself from kevent
iter->fd = -1;
}
}
});
std::for_each(events, events + n, [&](const struct kevent &e){
if (e.filter != EVFILT_PROC) return;
pid_t pid = (pid_t)e.ident;
int status = 0;
for(;;) {
int ok = waitpid(pid, &status, WNOHANG);
if (ok >= 0) break;
if (errno == EINTR) continue;
NSLog(@"waitpid(%d): %s", pid, strerror(errno));
break;
}
auto iter = find_pid(_table, pid);
if (iter == _table.end()) {
} else {
if (iter->fd >= 0) {
// check for pending i/o ?
if (iter->controller)
read(iter->fd, iter->controller);
NSLog(@"Closing fd %d (child exited)", iter->fd);
close(iter->fd);
iter->fd = -1;
}
[iter->controller childFinished: status];
[iter->controller release];
iter->controller = nil;
*iter = std::move(_table.back());
_table.pop_back();
}
NSLog(@"Child %d finished", pid);
});
}
}
}
@end

View File

@@ -220,26 +220,26 @@
| 0x80 .. 0x9f ${
/* uppercase inverse/normal */
uint8_t flag = ~(_context.flags & Screen::FlagInverse);
uint8_t flag = _context.flags ^ Screen::FlagInverse;
screen->putc(fc - 0x40, _context.cursor, flag);
} $advance
| 0xa0 .. 0xbf ${
/* special inverse/normal */
uint8_t flag = ~(_context.flags & Screen::FlagInverse);
uint8_t flag = _context.flags ^ Screen::FlagInverse;
screen->putc(fc - 0x80, _context.cursor, flag);
} $advance
| 0xc0 .. 0xdf ${
/* uppercase normal / mouse text. */
uint8_t flag = ~(_context.flags & Screen::FlagInverse);
uint8_t flag = _context.flags ^ Screen::FlagInverse;
if (flag) flag |= Screen::FlagMouseText;
screen->putc(fc - 0x80, _context.cursor, flag);
} $advance
| 0xe0 .. 0xff ${
/* special inverse/normal */
uint8_t flag = ~(_context.flags & Screen::FlagInverse);
uint8_t flag = _context.flags ^ Screen::FlagInverse;
screen->putc(fc - 0x80, _context.cursor, flag);
} $advance

View File

@@ -420,26 +420,26 @@ static void advance(Screen *screen, gsos_context &ctx) {
| 0x80 .. 0x9f ${
/* uppercase inverse/normal */
uint8_t flags = ~(_context.flags & Screen::FlagInverse);
uint8_t flags = _context.flags ^ Screen::FlagInverse;
screen->putc(fc - 0x40, cursor, flags);
} $advance_if
| 0xa0 .. 0xbf ${
/* special inverse/normal */
uint8_t flags = ~(_context.flags & Screen::FlagInverse);
uint8_t flags = _context.flags ^ Screen::FlagInverse;
screen->putc(fc - 0x80, cursor, flags);
} $advance_if
| 0xc0 .. 0xdf ${
/* uppercase normal / mouse text. */
uint8_t flags = ~(_context.flags & Screen::FlagInverse);
uint8_t flags = _context.flags ^ Screen::FlagInverse;
if (flags) flags |= Screen::FlagMouseText;
screen->putc(fc - 0x80, cursor, flags);
} $advance_if
| 0xe0 .. 0xff ${
/* special inverse/normal */
uint8_t flags = ~(_context.flags & Screen::FlagInverse);
uint8_t flags = _context.flags ^ Screen::FlagInverse;
screen->putc(fc - 0x80, cursor, flags);
} $advance_if

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13529" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13529"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
@@ -342,268 +342,6 @@
</items>
</menu>
</menuItem>
<menuItem title="Format" id="375">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Format" id="376">
<items>
<menuItem title="Font" id="377">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Font" systemMenu="font" id="388">
<items>
<menuItem title="Show Fonts" keyEquivalent="t" id="389">
<connections>
<action selector="orderFrontFontPanel:" target="420" id="424"/>
</connections>
</menuItem>
<menuItem title="Bold" tag="2" keyEquivalent="b" id="390">
<connections>
<action selector="addFontTrait:" target="420" id="421"/>
</connections>
</menuItem>
<menuItem title="Italic" tag="1" keyEquivalent="i" id="391">
<connections>
<action selector="addFontTrait:" target="420" id="422"/>
</connections>
</menuItem>
<menuItem title="Underline" keyEquivalent="u" id="392">
<connections>
<action selector="underline:" target="-1" id="432"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="393"/>
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="394">
<connections>
<action selector="modifyFont:" target="420" id="425"/>
</connections>
</menuItem>
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="395">
<connections>
<action selector="modifyFont:" target="420" id="423"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="396"/>
<menuItem title="Kern" id="397">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Kern" id="415">
<items>
<menuItem title="Use Default" id="416">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="useStandardKerning:" target="-1" id="438"/>
</connections>
</menuItem>
<menuItem title="Use None" id="417">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="turnOffKerning:" target="-1" id="441"/>
</connections>
</menuItem>
<menuItem title="Tighten" id="418">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="tightenKerning:" target="-1" id="431"/>
</connections>
</menuItem>
<menuItem title="Loosen" id="419">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="loosenKerning:" target="-1" id="435"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Ligature" id="398">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Ligature" id="411">
<items>
<menuItem title="Use Default" id="412">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="useStandardLigatures:" target="-1" id="439"/>
</connections>
</menuItem>
<menuItem title="Use None" id="413">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="turnOffLigatures:" target="-1" id="440"/>
</connections>
</menuItem>
<menuItem title="Use All" id="414">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="useAllLigatures:" target="-1" id="434"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Baseline" id="399">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Baseline" id="405">
<items>
<menuItem title="Use Default" id="406">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="unscript:" target="-1" id="437"/>
</connections>
</menuItem>
<menuItem title="Superscript" id="407">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="superscript:" target="-1" id="430"/>
</connections>
</menuItem>
<menuItem title="Subscript" id="408">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="subscript:" target="-1" id="429"/>
</connections>
</menuItem>
<menuItem title="Raise" id="409">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="raiseBaseline:" target="-1" id="426"/>
</connections>
</menuItem>
<menuItem title="Lower" id="410">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="lowerBaseline:" target="-1" id="427"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="400"/>
<menuItem title="Show Colors" keyEquivalent="C" id="401">
<connections>
<action selector="orderFrontColorPanel:" target="-1" id="433"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="402"/>
<menuItem title="Copy Style" keyEquivalent="c" id="403">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="copyFont:" target="-1" id="428"/>
</connections>
</menuItem>
<menuItem title="Paste Style" keyEquivalent="v" id="404">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="pasteFont:" target="-1" id="436"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Text" id="496">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Text" id="497">
<items>
<menuItem title="Align Left" keyEquivalent="{" id="498">
<connections>
<action selector="alignLeft:" target="-1" id="524"/>
</connections>
</menuItem>
<menuItem title="Center" keyEquivalent="|" id="499">
<connections>
<action selector="alignCenter:" target="-1" id="518"/>
</connections>
</menuItem>
<menuItem title="Justify" id="500">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="alignJustified:" target="-1" id="523"/>
</connections>
</menuItem>
<menuItem title="Align Right" keyEquivalent="}" id="501">
<connections>
<action selector="alignRight:" target="-1" id="521"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="502"/>
<menuItem title="Writing Direction" id="503">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Writing Direction" id="508">
<items>
<menuItem title="Paragraph" enabled="NO" id="509">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem id="510">
<string key="title"> Default</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeBaseWritingDirectionNatural:" target="-1" id="525"/>
</connections>
</menuItem>
<menuItem id="511">
<string key="title"> Left to Right</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeBaseWritingDirectionLeftToRight:" target="-1" id="526"/>
</connections>
</menuItem>
<menuItem id="512">
<string key="title"> Right to Left</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeBaseWritingDirectionRightToLeft:" target="-1" id="527"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="513"/>
<menuItem title="Selection" enabled="NO" id="514">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem id="515">
<string key="title"> Default</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeTextWritingDirectionNatural:" target="-1" id="528"/>
</connections>
</menuItem>
<menuItem id="516">
<string key="title"> Left to Right</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeTextWritingDirectionLeftToRight:" target="-1" id="529"/>
</connections>
</menuItem>
<menuItem id="517">
<string key="title"> Right to Left</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeTextWritingDirectionRightToLeft:" target="-1" id="530"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="504"/>
<menuItem title="Show Ruler" id="505">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleRuler:" target="-1" id="520"/>
</connections>
</menuItem>
<menuItem title="Copy Ruler" keyEquivalent="c" id="506">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="copyRuler:" target="-1" id="522"/>
</connections>
</menuItem>
<menuItem title="Paste Ruler" keyEquivalent="v" id="507">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="pasteRuler:" target="-1" id="519"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="View" id="295">
<menu key="submenu" title="View" id="296">
<items>
@@ -618,6 +356,11 @@
<action selector="runToolbarCustomizationPalette:" target="-1" id="365"/>
</connections>
</menuItem>
<menuItem title="Configure" keyEquivalent="i" id="6in-Fp-JDh">
<connections>
<action selector="configure:" target="-1" id="5yK-Bh-svP"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>

View File

@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11762"/>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
<capability name="box content view" minToolsVersion="7.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@@ -9,16 +10,9 @@
<customObject id="-2" userLabel="File's Owner" customClass="NewTerminalWindowController">
<connections>
<outlet property="backgroundColorControl" destination="53" id="65"/>
<outlet property="bloomSlider" destination="MVc-mQ-qGn" id="TzC-h7-eSd"/>
<outlet property="blurSlider" destination="78" id="100"/>
<outlet property="colorSchemeButton" destination="68" id="92"/>
<outlet property="darkenSlider" destination="84" id="99"/>
<outlet property="effectsButton" destination="62" id="93"/>
<outlet property="exampleView" destination="123" id="129"/>
<outlet property="foregroundColorControl" destination="49" id="64"/>
<outlet property="lightenSlider" destination="82" id="101"/>
<outlet property="terminalTypeButton" destination="55" id="67"/>
<outlet property="vignetteSlider" destination="vAv-z0-AKd" id="tmI-Tz-29w"/>
<outlet property="window" destination="1" id="38"/>
</connections>
</customObject>
@@ -27,14 +21,14 @@
<window title="New Terminal" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="1">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" texturedBackground="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="232" width="400" height="613"/>
<rect key="contentRect" x="196" y="232" width="400" height="218"/>
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1178"/>
<view key="contentView" wantsLayer="YES" misplaced="YES" id="2">
<rect key="frame" x="0.0" y="0.0" width="400" height="613"/>
<rect key="frame" x="0.0" y="0.0" width="400" height="218"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField verticalHuggingPriority="750" id="9">
<rect key="frame" x="17" y="573" width="99" height="17"/>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" id="9">
<rect key="frame" x="17" y="178" width="99" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Terminal Type:" id="10">
<font key="font" metaFont="system"/>
@@ -42,9 +36,9 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" id="17">
<button verticalHuggingPriority="750" misplaced="YES" id="17">
<rect key="frame" x="262" y="18" width="118" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="roundTextured" title="Connect" bezelStyle="texturedRounded" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="18">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@@ -56,22 +50,8 @@ DQ
<action selector="connectButton:" target="-2" id="41"/>
</connections>
</button>
<button verticalHuggingPriority="750" id="19">
<rect key="frame" x="20" y="18" width="118" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<buttonCell key="cell" type="roundTextured" title="Cancel" bezelStyle="texturedRounded" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="20">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
Gw
</string>
</buttonCell>
<connections>
<action selector="cancelButton:" target="-2" id="40"/>
</connections>
</button>
<popUpButton verticalHuggingPriority="750" id="55">
<rect key="frame" x="121" y="568" width="259" height="25"/>
<rect key="frame" x="121" y="173" width="259" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="roundTextured" title="Item 1" bezelStyle="texturedRounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" selectedItem="58" id="56">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@@ -86,13 +66,13 @@ Gw
</popUpButtonCell>
</popUpButton>
<box autoresizesSubviews="NO" borderType="line" title="Colors" id="76">
<rect key="frame" x="17" y="441" width="366" height="124"/>
<rect key="frame" x="17" y="46" width="366" height="124"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<view key="contentView" id="xsD-uS-uc3">
<rect key="frame" x="1" y="1" width="364" height="108"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" id="50">
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" id="50">
<rect key="frame" x="15" y="48" width="83" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Foreground:" id="51">
@@ -101,7 +81,7 @@ Gw
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" id="90">
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" id="90">
<rect key="frame" x="15" y="79" width="83" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Scheme:" id="91">
@@ -110,7 +90,7 @@ Gw
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" id="52">
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" id="52">
<rect key="frame" x="15" y="17" width="83" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Background:" id="54">
@@ -124,7 +104,7 @@ Gw
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="color" red="0.0" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<connections>
<action selector="filterParameterChanged:" target="-2" id="128"/>
<action selector="colorChanged:" target="-2" id="3vl-pH-esq"/>
</connections>
</colorWell>
<colorWell id="53">
@@ -132,7 +112,7 @@ Gw
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="color" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<connections>
<action selector="filterParameterChanged:" target="-2" id="127"/>
<action selector="colorChanged:" target="-2" id="ljb-zv-K8U"/>
</connections>
</colorWell>
<popUpButton verticalHuggingPriority="750" id="68">
@@ -156,128 +136,27 @@ Gw
</subviews>
</view>
</box>
<box autoresizesSubviews="NO" misplaced="YES" borderType="line" title="Effects" id="77">
<rect key="frame" x="17" y="238" width="366" height="199"/>
<button verticalHuggingPriority="750" misplaced="YES" id="19">
<rect key="frame" x="20" y="18" width="118" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<view key="contentView" id="Pmg-yY-Yvg">
<rect key="frame" x="1" y="1" width="364" height="183"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<slider verticalHuggingPriority="750" misplaced="YES" id="78">
<rect key="frame" x="85" y="131" width="263" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<sliderCell key="cell" continuous="YES" state="on" alignment="left" maxValue="1" tickMarkPosition="above" sliderType="linear" id="79"/>
<connections>
<action selector="filterParameterChanged:" target="-2" id="124"/>
<binding destination="-2" name="enabled" keyPath="effectsEnabled" id="115"/>
</connections>
</slider>
<slider verticalHuggingPriority="750" misplaced="YES" id="82">
<rect key="frame" x="85" y="79" width="263" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<sliderCell key="cell" continuous="YES" state="on" alignment="left" maxValue="1" doubleValue="0.25" tickMarkPosition="above" sliderType="linear" id="83"/>
<connections>
<action selector="filterParameterChanged:" target="-2" id="125"/>
<binding destination="-2" name="enabled" keyPath="effectsEnabled" id="117"/>
</connections>
</slider>
<textField verticalHuggingPriority="750" misplaced="YES" id="80">
<rect key="frame" x="25" y="134" width="56" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Blur:" id="81">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" misplaced="YES" id="86">
<rect key="frame" x="17" y="84" width="64" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Backlight:" id="87">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" misplaced="YES" id="88">
<rect key="frame" x="15" y="59" width="66" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Scanlines:" id="89">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<slider verticalHuggingPriority="750" misplaced="YES" id="84">
<rect key="frame" x="85" y="56" width="263" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<sliderCell key="cell" continuous="YES" state="on" alignment="left" maxValue="1" doubleValue="0.5" tickMarkPosition="above" sliderType="linear" id="85"/>
<connections>
<action selector="filterParameterChanged:" target="-2" id="126"/>
<binding destination="-2" name="enabled" keyPath="effectsEnabled" id="119"/>
</connections>
</slider>
<slider verticalHuggingPriority="750" misplaced="YES" id="vAv-z0-AKd">
<rect key="frame" x="85" y="31" width="263" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<sliderCell key="cell" continuous="YES" state="on" alignment="left" maxValue="1" doubleValue="1" tickMarkPosition="above" sliderType="linear" id="6ek-4n-F91"/>
<connections>
<action selector="filterParameterChanged:" target="-2" id="xT7-DI-d9v"/>
<binding destination="-2" name="enabled" keyPath="effectsEnabled" id="Zom-p6-sns"/>
</connections>
</slider>
<button misplaced="YES" id="62">
<rect key="frame" x="83" y="157" width="118" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="Effects Enabled" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="63">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="-2" name="value" keyPath="effectsEnabled" id="107"/>
</connections>
</button>
<textField verticalHuggingPriority="750" misplaced="YES" id="p8Y-GX-qsU">
<rect key="frame" x="33" y="109" width="46" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Bloom:" id="JPr-iB-JMl">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<slider verticalHuggingPriority="750" misplaced="YES" id="MVc-mQ-qGn">
<rect key="frame" x="83" y="106" width="263" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<sliderCell key="cell" continuous="YES" state="on" alignment="left" maxValue="1" doubleValue="0.75" tickMarkPosition="above" sliderType="linear" id="rry-su-ojc"/>
<connections>
<action selector="filterParameterChanged:" target="-2" id="QKT-s7-pAK"/>
<binding destination="-2" name="enabled" keyPath="effectsEnabled" id="DfY-jU-vle"/>
</connections>
</slider>
<textField verticalHuggingPriority="750" misplaced="YES" id="7Qa-e5-7OW">
<rect key="frame" x="20" y="33" width="59" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Vignette:" id="x41-sA-EDR">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
</view>
</box>
<customView id="123" customClass="ExampleView">
<rect key="frame" x="20" y="50" width="360" height="145"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
</customView>
<buttonCell key="cell" type="roundTextured" title="Cancel" bezelStyle="texturedRounded" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="20">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
Gw
</string>
</buttonCell>
<connections>
<action selector="cancelButton:" target="-2" id="40"/>
</connections>
</button>
</subviews>
</view>
<contentBorderThickness minY="0.0" maxY="0.0"/>
<connections>
<outlet property="delegate" destination="-2" id="39"/>
</connections>
<point key="canvasLocation" x="116" y="220.5"/>
<point key="canvasLocation" x="116" y="23"/>
</window>
<userDefaultsController representsSharedInstance="YES" id="102"/>
</objects>

View File

@@ -0,0 +1,244 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
<capability name="box content view" minToolsVersion="7.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="TermWindowController">
<connections>
<outlet property="_bg" destination="y7X-B6-fK7" id="8g8-jL-Hgq"/>
<outlet property="_bloomSlider" destination="zfR-wC-m69" id="NUl-l7-LxH"/>
<outlet property="_blurSlider" destination="HTX-GL-dSw" id="nzS-Rs-opd"/>
<outlet property="_darkenSlider" destination="rzo-AM-xgS" id="cQU-IX-Ayk"/>
<outlet property="_effectsButton" destination="45n-1u-DD3" id="RO9-5L-rw0"/>
<outlet property="_fg" destination="h2m-UV-1jK" id="vUr-6N-hct"/>
<outlet property="_lightenSlider" destination="Yyg-Jb-Ehs" id="VIu-nj-6sy"/>
<outlet property="_vignetteSlider" destination="m3R-Cx-hoV" id="yQC-Hh-YhM"/>
<outlet property="popover" destination="Ezq-gE-d2Y" id="kjM-1e-QEy"/>
<outlet property="popoverViewController" destination="OVV-qD-BBZ" id="GrG-Nb-XmA"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<viewController id="OVV-qD-BBZ" userLabel="Popover View Controller">
<connections>
<outlet property="view" destination="I75-XO-Tcx" id="wDA-e4-3DT"/>
</connections>
</viewController>
<popover behavior="semitransient" id="Ezq-gE-d2Y">
<connections>
<outlet property="contentViewController" destination="OVV-qD-BBZ" id="0a5-yM-Gvw"/>
<outlet property="delegate" destination="-2" id="kCQ-Mx-dwQ"/>
</connections>
</popover>
<view misplaced="YES" id="I75-XO-Tcx">
<rect key="frame" x="0.0" y="0.0" width="480" height="386"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<box autoresizesSubviews="NO" misplaced="YES" borderType="line" title="Colors" id="9nf-mJ-BR9">
<rect key="frame" x="-3" y="214" width="486" height="152"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<view key="contentView" id="Yk4-q6-pft">
<rect key="frame" x="1" y="1" width="484" height="136"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" id="FUz-bX-GbP">
<rect key="frame" x="15" y="76" width="83" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Foreground:" id="xJP-lw-Tbc">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" id="dnI-BK-Rcv">
<rect key="frame" x="15" y="107" width="83" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Scheme:" id="KcE-bJ-jXO">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" id="bBS-WW-w8G">
<rect key="frame" x="15" y="45" width="83" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Background:" id="yQ3-OB-2JZ">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<colorWell misplaced="YES" tag="101" id="h2m-UV-1jK">
<rect key="frame" x="103" y="73" width="44" height="23"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="color" red="0.0" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<connections>
<action selector="filterParameterChanged:" target="-2" id="3Ru-PH-hSQ"/>
<binding destination="-2" name="value" keyPath="foregroundColor" id="rBL-Ts-HGk"/>
</connections>
</colorWell>
<colorWell tag="102" id="y7X-B6-fK7">
<rect key="frame" x="103" y="42" width="44" height="23"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="color" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<connections>
<action selector="filterParameterChanged:" target="-2" id="R4l-cG-wwp"/>
<binding destination="-2" name="value" keyPath="backgroundColor" id="bvR-yG-ANl"/>
</connections>
</colorWell>
<popUpButton verticalHuggingPriority="750" id="3sV-7a-zHB">
<rect key="frame" x="103" y="102" width="363" height="25"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="roundTextured" title="Item 1" bezelStyle="texturedRounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" selectedItem="Fvo-nW-HxK" id="4D2-1v-aHi">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" title="OtherViews" id="MbT-U8-boD">
<items>
<menuItem title="Item 1" state="on" id="Fvo-nW-HxK"/>
<menuItem title="Item 2" id="M9V-09-Hcy"/>
<menuItem title="Item 3" id="Fc7-mh-zWC"/>
</items>
</menu>
</popUpButtonCell>
</popUpButton>
<button verticalHuggingPriority="750" misplaced="YES" id="KyB-fP-aHS">
<rect key="frame" x="103" y="10" width="75" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="roundTextured" title="Swap" bezelStyle="texturedRounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="jAf-VI-BPe">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="swapColors:" target="-2" id="chW-So-Y92"/>
</connections>
</button>
</subviews>
</view>
</box>
<box autoresizesSubviews="NO" misplaced="YES" borderType="line" title="Effects" id="KgG-2I-L3k">
<rect key="frame" x="-3" y="11" width="486" height="199"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<view key="contentView" id="Ugn-Ms-tK7">
<rect key="frame" x="1" y="1" width="484" height="183"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<slider verticalHuggingPriority="750" id="HTX-GL-dSw">
<rect key="frame" x="85" y="131" width="383" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<sliderCell key="cell" continuous="YES" state="on" alignment="left" maxValue="1" tickMarkPosition="above" sliderType="linear" id="L90-Mv-v8n"/>
<connections>
<action selector="filterParameterChanged:" target="-2" id="f7g-CF-VXa"/>
<binding destination="-2" name="value" keyPath="blurValue" id="D5Z-q9-Rlv"/>
<binding destination="-2" name="enabled" keyPath="effectsEnabled" id="zaD-eS-SmB"/>
</connections>
</slider>
<slider verticalHuggingPriority="750" id="Yyg-Jb-Ehs">
<rect key="frame" x="85" y="79" width="383" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<sliderCell key="cell" continuous="YES" state="on" alignment="left" maxValue="1" doubleValue="0.25" tickMarkPosition="above" sliderType="linear" id="u6M-Gg-qBE"/>
<connections>
<action selector="filterParameterChanged:" target="-2" id="x62-Id-NWe"/>
<binding destination="-2" name="value" keyPath="backlightValue" id="VfT-3v-Gax"/>
<binding destination="-2" name="enabled" keyPath="effectsEnabled" id="PUq-u9-d6F"/>
</connections>
</slider>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" id="H0z-mE-bY7">
<rect key="frame" x="25" y="134" width="56" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Blur:" id="JNK-dk-099">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" id="Z01-Bk-h4V">
<rect key="frame" x="17" y="84" width="64" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Backlight:" id="5mr-bX-5bG">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" id="q1N-n8-Z3T">
<rect key="frame" x="15" y="59" width="66" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Scanlines:" id="7S4-8E-SbL">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<slider verticalHuggingPriority="750" id="rzo-AM-xgS">
<rect key="frame" x="85" y="56" width="383" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<sliderCell key="cell" continuous="YES" state="on" alignment="left" maxValue="1" doubleValue="0.5" tickMarkPosition="above" sliderType="linear" id="938-Rg-ZhB"/>
<connections>
<action selector="filterParameterChanged:" target="-2" id="I4v-8E-7m0"/>
<binding destination="-2" name="enabled" keyPath="effectsEnabled" id="lKZ-pD-cDA"/>
<binding destination="-2" name="value" keyPath="scanlineValue" id="jM9-zH-7OX"/>
</connections>
</slider>
<slider verticalHuggingPriority="750" id="m3R-Cx-hoV">
<rect key="frame" x="85" y="31" width="383" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<sliderCell key="cell" continuous="YES" state="on" alignment="left" maxValue="1" doubleValue="1" tickMarkPosition="above" sliderType="linear" id="XLJ-uB-JVF"/>
<connections>
<action selector="filterParameterChanged:" target="-2" id="UIJ-Xs-mea"/>
<binding destination="-2" name="enabled" keyPath="effectsEnabled" id="xHh-22-Gmn"/>
<binding destination="-2" name="value" keyPath="vignetteValue" id="MOU-47-YUb"/>
</connections>
</slider>
<button id="45n-1u-DD3">
<rect key="frame" x="83" y="157" width="118" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="Effects Enabled" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="4dP-ze-wtI">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="filterParameterChanged:" target="-2" id="92u-Vv-Leg"/>
<binding destination="-2" name="value" keyPath="effectsEnabled" id="hEB-Mh-eRD"/>
</connections>
</button>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" id="V15-3Z-rcp">
<rect key="frame" x="33" y="109" width="46" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Bloom:" id="hao-V0-JkY">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<slider verticalHuggingPriority="750" id="zfR-wC-m69">
<rect key="frame" x="83" y="106" width="383" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<sliderCell key="cell" continuous="YES" state="on" alignment="left" maxValue="1" doubleValue="0.75" tickMarkPosition="above" sliderType="linear" id="KU3-BX-dWp"/>
<connections>
<action selector="filterParameterChanged:" target="-2" id="IxY-Oe-aaz"/>
<binding destination="-2" name="value" keyPath="bloomValue" id="3cg-US-D8y"/>
<binding destination="-2" name="enabled" keyPath="effectsEnabled" id="pKA-B0-P4C"/>
</connections>
</slider>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" id="oc8-uX-jXl">
<rect key="frame" x="20" y="33" width="59" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Vignette:" id="kD4-LV-p7U">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
</view>
</box>
</subviews>
<point key="canvasLocation" x="-521" y="413"/>
</view>
<userDefaultsController representsSharedInstance="YES" id="mq9-aV-tAe"/>
</objects>
</document>

View File

@@ -1,13 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="TermWindowController">
<connections>
<outlet property="colorView" destination="2" id="3TK-Yg-hmS"/>
<outlet property="emulatorView" destination="5" id="14"/>
<outlet property="_colorView" destination="2" id="QiD-Qe-7pg"/>
<outlet property="_emulatorView" destination="5" id="JNn-UY-fjw"/>
<outlet property="window" destination="1" id="3"/>
</connections>
</customObject>
@@ -44,5 +46,6 @@
<outlet property="textLabel" destination="jhD-Y5-62e" id="Zzx-CJ-wV8"/>
</connections>
</window>
<userDefaultsController representsSharedInstance="YES" id="mq9-aV-tAe"/>
</objects>
</document>

View File

@@ -21,7 +21,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>2</string>
<string>4</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSMinimumSystemVersion</key>

View File

@@ -19,18 +19,6 @@
NSColorWell *_foregroundColorControl;
NSColorWell *_backgroundColorControl;
NSButton *_effectsButton;
NSSlider *_blurSlider;
NSSlider *_lightenSlider;
NSSlider *_darkenSlider;
ExampleView *_exampleView;
BOOL _effectsEnabled;
}
@property (nonatomic, assign) IBOutlet ExampleView *exampleView;
@@ -42,15 +30,6 @@
@property (nonatomic, assign) IBOutlet NSColorWell *foregroundColorControl;
@property (nonatomic, assign) IBOutlet NSColorWell *backgroundColorControl;
@property (nonatomic, assign) IBOutlet NSButton *effectsButton;
@property (nonatomic, assign) IBOutlet NSSlider *blurSlider;
@property (nonatomic, assign) IBOutlet NSSlider *lightenSlider;
@property (nonatomic, assign) IBOutlet NSSlider *darkenSlider;
@property (nonatomic, assign) IBOutlet NSSlider *bloomSlider;
@property (nonatomic, assign) IBOutlet NSSlider *vignetteSlider;
@property (nonatomic, assign) BOOL effectsEnabled;
-(IBAction)cancelButton: (id)sender;
@@ -59,10 +38,7 @@
-(IBAction)colorChanged: (id)sender;
-(IBAction)setColorScheme: (id)sender;
-(IBAction)filterParameterChanged: (id)sender;
-(NSMenu *)colorMenu;
-(NSColor *)recalcBackground;
@end

View File

@@ -18,16 +18,9 @@
@synthesize terminalTypeButton = _terminalTypeButton;
@synthesize colorSchemeButton = _colorSchemeButton;
@synthesize effectsButton = _effectsButton;
@synthesize foregroundColorControl = _foregroundColorControl;
@synthesize backgroundColorControl = _backgroundColorControl;
@synthesize blurSlider = _blurSlider;
@synthesize lightenSlider = _lightenSlider;
@synthesize darkenSlider = _darkenSlider;
@synthesize effectsEnabled = _effectsEnabled;
// colors
enum {
kCustom = 0,
@@ -59,12 +52,11 @@ enum {
[super windowDidLoad];
window = [self window];
//[[window contentView] setWantsLayer: YES];
//[window setAutorecalculatesContentBorderThickness: NO forEdge: NSMinYEdge];
//[window setAutorecalculatesContentBorderThickness: NO forEdge: NSMaxYEdge];
[self setEffectsEnabled: YES];
[_terminalTypeButton setMenu: [EmulatorManager emulatorMenu]];
@@ -143,16 +135,11 @@ enum {
[userInfo setObject: klass forKey: kClass];
[userInfo setObject: [_foregroundColorControl color] forKey: kForegroundColor];
[userInfo setObject: [self recalcBackground] forKey: kBackgroundColor];
if (_effectsEnabled)
{
[userInfo setObject: [_exampleView contentFilters] forKey: kContentFilters];
}
[userInfo setObject: [_backgroundColorControl color] forKey: kBackgroundColor];
[nc postNotificationName: kNotificationNewTerminal object: self userInfo: userInfo];
// post notificiation...
}
@@ -205,43 +192,9 @@ enum {
}
[self filterParameterChanged: nil];
}
-(IBAction)filterParameterChanged: (id)sender
{
[_exampleView setForegroundColor: [_foregroundColorControl color]];
[_exampleView setColor: [self recalcBackground]];
if (_effectsEnabled)
{
[_exampleView setBlur: [_blurSlider floatValue]];
//[_exampleView setLighten: [_lightenSlider floatValue]];
[_exampleView setDarken: [_darkenSlider floatValue]];
[_exampleView setBloom: [_bloomSlider floatValue]];
[_exampleView setVignette: [_vignetteSlider floatValue]];
}
else
{
[_exampleView setBlur: 0.0];
//[_exampleView setLighten: 0.0];
[_exampleView setDarken: 0.0];
[_exampleView setBloom: 0.0];
[_exampleView setVignette: 0.0];
}
[_exampleView updateEffects];
[_exampleView setNeedsDisplay: YES];
}
-(void)setEffectsEnabled:(BOOL)effectsEnabled
{
_effectsEnabled = effectsEnabled;
[self filterParameterChanged: nil];
}
#pragma mark -
#pragma mark NSWindowDelegate
@@ -254,17 +207,6 @@ enum {
[self autorelease];
}
-(NSColor *)recalcBackground {
NSColor *bg = [_backgroundColorControl color];
NSColor *fg = [_foregroundColorControl color];
CGFloat value = [_lightenSlider doubleValue];
if (_effectsEnabled) {
bg = [bg blendedColorWithFraction: value ofColor: fg];
}
return bg;
}
@end

View File

@@ -14,30 +14,65 @@
@protocol Emulator;
@interface TermWindowController : NSWindowController <NSWindowDelegate> {
NSDictionary *_parameters;
EmulatorView *_emulatorView;
ColorView *_colorView;
@interface TermWindowController : NSWindowController <NSWindowDelegate, NSPopoverDelegate> {
IBOutlet EmulatorView *_emulatorView;
IBOutlet ColorView *_colorView;
NSObject <Emulator> *_emulator;
NSThread * _thread;
int _fd;
std::atomic<pid_t> _pid;
/* popover configuration options */
IBOutlet NSColorWell *_fg;
IBOutlet NSColorWell *_bg;
IBOutlet NSButton *_effectsButton;
IBOutlet NSSlider *_blurSlider;
IBOutlet NSSlider *_lightenSlider;
IBOutlet NSSlider *_darkenSlider;
IBOutlet NSSlider *_bloomSlider;
IBOutlet NSSlider *_vignetteSlider;
}
@property (nonatomic, retain) NSDictionary *parameters;
@property (nonatomic, retain) IBOutlet NSViewController *popoverViewController;
@property (nonatomic, retain) IBOutlet NSPopover *popover;
@property (nonatomic, retain) IBOutlet EmulatorView *emulatorView;
@property (nonatomic, retain) IBOutlet ColorView *colorView;
@property (nonatomic, retain) NSObject<Emulator> *emulator;
@property (nonatomic, assign) BOOL effectsEnabled;
@property (nonatomic, assign) double blurValue;
@property (nonatomic, assign) double bloomValue;
@property (nonatomic, assign) double backlightValue;
@property (nonatomic, assign) double scanlineValue;
@property (nonatomic, assign) double vignetteValue;
@property (nonatomic, retain) NSColor *foregroundColor;
@property (nonatomic, retain) NSColor *backgroundColor;
-(void)initPTY;
-(void)childFinished: (int)status;
-(void)processData: (const void *)buffer size: (size_t)size;
-(void)setParameters: (NSDictionary *)parameters;
@end
@interface TermWindowController (Config)
- (IBAction)configure: (id)sender;
- (IBAction)foregroundColor:(id)sender;
- (IBAction)backgroundColor:(id)sender;
- (IBAction)swapColors:(id)sender;
- (IBAction)filterParameterChanged: (id)sender;
-(void) updateBackgroundColor;
-(void) updateForegroundColor;
-(NSArray *)effectsFilter;
@end

View File

@@ -6,6 +6,9 @@
// Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import <CoreImage/CoreImage.h>
#import "ScanLineFilter.h"
#import "TermWindowController.h"
#import "EmulatorView.h"
#import "CurveView.h"
@@ -15,7 +18,7 @@
#include <sys/event.h>
#include <sys/time.h>
#include <atomic>
#include <utility>
#import "Defaults.h"
@@ -31,13 +34,12 @@
#include <string>
#include <vector>
#include "ChildMonitor.h"
#include "ColorView.h"
@implementation TermWindowController
@synthesize emulator = _emulator;
@synthesize emulatorView = _emulatorView;
@synthesize colorView = _colorView;
@synthesize parameters = _parameters;
+(id)new
{
@@ -46,36 +48,94 @@
-(void)dealloc
{
[_emulator release];
[_emulatorView release];
[_colorView release];
[_parameters release];
[_thread release];
[[ChildMonitor monitor] removeController: self];
[_emulator release];
[_popover release];
[_popoverViewController release];
[_foregroundColor release];
[_backgroundColor release];
[super dealloc];
}
/*
-(void)awakeFromNib
{
[self initPTY];
-(id)initWithWindow:(NSWindow *)window {
if ((self = [super initWithWindow: window])) {
_foregroundColor = [[NSColor greenColor] retain];
_backgroundColor = [[NSColor blackColor] retain];
_bloomValue = 0.75;
_blurValue = 0.0;
_backlightValue = 0.25;
_scanlineValue = 0.5;
_vignetteValue = 0.5;
_effectsEnabled = YES;
}
return self;
}
*/
-(void)setParameters: (NSDictionary *)parameters {
NSColor *o;
Class klass;
o = [parameters objectForKey: kForegroundColor];
o = o ? (NSColor *)o : [NSColor greenColor];
[self setForegroundColor: o];
o = [parameters objectForKey: kBackgroundColor];
o = o ? (NSColor *)o : [NSColor blackColor];
[self setBackgroundColor: o];
klass = [parameters objectForKey: kClass];
if (!klass || ![klass conformsToProtocol: @protocol(Emulator)])
{
klass = Nil;
//klass = [VT52 class];
}
[self willChangeValueForKey: @"emulator"];
_emulator = [klass new];
[self didChangeValueForKey: @"emulator"];
#if 0
[self updateBackgroundColor];
[self updateForegroundColor];
#endif
}
-(void)initPTY
{
static std::string username;
static std::string terminfo;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// getlogin() sometimes returns crap.
username = [NSUserName() UTF8String];
char *cp = getenv("TERMINFO_DIRS");
if (cp && *cp) {
terminfo = cp;
terminfo.push_back(':');
}
NSString *s = [[NSBundle mainBundle] resourcePath];
s = [s stringByAppendingPathComponent: @"terminfo"];
terminfo += [s UTF8String];
});
pid_t pid;
int fd;
struct termios term;
struct winsize ws = [_emulator defaultSize];
memset(&term, 0, sizeof(term));
//term.c_oflag = OPOST | ONLCR;
//term.c_lflag = ECHO;
//term.c_iflag = ICRNL; // | ICANON | ECHOE | ISIG;
term.c_oflag = TTYDEF_OFLAG;
term.c_lflag = TTYDEF_LFLAG;
term.c_iflag = TTYDEF_IFLAG;
@@ -89,21 +149,16 @@
[_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);
pid = forkpty(&fd, NULL, &term, &ws);
if (_pid < 0)
if (pid < 0)
{
fprintf(stderr, "forkpty failed\n");
fflush(stderr);
return;
}
if (_pid == 0)
if (pid == 0)
{
std::vector<const char *> environ;
@@ -118,8 +173,12 @@
s.append("TERM=");
s.append([_emulator termName]);
s.append(1, (char)0);
s.append("TERMINFO_DIRS=");
s.append(terminfo.c_str());
s.append(1, (char)0);
s.append(1, (char)0);
for (std::string::size_type index = 0;;)
@@ -175,201 +234,229 @@
[window setMinSize: [window frame].size];
[_emulatorView setFd: _fd];
[self monitor];
[_emulatorView setFd: fd];
[[ChildMonitor monitor] addController: self pid: pid fd: fd];
}
-(BOOL)read: (int)fd {
BOOL rv = NO;
for(;;) {
uint8_t buffer[1024];
ssize_t size = read(fd, buffer, sizeof(buffer));
if (size < 0 && errno == EINTR) continue;
if (size <= 0) break;
[_emulatorView processData: buffer size: size];
rv = YES;
}
return rv;
-(void)childFinished: (int)status {
[_emulatorView childFinished: status];
}
-(int)wait: (pid_t)pid {
std::atomic_exchange(&_pid, -1);
int status = 0;
for(;;) {
int ok = waitpid(pid, &status, WNOHANG);
if (ok >= 0) break;
if (errno == EINTR) continue;
NSLog(@"waitpid(%d): %s", pid, strerror(errno));
break;
}
return status;
-(void)processData: (const void *)buffer size: (size_t)size {
[_emulatorView processData: (uint8_t *)buffer size: size];
}
-(void)monitor {
int fd = _fd;
pid_t pid = _pid;
int q = kqueue();
struct kevent events[2] = {};
EV_SET(&events[0], pid, EVFILT_PROC, EV_ADD | EV_RECEIPT, NOTE_EXIT | NOTE_EXITSTATUS, 0, NULL);
EV_SET(&events[1], fd, EVFILT_READ, EV_ADD | EV_RECEIPT, 0, 0, NULL);
int flags;
// non-blocking io.
if (fcntl(_fd, F_GETFL, &flags) < 0) flags = 0;
fcntl(_fd, F_SETFL, flags | O_NONBLOCK);
kevent(q, events, 2, NULL, 0, NULL);
[_emulatorView childBegan];
_thread = [[NSThread alloc] initWithBlock: ^(){
struct kevent events[2] = {};
bool stop = false;
int status = 0;
while (!stop) {
int n = kevent(q, NULL, 0, events, 2, NULL);
if (n <= 0) {
NSLog(@"kevent");
break;
}
for (unsigned i = 0; i < n; ++i) {
const auto &e = events[i];
unsigned flags = e.flags;
if (e.filter == EVFILT_READ) {
int fd = (int)e.ident;
if (flags & EV_EOF) {
NSLog(@"EV_EOF");
}
if (flags & EV_ERROR) {
NSLog(@"EV_ERROR");
}
[self read: fd];
continue;
}
if (e.filter == EVFILT_PROC) {
pid_t pid = (pid_t)e.ident;
NSLog(@"Child finished");
status = [self wait: pid];
stop = true;
}
}
}
if (![_thread isCancelled]) {
// read any lingering io...
[self read: fd];
[_emulatorView childFinished: status];
}
close(q);
close(fd);
_fd = -1;
//NSLog(@"Closing fd");
}];
[_thread start];
}
#pragma mark -
#pragma mark NSWindowDelegate
- (void)windowDidLoad
{
NSColor *foregroundColor;
NSColor *backgroundColor;
Class klass;
id o;
NSWindow *window;
[super windowDidLoad];
window = [self window];
//[(CurveView *)[window contentView] setColor: [NSColor clearColor]];
//[window setContentView: _curveView];
// resize in 2.0 height increments to prevent jittering the scan lines.
//[window setResizeIncrements: NSMakeSize(1.0, 2.0)];
klass = [_parameters objectForKey: kClass];
if (!klass || ![klass conformsToProtocol: @protocol(Emulator)])
{
klass = Nil;
//klass = [VT52 class];
}
o = [_parameters objectForKey: kForegroundColor];
foregroundColor = o ? (NSColor *)o : [NSColor greenColor];
o = [_parameters objectForKey: kBackgroundColor];
backgroundColor = o ? (NSColor *)o : [NSColor blackColor];
[self willChangeValueForKey: @"emulator"];
_emulator = [klass new];
[self didChangeValueForKey: @"emulator"];
[window setBackgroundColor: backgroundColor];
[(EmulatorWindow *)window setTitleTextColor: foregroundColor];
window = [self window];
[_emulatorView setEmulator: _emulator];
[_emulatorView setForegroundColor: foregroundColor];
[_emulatorView setBackgroundColor: backgroundColor];
//[_emulatorView setScanLines: scanLines];
[self updateBackgroundColor];
[self updateForegroundColor];
[_colorView setColor: backgroundColor];
o = [_parameters objectForKey: kContentFilters];
if (o)
{
[_colorView setWantsLayer: YES];
[_colorView setContentFilters: (NSArray *)o];
}
[_colorView setWantsLayer: YES];
[_colorView setContentFilters: [self effectsFilter]];
[self initPTY];
}
-(void)windowWillClose:(NSNotification *)notification
{
pid_t pid = std::atomic_exchange(&_pid, -1);
[_thread cancel];
if (pid > 0) {
kill(pid, 9);
}
[[ChildMonitor monitor] removeController: self];
[self autorelease];
}
-(void)windowDidBecomeKey:(NSNotification *)notification {
[_emulatorView popCursor];
}
-(void)windowDidResignKey:(NSNotification *)notification {
[_emulatorView pushCursor: Screen::CursorTypeBlock];
}
-(void)popoverWillClose:(NSNotification *)notification {
[_fg deactivate];
[_bg deactivate];
[[NSColorPanel sharedColorPanel] orderOut: self];
}
@end
@implementation TermWindowController (Config)
-(NSColor *)recalcBackgroundColor {
if (_effectsEnabled) {
return [_backgroundColor blendedColorWithFraction: _backlightValue ofColor: _foregroundColor];
}
return _backgroundColor;
}
-(IBAction)filterParameterChanged:(id)sender {
if (sender == _effectsButton) sender = nil;
if (sender == nil || sender == _fg) {
[self updateForegroundColor];
}
if (sender == nil || sender == _fg || sender == _bg || sender == _lightenSlider) {
[self updateBackgroundColor];
}
if (sender == nil || sender == _vignetteSlider || sender == _darkenSlider || sender == _bloomSlider) {
[_colorView setContentFilters: [self effectsFilter]];
}
#if 0
CIFilter *filter = [_contentFilters objectAtIndex: 0];
[filter setValue: @(_vignetteValue) forKey: @"inputIntensity"];
}
if (sender == _darkenSlider) {
CIFilter *filter = [_contentFilters objectAtIndex: 1];
[filter setValue: @(_scanlineValue) forKey: @"inputDarken"];
}
if (sender == _bloomSlider) {
CIFilter *filter = [_contentFilters objectAtIndex: 2];
[filter setValue: @(_bloomValue) forKey: @"inputIntensity"];
}
#endif
}
-(NSArray *)effectsFilter {
if (!_effectsEnabled) return @[];
CIFilter *filter;
NSMutableArray *filters = [NSMutableArray arrayWithCapacity: 5];
// 1. vignette effect
filter = [CIFilter filterWithName: @"CIVignette"];
[filter setDefaults];
[filter setValue: @(_vignetteValue) forKey: @"inputIntensity"];
[filter setValue: @(2.0) forKey: @"inputRadius"];
[filters addObject: filter];
// 2. add the scanlines
filter = [[ScanLineFilter new] autorelease];
[filter setValue: @(_scanlineValue) forKey: @"inputDarken"];
[filter setValue: @(0.0) forKey: @"inputLighten"];
[filters addObject: filter];
// 3. bloom it...
filter = [CIFilter filterWithName: @"CIBloom"];
[filter setDefaults];
[filter setValue: @2.0 forKey: @"inputRadius"];
[filter setValue: @(_bloomValue) forKey: @"inputIntensity"];
[filters addObject: filter];
#if 0
//4. blur it a bit...
filter = [CIFilter filterWithName: @"CIGaussianBlur"];
[filter setDefaults];
[filter setValue: @(_blurValue) forKey: @"inputRadius"];
[filters addObject: filter];
#endif
return filters;
}
#pragma mark - IBActions
-(IBAction)configure: (id)sender {
if (!_popover) {
NSNib *nib = [[NSNib alloc] initWithNibNamed: @"TermConfig" bundle: nil];
// n.b. - instantiateWithOwner (10.8+) does not +1 refcount top level objects.
[nib instantiateWithOwner: self topLevelObjects: nil];
[nib release];
}
if ([_popover isShown]) {
[_popover close];
} else {
[_popover showRelativeToRect: NSZeroRect ofView: _emulatorView preferredEdge: NSRectEdgeMaxX];
}
}
- (IBAction)foregroundColor:(id)sender {
[self updateForegroundColor];
}
- (IBAction)backgroundColor:(id)sender {
[self updateBackgroundColor];
}
- (IBAction)swapColors:(id)sender {
[self willChangeValueForKey: @"foregroundColor"];
[self willChangeValueForKey: @"backgroundColor"];
std::swap(_foregroundColor, _backgroundColor);
[self didChangeValueForKey: @"foregroundColor"];
[self didChangeValueForKey: @"backgroundColor"];
[self updateBackgroundColor];
[self updateForegroundColor];
if ([_fg isActive]) {
[_bg activate: YES];
} else if ([_bg isActive]) {
[_fg activate: YES];
}
}
-(void)updateForegroundColor {
NSColor *color = _foregroundColor;
NSWindow *window = [self window];
[(EmulatorWindow *)window setTitleTextColor: color];
[_emulatorView setForegroundColor: color];
}
-(void)updateBackgroundColor {
NSColor *color = [self recalcBackgroundColor];
NSWindow *window = [self window];
[window setBackgroundColor: color];
[_colorView setColor: color];
[_emulatorView setBackgroundColor: color];
}
@end

View File

@@ -33,7 +33,6 @@
B61EF7D81482FB6D008C1891 /* titlebar-left.png in Resources */ = {isa = PBXBuildFile; fileRef = B61EF7D51482FB6D008C1891 /* titlebar-left.png */; };
B61EF7D91482FB6D008C1891 /* titlebar-right.png in Resources */ = {isa = PBXBuildFile; fileRef = B61EF7D61482FB6D008C1891 /* titlebar-right.png */; };
B638188214A179D60027D007 /* ColorView.m in Sources */ = {isa = PBXBuildFile; fileRef = B638188114A179D60027D007 /* ColorView.m */; };
B6407804201CE8BD00D3F2D1 /* GNOConsole.mm.ragel in Resources */ = {isa = PBXBuildFile; fileRef = B612F45B12DD5DF1005D1B77 /* GNOConsole.mm.ragel */; };
B6407805201CE93500D3F2D1 /* GNOConsole.mm.ragel in Sources */ = {isa = PBXBuildFile; fileRef = B612F45B12DD5DF1005D1B77 /* GNOConsole.mm.ragel */; };
B66412391480A070003BC8D3 /* EmulatorWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = B66412381480A070003BC8D3 /* EmulatorWindow.m */; };
B675F4A81E540394004B0D9C /* Screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B612F44D12DD5DAD005D1B77 /* Screen.cpp */; };
@@ -45,6 +44,8 @@
B67B3CE612B6FA040033AE07 /* a2-charset-80.png in Resources */ = {isa = PBXBuildFile; fileRef = B67B3CE412B6FA040033AE07 /* a2-charset-80.png */; };
B6801BD912EB549300B22E9E /* vt100-charset.png in Resources */ = {isa = PBXBuildFile; fileRef = B6801BD812EB549300B22E9E /* vt100-charset.png */; };
B68E632A12FF909D00EAFF5F /* ExampleView.m in Sources */ = {isa = PBXBuildFile; fileRef = B68E632912FF909C00EAFF5F /* ExampleView.m */; };
B69D0FBA202799B10073CCB7 /* TermConfig.xib in Resources */ = {isa = PBXBuildFile; fileRef = B69D0FB8202799B10073CCB7 /* TermConfig.xib */; };
B69E32A920221C9E0086D7B1 /* ChildMonitor.mm in Sources */ = {isa = PBXBuildFile; fileRef = B69E32A820221C9E0086D7B1 /* ChildMonitor.mm */; };
B6ACA2AD1E614E38000E774B /* VT52.mm in Sources */ = {isa = PBXBuildFile; fileRef = B612F46312DD5DF1005D1B77 /* VT52.mm */; };
B6ACA2AF1E635CEC000E774B /* vt52-charset.png in Resources */ = {isa = PBXBuildFile; fileRef = B6ACA2AE1E635CEC000E774B /* vt52-charset.png */; };
B6C704EF15CCC64100CC0401 /* titlebar-center@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B6C704EC15CCC64100CC0401 /* titlebar-center@2x.png */; };
@@ -103,6 +104,10 @@
29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
8D1107320486CEB800E47090 /* TwoTerm.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TwoTerm.app; sourceTree = BUILT_PRODUCTS_DIR; };
B60B98712022BAF100E688E3 /* appleIIgs.ti */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = appleIIgs.ti; sourceTree = "<group>"; };
B60B98732022BAF100E688E3 /* gno-console.ti */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "gno-console.ti"; sourceTree = "<group>"; };
B60B98742022BAF100E688E3 /* gsos-console.ti */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "gsos-console.ti"; sourceTree = "<group>"; };
B60B98762022BAF100E688E3 /* proterm-special.ti */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "proterm-special.ti"; sourceTree = "<group>"; };
B60EBD1111E8DEEF00C1974F /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = /System/Library/Frameworks/QuartzCore.framework; sourceTree = "<absolute>"; };
B60EBDE111E90FC300C1974F /* ScanLineFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScanLineFilter.h; sourceTree = "<group>"; };
B60EBDE211E90FC300C1974F /* ScanLineFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScanLineFilter.m; sourceTree = "<group>"; };
@@ -160,6 +165,9 @@
B6801BD812EB549300B22E9E /* vt100-charset.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "vt100-charset.png"; sourceTree = "<group>"; };
B68E632812FF909C00EAFF5F /* ExampleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExampleView.h; sourceTree = "<group>"; };
B68E632912FF909C00EAFF5F /* ExampleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExampleView.m; sourceTree = "<group>"; };
B69D0FB9202799B10073CCB7 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/TermConfig.xib; sourceTree = "<group>"; };
B69E32A820221C9E0086D7B1 /* ChildMonitor.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ChildMonitor.mm; sourceTree = "<group>"; };
B69E32AA20221CCA0086D7B1 /* ChildMonitor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ChildMonitor.h; sourceTree = "<group>"; };
B6ACA2AB1E5C8BEC000E774B /* GNOConsole.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GNOConsole.mm; sourceTree = "<group>"; };
B6ACA2AE1E635CEC000E774B /* vt52-charset.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "vt52-charset.png"; sourceTree = "<group>"; };
B6C173901D31D2B80024E360 /* GSOSConsole.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GSOSConsole.h; sourceTree = "<group>"; };
@@ -201,6 +209,8 @@
B6EBE2B411E0EA9100EA0458 /* CharacterGenerator.mm */,
B60EBDE111E90FC300C1974F /* ScanLineFilter.h */,
B60EBDE211E90FC300C1974F /* ScanLineFilter.m */,
B69E32A820221C9E0086D7B1 /* ChildMonitor.mm */,
B69E32AA20221CCA0086D7B1 /* ChildMonitor.h */,
);
name = Classes;
sourceTree = "<group>";
@@ -261,6 +271,7 @@
29B97317FDCFA39411CA2CEA /* Resources */ = {
isa = PBXGroup;
children = (
B60B98702022BAF100E688E3 /* a2-terminfo */,
B60EBDE711E9143F00C1974F /* ScanLineFilter.cikernel */,
B66979CE11E6BCAE002ED475 /* images */,
8D1107310486CEB800E47090 /* Info.plist */,
@@ -268,6 +279,7 @@
1DDD58140DA1D0A300B32029 /* MainMenu.xib */,
B676065011DEBAE900D6B66C /* TermWindow.xib */,
B61EF7C714815AF8008C1891 /* NewTerminal.xib */,
B69D0FB8202799B10073CCB7 /* TermConfig.xib */,
B61EF7CD148163E7008C1891 /* TitleBarView.xib */,
);
name = Resources;
@@ -282,6 +294,17 @@
name = Frameworks;
sourceTree = "<group>";
};
B60B98702022BAF100E688E3 /* a2-terminfo */ = {
isa = PBXGroup;
children = (
B60B98712022BAF100E688E3 /* appleIIgs.ti */,
B60B98732022BAF100E688E3 /* gno-console.ti */,
B60B98742022BAF100E688E3 /* gsos-console.ti */,
B60B98762022BAF100E688E3 /* proterm-special.ti */,
);
path = "a2-terminfo";
sourceTree = "<group>";
};
B612F44612DD5DAD005D1B77 /* cpp */ = {
isa = PBXGroup;
children = (
@@ -376,6 +399,7 @@
8D11072C0486CEB800E47090 /* Sources */,
8D11072E0486CEB800E47090 /* Frameworks */,
B61D0D57125B728D001C713B /* CopyFiles */,
B60B98802022BF5900E688E3 /* ShellScript */,
);
buildRules = (
B6C173931D32A8840024E360 /* PBXBuildRule */,
@@ -421,11 +445,11 @@
files = (
B60EBE2B11E918D500C1974F /* ScanLineFilter.cikernel in Resources */,
8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */,
B69D0FBA202799B10073CCB7 /* TermConfig.xib in Resources */,
1DDD58160DA1D0A300B32029 /* MainMenu.xib in Resources */,
B676065111DEBAE900D6B66C /* TermWindow.xib in Resources */,
B67B3CE512B6FA040033AE07 /* a2-charset-40.png in Resources */,
B67B3CE612B6FA040033AE07 /* a2-charset-80.png in Resources */,
B6407804201CE8BD00D3F2D1 /* GNOConsole.mm.ragel in Resources */,
B6801BD912EB549300B22E9E /* vt100-charset.png in Resources */,
B61EF7C51481561E008C1891 /* titlebar-corner.png in Resources */,
B61EF7C61481561E008C1891 /* titlebar-middle.png in Resources */,
@@ -443,6 +467,22 @@
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
B60B98802022BF5900E688E3 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "for x in \"$PROJECT_DIR/a2-terminfo/\"*.ti ; do\ntic -N -s -o \"$BUILT_PRODUCTS_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/terminfo\" \"$x\"\ndone";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
8D11072C0486CEB800E47090 /* Sources */ = {
isa = PBXSourcesBuildPhase;
@@ -451,6 +491,7 @@
B675F4A91E561D20004B0D9C /* Apple80.mm.ragel in Sources */,
B675F4AC1E56A7F2004B0D9C /* GSOSConsole.mm.ragel in Sources */,
B6D1CD071E577E7D00C4A6BC /* PTSE.mm.ragel in Sources */,
B69E32A920221C9E0086D7B1 /* ChildMonitor.mm in Sources */,
B6407805201CE93500D3F2D1 /* GNOConsole.mm.ragel in Sources */,
8D11072D0486CEB800E47090 /* main.m in Sources */,
256AC3DA0F4B6AC300CF3369 /* TwoTermAppDelegate.mm in Sources */,
@@ -519,6 +560,14 @@
name = TermWindow.xib;
sourceTree = "<group>";
};
B69D0FB8202799B10073CCB7 /* TermConfig.xib */ = {
isa = PBXVariantGroup;
children = (
B69D0FB9202799B10073CCB7 /* English */,
);
name = TermConfig.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */

View File

@@ -13,7 +13,7 @@
#import "Defaults.h"
//#import "VT52.h"
#import "GNOConsole.h"
#import "ChildMonitor.h"
#import "ScanLineFilter.h"
@implementation TwoTermAppDelegate
@@ -27,9 +27,7 @@
TermWindowController *controller;
NSMutableArray *filters;
NSDictionary *parameters;
CIFilter *filter;
#if 0
struct sigaction sa = {};
@@ -42,7 +40,7 @@
[nc addObserver: self selector: @selector(newTerminal:) name: kNotificationNewTerminal object: nil];
#if 0
filters = [NSMutableArray arrayWithCapacity: 5];
@@ -76,12 +74,12 @@
[filter setValue: @2.0 forKey: @"inputRadius"];
[filter setValue: @(0.75) forKey: @"inputIntensity"];
#endif
parameters = @{
kClass: [GNOConsole class],
kContentFilters: filters,
//kContentFilters: filters,
kForegroundColor: [NSColor colorWithRed: 0.0 green: 1.0 blue: 0.6 alpha: 1.0],
kBackgroundColor: [NSColor colorWithRed: 0.0 green: .25 blue: .15 alpha: 1.0]
};
@@ -92,6 +90,10 @@
// this leak is ok.
}
-(void)applicationWillTerminate:(NSNotification *)notification {
[[ChildMonitor monitor] removeAll];
}
-(void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver: self];

View File

@@ -73,13 +73,14 @@ private:
unsigned _cursorType;
NSImage *_cursors[4];
NSImage *_cursors[5];
#ifdef __cplusplus
ring_buffer<1024> _debug_buffer;
ViewScreen _screen;
#endif
std::vector<unsigned> _cursorStack;
}
@property (nonatomic, assign) BOOL scanLines;
@@ -121,5 +122,7 @@ private:
-(void)cursorTimer: (NSTimer *)timer;
-(void)startCursorTimer;
-(void)pushCursor: (unsigned)type;
-(void)popCursor;
@end

View File

@@ -58,6 +58,7 @@
[_cursorTimer release];
_cursorTimer = nil;
_cursorOn = YES;
iRect r(_screen.cursor(), iSize(1,1));
[self invalidateIRect: r];
}
@@ -95,30 +96,24 @@
{
return _cursorType;
}
#if 0
dispatch_async(dispatch_get_main_queue(), ^(){
if (_cursorType == cursorType) return;
-(void)pushCursor:(unsigned)type {
if (_fd < 0) return;
unsigned char c;
switch (cursorType) {
default:
case Screen::CursorTypeUnderscore: c = '_'; break;
case Screen::CursorTypePipe: c = '|'; break;
case Screen::CursorTypeBlock: c = 0x80; break;
}
[_cursorImg release];
_cursorType = cursorType;
_cursorImg = [[_charGen imageForCharacter: c] retain];
iRect r(_screen.cursor(), iSize(1,1));
[self invalidateIRect: r];
});
#endif
_cursorStack.push_back(_cursorType);
[self setCursorType: type];
[self stopCursorTimer];
}
-(void)popCursor {
if (_fd < 0) return;
if (!_cursorStack.empty()) {
[self setCursorType: _cursorStack.back()];
_cursorStack.pop_back();
if (_cursorStack.empty()) [self startCursorTimer];
}
}
@end
@@ -160,7 +155,7 @@ dispatch_async(dispatch_get_main_queue(), ^(){
_paddingLeft = 8;
_paddingTop = 8;
_paddingBottom = 8;
_fd = 1;
//_foregroundColor = [[NSColor greenColor] retain];
//_backgroundColor = [[NSColor blackColor] retain];
@@ -181,6 +176,7 @@ dispatch_async(dispatch_get_main_queue(), ^(){
_cursors[Screen::CursorTypeUnderscore] = [[_charGen imageForCharacter: '_'] retain];
_cursors[Screen::CursorTypePipe] = [[_charGen imageForCharacter: '|'] retain];
_cursors[Screen::CursorTypeBlock] = [[_charGen imageForCharacter: 0x80] retain];
_cursors[Screen::CursorTypeCrossHatch] = [[_charGen imageForCharacter: 0x7f] retain];
size = [_charGen characterSize];
@@ -214,49 +210,6 @@ dispatch_async(dispatch_get_main_queue(), ^(){
[self setNeedsDisplay: YES];
}
-(void)setScanLines:(BOOL)scanLines
{
if (_scanLines == scanLines) return;
_scanLines = scanLines;
if (_scanLines)
{
NSMutableArray *filters;
CIFilter *filter;
[self setWantsLayer: YES];
filters = [NSMutableArray arrayWithCapacity: 3];
//add the scanlines
filter = [[ScanLineFilter new] autorelease];
[filter setValue: [NSNumber numberWithFloat: 1.0] forKey: @"inputDarken"];
[filter setValue: [NSNumber numberWithFloat: 0.025] forKey: @"inputLighten"];
[filters addObject: filter];
//blur it a bit...
filter = [CIFilter filterWithName: @"CIGaussianBlur"];
[filter setDefaults];
[filter setValue: [NSNumber numberWithFloat: 0.33] forKey: @"inputRadius"];
[filters addObject: filter];
[self setContentFilters: filters];
}
else
{
[self setContentFilters: @[]];
}
}
-(BOOL)isFlipped
{
return YES;
@@ -273,11 +226,6 @@ dispatch_async(dispatch_get_main_queue(), ^(){
[self startCursorTimer];
/*
[[self window] display];
[[self window] setHasShadow: NO];
[[self window] setHasShadow: YES];
*/
}
-(void)viewDidMoveToSuperview
@@ -467,8 +415,6 @@ dispatch_async(dispatch_get_main_queue(), ^(){
-(void)dealloc
{
close(_fd);
[_foregroundColor release];
[_backgroundColor release];
@@ -531,11 +477,12 @@ dispatch_async(dispatch_get_main_queue(), ^(){
//NSLog(@"[process complete]");
_fd = -1;
dispatch_async(dispatch_get_main_queue(), ^(){
iRect updateRect;
[self setCursorType: Screen::CursorTypeNone];
[self setCursorType: Screen::CursorTypeCrossHatch];
[self stopCursorTimer];
//_screen.setCursorType(Screen::CursorTypeNone);
@@ -802,7 +749,7 @@ dispatch_async(dispatch_get_main_queue(), ^(){
SEL cmd = [anItem action];
if (cmd == @selector(paste:)) {
return _fd >= 1;
return _fd >= 0;
}
if (cmd == @selector(copy:)) return NO;
if (cmd == @selector(copyDebugData:)) return YES;

1
a2-terminfo Submodule

Submodule a2-terminfo added at b91763ed70

View File

@@ -69,7 +69,8 @@ public:
CursorTypeNone,
CursorTypeUnderscore,
CursorTypePipe,
CursorTypeBlock
CursorTypeBlock,
CursorTypeCrossHatch,
};
Screen(unsigned height = 24, unsigned width = 80);