app-manager/localmedia.c
author J. Ali Harlow <ali@juiblex.co.uk>
Tue Feb 21 22:55:40 2012 +0000 (2012-02-21)
changeset 19 5cafc65a6183
parent 10 8b50be3e2998
child 24 2b9f54d14cc2
permissions -rw-r--r--
Port to razor 0.5.4
     1 /*
     2  * Copyright (C) 2010  J. Ali Harlow <ali@juiblex.co.uk>
     3  *
     4  * This program is free software; you can redistribute it and/or modify
     5  * it under the terms of the GNU General Public License as published by
     6  * the Free Software Foundation; either version 2 of the License, or
     7  * (at your option) any later version.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License along
    15  * with this program; if not, write to the Free Software Foundation, Inc.,
    16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    17  */
    18 
    19 #include "config.h"
    20 #include <stdlib.h>
    21 #include <string.h>
    22 #ifdef WIN32
    23 #include <windows.h>
    24 #endif
    25 #include <glib.h>
    26 #include <gio/gio.h>
    27 #include <gtk/gtk.h>
    28 #include <plover-gtk/packagestore.h>
    29 #include "app-manager.h"
    30 #include "localmedia.h"
    31 
    32 G_DEFINE_TYPE(PloverLocalMediaStore,plover_local_media_store,
    33   PLOVER_TYPE_PACKAGE_STORE);
    34 
    35 static void plover_local_media_store_dispose(GObject *obj)
    36 {
    37     PloverLocalMediaStore *store=PLOVER_LOCAL_MEDIA_STORE(obj);
    38     if (store->monitor)
    39     {
    40 	g_object_unref(store->monitor);
    41 	store->monitor=NULL;
    42     }
    43     if (G_OBJECT_CLASS(plover_local_media_store_parent_class)->dispose)
    44 	G_OBJECT_CLASS(plover_local_media_store_parent_class)->dispose(obj);
    45 }
    46 
    47 static void
    48   plover_local_media_store_class_init(PloverLocalMediaStoreClass *klass)
    49 {
    50     GObjectClass *oclass=G_OBJECT_CLASS(klass);
    51     oclass->dispose=plover_local_media_store_dispose;
    52 }
    53 
    54 GtkTreeModel *plover_local_media_store_new(void)
    55 {
    56     return g_object_new(PLOVER_TYPE_LOCAL_MEDIA_STORE,NULL);
    57 }
    58 
    59 static void local_media_scan_mount(PloverLocalMediaStore *store,GMount *mount)
    60 {
    61     GFile *root;
    62     gchar *path;
    63 #ifdef WIN32
    64     gunichar2 *path2;
    65     UINT type;
    66 #endif
    67     PloverPackageSet *set;
    68     root=g_mount_get_root(mount);
    69     path=g_file_get_path(root);
    70 #ifdef WIN32
    71     if (path)
    72     {
    73 	path2=g_utf8_to_utf16(path,-1,NULL,NULL,NULL);
    74 	if (path2)
    75 	{
    76 	    type=GetDriveTypeW(path2);
    77 	    g_free(path2);
    78 	}
    79 	else
    80 	    type=DRIVE_UNKNOWN;
    81 	if (type!=DRIVE_REMOVABLE && type!=DRIVE_CDROM)
    82 	{
    83 	    gchar *name=g_mount_get_name(mount);
    84 	    g_debug("Skipping non-local mount \"%s\"",name);
    85 	    g_free(name);
    86 	    g_free(path);
    87 	    path=NULL;
    88 	}
    89     }
    90 #endif
    91     if (path)
    92     {
    93 	set=plover_package_set_new_from_repository(path,relocations,NULL);
    94 	if (set)
    95 	{
    96 	    g_object_set_data(G_OBJECT(mount),"plover-local-media-set",set);
    97 	    plover_package_store_add_set(PLOVER_PACKAGE_STORE(store),set);
    98 	    g_object_ref(mount);
    99 	}
   100 	g_free(path);
   101     }
   102     g_object_unref(root);
   103 }
   104 
   105 static void local_media_mounted(GObject *source,GAsyncResult *res,gpointer data)
   106 {
   107     GVolume *volume=G_VOLUME(source);
   108     GMount *mount;
   109     PloverLocalMediaStore *store=PLOVER_LOCAL_MEDIA_STORE(data);
   110     if (g_volume_mount_finish(volume,res,NULL))
   111     {
   112 	mount=g_volume_get_mount(volume);
   113 	if (mount)
   114 	{
   115 	    local_media_scan_mount(store,mount);
   116 	    g_object_unref(mount);
   117 	}
   118     }
   119     g_object_unref(volume);
   120 }
   121 
   122 static void local_media_scan_drive(PloverLocalMediaStore *store,GDrive *drive)
   123 {
   124     GVolume *volume;
   125     GMount *mount;
   126     GList *volumes,*mounts,*link;
   127     if (!drive)
   128 	volumes=g_volume_monitor_get_volumes(store->monitor);
   129     else if (g_drive_has_media(drive))
   130 	volumes=g_drive_get_volumes(drive);
   131     else
   132 	volumes=NULL;
   133     for(link=volumes;link;link=link->next)
   134     {
   135 	volume=G_VOLUME(link->data);
   136 	mount=g_volume_get_mount(volume);
   137 	if (mount)
   138 	{
   139 	    local_media_scan_mount(store,mount);
   140 	    g_object_unref(mount);
   141 	}
   142 	else if (!store->implicit_scan && g_volume_can_mount(volume))
   143 	    g_volume_mount(volume,G_MOUNT_MOUNT_NONE,NULL,NULL,
   144 	      local_media_mounted,store);
   145 	g_object_unref(volume);
   146     }
   147     g_list_free(volumes);
   148     if (!drive)
   149     {
   150 	mounts=g_volume_monitor_get_mounts(store->monitor);
   151 	for(link=mounts;link;link=link->next)
   152 	{
   153 	    mount=G_MOUNT(link->data);
   154 	    local_media_scan_mount(store,mount);
   155 	    g_object_unref(mount);
   156 	}
   157 	g_list_free(mounts);
   158     }
   159 }
   160 
   161 static void local_media_polled(GObject *source,GAsyncResult *res,gpointer data)
   162 {
   163     GDrive *drive=G_DRIVE(source);
   164     PloverLocalMediaStore *store=PLOVER_LOCAL_MEDIA_STORE(data);
   165     if (g_drive_poll_for_media_finish(drive,res,NULL))
   166 	local_media_scan_drive(store,drive);
   167     g_object_unref(drive);
   168 }
   169 
   170 void plover_local_media_store_scan(PloverLocalMediaStore *store)
   171 {
   172     GSList *sets,*slink;
   173     GList *drives,*link;
   174     GDrive *drive;
   175     g_return_if_fail(PLOVER_IS_LOCAL_MEDIA_STORE(store));
   176     sets=
   177       g_slist_copy(plover_package_store_get_sets(PLOVER_PACKAGE_STORE(store)));
   178     for(slink=sets;slink;slink=slink->next)
   179 	plover_package_store_remove_set(PLOVER_PACKAGE_STORE(store),
   180 	  PLOVER_PACKAGE_SET(slink->data));
   181     g_slist_free(sets);
   182     drives=g_volume_monitor_get_connected_drives(store->monitor);
   183     for(link=drives;link;link=link->next)
   184     {
   185 	drive=G_DRIVE(link->data);
   186 	if (g_drive_is_media_removable(drive))
   187 	{
   188 	    if (!g_drive_is_media_check_automatic(drive) &&
   189 	      g_drive_can_poll_for_media(drive) ||
   190 	      !g_drive_has_media(drive) && !store->implicit_scan)
   191 	    {
   192 		g_object_ref(drive);
   193 		g_drive_poll_for_media(drive,NULL,local_media_polled,store);
   194 	    }
   195 	    else
   196 		local_media_scan_drive(store,drive);
   197 	}
   198 	g_object_unref(drive);
   199     }
   200     g_list_free(drives);
   201     local_media_scan_drive(store,NULL);
   202 }
   203 
   204 static void local_media_mount_added(GVolumeMonitor *volume_monitor,
   205   GMount *mount,PloverLocalMediaStore *store)
   206 {
   207     local_media_scan_mount(store,mount);
   208 }
   209 
   210 static void local_media_mount_removed(GVolumeMonitor *volume_monitor,
   211   GMount *mount,PloverLocalMediaStore *store)
   212 {
   213     PloverPackageSet *set=
   214       g_object_get_data(G_OBJECT(mount),"plover-local-media-set");
   215     if (set)
   216     {
   217 	plover_package_store_remove_set(PLOVER_PACKAGE_STORE(store),set);
   218 	g_object_set_data(G_OBJECT(mount),"plover-local-media-set",NULL);
   219 	g_object_unref(set);
   220 	g_object_unref(mount);
   221     }
   222 }
   223 
   224 static void local_media_mount_changed(GVolumeMonitor *volume_monitor,
   225   GMount *mount,PloverLocalMediaStore *store)
   226 {
   227     local_media_mount_removed(volume_monitor,mount,store);
   228     local_media_mount_added(volume_monitor,mount,store);
   229 }
   230 
   231 static void plover_local_media_store_init(PloverLocalMediaStore *store)
   232 {
   233     store->monitor=g_volume_monitor_get();
   234     store->implicit_scan=TRUE;
   235     plover_local_media_store_scan(store);
   236     store->implicit_scan=FALSE;
   237     g_signal_connect(store->monitor,"mount-added",
   238       G_CALLBACK(local_media_mount_added),store);
   239     g_signal_connect(store->monitor,"mount-changed",
   240       G_CALLBACK(local_media_mount_changed),store);
   241     g_signal_connect(store->monitor,"mount-removed",
   242       G_CALLBACK(local_media_mount_removed),store);
   243 }