Broke stuff in an attempt to unbreak stuff. Segfaults galore.

This commit is contained in:
Ori Bernstein 2006-08-03 20:31:18 -05:00 committed by Ori Bernstein
parent a81adf16ef
commit 7bdcda388b
8 changed files with 372 additions and 110 deletions

View file

@ -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);
}
}

View file

@ -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);

View file

@ -34,6 +34,7 @@
#include "Xnest.h"
#include "Display.h"
#include "Events.h"
#include "Screen.h"
#include "XNGC.h"
#include "XNFont.h"

View file

@ -30,6 +30,8 @@ SRCS = Args.c \
Visual.c \
Visual.h \
Window.c \
WindowFuncs.h \
WindowFuncs.c \
XNCursor.h \
Xnest.h \
XNFont.h \

View file

@ -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;
}

290
hw/xnest/WindowFuncs.c Normal file
View file

@ -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 <xnest-config.h>
#endif
#include <X11/Xmd.h>
#include <X11/XCB/xcb.h>
#define NEED_EVENTS
#include <X11/XCB/xproto.h>
#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; j<splvl; j++)
ErrorF(" ");
ErrorF("Window %d, pWin 0x%x ", w.xid, pWin);
if (!pWin)
ErrorF("********************WARNING: NULL WINDOW********************");
ErrorF("\n");
/*and recurse, adding this window's children*/
splvl++;
DBG_xnestListWindows(child[i]);
splvl--;
}
}
/**
* Allocates and initializes a window based on the parent window.
* This function exists because CreateWindow() does too much, namely
* actually calling pScreen->CreateWindow().
*
* 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);
}

5
hw/xnest/WindowFuncs.h Normal file
View file

@ -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);

View file

@ -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);