Пример #1
0
static spif_bool_t
action_check_modifiers(spif_ushort_t mod, int x_mod)
{
    spif_uint32_t m = (AltMask | MetaMask | NumLockMask);

    /* When we do have to check the modifiers, we do so in this order to eliminate the
       most popular choices first.  If any test fails, we return FALSE. */
    D_ACTIONS(("Checking modifier set 0x%08x (%c%c%c%c) vs. X modifier set 0x%08x (%c%c%c%c)\n",
               mod, SHOW_MODS(mod), x_mod, SHOW_X_MODS(x_mod)));
    if (mod != ETERM_MOD_ANY) {
        /* LOGICAL_XOR() returns true if either the first parameter or the second parameter
           is true, but not both...just like XOR.  If the mask we're looking for is set in
           mod but not in x_mod, or set in x_mod but not in mod, we don't have a match. */
        if (LOGICAL_XOR((mod & ETERM_MOD_CTRL), (x_mod & ControlMask))) {
            return FALSE;
        }
        if (LOGICAL_XOR((mod & ETERM_MOD_SHIFT), (x_mod & ShiftMask))) {
            return FALSE;
        }
        if (MetaMask != AltMask) {
            if (LOGICAL_XOR((mod & ETERM_MOD_ALT), (x_mod & AltMask))) {
                return FALSE;
            }
            if (LOGICAL_XOR((mod & ETERM_MOD_META), (x_mod & MetaMask))) {
                return FALSE;
            }
        } else {
            if (LOGICAL_XOR((mod & (ETERM_MOD_META | ETERM_MOD_ALT)), (x_mod & (MetaMask | AltMask)))) {
                return FALSE;
            }
        }
        if (LOGICAL_XOR((mod & ETERM_MOD_LOCK), (x_mod & LockMask))) {
            return FALSE;
        }
        /* These tests can't use LOGICAL_XOR because the second test has an additional
           restriction that the Mod?Mask cannot be set in m; i.e., we want to ignore
           any Mod?Mask assigned to Alt, Meta, or the NumLock On state. */
        if (((mod & ETERM_MOD_MOD1) && !(x_mod & Mod1Mask)) || (!(mod & ETERM_MOD_MOD1) && (x_mod & Mod1Mask) && !(Mod1Mask & m))) {
            return FALSE;
        }
        if (((mod & ETERM_MOD_MOD2) && !(x_mod & Mod2Mask)) || (!(mod & ETERM_MOD_MOD2) && (x_mod & Mod2Mask) && !(Mod2Mask & m))) {
            return FALSE;
        }
        if (((mod & ETERM_MOD_MOD3) && !(x_mod & Mod3Mask)) || (!(mod & ETERM_MOD_MOD3) && (x_mod & Mod3Mask) && !(Mod3Mask & m))) {
            return FALSE;
        }
        if (((mod & ETERM_MOD_MOD4) && !(x_mod & Mod4Mask)) || (!(mod & ETERM_MOD_MOD4) && (x_mod & Mod4Mask) && !(Mod4Mask & m))) {
            return FALSE;
        }
        if (((mod & ETERM_MOD_MOD5) && !(x_mod & Mod5Mask)) || (!(mod & ETERM_MOD_MOD5) && (x_mod & Mod5Mask) && !(Mod5Mask & m))) {
            return FALSE;
        }
    }
    D_ACTIONS(("Modifier match confirmed.\n"));
    return TRUE;
}
Пример #2
0
void
winRestoreModeKeyStates(void)
{
    DWORD dwKeyState;
    BOOL processEvents = TRUE;
    unsigned short internalKeyStates;

    /* X server is being initialized */
    if (!inputInfo.keyboard)
        return;

    /* Only process events if the rootwindow is mapped. The keyboard events
     * will cause segfaults otherwise */
    if (screenInfo.screens[0]->root &&
        screenInfo.screens[0]->root->mapped == FALSE)
        processEvents = FALSE;

    /* Force to process all pending events in the mi event queue */
    if (processEvents)
        mieqProcessInputEvents();

    /* Read the mode key states of our X server */
    /* (stored in the virtual core keyboard) */
    internalKeyStates =
        XkbStateFieldFromRec(&inputInfo.keyboard->key->xkbInfo->state);
    winDebug("winRestoreModeKeyStates: state %d\n", internalKeyStates);

    {
        /* Make sure the message queue is empty, otherwise the GetKeyState will not always
          return the correct state of the numlock key, capslock key, ... 
          This is mainly because this function is called from the WM_SETFOCUS handler. 
          From MSDN GetKeyState: The key status returned from this function changes as a thread
          reads key messages from its message queue.*/
        MSG msg;

        /* Process all messages on our queue */
        while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
        {
            DispatchMessage (&msg);
        }
    }

    /* Check if modifier keys are pressed, and if so, fake a press */
    {
        BOOL ctrl = (GetAsyncKeyState(VK_CONTROL) < 0);
        BOOL shift = (GetAsyncKeyState(VK_SHIFT) < 0);
        BOOL alt = (GetAsyncKeyState(VK_LMENU) < 0);
        BOOL altgr = (GetAsyncKeyState(VK_RMENU) < 0);

        if (ctrl && altgr)
            ctrl = FALSE;

        if (LOGICAL_XOR(internalKeyStates & ControlMask, ctrl))
            winSendKeyEvent(KEY_LCtrl, ctrl);

        if (LOGICAL_XOR(internalKeyStates & ShiftMask, shift))
            winSendKeyEvent(KEY_ShiftL, shift);

        if (LOGICAL_XOR(internalKeyStates & Mod1Mask, alt))
            winSendKeyEvent(KEY_Alt, alt);

        if (LOGICAL_XOR(internalKeyStates & Mod5Mask, altgr))
            winSendKeyEvent(KEY_AltLang, altgr);
    }

    /*
       Check if latching modifier key states have changed, and if so,
       fake a press and a release to toggle the modifier to the correct
       state
    */
    dwKeyState = GetKeyState(VK_NUMLOCK) & 0x0001;
    if (LOGICAL_XOR(internalKeyStates & NumLockMask, dwKeyState)) {
        winSendKeyEvent(KEY_NumLock, TRUE);
        winSendKeyEvent(KEY_NumLock, FALSE);
    }

    dwKeyState = GetKeyState(VK_CAPITAL) & 0x0001;
    if (LOGICAL_XOR(internalKeyStates & LockMask, dwKeyState)) {
        winSendKeyEvent(KEY_CapsLock, TRUE);
        winSendKeyEvent(KEY_CapsLock, FALSE);
    }

    dwKeyState = GetKeyState(VK_SCROLL) & 0x0001;
    if (LOGICAL_XOR(internalKeyStates & ScrollLockMask, dwKeyState)) {
        winSendKeyEvent(KEY_ScrollLock, TRUE);
        winSendKeyEvent(KEY_ScrollLock, FALSE);
    }

    dwKeyState = GetKeyState(VK_KANA) & 0x0001;
    if (LOGICAL_XOR(internalKeyStates & KanaMask, dwKeyState)) {
        winSendKeyEvent(KEY_HKTG, TRUE);
        winSendKeyEvent(KEY_HKTG, FALSE);
    }
}
Пример #3
0
void
winRestoreModeKeyStates(void)
{
    DWORD dwKeyState;
    BOOL processEvents = TRUE;
    unsigned short internalKeyStates;

    /* X server is being initialized */
    if (!inputInfo.keyboard)
        return;

    /* Only process events if the rootwindow is mapped. The keyboard events
     * will cause segfaults otherwise */
    if (screenInfo.screens[0]->root &&
        screenInfo.screens[0]->root->mapped == FALSE)
        processEvents = FALSE;

    /* Force to process all pending events in the mi event queue */
    if (processEvents)
        mieqProcessInputEvents();

    /* Read the mode key states of our X server */
    /* (stored in the virtual core keyboard) */
    internalKeyStates =
        XkbStateFieldFromRec(&inputInfo.keyboard->key->xkbInfo->state);
    winDebug("winRestoreModeKeyStates: state %d\n", internalKeyStates);

    /* Check if modifier keys are pressed, and if so, fake a press */
    {

        BOOL lctrl = (GetAsyncKeyState(VK_LCONTROL) < 0);
        BOOL rctrl = (GetAsyncKeyState(VK_RCONTROL) < 0);
        BOOL lshift = (GetAsyncKeyState(VK_LSHIFT) < 0);
        BOOL rshift = (GetAsyncKeyState(VK_RSHIFT) < 0);
        BOOL alt = (GetAsyncKeyState(VK_LMENU) < 0);
        BOOL altgr = (GetAsyncKeyState(VK_RMENU) < 0);

        /*
           If AltGr and CtrlL appear to be pressed, assume the
           CtrL is a fake one
         */
        if (lctrl && altgr)
            lctrl = FALSE;

        if (lctrl)
            winSendKeyEvent(KEY_LCtrl, TRUE);

        if (rctrl)
            winSendKeyEvent(KEY_RCtrl, TRUE);

        if (lshift)
            winSendKeyEvent(KEY_ShiftL, TRUE);

        if (rshift)
            winSendKeyEvent(KEY_ShiftL, TRUE);

        if (alt)
            winSendKeyEvent(KEY_Alt, TRUE);

        if (altgr)
            winSendKeyEvent(KEY_AltLang, TRUE);
    }

    /*
       Check if latching modifier key states have changed, and if so,
       fake a press and a release to toggle the modifier to the correct
       state
    */
    dwKeyState = GetKeyState(VK_NUMLOCK) & 0x0001;
    if (LOGICAL_XOR(internalKeyStates & NumLockMask, dwKeyState)) {
        winSendKeyEvent(KEY_NumLock, TRUE);
        winSendKeyEvent(KEY_NumLock, FALSE);
    }

    dwKeyState = GetKeyState(VK_CAPITAL) & 0x0001;
    if (LOGICAL_XOR(internalKeyStates & LockMask, dwKeyState)) {
        winSendKeyEvent(KEY_CapsLock, TRUE);
        winSendKeyEvent(KEY_CapsLock, FALSE);
    }

    dwKeyState = GetKeyState(VK_SCROLL) & 0x0001;
    if (LOGICAL_XOR(internalKeyStates & ScrollLockMask, dwKeyState)) {
        winSendKeyEvent(KEY_ScrollLock, TRUE);
        winSendKeyEvent(KEY_ScrollLock, FALSE);
    }

    dwKeyState = GetKeyState(VK_KANA) & 0x0001;
    if (LOGICAL_XOR(internalKeyStates & KanaMask, dwKeyState)) {
        winSendKeyEvent(KEY_HKTG, TRUE);
        winSendKeyEvent(KEY_HKTG, FALSE);
    }

    /*
       For strict correctness, we should also press any non-modifier keys
       which are already down when we gain focus, but nobody has complained
       yet :-)
     */
}