diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index f0d5bb5c..2a7d63e4 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -1,30 +1,32 @@ include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}/core) add_definitions(-DTRANSLATION_DOMAIN=\"kdeconnect-plugins\") install(FILES kdeconnect_plugin.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR}) add_subdirectory(ping) add_subdirectory(clipboard) add_subdirectory(telephony) add_subdirectory(share) add_subdirectory(notifications) add_subdirectory(battery) add_subdirectory(remotecommands) add_subdirectory(findmyphone) add_subdirectory(remotekeyboard) -if(NOT WIN32) - add_subdirectory(runcommand) +if(WIN32) + add_subdirectory(mousepad_windows) +else() + add_subdirectory(runcommand) add_subdirectory(sendnotifications) add_subdirectory(pausemusic) add_subdirectory(mpriscontrol) add_subdirectory(mousepad) add_subdirectory(screensaver-inhibit) add_subdirectory(sftp) endif() if(EXPERIMENTALAPP_ENABLED) add_subdirectory(mprisremote) add_subdirectory(remotecontrol) add_subdirectory(lockdevice) endif() #FIXME: If we split notifications in several files, they won't appear in the same group in the Notifications KCM install(FILES kdeconnect.notifyrc DESTINATION ${KNOTIFYRC_INSTALL_DIR}) diff --git a/plugins/mousepad_windows/CMakeLists.txt b/plugins/mousepad_windows/CMakeLists.txt new file mode 100644 index 00000000..2fbe4db2 --- /dev/null +++ b/plugins/mousepad_windows/CMakeLists.txt @@ -0,0 +1,2 @@ +kdeconnect_add_plugin(kdeconnect_mousepad JSON kdeconnect_mousepad.json SOURCES mousepadplugin_windows.cpp) +target_link_libraries(kdeconnect_mousepad kdeconnectcore Qt5::Gui KF5::I18n) diff --git a/plugins/mousepad_windows/kdeconnect_mousepad.json b/plugins/mousepad_windows/kdeconnect_mousepad.json new file mode 100644 index 00000000..4274644a --- /dev/null +++ b/plugins/mousepad_windows/kdeconnect_mousepad.json @@ -0,0 +1,95 @@ +{ + "Encoding": "UTF-8", + "KPlugin": { + "Authors": [ + { + "Email": "ahmedibrahimkhali@gmail.com", + "Name": "Ahmed I. Khalil", + "Name[ar]": "أحمد إبراهيم خليل", + "Name[sr@ijekavian]": "Ахмед И. Калил", + "Name[sr@ijekavianlatin]": "Ahmed I. Kalil", + "Name[sr@latin]": "Ahmed I. Kalil", + "Name[sr]": "Ахмед И. Калил", + "Name[x-test]": "xxAhmed I. Khalilxx" + } + ], + "Description": "Use your phone as a touchpad and keyboard", + "Description[ar]": "استخدم الهاتف كفأرة ولوحة مفاتيح", + "Description[ca@valencia]": "Empra el telèfon com un ratolí tàctil i teclat", + "Description[ca]": "Empra el telèfon com un ratolí tàctil i teclat", + "Description[cs]": "Používejte svůj telefon jako touchpad a klávesnici", + "Description[da]": "Brug din telefon som touchpad og tastatur", + "Description[de]": "Verwendet Ihr Handy als Touchpad und Tastatur", + "Description[el]": "Χρήση του τηλεφώνου σας ως οθόνη αφής και πληκτρολογίου", + "Description[es]": "Usar teléfono como panel táctil y teclado", + "Description[et]": "Telefoni kasutamine puutepadja ja klaviatuurina", + "Description[fi]": "Käytä puhelintasi kosketuslevynä ja näppäimistönä", + "Description[fr]": "Utilisez votre téléphone comme un pavé tactile et un clavier", + "Description[gl]": "Usar o teléfono móbil como touchpad e teclado.", + "Description[hu]": "A telefon használata érintőtáblaként és billentyűzetként", + "Description[it]": "Usa il telefono come touchpad e tastiera", + "Description[ko]": "휴대폰을 터치패드와 키보드로 사용", + "Description[nl]": "Uw telefoon gebruiken als een touchpad en toetsenbord", + "Description[nn]": "Bruk telefonen som styreplate og tastatur", + "Description[pl]": "Używaj swojego telefonu jako gładzika i klawiatury", + "Description[pt]": "Use o seu telefone como um rato e teclado por toque", + "Description[pt_BR]": "Use seu telefone como um touchpad e teclado", + "Description[ru]": "Использование телефона в качестве сенсорной панели и клавиатуры", + "Description[sk]": "Použite váš telefón ako touchpad a klávesnicu", + "Description[sr@ijekavian]": "Користите телефон као додирник и тастатуру", + "Description[sr@ijekavianlatin]": "Koristite telefon kao dodirnik i tastaturu", + "Description[sr@latin]": "Koristite telefon kao dodirnik i tastaturu", + "Description[sr]": "Користите телефон као додирник и тастатуру", + "Description[sv]": "Använd telefonen som mus och tangentbord", + "Description[tr]": "Telefonunuzu dokunmatik yüzey ve klayve olarak kullanın", + "Description[uk]": "Скористайтеся телефоном як замінником сенсорної панелі і клавіатури", + "Description[x-test]": "xxUse your phone as a touchpad and keyboardxx", + "Description[zh_CN]": "用您的手机作为触摸板和键盘", + "Description[zh_TW]": "讓您的智慧型手機當作觸碰板與鍵盤", + "EnabledByDefault": true, + "Icon": "edit-select", + "Id": "kdeconnect_mousepad", + "License": "GPL", + "Name": "Virtual input", + "Name[ar]": "دخل وهميّ", + "Name[ca@valencia]": "Entrada virtual", + "Name[ca]": "Entrada virtual", + "Name[cs]": "Virtuální vstup", + "Name[da]": "Virtuelt input", + "Name[de]": "Virtuelle Eingabe", + "Name[el]": "Εικονικά στοιχεία εισόδου", + "Name[es]": "Entrada virtual", + "Name[et]": "Virtuaalsisestus", + "Name[fi]": "Virtuaalinen syöttö", + "Name[fr]": "Entrée virtuelle", + "Name[gl]": "Entrada virtual", + "Name[hu]": "Virtuális bevitel", + "Name[it]": "Inserimento virtuale", + "Name[ko]": "가상 입력", + "Name[nl]": "Virtuele invoer", + "Name[nn]": "Virtuelt tastatur", + "Name[pl]": "Wirtualna obsługa", + "Name[pt]": "Entrada virtual", + "Name[pt_BR]": "Entrada virtual", + "Name[ru]": "Виртуальный ввод", + "Name[sk]": "Virtuálny vstup", + "Name[sr@ijekavian]": "Виртуелни унос", + "Name[sr@ijekavianlatin]": "Virtuelni unos", + "Name[sr@latin]": "Virtuelni unos", + "Name[sr]": "Виртуелни унос", + "Name[sv]": "Virtuell inmatning", + "Name[tr]": "Sanal içe aktarma", + "Name[uk]": "Віртуальне введення даних", + "Name[x-test]": "xxVirtual inputxx", + "Name[zh_CN]": "虚拟输入", + "Name[zh_TW]": "虛擬輸入", + "ServiceTypes": [ + "KdeConnect/Plugin" + ], + "Version": "0.1" + }, + "X-KdeConnect-OutgoingPackageType": [], + "X-KdeConnect-SupportedPackageType": [ + "kdeconnect.mousepad.request" + ] +} diff --git a/plugins/mousepad_windows/mousepadplugin_windows.cpp b/plugins/mousepad_windows/mousepadplugin_windows.cpp new file mode 100644 index 00000000..31cfc927 --- /dev/null +++ b/plugins/mousepad_windows/mousepadplugin_windows.cpp @@ -0,0 +1,150 @@ +/** + * Copyright 2014 Ahmed I. Khalil + * Copyright 2015 Martin Gräßlin + * + * 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) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * 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, see . + */ + +#include "mousepadplugin_windows.h" +#include +#include +#include +#include +#include + +#include + +K_PLUGIN_FACTORY_WITH_JSON( KdeConnectPluginFactory, "kdeconnect_mousepad.json", registerPlugin< MousepadPlugin >(); ) + +MousepadPlugin::MousepadPlugin(QObject* parent, const QVariantList& args) + : KdeConnectPlugin(parent, args) +{ +} + +MousepadPlugin::~MousepadPlugin() +{ +} + +bool MousepadPlugin::receivePackage(const NetworkPackage& np) +{ + float dx = np.get(QStringLiteral("dx"), 0); + float dy = np.get(QStringLiteral("dy"), 0); + + bool isSingleClick = np.get(QStringLiteral("singleclick"), false); + bool isDoubleClick = np.get(QStringLiteral("doubleclick"), false); + bool isMiddleClick = np.get(QStringLiteral("middleclick"), false); + bool isRightClick = np.get(QStringLiteral("rightclick"), false); + bool isSingleHold = np.get(QStringLiteral("singlehold"), false); + bool isSingleRelease = np.get(QStringLiteral("singlerelease"), false); + bool isScroll = np.get(QStringLiteral("scroll"), false); + QString key = np.get(QStringLiteral("key"), QLatin1String("")); + int specialKey = np.get(QStringLiteral("specialKey"), 0); + + if (isSingleClick || isDoubleClick || isMiddleClick || isRightClick || isSingleHold || isScroll || !key.isEmpty() || specialKey) { + + INPUT input={0}; + input.type = INPUT_MOUSE; + + if (isSingleClick) { + input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN; + ::SendInput(1,&input,sizeof(INPUT)); + input.mi.dwFlags = MOUSEEVENTF_LEFTUP; + ::SendInput(1,&input,sizeof(INPUT)); + } else if (isDoubleClick) { + input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN; + ::SendInput(1,&input,sizeof(INPUT)); + input.mi.dwFlags = MOUSEEVENTF_LEFTUP; + ::SendInput(1,&input,sizeof(INPUT)); + input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN; + ::SendInput(1,&input,sizeof(INPUT)); + input.mi.dwFlags = MOUSEEVENTF_LEFTUP; + ::SendInput(1,&input,sizeof(INPUT)); + } else if (isMiddleClick) { + input.mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN; + ::SendInput(1,&input,sizeof(INPUT)); + input.mi.dwFlags = MOUSEEVENTF_MIDDLEUP; + ::SendInput(1,&input,sizeof(INPUT)); + } else if (isRightClick) { + input.mi.dwFlags = MOUSEEVENTF_RIGHTDOWN; + ::SendInput(1,&input,sizeof(INPUT)); + input.mi.dwFlags = MOUSEEVENTF_RIGHTUP; + ::SendInput(1,&input,sizeof(INPUT)); + } else if (isSingleHold){ + input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN; + ::SendInput(1,&input,sizeof(INPUT)); + } else if (isSingleRelease){ + input.mi.dwFlags = MOUSEEVENTF_LEFTUP; + ::SendInput(1,&input,sizeof(INPUT)); + } else if (isScroll) { + input.mi.dwFlags = MOUSEEVENTF_WHEEL; + input.mi.mouseData = dy; + ::SendInput(1,&input,sizeof(INPUT)); +/* + } else if (!key.isEmpty() || specialKey) { + + bool ctrl = np.get(QStringLiteral("ctrl"), false); + bool alt = np.get(QStringLiteral("alt"), false); + bool shift = np.get(QStringLiteral("shift"), false); + + if (ctrl) XTestFakeKeyEvent (display, XKeysymToKeycode(display, XK_Control_L), True, 0); + if (alt) XTestFakeKeyEvent (display, XKeysymToKeycode(display, XK_Alt_L), True, 0); + if (shift) XTestFakeKeyEvent (display, XKeysymToKeycode(display, XK_Shift_L), True, 0); + + if (specialKey) + { + if (specialKey >= (int)arraySize(SpecialKeysMap)) { + qWarning() << "Unsupported special key identifier"; + return false; + } + + int keycode = XKeysymToKeycode(display, SpecialKeysMap[specialKey]); + + XTestFakeKeyEvent (display, keycode, True, 0); + XTestFakeKeyEvent (display, keycode, False, 0); + + } else { + + if (!m_fakekey) { + m_fakekey = fakekey_init(display); + if (!m_fakekey) { + qWarning() << "Failed to initialize libfakekey"; + return false; + } + } + + //We use fakekey here instead of XTest (above) because it can handle utf characters instead of keycodes. + for (int i=0;i + * + * 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) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * 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, see . + */ + +#ifndef MOUSEPADPLUGIN_H +#define MOUSEPADPLUGIN_H + +#include +#include + +#include + +class MousepadPlugin + : public KdeConnectPlugin +{ + Q_OBJECT + +public: + explicit MousepadPlugin(QObject *parent, const QVariantList &args); + ~MousepadPlugin() override; + + bool receivePackage(const NetworkPackage& np) override; + void connected() override { } +}; + +#endif