From 304697e00b03f4c2c12988d4f4bc4e66d0e09a08 Mon Sep 17 00:00:00 2001 From: Ori Bernstein Date: Tue, 22 Aug 2006 00:23:34 -0500 Subject: [PATCH] Added a few files, filled in more missing code --- hw/xscreen/TODO | 6 + hw/xscreen/xs-color.h | 25 ++ hw/xscreen/xs-event.c | 35 +++ hw/xscreen/xs-font.c | 1 + hw/xscreen/xs-font.h | 16 ++ hw/xscreen/xs-gc.c | 357 ++++++++++++++++++++++++++ hw/xscreen/xs-gc.h | 23 ++ hw/xscreen/xs-gcops.c | 397 ++++++++++++++++++++++++++++ hw/xscreen/xs-gcops.h | 70 +++++ hw/xscreen/xs-globals.h | 10 + hw/xscreen/xs-pixmap.c | 192 ++++++++++++++ hw/xscreen/xs-pixmap.h | 27 ++ hw/xscreen/xs-screen.c | 3 +- hw/xscreen/xs-window.c | 556 ++++++++++++++++++++++++++++++++++++++++ hw/xscreen/xs-window.h | 38 +++ 15 files changed, 1754 insertions(+), 2 deletions(-) create mode 100644 hw/xscreen/TODO create mode 100644 hw/xscreen/xs-color.h create mode 100644 hw/xscreen/xs-event.c create mode 100644 hw/xscreen/xs-font.c create mode 100644 hw/xscreen/xs-font.h create mode 100644 hw/xscreen/xs-gc.c create mode 100644 hw/xscreen/xs-gc.h create mode 100644 hw/xscreen/xs-gcops.c create mode 100644 hw/xscreen/xs-gcops.h create mode 100644 hw/xscreen/xs-pixmap.c create mode 100644 hw/xscreen/xs-pixmap.h create mode 100644 hw/xscreen/xs-window.c create mode 100644 hw/xscreen/xs-window.h diff --git a/hw/xscreen/TODO b/hw/xscreen/TODO new file mode 100644 index 000000000..28a8e2fd2 --- /dev/null +++ b/hw/xscreen/TODO @@ -0,0 +1,6 @@ +- Implement all Window functions +- Finish the Window Creation bits +- Initialize the keyboard properly + (Do we want to do XKB? just forward events from the backing server?) +- Fonts +- Shape extension diff --git a/hw/xscreen/xs-color.h b/hw/xscreen/xs-color.h new file mode 100644 index 000000000..e3c5be14b --- /dev/null +++ b/hw/xscreen/xs-color.h @@ -0,0 +1,25 @@ +#ifndef _XS_COLOR_INCL_ +#define _XS_COLOR_INCL_ + +typedef struct { + XCBCOLORMAP colormap; +} XscreenPrivColormap; + +#define XS_CMAP_PRIV(pCmap) \ + ((XscreenPrivColormap *)((pCmap)->devPriv)) + +Bool xsCreateColormap(ColormapPtr pCmap); +void xsDestroyColormap(ColormapPtr pCmap); +void xsInstallColormap(ColormapPtr pCmap); +void xsUninstallColormap(ColormapPtr pCmap); +int xsListInstalledColormaps(ScreenPtr pScreen, XCBCOLORMAP *pCmapIDs); +void xsStoreColors(ColormapPtr pCmap, int nColors, XCBCOLORITEM *pColors); +void xsResolveColor(CARD16 *r, CARD16 *g, CARD16 *b, VisualPtr pVisual); + +//void xsSetInstalledColormapWindows(ScreenPtr pScreen); +//void xsSetScreenSaverColormapWindow(ScreenPtr pScreen); +//void xsDirectInstallColormaps(ScreenPtr pScreen); +//void xsDirectUninstallColormaps(ScreenPtr pScreen); +//Bool xsCreateDefaultColormap(ScreenPtr pScreen); + +#endif /* XNESTCOLOR_H */ diff --git a/hw/xscreen/xs-event.c b/hw/xscreen/xs-event.c new file mode 100644 index 000000000..e835f7b09 --- /dev/null +++ b/hw/xscreen/xs-event.c @@ -0,0 +1,35 @@ +#ifdef HAVE_XNEST_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include "regionstr.h" +#include "gcstruct.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "region.h" +#include "servermd.h" + + +#include "xs-globals.h" +#include "xs-window.h" + +void xsDoConfigure(XCBConfigureNotifyEvent *e) +{ +} + +void xsHandleEvent(XCBGenericEvent *evt) +{ + switch (evt->response_type & ~0x80) + { + case XCBConfigureNotify: + xsDoConfigure((XCBConfigureNotifyEvent *)evt); + break; + default: + ErrorF("Warning: Unhandled Event"); + } +} diff --git a/hw/xscreen/xs-font.c b/hw/xscreen/xs-font.c new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/hw/xscreen/xs-font.c @@ -0,0 +1 @@ + diff --git a/hw/xscreen/xs-font.h b/hw/xscreen/xs-font.h new file mode 100644 index 000000000..90c702423 --- /dev/null +++ b/hw/xscreen/xs-font.h @@ -0,0 +1,16 @@ +#ifndef _XS_FONT_INCL_ +#define _XS_FONT_INCL_ + +typedef struct { + XCBFONT font; +} XscreenPrivFont; + + +#define XS_FONT_PRIV(pFont) \ + ((XscreenPrivFont *)FontGetPrivate(pFont, xsFontPrivateIndex)) + +Bool xsRealizeFont(ScreenPtr pScreen, FontPtr pFont); +Bool xsUnrealizeFont(ScreenPtr pScreen, FontPtr pFont); + + +#endif diff --git a/hw/xscreen/xs-gc.c b/hw/xscreen/xs-gc.c new file mode 100644 index 000000000..6d000ac5a --- /dev/null +++ b/hw/xscreen/xs-gc.c @@ -0,0 +1,357 @@ +/* $Xorg: GC.c,v 1.3 2000/08/17 19:53:28 cpqbld Exp $ */ +/* + + Copyright 2006 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. Ori Bernstein makes no representations about + the suitability of this software for any purpose. It is provided "as + is" without express or implied warranty. + +*/ +/* $XFree86: xc/programs/Xserver/hw/xs/GC.c,v 3.6 2001/10/28 03:34:11 tsi Exp $ */ + +#ifdef HAVE_XNEST_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include "gcstruct.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include +#include "mistruct.h" +#include "region.h" + +#include "xs-globals.h" +#include "xs-pixmap.h" +#include "xs-font.h" +#include "xs-gcops.h" +#include "xs-gc.h" + +int XS_GC_PRIVateIndex; + +static GCFuncs xsFuncs = { + xsValidateGC, + xsChangeGC, + xsCopyGC, + xsDestroyGC, + xsChangeClip, + xsDestroyClip, + xsCopyClip, +}; + +static GCOps xsOps = { + xsFillSpans, + xsSetSpans, + xsPutImage, + xsCopyArea, + xsCopyPlane, + xsPolyPoint, + xsPolylines, + xsPolySegment, + xsPolyRectangle, + xsPolyArc, + xsFillPolygon, + xsPolyFillRect, + xsPolyFillArc, + xsPolyText8, + xsPolyText16, + xsImageText8, + xsImageText16, + xsImageGlyphBlt, + xsPolyGlyphBlt, + xsPushPixels +}; + +Bool xsCreateGC(GCPtr pGC) +{ + pGC->clientClipType = CT_NONE; + pGC->clientClip = NULL; + + pGC->funcs = &xsFuncs; + pGC->ops = &xsOps; + + pGC->miTranslate = 1; + + XS_GC_PRIV(pGC)->gc = XCBGCONTEXTNew(xsConnection); + XCBCreateGC(xsConnection, + XS_GC_PRIV(pGC)->gc, + xsDefaultDrawables[pGC->depth], + 0L, + NULL); + //XS_GC_PRIV(pGC)->nClipRects = 0; + + return TRUE; +} + +void xsValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) +{ + pGC->lastWinOrg.x = pDrawable->x; + pGC->lastWinOrg.y = pDrawable->y; +} + +void xsChangeGC(GCPtr pGC, unsigned long mask) +{ + XCBParamsGC values; + + if (mask & XCBGCFunction) + values.function = pGC->alu; + + if (mask & XCBGCPlaneMask) + values.plane_mask = pGC->planemask; + + if (mask & XCBGCForeground) + values.foreground = pGC->fgPixel; + + if (mask & XCBGCBackground) + values.background = pGC->bgPixel; + + if (mask & XCBGCLineWidth) + values.line_width = pGC->lineWidth; + + if (mask & XCBGCLineStyle) + values.line_style = pGC->lineStyle; + + if (mask & XCBGCCapStyle) + values.cap_style = pGC->capStyle; + + if (mask & XCBGCJoinStyle) + values.join_style = pGC->joinStyle; + + if (mask & XCBGCFillStyle) + values.fill_style = pGC->fillStyle; + + if (mask & XCBGCFillRule) + values.fill_rule = pGC->fillRule; + + if (mask & XCBGCTile) { + if (pGC->tileIsPixel) + mask &= ~GCTile; + else + values.tile = XS_PIXMAP_PRIV(pGC->tile.pixmap)->pixmap.xid; + } + + if (mask & XCBGCStipple) + values.stipple = XS_PIXMAP_PRIV(pGC->stipple)->pixmap.xid; + + if (mask & XCBGCTileStippleOriginX) + values.tile_stipple_originX = pGC->patOrg.x; + + if (mask & XCBGCTileStippleOriginY) + values.tile_stipple_originY = pGC->patOrg.y; + + if (mask & XCBGCFont) + values.font = XS_FONT_PRIV(pGC->font)->font.xid; + + if (mask & XCBGCSubwindowMode) + values.subwindow_mode = pGC->subWindowMode; + + if (mask & XCBGCGraphicsExposures) + values.graphics_exposures = pGC->graphicsExposures; + + if (mask & XCBGCClipOriginY) + values.clip_originX = pGC->clipOrg.x; + + if (mask & XCBGCClipOriginX) + values.clip_originY = pGC->clipOrg.y; + + if (mask & XCBGCClipMask) /* this is handled in change clip */ + mask &= ~GCClipMask; + + if (mask & XCBGCDashOffset) + values.dash_offset = pGC->dashOffset; + + if (mask & XCBGCDashList) { + mask &= ~GCDashList; + XCBSetDashes(xsConnection, + XS_GC_PRIV(pGC)->gc, + pGC->dashOffset, + pGC->numInDashList, + (BYTE *)pGC->dash); + } + + if (mask & XCBGCArcMode) + values.arc_mode = pGC->arcMode; + + if (mask) + XCBAuxChangeGC(xsConnection, XS_GC_PRIV(pGC)->gc, mask, &values); +} + +void xsCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst) +{ + XCBCopyGC(xsConnection, XS_GC_PRIV(pGCSrc)->gc, XS_GC_PRIV(pGCDst)->gc, mask); +} + +void xsDestroyGC(GCPtr pGC) +{ + XCBFreeGC(xsConnection, XS_GC_PRIV(pGC)->gc); +} + +void xsChangeClip(GCPtr pGC, int type, pointer pValue, int nRects) +{ + int i, size; + BoxPtr pBox; + XCBRECTANGLE *pRects; + XCBParamsGC param; + + xsDestroyClipHelper(pGC); + + switch(type) + { + case CT_NONE: + param.mask = None; + XCBAuxChangeGC(xsConnection, XS_GC_PRIV(pGC)->gc, XCBGCClipMask, ¶m); + break; + + case CT_REGION: + nRects = REGION_NUM_RECTS((RegionPtr)pValue); + size = nRects * sizeof(*pRects); + pRects = xalloc(size); + pBox = REGION_RECTS((RegionPtr)pValue); + for (i = nRects; i-- > 0; ) { + pRects[i].x = pBox[i].x1; + pRects[i].y = pBox[i].y1; + pRects[i].width = pBox[i].x2 - pBox[i].x1; + pRects[i].height = pBox[i].y2 - pBox[i].y1; + } + XCBSetClipRectangles(xsConnection, + XCBClipOrderingUnsorted, + XS_GC_PRIV(pGC)->gc, + 0, 0, + nRects, + pRects); + xfree((char *) pRects); + break; + + case CT_PIXMAP: + param.mask = XS_PIXMAP_PRIV((PixmapPtr)pValue)->pixmap.xid; + XCBAuxChangeGC(xsConnection, XS_GC_PRIV(pGC)->gc, XCBGCClipMask, ¶m); + /* + * Need to change into region, so subsequent uses are with + * current pixmap contents. + */ + pGC->clientClip = (pointer) (*pGC->pScreen->BitmapToRegion)((PixmapPtr)pValue); + (*pGC->pScreen->DestroyPixmap)((PixmapPtr)pValue); + pValue = pGC->clientClip; + type = CT_REGION; + break; + + case CT_UNSORTED: + XCBSetClipRectangles(xsConnection, + XCBClipOrderingUnsorted, + XS_GC_PRIV(pGC)->gc, + pGC->clipOrg.x, + pGC->clipOrg.y, + nRects, + (XCBRECTANGLE *)pValue); + break; + case CT_YSORTED: + XCBSetClipRectangles(xsConnection, + XCBClipOrderingYSorted, + XS_GC_PRIV(pGC)->gc, + pGC->clipOrg.x, + pGC->clipOrg.y, + nRects, + pValue); + break; + case CT_YXSORTED: + XCBSetClipRectangles(xsConnection, + XCBClipOrderingYXSorted, + XS_GC_PRIV(pGC)->gc, + pGC->clipOrg.x, + pGC->clipOrg.y, + nRects, + pValue); + break; + case CT_YXBANDED: + XCBSetClipRectangles(xsConnection, + XCBClipOrderingYXBanded, + XS_GC_PRIV(pGC)->gc, + pGC->clipOrg.x, + pGC->clipOrg.y, + nRects, + pValue); + break; + } + + switch(type) + { + default: + break; + + case CT_UNSORTED: + case CT_YSORTED: + case CT_YXSORTED: + case CT_YXBANDED: + + /* + * other parts of server can only deal with CT_NONE, + * CT_PIXMAP and CT_REGION client clips. + */ + pGC->clientClip = (pointer) RECTS_TO_REGION(pGC->pScreen, nRects, + (xRectangle *)pValue, type); + xfree(pValue); + pValue = pGC->clientClip; + type = CT_REGION; + + break; + } + + pGC->clientClipType = type; + pGC->clientClip = pValue; + //XS_GC_PRIV(pGC)->nClipRects = nRects; +} + +void xsDestroyClip(GCPtr pGC) +{ + XCBParamsGC param; + param.mask = None; + xsDestroyClipHelper(pGC); + + XCBAuxChangeGC(xsConnection, XS_GC_PRIV(pGC)->gc, XCBGCClipMask, ¶m); + + + pGC->clientClipType = CT_NONE; + pGC->clientClip = NULL; + //XS_GC_PRIV(pGC)->nClipRects = 0; +} + +void xsDestroyClipHelper(GCPtr pGC) +{ + switch (pGC->clientClipType) + { + default: + case CT_NONE: + break; + + case CT_REGION: + REGION_DESTROY(pGC->pScreen, pGC->clientClip); + break; + } +} + +void xsCopyClip(GCPtr pGCDst, GCPtr pGCSrc) +{ + RegionPtr pRgn; + + switch (pGCSrc->clientClipType) + { + default: + case CT_NONE: + xsDestroyClip(pGCDst); + break; + + case CT_REGION: + pRgn = REGION_CREATE(pGCDst->pScreen, NULL, 1); + REGION_COPY(pGCDst->pScreen, pRgn, pGCSrc->clientClip); + xsChangeClip(pGCDst, CT_REGION, pRgn, 0); + break; + } +} diff --git a/hw/xscreen/xs-gc.h b/hw/xscreen/xs-gc.h new file mode 100644 index 000000000..bbb056005 --- /dev/null +++ b/hw/xscreen/xs-gc.h @@ -0,0 +1,23 @@ +#ifndef XNESTGC_H +#define XNESTGC_H + +typedef struct { + XCBGCONTEXT gc; +} xsPrivGC; + +extern int xsGCPrivateIndex; + +#define XS_GC_PRIV(pGC) \ + ((xsPrivGC *)((pGC)->devPrivates[xsGCPrivateIndex].ptr)) + +Bool xsCreateGC(GCPtr pGC); +void xsValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable); +void xsChangeGC(GCPtr pGC, unsigned long mask); +void xsCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst); +void xsDestroyGC(GCPtr pGC); +void xsChangeClip(GCPtr pGC, int type, pointer pValue, int nRects); +void xsDestroyClip(GCPtr pGC); +void xsDestroyClipHelper(GCPtr pGC); +void xsCopyClip(GCPtr pGCDst, GCPtr pGCSrc); + +#endif /* XNESTGC_H */ diff --git a/hw/xscreen/xs-gcops.c b/hw/xscreen/xs-gcops.c new file mode 100644 index 000000000..0f08fa411 --- /dev/null +++ b/hw/xscreen/xs-gcops.c @@ -0,0 +1,397 @@ +#ifdef HAVE_XNEST_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include "regionstr.h" +#include +#include "gcstruct.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "region.h" +#include "servermd.h" + + +#include "xs-globals.h" +#include "xs-pixmap.h" +#include "xs-window.h" +#include "xs-gcops.h" +#include "xs-gc.h" + +void xsFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nSpans, xPoint *pPoints, + int *pWidths, int fSorted) +{ + ErrorF("xs warning: function xsFillSpans not implemented\n"); +} + +void xsSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *pSrc, + xPoint *pPoints, int *pWidths, int nSpans, int fSorted) +{ + ErrorF("xs warning: function xsSetSpans not implemented\n"); +} + +void xsGetSpans(DrawablePtr pDrawable, int maxWidth, DDXPointPtr pPoints, + int *pWidths, int nSpans, char *pBuffer) +{ + ErrorF("xs warning: function xsGetSpans not implemented\n"); +} + +void xsQueryBestSize(int class, unsigned short *pWidth, unsigned short *pHeight, + ScreenPtr pScreen) +{ + XCBQueryBestSizeCookie c; + XCBQueryBestSizeRep *r; + + + c = XCBQueryBestSize(xsConnection, class, (XCBDRAWABLE)xsDefaultWindow, *pWidth,*pHeight); + r = XCBQueryBestSizeReply(xsConnection, c, NULL); + + *pWidth = r->width; + *pHeight = r->height; +} + +void xsPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, + int w, int h, int leftPad, int format, char *pImage) +{ + int size; + int i; + size = xsPixmapCalcSize(depth, w, h); + XCBPutImage(xsConnection, + format, + XS_DRAWABLE_ID(pDrawable), + XS_GC_PRIV(pGC)->gc, + w, h, + x, y, + leftPad, + depth, + size, + (CARD8*) (pImage+leftPad)); +} + +void xsGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, + unsigned int format, unsigned long planeMask, + char *pImage) +{ + XCBImage *img; + int length; + + img = XCBImageGet(xsConnection, + XS_DRAWABLE_ID(pDrawable), + x, y, + w, h, + planeMask, + format); + + if (img) { + length = img->bytes_per_line * img->height; + memmove(pImage, img->data, length); + XCBImageDestroy(img); + } +} + +static Bool xsBitBlitPredicate(XCBGenericEvent *event) +{ + return (event->response_type == XCBGraphicsExposure || event->response_type == XCBNoExposure); +} + +static RegionPtr xsBitBlitHelper(GCPtr pGC) +{ + int err; + if (!pGC->graphicsExposures) + return NullRegion; + else { + XCBGenericEvent *event; + XCBGraphicsExposureEvent *exp; + RegionPtr pReg, pTmpReg; + BoxRec Box; + Bool pending, overlap; + + pReg = REGION_CREATE(pGC->pScreen, NULL, 1); + pTmpReg = REGION_CREATE(pGC->pScreen, NULL, 1); + if(!pReg || !pTmpReg) + return NullRegion; + + pending = TRUE; + while (pending) { + event = XCBPollForEvent(xsConnection, &err); + if (!event) + break; + switch (event->response_type) { + case XCBNoExposure: + pending = FALSE; + break; + + case XCBGraphicsExposure: + exp = (XCBGraphicsExposureEvent *) event; + Box.x1 = exp->x; + Box.y1 = exp->y; + Box.x2 = exp->x + exp->width; + Box.y2 = exp->y + exp->height; + REGION_RESET(pGC->pScreen, pTmpReg, &Box); + REGION_APPEND(pGC->pScreen, pReg, pTmpReg); + pending = exp->count; + break; + default: + ErrorF("File: %s Error: %d\n", __FILE__, err); + xsHandleEvent(event); + + } + } + + REGION_DESTROY(pGC->pScreen, pTmpReg); + REGION_VALIDATE(pGC->pScreen, pReg, &overlap); + return(pReg); + } +} + +RegionPtr xsCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, + GCPtr pGC, int srcx, int srcy, int width, int height, + int dstx, int dsty) +{ + XCBCopyArea(xsConnection, + XS_DRAWABLE_ID(pSrcDrawable), + XS_DRAWABLE_ID(pDstDrawable), + XS_GC_PRIV(pGC)->gc, + srcx, srcy, + dstx, dsty, + width, height); + + return xsBitBlitHelper(pGC); +} + +RegionPtr xsCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, + GCPtr pGC, int srcx, int srcy, int width, int height, + int dstx, int dsty, unsigned long plane) +{ + XCBCopyPlane(xsConnection, + XS_DRAWABLE_ID(pSrcDrawable), + XS_DRAWABLE_ID(pDstDrawable), + XS_GC_PRIV(pGC)->gc, + srcx, srcy, + dstx, dsty, + width, height, + plane); + + return xsBitBlitHelper(pGC); +} + +void xsPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int nPoints, + DDXPointPtr pPoints) +{ + XCBPolyPoint(xsConnection, + mode, + XS_DRAWABLE_ID(pDrawable), + XS_GC_PRIV(pGC)->gc, + nPoints, + (XCBPOINT *)pPoints); +} + +void xsPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int nPoints, + DDXPointPtr pPoints) +{ + XCBPolyLine(xsConnection, + mode, + XS_DRAWABLE_ID(pDrawable), + XS_GC_PRIV(pGC)->gc, + nPoints, + (XCBPOINT *)pPoints); +} + +void xsPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nSegments, + xSegment *pSegments) +{ + XCBPolySegment(xsConnection, + XS_DRAWABLE_ID(pDrawable), + XS_GC_PRIV(pGC)->gc, + nSegments, + (XCBSEGMENT *)pSegments); +} + +void xsPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nRectangles, + xRectangle *pRectangles) +{ + XCBPolyRectangle(xsConnection, + XS_DRAWABLE_ID(pDrawable), + XS_GC_PRIV(pGC)->gc, + nRectangles, + (XCBRECTANGLE *)pRectangles); +} + +void xsPolyArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, xArc *pArcs) +{ + XCBPolyArc(xsConnection, + XS_DRAWABLE_ID(pDrawable), + XS_GC_PRIV(pGC)->gc, + nArcs, + (XCBARC *)pArcs); +} + +void xsFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape, int mode, + int nPoints, DDXPointPtr pPoints) +{ + XCBFillPoly(xsConnection, + XS_DRAWABLE_ID(pDrawable), + XS_GC_PRIV(pGC)->gc, + shape, + mode, + nPoints, + (XCBPOINT *)pPoints); +} + +void xsPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nRectangles, + xRectangle *pRectangles) +{ +XCBPolyFillRectangle(xsConnection, + XS_DRAWABLE_ID(pDrawable), + XS_GC_PRIV(pGC)->gc, + nRectangles, + (XCBRECTANGLE*)pRectangles); +} + +void xsPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, xArc *pArcs) +{ + XCBPolyFillArc(xsConnection, + XS_DRAWABLE_ID(pDrawable), + XS_GC_PRIV(pGC)->gc, + nArcs, + (XCBARC *)pArcs); +} + +int xsPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *string) +{ +#if 0 + int width, i; + XCBCHAR2B *str; + XCBFONTABLE f; + XCBQueryTextExtentsCookie c; + XCBQueryTextExtentsRep *r; + XCBGenericError *e; + + XCBPolyText8(xsConnection, + XS_DRAWABLE_ID(pDrawable), + XS_GC_PRIV(pGC)->gc, + x, y, + count, + (BYTE *)string); + + f.font = xsFont(pGC->font); + f.gcontext = XS_GC_PRIV(pGC)->gc; + str = xalloc(count * sizeof(XCBCHAR2B)); + for (i=0; ioverall_width; + /*handle error.. what's appropriate?*/ + return width + x; +#endif + ErrorF("Would have printed %s\n", string); +} + + + +int xsPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *string) +{ +#if 0 + int width = 0; + XCBFONTABLE f; + XCBQueryTextExtentsCookie c; + XCBQueryTextExtentsRep *r; + XCBGenericError *e; + + XCBPolyText16(xsConnection, + XS_DRAWABLE_ID(pDrawable), + XS_GC_PRIV(pGC)->gc, + x, y, + count*2, + (BYTE *)string); + f.font = xsFont(pGC->font); + f.gcontext = XS_GC_PRIV(pGC)->gc; + c = XCBQueryTextExtents(xsConnection, f, count, (XCBCHAR2B*)string); + r = XCBQueryTextExtentsReply(xsConnection, c, &e); + if (r) + if (!e) + width = r->overall_width; + /*handle error.. what's appropriate?*/ + return width + x; +#endif + ErrorF("Would have printed %s\n", string); +} + +void xsImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, + char *string) +{ + XCBImageText8(xsConnection, + count, + XS_DRAWABLE_ID(pDrawable), + XS_GC_PRIV(pGC)->gc, + x, y, + string); +} + +void xsImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *string) +{ + XCBImageText16(xsConnection, + count, + XS_DRAWABLE_ID(pDrawable), + XS_GC_PRIV(pGC)->gc, + x, y, + (XCBCHAR2B *)string); +} + +void xsImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, + unsigned int nGlyphs, CharInfoPtr *pCharInfo, + pointer pGlyphBase) +{ + ErrorF("xs warning: function xsImageGlyphBlt not implemented\n"); +} + +void xsPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, + unsigned int nGlyphs, CharInfoPtr *pCharInfo, + pointer pGlyphBase) +{ + ErrorF("xs warning: function xsPolyGlyphBlt not implemented\n"); +} + +void xsPushPixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDst, + int width, int height, int x, int y) +{ + XCBParamsGC param; + XCBRECTANGLE rect; + /* only works for solid bitmaps */ + if (pGC->fillStyle == FillSolid) + { + param.stipple = XS_PIXMAP_PRIV(pBitmap)->pixmap.xid; + param.tile_stipple_originX = x; + param.tile_stipple_originY = y; + param.fill_style = XCBFillStyleStippled; + XCBAuxChangeGC(xsConnection, XS_GC_PRIV(pGC)->gc, + XCBGCStipple | XCBGCTileStippleOriginX | XCBGCTileStippleOriginY | XCBGCFillStyle, + ¶m); + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + XCBPolyFillRectangle (xsConnection, + XS_DRAWABLE_ID(pDst), + XS_GC_PRIV(pGC)->gc, + 1, + &rect); + param.fill_style = XCBFillStyleSolid; + XCBAuxChangeGC(xsConnection, XS_GC_PRIV(pGC)->gc, + XCBGCFillStyle, + ¶m); + } + else + ErrorF("xs warning: function xsPushPixels not implemented\n"); +} + diff --git a/hw/xscreen/xs-gcops.h b/hw/xscreen/xs-gcops.h new file mode 100644 index 000000000..819d4e02d --- /dev/null +++ b/hw/xscreen/xs-gcops.h @@ -0,0 +1,70 @@ +/* $Xorg: GCOps.h,v 1.3 2000/08/17 19:53:28 cpqbld Exp $ */ +/* + +Copyright 1993 by Davor Matic + +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. + +*/ +/* $XFree86$ */ + +#ifndef XNESTGCOPS_H +#define XNESTGCOPS_H + +void xsFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nSpans, + xPoint *pPoints, int *pWidths, int fSorted); +void xsSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *pSrc, + xPoint *pPoints, int *pWidths, int nSpans, int fSorted); +void xsGetSpans(DrawablePtr pDrawable, int maxWidth, DDXPointPtr pPoints, + int *pWidths, int nSpans, char *pBuffer); +void xsQueryBestSize(int class, unsigned short *pWidth, + unsigned short *pHeight, ScreenPtr pScreen); +void xsPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, + int w, int h, int leftPad, int format, char *pImage); +void xsGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, + unsigned int format, unsigned long planeMask, + char *pImage); +RegionPtr xsCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, + GCPtr pGC, int srcx, int srcy, int width, int height, + int dstx, int dsty); +RegionPtr xsCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, + GCPtr pGC, int srcx, int srcy, int width, int height, + int dstx, int dsty, unsigned long plane); +void xsPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int nPoints, + DDXPointPtr pPoints); +void xsPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int nPoints, + DDXPointPtr pPoints); +void xsPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nSegments, + xSegment *pSegments); +void xsPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nRectangles, + xRectangle *pRectangles); +void xsPolyArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, xArc *pArcs); +void xsFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape, int mode, + int nPoints, DDXPointPtr pPoints); +void xsPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nRectangles, + xRectangle *pRectangles); +void xsPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, xArc *pArcs); +int xsPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, + char *string); +int xsPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, + unsigned short *string); +void xsImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, + char *string); +void xsImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, + unsigned short *string); +void xsImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, + unsigned int nGlyphs, CharInfoPtr *pCharInfo, + pointer pGlyphBase); +void xsPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, + unsigned int nGlyphs, CharInfoPtr *pCharInfo, + pointer pGlyphBase); +void xsPushPixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable, + int width, int height, int x, int y); + +#endif /* XNESTGCOPS_H */ diff --git a/hw/xscreen/xs-globals.h b/hw/xscreen/xs-globals.h index f34a2864c..163883302 100644 --- a/hw/xscreen/xs-globals.h +++ b/hw/xscreen/xs-globals.h @@ -3,6 +3,16 @@ #define MAXDEPTH 32 +typedef enum { + XS_OWNED, + XS_UNOWNED, +} XSOwnership; + +#define XS_DRAWABLE_ID(/*DrawablePtr*/ d) \ + (((d)->type == DRAWABLE_WINDOW)? \ + ((XCBDRAWABLE) (XS_WINDOW_PRIV((WindowPtr)(d))->window)) : \ + ((XCBDRAWABLE) (XS_PIXMAP_PRIV((PixmapPtr)(d))->pixmap))) + extern XCBConnection *xsConnection; extern XCBDRAWABLE xsDefaultDrawables[MAXDEPTH]; extern XCBDRAWABLE xsDefaultWindow; diff --git a/hw/xscreen/xs-pixmap.c b/hw/xscreen/xs-pixmap.c new file mode 100644 index 000000000..bb55ec8de --- /dev/null +++ b/hw/xscreen/xs-pixmap.c @@ -0,0 +1,192 @@ +/* $Xorg: Pixmap.c,v 1.3 2000/08/17 19:53:28 cpqbld Exp $ */ +/* + +Copyright 1993 by Davor Matic + +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. + +*/ +/* $XFree86: xc/programs/Xserver/hw/xs/Pixmap.c,v 3.7 2003/07/16 01:38:51 dawes Exp $ */ + +#ifdef HAVE_XNEST_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include "regionstr.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "regionstr.h" +#include "gc.h" +#include "servermd.h" +#include "mi.h" + +#include "xs-globals.h" +#include "xs-pixmap.h" + +#ifdef PIXPRIV +int XS_PIXMAP_PRIVIndex; +#endif + +static int xsNumFormats; +static XCBFORMAT *xsFormats; + +/** + * Initializes the list of available formats, used + * in calculating the size and other such places. + **/ +void xsInitFormats() +{ + const XCBSetup *setup; + + setup = XCBGetSetup(xsConnection); + xsNumFormats = XCBSetupPixmapFormatsLength(setup); + xsFormats = XCBSetupPixmapFormats(setup); +} + +/** + * Calculates the size of a pixmap of a given depth, + * with a given width and height. + **/ +int xsPixmapCalcSize(int depth, int w, int h) +{ + int size; + int pad; + int bpp; + int i; + + for (i=0; i> 3)*h; + return size; +} + +/** + * Creates a new pixmap. + **/ +PixmapPtr xsCreatePixmap(ScreenPtr pScreen, int width, int height, int depth) +{ + PixmapPtr pPixmap; + + pPixmap = AllocatePixmap(pScreen, sizeof(XscreenPrivPixmap)); + if (!pPixmap) + return NullPixmap; + pPixmap->drawable.type = DRAWABLE_PIXMAP; + pPixmap->drawable.class = 0; + pPixmap->drawable.depth = depth; + pPixmap->drawable.bitsPerPixel = depth; + pPixmap->drawable.id = 0; + pPixmap->drawable.x = 0; + pPixmap->drawable.y = 0; + pPixmap->drawable.width = width; + pPixmap->drawable.height = height; + pPixmap->drawable.pScreen = pScreen; + pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + pPixmap->refcnt = 1; + pPixmap->devKind = PixmapBytePad(width, depth); +#ifdef PIXPRIV + pPixmap->devPrivates[XS_PIXMAP_PRIVateIndex].ptr = + (pointer)((char *)pPixmap + pScreen->totalPixmapSize); +#else + pPixmap->devPrivate.ptr = (pointer)(pPixmap + 1); +#endif + if (width && height){ + XS_PIXMAP_PRIV(pPixmap)->pixmap = XCBPIXMAPNew(xsConnection); + XCBCreatePixmap(xsConnection, + depth, + XS_PIXMAP_PRIV(pPixmap)->pixmap, + (XCBDRAWABLE)xsDefaultWindow, + width, height); + } else + XS_PIXMAP_PRIV(pPixmap)->pixmap.xid = 0; + + return pPixmap; +} + +/** + * Destroys a pixmap* + **/ +Bool xsDestroyPixmap(PixmapPtr pPixmap) +{ + if(--pPixmap->refcnt) + return TRUE; + XCBFreePixmap(xsConnection, XS_PIXMAP_PRIV(pPixmap)->pixmap); + xfree(pPixmap); + return TRUE; +} + +/** + * Converts a pixmap to a region + **/ +RegionPtr xsPixmapToRegion(PixmapPtr pPixmap) +{ + XCBImage *ximage; + register RegionPtr pReg, pTmpReg; + register int x, y; + unsigned long previousPixel, currentPixel; + BoxRec Box; + Bool overlap; + + ximage = XCBImageGet(xsConnection, + (XCBDRAWABLE)XS_PIXMAP_PRIV(pPixmap)->pixmap, + 0, 0, + pPixmap->drawable.width, pPixmap->drawable.height, + 1, + XYPixmap); + + pReg = REGION_CREATE(pPixmap->drawable.pScreen, NULL, 1); + pTmpReg = REGION_CREATE(pPixmap->drawable.pScreen, NULL, 1); + if(!pReg || !pTmpReg) { + XCBImageDestroy(ximage); + return NullRegion; + } + + for (y = 0; y < pPixmap->drawable.height; y++) { + Box.y1 = y; + Box.y2 = y + 1; + previousPixel = 0L; + for (x = 0; x < pPixmap->drawable.width; x++) { + currentPixel = XCBImageGetPixel(ximage, x, y); + if (previousPixel != currentPixel) { + if (previousPixel == 0L) { + /* left edge */ + Box.x1 = x; + } + else if (currentPixel == 0L) { + /* right edge */ + Box.x2 = x; + REGION_RESET(pPixmap->drawable.pScreen, pTmpReg, &Box); + REGION_APPEND(pPixmap->drawable.pScreen, pReg, pTmpReg); + } + previousPixel = currentPixel; + } + } + if (previousPixel != 0L) { + /* right edge because of the end of pixmap */ + Box.x2 = pPixmap->drawable.width; + REGION_RESET(pPixmap->drawable.pScreen, pTmpReg, &Box); + REGION_APPEND(pPixmap->drawable.pScreen, pReg, pTmpReg); + } + } + + REGION_DESTROY(pPixmap->drawable.pScreen, pTmpReg); + XCBImageDestroy(ximage); + + REGION_VALIDATE(pPixmap->drawable.pScreen, pReg, &overlap); + + return(pReg); +} diff --git a/hw/xscreen/xs-pixmap.h b/hw/xscreen/xs-pixmap.h new file mode 100644 index 000000000..2ed58432d --- /dev/null +++ b/hw/xscreen/xs-pixmap.h @@ -0,0 +1,27 @@ +#ifndef _XS_PIXMAP_INCL_ +#define _XS_PIXMAP_INCL_ + +#ifdef PIXPRIV +extern int xsPixmapPrivateIndex; +#endif + +typedef struct { + XCBPIXMAP pixmap; + XSOwnership owned; +} XscreenPrivPixmap; + +#ifdef PIXPRIV +#define XS_PIXMAP_PRIV(pPixmap) \ + ((XscreenPrivPixmap *)((pPixmap)->devPrivates[xsPixmapPrivateIndex].ptr)) +#else +#define XS_PIXMAP_PRIV(pPixmap) \ + ((XscreenPrivPixmap *)((pPixmap)->devPrivate.ptr)) +#endif + +void xsInitFormats(); +int xsPixmapCalcSize(int depth, int w, int h); +PixmapPtr xsCreatePixmap(ScreenPtr pScreen, int width, int height, int depth); +Bool xsDestroyPixmap(PixmapPtr pPixmap); +RegionPtr xsPixmapToRegion(PixmapPtr pPixmap); + +#endif diff --git a/hw/xscreen/xs-screen.c b/hw/xscreen/xs-screen.c index d823a5ee0..3ce701878 100644 --- a/hw/xscreen/xs-screen.c +++ b/hw/xscreen/xs-screen.c @@ -22,7 +22,6 @@ #include "mi.h" #include "xs-globals.h" -#include "xs-types.h" #include "xs-gc.h" #include "xs-font.h" #include "xs-gcops.h" @@ -63,7 +62,7 @@ static void xsScreenSetProcs(ScreenPtr pScreen) pScreen->RealizeWindow = xsRealizeWindow; pScreen->UnrealizeWindow = xsUnrealizeWindow; pScreen->PostValidateTree = NULL; - pScreen->WindowExposures = xsWindowExposures; + //pScreen->WindowExposures = xsWindowExposures; pScreen->PaintWindowBackground = xsPaintWindowBackground; pScreen->PaintWindowBorder = xsPaintWindowBorder; pScreen->CopyWindow = xsCopyWindow; diff --git a/hw/xscreen/xs-window.c b/hw/xscreen/xs-window.c new file mode 100644 index 000000000..95f2e6799 --- /dev/null +++ b/hw/xscreen/xs-window.c @@ -0,0 +1,556 @@ +#ifdef HAVE_XNEST_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include "regionstr.h" +#include +#include "gcstruct.h" +#include "colormapst.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "region.h" +#include "servermd.h" + + +#include "xs-globals.h" +#include "xs-pixmap.h" +#include "xs-window.h" +#include "xs-color.h" +#include "xs-gcops.h" +#include "xs-gc.h" + +/*Forward decls*/ +static WindowPtr xsTrackWindow(XCBWINDOW win, WindowPtr pParent); + +/** + * returns the WindowPtr of a window with a given XID on the backing server. + * if the window is not tracked by Xnest, NULL is returned. + **/ +typedef struct { + XCBWINDOW win; + WindowPtr pWin; +} XsWindowMatch; + +static int xsMatchFunc(WindowPtr pWin, XsWindowMatch *wm) +{ + if (wm->win.xid == XS_WINDOW_PRIV(pWin)->window.xid) { + wm->pWin = pWin; + return WT_STOPWALKING; + } + else + return WT_WALKCHILDREN; +} + +WindowPtr xsGetWindow(XCBWINDOW window) +{ + XsWindowMatch wm; + int i; + + wm.pWin = NULL; + wm.win = window; + + WalkTree(0, (int (*)(WindowPtr, pointer))xsMatchFunc, (pointer) &wm); + return wm.pWin; +} + + +/** + * Inserts a window into the window tree. + * pParent must NOT be NULL, ie: this must NOT be called on the root window. + **/ +void xsInstallWindow(WindowPtr pWin, WindowPtr pParent) +{ + +} + +/** + * Initializes a window with valid values. + * Assumes XS_WINDOW_PRIV(pWin)->window is valid. + * Arguments: + * pWin: the window + * pParent: the parent. may be NULL for root window. + * x, y: the locations relative to the parent window. + * w, h: the width and height of the window. + * bw: the border width of the window. + * + * FIXME: This might break stuff when being called from xsCreateWindow. We'll see. + **/ +static void xsInitWindow(WindowPtr pWin, WindowPtr pParent, int x, int y, int w, int h, int bw) +{ + XCBWINDOW win; + int parent_x, parent_y; + + win = XS_WINDOW_PRIV(pWin)->window; + if (pParent) { + parent_x = pParent->drawable.x; + parent_y = pParent->drawable.y; + } else { + parent_x = 0; + parent_y = 0; + } + /* copy parent's drawable. If there's no parent, we're initting the + * root window, which gets it's drawable initialized by the DIX */ + if (pParent) + pWin->drawable = pParent->drawable; + /*init drawable. Drawable's coordinates are in world coordinates.*/ + pWin->drawable.x = x + parent_x + wBorderWidth(pWin); + pWin->drawable.y = y + parent_y + wBorderWidth(pWin); + pWin->drawable.width = w; + pWin->drawable.height = h; + + /*init origin. pWin->origin is relative to parent.*/ + pWin->origin.x = x; + pWin->origin.y = y; + + pWin->prevSib = NULL; + pWin->nextSib = NULL; + pWin->firstChild = NULL; + pWin->lastChild = NULL; + + 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->borderWidth = bw; + pWin->drawable.x = pParent->drawable.x + x + bw; + pWin->drawable.y = pParent->drawable.y + y + bw; + pWin->drawable.type = DRAWABLE_WINDOW; + pWin->drawable.width = w; + pWin->drawable.height = h; + pWin->backingStore = NotUseful; + pWin->backStorage = NULL; + pWin->backgroundState = 0; + + XS_WINDOW_PRIV(pWin)->window = win; + XS_WINDOW_PRIV(pWin)->owned = XS_OWNED; + + 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); + + /*??? What exactly do these do that setting pWin->drawable.{x,y} etc don't + SetWinSize (pWin); + SetBorderSize (pWin); + */ +} + +/** + * Tracks all children of a given WindowPtr. the WindowPtr is _NOT_ tracked. + * the backing server *must* be grabbed when calling this function, since this + * function doesn't do the server grab on it's own + **/ +static void xsTrackChildren(WindowPtr pParent, CARD32 ev_mask) +{ + XCBWINDOW win; + WindowPtr pWin; + XCBQueryTreeCookie qcook; + XCBQueryTreeRep *qrep; + XCBGetGeometryCookie gcook; + XCBGetGeometryRep *grep; + XCBWINDOW *child; + int i; + + win = XS_WINDOW_PRIV(pParent)->window; + qcook = XCBQueryTree(xsConnection, win); + qrep = XCBQueryTreeReply(xsConnection, qcook, NULL); + child = XCBQueryTreeChildren(qrep); + for (i=0; i < qrep->children_len; i++) { + pWin = xsGetWindow(child[i]); + if (!pWin){ + gcook = XCBGetGeometry(xsConnection, (XCBDRAWABLE)child[i]); + grep = XCBGetGeometryReply(xsConnection, gcook, NULL); + pWin = AllocateWindow(pParent->drawable.pScreen); + XS_WINDOW_PRIV(pWin)->window = child[i]; + xsInitWindow(pWin, pParent, grep->x, grep->y, grep->width, grep->height, grep->border_width); + XCBChangeWindowAttributes(xsConnection, child[i], XCBCWEventMask, &ev_mask); + } else { + xsRemoveWindow(pWin); + } + xsInstallWindow(pParent, pWin); + } +} + +/** + * Allocates a new WindowPtr, and tracks it, inserting it into the + * window tree. Assumes that pParent is the parent of the window. + **/ +static WindowPtr xsTrackWindow(XCBWINDOW win, WindowPtr pParent) +{ + WindowPtr pWin; + CARD32 ev_mask; + XCBGetGeometryCookie gcook; + XCBGetGeometryRep *grep; + + pWin = AllocateWindow(pParent->drawable.pScreen); + gcook = XCBGetGeometry(xsConnection, (XCBDRAWABLE)win); + grep = XCBGetGeometryReply(xsConnection, gcook, NULL); + + /*initialize the window*/ + xsInitWindow(pWin, pParent, + grep->x, grep->y, + grep->width, grep->height, + grep->border_width); + + /*set the event mask*/ + ev_mask = XCBEventMaskSubstructureNotify|XCBEventMaskStructureNotify; + XCBChangeWindowAttributes(xsConnection, win, XCBCWEventMask, &ev_mask); + + /*make sure we've got all the children of the window*/ + XCBGrabServer(xsConnection); + xsTrackChildren(pWin, ev_mask); + XCBUngrabServer(xsConnection); + return pWin; +} + +/** + * Implements the CreateWindow handler for X clients. + * Not used by the event handling code, since xsCreateWindow + * assumes the WindowPtr gets handled in CreateWindow, in the DIX. + **/ +Bool xsCreateWindow(WindowPtr pWin) +{ + CARD32 mask; + CARD32 ev_mask; + XCBSCREEN *screen; + XCBVISUALID vid; + XCBParamsCW params; + + /* Inits too much for CreateWindow calls, but.. well.. otherwise we'd + * duplicate code. */ + screen = XCBSetupRootsIter (XCBGetSetup (xsConnection)).data; + /** + * We need to special-case creating the root window, since + * it's representation on the backing server has already been + * done for us. + **/ + if (XS_IS_ROOT(pWin)) { + XS_WINDOW_PRIV(pWin)->window = screen->root; + +#if 0 + /*FIXME! do we need to do this? + /*initialize the root window*/ + xsInitWindow(pWin, NULL, /*root has no parent*/ + 0, 0, /*origin at 0, 0*/ + screen->width_in_pixels, /*same size as screen*/ + screen->height_in_pixels, + 0); /*no border*/ +#endif + + /*we want to listen to both motion and creation events on the root*/ + mask = XCBEventMaskSubstructureNotify | XCBEventMaskPointerMotion; + XCBChangeWindowAttributes(xsConnection, screen->root, XCBCWEventMask, &ev_mask); + + /*track the children of the root window*/ + XCBGrabServer(xsConnection); + xsTrackChildren(pWin, ev_mask); + XCBUngrabServer(xsConnection); + return TRUE; + } + + if (pWin->drawable.class == XCBWindowClassInputOnly) { + 0L; + vid.id = XCBCopyFromParent; + } else { + if (pWin->optional && pWin->optional->visual != wVisual(pWin->parent)) { + ErrorF("Need to get visuals"); + exit(1); + } else { + vid.id = XCBCopyFromParent; + } + } + /*we want all the important events on the window*/ + params.event_mask = ((1<<25)-1) & + ~(XCBEventMaskSubstructureRedirect | + XCBEventMaskPointerMotionHint | + XCBEventMaskResizeRedirect); + + /*If we're not creating the root window, continue as normal*/ + XS_WINDOW_PRIV(pWin)->window = XCBWINDOWNew(xsConnection); + XCBAuxCreateWindow(xsConnection, + pWin->drawable.depth, + XS_WINDOW_PRIV(pWin)->window, + XS_WINDOW_PRIV(pWin->parent)->window, + pWin->origin.x - wBorderWidth(pWin), + pWin->origin.y - wBorderWidth(pWin), + pWin->drawable.width, + pWin->drawable.height, + pWin->borderWidth, + pWin->drawable.class, + vid, + mask, + ¶ms); +} + +/** + * Destroys a window on the backing server. + * Does nothing if the window is unowned by Xscreen. + * FIXME: not sure if it's possible for this function + * to be called by a window not owned by Xscreen + **/ +Bool xsDestroyWindow(WindowPtr pWin) +{ + /* I don't think we want to be destroying unowned windows. + * Might be wrong about this though.*/ + if (XS_WINDOW_PRIV(pWin)->owned != XS_OWNED) + return FALSE; + XCBDestroyWindow(xsConnection, XS_WINDOW_PRIV(pWin)->window); + XS_WINDOW_PRIV(pWin)->window = (XCBWINDOW){0}; + return TRUE; +} + + +/** + * Positions a window at the specified (x,y) coordinates. + **/ +Bool xsPositionWindow(WindowPtr pWin, int x, int y) +{ + CARD32 list[2]; + + list[0] = x; + list[1] = y; + XCBConfigureWindow(xsConnection, + XS_WINDOW_PRIV(pWin)->window, + XCBConfigWindowX | XCBConfigWindowY, + list); + return TRUE; +} + +/** + * Changes window attributes + **/ + +Bool xsChangeWindowAttributes(WindowPtr pWin, unsigned long mask) +{ + XCBParamsCW param; + PixmapPtr pPixmap; + + if (mask & XCBCWBackPixmap) { + switch (pWin->backgroundState) { + case XCBBackPixmapNone: + param.back_pixmap = 0; + break; + + case XCBBackPixmapParentRelative: + param.back_pixmap = XCBBackPixmapParentRelative; + break; + + /*X server internal things.*/ + case BackgroundPixmap: + pPixmap = pWin->background.pixmap; + param.back_pixmap = XS_PIXMAP_PRIV(pPixmap)->pixmap.xid; + break; + + case BackgroundPixel: + mask &= ~XCBCWBackPixmap; + break; + } + } + + if (mask & XCBCWBackPixel) { + if (pWin->backgroundState == BackgroundPixel) + param.back_pixel = pWin->background.pixel; + else + mask &= ~CWBackPixel; + } + + if (mask & XCBCWBorderPixmap) { + if (pWin->borderIsPixel) + mask &= ~CWBorderPixmap; + else + pPixmap = pWin->border.pixmap; + param.border_pixmap = XS_PIXMAP_PRIV(pPixmap)->pixmap.xid; + } + + if (mask & XCBCWBorderPixel) { + if (pWin->borderIsPixel) + param.border_pixel = pWin->border.pixel; + else + mask &= ~XCBCWBorderPixel; + } + + if (mask & XCBCWBitGravity) + param.bit_gravity = pWin->bitGravity; + + if (mask & XCBCWWinGravity) /* dix does this for us */ + mask &= ~CWWinGravity; + + if (mask & XCBCWBackingStore) /* this is really not useful */ + mask &= ~CWBackingStore; + + if (mask & XCBCWBackingPlanes) /* this is really not useful */ + mask &= ~CWBackingPlanes; + + if (mask & XCBCWBackingPixel) /* this is really not useful */ + mask &= ~CWBackingPixel; + + if (mask & XCBCWOverrideRedirect) + param.override_redirect = pWin->overrideRedirect; + + if (mask & XCBCWSaveUnder) /* this is really not useful */ + mask &= ~CWSaveUnder; + + if (mask & XCBCWEventMask) /* events are handled elsewhere */ + mask &= ~CWEventMask; + + if (mask & XCBCWDontPropagate) /* events are handled elsewhere */ + mask &= ~CWDontPropagate; + + if (mask & XCBCWColormap) { + ColormapPtr pCmap; + pCmap = LookupIDByType(wColormap(pWin), RT_COLORMAP); + param.colormap = XS_CMAP_PRIV(pCmap)->colormap.xid; + xsSetInstalledColormapWindows(pWin->drawable.pScreen); + } + if (mask & XCBCWCursor) /* this is handeled in cursor code */ + mask &= ~XCBCWCursor; + + if (mask) + XCBAuxChangeWindowAttributes(xsConnection, XS_WINDOW_PRIV(pWin)->window, mask, ¶m); +} + +/** + * Configures window. + * Assumes that the client won't do something completely stupid (namely + * configuring a window with a zero mask) and that the cost of actually + * doing a configure for extra values is unneeded. + **/ +void xsConfigureWindow(WindowPtr pWin, CARD32 mask) +{ + WindowPtr pSib; + CARD32 vmask; + XCBParamsConfigureWindow values; + + /* We fill the entire structure here, and let the mask weed out the + * extra data */ + /* window size/position */ + values.x = pWin->origin.x; + values.y = pWin->origin.y; + values.width = pWin->drawable.width; + values.height = pWin->drawable.height; + values.border_width = wBorder(pWin); + + XCBAuxConfigureWindow(xsConnection, XS_WINDOW_PRIV(pWin)->window, mask, &values); + + if (mask & XCBConfigWindowStackMode) { + /*get top sibling*/ + for (pSib = pWin; pSib->prevSib != NULL; pSib = pSib->prevSib); + + vmask = XCBConfigWindowStackMode; + values.stack_mode = XCBStackModeAbove; + XCBAuxConfigureWindow(xsConnection, XS_WINDOW_PRIV(pSib)->window, vmask, &values); + + /* the rest of siblings */ + for (pSib = pSib->nextSib; pSib != NullWindow; pSib = pSib->nextSib) { + vmask = XCBConfigWindowSibling | XCBConfigWindowStackMode; + values.sibling = XS_WINDOW_PRIV(pSib)->window.xid; + values.stack_mode = Below; + XCBAuxConfigureWindow(xsConnection, XS_WINDOW_PRIV(pSib)->window, vmask, &values); + } + } +} + + +/** + * Realizes a window on the screen + **/ +Bool xsRealizeWindow(WindowPtr pWin) +{ + if (XS_IS_ROOT(pWin)) + return TRUE; + xsConfigureWindow(pWin, XCBConfigWindowStackMode); + XCBMapWindow(xsConnection, XS_WINDOW_PRIV(pWin)->window); + return TRUE; +} + +/** + * Unrealizes a window + **/ +Bool xsUnrealizeWindow(WindowPtr pWin) +{ + XCBUnmapWindow(xsConnection, XS_WINDOW_PRIV(pWin)->window); + return TRUE; +} + +void xsPaintWindowBackground(WindowPtr pWin, RegionPtr pRegion, int what) +{ + int i; + BoxPtr pBox; + + pBox = REGION_RECTS(pRegion); + for (i = 0; i < REGION_NUM_RECTS(pRegion); i++) + XCBClearArea(xsConnection, + FALSE, + XS_WINDOW_PRIV(pWin)->window, + pBox[i].x1 - pWin->drawable.x, + pBox[i].y1 - pWin->drawable.y, + pBox[i].x2 - pBox[i].x1, + pBox[i].y2 - pBox[i].y1); +} + +Bool xsPaintWindowBorder(WindowPtr pWin, RegionPtr pRegion, int what) +{ + /* I think this should be a no-op? */ +} + +void xsCopyWindow(WindowPtr pWin, xPoint oldOrigin, RegionPtr oldRegion) +{ + /* another no-op */ +} + + +void xsClipNotify(WindowPtr pWin, int dx, int dy) +{ + xsConfigureWindow(pWin, XCBConfigWindowStackMode); +} diff --git a/hw/xscreen/xs-window.h b/hw/xscreen/xs-window.h new file mode 100644 index 000000000..7d3cd3bbe --- /dev/null +++ b/hw/xscreen/xs-window.h @@ -0,0 +1,38 @@ +#ifndef _XS_WINDOW_INCL_ +#define _XS_WINDOW_INCL_ + +extern int xsWindowPrivateIndex; + +typedef struct { + XCBWINDOW window; + XSOwnership owned; +} XscreenPrivWindow; + +/** + * returns the window privates + **/ +#define XS_WINDOW_PRIV(pWin) \ + ((XscreenPrivWindow *)((pWin)->devPrivates[xsWindowPrivateIndex].ptr)) +/** + * returns whether the window in question is the root window. + * NB: This ONLY works for screen 0, which is all I currently care about. + **/ +#define XS_IS_ROOT(pWin) \ + ((pWin) == (WindowTable[0])) + + +Bool xsCreateWindow(WindowPtr pWin); +Bool xsDestroyWindow(WindowPtr pWin); +Bool xsChangeWindowAttributes(WindowPtr pWin, unsigned long mask); +Bool xsRealizeWindow(WindowPtr pWin); +Bool xsUnrealizeWindow(WindowPtr pWin); +Bool xsPaintWindowBorder(WindowPtr pWin, RegionPtr pRegion, int what); +void xsPaintWindowBackground(WindowPtr pWin, RegionPtr pRegion, int what); +Bool xsPositionWindow(WindowPtr pWin, int x, int y); +void xsConfigureWindow(WindowPtr pWin, CARD32 mask); + +void xsWindowExposures(WindowPtr pWin, RegionPtr pRgn, RegionPtr pOther); +void xsCopyWindow(WindowPtr pWin, xPoint old_orig, RegionPtr old_rgn); +void xsClipNotify(WindowPtr pWin, int dx, int dy); + +#endif