| File: | ctk/ctkfilesystem.c |
| Warning: | line 624, column 12 Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* CTK - The GIMP Toolkit |
| 2 | * ctkfilesystem.c: Filesystem abstraction functions. |
| 3 | * Copyright (C) 2003, Red Hat, Inc. |
| 4 | * Copyright (C) 2007-2008 Carlos Garnacho |
| 5 | * |
| 6 | * This library is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU Lesser General Public License as |
| 8 | * published by the Free Software Foundation; either version 2 of the |
| 9 | * License, or (at your option) any later version. |
| 10 | * |
| 11 | * This library is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | * GNU Lesser General Public License for more details. |
| 15 | * |
| 16 | * You should have received a copy of the GNU Lesser General Public |
| 17 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
| 18 | * |
| 19 | * Authors: Carlos Garnacho <carlos@imendio.com> |
| 20 | */ |
| 21 | |
| 22 | #include "config.h" |
| 23 | |
| 24 | #include "ctkfilesystem.h" |
| 25 | |
| 26 | #include <string.h> |
| 27 | #include <glib/gi18n-lib.h> |
| 28 | |
| 29 | #include "ctkfilechooser.h" |
| 30 | #include "ctkcssiconthemevalueprivate.h" |
| 31 | #include "ctkintl.h" |
| 32 | #include "ctkprivate.h" |
| 33 | #include "ctkstylecontextprivate.h" |
| 34 | |
| 35 | /* #define DEBUG_MODE */ |
| 36 | #ifdef DEBUG_MODE |
| 37 | #define DEBUG(x) g_debug (x); |
| 38 | #else |
| 39 | #define DEBUG(x) |
| 40 | #endif |
| 41 | |
| 42 | #define FILES_PER_QUERY100 100 |
| 43 | |
| 44 | /* The pointers we return for a CtkFileSystemVolume are opaque tokens; they are |
| 45 | * really pointers to GDrive, GVolume or GMount objects. We need an extra |
| 46 | * token for the fake “File System” volume. So, we’ll return a pointer to |
| 47 | * this particular string. |
| 48 | */ |
| 49 | static const gchar *root_volume_token = N_("File System")("File System"); |
| 50 | #define IS_ROOT_VOLUME(volume)((gpointer) (volume) == (gpointer) root_volume_token) ((gpointer) (volume) == (gpointer) root_volume_token) |
| 51 | |
| 52 | enum { |
| 53 | PROP_0, |
| 54 | PROP_FILE, |
| 55 | PROP_ENUMERATOR, |
| 56 | PROP_ATTRIBUTES |
| 57 | }; |
| 58 | |
| 59 | enum { |
| 60 | VOLUMES_CHANGED, |
| 61 | FS_LAST_SIGNAL |
| 62 | }; |
| 63 | |
| 64 | enum { |
| 65 | FILES_ADDED, |
| 66 | FILES_REMOVED, |
| 67 | FILES_CHANGED, |
| 68 | FINISHED_LOADING, |
| 69 | DELETED, |
| 70 | FOLDER_LAST_SIGNAL |
| 71 | }; |
| 72 | |
| 73 | static guint fs_signals [FS_LAST_SIGNAL] = { 0, }; |
| 74 | |
| 75 | typedef struct AsyncFuncData AsyncFuncData; |
| 76 | |
| 77 | struct CtkFileSystemPrivate |
| 78 | { |
| 79 | GVolumeMonitor *volume_monitor; |
| 80 | |
| 81 | /* This list contains elements that can be |
| 82 | * of type GDrive, GVolume and GMount |
| 83 | */ |
| 84 | GSList *volumes; |
| 85 | }; |
| 86 | |
| 87 | struct AsyncFuncData |
| 88 | { |
| 89 | CtkFileSystem *file_system; |
| 90 | GFile *file; |
| 91 | GCancellable *cancellable; |
| 92 | |
| 93 | gpointer callback; |
| 94 | gpointer data; |
| 95 | }; |
| 96 | |
| 97 | G_DEFINE_TYPE_WITH_PRIVATE (CtkFileSystem, _ctk_file_system, G_TYPE_OBJECT)static void _ctk_file_system_init (CtkFileSystem *self); static void _ctk_file_system_class_init (CtkFileSystemClass *klass) ; static GType _ctk_file_system_get_type_once (void); static gpointer _ctk_file_system_parent_class = ((void*)0); static gint CtkFileSystem_private_offset ; static void _ctk_file_system_class_intern_init (gpointer klass ) { _ctk_file_system_parent_class = g_type_class_peek_parent ( klass); if (CtkFileSystem_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkFileSystem_private_offset); _ctk_file_system_class_init ((CtkFileSystemClass*) klass); } __attribute__ ((__unused__) ) static inline gpointer _ctk_file_system_get_instance_private (CtkFileSystem *self) { return (((gpointer) ((guint8*) (self ) + (glong) (CtkFileSystem_private_offset)))); } GType _ctk_file_system_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = _ctk_file_system_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType _ctk_file_system_get_type_once ( void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CtkFileSystem" ), sizeof (CtkFileSystemClass), (GClassInitFunc)(void (*)(void )) _ctk_file_system_class_intern_init, sizeof (CtkFileSystem) , (GInstanceInitFunc)(void (*)(void)) _ctk_file_system_init, ( GTypeFlags) 0); { {{ CtkFileSystem_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkFileSystemPrivate)); };} } return g_define_type_id; } |
| 98 | |
| 99 | |
| 100 | /* CtkFileSystem methods */ |
| 101 | static void |
| 102 | volumes_changed (GVolumeMonitor *volume_monitor G_GNUC_UNUSED__attribute__ ((__unused__)), |
| 103 | gpointer volume, |
| 104 | gpointer user_data) |
| 105 | { |
| 106 | CtkFileSystem *file_system; |
| 107 | |
| 108 | cdk_threads_enter (); |
| 109 | |
| 110 | file_system = CTK_FILE_SYSTEM (user_data)((((CtkFileSystem*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((user_data)), ((_ctk_file_system_get_type ())))))); |
| 111 | g_signal_emit (file_system, fs_signals[VOLUMES_CHANGED], 0, volume); |
| 112 | cdk_threads_leave (); |
| 113 | } |
| 114 | |
| 115 | static void |
| 116 | ctk_file_system_dispose (GObject *object) |
| 117 | { |
| 118 | CtkFileSystem *file_system = CTK_FILE_SYSTEM (object)((((CtkFileSystem*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((_ctk_file_system_get_type ())))))); |
| 119 | CtkFileSystemPrivate *priv = file_system->priv; |
| 120 | |
| 121 | DEBUG ("dispose"); |
| 122 | |
| 123 | if (priv->volumes) |
| 124 | { |
| 125 | g_slist_free_full (priv->volumes, g_object_unref); |
| 126 | priv->volumes = NULL((void*)0); |
| 127 | } |
| 128 | |
| 129 | if (priv->volume_monitor) |
| 130 | { |
| 131 | g_signal_handlers_disconnect_by_func (priv->volume_monitor, volumes_changed, object)g_signal_handlers_disconnect_matched ((priv->volume_monitor ), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (volumes_changed), (object)); |
| 132 | g_object_unref (priv->volume_monitor); |
| 133 | priv->volume_monitor = NULL((void*)0); |
| 134 | } |
| 135 | |
| 136 | G_OBJECT_CLASS (_ctk_file_system_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((_ctk_file_system_parent_class)), (((GType) ((20) << (2))))))))->dispose (object); |
| 137 | } |
| 138 | |
| 139 | static void |
| 140 | _ctk_file_system_class_init (CtkFileSystemClass *class) |
| 141 | { |
| 142 | GObjectClass *object_class = G_OBJECT_CLASS (class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((class)), (((GType) ((20) << (2)))))))); |
| 143 | |
| 144 | object_class->dispose = ctk_file_system_dispose; |
| 145 | |
| 146 | fs_signals[VOLUMES_CHANGED] = |
| 147 | g_signal_new (I_("volumes-changed")g_intern_static_string ("volumes-changed"), |
| 148 | G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type), |
| 149 | G_SIGNAL_RUN_LAST, |
| 150 | G_STRUCT_OFFSET (CtkFileSystemClass, volumes_changed)((glong) __builtin_offsetof(CtkFileSystemClass, volumes_changed )), |
| 151 | NULL((void*)0), NULL((void*)0), |
| 152 | NULL((void*)0), |
| 153 | G_TYPE_NONE((GType) ((1) << (2))), 0); |
| 154 | } |
| 155 | |
| 156 | static gboolean |
| 157 | mount_referenced_by_volume_activation_root (GList *volumes, GMount *mount) |
| 158 | { |
| 159 | GList *l; |
| 160 | GFile *mount_root; |
| 161 | gboolean ret; |
| 162 | |
| 163 | ret = FALSE(0); |
| 164 | |
| 165 | mount_root = g_mount_get_root (mount); |
| 166 | |
| 167 | for (l = volumes; l != NULL((void*)0); l = l->next) |
| 168 | { |
| 169 | GVolume *volume = G_VOLUME (l->data)((((GVolume*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((l->data)), ((g_volume_get_type ())))))); |
| 170 | GFile *volume_activation_root; |
| 171 | |
| 172 | volume_activation_root = g_volume_get_activation_root (volume); |
| 173 | if (volume_activation_root != NULL((void*)0)) |
| 174 | { |
| 175 | if (g_file_has_prefix (volume_activation_root, mount_root)) |
| 176 | { |
| 177 | ret = TRUE(!(0)); |
| 178 | g_object_unref (volume_activation_root); |
| 179 | break; |
| 180 | } |
| 181 | g_object_unref (volume_activation_root); |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | g_object_unref (mount_root); |
| 186 | return ret; |
| 187 | } |
| 188 | |
| 189 | static void |
| 190 | get_volumes_list (CtkFileSystem *file_system) |
| 191 | { |
| 192 | CtkFileSystemPrivate *priv = file_system->priv; |
| 193 | GList *l, *ll; |
| 194 | GList *drives; |
| 195 | GList *volumes; |
| 196 | GList *mounts; |
| 197 | GDrive *drive; |
| 198 | GVolume *volume; |
| 199 | GMount *mount; |
| 200 | |
| 201 | if (priv->volumes) |
| 202 | { |
| 203 | g_slist_free_full (priv->volumes, g_object_unref); |
| 204 | priv->volumes = NULL((void*)0); |
| 205 | } |
| 206 | |
| 207 | /* first go through all connected drives */ |
| 208 | drives = g_volume_monitor_get_connected_drives (priv->volume_monitor); |
| 209 | |
| 210 | for (l = drives; l != NULL((void*)0); l = l->next) |
| 211 | { |
| 212 | drive = l->data; |
| 213 | volumes = g_drive_get_volumes (drive); |
| 214 | |
| 215 | if (volumes) |
| 216 | { |
| 217 | for (ll = volumes; ll != NULL((void*)0); ll = ll->next) |
| 218 | { |
| 219 | volume = ll->data; |
| 220 | mount = g_volume_get_mount (volume); |
| 221 | |
| 222 | if (mount) |
| 223 | { |
| 224 | /* Show mounted volume */ |
| 225 | priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (mount)((__typeof__ (mount)) (g_object_ref) (mount))); |
| 226 | g_object_unref (mount); |
| 227 | } |
| 228 | else |
| 229 | { |
| 230 | /* Do show the unmounted volumes in the sidebar; |
| 231 | * this is so the user can mount it (in case automounting |
| 232 | * is off). |
| 233 | * |
| 234 | * Also, even if automounting is enabled, this gives a visual |
| 235 | * cue that the user should remember to yank out the media if |
| 236 | * he just unmounted it. |
| 237 | */ |
| 238 | priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (volume)((__typeof__ (volume)) (g_object_ref) (volume))); |
| 239 | } |
| 240 | |
| 241 | g_object_unref (volume); |
| 242 | } |
| 243 | |
| 244 | g_list_free (volumes); |
| 245 | } |
| 246 | else if (g_drive_is_media_removable (drive) && !g_drive_is_media_check_automatic (drive)) |
| 247 | { |
| 248 | /* If the drive has no mountable volumes and we cannot detect media change.. we |
| 249 | * display the drive in the sidebar so the user can manually poll the drive by |
| 250 | * right clicking and selecting "Rescan..." |
| 251 | * |
| 252 | * This is mainly for drives like floppies where media detection doesn't |
| 253 | * work.. but it's also for human beings who like to turn off media detection |
| 254 | * in the OS to save battery juice. |
| 255 | */ |
| 256 | |
| 257 | priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (drive)((__typeof__ (drive)) (g_object_ref) (drive))); |
| 258 | } |
| 259 | |
| 260 | g_object_unref (drive); |
| 261 | } |
| 262 | |
| 263 | g_list_free (drives); |
| 264 | |
| 265 | /* add all volumes that is not associated with a drive */ |
| 266 | volumes = g_volume_monitor_get_volumes (priv->volume_monitor); |
| 267 | |
| 268 | for (l = volumes; l != NULL((void*)0); l = l->next) |
| 269 | { |
| 270 | volume = l->data; |
| 271 | drive = g_volume_get_drive (volume); |
| 272 | |
| 273 | if (drive) |
| 274 | { |
| 275 | g_object_unref (drive); |
| 276 | continue; |
| 277 | } |
| 278 | |
| 279 | mount = g_volume_get_mount (volume); |
| 280 | |
| 281 | if (mount) |
| 282 | { |
| 283 | /* show this mount */ |
| 284 | priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (mount)((__typeof__ (mount)) (g_object_ref) (mount))); |
| 285 | g_object_unref (mount); |
| 286 | } |
| 287 | else |
| 288 | { |
| 289 | /* see comment above in why we add an icon for a volume */ |
| 290 | priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (volume)((__typeof__ (volume)) (g_object_ref) (volume))); |
| 291 | } |
| 292 | |
| 293 | g_object_unref (volume); |
| 294 | } |
| 295 | |
| 296 | /* add mounts that has no volume (/etc/mtab mounts, ftp, sftp,...) */ |
| 297 | mounts = g_volume_monitor_get_mounts (priv->volume_monitor); |
| 298 | |
| 299 | for (l = mounts; l != NULL((void*)0); l = l->next) |
| 300 | { |
| 301 | mount = l->data; |
| 302 | volume = g_mount_get_volume (mount); |
| 303 | |
| 304 | if (volume) |
| 305 | { |
| 306 | g_object_unref (volume); |
| 307 | continue; |
| 308 | } |
| 309 | |
| 310 | /* if there's exists one or more volumes with an activation root inside the mount, |
| 311 | * don't display the mount |
| 312 | */ |
| 313 | if (mount_referenced_by_volume_activation_root (volumes, mount)) |
| 314 | { |
| 315 | g_object_unref (mount); |
| 316 | continue; |
| 317 | } |
| 318 | |
| 319 | /* show this mount */ |
| 320 | priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (mount)((__typeof__ (mount)) (g_object_ref) (mount))); |
| 321 | g_object_unref (mount); |
| 322 | } |
| 323 | |
| 324 | g_list_free (volumes); |
| 325 | |
| 326 | g_list_free (mounts); |
| 327 | } |
| 328 | |
| 329 | static void |
| 330 | _ctk_file_system_init (CtkFileSystem *file_system) |
| 331 | { |
| 332 | CtkFileSystemPrivate *priv; |
| 333 | |
| 334 | DEBUG ("init"); |
| 335 | |
| 336 | file_system->priv = priv = _ctk_file_system_get_instance_private (file_system); |
| 337 | |
| 338 | /* Volumes */ |
| 339 | priv->volume_monitor = g_volume_monitor_get (); |
| 340 | |
| 341 | g_signal_connect (priv->volume_monitor, "mount-added",g_signal_connect_data ((priv->volume_monitor), ("mount-added" ), (((GCallback) (volumes_changed))), (file_system), ((void*) 0), (GConnectFlags) 0) |
| 342 | G_CALLBACK (volumes_changed), file_system)g_signal_connect_data ((priv->volume_monitor), ("mount-added" ), (((GCallback) (volumes_changed))), (file_system), ((void*) 0), (GConnectFlags) 0); |
| 343 | g_signal_connect (priv->volume_monitor, "mount-removed",g_signal_connect_data ((priv->volume_monitor), ("mount-removed" ), (((GCallback) (volumes_changed))), (file_system), ((void*) 0), (GConnectFlags) 0) |
| 344 | G_CALLBACK (volumes_changed), file_system)g_signal_connect_data ((priv->volume_monitor), ("mount-removed" ), (((GCallback) (volumes_changed))), (file_system), ((void*) 0), (GConnectFlags) 0); |
| 345 | g_signal_connect (priv->volume_monitor, "mount-changed",g_signal_connect_data ((priv->volume_monitor), ("mount-changed" ), (((GCallback) (volumes_changed))), (file_system), ((void*) 0), (GConnectFlags) 0) |
| 346 | G_CALLBACK (volumes_changed), file_system)g_signal_connect_data ((priv->volume_monitor), ("mount-changed" ), (((GCallback) (volumes_changed))), (file_system), ((void*) 0), (GConnectFlags) 0); |
| 347 | g_signal_connect (priv->volume_monitor, "volume-added",g_signal_connect_data ((priv->volume_monitor), ("volume-added" ), (((GCallback) (volumes_changed))), (file_system), ((void*) 0), (GConnectFlags) 0) |
| 348 | G_CALLBACK (volumes_changed), file_system)g_signal_connect_data ((priv->volume_monitor), ("volume-added" ), (((GCallback) (volumes_changed))), (file_system), ((void*) 0), (GConnectFlags) 0); |
| 349 | g_signal_connect (priv->volume_monitor, "volume-removed",g_signal_connect_data ((priv->volume_monitor), ("volume-removed" ), (((GCallback) (volumes_changed))), (file_system), ((void*) 0), (GConnectFlags) 0) |
| 350 | G_CALLBACK (volumes_changed), file_system)g_signal_connect_data ((priv->volume_monitor), ("volume-removed" ), (((GCallback) (volumes_changed))), (file_system), ((void*) 0), (GConnectFlags) 0); |
| 351 | g_signal_connect (priv->volume_monitor, "volume-changed",g_signal_connect_data ((priv->volume_monitor), ("volume-changed" ), (((GCallback) (volumes_changed))), (file_system), ((void*) 0), (GConnectFlags) 0) |
| 352 | G_CALLBACK (volumes_changed), file_system)g_signal_connect_data ((priv->volume_monitor), ("volume-changed" ), (((GCallback) (volumes_changed))), (file_system), ((void*) 0), (GConnectFlags) 0); |
| 353 | g_signal_connect (priv->volume_monitor, "drive-connected",g_signal_connect_data ((priv->volume_monitor), ("drive-connected" ), (((GCallback) (volumes_changed))), (file_system), ((void*) 0), (GConnectFlags) 0) |
| 354 | G_CALLBACK (volumes_changed), file_system)g_signal_connect_data ((priv->volume_monitor), ("drive-connected" ), (((GCallback) (volumes_changed))), (file_system), ((void*) 0), (GConnectFlags) 0); |
| 355 | g_signal_connect (priv->volume_monitor, "drive-disconnected",g_signal_connect_data ((priv->volume_monitor), ("drive-disconnected" ), (((GCallback) (volumes_changed))), (file_system), ((void*) 0), (GConnectFlags) 0) |
| 356 | G_CALLBACK (volumes_changed), file_system)g_signal_connect_data ((priv->volume_monitor), ("drive-disconnected" ), (((GCallback) (volumes_changed))), (file_system), ((void*) 0), (GConnectFlags) 0); |
| 357 | g_signal_connect (priv->volume_monitor, "drive-changed",g_signal_connect_data ((priv->volume_monitor), ("drive-changed" ), (((GCallback) (volumes_changed))), (file_system), ((void*) 0), (GConnectFlags) 0) |
| 358 | G_CALLBACK (volumes_changed), file_system)g_signal_connect_data ((priv->volume_monitor), ("drive-changed" ), (((GCallback) (volumes_changed))), (file_system), ((void*) 0), (GConnectFlags) 0); |
| 359 | } |
| 360 | |
| 361 | /* CtkFileSystem public methods */ |
| 362 | CtkFileSystem * |
| 363 | _ctk_file_system_new (void) |
| 364 | { |
| 365 | return g_object_new (CTK_TYPE_FILE_SYSTEM(_ctk_file_system_get_type ()), NULL((void*)0)); |
| 366 | } |
| 367 | |
| 368 | GSList * |
| 369 | _ctk_file_system_list_volumes (CtkFileSystem *file_system) |
| 370 | { |
| 371 | CtkFileSystemPrivate *priv = file_system->priv; |
| 372 | GSList *list; |
| 373 | |
| 374 | DEBUG ("list_volumes"); |
| 375 | |
| 376 | get_volumes_list (file_system); |
| 377 | |
| 378 | list = g_slist_copy (priv->volumes); |
| 379 | |
| 380 | #ifndef G_OS_WIN32 |
| 381 | /* Prepend root volume */ |
| 382 | list = g_slist_prepend (list, (gpointer) root_volume_token); |
| 383 | #endif |
| 384 | |
| 385 | return list; |
| 386 | } |
| 387 | |
| 388 | static void |
| 389 | free_async_data (AsyncFuncData *async_data) |
| 390 | { |
| 391 | g_object_unref (async_data->file_system); |
| 392 | g_object_unref (async_data->file); |
| 393 | g_object_unref (async_data->cancellable); |
| 394 | |
| 395 | g_free (async_data); |
| 396 | } |
| 397 | |
| 398 | static void |
| 399 | query_info_callback (GObject *source_object, |
| 400 | GAsyncResult *result, |
| 401 | gpointer user_data) |
| 402 | { |
| 403 | AsyncFuncData *async_data; |
| 404 | GError *error = NULL((void*)0); |
| 405 | GFileInfo *file_info; |
| 406 | GFile *file; |
| 407 | |
| 408 | DEBUG ("query_info_callback"); |
| 409 | |
| 410 | file = G_FILE (source_object)((((GFile*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((source_object)), ((g_file_get_type ())))))); |
| 411 | async_data = (AsyncFuncData *) user_data; |
| 412 | file_info = g_file_query_info_finish (file, result, &error); |
| 413 | |
| 414 | if (async_data->callback) |
| 415 | { |
| 416 | cdk_threads_enter (); |
| 417 | ((CtkFileSystemGetInfoCallback) async_data->callback) (async_data->cancellable, |
| 418 | file_info, error, async_data->data); |
| 419 | cdk_threads_leave (); |
| 420 | } |
| 421 | |
| 422 | if (file_info) |
| 423 | g_object_unref (file_info); |
| 424 | |
| 425 | if (error) |
| 426 | g_error_free (error); |
| 427 | |
| 428 | free_async_data (async_data); |
| 429 | } |
| 430 | |
| 431 | GCancellable * |
| 432 | _ctk_file_system_get_info (CtkFileSystem *file_system, |
| 433 | GFile *file, |
| 434 | const gchar *attributes, |
| 435 | CtkFileSystemGetInfoCallback callback, |
| 436 | gpointer data) |
| 437 | { |
| 438 | GCancellable *cancellable; |
| 439 | AsyncFuncData *async_data; |
| 440 | |
| 441 | g_return_val_if_fail (CTK_IS_FILE_SYSTEM (file_system), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((file_system)); GType __t = ((_ctk_file_system_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_FILE_SYSTEM (file_system)"); return (((void*)0)); } } while (0); |
| 442 | g_return_val_if_fail (G_IS_FILE (file), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((file)); GType __t = ((g_file_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "G_IS_FILE (file)"); return (((void*)0)); } } while (0); |
| 443 | |
| 444 | cancellable = g_cancellable_new (); |
| 445 | |
| 446 | async_data = g_new0 (AsyncFuncData, 1)((AsyncFuncData *) g_malloc0_n ((1), sizeof (AsyncFuncData))); |
| 447 | async_data->file_system = g_object_ref (file_system)((__typeof__ (file_system)) (g_object_ref) (file_system)); |
| 448 | async_data->file = g_object_ref (file)((__typeof__ (file)) (g_object_ref) (file)); |
| 449 | async_data->cancellable = g_object_ref (cancellable)((__typeof__ (cancellable)) (g_object_ref) (cancellable)); |
| 450 | |
| 451 | async_data->callback = callback; |
| 452 | async_data->data = data; |
| 453 | |
| 454 | g_file_query_info_async (file, |
| 455 | attributes, |
| 456 | G_FILE_QUERY_INFO_NONE, |
| 457 | G_PRIORITY_DEFAULT0, |
| 458 | cancellable, |
| 459 | query_info_callback, |
| 460 | async_data); |
| 461 | |
| 462 | return cancellable; |
| 463 | } |
| 464 | |
| 465 | static void |
| 466 | drive_poll_for_media_cb (GObject *source_object, |
| 467 | GAsyncResult *result, |
| 468 | gpointer user_data) |
| 469 | { |
| 470 | AsyncFuncData *async_data; |
| 471 | GError *error = NULL((void*)0); |
| 472 | |
| 473 | g_drive_poll_for_media_finish (G_DRIVE (source_object)((((GDrive*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((source_object)), ((g_drive_get_type ())))))), result, &error); |
| 474 | async_data = (AsyncFuncData *) user_data; |
| 475 | |
| 476 | cdk_threads_enter (); |
| 477 | ((CtkFileSystemVolumeMountCallback) async_data->callback) (async_data->cancellable, |
| 478 | (CtkFileSystemVolume *) source_object, |
| 479 | error, async_data->data); |
| 480 | cdk_threads_leave (); |
| 481 | |
| 482 | if (error) |
| 483 | g_error_free (error); |
| 484 | } |
| 485 | |
| 486 | static void |
| 487 | volume_mount_cb (GObject *source_object, |
| 488 | GAsyncResult *result, |
| 489 | gpointer user_data) |
| 490 | { |
| 491 | AsyncFuncData *async_data; |
| 492 | GError *error = NULL((void*)0); |
| 493 | |
| 494 | g_volume_mount_finish (G_VOLUME (source_object)((((GVolume*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((source_object)), ((g_volume_get_type ())))))), result, &error); |
| 495 | async_data = (AsyncFuncData *) user_data; |
| 496 | |
| 497 | cdk_threads_enter (); |
| 498 | ((CtkFileSystemVolumeMountCallback) async_data->callback) (async_data->cancellable, |
| 499 | (CtkFileSystemVolume *) source_object, |
| 500 | error, async_data->data); |
| 501 | cdk_threads_leave (); |
| 502 | |
| 503 | if (error) |
| 504 | g_error_free (error); |
| 505 | } |
| 506 | |
| 507 | GCancellable * |
| 508 | _ctk_file_system_mount_volume (CtkFileSystem *file_system, |
| 509 | CtkFileSystemVolume *volume, |
| 510 | GMountOperation *mount_operation, |
| 511 | CtkFileSystemVolumeMountCallback callback, |
| 512 | gpointer data) |
| 513 | { |
| 514 | GCancellable *cancellable; |
| 515 | AsyncFuncData *async_data; |
| 516 | gboolean handled = FALSE(0); |
| 517 | |
| 518 | DEBUG ("volume_mount"); |
| 519 | |
| 520 | cancellable = g_cancellable_new (); |
| 521 | |
| 522 | async_data = g_new0 (AsyncFuncData, 1)((AsyncFuncData *) g_malloc0_n ((1), sizeof (AsyncFuncData))); |
| 523 | async_data->file_system = g_object_ref (file_system)((__typeof__ (file_system)) (g_object_ref) (file_system)); |
| 524 | async_data->cancellable = g_object_ref (cancellable)((__typeof__ (cancellable)) (g_object_ref) (cancellable)); |
| 525 | |
| 526 | async_data->callback = callback; |
| 527 | async_data->data = data; |
| 528 | |
| 529 | if (G_IS_DRIVE (volume)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (volume)); GType __t = ((g_drive_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 530 | { |
| 531 | /* this path happens for drives that are not polled by the OS and where the last media |
| 532 | * check indicated that no media was available. So the thing to do here is to |
| 533 | * invoke poll_for_media() on the drive |
| 534 | */ |
| 535 | g_drive_poll_for_media (G_DRIVE (volume)((((GDrive*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((volume)), ((g_drive_get_type ())))))), cancellable, drive_poll_for_media_cb, async_data); |
| 536 | handled = TRUE(!(0)); |
| 537 | } |
| 538 | else if (G_IS_VOLUME (volume)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (volume)); GType __t = ((g_volume_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 539 | { |
| 540 | g_volume_mount (G_VOLUME (volume)((((GVolume*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((volume)), ((g_volume_get_type ())))))), G_MOUNT_MOUNT_NONE, mount_operation, cancellable, volume_mount_cb, async_data); |
| 541 | handled = TRUE(!(0)); |
| 542 | } |
| 543 | |
| 544 | if (!handled) |
| 545 | free_async_data (async_data); |
| 546 | |
| 547 | return cancellable; |
| 548 | } |
| 549 | |
| 550 | static void |
| 551 | enclosing_volume_mount_cb (GObject *source_object, |
| 552 | GAsyncResult *result, |
| 553 | gpointer user_data) |
| 554 | { |
| 555 | CtkFileSystemVolume *volume; |
| 556 | AsyncFuncData *async_data; |
| 557 | GError *error = NULL((void*)0); |
| 558 | |
| 559 | async_data = (AsyncFuncData *) user_data; |
| 560 | g_file_mount_enclosing_volume_finish (G_FILE (source_object)((((GFile*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((source_object)), ((g_file_get_type ())))))), result, &error); |
| 561 | volume = _ctk_file_system_get_volume_for_file (async_data->file_system, G_FILE (source_object)((((GFile*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((source_object)), ((g_file_get_type ()))))))); |
| 562 | |
| 563 | /* Silently drop G_IO_ERROR_ALREADY_MOUNTED error for gvfs backends without visible mounts. */ |
| 564 | /* Better than doing query_info with additional I/O every time. */ |
| 565 | if (error && g_error_matches (error, G_IO_ERRORg_io_error_quark(), G_IO_ERROR_ALREADY_MOUNTED)) |
| 566 | g_clear_error (&error); |
| 567 | |
| 568 | cdk_threads_enter (); |
| 569 | ((CtkFileSystemVolumeMountCallback) async_data->callback) (async_data->cancellable, volume, |
| 570 | error, async_data->data); |
| 571 | cdk_threads_leave (); |
| 572 | |
| 573 | if (error) |
| 574 | g_error_free (error); |
| 575 | |
| 576 | _ctk_file_system_volume_unref (volume); |
| 577 | } |
| 578 | |
| 579 | GCancellable * |
| 580 | _ctk_file_system_mount_enclosing_volume (CtkFileSystem *file_system, |
| 581 | GFile *file, |
| 582 | GMountOperation *mount_operation, |
| 583 | CtkFileSystemVolumeMountCallback callback, |
| 584 | gpointer data) |
| 585 | { |
| 586 | GCancellable *cancellable; |
| 587 | AsyncFuncData *async_data; |
| 588 | |
| 589 | g_return_val_if_fail (CTK_IS_FILE_SYSTEM (file_system), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((file_system)); GType __t = ((_ctk_file_system_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_FILE_SYSTEM (file_system)"); return (((void*)0)); } } while (0); |
| 590 | g_return_val_if_fail (G_IS_FILE (file), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((file)); GType __t = ((g_file_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "G_IS_FILE (file)"); return (((void*)0)); } } while (0); |
| 591 | |
| 592 | DEBUG ("mount_enclosing_volume"); |
| 593 | |
| 594 | cancellable = g_cancellable_new (); |
| 595 | |
| 596 | async_data = g_new0 (AsyncFuncData, 1)((AsyncFuncData *) g_malloc0_n ((1), sizeof (AsyncFuncData))); |
| 597 | async_data->file_system = g_object_ref (file_system)((__typeof__ (file_system)) (g_object_ref) (file_system)); |
| 598 | async_data->file = g_object_ref (file)((__typeof__ (file)) (g_object_ref) (file)); |
| 599 | async_data->cancellable = g_object_ref (cancellable)((__typeof__ (cancellable)) (g_object_ref) (cancellable)); |
| 600 | |
| 601 | async_data->callback = callback; |
| 602 | async_data->data = data; |
| 603 | |
| 604 | g_file_mount_enclosing_volume (file, |
| 605 | G_MOUNT_MOUNT_NONE, |
| 606 | mount_operation, |
| 607 | cancellable, |
| 608 | enclosing_volume_mount_cb, |
| 609 | async_data); |
| 610 | return cancellable; |
| 611 | } |
| 612 | |
| 613 | CtkFileSystemVolume * |
| 614 | _ctk_file_system_get_volume_for_file (CtkFileSystem *file_system G_GNUC_UNUSED__attribute__ ((__unused__)), |
| 615 | GFile *file) |
| 616 | { |
| 617 | GMount *mount; |
| 618 | |
| 619 | DEBUG ("get_volume_for_file"); |
| 620 | |
| 621 | mount = g_file_find_enclosing_mount (file, NULL((void*)0), NULL((void*)0)); |
| 622 | |
| 623 | if (!mount && g_file_is_native (file)) |
| 624 | return (CtkFileSystemVolume *) root_volume_token; |
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption | |
| 625 | |
| 626 | return (CtkFileSystemVolume *) mount; |
| 627 | } |
| 628 | |
| 629 | /* CtkFileSystemVolume public methods */ |
| 630 | gchar * |
| 631 | _ctk_file_system_volume_get_display_name (CtkFileSystemVolume *volume) |
| 632 | { |
| 633 | DEBUG ("volume_get_display_name"); |
| 634 | |
| 635 | if (IS_ROOT_VOLUME (volume)((gpointer) (volume) == (gpointer) root_volume_token)) |
| 636 | return g_strdup (_(root_volume_token))g_strdup_inline (((char *) g_dgettext ("ctk30", root_volume_token ))); |
| 637 | if (G_IS_DRIVE (volume)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (volume)); GType __t = ((g_drive_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 638 | return g_drive_get_name (G_DRIVE (volume)((((GDrive*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((volume)), ((g_drive_get_type ()))))))); |
| 639 | else if (G_IS_MOUNT (volume)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (volume)); GType __t = ((g_mount_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 640 | return g_mount_get_name (G_MOUNT (volume)((((GMount*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((volume)), ((g_mount_get_type ()))))))); |
| 641 | else if (G_IS_VOLUME (volume)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (volume)); GType __t = ((g_volume_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 642 | return g_volume_get_name (G_VOLUME (volume)((((GVolume*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((volume)), ((g_volume_get_type ()))))))); |
| 643 | |
| 644 | return NULL((void*)0); |
| 645 | } |
| 646 | |
| 647 | gboolean |
| 648 | _ctk_file_system_volume_is_mounted (CtkFileSystemVolume *volume) |
| 649 | { |
| 650 | gboolean mounted; |
| 651 | |
| 652 | DEBUG ("volume_is_mounted"); |
| 653 | |
| 654 | if (IS_ROOT_VOLUME (volume)((gpointer) (volume) == (gpointer) root_volume_token)) |
| 655 | return TRUE(!(0)); |
| 656 | |
| 657 | mounted = FALSE(0); |
| 658 | |
| 659 | if (G_IS_MOUNT (volume)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (volume)); GType __t = ((g_mount_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 660 | mounted = TRUE(!(0)); |
| 661 | else if (G_IS_VOLUME (volume)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (volume)); GType __t = ((g_volume_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 662 | { |
| 663 | GMount *mount; |
| 664 | |
| 665 | mount = g_volume_get_mount (G_VOLUME (volume)((((GVolume*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((volume)), ((g_volume_get_type ()))))))); |
| 666 | |
| 667 | if (mount) |
| 668 | { |
| 669 | mounted = TRUE(!(0)); |
| 670 | g_object_unref (mount); |
| 671 | } |
| 672 | } |
| 673 | |
| 674 | return mounted; |
| 675 | } |
| 676 | |
| 677 | GFile * |
| 678 | _ctk_file_system_volume_get_root (CtkFileSystemVolume *volume) |
| 679 | { |
| 680 | GFile *file = NULL((void*)0); |
| 681 | |
| 682 | DEBUG ("volume_get_base"); |
| 683 | |
| 684 | if (IS_ROOT_VOLUME (volume)((gpointer) (volume) == (gpointer) root_volume_token)) |
| 685 | return g_file_new_for_uri ("file:///"); |
| 686 | |
| 687 | if (G_IS_MOUNT (volume)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (volume)); GType __t = ((g_mount_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 688 | file = g_mount_get_root (G_MOUNT (volume)((((GMount*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((volume)), ((g_mount_get_type ()))))))); |
| 689 | else if (G_IS_VOLUME (volume)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (volume)); GType __t = ((g_volume_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 690 | { |
| 691 | GMount *mount; |
| 692 | |
| 693 | mount = g_volume_get_mount (G_VOLUME (volume)((((GVolume*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((volume)), ((g_volume_get_type ()))))))); |
| 694 | |
| 695 | if (mount) |
| 696 | { |
| 697 | file = g_mount_get_root (mount); |
| 698 | g_object_unref (mount); |
| 699 | } |
| 700 | } |
| 701 | |
| 702 | return file; |
| 703 | } |
| 704 | |
| 705 | static cairo_surface_t * |
| 706 | get_surface_from_gicon (GIcon *icon, |
| 707 | CtkWidget *widget, |
| 708 | gint icon_size, |
| 709 | GError **error) |
| 710 | { |
| 711 | CtkStyleContext *context; |
| 712 | CtkIconTheme *icon_theme; |
| 713 | CtkIconInfo *icon_info; |
| 714 | GdkPixbuf *pixbuf; |
| 715 | cairo_surface_t *surface; |
| 716 | |
| 717 | context = ctk_widget_get_style_context (widget); |
| 718 | icon_theme = ctk_css_icon_theme_value_get_icon_theme |
| 719 | (_ctk_style_context_peek_property (context, CTK_CSS_PROPERTY_ICON_THEME)); |
| 720 | |
| 721 | icon_info = ctk_icon_theme_lookup_by_gicon_for_scale (icon_theme, |
| 722 | icon, |
| 723 | icon_size, |
| 724 | ctk_widget_get_scale_factor (widget), |
| 725 | CTK_ICON_LOOKUP_USE_BUILTIN); |
| 726 | |
| 727 | if (!icon_info) |
| 728 | return NULL((void*)0); |
| 729 | |
| 730 | pixbuf = ctk_icon_info_load_symbolic_for_context (icon_info, |
| 731 | context, |
| 732 | NULL((void*)0), |
| 733 | error); |
| 734 | |
| 735 | g_object_unref (icon_info); |
| 736 | |
| 737 | if (pixbuf == NULL((void*)0)) |
| 738 | return NULL((void*)0); |
| 739 | |
| 740 | surface = cdk_cairo_surface_create_from_pixbuf (pixbuf, |
| 741 | ctk_widget_get_scale_factor (widget), |
| 742 | ctk_widget_get_window (widget)); |
| 743 | g_object_unref (pixbuf); |
| 744 | |
| 745 | return surface; |
| 746 | } |
| 747 | |
| 748 | cairo_surface_t * |
| 749 | _ctk_file_system_volume_render_icon (CtkFileSystemVolume *volume, |
| 750 | CtkWidget *widget, |
| 751 | gint icon_size, |
| 752 | GError **error) |
| 753 | { |
| 754 | GIcon *icon = NULL((void*)0); |
| 755 | cairo_surface_t *surface; |
| 756 | |
| 757 | if (IS_ROOT_VOLUME (volume)((gpointer) (volume) == (gpointer) root_volume_token)) |
| 758 | icon = g_themed_icon_new ("drive-harddisk"); |
| 759 | else if (G_IS_DRIVE (volume)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (volume)); GType __t = ((g_drive_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 760 | icon = g_drive_get_icon (G_DRIVE (volume)((((GDrive*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((volume)), ((g_drive_get_type ()))))))); |
| 761 | else if (G_IS_VOLUME (volume)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (volume)); GType __t = ((g_volume_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 762 | icon = g_volume_get_icon (G_VOLUME (volume)((((GVolume*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((volume)), ((g_volume_get_type ()))))))); |
| 763 | else if (G_IS_MOUNT (volume)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (volume)); GType __t = ((g_mount_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 764 | icon = g_mount_get_icon (G_MOUNT (volume)((((GMount*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((volume)), ((g_mount_get_type ()))))))); |
| 765 | |
| 766 | if (!icon) |
| 767 | return NULL((void*)0); |
| 768 | |
| 769 | surface = get_surface_from_gicon (icon, widget, icon_size, error); |
| 770 | |
| 771 | g_object_unref (icon); |
| 772 | |
| 773 | return surface; |
| 774 | } |
| 775 | |
| 776 | GIcon * |
| 777 | _ctk_file_system_volume_get_symbolic_icon (CtkFileSystemVolume *volume) |
| 778 | { |
| 779 | if (IS_ROOT_VOLUME (volume)((gpointer) (volume) == (gpointer) root_volume_token)) |
| 780 | return g_themed_icon_new ("drive-harddisk-symbolic"); |
| 781 | else if (G_IS_DRIVE (volume)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (volume)); GType __t = ((g_drive_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 782 | return g_drive_get_symbolic_icon (G_DRIVE (volume)((((GDrive*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((volume)), ((g_drive_get_type ()))))))); |
| 783 | else if (G_IS_VOLUME (volume)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (volume)); GType __t = ((g_volume_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 784 | return g_volume_get_symbolic_icon (G_VOLUME (volume)((((GVolume*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((volume)), ((g_volume_get_type ()))))))); |
| 785 | else if (G_IS_MOUNT (volume)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (volume)); GType __t = ((g_mount_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 786 | return g_mount_get_symbolic_icon (G_MOUNT (volume)((((GMount*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((volume)), ((g_mount_get_type ()))))))); |
| 787 | else |
| 788 | return NULL((void*)0); |
| 789 | } |
| 790 | |
| 791 | CtkFileSystemVolume * |
| 792 | _ctk_file_system_volume_ref (CtkFileSystemVolume *volume) |
| 793 | { |
| 794 | if (IS_ROOT_VOLUME (volume)((gpointer) (volume) == (gpointer) root_volume_token)) |
| 795 | return volume; |
| 796 | |
| 797 | if (G_IS_MOUNT (volume)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (volume)); GType __t = ((g_mount_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))) || |
| 798 | G_IS_VOLUME (volume)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (volume)); GType __t = ((g_volume_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))) || |
| 799 | G_IS_DRIVE (volume)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (volume)); GType __t = ((g_drive_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 800 | g_object_ref (volume)((__typeof__ (volume)) (g_object_ref) (volume)); |
| 801 | |
| 802 | return volume; |
| 803 | } |
| 804 | |
| 805 | void |
| 806 | _ctk_file_system_volume_unref (CtkFileSystemVolume *volume) |
| 807 | { |
| 808 | /* Root volume doesn't need to be freed */ |
| 809 | if (IS_ROOT_VOLUME (volume)((gpointer) (volume) == (gpointer) root_volume_token)) |
| 810 | return; |
| 811 | |
| 812 | if (G_IS_MOUNT (volume)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (volume)); GType __t = ((g_mount_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))) || |
| 813 | G_IS_VOLUME (volume)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (volume)); GType __t = ((g_volume_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))) || |
| 814 | G_IS_DRIVE (volume)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (volume)); GType __t = ((g_drive_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
| 815 | g_object_unref (volume); |
| 816 | } |
| 817 | |
| 818 | /* GFileInfo helper functions */ |
| 819 | static cairo_surface_t * |
| 820 | _ctk_file_info_render_icon_internal (GFileInfo *info, |
| 821 | CtkWidget *widget, |
| 822 | gint icon_size, |
| 823 | gboolean symbolic) |
| 824 | { |
| 825 | GIcon *icon; |
| 826 | GdkPixbuf *pixbuf; |
| 827 | const gchar *thumbnail_path; |
| 828 | cairo_surface_t *surface = NULL((void*)0); |
| 829 | int scale; |
| 830 | |
| 831 | thumbnail_path = g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH"thumbnail::path"); |
| 832 | |
| 833 | if (thumbnail_path) |
| 834 | { |
| 835 | scale = ctk_widget_get_scale_factor (widget); |
| 836 | pixbuf = gdk_pixbuf_new_from_file_at_size (thumbnail_path, |
| 837 | icon_size*scale, icon_size*scale, |
| 838 | NULL((void*)0)); |
| 839 | |
| 840 | if (pixbuf != NULL((void*)0)) |
| 841 | { |
| 842 | surface = cdk_cairo_surface_create_from_pixbuf (pixbuf, scale, |
| 843 | ctk_widget_get_window (widget)); |
| 844 | g_object_unref (pixbuf); |
| 845 | } |
| 846 | } |
| 847 | |
| 848 | if (!surface) |
| 849 | { |
| 850 | if (symbolic) |
| 851 | icon = g_file_info_get_symbolic_icon (info); |
| 852 | else |
| 853 | icon = g_file_info_get_icon (info); |
| 854 | |
| 855 | if (icon) |
| 856 | surface = get_surface_from_gicon (icon, widget, icon_size, NULL((void*)0)); |
| 857 | |
| 858 | if (!surface) |
| 859 | { |
| 860 | /* Use general fallback for all files without icon */ |
| 861 | if (symbolic) |
| 862 | icon = g_themed_icon_new ("text-x-generic-symbolic"); |
| 863 | else |
| 864 | icon = g_themed_icon_new ("text-x-generic"); |
| 865 | surface = get_surface_from_gicon (icon, widget, icon_size, NULL((void*)0)); |
| 866 | g_object_unref (icon); |
| 867 | } |
| 868 | } |
| 869 | |
| 870 | return surface; |
| 871 | } |
| 872 | |
| 873 | cairo_surface_t * |
| 874 | _ctk_file_info_render_icon (GFileInfo *info, |
| 875 | CtkWidget *widget, |
| 876 | gint icon_size) |
| 877 | { |
| 878 | return _ctk_file_info_render_icon_internal (info, widget, icon_size, FALSE(0)); |
| 879 | } |
| 880 | |
| 881 | gboolean |
| 882 | _ctk_file_info_consider_as_directory (GFileInfo *info) |
| 883 | { |
| 884 | GFileType type = g_file_info_get_file_type (info); |
| 885 | |
| 886 | return (type == G_FILE_TYPE_DIRECTORY || |
| 887 | type == G_FILE_TYPE_MOUNTABLE || |
| 888 | type == G_FILE_TYPE_SHORTCUT); |
| 889 | } |
| 890 | |
| 891 | gboolean |
| 892 | _ctk_file_has_native_path (GFile *file) |
| 893 | { |
| 894 | char *local_file_path; |
| 895 | gboolean has_native_path; |
| 896 | |
| 897 | /* Don't use g_file_is_native(), as we want to support FUSE paths if available */ |
| 898 | local_file_path = g_file_get_path (file); |
| 899 | has_native_path = (local_file_path != NULL((void*)0)); |
| 900 | g_free (local_file_path); |
| 901 | |
| 902 | return has_native_path; |
| 903 | } |
| 904 | |
| 905 | gboolean |
| 906 | _ctk_file_consider_as_remote (GFile *file) |
| 907 | { |
| 908 | GFileInfo *info; |
| 909 | gboolean is_remote; |
| 910 | |
| 911 | info = g_file_query_filesystem_info (file, G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE"filesystem::remote", NULL((void*)0), NULL((void*)0)); |
| 912 | if (info) |
| 913 | { |
| 914 | is_remote = g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE"filesystem::remote"); |
| 915 | |
| 916 | g_object_unref (info); |
| 917 | } |
| 918 | else |
| 919 | is_remote = FALSE(0); |
| 920 | |
| 921 | return is_remote; |
| 922 | } |