From 7c3e21803566f936bb38d8a533d92bfdfc1bb444 Mon Sep 17 00:00:00 2001 From: Kazuki Sakamoto Date: Fri, 26 Jun 2009 06:32:14 +0900 Subject: [PATCH] Add NetBeans support --- src/MacVim/MMBackend.h | 5 +++ src/MacVim/MMBackend.m | 49 +++++++++++++++++++++++++++ src/MacVim/MacVim.h | 1 + src/MacVim/MacVim.m | 1 + src/MacVim/gui_macvim.m | 28 ++++++++++++++++ src/feature.h | 5 +-- src/netbeans.c | 72 +++++++++++++++++++++++++++++++++++++--- src/proto/gui_macvim.pro | 3 ++ src/proto/netbeans.pro | 1 + 9 files changed, 158 insertions(+), 7 deletions(-) diff --git a/src/MacVim/MMBackend.h b/src/MacVim/MMBackend.h index 3fa4c9633f..d26d0d0842 100644 --- a/src/MacVim/MMBackend.h +++ b/src/MacVim/MMBackend.h @@ -50,6 +50,8 @@ unsigned numWholeLineChanges; unsigned offsetForDrawDataPrune; BOOL imState; + CFSocketRef netbeansSocket; + CFRunLoopSourceRef netbeansRunLoopSource; } + (MMBackend *)sharedInstance; @@ -135,6 +137,9 @@ - (BOOL)imState; - (void)setImState:(BOOL)activated; +- (void)messageFromNetbeans; +- (void)setNetbeansSocket:(int)socket; + @end diff --git a/src/MacVim/MMBackend.m b/src/MacVim/MMBackend.m index d3b3fea8a0..4bd176402c 100644 --- a/src/MacVim/MMBackend.m +++ b/src/MacVim/MMBackend.m @@ -1472,6 +1472,51 @@ extern GuiFont gui_mch_retain_font(GuiFont font); imState = activated; } +static void netbeansReadCallback(CFSocketRef s, + CFSocketCallBackType callbackType, + CFDataRef address, + const void *data, + void *info) +{ + // 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) + 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); +} + @end // MMBackend @@ -1798,6 +1843,10 @@ extern GuiFont gui_mch_retain_font(GuiFont font); [self setImState:YES]; } else if (DeactivatedImMsgID == msgid) { [self setImState:NO]; + } else if (NetBeansMsgID == msgid) { +#ifdef FEAT_NETBEANS_INTG + messageFromNetbeansMacVim(); +#endif } else { NSLog(@"WARNING: Unknown message received (msgid=%d)", msgid); } diff --git a/src/MacVim/MacVim.h b/src/MacVim/MacVim.h index 359803d0d5..895b4b98ad 100644 --- a/src/MacVim/MacVim.h +++ b/src/MacVim/MacVim.h @@ -177,6 +177,7 @@ enum { DeactivatedImMsgID, BrowseForFileMsgID, ShowDialogMsgID, + NetBeansMsgID, LastMsgID // NOTE: MUST BE LAST MESSAGE IN ENUM! }; diff --git a/src/MacVim/MacVim.m b/src/MacVim/MacVim.m index a7c586ba8b..058ce663d4 100644 --- a/src/MacVim/MacVim.m +++ b/src/MacVim/MacVim.m @@ -92,6 +92,7 @@ char *MessageStrings[] = "DeactivatedImMsgID", "BrowseForFileMsgID", "ShowDialogMsgID", + "NetBeansMsgID", "END OF MESSAGE IDs" // NOTE: Must be last! }; diff --git a/src/MacVim/gui_macvim.m b/src/MacVim/gui_macvim.m index fb0f6c32e5..91ad7855de 100644 --- a/src/MacVim/gui_macvim.m +++ b/src/MacVim/gui_macvim.m @@ -74,6 +74,19 @@ gui_mch_prepare(int *argc, char **argv) break; } } + +#ifdef FEAT_NETBEANS_INTG + for (i = 0; i < *argc; ++i) { + if (strncmp(argv[i], "-nb", 3) == 0) { + usingNetbeans++; + netbeansArg = argv[i]; + --*argc; + if (*argc > i) + mch_memmove(&argv[i], &argv[i+1], (*argc-i) * sizeof(char*)); + break; + } + } +#endif } @@ -2180,3 +2193,18 @@ static int vimModMaskToEventModifierFlags(int mods) return flags; } + + + +// -- NetBeans Support ------------------------------------------------------ + +#ifdef FEAT_NETBEANS_INTG + +/* Set NetBeans socket to CFRunLoop */ + void +gui_macvim_set_netbeans_socket(int socket) +{ + [[MMBackend sharedInstance] setNetbeansSocket:socket]; +} + +#endif // FEAT_NETBEANS_INTG diff --git a/src/feature.h b/src/feature.h index 1854b67d47..953821aa81 100644 --- a/src/feature.h +++ b/src/feature.h @@ -1200,10 +1200,11 @@ #endif /* - * The Netbeans features currently only work with Motif and GTK and Win32. + * The Netbeans features currently only work with Motif, GTK, Win32 and MacVim. * It also requires +listcmds and +eval. */ -#if ((!defined(FEAT_GUI_MOTIF) && !defined(FEAT_GUI_GTK) && !defined(FEAT_GUI_W32)) \ +#if ((!defined(FEAT_GUI_MOTIF) && !defined(FEAT_GUI_GTK) \ + && !defined(FEAT_GUI_W32) && !defined(FEAT_GUI_MACVIM)) \ || !defined(FEAT_LISTCMDS) || !defined(FEAT_EVAL)) \ && defined(FEAT_NETBEANS_INTG) # undef FEAT_NETBEANS_INTG diff --git a/src/netbeans.c b/src/netbeans.c index fe3a70c39f..47ca2fa2b2 100644 --- a/src/netbeans.c +++ b/src/netbeans.c @@ -118,6 +118,10 @@ static void netbeans_gtk_connect __ARGS((void)); #ifdef FEAT_GUI_W32 static void netbeans_w32_connect __ARGS((void)); #endif +#ifdef FEAT_GUI_MACVIM +static void netbeans_macvim_connect __ARGS((void)); +static int sock_select(int s); +#endif static int dosetvisible = FALSE; @@ -225,6 +229,50 @@ netbeans_disconnect(void) } #endif /* FEAT_GUI_W32 */ +#if defined(FEAT_GUI_MACVIM) || defined(PROTO) + static void +netbeans_macvim_connect(void) +{ + netbeans_connect(); + if (sd > 0) + { + /* + * Tell Core Foundation we are interested in being called when there + * is input on the editor connection socket + */ + gui_macvim_set_netbeans_socket(sd); + } +} + + static void +netbeans_disconnect(void) +{ + if (sd != -1) + { + sd = -1; + gui_macvim_set_netbeans_socket(sd); + } + haveConnection = FALSE; +# ifdef FEAT_BEVAL + bevalServers &= ~BEVAL_NETBEANS; +# endif +} + + 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 */ + #define NB_DEF_HOST "localhost" #define NB_DEF_ADDR "3219" #define NB_DEF_PASS "changeme" @@ -705,19 +753,22 @@ netbeans_parse_messages(void) /* Use this one when generating prototypes, the others are static. */ void messageFromNetbeansW32() -#else -# ifdef FEAT_GUI_MOTIF +#endif +#ifdef FEAT_GUI_MOTIF static void messageFromNetbeans(XtPointer clientData UNUSED, int *unused1 UNUSED, XtInputId *unused2 UNUSED) -# endif -# ifdef FEAT_GUI_GTK +#endif +#ifdef FEAT_GUI_GTK static void messageFromNetbeans(gpointer clientData UNUSED, gint unused1 UNUSED, GdkInputCondition unused2 UNUSED) -# endif +#endif +#if defined(FEAT_GUI_MACVIM) || defined(PROTO) + void +messageFromNetbeansMacVim() #endif { static char_u *buf = NULL; @@ -733,6 +784,13 @@ messageFromNetbeans(gpointer clientData UNUSED, 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(sd) <= 0) + return; +#endif + #ifndef FEAT_GUI_GTK ++level; /* recursion guard; this will be called from the X event loop */ #endif @@ -2806,6 +2864,10 @@ netbeans_startup_done(void) # else # ifdef FEAT_GUI_W32 netbeans_w32_connect(); +# else +# ifdef FEAT_GUI_MACVIM + netbeans_macvim_connect(); +# endif # endif # endif #endif diff --git a/src/proto/gui_macvim.pro b/src/proto/gui_macvim.pro index d6a7a13bc4..95abf9947e 100644 --- a/src/proto/gui_macvim.pro +++ b/src/proto/gui_macvim.pro @@ -216,3 +216,6 @@ gui_mch_find_dialog(exarg_T *eap); gui_mch_replace_dialog(exarg_T *eap); void im_set_control(int enable); + + void +gui_macvim_set_netbeans_socket(int socket); diff --git a/src/proto/netbeans.pro b/src/proto/netbeans.pro index bb1a1b5213..0bf469c1e4 100644 --- a/src/proto/netbeans.pro +++ b/src/proto/netbeans.pro @@ -1,6 +1,7 @@ /* netbeans.c */ void netbeans_parse_messages __ARGS((void)); void messageFromNetbeansW32 __ARGS((void)); +void messageFromNetbeansMacVim __ARGS((void)); int isNetbeansBuffer __ARGS((buf_T *bufp)); int isNetbeansModified __ARGS((buf_T *bufp)); void netbeans_end __ARGS((void));