• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDEUI

  • kdeui
  • util
kkeyserver_mac.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2006 Marijn Kruisselbrink <m.kruisselbrink@student.tue.nl>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18 */
19
20#include "kkeyserver_mac.h"
21
22#include <config.h>
23
24#include <QtCore/QCOORD>
25
26#ifdef Q_WS_MACX // Only compile this module if we're compiling for Mac OS X
27
28#include "kshortcut.h"
29#include <kdebug.h>
30#include <QMultiMap>
31#include <Carbon/Carbon.h>
32
33namespace KKeyServer {
34 struct TransKey {
35 int qt_code;
36 int mac_code;
37 };
38
39 static TransKey qtKeyToChar[] = {
40 {Qt::Key_Escape, kEscapeCharCode},
41 {Qt::Key_Tab, kTabCharCode},
42 {Qt::Key_Backtab, kTabCharCode}, // Backtab == tab with different modifiers
43 {Qt::Key_Backspace, kBackspaceCharCode},
44 {Qt::Key_Return, kReturnCharCode},
45 {Qt::Key_Enter, kEnterCharCode},
46 // Insert
47 {Qt::Key_Delete, kDeleteCharCode},
48 // Pause, Print, SysReq
49 {Qt::Key_Clear, kClearCharCode},
50 {Qt::Key_Home, kHomeCharCode},
51 {Qt::Key_End, kEndCharCode},
52 {Qt::Key_Left, kLeftArrowCharCode},
53 {Qt::Key_Up, kUpArrowCharCode},
54 {Qt::Key_Right, kRightArrowCharCode},
55 {Qt::Key_Down, kDownArrowCharCode},
56 {Qt::Key_PageUp, kPageUpCharCode},
57 {Qt::Key_PageDown, kPageDownCharCode},
58 // Shift, Control, Meta, Alt, CapsLock, NumLock, ScrollLock
59 // Super_L, Super_R, Menu, Hyper_L, Hyper_R
60 {Qt::Key_Help, kHelpCharCode},
61 // Direction_L, Direction_R
62 {Qt::Key_nobreakspace, kNonBreakingSpaceCharCode},
63 {0, 0}
64 };
65
66 static QMultiMap<int, uint> scancodes;
67 static long lastLayoutID = -1;
68#ifdef QT_MAC_USE_COCOA
69 static TISInputSourceRef lastLayout = 0;
70#else
71 static KeyboardLayoutRef lastLayout = NULL;
72#endif
73
74 void updateScancodes() {
75#ifdef QT_MAC_USE_COCOA
76 TISInputSourceRef layout = TISCopyCurrentKeyboardLayoutInputSource();
77 if (!layout) {
78 kWarning() << "Error retrieving current layout";
79 return;
80 }
81 if (layout == lastLayout) {
82 CFRelease(layout);
83 } else {
84 // keyboard layout changed
85#ifndef NDEBUG
86 const void *name = TISGetInputSourceProperty(layout, kTISPropertyLocalizedName);
87 kDebug() << "Layout changed to: " << CFStringGetCStringPtr((CFStringRef)name, 0);
88#endif
89 lastLayout = layout;
90 scancodes.clear();
91
92 CFDataRef data = static_cast<CFDataRef>(TISGetInputSourceProperty(layout,
93 kTISPropertyUnicodeKeyLayoutData));
94 const UCKeyboardLayout *ucData = data ? reinterpret_cast<const UCKeyboardLayout *>(CFDataGetBytePtr(data)) : 0;
95
96 if (!ucData) {
97 kWarning() << "Error retrieving current layout character data";
98 return;
99 }
100
101 for (int i = 0; i < 128; ++i) {
102 UInt32 tmpState = 0;
103 UniChar str[4];
104 UniCharCount actualLength = 0;
105 OSStatus err = UCKeyTranslate(ucData, i, kUCKeyActionDown, 0, LMGetKbdType(),
106 kUCKeyTranslateNoDeadKeysMask, &tmpState, 4, &actualLength, str);
107 if (err != noErr) {
108 kWarning() << "Error translating unicode key" << err;
109 } else {
110 if (str[0] && str[0] != kFunctionKeyCharCode)
111 scancodes.insert(str[0], i);
112 }
113 }
114 }
115#else
116 KeyboardLayoutRef layout;
117 if (KLGetCurrentKeyboardLayout(&layout) != noErr) {
118 kWarning() << "Error retrieving current layout";
119 }
120 if (layout != lastLayout) {
121#ifndef NDEBUG
122 void *name;
123 KLGetKeyboardLayoutProperty(layout, kKLName, const_cast<const void**>(&name));
124 kDebug() << "Layout changed to: " << CFStringGetCStringPtr((CFStringRef) name, 0);
125#endif
126 lastLayout = layout;
127 scancodes.clear();
128 void *kchr;
129 if (KLGetKeyboardLayoutProperty(layout, kKLKCHRData, const_cast<const void**>(&kchr)) != noErr) {
130 kWarning() << "Couldn't load active keyboard layout";
131 } else {
132 for (int i = 0; i < 128; i++) {
133 UInt32 tmpState = 0;
134 UInt32 chr = KeyTranslate(kchr, i, &tmpState);
135 if (chr && chr != kFunctionKeyCharCode) {
136 scancodes.insert(chr, i);
137 }
138 }
139 }
140 }
141#endif
142 }
143
144#define SCANCODE(name, value) { Qt::Key_ ## name, value }
145 static TransKey functionKeys[] = {
146 SCANCODE(F1, 122),
147 SCANCODE(F2, 120),
148 SCANCODE(F3, 99),
149 SCANCODE(F4, 118),
150 SCANCODE(F5, 96),
151 SCANCODE(F6, 97),
152 SCANCODE(F7, 98),
153 SCANCODE(F8, 100),
154 SCANCODE(F9, 101),
155 SCANCODE(F10, 109),
156 //TODO: figure out scancodes of other F* keys
157 { 0, 0 }
158 };
159#undef SCANCODE
160
161 bool keyQtToSymMac( int keyQt, int& sym )
162 {
163 // Printable ascii values, before A
164 if (keyQt >= 0x20 && keyQt < Qt::Key_A) {
165 sym = keyQt;
166 return true;
167 }
168 // Letters, return lower-case equivalent
169 if (keyQt >= Qt::Key_A && keyQt <= Qt::Key_Z) {
170 sym = keyQt - Qt::Key_A + 'a';
171 return true;
172 }
173 // Printable ascii values up to lower-case a
174 if (keyQt > Qt::Key_Z && keyQt <= 0x60) {
175 sym = keyQt;
176 return true;
177 }
178 // Remainder of printable ascii values
179 if (keyQt >= 0x7B && keyQt < 0x7F) {
180 sym = keyQt;
181 return true;
182 }
183 // Function keys
184 if (keyQt >= Qt::Key_F1 && keyQt <= Qt::Key_F35) {
185 sym = kFunctionKeyCharCode;
186 return true;
187 }
188 // Try to find in lookup table
189 for (int i = 0; qtKeyToChar[i].qt_code; i++) {
190 if (qtKeyToChar[i].qt_code == keyQt) {
191 sym = qtKeyToChar[i].mac_code;
192 return true;
193 }
194 }
195
196 // Not found
197 return false;
198 }
199
200 bool keyQtToCodeMac( int keyQt, QList<uint>& keyCodes )
201 {
202 updateScancodes();
203 keyCodes.clear();
204 keyQt &= ~Qt::KeyboardModifierMask;
205 int chr;
206 if (!keyQtToSymMac( keyQt, chr ) ) return false;
207
208 if (chr == kFunctionKeyCharCode) {
209 for (int i = 0; functionKeys[i].qt_code; i++) {
210 if (functionKeys[i].qt_code == keyQt) {
211 keyCodes.append(functionKeys[i].mac_code);
212 }
213 }
214 } else {
215 keyCodes += scancodes.values(chr);
216 }
217
218 return keyCodes.count() > 0;
219 }
220
221 bool keyQtToModMac( int keyQt, uint& mod )
222 {
223 mod = 0;
224 if (keyQt & Qt::ShiftModifier) {
225 mod |= shiftKey;
226 }
227 if (keyQt & Qt::ControlModifier) {
228 mod |= cmdKey;
229 }
230 if (keyQt & Qt::AltModifier) {
231 mod |= optionKey;
232 }
233 if (keyQt & Qt::MetaModifier) {
234 mod |= controlKey;
235 }
236 if (keyQt & Qt::KeypadModifier) {
237 mod |= kEventKeyModifierNumLockMask;
238 }
239 // Special case for Qt::Key_Backtab
240 if ((keyQt & ~Qt::KeyboardModifierMask) == Qt::Key_Backtab) {
241 mod |= shiftKey;
242 }
243
244 return true;
245 }
246} // end of namespace KKeyServer
247
248#endif // Q_WS_MACX
249
QList
kDebug
#define kDebug
kWarning
#define kWarning
kdebug.h
kkeyserver_mac.h
kshortcut.h
Defines platform-independent classes for keyboard shortcut handling.
KKeyServer
A collection of functions for the conversion of key presses and their modifiers from the window syste...
Definition: kkeyserver.cpp:31
KKeyServer::keyQtToCodeMac
bool keyQtToCodeMac(int keyQt, QList< uint > &keyCodes)
Extracts all the scancodes from the given Qt key.
KKeyServer::keyQtToModMac
bool keyQtToModMac(int keyQt, uint &mod)
Extracts the modifiers from the given Qt key and converts them in a mask of OSX modifiers.
KKeyServer::keyQtToSymMac
bool keyQtToSymMac(int keyQt, int &sym)
Extracts the symbol from the given Qt key, and converts it to an OSX symbol.
KStandardAction::name
const char * name(StandardAction id)
This will return the internal name of a given standard action.
Definition: kstandardaction.cpp:223
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal