#include <gtk/gtk.h>
#include <string.h>

#define _BYTE   8
#define _WORD   16
#define _DWORD  32

#ifndef	FALSE
#define	FALSE	(0)
#endif

#ifndef	TRUE
#define	TRUE	(!FALSE)
#endif


/******************************************************************************/
/* Define a list of data types called "targets" that a destination widget will
 * accept. The string type is arbitrary, and negotiated between DnD widgets by
 * the developer. An enum or GQuark can serve as the integer target id. */
enum {
        TARGET_INT32,
        TARGET_STRING,
        TARGET_ROOTWIN
};


/* datatype (string), restrictions on DnD (GtkTargetFlags), datatype (int) */
static GtkTargetEntry target_list[] = {
        { "INTEGER",    0, TARGET_INT32 },
        { "STRING",     0, TARGET_STRING },
        { "text/plain", 0, TARGET_STRING },
        { "application/x-rootwindow-drop", 0, TARGET_ROOTWIN }
};

static guint n_targets = G_N_ELEMENTS (target_list);

// Callback to print coordinates when mouse is released.
gboolean
button_released (GtkWidget *widget,
                GdkEvent  *event,
                gpointer   user_data)
{

	gdouble xcoord = event->button.x;
	gdouble ycoord = event->button.y;
	g_print("Button up pressed, x: %lf  y:%lf\n", xcoord, ycoord);
	return FALSE;
}


static void
activate (GtkApplication* app,
          gpointer        user_data)
{
  GtkWidget *window;

  window = gtk_application_window_new (app);
  gtk_window_set_title (GTK_WINDOW (window), "DnD breaks mouse up events");
  gtk_window_set_default_size (GTK_WINDOW (window), 500, 200);

  GtkWidget *fixed;
  GtkWidget *buttonSrc;
  
  //Main Container.
  fixed = gtk_fixed_new();
  gtk_container_add(GTK_CONTAINER(window), fixed);

  //Container for Drag source.
  buttonSrc = gtk_button_new_with_label("Click & drag me, release\nproduces 0 x/y coords.\n \nNot dragging produces\n ok results");
  gtk_fixed_put(GTK_FIXED(fixed), buttonSrc, 0, 0);
  gtk_widget_set_size_request(buttonSrc, 150, 150);

  g_signal_connect (G_OBJECT(buttonSrc), "button_release_event", G_CALLBACK(button_released), NULL);

  /* Make "Button2" a DnD source. */
  gtk_drag_source_set
  (
	  buttonSrc,            /* widget will be drag-able */
	  GDK_BUTTON1_MASK,       /* modifier that will start a drag */
	  target_list,            /* lists of target to support */
	  n_targets,              /* size of list */
	  GDK_ACTION_COPY         /* what to do with data after dropped */
  );

  gtk_widget_show_all (window);

}

int
main (int    argc,
      char **argv)
{
  GtkApplication *app;
  int status;
  gtk_init(&argc, &argv);
 
  app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  status = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);

  return status;
}
