1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2015-2016 Oleg Shparber 4 ** Copyright (C) 2013-2014 Jerzy Kozera 5 ** Contact: https://go.zealdocs.org/l/contact 6 ** 7 ** This file is part of Zeal. 8 ** 9 ** Zeal is free software: you can redistribute it and/or modify 10 ** it under the terms of the GNU General Public License as published by 11 ** the Free Software Foundation, either version 3 of the License, or 12 ** (at your option) any later version. 13 ** 14 ** Zeal is distributed in the hope that it will be useful, 15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 ** GNU General Public License for more details. 18 ** 19 ** You should have received a copy of the GNU General Public License 20 ** along with Zeal. If not, see <https://www.gnu.org/licenses/>. 21 ** 22 ****************************************************************************/ 23 /**************************************************************************** 24 ** Copyright (c) 2006 - 2011, the LibQxt project. 25 ** See the Qxt AUTHORS file for a list of authors and copyright holders. 26 ** All rights reserved. 27 ** 28 ** Redistribution and use in source and binary forms, with or without 29 ** modification, are permitted provided that the following conditions are met: 30 ** * Redistributions of source code must retain the above copyright 31 ** notice, this list of conditions and the following disclaimer. 32 ** * Redistributions in binary form must reproduce the above copyright 33 ** notice, this list of conditions and the following disclaimer in the 34 ** documentation and/or other materials provided with the distribution. 35 ** * Neither the name of the LibQxt project nor the 36 ** names of its contributors may be used to endorse or promote products 37 ** derived from this software without specific prior written permission. 38 ** 39 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 40 ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 41 ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 42 ** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY 43 ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 44 ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 45 ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 46 ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 47 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 48 ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 49 ** 50 ** <http://libqxt.org> <foundation@libqxt.org> 51 *****************************************************************************/ 52 53 #include "qxtglobalshortcut_p.h" 54 55 #include <qt_windows.h> 56 57 bool QxtGlobalShortcutPrivate::nativeEventFilter(const QByteArray &eventType, 58 void *message, long *result) 59 { 60 Q_UNUSED(eventType) 61 Q_UNUSED(result) 62 63 MSG *msg = static_cast<MSG *>(message); 64 if (msg->message == WM_HOTKEY) { 65 const quint32 keycode = HIWORD(msg->lParam); 66 const quint32 modifiers = LOWORD(msg->lParam); 67 activateShortcut(keycode, modifiers); 68 } 69 70 return false; 71 } 72 73 74 quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers) 75 { 76 // MOD_ALT, MOD_CONTROL, (MOD_KEYUP), MOD_SHIFT, MOD_WIN 77 quint32 native = 0; 78 if (modifiers & Qt::ShiftModifier) 79 native |= MOD_SHIFT; 80 if (modifiers & Qt::ControlModifier) 81 native |= MOD_CONTROL; 82 if (modifiers & Qt::AltModifier) 83 native |= MOD_ALT; 84 if (modifiers & Qt::MetaModifier) 85 native |= MOD_WIN; 86 // TODO: resolve these? 87 //if (modifiers & Qt::KeypadModifier) 88 //if (modifiers & Qt::GroupSwitchModifier) 89 return native; 90 } 91 92 quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key) 93 { 94 switch (key) { 95 case Qt::Key_Escape: 96 return VK_ESCAPE; 97 case Qt::Key_Tab: 98 case Qt::Key_Backtab: 99 return VK_TAB; 100 case Qt::Key_Backspace: 101 return VK_BACK; 102 case Qt::Key_Return: 103 case Qt::Key_Enter: 104 return VK_RETURN; 105 case Qt::Key_Insert: 106 return VK_INSERT; 107 case Qt::Key_Delete: 108 return VK_DELETE; 109 case Qt::Key_Pause: 110 return VK_PAUSE; 111 case Qt::Key_Print: 112 return VK_PRINT; 113 case Qt::Key_Clear: 114 return VK_CLEAR; 115 case Qt::Key_Home: 116 return VK_HOME; 117 case Qt::Key_End: 118 return VK_END; 119 case Qt::Key_Left: 120 return VK_LEFT; 121 case Qt::Key_Up: 122 return VK_UP; 123 case Qt::Key_Right: 124 return VK_RIGHT; 125 case Qt::Key_Down: 126 return VK_DOWN; 127 case Qt::Key_PageUp: 128 return VK_PRIOR; 129 case Qt::Key_PageDown: 130 return VK_NEXT; 131 case Qt::Key_F1: 132 return VK_F1; 133 case Qt::Key_F2: 134 return VK_F2; 135 case Qt::Key_F3: 136 return VK_F3; 137 case Qt::Key_F4: 138 return VK_F4; 139 case Qt::Key_F5: 140 return VK_F5; 141 case Qt::Key_F6: 142 return VK_F6; 143 case Qt::Key_F7: 144 return VK_F7; 145 case Qt::Key_F8: 146 return VK_F8; 147 case Qt::Key_F9: 148 return VK_F9; 149 case Qt::Key_F10: 150 return VK_F10; 151 case Qt::Key_F11: 152 return VK_F11; 153 case Qt::Key_F12: 154 return VK_F12; 155 case Qt::Key_F13: 156 return VK_F13; 157 case Qt::Key_F14: 158 return VK_F14; 159 case Qt::Key_F15: 160 return VK_F15; 161 case Qt::Key_F16: 162 return VK_F16; 163 case Qt::Key_F17: 164 return VK_F17; 165 case Qt::Key_F18: 166 return VK_F18; 167 case Qt::Key_F19: 168 return VK_F19; 169 case Qt::Key_F20: 170 return VK_F20; 171 case Qt::Key_F21: 172 return VK_F21; 173 case Qt::Key_F22: 174 return VK_F22; 175 case Qt::Key_F23: 176 return VK_F23; 177 case Qt::Key_F24: 178 return VK_F24; 179 case Qt::Key_Space: 180 return VK_SPACE; 181 case Qt::Key_Asterisk: 182 return VK_MULTIPLY; 183 case Qt::Key_Plus: 184 return VK_ADD; 185 case Qt::Key_Comma: 186 return VK_SEPARATOR; 187 case Qt::Key_Minus: 188 return VK_SUBTRACT; 189 case Qt::Key_Slash: 190 return VK_DIVIDE; 191 case Qt::Key_MediaNext: 192 return VK_MEDIA_NEXT_TRACK; 193 case Qt::Key_MediaPrevious: 194 return VK_MEDIA_PREV_TRACK; 195 case Qt::Key_MediaPlay: 196 return VK_MEDIA_PLAY_PAUSE; 197 case Qt::Key_MediaStop: 198 return VK_MEDIA_STOP; 199 // couldn't find those in VK_* 200 //case Qt::Key_MediaLast: 201 //case Qt::Key_MediaRecord: 202 case Qt::Key_VolumeDown: 203 return VK_VOLUME_DOWN; 204 case Qt::Key_VolumeUp: 205 return VK_VOLUME_UP; 206 case Qt::Key_VolumeMute: 207 return VK_VOLUME_MUTE; 208 209 // numbers 210 case Qt::Key_0: 211 case Qt::Key_1: 212 case Qt::Key_2: 213 case Qt::Key_3: 214 case Qt::Key_4: 215 case Qt::Key_5: 216 case Qt::Key_6: 217 case Qt::Key_7: 218 case Qt::Key_8: 219 case Qt::Key_9: 220 return key; 221 222 // letters 223 case Qt::Key_A: 224 case Qt::Key_B: 225 case Qt::Key_C: 226 case Qt::Key_D: 227 case Qt::Key_E: 228 case Qt::Key_F: 229 case Qt::Key_G: 230 case Qt::Key_H: 231 case Qt::Key_I: 232 case Qt::Key_J: 233 case Qt::Key_K: 234 case Qt::Key_L: 235 case Qt::Key_M: 236 case Qt::Key_N: 237 case Qt::Key_O: 238 case Qt::Key_P: 239 case Qt::Key_Q: 240 case Qt::Key_R: 241 case Qt::Key_S: 242 case Qt::Key_T: 243 case Qt::Key_U: 244 case Qt::Key_V: 245 case Qt::Key_W: 246 case Qt::Key_X: 247 case Qt::Key_Y: 248 case Qt::Key_Z: 249 return key; 250 251 default: 252 return 0; 253 } 254 } 255 256 bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods) 257 { 258 return RegisterHotKey(0, nativeMods ^ nativeKey, nativeMods, nativeKey); 259 } 260 261 bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods) 262 { 263 return UnregisterHotKey(0, nativeMods ^ nativeKey); 264 } 265