diff --git a/hw/xnest/Events.c b/hw/xnest/Events.c index cf6eebd0a..a0db9db1c 100644 --- a/hw/xnest/Events.c +++ b/hw/xnest/Events.c @@ -39,6 +39,7 @@ #include "Display.h" #include "Screen.h" #include "XNWindow.h" +#include "WindowFuncs.h" #include "Events.h" #include "Keyboard.h" #include "mipointer.h" @@ -94,17 +95,22 @@ void xnestHandleEvent(XCBGenericEvent *e) XCBButtonReleaseEvent *bre; XCBReparentNotifyEvent *ev_reparent; XCBCreateNotifyEvent *ev_create; - XCBGetGeometryCookie gcook; - XCBGetGeometryRep *grep; + XCBMapNotifyEvent *ev_map; + XCBUnmapNotifyEvent *ev_unmap; + XCBConfigureWindowReq cfg_req; CARD32 ev_mask; + CARD32 cfg_mask; + CARD32 cfg_data[7]; xEvent ev; ScreenPtr pScreen; WindowPtr pWin; WindowPtr pSib; WindowPtr pParent; + WindowPtr pPrev; RegionRec Rgn; BoxRec Box; lastEventTime = GetTimeInMillis(); + int i = 0; switch (e->response_type & ~0x80) { case XCBKeyPress: @@ -149,7 +155,7 @@ void xnestHandleEvent(XCBGenericEvent *e) mieqEnqueue(&x); #endif pev = (XCBMotionNotifyEvent *)e; - miPointerAbsoluteCursor (pev->event_x, pev->event_y, lastEventTime = GetTimeInMillis()); + miPointerAbsoluteCursor (pev->root_x, pev->root_y, lastEventTime = GetTimeInMillis()); break; case XCBFocusIn: @@ -225,25 +231,25 @@ void xnestHandleEvent(XCBGenericEvent *e) case XCBConfigureNotify: cev = (XCBConfigureNotifyEvent *)e; - pWin = xnestWindowPtr(cev->window); - if (xnestWindowPriv(pWin)->owner == XSCREEN_OWNED_XSCREEN) { - pScreen = pWin->drawable.pScreen; - pSib = xnestWindowPtr(cev->above_sibling); - cev->event = xnestWindow(xnestWindowPtr(cev->event)); - cev->window = xnestWindow(xnestWindowPtr(cev->window)); - if (pSib) - cev->above_sibling = xnestWindow(pSib); - memcpy(&ev, cev, sizeof(XCBGenericEvent)); - DeliverEvents(pWin, &ev, 1, NULL); - } - pWin->origin.x = pWin->drawable.x + wBorderWidth(pWin) + cev->x; - pWin->origin.y = pWin->drawable.y + wBorderWidth(pWin) + cev->y; - pWin->drawable.height = cev->height; - pWin->drawable.width = cev->width; - ErrorF("drawable->x: %d, drawable->y: %d, origin->x: %d, origin->y: %d\n", - pWin->drawable.x, pWin->drawable.y, pWin->origin.x, pWin->origin.y); - break; - + pWin = xnestWindowPtr(cev->event); + pSib = xnestWindowPtr(cev->above_sibling); + pParent = pWin->parent; + pScreen = pWin->drawable.pScreen; + + cfg_mask = (1<<7)-1; + cfg_data[i++] = cev->x; + cfg_data[i++] = cev->y; + cfg_data[i++] = cev->width; + cfg_data[i++] = cev->height; + cfg_data[i++] = cev->border_width; + if (pSib) + cfg_data[i++] = pSib ? xnestWindow(pSib).xid : 0; + else + cfg_mask &= ~XCBConfigWindowSibling; + /*FIXME! WTF do I do for this??*/ + cfg_data[i++] = 0; + ConfigureWindow(pWin, cfg_mask, cfg_data, wClient(pWin)); + break; case XCBReparentNotify: /*Reparent windows. This is to track non-xscreen managed windows and their * relationship to xscreen managed windows. It should be harmless to poke at @@ -252,7 +258,11 @@ void xnestHandleEvent(XCBGenericEvent *e) ev_reparent = (XCBReparentNotifyEvent *)e; pParent = xnestWindowPtr(ev_reparent->parent); pWin = xnestWindowPtr(ev_reparent->window); - ReparentWindow(pWin, pParent, ev_reparent->x, ev_reparent->y, wClient(pWin)); + + DBG_xnestListWindows(XCBSetupRootsIter (XCBGetSetup (xnestConnection)).data->root); + ErrorF("Reparenting %d to %d\n", (int) ev_reparent->window.xid, (int)ev_reparent->parent.xid); + /*we'll assume the root can't be reparented, and as such, pParent is _always_ valid*/ + xnestReparentWindow(pWin, pParent, ev_reparent->x, ev_reparent->y, wClient(pWin)); break; case XCBCreateNotify: @@ -261,52 +271,46 @@ void xnestHandleEvent(XCBGenericEvent *e) /*make sure we didn't create this window. If we did, ignore it, we already track it*/ pWin = xnestWindowPtr(ev_create->window); if (!pWin) { - gcook = XCBGetGeometry(xnestConnection, (XCBDRAWABLE)ev_create->window); + ErrorF("Adding new window\n"); - pWin = AllocateWindow(pScreen); + pWin = xnestTrackWindow(ev_create->window, + pParent, /*parent WindowPtr*/ + ev_create->x, ev_create->y, /*x, y*/ + ev_create->width, ev_create->height,/*w, h*/ + ev_create->border_width); + if (!pWin) { + ErrorF("AAGGHH! NULL WINDOW IN CREATE! SEPPUKU!"); + exit(1); + } + xnestInsertWindow(pWin, pParent); - xnestWindowPriv(pWin)->window = ev_create->window; - xnestWindowPriv(pWin)->sibling_above = (XCBWINDOW){0}; - xnestWindowPriv(pWin)->owner = XSCREEN_OWNED_BACKING; - - pWin->parent = pParent; - - grep = XCBGetGeometryReply(xnestConnection, gcook, NULL); - pWin->origin.x = grep->x; - pWin->origin.y = grep->y; - pWin->drawable.width = grep->width; - pWin->drawable.height = grep->height; - wClient(pWin) = serverClient; - pWin->drawable.id = FakeClientID(0); - - pWin->firstChild = NULL; - pWin->lastChild = NULL; - pWin->prevSib = NULL; - pWin->optional = NULL; - pWin->valdata = NULL; - - REGION_NULL(pScreen, &pWin->winSize); - REGION_NULL(pScreen, &pWin->borderSize); - REGION_NULL(pScreen, &pWin->clipList); - REGION_NULL(pScreen, &pWin->borderClip); - - /*set drawable relative to parent. FIXME: is this correct?*/ - pWin->drawable.x = pWin->origin.x - pWin->parent->origin.x + wBorderWidth(pWin); - pWin->drawable.y = pWin->origin.y - pWin->parent->origin.y + wBorderWidth(pWin); - ev_mask = XCBEventMaskSubstructureNotify|XCBEventMaskStructureNotify; + ev_mask = XCBEventMaskStructureNotify; XCBChangeWindowAttributes(xnestConnection, ev_create->window, XCBCWEventMask, &ev_mask); - } + } + ErrorF("-- Added win %d\n", (int)pWin->drawable.id); break; - case XCBNoExposure: case XCBGraphicsExposure: case XCBCirculateNotify: case XCBGravityNotify: +#if 0 case XCBMapNotify: + ev_map = (XCBMapNotifyEvent *)e; + pWin = xnestWindowPtr(ev_map->window); + pWin->mapped = 1; + //if (!pWin->mapped) + // MapWindow(pWin, wClient(pWin)); + break; case XCBUnmapNotify: - // break; + ev_unmap = (XCBUnmapNotifyEvent *)e; + pWin = xnestWindowPtr(ev_unmap->window); + // if (pWin->mapped) + // UnmapWindow(pWin, ev_unmap->from_configure); + pWin->mapped = 0; + break; +#endif default: ErrorF("****xnest warning: unhandled event %d\n", e->response_type & ~0x80); ErrorF("****Sequence number: %d\n", e->sequence); @@ -329,7 +333,6 @@ void xnestCollectEvents() ErrorF("****** File: %s Error: %d, Sequence %d\n", __FILE__, err->error_code, err->sequence); } else { - ErrorF("Handling event %x(%d) serial %d\n", e->response_type, e->response_type, e->sequence); xnestHandleEvent(e); } } diff --git a/hw/xnest/Events.h b/hw/xnest/Events.h index c61b26c0d..cda93c559 100644 --- a/hw/xnest/Events.h +++ b/hw/xnest/Events.h @@ -24,6 +24,7 @@ is" without express or implied warranty. extern CARD32 lastEventTime; void SetTimeSinceLastInputEvent(void); +void xnestHandleEvent(XCBGenericEvent *e); void xnestCollectExposures(void); void xnestCollectEvents(void); void xnestQueueKeyEvent(int type, unsigned int keycode); diff --git a/hw/xnest/GCOps.c b/hw/xnest/GCOps.c index 362ed1e47..85a1edcc9 100644 --- a/hw/xnest/GCOps.c +++ b/hw/xnest/GCOps.c @@ -34,6 +34,7 @@ #include "Xnest.h" #include "Display.h" +#include "Events.h" #include "Screen.h" #include "XNGC.h" #include "XNFont.h" diff --git a/hw/xnest/Makefile.am b/hw/xnest/Makefile.am index 37a76480e..bca1d9e21 100644 --- a/hw/xnest/Makefile.am +++ b/hw/xnest/Makefile.am @@ -30,6 +30,8 @@ SRCS = Args.c \ Visual.c \ Visual.h \ Window.c \ + WindowFuncs.h \ + WindowFuncs.c \ XNCursor.h \ Xnest.h \ XNFont.h \ diff --git a/hw/xnest/Window.c b/hw/xnest/Window.c index 09c34dc1b..2b158b3e2 100644 --- a/hw/xnest/Window.c +++ b/hw/xnest/Window.c @@ -110,67 +110,22 @@ static void xscreenInitBackingWindows(XCBConnection *c, WindowPtr pParent) /*if we're not already tracking this one*/ pWin = xnestWindowPtr(child[i]); if (!pWin) { + ErrorF("Adding window %d\n", child[i]); gcook = XCBGetGeometry(c, (XCBDRAWABLE)child[i]); - - pWin = AllocateWindow(pScreen); - - pWin->firstChild = NULL; - pWin->lastChild = NULL; - pWin->prevSib = NULL; - pWin->optional = NULL; - pWin->valdata = NULL; - pWin->parent = xnestWindowPtr(w); - wClient(pWin) = serverClient; - pWin->drawable.id = FakeClientID(0); - - REGION_NULL(pScreen, &pWin->winSize); - REGION_NULL(pScreen, &pWin->borderSize); - REGION_NULL(pScreen, &pWin->clipList); - REGION_NULL(pScreen, &pWin->borderClip); - - xnestWindowPriv(pWin)->window = child[i]; - xnestWindowPriv(pWin)->parent = w; - xnestWindowPriv(pWin)->sibling_above = (i>0) ? child[i-1] : (XCBWINDOW){0}; - xnestWindowPriv(pWin)->owner = XSCREEN_OWNED_BACKING; - - grep = XCBGetGeometryReply(c, gcook, NULL); - pWin->origin.x = grep->x; - pWin->origin.y = grep->y; - pWin->drawable.width = grep->width; - pWin->drawable.height = grep->height; - if (pWin->parent) { - /*set drawable relative to parent. FIXME: is this correct?*/ - pWin->drawable.x = pWin->origin.x - pWin->parent->origin.x + wBorderWidth(pWin); - pWin->drawable.y = pWin->origin.y - pWin->parent->origin.y + wBorderWidth(pWin); - } else { - /*root window*/ - pWin->drawable.x = pWin->origin.x; - pWin->drawable.y = pWin->origin.y; - } + pWin = xnestTrackWindow(child[i], pParent, grep->x, grep->y, grep->width, grep->height, grep->border_width); + /*listen to events on the new window*/ - ev_mask = XCBEventMaskSubstructureNotify|XCBEventMaskStructureNotify; + ev_mask = XCBEventMaskSubstructureNotify|XCBEventMaskStructureNotify;; XCBChangeWindowAttributes(xnestConnection, child[i], XCBCWEventMask, &ev_mask); + } else { + ErrorF("Skipping %d\n", child[i]); } - /** - * append the window into the list. - * NB: This reorders the WindowPtrs for windows we created in Xscreen. - * IS THIS RIGHT?!? - **/ - if (!pParent->firstChild) - pParent->firstChild = pWin; - if (pPrev) - pPrev->nextSib = pWin; - pParent->lastChild = pWin; - pWin->prevSib = pPrev; - /*this is the last sibling in the list*/ - pWin->nextSib = NULL; - pPrev = pWin; + xnestInsertWindow(pWin, pParent); /*and recurse, adding this window's children*/ xscreenInitBackingWindows(c, pWin); - /*FIXME: insert the window into the stack*/ } } @@ -187,9 +142,13 @@ Bool xnestCreateWindow(WindowPtr pWin) * we just set it's XID to the backing server's root.*/ screen = XCBSetupRootsIter (XCBGetSetup (xnestConnection)).data; if (xnestIsRoot(pWin)) { + ErrorF("Created Window\n"); xnestWindowPriv(pWin)->window = screen->root; + mask = XCBEventMaskSubstructureNotify|XCBEventMaskPointerMotion; + XCBChangeWindowAttributes(xnestConnection, screen->root, XCBCWEventMask, &mask); /*now that we've created the root window, we can do the backing windows*/ xscreenInitBackingWindows(xnestConnection, pWin); + ErrorF("Root window: %d\n", screen->root); return True; } diff --git a/hw/xnest/WindowFuncs.c b/hw/xnest/WindowFuncs.c new file mode 100644 index 000000000..cdda1d138 --- /dev/null +++ b/hw/xnest/WindowFuncs.c @@ -0,0 +1,290 @@ +/* $Xorg: Events.c,v 1.3 2000/08/17 19:53:28 cpqbld Exp $ */ +/* + + Copyright 2006 by Ori Bernstein + + 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. Davor Matic makes no representations about + the suitability of this software for any purpose. It is provided "as + is" without express or implied warranty. + +*/ +#ifdef HAVE_XNEST_CONFIG_H +#include +#endif + +#include +#include +#define NEED_EVENTS +#include +#include "screenint.h" +#include "input.h" +#include "misc.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "servermd.h" + +#include "mi.h" +#include "dix.h" +#include "Args.h" +#include "Color.h" +#include "Display.h" +#include "Screen.h" +#include "XNWindow.h" +#include "WindowFuncs.h" +#include "Events.h" +#include "Keyboard.h" +#include "mipointer.h" + +void DBG_xnestListWindows(XCBWINDOW w) +{ + XCBWINDOW *child; + WindowPtr pWin; + XCBQueryTreeCookie qcook; + XCBQueryTreeRep *qrep; + static int splvl = 0; + int i,j; + + + /*FIXME: THIS IS WRONG! How do I get the screen? + * No issue though, so far, since I only work with one screen. + * pScreen = xnestScreen(w); + */ + qcook = XCBQueryTree(xnestConnection, w); + qrep = XCBQueryTreeReply(xnestConnection, qcook, NULL); + child = XCBQueryTreeChildren(qrep); + /* Walk through the windows, initializing the privates. + * FIXME: initialize x, y, and pWin contents.. how? */ + for (i=0; i < qrep->children_len; i++){ + /*if we're not already tracking this one*/ + pWin = xnestWindowPtr(child[i]); + for (j=0; jCreateWindow(). + * + * This function is used to set up a window that's already been created + * on the backing server, which means I don't want to actually _create_ it. + **/ +WindowPtr xnestTrackWindow(XCBWINDOW w, WindowPtr pParent, int x, int y, int width, int height, int bw) +{ + WindowPtr pWin; + ScreenPtr pScreen; + + pWin = xnestWindowPtr(w); + if (pWin && xnestIsRoot(pWin)) + ErrorF("ASDFASDFLKASDJFLKASDJFLKJADSLKJASD"); + + pWin = AllocateWindow(pParent->drawable.pScreen); + if (!pWin) { + ErrorF("Unable to allocate window (out of RAM?)\n"); + return NULL; + } + pWin->prevSib = NullWindow; + pWin->firstChild = NullWindow; + pWin->lastChild = NullWindow; + + pWin->valdata = (ValidatePtr)NULL; + pWin->optional = (WindowOptPtr)NULL; + pWin->cursorIsNone = TRUE; + + pWin->backingStore = NotUseful; + pWin->DIXsaveUnder = FALSE; + pWin->backStorage = (pointer) NULL; + + pWin->mapped = FALSE; /* off */ + pWin->realized = FALSE; /* off */ + pWin->viewable = FALSE; + pWin->visibility = VisibilityNotViewable; + pWin->overrideRedirect = FALSE; + pWin->saveUnder = FALSE; + + pWin->bitGravity = ForgetGravity; + pWin->winGravity = NorthWestGravity; + + pWin->eventMask = 0; + pWin->deliverableEvents = 0; + pWin->dontPropagate = 0; + pWin->forcedBS = FALSE; +#ifdef NEED_DBE_BUF_BITS + pWin->srcBuffer = DBE_FRONT_BUFFER; + pWin->dstBuffer = DBE_FRONT_BUFFER; +#endif +#ifdef COMPOSITE + pWin->redirectDraw = 0; +#endif + + pWin->parent = pParent; + pWin->drawable = pParent->drawable; + + pWin->origin.x = x + bw; + pWin->origin.y = y + bw; + pWin->drawable.width = width; + pWin->drawable.height = height; + pWin->drawable.x = pParent->drawable.x + x + bw; + pWin->drawable.y = pParent->drawable.y + y + bw; + pWin->drawable.type = DRAWABLE_WINDOW; + pWin->drawable.width = width; + pWin->drawable.height = height; + pWin->backingStore = NotUseful; + pWin->backStorage = NULL; + pWin->backgroundState = 0; + + xnestWindowPriv(pWin)->window = w; + xnestWindowPriv(pWin)->x = pWin->drawable.x; + xnestWindowPriv(pWin)->y = pWin->drawable.y; + xnestWindowPriv(pWin)->width = pWin->drawable.width; + xnestWindowPriv(pWin)->height = pWin->drawable.height; + xnestWindowPriv(pWin)->sibling_above = (XCBWINDOW){0}; + xnestWindowPriv(pWin)->owner = XSCREEN_OWNED_BACKING; + + pWin->borderIsPixel = pParent->borderIsPixel; + pWin->border = pParent->border; + if (pWin->borderIsPixel == FALSE) + pWin->border.pixmap->refcnt++; + + wClient(pWin) = serverClient; + pWin->drawable.id = FakeClientID(0); + + pWin->firstChild = NULL; + pWin->lastChild = NULL; + pWin->prevSib = NULL; + pWin->nextSib = NULL; + pWin->optional = NULL; + pWin->valdata = NULL; + + REGION_NULL(pScreen, &pWin->winSize); + REGION_NULL(pScreen, &pWin->borderSize); + REGION_NULL(pScreen, &pWin->clipList); + REGION_NULL(pScreen, &pWin->borderClip); + xnestWindowPriv(pWin)->bounding_shape = REGION_CREATE(pWin->drawable.pScreen, NULL, 1); + xnestWindowPriv(pWin)->clip_shape = REGION_CREATE(pWin->drawable.pScreen, NULL, 1); + + SetWinSize (pWin); + SetBorderSize (pWin); + /*FIXME! THIS IS FUCKED. ONLY FOR TESTING.*/ + pWin->drawable.depth = 24; + + return pWin; +} + +void xnestInsertWindow(WindowPtr pWin, WindowPtr pParent) +{ + WindowPtr pPrev; + + pPrev = RealChildHead(pParent); + if (pPrev) + { + pWin->nextSib = pPrev->nextSib; + if (pPrev->nextSib) + pPrev->nextSib->prevSib = pWin; + else + pParent->lastChild = pWin; + pPrev->nextSib = pWin; + pWin->prevSib = pPrev; + } + else + { + pWin->nextSib = pParent->firstChild; + pWin->prevSib = NullWindow; + if (pParent->firstChild) + pParent->firstChild->prevSib = pWin; + else + pParent->lastChild = pWin; + pParent->firstChild = pWin; + } +} +/** + * YAY! copy-paste coding. + * Again, the reparenting window code almost does what I want, but not quite. + * + * If I use the DIX impementation, I get an infinite loop of reparent events. + **/ + +int xnestReparentWindow(register WindowPtr pWin, register WindowPtr pParent, + int x, int y, ClientPtr client) +{ + WindowPtr pPrev, pPriorParent; + Bool WasMapped = (Bool)(pWin->mapped); + int bw = wBorderWidth (pWin); + register ScreenPtr pScreen; + + pScreen = pWin->drawable.pScreen; + + if (WasMapped) + UnmapWindow(pWin, FALSE); + + + /* take out of sibling chain */ + + pPriorParent = pPrev = pWin->parent; + if (pPrev->firstChild == pWin) + pPrev->firstChild = pWin->nextSib; + if (pPrev->lastChild == pWin) + pPrev->lastChild = pWin->prevSib; + + if (pWin->nextSib) + pWin->nextSib->prevSib = pWin->prevSib; + if (pWin->prevSib) + pWin->prevSib->nextSib = pWin->nextSib; + + /* insert at begining of pParent */ + pWin->parent = pParent; + pPrev = RealChildHead(pParent); + if (pPrev) + { + pWin->nextSib = pPrev->nextSib; + if (pPrev->nextSib) + pPrev->nextSib->prevSib = pWin; + else + pParent->lastChild = pWin; + pPrev->nextSib = pWin; + pWin->prevSib = pPrev; + } + else + { + pWin->nextSib = pParent->firstChild; + pWin->prevSib = NullWindow; + if (pParent->firstChild) + pParent->firstChild->prevSib = pWin; + else + pParent->lastChild = pWin; + pParent->firstChild = pWin; + } + + pWin->origin.x = x + bw; + pWin->origin.y = y + bw; + pWin->drawable.x = x + bw + pParent->drawable.x; + pWin->drawable.y = y + bw + pParent->drawable.y; + + /* clip to parent */ + SetWinSize (pWin); + SetBorderSize (pWin); + if (pScreen->ReparentWindow) + (*pScreen->ReparentWindow)(pWin, pPriorParent); + (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y); + ResizeChildrenWinSize(pWin, 0, 0, 0, 0); + //CheckWindowOptionalNeed(pWin); + + if (WasMapped) + MapWindow(pWin, client); + RecalculateDeliverableEvents(pWin); + return(Success); +} + diff --git a/hw/xnest/WindowFuncs.h b/hw/xnest/WindowFuncs.h new file mode 100644 index 000000000..8ae4e04a9 --- /dev/null +++ b/hw/xnest/WindowFuncs.h @@ -0,0 +1,5 @@ +WindowPtr xnestTrackWindow(XCBWINDOW w, WindowPtr pParent, int x, int y, int width, int height, int bw); +void xnestInsertWindow(WindowPtr pWin, WindowPtr pParent); +int xnestReparentWindow(register WindowPtr pWin, register WindowPtr pParent, int x, int y, ClientPtr client); +void DBG_xnestListWindows(XCBWINDOW w); + diff --git a/hw/xnest/XNWindow.h b/hw/xnest/XNWindow.h index 46fd4f9fe..969842526 100644 --- a/hw/xnest/XNWindow.h +++ b/hw/xnest/XNWindow.h @@ -67,6 +67,7 @@ extern int xnestWindowPrivateIndex; #define xnestIsRoot(pWin) \ ((pWin) == WindowTable[(pWin)->drawable.pScreen->myNum]) + WindowPtr xnestWindowPtr(XCBWINDOW window); Bool xnestCreateWindow(WindowPtr pWin); Bool xnestDestroyWindow(WindowPtr pWin);