105b261ecSmrg/*
205b261ecSmrg *Copyright (C) 2004 Harold L Hunt II All Rights Reserved.
305b261ecSmrg *
405b261ecSmrg *Permission is hereby granted, free of charge, to any person obtaining
505b261ecSmrg * a copy of this software and associated documentation files (the
605b261ecSmrg *"Software"), to deal in the Software without restriction, including
705b261ecSmrg *without limitation the rights to use, copy, modify, merge, publish,
805b261ecSmrg *distribute, sublicense, and/or sell copies of the Software, and to
905b261ecSmrg *permit persons to whom the Software is furnished to do so, subject to
1005b261ecSmrg *the following conditions:
1105b261ecSmrg *
1205b261ecSmrg *The above copyright notice and this permission notice shall be
1305b261ecSmrg *included in all copies or substantial portions of the Software.
1405b261ecSmrg *
1505b261ecSmrg *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1605b261ecSmrg *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1705b261ecSmrg *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1805b261ecSmrg *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR
1905b261ecSmrg *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
2005b261ecSmrg *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
2105b261ecSmrg *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2205b261ecSmrg *
2305b261ecSmrg *Except as contained in this notice, the name of Harold L Hunt II
2405b261ecSmrg *shall not be used in advertising or otherwise to promote the sale, use
2505b261ecSmrg *or other dealings in this Software without prior written authorization
2605b261ecSmrg *from Harold L Hunt II.
2705b261ecSmrg *
2805b261ecSmrg * Authors:	Harold L Hunt II
2905b261ecSmrg */
3005b261ecSmrg
3105b261ecSmrg#ifdef HAVE_XWIN_CONFIG_H
3205b261ecSmrg#include <xwin-config.h>
3305b261ecSmrg#endif
3405b261ecSmrg#include "win.h"
3505b261ecSmrg
369ace9065Smrgstatic HHOOK g_hhookKeyboardLL = NULL;
3705b261ecSmrg
3805b261ecSmrg/*
3905b261ecSmrg * Function prototypes
4005b261ecSmrg */
4105b261ecSmrg
4205b261ecSmrgstatic LRESULT CALLBACK
4335c4bbdfSmrgwinKeyboardMessageHookLL(int iCode, WPARAM wParam, LPARAM lParam);
4405b261ecSmrg
4505b261ecSmrg#ifndef LLKHF_EXTENDED
4635c4bbdfSmrg#define LLKHF_EXTENDED  0x00000001
4705b261ecSmrg#endif
4805b261ecSmrg#ifndef LLKHF_UP
4935c4bbdfSmrg#define LLKHF_UP  0x00000080
5005b261ecSmrg#endif
5105b261ecSmrg
5205b261ecSmrg/*
5305b261ecSmrg * KeyboardMessageHook
5405b261ecSmrg */
5505b261ecSmrg
5605b261ecSmrgstatic LRESULT CALLBACK
5735c4bbdfSmrgwinKeyboardMessageHookLL(int iCode, WPARAM wParam, LPARAM lParam)
5805b261ecSmrg{
5935c4bbdfSmrg    BOOL fPassKeystroke = FALSE;
6035c4bbdfSmrg    BOOL fPassAltTab = TRUE;
6135c4bbdfSmrg    PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) lParam;
6235c4bbdfSmrg    HWND hwnd = GetActiveWindow();
6335c4bbdfSmrg
6435c4bbdfSmrg    WindowPtr pWin = NULL;
6535c4bbdfSmrg    winPrivWinPtr pWinPriv = NULL;
6635c4bbdfSmrg    winPrivScreenPtr pScreenPriv = NULL;
6735c4bbdfSmrg    winScreenInfo *pScreenInfo = NULL;
6835c4bbdfSmrg
6935c4bbdfSmrg    /* Check if the Windows window property for our X window pointer is valid */
7035c4bbdfSmrg    if ((pWin = GetProp(hwnd, WIN_WINDOW_PROP)) != NULL) {
7135c4bbdfSmrg        /* Get a pointer to our window privates */
7235c4bbdfSmrg        pWinPriv = winGetWindowPriv(pWin);
7335c4bbdfSmrg
7435c4bbdfSmrg        /* Get pointers to our screen privates and screen info */
7535c4bbdfSmrg        pScreenPriv = pWinPriv->pScreenPriv;
7635c4bbdfSmrg        pScreenInfo = pScreenPriv->pScreenInfo;
7735c4bbdfSmrg
7835c4bbdfSmrg        if (pScreenInfo->fMultiWindow)
7935c4bbdfSmrg            fPassAltTab = FALSE;
8005b261ecSmrg    }
8105b261ecSmrg
8235c4bbdfSmrg    /* Pass keystrokes on to our main message loop */
8335c4bbdfSmrg    if (iCode == HC_ACTION) {
8435c4bbdfSmrg        winDebug("winKeyboardMessageHook: vkCode: %08x scanCode: %08x\n",
8535c4bbdfSmrg                 (unsigned int)p->vkCode, (unsigned int)p->scanCode);
8635c4bbdfSmrg
8735c4bbdfSmrg        switch (wParam) {
8835c4bbdfSmrg        case WM_KEYDOWN:
8935c4bbdfSmrg        case WM_SYSKEYDOWN:
9035c4bbdfSmrg        case WM_KEYUP:
9135c4bbdfSmrg        case WM_SYSKEYUP:
9235c4bbdfSmrg            fPassKeystroke =
9335c4bbdfSmrg                (fPassAltTab &&
9435c4bbdfSmrg                 (p->vkCode == VK_TAB) && ((p->flags & LLKHF_ALTDOWN) != 0))
9535c4bbdfSmrg                || (p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN);
9635c4bbdfSmrg            break;
9735c4bbdfSmrg        }
9805b261ecSmrg    }
9905b261ecSmrg
10035c4bbdfSmrg    /*
10135c4bbdfSmrg     * Pass message on to our main message loop.
10235c4bbdfSmrg     * We process this immediately with SendMessage so that the keystroke
10335c4bbdfSmrg     * appears in, hopefully, the correct order.
10435c4bbdfSmrg     */
10535c4bbdfSmrg    if (fPassKeystroke) {
10635c4bbdfSmrg        LPARAM lParamKey = 0x0;
10735c4bbdfSmrg
10835c4bbdfSmrg        /* Construct the lParam from KBDLLHOOKSTRUCT */
10935c4bbdfSmrg        lParamKey = lParamKey | (0x0000FFFF & 0x00000001);      /* Repeat count */
11035c4bbdfSmrg        lParamKey = lParamKey | (0x00FF0000 & (p->scanCode << 16));
11135c4bbdfSmrg        lParamKey = lParamKey
11235c4bbdfSmrg            | (0x01000000 & ((p->flags & LLKHF_EXTENDED) << 23));
11335c4bbdfSmrg        lParamKey = lParamKey
11435c4bbdfSmrg            | (0x20000000 & ((p->flags & LLKHF_ALTDOWN) << 24));
11535c4bbdfSmrg        lParamKey = lParamKey | (0x80000000 & ((p->flags & LLKHF_UP) << 24));
11635c4bbdfSmrg
11735c4bbdfSmrg        /* Send message to our main window that has the keyboard focus */
11835c4bbdfSmrg        PostMessage(hwnd, (UINT) wParam, (WPARAM) p->vkCode, lParamKey);
11935c4bbdfSmrg
12035c4bbdfSmrg        return 1;
12105b261ecSmrg    }
12205b261ecSmrg
12335c4bbdfSmrg    /* Call next hook */
12435c4bbdfSmrg    return CallNextHookEx(NULL, iCode, wParam, lParam);
12505b261ecSmrg}
12605b261ecSmrg
12705b261ecSmrg/*
12805b261ecSmrg * Attempt to install the keyboard hook, return FALSE if it was not installed
12905b261ecSmrg */
13005b261ecSmrg
13105b261ecSmrgBool
13235c4bbdfSmrgwinInstallKeyboardHookLL(void)
13305b261ecSmrg{
13435c4bbdfSmrg    /* Install the hook only once */
13535c4bbdfSmrg    if (!g_hhookKeyboardLL)
13635c4bbdfSmrg        g_hhookKeyboardLL = SetWindowsHookEx(WH_KEYBOARD_LL,
13735c4bbdfSmrg                                             winKeyboardMessageHookLL,
13835c4bbdfSmrg                                             g_hInstance, 0);
13905b261ecSmrg
14035c4bbdfSmrg    return TRUE;
14105b261ecSmrg}
14205b261ecSmrg
14305b261ecSmrg/*
14405b261ecSmrg * Remove the keyboard hook if it is installed
14505b261ecSmrg */
14605b261ecSmrg
14705b261ecSmrgvoid
14835c4bbdfSmrgwinRemoveKeyboardHookLL(void)
14905b261ecSmrg{
15035c4bbdfSmrg    if (g_hhookKeyboardLL)
15135c4bbdfSmrg        UnhookWindowsHookEx(g_hhookKeyboardLL);
15235c4bbdfSmrg    g_hhookKeyboardLL = NULL;
15305b261ecSmrg}
154