xserver: Branch 'wonderland-dev'
Deron Johnson
deronj at kemper.freedesktop.org
Mon Jun 4 19:36:16 PDT 2007
hw/vfb/rwout.c | 2215 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 2215 insertions(+)
New commits:
diff-tree 9789f35cc5ca147c6c4b4bfc810d44fdbdbe5705 (from 1d7fbdfea4f4dbbbb685c7407a1c060ac3875874)
Author: Deron <dj at dj-laptop.(none)>
Date: Mon Jun 4 19:36:15 2007 -0700
New file in branch.
diff --git a/hw/vfb/rwout.c b/hw/vfb/rwout.c
new file mode 100644
index 0000000..6e1e3bd
--- /dev/null
+++ b/hw/vfb/rwout.c
@@ -0,0 +1,2215 @@
+#undef VERBOSE
+
+/*****************************************************************
+
+Copyright 2007 Sun Microsystems, Inc.
+
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, and/or sell copies of the Software, and to permit persons
+to whom the Software is furnished to do so, provided that the above
+copyright notice(s) and this permission notice appear in all copies of
+the Software and that both the above copyright notice(s) and this
+permission notice appear in supporting documentation.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+of the copyright holder.
+
+******************************************************************/
+
+#include <unistd.h>
+#include "regionstr.h"
+#include "damage.h"
+#include "windowstr.h"
+#include "remwin.h"
+#include "rwcomm.h"
+#include "misc.h"
+#include "protocol.h"
+#include "cursorstr.h"
+#include "servermd.h"
+
+/* TODO: replace with DS */
+#include "rwcommsock.h"
+
+#define USE_RLE_ENV_VAR "XREMWIN_USE_RLE"
+#define VERIFY_RLE_ENV_VAR "XREMWIN_VERIFY_RLE"
+
+static Bool useRle24 = FALSE;
+Bool rwRleVerifyPixels = FALSE;
+
+static unsigned long remwinGeneration = 0;
+int remwinScreenIndex;
+int remwinWinIndex;
+int remwinGCIndex;
+
+/* TODO: note: dix extension */
+extern WindowPtr dixGetSpriteWindow (void);
+
+static Bool rwoutCreateWindowWrite (ScreenPtr pScreen, WindowPtr pWin);
+static Bool rwoutDestroyWindowWrite (ScreenPtr pScreen, WindowPtr pWin);
+static Bool rwoutShowWindowWrite (ScreenPtr pScreen, WindowPtr pWin, int show);
+static Bool rwoutConfigureWindowWrite (ScreenPtr pScreen, WindowPtr pWin, int x, int y,
+ unsigned int w, unsigned int h, WindowPtr pSib);
+static Bool rwoutPositionWindowWrite (ScreenPtr pScreen, WindowPtr pWin, int x, int y);
+static Bool rwoutWindowSetDecoratedWrite (ScreenPtr pScreen, WindowPtr pWin);
+static Bool rwoutWindowSetBorderWidthWrite (ScreenPtr pScreen, WindowPtr pWin);
+static Bool rwoutWindowPixelsWrite (ScreenPtr pScreen, WindowPtr pWin,
+ RemwinWindowPrivPtr pWinPriv);
+static Bool rwoutPixelsWrite (ScreenPtr pScreen);
+static Bool rwoutUncodedPixelsWrite (ScreenPtr pScreen, WindowPtr pWin,
+ int x, int y, int w, int h);
+static Bool rwoutDisplayCursorWrite (ScreenPtr pScreen, CursorPtr pCursor);
+static Bool rwoutMoveCursorWrite (ScreenPtr pScreen, WindowPtr, int x, int y);
+static Bool rwoutShowCursorWrite (ScreenPtr pScreen, Bool show);
+
+static Bool rwoutCreateWindow(WindowPtr);
+static Bool rwoutRealizeWindow(WindowPtr);
+static Bool rwoutUnrealizeWindow(WindowPtr);
+static Bool rwoutDestroyWindow(WindowPtr);
+static void rwoutResizeWindow(WindowPtr, int x, int y,
+ unsigned int w, unsigned int h, WindowPtr pSib);
+static Bool rwoutPositionWindow(WindowPtr, int x, int y);
+static int rwoutChangeWindowAttributes(WindowPtr, Mask vmask);
+static Bool rwoutDisplayCursor (ScreenPtr pScreen, CursorPtr pCursor);
+static Bool rwoutSetCursorPosition (ScreenPtr pScreen, int x, int y,
+ Bool generateEvent);
+
+static CARD32 rwoutTimerCallback (OsTimerPtr timer, CARD32 now, pointer arg);
+
+/* TODO: do I really need to wrap them all? */
+
+static Bool rwoutCreateGC (GCPtr pGC);
+static void rwoutValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable);
+static void rwoutChangeGC (GCPtr pGC, unsigned long mask);
+static void rwoutCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
+static void rwoutDestroyGC(GCPtr pGC);
+static void rwoutChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects);
+static void rwoutCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
+static void rwoutDestroyClip(GCPtr pGC);
+
+static void rwoutFillSpans(DrawablePtr pDst, GCPtr pGC, int nInit,
+ DDXPointPtr pptInit, int *pwidthInit, int fSorted);
+static void rwoutSetSpans(DrawablePtr pDst, GCPtr pGC, char *psrc,
+ DDXPointPtr ppt, int *pwidth, int nspans, int fSorted);
+static void rwoutPutImage(DrawablePtr pDst, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad, int format,
+ char *pBits);
+static RegionPtr rwoutCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h,
+ int dstx, int dsty);
+static RegionPtr rwoutCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h,
+ int dstx, int dsty, unsigned long plane);
+static void rwoutPolyPoint(DrawablePtr pDst, GCPtr pGC, int mode, int npt,
+ xPoint *pptInit);
+static void rwoutPolylines(DrawablePtr pDst, GCPtr pGC, int mode, int npt,
+ DDXPointPtr pptInit);
+static void rwoutPolySegment(DrawablePtr pDst, GCPtr pGC, int nseg,
+ xSegment *pSegs);
+static void rwoutPolyRectangle(DrawablePtr pDst, GCPtr pGC,
+ int nrects, xRectangle *pRects);
+static void rwoutPolyArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *parcs);
+static void rwoutFillPolygon(DrawablePtr pDst, GCPtr pGC, int shape, int mode,
+ int count, DDXPointPtr pPts);
+static void rwoutPolyFillRect(DrawablePtr pDst, GCPtr pGC,
+ int nrectFill, xRectangle *prectInit);
+static void rwoutPolyFillArc(DrawablePtr pDst, GCPtr pGC,
+ int narcs, xArc *parcs);
+static int rwoutPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+ int count, char *chars);
+static int rwoutPolyText16(DrawablePtr pDst, GCPtr pGC, int x, int y,
+ int count, unsigned short *chars);
+static void rwoutImageText8(DrawablePtr pDst, GCPtr pGC, int x, int y,
+ int count, char *chars);
+static void rwoutImageText16(DrawablePtr pDst, GCPtr pGC, int x, int y,
+ int count, unsigned short *chars);
+static void rwoutImageGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y,
+ unsigned int nglyph, CharInfoPtr *ppci,
+ pointer pglyphBase);
+static void rwoutPolyGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y,
+ unsigned int nglyph, CharInfoPtr *ppci,
+ pointer pglyphBase);
+static void rwoutPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
+ int w, int h, int x, int y);
+
+#define PROLOG(pScrPriv, field) \
+ (pScrPriv) = REMWIN_GET_SCRPRIV(pScreen); \
+ pScreen->field = (pScrPriv)->field;
+
+#define EPILOG(field, wrapper) \
+ pScreen->field = wrapper;
+
+#define FUNC_PROLOG(pGC, pGCPriv) \
+ (pGC)->funcs = (pGCPriv)->wrapFuncs; \
+ (pGC)->ops = (pGCPriv)->wrapOps;
+
+#define FUNC_EPILOG(pGC, pGcPriv) \
+ (pGCPriv)->wrapFuncs = (pGC)->funcs; \
+ (pGCPriv)->wrapOps = (pGC)->ops; \
+ (pGC)->funcs = &rwoutGCFuncs; \
+ (pGC)->ops = &rwoutGCOps;
+
+#define OPS_PROLOG(pGC) \
+ pGC->funcs = pGCPriv->wrapFuncs; \
+ pGC->ops = pGCPriv->wrapOps;
+
+#define OPS_EPILOG(pGC) \
+ pGCPriv->wrapFuncs = (pGC)->funcs; \
+ pGCPriv->wrapOps = (pGC)->ops; \
+ (pGC)->funcs = &rwoutGCFuncs; \
+ (pGC)->ops = &rwoutGCOps;
+
+#define TOP_LEVEL_WIN(pWin) \
+ ((pWin)->parent != NULL && (pWin)->parent->parent == NULL)
+
+/* TODO: not yet supporting input only windows */
+#define MANAGED_WIN(pWin) \
+ ((pWin)->drawable.type == DRAWABLE_WINDOW && \
+ TOP_LEVEL_WIN(pWin))
+
+/* An optimzation: perform all CopyAreas on the client side */
+static Bool clientSideCopies = FALSE;
+
+static Bool ignoreCopyAreaDamage = FALSE;
+
+static Bool rwoutCloseScreen (int i, ScreenPtr pScreen);
+
+static GCFuncs rwoutGCFuncs = {
+ rwoutValidateGC,
+ rwoutChangeGC,
+ rwoutCopyGC,
+ rwoutDestroyGC,
+ rwoutChangeClip,
+ rwoutDestroyClip,
+ rwoutCopyClip,
+};
+
+static GCOps rwoutGCOps = {
+ rwoutFillSpans,
+ rwoutSetSpans,
+ rwoutPutImage,
+ rwoutCopyArea,
+ rwoutCopyPlane,
+ rwoutPolyPoint,
+ rwoutPolylines,
+ rwoutPolySegment,
+ rwoutPolyRectangle,
+ rwoutPolyArc,
+ rwoutFillPolygon,
+ rwoutPolyFillRect,
+ rwoutPolyFillArc,
+ rwoutPolyText8,
+ rwoutPolyText16,
+ rwoutImageText8,
+ rwoutImageText16,
+ rwoutImageGlyphBlt,
+ rwoutPolyGlyphBlt,
+ rwoutPushPixels
+};
+
+static void
+rwoutWakeupHandler (int screenNum, pointer wakeupData,
+ unsigned long result, pointer pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[screenNum];
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ RwcommPtr pComm = pScrPriv->pComm;
+
+ if ((int)result >= 0) {
+ RWCOMM_CLIENT_MESSAGE_POLL(pComm, pReadMask);
+ }
+
+ pScreen->WakeupHandler = pScrPriv->WakeupHandler;
+ (*pScreen->WakeupHandler)(screenNum, wakeupData, result,
+ pReadmask);
+ pScreen->WakeupHandler = rwoutWakeupHandler;
+}
+
+Bool
+rwoutInitScreen (ScreenPtr pScreen) {
+
+ RemwinScreenPrivPtr pScrPriv;
+ RwcommPtr pComm;
+
+ /*
+ ** Workaround for a netbeans black window bug caused by a bug in Java 6 AWT.
+ ** This is fixed in Java 6 update 1 but not all Wonderland users are using
+ ** that version.
+ **
+ ** TODO: eventually can remove this.
+ */
+ SetVendorString("The X.Org Foundation and Sun Microsystems - an eXcursion into Wonderland");
+
+ if (remwinGeneration != serverGeneration)
+ {
+ remwinScreenIndex = AllocateScreenPrivateIndex();
+ if (remwinScreenIndex < 0) {
+ return FALSE;
+ }
+ remwinWinIndex = AllocateWindowPrivateIndex();
+ if (remwinWinIndex < 0) {
+ return FALSE;
+ }
+ remwinGCIndex = AllocateGCPrivateIndex();
+ if (remwinGCIndex < 0) {
+ return FALSE;
+ }
+ remwinGeneration = serverGeneration;
+ }
+
+ if (!AllocateWindowPrivate(pScreen, remwinWinIndex, sizeof(RemwinWindowPrivRec))) {
+ return FALSE;
+ }
+
+ if (!AllocateGCPrivate(pScreen, remwinGCIndex, sizeof(RemwinGCPrivRec))) {
+ return FALSE;
+ }
+
+ pScrPriv = (RemwinScreenPrivPtr)xalloc(sizeof(RemwinScreenPrivRec));
+ if (pScrPriv == NULL) {
+ return FALSE;
+ }
+ pScreen->devPrivates[remwinScreenIndex].ptr = (pointer)pScrPriv;
+
+ /* TODO: replace with ds */
+ pComm = rwcommsockCreate(pScreen);
+ if (pComm == NULL) {
+ return FALSE;
+ }
+ pScrPriv->pComm = pComm;
+
+ pScrPriv->CloseScreen = pScreen->CloseScreen;
+ pScrPriv->WakeupHandler = pScreen->WakeupHandler;
+ pScrPriv->CreateWindow = pScreen->CreateWindow;
+ pScrPriv->RealizeWindow = pScreen->RealizeWindow;
+ pScrPriv->UnrealizeWindow = pScreen->UnrealizeWindow;
+ pScrPriv->DestroyWindow = pScreen->DestroyWindow;
+ pScrPriv->PositionWindow = pScreen->PositionWindow;
+ pScrPriv->ResizeWindow = pScreen->ResizeWindow;
+ pScrPriv->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
+ pScrPriv->CreateGC = pScreen->CreateGC;
+ pScrPriv->DisplayCursor = pScreen->DisplayCursor;
+ pScrPriv->SetCursorPosition = pScreen->SetCursorPosition;
+
+ pScreen->CloseScreen = rwoutCloseScreen;
+ pScreen->WakeupHandler = rwoutWakeupHandler;
+ pScreen->CreateWindow = rwoutCreateWindow;
+ pScreen->DestroyWindow = rwoutDestroyWindow;
+ pScreen->RealizeWindow = rwoutRealizeWindow;
+ pScreen->UnrealizeWindow = rwoutUnrealizeWindow;
+ pScreen->ResizeWindow = rwoutResizeWindow;
+ pScreen->PositionWindow = rwoutPositionWindow;
+ pScreen->ChangeWindowAttributes = rwoutChangeWindowAttributes;
+ pScreen->CreateGC = rwoutCreateGC;
+ pScreen->DisplayCursor = rwoutDisplayCursor;
+ pScreen->SetCursorPosition = rwoutSetCursorPosition;
+
+ pScrPriv->pPixelBuf = NULL;
+ pScrPriv->pRleBuf = NULL;
+ pScrPriv->pManagedWindows = NULL;
+
+ pScrPriv->pWmClient = NULL;
+ pScrPriv->windowsAreDirty = FALSE;
+
+ {
+ char *ev = getenv(USE_RLE_ENV_VAR);
+ if (ev != NULL && !strcmp(ev, "true")) {
+ useRle24 = TRUE;
+ ErrorF("XRemWin: enabling run-length encoding\n");
+ }
+
+ ev = getenv(VERIFY_RLE_ENV_VAR);
+ if (ev != NULL && !strcmp(ev, "true")) {
+ rwRleVerifyPixels = TRUE;
+ ErrorF("XRemWin: enabling RLE verification\n");
+ }
+ }
+
+ return TRUE;
+}
+
+static Bool
+rwoutCloseScreen (int i, ScreenPtr pScreen)
+{
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ WindowPtr pWin;
+ RemwinWindowPrivPtr pWinPriv;
+ int status;
+
+ PROLOG(pScrPriv, CloseScreen);
+ status = (*pScreen->CloseScreen)(i, pScreen);
+ EPILOG(CloseScreen, rwoutCloseScreen);
+ if (!status) {
+ return FALSE;
+ }
+
+ if (pScrPriv->pPixelBuf != NULL) {
+ xfree(pScrPriv->pPixelBuf);
+ }
+ if (pScrPriv->pRleBuf != NULL) {
+ xfree(pScrPriv->pRleBuf);
+ }
+
+ pWin = pScrPriv->pManagedWindows;
+ while (pWin != NULL) {
+ pWinPriv = REMWIN_GET_WINPRIV(pWin);
+ pWin = pWinPriv->pWinNext;
+ REGION_UNINIT(pScreen, &pWinPriv->dirtyReg);
+ xfree(pWinPriv);
+ }
+
+ rwoutTimerDestroy(pScreen);
+
+ RWCOMM_DESTROY(pScrPriv->pComm);
+ pScrPriv->pComm = NULL;
+
+ return status;
+}
+
+/*
+** Dirty the entire window area (including the border).
+*/
+
+extern RESTYPE DamageExtType;
+
+typedef struct _rwoutDamage {
+ DamagePtr pDamage;
+ DrawablePtr pDrawable;
+ DamageReportLevel level;
+ XID id;
+} RwoutDamageRec, *RwoutDamagePtr;
+
+static void
+rwoutDamageReport (DamagePtr pDa, RegionPtr pRegion, void *closure)
+{
+ RwoutDamagePtr pDamage = closure;
+ WindowPtr pWin = (WindowPtr) pDamage->pDrawable;
+ RemwinWindowPrivPtr pWinPriv;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+
+ /*
+ ** If copying on the client side ignore any damage generated
+ ** while inside CopyArea functions.
+ */
+ if (ignoreCopyAreaDamage) {
+ return;
+ }
+
+ /*
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ PrintRegion(pScreen, pRegion);
+ ErrorF("\n");
+ */
+
+ pWinPriv = REMWIN_GET_WINPRIV(pWin);
+ REGION_UNION(pScreen, &pWinPriv->dirtyReg, &pWinPriv->dirtyReg, pRegion);
+
+ /*
+ ErrorF("Modified region = ");
+ PrintRegion(pScreen, &pWinPriv->dirtyReg);
+ ErrorF("\n");
+ */
+
+ pWinPriv->dirty = TRUE;
+ pScrPriv->windowsAreDirty = TRUE;
+}
+
+static void
+rwoutDamageDestroy (DamagePtr pDam, void *closure)
+{
+ RwoutDamagePtr pDamage = closure;
+
+ pDamage->pDamage = 0;
+ if (pDamage->id) {
+ FreeResource (pDamage->id, RT_NONE);
+ }
+}
+
+static Bool
+rwoutCreateWindowWrite (ScreenPtr pScreen, WindowPtr pWin)
+{
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ RwcommPtr pComm = pScrPriv->pComm;
+ char buf[CREATE_WINDOW_MESSAGE_SIZE];
+ unsigned char decorated;
+ short bw;
+ int wid;
+ short x, y;
+ int wAndBorder, hAndBorder;
+ int n;
+
+ if (!RWCOMM_IS_CONNECTED(pComm)) {
+ return TRUE;
+ }
+
+ decorated = (unsigned char) !pWin->overrideRedirect;
+ bw = pWin->borderWidth;
+ wid = pWin->drawable.id;
+ x = pWin->drawable.x;
+ y = pWin->drawable.y;
+ wAndBorder = pWin->drawable.width + 2 * pWin->borderWidth;
+ hAndBorder = pWin->drawable.height + 2 * pWin->borderWidth;
+
+#ifdef VERBOSE
+ ErrorF("*** CreateWindow, id = %d, decor = %d, xy %d, %d, whAndBorder = %d, %d, bw = %d\n",
+ wid, decorated, x, y, wAndBorder, hAndBorder, bw);
+#endif /* VERBOSE */
+
+ swaps(&bw, n);
+ swapl(&wid, n);
+ swaps(&x, n);
+ swaps(&y, n);
+ swapl(&wAndBorder, n);
+ swapl(&hAndBorder, n);
+
+ CREATE_WINDOW_MESSAGE_SET_TYPE(buf, SERVER_MESSAGE_TYPE_CREATE_WINDOW);
+ CREATE_WINDOW_MESSAGE_SET_DECORATED(buf, decorated);
+ CREATE_WINDOW_MESSAGE_SET_BORDER_WIDTH(buf, bw);
+ CREATE_WINDOW_MESSAGE_SET_WID(buf, wid);
+ CREATE_WINDOW_MESSAGE_SET_X(buf, x);
+ CREATE_WINDOW_MESSAGE_SET_Y(buf, y);
+ CREATE_WINDOW_MESSAGE_SET_WANDBORDER(buf, wAndBorder);
+ CREATE_WINDOW_MESSAGE_SET_HANDBORDER(buf, hAndBorder);
+
+ if (!RWCOMM_BUFFER_WRITE(pComm, buf, CREATE_WINDOW_MESSAGE_SIZE)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static Bool
+rwoutDestroyWindowWrite (ScreenPtr pScreen, WindowPtr pWin)
+{
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ RwcommPtr pComm = pScrPriv->pComm;
+ char buf[DESTROY_WINDOW_MESSAGE_SIZE];
+ int wid;
+ int n;
+
+ if (!RWCOMM_IS_CONNECTED(pComm)) {
+ return TRUE;
+ }
+
+ wid = pWin->drawable.id;
+
+#ifdef VERBOSE
+ ErrorF("*** DestroyWindow, id = %d\n", wid);
+#endif /* VERBOSE */
+
+ swapl(&wid, n);
+
+ DESTROY_WINDOW_MESSAGE_SET_TYPE(buf, SERVER_MESSAGE_TYPE_DESTROY_WINDOW);
+ DESTROY_WINDOW_MESSAGE_SET_WID(buf, wid);
+
+ if (!RWCOMM_BUFFER_WRITE(pComm, buf, DESTROY_WINDOW_MESSAGE_SIZE)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static Bool
+rwoutShowWindowWrite (ScreenPtr pScreen, WindowPtr pWin, int show)
+{
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ RwcommPtr pComm = pScrPriv->pComm;
+ char buf[SHOW_WINDOW_MESSAGE_SIZE];
+ int wid;
+ int n;
+
+ if (!RWCOMM_IS_CONNECTED(pComm)) {
+ return TRUE;
+ }
+
+ wid = pWin->drawable.id;
+
+#ifdef VERBOSE
+ ErrorF("*** ShowWindow, id = %d, show = %d\n", wid, show);
+#endif /* VERBOSE */
+
+ swapl(&wid, n);
+
+ SHOW_WINDOW_MESSAGE_SET_TYPE(buf, SERVER_MESSAGE_TYPE_SHOW_WINDOW);
+ SHOW_WINDOW_MESSAGE_SET_SHOW(buf, (unsigned char)show);
+ SHOW_WINDOW_MESSAGE_SET_WID(buf, wid);
+
+ if (!RWCOMM_BUFFER_WRITE(pComm, buf, SHOW_WINDOW_MESSAGE_SIZE)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static Bool
+rwoutConfigureWindowWrite (ScreenPtr pScreen, WindowPtr pWin, int x, int y,
+ unsigned int wAndBorder, unsigned int hAndBorder,
+ WindowPtr pSib)
+{
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ RwcommPtr pComm = pScrPriv->pComm;
+ char buf[CONFIGURE_WINDOW_MESSAGE_SIZE];
+ int clientId;
+ int wid;
+ short xval, yval;
+ int wandb, handb;
+ int sibid;
+ int n;
+
+ if (!RWCOMM_IS_CONNECTED(pComm)) {
+ return TRUE;
+ }
+
+
+ clientId = pScrPriv->configuringClient;
+ wid = pWin->drawable.id;
+ xval = x;
+ yval = y;
+ wandb = wAndBorder;
+ handb = hAndBorder;
+ sibid = INVALID;
+ if (pSib != NULL) {
+ sibid = pSib->drawable.id;
+ }
+
+#ifdef VERBOSE
+ ErrorF("*** ConfigureWindow, clientId = %d, wid = %d, xy = %d, %d, whAndBorder = %d, %d",
+ clientId, wid, xval, yval, wandb, handb);
+ if (pSib != NULL) {
+ ErrorF(", pSib id = %d", sibid);
+ }
+ ErrorF("\n");
+#endif /* VERBOSE */
+
+ swapl(&clientId, n);
+ swapl(&wid, n);
+ swaps(&xval, n);
+ swaps(&yval, n);
+ swapl(&wandb, n);
+ swapl(&handb, n);
+ swapl(&sibid, n);
+
+ CONFIGURE_WINDOW_MESSAGE_SET_TYPE(buf, SERVER_MESSAGE_TYPE_CONFIGURE_WINDOW);
+ CONFIGURE_WINDOW_MESSAGE_SET_CLIENT_ID(buf, clientId);
+ CONFIGURE_WINDOW_MESSAGE_SET_WID(buf, wid);
+ CONFIGURE_WINDOW_MESSAGE_SET_X(buf, xval);
+ CONFIGURE_WINDOW_MESSAGE_SET_Y(buf, yval);
+ CONFIGURE_WINDOW_MESSAGE_SET_WANDBORDER(buf, wandb);
+ CONFIGURE_WINDOW_MESSAGE_SET_HANDBORDER(buf, handb);
+ CONFIGURE_WINDOW_MESSAGE_SET_SIBID(buf, sibid);
+
+ if (!RWCOMM_BUFFER_WRITE(pComm, buf, CONFIGURE_WINDOW_MESSAGE_SIZE)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool
+rwoutPositionWindowWrite (ScreenPtr pScreen, WindowPtr pWin, int x, int y)
+{
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ RwcommPtr pComm = pScrPriv->pComm;
+ char buf[POSITION_WINDOW_MESSAGE_SIZE];
+ int clientId;
+ int wid;
+ short xval, yval;
+ int n;
+
+ if (!RWCOMM_IS_CONNECTED(pComm)) {
+ return TRUE;
+ }
+
+ clientId = pScrPriv->configuringClient;
+ wid = pWin->drawable.id;
+ xval = x;
+ yval = y;
+
+#ifdef VERBOSE
+ ErrorF("*** PositionWindow, clientId = %d, wid = %d, xy = %d, %d\n",
+ clientId, wid, xval, yval);
+#endif /* VERBOSE */
+
+ swapl(&clientId, n);
+ swapl(&wid, n);
+ swaps(&xval, n);
+ swaps(&yval, n);
+
+ POSITION_WINDOW_MESSAGE_SET_TYPE(buf, SERVER_MESSAGE_TYPE_POSITION_WINDOW);
+ POSITION_WINDOW_MESSAGE_SET_CLIENT_ID(buf, clientid);
+ POSITION_WINDOW_MESSAGE_SET_WID(buf, wid);
+ POSITION_WINDOW_MESSAGE_SET_X(buf, xval);
+ POSITION_WINDOW_MESSAGE_SET_Y(buf, yval);
+
+ if (!RWCOMM_BUFFER_WRITE(pComm, buf, POSITION_WINDOW_MESSAGE_SIZE)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static Bool
+rwoutWindowSetDecoratedWrite(ScreenPtr pScreen, WindowPtr pWin)
+{
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ RwcommPtr pComm = pScrPriv->pComm;
+ char buf[WINDOW_SET_DECORATED_MESSAGE_SIZE];
+ unsigned char decorated;
+ int wid;
+ int n;
+
+ if (!RWCOMM_IS_CONNECTED(pComm)) {
+ return TRUE;
+ }
+
+ decorated = (unsigned char) !pWin->overrideRedirect;
+ wid = pWin->drawable.id;
+
+#ifdef VERBOSE
+ ErrorF("*** WindowSetDecorated, id = %d, decorated = %d\n",
+ wid, decorated);
+#endif /* VERBOSE */
+
+ swapl(&wid, n);
+
+ WINDOW_SET_DECORATED_MESSAGE_SET_TYPE(buf, SERVER_MESSAGE_TYPE_WINDOW_SET_DECORATED);
+ WINDOW_SET_DECORATED_MESSAGE_SET_DECORATED(buf, decorated);
+ WINDOW_SET_DECORATED_MESSAGE_SET_WID(buf, wid);
+
+ if (!RWCOMM_BUFFER_WRITE(pComm, buf, WINDOW_SET_DECORATED_MESSAGE_SIZE)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static Bool
+rwoutWindowSetBorderWidthWrite(ScreenPtr pScreen, WindowPtr pWin)
+{
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ RwcommPtr pComm = pScrPriv->pComm;
+ char buf[WINDOW_SET_DECORATED_MESSAGE_SIZE];
+ short bw;
+ int wid;
+ int n;
+
+ if (!RWCOMM_IS_CONNECTED(pComm)) {
+ return TRUE;
+ }
+
+ bw = pWin->borderWidth;
+ wid = pWin->drawable.id;
+
+#ifdef VERBOSE
+ ErrorF("*** WindowSetBorderWidth, id = %d, bw = %d\n", wid, bw);
+#endif /* VERBOSE */
+
+ swapl(&wid, n);
+ swaps(&bw, n);
+
+ WINDOW_SET_BORDER_WIDTH_MESSAGE_SET_TYPE(buf, SERVER_MESSAGE_TYPE_WINDOW_SET_BORDER_WIDTH);
+ WINDOW_SET_BORDER_WIDTH_MESSAGE_SET_BORDER_WIDTH(buf, bw);
+ WINDOW_SET_BORDER_WIDTH_MESSAGE_SET_WID(buf, wid);
+
+ if (!RWCOMM_BUFFER_WRITE(pComm, buf, WINDOW_SET_BORDER_WIDTH_MESSAGE_SIZE)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+** Search up the window tree (starting at the given window's parent)
+** until we find a window that is managed. Return NULL if no managed
+** window is found.
+*/
+
+static WindowPtr
+findManagedWindow (WindowPtr pWin)
+{
+ pWin = pWin->parent;
+
+ while (pWin != NULL) {
+ if (MANAGED_WIN(pWin)) {
+ return pWin;
+ }
+ pWin = pWin->parent;
+ }
+
+ return NULL;
+}
+
+static Bool
+rwoutCopyAreaWrite (WindowPtr pWin, int srcx, int srcy, int width, int height,
+ int dstx, int dsty)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ RwcommPtr pComm = pScrPriv->pComm;
+ char buf[COPY_AREA_MESSAGE_SIZE];
+ int sx, sy;
+ int w, h;
+ int dx, dy;
+ int wid;
+ int n;
+
+ if (!RWCOMM_IS_CONNECTED(pComm)) {
+ return TRUE;
+ }
+
+ wid = pWin->drawable.id;
+ sx = srcx;
+ sy = srcy;
+ w = width;
+ h = height;
+ dx = dstx;
+ dy = dsty;
+
+#ifdef VERBOSE
+ ErrorF("*** CopyArea id = %d, srcxy = %d, %d, wh = %d, %d, dstxy = %d, %d\n",
+ wid, sx, sy, w, h, dx, dy);
+#endif /* VERBOSE */
+
+ swapl(&wid, n);
+ swapl(&sx, n);
+ swapl(&sy, n);
+ swapl(&w, n);
+ swapl(&h, n);
+ swapl(&dx, n);
+ swapl(&dy, n);
+
+ COPY_AREA_MESSAGE_SET_TYPE(buf, SERVER_MESSAGE_TYPE_COPY_AREA);
+ COPY_AREA_MESSAGE_SET_WID(buf, wid);
+ COPY_AREA_MESSAGE_SET_SRCX(buf, sx);
+ COPY_AREA_MESSAGE_SET_SRCY(buf, sy);
+ COPY_AREA_MESSAGE_SET_WIDTH(buf, w);
+ COPY_AREA_MESSAGE_SET_HEIGHT(buf, h);
+ COPY_AREA_MESSAGE_SET_DSTX(buf, dx);
+ COPY_AREA_MESSAGE_SET_DSTY(buf, dy);
+
+ if (!RWCOMM_BUFFER_WRITE(pComm, buf, COPY_AREA_MESSAGE_SIZE)) {
+ return FALSE;
+ }
+
+ return TRUE;
+
+}
+
+static Bool
+rwoutUncodedPixelsWrite (ScreenPtr pScreen, WindowPtr pWin, int x, int y, int w, int h)
+{
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ RwcommPtr pComm = pScrPriv->pComm;
+ char buf[DIRTY_AREA_RECT_SIZE];
+ DirtyAreaRectPtr pDirty = (DirtyAreaRectPtr) &buf[0];
+ unsigned char *pPixels;
+ int n, i;
+ /* Debug
+ int linesSent = 0;
+ */
+
+ /* Size of chunk (in bytes) */
+ int chunkSize;
+
+ /* Size of chunk (in scan lines) */
+ int chunkHeight;
+
+ /* Number of full chunks that need to be sent */
+ int numChunks;
+
+#ifdef VERBOSE
+ ErrorF("uncoded rxywh = %d, %d, %d, %d\n", x, y, w, h);
+#endif /* VERBOSE */
+
+ /* First, send the information describing the dirty area */
+
+ pDirty->x = x;
+ pDirty->y = y;
+ pDirty->width = w;
+ pDirty->height = h;
+ pDirty->encodingType = DISPLAY_PIXELS_ENCODING_UNCODED;
+
+ swaps(&pDirty->x, n);
+ swaps(&pDirty->y, n);
+ swaps(&pDirty->width, n);
+ swaps(&pDirty->height, n);
+ swapl(&pDirty->encodingType, n);
+
+ /* Send it off */
+ if (!RWCOMM_BUFFER_WRITE(pComm, buf, DIRTY_AREA_RECT_SIZE)) {
+ return FALSE;
+ }
+
+ /* Lazy allocation of pixel buffer*/
+ if (pScrPriv->pPixelBuf == NULL) {
+ pScrPriv->pPixelBuf = (unsigned char *)
+ xalloc(PIXEL_BUF_MAX_NUM_BYTES);
+ }
+ pPixels = pScrPriv->pPixelBuf;
+
+ chunkHeight = PIXEL_BUF_MAX_NUM_PIXELS / w;
+ numChunks = h / chunkHeight;
+ chunkSize = w * chunkHeight * 4;
+ /*
+ ErrorF("chunkHeight = %d\n", chunkHeight);
+ ErrorF("numChunks (full) = %d\n", numChunks);
+ ErrorF("chunkSize = %d\n", chunkSize);
+ */
+
+ for (i = 0; i < numChunks; i++, h -= chunkHeight, y += chunkHeight) {
+
+ /*
+ ErrorF("Send full chunk %d: xywh = %d, %d, %d, %d\n",
+ i+1, x, y, w, chunkHeight);
+ */
+
+ /* Fetch chunk from frame buffer */
+ (*pScreen->GetImage)((DrawablePtr)pWin, x, y, w, chunkHeight,
+ ZPixmap, ~0, (char *)pPixels);
+
+ /* Send chunk */
+ if (!RWCOMM_BUFFER_WRITE(pComm, (char *)pPixels, chunkSize)) {
+ return FALSE;
+ }
+
+ /* Debug
+ linesSent += chunkHeight;
+ */
+ }
+
+ /* Send partial chunk at the end if necessary */
+ if (h > 0) {
+ /*
+ ErrorF("Send partial chunk xywh = %d, %d, %d, %d\n",
+ x, y, w, h);
+ */
+ chunkSize = w * h * 4;
+ (*pScreen->GetImage)((DrawablePtr)pWin, x, y, w, h,
+ ZPixmap, ~0, (char *)pPixels);
+ /*bytesSent += chunkSize;*/
+ if (!RWCOMM_BUFFER_WRITE(pComm, (char *)pPixels, chunkSize)) {
+ return FALSE;
+ }
+
+ /* Debug
+ linesSent += h;
+ */
+ }
+
+ /*
+ ErrorF("linesSent = %d\n", linesSent);
+ */
+
+ return TRUE;
+}
+
+static Bool
+rwoutWindowPixelsWrite (ScreenPtr pScreen, WindowPtr pWin, RemwinWindowPrivPtr pWinPriv)
+{
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ RwcommPtr pComm = pScrPriv->pComm;
+ char buf[DISPLAY_PIXELS_MESSAGE_SIZE];
+ RegionPtr pRegDirty = &pWinPriv->dirtyReg;
+ int numDirty, numDirtyRects;
+ int dx = pWin->drawable.x;
+ int dy = pWin->drawable.y;
+ BoxPtr pBox;
+ int wid;
+ int i, n;
+
+ /* If window is no longer mapped, skip the messages */
+ if (!pWin->mapped) {
+ return TRUE;
+ }
+
+ /*
+ ** Make dirty region screen absolute and constrain it to
+ ** lie within the window (Not sure if this is strictly
+ ** necessary but we'll do it for safety).
+ */
+ REGION_TRANSLATE(pScreen, pRegDirty, dx, dy);
+ REGION_INTERSECT(pScreen, pRegDirty, pRegDirty, &pWin->borderSize);
+ REGION_TRANSLATE(pScreen, pRegDirty, -dx, -dy);
+
+ /* Bail out early if nothing is left */
+ if (!REGION_NOTEMPTY(pScreen, pRegDirty)) {
+ REGION_NULL(pScreen, pRegDirty);
+ return TRUE;
+ }
+
+ /*
+ ** Send the message header
+ */
+
+ numDirty = REGION_NUM_RECTS(pRegDirty);
+ numDirtyRects = numDirty;
+ wid = pWin->drawable.id;
+
+#ifdef VERBOSE
+ ErrorF("Send dirty pixels for wid = %d, numDirty = %d\n",
+ wid, numDirty);
+#endif /* VERBOSE */
+
+ swaps(&numDirty, n);
+ swapl(&wid, n);
+
+ DISPLAY_PIXELS_MESSAGE_SET_TYPE(buf, SERVER_MESSAGE_TYPE_DISPLAY_PIXELS);
+ DISPLAY_PIXELS_MESSAGE_SET_NUM_DIRTY(buf, numDirty);
+ DISPLAY_PIXELS_MESSAGE_SET_WID(buf, wid);
+
+ /* Send it off */
+ if (!RWCOMM_BUFFER_WRITE(pComm, buf, DISPLAY_PIXELS_MESSAGE_SIZE)) {
+ return FALSE;
+ }
+
+ pBox = REGION_RECTS(pRegDirty);
+ for (i = 0; i < numDirtyRects; i++, pBox++) {
+ if (useRle24) {
+ if (!rlePixelsWrite(pScreen, pWin, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1)) {
+ REGION_UNINIT(pScreen, pRegDirty);
+ return FALSE;
+ }
+ if (rwRleVerifyPixels) {
+ if (!rwoutUncodedPixelsWrite(pScreen, pWin, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1)) {
+ REGION_UNINIT(pScreen, pRegDirty);
+ return FALSE;
+ }
+ }
+ } else {
+ if (!rwoutUncodedPixelsWrite(pScreen, pWin, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1)) {
+ REGION_UNINIT(pScreen, pRegDirty);
+ return FALSE;
+ }
+ }
+ }
+
+ REGION_NULL(pScreen, pRegDirty);
+
+ return TRUE;
+}
+
+static Bool
+rwoutPixelsWrite (ScreenPtr pScreen)
+{
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ WindowPtr pWin;
+ RemwinWindowPrivPtr pWinPriv;
+
+ pWin = pScrPriv->pManagedWindows;
+ while (pWin != NULL) {
+ pWinPriv = REMWIN_GET_WINPRIV(pWin);
+
+ if (pWinPriv->dirty) {
+ if (!rwoutWindowPixelsWrite(pScreen, pWin, pWinPriv)) {
+ return FALSE;
+ }
+ }
+
+ pWinPriv->dirty = !REGION_NOTEMPTY(pWin->pScreen, &pWinPriv->dirtyReg);
+ pScrPriv->windowsAreDirty = pScrPriv->windowsAreDirty || pWinPriv->dirty;
+
+ pWin = pWinPriv->pWinNext;
+ }
+
+ return TRUE;
+}
+
+/* Same as xfixes/cursor.c:GetBit */
+static int
+GetBit (unsigned char *line, int x)
+{
+ unsigned char mask;
+
+ if (screenInfo.bitmapBitOrder == LSBFirst)
+ mask = (1 << (x & 7));
+ else
+ mask = (0x80 >> (x & 7));
+ /* XXX assumes byte order is host byte order */
+ line += (x >> 3);
+ if (*line & mask)
+ return 1;
+ return 0;
+}
+
+/* Same as xfixes/cursor.c:CopyCursorToImage */
+static void
+CopyCursorToImage (CursorPtr pCursor, CARD32 *image)
+{
+ int width = pCursor->bits->width;
+ int height = pCursor->bits->height;
+ int npixels = width * height;
+
+#ifdef ARGB_CURSOR
+ if (pCursor->bits->argb)
+ memcpy (image, pCursor->bits->argb, npixels * sizeof (CARD32));
+ else
+#endif
+ {
+ unsigned char *srcLine = pCursor->bits->source;
+ unsigned char *mskLine = pCursor->bits->mask;
+ int stride = BitmapBytePad (width);
+ int x, y;
+ CARD32 fg, bg;
+
+ fg = (0xff000000 |
+ ((pCursor->foreRed & 0xff00) << 8) |
+ (pCursor->foreGreen & 0xff00) |
+ (pCursor->foreBlue >> 8));
+ bg = (0xff000000 |
+ ((pCursor->backRed & 0xff00) << 8) |
+ (pCursor->backGreen & 0xff00) |
+ (pCursor->backBlue >> 8));
+ for (y = 0; y < height; y++)
+ {
+ for (x = 0; x < width; x++)
+ {
+ if (GetBit (mskLine, x))
+ {
+ if (GetBit (srcLine, x))
+ *image++ = fg;
+ else
+ *image++ = bg;
+ }
+ else
+ *image++ = 0;
+ }
+ srcLine += stride;
+ mskLine += stride;
+ }
+ }
+}
+
+static Bool
+rwoutDisplayCursorWrite (ScreenPtr pScreen, CursorPtr pCursor)
+{
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ RwcommPtr pComm = pScrPriv->pComm;
+ char buf[DISPLAY_CURSOR_MESSAGE_SIZE];
+ short w, h;
+ short xh, yh;
+ int npixels;
+ CARD32 *pImage;
+ int imageSize;
+ int n;
+
+ if (!RWCOMM_IS_CONNECTED(pComm)) {
+ return TRUE;
+ }
+
+ /*
+ ** First write message header
+ */
+
+ w = pCursor->bits->width;
+ h = pCursor->bits->height;
+ xh = pCursor->bits->xhot;
+ yh = pCursor->bits->yhot;
+
+#ifdef VERBOSE
+ ErrorF("*** DisplayCursor wh = %d, %d, xyhot = %d, %d\n",
+ w, h, xh, yh);
+#endif /* VERBOSE */
+
+ swaps(&w, n);
+ swaps(&h, n);
+ swaps(&xh, n);
+ swaps(&yh, n);
+
+ DISPLAY_CURSOR_MESSAGE_SET_TYPE(buf, SERVER_MESSAGE_TYPE_DISPLAY_CURSOR);
+ DISPLAY_CURSOR_MESSAGE_SET_WIDTH(buf, w);
+ DISPLAY_CURSOR_MESSAGE_SET_HEIGHT(buf, h);
+ DISPLAY_CURSOR_MESSAGE_SET_XHOT(buf, xh);
+ DISPLAY_CURSOR_MESSAGE_SET_YHOT(buf, yh);
+
+ if (!RWCOMM_BUFFER_WRITE(pComm, buf, DISPLAY_CURSOR_MESSAGE_SIZE)) {
+ return FALSE;
+ }
+
+ /*
+ ** Then convert the cursor to a 32-bit pixel image and send.
+ */
+
+ w = pCursor->bits->width;
+ h = pCursor->bits->height;
+ npixels = w * h;
+ imageSize = npixels * sizeof (CARD32);
+
+ pImage = xalloc(imageSize);
+ if (pImage == NULL) {
+ return FALSE;
+ }
+
+ CopyCursorToImage(pCursor, pImage);
+
+ if (!RWCOMM_BUFFER_WRITE(pComm, (char *)pImage, imageSize)) {
+ return FALSE;
+ }
+
+ xfree(pImage);
+
+ return TRUE;
+}
+
+static Bool
+rwoutMoveCursorWrite (ScreenPtr pScreen, WindowPtr pWin, int x, int y)
+{
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ RwcommPtr pComm = pScrPriv->pComm;
+ char buf[MOVE_CURSOR_MESSAGE_SIZE];
+ int wid;
+ int cx, cy;
+ int n;
+
+ if (!RWCOMM_IS_CONNECTED(pComm)) {
+ return TRUE;
+ }
+
+ wid = pWin->drawable.id;
+ cx = x;
+ cy = y;
+
+#ifdef VERBOSE
+ ErrorF("*** MoveCursor: wid = %d, xy = %d, %d\n", wid, cx, cy);
+#endif /* VERBOSE */
+
+ swapl(&wid, n);
+ swapl(&cx, n);
+ swapl(&cy, n);
+
+ MOVE_CURSOR_MESSAGE_SET_TYPE(buf, SERVER_MESSAGE_TYPE_MOVE_CURSOR);
+ MOVE_CURSOR_MESSAGE_SET_WID(buf, wid);
+ MOVE_CURSOR_MESSAGE_SET_X(buf, cx);
+ MOVE_CURSOR_MESSAGE_SET_Y(buf, cy);
+
+ if (!RWCOMM_BUFFER_WRITE(pComm, buf, MOVE_CURSOR_MESSAGE_SIZE)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static Bool
+rwoutShowCursorWrite (ScreenPtr pScreen, Bool show)
+{
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ RwcommPtr pComm = pScrPriv->pComm;
+ char buf[SHOW_CURSOR_MESSAGE_SIZE];
+ char showit = show ? 1 : 0;
+
+ if (!RWCOMM_IS_CONNECTED(pComm)) {
+ return TRUE;
+ }
+
+#ifdef VERBOSE
+ ErrorF("*** ShowCursor: show = %d\n", showit);
+#endif /* VERBOSE */
+
+ SHOW_CURSOR_MESSAGE_SET_TYPE(buf, SERVER_MESSAGE_TYPE_SHOW_CURSOR);
+ SHOW_CURSOR_MESSAGE_SET_SHOW(buf, showit);
+
+ if (!RWCOMM_BUFFER_WRITE(pComm, buf, SHOW_CURSOR_MESSAGE_SIZE)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool
+rwoutSetWindowTitlesWrite (ScreenPtr pScreen, int strLen, char *buf)
+{
+ /* TODO: this causes sol new to fail */
+#ifdef NOTYET
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ RwcommPtr pComm = pScrPriv->pComm;
+ char hdrBuf[SET_WINDOW_TITLES_MESSAGE_SIZE];
+
+ if (!RWCOMM_IS_CONNECTED(pComm)) {
+ return TRUE;
+ }
+
+#ifdef VERBOSE
+ ErrorF("*** SetWindowTitles: strLen = %d\n", strLen);
+#endif /* VERBOSE */
+
+ /* First send the length */
+ SET_WINDOW_TITLES_MESSAGE_SET_TYPE(hdrBuf, SERVER_MESSAGE_TYPE_SET_WINDOW_TITLES);
+ SET_WINDOW_TITLES_MESSAGE_SET_STRLEN(hdrBuf, strLen);
+ if (!RWCOMM_BUFFER_WRITE(pComm, hdrBuf, SET_WINDOW_TITLES_MESSAGE_SIZE)) {
+ return FALSE;
+ }
+
+ /* Then send the string */
+ if (!RWCOMM_BUFFER_WRITE(pComm, buf, strLen)) {
+ return FALSE;
+ }
+#endif /* NOTYET */
+
+ return TRUE;
+}
+
+static Bool
+rwoutCreateWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ RemwinWindowPrivPtr pWinPriv = REMWIN_GET_WINPRIV(pWin);
+ RwoutDamagePtr pDamage;
+ Bool ret;
+
+ PROLOG(pScrPriv, CreateWindow);
+ ret = (*pScreen->CreateWindow)(pWin);
+ EPILOG(CreateWindow, rwoutCreateWindow);
+ if (!ret) {
+ return FALSE;
+ }
+
+ if (!MANAGED_WIN(pWin)) {
+ return TRUE;
+ }
+
+ pDamage = xalloc(sizeof(RwoutDamageRec));
+ if (pDamage == NULL) {
+ return BadAlloc;
+ }
+ pDamage->id = pWin->drawable.id;
+ pDamage->pDrawable = (DrawablePtr) pWin;
+ pDamage->level = DamageReportRawRegion;
+ pDamage->pDamage = DamageCreate (rwoutDamageReport, rwoutDamageDestroy, pDamage->level,
+ FALSE, pWin->drawable.pScreen, pDamage);
+ if (!pDamage->pDamage)
+ {
+ xfree (pDamage);
+ return FALSE;;
+ }
+ if (!AddResource (pDamage->id, DamageExtType, (pointer) pDamage)) {
+ xfree (pDamage);
+ return FALSE;
+ }
+
+ DamageRegister(pDamage->pDrawable, pDamage->pDamage);
+
+ /* Initial damage must include border */
+ RegionPtr pRegion = &pWin->borderClip;
+ DamageDamageRegion((DrawablePtr)pWin, pRegion);
+
+ if (!rwoutCreateWindowWrite(pScreen, pWin)) {
+ ErrorF("WARNING: could not notify clients of window creation for window %d\n",
+ (int)pWin->drawable.id);
+ return FALSE;
+ }
+
+ /* TODO: DELETE
+ pWinPriv = (RemwinWindowPrivPtr) xalloc(sizeof(RemwinWindowPrivRec));
+ if (pWinPriv == NULL) {
+ return FALSE;
+ }
+ REMWIN_SET_WINPRIV(pWin, pWinPriv);
+ */
+
+ REGION_NULL(pScreen, &pWinPriv->dirtyReg);
+ pWinPriv->mapped = FALSE;
+
+ /* Add to front of window list */
+ pWinPriv->pWinNext = pScrPriv->pManagedWindows;
+ pScrPriv->pManagedWindows = pWin;
+
+ return TRUE;
+}
+
+static Bool
+rwoutDestroyWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ RemwinWindowPrivPtr pWinPriv = REMWIN_GET_WINPRIV(pWin);
+ WindowPtr pW, pWPrev;
+ Bool ret;
+
+ PROLOG(pScrPriv, DestroyWindow);
+ ret = (*pScreen->DestroyWindow)(pWin);
+ EPILOG(DestroyWindow, rwoutDestroyWindow);
+ if (!ret) {
+ return FALSE;
+ }
+
+ if (!MANAGED_WIN(pWin) ||
+ pWinPriv == NULL) {
+ return TRUE;
+ }
+
+ /* Unlink from window list */
+ pWPrev = NULL;
+ pW = pScrPriv->pManagedWindows;
+ while (pW != NULL && pW != pWin) {
+ RemwinWindowPrivPtr pWPriv = REMWIN_GET_WINPRIV(pW);
+ pWPrev = pW;
+ pW = pWPriv->pWinNext;
+ }
+ if (pW != pWin) {
+ ErrorF("WARNING: cannot find window %d among managed windows\n",
+ (int)pWin->drawable.id);
+ EPILOG(DestroyWindow, rwoutDestroyWindow);
+ return FALSE;
+ }
+ pWinPriv = REMWIN_GET_WINPRIV(pW);
+ if (pWPrev == NULL) {
+ pScrPriv->pManagedWindows = pWinPriv->pWinNext;
+ } else {
+ RemwinWindowPrivPtr pWinPrivPrev = REMWIN_GET_WINPRIV(pWPrev)
+ pWinPrivPrev->pWinNext = pWinPriv->pWinNext;
+ }
+
+ REGION_UNINIT(pScreen, &pWinPriv->dirtyReg);
+
+ if (!rwoutDestroyWindowWrite(pScreen, pWin)) {
+ ErrorF("WARNING: could not notify clients of window destruction for window %d\n",
+ (int)pWin->drawable.id);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static Bool
+rwoutRealizeWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ Bool ret;
+ RemwinWindowPrivPtr pWinPriv = REMWIN_GET_WINPRIV(pWin);
+
+ PROLOG(pScrPriv, RealizeWindow);
+ ret = (*pScreen->RealizeWindow)(pWin);
+ EPILOG(RealizeWindow, rwoutRealizeWindow);
+ if (!ret) {
+ return FALSE;
+ }
+
+ if (!MANAGED_WIN(pWin)) {
+ return TRUE;
+ }
+
+ pWinPriv->mapped = TRUE;
+
+ if (!rwoutShowWindowWrite(pScreen, pWin, 1)) {
+ ErrorF("WARNING: could not notify clients of window mapping for window %d\n",
+ (int)pWin->drawable.id);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static Bool
+rwoutUnrealizeWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ Bool ret;
+ RemwinWindowPrivPtr pWinPriv = REMWIN_GET_WINPRIV(pWin);
+
+ PROLOG(pScrPriv, UnrealizeWindow);
+ ret = (*pScreen->UnrealizeWindow)(pWin);
+ EPILOG(UnrealizeWindow, rwoutUnrealizeWindow);
+ if (!ret) {
+ return FALSE;
+ }
+
+ if (!MANAGED_WIN(pWin)) {
+ return TRUE;
+ }
+
+ pWinPriv->mapped = FALSE;
+
+ /* The client no longer needs the pixels of this window. Clear the dirty regions */
+ pWinPriv->dirty = FALSE;
+ REGION_UNINIT(pScreen, &pWinPriv->dirtyReg);
+
+ if (!rwoutShowWindowWrite(pScreen, pWin, 0)) {
+ ErrorF("WARNING: could not notify clients of window unmapping for window %d\n",
+ (int)pWin->drawable.id);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+rwoutResizeWindow(WindowPtr pWin, int x, int y, unsigned int w, unsigned int h, WindowPtr pSib)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+
+ PROLOG(pScrPriv, ResizeWindow);
+ (*pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
+ EPILOG(ResizeWindow, rwoutResizeWindow);
+
+ if (!MANAGED_WIN(pWin)) {
+ return;
+ }
+
+ if (!rwoutConfigureWindowWrite(pScreen, pWin, x, y,
+ w + 2 * pWin->borderWidth, h + 2 * pWin->borderWidth,
+ pSib)) {
+ ErrorF("WARNING: could not notify clients of window move/resize/restack for window %d\n",
+ (int)pWin->drawable.id);
+ }
+}
+
+static Bool
+rwoutPositionWindow (WindowPtr pWin, int x, int y)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ Bool ret;
+
+ PROLOG(pScrPriv, PositionWindow);
+ ret = (*pScreen->PositionWindow)(pWin, x, y);
+ EPILOG(PositionWindow, rwoutPositionWindow);
+ if (!ret) {
+ return FALSE;
+ }
+
+ if (!MANAGED_WIN(pWin)) {
+ return TRUE;
+ }
+
+ if (!rwoutPositionWindowWrite(pScreen, pWin, x, y)) {
+ ErrorF("WARNING: could not notify clients of window move for window %d\n",
+ (int)pWin->drawable.id);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static Bool
+rwoutChangeWindowAttributes (WindowPtr pWin, Mask vmask)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ Bool ret;
+
+ PROLOG(pScrPriv, ChangeWindowAttributes);
+ ret = (*pScreen->ChangeWindowAttributes)(pWin, vmask);
+ EPILOG(ChangeWindowAttributes, rwoutChangeWindowAttributes);
+ if (!ret) {
+ return FALSE;
+ }
+
+ /* TODO: not yet supporting input only windows */
+ if (pWin->drawable.type == UNDRAWABLE_WINDOW ||
+ !MANAGED_WIN(pWin)) {
+ return TRUE;
+ }
+
+ if ((vmask & CWOverrideRedirect) != 0 &&
+ !rwoutWindowSetDecoratedWrite(pScreen, pWin)) {
+ ErrorF("WARNING: could not notify clients of decorated change for window %d\n",
+ (int)pWin->drawable.id);
+ return FALSE;
+ }
+
+ if ((vmask & CWBorderWidth) != 0 &&
+ !rwoutWindowSetBorderWidthWrite(pScreen, pWin)) {
+ ErrorF("WARNING: could not notify clients of border width change for window %d\n",
+ (int)pWin->drawable.id);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void
+rwoutBeep (int percent, DeviceIntPtr pDevice,
+ pointer ctrl, int unused)
+{
+ /* TODO: for now */
+ ScreenPtr pScreen = screenInfo.screens[0];
+
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ RwcommPtr pComm = pScrPriv->pComm;
+ /* TODO: notyet
+ char buf[BEEP_MESSAGE_SIZE];
+ */
+
+ if (!RWCOMM_IS_CONNECTED(pComm)) {
+ return;
+ }
+
+#ifdef VERBOSE
+ ErrorF("*** Beep\n");
+#endif /* VERBOSE */
+
+ /* TODO: bug this causes gt to hang
+ POSITION_WINDOW_MESSAGE_SET_TYPE(buf, SERVER_MESSAGE_TYPE_BEEP);
+
+ (void) RWCOMM_BUFFER_WRITE(pComm, buf, BEEP_MESSAGE_SIZE);
+ */
+}
+
+static Bool
+rwoutDisplayCursor (ScreenPtr pScreen, CursorPtr pCursor)
+{
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ Bool ret;
+
+ PROLOG(pScrPriv, DisplayCursor);
+ ret = (*pScreen->DisplayCursor)(pScreen, pCursor);
+ EPILOG(DisplayCursor, rwoutDisplayCursor);
+ if (!ret) {
+ return FALSE;
+ }
+
+ if (pCursor == pScrPriv->pCursor) {
+ return TRUE;
+ }
+
+ pScrPriv->pCursor = pCursor;
+
+ if (!rwoutDisplayCursorWrite(pScreen, pCursor)) {
+ ErrorF("WARNING: could not notify clients of new cursor\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static Bool
+rwoutSetCursorPosition (ScreenPtr pScreen, int x, int y, Bool generateEvent)
+{
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ WindowPtr pWin;
+ Bool ret;
+
+ PROLOG(pScrPriv, SetCursorPosition);
+ ret = (*pScreen->SetCursorPosition)(pScreen, x, y, generateEvent);
+ EPILOG(SetCursorPosition, rwoutSetCursorPosition);
+ if (!ret) {
+ return FALSE;
+ }
+
+ /* Determine whether cursor is in a managed window */
+ pWin = dixGetSpriteWindow();
+ if (!MANAGED_WIN(pWin)) {
+ pWin = findManagedWindow(pWin);
+ }
+ if (pWin == NULL) {
+
+ /* If window isn't in a manage window then disable cursor */
+ pScrPriv->pCursorWin = NULL;
+ if (!rwoutShowCursorWrite(pScreen, FALSE)) {
+ ErrorF("WARNING: could not notify clients of cursor not visible\n");
+ }
+ return TRUE;
+ }
+
+ /* Calculate window relative cursor position */
+ x -= pWin->drawable.x;
+ y -= pWin->drawable.y;
+
+ /* Show cursor if it is not currently shown */
+ if (pScrPriv->pCursorWin == NULL) {
+ if (!rwoutShowCursorWrite(pScreen, TRUE)) {
+ ErrorF("WARNING: could not notify clients of cursor made visible\n");
+ return FALSE;
+ }
+ }
+
+ pScrPriv->pCursorWin = pWin;
+ pScrPriv->cursorX = x;
+ pScrPriv->cursorY = y;
+
+ if (!rwoutMoveCursorWrite(pScreen, pWin, x, y)) {
+ ErrorF("WARNING: could not notify clients of cursor move in win %d\n",
+ (int)pWin->drawable.id);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+rwoutTimerReset (ScreenPtr pScreen)
+{
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ TimerSet(pScrPriv->outputTimer, 0, TIMER_MS, rwoutTimerCallback, pScreen);
+}
+
+static CARD32
+rwoutTimerCallback (OsTimerPtr timer, CARD32 now, pointer arg)
+{
+ ScreenPtr pScreen = (ScreenPtr) arg;
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+
+ if (pScrPriv->windowsAreDirty) {
+ rwoutPixelsWrite(pScreen);
+ pScrPriv->windowsAreDirty = FALSE;
+ }
+
+ /* Reenable for the next tick */
+ rwoutTimerReset(pScreen);
+
+ return 0;
+}
+
+void
+rwoutTimerCreate (ScreenPtr pScreen)
+{
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+
+ pScrPriv->outputTimer = NULL;
+ rwoutTimerReset(pScreen);
+}
+
+void
+rwoutTimerDestroy (ScreenPtr pScreen)
+{
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+
+ TimerFree(pScrPriv->outputTimer);
+ pScrPriv->outputTimer = NULL;
+}
+
+static Bool
+rwoutCreateGC (GCPtr pGC)
+{
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pGC->pScreen);
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+ ScreenPtr pScreen = pGC->pScreen;
+ Bool ret;
+
+ bzero(pGCPriv, sizeof(RemwinGCPrivRec));
+
+ PROLOG(pScrPriv, CreateGC);
+
+ if ((ret = (*pScreen->CreateGC)(pGC))) {
+ FUNC_EPILOG(pGC, pGCPriv);
+ }
+
+ EPILOG(CreateGC, rwoutCreateGC);
+
+ return ret;
+}
+
+static void
+rwoutValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+
+ FUNC_PROLOG(pGC, pGCPriv);
+
+ (*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable);
+
+ FUNC_EPILOG(pGC, pGCPriv);
+}
+
+static void
+rwoutChangeGC (GCPtr pGC, unsigned long mask)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+
+ FUNC_PROLOG(pGC, pGCPriv);
+
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+
+ FUNC_EPILOG(pGC, pGCPriv);
+}
+
+static void
+rwoutCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGCDst);
+
+ FUNC_PROLOG(pGCDst, pGCPriv);
+
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+
+ FUNC_EPILOG(pGCDst, pGCPriv);
+}
+
+static void
+rwoutDestroyGC(GCPtr pGC)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+
+ FUNC_PROLOG(pGC, pGCPriv);
+
+ (*pGC->funcs->DestroyGC) (pGC);
+
+ /* leave it unwrapped */
+}
+
+static void
+rwoutChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+
+ FUNC_PROLOG(pGC, pGCPriv);
+
+ (*pGC->funcs->ChangeClip)(pGC, type, pvalue, nrects);
+
+ FUNC_EPILOG(pGC, pGCPriv);
+}
+
+static void
+rwoutCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pgcDst);
+
+ FUNC_PROLOG(pgcDst, pGCPriv);
+
+ (*pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+
+ FUNC_EPILOG(pgcDst, pGCPriv);
+}
+
+static void
+rwoutDestroyClip(GCPtr pGC)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+
+ FUNC_PROLOG(pGC, pGCPriv);
+
+ (*pGC->funcs->DestroyClip)(pGC);
+
+ FUNC_EPILOG(pGC, pGCPriv);
+}
+
+static void
+rwoutFillSpans(DrawablePtr pDst, GCPtr pGC, int nspans, DDXPointPtr ppt,
+ int *pwidth, int fSorted)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+
+ OPS_PROLOG(pGC);
+
+ (*pGC->ops->FillSpans)(pDst, pGC, nspans, ppt, pwidth, fSorted);
+
+ OPS_EPILOG(pGC);
+}
+
+static void
+rwoutSetSpans(DrawablePtr pDst, GCPtr pGC, char *psrc, DDXPointPtr ppt,
+ int *pwidth, int nspans, int fSorted)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+
+ OPS_PROLOG(pGC);
+
+ (*pGC->ops->SetSpans)(pDst, pGC, psrc, ppt, pwidth, nspans, fSorted);
+
+ OPS_EPILOG(pGC);
+}
+
+static void
+rwoutPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y, int w, int h,
+ int leftPad, int format, char *pBits)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+
+ OPS_PROLOG(pGC);
+
+ (*pGC->ops->PutImage)(pDst, pGC, depth, x, y, w, h, leftPad, format, pBits);
+
+ OPS_EPILOG(pGC);
+}
+
+static RegionPtr
+rwoutCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy,
+ int w, int h, int dstx, int dsty)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+ RegionPtr exposed;
+ Bool clientCopy = FALSE;
+ WindowPtr pWin;
+
+ /*
+ ** Only do client-side copies when the destination is a managed window,
+ ** the src is the same as the dest, and the optimization is enabled.
+ */
+ if (clientSideCopies &&
+ pDst == pSrc &&
+ pDst->type == DRAWABLE_WINDOW) {
+ clientCopy = TRUE;
+ ignoreCopyAreaDamage = TRUE;
+ ErrorF("Use client side copy\n");
+ }
+
+ OPS_PROLOG(pGC);
+ exposed = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, srcx, srcy, w, h,
+ dstx, dsty);
+ OPS_EPILOG(pGC);
+ ignoreCopyAreaDamage = FALSE;
+
+ if (!clientCopy) {
+ return exposed;
+ }
+
+ /* Find the corresponding managed window */
+ pWin = findManagedWindow((WindowPtr)pDst);
+ if (pWin != (WindowPtr)pDst) {
+ /* Make the rectangles relative to the managed window */
+ int xOffset = pDst->x - pWin->drawable.x;
+ int yOffset = pDst->y - pWin->drawable.y;
+ srcx += xOffset;
+ srcy += yOffset;
+ dstx += xOffset;
+ dsty += yOffset;
+ }
+
+ if (!rwoutCopyAreaWrite((WindowPtr) pDst, srcx, srcy, w, h, dstx, dsty)) {
+ ErrorF("WARNING: could not notify clients of copy area for window %d\n",
+ (int)pDst->id);
+ return FALSE;
+ }
+
+ return exposed;
+}
+
+static RegionPtr
+rwoutCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy,
+ int w, int h, int dstx, int dsty, unsigned long plane)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+ RegionPtr exposed;
+
+ OPS_PROLOG(pGC);
+
+ exposed = (*pGC->ops->CopyPlane)(pSrc, pDst, pGC, srcx, srcy, w, h,
+ dstx, dsty, plane);
+
+ OPS_EPILOG(pGC);
+
+ return exposed;
+}
+
+static void
+rwoutPolyPoint(DrawablePtr pDst, GCPtr pGC, int mode, int npt, xPoint *ppt)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+
+ OPS_PROLOG(pGC);
+
+ (*pGC->ops->PolyPoint)(pDst, pGC, mode, npt, ppt);
+
+ OPS_EPILOG(pGC);
+}
+
+static void
+rwoutPolylines(DrawablePtr pDst, GCPtr pGC, int mode, int npt, DDXPointPtr ppt)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+
+ OPS_PROLOG(pGC);
+
+ (*pGC->ops->Polylines)(pDst, pGC, mode, npt, ppt);
+
+ OPS_EPILOG(pGC);
+}
+
+static void
+rwoutPolySegment(DrawablePtr pDst, GCPtr pGC, int nseg, xSegment *pSegs)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+
+ OPS_PROLOG(pGC);
+
+ (*pGC->ops->PolySegment)(pDst, pGC, nseg, pSegs);
+
+ OPS_EPILOG(pGC);
+}
+
+static void
+rwoutPolyRectangle(DrawablePtr pDst, GCPtr pGC, int nrects, xRectangle *pRects)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+
+ OPS_PROLOG(pGC);
+
+ (*pGC->ops->PolyRectangle)(pDst, pGC, nrects, pRects);
+
+ OPS_EPILOG(pGC);
+}
+
+static void
+rwoutPolyArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *pArcs)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+
+ OPS_PROLOG(pGC);
+
+ (*pGC->ops->PolyArc)(pDst, pGC, narcs, pArcs);
+
+ OPS_EPILOG(pGC);
+}
+
+static void
+rwoutFillPolygon(DrawablePtr pDst, GCPtr pGC, int shape, int mode, int npt,
+ DDXPointPtr ppt)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+
+ OPS_PROLOG(pGC);
+
+ (*pGC->ops->FillPolygon)(pDst, pGC, shape, mode, npt, ppt);
+
+ OPS_EPILOG(pGC);
+}
+
+static void
+rwoutPolyFillRect(DrawablePtr pDst, GCPtr pGC, int nrects, xRectangle *pRects)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+
+ OPS_PROLOG(pGC);
+
+ (*pGC->ops->PolyFillRect)(pDst, pGC, nrects, pRects);
+
+ OPS_EPILOG(pGC);
+}
+
+static void
+rwoutPolyFillArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *parcs)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+
+ OPS_PROLOG(pGC);
+
+ (*pGC->ops->PolyFillArc)(pDst, pGC, narcs, parcs);
+
+ OPS_EPILOG(pGC);
+}
+
+static int
+rwoutPolyText8(DrawablePtr pDst, GCPtr pGC, int x, int y, int count, char *chars)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+ int result;
+
+ OPS_PROLOG(pGC);
+
+ result = (*pGC->ops->PolyText8)(pDst, pGC, x, y, count, chars);
+
+ OPS_EPILOG(pGC);
+
+ return result;
+}
+
+static int
+rwoutPolyText16(DrawablePtr pDst, GCPtr pGC, int x, int y, int count,
+ unsigned short *chars)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+ int result;
+
+ OPS_PROLOG(pGC);
+
+ result = (*pGC->ops->PolyText16)(pDst, pGC, x, y, count, chars);
+
+ OPS_EPILOG(pGC);
+
+ return result;
+}
+
+static void
+rwoutImageText8(DrawablePtr pDst, GCPtr pGC, int x, int y, int count, char *chars)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+
+ OPS_PROLOG(pGC);
+
+ (*pGC->ops->ImageText8)(pDst, pGC, x, y, count, chars);
+
+ OPS_EPILOG(pGC);
+}
+
+static void
+rwoutImageText16(DrawablePtr pDst, GCPtr pGC, int x, int y, int count,
+ unsigned short *chars)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+
+ OPS_PROLOG(pGC);
+
+ (*pGC->ops->ImageText16)(pDst, pGC, x, y, count, chars);
+
+ OPS_EPILOG(pGC);
+}
+
+static void
+rwoutImageGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+
+ OPS_PROLOG(pGC);
+
+ (*pGC->ops->ImageGlyphBlt)(pDst, pGC, x, y, nglyph, ppci, pglyphBase);
+
+ OPS_EPILOG(pGC);
+}
+
+static void
+rwoutPolyGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+
+ OPS_PROLOG(pGC);
+
+ (*pGC->ops->PolyGlyphBlt)(pDst, pGC, x, y, nglyph, ppci, pglyphBase);
+
+ OPS_EPILOG(pGC);
+}
+
+static void
+rwoutPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, int w, int h,
+ int x, int y)
+{
+ RemwinGCPrivPtr pGCPriv = REMWIN_GET_GCPRIV(pGC);
+
+ OPS_PROLOG(pGC);
+
+ (*pGC->ops->PushPixels)(pGC, pBitMap, pDst, w, h, x, y);
+
+ OPS_EPILOG(pGC);
+}
+
+
+static void
+rwoutSyncWindowOnConnect (ScreenPtr pScreen, RwcommClientPtr pCommClient,
+ WindowPtr pWin)
+{
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+ RwcommPtr pComm = pScrPriv->pComm;
+ char buf[DISPLAY_PIXELS_MESSAGE_SIZE];
+ RegionPtr pReg = &pWin->borderSize;
+ int numRectsToSend, numRects;
+ BoxPtr pBox;
+ int wid;
+ int i, n;
+
+ if (!rwoutCreateWindowWrite(pScreen, pWin)) {
+ ErrorF("WARNING: could not notify newly connected client of existence of managed window\n");
+ return;
+ }
+
+ /* Send a configure in order to update the sibling information (the other info is redundant) */
+ if (!rwoutConfigureWindowWrite(pScreen, pWin, pWin->drawable.x, pWin->drawable.y,
+ pWin->drawable.width + 2 * pWin->borderWidth,
+ pWin->drawable.height + 2 * pWin->borderWidth,
+ pWin->nextSib)) {
+ ErrorF("WARNING: could not notify newly connected client of managed window configuration\n");
+ }
+
+ /* Send the current show state */
+ if (!rwoutShowWindowWrite(pScreen, pWin, pWin->mapped ? 1 : 0)) {
+ ErrorF("WARNING: could not notify clients of window mapping for window %d\n",
+ (int)pWin->drawable.id);
+ return;
+ }
+
+ if (!pWin->mapped) {
+ return;
+ }
+
+ /* Prepare the DisplayPixels message header */
+ numRects = REGION_NUM_RECTS(pReg);
+ numRectsToSend = numRects;
+ wid = pWin->drawable.id;
+
+#ifdef VERBOSE
+ ErrorF("Send sync pixels for wid = %d, numRect = %d\n",
+ wid, numRects);
+#endif /* VERBOSE */
+
+ swaps(&numRectsToSend, n);
+ swapl(&wid, n);
+
+ DISPLAY_PIXELS_MESSAGE_SET_TYPE(buf, SERVER_MESSAGE_TYPE_DISPLAY_PIXELS);
+ DISPLAY_PIXELS_MESSAGE_SET_NUM_DIRTY(buf, numRectsToSend);
+ DISPLAY_PIXELS_MESSAGE_SET_WID(buf, wid);
+
+ /* Send it off */
+ if (!RWCOMM_BUFFER_WRITE(pComm, buf, DISPLAY_PIXELS_MESSAGE_SIZE)) {
+ return;
+ }
+
+ pBox = REGION_RECTS(pReg);
+ for (i = 0; i < numRects; i++, pBox++) {
+ if (!rwoutUncodedPixelsWrite(pScreen, pWin, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1)) {
+ return;
+ }
+ }
+}
+
+static void
+rwoutSyncCursorOnConnect (ScreenPtr pScreen, RwcommClientPtr pCommClient)
+{
+ RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
+
+ /* Only non-null if cursor is in a managed window */
+ if (pScrPriv->pCursorWin == NULL) {
+ return;
+ }
+
+ /* Send cursor image and hot spot */
+ if (!rwoutDisplayCursorWrite(pScreen, pScrPriv->pCursor)) {
+ ErrorF("WARNING: could not sync cursor image for newly connected client\n");
+ return;
+ }
+
+ /* Send current cursor */
+ if (!rwoutMoveCursorWrite(pScreen, pScrPriv->pCursorWin,
+ pScrPriv->cursorX, pScrPriv->cursorY)) {
+ ErrorF("WARNING: could not sync cursor position for newly connected client\n");
+ return;
+ }
+
+ /* Since cursor is in a managed window, show it */
+ if (!rwoutShowCursorWrite(pScreen, TRUE)) {
+ ErrorF("WARNING: could not sync cursor show for newly connected client\n");
+ return;
+ }
+}
+
+void
+rwoutSyncClientOnConnect (ScreenPtr pScreen, RwcommClientPtr pCommClient)
+{
+ WindowPtr pRootWin = WindowTable[pScreen->myNum];
+ WindowPtr pChild = pRootWin->firstChild;
+
+ /* Send information about managed windows */
+ while (pChild) {
+ /* TODO: we aren't yet supporting input only windows */
+ if (pChild->drawable.type == DRAWABLE_WINDOW) {
+ rwoutSyncWindowOnConnect(pScreen, pCommClient, pChild);
+ }
+ pChild = pChild->nextSib;
+ }
+
+ /* Send information about cursor */
+ rwoutSyncCursorOnConnect(pScreen, pCommClient);
+}
More information about the xorg-commit
mailing list