(edit_suggest_current_word): the NULL check is unnecessary...
[midnight-commander.git] / src / clipboard.c
blobc277ae66b7ea48790a6d68fb46fcd15fd67ea431
1 /*
2 Util for external clipboard.
4 Copyright (C) 2009-2020
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 /*** file scope variables ************************************************************************/
57 static const int clip_open_flags = O_CREAT | O_WRONLY | O_TRUNC | O_BINARY;
58 static const mode_t clip_open_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
60 /* --------------------------------------------------------------------------------------------- */
61 /*** file scope functions ************************************************************************/
62 /* --------------------------------------------------------------------------------------------- */
64 /* --------------------------------------------------------------------------------------------- */
65 /*** public functions ****************************************************************************/
66 /* --------------------------------------------------------------------------------------------- */
68 /* event callback */
69 gboolean
70 clipboard_file_to_ext_clip (const gchar * event_group_name, const gchar * event_name,
71 gpointer init_data, gpointer data)
73 char *tmp, *cmd;
75 (void) event_group_name;
76 (void) event_name;
77 (void) init_data;
78 (void) data;
80 if (clipboard_store_path == NULL || clipboard_store_path[0] == '\0')
81 return TRUE;
83 tmp = mc_config_get_full_path (EDIT_HOME_CLIP_FILE);
84 cmd = g_strconcat (clipboard_store_path, " ", tmp, " 2>/dev/null", (char *) NULL);
86 if (cmd != NULL)
87 my_system (EXECUTE_AS_SHELL, mc_global.shell->path, cmd);
89 g_free (cmd);
90 g_free (tmp);
91 return TRUE;
94 /* --------------------------------------------------------------------------------------------- */
96 /* event callback */
97 gboolean
98 clipboard_file_from_ext_clip (const gchar * event_group_name, const gchar * event_name,
99 gpointer init_data, gpointer data)
101 mc_pipe_t *p;
102 int file = -1;
104 (void) event_group_name;
105 (void) event_name;
106 (void) init_data;
107 (void) data;
109 if (clipboard_paste_path == NULL || clipboard_paste_path[0] == '\0')
110 return TRUE;
112 p = mc_popen (clipboard_paste_path, NULL);
113 if (p == NULL)
114 return TRUE; /* don't show error message */
116 p->out.null_term = FALSE;
117 p->err.null_term = TRUE;
119 while (TRUE)
121 GError *error = NULL;
123 p->out.len = MC_PIPE_BUFSIZE;
124 p->err.len = MC_PIPE_BUFSIZE;
126 mc_pread (p, &error);
128 if (error != NULL)
130 /* don't show error message */
131 g_error_free (error);
132 break;
135 /* ignore stderr and get stdout */
136 if (p->out.len == MC_PIPE_STREAM_EOF || p->out.len == MC_PIPE_ERROR_READ)
137 break;
139 if (p->out.len > 0)
141 ssize_t nwrite;
143 if (file < 0)
145 vfs_path_t *fname_vpath;
147 fname_vpath = mc_config_get_full_vpath (EDIT_HOME_CLIP_FILE);
148 file = mc_open (fname_vpath, clip_open_flags, clip_open_mode);
149 vfs_path_free (fname_vpath);
151 if (file < 0)
152 break;
155 nwrite = mc_write (file, p->out.buf, p->out.len);
156 (void) nwrite;
160 if (file >= 0)
161 mc_close (file);
163 mc_pclose (p, NULL);
165 return TRUE;
168 /* --------------------------------------------------------------------------------------------- */
170 /* event callback */
171 gboolean
172 clipboard_text_to_file (const gchar * event_group_name, const gchar * event_name,
173 gpointer init_data, gpointer data)
175 int file;
176 vfs_path_t *fname_vpath = NULL;
177 size_t str_len;
178 const char *text = (const char *) data;
180 (void) event_group_name;
181 (void) event_name;
182 (void) init_data;
184 if (text == NULL)
185 return FALSE;
187 fname_vpath = mc_config_get_full_vpath (EDIT_HOME_CLIP_FILE);
188 file = mc_open (fname_vpath, clip_open_flags, clip_open_mode);
189 vfs_path_free (fname_vpath);
191 if (file == -1)
192 return TRUE;
194 str_len = strlen (text);
196 ssize_t ret;
198 ret = mc_write (file, text, str_len);
199 (void) ret;
201 mc_close (file);
202 return TRUE;
205 /* --------------------------------------------------------------------------------------------- */
207 /* event callback */
208 gboolean
209 clipboard_text_from_file (const gchar * event_group_name, const gchar * event_name,
210 gpointer init_data, gpointer data)
212 char buf[BUF_LARGE];
213 FILE *f;
214 char *fname = NULL;
215 gboolean first = TRUE;
216 ev_clipboard_text_from_file_t *event_data = (ev_clipboard_text_from_file_t *) data;
218 (void) event_group_name;
219 (void) event_name;
220 (void) init_data;
222 fname = mc_config_get_full_path (EDIT_HOME_CLIP_FILE);
223 f = fopen (fname, "r");
224 g_free (fname);
226 if (f == NULL)
228 event_data->ret = FALSE;
229 return TRUE;
232 *(event_data->text) = NULL;
234 while (fgets (buf, sizeof (buf), f))
236 size_t len;
238 len = strlen (buf);
239 if (len > 0)
241 if (buf[len - 1] == '\n')
242 buf[len - 1] = '\0';
244 if (first)
246 first = FALSE;
247 *(event_data->text) = g_strdup (buf);
249 else
251 /* remove \n on EOL */
252 char *tmp;
254 tmp = g_strconcat (*(event_data->text), " ", buf, (char *) NULL);
255 g_free (*(event_data->text));
256 *(event_data->text) = tmp;
261 fclose (f);
262 event_data->ret = (*(event_data->text) != NULL);
263 return TRUE;
266 /* --------------------------------------------------------------------------------------------- */