⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtkdnd.c

📁 gtk是linux一款强大的夸平台的图形化开发工具
💻 C
📖 第 1 页 / 共 5 页
字号:
 *   results: *************************************************************/voidgtk_drag_dest_handle_event (GtkWidget *toplevel,			    GdkEvent  *event){  GtkDragDestInfo *info;  GdkDragContext *context;  g_return_if_fail (toplevel != NULL);  g_return_if_fail (event != NULL);  context = event->dnd.context;  info = g_dataset_get_data (context, "gtk-info");  if (!info)    {      info = g_new (GtkDragDestInfo, 1);      info->widget = NULL;      info->context = event->dnd.context;      info->proxy_source = NULL;      info->proxy_data = NULL;      info->dropped = FALSE;      info->proxy_drop_wait = FALSE;      g_dataset_set_data_full (context,			       "gtk-info",			       info,			       gtk_drag_dest_info_destroy);    }  /* Find the widget for the event */  switch (event->type)    {    case GDK_DRAG_ENTER:      break;          case GDK_DRAG_LEAVE:      if (info->widget)	{	  gtk_drag_dest_leave (info->widget, context, event->dnd.time);	  info->widget = NULL;	}      break;          case GDK_DRAG_MOTION:    case GDK_DROP_START:      {	GtkDragFindData data;	gint tx, ty;	if (event->type == GDK_DROP_START)	  {	    info->dropped = TRUE;	    /* We send a leave here so that the widget unhighlights	     * properly.	     */	    if (info->widget)	      {		gtk_drag_dest_leave (info->widget, context, event->dnd.time);		info->widget = NULL;	      }	  }	gdk_window_get_origin (toplevel->window, &tx, &ty);	data.x = event->dnd.x_root - tx;	data.y = event->dnd.y_root - ty; 	data.context = context;	data.info = info;	data.found = FALSE;	data.toplevel = TRUE;	data.callback = (event->type == GDK_DRAG_MOTION) ?	  gtk_drag_dest_motion : gtk_drag_dest_drop;	data.time = event->dnd.time;		gtk_drag_find_widget (toplevel, &data);	if (info->widget && !data.found)	  {	    gtk_drag_dest_leave (info->widget, context, event->dnd.time);	    info->widget = NULL;	  }		/* Send a reply.	 */	if (event->type == GDK_DRAG_MOTION)	  {	    if (!data.found)	      gdk_drag_status (context, 0, event->dnd.time);	  }	else if (event->type == GDK_DROP_START && !info->proxy_source)	  {	    gdk_drop_reply (context, data.found, event->dnd.time);            if ((context->protocol == GDK_DRAG_PROTO_MOTIF) && !data.found)	      gtk_drag_finish (context, FALSE, FALSE, event->dnd.time);	  }      }      break;    default:      g_assert_not_reached ();    }}/************************************************************* * gtk_drag_dest_find_target: *     Decide on a target for the drag. *   arguments: *     site: *     context: *   results: *************************************************************/static GdkAtomgtk_drag_dest_find_target (GtkWidget       *widget,			   GtkDragDestSite *site,			   GdkDragContext  *context){  GList *tmp_target;  GList *tmp_source = NULL;  GtkWidget *source_widget = gtk_drag_get_source_widget (context);  tmp_target = site->target_list->list;  while (tmp_target)    {      GtkTargetPair *pair = tmp_target->data;      tmp_source = context->targets;      while (tmp_source)	{	  if (tmp_source->data == GUINT_TO_POINTER (pair->target))	    {	      if ((!(pair->flags & GTK_TARGET_SAME_APP) || source_widget) &&		  (!(pair->flags & GTK_TARGET_SAME_WIDGET) || (source_widget == widget)))		return pair->target;	      else		break;	    }	  tmp_source = tmp_source->next;	}      tmp_target = tmp_target->next;    }  return GDK_NONE;}static voidgtk_drag_selection_received (GtkWidget        *widget,			     GtkSelectionData *selection_data,			     guint32           time,			     gpointer          data){  GdkDragContext *context;  GtkDragDestInfo *info;  GtkWidget *drop_widget;  drop_widget = data;  context = gtk_object_get_data (GTK_OBJECT (widget), "drag-context");  info = g_dataset_get_data (context, "gtk-info");  if (info->proxy_data &&       info->proxy_data->target == selection_data->target)    {      gtk_selection_data_set (info->proxy_data,			      selection_data->type,			      selection_data->format,			      selection_data->data,			      selection_data->length);      gtk_main_quit ();      return;    }  if (selection_data->target == gdk_atom_intern ("DELETE", FALSE))    {      gtk_drag_finish (context, TRUE, FALSE, time);    }  else if ((selection_data->target == gdk_atom_intern ("XmTRANSFER_SUCCESS", FALSE)) ||	   (selection_data->target == gdk_atom_intern ("XmTRANSFER_FAILURE", FALSE)))    {      /* Do nothing */    }  else    {      GtkDragDestSite *site;      site = gtk_object_get_data (GTK_OBJECT (drop_widget), "gtk-drag-dest");      if (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)		gtk_signal_emit_by_name (GTK_OBJECT (drop_widget), 					 "drag_data_received",					 context, info->drop_x, info->drop_y,					 selection_data, 					 target_info, time);	    }	}      else	{	  gtk_signal_emit_by_name (GTK_OBJECT (drop_widget), 				   "drag_data_received",				   context, info->drop_x, info->drop_y,				   selection_data, 0, time);	}            if (site->flags & GTK_DEST_DEFAULT_DROP)	{	  gtk_drag_finish (context, 			   (selection_data->length >= 0),			   (context->action == GDK_ACTION_MOVE),			   time);	}            gtk_widget_unref (drop_widget);    }  gtk_signal_disconnect_by_func (GTK_OBJECT (widget), 				 GTK_SIGNAL_FUNC (gtk_drag_selection_received),				 data);    gtk_object_set_data (GTK_OBJECT (widget), "drag-context", NULL);  gdk_drag_context_unref (context);  gtk_drag_release_ipc_widget (widget);}/************************************************************* * gtk_drag_find_widget: *     Recursive callback used to locate widgets for  *     DRAG_MOTION and DROP_START events. *   arguments: *      *   results: *************************************************************/static voidgtk_drag_find_widget (GtkWidget       *widget,		      GtkDragFindData *data){  GtkAllocation new_allocation;  gint x_offset = 0;  gint y_offset = 0;  new_allocation = widget->allocation;  if (data->found || !GTK_WIDGET_MAPPED (widget))    return;  /* Note that in the following code, we only count the   * position as being inside a WINDOW widget if it is inside   * widget->window; points that are outside of widget->window   * but within the allocation are not counted. This is consistent   * with the way we highlight drag targets.   */  if (!GTK_WIDGET_NO_WINDOW (widget))    {      new_allocation.x = 0;      new_allocation.y = 0;    }    if (widget->parent)    {      GdkWindow *window = widget->window;      while (window != widget->parent->window)	{	  gint tx, ty, twidth, theight;	  gdk_window_get_size (window, &twidth, &theight);	  if (new_allocation.x < 0)	    {	      new_allocation.width += new_allocation.x;	      new_allocation.x = 0;	    }	  if (new_allocation.y < 0)	    {	      new_allocation.height += new_allocation.y;	      new_allocation.y = 0;	    }	  if (new_allocation.x + new_allocation.width > twidth)	    new_allocation.width = twidth - new_allocation.x;	  if (new_allocation.y + new_allocation.height > theight)	    new_allocation.height = theight - new_allocation.y;	  gdk_window_get_position (window, &tx, &ty);	  new_allocation.x += tx;	  x_offset += tx;	  new_allocation.y += ty;	  y_offset += ty;	  	  window = gdk_window_get_parent (window);	}    }  if (data->toplevel ||      ((data->x >= new_allocation.x) && (data->y >= new_allocation.y) &&       (data->x < new_allocation.x + new_allocation.width) &&        (data->y < new_allocation.y + new_allocation.height)))    {      /* First, check if the drag is in a valid drop site in       * one of our children        */      if (GTK_IS_CONTAINER (widget))	{	  GtkDragFindData new_data = *data;	  	  new_data.x -= x_offset;	  new_data.y -= y_offset;	  new_data.found = FALSE;	  new_data.toplevel = FALSE;	  	  gtk_container_forall (GTK_CONTAINER (widget),				(GtkCallback)gtk_drag_find_widget,				&new_data);	  	  data->found = new_data.found;	}      /* If not, and this widget is registered as a drop site, check to       * emit "drag_motion" to check if we are actually in       * a drop site.       */      if (!data->found &&	  gtk_object_get_data (GTK_OBJECT (widget), "gtk-drag-dest"))	{	  data->found = data->callback (widget,					data->context,					data->x - new_allocation.x,					data->y - new_allocation.y,					data->time);	  /* If so, send a "drag_leave" to the last widget */	  if (data->found)	    {	      if (data->info->widget && data->info->widget != widget)		{		  gtk_drag_dest_leave (data->info->widget, data->context, data->time);		}	      data->info->widget = widget;	    }	}    }}static voidgtk_drag_proxy_begin (GtkWidget       *widget, 		      GtkDragDestInfo *dest_info){  GtkDragSourceInfo *source_info;  GList *tmp_list;    source_info = g_new0 (GtkDragSourceInfo, 1);  source_info->ipc_widget = gtk_drag_get_ipc_widget ();    source_info->widget = widget;  gtk_widget_ref (source_info->widget);  source_info->context = gdk_drag_begin (source_info->ipc_widget->window,					 dest_info->context->targets);  source_info->target_list = gtk_target_list_new (NULL, 0);  tmp_list = dest_info->context->targets;  while (tmp_list)    {      gtk_target_list_add (source_info->target_list, 			   GPOINTER_TO_UINT (tmp_list->data), 0, 0);      tmp_list = tmp_list->next;    }  source_info->proxy_dest = dest_info;    g_dataset_set_data (source_info->context, "gtk-info", source_info);    gtk_signal_connect (GTK_OBJECT (source_info->ipc_widget), 		      "selection_get",		      GTK_SIGNAL_FUNC (gtk_drag_selection_get), 		      source_info);    dest_info->proxy_source = source_info;}static voidgtk_drag_dest_info_destroy (gpointer data){  GtkDragDestInfo *info = data;  g_free (info);}static voidgtk_drag_dest_realized (GtkWidget *widget){  GtkWidget *toplevel = gtk_widget_get_toplevel (widget);  gdk_window_register_dnd (toplevel->window);}static voidgtk_drag_dest_site_destroy (gpointer data){  GtkDragDestSite *site = data;  if (site->target_list)    gtk_target_list_unref (site->target_list);  g_free (site);}/* * Default drag handlers */static void  gtk_drag_dest_leave (GtkWidget      *widget,		     GdkDragContext *context,		     guint           time){  GtkDragDestSite *site;  site = gtk_object_get_data (GTK_OBJECT (widget), "gtk-drag-dest");  g_return_if_fail (site != NULL);  if (site->do_proxy)    {      GtkDragDestInfo *info = g_dataset_get_data (context, "gtk-info");      if (info->proxy_source && !info->dropped)	gdk_drag_abort (info->proxy_source->context, time);            return;    }  else    {      if ((site->flags & GTK_DEST_DEFAULT_HIGHLIGHT) && site->have_drag)	gtk_drag_unhighlight (widget);      if (!(site->flags & GTK_DEST_DEFAULT_MOTION) || site->have_drag)	gtk_signal_emit_by_name (GTK_OBJECT (widget), "drag_leave",				 context, time);            site->have_drag = FALSE;    }}static gbooleangtk_drag_dest_motion (GtkWidget	     *widget,		      GdkDragContext *context,		      gint            x,		      gint            y,		      guint           time){  GtkDragDestSite *site;  GdkDragAction action = 0;  gboolean retval;  site = gtk_object_get_data (GTK_OBJECT (widget), "gtk-drag-dest");  g_return_val_if_fail (site != NULL, FALSE);  if (site->do_proxy)    {      GdkAtom selection;      GdkEvent *current_event;      GdkWindow *dest_window;      GdkDragProtocol proto;	      GtkDragDestInfo *info = g_dataset_get_data (context, "gtk-info");      if (!info->proxy_source)	gtk_drag_proxy_begin (widget, info);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -