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

📄 gtkselection.c

📁 gtk是linux一款强大的夸平台的图形化开发工具
💻 C
📖 第 1 页 / 共 3 页
字号:
		info->conversions[i].offset;	      buffer = info->conversions[i].data.data + 		info->conversions[i].offset;	      	      if (num_bytes > GTK_SELECTION_MAX_SIZE)		{		  num_bytes = GTK_SELECTION_MAX_SIZE;		  info->conversions[i].offset += GTK_SELECTION_MAX_SIZE;		}	      else		info->conversions[i].offset = -2;	    }#ifdef DEBUG_SELECTION	  g_message ("INCR: put %d bytes (offset = %d) into window 0x%lx , property %ld",		     num_bytes, info->conversions[i].offset, 		     GDK_WINDOW_XWINDOW(info->requestor), event->atom);#endif	  gdk_property_change (info->requestor, event->atom,			       info->conversions[i].data.type,			       info->conversions[i].data.format,			       GDK_PROP_MODE_REPLACE,			       buffer, 			       (num_bytes + info->conversions[i].data.format/8 - 1) / 			       (info->conversions[i].data.format/8));	  	  if (info->conversions[i].offset == -2)	    {	      g_free (info->conversions[i].data.data);	      info->conversions[i].data.data = NULL;	    }	  	  if (num_bytes == 0)	    {	      info->num_incrs--;	      info->conversions[i].offset = -1;	    }	}      break;    }    /* Check if we're finished with all the targets */    if (info->num_incrs == 0)    {      current_incrs = g_list_remove_link (current_incrs, tmp_list);      g_list_free (tmp_list);      /* Let the timeout free it */    }    return TRUE;}/************************************************************* * gtk_selection_incr_timeout: *     Timeout callback for the sending portion of the INCR *     protocol *   arguments: *     info:	Information about this incr *   results: *************************************************************/static gintgtk_selection_incr_timeout (GtkIncrInfo *info){  GList *tmp_list;  gboolean retval;  GDK_THREADS_ENTER ();    /* Determine if retrieval has finished by checking if it still in     list of pending retrievals */    tmp_list = current_incrs;  while (tmp_list)    {      if (info == (GtkIncrInfo *)tmp_list->data)	break;      tmp_list = tmp_list->next;    }    /* If retrieval is finished */  if (!tmp_list || info->idle_time >= 5)    {      if (tmp_list && info->idle_time >= 5)	{	  current_incrs = g_list_remove_link (current_incrs, tmp_list);	  g_list_free (tmp_list);	}            g_free (info->conversions);      /* FIXME: we should check if requestor window is still in use,	 and if not, remove it? */            g_free (info);            retval =  FALSE;		/* remove timeout */    }  else    {      info->idle_time++;            retval = TRUE;		/* timeout will happen again */    }    GDK_THREADS_LEAVE ();  return retval;}/************************************************************* * gtk_selection_notify: *     Handler for "selection_notify_event" signals on windows *     where a retrieval is currently in process. The selection *     owner has responded to our conversion request. *   arguments: *     widget:		Widget getting signal *     event:		Selection event structure *     info:		Information about this retrieval *   results: *     was event handled? *************************************************************/gintgtk_selection_notify (GtkWidget	       *widget,		      GdkEventSelection *event){  GList *tmp_list;  GtkRetrievalInfo *info = NULL;  guchar  *buffer = NULL;  gint length;  GdkAtom type;  gint	  format;  #ifdef DEBUG_SELECTION  g_message ("Initial receipt of selection %ld, target %ld (property = %ld)",	     event->selection, event->target, event->property);#endif    tmp_list = current_retrievals;  while (tmp_list)    {      info = (GtkRetrievalInfo *)tmp_list->data;      if (info->widget == widget && info->selection == event->selection)	break;      tmp_list = tmp_list->next;    }    if (!tmp_list)		/* no retrieval in progress */    return FALSE;  if (event->property != GDK_NONE)    length = gdk_selection_property_get (widget->window, &buffer, 					 &type, &format);  if (event->property == GDK_NONE || buffer == NULL)    {      current_retrievals = g_list_remove_link (current_retrievals, tmp_list);      g_list_free (tmp_list);      /* structure will be freed in timeout */      gtk_selection_retrieval_report (info,				      GDK_NONE, 0, NULL, -1, event->time);            return TRUE;    }    if (type == gtk_selection_atoms[INCR])    {      /* The remainder of the selection will come through PropertyNotify	 events */      info->notify_time = event->time;      info->idle_time = 0;      info->offset = 0;		/* Mark as OK to proceed */      gdk_window_set_events (widget->window,			     gdk_window_get_events (widget->window)			     | GDK_PROPERTY_CHANGE_MASK);    }  else    {      /* We don't delete the info structure - that will happen in timeout */      current_retrievals = g_list_remove_link (current_retrievals, tmp_list);      g_list_free (tmp_list);            info->offset = length;      gtk_selection_retrieval_report (info,				      type, format, 				      buffer, length, event->time);    }    gdk_property_delete (widget->window, event->property);    g_free (buffer);    return TRUE;}/************************************************************* * gtk_selection_property_notify: *     Handler for "property_notify_event" signals on windows *     where a retrieval is currently in process. The selection *     owner has added more data. *   arguments: *     widget:		Widget getting signal *     event:		Property event structure *     info:		Information about this retrieval *   results: *     was event handled? *************************************************************/gintgtk_selection_property_notify (GtkWidget	*widget,			       GdkEventProperty *event){  GList *tmp_list;  GtkRetrievalInfo *info = NULL;  guchar *new_buffer;  int length;  GdkAtom type;  gint	  format;    g_return_val_if_fail (widget != NULL, FALSE);  g_return_val_if_fail (event != NULL, FALSE);  if ((event->state != GDK_PROPERTY_NEW_VALUE) ||  /* property was deleted */      (event->atom != gdk_selection_property)) /* not the right property */    return FALSE;  #ifdef DEBUG_SELECTION  g_message ("PropertyNewValue, property %ld",	     event->atom);#endif    tmp_list = current_retrievals;  while (tmp_list)    {      info = (GtkRetrievalInfo *)tmp_list->data;      if (info->widget == widget)	break;      tmp_list = tmp_list->next;    }    if (!tmp_list)		/* No retrieval in progress */    return FALSE;    if (info->offset < 0)		/* We haven't got the SelectionNotify				   for this retrieval yet */    return FALSE;    info->idle_time = 0;    length = gdk_selection_property_get (widget->window, &new_buffer, 				       &type, &format);  gdk_property_delete (widget->window, event->atom);    /* We could do a lot better efficiency-wise by paying attention to     what length was sent in the initial INCR transaction, instead of     doing memory allocation at every step. But its only guaranteed to     be a _lower bound_ (pretty useless!) */    if (length == 0 || type == GDK_NONE)		/* final zero length portion */    {      /* Info structure will be freed in timeout */      current_retrievals = g_list_remove_link (current_retrievals, tmp_list);      g_list_free (tmp_list);      gtk_selection_retrieval_report (info,				      type, format, 				      (type == GDK_NONE) ?  NULL : info->buffer,				      (type == GDK_NONE) ?  -1 : info->offset,				      info->notify_time);    }  else				/* append on newly arrived data */    {      if (!info->buffer)	{#ifdef DEBUG_SELECTION	  g_message ("Start - Adding %d bytes at offset 0",		     length);#endif	  info->buffer = new_buffer;	  info->offset = length;	}      else	{	  #ifdef DEBUG_SELECTION	  g_message ("Appending %d bytes at offset %d",		     length,info->offset);#endif	  /* We copy length+1 bytes to preserve guaranteed null termination */	  info->buffer = g_realloc (info->buffer, info->offset+length+1);	  memcpy (info->buffer + info->offset, new_buffer, length+1);	  info->offset += length;	  g_free (new_buffer);	}    }    return TRUE;}/************************************************************* * gtk_selection_retrieval_timeout: *     Timeout callback while receiving a selection. *   arguments: *     info:	Information about this retrieval *   results: *************************************************************/static gintgtk_selection_retrieval_timeout (GtkRetrievalInfo *info){  GList *tmp_list;  gboolean retval;  GDK_THREADS_ENTER ();    /* Determine if retrieval has finished by checking if it still in     list of pending retrievals */    tmp_list = current_retrievals;  while (tmp_list)    {      if (info == (GtkRetrievalInfo *)tmp_list->data)	break;      tmp_list = tmp_list->next;    }    /* If retrieval is finished */  if (!tmp_list || info->idle_time >= 5)    {      if (tmp_list && info->idle_time >= 5)	{	  current_retrievals = g_list_remove_link (current_retrievals, tmp_list);	  g_list_free (tmp_list);	  gtk_selection_retrieval_report (info, GDK_NONE, 0, NULL, -1, GDK_CURRENT_TIME);	}            g_free (info->buffer);      g_free (info);            retval =  FALSE;		/* remove timeout */    }  else    {      info->idle_time++;            retval =  TRUE;		/* timeout will happen again */    }  GDK_THREADS_LEAVE ();  return retval;}/************************************************************* * gtk_selection_retrieval_report: *     Emits a "selection_received" signal. *   arguments: *     info:	  information about the retrieval that completed *     buffer:	  buffer containing data (NULL => errror) *     time:      timestamp for data in buffer *   results: *************************************************************/static voidgtk_selection_retrieval_report (GtkRetrievalInfo *info,				GdkAtom type, gint format, 				guchar *buffer, gint length,				guint32 time){  GtkSelectionData data;    data.selection = info->selection;  data.target = info->target;  data.type = type;  data.format = format;    data.length = length;  data.data = buffer;    gtk_signal_emit_by_name (GTK_OBJECT(info->widget),			   "selection_received", 			   &data, time);}/************************************************************* * gtk_selection_invoke_handler: *     Finds and invokes handler for specified *     widget/selection/target combination, calls  *     gtk_selection_default_handler if none exists. * *   arguments: *     widget:	    selection owner *     data:	    selection data [INOUT] *     time:        time from requeset *      *   results: *     Number of bytes written to buffer, -1 if error *************************************************************/static voidgtk_selection_invoke_handler (GtkWidget	       *widget,			      GtkSelectionData *data,			      guint             time){  GtkTargetList *target_list;  guint info;    g_return_if_fail (widget != NULL);  target_list = gtk_selection_target_list_get (widget, data->selection);  if (target_list &&       gtk_target_list_find (target_list, data->target, &info))    {      gtk_signal_emit_by_name (GTK_OBJECT (widget), 			       "selection_get",			       data,			       info, time);    }  else    gtk_selection_default_handler (widget, data);}/************************************************************* * gtk_selection_default_handler: *     Handles some default targets that exist for any widget *     If it can't fit results into buffer, returns -1. This *     won't happen in any conceivable case, since it would *     require 1000 selection targets! * *   arguments: *     widget:	    selection owner *     data:	    selection data [INOUT] * *************************************************************/static voidgtk_selection_default_handler (GtkWidget	*widget,			       GtkSelectionData *data){  if (data->target == gtk_selection_atoms[TIMESTAMP])    {      /* Time which was used to obtain selection */      GList *tmp_list;      GtkSelectionInfo *selection_info;            tmp_list = current_selections;      while (tmp_list)	{	  selection_info = (GtkSelectionInfo *)tmp_list->data;	  if ((selection_info->widget == widget) &&	      (selection_info->selection == data->selection))	    {	      gtk_selection_data_set (data,				      GDK_SELECTION_TYPE_INTEGER,				      sizeof (guint32)*8,				      (guchar *)&selection_info->time,				      sizeof (guint32));	      return;	    }	  	  tmp_list = tmp_list->next;	}            data->length = -1;    }  else if (data->target == gtk_selection_atoms[TARGETS])    {      /* List of all targets supported for this widget/selection pair */      GdkAtom *p;      guint count;      GList *tmp_list;      GtkTargetList *target_list;      GtkTargetPair *pair;            target_list = gtk_selection_target_list_get (widget,						   data->selection);      count = g_list_length (target_list->list) + 3;            data->type = GDK_SELECTION_TYPE_ATOM;      data->format = 8*sizeof (GdkAtom);      data->length = count * sizeof (GdkAtom);            p = g_new (GdkAtom, count);      data->data = (guchar *)p;            *p++ = gtk_selection_atoms[TIMESTAMP];      *p++ = gtk_selection_atoms[TARGETS];      *p++ = gtk_selection_atoms[MULTIPLE];            tmp_list = target_list->list;      while (tmp_list)	{	  pair = (GtkTargetPair *)tmp_list->data;	  *p++ = pair->target;	  	  tmp_list = tmp_list->next;	}    }  else    {      data->length = -1;    }}GtkSelectioData*gtk_selection_data_copy (GtkSelectionData *data){  GtkSelectionData *new_data;    g_return_val_if_fail (data != NULL, NULL);    new_data = g_new (GtkSelectionData, 1);  *new_data = *data;    return new_data;}voidgtk_selection_data_free (GtkSelectionData *data){  g_return_if_fail (data != NULL);    g_free (data);}

⌨️ 快捷键说明

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