2
* globalaccelman_win.cpp - manager for global hotkeys
3
* Copyright (C) 2003 Justin Karneges
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2.1 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
// - don't invoke hotkey if there is a modal dialog?
23
// - do multi-mapping, like the x11 version
25
#include"globalaccelman.h"
27
#include<qkeysequence.h>
33
// We'll start our hotkeys at offset 0x1000 in the Windows hotkey table (no real reason)
34
#define HOTKEY_START 0x1000
41
{ Qt::Key_Escape, VK_ESCAPE },
42
{ Qt::Key_Tab, VK_TAB },
43
{ Qt::Key_Backtab, 0 },
44
{ Qt::Key_Backspace, VK_BACK },
45
{ Qt::Key_Return, VK_RETURN },
46
{ Qt::Key_Enter, VK_RETURN },
47
{ Qt::Key_Insert, VK_INSERT },
48
{ Qt::Key_Delete, VK_DELETE },
49
{ Qt::Key_Pause, VK_PAUSE },
50
{ Qt::Key_Print, VK_PRINT },
51
{ Qt::Key_SysReq, 0 },
52
{ Qt::Key_Clear, VK_CLEAR },
53
{ Qt::Key_Home, VK_HOME },
54
{ Qt::Key_End, VK_END },
55
{ Qt::Key_Left, VK_LEFT },
56
{ Qt::Key_Up, VK_UP },
57
{ Qt::Key_Right, VK_RIGHT },
58
{ Qt::Key_Down, VK_DOWN },
59
{ Qt::Key_Prior, VK_PRIOR },
60
{ Qt::Key_Next, VK_NEXT },
61
{ Qt::Key_Shift, VK_SHIFT },
62
{ Qt::Key_Control, VK_CONTROL },
63
{ Qt::Key_Meta, VK_LWIN },
64
{ Qt::Key_Alt, VK_MENU },
65
{ Qt::Key_CapsLock, VK_CAPITAL },
66
{ Qt::Key_NumLock, VK_NUMLOCK },
67
{ Qt::Key_ScrollLock, VK_SCROLL },
68
{ Qt::Key_F1, VK_F1 },
69
{ Qt::Key_F2, VK_F2 },
70
{ Qt::Key_F3, VK_F3 },
71
{ Qt::Key_F4, VK_F4 },
72
{ Qt::Key_F5, VK_F5 },
73
{ Qt::Key_F6, VK_F6 },
74
{ Qt::Key_F7, VK_F7 },
75
{ Qt::Key_F8, VK_F8 },
76
{ Qt::Key_F9, VK_F9 },
77
{ Qt::Key_F10, VK_F10 },
78
{ Qt::Key_F11, VK_F11 },
79
{ Qt::Key_F12, VK_F12 },
80
{ Qt::Key_F13, VK_F13 },
81
{ Qt::Key_F14, VK_F14 },
82
{ Qt::Key_F15, VK_F15 },
83
{ Qt::Key_F16, VK_F16 },
84
{ Qt::Key_F17, VK_F17 },
85
{ Qt::Key_F18, VK_F18 },
86
{ Qt::Key_F19, VK_F19 },
87
{ Qt::Key_F20, VK_F20 },
88
{ Qt::Key_F21, VK_F21 },
89
{ Qt::Key_F22, VK_F22 },
90
{ Qt::Key_F23, VK_F23 },
91
{ Qt::Key_F24, VK_F24 },
103
{ Qt::Key_Super_L, 0 },
104
{ Qt::Key_Super_R, 0 },
106
{ Qt::Key_Hyper_L, 0 },
107
{ Qt::Key_Hyper_R, 0 },
109
{ Qt::Key_Direction_L,0 },
110
{ Qt::Key_Direction_R,0 },
112
{ Qt::Key_unknown, 0 },
115
static bool convertKeySequence(const QKeySequence &ks, UINT *_mod, UINT *_key)
131
if(code >= 0x20 && code <= 0x7f)
134
for(int n = 0; qt_vk_table[n].key != Qt::Key_unknown; ++n) {
135
if(qt_vk_table[n].key == code) {
136
key = qt_vk_table[n].vk;
155
WindowsHotKey(HWND _w, int _win_key_id, int _id)
158
win_key_id = _win_key_id;
164
UnregisterHotKey(w, win_key_id);
168
int win_key_id; // Windows hotkey slot number
169
int id; // GlobalAccelManager unique ID for this hotkey
172
class GlobalAccelManager::Private
175
Private(GlobalAccelManager *par)
179
hidden = new HiddenWidget(this);
180
list.setAutoDelete(true);
188
int getFreeSlot() const
190
QPtrListIterator<WindowsHotKey> it(list);
191
// find first non-match
192
int n = HOTKEY_START;
193
for(WindowsHotKey *hk = 0; (hk = it.current()); ++it) {
194
if(hk->win_key_id != n)
201
int insertHotKey(int win_key_id)
203
WindowsHotKey *hk = new WindowsHotKey(hidden->winId(), win_key_id, id_at++);
204
if(win_key_id >= (int)list.count())
207
list.insert(win_key_id - HOTKEY_START, hk);
211
void hotkeyActivated(int win_key_id)
213
QPtrListIterator<WindowsHotKey> it(list);
214
for(WindowsHotKey *hk = 0; (hk = it.current()); ++it) {
215
if(hk->win_key_id == win_key_id)
216
manager->triggerActivated(hk->id);
220
class HiddenWidget : public QWidget
223
HiddenWidget(Private *_p)
229
bool winEvent(MSG *m)
231
m->message &= 0xffff;
232
if(m->message == WM_HOTKEY) {
233
p->hotkeyActivated(m->wParam);
236
return QWidget::winEvent(m);
243
GlobalAccelManager *manager;
245
HiddenWidget *hidden;
246
QPtrList<WindowsHotKey> list;
249
GlobalAccelManager::GlobalAccelManager()
251
d = new Private(this);
254
GlobalAccelManager::~GlobalAccelManager()
259
int GlobalAccelManager::setAccel(const QKeySequence &ks)
262
if(!convertKeySequence(ks, &mod, &key))
265
int win_key_id = d->getFreeSlot();
267
if(!RegisterHotKey(d->hidden->winId(), win_key_id, mod, key))
270
return d->insertHotKey(win_key_id);
273
void GlobalAccelManager::removeAccel(int id)
275
QPtrListIterator<WindowsHotKey> it(d->list);
276
for(WindowsHotKey *hk = 0; (hk = it.current()); ++it) {
278
d->list.removeRef(hk);