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

📄 gtkbindings.c

📁 gtk是linux一款强大的夸平台的图形化开发工具
💻 C
📖 第 1 页 / 共 3 页
字号:
/* GTK - The GIMP Toolkit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * GtkBindingSet: Keybinding manager for GtkObjects. * Copyright (C) 1998 Tim Janik * * 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 <ctype.h>#include <string.h>#include <stdarg.h>#include "gtkbindings.h"#include "gtksignal.h"#include "gtkwidget.h"#include "gtkrc.h"/* --- defines --- */#define	BINDING_MOD_MASK()	(gtk_accelerator_get_default_mod_mask () | GDK_RELEASE_MASK)/* --- variables --- */static GHashTable	*binding_entry_hash_table = NULL;static GSList		*binding_set_list = NULL;static const gchar	*key_class_binding_set = "gtk-class-binding-set";static GQuark		 key_id_class_binding_set = 0;/* --- functions --- */static GtkBindingSignal*binding_signal_new (const gchar *signal_name,		    guint	 n_args){  GtkBindingSignal *signal;    signal = g_new (GtkBindingSignal, 1);  signal->next = NULL;  signal->signal_name = g_strdup (signal_name);  signal->n_args = n_args;  signal->args = g_new0 (GtkBindingArg, n_args);    return signal;}static voidbinding_signal_free (GtkBindingSignal *sig){  guint i;    for (i = 0; i < sig->n_args; i++)    {      if (GTK_FUNDAMENTAL_TYPE (sig->args[i].arg_type) == GTK_TYPE_STRING)	g_free (sig->args[i].d.string_data);    }  g_free (sig->args);  g_free (sig->signal_name);  g_free (sig);}static guintbinding_entry_hash (gconstpointer  key){  register const GtkBindingEntry *e = key;  register guint h;  h = e->keyval;  h ^= e->modifiers;  return h;}static gintbinding_entries_compare (gconstpointer  a,			 gconstpointer  b){  register const GtkBindingEntry *ea = a;  register const GtkBindingEntry *eb = b;  return (ea->keyval == eb->keyval && ea->modifiers == eb->modifiers);}static GtkBindingEntry*binding_entry_new (GtkBindingSet *binding_set,		   guint          keyval,		   guint          modifiers){  GtkBindingEntry *entry;    if (!binding_entry_hash_table)    binding_entry_hash_table = g_hash_table_new (binding_entry_hash, binding_entries_compare);  entry = g_new (GtkBindingEntry, 1);  entry->keyval = keyval;  entry->modifiers = modifiers;  entry->binding_set = binding_set,  entry->destroyed = FALSE;  entry->in_emission = FALSE;  entry->signals = NULL;  entry->set_next = binding_set->entries;  binding_set->entries = entry;  entry->hash_next = g_hash_table_lookup (binding_entry_hash_table, entry);  g_hash_table_freeze (binding_entry_hash_table);  if (entry->hash_next)    g_hash_table_remove (binding_entry_hash_table, entry->hash_next);  g_hash_table_insert (binding_entry_hash_table, entry, entry);  g_hash_table_thaw (binding_entry_hash_table);    return entry;}static voidbinding_entry_free (GtkBindingEntry *entry){  GtkBindingSignal *sig;  g_assert (entry->set_next == NULL &&	    entry->hash_next == NULL &&	    entry->in_emission == FALSE &&	    entry->destroyed == TRUE);  entry->destroyed = FALSE;    sig = entry->signals;  while (sig)    {      GtkBindingSignal *prev;            prev = sig;      sig = prev->next;      binding_signal_free (prev);    }  g_free (entry);}static voidbinding_entry_destroy (GtkBindingEntry *entry){  GtkBindingEntry *o_entry;  register GtkBindingEntry *tmp;  GtkBindingEntry *begin;  register GtkBindingEntry *last;  /* unlink from binding set   */  last = NULL;  tmp = entry->binding_set->entries;  while (tmp)    {      if (tmp == entry)	{	  if (last)	    last->set_next = entry->set_next;	  else	    entry->binding_set->entries = entry->set_next;	  break;	}      last = tmp;      tmp = last->set_next;    }  entry->set_next = NULL;    o_entry = g_hash_table_lookup (binding_entry_hash_table, entry);  begin = o_entry;  last = NULL;  tmp = begin;  while (tmp)    {      if (tmp == entry)	{	  if (last)	    last->hash_next = entry->hash_next;	  else	    begin = entry->hash_next;	  break;	}      last = tmp;      tmp = last->hash_next;    }  entry->hash_next = NULL;    if (!begin)    g_hash_table_remove (binding_entry_hash_table, entry);  else if (begin != o_entry)    {      g_hash_table_freeze (binding_entry_hash_table);      g_hash_table_remove (binding_entry_hash_table, entry);      g_hash_table_insert (binding_entry_hash_table, begin, begin);      g_hash_table_thaw (binding_entry_hash_table);    }  entry->destroyed = TRUE;  if (!entry->in_emission)    binding_entry_free (entry);}static GtkBindingEntry*binding_ht_lookup_list (guint keyval,			guint modifiers){  GtkBindingEntry lookup_entry = { 0 };    if (!binding_entry_hash_table)    return NULL;    lookup_entry.keyval = keyval;  lookup_entry.modifiers = modifiers;    return g_hash_table_lookup (binding_entry_hash_table, &lookup_entry);}static GtkBindingEntry*binding_ht_lookup_entry (GtkBindingSet *set,			 guint		keyval,			 guint		modifiers){  GtkBindingEntry lookup_entry = { 0 };  GtkBindingEntry *entry;    if (!binding_entry_hash_table)    return NULL;    lookup_entry.keyval = keyval;  lookup_entry.modifiers = modifiers;    entry = g_hash_table_lookup (binding_entry_hash_table, &lookup_entry);  for (; entry; entry = entry->hash_next)    if (entry->binding_set == set)      return entry;  return NULL;}static gbooleanbinding_compose_params (GtkBindingArg	*args,			GtkSignalQuery	*query,			GtkArg		**params_p){  GtkArg *params;  const GtkType *types;  guint i;  gboolean valid;    params = g_new0 (GtkArg, query->nparams);  *params_p = params;    types = query->params;  valid = TRUE;  for (i = 0; i < query->nparams && valid; i++)    {      GtkType param_ftype;      params->type = *types;      params->name = NULL;      param_ftype = GTK_FUNDAMENTAL_TYPE (params->type);      switch (GTK_FUNDAMENTAL_TYPE (args->arg_type))	{	case  GTK_TYPE_DOUBLE:	  if (param_ftype == GTK_TYPE_FLOAT)	    GTK_VALUE_FLOAT (*params) = args->d.double_data;	  else if (param_ftype == GTK_TYPE_DOUBLE)	    GTK_VALUE_DOUBLE (*params) = args->d.double_data;	  else	    valid = FALSE;	  break;	case  GTK_TYPE_LONG:	  if (param_ftype == GTK_TYPE_BOOL &&	      (args->d.long_data == 0 ||	       args->d.long_data == 1))	    GTK_VALUE_BOOL (*params) = args->d.long_data;	  else if (param_ftype == GTK_TYPE_INT ||		   param_ftype == GTK_TYPE_ENUM)	    GTK_VALUE_INT (*params) = args->d.long_data;	  else if ((param_ftype == GTK_TYPE_UINT ||		    param_ftype == GTK_TYPE_FLAGS) &&		   args->d.long_data >= 0)	    GTK_VALUE_UINT (*params) = args->d.long_data;	  else if (param_ftype == GTK_TYPE_LONG)	    GTK_VALUE_LONG (*params) = args->d.long_data;	  else if (param_ftype == GTK_TYPE_ULONG &&		   args->d.long_data >= 0)	    GTK_VALUE_ULONG (*params) = args->d.long_data;	  else if (param_ftype == GTK_TYPE_FLOAT)	    GTK_VALUE_FLOAT (*params) = args->d.long_data;	  else if (param_ftype == GTK_TYPE_DOUBLE)	    GTK_VALUE_DOUBLE (*params) = args->d.long_data;	  else	    valid = FALSE;	  break;	case  GTK_TYPE_STRING:	  if (args->arg_type == GTK_TYPE_STRING &&	      param_ftype == GTK_TYPE_STRING)	    GTK_VALUE_STRING (*params) = args->d.string_data;	  else if (args->arg_type == GTK_TYPE_IDENTIFIER &&		   (param_ftype == GTK_TYPE_ENUM ||		    param_ftype == GTK_TYPE_FLAGS))	    {	      GtkEnumValue *value;	      value = gtk_type_enum_find_value (params->type, args->d.string_data);	      if (value)		GTK_VALUE_ENUM (*params) = value->value;	      else		valid = FALSE;	    }	  else	    valid = FALSE;	  break;	default:	  valid = FALSE;	  break;	}      types++;      params++;      args++;    }    if (!valid)    {      g_free (*params_p);      *params_p = NULL;    }    return valid;}static voidgtk_binding_entry_activate (GtkBindingEntry	*entry,			    GtkObject	*object){  GtkBindingSignal *sig;  gboolean old_emission;    old_emission = entry->in_emission;  entry->in_emission = TRUE;    gtk_object_ref (object);    for (sig = entry->signals; sig; sig = sig->next)    {      GtkSignalQuery *query;      guint signal_id;      GtkArg *params = NULL;      gchar *accelerator = NULL;            signal_id = gtk_signal_lookup (sig->signal_name, GTK_OBJECT_TYPE (object));      if (!signal_id)	{	  accelerator = gtk_accelerator_name (entry->keyval, entry->modifiers);	  g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": "		     "could not find signal \"%s\" in the `%s' class ancestry",		     entry->binding_set->set_name,		     accelerator,		     sig->signal_name,		     gtk_type_name (GTK_OBJECT_TYPE (object)));	  g_free (accelerator);	  continue;	}            query = gtk_signal_query (signal_id);      if (query->nparams != sig->n_args ||	  query->return_val != GTK_TYPE_NONE ||	  !binding_compose_params (sig->args, query, &params))	{	  accelerator = gtk_accelerator_name (entry->keyval, entry->modifiers);	  g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": "		     "signature mismatch for signal \"%s\" in the `%s' class ancestry",		     entry->binding_set->set_name,		     accelerator,		     sig->signal_name,		     gtk_type_name (GTK_OBJECT_TYPE (object)));	}      else if (!(query->signal_flags & GTK_RUN_ACTION))	{	  accelerator = gtk_accelerator_name (entry->keyval, entry->modifiers);	  g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": "		     "signal \"%s\" in the `%s' class ancestry cannot be used for action emissions",		     entry->binding_set->set_name,		     accelerator,		     sig->signal_name,		     gtk_type_name (GTK_OBJECT_TYPE (object)));	}      g_free (accelerator);      g_free (query);      if (accelerator)	continue;      gtk_signal_emitv (object, signal_id, params);      g_free (params);            if (GTK_OBJECT_DESTROYED (object) || entry->destroyed)	break;    }    gtk_object_unref (object);  entry->in_emission = old_emission;  if (entry->destroyed && !entry->in_emission)    binding_entry_free (entry);}GtkBindingSet*gtk_binding_set_new (const gchar    *set_name){  GtkBindingSet *binding_set;    g_return_val_if_fail (set_name != NULL, NULL);    binding_set = g_new (GtkBindingSet, 1);  binding_set->set_name = g_strdup (set_name);  binding_set->widget_path_pspecs = NULL;  binding_set->widget_class_pspecs = NULL;  binding_set->class_branch_pspecs = NULL;  binding_set->entries = NULL;  binding_set->current = NULL;    binding_set_list = g_slist_prepend (binding_set_list, binding_set);    return binding_set;}GtkBindingSet*gtk_binding_set_by_class (gpointer object_class){  GtkObjectClass *class = object_class;  GtkBindingSet* binding_set;  g_return_val_if_fail (GTK_IS_OBJECT_CLASS (class), NULL);  if (!key_id_class_binding_set)    key_id_class_binding_set = g_quark_from_static_string (key_class_binding_set);  binding_set = g_dataset_id_get_data (class, key_id_class_binding_set);  if (binding_set)    return binding_set;  binding_set = gtk_binding_set_new (gtk_type_name (class->type));  gtk_binding_set_add_path (binding_set,			    GTK_PATH_CLASS,			    gtk_type_name (class->type),			    GTK_PATH_PRIO_GTK);  g_dataset_id_set_data (class, key_id_class_binding_set, binding_set);  return binding_set;}GtkBindingSet*gtk_binding_set_find (const gchar    *set_name){  GSList *slist;    g_return_val_if_fail (set_name != NULL, NULL);    for (slist = binding_set_list; slist; slist = slist->next)    {      GtkBindingSet *binding_set;            binding_set = slist->data;      if (g_str_equal (binding_set->set_name, (gpointer) set_name))	return binding_set;    }  return NULL;

⌨️ 快捷键说明

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