1/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/* vim:set expandtab ts=4 shiftwidth=4: */
3/* GIO - GLib Input, Output and Streaming Library
4 *
5 * Copyright (C) 2006-2007 Red Hat, Inc.
6 * Copyright (C) 2007 Sebastian Dröge.
7 * Copyright (C) 2008 Sun Microsystems, Inc. All rights reserved.
8 * Use is subject to license terms.
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
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General
21 * Public License along with this library; if not, write to the
22 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
23 * Boston, MA 02111-1307, USA.
24 *
25 * Authors: Alexander Larsson <alexl@redhat.com>
26 *          John McCutchan <john@johnmccutchan.com>
27 *          Sebastian Dröge <slomo@circular-chaos.org>
28 *          Lin Ma <lin.ma@sun.com>
29 */
30
31#include "config.h"
32
33#include "gfenfilemonitor.h"
34#include <gio/giomodule.h>
35
36#include "fen-helper.h"
37
38#include "gioalias.h"
39
40struct _GFenFileMonitor
41{
42    GLocalFileMonitor parent_instance;
43    fen_sub* sub;
44};
45
46static gboolean g_fen_file_monitor_cancel (GFileMonitor* monitor);
47
48#define g_fen_file_monitor_get_type _g_fen_file_monitor_get_type
49G_DEFINE_TYPE_WITH_CODE (GFenFileMonitor, g_fen_file_monitor, G_TYPE_LOCAL_FILE_MONITOR,
50  g_io_extension_point_implement (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME,
51    g_define_type_id,
52    "fen",
53    20))
54
55static void
56g_fen_file_monitor_finalize (GObject *object)
57{
58	GFenFileMonitor *self = G_FEN_FILE_MONITOR (object);
59
60    if (self->sub) {
61        fen_remove (G_LOCAL_FILE_MONITOR (self)->filename, self->sub, FALSE);
62        fen_sub_delete (self->sub);
63        self->sub = NULL;
64    }
65
66    if (G_OBJECT_CLASS (g_fen_file_monitor_parent_class)->finalize)
67        (*G_OBJECT_CLASS (g_fen_file_monitor_parent_class)->finalize) (object);
68}
69
70static GObject *
71g_fen_file_monitor_constructor (GType type,
72  guint n_construct_properties,
73  GObjectConstructParam *construct_properties)
74{
75    GObject *obj;
76    GFenFileMonitorClass *klass;
77    GObjectClass *parent_class;
78    GFenFileMonitor *self;
79    const gchar *filename = NULL;
80
81    klass = G_FEN_FILE_MONITOR_CLASS (g_type_class_peek (G_TYPE_FEN_FILE_MONITOR));
82    parent_class = g_fen_file_monitor_parent_class;
83    obj = parent_class->constructor (type,
84      n_construct_properties,
85      construct_properties);
86
87    self = G_FEN_FILE_MONITOR (obj);
88
89    filename = G_LOCAL_FILE_MONITOR (obj)->filename;
90
91    g_assert (filename != NULL);
92
93    /* Will never fail as is_supported() should be called before instanciating
94     * anyway */
95    if (!fen_init ())
96        g_assert_not_reached ();
97
98    /* FIXME: what to do about errors here? we can't return NULL or another
99     * kind of error and an assertion is probably too hard */
100    self->sub = fen_sub_new (self, FALSE);
101    g_assert (self->sub);
102
103    fen_add (filename, self->sub, FALSE);
104
105    return obj;
106}
107
108static gboolean
109g_fen_file_monitor_is_supported (void)
110{
111	return fen_init ();
112}
113
114static void
115g_fen_file_monitor_class_init (GFenFileMonitorClass* klass)
116{
117    GObjectClass* gobject_class = G_OBJECT_CLASS (klass);
118    GFileMonitorClass *file_monitor_class = G_FILE_MONITOR_CLASS (klass);
119    GLocalFileMonitorClass *local_file_monitor_class = G_LOCAL_FILE_MONITOR_CLASS (klass);
120
121    gobject_class->finalize = g_fen_file_monitor_finalize;
122    gobject_class->constructor = g_fen_file_monitor_constructor;
123    file_monitor_class->cancel = g_fen_file_monitor_cancel;
124
125    local_file_monitor_class->is_supported = g_fen_file_monitor_is_supported;
126}
127
128static void
129g_fen_file_monitor_init (GFenFileMonitor* monitor)
130{
131}
132
133static gboolean
134g_fen_file_monitor_cancel (GFileMonitor* monitor)
135{
136    GFenFileMonitor *self = G_FEN_FILE_MONITOR (monitor);
137
138    if (self->sub) {
139        fen_remove (G_LOCAL_FILE_MONITOR (self)->filename, self->sub, FALSE);
140        fen_sub_delete (self->sub);
141        self->sub = NULL;
142    }
143
144    if (G_FILE_MONITOR_CLASS (g_fen_file_monitor_parent_class)->cancel)
145        (*G_FILE_MONITOR_CLASS (g_fen_file_monitor_parent_class)->cancel) (monitor);
146
147    return TRUE;
148}
149
150