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

📄 gtksignal.c

📁 gtk是linux一款强大的夸平台的图形化开发工具
💻 C
📖 第 1 页 / 共 4 页
字号:
/* GTK - The GIMP Toolkit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//* * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS * file for a list of people on the GTK+ Team.  See the ChangeLog * files for a list of changes.  These files are distributed with * GTK+ at ftp://ftp.gtk.org/pub/gtk/.  */#include <stdarg.h>#include <string.h>#include <stdio.h>#include "gtksignal.h"#include "gtkargcollector.c"#define	SIGNAL_BLOCK_SIZE		(100)#define	HANDLER_BLOCK_SIZE		(200)#define	EMISSION_BLOCK_SIZE		(100)#define	DISCONNECT_INFO_BLOCK_SIZE	(64)#define MAX_SIGNAL_PARAMS		(31)enum{  EMISSION_CONTINUE,  EMISSION_RESTART,  EMISSION_DONE};#define GTK_RUN_TYPE(x)	 ((x) & GTK_RUN_BOTH)typedef struct _GtkSignal		GtkSignal;typedef struct _GtkSignalHash		GtkSignalHash;typedef struct _GtkHandler		GtkHandler;typedef struct _GtkEmission		GtkEmission;typedef struct _GtkEmissionHookData	GtkEmissionHookData;typedef struct _GtkDisconnectInfo	GtkDisconnectInfo;typedef void (*GtkSignalMarshaller0) (GtkObject *object,				      gpointer	 data);struct _GtkSignal{  guint		      signal_id;  GtkType	      object_type;  gchar		     *name;  guint		      function_offset;  GtkSignalMarshaller marshaller;  GtkType	      return_val;  guint		      signal_flags : 16;  guint		      nparams : 16;  GtkType	     *params;  GHookList	     *hook_list;};struct _GtkSignalHash{  GtkType object_type;  GQuark  quark;  guint	  signal_id;};struct _GtkHandler{  guint		   id;  GtkHandler	  *next;  GtkHandler	  *prev;  guint		   blocked : 20;  guint		   object_signal : 1;  guint		   after : 1;  guint		   no_marshal : 1;  guint16	   ref_count;  guint16	   signal_id;  GtkSignalFunc	   func;  gpointer	   func_data;  GtkSignalDestroy destroy_func;};struct _GtkEmission{  GtkObject   *object;  guint16      signal_id;  guint	       in_hook : 1;  GtkEmission *next;};struct _GtkEmissionHookData{  GtkObject *object;  guint signal_id;  guint n_params;  GtkArg *params;};struct _GtkDisconnectInfo{  GtkObject	*object1;  guint		 disconnect_handler1;  guint		 signal_handler;  GtkObject	*object2;  guint		 disconnect_handler2;};static guint	    gtk_signal_hash	       (gconstpointer h);static gint	    gtk_signal_compare	       (gconstpointer h1,						gconstpointer h2);static GtkHandler*  gtk_signal_handler_new     (void);static void	    gtk_signal_handler_ref     (GtkHandler    *handler);static void	    gtk_signal_handler_unref   (GtkHandler    *handler,						GtkObject     *object);static void	    gtk_signal_handler_insert  (GtkObject     *object,						GtkHandler    *handler);static void	    gtk_signal_real_emit       (GtkObject     *object,						guint	       signal_id,						GtkArg	      *params);static guint	    gtk_signal_connect_by_type (GtkObject     *object,						guint	       signal_id,						GtkSignalFunc  func,						gpointer       func_data,						GtkSignalDestroy destroy_func,						gint	       object_signal,						gint	       after,						gint	       no_marshal);static guint	    gtk_alive_disconnecter     (GtkDisconnectInfo *info);static GtkEmission* gtk_emission_new	       (void);static void	    gtk_emission_add	       (GtkEmission   **emissions,						GtkObject      *object,						guint		signal_type);static void	    gtk_emission_remove	       (GtkEmission   **emissions,						GtkObject      *object,						guint		signal_type);static gint	    gtk_emission_check	       (GtkEmission    *emissions,						GtkObject      *object,						guint		signal_type);static gint	    gtk_handlers_run	       (GtkHandler     *handlers,						GtkSignal      *signal,						GtkObject      *object,						GtkArg         *params,						gint		after);static gboolean gtk_emission_hook_marshaller   (GHook          *hook,						gpointer        data);static gboolean	gtk_signal_collect_params      (GtkArg	       *params,						guint		nparams,						GtkType	       *param_types,						GtkType		return_type,						va_list		var_args);#define LOOKUP_SIGNAL_ID(signal_id)	( \  signal_id > 0 && signal_id < _gtk_private_n_signals ? \    (GtkSignal*) _gtk_private_signals + signal_id : \    (GtkSignal*) 0 \)static GtkSignalMarshal global_marshaller = NULL;static GtkSignalDestroy global_destroy_notify = NULL;static guint	   		 gtk_handler_id = 1;static guint	   		 gtk_handler_quark = 0;static GHashTable  		*gtk_signal_hash_table = NULL;       GtkSignal   		*_gtk_private_signals = NULL;       guint	   		 _gtk_private_n_signals = 0;static GMemChunk   		*gtk_signal_hash_mem_chunk = NULL;static GMemChunk   		*gtk_disconnect_info_mem_chunk = NULL;static GtkHandler  		*gtk_handler_free_list = NULL;static GtkEmission		*gtk_free_emissions = NULL;static GtkEmission *current_emissions = NULL;static GtkEmission *stop_emissions = NULL;static GtkEmission *restart_emissions = NULL;static GtkSignal*gtk_signal_next_and_invalidate (void){  static guint gtk_n_free_signals = 0;  register GtkSignal *signal;  register guint new_signal_id;    /* don't keep *any* GtkSignal pointers across invokation of this function!!!   */    if (gtk_n_free_signals == 0)    {      register guint i;      register guint size;            /* nearest pow       */      size = _gtk_private_n_signals + SIGNAL_BLOCK_SIZE;      size *= sizeof (GtkSignal);      i = 1;      while (i < size)	i <<= 1;      size = i;            _gtk_private_signals = g_realloc (_gtk_private_signals, size);            gtk_n_free_signals = size / sizeof (GtkSignal) - _gtk_private_n_signals;            memset (_gtk_private_signals + _gtk_private_n_signals, 0, gtk_n_free_signals * sizeof (GtkSignal));    }    new_signal_id = _gtk_private_n_signals++;  gtk_n_free_signals--;  g_assert (_gtk_private_n_signals < 65535);    signal = LOOKUP_SIGNAL_ID (new_signal_id);  if (signal)    signal->signal_id = new_signal_id;    return signal;}static inline GtkHandler*gtk_signal_get_handlers (GtkObject *object,			 guint	    signal_id){  GtkHandler *handlers;    handlers = gtk_object_get_data_by_id (object, gtk_handler_quark);    while (handlers)    {      if (handlers->signal_id == signal_id)	return handlers;      handlers = handlers->next;    }    return NULL;}voidgtk_signal_init (void){  if (!gtk_handler_quark)    {      GtkSignal *zero;            zero = gtk_signal_next_and_invalidate ();      g_assert (zero == NULL);            gtk_handler_quark = g_quark_from_static_string ("gtk-signal-handlers");            gtk_signal_hash_mem_chunk =	g_mem_chunk_new ("GtkSignalHash mem chunk",			 sizeof (GtkSignalHash),			 sizeof (GtkSignalHash) * SIGNAL_BLOCK_SIZE,			 G_ALLOC_ONLY);      gtk_disconnect_info_mem_chunk =	g_mem_chunk_new ("GtkDisconnectInfo mem chunk",			 sizeof (GtkDisconnectInfo),			 sizeof (GtkDisconnectInfo) * DISCONNECT_INFO_BLOCK_SIZE,			 G_ALLOC_AND_FREE);      gtk_handler_free_list = NULL;      gtk_free_emissions = NULL;            gtk_signal_hash_table = g_hash_table_new (gtk_signal_hash,						gtk_signal_compare);    }}guintgtk_signal_newv (const gchar	     *r_name,		 GtkSignalRunType     signal_flags,		 GtkType	      object_type,		 guint		      function_offset,		 GtkSignalMarshaller  marshaller,		 GtkType	      return_val,		 guint		      nparams,		 GtkType	     *params){  GtkSignal *signal;  GtkSignalHash *hash;  GQuark quark;  guint i;  gchar *name;    g_return_val_if_fail (r_name != NULL, 0);  g_return_val_if_fail (marshaller != NULL, 0);  g_return_val_if_fail (nparams < MAX_SIGNAL_PARAMS, 0);  if (nparams)    g_return_val_if_fail (params != NULL, 0);    if (!gtk_handler_quark)    gtk_signal_init ();  name = g_strdup (r_name);  g_strdelimit (name, NULL, '_');  quark = gtk_signal_lookup (name, object_type);  if (quark)    {      g_warning ("gtk_signal_newv(): signal \"%s\" already exists in the `%s' class ancestry\n",		 r_name,		 gtk_type_name (object_type));      g_free (name);      return 0;    }    if (return_val != GTK_TYPE_NONE &&      (signal_flags & GTK_RUN_BOTH) == GTK_RUN_FIRST)    {      g_warning ("gtk_signal_newv(): signal \"%s\" - return value `%s' incompatible with GTK_RUN_FIRST",		 name, gtk_type_name (return_val));      g_free (name);      return 0;    }    signal = gtk_signal_next_and_invalidate ();    /* signal->signal_id already set */    signal->object_type = object_type;  signal->name = name;  signal->function_offset = function_offset;  signal->marshaller = marshaller;  signal->return_val = return_val;  signal->signal_flags = signal_flags;  signal->nparams = nparams;  signal->hook_list = NULL;    if (nparams > 0)    {      signal->params = g_new (GtkType, nparams);            for (i = 0; i < nparams; i++)	signal->params[i] = params[i];    }  else    signal->params = NULL;  /* insert "signal_name" into hash table   */  hash = g_chunk_new (GtkSignalHash, gtk_signal_hash_mem_chunk);  hash->object_type = object_type;  hash->quark = g_quark_from_string (signal->name);  hash->signal_id = signal->signal_id;  g_hash_table_insert (gtk_signal_hash_table, hash, GUINT_TO_POINTER (hash->signal_id));  /* insert "signal-name" into hash table   */  g_strdelimit (signal->name, NULL, '-');  quark = g_quark_from_static_string (signal->name);  if (quark != hash->quark)    {      hash = g_chunk_new (GtkSignalHash, gtk_signal_hash_mem_chunk);      hash->object_type = object_type;      hash->quark = quark;      hash->signal_id = signal->signal_id;      g_hash_table_insert (gtk_signal_hash_table, hash, GUINT_TO_POINTER (hash->signal_id));    }    return signal->signal_id;}guintgtk_signal_new (const gchar	    *name,		GtkSignalRunType     signal_flags,		GtkType		     object_type,		guint		     function_offset,		GtkSignalMarshaller  marshaller,		GtkType		     return_val,		guint		     nparams,		...){  GtkType *params;  guint i;  va_list args;  guint signal_id;    g_return_val_if_fail (nparams < MAX_SIGNAL_PARAMS, 0);    if (nparams > 0)    {      params = g_new (GtkType, nparams);            va_start (args, nparams);            for (i = 0; i < nparams; i++)	params[i] = va_arg (args, GtkType);            va_end (args);    }  else    params = NULL;    signal_id = gtk_signal_newv (name,			       signal_flags,			       object_type,			       function_offset,			       marshaller,			       return_val,			       nparams,			       params);    g_free (params);    return signal_id;}guintgtk_signal_lookup (const gchar *name,		   GtkType	object_type){  GtkSignalHash hash;  GtkType lookup_type;  gpointer class = NULL;  g_return_val_if_fail (name != NULL, 0);  g_return_val_if_fail (gtk_type_is_a (object_type, GTK_TYPE_OBJECT), 0);   relookup:  lookup_type = object_type;  hash.quark = g_quark_try_string (name);  if (hash.quark)    {      while (lookup_type)	{	  guint signal_id;	  	  hash.object_type = lookup_type;	  	  signal_id = GPOINTER_TO_UINT (g_hash_table_lookup (gtk_signal_hash_table, &hash));	  if (signal_id)	    return signal_id;	  	  lookup_type = gtk_type_parent (lookup_type);	}    }  if (!class)    {      class = gtk_type_class (object_type);      goto relookup;    }  return 0;}GtkSignalQuery*gtk_signal_query (guint signal_id){  GtkSignalQuery *query;  GtkSignal *signal;    g_return_val_if_fail (signal_id >= 1, NULL);    signal = LOOKUP_SIGNAL_ID (signal_id);  if (signal)    {      query = g_new (GtkSignalQuery, 1);            query->object_type = signal->object_type;      query->signal_id = signal_id;      query->signal_name = signal->name;      query->is_user_signal = signal->function_offset == 0;      query->signal_flags = signal->signal_flags;      query->return_val = signal->return_val;      query->nparams = signal->nparams;      query->params = signal->params;    }  else    query = NULL;    return query;}gchar*gtk_signal_name (guint signal_id){  GtkSignal *signal;    g_return_val_if_fail (signal_id >= 1, NULL);    signal = LOOKUP_SIGNAL_ID (signal_id);  if (signal)    return signal->name;    return NULL;

⌨️ 快捷键说明

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