Warning, /network/kdeconnect-kde/plugins/mousepad/macosremoteinput.mm is written in an unsupported language. File is not indexed.
0001 /** 0002 * SPDX-FileCopyrightText: 2019 Weixuan XIAO <veyx.shaw@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "macosremoteinput.h" 0008 0009 #include <QCursor> 0010 #include <QDebug> 0011 0012 #include <CoreGraphics/CGEvent.h> 0013 #include <Carbon/Carbon.h> 0014 #include <ApplicationServices/ApplicationServices.h> 0015 0016 int SpecialKeysMap[] = { 0017 0, // Invalid 0018 kVK_Delete, // 1 0019 kVK_Tab, // 2 0020 kVK_Return, // 3 0021 kVK_LeftArrow, // 4 0022 kVK_UpArrow, // 5 0023 kVK_RightArrow, // 6 0024 kVK_DownArrow, // 7 0025 kVK_PageUp, // 8 0026 kVK_PageDown, // 9 0027 kVK_Home, // 10 0028 kVK_End, // 11 0029 kVK_Return, // 12 0030 kVK_ForwardDelete, // 13 0031 kVK_Escape, // 14 0032 0, // 15 0033 0, // 16 0034 0, // 17 0035 0, // 18 0036 0, // 19 0037 0, // 20 0038 kVK_F1, // 21 0039 kVK_F2, // 22 0040 kVK_F3, // 23 0041 kVK_F4, // 24 0042 kVK_F5, // 25 0043 kVK_F6, // 26 0044 kVK_F7, // 27 0045 kVK_F8, // 28 0046 kVK_F9, // 29 0047 kVK_F10, // 30 0048 kVK_F11, // 31 0049 kVK_F12, // 32 0050 }; 0051 0052 template <typename T, size_t N> 0053 size_t arraySize(T(&arr)[N]) { (void)arr; return N; } 0054 0055 MacOSRemoteInput::MacOSRemoteInput(QObject* parent) 0056 : AbstractRemoteInput(parent) 0057 { 0058 // Ask user to enable accessibility API 0059 NSDictionary *options = @{(id)kAXTrustedCheckOptionPrompt: @YES}; 0060 if (!AXIsProcessTrustedWithOptions((CFDictionaryRef)options)) { 0061 qWarning() << "kdeconnectd is not set as a trusted accessibility, mousepad and keyboard will not work"; 0062 } 0063 } 0064 0065 bool MacOSRemoteInput::handlePacket(const NetworkPacket& np) 0066 { 0067 // Return if not trusted 0068 if (!AXIsProcessTrusted()) { 0069 return false; 0070 } 0071 0072 float dx = np.get<float>(QStringLiteral("dx"), 0); 0073 float dy = np.get<float>(QStringLiteral("dy"), 0); 0074 0075 bool isSingleClick = np.get<bool>(QStringLiteral("singleclick"), false); 0076 bool isDoubleClick = np.get<bool>(QStringLiteral("doubleclick"), false); 0077 bool isMiddleClick = np.get<bool>(QStringLiteral("middleclick"), false); 0078 bool isRightClick = np.get<bool>(QStringLiteral("rightclick"), false); 0079 bool isSingleHold = np.get<bool>(QStringLiteral("singlehold"), false); 0080 bool isSingleRelease = np.get<bool>(QStringLiteral("singlerelease"), false); 0081 bool isScroll = np.get<bool>(QStringLiteral("scroll"), false); 0082 QString key = np.get<QString>(QStringLiteral("key"), QLatin1String("")); 0083 int specialKey = np.get<int>(QStringLiteral("specialKey"), 0); 0084 0085 if (isSingleClick || isDoubleClick || isMiddleClick || isRightClick || isSingleHold || isSingleRelease || isScroll || !key.isEmpty() || specialKey) { 0086 QPoint point = QCursor::pos(); 0087 0088 if (isSingleClick) { 0089 CGEventRef event = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDown, CGPointMake(point.x(), point.y()), kCGMouseButtonLeft); 0090 CGEventPost(kCGHIDEventTap, event); 0091 CGEventSetType(event, kCGEventLeftMouseUp); 0092 CGEventPost(kCGHIDEventTap, event); 0093 CFRelease(event); 0094 } else if (isDoubleClick) { 0095 CGEventRef event = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDown, CGPointMake(point.x(), point.y()), kCGMouseButtonLeft); 0096 CGEventPost(kCGHIDEventTap, event); 0097 CGEventSetType(event, kCGEventLeftMouseUp); 0098 CGEventPost(kCGHIDEventTap, event); 0099 0100 /* Key to access an integer field that contains the mouse button click 0101 state. A click state of 1 represents a single click. A click state of 2 0102 represents a double-click. A click state of 3 represents a 0103 triple-click. */ 0104 CGEventSetIntegerValueField(event, kCGMouseEventClickState, 2); 0105 0106 CGEventSetType(event, kCGEventLeftMouseDown); 0107 CGEventPost(kCGHIDEventTap, event); 0108 CGEventSetType(event, kCGEventLeftMouseUp); 0109 CGEventPost(kCGHIDEventTap, event); 0110 CFRelease(event); 0111 } else if (isMiddleClick) { 0112 CGEventRef event = CGEventCreateMouseEvent(NULL, kCGEventOtherMouseDown, CGPointMake(point.x(), point.y()), kCGMouseButtonLeft); 0113 CGEventPost(kCGHIDEventTap, event); 0114 CGEventSetType(event, kCGEventOtherMouseUp); 0115 CGEventPost(kCGHIDEventTap, event); 0116 CFRelease(event); 0117 } else if (isRightClick) { 0118 CGEventRef event = CGEventCreateMouseEvent(NULL, kCGEventRightMouseDown, CGPointMake(point.x(), point.y()), kCGMouseButtonLeft); 0119 CGEventPost(kCGHIDEventTap, event); 0120 CGEventSetType(event, kCGEventRightMouseUp); 0121 CGEventPost(kCGHIDEventTap, event); 0122 CFRelease(event); 0123 } else if (isSingleHold) { 0124 CGEventRef event = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDown, CGPointMake(point.x(), point.y()), kCGMouseButtonLeft); 0125 CGEventPost(kCGHIDEventTap, event); 0126 CFRelease(event); 0127 } else if (isSingleRelease) { 0128 CGEventRef event = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseUp, CGPointMake(point.x(), point.y()), kCGMouseButtonLeft); 0129 CGEventPost(kCGHIDEventTap, event); 0130 CFRelease(event); 0131 } else if (isScroll) { 0132 CGEventRef event = CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitPixel, 1, dy); 0133 CGEventPost(kCGHIDEventTap, event); 0134 CFRelease(event); 0135 } else if (!key.isEmpty() || specialKey) { 0136 // Get function keys 0137 bool ctrl = np.get<bool>(QStringLiteral("ctrl"), false); 0138 bool alt = np.get<bool>(QStringLiteral("alt"), false); 0139 bool shift = np.get<bool>(QStringLiteral("shift"), false); 0140 bool super = np.get<bool>(QStringLiteral("super"), false); 0141 0142 0143 if (ctrl) { 0144 CGEventRef ctrlEvent = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)kVK_Control, true); 0145 CGEventPost(kCGHIDEventTap, ctrlEvent); 0146 CFRelease(ctrlEvent); 0147 } 0148 if (alt) { 0149 CGEventRef optionEvent = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)kVK_Option, true); 0150 CGEventPost(kCGHIDEventTap, optionEvent); 0151 CFRelease(optionEvent); 0152 } 0153 if (shift) { 0154 CGEventRef shiftEvent = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)kVK_Shift, true); 0155 CGEventPost(kCGHIDEventTap, shiftEvent); 0156 CFRelease(shiftEvent); 0157 } 0158 if (super) { 0159 CGEventRef commandEvent = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)kVK_Command, true); 0160 CGEventPost(kCGHIDEventTap, commandEvent); 0161 CFRelease(commandEvent); 0162 } 0163 0164 // Keys 0165 if (specialKey) 0166 { 0167 if (specialKey >= (int)arraySize(SpecialKeysMap)) { 0168 qWarning() << "Unsupported special key identifier"; 0169 return false; 0170 } 0171 0172 CGEventRef specialKeyDownEvent = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)SpecialKeysMap[specialKey], true), 0173 specialKeyUpEvent = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)SpecialKeysMap[specialKey], false); 0174 0175 CGEventPost(kCGHIDEventTap, specialKeyDownEvent); 0176 CGEventPost(kCGHIDEventTap, specialKeyUpEvent); 0177 0178 CFRelease(specialKeyDownEvent); 0179 CFRelease(specialKeyUpEvent); 0180 } else { 0181 for (int i = 0; i < key.length(); i++) { 0182 const UniChar unicharData = (const UniChar)key.at(i).unicode(); 0183 0184 CGEventRef event = CGEventCreateKeyboardEvent(NULL, 0, true); 0185 0186 CGEventKeyboardSetUnicodeString(event, 1, &unicharData); 0187 CGEventPost(kCGSessionEventTap, event); 0188 0189 CFRelease(event); 0190 } 0191 0192 } 0193 0194 if (ctrl) { 0195 CGEventRef ctrlEvent = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)kVK_Control, false); 0196 CGEventPost(kCGHIDEventTap, ctrlEvent); 0197 CFRelease(ctrlEvent); 0198 } 0199 if (alt) { 0200 CGEventRef optionEvent = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)kVK_Option, false); 0201 CGEventPost(kCGHIDEventTap, optionEvent); 0202 CFRelease(optionEvent); 0203 } 0204 if (shift) { 0205 CGEventRef shiftEvent = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)kVK_Shift, false); 0206 CGEventPost(kCGHIDEventTap, shiftEvent); 0207 CFRelease(shiftEvent); 0208 } 0209 if (super) { 0210 CGEventRef commandEvent = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)kVK_Command, false); 0211 CGEventPost(kCGHIDEventTap, commandEvent); 0212 CFRelease(commandEvent); 0213 } 0214 0215 } 0216 } else { //Is a mouse move event 0217 QPoint point = QCursor::pos(); 0218 QCursor::setPos(point.x() + (int)dx, point.y() + (int)dy); 0219 } 0220 return true; 0221 } 0222 0223 bool MacOSRemoteInput::hasKeyboardSupport() { 0224 return true; 0225 } 0226 0227 #include "moc_macosremoteinput.cpp"