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 "gfendirectorymonitor.h"
34 #include "giomodule.h"
35
36 #include "fen-helper.h"
37
38 #include "gioalias.h"
39
40 struct _GFenDirectoryMonitor
41 {
42 GLocalDirectoryMonitor parent_instance;
43 gboolean cancelled;
44 fen_sub* sub;
45 };
46
47 static gboolean g_fen_directory_monitor_cancel (GFileMonitor* monitor);
48
49 #define g_fen_directory_monitor_get_type _g_fen_directory_monitor_get_type
50 G_DEFINE_TYPE_WITH_CODE (GFenDirectoryMonitor, g_fen_directory_monitor, G_TYPE_LOCAL_DIRECTORY_MONITOR,
51 g_io_extension_point_implement (G_LOCAL_DIRECTORY_MONITOR_EXTENSION_POINT_NAME,
52 g_define_type_id,
53 "fen",
54 20))
55
56 static void
g_fen_directory_monitor_finalize(GObject * object)57 g_fen_directory_monitor_finalize (GObject *object)
58 {
59 GFenDirectoryMonitor *self = G_FEN_DIRECTORY_MONITOR (object);
60
61 if (self->sub) {
62 fen_remove (G_LOCAL_DIRECTORY_MONITOR (self)->dirname, self->sub, TRUE);
63 fen_sub_delete (self->sub);
64 self->sub = NULL;
65 }
66
67 if (G_OBJECT_CLASS (g_fen_directory_monitor_parent_class)->finalize)
68 (*G_OBJECT_CLASS (g_fen_directory_monitor_parent_class)->finalize) (object);
69 }
70
71 static GObject *
g_fen_directory_monitor_constructor(GType type,guint n_construct_properties,GObjectConstructParam * construct_properties)72 g_fen_directory_monitor_constructor (GType type,
73 guint n_construct_properties,
74 GObjectConstructParam *construct_properties)
75 {
76 GObject *obj;
77 GFenDirectoryMonitorClass *klass;
78 GObjectClass *parent_class;
79 GFenDirectoryMonitor *self;
80 const gchar *dirname = NULL;
81
82 klass = G_FEN_DIRECTORY_MONITOR_CLASS (g_type_class_peek (G_TYPE_FEN_DIRECTORY_MONITOR));
83 parent_class = g_fen_directory_monitor_parent_class;
84 obj = parent_class->constructor (type,
85 n_construct_properties,
86 construct_properties);
87
88 self = G_FEN_DIRECTORY_MONITOR (obj);
89
90 dirname = G_LOCAL_DIRECTORY_MONITOR (self)->dirname;
91 g_assert (dirname != 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, TRUE);
101 g_assert (self->sub);
102
103 fen_add (dirname, self->sub, TRUE);
104
105 return obj;
106 }
107
108 static gboolean
g_fen_directory_monitor_is_supported(void)109 g_fen_directory_monitor_is_supported (void)
110 {
111 return fen_init ();
112 }
113
114 static void
g_fen_directory_monitor_class_init(GFenDirectoryMonitorClass * klass)115 g_fen_directory_monitor_class_init (GFenDirectoryMonitorClass* klass)
116 {
117 GObjectClass* gobject_class = G_OBJECT_CLASS (klass);
118 GFileMonitorClass *directory_monitor_class = G_FILE_MONITOR_CLASS (klass);
119 GLocalDirectoryMonitorClass *local_directory_monitor_class = G_LOCAL_DIRECTORY_MONITOR_CLASS (klass);
120
121 gobject_class->finalize = g_fen_directory_monitor_finalize;
122 gobject_class->constructor = g_fen_directory_monitor_constructor;
123 directory_monitor_class->cancel = g_fen_directory_monitor_cancel;
124
125 local_directory_monitor_class->mount_notify = TRUE;
126 local_directory_monitor_class->is_supported = g_fen_directory_monitor_is_supported;
127 }
128
129 static void
g_fen_directory_monitor_init(GFenDirectoryMonitor * monitor)130 g_fen_directory_monitor_init (GFenDirectoryMonitor* monitor)
131 {
132 }
133
134 static gboolean
g_fen_directory_monitor_cancel(GFileMonitor * monitor)135 g_fen_directory_monitor_cancel (GFileMonitor* monitor)
136 {
137 GFenDirectoryMonitor *self = G_FEN_DIRECTORY_MONITOR (monitor);
138
139 if (self->sub) {
140 fen_remove (G_LOCAL_DIRECTORY_MONITOR (self)->dirname, self->sub, TRUE);
141 fen_sub_delete (self->sub);
142 self->sub = NULL;
143 }
144
145 if (G_FILE_MONITOR_CLASS (g_fen_directory_monitor_parent_class)->cancel)
146 (*G_FILE_MONITOR_CLASS (g_fen_directory_monitor_parent_class)->cancel) (monitor);
147
148 return TRUE;
149 }
150
151