Changeset 434 for trunk/src/gui/kernel
- Timestamp:
- Dec 22, 2009, 2:34:55 AM (16 years ago)
- Location:
- trunk/src/gui/kernel
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gui/kernel/qapplication_pm.cpp
r432 r434 65 65 #include "qcursor_p.h" 66 66 67 #define WM_KBDLAYERCHANGED 0x0BD4 // defined in OS2TK45/h/pmbidi.h 68 67 69 //#define QT_DEBUGMSGFLOW 68 70 … … 944 946 945 947 case WM_CHAR: { // keyboard event 948 if (!(CHARMSG(&qmsg.msg)->fs & KC_KEYUP)) 949 qt_keymapper_private()->updateKeyMap(qmsg); 950 946 951 QWidget *g = QWidget::keyboardGrabber(); 947 952 if (g) … … 966 971 return (MRESULT)TRUE; 967 972 } 973 break; 974 } 975 976 case WM_KBDLAYERCHANGED: { // Keyboard layout change 977 QKeyMapper::changeKeyboard(); 968 978 break; 969 979 } … … 2529 2539 myCaseEnd() 2530 2540 2541 myCaseBegin(WM_KBDLAYERCHANGED) 2542 str += QString().sprintf(" mp1 %p mp2 %p", qmsg.mp1, qmsg.mp2); 2543 break; 2544 myCaseEnd() 2545 2531 2546 myCaseBegin(WM_PAINT) 2532 2547 break; -
trunk/src/gui/kernel/qkeymapper.cpp
r2 r434 91 91 void QKeyMapper::changeKeyboard() 92 92 { 93 #ifdef Q_WS_PM 94 // don't clear key mappings on layout change on OS/2 since we keep track of 95 // both layouts (Latin and National) in parallel 96 #else 93 97 instance()->d_func()->clearMappings(); 98 #endif 94 99 95 100 // inform all toplevel widgets of the change -
trunk/src/gui/kernel/qkeymapper_p.h
r136 r434 166 166 #elif defined(Q_WS_PM) 167 167 168 void updateKeyMap(const QMSG &qmsg); 168 169 bool translateKeyEvent(QWidget *receiver, const QMSG &qmsg, bool grab); 169 170 170 171 int extraKeyState; 172 KeyboardLayoutItem *keyLayout[256]; 173 enum { KeyLayoutSize = sizeof(keyLayout) / sizeof(keyLayout[0]) }; 171 174 172 175 #elif defined(Q_WS_X11) -
trunk/src/gui/kernel/qkeymapper_pm.cpp
r433 r434 49 49 #include "qt_os2.h" 50 50 51 //#define DEBUG_KEYMAPPER 52 53 // BIDI API --------------------------------------------------------[ start ] -- 54 // copied from pmbidi.h from the OS/2 toolkit as Innotek GCC headers lack this 55 56 #define KL_LATIN 0x00000000 57 #define KL_NATIONAL 0x00000001 58 59 ULONG APIENTRY WinSetKbdLayer (HWND hwnd, 60 ULONG idKbdLayer, 61 ULONG flFlags); 62 63 ULONG APIENTRY WinQueryKbdLayer (HWND hwnd); 64 65 ULONG APIENTRY WinQueryKbdLayout (HWND hwndDesktop); 66 67 BOOL APIENTRY WinSetKbdLayout (HWND hwndDesktop, 68 ULONG idKbdLayout); 69 70 // BIDI API ----------------------------------------------------------[ end ] -- 71 51 72 QT_BEGIN_NAMESPACE 52 53 //#define DEBUG_KEYMAPPER54 73 55 74 // Key recorder ----------------------------------------------------[ start ] -- … … 246 265 // Keyboard map private --------------------------------------------[ start ]--- 247 266 267 /* 268 \internal 269 270 An OS/2 KeyboardLayoutItem has 8 possible states meaningful for Qt: 271 1. Unmodified 272 2. Shift 273 3. Control 274 4. Control + Shift 275 5. Alt 276 6. Alt + Shift 277 7. Alt + Control 278 8. Alt + Control + Shift 279 */ 280 struct KeyboardLayoutItem { 281 int qtKey[8][2]; // Can be any Qt::Key_<foo>, or unicode character. 282 // The second index is for different keyboard layouts 283 ULONG layoutIds[2]; // Latin layout ID + National layout ID 284 enum { QtKeySize = sizeof(qtKey) / sizeof(qtKey[0]) }; 285 }; 286 287 // Possible Qt modifier states. Must match KbdModsTbl 288 static const Qt::KeyboardModifiers QtModsTbl[KeyboardLayoutItem::QtKeySize] = { 289 Qt::NoModifier, // 0 290 Qt::ShiftModifier, // 1 291 Qt::ControlModifier, // 2 292 Qt::ControlModifier | Qt::ShiftModifier, // 3 293 Qt::AltModifier, // 4 294 Qt::AltModifier | Qt::ShiftModifier, // 5 295 Qt::AltModifier | Qt::ControlModifier, // 6 296 Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 7 297 }; 298 299 // Possible OS/2 keyboard modifier states. Must match QtModsTbl 300 static const USHORT KbdModsTbl[] = { 301 0, // 0 302 KBDSTF_RIGHTSHIFT, // 1 303 KBDSTF_CONTROL, // 2 304 KBDSTF_CONTROL | KBDSTF_RIGHTSHIFT, // 3 305 KBDSTF_ALT, // 4 306 KBDSTF_ALT | KBDSTF_RIGHTSHIFT, // 5 307 KBDSTF_ALT | KBDSTF_CONTROL, // 6 308 KBDSTF_ALT | KBDSTF_RIGHTSHIFT | KBDSTF_CONTROL, // 7 309 }; 310 248 311 QKeyMapperPrivate::QKeyMapperPrivate() 249 312 { … … 252 315 extraKeyState = 0; 253 316 254 // @todo implement317 memset(keyLayout, 0, sizeof(keyLayout)); 255 318 } 256 319 … … 262 325 void QKeyMapperPrivate::clearMappings() 263 326 { 264 // @todo implement 327 for (int i = 0; i < KeyLayoutSize; ++i) { 328 if (keyLayout[i]) { 329 delete keyLayout[i]; 330 keyLayout[i] = 0; 331 } 332 } 265 333 } 266 334 … … 269 337 QList<int> result; 270 338 271 // @todo implement; so far do the same as QKeyMapper::possibleKeys() 272 if (e->key() && (e->key() != Qt::Key_unknown)) 273 result << int(e->key() + e->modifiers()); 274 else if (!e->text().isEmpty()) 275 result << int(e->text().at(0).unicode() + e->modifiers()); 339 KeyboardLayoutItem *kbItem = keyLayout[e->nativeScanCode()]; 340 if(!kbItem) { 341 #ifdef DEBUG_KEYMAPPER 342 qDebug("QKeyMapperPrivate::possibleKeys: none"); 343 #endif 344 return result; 345 } 346 347 int baseKey0 = kbItem->qtKey[0][0] ? kbItem->qtKey[0][0] : 348 e->key() && e->key() != Qt::Key_unknown ? e->key() : 349 e->text().at(0).unicode(); 350 351 int baseKey1 = baseKey0; 352 if (kbItem->layoutIds[1]) 353 kbItem->qtKey[0][1] ? kbItem->qtKey[0][1] : 354 e->key() && e->key() != Qt::Key_unknown ? e->key() : 355 e->text().at(0).unicode(); 356 357 Qt::KeyboardModifiers keyMods = e->modifiers(); 358 359 // The base key is _always_ valid, of course 360 result << int(baseKey0 + keyMods); 361 if (baseKey1 != baseKey0) 362 result << int(baseKey1 + keyMods); 363 364 // go through both keyboard layouts 365 for (int j = 0; j < 2; ++j) { 366 // check if we skipped the layout in updateKeyMap() and skip too if so 367 if (!kbItem->layoutIds[j]) 368 continue; 369 // go through all modifiers 370 for(int i = 0; i < KeyboardLayoutItem::QtKeySize; ++i) { 371 Qt::KeyboardModifiers neededMods = QtModsTbl[i]; 372 int key = kbItem->qtKey[i][j]; 373 if (key && key != baseKey0 && key != baseKey1 && 374 ((keyMods & neededMods) == neededMods)) { 375 int k = int(key + (keyMods & ~neededMods)); 376 if (!result.contains(k)) 377 result << k; 378 } 379 } 380 } 381 382 #ifdef DEBUG_KEYMAPPER 383 qDebug("QKeyMapperPrivate::possibleKeys:"); 384 foreach(int k, result) 385 qDebug(" 0x%x", k); 386 #endif 387 276 388 return result; 389 } 390 391 void QKeyMapperPrivate::updateKeyMap(const QMSG &qmsg) 392 { 393 CHRMSG chm = *CHARMSG(&qmsg.msg); 394 395 // it may be a keyboard layout change message, see translateKeyEvent() 396 // for details 397 if ((chm.fs & KC_VIRTUALKEY) && chm.vkey == 0) { 398 if (chm.chr == 0xF0 || chm.chr == 0xF1) { 399 chm.fs |= KC_ALT | KC_SHIFT; 400 chm.vkey = VK_SHIFT; 401 chm.scancode = chm.chr == 0xF1 ? 0x2A : 0x36; 402 chm.chr = 0; 403 } 404 } 405 406 if (!chm.scancode) 407 return; 408 409 if (!keyLayout[chm.scancode]) 410 keyLayout[chm.scancode] = new KeyboardLayoutItem; 411 412 KBDTRANS kt; 413 ULONG curLayerId = WinQueryKbdLayer(qmsg.hwnd); 414 415 #ifdef DEBUG_KEYMAPPER 416 int layoutsChanged = 0; 417 #endif 418 419 // go through both keyboard layouts 420 for (int j = 0; j < 2; ++j) { 421 WinSetKbdLayer(qmsg.hwnd, j ? KL_NATIONAL : KL_LATIN, 0); 422 // check if the data is still valid and skip if so. Also skip the 423 // National layout if it's the same as Latin 424 ULONG layoutId = WinQueryKbdLayout(HWND_DESKTOP); 425 if (keyLayout[chm.scancode]->layoutIds[j] == layoutId || 426 (j && keyLayout[chm.scancode]->layoutIds[0] == layoutId)) 427 continue; 428 keyLayout[chm.scancode]->layoutIds[j] = layoutId; 429 430 // now go through all modifiers 431 for (int i = 0; i < KeyboardLayoutItem::QtKeySize; ++i) { 432 // reset all kbd states and modifiers 433 memset(&kt, 0, sizeof(KBDTRANS)); 434 kt.chScan = chm.scancode; 435 kt.fsState = KbdModsTbl[i]; 436 APIRET arc = KbdXlate(&kt, 0); 437 Q_ASSERT(arc == NO_ERROR); 438 keyLayout[chm.scancode]->qtKey[i][j] = 439 QString::fromLocal8Bit((char*)&kt.chChar, 1)[0].toUpper().unicode(); 440 } 441 #ifdef DEBUG_KEYMAPPER 442 ++layoutsChanged; 443 #endif 444 } 445 446 // restore the layout 447 WinSetKbdLayer(qmsg.hwnd, curLayerId, 0); 448 449 #ifdef DEBUG_KEYMAPPER 450 if (layoutsChanged) { 451 qDebug("QKeyMapperPrivate::updateKeyMap: scancode 0x%02x", chm.scancode); 452 for (int i = 0; i < KeyboardLayoutItem::QtKeySize; ++i) { 453 qDebug(" [%d] (0x%04x, '%lc') (0x%04x, '%lc')", i, 454 keyLayout[chm.scancode]->qtKey[i][0], 455 keyLayout[chm.scancode]->qtKey[i][0] < 0x20 ? ' ' : 456 keyLayout[chm.scancode]->qtKey[i][0], 457 keyLayout[chm.scancode]->qtKey[i][1], 458 keyLayout[chm.scancode]->qtKey[i][1] < 0x20 ? ' ' : 459 keyLayout[chm.scancode]->qtKey[i][1]); 460 } 461 } 462 #endif 277 463 } 278 464 … … 334 520 // char code in the high byte of chm.chr (probably this is less 335 521 // device-dependent than scancode) 336 switch (chm.chr) { 337 case 0xEC00: // LWIN 338 case 0xED00: // RWIN 339 code = Qt::Key_Meta; 340 if (!(chm.fs & KC_KEYUP)) 341 extraKeyState |= Qt::MetaModifier; 342 else 343 extraKeyState &= ~Qt::MetaModifier; 344 break; 345 case 0xEE00: // WINAPP (menu with arrow) 346 code = Qt::Key_Menu; 347 break; 348 case 0x5600: // additional '\' (0x56 is actually its scancode) 349 chm.chr = state & Qt::ShiftModifier ? '|' : '\\'; 350 break; 351 case 0xFA00: // Back 352 code = Qt::Key_Back; 353 break; 354 case 0xF900: // Forward 355 code = Qt::Key_Forward; 356 break; 357 case 0x2064: // Volume Mute 358 code = Qt::Key_VolumeMute; 359 break; 360 case 0x2E63: // Volume Down 361 code = Qt::Key_VolumeDown; 362 break; 363 case 0x3062: // Volume Up 364 code = Qt::Key_VolumeUp; 365 break; 366 case 0x2267: // Play/Pause 367 code = Qt::Key_MediaPlay; 368 break; 369 case 0x326D: // Web/Home 370 code = Qt::Key_HomePage; 371 break; 372 case 0xF500: // Search 373 code = Qt::Key_Search; 374 break; 375 case 0xF600: // Favorites 376 code = Qt::Key_Favorites; 377 break; 378 } 522 if (!code){ 523 switch (chm.chr) { 524 case 0xEC00: // LWIN 525 case 0xED00: // RWIN 526 code = Qt::Key_Meta; 527 if (!(chm.fs & KC_KEYUP)) 528 extraKeyState |= Qt::MetaModifier; 529 else 530 extraKeyState &= ~Qt::MetaModifier; 531 break; 532 case 0xEE00: // WINAPP (menu with arrow) 533 code = Qt::Key_Menu; 534 break; 535 case 0x5600: // additional '\' (0x56 is actually its scancode) 536 chm.chr = state & Qt::ShiftModifier ? '|' : '\\'; 537 break; 538 case 0xFA00: // Back 539 code = Qt::Key_Back; 540 break; 541 case 0xF900: // Forward 542 code = Qt::Key_Forward; 543 break; 544 case 0x2064: // Volume Mute 545 code = Qt::Key_VolumeMute; 546 break; 547 case 0x2E63: // Volume Down 548 code = Qt::Key_VolumeDown; 549 break; 550 case 0x3062: // Volume Up 551 code = Qt::Key_VolumeUp; 552 break; 553 case 0x2267: // Play/Pause 554 code = Qt::Key_MediaPlay; 555 break; 556 case 0x326D: // Web/Home 557 code = Qt::Key_HomePage; 558 break; 559 case 0xF500: // Search 560 code = Qt::Key_Search; 561 break; 562 case 0xF600: // Favorites 563 code = Qt::Key_Favorites; 564 break; 565 } 566 } 379 567 380 568 // update state after updating extraKeyState
Note:
See TracChangeset
for help on using the changeset viewer.