Call-back based async request handling.

This commit is contained in:
David Reveman 2008-10-08 14:41:20 -04:00
parent b72d8f4037
commit 8b167b13dc
12 changed files with 513 additions and 532 deletions

View file

@ -100,11 +100,14 @@ typedef struct _DMXQueue {
typedef void (*ReplyProcPtr) (ScreenPtr pScreen,
unsigned int sequence,
xcb_generic_reply_t *reply);
xcb_generic_reply_t *reply,
xcb_generic_error_t *error,
void *data);
typedef struct _DMXRequest {
DMXSequence base;
ReplyProcPtr reply;
void *data;
} DMXRequest;
typedef struct _DMXPropTrans {

View file

@ -246,6 +246,233 @@ dmxDnDUpdatePosition (DMXScreenInfo *dmxScreen,
}
}
/* version 5 of the XDND protocol doesn't provide information about
the pointer device that is used so we'll simply update all devices */
static void
dmxDnDUpdatePointerDevice (ScreenPtr pScreen,
int x,
int y)
{
DMXInputInfo *dmxInput = &dmxScreens[pScreen->myNum].input;
int i;
for (i = 0; i < dmxInput->numDevs; i++)
{
DeviceIntPtr pDevice = dmxInput->devs[i];
dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDevice);
xcb_generic_event_t xevent;
/* extension device */
if (pDevPriv->deviceId >= 0)
{
xcb_input_device_motion_notify_event_t *xmotion =
(xcb_input_device_motion_notify_event_t *) &xevent;
xmotion->response_type = dmxInput->eventBase +
XCB_INPUT_DEVICE_MOTION_NOTIFY;
xmotion->device_id = pDevPriv->deviceId;
xmotion->event_x = x;
xmotion->event_y = y;
}
else
{
xcb_motion_notify_event_t *xmotion =
(xcb_motion_notify_event_t *) &xevent;
xmotion->response_type = XCB_MOTION_NOTIFY;
xmotion->event_x = x;
xmotion->event_y = y;
}
(*pDevPriv->EventCheck) (pDevice, &xevent);
}
}
static void
dmxDnDTranslateCoordinatesReply (ScreenPtr pScreen,
unsigned int sequence,
xcb_generic_reply_t *reply,
xcb_generic_error_t *error,
void *data)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
if (reply)
{
xcb_translate_coordinates_reply_t *xcoord =
(xcb_translate_coordinates_reply_t *) reply;
dmxScreen->dndX = xcoord->dst_x;
dmxScreen->dndY = xcoord->dst_y;
if (dmxScreen->dndSource)
{
WindowPtr pWin = WindowTable[pScreen->myNum];
xcb_client_message_event_t xevent;
dmxDnDUpdatePointerDevice (pScreen, xcoord->dst_x, xcoord->dst_y);
#ifdef PANORAMIX
if (!noPanoramiXExtension)
pWin = WindowTable[0];
#endif
if (!dmxScreen->getTypeProp.sequence)
dmxDnDUpdatePosition (dmxScreen,
pWin,
dmxScreen->dndX,
dmxScreen->dndY);
xevent.response_type = XCB_CLIENT_MESSAGE;
xevent.format = 32;
xevent.type = dmxBEAtom (dmxScreen, dmxScreen->xdndStatusAtom);
xevent.window = dmxScreen->dndSource;
xevent.data.data32[0] = dmxScreen->dndWid;
xevent.data.data32[1] = dmxScreen->dndStatus;
xevent.data.data32[2] = 0;
xevent.data.data32[3] = 0;
xevent.data.data32[4] = 0;
if (dmxScreen->dndAcceptedAction &&
ValidAtom (dmxScreen->dndAcceptedAction))
xevent.data.data32[4] =
dmxBEAtom (dmxScreen, dmxScreen->dndAcceptedAction);
xcb_send_event (dmxScreen->connection,
FALSE,
dmxScreen->dndSource,
0,
(const char *) &xevent);
}
}
}
static void
dmxDnDGetTypePropReply (ScreenPtr pScreen,
unsigned int sequence,
xcb_generic_reply_t *reply,
xcb_generic_error_t *error,
void *data)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
if (reply)
{
xcb_get_property_reply_t *xproperty =
(xcb_get_property_reply_t *) reply;
if (xproperty->format == 32 &&
dmxAtom (dmxScreen, xproperty->type) == XA_ATOM)
{
uint32_t *data = xcb_get_property_value (xproperty);
int i;
for (i = 0; i < xcb_get_property_value_length (xproperty); i++)
data[i] = dmxAtom (dmxScreen, data[i]);
ChangeWindowProperty (dmxScreens[0].pSelectionProxyWin[0],
dmxScreen->xdndTypeListAtom,
XA_ATOM,
32,
PropModeReplace,
xcb_get_property_value_length (xproperty),
data,
TRUE);
dmxScreen->dndHasTypeProp = TRUE;
}
if (dmxScreen->dndX != -1 && dmxScreen->dndY != -1)
{
WindowPtr pWin = WindowTable[pScreen->myNum];
#ifdef PANORAMIX
if (!noPanoramiXExtension)
pWin = WindowTable[0];
#endif
dmxDnDUpdatePosition (dmxScreen,
pWin,
dmxScreen->dndX,
dmxScreen->dndY);
}
}
dmxScreen->getTypeProp.sequence = 0;
}
static void
dmxDnDGetActionListPropReply (ScreenPtr pScreen,
unsigned int sequence,
xcb_generic_reply_t *reply,
xcb_generic_error_t *error,
void *data)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
if (reply)
{
xcb_get_property_reply_t *xproperty =
(xcb_get_property_reply_t *) reply;
if (xproperty->format == 32 &&
dmxAtom (dmxScreen, xproperty->type) == XA_ATOM)
{
uint32_t *data = xcb_get_property_value (xproperty);
int i;
for (i = 0; i < xcb_get_property_value_length (xproperty); i++)
data[i] = dmxAtom (dmxScreen, data[i]);
ChangeWindowProperty (dmxScreens[0].pSelectionProxyWin[0],
dmxScreen->xdndActionListAtom,
XA_ATOM,
32,
PropModeReplace,
xcb_get_property_value_length (xproperty),
data,
TRUE);
}
}
dmxScreen->getActionListProp.sequence = 0;
}
static void
dmxDnDGetActionDescriptionPropReply (ScreenPtr pScreen,
unsigned int sequence,
xcb_generic_reply_t *reply,
xcb_generic_error_t *error,
void *data)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
if (reply)
{
xcb_get_property_reply_t *xproperty =
(xcb_get_property_reply_t *) reply;
if (xproperty->format == 8 &&
dmxAtom (dmxScreen, xproperty->type) == XA_STRING)
{
ChangeWindowProperty (dmxScreens[0].pSelectionProxyWin[0],
dmxScreen->xdndActionDescriptionAtom,
XA_STRING,
8,
PropModeReplace,
xcb_get_property_value_length (xproperty),
xcb_get_property_value (xproperty),
TRUE);
}
}
dmxScreen->getActionDescriptionProp.sequence = 0;
}
static void
dmxDnDPositionMessage (ScreenPtr pScreen,
Window source,
@ -271,8 +498,10 @@ dmxDnDPositionMessage (ScreenPtr pScreen,
0,
0xffffffff);
dmxAddSequence (&dmxScreen->request,
dmxScreen->getActionListProp.sequence);
dmxAddRequest (&dmxScreen->request,
dmxDnDGetActionListPropReply,
dmxScreen->getActionListProp.sequence,
0);
dmxScreen->getActionDescriptionProp =
xcb_get_property (dmxScreen->connection,
@ -284,8 +513,10 @@ dmxDnDPositionMessage (ScreenPtr pScreen,
0,
0xffffffff);
dmxAddSequence (&dmxScreen->request,
dmxScreen->getActionDescriptionProp.sequence);
dmxAddRequest (&dmxScreen->request,
dmxDnDGetActionDescriptionPropReply,
dmxScreen->getActionDescriptionProp.sequence,
0);
}
dmxScreen->translateCoordinates =
@ -294,8 +525,10 @@ dmxDnDPositionMessage (ScreenPtr pScreen,
dmxScreen->rootWin,
xRoot,
yRoot);
dmxAddSequence (&dmxScreen->request,
dmxScreen->translateCoordinates.sequence);
dmxAddRequest (&dmxScreen->request,
dmxDnDTranslateCoordinatesReply,
dmxScreen->translateCoordinates.sequence,
0);
}
static void
@ -332,8 +565,10 @@ dmxDnDEnterMessage (ScreenPtr pScreen,
0xffffffff);
if (dmxScreen->getTypeProp.sequence)
dmxAddSequence (&dmxScreen->request,
dmxScreen->getTypeProp.sequence);
dmxAddRequest (&dmxScreen->request,
dmxDnDGetTypePropReply,
dmxScreen->getTypeProp.sequence,
0);
}
}
@ -480,219 +715,6 @@ dmxScreenEventCheckDnD (ScreenPtr pScreen,
return TRUE;
}
/* version 5 of the XDND protocol doesn't provide information about
the pointer device that is used so we'll simply update all devices */
static void
dmxDnDUpdatePointerDevice (ScreenPtr pScreen,
int x,
int y)
{
DMXInputInfo *dmxInput = &dmxScreens[pScreen->myNum].input;
int i;
for (i = 0; i < dmxInput->numDevs; i++)
{
DeviceIntPtr pDevice = dmxInput->devs[i];
dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDevice);
xcb_generic_event_t xevent;
/* extension device */
if (pDevPriv->deviceId >= 0)
{
xcb_input_device_motion_notify_event_t *xmotion =
(xcb_input_device_motion_notify_event_t *) &xevent;
xmotion->response_type = dmxInput->eventBase +
XCB_INPUT_DEVICE_MOTION_NOTIFY;
xmotion->device_id = pDevPriv->deviceId;
xmotion->event_x = x;
xmotion->event_y = y;
}
else
{
xcb_motion_notify_event_t *xmotion =
(xcb_motion_notify_event_t *) &xevent;
xmotion->response_type = XCB_MOTION_NOTIFY;
xmotion->event_x = x;
xmotion->event_y = y;
}
(*pDevPriv->EventCheck) (pDevice, &xevent);
}
}
Bool
dmxScreenReplyCheckDnD (ScreenPtr pScreen,
unsigned int sequence,
xcb_generic_reply_t *reply)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
if (sequence == dmxScreen->translateCoordinates.sequence)
{
xcb_translate_coordinates_reply_t *xcoord =
(xcb_translate_coordinates_reply_t *) reply;
dmxScreen->dndX = xcoord->dst_x;
dmxScreen->dndY = xcoord->dst_y;
dmxDnDUpdatePointerDevice (pScreen, xcoord->dst_x, xcoord->dst_y);
if (dmxScreen->dndSource)
{
WindowPtr pWin = WindowTable[pScreen->myNum];
xcb_client_message_event_t xevent;
#ifdef PANORAMIX
if (!noPanoramiXExtension)
pWin = WindowTable[0];
#endif
if (!dmxScreen->getTypeProp.sequence)
dmxDnDUpdatePosition (dmxScreen,
pWin,
dmxScreen->dndX,
dmxScreen->dndY);
xevent.response_type = XCB_CLIENT_MESSAGE;
xevent.format = 32;
xevent.type = dmxBEAtom (dmxScreen, dmxScreen->xdndStatusAtom);
xevent.window = dmxScreen->dndSource;
xevent.data.data32[0] = dmxScreen->dndWid;
xevent.data.data32[1] = dmxScreen->dndStatus;
xevent.data.data32[2] = 0;
xevent.data.data32[3] = 0;
xevent.data.data32[4] = 0;
if (dmxScreen->dndAcceptedAction &&
ValidAtom (dmxScreen->dndAcceptedAction))
xevent.data.data32[4] =
dmxBEAtom (dmxScreen, dmxScreen->dndAcceptedAction);
xcb_send_event (dmxScreen->connection,
FALSE,
dmxScreen->dndSource,
0,
(const char *) &xevent);
}
dmxScreen->translateCoordinates.sequence = 0;
return TRUE;
}
else if (sequence == dmxScreen->getTypeProp.sequence)
{
if (reply->response_type)
{
xcb_get_property_reply_t *xproperty =
(xcb_get_property_reply_t *) reply;
if (xproperty->format == 32 &&
dmxAtom (dmxScreen, xproperty->type) == XA_ATOM)
{
uint32_t *data = xcb_get_property_value (xproperty);
int i;
for (i = 0; i < xcb_get_property_value_length (xproperty); i++)
data[i] = dmxAtom (dmxScreen, data[i]);
ChangeWindowProperty (dmxScreens[0].pSelectionProxyWin[0],
dmxScreen->xdndTypeListAtom,
XA_ATOM,
32,
PropModeReplace,
xcb_get_property_value_length (xproperty),
data,
TRUE);
dmxScreen->dndHasTypeProp = TRUE;
}
}
if (dmxScreen->dndX != -1 && dmxScreen->dndY != -1)
{
WindowPtr pWin = WindowTable[pScreen->myNum];
#ifdef PANORAMIX
if (!noPanoramiXExtension)
pWin = WindowTable[0];
#endif
dmxDnDUpdatePosition (dmxScreen,
pWin,
dmxScreen->dndX,
dmxScreen->dndY);
}
dmxScreen->getTypeProp.sequence = 0;
return TRUE;
}
else if (sequence == dmxScreen->getActionListProp.sequence)
{
if (reply->response_type)
{
xcb_get_property_reply_t *xproperty =
(xcb_get_property_reply_t *) reply;
if (xproperty->format == 32 &&
dmxAtom (dmxScreen, xproperty->type) == XA_ATOM)
{
uint32_t *data = xcb_get_property_value (xproperty);
int i;
for (i = 0; i < xcb_get_property_value_length (xproperty); i++)
data[i] = dmxAtom (dmxScreen, data[i]);
ChangeWindowProperty (dmxScreens[0].pSelectionProxyWin[0],
dmxScreen->xdndActionListAtom,
XA_ATOM,
32,
PropModeReplace,
xcb_get_property_value_length (xproperty),
data,
TRUE);
}
}
dmxScreen->getActionListProp.sequence = 0;
return TRUE;
}
else if (sequence == dmxScreen->getActionDescriptionProp.sequence)
{
if (reply->response_type)
{
xcb_get_property_reply_t *xproperty =
(xcb_get_property_reply_t *) reply;
if (xproperty->format == 8 &&
dmxAtom (dmxScreen, xproperty->type) == XA_STRING)
{
ChangeWindowProperty (dmxScreens[0].pSelectionProxyWin[0],
dmxScreen->xdndActionDescriptionAtom,
XA_STRING,
8,
PropModeReplace,
xcb_get_property_value_length (xproperty),
xcb_get_property_value (xproperty),
TRUE);
}
}
dmxScreen->getActionDescriptionProp.sequence = 0;
return TRUE;
}
return FALSE;
}
void
dmxDnDClientMessageEvent (xEvent *event)
{

View file

@ -36,11 +36,6 @@ Bool
dmxScreenEventCheckDnD (ScreenPtr pScreen,
xcb_generic_event_t *event);
Bool
dmxScreenReplyCheckDnD (ScreenPtr pScreen,
unsigned int sequence,
xcb_generic_reply_t *reply);
void
dmxDnDClientMessageEvent (xEvent *event);

View file

@ -2066,13 +2066,7 @@ dmxDisableScreen (int idx)
dmxScreen->beDisplay = NULL;
/* Make sure we don't have any pending sync replies */
if (!dmxScreen->broken)
{
static xcb_generic_error_t detached_error = { 0, DMX_DETACHED };
dmxScreenReplyCheckSync (pScreen, 0, (xcb_generic_reply_t *)
&detached_error);
}
dmxScreenSyncReply (pScreen, 0, NULL, NULL, 0);
#ifdef RANDR
RRGetInfo (screenInfo.screens[0]);

View file

@ -832,6 +832,26 @@ dmxDeviceUngrabButton (DeviceIntPtr pDevice,
}
}
static void
dmxInputGrabPointerReply (ScreenPtr pScreen,
unsigned int sequence,
xcb_generic_reply_t *reply,
xcb_generic_error_t *error,
void *data)
{
DMXInputInfo *dmxInput = &dmxScreens[pScreen->myNum].input;
int i;
for (i = 0; i < dmxInput->numDevs; i++)
{
DeviceIntPtr pDevice = dmxInput->devs[i];
dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDevice);
if ((*pDevPriv->ReplyCheck) (pDevice, sequence, reply))
break;
}
}
static void
dmxDeviceGrabPointer (DeviceIntPtr pDevice,
WindowPtr pWindow,
@ -889,7 +909,10 @@ dmxDeviceGrabPointer (DeviceIntPtr pDevice,
0).sequence;
}
dmxAddSequence (&dmxScreen->request, pDevPriv->grab.sequence);
dmxAddRequest (&dmxScreen->request,
dmxInputGrabPointerReply,
pDevPriv->grab.sequence,
0);
}
static void
@ -929,25 +952,6 @@ dmxInputEventCheck (DMXInputInfo *dmxInput,
return FALSE;
}
Bool
dmxInputReplyCheck (DMXInputInfo *dmxInput,
unsigned int request,
xcb_generic_reply_t *reply)
{
int i;
for (i = 0; i < dmxInput->numDevs; i++)
{
DeviceIntPtr pDevice = dmxInput->devs[i];
dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDevice);
if ((*pDevPriv->ReplyCheck) (pDevice, request, reply))
return TRUE;
}
return FALSE;
}
void
dmxInputGrabButton (DMXInputInfo *dmxInput,
DeviceIntPtr pDevice,

View file

@ -61,11 +61,6 @@ Bool
dmxInputEventCheck (DMXInputInfo *dmxInput,
xcb_generic_event_t *event);
Bool
dmxInputReplyCheck (DMXInputInfo *dmxInput,
unsigned int request,
xcb_generic_reply_t *reply);
void
dmxInputGrabButton (DMXInputInfo *dmxInput,
DeviceIntPtr pDevice,

View file

@ -210,16 +210,6 @@ dmxScreenEventCheckInput (ScreenPtr pScreen,
return dmxInputEventCheck (&dmxScreen->input, event);
}
static Bool
dmxScreenReplyCheckInput (ScreenPtr pScreen,
unsigned int sequence,
xcb_generic_reply_t *reply)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
return dmxInputReplyCheck (&dmxScreen->input, sequence, reply);
}
static void
dmxScreenGetSelectionOwner (ScreenPtr pScreen)
{
@ -358,33 +348,6 @@ dmxScreenEventCheckSelection (ScreenPtr pScreen,
return TRUE;
}
static Bool
dmxScreenReplyCheckSelection (ScreenPtr pScreen,
unsigned int sequence,
xcb_generic_reply_t *reply)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
if (sequence == dmxScreen->getSelectionOwner.sequence)
{
dmxScreen->getSelectionOwner.sequence = 0;
if (reply->response_type)
{
xcb_get_selection_owner_reply_t *xselection =
(xcb_get_selection_owner_reply_t *) reply;
dmxScreen->getSelectionOwnerResult = xselection->owner;
}
return TRUE;
}
else
{
return dmxSelectionPropertyReplyCheck (pScreen, sequence, reply);
}
}
static void
dmxDiscardIgnore (DMXScreenInfo *dmxScreen,
unsigned long sequence)
@ -901,30 +864,17 @@ dmxBEDispatch (ScreenPtr pScreen)
(void **) &reply,
&error))
{
static xcb_generic_reply_t _default_rep = { 1 };
DMXSequence *head = dmxScreen->request.head;
xcb_generic_reply_t *rep = &_default_rep;
DMXRequest *head = (DMXRequest *) dmxScreen->request.head;
if (error)
rep = (xcb_generic_reply_t *) error;
if (reply)
rep = (xcb_generic_reply_t *) reply;
dmxScreen->request.head = head->next;
dmxScreen->request.head = head->base.next;
if (!dmxScreen->request.head)
dmxScreen->request.tail = &dmxScreen->request.head;
if (!dmxScreenReplyCheckSync (pScreen, head->sequence, rep) &&
!dmxScreenReplyCheckInput (pScreen, head->sequence, rep) &&
!dmxScreenReplyCheckSelection (pScreen, head->sequence, rep) &&
!dmxScreenReplyCheckDnD (pScreen, head->sequence, rep))
{
/* error response */
if (rep->response_type == 0)
dmxLogOutput (dmxScreen, "error %d sequence %d\n",
((xcb_generic_error_t *) rep)->error_code,
head->sequence);
}
(*head->reply) (pScreen,
head->base.sequence,
reply,
error,
head->data);
if (reply)
free (reply);
@ -937,27 +887,23 @@ dmxBEDispatch (ScreenPtr pScreen)
if (!dmxScreen->scrnWin ||
xcb_connection_has_error (dmxScreen->connection))
{
static xcb_generic_error_t detached_error = { 0, DMX_DETACHED };
while (dmxScreen->request.head)
{
DMXSequence *head = dmxScreen->request.head;
static xcb_generic_error_t detached_error = { 0, DMX_DETACHED };
DMXRequest *head = (DMXRequest *) dmxScreen->request.head;
dmxScreen->request.head = head->next;
dmxScreen->request.head = head->base.next;
if (!dmxScreen->request.head)
dmxScreen->request.tail = &dmxScreen->request.head;
dmxScreenReplyCheckSync (pScreen, head->sequence,
(xcb_generic_reply_t *)
&detached_error);
dmxScreenReplyCheckInput (pScreen, head->sequence,
(xcb_generic_reply_t *)
&detached_error);
dmxScreenReplyCheckSelection (pScreen, head->sequence,
(xcb_generic_reply_t *)
&detached_error);
dmxScreenReplyCheckDnD (pScreen, head->sequence,
(xcb_generic_reply_t *)
&detached_error);
(*head->reply) (pScreen,
head->base.sequence,
NULL,
&detached_error,
head->data);
free (head);
}
dmxScreen->broken = TRUE;
@ -1517,7 +1463,8 @@ dmxClearQueue (DMXQueue *q)
Bool
dmxAddRequest (DMXQueue *q,
ReplyProcPtr reply,
unsigned long sequence)
unsigned long sequence,
void *data)
{
DMXRequest *r;
@ -1528,6 +1475,7 @@ dmxAddRequest (DMXQueue *q,
r->base.sequence = sequence;
r->base.next = 0;
r->reply = reply;
r->data = data;
*(q->tail) = &r->base;
q->tail = &r->base.next;

View file

@ -54,6 +54,7 @@ extern void dmxClearQueue (DMXQueue *q);
extern Bool dmxAddRequest (DMXQueue *q,
ReplyProcPtr reply,
unsigned long sequence);
unsigned long sequence,
void *data);
#endif /* DMXSCRINIT_H */

View file

@ -302,6 +302,26 @@ dmxBESetSelectionOwner (ScreenPtr pScreen,
0);
}
static void
dmxSelectionOwnerReply (ScreenPtr pScreen,
unsigned int sequence,
xcb_generic_reply_t *reply,
xcb_generic_error_t *error,
void *data)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
if (reply)
{
xcb_get_selection_owner_reply_t *xselection =
(xcb_get_selection_owner_reply_t *) reply;
dmxScreen->getSelectionOwnerResult = xselection->owner;
}
dmxScreen->getSelectionOwner.sequence = 0;
}
static Bool
dmxBEGetSelectionOwner (ScreenPtr pScreen,
Atom selection)
@ -322,11 +342,10 @@ dmxBEGetSelectionOwner (ScreenPtr pScreen,
xcb_get_selection_owner (dmxScreen->connection,
dmxBESelectionAtom (dmxScreen, selection));
if (!dmxScreen->getSelectionOwner.sequence)
return FALSE;
dmxAddSequence (&dmxScreen->request,
dmxScreen->getSelectionOwner.sequence);
dmxAddRequest (&dmxScreen->request,
dmxSelectionOwnerReply,
dmxScreen->getSelectionOwner.sequence,
0);
return TRUE;
}
@ -417,180 +436,12 @@ dmxSelectionClear (ScreenPtr pScreen,
}
}
void
dmxSelectionNotify (ScreenPtr pScreen,
Window requestor,
Atom xSelection,
Atom xTarget,
Atom xProperty,
Time xTime)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
Atom selection = dmxSelectionAtom (dmxScreen, xSelection);
Atom target = dmxAtom (dmxScreen, xTarget);
DMXSelection *s;
for (s = convHead; s; s = s->next)
if (s->value[pScreen->myNum].out == requestor &&
s->selection == selection &&
s->target == target)
break;
if (s)
{
xcb_get_property_cookie_t cookie = { 0 };
Atom property = dmxAtom (dmxScreen, xProperty);
Atom target = dmxAtom (dmxScreen, xTarget);
if (ValidAtom (property) && ValidAtom (target))
cookie = xcb_get_property (dmxScreen->connection,
xFalse,
requestor,
xProperty,
XCB_GET_PROPERTY_TYPE_ANY,
0,
0xffffffff);
if (cookie.sequence)
{
const uint32_t value =
XCB_EVENT_MASK_STRUCTURE_NOTIFY |
XCB_EVENT_MASK_PROPERTY_CHANGE;
dmxUnhookSelection (s, &convHead, &convTail);
memset (s->value, 0, sizeof (s->value));
s->value[pScreen->myNum].out = requestor;
s->value[pScreen->myNum].in = cookie.sequence;
s->property = property;
s->target = target;
if (property == dmxScreen->incrAtom)
xcb_change_window_attributes (dmxScreen->connection,
requestor,
XCB_CW_EVENT_MASK,
&value);
dmxAppendSelection (s, &propTail);
dmxAddSequence (&dmxScreen->request, cookie.sequence);
}
else
{
int i;
s->value[pScreen->myNum].out = 0;
for (i = 0; i < dmxNumScreens; i++)
if (s->value[i].out)
break;
if (i == dmxNumScreens)
dmxSelectionDeleteConv (dmxUnhookSelection (s,
&convHead,
&convTail));
}
}
}
Bool
dmxSelectionDestroyNotify (ScreenPtr pScreen,
Window window)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
DMXSelection *s;
for (s = reqHead; s; s = s->next)
if (s->value[pScreen->myNum].out == window &&
s->property == dmxScreen->incrAtom)
break;
if (s)
{
dmxSelectionDeleteReq (dmxUnhookSelection (s, &reqHead, &reqTail));
return TRUE;
}
return FALSE;
}
Bool
dmxSelectionPropertyNotify (ScreenPtr pScreen,
Window window,
int state,
Atom xProperty,
Time xTime)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
Atom property = dmxAtom (dmxScreen, xProperty);
DMXSelection *s;
if (property != dmxScreen->incrAtom)
return FALSE;
if (state == XCB_PROPERTY_NEW_VALUE)
{
for (s = propHead; s; s = s->next)
if (s->value[pScreen->myNum].out == window &&
s->property == dmxScreen->incrAtom)
break;
if (s)
{
xcb_get_property_cookie_t cookie = { 0 };
cookie = xcb_get_property (dmxScreen->connection,
xFalse,
window,
xProperty,
XCB_GET_PROPERTY_TYPE_ANY,
0,
0xffffffff);
if (cookie.sequence)
{
s->value[pScreen->myNum].in = cookie.sequence;
dmxAddSequence (&dmxScreen->request, cookie.sequence);
dmxSelectionResetTimer (s);
}
else
{
dmxSelectionDeleteProp (dmxUnhookSelection (s,
&propHead,
&propTail));
}
}
}
else
{
for (s = reqHead; s; s = s->next)
if (s->value[pScreen->myNum].out == window &&
s->property == dmxScreen->incrAtom)
break;
if (s)
{
WindowPtr pWin;
if (dixLookupWindow (&pWin,
s->wid,
serverClient,
DixReadAccess) == Success)
DeleteProperty (serverClient, pWin, s->property);
dmxSelectionResetTimer (s);
}
}
return TRUE;
}
Bool
dmxSelectionPropertyReplyCheck (ScreenPtr pScreen,
unsigned int sequence,
xcb_generic_reply_t *reply)
static void
dmxSelectionPropertyReply (ScreenPtr pScreen,
unsigned int sequence,
xcb_generic_reply_t *reply,
xcb_generic_error_t *error,
void *data)
{
DMXSelection *s;
@ -680,8 +531,7 @@ dmxSelectionPropertyReplyCheck (ScreenPtr pScreen,
/* don't send another selection notify event */
s->selection = None;
dmxSelectionResetTimer (s);
return TRUE;
return;
}
}
}
@ -689,13 +539,185 @@ dmxSelectionPropertyReplyCheck (ScreenPtr pScreen,
dmxSelectionDeleteProp (dmxUnhookSelection (s,
&propHead,
&propTail));
}
}
void
dmxSelectionNotify (ScreenPtr pScreen,
Window requestor,
Atom xSelection,
Atom xTarget,
Atom xProperty,
Time xTime)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
Atom selection = dmxSelectionAtom (dmxScreen, xSelection);
Atom target = dmxAtom (dmxScreen, xTarget);
DMXSelection *s;
for (s = convHead; s; s = s->next)
if (s->value[pScreen->myNum].out == requestor &&
s->selection == selection &&
s->target == target)
break;
if (s)
{
xcb_get_property_cookie_t cookie = { 0 };
Atom property = dmxAtom (dmxScreen, xProperty);
Atom target = dmxAtom (dmxScreen, xTarget);
if (ValidAtom (property) && ValidAtom (target))
cookie = xcb_get_property (dmxScreen->connection,
xFalse,
requestor,
xProperty,
XCB_GET_PROPERTY_TYPE_ANY,
0,
0xffffffff);
if (cookie.sequence)
{
const uint32_t value =
XCB_EVENT_MASK_STRUCTURE_NOTIFY |
XCB_EVENT_MASK_PROPERTY_CHANGE;
dmxUnhookSelection (s, &convHead, &convTail);
memset (s->value, 0, sizeof (s->value));
s->value[pScreen->myNum].out = requestor;
s->value[pScreen->myNum].in = cookie.sequence;
s->property = property;
s->target = target;
if (property == dmxScreen->incrAtom)
xcb_change_window_attributes (dmxScreen->connection,
requestor,
XCB_CW_EVENT_MASK,
&value);
dmxAppendSelection (s, &propTail);
dmxAddRequest (&dmxScreen->request,
dmxSelectionPropertyReply,
cookie.sequence,
0);
}
else
{
int i;
s->value[pScreen->myNum].out = 0;
for (i = 0; i < dmxNumScreens; i++)
if (s->value[i].out)
break;
if (i == dmxNumScreens)
dmxSelectionDeleteConv (dmxUnhookSelection (s,
&convHead,
&convTail));
}
}
}
Bool
dmxSelectionDestroyNotify (ScreenPtr pScreen,
Window window)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
DMXSelection *s;
for (s = reqHead; s; s = s->next)
if (s->value[pScreen->myNum].out == window &&
s->property == dmxScreen->incrAtom)
break;
if (s)
{
dmxSelectionDeleteReq (dmxUnhookSelection (s, &reqHead, &reqTail));
return TRUE;
}
return FALSE;
}
Bool
dmxSelectionPropertyNotify (ScreenPtr pScreen,
Window window,
int state,
Atom xProperty,
Time xTime)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
Atom property = dmxAtom (dmxScreen, xProperty);
DMXSelection *s;
if (property != dmxScreen->incrAtom)
return FALSE;
if (state == XCB_PROPERTY_NEW_VALUE)
{
for (s = propHead; s; s = s->next)
if (s->value[pScreen->myNum].out == window &&
s->property == dmxScreen->incrAtom)
break;
if (s)
{
xcb_get_property_cookie_t cookie = { 0 };
cookie = xcb_get_property (dmxScreen->connection,
xFalse,
window,
xProperty,
XCB_GET_PROPERTY_TYPE_ANY,
0,
0xffffffff);
if (cookie.sequence)
{
s->value[pScreen->myNum].in = cookie.sequence;
dmxAddRequest (&dmxScreen->request,
dmxSelectionPropertyReply,
cookie.sequence,
0);
dmxSelectionResetTimer (s);
}
else
{
dmxSelectionDeleteProp (dmxUnhookSelection (s,
&propHead,
&propTail));
}
}
}
else
{
for (s = reqHead; s; s = s->next)
if (s->value[pScreen->myNum].out == window &&
s->property == dmxScreen->incrAtom)
break;
if (s)
{
WindowPtr pWin;
if (dixLookupWindow (&pWin,
s->wid,
serverClient,
DixReadAccess) == Success)
DeleteProperty (serverClient, pWin, s->property);
dmxSelectionResetTimer (s);
}
}
return TRUE;
}
void
dmxSelectionRequest (ScreenPtr pScreen,
Window owner,

View file

@ -56,11 +56,6 @@ Bool
dmxSelectionDestroyNotify (ScreenPtr pScreen,
Window requestor);
Bool
dmxSelectionPropertyReplyCheck (ScreenPtr pScreen,
unsigned int sequence,
xcb_generic_reply_t *reply);
void
dmxSelectionRequest (ScreenPtr pScreen,
Window owner,

View file

@ -131,7 +131,10 @@ static void dmxDoSync(DMXScreenInfo *dmxScreen)
return;
dmxScreen->sync = xcb_get_input_focus (dmxScreen->connection);
dmxAddSequence (&dmxScreen->request, dmxScreen->sync.sequence);
dmxAddRequest (&dmxScreen->request,
dmxScreenSyncReply,
dmxScreen->sync.sequence,
0);
dmxSyncRequest++;
}
@ -276,16 +279,15 @@ void dmxSync(DMXScreenInfo *dmxScreen, Bool now)
/* error or reply doesn't matter, all we need is some response
from the back-end server */
Bool
dmxScreenReplyCheckSync (ScreenPtr pScreen,
unsigned int sequence,
xcb_generic_reply_t *reply)
void
dmxScreenSyncReply (ScreenPtr pScreen,
unsigned int sequence,
xcb_generic_reply_t *reply,
xcb_generic_error_t *error,
void *data)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
if (sequence != dmxScreen->sync.sequence)
return FALSE;
if (dmxScreen->sync.sequence)
{
dmxScreen->sync.sequence = 0;
@ -297,6 +299,4 @@ dmxScreenReplyCheckSync (ScreenPtr pScreen,
dmxActiveSyncTimer = NULL;
}
}
return TRUE;
}

View file

@ -42,7 +42,9 @@ extern int dmxWaitForResponse (void);
extern void dmxSyncActivate(const char *interval);
extern void dmxSyncInit(void);
extern void dmxSync(DMXScreenInfo *dmxScreen, Bool now);
extern Bool dmxScreenReplyCheckSync (ScreenPtr pScreen,
unsigned int sequence,
xcb_generic_reply_t *reply);
extern void dmxScreenSyncReply (ScreenPtr pScreen,
unsigned int sequence,
xcb_generic_reply_t *reply,
xcb_generic_error_t *error,
void *data);
#endif