summaryrefslogtreecommitdiffstats
path: root/src/clipboard.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/clipboard.c266
1 files changed, 266 insertions, 0 deletions
diff --git a/src/clipboard.c b/src/clipboard.c
new file mode 100644
index 0000000..ab154cb
--- /dev/null
+++ b/src/clipboard.c
@@ -0,0 +1,266 @@
+/*
+ Util for external clipboard.
+
+ Copyright (C) 2009-2022
+ Free Software Foundation, Inc.
+
+ Written by:
+ Ilia Maslakov <il.smind@gmail.com>, 2010.
+ Andrew Borodin <aborodin@vmail.ru>, 2014.
+
+ This file is part of the Midnight Commander.
+
+ The Midnight Commander is free software: you can redistribute it
+ and/or modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ The Midnight Commander is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#include "lib/global.h"
+#include "lib/fileloc.h"
+#include "lib/mcconfig.h"
+#include "lib/util.h"
+#include "lib/event.h"
+
+#include "lib/vfs/vfs.h"
+
+#include "src/execute.h"
+
+#include "clipboard.h"
+
+/*** global variables ****************************************************************************/
+
+/* path to X clipboard utility */
+char *clipboard_store_path = NULL;
+char *clipboard_paste_path = NULL;
+
+/*** file scope macro definitions ****************************************************************/
+
+/*** file scope type declarations ****************************************************************/
+
+/*** 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 ************************************************************************/
+/* --------------------------------------------------------------------------------------------- */
+
+/* --------------------------------------------------------------------------------------------- */
+/*** public functions ****************************************************************************/
+/* --------------------------------------------------------------------------------------------- */
+
+/* event callback */
+gboolean
+clipboard_file_to_ext_clip (const gchar * event_group_name, const gchar * event_name,
+ gpointer init_data, gpointer data)
+{
+ char *tmp, *cmd;
+
+ (void) event_group_name;
+ (void) event_name;
+ (void) init_data;
+ (void) data;
+
+ if (clipboard_store_path == NULL || clipboard_store_path[0] == '\0')
+ return TRUE;
+
+ tmp = mc_config_get_full_path (EDIT_HOME_CLIP_FILE);
+ cmd = g_strconcat (clipboard_store_path, " ", tmp, " 2>/dev/null", (char *) NULL);
+
+ if (cmd != NULL)
+ my_system (EXECUTE_AS_SHELL, mc_global.shell->path, cmd);
+
+ g_free (cmd);
+ g_free (tmp);
+ return TRUE;
+}
+
+/* --------------------------------------------------------------------------------------------- */
+
+/* event callback */
+gboolean
+clipboard_file_from_ext_clip (const gchar * event_group_name, const gchar * event_name,
+ gpointer init_data, gpointer data)
+{
+ mc_pipe_t *p;
+ int file = -1;
+
+ (void) event_group_name;
+ (void) event_name;
+ (void) init_data;
+ (void) data;
+
+ if (clipboard_paste_path == NULL || clipboard_paste_path[0] == '\0')
+ return TRUE;
+
+ p = mc_popen (clipboard_paste_path, TRUE, TRUE, NULL);
+ if (p == NULL)
+ return TRUE; /* don't show error message */
+
+ 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_HOME_CLIP_FILE);
+ file = mc_open (fname_vpath, clip_open_flags, clip_open_mode);
+ vfs_path_free (fname_vpath, TRUE);
+
+ 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);
+
+ return TRUE;
+}
+
+/* --------------------------------------------------------------------------------------------- */
+
+/* event callback */
+gboolean
+clipboard_text_to_file (const gchar * event_group_name, const gchar * event_name,
+ gpointer init_data, gpointer data)
+{
+ int file;
+ vfs_path_t *fname_vpath = NULL;
+ size_t str_len;
+ const char *text = (const char *) data;
+
+ (void) event_group_name;
+ (void) event_name;
+ (void) init_data;
+
+ if (text == NULL)
+ return FALSE;
+
+ fname_vpath = mc_config_get_full_vpath (EDIT_HOME_CLIP_FILE);
+ file = mc_open (fname_vpath, clip_open_flags, clip_open_mode);
+ vfs_path_free (fname_vpath, TRUE);
+
+ if (file == -1)
+ return TRUE;
+
+ str_len = strlen (text);
+ {
+ ssize_t ret;
+
+ ret = mc_write (file, text, str_len);
+ (void) ret;
+ }
+ mc_close (file);
+ return TRUE;
+}
+
+/* --------------------------------------------------------------------------------------------- */
+
+/* event callback */
+gboolean
+clipboard_text_from_file (const gchar * event_group_name, const gchar * event_name,
+ gpointer init_data, gpointer data)
+{
+ char buf[BUF_LARGE];
+ FILE *f;
+ char *fname = NULL;
+ gboolean first = TRUE;
+ ev_clipboard_text_from_file_t *event_data = (ev_clipboard_text_from_file_t *) data;
+
+ (void) event_group_name;
+ (void) event_name;
+ (void) init_data;
+
+ fname = mc_config_get_full_path (EDIT_HOME_CLIP_FILE);
+ f = fopen (fname, "r");
+ g_free (fname);
+
+ if (f == NULL)
+ {
+ event_data->ret = FALSE;
+ return TRUE;
+ }
+
+ *(event_data->text) = NULL;
+
+ while (fgets (buf, sizeof (buf), f))
+ {
+ size_t len;
+
+ len = strlen (buf);
+ if (len > 0)
+ {
+ if (buf[len - 1] == '\n')
+ buf[len - 1] = '\0';
+
+ if (first)
+ {
+ first = FALSE;
+ *(event_data->text) = g_strdup (buf);
+ }
+ else
+ {
+ /* remove \n on EOL */
+ char *tmp;
+
+ tmp = g_strconcat (*(event_data->text), " ", buf, (char *) NULL);
+ g_free (*(event_data->text));
+ *(event_data->text) = tmp;
+ }
+ }
+ }
+
+ fclose (f);
+ event_data->ret = (*(event_data->text) != NULL);
+ return TRUE;
+}
+
+/* --------------------------------------------------------------------------------------------- */