From f1caea5d83e4217dc51b2bc833a57cb56ccdc5fe Mon Sep 17 00:00:00 2001 From: Kazuki Sakamoto Date: Thu, 28 Jan 2016 20:54:09 -0800 Subject: [PATCH] Fix channel in GUI --- src/MacVim/MMBackend.h | 7 ++- src/MacVim/MMBackend.m | 113 ++++++++++++++++++++++++--------------- src/MacVim/MacVim.h | 1 - src/MacVim/MacVim.m | 1 - src/MacVim/gui_macvim.m | 22 +++----- src/channel.c | 36 +++---------- src/netbeans.c | 8 --- src/proto/gui_macvim.pro | 4 +- src/proto/netbeans.pro | 1 - 9 files changed, 89 insertions(+), 104 deletions(-) diff --git a/src/MacVim/MMBackend.h b/src/MacVim/MMBackend.h index 4ae028d48a..06b0231ea7 100644 --- a/src/MacVim/MMBackend.h +++ b/src/MacVim/MMBackend.h @@ -56,8 +56,7 @@ extern NSTimeInterval MMBalloonEvalInternalDelay; unsigned numWholeLineChanges; unsigned offsetForDrawDataPrune; BOOL imState; - CFSocketRef netbeansSocket; - CFRunLoopSourceRef netbeansRunLoopSource; + NSMutableDictionary *channelDict; int winposX; int winposY; #ifdef FEAT_BEVAL @@ -157,8 +156,8 @@ extern NSTimeInterval MMBalloonEvalInternalDelay; - (BOOL)imState; - (void)setImState:(BOOL)activated; -- (void)messageFromNetbeans; -- (void)setNetbeansSocket:(int)socket; +- (void)addChannel:(int)idx fileDescriptor:(int)fd; +- (void)removeChannel:(int)idx; #ifdef FEAT_BEVAL - (void)setLastToolTip:(NSString *)toolTip; diff --git a/src/MacVim/MMBackend.m b/src/MacVim/MMBackend.m index 9dbeceb28d..6e289c8967 100644 --- a/src/MacVim/MMBackend.m +++ b/src/MacVim/MMBackend.m @@ -163,6 +163,13 @@ extern GuiFont gui_mch_retain_font(GuiFont font); @end +@interface MMChannel : NSObject { + CFSocketRef socket; + CFRunLoopSourceRef runLoopSource; +} + +- (id)initWithIndex:(int)idx fileDescriptor:(int)fd; +@end @interface MMBackend (Private) @@ -234,6 +241,7 @@ extern GuiFont gui_mch_retain_font(GuiFont font); connectionNameDict = [[NSMutableDictionary alloc] init]; clientProxyDict = [[NSMutableDictionary alloc] init]; serverReplyDict = [[NSMutableDictionary alloc] init]; + channelDict = [[NSMutableDictionary alloc] init]; NSBundle *mainBundle = [NSBundle mainBundle]; NSString *path = [mainBundle pathForResource:@"Colors" ofType:@"plist"]; @@ -265,6 +273,7 @@ extern GuiFont gui_mch_retain_font(GuiFont font); gui_mch_free_font(oldWideFont); oldWideFont = NOFONT; [blinkTimer release]; blinkTimer = nil; [alternateServerName release]; alternateServerName = nil; + [channelDict release]; channelDict = nil; [serverReplyDict release]; serverReplyDict = nil; [clientProxyDict release]; clientProxyDict = nil; [connectionNameDict release]; connectionNameDict = nil; @@ -1675,49 +1684,21 @@ extern GuiFont gui_mch_retain_font(GuiFont font); [self flushQueue:YES]; } -static void netbeansReadCallback(CFSocketRef s, - CFSocketCallBackType callbackType, - CFDataRef address, - const void *data, - void *info) +- (void)addChannel:(int)idx fileDescriptor:(int)fd { - // NetBeans socket is readable. - [[MMBackend sharedInstance] messageFromNetbeans]; -} - -- (void)messageFromNetbeans -{ - [inputQueue addObject:[NSNumber numberWithInt:NetBeansMsgID]]; - [inputQueue addObject:[NSNull null]]; -} - -- (void)setNetbeansSocket:(int)socket -{ - if (netbeansSocket) { - CFRelease(netbeansSocket); - netbeansSocket = NULL; - } - - if (netbeansRunLoopSource) { - CFRunLoopSourceInvalidate(netbeansRunLoopSource); - netbeansRunLoopSource = NULL; - } - - if (socket == -1) + if (fd == -1) return; - // Tell CFRunLoop that we are interested in NetBeans socket input. - netbeansSocket = CFSocketCreateWithNative(kCFAllocatorDefault, - socket, - kCFSocketReadCallBack, - &netbeansReadCallback, - NULL); - netbeansRunLoopSource = CFSocketCreateRunLoopSource(NULL, - netbeansSocket, - 0); - CFRunLoopAddSource(CFRunLoopGetCurrent(), - netbeansRunLoopSource, - kCFRunLoopCommonModes); + NSNumber *key = [NSNumber numberWithInt:idx]; + MMChannel *channel = + [[[MMChannel alloc] initWithIndex:idx fileDescriptor:fd] autorelease]; + [channelDict setObject:channel forKey:key]; +} + +- (void)removeChannel:(int)idx +{ + NSNumber *key = [NSNumber numberWithInt:idx]; + [channelDict removeObjectForKey:key]; } #ifdef FEAT_BEVAL @@ -2075,10 +2056,6 @@ static void netbeansReadCallback(CFSocketRef s, [self handleOpenWithArguments:[NSDictionary dictionaryWithData:data]]; } else if (FindReplaceMsgID == msgid) { [self handleFindReplace:[NSDictionary dictionaryWithData:data]]; - } else if (NetBeansMsgID == msgid) { -#ifdef FEAT_NETBEANS_INTG - netbeans_read(); -#endif } else if (ZoomMsgID == msgid) { if (!data) return; const void *bytes = [data bytes]; @@ -3435,3 +3412,51 @@ static id evalExprCocoa(NSString * expr, NSString ** errstr) } @end // NSString (VimStrings) + + + +@implementation MMChannel + +- (void)dealloc +{ + CFRunLoopSourceInvalidate(runLoopSource); + CFRelease(runLoopSource); + CFRelease(socket); + [super dealloc]; +} + +static void socketReadCallback(CFSocketRef s, + CFSocketCallBackType callbackType, + CFDataRef address, + const void *data, + void *info) +{ +#ifdef FEAT_CHANNEL + int idx = (int)(intptr_t)info; + channel_read(idx); +#endif +} + +- (id)initWithIndex:(int)idx fileDescriptor:(int)fd +{ + self = [super init]; + if (!self) return nil; + + // Tell CFRunLoop that we are interested in channel socket input. + CFSocketContext ctx = {0, (void *)(intptr_t)idx, NULL, NULL, NULL}; + socket = CFSocketCreateWithNative(kCFAllocatorDefault, + fd, + kCFSocketReadCallBack, + &socketReadCallback, + &ctx); + runLoopSource = CFSocketCreateRunLoopSource(NULL, + socket, + 0); + CFRunLoopAddSource(CFRunLoopGetCurrent(), + runLoopSource, + kCFRunLoopCommonModes); + + return self; +} + +@end diff --git a/src/MacVim/MacVim.h b/src/MacVim/MacVim.h index 0865efed51..c20c164aa5 100644 --- a/src/MacVim/MacVim.h +++ b/src/MacVim/MacVim.h @@ -191,7 +191,6 @@ enum { DeactivatedImMsgID, BrowseForFileMsgID, ShowDialogMsgID, - NetBeansMsgID, SetMarkedTextMsgID, ZoomMsgID, SetWindowPositionMsgID, diff --git a/src/MacVim/MacVim.m b/src/MacVim/MacVim.m index 7b96e31101..b86ce869b2 100644 --- a/src/MacVim/MacVim.m +++ b/src/MacVim/MacVim.m @@ -90,7 +90,6 @@ char *MessageStrings[] = "DeactivatedImMsgID", "BrowseForFileMsgID", "ShowDialogMsgID", - "NetBeansMsgID", "SetMarkedTextMsgID", "ZoomMsgID", "SetWindowPositionMsgID", diff --git a/src/MacVim/gui_macvim.m b/src/MacVim/gui_macvim.m index f2406e90d2..5206d461c8 100644 --- a/src/MacVim/gui_macvim.m +++ b/src/MacVim/gui_macvim.m @@ -2239,18 +2239,19 @@ static int vimModMaskToEventModifierFlags(int mods) -// -- NetBeans Support ------------------------------------------------------ +// -- Channel Support ------------------------------------------------------ -#ifdef FEAT_NETBEANS_INTG - -/* Set NetBeans socket to CFRunLoop */ void -gui_macvim_set_netbeans_socket(int socket) +gui_macvim_add_channel(int idx, int fd) { - [[MMBackend sharedInstance] setNetbeansSocket:socket]; + [[MMBackend sharedInstance] addChannel:idx fileDescriptor:fd]; } -#endif // FEAT_NETBEANS_INTG + void +gui_macvim_remove_channel(int idx) +{ + [[MMBackend sharedInstance] removeChannel:idx]; +} @@ -2309,13 +2310,6 @@ gui_mch_destroy_sign(void *sign) [imgName release]; } -# ifdef FEAT_NETBEANS_INTG - void -netbeans_draw_multisign_indicator(int row) -{ -} -# endif // FEAT_NETBEANS_INTG - #endif // FEAT_SIGN_ICONS diff --git a/src/channel.c b/src/channel.c index 8ec2c1bf89..2c6d50ac13 100644 --- a/src/channel.c +++ b/src/channel.c @@ -95,7 +95,7 @@ typedef struct { int ch_inputHandler; /* simply ret.value of WSAAsyncSelect() */ #endif #ifdef FEAT_GUI_MACVIM - int ch_inputHandler; + int ch_inputHandler; #endif void (*ch_close_cb)(void); /* callback for when channel is closed */ @@ -155,6 +155,9 @@ add_channel(void) #ifdef FEAT_GUI_W32 channels[channel_count].ch_inputHandler = -1; #endif +#ifdef FEAT_GUI_MACVIM + channels[channel_count].ch_inputHandler = -1; +#endif return channel_count++; } @@ -183,22 +186,6 @@ messageFromNetbeans(gpointer clientData, } #endif -#ifdef FEAT_GUI_MACVIM - static int -sock_select(int s) -{ - fd_set readset; - struct timeval timeout; - - FD_ZERO(&readset); - FD_SET(s, &readset); - timeout.tv_sec = 0; - timeout.tv_usec = 0; - - return select(s + 1, &readset, NULL, NULL, &timeout); -} -#endif /* FEAT_GUI_MACVIM */ - static void channel_gui_register(int idx) { @@ -244,9 +231,7 @@ channel_gui_register(int idx) */ if (channel->ch_inputHandler == -1) { channel->ch_inputHandler = 0; -# ifdef FEAT_NETBEANS_INTG - gui_macvim_set_netbeans_socket(channel->ch_fd); -# endif + gui_macvim_add_channel(idx, channel->ch_fd); } # endif # endif @@ -297,9 +282,7 @@ channel_gui_unregister(int idx) # ifdef FEAT_GUI_MACVIM if (channel->ch_inputHandler == 0) { -# ifdef FEAT_NETBEANS_INTG - gui_macvim_set_netbeans_socket(-1); -# endif + gui_macvim_remove_channel(idx); channel->ch_inputHandler = -1; } # endif @@ -812,13 +795,6 @@ channel_read(int idx) return; } -#ifdef FEAT_GUI_MACVIM - /* It may happen that socket is not readable because socket has been already - * read by timing of CFRunLoop callback. So check socket using select. */ - if (sock_select(channel->ch_fd) <= 0) - return; -#endif - /* Allocate a buffer to read into. */ if (buf == NULL) { diff --git a/src/netbeans.c b/src/netbeans.c index 2e7890d95e..f080377a8f 100644 --- a/src/netbeans.c +++ b/src/netbeans.c @@ -427,14 +427,6 @@ netbeans_parse_messages(void) } } -/* TODO: remove */ - void -netbeans_read() -{ - if (nb_channel_idx >= 0) - channel_read(nb_channel_idx); -} - /* * Handle one NUL terminated command. * diff --git a/src/proto/gui_macvim.pro b/src/proto/gui_macvim.pro index 7281dd102d..ff6a6072c0 100644 --- a/src/proto/gui_macvim.pro +++ b/src/proto/gui_macvim.pro @@ -228,7 +228,9 @@ gui_mch_replace_dialog(exarg_T *eap); im_set_control(int enable); void -gui_macvim_set_netbeans_socket(int socket); +gui_macvim_add_channel(int idx, int fd); + void +gui_macvim_remove_channel(int idx); void gui_mch_drawsign(int row, int col, int typenr); diff --git a/src/proto/netbeans.pro b/src/proto/netbeans.pro index b01bf02ed1..2df71a11af 100644 --- a/src/proto/netbeans.pro +++ b/src/proto/netbeans.pro @@ -1,6 +1,5 @@ /* netbeans.c */ void netbeans_parse_messages(void); -void netbeans_read(void); int isNetbeansBuffer(buf_T *bufp); int isNetbeansModified(buf_T *bufp); void netbeans_end(void);