diff options
author | Alexander Larsson <alexl@redhat.com> | 2007-11-26 16:13:05 +0000 |
---|---|---|
committer | Alexander Larsson <alexl@src.gnome.org> | 2007-11-26 16:13:05 +0000 |
commit | 3781343738de4abddf56982325a77bd70a98cd26 (patch) | |
tree | 7edf4bfd446dc1465fdb8595641bf5307955940a /gio/gpollfilemonitor.c | |
parent | 8bdbcb92135c8831d045874d5913a13fe30c3af4 (diff) |
gio/ docs/reference/gio Merged gio-standalone into glib.
2007-11-26 Alexander Larsson <alexl@redhat.com>
* Makefile.am:
* configure.in:
* gio-2.0-uninstalled.pc.in:
* gio-2.0.pc.in:
* gio-unix-2.0-uninstalled.pc.in:
* gio-unix-2.0.pc.in:
* gio/
* docs/reference/gio
Merged gio-standalone into glib.
* glib/glibintl.h:
* glib/gutils.c:
Export glib_gettext so that gio can use it
Add P_ (using same domain for now)
Add I_ as g_intern_static_string
svn path=/trunk/; revision=5941
Diffstat (limited to 'gio/gpollfilemonitor.c')
-rw-r--r-- | gio/gpollfilemonitor.c | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/gio/gpollfilemonitor.c b/gio/gpollfilemonitor.c new file mode 100644 index 000000000..0b5a5e79d --- /dev/null +++ b/gio/gpollfilemonitor.c @@ -0,0 +1,226 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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. + * + * Author: Alexander Larsson <alexl@redhat.com> + */ + +#include <config.h> +#include <string.h> + +#include "gpollfilemonitor.h" +#include "gfilemonitor.h" + +static gboolean g_poll_file_monitor_cancel (GFileMonitor* monitor); +static void schedule_poll_timeout (GPollFileMonitor* poll_monitor); + +struct _GPollFileMonitor +{ + GFileMonitor parent_instance; + GFile *file; + GFileInfo *last_info; + guint timeout; +}; + +#define POLL_TIME_SECS 5 + +G_DEFINE_TYPE (GPollFileMonitor, g_poll_file_monitor, G_TYPE_FILE_MONITOR) + +static void +g_poll_file_monitor_finalize (GObject* object) +{ + GPollFileMonitor* poll_monitor; + + poll_monitor = G_POLL_FILE_MONITOR (object); + + g_object_unref (poll_monitor->file); + + if (G_OBJECT_CLASS (g_poll_file_monitor_parent_class)->finalize) + (*G_OBJECT_CLASS (g_poll_file_monitor_parent_class)->finalize) (object); +} + + +static void +g_poll_file_monitor_class_init (GPollFileMonitorClass* klass) +{ + GObjectClass* gobject_class = G_OBJECT_CLASS (klass); + GFileMonitorClass *file_monitor_class = G_FILE_MONITOR_CLASS (klass); + + gobject_class->finalize = g_poll_file_monitor_finalize; + + file_monitor_class->cancel = g_poll_file_monitor_cancel; +} + +static void +g_poll_file_monitor_init (GPollFileMonitor* poll_monitor) +{ +} + +static int +safe_strcmp (const char *a, const char *b) +{ + if (a == NULL && b == NULL) + return 0; + if (a == NULL) + return -1; + if (b == NULL) + return 1; + + return strcmp (a, b); +} + +static int +calc_event_type (GFileInfo *last, + GFileInfo *new) +{ + if (last == NULL && new == NULL) + return -1; + + if (last == NULL && new != NULL) + return G_FILE_MONITOR_EVENT_CREATED; + + if (last != NULL && new == NULL) + return G_FILE_MONITOR_EVENT_DELETED; + + if (safe_strcmp (g_file_info_get_etag (last), + g_file_info_get_etag (new))) + return G_FILE_MONITOR_EVENT_CHANGED; + + if (g_file_info_get_size (last) != + g_file_info_get_size (new)) + return G_FILE_MONITOR_EVENT_CHANGED; + + return -1; +} + +static void +got_new_info (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GPollFileMonitor* poll_monitor = user_data; + GFileInfo *info; + int event; + + info = g_file_query_info_finish (poll_monitor->file, res, NULL); + + if (!g_file_monitor_is_cancelled (G_FILE_MONITOR (poll_monitor))) + { + event = calc_event_type (poll_monitor->last_info, info); + + if (event != -1) + { + g_file_monitor_emit_event (G_FILE_MONITOR (poll_monitor), + poll_monitor->file, + NULL, event); + /* We're polling so slowly anyway, so always emit the done hint */ + if (event == G_FILE_MONITOR_EVENT_CHANGED) + g_file_monitor_emit_event (G_FILE_MONITOR (poll_monitor), + poll_monitor->file, + NULL, G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT); + } + + if (poll_monitor->last_info) + { + g_object_unref (poll_monitor->last_info); + poll_monitor->last_info = NULL; + } + + if (info) + poll_monitor->last_info = g_object_ref (info); + + schedule_poll_timeout (poll_monitor); + } + + if (info) + g_object_unref (info); + + g_object_unref (poll_monitor); +} + +static gboolean +poll_file_timeout (gpointer data) +{ + GPollFileMonitor* poll_monitor = data; + + poll_monitor->timeout = FALSE; + + g_file_query_info_async (poll_monitor->file, G_FILE_ATTRIBUTE_ETAG_VALUE "," G_FILE_ATTRIBUTE_STD_SIZE, + 0, 0, NULL, got_new_info, g_object_ref (poll_monitor)); + + return FALSE; +} + +static void +schedule_poll_timeout (GPollFileMonitor* poll_monitor) +{ + poll_monitor->timeout = g_timeout_add_seconds (POLL_TIME_SECS, poll_file_timeout, poll_monitor); + } + +static void +got_initial_info (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GPollFileMonitor* poll_monitor = user_data; + GFileInfo *info; + + info = g_file_query_info_finish (poll_monitor->file, res, NULL); + + poll_monitor->last_info = info; + + if (!g_file_monitor_is_cancelled (G_FILE_MONITOR (poll_monitor))) + schedule_poll_timeout (poll_monitor); + + g_object_unref (poll_monitor); +} + +/** + * g_poll_file_monitor_new: + * @file: + * + * Returns a new #GFileMonitor for the given #GFile. + **/ +GFileMonitor* +g_poll_file_monitor_new (GFile *file) +{ + GPollFileMonitor* poll_monitor; + + poll_monitor = g_object_new (G_TYPE_POLL_FILE_MONITOR, NULL); + + poll_monitor->file = g_object_ref (file); + + g_file_query_info_async (file, G_FILE_ATTRIBUTE_ETAG_VALUE "," G_FILE_ATTRIBUTE_STD_SIZE, + 0, 0, NULL, got_initial_info, g_object_ref (poll_monitor)); + + return G_FILE_MONITOR (poll_monitor); +} + +static gboolean +g_poll_file_monitor_cancel (GFileMonitor* monitor) +{ + GPollFileMonitor *poll_monitor = G_POLL_FILE_MONITOR (monitor); + + if (poll_monitor->timeout) + { + g_source_remove (poll_monitor->timeout); + poll_monitor->timeout = 0; + } + + return TRUE; +} |