Updated copyright text/header in most source files.
[geda-gaf/peter-b.git] / gschem / src / x_clipboard.c
blobb70fe3c81a1eabff99471e57a10c8be3631c525f
1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details)
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
19 #include <config.h>
21 #include <stdio.h>
22 #ifdef HAVE_STRING_H
23 #include <string.h>
24 #endif
25 #ifdef HAVE_UNISTD_H
26 #include <unistd.h>
27 #endif
29 #include "gschem.h"
31 #ifdef HAVE_LIBDMALLOC
32 #include <dmalloc.h>
33 #endif
35 #define MIME_TYPE_SCHEMATIC "application/x-geda-schematic"
36 #define CLIP_TYPE_SCHEMATIC 1
38 /* \brief Callback for handling system clipboard owner change.
39 * \par Function Description
42 static void
43 clip_handle_owner_change (GtkClipboard *cb, GdkEvent *event,
44 gpointer user_data)
46 GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL *) user_data;
48 i_update_menus (w_current);
51 static void
52 clip_get (GtkClipboard *cb, GtkSelectionData *selection_data,
53 guint info, gpointer user_data_or_owner)
55 GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL *) user_data_or_owner;
56 TOPLEVEL *toplevel = w_current->toplevel;
57 GdkAtom type = gdk_atom_intern (MIME_TYPE_SCHEMATIC, FALSE);
58 gchar *buf;
59 if (info != CLIP_TYPE_SCHEMATIC) return;
60 /* Convert the objects in the clipboard buffer to gEDA schematic
61 * format */
62 buf = o_save_buffer (toplevel, w_current->clipboard_buffer);
63 /* Set the selection appropriately */
64 gtk_selection_data_set (selection_data, type,
65 8, /* 8-bit data (UTF-8) */
66 (guchar *) buf,
67 (gint) strlen(buf));
68 g_free (buf);
71 static void
72 clip_clear (GtkClipboard *cb, gpointer user_data_or_owner)
74 GSCHEM_TOPLEVEL *w_current = user_data_or_owner;
75 TOPLEVEL *toplevel = w_current->toplevel;
77 /* Free the objects in the clipboard buffer */
78 s_delete_object_glist (toplevel, w_current->clipboard_buffer);
79 w_current->clipboard_buffer = NULL;
82 /* \brief Initialises system clipboard support
83 * \par Function Description
84 * Registers a signal handler to detect if the clipboard has changed
85 * and update the menu item sensitivity if necessary.
87 void
88 x_clipboard_init (GSCHEM_TOPLEVEL *w_current)
90 GtkClipboard *cb = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
91 g_signal_connect (G_OBJECT (cb),
92 "owner-change",
93 G_CALLBACK (clip_handle_owner_change),
94 w_current);
97 /* \brief Initialises system clipboard support
98 * \par Function Description
99 * Registers a signal handler to detect if the clipboard has changed
100 * and update the menu item sensitivity if necessary.
102 void
103 x_clipboard_finish (GSCHEM_TOPLEVEL *w_current)
105 GtkClipboard *cb = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
106 g_signal_handlers_disconnect_by_func (cb, clip_handle_owner_change, w_current);
107 if (w_current->clipboard_buffer)
108 gtk_clipboard_store (cb);
111 struct query_usable {
112 void (*callback) (int, void *);
113 void *userdata;
117 /* \brief Callback for determining if any clipboard targets are pastable
118 * \par Function Description
120 * Checks if the clipboard targets match any format we recognise, then
121 * calls back into a supplied callback function which is interested in
122 * the TRUE / FALSE answer to whether we can paste from the clipboard.
124 static void
125 query_usable_targets_cb (GtkClipboard *clip, GdkAtom *targets, gint ntargets,
126 gpointer data)
128 struct query_usable *cbinfo = data;
129 int i;
130 int is_usable = FALSE;
132 for (i = 0; i < ntargets; i++) {
133 if (strcmp (gdk_atom_name (targets[i]), MIME_TYPE_SCHEMATIC) == 0) {
134 is_usable = TRUE;
135 break;
139 cbinfo->callback (is_usable, cbinfo->userdata);
140 g_free (cbinfo);
144 /* \brief Checks if the system clipboard contains schematic data.
145 * \par Function Description
146 * Checks whether the current owner of the system clipboard is
147 * advertising gEDA schematic data.
149 * The check is performed asynchronously. When a response is
150 * recieved, the provided callback is called with a TRUE / FALSE
151 * result.
153 * \param [in] w_current The current GSCHEM_TOPLEVEL.
154 * \param [in] callback The callback to recieve the response.
155 * \param [in] userdata Arbitrary data to pass the callback.
157 void
158 x_clipboard_query_usable (GSCHEM_TOPLEVEL *w_current,
159 void (*callback) (int, void *), void *userdata)
161 GtkClipboard *clip = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
162 struct query_usable *cbinfo;
164 cbinfo = g_new (struct query_usable, 1);
165 cbinfo->callback = callback;
166 cbinfo->userdata = userdata;
168 gtk_clipboard_request_targets (clip, query_usable_targets_cb, cbinfo);
171 /* \brief Set the contents of the system clipboard.
172 * \par Function Description
173 * Set the system clipboard to contain the gschem objects listed in \a
174 * object_list.
176 * \param [in,out] w_current The current GSCHEM_TOPLEVEL.
177 * \param [in] object_list The objects to put in the clipboard.
179 * \return TRUE if the clipboard is successfully set.
181 gboolean
182 x_clipboard_set (GSCHEM_TOPLEVEL *w_current, const GList *object_list)
184 GtkClipboard *cb = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
185 GtkTargetEntry target = { MIME_TYPE_SCHEMATIC, 0,
186 CLIP_TYPE_SCHEMATIC };
187 TOPLEVEL *toplevel = w_current->toplevel;
188 gboolean result;
190 /* Clear the clipboard buffer */
191 if (w_current->clipboard_buffer)
192 gtk_clipboard_clear (cb);
194 /* Copy the objects to the clipboard buffer */
195 w_current->clipboard_buffer =
196 o_glist_copy_all (toplevel, object_list, w_current->clipboard_buffer,
197 SELECTION_FLAG);
199 /* Advertise that the data is available */
200 result = gtk_clipboard_set_with_data (cb, &target, 1,
201 clip_get, clip_clear, w_current);
203 /* Hint that the data can be stored to be accessed after the program
204 * has quit. */
205 gtk_clipboard_set_can_store (cb, NULL, 0);
207 return result;
210 /* \brief Get the contents of the system clipboard.
211 * \par Function Description
212 * If the system clipboard contains schematic data, retrieve it.
214 * \param [in,out] w_current The current GSCHEM_TOPLEVEL.
216 * \returns Any OBJECTs retrieved from the system clipboard, or NULL
217 * if none were available.
219 GList *
220 x_clipboard_get (GSCHEM_TOPLEVEL *w_current)
222 GtkClipboard *cb = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
223 TOPLEVEL *toplevel = w_current->toplevel;
224 GdkAtom type = gdk_atom_intern (MIME_TYPE_SCHEMATIC, FALSE);
225 GtkSelectionData *selection_data;
226 GList *object_list = NULL;
227 const guchar *buf;
229 /* Try to get the contents of the clipboard */
230 selection_data = gtk_clipboard_wait_for_contents (cb, type);
231 if (selection_data == NULL) return FALSE;
233 /* Convert the data buffer to OBJECTs */
234 #if GTK_CHECK_VERSION(2,14,0)
235 buf = gtk_selection_data_get_data (selection_data);
236 #else
237 buf = selection_data->data;
238 #endif
240 toplevel->ADDING_SEL = 1; /* HACK: Avoid adding objects to the tile system */
241 object_list = o_read_buffer (toplevel, object_list,
242 (gchar *) buf, -1, "Clipboard");
243 toplevel->ADDING_SEL = 0;
245 gtk_selection_data_free (selection_data);
246 return object_list;