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

📄 gtkaccelgroup.c

📁 gtk是linux一款强大的夸平台的图形化开发工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/* GTK - The GIMP Toolkit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * GtkAccelGroup: Accelerator 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 "gtkaccelgroup.h"#include "gdk/gdkkeysyms.h"#include "gtksignal.h"#include "gtkwidget.h"/* --- signals --- */typedef void (*GtkSignalAddAccelerator)	   (GtkObject	    *object,					    guint	     accel_signal_id,					    GtkAccelGroup   *accel_group,					    guint	     accel_key,					    GdkModifierType  accel_mods,					    GtkAccelFlags    accel_flags,					    gpointer	     func_data);typedef void (*GtkSignalRemoveAccelerator) (GtkObject	    *object,					    GtkAccelGroup   *accel_group,					    guint	     accel_key,					    GdkModifierType  accel_mods,					    gpointer	     func_data);/* --- variables --- */static GtkAccelGroup	*default_accel_group = NULL;static guint		 default_accel_mod_mask = (GDK_SHIFT_MASK |						   GDK_CONTROL_MASK |						   GDK_MOD1_MASK);static const gchar	*accel_groups_key = "gtk-accel-groups";static guint		 accel_groups_key_id = 0;static const gchar	*accel_entries_key = "gtk-accel-entries";static guint		 accel_entries_key_id = 0;static GHashTable	*accel_entry_hash_table = NULL;static GMemChunk	*accel_tables_mem_chunk = NULL;static GMemChunk	*accel_entries_mem_chunk = NULL;/* --- functions --- */static gintgtk_accel_entries_equal (gconstpointer a,			 gconstpointer b){  const GtkAccelEntry *e1;  const GtkAccelEntry *e2;    e1 = a;  e2 = b;    return ((e1->accel_group == e2->accel_group) &&	  (e1->accelerator_key == e2->accelerator_key) &&	  (e1->accelerator_mods == e2->accelerator_mods));}static guintgtk_accel_entries_hash (gconstpointer a){  const GtkAccelEntry *e;  guint h;    e = a;    h = (gulong) e->accel_group;  h ^= e->accelerator_key << 16;  h ^= e->accelerator_key >> 16;  h ^= e->accelerator_mods;    return h;}GtkAccelGroup*gtk_accel_group_new (void){  GtkAccelGroup *accel_group;    if (!accel_groups_key_id)    {      accel_groups_key_id = g_quark_from_static_string (accel_groups_key);      accel_entries_key_id = g_quark_from_static_string (accel_entries_key);            accel_entry_hash_table = g_hash_table_new (gtk_accel_entries_hash,						 gtk_accel_entries_equal);            accel_tables_mem_chunk = g_mem_chunk_create (GtkAccelGroup, 8, G_ALLOC_AND_FREE);      accel_entries_mem_chunk = g_mem_chunk_create (GtkAccelEntry, 64, G_ALLOC_AND_FREE);    }    accel_group = g_chunk_new (GtkAccelGroup, accel_tables_mem_chunk);    accel_group->ref_count = 1;  accel_group->lock_count = 0;  accel_group->modifier_mask = gtk_accelerator_get_default_mod_mask ();  accel_group->attach_objects = NULL;    return accel_group;}GtkAccelGroup*gtk_accel_group_get_default (void){  if (!default_accel_group)    default_accel_group = gtk_accel_group_new ();    return default_accel_group;}GtkAccelGroup*gtk_accel_group_ref (GtkAccelGroup	*accel_group){  g_return_val_if_fail (accel_group != NULL, NULL);    accel_group->ref_count += 1;    return accel_group;}voidgtk_accel_group_unref (GtkAccelGroup  *accel_group){  g_return_if_fail (accel_group != NULL);  g_return_if_fail (accel_group->ref_count > 0);    accel_group->ref_count -= 1;  if (accel_group->ref_count == 0)    {      g_return_if_fail (accel_group != default_accel_group);      g_return_if_fail (accel_group->attach_objects == NULL);            g_chunk_free (accel_group, accel_tables_mem_chunk);    }}static voidgtk_accel_group_object_destroy (GtkObject *object){  GSList *free_list, *slist;    free_list = gtk_object_get_data_by_id (object, accel_groups_key_id);  gtk_object_set_data_by_id (object, accel_groups_key_id, NULL);    for (slist = free_list; slist; slist = slist->next)    {      GtkAccelGroup *accel_group;            accel_group = slist->data;      accel_group->attach_objects = g_slist_remove (accel_group->attach_objects, object);      gtk_accel_group_unref (accel_group);    }  g_slist_free (free_list);}voidgtk_accel_group_attach (GtkAccelGroup	*accel_group,			GtkObject	*object){  GSList *slist;    g_return_if_fail (accel_group != NULL);  g_return_if_fail (object != NULL);  g_return_if_fail (GTK_IS_OBJECT (object));  g_return_if_fail (g_slist_find (accel_group->attach_objects, object) == NULL);    accel_group->attach_objects = g_slist_prepend (accel_group->attach_objects, object);  gtk_accel_group_ref (accel_group);  slist = gtk_object_get_data_by_id (object, accel_groups_key_id);  if (!slist)    gtk_signal_connect (object,			"destroy",			GTK_SIGNAL_FUNC (gtk_accel_group_object_destroy),			NULL);  slist = g_slist_prepend (slist, accel_group);  gtk_object_set_data_by_id (object, accel_groups_key_id, slist);}voidgtk_accel_group_detach (GtkAccelGroup	*accel_group,		        GtkObject	*object){  GSList *slist;    g_return_if_fail (accel_group != NULL);  g_return_if_fail (object != NULL);  g_return_if_fail (GTK_IS_OBJECT (object));  g_return_if_fail (g_slist_find (accel_group->attach_objects, object) != NULL);    accel_group->attach_objects = g_slist_remove (accel_group->attach_objects, object);  gtk_accel_group_unref (accel_group);  slist = gtk_object_get_data_by_id (object, accel_groups_key_id);  slist = g_slist_remove (slist, accel_group);  if (!slist)    gtk_signal_disconnect_by_func (object,				   GTK_SIGNAL_FUNC (gtk_accel_group_object_destroy),				   NULL);  gtk_object_set_data_by_id (object, accel_groups_key_id, slist);}voidgtk_accel_group_lock (GtkAccelGroup	 *accel_group){  g_return_if_fail (accel_group != NULL);    accel_group->lock_count += 1;}voidgtk_accel_group_unlock (GtkAccelGroup  *accel_group){  g_return_if_fail (accel_group != NULL);    if (accel_group->lock_count)    accel_group->lock_count -= 1;}static GtkAccelEntry*gtk_accel_group_lookup (GtkAccelGroup	*accel_group,			guint		 accel_key,			GdkModifierType	 accel_mods){  GtkAccelEntry key_entry = { 0 };    key_entry.accel_group = accel_group;  key_entry.accelerator_key = gdk_keyval_to_lower (accel_key);  key_entry.accelerator_mods = accel_mods & accel_group->modifier_mask;    return g_hash_table_lookup (accel_entry_hash_table, &key_entry);}gbooleangtk_accel_group_activate (GtkAccelGroup	 *accel_group,			  guint		  accel_key,			  GdkModifierType accel_mods){  GtkAccelEntry *entry;    g_return_val_if_fail (accel_group != NULL, FALSE);    entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods);  if (entry && entry->signal_id &&      (!GTK_IS_WIDGET (entry->object) || GTK_WIDGET_IS_SENSITIVE (entry->object)))    {      gtk_signal_emit (entry->object, entry->signal_id);      return TRUE;    }  return FALSE;}gbooleangtk_accel_groups_activate (GtkObject	    *object,			   guint	     accel_key,			   GdkModifierType   accel_mods){  g_return_val_if_fail (object != NULL, FALSE);  g_return_val_if_fail (GTK_IS_OBJECT (object), FALSE);    if (gtk_accelerator_valid (accel_key, accel_mods))    {      GSList *slist;            for (slist = gtk_accel_groups_from_object (object); slist; slist = slist->next)	if (gtk_accel_group_activate (slist->data, accel_key, accel_mods))	  return TRUE;      return gtk_accel_group_activate (gtk_accel_group_get_default (), accel_key, accel_mods);    }    return FALSE;}voidgtk_accel_group_lock_entry (GtkAccelGroup	 *accel_group,			    guint		  accel_key,			    GdkModifierType	  accel_mods){  GtkAccelEntry *entry;    g_return_if_fail (accel_group != NULL);    entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods);  if (entry)    entry->accel_flags |= GTK_ACCEL_LOCKED;}voidgtk_accel_group_unlock_entry (GtkAccelGroup	*accel_group,			      guint		 accel_key,			      GdkModifierType	 accel_mods){  GtkAccelEntry *entry;    g_return_if_fail (accel_group != NULL);    entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods);  if (entry)    entry->accel_flags &= ~GTK_ACCEL_LOCKED;}GtkAccelEntry*gtk_accel_group_get_entry (GtkAccelGroup    *accel_group,			   guint             accel_key,			   GdkModifierType   accel_mods){  g_return_val_if_fail (accel_group != NULL, 0);    return gtk_accel_group_lookup (accel_group, accel_key, accel_mods);}voidgtk_accel_group_add (GtkAccelGroup	*accel_group,		     guint		 accel_key,		     GdkModifierType	 accel_mods,		     GtkAccelFlags	 accel_flags,		     GtkObject		*object,		     const gchar	*accel_signal){  guint accel_signal_id = 0;  guint add_accelerator_signal_id = 0;  guint remove_accelerator_signal_id = 0;  gchar *signal;  GtkSignalQuery *query;  GSList *slist;  GSList *groups;  GSList *attach_objects;  GtkAccelEntry *entry;    g_return_if_fail (accel_group != NULL);  g_return_if_fail (object != NULL);  g_return_if_fail (GTK_IS_OBJECT (object));  g_return_if_fail (accel_signal != NULL);    /* check for required signals in the objects branch   */  signal = (gchar*) accel_signal;  accel_signal_id = gtk_signal_lookup (signal, GTK_OBJECT_TYPE (object));  if (accel_signal_id)    {      signal = "add-accelerator";      add_accelerator_signal_id = gtk_signal_lookup (signal, GTK_OBJECT_TYPE (object));    }  if (add_accelerator_signal_id)    {      signal = "remove-accelerator";      remove_accelerator_signal_id = gtk_signal_lookup (signal, GTK_OBJECT_TYPE (object));    }  if (!accel_signal_id ||      !add_accelerator_signal_id ||      !remove_accelerator_signal_id)    {      g_warning ("gtk_accel_group_add(): could not find signal \"%s\""		 "in the `%s' class ancestry",		 signal,		 gtk_type_name (GTK_OBJECT_TYPE (object)));      return;    }  query = gtk_signal_query (accel_signal_id);  if (!query ||      query->nparams > 0)    {      g_warning ("gtk_accel_group_add(): signal \"%s\" in the `%s' class ancestry"		 "cannot be used as accelerator signal",		 accel_signal,		 gtk_type_name (GTK_OBJECT_TYPE (object)));      if (query)	g_free (query);      return;    }  g_free (query);  /* prematurely abort if the group/entry is already locked   */  if (accel_group->lock_count > 0)    return;  entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods);  if (entry && entry->accel_flags & GTK_ACCEL_LOCKED)    return;    /* make sure our structures stay alive   */  gtk_accel_group_ref (accel_group);  gtk_object_ref (object);    /* remove an existing entry   */  if (entry)    gtk_signal_emit (entry->object, remove_accelerator_signal_id,		     accel_group,		     gdk_keyval_to_lower (accel_key),		     accel_mods & accel_group->modifier_mask);    /* abort if the entry still exists   */  entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods);  if (entry)    {      gtk_accel_group_unref (accel_group);      gtk_object_unref (object);            return;    }    /* collect accel groups and remove existing entries   */  attach_objects = accel_group->attach_objects;  groups = NULL;  for (attach_objects = accel_group->attach_objects; attach_objects; attach_objects = attach_objects->next)    {      GSList *tmp_groups;            tmp_groups = gtk_object_get_data_by_id (attach_objects->data, accel_groups_key_id);      while (tmp_groups)	{	  groups = g_slist_prepend (groups, tmp_groups->data);	  gtk_accel_group_ref (tmp_groups->data);	  tmp_groups = tmp_groups->next;	}    }  for (slist = groups; slist; slist = slist->next)    {      GtkAccelGroup *tmp_group;            tmp_group = slist->data;            /* we only remove the accelerator if neccessary       */      if (tmp_group->lock_count == 0)	{	  entry = gtk_accel_group_lookup (tmp_group, accel_key, accel_mods);	  if (entry && !(entry->accel_flags & GTK_ACCEL_LOCKED))	    gtk_signal_emit (entry->object, remove_accelerator_signal_id,			     tmp_group,			     gdk_keyval_to_lower (accel_key),			     accel_mods & tmp_group->modifier_mask);	}      gtk_accel_group_unref (tmp_group);    }  g_slist_free (groups);    /* now install the new accelerator   */  entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods);  if (!entry)    gtk_signal_emit (object, add_accelerator_signal_id,		     accel_signal_id,		     accel_group,		     gdk_keyval_to_lower (accel_key),		     accel_mods & accel_group->modifier_mask,		     accel_flags & GTK_ACCEL_MASK);    /* and release the structures again   */  gtk_accel_group_unref (accel_group);  gtk_object_unref (object);}static voidgtk_accel_group_delete_entries (GtkObject *object){  GSList *free_slist, *slist;    gtk_signal_disconnect_by_func (object,				 GTK_SIGNAL_FUNC (gtk_accel_group_delete_entries),				 NULL);  /* we remove all entries of this object the hard   * way (i.e. without signal emission).   */  free_slist = gtk_object_get_data_by_id (object, accel_entries_key_id);  gtk_object_set_data_by_id (object, accel_entries_key_id, NULL);  for (slist = free_slist; slist; slist = slist->next)    {      GtkAccelEntry *entry;            entry = slist->data;            g_hash_table_remove (accel_entry_hash_table, entry);      gtk_accel_group_unref (entry->accel_group);      g_chunk_free (entry, accel_entries_mem_chunk);    }  g_slist_free (free_slist);}voidgtk_accel_group_handle_add (GtkObject	      *object,			    guint	       accel_signal_id,			    GtkAccelGroup     *accel_group,			    guint	       accel_key,			    GdkModifierType    accel_mods,			    GtkAccelFlags      accel_flags){  GtkAccelEntry *entry;    g_return_if_fail (object != NULL);  g_return_if_fail (GTK_IS_OBJECT (object));  g_return_if_fail (accel_group != NULL);  g_return_if_fail (accel_signal_id > 0);

⌨️ 快捷键说明

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