ftp://ftp.redhat.com/pub/redhat/linux/rawhide/SRPMS/SRPMS/gnome-vfs2-2.3.8-1.src.rpm
[gnome-vfs-httpcaptive.git] / libgnomevfs / gnome-vfs-mime-monitor.c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
2
3    gnome-vfs-mime-monitor.c: Class for noticing changes in MIME data.
4  
5    Copyright (C) 2000 Eazel, Inc.
6   
7    This program is free software; you can redistribute it and/or
8    modify it under the terms of the GNU General Public License as
9    published by the Free Software Foundation; either version 2 of the
10    License, or (at your option) any later version.
11   
12    This program is distributed in the hope that it will be useful,
13    but 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
18    License along with this program; if not, write to the
19    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.
21   
22    Authors: John Sullivan <sullivan@eazel.com>,
23 */
24
25 #include <config.h>
26 #include "gnome-vfs-mime-monitor.h"
27 #include "gnome-vfs-mime-private.h"
28 #include "gnome-vfs-ops.h"
29
30 enum {
31         DATA_CHANGED,
32         LAST_SIGNAL
33 };
34
35 enum {
36         LOCAL_MIME_DIR,
37         GNOME_MIME_DIR,
38 };
39
40 static guint signals[LAST_SIGNAL];
41
42 static GnomeVFSMIMEMonitor *global_mime_monitor = NULL;
43
44 typedef struct _MonitorCallbackData
45 {
46         GnomeVFSMIMEMonitor *monitor;
47         gint type;
48 } MonitorCallbackData;
49
50 struct _GnomeVFSMIMEMonitorPrivate
51 {
52         GnomeVFSMonitorHandle *global_handle;
53         GnomeVFSMonitorHandle *local_handle;
54
55         /* The hoops I jump through */
56         MonitorCallbackData *gnome_callback_data;
57         MonitorCallbackData *local_callback_data;
58 };
59
60
61 static void                   gnome_vfs_mime_monitor_class_init              (GnomeVFSMIMEMonitorClass *klass);
62 static void                   gnome_vfs_mime_monitor_init                    (GnomeVFSMIMEMonitor      *monitor);
63 static void                   mime_dir_changed_callback                      (GnomeVFSMonitorHandle    *handle,
64                                                                               const gchar              *monitor_uri,
65                                                                               const gchar              *info_uri,
66                                                                               GnomeVFSMonitorEventType  event_type,
67                                                                               gpointer                  user_data);
68 static void                   gnome_vfs_mime_monitor_finalize                (GObject                  *object);
69
70
71
72 static void
73 gnome_vfs_mime_monitor_class_init (GnomeVFSMIMEMonitorClass *klass)
74 {
75         GObjectClass *object_class = G_OBJECT_CLASS (klass);
76
77         object_class->finalize = gnome_vfs_mime_monitor_finalize;
78
79         signals [DATA_CHANGED] = 
80                 g_signal_new ("data_changed",
81                               G_TYPE_FROM_CLASS (klass),
82                               G_SIGNAL_RUN_LAST,
83                               G_STRUCT_OFFSET (GnomeVFSMIMEMonitorClass, data_changed),
84                               NULL, NULL,
85                               g_cclosure_marshal_VOID__VOID,
86                               G_TYPE_NONE, 0);
87 }
88
89 static void
90 gnome_vfs_mime_monitor_init (GnomeVFSMIMEMonitor *monitor)
91 {
92         gchar *mime_dir;
93
94         monitor->priv = g_new (GnomeVFSMIMEMonitorPrivate, 1);
95
96         monitor->priv->gnome_callback_data = g_new (MonitorCallbackData, 1);
97         monitor->priv->local_callback_data = g_new (MonitorCallbackData, 1);
98
99         /* FIXME: Bug #80268.  These wouldn't be private members if we had a
100          * _full variant.  However, if I want to clean them up, I need to keep
101          * them around. */
102         monitor->priv->gnome_callback_data->type = GNOME_MIME_DIR;
103         monitor->priv->gnome_callback_data->monitor = monitor;
104         monitor->priv->local_callback_data->type = LOCAL_MIME_DIR;
105         monitor->priv->local_callback_data->monitor = monitor;
106
107         mime_dir = g_strdup (DATADIR "/mime-info");
108         gnome_vfs_monitor_add (&monitor->priv->global_handle,
109                                mime_dir,
110                                GNOME_VFS_MONITOR_DIRECTORY,
111                                mime_dir_changed_callback,
112                                monitor->priv->gnome_callback_data);
113         g_free (mime_dir);
114
115         mime_dir = g_strconcat (g_get_home_dir (), "/.gnome/mime-info", NULL);
116         if (!g_file_test (mime_dir, G_FILE_TEST_EXISTS)) {
117                 mkdir (mime_dir, S_IRWXU);
118         }
119         gnome_vfs_monitor_add (&monitor->priv->local_handle,
120                                mime_dir,
121                                GNOME_VFS_MONITOR_DIRECTORY,
122                                mime_dir_changed_callback,
123                                monitor->priv->local_callback_data);
124         g_free (mime_dir);
125 }
126
127
128 static void
129 mime_dir_changed_callback (GnomeVFSMonitorHandle    *handle,
130                            const gchar              *monitor_uri,
131                            const gchar              *info_uri,
132                            GnomeVFSMonitorEventType  event_type,
133                            gpointer                  user_data)
134 {
135         MonitorCallbackData *monitor_callback_data = (MonitorCallbackData *)user_data;
136
137         if (monitor_callback_data->type == GNOME_MIME_DIR)
138                 _gnome_vfs_mime_info_mark_gnome_mime_dir_dirty ();
139         else if (monitor_callback_data->type == LOCAL_MIME_DIR)
140                 _gnome_vfs_mime_info_mark_user_mime_dir_dirty ();
141                 
142         _gnome_vfs_mime_monitor_emit_data_changed (monitor_callback_data->monitor);
143 }
144
145 static void
146 gnome_vfs_mime_monitor_finalize (GObject *object)
147 {
148         gnome_vfs_monitor_cancel (GNOME_VFS_MIME_MONITOR (object)->priv->global_handle);
149         gnome_vfs_monitor_cancel (GNOME_VFS_MIME_MONITOR (object)->priv->local_handle);
150         g_free (GNOME_VFS_MIME_MONITOR (object)->priv->gnome_callback_data);
151         g_free (GNOME_VFS_MIME_MONITOR (object)->priv->local_callback_data);
152         g_free (GNOME_VFS_MIME_MONITOR (object)->priv);
153 }
154
155 /**
156  * gnome_vfs_mime_monitor_get:
157  *
158  * Get access to the single global monitor. 
159  *
160  * Return value: the global #GnomeVFSMIMEMonitor
161  **/
162 GnomeVFSMIMEMonitor *
163 gnome_vfs_mime_monitor_get (void)
164 {
165         if (global_mime_monitor == NULL) {
166                 global_mime_monitor = GNOME_VFS_MIME_MONITOR
167                         (g_object_new (gnome_vfs_mime_monitor_get_type (), NULL));
168         }
169         return global_mime_monitor;
170 }
171
172
173 void
174 _gnome_vfs_mime_monitor_emit_data_changed (GnomeVFSMIMEMonitor *monitor)
175 {
176         g_return_if_fail (GNOME_VFS_IS_MIME_MONITOR (monitor));
177
178         g_signal_emit (G_OBJECT (monitor),
179                        signals [DATA_CHANGED], 0);
180 }
181
182 GType
183 gnome_vfs_mime_monitor_get_type (void)
184 {
185         static GType type = 0;
186
187         if (type == 0) {
188                 GTypeInfo info = {
189                         sizeof (GnomeVFSMIMEMonitorClass),
190                         (GBaseInitFunc) NULL,
191                         (GBaseFinalizeFunc) NULL,
192                         (GClassInitFunc) gnome_vfs_mime_monitor_class_init,
193                         NULL, /* class_finalize */
194                         NULL, /* class_data */
195                         sizeof (GnomeVFSMIMEMonitor),
196                         0, /* n_preallocs */
197                         (GInstanceInitFunc) gnome_vfs_mime_monitor_init
198                 };
199                 
200                 type = g_type_register_static (
201                         G_TYPE_OBJECT, "GnomeVFSMIMEMonitor", &info, 0);
202         }
203
204         return type;
205 }