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

📄 gdkdnd-x11.c

📁 linux下电话本所依赖的一些图形库
💻 C
📖 第 1 页 / 共 5 页
字号:
/* GDK - The GIMP Drawing Kit * Copyright (C) 1995-1999 Peter Mattis, Spencer Kimball and Josh MacDonald * * 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 <X11/Xlib.h>#include <X11/Xatom.h>#include <string.h>#include "gdk.h"          /* For gdk_flush() */#include "gdkx.h"#include "gdkasync.h"#include "gdkdnd.h"#include "gdkproperty.h"#include "gdkprivate-x11.h"#include "gdkinternals.h"#include "gdkscreen-x11.h"#include "gdkdisplay-x11.h"#include "gdkalias.h"typedef struct _GdkDragContextPrivateX11 GdkDragContextPrivateX11;typedef enum {  GDK_DRAG_STATUS_DRAG,  GDK_DRAG_STATUS_MOTION_WAIT,  GDK_DRAG_STATUS_ACTION_WAIT,  GDK_DRAG_STATUS_DROP} GtkDragStatus;typedef struct {  guint32 xid;  gint x, y, width, height;  gboolean mapped;} GdkCacheChild;typedef struct {  GList *children;  GHashTable *child_hash;  guint old_event_mask;  GdkScreen *screen;} GdkWindowCache;/* Structure that holds information about a drag in progress. * this is used on both source and destination sides. */struct _GdkDragContextPrivateX11 {  GdkDragContext context;  Atom motif_selection;  guint   ref_count;  guint16 last_x;		/* Coordinates from last event */  guint16 last_y;  GdkDragAction old_action;	  /* The last action we sent to the source */  GdkDragAction old_actions;	  /* The last actions we sent to the source */  GdkDragAction xdnd_actions;     /* What is currently set in XdndActionList */  Window dest_xid;              /* The last window we looked up */  Window drop_xid;            /* The (non-proxied) window that is receiving drops */  guint xdnd_targets_set : 1;   /* Whether we've already set XdndTypeList */  guint xdnd_actions_set : 1;   /* Whether we've already set XdndActionList */  guint xdnd_have_actions : 1;  /* Whether an XdndActionList was provided */  guint motif_targets_set : 1;  /* Whether we've already set motif initiator info */  guint drag_status : 4;	/* current status of drag */    guint drop_failed : 1;        /* Whether the drop was unsuccessful */  guint version;                /* Xdnd protocol version */  GSList *window_caches;};#define PRIVATE_DATA(context) ((GdkDragContextPrivateX11 *) GDK_DRAG_CONTEXT (context)->windowing_data)/* Forward declarations */static void gdk_window_cache_destroy (GdkWindowCache *cache);static void motif_read_target_table (GdkDisplay *display);static GdkFilterReturn motif_dnd_filter (GdkXEvent *xev,					 GdkEvent  *event,					 gpointer   data);static GdkFilterReturn xdnd_enter_filter    (GdkXEvent *xev,					     GdkEvent  *event,					     gpointer   data);static GdkFilterReturn xdnd_leave_filter    (GdkXEvent *xev,					     GdkEvent  *event,					     gpointer   data);static GdkFilterReturn xdnd_position_filter (GdkXEvent *xev,					     GdkEvent  *event,					     gpointer   data);static GdkFilterReturn xdnd_status_filter   (GdkXEvent *xev,					     GdkEvent  *event,					     gpointer   data);static GdkFilterReturn xdnd_finished_filter (GdkXEvent *xev,					     GdkEvent  *event,					     gpointer   data);static GdkFilterReturn xdnd_drop_filter     (GdkXEvent *xev,					     GdkEvent  *event,					     gpointer   data);static void   xdnd_manage_source_filter (GdkDragContext *context,					 GdkWindow      *window,					 gboolean        add_filter);static void gdk_drag_context_init       (GdkDragContext      *dragcontext);static void gdk_drag_context_class_init (GdkDragContextClass *klass);static void gdk_drag_context_finalize   (GObject              *object);static gpointer parent_class = NULL;static GList *contexts;const static struct {  const char *atom_name;  GdkFilterFunc func;} xdnd_filters[] = {  { "XdndEnter",    xdnd_enter_filter },  { "XdndLeave",    xdnd_leave_filter },  { "XdndPosition", xdnd_position_filter },  { "XdndStatus",   xdnd_status_filter },  { "XdndFinished", xdnd_finished_filter },  { "XdndDrop",     xdnd_drop_filter },};	      GTypegdk_drag_context_get_type (void){  static GType object_type = 0;  if (!object_type)    {      static const GTypeInfo object_info =      {        sizeof (GdkDragContextClass),        (GBaseInitFunc) NULL,        (GBaseFinalizeFunc) NULL,        (GClassInitFunc) gdk_drag_context_class_init,        NULL,           /* class_finalize */        NULL,           /* class_data */        sizeof (GdkDragContext),        0,              /* n_preallocs */        (GInstanceInitFunc) gdk_drag_context_init,      };            object_type = g_type_register_static (G_TYPE_OBJECT,                                            "GdkDragContext",                                            &object_info, 0);    }    return object_type;}static voidgdk_drag_context_init (GdkDragContext *dragcontext){  GdkDragContextPrivateX11 *private;  private = g_new0 (GdkDragContextPrivateX11, 1);  dragcontext->windowing_data = private;  contexts = g_list_prepend (contexts, dragcontext);}static voidgdk_drag_context_class_init (GdkDragContextClass *klass){  GObjectClass *object_class = G_OBJECT_CLASS (klass);  parent_class = g_type_class_peek_parent (klass);  object_class->finalize = gdk_drag_context_finalize;}static voidgdk_drag_context_finalize (GObject *object){  GdkDragContext *context = GDK_DRAG_CONTEXT (object);  GdkDragContextPrivateX11 *private = PRIVATE_DATA (context);  GSList *tmp_list;    g_list_free (context->targets);  if (context->source_window)    {      if ((context->protocol == GDK_DRAG_PROTO_XDND) &&          !context->is_source)        xdnd_manage_source_filter (context, context->source_window, FALSE);            g_object_unref (context->source_window);    }    if (context->dest_window)    g_object_unref (context->dest_window);  for (tmp_list = private->window_caches; tmp_list; tmp_list = tmp_list->next)    gdk_window_cache_destroy (tmp_list->data);  g_slist_free (private->window_caches);    contexts = g_list_remove (contexts, context);  g_free (private);    G_OBJECT_CLASS (parent_class)->finalize (object);}/* Drag Contexts *//** * gdk_drag_context_new: *  * Creates a new #GdkDragContext. *  * Return value: the newly created #GdkDragContext. **/GdkDragContext *gdk_drag_context_new        (void){  return g_object_new (gdk_drag_context_get_type (), NULL);}/** * gdk_drag_context_ref: * @context: a #GdkDragContext. *  * Deprecated function; use g_object_ref() instead. **/void            gdk_drag_context_ref (GdkDragContext *context){  g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));  g_object_ref (context);}/** * gdk_drag_context_unref: * @context: a #GdkDragContext. *  * Deprecated function; use g_object_unref() instead. **/void            gdk_drag_context_unref (GdkDragContext *context){  g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));  g_object_unref (context);}static GdkDragContext *gdk_drag_context_find (GdkDisplay *display,		       gboolean    is_source,		       Window      source_xid,		       Window      dest_xid){  GList *tmp_list = contexts;  GdkDragContext *context;  GdkDragContextPrivateX11 *private;  Window context_dest_xid;  while (tmp_list)    {      context = (GdkDragContext *)tmp_list->data;      private = PRIVATE_DATA (context);      if ((context->source_window && gdk_drawable_get_display (context->source_window) != display) ||	  (context->dest_window && gdk_drawable_get_display (context->dest_window) != display))	continue;      context_dest_xid = context->dest_window ?                             (private->drop_xid ?                              private->drop_xid :                              GDK_DRAWABLE_XID (context->dest_window)) :	                     None;      if ((!context->is_source == !is_source) &&	  ((source_xid == None) || (context->source_window &&	    (GDK_DRAWABLE_XID (context->source_window) == source_xid))) &&	  ((dest_xid == None) || (context_dest_xid == dest_xid)))	return context;            tmp_list = tmp_list->next;    }    return NULL;}static voidprecache_target_list (GdkDragContext *context){  if (context->targets)    {      GPtrArray *targets = g_ptr_array_new ();      GList *tmp_list;      int i;      for (tmp_list = context->targets; tmp_list; tmp_list = tmp_list->next)	g_ptr_array_add (targets, gdk_atom_name (GDK_POINTER_TO_ATOM (tmp_list->data)));      _gdk_x11_precache_atoms (GDK_WINDOW_DISPLAY (context->source_window),			       (const gchar **)targets->pdata,			       targets->len);      for (i =0; i < targets->len; i++)	g_free (targets->pdata[i]);      g_ptr_array_free (targets, TRUE);    }}/* Utility functions */static voidgdk_window_cache_add (GdkWindowCache *cache,		      guint32 xid,		      gint x, gint y, gint width, gint height, 		      gboolean mapped){  GdkCacheChild *child = g_new (GdkCacheChild, 1);  child->xid = xid;  child->x = x;  child->y = y;  child->width = width;  child->height = height;  child->mapped = mapped;  cache->children = g_list_prepend (cache->children, child);  g_hash_table_insert (cache->child_hash, GUINT_TO_POINTER (xid), 		       cache->children);}static GdkFilterReturngdk_window_cache_filter (GdkXEvent *xev,			 GdkEvent  *event,			 gpointer   data){  XEvent *xevent = (XEvent *)xev;  GdkWindowCache *cache = data;  switch (xevent->type)    {    case CirculateNotify:      break;    case ConfigureNotify:      {	XConfigureEvent *xce = &xevent->xconfigure;	GList *node;	node = g_hash_table_lookup (cache->child_hash, 				    GUINT_TO_POINTER (xce->window));	if (node) 	  {	    GdkCacheChild *child = node->data;	    child->x = xce->x; 	    child->y = xce->y;	    child->width = xce->width; 	    child->height = xce->height;	    if (xce->above == None && (node->next))	      {		GList *last = g_list_last (cache->children);		cache->children = g_list_remove_link (cache->children, node);		last->next = node;		node->next = NULL;		node->prev = last;	      }	    else	      {		GList *above_node = g_hash_table_lookup (cache->child_hash, 							 GUINT_TO_POINTER (xce->above));		if (above_node && node->next != above_node)		  {		    /* Put the window above (before in the list) above_node		     */		    cache->children = g_list_remove_link (cache->children, node);		    node->prev = above_node->prev;		    if (node->prev)		      node->prev->next = node;		    else		      cache->children = node;		    node->next = above_node;		    above_node->prev = node;		  }	      }	  }	break;      }    case CreateNotify:      {	XCreateWindowEvent *xcwe = &xevent->xcreatewindow;	if (!g_hash_table_lookup (cache->child_hash, 				  GUINT_TO_POINTER (xcwe->window))) 	  gdk_window_cache_add (cache, xcwe->window, 				xcwe->x, xcwe->y, xcwe->width, xcwe->height,				FALSE);	break;      }    case DestroyNotify:      {	XDestroyWindowEvent *xdwe = &xevent->xdestroywindow;	GList *node;	node = g_hash_table_lookup (cache->child_hash, 				    GUINT_TO_POINTER (xdwe->window));	if (node) 	  {	    g_hash_table_remove (cache->child_hash,				 GUINT_TO_POINTER (xdwe->window));	    cache->children = g_list_remove_link (cache->children, node);	    g_free (node->data);	    g_list_free_1 (node);	  }	break;      }    case MapNotify:      {	XMapEvent *xme = &xevent->xmap;	GList *node;	node = g_hash_table_lookup (cache->child_hash, 				    GUINT_TO_POINTER (xme->window));	if (node) 	  {	    GdkCacheChild *child = node->data;	    child->mapped = TRUE;	  }	break;      }    case ReparentNotify:      break;    case UnmapNotify:      {	XMapEvent *xume = &xevent->xmap;	GList *node;	node = g_hash_table_lookup (cache->child_hash, 				    GUINT_TO_POINTER (xume->window));	if (node) 	  {	    GdkCacheChild *child = node->data;	    child->mapped = FALSE;	  }	break;      }    default:      return GDK_FILTER_CONTINUE;    }  return GDK_FILTER_REMOVE;

⌨️ 快捷键说明

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