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

📄 gdkdnd.c

📁 gtk是linux一款强大的夸平台的图形化开发工具
💻 C
📖 第 1 页 / 共 5 页
字号:
static ginttargets_sort_func (gconstpointer a, gconstpointer b){  return (GPOINTER_TO_UINT (a) < GPOINTER_TO_UINT (b)) ?    -1 : ((GPOINTER_TO_UINT (a) > GPOINTER_TO_UINT (b)) ? 1 : 0);}/* Check if given (sorted) list is in the targets table */static gbooleanmotif_target_table_check (GList *sorted){  GList *tmp_list1, *tmp_list2;  gint i;  for (i=0; i<motif_n_target_lists; i++)    {      tmp_list1 = motif_target_lists[i];      tmp_list2 = sorted;            while (tmp_list1 && tmp_list2)	{	  if (tmp_list1->data != tmp_list2->data)	    break;	  tmp_list1 = tmp_list1->next;	  tmp_list2 = tmp_list2->next;	}      if (!tmp_list1 && !tmp_list2)	/* Found it */	return i;    }  return -1;}static gintmotif_add_to_target_table (GList *targets){  GList *sorted = NULL;  gint index = -1;  gint i;  GList *tmp_list;    /* make a sorted copy of the list */    while (targets)    {      sorted = g_list_insert_sorted (sorted, targets->data, targets_sort_func);      targets = targets->next;    }  /* First check if it is their already */  if (motif_target_lists)    index = motif_target_table_check (sorted);  /* We need to grab the server while doing this, to ensure   * atomiticity. Ugh   */  if (index < 0)    {      /* We need to make sure that it exists _before_ we grab the       * server, since we can't open a new connection after we       * grab the server.        */      motif_find_drag_window (TRUE);      XGrabServer(gdk_display);      motif_read_target_table();          /* Check again, in case it was added in the meantime */            if (motif_target_lists)	index =  motif_target_table_check (sorted);      if (index < 0)	{	  guint32 total_size = 0;	  guchar *data;	  guchar *p;	  guint16 *p16;	  MotifTargetTableHeader *header;	  	  if (!motif_target_lists)	    {	      motif_target_lists = g_new (GList *, 1);	      motif_n_target_lists = 1;	    }	  else	    {	      motif_n_target_lists++;	      motif_target_lists = g_realloc (motif_target_lists,					      sizeof(GList *) * motif_n_target_lists);	    }	  motif_target_lists[motif_n_target_lists - 1] = sorted;	  sorted = NULL;	  index = motif_n_target_lists - 1;	  total_size = sizeof (MotifTargetTableHeader);	  for (i = 0; i < motif_n_target_lists ; i++)	    total_size += sizeof(guint16) + sizeof(guint32) * g_list_length (motif_target_lists[i]);	  data = g_malloc (total_size);	  header = (MotifTargetTableHeader *)data;	  p = data + sizeof(MotifTargetTableHeader);	  header->byte_order = local_byte_order;	  header->protocol_version = 0;	  header->n_lists = motif_n_target_lists;	  header->total_size = total_size;	  for (i = 0; i < motif_n_target_lists ; i++)	    {	      guint16 n_targets = g_list_length (motif_target_lists[i]);	      guint32 *targets = g_new (guint32, n_targets);	      guint32 *p32 = targets;	      	      tmp_list = motif_target_lists[i];	      while (tmp_list)		{		  *p32 = GPOINTER_TO_UINT (tmp_list->data);		  		  tmp_list = tmp_list->next;		  p32++;		}	      p16 = (guint16 *)p;	      p += sizeof(guint16);	      memcpy (p, targets, n_targets * sizeof(guint32));	      *p16 = n_targets;	      p += sizeof(guint32) * n_targets;	      g_free (targets);	    }	  XChangeProperty (gdk_display, motif_drag_window,			   motif_drag_targets_atom,			   motif_drag_targets_atom,			   8, PropModeReplace,			   data, total_size);	}      XUngrabServer(gdk_display);    }  g_list_free (sorted);  return index;}/* Translate flags */static voidmotif_dnd_translate_flags (GdkDragContext *context, guint16 flags){  guint recommended_op = flags & 0x000f;  guint possible_ops = (flags & 0x0f0) >> 4;    switch (recommended_op)    {    case XmDROP_MOVE:      context->suggested_action = GDK_ACTION_MOVE;      break;    case XmDROP_COPY:      context->suggested_action = GDK_ACTION_COPY;      break;    case XmDROP_LINK:      context->suggested_action = GDK_ACTION_LINK;      break;    default:      context->suggested_action = GDK_ACTION_COPY;      break;    }  context->actions = 0;  if (possible_ops & XmDROP_MOVE)    context->actions |= GDK_ACTION_MOVE;  if (possible_ops & XmDROP_COPY)    context->actions |= GDK_ACTION_COPY;  if (possible_ops & XmDROP_LINK)    context->actions |= GDK_ACTION_LINK;}static guint16motif_dnd_get_flags (GdkDragContext *context){  guint16 flags = 0;    switch (context->suggested_action)    {    case GDK_ACTION_MOVE:      flags = XmDROP_MOVE;      break;    case GDK_ACTION_COPY:      flags = XmDROP_COPY;      break;    case GDK_ACTION_LINK:      flags = XmDROP_LINK;      break;    default:      flags = XmDROP_NOOP;      break;    }    if (context->actions & GDK_ACTION_MOVE)    flags |= XmDROP_MOVE << 8;  if (context->actions & GDK_ACTION_COPY)    flags |= XmDROP_COPY << 8;  if (context->actions & GDK_ACTION_LINK)    flags |= XmDROP_LINK << 8;  return flags;}/* Source Side */static voidmotif_set_targets (GdkDragContext *context){  GdkDragContextPrivate *private = (GdkDragContextPrivate *)context;  MotifDragInitiatorInfo info;  gint i;  static GdkAtom motif_drag_initiator_info = GDK_NONE;  if (!motif_drag_initiator_info)    motif_drag_initiator_info = gdk_atom_intern ("_MOTIF_DRAG_INITIATOR_INFO", FALSE);  info.byte_order = local_byte_order;  info.protocol_version = 0;    info.targets_index = motif_add_to_target_table (context->targets);  for (i=0; ; i++)    {      gchar buf[20];      g_snprintf(buf, 20, "_GDK_SELECTION_%d", i);            private->motif_selection = gdk_atom_intern (buf, FALSE);      if (!XGetSelectionOwner (gdk_display, private->motif_selection))	break;    }  info.selection_atom = private->motif_selection;  XChangeProperty (GDK_WINDOW_XDISPLAY (context->source_window),		   GDK_WINDOW_XWINDOW (context->source_window),		   private->motif_selection,		   motif_drag_initiator_info, 8, PropModeReplace,		   (guchar *)&info, sizeof (info));  private->motif_targets_set = 1;}guint32motif_check_dest (Window win){  gboolean retval = FALSE;  MotifDragReceiverInfo *info;  Atom type = None;  int format;  unsigned long nitems, after;  if (!motif_drag_receiver_info_atom)    motif_drag_receiver_info_atom = gdk_atom_intern ("_MOTIF_DRAG_RECEIVER_INFO", FALSE);  XGetWindowProperty (gdk_display, win, 		      motif_drag_receiver_info_atom, 		      0, (sizeof(*info)+3)/4, False, AnyPropertyType,		      &type, &format, &nitems, &after, 		      (guchar **)&info);    if (type != None)    {      if ((format == 8) && (nitems == sizeof(*info)))	{	  if ((info->protocol_version == 0) &&	      ((info->protocol_style == XmDRAG_PREFER_PREREGISTER) ||	       (info->protocol_style == XmDRAG_PREFER_DYNAMIC) ||	       (info->protocol_style == XmDRAG_DYNAMIC)))	    retval = TRUE;	}      else	{	  GDK_NOTE (DND, 		    g_warning ("Invalid Motif drag receiver property on window %ld\n", win));	}      XFree (info);    }  return retval ? win : GDK_NONE;  }static voidmotif_send_enter (GdkDragContext  *context,		  guint32          time){  XEvent xev;  GdkDragContextPrivate *private = (GdkDragContextPrivate *)context;  xev.xclient.type = ClientMessage;  xev.xclient.message_type = gdk_atom_intern ("_MOTIF_DRAG_AND_DROP_MESSAGE", FALSE);  xev.xclient.format = 8;  xev.xclient.window = GDK_WINDOW_XWINDOW (context->dest_window);  MOTIF_XCLIENT_BYTE (&xev, 0) = XmTOP_LEVEL_ENTER;  MOTIF_XCLIENT_BYTE (&xev, 1) = local_byte_order;  MOTIF_XCLIENT_SHORT (&xev, 1) = 0;  MOTIF_XCLIENT_LONG (&xev, 1) = time;  MOTIF_XCLIENT_LONG (&xev, 2) = GDK_WINDOW_XWINDOW (context->source_window);  if (!private->motif_targets_set)    motif_set_targets (context);  MOTIF_XCLIENT_LONG (&xev, 3) = private->motif_selection;  if (!gdk_send_xevent (GDK_WINDOW_XWINDOW (context->dest_window),			FALSE, 0, &xev))    GDK_NOTE (DND, 	      g_message ("Send event to %lx failed",			 GDK_WINDOW_XWINDOW (context->dest_window)));}static voidmotif_send_leave (GdkDragContext  *context,		  guint32          time){  XEvent xev;  xev.xclient.type = ClientMessage;  xev.xclient.message_type = gdk_atom_intern ("_MOTIF_DRAG_AND_DROP_MESSAGE", FALSE);  xev.xclient.format = 8;  xev.xclient.window = GDK_WINDOW_XWINDOW (context->dest_window);  MOTIF_XCLIENT_BYTE (&xev, 0) = XmTOP_LEVEL_LEAVE;  MOTIF_XCLIENT_BYTE (&xev, 1) = local_byte_order;  MOTIF_XCLIENT_SHORT (&xev, 1) = 0;  MOTIF_XCLIENT_LONG (&xev, 1) = time;  MOTIF_XCLIENT_LONG (&xev, 2) = GDK_WINDOW_XWINDOW (context->source_window);  MOTIF_XCLIENT_LONG (&xev, 3) = 0;  if (!gdk_send_xevent (GDK_WINDOW_XWINDOW (context->dest_window),			FALSE, 0, &xev))    GDK_NOTE (DND, 	      g_message ("Send event to %lx failed",			 GDK_WINDOW_XWINDOW (context->dest_window)));}static gbooleanmotif_send_motion (GdkDragContext  *context,		    gint            x_root, 		    gint            y_root,		    GdkDragAction   action,		    guint32         time){  gboolean retval;  XEvent xev;  GdkDragContextPrivate *private = (GdkDragContextPrivate *)context;  xev.xclient.type = ClientMessage;  xev.xclient.message_type = gdk_atom_intern ("_MOTIF_DRAG_AND_DROP_MESSAGE", FALSE);  xev.xclient.format = 8;  xev.xclient.window = GDK_WINDOW_XWINDOW (context->dest_window);  MOTIF_XCLIENT_BYTE (&xev, 1) = local_byte_order;  MOTIF_XCLIENT_SHORT (&xev, 1) = motif_dnd_get_flags (context);  MOTIF_XCLIENT_LONG (&xev, 1) = time;  if ((context->suggested_action != private->old_action) ||      (context->actions != private->old_actions))    {      MOTIF_XCLIENT_BYTE (&xev, 0) = XmOPERATION_CHANGED;      /* private->drag_status = GDK_DRAG_STATUS_ACTION_WAIT; */      retval = TRUE;    }  else    {      MOTIF_XCLIENT_BYTE (&xev, 0) = XmDRAG_MOTION;      MOTIF_XCLIENT_SHORT (&xev, 4) = x_root;      MOTIF_XCLIENT_SHORT (&xev, 5) = y_root;            private->drag_status = GDK_DRAG_STATUS_MOTION_WAIT;      retval = FALSE;    }  if (!gdk_send_xevent (GDK_WINDOW_XWINDOW (context->dest_window),			FALSE, 0, &xev))    GDK_NOTE (DND, 	      g_message ("Send event to %lx failed",			 GDK_WINDOW_XWINDOW (context->dest_window)));  return retval;}static voidmotif_send_drop (GdkDragContext *context, guint32 time){  XEvent xev;  GdkDragContextPrivate *private = (GdkDragContextPrivate *)context;  xev.xclient.type = ClientMessage;  xev.xclient.message_type = gdk_atom_intern ("_MOTIF_DRAG_AND_DROP_MESSAGE", FALSE);  xev.xclient.format = 8;  xev.xclient.window = GDK_WINDOW_XWINDOW (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_WINDOW_XWINDOW (context->source_window);  if (!gdk_send_xevent (GDK_WINDOW_XWINDOW (context->dest_window),			FALSE, 0, &xev))    GDK_NOTE (DND, 	      g_message ("Send event to %lx failed",			 GDK_WINDOW_XWINDOW (context->dest_window)));}/* Target Side */static gbooleanmotif_read_initiator_info (Window source_window, 			   Atom atom,			   GList  **targets,			   GdkAtom *selection){  GList *tmp_list;  static GdkAtom motif_drag_initiator_info = GDK_NONE;  GdkAtom type;  gint format;  gulong nitems;  gulong bytes_after;  MotifDragInitiatorInfo *initiator_info;  if (!motif_drag_initiator_info)    motif_drag_initiator_info = gdk_atom_intern ("_MOTIF_DRAG_INITIATOR_INFO", FALSE);  XGetWindowProperty (gdk_display, source_window, atom,		      0, sizeof(*initiator_info), FALSE,		      motif_drag_initiator_info, 		      &type, &format, &nitems, &bytes_after,		      (guchar **)&initiator_info);  if ((format != 8) || (nitems != sizeof (MotifDragInitiatorInfo)) || (bytes_after != 0))    {      g_warning ("Error reading initiator info\n");      return FALSE;    }  motif_read_target_table ();  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 >= motif_n_target_lists)    {      g_warning ("Invalid target index in TOP_LEVEL_ENTER MESSAGE");      XFree (initiator_info);      return GDK_FILTER_REMOVE;    }  tmp_list = g_list_last (motif_target_lists[initiator_info->targets_index]);  *targets = NULL;  while (tmp_list)    {      *targets = g_list_prepend (*targets,				 tmp_list->data);      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;  GdkDragContextPrivate *private;  /* FIXME, current_dest_drag really shouldn't be NULL'd   * if we error below.   */  if (current_dest_drag != NULL)    {      if (timestamp >= current_dest_drag->start_time)	{	  gdk_drag_context_unref (current_dest_drag);	  current_dest_drag = NULL;	}      else

⌨️ 快捷键说明

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