Merge branch '4524_cleanup'
[midnight-commander.git] / src / clipboard.c
bloba9197929c31d562af08b1da4f1927ef2934e87b8
1 /*
2 Util for external clipboard.
4 Copyright (C) 2009-2024
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>
33 #include "lib/global.h"
34 #include "lib/fileloc.h"
35 #include "lib/mcconfig.h"
36 #include "lib/util.h"
37 #include "lib/event.h"
39 #include "lib/vfs/vfs.h"
41 #include "src/execute.h"
43 #include "clipboard.h"
45 /*** global variables ****************************************************************************/
47 /* path to X clipboard utility */
48 char *clipboard_store_path = NULL;
49 char *clipboard_paste_path = NULL;
51 /*** file scope macro definitions ****************************************************************/
53 /*** file scope type declarations ****************************************************************/
55 /*** forward declarations (file scope functions) *************************************************/
57 /*** file scope variables ************************************************************************/
59 static const int clip_open_flags = O_CREAT | O_WRONLY | O_TRUNC | O_BINARY;
60 static const mode_t clip_open_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
62 /* --------------------------------------------------------------------------------------------- */
63 /*** file scope functions ************************************************************************/
64 /* --------------------------------------------------------------------------------------------- */
66 /* --------------------------------------------------------------------------------------------- */
67 /*** public functions ****************************************************************************/
68 /* --------------------------------------------------------------------------------------------- */
70 /* event callback */
71 gboolean
72 clipboard_file_to_ext_clip (const gchar * event_group_name, const gchar * event_name,
73 gpointer init_data, gpointer data)
75 char *tmp, *cmd;
77 (void) event_group_name;
78 (void) event_name;
79 (void) init_data;
80 (void) data;
82 if (clipboard_store_path == NULL || clipboard_store_path[0] == '\0')
83 return TRUE;
85 tmp = mc_config_get_full_path (EDIT_HOME_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.shell->path, 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;
106 (void) event_group_name;
107 (void) event_name;
108 (void) init_data;
109 (void) data;
111 if (clipboard_paste_path == NULL || clipboard_paste_path[0] == '\0')
112 return TRUE;
114 p = mc_popen (clipboard_paste_path, TRUE, TRUE, NULL);
115 if (p == NULL)
116 return TRUE; /* don't show error message */
118 p->out.null_term = FALSE;
119 p->err.null_term = TRUE;
121 while (TRUE)
123 GError *error = NULL;
125 p->out.len = MC_PIPE_BUFSIZE;
126 p->err.len = MC_PIPE_BUFSIZE;
128 mc_pread (p, &error);
130 if (error != NULL)
132 /* don't show error message */
133 g_error_free (error);
134 break;
137 /* ignore stderr and get stdout */
138 if (p->out.len == MC_PIPE_STREAM_EOF || p->out.len == MC_PIPE_ERROR_READ)
139 break;
141 if (p->out.len > 0)
143 ssize_t nwrite;
145 if (file < 0)
147 vfs_path_t *fname_vpath;
149 fname_vpath = mc_config_get_full_vpath (EDIT_HOME_CLIP_FILE);
150 file = mc_open (fname_vpath, clip_open_flags, clip_open_mode);
151 vfs_path_free (fname_vpath, TRUE);
153 if (file < 0)
154 break;
157 nwrite = mc_write (file, p->out.buf, p->out.len);
158 (void) nwrite;
162 if (file >= 0)
163 mc_close (file);
165 mc_pclose (p, NULL);
167 return TRUE;
170 /* --------------------------------------------------------------------------------------------- */
172 /* event callback */
173 gboolean
174 clipboard_text_to_file (const gchar * event_group_name, const gchar * event_name,
175 gpointer init_data, gpointer data)
177 int file;
178 vfs_path_t *fname_vpath = NULL;
179 size_t str_len;
180 const char *text = (const char *) data;
182 (void) event_group_name;
183 (void) event_name;
184 (void) init_data;
186 if (text == NULL)
187 return FALSE;
189 fname_vpath = mc_config_get_full_vpath (EDIT_HOME_CLIP_FILE);
190 file = mc_open (fname_vpath, clip_open_flags, clip_open_mode);
191 vfs_path_free (fname_vpath, TRUE);
193 if (file == -1)
194 return TRUE;
196 str_len = strlen (text);
198 ssize_t ret;
200 ret = mc_write (file, text, str_len);
201 (void) ret;
203 mc_close (file);
204 return TRUE;
207 /* --------------------------------------------------------------------------------------------- */
209 /* event callback */
210 gboolean
211 clipboard_text_from_file (const gchar * event_group_name, const gchar * event_name,
212 gpointer init_data, gpointer data)
214 char buf[BUF_LARGE];
215 FILE *f;
216 char *fname = NULL;
217 gboolean first = TRUE;
218 ev_clipboard_text_from_file_t *event_data = (ev_clipboard_text_from_file_t *) data;
220 (void) event_group_name;
221 (void) event_name;
222 (void) init_data;
224 fname = mc_config_get_full_path (EDIT_HOME_CLIP_FILE);
225 f = fopen (fname, "r");
226 g_free (fname);
228 if (f == NULL)
230 event_data->ret = FALSE;
231 return TRUE;
234 *(event_data->text) = NULL;
236 while (fgets (buf, sizeof (buf), f))
238 size_t len;
240 len = strlen (buf);
241 if (len > 0)
243 if (buf[len - 1] == '\n')
244 buf[len - 1] = '\0';
246 if (first)
248 first = FALSE;
249 *(event_data->text) = g_strdup (buf);
251 else
253 /* remove \n on EOL */
254 char *tmp;
256 tmp = g_strconcat (*(event_data->text), " ", buf, (char *) NULL);
257 g_free (*(event_data->text));
258 *(event_data->text) = tmp;
263 fclose (f);
264 event_data->ret = (*(event_data->text) != NULL);
265 return TRUE;
268 /* --------------------------------------------------------------------------------------------- */