Changeset 2768


Ignore:
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.

Location:
trunk/synergy/lib
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/synergy/lib/common/BasicTypes.h

    r2749 r2768  
    22 * synergy -- mouse and keyboard sharing utility
    33 * Copyright (C) 2002 Chris Schoeneman
    4  * 
     4 *
    55 * This package is free software; you can redistribute it and/or
    66 * modify it under the terms of the GNU General Public License
    77 * found in the file COPYING that should have accompanied this file.
    8  * 
     8 *
    99 * This package is distributed in the hope that it will be useful,
    1010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     
    4545#endif
    4646
     47#if !defined(TYPE_OF_SIZE_8)
     48#       ifdef _MSC_VER
     49#               define TYPE_OF_SIZE_8 _int64
     50#       else
     51#               define TYPE_OF_SIZE_8 long long
     52#       endif
     53#endif
     54
    4755//
    4856// verify existence of required types
     
    5765#if !defined(TYPE_OF_SIZE_4)
    5866#       error No 4 byte integer type
     67#endif
     68#if !defined(TYPE_OF_SIZE_8)
     69#       error No 8 byte integer type
    5970#endif
    6071
     
    7182typedef signed TYPE_OF_SIZE_2   SInt16;
    7283typedef signed TYPE_OF_SIZE_4   SInt32;
     84typedef signed TYPE_OF_SIZE_8   SInt64;
    7385
    7486typedef unsigned TYPE_OF_SIZE_1 UInt8;
    7587typedef unsigned TYPE_OF_SIZE_2 UInt16;
    7688typedef unsigned TYPE_OF_SIZE_4 UInt32;
     89typedef unsigned TYPE_OF_SIZE_8 UInt64;
    7790
    7891//
     
    8396#undef TYPE_OF_SIZE_2
    8497#undef TYPE_OF_SIZE_4
     98#undef TYPE_OF_SIZE_8
    8599
    86100#endif
  • trunk/synergy/lib/platform/CMSWindowsKeyState.cpp

    r2753 r2768  
    11891189        switch (keystroke.m_type) {
    11901190        case Keystroke::kButton: {
    1191                 LOG((CLOG_DEBUG1 "  %03x (%08x) %s", keystroke.m_data.m_button.m_button, keystroke.m_data.m_button.m_client, keystroke.m_data.m_button.m_press ? "down" : "up"));
     1191                LOG((CLOG_DEBUG1 "  %03x (%08x) %s", keystroke.m_data.m_button.m_button, (UInt32)keystroke.m_data.m_button.m_client, keystroke.m_data.m_button.m_press ? "down" : "up"));
    11921192                KeyButton button = keystroke.m_data.m_button.m_button;
    11931193
     
    12001200
    12011201                // get the virtual key for the button
    1202                 UINT vk = keystroke.m_data.m_button.m_client;
     1202                UINT vk = (UINT)keystroke.m_data.m_button.m_client;
    12031203
    12041204                // special handling of VK_SNAPSHOT
  • trunk/synergy/lib/platform/COSXKeyState.cpp

    r2749 r2768  
    22 * synergy -- mouse and keyboard sharing utility
    33 * Copyright (C) 2004 Chris Schoeneman
    4  * 
     4 *
    55 * This package is free software; you can redistribute it and/or
    66 * modify it under the terms of the GNU General Public License
    77 * found in the file COPYING that should have accompanied this file.
    8  * 
     8 *
    99 * This package is distributed in the hope that it will be useful,
    1010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     
    145145}
    146146
    147 KeyButton 
     147KeyButton
    148148COSXKeyState::mapKeyFromEvent(CKeyIDs& ids,
    149149                                KeyModifierMask* maskOut, EventRef event) const
     
    366366        switch (keystroke.m_type) {
    367367        case Keystroke::kButton:
    368                 LOG((CLOG_DEBUG1 "  %03x (%08x) %s", keystroke.m_data.m_button.m_button, keystroke.m_data.m_button.m_client, keystroke.m_data.m_button.m_press ? "down" : "up"));
     368                LOG((CLOG_DEBUG1 "  %03x (%08x) %s", keystroke.m_data.m_button.m_button, (UInt32)keystroke.m_data.m_button.m_client, keystroke.m_data.m_button.m_press ? "down" : "up"));
    369369
    370370                // let system figure out character for us
     
    552552        }
    553553        macVirtualKey = mapKeyButtonToVirtualKey(button);
    554        
     554
    555555        // calculate modifier mask
    556556        macModifierMask = 0;
     
    570570                macModifierMask |= alphaLock;
    571571        }
    572        
     572
    573573        return true;
    574574}
    575                                                
     575
    576576void
    577577COSXKeyState::handleModifierKeys(void* target,
  • 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::VirtualKey   CPMKeyState::s_virtualKey[0x42] =
     31{
     32{ /* 0x000 */ kKeyNone,         0,    0,    0 },    // reserved
     33{ /* 0x001 */ kKeyNone,         0,    0,    0 },    // VK_BUTTON1
     34{ /* 0x002 */ kKeyNone,         0,    0,    0 },    // VK_BUTTON2
     35{ /* 0x003 */ kKeyNone,         0,    0,    0 },    // VK_BUTTON3
     36{ /* 0x004 */ kKeyBreak,        0,    0,    0 },    // VK_BREAK
     37{ /* 0x005 */ kKeyBackSpace,    8,    0,    0 },    // VK_BACKSPACE
     38{ /* 0x006 */ kKeyTab,          9,    0,    0 },    // VK_TAB
     39{ /* 0x007 */ kKeyLeftTab,      9,    0,    1 },    // VK_BACKTAB
     40{ /* 0x008 */ kKeyReturn,    0x0d,    0,    0 },    // VK_NEWLINE
     41{ /* 0x009 */ kKeyShift_L,      0,    0,    0 },    // VK_SHIFT
     42{ /* 0x00a */ kKeyControl_L,    0,    0,    0 },    // VK_CTRL
     43{ /* 0x00b */ kKeyAlt_L,        0,    0,    0 },    // VK_ALT
     44{ /* 0x00c */ kKeyAltGr,        0,    0,    0 },    // VK_ALTGRAF
     45{ /* 0x00d */ kKeyPause,        0,    0,    0 },    // VK_PAUSE
     46{ /* 0x00e */ kKeyCapsLock,     0,    0,    0 },    // VK_CAPSLOCK
     47{ /* 0x00f */ kKeyEscape,    0x1b,    0,    0 },    // VK_ESC
     48{ /* 0x010 */ ' ',           0x20,    0,    0 },    // VK_SPACE
     49{ /* 0x011 */ kKeyPageUp,    0xe0,    1,   -1 },    // VK_PAGEUP
     50{ /* 0x012 */ kKeyPageDown,  0xe0,    1,   -1 },    // VK_PAGEDOWN
     51{ /* 0x013 */ kKeyEnd,       0xe0,    1,   -1 },    // VK_END
     52{ /* 0x014 */ kKeyHome,      0xe0,    1,   -1 },    // VK_HOME
     53{ /* 0x015 */ kKeyLeft,      0xe0,    1,   -1 },    // VK_LEFT
     54{ /* 0x016 */ kKeyUp,        0xe0,    1,   -1 },    // VK_UP
     55{ /* 0x017 */ kKeyRight,     0xe0,    1,   -1 },    // VK_RIGHT
     56{ /* 0x018 */ kKeyDown,      0xe0,    1,   -1 },    // VK_DOWN
     57{ /* 0x019 */ kKeyNone,      0xe0,    0,    0 },    // VK_PRINTSCRN
     58{ /* 0x01a */ kKeyInsert,    0xe0,    1,    1 },    // VK_INSERT
     59{ /* 0x01b */ kKeyDelete,    0xe0,    1,    1 },    // VK_DELETE
     60{ /* 0x01c */ kKeyScrollLock,   0,    0,    0 },    // VK_SCRLLOCK
     61{ /* 0x01d */ kKeyNumLock,      0,    0,    0 },    // VK_NUMLOCK
     62{ /* 0x01e */ kKeyKP_Enter,  0x0d,    1,    1 },    // VK_ENTER
     63{ /* 0x01f */ kKeySysReq,       0,    0,    0 },    // VK_SYSRQ
     64{ /* 0x020 */ kKeyF1,           0,    0,    1 },    // VK_F1
     65{ /* 0x021 */ kKeyF2,           0,    0,    1 },    // VK_F2
     66{ /* 0x022 */ kKeyF3,           0,    0,    1 },    // VK_F3
     67{ /* 0x023 */ kKeyF4,           0,    0,    1 },    // VK_F4
     68{ /* 0x024 */ kKeyF5,           0,    0,    1 },    // VK_F5
     69{ /* 0x025 */ kKeyF6,           0,    0,    1 },    // VK_F6
     70{ /* 0x026 */ kKeyF7,           0,    0,    1 },    // VK_F7
     71{ /* 0x027 */ kKeyF8,           0,    0,    1 },    // VK_F8
     72{ /* 0x028 */ kKeyF9,           0,    0,    1 },    // VK_F9
     73{ /* 0x029 */ kKeyF10,          0,    0,    1 },    // VK_F10
     74{ /* 0x02a */ kKeyF11,          0,    0,    1 },    // VK_F11
     75{ /* 0x02b */ kKeyF12,          0,    0,    1 },    // VK_F12
     76{ /* 0x02c */ kKeyF13,          0,    0,    1 },    // VK_F13
     77{ /* 0x02d */ kKeyF14,          0,    0,    1 },    // VK_F14
     78{ /* 0x02e */ kKeyF15,          0,    0,    1 },    // VK_F15
     79{ /* 0x02f */ kKeyF16,          0,    0,    1 },    // VK_F16
     80{ /* 0x030 */ kKeyF17,          0,    0,    1 },    // VK_F17
     81{ /* 0x031 */ kKeyF18,          0,    0,    1 },    // VK_F18
     82{ /* 0x032 */ kKeyF19,          0,    0,    1 },    // VK_F19
     83{ /* 0x033 */ kKeyF20,          0,    0,    1 },    // VK_F20
     84{ /* 0x034 */ kKeyF21,          0,    0,    1 },    // VK_F21
     85{ /* 0x035 */ kKeyF22,          0,    0,    1 },    // VK_F22
     86{ /* 0x036 */ kKeyF23,          0,    0,    1 },    // VK_F23
     87{ /* 0x037 */ kKeyF24,          0,    0,    1 },    // VK_F24
     88{ /* 0x038 */ kKeyNone,         0,    0,    0 },    // VK_ENDDRAG
     89{ /* 0x039 */ kKeyNone,         0,    0,    0 },    // VK_CLEAR
     90{ /* 0x03a */ kKeyNone,         0,    0,    0 },    // VK_EREOF
     91{ /* 0x03b */ kKeyNone,         0,    0,    0 },    // VK_PA1
     92{ /* 0x03c */ kKeyNone,         0,    0,    0 },    // VK_ATTN
     93{ /* 0x03d */ kKeyNone,         0,    0,    0 },    // VK_CRSEL
     94{ /* 0x03e */ kKeyNone,         0,    0,    0 },    // VK_EXSEL
     95{ /* 0x03f */ kKeyNone,         0,    0,    0 },    // VK_COPY
     96{ /* 0x040 */ kKeyNone,         0,    0,    0 },    // VK_BLK1
     97{ /* 0x041 */ kKeyNone,         0,    0,    0 },    // VK_BLK2
    9898};
    9999
     
    354354}
    355355
     356static USHORT
     357convertKeyModiferMaskToTCF(const KeyModifierMask mask)
     358{
     359    USHORT fShiftState = 0;
     360    if (mask & KeyModifierShift)    fShiftState |= TCF_SHIFT;
     361    if (mask & KeyModifierControl)  fShiftState |= TCF_CONTROL;
     362    if (mask & KeyModifierAlt)      fShiftState |= TCF_ALT;
     363    if (mask & KeyModifierAltGr)    fShiftState |= TCF_ALTGR;
     364    if (mask & KeyModifierCapsLock) fShiftState |= TCF_CAPSLOCK;
     365    if (mask & KeyModifierNumLock)  fShiftState |= TCF_NUMLOCK;
     366    return fShiftState;
     367}
     368
     369static KeyModifierMask
     370convertTCFToKeyModiferMask(const USHORT fShiftState)
     371{
     372    KeyModifierMask mask = 0;
     373    if (fShiftState & TCF_SHIFT)    mask |= KeyModifierShift;
     374    if (fShiftState & TCF_CONTROL)  mask |= KeyModifierControl;
     375    if (fShiftState & TCF_ALT)      mask |= KeyModifierAlt;
     376    if (fShiftState & TCF_ALTGR)    mask |= KeyModifierAltGr;
     377    if (fShiftState & TCF_CAPSLOCK) mask |= KeyModifierCapsLock;
     378    if (fShiftState & TCF_NUMLOCK)  mask |= KeyModifierNumLock;
     379    return mask;
     380}
     381
     382static bool
     383isASCIIControlChar(const USHORT usChar)
     384{
     385    switch (usChar) {
     386        /* Skip the ones with virtual keys. */
     387        case 0x08 + 0x40: case 0x08 + 0x60: // backspace
     388        case 0x09 + 0x40: case 0x09 + 0x60: // horizontal tab
     389        case 0x1b + 0x40: case 0x1b + 0x60: // escape
     390        case 0x0d + 0x40: case 0x0d + 0x60: // return
     391            return false;
     392        default:
     393            return (usChar >= 'A' && usChar <= '_')
     394                || (usChar >= 'a' && usChar <= 'z');
     395    }
     396}
     397
     398void
     399CPMKeyState::convertScancodes(ClientData *pData)
     400{
     401        /*
     402         * This is a bit tricky / hackish, but what we have to do here is to
     403         * deal with extended keys and the keypad stuff. The scancode
     404         * translation tables doesn't seem to be 100% correct for these
     405         * keys, and these keys are the ones we need them the most. sigh.
     406     */
     407
     408        //
     409        // navigation and insert/delete buttons left of the numpad:
     410        //              home, up, pgup, left, right, end, down, pgdn, insert, delete
     411        //
     412        // The pm and translated scancodes are mixed up in these cases.
     413        // The keys are all extended and secondary.
     414        //
     415        if (    pData->s.xlatScan >= 0x60 /* VK_HOME */
     416                &&      pData->s.xlatScan <= 0x69 /* VK_DELETE */
     417                &&  pData->s.virtualKey != 0) {
     418                pData->s.scan = pData->s.xlatScan;
     419                pData->s.xlatScan = m_pmScanToOemScanExt[pData->s.xlatScan];
     420                pData->s.fExtendedKey = true;
     421                pData->s.fNeedNumUnlockKey = true;
     422                pData->s.fSecondary = true;
     423                return;
     424        }
     425
     426        //
     427        // There are some virtual keys we know are extended, mark them so (like the Fxx keys).
     428        //
     429        if (    pData->s.virtualKey < sizeof(s_virtualKey) / sizeof(s_virtualKey[0])
     430                &&      !pData->s.fExtendedKey) {
     431                if (    s_virtualKey[pData->s.virtualKey].extended == 1
     432                        ||  (   s_virtualKey[pData->s.virtualKey].extended == -1
     433                                 && (   pData->s.xlatChar == 0
     434                                         || pData->s.xlatChar == s_virtualKey[pData->s.virtualKey].ch))) {
     435                        pData->s.fExtendedKey = true;
     436                }
     437        }
     438
     439        //
     440        // Do the translating.
     441        //
     442        if (pData->s.xlatScan == pData->s.scan) {
     443                pData->s.scan = m_pmScanToOemScan[pData->s.xlatScan];
     444                //if (pData->s.fExtendedKey) {
     445                //      pData->s.scan = m_pmScanToOemScanExt[pData->s.xlatScan];
     446                //} else {
     447                //      pData->s.scan = m_pmScanToOemScan[pData->s.xlatScan];
     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/// @todo the stuff down to the button loop isn't really done yet.
    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                ||  usVirtualKey) {
     602                                // initialize the item
     603                                item.m_id        = getKeyID(m_buttonToVK[i], i, false, usChar);
    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 (%08llx) %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        // There are two options at this point, WM_CHAR or WM_VIOCHAR. It seems
     851        // like WM_VIOCHAR is the better choice since that's the form in which
     852        // keyboard events normally arrive in the system queue.
     853        //
     854        // WM_VIOCHAR:
     855        //      mp1.s1: KC_ flags.
     856        //      mp1.c3: repeat
     857        //      mp1.c4: scancode
     858        //      mp2.c1: translated char
     859        //      mp2.c2: translated scancode
     860        //      mp2.s2: KDD_ flags.
     861        //
     862
     863        // the standard bits.
    578864        HAB hab = CPMUtil::getHAB();/// @todo fix this
    579865        QMSG qmsg;
    580866        qmsg.hwnd = NULLHANDLE;
    581         qmsg.msg = WM_CHAR;
     867        qmsg.msg = WM_VIOCHAR;
    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 = data.s.scan;
    621983                break;
    622984        }
     
    6541016
    6551017KeyID
    656 CPMKeyState::getKeyID(ULONG virtualKey, KeyButton button)
     1018CPMKeyState::getKeyID(ULONG virtualKey, KeyButton button, bool numpad, USHORT usChar)
    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
     1116static const char *
     1117getKeyName(KeyID key)
     1118{
     1119    const KeyNameMapEntry *entry = &kKeyNameMap[0];
     1120    while (entry->m_id != kKeyNone) {
     1121        if (entry->m_id == key) {
     1122            return entry->m_name;
     1123        }
     1124        entry++;
     1125    }
     1126    /* ASCII? */
     1127    static char s_buf[2][2];
     1128    static char s_idxBuf;
     1129    if (key >= ' ' && key <= 'z') {
     1130        char *buf = &s_buf[s_idxBuf = (s_idxBuf + 1) % 2][0];
     1131        *buf = key;
     1132        return buf;
     1133    }
     1134    return "";
     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;
  • trunk/synergy/lib/platform/CPMKeyState.h

    r2765 r2768  
    113113        no such key.
    114114        */
    115         static KeyID            getKeyID(ULONG virtualKey, KeyButton button);
     115        KeyID                   getKeyID(ULONG virtualKey, KeyButton button, bool fNumPadKey, USHORT usChar);
    116116
    117117        //@}
     
    142142
    143143private:
     144        typedef union {
     145                /** the 64-bit data view. */
     146                UInt64                  u;
     147                /** the struct view. */
     148                struct
     149                {
     150                        /** The pm scan code. */
     151                        unsigned        xlatScan : 8;
     152                        /** The char. */
     153                        unsigned        xlatChar: 8;
     154                        /** The raw scan code. */
     155                        unsigned        scan : 7;
     156                        /** KDD_EXTENDEDKEY. */
     157                        unsigned        fExtendedKey : 1;
     158                        /** The pm scan code of the 2nd message. */
     159                        unsigned        xlatScan2 : 8;
     160                        /** The char of the 2nd message. */
     161                        unsigned        xlatChar2: 8;
     162                        /** The raw scan code of the 2nd message. */
     163                        unsigned        scan2 : 7;
     164                        /** KDD_SECONDARY. */
     165                        unsigned        fSecondary : 1;
     166                        /** The virtual key. */
     167                        unsigned        virtualKey : 7;
     168                        /** KC_DEADKEY. */
     169                        unsigned        fDeadKey : 1;
     170                        /** KC_COMPOSITE. */
     171                        unsigned        fComposite : 1;
     172                        /** shift key. */
     173                        unsigned        fShiftKey : 1;
     174                        /** Indicates that the key requires the xlscan=2a KDD_SECONADARY+KDD_UNDEFINED+KDD_UNDEFINED
     175                         * key if numlock is effective. */
     176                        unsigned        fNeedNumUnlockKey : 1;
     177                        /** Bits we haven't used yet. */
     178                        unsigned    fReserved : 4;
     179                } s;
     180        } ClientData;
     181
     182        void                            convertScancodes(ClientData *pData);
    144183        KeyID                           getIDForKey(CKeyMap::KeyItem& item,
    145184                                                        KeyButton button, ULONG virtualKey,
     
    160199        KeyToVKMap                      m_keyToVKMap;
    161200
     201        // scan code conversions.
     202        UInt8                           m_pmScanToOemScan[256];
     203        UInt8                           m_pmScanToOemScanExt[256];
     204        UInt8                           m_oemScanToPmScan[128];
     205        UInt8                           m_oemScanToPmScanExt[128];
     206
    162207    // function which can inject fake WM_CHAR messages.
    163208    FakeMsgFunc                 m_fakeMsg;
     
    180225        KeyModifierMask         m_originalSavedModifiers;
    181226
    182         static const KeyID      s_virtualKey[0x42];
     227    typedef struct {
     228        KeyID           key;
     229        unsigned char   ch;
     230        bool            numpad;
     231        char            extended;
     232    } VirtualKey;
     233        static const VirtualKey s_virtualKey[0x42];
    183234};
    184235
  • trunk/synergy/lib/platform/CPMSynergyHook.cpp

    r2764 r2768  
    2222#include <InnoTekLIBC/FastInfoBlocks.h>
    2323#else
    24 unsigned long fibGetMsCount(void )
     24unsigned long fibGetMsCount(void)
    2525{
    2626    ULONG ul = 0;
     
    5050}
    5151
    52 #endif 
     52#endif
    5353
    5454//
     
    542542 * @param   hab         The hab of the current thread.
    543543 * @param   pqmsg       Where to put the message.
    544  * @param   fSkip       Skip message flag. 
     544 * @param   fSkip       Skip message flag.
    545545 *                      If TRUE we should just skip a message (pqmsg is NULL). If no futher
    546546 *                      messages are queued, we must release the hook.
     
    567567    } else {
    568568        *pqmsg = g_qmsg;
    569     }
    570 
     569        if (pqmsg->msg == WM_VIOCHAR) {
     570            /* mp1.s1: KC_ flags.
     571             * mp1.c3: repeat
     572             * mp1.c4: scancode
     573             * mp2.c1: translated char
     574             * mp2.c2: translated scancode
     575             * mp2.s2: KDD_ flags.
     576             */
     577            KbdPacket[0].monFlags = 0; // no monitor flag
     578            KbdPacket[0].scancode = CHAR4FROMMP(pqmsg->mp1);
     579            KbdPacket[0].xlatedchar = CHAR1FROMMP(pqmsg->mp2);
     580            KbdPacket[0].xlatedscan = CHAR2FROMMP(pqmsg->mp2);
     581            KbdPacket[0].time = pqmsg->time;
     582            KbdPacket[0].ddFlags = SHORT2FROMMP(pqmsg->mp2);
     583            /** @todo extended stuff, keypad, workarounds. see pmvnc. */
     584        }
     585    }
     586
     587    /*
     588     * We're not recording, so no chance of a feedback loop here.
     589     * This doesn't seem to work, bah!
     590     */
     591    if (pfNoRecord) {
     592        *pfNoRecord = FALSE;
     593    }
    571594    return TRUE;
    572595}
     
    587610    assert(g_fSynergyInitialized);
    588611    if (g_fSynergyInitialized) {
    589         /* 
     612        /*
    590613         * Reset the event semaphore and queue the message for MsgInputHook.
    591614         */
     
    609632
    610633                /*
    611                  * It took a bit longer than expected. We'll wait for some 2-3 
     634                 * It took a bit longer than expected. We'll wait for some 2-3
    612635                 * seconds before we give up. This might be a bit paranoid, but
    613636                 * I'd rather drop a message than locking up PM.
     
    623646                        if (rc != ERROR_TIMEOUT && rc != ERROR_SEM_TIMEOUT && rc != ERROR_INTERRUPT) {
    624647                            break;
    625                         } 
     648                        }
    626649                        if (fibGetMsCount() - ulStart > 2500) {
    627650                            break;
     
    630653                }
    631654
    632                 /* 
    633                  * Since we probably didn't manage to inject the message, we should 
    634                  * release the hook to make sure we're not overwriting g_qmsg while 
     655                /*
     656                 * Since we probably didn't manage to inject the message, we should
     657                 * release the hook to make sure we're not overwriting g_qmsg while
    635658                 * some other thread is reading it from MsgInputHook.
    636659                 */
     
    639662                pszRet = g_pszErrorMsg;
    640663                return pszRet ? pszRet : "timed out";
    641             } 
     664            }
    642665            pszRet = "WinSetHook failed";
    643666        } else {
  • trunk/synergy/lib/platform/CPMSynergyHook.def

    r2763 r2768  
    22DATA SHARED
    33
     4IMPORTS
     5    _KbdPacket = PMWIN.174 ; fix KbdPacket in win.imp and make it data!
     6
  • trunk/synergy/lib/platform/CPMSynergyHook.h

    r2763 r2768  
    8787CSYNERGYHOOK_API const char * fakeMsg(HAB hab, const QMSG *pQmsg);
    8888
     89
     90
     91//
     92// Various OS/2 stuff from the DDK.
     93//
     94
     95/*
     96 * video/rel/.../pmwinp.mac and pmwinx.h in the ddk.
     97 */
     98typedef struct _KBDEVENT {    /* kevt */
     99    BYTE monFlags;          /* Open, Close and Flush monitor flags */
     100    BYTE scancode;          /* Original scan code (actually high byte of
     101                               monitor flags */
     102    BYTE xlatedchar;        /* Output of interrupt level character translation
     103                               table */
     104
     105    BYTE xlatedscan;        /* Translated scan code.  Different only for
     106                               the enhanced keyboard */
     107
     108    USHORT shiftDBCS;         /* DBCS shift state and status */
     109    USHORT shiftstate;        /* Current state of shift keys */
     110    ULONG time;             /* millisecond counter time stamp */
     111    USHORT ddFlags;           /* Keyboard device driver flags */
     112} KBDEVENT;
     113typedef KBDEVENT *PKBDEVENT;
     114// guess MON_* are for the monFlags field.
     115#define MON_OPEN        EQU     0001H
     116#define MON_CLOSE       EQU     0002H
     117#define MON_FLUSH       EQU     0004H
     118// guess KSS_* is for the shiftstate field.
     119#define KSS_SYSREQ      EQU     8000H
     120#define KSS_CAPSLOCK    EQU     4000H
     121#define KSS_NUMLOCK     EQU     2000H
     122#define KSS_SCROLLLOCK  EQU     1000H
     123#define KSS_RIGHTALT    EQU     0800H
     124#define KSS_RIGHTCTRL   EQU     0400H
     125#define KSS_LEFTALT     EQU     0200H
     126#define KSS_LEFTCTRL    EQU     0100H
     127#define KSS_INSERTON    EQU     0080H
     128#define KSS_CAPSLOCKON  EQU     0040H
     129#define KSS_NUMLOCKON   EQU     0020H
     130#define KSS_SCROLLLOCKON        EQU     0010H
     131#define KSS_EITHERALT   EQU     0008H
     132#define KSS_EITHERCTRL  EQU     0004H
     133#define KSS_LEFTSHIFT   EQU     0002H
     134#define KSS_RIGHTSHIFT  EQU     0001H
     135#define KSS_EITHERSHIFT EQU     0003H
     136/* Valid values for ddFlags field */
     137#define KDD_MONFLAG1    0x8000 // bird: conflicts with KDD_KC_LONEKEY - relevant for VIOCHAR?
     138#define KDD_MONFLAG2    0x4000 // bird: conflicts with KDD_KC_PREVDOWN - relevant for VIOCHAR?
     139#define KDD_RESERVED    0x3C00
     140#define KDD_ACCENTED    0x0200
     141#define KDD_MULTIMAKE   0x0100
     142#define KDD_SECONDARY   0x0080
     143#define KDD_BREAK       0x0040
     144#define KDD_EXTENDEDKEY 0x0020
     145#define KDD_ACTIONFIELD 0x001F
     146#define KDD_KC_LONEKEY  0x8000
     147#define KDD_KC_PREVDOWN 0x4000
     148#define KDD_KC_KEYUP    0x2000
     149#define KDD_KC_ALT      0x1000
     150#define KDD_KC_CTRL     0x0800
     151#define KDD_KC_SHIFT    0x0400
     152#define KDD_KC_FLAGS    0x0FC00
     153/* Valid values for KDD_ACTIONFIELD portion of ddFlags field */
     154#define KDD_PUTINKIB    0x0000
     155#define KDD_ACK 0x0001
     156#define KDD_PREFIXKEY   0x0002
     157#define KDD_OVERRUN     0x0003
     158#define KDD_RESEND      0x0004
     159#define KDD_REBOOTKEY   0x0005
     160#define KDD_DUMPKEY     0x0006
     161#define KDD_SHIFTKEY    0x0007
     162#define KDD_PAUSEKEY    0x0008
     163#define KDD_PSEUDOPAUSE 0x0009
     164#define KDD_WAKEUPKEY   0x000A
     165#define KDD_BADACCENT   0x000B
     166#define KDD_HOTKEY      0x000C
     167#define KDD_ACCENTKEY   0x0010
     168#define KDD_BREAKKEY    0x0011
     169#define KDD_PSEUDOBREAK 0x0012
     170#define KDD_PRTSCKEY    0x0013
     171#define KDD_PRTECHOKEY  0x0014
     172#define KDD_PSEUDOPRECH 0x0015
     173#define KDD_STATUSCHG   0x0016
     174#define KDD_WRITTENKEY  0x0017
     175#define KDD_UNDEFINED   0x001F
     176
     177/// PMWIN.174
     178// This needs to be used when pushing stuff to VIO programs. (pmvnc does anyway)
     179extern "C" KBDEVENT KbdPacket[2];
     180
    89181#endif
  • trunk/synergy/lib/platform/CPMUtil.h

    r2765 r2768  
    4242
    4343};
    44 
    4544
    4645/** The WinTranlateChar2 operation. */
  • trunk/synergy/lib/platform/CXWindowsKeyState.cpp

    r2749 r2768  
    22 * synergy -- mouse and keyboard sharing utility
    33 * Copyright (C) 2003 Chris Schoeneman
    4  * 
     4 *
    55 * This package is free software; you can redistribute it and/or
    66 * modify it under the terms of the GNU General Public License
    77 * found in the file COPYING that should have accompanied this file.
    8  * 
     8 *
    99 * This package is distributed in the hope that it will be useful,
    1010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     
    206206        switch (keystroke.m_type) {
    207207        case Keystroke::kButton:
    208                 LOG((CLOG_DEBUG1 "  %03x (%08x) %s", keystroke.m_data.m_button.m_button, keystroke.m_data.m_button.m_client, keystroke.m_data.m_button.m_press ? "down" : "up"));
     208                LOG((CLOG_DEBUG1 "  %03x (%08llx) %s", keystroke.m_data.m_button.m_button, keystroke.m_data.m_button.m_client, keystroke.m_data.m_button.m_press ? "down" : "up"));
    209209                if (keystroke.m_data.m_button.m_repeat) {
    210210                        int c = keystroke.m_data.m_button.m_button;
     
    301301                                        tmpKeysyms[maxKeysyms * i + j] = NoSymbol;
    302302                                }
    303                         }       
     303                        }
    304304                }
    305305                XFree(allKeysyms);
  • trunk/synergy/lib/synergy/CKeyMap.cpp

    r2749 r2768  
    22 * synergy -- mouse and keyboard sharing utility
    33 * Copyright (C) 2005 Chris Schoeneman
    4  * 
     4 *
    55 * This package is free software; you can redistribute it and/or
    66 * modify it under the terms of the GNU General Public License
    77 * found in the file COPYING that should have accompanied this file.
    8  * 
     8 *
    99 * This package is distributed in the hope that it will be useful,
    1010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     
    6060}
    6161
    62 void
     62bool
    6363CKeyMap::addKeyEntry(const KeyItem& item)
    6464{
    6565        // ignore kKeyNone
    6666        if (item.m_id == kKeyNone) {
    67                 return;
     67                return false;
    6868        }
    6969
     
    9393        for (size_t i = 0, n = entries.size(); i < n; ++i) {
    9494                if (entries[i].size() == 1 && newItem == entries[i][0]) {
    95                         return;
     95                        return false;
    9696                }
    9797        }
     
    9999        // add item list
    100100        entries.push_back(items);
    101         LOG((CLOG_DEBUG1 "add key: %04x %d %03x %04x (%04x %04x %04x)%s", newItem.m_id, newItem.m_group, newItem.m_button, newItem.m_client, newItem.m_required, newItem.m_sensitive, newItem.m_generates, newItem.m_dead ? " dead" : ""));
     101        LOG((CLOG_DEBUG1 "add key: %04x %d %03x %04x (%04x %04x %04x)%s", newItem.m_id, newItem.m_group, newItem.m_button, (UInt32)newItem.m_client, newItem.m_required, newItem.m_sensitive, newItem.m_generates, newItem.m_dead ? " dead" : ""));
     102    return true;
    102103}
    103104
     
    722723        assert(group >= 0 && group < getNumGroups());
    723724
    724         // find a key that generates the given modifier in the given group 
     725        // find a key that generates the given modifier in the given group
    725726        // but doesn't use the given button, presumably because we're trying
    726727        // to generate a KeyID that's only bound the the given button.
     
    960961{
    961962        KeyButton button = keyItem.m_button;
    962         UInt32 data      = keyItem.m_client;
     963        UInt64 data      = keyItem.m_client;
    963964        switch (type) {
    964965        case kKeystrokePress:
     
    978979                }
    979980                break;
    980                
     981
    981982        case kKeystrokeRelease:
    982983                keystrokes.push_back(Keystroke(button, false, false, data));
     
    10001001                }
    10011002                break;
    1002                
     1003
    10031004        case kKeystrokeRepeat:
    10041005                keystrokes.push_back(Keystroke(button, false, true, data));
     
    10061007                // no modifier changes on key repeat
    10071008                break;
    1008                
     1009
    10091010        case kKeystrokeClick:
    10101011                keystrokes.push_back(Keystroke(button,  true, false, data));
     
    10121013                // no modifier changes on key click
    10131014                break;
    1014                
     1015
    10151016        case kKeystrokeModify:
    10161017        case kKeystrokeUnmodify:
     
    13131314
    13141315CKeyMap::Keystroke::Keystroke(KeyButton button,
    1315                                 bool press, bool repeat, UInt32 data) :
     1316                                bool press, bool repeat, UInt64 data) :
    13161317        m_type(kButton)
    13171318{
  • trunk/synergy/lib/synergy/CKeyMap.h

    r2749 r2768  
    22 * synergy -- mouse and keyboard sharing utility
    33 * Copyright (C) 2005 Chris Schoeneman
    4  * 
     4 *
    55 * This package is free software; you can redistribute it and/or
    66 * modify it under the terms of the GNU General Public License
    77 * found in the file COPYING that should have accompanied this file.
    8  * 
     8 *
    99 * This package is distributed in the hope that it will be useful,
    1010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     
    5151                bool                    m_dead;                 //!< \c true if this is a dead KeyID
    5252                bool                    m_lock;                 //!< \c true if this locks a modifier
    53                 UInt32                  m_client;               //!< Client data
     53                UInt64                  m_client;               //!< Client data
    5454
    5555        public:
     
    7777                };
    7878
    79                 Keystroke(KeyButton, bool press, bool repeat, UInt32 clientData);
     79                Keystroke(KeyButton, bool press, bool repeat, UInt64 clientData);
    8080                Keystroke(SInt32 group, bool absolute, bool restore);
    8181
     
    8686                        bool            m_press;                //!< \c true iff press
    8787                        bool            m_repeat;               //!< \c true iff for an autorepeat
    88                         UInt32          m_client;               //!< Client data
     88                        UInt64          m_client;               //!< Client data
    8989                };
    9090                struct CGroup {
     
    127127        Adds \p item to the entries for the item's id and group.  The
    128128        \c m_dead member is set automatically.
    129         */
    130         void                            addKeyEntry(const KeyItem& item);
     129    Returns true if accepted, false if for some reasons rejected.
     130        */
     131        bool                            addKeyEntry(const KeyItem& item);
    131132
    132133        //! Add an alias key entry
     
    315316        and \c false if the string cannot be parsed.  The modifiers plus any
    316317        remaining leading and trailing whitespace is stripped from the input
    317         string. 
     318        string.
    318319        */
    319320        static bool                     parseModifiers(CString&, KeyModifierMask&);
     
    331332                kKeystrokeUnmodify              //!< Synthesize releasing a modifier
    332333        };
    333                
     334
    334335        // A list of ways to synthesize a KeyID
    335336        typedef std::vector<KeyItemList> KeyEntryList;
  • trunk/synergy/lib/synergy/CKeyState.cpp

    r2749 r2768  
    22 * synergy -- mouse and keyboard sharing utility
    33 * Copyright (C) 2004 Chris Schoeneman
    4  * 
     4 *
    55 * This package is free software; you can redistribute it and/or
    66 * modify it under the terms of the GNU General Public License
    77 * found in the file COPYING that should have accompanied this file.
    8  * 
     8 *
    99 * This package is distributed in the hope that it will be useful,
    1010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     
    503503                context->m_activeModifiers.insert(std::make_pair(
    504504                                                                keyItem.m_generates, keyItem));
    505         }       
     505        }
    506506}
    507507
     
    614614                ++m_keys[localID];
    615615                ++m_syntheticKeys[localID];
    616                 m_keyClientData[localID] = keyItem->m_client;
    617616                m_serverKeys[serverID]   = localID;
    618617        }
  • trunk/synergy/lib/synergy/CKeyState.h

    r2749 r2768  
    22 * synergy -- mouse and keyboard sharing utility
    33 * Copyright (C) 2004 Chris Schoeneman
    4  * 
     4 *
    55 * This package is free software; you can redistribute it and/or
    66 * modify it under the terms of the GNU General Public License
    77 * found in the file COPYING that should have accompanied this file.
    8  * 
     8 *
    99 * This package is distributed in the hope that it will be useful,
    1010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     
    148148                CAddActiveModifierContext& operator=(const CAddActiveModifierContext&);
    149149        };
    150        
     150
    151151        class ButtonToKeyLess {
    152152        public:
     
    207207
    208208        // client data for each pressed key
    209         UInt32                          m_keyClientData[kNumButtons];
     209        UInt64                          m_keyClientData[kNumButtons];
    210210
    211211        // server keyboard state.  an entry is 0 if not the key isn't pressed
Note: See TracChangeset for help on using the changeset viewer.