mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-11 15:37:29 +02:00
- Added support for Distributed Objects, as an alternative to NSPortMessage for communicating between processes (MM_USE_DO=0 to disable in MacVim.h) - MMWindowController, MMTextView does not communicate directly with backend anymore, instead they have to go through MMVimController sendMessage:data:wait:. - If window is closed by clicking the red button, Vim now displays a message if a buffer has been modified.
git-svn-id: http://macvim.googlecode.com/svn/trunk@20 96c4425d-ca35-0410-94e5-3396d5c13a8f
This commit is contained in:
+6
-1
@@ -9,10 +9,15 @@
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "MacVim.h"
|
||||
|
||||
|
||||
|
||||
@interface MMAppController : NSObject {
|
||||
@interface MMAppController : NSObject
|
||||
#if MM_USE_DO
|
||||
<MMAppProtocol>
|
||||
#endif
|
||||
{
|
||||
NSPort *receivePort;
|
||||
NSMutableArray *vimControllers;
|
||||
unsigned terminateNowCount;
|
||||
|
||||
+70
-1
@@ -10,7 +10,6 @@
|
||||
|
||||
#import "MMAppController.h"
|
||||
#import "MMVimController.h"
|
||||
#import "MacVim.h"
|
||||
|
||||
|
||||
|
||||
@@ -21,6 +20,20 @@
|
||||
if ((self = [super init])) {
|
||||
vimControllers = [NSMutableArray new];
|
||||
|
||||
#if MM_USE_DO
|
||||
// NOTE! If the name of the connection changes here it must also be
|
||||
// updated in MMBackend.m.
|
||||
NSConnection *connection = [NSConnection defaultConnection];
|
||||
NSString *name = [NSString stringWithFormat:@"%@-connection",
|
||||
[[NSBundle mainBundle] bundleIdentifier]];
|
||||
//NSLog(@"Registering connection with name '%@'", name);
|
||||
if ([connection registerName:name]) {
|
||||
[connection setRootObject:self];
|
||||
} else {
|
||||
NSLog(@"WARNING: Failed to register connection with name '%@'",
|
||||
name);
|
||||
}
|
||||
#else
|
||||
// Init named port for VimTasks to connect to
|
||||
receivePort = [NSMachPort new];
|
||||
[receivePort setDelegate:self];
|
||||
@@ -37,6 +50,7 @@
|
||||
name:portName]) {
|
||||
NSLog(@"WARNING: Failed to start mach bootstrap server");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -46,7 +60,9 @@
|
||||
{
|
||||
//NSLog(@"MMAppController dealloc");
|
||||
|
||||
#if !MM_USE_DO
|
||||
[receivePort release];
|
||||
#endif
|
||||
[vimControllers release];
|
||||
|
||||
[super dealloc];
|
||||
@@ -86,6 +102,38 @@
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:
|
||||
(NSApplication *)sender
|
||||
{
|
||||
#if MM_USE_DO
|
||||
int reply = NSTerminateNow;
|
||||
BOOL modifiedBuffers = NO;
|
||||
|
||||
unsigned i, count = [vimControllers count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
MMVimController *controller = [vimControllers objectAtIndex:i];
|
||||
id proxy = [controller backendProxy];
|
||||
if (proxy && [proxy checkForModifiedBuffers]) {
|
||||
modifiedBuffers = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (modifiedBuffers) {
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert addButtonWithTitle:@"Quit"];
|
||||
[alert addButtonWithTitle:@"Cancel"];
|
||||
[alert setMessageText:@"Quit without saving?"];
|
||||
[alert setInformativeText:@"There are modified buffers, "
|
||||
" if you quit now all changes will be lost. Quit anyway?"];
|
||||
[alert setAlertStyle:NSWarningAlertStyle];
|
||||
|
||||
if ([alert runModal] != NSAlertFirstButtonReturn) {
|
||||
reply = NSTerminateCancel;
|
||||
}
|
||||
|
||||
[alert release];
|
||||
}
|
||||
|
||||
return reply;
|
||||
#else
|
||||
int reply = NSTerminateNow;
|
||||
|
||||
// HACK! Send message to all vim tasks asking if they have modified
|
||||
@@ -136,6 +184,7 @@
|
||||
}
|
||||
|
||||
return reply;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(NSNotification *)aNotification
|
||||
@@ -145,6 +194,7 @@
|
||||
[self autorelease];
|
||||
}
|
||||
|
||||
#if !MM_USE_DO
|
||||
- (void)handlePortMessage:(NSPortMessage *)portMessage
|
||||
{
|
||||
unsigned msgid = [portMessage msgid];
|
||||
@@ -163,6 +213,7 @@
|
||||
NSLog(@"WARNING: Unknown message received (msgid=%d)", msgid);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)removeVimController:(id)controller
|
||||
{
|
||||
@@ -179,4 +230,22 @@
|
||||
[NSTask launchedTaskWithLaunchPath:path arguments:args];
|
||||
}
|
||||
|
||||
#if MM_USE_DO
|
||||
- (byref id <MMFrontendProtocol>)connectBackend:
|
||||
(byref in id <MMBackendProtocol>)backend;
|
||||
{
|
||||
//NSLog(@"Frontend got connection request from backend...adding new "
|
||||
// "MMVimController");
|
||||
|
||||
[(NSDistantObject*)backend
|
||||
setProtocolForProxy:@protocol(MMBackendProtocol)];
|
||||
|
||||
MMVimController *wc = [[[MMVimController alloc] initWithBackend:backend]
|
||||
autorelease];
|
||||
[vimControllers addObject:wc];
|
||||
|
||||
return wc;
|
||||
}
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
+12
-2
@@ -9,15 +9,25 @@
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "MacVim.h"
|
||||
|
||||
|
||||
|
||||
@interface MMBackend : NSObject {
|
||||
@interface MMBackend : NSObject
|
||||
#if MM_USE_DO
|
||||
<MMBackendProtocol>
|
||||
#endif
|
||||
{
|
||||
NSMutableArray *queue;
|
||||
NSMutableData *drawData;
|
||||
NSData *replyData;
|
||||
#if MM_USE_DO
|
||||
NSConnection *connection;
|
||||
id frontendProxy;
|
||||
#else
|
||||
NSPort *sendPort;
|
||||
NSPort *receivePort;
|
||||
NSData *replyData;
|
||||
#endif
|
||||
NSDictionary *colorDict;
|
||||
BOOL inputReceived;
|
||||
BOOL receivedKillTaskMsg;
|
||||
|
||||
+181
-59
@@ -9,7 +9,6 @@
|
||||
*/
|
||||
|
||||
#import "MMBackend.h"
|
||||
#import "MacVim.h"
|
||||
#import "vim.h"
|
||||
|
||||
|
||||
@@ -21,9 +20,13 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
|
||||
|
||||
@interface MMBackend (Private)
|
||||
- (void)handleMessage:(int)msgid data:(NSData *)data;
|
||||
+ (NSDictionary *)specialKeys;
|
||||
- (void)handleKeyDown:(NSString *)key modifiers:(int)mods;
|
||||
- (void)queueMessage:(int)msgid data:(NSData *)data;
|
||||
#if MM_USE_DO
|
||||
- (void)connectionDidDie:(NSNotification *)notification;
|
||||
#endif
|
||||
@end
|
||||
|
||||
|
||||
@@ -51,10 +54,17 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
|
||||
[queue release];
|
||||
[drawData release];
|
||||
#if MM_USE_DO
|
||||
[frontendProxy release];
|
||||
[connection release];
|
||||
#else
|
||||
[sendPort release];
|
||||
[receivePort release];
|
||||
#endif
|
||||
[colorDict release];
|
||||
|
||||
[super dealloc];
|
||||
@@ -78,6 +88,14 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
|
||||
- (BOOL)checkin
|
||||
{
|
||||
#if MM_USE_DO
|
||||
// NOTE! If the name of the connection changes here it must also be
|
||||
// updated in MMAppController.m.
|
||||
NSString *name = [NSString stringWithFormat:@"%@-connection",
|
||||
[[NSBundle mainBundle] bundleIdentifier]];
|
||||
connection = [NSConnection connectionWithRegisteredName:name host:nil];
|
||||
if (!connection)
|
||||
#else
|
||||
// NOTE! If the name of the port changes here it must also be updated in
|
||||
// MMAppController.m.
|
||||
NSString *portName = [NSString stringWithFormat:@"%@-taskport",
|
||||
@@ -85,7 +103,9 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
|
||||
NSPort *port = [[[NSMachBootstrapServer sharedInstance]
|
||||
portForName:portName host:nil] retain];
|
||||
if (!port) {
|
||||
if (!port)
|
||||
#endif
|
||||
{
|
||||
#if 0
|
||||
NSString *path = [[NSBundle mainBundle] bundlePath];
|
||||
if (![[NSWorkspace sharedWorkspace] launchApplication:path]) {
|
||||
@@ -113,20 +133,52 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
// returns a valid port. Also set a time-out date so that we don't get
|
||||
// stuck doing this forever.
|
||||
NSDate *timeOutDate = [NSDate dateWithTimeIntervalSinceNow:15];
|
||||
while (!port &&
|
||||
NSOrderedDescending == [timeOutDate compare:[NSDate date]]) {
|
||||
while (
|
||||
#if MM_USE_DO
|
||||
!connection
|
||||
#else
|
||||
!port
|
||||
#endif
|
||||
&& NSOrderedDescending == [timeOutDate compare:[NSDate date]])
|
||||
{
|
||||
[[NSRunLoop currentRunLoop]
|
||||
runMode:NSDefaultRunLoopMode
|
||||
beforeDate:[NSDate dateWithTimeIntervalSinceNow:1]];
|
||||
port = [[NSMachBootstrapServer sharedInstance] portForName:portName];
|
||||
#if MM_USE_DO
|
||||
connection = [NSConnection connectionWithRegisteredName:name
|
||||
host:nil];
|
||||
#else
|
||||
port = [[NSMachBootstrapServer sharedInstance]
|
||||
portForName:portName];
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!port) {
|
||||
#if MM_USE_DO
|
||||
if (!connection)
|
||||
#else
|
||||
if (!port)
|
||||
#endif
|
||||
{
|
||||
NSLog(@"WARNING: Timed-out waiting for GUI to launch.");
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
#if MM_USE_DO
|
||||
id proxy = [connection rootProxy];
|
||||
[proxy setProtocolForProxy:@protocol(MMAppProtocol)];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(connectionDidDie:)
|
||||
name:NSConnectionDidDieNotification object:connection];
|
||||
|
||||
frontendProxy = [(NSDistantObject*)[proxy connectBackend:self] retain];
|
||||
if (frontendProxy) {
|
||||
[frontendProxy setProtocolForProxy:@protocol(MMAppProtocol)];
|
||||
}
|
||||
|
||||
return connection && frontendProxy;
|
||||
#else
|
||||
receivePort = [NSMachPort new];
|
||||
[receivePort setDelegate:self];
|
||||
|
||||
@@ -137,10 +189,12 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
receivePort:receivePort wait:YES];
|
||||
|
||||
return YES;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (BOOL)openVimWindowWithRows:(int)rows columns:(int)cols
|
||||
{
|
||||
#if !MM_USE_DO
|
||||
if (!sendPort) {
|
||||
#if 0
|
||||
// TODO: Wait until connected---maybe time out at some point?
|
||||
@@ -165,6 +219,7 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif // !MM_USE_DO
|
||||
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
|
||||
@@ -276,19 +331,25 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
// TODO: Come up with a better way to handle the insertion point.
|
||||
[self updateInsertionPoint];
|
||||
|
||||
#if MM_USE_DO
|
||||
[frontendProxy processCommandQueue:queue];
|
||||
#else
|
||||
[NSPortMessage sendMessage:FlushQueueMsgID withSendPort:sendPort
|
||||
components:queue wait:YES];
|
||||
#endif
|
||||
[queue removeAllObjects];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)waitForInput:(int)milliseconds
|
||||
{
|
||||
#if !MM_USE_DO
|
||||
if (![receivePort isValid]) {
|
||||
// This should only happen if the GUI crashes.
|
||||
NSLog(@"ERROR: The receive port is no longer valid, quitting...");
|
||||
getout(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
NSDate *date = milliseconds > 0 ?
|
||||
[NSDate dateWithTimeIntervalSinceNow:.001*milliseconds] :
|
||||
@@ -308,10 +369,18 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
|
||||
- (void)exit
|
||||
{
|
||||
#if MM_USE_DO
|
||||
// By invalidating the NSConnection the MMWindowController immediately
|
||||
// finds out that the connection is down and as a result
|
||||
// [MMWindowController connectionDidDie:] is invoked.
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[connection invalidate];
|
||||
#else
|
||||
if (!receivedKillTaskMsg) {
|
||||
[NSPortMessage sendMessage:TaskExitedMsgID withSendPort:sendPort
|
||||
receivePort:receivePort wait:YES];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)selectTab:(int)index
|
||||
@@ -388,6 +457,9 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
- (char *)browseForFileInDirectory:(char *)dir title:(char *)title
|
||||
saving:(int)saving
|
||||
{
|
||||
#if MM_USE_DO
|
||||
return nil;
|
||||
#else
|
||||
//NSLog(@"browseForFileInDirectory:%s title:%s saving:%d", dir, title,
|
||||
// saving);
|
||||
|
||||
@@ -430,6 +502,7 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
|
||||
[replyData release]; replyData = nil;
|
||||
return (char*)s;
|
||||
#endif // MM_USE_DO
|
||||
}
|
||||
|
||||
- (void)updateInsertionPoint
|
||||
@@ -665,6 +738,27 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
return INVALCOLOR;
|
||||
}
|
||||
|
||||
#if MM_USE_DO
|
||||
- (oneway void)processInput:(int)msgid data:(in NSData *)data
|
||||
{
|
||||
[self handleMessage:msgid data:data];
|
||||
inputReceived = YES;
|
||||
}
|
||||
|
||||
- (BOOL)checkForModifiedBuffers
|
||||
{
|
||||
buf_T *buf;
|
||||
for (buf = firstbuf; buf != NULL; buf = buf->b_next) {
|
||||
if (bufIsChanged(buf)) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
#else // MM_USE_DO
|
||||
|
||||
- (void)handlePortMessage:(NSPortMessage *)portMessage
|
||||
{
|
||||
unsigned msgid = [portMessage msgid];
|
||||
@@ -672,17 +766,48 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
if (ConnectedMsgID == msgid) {
|
||||
sendPort = [[portMessage sendPort] retain];
|
||||
//NSLog(@"VimTask connected to MMVimController.");
|
||||
} else if (KillTaskMsgID == msgid) {
|
||||
} else if (TaskShouldTerminateMsgID == msgid) {
|
||||
int reply = TerminateReplyYesMsgID;
|
||||
buf_T *buf;
|
||||
for (buf = firstbuf; buf != NULL; buf = buf->b_next) {
|
||||
if (bufIsChanged(buf)) {
|
||||
reply = TerminateReplyNoMsgID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//NSLog(@"TaskShouldTerminateMsgID = %s",
|
||||
// reply == TerminateReplyYesMsgID ? "YES" : "NO");
|
||||
|
||||
[NSPortMessage sendMessage:reply withSendPort:[portMessage sendPort]
|
||||
wait:YES];
|
||||
} else {
|
||||
NSArray *components = [portMessage components];
|
||||
NSData *data = [components count] > 0 ?
|
||||
[components objectAtIndex:0] : nil;
|
||||
[self handleMessage:msgid data:data];
|
||||
}
|
||||
}
|
||||
#endif // MM_USE_DO
|
||||
|
||||
@end // MMBackend
|
||||
|
||||
|
||||
|
||||
@implementation MMBackend (Private)
|
||||
|
||||
- (void)handleMessage:(int)msgid data:(NSData *)data
|
||||
{
|
||||
if (KillTaskMsgID == msgid) {
|
||||
//NSLog(@"VimTask received kill message; exiting now.");
|
||||
// Set this flag here so that exit does not send TaskExitedMsgID back
|
||||
// to MMVimController.
|
||||
receivedKillTaskMsg = YES;
|
||||
getout(0);
|
||||
} else if (InsertTextMsgID == msgid) {
|
||||
if (![[portMessage components] count]) return;
|
||||
NSString *key = [[NSString alloc]
|
||||
initWithData:[[portMessage components] objectAtIndex:0]
|
||||
encoding:NSUTF8StringEncoding];
|
||||
if (!data) return;
|
||||
NSString *key = [[NSString alloc] initWithData:data
|
||||
encoding:NSUTF8StringEncoding];
|
||||
//NSLog(@"insert text: %@ (hex=%x)", key, [key characterAtIndex:0]);
|
||||
add_to_input_buf((char_u*)[key UTF8String],
|
||||
[key lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
|
||||
@@ -690,8 +815,8 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
|
||||
inputReceived = YES;
|
||||
} else if (KeyDownMsgID == msgid || CmdKeyMsgID == msgid) {
|
||||
if (![[portMessage components] count]) return;
|
||||
const void *bytes = [[[portMessage components] objectAtIndex:0] bytes];
|
||||
if (!data) return;
|
||||
const void *bytes = [data bytes];
|
||||
int mods = *((int*)bytes); bytes += sizeof(int);
|
||||
int len = *((int*)bytes); bytes += sizeof(int);
|
||||
NSString *key = [[NSString alloc] initWithBytes:bytes length:len
|
||||
@@ -703,15 +828,15 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
[key release];
|
||||
inputReceived = YES;
|
||||
} else if (SelectTabMsgID == msgid) {
|
||||
if (![[portMessage components] count]) return;
|
||||
const void *bytes = [[[portMessage components] objectAtIndex:0] bytes];
|
||||
if (!data) return;
|
||||
const void *bytes = [data bytes];
|
||||
int idx = *((int*)bytes) + 1;
|
||||
//NSLog(@"Selecting tab %d", idx);
|
||||
send_tabline_event(idx);
|
||||
inputReceived = YES;
|
||||
} else if (CloseTabMsgID == msgid) {
|
||||
if (![[portMessage components] count]) return;
|
||||
const void *bytes = [[[portMessage components] objectAtIndex:0] bytes];
|
||||
if (!data) return;
|
||||
const void *bytes = [data bytes];
|
||||
int idx = *((int*)bytes) + 1;
|
||||
//NSLog(@"Closing tab %d", idx);
|
||||
send_tabline_menu_event(idx, TABLINE_MENU_CLOSE);
|
||||
@@ -721,8 +846,8 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
send_tabline_menu_event(0, TABLINE_MENU_NEW);
|
||||
inputReceived = YES;
|
||||
} else if (DraggedTabMsgID == msgid) {
|
||||
if (![[portMessage components] count]) return;
|
||||
const void *bytes = [[[portMessage components] objectAtIndex:0] bytes];
|
||||
if (!data) return;
|
||||
const void *bytes = [data bytes];
|
||||
// NOTE! The destination index is 0 based, so do not add 1 to make it 1
|
||||
// based.
|
||||
int idx = *((int*)bytes);
|
||||
@@ -743,8 +868,8 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
tabpage_move(idx);
|
||||
#endif
|
||||
} else if (ScrollWheelMsgID == msgid) {
|
||||
if (![[portMessage components] count]) return;
|
||||
const void *bytes = [[[portMessage components] objectAtIndex:0] bytes];
|
||||
if (!data) return;
|
||||
const void *bytes = [data bytes];
|
||||
|
||||
int row = *((int*)bytes); bytes += sizeof(int);
|
||||
int col = *((int*)bytes); bytes += sizeof(int);
|
||||
@@ -759,8 +884,8 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
gui_send_mouse_event(button, col, row, NO, flags);
|
||||
inputReceived = YES;
|
||||
} else if (MouseDownMsgID == msgid) {
|
||||
if (![[portMessage components] count]) return;
|
||||
const void *bytes = [[[portMessage components] objectAtIndex:0] bytes];
|
||||
if (!data) return;
|
||||
const void *bytes = [data bytes];
|
||||
|
||||
int row = *((int*)bytes); bytes += sizeof(int);
|
||||
int col = *((int*)bytes); bytes += sizeof(int);
|
||||
@@ -775,8 +900,8 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
|
||||
inputReceived = YES;
|
||||
} else if (MouseUpMsgID == msgid) {
|
||||
if (![[portMessage components] count]) return;
|
||||
const void *bytes = [[[portMessage components] objectAtIndex:0] bytes];
|
||||
if (!data) return;
|
||||
const void *bytes = [data bytes];
|
||||
|
||||
int row = *((int*)bytes); bytes += sizeof(int);
|
||||
int col = *((int*)bytes); bytes += sizeof(int);
|
||||
@@ -787,8 +912,8 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
gui_send_mouse_event(MOUSE_RELEASE, col, row, NO, flags);
|
||||
inputReceived = YES;
|
||||
} else if (MouseDraggedMsgID == msgid) {
|
||||
if (![[portMessage components] count]) return;
|
||||
const void *bytes = [[[portMessage components] objectAtIndex:0] bytes];
|
||||
if (!data) return;
|
||||
const void *bytes = [data bytes];
|
||||
|
||||
int row = *((int*)bytes); bytes += sizeof(int);
|
||||
int col = *((int*)bytes); bytes += sizeof(int);
|
||||
@@ -798,21 +923,25 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
|
||||
gui_send_mouse_event(MOUSE_DRAG, col, row, NO, flags);
|
||||
inputReceived = YES;
|
||||
} else if (BrowseForFileReplyMsgID == msgid) {
|
||||
if (![[portMessage components] count]) return;
|
||||
}
|
||||
#if !MM_USE_DO
|
||||
else if (BrowseForFileReplyMsgID == msgid) {
|
||||
if (!data) return;
|
||||
[replyData release];
|
||||
replyData = [[[portMessage components] objectAtIndex:0] copy];
|
||||
} else if (SetTextDimensionsMsgID == msgid) {
|
||||
if (![[portMessage components] count]) return;
|
||||
const void *bytes = [[[portMessage components] objectAtIndex:0] bytes];
|
||||
replyData = [data copy];
|
||||
}
|
||||
#endif
|
||||
else if (SetTextDimensionsMsgID == msgid) {
|
||||
if (!data) return;
|
||||
const void *bytes = [data bytes];
|
||||
int rows = *((int*)bytes); bytes += sizeof(int);
|
||||
int cols = *((int*)bytes); bytes += sizeof(int);
|
||||
|
||||
//NSLog(@"[VimTask] Resizing shell to %dx%d.", cols, rows);
|
||||
gui_resize_shell(cols, rows);
|
||||
} else if (ExecuteMenuMsgID == msgid) {
|
||||
if (![[portMessage components] count]) return;
|
||||
const void *bytes = [[[portMessage components] objectAtIndex:0] bytes];
|
||||
if (!data) return;
|
||||
const void *bytes = [data bytes];
|
||||
int tag = *((int*)bytes); bytes += sizeof(int);
|
||||
|
||||
vimmenu_T *menu = (vimmenu_T*)tag;
|
||||
@@ -821,24 +950,9 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
gui_menu_cb(menu);
|
||||
inputReceived = YES;
|
||||
}
|
||||
} else if (TaskShouldTerminateMsgID == msgid) {
|
||||
int reply = TerminateReplyYesMsgID;
|
||||
buf_T *buf;
|
||||
for (buf = firstbuf; buf != NULL; buf = buf->b_next) {
|
||||
if (bufIsChanged(buf)) {
|
||||
reply = TerminateReplyNoMsgID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//NSLog(@"TaskShouldTerminateMsgID = %s",
|
||||
// reply == TerminateReplyYesMsgID ? "YES" : "NO");
|
||||
|
||||
[NSPortMessage sendMessage:reply withSendPort:[portMessage sendPort]
|
||||
wait:YES];
|
||||
} else if (ScrollbarEventMsgID == msgid) {
|
||||
if (![[portMessage components] count]) return;
|
||||
const void *bytes = [[[portMessage components] objectAtIndex:0] bytes];
|
||||
if (!data) return;
|
||||
const void *bytes = [data bytes];
|
||||
long ident = *((long*)bytes); bytes += sizeof(long);
|
||||
int hitPart = *((int*)bytes); bytes += sizeof(int);
|
||||
float fval = *((float*)bytes); bytes += sizeof(float);
|
||||
@@ -900,18 +1014,13 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
|
||||
inputReceived = YES;
|
||||
}
|
||||
} else if (VimShouldCloseMsgID == msgid) {
|
||||
gui_shell_closed();
|
||||
} else {
|
||||
NSLog(@"WARNING: Unknown message received (msgid=%d)", msgid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@end // MMBackend
|
||||
|
||||
|
||||
|
||||
@implementation MMBackend (Private)
|
||||
|
||||
+ (NSDictionary *)specialKeys
|
||||
{
|
||||
static NSDictionary *specialKeys = nil;
|
||||
@@ -1002,6 +1111,19 @@ static int eventButtonNumberToVimMouseButton(int buttonNumber);
|
||||
[queue addObject:[NSData data]];
|
||||
}
|
||||
|
||||
#if MM_USE_DO
|
||||
- (void)connectionDidDie:(NSNotification *)notification
|
||||
{
|
||||
// If the main connection to MacVim is lost this means that MacVim was
|
||||
// either quit (by the user chosing Quit on the MacVim menu), or it has
|
||||
// crashed. In either case our only option is to quit now.
|
||||
// TODO: Write backup file?
|
||||
|
||||
//NSLog(@"A Vim process lots its connection to MacVim; quitting.");
|
||||
getout(0);
|
||||
}
|
||||
#endif // MM_USE_DO
|
||||
|
||||
@end // MMBackend (Private)
|
||||
|
||||
|
||||
|
||||
@@ -54,6 +54,8 @@
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
//NSLog(@"%@ %s", [self className], _cmd);
|
||||
|
||||
[emptyRowString release];
|
||||
//[paragraphStyle release];
|
||||
[font release];
|
||||
|
||||
@@ -12,15 +12,9 @@
|
||||
|
||||
|
||||
@interface MMTextView : NSTextView {
|
||||
BOOL ownsTextStorage;
|
||||
int tabpageIdx;
|
||||
NSPort *sendPort;
|
||||
BOOL shouldDrawInsertionPoint;
|
||||
}
|
||||
|
||||
- (id)initWithPort:(NSPort *)port frame:(NSRect)frame
|
||||
textContainer:(NSTextContainer *)tc;
|
||||
- (MMTextView *)initWithFrame:(NSRect)frame port:(NSPort *)port;
|
||||
- (void)setShouldDrawInsertionPoint:(BOOL)enable;
|
||||
|
||||
@end
|
||||
|
||||
+21
-76
@@ -10,80 +10,22 @@
|
||||
|
||||
#import "MMTextView.h"
|
||||
#import "MMTextStorage.h"
|
||||
#import "MacVim.h"
|
||||
#import "MMWindowController.h"
|
||||
#import "MMVimController.h"
|
||||
#import "MacVim.h"
|
||||
|
||||
|
||||
|
||||
@interface MMTextView (Private)
|
||||
- (BOOL)convertPoint:(NSPoint)point toRow:(int *)row column:(int *)column;
|
||||
- (void)dispatchKeyEvent:(NSEvent *)event;
|
||||
- (MMVimController *)vimController;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@implementation MMTextView
|
||||
|
||||
- (id)initWithPort:(NSPort *)port frame:(NSRect)frame
|
||||
textContainer:(NSTextContainer *)tc
|
||||
{
|
||||
if ((self = [super initWithFrame:frame textContainer:tc])) {
|
||||
sendPort = [port retain];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (MMTextView *)initWithFrame:(NSRect)frame port:(NSPort *)port
|
||||
{
|
||||
MMTextStorage *ts = [[MMTextStorage alloc] init];
|
||||
NSLayoutManager *lm = [[NSLayoutManager alloc] init];
|
||||
NSTextContainer *tc = [[NSTextContainer alloc] initWithContainerSize:
|
||||
NSMakeSize(1.0e7,1.0e7)];
|
||||
|
||||
[tc setWidthTracksTextView:NO];
|
||||
[tc setHeightTracksTextView:NO];
|
||||
[tc setLineFragmentPadding:0];
|
||||
|
||||
[ts addLayoutManager:lm];
|
||||
[lm addTextContainer:tc];
|
||||
|
||||
[tc release];
|
||||
[lm release];
|
||||
|
||||
// HACK! Where should i get these values from?
|
||||
// TODO: get values from frame
|
||||
[ts setMaxRows:24 columns:80];
|
||||
|
||||
if ((self = [super initWithFrame:frame textContainer:tc])) {
|
||||
ownsTextStorage = YES;
|
||||
//[self setRichText:NO];
|
||||
sendPort = [port retain];
|
||||
} else {
|
||||
ownsTextStorage = NO;
|
||||
[ts release];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
// BUG! The reference count of the text view will never reach 0 unless
|
||||
// release is explicitly called on the text storage; so this code is
|
||||
// meaningless.
|
||||
if (ownsTextStorage) {
|
||||
[[self textContainer] setTextView:nil];
|
||||
[[self textStorage] release];
|
||||
ownsTextStorage = NO;
|
||||
}
|
||||
|
||||
[sendPort release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)setShouldDrawInsertionPoint:(BOOL)enable
|
||||
{
|
||||
shouldDrawInsertionPoint = enable;
|
||||
@@ -122,9 +64,9 @@
|
||||
|
||||
[NSCursor setHiddenUntilMouseMoves:YES];
|
||||
|
||||
[NSPortMessage sendMessage:InsertTextMsgID withSendPort:sendPort
|
||||
data:[string dataUsingEncoding:NSUTF8StringEncoding]
|
||||
wait:NO];
|
||||
[[self vimController] sendMessage:InsertTextMsgID
|
||||
data:[string dataUsingEncoding:NSUTF8StringEncoding]
|
||||
wait:NO];
|
||||
}
|
||||
|
||||
|
||||
@@ -174,8 +116,7 @@
|
||||
[data appendBytes:&len length:sizeof(int)];
|
||||
[data appendBytes:[string UTF8String] length:len];
|
||||
|
||||
[NSPortMessage sendMessage:CmdKeyMsgID withSendPort:sendPort data:data
|
||||
wait:NO];
|
||||
[[self vimController] sendMessage:CmdKeyMsgID data:data wait:NO];
|
||||
|
||||
return YES;
|
||||
}
|
||||
@@ -220,8 +161,7 @@
|
||||
[data appendBytes:&flags length:sizeof(int)];
|
||||
[data appendBytes:&dy length:sizeof(float)];
|
||||
|
||||
[NSPortMessage sendMessage:ScrollWheelMsgID withSendPort:sendPort
|
||||
data:data wait:NO];
|
||||
[[self vimController] sendMessage:ScrollWheelMsgID data:data wait:NO];
|
||||
}
|
||||
|
||||
- (void)mouseDown:(NSEvent *)event
|
||||
@@ -242,8 +182,7 @@
|
||||
[data appendBytes:&flags length:sizeof(int)];
|
||||
[data appendBytes:&count length:sizeof(int)];
|
||||
|
||||
[NSPortMessage sendMessage:MouseDownMsgID withSendPort:sendPort
|
||||
data:data wait:NO];
|
||||
[[self vimController] sendMessage:MouseDownMsgID data:data wait:NO];
|
||||
}
|
||||
|
||||
- (void)rightMouseDown:(NSEvent *)event
|
||||
@@ -270,8 +209,7 @@
|
||||
[data appendBytes:&col length:sizeof(int)];
|
||||
[data appendBytes:&flags length:sizeof(int)];
|
||||
|
||||
[NSPortMessage sendMessage:MouseUpMsgID withSendPort:sendPort
|
||||
data:data wait:NO];
|
||||
[[self vimController] sendMessage:MouseUpMsgID data:data wait:NO];
|
||||
}
|
||||
|
||||
- (void)rightMouseUp:(NSEvent *)event
|
||||
@@ -298,8 +236,7 @@
|
||||
[data appendBytes:&col length:sizeof(int)];
|
||||
[data appendBytes:&flags length:sizeof(int)];
|
||||
|
||||
[NSPortMessage sendMessage:MouseDraggedMsgID withSendPort:sendPort
|
||||
data:data wait:NO];
|
||||
[[self vimController] sendMessage:MouseDraggedMsgID data:data wait:NO];
|
||||
}
|
||||
|
||||
- (void)rightMouseDragged:(NSEvent *)event
|
||||
@@ -393,9 +330,17 @@
|
||||
|
||||
[NSCursor setHiddenUntilMouseMoves:YES];
|
||||
|
||||
[NSPortMessage sendMessage:KeyDownMsgID withSendPort:sendPort data:data
|
||||
wait:NO];
|
||||
[[self vimController] sendMessage:KeyDownMsgID data:data wait:NO];
|
||||
}
|
||||
}
|
||||
|
||||
- (MMVimController *)vimController
|
||||
{
|
||||
id windowController = [[self window] windowController];
|
||||
|
||||
// TODO: Make sure 'windowController' is a MMWindowController before type
|
||||
// casting.
|
||||
return [(MMWindowController*)windowController vimController];
|
||||
}
|
||||
|
||||
@end // MMTextView (Private)
|
||||
|
||||
+17
-2
@@ -9,15 +9,24 @@
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "MacVim.h"
|
||||
|
||||
@class MMWindowController;
|
||||
|
||||
|
||||
|
||||
@interface MMVimController : NSObject {
|
||||
@interface MMVimController : NSObject
|
||||
#if MM_USE_DO
|
||||
<MMFrontendProtocol>
|
||||
#endif
|
||||
{
|
||||
MMWindowController *windowController;
|
||||
#if MM_USE_DO
|
||||
id backendProxy;
|
||||
#else
|
||||
NSPort *sendPort;
|
||||
NSPort *receivePort;
|
||||
#endif
|
||||
NSMutableArray *mainMenuItems;
|
||||
BOOL shouldUpdateMainMenu;
|
||||
//NSMutableArray *popupMenus;
|
||||
@@ -25,9 +34,15 @@
|
||||
NSMutableDictionary *toolbarItemDict;
|
||||
}
|
||||
|
||||
#if MM_USE_DO
|
||||
- (id)initWithBackend:(id)backend;
|
||||
- (id)backendProxy;
|
||||
#else
|
||||
- (id)initWithPort:(NSPort *)port;
|
||||
- (void)windowWillClose:(NSNotification *)notification;
|
||||
- (NSPort *)sendPort;
|
||||
#endif
|
||||
- (void)windowWillClose:(NSNotification *)notification;
|
||||
- (void)sendMessage:(int)msgid data:(NSData *)data wait:(BOOL)wait;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
+100
-23
@@ -10,7 +10,6 @@
|
||||
|
||||
#import "MMVimController.h"
|
||||
#import "MMWindowController.h"
|
||||
#import "MacVim.h"
|
||||
#import "MMAppController.h"
|
||||
#import "MMTextView.h"
|
||||
#import "MMTextStorage.h"
|
||||
@@ -32,6 +31,7 @@ static NSString *DefaultToolbarImageName = @"Attention";
|
||||
- (IBAction)toolbarAction:(id)sender;
|
||||
- (void)addToolbarItemToDictionaryWithTag:(int)tag label:(NSString *)title
|
||||
toolTip:(NSString *)tip icon:(NSString *)icon;
|
||||
- (void)connectionDidDie:(NSNotification *)notification;
|
||||
@end
|
||||
|
||||
|
||||
@@ -67,10 +67,40 @@ static NSMenuItem *findMenuItemWithTagInMenu(NSMenu *root, int tag)
|
||||
|
||||
@implementation MMVimController
|
||||
|
||||
#if MM_USE_DO
|
||||
- (id)initWithBackend:(id)backend
|
||||
#else
|
||||
- (id)initWithPort:(NSPort *)port
|
||||
#endif
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
windowController = [[MMWindowController alloc] initWithPort:port];
|
||||
windowController =
|
||||
[[MMWindowController alloc] initWithVimController:self];
|
||||
#if MM_USE_DO
|
||||
backendProxy = [backend retain];
|
||||
|
||||
NSConnection *connection = [backendProxy connectionForProxy];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(connectionDidDie:)
|
||||
name:NSConnectionDidDieNotification object:connection];
|
||||
#else
|
||||
sendPort = [port retain];
|
||||
|
||||
// Init receive port and send connected message to VimTask
|
||||
receivePort = [NSMachPort new];
|
||||
[receivePort setDelegate:self];
|
||||
|
||||
// Add to the default run loop mode as well as the event tracking mode;
|
||||
// the latter ensures that updates from the VimTask reaches
|
||||
// MMVimController whilst the user resizes a window with the mouse.
|
||||
[[NSRunLoop currentRunLoop] addPort:receivePort
|
||||
forMode:NSDefaultRunLoopMode];
|
||||
[[NSRunLoop currentRunLoop] addPort:receivePort
|
||||
forMode:NSEventTrackingRunLoopMode];
|
||||
|
||||
[NSPortMessage sendMessage:ConnectedMsgID withSendPort:sendPort
|
||||
receivePort:receivePort wait:YES];
|
||||
#endif
|
||||
|
||||
mainMenuItems = [[NSMutableArray alloc] init];
|
||||
|
||||
@@ -90,22 +120,6 @@ static NSMenuItem *findMenuItemWithTagInMenu(NSMenu *root, int tag)
|
||||
name:NSWindowDidBecomeMainNotification
|
||||
object:[windowController window]];
|
||||
|
||||
sendPort = [port retain];
|
||||
|
||||
// Init receive port and send connected message to VimTask
|
||||
receivePort = [NSMachPort new];
|
||||
[receivePort setDelegate:self];
|
||||
|
||||
// Add to the default run loop mode as well as the event tracking mode;
|
||||
// the latter ensures that updates from the VimTask reaches
|
||||
// MMVimController whilst the user resizes a window with the mouse.
|
||||
[[NSRunLoop currentRunLoop] addPort:receivePort
|
||||
forMode:NSDefaultRunLoopMode];
|
||||
[[NSRunLoop currentRunLoop] addPort:receivePort
|
||||
forMode:NSEventTrackingRunLoopMode];
|
||||
|
||||
[NSPortMessage sendMessage:ConnectedMsgID withSendPort:sendPort
|
||||
receivePort:receivePort wait:YES];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -113,24 +127,67 @@ static NSMenuItem *findMenuItemWithTagInMenu(NSMenu *root, int tag)
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
//NSLog(@"%@ %s", [self className], _cmd);
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
|
||||
#if MM_USE_DO
|
||||
[backendProxy release];
|
||||
#else
|
||||
if (sendPort) {
|
||||
// Kill task immediately
|
||||
[NSPortMessage sendMessage:KillTaskMsgID withSendPort:sendPort
|
||||
receivePort:receivePort wait:NO];
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[sendPort release];
|
||||
[receivePort release];
|
||||
#endif
|
||||
|
||||
[toolbarItemDict release];
|
||||
[toolbar release];
|
||||
[mainMenuItems release];
|
||||
[windowController release];
|
||||
[sendPort release];
|
||||
[receivePort release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id)backendProxy
|
||||
{
|
||||
return backendProxy;
|
||||
}
|
||||
|
||||
- (void)sendMessage:(int)msgid data:(NSData *)data wait:(BOOL)wait
|
||||
{
|
||||
#if MM_USE_DO
|
||||
// TODO: Decrease reply/request timeouts if 'wait' is off.
|
||||
[backendProxy processInput:msgid data:data];
|
||||
#else
|
||||
[NSPortMessage sendMessage:msgid withSendPort:sendPort data:data
|
||||
wait:wait];
|
||||
#endif
|
||||
}
|
||||
|
||||
#if MM_USE_DO
|
||||
- (oneway void)processCommandQueue:(in NSArray *)queue
|
||||
{
|
||||
unsigned i, count = [queue count];
|
||||
if (count % 2) {
|
||||
NSLog(@"WARNING: Uneven number of components (%d) in flush queue "
|
||||
"message; ignoring this message.", count);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i += 2) {
|
||||
NSData *value = [queue objectAtIndex:i];
|
||||
NSData *data = [queue objectAtIndex:i+1];
|
||||
|
||||
[self handleMessage:*((int*)[value bytes]) data:data];
|
||||
}
|
||||
}
|
||||
|
||||
#else // MM_USE_DO
|
||||
|
||||
- (NSPort *)sendPort
|
||||
{
|
||||
return sendPort;
|
||||
@@ -138,6 +195,8 @@ static NSMenuItem *findMenuItemWithTagInMenu(NSMenu *root, int tag)
|
||||
|
||||
- (void)handlePortMessage:(NSPortMessage *)portMessage
|
||||
{
|
||||
//NSLog(@"%@ %s %@", [self className], _cmd, portMessage);
|
||||
|
||||
NSArray *components = [portMessage components];
|
||||
unsigned msgid = [portMessage msgid];
|
||||
|
||||
@@ -168,6 +227,7 @@ static NSMenuItem *findMenuItemWithTagInMenu(NSMenu *root, int tag)
|
||||
if (shouldUpdateMainMenu)
|
||||
[self updateMainMenu];
|
||||
}
|
||||
#endif // MM_USE_DO
|
||||
|
||||
- (void)windowWillClose:(NSNotification *)notification
|
||||
{
|
||||
@@ -216,6 +276,8 @@ static NSMenuItem *findMenuItemWithTagInMenu(NSMenu *root, int tag)
|
||||
|
||||
- (void)handleMessage:(int)msgid data:(NSData *)data
|
||||
{
|
||||
//NSLog(@"%@ %s", [self className], _cmd);
|
||||
|
||||
if (OpenVimWindowMsgID == msgid) {
|
||||
const void *bytes = [data bytes];
|
||||
int rows = *((int*)bytes); bytes += sizeof(int);
|
||||
@@ -225,7 +287,9 @@ static NSMenuItem *findMenuItemWithTagInMenu(NSMenu *root, int tag)
|
||||
// cols, rows);
|
||||
|
||||
[windowController openWindowWithRows:rows columns:cols];
|
||||
} else if (TaskExitedMsgID == msgid) {
|
||||
}
|
||||
#if !MM_USE_DO
|
||||
else if (TaskExitedMsgID == msgid) {
|
||||
//NSLog(@"Received task exited message from VimTask; closing window.");
|
||||
|
||||
// Release sendPort immediately to avoid dealloc trying to send a 'kill
|
||||
@@ -237,7 +301,9 @@ static NSMenuItem *findMenuItemWithTagInMenu(NSMenu *root, int tag)
|
||||
|
||||
// HACK! Make sure no menu updating is done, we're about to close.
|
||||
shouldUpdateMainMenu = NO;
|
||||
} else if (BatchDrawMsgID == msgid) {
|
||||
}
|
||||
#endif // !MM_USE_DO
|
||||
else if (BatchDrawMsgID == msgid) {
|
||||
//NSLog(@"Received batch draw message from VimTask.");
|
||||
|
||||
[self performBatchDrawWithData:data];
|
||||
@@ -673,6 +739,7 @@ static NSMenuItem *findMenuItemWithTagInMenu(NSMenu *root, int tag)
|
||||
|
||||
- (void)panelDidEnd:(NSSavePanel *)panel code:(int)code context:(void *)context
|
||||
{
|
||||
#if !MM_USE_DO
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
int ok = (code == NSOKButton);
|
||||
NSString *filename = [panel filename];
|
||||
@@ -690,6 +757,7 @@ static NSMenuItem *findMenuItemWithTagInMenu(NSMenu *root, int tag)
|
||||
}
|
||||
|
||||
[windowController setStatusText:@""];
|
||||
#endif // !MM_USE_DO
|
||||
}
|
||||
|
||||
- (NSMenuItem *)menuItemForTag:(int)tag
|
||||
@@ -801,6 +869,15 @@ static NSMenuItem *findMenuItemWithTagInMenu(NSMenu *root, int tag)
|
||||
[item release];
|
||||
}
|
||||
|
||||
#if MM_USE_DO
|
||||
- (void)connectionDidDie:(NSNotification *)notification
|
||||
{
|
||||
//NSLog(@"A MMVimController lost its connection to the backend; "
|
||||
// "closing the controller.");
|
||||
[windowController close];
|
||||
}
|
||||
#endif // MM_USE_DO
|
||||
|
||||
@end // MMVimController (Private)
|
||||
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
@class PSMTabBarControl;
|
||||
@class MMTextView;
|
||||
@class MMTextStorage;
|
||||
@class MMVimController;
|
||||
|
||||
|
||||
@interface MMWindowController : NSWindowController
|
||||
@@ -20,7 +21,8 @@
|
||||
IBOutlet PSMTabBarControl *tabBarControl;
|
||||
IBOutlet NSTabView *tabView;
|
||||
IBOutlet NSTextField *statusTextField;
|
||||
NSPort *sendPort;
|
||||
|
||||
MMVimController *vimController;
|
||||
BOOL vimTaskSelectedTab;
|
||||
NSTimer *statusTimer;
|
||||
MMTextView *textView;
|
||||
@@ -29,7 +31,8 @@
|
||||
BOOL setupDone;
|
||||
}
|
||||
|
||||
- (id)initWithPort:(NSPort *)port;
|
||||
- (id)initWithVimController:(MMVimController *)controller;
|
||||
- (MMVimController *)vimController;
|
||||
- (MMTextView *)textView;
|
||||
- (MMTextStorage *)textStorage;
|
||||
- (void)openWindowWithRows:(int)rows columns:(int)cols;
|
||||
|
||||
+37
-56
@@ -12,6 +12,7 @@
|
||||
#import <PSMTabBarControl.h>
|
||||
#import "MMTextView.h"
|
||||
#import "MMTextStorage.h"
|
||||
#import "MMVimController.h"
|
||||
#import "MacVim.h"
|
||||
|
||||
|
||||
@@ -93,10 +94,10 @@ NSMutableArray *buildMenuAddress(NSMenu *menu)
|
||||
|
||||
@implementation MMWindowController
|
||||
|
||||
- (id)initWithPort:(NSPort *)port
|
||||
- (id)initWithVimController:(MMVimController *)controller
|
||||
{
|
||||
if ((self = [super initWithWindowNibName:@"VimWindow"])) {
|
||||
sendPort = [port retain];
|
||||
vimController = controller;
|
||||
scrollbars = [[NSMutableArray alloc] init];
|
||||
textStorage = [[MMTextStorage alloc] init];
|
||||
}
|
||||
@@ -106,8 +107,12 @@ NSMutableArray *buildMenuAddress(NSMenu *menu)
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
//NSLog(@"%@ %s", [self className], _cmd);
|
||||
|
||||
// TODO: release tabBarControl and tabView?
|
||||
|
||||
vimController = nil;
|
||||
|
||||
[tabBarControl setDelegate:nil];
|
||||
[[self window] setDelegate:nil];
|
||||
|
||||
@@ -116,11 +121,15 @@ NSMutableArray *buildMenuAddress(NSMenu *menu)
|
||||
[scrollbars release];
|
||||
[textView release];
|
||||
[textStorage release];
|
||||
[sendPort release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (MMVimController *)vimController
|
||||
{
|
||||
return vimController;
|
||||
}
|
||||
|
||||
- (void)windowDidLoad
|
||||
{
|
||||
// Called after window nib file is loaded.
|
||||
@@ -223,39 +232,6 @@ NSMutableArray *buildMenuAddress(NSMenu *menu)
|
||||
|
||||
- (void)openWindowWithRows:(int)rows columns:(int)cols
|
||||
{
|
||||
#if 0
|
||||
// Make sure window nib file is loaded.
|
||||
[self window];
|
||||
|
||||
// Set up text system
|
||||
textStorage = [[MMTextStorage alloc] init];
|
||||
NSLayoutManager *lm = [[NSLayoutManager alloc] init];
|
||||
NSTextContainer *tc = [[NSTextContainer alloc] initWithContainerSize:
|
||||
NSMakeSize(1.0e7,1.0e7)];
|
||||
|
||||
[tc setWidthTracksTextView:NO];
|
||||
[tc setHeightTracksTextView:NO];
|
||||
[tc setLineFragmentPadding:0];
|
||||
|
||||
[textStorage setMaxRows:rows columns:cols];
|
||||
[textStorage addLayoutManager:lm];
|
||||
[lm addTextContainer:tc];
|
||||
//[[lm typesetter] setUsesFontLeading:NO];
|
||||
|
||||
textView = [[MMTextView alloc] initWithPort:sendPort frame:[tabView frame]
|
||||
textContainer:tc];
|
||||
[[self window] makeFirstResponder:textView];
|
||||
|
||||
// Keep track of when the layout has changed.
|
||||
[[textView layoutManager] setDelegate:self];
|
||||
|
||||
// The text storage retains the layout manager which in turn retains the
|
||||
// text container.
|
||||
[tc release];
|
||||
[lm release];
|
||||
|
||||
[self addNewTabViewItem];
|
||||
#else
|
||||
// Setup a complete text system.
|
||||
NSLayoutManager *lm = [[NSLayoutManager alloc] init];
|
||||
NSTextContainer *tc = [[NSTextContainer alloc] initWithContainerSize:
|
||||
@@ -269,8 +245,8 @@ NSMutableArray *buildMenuAddress(NSMenu *menu)
|
||||
[textStorage addLayoutManager:lm];
|
||||
[lm addTextContainer:tc];
|
||||
|
||||
textView = [[MMTextView alloc] initWithPort:sendPort frame:[tabView frame]
|
||||
textContainer:tc];
|
||||
textView = [[MMTextView alloc] initWithFrame:[tabView frame]
|
||||
textContainer:tc];
|
||||
|
||||
[[self window] makeFirstResponder:textView];
|
||||
|
||||
@@ -283,7 +259,6 @@ NSMutableArray *buildMenuAddress(NSMenu *menu)
|
||||
[lm release];
|
||||
|
||||
[self addNewTabViewItem];
|
||||
#endif
|
||||
|
||||
// NOTE! This flag is set once the entire text system is set up.
|
||||
setupDone = YES;
|
||||
@@ -409,7 +384,7 @@ NSMutableArray *buildMenuAddress(NSMenu *menu)
|
||||
|
||||
- (IBAction)addNewTab:(id)sender
|
||||
{
|
||||
[NSPortMessage sendMessage:AddNewTabMsgID withSendPort:sendPort wait:NO];
|
||||
[vimController sendMessage:AddNewTabMsgID data:nil wait:NO];
|
||||
}
|
||||
|
||||
- (IBAction)showTabBar:(id)sender
|
||||
@@ -446,8 +421,7 @@ NSMutableArray *buildMenuAddress(NSMenu *menu)
|
||||
// Propagate the selection message to the VimTask.
|
||||
int idx = [self representedIndexOfTabViewItem:tabViewItem];
|
||||
NSData *data = [NSData dataWithBytes:&idx length:sizeof(int)];
|
||||
[NSPortMessage sendMessage:SelectTabMsgID withSendPort:sendPort
|
||||
data:data wait:YES];
|
||||
[vimController sendMessage:SelectTabMsgID data:data wait:YES];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,8 +434,7 @@ NSMutableArray *buildMenuAddress(NSMenu *menu)
|
||||
int idx = [self representedIndexOfTabViewItem:tabViewItem];
|
||||
//NSLog(@"Closing tab with index %d", idx);
|
||||
NSData *data = [NSData dataWithBytes:&idx length:sizeof(int)];
|
||||
[NSPortMessage sendMessage:CloseTabMsgID withSendPort:sendPort
|
||||
data:data wait:YES];
|
||||
[vimController sendMessage:CloseTabMsgID data:data wait:YES];
|
||||
|
||||
return NO;
|
||||
}
|
||||
@@ -472,8 +445,7 @@ NSMutableArray *buildMenuAddress(NSMenu *menu)
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
[data appendBytes:&idx length:sizeof(int)];
|
||||
|
||||
[NSPortMessage sendMessage:DraggedTabMsgID withSendPort:sendPort
|
||||
data:data wait:YES];
|
||||
[vimController sendMessage:DraggedTabMsgID data:data wait:YES];
|
||||
}
|
||||
|
||||
|
||||
@@ -524,11 +496,24 @@ NSMutableArray *buildMenuAddress(NSMenu *menu)
|
||||
// -- NSWindow delegate ------------------------------------------------------
|
||||
|
||||
|
||||
#if 0
|
||||
- (void)windowWillClose:(NSNotification *)notification
|
||||
- (BOOL)windowShouldClose:(id)sender
|
||||
{
|
||||
[vimController sendMessage:VimShouldCloseMsgID data:nil wait:YES];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)windowWillClose:(NSNotification *)notification
|
||||
{
|
||||
//NSLog(@"%@ %s", [self className], _cmd);
|
||||
|
||||
// NOTE! There is a bug in PSMTabBarControl in that it retains the delegate
|
||||
// (which is the MMWindowController) so reset the delegate here, otherwise
|
||||
// the MMWindowController never gets released resulting in a pretty serious
|
||||
// memory leak.
|
||||
[tabBarControl setDelegate:nil];
|
||||
}
|
||||
|
||||
#if 0
|
||||
- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)proposedFrameSize
|
||||
{
|
||||
//NSLog(@"%s (%.2f,%.2f)", _cmd, proposedFrameSize.width,
|
||||
@@ -725,8 +710,7 @@ NSMutableArray *buildMenuAddress(NSMenu *menu)
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
[data appendBytes:&tag length:sizeof(int)];
|
||||
|
||||
[NSPortMessage sendMessage:ExecuteMenuMsgID withSendPort:sendPort
|
||||
data:data wait:NO];
|
||||
[vimController sendMessage:ExecuteMenuMsgID data:data wait:NO];
|
||||
}
|
||||
|
||||
- (MMScroller *)scrollbarForIdentifier:(long)ident index:(unsigned *)idx
|
||||
@@ -871,8 +855,7 @@ NSMutableArray *buildMenuAddress(NSMenu *menu)
|
||||
[data appendBytes:&hitPart length:sizeof(int)];
|
||||
[data appendBytes:&value length:sizeof(float)];
|
||||
|
||||
[NSPortMessage sendMessage:ScrollbarEventMsgID withSendPort:sendPort
|
||||
data:data wait:YES];
|
||||
[vimController sendMessage:ScrollbarEventMsgID data:data wait:YES];
|
||||
}
|
||||
|
||||
- (void)fitWindowToScrollbars:(id)sender
|
||||
@@ -902,10 +885,8 @@ NSMutableArray *buildMenuAddress(NSMenu *menu)
|
||||
//NSLog(@"Notify Vim that text storage dimensions changed to %dx%d",
|
||||
// dim[0], dim[1]);
|
||||
NSData *data = [NSData dataWithBytes:dim length:2*sizeof(int)];
|
||||
[NSPortMessage sendMessage:SetTextDimensionsMsgID
|
||||
withSendPort:sendPort
|
||||
data:data
|
||||
wait:![textView inLiveResize]];
|
||||
[vimController sendMessage:SetTextDimensionsMsgID data:data
|
||||
wait:![textView inLiveResize]];
|
||||
}
|
||||
|
||||
[tabView setFrame:textViewRect];
|
||||
|
||||
@@ -11,6 +11,30 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
#define MM_USE_DO 1
|
||||
|
||||
|
||||
|
||||
#if MM_USE_DO
|
||||
|
||||
@protocol MMBackendProtocol
|
||||
- (oneway void)processInput:(int)msgid data:(in NSData *)data;
|
||||
- (BOOL)checkForModifiedBuffers;
|
||||
@end
|
||||
|
||||
@protocol MMFrontendProtocol
|
||||
- (oneway void)processCommandQueue:(in NSArray *)queue;
|
||||
@end
|
||||
|
||||
@protocol MMAppProtocol
|
||||
- (byref id <MMFrontendProtocol>)connectBackend:
|
||||
(byref in id <MMBackendProtocol>)backend;
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
enum {
|
||||
CheckinMsgID = 1,
|
||||
ConnectedMsgID,
|
||||
@@ -44,9 +68,11 @@ enum {
|
||||
EnableMenuItemMsgID,
|
||||
ExecuteMenuMsgID,
|
||||
ShowToolbarMsgID,
|
||||
#if !MM_USE_DO
|
||||
TaskShouldTerminateMsgID,
|
||||
TerminateReplyYesMsgID,
|
||||
TerminateReplyNoMsgID,
|
||||
#endif
|
||||
CreateScrollbarMsgID,
|
||||
DestroyScrollbarMsgID,
|
||||
ShowScrollbarMsgID,
|
||||
@@ -54,6 +80,7 @@ enum {
|
||||
SetScrollbarThumbMsgID,
|
||||
ScrollbarEventMsgID,
|
||||
SetFontMsgID,
|
||||
VimShouldCloseMsgID,
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user