/* Test program for drag and drop with two sorts of targets available. Allin Cottrell (cottrell wfu edu), March 2003. */ #include enum { DRAG_FILENAME, DRAG_POINTER }; GtkTargetEntry test_drag_targets[] = { { "text/uri-list", 0, DRAG_FILENAME }, { "pointer", GTK_TARGET_SAME_APP, DRAG_POINTER } }; void app_exit (GtkWidget *w, gpointer p) { gtk_main_quit(); } static void msgbox (const char *msg) { GtkWidget *dialog; dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, msg); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } static void get_drag_pointer (GtkWidget *w, GdkDragContext *context, GtkSelectionData *sel, guint info, guint t, gpointer ptr) { gtk_selection_data_set(sel, GDK_SELECTION_TYPE_INTEGER, 8, (const guchar *) &ptr, sizeof ptr); } static void pointer_window_drag_connect (GtkWidget *widget, gpointer ptr) { gtk_drag_source_set(widget, GDK_BUTTON1_MASK, &test_drag_targets[DRAG_POINTER], 1, GDK_ACTION_COPY); g_signal_connect(G_OBJECT(widget), "drag_data_get", G_CALLBACK(get_drag_pointer), ptr); } static void pointer_window (void) /* mock-up of a window which supplies a pointer to drop */ { GtkWidget *pw, *plabel; pw = gtk_window_new(GTK_WINDOW_TOPLEVEL); g_print("Pointer window is at %p\n", (void *) pw); plabel = gtk_label_new("\n Pointer window \n"); gtk_container_add(GTK_CONTAINER(pw), plabel); pointer_window_drag_connect(pw, (gpointer) pw); gtk_widget_show_all(pw); } static void handle_drag_data (GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *data, guint info, guint time, gpointer p) { gchar *input = NULL; if (info == DRAG_FILENAME) { input = g_strdup_printf("Got uri-list: %s", data->data); } else if (info == DRAG_POINTER) { input = g_strdup_printf("Got pointer (address of pointer window):\n" "%p", *(void **) data->data); } else { input = g_strdup("Got unknown drag input"); } msgbox(input); g_free(input); } static void main_window_drag_connect (GtkWidget *widget) { gtk_drag_dest_set (widget, GTK_DEST_DEFAULT_ALL, test_drag_targets, 2, GDK_ACTION_COPY); g_signal_connect (G_OBJECT(widget), "drag_data_received", G_CALLBACK(handle_drag_data), NULL); } int main (int argc, char *argv[]) { GtkWidget *w, *label; gtk_init(&argc, &argv); w = gtk_window_new(GTK_WINDOW_TOPLEVEL); g_signal_connect(G_OBJECT(w), "destroy", G_CALLBACK(app_exit), NULL); label = gtk_label_new("\n Drag onto me, from a file icon \n" " or from the pointer window. \n"); gtk_container_add(GTK_CONTAINER(w), label); main_window_drag_connect(label); gtk_widget_show_all(w); pointer_window(); gtk_main(); return 0; }