To: vim_dev@googlegroups.com Subject: Patch 7.3.856 Fcc: outbox From: Bram Moolenaar 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 ///