1 /*
2  *      fm-file.c
3  *
4  *      Copyright 2012-2013 Andriy Grytsenko (LStranger) <andrej@rep.kiev.ua>
5  *
6  *      This file is a part of the Libfm library.
7  *
8  *      This library is free software; you can redistribute it and/or
9  *      modify it under the terms of the GNU Lesser General Public
10  *      License as published by the Free Software Foundation; either
11  *      version 2.1 of the License, or (at your option) any later version.
12  *
13  *      This library is distributed in the hope that it will be useful,
14  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *      Lesser General Public License for more details.
17  *
18  *      You should have received a copy of the GNU Lesser General Public
19  *      License along with this library; if not, write to the Free Software
20  *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22 
23 /**
24  * SECTION:fm-file
25  * @short_description: Extensions for GFile interface.
26  * @title: FmFile
27  *
28  * @include: libfm/fm.h
29  *
30  * The #FmFile represents interface to build extensions to GFile which
31  * will handle schemas that are absent in Glib/GVFS - such as "search:".
32  *
33  * To use it the GFile implementation should also implement FmFile vtable
34  * calls. The implementation should be added to list of known schemes via
35  * call to fm_file_add_vfs() then calls such as fm_file_new_for_uri() can
36  * use it.
37  */
38 
39 #ifdef HAVE_CONFIG_H
40 #include <config.h>
41 #endif
42 #include "glib-compat.h"
43 #define CHECK_MODULES() // this is not needed for libfm-qt
44 
45 #include "fm-file.h"
46 
47 #include <string.h>
48 
49 static GHashTable *schemes = NULL;
50 
51 #define FM_FILE_MODULE_MIN_VERSION 1
52 #define FM_FILE_MODULE_MAX_VERSION 1
53 
54 G_LOCK_DEFINE_STATIC(vfs);
55 
G_DEFINE_INTERFACE(FmFile,fm_file,G_TYPE_FILE)56 G_DEFINE_INTERFACE(FmFile, fm_file, G_TYPE_FILE)
57 
58 static gboolean fm_file_wants_incremental_false(GFile *unused)
59 {
60     return FALSE;
61 }
62 
fm_file_default_init(FmFileInterface * iface)63 static void fm_file_default_init(FmFileInterface *iface)
64 {
65     iface->wants_incremental = fm_file_wants_incremental_false;
66 }
67 
68 
fm_find_scheme(const char * name)69 static inline FmFileInitTable *fm_find_scheme(const char *name)
70 {
71     FmFileInitTable *t;
72     CHECK_MODULES();
73     G_LOCK(vfs);
74     t = (FmFileInitTable*)g_hash_table_lookup(schemes, name);
75     G_UNLOCK(vfs);
76     return t;
77 }
78 
79 /**
80  * fm_file_add_vfs
81  * @name: scheme to act upon
82  * @init: table of functions
83  *
84  * Adds VFS to list of extensions that will be applied on next call to
85  * fm_file_new_for_uri() or fm_file_new_for_commandline_arg(). The @name
86  * is a schema which will be handled by those calls.
87  *
88  * Since: 1.0.2
89  */
fm_file_add_vfs(const char * name,FmFileInitTable * init)90 void fm_file_add_vfs(const char *name, FmFileInitTable *init)
91 {
92     G_LOCK(vfs);
93     if(g_hash_table_lookup(schemes, name) == NULL)
94         g_hash_table_insert(schemes, g_strdup(name), init);
95     G_UNLOCK(vfs);
96 }
97 
98 /**
99  * fm_file_wants_incremental
100  * @file: file to inspect
101  *
102  * Checks if contents of directory @file cannot be retrieved at once so
103  * scanning it may be done in incremental manner for the best results.
104  *
105  * Returns: %TRUE if retrieve of contents of @file will be incremental.
106  *
107  * Since: 1.0.2
108  */
fm_file_wants_incremental(GFile * file)109 gboolean fm_file_wants_incremental(GFile* file)
110 {
111     FmFileInterface *iface;
112 
113     g_return_val_if_fail(file != NULL, FALSE);
114     if(!FM_IS_FILE(file))
115         return FALSE;
116     iface = FM_FILE_GET_IFACE(file);
117     return iface->wants_incremental ? iface->wants_incremental(file) : FALSE;
118 }
119