To: vim_dev@googlegroups.com
Subject: Patch 7.3.856
Fcc: outbox
From: Bram Moolenaar <Bram@moolenaar.net>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
------------

Patch 7.3.856
Problem:    When calling system() multi-byte clipboard contents is garbled.
Solution:   Save and restore the clipboard contents.  (Yukihiro Nakadaira)
Files:	    src/gui_gtk_x11.c, src/proto/gui_gtk_x11.pro, src/ops.c,
	    src/proto/ops.pro, src/os_unix.c, src/proto/ui.pro, src/ui.c


*** ../vim-7.3.855/src/gui_gtk_x11.c	2013-02-14 22:11:31.000000000 +0100
--- src/gui_gtk_x11.c	2013-03-13 17:28:00.000000000 +0100
***************
*** 5674,5685 ****
      void
  clip_mch_lose_selection(VimClipboard *cbd UNUSED)
  {
!     /* WEIRD: when using NULL to actually disown the selection, we lose the
!      * selection the first time we own it. */
!     /*
!     gtk_selection_owner_set(NULL, cbd->gtk_sel_atom, (guint32)GDK_CURRENT_TIME);
      gui_mch_update();
-      */
  }
  
  /*
--- 5674,5681 ----
      void
  clip_mch_lose_selection(VimClipboard *cbd UNUSED)
  {
!     gtk_selection_owner_set(NULL, cbd->gtk_sel_atom, gui.event_time);
      gui_mch_update();
  }
  
  /*
***************
*** 5705,5710 ****
--- 5701,5712 ----
  {
  }
  
+     int
+ clip_gtk_owner_exists(VimClipboard *cbd)
+ {
+     return gdk_selection_owner_get(cbd->gtk_sel_atom) != NULL;
+ }
+ 
  
  #if defined(FEAT_MENU) || defined(PROTO)
  /*
*** ../vim-7.3.855/src/proto/gui_gtk_x11.pro	2012-05-18 17:03:14.000000000 +0200
--- src/proto/gui_gtk_x11.pro	2013-03-13 17:35:17.000000000 +0100
***************
*** 59,64 ****
--- 59,65 ----
  void clip_mch_lose_selection __ARGS((VimClipboard *cbd));
  int clip_mch_own_selection __ARGS((VimClipboard *cbd));
  void clip_mch_set_selection __ARGS((VimClipboard *cbd));
+ int clip_gtk_owner_exists __ARGS((VimClipboard *cbd));
  void gui_mch_menu_grey __ARGS((vimmenu_T *menu, int grey));
  void gui_mch_menu_hidden __ARGS((vimmenu_T *menu, int hidden));
  void gui_mch_draw_menubar __ARGS((void));
*** ../vim-7.3.855/src/ops.c	2013-03-07 18:50:52.000000000 +0100
--- src/ops.c	2013-03-13 17:30:50.000000000 +0100
***************
*** 1017,1022 ****
--- 1017,1035 ----
      may_set_selection();
  # endif
  }
+ 
+     void
+ free_register(reg)
+     void	*reg;
+ {
+     struct yankreg tmp;
+ 
+     tmp = *y_current;
+     *y_current = *(struct yankreg *)reg;
+     free_yank_all();
+     vim_free(reg);
+     *y_current = tmp;
+ }
  #endif
  
  #if defined(FEAT_MOUSE) || defined(PROTO)
*** ../vim-7.3.855/src/proto/ops.pro	2012-06-06 16:12:54.000000000 +0200
--- src/proto/ops.pro	2013-03-13 17:35:04.000000000 +0100
***************
*** 15,20 ****
--- 15,21 ----
  int may_get_selection __ARGS((int regname));
  void *get_register __ARGS((int name, int copy));
  void put_register __ARGS((int name, void *reg));
+ void free_register __ARGS((void *reg));
  int yank_register_mline __ARGS((int regname));
  int do_record __ARGS((int c));
  int do_execreg __ARGS((int regname, int colon, int addcr, int silent));
*** ../vim-7.3.855/src/os_unix.c	2013-02-26 14:56:24.000000000 +0100
--- src/os_unix.c	2013-03-13 17:33:00.000000000 +0100
***************
*** 1138,1143 ****
--- 1138,1148 ----
  
  # if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
  static void loose_clipboard __ARGS((void));
+ static void save_clipboard __ARGS((void));
+ static void restore_clipboard __ARGS((void));
+ 
+ static void *clip_star_save = NULL;
+ static void *clip_plus_save = NULL;
  
  /*
   * Called when Vim is going to sleep or execute a shell command.
***************
*** 1158,1163 ****
--- 1163,1204 ----
  	    XFlush(x11_display);
      }
  }
+ 
+ /*
+  * Save clipboard text to restore later.
+  */
+     static void
+ save_clipboard()
+ {
+     if (clip_star.owned)
+ 	clip_star_save = get_register('*', TRUE);
+     if (clip_plus.owned)
+ 	clip_plus_save = get_register('+', TRUE);
+ }
+ 
+ /*
+  * Restore clipboard text if no one own the X selection.
+  */
+     static void
+ restore_clipboard()
+ {
+     if (clip_star_save != NULL)
+     {
+ 	if (!clip_gen_owner_exists(&clip_star))
+ 	    put_register('*', clip_star_save);
+ 	else
+ 	    free_register(clip_star_save);
+ 	clip_star_save = NULL;
+     }
+     if (clip_plus_save != NULL)
+     {
+ 	if (!clip_gen_owner_exists(&clip_plus))
+ 	    put_register('+', clip_plus_save);
+ 	else
+ 	    free_register(clip_plus_save);
+ 	clip_plus_save = NULL;
+     }
+ }
  #endif
  
  /*
***************
*** 3844,3849 ****
--- 3885,3891 ----
  	settmode(TMODE_COOK);	    /* set to normal mode */
  
  # if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
+     save_clipboard();
      loose_clipboard();
  # endif
  
***************
*** 3917,3922 ****
--- 3959,3967 ----
  # ifdef FEAT_TITLE
      resettitle();
  # endif
+ # if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
+     restore_clipboard();
+ # endif
      return x;
  
  #else /* USE_SYSTEM */	    /* don't use system(), use fork()/exec() */
***************
*** 3965,3970 ****
--- 4010,4018 ----
  	settmode(TMODE_COOK);		/* set to normal mode */
  
  # if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
+     /* Disown the clipboard, because is the executed command tries to obtain a
+      * selection and we own it we get a deadlock. */
+     save_clipboard();
      loose_clipboard();
  # endif
  
***************
*** 4836,4841 ****
--- 4884,4892 ----
  # ifdef FEAT_TITLE
      resettitle();
  # endif
+ # if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
+     restore_clipboard();
+ # endif
      vim_free(newcmd);
  
      return retval;
*** ../vim-7.3.855/src/proto/ui.pro	2012-07-10 16:49:08.000000000 +0200
--- src/proto/ui.pro	2013-03-13 17:35:08.000000000 +0100
***************
*** 29,34 ****
--- 29,35 ----
  void clip_gen_lose_selection __ARGS((VimClipboard *cbd));
  void clip_gen_set_selection __ARGS((VimClipboard *cbd));
  void clip_gen_request_selection __ARGS((VimClipboard *cbd));
+ int clip_gen_owner_exists __ARGS((VimClipboard *cbd));
  int vim_is_input_buf_full __ARGS((void));
  int vim_is_input_buf_empty __ARGS((void));
  int vim_free_in_input_buf __ARGS((void));
***************
*** 52,57 ****
--- 53,59 ----
  void clip_x11_lose_selection __ARGS((Widget myShell, VimClipboard *cbd));
  int clip_x11_own_selection __ARGS((Widget myShell, VimClipboard *cbd));
  void clip_x11_set_selection __ARGS((VimClipboard *cbd));
+ int clip_x11_owner_exists __ARGS((VimClipboard *cbd));
  void yank_cut_buffer0 __ARGS((Display *dpy, VimClipboard *cbd));
  int jump_to_mouse __ARGS((int flags, int *inclusive, int which_button));
  int mouse_comp_pos __ARGS((win_T *win, int *rowp, int *colp, linenr_T *lnump));
*** ../vim-7.3.855/src/ui.c	2013-03-07 18:02:27.000000000 +0100
--- src/ui.c	2013-03-13 17:31:31.000000000 +0100
***************
*** 1456,1461 ****
--- 1456,1476 ----
  #endif
  }
  
+     int
+ clip_gen_owner_exists(cbd)
+     VimClipboard	*cbd;
+ {
+ #ifdef FEAT_XCLIPBOARD
+ # ifdef FEAT_GUI_GTK
+     if (gui.in_use)
+ 	return clip_gtk_owner_exists(cbd);
+     else
+ # endif
+ 	return clip_x11_owner_exists(cbd);
+ #endif
+     return TRUE;
+ }
+ 
  #endif /* FEAT_CLIPBOARD */
  
  /*****************************************************************************
***************
*** 2398,2404 ****
      Widget		myShell;
      VimClipboard	*cbd;
  {
!     XtDisownSelection(myShell, cbd->sel_atom, CurrentTime);
  }
  
      int
--- 2413,2420 ----
      Widget		myShell;
      VimClipboard	*cbd;
  {
!     XtDisownSelection(myShell, cbd->sel_atom,
! 				XtLastTimestampProcessed(XtDisplay(myShell)));
  }
  
      int
***************
*** 2440,2445 ****
--- 2456,2468 ----
      VimClipboard *cbd UNUSED;
  {
  }
+ 
+     int
+ clip_x11_owner_exists(cbd)
+     VimClipboard	*cbd;
+ {
+     return XGetSelectionOwner(X_DISPLAY, cbd->sel_atom) != None;
+ }
  #endif
  
  #if defined(FEAT_XCLIPBOARD) || defined(FEAT_GUI_X11) \
*** ../vim-7.3.855/src/version.c	2013-03-13 17:01:47.000000000 +0100
--- src/version.c	2013-03-13 17:45:25.000000000 +0100
***************
*** 730,731 ****
--- 730,733 ----
  {   /* Add new patch number below this line */
+ /**/
+     856,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
39. You move into a new house and decide to Netscape before you landscape.

 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///
