#include #include GtkWidget *window1; GtkWidget *textview1; GdkAtom atomString = GDK_NONE; GdkAtom atomTextHtml = GDK_NONE; #ifdef _WIN32 GdkAtom atomTextHtmlWin= GDK_NONE; #endif std::string g_strClipTxt; std::string g_strClipHtml; std::string g_strClipHtmlWin; void SuppressDefaultSignal(GtkWidget *widget, const char *szSignalName) { //FIX: this version throws a warning in console if the signal was not fired g_signal_stop_emission_by_name(widget, szSignalName); GSignalInvocationHint* hint = g_signal_get_invocation_hint(widget); if(hint) //has the code actually been invoked by a signal { gint signal_id = g_signal_lookup(szSignalName, G_OBJECT_TYPE (widget)); if (signal_id > 0){ gulong nSignal = g_signal_handler_find(widget, G_SIGNAL_MATCH_ID, signal_id, 0, 0, 0, 0); if(nSignal != 0){ if(g_signal_has_handler_pending(widget, signal_id, 0, true)) g_signal_stop_emission (widget, signal_id, 0); } } } } extern "C" void MyGtkClipboardGetFunc(GtkClipboard *clipboard, GtkSelectionData *selection_data, guint info, gpointer user_data_or_owner) { GdkAtom atSelTarget = gtk_selection_data_get_target(selection_data); if(atSelTarget == atomTextHtml) { gtk_selection_data_set (selection_data, atomTextHtml, 8, (guchar *)g_strClipHtml.c_str(), g_strClipHtml.size()); } #ifdef _WIN32 else if(atSelTarget == atomTextHtmlWin) { gtk_selection_data_set (selection_data, atomTextHtmlWin, 8, (guchar *)g_strClipHtmlWin.c_str(), g_strClipHtmlWin.size()); } #endif else { gtk_selection_data_set_text (selection_data, g_strClipTxt.c_str(), -1); } } void on_copy1_activate (GtkMenuItem *menuitem, gpointer user_data) { //suppress default handler (copies plain text only) SuppressDefaultSignal(textview1, "copy_clipboard"); //init data to be pushed g_strClipTxt = "Some text"; g_strClipHtml = "Some text"; //g_strClipHtmlWin = ""; //initiate clipboard transfer GtkTargetList *list = gtk_target_list_new (NULL, 0); if(!g_strClipTxt.empty()){ gtk_target_list_add(list, gdk_atom_intern("TEXT", FALSE), 0, 0); gtk_target_list_add(list, gdk_atom_intern("UTF8_STRING", FALSE), 0, 0); gtk_target_list_add(list, gdk_atom_intern("STRING", FALSE), 0, 0); } if(!g_strClipHtml.empty()){ gtk_target_list_add(list, atomTextHtml, 0, 0); } #ifdef _WIN32 if(!g_strClipHtmlWin.empty()){ gtk_target_list_add(list, atomTextHtmlWin, 0, 0); } #endif int nTargetCnt = 0; GtkTargetEntry *targets = gtk_target_table_new_from_list(list, &nTargetCnt); if(nTargetCnt < 1){ gtk_target_table_free(targets, nTargetCnt); gtk_target_list_unref (list); return; //nothing to export } GdkDisplay *display = gtk_widget_get_display (textview1); GtkClipboard *clipboard = gtk_clipboard_get_for_display (display, GDK_SELECTION_CLIPBOARD); gboolean bOK = gtk_clipboard_set_with_data(clipboard, targets, nTargetCnt, MyGtkClipboardGetFunc, NULL, 0); if(bOK){ gtk_clipboard_set_can_store (clipboard, NULL, 0); } gtk_target_table_free(targets, nTargetCnt); gtk_target_list_unref (list); } void create_gui() { window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window1), "Clipboard test"); gtk_window_set_default_size (GTK_WINDOW (window1), 500, 350); gtk_widget_show (window1); GtkWidget *vbox1 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox1); gtk_container_add (GTK_CONTAINER (window1), vbox1); GtkWidget *scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL); gtk_widget_show (scrolledwindow1); gtk_container_add (GTK_CONTAINER (vbox1), scrolledwindow1); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); GtkTextBuffer *buffer = gtk_text_buffer_new (NULL); textview1 = gtk_text_view_new_with_buffer (buffer); gtk_widget_show (textview1); gtk_container_add (GTK_CONTAINER (scrolledwindow1), textview1); g_signal_connect (textview1, "copy-clipboard", G_CALLBACK (on_copy1_activate), NULL); g_signal_connect (window1, "destroy", G_CALLBACK (gtk_main_quit), NULL); atomString = gdk_atom_intern("STRING", FALSE); atomTextHtml = gdk_atom_intern_static_string("text/html"); #ifdef _WIN32 atomTextHtmlWin = gdk_atom_intern_static_string("HTML Format"); #endif } int main (int argc, char *argv[]) { gtk_init (&argc, &argv); create_gui(); gtk_main (); return 0; } #ifdef _WIN32 #include int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { return main( __argc, __argv ); } #endif