static void delete_done_cb (LIBMTP_mtpdevice_t *device, TracksDeletedCallbackData *data) { data->actually_free = FALSE; update_free_space_cb (device, RB_MTP_SOURCE (data->source)); g_idle_add ((GSourceFunc) delete_done_idle_cb, data); }
/* this callback runs on the device handling thread, so it can call libmtp directly */ static void mtp_device_open_cb (LIBMTP_mtpdevice_t *device, RBMtpSource *source) { RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source); DeviceOpenedData *data; if (device == NULL) { /* can't delete the source on this thread, so move it to the main thread */ g_idle_add ((GSourceFunc) device_open_failed_idle, g_object_ref (source)); return; } /* set the source name to match the device, ignoring some * particular broken device names. */ data = g_new0 (DeviceOpenedData, 1); data->source = g_object_ref (source); data->name = LIBMTP_Get_Friendlyname (device); if (data->name == NULL || strcmp (data->name, "?????") == 0) { g_free (data->name); data->name = LIBMTP_Get_Modelname (device); } if (data->name == NULL) { data->name = g_strdup (_("Digital Audio Player")); } /* get some other device information that doesn't change */ priv->manufacturer = LIBMTP_Get_Manufacturername (device); priv->device_version = LIBMTP_Get_Deviceversion (device); priv->model_name = LIBMTP_Get_Modelname (device); priv->serial = LIBMTP_Get_Serialnumber (device); /* calculate the device capacity */ priv->capacity = 0; if (LIBMTP_Get_Storage (device, LIBMTP_STORAGE_SORTBY_NOTSORTED) == 0) { LIBMTP_devicestorage_t *storage; for (storage = device->storage; storage != NULL; storage = storage->next) { priv->capacity += storage->MaxCapacity; } } update_free_space_cb (device, RB_MTP_SOURCE (source)); /* figure out the set of formats supported by the device */ if (LIBMTP_Get_Supported_Filetypes (device, &data->types, &data->num_types) != 0) { rb_mtp_thread_report_errors (priv->device_thread, FALSE); } g_idle_add ((GSourceFunc) device_opened_idle, data); /* now get the track list */ rb_mtp_thread_get_track_list (priv->device_thread, (RBMtpTrackListCallback) mtp_tracklist_cb, g_object_ref (source), g_object_unref); }
/* this callback runs on the device handling thread, so it can call libmtp directly */ static void mtp_device_open_cb (LIBMTP_mtpdevice_t *device, RBMtpSource *source) { RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source); gboolean has_audio = FALSE; DeviceOpenedData *data; if (device == NULL) { /* can't delete the source on this thread, so move it to the main thread */ g_idle_add ((GSourceFunc) device_open_failed_idle, g_object_ref (source)); return; } /* set the source name to match the device, ignoring some * particular broken device names. */ data = g_new0 (DeviceOpenedData, 1); data->source = g_object_ref (source); data->name = LIBMTP_Get_Friendlyname (device); if (data->name == NULL || strcmp (data->name, "?????") == 0) { g_free (data->name); data->name = LIBMTP_Get_Modelname (device); } if (data->name == NULL) { data->name = g_strdup (_("Digital Audio Player")); } /* get some other device information that doesn't change */ priv->manufacturer = LIBMTP_Get_Manufacturername (device); priv->device_version = LIBMTP_Get_Deviceversion (device); priv->model_name = LIBMTP_Get_Modelname (device); priv->serial = LIBMTP_Get_Serialnumber (device); /* calculate the device capacity */ priv->capacity = 0; if (LIBMTP_Get_Storage (device, LIBMTP_STORAGE_SORTBY_NOTSORTED) == 0) { LIBMTP_devicestorage_t *storage; for (storage = device->storage; storage != NULL; storage = storage->next) { priv->capacity += storage->MaxCapacity; } } update_free_space_cb (device, RB_MTP_SOURCE (source)); /* figure out the set of formats supported by the device, ensuring there's at least * one audio format aside from WAV. the purpose of this is to exclude cameras and other * MTP devices that aren't interesting to us. */ if (LIBMTP_Get_Supported_Filetypes (device, &data->types, &data->num_types) != 0) { rb_mtp_thread_report_errors (priv->device_thread, FALSE); } else { int i; for (i = 0; i < data->num_types; i++) { if (data->types[i] != LIBMTP_FILETYPE_WAV && LIBMTP_FILETYPE_IS_AUDIO (data->types[i])) { has_audio = TRUE; break; } } } if (has_audio == FALSE) { rb_debug ("device doesn't support any audio formats"); g_idle_add ((GSourceFunc) device_open_ignore_idle, data); return; } g_idle_add ((GSourceFunc) device_opened_idle, data); /* now get the track list */ rb_mtp_thread_get_track_list (priv->device_thread, (RBMtpTrackListCallback) mtp_tracklist_cb, g_object_ref (source), g_object_unref); }
static void delete_done_cb (LIBMTP_mtpdevice_t *device, TracksDeletedCallbackData *data) { LIBMTP_folder_t *folders; LIBMTP_file_t *files; data->actually_free = FALSE; update_free_space_cb (device, RB_MTP_SOURCE (data->source)); /* if any of the folders we just deleted from are now empty, delete them */ folders = LIBMTP_Get_Folder_List (device); files = LIBMTP_Get_Filelisting_With_Callback (device, NULL, NULL); if (folders != NULL) { GHashTableIter iter; gpointer key; g_hash_table_iter_init (&iter, data->check_folders); while (g_hash_table_iter_next (&iter, &key, NULL)) { LIBMTP_folder_t *f; LIBMTP_folder_t *c; LIBMTP_file_t *file; uint32_t folder_id = GPOINTER_TO_UINT(key); while (folder_id != device->default_music_folder && folder_id != 0) { f = LIBMTP_Find_Folder (folders, folder_id); if (f == NULL) { rb_debug ("unable to find folder %u", folder_id); break; } /* don't delete folders with children that we didn't just delete */ for (c = f->child; c != NULL; c = c->sibling) { if (g_hash_table_lookup (data->check_folders, GUINT_TO_POINTER (c->folder_id)) == NULL) { break; } } if (c != NULL) { rb_debug ("folder %s has children", f->name); break; } /* don't delete folders that contain files */ for (file = files; file != NULL; file = file->next) { if (file->parent_id == folder_id) { break; } } if (file != NULL) { rb_debug ("folder %s contains at least one file: %s", f->name, file->filename); break; } /* ok, the folder is empty */ rb_debug ("deleting empty folder %s", f->name); LIBMTP_Delete_Object (device, f->folder_id); /* if the folder we just deleted has siblings, the parent * can't be empty. */ if (f->sibling != NULL) { rb_debug ("folder %s has siblings, can't delete parent", f->name); break; } folder_id = f->parent_id; } } LIBMTP_destroy_folder_t (folders); } else { rb_debug ("unable to get device folder list"); } /* clean up the file list */ while (files != NULL) { LIBMTP_file_t *n; n = files->next; LIBMTP_destroy_file_t (files); files = n; } g_idle_add ((GSourceFunc) delete_done_idle_cb, data); }