git-svn-id: svn://qnap.local/TwoTerm/trunk@1650 5590a31f-7b70-45f8-8c82-aa3a8e5f4507

This commit is contained in:
Kelvin Sherlock 2010-07-09 01:18:30 +00:00
parent 0ea3270420
commit 829183a0f3
17 changed files with 1222 additions and 243 deletions

File diff suppressed because it is too large Load Diff

View File

@ -273,6 +273,7 @@
<string>29B97315FDCFA39411CA2CEA</string>
<string>29B97317FDCFA39411CA2CEA</string>
<string>1DDD58140DA1D0A300B32029</string>
<string>B676065011DEBAE900D6B66C</string>
<string>29B97323FDCFA39411CA2CEA</string>
<string>1C37FBAC04509CD000000102</string>
<string>1C77FABC04509CD000000102</string>
@ -303,7 +304,7 @@
<real>324</real>
</array>
<key>RubberWindowFrame</key>
<string>156 170 1060 902 0 0 1920 1178 </string>
<string>522 243 1060 902 0 0 1920 1178 </string>
</dict>
<key>Module</key>
<string>PBXSmartGroupTreeModule</string>
@ -331,7 +332,7 @@
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
<string>B699A0C811E58D3B00F54CC8</string>
<string>B66979C511E6B0EB002ED475</string>
<key>history</key>
<array>
<string>B676058811DAE21100D6B66C</string>
@ -342,25 +343,23 @@
<string>B676062F11DE96AE00D6B66C</string>
<string>B676064811DEB80600D6B66C</string>
<string>B67606C811DED91C00D6B66C</string>
<string>B6EBE2CA11E0FF3E00EA0458</string>
<string>B65FA28111E29EDE00EB447E</string>
<string>B65FA2AD11E29F9300EB447E</string>
<string>B65FA2B411E29F9A00EB447E</string>
<string>B65FA2FE11E2A5D200EB447E</string>
<string>B649E0B511E2A88D0061921F</string>
<string>B649E1B211E2CDDE0061921F</string>
<string>B6F444CD11E41C7200C3A836</string>
<string>B6F444CF11E41C7200C3A836</string>
<string>B699A0BE11E58D3B00F54CC8</string>
<string>B699A0BF11E58D3B00F54CC8</string>
<string>B699A0C011E58D3B00F54CC8</string>
<string>B699A0C111E58D3B00F54CC8</string>
<string>B699A0C211E58D3B00F54CC8</string>
<string>B699A0C311E58D3B00F54CC8</string>
<string>B699A0C411E58D3B00F54CC8</string>
<string>B699A0C511E58D3B00F54CC8</string>
<string>B699A0C611E58D3B00F54CC8</string>
<string>B699A0C711E58D3B00F54CC8</string>
<string>B669796011E6A606002ED475</string>
<string>B669796111E6A606002ED475</string>
<string>B669796211E6A606002ED475</string>
<string>B669796311E6A606002ED475</string>
<string>B669797711E6A6CE002ED475</string>
<string>B669799411E6A7DF002ED475</string>
<string>B66979BD11E6ACB9002ED475</string>
<string>B66979BC11E6ACB4002ED475</string>
</array>
</dict>
<key>SplitCount</key>
@ -374,18 +373,18 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {714, 464}}</string>
<string>{{0, 0}, {714, 454}}</string>
<key>RubberWindowFrame</key>
<string>156 170 1060 902 0 0 1920 1178 </string>
<string>522 243 1060 902 0 0 1920 1178 </string>
</dict>
<key>Module</key>
<string>PBXNavigatorGroup</string>
<key>Proportion</key>
<string>464pt</string>
<string>454pt</string>
</dict>
<dict>
<key>Proportion</key>
<string>392pt</string>
<string>402pt</string>
<key>Tabs</key>
<array>
<dict>
@ -399,7 +398,7 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{10, 27}, {714, 365}}</string>
<string>{{10, 27}, {714, 375}}</string>
</dict>
<key>Module</key>
<string>XCDetailModule</string>
@ -425,6 +424,27 @@
<dict>
<key>PBXCVSModuleFilterTypeKey</key>
<integer>1032</integer>
<key>PBXCVSModuleTreeModuleColumnData</key>
<dict>
<key>PBXCVSModuleTreeModuleColumnWidthsKey</key>
<array>
<real>200</real>
<real>56.66162109375</real>
<real>63</real>
<real>60</real>
<real>63</real>
<real>139.556640625</real>
</array>
<key>PBXCVSModuleTreeModuleColumnsKey</key>
<array>
<string>Name</string>
<string>Status</string>
<string>Update</string>
<string>Revision</string>
<string>Author</string>
<string>Date</string>
</array>
</dict>
<key>PBXProjectModuleGUID</key>
<string>1CA23EE10692099D00951B8B</string>
<key>PBXProjectModuleLabel</key>
@ -453,9 +473,9 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{10, 27}, {714, 365}}</string>
<string>{{10, 27}, {714, 375}}</string>
<key>RubberWindowFrame</key>
<string>156 170 1060 902 0 0 1920 1178 </string>
<string>522 243 1060 902 0 0 1920 1178 </string>
</dict>
<key>Module</key>
<string>PBXBuildResultsModule</string>
@ -483,11 +503,11 @@
</array>
<key>TableOfContents</key>
<array>
<string>B699A0C911E58D3B00F54CC8</string>
<string>B669791311E68B9C002ED475</string>
<string>1CA23ED40692098700951B8B</string>
<string>B699A0CA11E58D3B00F54CC8</string>
<string>B669791411E68B9C002ED475</string>
<string>B676054211DADB9000D6B66C</string>
<string>B699A0CB11E58D3B00F54CC8</string>
<string>B669791511E68B9C002ED475</string>
<string>1CA23EDF0692099D00951B8B</string>
<string>1CA23EE00692099D00951B8B</string>
<string>1CA23EE10692099D00951B8B</string>
@ -636,14 +656,14 @@
</array>
<key>TableOfContents</key>
<array>
<string>B699A0CC11E58D3B00F54CC8</string>
<string>B669791611E68B9C002ED475</string>
<string>1CCC7628064C1048000F2A68</string>
<string>1CCC7629064C1048000F2A68</string>
<string>B699A0CD11E58D3B00F54CC8</string>
<string>B699A0CE11E58D3B00F54CC8</string>
<string>B699A0CF11E58D3B00F54CC8</string>
<string>B699A0D011E58D3B00F54CC8</string>
<string>B699A0D111E58D3B00F54CC8</string>
<string>B669791711E68B9C002ED475</string>
<string>B669791811E68B9C002ED475</string>
<string>B669791911E68B9C002ED475</string>
<string>B669791A11E68B9C002ED475</string>
<string>B669791B11E68B9C002ED475</string>
</array>
<key>ToolbarConfigUserDefaultsMinorVersion</key>
<string>2</string>
@ -677,11 +697,15 @@
<integer>5</integer>
<key>WindowOrderList</key>
<array>
<string>B66979B711E6A924002ED475</string>
<string>B669796711E6A606002ED475</string>
<string>B669796811E6A606002ED475</string>
<string>B66979C211E6B071002ED475</string>
<string>/Users/kelvin/Projects/2Term/2Term.xcodeproj</string>
<string>B699A0D211E58D3B00F54CC8</string>
<string>B66979A411E6A805002ED475</string>
</array>
<key>WindowString</key>
<string>156 170 1060 902 0 0 1920 1178 </string>
<string>522 243 1060 902 0 0 1920 1178 </string>
<key>WindowToolsV3</key>
<array>
<dict>

View File

@ -12,9 +12,9 @@
8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
B669798511E6A786002ED475 /* Lock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B669798411E6A786002ED475 /* Lock.cpp */; };
B676063B11DEAD3500D6B66C /* TermWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = B676063A11DEAD3500D6B66C /* TermWindowController.m */; };
B676065111DEBAE900D6B66C /* TermWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = B676065011DEBAE900D6B66C /* TermWindow.xib */; };
B67606D411DEDB4100D6B66C /* VT52View.mm in Sources */ = {isa = PBXBuildFile; fileRef = B67606D311DEDB4100D6B66C /* VT52View.mm */; };
B67606DA11DF6DAB00D6B66C /* EmulatorView.mm in Sources */ = {isa = PBXBuildFile; fileRef = B67606D911DF6DAB00D6B66C /* EmulatorView.mm */; };
B699A03011E528BC00F54CC8 /* Screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B699A02F11E528BC00F54CC8 /* Screen.cpp */; };
B699A05D11E54D4500F54CC8 /* OutputChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B699A05C11E54D4500F54CC8 /* OutputChannel.cpp */; };
@ -36,11 +36,11 @@
29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
8D1107310486CEB800E47090 /* TwoTerm-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "TwoTerm-Info.plist"; sourceTree = "<group>"; };
8D1107320486CEB800E47090 /* 2Term.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = 2Term.app; sourceTree = BUILT_PRODUCTS_DIR; };
B669798311E6A786002ED475 /* Lock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Lock.h; sourceTree = "<group>"; };
B669798411E6A786002ED475 /* Lock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Lock.cpp; sourceTree = "<group>"; };
B676063911DEAD3500D6B66C /* TermWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TermWindowController.h; sourceTree = "<group>"; };
B676063A11DEAD3500D6B66C /* TermWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TermWindowController.m; sourceTree = "<group>"; };
B676064D11DEBAE300D6B66C /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/TermWindow.xib; sourceTree = "<group>"; };
B67606D211DEDB4100D6B66C /* VT52View.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VT52View.h; sourceTree = "<group>"; };
B67606D311DEDB4100D6B66C /* VT52View.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = VT52View.mm; sourceTree = "<group>"; };
B67606D811DF6DAB00D6B66C /* EmulatorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EmulatorView.h; sourceTree = "<group>"; };
B67606D911DF6DAB00D6B66C /* EmulatorView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = EmulatorView.mm; sourceTree = "<group>"; };
B699A02E11E528BC00F54CC8 /* Screen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Screen.h; sourceTree = "<group>"; };
@ -72,12 +72,12 @@
080E96DDFE201D6D7F000001 /* Classes */ = {
isa = PBXGroup;
children = (
B669798311E6A786002ED475 /* Lock.h */,
B669798411E6A786002ED475 /* Lock.cpp */,
256AC3D80F4B6AC300CF3369 /* TwoTermAppDelegate.h */,
256AC3D90F4B6AC300CF3369 /* TwoTermAppDelegate.m */,
B676063911DEAD3500D6B66C /* TermWindowController.h */,
B676063A11DEAD3500D6B66C /* TermWindowController.m */,
B67606D211DEDB4100D6B66C /* VT52View.h */,
B67606D311DEDB4100D6B66C /* VT52View.mm */,
B67606D811DF6DAB00D6B66C /* EmulatorView.h */,
B67606D911DF6DAB00D6B66C /* EmulatorView.mm */,
B6EBE2B311E0EA9100EA0458 /* CharacterGenerator.h */,
@ -222,13 +222,13 @@
8D11072D0486CEB800E47090 /* main.m in Sources */,
256AC3DA0F4B6AC300CF3369 /* TwoTermAppDelegate.m in Sources */,
B676063B11DEAD3500D6B66C /* TermWindowController.m in Sources */,
B67606D411DEDB4100D6B66C /* VT52View.mm in Sources */,
B67606DA11DF6DAB00D6B66C /* EmulatorView.mm in Sources */,
B6EBE2B511E0EA9100EA0458 /* CharacterGenerator.m in Sources */,
B6F444C811E41AC000C3A836 /* VT05.mm in Sources */,
B699A03011E528BC00F54CC8 /* Screen.cpp in Sources */,
B699A05D11E54D4500F54CC8 /* OutputChannel.cpp in Sources */,
B699A09111E572A300F54CC8 /* VT52.mm in Sources */,
B669798511E6A786002ED475 /* Lock.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

48
Benaphore.cpp Normal file
View File

@ -0,0 +1,48 @@
/*
* Benaphore.cpp
* Blue Box
*
* Created by Kelvin Sherlock on 11/29/2009.
* Copyright 2009 Kelvin W Sherlock LLC. All rights reserved.
*
*/
#include "Benaphore.h"
#include <libkern/OSAtomic.h>
#include <mach/semaphore.h>
#include <mach/task.h>
#include <mach/mach_init.h>
#include <cstdio>
Benaphore::Benaphore()
{
_atom = 0;
semaphore_create(mach_task_self(), (semaphore_t *)&_sem, SYNC_POLICY_FIFO, 0);
}
Benaphore::~Benaphore()
{
semaphore_destroy(mach_task_self(), (semaphore_t)_sem);
}
void Benaphore::lock()
{
// returns new value
if (OSAtomicIncrement32Barrier(&_atom) > 1)
{
fprintf(stderr, "waiting %u\n", _atom);
semaphore_wait((semaphore_t)_sem);
}
}
void Benaphore::unlock()
{
if (OSAtomicDecrement32Barrier(&_atom) > 0)
{
fprintf(stderr, "releasing %u\n", _atom);
semaphore_signal((semaphore_t)_sem);
}
}

39
Benaphore.h Normal file
View File

@ -0,0 +1,39 @@
/*
* Benaphore.h
* Blue Box
*
* Created by Kelvin Sherlock on 11/29/2009.
* Copyright 2009 Kelvin W Sherlock LLC. All rights reserved.
*
*/
#ifndef __BENAPHORE_H__
#define __BENAPHORE_H__
#include <stdint.h>
#include <mach/semaphore.h>
class Benaphore {
public:
Benaphore();
~Benaphore();
void lock();
void unlock();
private:
int32_t _atom;
semaphore_t _sem;
};
class Locker {
public:
Locker(Benaphore& lock) : _lock(lock) { _lock.lock(); }
~Locker() { _lock.unlock(); }
private:
Benaphore& _lock;
};
#endif

View File

@ -14,7 +14,7 @@ class Screen;
class OutputChannel;
#else
#define Screen void
#define OutputChannel void;
#define OutputChannel void
#endif
@protocol Emulator
@ -23,4 +23,8 @@ class OutputChannel;
-(void)keyDown: (NSEvent *)event screen: (Screen *)screen output: (OutputChannel *)output;
-(void)reset;
-(NSString *)name;
-(const char *)termName;
@end

View File

@ -8,47 +8,27 @@
#import <Cocoa/Cocoa.h>
#include "Emulator.h"
#include "iGeometry.h"
#ifdef __cplusplus
#include <vector>
#include "Screen.h"
#endif
struct CursorPosition {
#ifdef __cplusplus
CursorPosition(int _x, int _y) throw() : x(_x), y(_y) {}
CursorPosition() throw() : x(0), y(0) {}
bool operator == (const CursorPosition& rhs) throw()
{ return rhs.x == x && rhs.y == y; }
bool operator != (const CursorPosition& rhs) throw()
{ return ! (*this == rhs); }
#endif
int x;
int y;
};
struct CharInfo {
char c;
uint8_t flags;
};
@class CharacterGenerator;
@interface EmulatorView : NSView {
int _fd;
/* these should not be modified without locking */
struct CursorPosition _cursor;
struct CharInfo _screen[24][80];
/* end locking */
int _fd;
NSObject<Emulator> *_emulator;
NSThread *_readerThread;
NSLock *_lock;
CharacterGenerator *_charGen;
@ -57,15 +37,16 @@ struct CharInfo {
CGFloat _charHeight;
CGFloat _charWidth;
unsigned _height;
unsigned _width;
CGFloat _paddingTop;
CGFloat _paddingBottom;
CGFloat _paddingLeft;
CGFloat _paddingRight;
#ifdef __cplusplus
//std::vector< std::vector<CharInfo> > _screen;
Screen _screen;
#endif
}
@ -74,6 +55,6 @@ struct CharInfo {
-(void)dataAvailable;
@property (nonatomic, assign) int fd;
@property (nonatomic, assign) struct CursorPosition cursorPosition;
//@property (nonatomic, assign) iPoint cursor;
@end

View File

@ -10,10 +10,13 @@
#import "CharacterGenerator.h"
#import "VT52.h"
#include "OutputChannel.h"
@implementation EmulatorView
@synthesize fd = _fd;
@synthesize cursorPosition = _cursor;
-(void)awakeFromNib
@ -21,21 +24,14 @@
_charWidth = 7;
_charHeight = 16;
_height = 24;
_width = 80;
_foregroundColor = [[NSColor greenColor] retain];
_backgroundColor = [[NSColor blackColor] retain];
_charGen = [[CharacterGenerator generator] retain];
_lock = [NSLock new];
std::memset(_screen, 0, sizeof(_screen));
_cursor = CursorPosition(0, 0);
_emulator = [VT52 new];
}
-(BOOL)isFlipped
@ -63,36 +59,49 @@
{
NSRect bounds = [self bounds];
NSRect screenRect = dirtyRect;
unsigned x, y;
unsigned minX = floor(dirtyRect.origin.x / _charWidth);
unsigned maxX = ceil((dirtyRect.origin.x + dirtyRect.size.width) / _charWidth);
screenRect.origin.x -= _paddingLeft;
screenRect.origin.y -= _paddingTop;
if (screenRect.origin.x < 0)
{
screenRect.size.width -= screenRect.origin.x;
screenRect.origin.x = 0;
}
if (screenRect.origin.y < 0)
{
screenRect.size.width -= screenRect.origin.y;
screenRect.origin.y = 0;
}
unsigned minX = floor(screenRect.origin.x / _charWidth);
unsigned maxX = ceil((screenRect.origin.x + screenRect.size.width) / _charWidth);
unsigned minY = floor(dirtyRect.origin.y / _charHeight);
unsigned maxY = ceil((dirtyRect.origin.y + dirtyRect.size.height) / _charHeight);
unsigned minY = floor(screenRect.origin.y / _charHeight);
unsigned maxY = ceil((screenRect.origin.y + screenRect.size.height) / _charHeight);
// x/y are 0-indexed here.
maxY = std::min(_height - 1, maxY);
maxX = std::min(_width - 1, maxX);
maxY = std::min(_screen.height() - 1, maxY);
maxX = std::min(_screen.width() - 1, maxX);
[_backgroundColor setFill];
NSRectFill(dirtyRect);
[_foregroundColor setFill];
_screen.lock();
[_lock lock];
for (x = minX; x <= maxX; ++x)
{
for (y = minY; y <= maxY; ++y)
{
NSImage *img;
CharInfo ci = _screen[y][x];
CharInfo ci = _screen.getc(x, y);
// todo -- check flags to determine fg/bg color, etc.
@ -107,7 +116,7 @@
*/
if (img)
{
[img drawInRect: NSMakeRect(x * _charWidth, y *_charHeight, _charWidth, _charHeight)
[img drawInRect: NSMakeRect(_paddingLeft + x * _charWidth, _paddingTop + y *_charHeight, _charWidth, _charHeight)
fromRect: NSZeroRect operation: NSCompositeCopy
fraction: 1.0
respectFlipped: YES
@ -116,19 +125,29 @@
}
}
[_lock unlock];
_screen.unlock();
}
-(void)dealloc
{
close(_fd);
[_readerThread release];
[_lock release];
[_emulator release];
[super dealloc];
}
-(void)keyDown:(NSEvent *)theEvent
{
OutputChannel channel(_fd);
[_emulator keyDown: theEvent screen: &_screen output: &channel];
}
-(void)startBackgroundReader
{
if (_readerThread) return;
@ -169,7 +188,66 @@
}
-(void)dataAvailable { }
-(void)dataAvailable
{
typedef void (*ProcessCharFX)(id, SEL, uint8_t, Screen *, OutputChannel *);
ProcessCharFX fx;
SEL cmd;
OutputChannel channel(_fd);
cmd = @selector(processCharacter: screen: output:);
fx = (ProcessCharFX)[_emulator methodForSelector: cmd];
for(;;)
{
NSAutoreleasePool *pool;
iRect updateRect;
CGRect rect;
uint8_t buffer[512];
ssize_t size;
size = read(_fd, buffer, sizeof(buffer));
if (size == 0) break;
if (size < 0)
{
if (errno == EINTR || errno == EAGAIN) continue;
perror("[EmulatorView dataAvailable]");
break;
}
pool = [NSAutoreleasePool new];
_screen.beginUpdate();
for (unsigned i = 0; i < size; ++i)
{
fx(_emulator,cmd, buffer[i], &_screen, &channel);
}
updateRect = _screen.endUpdate();
rect.origin.x = updateRect.origin.x;
rect.origin.y = updateRect.origin.y;
rect.size.width = updateRect.size.width;
rect.size.height = updateRect.size.height;
rect.origin.x *= _charWidth;
rect.origin.y *= _charHeight;
rect.size.width *= _charWidth;
rect.size.height *= _charHeight;
rect.origin.x += _paddingLeft;
rect.origin.y += _paddingTop;
[self setNeedsDisplayInRect: rect];
[pool release];
}
}
@end

View File

@ -12,7 +12,7 @@
</object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="1"/>
<integer value="2"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@ -52,22 +52,12 @@
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSCustomView" id="296370061">
<object class="NSCustomView" id="59249513">
<reference key="NSNextResponder" ref="1006"/>
<int key="NSvFlags">268</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSCustomView" id="59249513">
<reference key="NSNextResponder" ref="296370061"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{10, 10}, {560, 384}}</string>
<reference key="NSSuperview" ref="296370061"/>
<string key="NSClassName">VT52View</string>
</object>
</object>
<string key="NSFrame">{{20, 20}, {580, 404}}</string>
<string key="NSFrame">{{30, 30}, {560, 384}}</string>
<reference key="NSSuperview" ref="1006"/>
<string key="NSClassName">NSView</string>
<string key="NSClassName">EmulatorView</string>
</object>
</object>
<string key="NSFrameSize">{620, 444}</string>
@ -146,24 +136,14 @@
<reference key="object" ref="1006"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="296370061"/>
<reference ref="59249513"/>
</object>
<reference key="parent" ref="1005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">7</int>
<reference key="object" ref="296370061"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="59249513"/>
</object>
<reference key="parent" ref="1006"/>
<string key="objectName">Back View</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">5</int>
<reference key="object" ref="59249513"/>
<reference key="parent" ref="296370061"/>
<reference key="parent" ref="1006"/>
<string key="objectName">Emulator View</string>
</object>
</object>
@ -180,8 +160,6 @@
<string>1.editorWindowContentRectSynchronizationRect</string>
<string>2.IBPluginDependency</string>
<string>5.IBPluginDependency</string>
<string>7.IBPluginDependency</string>
<string>7.IBViewIntegration.shadowColor</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
@ -193,11 +171,6 @@
<string>{{202, 428}, {480, 270}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MAA</bytes>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
@ -248,14 +221,6 @@
<string key="minorKey">TermWindowController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">VT52View</string>
<string key="superclassName">EmulatorView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">VT52View.h</string>
</object>
</object>
</object>
<object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
<bool key="EncodedWithXMLCoder">YES</bool>

26
Lock.cpp Normal file
View File

@ -0,0 +1,26 @@
#include "Lock.h"
Lock::Lock()
{
pthread_mutex_init(&_mutex, NULL);
}
Lock::~Lock()
{
pthread_mutex_destroy(&_mutex);
}
void Lock::lock()
{
pthread_mutex_lock(&_mutex);
}
void Lock::unlock()
{
pthread_mutex_unlock(&_mutex);
}
bool Lock::tryLock()
{
return pthread_mutex_trylock(&_mutex) == 0;
}

31
Lock.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef __LOCK_H__
#define __LOCK_H__
#include <pthread.h>
class Lock {
public:
Lock();
~Lock();
void lock();
void unlock();
bool tryLock();
private:
pthread_mutex_t _mutex;
};
class Locker {
public:
Locker(Lock& lock) : _lock(lock) { _lock.lock(); }
~Locker() { _lock.unlock(); }
private:
Lock &_lock;
};
#endif

View File

@ -32,6 +32,7 @@ Screen::Screen(unsigned height, unsigned width)
void Screen::beginUpdate()
{
_lock.lock();
_updates.clear();
}
@ -41,6 +42,8 @@ iRect Screen::endUpdate()
int maxY = -1;
int minX = _width;
int minY = _height;
for (UpdateIterator iter = _updates.begin(); iter != _updates.end(); ++iter)
{
@ -51,6 +54,8 @@ iRect Screen::endUpdate()
minY = std::min(minY, iter->y);
}
_lock.unlock();
return iRect(iPoint(minX, minY), iSize(maxX + 1 - minX, maxY + 1 - minY));
}

View File

@ -11,9 +11,12 @@
#define __SCREEN_H__
#include "iGeometry.h"
#include "Lock.h"
#include <vector>
typedef struct CharInfo {
CharInfo() : c(0), flag(0) {}
@ -28,7 +31,7 @@ class Screen {
public:
Screen(unsigned height, unsigned width);
Screen(unsigned height = 24, unsigned width = 80);
int x() const;
int y() const;
@ -55,6 +58,8 @@ public:
void putc(uint8_t c, bool incrementX = true);
CharInfo getc(int x, int y) const;
void eraseLine();
void eraseScreen();
@ -65,6 +70,10 @@ public:
void beginUpdate();
iRect endUpdate();
void lock();
void unlock();
private:
iPoint _cursor;
@ -73,6 +82,9 @@ private:
uint8_t _flag;
Lock _lock;
std::vector< std::vector< CharInfo > > _screen;
std::vector<iPoint> _updates;
@ -87,47 +99,66 @@ private:
};
int Screen::x() const
inline int Screen::x() const
{
return _cursor.x;
}
int Screen::y() const
inline int Screen::y() const
{
return _cursor.y;
}
iPoint Screen::cursor() const
inline iPoint Screen::cursor() const
{
return _cursor;
}
uint8_t Screen::flag() const
inline uint8_t Screen::flag() const
{
return _flag;
}
unsigned Screen::height() const
inline unsigned Screen::height() const
{
return _height;
}
unsigned Screen::width() const
inline unsigned Screen::width() const
{
return _width;
}
void Screen::setCursor(iPoint point, bool clampX, bool clampY)
inline void Screen::setCursor(iPoint point, bool clampX, bool clampY)
{
setX(point.x, clampX);
setY(point.y, clampY);
}
void Screen::setCursor(int x, int y, bool clampX, bool clampY)
inline void Screen::setCursor(int x, int y, bool clampX, bool clampY)
{
setX(x, clampX);
setY(y, clampY);
}
inline void Screen::lock()
{
_lock.lock();
}
inline void Screen::unlock()
{
_lock.unlock();
}
inline CharInfo Screen::getc(int x, int y) const
{
if (x < 0 || y < 0) return CharInfo(0,0);
if (x >= _width || y >= _height) return CharInfo(0,0);
return _screen[y][x];
}
#endif

View File

@ -8,7 +8,6 @@
#import "TwoTermAppDelegate.h"
#include "chars.h"
#import "TermWindowController.h"

11
VT05.mm
View File

@ -40,6 +40,17 @@ enum {
};
-(NSString *)name
{
return @"vt05";
}
-(const char *)termName
{
return "vt05";
}
-(void)reset
{
_state = StateText;

39
VT52.mm
View File

@ -36,6 +36,39 @@ enum {
@implementation VT52
-(NSString *)name
{
switch (_model)
{
case ModelVT50:
return @"VT50";
case ModelVT50H:
return @"VT50H";
case ModelVT55:
return @"VT55";
case ModelVT52:
default:
return @"VT52";
}
}
-(const char *)termName
{
switch (_model)
{
case ModelVT50:
return "vt50";
case ModelVT50H:
return "vt50h";
case ModelVT55:
return "vt55";
case ModelVT52:
default:
return "vt52";
}
}
-(void)keyDown: (NSEvent *)event screen: (Screen *)screen output: (OutputChannel *)output
{
unsigned flags = [event modifierFlags];
@ -179,6 +212,7 @@ enum {
screen->decrementY();
_state = StateText;
break;
case 'C':
/* cursor right */
screen->incrementX();
@ -205,6 +239,7 @@ enum {
/* home */
screen->setCursor(0, 0);
_state = StateText;
break;
case 'Y':
/* direct cursor addressing (not on the VT50) */
@ -381,6 +416,7 @@ enum {
case 0x09:
[self tab: screen];
break;
case 0x0a:
screen->lineFeed();
@ -404,8 +440,9 @@ enum {
if (c >= 0140 && (_model == ModelVT50 || _model == ModelVT50H))
c -= 040;
output->write(c);
screen->putc(c);
}
break;
}
break;

View File

@ -51,4 +51,4 @@ typedef struct iRect {
} iRect;
#endif;
#endif