#include<string.h> 
#include<stdlib.h> 

#include<gdk/gdk.h> 
#include<gtk/gtk.h> 
#include<gtk/gtkclipboard.h> 

/* Compile via: gcc postclip.c `pkg-config --cflags --libs gtk+-2.0` -o postclip
 * 
 * Note: if you encounter problems, check you are not running it via a remote terminal session!
 * 
 */
 
void clip_get(GtkClipboard *clip, GtkSelectionData *sel, guint info, gpointer user) 
{ 
    const char IMAGE[] = "image"; 
    GdkPixbuf* pixbuf = (GdkPixbuf*) user; 
    
    printf("GtkClipboardGetFunc callback invoked!\n"); 

    printf("Data request: \n"); 
    printf("\tSelectionData:\n"); 
    printf("\t.selection = %s\n", gdk_atom_name(sel->selection)); 
    printf("\t.target = %s\n", gdk_atom_name(sel->target)); 
    printf("\t.type = %s\n", gdk_atom_name(sel->type)); 
    printf("\n"); 
    printf("\tinfo = %d\n", info); 
    printf("\n"); 
    
    if (strncmp(gdk_atom_name(sel->target), IMAGE, strlen(IMAGE)) == 0) { 
        gtk_selection_data_set_pixbuf(sel, pixbuf); 
    } 
} 

void clip_clear(GtkClipboard *clip, gpointer user) { 
    printf("GtkClipboardClearFunc callback invoked!\n"); 
}


void owner_changed_cb(GtkClipboard *clipboard,
                      GdkEvent     *event,
                      gpointer      user_data)
{
    printf("GtkClipboard::owner-change signal callback invoked!\n"); 
} 
    

void print_targets(const GtkTargetEntry *targets, const int N) 
{ 
    int i; 
    for (i=0; i < N; i++) { 
        printf("%d: %s\n", i, targets[i].target);
    } 
} 

int main(int argc, char** argv) 
{ 
    gtk_init(&argc, &argv);

    { 
      gboolean result; 
      GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

      GtkTargetEntry targets[] = {/* { .target = "video/H264", .info=0 }, */
                                     { .target = "image/png",  .info=0 },  
				  /* { .target = "image/bmp",  .info=2 }, */
				  /* { .target = "nonstandard/foo", .info=3}, */
                                  /* { .target = "audio/GSM",  .info=4 } */
      }; 
                    
      const int N = sizeof(targets) / sizeof(GtkTargetEntry); 

      GtkClipboard* clip = gtk_widget_get_clipboard(window, GDK_SELECTION_CLIPBOARD);

      const char IMAGENAME[] = "example.png"; 
      GdkPixbuf* img = gdk_pixbuf_new_from_file(IMAGENAME, NULL); 

      if (!img) { 
        printf("Could not open %s\n", IMAGENAME); 
        exit(1); 
      } 
          
      printf("GTK+ version %d.%d.%d\n", 
             gtk_major_version, gtk_minor_version, gtk_micro_version); 

      printf("Connecting GtkClipboard::owner-change signal\n"); 
      g_signal_connect (clip, "owner-change", G_CALLBACK (owner_changed_cb), NULL); 

      printf("Posting %d targets: \n\n", N); 
      print_targets(targets, N); 

      printf("Calling gtk_clipboard_set_with_data..."); 
      result = gtk_clipboard_set_with_data(clip, targets, N, clip_get, clip_clear, img);
          
      printf("  %s\n",  result ? "Success" : "Failure"); 
    }

    gtk_main();
        
    return 0; 
} 
