root/src/clipboard.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. clipboard_file_to_ext_clip
  2. clipboard_file_from_ext_clip
  3. clipboard_text_to_file
  4. clipboard_text_from_file

   1 /*
   2    Util for external clipboard.
   3 
   4    Copyright (C) 2009-2024
   5    Free Software Foundation, Inc.
   6 
   7    Written by:
   8    Ilia Maslakov <il.smind@gmail.com>, 2010.
   9    Andrew Borodin <aborodin@vmail.ru>, 2014.
  10 
  11    This file is part of the Midnight Commander.
  12 
  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.
  17 
  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.
  22 
  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/>.
  25  */
  26 
  27 #include <config.h>
  28 
  29 #include <stdio.h>
  30 #include <stdlib.h>
  31 #include <sys/types.h>
  32 
  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"
  38 
  39 #include "lib/vfs/vfs.h"
  40 
  41 #include "src/execute.h"
  42 
  43 #include "clipboard.h"
  44 
  45 /*** global variables ****************************************************************************/
  46 
  47 /* path to X clipboard utility */
  48 char *clipboard_store_path = NULL;
  49 char *clipboard_paste_path = NULL;
  50 
  51 /*** file scope macro definitions ****************************************************************/
  52 
  53 /*** file scope type declarations ****************************************************************/
  54 
  55 /*** forward declarations (file scope functions) *************************************************/
  56 
  57 /*** file scope variables ************************************************************************/
  58 
  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;
  61 
  62 /* --------------------------------------------------------------------------------------------- */
  63 /*** file scope functions ************************************************************************/
  64 /* --------------------------------------------------------------------------------------------- */
  65 
  66 /* --------------------------------------------------------------------------------------------- */
  67 /*** public functions ****************************************************************************/
  68 /* --------------------------------------------------------------------------------------------- */
  69 
  70 /* event callback */
  71 gboolean
  72 clipboard_file_to_ext_clip (const gchar *event_group_name, const gchar *event_name,
     /* [previous][next][first][last][top][bottom][index][help]  */
  73                             gpointer init_data, gpointer data)
  74 {
  75     char *tmp, *cmd;
  76 
  77     (void) event_group_name;
  78     (void) event_name;
  79     (void) init_data;
  80     (void) data;
  81 
  82     if (clipboard_store_path == NULL || clipboard_store_path[0] == '\0')
  83         return TRUE;
  84 
  85     tmp = mc_config_get_full_path (EDIT_HOME_CLIP_FILE);
  86     cmd = g_strconcat (clipboard_store_path, " ", tmp, " 2>/dev/null", (char *) NULL);
  87 
  88     if (cmd != NULL)
  89         my_system (EXECUTE_AS_SHELL, mc_global.shell->path, cmd);
  90 
  91     g_free (cmd);
  92     g_free (tmp);
  93     return TRUE;
  94 }
  95 
  96 /* --------------------------------------------------------------------------------------------- */
  97 
  98 /* event callback */
  99 gboolean
 100 clipboard_file_from_ext_clip (const gchar *event_group_name, const gchar *event_name,
     /* [previous][next][first][last][top][bottom][index][help]  */
 101                               gpointer init_data, gpointer data)
 102 {
 103     mc_pipe_t *p;
 104     int file = -1;
 105 
 106     (void) event_group_name;
 107     (void) event_name;
 108     (void) init_data;
 109     (void) data;
 110 
 111     if (clipboard_paste_path == NULL || clipboard_paste_path[0] == '\0')
 112         return TRUE;
 113 
 114     p = mc_popen (clipboard_paste_path, TRUE, TRUE, NULL);
 115     if (p == NULL)
 116         return TRUE;            /* don't show error message */
 117 
 118     p->out.null_term = FALSE;
 119     p->err.null_term = TRUE;
 120 
 121     while (TRUE)
 122     {
 123         GError *error = NULL;
 124 
 125         p->out.len = MC_PIPE_BUFSIZE;
 126         p->err.len = MC_PIPE_BUFSIZE;
 127 
 128         mc_pread (p, &error);
 129 
 130         if (error != NULL)
 131         {
 132             /* don't show error message */
 133             g_error_free (error);
 134             break;
 135         }
 136 
 137         /* ignore stderr and get stdout */
 138         if (p->out.len == MC_PIPE_STREAM_EOF || p->out.len == MC_PIPE_ERROR_READ)
 139             break;
 140 
 141         if (p->out.len > 0)
 142         {
 143             ssize_t nwrite;
 144 
 145             if (file < 0)
 146             {
 147                 vfs_path_t *fname_vpath;
 148 
 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);
 152 
 153                 if (file < 0)
 154                     break;
 155             }
 156 
 157             nwrite = mc_write (file, p->out.buf, p->out.len);
 158             (void) nwrite;
 159         }
 160     }
 161 
 162     if (file >= 0)
 163         mc_close (file);
 164 
 165     mc_pclose (p, NULL);
 166 
 167     return TRUE;
 168 }
 169 
 170 /* --------------------------------------------------------------------------------------------- */
 171 
 172 /* event callback */
 173 gboolean
 174 clipboard_text_to_file (const gchar *event_group_name, const gchar *event_name,
     /* [previous][next][first][last][top][bottom][index][help]  */
 175                         gpointer init_data, gpointer data)
 176 {
 177     int file;
 178     vfs_path_t *fname_vpath = NULL;
 179     size_t str_len;
 180     const char *text = (const char *) data;
 181 
 182     (void) event_group_name;
 183     (void) event_name;
 184     (void) init_data;
 185 
 186     if (text == NULL)
 187         return FALSE;
 188 
 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);
 192 
 193     if (file == -1)
 194         return TRUE;
 195 
 196     str_len = strlen (text);
 197     {
 198         ssize_t ret;
 199 
 200         ret = mc_write (file, text, str_len);
 201         (void) ret;
 202     }
 203     mc_close (file);
 204     return TRUE;
 205 }
 206 
 207 /* --------------------------------------------------------------------------------------------- */
 208 
 209 /* event callback */
 210 gboolean
 211 clipboard_text_from_file (const gchar *event_group_name, const gchar *event_name,
     /* [previous][next][first][last][top][bottom][index][help]  */
 212                           gpointer init_data, gpointer data)
 213 {
 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;
 219 
 220     (void) event_group_name;
 221     (void) event_name;
 222     (void) init_data;
 223 
 224     fname = mc_config_get_full_path (EDIT_HOME_CLIP_FILE);
 225     f = fopen (fname, "r");
 226     g_free (fname);
 227 
 228     if (f == NULL)
 229     {
 230         event_data->ret = FALSE;
 231         return TRUE;
 232     }
 233 
 234     *(event_data->text) = NULL;
 235 
 236     while (fgets (buf, sizeof (buf), f))
 237     {
 238         size_t len;
 239 
 240         len = strlen (buf);
 241         if (len > 0)
 242         {
 243             if (buf[len - 1] == '\n')
 244                 buf[len - 1] = '\0';
 245 
 246             if (first)
 247             {
 248                 first = FALSE;
 249                 *(event_data->text) = g_strdup (buf);
 250             }
 251             else
 252             {
 253                 /* remove \n on EOL */
 254                 char *tmp;
 255 
 256                 tmp = g_strconcat (*(event_data->text), " ", buf, (char *) NULL);
 257                 g_free (*(event_data->text));
 258                 *(event_data->text) = tmp;
 259             }
 260         }
 261     }
 262 
 263     fclose (f);
 264     event_data->ret = (*(event_data->text) != NULL);
 265     return TRUE;
 266 }
 267 
 268 /* --------------------------------------------------------------------------------------------- */

/* [previous][next][first][last][top][bottom][index][help]  */