<commit_before>/* GTK - The GIMP Toolkit
 * Copyright (C) 1995-1999 <NAME>, <NAME> and <NAME>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/*
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
 * file for a list of people on the GTK+ Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
 */

#include "config.h"

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

#include "gdk/gdk.h"

#include "gtkdnd.h"
#include "gtkiconfactory.h"
#include "gtkicontheme.h"
#include "gtkimageprivate.h"
#include "gtkinvisible.h"
#include "gtkmain.h"
#include "gtkplug.h"
#include "gtkstock.h"
#include "gtkwindow.h"
#include "gtkintl.h"
#include "gtkquartz.h"
#include "gdk/quartz/gdkquartz.h"
#include "gtkselectionprivate.h"

typedef struct _GtkDragSourceSite GtkDragSourceSite;
typedef struct _GtkDragSourceInfo GtkDragSourceInfo;
typedef struct _GtkDragDestSite GtkDragDestSite;
typedef struct _GtkDragDestInfo GtkDragDestInfo;
typedef struct _GtkDragFindData GtkDragFindData;

static void     gtk_drag_find_widget            (GtkWidget        *widget,
						 GtkDragFindData  *data);
static void     gtk_drag_dest_site_destroy      (gpointer          data);
static void     gtk_drag_dest_leave             (GtkWidget        *widget,
						 GdkDragContext   *context,
						 guint             time);
static GtkDragDestInfo *gtk_drag_get_dest_info  (GdkDragContext   *context,
						 gboolean          create);
static void gtk_drag_source_site_destroy        (gpointer           data);

static GtkDragSourceInfo *gtk_drag_get_source_info (GdkDragContext *context,
						    gboolean        create);

extern GdkDragContext *gdk_quartz_drag_source_context (); /* gdk/quartz/gdkdnd-quartz.c */

struct _GtkDragSourceSite 
{
  GdkModifierType    start_button_mask;
  GtkTargetList     *target_list;        /* Targets for drag data */
  GdkDragAction      actions;            /* Possible actions */

  /* Drag icon */
  GtkImageType icon_type;
  union
  {
    GtkImagePixbufData pixbuf;
    GtkImageStockData stock;
    GtkImageIconNameData name;
  } icon_data;

  /* Stored button press information to detect drag beginning */
  gint               state;
  gint               x, y;
};

struct _GtkDragSourceInfo 
{
  GtkWidget         *source_widget;
  GtkWidget         *widget;
  GtkTargetList     *target_list; /* Targets for drag data */
  GdkDragAction      possible_actions; /* Actions allowed by source */
  GdkDragContext    *context;	  /* drag context */
  NSEvent           *nsevent;     /* what started it */
  gint hot_x, hot_y;		  /* Hot spot for drag */
  GdkPixbuf         *icon_pixbuf;
  gboolean           success;
  gboolean           delete;
};

struct _GtkDragDestSite 
{
  GtkDestDefaults    flags;
  GtkTargetList     *target_list;
  GdkDragAction      actions;
  guint              have_drag : 1;
  guint              track_motion : 1;
};

struct _GtkDragDestInfo 
{
  GtkWidget         *widget;	   /* Widget in which drag is in */
  GdkDragContext    *context;	   /* Drag context */
  guint              dropped : 1;     /* Set after we receive a drop */
  gint               drop_x, drop_y; /* Position of drop */
};

struct _GtkDragFindData 
{
  gint x;
  gint y;
  GdkDragContext *context;
  GtkDragDestInfo *info;
  gboolean found;
  gboolean toplevel;
  gboolean (*callback) (GtkWidget *widget, GdkDragContext *context,
			gint x, gint y, guint32 time);
  guint32 time;
};


@interface GtkDragSourceOwner : NSObject {
  GtkDragSourceInfo *info;
}

@end

@implementation GtkDragSourceOwner
-(void)pasteboard:(NSPasteboard *)sender provideDataForType:(NSString *)type
{
  guint target_info;
  GtkSelectionData selection_data;

  selection_data.selection = GDK_NONE;
  selection_data.data = NULL;
  selection_data.length = -1;
  selection_data.target = _gtk_quartz_pasteboard_type_to_atom (type);
  selection_data.display = gdk_display_get_default ();

  if (gtk_target_list_find (info->target_list, 
			    selection_data.target, 
			    &target_info)) 
    {
      g_signal_emit_by_name (info->widget, "drag-data-get",
			     info->context,
			     &selection_data,
			     target_info,
			     time);

      if (selection_data.length >= 0)
        _gtk_quartz_set_selection_data_for_pasteboard (sender, &selection_data);
      
      g_free (selection_data.data);
    }
}

- (id)initWithInfo:(GtkDragSourceInfo *)anInfo
{
  self = [super init];

  if (self) 
    {
      info = anInfo;
    }

  return self;
}

@end

void 
gtk_drag_get_data (GtkWidget      *widget,
		   GdkDragContext *context,
		   GdkAtom         target,
		   guint32         time)
{
  id <NSDraggingInfo> dragging_info;
  NSPasteboard *pasteboard;
  GtkSelectionData *selection_data;
  GtkDragDestInfo *info;
  GtkDragDestSite *site;

  dragging_info = gdk_quartz_drag_context_get_dragging_info_libgtk_only (context);
  pasteboard = [dragging_info draggingPasteboard];

  info = gtk_drag_get_dest_info (context, FALSE);
  site = g_object_get_data (G_OBJECT (widget), "gtk-drag-dest");

  selection_data = _gtk_quartz_get_selection_data_from_pasteboard (pasteboard,
								   target, 0);

  if (site && site->target_list)
    {
      guint target_info;
      
      if (gtk_target_list_find (site->target_list, 
				selection_data->target,
				&target_info))
	{
	  if (!(site->flags & GTK_DEST_DEFAULT_DROP) ||
	      selection_data->length >= 0)
	    g_signal_emit_by_name (widget,
				   "drag-data-received",
				   context, info->drop_x, info->drop_y,
				   selection_data,
				   target_info, time);
	}
    }
  else
    {
      g_signal_emit_by_name (widget,
			     "drag-data-received",
			     context, info->drop_x, info->drop_y,
			     selection_data,
			     0, time);
    }
  
  if (site && site->flags & GTK_DEST_DEFAULT_DROP)
    {
      gtk_drag_finish (context, 
		       (selection_data->length >= 0),
		       (gdk_drag_context_get_selected_action (context) == GDK_ACTION_MOVE),
		       time);
    }      
}

void 
gtk_drag_finish (GdkDragContext *context,
		 gboolean        success,
		 gboolean        del,
		 guint32         time)
{
  GtkDragSourceInfo *info;
  GdkDragContext* source_context = gdk_quartz_drag_source_context ();

  if (source_context)
    {
      info = gtk_drag_get_source_info (source_context, FALSE);
      if (info)
        {
          info->success = success;
          info->delete = del;
        }
    }
}

static void
gtk_drag_dest_info_destroy (gpointer data)
{
  GtkDragDestInfo *info = data;

  g_free (info);
}

static GtkDragDestInfo *
gtk_drag_get_dest_info (GdkDragContext *context,
			gboolean        create)
{
  GtkDragDestInfo *info;
  static GQuark info_quark = 0;
  if (!info_quark)
    info_quark = g_quark_from_static_string ("gtk-dest-info");
  
  info = g_object_get_qdata (G_OBJECT (context), info_quark);
  if (!info && create)
    {
      info = g_new (GtkDragDestInfo, 1);
      info->widget = NULL;
      info->context = context;
      info->dropped = FALSE;
      g_object_set_qdata_full (G_OBJECT (context), info_quark,
			       info, gtk_drag_dest_info_destroy);
    }

  return info;
}

static GQuark dest_info_quark = 0;

static GtkDragSourceInfo *
gtk_drag_get_source_info (GdkDragContext *context,
			  gboolean        create)
{
  GtkDragSourceInfo *info;

  if (!dest_info_quark)
    dest_info_quark = g_quark_from_static_string ("gtk-source-info");
  
  info = g_object_get_qdata (G_OBJECT (context), dest_info_quark);
  if (!info && create)
    {
      info = g_new0 (GtkDragSourceInfo, 1);
      info->context = context;
      g_object_set_qdata (G_OBJECT (context), dest_info_quark, info);
    }

  return info;
}

static void
gtk_drag_clear_source_info (GdkDragContext *context)
{
  g_object_set_qdata (G_OBJECT (context), dest_info_quark, NULL);
}

GtkWidget *
gtk_drag_get_source_widget (GdkDragContext *context)
{
  GtkDragSourceInfo *info;
  GdkDragContext* real_source_context = gdk_quartz_drag_source_context();

  if (!real_source_context)
    return NULL;

  info = gtk_drag_get_source_info (real_source_context, FALSE);
  if (!info)
     return NULL;

  return info->source_widget;
}

/*************************************************************
 * gtk_drag_highlight_draw:
 *     Callback for expose_event for highlighted widgets.
 *   arguments:
 *     widget:
 *     event:
 *     data:
 *   results:
 *************************************************************/

static gboolean
gtk_drag_highlight_draw (GtkWidget *widget,
                         cairo_t   *cr,
			 gpointer   data)
{
  int width = gtk_widget_get_allocated_width (widget);
  int height = gtk_widget_get_allocated_height (widget);
  GtkStyleContext *context;

  gtk_style_context_save (context);
  gtk_style_context_add_class (context, GTK_STYLE_CLASS_DND);

  gtk_render_frame (context, cr, 0, 0, width, height);

  gtk_style_context_restore (context);

  cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */
  cairo_set_line_width (cr, 1.0);
  cairo_rectangle (cr,
                   0.5, 0.5,
                   width - 1, height - 1);
  cairo_stroke (cr);
 
  return FALSE;
}

/*************************************************************
 * gtk_drag_highlight:<commit_msg>Quartz: gtk_drag_highlight_draw(): Set the GtkStyleContext to the widget.<commit_after>/* GTK - The GIMP Toolkit
 * Copyright (C) 1995-1999 <NAME>, <NAME> and <NAME>d
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/*
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
 * file for a list of people on the GTK+ Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
 */

#include "config.h"

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

#include "gdk/gdk.h"

#include "gtkdnd.h"
#include "gtkiconfactory.h"
#include "gtkicontheme.h"
#include "gtkimageprivate.h"
#include "gtkinvisible.h"
#include "gtkmain.h"
#include "gtkplug.h"
#include "gtkstock.h"
#include "gtkwindow.h"
#include "gtkintl.h"
#include "gtkquartz.h"
#include "gdk/quartz/gdkquartz.h"
#include "gtkselectionprivate.h"

typedef struct _GtkDragSourceSite GtkDragSourceSite;
typedef struct _GtkDragSourceInfo GtkDragSourceInfo;
typedef struct _GtkDragDestSite GtkDragDestSite;
typedef struct _GtkDragDestInfo GtkDragDestInfo;
typedef struct _GtkDragFindData GtkDragFindData;

static void     gtk_drag_find_widget            (GtkWidget        *widget,
						 GtkDragFindData  *data);
static void     gtk_drag_dest_site_destroy      (gpointer          data);
static void     gtk_drag_dest_leave             (GtkWidget        *widget,
						 GdkDragContext   *context,
						 guint             time);
static GtkDragDestInfo *gtk_drag_get_dest_info  (GdkDragContext   *context,
						 gboolean          create);
static void gtk_drag_source_site_destroy        (gpointer           data);

static GtkDragSourceInfo *gtk_drag_get_source_info (GdkDragContext *context,
						    gboolean        create);

extern GdkDragContext *gdk_quartz_drag_source_context (); /* gdk/quartz/gdkdnd-quartz.c */

struct _GtkDragSourceSite 
{
  GdkModifierType    start_button_mask;
  GtkTargetList     *target_list;        /* Targets for drag data */
  GdkDragAction      actions;            /* Possible actions */

  /* Drag icon */
  GtkImageType icon_type;
  union
  {
    GtkImagePixbufData pixbuf;
    GtkImageStockData stock;
    GtkImageIconNameData name;
  } icon_data;

  /* Stored button press information to detect drag beginning */
  gint               state;
  gint               x, y;
};

struct _GtkDragSourceInfo 
{
  GtkWidget         *source_widget;
  GtkWidget         *widget;
  GtkTargetList     *target_list; /* Targets for drag data */
  GdkDragAction      possible_actions; /* Actions allowed by source */
  GdkDragContext    *context;	  /* drag context */
  NSEvent           *nsevent;     /* what started it */
  gint hot_x, hot_y;		  /* Hot spot for drag */
  GdkPixbuf         *icon_pixbuf;
  gboolean           success;
  gboolean           delete;
};

struct _GtkDragDestSite 
{
  GtkDestDefaults    flags;
  GtkTargetList     *target_list;
  GdkDragAction      actions;
  guint              have_drag : 1;
  guint              track_motion : 1;
};

struct _GtkDragDestInfo 
{
  GtkWidget         *widget;	   /* Widget in which drag is in */
  GdkDragContext    *context;	   /* Drag context */
  guint              dropped : 1;     /* Set after we receive a drop */
  gint               drop_x, drop_y; /* Position of drop */
};

struct _GtkDragFindData 
{
  gint x;
  gint y;
  GdkDragContext *context;
  GtkDragDestInfo *info;
  gboolean found;
  gboolean toplevel;
  gboolean (*callback) (GtkWidget *widget, GdkDragContext *context,
			gint x, gint y, guint32 time);
  guint32 time;
};


@interface GtkDragSourceOwner : NSObject {
  GtkDragSourceInfo *info;
}

@end

@implementation GtkDragSourceOwner
-(void)pasteboard:(NSPasteboard *)sender provideDataForType:(NSString *)type
{
  guint target_info;
  GtkSelectionData selection_data;

  selection_data.selection = GDK_NONE;
  selection_data.data = NULL;
  selection_data.length = -1;
  selection_data.target = _gtk_quartz_pasteboard_type_to_atom (type);
  selection_data.display = gdk_display_get_default ();

  if (gtk_target_list_find (info->target_list, 
			    selection_data.target, 
			    &target_info)) 
    {
      g_signal_emit_by_name (info->widget, "drag-data-get",
			     info->context,
			     &selection_data,
			     target_info,
			     time);

      if (selection_data.length >= 0)
        _gtk_quartz_set_selection_data_for_pasteboard (sender, &selection_data);
      
      g_free (selection_data.data);
    }
}

- (id)initWithInfo:(GtkDragSourceInfo *)anInfo
{
  self = [super init];

  if (self) 
    {
      info = anInfo;
    }

  return self;
}

@end

void 
gtk_drag_get_data (GtkWidget      *widget,
		   GdkDragContext *context,
		   GdkAtom         target,
		   guint32         time)
{
  id <NSDraggingInfo> dragging_info;
  NSPasteboard *pasteboard;
  GtkSelectionData *selection_data;
  GtkDragDestInfo *info;
  GtkDragDestSite *site;

  dragging_info = gdk_quartz_drag_context_get_dragging_info_libgtk_only (context);
  pasteboard = [dragging_info draggingPasteboard];

  info = gtk_drag_get_dest_info (context, FALSE);
  site = g_object_get_data (G_OBJECT (widget), "gtk-drag-dest");

  selection_data = _gtk_quartz_get_selection_data_from_pasteboard (pasteboard,
								   target, 0);

  if (site && site->target_list)
    {
      guint target_info;
      
      if (gtk_target_list_find (site->target_list, 
				selection_data->target,
				&target_info))
	{
	  if (!(site->flags & GTK_DEST_DEFAULT_DROP) ||
	      selection_data->length >= 0)
	    g_signal_emit_by_name (widget,
				   "drag-data-received",
				   context, info->drop_x, info->drop_y,
				   selection_data,
				   target_info, time);
	}
    }
  else
    {
      g_signal_emit_by_name (widget,
			     "drag-data-received",
			     context, info->drop_x, info->drop_y,
			     selection_data,
			     0, time);
    }
  
  if (site && site->flags & GTK_DEST_DEFAULT_DROP)
    {
      gtk_drag_finish (context, 
		       (selection_data->length >= 0),
		       (gdk_drag_context_get_selected_action (context) == GDK_ACTION_MOVE),
		       time);
    }      
}

void 
gtk_drag_finish (GdkDragContext *context,
		 gboolean        success,
		 gboolean        del,
		 guint32         time)
{
  GtkDragSourceInfo *info;
  GdkDragContext* source_context = gdk_quartz_drag_source_context ();

  if (source_context)
    {
      info = gtk_drag_get_source_info (source_context, FALSE);
      if (info)
        {
          info->success = success;
          info->delete = del;
        }
    }
}

static void
gtk_drag_dest_info_destroy (gpointer data)
{
  GtkDragDestInfo *info = data;

  g_free (info);
}

static GtkDragDestInfo *
gtk_drag_get_dest_info (GdkDragContext *context,
			gboolean        create)
{
  GtkDragDestInfo *info;
  static GQuark info_quark = 0;
  if (!info_quark)
    info_quark = g_quark_from_static_string ("gtk-dest-info");
  
  info = g_object_get_qdata (G_OBJECT (context), info_quark);
  if (!info && create)
    {
      info = g_new (GtkDragDestInfo, 1);
      info->widget = NULL;
      info->context = context;
      info->dropped = FALSE;
      g_object_set_qdata_full (G_OBJECT (context), info_quark,
			       info, gtk_drag_dest_info_destroy);
    }

  return info;
}

static GQuark dest_info_quark = 0;

static GtkDragSourceInfo *
gtk_drag_get_source_info (GdkDragContext *context,
			  gboolean        create)
{
  GtkDragSourceInfo *info;

  if (!dest_info_quark)
    dest_info_quark = g_quark_from_static_string ("gtk-source-info");
  
  info = g_object_get_qdata (G_OBJECT (context), dest_info_quark);
  if (!info && create)
    {
      info = g_new0 (GtkDragSourceInfo, 1);
      info->context = context;
      g_object_set_qdata (G_OBJECT (context), dest_info_quark, info);
    }

  return info;
}

static void
gtk_drag_clear_source_info (GdkDragContext *context)
{
  g_object_set_qdata (G_OBJECT (context), dest_info_quark, NULL);
}

GtkWidget *
gtk_drag_get_source_widget (GdkDragContext *context)
{
  GtkDragSourceInfo *info;
  GdkDragContext* real_source_context = gdk_quartz_drag_source_context();

  if (!real_source_context)
    return NULL;

  info = gtk_drag_get_source_info (real_source_context, FALSE);
  if (!info)
     return NULL;

  return info->source_widget;
}

/*************************************************************
 * gtk_drag_highlight_draw:
 *     Callback for expose_event for highlighted widgets.
 *   arguments:
 *     widget:
 *     event:
 *     data:
 *   results:
 *************************************************************/

static gboolean
gtk_drag_highlight_draw (GtkWidget *widget,
                         cairo_t   *cr,
			 gpointer   data)
{
  int width = gtk_widget_get_allocated_width (widget);
  int height = gtk_widget_get_allocated_height (widget);
  GtkStyleContext *context = gtk_widget_get_style_context (widget);

  gtk_style_context_save (context);
  gtk_style_context_add_class (context, GTK_STYLE_CLASS_DND);

  gtk_render_frame (context, cr, 0, 0, width, height);

  gtk_style_context_restore (context);

  cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */
  cairo_set_line_width (cr, 1.0);
  cairo_rectangle (cr,
                   0.5, 0.5,
                   width - 1, height - 1);
  cairo_stroke (cr);
 
  return FALSE;
}

/*************************************************************
 * gtk_drag_highlight:
{'fraction_non_alphanumeric': 0.10721628804974676, 'fraction_numerical': 0.006920415224913495, 'mean_word_length': 3.1442227763923523, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2181610', 'n_tokens_mistral': 7181, 'n_tokens_neox': 6545, 'n_words': 1568}