pidgin.custom_smiley: 7e909282: Make PurpleSmiley a GObject.
sadrul at pidgin.im
sadrul at pidgin.im
Sat May 10 13:52:13 EDT 2008
-----------------------------------------------------------------
Revision: 7e9092824f06c7b014382e99b562f752ac48ffb4
Ancestor: 6cb9a36e5f58b4bd1b1967b93314b9180f668d51
Author: sadrul at pidgin.im
Date: 2008-05-10T16:31:06
Branch: im.pidgin.pidgin.custom_smiley
URL: http://d.pidgin.im/viewmtn/revision/info/7e9092824f06c7b014382e99b562f752ac48ffb4
Modified files:
libpurple/smiley.c libpurple/smiley.h pidgin/gtksmiley.c
ChangeLog:
Make PurpleSmiley a GObject.
Removed some functions from the API that are not really necessary,
including purple_smileys_add and purple_smileys_remove. They are called
automatically when a new smiley is created or removed.
PurpleSmiley has a 'destroy' signal, and 'shortcut' and 'image'
properties. These might be of interest to UIs.
-------------- next part --------------
============================================================
--- libpurple/smiley.c e0b362deae69584557dd24fde5fe90a380e04fcd
+++ libpurple/smiley.c e8df1adf843916528bbc1ee43009e09f674ad349
@@ -31,21 +31,26 @@
#include "smiley.h"
#include "util.h"
-
/**************************************************************************/
/* Main structures, members and constants */
/**************************************************************************/
struct _PurpleSmiley
{
- PurpleStoredImage *img; /**< The id of the stored image with the
- the smiley data. */
- char *shortcut; /**< Shortcut associated with the custom
- smiley. This field will work as a
- unique key by this API. */
- char *checksum; /**< The smiley checksum. */
+ GObject parent;
+ PurpleStoredImage *img; /**< The id of the stored image with the
+ the smiley data. */
+ char *shortcut; /**< Shortcut associated with the custom
+ smiley. This field will work as a
+ unique key by this API. */
+ char *checksum; /**< The smiley checksum. */
};
+struct _PurpleSmileyClass
+{
+ GObjectClass parent_class;
+};
+
static GHashTable *smiley_shortcut_index = NULL; /* shortcut (char *) => smiley (PurpleSmiley*) */
static GHashTable *smiley_checksum_index = NULL; /* checksum (char *) => smiley (PurpleSmiley*) */
@@ -115,7 +120,12 @@ purple_smiley_set_data_impl(PurpleSmiley
purple_smiley_set_data_impl(PurpleSmiley *smiley, guchar *smiley_data,
size_t smiley_data_len, const char *filename);
+static void
+purple_smiley_data_store(PurpleStoredImage *stored_img);
+static void
+purple_smiley_data_unstore(const char *filename);
+
/*********************************************************************
* Writing to disk *
*********************************************************************/
@@ -264,17 +274,174 @@ purple_smileys_load()
PurpleSmiley *smiley;
smiley = parse_smiley(smiley_node);
-
- purple_smileys_add(smiley);
}
}
xmlnode_free(root_node);
}
+/*********************************************************************
+ * GObject Stuff *
+ *********************************************************************/
+enum
+{
+ PROP_0,
+ PROP_SHORTCUT,
+ PROP_IMGSTORE,
+};
+#define PROP_SHORTCUT_S "shortcut"
+#define PROP_IMGSTORE_S "image"
+
+enum
+{
+ SIG_DESTROY,
+ SIG_LAST
+};
+
+static guint signals[SIG_LAST];
+
+static void
+purple_smiley_init(GTypeInstance *instance, gpointer klass)
+{
+}
+
+static void
+purple_smiley_get_property(GObject *object, guint param_id, GValue *value,
+ GParamSpec *spec)
+{
+ PurpleSmiley *smiley = PURPLE_SMILEY(object);
+ switch (param_id) {
+ case PROP_SHORTCUT:
+ g_value_set_string(value, smiley->shortcut);
+ break;
+ case PROP_IMGSTORE:
+ g_value_set_pointer(value, smiley->img);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, spec);
+ break;
+ }
+}
+
+static void
+purple_smiley_set_property(GObject *object, guint param_id, const GValue *value,
+ GParamSpec *spec)
+{
+ PurpleSmiley *smiley = PURPLE_SMILEY(object);
+ switch (param_id) {
+ case PROP_SHORTCUT:
+ {
+ const char *shortcut = g_value_get_string(value);
+ purple_smiley_set_shortcut(smiley, shortcut);
+ }
+ break;
+ case PROP_IMGSTORE:
+ {
+ PurpleStoredImage *img = g_value_get_pointer(value);
+
+ purple_imgstore_unref(smiley->img);
+ g_free(smiley->checksum);
+
+ smiley->img = img;
+ if (img) {
+ smiley->checksum = purple_util_get_image_checksum(
+ purple_imgstore_get_data(img),
+ purple_imgstore_get_size(img));
+ purple_smiley_data_store(img);
+ } else {
+ smiley->checksum = NULL;
+ }
+
+ g_object_notify(object, PROP_IMGSTORE_S);
+ }
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, spec);
+ break;
+ }
+}
+
+static void
+purple_smiley_finalize(GObject *obj)
+{
+ PurpleSmiley *smiley = PURPLE_SMILEY(obj);
+ g_signal_emit(obj, signals[SIG_DESTROY], 0);
+
+ if (g_hash_table_lookup(smiley_shortcut_index, smiley->shortcut)) {
+ g_hash_table_remove(smiley_shortcut_index, smiley->shortcut);
+ g_hash_table_remove(smiley_checksum_index, smiley->checksum);
+ }
+
+ g_free(smiley->shortcut);
+ g_free(smiley->checksum);
+ if (smiley->img)
+ purple_smiley_data_unstore(purple_imgstore_get_filename(smiley->img));
+ purple_imgstore_unref(smiley->img);
+
+ purple_smileys_save();
+}
+
+static void
+purple_smiley_class_init(PurpleSmileyClass *klass)
+{
+ GObjectClass *gobj_class = G_OBJECT_CLASS(klass);
+ GParamSpec *pspec;
+
+ gobj_class->get_property = purple_smiley_get_property;
+ gobj_class->set_property = purple_smiley_set_property;
+ gobj_class->finalize = purple_smiley_finalize;
+
+ /* Shortcut */
+ pspec = g_param_spec_string(PROP_SHORTCUT_S, _("Shortcut"),
+ _("The text-shortcut for the smiley"),
+ NULL,
+ G_PARAM_READWRITE);
+ g_object_class_install_property(gobj_class, PROP_SHORTCUT, pspec);
+
+ /* Stored Image */
+ pspec = g_param_spec_pointer(PROP_IMGSTORE_S, _("Stored Image"),
+ _("Stored Image. (that'll have to do for now)"),
+ G_PARAM_READWRITE);
+ g_object_class_install_property(gobj_class, PROP_IMGSTORE, pspec);
+
+ signals[SIG_DESTROY] = g_signal_new("destroy",
+ G_OBJECT_CLASS_TYPE(klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+GType
+purple_smiley_get_type(void)
+{
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleSmileyClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_smiley_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleSmiley),
+ 0,
+ purple_smiley_init,
+ NULL,
+ };
+
+ type = g_type_register_static(G_TYPE_OBJECT,
+ "PurpleSmiley",
+ &info, 0);
+ }
+
+ return type;
+}
+
/*********************************************************************
- * Stuff *
+ * Other Stuff *
*********************************************************************/
static char *get_file_full_path(const char *filename)
@@ -437,7 +604,7 @@ purple_smiley_set_data_impl(PurpleSmiley
purple_smiley_set_data_impl(PurpleSmiley *smiley, guchar *smiley_data,
size_t smiley_data_len, const char *filename)
{
- PurpleStoredImage *old_img;
+ PurpleStoredImage *old_img, *new_img;
const char *old_filename = NULL;
const char *new_filename = NULL;
@@ -446,23 +613,19 @@ purple_smiley_set_data_impl(PurpleSmiley
g_return_if_fail(smiley_data_len > 0);
old_img = smiley->img;
- smiley->img = NULL;
if (filename)
- smiley->img = purple_imgstore_add(smiley_data,
- smiley_data_len, filename);
+ new_img = purple_imgstore_add(smiley_data, smiley_data_len, filename);
else
- smiley->img = purple_smiley_data_new(smiley_data, smiley_data_len);
+ new_img = purple_smiley_data_new(smiley_data, smiley_data_len);
- g_free(smiley->checksum);
- smiley->checksum = purple_util_get_image_checksum(
- smiley_data, smiley_data_len);
+ g_object_set(G_OBJECT(smiley), PROP_IMGSTORE_S, new_img, NULL);
+ /* If the old and new image files have different names we need
+ * to unstore old image file. */
if (!old_img)
return;
- /* If the old and new image files have different names we need
- * to unstore old image file. */
old_filename = purple_imgstore_get_filename(old_img);
new_filename = purple_imgstore_get_filename(smiley->img);
@@ -482,27 +645,11 @@ purple_smiley_create(const char *shortcu
{
PurpleSmiley *smiley;
- smiley = g_slice_new0(PurpleSmiley);
- if (!smiley)
- return NULL;
+ smiley = PURPLE_SMILEY(g_object_new(PURPLE_TYPE_SMILEY, PROP_SHORTCUT_S, shortcut, NULL));
- smiley->shortcut = g_strdup(shortcut);
-
return smiley;
}
-static void
-purple_smiley_destroy(PurpleSmiley *smiley)
-{
- g_return_if_fail(smiley != NULL);
-
- g_free(smiley->shortcut);
- g_free(smiley->checksum);
- purple_imgstore_unref(smiley->img);
-
- g_slice_free(PurpleSmiley, smiley);
-}
-
PurpleSmiley *
purple_smiley_new(PurpleStoredImage *img, const char *shortcut)
{
@@ -519,17 +666,12 @@ purple_smiley_new(PurpleStoredImage *img
if (!smiley)
return NULL;
- smiley->checksum = purple_util_get_image_checksum(
- purple_imgstore_get_data(img),
- purple_imgstore_get_size(img));
+ g_object_set(G_OBJECT(smiley), PROP_IMGSTORE_S, img, NULL);
- smiley->img = img;
- purple_smiley_data_store(img);
-
return smiley;
}
-PurpleSmiley *
+static PurpleSmiley *
purple_smiley_new_from_stream(const char *shortcut, guchar *smiley_data,
size_t smiley_data_len, const char *filename)
{
@@ -580,11 +722,7 @@ purple_smiley_delete(PurpleSmiley *smile
{
g_return_if_fail(smiley != NULL);
- purple_smileys_remove(smiley);
- if (smiley->img)
- purple_smiley_data_unstore(purple_imgstore_get_filename(smiley->img));
-
- purple_smiley_destroy(smiley);
+ g_object_unref(smiley);
}
gboolean
@@ -598,7 +736,8 @@ purple_smiley_set_shortcut(PurpleSmiley
return FALSE;
/* Remove the old shortcut. */
- g_hash_table_remove(smiley_shortcut_index, smiley->shortcut);
+ if (smiley->shortcut)
+ g_hash_table_remove(smiley_shortcut_index, smiley->shortcut);
/* Insert the new shortcut. */
g_hash_table_insert(smiley_shortcut_index, g_strdup(shortcut), smiley);
@@ -606,6 +745,8 @@ purple_smiley_set_shortcut(PurpleSmiley
g_free(smiley->shortcut);
smiley->shortcut = g_strdup(shortcut);
+ g_object_notify(G_OBJECT(smiley), PROP_SHORTCUT_S);
+
purple_smileys_save();
return TRUE;
@@ -710,32 +851,6 @@ purple_smileys_get_all(void)
return returninglist;
}
-void
-purple_smileys_add(PurpleSmiley *smiley)
-{
- g_return_if_fail(smiley != NULL);
-
- if (!g_hash_table_lookup(smiley_shortcut_index, smiley->shortcut)) {
- g_hash_table_insert(smiley_shortcut_index, g_strdup(smiley->shortcut), smiley);
- g_hash_table_insert(smiley_checksum_index, g_strdup(smiley->checksum), smiley);
-
- purple_smileys_save();
- }
-}
-
-void
-purple_smileys_remove(PurpleSmiley *smiley)
-{
- g_return_if_fail(smiley != NULL);
-
- if (g_hash_table_lookup(smiley_shortcut_index, smiley->shortcut)) {
- g_hash_table_remove(smiley_shortcut_index, smiley->shortcut);
- g_hash_table_remove(smiley_checksum_index, smiley->checksum);
-
- purple_smileys_save();
- }
-}
-
PurpleSmiley *
purple_smileys_find_by_shortcut(const char *shortcut)
{
============================================================
--- libpurple/smiley.h 3a4f1b4b71fdab437064af39648a47a1327087c8
+++ libpurple/smiley.h ad29a9cdfd515a9056cd109f749a557ad69f7e11
@@ -1,5 +1,5 @@
/**
- * @file Smiley.h Smiley API
+ * @file smiley.h Smiley API
* @ingroup core
*/
@@ -28,6 +28,8 @@
#ifndef _PURPLE_SMILEY_H_
#define _PURPLE_SMILEY_H_
+#include <glib-object.h>
+
#include "imgstore.h"
#include "util.h"
@@ -35,9 +37,19 @@
* A custom smiley.
* This contains everything Purple will ever need to know about a custom smiley.
* Everything.
+ *
+ * PurpleSmiley is a GObject.
*/
-typedef struct _PurpleSmiley PurpleSmiley;
+typedef struct _PurpleSmiley PurpleSmiley;
+typedef struct _PurpleSmileyClass PurpleSmileyClass;
+#define PURPLE_TYPE_SMILEY (purple_smiley_get_type ())
+#define PURPLE_SMILEY(smiley) (G_TYPE_CHECK_INSTANCE_CAST ((smiley), PURPLE_TYPE_SMILEY, PurpleSmiley))
+#define PURPLE_SMILEY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PURPLE_TYPE_SMILEY, PurpleSmileyClass))
+#define PURPLE_IS_SMILEY(smiley) (G_TYPE_CHECK_INSTANCE_TYPE ((smiley), PURPLE_TYPE_SMILEY))
+#define PURPLE_IS_SMILEY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PURPLE_TYPE_SMILEY))
+#define PURPLE_SMILEY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PURPLE_TYPE_SMILEY, PurpleSmileyClass))
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -48,18 +60,10 @@ extern "C" {
/*@{*/
/**
- * Creates a new custom smiley structure and populates it.
- *
- * If a custom smiley with the informed shortcut already exist, it
- * will be automaticaly returned.
- *
- * @param img The image associated with the smiley.
- * @param shortcut The custom smiley associated shortcut.
- *
- * @return The custom smiley structure filled up.
+ * GObject foo.
+ * @internal.
*/
-PurpleSmiley *
-purple_smiley_new(PurpleStoredImage *img, const char *shortcut);
+GType purple_smiley_get_type(void);
/**
* Creates a new custom smiley structure and populates it.
@@ -67,15 +71,13 @@ purple_smiley_new(PurpleStoredImage *img
* If a custom smiley with the informed shortcut already exist, it
* will be automaticaly returned.
*
- * @param shortcut The custom smiley associated shortcut.
- * @param smiley_data The custom smiley data.
- * @param smiley_data_len The custom smiley data length.
+ * @param img The image associated with the smiley.
+ * @param shortcut The custom smiley associated shortcut.
*
* @return The custom smiley structure filled up.
*/
PurpleSmiley *
-purple_smiley_new_from_stream(const char *shortcut, guchar *smiley_data,
- size_t smiley_data_len, const char *filename);
+purple_smiley_new(PurpleStoredImage *img, const char *shortcut);
/**
* Creates a new custom smiley structure and populates it.
@@ -118,7 +120,7 @@ purple_smiley_set_shortcut(PurpleSmiley
* Changes the custom smiley's data.
*
* When the filename controling is made outside this API, the param
- * @keepfilename must be TRUE.
+ * #keepfilename must be TRUE.
* Otherwise, the file and filename will be regenerated, and the
* old one will be removed.
*
@@ -204,7 +206,7 @@ char *purple_smiley_get_full_path(Purple
/**************************************************************************/
-/** @name Custom Smiley Subsistem API */
+/** @name Custom Smiley Subsystem API */
/**************************************************************************/
/*@{*/
@@ -217,24 +219,6 @@ purple_smileys_get_all(void);
purple_smileys_get_all(void);
/**
- * Adds the custom smiley to the library persistence.
- *
- * @param smiley The custom smiley.
- *
- */
-void
-purple_smileys_add(PurpleSmiley *smiley);
-
-/**
- * Remove the custom smiley from persistence.
- *
- * @param smiley The custom smiley.
- *
- */
-void
-purple_smileys_remove(PurpleSmiley *smiley);
-
-/**
* Returns the custom smiley given it's shortcut.
*
* @param shortcut The custom smiley's shortcut.
============================================================
--- pidgin/gtksmiley.c 3fadd5ba67a99e74f719ccd0aecf878e991d3ef3
+++ pidgin/gtksmiley.c 5535824aa2328db107ceea8db49c5479e8375725
@@ -76,6 +76,7 @@ pidgin_smiley_destroy(PidginSmiley *smil
/******************************************************************************
* GtkIMHtmlSmileys stuff
*****************************************************************************/
+/* Perhaps these should be in gtkimhtml.c instead. -- sadrul */
static void add_gtkimhtml_to_list(GtkIMHtmlSmiley *gtksmiley)
{
gtk_smileys = g_slist_prepend(gtk_smileys, gtksmiley);
@@ -83,7 +84,13 @@ static void add_gtkimhtml_to_list(GtkIMH
purple_debug_info("gtksmiley", "adding %s to gtk_smileys\n", gtksmiley->smile);
}
-/* Perhaps this should be in gtkimhtml.c instead. -- sad */
+static void
+shortcut_changed_cb(PurpleSmiley *smiley, gpointer dontcare, GtkIMHtmlSmiley *gtksmiley)
+{
+ g_free(gtksmiley->smile);
+ gtksmiley->smile = g_strdup(purple_smiley_get_shortcut(smiley));
+}
+
static GtkIMHtmlSmiley *smiley_purple_to_gtkimhtml(PurpleSmiley *smiley)
{
GtkIMHtmlSmiley *gtksmiley;
@@ -92,21 +99,17 @@ static GtkIMHtmlSmiley *smiley_purple_to
file = purple_imgstore_get_filename(purple_smiley_get_stored_image(smiley));
- filename = g_build_filename(purple_smileys_get_storing_dir(),file, NULL);
+ filename = g_build_filename(purple_smileys_get_storing_dir(), file, NULL);
gtksmiley = gtk_imhtml_smiley_create(filename, purple_smiley_get_shortcut(smiley),
FALSE, GTK_IMHTML_SMILEY_CUSTOM);
g_free(filename);
- return gtksmiley;
-}
+ /* Make sure the shortcut for the GtkIMHtmlSmiley is updated with the PurpleSmiley */
+ g_signal_connect(G_OBJECT(smiley), "notify::shortcut",
+ G_CALLBACK(shortcut_changed_cb), gtksmiley);
-void pidgin_smiley_add_to_list(PurpleSmiley *smiley)
-{
- GtkIMHtmlSmiley *gtksmiley;
-
- gtksmiley = smiley_purple_to_gtkimhtml(smiley);
- add_gtkimhtml_to_list(gtksmiley);
+ return gtksmiley;
}
void pidgin_smiley_del_from_list(PurpleSmiley *smiley)
@@ -126,6 +129,8 @@ void pidgin_smiley_del_from_list(PurpleS
continue;
gtk_imhtml_smiley_destroy(gtksmiley);
+ g_signal_handlers_disconnect_matched(G_OBJECT(smiley), G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, gtksmiley);
break;
}
@@ -133,6 +138,15 @@ void pidgin_smiley_del_from_list(PurpleS
gtk_smileys = g_slist_delete_link(gtk_smileys, list);
}
+void pidgin_smiley_add_to_list(PurpleSmiley *smiley)
+{
+ GtkIMHtmlSmiley *gtksmiley;
+
+ gtksmiley = smiley_purple_to_gtkimhtml(smiley);
+ add_gtkimhtml_to_list(gtksmiley);
+ g_signal_connect(G_OBJECT(smiley), "destroy", G_CALLBACK(pidgin_smiley_del_from_list), NULL);
+}
+
void pidgin_smileys_init(void)
{
GList *smileys;
@@ -224,7 +238,6 @@ static void do_add(GtkWidget *widget, Pi
purple_debug_info("gtksmiley", "adding a new smiley\n");
emoticon = purple_smiley_new_from_file(entry, s->filename);
- purple_smileys_add(emoticon);
if (gtk_smileys != NULL)
pidgin_smiley_add_to_list(emoticon);
}
@@ -371,36 +384,45 @@ static void delete_foreach(GtkTreeModel
static void delete_foreach(GtkTreeModel *model, GtkTreePath *path,
GtkTreeIter *iter, gpointer data)
{
- PurpleSmiley *smiley;
- char *shortcut;
+ PurpleSmiley *smiley = NULL;
SmileyManager *dialog;
dialog = (SmileyManager*)data;
gtk_tree_model_get(model, iter,
- SHORTCUT, &shortcut,
+ SMILEY, &smiley,
-1);
- purple_debug_info("gtksmiley", "delete_foreach shortcut = %s\n", shortcut);
-
- smiley = purple_smileys_find_by_shortcut(shortcut);
-
- if(smiley == NULL)
- purple_debug_error("gtksmiley", "%s not found\n", shortcut);
- else {
+ if(smiley != NULL) {
+ g_object_unref(G_OBJECT(smiley));
pidgin_smiley_del_from_list(smiley);
purple_smiley_delete(smiley);
}
+}
- g_free(shortcut);
+static void append_to_list(GtkTreeModel *model, GtkTreePath *path,
+ GtkTreeIter *iter, gpointer data)
+{
+ GList **list = data;
+ *list = g_list_prepend(*list, gtk_tree_path_copy(path));
}
static void smiley_delete(SmileyManager *dialog)
{
GtkTreeSelection *selection;
+ GList *list = NULL;
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview));
gtk_tree_selection_selected_foreach(selection, delete_foreach, dialog);
+ gtk_tree_selection_selected_foreach(selection, append_to_list, &list);
+
+ while (list) {
+ GtkTreeIter iter;
+ if (gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), &iter, list->data))
+ gtk_list_store_remove(GTK_LIST_STORE(dialog->model), &iter);
+ gtk_tree_path_free(list->data);
+ list = g_list_delete_link(list, list);
+ }
}
/******************************************************************************
* The Smiley Manager
@@ -499,6 +521,7 @@ static void smiley_edit_cb(GtkTreeView *
gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), &iter, path);
gtk_tree_model_get(GTK_TREE_MODEL(dialog->model), &iter, SMILEY, &smiley, -1);
pidgin_smiley_edit(gtk_widget_get_toplevel(GTK_WIDGET(treeview)), smiley);
+ g_object_unref(G_OBJECT(smiley));
}
static GtkWidget *smiley_list_create(SmileyManager *dialog)
@@ -519,7 +542,7 @@ static GtkWidget *smiley_list_create(Smi
dialog->model = gtk_list_store_new(N_COL,
GDK_TYPE_PIXBUF, /* ICON */
G_TYPE_STRING, /* SHORTCUT */
- G_TYPE_POINTER /* SMILEY */
+ G_TYPE_OBJECT /* SMILEY */
);
/* the actual treeview */
@@ -557,7 +580,6 @@ static void smiley_manager_select_cb(Gtk
break;
case GTK_RESPONSE_NO:
smiley_delete(dialog);
- refresh_list();
break;
case GTK_RESPONSE_DELETE_EVENT:
case GTK_RESPONSE_CLOSE:
More information about the Commits
mailing list