Timestamp:
Aug 20, 2006, 8:11:44 AM (19 years ago)
Author:
bird
Message:

Expanded m_client to 64-bit. Finally managed to hack together a getKeyMap and fakeKey for PM.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/synergy/lib/platform/CPMKeyState.cpp

    r2765 r2768  
    2828
    2929// map virtual keys to synergy key enumeration
    30 const KeyID                             CPMKeyState::s_virtualKey[0x42] =
    31 {
    32         /* 0x000 */ kKeyNone,           // reserved
    33         /* 0x001 */ kKeyNone,           // VK_BUTTON1
    34         /* 0x002 */ kKeyNone,           // VK_BUTTON2
    35         /* 0x003 */ kKeyNone,           // VK_BUTTON3
    36         /* 0x004 */ kKeyBreak,          // VK_BREAK
    37         /* 0x005 */ kKeyBackSpace,      // VK_BACKSPACE
    38         /* 0x006 */ kKeyTab,            // VK_TAB
    39         /* 0x007 */ kKeyLeftTab,        // VK_BACKTAB -- ???
    40         /* 0x008 */ kKeyReturn,         // VK_NEWLINE
    41         /* 0x009 */ kKeyShift_L,        // VK_SHIFT
    42         /* 0x00a */ kKeyControl_L,      // VK_CTRL
    43         /* 0x00b */ kKeyAlt_L,          // VK_ALT
    44         /* 0x00c */ kKeyAltGr,          // VK_ALTGRAF
    45         /* 0x00d */ kKeyPause,          // VK_PAUSE
    46         /* 0x00e */ kKeyCapsLock,       // VK_CAPSLOCK
    47         /* 0x00f */ kKeyEscape,         // VK_ESC
    48         /* 0x010 */ kKeyNone,           // VK_SPACE
    49         /* 0x011 */ kKeyPageUp,         // VK_PAGEUP
    50         /* 0x012 */ kKeyPageDown,       // VK_PAGEDOWN
    51         /* 0x013 */ kKeyEnd,            // VK_END
    52         /* 0x014 */ kKeyHome,           // VK_HOME
    53         /* 0x015 */ kKeyLeft,           // VK_LEFT
    54         /* 0x016 */ kKeyUp,                     // VK_UP
    55         /* 0x017 */ kKeyRight,          // VK_RIGHT
    56         /* 0x018 */ kKeyDown,           // VK_DOWN
    57         /* 0x019 */ kKeyNone,           // VK_PRINTSCRN
    58         /* 0x01a */ kKeyInsert,         // VK_INSERT
    59         /* 0x01b */ kKeyDelete,         // VK_DELETE
    60         /* 0x01c */ kKeyScrollLock,     // VK_SCRLLOCK
    61         /* 0x01d */ kKeyNumLock,        // VK_NUMLOCK
    62         /* 0x01e */ kKeyKP_Enter,       // VK_ENTER
    63         /* 0x01f */ kKeySysReq,         // VK_SYSRQ
    64         /* 0x020 */ kKeyF1,                     // VK_F1
    65         /* 0x021 */ kKeyF2,                     // VK_F2
    66         /* 0x022 */ kKeyF3,                     // VK_F3
    67         /* 0x023 */ kKeyF4,                     // VK_F4
    68         /* 0x024 */ kKeyF5,                     // VK_F5
    69         /* 0x025 */ kKeyF6,                     // VK_F6
    70         /* 0x026 */ kKeyF7,                     // VK_F7
    71         /* 0x027 */ kKeyF8,                     // VK_F8
    72         /* 0x028 */ kKeyF9,                     // VK_F9
    73         /* 0x029 */ kKeyF10,            // VK_F10
    74         /* 0x02a */ kKeyF11,            // VK_F11
    75         /* 0x02b */ kKeyF12,            // VK_F12
    76         /* 0x02c */ kKeyF13,            // VK_F13
    77         /* 0x02d */ kKeyF14,            // VK_F14
    78         /* 0x02e */ kKeyF15,            // VK_F15
    79         /* 0x02f */ kKeyF16,            // VK_F16
    80         /* 0x030 */ kKeyF17,            // VK_F17
    81         /* 0x031 */ kKeyF18,            // VK_F18
    82         /* 0x032 */ kKeyF19,            // VK_F19
    83         /* 0x033 */ kKeyF20,            // VK_F20
    84         /* 0x034 */ kKeyF21,            // VK_F21
    85         /* 0x035 */ kKeyF22,            // VK_F22
    86         /* 0x036 */ kKeyF23,            // VK_F23
    87         /* 0x037 */ kKeyF24,            // VK_F24
    88         /* 0x038 */ kKeyNone,           // VK_ENDDRAG
    89         /* 0x039 */ kKeyClear,          // VK_CLEAR
    90         /* 0x03a */ kKeyNone,           // VK_EREOF
    91         /* 0x03b */ kKeyNone,           // VK_PA1
    92         /* 0x03c */ kKeyNone,           // VK_ATTN
    93         /* 0x03d */ kKeyNone,           // VK_CRSEL
    94         /* 0x03e */ kKeyNone,           // VK_EXSEL
    95         /* 0x03f */ kKeyNone,           // VK_COPY
    96         /* 0x040 */ kKeyNone,           // VK_BLK1
    97         /* 0x041 */ kKeyNone            // VK_BLK2
     30const CPMKeyState::s_virtualKey[0x42] =
     31{
     32// reserved
     33// VK_BUTTON1
     34// VK_BUTTON2
     35// VK_BUTTON3
     36// VK_BREAK
     37// VK_BACKSPACE
     38// VK_TAB
     39{ /* 0x007 */ kKeyLeftTab,      9,    0,    1 },    // VK_BACKTAB
     40// VK_NEWLINE
     41// VK_SHIFT
     42// VK_CTRL
     43// VK_ALT
     44// VK_ALTGRAF
     45// VK_PAUSE
     46// VK_CAPSLOCK
     47// VK_ESC
     48// VK_SPACE
     49// VK_PAGEUP
     50// VK_PAGEDOWN
     51// VK_END
     52// VK_HOME
     53// VK_LEFT
     54// VK_UP
     55// VK_RIGHT
     56// VK_DOWN
     57// VK_PRINTSCRN
     58// VK_INSERT
     59// VK_DELETE
     60// VK_SCRLLOCK
     61// VK_NUMLOCK
     62// VK_ENTER
     63// VK_SYSRQ
     64// VK_F1
     65// VK_F2
     66// VK_F3
     67// VK_F4
     68// VK_F5
     69// VK_F6
     70// VK_F7
     71// VK_F8
     72// VK_F9
     73// VK_F10
     74// VK_F11
     75// VK_F12
     76// VK_F13
     77// VK_F14
     78// VK_F15
     79// VK_F16
     80// VK_F17
     81// VK_F18
     82// VK_F19
     83// VK_F20
     84// VK_F21
     85// VK_F22
     86// VK_F23
     87// VK_F24
     88// VK_ENDDRAG
     89// VK_CLEAR
     90// VK_EREOF
     91// VK_PA1
     92// VK_ATTN
     93// VK_CRSEL
     94// VK_EXSEL
     95// VK_COPY
     96// VK_BLK1
     97// VK_BLK2
    9898};
    9999
     
    354354}
    355355
     356
     357
     358
     359
     360
     361
     362
     363
     364
     365
     366
     367
     368
     369
     370
     371
     372
     373
     374
     375
     376
     377
     378
     379
     380
     381
     382
     383
     384
     385
     386
     387
     388
     389
     390
     391
     392
     393
     394
     395
     396
     397
     398
     399
     400
     401
     402
     403
     404
     405
     406
     407
     408
     409
     410
     411
     412
     413
     414
     415
     416
     417
     418
     419
     420
     421
     422
     423
     424
     425
     426
     427
     428
     429
     430
     431
     432
     433
     434
     435
     436
     437
     438
     439
     440
     441
     442
     443
     444
     445
     446
     447
     448
     449
     450
     451
     452
    356453void
    357454CPMKeyState::getKeyMap(CKeyMap& keyMap)
     
    375472
    376473        CKeyMap::KeyItem item;
    377 //      SInt32 numGroups = (SInt32)m_groups.size();
    378 //      for (SInt32 g = 0; g < numGroups; ++g) {
    379474        for (SInt32 g = 0; g < 1; ++g) {
    380475                item.m_group = g;
    381 //              ActivateKeyboardLayout(m_groups[g], 0);
    382 
    383                 // clear tables
     476
     477                //
     478                // Fill the scan code conversion tables.
     479                //
     480                for (unsigned i = 0; i < sizeof(m_pmScanToOemScan) / sizeof(m_pmScanToOemScan[0]); i++) {
     481                        USHORT us = i;
     482                        USHORT fShiftState = 0;
     483                        WinTranslateChar2(0, &us, NULL, TC_SCANTOOEMSCAN, &fShiftState);
     484                        m_pmScanToOemScan[i] = us;
     485                }
     486                for (unsigned i = 0; i < sizeof(m_pmScanToOemScanExt) / sizeof(m_pmScanToOemScanExt[0]); i++) {
     487                        USHORT us = i;
     488                        USHORT fShiftState = TCF_EXTENDEDKEY;
     489                        WinTranslateChar2(0, &us, NULL, TC_SCANTOOEMSCAN, &fShiftState);
     490                        m_pmScanToOemScanExt[i] = us;
     491                }
     492                for (unsigned i = 0; i < sizeof(m_oemScanToPmScan) / sizeof(m_oemScanToPmScan[0]); i++) {
     493                        USHORT us = i;
     494                        USHORT fShiftState = 0;
     495                        WinTranslateChar2(0, &us, NULL, TC_OEMSCANTOSCAN, &fShiftState);
     496                        m_oemScanToPmScan[i] = us;
     497                }
     498                for (unsigned i = 0; i < sizeof(m_oemScanToPmScanExt) / sizeof(m_oemScanToPmScanExt[0]); i++) {
     499                        USHORT us = i;
     500                        USHORT fShiftState = TCF_EXTENDEDKEY;
     501                        WinTranslateChar2(0, &us, NULL, TC_OEMSCANTOSCAN, &fShiftState);
     502                        m_oemScanToPmScanExt[i] = us;
     503                }
     504
     505
     506                //
     507                // map buttons (scancodes) to virtual keys
     508                //
    384509                memset(m_buttonToVK, 0, sizeof(m_buttonToVK));
    385 
    386                 // map buttons (scancodes) to virtual keys
    387510                for (KeyButton i = 1; i < 256; ++i) {
    388511            USHORT usVirtualKey = i;
     
    394517                        }
    395518                }
     519
     520
    396521
    397522                // now map virtual keys to buttons.  multiple virtual keys may map
     
    406531                        case VK_BUTTON2:
    407532                        case VK_BUTTON3:
    408                         case VK_SHIFT:
    409                         case VK_CTRL:
    410533                        case VK_MENU:
    411534                                continue;
     
    423546                        }
    424547                }
    425 
    426 /// @todo?
    427 //              // add alt+printscreen
    428 //              if (m_buttonToVK[0x54u] == 0) {
    429 //                      m_buttonToVK[0x54u] = VK_SNAPSHOT;
    430 //              }
    431548
    432549                // set virtual key to button table
     
    441558//              }
    442559
    443                 // add the keys to the map.
    444                 BYTE keys[256];
    445                 memset(keys, 0, sizeof(keys));
    446                 for (KeyButton i = 0; i < 512; ++i) {
     560                //
     561                // Add the keys to the map.
     562                //
     563                //for (KeyButton i = 0; i < 256; ++i) {
     564                for (KeyButton i = 0; i < 256; ++i) {
     565                        //
     566            // Does this translate to a virtual key or character?
     567                        //
    447568            USHORT usChar = i;
    448             USHORT fCharShiftState = 0;
    449             USHORT fCharKCFlags = WinTranslateChar2(0, &usChar, NULL, TC_SCANCODETOVIRTUALKEY, &fCharShiftState);
     569            USHORT fShiftState = 0;
     570            USHORT fCharKCFlags = WinTranslateChar2(0, &usChar, NULL, TC_SCANCODETOCHAR, &fShiftState);
     571            USHORT usVirtualKey = i;
     572            USHORT fVirtualKeyKCFlags = WinTranslateChar2(0, &usVirtualKey, NULL, TC_SCANCODETOVIRTUALKEY, &fShiftState);
     573                        if (!usChar && !usVirtualKey) {
     574                                // try with control down.
     575                                usChar = i;
     576                                fShiftState = TCF_CONTROL;
     577                                fCharKCFlags = WinTranslateChar2(0, &usChar, NULL, TC_SCANCODETOCHAR, &fShiftState);
     578                                usVirtualKey = i;
     579                                fShiftState = TCF_CONTROL;
     580                                fVirtualKeyKCFlags = WinTranslateChar2(0, &usVirtualKey, NULL, TC_SCANCODETOVIRTUALKEY, &fShiftState);
     581                        }
     582                        if (!usChar && !usVirtualKey) {
     583                                // try with altgr down.
     584                                usChar = i;
     585                                fShiftState = TCF_ALTGR;
     586                                fCharKCFlags = WinTranslateChar2(0, &usChar, NULL, TC_SCANCODETOCHAR, &fShiftState);
     587                                usVirtualKey = i;
     588                                fShiftState = TCF_ALTGR;
     589                                fVirtualKeyKCFlags = WinTranslateChar2(0, &usVirtualKey, NULL, TC_SCANCODETOVIRTUALKEY, &fShiftState);
     590                        }
     591                        if (!usChar && !usVirtualKey) {
     592                                // try with numlock toggled.
     593                                usChar = i;
     594                                fShiftState = TCF_NUMLOCK;
     595                                fCharKCFlags = WinTranslateChar2(0, &usChar, NULL, TC_SCANCODETOCHAR, &fShiftState);
     596                                usVirtualKey = i;
     597                                fShiftState = TCF_NUMLOCK;
     598                                fVirtualKeyKCFlags = WinTranslateChar2(0, &usVirtualKey, NULL, TC_SCANCODETOVIRTUALKEY, &fShiftState);
     599                        }
    450600                        if (    usChar
    451                 ||  m_buttonToVK[i]) {
    452                                 // initialize item
    453                                 item.m_id        = getKeyID(m_buttonToVK[i], i);
     601                ||  ) {
     602                                // initialize item
     603                                item.m_id        = getKeyID(m_buttonToVK[i], i);
    454604                                item.m_button    = i;
    455605                                item.m_required  = 0;
    456606                                item.m_sensitive = 0;
    457                                 item.m_client    = (m_buttonToVK[i] & 0xff) //  0-7 : virtual key.
    458                                  | (i << 8)                 //  8-15: scancode
    459                                  | (usChar & 0x3fff)        // 16-29: PM char
    460                                  | (0 << 30)                //    30: KC_DEADKEY ??
    461                                  | (0 << 31);               //    31: KC_COMPOSITE ??
     607                                item.m_dead      = false;
     608                                item.m_lock      = false;
    462609
    463610                                // get flags for modifier keys
    464611                                CKeyMap::initModifierKey(item);
    465 
    466                                 if (item.m_id == 0) {
    467 #if 0
    468                                         // translate virtual key to a character with and without
    469                                         // shift, caps lock, and AltGr.
    470                                         struct Modifier {
    471                                                 ULONG                   m_vk1;
    472                                                 ULONG                   m_vk2;
    473                                                 BYTE                    m_state;
    474                                                 KeyModifierMask m_mask;
    475                                         };
    476                                         static const Modifier modifiers[] = {
    477                                                 { VK_SHIFT,   VK_SHIFT,   0x80u, KeyModifierShift    },
    478                                                 { VK_CAPITAL, VK_CAPITAL, 0x01u, KeyModifierCapsLock },
    479                                                 { VK_CONTROL, VK_MENU,    0x80u, KeyModifierControl | KeyModifierAlt }
    480                                         };
    481                                         static const size_t s_numModifiers = sizeof(modifiers) / sizeof(modifiers[0]);
    482                                         static const size_t s_numCombinations = 1 << s_numModifiers;
    483                                         KeyID id[s_numCombinations];
    484 
    485                                         bool anyFound = false;
    486                                         KeyButton button = static_cast<KeyButton>(i & 0xffu);
    487                                         for (size_t j = 0; j < s_numCombinations; ++j) {
    488                                                 for (size_t k = 0; k < s_numModifiers; ++k) {
    489                                                         if ((j & (1 << k)) != 0) {
    490                                                                 keys[modifiers[k].m_vk1] = modifiers[k].m_state;
    491                                                                 keys[modifiers[k].m_vk2] = modifiers[k].m_state;
    492                                                         }
    493                                                         else {
    494                                                                 keys[modifiers[k].m_vk1] = 0;
    495                                                                 keys[modifiers[k].m_vk2] = 0;
    496                                                         }
    497                                                 }
    498                                                 id[j] = getIDForKey(item, button, m_buttonToVK[i], keys, m_groups[g]);
    499                                                 if (id[j] != 0) {
    500                                                         anyFound = true;
    501                                                 }
    502                                         }
    503 
    504                                         if (anyFound) {
    505                                                 // determine what modifiers we're sensitive to.
    506                                                 // we're sensitive if the KeyID changes when the
    507                                                 // modifier does.
    508                                                 item.m_sensitive = 0;
    509                                                 for (size_t k = 0; k < s_numModifiers; ++k) {
    510                                                         for (size_t j = 0; j < s_numCombinations; ++j) {
    511                                                                 if (id[j] != id[j ^ (1u << k)]) {
    512                                                                         item.m_sensitive |= modifiers[k].m_mask;
    513                                                                         break;
    514                                                                 }
    515                                                         }
    516                                                 }
    517 
    518                                                 // save each key.  the map will automatically discard
    519                                                 // duplicates, like an unshift and shifted version of
    520                                                 // a key that's insensitive to shift.
    521                                                 for (size_t j = 0; j < s_numCombinations; ++j) {
    522                                                         item.m_id       = id[j];
    523                                                         item.m_required = 0;
    524                                                         for (size_t k = 0; k < s_numModifiers; ++k) {
    525                                                                 if ((j & (1 << k)) != 0) {
    526                                                                         item.m_required |= modifiers[k].m_mask;
    527                                                                 }
    528                                                         }
    529                                                         addKeyEntry(keyMap, item);
    530                                                 }
    531                                         }
    532 #endif
    533                                 } else {
    534                                         // found in table - adjust modifiers and add it.
    535                                         switch (m_buttonToVK[i]) {
    536                                         case VK_BACKTAB:
    537                                                 item.m_required  |= KeyModifierShift;
    538                                                 item.m_sensitive |= KeyModifierShift;
    539                                                 break;
    540                                         }
    541                                         addKeyEntry(keyMap, item);
    542                                 }
    543                         }
    544                 } // for buttons 0 thru 511
     612                if (item.m_generates != 0) {
     613                    // it's a modifier key.
     614                    item.m_lock = usVirtualKey == VK_NUMLOCK
     615                               || usVirtualKey == VK_SCRLLOCK
     616                               || usVirtualKey == VK_CAPSLOCK;
     617                                        ClientData data;
     618                                        data.u = 0;
     619                                        data.s.scan       = i;
     620                                        data.s.xlatScan   = i;
     621                                        data.s.fShiftKey  = true;
     622                                        data.s.xlatChar   = usChar;
     623                                        data.s.virtualKey = usVirtualKey;
     624                                        convertScancodes(&data);
     625                                        item.m_client = data.u;
     626                    addKeyEntry(keyMap, item);
     627                } else {
     628                    //
     629                    // Check which keys it might be sensitive to.
     630                    // We assume (possibly incorrectly) that combinations doesn't matter... :)
     631                    //
     632                    static const struct {
     633                        KeyModifierMask mask;
     634                        unsigned        fShiftState;
     635                    } modifiers[] = {
     636                        { KeyModifierShift, TCF_SHIFT},
     637                        { KeyModifierControl, TCF_CONTROL },
     638                        { KeyModifierAlt, TCF_ALT },
     639                        { KeyModifierAltGr, TCF_ALTGR },
     640                        { KeyModifierCapsLock, TCF_CAPSLOCK },
     641                        { KeyModifierNumLock, TCF_NUMLOCK }
     642                    };
     643                                        usChar = i;
     644                                        fShiftState = 0;
     645                                        fCharKCFlags = WinTranslateChar2(0, &usChar, NULL, TC_SCANCODETOCHAR, &fShiftState);
     646                                        usVirtualKey = i;
     647                                        fShiftState = 0;
     648                                        fVirtualKeyKCFlags = WinTranslateChar2(0, &usVirtualKey, NULL, TC_SCANCODETOVIRTUALKEY, &fShiftState);
     649                    for (unsigned j = 0; j < sizeof(modifiers) / sizeof(modifiers[0]); j++) {
     650                        USHORT usCh = i;
     651                        fShiftState = modifiers[j].fShiftState;
     652                        if (    WinTranslateChar2(0, &usCh, NULL, TC_SCANCODETOCHAR, &fShiftState) != 0
     653                            &&  usCh != 0
     654                            &&  usCh != usChar) {
     655                            item.m_sensitive |= modifiers[j].mask;
     656                            continue;
     657                        }
     658                        usCh = i;
     659                        fShiftState = modifiers[j].fShiftState;
     660                        WinTranslateChar2(0, &usCh, NULL, TC_SCANCODETOVIRTUALKEY, &fShiftState);
     661                        if (    usCh != 0
     662                            &&  usCh != usVirtualKey) {
     663                            item.m_sensitive |= modifiers[j].mask;
     664                            continue;
     665                        }
     666                    }
     667                    if (isASCIIControlChar(usChar)) {
     668                        item.m_sensitive |= KeyModifierControl;
     669                    }
     670
     671                    //
     672                    // Check for numpad keys. We need to adjust stuff then.
     673                    // It think this test should be sufficient.
     674                    //
     675                    bool numpad = (item.m_sensitive & KeyModifierNumLock) != 0;
     676
     677                    //
     678                    // Unoptimized brute force algorithm for determining the
     679                    // possible combinations and adding them to the key map.
     680                    //
     681                    struct
     682                    {
     683                        UCHAR   uchChar;
     684                        UCHAR   uchVirtualKey;
     685                    } combinations[1 << TCF_MAX_BITS];
     686
     687                    for (unsigned j = 0; j < sizeof(combinations) / sizeof(combinations[0]); j++) {
     688                        const KeyModifierMask mask = convertTCFToKeyModiferMask(j);
     689                        if ((mask & item.m_sensitive) != mask /*|| j>3*/) {
     690                            combinations[j].uchChar = combinations[j].uchVirtualKey = 0;
     691                            continue;
     692                        }
     693                        // get any character value
     694                        USHORT us = i;
     695                        fShiftState = j;
     696                        if (WinTranslateChar2(0, &us, NULL, TC_SCANCODETOCHAR, &fShiftState) == 0) {
     697                            us = 0;
     698                        }
     699                        combinations[j].uchChar = us;
     700
     701                        // get any virtual key value
     702                        us = i;
     703                        fShiftState = j;
     704                        WinTranslateChar2(0, &us, NULL, TC_SCANCODETOVIRTUALKEY, &fShiftState);
     705                        combinations[j].uchVirtualKey = us;
     706
     707                        // deal with missing character translations
     708                        if (    combinations[j].uchChar == 0
     709                            &&  us != 0
     710                            &&  us < sizeof(s_virtualKey) / sizeof(s_virtualKey[0])) {
     711                            combinations[j].uchChar = s_virtualKey[us].ch;
     712                        }
     713                    }
     714
     715                    // 2. Eliminate duplicates.
     716                    for (unsigned j = 0; j < sizeof(combinations) / sizeof(combinations[0]); j++) {
     717                        unsigned best = j;
     718                        KeyModifierMask bestMask = convertTCFToKeyModiferMask(j);
     719                        for (unsigned k = j + 1; k < sizeof(combinations) / sizeof(combinations[0]); k++) {
     720                            if (    combinations[best].uchChar == combinations[k].uchChar
     721                                &&  combinations[best].uchVirtualKey == combinations[k].uchVirtualKey) {
     722                                const KeyModifierMask mask = convertTCFToKeyModiferMask(k);
     723                                // drop L/R mixes.
     724                                if (mask == bestMask) {
     725                                    combinations[k].uchChar = combinations[k].uchVirtualKey = 0;
     726                                }
     727                            }
     728                        }
     729                    }
     730
     731                    // 3. Add the remainders.
     732                    for (unsigned j = 0; j < sizeof(combinations) / sizeof(combinations[0]); j++) {
     733                        if (combinations[j].uchChar || combinations[j].uchVirtualKey) {
     734                            USHORT usChar = combinations[j].uchChar;
     735                            USHORT usVirtualKey = combinations[j].uchVirtualKey;
     736
     737                            // update the changing item members
     738                            item.m_required  = convertTCFToKeyModiferMask(j);
     739                            if (usVirtualKey) {
     740                                switch (usVirtualKey) {
     741                                case VK_BACKTAB:
     742                                    item.m_required  |= KeyModifierShift;
     743                                    item.m_sensitive |= KeyModifierShift;
     744                                                                        usChar                    = 0; // this one is translated incorrectly
     745                                    break;
     746                                }
     747                                item.m_id    = getKeyID(usVirtualKey, i, numpad, usChar);
     748                            } else {
     749                                item.m_id    = usChar; /// @todo translate to unicode!
     750                            }
     751                                                        ClientData data;
     752                                                        data.u = 0;
     753                                                        data.s.scan       = i;
     754                                                        data.s.xlatScan   = i;
     755                                                        data.s.xlatChar   = usChar;
     756                                                        data.s.virtualKey = usVirtualKey;
     757                                                        convertScancodes(&data);
     758                                                        item.m_client = data.u;
     759                            addKeyEntry(keyMap, item);
     760                        }
     761                    }
     762
     763                    // 4. ASCII Control Character variants. (ARG! this doesn't work, fakeMsg hacks it.)
     764                    if (isASCIIControlChar(usChar)) {
     765                        /* add key */
     766                        item.m_id        = usChar - (usChar >= 'a' ? 0x60 : 0x40);
     767                        item.m_required  = KeyModifierControl;
     768                                                ClientData data;
     769                                                data.u = 0;
     770                                                data.s.scan      = i;
     771                                                data.s.xlatScan  = i;
     772                                                data.s.xlatChar  = item.m_id;
     773                                                convertScancodes(&data);
     774                                                item.m_client    = data.u;
     775                        addKeyEntry(keyMap, item);
     776                        item.m_id        = usChar;
     777                        addKeyEntry(keyMap, item);
     778                    }
     779                }
     780                        }
     781                } // for buttons 0 thru 254
     782
     783                //
     784                // Various other keys for which we don't expect the above loops to catch.
     785                //
     786                item.m_id        = kKeyMenu;
     787                item.m_button    = 0xee;
     788                item.m_required  = 0;
     789                item.m_sensitive = 0;
     790                item.m_dead      = false;
     791                item.m_lock      = false;
     792                ClientData data;
     793                data.u = 0;
     794                data.s.scan      = 0x7c;
     795                data.s.xlatScan  = 0xee;
     796                data.s.fSecondary = true;
     797                data.s.fExtendedKey = true;
     798                data.s.fNeedNumUnlockKey = true;
     799                item.m_client    = data.u;
     800                CKeyMap::initModifierKey(item);
     801                addKeyEntry(keyMap, item);
     802
     803                item.m_id                = kKeySuper_L;
     804                item.m_button    = 0xec;
     805                data.s.xlatScan  = 0xec;
     806                data.s.scan      = 0x7e;
     807                item.m_client    = data.u;
     808                CKeyMap::initModifierKey(item);
     809                addKeyEntry(keyMap, item);
     810
     811                item.m_id                = kKeySuper_R;
     812                item.m_button    = 0xed;
     813                data.s.xlatScan  = 0xed;
     814                data.s.scan      = 0x7f;
     815                item.m_client    = data.u;
     816                CKeyMap::initModifierKey(item);
     817                addKeyEntry(keyMap, item);
     818
    545819        }
    546820
     
    557831        switch (keystroke.m_type) {
    558832        case Keystroke::kButton: {
    559                 LOG((CLOG_DEBUG1 "  %03x (%08x) %s%s", keystroke.m_data.m_button.m_button, keystroke.m_data.m_button.m_client,
     833                LOG((CLOG_DEBUG1 "  %03x (%08x) %s%s", keystroke.m_data.m_button.m_button, keystroke.m_data.m_button.m_client,
    560834             keystroke.m_data.m_button.m_press ? "down" : "up", keystroke.m_data.m_button.m_repeat ? " repeate" : ""));
    561835                KeyButton button = keystroke.m_data.m_button.m_button;
     
    569843
    570844                // unpack the m_client packet.
    571                 USHORT virtualKey = 0;//keystroke.m_data.m_button.m_client & 0xff;
    572         UCHAR  scanCode = (keystroke.m_data.m_button.m_client >> 8) & 0xff;
    573         USHORT pmChar = 0;//(keystroke.m_data.m_button.m_client >> 16) & 0xff;
    574         bool   fKC_DEADKEY = (keystroke.m_data.m_button.m_client >> 30) & 1;
    575         bool   fKC_COMPOSITE = (keystroke.m_data.m_button.m_client >> 31) & 1;
    576 
     845                ClientData data;
     846                data.u = keystroke.m_data.m_button.m_client;
     847
     848        //
    577849        // synthesize message
     850
     851
     852
     853
     854
     855
     856
     857
     858
     859
     860
     861
     862
     863
    578864        HAB hab = CPMUtil::getHAB();/// @todo fix this
    579865        QMSG qmsg;
    580866        qmsg.hwnd = NULLHANDLE;
    581         qmsg.msg = WM_CHAR;
     867        qmsg.msg = WM_CHAR;
    582868        qmsg.ptl.x = 0;
    583869        qmsg.ptl.y = 0;
     
    585871        qmsg.reserved = 0;
    586872
    587         // mp2
    588         if (!keystroke.m_data.m_button.m_press) {
    589             pmChar |= 0x0e00; /// @todo figure out what's going on here...
     873        //
     874        // calc the key code flags.
     875        // PM deals with: KC_TOGGLE, KC_VIRTUALKEY, KC_CHAR, (WM_CHAR: also KC_CTRL, KC_ALT, KC_SHIFT).
     876        //
     877        USHORT fKC = 0;
     878        if (data.s.scan)
     879            fKC |= KC_SCANCODE;
     880        if (!keystroke.m_data.m_button.m_press)
     881            fKC |= KC_KEYUP;
     882        /// @todo check that PM does KC_INVALIDCOMP
     883        if (data.s.fDeadKey)
     884            fKC |= KC_DEADKEY;
     885        if (data.s.fComposite)
     886            fKC |= KC_COMPOSITE;
     887        if (!keystroke.m_data.m_button.m_press && m_lastButton == data.s.scan)
     888            fKC |= KC_LONEKEY;
     889
     890        // we need these for calcing fKDD, so just put them in even if PM can do it for us.
     891        KeyModifierMask modifierMask = this->getActiveModifiers();
     892        if (modifierMask & KeyModifierShift)
     893            fKC |= KC_SHIFT;
     894        if (modifierMask & KeyModifierControl)
     895            fKC |= KC_CTRL;
     896        if (modifierMask & KeyModifierAlt)
     897            fKC |= KC_ALT;
     898
     899        //
     900        // Calc the keyboard device driver flags.
     901        //
     902        USHORT fKDD;
     903        // the action
     904        if (data.s.fShiftKey)
     905            fKDD = KDD_SHIFTKEY;
     906/** @todo Determin the KDD_ACTIONMASK value.
     907KDD_PREFIXKEY
     908KDD_PAUSEKEY
     909KDD_PSEUDOPAUSE
     910KDD_WAKEUPKEY
     911KDD_BREAKKEY
     912KDD_PSEUDOBREAK
     913KDD_PRTECHOKEY
     914KDD_PSEUDOPRECH */
     915        else
     916            fKDD = KDD_PUTINKIB;
     917#if 0
     918        if (fKC & KC_LONEKEY)       fKDD |= KDD_KC_LONEKEY;
     919        if (fKC & KC_PREVDOWN)      fKDD |= KDD_KC_PREVDOWN;
     920        if (fKC & KC_KEYUP)         fKDD |= KDD_KC_KEYUP | KDD_BREAK;
     921        if (fKC & KC_ALT)           fKDD |= KDD_KC_ALT;
     922        if (fKC & KC_CTRL)          fKDD |= KDD_KC_CTRL;
     923        if (fKC & KC_SHIFT)         fKDD |= KDD_KC_SHIFT;
     924#else
     925        if (fKC & KC_KEYUP)         fKDD |= KDD_BREAK;
     926#endif
     927        if (data.s.fSecondary)      fKDD |= KDD_SECONDARY;
     928        if (data.s.fExtendedKey)    fKDD |= KDD_EXTENDEDKEY;
     929
     930        //
     931        // Adjust char for ASCII control keys. (Ctrl+C and stuff)
     932        //
     933        if (    (fKC & KC_CTRL)
     934            &&  isASCIIControlChar(data.s.xlatChar)) {
     935            data.s.xlatChar -= (data.s.xlatChar >= 'a' ? 0x60 : 0x40);
    590936        }
    591         qmsg.mp2 = MPFROM2SHORT(pmChar, virtualKey);
    592 
    593         // mp1
    594         USHORT fFlags = 0;
    595         if (!keystroke.m_data.m_button.m_press) {
    596             fFlags |= KC_KEYUP;
    597             /// @todo KC_LONEKEY and KC_TOGGLE, or will PM take care of that?
     937
     938                //
     939                // For some keys (navigation and edit keys left to the numpad),
     940                // any numlock or shift needs to be 'canceled'.
     941                // (At least this happens with my logitech diNovo keyboards.)
     942                //
     943        if (    data.s.fNeedNumUnlockKey
     944                        &&      (       (modifierMask & (KeyModifierShift | KeyModifierNumLock)) == KeyModifierNumLock
     945                                 ||     (modifierMask & (KeyModifierShift | KeyModifierNumLock)) == KeyModifierShift)) {
     946                        // need to insert a key nullifying the numlock/shift.
     947                        QMSG qmsg0 = qmsg;
     948                        qmsg0.mp1 = MPFROMSH2CH(fKC & KC_KEYUP, 1, 0);
     949                        qmsg0.mp2 = MPFROM2SHORT(MAKESHORT(0, 0x2a), (fKDD & KDD_BREAK) | KDD_UNDEFINED | KDD_SECONDARY | KDD_EXTENDEDKEY);
     950
     951                        // this message comes first on keydown and last on keyup.
     952                        if (fKC & KC_KEYUP) {
     953                                QMSG tmp = qmsg;
     954                                qmsg = qmsg0;
     955                                qmsg0 = tmp;
     956                        }
     957
     958                        LOG((CLOG_INFO "WM_VIOCHAR: fKC=%04x rep=%02x scan=%02x xlch=%02x(%c) xlscan=%02x fKDD=%04x ",
     959                                 SHORT1FROMMP(qmsg0.mp1), CHAR3FROMMP(qmsg0.mp1), CHAR4FROMMP(qmsg0.mp1), CHAR1FROMMP(qmsg0.mp2),
     960                                 isprint(CHAR1FROMMP(qmsg0.mp2)) ? CHAR1FROMMP(qmsg0.mp2) : '.', CHAR2FROMMP(qmsg0.mp2), SHORT2FROMMP(qmsg0.mp2)));
     961                        const char *pszError = m_fakeMsg(hab, &qmsg0);
     962                        if (pszError) {
     963                                LOG((CLOG_ERR " fakeMsg failed to inject msg=%#lx mp1=%#lx mp2=%#lx: %s", qmsg0.msg, qmsg0.mp1, qmsg0.mp2, pszError));
     964                        }
    598965        }
    599         /// @todo check that PM does KC_CTRL, KC_ALT and KC_SHIFT.
    600         /// @todo check that PM does KC_INVALIDCOMP
    601         if (fKC_DEADKEY)    fFlags |= KC_DEADKEY;
    602         if (fKC_COMPOSITE)  fFlags |= KC_COMPOSITE;
    603 //        if (virtualKey)     fFlags |= KC_VIRTUALKEY;
    604 //        if (keystroke.m_data.m_button.m_press && pmChar)
    605 //                            fFlags |= KC_CHAR;
    606         if (scanCode)       fFlags |= KC_SCANCODE;
    607         if (!keystroke.m_data.m_button.m_press && m_lastButton == scanCode)
    608                             fFlags |= KC_LONEKEY;
    609         // PM does: KC_TOGGLE, KC_CTRL, KC_ALT, KC_SHIFT. more?
    610         qmsg.mp1 = MPFROMSH2CH(fFlags, 1, scanCode); /** @todo translate the scan code back to its untranslated form. */
    611 
    612         // finaly inject it.
     966
     967                //
     968                // Inject the (last) message.
     969                //
     970        qmsg.mp1 = MPFROMSH2CH(fKC, 1, data.s.scan);
     971        qmsg.mp2 = MPFROM2SHORT(MAKESHORT(data.s.xlatChar, data.s.xlatScan), fKDD);
     972        LOG((CLOG_INFO "WM_VIOCHAR: fKC=%04x rep=%02x scan=%02x xlch=%02x(%c) xlscan=%02x fKDD=%04x ",
     973             SHORT1FROMMP(qmsg.mp1), CHAR3FROMMP(qmsg.mp1), CHAR4FROMMP(qmsg.mp1), CHAR1FROMMP(qmsg.mp2),
     974             isprint(CHAR1FROMMP(qmsg.mp2)) ? CHAR1FROMMP(qmsg.mp2) : '.', CHAR2FROMMP(qmsg.mp2), SHORT2FROMMP(qmsg.mp2)));
    613975        const char *pszError = m_fakeMsg(hab, &qmsg);
    614976        if (pszError) {
     
    618980        // remember the previous key for KC_LONEKEY.
    619981        if (keystroke.m_data.m_button.m_press && !keystroke.m_data.m_button.m_repeat)
    620             m_lastButton = scanCode;
     982            m_lastButton = ;
    621983                break;
    622984        }
     
    6541016
    6551017KeyID
    656 CPMKeyState::getKeyID(ULONG virtualKey, KeyButton button)
     1018CPMKeyState::getKeyID(ULONG virtualKey, KeyButton button)
    6571019{
    6581020    LOG((CLOG_DEBUG "getKeyID:"));
    659 //      if ((button & 0x100u) != 0) {
    660 //              virtualKey += 0x100u;
    661 //      }
    662 //      return s_virtualKey[virtualKey];
    663         return  virtualKey < sizeof(s_virtualKey) / sizeof(s_virtualKey[0])
    664         ?  s_virtualKey[virtualKey]
    665         : kKeyNone;
     1021    if (virtualKey < sizeof(s_virtualKey) / sizeof(s_virtualKey[0])) {
     1022
     1023                //
     1024                // Numpad kludge.
     1025                //
     1026        if (numpad && s_virtualKey[virtualKey].numpad) {
     1027            switch (usChar) {
     1028                case '=':   return kKeyKP_Equal;
     1029                case '*':   return kKeyKP_Multiply;
     1030                case '+':   return kKeyKP_Add;
     1031                //case ',':
     1032                //case '.':   return kKeyKP_Separator ? kKeyKP_Decimal;
     1033                case '-':   return kKeyKP_Subtract;
     1034                case '/':   return kKeyKP_Divide;
     1035                case '0':   return kKeyKP_0;
     1036                case '1':   return kKeyKP_1;
     1037                case '2':   return kKeyKP_2;
     1038                case '3':   return kKeyKP_3;
     1039                case '4':   return kKeyKP_4;
     1040                case '5':   return kKeyKP_5;
     1041                case '6':   return kKeyKP_6;
     1042                case '7':   return kKeyKP_7;
     1043                case '8':   return kKeyKP_8;
     1044                case '9':   return kKeyKP_9;
     1045                case ' ':   return kKeyKP_Space;
     1046            }
     1047            switch (s_virtualKey[virtualKey].key) {
     1048               case kKeyHome:       return kKeyKP_Home;
     1049               case kKeyLeft:       return kKeyKP_Left;
     1050               case kKeyUp:         return kKeyKP_Up;
     1051               case kKeyRight:      return kKeyKP_Right;
     1052               case kKeyDown:       return kKeyKP_Down;
     1053               case kKeyPageUp:     return kKeyKP_PageUp;
     1054               case kKeyPageDown:   return kKeyKP_PageDown;
     1055               case kKeyEnd:        return kKeyKP_End;
     1056               case kKeyBegin:      return kKeyKP_Begin;
     1057               case kKeyInsert:     return kKeyKP_Insert;
     1058               case kKeyDelete:     return kKeyKP_Delete;
     1059            }
     1060        } else {
     1061                        //
     1062                        // Left/right shift and control kludge.
     1063                        //
     1064            switch (virtualKey) {
     1065                case VK_CTRL:
     1066                    if (m_virtualKeyToButton[VK_CTRL] != button) {
     1067                        return kKeyControl_R;
     1068                    }
     1069                    break;
     1070                case VK_SHIFT:
     1071                    if (m_virtualKeyToButton[VK_SHIFT] != button) {
     1072                        return kKeyShift_R;
     1073                    }
     1074                    break;
     1075            }
     1076        }
     1077        return s_virtualKey[virtualKey].key;
     1078    }
     1079    return kKeyNone;
    6661080}
    6671081
     
    7001114}
    7011115
     1116
     1117
     1118
     1119
     1120
     1121
     1122
     1123
     1124
     1125
     1126
     1127
     1128
     1129
     1130
     1131
     1132
     1133
     1134
     1135
     1136
    7021137void
    7031138CPMKeyState::addKeyEntry(CKeyMap& keyMap, CKeyMap::KeyItem& item)
    7041139{
    705     LOG((CLOG_DEBUG "addKeyEntry:"));
    706         keyMap.addKeyEntry(item);
     1140        ClientData data; data.u = item.m_client; assert(sizeof(data.u) == sizeof(data));
     1141    LOG((CLOG_DEBUG
     1142         "addKeyEntry: scan=%02x+%02x req=%c%c%c%c%c%c[%c%c%c%c%c%c]{%x} id=%04x(%c) xlatChar=%02x(%c) scan=%02x xlatScan=%02x [%s]%s%s%s%s%s%s",
     1143         item.m_button, convertKeyModiferMaskToTCF(item.m_required),
     1144         item.m_required & KeyModifierShift ? 'S' : '-',
     1145         item.m_required & KeyModifierControl ? 'C' : '-',
     1146         item.m_required & KeyModifierAlt ? 'A' : '-',
     1147         item.m_required & KeyModifierAltGr ? 'R' : '-',
     1148         item.m_required & KeyModifierCapsLock ? 'U' : '-',
     1149         item.m_required & KeyModifierNumLock ? 'N' : '-',
     1150         item.m_sensitive & KeyModifierShift ? 'S' : '-',
     1151         item.m_sensitive & KeyModifierControl ? 'C' : '-',
     1152         item.m_sensitive & KeyModifierAlt ? 'A' : '-',
     1153         item.m_sensitive & KeyModifierAltGr ? 'R' : '-',
     1154         item.m_sensitive & KeyModifierCapsLock ? 'U' : '-',
     1155         item.m_sensitive & KeyModifierNumLock ? 'N' : '-',
     1156         item.m_generates,
     1157         item.m_id,             item.m_id < 128 && isprint(item.m_id)       ? item.m_id       : '.',
     1158                 data.s.xlatChar, data.s.xlatChar < 128 && isprint(data.s.xlatChar) ? data.s.xlatChar : '.',
     1159                 data.s.scan, data.s.xlatScan,
     1160         getKeyName(item.m_id),
     1161         data.s.fExtendedKey ? " extendedkey" : "",
     1162         data.s.fShiftKey    ? " shiftkey" : "",
     1163         data.s.fDeadKey     ? " deadkey" : "",
     1164         data.s.fComposite   ? " composite" : "",
     1165         item.m_lock         ? " lock" : "",
     1166         item.m_dead         ? " dead" : ""
     1167         ));
     1168        if (data.s.scan2 || data.s.xlatScan2) {
     1169                LOG((CLOG_DEBUG
     1170                         "addKeyEntry: xlatChar2=%02x(%c) scan2=%02x xlatScan2=%02x",
     1171                         data.s.xlatChar2, data.s.xlatChar2 < 128 && isprint(data.s.xlatChar2) ? data.s.xlatChar2 : '.',
     1172                         data.s.scan2, data.s.xlatScan2));
     1173        }
     1174
     1175        if (!keyMap.addKeyEntry(item)) {
     1176                LOG((CLOG_DEBUG "!not accepted!"));
     1177    }
    7071178        if (item.m_group == 0) {
    7081179                m_keyToVKMap[item.m_id] = item.m_client;
Note: See TracChangeset for help on using the changeset viewer.