Fix issues with focus in and modifiers from host confusing Xephr

This commit is contained in:
Matthew Allum 2005-06-23 16:50:07 +00:00
parent a668b6c11a
commit 5620122206
4 changed files with 73 additions and 4 deletions

View File

@ -38,7 +38,10 @@
#endif #endif
#include "ephyr.h" #include "ephyr.h"
#include "inputstr.h"
extern int KdTsPhyScreen; extern int KdTsPhyScreen;
extern DeviceIntPtr pKdKeyboard;
static int mouseState = 0; static int mouseState = 0;
@ -564,6 +567,65 @@ ephyrScreenFini (KdScreenInfo *screen)
{ {
} }
/*
* Port of Mark McLoughlin's Xnest fix for focus in + modifier bug.
* See https://bugs.freedesktop.org/show_bug.cgi?id=3030
*/
void
ephyrUpdateModifierState(unsigned int state)
{
DeviceIntPtr pkeydev;
KeyClassPtr keyc;
int i;
CARD8 mask;
pkeydev = LookupKeyboardDevice();
if (!pkeydev)
return;
keyc = pkeydev->key;
if (keyc->state == state)
return;
for (i = 0, mask = 1; i < 8; i++, mask <<= 1)
{
int key;
/* Modifier is down, but shouldn't be */
if ((keyc->state & mask) && !(state & mask))
{
int count = keyc->modifierKeyCount[i];
for (key = 0; key < MAP_LENGTH; key++)
if (keyc->modifierMap[key] & mask)
{
int bit;
BYTE *kptr;
kptr = &keyc->down[key >> 3];
bit = 1 << (key & 7);
if (*kptr & bit)
KdEnqueueKeyboardEvent(key, TRUE); /* release */
if (--count == 0)
break;
}
}
/* Modifier shoud be down, but isn't */
if (!(keyc->state & mask) && (state & mask))
for (key = 0; key < MAP_LENGTH; key++)
if (keyc->modifierMap[key] & mask)
{
KdEnqueueKeyboardEvent(key, FALSE); /* press */
break;
}
}
}
void void
ephyrPoll(void) ephyrPoll(void)
{ {
@ -592,12 +654,12 @@ ephyrPoll(void)
break; break;
case EPHYR_EV_KEY_PRESS: case EPHYR_EV_KEY_PRESS:
ephyrUpdateModifierState(ev.data.key_down.state);
KdEnqueueKeyboardEvent (ev.data.key_down.scancode, FALSE); KdEnqueueKeyboardEvent (ev.data.key_down.scancode, FALSE);
break; break;
case EPHYR_EV_KEY_RELEASE: case EPHYR_EV_KEY_RELEASE:
ephyrUpdateModifierState(ev.data.key_up.state);
KdEnqueueKeyboardEvent (ev.data.key_up.scancode, TRUE); KdEnqueueKeyboardEvent (ev.data.key_up.scancode, TRUE);
break; break;

View File

@ -142,6 +142,9 @@ ephyrShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf);
#endif #endif
void
ephyrUpdateModifierState(unsigned int state);
extern KdMouseFuncs EphyrMouseFuncs; extern KdMouseFuncs EphyrMouseFuncs;
extern KdKeyboardFuncs EphyrKeyboardFuncs; extern KdKeyboardFuncs EphyrKeyboardFuncs;

View File

@ -29,11 +29,11 @@
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> /* for memset */ #include <string.h> /* for memset */
#include <time.h>
#include <sys/ipc.h> #include <sys/ipc.h>
#include <sys/shm.h> #include <sys/shm.h>
#include <sys/time.h> #include <sys/time.h>
#include <time.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
@ -733,7 +733,8 @@ hostx_get_event(EphyrHostXEvent *ev)
case KeyPress: case KeyPress:
{ {
ev->type = EPHYR_EV_KEY_PRESS; ev->type = EPHYR_EV_KEY_PRESS;
ev->data.key_down.state = xev.xkey.state;
ev->data.key_down.scancode = xev.xkey.keycode; ev->data.key_down.scancode = xev.xkey.keycode;
return 1; return 1;
} }
@ -779,6 +780,7 @@ hostx_get_event(EphyrHostXEvent *ev)
* kdrive all togeather. * kdrive all togeather.
*/ */
ev->type = EPHYR_EV_KEY_RELEASE; ev->type = EPHYR_EV_KEY_RELEASE;
ev->data.key_up.state = xev.xkey.state;
ev->data.key_up.scancode = xev.xkey.keycode; ev->data.key_up.scancode = xev.xkey.keycode;
return 1; return 1;

View File

@ -69,10 +69,12 @@ struct EphyrHostXEvent
struct key_up { struct key_up {
int scancode; int scancode;
int state;
} key_up; } key_up;
struct key_down { struct key_down {
int scancode; int scancode;
int state;
} key_down; } key_down;
} data; } data;