mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-23 18:32:50 +00:00

the camera slave is on the chopping block, libtmp is supposed to be able to handle PTP too Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
364 lines
14 KiB
C++
364 lines
14 KiB
C++
/*
|
|
* Helper implementations for KIO-MTP
|
|
* Copyright (C) 2013 Philipp Schmidt <philschmidt@gmx.net>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
|
|
#include "kio_mtp_helpers.h"
|
|
|
|
|
|
int dataProgress(uint64_t const sent, uint64_t const, void const *const priv)
|
|
{
|
|
((MTPSlave*)priv)->processedSize(sent);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* MTPDataPutFunc callback function, "puts" data from the device somewhere else
|
|
*/
|
|
uint16_t dataPut(void*, void *priv, uint32_t sendlen, unsigned char *data, uint32_t *putlen)
|
|
{
|
|
kDebug(KIO_MTP) << "transferring" << sendlen << "bytes to data()";
|
|
|
|
((MTPSlave* )priv)->data(QByteArray((char*)data, (int)sendlen));
|
|
*putlen = sendlen;
|
|
|
|
return LIBMTP_HANDLER_RETURN_OK;
|
|
}
|
|
|
|
/**
|
|
* MTPDataGetFunc callback function, "gets" data and puts it on the device
|
|
*/
|
|
uint16_t dataGet(void*, void *priv, uint32_t, unsigned char *data, uint32_t *gotlen)
|
|
{
|
|
((MTPSlave*)priv)->dataReq();
|
|
|
|
QByteArray buffer;
|
|
*gotlen = ((MTPSlave*)priv)->readData(buffer);
|
|
|
|
kDebug(KIO_MTP) << "transferring" << *gotlen << "bytes to data()";
|
|
|
|
data = (unsigned char*)buffer.data();
|
|
|
|
return LIBMTP_HANDLER_RETURN_OK;
|
|
}
|
|
|
|
QString convertToPath(const QStringList& pathItems, const int elements)
|
|
{
|
|
QString path;
|
|
|
|
for (int i = 0; i < elements && elements <= pathItems.size(); i++) {
|
|
path.append(QLatin1Char('/'));
|
|
path.append(pathItems.at(i));
|
|
}
|
|
|
|
return path;
|
|
}
|
|
|
|
QString getMimetype(LIBMTP_filetype_t filetype)
|
|
{
|
|
switch (filetype) {
|
|
case LIBMTP_FILETYPE_FOLDER:
|
|
return QLatin1String("inode/directory");
|
|
case LIBMTP_FILETYPE_WAV:
|
|
return QLatin1String("audio/wav");
|
|
case LIBMTP_FILETYPE_MP3:
|
|
return QLatin1String("audio/x-mp3");
|
|
case LIBMTP_FILETYPE_WMA:
|
|
return QLatin1String("audio/x-ms-wma");
|
|
case LIBMTP_FILETYPE_OGG:
|
|
return QLatin1String("audio/x-vorbis+ogg");
|
|
case LIBMTP_FILETYPE_AUDIBLE:
|
|
return QLatin1String("");
|
|
case LIBMTP_FILETYPE_MP4:
|
|
return QLatin1String("audio/mp4");
|
|
case LIBMTP_FILETYPE_UNDEF_AUDIO:
|
|
return QLatin1String("");
|
|
case LIBMTP_FILETYPE_WMV:
|
|
return QLatin1String("video/x-ms-wmv");
|
|
case LIBMTP_FILETYPE_AVI:
|
|
return QLatin1String("video/x-msvideo");
|
|
case LIBMTP_FILETYPE_MPEG:
|
|
return QLatin1String("video/mpeg");
|
|
case LIBMTP_FILETYPE_ASF:
|
|
return QLatin1String("video/x-ms-asf");
|
|
case LIBMTP_FILETYPE_QT:
|
|
return QLatin1String("video/quicktime");
|
|
case LIBMTP_FILETYPE_UNDEF_VIDEO:
|
|
return QLatin1String("");
|
|
case LIBMTP_FILETYPE_JPEG:
|
|
return QLatin1String("image/jpeg");
|
|
case LIBMTP_FILETYPE_JFIF:
|
|
return QLatin1String("");
|
|
case LIBMTP_FILETYPE_TIFF:
|
|
return QLatin1String("image/tiff");
|
|
case LIBMTP_FILETYPE_BMP:
|
|
return QLatin1String("image/bmp");
|
|
case LIBMTP_FILETYPE_GIF:
|
|
return QLatin1String("image/gif");
|
|
case LIBMTP_FILETYPE_PICT:
|
|
return QLatin1String("image/x-pict");
|
|
case LIBMTP_FILETYPE_PNG:
|
|
return QLatin1String("image/png");
|
|
case LIBMTP_FILETYPE_VCALENDAR1:
|
|
return QLatin1String("text/x-vcalendar");
|
|
case LIBMTP_FILETYPE_VCALENDAR2:
|
|
return QLatin1String("text/x-vcalendar");
|
|
case LIBMTP_FILETYPE_VCARD2:
|
|
return QLatin1String("text/x-vcard");
|
|
case LIBMTP_FILETYPE_VCARD3:
|
|
return QLatin1String("text/x-vcard");
|
|
case LIBMTP_FILETYPE_WINDOWSIMAGEFORMAT:
|
|
return QLatin1String("image/x-wmf");
|
|
case LIBMTP_FILETYPE_WINEXEC:
|
|
return QLatin1String("application/x-ms-dos-executable");
|
|
case LIBMTP_FILETYPE_TEXT:
|
|
return QLatin1String("text/plain");
|
|
case LIBMTP_FILETYPE_HTML:
|
|
return QLatin1String("text/html");
|
|
case LIBMTP_FILETYPE_FIRMWARE:
|
|
return QLatin1String("");
|
|
case LIBMTP_FILETYPE_AAC:
|
|
return QLatin1String("audio/aac");
|
|
case LIBMTP_FILETYPE_MEDIACARD:
|
|
return QLatin1String("");
|
|
case LIBMTP_FILETYPE_FLAC:
|
|
return QLatin1String("audio/flac");
|
|
case LIBMTP_FILETYPE_MP2:
|
|
return QLatin1String("video/mpeg");
|
|
case LIBMTP_FILETYPE_M4A:
|
|
return QLatin1String("audio/mp4");
|
|
case LIBMTP_FILETYPE_DOC:
|
|
return QLatin1String("application/msword");
|
|
case LIBMTP_FILETYPE_XML:
|
|
return QLatin1String("text/xml");
|
|
case LIBMTP_FILETYPE_XLS:
|
|
return QLatin1String("application/vnd.ms-excel");
|
|
case LIBMTP_FILETYPE_PPT:
|
|
return QLatin1String("application/vnd.ms-powerpoint");
|
|
case LIBMTP_FILETYPE_MHT:
|
|
return QLatin1String("application/x-mimearchive");
|
|
case LIBMTP_FILETYPE_JP2:
|
|
return QLatin1String("image/jpeg2000");
|
|
case LIBMTP_FILETYPE_JPX:
|
|
return QLatin1String("application/x-jbuilder-project");
|
|
case LIBMTP_FILETYPE_UNKNOWN:
|
|
return QString();
|
|
}
|
|
return QString();
|
|
}
|
|
|
|
LIBMTP_filetype_t getFiletype(const QString &filename)
|
|
{
|
|
LIBMTP_filetype_t filetype;
|
|
|
|
QString ptype = filename.split(QLatin1Char('.')).last();
|
|
|
|
/* This need to be kept constantly updated as new file types arrive. */
|
|
if (ptype == QLatin1String("wav")) {
|
|
filetype = LIBMTP_FILETYPE_WAV;
|
|
} else if (ptype == QLatin1String("mp3")) {
|
|
filetype = LIBMTP_FILETYPE_MP3;
|
|
} else if (ptype == QLatin1String("wma")) {
|
|
filetype = LIBMTP_FILETYPE_WMA;
|
|
} else if (ptype == QLatin1String("ogg")) {
|
|
filetype = LIBMTP_FILETYPE_OGG;
|
|
} else if (ptype == QLatin1String("mp4")) {
|
|
filetype = LIBMTP_FILETYPE_MP4;
|
|
} else if (ptype == QLatin1String("wmv")) {
|
|
filetype = LIBMTP_FILETYPE_WMV;
|
|
} else if (ptype == QLatin1String("avi")) {
|
|
filetype = LIBMTP_FILETYPE_AVI;
|
|
} else if (ptype == QLatin1String("mpeg") || ptype == QLatin1String("mpg")) {
|
|
filetype = LIBMTP_FILETYPE_MPEG;
|
|
} else if (ptype == QLatin1String("asf")) {
|
|
filetype = LIBMTP_FILETYPE_ASF;
|
|
} else if (ptype == QLatin1String("qt") || ptype == QLatin1String("mov")) {
|
|
filetype = LIBMTP_FILETYPE_QT;
|
|
} else if (ptype == QLatin1String("wma")) {
|
|
filetype = LIBMTP_FILETYPE_WMA;
|
|
} else if (ptype == QLatin1String("jpg") || ptype == QLatin1String("jpeg")) {
|
|
filetype = LIBMTP_FILETYPE_JPEG;
|
|
} else if (ptype == QLatin1String("jfif")) {
|
|
filetype = LIBMTP_FILETYPE_JFIF;
|
|
} else if (ptype == QLatin1String("tif") || ptype == QLatin1String("tiff")) {
|
|
filetype = LIBMTP_FILETYPE_TIFF;
|
|
} else if (ptype == QLatin1String("bmp")) {
|
|
filetype = LIBMTP_FILETYPE_BMP;
|
|
} else if (ptype == QLatin1String ("gif")) {
|
|
filetype = LIBMTP_FILETYPE_GIF;
|
|
} else if (ptype == QLatin1String("pic") || ptype == QLatin1String ("pict")) {
|
|
filetype = LIBMTP_FILETYPE_PICT;
|
|
} else if (ptype == QLatin1String("png")) {
|
|
filetype = LIBMTP_FILETYPE_PNG;
|
|
} else if (ptype == QLatin1String("wmf")) {
|
|
filetype = LIBMTP_FILETYPE_WINDOWSIMAGEFORMAT;
|
|
} else if (ptype == QLatin1String("ics")) {
|
|
filetype = LIBMTP_FILETYPE_VCALENDAR2;
|
|
} else if (ptype == QLatin1String ("exe") || ptype == QLatin1String("com") ||
|
|
ptype == QLatin1String("bat") || ptype == QLatin1String("dll") ||
|
|
ptype == QLatin1String("sys")) {
|
|
filetype = LIBMTP_FILETYPE_WINEXEC;
|
|
} else if (ptype == QLatin1String("aac")) {
|
|
filetype = LIBMTP_FILETYPE_AAC;
|
|
} else if (ptype == QLatin1String("mp2")) {
|
|
filetype = LIBMTP_FILETYPE_MP2;
|
|
} else if (ptype == QLatin1String("flac")) {
|
|
filetype = LIBMTP_FILETYPE_FLAC;
|
|
} else if (ptype == QLatin1String("m4a")) {
|
|
filetype = LIBMTP_FILETYPE_M4A;
|
|
} else if (ptype == QLatin1String("doc")) {
|
|
filetype = LIBMTP_FILETYPE_DOC;
|
|
} else if (ptype == QLatin1String("xml")) {
|
|
filetype = LIBMTP_FILETYPE_XML;
|
|
} else if (ptype == QLatin1String("xls")) {
|
|
filetype = LIBMTP_FILETYPE_XLS;
|
|
} else if (ptype == QLatin1String("ppt")) {
|
|
filetype = LIBMTP_FILETYPE_PPT;
|
|
} else if (ptype == QLatin1String("mht")) {
|
|
filetype = LIBMTP_FILETYPE_MHT;
|
|
} else if (ptype == QLatin1String("jp2")) {
|
|
filetype = LIBMTP_FILETYPE_JP2;
|
|
} else if (ptype == QLatin1String ("jpx")) {
|
|
filetype = LIBMTP_FILETYPE_JPX;
|
|
} else if (ptype == QLatin1String("bin")) {
|
|
filetype = LIBMTP_FILETYPE_FIRMWARE;
|
|
} else if (ptype == QLatin1String("vcf")) {
|
|
filetype = LIBMTP_FILETYPE_VCARD3;
|
|
} else {
|
|
/* Tagging as unknown file type */
|
|
filetype = LIBMTP_FILETYPE_UNKNOWN;
|
|
}
|
|
|
|
return filetype;
|
|
}
|
|
|
|
QMap<QString, LIBMTP_devicestorage_t*> getDevicestorages(LIBMTP_mtpdevice_t *&device)
|
|
{
|
|
kDebug (KIO_MTP) << "[ENTER]" << (device == 0);
|
|
|
|
QMap<QString, LIBMTP_devicestorage_t*> storages;
|
|
if (device) {
|
|
for (LIBMTP_devicestorage_t* storage = device->storage; storage != NULL; storage = storage->next) {
|
|
// char *storageIdentifier = storage->VolumeIdentifier;
|
|
char *storageDescription = storage->StorageDescription;
|
|
|
|
QString storagename;
|
|
// if (!storageIdentifier)
|
|
storagename = QString::fromUtf8(storageDescription);
|
|
// } else {
|
|
// storagename = QString::fromUtf8(storageIdentifier);
|
|
// }
|
|
|
|
kDebug(KIO_MTP) << "found storage" << storagename;
|
|
|
|
storages.insert(storagename, storage);
|
|
}
|
|
}
|
|
|
|
kDebug(KIO_MTP) << "[EXIT]" << storages.size();
|
|
|
|
return storages;
|
|
}
|
|
|
|
QMap<QString, LIBMTP_file_t*> getFiles(LIBMTP_mtpdevice_t *&device, uint32_t storage_id, uint32_t parent_id)
|
|
{
|
|
kDebug(KIO_MTP) << "getFiles() for parent" << parent_id;
|
|
|
|
QMap<QString, LIBMTP_file_t*> fileMap;
|
|
|
|
LIBMTP_file_t *files = LIBMTP_Get_Files_And_Folders(device, storage_id, parent_id), *file;
|
|
for (file = files; file != NULL; file = file->next) {
|
|
fileMap.insert(QString::fromUtf8(file->filename), file);
|
|
// kDebug(KIO_MTP) << "found file" << file->filename;
|
|
}
|
|
|
|
kDebug(KIO_MTP) << "[EXIT]";
|
|
|
|
return fileMap;
|
|
}
|
|
|
|
void getEntry(UDSEntry &entry, LIBMTP_mtpdevice_t* device, const QString &url)
|
|
{
|
|
char *charName = LIBMTP_Get_Friendlyname(device);
|
|
char *charModel = LIBMTP_Get_Modelname(device);
|
|
|
|
// prefer friendly devicename over model
|
|
QString deviceName;
|
|
if (!charName) {
|
|
deviceName = QString::fromUtf8(charModel);
|
|
} else {
|
|
deviceName = QString::fromUtf8(charName);
|
|
}
|
|
|
|
entry.insert(UDSEntry::UDS_NAME, deviceName);
|
|
entry.insert(UDSEntry::UDS_URL, url);
|
|
entry.insert(UDSEntry::UDS_ICON_NAME, QLatin1String("multimedia-player"));
|
|
entry.insert(UDSEntry::UDS_FILE_TYPE, S_IFDIR);
|
|
entry.insert(UDSEntry::UDS_ACCESS, S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH);
|
|
entry.insert(UDSEntry::UDS_MIME_TYPE, QLatin1String("inode/directory"));
|
|
}
|
|
|
|
void getEntry(UDSEntry &entry, const LIBMTP_devicestorage_t* storage, const QString &url)
|
|
{
|
|
// char *charIdentifier = storage->VolumeIdentifier;
|
|
char *charDescription = storage->StorageDescription;
|
|
|
|
QString storageName;
|
|
// if ( !charIdentifier )
|
|
storageName = QString::fromUtf8(charDescription);
|
|
// else {
|
|
// storageName = QString::fromUtf8(charIdentifier);
|
|
// }
|
|
|
|
entry.insert(UDSEntry::UDS_NAME, storageName);
|
|
entry.insert(UDSEntry::UDS_URL, url);
|
|
entry.insert(UDSEntry::UDS_ICON_NAME, QLatin1String("drive-removable-media"));
|
|
entry.insert(UDSEntry::UDS_FILE_TYPE, S_IFDIR );
|
|
entry.insert(UDSEntry::UDS_ACCESS, S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH);
|
|
entry.insert(UDSEntry::UDS_MIME_TYPE, QLatin1String("inode/directory"));
|
|
}
|
|
|
|
void getEntry(UDSEntry &entry, const LIBMTP_file_t* file, const QString &url)
|
|
{
|
|
entry.insert(UDSEntry::UDS_NAME, QString::fromUtf8(file->filename));
|
|
entry.insert(UDSEntry::UDS_URL, url);
|
|
if (file->filetype == LIBMTP_FILETYPE_FOLDER) {
|
|
entry.insert(UDSEntry::UDS_FILE_TYPE, S_IFDIR);
|
|
entry.insert(UDSEntry::UDS_ACCESS, S_IRWXU | S_IRWXG | S_IRWXO);
|
|
entry.insert(UDSEntry::UDS_MIME_TYPE, QLatin1String("inode/directory"));
|
|
} else {
|
|
entry.insert(UDSEntry::UDS_FILE_TYPE, S_IFREG );
|
|
entry.insert(UDSEntry::UDS_ACCESS, S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH);
|
|
entry.insert(UDSEntry::UDS_SIZE, file->filesize );
|
|
entry.insert(UDSEntry::UDS_MIME_TYPE, getMimetype(file->filetype));
|
|
}
|
|
entry.insert(UDSEntry::UDS_INODE, file->item_id);
|
|
entry.insert(UDSEntry::UDS_ACCESS_TIME, file->modificationdate);
|
|
entry.insert(UDSEntry::UDS_MODIFICATION_TIME, file->modificationdate);
|
|
entry.insert(UDSEntry::UDS_CREATION_TIME, file->modificationdate);
|
|
}
|
|
|
|
void resetDeviceStack(LIBMTP_mtpdevice_t* device)
|
|
{
|
|
LIBMTP_error_t* error = LIBMTP_Get_Errorstack(device);
|
|
while (error) {
|
|
kWarning(KIO_MTP) << error->error_text;
|
|
error = error->next;
|
|
}
|
|
LIBMTP_Clear_Errorstack(device);
|
|
}
|