mirror of
https://github.com/ksherlock/TwoTerm.git
synced 2026-01-24 03:16:09 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4507998f1d | ||
|
|
9fcf9f333f | ||
|
|
6a117c7b8a | ||
|
|
5bd035e33e | ||
|
|
66040a8366 | ||
|
|
b63b60826d | ||
|
|
e0bc21d663 |
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "a2-terminfo"]
|
||||
path = a2-terminfo
|
||||
url = https://github.com/ksherlock/a2-terminfo
|
||||
20
ChildMonitor.h
Normal file
20
ChildMonitor.h
Normal file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// 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;
|
||||
|
||||
@end
|
||||
239
ChildMonitor.mm
Normal file
239
ChildMonitor.mm
Normal file
@@ -0,0 +1,239 @@
|
||||
//
|
||||
// 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)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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>2</string>
|
||||
<string>3</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.utilities</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
||||
@@ -25,10 +25,6 @@
|
||||
|
||||
NSObject <Emulator> *_emulator;
|
||||
|
||||
NSThread * _thread;
|
||||
int _fd;
|
||||
std::atomic<pid_t> _pid;
|
||||
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) NSDictionary *parameters;
|
||||
@@ -39,5 +35,7 @@
|
||||
@property (nonatomic, retain) NSObject<Emulator> *emulator;
|
||||
|
||||
-(void)initPTY;
|
||||
-(void)childFinished: (int)status;
|
||||
-(void)processData: (const void *)buffer size: (size_t)size;
|
||||
|
||||
@end
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "ChildMonitor.h"
|
||||
|
||||
@implementation TermWindowController
|
||||
|
||||
@synthesize emulator = _emulator;
|
||||
@@ -46,12 +48,13 @@
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
[[ChildMonitor monitor] removeController: self];
|
||||
|
||||
[_emulator release];
|
||||
[_emulatorView release];
|
||||
[_colorView release];
|
||||
|
||||
[_parameters release];
|
||||
[_thread release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
@@ -66,16 +69,30 @@
|
||||
-(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 +106,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 +130,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,122 +191,18 @@
|
||||
|
||||
[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)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];
|
||||
-(void)processData: (const void *)buffer size: (size_t)size {
|
||||
[_emulatorView processData: (uint8_t *)buffer size: size];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
@@ -359,14 +271,7 @@
|
||||
|
||||
-(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];
|
||||
}
|
||||
|
||||
|
||||
@@ -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,7 @@
|
||||
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 */; };
|
||||
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 +103,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 +164,8 @@
|
||||
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>"; };
|
||||
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 +207,8 @@
|
||||
B6EBE2B411E0EA9100EA0458 /* CharacterGenerator.mm */,
|
||||
B60EBDE111E90FC300C1974F /* ScanLineFilter.h */,
|
||||
B60EBDE211E90FC300C1974F /* ScanLineFilter.m */,
|
||||
B69E32A820221C9E0086D7B1 /* ChildMonitor.mm */,
|
||||
B69E32AA20221CCA0086D7B1 /* ChildMonitor.h */,
|
||||
);
|
||||
name = Classes;
|
||||
sourceTree = "<group>";
|
||||
@@ -261,6 +269,7 @@
|
||||
29B97317FDCFA39411CA2CEA /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B60B98702022BAF100E688E3 /* a2-terminfo */,
|
||||
B60EBDE711E9143F00C1974F /* ScanLineFilter.cikernel */,
|
||||
B66979CE11E6BCAE002ED475 /* images */,
|
||||
8D1107310486CEB800E47090 /* Info.plist */,
|
||||
@@ -282,6 +291,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 +396,7 @@
|
||||
8D11072C0486CEB800E47090 /* Sources */,
|
||||
8D11072E0486CEB800E47090 /* Frameworks */,
|
||||
B61D0D57125B728D001C713B /* CopyFiles */,
|
||||
B60B98802022BF5900E688E3 /* ShellScript */,
|
||||
);
|
||||
buildRules = (
|
||||
B6C173931D32A8840024E360 /* PBXBuildRule */,
|
||||
@@ -425,7 +446,6 @@
|
||||
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 +463,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 +487,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 */,
|
||||
|
||||
1
a2-terminfo
Submodule
1
a2-terminfo
Submodule
Submodule a2-terminfo added at b91763ed70
Reference in New Issue
Block a user