mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2025-12-26 11:10:05 +01:00
Add selection support.
Selections are automatically shared with back-end servers. This provides seamless communication between back-end server clients and local clients. Some selections are not appropriate to share as they will cause unwanted conflicts. E.g. most manager selections. These selections can still be shared by adding a unique identifier to them. Selections that need this identifier can be specified using a command line option.
This commit is contained in:
parent
836e966663
commit
a1dd3fe551
10 changed files with 1696 additions and 104 deletions
25
hw/dmx/dmx.h
25
hw/dmx/dmx.h
|
|
@ -104,9 +104,18 @@ typedef struct _DMXPropTrans {
|
|||
Atom type;
|
||||
} DMXPropTrans;
|
||||
|
||||
/** Opcode for xcb_implementation. */
|
||||
typedef struct _DMXSelectionMap {
|
||||
const char *name;
|
||||
Atom atom;
|
||||
Atom beAtom;
|
||||
} DMXSelectionMap;
|
||||
|
||||
#define DMX_DETACHED 0xff
|
||||
|
||||
/** Number of backend selection conversion requests that can be
|
||||
processed simultaneously . */
|
||||
#define DMX_N_SELECTION_PROXY 10
|
||||
|
||||
/** Provide the typedef globally, but keep the contents opaque outside
|
||||
* of the XSync statistic routines. \see dmxstat.c */
|
||||
typedef struct _DMXStatInfo DMXStatInfo;
|
||||
|
|
@ -203,6 +212,15 @@ typedef struct _DMXScreenInfo {
|
|||
int rootY; /**< Y offset of "root" window WRT "screen"*/
|
||||
int rootEventMask;
|
||||
|
||||
/*---------- Selection information ----------*/
|
||||
Atom selectionAtom;
|
||||
Window selectionOwner;
|
||||
xcb_get_selection_owner_cookie_t getSelectionOwner;
|
||||
Window getSelectionOwnerResult;
|
||||
XID selectionProxyWid[DMX_N_SELECTION_PROXY];
|
||||
WindowPtr pSelectionProxyWin[DMX_N_SELECTION_PROXY];
|
||||
Atom incrAtom;
|
||||
|
||||
/*---------- Other related information ----------*/
|
||||
|
||||
int dpmsCapable; /**< Non-zero if backend is DPMS capable */
|
||||
|
|
@ -364,11 +382,16 @@ extern int xRRCrtcsPerScreen;
|
|||
extern DMXPropTrans *dmxPropTrans;
|
||||
extern int dmxPropTransNum;
|
||||
|
||||
extern DMXSelectionMap *dmxSelectionMap;
|
||||
extern int dmxSelectionMapNum;
|
||||
|
||||
#ifdef XV
|
||||
extern char **dmxXvImageFormats;
|
||||
extern int dmxXvImageFormatsNum;
|
||||
#endif
|
||||
|
||||
extern char dmxDigest[64];
|
||||
|
||||
/** Wrap screen or GC function pointer */
|
||||
#define DMX_WRAP(_entry, _newfunc, _saved, _actual) \
|
||||
do { \
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include "dmxcb.h"
|
||||
#include "dmxinput.h"
|
||||
#include "dmxlog.h"
|
||||
#include "dmxselection.h"
|
||||
|
||||
extern int connBlockScreenStart;
|
||||
|
||||
|
|
@ -194,4 +195,6 @@ void dmxConnectionBlockCallback(void)
|
|||
}
|
||||
#endif
|
||||
MAXSCREENSFREE(found);
|
||||
|
||||
dmxCreateSelectionProxies ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,6 +141,9 @@ int xRRCrtcsPerScreen = 1;
|
|||
DMXPropTrans *dmxPropTrans = NULL;
|
||||
int dmxPropTransNum = 0;
|
||||
|
||||
DMXSelectionMap *dmxSelectionMap = NULL;
|
||||
int dmxSelectionMapNum = 0;
|
||||
|
||||
#ifdef XV
|
||||
char **dmxXvImageFormats = NULL;
|
||||
int dmxXvImageFormatsNum = 0;
|
||||
|
|
@ -839,6 +842,26 @@ void InitOutput(ScreenInfo *pScreenInfo, int argc, char *argv[])
|
|||
strlen (dmxPropTrans[i].name),
|
||||
TRUE);
|
||||
|
||||
for (i = 0; i < dmxSelectionMapNum; i++)
|
||||
{
|
||||
char *beName;
|
||||
|
||||
dmxSelectionMap[i].atom = MakeAtom ((char *) dmxSelectionMap[i].name,
|
||||
strlen (dmxSelectionMap[i].name),
|
||||
TRUE);
|
||||
|
||||
beName = xalloc (strlen (dmxSelectionMap[i].name) +
|
||||
strlen (dmxDigest) + 2);
|
||||
if (!beName)
|
||||
dmxLog (dmxFatal, "InitOutput: not enough memory\n");
|
||||
|
||||
sprintf (beName, "%s_%s", dmxSelectionMap[i].name, dmxDigest);
|
||||
dmxSelectionMap[i].beAtom = MakeAtom ((char *) beName,
|
||||
strlen (beName),
|
||||
TRUE);
|
||||
xfree (beName);
|
||||
}
|
||||
|
||||
if (!dmxNumScreens)
|
||||
{
|
||||
dmxLaunchDisplay (argc, argv, dmxLaunchIndex, dmxLaunchVT);
|
||||
|
|
@ -1093,6 +1116,39 @@ void OsVendorInit(void)
|
|||
dmxPropTransNum = 1;
|
||||
}
|
||||
|
||||
if (!dmxSelectionMap)
|
||||
{
|
||||
dmxSelectionMap = xalloc (sizeof (DMXSelectionMap) * 9);
|
||||
dmxSelectionMap[0].name = "WM_S0";
|
||||
dmxSelectionMap[0].atom = 0;
|
||||
dmxSelectionMap[0].beAtom = 0;
|
||||
dmxSelectionMap[1].name = "_NET_WM_CM_S0";
|
||||
dmxSelectionMap[1].atom = 0;
|
||||
dmxSelectionMap[1].beAtom = 0;
|
||||
dmxSelectionMap[2].name = "_NET_SYSTEM_TRAY_S0";
|
||||
dmxSelectionMap[2].atom = 0;
|
||||
dmxSelectionMap[2].beAtom = 0;
|
||||
dmxSelectionMap[3].name = "_NET_DESKTOP_LAYOUT_S0";
|
||||
dmxSelectionMap[3].atom = 0;
|
||||
dmxSelectionMap[3].beAtom = 0;
|
||||
dmxSelectionMap[4].name = "_NET_DESKTOP_MANAGER_S0";
|
||||
dmxSelectionMap[4].atom = 0;
|
||||
dmxSelectionMap[4].beAtom = 0;
|
||||
dmxSelectionMap[5].name = "_XSETTINGS_S0";
|
||||
dmxSelectionMap[5].atom = 0;
|
||||
dmxSelectionMap[5].beAtom = 0;
|
||||
dmxSelectionMap[6].name = "CLIPBOARD_MANAGER";
|
||||
dmxSelectionMap[6].atom = 0;
|
||||
dmxSelectionMap[6].beAtom = 0;
|
||||
dmxSelectionMap[7].name = "GVM_SELECTION";
|
||||
dmxSelectionMap[7].atom = 0;
|
||||
dmxSelectionMap[7].beAtom = 0;
|
||||
dmxSelectionMap[8].name = "_COMPIZ_DM_S0";
|
||||
dmxSelectionMap[8].atom = 0;
|
||||
dmxSelectionMap[8].beAtom = 0;
|
||||
dmxSelectionMapNum = 9;
|
||||
}
|
||||
|
||||
#ifdef PANORAMIX
|
||||
noPanoramiXExtension = dmxNoPanoramiXExtension;
|
||||
PanoramiXExtensionDisabledHack = TRUE;
|
||||
|
|
@ -1211,6 +1267,26 @@ int ddxProcessArgument(int argc, char *argv[], int i)
|
|||
}
|
||||
retval = 3;
|
||||
}
|
||||
else if (!strcmp (argv[i], "-selection"))
|
||||
{
|
||||
if (++i < argc)
|
||||
{
|
||||
DMXSelectionMap *selection;
|
||||
|
||||
selection = xrealloc (dmxSelectionMap, sizeof (DMXSelectionMap) *
|
||||
(dmxSelectionMapNum + 1));
|
||||
if (selection)
|
||||
{
|
||||
selection[dmxSelectionMapNum].name = argv[i];
|
||||
selection[dmxSelectionMapNum].atom = 0;
|
||||
selection[dmxSelectionMapNum].beAtom = 0;
|
||||
|
||||
dmxSelectionMapNum++;
|
||||
dmxSelectionMap = selection;
|
||||
}
|
||||
}
|
||||
retval = 2;
|
||||
}
|
||||
#ifdef XV
|
||||
else if (!strcmp (argv[i], "-xvimage"))
|
||||
{
|
||||
|
|
@ -1277,6 +1353,7 @@ void ddxUseMsg(void)
|
|||
ErrorF("-crtcs num RANDR crtcs for each back-end display\n");
|
||||
#endif
|
||||
ErrorF("-prop name format Specify property translation\n");
|
||||
ErrorF("-selection name Specify selection that needs unique prefix\n");
|
||||
#ifdef XV
|
||||
ErrorF("-xvimage fourcc Enable XVideo image format\n");
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@
|
|||
#include "dmxwindow.h"
|
||||
#include "dmxlog.h"
|
||||
#include "dmxatom.h"
|
||||
#include "dmxselection.h"
|
||||
|
||||
#ifdef PANORAMIX
|
||||
#include "panoramiX.h"
|
||||
|
|
@ -146,14 +147,20 @@ dmxProcChangeProperty (ClientPtr client)
|
|||
XRT_WINDOW,
|
||||
DixReadAccess)))
|
||||
{
|
||||
FOR_NSCREENS_FORWARD(j) {
|
||||
if (dixLookupWindow (&pWin,
|
||||
FOR_NSCREENS_BACKWARD(j) {
|
||||
WindowPtr pScrWin;
|
||||
|
||||
if (dixLookupWindow (&pScrWin,
|
||||
win->info[j].id,
|
||||
serverClient,
|
||||
DixReadAccess) == Success)
|
||||
dmxBESetWindowProperty (pWin, pProp);
|
||||
dmxBESetWindowProperty (pScrWin, pProp);
|
||||
}
|
||||
}
|
||||
|
||||
dmxSelectionPropertyChangeCheck (pWin,
|
||||
stuff->property,
|
||||
stuff->nUnits);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
|
@ -161,6 +168,10 @@ dmxProcChangeProperty (ClientPtr client)
|
|||
|
||||
dmxBESetWindowProperty (pWin, pProp);
|
||||
|
||||
dmxSelectionPropertyChangeCheck (pWin,
|
||||
stuff->property,
|
||||
stuff->nUnits);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
|
@ -168,16 +179,17 @@ static void
|
|||
dmxDeleteProperty (WindowPtr pWin,
|
||||
Atom property)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV (pWin);
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
Window window;
|
||||
|
||||
if (!pWinPriv->window)
|
||||
window = dmxBEGetSelectionAdjustedPropertyWindow (pWin);
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
XLIB_PROLOGUE (dmxScreen);
|
||||
XDeleteProperty (dmxScreen->beDisplay,
|
||||
pWinPriv->window,
|
||||
window,
|
||||
dmxBEAtom (dmxScreen, property));
|
||||
XLIB_EPILOGUE (dmxScreen);
|
||||
}
|
||||
|
|
@ -226,6 +238,60 @@ dmxProcDeleteProperty (ClientPtr client)
|
|||
return Success;
|
||||
}
|
||||
|
||||
static int
|
||||
dmxProcGetProperty (ClientPtr client)
|
||||
{
|
||||
WindowPtr pWin;
|
||||
PropertyPtr pProp;
|
||||
int err;
|
||||
REQUEST(xGetPropertyReq);
|
||||
|
||||
err = (*dmxSaveProcVector[X_GetProperty]) (client);
|
||||
if (err != Success || !stuff->delete)
|
||||
return err;
|
||||
|
||||
if (dixLookupWindow (&pWin,
|
||||
stuff->window,
|
||||
serverClient,
|
||||
DixReadAccess) != Success ||
|
||||
dixLookupProperty (&pProp,
|
||||
pWin,
|
||||
stuff->property,
|
||||
serverClient,
|
||||
DixReadAccess) != BadMatch)
|
||||
return Success;
|
||||
|
||||
#ifdef PANORAMIX
|
||||
if (!noPanoramiXExtension)
|
||||
{
|
||||
PanoramiXRes *win;
|
||||
int j;
|
||||
|
||||
if ((win = (PanoramiXRes *) SecurityLookupIDByType (serverClient,
|
||||
stuff->window,
|
||||
XRT_WINDOW,
|
||||
DixReadAccess)))
|
||||
{
|
||||
FOR_NSCREENS_FORWARD(j) {
|
||||
if (dixLookupWindow (&pWin,
|
||||
win->info[j].id,
|
||||
serverClient,
|
||||
DixReadAccess) == Success)
|
||||
{
|
||||
dmxDeleteProperty (pWin, stuff->property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
#endif
|
||||
|
||||
dmxDeleteProperty (pWin, stuff->property);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static void
|
||||
dmxRotateProperties (WindowPtr pWin,
|
||||
Atom *atoms,
|
||||
|
|
@ -235,22 +301,22 @@ dmxRotateProperties (WindowPtr pWin,
|
|||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV (pWin);
|
||||
Window window;
|
||||
int i;
|
||||
|
||||
if (!pWinPriv->window)
|
||||
window = dmxBEGetSelectionAdjustedPropertyWindow (pWin);
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
XLIB_PROLOGUE (dmxScreen);
|
||||
for (i = 0; i < nAtoms; i++)
|
||||
buf[i] = dmxBEAtom (dmxScreen, atoms[i]);
|
||||
|
||||
XLIB_PROLOGUE (dmxScreen);
|
||||
XRotateWindowProperties (dmxScreen->beDisplay,
|
||||
pWinPriv->window,
|
||||
window,
|
||||
buf,
|
||||
nAtoms,
|
||||
nPositions);
|
||||
|
||||
XLIB_EPILOGUE (dmxScreen);
|
||||
}
|
||||
|
||||
|
|
@ -323,6 +389,7 @@ void dmxInitProps (void)
|
|||
|
||||
ProcVector[X_ChangeProperty] = dmxProcChangeProperty;
|
||||
ProcVector[X_DeleteProperty] = dmxProcDeleteProperty;
|
||||
ProcVector[X_GetProperty] = dmxProcGetProperty;
|
||||
ProcVector[X_RotateProperties] = dmxProcRotateProperties;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ DevPrivateKey dmxGlyphPrivateKey = &dmxGlyphPrivateKeyIndex; /**< Private index
|
|||
void dmxBEScreenInit(int idx, ScreenPtr pScreen)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[idx];
|
||||
char buf[256];
|
||||
int i, j;
|
||||
|
||||
/* FIXME: The dmxScreenInit() code currently assumes that it will
|
||||
|
|
@ -138,6 +139,12 @@ void dmxBEScreenInit(int idx, ScreenPtr pScreen)
|
|||
pScreen->whitePixel = dmxScreen->beWhitePixel;
|
||||
pScreen->blackPixel = dmxScreen->beBlackPixel;
|
||||
|
||||
dmxScreen->selectionAtom = None;
|
||||
dmxScreen->selectionOwner = None;
|
||||
|
||||
sprintf(buf, "DMX_%s", dmxDigest);
|
||||
dmxScreen->selectionAtom = XInternAtom (dmxScreen->beDisplay, buf, 0);
|
||||
|
||||
/* Handle screen savers and DPMS on the backend */
|
||||
dmxDPMSInit(dmxScreen);
|
||||
|
||||
|
|
@ -208,6 +215,168 @@ dmxScreenReplyCheckInput (ScreenPtr pScreen,
|
|||
return dmxInputReplyCheck (&dmxScreen->input, sequence, reply);
|
||||
}
|
||||
|
||||
static void
|
||||
dmxScreenGetSelectionOwner (ScreenPtr pScreen)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
|
||||
dmxScreen->selectionOwner = None;
|
||||
while (dmxScreen->selectionOwner == None)
|
||||
{
|
||||
xcb_connection_t *c = dmxScreen->connection;
|
||||
xcb_atom_t a = dmxScreen->selectionAtom;
|
||||
xcb_get_selection_owner_reply_t *reply;
|
||||
|
||||
reply = xcb_get_selection_owner_reply (c,
|
||||
xcb_get_selection_owner (c, a),
|
||||
NULL);
|
||||
if (!reply)
|
||||
break;
|
||||
|
||||
if (reply->owner)
|
||||
{
|
||||
if (reply->owner != dmxScreen->rootWin)
|
||||
{
|
||||
const uint32_t value = XCB_EVENT_MASK_STRUCTURE_NOTIFY;
|
||||
xcb_void_cookie_t r;
|
||||
xcb_generic_error_t *error;
|
||||
|
||||
r = xcb_change_window_attributes_checked (c,
|
||||
reply->owner,
|
||||
XCB_CW_EVENT_MASK,
|
||||
&value);
|
||||
error = xcb_request_check (c, r);
|
||||
if (error)
|
||||
{
|
||||
if (error->error_code != BadWindow)
|
||||
dmxScreen->selectionOwner = reply->owner;
|
||||
|
||||
free (error);
|
||||
}
|
||||
else
|
||||
{
|
||||
dmxScreen->selectionOwner = reply->owner;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dmxScreen->selectionOwner = dmxScreen->rootWin;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xcb_set_selection_owner (dmxScreen->connection,
|
||||
dmxScreen->rootWin,
|
||||
dmxScreen->selectionAtom,
|
||||
0);
|
||||
}
|
||||
|
||||
free (reply);
|
||||
}
|
||||
}
|
||||
|
||||
static Bool
|
||||
dmxScreenEventCheckSelection (ScreenPtr pScreen,
|
||||
xcb_generic_event_t *event)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
|
||||
switch (event->response_type & ~0x80) {
|
||||
case XCB_DESTROY_NOTIFY: {
|
||||
xcb_destroy_notify_event_t *xdestroy =
|
||||
(xcb_destroy_notify_event_t *) event;
|
||||
|
||||
if (xdestroy->window != dmxScreen->selectionOwner)
|
||||
return FALSE;
|
||||
|
||||
if (dmxScreen->selectionOwner == dmxScreen->rootWin)
|
||||
return FALSE;
|
||||
|
||||
dmxScreenGetSelectionOwner (pScreen);
|
||||
} break;
|
||||
case XCB_PROPERTY_NOTIFY: {
|
||||
xcb_property_notify_event_t *xproperty =
|
||||
(xcb_property_notify_event_t *) event;
|
||||
|
||||
if (!dmxSelectionPropertyNotify (pScreen,
|
||||
xproperty->window,
|
||||
xproperty->state,
|
||||
xproperty->atom,
|
||||
xproperty->time))
|
||||
return FALSE;
|
||||
} break;
|
||||
case XCB_SELECTION_CLEAR: {
|
||||
xcb_selection_clear_event_t *xclear =
|
||||
(xcb_selection_clear_event_t *) event;
|
||||
|
||||
if (xclear->selection == dmxScreen->selectionAtom)
|
||||
{
|
||||
dmxScreenGetSelectionOwner (pScreen);
|
||||
}
|
||||
else
|
||||
{
|
||||
dmxSelectionClear (pScreen,
|
||||
xclear->owner,
|
||||
xclear->selection);
|
||||
}
|
||||
} break;
|
||||
case XCB_SELECTION_NOTIFY: {
|
||||
xcb_selection_notify_event_t *xnotify =
|
||||
(xcb_selection_notify_event_t *) event;
|
||||
|
||||
dmxSelectionNotify (pScreen,
|
||||
xnotify->requestor,
|
||||
xnotify->selection,
|
||||
xnotify->target,
|
||||
xnotify->property,
|
||||
xnotify->time);
|
||||
} break;
|
||||
case XCB_SELECTION_REQUEST: {
|
||||
xcb_selection_request_event_t *xrequest =
|
||||
(xcb_selection_request_event_t *) event;
|
||||
|
||||
dmxSelectionRequest (pScreen,
|
||||
xrequest->owner,
|
||||
xrequest->requestor,
|
||||
xrequest->selection,
|
||||
xrequest->target,
|
||||
xrequest->property,
|
||||
xrequest->time);
|
||||
} break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
@ -326,6 +495,7 @@ dmxScreenEventCheckOutputWindow (ScreenPtr pScreen,
|
|||
/* output window has been destroyed, detach screen when we reach
|
||||
the block handler */
|
||||
dmxScreen->scrnWin = None;
|
||||
return TRUE;
|
||||
} break;
|
||||
case XCB_MAP_NOTIFY: {
|
||||
xcb_map_notify_event_t *xmap = (xcb_map_notify_event_t *) event;
|
||||
|
|
@ -334,10 +504,10 @@ dmxScreenEventCheckOutputWindow (ScreenPtr pScreen,
|
|||
return TRUE;
|
||||
} break;
|
||||
default:
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
|
|
@ -361,7 +531,7 @@ dmxScreenEventCheckManageRoot (ScreenPtr pScreen,
|
|||
(xcb_map_request_event_t *) event;
|
||||
xcb_client_message_event_t *xclient =
|
||||
(xcb_client_message_event_t *) event;
|
||||
xcb_map_notify_event_t * xmap =
|
||||
xcb_map_notify_event_t *xmap =
|
||||
(xcb_map_notify_event_t *) event;
|
||||
|
||||
switch (event->response_type & ~0x80) {
|
||||
|
|
@ -379,7 +549,10 @@ dmxScreenEventCheckManageRoot (ScreenPtr pScreen,
|
|||
break;
|
||||
case XCB_MAP_NOTIFY:
|
||||
if (xmap->window == dmxScreen->rootWin)
|
||||
{
|
||||
dmxScreenGetSelectionOwner (pScreen);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* fall-through */
|
||||
default:
|
||||
|
|
@ -680,6 +853,7 @@ dmxBEDispatch (ScreenPtr pScreen)
|
|||
while ((event = xcb_poll_for_event (dmxScreen->connection)))
|
||||
{
|
||||
if (!dmxScreenEventCheckInput (pScreen, event) &&
|
||||
!dmxScreenEventCheckSelection (pScreen, event) &&
|
||||
!dmxScreenEventCheckOutputWindow (pScreen, event) &&
|
||||
!dmxScreenEventCheckManageRoot (pScreen, event) &&
|
||||
!dmxScreenEventCheckExpose (pScreen, event) &&
|
||||
|
|
@ -731,7 +905,8 @@ dmxBEDispatch (ScreenPtr pScreen)
|
|||
dmxScreen->request.tail = &dmxScreen->request.head;
|
||||
|
||||
if (!dmxScreenReplyCheckSync (pScreen, head->sequence, rep) &&
|
||||
!dmxScreenReplyCheckInput (pScreen, head->sequence, rep))
|
||||
!dmxScreenReplyCheckInput (pScreen, head->sequence, rep) &&
|
||||
!dmxScreenReplyCheckSelection (pScreen, head->sequence, rep))
|
||||
{
|
||||
/* error response */
|
||||
if (rep->response_type == 0)
|
||||
|
|
@ -751,36 +926,27 @@ dmxBEDispatch (ScreenPtr pScreen)
|
|||
if (!dmxScreen->scrnWin ||
|
||||
xcb_connection_has_error (dmxScreen->connection))
|
||||
{
|
||||
if (!dmxScreen->broken)
|
||||
while (dmxScreen->request.head)
|
||||
{
|
||||
DMXSequence *head = dmxScreen->request.head;
|
||||
static xcb_generic_error_t detached_error = { 0, DMX_DETACHED };
|
||||
|
||||
dmxScreenEventCheckInput (pScreen, (xcb_generic_event_t *)
|
||||
&detached_error);
|
||||
dmxScreenEventCheckOutputWindow (pScreen, (xcb_generic_event_t *)
|
||||
&detached_error);
|
||||
dmxScreenEventCheckManageRoot (pScreen, (xcb_generic_event_t *)
|
||||
&detached_error);
|
||||
dmxScreenEventCheckExpose (pScreen, (xcb_generic_event_t *)
|
||||
&detached_error);
|
||||
dmxScreen->request.head = head->next;
|
||||
if (!dmxScreen->request.head)
|
||||
dmxScreen->request.tail = &dmxScreen->request.head;
|
||||
|
||||
#ifdef MITSHM
|
||||
dmxScreenEventCheckShm (pScreen, (xcb_generic_event_t *)
|
||||
&detached_error);
|
||||
#endif
|
||||
|
||||
#ifdef RANDR
|
||||
dmxScreenEventCheckRR (pScreen, (xcb_generic_event_t *)
|
||||
&detached_error);
|
||||
#endif
|
||||
|
||||
dmxScreenReplyCheckSync (pScreen, 0, (xcb_generic_reply_t *)
|
||||
dmxScreenReplyCheckSync (pScreen, head->sequence,
|
||||
(xcb_generic_reply_t *)
|
||||
&detached_error);
|
||||
dmxScreenReplyCheckInput (pScreen, 0, (xcb_generic_reply_t *)
|
||||
dmxScreenReplyCheckInput (pScreen, head->sequence,
|
||||
(xcb_generic_reply_t *)
|
||||
&detached_error);
|
||||
|
||||
dmxScreen->broken = TRUE;
|
||||
dmxScreenReplyCheckSelection (pScreen, head->sequence,
|
||||
(xcb_generic_reply_t *)
|
||||
&detached_error);
|
||||
}
|
||||
|
||||
dmxScreen->broken = TRUE;
|
||||
}
|
||||
|
||||
dmxScreen->inDispatch--;
|
||||
|
|
@ -902,7 +1068,10 @@ Bool dmxScreenInit(int idx, ScreenPtr pScreen, int argc, char *argv[])
|
|||
dmxScreen->request.head = NULL;
|
||||
dmxScreen->request.tail = &dmxScreen->request.head;
|
||||
|
||||
dmxScreen->rootEventMask = ExposureMask | SubstructureRedirectMask;
|
||||
dmxScreen->rootEventMask = ExposureMask | StructureNotifyMask |
|
||||
SubstructureRedirectMask;
|
||||
|
||||
dmxScreen->incrAtom = MakeAtom ("INCR", strlen ("INCR"), TRUE);
|
||||
|
||||
#ifdef MITSHM
|
||||
dmxScreen->beShm = FALSE;
|
||||
|
|
@ -1207,6 +1376,10 @@ Bool dmxCloseScreen(int idx, ScreenPtr pScreen)
|
|||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[idx];
|
||||
|
||||
/* Free selection proxy window tree */
|
||||
if (dmxScreen->selectionProxyWid[0])
|
||||
FreeResource (dmxScreen->selectionProxyWid[0], RT_NONE);
|
||||
|
||||
/* Reset the proc vectors */
|
||||
if (idx == 0) {
|
||||
#ifdef COMPOSITE
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -27,8 +27,57 @@
|
|||
#define DMXSELECTION_H
|
||||
|
||||
#include "dmx.h"
|
||||
#include "propertyst.h"
|
||||
|
||||
extern void dmxInitSelections (void);
|
||||
extern void dmxResetSelections (void);
|
||||
Window
|
||||
dmxBEGetSelectionAdjustedPropertyWindow (WindowPtr pWin);
|
||||
|
||||
void
|
||||
dmxSelectionClear (ScreenPtr pScreen,
|
||||
Window owner,
|
||||
Atom xSelection);
|
||||
|
||||
void
|
||||
dmxSelectionNotify (ScreenPtr pScreen,
|
||||
Window requestor,
|
||||
Atom xSelection,
|
||||
Atom xTarget,
|
||||
Atom xProperty,
|
||||
Time xTime);
|
||||
|
||||
Bool
|
||||
dmxSelectionPropertyNotify (ScreenPtr pScreen,
|
||||
Window requestor,
|
||||
int state,
|
||||
Atom xProperty,
|
||||
Time xTime);
|
||||
|
||||
Bool
|
||||
dmxSelectionPropertyReplyCheck (ScreenPtr pScreen,
|
||||
unsigned int sequence,
|
||||
xcb_generic_reply_t *reply);
|
||||
|
||||
void
|
||||
dmxSelectionRequest (ScreenPtr pScreen,
|
||||
Window owner,
|
||||
Window requestor,
|
||||
Atom xSelection,
|
||||
Atom xTarget,
|
||||
Atom xProperty,
|
||||
Time xTime);
|
||||
|
||||
void
|
||||
dmxSelectionPropertyChangeCheck (WindowPtr pWin,
|
||||
Atom property,
|
||||
int nUnits);
|
||||
|
||||
Bool
|
||||
dmxCreateSelectionProxies (void);
|
||||
|
||||
void
|
||||
dmxInitSelections (void);
|
||||
|
||||
void
|
||||
dmxResetSelections (void);
|
||||
|
||||
#endif /* DMXSELECTION_H */
|
||||
|
|
|
|||
|
|
@ -650,12 +650,13 @@ dmxShmInit (ScreenPtr pScreen)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
mask = (GCFunction | GCPlaneMask | GCClipMask);
|
||||
mask = (GCFunction | GCPlaneMask | GCClipMask | GCGraphicsExposures);
|
||||
|
||||
gcvals.function = GXcopy;
|
||||
gcvals.plane_mask = AllPlanes;
|
||||
gcvals.clip_mask = None;
|
||||
gcvals.foreground = 0;
|
||||
gcvals.function = GXcopy;
|
||||
gcvals.plane_mask = AllPlanes;
|
||||
gcvals.clip_mask = None;
|
||||
gcvals.foreground = 0;
|
||||
gcvals.graphics_exposures = FALSE;
|
||||
|
||||
pixmap = xcb_generate_id (dmxScreen->connection);
|
||||
xcb_create_pixmap (dmxScreen->connection,
|
||||
|
|
|
|||
|
|
@ -283,9 +283,8 @@ dmxScreenReplyCheckSync (ScreenPtr pScreen,
|
|||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
|
||||
if (reply->response_type || reply->pad0 != DMX_DETACHED)
|
||||
if (sequence != dmxScreen->sync.sequence)
|
||||
return FALSE;
|
||||
if (sequence != dmxScreen->sync.sequence)
|
||||
return FALSE;
|
||||
|
||||
if (dmxScreen->sync.sequence)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
#include "dmxfont.h"
|
||||
#include "dmxatom.h"
|
||||
#include "dmxprop.h"
|
||||
#include "dmxselection.h"
|
||||
#ifdef RENDER
|
||||
#include "dmxpict.h"
|
||||
#endif
|
||||
|
|
@ -152,7 +153,7 @@ Window dmxCreateRootWindow(WindowPtr pWindow)
|
|||
XLIB_EPILOGUE (dmxScreen);
|
||||
|
||||
dmxPropertyWindow (dmxScreen, win);
|
||||
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
|
|
@ -1347,12 +1348,13 @@ dmxBESetWindowProperty (WindowPtr pWindow,
|
|||
{
|
||||
ScreenPtr pScreen = pWindow->drawable.pScreen;
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV (pWindow);
|
||||
unsigned char *data = pProp->data;
|
||||
const char *format = NULL;
|
||||
Window window;
|
||||
int i;
|
||||
|
||||
if (!pWinPriv->window)
|
||||
window = dmxBEGetSelectionAdjustedPropertyWindow (pWindow);
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
/* only 32 bit data types can be translated */
|
||||
|
|
@ -1429,7 +1431,7 @@ dmxBESetWindowProperty (WindowPtr pWindow,
|
|||
|
||||
XLIB_PROLOGUE (dmxScreen);
|
||||
XChangeProperty (dmxScreen->beDisplay,
|
||||
pWinPriv->window,
|
||||
window,
|
||||
dmxBEAtom (dmxScreen, pProp->propertyName),
|
||||
dmxBEAtom (dmxScreen, pProp->type),
|
||||
pProp->format,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue