[mpriscontrol] add primitive windows support

Summary: Added primitive support for the mpriscontrol plugin on Windows by simulating VK_MEDIA key presses. I took a look into `ISystemMediaTransportControls`, but there doesn't seem to query it since it's per app. Leaving simulating key presses our only option for now. Completes T10000

Reviewers: kdeconnect, #kde_connect, albertvaka

Reviewed By: #kde_connect, albertvaka

Subscribers: albertvaka

Tags: #kde_connect, #windows

Maniphest Tasks: T10000

Differential Revision: https://phabricator.kde.org/D17702
This commit is contained in:
Jun Bo Bi 2018-12-21 19:23:49 +01:00 committed by Albert Vaca
parent 27f47ce8d4
commit f4c7e12ea6
4 changed files with 153 additions and 18 deletions

View file

@ -5,10 +5,7 @@ install(FILES kdeconnect_plugin.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR})
add_subdirectory(ping) add_subdirectory(ping)
add_subdirectory(battery) add_subdirectory(battery)
add_subdirectory(sendnotifications) add_subdirectory(sendnotifications)
add_subdirectory(mpriscontrol)
if (NOT WIN32)
add_subdirectory(mpriscontrol)
endif()
if(NOT SAILFISHOS) if(NOT SAILFISHOS)
add_subdirectory(clipboard) add_subdirectory(clipboard)

View file

@ -1,19 +1,29 @@
set(kdeconnect_mpriscontrol_SRCS if(WIN32)
mpriscontrolplugin.cpp set(kdeconnect_mpriscontrol_SRCS
) mpriscontrolplugin-win.cpp
)
else()
set(kdeconnect_mpriscontrol_SRCS
mpriscontrolplugin.cpp
)
qt5_add_dbus_interface( qt5_add_dbus_interface(
kdeconnect_mpriscontrol_SRCS kdeconnect_mpriscontrol_SRCS
mprisdbusinterface.xml mprisdbusinterface.xml
mprisdbusinterface mprisdbusinterface
) )
qt5_add_dbus_interface( qt5_add_dbus_interface(
kdeconnect_mpriscontrol_SRCS kdeconnect_mpriscontrol_SRCS
propertiesInterface.xml propertiesInterface.xml
propertiesdbusinterface propertiesdbusinterface
) )
endif()
kdeconnect_add_plugin(kdeconnect_mpriscontrol JSON kdeconnect_mpriscontrol.json SOURCES ${kdeconnect_mpriscontrol_SRCS}) kdeconnect_add_plugin(kdeconnect_mpriscontrol JSON kdeconnect_mpriscontrol.json SOURCES ${kdeconnect_mpriscontrol_SRCS})
target_link_libraries(kdeconnect_mpriscontrol Qt5::DBus kdeconnectcore) if(WIN32)
target_link_libraries(kdeconnect_mpriscontrol kdeconnectcore)
else()
target_link_libraries(kdeconnect_mpriscontrol Qt5::DBus kdeconnectcore)
endif()

View file

@ -0,0 +1,99 @@
#include "mpriscontrolplugin-win.h"
#include <core/device.h>
#include <KPluginFactory>
#include <Windows.h>
K_PLUGIN_FACTORY_WITH_JSON( KdeConnectPluginFactory, "kdeconnect_mpriscontrol.json", registerPlugin< MprisControlPlugin >(); )
Q_LOGGING_CATEGORY(KDECONNECT_PLUGIN_MPRIS, "kdeconnect.plugin.mpris")
MprisControlPlugin::MprisControlPlugin(QObject *parent, const QVariantList &args) : KdeConnectPlugin(parent, args) { }
bool MprisControlPlugin::receivePacket(const NetworkPacket &np)
{
if (np.has(QStringLiteral("playerList"))) {
return false; //Whoever sent this is an mpris client and not an mpris control!
}
//Send the player list
const QString player = np.get<QString>(QStringLiteral("player"));
bool valid_player = (player == playername);
if (!valid_player || np.get<bool>(QStringLiteral("requestPlayerList"))) {
const QList<QString> playerlist = {playername};
NetworkPacket np(PACKET_TYPE_MPRIS);
np.set(QStringLiteral("playerList"), playerlist);
np.set(QStringLiteral("supportAlbumArtPayload"), false);
sendPacket(np);
if (!valid_player) {
return true;
}
}
if (np.has(QStringLiteral("action"))) {
INPUT input={0};
input.type = INPUT_KEYBOARD;
input.ki.time = 0;
input.ki.dwExtraInfo = 0;
input.ki.wScan = 0;
input.ki.dwFlags = 0;
if (np.has(QStringLiteral("action"))) {
const QString& action = np.get<QString>(QStringLiteral("action"));
if (action == QStringLiteral("PlayPause") || (action == QStringLiteral("Play")) || (action == QStringLiteral("Pause")) ) {
input.ki.wVk = VK_MEDIA_PLAY_PAUSE;
::SendInput(1,&input,sizeof(INPUT));
}
else if (action == QStringLiteral("Stop")) {
input.ki.wVk = VK_MEDIA_STOP;
::SendInput(1,&input,sizeof(INPUT));
}
else if (action == QStringLiteral("Next")) {
input.ki.wVk = VK_MEDIA_NEXT_TRACK;
::SendInput(1,&input,sizeof(INPUT));
}
else if (action == QStringLiteral("Previous")) {
input.ki.wVk = VK_MEDIA_PREV_TRACK;
::SendInput(1,&input,sizeof(INPUT));
}
else if (action == QStringLiteral("Stop")) {
input.ki.wVk = VK_MEDIA_STOP;
::SendInput(1,&input,sizeof(INPUT));
}
}
}
NetworkPacket answer(PACKET_TYPE_MPRIS);
bool somethingToSend = false;
if (np.get<bool>(QStringLiteral("requestNowPlaying"))) {
answer.set(QStringLiteral("pos"), 0);
answer.set(QStringLiteral("isPlaying"), false);
answer.set(QStringLiteral("canPause"), false);
answer.set(QStringLiteral("canPlay"), true);
answer.set(QStringLiteral("canGoNext"), true);
answer.set(QStringLiteral("canGoPrevious"), true);
answer.set(QStringLiteral("canSeek"), false);
somethingToSend = true;
}
if (np.get<bool>(QStringLiteral("requestVolume"))) {
answer.set(QStringLiteral("volume"), 100);
somethingToSend = true;
}
if (somethingToSend) {
answer.set(QStringLiteral("player"), player);
sendPacket(answer);
}
return true;
}
#include "mpriscontrolplugin-win.moc"

View file

@ -0,0 +1,29 @@
#ifndef MPRISCONTROLPLUGINWIN_H
#define MPRISCONTROLPLUGINWIN_H
#include <core/kdeconnectplugin.h>
#include <QString>
#include <QLoggingCategory>
#define PLAYERNAME QStringLiteral("Media Player")
#define PACKET_TYPE_MPRIS QStringLiteral("kdeconnect.mpris")
Q_DECLARE_LOGGING_CATEGORY(KDECONNECT_PLUGIN_MPRIS)
class MprisControlPlugin
: public KdeConnectPlugin
{
Q_OBJECT
public:
explicit MprisControlPlugin(QObject *parent, const QVariantList &args);
bool receivePacket(const NetworkPacket &np) override;
void connected() override {}
private:
const QString playername = "Media Player";
};
#endif //MPRISCONTROLPLUGINWIN_H