mi: change custom handlers to internal events

This should re-enable DGA, but XQuartz needs to be changed to internal events
too now.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2009-02-06 12:08:43 +10:00
parent bdc262701a
commit 47f136ed6f
4 changed files with 150 additions and 117 deletions

View File

@ -46,6 +46,8 @@
#include "xf86Xinput.h" #include "xf86Xinput.h"
#include "exglobals.h" #include "exglobals.h"
#include "exevents.h" #include "exevents.h"
#include "events.h"
#include "eventconvert.h"
#include "mi.h" #include "mi.h"
@ -57,8 +59,8 @@ static Bool DGACloseScreen(int i, ScreenPtr pScreen);
static void DGADestroyColormap(ColormapPtr pmap); static void DGADestroyColormap(ColormapPtr pmap);
static void DGAInstallColormap(ColormapPtr pmap); static void DGAInstallColormap(ColormapPtr pmap);
static void DGAUninstallColormap(ColormapPtr pmap); static void DGAUninstallColormap(ColormapPtr pmap);
static void DGAHandleEvent(int screen_num, xEvent *event, static void DGAHandleEvent(int screen_num, InternalEvent *event,
DeviceIntPtr device, int nevents); DeviceIntPtr device);
static void static void
DGACopyModeInfo( DGACopyModeInfo(
@ -245,11 +247,7 @@ DGACloseScreen(int i, ScreenPtr pScreen)
DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen); DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
if (XDGAEventBase) { if (XDGAEventBase) {
mieqSetHandler(*XDGAEventBase + MotionNotify, NULL); mieqSetHandler(ET_DGAEvent, NULL);
mieqSetHandler(*XDGAEventBase + ButtonPress, NULL);
mieqSetHandler(*XDGAEventBase + ButtonRelease, NULL);
mieqSetHandler(*XDGAEventBase + KeyPress, NULL);
mieqSetHandler(*XDGAEventBase + KeyRelease, NULL);
} }
FreeMarkedVisuals(pScreen); FreeMarkedVisuals(pScreen);
@ -463,11 +461,7 @@ DGASetInputMode(int index, Bool keyboard, Bool mouse)
pScreenPriv->grabKeyboard = keyboard; pScreenPriv->grabKeyboard = keyboard;
if (!mieq_installed) { if (!mieq_installed) {
mieqSetHandler(*XDGAEventBase + MotionNotify, DGAHandleEvent); mieqSetHandler(ET_DGAEvent, DGAHandleEvent);
mieqSetHandler(*XDGAEventBase + ButtonPress, DGAHandleEvent);
mieqSetHandler(*XDGAEventBase + ButtonRelease, DGAHandleEvent);
mieqSetHandler(*XDGAEventBase + KeyPress, DGAHandleEvent);
mieqSetHandler(*XDGAEventBase + KeyRelease, DGAHandleEvent);
mieq_installed = 1; mieq_installed = 1;
} }
} }
@ -916,8 +910,8 @@ Bool
DGAStealKeyEvent(DeviceIntPtr dev, int index, int key_code, int is_down) DGAStealKeyEvent(DeviceIntPtr dev, int index, int key_code, int is_down)
{ {
DGAScreenPtr pScreenPriv; DGAScreenPtr pScreenPriv;
dgaEvent de; DGAEvent event;
if(DGAScreenKey == NULL) /* no DGA */ if(DGAScreenKey == NULL) /* no DGA */
return FALSE; return FALSE;
@ -929,10 +923,16 @@ DGAStealKeyEvent(DeviceIntPtr dev, int index, int key_code, int is_down)
if(!pScreenPriv || !pScreenPriv->grabKeyboard) /* no direct mode */ if(!pScreenPriv || !pScreenPriv->grabKeyboard) /* no direct mode */
return FALSE; return FALSE;
de.u.u.type = *XDGAEventBase + (is_down ? KeyPress : KeyRelease); memset(&event, 0, sizeof(event));
de.u.u.detail = key_code; event.header = ET_Internal;
de.u.event.time = GetTimeInMillis(); event.type = ET_DGAEvent;
mieqEnqueue (dev, (xEvent *) &de); event.length = sizeof(event);
event.time = GetTimeInMillis();
event.subtype = (is_down ? ET_KeyPress : ET_KeyRelease);
event.detail = key_code;
event.dx = 0;
event.dy = 0;
mieqEnqueue (dev, (InternalEvent*)&event);
return TRUE; return TRUE;
} }
@ -943,7 +943,7 @@ Bool
DGAStealMotionEvent(DeviceIntPtr dev, int index, int dx, int dy) DGAStealMotionEvent(DeviceIntPtr dev, int index, int dx, int dy)
{ {
DGAScreenPtr pScreenPriv; DGAScreenPtr pScreenPriv;
dgaEvent de; DGAEvent event;
if(DGAScreenKey == NULL) /* no DGA */ if(DGAScreenKey == NULL) /* no DGA */
return FALSE; return FALSE;
@ -963,14 +963,17 @@ DGAStealMotionEvent(DeviceIntPtr dev, int index, int dx, int dy)
DGAMouseY = 0; DGAMouseY = 0;
else if (DGAMouseY > screenInfo.screens[index]->height) else if (DGAMouseY > screenInfo.screens[index]->height)
DGAMouseY = screenInfo.screens[index]->height; DGAMouseY = screenInfo.screens[index]->height;
de.u.u.type = *XDGAEventBase + MotionNotify;
de.u.u.detail = 0; memset(&event, 0, sizeof(event));
de.u.event.time = GetTimeInMillis(); event.header = ET_Internal;
de.u.event.dx = dx; event.type = ET_DGAEvent;
de.u.event.dy = dy; event.length = sizeof(event);
de.u.event.pad1 = DGAMouseX; event.time = GetTimeInMillis();
de.u.event.pad2 = DGAMouseY; event.subtype = ET_Motion;
mieqEnqueue (dev, (xEvent *) &de); event.detail = 0;
event.dx = dx;
event.dy = dy;
mieqEnqueue (dev, (InternalEvent*)&event);
return TRUE; return TRUE;
} }
@ -978,7 +981,7 @@ Bool
DGAStealButtonEvent(DeviceIntPtr dev, int index, int button, int is_down) DGAStealButtonEvent(DeviceIntPtr dev, int index, int button, int is_down)
{ {
DGAScreenPtr pScreenPriv; DGAScreenPtr pScreenPriv;
dgaEvent de; DGAEvent event;
if (DGAScreenKey == NULL) if (DGAScreenKey == NULL)
return FALSE; return FALSE;
@ -988,14 +991,16 @@ DGAStealButtonEvent(DeviceIntPtr dev, int index, int button, int is_down)
if (!pScreenPriv || !pScreenPriv->grabMouse) if (!pScreenPriv || !pScreenPriv->grabMouse)
return FALSE; return FALSE;
de.u.u.type = *XDGAEventBase + (is_down ? ButtonPress : ButtonRelease); memset(&event, 0, sizeof(event));
de.u.u.detail = button; event.header = ET_Internal;
de.u.event.time = GetTimeInMillis(); event.type = ET_DGAEvent;
de.u.event.dx = 0; event.length = sizeof(event);
de.u.event.dy = 0; event.time = GetTimeInMillis();
de.u.event.pad1 = DGAMouseX; event.subtype = (is_down ? ET_ButtonPress : ET_ButtonRelease);
de.u.event.pad2 = DGAMouseY; event.detail = button;
mieqEnqueue (dev, (xEvent *) &de); event.dx = 0;
event.dy = 0;
mieqEnqueue (dev, (InternalEvent*)&event);
return TRUE; return TRUE;
} }
@ -1027,93 +1032,91 @@ static Mask filters[] =
}; };
static void static void
DGAProcessKeyboardEvent (ScreenPtr pScreen, dgaEvent *de, DeviceIntPtr keybd) DGAProcessKeyboardEvent (ScreenPtr pScreen, DGAEvent *event, DeviceIntPtr keybd)
{ {
int coreEquiv;
xEvent xi;
KeyClassPtr keyc = keybd->key; KeyClassPtr keyc = keybd->key;
DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen); DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
DeviceIntPtr pointer = GetPairedDevice(keybd); DeviceIntPtr pointer = GetPairedDevice(keybd);
DeviceEvent ev;
coreEquiv = de->u.u.type - *XDGAEventBase; memset(&ev, 0, sizeof(ev));
ev.length = sizeof(ev);
ev.detail.key = event->detail;
ev.type = event->subtype;
ev.root_x = 0;
ev.root_y = 0;
ev.corestate = XkbStateFieldFromRec(&keyc->xkbInfo->state);
ev.corestate |= pointer->button->state;
/* UpdateDeviceState(keybd, &ev);
* Fill in remaining event state
*/
de->u.event.dx = 0;
de->u.event.dy = 0;
de->u.event.screen = pScreen->myNum;
de->u.event.state = XkbStateFieldFromRec(&keyc->xkbInfo->state);
de->u.event.state |= pointer->button->state;
de->u.u.type = (IEventBase - 1) + coreEquiv; /* change to XI event */
#if 0
/* FIXME: Hello. I am broken. Please fix me. Thanks. */
UpdateDeviceState(keybd, (xEvent*)de, 1);
#endif
de->u.u.type = *XDGAEventBase + coreEquiv; /* change back */
/* /*
* Deliver the DGA event * Deliver the DGA event
*/ */
if (pScreenPriv->client) if (pScreenPriv->client)
{ {
dgaEvent de;
de.u.u.type = *XDGAEventBase + GetCoreType((InternalEvent*)&ev);
de.u.u.detail = event->detail;
de.u.event.time = event->time;
de.u.event.dx = 0;
de.u.event.dy = 0;
de.u.event.screen = pScreen->myNum;
de.u.event.state = ev.corestate;
/* If the DGA client has selected input, then deliver based on the usual filter */ /* If the DGA client has selected input, then deliver based on the usual filter */
TryClientEvents (pScreenPriv->client, keybd, (xEvent *) de, 1, TryClientEvents (pScreenPriv->client, keybd, (xEvent *)&de, 1,
filters[coreEquiv], pScreenPriv->input, 0); filters[ev.type], pScreenPriv->input, 0);
} }
else else
{ {
/* If the keyboard is actively grabbed, deliver a grabbed core event */ /* If the keyboard is actively grabbed, deliver a grabbed core event */
if (keybd->deviceGrab.grab && !keybd->deviceGrab.fromPassiveGrab) if (keybd->deviceGrab.grab && !keybd->deviceGrab.fromPassiveGrab)
{ {
#if 0 ev.detail.key = event->detail;
/* FIXME: Hello. I am broken. Please fix me. Thanks. */ ev.time = event->time;
xi.u.u.type = (IEventBase - 1) + coreEquiv; ev.root_x = event->dx;
xi.u.u.detail = de->u.u.detail; ev.root_y = event->dy;
xi.u.keyButtonPointer.time = de->u.event.time; ev.corestate = event->state;
xi.u.keyButtonPointer.eventX = de->u.event.dx; ev.deviceid = keybd->id;
xi.u.keyButtonPointer.eventY = de->u.event.dy; DeliverGrabbedEvent ((InternalEvent*)&ev, keybd, FALSE);
xi.u.keyButtonPointer.rootX = de->u.event.dx;
xi.u.keyButtonPointer.rootY = de->u.event.dy;
xi.u.keyButtonPointer.state = de->u.event.state;
((deviceKeyButtonPointer*)&xi)->deviceid = keybd->id;
DeliverGrabbedEvent (&xi, keybd, FALSE, 1);
#endif
} }
} }
} }
static void static void
DGAProcessPointerEvent (ScreenPtr pScreen, dgaEvent *de, DeviceIntPtr mouse) DGAProcessPointerEvent (ScreenPtr pScreen, DGAEvent *event, DeviceIntPtr mouse)
{ {
ButtonClassPtr butc = mouse->button; ButtonClassPtr butc = mouse->button;
int coreEquiv; int coreEquiv;
DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen); DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
xEvent xi; DeviceEvent ev;
coreEquiv = de->u.u.type - *XDGAEventBase; memset(&ev, 0, sizeof(ev));
/* ev.header = ET_Internal;
* Fill in remaining event state ev.length = sizeof(ev);
*/ ev.type = event->subtype;
de->u.event.screen = pScreen->myNum; ev.corestate = butc->state;
de->u.event.state = butc->state; ev.corestate |= XkbStateFieldFromRec(&GetPairedDevice(mouse)->key->xkbInfo->state);
de->u.event.state |= XkbStateFieldFromRec(&GetPairedDevice(mouse)->key->xkbInfo->state);
de->u.u.type = (IEventBase - 1) + coreEquiv; /* change to XI event */ UpdateDeviceState(mouse, &ev);
#if 0
/* FIXME: Hello. I am broken. Please fix me. Thanks. */
UpdateDeviceState(mouse, (xEvent*)de, 1);
#endif
de->u.u.type = *XDGAEventBase + coreEquiv; /* change back */
/* /*
* Deliver the DGA event * Deliver the DGA event
*/ */
if (pScreenPriv->client) if (pScreenPriv->client)
{ {
dgaEvent de;
de.u.u.type = *XDGAEventBase + GetCoreType((InternalEvent*)&ev);
de.u.u.detail = event->detail;
de.u.event.time = event->time;
de.u.event.dx = 0;
de.u.event.dy = 0;
de.u.event.screen = pScreen->myNum;
de.u.event.state = ev.corestate;
/* If the DGA client has selected input, then deliver based on the usual filter */ /* If the DGA client has selected input, then deliver based on the usual filter */
TryClientEvents (pScreenPriv->client, mouse, (xEvent *) de, 1, TryClientEvents (pScreenPriv->client, mouse, (xEvent *)&de, 1,
filters[coreEquiv], pScreenPriv->input, 0); filters[coreEquiv], pScreenPriv->input, 0);
} }
else else
@ -1121,18 +1124,12 @@ DGAProcessPointerEvent (ScreenPtr pScreen, dgaEvent *de, DeviceIntPtr mouse)
/* If the pointer is actively grabbed, deliver a grabbed core event */ /* If the pointer is actively grabbed, deliver a grabbed core event */
if (mouse->deviceGrab.grab && !mouse->deviceGrab.fromPassiveGrab) if (mouse->deviceGrab.grab && !mouse->deviceGrab.fromPassiveGrab)
{ {
#if 0 ev.detail.button = event->detail;
/* FIXME: Hello. I am broken. Please fix me. Thanks. */ ev.time = event->time;
xi.u.u.type = (IEventBase - 1 ) + coreEquiv; ev.root_x = event->dx;
xi.u.u.detail = de->u.u.detail; ev.root_y = event->dy;
xi.u.keyButtonPointer.time = de->u.event.time; ev.corestate = event->state;
xi.u.keyButtonPointer.eventX = de->u.event.dx; DeliverGrabbedEvent ((InternalEvent*)&ev, mouse, FALSE);
xi.u.keyButtonPointer.eventY = de->u.event.dy;
xi.u.keyButtonPointer.rootX = de->u.event.dx;
xi.u.keyButtonPointer.rootY = de->u.event.dy;
xi.u.keyButtonPointer.state = de->u.event.state;
DeliverGrabbedEvent (&xi, mouse, FALSE, 1);
#endif
} }
} }
} }
@ -1196,34 +1193,32 @@ DGAGetOldDGAMode(int index)
} }
static void static void
DGAHandleEvent(int screen_num, xEvent *event, DeviceIntPtr device, int nevents) DGAHandleEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
{ {
dgaEvent *de = (dgaEvent *) event; DGAEvent *event= (DGAEvent*)ev;
ScreenPtr pScreen = screenInfo.screens[screen_num]; ScreenPtr pScreen = screenInfo.screens[screen_num];
DGAScreenPtr pScreenPriv; DGAScreenPtr pScreenPriv;
int coreEquiv;
/* no DGA */ /* no DGA */
if (DGAScreenKey == NULL || XDGAEventBase == 0) if (DGAScreenKey == NULL || XDGAEventBase == 0)
return; return;
pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen); pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
/* DGA not initialized on this screen */ /* DGA not initialized on this screen */
if (!pScreenPriv) if (!pScreenPriv)
return; return;
coreEquiv = de->u.u.type - *XDGAEventBase; switch (event->subtype) {
/* Not a DGA event; shouldn't happen, but you never know. */
if (coreEquiv < KeyPress || coreEquiv > MotionNotify)
return;
switch (coreEquiv) {
case KeyPress: case KeyPress:
case KeyRelease: case KeyRelease:
DGAProcessKeyboardEvent (pScreen, de, device); DGAProcessKeyboardEvent (pScreen, event, device);
break; break;
case MotionNotify:
case ButtonPress:
case ButtonRelease:
DGAProcessPointerEvent (pScreen, event, device);
break;
default: default:
DGAProcessPointerEvent (pScreen, de, device);
break; break;
} }
} }

View File

@ -55,6 +55,9 @@ enum {
ET_ProximityOut, ET_ProximityOut,
ET_DeviceChanged, ET_DeviceChanged,
ET_Hierarchy, ET_Hierarchy,
#if XFreeXDGA
ET_DGAEvent,
#endif
ET_Internal = 0xFF /* First byte */ ET_Internal = 0xFF /* First byte */
} EventType; } EventType;
@ -153,6 +156,36 @@ typedef struct
/* FIXME: add the new capabilities here */ /* FIXME: add the new capabilities here */
} DeviceChangedEvent; } DeviceChangedEvent;
#if XFreeXDGA
/**
* DGAEvent, used by DGA to intercept and emulate input events.
*
* @header: Always ET_Internal
* @type: ET_DGAEvent
* @length: Length in bytes
* @time: Time in ms
* @subtype: KeyPress, KeyRelease, ButtonPress, ButtonRelease, MotionNotify
* @detail: Key code or button number.
* @dx: Relative x coordinate
* @dy: Relative y coordinate
* @screen: Screen number this event applies to
* @state: Core modifier/button state
*/
typedef struct
{
unsigned char header;
int type;
int length;
Time time;
int subtype;
int detail;
int dx;
int dy;
int screen;
uint16_t state;
} DGAEvent;
#endif
/** /**
* InternalEvent, event type used inside the X server for input event * InternalEvent, event type used inside the X server for input event
* processing. * processing.
@ -173,6 +206,9 @@ typedef struct
} any; } any;
DeviceEvent device; DeviceEvent device;
DeviceChangedEvent changed; DeviceChangedEvent changed;
#if XFreeXDGA
DGAEvent dga;
#endif
} u; } u;
} InternalEvent; } InternalEvent;

View File

@ -215,7 +215,12 @@ extern _X_EXPORT void mieqProcessInputEvents(
void void
); );
typedef void (*mieqHandler)(int, xEventPtr, DeviceIntPtr, int); /**
* Custom input event handler. If you need to process input events in some
* other way than the default path, register an input event handler for the
* given internal event type.
*/
typedef void (*mieqHandler)(int screen, InternalEvent* event, DeviceIntPtr dev);
void _X_EXPORT mieqSetHandler(int event, mieqHandler handler); void _X_EXPORT mieqSetHandler(int event, mieqHandler handler);
/* miexpose.c */ /* miexpose.c */

View File

@ -391,16 +391,13 @@ mieqProcessInputEvents(void)
/* If someone's registered a custom event handler, let them /* If someone's registered a custom event handler, let them
* steal it. */ * steal it. */
#if 0
if (handler) if (handler)
{ {
/* FIXME: this is broken now, InternalEvents! */ handler(DequeueScreen(dev)->myNum, event, dev);
handler(DequeueScreen(dev)->myNum, event, dev, 1);
if (master) if (master)
handler(DequeueScreen(master)->myNum, handler(DequeueScreen(master)->myNum,
masterEvents->event, master, 1); (InternalEvent*)masterEvents->event, master);
} else } else
#endif
{ {
/* process slave first, then master */ /* process slave first, then master */
dev->public.processInputProc(event, dev); dev->public.processInputProc(event, dev);