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

📄 gdkdnd.c

📁 gtk是linux一款强大的夸平台的图形化开发工具
💻 C
📖 第 1 页 / 共 5 页
字号:
  gint old_warnings = gdk_error_warnings;    gdk_error_code = 0;  gdk_error_warnings = 0;  tmp_list = cache->children;  while (tmp_list && !retval)    {      GdkCacheChild *child = tmp_list->data;      if ((child->xid != ignore) && (child->mapped))	{	  if ((x_root >= child->x) && (x_root < child->x + child->width) &&	      (y_root >= child->y) && (y_root < child->y + child->height))	    {	      retval = get_client_window_at_coords_recurse (child->xid,							    x_root - child->x, 							    y_root - child->y);	      if (!retval)		retval = child->xid;	    }	  	}      tmp_list = tmp_list->next;    }  gdk_error_warnings = old_warnings;  if (retval)    return retval;  else    return gdk_root_window;}#if 0static Windowget_client_window_at_coords_recurse (Window  win,				     gint    x_root,				     gint    y_root){  Window child;  Atom type = None;  int format;  unsigned long nitems, after;  unsigned char *data;  int dest_x, dest_y;    static Atom wm_state_atom = None;  if (!wm_state_atom)    wm_state_atom = gdk_atom_intern ("WM_STATE", FALSE);      XGetWindowProperty (gdk_display, win, 		      wm_state_atom, 0, 0, False, AnyPropertyType,		      &type, &format, &nitems, &after, &data);    if (gdk_error_code)    {      gdk_error_code = 0;      return None;    }  if (type != None)    {      XFree (data);      return win;    }  XTranslateCoordinates (gdk_display, gdk_root_window, win,			 x_root, y_root, &dest_x, &dest_y, &child);  if (gdk_error_code)    {      gdk_error_code = 0;      return None;    }  if (child)    return get_client_window_at_coords_recurse (child, x_root, y_root);  else    return None;}static Window get_client_window_at_coords (Window  ignore,			     gint    x_root,			     gint    y_root){  Window root, parent, *children;  unsigned int nchildren;  int i;  Window retval = None;    gint old_warnings = gdk_error_warnings;    gdk_error_code = 0;  gdk_error_warnings = 0;  if (XQueryTree(gdk_display, gdk_root_window, 		 &root, &parent, &children, &nchildren) == 0)    return 0;  for (i = nchildren - 1; (i >= 0) && (retval == None); i--)    {      if (children[i] != ignore)	{	  XWindowAttributes xwa;	  XGetWindowAttributes (gdk_display, children[i], &xwa);	  if (gdk_error_code)	    gdk_error_code = 0;	  else if ((xwa.map_state == IsViewable) &&		   (x_root >= xwa.x) && (x_root < xwa.x + (gint)xwa.width) &&		   (y_root >= xwa.y) && (y_root < xwa.y + (gint)xwa.height))	    {	      retval = get_client_window_at_coords_recurse (children[i],							    x_root, y_root);	      if (!retval)		retval = children[i];	    }	}    }  XFree (children);  gdk_error_warnings = old_warnings;  if (retval)    return retval;  else    return gdk_root_window;}#endif/************************************************************* ***************************** MOTIF ************************* *************************************************************//* values used in the message type for Motif DND */enum {    XmTOP_LEVEL_ENTER,    XmTOP_LEVEL_LEAVE,    XmDRAG_MOTION,    XmDROP_SITE_ENTER,    XmDROP_SITE_LEAVE,    XmDROP_START,    XmDROP_FINISH,    XmDRAG_DROP_FINISH,    XmOPERATION_CHANGED};/* Values used to specify type of protocol to use */enum {    XmDRAG_NONE,    XmDRAG_DROP_ONLY,    XmDRAG_PREFER_PREREGISTER,    XmDRAG_PREREGISTER,    XmDRAG_PREFER_DYNAMIC,    XmDRAG_DYNAMIC,    XmDRAG_PREFER_RECEIVER};/* Operation codes */enum {  XmDROP_NOOP,  XmDROP_MOVE = 0x01,  XmDROP_COPY = 0x02,  XmDROP_LINK = 0x04};/* Drop site status */enum {  XmNO_DROP_SITE = 0x01,  XmDROP_SITE_INVALID = 0x02,  XmDROP_SITE_VALID = 0x03};/* completion status */enum {  XmDROP,  XmDROP_HELP,  XmDROP_CANCEL,  XmDROP_INTERRUPT};/* Static data for MOTIF DND */static GList **motif_target_lists = NULL;static gint motif_n_target_lists = -1;/* Byte swapping routines. The motif specification leaves it * up to us to save a few bytes in the client messages */static gchar local_byte_order = '\0';#ifdef G_ENABLE_DEBUGstatic voidprint_target_list (GList *targets){  while (targets)    {      gchar *name = gdk_atom_name (GPOINTER_TO_INT (targets->data));      g_message ("\t%s", name);      g_free (name);      targets = targets->next;    }}#endif /* G_ENABLE_DEBUG */static voidinit_byte_order (void){  guint32 myint = 0x01020304;  local_byte_order = (*(gchar *)&myint == 1) ? 'B' : 'l';}static guint16card16_to_host (guint16 x, gchar byte_order) {  if (byte_order == local_byte_order)    return x;  else    return (x << 8) | (x >> 8);}static guint32card32_to_host (guint32 x, gchar byte_order) {  if (byte_order == local_byte_order)    return x;  else    return (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24);}/* Motif packs together fields of varying length into the * client message. We can't rely on accessing these * through data.s[], data.l[], etc, because on some architectures * (i.e., Alpha) these won't be valid for format == 8.  */#define MOTIF_XCLIENT_BYTE(xevent,i) \  (xevent)->xclient.data.b[i]#define MOTIF_XCLIENT_SHORT(xevent,i) \  ((gint16 *)&((xevent)->xclient.data.b[0]))[i]#define MOTIF_XCLIENT_LONG(xevent,i) \  ((gint32 *)&((xevent)->xclient.data.b[0]))[i]#define MOTIF_UNPACK_BYTE(xevent,i) MOTIF_XCLIENT_BYTE(xevent,i)#define MOTIF_UNPACK_SHORT(xevent,i) \  card16_to_host (MOTIF_XCLIENT_SHORT(xevent,i), MOTIF_XCLIENT_BYTE(xevent, 1))#define MOTIF_UNPACK_LONG(xevent,i) \  card32_to_host (MOTIF_XCLIENT_LONG(xevent,i), MOTIF_XCLIENT_BYTE(xevent, 1))/***** Dest side ***********//* Property placed on source windows */typedef struct _MotifDragInitiatorInfo {  guint8 byte_order;  guint8 protocol_version;  guint16 targets_index;  guint32 selection_atom;} MotifDragInitiatorInfo;/* Header for target table on the drag window */typedef struct _MotifTargetTableHeader {  guchar byte_order;  guchar protocol_version;  guint16 n_lists;  guint32 total_size;} MotifTargetTableHeader;/* Property placed on target windows */typedef struct _MotifDragReceiverInfo {  guint8 byte_order;  guint8 protocol_version;  guint8 protocol_style;  guint8 pad;  guint32 proxy_window;  guint16 num_drop_sites;  guint16 padding;  guint32 total_size;} MotifDragReceiverInfo;static Window motif_drag_window = None;static GdkWindow *motif_drag_gdk_window = NULL;static GdkAtom motif_drag_targets_atom = GDK_NONE;static GdkAtom motif_drag_receiver_info_atom = GDK_NONE;/* Target table handling */GdkFilterReturnmotif_drag_window_filter (GdkXEvent *xevent,			  GdkEvent  *event,			  gpointer data){  XEvent *xev = (XEvent *)xevent;  switch (xev->xany.type)    {    case DestroyNotify:      motif_drag_window = None;      motif_drag_gdk_window = NULL;      break;    case PropertyNotify:      if (motif_target_lists &&	  motif_drag_targets_atom &&	  (xev->xproperty.atom == motif_drag_targets_atom))	motif_read_target_table();      break;    }  return GDK_FILTER_REMOVE;}static Atom motif_drag_window_atom = GDK_NONE;static Windowmotif_lookup_drag_window (Display *display){  Window retval = None;  gulong bytes_after, nitems;  GdkAtom type;  gint format;  guchar *data;  XGetWindowProperty (gdk_display, gdk_root_window, motif_drag_window_atom,		      0, 1, FALSE,		      XA_WINDOW, &type, &format, &nitems, &bytes_after,		      &data);    if ((format == 32) && (nitems == 1) && (bytes_after == 0))    {      retval = *(Window *)data;      GDK_NOTE(DND, 	       g_message ("Found drag window %#lx\n", motif_drag_window));    }  if (type != None)    XFree (data);  return retval;}/* Finds the window where global Motif drag information is stored. * If it doesn't exist and 'create' is TRUE, create one. */Window motif_find_drag_window (gboolean create){  if (!motif_drag_window)    {      if (!motif_drag_window_atom)	motif_drag_window_atom = gdk_atom_intern ("_MOTIF_DRAG_WINDOW", TRUE);      motif_drag_window = motif_lookup_drag_window (gdk_display);            if (!motif_drag_window && create)	{	  /* Create a persistant window. (Copied from LessTif) */	  	  Display *display;	  XSetWindowAttributes attr;	  display = XOpenDisplay (gdk_display_name);	  XSetCloseDownMode (display, RetainPermanent);	  XGrabServer (display);	  	  motif_drag_window = motif_lookup_drag_window (display);	  if (!motif_drag_window)	    {	      attr.override_redirect = True;	      attr.event_mask = PropertyChangeMask;	      	      motif_drag_window = 		XCreateWindow(display, DefaultRootWindow(display),			      -100, -100, 10, 10, 0, 0,			      InputOnly, CopyFromParent,			      (CWOverrideRedirect | CWEventMask), &attr);	      	      GDK_NOTE (DND,			g_message ("Created drag window %#lx\n", motif_drag_window));	      	      XChangeProperty (display, gdk_root_window,			       motif_drag_window_atom, XA_WINDOW,			       32, PropModeReplace,			       (guchar *)&motif_drag_window_atom, 1);	    }	  XUngrabServer (display);	  XCloseDisplay (display);	}      /* There is a miniscule race condition here if the drag window       * gets destroyed exactly now.       */      if (motif_drag_window)	{	  motif_drag_gdk_window = gdk_window_foreign_new (motif_drag_window);	  gdk_window_add_filter (motif_drag_gdk_window,				 motif_drag_window_filter,				 NULL);	}    }  return motif_drag_window;}static void motif_read_target_table (void){  gulong bytes_after, nitems;  GdkAtom type;  gint format;  gint i, j;  if (!motif_drag_targets_atom)    motif_drag_targets_atom = gdk_atom_intern ("_MOTIF_DRAG_TARGETS", FALSE);  if (motif_target_lists)    {      for (i=0; i<motif_n_target_lists; i++)	g_list_free (motif_target_lists[i]);            g_free (motif_target_lists);      motif_target_lists = NULL;      motif_n_target_lists = 0;    }  if (motif_find_drag_window (FALSE))    {      MotifTargetTableHeader *header = NULL;      guchar *target_bytes = NULL;      guchar *p;      gboolean success = FALSE;      XGetWindowProperty (gdk_display, motif_drag_window, 			  motif_drag_targets_atom,			  0, (sizeof(MotifTargetTableHeader)+3)/4, FALSE,			  motif_drag_targets_atom, 			  &type, &format, &nitems, &bytes_after,			  (guchar **)&header);      if ((format != 8) || (nitems < sizeof (MotifTargetTableHeader)))	goto error;      header->n_lists = card16_to_host (header->n_lists, header->byte_order);      header->total_size = card32_to_host (header->total_size, header->byte_order);      XGetWindowProperty (gdk_display, motif_drag_window, motif_drag_targets_atom,			  (sizeof(MotifTargetTableHeader)+3)/4, 			  (header->total_size + 3)/4 - (sizeof(MotifTargetTableHeader) + 3)/4,			  FALSE,			  motif_drag_targets_atom, &type, &format, &nitems, 			  &bytes_after, &target_bytes);            if ((format != 8) || (bytes_after != 0) || 	  (nitems != header->total_size - sizeof(MotifTargetTableHeader)))	  goto error;      motif_n_target_lists = header->n_lists;      motif_target_lists = g_new0 (GList *, motif_n_target_lists);      p = target_bytes;      for (i=0; i<header->n_lists; i++)	{	  gint n_targets;	  guint32 *targets;	  	  if (p + sizeof(guint16) - target_bytes > nitems)	    goto error;	  n_targets = card16_to_host (*(gushort *)p, header->byte_order);	  /* We need to make a copy of the targets, since it may	   * be unaligned	   */	  targets = g_new (guint32, n_targets);	  memcpy (targets, p + sizeof(guint16), sizeof(guint32) * n_targets);	  p +=  sizeof(guint16) + n_targets * sizeof(guint32);	  if (p - target_bytes > nitems)	    goto error;	  for (j=0; j<n_targets; j++)	    motif_target_lists[i] = 	      g_list_prepend (motif_target_lists[i],			      GUINT_TO_POINTER (card32_to_host (targets[j], 								header->byte_order)));	  g_free (targets);	  motif_target_lists[i] = g_list_reverse (motif_target_lists[i]);	}      success = TRUE;          error:      if (header)	XFree (header);            if (target_bytes)	XFree (target_bytes);      if (!success)	{	  if (motif_target_lists)	    {	      g_free (motif_target_lists);	      motif_target_lists = NULL;	      motif_n_target_lists = 0;	    }	  g_warning ("Error reading Motif target table\n");	}    }}

⌨️ 快捷键说明

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