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

📄 gdkdnd-x11.c

📁 linux下电话本所依赖的一些图形库
💻 C
📖 第 1 页 / 共 5 页
字号:
  return retval;}static voidmotif_send_drop (GdkDragContext *context, guint32 time){  GdkDragContextPrivateX11 *private = PRIVATE_DATA (context);  GdkDisplay *display = GDK_DRAWABLE_DISPLAY (context->source_window);  XEvent xev;  xev.xclient.type = ClientMessage;  xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_MOTIF_DRAG_AND_DROP_MESSAGE");  xev.xclient.format = 8;  xev.xclient.window = GDK_DRAWABLE_XID (context->dest_window);  MOTIF_XCLIENT_BYTE (&xev, 0) = XmDROP_START;  MOTIF_XCLIENT_BYTE (&xev, 1) = local_byte_order;  MOTIF_XCLIENT_SHORT (&xev, 1) = motif_dnd_get_flags (context);  MOTIF_XCLIENT_LONG (&xev, 1)  = time;  MOTIF_XCLIENT_SHORT (&xev, 4) = private->last_x;  MOTIF_XCLIENT_SHORT (&xev, 5) = private->last_y;  MOTIF_XCLIENT_LONG (&xev, 3)  = private->motif_selection;  MOTIF_XCLIENT_LONG (&xev, 4)  = GDK_DRAWABLE_XID (context->source_window);  if (!_gdk_send_xevent (display,			 GDK_DRAWABLE_XID (context->dest_window),			 FALSE, 0, &xev))    GDK_NOTE (DND, 	      g_message ("Send event to %lx failed",			 GDK_DRAWABLE_XID (context->dest_window)));}/* Target Side */static gbooleanmotif_read_initiator_info (GdkDisplay *display,			   Window      source_window, 			   Atom        atom,			   GList     **targets,			   Atom       *selection){  GList *tmp_list;  Atom type;  gint format;  gulong nitems;  gulong bytes_after;  guchar *data;  MotifDragInitiatorInfo *initiator_info;    GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);    gdk_error_trap_push ();  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), source_window, atom,		      0, sizeof(*initiator_info), FALSE,		      gdk_x11_get_xatom_by_name_for_display (display, "_MOTIF_DRAG_INITIATOR_INFO"),		      &type, &format, &nitems, &bytes_after,		      &data);  if (gdk_error_trap_pop () || (format != 8) || (nitems != sizeof (MotifDragInitiatorInfo)) || (bytes_after != 0))    {      g_warning ("Error reading initiator info\n");      return FALSE;    }  initiator_info = (MotifDragInitiatorInfo *)data;  motif_read_target_table (display);  initiator_info->targets_index =     card16_to_host (initiator_info->targets_index, initiator_info->byte_order);  initiator_info->selection_atom =     card32_to_host (initiator_info->selection_atom, initiator_info->byte_order);    if (initiator_info->targets_index >= display_x11->motif_n_target_lists)    {      g_warning ("Invalid target index in TOP_LEVEL_ENTER MESSAGE");      XFree (initiator_info);      return FALSE;    }  tmp_list = g_list_last (display_x11->motif_target_lists[initiator_info->targets_index]);  *targets = NULL;  while (tmp_list)    {      GdkAtom atom = gdk_x11_xatom_to_atom_for_display (display, GPOINTER_TO_UINT (tmp_list->data));      *targets = g_list_prepend (*targets, GDK_ATOM_TO_POINTER (atom));      tmp_list = tmp_list->prev;    }#ifdef G_ENABLE_DEBUG  if (_gdk_debug_flags & GDK_DEBUG_DND)    print_target_list (*targets);#endif /* G_ENABLE_DEBUG */  *selection = initiator_info->selection_atom;  XFree (initiator_info);  return TRUE;}static GdkDragContext *motif_drag_context_new (GdkWindow *dest_window,			guint32    timestamp,			guint32    source_window,			guint32    atom){  GdkDragContext *new_context;  GdkDragContextPrivateX11 *private;  GdkDisplay *display = GDK_DRAWABLE_DISPLAY (dest_window);  GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);  /* FIXME, current_dest_drag really shouldn't be NULL'd   * if we error below.   */  if (display_x11->current_dest_drag != NULL)    {      if (timestamp >= display_x11->current_dest_drag->start_time)	{	  g_object_unref (display_x11->current_dest_drag);	  display_x11->current_dest_drag = NULL;	}      else	return NULL;    }  new_context = gdk_drag_context_new ();  private = PRIVATE_DATA (new_context);  new_context->protocol = GDK_DRAG_PROTO_MOTIF;  new_context->is_source = FALSE;  new_context->source_window = gdk_window_lookup_for_display (display, source_window);  if (new_context->source_window)    g_object_ref (new_context->source_window);  else    {      new_context->source_window = gdk_window_foreign_new_for_display (display, source_window);      if (!new_context->source_window)	{	  g_object_unref (new_context);	  return NULL;	}    }  new_context->dest_window = dest_window;  g_object_ref (dest_window);  new_context->start_time = timestamp;  if (!motif_read_initiator_info (GDK_WINDOW_DISPLAY (dest_window),				  source_window,				  atom,				  &new_context->targets,				  &private->motif_selection))    {      g_object_unref (new_context);      return NULL;    }  return new_context;}/* * The MOTIF drag protocol has no real provisions for distinguishing * multiple simultaneous drops. If the sources grab the pointer * when doing drags, that shouldn't happen, in any case. If it * does, we can't do much except hope for the best. */static GdkFilterReturnmotif_top_level_enter (GdkEvent *event,		       guint16   flags, 		       guint32   timestamp, 		       guint32   source_window, 		       guint32   atom){  GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_DRAWABLE_DISPLAY (event->any.window));  GdkDragContext *new_context;  GDK_NOTE(DND, g_message ("Motif DND top level enter: flags: %#4x time: %d source_widow: %#4x atom: %d",			   flags, timestamp, source_window, atom));  new_context = motif_drag_context_new (event->any.window, timestamp, source_window, atom);  if (!new_context)    return GDK_FILTER_REMOVE;  event->dnd.type = GDK_DRAG_ENTER;  event->dnd.context = new_context;  g_object_ref (new_context);  display_x11->current_dest_drag = new_context;  return GDK_FILTER_TRANSLATE;}static GdkFilterReturnmotif_top_level_leave (GdkEvent *event,		       guint16   flags, 		       guint32   timestamp){  GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_DRAWABLE_DISPLAY (event->any.window));  GDK_NOTE(DND, g_message ("Motif DND top level leave: flags: %#4x time: %d",			   flags, timestamp));  if ((display_x11->current_dest_drag != NULL) &&      (display_x11->current_dest_drag->protocol == GDK_DRAG_PROTO_MOTIF) &&      (timestamp >= display_x11->current_dest_drag->start_time))    {      event->dnd.type = GDK_DRAG_LEAVE;      /* Pass ownership of context to the event */      event->dnd.context = display_x11->current_dest_drag;      display_x11->current_dest_drag = NULL;      return GDK_FILTER_TRANSLATE;    }  else    return GDK_FILTER_REMOVE;}static GdkFilterReturnmotif_motion (GdkEvent *event,	      guint16   flags, 	      guint32   timestamp,	      gint16    x_root,	      gint16    y_root){  GdkDragContextPrivateX11 *private;  GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_DRAWABLE_DISPLAY (event->any.window));    GDK_NOTE(DND, g_message ("Motif DND motion: flags: %#4x time: %d (%d, %d)",			   flags, timestamp, x_root, y_root));  if ((display_x11->current_dest_drag != NULL) &&      (display_x11->current_dest_drag->protocol == GDK_DRAG_PROTO_MOTIF) &&      (timestamp >= display_x11->current_dest_drag->start_time))    {      private = PRIVATE_DATA (display_x11->current_dest_drag);      event->dnd.type = GDK_DRAG_MOTION;      event->dnd.context = display_x11->current_dest_drag;      g_object_ref (display_x11->current_dest_drag);      event->dnd.time = timestamp;      motif_dnd_translate_flags (display_x11->current_dest_drag, flags);      event->dnd.x_root = x_root;      event->dnd.y_root = y_root;      private->last_x = x_root;      private->last_y = y_root;      private->drag_status = GDK_DRAG_STATUS_MOTION_WAIT;      return GDK_FILTER_TRANSLATE;    }  return GDK_FILTER_REMOVE;}static GdkFilterReturnmotif_operation_changed (GdkEvent *event,			 guint16   flags, 			 guint32   timestamp){  GdkDragContextPrivateX11 *private;  GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_DRAWABLE_DISPLAY (event->any.window));  GDK_NOTE(DND, g_message ("Motif DND operation changed: flags: %#4x time: %d",			   flags, timestamp));  if ((display_x11->current_dest_drag != NULL) &&      (display_x11->current_dest_drag->protocol == GDK_DRAG_PROTO_MOTIF) &&      (timestamp >= display_x11->current_dest_drag->start_time))    {      event->dnd.type = GDK_DRAG_MOTION;      event->dnd.send_event = FALSE;      event->dnd.context = display_x11->current_dest_drag;      g_object_ref (display_x11->current_dest_drag);      event->dnd.time = timestamp;      private = PRIVATE_DATA (display_x11->current_dest_drag);      motif_dnd_translate_flags (display_x11->current_dest_drag, flags);      event->dnd.x_root = private->last_x;      event->dnd.y_root = private->last_y;      private->drag_status = GDK_DRAG_STATUS_ACTION_WAIT;      return GDK_FILTER_TRANSLATE;    }  return GDK_FILTER_REMOVE;}static GdkFilterReturnmotif_drop_start (GdkEvent *event,		  guint16   flags,		  guint32   timestamp,		  guint32   source_window,		  guint32   atom,		  gint16    x_root,		  gint16    y_root){  GdkDragContext *new_context;  GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_DRAWABLE_DISPLAY (event->any.window));  GDK_NOTE(DND, g_message ("Motif DND drop start: flags: %#4x time: %d (%d, %d) source_widow: %#4x atom: %d",			   flags, timestamp, x_root, y_root, source_window, atom));  new_context = motif_drag_context_new (event->any.window, timestamp, source_window, atom);  if (!new_context)    return GDK_FILTER_REMOVE;  motif_dnd_translate_flags (new_context, flags);  event->dnd.type = GDK_DROP_START;  event->dnd.context = new_context;  event->dnd.time = timestamp;  event->dnd.x_root = x_root;  event->dnd.y_root = y_root;  gdk_x11_window_set_user_time (event->any.window, timestamp);  g_object_ref (new_context);  display_x11->current_dest_drag = new_context;  return GDK_FILTER_TRANSLATE;}  static GdkFilterReturnmotif_drag_status (GdkEvent *event,		   guint16   flags,		   guint32   timestamp){  GdkDragContext *context;  GdkDisplay *display;    GDK_NOTE (DND, 	    g_message ("Motif status message: flags %x", flags));  display = gdk_drawable_get_display (event->any.window);  if (!display)    return GDK_FILTER_REMOVE;    context = gdk_drag_context_find (display, TRUE, GDK_DRAWABLE_XID (event->any.window), None);  if (context)    {      GdkDragContextPrivateX11 *private = PRIVATE_DATA (context);      if ((private->drag_status == GDK_DRAG_STATUS_MOTION_WAIT) ||	  (private->drag_status == GDK_DRAG_STATUS_ACTION_WAIT))	private->drag_status = GDK_DRAG_STATUS_DRAG;            event->dnd.type = GDK_DRAG_STATUS;      event->dnd.send_event = FALSE;      event->dnd.context = context;      g_object_ref (context);      event->dnd.time = timestamp;      if ((flags & 0x00f0) >> 4 == XmDROP_SITE_VALID)	{	  switch (flags & 0x000f)	    {	    case XmDROP_NOOP:	      context->action = 0;	      break;	    case XmDROP_MOVE:		context->action = GDK_ACTION_MOVE;		break;	    case XmDROP_COPY:	      context->action = GDK_ACTION_COPY;	      break;	    case XmDROP_LINK:	      context->action = GDK_ACTION_LINK;	      break;	    }	}      else	context->action = 0;      return GDK_FILTER_TRANSLATE;    }  return GDK_FILTER_REMOVE;}static GdkFilterReturnmotif_dnd_filter (GdkXEvent *xev,		  GdkEvent  *event,		  gpointer data){  XEvent *xevent = (XEvent *)xev;  guint8 reason;  guint16 flags;  guint32 timestamp;  guint32 source_window;  Atom atom;  gint16 x_root, y_root;  gboolean is_reply;  if (!event->any.window ||      gdk_window_get_window_type (event->any.window) == GDK_WINDOW_FOREIGN)    return GDK_FILTER_CONTINUE;			/* Not for us */    /* First read some fields common to all Motif DND messages */  reason = MOTIF_UNPACK_BYTE (xevent, 0);  flags = MOTIF_UNPACK_SHORT (xevent, 1);  timestamp = MOTIF_UNPACK_LONG (xevent, 1);  is_reply = ((reason & 0x80) != 0);  switch (reason & 0x7f)    {    case XmTOP_LEVEL_ENTER:      source_window = MOTIF_UNPACK_LONG (xevent, 2);      atom = MOTIF_UNPACK_LONG (xevent, 3);      return motif_top_level_enter (event, flags, timestamp, source_window, atom);    case XmTOP_LEVEL_LEAVE:      return motif_top_level_leave (event, flags, timestamp);    case XmDRAG_MOTION:      x_root = MOTIF_UNPACK_SHORT (xevent, 4);      y_root = MOTIF_UNPACK_SHORT (xevent, 5);            if (!is_reply)	return motif_motion (event, flags, timestamp, x_root, y_root);      else	return motif_drag_status (event, flags, timestamp);    case XmDROP_SITE_ENTER:      return motif_drag_status (event, flags, timestamp);    case XmDROP_SITE_LEAVE:      return motif_drag_status (event,				XmNO_DROP_SITE << 8 | XmDROP_NOOP, 				timestamp);    case XmDROP_START:      x_root = MOTIF_UNPACK_SHORT (xevent, 4);      y_root = MOTIF_UNPACK_SHORT (xevent, 5);      atom = MOTIF_UNPACK_LONG (xevent, 3);      source_window = MOTIF_UNPACK_LONG (xevent, 4);      if (!is_reply)	return motif_drop_start (event, flags, timestamp, source_window, atom, x_root, y_root);           break;    case XmOPERATION_CHANGED:      if (!is_reply)	return motif_operation_changed (event, flags, timestamp);      else	return motif_drag_status (event, flags, timestamp);      break;      /* To the best of my knowledge, these next two messages are        * not part of the protocol, though they are defined in       * the header files.       */    case XmDROP_FINISH:    case XmDRAG_DROP_FINISH:      break;    }  return GDK_FILTER_REMOVE;}

⌨️ 快捷键说明

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