Merge branch '3416_find_accents'
[midnight-commander.git] / src / clipboard.c
blob7395ea02a187971da03153a4df61d312328a22c1
1 /*
2 Util for external clipboard.
4 Copyright (C) 2009-2015
5 Free Software Foundation, Inc.
7 Written by:
8 Ilia Maslakov <il.smind@gmail.com>, 2010.
9 Andrew Borodin <aborodin@vmail.ru>, 2014.
11 This file is part of the Midnight Commander.
13 The Midnight Commander is free software: you can redistribute it
14 and/or modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation, either version 3 of the License,
16 or (at your option) any later version.
18 The Midnight Commander is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #include <config.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <sys/types.h>
32 #include <fcntl.h>
34 #include "lib/global.h"
35 #include "lib/fileloc.h"
36 #include "lib/mcconfig.h"
37 #include "lib/util.h"
38 #include "lib/event.h"
40 #include "lib/vfs/vfs.h"
42 #include "src/execute.h"
44 #include "clipboard.h"
46 /*** global variables ****************************************************************************/
48 /* path to X clipboard utility */
49 char *clipboard_store_path = NULL;
50 char *clipboard_paste_path = NULL;
52 /*** file scope macro definitions ****************************************************************/
54 /*** file scope type declarations ****************************************************************/
56 /*** file scope variables ************************************************************************/
58 static const int clip_open_flags = O_CREAT | O_WRONLY | O_TRUNC | O_BINARY;
59 static const mode_t clip_open_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
61 /* --------------------------------------------------------------------------------------------- */
62 /*** file scope functions ************************************************************************/
63 /* --------------------------------------------------------------------------------------------- */
65 /* --------------------------------------------------------------------------------------------- */
66 /*** public functions ****************************************************************************/
67 /* --------------------------------------------------------------------------------------------- */
69 /* event callback */
70 gboolean
71 clipboard_file_to_ext_clip (const gchar * event_group_name, const gchar * event_name,
72 gpointer init_data, gpointer data)
74 char *tmp, *cmd;
75 const char *d = getenv ("DISPLAY");
77 (void) event_group_name;
78 (void) event_name;
79 (void) init_data;
80 (void) data;
82 if (d == NULL || clipboard_store_path == NULL || clipboard_store_path[0] == '\0')
83 return TRUE;
85 tmp = mc_config_get_full_path (EDIT_CLIP_FILE);
86 cmd = g_strconcat (clipboard_store_path, " ", tmp, " 2>/dev/null", (char *) NULL);
88 if (cmd != NULL)
89 my_system (EXECUTE_AS_SHELL, mc_global.tty.shell, cmd);
91 g_free (cmd);
92 g_free (tmp);
93 return TRUE;
96 /* --------------------------------------------------------------------------------------------- */
98 /* event callback */
99 gboolean
100 clipboard_file_from_ext_clip (const gchar * event_group_name, const gchar * event_name,
101 gpointer init_data, gpointer data)
103 mc_pipe_t *p;
104 int file = -1;
105 const char *d = getenv ("DISPLAY");
107 (void) event_group_name;
108 (void) event_name;
109 (void) init_data;
110 (void) data;
112 if (d == NULL || clipboard_paste_path == NULL || clipboard_paste_path[0] == '\0')
113 return TRUE;
115 p = mc_popen (clipboard_paste_path, NULL);
116 if (p == NULL)
117 return TRUE; /* don't show error message */
119 p->out.null_term = FALSE;
120 p->err.null_term = TRUE;
122 while (TRUE)
124 GError *error = NULL;
126 p->out.len = MC_PIPE_BUFSIZE;
127 p->err.len = MC_PIPE_BUFSIZE;
129 mc_pread (p, &error);
131 if (error != NULL)
133 /* don't show error message */
134 g_error_free (error);
135 break;
138 /* ignore stderr and get stdout */
139 if (p->out.len == MC_PIPE_STREAM_EOF || p->out.len == MC_PIPE_ERROR_READ)
140 break;
142 if (p->out.len > 0)
144 ssize_t nwrite;
146 if (file < 0)
148 vfs_path_t *fname_vpath;
150 fname_vpath = mc_config_get_full_vpath (EDIT_CLIP_FILE);
151 file = mc_open (fname_vpath, clip_open_flags, clip_open_mode);
152 vfs_path_free (fname_vpath);
154 if (file < 0)
155 break;
158 nwrite = mc_write (file, p->out.buf, p->out.len);
159 (void) nwrite;
163 if (file >= 0)
164 mc_close (file);
166 mc_pclose (p, NULL);
168 return TRUE;
171 /* --------------------------------------------------------------------------------------------- */
173 /* event callback */
174 gboolean
175 clipboard_text_to_file (const gchar * event_group_name, const gchar * event_name,
176 gpointer init_data, gpointer data)
178 int file;
179 vfs_path_t *fname_vpath = NULL;
180 size_t str_len;
181 const char *text = (const char *) data;
183 (void) event_group_name;
184 (void) event_name;
185 (void) init_data;
187 if (text == NULL)
188 return FALSE;
190 fname_vpath = mc_config_get_full_vpath (EDIT_CLIP_FILE);
191 file = mc_open (fname_vpath, clip_open_flags, clip_open_mode);
192 vfs_path_free (fname_vpath);
194 if (file == -1)
195 return TRUE;
197 str_len = strlen (text);
199 ssize_t ret;
201 ret = mc_write (file, (char *) text, str_len);
202 (void) ret;
204 mc_close (file);
205 return TRUE;
208 /* --------------------------------------------------------------------------------------------- */
210 /* event callback */
211 gboolean
212 clipboard_text_from_file (const gchar * event_group_name, const gchar * event_name,
213 gpointer init_data, gpointer data)
215 char buf[BUF_LARGE];
216 FILE *f;
217 char *fname = NULL;
218 gboolean first = TRUE;
219 ev_clipboard_text_from_file_t *event_data = (ev_clipboard_text_from_file_t *) data;
221 (void) event_group_name;
222 (void) event_name;
223 (void) init_data;
225 fname = mc_config_get_full_path (EDIT_CLIP_FILE);
226 f = fopen (fname, "r");
227 g_free (fname);
229 if (f == NULL)
231 event_data->ret = FALSE;
232 return TRUE;
235 *(event_data->text) = NULL;
237 while (fgets (buf, sizeof (buf), f))
239 size_t len;
241 len = strlen (buf);
242 if (len > 0)
244 if (buf[len - 1] == '\n')
245 buf[len - 1] = '\0';
247 if (first)
249 first = FALSE;
250 *(event_data->text) = g_strdup (buf);
252 else
254 /* remove \n on EOL */
255 char *tmp;
257 tmp = g_strconcat (*(event_data->text), " ", buf, (char *) NULL);
258 g_free (*(event_data->text));
259 *(event_data->text) = tmp;
264 fclose (f);
265 event_data->ret = (*(event_data->text) != NULL);
266 return TRUE;
269 /* --------------------------------------------------------------------------------------------- */