source: trunk/source/cocoa-ide/altconsole/AltConsoleDocument.m @ 11540

Last change on this file since 11540 was 11540, checked in by gb, 11 years ago

An "alternate console" application which can serve as a terminal/console
for a client application whose standard file descriptors aren't pointing
anywhere useful.

Looks like something written >5 years ago. Is.

File size: 5.9 KB
Line 
1/*
2   Copyright (C) 2003 Clozure Associates
3   This file is part of OpenMCL. 
4
5   OpenMCL is licensed under the terms of the Lisp Lesser GNU Public
6   License , known as the LLGPL and distributed with OpenMCL as the
7   file "LICENSE".  The LLGPL consists of a preamble and the LGPL,
8   which is distributed with OpenMCL as the file "LGPL".  Where these
9   conflict, the preamble takes precedence. 
10
11   OpenMCL is referenced in the preamble as the "LIBRARY."
12
13   The LLGPL is also available online at
14   http://opensource.franz.com/preamble.html
15
16  $Log: AltConsoleDocument.m,v $
17  Revision 1.2  2003/11/17 07:30:39  gb
18  update copyright/license
19
20  Revision 1.1.1.1  2003/11/17 07:14:42  gb
21  initial checkin
22
23*/
24
25#import "AltConsoleDocument.h"
26#import "AltConsoleDocumentController.h"
27#include <sys/signal.h>
28
29@implementation AltConsoleDocument
30- (id)init {
31    self = [super init];
32    if (self) {
33      NSMutableDictionary *dict;
34
35      peerDied = NO;
36      in = [[[NSFileHandle alloc] initWithFileDescriptor: 0] retain];
37      out =[[[NSFileHandle alloc] initWithFileDescriptor: 1] retain];
38      err =[[[NSFileHandle alloc] initWithFileDescriptor: 2] retain];
39      dict = [[NSMutableDictionary alloc] initWithCapacity: 3];
40      [dict setObject: [NSFont fontWithName: @"Courier" size:12.0] forKey: @"NSFont"];
41      [dict setObject: [NSColor redColor] forKey: @"NSColor"];
42      [dict setObject: [NSParagraphStyle defaultParagraphStyle] forKey: @"NSParagraphStyle"];
43      system_output_attributes = [dict retain];
44      dict = [NSMutableDictionary dictionaryWithDictionary: dict];
45      [dict setObject: [NSColor blackColor] forKey: @"NSColor"];
46      local_typing_attributes = [dict retain];
47      outpos = 0;
48    }
49    return self;
50}
51
52- (NSString *)windowNibName {
53    return @"AltConsole";
54}
55
56- (void) peerDied:(NSNotification *)notification {
57  peerDied = YES;
58  [indicator setTitle: @"Disconnected"];
59  [textView setEditable: NO];
60  if (watchdog) {
61    [watchdog invalidate];
62    watchdog = nil;
63  }
64}
65
66- (void) gotData:(NSNotification *)notification {
67  NSData *data = [[notification userInfo] objectForKey: NSFileHandleNotificationDataItem];
68  if ([data length] != 0) {
69    NSTextStorage *buffer_text = [textView textStorage];
70    NSString *s = [[NSString alloc] initWithData: data encoding: NSASCIIStringEncoding];
71    NSAttributedString *str = [[NSAttributedString alloc] initWithString: s attributes: system_output_attributes];
72    int textlen;
73   
74    [buffer_text beginEditing];
75    [buffer_text appendAttributedString: str];
76    [buffer_text endEditing];
77    textlen = [buffer_text length];
78    [textView scrollRangeToVisible: NSMakeRange(textlen, 0)];
79    [str release];
80    [in readInBackgroundAndNotify];
81    [self updateChangeCount: NSChangeDone];
82    outpos = textlen;
83  }
84}
85
86
87- (void) watchPeer: (id) theTimer {
88  pid_t peer = getppid();
89
90  if (kill(peer, 0) < 0) {
91    [[NSNotificationCenter defaultCenter]
92      postNotificationName: @"peerDied" object: nil];
93  }
94}
95
96
97- (void)windowControllerDidLoadNib:(NSWindowController *) aController {
98    [super windowControllerDidLoadNib:aController];
99    [[NSNotificationCenter defaultCenter]
100     addObserver: self
101     selector: @selector(gotData:)
102     name: NSFileHandleReadCompletionNotification
103     object: in];
104    [[NSNotificationCenter defaultCenter]
105     addObserver: self
106     selector: @selector(peerDied:)
107     name: @"peerDied"
108     object: nil];
109    [in readInBackgroundAndNotify];
110    [textView setUsesFontPanel: NO];
111    [textView setRichText: NO];
112    [textView setSmartInsertDeleteEnabled: NO];
113    [textView setUsesRuler: NO];
114    [textView setDelegate: self];
115    [textView setContinuousSpellCheckingEnabled: NO];
116    [self setFileName: [[AltConsoleDocumentController sharedDocumentController] herald]];
117    [[AltConsoleDocumentController sharedDocumentController]
118      add_console_document];
119    watchdog = [NSTimer scheduledTimerWithTimeInterval: 1.0
120                        target: self
121                        selector: @selector(watchPeer:)
122                        userInfo: nil
123                        repeats: YES];
124    [NSApp activateIgnoringOtherApps: YES];
125}
126
127- (NSData *)dataRepresentationOfType:(NSString *)aType {
128  [[textView string]
129    dataUsingEncoding: NSASCIIStringEncoding
130    allowLossyConversion: YES];
131}
132
133- (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType {
134    return YES;
135}
136
137- (BOOL)textView: tv shouldChangeTextInRange: (NSRange)r replacementString: s {
138  if (peerDied) {
139    return NO;
140  }
141  if (r.location < outpos) {
142    return NO;
143  }
144  [tv setTypingAttributes: local_typing_attributes];
145  return YES;
146}
147
148- (BOOL)textView: tv doCommandBySelector: (SEL) aselector {
149  if (! [self respondsToSelector: aselector]) {
150    return NO;
151  }
152  [self performSelector: aselector withObject: tv];
153  return YES;
154}
155
156- (void) sendString: (NSString *)s {
157  [out writeData: [s dataUsingEncoding: NSASCIIStringEncoding allowLossyConversion: YES]];
158}
159
160- (void) insertNewline:(NSTextView *)tv {
161  if (peerDied) {
162    [tv insertNewline: self];
163  } else {
164    NSTextStorage *textbuf = [tv textStorage];
165    int textlen = [textbuf length];
166    NSString *textstring = [textbuf string];
167    NSRange r = [tv selectedRange];
168    int curpos = r.location, curlen = r.length;
169   
170    if (curpos >= outpos) {
171      curpos += curlen;
172      [tv setSelectedRange: NSMakeRange(curpos, 0)];
173      [tv insertNewline: self];
174      curpos++;
175      textlen++;
176      if (curpos == textlen) {
177        [self sendString: [textstring substringWithRange: NSMakeRange(outpos, textlen-outpos)]];
178        outpos = textlen;
179      }
180    } else if (curlen > 0) {
181      [tv setSelectedRange: NSMakeRange(textlen,0)];
182      [tv insertText: [textstring substringWithRange: r]];
183      [tv scrollRangeToVisible: NSMakeRange([textbuf length],0)];
184    }
185  }
186}
187
188- (void) close {
189  [[NSNotificationCenter defaultCenter] removeObserver: self];
190  [[AltConsoleDocumentController sharedDocumentController]
191    remove_console_document];
192  if (watchdog) {
193    [watchdog invalidate];
194    watchdog = nil;
195  }
196  [super close];
197}
198 
199
200
201@end
Note: See TracBrowser for help on using the repository browser.