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

KDEUI

kkeyserver_mac.cpp

Go to the documentation of this file.
00001 /*
00002  Copyright (C) 2006 Marijn Kruisselbrink <m.kruisselbrink@student.tue.nl>
00003  
00004  This library is free software; you can redistribute it and/or
00005  modify it under the terms of the GNU Library General Public
00006  License as published by the Free Software Foundation; either
00007  version 2 of the License, or (at your option) any later version.
00008  
00009  This library is distributed in the hope that it will be useful,
00010  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  Library General Public License for more details.
00013  
00014  You should have received a copy of the GNU Library General Public License
00015  along with this library; see the file COPYING.LIB.  If not, write to
00016  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  Boston, MA 02110-1301, USA.
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},  // Backtab == tab with different modifiers
00043     {Qt::Key_Backspace,  kBackspaceCharCode},
00044     {Qt::Key_Return,     kReturnCharCode},
00045     {Qt::Key_Enter,      kEnterCharCode},
00046         // Insert
00047     {Qt::Key_Delete,     kDeleteCharCode},
00048         // Pause, Print, SysReq
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         // Shift, Control, Meta, Alt, CapsLock, NumLock, ScrollLock
00059         // Super_L, Super_R, Menu, Hyper_L, Hyper_R
00060     {Qt::Key_Help,       kHelpCharCode},
00061         // Direction_L, Direction_R
00062     {Qt::Key_nobreakspace, kNonBreakingSpaceCharCode},
00063     {0, 0}
00064     };
00065     
00066     static QMultiMap<int, uint> scancodes;
00067     static long lastLayoutID = -1;
00068 #ifdef QT_MAC_USE_COCOA
00069     static TISInputSourceRef lastLayout = 0;
00070 #else
00071     static KeyboardLayoutRef lastLayout = NULL;
00072 #endif
00073     
00074     void updateScancodes() {
00075 #ifdef QT_MAC_USE_COCOA
00076         TISInputSourceRef layout = TISCopyCurrentKeyboardLayoutInputSource();
00077         if (!layout) {
00078             kWarning() << "Error retrieving current layout";
00079             return;
00080         }
00081         if (layout == lastLayout) {
00082             CFRelease(layout);
00083         } else {
00084             // keyboard layout changed
00085 #ifndef NDEBUG
00086             const void *name = TISGetInputSourceProperty(layout, kTISPropertyLocalizedName);
00087             kDebug() << "Layout changed to: " << CFStringGetCStringPtr((CFStringRef)name, 0);
00088 #endif
00089             lastLayout = layout;
00090             scancodes.clear();
00091 
00092             CFDataRef data = static_cast<CFDataRef>(TISGetInputSourceProperty(layout,
00093                                          kTISPropertyUnicodeKeyLayoutData));
00094             const UCKeyboardLayout *ucData = data ? reinterpret_cast<const UCKeyboardLayout *>(CFDataGetBytePtr(data)) : 0;
00095 
00096             if (!ucData) {
00097                 kWarning() << "Error retrieving current layout character data";
00098                 return;
00099             }
00100 
00101             for (int i = 0; i < 128; ++i) {
00102                 UInt32 tmpState = 0;
00103                 UniChar str[4];
00104                 UniCharCount actualLength = 0;
00105                 OSStatus err = UCKeyTranslate(ucData, i, kUCKeyActionDown, 0, LMGetKbdType(),
00106                     kUCKeyTranslateNoDeadKeysMask, &tmpState, 4, &actualLength, str);
00107                 if (err != noErr) {
00108                     kWarning() << "Error translating unicode key" << err;
00109                 } else {
00110                     if (str[0] && str[0] != kFunctionKeyCharCode)
00111                         scancodes.insert(str[0], i);
00112                 }
00113             }
00114         }
00115 #else
00116         KeyboardLayoutRef layout;
00117         if (KLGetCurrentKeyboardLayout(&layout) != noErr) {
00118             kWarning() << "Error retrieving current layout";
00119         }
00120         if (layout != lastLayout) {
00121 #ifndef NDEBUG
00122             void *name;
00123             KLGetKeyboardLayoutProperty(layout, kKLName, const_cast<const void**>(&name));
00124             kDebug() << "Layout changed to: " << CFStringGetCStringPtr((CFStringRef) name, 0);
00125 #endif
00126             lastLayout = layout;
00127             scancodes.clear();
00128             void *kchr;
00129             if (KLGetKeyboardLayoutProperty(layout, kKLKCHRData, const_cast<const void**>(&kchr)) != noErr) {
00130                 kWarning() << "Couldn't load active keyboard layout";
00131             } else {
00132                 for (int i = 0; i < 128; i++) {
00133                     UInt32 tmpState = 0;
00134                     UInt32 chr = KeyTranslate(kchr, i, &tmpState);
00135                     if (chr && chr != kFunctionKeyCharCode) {
00136                         scancodes.insert(chr, i);
00137                     }
00138                 }
00139             }
00140         }
00141 #endif
00142     }
00143     
00144 #define SCANCODE(name, value) { Qt::Key_ ## name, value }    
00145     static TransKey functionKeys[] = {
00146         SCANCODE(F1, 122),
00147         SCANCODE(F2, 120),
00148         SCANCODE(F3, 99),
00149         SCANCODE(F4, 118),
00150         SCANCODE(F5, 96),
00151         SCANCODE(F6, 97),
00152         SCANCODE(F7, 98),
00153         SCANCODE(F8, 100),
00154         SCANCODE(F9, 101),
00155         SCANCODE(F10, 109),
00156         //TODO: figure out scancodes of other F* keys
00157     { 0, 0 }
00158     };
00159 #undef SCANCODE
00160     
00161     bool keyQtToSymMac( int keyQt, int& sym )
00162     {
00163         // Printable ascii values, before A
00164         if (keyQt >= 0x20 && keyQt < Qt::Key_A) {
00165             sym = keyQt;
00166             return true;
00167         }
00168         // Letters, return lower-case equivalent
00169         if (keyQt >= Qt::Key_A && keyQt <= Qt::Key_Z) {
00170             sym = keyQt - Qt::Key_A + 'a';
00171             return true;
00172         }
00173         // Printable ascii values up to lower-case a
00174         if (keyQt > Qt::Key_Z && keyQt <= 0x60) {
00175             sym = keyQt;
00176             return true;
00177         }
00178         // Remainder of printable ascii values
00179         if (keyQt >= 0x7B && keyQt < 0x7F) {
00180             sym = keyQt;
00181             return true;
00182         }
00183         // Function keys
00184         if (keyQt >= Qt::Key_F1 && keyQt <= Qt::Key_F35) {
00185             sym = kFunctionKeyCharCode;
00186             return true;
00187         }
00188         // Try to find in lookup table
00189         for (int i = 0; qtKeyToChar[i].qt_code; i++) {
00190             if (qtKeyToChar[i].qt_code == keyQt) {
00191                 sym = qtKeyToChar[i].mac_code;
00192                 return true;
00193             }
00194         }
00195 
00196         // Not found
00197         return false;
00198     }
00199     
00200     bool keyQtToCodeMac( int keyQt, QList<uint>& keyCodes )
00201     {
00202         updateScancodes();
00203         keyCodes.clear();
00204         keyQt &= ~Qt::KeyboardModifierMask;
00205         int chr;
00206         if (!keyQtToSymMac( keyQt, chr ) ) return false;
00207         
00208         if (chr == kFunctionKeyCharCode) {
00209             for (int i = 0; functionKeys[i].qt_code; i++) {
00210                 if (functionKeys[i].qt_code == keyQt) {
00211                     keyCodes.append(functionKeys[i].mac_code);
00212                 }
00213             }
00214         } else {
00215             keyCodes += scancodes.values(chr);
00216         }
00217         
00218         return keyCodes.count() > 0;
00219     }
00220     
00221     bool keyQtToModMac( int keyQt, uint& mod )
00222     {
00223         mod = 0;
00224         if (keyQt & Qt::ShiftModifier) {
00225             mod |= shiftKey;
00226         }
00227         if (keyQt & Qt::ControlModifier) {
00228             mod |= cmdKey;
00229         }
00230         if (keyQt & Qt::AltModifier) {
00231             mod |= optionKey;
00232         }
00233         if (keyQt & Qt::MetaModifier) {
00234             mod |= controlKey;
00235         }
00236         if (keyQt & Qt::KeypadModifier) {
00237             mod |= kEventKeyModifierNumLockMask;
00238         }
00239         // Special case for Qt::Key_Backtab
00240         if ((keyQt & ~Qt::KeyboardModifierMask) == Qt::Key_Backtab) {
00241             mod |= shiftKey;
00242         }
00243         
00244         return true;
00245     }
00246 } // end of namespace KKeyServer
00247 
00248 #endif // Q_WS_MACX
00249 

KDEUI

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • 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
Generated for kdelibs by doxygen 1.7.3
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal