Karsten Hopp d250f9
To: vim_dev@googlegroups.com
Karsten Hopp d250f9
Subject: Patch 7.4.866
Karsten Hopp d250f9
Fcc: outbox
Karsten Hopp d250f9
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp d250f9
Mime-Version: 1.0
Karsten Hopp d250f9
Content-Type: text/plain; charset=UTF-8
Karsten Hopp d250f9
Content-Transfer-Encoding: 8bit
Karsten Hopp d250f9
------------
Karsten Hopp d250f9
Karsten Hopp d250f9
Patch 7.4.866
Karsten Hopp d250f9
Problem:    Crash when changing the 'tags' option from a remote command.
Karsten Hopp d250f9
            (Benjamin Fritz)
Karsten Hopp d250f9
Solution:   Instead of executing messages immediately, use a queue, like for
Karsten Hopp d250f9
            netbeans. (James Kolb)
Karsten Hopp d250f9
Files:      src/ex_docmd.c, src/getchar.c, src/gui_gtk_x11.c, src/gui_w48.c,
Karsten Hopp d250f9
            src/gui_x11.c, src/if_xcmdsrv.c, src/misc2.c, src/os_unix.c,
Karsten Hopp d250f9
            src/proto/if_xcmdsrv.pro, src/proto/misc2.pro, src/macros.h
Karsten Hopp d250f9
Karsten Hopp d250f9
Karsten Hopp d250f9
*** ../vim-7.4.865/src/ex_docmd.c	2015-09-09 21:10:34.334602633 +0200
Karsten Hopp d250f9
--- src/ex_docmd.c	2015-09-15 13:27:17.534755748 +0200
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 9033,9043 ****
Karsten Hopp d250f9
      {
Karsten Hopp d250f9
  	ui_delay(msec - done > 1000L ? 1000L : msec - done, TRUE);
Karsten Hopp d250f9
  	ui_breakcheck();
Karsten Hopp d250f9
! #ifdef FEAT_NETBEANS_INTG
Karsten Hopp d250f9
! 	/* Process the netbeans messages that may have been received in the
Karsten Hopp d250f9
! 	 * call to ui_breakcheck() when the GUI is in use. This may occur when
Karsten Hopp d250f9
! 	 * running a test case. */
Karsten Hopp d250f9
! 	netbeans_parse_messages();
Karsten Hopp d250f9
  #endif
Karsten Hopp d250f9
      }
Karsten Hopp d250f9
  }
Karsten Hopp d250f9
--- 9033,9043 ----
Karsten Hopp d250f9
      {
Karsten Hopp d250f9
  	ui_delay(msec - done > 1000L ? 1000L : msec - done, TRUE);
Karsten Hopp d250f9
  	ui_breakcheck();
Karsten Hopp d250f9
! #ifdef MESSAGE_QUEUE
Karsten Hopp d250f9
! 	/* Process the netbeans and clientserver messages that may have been
Karsten Hopp d250f9
! 	 * received in the call to ui_breakcheck() when the GUI is in use. This
Karsten Hopp d250f9
! 	 * may occur when running a test case. */
Karsten Hopp d250f9
! 	parse_queued_messages();
Karsten Hopp d250f9
  #endif
Karsten Hopp d250f9
      }
Karsten Hopp d250f9
  }
Karsten Hopp d250f9
*** ../vim-7.4.865/src/getchar.c	2015-07-10 17:19:25.024620239 +0200
Karsten Hopp d250f9
--- src/getchar.c	2015-09-15 13:27:23.318695538 +0200
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 3034,3042 ****
Karsten Hopp d250f9
  	    )
Karsten Hopp d250f9
      {
Karsten Hopp d250f9
  
Karsten Hopp d250f9
! #if defined(FEAT_NETBEANS_INTG)
Karsten Hopp d250f9
! 	/* Process the queued netbeans messages. */
Karsten Hopp d250f9
! 	netbeans_parse_messages();
Karsten Hopp d250f9
  #endif
Karsten Hopp d250f9
  
Karsten Hopp d250f9
  	if (got_int || (script_char = getc(scriptin[curscript])) < 0)
Karsten Hopp d250f9
--- 3034,3041 ----
Karsten Hopp d250f9
  	    )
Karsten Hopp d250f9
      {
Karsten Hopp d250f9
  
Karsten Hopp d250f9
! #ifdef MESSAGE_QUEUE
Karsten Hopp d250f9
! 	parse_queued_messages();
Karsten Hopp d250f9
  #endif
Karsten Hopp d250f9
  
Karsten Hopp d250f9
  	if (got_int || (script_char = getc(scriptin[curscript])) < 0)
Karsten Hopp d250f9
*** ../vim-7.4.865/src/gui_gtk_x11.c	2015-09-08 20:00:17.531627716 +0200
Karsten Hopp d250f9
--- src/gui_gtk_x11.c	2015-09-15 13:27:27.514651858 +0200
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 650,656 ****
Karsten Hopp d250f9
  	xev.xproperty.atom = commProperty;
Karsten Hopp d250f9
  	xev.xproperty.window = commWindow;
Karsten Hopp d250f9
  	xev.xproperty.state = PropertyNewValue;
Karsten Hopp d250f9
! 	serverEventProc(GDK_WINDOW_XDISPLAY(widget->window), &xev);
Karsten Hopp d250f9
      }
Karsten Hopp d250f9
      return FALSE;
Karsten Hopp d250f9
  }
Karsten Hopp d250f9
--- 650,656 ----
Karsten Hopp d250f9
  	xev.xproperty.atom = commProperty;
Karsten Hopp d250f9
  	xev.xproperty.window = commWindow;
Karsten Hopp d250f9
  	xev.xproperty.state = PropertyNewValue;
Karsten Hopp d250f9
! 	serverEventProc(GDK_WINDOW_XDISPLAY(widget->window), &xev, 0);
Karsten Hopp d250f9
      }
Karsten Hopp d250f9
      return FALSE;
Karsten Hopp d250f9
  }
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 5476,5484 ****
Karsten Hopp d250f9
  	    focus = gui.in_focus;
Karsten Hopp d250f9
  	}
Karsten Hopp d250f9
  
Karsten Hopp d250f9
! #if defined(FEAT_NETBEANS_INTG)
Karsten Hopp d250f9
! 	/* Process any queued netbeans messages. */
Karsten Hopp d250f9
! 	netbeans_parse_messages();
Karsten Hopp d250f9
  #endif
Karsten Hopp d250f9
  
Karsten Hopp d250f9
  	/*
Karsten Hopp d250f9
--- 5476,5483 ----
Karsten Hopp d250f9
  	    focus = gui.in_focus;
Karsten Hopp d250f9
  	}
Karsten Hopp d250f9
  
Karsten Hopp d250f9
! #ifdef MESSAGE_QUEUE
Karsten Hopp d250f9
! 	parse_queued_messages();
Karsten Hopp d250f9
  #endif
Karsten Hopp d250f9
  
Karsten Hopp d250f9
  	/*
Karsten Hopp d250f9
*** ../vim-7.4.865/src/gui_w48.c	2015-06-09 19:14:18.773373964 +0200
Karsten Hopp d250f9
--- src/gui_w48.c	2015-09-15 13:27:31.402611385 +0200
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 2016,2024 ****
Karsten Hopp d250f9
  	    s_need_activate = FALSE;
Karsten Hopp d250f9
  	}
Karsten Hopp d250f9
  
Karsten Hopp d250f9
! #ifdef FEAT_NETBEANS_INTG
Karsten Hopp d250f9
! 	/* Process the queued netbeans messages. */
Karsten Hopp d250f9
! 	netbeans_parse_messages();
Karsten Hopp d250f9
  #endif
Karsten Hopp d250f9
  
Karsten Hopp d250f9
  	/*
Karsten Hopp d250f9
--- 2016,2023 ----
Karsten Hopp d250f9
  	    s_need_activate = FALSE;
Karsten Hopp d250f9
  	}
Karsten Hopp d250f9
  
Karsten Hopp d250f9
! #ifdef MESSAGE_QUEUE
Karsten Hopp d250f9
! 	parse_queued_messages();
Karsten Hopp d250f9
  #endif
Karsten Hopp d250f9
  
Karsten Hopp d250f9
  	/*
Karsten Hopp d250f9
*** ../vim-7.4.865/src/gui_x11.c	2013-07-14 15:01:56.000000000 +0200
Karsten Hopp d250f9
--- src/gui_x11.c	2015-09-15 13:27:35.482568913 +0200
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 2895,2903 ****
Karsten Hopp d250f9
  	    focus = gui.in_focus;
Karsten Hopp d250f9
  	}
Karsten Hopp d250f9
  
Karsten Hopp d250f9
! #if defined(FEAT_NETBEANS_INTG)
Karsten Hopp d250f9
! 	/* Process any queued netbeans messages. */
Karsten Hopp d250f9
! 	netbeans_parse_messages();
Karsten Hopp d250f9
  #endif
Karsten Hopp d250f9
  
Karsten Hopp d250f9
  	/*
Karsten Hopp d250f9
--- 2895,2902 ----
Karsten Hopp d250f9
  	    focus = gui.in_focus;
Karsten Hopp d250f9
  	}
Karsten Hopp d250f9
  
Karsten Hopp d250f9
! #ifdef MESSAGE_QUEUE
Karsten Hopp d250f9
! 	parse_queued_messages();
Karsten Hopp d250f9
  #endif
Karsten Hopp d250f9
  
Karsten Hopp d250f9
  	/*
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 3199,3205 ****
Karsten Hopp d250f9
      if (e->type == PropertyNotify && e->window == commWindow
Karsten Hopp d250f9
  	    && e->atom == commProperty &&  e->state == PropertyNewValue)
Karsten Hopp d250f9
      {
Karsten Hopp d250f9
! 	serverEventProc(gui.dpy, event);
Karsten Hopp d250f9
      }
Karsten Hopp d250f9
  }
Karsten Hopp d250f9
  #endif
Karsten Hopp d250f9
--- 3198,3204 ----
Karsten Hopp d250f9
      if (e->type == PropertyNotify && e->window == commWindow
Karsten Hopp d250f9
  	    && e->atom == commProperty &&  e->state == PropertyNewValue)
Karsten Hopp d250f9
      {
Karsten Hopp d250f9
! 	serverEventProc(gui.dpy, event, 0);
Karsten Hopp d250f9
      }
Karsten Hopp d250f9
  }
Karsten Hopp d250f9
  #endif
Karsten Hopp d250f9
*** ../vim-7.4.865/src/if_xcmdsrv.c	2015-08-11 19:13:55.138175689 +0200
Karsten Hopp d250f9
--- src/if_xcmdsrv.c	2015-09-15 14:01:47.597081931 +0200
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 169,174 ****
Karsten Hopp d250f9
--- 169,187 ----
Karsten Hopp d250f9
  
Karsten Hopp d250f9
  typedef int (*EndCond) __ARGS((void *));
Karsten Hopp d250f9
  
Karsten Hopp d250f9
+ struct x_cmdqueue
Karsten Hopp d250f9
+ {
Karsten Hopp d250f9
+     char_u		*propInfo;
Karsten Hopp d250f9
+     int			len;
Karsten Hopp d250f9
+     struct x_cmdqueue	*next;
Karsten Hopp d250f9
+     struct x_cmdqueue	*prev;
Karsten Hopp d250f9
+ };
Karsten Hopp d250f9
+ 
Karsten Hopp d250f9
+ typedef struct x_cmdqueue x_queue_T;
Karsten Hopp d250f9
+ 
Karsten Hopp d250f9
+ /* dummy node, header for circular queue */
Karsten Hopp d250f9
+ static x_queue_T head = {NULL, 0, NULL, NULL};
Karsten Hopp d250f9
+ 
Karsten Hopp d250f9
  /*
Karsten Hopp d250f9
   * Forward declarations for procedures defined later in this file:
Karsten Hopp d250f9
   */
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 186,191 ****
Karsten Hopp d250f9
--- 199,206 ----
Karsten Hopp d250f9
  static int	AppendPropCarefully __ARGS((Display *display, Window window, Atom property, char_u *value, int length));
Karsten Hopp d250f9
  static int	x_error_check __ARGS((Display *dpy, XErrorEvent *error_event));
Karsten Hopp d250f9
  static int	IsSerialName __ARGS((char_u *name));
Karsten Hopp d250f9
+ static void	save_in_queue __ARGS((char_u *buf, int len));
Karsten Hopp d250f9
+ static void	server_parse_message __ARGS((Display *dpy, char_u *propInfo, int numItems));
Karsten Hopp d250f9
  
Karsten Hopp d250f9
  /* Private variables for the "server" functionality */
Karsten Hopp d250f9
  static Atom	registryProperty = None;
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 595,601 ****
Karsten Hopp d250f9
      while (TRUE)
Karsten Hopp d250f9
      {
Karsten Hopp d250f9
  	while (XCheckWindowEvent(dpy, commWindow, PropertyChangeMask, &event))
Karsten Hopp d250f9
! 	    serverEventProc(dpy, &event);
Karsten Hopp d250f9
  
Karsten Hopp d250f9
  	if (endCond(endData) != 0)
Karsten Hopp d250f9
  	    break;
Karsten Hopp d250f9
--- 610,616 ----
Karsten Hopp d250f9
      while (TRUE)
Karsten Hopp d250f9
      {
Karsten Hopp d250f9
  	while (XCheckWindowEvent(dpy, commWindow, PropertyChangeMask, &event))
Karsten Hopp d250f9
! 	    serverEventProc(dpy, &event, 1);
Karsten Hopp d250f9
  
Karsten Hopp d250f9
  	if (endCond(endData) != 0)
Karsten Hopp d250f9
  	    break;
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 1127,1148 ****
Karsten Hopp d250f9
      return OK;
Karsten Hopp d250f9
  }
Karsten Hopp d250f9
  
Karsten Hopp d250f9
  /*
Karsten Hopp d250f9
   * This procedure is invoked by the various X event loops throughout Vims when
Karsten Hopp d250f9
   * a property changes on the communication window.  This procedure reads the
Karsten Hopp d250f9
!  * property and handles command requests and responses.
Karsten Hopp d250f9
   */
Karsten Hopp d250f9
      void
Karsten Hopp d250f9
! serverEventProc(dpy, eventPtr)
Karsten Hopp d250f9
      Display	*dpy;
Karsten Hopp d250f9
!     XEvent	*eventPtr;		/* Information about event. */
Karsten Hopp d250f9
  {
Karsten Hopp d250f9
      char_u	*propInfo;
Karsten Hopp d250f9
!     char_u	*p;
Karsten Hopp d250f9
!     int		result, actualFormat, code;
Karsten Hopp d250f9
      long_u	numItems, bytesAfter;
Karsten Hopp d250f9
      Atom	actualType;
Karsten Hopp d250f9
-     char_u	*tofree;
Karsten Hopp d250f9
  
Karsten Hopp d250f9
      if (eventPtr != NULL)
Karsten Hopp d250f9
      {
Karsten Hopp d250f9
--- 1142,1166 ----
Karsten Hopp d250f9
      return OK;
Karsten Hopp d250f9
  }
Karsten Hopp d250f9
  
Karsten Hopp d250f9
+ 
Karsten Hopp d250f9
  /*
Karsten Hopp d250f9
   * This procedure is invoked by the various X event loops throughout Vims when
Karsten Hopp d250f9
   * a property changes on the communication window.  This procedure reads the
Karsten Hopp d250f9
!  * property and enqueues command requests and responses. If immediate is true,
Karsten Hopp d250f9
!  * it runs the event immediatly instead of enqueuing it. Immediate can cause
Karsten Hopp d250f9
!  * unintended behavior and should only be used for code that blocks for a
Karsten Hopp d250f9
!  * response.
Karsten Hopp d250f9
   */
Karsten Hopp d250f9
      void
Karsten Hopp d250f9
! serverEventProc(dpy, eventPtr, immediate)
Karsten Hopp d250f9
      Display	*dpy;
Karsten Hopp d250f9
!     XEvent	*eventPtr;	/* Information about event. */
Karsten Hopp d250f9
!     int		immediate;	/* Run event immediately. Should mostly be 0. */
Karsten Hopp d250f9
  {
Karsten Hopp d250f9
      char_u	*propInfo;
Karsten Hopp d250f9
!     int		result, actualFormat;
Karsten Hopp d250f9
      long_u	numItems, bytesAfter;
Karsten Hopp d250f9
      Atom	actualType;
Karsten Hopp d250f9
  
Karsten Hopp d250f9
      if (eventPtr != NULL)
Karsten Hopp d250f9
      {
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 1168,1173 ****
Karsten Hopp d250f9
--- 1186,1272 ----
Karsten Hopp d250f9
  	    XFree(propInfo);
Karsten Hopp d250f9
  	return;
Karsten Hopp d250f9
      }
Karsten Hopp d250f9
+     if (immediate)
Karsten Hopp d250f9
+ 	server_parse_message(dpy, propInfo, numItems);
Karsten Hopp d250f9
+     else
Karsten Hopp d250f9
+ 	save_in_queue(propInfo, numItems);
Karsten Hopp d250f9
+ }
Karsten Hopp d250f9
+ 
Karsten Hopp d250f9
+ /*
Karsten Hopp d250f9
+  * Saves x clientserver commands in a queue so that they can be called when
Karsten Hopp d250f9
+  * vim is idle.
Karsten Hopp d250f9
+  */
Karsten Hopp d250f9
+     static void
Karsten Hopp d250f9
+ save_in_queue(propInfo, len)
Karsten Hopp d250f9
+     char_u  *propInfo;
Karsten Hopp d250f9
+     int	    len;
Karsten Hopp d250f9
+ {
Karsten Hopp d250f9
+     x_queue_T *node;
Karsten Hopp d250f9
+ 
Karsten Hopp d250f9
+     node = (x_queue_T *)alloc(sizeof(x_queue_T));
Karsten Hopp d250f9
+     if (node == NULL)
Karsten Hopp d250f9
+ 	return;	    /* out of memory */
Karsten Hopp d250f9
+     node->propInfo = propInfo;
Karsten Hopp d250f9
+     node->len = len;
Karsten Hopp d250f9
+ 
Karsten Hopp d250f9
+     if (head.next == NULL)   /* initialize circular queue */
Karsten Hopp d250f9
+     {
Karsten Hopp d250f9
+ 	head.next = &head;
Karsten Hopp d250f9
+ 	head.prev = &head;
Karsten Hopp d250f9
+     }
Karsten Hopp d250f9
+ 
Karsten Hopp d250f9
+     /* insert node at tail of queue */
Karsten Hopp d250f9
+     node->next = &head;
Karsten Hopp d250f9
+     node->prev = head.prev;
Karsten Hopp d250f9
+     head.prev->next = node;
Karsten Hopp d250f9
+     head.prev = node;
Karsten Hopp d250f9
+ }
Karsten Hopp d250f9
+ 
Karsten Hopp d250f9
+ /*
Karsten Hopp d250f9
+  * Parses queued clientserver messages.
Karsten Hopp d250f9
+  */
Karsten Hopp d250f9
+     void
Karsten Hopp d250f9
+ server_parse_messages()
Karsten Hopp d250f9
+ {
Karsten Hopp d250f9
+     char_u	*p;
Karsten Hopp d250f9
+     x_queue_T	*node;
Karsten Hopp d250f9
+ 
Karsten Hopp d250f9
+     if (!X_DISPLAY)
Karsten Hopp d250f9
+ 	return; /* cannot happen? */
Karsten Hopp d250f9
+     while (head.next != NULL && head.next != &head)
Karsten Hopp d250f9
+     {
Karsten Hopp d250f9
+ 	node = head.next;
Karsten Hopp d250f9
+ 	server_parse_message(X_DISPLAY, node->propInfo, node->len);
Karsten Hopp d250f9
+ 	head.next = node->next;
Karsten Hopp d250f9
+ 	node->next->prev = node->prev;
Karsten Hopp d250f9
+ 	vim_free(node);
Karsten Hopp d250f9
+     }
Karsten Hopp d250f9
+ }
Karsten Hopp d250f9
+ 
Karsten Hopp d250f9
+ /*
Karsten Hopp d250f9
+  * Returns a non-zero value if there are clientserver messages waiting
Karsten Hopp d250f9
+  * int the queue.
Karsten Hopp d250f9
+  */
Karsten Hopp d250f9
+     int
Karsten Hopp d250f9
+ server_waiting()
Karsten Hopp d250f9
+ {
Karsten Hopp d250f9
+     return head.next != NULL && head.next != &head;
Karsten Hopp d250f9
+ }
Karsten Hopp d250f9
+ 
Karsten Hopp d250f9
+ /*
Karsten Hopp d250f9
+  * Prases a single clientserver message. A single message may contain multiple
Karsten Hopp d250f9
+  * commands.
Karsten Hopp d250f9
+  * "propInfo" will be freed.
Karsten Hopp d250f9
+  */
Karsten Hopp d250f9
+     static void
Karsten Hopp d250f9
+ server_parse_message(dpy, propInfo, numItems)
Karsten Hopp d250f9
+     Display	*dpy;
Karsten Hopp d250f9
+     char_u	*propInfo; /* A string containing 0 or more X commands */
Karsten Hopp d250f9
+     int		numItems;  /* The size of propInfo in bytes. */
Karsten Hopp d250f9
+ {
Karsten Hopp d250f9
+     char_u	*p;
Karsten Hopp d250f9
+     int		code;
Karsten Hopp d250f9
+     char_u	*tofree;
Karsten Hopp d250f9
  
Karsten Hopp d250f9
      /*
Karsten Hopp d250f9
       * Several commands and results could arrive in the property at
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 1248,1263 ****
Karsten Hopp d250f9
  	    if (script == NULL || name == NULL)
Karsten Hopp d250f9
  		continue;
Karsten Hopp d250f9
  
Karsten Hopp d250f9
!             if (serverName != NULL && STRICMP(name, serverName) == 0)
Karsten Hopp d250f9
!             {
Karsten Hopp d250f9
!                 script = serverConvert(enc, script, &tofree);
Karsten Hopp d250f9
!                 if (asKeys)
Karsten Hopp d250f9
!                     server_to_input_buf(script);
Karsten Hopp d250f9
!                 else
Karsten Hopp d250f9
!                 {
Karsten Hopp d250f9
!                     char_u      *res;
Karsten Hopp d250f9
  
Karsten Hopp d250f9
!                     res = eval_client_expr_to_string(script);
Karsten Hopp d250f9
  		    if (resWindow != None)
Karsten Hopp d250f9
  		    {
Karsten Hopp d250f9
  			garray_T    reply;
Karsten Hopp d250f9
--- 1347,1362 ----
Karsten Hopp d250f9
  	    if (script == NULL || name == NULL)
Karsten Hopp d250f9
  		continue;
Karsten Hopp d250f9
  
Karsten Hopp d250f9
! 	    if (serverName != NULL && STRICMP(name, serverName) == 0)
Karsten Hopp d250f9
! 	    {
Karsten Hopp d250f9
! 		script = serverConvert(enc, script, &tofree);
Karsten Hopp d250f9
! 		if (asKeys)
Karsten Hopp d250f9
! 		    server_to_input_buf(script);
Karsten Hopp d250f9
! 		else
Karsten Hopp d250f9
! 		{
Karsten Hopp d250f9
! 		    char_u      *res;
Karsten Hopp d250f9
  
Karsten Hopp d250f9
! 		    res = eval_client_expr_to_string(script);
Karsten Hopp d250f9
  		    if (resWindow != None)
Karsten Hopp d250f9
  		    {
Karsten Hopp d250f9
  			garray_T    reply;
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 1290,1299 ****
Karsten Hopp d250f9
  						 reply.ga_data, reply.ga_len);
Karsten Hopp d250f9
  			ga_clear(&reply);
Karsten Hopp d250f9
  		    }
Karsten Hopp d250f9
!                     vim_free(res);
Karsten Hopp d250f9
!                 }
Karsten Hopp d250f9
!                 vim_free(tofree);
Karsten Hopp d250f9
!             }
Karsten Hopp d250f9
  	}
Karsten Hopp d250f9
  	else if (*p == 'r' && p[1] == 0)
Karsten Hopp d250f9
  	{
Karsten Hopp d250f9
--- 1389,1398 ----
Karsten Hopp d250f9
  						 reply.ga_data, reply.ga_len);
Karsten Hopp d250f9
  			ga_clear(&reply);
Karsten Hopp d250f9
  		    }
Karsten Hopp d250f9
! 		    vim_free(res);
Karsten Hopp d250f9
! 		}
Karsten Hopp d250f9
! 		vim_free(tofree);
Karsten Hopp d250f9
! 	    }
Karsten Hopp d250f9
  	}
Karsten Hopp d250f9
  	else if (*p == 'r' && p[1] == 0)
Karsten Hopp d250f9
  	{
Karsten Hopp d250f9
*** ../vim-7.4.865/src/misc2.c	2015-08-27 22:30:43.548873347 +0200
Karsten Hopp d250f9
--- src/misc2.c	2015-09-15 13:28:12.086187881 +0200
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 6328,6330 ****
Karsten Hopp d250f9
--- 6328,6350 ----
Karsten Hopp d250f9
      return FALSE;
Karsten Hopp d250f9
  }
Karsten Hopp d250f9
  #endif
Karsten Hopp d250f9
+ 
Karsten Hopp d250f9
+ #if defined(MESSAGE_QUEUE) || defined(PROTO)
Karsten Hopp d250f9
+ /*
Karsten Hopp d250f9
+  * Process messages that have been queued for netbeans or clientserver.
Karsten Hopp d250f9
+  * These functions can call arbitrary vimscript and should only be called when
Karsten Hopp d250f9
+  * it is safe to do so.
Karsten Hopp d250f9
+  */
Karsten Hopp d250f9
+     void
Karsten Hopp d250f9
+ parse_queued_messages()
Karsten Hopp d250f9
+ {
Karsten Hopp d250f9
+ # ifdef FEAT_NETBEANS_INTG
Karsten Hopp d250f9
+     /* Process the queued netbeans messages. */
Karsten Hopp d250f9
+     netbeans_parse_messages();
Karsten Hopp d250f9
+ # endif
Karsten Hopp d250f9
+ # ifdef FEAT_CLIENTSERVER
Karsten Hopp d250f9
+     /* Process the queued clientserver messages. */
Karsten Hopp d250f9
+     server_parse_messages();
Karsten Hopp d250f9
+ # endif
Karsten Hopp d250f9
+ }
Karsten Hopp d250f9
+ #endif
Karsten Hopp d250f9
*** ../vim-7.4.865/src/os_unix.c	2015-08-11 19:13:55.130175784 +0200
Karsten Hopp d250f9
--- src/os_unix.c	2015-09-15 13:33:20.218978266 +0200
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 388,396 ****
Karsten Hopp d250f9
  {
Karsten Hopp d250f9
      int		len;
Karsten Hopp d250f9
  
Karsten Hopp d250f9
! #ifdef FEAT_NETBEANS_INTG
Karsten Hopp d250f9
!     /* Process the queued netbeans messages. */
Karsten Hopp d250f9
!     netbeans_parse_messages();
Karsten Hopp d250f9
  #endif
Karsten Hopp d250f9
  
Karsten Hopp d250f9
      /* Check if window changed size while we were busy, perhaps the ":set
Karsten Hopp d250f9
--- 388,395 ----
Karsten Hopp d250f9
  {
Karsten Hopp d250f9
      int		len;
Karsten Hopp d250f9
  
Karsten Hopp d250f9
! #ifdef MESSAGE_QUEUE
Karsten Hopp d250f9
!     parse_queued_messages();
Karsten Hopp d250f9
  #endif
Karsten Hopp d250f9
  
Karsten Hopp d250f9
      /* Check if window changed size while we were busy, perhaps the ":set
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 405,413 ****
Karsten Hopp d250f9
  	    if (!do_resize)	/* return if not interrupted by resize */
Karsten Hopp d250f9
  		return 0;
Karsten Hopp d250f9
  	    handle_resize();
Karsten Hopp d250f9
! #ifdef FEAT_NETBEANS_INTG
Karsten Hopp d250f9
! 	    /* Process the queued netbeans messages. */
Karsten Hopp d250f9
! 	    netbeans_parse_messages();
Karsten Hopp d250f9
  #endif
Karsten Hopp d250f9
  	}
Karsten Hopp d250f9
      }
Karsten Hopp d250f9
--- 404,411 ----
Karsten Hopp d250f9
  	    if (!do_resize)	/* return if not interrupted by resize */
Karsten Hopp d250f9
  		return 0;
Karsten Hopp d250f9
  	    handle_resize();
Karsten Hopp d250f9
! #ifdef MESSAGE_QUEUE
Karsten Hopp d250f9
! 	    parse_queued_messages();
Karsten Hopp d250f9
  #endif
Karsten Hopp d250f9
  	}
Karsten Hopp d250f9
      }
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 439,447 ****
Karsten Hopp d250f9
  	while (do_resize)    /* window changed size */
Karsten Hopp d250f9
  	    handle_resize();
Karsten Hopp d250f9
  
Karsten Hopp d250f9
! #ifdef FEAT_NETBEANS_INTG
Karsten Hopp d250f9
! 	/* Process the queued netbeans messages. */
Karsten Hopp d250f9
! 	netbeans_parse_messages();
Karsten Hopp d250f9
  #endif
Karsten Hopp d250f9
  	/*
Karsten Hopp d250f9
  	 * We want to be interrupted by the winch signal
Karsten Hopp d250f9
--- 437,444 ----
Karsten Hopp d250f9
  	while (do_resize)    /* window changed size */
Karsten Hopp d250f9
  	    handle_resize();
Karsten Hopp d250f9
  
Karsten Hopp d250f9
! #ifdef MESSAGE_QUEUE
Karsten Hopp d250f9
! 	parse_queued_messages();
Karsten Hopp d250f9
  #endif
Karsten Hopp d250f9
  	/*
Karsten Hopp d250f9
  	 * We want to be interrupted by the winch signal
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 5208,5213 ****
Karsten Hopp d250f9
--- 5205,5211 ----
Karsten Hopp d250f9
   * When a GUI is being used, this will not be used for input -- webb
Karsten Hopp d250f9
   * Returns also, when a request from Sniff is waiting -- toni.
Karsten Hopp d250f9
   * Or when a Linux GPM mouse event is waiting.
Karsten Hopp d250f9
+  * Or when a clientserver message is on the queue.
Karsten Hopp d250f9
   */
Karsten Hopp d250f9
  #if defined(__BEOS__)
Karsten Hopp d250f9
      int
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 5601,5606 ****
Karsten Hopp d250f9
--- 5599,5609 ----
Karsten Hopp d250f9
  	if (finished || msec == 0)
Karsten Hopp d250f9
  	    break;
Karsten Hopp d250f9
  
Karsten Hopp d250f9
+ # ifdef FEAT_CLIENTSERVER
Karsten Hopp d250f9
+ 	if (server_waiting())
Karsten Hopp d250f9
+ 	    break;
Karsten Hopp d250f9
+ # endif
Karsten Hopp d250f9
+ 
Karsten Hopp d250f9
  	/* We're going to loop around again, find out for how long */
Karsten Hopp d250f9
  	if (msec > 0)
Karsten Hopp d250f9
  	{
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 7106,7136 ****
Karsten Hopp d250f9
  
Karsten Hopp d250f9
      for (;;)
Karsten Hopp d250f9
      {
Karsten Hopp d250f9
!         XtInputMask mask = XtAppPending(app_context);
Karsten Hopp d250f9
  
Karsten Hopp d250f9
!         if (mask == 0 || vim_is_input_buf_full())
Karsten Hopp d250f9
  	    break;
Karsten Hopp d250f9
  
Karsten Hopp d250f9
!         if (mask & XtIMXEvent)
Karsten Hopp d250f9
  	{
Karsten Hopp d250f9
  	    /* There is an event to process. */
Karsten Hopp d250f9
!             XtAppNextEvent(app_context, &event);
Karsten Hopp d250f9
  #ifdef FEAT_CLIENTSERVER
Karsten Hopp d250f9
  	    {
Karsten Hopp d250f9
  		XPropertyEvent *e = (XPropertyEvent *)&event;
Karsten Hopp d250f9
  
Karsten Hopp d250f9
  		if (e->type == PropertyNotify && e->window == commWindow
Karsten Hopp d250f9
  		   && e->atom == commProperty && e->state == PropertyNewValue)
Karsten Hopp d250f9
!                 serverEventProc(xterm_dpy, &event);
Karsten Hopp d250f9
  	    }
Karsten Hopp d250f9
  #endif
Karsten Hopp d250f9
!             XtDispatchEvent(&event);
Karsten Hopp d250f9
!         }
Karsten Hopp d250f9
  	else
Karsten Hopp d250f9
  	{
Karsten Hopp d250f9
  	    /* There is something else than an event to process. */
Karsten Hopp d250f9
!             XtAppProcessEvent(app_context, mask);
Karsten Hopp d250f9
!         }
Karsten Hopp d250f9
      }
Karsten Hopp d250f9
  }
Karsten Hopp d250f9
  
Karsten Hopp d250f9
--- 7109,7139 ----
Karsten Hopp d250f9
  
Karsten Hopp d250f9
      for (;;)
Karsten Hopp d250f9
      {
Karsten Hopp d250f9
! 	XtInputMask mask = XtAppPending(app_context);
Karsten Hopp d250f9
  
Karsten Hopp d250f9
! 	if (mask == 0 || vim_is_input_buf_full())
Karsten Hopp d250f9
  	    break;
Karsten Hopp d250f9
  
Karsten Hopp d250f9
! 	if (mask & XtIMXEvent)
Karsten Hopp d250f9
  	{
Karsten Hopp d250f9
  	    /* There is an event to process. */
Karsten Hopp d250f9
! 	    XtAppNextEvent(app_context, &event);
Karsten Hopp d250f9
  #ifdef FEAT_CLIENTSERVER
Karsten Hopp d250f9
  	    {
Karsten Hopp d250f9
  		XPropertyEvent *e = (XPropertyEvent *)&event;
Karsten Hopp d250f9
  
Karsten Hopp d250f9
  		if (e->type == PropertyNotify && e->window == commWindow
Karsten Hopp d250f9
  		   && e->atom == commProperty && e->state == PropertyNewValue)
Karsten Hopp d250f9
! 		    serverEventProc(xterm_dpy, &event, 0);
Karsten Hopp d250f9
  	    }
Karsten Hopp d250f9
  #endif
Karsten Hopp d250f9
! 	    XtDispatchEvent(&event);
Karsten Hopp d250f9
! 	}
Karsten Hopp d250f9
  	else
Karsten Hopp d250f9
  	{
Karsten Hopp d250f9
  	    /* There is something else than an event to process. */
Karsten Hopp d250f9
! 	    XtAppProcessEvent(app_context, mask);
Karsten Hopp d250f9
! 	}
Karsten Hopp d250f9
      }
Karsten Hopp d250f9
  }
Karsten Hopp d250f9
  
Karsten Hopp d250f9
*** ../vim-7.4.865/src/proto/if_xcmdsrv.pro	2013-08-10 13:37:15.000000000 +0200
Karsten Hopp d250f9
--- src/proto/if_xcmdsrv.pro	2015-09-15 13:50:22.648292769 +0200
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 7,11 ****
Karsten Hopp d250f9
  int serverSendReply __ARGS((char_u *name, char_u *str));
Karsten Hopp d250f9
  int serverReadReply __ARGS((Display *dpy, Window win, char_u **str, int localLoop));
Karsten Hopp d250f9
  int serverPeekReply __ARGS((Display *dpy, Window win, char_u **str));
Karsten Hopp d250f9
! void serverEventProc __ARGS((Display *dpy, XEvent *eventPtr));
Karsten Hopp d250f9
  /* vim: set ft=c : */
Karsten Hopp d250f9
--- 7,13 ----
Karsten Hopp d250f9
  int serverSendReply __ARGS((char_u *name, char_u *str));
Karsten Hopp d250f9
  int serverReadReply __ARGS((Display *dpy, Window win, char_u **str, int localLoop));
Karsten Hopp d250f9
  int serverPeekReply __ARGS((Display *dpy, Window win, char_u **str));
Karsten Hopp d250f9
! void serverEventProc __ARGS((Display *dpy, XEvent *eventPtr, int immediate));
Karsten Hopp d250f9
! void server_parse_messages __ARGS((void));
Karsten Hopp d250f9
! int server_waiting __ARGS((void));
Karsten Hopp d250f9
  /* vim: set ft=c : */
Karsten Hopp d250f9
*** ../vim-7.4.865/src/proto/misc2.pro	2015-07-17 13:22:43.157523671 +0200
Karsten Hopp d250f9
--- src/proto/misc2.pro	2015-09-15 13:34:55.177985281 +0200
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 106,109 ****
Karsten Hopp d250f9
--- 106,110 ----
Karsten Hopp d250f9
  void put_time __ARGS((FILE *fd, time_t the_time));
Karsten Hopp d250f9
  void time_to_bytes __ARGS((time_t the_time, char_u *buf));
Karsten Hopp d250f9
  int has_non_ascii __ARGS((char_u *s));
Karsten Hopp d250f9
+ void parse_queued_messages __ARGS((void));
Karsten Hopp d250f9
  /* vim: set ft=c : */
Karsten Hopp d250f9
*** ../vim-7.4.865/src/macros.h	2015-09-09 20:59:34.013186842 +0200
Karsten Hopp d250f9
--- src/macros.h	2015-09-15 13:26:44.155103230 +0200
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 321,323 ****
Karsten Hopp d250f9
--- 321,327 ----
Karsten Hopp d250f9
  #else
Karsten Hopp d250f9
  # define PLINES_NOFILL(x) plines(x)
Karsten Hopp d250f9
  #endif
Karsten Hopp d250f9
+ 
Karsten Hopp d250f9
+ #if defined(FEAT_NETBEANS_INTG) || defined(FEAT_CLIENTSERVER)
Karsten Hopp d250f9
+ # define MESSAGE_QUEUE
Karsten Hopp d250f9
+ #endif
Karsten Hopp d250f9
*** ../vim-7.4.865/src/version.c	2015-09-09 22:35:25.792564584 +0200
Karsten Hopp d250f9
--- src/version.c	2015-09-15 14:08:07.297090947 +0200
Karsten Hopp d250f9
***************
Karsten Hopp d250f9
*** 743,744 ****
Karsten Hopp d250f9
--- 743,746 ----
Karsten Hopp d250f9
  {   /* Add new patch number below this line */
Karsten Hopp d250f9
+ /**/
Karsten Hopp d250f9
+     866,
Karsten Hopp d250f9
  /**/
Karsten Hopp d250f9
Karsten Hopp d250f9
-- 
Karsten Hopp d250f9
ALL:   A witch!  A witch!
Karsten Hopp d250f9
WITCH: It's a fair cop.
Karsten Hopp d250f9
ALL:   Burn her!  Burn her!  Let's make her into a ladder.
Karsten Hopp d250f9
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
Karsten Hopp d250f9
Karsten Hopp d250f9
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp d250f9
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp d250f9
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp d250f9
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///