ali@9: /* ali@9: * Copyright (C) 2010 J. Ali Harlow ali@9: * ali@9: * This program is free software; you can redistribute it and/or modify ali@9: * it under the terms of the GNU General Public License as published by ali@9: * the Free Software Foundation; either version 2 of the License, or ali@9: * (at your option) any later version. ali@9: * ali@9: * This program is distributed in the hope that it will be useful, ali@9: * but WITHOUT ANY WARRANTY; without even the implied warranty of ali@9: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ali@9: * GNU General Public License for more details. ali@9: * ali@9: * You should have received a copy of the GNU General Public License along ali@9: * with this program; if not, write to the Free Software Foundation, Inc., ali@9: * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ali@9: */ ali@9: ali@9: #include "config.h" ali@9: #include ali@9: #include ali@10: #ifdef WIN32 ali@10: #include ali@10: #endif ali@9: #include ali@9: #include ali@9: #include ali@9: #include ali@10: #include "app-manager.h" ali@9: #include "localmedia.h" ali@9: ali@9: G_DEFINE_TYPE(PloverLocalMediaStore,plover_local_media_store, ali@9: PLOVER_TYPE_PACKAGE_STORE); ali@9: ali@9: static void plover_local_media_store_dispose(GObject *obj) ali@9: { ali@9: PloverLocalMediaStore *store=PLOVER_LOCAL_MEDIA_STORE(obj); ali@9: if (store->monitor) ali@9: { ali@9: g_object_unref(store->monitor); ali@9: store->monitor=NULL; ali@9: } ali@9: if (G_OBJECT_CLASS(plover_local_media_store_parent_class)->dispose) ali@9: G_OBJECT_CLASS(plover_local_media_store_parent_class)->dispose(obj); ali@9: } ali@9: ali@9: static void ali@9: plover_local_media_store_class_init(PloverLocalMediaStoreClass *klass) ali@9: { ali@9: GObjectClass *oclass=G_OBJECT_CLASS(klass); ali@9: oclass->dispose=plover_local_media_store_dispose; ali@9: } ali@9: ali@9: GtkTreeModel *plover_local_media_store_new(void) ali@9: { ali@9: return g_object_new(PLOVER_TYPE_LOCAL_MEDIA_STORE,NULL); ali@9: } ali@9: ali@9: static void local_media_scan_mount(PloverLocalMediaStore *store,GMount *mount) ali@9: { ali@9: GFile *root; ali@9: gchar *path; ali@10: #ifdef WIN32 ali@10: gunichar2 *path2; ali@10: UINT type; ali@10: #endif ali@9: PloverPackageSet *set; ali@9: root=g_mount_get_root(mount); ali@9: path=g_file_get_path(root); ali@10: #ifdef WIN32 ali@9: if (path) ali@9: { ali@10: path2=g_utf8_to_utf16(path,-1,NULL,NULL,NULL); ali@10: if (path2) ali@10: { ali@10: type=GetDriveTypeW(path2); ali@10: g_free(path2); ali@10: } ali@10: else ali@10: type=DRIVE_UNKNOWN; ali@10: if (type!=DRIVE_REMOVABLE && type!=DRIVE_CDROM) ali@10: { ali@10: gchar *name=g_mount_get_name(mount); ali@10: g_debug("Skipping non-local mount \"%s\"",name); ali@10: g_free(name); ali@10: g_free(path); ali@10: path=NULL; ali@10: } ali@10: } ali@10: #endif ali@10: if (path) ali@10: { ali@10: set=plover_package_set_new_from_repository(path,relocations,NULL); ali@9: if (set) ali@9: { ali@9: g_object_set_data(G_OBJECT(mount),"plover-local-media-set",set); ali@9: plover_package_store_add_set(PLOVER_PACKAGE_STORE(store),set); ali@9: g_object_ref(mount); ali@9: } ali@9: g_free(path); ali@9: } ali@9: g_object_unref(root); ali@9: } ali@9: ali@9: static void local_media_mounted(GObject *source,GAsyncResult *res,gpointer data) ali@9: { ali@9: GVolume *volume=G_VOLUME(source); ali@9: GMount *mount; ali@9: PloverLocalMediaStore *store=PLOVER_LOCAL_MEDIA_STORE(data); ali@9: if (g_volume_mount_finish(volume,res,NULL)) ali@9: { ali@9: mount=g_volume_get_mount(volume); ali@9: if (mount) ali@9: { ali@9: local_media_scan_mount(store,mount); ali@9: g_object_unref(mount); ali@9: } ali@9: } ali@9: g_object_unref(volume); ali@9: } ali@9: ali@9: static void local_media_scan_drive(PloverLocalMediaStore *store,GDrive *drive) ali@9: { ali@9: GVolume *volume; ali@9: GMount *mount; ali@10: GList *volumes,*mounts,*link; ali@10: if (!drive) ali@10: volumes=g_volume_monitor_get_volumes(store->monitor); ali@10: else if (g_drive_has_media(drive)) ali@10: volumes=g_drive_get_volumes(drive); ali@10: else ali@10: volumes=NULL; ali@10: for(link=volumes;link;link=link->next) ali@9: { ali@10: volume=G_VOLUME(link->data); ali@10: mount=g_volume_get_mount(volume); ali@10: if (mount) ali@9: { ali@10: local_media_scan_mount(store,mount); ali@10: g_object_unref(mount); ali@9: } ali@10: else if (!store->implicit_scan && g_volume_can_mount(volume)) ali@10: g_volume_mount(volume,G_MOUNT_MOUNT_NONE,NULL,NULL, ali@10: local_media_mounted,store); ali@10: g_object_unref(volume); ali@10: } ali@10: g_list_free(volumes); ali@10: if (!drive) ali@10: { ali@10: mounts=g_volume_monitor_get_mounts(store->monitor); ali@10: for(link=mounts;link;link=link->next) ali@10: { ali@10: mount=G_MOUNT(link->data); ali@10: local_media_scan_mount(store,mount); ali@10: g_object_unref(mount); ali@10: } ali@10: g_list_free(mounts); ali@9: } ali@9: } ali@9: ali@9: static void local_media_polled(GObject *source,GAsyncResult *res,gpointer data) ali@9: { ali@9: GDrive *drive=G_DRIVE(source); ali@9: PloverLocalMediaStore *store=PLOVER_LOCAL_MEDIA_STORE(data); ali@9: if (g_drive_poll_for_media_finish(drive,res,NULL)) ali@9: local_media_scan_drive(store,drive); ali@9: g_object_unref(drive); ali@9: } ali@9: ali@9: void plover_local_media_store_scan(PloverLocalMediaStore *store) ali@9: { ali@10: GList *sets,*drives,*link; ali@9: GDrive *drive; ali@9: g_return_if_fail(PLOVER_IS_LOCAL_MEDIA_STORE(store)); ali@10: sets= ali@10: g_slist_copy(plover_package_store_get_sets(PLOVER_PACKAGE_STORE(store))); ali@10: for(link=sets;link;link=link->next) ali@10: plover_package_store_remove_set(PLOVER_PACKAGE_STORE(store), ali@10: PLOVER_PACKAGE_SET(link->data)); ali@10: g_slist_free(sets); ali@9: drives=g_volume_monitor_get_connected_drives(store->monitor); ali@9: for(link=drives;link;link=link->next) ali@9: { ali@9: drive=G_DRIVE(link->data); ali@9: if (g_drive_is_media_removable(drive)) ali@9: { ali@9: if (!g_drive_is_media_check_automatic(drive) && ali@9: g_drive_can_poll_for_media(drive) || ali@9: !g_drive_has_media(drive) && !store->implicit_scan) ali@9: { ali@9: g_object_ref(drive); ali@9: g_drive_poll_for_media(drive,NULL,local_media_polled,store); ali@9: } ali@9: else ali@9: local_media_scan_drive(store,drive); ali@9: } ali@9: g_object_unref(drive); ali@9: } ali@9: g_list_free(drives); ali@10: local_media_scan_drive(store,NULL); ali@9: } ali@9: ali@9: static void local_media_mount_added(GVolumeMonitor *volume_monitor, ali@9: GMount *mount,PloverLocalMediaStore *store) ali@9: { ali@9: local_media_scan_mount(store,mount); ali@9: } ali@9: ali@9: static void local_media_mount_removed(GVolumeMonitor *volume_monitor, ali@9: GMount *mount,PloverLocalMediaStore *store) ali@9: { ali@9: PloverPackageSet *set= ali@9: g_object_get_data(G_OBJECT(mount),"plover-local-media-set"); ali@9: if (set) ali@9: { ali@9: plover_package_store_remove_set(PLOVER_PACKAGE_STORE(store),set); ali@9: g_object_set_data(G_OBJECT(mount),"plover-local-media-set",NULL); ali@9: g_object_unref(set); ali@9: g_object_unref(mount); ali@9: } ali@9: } ali@9: ali@9: static void local_media_mount_changed(GVolumeMonitor *volume_monitor, ali@9: GMount *mount,PloverLocalMediaStore *store) ali@9: { ali@9: local_media_mount_removed(volume_monitor,mount,store); ali@9: local_media_mount_added(volume_monitor,mount,store); ali@9: } ali@9: ali@9: static void plover_local_media_store_init(PloverLocalMediaStore *store) ali@9: { ali@9: store->monitor=g_volume_monitor_get(); ali@9: store->implicit_scan=TRUE; ali@9: plover_local_media_store_scan(store); ali@9: store->implicit_scan=FALSE; ali@9: g_signal_connect(store->monitor,"mount-added", ali@9: G_CALLBACK(local_media_mount_added),store); ali@9: g_signal_connect(store->monitor,"mount-changed", ali@9: G_CALLBACK(local_media_mount_changed),store); ali@9: g_signal_connect(store->monitor,"mount-removed", ali@9: G_CALLBACK(local_media_mount_removed),store); ali@9: }