| File: | shell/ev-daemon.c |
| Warning: | line 212, column 52 Access to field 'loaded_id' results in a dereference of a null pointer (loaded from variable 'doc') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* ev-daemon.c | |||
| 2 | * this file is part of lector, a cafe document viewer | |||
| 3 | * | |||
| 4 | * Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org> | |||
| 5 | * Copyright © 2010, 2012 Christian Persch | |||
| 6 | * | |||
| 7 | * Lector is free software; you can redistribute it and/or modify it | |||
| 8 | * under the terms of the GNU General Public License as published by | |||
| 9 | * the Free Software Foundation; either version 2 of the License, or | |||
| 10 | * (at your option) any later version. | |||
| 11 | * | |||
| 12 | * Lector is distributed in the hope that it will be useful, but | |||
| 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| 15 | * General Public License for more details. | |||
| 16 | * | |||
| 17 | * You should have received a copy of the GNU General Public License | |||
| 18 | * along with this program; if not, write to the Free Software | |||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
| 20 | */ | |||
| 21 | ||||
| 22 | #include "config.h" | |||
| 23 | ||||
| 24 | #define G_LOG_DOMAIN"LectorDaemon" "LectorDaemon" | |||
| 25 | #include <glib.h> | |||
| 26 | #include <glib/gstdio.h> | |||
| 27 | #include <gio/gio.h> | |||
| 28 | #include <string.h> | |||
| 29 | #include <sys/types.h> | |||
| 30 | #include <sys/stat.h> | |||
| 31 | #include <sys/wait.h> | |||
| 32 | #include <fcntl.h> | |||
| 33 | #include <unistd.h> | |||
| 34 | ||||
| 35 | #include "ev-daemon-gdbus-generated.h" | |||
| 36 | ||||
| 37 | #define EV_DBUS_DAEMON_NAME"org.cafe.lector.Daemon" "org.cafe.lector.Daemon" | |||
| 38 | #define EV_DBUS_DAEMON_INTERFACE_NAME"org.cafe.lector.Daemon" "org.cafe.lector.Daemon" | |||
| 39 | #define EV_DBUS_DAEMON_OBJECT_PATH"/org/cafe/lector/Daemon" "/org/cafe/lector/Daemon" | |||
| 40 | ||||
| 41 | #define EV_DBUS_WINDOW_INTERFACE_NAME"org.cafe.lector.Window" "org.cafe.lector.Window" | |||
| 42 | ||||
| 43 | #define DAEMON_TIMEOUT(30) (30) /* seconds */ | |||
| 44 | ||||
| 45 | #define LOGg_debug g_debug | |||
| 46 | ||||
| 47 | ||||
| 48 | #define EV_TYPE_DAEMON_APPLICATION(ev_daemon_application_get_type ()) (ev_daemon_application_get_type ()) | |||
| 49 | #define EV_DAEMON_APPLICATION(object)((((EvDaemonApplication*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((object)), ((ev_daemon_application_get_type ())))))) (G_TYPE_CHECK_INSTANCE_CAST ((object), EV_TYPE_DAEMON_APPLICATION, EvDaemonApplication)(((EvDaemonApplication*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((object)), ((ev_daemon_application_get_type ())))))) | |||
| 50 | #define EV_DAEMON_APPLICATION_CLASS(klass)((((EvDaemonApplicationClass*) (void *) g_type_check_class_cast ((GTypeClass*) ((klass)), ((ev_daemon_application_get_type ( ))))))) (G_TYPE_CHECK_CLASS_CAST ((klass), EV_TYPE_DAEMON_APPLICATION, EvDaemonApplicationClass)(((EvDaemonApplicationClass*) (void *) g_type_check_class_cast ((GTypeClass*) ((klass)), ((ev_daemon_application_get_type ( ))))))) | |||
| 51 | #define EV_IS_DAEMON_APPLICATION(object)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (object)); GType __t = ((ev_daemon_application_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0) ); else __r = g_type_check_instance_is_a (__inst, __t); __r; } )))) (G_TYPE_CHECK_INSTANCE_TYPE ((object), EV_TYPE_DAEMON_APPLICATION)((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (object)); GType __t = ((ev_daemon_application_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0) ); else __r = g_type_check_instance_is_a (__inst, __t); __r; } )))) | |||
| 52 | #define EV_IS_DAEMON_APPLICATION_CLASS(klass)(((__extension__ ({ GTypeClass *__class = (GTypeClass*) ((klass )); GType __t = ((ev_daemon_application_get_type ())); gboolean __r; if (!__class) __r = (0); else if (__class->g_type == __t) __r = (!(0)); else __r = g_type_check_class_is_a (__class , __t); __r; })))) (G_TYPE_CHECK_CLASS_TYPE ((klass), EV_TYPE_DAEMON_APPLICATION)((__extension__ ({ GTypeClass *__class = (GTypeClass*) ((klass )); GType __t = ((ev_daemon_application_get_type ())); gboolean __r; if (!__class) __r = (0); else if (__class->g_type == __t) __r = (!(0)); else __r = g_type_check_class_is_a (__class , __t); __r; })))) | |||
| 53 | #define EV_DAEMON_APPLICATION_GET_CLASS(obj)((((EvDaemonApplicationClass*) (((GTypeInstance*) ((obj)))-> g_class)))) (G_TYPE_INSTANCE_GET_CLASS ((obj), EV_TYPE_DAEMON_APPLICATION, EvDaemonApplicationClass)(((EvDaemonApplicationClass*) (((GTypeInstance*) ((obj)))-> g_class)))) | |||
| 54 | ||||
| 55 | typedef struct _EvDaemonApplication EvDaemonApplication; | |||
| 56 | typedef struct _EvDaemonApplicationClass EvDaemonApplicationClass; | |||
| 57 | ||||
| 58 | struct _EvDaemonApplicationClass { | |||
| 59 | GApplicationClass parent_class; | |||
| 60 | }; | |||
| 61 | ||||
| 62 | struct _EvDaemonApplication | |||
| 63 | { | |||
| 64 | GApplication parent_instance; | |||
| 65 | ||||
| 66 | EvDaemon *daemon; | |||
| 67 | GHashTable *pending_invocations; | |||
| 68 | GList *docs; | |||
| 69 | }; | |||
| 70 | ||||
| 71 | static GType ev_daemon_application_get_type (void); | |||
| 72 | G_DEFINE_TYPE (EvDaemonApplication, ev_daemon_application, G_TYPE_APPLICATION)static void ev_daemon_application_init (EvDaemonApplication * self); static void ev_daemon_application_class_init (EvDaemonApplicationClass *klass); static GType ev_daemon_application_get_type_once (void ); static gpointer ev_daemon_application_parent_class = ((void *)0); static gint EvDaemonApplication_private_offset; static void ev_daemon_application_class_intern_init (gpointer klass) { ev_daemon_application_parent_class = g_type_class_peek_parent (klass); if (EvDaemonApplication_private_offset != 0) g_type_class_adjust_private_offset (klass, &EvDaemonApplication_private_offset ); ev_daemon_application_class_init ((EvDaemonApplicationClass *) klass); } __attribute__ ((__unused__)) static inline gpointer ev_daemon_application_get_instance_private (EvDaemonApplication *self) { return (((gpointer) ((guint8*) (self) + (glong) (EvDaemonApplication_private_offset )))); } GType ev_daemon_application_get_type (void) { static gsize static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); (void) (0 ? (gpointer) *( &static_g_define_type_id) : ((void*)0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id )); }))) { GType g_define_type_id = ev_daemon_application_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id) = (g_define_type_id) ) : (void) 0; g_once_init_leave ((&static_g_define_type_id ), (gsize) (g_define_type_id)); })); } return static_g_define_type_id ; } __attribute__ ((__noinline__)) static GType ev_daemon_application_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple ((g_application_get_type ()), g_intern_static_string ("EvDaemonApplication" ), sizeof (EvDaemonApplicationClass), (GClassInitFunc)(void ( *)(void)) ev_daemon_application_class_intern_init, sizeof (EvDaemonApplication ), (GInstanceInitFunc)(void (*)(void)) ev_daemon_application_init , (GTypeFlags) 0); { {{};} } return g_define_type_id; } | |||
| 73 | ||||
| 74 | typedef struct { | |||
| 75 | gchar *dbus_name; | |||
| 76 | gchar *uri; | |||
| 77 | guint watch_id; | |||
| 78 | guint loaded_id; | |||
| 79 | } EvDoc; | |||
| 80 | ||||
| 81 | static void | |||
| 82 | ev_doc_free (EvDoc *doc) | |||
| 83 | { | |||
| 84 | if (!doc) | |||
| 85 | return; | |||
| 86 | ||||
| 87 | g_free (doc->dbus_name); | |||
| 88 | g_free (doc->uri); | |||
| 89 | ||||
| 90 | g_bus_unwatch_name (doc->watch_id); | |||
| 91 | ||||
| 92 | g_free (doc); | |||
| 93 | } | |||
| 94 | ||||
| 95 | static EvDoc * | |||
| 96 | ev_daemon_application_find_doc (EvDaemonApplication *application, | |||
| 97 | const gchar *uri) | |||
| 98 | { | |||
| 99 | GList *l; | |||
| 100 | ||||
| 101 | for (l = application->docs; l != NULL((void*)0); l = l->next) { | |||
| 102 | EvDoc *doc = (EvDoc *)l->data; | |||
| 103 | ||||
| 104 | if (strcmp (doc->uri, uri) == 0) | |||
| 105 | return doc; | |||
| 106 | } | |||
| 107 | ||||
| 108 | return NULL((void*)0); | |||
| 109 | } | |||
| 110 | ||||
| 111 | static gboolean | |||
| 112 | spawn_lector (const gchar *uri) | |||
| 113 | { | |||
| 114 | gchar *argv[3]; | |||
| 115 | gboolean retval; | |||
| 116 | GError *error = NULL((void*)0); | |||
| 117 | ||||
| 118 | /* TODO Check that the uri exists */ | |||
| 119 | argv[0] = g_build_filename (BINDIR"/usr/bin", "lector", NULL((void*)0)); | |||
| 120 | argv[1] = (gchar *) uri; | |||
| 121 | argv[2] = NULL((void*)0); | |||
| 122 | ||||
| 123 | retval = g_spawn_async (NULL((void*)0) /* wd */, argv, NULL((void*)0) /* env */, | |||
| 124 | 0, NULL((void*)0), NULL((void*)0), NULL((void*)0), &error); | |||
| 125 | if (!retval) { | |||
| 126 | g_printerr ("Error spawning lector for uri %s: %s\n", uri, error->message); | |||
| 127 | g_error_free (error); | |||
| 128 | } | |||
| 129 | g_free (argv[0]); | |||
| 130 | ||||
| 131 | return retval; | |||
| 132 | } | |||
| 133 | ||||
| 134 | static void | |||
| 135 | name_appeared_cb (GDBusConnection *connection, | |||
| 136 | const gchar *name, | |||
| 137 | const gchar *name_owner, | |||
| 138 | gpointer user_data) | |||
| 139 | { | |||
| 140 | LOGg_debug ("Watch name'%s' appeared with owner '%s'", name, name_owner); | |||
| 141 | } | |||
| 142 | ||||
| 143 | static void | |||
| 144 | name_vanished_cb (GDBusConnection *connection, | |||
| 145 | const gchar *name, | |||
| 146 | gpointer user_data) | |||
| 147 | { | |||
| 148 | EvDaemonApplication *application = EV_DAEMON_APPLICATION (user_data)((((EvDaemonApplication*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((user_data)), ((ev_daemon_application_get_type ())))))); | |||
| 149 | GList *l; | |||
| 150 | ||||
| 151 | LOGg_debug ("Watch name'%s' disappeared", name); | |||
| 152 | ||||
| 153 | for (l = application->docs; l != NULL((void*)0); l = l->next) { | |||
| 154 | EvDoc *doc = (EvDoc *) l->data; | |||
| 155 | ||||
| 156 | if (strcmp (doc->dbus_name, name) != 0) | |||
| 157 | continue; | |||
| 158 | ||||
| 159 | LOGg_debug ("Watch found URI '%s' for name; removing", doc->uri); | |||
| 160 | ||||
| 161 | application->docs = g_list_delete_link (application->docs, l); | |||
| 162 | ev_doc_free (doc); | |||
| 163 | ||||
| 164 | g_application_release (G_APPLICATION (application)((((GApplication*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((application)), ((g_application_get_type ()))))))); | |||
| 165 | ||||
| 166 | return; | |||
| 167 | } | |||
| 168 | } | |||
| 169 | ||||
| 170 | static void | |||
| 171 | process_pending_invocations (EvDaemonApplication *application, | |||
| 172 | const gchar *uri, | |||
| 173 | const gchar *dbus_name) | |||
| 174 | { | |||
| 175 | GList *l; | |||
| 176 | GList *uri_invocations; | |||
| 177 | ||||
| 178 | LOGg_debug ("RegisterDocument process pending invocations for URI %s", uri); | |||
| 179 | uri_invocations = g_hash_table_lookup (application->pending_invocations, uri); | |||
| 180 | ||||
| 181 | for (l = uri_invocations; l != NULL((void*)0); l = l->next) { | |||
| 182 | GDBusMethodInvocation *invocation; | |||
| 183 | ||||
| 184 | invocation = (GDBusMethodInvocation *)l->data; | |||
| 185 | g_dbus_method_invocation_return_value (invocation, | |||
| 186 | g_variant_new ("(s)", dbus_name)); | |||
| 187 | } | |||
| 188 | ||||
| 189 | g_list_free (uri_invocations); | |||
| 190 | g_hash_table_remove (application->pending_invocations, uri); | |||
| 191 | } | |||
| 192 | ||||
| 193 | static void | |||
| 194 | document_loaded_cb (GDBusConnection *connection, | |||
| 195 | const gchar *sender_name, | |||
| 196 | const gchar *object_path, | |||
| 197 | const gchar *interface_name, | |||
| 198 | const gchar *signal_name, | |||
| 199 | GVariant *parameters, | |||
| 200 | gpointer user_data) | |||
| 201 | { | |||
| 202 | EvDaemonApplication *application = EV_DAEMON_APPLICATION (user_data)((((EvDaemonApplication*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((user_data)), ((ev_daemon_application_get_type ())))))); | |||
| 203 | const gchar *uri; | |||
| 204 | EvDoc *doc; | |||
| 205 | ||||
| 206 | g_variant_get (parameters, "(&s)", &uri); | |||
| 207 | doc = ev_daemon_application_find_doc (application, uri); | |||
| ||||
| 208 | if (doc != NULL((void*)0) && strcmp (uri, doc->uri) == 0) { | |||
| 209 | process_pending_invocations (application, uri, sender_name); | |||
| 210 | } | |||
| 211 | ||||
| 212 | g_dbus_connection_signal_unsubscribe (connection, doc->loaded_id); | |||
| ||||
| 213 | doc->loaded_id = 0; | |||
| 214 | } | |||
| 215 | ||||
| 216 | static gboolean | |||
| 217 | handle_register_document_cb (EvDaemon *object, | |||
| 218 | GDBusMethodInvocation *invocation, | |||
| 219 | const gchar *uri, | |||
| 220 | EvDaemonApplication *application) | |||
| 221 | { | |||
| 222 | GDBusConnection *connection; | |||
| 223 | const char *sender; | |||
| 224 | EvDoc *doc; | |||
| 225 | ||||
| 226 | doc = ev_daemon_application_find_doc (application, uri); | |||
| 227 | if (doc != NULL((void*)0)) { | |||
| 228 | LOGg_debug ("RegisterDocument found owner '%s' for URI '%s'", doc->dbus_name, uri); | |||
| 229 | ev_daemon_complete_register_document (object, invocation, doc->dbus_name); | |||
| 230 | ||||
| 231 | return TRUE(!(0)); | |||
| 232 | } | |||
| 233 | ||||
| 234 | sender = g_dbus_method_invocation_get_sender (invocation); | |||
| 235 | connection = g_dbus_method_invocation_get_connection (invocation); | |||
| 236 | ||||
| 237 | LOGg_debug ("RegisterDocument registered owner '%s' for URI '%s'", sender, uri); | |||
| 238 | ||||
| 239 | doc = g_new (EvDoc, 1)((EvDoc *) g_malloc_n ((1), sizeof (EvDoc))); | |||
| 240 | doc->dbus_name = g_strdup (sender)g_strdup_inline (sender); | |||
| 241 | doc->uri = g_strdup (uri)g_strdup_inline (uri); | |||
| 242 | ||||
| 243 | application->docs = g_list_prepend (application->docs, doc); | |||
| 244 | ||||
| 245 | doc->loaded_id = g_dbus_connection_signal_subscribe (connection, | |||
| 246 | doc->dbus_name, | |||
| 247 | EV_DBUS_WINDOW_INTERFACE_NAME"org.cafe.lector.Window", | |||
| 248 | "DocumentLoaded", | |||
| 249 | NULL((void*)0), | |||
| 250 | NULL((void*)0), | |||
| 251 | 0, | |||
| 252 | document_loaded_cb, | |||
| 253 | application, NULL((void*)0)); | |||
| 254 | doc->watch_id = g_bus_watch_name_on_connection (connection, | |||
| 255 | sender, | |||
| 256 | G_BUS_NAME_WATCHER_FLAGS_NONE, | |||
| 257 | name_appeared_cb, | |||
| 258 | name_vanished_cb, | |||
| 259 | application, NULL((void*)0)); | |||
| 260 | ||||
| 261 | ev_daemon_complete_register_document (object, invocation, ""); | |||
| 262 | ||||
| 263 | g_application_hold (G_APPLICATION (application)((((GApplication*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((application)), ((g_application_get_type ()))))))); | |||
| 264 | ||||
| 265 | return TRUE(!(0)); | |||
| 266 | } | |||
| 267 | ||||
| 268 | static gboolean | |||
| 269 | handle_unregister_document_cb (EvDaemon *object, | |||
| 270 | GDBusMethodInvocation *invocation, | |||
| 271 | const gchar *uri, | |||
| 272 | EvDaemonApplication *application) | |||
| 273 | { | |||
| 274 | EvDoc *doc; | |||
| 275 | const char *sender; | |||
| 276 | ||||
| 277 | LOGg_debug ("UnregisterDocument URI '%s'", uri); | |||
| 278 | ||||
| 279 | doc = ev_daemon_application_find_doc (application, uri); | |||
| 280 | if (doc == NULL((void*)0)) { | |||
| 281 | LOGg_debug ("UnregisterDocument URI was not registered!"); | |||
| 282 | g_dbus_method_invocation_return_error_literal (invocation, | |||
| 283 | G_DBUS_ERRORg_dbus_error_quark(), | |||
| 284 | G_DBUS_ERROR_INVALID_ARGS, | |||
| 285 | "URI not registered"); | |||
| 286 | return TRUE(!(0)); | |||
| 287 | } | |||
| 288 | ||||
| 289 | sender = g_dbus_method_invocation_get_sender (invocation); | |||
| 290 | if (strcmp (doc->dbus_name, sender) != 0) { | |||
| 291 | LOGg_debug ("UnregisterDocument called by non-owner (owner '%s' sender '%s')", | |||
| 292 | doc->dbus_name, sender); | |||
| 293 | ||||
| 294 | g_dbus_method_invocation_return_error_literal (invocation, | |||
| 295 | G_DBUS_ERRORg_dbus_error_quark(), | |||
| 296 | G_DBUS_ERROR_BAD_ADDRESS, | |||
| 297 | "Only owner can call this method"); | |||
| 298 | return TRUE(!(0)); | |||
| 299 | } | |||
| 300 | ||||
| 301 | application->docs = g_list_remove (application->docs, doc); | |||
| 302 | ||||
| 303 | if (doc->loaded_id != 0) { | |||
| 304 | g_dbus_connection_signal_unsubscribe (g_dbus_method_invocation_get_connection (invocation), | |||
| 305 | doc->loaded_id); | |||
| 306 | doc->loaded_id = 0; | |||
| 307 | } | |||
| 308 | ||||
| 309 | ev_doc_free (doc); | |||
| 310 | ||||
| 311 | ev_daemon_complete_unregister_document (object, invocation); | |||
| 312 | ||||
| 313 | g_application_release (G_APPLICATION (application)((((GApplication*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((application)), ((g_application_get_type ()))))))); | |||
| 314 | ||||
| 315 | return TRUE(!(0)); | |||
| 316 | } | |||
| 317 | ||||
| 318 | static gboolean | |||
| 319 | handle_find_document_cb (EvDaemon *object, | |||
| 320 | GDBusMethodInvocation *invocation, | |||
| 321 | const gchar *uri, | |||
| 322 | gboolean spawn, | |||
| 323 | EvDaemonApplication *application) | |||
| 324 | { | |||
| 325 | EvDoc *doc; | |||
| 326 | ||||
| 327 | LOGg_debug ("FindDocument URI '%s'", uri); | |||
| 328 | ||||
| 329 | doc = ev_daemon_application_find_doc (application, uri); | |||
| 330 | if (doc != NULL((void*)0)) { | |||
| 331 | ev_daemon_complete_find_document (object, invocation, doc->dbus_name); | |||
| 332 | ||||
| 333 | return TRUE(!(0)); | |||
| 334 | } | |||
| 335 | ||||
| 336 | if (spawn) { | |||
| 337 | GList *uri_invocations; | |||
| 338 | gboolean ret_val = TRUE(!(0)); | |||
| 339 | ||||
| 340 | uri_invocations = g_hash_table_lookup (application->pending_invocations, uri); | |||
| 341 | ||||
| 342 | if (uri_invocations == NULL((void*)0)) { | |||
| 343 | /* Only spawn once. */ | |||
| 344 | ret_val = spawn_lector (uri); | |||
| 345 | } | |||
| 346 | ||||
| 347 | if (ret_val) { | |||
| 348 | /* Only defer DBUS answer if lector was succesfully spawned */ | |||
| 349 | uri_invocations = g_list_prepend (uri_invocations, invocation); | |||
| 350 | g_hash_table_insert (application->pending_invocations, | |||
| 351 | g_strdup (uri)g_strdup_inline (uri), | |||
| 352 | uri_invocations); | |||
| 353 | return TRUE(!(0)); | |||
| 354 | } | |||
| 355 | } | |||
| 356 | ||||
| 357 | LOGg_debug ("FindDocument URI '%s' was not registered!", uri); | |||
| 358 | // FIXME: shouldn't this return an error then? | |||
| 359 | ev_daemon_complete_find_document (object, invocation, ""); | |||
| 360 | ||||
| 361 | return TRUE(!(0)); | |||
| 362 | } | |||
| 363 | ||||
| 364 | /* ------------------------------------------------------------------------- */ | |||
| 365 | ||||
| 366 | static gboolean | |||
| 367 | ev_daemon_application_dbus_register (GApplication *gapplication, | |||
| 368 | GDBusConnection *connection, | |||
| 369 | const gchar *object_path, | |||
| 370 | GError **error) | |||
| 371 | { | |||
| 372 | EvDaemonApplication *application = EV_DAEMON_APPLICATION (gapplication)((((EvDaemonApplication*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((gapplication)), ((ev_daemon_application_get_type ())))))); | |||
| 373 | EvDaemon *skeleton; | |||
| 374 | ||||
| 375 | if (!G_APPLICATION_CLASS (ev_daemon_application_parent_class)((((GApplicationClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ev_daemon_application_parent_class)), ((g_application_get_type ()))))))->dbus_register (gapplication, | |||
| 376 | connection, | |||
| 377 | object_path, | |||
| 378 | error)) | |||
| 379 | return FALSE(0); | |||
| 380 | ||||
| 381 | skeleton = ev_daemon_skeleton_new (); | |||
| 382 | if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (skeleton)((((GDBusInterfaceSkeleton*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((skeleton)), ((g_dbus_interface_skeleton_get_type ())))))), | |||
| 383 | connection, | |||
| 384 | EV_DBUS_DAEMON_OBJECT_PATH"/org/cafe/lector/Daemon", | |||
| 385 | error)) { | |||
| 386 | g_object_unref (skeleton); | |||
| 387 | return FALSE(0); | |||
| 388 | } | |||
| 389 | ||||
| 390 | application->daemon = skeleton; | |||
| 391 | ||||
| 392 | g_signal_connect (skeleton, "handle-register-document",g_signal_connect_data ((skeleton), ("handle-register-document" ), (((GCallback) (handle_register_document_cb))), (application ), ((void*)0), (GConnectFlags) 0) | |||
| 393 | G_CALLBACK (handle_register_document_cb), application)g_signal_connect_data ((skeleton), ("handle-register-document" ), (((GCallback) (handle_register_document_cb))), (application ), ((void*)0), (GConnectFlags) 0); | |||
| 394 | g_signal_connect (skeleton, "handle-unregister-document",g_signal_connect_data ((skeleton), ("handle-unregister-document" ), (((GCallback) (handle_unregister_document_cb))), (application ), ((void*)0), (GConnectFlags) 0) | |||
| 395 | G_CALLBACK (handle_unregister_document_cb), application)g_signal_connect_data ((skeleton), ("handle-unregister-document" ), (((GCallback) (handle_unregister_document_cb))), (application ), ((void*)0), (GConnectFlags) 0); | |||
| 396 | g_signal_connect (skeleton, "handle-find-document",g_signal_connect_data ((skeleton), ("handle-find-document"), ( ((GCallback) (handle_find_document_cb))), (application), ((void *)0), (GConnectFlags) 0) | |||
| 397 | G_CALLBACK (handle_find_document_cb), application)g_signal_connect_data ((skeleton), ("handle-find-document"), ( ((GCallback) (handle_find_document_cb))), (application), ((void *)0), (GConnectFlags) 0); | |||
| 398 | return TRUE(!(0)); | |||
| 399 | } | |||
| 400 | ||||
| 401 | static void | |||
| 402 | ev_daemon_application_dbus_unregister (GApplication *gapplication, | |||
| 403 | GDBusConnection *connection, | |||
| 404 | const gchar *object_path) | |||
| 405 | { | |||
| 406 | EvDaemonApplication *application = EV_DAEMON_APPLICATION (gapplication)((((EvDaemonApplication*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((gapplication)), ((ev_daemon_application_get_type ())))))); | |||
| 407 | ||||
| 408 | if (application->daemon) { | |||
| 409 | g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (application->daemon)((((GDBusInterfaceSkeleton*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((application->daemon)), ((g_dbus_interface_skeleton_get_type ()))))))); | |||
| 410 | g_object_unref (application->daemon); | |||
| 411 | application->daemon = NULL((void*)0); | |||
| 412 | } | |||
| 413 | ||||
| 414 | G_APPLICATION_CLASS (ev_daemon_application_parent_class)((((GApplicationClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ev_daemon_application_parent_class)), ((g_application_get_type ()))))))->dbus_unregister (gapplication, | |||
| 415 | connection, | |||
| 416 | object_path); | |||
| 417 | } | |||
| 418 | ||||
| 419 | static void | |||
| 420 | ev_daemon_application_init (EvDaemonApplication *application) | |||
| 421 | { | |||
| 422 | application->pending_invocations = g_hash_table_new_full (g_str_hash, | |||
| 423 | g_str_equal, | |||
| 424 | (GDestroyNotify) g_free, | |||
| 425 | NULL((void*)0)); | |||
| 426 | } | |||
| 427 | ||||
| 428 | static void | |||
| 429 | ev_daemon_application_finalize (GObject *object) | |||
| 430 | { | |||
| 431 | EvDaemonApplication *application = EV_DAEMON_APPLICATION (object)((((EvDaemonApplication*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((object)), ((ev_daemon_application_get_type ())))))); | |||
| 432 | ||||
| 433 | g_warn_if_fail (g_hash_table_size (application->pending_invocations) == 0)do { if (g_hash_table_size (application->pending_invocations ) == 0) ; else g_warn_message ("LectorDaemon", "ev-daemon.c", 433, ((const char*) (__func__)), "g_hash_table_size (application->pending_invocations) == 0" ); } while (0); | |||
| 434 | g_hash_table_destroy (application->pending_invocations); | |||
| 435 | ||||
| 436 | g_list_free_full (application->docs, (GDestroyNotify) ev_doc_free); | |||
| 437 | ||||
| 438 | G_OBJECT_CLASS (ev_daemon_application_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ev_daemon_application_parent_class)), (((GType) ((20) << (2))))))))->finalize (object); | |||
| 439 | } | |||
| 440 | ||||
| 441 | static void | |||
| 442 | ev_daemon_application_class_init (EvDaemonApplicationClass *klass) | |||
| 443 | { | |||
| 444 | GObjectClass *object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((klass)), (((GType) ((20) << (2)))))))); | |||
| 445 | GApplicationClass *g_application_class = G_APPLICATION_CLASS (klass)((((GApplicationClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((klass)), ((g_application_get_type ())))))); | |||
| 446 | ||||
| 447 | object_class->finalize = ev_daemon_application_finalize; | |||
| 448 | ||||
| 449 | g_application_class->dbus_register = ev_daemon_application_dbus_register; | |||
| 450 | g_application_class->dbus_unregister = ev_daemon_application_dbus_unregister; | |||
| 451 | } | |||
| 452 | ||||
| 453 | /* ------------------------------------------------------------------------- */ | |||
| 454 | ||||
| 455 | gint | |||
| 456 | main (gint argc, gchar **argv) | |||
| 457 | { | |||
| 458 | GApplication *application; | |||
| 459 | const GApplicationFlags flags = G_APPLICATION_IS_SERVICE; | |||
| 460 | GError *error = NULL((void*)0); | |||
| 461 | int status; | |||
| 462 | ||||
| 463 | g_set_prgname ("lector-daemon"); | |||
| 464 | ||||
| 465 | application = g_object_new (EV_TYPE_DAEMON_APPLICATION(ev_daemon_application_get_type ()), | |||
| 466 | "application-id", EV_DBUS_DAEMON_NAME"org.cafe.lector.Daemon", | |||
| 467 | "flags", flags, | |||
| 468 | NULL((void*)0)); | |||
| 469 | g_application_set_inactivity_timeout (application, DAEMON_TIMEOUT(30)); | |||
| 470 | ||||
| 471 | if (!g_application_register (application, NULL((void*)0), &error)) { | |||
| 472 | g_printerr ("Failed to register: %s\n", error->message); | |||
| 473 | g_error_free (error); | |||
| 474 | g_object_unref (application); | |||
| 475 | ||||
| 476 | return 1; | |||
| 477 | } | |||
| 478 | ||||
| 479 | status = g_application_run (application, 0, NULL((void*)0)); | |||
| 480 | g_object_unref (application); | |||
| 481 | ||||
| 482 | return status; | |||
| 483 | } |