Changeset 136 for trunk/src/gui/kernel
- Timestamp:
- Aug 28, 2009, 7:46:09 PM (16 years ago)
- Location:
- trunk/src/gui/kernel
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gui/kernel/qapplication_pm.cpp
r134 r136 508 508 #if defined(QT_DEBUGMSGFLOW) 509 509 { 510 Q Stringstr = qStrQMSG(qmsg);510 Q str = qStrQMSG(qmsg); 511 511 if (!str.isEmpty()) 512 qDebug() << "*** [W]" << str .toUtf8().constData();512 qDebug() << "*** [W]" << str; 513 513 } 514 514 #endif … … 602 602 } else { 603 603 switch(msg) { 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 604 630 605 631 case WM_PAINT: { // paint event … … 811 837 #if defined(QT_DEBUGMSGFLOW) 812 838 { 813 Q Stringstr = qStrQMSG(qmsg);839 Q str = qStrQMSG(qmsg); 814 840 if (!str.isEmpty()) 815 qDebug() << "*** [F]" << str .toUtf8().constData();841 qDebug() << "*** [F]" << str; 816 842 } 817 843 #endif … … 1033 1059 *****************************************************************************/ 1034 1060 1035 // State holder for LWIN/RWIN and ALTGr keys1036 // (ALTGr is also necessary since OS/2 doesn't report ALTGr as KC_ALT)1037 static int qt_extraKeyState = 0;1038 1039 1061 static int mouseButtonState() 1040 1062 { … … 1122 1144 bst |= Qt::ControlModifier; 1123 1145 } 1124 if ( (qt_extraKeyState & Qt::AltModifier))1146 if () 1125 1147 bst |= Qt::AltModifier; 1126 if (qt_ extraKeyState & Qt::MetaModifier)1148 if (qt_extraKeyState & Qt::MetaModifier) 1127 1149 bst |= Qt::MetaModifier; 1128 1150 … … 1547 1569 state |= Qt::ShiftModifier; 1548 1570 if (WinGetKeyState(HWND_DESKTOP, VK_ALT) & 0x8000 || 1549 (qt_ extraKeyState & Qt::AltModifier))1571 (qt_extraKeyState & Qt::AltModifier)) 1550 1572 state |= Qt::AltModifier; 1551 1573 if (WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x8000) 1552 1574 state |= Qt::ControlModifier; 1553 if (qt_ extraKeyState & Qt::MetaModifier)1575 if (qt_extraKeyState & Qt::MetaModifier) 1554 1576 state |= Qt::MetaModifier; 1555 1577 … … 1909 1931 switch (qmsg.msg) { 1910 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1911 1963 myCaseBegin(WM_PAINT) 1912 1964 break; -
trunk/src/gui/kernel/qkeymapper_p.h
r2 r136 164 164 KeyboardLayoutItem *keyLayout[256]; 165 165 166 167 168 169 170 171 166 172 #elif defined(Q_WS_X11) 167 173 -
trunk/src/gui/kernel/qkeymapper_pm.cpp
r95 r136 43 43 44 44 #include "qkeymapper_p.h" 45 46 47 48 45 49 46 50 QT_BEGIN_NAMESPACE 47 51 48 // Uncommend, to show debugging information for the keymapper49 52 //#define DEBUG_KEYMAPPER 50 53 51 // Keyboard map private ----------------------------------------------------------------[ start ]--- 54 // Key recorder ----------------------------------------------------[ start ] -- 55 struct KeyRecord { 56 KeyRecord(int _scan, int _code, int _state, const QString &_text) 57 : scan(_scan), code(_code), state(_state), text(_text) {} 58 KeyRecord() {} 59 60 int scan; 61 int code; 62 int state; 63 QString text; 64 }; 65 66 static const int QT_MAX_KEY_RECORDINGS = 64; // User has LOTS of fingers... 67 68 struct KeyRecorder 69 { 70 KeyRecorder() : nrecs(0) {} 71 72 inline KeyRecord *findKey(int code, bool remove); 73 inline void storeKey(int scan, int code, int state, const QString& text); 74 inline void clearKeys(); 75 76 int nrecs; 77 KeyRecord deleted_record; // A copy of last entry removed from records[] 78 KeyRecord records[QT_MAX_KEY_RECORDINGS]; 79 }; 80 static KeyRecorder key_recorder; 81 82 KeyRecord *KeyRecorder::findKey(int scan, bool remove) 83 { 84 KeyRecord *result = 0; 85 for (int i = 0; i < nrecs; ++i) { 86 if (records[i].scan == scan) { 87 if (remove) { 88 deleted_record = records[i]; 89 // Move rest down, and decrease count 90 while (i + 1 < nrecs) { 91 records[i] = records[i + 1]; 92 ++i; 93 } 94 --nrecs; 95 result = &deleted_record; 96 } else { 97 result = &records[i]; 98 } 99 break; 100 } 101 } 102 return result; 103 } 104 105 void KeyRecorder::storeKey(int scan, int code, int state, const QString& text) 106 { 107 Q_ASSERT_X(nrecs != QT_MAX_KEY_RECORDINGS, 108 "Internal KeyRecorder", 109 "Keyboard recorder buffer overflow, consider increasing QT_MAX_KEY_RECORDINGS"); 110 111 if (nrecs == QT_MAX_KEY_RECORDINGS) { 112 qWarning("Qt: Internal keyboard buffer overflow"); 113 return; 114 } 115 records[nrecs++] = KeyRecord(scan, code, state, text); 116 } 117 118 void KeyRecorder::clearKeys() 119 { 120 nrecs = 0; 121 } 122 // Key recorder ------------------------------------------------------[ end ] -- 123 124 // Key translation -------------------------------------------------[ start ] -- 125 // Meaning of values: 126 // 0 = Character output key, needs keyboard driver mapping 127 // Key_unknown = Unknown Virtual Key, no translation possible, ignore 128 static const uint KeyTbl[] = { // Keyboard mapping table 129 // Dec | Hex | PM Virtual key 130 Qt::Key_unknown, // 0 0x00 131 Qt::Key_unknown, // 1 0x01 VK_BUTTON1 | Mouse button 1 132 Qt::Key_unknown, // 2 0x02 VK_BUTTON2 | Mouse button 2 133 Qt::Key_unknown, // 3 0x03 VK_BUTTON3 | Mouse button 3 134 Qt::Key_Cancel, // 4 0x04 VK_BREAK | Control-Break processing 135 Qt::Key_Backspace, // 5 0x05 VK_BACKSPACE | BackSpace key 136 Qt::Key_Tab, // 6 0x06 VK_TAB | Tab key 137 Qt::Key_Backtab, // 7 0x07 VK_BACKTAB | Shift+Tab key 138 Qt::Key_Return, // 8 0x08 VK_RETURN | Enter key 139 Qt::Key_Shift, // 9 0x09 VK_SHIFT | Shift key 140 Qt::Key_Control, // 10 0x0A VK_CTRL | Ctrl key 141 Qt::Key_Alt, // 11 0x0B VK_ALT | Alt key 142 Qt::Key_Alt, // 12 0x0C VK_ALTGRAF | AltGr key 143 Qt::Key_Pause, // 13 0x0D VK_PAUSE | Pause key 144 Qt::Key_CapsLock, // 14 0x0E VK_CAPSLOCK | Caps-Lock 145 Qt::Key_Escape, // 15 0x0F VK_ESC | Esc key 146 Qt::Key_Space, // 16 0x10 VK_SPACE | Spacebar 147 Qt::Key_PageUp, // 17 0x11 VK_PAGEUP | Page Up key 148 Qt::Key_PageDown, // 18 0x12 VK_PAGEDOWN | Page Down key 149 Qt::Key_End, // 19 0x13 VK_END | End key 150 Qt::Key_Home, // 20 0x14 VK_HOME | Home key 151 Qt::Key_Left, // 21 0x15 VK_LEFT | Left arrow key 152 Qt::Key_Up, // 22 0x16 VK_UP | Up arrow key 153 Qt::Key_Right, // 23 0x17 VK_RIGHT | Right arrow key 154 Qt::Key_Down, // 24 0x18 VK_DOWN | Down arrow key 155 Qt::Key_Print, // 25 0x19 VK_PRINTSCRN | Print Screen key 156 Qt::Key_Insert, // 26 0x1A VK_INSERT | Ins key 157 Qt::Key_Delete, // 27 0x1B VK_DELETE | Del key 158 Qt::Key_NumLock, // 28 0x1C VK_SCROLL | Scroll Lock key 159 Qt::Key_ScrollLock, // 29 0x1D VK_NUMLOCK | Num Lock key 160 Qt::Key_Enter, // 30 0x1E VK_ENTER | Enter (Numpad) key 161 Qt::Key_SysReq, // 31 0x1F VK_SYSRQ | SysReq key 162 Qt::Key_F1, // 32 0x20 VK_F1 | F1 key 163 Qt::Key_F2, // 33 0x21 VK_F2 | F2 key 164 Qt::Key_F3, // 34 0x22 VK_F3 | F3 key 165 Qt::Key_F4, // 35 0x23 VK_F4 | F4 key 166 Qt::Key_F5, // 36 0x24 VK_F5 | F5 key 167 Qt::Key_F6, // 37 0x25 VK_F6 | F6 key 168 Qt::Key_F7, // 38 0x26 VK_F7 | F7 key 169 Qt::Key_F8, // 39 0x27 VK_F8 | F8 key 170 Qt::Key_F9, // 40 0x28 VK_F9 | F9 key 171 Qt::Key_F10, // 41 0x29 VK_F10 | F10 key 172 Qt::Key_F11, // 42 0x2A VK_F11 | F11 key 173 Qt::Key_F12, // 43 0x2B VK_F12 | F12 key 174 Qt::Key_F13, // 44 0x2C VK_F13 | F13 key 175 Qt::Key_F14, // 45 0x2D VK_F14 | F14 key 176 Qt::Key_F15, // 46 0x2E VK_F15 | F15 key 177 Qt::Key_F16, // 47 0x2F VK_F16 | F16 key 178 Qt::Key_F17, // 48 0x30 VK_F17 | F17 key 179 Qt::Key_F18, // 49 0x31 VK_F18 | F18 key 180 Qt::Key_F19, // 50 0x32 VK_F19 | F19 key 181 Qt::Key_F20, // 51 0x33 VK_F20 | F20 key 182 Qt::Key_F21, // 52 0x34 VK_F21 | F21 key 183 Qt::Key_F22, // 53 0x35 VK_F22 | F22 key 184 Qt::Key_F23, // 54 0x36 VK_F23 | F23 key 185 Qt::Key_F24, // 55 0x37 VK_F24 | F24 key 186 Qt::Key_unknown, // 56 0x38 VK_ENDDRAG | ??? 187 Qt::Key_Clear, // 57 0x39 VK_CLEAR | Clear key 188 Qt::Key_unknown, // 58 0x3A VK_EREOF | ??? 189 Qt::Key_unknown, // 59 0x3B VK_PA1 | ??? 190 Qt::Key_unknown, // 60 0x3C VK_ATTN | ??? 191 Qt::Key_unknown, // 61 0x3D VK_CRSEL | ??? 192 Qt::Key_unknown, // 62 0x3E VK_EXSEL | ??? 193 Qt::Key_unknown, // 63 0x3F VK_COPY | ??? 194 Qt::Key_unknown, // 64 0x40 VK_BLK1 | ??? 195 Qt::Key_unknown, // 65 0x41 VK_BLK2 | ??? 196 }; 197 198 // Key translation ---------------------------------------------------[ end ]--- 199 200 // QETWidget class is only for accessing the sendSpontaneousEvent function in QApplication 201 class QETWidget : public QWidget { 202 public: 203 static bool sendSpontaneousEvent(QObject *r, QEvent *e) 204 { return QApplication::sendSpontaneousEvent(r, e); } 205 }; 206 207 // Keyboard map private --------------------------------------------[ start ]--- 52 208 53 209 QKeyMapperPrivate::QKeyMapperPrivate() 54 210 { 55 // @todo implement 211 // State holder for LWIN/RWIN and ALTGr keys 212 // (ALTGr is also necessary since OS/2 doesn't report ALTGr as KC_ALT) 213 extraKeyState = 0; 214 215 // @todo implement 56 216 } 57 217 … … 74 234 } 75 235 76 // QKeyMapper (PM) implementation -------------------------------------------------[ start ]--- 236 static inline int asciiToKeycode(char a, int state) 237 { 238 if (a >= 'a' && a <= 'z') 239 a = toupper(a); 240 if ((state & Qt::ControlModifier) != 0) { 241 if (a >= 0 && a <= 31) // [email protected]+A..CTRL+Z..Ctrl+_ 242 a += '@'; // to @..A..Z.._ 243 } 244 return a & 0xff; 245 } 246 247 bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const QMSG &qmsg, bool grab) 248 { 249 Q_Q(QKeyMapper); 250 251 bool k0 = false; 252 bool k1 = false; 253 254 CHRMSG chm = *CHARMSG(&qmsg.msg); 255 256 // we combine the flags from the message with the raw chr value and pass 257 // them as QKeyEvent::nativeModifiers(). Together with chr.vkey passed as 258 // nativeVirtualKey() and chr.scancode as nativeScanCode(), the Qt 259 // application gets the full key message details (except the repeat count). 260 quint32 nativeMods = chm.fs | chm.chr << 16; 261 262 // Get the modifier states (may be altered later, depending on key code) 263 int state = 0; 264 if (chm.fs & KC_SHIFT) 265 state |= Qt::ShiftModifier; 266 if (chm.fs & KC_CTRL) 267 state |= Qt::ControlModifier; 268 if (chm.fs & KC_ALT) 269 state |= Qt::AltModifier; 270 271 // Translate VK_* (native) -> Key_* (Qt) keys 272 int code = 0; 273 if ((chm.fs & KC_VIRTUALKEY)) { 274 if (chm.vkey == 0) { 275 // The only known situation when KC_VIRTUALKEY is present but 276 // vkey is zero is when Alt+Shift is pressed to switch the 277 // keyboard layout state from latin to national and back. 278 // It seems that this way the system informs applications about 279 // layout changes: chm.chr is 0xF1 when the user switches 280 // to the national layout (i.e. presses Alt + Left Shift) 281 // and 0xF0 when he switches back (presses Alt + Right Shift). 282 // We assume this and restore fs, vkey, scancode and chr accordingly. 283 if (chm.chr == 0xF0 || chm.chr == 0xF1) { 284 chm.fs |= KC_ALT | KC_SHIFT; 285 chm.vkey = VK_SHIFT; 286 chm.scancode = chm.chr == 0xF1 ? 0x2A : 0x36; 287 chm.chr = 0; 288 state |= Qt::AltModifier | Qt::ShiftModifier; 289 // code will be assigned by the normal procedure below 290 } 291 } else if (chm.vkey == VK_ALTGRAF) { 292 if (!(chm.fs & KC_KEYUP)) 293 extraKeyState |= Qt::AltModifier; 294 else 295 extraKeyState &= ~Qt::AltModifier; 296 } 297 if (chm.vkey < sizeof(KeyTbl)) 298 code = KeyTbl[chm.vkey]; 299 } 300 301 // detect some special keys that don't have a virtual key but have a pseudo 302 // char code in the high byte of chm.chr (probably this is less 303 // device-dependent than scancode) 304 switch (chm.chr) { 305 case 0xEC00: // LWIN 306 case 0xED00: // RWIN 307 code = Qt::Key_Meta; 308 if (!(chm.fs & KC_KEYUP)) 309 extraKeyState |= Qt::MetaModifier; 310 else 311 extraKeyState &= ~Qt::MetaModifier; 312 break; 313 case 0xEE00: // WINAPP (menu with arrow) 314 code = Qt::Key_Menu; 315 break; 316 case 0x5600: // additional '\' (0x56 is actually its scancode) 317 chm.chr = state & Qt::ShiftModifier ? '|' : '\\'; 318 break; 319 } 320 321 // update state after updating extraKeyState 322 if (extraKeyState & Qt::AltModifier) 323 state |= Qt::AltModifier; 324 if (extraKeyState & Qt::MetaModifier) 325 state |= Qt::MetaModifier; 326 327 // Invert state logic: 328 // If the key actually pressed is a modifier key, then we remove its modifier key from the 329 // state, since a modifier-key can't have itself as a modifier 330 // 331 // ### QKeyEvent::modifiers() already does this inversion which in result 332 // cancels the inversion we do below and therefore makes the above statement 333 // incorrect! It looks like the inversion block should be removed from this 334 // function but it is left here for compatibility with other platforms which 335 // also have this bug. 336 // 337 if (code == Qt::Key_Control) 338 state = state ^ Qt::ControlModifier; 339 else if (code == Qt::Key_Shift) 340 state = state ^ Qt::ShiftModifier; 341 else if (code == Qt::Key_Alt) 342 state = state ^ Qt::AltModifier; 343 else if (code == Qt::Key_Meta) 344 state = state ^ Qt::MetaModifier; 345 346 // KEYDOWN ----------------------------------------------------------------- 347 if (!(chm.fs & KC_KEYUP)) { 348 // Get the last record of this key press, so we can validate the current state 349 // The record is not removed from the list 350 KeyRecord *rec = key_recorder.findKey(chm.scancode, false); 351 352 // If rec's state doesn't match the current state, something has changed behind our back 353 // (Consumed by modal widget is one possibility) So, remove the record from the list 354 // This will stop the auto-repeat of the key, should a modifier change, for example 355 if (rec && rec->state != state) { 356 key_recorder.findKey(chm.scancode, true); 357 rec = 0; 358 } 359 360 // If we have a record, it means that the key is already pressed, the state is the same 361 // so, we have an auto-repeating key 362 if (rec) { 363 Q_ASSERT(!code || code == rec->code); 364 if (rec->code < Qt::Key_Shift || rec->code > Qt::Key_ScrollLock) { 365 k0 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, rec->code, 366 Qt::KeyboardModifier(state), rec->text, true, 0, 367 chm.scancode, chm.vkey, nativeMods); 368 k1 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, rec->code, 369 Qt::KeyboardModifier(state), rec->text, true, 0, 370 chm.scancode, chm.vkey, nativeMods); 371 } 372 } 373 // No record of the key being previous pressed, so we now send a QEvent::KeyPress event, 374 // and store the key data into our records. 375 else { 376 QString text; 377 if (chm.chr) { 378 // Note: We ignore the KC_CHAR flag when generating text for the 379 // key in order to get correct (non-null) text even for Alt+Letter 380 // combinations (that don't have KC_CHAR set) because processing 381 // Alt+Letter shortcuts for non-ASCII letters in widgets (e.g. 382 // QPushButton) depends on that. 383 if ((chm.fs & (KC_VIRTUALKEY | KC_CHAR)) == KC_CHAR && (chm.chr & 0xFF00)) { 384 // We assime we get a DBCS char if the above condition is met. 385 // DBCS chars seem to have KC_CHAR set but not KC_VIRTUALKEY; we 386 // use this to prevent keys like ESC (chm=0x011B) with the 387 // non-zero high byte to be mistakenly recognized as DBCS. 388 text = QString::fromLocal8Bit((char *)&chm.chr, 2); 389 } else if (chm.chr & 0xFF) { 390 text = QString::fromLocal8Bit((char*)&chm.chr, 1); 391 } 392 393 Q_ASSERT(code || !text.isEmpty()); // we must provide the key code 394 if (!code && !text.isEmpty()) { 395 if (!text[0].row()) 396 code = asciiToKeycode(text[0].cell(), state); 397 else 398 code = text[0].toUpper().unicode(); 399 } 400 } 401 key_recorder.storeKey(chm.scancode, code, state, text); 402 k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, code, 403 Qt::KeyboardModifier(state), text, false, 0, 404 chm.scancode, chm.vkey, nativeMods); 405 } 406 } 407 // KEYUP ------------------------------------------------------------------- 408 else { 409 // Try to locate the key in our records, and remove it if it exists. 410 // The key may not be in our records if, for example, the down event was handled by 411 // PM natively, or our window gets focus while a key is already press, but now gets 412 // the key release event. 413 KeyRecord* rec = key_recorder.findKey(chm.scancode, true); 414 if (!rec) { 415 // Someone ate the key down event 416 } else { 417 k0 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, rec->code, 418 Qt::KeyboardModifier(state), rec->text, false, 0, 419 chm.scancode, chm.vkey, nativeMods); 420 } 421 } 422 423 // Return true, if a QKeyEvent was sent to a widget 424 return k0 || k1; 425 } 426 427 // QKeyMapper (PM) implementation ----------------------------------[ start ]--- 77 428 78 429 bool QKeyMapper::sendKeyEvent(QWidget *widget, bool grab, … … 82 433 bool *) 83 434 { 84 // @todo implement 85 return false; 435 Q_UNUSED(count); 436 437 #if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT) 438 if (type == QEvent::KeyPress 439 && !grab 440 && QApplicationPrivate::instance()->use_compat()) { 441 // send accel events if the keyboard is not grabbed 442 QKeyEventEx a(type, code, modifiers, 443 text, autorepeat, qMax(1, int(text.length())), 444 nativeScanCode, nativeVirtualKey, nativeModifiers); 445 if (QApplicationPrivate::instance()->qt_tryAccelEvent(widget, &a)) 446 return true; 447 } 448 #endif 449 if (!widget->isEnabled()) 450 return false; 451 452 QKeyEventEx e(type, code, modifiers, 453 text, autorepeat, qMax(1, int(text.length())), 454 nativeScanCode, nativeVirtualKey, nativeModifiers); 455 QETWidget::sendSpontaneousEvent(widget, &e); 456 457 return e.isAccepted(); 86 458 } 87 459
Note:
See TracChangeset
for help on using the changeset viewer.