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