1 /* vi: set et sw=4 ts=8 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 8 -*- */
3 /*
4 * This file is part of mission-control
5 *
6 * Copyright (C) 2007 Nokia Corporation.
7 *
8 * Contact: Naba Kumar <naba.kumar@nokia.com>
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public License
12 * version 2.1 as published by the Free Software Foundation.
13 *
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 *
24 */
25
26 /**
27 * SECTION:mcd-mission
28 * @title: McdMission
29 * @short_description: Base class for server classes
30 * @see_also:
31 * @stability: Unstable
32 * @include: mcd-mission.h
33 *
34 * It is the base class for every object in mission-control. It defines
35 * a set of virtual functions and set of corresponding action signals.
36 * all virtual functions results in emission of their corresponding action
37 * signals. The virtual functions define states of the object, such
38 * as memory conserved state, connected state, locked state, low power state,
39 * lit state, sleeping state etc. Each of the object states can also be queried
40 * independently as properties.
41 *
42 * There are also some action signals such as abort, which is used to notify
43 * other objects holding hard references to it to release them (this object
44 * should then automatically die since all held references are released). It
45 * is mandatory for all other objects that hold a hard reference to it to
46 * listen for this signal and release the reference in signal handler.
47 *
48 * Concrete derived classes should override the sate methods to implement
49 * object specific state managements.
50 */
51
52 #include "config.h"
53
54 #include "mcd-mission-priv.h"
55
56 #include <telepathy-glib/telepathy-glib.h>
57
58 #include "mcd-enum-types.h"
59
60 #define MCD_MISSION_PRIV(mission) (G_TYPE_INSTANCE_GET_PRIVATE ((mission), \
61 MCD_TYPE_MISSION, \
62 McdMissionPrivate))
63
64 G_DEFINE_TYPE (McdMission, mcd_mission, G_TYPE_OBJECT);
65
66 /* Private */
67
68 typedef struct _McdMissionPrivate
69 {
70 McdMission *parent;
71
72 gboolean connected;
73 gboolean is_disposed;
74
75 } McdMissionPrivate;
76
77 enum _McdMissionSignalType
78 {
79 CONNECTED,
80 DISCONNECTED,
81 PARENT_SET,
82 ABORT,
83 LAST_SIGNAL
84 };
85
86 enum _McdMissionPropertyType
87 {
88 PROP_0,
89 PROP_PARENT
90 };
91
92 static guint mcd_mission_signals[LAST_SIGNAL] = { 0 };
93
94 static void
_mcd_mission_connect(McdMission * mission)95 _mcd_mission_connect (McdMission * mission)
96 {
97 McdMissionPrivate *priv;
98
99 g_return_if_fail (MCD_IS_MISSION (mission));
100 priv = MCD_MISSION_PRIV (mission);
101
102 if (!priv->connected)
103 {
104 priv->connected = TRUE;
105 g_signal_emit_by_name (mission, "connected");
106 }
107 }
108
109 static void
_mcd_mission_disconnect(McdMission * mission)110 _mcd_mission_disconnect (McdMission * mission)
111 {
112 McdMissionPrivate *priv;
113
114 g_return_if_fail (MCD_IS_MISSION (mission));
115 priv = MCD_MISSION_PRIV (mission);
116
117 if (priv->connected)
118 {
119 priv->connected = FALSE;
120 g_signal_emit_by_name (mission, "disconnected");
121 }
122 }
123
124 static void
on_parent_abort(McdMission * parent,McdMission * mission)125 on_parent_abort (McdMission *parent, McdMission *mission)
126 {
127 DEBUG ("called");
128 _mcd_mission_set_parent (mission, NULL);
129 }
130
131 void
_mcd_mission_set_parent(McdMission * mission,McdMission * parent)132 _mcd_mission_set_parent (McdMission * mission, McdMission * parent)
133 {
134 McdMissionPrivate *priv;
135
136 g_return_if_fail (MCD_IS_MISSION (mission));
137 g_return_if_fail ((parent == NULL) || MCD_IS_MISSION (parent));
138
139 priv = MCD_MISSION_PRIV (mission);
140
141 DEBUG ("child = %p, parent = %p", mission, parent);
142
143 if (priv->parent)
144 {
145 g_signal_handlers_disconnect_by_func (priv->parent,
146 on_parent_abort,
147 mission);
148 }
149
150 if (parent)
151 {
152 g_signal_connect (parent, "abort",
153 G_CALLBACK (on_parent_abort),
154 mission);
155 g_object_ref (parent);
156 }
157
158 tp_clear_object (&priv->parent);
159 priv->parent = parent;
160 }
161
162 static void
_mcd_mission_abort(McdMission * mission)163 _mcd_mission_abort (McdMission * mission)
164 {
165 g_signal_emit_by_name (G_OBJECT (mission), "abort");
166 }
167
168 static void
_mcd_mission_dispose(GObject * object)169 _mcd_mission_dispose (GObject * object)
170 {
171 McdMissionPrivate *priv;
172 g_return_if_fail (MCD_IS_MISSION (object));
173
174 priv = MCD_MISSION_PRIV (object);
175
176 if (priv->is_disposed)
177 {
178 return;
179 }
180
181 priv->is_disposed = TRUE;
182
183 DEBUG ("mission disposed %p", object);
184 if (priv->parent)
185 {
186 g_signal_handlers_disconnect_by_func (priv->parent,
187 on_parent_abort,
188 object);
189 }
190
191 tp_clear_object (&priv->parent);
192
193 G_OBJECT_CLASS (mcd_mission_parent_class)->dispose (object);
194 }
195
196 static void
_mcd_mission_finalize(GObject * object)197 _mcd_mission_finalize (GObject * object)
198 {
199 DEBUG ("mission finalized %p", object);
200 G_OBJECT_CLASS (mcd_mission_parent_class)->finalize (object);
201 }
202
203 static void
_mcd_set_property(GObject * object,guint prop_id,const GValue * val,GParamSpec * pspec)204 _mcd_set_property (GObject * object, guint prop_id, const GValue * val,
205 GParamSpec * pspec)
206 {
207 McdMission *mission = MCD_MISSION (object);
208
209 switch (prop_id)
210 {
211 case PROP_PARENT:
212 _mcd_mission_set_parent (mission, g_value_get_object (val));
213 break;
214 default:
215 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
216 break;
217 }
218 }
219
220 static void
_mcd_get_property(GObject * object,guint prop_id,GValue * val,GParamSpec * pspec)221 _mcd_get_property (GObject * object, guint prop_id, GValue * val,
222 GParamSpec * pspec)
223 {
224 McdMission *mission = MCD_MISSION (object);
225
226 switch (prop_id)
227 {
228 case PROP_PARENT:
229 g_value_set_object (val, mcd_mission_get_parent (mission));
230 break;
231 default:
232 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
233 break;
234 }
235 }
236
237 static void
mcd_mission_class_init(McdMissionClass * klass)238 mcd_mission_class_init (McdMissionClass * klass)
239 {
240 GObjectClass *object_class = G_OBJECT_CLASS (klass);
241 g_type_class_add_private (object_class, sizeof (McdMissionPrivate));
242
243 /* virtual medthods */
244 object_class->finalize = _mcd_mission_finalize;
245 object_class->dispose = _mcd_mission_dispose;
246 object_class->set_property = _mcd_set_property;
247 object_class->get_property = _mcd_get_property;
248
249 /* virtual medthods */
250 klass->abort = _mcd_mission_abort;
251 klass->connect = _mcd_mission_connect;
252 klass->disconnect = _mcd_mission_disconnect;
253
254 /* signals */
255 mcd_mission_signals[ABORT] =
256 g_signal_new ("abort",
257 G_OBJECT_CLASS_TYPE (klass),
258 G_SIGNAL_RUN_FIRST,
259 G_STRUCT_OFFSET (McdMissionClass, abort_signal),
260 NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE,
261 0);
262 mcd_mission_signals[CONNECTED] =
263 g_signal_new ("connected", G_OBJECT_CLASS_TYPE (klass),
264 G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (McdMissionClass,
265 connected_signal),
266 NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE,
267 0);
268 mcd_mission_signals[DISCONNECTED] =
269 g_signal_new ("disconnected", G_OBJECT_CLASS_TYPE (klass),
270 G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (McdMissionClass,
271 disconnected_signal),
272 NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE,
273 0);
274 }
275
276 static void
mcd_mission_init(McdMission * obj)277 mcd_mission_init (McdMission * obj)
278 {
279 }
280
281 /* Public methods */
282
283 void
mcd_mission_connect(McdMission * mission)284 mcd_mission_connect (McdMission * mission)
285 {
286 g_return_if_fail (MCD_IS_MISSION (mission));
287 MCD_MISSION_GET_CLASS (mission)->connect (mission);
288 }
289
290 void
mcd_mission_disconnect(McdMission * mission)291 mcd_mission_disconnect (McdMission * mission)
292 {
293 g_return_if_fail (MCD_IS_MISSION (mission));
294 MCD_MISSION_GET_CLASS (mission)->disconnect (mission);
295 }
296
297 void
mcd_mission_abort(McdMission * mission)298 mcd_mission_abort (McdMission * mission)
299 {
300 g_return_if_fail (MCD_IS_MISSION (mission));
301 MCD_MISSION_GET_CLASS (mission)->abort (mission);
302 }
303
304 gboolean
mcd_mission_is_connected(McdMission * mission)305 mcd_mission_is_connected (McdMission * mission)
306 {
307 McdMissionPrivate *priv;
308
309 g_return_val_if_fail (MCD_IS_MISSION (mission), FALSE);
310 priv = MCD_MISSION_PRIV (mission);
311
312 return priv->connected;
313 }
314
315 McdMission *
mcd_mission_get_parent(McdMission * mission)316 mcd_mission_get_parent (McdMission * mission)
317 {
318 McdMissionPrivate *priv;
319
320 g_return_val_if_fail (MCD_IS_MISSION (mission), NULL);
321 priv = MCD_MISSION_PRIV (mission);
322
323 return priv->parent;
324 }
325