1 /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
2 /* vim:set et sts=4: */
3 /* ibus - The Input Bus
4 * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
5 * Copyright (C) 2008-2019 Red Hat, Inc.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
20 * USA
21 */
22
23 #include "ibusobject.h"
24 #include "ibusmarshalers.h"
25 #include "ibusinternal.h"
26
27 #define IBUS_OBJECT_GET_PRIVATE(o) \
28 ((IBusObjectPrivate *)ibus_object_get_instance_private (o))
29
30 enum {
31 DESTROY,
32 LAST_SIGNAL,
33 };
34
35 struct _IBusObjectPrivate {
36 gpointer pad;
37 };
38
39 static guint object_signals[LAST_SIGNAL] = { 0 };
40
41 // #define DEBUG_MEMORY
42 #ifdef DEBUG_MEMORY
43 static GHashTable *_count_table;
44 static guint _count = 0;
45 #endif
46
47 /* functions prototype */
48 static GObject *ibus_object_constructor (GType type,
49 guint n,
50 GObjectConstructParam
51 *args);
52 static void ibus_object_dispose (IBusObject *obj);
53 static void ibus_object_finalize (IBusObject *obj);
54 static void ibus_object_real_destroy (IBusObject *obj);
55
G_DEFINE_TYPE_WITH_PRIVATE(IBusObject,ibus_object,G_TYPE_INITIALLY_UNOWNED)56 G_DEFINE_TYPE_WITH_PRIVATE (IBusObject, ibus_object, G_TYPE_INITIALLY_UNOWNED)
57
58 static void
59 ibus_object_class_init (IBusObjectClass *class)
60 {
61 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
62
63 gobject_class->constructor = ibus_object_constructor;
64 gobject_class->dispose = (GObjectFinalizeFunc) ibus_object_dispose;
65 gobject_class->finalize = (GObjectFinalizeFunc) ibus_object_finalize;
66
67 class->destroy = ibus_object_real_destroy;
68
69 /* install signals */
70 /**
71 * IBusObject::destroy:
72 * @object: An IBusObject.
73 *
74 * Destroy and free an IBusObject
75 *
76 * See also: ibus_object_destroy().
77 *
78 * <note><para>Argument @user_data is ignored in this function.</para></note>
79 */
80 object_signals[DESTROY] =
81 g_signal_new (I_("destroy"),
82 G_TYPE_FROM_CLASS (gobject_class),
83 G_SIGNAL_RUN_LAST,
84 G_STRUCT_OFFSET (IBusObjectClass, destroy),
85 NULL, NULL,
86 _ibus_marshal_VOID__VOID,
87 G_TYPE_NONE, 0);
88
89 #ifdef DEBUG_MEMORY
90 _count_table = g_hash_table_new (g_direct_hash, g_direct_equal);
91 #endif
92 }
93
94 static void
ibus_object_init(IBusObject * obj)95 ibus_object_init (IBusObject *obj)
96 {
97 obj->flags = 0;
98 obj->priv = IBUS_OBJECT_GET_PRIVATE (obj);
99 }
100
101
102 static GObject *
ibus_object_constructor(GType type,guint n,GObjectConstructParam * args)103 ibus_object_constructor (GType type,
104 guint n,
105 GObjectConstructParam *args)
106 {
107 GObject *object;
108
109 object = G_OBJECT_CLASS (ibus_object_parent_class)->constructor (type, n ,args);
110
111 #ifdef DEBUG_MEMORY
112 if (object != NULL) {
113 guint count;
114 _count ++;
115
116 count = GPOINTER_TO_UINT (g_hash_table_lookup (_count_table, (gpointer) type));
117 g_hash_table_replace (_count_table, (gpointer) type, GUINT_TO_POINTER (++count));
118
119 g_debug ("new %s, count = %d, all = %d", g_type_name (type), count, _count);
120 }
121 #endif
122
123 return object;
124 }
125
126
127 static void
ibus_object_dispose(IBusObject * obj)128 ibus_object_dispose (IBusObject *obj)
129 {
130 if (! (IBUS_OBJECT_FLAGS (obj) & IBUS_IN_DESTRUCTION)) {
131 IBUS_OBJECT_SET_FLAGS (obj, IBUS_IN_DESTRUCTION);
132 if (! (IBUS_OBJECT_FLAGS (obj) & IBUS_DESTROYED)) {
133 g_signal_emit (obj, object_signals[DESTROY], 0);
134 IBUS_OBJECT_SET_FLAGS (obj, IBUS_DESTROYED);
135 }
136 IBUS_OBJECT_UNSET_FLAGS (obj, IBUS_IN_DESTRUCTION);
137 }
138
139 G_OBJECT_CLASS(ibus_object_parent_class)->dispose (G_OBJECT (obj));
140 }
141
142 static void
ibus_object_finalize(IBusObject * obj)143 ibus_object_finalize (IBusObject *obj)
144 {
145 #ifdef DEBUG_MEMORY
146 guint count;
147
148 _count --;
149 count = GPOINTER_TO_UINT (g_hash_table_lookup (_count_table, (gpointer)G_OBJECT_TYPE (obj)));
150 g_hash_table_replace (_count_table, (gpointer)G_OBJECT_TYPE (obj), GUINT_TO_POINTER (--count));
151 g_debug ("Finalize %s, count = %d, all = %d", G_OBJECT_TYPE_NAME (obj), count, _count);
152 #endif
153
154 G_OBJECT_CLASS(ibus_object_parent_class)->finalize (G_OBJECT (obj));
155 }
156
157 static void
ibus_object_real_destroy(IBusObject * obj)158 ibus_object_real_destroy (IBusObject *obj)
159 {
160 g_signal_handlers_destroy (obj);
161 }
162
163 IBusObject *
ibus_object_new(void)164 ibus_object_new (void)
165 {
166 GObject *object = g_object_new (IBUS_TYPE_OBJECT, NULL);
167 return IBUS_OBJECT (object);
168 }
169
170 void
ibus_object_destroy(IBusObject * obj)171 ibus_object_destroy (IBusObject *obj)
172 {
173 g_return_if_fail (IBUS_IS_OBJECT (obj));
174
175 if (! (IBUS_OBJECT_FLAGS (obj) & IBUS_IN_DESTRUCTION)) {
176 g_object_run_dispose (G_OBJECT (obj));
177 }
178 }
179