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

📄 gdkdnd-x11.c

📁 linux下电话本所依赖的一些图形库
💻 C
📖 第 1 页 / 共 5 页
字号:
      if (gdk_error_trap_pop () || (format != 8) || (bytes_after != 0) || 	  (nitems != header->total_size - sizeof(MotifTargetTableHeader)))	  goto error;      display_x11->motif_n_target_lists = header->n_lists;      display_x11->motif_target_lists = g_new0 (GList *, display_x11->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++)	    display_x11->motif_target_lists[i] = 	      g_list_prepend (display_x11->motif_target_lists[i],			      GUINT_TO_POINTER (card32_to_host (targets[j],								header->byte_order)));	  g_free (targets);	  display_x11->motif_target_lists[i] = g_list_reverse (display_x11->motif_target_lists[i]);	}      success = TRUE;          error:      if (header)	XFree (header);            if (target_bytes)	XFree (target_bytes);      if (!success)	{	  if (display_x11->motif_target_lists)	    {	      g_free (display_x11->motif_target_lists);	      display_x11->motif_target_lists = NULL;	      display_x11->motif_n_target_lists = 0;	    }	  g_warning ("Error reading Motif target table\n");	}    }}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 gintmotif_target_table_check (GdkDisplay *display,			  GList      *sorted){  GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);  GList *tmp_list1, *tmp_list2;  gint i;  for (i=0; i<display_x11->motif_n_target_lists; i++)    {      tmp_list1 = display_x11->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 (GdkDisplay *display,			   GList      *targets) /* targets is list of GdkAtom */{  GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);  GList *sorted = NULL;  gint index = -1;  gint i;  GList *tmp_list;    /* make a sorted copy of the list */    while (targets)    {      Atom xatom = gdk_x11_atom_to_xatom_for_display (display, GDK_POINTER_TO_ATOM (targets->data));      sorted = g_list_insert_sorted (sorted, GUINT_TO_POINTER (xatom), targets_sort_func);      targets = targets->next;    }  /* First check if it is there already */  if (display_x11->motif_target_lists)    index = motif_target_table_check (display, 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 (display, TRUE);      gdk_x11_display_grab (display);      motif_read_target_table (display);          /* Check again, in case it was added in the meantime */            if (display_x11->motif_target_lists)	index = motif_target_table_check (display, sorted);      if (index < 0)	{	  guint32 total_size = 0;	  guchar *data;	  guchar *p;	  guint16 *p16;	  MotifTargetTableHeader *header;	  	  if (!display_x11->motif_target_lists)	    {	      display_x11->motif_target_lists = g_new (GList *, 1);	      display_x11->motif_n_target_lists = 1;	    }	  else	    {	      display_x11->motif_n_target_lists++;	      display_x11->motif_target_lists = g_realloc (display_x11->motif_target_lists,							   sizeof(GList *) * display_x11->motif_n_target_lists);	    }	  display_x11->motif_target_lists[display_x11->motif_n_target_lists - 1] = sorted;	  sorted = NULL;	  index = display_x11->motif_n_target_lists - 1;	  total_size = sizeof (MotifTargetTableHeader);	  for (i = 0; i < display_x11->motif_n_target_lists ; i++)	    total_size += sizeof(guint16) + sizeof(guint32) * g_list_length (display_x11->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 = display_x11->motif_n_target_lists;	  header->total_size = total_size;	  for (i = 0; i < display_x11->motif_n_target_lists ; i++)	    {	      guint16 n_targets = g_list_length (display_x11->motif_target_lists[i]);	      guint32 *targets = g_new (guint32, n_targets);	      guint32 *p32 = targets;	      	      tmp_list = display_x11->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 (display_x11->xdisplay,			   display_x11->motif_drag_window,			   gdk_x11_get_xatom_by_name_for_display (display, "_MOTIF_DRAG_TARGETS"),			   gdk_x11_get_xatom_by_name_for_display (display, "_MOTIF_DRAG_TARGETS"),			   8, PropModeReplace,			   data, total_size);	}      gdk_x11_display_ungrab (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){  GdkDragContextPrivateX11 *private = PRIVATE_DATA (context);  MotifDragInitiatorInfo info;  gint i;  GdkDisplay *display = GDK_DRAWABLE_DISPLAY (context->source_window);    info.byte_order = local_byte_order;  info.protocol_version = 0;    info.targets_index = motif_add_to_target_table (display, context->targets);  for (i=0; ; i++)    {      gchar buf[20];      g_snprintf(buf, 20, "_GDK_SELECTION_%d", i);            private->motif_selection = gdk_x11_get_xatom_by_name_for_display (display, buf);      if (!XGetSelectionOwner (GDK_DISPLAY_XDISPLAY (display), private->motif_selection))	break;    }  info.selection_atom = private->motif_selection;  XChangeProperty (GDK_DRAWABLE_XDISPLAY (context->source_window),		   GDK_DRAWABLE_XID (context->source_window),		   private->motif_selection,		   gdk_x11_get_xatom_by_name_for_display (display, "_MOTIF_DRAG_INITIATOR_INFO"),		   8, PropModeReplace,		   (guchar *)&info, sizeof (info));  private->motif_targets_set = 1;}static guint32motif_check_dest (GdkDisplay *display,		  Window      win){  gboolean retval = FALSE;  guchar *data;  MotifDragReceiverInfo *info;  Atom type = None;  int format;  unsigned long nitems, after;  Atom motif_drag_receiver_info_atom = gdk_x11_get_xatom_by_name_for_display (display, "_MOTIF_DRAG_RECEIVER_INFO");  gdk_error_trap_push ();  XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), win, 		      motif_drag_receiver_info_atom, 		      0, (sizeof(*info)+3)/4, False, AnyPropertyType,		      &type, &format, &nitems, &after, 		      &data);  if (gdk_error_trap_pop() == 0)    {      if (type != None)	{	  info = (MotifDragReceiverInfo *)data;	  	  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 : None;}static voidmotif_send_enter (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) = 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_DRAWABLE_XID (context->source_window);  if (!private->motif_targets_set)    motif_set_targets (context);  MOTIF_XCLIENT_LONG (&xev, 3) = private->motif_selection;  MOTIF_XCLIENT_LONG (&xev, 4) = 0;  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)));}static voidmotif_send_leave (GdkDragContext  *context,		  guint32          time){  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) = 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) = 0;  MOTIF_XCLIENT_LONG (&xev, 3) = 0;  MOTIF_XCLIENT_LONG (&xev, 4) = 0;  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)));}static gbooleanmotif_send_motion (GdkDragContext  *context,		    gint            x_root, 		    gint            y_root,		    GdkDragAction   action,		    guint32         time){  GdkDragContextPrivateX11 *private = PRIVATE_DATA (context);  GdkDisplay *display = GDK_DRAWABLE_DISPLAY (context->source_window);  gboolean retval;  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, 1) = local_byte_order;  MOTIF_XCLIENT_SHORT (&xev, 1) = motif_dnd_get_flags (context);  MOTIF_XCLIENT_LONG (&xev, 1) = time;  MOTIF_XCLIENT_LONG (&xev, 3) = 0;  MOTIF_XCLIENT_LONG (&xev, 4) = 0;  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 (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)));

⌨️ 快捷键说明

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