Example #1
0
/* \brief Set the contents of the system clipboard.
 * \par Function Description
 * Set the system clipboard to contain the gschem objects listed in \a
 * object_list.
 *
 * \param [in,out] w_current   The current GSCHEM_TOPLEVEL.
 * \param [in]     object_list The objects to put in the clipboard.
 *
 * \return TRUE if the clipboard is successfully set.
 */
gboolean
x_clipboard_set (GSCHEM_TOPLEVEL *w_current, const GList *object_list)
{
  GtkClipboard *cb = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
  GtkTargetEntry target = { MIME_TYPE_SCHEMATIC, 0,
                            CLIP_TYPE_SCHEMATIC };
  TOPLEVEL *toplevel = w_current->toplevel;
  gboolean result;

  /* Clear the clipboard buffer */
  if (w_current->clipboard_buffer)
    gtk_clipboard_clear (cb);

  /* Copy the objects to the clipboard buffer */
  w_current->clipboard_buffer =
    o_glist_copy_all (toplevel, object_list, w_current->clipboard_buffer);

  /* Advertise that the data is available */
  result = gtk_clipboard_set_with_data (cb, &target, 1,
                                        clip_get, clip_clear, w_current);

  /* Hint that the data can be stored to be accessed after the program
   * has quit. */
  gtk_clipboard_set_can_store (cb, NULL, 0);

  return result;
}
Example #2
0
void PasteboardHelper::writeClipboardContents(GtkClipboard* clipboard, SmartPasteInclusion includeSmartPaste, GClosure* callback)
{
    DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard);
    GtkTargetList* list = targetListForDataObject(dataObject, includeSmartPaste);

    int numberOfTargets;
    GtkTargetEntry* table = gtk_target_table_new_from_list(list, &numberOfTargets);

    if (numberOfTargets > 0 && table) {
        settingClipboardDataObject = dataObject;

        if (gtk_clipboard_set_with_data(clipboard, table, numberOfTargets, getClipboardContentsCallback, clearClipboardContentsCallback, callback ? g_closure_ref(callback) : nullptr))
            gtk_clipboard_set_can_store(clipboard, nullptr, 0);
        else {
            // When gtk_clipboard_set_with_data fails the callbacks are ignored, so we need to release the reference we were passing to clearClipboardContentsCallback.
            if (callback)
                g_closure_unref(callback);
        }

        settingClipboardDataObject = nullptr;

    } else
        gtk_clipboard_clear(clipboard);

    if (table)
        gtk_target_table_free(table, numberOfTargets);
    gtk_target_list_unref(list);
}
Example #3
0
void fd_clipboard_init()
{
	/* tell the clipboard manager to make the data persistent */
	clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
	/* GDK_SELECTION_PRIMARY, CLIPBOARD */
	gtk_clipboard_set_can_store(clipboard, NULL, 0);
	timer_id = g_timeout_add(100, timeout_func, NULL);
}
Example #4
0
void sys_set_clipboard_text(void *user, const char *text)
{
    GtkClipboard *cb;
    gtk_init_check(NULL, NULL);
    cb = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
    gtk_clipboard_set_can_store(cb, NULL, 0);
    gtk_clipboard_set_text(cb, text, -1);
    gtk_clipboard_store(cb);
}
Example #5
0
static VALUE
rg_set_can_store(VALUE self, VALUE rbtargets)
{
    GtkClipboard *clipboard = _SELF(self);
    long n = 0;
    GtkTargetEntry *targets = RVAL2GTKTARGETENTRIES_ACCEPT_NIL(rbtargets, &n);

    gtk_clipboard_set_can_store(clipboard, targets, n);

    g_free(targets);

    return self;
}
Example #6
0
void on_menu_cal_click(GtkMenuItem *item,
                       gpointer data)
{
  const gchar *today_text;
  GtkClipboard *clipboard;
  
  today_text = gtk_menu_item_get_label(item);
  
  /* tell the clipboard manager to make the data persistent */
  clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
  gtk_clipboard_set_can_store(clipboard, NULL, 0);
  
  /* set clipboard text */
  gtk_clipboard_set_text(clipboard, today_text, -1);
}
Example #7
0
/**
 * gimp_clipboard_set_buffer:
 * @gimp:   pointer to #Gimp
 * @buffer: a #GimpBuffer, or %NULL.
 *
 * Offers the buffer in %GDK_SELECTION_CLIPBOARD.
 **/
void
gimp_clipboard_set_buffer (Gimp       *gimp,
                           GimpBuffer *buffer)
{
  GimpClipboard *gimp_clip;
  GtkClipboard  *clipboard;

  g_return_if_fail (GIMP_IS_GIMP (gimp));
  g_return_if_fail (buffer == NULL || GIMP_IS_BUFFER (buffer));

  clipboard = gtk_clipboard_get_for_display (gdk_display_get_default (),
                                             GDK_SELECTION_CLIPBOARD);
  if (! clipboard)
    return;

  gimp_clip = gimp_clipboard_get (gimp);

  gimp_clipboard_clear (gimp_clip);

  if (buffer)
    {
      gimp_clip->buffer = g_object_ref (buffer);

      gtk_clipboard_set_with_owner (clipboard,
                                    gimp_clip->target_entries,
                                    gimp_clip->n_target_entries,
                                    (GtkClipboardGetFunc) gimp_clipboard_send_buffer,
                                    (GtkClipboardClearFunc) NULL,
                                    G_OBJECT (gimp));

      /*  mark the first entry (image/png) as suitable for storing  */
      gtk_clipboard_set_can_store (clipboard, gimp_clip->target_entries, 1);
    }
  else if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (gimp))
    {
      gtk_clipboard_clear (clipboard);
    }
}
Example #8
0
/**
 * gimp_clipboard_set_svg:
 * @gimp: pointer to #Gimp
 * @svg: a string containing the SVG data, or %NULL
 *
 * Offers SVG data in %GDK_SELECTION_CLIPBOARD.
 **/
void
gimp_clipboard_set_svg (Gimp        *gimp,
                        const gchar *svg)
{
  GimpClipboard *gimp_clip;
  GtkClipboard  *clipboard;

  g_return_if_fail (GIMP_IS_GIMP (gimp));

  clipboard = gtk_clipboard_get_for_display (gdk_display_get_default (),
                                             GDK_SELECTION_CLIPBOARD);
  if (! clipboard)
    return;

  gimp_clip = gimp_clipboard_get (gimp);

  gimp_clipboard_clear (gimp_clip);

  if (svg)
    {
      gimp_clip->svg = g_strdup (svg);

      gtk_clipboard_set_with_owner (clipboard,
                                    gimp_clip->svg_target_entries,
                                    gimp_clip->n_svg_target_entries,
                                    (GtkClipboardGetFunc) gimp_clipboard_send_svg,
                                    (GtkClipboardClearFunc) NULL,
                                    G_OBJECT (gimp));

      /*  mark the first entry (image/svg) as suitable for storing  */
      gtk_clipboard_set_can_store (clipboard, gimp_clip->svg_target_entries, 1);
    }
  else if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (gimp))
    {
      gtk_clipboard_clear (clipboard);
    }
}
    void SetupClipboardContentTypes()
    {
        GtkTargetList* list = gtk_target_list_new(NULL, 0);

        // TODO: Support for images
        if (!this->text && !this->uris)
            return;

        if (this->text)
            gtk_target_list_add_text_targets(list, ClipboardPrivate::TEXT_DATA);

        if (this->uris)
            gtk_target_list_add_uri_targets(list, ClipboardPrivate::URI_LIST_DATA);

        int size = 0;
        GtkTargetEntry* table = gtk_target_table_new_from_list(list, &size);
        if (table)
        {
            // gtk_clipboard_set_with_data may try to clear our clipboard when we
            // call it, so we turn on a flag here which prevents our clipboard data
            // from being freed during this call.
            this->preserve = true;
            GtkClipboard* clipboard = GetClipboard();
            if (gtk_clipboard_set_with_data(clipboard, table, size, GetClipboardData,
                ClearClipboardData, NULL))
            {
                this->ownClipboard = true;
                gtk_clipboard_set_can_store(clipboard, NULL, 0);
            }
            this->preserve = false;

            gtk_target_table_free(table, size);
        }

        gtk_target_list_unref(list);
    }
Example #10
0
void PasteboardHelper::writeClipboardContents(GtkClipboard* clipboard, GClosure* callback)
{
    DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard);
    GtkTargetList* list = targetListForDataObject(dataObject);

    int numberOfTargets;
    GtkTargetEntry* table = gtk_target_table_new_from_list(list, &numberOfTargets);

    if (numberOfTargets > 0 && table) {
        settingClipboardDataObject = dataObject;

        gtk_clipboard_set_with_data(clipboard, table, numberOfTargets,
            getClipboardContentsCallback, clearClipboardContentsCallback, callback);
        gtk_clipboard_set_can_store(clipboard, 0, 0);

        settingClipboardDataObject = 0;

    } else
        gtk_clipboard_clear(clipboard);

    if (table)
        gtk_target_table_free(table, numberOfTargets);
    gtk_target_list_unref(list);
}
Example #11
0
void uploader_curl_file (void **apFilesPaths , int ListCount) {

	void *pChoosedFile = NULL;
	char *FileName = NULL;
	long long FileSize = 0;
	double TotalTime = 0;
	double BatchTotalTime = 0;
	float BatchSize = 0;
	char buff[256];
	bool CancelReq = false;
	int i, UpDone = 0;

	if(access(PathCurlOut, F_OK ) != -1)
		remove(PathCurlOut);
	if(ListCount == 0)
		return;

	BatchLinks = (char*) realloc(BatchLinks,(ListCount*sizeof(RegexMatchURL)));
	if(BatchLinks == NULL)
			log_error(true,"***Error: Memory error @ L62 - pomfit.c");

	for(i = 0 ; i < ListCount; ++i) {

		pChoosedFile = apFilesPaths[i];
		if(pomfit_check_size(pChoosedFile,ActiveProfile.MaxSize) == 1)
			continue;

		CURL *curl;
		CURLcode res;
		struct curl_httppost *post = NULL;
		struct curl_httppost *last = NULL;
		pChoosedFile = apFilesPaths[i];
		FILE *pUploadFile = fopen(pChoosedFile, "rb");
		if(!pUploadFile) {

			log_error(true,"***Error: Uploader failed to read file %s",pChoosedFile);
			pChoosedFile = NULL;
			return;
		} else {

			fseek(pUploadFile, 0 , SEEK_END);
			FileSize = ftell(pUploadFile);
			rewind(pUploadFile);
		}
		FILE *pOutputFile;
		pOutputFile = fopen(PathCurlOut, "a");
		if(!pOutputFile) {

			log_error(true,"***Error: Uploader failed to create output file %s",PathCurlOut);
			if(pUploadFile)
				fclose(pUploadFile);
			return;
		}
		/// Get name from filepath
		#ifdef __linux__
		FileName = strrchr(pChoosedFile, '/');
		#elif _WIN32
		FileName = strrchr(pChoosedFile, '\\');
		#endif
		FileName += 1;
		gtk_button_set_relief(GTK_BUTTON(up_but), GTK_RELIEF_NONE);
		gtk_button_set_label(GTK_BUTTON(up_but), "Cancel");
		IsUploading = TRUE;

		TimeUpStarted = time(NULL);
		curl = curl_easy_init();
		if(curl)
		{
			if(ActiveProfile.bFormName) {
				char *Suffix = strrchr(FileName, '.');
				char CustomFileName[512];
				sprintf(CustomFileName, "%s%s",ActiveProfile.FormFileName,Suffix);
				printf("%s\n",CustomFileName);
				curl_formadd(&post, &last,
					CURLFORM_COPYNAME, ActiveProfile.FormName,
					CURLFORM_FILE, pChoosedFile,
					CURLFORM_FILENAME, CustomFileName,
					CURLFORM_CONTENTTYPE, ActiveProfile.FormType,
					CURLFORM_END);

			} else if (!ActiveProfile.bNames){
				curl_formadd(&post, &last,
					CURLFORM_COPYNAME, ActiveProfile.FormName,
					CURLFORM_FILE, pChoosedFile,
					CURLFORM_FILENAME, "Pomfit_Upload",
					CURLFORM_CONTENTTYPE, ActiveProfile.FormType,
					CURLFORM_END);
			} else {
				curl_formadd(&post, &last,
					CURLFORM_COPYNAME, ActiveProfile.FormName,
					CURLFORM_FILE, pChoosedFile,
					CURLFORM_CONTENTTYPE, ActiveProfile.FormType,
					CURLFORM_END);
			}
			curl_easy_setopt(curl, CURLOPT_URL, ActiveProfile.URL);
			curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
			curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, uploader_curl_progress);
			curl_easy_setopt(curl, CURLOPT_READDATA, pUploadFile);
			curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
                     (curl_off_t)FileSize);
			curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
			curl_easy_setopt(curl, CURLOPT_USERAGENT, POMFIT_USER_AGENT);

			curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, true);
			curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L);
			curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
			curl_easy_setopt(curl, CURLOPT_WRITEDATA, pOutputFile);
			if(ActiveProfile.bCookie) {
				curl_easy_setopt(curl, CURLOPT_COOKIESESSION, TRUE);
				curl_easy_setopt(curl, CURLOPT_COOKIEJAR, PathCookie);
				curl_easy_setopt(curl, CURLOPT_COOKIEFILE, PathCookie);
			}
			res = curl_easy_perform(curl);
			if(res != CURLE_OK) {

				log_error(true, "***Error: curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
				if(ListCount == 1 || strstr(curl_easy_strerror(res),"aborted") || CancelReq) {

					gtk_statusbar_push(GTK_STATUSBAR(status_bar),
										1,"Uploading canceled.");
					gtk_button_set_relief(GTK_BUTTON(up_but),
											GTK_RELIEF_NORMAL);
					gtk_button_set_label(GTK_BUTTON(up_but), "Upload");
					IsUploading = FALSE;
					pomfit_notify(curl_easy_strerror(res),"Uploading canceled");
					pChoosedFile = NULL;
					if(pUploadFile)
						fclose(pUploadFile);
					if(pOutputFile)
						fclose(pOutputFile);
					curl_formfree(post);
					curl_easy_cleanup(curl);
					if(remove(PathCurlOut) != 0)
                        perror("Error deleting temp file");

					return;
				} else {

                    pChoosedFile = NULL;
					if(pUploadFile)
						fclose(pUploadFile);
					if(pOutputFile)
						fclose(pOutputFile);
					curl_formfree(post);
					curl_easy_cleanup(curl);
					CancelReq = true;
					continue;
                }
			} else {
				fprintf(pOutputFile,"\n");
				BatchSize += (float)FileSize/1000000;;
				UpDone += 1;
			}
			curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &TotalTime);
			curl_formfree(post);
			curl_easy_cleanup(curl);
			BatchTotalTime += TotalTime;
		}
		fclose(pOutputFile);
		if(pUploadFile)
			fclose(pUploadFile);

		if (uploader_curl_output(PathCurlOut,pChoosedFile) == 0) {

			if(i == 0)
				sprintf(BatchLinks,"%s ", RegexMatchURL);
			else
				sprintf(strchr(BatchLinks, '\0'),"%s ", RegexMatchURL);


			RegexMatchURL[0] = '\0';
			RegexMatchDEL[0] = '\0';

		}
	}
	if(UpDone == 0)
		return;
    sprintf(buff, "%d File%s(%.2f MB) in %dmin %dsec",
				UpDone,UpDone < 2 ? "" : "s",BatchSize ,
				(int)BatchTotalTime > 60 ? (int)BatchTotalTime/60 : 0,
				(int)BatchTotalTime%60 > 0 ? (int)BatchTotalTime%60 : 1);
	GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
	gtk_clipboard_set_can_store (clipboard,NULL,0);
	gtk_clipboard_set_text(clipboard, BatchLinks, strlen(BatchLinks)-1);
	gtk_clipboard_store(clipboard);
	gtk_statusbar_push (GTK_STATUSBAR(status_bar), 1, buff);
	sprintf(strchr(buff, '\0'),"\nLink%s copied to clipboard ", UpDone < 2 ? "" : "s");
	pomfit_notify(buff,"Uploading Finished");
	sprintf(buff,"Click to open all links.\nRight click to copy links.");
	gtk_widget_set_tooltip_text(link_but, buff);
	gtk_link_button_set_uri(GTK_LINK_BUTTON(link_but), BatchLinks);
	sprintf(buff,"%d/%d File%s Uploaded",
				UpDone, ListCount, UpDone < 2 ? "" : "s");
	gtk_button_set_label(GTK_BUTTON(link_but), buff);
	gtk_button_set_relief(GTK_BUTTON(up_but), GTK_RELIEF_NORMAL);
	gtk_button_set_label(GTK_BUTTON(up_but), "Upload");
	IsUploading = FALSE;

	pChoosedFile = NULL;
	for(i = 0 ; i < ListCount; ++i)
		apFilesPaths[i] = NULL;

}
NS_IMETHODIMP
nsClipboard::SetData(nsITransferable *aTransferable,
                     nsIClipboardOwner *aOwner, PRInt32 aWhichClipboard)
{
    // See if we can short cut
    if ((aWhichClipboard == kGlobalClipboard &&
         aTransferable == mGlobalTransferable.get() &&
         aOwner == mGlobalOwner.get()) ||
        (aWhichClipboard == kSelectionClipboard &&
         aTransferable == mSelectionTransferable.get() &&
         aOwner == mSelectionOwner.get())) {
        return NS_OK;
    }

    nsresult rv;
    if (!mPrivacyHandler) {
        rv = NS_NewClipboardPrivacyHandler(getter_AddRefs(mPrivacyHandler));
        NS_ENSURE_SUCCESS(rv, rv);
    }
    rv = mPrivacyHandler->PrepareDataForClipboard(aTransferable);
    NS_ENSURE_SUCCESS(rv, rv);

    // Clear out the clipboard in order to set the new data
    EmptyClipboard(aWhichClipboard);

    // List of suported targets
    GtkTargetList *list = gtk_target_list_new(NULL, 0);

    // Get the types of supported flavors
    nsCOMPtr<nsISupportsArray> flavors;

    rv = aTransferable->FlavorsTransferableCanExport(getter_AddRefs(flavors));
    if (!flavors || NS_FAILED(rv))
        return NS_ERROR_FAILURE;

    // Add all the flavors to this widget's supported type.
    PRBool imagesAdded = PR_FALSE;
    PRUint32 count;
    flavors->Count(&count);
    for (PRUint32 i=0; i < count; i++) {
        nsCOMPtr<nsISupports> tastesLike;
        flavors->GetElementAt(i, getter_AddRefs(tastesLike));
        nsCOMPtr<nsISupportsCString> flavor = do_QueryInterface(tastesLike);

        if (flavor) {
            nsXPIDLCString flavorStr;
            flavor->ToString(getter_Copies(flavorStr));

            // special case text/unicode since we can handle all of
            // the string types
            if (!strcmp(flavorStr, kUnicodeMime)) {
                gtk_target_list_add(list, gdk_atom_intern("UTF8_STRING", FALSE), 0, 0);
                gtk_target_list_add(list, gdk_atom_intern("COMPOUND_TEXT", FALSE), 0, 0);
                gtk_target_list_add(list, gdk_atom_intern("TEXT", FALSE), 0, 0);
                gtk_target_list_add(list, GDK_SELECTION_TYPE_STRING, 0, 0);
                continue;
            }

            if (flavorStr.EqualsLiteral(kNativeImageMime) ||
                flavorStr.EqualsLiteral(kPNGImageMime) ||
                flavorStr.EqualsLiteral(kJPEGImageMime) ||
                flavorStr.EqualsLiteral(kGIFImageMime)) {
                // don't bother adding image targets twice
                if (!imagesAdded) {
                    // accept any writable image type
                    gtk_target_list_add_image_targets(list, 0, TRUE);
                    imagesAdded = PR_TRUE;
                }
                continue;
            }

            // Add this to our list of valid targets
            GdkAtom atom = gdk_atom_intern(flavorStr, FALSE);
            gtk_target_list_add(list, atom, 0, 0);
        }
    }
    
    // Get GTK clipboard (CLIPBOARD or PRIMARY)
    GtkClipboard *gtkClipboard = gtk_clipboard_get(GetSelectionAtom(aWhichClipboard));
  
    gint numTargets;
    GtkTargetEntry *gtkTargets = gtk_target_table_new_from_list(list, &numTargets);
          
    // Set getcallback and request to store data after an application exit
    if (gtk_clipboard_set_with_data(gtkClipboard, gtkTargets, numTargets, 
                                    clipboard_get_cb, clipboard_clear_cb, this))
    {
        // We managed to set-up the clipboard so update internal state
        // We have to set it now because gtk_clipboard_set_with_data() calls clipboard_clear_cb()
        // which reset our internal state 
        if (aWhichClipboard == kSelectionClipboard) {
            mSelectionOwner = aOwner;
            mSelectionTransferable = aTransferable;
        }
        else {
            mGlobalOwner = aOwner;
            mGlobalTransferable = aTransferable;
            gtk_clipboard_set_can_store(gtkClipboard, gtkTargets, numTargets);
        }

        rv = NS_OK;
    }
    else {  
        rv = NS_ERROR_FAILURE;
    }

    gtk_target_table_free(gtkTargets, numTargets);
    gtk_target_list_unref(list);
  
    return rv;
}
Example #13
0
GtkWidget *
do_clipboard (GtkWidget *do_widget)
{
  if (!window)
    {
      GtkWidget *vbox, *hbox;
      GtkWidget *label;
      GtkWidget *entry, *button;
      GtkWidget *ebox, *image;
      GtkClipboard *clipboard;

      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_window_set_screen (GTK_WINDOW (window),
                             gtk_widget_get_screen (do_widget));
      gtk_window_set_title (GTK_WINDOW (window), "Clipboard demo");

      g_signal_connect (window, "destroy",
                        G_CALLBACK (gtk_widget_destroyed), &window);

      vbox = gtk_vbox_new (FALSE, 0);
      gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);

      gtk_container_add (GTK_CONTAINER (window), vbox);

      label = gtk_label_new ("\"Copy\" will copy the text\nin the entry to the clipboard");

      gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);

      hbox = gtk_hbox_new (FALSE, 4);
      gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
      gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);

      /* Create the first entry */
      entry = gtk_entry_new ();
      gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);

      /* Create the button */
      button = gtk_button_new_from_stock (GTK_STOCK_COPY);
      gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
      g_signal_connect (button, "clicked",
                        G_CALLBACK (copy_button_clicked), entry);

      label = gtk_label_new ("\"Paste\" will paste the text from the clipboard to the entry");
      gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);

      hbox = gtk_hbox_new (FALSE, 4);
      gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
      gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);

      /* Create the second entry */
      entry = gtk_entry_new ();
      gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);

      /* Create the button */
      button = gtk_button_new_from_stock (GTK_STOCK_PASTE);
      gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
      g_signal_connect (button, "clicked",
                        G_CALLBACK (paste_button_clicked), entry);

      label = gtk_label_new ("Images can be transferred via the clipboard, too");
      gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);

      hbox = gtk_hbox_new (FALSE, 4);
      gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
      gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);

      /* Create the first image */
      image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING,
                                        GTK_ICON_SIZE_BUTTON);
      ebox = gtk_event_box_new ();
      gtk_container_add (GTK_CONTAINER (ebox), image);
      gtk_container_add (GTK_CONTAINER (hbox), ebox);

      /* make ebox a drag source */
      gtk_drag_source_set (ebox, GDK_BUTTON1_MASK, NULL, 0, GDK_ACTION_COPY);
      gtk_drag_source_add_image_targets (ebox);
      g_signal_connect (ebox, "drag-begin",
                        G_CALLBACK (drag_begin), image);
      g_signal_connect (ebox, "drag-data-get",
                        G_CALLBACK (drag_data_get), image);

      /* accept drops on ebox */
      gtk_drag_dest_set (ebox, GTK_DEST_DEFAULT_ALL,
                         NULL, 0, GDK_ACTION_COPY);
      gtk_drag_dest_add_image_targets (ebox);
      g_signal_connect (ebox, "drag-data-received",
                        G_CALLBACK (drag_data_received), image);

      /* context menu on ebox */
      g_signal_connect (ebox, "button-press-event",
                        G_CALLBACK (button_press), image);

      /* Create the second image */
      image = gtk_image_new_from_stock (GTK_STOCK_STOP,
                                        GTK_ICON_SIZE_BUTTON);
      ebox = gtk_event_box_new ();
      gtk_container_add (GTK_CONTAINER (ebox), image);
      gtk_container_add (GTK_CONTAINER (hbox), ebox);

      /* make ebox a drag source */
      gtk_drag_source_set (ebox, GDK_BUTTON1_MASK, NULL, 0, GDK_ACTION_COPY);
      gtk_drag_source_add_image_targets (ebox);
      g_signal_connect (ebox, "drag-begin",
                        G_CALLBACK (drag_begin), image);
      g_signal_connect (ebox, "drag-data-get",
                        G_CALLBACK (drag_data_get), image);

      /* accept drops on ebox */
      gtk_drag_dest_set (ebox, GTK_DEST_DEFAULT_ALL,
                         NULL, 0, GDK_ACTION_COPY);
      gtk_drag_dest_add_image_targets (ebox);
      g_signal_connect (ebox, "drag-data-received",
                        G_CALLBACK (drag_data_received), image);

      /* context menu on ebox */
      g_signal_connect (ebox, "button-press-event",
                        G_CALLBACK (button_press), image);

      /* tell the clipboard manager to make the data persistent */
      clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
      gtk_clipboard_set_can_store (clipboard, NULL, 0);
    }

  if (!gtk_widget_get_visible (window))
    gtk_widget_show_all (window);
  else
    {
      gtk_widget_destroy (window);
      window = NULL;
    }

  return window;
}