Warning: That file was not part of the compilation database. It may have many parsing errors.
1 | /* This file is part of the KDE libraries |
---|---|
2 | Copyright (C) 2001,2002 Ellis Whitehead <ellis@kde.org> |
3 | Copyright (C) 2006 Marijn Kruisselbrink <m.kruisselbrink@student.tue.nl> |
4 | |
5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Library General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2 of the License, or (at your option) any later version. |
9 | |
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 | Library General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Library General Public License |
16 | along with this library; see the file COPYING.LIB. If not, write to |
17 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | Boston, MA 02110-1301, USA. |
19 | */ |
20 | |
21 | #include "kglobalaccel_mac.h" |
22 | |
23 | #include <kdebug.h> |
24 | |
25 | #ifdef Q_WS_MAC |
26 | |
27 | #include <QMultiMap> |
28 | #include <QList> |
29 | |
30 | #include "globalshortcutsregistry.h" |
31 | #include "kkeyserver.h" |
32 | |
33 | OSStatus hotKeyEventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void * inUserData) |
34 | { |
35 | UInt32 eventKind = GetEventKind(inEvent); |
36 | if (eventKind == kEventRawKeyDown) { |
37 | UInt32 keycode; |
38 | if (GetEventParameter(inEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(keycode), NULL, &keycode) != noErr) { |
39 | kWarning(125) << "Error retrieving keycode parameter from event"; |
40 | } |
41 | kDebug() << " key down, keycode = "<< keycode; |
42 | } else if (eventKind == kEventHotKeyPressed) { |
43 | KGlobalAccelImpl* impl = static_cast<KGlobalAccelImpl *>(inUserData); |
44 | EventHotKeyID hotkey; |
45 | if (GetEventParameter(inEvent, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(hotkey), NULL, &hotkey) != noErr) { |
46 | kWarning(125) << "Error retrieving hotkey parameter from event"; |
47 | return eventNotHandledErr; |
48 | } |
49 | // Typecasts necesary to prevent a warning from gcc |
50 | return (impl->keyPressed(hotkey.id) ? (OSStatus) noErr : (OSStatus) eventNotHandledErr); |
51 | } |
52 | return eventNotHandledErr; |
53 | } |
54 | |
55 | void layoutChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { |
56 | static_cast<KGlobalAccelImpl *>(observer)->keyboardLayoutChanged(); |
57 | } |
58 | |
59 | KGlobalAccelImpl::KGlobalAccelImpl(GlobalShortcutsRegistry* owner) |
60 | : m_owner(owner) |
61 | , m_eventTarget(GetApplicationEventTarget()) |
62 | , m_eventHandler(NewEventHandlerUPP(hotKeyEventHandler)) |
63 | { |
64 | m_eventType[0].eventClass = kEventClassKeyboard; |
65 | m_eventType[0].eventKind = kEventHotKeyPressed; |
66 | m_eventType[1].eventClass = kEventClassKeyboard; // only useful for testing, is not used because count passed in call to InstallEventHandler is 1 |
67 | m_eventType[1].eventKind = kEventRawKeyDown; |
68 | refs = new QMap<int, QList<EventHotKeyRef> >(); |
69 | |
70 | CFStringRef str = CFStringCreateWithCString(NULL, "AppleKeyboardPreferencesChangedNotification", kCFStringEncodingASCII); |
71 | if (str) { |
72 | CFNotificationCenterAddObserver(CFNotificationCenterGetDistributedCenter(), this, layoutChanged, str, NULL, CFNotificationSuspensionBehaviorHold); |
73 | CFRelease(str); |
74 | } else { |
75 | kWarning(125) << "Couldn't create CFString to register for keyboard notifications"; |
76 | } |
77 | } |
78 | |
79 | KGlobalAccelImpl::~KGlobalAccelImpl() |
80 | { |
81 | DisposeEventHandlerUPP(hotKeyEventHandler); |
82 | CFNotificationCenterRemoveObserver(CFNotificationCenterGetDistributedCenter(), this, NULL, NULL); |
83 | delete refs; |
84 | } |
85 | |
86 | bool KGlobalAccelImpl::grabKey( int keyQt, bool grab ) |
87 | { |
88 | if (grab) { |
89 | kDebug() << "Grabbing key "<< keyQt; |
90 | QList<uint> keyCodes; |
91 | uint mod; |
92 | KKeyServer::keyQtToCodeMac( keyQt, keyCodes ); |
93 | KKeyServer::keyQtToModMac( keyQt, mod ); |
94 | |
95 | kDebug() << "keyQt: "<< keyQt << " mod: "<< mod; |
96 | foreach (uint keyCode, keyCodes) { |
97 | kDebug() << " keyCode: "<< keyCode; |
98 | } |
99 | |
100 | EventHotKeyID ehkid; |
101 | ehkid.signature = |
102 | ehkid.id = keyQt; |
103 | QList<EventHotKeyRef> hotkeys; |
104 | foreach (uint keyCode, keyCodes) { |
105 | EventHotKeyRef ref; |
106 | if (RegisterEventHotKey(keyCode, mod, ehkid, m_eventTarget, 0, &ref) != noErr) { |
107 | kWarning(125) << "RegisterEventHotKey failed!"; |
108 | } |
109 | hotkeys.append(ref); |
110 | } |
111 | refs->insert(keyQt, hotkeys); |
112 | } else { |
113 | kDebug() << "Ungrabbing key "<< keyQt; |
114 | if (refs->count(keyQt) == 0) kWarning(125) << "Trying to ungrab a key thas is not grabbed"; |
115 | foreach (const EventHotKeyRef &ref, refs->value(keyQt)) { |
116 | if (UnregisterEventHotKey(ref) != noErr) { |
117 | kWarning(125) << "UnregisterEventHotKey should not fail!"; |
118 | } |
119 | } |
120 | refs->remove(keyQt); |
121 | } |
122 | return true; |
123 | } |
124 | |
125 | void KGlobalAccelImpl::setEnabled(bool enable) |
126 | { |
127 | if (enable) { |
128 | if (InstallEventHandler(m_eventTarget, m_eventHandler, 1, m_eventType, this, &m_curHandler) != noErr) |
129 | kWarning(125) << "InstallEventHandler failed!"; |
130 | } else { |
131 | if (RemoveEventHandler(m_curHandler) != noErr) |
132 | kWarning(125) << "RemoveEventHandler failed!"; |
133 | } |
134 | } |
135 | |
136 | bool KGlobalAccelImpl::keyPressed( int key ) |
137 | { |
138 | return m_owner->keyPressed(key); |
139 | } |
140 | |
141 | void KGlobalAccelImpl::keyboardLayoutChanged() |
142 | { |
143 | // Keyboard layout might have changed, first ungrab all keys |
144 | QList<int> keys; // Array to store all the keys that were grabbed |
145 | while (!refs->empty()) { |
146 | int key = refs->begin().key(); |
147 | keys.append(key); |
148 | grabKey(key, false); |
149 | } |
150 | // Now re-grab all the keys |
151 | foreach (int key, keys) { |
152 | grabKey(key, true); |
153 | } |
154 | } |
155 | |
156 | #include "kglobalaccel_mac.moc" |
157 | |
158 | #endif // !Q_WS_MAC |
159 |
Warning: That file was not part of the compilation database. It may have many parsing errors.