Browse Source

Merge branch '3339_mcedit_paste_to_clipboard'

* 3339_mcedit_paste_to_clipboard:
  Clarify description of clipboard_store and clipboard_paste options.
  Clarify flags and mode to open clipboard file.
  Ticket #3339: fix pasting from clipboard.
Andrew Borodin 10 years ago
parent
commit
e4f3aed41f
4 changed files with 67 additions and 15 deletions
  1. 2 2
      doc/man/es/mc.1.in
  2. 2 2
      doc/man/mc.1.in
  3. 2 2
      doc/man/ru/mc.1.in
  4. 61 9
      src/clipboard.c

+ 2 - 2
doc/man/es/mc.1.in

@@ -3927,7 +3927,7 @@ para cargar texto de un archivo como selección en X Window.
 Por ejemplo:
 .PP
 .nf
-clipboard_store=xclip \-i
+clipboard_store=/usr/bin/xclip \-i
 .fi
 .TP
 .I clipboard_paste
@@ -3936,7 +3936,7 @@ para volcar la selección de X Window a la salida estándar.
 Por ejemplo:
 .PP
 .nf
-clipboard_paste=xclip \-o
+clipboard_paste=/usr/bin/xclip \-o
 .fi
 .TP
 .I autodetect_codeset

+ 2 - 2
doc/man/mc.1.in

@@ -4108,7 +4108,7 @@ utility like 'xclip' to read text into X selection from file.
 For example:
 .PP
 .nf
-clipboard_store=xclip \-i
+clipboard_store=/usr/bin/xclip \-i
 .fi
 .TP
 .I clipboard_paste
@@ -4117,7 +4117,7 @@ utility like 'xclip' to print the selection to standard out.
 For example:
 .PP
 .nf
-clipboard_paste=xclip \-o
+clipboard_paste=/usr/bin/xclip \-o
 .fi
 .TP
 .I autodetect_codeset

+ 2 - 2
doc/man/ru/mc.1.in

@@ -4491,7 +4491,7 @@ mc.ext\&.
 Например:
 .PP
 .nf
-clipboard_store=xclip \-i
+clipboard_store=/usr/bin/xclip \-i
 .fi
 .TP
 .I clipboard_paste
@@ -4501,7 +4501,7 @@ clipboard_store=xclip \-i
 Например:
 .PP
 .nf
-clipboard_paste=xclip \-o
+clipboard_paste=/usr/bin/xclip \-o
 .fi
 .PP
 .I autodetect_codeset

+ 61 - 9
src/clipboard.c

@@ -6,6 +6,7 @@
 
    Written by:
    Ilia Maslakov <il.smind@gmail.com>, 2010.
+   Andrew Borodin <aborodin@vmail.ru>, 2014.
 
    This file is part of the Midnight Commander.
 
@@ -27,6 +28,8 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/types.h>
+#include <fcntl.h>
 
 #include "lib/global.h"
 #include "lib/fileloc.h"
@@ -52,6 +55,10 @@ char *clipboard_paste_path = NULL;
 
 /*** file scope variables ************************************************************************/
 
+static const int clip_open_flags = O_CREAT | O_WRONLY | O_TRUNC | O_BINARY;
+static const mode_t clip_open_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+
+/* --------------------------------------------------------------------------------------------- */
 /*** file scope functions ************************************************************************/
 /* --------------------------------------------------------------------------------------------- */
 
@@ -93,7 +100,8 @@ gboolean
 clipboard_file_from_ext_clip (const gchar * event_group_name, const gchar * event_name,
                               gpointer init_data, gpointer data)
 {
-    char *tmp, *cmd;
+    mc_pipe_t *p;
+    int file = -1;
     const char *d = getenv ("DISPLAY");
 
     (void) event_group_name;
@@ -104,14 +112,59 @@ clipboard_file_from_ext_clip (const gchar * event_group_name, const gchar * even
     if (d == NULL || clipboard_paste_path == NULL || clipboard_paste_path[0] == '\0')
         return TRUE;
 
-    tmp = mc_config_get_full_path (EDIT_CLIP_FILE);
-    cmd = g_strconcat (clipboard_paste_path, " > ", tmp, " 2>/dev/null", (char *) NULL);
+    p = mc_popen (clipboard_paste_path, NULL);
+    if (p == NULL)
+        return TRUE;    /* don't show error message */
 
-    if (cmd != NULL)
-        my_system (EXECUTE_AS_SHELL, mc_global.tty.shell, cmd);
+    p->out.null_term = FALSE;
+    p->err.null_term = TRUE;
+
+    while (TRUE)
+    {
+        GError *error = NULL;
+
+        p->out.len = MC_PIPE_BUFSIZE;
+        p->err.len = MC_PIPE_BUFSIZE;
+
+        mc_pread (p, &error);
+
+        if (error != NULL)
+        {
+            /* don't show error message */
+            g_error_free (error);
+            break;
+        }
+
+        /* ignore stderr and get stdout */
+        if (p->out.len == MC_PIPE_STREAM_EOF || p->out.len == MC_PIPE_ERROR_READ)
+            break;
+
+        if (p->out.len > 0)
+        {
+            ssize_t nwrite;
+
+            if (file < 0)
+            {
+                vfs_path_t *fname_vpath;
+
+                fname_vpath = mc_config_get_full_vpath (EDIT_CLIP_FILE);
+                file = mc_open (fname_vpath, clip_open_flags, clip_open_mode);
+                vfs_path_free (fname_vpath);
+
+                if (file < 0)
+                    break;
+            }
+
+            nwrite = mc_write (file, p->out.buf, p->out.len);
+            (void) nwrite;
+        }
+    }
+
+    if (file >= 0)
+        mc_close (file);
+
+    mc_pclose (p, NULL);
 
-    g_free (cmd);
-    g_free (tmp);
     return TRUE;
 }
 
@@ -135,8 +188,7 @@ clipboard_text_to_file (const gchar * event_group_name, const gchar * event_name
         return FALSE;
 
     fname_vpath = mc_config_get_full_vpath (EDIT_CLIP_FILE);
-    file = mc_open (fname_vpath, O_CREAT | O_WRONLY | O_TRUNC,
-                    S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH | O_BINARY);
+    file = mc_open (fname_vpath, clip_open_flags, clip_open_mode);
     vfs_path_free (fname_vpath);
 
     if (file == -1)