#ifdef HAVE_XWIN_CONFIG_H
#include <xwin-config.h>
#endif
#include "win.h"
#include "winkeybd.h"
#include "winconfig.h"
#include "winmsg.h"
#include "xkbsrv.h"
static Bool g_winKeyState[NUM_KEYCODES];
static void
winKeybdBell (int iPercent, DeviceIntPtr pDeviceInt,
pointer pCtrl, int iClass);
static void
winKeybdCtrl (DeviceIntPtr pDevice, KeybdCtrl *pCtrl);
void
winTranslateKey (WPARAM wParam, LPARAM lParam, int *piScanCode)
{
int iKeyFixup = g_iKeyMap[wParam * WIN_KEYMAP_COLS + 1];
int iKeyFixupEx = g_iKeyMap[wParam * WIN_KEYMAP_COLS + 2];
int iParam = HIWORD (lParam);
int iParamScanCode = LOBYTE (iParam);
winDebug("winTranslateKey: wParam %08x lParam %08x\n", wParam, lParam);
if (iParamScanCode <= 1)
{
if (VK_PRIOR <= wParam && wParam <= VK_DOWN)
iParam |= KF_EXTENDED;
else
iParamScanCode = MapVirtualKeyEx(wParam,
0,
GetKeyboardLayout(0));
}
if ((iParam & KF_EXTENDED) && iKeyFixupEx)
*piScanCode = iKeyFixupEx;
else if (iKeyFixup)
*piScanCode = iKeyFixup;
else if (wParam == 0 && iParamScanCode == 0x70)
*piScanCode = KEY_HKTG;
else
switch (iParamScanCode)
{
case 0x70:
*piScanCode = KEY_HKTG;
break;
case 0x73:
*piScanCode = KEY_BSlash2;
break;
default:
*piScanCode = iParamScanCode;
break;
}
}
static void
winKeybdBell (int iPercent, DeviceIntPtr pDeviceInt,
pointer pCtrl, int iClass)
{
MessageBeep (MB_OK);
}
static void
winKeybdCtrl (DeviceIntPtr pDevice, KeybdCtrl *pCtrl)
{
}
int
winKeybdProc (DeviceIntPtr pDeviceInt, int iState)
{
DevicePtr pDevice = (DevicePtr) pDeviceInt;
XkbSrvInfoPtr xkbi;
XkbControlsPtr ctrl;
switch (iState)
{
case DEVICE_INIT:
winConfigKeyboard (pDeviceInt);
defaultKeyboardControl.leds = g_winInfo.keyboard.leds;
winErrorFVerb(2, "Rules = \"%s\" Model = \"%s\" Layout = \"%s\""
" Variant = \"%s\" Options = \"%s\"\n",
g_winInfo.xkb.rules ? g_winInfo.xkb.rules : "none",
g_winInfo.xkb.model ? g_winInfo.xkb.model : "none",
g_winInfo.xkb.layout ? g_winInfo.xkb.layout : "none",
g_winInfo.xkb.variant ? g_winInfo.xkb.variant : "none",
g_winInfo.xkb.options ? g_winInfo.xkb.options : "none");
InitKeyboardDeviceStruct (pDeviceInt,
&g_winInfo.xkb,
winKeybdBell,
winKeybdCtrl);
xkbi = pDeviceInt->key->xkbInfo;
if ((xkbi != NULL) && (xkbi->desc != NULL))
{
ctrl = xkbi->desc->ctrls;
ctrl->repeat_delay = g_winInfo.keyboard.delay;
ctrl->repeat_interval = 1000/g_winInfo.keyboard.rate;
}
else
{
winErrorFVerb (1, "winKeybdProc - Error initializing keyboard AutoRepeat\n");
}
break;
case DEVICE_ON:
pDevice->on = TRUE;
CopyKeyClass(pDeviceInt, inputInfo.keyboard);
break;
case DEVICE_CLOSE:
case DEVICE_OFF:
pDevice->on = FALSE;
break;
}
return Success;
}
void
winInitializeModeKeyStates (void)
{
if (GetKeyState (VK_NUMLOCK) & 0x0001)
{
winSendKeyEvent (KEY_NumLock, TRUE);
winSendKeyEvent (KEY_NumLock, FALSE);
}
if (GetKeyState (VK_CAPITAL) & 0x0001)
{
winSendKeyEvent (KEY_CapsLock, TRUE);
winSendKeyEvent (KEY_CapsLock, FALSE);
}
if (GetKeyState (VK_SCROLL) & 0x0001)
{
winSendKeyEvent (KEY_ScrollLock, TRUE);
winSendKeyEvent (KEY_ScrollLock, FALSE);
}
if (GetKeyState (VK_KANA) & 0x0001)
{
winSendKeyEvent (KEY_HKTG, TRUE);
winSendKeyEvent (KEY_HKTG, FALSE);
}
}
void
winRestoreModeKeyStates (void)
{
DWORD dwKeyState;
BOOL processEvents = TRUE;
unsigned short internalKeyStates;
if (!inputInfo.keyboard)
return;
if (screenInfo.screens[0]->root && screenInfo.screens[0]->root->mapped == FALSE)
processEvents = FALSE;
if (processEvents)
mieqProcessInputEvents ();
internalKeyStates = XkbStateFieldFromRec(&inputInfo.keyboard->key->xkbInfo->state);
winDebug("winRestoreModeKeyStates: state %d\n", internalKeyStates);
dwKeyState = GetKeyState (VK_NUMLOCK) & 0x0001;
if (WIN_XOR (internalKeyStates & NumLockMask, dwKeyState))
{
winSendKeyEvent (KEY_NumLock, TRUE);
winSendKeyEvent (KEY_NumLock, FALSE);
}
dwKeyState = GetKeyState (VK_CAPITAL) & 0x0001;
if (WIN_XOR (internalKeyStates & LockMask, dwKeyState))
{
winSendKeyEvent (KEY_CapsLock, TRUE);
winSendKeyEvent (KEY_CapsLock, FALSE);
}
dwKeyState = GetKeyState (VK_SCROLL) & 0x0001;
if (WIN_XOR (internalKeyStates & ScrollLockMask, dwKeyState))
{
winSendKeyEvent (KEY_ScrollLock, TRUE);
winSendKeyEvent (KEY_ScrollLock, FALSE);
}
dwKeyState = GetKeyState (VK_KANA) & 0x0001;
if (WIN_XOR (internalKeyStates & KanaMask, dwKeyState))
{
winSendKeyEvent (KEY_HKTG, TRUE);
winSendKeyEvent (KEY_HKTG, FALSE);
}
}
Bool
winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam)
{
MSG msgNext;
LONG lTime;
Bool fReturn;
if ((message == WM_KEYDOWN || message == WM_SYSKEYDOWN)
&& wParam == VK_CONTROL
&& (HIWORD (lParam) & KF_EXTENDED) == 0)
{
lTime = GetMessageTime ();
fReturn = PeekMessage (&msgNext, NULL,
WM_KEYDOWN, WM_SYSKEYDOWN,
PM_NOREMOVE);
if (!fReturn)
{
Sleep (0);
fReturn = PeekMessage (&msgNext, NULL,
WM_KEYDOWN, WM_SYSKEYDOWN,
PM_NOREMOVE);
}
if (msgNext.message != WM_KEYDOWN && msgNext.message != WM_SYSKEYDOWN)
fReturn = 0;
if (fReturn && msgNext.wParam == VK_MENU
&& msgNext.time == lTime
&& (HIWORD (msgNext.lParam) & KF_EXTENDED))
{
return TRUE;
}
}
if ((message == WM_KEYUP || message == WM_SYSKEYUP)
&& wParam == VK_CONTROL
&& (HIWORD (lParam) & KF_EXTENDED) == 0)
{
lTime = GetMessageTime ();
fReturn = PeekMessage (&msgNext, NULL,
WM_KEYUP, WM_SYSKEYUP,
PM_NOREMOVE);
if (!fReturn)
{
Sleep (0);
fReturn = PeekMessage (&msgNext, NULL,
WM_KEYUP, WM_SYSKEYUP,
PM_NOREMOVE);
}
if (msgNext.message != WM_KEYUP && msgNext.message != WM_SYSKEYUP)
fReturn = 0;
if (fReturn
&& (msgNext.message == WM_KEYUP
|| msgNext.message == WM_SYSKEYUP)
&& msgNext.wParam == VK_MENU
&& msgNext.time == lTime
&& (HIWORD (msgNext.lParam) & KF_EXTENDED))
{
return TRUE;
}
}
return FALSE;
}
void
winKeybdReleaseKeys (void)
{
int i;
#ifdef HAS_DEVWINDOWS
if (g_fdMessageQueue == WIN_FD_INVALID)
return;
#endif
for (i = 0; i < NUM_KEYCODES; ++i)
{
if (g_winKeyState[i])
winSendKeyEvent (i, FALSE);
g_winKeyState[i] = FALSE;
}
}
void
winSendKeyEvent (DWORD dwKey, Bool fDown)
{
EventListPtr events;
int i, nevents;
if (g_winKeyState[dwKey] == FALSE && fDown == FALSE) return;
g_winKeyState[dwKey] = fDown;
GetEventList(&events);
nevents = GetKeyboardEvents(events, g_pwinKeyboard, fDown ? KeyPress : KeyRelease, dwKey + MIN_KEYCODE);
for (i = 0; i < nevents; i++)
mieqEnqueue(g_pwinKeyboard, (InternalEvent*)events[i].event);
winDebug("winSendKeyEvent: dwKey: %d, fDown: %d, nEvents %d\n",
dwKey, fDown, nevents);
}
BOOL winCheckKeyPressed(WPARAM wParam, LPARAM lParam)
{
switch (wParam)
{
case VK_CONTROL:
if ((lParam & 0x1ff0000) == 0x11d0000 && g_winKeyState[KEY_RCtrl])
return TRUE;
if ((lParam & 0x1ff0000) == 0x01d0000 && g_winKeyState[KEY_LCtrl])
return TRUE;
break;
case VK_SHIFT:
if ((lParam & 0x1ff0000) == 0x0360000 && g_winKeyState[KEY_ShiftR])
return TRUE;
if ((lParam & 0x1ff0000) == 0x02a0000 && g_winKeyState[KEY_ShiftL])
return TRUE;
break;
default:
return TRUE;
}
return FALSE;
}
void winFixShiftKeys (int iScanCode)
{
if (GetKeyState (VK_SHIFT) & 0x8000)
return;
if (iScanCode == KEY_ShiftL && g_winKeyState[KEY_ShiftR])
winSendKeyEvent (KEY_ShiftR, FALSE);
if (iScanCode == KEY_ShiftR && g_winKeyState[KEY_ShiftL])
winSendKeyEvent (KEY_ShiftL, FALSE);
}