00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kkeyserver_mac.h"
00021
00022 #include <config.h>
00023
00024 #include <QtCore/QCOORD>
00025
00026 #ifdef Q_WS_MACX // Only compile this module if we're compiling for Mac OS X
00027
00028 #include "kshortcut.h"
00029 #include <kdebug.h>
00030 #include <QMultiMap>
00031 #include <Carbon/Carbon.h>
00032
00033 namespace KKeyServer {
00034 struct TransKey {
00035 int qt_code;
00036 int mac_code;
00037 };
00038
00039 static TransKey qtKeyToChar[] = {
00040 {Qt::Key_Escape, kEscapeCharCode},
00041 {Qt::Key_Tab, kTabCharCode},
00042 {Qt::Key_Backtab, kTabCharCode},
00043 {Qt::Key_Backspace, kBackspaceCharCode},
00044 {Qt::Key_Return, kReturnCharCode},
00045 {Qt::Key_Enter, kEnterCharCode},
00046
00047 {Qt::Key_Delete, kDeleteCharCode},
00048
00049 {Qt::Key_Clear, kClearCharCode},
00050 {Qt::Key_Home, kHomeCharCode},
00051 {Qt::Key_End, kEndCharCode},
00052 {Qt::Key_Left, kLeftArrowCharCode},
00053 {Qt::Key_Up, kUpArrowCharCode},
00054 {Qt::Key_Right, kRightArrowCharCode},
00055 {Qt::Key_Down, kDownArrowCharCode},
00056 {Qt::Key_PageUp, kPageUpCharCode},
00057 {Qt::Key_PageDown, kPageDownCharCode},
00058
00059
00060 {Qt::Key_Help, kHelpCharCode},
00061
00062 {Qt::Key_nobreakspace, kNonBreakingSpaceCharCode},
00063 {0, 0}
00064 };
00065
00066 static QMultiMap<int, uint> scancodes;
00067 static long lastLayoutID = -1;
00068 static KeyboardLayoutRef lastLayout = NULL;
00069
00070 void updateScancodes() {
00071 KeyboardLayoutRef layout;
00072 if (KLGetCurrentKeyboardLayout(&layout) != noErr) {
00073 kWarning() << "Error retrieving current layout";
00074 }
00075 if (layout != lastLayout) {
00076 #ifndef NDEBUG
00077 void *name;
00078 KLGetKeyboardLayoutProperty(layout, kKLName, const_cast<const void**>(&name));
00079 kDebug() << "Layout changed to: " << CFStringGetCStringPtr((CFStringRef) name, 0);
00080 #endif
00081 lastLayout = layout;
00082 scancodes.clear();
00083 void *kchr;
00084 if (KLGetKeyboardLayoutProperty(layout, kKLKCHRData, const_cast<const void**>(&kchr)) != noErr) {
00085 kWarning() << "Couldn't load active keyboard layout";
00086 } else {
00087 for (int i = 0; i < 128; i++) {
00088 UInt32 tmpState = 0;
00089 UInt32 chr = KeyTranslate(kchr, i, &tmpState);
00090 if (chr && chr != kFunctionKeyCharCode) {
00091 scancodes.insert(chr, i);
00092 }
00093 }
00094 }
00095 }
00096 }
00097
00098 #define SCANCODE(name, value) { Qt::Key_ ## name, value }
00099 static TransKey functionKeys[] = {
00100 SCANCODE(F1, 122),
00101 SCANCODE(F2, 120),
00102 SCANCODE(F3, 99),
00103 SCANCODE(F4, 118),
00104 SCANCODE(F5, 96),
00105 SCANCODE(F6, 97),
00106 SCANCODE(F7, 98),
00107 SCANCODE(F8, 100),
00108 SCANCODE(F9, 101),
00109 SCANCODE(F10, 109),
00110
00111 { 0, 0 }
00112 };
00113 #undef SCANCODE
00114
00115 bool keyQtToSymMac( int keyQt, int& sym )
00116 {
00117
00118 if (keyQt >= 0x20 && keyQt < Qt::Key_A) {
00119 sym = keyQt;
00120 return true;
00121 }
00122
00123 if (keyQt >= Qt::Key_A && keyQt <= Qt::Key_Z) {
00124 sym = keyQt - Qt::Key_A + 'a';
00125 return true;
00126 }
00127
00128 if (keyQt > Qt::Key_Z && keyQt <= 0x60) {
00129 sym = keyQt;
00130 return true;
00131 }
00132
00133 if (keyQt >= 0x7B && keyQt < 0x7F) {
00134 sym = keyQt;
00135 return true;
00136 }
00137
00138 if (keyQt >= Qt::Key_F1 && keyQt <= Qt::Key_F35) {
00139 sym = kFunctionKeyCharCode;
00140 return true;
00141 }
00142
00143 for (int i = 0; qtKeyToChar[i].qt_code; i++) {
00144 if (qtKeyToChar[i].qt_code == keyQt) {
00145 sym = qtKeyToChar[i].mac_code;
00146 return true;
00147 }
00148 }
00149
00150
00151 return false;
00152 }
00153
00154 bool keyQtToCodeMac( int keyQt, QList<uint>& keyCodes )
00155 {
00156 updateScancodes();
00157 keyCodes.clear();
00158 keyQt &= ~Qt::KeyboardModifierMask;
00159 int chr;
00160 if (!keyQtToSymMac( keyQt, chr ) ) return false;
00161
00162 if (chr == kFunctionKeyCharCode) {
00163 for (int i = 0; functionKeys[i].qt_code; i++) {
00164 if (functionKeys[i].qt_code == keyQt) {
00165 keyCodes.append(functionKeys[i].mac_code);
00166 }
00167 }
00168 } else {
00169 keyCodes += scancodes.values(chr);
00170 }
00171
00172 return keyCodes.count() > 0;
00173 }
00174
00175 bool keyQtToModMac( int keyQt, uint& mod )
00176 {
00177 mod = 0;
00178 if (keyQt & Qt::ShiftModifier) {
00179 mod |= shiftKey;
00180 }
00181 if (keyQt & Qt::ControlModifier) {
00182 mod |= cmdKey;
00183 }
00184 if (keyQt & Qt::AltModifier) {
00185 mod |= optionKey;
00186 }
00187 if (keyQt & Qt::MetaModifier) {
00188 mod |= controlKey;
00189 }
00190 if (keyQt & Qt::KeypadModifier) {
00191 mod |= kEventKeyModifierNumLockMask;
00192 }
00193
00194 if ((keyQt & ~Qt::KeyboardModifierMask) == Qt::Key_Backtab) {
00195 mod |= shiftKey;
00196 }
00197
00198 return true;
00199 }
00200 }
00201
00202 #endif // Q_WS_MACX
00203