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