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

📄 gdkdnd.c

📁 gtk是linux一款强大的夸平台的图形化开发工具
💻 C
📖 第 1 页 / 共 5 页
字号:
	  actions &= ~xdnd_actions_table[i].action;	  n_atoms++;	}    }  atomlist = g_new (GdkAtom, n_atoms);  actions = context->actions;  n_atoms = 0;  for (i=0; i<xdnd_n_actions; i++)    {      if (actions & xdnd_actions_table[i].action)	{	  actions &= ~xdnd_actions_table[i].action;	  atomlist[n_atoms] = xdnd_actions_table[i].atom;	  n_atoms++;	}    }  XChangeProperty (GDK_WINDOW_XDISPLAY (context->source_window),		   GDK_WINDOW_XWINDOW (context->source_window),		   gdk_atom_intern ("XdndActionList", FALSE),		   XA_ATOM, 32, PropModeReplace,		   (guchar *)atomlist, n_atoms);  g_free (atomlist);  private->xdnd_actions_set = 1;  private->xdnd_actions = context->actions;}/************************************************************* * xdnd_send_xevent: *     Like gdk_send_event, but if the target is the root *     window, sets an event mask of ButtonPressMask, otherwise *     an event mask of 0. *   arguments: *      *   results: *************************************************************/gintxdnd_send_xevent (Window window, gboolean propagate, 		  XEvent *event_send){  if (window == gdk_root_window)    return gdk_send_xevent (window, propagate, ButtonPressMask, event_send);  else    return gdk_send_xevent (window, propagate, 0, event_send);}static voidxdnd_send_enter (GdkDragContext *context){  XEvent xev;  GdkDragContextPrivate *private = (GdkDragContextPrivate *)context;  xev.xclient.type = ClientMessage;  xev.xclient.message_type = gdk_atom_intern ("XdndEnter", FALSE);  xev.xclient.format = 32;  xev.xclient.window = private->drop_xid ?                            private->drop_xid :                            GDK_WINDOW_XWINDOW (context->dest_window);  xev.xclient.data.l[0] = GDK_WINDOW_XWINDOW (context->source_window);  xev.xclient.data.l[1] = (3 << 24); /* version */  xev.xclient.data.l[2] = 0;  xev.xclient.data.l[3] = 0;  xev.xclient.data.l[4] = 0;  if (!private->xdnd_selection)    private->xdnd_selection = gdk_atom_intern ("XdndSelection", FALSE);  if (g_list_length (context->targets) > 3)    {      if (!private->xdnd_targets_set)	xdnd_set_targets (context);      xev.xclient.data.l[1] |= 1;    }  else    {      GList *tmp_list = context->targets;      gint i = 2;      while (tmp_list)	{	  xev.xclient.data.l[i] = GPOINTER_TO_INT (tmp_list->data);	  tmp_list = tmp_list->next;	  i++;	}    }  if (!xdnd_send_xevent (GDK_WINDOW_XWINDOW (context->dest_window),			 FALSE, &xev))    {      GDK_NOTE (DND, 		g_message ("Send event to %lx failed",			   GDK_WINDOW_XWINDOW (context->dest_window)));      gdk_window_unref (context->dest_window);      context->dest_window = NULL;    }}static voidxdnd_send_leave (GdkDragContext *context){  XEvent xev;  GdkDragContextPrivate *private = (GdkDragContextPrivate *)context;  xev.xclient.type = ClientMessage;  xev.xclient.message_type = gdk_atom_intern ("XdndLeave", FALSE);  xev.xclient.format = 32;  xev.xclient.window = private->drop_xid ?                            private->drop_xid :                            GDK_WINDOW_XWINDOW (context->dest_window);  xev.xclient.data.l[0] = GDK_WINDOW_XWINDOW (context->source_window);  xev.xclient.data.l[1] = 0;  xev.xclient.data.l[2] = 0;  xev.xclient.data.l[3] = 0;  xev.xclient.data.l[4] = 0;  if (!xdnd_send_xevent (GDK_WINDOW_XWINDOW (context->dest_window),			 FALSE, &xev))    {      GDK_NOTE (DND, 		g_message ("Send event to %lx failed",			   GDK_WINDOW_XWINDOW (context->dest_window)));      gdk_window_unref (context->dest_window);      context->dest_window = NULL;    }}static voidxdnd_send_drop (GdkDragContext *context, guint32 time){  GdkDragContextPrivate *private = (GdkDragContextPrivate *)context;  XEvent xev;  xev.xclient.type = ClientMessage;  xev.xclient.message_type = gdk_atom_intern ("XdndDrop", FALSE);  xev.xclient.format = 32;  xev.xclient.window = private->drop_xid ?                            private->drop_xid :                            GDK_WINDOW_XWINDOW (context->dest_window);  xev.xclient.data.l[0] = GDK_WINDOW_XWINDOW (context->source_window);  xev.xclient.data.l[1] = 0;  xev.xclient.data.l[2] = time;  xev.xclient.data.l[3] = 0;  xev.xclient.data.l[4] = 0;  if (!xdnd_send_xevent (GDK_WINDOW_XWINDOW (context->dest_window),			 FALSE, &xev))    {      GDK_NOTE (DND, 		g_message ("Send event to %lx failed",			   GDK_WINDOW_XWINDOW (context->dest_window)));      gdk_window_unref (context->dest_window);      context->dest_window = NULL;    }}static voidxdnd_send_motion (GdkDragContext *context,		  gint            x_root, 		  gint            y_root,		  GdkDragAction   action,		  guint32         time){  GdkDragContextPrivate *private = (GdkDragContextPrivate *)context;  XEvent xev;  xev.xclient.type = ClientMessage;  xev.xclient.message_type = gdk_atom_intern ("XdndPosition", FALSE);  xev.xclient.format = 32;  xev.xclient.window = private->drop_xid ?                            private->drop_xid :                            GDK_WINDOW_XWINDOW (context->dest_window);  xev.xclient.data.l[0] = GDK_WINDOW_XWINDOW (context->source_window);  xev.xclient.data.l[1] = 0;  xev.xclient.data.l[2] = (x_root << 16) | y_root;  xev.xclient.data.l[3] = time;  xev.xclient.data.l[4] = xdnd_action_to_atom (action);  if (!xdnd_send_xevent (GDK_WINDOW_XWINDOW (context->dest_window),			 FALSE, &xev))    {      GDK_NOTE (DND, 		g_message ("Send event to %lx failed",			   GDK_WINDOW_XWINDOW (context->dest_window)));      gdk_window_unref (context->dest_window);      context->dest_window = NULL;    }  private->drag_status = GDK_DRAG_STATUS_MOTION_WAIT;}static guint32xdnd_check_dest (Window win){  gboolean retval = FALSE;  Atom type = None;  int format;  unsigned long nitems, after;  GdkAtom *version;  Window *proxy_data;  Window proxy;  static GdkAtom xdnd_proxy_atom = GDK_NONE;  gint old_warnings = gdk_error_warnings;  if (!xdnd_proxy_atom)    xdnd_proxy_atom = gdk_atom_intern ("XdndProxy", FALSE);  if (!xdnd_aware_atom)    xdnd_aware_atom = gdk_atom_intern ("XdndAware", FALSE);  proxy = GDK_NONE;    gdk_error_code = 0;  gdk_error_warnings = 0;  XGetWindowProperty (gdk_display, win, 		      xdnd_proxy_atom, 0, 		      1, False, AnyPropertyType,		      &type, &format, &nitems, &after, 		      (guchar **)&proxy_data);  if (!gdk_error_code)    {      if (type != None)	{	  if ((format == 32) && (nitems == 1))	    {	      proxy = *proxy_data;	    }	  else	    GDK_NOTE (DND, 		      g_warning ("Invalid XdndOwner property on window %ld\n", win));	  	  XFree (proxy_data);	}            XGetWindowProperty (gdk_display, proxy ? proxy : win,			  xdnd_aware_atom, 0, 			  1, False, AnyPropertyType,			  &type, &format, &nitems, &after, 			  (guchar **)&version);            if (!gdk_error_code && type != None)	{	  if ((format == 32) && (nitems == 1))	    {	      if (*version == 3)		retval = TRUE;	    }	  else	    GDK_NOTE (DND, 		      g_warning ("Invalid XdndAware property on window %ld\n", win));	  	  XFree (version);	}          }  gdk_error_warnings = old_warnings;  gdk_error_code = 0;    return retval ? (proxy ? proxy : win) : GDK_NONE;}/* Target side */static voidxdnd_read_actions (GdkDragContext *context){  Atom type;  int format;  gulong nitems, after;  Atom *data;  gint i;  gint old_warnings = gdk_error_warnings;  gdk_error_code = 0;  gdk_error_warnings = 0;  /* Get the XdndActionList, if set */  XGetWindowProperty (GDK_WINDOW_XDISPLAY (context->source_window),		      GDK_WINDOW_XWINDOW (context->source_window),		      gdk_atom_intern ("XdndActionList", FALSE), 0, 65536,		      False, XA_ATOM, &type, &format, &nitems,		      &after, (guchar **)&data);    if (!gdk_error_code && (format == 32) && (type == XA_ATOM))    {      context->actions = 0;      for (i=0; i<nitems; i++)	context->actions |= xdnd_action_from_atom (data[i]);      ((GdkDragContextPrivate *)context)->xdnd_have_actions = TRUE;#ifdef G_ENABLE_DEBUG      if (gdk_debug_flags & GDK_DEBUG_DND)	{	  GString *action_str = g_string_new (NULL);	  if (context->actions & GDK_ACTION_MOVE)	    g_string_append(action_str, "MOVE ");	  if (context->actions & GDK_ACTION_COPY)	    g_string_append(action_str, "COPY ");	  if (context->actions & GDK_ACTION_LINK)	    g_string_append(action_str, "LINK ");	  if (context->actions & GDK_ACTION_ASK)	    g_string_append(action_str, "ASK ");	  	  g_message("Xdnd actions = %s", action_str->str);	  g_string_free (action_str, TRUE);	}#endif /* G_ENABLE_DEBUG */      XFree(data);    }  gdk_error_warnings = old_warnings;  gdk_error_code = 0;}/* We have to make sure that the XdndActionList we keep internally * is up to date with the XdndActionList on the source window * because we get no notification, because Xdnd wasn't meant * to continually send actions. So we select on PropertyChangeMask * and add this filter. */static GdkFilterReturn xdnd_source_window_filter (GdkXEvent *xev,			   GdkEvent  *event,			   gpointer   cb_data){  XEvent *xevent = (XEvent *)xev;  GdkDragContext *context = cb_data;  if ((xevent->xany.type == PropertyNotify) &&      (xevent->xproperty.atom == gdk_atom_intern ("XdndActionList", FALSE)))    {      xdnd_read_actions (context);      return GDK_FILTER_REMOVE;    }  return GDK_FILTER_CONTINUE;}static voidxdnd_manage_source_filter (GdkDragContext *context,			   GdkWindow      *window,			   gboolean        add_filter){  gint old_warnings = 0;	/* quiet gcc */  GdkWindowPrivate *private = (GdkWindowPrivate *)window;			         gboolean is_foreign = (private->window_type == GDK_WINDOW_FOREIGN);  if (is_foreign)    {      old_warnings = gdk_error_warnings;      gdk_error_warnings = 0;    }  if (!private->destroyed)    {      if (add_filter)	{	  gdk_window_set_events (window,				 gdk_window_get_events (window) |				 GDK_PROPERTY_CHANGE_MASK);	  gdk_window_add_filter (window, xdnd_source_window_filter, context);	}      else	{	  gdk_window_remove_filter (window,				    xdnd_source_window_filter,				    context);	  /* Should we remove the GDK_PROPERTY_NOTIFY mask?	   * but we might want it for other reasons. (Like	   * INCR selection transactions).	   */	}    }  if (is_foreign)    {      gdk_flush();      gdk_error_warnings = old_warnings;    }}static GdkFilterReturn xdnd_enter_filter (GdkXEvent *xev,		   GdkEvent  *event,		   gpointer   cb_data){  XEvent *xevent = (XEvent *)xev;  GdkDragContext *new_context;  gint i;    Atom type;  int format;  gulong nitems, after;  Atom *data;  guint32 source_window = xevent->xclient.data.l[0];  gboolean get_types = ((xevent->xclient.data.l[1] & 1) != 0);  gint version = (xevent->xclient.data.l[1] & 0xff000000) >> 24;    GDK_NOTE (DND, 	    g_message ("XdndEnter: source_window: %#x, version: %#x",		       source_window, version));  if (version != 3)    {      /* Old source ignore */      GDK_NOTE (DND, g_message ("Ignored old XdndEnter message"));      return GDK_FILTER_REMOVE;    }    if (current_dest_drag != NULL)    {      gdk_drag_context_unref (current_dest_drag);      current_dest_drag = NULL;    }  new_context = gdk_drag_context_new ();  new_context->protocol = GDK_DRAG_PROTO_XDND;  new_context->is_source = FALSE;  new_context->source_window = gdk_window_lookup (source_window);  if (new_context->source_window)    gdk_window_ref (new_context->source_window);  else    {      new_context->source_window = gdk_window_foreign_new (source_window);      if (!new_context->source_window)	{	  gdk_drag_context_unref (new_context);	  return GDK_FILTER_REMOVE;	}    }  new_context->dest_window = event->any.window;  gdk_window_ref (new_context->dest_window);  new_context->targets = NULL;  if (get_types)    {      XGetWindowProperty (GDK_WINDOW_XDISPLAY (event->any.window), 			  source_window, 			  gdk_atom_intern ("XdndTypeList", FALSE), 0, 65536,			  False, XA_ATOM, &type, &format, &nitems,			  &after, (guchar **)&data);      if ((format != 32) || (type != XA_ATOM))	{	  gdk_drag_context_unref (new_context);	  return GDK_FILTER_REMOVE;	}      for (i=0; i<nitems; i++)	new_context->targets = g_list_append (new_context->targets,					      GUINT_TO_POINTER (data[i]));      XFree(data);    }  else    {      for (i=0; i<3; i++)	if (xevent->xclient.data.l[2+i])	  new_context->targets = g_list_append (new_context->targets,						GUINT_TO_POINTER (xevent->xclient.data.l[2+i]));    }#ifdef G_ENABLE_DEBUG  if (gdk_debug_flags & GDK_DEBUG_DND)    print_target_list (new_context->targets);#endif /* G_ENABLE_DEBUG */  xdnd_manage_source_filter (new_context, new_context->source_window, TRUE);  xdnd_read_actions (new_context);  event->dnd.type = GDK_DRAG_ENTER;  event->dnd.context = new_context;  gdk_drag_context_ref (new_context);  current_dest_drag = new_context;  ((GdkDragContextPrivate *)new_context)->xdnd_selection =     gdk_atom_intern ("XdndSelection", FALSE);  return GDK_FILTER_TRANSLATE;}static GdkFilterReturn xdnd_leave_filter (GdkXEvent *xev,		   GdkEvent  *event,		   gpointer   data){  XEvent *xevent = (XEvent *)xev;  guint32 source_window = xevent->xclient.data.l[0];    GDK_NOTE (DND, 	    g_message ("XdndLeave: sou

⌨️ 快捷键说明

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