From 4174d4f00dfba6748e8f0368563a390a928f53ef Mon Sep 17 00:00:00 2001 From: David Reveman Date: Mon, 6 Oct 2008 19:13:52 -0400 Subject: [PATCH] Clean up and initial XDnD support. --- hw/dmx/Makefile.am | 2 + hw/dmx/dmx.h | 33 +- hw/dmx/dmxdnd.c | 713 ++++++++++++++++++++++++++++++++++++++++++ hw/dmx/dmxdnd.h | 53 ++++ hw/dmx/dmxdpms.c | 19 +- hw/dmx/dmxdpms.h | 4 +- hw/dmx/dmxextension.c | 54 +--- hw/dmx/dmxinit.c | 4 + hw/dmx/dmxinput.c | 22 +- hw/dmx/dmxprop.c | 40 --- hw/dmx/dmxprop.h | 1 - hw/dmx/dmxrandr.c | 64 +++- hw/dmx/dmxscrinit.c | 94 +++--- hw/dmx/dmxscrinit.h | 2 +- hw/dmx/dmxselection.c | 85 +++-- hw/dmx/dmxshm.c | 27 +- hw/dmx/dmxshm.h | 2 +- hw/dmx/dmxwindow.c | 9 +- 18 files changed, 1007 insertions(+), 221 deletions(-) create mode 100644 hw/dmx/dmxdnd.c create mode 100644 hw/dmx/dmxdnd.h diff --git a/hw/dmx/Makefile.am b/hw/dmx/Makefile.am index 593e0c6bb..53c1027b7 100644 --- a/hw/dmx/Makefile.am +++ b/hw/dmx/Makefile.am @@ -100,6 +100,8 @@ Xdmx_SOURCES = dmx.c \ dmxgrab.h \ dmxselection.c \ dmxselection.h \ + dmxdnd.c \ + dmxdnd.h \ $(top_srcdir)/mi/miinitext.c \ $(top_srcdir)/fb/fbcmap_mi.c \ $(GLX_SRCS) \ diff --git a/hw/dmx/dmx.h b/hw/dmx/dmx.h index 9f3bcb86f..73dc9312c 100644 --- a/hw/dmx/dmx.h +++ b/hw/dmx/dmx.h @@ -213,7 +213,7 @@ typedef struct _DMXScreenInfo { int rootEventMask; /*---------- Selection information ----------*/ - Atom selectionAtom; + Atom beSelectionAtom; Window selectionOwner; xcb_get_selection_owner_cookie_t getSelectionOwner; Window getSelectionOwnerResult; @@ -221,6 +221,37 @@ typedef struct _DMXScreenInfo { WindowPtr pSelectionProxyWin[DMX_N_SELECTION_PROXY]; Atom incrAtom; + /*---------- DnD information ----------*/ + Atom wmStateAtom; + Atom xdndProxyAtom; + Atom xdndAwareAtom; + Atom xdndSelectionAtom; + Atom xdndEnterAtom; + Atom xdndPositionAtom; + Atom xdndStatusAtom; + Atom xdndLeaveAtom; + Atom xdndDropAtom; + Atom xdndFinishedAtom; + Atom xdndTypeListAtom; + Atom xdndActionListAtom; + Atom xdndActionDescriptionAtom; + Bool dndHasTypeProp; + XID dndWid; + XID dndSource; + XID dndTarget; + int dndStatus; + XID dndWindow; + Atom dndAction; + int dndVersion; + Atom dndType[3]; + RegionRec dndBox; + int dndX; + int dndY; + int dndXPos; + int dndYPos; + xcb_translate_coordinates_cookie_t translateCoordinates; + xcb_get_property_cookie_t getTypeProp; + /*---------- Other related information ----------*/ int dpmsCapable; /**< Non-zero if backend is DPMS capable */ diff --git a/hw/dmx/dmxdnd.c b/hw/dmx/dmxdnd.c new file mode 100644 index 000000000..8214c23f3 --- /dev/null +++ b/hw/dmx/dmxdnd.c @@ -0,0 +1,713 @@ +/* + * Copyright © 2008 Novell, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Novell, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior permission. + * Novell, Inc. makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN + * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: David Reveman + */ + +#ifdef HAVE_DMX_CONFIG_H +#include +#endif + +#include "dmx.h" +#include "dmxlog.h" +#include "dmxatom.h" +#include "dmxwindow.h" +#include "dmxscrinit.h" +#include "dmxsync.h" +#include "dmxselection.h" +#include "dmxdnd.h" + +void +dmxBEDnDRootWindowUpdate (ScreenPtr pScreen, + Window window) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + xcb_atom_t version = 5; + + xcb_change_property (dmxScreen->connection, + XCB_PROP_MODE_REPLACE, + window, + dmxBEAtom (dmxScreen, dmxScreen->xdndAwareAtom), + XA_ATOM, + 32, + 1, + &version); + xcb_change_property (dmxScreen->connection, + XCB_PROP_MODE_REPLACE, + window, + dmxBEAtom (dmxScreen, dmxScreen->xdndProxyAtom), + XA_WINDOW, + 32, + 1, + &window); +} + +static void +dmxDnDUpdatePosition (DMXScreenInfo *dmxScreen, + WindowPtr pWin, + int x, + int y) +{ + WindowPtr pDst = NullWindow; + BoxRec box; + XID targetId = None; + xEvent event; + int version = 0; + + event.u.u.type = ClientMessage | 0x80; + event.u.u.detail = 32; + + event.u.clientMessage.u.l.longs0 = dmxScreens[0].selectionProxyWid[0]; + + while (pWin) + { + if ((pWin->mapped) && + (x >= pWin->drawable.x - wBorderWidth (pWin)) && + (x < pWin->drawable.x + (int) pWin->drawable.width + + wBorderWidth(pWin)) && + (y >= pWin->drawable.y - wBorderWidth (pWin)) && + (y < pWin->drawable.y + (int) pWin->drawable.height + + wBorderWidth (pWin)) + /* When a window is shaped, a further check + * is made to see if the point is inside + * borderSize + */ + && (!wBoundingShape (pWin) || + POINT_IN_REGION (pWin->drawable.pScreen, + &pWin->borderSize, x, y, &box)) + + && (!wInputShape (pWin) || + POINT_IN_REGION (pWin->drawable.pScreen, + wInputShape (pWin), + x - pWin->drawable.x, + y - pWin->drawable.y, &box))) + { + WindowPtr pProxy = NullWindow; + PropertyPtr pProp; + + if (dixLookupProperty (&pProp, + pWin, + dmxScreen->xdndProxyAtom, + serverClient, + DixReadAccess) == Success) + { + if (pProp->format == 32 && pProp->size == 1) + dixLookupWindow (&pProxy, + *((XID *) pProp->data), + serverClient, + DixReadAccess); + } + + if (dixLookupProperty (&pProp, + pProxy ? pProxy : pWin, + dmxScreen->xdndAwareAtom, + serverClient, + DixReadAccess) == Success) + { + if (pProp->format == 32 && pProp->size == 1) + { + Atom v; + + v = *((Atom *) pProp->data); + if (v >= 3) + { + pDst = pProxy ? pProxy : pWin; + targetId = pWin->drawable.id; + version = v; + if (version > 5) + version = 5; + } + } + } + + if (dixLookupProperty (&pProp, + pWin, + dmxScreen->wmStateAtom, + serverClient, + DixReadAccess) == Success) + break; + + pWin = pWin->firstChild; + } + else + pWin = pWin->nextSib; + } + + if (dmxScreen->dndTarget != targetId) + { + if (dmxScreen->dndWindow) + { + event.u.clientMessage.window = dmxScreen->dndTarget; + event.u.clientMessage.u.l.type = dmxScreen->xdndLeaveAtom; + + event.u.clientMessage.u.l.longs1 = 0; + event.u.clientMessage.u.l.longs2 = 0; + event.u.clientMessage.u.l.longs3 = 0; + event.u.clientMessage.u.l.longs4 = 0; + + if (dixLookupWindow (&pWin, + dmxScreen->dndWindow, + serverClient, + DixReadAccess) == Success) + DeliverEventsToWindow (PickPointer (serverClient), + pWin, + &event, + 1, + NoEventMask, + NullGrab, 0); + + dmxScreen->dndStatus = 0; + dmxScreen->dndTarget = None; + dmxScreen->dndWindow = None; + } + + if (pDst) + { + event.u.clientMessage.window = targetId; + event.u.clientMessage.u.l.type = dmxScreen->xdndEnterAtom; + + event.u.clientMessage.u.l.longs1 = version << 24; + event.u.clientMessage.u.l.longs2 = dmxScreen->dndType[0]; + event.u.clientMessage.u.l.longs3 = dmxScreen->dndType[1]; + event.u.clientMessage.u.l.longs4 = dmxScreen->dndType[2]; + + if (dmxScreen->dndHasTypeProp) + event.u.clientMessage.u.l.longs1 |= 1; + + DeliverEventsToWindow (PickPointer (serverClient), + pDst, + &event, + 1, + NoEventMask, + NullGrab, 0); + + dmxScreen->dndStatus = 0; + dmxScreen->dndWindow = pDst->drawable.id; + dmxScreen->dndTarget = targetId; + dmxScreen->dndXPos = -1; + dmxScreen->dndYPos = -1; + dmxScreen->dndVersion = version; + + REGION_EMPTY (pScreen, &dmxScreen->dndBox); + } + } + + if (pDst && !POINT_IN_REGION (pScreen, + &dmxScreen->dndBox, + x, y, &box)) + { + event.u.clientMessage.window = dmxScreen->dndTarget; + event.u.clientMessage.u.l.type = dmxScreen->xdndPositionAtom; + + event.u.clientMessage.u.l.longs1 = 0; + event.u.clientMessage.u.l.longs2 = (x << 16) | y; + event.u.clientMessage.u.l.longs3 = currentTime.milliseconds; + event.u.clientMessage.u.l.longs4 = dmxAtom (dmxScreen, + dmxScreen->dndAction); + + DeliverEventsToWindow (PickPointer (serverClient), + pDst, + &event, + 1, + NoEventMask, + NullGrab, 0); + + dmxScreen->dndXPos = x; + dmxScreen->dndYPos = y; + + box.x1 = SHRT_MIN; + box.y1 = SHRT_MIN; + box.x2 = SHRT_MAX; + box.y2 = SHRT_MAX; + + REGION_RESET (pScreen, &dmxScreen->dndBox, &box); + } +} + +static void +dmxDnDPositionMessage (ScreenPtr pScreen, + Window source, + int xRoot, + int yRoot, + Time time, + int action) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + + dmxScreen->dndAction = action; + + dmxScreen->translateCoordinates = + xcb_translate_coordinates (dmxScreen->connection, + DefaultRootWindow (dmxScreen->beDisplay), + dmxScreen->rootWin, + xRoot, + yRoot); + dmxAddSequence (&dmxScreen->request, + dmxScreen->translateCoordinates.sequence); +} + +static void +dmxDnDEnterMessage (ScreenPtr pScreen, + Window target, + Window source, + Atom type0, + Atom type1, + Atom type2, + Bool hasTypeProp, + int version) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + + dmxScreen->dndWid = target; + dmxScreen->dndSource = source; + dmxScreen->dndAction = None; + dmxScreen->dndType[0] = type0; + dmxScreen->dndType[1] = type1; + dmxScreen->dndType[2] = type2; + + dmxScreen->dndHasTypeProp = FALSE; + + if (hasTypeProp) + { + dmxScreen->getTypeProp = + xcb_get_property (dmxScreen->connection, + xFalse, + source, + dmxBEAtom (dmxScreen, + dmxScreen->xdndTypeListAtom), + XCB_GET_PROPERTY_TYPE_ANY, + 0, + 0xffffffff); + + if (dmxScreen->getTypeProp.sequence) + dmxAddSequence (&dmxScreen->request, + dmxScreen->getTypeProp.sequence); + } +} + +static void +dmxDnDLeaveMessage (ScreenPtr pScreen, + Window source) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + + dmxDnDUpdatePosition (dmxScreen, NullWindow, 0, 0); + + dmxScreen->dndWid = None; + dmxScreen->dndSource = None; + dmxScreen->dndStatus = 0; + dmxScreen->dndXPos = -1; + dmxScreen->dndYPos = -1; + dmxScreen->dndX = -1; + dmxScreen->dndY = -1; +} + +static void +dmxDnDDropMessage (ScreenPtr pScreen, + Window source, + Time time) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + + if (dmxScreen->dndWindow) + { + WindowPtr pWin; + xEvent event; + BoxRec box; + + event.u.u.type = ClientMessage | 0x80; + event.u.u.detail = 32; + + event.u.clientMessage.window = dmxScreen->dndTarget; + event.u.clientMessage.u.l.type = dmxScreen->xdndDropAtom; + + event.u.clientMessage.u.l.longs0 = dmxScreens[0].selectionProxyWid[0]; + event.u.clientMessage.u.l.longs1 = 0; + event.u.clientMessage.u.l.longs2 = currentTime.milliseconds; + event.u.clientMessage.u.l.longs3 = 0; + event.u.clientMessage.u.l.longs4 = 0; + + if (dixLookupWindow (&pWin, + dmxScreen->dndWindow, + serverClient, + DixReadAccess) == Success) + DeliverEventsToWindow (PickPointer (serverClient), + pWin, + &event, + 1, + NoEventMask, + NullGrab, 0); + + box.x1 = SHRT_MIN; + box.y1 = SHRT_MIN; + box.x2 = SHRT_MAX; + box.y2 = SHRT_MAX; + + REGION_RESET (pScreen, &dmxScreen->dndBox, &box); + } + else + { + xcb_client_message_event_t xevent; + + dmxDnDLeaveMessage (pScreen, source); + + xevent.response_type = XCB_CLIENT_MESSAGE; + xevent.format = 32; + + xevent.type = dmxBEAtom (dmxScreen, dmxScreen->xdndFinishedAtom); + xevent.window = dmxScreen->dndSource; + + xevent.data.data32[0] = dmxScreen->dndWid; + xevent.data.data32[1] = 0; + xevent.data.data32[2] = 0; + xevent.data.data32[3] = 0; + xevent.data.data32[4] = 0; + + xcb_send_event (dmxScreen->connection, + FALSE, + dmxScreen->dndSource, + 0, + (const char *) &xevent); + + dmxScreen->dndWid = None; + dmxScreen->dndSource = None; + } +} + +Bool +dmxScreenEventCheckDnD (ScreenPtr pScreen, + xcb_generic_event_t *event) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + + switch (event->response_type & ~0x80) { + case XCB_CLIENT_MESSAGE: { + xcb_client_message_event_t *xclient = + (xcb_client_message_event_t *) event; + xcb_atom_t type = xclient->type; + + if (dmxAtom (dmxScreen, type) == dmxScreen->xdndPositionAtom) + { + dmxDnDPositionMessage (pScreen, + xclient->data.data32[0], + xclient->data.data32[2] >> 16, + xclient->data.data32[2] & 0xffff, + xclient->data.data32[3], + xclient->data.data32[4]); + } + else if (dmxAtom (dmxScreen, type) == dmxScreen->xdndEnterAtom) + { + dmxDnDEnterMessage (pScreen, + xclient->window, + xclient->data.data32[0], + xclient->data.data32[2], + xclient->data.data32[3], + xclient->data.data32[4], + ((xclient->data.data32[1] & 1) != 0), + (xclient->data.data32[1] & 0xff000000) >> 24); + } + else if (dmxAtom (dmxScreen, type) == dmxScreen->xdndLeaveAtom) + { + dmxDnDLeaveMessage (pScreen, xclient->data.data32[0]); + } + else if (dmxAtom (dmxScreen, type) == dmxScreen->xdndDropAtom) + { + dmxDnDDropMessage (pScreen, + xclient->data.data32[0], + xclient->data.data32[2]); + } + else + { + return FALSE; + } + } break; + default: + return FALSE; + } + + return TRUE; +} + +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; + + 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 | 1 << 1; + xevent.data.data32[2] = 0; + xevent.data.data32[3] = 0; + xevent.data.data32[4] = dmxScreen->dndAction; + + 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 = (uint32_t *) (&xproperty[1]); + int i; + + for (i = 0; i < xproperty->value_len; i++) + data[i] = dmxAtom (dmxScreen, data[i]); + + ChangeWindowProperty (dmxScreens[0].pSelectionProxyWin[0], + dmxScreen->xdndTypeListAtom, + XA_ATOM, + 32, + PropModeReplace, + xproperty->value_len, + &xproperty[1], + 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; + } + + return FALSE; +} + +void +dmxDnDClientMessageEvent (xEvent *event) +{ + int i; + + for (i = 0; i < dmxNumScreens; i++) + { + DMXScreenInfo *dmxScreen = &dmxScreens[i]; + + if (event->u.clientMessage.u.l.longs0 == dmxScreen->dndTarget) + { + Atom type = event->u.clientMessage.u.l.type; + + if (!dmxScreen->dndSource) + continue; + + if (type == dmxScreen->xdndStatusAtom) + { + int dndStatus = event->u.clientMessage.u.l.longs0 | (1 << 0); + + if (dmxScreen->dndStatus != dndStatus || + dmxScreen->dndAction != event->u.clientMessage.u.l.longs4) + { + xcb_client_message_event_t xevent; + + dmxScreen->dndStatus = dndStatus; + dmxScreen->dndAction = event->u.clientMessage.u.l.longs4; + + 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 | (1 << 1); + xevent.data.data32[2] = 0; + xevent.data.data32[3] = 0; + xevent.data.data32[4] = dmxScreen->dndAction; + + xcb_send_event (dmxScreen->connection, + FALSE, + dmxScreen->dndSource, + 0, + (const char *) &xevent); + } + + if (dmxScreen->dndStatus & (1 << 1)) + { + BoxRec box; + + box.x1 = event->u.clientMessage.u.l.longs2 >> 16; + box.y1 = event->u.clientMessage.u.l.longs2 & 0xffff; + box.x2 = box.x1 + + (event->u.clientMessage.u.l.longs3 >> 16); + box.y2 = box.y1 + + (event->u.clientMessage.u.l.longs3 & 0xffff); + + REGION_RESET (pScreen, &dmxScreen->dndBox, &box); + } + + if (dmxScreen->dndX != dmxScreen->dndXPos || + dmxScreen->dndY != dmxScreen->dndYPos) + { + WindowPtr pWin = WindowTable[i]; +#ifdef PANORAMIX + if (!noPanoramiXExtension) + pWin = WindowTable[0]; +#endif + + dmxDnDUpdatePosition (dmxScreen, + pWin, + dmxScreen->dndX, + dmxScreen->dndY); + } + } + else if (type == dmxScreen->xdndFinishedAtom) + { + xcb_client_message_event_t xevent; + + xevent.response_type = XCB_CLIENT_MESSAGE; + xevent.format = 32; + + xevent.type = dmxBEAtom (dmxScreen, + dmxScreen->xdndFinishedAtom); + xevent.window = dmxScreen->dndSource; + + xevent.data.data32[0] = dmxScreen->dndWid; + xevent.data.data32[1] = 0; + xevent.data.data32[2] = 0; + xevent.data.data32[3] = 0; + xevent.data.data32[4] = 0; + + if (dmxScreen->dndVersion >= 5) + { + xevent.data.data32[1] = + event->u.clientMessage.u.l.longs1 & 1; + xevent.data.data32[2] = event->u.clientMessage.u.l.longs2; + } + + xcb_send_event (dmxScreen->connection, + FALSE, + dmxScreen->dndSource, + 0, + (const char *) &xevent); + + dmxScreen->dndTarget = None; + dmxScreen->dndWindow = None; + + dmxDnDLeaveMessage (screenInfo.screens[i], + dmxScreen->dndSource); + + dmxScreen->dndWid = None; + dmxScreen->dndSource = None; + } + } + } +} + +#define MAKE_DND_ATOM(name) \ + MakeAtom ("Xdnd" name, strlen ("Xdnd" name), TRUE) + +Bool +dmxDnDScreenInit (ScreenPtr pScreen) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + + dmxScreen->wmStateAtom = MakeAtom ("WM_STATE", strlen ("WM_STATE"), TRUE); + + dmxScreen->xdndProxyAtom = MAKE_DND_ATOM ("Proxy"); + dmxScreen->xdndAwareAtom = MAKE_DND_ATOM ("Aware"); + dmxScreen->xdndSelectionAtom = MAKE_DND_ATOM ("Selection"); + dmxScreen->xdndEnterAtom = MAKE_DND_ATOM ("Enter"); + dmxScreen->xdndPositionAtom = MAKE_DND_ATOM ("Position"); + dmxScreen->xdndStatusAtom = MAKE_DND_ATOM ("Status"); + dmxScreen->xdndLeaveAtom = MAKE_DND_ATOM ("Leave"); + dmxScreen->xdndDropAtom = MAKE_DND_ATOM ("Drop"); + dmxScreen->xdndFinishedAtom = MAKE_DND_ATOM ("Finished"); + dmxScreen->xdndTypeListAtom = MAKE_DND_ATOM ("TypeList"); + dmxScreen->xdndActionListAtom = MAKE_DND_ATOM ("ActionList"); + dmxScreen->xdndActionDescriptionAtom = MAKE_DND_ATOM ("ActionDescription"); + + dmxScreen->dndXPos = -1; + dmxScreen->dndYPos = -1; + + REGION_INIT (pScreen, &dmxScreen->dndBox, NullBox, 0); + + return TRUE; +} + +void +dmxDnDScreenFini (ScreenPtr pScreen) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + + REGION_UNINIT (pScreen, &dmxScreen->dndBox); +} diff --git a/hw/dmx/dmxdnd.h b/hw/dmx/dmxdnd.h new file mode 100644 index 000000000..538898d4a --- /dev/null +++ b/hw/dmx/dmxdnd.h @@ -0,0 +1,53 @@ +/* + * Copyright © 2008 Novell, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Novell, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior permission. + * Novell, Inc. makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN + * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: David Reveman + */ + +#ifndef DMXDND_H +#define DMXDND_H + +#include "dmx.h" + +void +dmxBEDnDRootWindowUpdate (ScreenPtr pScreen, + Window window); + +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); + +Bool +dmxDnDScreenInit (ScreenPtr pScreen); + +void +dmxDnDScreenFini (ScreenPtr pScreen); + +#endif /* DMXDND_H */ diff --git a/hw/dmx/dmxdpms.c b/hw/dmx/dmxdpms.c index f3a167dcf..0498cf444 100644 --- a/hw/dmx/dmxdpms.c +++ b/hw/dmx/dmxdpms.c @@ -58,14 +58,15 @@ static Bool dpmsSupported = TRUE; /** Initialize DPMS support. We save the current settings and turn off * DPMS. The settings are restored in #dmxDPMSTerm. */ -void dmxDPMSInit(DMXScreenInfo *dmxScreen) +void dmxBEDPMSScreenInit(ScreenPtr pScreen) { - int event_base, error_base; - int major, minor; - CARD16 level, standby, suspend, off; - BOOL state; - const char *monitor; - int status = 1; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + int event_base, error_base; + int major, minor; + CARD16 level, standby, suspend, off; + BOOL state; + const char *monitor; + int status = 1; if (dpmsGeneration != serverGeneration) { dpmsSupported = TRUE; /* On unless a backend doesn't support it */ @@ -145,8 +146,10 @@ void dmxDPMSInit(DMXScreenInfo *dmxScreen) /** Terminate DPMS support on \a dmxScreen. We restore the settings * saved in #dmxDPMSInit. */ -void dmxDPMSTerm(DMXScreenInfo *dmxScreen) +void dmxBEDPMSScreenFini(ScreenPtr pScreen) { + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + if (!dmxScreen->beDisplay) return; diff --git a/hw/dmx/dmxdpms.h b/hw/dmx/dmxdpms.h index e3eee983a..5be9a3943 100644 --- a/hw/dmx/dmxdpms.h +++ b/hw/dmx/dmxdpms.h @@ -36,7 +36,7 @@ #ifndef _DMXDPMS_H_ #define _DMXDPMS_H_ -extern void dmxDPMSInit(DMXScreenInfo *dmxScreen); -extern void dmxDPMSTerm(DMXScreenInfo *dmxScreen); +extern void dmxBEDPMSScreenInit(ScreenPtr pScreen); +extern void dmxBEDPMSScreenFini(ScreenPtr pScreen); extern void dmxDPMSWakeup(void); /* Call when input is processed */ #endif diff --git a/hw/dmx/dmxextension.c b/hw/dmx/dmxextension.c index 24b5f19d5..8f387a712 100644 --- a/hw/dmx/dmxextension.c +++ b/hw/dmx/dmxextension.c @@ -1609,60 +1609,8 @@ dmxEnableScreen (int idx) dmxScreen->beDisplay = dmxScreen->beAttachedDisplay; -#ifdef MITSHM - dmxScreen->beShm = dmxShmInit (pScreen); - if (dmxScreen->beShm) - { - dmxScreen->beShmEventBase = - XShmGetEventBase (dmxScreen->beDisplay); - dmxLogOutput (dmxScreen, "Using MIT-SHM extension\n"); - } -#endif - -#ifdef RANDR - dmxScreen->beRandr = FALSE; -#endif - - if (dmxScreen->scrnWin == DefaultRootWindow (dmxScreen->beDisplay)) - { - -#ifdef RANDR - int major, minor, status = 0; - - XLIB_PROLOGUE (dmxScreen); - status = XRRQueryVersion (dmxScreen->beDisplay, &major, &minor); - XLIB_EPILOGUE (dmxScreen); - - if (status) - { - if (major > 1 || (major == 1 && minor >= 2)) - { - int ignore; - - XLIB_PROLOGUE (dmxScreen); - dmxScreen->beRandr = - XRRQueryExtension (dmxScreen->beDisplay, - &dmxScreen->beRandrEventBase, - &ignore); - XLIB_EPILOGUE (dmxScreen); - - dmxLog (dmxInfo, "RandR 1.2 is present\n"); - } - else - { - dmxLog (dmxInfo, "RandR 1.2 is not present\n"); - } - } - else - { - dmxLog (dmxInfo, "RandR extension missing\n"); - } -#endif - - } - /* Initialize the BE screen resources */ - dmxBEScreenInit(idx, screenInfo.screens[idx]); + dmxBEScreenInit(screenInfo.screens[idx]); /* TODO: Handle GLX visual initialization. GLXProxy needs to be * updated to handle dynamic addition/removal of screens. */ diff --git a/hw/dmx/dmxinit.c b/hw/dmx/dmxinit.c index 56af57574..6cfbe0cc7 100644 --- a/hw/dmx/dmxinit.c +++ b/hw/dmx/dmxinit.c @@ -1051,6 +1051,10 @@ void InitOutput(ScreenInfo *pScreenInfo, int argc, char *argv[]) /* Initialized things that need timer hooks */ dmxStatInit(); dmxSyncInit(); /* Calls RegisterBlockAndWakeupHandlers */ + + for (i = 0; i < dmxNumScreens; i++) + if (dmxScreens[i].beDisplay) + dmxBEScreenInit (screenInfo.screens[i]); } /* RATS: Assuming the fp string (which comes from the command-line argv diff --git a/hw/dmx/dmxinput.c b/hw/dmx/dmxinput.c index b5a5fe267..ea4b31e37 100644 --- a/hw/dmx/dmxinput.c +++ b/hw/dmx/dmxinput.c @@ -1184,10 +1184,13 @@ dmxKeyboardOff (DeviceIntPtr pDevice) { dmxScreen->rootEventMask &= ~DMX_KEYBOARD_EVENT_MASK; - XLIB_PROLOGUE (dmxScreen); - XSelectInput (dmxScreen->beDisplay, dmxScreen->rootWin, - dmxScreen->rootEventMask); - XLIB_EPILOGUE (dmxScreen); + if (dmxScreen->scrnWin) + { + XLIB_PROLOGUE (dmxScreen); + XSelectInput (dmxScreen->beDisplay, dmxScreen->rootWin, + dmxScreen->rootEventMask); + XLIB_EPILOGUE (dmxScreen); + } } if (pDevPriv->keySyms.map) @@ -1336,10 +1339,13 @@ dmxPointerOff (DeviceIntPtr pDevice) { dmxScreen->rootEventMask &= ~DMX_POINTER_EVENT_MASK; - XLIB_PROLOGUE (dmxScreen); - XSelectInput (dmxScreen->beDisplay, dmxScreen->rootWin, - dmxScreen->rootEventMask); - XLIB_EPILOGUE (dmxScreen); + if (dmxScreen->scrnWin) + { + XLIB_PROLOGUE (dmxScreen); + XSelectInput (dmxScreen->beDisplay, dmxScreen->rootWin, + dmxScreen->rootEventMask); + XLIB_EPILOGUE (dmxScreen); + } } } diff --git a/hw/dmx/dmxprop.c b/hw/dmx/dmxprop.c index e37631e62..b856184de 100644 --- a/hw/dmx/dmxprop.c +++ b/hw/dmx/dmxprop.c @@ -71,46 +71,6 @@ #include "panoramiXsrv.h" #endif -/** Holds the window id of all DMX windows on the backend X server. */ -#define DMX_ATOMNAME "DMX_NAME" - -/** The identification string of this DMX server */ -#define DMX_IDENT "DMX" - -extern char *display; - -static const unsigned char *dmxPropertyIdentifier(void) -{ - /* RATS: These buffers are only used in - * length-limited calls. */ - char hostname[256]; - static char buf[128]; - static int initialized = 0; - - if (initialized++) return (unsigned char *)buf; - - XmuGetHostname(hostname, sizeof(hostname)); - XmuSnprintf(buf, sizeof(buf), "%s:%s:%s", DMX_IDENT, hostname, display); - return (unsigned char *)buf; -} - -void dmxPropertyWindow(DMXScreenInfo *dmxScreen, Window win) -{ - Atom atom; - const unsigned char *id = dmxPropertyIdentifier(); - Display *dpy = dmxScreen->beDisplay; - char buf[128]; /* RATS: only used with XmuSnprintf */ - - if (!dpy) - return; - - atom = XInternAtom(dpy, DMX_ATOMNAME, False); - - XmuSnprintf(buf, sizeof(buf), "%s,%d", id, dmxScreen->index); - XChangeProperty(dpy, win, atom, XA_STRING, 8, - PropModeReplace, (unsigned char *)buf, strlen(buf)); -} - static int (*dmxSaveProcVector[256]) (ClientPtr); static int diff --git a/hw/dmx/dmxprop.h b/hw/dmx/dmxprop.h index 6932bc1d5..5f800f436 100644 --- a/hw/dmx/dmxprop.h +++ b/hw/dmx/dmxprop.h @@ -36,7 +36,6 @@ #ifndef _DMXPROP_H_ #define _DMXPROP_H_ -extern void dmxPropertyWindow(DMXScreenInfo *dmxScreen, Window win); extern void dmxInitProps (void); extern void dmxResetProps (void); #endif diff --git a/hw/dmx/dmxrandr.c b/hw/dmx/dmxrandr.c index c033dba4c..e40c85013 100644 --- a/hw/dmx/dmxrandr.c +++ b/hw/dmx/dmxrandr.c @@ -1143,7 +1143,9 @@ dmxScreenEventCheckRR (ScreenPtr pScreen, DisplayHeight (dmxScreen->beDisplay, DefaultScreen (dmxScreen->beDisplay)); - RRGetInfo (screenInfo.screens[0]); + /* only call RRGetInfo when server is fully initialized */ + if (dmxScreens[0].selectionProxyWid[0]) + RRGetInfo (screenInfo.screens[0]); return TRUE; } @@ -1194,8 +1196,30 @@ dmxRRScreenInit (ScreenPtr pScreen) XRRScreenResources *r = NULL; DMXScreenInfo *dmxScreen = dmxScreens; Display *display = dmxScreen->beDisplay; + Bool beRandr = FALSE; - if (display && dmxScreens->beRandr) + if (display && dmxScreen->scrnWin == DefaultRootWindow (display)) + { + int major, minor, status = 0; + + XLIB_PROLOGUE (dmxScreen); + status = XRRQueryVersion (display, &major, &minor); + XLIB_EPILOGUE (dmxScreen); + + if (status) + { + if (major > 1 || (major == 1 && minor >= 2)) + { + int ignore; + + XLIB_PROLOGUE (dmxScreen); + beRandr = XRRQueryExtension (display, &ignore, &ignore); + XLIB_EPILOGUE (dmxScreen); + } + } + } + + if (display && beRandr) { XLIB_PROLOGUE (dmxScreens); r = XRRGetScreenResources (display, DefaultRootWindow (display)); @@ -1246,6 +1270,42 @@ Bool dmxBERRScreenInit (ScreenPtr pScreen) { DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + + dmxScreen->beRandr = FALSE; + + if (dmxScreen->scrnWin == DefaultRootWindow (dmxScreen->beDisplay)) + { + int major, minor, status = 0; + + XLIB_PROLOGUE (dmxScreen); + status = XRRQueryVersion (dmxScreen->beDisplay, &major, &minor); + XLIB_EPILOGUE (dmxScreen); + + if (status) + { + if (major > 1 || (major == 1 && minor >= 2)) + { + int ignore; + + XLIB_PROLOGUE (dmxScreen); + dmxScreen->beRandr = + XRRQueryExtension (dmxScreen->beDisplay, + &dmxScreen->beRandrEventBase, + &ignore); + XLIB_EPILOGUE (dmxScreen); + + dmxLog (dmxInfo, "RandR 1.2 is present\n"); + } + else + { + dmxLog (dmxInfo, "RandR 1.2 is not present\n"); + } + } + else + { + dmxLog (dmxInfo, "RandR extension missing\n"); + } + } if (!dmxScreen->beRandr) return FALSE; diff --git a/hw/dmx/dmxscrinit.c b/hw/dmx/dmxscrinit.c index ba5c097db..a6cff0807 100644 --- a/hw/dmx/dmxscrinit.c +++ b/hw/dmx/dmxscrinit.c @@ -59,6 +59,7 @@ #include "dmxselection.h" #include "dmxatom.h" #include "dmxshm.h" +#include "dmxdnd.h" #ifdef PANORAMIX #include "panoramiX.h" @@ -116,9 +117,9 @@ DevPrivateKey dmxGlyphPrivateKey = &dmxGlyphPrivateKeyIndex; /**< Private index /** Initialize the parts of screen \a idx that require access to the * back-end server. */ -void dmxBEScreenInit(int idx, ScreenPtr pScreen) +void dmxBEScreenInit(ScreenPtr pScreen) { - DMXScreenInfo *dmxScreen = &dmxScreens[idx]; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; char buf[256]; int i, j; @@ -139,14 +140,20 @@ 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); + + XLIB_PROLOGUE (dmxScreens); + dmxScreen->beSelectionAtom = XInternAtom (dmxScreen->beDisplay, buf, 0); + XLIB_EPILOGUE (dmxScreen); /* Handle screen savers and DPMS on the backend */ - dmxDPMSInit(dmxScreen); + dmxBEDPMSScreenInit (pScreen); + +#ifdef MITSHM + dmxBEShmScreenInit (pScreen); +#endif #ifdef RANDR dmxBERRScreenInit (pScreen); @@ -162,9 +169,11 @@ void dmxBEScreenInit(int idx, ScreenPtr pScreen) if ((dmxScreen->bePixmapFormats[i].depth == 1) || (dmxScreen->bePixmapFormats[i].depth == dmxScreen->beDepths[j])) { + XLIB_PROLOGUE (dmxScreens); dmxScreen->scrnDefDrawables[i] = (Drawable) XCreatePixmap(dmxScreen->beDisplay, dmxScreen->scrnWin, 1, 1, dmxScreen->bePixmapFormats[i].depth); + XLIB_EPILOGUE (dmxScreen); break; } } @@ -220,7 +229,7 @@ dmxScreenGetSelectionOwner (ScreenPtr pScreen) while (dmxScreen->selectionOwner == None) { xcb_connection_t *c = dmxScreen->connection; - xcb_atom_t a = dmxScreen->selectionAtom; + xcb_atom_t a = dmxScreen->beSelectionAtom; xcb_get_selection_owner_reply_t *reply; reply = xcb_get_selection_owner_reply (c, @@ -263,7 +272,7 @@ dmxScreenGetSelectionOwner (ScreenPtr pScreen) { xcb_set_selection_owner (dmxScreen->connection, dmxScreen->rootWin, - dmxScreen->selectionAtom, + dmxScreen->beSelectionAtom, 0); } @@ -305,7 +314,7 @@ dmxScreenEventCheckSelection (ScreenPtr pScreen, xcb_selection_clear_event_t *xclear = (xcb_selection_clear_event_t *) event; - if (xclear->selection == dmxScreen->selectionAtom) + if (xclear->selection == dmxScreen->beSelectionAtom) { dmxScreenGetSelectionOwner (pScreen); } @@ -850,6 +859,7 @@ dmxBEDispatch (ScreenPtr pScreen) { if (!dmxScreenEventCheckInput (pScreen, event) && !dmxScreenEventCheckSelection (pScreen, event) && + !dmxScreenEventCheckDnD (pScreen, event) && !dmxScreenEventCheckOutputWindow (pScreen, event) && !dmxScreenEventCheckManageRoot (pScreen, event) && !dmxScreenEventCheckExpose (pScreen, event) && @@ -902,7 +912,8 @@ dmxBEDispatch (ScreenPtr pScreen) if (!dmxScreenReplyCheckSync (pScreen, head->sequence, rep) && !dmxScreenReplyCheckInput (pScreen, head->sequence, rep) && - !dmxScreenReplyCheckSelection (pScreen, head->sequence, rep)) + !dmxScreenReplyCheckSelection (pScreen, head->sequence, rep) && + !dmxScreenReplyCheckDnD (pScreen, head->sequence, rep)) { /* error response */ if (rep->response_type == 0) @@ -940,6 +951,9 @@ dmxBEDispatch (ScreenPtr pScreen) dmxScreenReplyCheckSelection (pScreen, head->sequence, (xcb_generic_reply_t *) &detached_error); + dmxScreenReplyCheckDnD (pScreen, head->sequence, + (xcb_generic_reply_t *) + &detached_error); } dmxScreen->broken = TRUE; @@ -1069,15 +1083,6 @@ Bool dmxScreenInit(int idx, ScreenPtr pScreen, int argc, char *argv[]) dmxScreen->incrAtom = MakeAtom ("INCR", strlen ("INCR"), TRUE); -#ifdef MITSHM - dmxScreen->beShm = FALSE; -#endif - -#ifdef RANDR - dmxScreen->beRandr = FALSE; - dmxScreen->beRandrPending = FALSE; -#endif - if (!dmxInitGC(pScreen)) return FALSE; if (!dmxInitWindow(pScreen)) return FALSE; if (!dmxInitPixmap(pScreen)) return FALSE; @@ -1090,7 +1095,7 @@ Bool dmxScreenInit(int idx, ScreenPtr pScreen, int argc, char *argv[]) * Maybe a miAddVisualTypeAndMask() function will be added to make * things easier here. */ - if (dmxScreen->beDisplay) + if (dmxScreen->beAttachedDisplay) { for (i = 0; i < dmxScreen->beNumDepths; i++) { int depth; @@ -1198,13 +1203,6 @@ Bool dmxScreenInit(int idx, ScreenPtr pScreen, int argc, char *argv[]) #ifdef MITSHM ShmRegisterDmxFuncs (pScreen); - dmxScreen->beShm = dmxShmInit (pScreen); - if (dmxScreen->beShm) - { - dmxScreen->beShmEventBase = - XShmGetEventBase (dmxScreen->beDisplay); - dmxLogOutput (dmxScreen, "Using MIT-SHM extension\n"); - } #endif #ifdef PANORAMIX @@ -1217,35 +1215,11 @@ Bool dmxScreenInit(int idx, ScreenPtr pScreen, int argc, char *argv[]) #endif #ifdef RENDER - (void)dmxPictureInit(pScreen, 0, 0); + if (!dmxPictureInit (pScreen, 0, 0)) + return FALSE; #endif #ifdef RANDR - if (dmxScreen->beDisplay && - dmxScreen->scrnWin == DefaultRootWindow (dmxScreen->beDisplay)) - { - int major, minor, status = 0; - - XLIB_PROLOGUE (dmxScreen); - status = XRRQueryVersion (dmxScreen->beDisplay, &major, &minor); - XLIB_EPILOGUE (dmxScreen); - - if (status) - { - if (major > 1 || (major == 1 && minor >= 2)) - { - int ignore; - - XLIB_PROLOGUE (dmxScreen); - dmxScreen->beRandr = - XRRQueryExtension (dmxScreen->beDisplay, - &dmxScreen->beRandrEventBase, - &ignore); - XLIB_EPILOGUE (dmxScreen); - } - } - } - if (!dmxRRScreenInit (pScreen)) return FALSE; #endif @@ -1255,6 +1229,9 @@ Bool dmxScreenInit(int idx, ScreenPtr pScreen, int argc, char *argv[]) return FALSE; #endif + if (!dmxDnDScreenInit (pScreen)) + return FALSE; + miInitializeBackingStore(pScreen); MAXSCREENSALLOC(dmxCursorGeneration); @@ -1271,9 +1248,6 @@ Bool dmxScreenInit(int idx, ScreenPtr pScreen, int argc, char *argv[]) DMX_WRAP(CloseScreen, dmxCloseScreen, dmxScreen, pScreen); DMX_WRAP(SaveScreen, dmxSaveScreen, dmxScreen, pScreen); - if (dmxScreen->beDisplay) - dmxBEScreenInit(idx, pScreen); - /* Wrap GC functions */ DMX_WRAP(CreateGC, dmxCreateGC, dmxScreen, pScreen); @@ -1336,8 +1310,16 @@ void dmxBECloseScreen(ScreenPtr pScreen) DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; int i; +#ifdef XV + dmxBEXvScreenFini (pScreen); +#endif + +#ifdef RANDR + dmxBERRScreenFini (pScreen); +#endif + /* Restore the back-end screen-saver and DPMS state. */ - dmxDPMSTerm(dmxScreen); + dmxBEDPMSScreenFini (pScreen); /* Free the screen resources */ dmxScreen->scrnWin = (Window)0; diff --git a/hw/dmx/dmxscrinit.h b/hw/dmx/dmxscrinit.h index 8ba05a63c..d92dd4064 100644 --- a/hw/dmx/dmxscrinit.h +++ b/hw/dmx/dmxscrinit.h @@ -45,7 +45,7 @@ extern DevPrivateKey dmxScreenPrivateKey; extern Bool dmxScreenInit(int idx, ScreenPtr pScreen, int argc, char *argv[]); -extern void dmxBEScreenInit(int idx, ScreenPtr pScreen); +extern void dmxBEScreenInit(ScreenPtr pScreen); extern void dmxBECloseScreen(ScreenPtr pScreen); extern void dmxBEDispatch (ScreenPtr pScreen); diff --git a/hw/dmx/dmxselection.c b/hw/dmx/dmxselection.c index 964f84138..ec3ce6758 100644 --- a/hw/dmx/dmxselection.c +++ b/hw/dmx/dmxselection.c @@ -33,6 +33,7 @@ #include "dmxwindow.h" #include "dmxscrinit.h" #include "dmxsync.h" +#include "dmxdnd.h" #include "dmxselection.h" #include "selection.h" @@ -549,7 +550,7 @@ dmxSelectionPropertyNotify (ScreenPtr pScreen, if (s) { WindowPtr pWin; - + if (dixLookupWindow (&pWin, s->wid, serverClient, @@ -801,7 +802,7 @@ dmxSelectionRequest (ScreenPtr pScreen, } else { - /* TODO: wait for proxy window to become availble */ + /* TODO: wait for proxy window to become available */ dmxLog (dmxWarning, "dmxSelectionRequest: no proxy window available " "for conversion of %s selection\n", @@ -1123,7 +1124,7 @@ dmxProcConvertSelection (ClientPtr client) if (!s) return BadAlloc; - s->wid = stuff->requestor; + s->wid = 0; s->requestor = 0; s->selection = stuff->selection; s->target = stuff->target; @@ -1197,6 +1198,8 @@ dmxProcConvertSelection (ClientPtr client) if (j < dmxNumScreens) { + s->wid = stuff->requestor; + dmxAppendSelection (s, &convTail); return client->noClientException; @@ -1222,37 +1225,39 @@ dmxProcSendEvent (ClientPtr client) REQUEST(xSendEventReq); REQUEST_SIZE_MATCH(xSendEventReq); - if (stuff->event.u.u.type == SelectionNotify && - stuff->eventMask == NoEventMask && - stuff->destination != PointerWindow && - stuff->destination != InputFocus) + if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue)) { - Atom property = stuff->event.u.selectionNotify.property; - Atom target = stuff->event.u.selectionNotify.target; - DMXSelection *s; + client->errorValue = stuff->propagate; + return BadValue; + } - if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue)) + switch (stuff->event.u.u.type) { + case SelectionNotify: + if (stuff->eventMask == NoEventMask && + stuff->destination != PointerWindow && + stuff->destination != InputFocus) { - client->errorValue = stuff->propagate; - return BadValue; - } + Atom property = stuff->event.u.selectionNotify.property; + Atom target = stuff->event.u.selectionNotify.target; + DMXSelection *s; - for (s = reqHead; s; s = s->next) - if (s->wid == stuff->destination && - s->selection == stuff->event.u.selectionNotify.selection) - break; + for (s = reqHead; s; s = s->next) + if (s->wid == stuff->destination && + s->selection == stuff->event.u.selectionNotify.selection) + break; - if (s) - { - int i; - - for (i = 0; i < dmxNumScreens; i++) + if (s) { - if (s->value[i].out) + int i; + + for (i = 0; i < dmxNumScreens; i++) { xcb_selection_notify_event_t xevent; DMXScreenInfo *dmxScreen = &dmxScreens[i]; + if (!s->value[i].out) + continue; + xevent.response_type = XCB_SELECTION_NOTIFY; xevent.pad0 = 0; xevent.sequence = 0; @@ -1297,18 +1302,32 @@ dmxProcSendEvent (ClientPtr client) &reqHead, &reqTail)); - return Success; + return client->noClientException; } - } - s->property = property; - if (property == dmxScreens[0].incrAtom) - dmxSelectionResetTimer (s); - else - dmxSelectionDeleteReq (dmxUnhookSelection (s, - &reqHead, - &reqTail)); + s->property = property; + if (property == dmxScreens[0].incrAtom) + dmxSelectionResetTimer (s); + else + dmxSelectionDeleteReq (dmxUnhookSelection (s, + &reqHead, + &reqTail)); + } } + break; + case ClientMessage: + if (stuff->event.u.u.detail != 8 && + stuff->event.u.u.detail != 16 && + stuff->event.u.u.detail != 32) + { + client->errorValue = stuff->event.u.u.detail; + return BadValue; + } + + if (stuff->destination == dmxScreens[0].selectionProxyWid[0]) + dmxDnDClientMessageEvent (&stuff->event); + + break; } return (*dmxSaveProcVector[X_SendEvent]) (client); diff --git a/hw/dmx/dmxshm.c b/hw/dmx/dmxshm.c index f16ec7f51..17c6ceece 100644 --- a/hw/dmx/dmxshm.c +++ b/hw/dmx/dmxshm.c @@ -33,6 +33,7 @@ #include "dmxwindow.h" #include "dmxpixmap.h" #include "dmxsync.h" +#include "dmxlog.h" #include "scrnintstr.h" #include "servermd.h" #include "shmint.h" @@ -229,10 +230,7 @@ dmxScreenEventCheckShm (ScreenPtr pScreen, } else { - xcb_generic_error_t *error = (xcb_generic_error_t *) event; - - if (event->pad0 != DMX_DETACHED) - sequence = error->sequence; + sequence = ((xcb_generic_error_t *) event)->sequence; } for (pShmInfo = shmSegs; pShmInfo; pShmInfo = pShmInfo->next) @@ -604,8 +602,8 @@ dmxProcShmPutImage (ClientPtr client) return (client->noClientException); } -Bool -dmxShmInit (ScreenPtr pScreen) +void +dmxBEShmScreenInit (ScreenPtr pScreen) { DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; xcb_generic_error_t *error; @@ -620,18 +618,17 @@ dmxShmInit (ScreenPtr pScreen) unsigned long mask; int i; - if (!dmxScreen->beDisplay) - return FALSE; + dmxScreen->beShm = FALSE; shmid = shmget (IPC_PRIVATE, sizeof (key), IPC_CREAT | 0600); if (shmid == -1) - return FALSE; + return; shmaddr = shmat (shmid, NULL, 0); if (shmaddr == (char *) -1) { shmctl (shmid, IPC_RMID, NULL); - return FALSE; + return; } memset (shmaddr, 0, sizeof (key)); @@ -647,7 +644,7 @@ dmxShmInit (ScreenPtr pScreen) free (error); shmdt (shmaddr); shmctl (shmid, IPC_RMID, NULL); - return FALSE; + return; } mask = (GCFunction | GCPlaneMask | GCClipMask | GCGraphicsExposures); @@ -700,7 +697,7 @@ dmxShmInit (ScreenPtr pScreen) xcb_shm_detach (dmxScreen->connection, shmseg); shmdt (shmaddr); shmctl (shmid, IPC_RMID, NULL); - return FALSE; + return; } free (reply); @@ -714,9 +711,11 @@ dmxShmInit (ScreenPtr pScreen) shmctl (shmid, IPC_RMID, NULL); if (i < sizeof (key)) - return FALSE; + return; - return TRUE; + dmxScreen->beShm = TRUE; + dmxScreen->beShmEventBase = XShmGetEventBase (dmxScreen->beDisplay); + dmxLogOutput (dmxScreen, "Using MIT-SHM extension\n"); } void dmxInitShm (void) diff --git a/hw/dmx/dmxshm.h b/hw/dmx/dmxshm.h index 611b1eddd..69577f083 100644 --- a/hw/dmx/dmxshm.h +++ b/hw/dmx/dmxshm.h @@ -53,7 +53,7 @@ extern void dmxBEDetachShmSeg (DMXScreenInfo *dmxScreen, extern Bool dmxScreenEventCheckShm (ScreenPtr pScreen, xcb_generic_event_t *event); -extern Bool dmxShmInit (ScreenPtr pScreen); +extern void dmxBEShmScreenInit (ScreenPtr pScreen); extern void dmxInitShm (void); extern void dmxResetShm (void); diff --git a/hw/dmx/dmxwindow.c b/hw/dmx/dmxwindow.c index 1dcbd4a30..4e06fea13 100644 --- a/hw/dmx/dmxwindow.c +++ b/hw/dmx/dmxwindow.c @@ -52,6 +52,7 @@ #include "dmxatom.h" #include "dmxprop.h" #include "dmxselection.h" +#include "dmxdnd.h" #ifdef RENDER #include "dmxpict.h" #endif @@ -150,9 +151,15 @@ Window dmxCreateRootWindow(WindowPtr pWindow) visual, mask, &attribs); + XChangeProperty (dmxScreen->beDisplay, win, + XInternAtom (dmxScreen->beDisplay, "DMX_NAME", False), + XA_STRING, 8, + PropModeReplace, + (unsigned char *) dmxDigest, + strlen (dmxDigest)); XLIB_EPILOGUE (dmxScreen); - dmxPropertyWindow (dmxScreen, win); + dmxBEDnDRootWindowUpdate (pWindow->drawable.pScreen, win); return win; }