diff options
author | marha <marha@users.sourceforge.net> | 2010-06-11 14:16:16 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2010-06-11 14:16:16 +0000 |
commit | d1e4f4b8546c7955c66dd023bfd6ef437db9d21d (patch) | |
tree | 529985e77bfc95aa95fe5b540e8f42b0ef041206 /xorg-server/hw/xwin | |
parent | 13919cf85a6ca41d97238de13344aba59e0f7680 (diff) | |
parent | 4c61bf84b11e26e6f22648668c95ea760a379163 (diff) | |
download | vcxsrv-d1e4f4b8546c7955c66dd023bfd6ef437db9d21d.tar.gz vcxsrv-d1e4f4b8546c7955c66dd023bfd6ef437db9d21d.tar.bz2 vcxsrv-d1e4f4b8546c7955c66dd023bfd6ef437db9d21d.zip |
svn merge ^/branches/released .
Diffstat (limited to 'xorg-server/hw/xwin')
-rw-r--r-- | xorg-server/hw/xwin/win.h | 20 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winallpriv.c | 328 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winclipboardxevents.c | 9 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winconfig.c | 6 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winerror.c | 6 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winfillsp.c | 1732 | ||||
-rw-r--r-- | xorg-server/hw/xwin/wingc.c | 334 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winglobals.c | 290 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winkeybd.c | 1058 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winmultiwindowshape.c | 433 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winprefs.c | 1746 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winscrinit.c | 1550 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winsetsp.c | 378 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winshaddd.c | 2826 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winshadddnl.c | 6 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winshadgdi.c | 2604 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winvideo.c | 2 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winwin32rootless.c | 1964 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winwin32rootlesswindow.c | 952 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winwindow.c | 35 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winwindowswm.c | 10 |
21 files changed, 8141 insertions, 8148 deletions
diff --git a/xorg-server/hw/xwin/win.h b/xorg-server/hw/xwin/win.h index d0a41f9ea..3649fe830 100644 --- a/xorg-server/hw/xwin/win.h +++ b/xorg-server/hw/xwin/win.h @@ -596,11 +596,17 @@ extern DWORD g_dwEvents; #ifdef HAS_DEVWINDOWS
extern int g_fdMessageQueue;
#endif
-extern DevPrivateKey g_iScreenPrivateKey;
-extern DevPrivateKey g_iCmapPrivateKey;
-extern DevPrivateKey g_iGCPrivateKey;
-extern DevPrivateKey g_iPixmapPrivateKey;
-extern DevPrivateKey g_iWindowPrivateKey;
+extern DevPrivateKeyRec g_iScreenPrivateKeyRec;
+#define g_iScreenPrivateKey (&g_iScreenPrivateKeyRec)
+extern DevPrivateKeyRec g_iCmapPrivateKeyRec;
+#define g_iCmapPrivateKey (&g_iCmapPrivateKeyRec)
+extern DevPrivateKeyRec g_iGCPrivateKeyRec;
+#define g_iGCPrivateKey (&g_iGCPrivateKeyRec)
+extern DevPrivateKeyRec g_iPixmapPrivateKeyRec;
+#define g_iPixmapPrivateKey (&g_iPixmapPrivateKeyRec)
+extern DevPrivateKeyRec g_iWindowPrivateKeyRec;
+#define g_iWindowPrivateKey (&g_iWindowPrivateKeyRec)
+
extern unsigned long g_ulServerGeneration;
extern DWORD g_dwEnginesSupported;
extern HINSTANCE g_hInstance;
@@ -1175,7 +1181,7 @@ Bool winMapWindowRootless (WindowPtr pWindow);
void
-winSetShapeRootless (WindowPtr pWindow);
+winSetShapeRootless (WindowPtr pWindow, int kind);
/*
@@ -1197,7 +1203,7 @@ void winReshapeMultiWindow (WindowPtr pWin);
void
-winSetShapeMultiWindow (WindowPtr pWindow);
+winSetShapeMultiWindow (WindowPtr pWindow, int kind);
void
winUpdateRgnMultiWindow (WindowPtr pWindow);
diff --git a/xorg-server/hw/xwin/winallpriv.c b/xorg-server/hw/xwin/winallpriv.c index 3413ece53..604c5f673 100644 --- a/xorg-server/hw/xwin/winallpriv.c +++ b/xorg-server/hw/xwin/winallpriv.c @@ -1,164 +1,164 @@ -/* - *Copyright (C) 1994-2000 The XFree86 Project, 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, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *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. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of the XFree86 Project - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from the XFree86 Project. - * - * Authors: Keith Packard, MIT X Consortium - * Harold L Hunt II - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" - - -/* See Porting Layer Definition - p. 58 */ -/* - * Allocate indexes for the privates that we use. - * Allocate memory directly for the screen privates. - * Reserve space in GCs and Pixmaps for our privates. - * Colormap privates are handled in winAllocateCmapPrivates () - */ - -Bool -winAllocatePrivates (ScreenPtr pScreen) -{ - winPrivScreenPtr pScreenPriv; - - winDebug ("winAllocateScreenPrivates - g_ulServerGeneration: %d " - "serverGeneration: %d\n", - g_ulServerGeneration, serverGeneration); - - /* We need a new slot for our privates if the screen gen has changed */ - if (g_ulServerGeneration != serverGeneration) - { - g_ulServerGeneration = serverGeneration; - } - - /* Allocate memory for the screen private structure */ - pScreenPriv = (winPrivScreenPtr) malloc (sizeof (winPrivScreenRec)); - if (!pScreenPriv) - { - ErrorF ("winAllocateScreenPrivates - malloc () failed\n"); - return FALSE; - } - - /* Initialize the memory of the private structure */ - ZeroMemory (pScreenPriv, sizeof (winPrivScreenRec)); - - /* Intialize private structure members */ - pScreenPriv->fActive = TRUE; - - /* Save the screen private pointer */ - winSetScreenPriv (pScreen, pScreenPriv); - - /* Reserve GC memory for our privates */ - if (!dixRequestPrivate(g_iGCPrivateKey, sizeof (winPrivGCRec))) - { - ErrorF ("winAllocatePrivates - AllocateGCPrivate () failed\n"); - return FALSE; - } - - /* Reserve Pixmap memory for our privates */ - if (!dixRequestPrivate(g_iPixmapPrivateKey, sizeof (winPrivPixmapRec))) - { - ErrorF ("winAllocatePrivates - AllocatePixmapPrivates () failed\n"); - return FALSE; - } - - /* Reserve Window memory for our privates */ - if (!dixRequestPrivate(g_iWindowPrivateKey, sizeof (winPrivWinRec))) - { - ErrorF ("winAllocatePrivates () - AllocateWindowPrivates () failed\n"); - return FALSE; - } - - return TRUE; -} - - -/* - * Colormap privates may be allocated after the default colormap has - * already been created for some screens. This initialization procedure - * is called for each default colormap that is found. - */ - -Bool -winInitCmapPrivates (ColormapPtr pcmap, int index) -{ - winDebug ("winInitCmapPrivates\n"); - - /* - * I see no way that this function can do anything useful - * with only a ColormapPtr. We don't have the index for - * our dev privates yet, so we can't really initialize - * anything. Perhaps I am misunderstanding the purpose - * of this function. - */ - /* That's definitely true. - * I therefore changed the API and added the index as argument. - */ - return TRUE; -} - - -/* - * Allocate memory for our colormap privates - */ - -Bool -winAllocateCmapPrivates (ColormapPtr pCmap) -{ - winPrivCmapPtr pCmapPriv; - static unsigned long s_ulPrivateGeneration = 0; - - winDebug ("winAllocateCmapPrivates\n"); - - /* Get a new privates index when the server generation changes */ - if (s_ulPrivateGeneration != serverGeneration) - { - /* Save the new server generation */ - s_ulPrivateGeneration = serverGeneration; - } - - /* Allocate memory for our private structure */ - pCmapPriv = (winPrivCmapPtr) malloc (sizeof (winPrivCmapRec)); - if (!pCmapPriv) - { - ErrorF ("winAllocateCmapPrivates - malloc () failed\n"); - return FALSE; - } - - /* Initialize the memory of the private structure */ - ZeroMemory (pCmapPriv, sizeof (winPrivCmapRec)); - - /* Save the cmap private pointer */ - winSetCmapPriv (pCmap, pCmapPriv); - - winDebug ("winAllocateCmapPrivates - Returning\n"); - - return TRUE; -} +/*
+ *Copyright (C) 1994-2000 The XFree86 Project, 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, sublicense, and/or sell copies of the Software, and to
+ *permit persons to whom the Software is furnished to do so, subject to
+ *the following conditions:
+ *
+ *The above copyright notice and this permission notice shall be
+ *included in all copies or substantial portions of the Software.
+ *
+ *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. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
+ *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *Except as contained in this notice, the name of the XFree86 Project
+ *shall not be used in advertising or otherwise to promote the sale, use
+ *or other dealings in this Software without prior written authorization
+ *from the XFree86 Project.
+ *
+ * Authors: Keith Packard, MIT X Consortium
+ * Harold L Hunt II
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+
+
+/* See Porting Layer Definition - p. 58 */
+/*
+ * Allocate indexes for the privates that we use.
+ * Allocate memory directly for the screen privates.
+ * Reserve space in GCs and Pixmaps for our privates.
+ * Colormap privates are handled in winAllocateCmapPrivates ()
+ */
+
+Bool
+winAllocatePrivates (ScreenPtr pScreen)
+{
+ winPrivScreenPtr pScreenPriv;
+
+ winDebug ("winAllocateScreenPrivates - g_ulServerGeneration: %d "
+ "serverGeneration: %d\n",
+ g_ulServerGeneration, serverGeneration);
+
+ /* We need a new slot for our privates if the screen gen has changed */
+ if (g_ulServerGeneration != serverGeneration)
+ {
+ g_ulServerGeneration = serverGeneration;
+ }
+
+ /* Allocate memory for the screen private structure */
+ pScreenPriv = (winPrivScreenPtr) malloc (sizeof (winPrivScreenRec));
+ if (!pScreenPriv)
+ {
+ ErrorF ("winAllocateScreenPrivates - malloc () failed\n");
+ return FALSE;
+ }
+
+ /* Initialize the memory of the private structure */
+ ZeroMemory (pScreenPriv, sizeof (winPrivScreenRec));
+
+ /* Intialize private structure members */
+ pScreenPriv->fActive = TRUE;
+
+ /* Save the screen private pointer */
+ winSetScreenPriv (pScreen, pScreenPriv);
+
+ /* Reserve GC memory for our privates */
+ if (!dixRegisterPrivateKey(g_iGCPrivateKey, PRIVATE_GC, sizeof (winPrivGCRec)))
+ {
+ ErrorF ("winAllocatePrivates - AllocateGCPrivate () failed\n");
+ return FALSE;
+ }
+
+ /* Reserve Pixmap memory for our privates */
+ if (!dixRegisterPrivateKey(g_iPixmapPrivateKey, PRIVATE_PIXMAP, sizeof (winPrivPixmapRec)))
+ {
+ ErrorF ("winAllocatePrivates - AllocatePixmapPrivates () failed\n");
+ return FALSE;
+ }
+
+ /* Reserve Window memory for our privates */
+ if (!dixRegisterPrivateKey(g_iWindowPrivateKey, PRIVATE_WINDOW, sizeof (winPrivWinRec)))
+ {
+ ErrorF ("winAllocatePrivates () - AllocateWindowPrivates () failed\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Colormap privates may be allocated after the default colormap has
+ * already been created for some screens. This initialization procedure
+ * is called for each default colormap that is found.
+ */
+
+Bool
+winInitCmapPrivates (ColormapPtr pcmap, int index)
+{
+ winDebug ("winInitCmapPrivates\n");
+
+ /*
+ * I see no way that this function can do anything useful
+ * with only a ColormapPtr. We don't have the index for
+ * our dev privates yet, so we can't really initialize
+ * anything. Perhaps I am misunderstanding the purpose
+ * of this function.
+ */
+ /* That's definitely true.
+ * I therefore changed the API and added the index as argument.
+ */
+ return TRUE;
+}
+
+
+/*
+ * Allocate memory for our colormap privates
+ */
+
+Bool
+winAllocateCmapPrivates (ColormapPtr pCmap)
+{
+ winPrivCmapPtr pCmapPriv;
+ static unsigned long s_ulPrivateGeneration = 0;
+
+ winDebug ("winAllocateCmapPrivates\n");
+
+ /* Get a new privates index when the server generation changes */
+ if (s_ulPrivateGeneration != serverGeneration)
+ {
+ /* Save the new server generation */
+ s_ulPrivateGeneration = serverGeneration;
+ }
+
+ /* Allocate memory for our private structure */
+ pCmapPriv = (winPrivCmapPtr) malloc (sizeof (winPrivCmapRec));
+ if (!pCmapPriv)
+ {
+ ErrorF ("winAllocateCmapPrivates - malloc () failed\n");
+ return FALSE;
+ }
+
+ /* Initialize the memory of the private structure */
+ ZeroMemory (pCmapPriv, sizeof (winPrivCmapRec));
+
+ /* Save the cmap private pointer */
+ winSetCmapPriv (pCmap, pCmapPriv);
+
+ winDebug ("winAllocateCmapPrivates - Returning\n");
+
+ return TRUE;
+}
diff --git a/xorg-server/hw/xwin/winclipboardxevents.c b/xorg-server/hw/xwin/winclipboardxevents.c index d7fa8ffd7..a3d333d80 100644 --- a/xorg-server/hw/xwin/winclipboardxevents.c +++ b/xorg-server/hw/xwin/winclipboardxevents.c @@ -426,8 +426,7 @@ winClipboardFlushXEvents (HWND hwnd, xtpText.value = NULL;
xtpText.nitems = 0;
}
- if (pszConvertData)
- free (pszConvertData);
+ free(pszConvertData);
if (hGlobal && pszGlobalData)
GlobalUnlock (hGlobal);
@@ -792,10 +791,8 @@ winClipboardFlushXEvents (HWND hwnd, xtpText.value = NULL;
xtpText.nitems = 0;
}
- if (pszConvertData)
- free (pszConvertData);
- if (pwszUnicodeStr)
- free (pwszUnicodeStr);
+ free(pszConvertData);
+ free(pwszUnicodeStr);
if (hGlobal && pszGlobalData)
GlobalUnlock (hGlobal);
if (fSetClipboardData && g_fUnicodeSupport)
diff --git a/xorg-server/hw/xwin/winconfig.c b/xorg-server/hw/xwin/winconfig.c index fffd3e813..89a57eada 100644 --- a/xorg-server/hw/xwin/winconfig.c +++ b/xorg-server/hw/xwin/winconfig.c @@ -727,7 +727,7 @@ winNameCompare (const char *s1, const char *s2) c1 = (isupper (*s1) ? tolower (*s1) : *s1);
c2 = (isupper (*s2) ? tolower (*s2) : *s2);
}
- return (c1 - c2);
+ return c1 - c2;
}
@@ -762,11 +762,11 @@ winFindOptionValue (XF86OptionPtr list, const char *name) if (list)
{
if (list->opt_val)
- return (list->opt_val);
+ return list->opt_val;
else
return "";
}
- return (NULL);
+ return NULL;
}
diff --git a/xorg-server/hw/xwin/winerror.c b/xorg-server/hw/xwin/winerror.c index 2e706009c..b6b780ec4 100644 --- a/xorg-server/hw/xwin/winerror.c +++ b/xorg-server/hw/xwin/winerror.c @@ -162,9 +162,7 @@ winMessageBoxF (const char *pszError, UINT uType, ...) MB_OK | uType);
winMessageBoxF_Cleanup:
- if (pszErrorF)
- free(pszErrorF);
- if (pszMsgBox)
- free(pszMsgBox);
+ free(pszErrorF);
+ free(pszMsgBox);
#undef MESSAGEBOXF
}
diff --git a/xorg-server/hw/xwin/winfillsp.c b/xorg-server/hw/xwin/winfillsp.c index 702f34f96..ef427a3f1 100644 --- a/xorg-server/hw/xwin/winfillsp.c +++ b/xorg-server/hw/xwin/winfillsp.c @@ -1,866 +1,866 @@ -/* - *Copyright (C) 1994-2000 The XFree86 Project, 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, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *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. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of the XFree86 Project - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from the XFree86 Project. - * - * Authors: Harold L Hunt II - * Alan Hourihane <alanh@fairlite.demon.co.uk> - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" - - -extern void ROP16(HDC hdc, int rop); - -#define TRANSLATE_COLOR(color) \ -{ \ - if (pDrawable->depth == 15) \ - color = ((color & 0x1F) << 19) | ((color & 0x03E0) << 6) | \ - ((color & 0xF800) >> 8); \ - else if (pDrawable->depth == 16) \ - color = ((color & 0x1F) << 19) | ((color & 0x07E0) << 5) | \ - ((color & 0xF800) >> 8); \ - else if (pDrawable->depth == 24 || pDrawable->depth == 32) \ - color = ((color & 0xFF) << 16) | (color & 0xFF00) | \ - ((color & 0xFF0000) >> 16); \ -} - -/* See Porting Layer Definition - p. 54 */ -void -winFillSpansNativeGDI (DrawablePtr pDrawable, - GCPtr pGC, - int iSpans, - DDXPointPtr pPoints, - int *piWidths, - int fSorted) -{ - winGCPriv(pGC); - HBITMAP hbmpOrig = NULL, hbmpOrigStipple = NULL; - HBITMAP hPenOrig = NULL; - HBITMAP hBitmap = NULL; - PixmapPtr pPixmap = NULL; - winPrivPixmapPtr pPixmapPriv = NULL; - PixmapPtr pStipple = NULL; - winPrivPixmapPtr pStipplePriv = NULL; - PixmapPtr pTile = NULL; - winPrivPixmapPtr pTilePriv = NULL; - HDC hdcStipple = NULL, hdcTile = NULL; - HPEN hPen = NULL; - int iX; - int fg, bg; - RegionPtr pClip = pGC->pCompositeClip; - BoxPtr pextent, pbox; - int nbox; - int extentX1, extentX2, extentY1, extentY2; - int fullX1, fullX2, fullY1; - HRGN hrgn = NULL, combined = NULL; - - nbox = REGION_NUM_RECTS (pClip); - pbox = REGION_RECTS (pClip); - - if (!nbox) return; - - combined = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2, pbox->y2); - nbox--; pbox++; - - while (nbox--) - { - hrgn = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2, pbox->y2); - CombineRgn (combined, combined, hrgn, RGN_OR); - DeleteObject (hrgn); - hrgn = NULL; - pbox++; - } - - pextent = REGION_EXTENTS (pGC->pScreen, pClip); - extentX1 = pextent->x1; - extentY1 = pextent->y1; - extentX2 = pextent->x2; - extentY2 = pextent->y2; - - /* Branch on the type of drawable we have */ - switch (pDrawable->type) - { - case DRAWABLE_PIXMAP: - - SelectClipRgn (pGCPriv->hdcMem, combined); - DeleteObject (combined); - combined = NULL; - - /* Get a pixmap pointer from the drawable pointer, and fetch privates */ - pPixmap = (PixmapPtr) pDrawable; - pPixmapPriv = winGetPixmapPriv (pPixmap); - - /* Select the drawable pixmap into memory hdc */ - hbmpOrig = SelectObject (pGCPriv->hdcMem, pPixmapPriv->hBitmap); - if (hbmpOrig == NULL) - FatalError ("winFillSpans - DRAWABLE_PIXMAP - " - "SelectObject () failed on\n\tpPixmapPriv->hBitmap: " - "%08x\n", (unsigned int) pPixmapPriv->hBitmap); - - /* Branch on the fill type */ - switch (pGC->fillStyle) - { - case FillSolid: - - ROP16 (pGCPriv->hdcMem, pGC->alu); - - if (pDrawable->depth == 1) - { - if (pGC->fgPixel == 0) - hPenOrig = SelectObject (pGCPriv->hdcMem, - GetStockObject (BLACK_PEN)); - else - hPenOrig = SelectObject (pGCPriv->hdcMem, - GetStockObject (WHITE_PEN)); - } - else - { - fg = pGC->fgPixel; - TRANSLATE_COLOR (fg); - hPen = CreatePen (PS_SOLID, 0, fg); - hPenOrig = SelectObject (pGCPriv->hdcMem, hPen); - } - - while (iSpans--) - { - fullX1 = pPoints->x; - fullY1 = pPoints->y; - fullX2 = fullX1 + (int) *piWidths; - pPoints++; - piWidths++; - - if (fullY1 < extentY1 || extentY2 <= fullY1) - continue; - - if (fullX1 < extentX1) - fullX1 = extentX1; - if (fullX2 > extentX2) - fullX2 = extentX2; - - if (fullX1 >= fullX2) - continue; - - MoveToEx (pGCPriv->hdcMem, fullX1, fullY1, NULL); - LineTo (pGCPriv->hdcMem, fullX2, fullY1); - } - - SetROP2 (pGCPriv->hdcMem, R2_COPYPEN); - - /* Give back the Pen */ - SelectObject (pGCPriv->hdcMem, hPenOrig); - - if (pDrawable->depth != 1) - DeleteObject (hPen); - break; - - case FillOpaqueStippled: - - pStipple = pGC->stipple; - pStipplePriv = winGetPixmapPriv (pStipple); - - /* Create a device-dependent bitmap for the stipple */ - hBitmap = CreateDIBitmap (pGCPriv->hdcMem, - (BITMAPINFOHEADER *)pStipplePriv->pbmih, - CBM_INIT, - pStipplePriv->pbBits, - (BITMAPINFO *)pStipplePriv->pbmih, - DIB_RGB_COLORS); - - /* Create a memory DC to hold the stipple */ - hdcStipple = CreateCompatibleDC (pGCPriv->hdcMem); - - /* Select the stipple bitmap into the stipple DC */ - hbmpOrigStipple = SelectObject (hdcStipple, hBitmap); - if (hbmpOrigStipple == NULL) - FatalError ("winFillSpans () - DRAWABLE_PIXMAP - FillStippled - " - "SelectObject () failed on hbmpOrigStipple\n"); - - /* Make a temporary copy of the foreground and background colors */ - bg = pGC->bgPixel; - fg = pGC->fgPixel; - - /* Translate the depth-dependent colors to Win32 COLORREFs */ - TRANSLATE_COLOR (fg); - TRANSLATE_COLOR (bg); - SetTextColor (pGCPriv->hdcMem, fg); - SetBkColor (pGCPriv->hdcMem, bg); - - while (iSpans--) - { - int width = pStipple->drawable.width; - fullX1 = pPoints->x; - fullY1 = pPoints->y; - fullX2 = fullX1 + (int) *piWidths; - pPoints++; - piWidths++; - - if (fullY1 < extentY1 || extentY2 <= fullY1) - continue; - - if (fullX1 < extentX1) - fullX1 = extentX1; - if (fullX2 > extentX2) - fullX2 = extentX2; - - if (fullX1 >= fullX2) - continue; - - for (iX = fullX1; iX < fullX2; iX += width) - { - int xoffset; - - if ((iX + pStipple->drawable.width) > fullX2) - width = fullX2 - iX; - else - width = pStipple->drawable.width; - - if (iX == fullX1) - xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pStipple->drawable.width) - pStipple->drawable.width)) % pStipple->drawable.width; - else - xoffset = 0; - - if (xoffset + width > pStipple->drawable.width) - width = pStipple->drawable.width - xoffset; - - BitBlt (pGCPriv->hdcMem, - iX, fullY1, - width, 1, - hdcStipple, - xoffset, - (fullY1 - (pDrawable->y + (pGC->patOrg.y % pStipple->drawable.height) - pStipple->drawable.height)) % pStipple->drawable.height, - g_copyROP[pGC->alu]); - } - } - - /* Clear the stipple HDC */ - SelectObject (hdcStipple, hbmpOrigStipple); - DeleteDC (hdcStipple); - - /* Delete the device dependent stipple bitmap */ - DeleteObject (hBitmap); - - break; - case FillStippled: - - pStipple = pGC->stipple; - pStipplePriv = winGetPixmapPriv (pStipple); - - /* Create a device-dependent bitmap for the stipple */ - hBitmap = CreateDIBitmap (pGCPriv->hdcMem, - (BITMAPINFOHEADER *)pStipplePriv->pbmih, - CBM_INIT, - pStipplePriv->pbBits, - (BITMAPINFO *)pStipplePriv->pbmih, - DIB_RGB_COLORS); - - /* Create a memory DC to hold the stipple */ - hdcStipple = CreateCompatibleDC (pGCPriv->hdcMem); - - /* Select the stipple bitmap into the stipple DC */ - hbmpOrigStipple = SelectObject (hdcStipple, hBitmap); - if (hbmpOrigStipple == NULL) - FatalError ("winFillSpans () - DRAWABLE_PIXMAP - FillStippled - " - "SelectObject () failed on hbmpOrigStipple\n"); - - /* Make a temporary copy of the foreground and background colors */ - bg = pGC->bgPixel; - fg = pGC->fgPixel; - - /* Translate the depth-dependent colors to Win32 COLORREFs */ - TRANSLATE_COLOR (fg); - TRANSLATE_COLOR (bg); - - /* this is fudgy, we should only invert on the last one - * We need to get the black/white pixels right in the - * colormap. But yeah ! it's working.. - */ - if (pGC->bgPixel != -1 && pGC->fgPixel != -1) - { - SetTextColor (pGCPriv->hdcMem, fg); - SetBkColor (pGCPriv->hdcMem, bg); - BitBlt (hdcStipple, - 0, 0, - pStipple->drawable.width, pStipple->drawable.height, - hdcStipple, - 0, 0, - 0x330008); - } - else if (pGC->bgPixel == -1) - { - SetTextColor (pGCPriv->hdcMem, fg); - SetBkMode (pGCPriv->hdcMem, TRANSPARENT); - BitBlt (hdcStipple, - 0, 0, - pStipple->drawable.width, pStipple->drawable.height, - hdcStipple, - 0, 0, - 0x330008); - } - else if (pGC->fgPixel == -1) - { - SetTextColor (pGCPriv->hdcMem, bg); - SetBkMode (pGCPriv->hdcMem, TRANSPARENT); -#if 0 - BitBlt (hdcStipple, - 0, 0, - pStipple->drawable.width, pStipple->drawable.height, - hdcStipple, - 0, 0, - 0x330008); -#endif - } - - while (iSpans--) - { - int width = pStipple->drawable.width; - fullX1 = pPoints->x; - fullY1 = pPoints->y; - fullX2 = fullX1 + (int) *piWidths; - pPoints++; - piWidths++; - - if (fullY1 < extentY1 || extentY2 <= fullY1) - continue; - - if (fullX1 < extentX1) - fullX1 = extentX1; - if (fullX2 > extentX2) - fullX2 = extentX2; - - if (fullX1 >= fullX2) - continue; - - for (iX = fullX1; iX < fullX2; iX += width) - { - int xoffset; - - if ((iX + pStipple->drawable.width) > fullX2) - width = fullX2 - iX; - else - width = pStipple->drawable.width; - - if (iX == fullX1) - xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pStipple->drawable.width) - pStipple->drawable.width)) % pStipple->drawable.width; - else - xoffset = 0; - - if (xoffset + width > pStipple->drawable.width) - width = pStipple->drawable.width - xoffset; - - BitBlt (pGCPriv->hdcMem, - iX, fullY1, - width, 1, - hdcStipple, - xoffset, - (fullY1 - (pDrawable->y + (pGC->patOrg.y % pStipple->drawable.height) - pStipple->drawable.height)) % pStipple->drawable.height, - g_copyROP[pGC->alu]); - } - } - - /* Clear the stipple HDC */ - SelectObject (hdcStipple, hbmpOrigStipple); - DeleteDC (hdcStipple); - - /* Delete the device dependent stipple bitmap */ - DeleteObject (hBitmap); - - /* Restore the background mode */ - SetBkMode (pGCPriv->hdcMem, OPAQUE); - break; - - case FillTiled: - - /* Get a pixmap pointer from the tile pointer, and fetch privates */ - pTile = (PixmapPtr) pGC->tile.pixmap; - pTilePriv = winGetPixmapPriv (pTile); - - /* Create a memory DC to hold the tile */ - hdcTile = CreateCompatibleDC (pGCPriv->hdcMem); - - /* Select the tile into a DC */ - hbmpOrig = SelectObject (hdcTile, pTilePriv->hBitmap); - if (hbmpOrig == NULL) - FatalError ("winFillSpans - DRAWABLE_PIXMAP - FillTiled - " - "SelectObject () failed on pTilePriv->hBitmap\n"); - - while (iSpans--) - { - int width = pTile->drawable.width; - fullX1 = pPoints->x; - fullY1 = pPoints->y; - fullX2 = fullX1 + (int) *piWidths; - pPoints++; - piWidths++; - - if (fullY1 < extentY1 || extentY2 <= fullY1) - continue; - - if (fullX1 < extentX1) - fullX1 = extentX1; - if (fullX2 > extentX2) - fullX2 = extentX2; - - if (fullX1 >= fullX2) - continue; - - for (iX = fullX1; iX < fullX2; iX += width) - { - int xoffset; - - if ((iX + pTile->drawable.width) > fullX2) - width = fullX2 - iX; - else - width = pTile->drawable.width; - - if (iX == fullX1) - xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pTile->drawable.width) - pTile->drawable.width)) % pTile->drawable.width; - else - xoffset = 0; - - if (xoffset + width > pTile->drawable.width) - width = pTile->drawable.width - xoffset; - - BitBlt (pGCPriv->hdcMem, - iX, fullY1, - width, 1, - hdcTile, - xoffset, - (fullY1 - (pDrawable->y + (pGC->patOrg.y % pTile->drawable.height) - pTile->drawable.height)) % pTile->drawable.height, - g_copyROP[pGC->alu]); - } - } - - /* Push the tile pixmap out of the memory HDC */ - SelectObject (hdcTile, hbmpOrig); - - /* Delete the tile */ - DeleteDC (hdcTile); - break; - - default: - ErrorF ("winFillSpans - DRAWABLE_PIXMAP - Unknown fillStyle\n"); - break; - } - - /* Reset clip region */ - SelectClipRgn (pGCPriv->hdcMem, NULL); - - /* Push the drawable pixmap out of the GC HDC */ - SelectObject (pGCPriv->hdcMem, hbmpOrig); - break; - - case DRAWABLE_WINDOW: - - SelectClipRgn (pGCPriv->hdc, combined); - DeleteObject (combined); - combined = NULL; - - /* Branch on fill style */ - switch (pGC->fillStyle) - { - case FillSolid: - - ROP16 (pGCPriv->hdc, pGC->alu); - - if (pDrawable->depth == 1) - { - if (pGC->fgPixel == 0) - hPenOrig = SelectObject (pGCPriv->hdc, - GetStockObject (BLACK_PEN)); - else - hPenOrig = SelectObject (pGCPriv->hdc, - GetStockObject (WHITE_PEN)); - } - else - { - fg = pGC->fgPixel; - TRANSLATE_COLOR (fg); - hPen = CreatePen (PS_SOLID, 0, fg); - hPenOrig = SelectObject (pGCPriv->hdc, hPen); - } - - while (iSpans--) - { - fullX1 = pPoints->x; - fullY1 = pPoints->y; - fullX2 = fullX1 + (int) *piWidths; - pPoints++; - piWidths++; - - if (fullY1 < extentY1 || extentY2 <= fullY1) - continue; - - if (fullX1 < extentX1) - fullX1 = extentX1; - if (fullX2 > extentX2) - fullX2 = extentX2; - - if (fullX1 >= fullX2) - continue; - - MoveToEx (pGCPriv->hdc, fullX1, fullY1, NULL); - LineTo (pGCPriv->hdc, fullX2, fullY1); - } - - SetROP2 (pGCPriv->hdc, R2_COPYPEN); - - /* Give back the Brush */ - SelectObject (pGCPriv->hdc, hPenOrig); - - if (pDrawable->depth != 1) - DeleteObject (hPen); - break; - - case FillOpaqueStippled: - - pStipple = pGC->stipple; - pStipplePriv = winGetPixmapPriv (pStipple); - - /* Create a device-dependent bitmap for the stipple */ - hBitmap = CreateDIBitmap (pGCPriv->hdc, - (BITMAPINFOHEADER *)pStipplePriv->pbmih, - CBM_INIT, - pStipplePriv->pbBits, - (BITMAPINFO *)pStipplePriv->pbmih, - DIB_RGB_COLORS); - - /* Create a memory DC to hold the stipple */ - hdcStipple = CreateCompatibleDC (pGCPriv->hdc); - - /* Select the stipple bitmap into the stipple DC */ - hbmpOrigStipple = SelectObject (hdcStipple, hBitmap); - if (hbmpOrigStipple == NULL) - FatalError ("winFillSpans () - DRAWABLE_PIXMAP - FillStippled - " - "SelectObject () failed on hbmpOrigStipple\n"); - - /* Make a temporary copy of the foreground and background colors */ - bg = pGC->bgPixel; - fg = pGC->fgPixel; - - /* Translate the depth-dependent colors to Win32 COLORREFs */ - TRANSLATE_COLOR (fg); - TRANSLATE_COLOR (bg); - SetTextColor (pGCPriv->hdc, fg); - SetBkColor (pGCPriv->hdc, bg); - - while (iSpans--) - { - int width = pStipple->drawable.width; - fullX1 = pPoints->x; - fullY1 = pPoints->y; - fullX2 = fullX1 + (int) *piWidths; - pPoints++; - piWidths++; - - if (fullY1 < extentY1 || extentY2 <= fullY1) - continue; - - if (fullX1 < extentX1) - fullX1 = extentX1; - if (fullX2 > extentX2) - fullX2 = extentX2; - - if (fullX1 >= fullX2) - continue; - - for (iX = fullX1; iX < fullX2; iX += width) - { - int xoffset; - - if ((iX + pStipple->drawable.width) > fullX2) - width = fullX2 - iX; - else - width = pStipple->drawable.width; - - if (iX == fullX1) - xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pStipple->drawable.width) - pStipple->drawable.width)) % pStipple->drawable.width; - else - xoffset = 0; - - if (xoffset + width > pStipple->drawable.width) - width = pStipple->drawable.width - xoffset; - - BitBlt (pGCPriv->hdc, - iX, fullY1, - width, 1, - hdcStipple, - xoffset, - (fullY1 - (pDrawable->y + (pGC->patOrg.y % pStipple->drawable.height) - pStipple->drawable.height)) % pStipple->drawable.height, - g_copyROP[pGC->alu]); - } - } - - /* Clear the stipple HDC */ - SelectObject (hdcStipple, hbmpOrigStipple); - DeleteDC (hdcStipple); - - /* Delete the device dependent stipple bitmap */ - DeleteObject (hBitmap); - - break; - - case FillStippled: - pStipple = pGC->stipple; - pStipplePriv = winGetPixmapPriv (pStipple); - - /* Create a device-dependent bitmap for the stipple */ - hBitmap = CreateDIBitmap (pGCPriv->hdcMem, - (BITMAPINFOHEADER *)pStipplePriv->pbmih, - CBM_INIT, - pStipplePriv->pbBits, - (BITMAPINFO *)pStipplePriv->pbmih, - DIB_RGB_COLORS); - - /* Create a memory DC to hold the stipple */ - hdcStipple = CreateCompatibleDC (pGCPriv->hdc); - - /* Select the stipple bitmap into the stipple DC */ - hbmpOrigStipple = SelectObject (hdcStipple, hBitmap); - if (hbmpOrigStipple == NULL) - FatalError ("winFillSpans () - DRAWABLE_PIXMAP - FillStippled - " - "SelectObject () failed on hbmpOrigStipple\n"); - - /* Make a temporary copy of the foreground and background colors */ - bg = pGC->bgPixel; - fg = pGC->fgPixel; - - /* Translate the depth-dependent colors to Win32 COLORREFs */ - TRANSLATE_COLOR (fg); - TRANSLATE_COLOR (bg); - - /* this is fudgy, we should only invert on the last one - * We need to get the black/white pixels right in the - * colormap. But yeah ! it's working.. - */ - if (pGC->bgPixel != -1 && pGC->fgPixel != -1) - { - SetTextColor (pGCPriv->hdc, fg); - SetBkColor (pGCPriv->hdc, bg); - BitBlt (hdcStipple, - 0, 0, - pStipple->drawable.width, pStipple->drawable.height, - hdcStipple, - 0,0, - 0x330008); - } - else if (pGC->bgPixel == -1) - { - SetTextColor (pGCPriv->hdc, fg); - SetBkMode (pGCPriv->hdc, TRANSPARENT); - BitBlt (hdcStipple, - 0, 0, - pStipple->drawable.width, pStipple->drawable.height, - hdcStipple, - 0,0, - 0x330008); - } - else if (pGC->fgPixel == -1) - { - SetTextColor (pGCPriv->hdc, bg); - SetBkMode (pGCPriv->hdc, TRANSPARENT); -#if 0 - BitBlt (hdcStipple, - 0, 0, - pStipple->drawable.width, pStipple->drawable.height, - hdcStipple, - 0, 0, - 0x330008); -#endif - } - - while (iSpans--) - { - int width = pStipple->drawable.width; - fullX1 = pPoints->x; - fullY1 = pPoints->y; - fullX2 = fullX1 + (int) *piWidths; - pPoints++; - piWidths++; - - if (fullY1 < extentY1 || extentY2 <= fullY1) - continue; - - if (fullX1 < extentX1) - fullX1 = extentX1; - if (fullX2 > extentX2) - fullX2 = extentX2; - - if (fullX1 >= fullX2) - continue; - - for (iX = fullX1; iX < fullX2; iX += width) - { - int xoffset; - - if ((iX + pStipple->drawable.width) > fullX2) - width = fullX2 - iX; - else - width = pStipple->drawable.width; - - if (iX == fullX1) - xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pStipple->drawable.width) - pStipple->drawable.width)) % pStipple->drawable.width; - else - xoffset = 0; - - if (xoffset + width > pStipple->drawable.width) - width = pStipple->drawable.width - xoffset; - - BitBlt (pGCPriv->hdc, - iX, fullY1, - width, 1, - hdcStipple, - xoffset, - (fullY1 - (pDrawable->y + (pGC->patOrg.y % pStipple->drawable.height) - pStipple->drawable.height)) % pStipple->drawable.height, - g_copyROP[pGC->alu]); - } - } - - /* Clear the stipple HDC */ - SelectObject (hdcStipple, hbmpOrigStipple); - DeleteDC (hdcStipple); - - /* Delete the device dependent stipple bitmap */ - DeleteObject (hBitmap); - - /* Restore the background mode */ - SetBkMode (pGCPriv->hdc, OPAQUE); - break; - - case FillTiled: - - /* Get a pixmap pointer from the tile pointer, and fetch privates */ - pTile = (PixmapPtr) pGC->tile.pixmap; - pTilePriv = winGetPixmapPriv (pTile); - - /* Select the tile into a DC */ - hbmpOrig = SelectObject (pGCPriv->hdcMem, pTilePriv->hBitmap); - if (hbmpOrig == NULL) - FatalError ("winFillSpans - DRAWABLE_WINDOW - FillTiled - " - "SelectObject () failed on pTilePriv->hBitmap\n"); - - while (iSpans--) - { - int width = pTile->drawable.width; - fullX1 = pPoints->x; - fullY1 = pPoints->y; - fullX2 = fullX1 + (int) *piWidths; - pPoints++; - piWidths++; - - if (fullY1 < extentY1 || extentY2 <= fullY1) - continue; - - if (fullX1 < extentX1) - fullX1 = extentX1; - if (fullX2 > extentX2) - fullX2 = extentX2; - - if (fullX1 >= fullX2) - continue; - - for (iX = fullX1; iX < fullX2; iX += width) - { - int xoffset; - - if ((iX + pTile->drawable.width) > fullX2) - width = fullX2 - iX; - else - width = pTile->drawable.width; - - if (iX == fullX1) - xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pTile->drawable.width) - pTile->drawable.width)) % pTile->drawable.width; - else - xoffset = 0; - - if (xoffset + width > pTile->drawable.width) - width = pTile->drawable.width - xoffset; - - BitBlt (pGCPriv->hdc, - iX, fullY1, - width, 1, - pGCPriv->hdcMem, - xoffset, - (fullY1 - (pDrawable->y + (pGC->patOrg.y % pTile->drawable.height) - pTile->drawable.height)) % pTile->drawable.height, - g_copyROP[pGC->alu]); - } - } - - /* Push the tile pixmap out of the memory HDC */ - SelectObject (pGCPriv->hdcMem, hbmpOrig); - break; - - default: - ErrorF ("winFillSpans - DRAWABLE_WINDOW - Unknown fillStyle\n"); - break; - } - - /* Reset clip region */ - SelectClipRgn (pGCPriv->hdc, NULL); - break; - - case UNDRAWABLE_WINDOW: - /* UNDRAWABLE_WINDOW doesn't appear to get called when running xterm */ - switch (pGC->fillStyle) - { - case FillSolid: - ErrorF ("winFillSpans - UNDRAWABLE_WINDOW - FillSolid - " - "Unimplemented\n"); - break; - - case FillStippled: - ErrorF ("winFillSpans - UNDRAWABLE_WINDOW - FillStippled - " - "Unimplemented\n"); - break; - - case FillTiled: - ErrorF ("winFillSpans - UNDRAWABLE_WINDOW - FillTiled - " - "Unimplemented\n"); - break; - - case FillOpaqueStippled: - ErrorF ("winFillSpans - UNDRAWABLE_WINDOW - OpaqueStippled - " - "Unimplemented\n"); - break; - - default: - ErrorF ("winFillSpans - UNDRAWABLE_WINDOW - Unknown fillStyle\n"); - break; - } - break; - - case DRAWABLE_BUFFER: - /* DRAWABLE_BUFFER seems to be undocumented. */ - ErrorF ("winFillSpans - DRAWABLE_BUFFER - Unimplemented\n"); - break; - - default: - ErrorF ("winFillSpans - Unknown drawable type\n"); - break; - } -} +/*
+ *Copyright (C) 1994-2000 The XFree86 Project, 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, sublicense, and/or sell copies of the Software, and to
+ *permit persons to whom the Software is furnished to do so, subject to
+ *the following conditions:
+ *
+ *The above copyright notice and this permission notice shall be
+ *included in all copies or substantial portions of the Software.
+ *
+ *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. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
+ *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *Except as contained in this notice, the name of the XFree86 Project
+ *shall not be used in advertising or otherwise to promote the sale, use
+ *or other dealings in this Software without prior written authorization
+ *from the XFree86 Project.
+ *
+ * Authors: Harold L Hunt II
+ * Alan Hourihane <alanh@fairlite.demon.co.uk>
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+
+
+extern void ROP16(HDC hdc, int rop);
+
+#define TRANSLATE_COLOR(color) \
+{ \
+ if (pDrawable->depth == 15) \
+ color = ((color & 0x1F) << 19) | ((color & 0x03E0) << 6) | \
+ ((color & 0xF800) >> 8); \
+ else if (pDrawable->depth == 16) \
+ color = ((color & 0x1F) << 19) | ((color & 0x07E0) << 5) | \
+ ((color & 0xF800) >> 8); \
+ else if (pDrawable->depth == 24 || pDrawable->depth == 32) \
+ color = ((color & 0xFF) << 16) | (color & 0xFF00) | \
+ ((color & 0xFF0000) >> 16); \
+}
+
+/* See Porting Layer Definition - p. 54 */
+void
+winFillSpansNativeGDI (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int iSpans,
+ DDXPointPtr pPoints,
+ int *piWidths,
+ int fSorted)
+{
+ winGCPriv(pGC);
+ HBITMAP hbmpOrig = NULL, hbmpOrigStipple = NULL;
+ HBITMAP hPenOrig = NULL;
+ HBITMAP hBitmap = NULL;
+ PixmapPtr pPixmap = NULL;
+ winPrivPixmapPtr pPixmapPriv = NULL;
+ PixmapPtr pStipple = NULL;
+ winPrivPixmapPtr pStipplePriv = NULL;
+ PixmapPtr pTile = NULL;
+ winPrivPixmapPtr pTilePriv = NULL;
+ HDC hdcStipple = NULL, hdcTile = NULL;
+ HPEN hPen = NULL;
+ int iX;
+ int fg, bg;
+ RegionPtr pClip = pGC->pCompositeClip;
+ BoxPtr pextent, pbox;
+ int nbox;
+ int extentX1, extentX2, extentY1, extentY2;
+ int fullX1, fullX2, fullY1;
+ HRGN hrgn = NULL, combined = NULL;
+
+ nbox = RegionNumRects (pClip);
+ pbox = RegionRects (pClip);
+
+ if (!nbox) return;
+
+ combined = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2, pbox->y2);
+ nbox--; pbox++;
+
+ while (nbox--)
+ {
+ hrgn = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2, pbox->y2);
+ CombineRgn (combined, combined, hrgn, RGN_OR);
+ DeleteObject (hrgn);
+ hrgn = NULL;
+ pbox++;
+ }
+
+ pextent = RegionExtents(pClip);
+ extentX1 = pextent->x1;
+ extentY1 = pextent->y1;
+ extentX2 = pextent->x2;
+ extentY2 = pextent->y2;
+
+ /* Branch on the type of drawable we have */
+ switch (pDrawable->type)
+ {
+ case DRAWABLE_PIXMAP:
+
+ SelectClipRgn (pGCPriv->hdcMem, combined);
+ DeleteObject (combined);
+ combined = NULL;
+
+ /* Get a pixmap pointer from the drawable pointer, and fetch privates */
+ pPixmap = (PixmapPtr) pDrawable;
+ pPixmapPriv = winGetPixmapPriv (pPixmap);
+
+ /* Select the drawable pixmap into memory hdc */
+ hbmpOrig = SelectObject (pGCPriv->hdcMem, pPixmapPriv->hBitmap);
+ if (hbmpOrig == NULL)
+ FatalError ("winFillSpans - DRAWABLE_PIXMAP - "
+ "SelectObject () failed on\n\tpPixmapPriv->hBitmap: "
+ "%08x\n", (unsigned int) pPixmapPriv->hBitmap);
+
+ /* Branch on the fill type */
+ switch (pGC->fillStyle)
+ {
+ case FillSolid:
+
+ ROP16 (pGCPriv->hdcMem, pGC->alu);
+
+ if (pDrawable->depth == 1)
+ {
+ if (pGC->fgPixel == 0)
+ hPenOrig = SelectObject (pGCPriv->hdcMem,
+ GetStockObject (BLACK_PEN));
+ else
+ hPenOrig = SelectObject (pGCPriv->hdcMem,
+ GetStockObject (WHITE_PEN));
+ }
+ else
+ {
+ fg = pGC->fgPixel;
+ TRANSLATE_COLOR (fg);
+ hPen = CreatePen (PS_SOLID, 0, fg);
+ hPenOrig = SelectObject (pGCPriv->hdcMem, hPen);
+ }
+
+ while (iSpans--)
+ {
+ fullX1 = pPoints->x;
+ fullY1 = pPoints->y;
+ fullX2 = fullX1 + (int) *piWidths;
+ pPoints++;
+ piWidths++;
+
+ if (fullY1 < extentY1 || extentY2 <= fullY1)
+ continue;
+
+ if (fullX1 < extentX1)
+ fullX1 = extentX1;
+ if (fullX2 > extentX2)
+ fullX2 = extentX2;
+
+ if (fullX1 >= fullX2)
+ continue;
+
+ MoveToEx (pGCPriv->hdcMem, fullX1, fullY1, NULL);
+ LineTo (pGCPriv->hdcMem, fullX2, fullY1);
+ }
+
+ SetROP2 (pGCPriv->hdcMem, R2_COPYPEN);
+
+ /* Give back the Pen */
+ SelectObject (pGCPriv->hdcMem, hPenOrig);
+
+ if (pDrawable->depth != 1)
+ DeleteObject (hPen);
+ break;
+
+ case FillOpaqueStippled:
+
+ pStipple = pGC->stipple;
+ pStipplePriv = winGetPixmapPriv (pStipple);
+
+ /* Create a device-dependent bitmap for the stipple */
+ hBitmap = CreateDIBitmap (pGCPriv->hdcMem,
+ (BITMAPINFOHEADER *)pStipplePriv->pbmih,
+ CBM_INIT,
+ pStipplePriv->pbBits,
+ (BITMAPINFO *)pStipplePriv->pbmih,
+ DIB_RGB_COLORS);
+
+ /* Create a memory DC to hold the stipple */
+ hdcStipple = CreateCompatibleDC (pGCPriv->hdcMem);
+
+ /* Select the stipple bitmap into the stipple DC */
+ hbmpOrigStipple = SelectObject (hdcStipple, hBitmap);
+ if (hbmpOrigStipple == NULL)
+ FatalError ("winFillSpans () - DRAWABLE_PIXMAP - FillStippled - "
+ "SelectObject () failed on hbmpOrigStipple\n");
+
+ /* Make a temporary copy of the foreground and background colors */
+ bg = pGC->bgPixel;
+ fg = pGC->fgPixel;
+
+ /* Translate the depth-dependent colors to Win32 COLORREFs */
+ TRANSLATE_COLOR (fg);
+ TRANSLATE_COLOR (bg);
+ SetTextColor (pGCPriv->hdcMem, fg);
+ SetBkColor (pGCPriv->hdcMem, bg);
+
+ while (iSpans--)
+ {
+ int width = pStipple->drawable.width;
+ fullX1 = pPoints->x;
+ fullY1 = pPoints->y;
+ fullX2 = fullX1 + (int) *piWidths;
+ pPoints++;
+ piWidths++;
+
+ if (fullY1 < extentY1 || extentY2 <= fullY1)
+ continue;
+
+ if (fullX1 < extentX1)
+ fullX1 = extentX1;
+ if (fullX2 > extentX2)
+ fullX2 = extentX2;
+
+ if (fullX1 >= fullX2)
+ continue;
+
+ for (iX = fullX1; iX < fullX2; iX += width)
+ {
+ int xoffset;
+
+ if ((iX + pStipple->drawable.width) > fullX2)
+ width = fullX2 - iX;
+ else
+ width = pStipple->drawable.width;
+
+ if (iX == fullX1)
+ xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pStipple->drawable.width) - pStipple->drawable.width)) % pStipple->drawable.width;
+ else
+ xoffset = 0;
+
+ if (xoffset + width > pStipple->drawable.width)
+ width = pStipple->drawable.width - xoffset;
+
+ BitBlt (pGCPriv->hdcMem,
+ iX, fullY1,
+ width, 1,
+ hdcStipple,
+ xoffset,
+ (fullY1 - (pDrawable->y + (pGC->patOrg.y % pStipple->drawable.height) - pStipple->drawable.height)) % pStipple->drawable.height,
+ g_copyROP[pGC->alu]);
+ }
+ }
+
+ /* Clear the stipple HDC */
+ SelectObject (hdcStipple, hbmpOrigStipple);
+ DeleteDC (hdcStipple);
+
+ /* Delete the device dependent stipple bitmap */
+ DeleteObject (hBitmap);
+
+ break;
+ case FillStippled:
+
+ pStipple = pGC->stipple;
+ pStipplePriv = winGetPixmapPriv (pStipple);
+
+ /* Create a device-dependent bitmap for the stipple */
+ hBitmap = CreateDIBitmap (pGCPriv->hdcMem,
+ (BITMAPINFOHEADER *)pStipplePriv->pbmih,
+ CBM_INIT,
+ pStipplePriv->pbBits,
+ (BITMAPINFO *)pStipplePriv->pbmih,
+ DIB_RGB_COLORS);
+
+ /* Create a memory DC to hold the stipple */
+ hdcStipple = CreateCompatibleDC (pGCPriv->hdcMem);
+
+ /* Select the stipple bitmap into the stipple DC */
+ hbmpOrigStipple = SelectObject (hdcStipple, hBitmap);
+ if (hbmpOrigStipple == NULL)
+ FatalError ("winFillSpans () - DRAWABLE_PIXMAP - FillStippled - "
+ "SelectObject () failed on hbmpOrigStipple\n");
+
+ /* Make a temporary copy of the foreground and background colors */
+ bg = pGC->bgPixel;
+ fg = pGC->fgPixel;
+
+ /* Translate the depth-dependent colors to Win32 COLORREFs */
+ TRANSLATE_COLOR (fg);
+ TRANSLATE_COLOR (bg);
+
+ /* this is fudgy, we should only invert on the last one
+ * We need to get the black/white pixels right in the
+ * colormap. But yeah ! it's working..
+ */
+ if (pGC->bgPixel != -1 && pGC->fgPixel != -1)
+ {
+ SetTextColor (pGCPriv->hdcMem, fg);
+ SetBkColor (pGCPriv->hdcMem, bg);
+ BitBlt (hdcStipple,
+ 0, 0,
+ pStipple->drawable.width, pStipple->drawable.height,
+ hdcStipple,
+ 0, 0,
+ 0x330008);
+ }
+ else if (pGC->bgPixel == -1)
+ {
+ SetTextColor (pGCPriv->hdcMem, fg);
+ SetBkMode (pGCPriv->hdcMem, TRANSPARENT);
+ BitBlt (hdcStipple,
+ 0, 0,
+ pStipple->drawable.width, pStipple->drawable.height,
+ hdcStipple,
+ 0, 0,
+ 0x330008);
+ }
+ else if (pGC->fgPixel == -1)
+ {
+ SetTextColor (pGCPriv->hdcMem, bg);
+ SetBkMode (pGCPriv->hdcMem, TRANSPARENT);
+#if 0
+ BitBlt (hdcStipple,
+ 0, 0,
+ pStipple->drawable.width, pStipple->drawable.height,
+ hdcStipple,
+ 0, 0,
+ 0x330008);
+#endif
+ }
+
+ while (iSpans--)
+ {
+ int width = pStipple->drawable.width;
+ fullX1 = pPoints->x;
+ fullY1 = pPoints->y;
+ fullX2 = fullX1 + (int) *piWidths;
+ pPoints++;
+ piWidths++;
+
+ if (fullY1 < extentY1 || extentY2 <= fullY1)
+ continue;
+
+ if (fullX1 < extentX1)
+ fullX1 = extentX1;
+ if (fullX2 > extentX2)
+ fullX2 = extentX2;
+
+ if (fullX1 >= fullX2)
+ continue;
+
+ for (iX = fullX1; iX < fullX2; iX += width)
+ {
+ int xoffset;
+
+ if ((iX + pStipple->drawable.width) > fullX2)
+ width = fullX2 - iX;
+ else
+ width = pStipple->drawable.width;
+
+ if (iX == fullX1)
+ xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pStipple->drawable.width) - pStipple->drawable.width)) % pStipple->drawable.width;
+ else
+ xoffset = 0;
+
+ if (xoffset + width > pStipple->drawable.width)
+ width = pStipple->drawable.width - xoffset;
+
+ BitBlt (pGCPriv->hdcMem,
+ iX, fullY1,
+ width, 1,
+ hdcStipple,
+ xoffset,
+ (fullY1 - (pDrawable->y + (pGC->patOrg.y % pStipple->drawable.height) - pStipple->drawable.height)) % pStipple->drawable.height,
+ g_copyROP[pGC->alu]);
+ }
+ }
+
+ /* Clear the stipple HDC */
+ SelectObject (hdcStipple, hbmpOrigStipple);
+ DeleteDC (hdcStipple);
+
+ /* Delete the device dependent stipple bitmap */
+ DeleteObject (hBitmap);
+
+ /* Restore the background mode */
+ SetBkMode (pGCPriv->hdcMem, OPAQUE);
+ break;
+
+ case FillTiled:
+
+ /* Get a pixmap pointer from the tile pointer, and fetch privates */
+ pTile = (PixmapPtr) pGC->tile.pixmap;
+ pTilePriv = winGetPixmapPriv (pTile);
+
+ /* Create a memory DC to hold the tile */
+ hdcTile = CreateCompatibleDC (pGCPriv->hdcMem);
+
+ /* Select the tile into a DC */
+ hbmpOrig = SelectObject (hdcTile, pTilePriv->hBitmap);
+ if (hbmpOrig == NULL)
+ FatalError ("winFillSpans - DRAWABLE_PIXMAP - FillTiled - "
+ "SelectObject () failed on pTilePriv->hBitmap\n");
+
+ while (iSpans--)
+ {
+ int width = pTile->drawable.width;
+ fullX1 = pPoints->x;
+ fullY1 = pPoints->y;
+ fullX2 = fullX1 + (int) *piWidths;
+ pPoints++;
+ piWidths++;
+
+ if (fullY1 < extentY1 || extentY2 <= fullY1)
+ continue;
+
+ if (fullX1 < extentX1)
+ fullX1 = extentX1;
+ if (fullX2 > extentX2)
+ fullX2 = extentX2;
+
+ if (fullX1 >= fullX2)
+ continue;
+
+ for (iX = fullX1; iX < fullX2; iX += width)
+ {
+ int xoffset;
+
+ if ((iX + pTile->drawable.width) > fullX2)
+ width = fullX2 - iX;
+ else
+ width = pTile->drawable.width;
+
+ if (iX == fullX1)
+ xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pTile->drawable.width) - pTile->drawable.width)) % pTile->drawable.width;
+ else
+ xoffset = 0;
+
+ if (xoffset + width > pTile->drawable.width)
+ width = pTile->drawable.width - xoffset;
+
+ BitBlt (pGCPriv->hdcMem,
+ iX, fullY1,
+ width, 1,
+ hdcTile,
+ xoffset,
+ (fullY1 - (pDrawable->y + (pGC->patOrg.y % pTile->drawable.height) - pTile->drawable.height)) % pTile->drawable.height,
+ g_copyROP[pGC->alu]);
+ }
+ }
+
+ /* Push the tile pixmap out of the memory HDC */
+ SelectObject (hdcTile, hbmpOrig);
+
+ /* Delete the tile */
+ DeleteDC (hdcTile);
+ break;
+
+ default:
+ ErrorF ("winFillSpans - DRAWABLE_PIXMAP - Unknown fillStyle\n");
+ break;
+ }
+
+ /* Reset clip region */
+ SelectClipRgn (pGCPriv->hdcMem, NULL);
+
+ /* Push the drawable pixmap out of the GC HDC */
+ SelectObject (pGCPriv->hdcMem, hbmpOrig);
+ break;
+
+ case DRAWABLE_WINDOW:
+
+ SelectClipRgn (pGCPriv->hdc, combined);
+ DeleteObject (combined);
+ combined = NULL;
+
+ /* Branch on fill style */
+ switch (pGC->fillStyle)
+ {
+ case FillSolid:
+
+ ROP16 (pGCPriv->hdc, pGC->alu);
+
+ if (pDrawable->depth == 1)
+ {
+ if (pGC->fgPixel == 0)
+ hPenOrig = SelectObject (pGCPriv->hdc,
+ GetStockObject (BLACK_PEN));
+ else
+ hPenOrig = SelectObject (pGCPriv->hdc,
+ GetStockObject (WHITE_PEN));
+ }
+ else
+ {
+ fg = pGC->fgPixel;
+ TRANSLATE_COLOR (fg);
+ hPen = CreatePen (PS_SOLID, 0, fg);
+ hPenOrig = SelectObject (pGCPriv->hdc, hPen);
+ }
+
+ while (iSpans--)
+ {
+ fullX1 = pPoints->x;
+ fullY1 = pPoints->y;
+ fullX2 = fullX1 + (int) *piWidths;
+ pPoints++;
+ piWidths++;
+
+ if (fullY1 < extentY1 || extentY2 <= fullY1)
+ continue;
+
+ if (fullX1 < extentX1)
+ fullX1 = extentX1;
+ if (fullX2 > extentX2)
+ fullX2 = extentX2;
+
+ if (fullX1 >= fullX2)
+ continue;
+
+ MoveToEx (pGCPriv->hdc, fullX1, fullY1, NULL);
+ LineTo (pGCPriv->hdc, fullX2, fullY1);
+ }
+
+ SetROP2 (pGCPriv->hdc, R2_COPYPEN);
+
+ /* Give back the Brush */
+ SelectObject (pGCPriv->hdc, hPenOrig);
+
+ if (pDrawable->depth != 1)
+ DeleteObject (hPen);
+ break;
+
+ case FillOpaqueStippled:
+
+ pStipple = pGC->stipple;
+ pStipplePriv = winGetPixmapPriv (pStipple);
+
+ /* Create a device-dependent bitmap for the stipple */
+ hBitmap = CreateDIBitmap (pGCPriv->hdc,
+ (BITMAPINFOHEADER *)pStipplePriv->pbmih,
+ CBM_INIT,
+ pStipplePriv->pbBits,
+ (BITMAPINFO *)pStipplePriv->pbmih,
+ DIB_RGB_COLORS);
+
+ /* Create a memory DC to hold the stipple */
+ hdcStipple = CreateCompatibleDC (pGCPriv->hdc);
+
+ /* Select the stipple bitmap into the stipple DC */
+ hbmpOrigStipple = SelectObject (hdcStipple, hBitmap);
+ if (hbmpOrigStipple == NULL)
+ FatalError ("winFillSpans () - DRAWABLE_PIXMAP - FillStippled - "
+ "SelectObject () failed on hbmpOrigStipple\n");
+
+ /* Make a temporary copy of the foreground and background colors */
+ bg = pGC->bgPixel;
+ fg = pGC->fgPixel;
+
+ /* Translate the depth-dependent colors to Win32 COLORREFs */
+ TRANSLATE_COLOR (fg);
+ TRANSLATE_COLOR (bg);
+ SetTextColor (pGCPriv->hdc, fg);
+ SetBkColor (pGCPriv->hdc, bg);
+
+ while (iSpans--)
+ {
+ int width = pStipple->drawable.width;
+ fullX1 = pPoints->x;
+ fullY1 = pPoints->y;
+ fullX2 = fullX1 + (int) *piWidths;
+ pPoints++;
+ piWidths++;
+
+ if (fullY1 < extentY1 || extentY2 <= fullY1)
+ continue;
+
+ if (fullX1 < extentX1)
+ fullX1 = extentX1;
+ if (fullX2 > extentX2)
+ fullX2 = extentX2;
+
+ if (fullX1 >= fullX2)
+ continue;
+
+ for (iX = fullX1; iX < fullX2; iX += width)
+ {
+ int xoffset;
+
+ if ((iX + pStipple->drawable.width) > fullX2)
+ width = fullX2 - iX;
+ else
+ width = pStipple->drawable.width;
+
+ if (iX == fullX1)
+ xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pStipple->drawable.width) - pStipple->drawable.width)) % pStipple->drawable.width;
+ else
+ xoffset = 0;
+
+ if (xoffset + width > pStipple->drawable.width)
+ width = pStipple->drawable.width - xoffset;
+
+ BitBlt (pGCPriv->hdc,
+ iX, fullY1,
+ width, 1,
+ hdcStipple,
+ xoffset,
+ (fullY1 - (pDrawable->y + (pGC->patOrg.y % pStipple->drawable.height) - pStipple->drawable.height)) % pStipple->drawable.height,
+ g_copyROP[pGC->alu]);
+ }
+ }
+
+ /* Clear the stipple HDC */
+ SelectObject (hdcStipple, hbmpOrigStipple);
+ DeleteDC (hdcStipple);
+
+ /* Delete the device dependent stipple bitmap */
+ DeleteObject (hBitmap);
+
+ break;
+
+ case FillStippled:
+ pStipple = pGC->stipple;
+ pStipplePriv = winGetPixmapPriv (pStipple);
+
+ /* Create a device-dependent bitmap for the stipple */
+ hBitmap = CreateDIBitmap (pGCPriv->hdcMem,
+ (BITMAPINFOHEADER *)pStipplePriv->pbmih,
+ CBM_INIT,
+ pStipplePriv->pbBits,
+ (BITMAPINFO *)pStipplePriv->pbmih,
+ DIB_RGB_COLORS);
+
+ /* Create a memory DC to hold the stipple */
+ hdcStipple = CreateCompatibleDC (pGCPriv->hdc);
+
+ /* Select the stipple bitmap into the stipple DC */
+ hbmpOrigStipple = SelectObject (hdcStipple, hBitmap);
+ if (hbmpOrigStipple == NULL)
+ FatalError ("winFillSpans () - DRAWABLE_PIXMAP - FillStippled - "
+ "SelectObject () failed on hbmpOrigStipple\n");
+
+ /* Make a temporary copy of the foreground and background colors */
+ bg = pGC->bgPixel;
+ fg = pGC->fgPixel;
+
+ /* Translate the depth-dependent colors to Win32 COLORREFs */
+ TRANSLATE_COLOR (fg);
+ TRANSLATE_COLOR (bg);
+
+ /* this is fudgy, we should only invert on the last one
+ * We need to get the black/white pixels right in the
+ * colormap. But yeah ! it's working..
+ */
+ if (pGC->bgPixel != -1 && pGC->fgPixel != -1)
+ {
+ SetTextColor (pGCPriv->hdc, fg);
+ SetBkColor (pGCPriv->hdc, bg);
+ BitBlt (hdcStipple,
+ 0, 0,
+ pStipple->drawable.width, pStipple->drawable.height,
+ hdcStipple,
+ 0,0,
+ 0x330008);
+ }
+ else if (pGC->bgPixel == -1)
+ {
+ SetTextColor (pGCPriv->hdc, fg);
+ SetBkMode (pGCPriv->hdc, TRANSPARENT);
+ BitBlt (hdcStipple,
+ 0, 0,
+ pStipple->drawable.width, pStipple->drawable.height,
+ hdcStipple,
+ 0,0,
+ 0x330008);
+ }
+ else if (pGC->fgPixel == -1)
+ {
+ SetTextColor (pGCPriv->hdc, bg);
+ SetBkMode (pGCPriv->hdc, TRANSPARENT);
+#if 0
+ BitBlt (hdcStipple,
+ 0, 0,
+ pStipple->drawable.width, pStipple->drawable.height,
+ hdcStipple,
+ 0, 0,
+ 0x330008);
+#endif
+ }
+
+ while (iSpans--)
+ {
+ int width = pStipple->drawable.width;
+ fullX1 = pPoints->x;
+ fullY1 = pPoints->y;
+ fullX2 = fullX1 + (int) *piWidths;
+ pPoints++;
+ piWidths++;
+
+ if (fullY1 < extentY1 || extentY2 <= fullY1)
+ continue;
+
+ if (fullX1 < extentX1)
+ fullX1 = extentX1;
+ if (fullX2 > extentX2)
+ fullX2 = extentX2;
+
+ if (fullX1 >= fullX2)
+ continue;
+
+ for (iX = fullX1; iX < fullX2; iX += width)
+ {
+ int xoffset;
+
+ if ((iX + pStipple->drawable.width) > fullX2)
+ width = fullX2 - iX;
+ else
+ width = pStipple->drawable.width;
+
+ if (iX == fullX1)
+ xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pStipple->drawable.width) - pStipple->drawable.width)) % pStipple->drawable.width;
+ else
+ xoffset = 0;
+
+ if (xoffset + width > pStipple->drawable.width)
+ width = pStipple->drawable.width - xoffset;
+
+ BitBlt (pGCPriv->hdc,
+ iX, fullY1,
+ width, 1,
+ hdcStipple,
+ xoffset,
+ (fullY1 - (pDrawable->y + (pGC->patOrg.y % pStipple->drawable.height) - pStipple->drawable.height)) % pStipple->drawable.height,
+ g_copyROP[pGC->alu]);
+ }
+ }
+
+ /* Clear the stipple HDC */
+ SelectObject (hdcStipple, hbmpOrigStipple);
+ DeleteDC (hdcStipple);
+
+ /* Delete the device dependent stipple bitmap */
+ DeleteObject (hBitmap);
+
+ /* Restore the background mode */
+ SetBkMode (pGCPriv->hdc, OPAQUE);
+ break;
+
+ case FillTiled:
+
+ /* Get a pixmap pointer from the tile pointer, and fetch privates */
+ pTile = (PixmapPtr) pGC->tile.pixmap;
+ pTilePriv = winGetPixmapPriv (pTile);
+
+ /* Select the tile into a DC */
+ hbmpOrig = SelectObject (pGCPriv->hdcMem, pTilePriv->hBitmap);
+ if (hbmpOrig == NULL)
+ FatalError ("winFillSpans - DRAWABLE_WINDOW - FillTiled - "
+ "SelectObject () failed on pTilePriv->hBitmap\n");
+
+ while (iSpans--)
+ {
+ int width = pTile->drawable.width;
+ fullX1 = pPoints->x;
+ fullY1 = pPoints->y;
+ fullX2 = fullX1 + (int) *piWidths;
+ pPoints++;
+ piWidths++;
+
+ if (fullY1 < extentY1 || extentY2 <= fullY1)
+ continue;
+
+ if (fullX1 < extentX1)
+ fullX1 = extentX1;
+ if (fullX2 > extentX2)
+ fullX2 = extentX2;
+
+ if (fullX1 >= fullX2)
+ continue;
+
+ for (iX = fullX1; iX < fullX2; iX += width)
+ {
+ int xoffset;
+
+ if ((iX + pTile->drawable.width) > fullX2)
+ width = fullX2 - iX;
+ else
+ width = pTile->drawable.width;
+
+ if (iX == fullX1)
+ xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pTile->drawable.width) - pTile->drawable.width)) % pTile->drawable.width;
+ else
+ xoffset = 0;
+
+ if (xoffset + width > pTile->drawable.width)
+ width = pTile->drawable.width - xoffset;
+
+ BitBlt (pGCPriv->hdc,
+ iX, fullY1,
+ width, 1,
+ pGCPriv->hdcMem,
+ xoffset,
+ (fullY1 - (pDrawable->y + (pGC->patOrg.y % pTile->drawable.height) - pTile->drawable.height)) % pTile->drawable.height,
+ g_copyROP[pGC->alu]);
+ }
+ }
+
+ /* Push the tile pixmap out of the memory HDC */
+ SelectObject (pGCPriv->hdcMem, hbmpOrig);
+ break;
+
+ default:
+ ErrorF ("winFillSpans - DRAWABLE_WINDOW - Unknown fillStyle\n");
+ break;
+ }
+
+ /* Reset clip region */
+ SelectClipRgn (pGCPriv->hdc, NULL);
+ break;
+
+ case UNDRAWABLE_WINDOW:
+ /* UNDRAWABLE_WINDOW doesn't appear to get called when running xterm */
+ switch (pGC->fillStyle)
+ {
+ case FillSolid:
+ ErrorF ("winFillSpans - UNDRAWABLE_WINDOW - FillSolid - "
+ "Unimplemented\n");
+ break;
+
+ case FillStippled:
+ ErrorF ("winFillSpans - UNDRAWABLE_WINDOW - FillStippled - "
+ "Unimplemented\n");
+ break;
+
+ case FillTiled:
+ ErrorF ("winFillSpans - UNDRAWABLE_WINDOW - FillTiled - "
+ "Unimplemented\n");
+ break;
+
+ case FillOpaqueStippled:
+ ErrorF ("winFillSpans - UNDRAWABLE_WINDOW - OpaqueStippled - "
+ "Unimplemented\n");
+ break;
+
+ default:
+ ErrorF ("winFillSpans - UNDRAWABLE_WINDOW - Unknown fillStyle\n");
+ break;
+ }
+ break;
+
+ case DRAWABLE_BUFFER:
+ /* DRAWABLE_BUFFER seems to be undocumented. */
+ ErrorF ("winFillSpans - DRAWABLE_BUFFER - Unimplemented\n");
+ break;
+
+ default:
+ ErrorF ("winFillSpans - Unknown drawable type\n");
+ break;
+ }
+}
diff --git a/xorg-server/hw/xwin/wingc.c b/xorg-server/hw/xwin/wingc.c index 61ba78a54..5f8b2905e 100644 --- a/xorg-server/hw/xwin/wingc.c +++ b/xorg-server/hw/xwin/wingc.c @@ -1,167 +1,167 @@ -/* - *Copyright (C) 2001-2004 Harold L Hunt II 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, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *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. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of Harold L Hunt II - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from Harold L Hunt II. - * - * Authors: Harold L Hunt II - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" - -void -winPushPixels (GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable, int dx, int dy, int xOrg, int yOrg); - - -/* - * Local prototypes - */ - -static void -winValidateGCNativeGDI (GCPtr pGC, - unsigned long changes, - DrawablePtr pDrawable); - -static void -winDestroyGCNativeGDI (GCPtr pGC); - -const GCFuncs winGCFuncs = { - winValidateGCNativeGDI, - miChangeGC, - miCopyGC, - winDestroyGCNativeGDI, - miChangeClip, - miDestroyClip, - miCopyClip, -}; - -/* Drawing Primitives */ -const GCOps winGCOps = { - winFillSpansNativeGDI, - winSetSpansNativeGDI, - miPutImage, - miCopyArea, - miCopyPlane, - miPolyPoint, - winPolyLineNativeGDI, - miPolySegment, - miPolyRectangle, - miPolyArc, - miFillPolygon, - miPolyFillRect, - miPolyFillArc, - miPolyText8, - miPolyText16, - miImageText8, - miImageText16, - miImageGlyphBlt, - miPolyGlyphBlt, - miPushPixels, -}; - - -/* See Porting Layer Definition - p. 45 */ -/* See mfb/mfbgc.c - mfbCreateGC() */ -/* See Strategies for Porting - pp. 15, 16 */ -Bool -winCreateGCNativeGDI (GCPtr pGC) -{ - winPrivGCPtr pGCPriv = NULL; - winPrivScreenPtr pScreenPriv = NULL; - - winDebug ("winCreateGCNativeGDI - depth: %d\n", - pGC->depth); - - pGC->clientClip = NULL; - pGC->clientClipType = CT_NONE; - pGC->freeCompClip = FALSE; - pGC->pCompositeClip = 0; - - pGC->ops = (GCOps *) &winGCOps; - pGC->funcs = (GCFuncs *) &winGCFuncs; - - /* We want all coordinates passed to spans functions to be screen relative */ - pGC->miTranslate = TRUE; - - /* Allocate privates for this GC */ - pGCPriv = winGetGCPriv (pGC); - if (pGCPriv == NULL) - { - ErrorF ("winCreateGCNativeGDI () - Privates pointer was NULL\n"); - return FALSE; - } - - /* Create a new screen DC for the display window */ - pScreenPriv = winGetScreenPriv (pGC->pScreen); - pGCPriv->hdc = GetDC (pScreenPriv->hwndScreen); - - /* Allocate a memory DC for the GC */ - pGCPriv->hdcMem = CreateCompatibleDC (pGCPriv->hdc); - - return TRUE; -} - -static void -winValidateGCNativeGDI (GCPtr pGC, - unsigned long ulChanges, - DrawablePtr pDrawable) -{ - if ((ulChanges & (GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode)) - || (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))) - { - miComputeCompositeClip (pGC, pDrawable); - } -} - - -/* See Porting Layer Definition - p. 46 */ -static void -winDestroyGCNativeGDI (GCPtr pGC) -{ - winGCPriv(pGC); - winScreenPriv(pGC->pScreen); - - if (pGC->freeCompClip) - REGION_DESTROY (pGC->pScreen, pGC->pCompositeClip); - - /* Free the memory DC */ - if (pGCPriv->hdcMem != NULL) - { - DeleteDC (pGCPriv->hdcMem); - pGCPriv->hdcMem = NULL; - } - - /* Release the screen DC for the display window */ - if (pGCPriv->hdc != NULL) - { - ReleaseDC (pScreenPriv->hwndScreen, pGCPriv->hdc); - pGCPriv->hdc = NULL; - } - - /* Invalidate the GC privates pointer */ - winSetGCPriv (pGC, NULL); -} +/*
+ *Copyright (C) 2001-2004 Harold L Hunt II 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, sublicense, and/or sell copies of the Software, and to
+ *permit persons to whom the Software is furnished to do so, subject to
+ *the following conditions:
+ *
+ *The above copyright notice and this permission notice shall be
+ *included in all copies or substantial portions of the Software.
+ *
+ *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. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR
+ *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *Except as contained in this notice, the name of Harold L Hunt II
+ *shall not be used in advertising or otherwise to promote the sale, use
+ *or other dealings in this Software without prior written authorization
+ *from Harold L Hunt II.
+ *
+ * Authors: Harold L Hunt II
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+
+void
+winPushPixels (GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable, int dx, int dy, int xOrg, int yOrg);
+
+
+/*
+ * Local prototypes
+ */
+
+static void
+winValidateGCNativeGDI (GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDrawable);
+
+static void
+winDestroyGCNativeGDI (GCPtr pGC);
+
+const GCFuncs winGCFuncs = {
+ winValidateGCNativeGDI,
+ miChangeGC,
+ miCopyGC,
+ winDestroyGCNativeGDI,
+ miChangeClip,
+ miDestroyClip,
+ miCopyClip,
+};
+
+/* Drawing Primitives */
+const GCOps winGCOps = {
+ winFillSpansNativeGDI,
+ winSetSpansNativeGDI,
+ miPutImage,
+ miCopyArea,
+ miCopyPlane,
+ miPolyPoint,
+ winPolyLineNativeGDI,
+ miPolySegment,
+ miPolyRectangle,
+ miPolyArc,
+ miFillPolygon,
+ miPolyFillRect,
+ miPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ miImageGlyphBlt,
+ miPolyGlyphBlt,
+ miPushPixels,
+};
+
+
+/* See Porting Layer Definition - p. 45 */
+/* See mfb/mfbgc.c - mfbCreateGC() */
+/* See Strategies for Porting - pp. 15, 16 */
+Bool
+winCreateGCNativeGDI (GCPtr pGC)
+{
+ winPrivGCPtr pGCPriv = NULL;
+ winPrivScreenPtr pScreenPriv = NULL;
+
+ winDebug ("winCreateGCNativeGDI - depth: %d\n",
+ pGC->depth);
+
+ pGC->clientClip = NULL;
+ pGC->clientClipType = CT_NONE;
+ pGC->freeCompClip = FALSE;
+ pGC->pCompositeClip = 0;
+
+ pGC->ops = (GCOps *) &winGCOps;
+ pGC->funcs = (GCFuncs *) &winGCFuncs;
+
+ /* We want all coordinates passed to spans functions to be screen relative */
+ pGC->miTranslate = TRUE;
+
+ /* Allocate privates for this GC */
+ pGCPriv = winGetGCPriv (pGC);
+ if (pGCPriv == NULL)
+ {
+ ErrorF ("winCreateGCNativeGDI () - Privates pointer was NULL\n");
+ return FALSE;
+ }
+
+ /* Create a new screen DC for the display window */
+ pScreenPriv = winGetScreenPriv (pGC->pScreen);
+ pGCPriv->hdc = GetDC (pScreenPriv->hwndScreen);
+
+ /* Allocate a memory DC for the GC */
+ pGCPriv->hdcMem = CreateCompatibleDC (pGCPriv->hdc);
+
+ return TRUE;
+}
+
+static void
+winValidateGCNativeGDI (GCPtr pGC,
+ unsigned long ulChanges,
+ DrawablePtr pDrawable)
+{
+ if ((ulChanges & (GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode))
+ || (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS)))
+ {
+ miComputeCompositeClip (pGC, pDrawable);
+ }
+}
+
+
+/* See Porting Layer Definition - p. 46 */
+static void
+winDestroyGCNativeGDI (GCPtr pGC)
+{
+ winGCPriv(pGC);
+ winScreenPriv(pGC->pScreen);
+
+ if (pGC->freeCompClip)
+ RegionDestroy(pGC->pCompositeClip);
+
+ /* Free the memory DC */
+ if (pGCPriv->hdcMem != NULL)
+ {
+ DeleteDC (pGCPriv->hdcMem);
+ pGCPriv->hdcMem = NULL;
+ }
+
+ /* Release the screen DC for the display window */
+ if (pGCPriv->hdc != NULL)
+ {
+ ReleaseDC (pScreenPriv->hwndScreen, pGCPriv->hdc);
+ pGCPriv->hdc = NULL;
+ }
+
+ /* Invalidate the GC privates pointer */
+ winSetGCPriv (pGC, NULL);
+}
diff --git a/xorg-server/hw/xwin/winglobals.c b/xorg-server/hw/xwin/winglobals.c index 09b75031e..b698270b7 100644 --- a/xorg-server/hw/xwin/winglobals.c +++ b/xorg-server/hw/xwin/winglobals.c @@ -1,144 +1,146 @@ -/* - *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. - *Copyright (C) Colin Harrison 2005-2008 - * - *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, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *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. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of Harold L Hunt II - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from Harold L Hunt II. - * - * Authors: Harold L Hunt II - * Colin Harrison - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" - - -/* - * General global variables - */ - -int g_iNumScreens = 0; -winScreenInfo * g_ScreenInfo = 0; -#ifdef HAS_DEVWINDOWS -int g_fdMessageQueue = WIN_FD_INVALID; -#endif -static int g_iScreenPrivateKeyIndex; -DevPrivateKey g_iScreenPrivateKey = &g_iScreenPrivateKeyIndex; -static int g_iCmapPrivateKeyIndex; -DevPrivateKey g_iCmapPrivateKey = &g_iCmapPrivateKeyIndex; -static int g_iGCPrivateKeyIndex; -DevPrivateKey g_iGCPrivateKey = &g_iGCPrivateKeyIndex; -static int g_iPixmapPrivateKeyIndex; -DevPrivateKey g_iPixmapPrivateKey = &g_iPixmapPrivateKeyIndex; -static int g_iWindowPrivateKeyIndex; -DevPrivateKey g_iWindowPrivateKey = &g_iWindowPrivateKeyIndex; -unsigned long g_ulServerGeneration = 0; -DWORD g_dwEnginesSupported = 0; -HINSTANCE g_hInstance = 0; -HWND g_hDlgDepthChange = NULL; -HWND g_hDlgExit = NULL; -HWND g_hDlgAbout = NULL; -const char * g_pszQueryHost = NULL; -Bool g_fXdmcpEnabled = FALSE; -Bool g_fAuthEnabled = FALSE; -HICON g_hIconX = NULL; -HICON g_hSmallIconX = NULL; -#ifndef RELOCATE_PROJECTROOT -const char * g_pszLogFile = DEFAULT_LOGDIR "/XWin.%s.log"; -#else -const char * g_pszLogFile = "XWin.log"; -Bool g_fLogFileChanged = FALSE; -#endif -int g_iLogVerbose = 2; -Bool g_fLogInited = FALSE; -char * g_pszCommandLine = NULL; -Bool g_fSilentFatalError = FALSE; -DWORD g_dwCurrentThreadID = 0; -Bool g_fKeyboardHookLL = FALSE; -HHOOK g_hhookKeyboardLL = NULL; -HWND g_hwndKeyboardFocus = NULL; -Bool g_fNoHelpMessageBox = FALSE; -Bool g_fSoftwareCursor = FALSE; -Bool g_fSilentDupError = FALSE; -Bool g_fNativeGl = FALSE; - -/* - * Global variables for dynamically loaded libraries and - * their function pointers - */ - -HMODULE g_hmodDirectDraw = NULL; -FARPROC g_fpDirectDrawCreate = NULL; -FARPROC g_fpDirectDrawCreateClipper = NULL; - -HMODULE g_hmodCommonControls = NULL; -FARPROC g_fpTrackMouseEvent = (FARPROC) (void (*)(void))NoopDDA; - - -#ifdef XWIN_CLIPBOARD -/* - * Wrapped DIX functions - */ -winDispatchProcPtr winProcEstablishConnectionOrig = NULL; -winDispatchProcPtr winProcQueryTreeOrig = NULL; -winDispatchProcPtr winProcSetSelectionOwnerOrig = NULL; - - -/* - * Clipboard variables - */ - -Bool g_fUnicodeClipboard = TRUE; -Bool g_fClipboard = TRUE; -Bool g_fClipboardLaunched = FALSE; -Bool g_fClipboardStarted = FALSE; -pthread_t g_ptClipboardProc; -HWND g_hwndClipboard = NULL; -void *g_pClipboardDisplay = NULL; -Window g_iClipboardWindow = None; -Atom g_atomLastOwnedSelection = None; -#endif - - -/* - * Re-initialize global variables that are invalidated - * by a server reset. - */ - -void -winInitializeGlobals (void) -{ - g_dwCurrentThreadID = GetCurrentThreadId (); - g_hwndKeyboardFocus = NULL; -#ifdef XWIN_CLIPBOARD - g_fClipboardLaunched = FALSE; - g_fClipboardStarted = FALSE; - g_iClipboardWindow = None; - g_pClipboardDisplay = NULL; - g_atomLastOwnedSelection = None; - g_hwndClipboard = NULL; -#endif -} +/*
+ *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved.
+ *Copyright (C) Colin Harrison 2005-2008
+ *
+ *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, sublicense, and/or sell copies of the Software, and to
+ *permit persons to whom the Software is furnished to do so, subject to
+ *the following conditions:
+ *
+ *The above copyright notice and this permission notice shall be
+ *included in all copies or substantial portions of the Software.
+ *
+ *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. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR
+ *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *Except as contained in this notice, the name of Harold L Hunt II
+ *shall not be used in advertising or otherwise to promote the sale, use
+ *or other dealings in this Software without prior written authorization
+ *from Harold L Hunt II.
+ *
+ * Authors: Harold L Hunt II
+ * Colin Harrison
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+
+
+/*
+ * General global variables
+ */
+
+int g_iNumScreens = 0;
+winScreenInfo * g_ScreenInfo = 0;
+#ifdef HAS_DEVWINDOWS
+int g_fdMessageQueue = WIN_FD_INVALID;
+#endif
+DevPrivateKeyRec g_iScreenPrivateKeyRec;
+DevPrivateKeyRec g_iCmapPrivateKeyRec;
+DevPrivateKeyRec g_iGCPrivateKeyRec;
+DevPrivateKeyRec g_iPixmapPrivateKeyRec;
+DevPrivateKeyRec g_iWindowPrivateKeyRec;
+unsigned long g_ulServerGeneration = 0;
+DWORD g_dwEnginesSupported = 0;
+HINSTANCE g_hInstance = 0;
+HWND g_hDlgDepthChange = NULL;
+HWND g_hDlgExit = NULL;
+HWND g_hDlgAbout = NULL;
+const char * g_pszQueryHost = NULL;
+Bool g_fXdmcpEnabled = FALSE;
+Bool g_fAuthEnabled = FALSE;
+HICON g_hIconX = NULL;
+HICON g_hSmallIconX = NULL;
+#ifndef RELOCATE_PROJECTROOT
+const char * g_pszLogFile = DEFAULT_LOGDIR "/XWin.%s.log";
+#else
+const char * g_pszLogFile = "XWin.log";
+Bool g_fLogFileChanged = FALSE;
+#endif
+int g_iLogVerbose = 2;
+Bool g_fLogInited = FALSE;
+char * g_pszCommandLine = NULL;
+Bool g_fSilentFatalError = FALSE;
+DWORD g_dwCurrentThreadID = 0;
+Bool g_fKeyboardHookLL = FALSE;
+HHOOK g_hhookKeyboardLL = NULL;
+HWND g_hwndKeyboardFocus = NULL;
+Bool g_fNoHelpMessageBox = FALSE;
+Bool g_fSoftwareCursor = FALSE;
+Bool g_fSilentDupError = FALSE;
+Bool g_fNativeGl = FALSE;
+
+/*
+ * Global variables for dynamically loaded libraries and
+ * their function pointers
+ */
+
+HMODULE g_hmodDirectDraw = NULL;
+FARPROC g_fpDirectDrawCreate = NULL;
+FARPROC g_fpDirectDrawCreateClipper = NULL;
+
+HMODULE g_hmodCommonControls = NULL;
+FARPROC g_fpTrackMouseEvent = (FARPROC) (void (*)(void))NoopDDA;
+
+
+#ifdef XWIN_CLIPBOARD
+/*
+ * Wrapped DIX functions
+ */
+winDispatchProcPtr winProcEstablishConnectionOrig = NULL;
+winDispatchProcPtr winProcQueryTreeOrig = NULL;
+winDispatchProcPtr winProcSetSelectionOwnerOrig = NULL;
+
+
+/*
+ * Clipboard variables
+ */
+
+Bool g_fUnicodeClipboard = TRUE;
+Bool g_fClipboard = TRUE;
+Bool g_fClipboardLaunched = FALSE;
+Bool g_fClipboardStarted = FALSE;
+pthread_t g_ptClipboardProc;
+HWND g_hwndClipboard = NULL;
+void *g_pClipboardDisplay = NULL;
+Window g_iClipboardWindow = None;
+Atom g_atomLastOwnedSelection = None;
+#endif
+
+
+/*
+ * Re-initialize global variables that are invalidated
+ * by a server reset.
+ */
+
+void
+winInitializeGlobals (void)
+{
+ if (!dixRegisterPrivateKey(&g_iScreenPrivateKeyRec, PRIVATE_SCREEN, 0) ||
+ !dixRegisterPrivateKey(&g_iCmapPrivateKeyRec, PRIVATE_COLORMAP, 0) ||
+ !dixRegisterPrivateKey(&g_iGCPrivateKeyRec, PRIVATE_GC, 0) ||
+ !dixRegisterPrivateKey(&g_iPixmapPrivateKeyRec, PRIVATE_PIXMAP, 0) ||
+ !dixRegisterPrivateKey(&g_iWindowPrivateKeyRec, PRIVATE_WINDOW, 0)) {
+ FatalError("cannot register private key");
+ }
+ g_dwCurrentThreadID = GetCurrentThreadId ();
+ g_hwndKeyboardFocus = NULL;
+#ifdef XWIN_CLIPBOARD
+ g_fClipboardLaunched = FALSE;
+ g_fClipboardStarted = FALSE;
+ g_iClipboardWindow = None;
+ g_pClipboardDisplay = NULL;
+ g_atomLastOwnedSelection = None;
+ g_hwndClipboard = NULL;
+#endif
+}
diff --git a/xorg-server/hw/xwin/winkeybd.c b/xorg-server/hw/xwin/winkeybd.c index bbfeba553..e69edf7c0 100644 --- a/xorg-server/hw/xwin/winkeybd.c +++ b/xorg-server/hw/xwin/winkeybd.c @@ -1,529 +1,529 @@ -/* - *Copyright (C) 1994-2000 The XFree86 Project, 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, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *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. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of the XFree86 Project - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from the XFree86 Project. - * - * Authors: Dakshinamurthy Karra - * Suhaib M Siddiqi - * Peter Busch - * Harold L Hunt II - */ - - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" -#include "winkeybd.h" -#include "winconfig.h" -#include "winmsg.h" - -#include "xkbsrv.h" - -static Bool g_winKeyState[NUM_KEYCODES]; - -/* - * Local prototypes - */ - -static void -winKeybdBell (int iPercent, DeviceIntPtr pDeviceInt, - pointer pCtrl, int iClass); - -static void -winKeybdCtrl (DeviceIntPtr pDevice, KeybdCtrl *pCtrl); - - -/* - * Translate a Windows WM_[SYS]KEY(UP/DOWN) message - * into an ASCII scan code. - * - * We do this ourselves, rather than letting Windows handle it, - * because Windows tends to munge the handling of special keys, - * like AltGr on European keyboards. - */ - -void -winTranslateKey (WPARAM wParam, LPARAM lParam, int *piScanCode) -{ - int iKeyFixup = g_iKeyMap[wParam * WIN_KEYMAP_COLS + 1]; - int iKeyFixupEx = g_iKeyMap[wParam * WIN_KEYMAP_COLS + 2]; - int iParam = HIWORD (lParam); - int iParamScanCode = LOBYTE (iParam); - -/* WM_ key messages faked by Vista speech recognition (WSR) don't have a - * scan code. - * - * Vocola 3 (Rick Mohr's supplement to WSR) uses - * System.Windows.Forms.SendKeys.SendWait(), which appears always to give a - * scan code of 1 - */ - if (iParamScanCode <= 1) - { - if (VK_PRIOR <= wParam && wParam <= VK_DOWN) - /* Trigger special case table to translate to extended - * keycode, otherwise if num_lock is on, we can get keypad - * numbers instead of navigation keys. */ - iParam |= KF_EXTENDED; - else - iParamScanCode = MapVirtualKeyEx(wParam, - /*MAPVK_VK_TO_VSC*/0, - GetKeyboardLayout(0)); - } - - /* Branch on special extended, special non-extended, or normal key */ - if ((iParam & KF_EXTENDED) && iKeyFixupEx) - *piScanCode = iKeyFixupEx; - else if (iKeyFixup) - *piScanCode = iKeyFixup; - else if (wParam == 0 && iParamScanCode == 0x70) - *piScanCode = KEY_HKTG; - else - switch (iParamScanCode) - { - case 0x70: - *piScanCode = KEY_HKTG; - break; - case 0x73: - *piScanCode = KEY_BSlash2; - break; - default: - *piScanCode = iParamScanCode; - break; - } -} - -/* Ring the keyboard bell (system speaker on PCs) */ -static void -winKeybdBell (int iPercent, DeviceIntPtr pDeviceInt, - pointer pCtrl, int iClass) -{ - /* - * We can't use Beep () here because it uses the PC speaker - * on NT/2000. MessageBeep (MB_OK) will play the default system - * sound on systems with a sound card or it will beep the PC speaker - * on systems that do not have a sound card. - */ - MessageBeep (MB_OK); -} - - -/* Change some keyboard configuration parameters */ -static void -winKeybdCtrl (DeviceIntPtr pDevice, KeybdCtrl *pCtrl) -{ -} - - -/* - * See Porting Layer Definition - p. 18 - * winKeybdProc is known as a DeviceProc. - */ - -int -winKeybdProc (DeviceIntPtr pDeviceInt, int iState) -{ - DevicePtr pDevice = (DevicePtr) pDeviceInt; - XkbSrvInfoPtr xkbi; - XkbControlsPtr ctrl; - - switch (iState) - { - case DEVICE_INIT: - winConfigKeyboard (pDeviceInt); - - /* FIXME: Maybe we should use winGetKbdLeds () here? */ - defaultKeyboardControl.leds = g_winInfo.keyboard.leds; - - winDebug("Rules = \"%s\" Model = \"%s\" Layout = \"%s\"" - " Variant = \"%s\" Options = \"%s\"\n", - g_winInfo.xkb.rules ? g_winInfo.xkb.rules : "none", - g_winInfo.xkb.model ? g_winInfo.xkb.model : "none", - g_winInfo.xkb.layout ? g_winInfo.xkb.layout : "none", - g_winInfo.xkb.variant ? g_winInfo.xkb.variant : "none", - g_winInfo.xkb.options ? g_winInfo.xkb.options : "none"); - - InitKeyboardDeviceStruct (pDeviceInt, - &g_winInfo.xkb, - winKeybdBell, - winKeybdCtrl); - - xkbi = pDeviceInt->key->xkbInfo; - if ((xkbi != NULL) && (xkbi->desc != NULL)) - { - ctrl = xkbi->desc->ctrls; - ctrl->repeat_delay = g_winInfo.keyboard.delay; - ctrl->repeat_interval = 1000/g_winInfo.keyboard.rate; - } - else - { - winDebug ("winKeybdProc - Error initializing keyboard AutoRepeat\n"); - } - - XkbSetExtension(pDeviceInt, ProcessKeyboardEvent); - break; - - case DEVICE_ON: - pDevice->on = TRUE; - - // immediately copy the state of this keyboard device to the VCK - // (which otherwise happens lazily after the first keypress) - CopyKeyClass(pDeviceInt, inputInfo.keyboard); - break; - - case DEVICE_CLOSE: - case DEVICE_OFF: - pDevice->on = FALSE; - break; - } - - return Success; -} - - -/* - * Detect current mode key states upon server startup. - * - * Simulate a press and release of any key that is currently - * toggled. - */ - -void -winInitializeModeKeyStates (void) -{ - /* Restore NumLock */ - if (GetKeyState (VK_NUMLOCK) & 0x0001) - { - winSendKeyEvent (KEY_NumLock, TRUE); - winSendKeyEvent (KEY_NumLock, FALSE); - } - - /* Restore CapsLock */ - if (GetKeyState (VK_CAPITAL) & 0x0001) - { - winSendKeyEvent (KEY_CapsLock, TRUE); - winSendKeyEvent (KEY_CapsLock, FALSE); - } - - /* Restore ScrollLock */ - if (GetKeyState (VK_SCROLL) & 0x0001) - { - winSendKeyEvent (KEY_ScrollLock, TRUE); - winSendKeyEvent (KEY_ScrollLock, FALSE); - } - - /* Restore KanaLock */ - if (GetKeyState (VK_KANA) & 0x0001) - { - winSendKeyEvent (KEY_HKTG, TRUE); - winSendKeyEvent (KEY_HKTG, FALSE); - } -} - - -/* - * Upon regaining the keyboard focus we must - * resynchronize our internal mode key states - * with the actual state of the keys. - */ - -void -winRestoreModeKeyStates (void) -{ - DWORD dwKeyState; - BOOL processEvents = TRUE; - unsigned short internalKeyStates; - - /* X server is being initialized */ - if (!inputInfo.keyboard) - return; - - /* Only process events if the rootwindow is mapped. The keyboard events - * will cause segfaults otherwise */ - if (WindowTable && WindowTable[0] && WindowTable[0]->mapped == FALSE) - processEvents = FALSE; - - /* Force to process all pending events in the mi event queue */ - if (processEvents) - mieqProcessInputEvents (); - - /* Read the mode key states of our X server */ - /* (stored in the virtual core keyboard) */ - internalKeyStates = XkbStateFieldFromRec(&inputInfo.keyboard->key->xkbInfo->state); - winDebug("winRestoreModeKeyStates: state %d\n", internalKeyStates); - - /* - * NOTE: The C XOR operator, ^, will not work here because it is - * a bitwise operator, not a logical operator. C does not - * have a logical XOR operator, so we use a macro instead. - */ - - /* Has the key state changed? */ - dwKeyState = GetKeyState (VK_NUMLOCK) & 0x0001; - if (WIN_XOR (internalKeyStates & NumLockMask, dwKeyState)) - { - winSendKeyEvent (KEY_NumLock, TRUE); - winSendKeyEvent (KEY_NumLock, FALSE); - } - - /* Has the key state changed? */ - dwKeyState = GetKeyState (VK_CAPITAL) & 0x0001; - if (WIN_XOR (internalKeyStates & LockMask, dwKeyState)) - { - winSendKeyEvent (KEY_CapsLock, TRUE); - winSendKeyEvent (KEY_CapsLock, FALSE); - } - - /* Has the key state changed? */ - dwKeyState = GetKeyState (VK_SCROLL) & 0x0001; - if (WIN_XOR (internalKeyStates & ScrollLockMask, dwKeyState)) - { - winSendKeyEvent (KEY_ScrollLock, TRUE); - winSendKeyEvent (KEY_ScrollLock, FALSE); - } - - /* Has the key state changed? */ - dwKeyState = GetKeyState (VK_KANA) & 0x0001; - if (WIN_XOR (internalKeyStates & KanaMask, dwKeyState)) - { - winSendKeyEvent (KEY_HKTG, TRUE); - winSendKeyEvent (KEY_HKTG, FALSE); - } -} - - -/* - * Look for the lovely fake Control_L press/release generated by Windows - * when AltGr is pressed/released on a non-U.S. keyboard. - */ - -Bool -winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam) -{ - MSG msgNext; - LONG lTime; - Bool fReturn; - - /* - * Fake Ctrl_L presses will be followed by an Alt_R keypress - * with the same timestamp as the Ctrl_L press. - */ - if ((message == WM_KEYDOWN || message == WM_SYSKEYDOWN) - && wParam == VK_CONTROL - && (HIWORD (lParam) & KF_EXTENDED) == 0) - { - /* Got a Ctrl_L press */ - - /* Get time of current message */ - lTime = GetMessageTime (); - - /* Look for fake Ctrl_L preceeding an Alt_R press. */ - fReturn = PeekMessage (&msgNext, NULL, - WM_KEYDOWN, WM_SYSKEYDOWN, - PM_NOREMOVE); - - /* - * Try again if the first call fails. - * NOTE: This usually happens when TweakUI is enabled. - */ - if (!fReturn) - { - /* Voodoo to make sure that the Alt_R message has posted */ - Sleep (0); - - /* Look for fake Ctrl_L preceeding an Alt_R press. */ - fReturn = PeekMessage (&msgNext, NULL, - WM_KEYDOWN, WM_SYSKEYDOWN, - PM_NOREMOVE); - } - if (msgNext.message != WM_KEYDOWN && msgNext.message != WM_SYSKEYDOWN) - fReturn = 0; - - /* Is next press an Alt_R with the same timestamp? */ - if (fReturn && msgNext.wParam == VK_MENU - && msgNext.time == lTime - && (HIWORD (msgNext.lParam) & KF_EXTENDED)) - { - /* - * Next key press is Alt_R with same timestamp as current - * Ctrl_L message. Therefore, this Ctrl_L press is a fake - * event, so discard it. - */ - return TRUE; - } - } - - /* - * Fake Ctrl_L releases will be followed by an Alt_R release - * with the same timestamp as the Ctrl_L release. - */ - if ((message == WM_KEYUP || message == WM_SYSKEYUP) - && wParam == VK_CONTROL - && (HIWORD (lParam) & KF_EXTENDED) == 0) - { - /* Got a Ctrl_L release */ - - /* Get time of current message */ - lTime = GetMessageTime (); - - /* Look for fake Ctrl_L release preceeding an Alt_R release. */ - fReturn = PeekMessage (&msgNext, NULL, - WM_KEYUP, WM_SYSKEYUP, - PM_NOREMOVE); - - /* - * Try again if the first call fails. - * NOTE: This usually happens when TweakUI is enabled. - */ - if (!fReturn) - { - /* Voodoo to make sure that the Alt_R message has posted */ - Sleep (0); - - /* Look for fake Ctrl_L release preceeding an Alt_R release. */ - fReturn = PeekMessage (&msgNext, NULL, - WM_KEYUP, WM_SYSKEYUP, - PM_NOREMOVE); - } - - if (msgNext.message != WM_KEYUP && msgNext.message != WM_SYSKEYUP) - fReturn = 0; - - /* Is next press an Alt_R with the same timestamp? */ - if (fReturn - && (msgNext.message == WM_KEYUP - || msgNext.message == WM_SYSKEYUP) - && msgNext.wParam == VK_MENU - && msgNext.time == lTime - && (HIWORD (msgNext.lParam) & KF_EXTENDED)) - { - /* - * Next key release is Alt_R with same timestamp as current - * Ctrl_L message. Therefore, this Ctrl_L release is a fake - * event, so discard it. - */ - return TRUE; - } - } - - /* Not a fake control left press/release */ - return FALSE; -} - - -/* - * Lift any modifier keys that are pressed - */ - -void -winKeybdReleaseKeys (void) -{ - int i; - -#ifdef HAS_DEVWINDOWS - /* Verify that the mi input system has been initialized */ - if (g_fdMessageQueue == WIN_FD_INVALID) - return; -#endif - - /* Loop through all keys */ - for (i = 0; i < NUM_KEYCODES; ++i) - { - /* Pop key if pressed */ - if (g_winKeyState[i]) - winSendKeyEvent (i, FALSE); - - /* Reset pressed flag for keys */ - g_winKeyState[i] = FALSE; - } -} - - -/* - * Take a raw X key code and send an up or down event for it. - * - * Thanks to VNC for inspiration, though it is a simple function. - */ - -void -winSendKeyEvent (DWORD dwKey, Bool fDown) -{ - EventListPtr events; - int i, nevents; - - /* - * When alt-tabing between screens we can get phantom key up messages - * Here we only pass them through it we think we should! - */ - if (g_winKeyState[dwKey] == FALSE && fDown == FALSE) return; - - /* Update the keyState map */ - g_winKeyState[dwKey] = fDown; - - GetEventList(&events); - nevents = GetKeyboardEvents(events, g_pwinKeyboard, fDown ? KeyPress : KeyRelease, dwKey + MIN_KEYCODE); - - for (i = 0; i < nevents; i++) - mieqEnqueue(g_pwinKeyboard, (InternalEvent*)events[i].event); - - winDebug("winSendKeyEvent: dwKey: %d, fDown: %d, nEvents %d\n", - dwKey, fDown, nevents); -} - -BOOL winCheckKeyPressed(WPARAM wParam, LPARAM lParam) -{ - switch (wParam) - { - case VK_CONTROL: - if ((lParam & 0x1ff0000) == 0x11d0000 && g_winKeyState[KEY_RCtrl]) - return TRUE; - if ((lParam & 0x1ff0000) == 0x01d0000 && g_winKeyState[KEY_LCtrl]) - return TRUE; - break; - case VK_SHIFT: - if ((lParam & 0x1ff0000) == 0x0360000 && g_winKeyState[KEY_ShiftR]) - return TRUE; - if ((lParam & 0x1ff0000) == 0x02a0000 && g_winKeyState[KEY_ShiftL]) - return TRUE; - break; - default: - return TRUE; - } - return FALSE; -} - -/* Only on shift release message is sent even if both are pressed. - * Fix this here - */ -void winFixShiftKeys (int iScanCode) -{ - if (GetKeyState (VK_SHIFT) & 0x8000) - return; - - if (iScanCode == KEY_ShiftL && g_winKeyState[KEY_ShiftR]) - winSendKeyEvent (KEY_ShiftR, FALSE); - if (iScanCode == KEY_ShiftR && g_winKeyState[KEY_ShiftL]) - winSendKeyEvent (KEY_ShiftL, FALSE); -} +/*
+ *Copyright (C) 1994-2000 The XFree86 Project, 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, sublicense, and/or sell copies of the Software, and to
+ *permit persons to whom the Software is furnished to do so, subject to
+ *the following conditions:
+ *
+ *The above copyright notice and this permission notice shall be
+ *included in all copies or substantial portions of the Software.
+ *
+ *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. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
+ *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *Except as contained in this notice, the name of the XFree86 Project
+ *shall not be used in advertising or otherwise to promote the sale, use
+ *or other dealings in this Software without prior written authorization
+ *from the XFree86 Project.
+ *
+ * Authors: Dakshinamurthy Karra
+ * Suhaib M Siddiqi
+ * Peter Busch
+ * Harold L Hunt II
+ */
+
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+#include "winkeybd.h"
+#include "winconfig.h"
+#include "winmsg.h"
+
+#include "xkbsrv.h"
+
+static Bool g_winKeyState[NUM_KEYCODES];
+
+/*
+ * Local prototypes
+ */
+
+static void
+winKeybdBell (int iPercent, DeviceIntPtr pDeviceInt,
+ pointer pCtrl, int iClass);
+
+static void
+winKeybdCtrl (DeviceIntPtr pDevice, KeybdCtrl *pCtrl);
+
+
+/*
+ * Translate a Windows WM_[SYS]KEY(UP/DOWN) message
+ * into an ASCII scan code.
+ *
+ * We do this ourselves, rather than letting Windows handle it,
+ * because Windows tends to munge the handling of special keys,
+ * like AltGr on European keyboards.
+ */
+
+void
+winTranslateKey (WPARAM wParam, LPARAM lParam, int *piScanCode)
+{
+ int iKeyFixup = g_iKeyMap[wParam * WIN_KEYMAP_COLS + 1];
+ int iKeyFixupEx = g_iKeyMap[wParam * WIN_KEYMAP_COLS + 2];
+ int iParam = HIWORD (lParam);
+ int iParamScanCode = LOBYTE (iParam);
+
+/* WM_ key messages faked by Vista speech recognition (WSR) don't have a
+ * scan code.
+ *
+ * Vocola 3 (Rick Mohr's supplement to WSR) uses
+ * System.Windows.Forms.SendKeys.SendWait(), which appears always to give a
+ * scan code of 1
+ */
+ if (iParamScanCode <= 1)
+ {
+ if (VK_PRIOR <= wParam && wParam <= VK_DOWN)
+ /* Trigger special case table to translate to extended
+ * keycode, otherwise if num_lock is on, we can get keypad
+ * numbers instead of navigation keys. */
+ iParam |= KF_EXTENDED;
+ else
+ iParamScanCode = MapVirtualKeyEx(wParam,
+ /*MAPVK_VK_TO_VSC*/0,
+ GetKeyboardLayout(0));
+ }
+
+ /* Branch on special extended, special non-extended, or normal key */
+ if ((iParam & KF_EXTENDED) && iKeyFixupEx)
+ *piScanCode = iKeyFixupEx;
+ else if (iKeyFixup)
+ *piScanCode = iKeyFixup;
+ else if (wParam == 0 && iParamScanCode == 0x70)
+ *piScanCode = KEY_HKTG;
+ else
+ switch (iParamScanCode)
+ {
+ case 0x70:
+ *piScanCode = KEY_HKTG;
+ break;
+ case 0x73:
+ *piScanCode = KEY_BSlash2;
+ break;
+ default:
+ *piScanCode = iParamScanCode;
+ break;
+ }
+}
+
+/* Ring the keyboard bell (system speaker on PCs) */
+static void
+winKeybdBell (int iPercent, DeviceIntPtr pDeviceInt,
+ pointer pCtrl, int iClass)
+{
+ /*
+ * We can't use Beep () here because it uses the PC speaker
+ * on NT/2000. MessageBeep (MB_OK) will play the default system
+ * sound on systems with a sound card or it will beep the PC speaker
+ * on systems that do not have a sound card.
+ */
+ MessageBeep (MB_OK);
+}
+
+
+/* Change some keyboard configuration parameters */
+static void
+winKeybdCtrl (DeviceIntPtr pDevice, KeybdCtrl *pCtrl)
+{
+}
+
+
+/*
+ * See Porting Layer Definition - p. 18
+ * winKeybdProc is known as a DeviceProc.
+ */
+
+int
+winKeybdProc (DeviceIntPtr pDeviceInt, int iState)
+{
+ DevicePtr pDevice = (DevicePtr) pDeviceInt;
+ XkbSrvInfoPtr xkbi;
+ XkbControlsPtr ctrl;
+
+ switch (iState)
+ {
+ case DEVICE_INIT:
+ winConfigKeyboard (pDeviceInt);
+
+ /* FIXME: Maybe we should use winGetKbdLeds () here? */
+ defaultKeyboardControl.leds = g_winInfo.keyboard.leds;
+
+ winDebug("Rules = \"%s\" Model = \"%s\" Layout = \"%s\""
+ " Variant = \"%s\" Options = \"%s\"\n",
+ g_winInfo.xkb.rules ? g_winInfo.xkb.rules : "none",
+ g_winInfo.xkb.model ? g_winInfo.xkb.model : "none",
+ g_winInfo.xkb.layout ? g_winInfo.xkb.layout : "none",
+ g_winInfo.xkb.variant ? g_winInfo.xkb.variant : "none",
+ g_winInfo.xkb.options ? g_winInfo.xkb.options : "none");
+
+ InitKeyboardDeviceStruct (pDeviceInt,
+ &g_winInfo.xkb,
+ winKeybdBell,
+ winKeybdCtrl);
+
+ xkbi = pDeviceInt->key->xkbInfo;
+ if ((xkbi != NULL) && (xkbi->desc != NULL))
+ {
+ ctrl = xkbi->desc->ctrls;
+ ctrl->repeat_delay = g_winInfo.keyboard.delay;
+ ctrl->repeat_interval = 1000/g_winInfo.keyboard.rate;
+ }
+ else
+ {
+ winDebug ("winKeybdProc - Error initializing keyboard AutoRepeat\n");
+ }
+
+ XkbSetExtension(pDeviceInt, ProcessKeyboardEvent);
+ break;
+
+ case DEVICE_ON:
+ pDevice->on = TRUE;
+
+ // immediately copy the state of this keyboard device to the VCK
+ // (which otherwise happens lazily after the first keypress)
+ CopyKeyClass(pDeviceInt, inputInfo.keyboard);
+ break;
+
+ case DEVICE_CLOSE:
+ case DEVICE_OFF:
+ pDevice->on = FALSE;
+ break;
+ }
+
+ return Success;
+}
+
+
+/*
+ * Detect current mode key states upon server startup.
+ *
+ * Simulate a press and release of any key that is currently
+ * toggled.
+ */
+
+void
+winInitializeModeKeyStates (void)
+{
+ /* Restore NumLock */
+ if (GetKeyState (VK_NUMLOCK) & 0x0001)
+ {
+ winSendKeyEvent (KEY_NumLock, TRUE);
+ winSendKeyEvent (KEY_NumLock, FALSE);
+ }
+
+ /* Restore CapsLock */
+ if (GetKeyState (VK_CAPITAL) & 0x0001)
+ {
+ winSendKeyEvent (KEY_CapsLock, TRUE);
+ winSendKeyEvent (KEY_CapsLock, FALSE);
+ }
+
+ /* Restore ScrollLock */
+ if (GetKeyState (VK_SCROLL) & 0x0001)
+ {
+ winSendKeyEvent (KEY_ScrollLock, TRUE);
+ winSendKeyEvent (KEY_ScrollLock, FALSE);
+ }
+
+ /* Restore KanaLock */
+ if (GetKeyState (VK_KANA) & 0x0001)
+ {
+ winSendKeyEvent (KEY_HKTG, TRUE);
+ winSendKeyEvent (KEY_HKTG, FALSE);
+ }
+}
+
+
+/*
+ * Upon regaining the keyboard focus we must
+ * resynchronize our internal mode key states
+ * with the actual state of the keys.
+ */
+
+void
+winRestoreModeKeyStates (void)
+{
+ DWORD dwKeyState;
+ BOOL processEvents = TRUE;
+ unsigned short internalKeyStates;
+
+ /* X server is being initialized */
+ if (!inputInfo.keyboard)
+ return;
+
+ /* Only process events if the rootwindow is mapped. The keyboard events
+ * will cause segfaults otherwise */
+ if (screenInfo.screens[0]->root && screenInfo.screens[0]->root->mapped == FALSE)
+ processEvents = FALSE;
+
+ /* Force to process all pending events in the mi event queue */
+ if (processEvents)
+ mieqProcessInputEvents ();
+
+ /* Read the mode key states of our X server */
+ /* (stored in the virtual core keyboard) */
+ internalKeyStates = XkbStateFieldFromRec(&inputInfo.keyboard->key->xkbInfo->state);
+ winDebug("winRestoreModeKeyStates: state %d\n", internalKeyStates);
+
+ /*
+ * NOTE: The C XOR operator, ^, will not work here because it is
+ * a bitwise operator, not a logical operator. C does not
+ * have a logical XOR operator, so we use a macro instead.
+ */
+
+ /* Has the key state changed? */
+ dwKeyState = GetKeyState (VK_NUMLOCK) & 0x0001;
+ if (WIN_XOR (internalKeyStates & NumLockMask, dwKeyState))
+ {
+ winSendKeyEvent (KEY_NumLock, TRUE);
+ winSendKeyEvent (KEY_NumLock, FALSE);
+ }
+
+ /* Has the key state changed? */
+ dwKeyState = GetKeyState (VK_CAPITAL) & 0x0001;
+ if (WIN_XOR (internalKeyStates & LockMask, dwKeyState))
+ {
+ winSendKeyEvent (KEY_CapsLock, TRUE);
+ winSendKeyEvent (KEY_CapsLock, FALSE);
+ }
+
+ /* Has the key state changed? */
+ dwKeyState = GetKeyState (VK_SCROLL) & 0x0001;
+ if (WIN_XOR (internalKeyStates & ScrollLockMask, dwKeyState))
+ {
+ winSendKeyEvent (KEY_ScrollLock, TRUE);
+ winSendKeyEvent (KEY_ScrollLock, FALSE);
+ }
+
+ /* Has the key state changed? */
+ dwKeyState = GetKeyState (VK_KANA) & 0x0001;
+ if (WIN_XOR (internalKeyStates & KanaMask, dwKeyState))
+ {
+ winSendKeyEvent (KEY_HKTG, TRUE);
+ winSendKeyEvent (KEY_HKTG, FALSE);
+ }
+}
+
+
+/*
+ * Look for the lovely fake Control_L press/release generated by Windows
+ * when AltGr is pressed/released on a non-U.S. keyboard.
+ */
+
+Bool
+winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam)
+{
+ MSG msgNext;
+ LONG lTime;
+ Bool fReturn;
+
+ /*
+ * Fake Ctrl_L presses will be followed by an Alt_R keypress
+ * with the same timestamp as the Ctrl_L press.
+ */
+ if ((message == WM_KEYDOWN || message == WM_SYSKEYDOWN)
+ && wParam == VK_CONTROL
+ && (HIWORD (lParam) & KF_EXTENDED) == 0)
+ {
+ /* Got a Ctrl_L press */
+
+ /* Get time of current message */
+ lTime = GetMessageTime ();
+
+ /* Look for fake Ctrl_L preceeding an Alt_R press. */
+ fReturn = PeekMessage (&msgNext, NULL,
+ WM_KEYDOWN, WM_SYSKEYDOWN,
+ PM_NOREMOVE);
+
+ /*
+ * Try again if the first call fails.
+ * NOTE: This usually happens when TweakUI is enabled.
+ */
+ if (!fReturn)
+ {
+ /* Voodoo to make sure that the Alt_R message has posted */
+ Sleep (0);
+
+ /* Look for fake Ctrl_L preceeding an Alt_R press. */
+ fReturn = PeekMessage (&msgNext, NULL,
+ WM_KEYDOWN, WM_SYSKEYDOWN,
+ PM_NOREMOVE);
+ }
+ if (msgNext.message != WM_KEYDOWN && msgNext.message != WM_SYSKEYDOWN)
+ fReturn = 0;
+
+ /* Is next press an Alt_R with the same timestamp? */
+ if (fReturn && msgNext.wParam == VK_MENU
+ && msgNext.time == lTime
+ && (HIWORD (msgNext.lParam) & KF_EXTENDED))
+ {
+ /*
+ * Next key press is Alt_R with same timestamp as current
+ * Ctrl_L message. Therefore, this Ctrl_L press is a fake
+ * event, so discard it.
+ */
+ return TRUE;
+ }
+ }
+
+ /*
+ * Fake Ctrl_L releases will be followed by an Alt_R release
+ * with the same timestamp as the Ctrl_L release.
+ */
+ if ((message == WM_KEYUP || message == WM_SYSKEYUP)
+ && wParam == VK_CONTROL
+ && (HIWORD (lParam) & KF_EXTENDED) == 0)
+ {
+ /* Got a Ctrl_L release */
+
+ /* Get time of current message */
+ lTime = GetMessageTime ();
+
+ /* Look for fake Ctrl_L release preceeding an Alt_R release. */
+ fReturn = PeekMessage (&msgNext, NULL,
+ WM_KEYUP, WM_SYSKEYUP,
+ PM_NOREMOVE);
+
+ /*
+ * Try again if the first call fails.
+ * NOTE: This usually happens when TweakUI is enabled.
+ */
+ if (!fReturn)
+ {
+ /* Voodoo to make sure that the Alt_R message has posted */
+ Sleep (0);
+
+ /* Look for fake Ctrl_L release preceeding an Alt_R release. */
+ fReturn = PeekMessage (&msgNext, NULL,
+ WM_KEYUP, WM_SYSKEYUP,
+ PM_NOREMOVE);
+ }
+
+ if (msgNext.message != WM_KEYUP && msgNext.message != WM_SYSKEYUP)
+ fReturn = 0;
+
+ /* Is next press an Alt_R with the same timestamp? */
+ if (fReturn
+ && (msgNext.message == WM_KEYUP
+ || msgNext.message == WM_SYSKEYUP)
+ && msgNext.wParam == VK_MENU
+ && msgNext.time == lTime
+ && (HIWORD (msgNext.lParam) & KF_EXTENDED))
+ {
+ /*
+ * Next key release is Alt_R with same timestamp as current
+ * Ctrl_L message. Therefore, this Ctrl_L release is a fake
+ * event, so discard it.
+ */
+ return TRUE;
+ }
+ }
+
+ /* Not a fake control left press/release */
+ return FALSE;
+}
+
+
+/*
+ * Lift any modifier keys that are pressed
+ */
+
+void
+winKeybdReleaseKeys (void)
+{
+ int i;
+
+#ifdef HAS_DEVWINDOWS
+ /* Verify that the mi input system has been initialized */
+ if (g_fdMessageQueue == WIN_FD_INVALID)
+ return;
+#endif
+
+ /* Loop through all keys */
+ for (i = 0; i < NUM_KEYCODES; ++i)
+ {
+ /* Pop key if pressed */
+ if (g_winKeyState[i])
+ winSendKeyEvent (i, FALSE);
+
+ /* Reset pressed flag for keys */
+ g_winKeyState[i] = FALSE;
+ }
+}
+
+
+/*
+ * Take a raw X key code and send an up or down event for it.
+ *
+ * Thanks to VNC for inspiration, though it is a simple function.
+ */
+
+void
+winSendKeyEvent (DWORD dwKey, Bool fDown)
+{
+ EventListPtr events;
+ int i, nevents;
+
+ /*
+ * When alt-tabing between screens we can get phantom key up messages
+ * Here we only pass them through it we think we should!
+ */
+ if (g_winKeyState[dwKey] == FALSE && fDown == FALSE) return;
+
+ /* Update the keyState map */
+ g_winKeyState[dwKey] = fDown;
+
+ GetEventList(&events);
+ nevents = GetKeyboardEvents(events, g_pwinKeyboard, fDown ? KeyPress : KeyRelease, dwKey + MIN_KEYCODE);
+
+ for (i = 0; i < nevents; i++)
+ mieqEnqueue(g_pwinKeyboard, (InternalEvent*)events[i].event);
+
+ winDebug("winSendKeyEvent: dwKey: %d, fDown: %d, nEvents %d\n",
+ dwKey, fDown, nevents);
+}
+
+BOOL winCheckKeyPressed(WPARAM wParam, LPARAM lParam)
+{
+ switch (wParam)
+ {
+ case VK_CONTROL:
+ if ((lParam & 0x1ff0000) == 0x11d0000 && g_winKeyState[KEY_RCtrl])
+ return TRUE;
+ if ((lParam & 0x1ff0000) == 0x01d0000 && g_winKeyState[KEY_LCtrl])
+ return TRUE;
+ break;
+ case VK_SHIFT:
+ if ((lParam & 0x1ff0000) == 0x0360000 && g_winKeyState[KEY_ShiftR])
+ return TRUE;
+ if ((lParam & 0x1ff0000) == 0x02a0000 && g_winKeyState[KEY_ShiftL])
+ return TRUE;
+ break;
+ default:
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* Only on shift release message is sent even if both are pressed.
+ * Fix this here
+ */
+void winFixShiftKeys (int iScanCode)
+{
+ if (GetKeyState (VK_SHIFT) & 0x8000)
+ return;
+
+ if (iScanCode == KEY_ShiftL && g_winKeyState[KEY_ShiftR])
+ winSendKeyEvent (KEY_ShiftR, FALSE);
+ if (iScanCode == KEY_ShiftR && g_winKeyState[KEY_ShiftL])
+ winSendKeyEvent (KEY_ShiftL, FALSE);
+}
diff --git a/xorg-server/hw/xwin/winmultiwindowshape.c b/xorg-server/hw/xwin/winmultiwindowshape.c index 32a3f16e6..9219bb708 100644 --- a/xorg-server/hw/xwin/winmultiwindowshape.c +++ b/xorg-server/hw/xwin/winmultiwindowshape.c @@ -1,218 +1,215 @@ -/* - *Copyright (C) 1994-2000 The XFree86 Project, 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, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *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. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of the XFree86 Project - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from the XFree86 Project. - * - * Authors: Kensuke Matsuzaki - * Harold L Hunt II - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif - -#include "win.h" - - -/* - * winSetShapeMultiWindow - See Porting Layer Definition - p. 42 - */ - -void -winSetShapeMultiWindow (WindowPtr pWin) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - winScreenPriv(pScreen); - - winDebug ("winSetShapeMultiWindow - pWin: %08x\n", pWin); - - WIN_UNWRAP(SetShape); - (*pScreen->SetShape)(pWin); - WIN_WRAP(SetShape, winSetShapeMultiWindow); - - /* Update the Windows window's shape */ - winReshapeMultiWindow (pWin); - winUpdateRgnMultiWindow (pWin); - - return; -} - - -/* - * winUpdateRgnMultiWindow - Local function to update a Windows window region - */ - -void -winUpdateRgnMultiWindow (WindowPtr pWin) -{ - SetWindowRgn (winGetWindowPriv(pWin)->hWnd, - winGetWindowPriv(pWin)->hRgn, TRUE); - - /* The system now owns the region specified by the region handle and will delete it when it is no longer needed. */ - winGetWindowPriv(pWin)->hRgn = NULL; -} - - -/* - * winReshapeMultiWindow - Computes the composite clipping region for a window - */ - -void -winReshapeMultiWindow (WindowPtr pWin) -{ - int nRects; - RegionRec rrNewShape; - BoxPtr pShape, pRects, pEnd; - HRGN hRgn, hRgnRect; - winWindowPriv(pWin); - - winDebug ("winReshape ()\n"); - - /* Bail if the window is the root window */ - if (pWin->parent == NULL) - return; - - /* Bail if the window is not top level */ - if (pWin->parent->parent != NULL) - return; - - /* Bail if Windows window handle is invalid */ - if (pWinPriv->hWnd == NULL) - return; - - /* Free any existing window region stored in the window privates */ - if (pWinPriv->hRgn != NULL) - { - DeleteObject (pWinPriv->hRgn); - pWinPriv->hRgn = NULL; - } - - /* Bail if the window has no bounding region defined */ - if (!wBoundingShape (pWin)) - return; - - REGION_NULL(pWin->drawable.pScreen, &rrNewShape); - REGION_COPY(pWin->drawable.pScreen, &rrNewShape, wBoundingShape(pWin)); - REGION_TRANSLATE(pWin->drawable.pScreen, - &rrNewShape, - pWin->borderWidth, - pWin->borderWidth); - - nRects = REGION_NUM_RECTS(&rrNewShape); - pShape = REGION_RECTS(&rrNewShape); - - /* Don't do anything if there are no rectangles in the region */ - if (nRects > 0) - { - RECT rcClient; - RECT rcWindow; - int iOffsetX, iOffsetY; - - /* Get client rectangle */ - if (!GetClientRect (pWinPriv->hWnd, &rcClient)) - { - ErrorF ("winReshape - GetClientRect failed, bailing: %d\n", - (int) GetLastError ()); - return; - } - - /* Translate client rectangle coords to screen coords */ - /* NOTE: Only transforms top and left members */ - ClientToScreen (pWinPriv->hWnd, (LPPOINT) &rcClient); - - /* Get window rectangle */ - if (!GetWindowRect (pWinPriv->hWnd, &rcWindow)) - { - ErrorF ("winReshape - GetWindowRect failed, bailing: %d\n", - (int) GetLastError ()); - return; - } - - /* Calculate offset from window upper-left to client upper-left */ - iOffsetX = rcClient.left - rcWindow.left; - iOffsetY = rcClient.top - rcWindow.top; - - /* Create initial Windows region for title bar */ - /* FIXME: Mean, nasty, ugly hack!!! */ - hRgn = CreateRectRgn (0, 0, rcWindow.right, iOffsetY); - if (hRgn == NULL) - { - ErrorF ("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) " - "failed: %d\n", - 0, 0, (int) rcWindow.right, iOffsetY, (int) GetLastError ()); - } - - /* Loop through all rectangles in the X region */ - for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++) - { - /* Create a Windows region for the X rectangle */ - hRgnRect = CreateRectRgn (pRects->x1 + iOffsetX, - pRects->y1 + iOffsetY, - pRects->x2 + iOffsetX, - pRects->y2 + iOffsetY); - if (hRgnRect == NULL) - { - ErrorF ("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) " - "failed: %d\n" - "\tx1: %d x2: %d xOff: %d y1: %d y2: %d yOff: %d\n", - pRects->x1 + iOffsetX, - pRects->y1 + iOffsetY, - pRects->x2 + iOffsetX, - pRects->y2 + iOffsetY, - (int) GetLastError (), - pRects->x1, pRects->x2, iOffsetX, - pRects->y1, pRects->y2, iOffsetY); - } - - /* Merge the Windows region with the accumulated region */ - if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) - { - ErrorF ("winReshape - CombineRgn () failed: %d\n", - (int) GetLastError ()); - } - - /* Delete the temporary Windows region */ - DeleteObject (hRgnRect); - } - - /* Save a handle to the composite region in the window privates */ - pWinPriv->hRgn = hRgn; - } - - REGION_UNINIT(pWin->drawable.pScreen, &rrNewShape); - - return; -} - -void -winShapeRgnUpdateMultiwindow(HWND hwnd) -{ - WindowPtr pWin = GetProp (hwnd, WIN_WINDOW_PROP); - if (pWin) - { - winReshapeMultiWindow(pWin); - winUpdateRgnMultiWindow(pWin); - } -} +/*
+ *Copyright (C) 1994-2000 The XFree86 Project, 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, sublicense, and/or sell copies of the Software, and to
+ *permit persons to whom the Software is furnished to do so, subject to
+ *the following conditions:
+ *
+ *The above copyright notice and this permission notice shall be
+ *included in all copies or substantial portions of the Software.
+ *
+ *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. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
+ *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *Except as contained in this notice, the name of the XFree86 Project
+ *shall not be used in advertising or otherwise to promote the sale, use
+ *or other dealings in this Software without prior written authorization
+ *from the XFree86 Project.
+ *
+ * Authors: Kensuke Matsuzaki
+ * Harold L Hunt II
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+
+#include "win.h"
+
+
+/*
+ * winSetShapeMultiWindow - See Porting Layer Definition - p. 42
+ */
+
+void
+winSetShapeMultiWindow (WindowPtr pWin, int kind)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winScreenPriv(pScreen);
+
+ winDebug ("winSetShapeMultiWindow - pWin: %08x kind: %i\n", pWin, kind);
+
+ WIN_UNWRAP(SetShape);
+ (*pScreen->SetShape)(pWin, kind);
+ WIN_WRAP(SetShape, winSetShapeMultiWindow);
+
+ /* Update the Windows window's shape */
+ winReshapeMultiWindow (pWin);
+ winUpdateRgnMultiWindow (pWin);
+
+ return;
+}
+
+
+/*
+ * winUpdateRgnMultiWindow - Local function to update a Windows window region
+ */
+
+void
+winUpdateRgnMultiWindow (WindowPtr pWin)
+{
+ SetWindowRgn (winGetWindowPriv(pWin)->hWnd,
+ winGetWindowPriv(pWin)->hRgn, TRUE);
+
+ /* The system now owns the region specified by the region handle and will delete it when it is no longer needed. */
+ winGetWindowPriv(pWin)->hRgn = NULL;
+}
+
+
+/*
+ * winReshapeMultiWindow - Computes the composite clipping region for a window
+ */
+
+void
+winReshapeMultiWindow (WindowPtr pWin)
+{
+ int nRects;
+ RegionRec rrNewShape;
+ BoxPtr pShape, pRects, pEnd;
+ HRGN hRgn, hRgnRect;
+ winWindowPriv(pWin);
+
+ winDebug ("winReshape ()\n");
+
+ /* Bail if the window is the root window */
+ if (pWin->parent == NULL)
+ return;
+
+ /* Bail if the window is not top level */
+ if (pWin->parent->parent != NULL)
+ return;
+
+ /* Bail if Windows window handle is invalid */
+ if (pWinPriv->hWnd == NULL)
+ return;
+
+ /* Free any existing window region stored in the window privates */
+ if (pWinPriv->hRgn != NULL)
+ {
+ DeleteObject (pWinPriv->hRgn);
+ pWinPriv->hRgn = NULL;
+ }
+
+ /* Bail if the window has no bounding region defined */
+ if (!wBoundingShape (pWin))
+ return;
+
+ RegionNull(&rrNewShape);
+ RegionCopy(&rrNewShape, wBoundingShape(pWin));
+ RegionTranslate(&rrNewShape, pWin->borderWidth, pWin->borderWidth);
+
+ nRects = RegionNumRects(&rrNewShape);
+ pShape = RegionRects(&rrNewShape);
+
+ /* Don't do anything if there are no rectangles in the region */
+ if (nRects > 0)
+ {
+ RECT rcClient;
+ RECT rcWindow;
+ int iOffsetX, iOffsetY;
+
+ /* Get client rectangle */
+ if (!GetClientRect (pWinPriv->hWnd, &rcClient))
+ {
+ ErrorF ("winReshape - GetClientRect failed, bailing: %d\n",
+ (int) GetLastError ());
+ return;
+ }
+
+ /* Translate client rectangle coords to screen coords */
+ /* NOTE: Only transforms top and left members */
+ ClientToScreen (pWinPriv->hWnd, (LPPOINT) &rcClient);
+
+ /* Get window rectangle */
+ if (!GetWindowRect (pWinPriv->hWnd, &rcWindow))
+ {
+ ErrorF ("winReshape - GetWindowRect failed, bailing: %d\n",
+ (int) GetLastError ());
+ return;
+ }
+
+ /* Calculate offset from window upper-left to client upper-left */
+ iOffsetX = rcClient.left - rcWindow.left;
+ iOffsetY = rcClient.top - rcWindow.top;
+
+ /* Create initial Windows region for title bar */
+ /* FIXME: Mean, nasty, ugly hack!!! */
+ hRgn = CreateRectRgn (0, 0, rcWindow.right, iOffsetY);
+ if (hRgn == NULL)
+ {
+ ErrorF ("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) "
+ "failed: %d\n",
+ 0, 0, (int) rcWindow.right, iOffsetY, (int) GetLastError ());
+ }
+
+ /* Loop through all rectangles in the X region */
+ for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++)
+ {
+ /* Create a Windows region for the X rectangle */
+ hRgnRect = CreateRectRgn (pRects->x1 + iOffsetX,
+ pRects->y1 + iOffsetY,
+ pRects->x2 + iOffsetX,
+ pRects->y2 + iOffsetY);
+ if (hRgnRect == NULL)
+ {
+ ErrorF ("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) "
+ "failed: %d\n"
+ "\tx1: %d x2: %d xOff: %d y1: %d y2: %d yOff: %d\n",
+ pRects->x1 + iOffsetX,
+ pRects->y1 + iOffsetY,
+ pRects->x2 + iOffsetX,
+ pRects->y2 + iOffsetY,
+ (int) GetLastError (),
+ pRects->x1, pRects->x2, iOffsetX,
+ pRects->y1, pRects->y2, iOffsetY);
+ }
+
+ /* Merge the Windows region with the accumulated region */
+ if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR)
+ {
+ ErrorF ("winReshape - CombineRgn () failed: %d\n",
+ (int) GetLastError ());
+ }
+
+ /* Delete the temporary Windows region */
+ DeleteObject (hRgnRect);
+ }
+
+ /* Save a handle to the composite region in the window privates */
+ pWinPriv->hRgn = hRgn;
+ }
+
+ RegionUninit(&rrNewShape);
+
+ return;
+}
+
+void
+winShapeRgnUpdateMultiwindow(HWND hwnd)
+{
+ WindowPtr pWin = GetProp (hwnd, WIN_WINDOW_PROP);
+ if (pWin)
+ {
+ winReshapeMultiWindow(pWin);
+ winUpdateRgnMultiWindow(pWin);
+ }
+}
diff --git a/xorg-server/hw/xwin/winprefs.c b/xorg-server/hw/xwin/winprefs.c index 3becb436a..4d34e41a1 100644 --- a/xorg-server/hw/xwin/winprefs.c +++ b/xorg-server/hw/xwin/winprefs.c @@ -1,875 +1,871 @@ -/* - * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. - * Copyright (C) Colin Harrison 2005-2008 - * - * 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, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * 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. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name of the XFree86 Project - * shall not be used in advertising or otherwise to promote the sale, use - * or other dealings in this Software without prior written authorization - * from the XFree86 Project. - * - * Authors: Earle F. Philhower, III - * Colin Harrison - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include <stdio.h> -#include <stdlib.h> -#ifdef __CYGWIN__ -#include <sys/resource.h> -#endif -#include "win.h" - -#include <X11/Xwindows.h> -#include <shellapi.h> - -#include "winprefs.h" -#include "winmultiwindowclass.h" - -/* Where will the custom menu commands start counting from? */ -#define STARTMENUID WM_USER - -/* External global variables */ -#ifdef XWIN_MULTIWINDOW -extern DWORD g_dwCurrentThreadID; -#endif - -extern const char *winGetBaseDir(void); - -extern const char *g_pszLogFile; - -/* From winmultiwindowflex.l, the real parser */ -extern void parse_file (FILE *fp); - -/* From winprefyacc.y, the pref structure loaded by the parser */ -extern WINPREFS pref; - -/* The global X default icon */ -extern HICON g_hIconX; -extern HICON g_hSmallIconX; - -/* Currently in use command ID, incremented each new menu item created */ -static int g_cmdid = STARTMENUID; - - -/* Defined in DIX */ -extern char *display; - -/* Local function to handle comma-ified icon names */ -static HICON -LoadImageComma (char *fname, int sx, int sy, int flags); - - -/* - * Creates or appends a menu from a MENUPARSED structure - */ -static HMENU -MakeMenu (char *name, - HMENU editMenu, - int editItem) -{ - int i; - int item; - MENUPARSED *m; - HMENU hmenu, hsub; - - for (i=0; i<pref.menuItems; i++) - { - if (!strcmp(name, pref.menu[i].menuName)) - break; - } - - /* Didn't find a match, bummer */ - if (i==pref.menuItems) - { - ErrorF("MakeMenu: Can't find menu %s\n", name); - return NULL; - } - - m = &(pref.menu[i]); - - if (editMenu) - { - hmenu = editMenu; - item = editItem; - } - else - { - hmenu = CreatePopupMenu(); - if (!hmenu) - { - ErrorF("MakeMenu: Unable to CreatePopupMenu() %s\n", name); - return NULL; - } - item = 0; - } - - /* Add the menu items */ - for (i=0; i<m->menuItems; i++) - { - /* Only assign IDs one time... */ - if ( m->menuItem[i].commandID == 0 ) - m->menuItem[i].commandID = g_cmdid++; - - switch (m->menuItem[i].cmd) - { - case CMD_EXEC: - case CMD_ALWAYSONTOP: - case CMD_RELOAD: - InsertMenu (hmenu, - item, - MF_BYPOSITION|MF_ENABLED|MF_STRING, - m->menuItem[i].commandID, - m->menuItem[i].text); - break; - - case CMD_SEPARATOR: - InsertMenu (hmenu, - item, - MF_BYPOSITION|MF_SEPARATOR, - 0, - NULL); - break; - - case CMD_MENU: - /* Recursive! */ - hsub = MakeMenu (m->menuItem[i].param, 0, 0); - if (hsub) - InsertMenu (hmenu, - item, - MF_BYPOSITION|MF_POPUP|MF_ENABLED|MF_STRING, - (UINT_PTR)hsub, - m->menuItem[i].text); - break; - } - - /* If item==-1 (means to add at end of menu) don't increment) */ - if (item>=0) - item++; - } - - return hmenu; -} - - -#ifdef XWIN_MULTIWINDOW -/* - * Callback routine that is executed once per window class. - * Removes or creates custom window settings depending on LPARAM - */ -static wBOOL CALLBACK -ReloadEnumWindowsProc (HWND hwnd, LPARAM lParam) -{ - HICON hicon; - Window wid; - - if (!hwnd) { - ErrorF("ReloadEnumWindowsProc: hwnd==NULL!\n"); - return FALSE; - } - - /* It's our baby, either clean or dirty it */ - if (lParam==FALSE) - { - /* Reset the window's icon to undefined. */ - hicon = (HICON)SendMessage(hwnd, WM_SETICON, ICON_BIG, 0); - - /* If the old icon is generated on-the-fly, get rid of it, will regen */ - winDestroyIcon (hicon); - - /* Same for the small icon */ - hicon = (HICON)SendMessage(hwnd, WM_SETICON, ICON_SMALL, 0); - winDestroyIcon (hicon); - - /* Remove any menu additions; bRevert=TRUE destroys any modified menus */ - GetSystemMenu (hwnd, TRUE); - - /* This window is now clean of our taint (but with undefined icons) */ - } - else - { - /* winUpdateIcon() will set the icon default, dynamic, or from xwinrc */ - wid = (Window)GetProp (hwnd, WIN_WID_PROP); - if (wid) - winUpdateIcon (wid); - - /* Update the system menu for this window */ - SetupSysMenu ((unsigned long)hwnd); - - /* That was easy... */ - } - - return TRUE; -} -#endif - - -/* - * Removes any custom icons in classes, custom menus, etc. - * Frees all members in pref structure. - * Reloads the preferences file. - * Set custom icons and menus again. - */ -static void -ReloadPrefs (void) -{ - int i; - -#ifdef XWIN_MULTIWINDOW - /* First, iterate over all windows, deleting their icons and custom menus. - * This is really only needed because winDestroyIcon() will try to - * destroy the old global icons, which will have changed. - * It is probably better to set a windows USER_DATA to flag locally defined - * icons, and use that to accurately know when to destroy old icons. - */ - EnumThreadWindows (g_dwCurrentThreadID, ReloadEnumWindowsProc, FALSE); -#endif - - /* Now, free/clear all info from our prefs structure */ - for (i=0; i<pref.menuItems; i++) - free (pref.menu[i].menuItem); - free (pref.menu); - pref.menu = NULL; - pref.menuItems = 0; - - pref.rootMenuName[0] = 0; - - free (pref.sysMenu); - pref.sysMenuItems = 0; - - pref.defaultSysMenuName[0] = 0; - pref.defaultSysMenuPos = 0; - - pref.iconDirectory[0] = 0; - pref.defaultIconName[0] = 0; - pref.trayIconName[0] = 0; - - for (i=0; i<pref.iconItems; i++) - if (pref.icon[i].hicon) - DestroyIcon ((HICON)pref.icon[i].hicon); - free (pref.icon); - pref.icon = NULL; - pref.iconItems = 0; - - /* Free global default X icon */ - if (g_hIconX) - DestroyIcon (g_hIconX); - if (g_hSmallIconX) - DestroyIcon (g_hSmallIconX); - - /* Reset the custom command IDs */ - g_cmdid = STARTMENUID; - - /* Load the updated resource file */ - LoadPreferences(); - - g_hIconX = NULL; - g_hSmallIconX = NULL; - -#ifdef XWIN_MULTIWINDOW - winInitGlobalIcons(); -#endif - -#ifdef XWIN_MULTIWINDOW - /* Rebuild the icons and menus */ - EnumThreadWindows (g_dwCurrentThreadID, ReloadEnumWindowsProc, TRUE); -#endif - - /* Whew, done */ -} - -/* - * Check/uncheck the ALWAYSONTOP items in this menu - */ -void -HandleCustomWM_INITMENU(unsigned long hwndIn, - unsigned long hmenuIn) -{ - HWND hwnd; - HMENU hmenu; - DWORD dwExStyle; - int i, j; - - hwnd = (HWND)hwndIn; - hmenu = (HMENU)hmenuIn; - if (!hwnd || !hmenu) - return; - - if (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) - dwExStyle = MF_BYCOMMAND | MF_CHECKED; - else - dwExStyle = MF_BYCOMMAND | MF_UNCHECKED; - - for (i=0; i<pref.menuItems; i++) - for (j=0; j<pref.menu[i].menuItems; j++) - if (pref.menu[i].menuItem[j].cmd==CMD_ALWAYSONTOP) - CheckMenuItem (hmenu, pref.menu[i].menuItem[j].commandID, dwExStyle ); - -} - -/* - * Searches for the custom WM_COMMAND command ID and performs action. - * Return TRUE if command is proccessed, FALSE otherwise. - */ -Bool -HandleCustomWM_COMMAND (unsigned long hwndIn, - int command) -{ - HWND hwnd; - int i, j; - MENUPARSED *m; - DWORD dwExStyle; - - hwnd = (HWND)hwndIn; - - if (!command) - return FALSE; - - for (i=0; i<pref.menuItems; i++) - { - m = &(pref.menu[i]); - for (j=0; j<m->menuItems; j++) - { - if (command==m->menuItem[j].commandID) - { - /* Match! */ - switch(m->menuItem[j].cmd) - { -#ifdef __CYGWIN__ - case CMD_EXEC: - if (fork()==0) - { - struct rlimit rl; - unsigned long i; - - /* Close any open descriptors except for STD* */ - getrlimit (RLIMIT_NOFILE, &rl); - for (i = STDERR_FILENO+1; i < rl.rlim_cur; i++) - close(i); - - /* Disassociate any TTYs */ - setsid(); - - execl ("/bin/sh", - "/bin/sh", - "-c", - m->menuItem[j].param, - NULL); - exit (0); - } - else - return TRUE; - break; -#else - case CMD_EXEC: - { - /* Start process without console window */ - STARTUPINFO start; - PROCESS_INFORMATION child; - - memset (&start, 0, sizeof (start)); - start.cb = sizeof (start); - //start.dwFlags = STARTF_USESHOWWINDOW; - //start.wShowWindow = SW_HIDE; - - memset (&child, 0, sizeof (child)); - - if (CreateProcess (NULL, m->menuItem[j].param, NULL, NULL, FALSE, 0, - NULL, NULL, &start, &child)) - { - CloseHandle (child.hThread); - CloseHandle (child.hProcess); - } - else - MessageBox(NULL, m->menuItem[j].param, "VcXsrv Exec Command Error!", MB_OK | MB_ICONEXCLAMATION); - } - return TRUE; -#endif - case CMD_ALWAYSONTOP: - if (!hwnd) - return FALSE; - - /* Get extended window style */ - dwExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE); - - /* Handle topmost windows */ - if (dwExStyle & WS_EX_TOPMOST) - SetWindowPos (hwnd, - HWND_NOTOPMOST, - 0, 0, - 0, 0, - SWP_NOSIZE | SWP_NOMOVE); - else - SetWindowPos (hwnd, - HWND_TOPMOST, - 0, 0, - 0, 0, - SWP_NOSIZE | SWP_NOMOVE); -#if XWIN_MULTIWINDOW - /* Reflect the changed Z order */ - winReorderWindowsMultiWindow (); -#endif - return TRUE; - - case CMD_RELOAD: - ReloadPrefs(); - return TRUE; - - default: - return FALSE; - } - } /* match */ - } /* for j */ - } /* for i */ - - return FALSE; -} - - -#ifdef XWIN_MULTIWINDOW -/* - * Add the default or a custom menu depending on the class match - */ -void -SetupSysMenu (unsigned long hwndIn) -{ - HWND hwnd; - HMENU sys; - int i; - WindowPtr pWin; - char *res_name, *res_class; - - hwnd = (HWND)hwndIn; - if (!hwnd) - return; - - pWin = GetProp (hwnd, WIN_WINDOW_PROP); - - sys = GetSystemMenu (hwnd, FALSE); - if (!sys) - return; - - if (pWin) - { - /* First see if there's a class match... */ - if (winMultiWindowGetClassHint (pWin, &res_name, &res_class)) - { - for (i=0; i<pref.sysMenuItems; i++) - { - if (!strcmp(pref.sysMenu[i].match, res_name) || - !strcmp(pref.sysMenu[i].match, res_class) ) - { - free(res_name); - free(res_class); - - MakeMenu (pref.sysMenu[i].menuName, sys, - pref.sysMenu[i].menuPos==AT_START?0:-1); - return; - } - } - - /* No match, just free alloc'd strings */ - free(res_name); - free(res_class); - } /* Found wm_class */ - } /* if pwin */ - - /* Fallback to system default */ - if (pref.defaultSysMenuName[0]) - { - if (pref.defaultSysMenuPos==AT_START) - MakeMenu (pref.defaultSysMenuName, sys, 0); - else - MakeMenu (pref.defaultSysMenuName, sys, -1); - } -} -#endif - - -/* - * Possibly add a menu to the toolbar icon - */ -void -SetupRootMenu (unsigned long hmenuRoot) -{ - HMENU root; - - root = (HMENU)hmenuRoot; - if (!root) - return; - - if (pref.rootMenuName[0]) - { - MakeMenu(pref.rootMenuName, root, 0); - } -} - - -/* - * Check for and return an overridden default ICON specified in the prefs - */ -HICON -winOverrideDefaultIcon(int size) -{ - HICON hicon; - - if (pref.defaultIconName[0]) - { - hicon = LoadImageComma (pref.defaultIconName, size, size, 0); - if (hicon==NULL) - ErrorF ("winOverrideDefaultIcon: LoadImageComma(%s) failed\n", - pref.defaultIconName); - - return hicon; - } - - return 0; -} - - -/* - * Return the HICON to use in the taskbar notification area - */ -HICON -winTaskbarIcon(void) -{ - HICON hicon; - - hicon = 0; - /* First try and load an overridden, if success then return it */ - if (pref.trayIconName[0]) - { - hicon = LoadImageComma (pref.trayIconName, - GetSystemMetrics (SM_CXSMICON), - GetSystemMetrics (SM_CYSMICON), - 0 ); - } - - /* Otherwise return the default */ - if (!hicon) - hicon = (HICON) LoadImage (g_hInstance, - MAKEINTRESOURCE(IDI_XWIN), - IMAGE_ICON, - GetSystemMetrics (SM_CXSMICON), - GetSystemMetrics (SM_CYSMICON), - 0); - - return hicon; -} - - -/* - * Parse a filename to extract an icon: - * If fname is exactly ",nnn" then extract icon from our resource - * else if it is "file,nnn" then extract icon nnn from that file - * else try to load it as an .ico file and if that fails return NULL - */ -static HICON -LoadImageComma (char *fname, int sx, int sy, int flags) -{ - HICON hicon; - int index; - char file[PATH_MAX+NAME_MAX+2]; - - /* Some input error checking */ - if (!fname || !fname[0]) - return NULL; - - index = 0; - hicon = NULL; - - if (fname[0]==',') - { - /* It's the XWIN.EXE resource they want */ - index = atoi (fname+1); - hicon = LoadImage (g_hInstance, - MAKEINTRESOURCE(index), - IMAGE_ICON, - sx, - sy, - flags); - } - else - { - file[0] = 0; - /* Prepend path if not given a "X:\" filename */ - if ( !(fname[0] && fname[1]==':' && fname[2]=='\\') ) - { - strcpy (file, pref.iconDirectory); - if (pref.iconDirectory[0]) - if (fname[strlen(fname)-1]!='\\') - strcat (file, "\\"); - } - strcat (file, fname); - - if (strrchr (file, ',')) - { - /* Specified as <fname>,<index> */ - - *(strrchr (file, ',')) = 0; /* End string at comma */ - index = atoi (strrchr (fname, ',') + 1); - hicon = ExtractIcon (g_hInstance, file, index); - } - else - { - /* Just an .ico file... */ - - hicon = (HICON)LoadImage (NULL, - file, - IMAGE_ICON, - sx, - sy, - LR_LOADFROMFILE|flags); - } - } - return hicon; -} - -/* - * Check for a match of the window class to one specified in the - * ICONS{} section in the prefs file, and load the icon from a file - */ -HICON -winOverrideIcon (unsigned long longWin) -{ - WindowPtr pWin = (WindowPtr) longWin; - char *res_name, *res_class; - int i; - HICON hicon; - char *wmName; - - if (pWin==NULL) - return 0; - - /* If we can't find the class, we can't override from default! */ - if (!winMultiWindowGetClassHint (pWin, &res_name, &res_class)) - return 0; - - winMultiWindowGetWMName (pWin, &wmName); - - for (i=0; i<pref.iconItems; i++) { - if (!strcmp(pref.icon[i].match, res_name) || - !strcmp(pref.icon[i].match, res_class) || - (wmName && strstr(wmName, pref.icon[i].match))) - { - free (res_name); - free (res_class); - if (wmName) - free (wmName); - - if (pref.icon[i].hicon) - return pref.icon[i].hicon; - - hicon = LoadImageComma (pref.icon[i].iconFile, 0, 0, LR_DEFAULTSIZE); - if (hicon==NULL) - ErrorF ("winOverrideIcon: LoadImageComma(%s) failed\n", - pref.icon[i].iconFile); - - pref.icon[i].hicon = hicon; - return hicon; - } - } - - /* Didn't find the icon, fail gracefully */ - free (res_name); - free (res_class); - if (wmName) - free (wmName); - - return 0; -} - - -/* - * Should we free this icon or leave it in memory (is it part of our - * ICONS{} overrides)? - */ -int -winIconIsOverride(unsigned hiconIn) -{ - HICON hicon; - int i; - - hicon = (HICON)hiconIn; - - if (!hicon) - return 0; - - for (i=0; i<pref.iconItems; i++) - if ((HICON)pref.icon[i].hicon == hicon) - return 1; - - return 0; -} - - - -/* - * Try and open ~/.XWinrc and system.XWinrc - * Load it into prefs structure for use by other functions - */ -void -LoadPreferences (void) -{ - char *home; - char fname[PATH_MAX+NAME_MAX+2]; - FILE *prefFile; - char szDisplay[512]; - char *szEnvDisplay; - int i, j; - char param[PARAM_MAX+1]; - char *srcParam, *dstParam; - - /* First, clear all preference settings */ - memset (&pref, 0, sizeof(pref)); - prefFile = NULL; - - /* Now try and find a ~/.xwinrc file */ - home = getenv ("HOME"); - if (home) - { - strcpy (fname, home); - if (fname[strlen(fname)-1]!='/') - strcat (fname, "/"); - strcat (fname, ".XWinrc"); - - prefFile = fopen (fname, "r"); - if (prefFile) - { - winDebug ("winPrefsLoadPreferences: %s\n", fname); - } - } - - /* No home file found, check system default */ - if (!prefFile) - { - char buffer[MAX_PATH]; -#ifdef RELOCATE_PROJECTROOT - snprintf(buffer, sizeof(buffer), "%s\\system.XWinrc", winGetBaseDir()); -#else - strncpy(buffer, SYSCONFDIR"/X11/system.XWinrc", sizeof(buffer)); -#endif - buffer[sizeof(buffer)-1] = 0; - prefFile = fopen (buffer, "r"); - if (prefFile) - { - winDebug ("winPrefsLoadPreferences: %s\n", buffer); - } - } - - /* If we could open it, then read the settings and close it */ - if (prefFile) - { - parse_file (prefFile); - fclose (prefFile); - } - - /* Setup a DISPLAY environment variable, need to allocate on heap */ - /* because putenv doesn't copy the argument... Always use screen 0 */ - winGetDisplayName(szDisplay, 0); - szEnvDisplay = (char *)(malloc(strlen(szDisplay)+9/*strlen("DISPLAY=")+1*/)); - snprintf(szEnvDisplay, 512, "DISPLAY=%s", szDisplay); - putenv (szEnvDisplay); - - /* Replace any "%display%" in menu commands with display string */ - for (i=0; i<pref.menuItems; i++) - { - for (j=0; j<pref.menu[i].menuItems; j++) - { - if (pref.menu[i].menuItem[j].cmd==CMD_EXEC) - { - srcParam = pref.menu[i].menuItem[j].param; - dstParam = param; - while (*srcParam) { - if (!strncmp(srcParam, "%display%", 9)) - { - memcpy (dstParam, szDisplay, strlen(szDisplay)); - dstParam += strlen(szDisplay); - srcParam += 9; - } - else if (!strncmp(srcParam, "%logfile%", 9)) - { - memcpy (dstParam, g_pszLogFile, strlen(g_pszLogFile)); - dstParam += strlen(g_pszLogFile); - srcParam += 9; - } - else - { - *dstParam = *srcParam; - dstParam++; - srcParam++; - } - } - *dstParam = 0; - strcpy (pref.menu[i].menuItem[j].param, param); - } /* cmd==cmd_exec */ - } /* for all menuitems */ - } /* for all menus */ - -} - - -/* - * Check for a match of the window class to one specified in the - * STYLES{} section in the prefs file, and return the style type - */ -unsigned long -winOverrideStyle (unsigned long longpWin) -{ - WindowPtr pWin = (WindowPtr) longpWin; - char *res_name, *res_class; - int i; - char *wmName; - - if (pWin==NULL) - return STYLE_NONE; - - /* If we can't find the class, we can't override from default! */ - if (!winMultiWindowGetClassHint (pWin, &res_name, &res_class)) - return STYLE_NONE; - - winMultiWindowGetWMName (pWin, &wmName); - - for (i=0; i<pref.styleItems; i++) { - if (!strcmp(pref.style[i].match, res_name) || - !strcmp(pref.style[i].match, res_class) || - (wmName && strstr(wmName, pref.style[i].match))) - { - free (res_name); - free (res_class); - if (wmName) - free (wmName); - - if (pref.style[i].type) - return pref.style[i].type; - } - } - - /* Didn't find the style, fail gracefully */ - free (res_name); - free (res_class); - if (wmName) - free (wmName); - - return STYLE_NONE; -} +/*
+ * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
+ * Copyright (C) Colin Harrison 2005-2008
+ *
+ * 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, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * 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. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the XFree86 Project
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * from the XFree86 Project.
+ *
+ * Authors: Earle F. Philhower, III
+ * Colin Harrison
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef __CYGWIN__
+#include <sys/resource.h>
+#endif
+#include "win.h"
+
+#include <X11/Xwindows.h>
+#include <shellapi.h>
+
+#include "winprefs.h"
+#include "winmultiwindowclass.h"
+
+/* Where will the custom menu commands start counting from? */
+#define STARTMENUID WM_USER
+
+/* External global variables */
+#ifdef XWIN_MULTIWINDOW
+extern DWORD g_dwCurrentThreadID;
+#endif
+
+extern const char *winGetBaseDir(void);
+
+extern const char *g_pszLogFile;
+
+/* From winmultiwindowflex.l, the real parser */
+extern void parse_file (FILE *fp);
+
+/* From winprefyacc.y, the pref structure loaded by the parser */
+extern WINPREFS pref;
+
+/* The global X default icon */
+extern HICON g_hIconX;
+extern HICON g_hSmallIconX;
+
+/* Currently in use command ID, incremented each new menu item created */
+static int g_cmdid = STARTMENUID;
+
+
+/* Defined in DIX */
+extern char *display;
+
+/* Local function to handle comma-ified icon names */
+static HICON
+LoadImageComma (char *fname, int sx, int sy, int flags);
+
+
+/*
+ * Creates or appends a menu from a MENUPARSED structure
+ */
+static HMENU
+MakeMenu (char *name,
+ HMENU editMenu,
+ int editItem)
+{
+ int i;
+ int item;
+ MENUPARSED *m;
+ HMENU hmenu, hsub;
+
+ for (i=0; i<pref.menuItems; i++)
+ {
+ if (!strcmp(name, pref.menu[i].menuName))
+ break;
+ }
+
+ /* Didn't find a match, bummer */
+ if (i==pref.menuItems)
+ {
+ ErrorF("MakeMenu: Can't find menu %s\n", name);
+ return NULL;
+ }
+
+ m = &(pref.menu[i]);
+
+ if (editMenu)
+ {
+ hmenu = editMenu;
+ item = editItem;
+ }
+ else
+ {
+ hmenu = CreatePopupMenu();
+ if (!hmenu)
+ {
+ ErrorF("MakeMenu: Unable to CreatePopupMenu() %s\n", name);
+ return NULL;
+ }
+ item = 0;
+ }
+
+ /* Add the menu items */
+ for (i=0; i<m->menuItems; i++)
+ {
+ /* Only assign IDs one time... */
+ if ( m->menuItem[i].commandID == 0 )
+ m->menuItem[i].commandID = g_cmdid++;
+
+ switch (m->menuItem[i].cmd)
+ {
+ case CMD_EXEC:
+ case CMD_ALWAYSONTOP:
+ case CMD_RELOAD:
+ InsertMenu (hmenu,
+ item,
+ MF_BYPOSITION|MF_ENABLED|MF_STRING,
+ m->menuItem[i].commandID,
+ m->menuItem[i].text);
+ break;
+
+ case CMD_SEPARATOR:
+ InsertMenu (hmenu,
+ item,
+ MF_BYPOSITION|MF_SEPARATOR,
+ 0,
+ NULL);
+ break;
+
+ case CMD_MENU:
+ /* Recursive! */
+ hsub = MakeMenu (m->menuItem[i].param, 0, 0);
+ if (hsub)
+ InsertMenu (hmenu,
+ item,
+ MF_BYPOSITION|MF_POPUP|MF_ENABLED|MF_STRING,
+ (UINT_PTR)hsub,
+ m->menuItem[i].text);
+ break;
+ }
+
+ /* If item==-1 (means to add at end of menu) don't increment) */
+ if (item>=0)
+ item++;
+ }
+
+ return hmenu;
+}
+
+
+#ifdef XWIN_MULTIWINDOW
+/*
+ * Callback routine that is executed once per window class.
+ * Removes or creates custom window settings depending on LPARAM
+ */
+static wBOOL CALLBACK
+ReloadEnumWindowsProc (HWND hwnd, LPARAM lParam)
+{
+ HICON hicon;
+ Window wid;
+
+ if (!hwnd) {
+ ErrorF("ReloadEnumWindowsProc: hwnd==NULL!\n");
+ return FALSE;
+ }
+
+ /* It's our baby, either clean or dirty it */
+ if (lParam==FALSE)
+ {
+ /* Reset the window's icon to undefined. */
+ hicon = (HICON)SendMessage(hwnd, WM_SETICON, ICON_BIG, 0);
+
+ /* If the old icon is generated on-the-fly, get rid of it, will regen */
+ winDestroyIcon (hicon);
+
+ /* Same for the small icon */
+ hicon = (HICON)SendMessage(hwnd, WM_SETICON, ICON_SMALL, 0);
+ winDestroyIcon (hicon);
+
+ /* Remove any menu additions; bRevert=TRUE destroys any modified menus */
+ GetSystemMenu (hwnd, TRUE);
+
+ /* This window is now clean of our taint (but with undefined icons) */
+ }
+ else
+ {
+ /* winUpdateIcon() will set the icon default, dynamic, or from xwinrc */
+ wid = (Window)GetProp (hwnd, WIN_WID_PROP);
+ if (wid)
+ winUpdateIcon (wid);
+
+ /* Update the system menu for this window */
+ SetupSysMenu ((unsigned long)hwnd);
+
+ /* That was easy... */
+ }
+
+ return TRUE;
+}
+#endif
+
+
+/*
+ * Removes any custom icons in classes, custom menus, etc.
+ * Frees all members in pref structure.
+ * Reloads the preferences file.
+ * Set custom icons and menus again.
+ */
+static void
+ReloadPrefs (void)
+{
+ int i;
+
+#ifdef XWIN_MULTIWINDOW
+ /* First, iterate over all windows, deleting their icons and custom menus.
+ * This is really only needed because winDestroyIcon() will try to
+ * destroy the old global icons, which will have changed.
+ * It is probably better to set a windows USER_DATA to flag locally defined
+ * icons, and use that to accurately know when to destroy old icons.
+ */
+ EnumThreadWindows (g_dwCurrentThreadID, ReloadEnumWindowsProc, FALSE);
+#endif
+
+ /* Now, free/clear all info from our prefs structure */
+ for (i=0; i<pref.menuItems; i++)
+ free (pref.menu[i].menuItem);
+ free (pref.menu);
+ pref.menu = NULL;
+ pref.menuItems = 0;
+
+ pref.rootMenuName[0] = 0;
+
+ free (pref.sysMenu);
+ pref.sysMenuItems = 0;
+
+ pref.defaultSysMenuName[0] = 0;
+ pref.defaultSysMenuPos = 0;
+
+ pref.iconDirectory[0] = 0;
+ pref.defaultIconName[0] = 0;
+ pref.trayIconName[0] = 0;
+
+ for (i=0; i<pref.iconItems; i++)
+ if (pref.icon[i].hicon)
+ DestroyIcon ((HICON)pref.icon[i].hicon);
+ free (pref.icon);
+ pref.icon = NULL;
+ pref.iconItems = 0;
+
+ /* Free global default X icon */
+ if (g_hIconX)
+ DestroyIcon (g_hIconX);
+ if (g_hSmallIconX)
+ DestroyIcon (g_hSmallIconX);
+
+ /* Reset the custom command IDs */
+ g_cmdid = STARTMENUID;
+
+ /* Load the updated resource file */
+ LoadPreferences();
+
+ g_hIconX = NULL;
+ g_hSmallIconX = NULL;
+
+#ifdef XWIN_MULTIWINDOW
+ winInitGlobalIcons();
+#endif
+
+#ifdef XWIN_MULTIWINDOW
+ /* Rebuild the icons and menus */
+ EnumThreadWindows (g_dwCurrentThreadID, ReloadEnumWindowsProc, TRUE);
+#endif
+
+ /* Whew, done */
+}
+
+/*
+ * Check/uncheck the ALWAYSONTOP items in this menu
+ */
+void
+HandleCustomWM_INITMENU(unsigned long hwndIn,
+ unsigned long hmenuIn)
+{
+ HWND hwnd;
+ HMENU hmenu;
+ DWORD dwExStyle;
+ int i, j;
+
+ hwnd = (HWND)hwndIn;
+ hmenu = (HMENU)hmenuIn;
+ if (!hwnd || !hmenu)
+ return;
+
+ if (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST)
+ dwExStyle = MF_BYCOMMAND | MF_CHECKED;
+ else
+ dwExStyle = MF_BYCOMMAND | MF_UNCHECKED;
+
+ for (i=0; i<pref.menuItems; i++)
+ for (j=0; j<pref.menu[i].menuItems; j++)
+ if (pref.menu[i].menuItem[j].cmd==CMD_ALWAYSONTOP)
+ CheckMenuItem (hmenu, pref.menu[i].menuItem[j].commandID, dwExStyle );
+
+}
+
+/*
+ * Searches for the custom WM_COMMAND command ID and performs action.
+ * Return TRUE if command is proccessed, FALSE otherwise.
+ */
+Bool
+HandleCustomWM_COMMAND (unsigned long hwndIn,
+ int command)
+{
+ HWND hwnd;
+ int i, j;
+ MENUPARSED *m;
+ DWORD dwExStyle;
+
+ hwnd = (HWND)hwndIn;
+
+ if (!command)
+ return FALSE;
+
+ for (i=0; i<pref.menuItems; i++)
+ {
+ m = &(pref.menu[i]);
+ for (j=0; j<m->menuItems; j++)
+ {
+ if (command==m->menuItem[j].commandID)
+ {
+ /* Match! */
+ switch(m->menuItem[j].cmd)
+ {
+#ifdef __CYGWIN__
+ case CMD_EXEC:
+ if (fork()==0)
+ {
+ struct rlimit rl;
+ unsigned long i;
+
+ /* Close any open descriptors except for STD* */
+ getrlimit (RLIMIT_NOFILE, &rl);
+ for (i = STDERR_FILENO+1; i < rl.rlim_cur; i++)
+ close(i);
+
+ /* Disassociate any TTYs */
+ setsid();
+
+ execl ("/bin/sh",
+ "/bin/sh",
+ "-c",
+ m->menuItem[j].param,
+ NULL);
+ exit (0);
+ }
+ else
+ return TRUE;
+ break;
+#else
+ case CMD_EXEC:
+ {
+ /* Start process without console window */
+ STARTUPINFO start;
+ PROCESS_INFORMATION child;
+
+ memset (&start, 0, sizeof (start));
+ start.cb = sizeof (start);
+ //start.dwFlags = STARTF_USESHOWWINDOW;
+ //start.wShowWindow = SW_HIDE;
+
+ memset (&child, 0, sizeof (child));
+
+ if (CreateProcess (NULL, m->menuItem[j].param, NULL, NULL, FALSE, 0,
+ NULL, NULL, &start, &child))
+ {
+ CloseHandle (child.hThread);
+ CloseHandle (child.hProcess);
+ }
+ else
+ MessageBox(NULL, m->menuItem[j].param, "VcXsrv Exec Command Error!", MB_OK | MB_ICONEXCLAMATION);
+ }
+ return TRUE;
+#endif
+ case CMD_ALWAYSONTOP:
+ if (!hwnd)
+ return FALSE;
+
+ /* Get extended window style */
+ dwExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
+
+ /* Handle topmost windows */
+ if (dwExStyle & WS_EX_TOPMOST)
+ SetWindowPos (hwnd,
+ HWND_NOTOPMOST,
+ 0, 0,
+ 0, 0,
+ SWP_NOSIZE | SWP_NOMOVE);
+ else
+ SetWindowPos (hwnd,
+ HWND_TOPMOST,
+ 0, 0,
+ 0, 0,
+ SWP_NOSIZE | SWP_NOMOVE);
+#if XWIN_MULTIWINDOW
+ /* Reflect the changed Z order */
+ winReorderWindowsMultiWindow ();
+#endif
+ return TRUE;
+
+ case CMD_RELOAD:
+ ReloadPrefs();
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+ } /* match */
+ } /* for j */
+ } /* for i */
+
+ return FALSE;
+}
+
+
+#ifdef XWIN_MULTIWINDOW
+/*
+ * Add the default or a custom menu depending on the class match
+ */
+void
+SetupSysMenu (unsigned long hwndIn)
+{
+ HWND hwnd;
+ HMENU sys;
+ int i;
+ WindowPtr pWin;
+ char *res_name, *res_class;
+
+ hwnd = (HWND)hwndIn;
+ if (!hwnd)
+ return;
+
+ pWin = GetProp (hwnd, WIN_WINDOW_PROP);
+
+ sys = GetSystemMenu (hwnd, FALSE);
+ if (!sys)
+ return;
+
+ if (pWin)
+ {
+ /* First see if there's a class match... */
+ if (winMultiWindowGetClassHint (pWin, &res_name, &res_class))
+ {
+ for (i=0; i<pref.sysMenuItems; i++)
+ {
+ if (!strcmp(pref.sysMenu[i].match, res_name) ||
+ !strcmp(pref.sysMenu[i].match, res_class) )
+ {
+ free(res_name);
+ free(res_class);
+
+ MakeMenu (pref.sysMenu[i].menuName, sys,
+ pref.sysMenu[i].menuPos==AT_START?0:-1);
+ return;
+ }
+ }
+
+ /* No match, just free alloc'd strings */
+ free(res_name);
+ free(res_class);
+ } /* Found wm_class */
+ } /* if pwin */
+
+ /* Fallback to system default */
+ if (pref.defaultSysMenuName[0])
+ {
+ if (pref.defaultSysMenuPos==AT_START)
+ MakeMenu (pref.defaultSysMenuName, sys, 0);
+ else
+ MakeMenu (pref.defaultSysMenuName, sys, -1);
+ }
+}
+#endif
+
+
+/*
+ * Possibly add a menu to the toolbar icon
+ */
+void
+SetupRootMenu (unsigned long hmenuRoot)
+{
+ HMENU root;
+
+ root = (HMENU)hmenuRoot;
+ if (!root)
+ return;
+
+ if (pref.rootMenuName[0])
+ {
+ MakeMenu(pref.rootMenuName, root, 0);
+ }
+}
+
+
+/*
+ * Check for and return an overridden default ICON specified in the prefs
+ */
+HICON
+winOverrideDefaultIcon(int size)
+{
+ HICON hicon;
+
+ if (pref.defaultIconName[0])
+ {
+ hicon = LoadImageComma (pref.defaultIconName, size, size, 0);
+ if (hicon==NULL)
+ ErrorF ("winOverrideDefaultIcon: LoadImageComma(%s) failed\n",
+ pref.defaultIconName);
+
+ return hicon;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Return the HICON to use in the taskbar notification area
+ */
+HICON
+winTaskbarIcon(void)
+{
+ HICON hicon;
+
+ hicon = 0;
+ /* First try and load an overridden, if success then return it */
+ if (pref.trayIconName[0])
+ {
+ hicon = LoadImageComma (pref.trayIconName,
+ GetSystemMetrics (SM_CXSMICON),
+ GetSystemMetrics (SM_CYSMICON),
+ 0 );
+ }
+
+ /* Otherwise return the default */
+ if (!hicon)
+ hicon = (HICON) LoadImage (g_hInstance,
+ MAKEINTRESOURCE(IDI_XWIN),
+ IMAGE_ICON,
+ GetSystemMetrics (SM_CXSMICON),
+ GetSystemMetrics (SM_CYSMICON),
+ 0);
+
+ return hicon;
+}
+
+
+/*
+ * Parse a filename to extract an icon:
+ * If fname is exactly ",nnn" then extract icon from our resource
+ * else if it is "file,nnn" then extract icon nnn from that file
+ * else try to load it as an .ico file and if that fails return NULL
+ */
+static HICON
+LoadImageComma (char *fname, int sx, int sy, int flags)
+{
+ HICON hicon;
+ int index;
+ char file[PATH_MAX+NAME_MAX+2];
+
+ /* Some input error checking */
+ if (!fname || !fname[0])
+ return NULL;
+
+ index = 0;
+ hicon = NULL;
+
+ if (fname[0]==',')
+ {
+ /* It's the XWIN.EXE resource they want */
+ index = atoi (fname+1);
+ hicon = LoadImage (g_hInstance,
+ MAKEINTRESOURCE(index),
+ IMAGE_ICON,
+ sx,
+ sy,
+ flags);
+ }
+ else
+ {
+ file[0] = 0;
+ /* Prepend path if not given a "X:\" filename */
+ if ( !(fname[0] && fname[1]==':' && fname[2]=='\\') )
+ {
+ strcpy (file, pref.iconDirectory);
+ if (pref.iconDirectory[0])
+ if (fname[strlen(fname)-1]!='\\')
+ strcat (file, "\\");
+ }
+ strcat (file, fname);
+
+ if (strrchr (file, ','))
+ {
+ /* Specified as <fname>,<index> */
+
+ *(strrchr (file, ',')) = 0; /* End string at comma */
+ index = atoi (strrchr (fname, ',') + 1);
+ hicon = ExtractIcon (g_hInstance, file, index);
+ }
+ else
+ {
+ /* Just an .ico file... */
+
+ hicon = (HICON)LoadImage (NULL,
+ file,
+ IMAGE_ICON,
+ sx,
+ sy,
+ LR_LOADFROMFILE|flags);
+ }
+ }
+ return hicon;
+}
+
+/*
+ * Check for a match of the window class to one specified in the
+ * ICONS{} section in the prefs file, and load the icon from a file
+ */
+HICON
+winOverrideIcon (unsigned long longWin)
+{
+ WindowPtr pWin = (WindowPtr) longWin;
+ char *res_name, *res_class;
+ int i;
+ HICON hicon;
+ char *wmName;
+
+ if (pWin==NULL)
+ return 0;
+
+ /* If we can't find the class, we can't override from default! */
+ if (!winMultiWindowGetClassHint (pWin, &res_name, &res_class))
+ return 0;
+
+ winMultiWindowGetWMName (pWin, &wmName);
+
+ for (i=0; i<pref.iconItems; i++) {
+ if (!strcmp(pref.icon[i].match, res_name) ||
+ !strcmp(pref.icon[i].match, res_class) ||
+ (wmName && strstr(wmName, pref.icon[i].match)))
+ {
+ free (res_name);
+ free (res_class);
+ free(wmName);
+
+ if (pref.icon[i].hicon)
+ return pref.icon[i].hicon;
+
+ hicon = LoadImageComma (pref.icon[i].iconFile, 0, 0, LR_DEFAULTSIZE);
+ if (hicon==NULL)
+ ErrorF ("winOverrideIcon: LoadImageComma(%s) failed\n",
+ pref.icon[i].iconFile);
+
+ pref.icon[i].hicon = hicon;
+ return hicon;
+ }
+ }
+
+ /* Didn't find the icon, fail gracefully */
+ free (res_name);
+ free (res_class);
+ free(wmName);
+
+ return 0;
+}
+
+
+/*
+ * Should we free this icon or leave it in memory (is it part of our
+ * ICONS{} overrides)?
+ */
+int
+winIconIsOverride(unsigned hiconIn)
+{
+ HICON hicon;
+ int i;
+
+ hicon = (HICON)hiconIn;
+
+ if (!hicon)
+ return 0;
+
+ for (i=0; i<pref.iconItems; i++)
+ if ((HICON)pref.icon[i].hicon == hicon)
+ return 1;
+
+ return 0;
+}
+
+
+
+/*
+ * Try and open ~/.XWinrc and system.XWinrc
+ * Load it into prefs structure for use by other functions
+ */
+void
+LoadPreferences (void)
+{
+ char *home;
+ char fname[PATH_MAX+NAME_MAX+2];
+ FILE *prefFile;
+ char szDisplay[512];
+ char *szEnvDisplay;
+ int i, j;
+ char param[PARAM_MAX+1];
+ char *srcParam, *dstParam;
+
+ /* First, clear all preference settings */
+ memset (&pref, 0, sizeof(pref));
+ prefFile = NULL;
+
+ /* Now try and find a ~/.xwinrc file */
+ home = getenv ("HOME");
+ if (home)
+ {
+ strcpy (fname, home);
+ if (fname[strlen(fname)-1]!='/')
+ strcat (fname, "/");
+ strcat (fname, ".XWinrc");
+
+ prefFile = fopen (fname, "r");
+ if (prefFile)
+ {
+ winDebug ("winPrefsLoadPreferences: %s\n", fname);
+ }
+ }
+
+ /* No home file found, check system default */
+ if (!prefFile)
+ {
+ char buffer[MAX_PATH];
+#ifdef RELOCATE_PROJECTROOT
+ snprintf(buffer, sizeof(buffer), "%s\\system.XWinrc", winGetBaseDir());
+#else
+ strncpy(buffer, SYSCONFDIR"/X11/system.XWinrc", sizeof(buffer));
+#endif
+ buffer[sizeof(buffer)-1] = 0;
+ prefFile = fopen (buffer, "r");
+ if (prefFile)
+ {
+ winDebug ("winPrefsLoadPreferences: %s\n", buffer);
+ }
+ }
+
+ /* If we could open it, then read the settings and close it */
+ if (prefFile)
+ {
+ parse_file (prefFile);
+ fclose (prefFile);
+ }
+
+ /* Setup a DISPLAY environment variable, need to allocate on heap */
+ /* because putenv doesn't copy the argument... Always use screen 0 */
+ winGetDisplayName(szDisplay, 0);
+ szEnvDisplay = (char *)(malloc(strlen(szDisplay)+9/*strlen("DISPLAY=")+1*/));
+ snprintf(szEnvDisplay, 512, "DISPLAY=%s", szDisplay);
+ putenv (szEnvDisplay);
+
+ /* Replace any "%display%" in menu commands with display string */
+ for (i=0; i<pref.menuItems; i++)
+ {
+ for (j=0; j<pref.menu[i].menuItems; j++)
+ {
+ if (pref.menu[i].menuItem[j].cmd==CMD_EXEC)
+ {
+ srcParam = pref.menu[i].menuItem[j].param;
+ dstParam = param;
+ while (*srcParam) {
+ if (!strncmp(srcParam, "%display%", 9))
+ {
+ memcpy (dstParam, szDisplay, strlen(szDisplay));
+ dstParam += strlen(szDisplay);
+ srcParam += 9;
+ }
+ else if (!strncmp(srcParam, "%logfile%", 9))
+ {
+ memcpy (dstParam, g_pszLogFile, strlen(g_pszLogFile));
+ dstParam += strlen(g_pszLogFile);
+ srcParam += 9;
+ }
+ else
+ {
+ *dstParam = *srcParam;
+ dstParam++;
+ srcParam++;
+ }
+ }
+ *dstParam = 0;
+ strcpy (pref.menu[i].menuItem[j].param, param);
+ } /* cmd==cmd_exec */
+ } /* for all menuitems */
+ } /* for all menus */
+
+}
+
+
+/*
+ * Check for a match of the window class to one specified in the
+ * STYLES{} section in the prefs file, and return the style type
+ */
+unsigned long
+winOverrideStyle (unsigned long longpWin)
+{
+ WindowPtr pWin = (WindowPtr) longpWin;
+ char *res_name, *res_class;
+ int i;
+ char *wmName;
+
+ if (pWin==NULL)
+ return STYLE_NONE;
+
+ /* If we can't find the class, we can't override from default! */
+ if (!winMultiWindowGetClassHint (pWin, &res_name, &res_class))
+ return STYLE_NONE;
+
+ winMultiWindowGetWMName (pWin, &wmName);
+
+ for (i=0; i<pref.styleItems; i++) {
+ if (!strcmp(pref.style[i].match, res_name) ||
+ !strcmp(pref.style[i].match, res_class) ||
+ (wmName && strstr(wmName, pref.style[i].match)))
+ {
+ free (res_name);
+ free (res_class);
+ free(wmName);
+
+ if (pref.style[i].type)
+ return pref.style[i].type;
+ }
+ }
+
+ /* Didn't find the style, fail gracefully */
+ free (res_name);
+ free (res_class);
+ free(wmName);
+
+ return STYLE_NONE;
+}
diff --git a/xorg-server/hw/xwin/winscrinit.c b/xorg-server/hw/xwin/winscrinit.c index 501a999a4..5273460a4 100644 --- a/xorg-server/hw/xwin/winscrinit.c +++ b/xorg-server/hw/xwin/winscrinit.c @@ -1,775 +1,775 @@ -/* - *Copyright (C) 1994-2000 The XFree86 Project, 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, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *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. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of the XFree86 Project - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from the XFree86 Project. - * - * Authors: Dakshinamurthy Karra - * Suhaib M Siddiqi - * Peter Busch - * Harold L Hunt II - * Kensuke Matsuzaki - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" -#include "winmsg.h" - - -#ifdef XWIN_MULTIWINDOWEXTWM -static RootlessFrameProcsRec -winMWExtWMProcs = { - winMWExtWMCreateFrame, - winMWExtWMDestroyFrame, - - winMWExtWMMoveFrame, - winMWExtWMResizeFrame, - winMWExtWMRestackFrame, - winMWExtWMReshapeFrame, - winMWExtWMUnmapFrame, - - winMWExtWMStartDrawing, - winMWExtWMStopDrawing, - winMWExtWMUpdateRegion, -#ifndef ROOTLESS_TRACK_DAMAGE - winMWExtWMDamageRects, -#endif - winMWExtWMRootlessSwitchWindow, - NULL,//winMWExtWMDoReorderWindow, - NULL,//winMWExtWMHideWindow, - NULL,//winMWExtWMUpdateColorMap, - - NULL,//winMWExtWMCopyBytes, - NULL,//winMWExtWMFillBytes, - NULL,//winMWExtWMCompositePixels, - winMWExtWMCopyWindow -}; -#endif - - -/* - * References to external symbols - */ - -extern Bool g_fSoftwareCursor; - - -/* - * Prototypes - */ - -Bool -winRandRInit (ScreenPtr pScreen); - - -/* - * Local functions - */ - -static Bool -winSaveScreen (ScreenPtr pScreen, int on); - - -/* - * Determine what type of screen we are initializing - * and call the appropriate procedure to intiailize - * that type of screen. - */ - -Bool -winScreenInit (int index, - ScreenPtr pScreen, - int argc, char **argv) -{ - winScreenInfoPtr pScreenInfo = &g_ScreenInfo[index]; - winPrivScreenPtr pScreenPriv; - HDC hdc; - - winDebug ("winScreenInit - dwWidth: %ld dwHeight: %ld\n", - pScreenInfo->dwWidth, pScreenInfo->dwHeight); - - /* Allocate privates for this screen */ - if (!winAllocatePrivates (pScreen)) - { - ErrorF ("winScreenInit - Couldn't allocate screen privates\n"); - return FALSE; - } - - /* Get a pointer to the privates structure that was allocated */ - pScreenPriv = winGetScreenPriv (pScreen); - - /* Save a pointer to this screen in the screen info structure */ - pScreenInfo->pScreen = pScreen; - - /* Save a pointer to the screen info in the screen privates structure */ - /* This allows us to get back to the screen info from a screen pointer */ - pScreenPriv->pScreenInfo = pScreenInfo; - - /* - * Determine which engine to use. - * - * NOTE: This is done once per screen because each screen possibly has - * a preferred engine specified on the command line. - */ - if (!winSetEngine (pScreen)) - { - ErrorF ("winScreenInit - winSetEngine () failed\n"); - return FALSE; - } - - /* Adjust the video mode for our engine type */ - if (pScreenPriv->pwinAdjustVideoMode && !(*pScreenPriv->pwinAdjustVideoMode) (pScreen)) - { - ErrorF ("winScreenInit - winAdjustVideoMode () failed\n"); - return FALSE; - } - - /* Check for supported display depth */ - if (!(WIN_SUPPORTED_BPPS & (1 << (pScreenInfo->dwBPP - 1)))) - { - ErrorF ("winScreenInit - Unsupported display depth: %d\n" \ - "Change your Windows display depth to 15, 16, 24, or 32 bits " - "per pixel.\n", - (int) pScreenInfo->dwBPP); - ErrorF ("winScreenInit - Supported depths: %08x\n", - WIN_SUPPORTED_BPPS); -#if WIN_CHECK_DEPTH - return FALSE; -#endif - } - - /* - * Check that all monitors have the same display depth if we are using - * multiple monitors - */ - if (pScreenInfo->fMultipleMonitors - && !GetSystemMetrics (SM_SAMEDISPLAYFORMAT)) - { - ErrorF ("winScreenInit - Monitors do not all have same pixel format / " - "display depth.\n" - "Using primary display only.\n"); - pScreenInfo->fMultipleMonitors = FALSE; - } - - /* Create display window */ - if (pScreenPriv->pwinCreateBoundingWindow && !(*pScreenPriv->pwinCreateBoundingWindow) (pScreen)) - { - ErrorF ("winScreenInit - pwinCreateBoundingWindow () " - "failed\n"); - return FALSE; - } - - /* Get a device context */ - hdc = GetDC (pScreenPriv->hwndScreen); - - /* Store the initial height, width, and depth of the display */ - /* Are we using multiple monitors? */ - if (pScreenInfo->fMultipleMonitors) - { - pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN); - pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN); - - /* - * In this case, some of the defaults set in - * winInitializeScreenDefaults() are not correct ... - */ - if (!pScreenInfo->fUserGaveHeightAndWidth) - { - pScreenInfo->dwWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN); - pScreenInfo->dwHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN); - pScreenInfo->dwWidth_mm = (pScreenInfo->dwWidth / - WIN_DEFAULT_DPI) * 25.4; - pScreenInfo->dwHeight_mm = (pScreenInfo->dwHeight / - WIN_DEFAULT_DPI) * 25.4; - } - } - else - { - pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXSCREEN); - pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYSCREEN); - } - - /* Save the original bits per pixel */ - pScreenPriv->dwLastWindowsBitsPixel = GetDeviceCaps (hdc, BITSPIXEL); - - /* Release the device context */ - ReleaseDC (pScreenPriv->hwndScreen, hdc); - - /* Clear the visuals list */ - miClearVisualTypes (); - - /* Set the padded screen width */ - pScreenInfo->dwPaddedWidth = PixmapBytePad (pScreenInfo->dwWidth, - pScreenInfo->dwBPP); - - /* Call the engine dependent screen initialization procedure */ - if (pScreenPriv->pwinFinishScreenInit && !((*pScreenPriv->pwinFinishScreenInit) (index, pScreen, argc, argv))) - { - ErrorF ("winScreenInit - winFinishScreenInit () failed\n"); - return FALSE; - } - - if (!g_fSoftwareCursor) - winInitCursor(pScreen); -#ifdef WINDBG - else - winDebug("winScreenInit - Using software cursor\n"); -#endif - - /* - Note the screen origin in a normalized coordinate space where (0,0) is at the top left - of the native virtual desktop area - */ - dixScreenOrigins[index].x = pScreenInfo->dwInitialX - GetSystemMetrics(SM_XVIRTUALSCREEN); - dixScreenOrigins[index].y = pScreenInfo->dwInitialY - GetSystemMetrics(SM_YVIRTUALSCREEN); - - winDebug("Screen %d added at virtual desktop coordinate (%d,%d).\n", - index, dixScreenOrigins[index].x, dixScreenOrigins[index].y); - winDebug ("winScreenInit - returning\n"); - - return TRUE; -} - -static Bool -winCreateScreenResources(ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - Bool result; - - result = pScreenPriv->pwinCreateScreenResources(pScreen); - - /* Now the screen bitmap has been wrapped in a pixmap, - add that to the Shadow framebuffer */ - if (!shadowAdd(pScreen, pScreen->devPrivate, - pScreenPriv->pwinShadowUpdate, NULL, 0, 0)) - { - ErrorF ("winCreateScreenResources - shadowAdd () failed\n"); - return FALSE; - } - - return result; -} - -/* See Porting Layer Definition - p. 20 */ -Bool -winFinishScreenInitFB (int index, - ScreenPtr pScreen, - int argc, char **argv) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - VisualPtr pVisual = NULL; - char *pbits = NULL; -#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) - int iReturn; -#endif - - /* Create framebuffer */ - if (!(*pScreenPriv->pwinAllocateFB) (pScreen)) - { - ErrorF ("winFinishScreenInitFB - Could not allocate framebuffer\n"); - return FALSE; - } - - /* - * Grab the number of bits that are used to represent color in each pixel. - */ - if (pScreenInfo->dwBPP == 8) - pScreenInfo->dwDepth = 8; - else - pScreenInfo->dwDepth = winCountBits (pScreenPriv->dwRedMask) - + winCountBits (pScreenPriv->dwGreenMask) - + winCountBits (pScreenPriv->dwBlueMask); - - winDebug ("winFinishScreenInitFB - Masks: %08x %08x %08x\n", - (unsigned int) pScreenPriv->dwRedMask, - (unsigned int) pScreenPriv->dwGreenMask, - (unsigned int) pScreenPriv->dwBlueMask); - - /* Init visuals */ - if (!(*pScreenPriv->pwinInitVisuals) (pScreen)) - { - ErrorF ("winFinishScreenInitFB - winInitVisuals failed\n"); - return FALSE; - } - - /* Setup a local variable to point to the framebuffer */ - pbits = pScreenInfo->pfb; - - /* Apparently we need this for the render extension */ - miSetPixmapDepths (); - - /* Start fb initialization */ - if (!fbSetupScreen (pScreen, - pScreenInfo->pfb, - pScreenInfo->dwWidth, pScreenInfo->dwHeight, - monitorResolution, monitorResolution, - pScreenInfo->dwStride, - pScreenInfo->dwBPP)) - { - ErrorF ("winFinishScreenInitFB - fbSetupScreen failed\n"); - return FALSE; - } - - /* Override default colormap routines if visual class is dynamic */ - if (pScreenInfo->dwDepth == 8 - && (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI - || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL - && pScreenInfo->fFullScreen) - || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD - && pScreenInfo->fFullScreen))) - { - winSetColormapFunctions (pScreen); - - /* - * NOTE: Setting whitePixel to 255 causes Magic 7.1 to allocate its - * own colormap, as it cannot allocate 7 planes in the default - * colormap. Setting whitePixel to 1 allows Magic to get 7 - * planes in the default colormap, so it doesn't create its - * own colormap. This latter situation is highly desireable, - * as it keeps the Magic window viewable when switching to - * other X clients that use the default colormap. - */ - pScreen->blackPixel = 0; - pScreen->whitePixel = 1; - } - - /* Place our save screen function */ - pScreen->SaveScreen = winSaveScreen; - - /* Finish fb initialization */ - if (!fbFinishScreenInit (pScreen, - pScreenInfo->pfb, - pScreenInfo->dwWidth, pScreenInfo->dwHeight, - monitorResolution, monitorResolution, - pScreenInfo->dwStride, - pScreenInfo->dwBPP)) - { - ErrorF ("winFinishScreenInitFB - fbFinishScreenInit failed\n"); - return FALSE; - } - - /* Save a pointer to the root visual */ - for (pVisual = pScreen->visuals; - pVisual->vid != pScreen->rootVisual; - pVisual++); - pScreenPriv->pRootVisual = pVisual; - - /* - * Setup points to the block and wakeup handlers. Pass a pointer - * to the current screen as pWakeupdata. - */ - pScreen->BlockHandler = winBlockHandler; - pScreen->WakeupHandler = winWakeupHandler; - pScreen->blockData = pScreen; - pScreen->wakeupData = pScreen; - - /* Render extension initialization, calls miPictureInit */ - if (!fbPictureInit (pScreen, NULL, 0)) - { - ErrorF ("winFinishScreenInitFB - fbPictureInit () failed\n"); - return FALSE; - } - -#ifdef RANDR - /* Initialize resize and rotate support */ - if (!winRandRInit (pScreen)) - { - ErrorF ("winFinishScreenInitFB - winRandRInit () failed\n"); - return FALSE; - } -#endif - - /* - * Backing store support should reduce network traffic and increase - * performance. - */ - miInitializeBackingStore (pScreen); - - /* KDrive does miDCInitialize right after miInitializeBackingStore */ - /* Setup the cursor routines */ - winDebug ("winFinishScreenInitFB - Calling miDCInitialize ()\n"); - miDCInitialize (pScreen, &g_winPointerCursorFuncs); - - /* KDrive does winCreateDefColormap right after miDCInitialize */ - /* Create a default colormap */ - winDebug ("winFinishScreenInitFB - Calling winCreateDefColormap ()\n"); - if (!winCreateDefColormap (pScreen)) - { - ErrorF ("winFinishScreenInitFB - Could not create colormap\n"); - return FALSE; - } - - /* Initialize the shadow framebuffer layer */ - if ((pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI - || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD - || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL) -#ifdef XWIN_MULTIWINDOWEXTWM - && !pScreenInfo->fMWExtWM -#endif - ) - { - winDebug ("winFinishScreenInitFB - Calling shadowSetup ()\n"); - if (!shadowSetup(pScreen)) - { - ErrorF ("winFinishScreenInitFB - shadowSetup () failed\n"); - return FALSE; - } - - /* Wrap CreateScreenResources so we can add the screen pixmap - to the Shadow framebuffer after it's been created */ - pScreenPriv->pwinCreateScreenResources = pScreen->CreateScreenResources; - pScreen->CreateScreenResources = winCreateScreenResources; - } - -#ifdef XWIN_MULTIWINDOWEXTWM - /* Handle multi-window external window manager mode */ - if (pScreenInfo->fMWExtWM) - { - winDebug ("winScreenInit - MultiWindowExtWM - Calling RootlessInit\n"); - - RootlessInit(pScreen, &winMWExtWMProcs); - - winDebug ("winScreenInit - MultiWindowExtWM - RootlessInit returned\n"); - - rootless_CopyBytes_threshold = 0; - rootless_FillBytes_threshold = 0; - rootless_CompositePixels_threshold = 0; - /* FIXME: How many? Profiling needed? */ - rootless_CopyWindow_threshold = 1; - - winWindowsWMExtensionInit (); - } -#endif - - /* Handle rootless mode */ - if (pScreenInfo->fRootless) - { - /* Define the WRAP macro temporarily for local use */ -#define WRAP(a) \ - if (pScreen->a) { \ - pScreenPriv->a = pScreen->a; \ - } else { \ - ErrorF("null screen fn " #a "\n"); \ - pScreenPriv->a = NULL; \ - } - - /* Save a pointer to each lower-level window procedure */ - WRAP(CreateWindow); - WRAP(DestroyWindow); - WRAP(RealizeWindow); - WRAP(UnrealizeWindow); - WRAP(PositionWindow); - WRAP(ChangeWindowAttributes); - WRAP(SetShape); - - /* Assign rootless window procedures to be top level procedures */ - pScreen->CreateWindow = winCreateWindowRootless; - pScreen->DestroyWindow = winDestroyWindowRootless; - pScreen->PositionWindow = winPositionWindowRootless; - /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesRootless;*/ - pScreen->RealizeWindow = winMapWindowRootless; - pScreen->UnrealizeWindow = winUnmapWindowRootless; - pScreen->SetShape = winSetShapeRootless; - - /* Undefine the WRAP macro, as it is not needed elsewhere */ -#undef WRAP - } - - -#ifdef XWIN_MULTIWINDOW - /* Handle multi window mode */ - else if (pScreenInfo->fMultiWindow) - { - /* Define the WRAP macro temporarily for local use */ -#define WRAP(a) \ - if (pScreen->a) { \ - pScreenPriv->a = pScreen->a; \ - } else { \ - ErrorF("null screen fn " #a "\n"); \ - pScreenPriv->a = NULL; \ - } - - /* Save a pointer to each lower-level window procedure */ - WRAP(CreateWindow); - WRAP(DestroyWindow); - WRAP(RealizeWindow); - WRAP(UnrealizeWindow); - WRAP(PositionWindow); - WRAP(ChangeWindowAttributes); - WRAP(ReparentWindow); - WRAP(RestackWindow); - WRAP(ResizeWindow); - WRAP(MoveWindow); - WRAP(CopyWindow); - WRAP(SetShape); - - /* Assign multi-window window procedures to be top level procedures */ - pScreen->CreateWindow = winCreateWindowMultiWindow; - pScreen->DestroyWindow = winDestroyWindowMultiWindow; - pScreen->PositionWindow = winPositionWindowMultiWindow; - /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesMultiWindow;*/ - pScreen->RealizeWindow = winMapWindowMultiWindow; - pScreen->UnrealizeWindow = winUnmapWindowMultiWindow; - pScreen->ReparentWindow = winReparentWindowMultiWindow; - pScreen->RestackWindow = winRestackWindowMultiWindow; - pScreen->ResizeWindow = winResizeWindowMultiWindow; - pScreen->MoveWindow = winMoveWindowMultiWindow; - pScreen->CopyWindow = winCopyWindowMultiWindow; - pScreen->SetShape = winSetShapeMultiWindow; - - /* Undefine the WRAP macro, as it is not needed elsewhere */ -#undef WRAP - } -#endif - - /* Wrap either fb's or shadow's CloseScreen with our CloseScreen */ - pScreenPriv->CloseScreen = pScreen->CloseScreen; - pScreen->CloseScreen = pScreenPriv->pwinCloseScreen; - -#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) - /* Create a mutex for modules in separate threads to wait for */ - iReturn = pthread_mutex_init (&pScreenPriv->pmServerStarted, NULL); - if (iReturn != 0) - { - ErrorF ("winFinishScreenInitFB - pthread_mutex_init () failed: %d\n", - iReturn); - return FALSE; - } - - /* Own the mutex for modules in separate threads */ - iReturn = pthread_mutex_lock (&pScreenPriv->pmServerStarted); - if (iReturn != 0) - { - ErrorF ("winFinishScreenInitFB - pthread_mutex_lock () failed: %d\n", - iReturn); - return FALSE; - } - - /* Set the ServerStarted flag to false */ - pScreenPriv->fServerStarted = FALSE; -#endif - -#ifdef XWIN_MULTIWINDOWEXTWM - pScreenPriv->fRestacking = FALSE; -#endif - -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - if (FALSE -#ifdef XWIN_MULTIWINDOW - || pScreenInfo->fMultiWindow -#endif -#ifdef XWIN_MULTIWINDOWEXTWM - || pScreenInfo->fInternalWM -#endif - ) - { - winDebug ("winFinishScreenInitFB - Calling winInitWM.\n"); - - /* Initialize multi window mode */ - if (!winInitWM (&pScreenPriv->pWMInfo, - &pScreenPriv->ptWMProc, - &pScreenPriv->ptXMsgProc, - &pScreenPriv->pmServerStarted, - pScreenInfo->dwScreen, - (HWND)&pScreenPriv->hwndScreen, -#ifdef XWIN_MULTIWINDOWEXTWM - pScreenInfo->fInternalWM || -#endif - FALSE)) - { - ErrorF ("winFinishScreenInitFB - winInitWM () failed.\n"); - return FALSE; - } - } -#endif - - /* Tell the server that we are enabled */ - pScreenPriv->fEnabled = TRUE; - - /* Tell the server that we have a valid depth */ - pScreenPriv->fBadDepth = FALSE; - - winDebug ("winFinishScreenInitFB - returning\n"); - - return TRUE; -} - -#ifdef XWIN_NATIVEGDI -/* See Porting Layer Definition - p. 20 */ - -Bool -winFinishScreenInitNativeGDI (int index, - ScreenPtr pScreen, - int argc, char **argv) -{ - winScreenPriv(pScreen); - winScreenInfoPtr pScreenInfo = &g_ScreenInfo[index]; - VisualPtr pVisuals = NULL; - DepthPtr pDepths = NULL; - VisualID rootVisual = 0; - int nVisuals = 0, nDepths = 0, nRootDepth = 0; - - /* Ignore user input (mouse, keyboard) */ - pScreenInfo->fIgnoreInput = FALSE; - - /* Get device contexts for the screen and shadow bitmap */ - pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen); - if (pScreenPriv->hdcScreen == NULL) - FatalError ("winFinishScreenInitNativeGDI - Couldn't get a DC\n"); - - /* Init visuals */ - if (!(*pScreenPriv->pwinInitVisuals) (pScreen)) - { - ErrorF ("winFinishScreenInitNativeGDI - pwinInitVisuals failed\n"); - return FALSE; - } - - /* Initialize the mi visuals */ - if (!miInitVisuals (&pVisuals, &pDepths, &nVisuals, &nDepths, &nRootDepth, - &rootVisual, - ((unsigned long)1 << (pScreenInfo->dwDepth - 1)), 8, - TrueColor)) - { - ErrorF ("winFinishScreenInitNativeGDI - miInitVisuals () failed\n"); - return FALSE; - } - - /* Initialize the CloseScreen procedure pointer */ - pScreen->CloseScreen = NULL; - - /* Initialize the mi code */ - if (!miScreenInit (pScreen, - NULL, /* No framebuffer */ - pScreenInfo->dwWidth, pScreenInfo->dwHeight, - monitorResolution, monitorResolution, - pScreenInfo->dwStride, - nRootDepth, nDepths, pDepths, rootVisual, - nVisuals, pVisuals)) - { - ErrorF ("winFinishScreenInitNativeGDI - miScreenInit failed\n"); - return FALSE; - } - - pScreen->defColormap = FakeClientID(0); - - /* - * Register our block and wakeup handlers; these procedures - * process messages in our Windows message queue; specifically, - * they process mouse and keyboard input. - */ - pScreen->BlockHandler = winBlockHandler; - pScreen->WakeupHandler = winWakeupHandler; - pScreen->blockData = pScreen; - pScreen->wakeupData = pScreen; - - /* Place our save screen function */ - pScreen->SaveScreen = winSaveScreen; - - /* Pixmaps */ - pScreen->CreatePixmap = winCreatePixmapNativeGDI; - pScreen->DestroyPixmap = winDestroyPixmapNativeGDI; - - /* Other Screen Routines */ - pScreen->QueryBestSize = winQueryBestSizeNativeGDI; - pScreen->SaveScreen = winSaveScreen; - pScreen->GetImage = miGetImage; - pScreen->GetSpans = winGetSpansNativeGDI; - - /* Window Procedures */ - pScreen->CreateWindow = winCreateWindowNativeGDI; - pScreen->DestroyWindow = winDestroyWindowNativeGDI; - pScreen->PositionWindow = winPositionWindowNativeGDI; - /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesNativeGDI;*/ - pScreen->RealizeWindow = winMapWindowNativeGDI; - pScreen->UnrealizeWindow = winUnmapWindowNativeGDI; - - /* Paint window */ - pScreen->CopyWindow = winCopyWindowNativeGDI; - - /* Fonts */ - pScreen->RealizeFont = winRealizeFontNativeGDI; - pScreen->UnrealizeFont = winUnrealizeFontNativeGDI; - - /* GC */ - pScreen->CreateGC = winCreateGCNativeGDI; - - /* Colormap Routines */ - pScreen->CreateColormap = miInitializeColormap; - pScreen->DestroyColormap = (DestroyColormapProcPtr) (void (*)(void)) NoopDDA; - pScreen->InstallColormap = miInstallColormap; - pScreen->UninstallColormap = miUninstallColormap; - pScreen->ListInstalledColormaps = miListInstalledColormaps; - pScreen->StoreColors = (StoreColorsProcPtr) (void (*)(void)) NoopDDA; - pScreen->ResolveColor = miResolveColor; - - /* Bitmap */ - pScreen->BitmapToRegion = winPixmapToRegionNativeGDI; - - winDebug ("winFinishScreenInitNativeGDI - calling miDCInitialize\n"); - - /* Set the default white and black pixel positions */ - pScreen->whitePixel = pScreen->blackPixel = (Pixel) 0; - - /* Initialize the cursor */ - if (!miDCInitialize (pScreen, &g_winPointerCursorFuncs)) - { - ErrorF ("winFinishScreenInitNativeGDI - miDCInitialize failed\n"); - return FALSE; - } - - /* Create a default colormap */ - if (!miCreateDefColormap (pScreen)) - { - ErrorF ("winFinishScreenInitNativeGDI - miCreateDefColormap () " - "failed\n"); - return FALSE; - } - - winDebug ("winFinishScreenInitNativeGDI - miCreateDefColormap () " - "returned\n"); - - /* mi doesn't use a CloseScreen procedure, so no need to wrap */ - pScreen->CloseScreen = pScreenPriv->pwinCloseScreen; - - /* Tell the server that we are enabled */ - pScreenPriv->fEnabled = TRUE; - - winDebug ("winFinishScreenInitNativeGDI - Successful addition of " - "screen %08x\n", - (unsigned int) pScreen); - - return TRUE; -} -#endif - - -/* See Porting Layer Definition - p. 33 */ -static Bool -winSaveScreen (ScreenPtr pScreen, int on) -{ - return TRUE; -} +/*
+ *Copyright (C) 1994-2000 The XFree86 Project, 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, sublicense, and/or sell copies of the Software, and to
+ *permit persons to whom the Software is furnished to do so, subject to
+ *the following conditions:
+ *
+ *The above copyright notice and this permission notice shall be
+ *included in all copies or substantial portions of the Software.
+ *
+ *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. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
+ *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *Except as contained in this notice, the name of the XFree86 Project
+ *shall not be used in advertising or otherwise to promote the sale, use
+ *or other dealings in this Software without prior written authorization
+ *from the XFree86 Project.
+ *
+ * Authors: Dakshinamurthy Karra
+ * Suhaib M Siddiqi
+ * Peter Busch
+ * Harold L Hunt II
+ * Kensuke Matsuzaki
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+#include "winmsg.h"
+
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+static RootlessFrameProcsRec
+winMWExtWMProcs = {
+ winMWExtWMCreateFrame,
+ winMWExtWMDestroyFrame,
+
+ winMWExtWMMoveFrame,
+ winMWExtWMResizeFrame,
+ winMWExtWMRestackFrame,
+ winMWExtWMReshapeFrame,
+ winMWExtWMUnmapFrame,
+
+ winMWExtWMStartDrawing,
+ winMWExtWMStopDrawing,
+ winMWExtWMUpdateRegion,
+#ifndef ROOTLESS_TRACK_DAMAGE
+ winMWExtWMDamageRects,
+#endif
+ winMWExtWMRootlessSwitchWindow,
+ NULL,//winMWExtWMDoReorderWindow,
+ NULL,//winMWExtWMHideWindow,
+ NULL,//winMWExtWMUpdateColorMap,
+
+ NULL,//winMWExtWMCopyBytes,
+ NULL,//winMWExtWMFillBytes,
+ NULL,//winMWExtWMCompositePixels,
+ winMWExtWMCopyWindow
+};
+#endif
+
+
+/*
+ * References to external symbols
+ */
+
+extern Bool g_fSoftwareCursor;
+
+
+/*
+ * Prototypes
+ */
+
+Bool
+winRandRInit (ScreenPtr pScreen);
+
+
+/*
+ * Local functions
+ */
+
+static Bool
+winSaveScreen (ScreenPtr pScreen, int on);
+
+
+/*
+ * Determine what type of screen we are initializing
+ * and call the appropriate procedure to intiailize
+ * that type of screen.
+ */
+
+Bool
+winScreenInit (int index,
+ ScreenPtr pScreen,
+ int argc, char **argv)
+{
+ winScreenInfoPtr pScreenInfo = &g_ScreenInfo[index];
+ winPrivScreenPtr pScreenPriv;
+ HDC hdc;
+
+ winDebug ("winScreenInit - dwWidth: %ld dwHeight: %ld\n",
+ pScreenInfo->dwWidth, pScreenInfo->dwHeight);
+
+ /* Allocate privates for this screen */
+ if (!winAllocatePrivates (pScreen))
+ {
+ ErrorF ("winScreenInit - Couldn't allocate screen privates\n");
+ return FALSE;
+ }
+
+ /* Get a pointer to the privates structure that was allocated */
+ pScreenPriv = winGetScreenPriv (pScreen);
+
+ /* Save a pointer to this screen in the screen info structure */
+ pScreenInfo->pScreen = pScreen;
+
+ /* Save a pointer to the screen info in the screen privates structure */
+ /* This allows us to get back to the screen info from a screen pointer */
+ pScreenPriv->pScreenInfo = pScreenInfo;
+
+ /*
+ * Determine which engine to use.
+ *
+ * NOTE: This is done once per screen because each screen possibly has
+ * a preferred engine specified on the command line.
+ */
+ if (!winSetEngine (pScreen))
+ {
+ ErrorF ("winScreenInit - winSetEngine () failed\n");
+ return FALSE;
+ }
+
+ /* Adjust the video mode for our engine type */
+ if (pScreenPriv->pwinAdjustVideoMode && !(*pScreenPriv->pwinAdjustVideoMode) (pScreen))
+ {
+ ErrorF ("winScreenInit - winAdjustVideoMode () failed\n");
+ return FALSE;
+ }
+
+ /* Check for supported display depth */
+ if (!(WIN_SUPPORTED_BPPS & (1 << (pScreenInfo->dwBPP - 1))))
+ {
+ ErrorF ("winScreenInit - Unsupported display depth: %d\n" \
+ "Change your Windows display depth to 15, 16, 24, or 32 bits "
+ "per pixel.\n",
+ (int) pScreenInfo->dwBPP);
+ ErrorF ("winScreenInit - Supported depths: %08x\n",
+ WIN_SUPPORTED_BPPS);
+#if WIN_CHECK_DEPTH
+ return FALSE;
+#endif
+ }
+
+ /*
+ * Check that all monitors have the same display depth if we are using
+ * multiple monitors
+ */
+ if (pScreenInfo->fMultipleMonitors
+ && !GetSystemMetrics (SM_SAMEDISPLAYFORMAT))
+ {
+ ErrorF ("winScreenInit - Monitors do not all have same pixel format / "
+ "display depth.\n"
+ "Using primary display only.\n");
+ pScreenInfo->fMultipleMonitors = FALSE;
+ }
+
+ /* Create display window */
+ if (pScreenPriv->pwinCreateBoundingWindow && !(*pScreenPriv->pwinCreateBoundingWindow) (pScreen))
+ {
+ ErrorF ("winScreenInit - pwinCreateBoundingWindow () "
+ "failed\n");
+ return FALSE;
+ }
+
+ /* Get a device context */
+ hdc = GetDC (pScreenPriv->hwndScreen);
+
+ /* Store the initial height, width, and depth of the display */
+ /* Are we using multiple monitors? */
+ if (pScreenInfo->fMultipleMonitors)
+ {
+ pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN);
+ pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
+
+ /*
+ * In this case, some of the defaults set in
+ * winInitializeScreenDefaults() are not correct ...
+ */
+ if (!pScreenInfo->fUserGaveHeightAndWidth)
+ {
+ pScreenInfo->dwWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN);
+ pScreenInfo->dwHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
+ pScreenInfo->dwWidth_mm = (pScreenInfo->dwWidth /
+ WIN_DEFAULT_DPI) * 25.4;
+ pScreenInfo->dwHeight_mm = (pScreenInfo->dwHeight /
+ WIN_DEFAULT_DPI) * 25.4;
+ }
+ }
+ else
+ {
+ pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXSCREEN);
+ pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYSCREEN);
+ }
+
+ /* Save the original bits per pixel */
+ pScreenPriv->dwLastWindowsBitsPixel = GetDeviceCaps (hdc, BITSPIXEL);
+
+ /* Release the device context */
+ ReleaseDC (pScreenPriv->hwndScreen, hdc);
+
+ /* Clear the visuals list */
+ miClearVisualTypes ();
+
+ /* Set the padded screen width */
+ pScreenInfo->dwPaddedWidth = PixmapBytePad (pScreenInfo->dwWidth,
+ pScreenInfo->dwBPP);
+
+ /* Call the engine dependent screen initialization procedure */
+ if (pScreenPriv->pwinFinishScreenInit && !((*pScreenPriv->pwinFinishScreenInit) (index, pScreen, argc, argv)))
+ {
+ ErrorF ("winScreenInit - winFinishScreenInit () failed\n");
+ return FALSE;
+ }
+
+ if (!g_fSoftwareCursor)
+ winInitCursor(pScreen);
+#ifdef WINDBG
+ else
+ winDebug("winScreenInit - Using software cursor\n");
+#endif
+
+ /*
+ Note the screen origin in a normalized coordinate space where (0,0) is at the top left
+ of the native virtual desktop area
+ */
+ pScreen->x = pScreenInfo->dwInitialX - GetSystemMetrics(SM_XVIRTUALSCREEN);
+ pScreen->y = pScreenInfo->dwInitialY - GetSystemMetrics(SM_YVIRTUALSCREEN);
+
+ winDebug("Screen %d added at virtual desktop coordinate (%d,%d).\n",
+ index, pScreen->x, pScreen->y);
+ winDebug ("winScreenInit - returning\n");
+
+ return TRUE;
+}
+
+static Bool
+winCreateScreenResources(ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ Bool result;
+
+ result = pScreenPriv->pwinCreateScreenResources(pScreen);
+
+ /* Now the screen bitmap has been wrapped in a pixmap,
+ add that to the Shadow framebuffer */
+ if (!shadowAdd(pScreen, pScreen->devPrivate,
+ pScreenPriv->pwinShadowUpdate, NULL, 0, 0))
+ {
+ ErrorF ("winCreateScreenResources - shadowAdd () failed\n");
+ return FALSE;
+ }
+
+ return result;
+}
+
+/* See Porting Layer Definition - p. 20 */
+Bool
+winFinishScreenInitFB (int index,
+ ScreenPtr pScreen,
+ int argc, char **argv)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+ VisualPtr pVisual = NULL;
+ char *pbits = NULL;
+#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
+ int iReturn;
+#endif
+
+ /* Create framebuffer */
+ if (!(*pScreenPriv->pwinAllocateFB) (pScreen))
+ {
+ ErrorF ("winFinishScreenInitFB - Could not allocate framebuffer\n");
+ return FALSE;
+ }
+
+ /*
+ * Grab the number of bits that are used to represent color in each pixel.
+ */
+ if (pScreenInfo->dwBPP == 8)
+ pScreenInfo->dwDepth = 8;
+ else
+ pScreenInfo->dwDepth = winCountBits (pScreenPriv->dwRedMask)
+ + winCountBits (pScreenPriv->dwGreenMask)
+ + winCountBits (pScreenPriv->dwBlueMask);
+
+ winDebug ("winFinishScreenInitFB - Masks: %08x %08x %08x\n",
+ (unsigned int) pScreenPriv->dwRedMask,
+ (unsigned int) pScreenPriv->dwGreenMask,
+ (unsigned int) pScreenPriv->dwBlueMask);
+
+ /* Init visuals */
+ if (!(*pScreenPriv->pwinInitVisuals) (pScreen))
+ {
+ ErrorF ("winFinishScreenInitFB - winInitVisuals failed\n");
+ return FALSE;
+ }
+
+ /* Setup a local variable to point to the framebuffer */
+ pbits = pScreenInfo->pfb;
+
+ /* Apparently we need this for the render extension */
+ miSetPixmapDepths ();
+
+ /* Start fb initialization */
+ if (!fbSetupScreen (pScreen,
+ pScreenInfo->pfb,
+ pScreenInfo->dwWidth, pScreenInfo->dwHeight,
+ monitorResolution, monitorResolution,
+ pScreenInfo->dwStride,
+ pScreenInfo->dwBPP))
+ {
+ ErrorF ("winFinishScreenInitFB - fbSetupScreen failed\n");
+ return FALSE;
+ }
+
+ /* Override default colormap routines if visual class is dynamic */
+ if (pScreenInfo->dwDepth == 8
+ && (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI
+ || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL
+ && pScreenInfo->fFullScreen)
+ || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
+ && pScreenInfo->fFullScreen)))
+ {
+ winSetColormapFunctions (pScreen);
+
+ /*
+ * NOTE: Setting whitePixel to 255 causes Magic 7.1 to allocate its
+ * own colormap, as it cannot allocate 7 planes in the default
+ * colormap. Setting whitePixel to 1 allows Magic to get 7
+ * planes in the default colormap, so it doesn't create its
+ * own colormap. This latter situation is highly desireable,
+ * as it keeps the Magic window viewable when switching to
+ * other X clients that use the default colormap.
+ */
+ pScreen->blackPixel = 0;
+ pScreen->whitePixel = 1;
+ }
+
+ /* Place our save screen function */
+ pScreen->SaveScreen = winSaveScreen;
+
+ /* Finish fb initialization */
+ if (!fbFinishScreenInit (pScreen,
+ pScreenInfo->pfb,
+ pScreenInfo->dwWidth, pScreenInfo->dwHeight,
+ monitorResolution, monitorResolution,
+ pScreenInfo->dwStride,
+ pScreenInfo->dwBPP))
+ {
+ ErrorF ("winFinishScreenInitFB - fbFinishScreenInit failed\n");
+ return FALSE;
+ }
+
+ /* Save a pointer to the root visual */
+ for (pVisual = pScreen->visuals;
+ pVisual->vid != pScreen->rootVisual;
+ pVisual++);
+ pScreenPriv->pRootVisual = pVisual;
+
+ /*
+ * Setup points to the block and wakeup handlers. Pass a pointer
+ * to the current screen as pWakeupdata.
+ */
+ pScreen->BlockHandler = winBlockHandler;
+ pScreen->WakeupHandler = winWakeupHandler;
+ pScreen->blockData = pScreen;
+ pScreen->wakeupData = pScreen;
+
+ /* Render extension initialization, calls miPictureInit */
+ if (!fbPictureInit (pScreen, NULL, 0))
+ {
+ ErrorF ("winFinishScreenInitFB - fbPictureInit () failed\n");
+ return FALSE;
+ }
+
+#ifdef RANDR
+ /* Initialize resize and rotate support */
+ if (!winRandRInit (pScreen))
+ {
+ ErrorF ("winFinishScreenInitFB - winRandRInit () failed\n");
+ return FALSE;
+ }
+#endif
+
+ /*
+ * Backing store support should reduce network traffic and increase
+ * performance.
+ */
+ miInitializeBackingStore (pScreen);
+
+ /* KDrive does miDCInitialize right after miInitializeBackingStore */
+ /* Setup the cursor routines */
+ winDebug ("winFinishScreenInitFB - Calling miDCInitialize ()\n");
+ miDCInitialize (pScreen, &g_winPointerCursorFuncs);
+
+ /* KDrive does winCreateDefColormap right after miDCInitialize */
+ /* Create a default colormap */
+ winDebug ("winFinishScreenInitFB - Calling winCreateDefColormap ()\n");
+ if (!winCreateDefColormap (pScreen))
+ {
+ ErrorF ("winFinishScreenInitFB - Could not create colormap\n");
+ return FALSE;
+ }
+
+ /* Initialize the shadow framebuffer layer */
+ if ((pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI
+ || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
+ || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL)
+#ifdef XWIN_MULTIWINDOWEXTWM
+ && !pScreenInfo->fMWExtWM
+#endif
+ )
+ {
+ winDebug ("winFinishScreenInitFB - Calling shadowSetup ()\n");
+ if (!shadowSetup(pScreen))
+ {
+ ErrorF ("winFinishScreenInitFB - shadowSetup () failed\n");
+ return FALSE;
+ }
+
+ /* Wrap CreateScreenResources so we can add the screen pixmap
+ to the Shadow framebuffer after it's been created */
+ pScreenPriv->pwinCreateScreenResources = pScreen->CreateScreenResources;
+ pScreen->CreateScreenResources = winCreateScreenResources;
+ }
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+ /* Handle multi-window external window manager mode */
+ if (pScreenInfo->fMWExtWM)
+ {
+ winDebug ("winScreenInit - MultiWindowExtWM - Calling RootlessInit\n");
+
+ RootlessInit(pScreen, &winMWExtWMProcs);
+
+ winDebug ("winScreenInit - MultiWindowExtWM - RootlessInit returned\n");
+
+ rootless_CopyBytes_threshold = 0;
+ rootless_FillBytes_threshold = 0;
+ rootless_CompositePixels_threshold = 0;
+ /* FIXME: How many? Profiling needed? */
+ rootless_CopyWindow_threshold = 1;
+
+ winWindowsWMExtensionInit ();
+ }
+#endif
+
+ /* Handle rootless mode */
+ if (pScreenInfo->fRootless)
+ {
+ /* Define the WRAP macro temporarily for local use */
+#define WRAP(a) \
+ if (pScreen->a) { \
+ pScreenPriv->a = pScreen->a; \
+ } else { \
+ ErrorF("null screen fn " #a "\n"); \
+ pScreenPriv->a = NULL; \
+ }
+
+ /* Save a pointer to each lower-level window procedure */
+ WRAP(CreateWindow);
+ WRAP(DestroyWindow);
+ WRAP(RealizeWindow);
+ WRAP(UnrealizeWindow);
+ WRAP(PositionWindow);
+ WRAP(ChangeWindowAttributes);
+ WRAP(SetShape);
+
+ /* Assign rootless window procedures to be top level procedures */
+ pScreen->CreateWindow = winCreateWindowRootless;
+ pScreen->DestroyWindow = winDestroyWindowRootless;
+ pScreen->PositionWindow = winPositionWindowRootless;
+ /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesRootless;*/
+ pScreen->RealizeWindow = winMapWindowRootless;
+ pScreen->UnrealizeWindow = winUnmapWindowRootless;
+ pScreen->SetShape = winSetShapeRootless;
+
+ /* Undefine the WRAP macro, as it is not needed elsewhere */
+#undef WRAP
+ }
+
+
+#ifdef XWIN_MULTIWINDOW
+ /* Handle multi window mode */
+ else if (pScreenInfo->fMultiWindow)
+ {
+ /* Define the WRAP macro temporarily for local use */
+#define WRAP(a) \
+ if (pScreen->a) { \
+ pScreenPriv->a = pScreen->a; \
+ } else { \
+ ErrorF("null screen fn " #a "\n"); \
+ pScreenPriv->a = NULL; \
+ }
+
+ /* Save a pointer to each lower-level window procedure */
+ WRAP(CreateWindow);
+ WRAP(DestroyWindow);
+ WRAP(RealizeWindow);
+ WRAP(UnrealizeWindow);
+ WRAP(PositionWindow);
+ WRAP(ChangeWindowAttributes);
+ WRAP(ReparentWindow);
+ WRAP(RestackWindow);
+ WRAP(ResizeWindow);
+ WRAP(MoveWindow);
+ WRAP(CopyWindow);
+ WRAP(SetShape);
+
+ /* Assign multi-window window procedures to be top level procedures */
+ pScreen->CreateWindow = winCreateWindowMultiWindow;
+ pScreen->DestroyWindow = winDestroyWindowMultiWindow;
+ pScreen->PositionWindow = winPositionWindowMultiWindow;
+ /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesMultiWindow;*/
+ pScreen->RealizeWindow = winMapWindowMultiWindow;
+ pScreen->UnrealizeWindow = winUnmapWindowMultiWindow;
+ pScreen->ReparentWindow = winReparentWindowMultiWindow;
+ pScreen->RestackWindow = winRestackWindowMultiWindow;
+ pScreen->ResizeWindow = winResizeWindowMultiWindow;
+ pScreen->MoveWindow = winMoveWindowMultiWindow;
+ pScreen->CopyWindow = winCopyWindowMultiWindow;
+ pScreen->SetShape = winSetShapeMultiWindow;
+
+ /* Undefine the WRAP macro, as it is not needed elsewhere */
+#undef WRAP
+ }
+#endif
+
+ /* Wrap either fb's or shadow's CloseScreen with our CloseScreen */
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = pScreenPriv->pwinCloseScreen;
+
+#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
+ /* Create a mutex for modules in separate threads to wait for */
+ iReturn = pthread_mutex_init (&pScreenPriv->pmServerStarted, NULL);
+ if (iReturn != 0)
+ {
+ ErrorF ("winFinishScreenInitFB - pthread_mutex_init () failed: %d\n",
+ iReturn);
+ return FALSE;
+ }
+
+ /* Own the mutex for modules in separate threads */
+ iReturn = pthread_mutex_lock (&pScreenPriv->pmServerStarted);
+ if (iReturn != 0)
+ {
+ ErrorF ("winFinishScreenInitFB - pthread_mutex_lock () failed: %d\n",
+ iReturn);
+ return FALSE;
+ }
+
+ /* Set the ServerStarted flag to false */
+ pScreenPriv->fServerStarted = FALSE;
+#endif
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+ pScreenPriv->fRestacking = FALSE;
+#endif
+
+#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
+ if (FALSE
+#ifdef XWIN_MULTIWINDOW
+ || pScreenInfo->fMultiWindow
+#endif
+#ifdef XWIN_MULTIWINDOWEXTWM
+ || pScreenInfo->fInternalWM
+#endif
+ )
+ {
+ winDebug ("winFinishScreenInitFB - Calling winInitWM.\n");
+
+ /* Initialize multi window mode */
+ if (!winInitWM (&pScreenPriv->pWMInfo,
+ &pScreenPriv->ptWMProc,
+ &pScreenPriv->ptXMsgProc,
+ &pScreenPriv->pmServerStarted,
+ pScreenInfo->dwScreen,
+ (HWND)&pScreenPriv->hwndScreen,
+#ifdef XWIN_MULTIWINDOWEXTWM
+ pScreenInfo->fInternalWM ||
+#endif
+ FALSE))
+ {
+ ErrorF ("winFinishScreenInitFB - winInitWM () failed.\n");
+ return FALSE;
+ }
+ }
+#endif
+
+ /* Tell the server that we are enabled */
+ pScreenPriv->fEnabled = TRUE;
+
+ /* Tell the server that we have a valid depth */
+ pScreenPriv->fBadDepth = FALSE;
+
+ winDebug ("winFinishScreenInitFB - returning\n");
+
+ return TRUE;
+}
+
+#ifdef XWIN_NATIVEGDI
+/* See Porting Layer Definition - p. 20 */
+
+Bool
+winFinishScreenInitNativeGDI (int index,
+ ScreenPtr pScreen,
+ int argc, char **argv)
+{
+ winScreenPriv(pScreen);
+ winScreenInfoPtr pScreenInfo = &g_ScreenInfo[index];
+ VisualPtr pVisuals = NULL;
+ DepthPtr pDepths = NULL;
+ VisualID rootVisual = 0;
+ int nVisuals = 0, nDepths = 0, nRootDepth = 0;
+
+ /* Ignore user input (mouse, keyboard) */
+ pScreenInfo->fIgnoreInput = FALSE;
+
+ /* Get device contexts for the screen and shadow bitmap */
+ pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
+ if (pScreenPriv->hdcScreen == NULL)
+ FatalError ("winFinishScreenInitNativeGDI - Couldn't get a DC\n");
+
+ /* Init visuals */
+ if (!(*pScreenPriv->pwinInitVisuals) (pScreen))
+ {
+ ErrorF ("winFinishScreenInitNativeGDI - pwinInitVisuals failed\n");
+ return FALSE;
+ }
+
+ /* Initialize the mi visuals */
+ if (!miInitVisuals (&pVisuals, &pDepths, &nVisuals, &nDepths, &nRootDepth,
+ &rootVisual,
+ ((unsigned long)1 << (pScreenInfo->dwDepth - 1)), 8,
+ TrueColor))
+ {
+ ErrorF ("winFinishScreenInitNativeGDI - miInitVisuals () failed\n");
+ return FALSE;
+ }
+
+ /* Initialize the CloseScreen procedure pointer */
+ pScreen->CloseScreen = NULL;
+
+ /* Initialize the mi code */
+ if (!miScreenInit (pScreen,
+ NULL, /* No framebuffer */
+ pScreenInfo->dwWidth, pScreenInfo->dwHeight,
+ monitorResolution, monitorResolution,
+ pScreenInfo->dwStride,
+ nRootDepth, nDepths, pDepths, rootVisual,
+ nVisuals, pVisuals))
+ {
+ ErrorF ("winFinishScreenInitNativeGDI - miScreenInit failed\n");
+ return FALSE;
+ }
+
+ pScreen->defColormap = FakeClientID(0);
+
+ /*
+ * Register our block and wakeup handlers; these procedures
+ * process messages in our Windows message queue; specifically,
+ * they process mouse and keyboard input.
+ */
+ pScreen->BlockHandler = winBlockHandler;
+ pScreen->WakeupHandler = winWakeupHandler;
+ pScreen->blockData = pScreen;
+ pScreen->wakeupData = pScreen;
+
+ /* Place our save screen function */
+ pScreen->SaveScreen = winSaveScreen;
+
+ /* Pixmaps */
+ pScreen->CreatePixmap = winCreatePixmapNativeGDI;
+ pScreen->DestroyPixmap = winDestroyPixmapNativeGDI;
+
+ /* Other Screen Routines */
+ pScreen->QueryBestSize = winQueryBestSizeNativeGDI;
+ pScreen->SaveScreen = winSaveScreen;
+ pScreen->GetImage = miGetImage;
+ pScreen->GetSpans = winGetSpansNativeGDI;
+
+ /* Window Procedures */
+ pScreen->CreateWindow = winCreateWindowNativeGDI;
+ pScreen->DestroyWindow = winDestroyWindowNativeGDI;
+ pScreen->PositionWindow = winPositionWindowNativeGDI;
+ /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesNativeGDI;*/
+ pScreen->RealizeWindow = winMapWindowNativeGDI;
+ pScreen->UnrealizeWindow = winUnmapWindowNativeGDI;
+
+ /* Paint window */
+ pScreen->CopyWindow = winCopyWindowNativeGDI;
+
+ /* Fonts */
+ pScreen->RealizeFont = winRealizeFontNativeGDI;
+ pScreen->UnrealizeFont = winUnrealizeFontNativeGDI;
+
+ /* GC */
+ pScreen->CreateGC = winCreateGCNativeGDI;
+
+ /* Colormap Routines */
+ pScreen->CreateColormap = miInitializeColormap;
+ pScreen->DestroyColormap = (DestroyColormapProcPtr) (void (*)(void)) NoopDDA;
+ pScreen->InstallColormap = miInstallColormap;
+ pScreen->UninstallColormap = miUninstallColormap;
+ pScreen->ListInstalledColormaps = miListInstalledColormaps;
+ pScreen->StoreColors = (StoreColorsProcPtr) (void (*)(void)) NoopDDA;
+ pScreen->ResolveColor = miResolveColor;
+
+ /* Bitmap */
+ pScreen->BitmapToRegion = winPixmapToRegionNativeGDI;
+
+ winDebug ("winFinishScreenInitNativeGDI - calling miDCInitialize\n");
+
+ /* Set the default white and black pixel positions */
+ pScreen->whitePixel = pScreen->blackPixel = (Pixel) 0;
+
+ /* Initialize the cursor */
+ if (!miDCInitialize (pScreen, &g_winPointerCursorFuncs))
+ {
+ ErrorF ("winFinishScreenInitNativeGDI - miDCInitialize failed\n");
+ return FALSE;
+ }
+
+ /* Create a default colormap */
+ if (!miCreateDefColormap (pScreen))
+ {
+ ErrorF ("winFinishScreenInitNativeGDI - miCreateDefColormap () "
+ "failed\n");
+ return FALSE;
+ }
+
+ winDebug ("winFinishScreenInitNativeGDI - miCreateDefColormap () "
+ "returned\n");
+
+ /* mi doesn't use a CloseScreen procedure, so no need to wrap */
+ pScreen->CloseScreen = pScreenPriv->pwinCloseScreen;
+
+ /* Tell the server that we are enabled */
+ pScreenPriv->fEnabled = TRUE;
+
+ winDebug ("winFinishScreenInitNativeGDI - Successful addition of "
+ "screen %08x\n",
+ (unsigned int) pScreen);
+
+ return TRUE;
+}
+#endif
+
+
+/* See Porting Layer Definition - p. 33 */
+static Bool
+winSaveScreen (ScreenPtr pScreen, int on)
+{
+ return TRUE;
+}
diff --git a/xorg-server/hw/xwin/winsetsp.c b/xorg-server/hw/xwin/winsetsp.c index 674e147d4..d1803489a 100644 --- a/xorg-server/hw/xwin/winsetsp.c +++ b/xorg-server/hw/xwin/winsetsp.c @@ -1,191 +1,191 @@ -/* - *Copyright (C) 1994-2000 The XFree86 Project, 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, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *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. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of the XFree86 Project - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from the XFree86 Project. - * - * Authors: Harold L Hunt II - * Alan Hourihane <alanh@fairlite.demon.co.uk> - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" - -typedef struct mybitmap -{ +/*
+ *Copyright (C) 1994-2000 The XFree86 Project, 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, sublicense, and/or sell copies of the Software, and to
+ *permit persons to whom the Software is furnished to do so, subject to
+ *the following conditions:
+ *
+ *The above copyright notice and this permission notice shall be
+ *included in all copies or substantial portions of the Software.
+ *
+ *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. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
+ *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *Except as contained in this notice, the name of the XFree86 Project
+ *shall not be used in advertising or otherwise to promote the sale, use
+ *or other dealings in this Software without prior written authorization
+ *from the XFree86 Project.
+ *
+ * Authors: Harold L Hunt II
+ * Alan Hourihane <alanh@fairlite.demon.co.uk>
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+
+typedef struct mybitmap
+{
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[256]; /* Maximum palette used in case of 8-bit per pixel */
-} mybitmap_t; - -/* See Porting Layer Definition - p. 55 */ -void -winSetSpansNativeGDI (DrawablePtr pDrawable, - GCPtr pGC, - char *pSrcs, - DDXPointPtr pPoints, - int *piWidths, - int iSpans, - int fSorted) -{ - winGCPriv(pGC); - PixmapPtr pPixmap = NULL; - winPrivPixmapPtr pPixmapPriv = NULL; - HBITMAP hbmpOrig = NULL; - mybitmap_t bmi; - HRGN hrgn = NULL, combined = NULL; - int nbox; - BoxPtr pbox; - - nbox = REGION_NUM_RECTS (pGC->pCompositeClip); - pbox = REGION_RECTS (pGC->pCompositeClip); - - if (!nbox) return; - - combined = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2, pbox->y2); - nbox--; pbox++; - while (nbox--) - { - hrgn = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2, pbox->y2); - CombineRgn (combined, combined, hrgn, RGN_OR); - DeleteObject (hrgn); - hrgn = NULL; - pbox++; - } - - /* Branch on the drawable type */ - switch (pDrawable->type) - { - case DRAWABLE_PIXMAP: - - SelectClipRgn (pGCPriv->hdcMem, combined); - DeleteObject (combined); - combined = NULL; - - pPixmap = (PixmapPtr) pDrawable; - pPixmapPriv = winGetPixmapPriv (pPixmap); - - /* Select the drawable pixmap into a DC */ - hbmpOrig = SelectObject (pGCPriv->hdcMem, pPixmapPriv->hBitmap); - if (hbmpOrig == NULL) - FatalError ("winSetSpans - DRAWABLE_PIXMAP - SelectObject () " - "failed on pPixmapPriv->hBitmap\n"); - - while (iSpans--) - { - ZeroMemory (&bmi, sizeof (mybitmap_t)); - bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = *piWidths; - bmi.bmiHeader.biHeight = 1; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = pDrawable->depth; - bmi.bmiHeader.biCompression = BI_RGB; - - /* Setup color table for mono DIBs */ - if (pDrawable->depth == 1) - { - bmi.bmiColors[1].rgbBlue = 255; - bmi.bmiColors[1].rgbGreen = 255; - bmi.bmiColors[1].rgbRed = 255; - } - - StretchDIBits (pGCPriv->hdcMem, - pPoints->x, pPoints->y, - *piWidths, 1, - 0, 0, - *piWidths, 1, - pSrcs, - (BITMAPINFO*)&bmi, - DIB_RGB_COLORS, - g_copyROP[pGC->alu]); - - pSrcs += PixmapBytePad (*piWidths, pDrawable->depth); - pPoints++; - piWidths++; - } - - /* Reset the clip region */ - SelectClipRgn (pGCPriv->hdcMem, NULL); - - /* Push the drawable pixmap out of the GC HDC */ - SelectObject (pGCPriv->hdcMem, hbmpOrig); - break; - - case DRAWABLE_WINDOW: - - SelectClipRgn (pGCPriv->hdc, combined); - DeleteObject (combined); - combined = NULL; - - while (iSpans--) - { - ZeroMemory (&bmi, sizeof (mybitmap_t)); - bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = *piWidths; - bmi.bmiHeader.biHeight = 1; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = pDrawable->depth; - bmi.bmiHeader.biCompression = BI_RGB; - - /* Setup color table for mono DIBs */ - if (pDrawable->depth == 1) - { - bmi.bmiColors[1].rgbBlue = 255; - bmi.bmiColors[1].rgbGreen = 255; - bmi.bmiColors[1].rgbRed = 255; - } - - StretchDIBits (pGCPriv->hdc, - pPoints->x, pPoints->y, - *piWidths, 1, - 0, 0, - *piWidths, 1, - pSrcs, - (BITMAPINFO *) &bmi, - DIB_RGB_COLORS, - g_copyROP[pGC->alu]); - - pSrcs += PixmapBytePad (*piWidths, pDrawable->depth); - pPoints++; - piWidths++; - } - - /* Reset the clip region */ - SelectClipRgn (pGCPriv->hdc, NULL); - break; - - case UNDRAWABLE_WINDOW: - FatalError ("\nwinSetSpansNativeGDI - UNDRAWABLE_WINDOW\n\n"); - break; - - case DRAWABLE_BUFFER: - FatalError ("\nwinSetSpansNativeGDI - DRAWABLE_BUFFER\n\n"); - break; - - default: - FatalError ("\nwinSetSpansNativeGDI - Unknown drawable type\n\n"); - break; - } -} +} mybitmap_t;
+
+/* See Porting Layer Definition - p. 55 */
+void
+winSetSpansNativeGDI (DrawablePtr pDrawable,
+ GCPtr pGC,
+ char *pSrcs,
+ DDXPointPtr pPoints,
+ int *piWidths,
+ int iSpans,
+ int fSorted)
+{
+ winGCPriv(pGC);
+ PixmapPtr pPixmap = NULL;
+ winPrivPixmapPtr pPixmapPriv = NULL;
+ HBITMAP hbmpOrig = NULL;
+ mybitmap_t bmi;
+ HRGN hrgn = NULL, combined = NULL;
+ int nbox;
+ BoxPtr pbox;
+
+ nbox = RegionNumRects (pGC->pCompositeClip);
+ pbox = RegionRects (pGC->pCompositeClip);
+
+ if (!nbox) return;
+
+ combined = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2, pbox->y2);
+ nbox--; pbox++;
+ while (nbox--)
+ {
+ hrgn = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2, pbox->y2);
+ CombineRgn (combined, combined, hrgn, RGN_OR);
+ DeleteObject (hrgn);
+ hrgn = NULL;
+ pbox++;
+ }
+
+ /* Branch on the drawable type */
+ switch (pDrawable->type)
+ {
+ case DRAWABLE_PIXMAP:
+
+ SelectClipRgn (pGCPriv->hdcMem, combined);
+ DeleteObject (combined);
+ combined = NULL;
+
+ pPixmap = (PixmapPtr) pDrawable;
+ pPixmapPriv = winGetPixmapPriv (pPixmap);
+
+ /* Select the drawable pixmap into a DC */
+ hbmpOrig = SelectObject (pGCPriv->hdcMem, pPixmapPriv->hBitmap);
+ if (hbmpOrig == NULL)
+ FatalError ("winSetSpans - DRAWABLE_PIXMAP - SelectObject () "
+ "failed on pPixmapPriv->hBitmap\n");
+
+ while (iSpans--)
+ {
+ ZeroMemory (&bmi, sizeof (mybitmap_t));
+ bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = *piWidths;
+ bmi.bmiHeader.biHeight = 1;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = pDrawable->depth;
+ bmi.bmiHeader.biCompression = BI_RGB;
+
+ /* Setup color table for mono DIBs */
+ if (pDrawable->depth == 1)
+ {
+ bmi.bmiColors[1].rgbBlue = 255;
+ bmi.bmiColors[1].rgbGreen = 255;
+ bmi.bmiColors[1].rgbRed = 255;
+ }
+
+ StretchDIBits (pGCPriv->hdcMem,
+ pPoints->x, pPoints->y,
+ *piWidths, 1,
+ 0, 0,
+ *piWidths, 1,
+ pSrcs,
+ (BITMAPINFO*)&bmi,
+ DIB_RGB_COLORS,
+ g_copyROP[pGC->alu]);
+
+ pSrcs += PixmapBytePad (*piWidths, pDrawable->depth);
+ pPoints++;
+ piWidths++;
+ }
+
+ /* Reset the clip region */
+ SelectClipRgn (pGCPriv->hdcMem, NULL);
+
+ /* Push the drawable pixmap out of the GC HDC */
+ SelectObject (pGCPriv->hdcMem, hbmpOrig);
+ break;
+
+ case DRAWABLE_WINDOW:
+
+ SelectClipRgn (pGCPriv->hdc, combined);
+ DeleteObject (combined);
+ combined = NULL;
+
+ while (iSpans--)
+ {
+ ZeroMemory (&bmi, sizeof (mybitmap_t));
+ bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = *piWidths;
+ bmi.bmiHeader.biHeight = 1;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = pDrawable->depth;
+ bmi.bmiHeader.biCompression = BI_RGB;
+
+ /* Setup color table for mono DIBs */
+ if (pDrawable->depth == 1)
+ {
+ bmi.bmiColors[1].rgbBlue = 255;
+ bmi.bmiColors[1].rgbGreen = 255;
+ bmi.bmiColors[1].rgbRed = 255;
+ }
+
+ StretchDIBits (pGCPriv->hdc,
+ pPoints->x, pPoints->y,
+ *piWidths, 1,
+ 0, 0,
+ *piWidths, 1,
+ pSrcs,
+ (BITMAPINFO *) &bmi,
+ DIB_RGB_COLORS,
+ g_copyROP[pGC->alu]);
+
+ pSrcs += PixmapBytePad (*piWidths, pDrawable->depth);
+ pPoints++;
+ piWidths++;
+ }
+
+ /* Reset the clip region */
+ SelectClipRgn (pGCPriv->hdc, NULL);
+ break;
+
+ case UNDRAWABLE_WINDOW:
+ FatalError ("\nwinSetSpansNativeGDI - UNDRAWABLE_WINDOW\n\n");
+ break;
+
+ case DRAWABLE_BUFFER:
+ FatalError ("\nwinSetSpansNativeGDI - DRAWABLE_BUFFER\n\n");
+ break;
+
+ default:
+ FatalError ("\nwinSetSpansNativeGDI - Unknown drawable type\n\n");
+ break;
+ }
+}
diff --git a/xorg-server/hw/xwin/winshaddd.c b/xorg-server/hw/xwin/winshaddd.c index 4d82ef714..4644a8493 100644 --- a/xorg-server/hw/xwin/winshaddd.c +++ b/xorg-server/hw/xwin/winshaddd.c @@ -1,1413 +1,1413 @@ -/* - *Copyright (C) 1994-2000 The XFree86 Project, 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, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *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. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of the XFree86 Project - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from the XFree86 Project. - * - * Authors: Dakshinamurthy Karra - * Suhaib M Siddiqi - * Peter Busch - * Harold L Hunt II - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" - - -/* - * External symbols - */ - -extern HWND g_hDlgExit; -extern const char *g_pszLogFile; - - - -/* - * Local prototypes - */ - -static Bool -winAllocateFBShadowDD (ScreenPtr pScreen); - -static void -winShadowUpdateDD (ScreenPtr pScreen, - shadowBufPtr pBuf); - -static Bool -winCloseScreenShadowDD (int nIndex, ScreenPtr pScreen); - -static Bool -winInitVisualsShadowDD (ScreenPtr pScreen); - -static Bool -winAdjustVideoModeShadowDD (ScreenPtr pScreen); - -static Bool -winBltExposedRegionsShadowDD (ScreenPtr pScreen); - -static Bool -winActivateAppShadowDD (ScreenPtr pScreen); - -static Bool -winRedrawScreenShadowDD (ScreenPtr pScreen); - -static Bool -winRealizeInstalledPaletteShadowDD (ScreenPtr pScreen); - -static Bool -winInstallColormapShadowDD (ColormapPtr pColormap); - -static Bool -winStoreColorsShadowDD (ColormapPtr pmap, - int ndef, - xColorItem *pdefs); - -static Bool -winCreateColormapShadowDD (ColormapPtr pColormap); - -static Bool -winDestroyColormapShadowDD (ColormapPtr pColormap); - -static Bool -winCreatePrimarySurfaceShadowDD (ScreenPtr pScreen); - -static Bool -winReleasePrimarySurfaceShadowDD (ScreenPtr pScreen); - - -/* - * Create the primary surface and attach the clipper. - * Used for both the initial surface creation and during - * WM_DISPLAYCHANGE messages. - */ - -static Bool -winCreatePrimarySurfaceShadowDD (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - HRESULT ddrval = DD_OK; - DDSURFACEDESC ddsd; - - /* Describe the primary surface */ - ZeroMemory (&ddsd, sizeof (ddsd)); - ddsd.dwSize = sizeof (ddsd); - ddsd.dwFlags = DDSD_CAPS; - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - - /* Create the primary surface */ - ddrval = IDirectDraw2_CreateSurface (pScreenPriv->pdd2, - &ddsd, - &pScreenPriv->pddsPrimary, - NULL); - if (FAILED (ddrval)) - { - ErrorF ("winCreatePrimarySurfaceShadowDD - Could not create primary " - "surface: %08x\n", (unsigned int) ddrval); - return FALSE; - } - - winDebug ("winCreatePrimarySurfaceShadowDD - Created primary surface\n"); - - /* - * Attach a clipper to the primary surface that will clip our blits to our - * display window. - */ - ddrval = IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary, - pScreenPriv->pddcPrimary); - if (FAILED (ddrval)) - { - ErrorF ("winCreatePrimarySurfaceShadowDD - Primary attach clipper " - "failed: %08x\n", - (unsigned int) ddrval); - return FALSE; - } - - winDebug ("winCreatePrimarySurfaceShadowDD - Attached clipper to " - "primary surface\n"); - - /* Everything was correct */ - return TRUE; -} - - -/* - * Detach the clipper and release the primary surface. - * Called from WM_DISPLAYCHANGE. - */ - -static Bool -winReleasePrimarySurfaceShadowDD (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - - winDebug ("winReleasePrimarySurfaceShadowDD - Hello\n"); - - /* Release the primary surface and clipper, if they exist */ - if (pScreenPriv->pddsPrimary) - { - /* - * Detach the clipper from the primary surface. - * NOTE: We do this explicity for clarity. The Clipper is not released. - */ - IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary, - NULL); - - winDebug ("winReleasePrimarySurfaceShadowDD - Detached clipper\n"); - - /* Release the primary surface */ - IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary); - pScreenPriv->pddsPrimary = NULL; - } - - winDebug ("winReleasePrimarySurfaceShadowDD - Released primary surface\n"); - - return TRUE; -} - - -/* - * Create a DirectDraw surface for the shadow framebuffer; also create - * a primary surface object so we can blit to the display. - * - * Install a DirectDraw clipper on our primary surface object - * that clips our blits to the unobscured client area of our display window. - */ - -static Bool -winAllocateFBShadowDD (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - HRESULT ddrval = DD_OK; - DDSURFACEDESC ddsd; - DDSURFACEDESC *pddsdShadow = NULL; - - winDebug ("winAllocateFBShadowDD\n"); - - /* Create a clipper */ - ddrval = (*g_fpDirectDrawCreateClipper) (0, - &pScreenPriv->pddcPrimary, - NULL); - if (FAILED (ddrval)) - { - ErrorF ("winAllocateFBShadowDD - Could not create clipper: %08x\n", - (unsigned int) ddrval); - return FALSE; - } - - winDebug ("winAllocateFBShadowDD - Created a clipper\n"); - - /* Get a device context for the screen */ - pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen); - - /* Attach the clipper to our display window */ - ddrval = IDirectDrawClipper_SetHWnd (pScreenPriv->pddcPrimary, - 0, - pScreenPriv->hwndScreen); - if (FAILED (ddrval)) - { - ErrorF ("winAllocateFBShadowDD - Clipper not attached to " - "window: %08x\n", - (unsigned int) ddrval); - return FALSE; - } - - winDebug ("winAllocateFBShadowDD - Attached clipper to window\n"); - - /* Create a DirectDraw object, store the address at lpdd */ - ddrval = (*g_fpDirectDrawCreate) (NULL, &pScreenPriv->pdd, NULL); - if (FAILED (ddrval)) - { - ErrorF ("winAllocateFBShadowDD - Could not start DirectDraw: %08x\n", - (unsigned int) ddrval); - return FALSE; - } - - winDebug ("winAllocateFBShadowDD () - Created and initialized DD\n"); - - /* Get a DirectDraw2 interface pointer */ - ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd, - &IID_IDirectDraw2, - (LPVOID*) &pScreenPriv->pdd2); - if (FAILED (ddrval)) - { - ErrorF ("winAllocateFBShadowDD - Failed DD2 query: %08x\n", - (unsigned int) ddrval); - return FALSE; - } - - /* Are we full screen? */ - if (pScreenInfo->fFullScreen) - { - DDSURFACEDESC ddsdCurrent; - DWORD dwRefreshRateCurrent = 0; - HDC hdc = NULL; - - /* Set the cooperative level to full screen */ - ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2, - pScreenPriv->hwndScreen, - DDSCL_EXCLUSIVE - | DDSCL_FULLSCREEN); - if (FAILED (ddrval)) - { - ErrorF ("winAllocateFBShadowDD - Could not set " - "cooperative level: %08x\n", - (unsigned int) ddrval); - return FALSE; - } - - /* - * We only need to get the current refresh rate for comparison - * if a refresh rate has been passed on the command line. - */ - if (pScreenInfo->dwRefreshRate != 0) - { - ZeroMemory (&ddsdCurrent, sizeof (ddsdCurrent)); - ddsdCurrent.dwSize = sizeof (ddsdCurrent); - - /* Get information about current display settings */ - ddrval = IDirectDraw2_GetDisplayMode (pScreenPriv->pdd2, - &ddsdCurrent); - if (FAILED (ddrval)) - { - ErrorF ("winAllocateFBShadowDD - Could not get current " - "refresh rate: %08x. Continuing.\n", - (unsigned int) ddrval); - dwRefreshRateCurrent = 0; - } - else - { - /* Grab the current refresh rate */ - dwRefreshRateCurrent = ddsdCurrent.u2.dwRefreshRate; - } - } - - /* Clean up the refresh rate */ - if (dwRefreshRateCurrent == pScreenInfo->dwRefreshRate) - { - /* - * Refresh rate is non-specified or equal to current. - */ - pScreenInfo->dwRefreshRate = 0; - } - - /* Grab a device context for the screen */ - hdc = GetDC (NULL); - if (hdc == NULL) - { - ErrorF ("winAllocateFBShadowDD - GetDC () failed\n"); - return FALSE; - } - - /* Only change the video mode when different than current mode */ - if (!pScreenInfo->fMultipleMonitors - && (pScreenInfo->dwWidth != GetSystemMetrics (SM_CXSCREEN) - || pScreenInfo->dwHeight != GetSystemMetrics (SM_CYSCREEN) - || pScreenInfo->dwBPP != GetDeviceCaps (hdc, BITSPIXEL) - || pScreenInfo->dwRefreshRate != 0)) - { - winDebug ("winAllocateFBShadowDD - Changing video mode\n"); - - /* Change the video mode to the mode requested, and use the driver default refresh rate on failure */ - ddrval = IDirectDraw2_SetDisplayMode (pScreenPriv->pdd2, - pScreenInfo->dwWidth, - pScreenInfo->dwHeight, - pScreenInfo->dwBPP, - pScreenInfo->dwRefreshRate, - 0); - if (FAILED (ddrval)) - { - ErrorF ("winAllocateFBShadowDD - Could not set "\ - "full screen display mode: %08x\n", - (unsigned int) ddrval); - ErrorF ("winAllocateFBShadowDD - Using default driver refresh rate\n"); - ddrval = IDirectDraw2_SetDisplayMode (pScreenPriv->pdd2, - pScreenInfo->dwWidth, - pScreenInfo->dwHeight, - pScreenInfo->dwBPP, - 0, - 0); - if (FAILED(ddrval)) - { - ErrorF ("winAllocateFBShadowDD - Could not set default refresh rate " - "full screen display mode: %08x\n", - (unsigned int) ddrval); - return FALSE; - } - } - } - else - { - winDebug ("winAllocateFBShadowDD - Not changing video mode\n"); - } - - /* Release our DC */ - ReleaseDC (NULL, hdc); - hdc = NULL; - } - else - { - /* Set the cooperative level for windowed mode */ - ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2, - pScreenPriv->hwndScreen, - DDSCL_NORMAL); - if (FAILED (ddrval)) - { - ErrorF ("winAllocateFBShadowDD - Could not set "\ - "cooperative level: %08x\n", - (unsigned int) ddrval); - return FALSE; - } - } - - /* Create the primary surface */ - if (!winCreatePrimarySurfaceShadowDD (pScreen)) - { - ErrorF ("winAllocateFBShadowDD - winCreatePrimarySurfaceShadowDD " - "failed\n"); - return FALSE; - } - - /* Describe the shadow surface to be created */ - /* NOTE: Do not use a DDSCAPS_VIDEOMEMORY surface, - * as drawing, locking, and unlocking take forever - * with video memory surfaces. In addition, - * video memory is a somewhat scarce resource, - * so you shouldn't be allocating video memory when - * you have the option of using system memory instead. - */ - ZeroMemory (&ddsd, sizeof (ddsd)); - ddsd.dwSize = sizeof (ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; - ddsd.dwHeight = pScreenInfo->dwHeight; - ddsd.dwWidth = pScreenInfo->dwWidth; - - /* Create the shadow surface */ - ddrval = IDirectDraw2_CreateSurface (pScreenPriv->pdd2, - &ddsd, - &pScreenPriv->pddsShadow, - NULL); - if (FAILED (ddrval)) - { - ErrorF ("winAllocateFBShadowDD - Could not create shadow "\ - "surface: %08x\n", (unsigned int) ddrval); - return FALSE; - } - - winDebug ("winAllocateFBShadowDD - Created shadow\n"); - - /* Allocate a DD surface description for our screen privates */ - pddsdShadow = pScreenPriv->pddsdShadow = malloc (sizeof (DDSURFACEDESC)); - if (pddsdShadow == NULL) - { - ErrorF ("winAllocateFBShadowDD - Could not allocate surface "\ - "description memory\n"); - return FALSE; - } - ZeroMemory (pddsdShadow, sizeof (*pddsdShadow)); - pddsdShadow->dwSize = sizeof (*pddsdShadow); - - winDebug ("winAllocateFBShadowDD - Locking shadow\n"); - - /* Lock the shadow surface */ - ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow, - NULL, - pddsdShadow, - DDLOCK_WAIT, - NULL); - if (FAILED (ddrval) || pddsdShadow->lpSurface == NULL) - { - ErrorF ("winAllocateFBShadowDD - Could not lock shadow "\ - "surface: %08x\n", (unsigned int) ddrval); - return FALSE; - } - - winDebug ("winAllocateFBShadowDD - Locked shadow\n"); - - /* We don't know how to deal with anything other than RGB */ - if (!(pddsdShadow->ddpfPixelFormat.dwFlags & DDPF_RGB)) - { - ErrorF ("winAllocateFBShadowDD - Color format other than RGB\n"); - return FALSE; - } - - /* Grab the pitch from the surface desc */ - pScreenInfo->dwStride = (pddsdShadow->u1.lPitch * 8) - / pScreenInfo->dwBPP; - - /* Save the pointer to our surface memory */ - pScreenInfo->pfb = pddsdShadow->lpSurface; - - /* Grab the color depth and masks from the surface description */ - pScreenPriv->dwRedMask = pddsdShadow->ddpfPixelFormat.u2.dwRBitMask; - pScreenPriv->dwGreenMask = pddsdShadow->ddpfPixelFormat.u3.dwGBitMask; - pScreenPriv->dwBlueMask = pddsdShadow->ddpfPixelFormat.u4.dwBBitMask; - - winDebug ("winAllocateFBShadowDD - Returning\n"); - - return TRUE; -} - - -/* - * Transfer the damaged regions of the shadow framebuffer to the display. - */ - -static void -winShadowUpdateDD (ScreenPtr pScreen, - shadowBufPtr pBuf) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - RegionPtr damage = shadowDamage(pBuf); - HRESULT ddrval = DD_OK; - RECT rcDest, rcSrc; - POINT ptOrigin; - DWORD dwBox = REGION_NUM_RECTS (damage); - BoxPtr pBox = REGION_RECTS (damage); - HRGN hrgnTemp = NULL, hrgnCombined = NULL; - - /* - * Return immediately if the app is not active - * and we are fullscreen, or if we have a bad display depth - */ - if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen) - || pScreenPriv->fBadDepth) return; - - /* Get the origin of the window in the screen coords */ - ptOrigin.x = pScreenInfo->dwXOffset; - ptOrigin.y = pScreenInfo->dwYOffset; - MapWindowPoints (pScreenPriv->hwndScreen, - HWND_DESKTOP, - (LPPOINT)&ptOrigin, 1); - - /* Unlock the shadow surface, so we can blit */ - ddrval = IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL); - if (FAILED (ddrval)) - { - ErrorF ("winShadowUpdateDD - Unlock failed\n"); - return; - } - - /* - * Handle small regions with multiple blits, - * handle large regions by creating a clipping region and - * doing a single blit constrained to that clipping region. - */ - if (pScreenInfo->dwClipUpdatesNBoxes == 0 - || dwBox < pScreenInfo->dwClipUpdatesNBoxes) - { - /* Loop through all boxes in the damaged region */ - while (dwBox--) - { - /* Assign damage box to source rectangle */ - rcSrc.left = pBox->x1; - rcSrc.top = pBox->y1; - rcSrc.right = pBox->x2; - rcSrc.bottom = pBox->y2; - - /* Calculate destination rectange */ - rcDest.left = ptOrigin.x + rcSrc.left; - rcDest.top = ptOrigin.y + rcSrc.top; - rcDest.right = ptOrigin.x + rcSrc.right; - rcDest.bottom = ptOrigin.y + rcSrc.bottom; - - /* Blit the damaged areas */ - ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, - &rcDest, - pScreenPriv->pddsShadow, - &rcSrc, - DDBLT_WAIT, - NULL); - - /* Get a pointer to the next box */ - ++pBox; - } - } - else - { - BoxPtr pBoxExtents = REGION_EXTENTS (pScreen, damage); - - /* Compute a GDI region from the damaged region */ - hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); - dwBox--; - pBox++; - while (dwBox--) - { - hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); - CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR); - DeleteObject (hrgnTemp); - pBox++; - } - - /* Install the GDI region as a clipping region */ - SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined); - DeleteObject (hrgnCombined); - hrgnCombined = NULL; - - /* Calculating a bounding box for the source is easy */ - rcSrc.left = pBoxExtents->x1; - rcSrc.top = pBoxExtents->y1; - rcSrc.right = pBoxExtents->x2; - rcSrc.bottom = pBoxExtents->y2; - - /* Calculating a bounding box for the destination is trickier */ - rcDest.left = ptOrigin.x + rcSrc.left; - rcDest.top = ptOrigin.y + rcSrc.top; - rcDest.right = ptOrigin.x + rcSrc.right; - rcDest.bottom = ptOrigin.y + rcSrc.bottom; - - /* Our Blt should be clipped to the invalidated region */ - ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, - &rcDest, - pScreenPriv->pddsShadow, - &rcSrc, - DDBLT_WAIT, - NULL); - - /* Reset the clip region */ - SelectClipRgn (pScreenPriv->hdcScreen, NULL); - } - - /* Relock the shadow surface */ - ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow, - NULL, - pScreenPriv->pddsdShadow, - DDLOCK_WAIT, - NULL); - if (FAILED (ddrval)) - { - ErrorF ("winShadowUpdateDD - Lock failed\n"); - return; - } - - /* Has our memory pointer changed? */ - if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface) - { - extern const char *g_pszLogFile; - ErrorF ("winShadowUpdateDD - Memory location of the shadow " - "surface has changed, trying to update the root window " - "pixmap header to point to the new address. If you get " - "this message and "PROJECT_NAME" freezes or crashes " - "after this message then send a problem report and your " - "%s file to " BUILDERADDR "\n", g_pszLogFile); - - /* Location of shadow framebuffer has changed */ - pScreenInfo->pfb = pScreenPriv->pddsdShadow->lpSurface; - - /* Update the screen pixmap */ - if (!(*pScreen->ModifyPixmapHeader)(pScreen->devPrivate, - pScreen->width, - pScreen->height, - pScreen->rootDepth, - BitsPerPixel (pScreen->rootDepth), - PixmapBytePad (pScreenInfo->dwStride, - pScreenInfo->dwBPP), - pScreenInfo->pfb)) - { - ErrorF ("winShadowUpdateDD - Bits changed, could not " - "notify fb.\n"); - return; - } - } -} - - -/* - * Call the wrapped CloseScreen function. - * - * Free our resources and private structures. - */ - -static Bool -winCloseScreenShadowDD (int nIndex, ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - Bool fReturn; - - winDebug ("winCloseScreenShadowDD - Freeing screen resources\n"); - - /* Flag that the screen is closed */ - pScreenPriv->fClosed = TRUE; - pScreenPriv->fActive = FALSE; - - /* Call the wrapped CloseScreen procedure */ - WIN_UNWRAP(CloseScreen); - fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); - - /* Free the screen DC */ - ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen); - - /* Delete the window property */ - RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP); - - /* Free the shadow surface, if there is one */ - if (pScreenPriv->pddsShadow) - { - IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL); - IDirectDrawSurface2_Release (pScreenPriv->pddsShadow); - pScreenPriv->pddsShadow = NULL; - } - - /* Detach the clipper from the primary surface and release the clipper. */ - if (pScreenPriv->pddcPrimary) - { - /* Detach the clipper */ - IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary, - NULL); - - /* Release the clipper object */ - IDirectDrawClipper_Release (pScreenPriv->pddcPrimary); - pScreenPriv->pddcPrimary = NULL; - } - - /* Release the primary surface, if there is one */ - if (pScreenPriv->pddsPrimary) - { - IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary); - pScreenPriv->pddsPrimary = NULL; - } - - /* Free the DirectDraw2 object, if there is one */ - if (pScreenPriv->pdd2) - { - IDirectDraw2_RestoreDisplayMode (pScreenPriv->pdd2); - IDirectDraw2_Release (pScreenPriv->pdd2); - pScreenPriv->pdd2 = NULL; - } - - /* Free the DirectDraw object, if there is one */ - if (pScreenPriv->pdd) - { - IDirectDraw_Release (pScreenPriv->pdd); - pScreenPriv->pdd = NULL; - } - - /* Delete tray icon, if we have one */ - if (!pScreenInfo->fNoTrayIcon) - winDeleteNotifyIcon (pScreenPriv); - - /* Free the exit confirmation dialog box, if it exists */ - if (g_hDlgExit != NULL) - { - DestroyWindow (g_hDlgExit); - g_hDlgExit = NULL; - } - - /* Kill our window */ - if (pScreenPriv->hwndScreen) - { - DestroyWindow (pScreenPriv->hwndScreen); - pScreenPriv->hwndScreen = NULL; - } - -#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) - /* Destroy the thread startup mutex */ - pthread_mutex_destroy (&pScreenPriv->pmServerStarted); -#endif - - /* Kill our screeninfo's pointer to the screen */ - pScreenInfo->pScreen = NULL; - - /* Invalidate the ScreenInfo's fb pointer */ - pScreenInfo->pfb = NULL; - - /* Free the screen privates for this screen */ - free ((pointer) pScreenPriv); - - return fReturn; -} - - -/* - * Tell mi what sort of visuals we need. - * - * Generally we only need one visual, as our screen can only - * handle one format at a time, I believe. You may want - * to verify that last sentence. - */ - -static Bool -winInitVisualsShadowDD (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - DWORD dwRedBits, dwGreenBits, dwBlueBits; - - /* Count the number of ones in each color mask */ - dwRedBits = winCountBits (pScreenPriv->dwRedMask); - dwGreenBits = winCountBits (pScreenPriv->dwGreenMask); - dwBlueBits = winCountBits (pScreenPriv->dwBlueMask); - - /* Store the maximum number of ones in a color mask as the bitsPerRGB */ - if (dwRedBits == 0 || dwGreenBits == 0 || dwBlueBits == 0) - pScreenPriv->dwBitsPerRGB = 8; - else if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits) - pScreenPriv->dwBitsPerRGB = dwRedBits; - else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits) - pScreenPriv->dwBitsPerRGB = dwGreenBits; - else - pScreenPriv->dwBitsPerRGB = dwBlueBits; - - winDebug ("winInitVisualsShadowDD - Masks %08x %08x %08x BPRGB %d d %d " - "bpp %d\n", - (unsigned int) pScreenPriv->dwRedMask, - (unsigned int) pScreenPriv->dwGreenMask, - (unsigned int) pScreenPriv->dwBlueMask, - (int) pScreenPriv->dwBitsPerRGB, - (int) pScreenInfo->dwDepth, - (int) pScreenInfo->dwBPP); - - /* Create a single visual according to the Windows screen depth */ - switch (pScreenInfo->dwDepth) - { - case 24: - case 16: - case 15: -#if defined(XFree86Server) - /* Create the real visual */ - if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, - TrueColorMask, - pScreenPriv->dwBitsPerRGB, - TrueColor, - pScreenPriv->dwRedMask, - pScreenPriv->dwGreenMask, - pScreenPriv->dwBlueMask)) - { - ErrorF ("winInitVisualsShadowDD - miSetVisualTypesAndMasks " - "failed for TrueColor\n"); - return FALSE; - } - -#ifdef XWIN_EMULATEPSEUDO - if (!pScreenInfo->fEmulatePseudo) - break; - - /* Setup a pseudocolor visual */ - if (!miSetVisualTypesAndMasks (8, - PseudoColorMask, - 8, - -1, - 0, - 0, - 0)) - { - ErrorF ("winInitVisualsShadowDD - miSetVisualTypesAndMasks " - "failed for PseudoColor\n"); - return FALSE; - } -#endif -#else /* XFree86Server */ - /* Create the real visual */ - if (!fbSetVisualTypesAndMasks (pScreenInfo->dwDepth, - TrueColorMask, - pScreenPriv->dwBitsPerRGB, - pScreenPriv->dwRedMask, - pScreenPriv->dwGreenMask, - pScreenPriv->dwBlueMask)) - { - ErrorF ("winInitVisualsShadowDD - fbSetVisualTypesAndMasks " - "failed for TrueColor\n"); - return FALSE; - } - -#ifdef XWIN_EMULATEPSEUDO - if (!pScreenInfo->fEmulatePseudo) - break; - - /* Setup a pseudocolor visual */ - if (!fbSetVisualTypesAndMasks (8, - PseudoColorMask, - 8, - 0, - 0, - 0)) - { - ErrorF ("winInitVisualsShadowDD - fbSetVisualTypesAndMasks " - "failed for PseudoColor\n"); - return FALSE; - } -#endif -#endif /* XFree86Server */ - break; - - case 8: -#if defined(XFree86Server) - if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, - pScreenInfo->fFullScreen - ? PseudoColorMask : StaticColorMask, - pScreenPriv->dwBitsPerRGB, - pScreenInfo->fFullScreen - ? PseudoColor : StaticColor, - pScreenPriv->dwRedMask, - pScreenPriv->dwGreenMask, - pScreenPriv->dwBlueMask)) - { - ErrorF ("winInitVisualsShadowDD - miSetVisualTypesAndMasks " - "failed\n"); - return FALSE; - } -#else /* XFree86Server */ - if (!fbSetVisualTypesAndMasks (pScreenInfo->dwDepth, - pScreenInfo->fFullScreen - ? PseudoColorMask : StaticColorMask, - pScreenPriv->dwBitsPerRGB, - pScreenPriv->dwRedMask, - pScreenPriv->dwGreenMask, - pScreenPriv->dwBlueMask)) - { - ErrorF ("winInitVisualsShadowDD - fbSetVisualTypesAndMasks " - "failed\n"); - return FALSE; - } -#endif /* XFree86Server */ - break; - - default: - ErrorF ("winInitVisualsShadowDD - Unknown screen depth\n"); - return FALSE; - } - - winDebug ("winInitVisualsShadowDD - Returning\n"); - - return TRUE; -} - - -/* - * Adjust the user proposed video mode - */ - -static Bool -winAdjustVideoModeShadowDD (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - HDC hdc = NULL; - DWORD dwBPP; - - /* We're in serious trouble if we can't get a DC */ - hdc = GetDC (NULL); - if (hdc == NULL) - { - ErrorF ("winAdjustVideoModeShadowDD - GetDC () failed\n"); - return FALSE; - } - - /* Query GDI for current display depth */ - dwBPP = GetDeviceCaps (hdc, BITSPIXEL); - - /* DirectDraw can only change the depth in fullscreen mode */ - if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP) - { - /* No -depth parameter passed, let the user know the depth being used */ - winDebug ("winAdjustVideoModeShadowDD - Using Windows display " - "depth of %d bits per pixel\n", (int) dwBPP); - - /* Use GDI's depth */ - pScreenInfo->dwBPP = dwBPP; - } - else if (pScreenInfo->fFullScreen - && pScreenInfo->dwBPP != dwBPP) - { - /* FullScreen, and GDI depth differs from -depth parameter */ - winDebug ("winAdjustVideoModeShadowDD - FullScreen, using command line " - "bpp: %d\n", (int) pScreenInfo->dwBPP); - } - else if (dwBPP != pScreenInfo->dwBPP) - { - /* Windowed, and GDI depth differs from -depth parameter */ - winDebug ("winAdjustVideoModeShadowDD - Windowed, command line bpp: " - "%d, using bpp: %d\n", (int) pScreenInfo->dwBPP, (int) dwBPP); - - /* We'll use GDI's depth */ - pScreenInfo->dwBPP = dwBPP; - } - - /* See if the shadow bitmap will be larger than the DIB size limit */ - if (pScreenInfo->dwWidth * pScreenInfo->dwHeight * pScreenInfo->dwBPP - >= WIN_DIB_MAXIMUM_SIZE) - { - ErrorF ("winAdjustVideoModeShadowDD - Requested DirectDraw surface " - "will be larger than %d MB. The surface may fail to be " - "allocated on Windows 95, 98, or Me, due to a %d MB limit in " - "DIB size. This limit does not apply to Windows NT/2000, and " - "this message may be ignored on those platforms.\n", - WIN_DIB_MAXIMUM_SIZE_MB, WIN_DIB_MAXIMUM_SIZE_MB); - } - - /* Release our DC */ - ReleaseDC (NULL, hdc); - return TRUE; -} - - -/* - * Blt exposed regions to the screen - */ - -static Bool -winBltExposedRegionsShadowDD (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - RECT rcSrc, rcDest; - POINT ptOrigin; - HDC hdcUpdate = NULL; - PAINTSTRUCT ps; - HRESULT ddrval = DD_OK; - Bool fReturn = TRUE; - Bool fLocked = TRUE; - int i; - - /* BeginPaint gives us an hdc that clips to the invalidated region */ - hdcUpdate = BeginPaint (pScreenPriv->hwndScreen, &ps); - if (hdcUpdate == NULL) - { - ErrorF ("winBltExposedRegionsShadowDD - BeginPaint () returned " - "a NULL device context handle. Aborting blit attempt.\n"); - return FALSE; - } - - /* Unlock the shadow surface, so we can blit */ - ddrval = IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL); - if (FAILED (ddrval)) - { - fReturn = FALSE; - goto winBltExposedRegionsShadowDD_Exit; - } - else - { - /* Flag that we have unlocked the shadow surface */ - fLocked = FALSE; - } - - /* Get the origin of the window in the screen coords */ - ptOrigin.x = pScreenInfo->dwXOffset; - ptOrigin.y = pScreenInfo->dwYOffset; - - MapWindowPoints (pScreenPriv->hwndScreen, - HWND_DESKTOP, - (LPPOINT)&ptOrigin, 1); - rcDest.left = ptOrigin.x; - rcDest.right = ptOrigin.x + pScreenInfo->dwWidth; - rcDest.top = ptOrigin.y; - rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight; - - /* Source can be enter shadow surface, as Blt should clip */ - rcSrc.left = 0; - rcSrc.top = 0; - rcSrc.right = pScreenInfo->dwWidth; - rcSrc.bottom = pScreenInfo->dwHeight; - - /* Try to regain the primary surface and blit again if we've lost it */ - for (i = 0; i <= WIN_REGAIN_SURFACE_RETRIES; ++i) - { - /* Our Blt should be clipped to the invalidated region */ - ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, - &rcDest, - pScreenPriv->pddsShadow, - &rcSrc, - DDBLT_WAIT, - NULL); - if (ddrval == DDERR_SURFACELOST) - { - /* Surface was lost */ - ErrorF ("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Blt " - "reported that the primary surface was lost, " - "trying to restore, retry: %d\n", i + 1); - - /* Try to restore the surface, once */ - ddrval = IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary); - ErrorF ("winBltExposedRegionsShadowDD - " - "IDirectDrawSurface2_Restore returned: "); - if (ddrval == DD_OK) - ErrorF ("DD_OK\n"); - else if (ddrval == DDERR_WRONGMODE) - ErrorF ("DDERR_WRONGMODE\n"); - else if (ddrval == DDERR_INCOMPATIBLEPRIMARY) - ErrorF ("DDERR_INCOMPATIBLEPRIMARY\n"); - else if (ddrval == DDERR_UNSUPPORTED) - ErrorF ("DDERR_UNSUPPORTED\n"); - else if (ddrval == DDERR_INVALIDPARAMS) - ErrorF ("DDERR_INVALIDPARAMS\n"); - else if (ddrval == DDERR_INVALIDOBJECT) - ErrorF ("DDERR_INVALIDOBJECT\n"); - else - ErrorF ("unknown error: %08x\n", (unsigned int) ddrval); - - /* Loop around to try the blit one more time */ - continue; - } - else if (FAILED (ddrval)) - { - fReturn = FALSE; - ErrorF ("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Blt " - "failed, but surface not lost: %08x %d\n", - (unsigned int) ddrval, (int) ddrval); - goto winBltExposedRegionsShadowDD_Exit; - } - else - { - /* Success, stop looping */ - break; - } - } - - /* Relock the shadow surface */ - ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow, - NULL, - pScreenPriv->pddsdShadow, - DDLOCK_WAIT, - NULL); - if (FAILED (ddrval)) - { - fReturn = FALSE; - ErrorF ("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Lock " - "failed\n"); - goto winBltExposedRegionsShadowDD_Exit; - } - else - { - /* Indicate that we have relocked the shadow surface */ - fLocked = TRUE; - } - - /* Has our memory pointer changed? */ - if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface) - winUpdateFBPointer (pScreen, - pScreenPriv->pddsdShadow->lpSurface); - - winBltExposedRegionsShadowDD_Exit: - /* EndPaint frees the DC */ - if (hdcUpdate != NULL) - EndPaint (pScreenPriv->hwndScreen, &ps); - - /* - * Relock the surface if it is not locked. We don't care if locking fails, - * as it will cause the server to shutdown within a few more operations. - */ - if (!fLocked) - { - IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow, - NULL, - pScreenPriv->pddsdShadow, - DDLOCK_WAIT, - NULL); - - /* Has our memory pointer changed? */ - if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface) - winUpdateFBPointer (pScreen, - pScreenPriv->pddsdShadow->lpSurface); - - fLocked = TRUE; - } - return fReturn; -} - - -/* - * Do any engine-specific appliation-activation processing - */ - -static Bool -winActivateAppShadowDD (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - - /* - * Do we have a surface? - * Are we active? - * Are we fullscreen? - */ - if (pScreenPriv != NULL - && pScreenPriv->pddsPrimary != NULL - && pScreenPriv->fActive) - { - /* Primary surface was lost, restore it */ - IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary); - } - - return TRUE; -} - - -/* - * Reblit the shadow framebuffer to the screen. - */ - -static Bool -winRedrawScreenShadowDD (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - HRESULT ddrval = DD_OK; - RECT rcSrc, rcDest; - POINT ptOrigin; - - /* Get the origin of the window in the screen coords */ - ptOrigin.x = pScreenInfo->dwXOffset; - ptOrigin.y = pScreenInfo->dwYOffset; - MapWindowPoints (pScreenPriv->hwndScreen, - HWND_DESKTOP, - (LPPOINT)&ptOrigin, 1); - rcDest.left = ptOrigin.x; - rcDest.right = ptOrigin.x + pScreenInfo->dwWidth; - rcDest.top = ptOrigin.y; - rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight; - - /* Source can be entire shadow surface, as Blt should clip for us */ - rcSrc.left = 0; - rcSrc.top = 0; - rcSrc.right = pScreenInfo->dwWidth; - rcSrc.bottom = pScreenInfo->dwHeight; - - /* Redraw the whole window, to take account for the new colors */ - ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, - &rcDest, - pScreenPriv->pddsShadow, - &rcSrc, - DDBLT_WAIT, - NULL); - if (FAILED (ddrval)) - { - ErrorF ("winRedrawScreenShadowDD - IDirectDrawSurface_Blt () " - "failed: %08x\n", - (unsigned int) ddrval); - } - - return TRUE; -} - - -/* - * Realize the currently installed colormap - */ - -static Bool -winRealizeInstalledPaletteShadowDD (ScreenPtr pScreen) -{ - return TRUE; -} - - -/* - * Install the specified colormap - */ - -static Bool -winInstallColormapShadowDD (ColormapPtr pColormap) -{ - ScreenPtr pScreen = pColormap->pScreen; - winScreenPriv(pScreen); - winCmapPriv(pColormap); - HRESULT ddrval = DD_OK; - - /* Install the DirectDraw palette on the primary surface */ - ddrval = IDirectDrawSurface2_SetPalette (pScreenPriv->pddsPrimary, - pCmapPriv->lpDDPalette); - if (FAILED (ddrval)) - { - ErrorF ("winInstallColormapShadowDD - Failed installing the " - "DirectDraw palette.\n"); - return FALSE; - } - - /* Save a pointer to the newly installed colormap */ - pScreenPriv->pcmapInstalled = pColormap; - - return TRUE; -} - - -/* - * Store the specified colors in the specified colormap - */ - -static Bool -winStoreColorsShadowDD (ColormapPtr pColormap, - int ndef, - xColorItem *pdefs) -{ - ScreenPtr pScreen = pColormap->pScreen; - winScreenPriv(pScreen); - winCmapPriv(pColormap); - ColormapPtr curpmap = pScreenPriv->pcmapInstalled; - HRESULT ddrval = DD_OK; - - /* Put the X colormap entries into the Windows logical palette */ - ddrval = IDirectDrawPalette_SetEntries (pCmapPriv->lpDDPalette, - 0, - pdefs[0].pixel, - ndef, - pCmapPriv->peColors - + pdefs[0].pixel); - if (FAILED (ddrval)) - { - ErrorF ("winStoreColorsShadowDD - SetEntries () failed\n"); - return FALSE; - } - - /* Don't install the DirectDraw palette if the colormap is not installed */ - if (pColormap != curpmap) - { - return TRUE; - } - - if (!winInstallColormapShadowDD (pColormap)) - { - ErrorF ("winStoreColorsShadowDD - Failed installing colormap\n"); - return FALSE; - } - - return TRUE; -} - - -/* - * Colormap initialization procedure - */ - -static Bool -winCreateColormapShadowDD (ColormapPtr pColormap) -{ - HRESULT ddrval = DD_OK; - ScreenPtr pScreen = pColormap->pScreen; - winScreenPriv(pScreen); - winCmapPriv(pColormap); - - /* Create a DirectDraw palette */ - ddrval = IDirectDraw2_CreatePalette (pScreenPriv->pdd, - DDPCAPS_8BIT | DDPCAPS_ALLOW256, - pCmapPriv->peColors, - &pCmapPriv->lpDDPalette, - NULL); - if (FAILED (ddrval)) - { - ErrorF ("winCreateColormapShadowDD - CreatePalette failed\n"); - return FALSE; - } - - return TRUE; -} - - -/* - * Colormap destruction procedure - */ - -static Bool -winDestroyColormapShadowDD (ColormapPtr pColormap) -{ - winScreenPriv(pColormap->pScreen); - winCmapPriv(pColormap); - HRESULT ddrval = DD_OK; - - /* - * Is colormap to be destroyed the default? - * - * Non-default colormaps should have had winUninstallColormap - * called on them before we get here. The default colormap - * will not have had winUninstallColormap called on it. Thus, - * we need to handle the default colormap in a special way. - */ - if (pColormap->flags & IsDefault) - { - winDebug ("winDestroyColormapShadowDD - Destroying default " - "colormap\n"); - - /* - * FIXME: Walk the list of all screens, popping the default - * palette out of each screen device context. - */ - - /* Pop the palette out of the primary surface */ - ddrval = IDirectDrawSurface2_SetPalette (pScreenPriv->pddsPrimary, - NULL); - if (FAILED (ddrval)) - { - ErrorF ("winDestroyColormapShadowDD - Failed freeing the " - "default colormap DirectDraw palette.\n"); - return FALSE; - } - - /* Clear our private installed colormap pointer */ - pScreenPriv->pcmapInstalled = NULL; - } - - /* Release the palette */ - IDirectDrawPalette_Release (pCmapPriv->lpDDPalette); - - /* Invalidate the colormap privates */ - pCmapPriv->lpDDPalette = NULL; - - return TRUE; -} - - -/* - * Set engine specific functions - */ - -Bool -winSetEngineFunctionsShadowDD (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - - /* Set our pointers */ - pScreenPriv->pwinAllocateFB = winAllocateFBShadowDD; - pScreenPriv->pwinShadowUpdate = winShadowUpdateDD; - pScreenPriv->pwinCloseScreen = winCloseScreenShadowDD; - pScreenPriv->pwinInitVisuals = winInitVisualsShadowDD; - pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowDD; - if (pScreenInfo->fFullScreen) - pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen; - else - pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed; - pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB; - pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowDD; - pScreenPriv->pwinActivateApp = winActivateAppShadowDD; - pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowDD; - pScreenPriv->pwinRealizeInstalledPalette - = winRealizeInstalledPaletteShadowDD; - pScreenPriv->pwinInstallColormap = winInstallColormapShadowDD; - pScreenPriv->pwinStoreColors = winStoreColorsShadowDD; - pScreenPriv->pwinCreateColormap = winCreateColormapShadowDD; - pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowDD; - pScreenPriv->pwinHotKeyAltTab = (winHotKeyAltTabProcPtr) (void (*)(void))NoopDDA; - pScreenPriv->pwinCreatePrimarySurface = winCreatePrimarySurfaceShadowDD; - pScreenPriv->pwinReleasePrimarySurface = winReleasePrimarySurfaceShadowDD; -#ifdef XWIN_MULTIWINDOW - pScreenPriv->pwinFinishCreateWindowsWindow = - (winFinishCreateWindowsWindowProcPtr) (void (*)(void))NoopDDA; -#endif - - return TRUE; -} +/*
+ *Copyright (C) 1994-2000 The XFree86 Project, 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, sublicense, and/or sell copies of the Software, and to
+ *permit persons to whom the Software is furnished to do so, subject to
+ *the following conditions:
+ *
+ *The above copyright notice and this permission notice shall be
+ *included in all copies or substantial portions of the Software.
+ *
+ *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. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
+ *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *Except as contained in this notice, the name of the XFree86 Project
+ *shall not be used in advertising or otherwise to promote the sale, use
+ *or other dealings in this Software without prior written authorization
+ *from the XFree86 Project.
+ *
+ * Authors: Dakshinamurthy Karra
+ * Suhaib M Siddiqi
+ * Peter Busch
+ * Harold L Hunt II
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+
+
+/*
+ * External symbols
+ */
+
+extern HWND g_hDlgExit;
+extern const char *g_pszLogFile;
+
+
+
+/*
+ * Local prototypes
+ */
+
+static Bool
+winAllocateFBShadowDD (ScreenPtr pScreen);
+
+static void
+winShadowUpdateDD (ScreenPtr pScreen,
+ shadowBufPtr pBuf);
+
+static Bool
+winCloseScreenShadowDD (int nIndex, ScreenPtr pScreen);
+
+static Bool
+winInitVisualsShadowDD (ScreenPtr pScreen);
+
+static Bool
+winAdjustVideoModeShadowDD (ScreenPtr pScreen);
+
+static Bool
+winBltExposedRegionsShadowDD (ScreenPtr pScreen);
+
+static Bool
+winActivateAppShadowDD (ScreenPtr pScreen);
+
+static Bool
+winRedrawScreenShadowDD (ScreenPtr pScreen);
+
+static Bool
+winRealizeInstalledPaletteShadowDD (ScreenPtr pScreen);
+
+static Bool
+winInstallColormapShadowDD (ColormapPtr pColormap);
+
+static Bool
+winStoreColorsShadowDD (ColormapPtr pmap,
+ int ndef,
+ xColorItem *pdefs);
+
+static Bool
+winCreateColormapShadowDD (ColormapPtr pColormap);
+
+static Bool
+winDestroyColormapShadowDD (ColormapPtr pColormap);
+
+static Bool
+winCreatePrimarySurfaceShadowDD (ScreenPtr pScreen);
+
+static Bool
+winReleasePrimarySurfaceShadowDD (ScreenPtr pScreen);
+
+
+/*
+ * Create the primary surface and attach the clipper.
+ * Used for both the initial surface creation and during
+ * WM_DISPLAYCHANGE messages.
+ */
+
+static Bool
+winCreatePrimarySurfaceShadowDD (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ HRESULT ddrval = DD_OK;
+ DDSURFACEDESC ddsd;
+
+ /* Describe the primary surface */
+ ZeroMemory (&ddsd, sizeof (ddsd));
+ ddsd.dwSize = sizeof (ddsd);
+ ddsd.dwFlags = DDSD_CAPS;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+
+ /* Create the primary surface */
+ ddrval = IDirectDraw2_CreateSurface (pScreenPriv->pdd2,
+ &ddsd,
+ &pScreenPriv->pddsPrimary,
+ NULL);
+ if (FAILED (ddrval))
+ {
+ ErrorF ("winCreatePrimarySurfaceShadowDD - Could not create primary "
+ "surface: %08x\n", (unsigned int) ddrval);
+ return FALSE;
+ }
+
+ winDebug ("winCreatePrimarySurfaceShadowDD - Created primary surface\n");
+
+ /*
+ * Attach a clipper to the primary surface that will clip our blits to our
+ * display window.
+ */
+ ddrval = IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary,
+ pScreenPriv->pddcPrimary);
+ if (FAILED (ddrval))
+ {
+ ErrorF ("winCreatePrimarySurfaceShadowDD - Primary attach clipper "
+ "failed: %08x\n",
+ (unsigned int) ddrval);
+ return FALSE;
+ }
+
+ winDebug ("winCreatePrimarySurfaceShadowDD - Attached clipper to "
+ "primary surface\n");
+
+ /* Everything was correct */
+ return TRUE;
+}
+
+
+/*
+ * Detach the clipper and release the primary surface.
+ * Called from WM_DISPLAYCHANGE.
+ */
+
+static Bool
+winReleasePrimarySurfaceShadowDD (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+
+ winDebug ("winReleasePrimarySurfaceShadowDD - Hello\n");
+
+ /* Release the primary surface and clipper, if they exist */
+ if (pScreenPriv->pddsPrimary)
+ {
+ /*
+ * Detach the clipper from the primary surface.
+ * NOTE: We do this explicity for clarity. The Clipper is not released.
+ */
+ IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary,
+ NULL);
+
+ winDebug ("winReleasePrimarySurfaceShadowDD - Detached clipper\n");
+
+ /* Release the primary surface */
+ IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary);
+ pScreenPriv->pddsPrimary = NULL;
+ }
+
+ winDebug ("winReleasePrimarySurfaceShadowDD - Released primary surface\n");
+
+ return TRUE;
+}
+
+
+/*
+ * Create a DirectDraw surface for the shadow framebuffer; also create
+ * a primary surface object so we can blit to the display.
+ *
+ * Install a DirectDraw clipper on our primary surface object
+ * that clips our blits to the unobscured client area of our display window.
+ */
+
+static Bool
+winAllocateFBShadowDD (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+ HRESULT ddrval = DD_OK;
+ DDSURFACEDESC ddsd;
+ DDSURFACEDESC *pddsdShadow = NULL;
+
+ winDebug ("winAllocateFBShadowDD\n");
+
+ /* Create a clipper */
+ ddrval = (*g_fpDirectDrawCreateClipper) (0,
+ &pScreenPriv->pddcPrimary,
+ NULL);
+ if (FAILED (ddrval))
+ {
+ ErrorF ("winAllocateFBShadowDD - Could not create clipper: %08x\n",
+ (unsigned int) ddrval);
+ return FALSE;
+ }
+
+ winDebug ("winAllocateFBShadowDD - Created a clipper\n");
+
+ /* Get a device context for the screen */
+ pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
+
+ /* Attach the clipper to our display window */
+ ddrval = IDirectDrawClipper_SetHWnd (pScreenPriv->pddcPrimary,
+ 0,
+ pScreenPriv->hwndScreen);
+ if (FAILED (ddrval))
+ {
+ ErrorF ("winAllocateFBShadowDD - Clipper not attached to "
+ "window: %08x\n",
+ (unsigned int) ddrval);
+ return FALSE;
+ }
+
+ winDebug ("winAllocateFBShadowDD - Attached clipper to window\n");
+
+ /* Create a DirectDraw object, store the address at lpdd */
+ ddrval = (*g_fpDirectDrawCreate) (NULL, &pScreenPriv->pdd, NULL);
+ if (FAILED (ddrval))
+ {
+ ErrorF ("winAllocateFBShadowDD - Could not start DirectDraw: %08x\n",
+ (unsigned int) ddrval);
+ return FALSE;
+ }
+
+ winDebug ("winAllocateFBShadowDD () - Created and initialized DD\n");
+
+ /* Get a DirectDraw2 interface pointer */
+ ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd,
+ &IID_IDirectDraw2,
+ (LPVOID*) &pScreenPriv->pdd2);
+ if (FAILED (ddrval))
+ {
+ ErrorF ("winAllocateFBShadowDD - Failed DD2 query: %08x\n",
+ (unsigned int) ddrval);
+ return FALSE;
+ }
+
+ /* Are we full screen? */
+ if (pScreenInfo->fFullScreen)
+ {
+ DDSURFACEDESC ddsdCurrent;
+ DWORD dwRefreshRateCurrent = 0;
+ HDC hdc = NULL;
+
+ /* Set the cooperative level to full screen */
+ ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2,
+ pScreenPriv->hwndScreen,
+ DDSCL_EXCLUSIVE
+ | DDSCL_FULLSCREEN);
+ if (FAILED (ddrval))
+ {
+ ErrorF ("winAllocateFBShadowDD - Could not set "
+ "cooperative level: %08x\n",
+ (unsigned int) ddrval);
+ return FALSE;
+ }
+
+ /*
+ * We only need to get the current refresh rate for comparison
+ * if a refresh rate has been passed on the command line.
+ */
+ if (pScreenInfo->dwRefreshRate != 0)
+ {
+ ZeroMemory (&ddsdCurrent, sizeof (ddsdCurrent));
+ ddsdCurrent.dwSize = sizeof (ddsdCurrent);
+
+ /* Get information about current display settings */
+ ddrval = IDirectDraw2_GetDisplayMode (pScreenPriv->pdd2,
+ &ddsdCurrent);
+ if (FAILED (ddrval))
+ {
+ ErrorF ("winAllocateFBShadowDD - Could not get current "
+ "refresh rate: %08x. Continuing.\n",
+ (unsigned int) ddrval);
+ dwRefreshRateCurrent = 0;
+ }
+ else
+ {
+ /* Grab the current refresh rate */
+ dwRefreshRateCurrent = ddsdCurrent.u2.dwRefreshRate;
+ }
+ }
+
+ /* Clean up the refresh rate */
+ if (dwRefreshRateCurrent == pScreenInfo->dwRefreshRate)
+ {
+ /*
+ * Refresh rate is non-specified or equal to current.
+ */
+ pScreenInfo->dwRefreshRate = 0;
+ }
+
+ /* Grab a device context for the screen */
+ hdc = GetDC (NULL);
+ if (hdc == NULL)
+ {
+ ErrorF ("winAllocateFBShadowDD - GetDC () failed\n");
+ return FALSE;
+ }
+
+ /* Only change the video mode when different than current mode */
+ if (!pScreenInfo->fMultipleMonitors
+ && (pScreenInfo->dwWidth != GetSystemMetrics (SM_CXSCREEN)
+ || pScreenInfo->dwHeight != GetSystemMetrics (SM_CYSCREEN)
+ || pScreenInfo->dwBPP != GetDeviceCaps (hdc, BITSPIXEL)
+ || pScreenInfo->dwRefreshRate != 0))
+ {
+ winDebug ("winAllocateFBShadowDD - Changing video mode\n");
+
+ /* Change the video mode to the mode requested, and use the driver default refresh rate on failure */
+ ddrval = IDirectDraw2_SetDisplayMode (pScreenPriv->pdd2,
+ pScreenInfo->dwWidth,
+ pScreenInfo->dwHeight,
+ pScreenInfo->dwBPP,
+ pScreenInfo->dwRefreshRate,
+ 0);
+ if (FAILED (ddrval))
+ {
+ ErrorF ("winAllocateFBShadowDD - Could not set "\
+ "full screen display mode: %08x\n",
+ (unsigned int) ddrval);
+ ErrorF ("winAllocateFBShadowDD - Using default driver refresh rate\n");
+ ddrval = IDirectDraw2_SetDisplayMode (pScreenPriv->pdd2,
+ pScreenInfo->dwWidth,
+ pScreenInfo->dwHeight,
+ pScreenInfo->dwBPP,
+ 0,
+ 0);
+ if (FAILED(ddrval))
+ {
+ ErrorF ("winAllocateFBShadowDD - Could not set default refresh rate "
+ "full screen display mode: %08x\n",
+ (unsigned int) ddrval);
+ return FALSE;
+ }
+ }
+ }
+ else
+ {
+ winDebug ("winAllocateFBShadowDD - Not changing video mode\n");
+ }
+
+ /* Release our DC */
+ ReleaseDC (NULL, hdc);
+ hdc = NULL;
+ }
+ else
+ {
+ /* Set the cooperative level for windowed mode */
+ ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2,
+ pScreenPriv->hwndScreen,
+ DDSCL_NORMAL);
+ if (FAILED (ddrval))
+ {
+ ErrorF ("winAllocateFBShadowDD - Could not set "\
+ "cooperative level: %08x\n",
+ (unsigned int) ddrval);
+ return FALSE;
+ }
+ }
+
+ /* Create the primary surface */
+ if (!winCreatePrimarySurfaceShadowDD (pScreen))
+ {
+ ErrorF ("winAllocateFBShadowDD - winCreatePrimarySurfaceShadowDD "
+ "failed\n");
+ return FALSE;
+ }
+
+ /* Describe the shadow surface to be created */
+ /* NOTE: Do not use a DDSCAPS_VIDEOMEMORY surface,
+ * as drawing, locking, and unlocking take forever
+ * with video memory surfaces. In addition,
+ * video memory is a somewhat scarce resource,
+ * so you shouldn't be allocating video memory when
+ * you have the option of using system memory instead.
+ */
+ ZeroMemory (&ddsd, sizeof (ddsd));
+ ddsd.dwSize = sizeof (ddsd);
+ ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
+ ddsd.dwHeight = pScreenInfo->dwHeight;
+ ddsd.dwWidth = pScreenInfo->dwWidth;
+
+ /* Create the shadow surface */
+ ddrval = IDirectDraw2_CreateSurface (pScreenPriv->pdd2,
+ &ddsd,
+ &pScreenPriv->pddsShadow,
+ NULL);
+ if (FAILED (ddrval))
+ {
+ ErrorF ("winAllocateFBShadowDD - Could not create shadow "\
+ "surface: %08x\n", (unsigned int) ddrval);
+ return FALSE;
+ }
+
+ winDebug ("winAllocateFBShadowDD - Created shadow\n");
+
+ /* Allocate a DD surface description for our screen privates */
+ pddsdShadow = pScreenPriv->pddsdShadow = malloc (sizeof (DDSURFACEDESC));
+ if (pddsdShadow == NULL)
+ {
+ ErrorF ("winAllocateFBShadowDD - Could not allocate surface "\
+ "description memory\n");
+ return FALSE;
+ }
+ ZeroMemory (pddsdShadow, sizeof (*pddsdShadow));
+ pddsdShadow->dwSize = sizeof (*pddsdShadow);
+
+ winDebug ("winAllocateFBShadowDD - Locking shadow\n");
+
+ /* Lock the shadow surface */
+ ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow,
+ NULL,
+ pddsdShadow,
+ DDLOCK_WAIT,
+ NULL);
+ if (FAILED (ddrval) || pddsdShadow->lpSurface == NULL)
+ {
+ ErrorF ("winAllocateFBShadowDD - Could not lock shadow "\
+ "surface: %08x\n", (unsigned int) ddrval);
+ return FALSE;
+ }
+
+ winDebug ("winAllocateFBShadowDD - Locked shadow\n");
+
+ /* We don't know how to deal with anything other than RGB */
+ if (!(pddsdShadow->ddpfPixelFormat.dwFlags & DDPF_RGB))
+ {
+ ErrorF ("winAllocateFBShadowDD - Color format other than RGB\n");
+ return FALSE;
+ }
+
+ /* Grab the pitch from the surface desc */
+ pScreenInfo->dwStride = (pddsdShadow->u1.lPitch * 8)
+ / pScreenInfo->dwBPP;
+
+ /* Save the pointer to our surface memory */
+ pScreenInfo->pfb = pddsdShadow->lpSurface;
+
+ /* Grab the color depth and masks from the surface description */
+ pScreenPriv->dwRedMask = pddsdShadow->ddpfPixelFormat.u2.dwRBitMask;
+ pScreenPriv->dwGreenMask = pddsdShadow->ddpfPixelFormat.u3.dwGBitMask;
+ pScreenPriv->dwBlueMask = pddsdShadow->ddpfPixelFormat.u4.dwBBitMask;
+
+ winDebug ("winAllocateFBShadowDD - Returning\n");
+
+ return TRUE;
+}
+
+
+/*
+ * Transfer the damaged regions of the shadow framebuffer to the display.
+ */
+
+static void
+winShadowUpdateDD (ScreenPtr pScreen,
+ shadowBufPtr pBuf)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+ RegionPtr damage = shadowDamage(pBuf);
+ HRESULT ddrval = DD_OK;
+ RECT rcDest, rcSrc;
+ POINT ptOrigin;
+ DWORD dwBox = RegionNumRects (damage);
+ BoxPtr pBox = RegionRects (damage);
+ HRGN hrgnTemp = NULL, hrgnCombined = NULL;
+
+ /*
+ * Return immediately if the app is not active
+ * and we are fullscreen, or if we have a bad display depth
+ */
+ if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen)
+ || pScreenPriv->fBadDepth) return;
+
+ /* Get the origin of the window in the screen coords */
+ ptOrigin.x = pScreenInfo->dwXOffset;
+ ptOrigin.y = pScreenInfo->dwYOffset;
+ MapWindowPoints (pScreenPriv->hwndScreen,
+ HWND_DESKTOP,
+ (LPPOINT)&ptOrigin, 1);
+
+ /* Unlock the shadow surface, so we can blit */
+ ddrval = IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL);
+ if (FAILED (ddrval))
+ {
+ ErrorF ("winShadowUpdateDD - Unlock failed\n");
+ return;
+ }
+
+ /*
+ * Handle small regions with multiple blits,
+ * handle large regions by creating a clipping region and
+ * doing a single blit constrained to that clipping region.
+ */
+ if (pScreenInfo->dwClipUpdatesNBoxes == 0
+ || dwBox < pScreenInfo->dwClipUpdatesNBoxes)
+ {
+ /* Loop through all boxes in the damaged region */
+ while (dwBox--)
+ {
+ /* Assign damage box to source rectangle */
+ rcSrc.left = pBox->x1;
+ rcSrc.top = pBox->y1;
+ rcSrc.right = pBox->x2;
+ rcSrc.bottom = pBox->y2;
+
+ /* Calculate destination rectange */
+ rcDest.left = ptOrigin.x + rcSrc.left;
+ rcDest.top = ptOrigin.y + rcSrc.top;
+ rcDest.right = ptOrigin.x + rcSrc.right;
+ rcDest.bottom = ptOrigin.y + rcSrc.bottom;
+
+ /* Blit the damaged areas */
+ ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary,
+ &rcDest,
+ pScreenPriv->pddsShadow,
+ &rcSrc,
+ DDBLT_WAIT,
+ NULL);
+
+ /* Get a pointer to the next box */
+ ++pBox;
+ }
+ }
+ else
+ {
+ BoxPtr pBoxExtents = RegionExtents(damage);
+
+ /* Compute a GDI region from the damaged region */
+ hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
+ dwBox--;
+ pBox++;
+ while (dwBox--)
+ {
+ hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
+ CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR);
+ DeleteObject (hrgnTemp);
+ pBox++;
+ }
+
+ /* Install the GDI region as a clipping region */
+ SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined);
+ DeleteObject (hrgnCombined);
+ hrgnCombined = NULL;
+
+ /* Calculating a bounding box for the source is easy */
+ rcSrc.left = pBoxExtents->x1;
+ rcSrc.top = pBoxExtents->y1;
+ rcSrc.right = pBoxExtents->x2;
+ rcSrc.bottom = pBoxExtents->y2;
+
+ /* Calculating a bounding box for the destination is trickier */
+ rcDest.left = ptOrigin.x + rcSrc.left;
+ rcDest.top = ptOrigin.y + rcSrc.top;
+ rcDest.right = ptOrigin.x + rcSrc.right;
+ rcDest.bottom = ptOrigin.y + rcSrc.bottom;
+
+ /* Our Blt should be clipped to the invalidated region */
+ ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary,
+ &rcDest,
+ pScreenPriv->pddsShadow,
+ &rcSrc,
+ DDBLT_WAIT,
+ NULL);
+
+ /* Reset the clip region */
+ SelectClipRgn (pScreenPriv->hdcScreen, NULL);
+ }
+
+ /* Relock the shadow surface */
+ ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow,
+ NULL,
+ pScreenPriv->pddsdShadow,
+ DDLOCK_WAIT,
+ NULL);
+ if (FAILED (ddrval))
+ {
+ ErrorF ("winShadowUpdateDD - Lock failed\n");
+ return;
+ }
+
+ /* Has our memory pointer changed? */
+ if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface)
+ {
+ extern const char *g_pszLogFile;
+ ErrorF ("winShadowUpdateDD - Memory location of the shadow "
+ "surface has changed, trying to update the root window "
+ "pixmap header to point to the new address. If you get "
+ "this message and "PROJECT_NAME" freezes or crashes "
+ "after this message then send a problem report and your "
+ "%s file to " BUILDERADDR "\n", g_pszLogFile);
+
+ /* Location of shadow framebuffer has changed */
+ pScreenInfo->pfb = pScreenPriv->pddsdShadow->lpSurface;
+
+ /* Update the screen pixmap */
+ if (!(*pScreen->ModifyPixmapHeader)(pScreen->devPrivate,
+ pScreen->width,
+ pScreen->height,
+ pScreen->rootDepth,
+ BitsPerPixel (pScreen->rootDepth),
+ PixmapBytePad (pScreenInfo->dwStride,
+ pScreenInfo->dwBPP),
+ pScreenInfo->pfb))
+ {
+ ErrorF ("winShadowUpdateDD - Bits changed, could not "
+ "notify fb.\n");
+ return;
+ }
+ }
+}
+
+
+/*
+ * Call the wrapped CloseScreen function.
+ *
+ * Free our resources and private structures.
+ */
+
+static Bool
+winCloseScreenShadowDD (int nIndex, ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+ Bool fReturn;
+
+ winDebug ("winCloseScreenShadowDD - Freeing screen resources\n");
+
+ /* Flag that the screen is closed */
+ pScreenPriv->fClosed = TRUE;
+ pScreenPriv->fActive = FALSE;
+
+ /* Call the wrapped CloseScreen procedure */
+ WIN_UNWRAP(CloseScreen);
+ fReturn = (*pScreen->CloseScreen) (nIndex, pScreen);
+
+ /* Free the screen DC */
+ ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen);
+
+ /* Delete the window property */
+ RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP);
+
+ /* Free the shadow surface, if there is one */
+ if (pScreenPriv->pddsShadow)
+ {
+ IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL);
+ IDirectDrawSurface2_Release (pScreenPriv->pddsShadow);
+ pScreenPriv->pddsShadow = NULL;
+ }
+
+ /* Detach the clipper from the primary surface and release the clipper. */
+ if (pScreenPriv->pddcPrimary)
+ {
+ /* Detach the clipper */
+ IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary,
+ NULL);
+
+ /* Release the clipper object */
+ IDirectDrawClipper_Release (pScreenPriv->pddcPrimary);
+ pScreenPriv->pddcPrimary = NULL;
+ }
+
+ /* Release the primary surface, if there is one */
+ if (pScreenPriv->pddsPrimary)
+ {
+ IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary);
+ pScreenPriv->pddsPrimary = NULL;
+ }
+
+ /* Free the DirectDraw2 object, if there is one */
+ if (pScreenPriv->pdd2)
+ {
+ IDirectDraw2_RestoreDisplayMode (pScreenPriv->pdd2);
+ IDirectDraw2_Release (pScreenPriv->pdd2);
+ pScreenPriv->pdd2 = NULL;
+ }
+
+ /* Free the DirectDraw object, if there is one */
+ if (pScreenPriv->pdd)
+ {
+ IDirectDraw_Release (pScreenPriv->pdd);
+ pScreenPriv->pdd = NULL;
+ }
+
+ /* Delete tray icon, if we have one */
+ if (!pScreenInfo->fNoTrayIcon)
+ winDeleteNotifyIcon (pScreenPriv);
+
+ /* Free the exit confirmation dialog box, if it exists */
+ if (g_hDlgExit != NULL)
+ {
+ DestroyWindow (g_hDlgExit);
+ g_hDlgExit = NULL;
+ }
+
+ /* Kill our window */
+ if (pScreenPriv->hwndScreen)
+ {
+ DestroyWindow (pScreenPriv->hwndScreen);
+ pScreenPriv->hwndScreen = NULL;
+ }
+
+#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
+ /* Destroy the thread startup mutex */
+ pthread_mutex_destroy (&pScreenPriv->pmServerStarted);
+#endif
+
+ /* Kill our screeninfo's pointer to the screen */
+ pScreenInfo->pScreen = NULL;
+
+ /* Invalidate the ScreenInfo's fb pointer */
+ pScreenInfo->pfb = NULL;
+
+ /* Free the screen privates for this screen */
+ free ((pointer) pScreenPriv);
+
+ return fReturn;
+}
+
+
+/*
+ * Tell mi what sort of visuals we need.
+ *
+ * Generally we only need one visual, as our screen can only
+ * handle one format at a time, I believe. You may want
+ * to verify that last sentence.
+ */
+
+static Bool
+winInitVisualsShadowDD (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+ DWORD dwRedBits, dwGreenBits, dwBlueBits;
+
+ /* Count the number of ones in each color mask */
+ dwRedBits = winCountBits (pScreenPriv->dwRedMask);
+ dwGreenBits = winCountBits (pScreenPriv->dwGreenMask);
+ dwBlueBits = winCountBits (pScreenPriv->dwBlueMask);
+
+ /* Store the maximum number of ones in a color mask as the bitsPerRGB */
+ if (dwRedBits == 0 || dwGreenBits == 0 || dwBlueBits == 0)
+ pScreenPriv->dwBitsPerRGB = 8;
+ else if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits)
+ pScreenPriv->dwBitsPerRGB = dwRedBits;
+ else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits)
+ pScreenPriv->dwBitsPerRGB = dwGreenBits;
+ else
+ pScreenPriv->dwBitsPerRGB = dwBlueBits;
+
+ winDebug ("winInitVisualsShadowDD - Masks %08x %08x %08x BPRGB %d d %d "
+ "bpp %d\n",
+ (unsigned int) pScreenPriv->dwRedMask,
+ (unsigned int) pScreenPriv->dwGreenMask,
+ (unsigned int) pScreenPriv->dwBlueMask,
+ (int) pScreenPriv->dwBitsPerRGB,
+ (int) pScreenInfo->dwDepth,
+ (int) pScreenInfo->dwBPP);
+
+ /* Create a single visual according to the Windows screen depth */
+ switch (pScreenInfo->dwDepth)
+ {
+ case 24:
+ case 16:
+ case 15:
+#if defined(XFree86Server)
+ /* Create the real visual */
+ if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth,
+ TrueColorMask,
+ pScreenPriv->dwBitsPerRGB,
+ TrueColor,
+ pScreenPriv->dwRedMask,
+ pScreenPriv->dwGreenMask,
+ pScreenPriv->dwBlueMask))
+ {
+ ErrorF ("winInitVisualsShadowDD - miSetVisualTypesAndMasks "
+ "failed for TrueColor\n");
+ return FALSE;
+ }
+
+#ifdef XWIN_EMULATEPSEUDO
+ if (!pScreenInfo->fEmulatePseudo)
+ break;
+
+ /* Setup a pseudocolor visual */
+ if (!miSetVisualTypesAndMasks (8,
+ PseudoColorMask,
+ 8,
+ -1,
+ 0,
+ 0,
+ 0))
+ {
+ ErrorF ("winInitVisualsShadowDD - miSetVisualTypesAndMasks "
+ "failed for PseudoColor\n");
+ return FALSE;
+ }
+#endif
+#else /* XFree86Server */
+ /* Create the real visual */
+ if (!fbSetVisualTypesAndMasks (pScreenInfo->dwDepth,
+ TrueColorMask,
+ pScreenPriv->dwBitsPerRGB,
+ pScreenPriv->dwRedMask,
+ pScreenPriv->dwGreenMask,
+ pScreenPriv->dwBlueMask))
+ {
+ ErrorF ("winInitVisualsShadowDD - fbSetVisualTypesAndMasks "
+ "failed for TrueColor\n");
+ return FALSE;
+ }
+
+#ifdef XWIN_EMULATEPSEUDO
+ if (!pScreenInfo->fEmulatePseudo)
+ break;
+
+ /* Setup a pseudocolor visual */
+ if (!fbSetVisualTypesAndMasks (8,
+ PseudoColorMask,
+ 8,
+ 0,
+ 0,
+ 0))
+ {
+ ErrorF ("winInitVisualsShadowDD - fbSetVisualTypesAndMasks "
+ "failed for PseudoColor\n");
+ return FALSE;
+ }
+#endif
+#endif /* XFree86Server */
+ break;
+
+ case 8:
+#if defined(XFree86Server)
+ if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth,
+ pScreenInfo->fFullScreen
+ ? PseudoColorMask : StaticColorMask,
+ pScreenPriv->dwBitsPerRGB,
+ pScreenInfo->fFullScreen
+ ? PseudoColor : StaticColor,
+ pScreenPriv->dwRedMask,
+ pScreenPriv->dwGreenMask,
+ pScreenPriv->dwBlueMask))
+ {
+ ErrorF ("winInitVisualsShadowDD - miSetVisualTypesAndMasks "
+ "failed\n");
+ return FALSE;
+ }
+#else /* XFree86Server */
+ if (!fbSetVisualTypesAndMasks (pScreenInfo->dwDepth,
+ pScreenInfo->fFullScreen
+ ? PseudoColorMask : StaticColorMask,
+ pScreenPriv->dwBitsPerRGB,
+ pScreenPriv->dwRedMask,
+ pScreenPriv->dwGreenMask,
+ pScreenPriv->dwBlueMask))
+ {
+ ErrorF ("winInitVisualsShadowDD - fbSetVisualTypesAndMasks "
+ "failed\n");
+ return FALSE;
+ }
+#endif /* XFree86Server */
+ break;
+
+ default:
+ ErrorF ("winInitVisualsShadowDD - Unknown screen depth\n");
+ return FALSE;
+ }
+
+ winDebug ("winInitVisualsShadowDD - Returning\n");
+
+ return TRUE;
+}
+
+
+/*
+ * Adjust the user proposed video mode
+ */
+
+static Bool
+winAdjustVideoModeShadowDD (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+ HDC hdc = NULL;
+ DWORD dwBPP;
+
+ /* We're in serious trouble if we can't get a DC */
+ hdc = GetDC (NULL);
+ if (hdc == NULL)
+ {
+ ErrorF ("winAdjustVideoModeShadowDD - GetDC () failed\n");
+ return FALSE;
+ }
+
+ /* Query GDI for current display depth */
+ dwBPP = GetDeviceCaps (hdc, BITSPIXEL);
+
+ /* DirectDraw can only change the depth in fullscreen mode */
+ if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP)
+ {
+ /* No -depth parameter passed, let the user know the depth being used */
+ winDebug ("winAdjustVideoModeShadowDD - Using Windows display "
+ "depth of %d bits per pixel\n", (int) dwBPP);
+
+ /* Use GDI's depth */
+ pScreenInfo->dwBPP = dwBPP;
+ }
+ else if (pScreenInfo->fFullScreen
+ && pScreenInfo->dwBPP != dwBPP)
+ {
+ /* FullScreen, and GDI depth differs from -depth parameter */
+ winDebug ("winAdjustVideoModeShadowDD - FullScreen, using command line "
+ "bpp: %d\n", (int) pScreenInfo->dwBPP);
+ }
+ else if (dwBPP != pScreenInfo->dwBPP)
+ {
+ /* Windowed, and GDI depth differs from -depth parameter */
+ winDebug ("winAdjustVideoModeShadowDD - Windowed, command line bpp: "
+ "%d, using bpp: %d\n", (int) pScreenInfo->dwBPP, (int) dwBPP);
+
+ /* We'll use GDI's depth */
+ pScreenInfo->dwBPP = dwBPP;
+ }
+
+ /* See if the shadow bitmap will be larger than the DIB size limit */
+ if (pScreenInfo->dwWidth * pScreenInfo->dwHeight * pScreenInfo->dwBPP
+ >= WIN_DIB_MAXIMUM_SIZE)
+ {
+ ErrorF ("winAdjustVideoModeShadowDD - Requested DirectDraw surface "
+ "will be larger than %d MB. The surface may fail to be "
+ "allocated on Windows 95, 98, or Me, due to a %d MB limit in "
+ "DIB size. This limit does not apply to Windows NT/2000, and "
+ "this message may be ignored on those platforms.\n",
+ WIN_DIB_MAXIMUM_SIZE_MB, WIN_DIB_MAXIMUM_SIZE_MB);
+ }
+
+ /* Release our DC */
+ ReleaseDC (NULL, hdc);
+ return TRUE;
+}
+
+
+/*
+ * Blt exposed regions to the screen
+ */
+
+static Bool
+winBltExposedRegionsShadowDD (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+ RECT rcSrc, rcDest;
+ POINT ptOrigin;
+ HDC hdcUpdate = NULL;
+ PAINTSTRUCT ps;
+ HRESULT ddrval = DD_OK;
+ Bool fReturn = TRUE;
+ Bool fLocked = TRUE;
+ int i;
+
+ /* BeginPaint gives us an hdc that clips to the invalidated region */
+ hdcUpdate = BeginPaint (pScreenPriv->hwndScreen, &ps);
+ if (hdcUpdate == NULL)
+ {
+ ErrorF ("winBltExposedRegionsShadowDD - BeginPaint () returned "
+ "a NULL device context handle. Aborting blit attempt.\n");
+ return FALSE;
+ }
+
+ /* Unlock the shadow surface, so we can blit */
+ ddrval = IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL);
+ if (FAILED (ddrval))
+ {
+ fReturn = FALSE;
+ goto winBltExposedRegionsShadowDD_Exit;
+ }
+ else
+ {
+ /* Flag that we have unlocked the shadow surface */
+ fLocked = FALSE;
+ }
+
+ /* Get the origin of the window in the screen coords */
+ ptOrigin.x = pScreenInfo->dwXOffset;
+ ptOrigin.y = pScreenInfo->dwYOffset;
+
+ MapWindowPoints (pScreenPriv->hwndScreen,
+ HWND_DESKTOP,
+ (LPPOINT)&ptOrigin, 1);
+ rcDest.left = ptOrigin.x;
+ rcDest.right = ptOrigin.x + pScreenInfo->dwWidth;
+ rcDest.top = ptOrigin.y;
+ rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight;
+
+ /* Source can be enter shadow surface, as Blt should clip */
+ rcSrc.left = 0;
+ rcSrc.top = 0;
+ rcSrc.right = pScreenInfo->dwWidth;
+ rcSrc.bottom = pScreenInfo->dwHeight;
+
+ /* Try to regain the primary surface and blit again if we've lost it */
+ for (i = 0; i <= WIN_REGAIN_SURFACE_RETRIES; ++i)
+ {
+ /* Our Blt should be clipped to the invalidated region */
+ ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary,
+ &rcDest,
+ pScreenPriv->pddsShadow,
+ &rcSrc,
+ DDBLT_WAIT,
+ NULL);
+ if (ddrval == DDERR_SURFACELOST)
+ {
+ /* Surface was lost */
+ ErrorF ("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Blt "
+ "reported that the primary surface was lost, "
+ "trying to restore, retry: %d\n", i + 1);
+
+ /* Try to restore the surface, once */
+ ddrval = IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary);
+ ErrorF ("winBltExposedRegionsShadowDD - "
+ "IDirectDrawSurface2_Restore returned: ");
+ if (ddrval == DD_OK)
+ ErrorF ("DD_OK\n");
+ else if (ddrval == DDERR_WRONGMODE)
+ ErrorF ("DDERR_WRONGMODE\n");
+ else if (ddrval == DDERR_INCOMPATIBLEPRIMARY)
+ ErrorF ("DDERR_INCOMPATIBLEPRIMARY\n");
+ else if (ddrval == DDERR_UNSUPPORTED)
+ ErrorF ("DDERR_UNSUPPORTED\n");
+ else if (ddrval == DDERR_INVALIDPARAMS)
+ ErrorF ("DDERR_INVALIDPARAMS\n");
+ else if (ddrval == DDERR_INVALIDOBJECT)
+ ErrorF ("DDERR_INVALIDOBJECT\n");
+ else
+ ErrorF ("unknown error: %08x\n", (unsigned int) ddrval);
+
+ /* Loop around to try the blit one more time */
+ continue;
+ }
+ else if (FAILED (ddrval))
+ {
+ fReturn = FALSE;
+ ErrorF ("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Blt "
+ "failed, but surface not lost: %08x %d\n",
+ (unsigned int) ddrval, (int) ddrval);
+ goto winBltExposedRegionsShadowDD_Exit;
+ }
+ else
+ {
+ /* Success, stop looping */
+ break;
+ }
+ }
+
+ /* Relock the shadow surface */
+ ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow,
+ NULL,
+ pScreenPriv->pddsdShadow,
+ DDLOCK_WAIT,
+ NULL);
+ if (FAILED (ddrval))
+ {
+ fReturn = FALSE;
+ ErrorF ("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Lock "
+ "failed\n");
+ goto winBltExposedRegionsShadowDD_Exit;
+ }
+ else
+ {
+ /* Indicate that we have relocked the shadow surface */
+ fLocked = TRUE;
+ }
+
+ /* Has our memory pointer changed? */
+ if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface)
+ winUpdateFBPointer (pScreen,
+ pScreenPriv->pddsdShadow->lpSurface);
+
+ winBltExposedRegionsShadowDD_Exit:
+ /* EndPaint frees the DC */
+ if (hdcUpdate != NULL)
+ EndPaint (pScreenPriv->hwndScreen, &ps);
+
+ /*
+ * Relock the surface if it is not locked. We don't care if locking fails,
+ * as it will cause the server to shutdown within a few more operations.
+ */
+ if (!fLocked)
+ {
+ IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow,
+ NULL,
+ pScreenPriv->pddsdShadow,
+ DDLOCK_WAIT,
+ NULL);
+
+ /* Has our memory pointer changed? */
+ if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface)
+ winUpdateFBPointer (pScreen,
+ pScreenPriv->pddsdShadow->lpSurface);
+
+ fLocked = TRUE;
+ }
+ return fReturn;
+}
+
+
+/*
+ * Do any engine-specific appliation-activation processing
+ */
+
+static Bool
+winActivateAppShadowDD (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+
+ /*
+ * Do we have a surface?
+ * Are we active?
+ * Are we fullscreen?
+ */
+ if (pScreenPriv != NULL
+ && pScreenPriv->pddsPrimary != NULL
+ && pScreenPriv->fActive)
+ {
+ /* Primary surface was lost, restore it */
+ IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary);
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Reblit the shadow framebuffer to the screen.
+ */
+
+static Bool
+winRedrawScreenShadowDD (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+ HRESULT ddrval = DD_OK;
+ RECT rcSrc, rcDest;
+ POINT ptOrigin;
+
+ /* Get the origin of the window in the screen coords */
+ ptOrigin.x = pScreenInfo->dwXOffset;
+ ptOrigin.y = pScreenInfo->dwYOffset;
+ MapWindowPoints (pScreenPriv->hwndScreen,
+ HWND_DESKTOP,
+ (LPPOINT)&ptOrigin, 1);
+ rcDest.left = ptOrigin.x;
+ rcDest.right = ptOrigin.x + pScreenInfo->dwWidth;
+ rcDest.top = ptOrigin.y;
+ rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight;
+
+ /* Source can be entire shadow surface, as Blt should clip for us */
+ rcSrc.left = 0;
+ rcSrc.top = 0;
+ rcSrc.right = pScreenInfo->dwWidth;
+ rcSrc.bottom = pScreenInfo->dwHeight;
+
+ /* Redraw the whole window, to take account for the new colors */
+ ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary,
+ &rcDest,
+ pScreenPriv->pddsShadow,
+ &rcSrc,
+ DDBLT_WAIT,
+ NULL);
+ if (FAILED (ddrval))
+ {
+ ErrorF ("winRedrawScreenShadowDD - IDirectDrawSurface_Blt () "
+ "failed: %08x\n",
+ (unsigned int) ddrval);
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Realize the currently installed colormap
+ */
+
+static Bool
+winRealizeInstalledPaletteShadowDD (ScreenPtr pScreen)
+{
+ return TRUE;
+}
+
+
+/*
+ * Install the specified colormap
+ */
+
+static Bool
+winInstallColormapShadowDD (ColormapPtr pColormap)
+{
+ ScreenPtr pScreen = pColormap->pScreen;
+ winScreenPriv(pScreen);
+ winCmapPriv(pColormap);
+ HRESULT ddrval = DD_OK;
+
+ /* Install the DirectDraw palette on the primary surface */
+ ddrval = IDirectDrawSurface2_SetPalette (pScreenPriv->pddsPrimary,
+ pCmapPriv->lpDDPalette);
+ if (FAILED (ddrval))
+ {
+ ErrorF ("winInstallColormapShadowDD - Failed installing the "
+ "DirectDraw palette.\n");
+ return FALSE;
+ }
+
+ /* Save a pointer to the newly installed colormap */
+ pScreenPriv->pcmapInstalled = pColormap;
+
+ return TRUE;
+}
+
+
+/*
+ * Store the specified colors in the specified colormap
+ */
+
+static Bool
+winStoreColorsShadowDD (ColormapPtr pColormap,
+ int ndef,
+ xColorItem *pdefs)
+{
+ ScreenPtr pScreen = pColormap->pScreen;
+ winScreenPriv(pScreen);
+ winCmapPriv(pColormap);
+ ColormapPtr curpmap = pScreenPriv->pcmapInstalled;
+ HRESULT ddrval = DD_OK;
+
+ /* Put the X colormap entries into the Windows logical palette */
+ ddrval = IDirectDrawPalette_SetEntries (pCmapPriv->lpDDPalette,
+ 0,
+ pdefs[0].pixel,
+ ndef,
+ pCmapPriv->peColors
+ + pdefs[0].pixel);
+ if (FAILED (ddrval))
+ {
+ ErrorF ("winStoreColorsShadowDD - SetEntries () failed\n");
+ return FALSE;
+ }
+
+ /* Don't install the DirectDraw palette if the colormap is not installed */
+ if (pColormap != curpmap)
+ {
+ return TRUE;
+ }
+
+ if (!winInstallColormapShadowDD (pColormap))
+ {
+ ErrorF ("winStoreColorsShadowDD - Failed installing colormap\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Colormap initialization procedure
+ */
+
+static Bool
+winCreateColormapShadowDD (ColormapPtr pColormap)
+{
+ HRESULT ddrval = DD_OK;
+ ScreenPtr pScreen = pColormap->pScreen;
+ winScreenPriv(pScreen);
+ winCmapPriv(pColormap);
+
+ /* Create a DirectDraw palette */
+ ddrval = IDirectDraw2_CreatePalette (pScreenPriv->pdd,
+ DDPCAPS_8BIT | DDPCAPS_ALLOW256,
+ pCmapPriv->peColors,
+ &pCmapPriv->lpDDPalette,
+ NULL);
+ if (FAILED (ddrval))
+ {
+ ErrorF ("winCreateColormapShadowDD - CreatePalette failed\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Colormap destruction procedure
+ */
+
+static Bool
+winDestroyColormapShadowDD (ColormapPtr pColormap)
+{
+ winScreenPriv(pColormap->pScreen);
+ winCmapPriv(pColormap);
+ HRESULT ddrval = DD_OK;
+
+ /*
+ * Is colormap to be destroyed the default?
+ *
+ * Non-default colormaps should have had winUninstallColormap
+ * called on them before we get here. The default colormap
+ * will not have had winUninstallColormap called on it. Thus,
+ * we need to handle the default colormap in a special way.
+ */
+ if (pColormap->flags & IsDefault)
+ {
+ winDebug ("winDestroyColormapShadowDD - Destroying default "
+ "colormap\n");
+
+ /*
+ * FIXME: Walk the list of all screens, popping the default
+ * palette out of each screen device context.
+ */
+
+ /* Pop the palette out of the primary surface */
+ ddrval = IDirectDrawSurface2_SetPalette (pScreenPriv->pddsPrimary,
+ NULL);
+ if (FAILED (ddrval))
+ {
+ ErrorF ("winDestroyColormapShadowDD - Failed freeing the "
+ "default colormap DirectDraw palette.\n");
+ return FALSE;
+ }
+
+ /* Clear our private installed colormap pointer */
+ pScreenPriv->pcmapInstalled = NULL;
+ }
+
+ /* Release the palette */
+ IDirectDrawPalette_Release (pCmapPriv->lpDDPalette);
+
+ /* Invalidate the colormap privates */
+ pCmapPriv->lpDDPalette = NULL;
+
+ return TRUE;
+}
+
+
+/*
+ * Set engine specific functions
+ */
+
+Bool
+winSetEngineFunctionsShadowDD (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+
+ /* Set our pointers */
+ pScreenPriv->pwinAllocateFB = winAllocateFBShadowDD;
+ pScreenPriv->pwinShadowUpdate = winShadowUpdateDD;
+ pScreenPriv->pwinCloseScreen = winCloseScreenShadowDD;
+ pScreenPriv->pwinInitVisuals = winInitVisualsShadowDD;
+ pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowDD;
+ if (pScreenInfo->fFullScreen)
+ pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen;
+ else
+ pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
+ pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB;
+ pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowDD;
+ pScreenPriv->pwinActivateApp = winActivateAppShadowDD;
+ pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowDD;
+ pScreenPriv->pwinRealizeInstalledPalette
+ = winRealizeInstalledPaletteShadowDD;
+ pScreenPriv->pwinInstallColormap = winInstallColormapShadowDD;
+ pScreenPriv->pwinStoreColors = winStoreColorsShadowDD;
+ pScreenPriv->pwinCreateColormap = winCreateColormapShadowDD;
+ pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowDD;
+ pScreenPriv->pwinHotKeyAltTab = (winHotKeyAltTabProcPtr) (void (*)(void))NoopDDA;
+ pScreenPriv->pwinCreatePrimarySurface = winCreatePrimarySurfaceShadowDD;
+ pScreenPriv->pwinReleasePrimarySurface = winReleasePrimarySurfaceShadowDD;
+#ifdef XWIN_MULTIWINDOW
+ pScreenPriv->pwinFinishCreateWindowsWindow =
+ (winFinishCreateWindowsWindowProcPtr) (void (*)(void))NoopDDA;
+#endif
+
+ return TRUE;
+}
diff --git a/xorg-server/hw/xwin/winshadddnl.c b/xorg-server/hw/xwin/winshadddnl.c index af7b989df..95fb0e6fc 100644 --- a/xorg-server/hw/xwin/winshadddnl.c +++ b/xorg-server/hw/xwin/winshadddnl.c @@ -583,8 +583,8 @@ winShadowUpdateDDNL (ScreenPtr pScreen, HRESULT ddrval = DD_OK;
RECT rcDest, rcSrc;
POINT ptOrigin;
- DWORD dwBox = REGION_NUM_RECTS (damage);
- BoxPtr pBox = REGION_RECTS (damage);
+ DWORD dwBox = RegionNumRects (damage);
+ BoxPtr pBox = RegionRects (damage);
HRGN hrgnTemp = NULL, hrgnCombined = NULL;
/*
@@ -659,7 +659,7 @@ winShadowUpdateDDNL (ScreenPtr pScreen, }
else
{
- BoxPtr pBoxExtents = REGION_EXTENTS (pScreen, damage);
+ BoxPtr pBoxExtents = RegionExtents(damage);
/* Compute a GDI region from the damaged region */
hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
diff --git a/xorg-server/hw/xwin/winshadgdi.c b/xorg-server/hw/xwin/winshadgdi.c index fbc15abb3..09135c702 100644 --- a/xorg-server/hw/xwin/winshadgdi.c +++ b/xorg-server/hw/xwin/winshadgdi.c @@ -1,1302 +1,1302 @@ -/* - *Copyright (C) 2001-2004 Harold L Hunt II 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, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *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. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of Harold L Hunt II - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from Harold L Hunt II. - * - * Authors: Harold L Hunt II - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" - - -/* - * External symbols - */ - -#ifdef XWIN_MULTIWINDOW -extern DWORD g_dwCurrentThreadID; -#endif -extern HWND g_hDlgExit; - - -/* - * Local function prototypes - */ - -#ifdef XWIN_MULTIWINDOW -static wBOOL CALLBACK -winRedrawAllProcShadowGDI (HWND hwnd, LPARAM lParam); - -static wBOOL CALLBACK -winRedrawDamagedWindowShadowGDI (HWND hwnd, LPARAM lParam); -#endif - -static Bool -winAllocateFBShadowGDI (ScreenPtr pScreen); - -static void -winShadowUpdateGDI (ScreenPtr pScreen, - shadowBufPtr pBuf); - -static Bool -winCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen); - -static Bool -winInitVisualsShadowGDI (ScreenPtr pScreen); - -static Bool -winAdjustVideoModeShadowGDI (ScreenPtr pScreen); - -static Bool -winBltExposedRegionsShadowGDI (ScreenPtr pScreen); - -static Bool -winActivateAppShadowGDI (ScreenPtr pScreen); - -static Bool -winRedrawScreenShadowGDI (ScreenPtr pScreen); - -static Bool -winRealizeInstalledPaletteShadowGDI (ScreenPtr pScreen); - -static Bool -winInstallColormapShadowGDI (ColormapPtr pColormap); - -static Bool -winStoreColorsShadowGDI (ColormapPtr pmap, - int ndef, - xColorItem *pdefs); - -static Bool -winCreateColormapShadowGDI (ColormapPtr pColormap); - -static Bool -winDestroyColormapShadowGDI (ColormapPtr pColormap); - - -/* - * Internal function to get the DIB format that is compatible with the screen - */ - -static -Bool -winQueryScreenDIBFormat (ScreenPtr pScreen, BITMAPINFOHEADER *pbmih) -{ - winScreenPriv(pScreen); - HBITMAP hbmp; -#ifdef WINDBG - LPDWORD pdw = NULL; -#endif - - /* Create a memory bitmap compatible with the screen */ - hbmp = CreateCompatibleBitmap (pScreenPriv->hdcScreen, 1, 1); - if (hbmp == NULL) - { - ErrorF ("winQueryScreenDIBFormat - CreateCompatibleBitmap failed\n"); - return FALSE; - } - - /* Initialize our bitmap info header */ - ZeroMemory (pbmih, sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD)); - pbmih->biSize = sizeof (BITMAPINFOHEADER); - - /* Get the biBitCount */ - if (!GetDIBits (pScreenPriv->hdcScreen, - hbmp, - 0, 1, - NULL, - (BITMAPINFO*) pbmih, - DIB_RGB_COLORS)) - { - ErrorF ("winQueryScreenDIBFormat - First call to GetDIBits failed\n"); - DeleteObject (hbmp); - return FALSE; - } - -#ifdef WINDBG - /* Get a pointer to bitfields */ - pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER)); - - winDebug ("winQueryScreenDIBFormat - First call masks: %08x %08x %08x\n", - pdw[0], pdw[1], pdw[2]); -#endif - - /* Get optimal color table, or the optimal bitfields */ - if (!GetDIBits (pScreenPriv->hdcScreen, - hbmp, - 0, 1, - NULL, - (BITMAPINFO*)pbmih, - DIB_RGB_COLORS)) - { - ErrorF ("winQueryScreenDIBFormat - Second call to GetDIBits " - "failed\n"); - DeleteObject (hbmp); - return FALSE; - } - - /* Free memory */ - DeleteObject (hbmp); - - return TRUE; -} - - -/* - * Internal function to determine the GDI bits per rgb and bit masks - */ - -static -Bool -winQueryRGBBitsAndMasks (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - BITMAPINFOHEADER *pbmih = NULL; - Bool fReturn = TRUE; - LPDWORD pdw = NULL; - DWORD dwRedBits, dwGreenBits, dwBlueBits; - - /* Color masks for 8 bpp are standardized */ - if (GetDeviceCaps (pScreenPriv->hdcScreen, RASTERCAPS) & RC_PALETTE) - { - /* - * RGB BPP for 8 bit palletes is always 8 - * and the color masks are always 0. - */ - pScreenPriv->dwBitsPerRGB = 8; - pScreenPriv->dwRedMask = 0x0L; - pScreenPriv->dwGreenMask = 0x0L; - pScreenPriv->dwBlueMask = 0x0L; - return TRUE; - } - - /* Color masks for 24 bpp are standardized */ - if (GetDeviceCaps (pScreenPriv->hdcScreen, PLANES) - * GetDeviceCaps (pScreenPriv->hdcScreen, BITSPIXEL) == 24) - { - winDebug ("winQueryRGBBitsAndMasks - GetDeviceCaps (BITSPIXEL) " - "returned 24 for the screen. Using default 24bpp masks.\n"); - - /* 8 bits per primary color */ - pScreenPriv->dwBitsPerRGB = 8; - - /* Set screen privates masks */ - pScreenPriv->dwRedMask = WIN_24BPP_MASK_RED; - pScreenPriv->dwGreenMask = WIN_24BPP_MASK_GREEN; - pScreenPriv->dwBlueMask = WIN_24BPP_MASK_BLUE; - - return TRUE; - } - - /* Allocate a bitmap header and color table */ - pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER) - + 256 * sizeof (RGBQUAD)); - if (pbmih == NULL) - { - ErrorF ("winQueryRGBBitsAndMasks - malloc failed\n"); - return FALSE; - } - - /* Get screen description */ - if (winQueryScreenDIBFormat (pScreen, pbmih)) - { - /* Get a pointer to bitfields */ - pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER)); - -#ifdef WINDBG - winDebug ("%s - Masks: %08x %08x %08x\n", __FUNCTION__, - pdw[0], pdw[1], pdw[2]); - winDebug ("%s - Bitmap: %dx%d %d bpp %d planes\n", __FUNCTION__, - pbmih->biWidth, pbmih->biHeight, pbmih->biBitCount, pbmih->biPlanes); - winDebug ("%s - Compression: %d %s\n", __FUNCTION__, - pbmih->biCompression, - (pbmih->biCompression == BI_RGB?"(BI_RGB)": - (pbmih->biCompression == BI_RLE8?"(BI_RLE8)": - (pbmih->biCompression == BI_RLE4?"(BI_RLE4)": - (pbmih->biCompression == BI_BITFIELDS?"(BI_BITFIELDS)":"" - ))))); -#endif - - /* Handle BI_RGB case, which is returned by Wine */ - if (pbmih->biCompression == BI_RGB) - { - dwRedBits = 5; - dwGreenBits = 5; - dwBlueBits = 5; - - pScreenPriv->dwBitsPerRGB = 5; - - /* Set screen privates masks */ - pScreenPriv->dwRedMask = 0x7c00; - pScreenPriv->dwGreenMask = 0x03e0; - pScreenPriv->dwBlueMask = 0x001f; - } - else - { - /* Count the number of bits in each mask */ - dwRedBits = winCountBits (pdw[0]); - dwGreenBits = winCountBits (pdw[1]); - dwBlueBits = winCountBits (pdw[2]); - - /* Find maximum bits per red, green, blue */ - if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits) - pScreenPriv->dwBitsPerRGB = dwRedBits; - else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits) - pScreenPriv->dwBitsPerRGB = dwGreenBits; - else - pScreenPriv->dwBitsPerRGB = dwBlueBits; - - /* Set screen privates masks */ - pScreenPriv->dwRedMask = pdw[0]; - pScreenPriv->dwGreenMask = pdw[1]; - pScreenPriv->dwBlueMask = pdw[2]; - } - } - else - { - ErrorF ("winQueryRGBBitsAndMasks - winQueryScreenDIBFormat failed\n"); - free (pbmih); - fReturn = FALSE; - } - - /* Free memory */ - free (pbmih); - - return fReturn; -} - - -#ifdef XWIN_MULTIWINDOW -/* - * Redraw all ---? - */ - -static wBOOL CALLBACK -winRedrawAllProcShadowGDI (HWND hwnd, LPARAM lParam) -{ - if (hwnd == (HWND)lParam) - return TRUE; - InvalidateRect (hwnd, NULL, FALSE); - UpdateWindow (hwnd); - return TRUE; -} - -static wBOOL CALLBACK -winRedrawDamagedWindowShadowGDI (HWND hwnd, LPARAM lParam) -{ - BoxPtr pDamage = (BoxPtr)lParam; - RECT rcClient, rcDamage, rcRedraw; - POINT topLeft, bottomRight; - - if (IsIconic (hwnd)) - return TRUE; /* Don't care minimized windows */ - - /* Convert the damaged area from Screen coords to Client coords */ - topLeft.x = pDamage->x1; topLeft.y = pDamage->y1; - bottomRight.x = pDamage->x2; bottomRight.y = pDamage->y2; - topLeft.x += GetSystemMetrics (SM_XVIRTUALSCREEN); - bottomRight.x += GetSystemMetrics (SM_XVIRTUALSCREEN); - topLeft.y += GetSystemMetrics (SM_YVIRTUALSCREEN); - bottomRight.y += GetSystemMetrics (SM_YVIRTUALSCREEN); - ScreenToClient (hwnd, &topLeft); - ScreenToClient (hwnd, &bottomRight); - SetRect (&rcDamage, topLeft.x, topLeft.y, bottomRight.x, bottomRight.y); - - GetClientRect (hwnd, &rcClient); - - if (IntersectRect (&rcRedraw, &rcClient, &rcDamage)) - { - InvalidateRect (hwnd, &rcRedraw, FALSE); - UpdateWindow (hwnd); - } - return TRUE; -} -#endif - - -/* - * Allocate a DIB for the shadow framebuffer GDI server - */ - -static Bool -winAllocateFBShadowGDI (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - BITMAPINFOHEADER *pbmih = NULL; - DIBSECTION dibsection; - Bool fReturn = TRUE; - - /* Get device contexts for the screen and shadow bitmap */ - pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen); - pScreenPriv->hdcShadow = CreateCompatibleDC (pScreenPriv->hdcScreen); - - /* Allocate bitmap info header */ - pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER) - + 256 * sizeof (RGBQUAD)); - if (pbmih == NULL) - { - ErrorF ("winAllocateFBShadowGDI - malloc () failed\n"); - return FALSE; - } - - /* Query the screen format */ - fReturn = winQueryScreenDIBFormat (pScreen, pbmih); - - /* Describe shadow bitmap to be created */ - pbmih->biWidth = pScreenInfo->dwWidth; - pbmih->biHeight = -pScreenInfo->dwHeight; - - winDebug ("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d " - "depth: %d\n", - (int) pbmih->biWidth, (int) -pbmih->biHeight, pbmih->biBitCount); - - /* Create a DI shadow bitmap with a bit pointer */ - pScreenPriv->hbmpShadow = CreateDIBSection (pScreenPriv->hdcScreen, - (BITMAPINFO *) pbmih, - DIB_RGB_COLORS, - (VOID**) &pScreenInfo->pfb, - NULL, - 0); - if (pScreenPriv->hbmpShadow == NULL || pScreenInfo->pfb == NULL) - { - winW32Error ("winAllocateFBShadowGDI - CreateDIBSection failed:"); - return FALSE; - } - else - { - winDebug ("winAllocateFBShadowGDI - Shadow buffer allocated\n"); - } - - /* Get information about the bitmap that was allocated */ - GetObject (pScreenPriv->hbmpShadow, - sizeof (dibsection), - &dibsection); - - /* Print information about bitmap allocated */ - winDebug ("winAllocateFBShadowGDI - Dibsection width: %d height: %d " - "depth: %d size image: %d\n", - (int) dibsection.dsBmih.biWidth, (int) dibsection.dsBmih.biHeight, - dibsection.dsBmih.biBitCount, - (int) dibsection.dsBmih.biSizeImage); - - /* Select the shadow bitmap into the shadow DC */ - SelectObject (pScreenPriv->hdcShadow, - pScreenPriv->hbmpShadow); - - winDebug ("winAllocateFBShadowGDI - Attempting a shadow blit\n"); - - /* Do a test blit from the shadow to the screen, I think */ - fReturn = BitBlt (pScreenPriv->hdcScreen, - 0, 0, - pScreenInfo->dwWidth, pScreenInfo->dwHeight, - pScreenPriv->hdcShadow, - 0, 0, - SRCCOPY); - if (fReturn) - { - winDebug ("winAllocateFBShadowGDI - Shadow blit success\n"); - } - else - { - winW32Error ("winAllocateFBShadowGDI - Shadow blit failure\n"); - /* ago: ignore this error. The blit fails with wine, but does not - * cause any problems later. */ - - fReturn = TRUE; - } - - /* Look for height weirdness */ - if (dibsection.dsBmih.biHeight < 0) - { - dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight; - } - - /* Set screeninfo stride */ - pScreenInfo->dwStride = ((dibsection.dsBmih.biSizeImage - / dibsection.dsBmih.biHeight) - * 8) / pScreenInfo->dwBPP; - - winDebug ("winAllocateFBShadowGDI - Created shadow stride: %d\n", - (int) pScreenInfo->dwStride); - - /* See if the shadow bitmap will be larger than the DIB size limit */ - if (pScreenInfo->dwWidth * pScreenInfo->dwHeight * pScreenInfo->dwBPP - >= WIN_DIB_MAXIMUM_SIZE) - { - ErrorF ("winAllocateFBShadowGDI - Requested DIB (bitmap) " - "will be larger than %d MB. The surface may fail to be " - "allocated on Windows 95, 98, or Me, due to a %d MB limit in " - "DIB size. This limit does not apply to Windows NT/2000, and " - "this message may be ignored on those platforms.\n", - WIN_DIB_MAXIMUM_SIZE_MB, WIN_DIB_MAXIMUM_SIZE_MB); - } - - /* Determine our color masks */ - if (!winQueryRGBBitsAndMasks (pScreen)) - { - ErrorF ("winAllocateFBShadowGDI - winQueryRGBBitsAndMasks failed\n"); - return FALSE; - } - -#ifdef XWIN_MULTIWINDOW - /* Redraw all windows */ - if (pScreenInfo->fMultiWindow) - EnumThreadWindows (g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0); -#endif - - return fReturn; -} - - -/* - * Blit the damaged regions of the shadow fb to the screen - */ - -static void -winShadowUpdateGDI (ScreenPtr pScreen, - shadowBufPtr pBuf) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - RegionPtr damage = shadowDamage(pBuf); - DWORD dwBox = REGION_NUM_RECTS (damage); - BoxPtr pBox = REGION_RECTS (damage); - int x, y, w, h; - HRGN hrgnTemp = NULL, hrgnCombined = NULL; -#ifdef XWIN_UPDATESTATS - static DWORD s_dwNonUnitRegions = 0; - static DWORD s_dwTotalUpdates = 0; - static DWORD s_dwTotalBoxes = 0; -#endif - BoxPtr pBoxExtents = REGION_EXTENTS (pScreen, damage); - - /* - * Return immediately if the app is not active - * and we are fullscreen, or if we have a bad display depth - */ - if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen) - || pScreenPriv->fBadDepth) return; - -#ifdef XWIN_UPDATESTATS - ++s_dwTotalUpdates; - s_dwTotalBoxes += dwBox; - - if (dwBox != 1) - { - ++s_dwNonUnitRegions; - winDebug ("winShadowUpdatGDI - dwBox: %d\n", dwBox); - } - - if ((s_dwTotalUpdates % 100) == 0) - { - winDebug ("winShadowUpdateGDI - %d%% non-unity regions, avg boxes: %d " - "nu: %d tu: %d\n", - (s_dwNonUnitRegions * 100) / s_dwTotalUpdates, - s_dwTotalBoxes / s_dwTotalUpdates, - s_dwNonUnitRegions, s_dwTotalUpdates); - } -#endif /* XWIN_UPDATESTATS */ - - /* - * Handle small regions with multiple blits, - * handle large regions by creating a clipping region and - * doing a single blit constrained to that clipping region. - */ - if (!pScreenInfo->fMultiWindow && - (pScreenInfo->dwClipUpdatesNBoxes == 0 || - dwBox < pScreenInfo->dwClipUpdatesNBoxes)) - { - /* Loop through all boxes in the damaged region */ - while (dwBox--) - { - /* - * Calculate x offset, y offset, width, and height for - * current damage box - */ - x = pBox->x1; - y = pBox->y1; - w = pBox->x2 - pBox->x1; - h = pBox->y2 - pBox->y1; - - BitBlt (pScreenPriv->hdcScreen, - x, y, - w, h, - pScreenPriv->hdcShadow, - x, y, - SRCCOPY); - - /* Get a pointer to the next box */ - ++pBox; - } - } - else if (!pScreenInfo->fMultiWindow) - { - /* Compute a GDI region from the damaged region */ - hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); - dwBox--; - pBox++; - while (dwBox--) - { - hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); - CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR); - DeleteObject (hrgnTemp); - pBox++; - } - - /* Install the GDI region as a clipping region */ - SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined); - DeleteObject (hrgnCombined); - hrgnCombined = NULL; - - /* - * Blit the shadow buffer to the screen, - * constrained to the clipping region. - */ - BitBlt (pScreenPriv->hdcScreen, - pBoxExtents->x1, pBoxExtents->y1, - pBoxExtents->x2 - pBoxExtents->x1, - pBoxExtents->y2 - pBoxExtents->y1, - pScreenPriv->hdcShadow, - pBoxExtents->x1, pBoxExtents->y1, - SRCCOPY); - - /* Reset the clip region */ - SelectClipRgn (pScreenPriv->hdcScreen, NULL); - } - -#ifdef XWIN_MULTIWINDOW - /* Redraw all multiwindow windows */ - if (pScreenInfo->fMultiWindow) - EnumThreadWindows (g_dwCurrentThreadID, - winRedrawDamagedWindowShadowGDI, - (LPARAM)pBoxExtents); -#endif -} - - -/* See Porting Layer Definition - p. 33 */ -/* - * We wrap whatever CloseScreen procedure was specified by fb; - * a pointer to said procedure is stored in our privates. - */ - -static Bool -winCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - Bool fReturn; - - winDebug ("winCloseScreenShadowGDI - Freeing screen resources\n"); - - /* Flag that the screen is closed */ - pScreenPriv->fClosed = TRUE; - pScreenPriv->fActive = FALSE; - - /* Call the wrapped CloseScreen procedure */ - WIN_UNWRAP(CloseScreen); - fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); - - /* Delete the window property */ - RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP); - - /* Free the shadow DC; which allows the bitmap to be freed */ - DeleteDC (pScreenPriv->hdcShadow); - - /* Free the shadow bitmap */ - DeleteObject (pScreenPriv->hbmpShadow); - - /* Free the screen DC */ - ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen); - - /* Delete tray icon, if we have one */ - if (!pScreenInfo->fNoTrayIcon) - winDeleteNotifyIcon (pScreenPriv); - - /* Free the exit confirmation dialog box, if it exists */ - if (g_hDlgExit != NULL) - { - DestroyWindow (g_hDlgExit); - g_hDlgExit = NULL; - } - - /* Kill our window */ - if (pScreenPriv->hwndScreen) - { - DestroyWindow (pScreenPriv->hwndScreen); - pScreenPriv->hwndScreen = NULL; - } - -#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) - /* Destroy the thread startup mutex */ - pthread_mutex_destroy (&pScreenPriv->pmServerStarted); -#endif - - /* Invalidate our screeninfo's pointer to the screen */ - pScreenInfo->pScreen = NULL; - - /* Invalidate the ScreenInfo's fb pointer */ - pScreenInfo->pfb = NULL; - - /* Free the screen privates for this screen */ - free ((pointer) pScreenPriv); - - return fReturn; -} - - -/* - * Tell mi what sort of visuals we need. - * - * Generally we only need one visual, as our screen can only - * handle one format at a time, I believe. You may want - * to verify that last sentence. - */ - -static Bool -winInitVisualsShadowGDI (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - - /* Display debugging information */ - winDebug ("winInitVisualsShadowGDI - Masks %08x %08x %08x BPRGB %d d %d " - "bpp %d\n", - (unsigned int) pScreenPriv->dwRedMask, - (unsigned int) pScreenPriv->dwGreenMask, - (unsigned int) pScreenPriv->dwBlueMask, - (int) pScreenPriv->dwBitsPerRGB, - (int) pScreenInfo->dwDepth, - (int) pScreenInfo->dwBPP); - - /* Create a single visual according to the Windows screen depth */ - switch (pScreenInfo->dwDepth) - { - case 24: - case 16: - case 15: -#if defined(XFree86Server) - /* Setup the real visual */ - if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, - TrueColorMask, - pScreenPriv->dwBitsPerRGB, - -1, - pScreenPriv->dwRedMask, - pScreenPriv->dwGreenMask, - pScreenPriv->dwBlueMask)) - { - ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " - "failed\n"); - return FALSE; - } - -#ifdef XWIN_EMULATEPSEUDO - if (!pScreenInfo->fEmulatePseudo) - break; - - /* Setup a pseudocolor visual */ - if (!miSetVisualTypesAndMasks (8, - PseudoColorMask, - 8, - -1, - 0, - 0, - 0)) - { - ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " - "failed for PseudoColor\n"); - return FALSE; - } -#endif -#else /* XFree86Server */ - /* Setup the real visual */ - if (!fbSetVisualTypesAndMasks (pScreenInfo->dwDepth, - TrueColorMask, - pScreenPriv->dwBitsPerRGB, - pScreenPriv->dwRedMask, - pScreenPriv->dwGreenMask, - pScreenPriv->dwBlueMask)) - { - ErrorF ("winInitVisualsShadowGDI - fbSetVisualTypesAndMasks " - "failed for TrueColor\n"); - return FALSE; - } - -#ifdef XWIN_EMULATEPSEUDO - if (!pScreenInfo->fEmulatePseudo) - break; - - /* Setup a pseudocolor visual */ - if (!fbSetVisualTypesAndMasks (8, - PseudoColorMask, - 8, - 0, - 0, - 0)) - { - ErrorF ("winInitVisualsShadowGDI - fbSetVisualTypesAndMasks " - "failed for PseudoColor\n"); - return FALSE; - } -#endif -#endif /* XFree86Server */ - break; - - case 8: -#if defined(XFree86Server) - if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, - PseudoColorMask, - pScreenPriv->dwBitsPerRGB, - PseudoColor, - pScreenPriv->dwRedMask, - pScreenPriv->dwGreenMask, - pScreenPriv->dwBlueMask)) - { - ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " - "failed\n"); - return FALSE; - } -#else /* XFree86Server */ - if (!fbSetVisualTypesAndMasks (pScreenInfo->dwDepth, - PseudoColorMask, - pScreenPriv->dwBitsPerRGB, - pScreenPriv->dwRedMask, - pScreenPriv->dwGreenMask, - pScreenPriv->dwBlueMask)) - { - ErrorF ("winInitVisualsShadowGDI - fbSetVisualTypesAndMasks " - "failed\n"); - return FALSE; - } -#endif - break; - - default: - ErrorF ("winInitVisualsShadowGDI - Unknown screen depth\n"); - return FALSE; - } - - winDebug ("winInitVisualsShadowGDI - Returning\n"); - - return TRUE; -} - - -/* - * Adjust the proposed video mode - */ - -static Bool -winAdjustVideoModeShadowGDI (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - HDC hdc; - DWORD dwBPP; - - hdc = GetDC (NULL); - - /* We're in serious trouble if we can't get a DC */ - if (hdc == NULL) - { - ErrorF ("winAdjustVideoModeShadowGDI - GetDC () failed\n"); - return FALSE; - } - - /* Query GDI for current display depth */ - dwBPP = GetDeviceCaps (hdc, BITSPIXEL); - - /* GDI cannot change the screen depth */ - if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP) - { - /* No -depth parameter passed, let the user know the depth being used */ - winDebug ("winAdjustVideoModeShadowGDI - Using Windows display " - "depth of %d bits per pixel\n", (int) dwBPP); - - /* Use GDI's depth */ - pScreenInfo->dwBPP = dwBPP; - } - else if (dwBPP != pScreenInfo->dwBPP) - { - /* Warn user if GDI depth is different than -depth parameter */ - winDebug ("winAdjustVideoModeShadowGDI - Command line bpp: %d, "\ - "using bpp: %d\n", (int) pScreenInfo->dwBPP, (int) dwBPP); - - /* We'll use GDI's depth */ - pScreenInfo->dwBPP = dwBPP; - } - - /* Release our DC */ - ReleaseDC (NULL, hdc); - hdc = NULL; - - return TRUE; -} - - -/* - * Blt exposed regions to the screen - */ - -static Bool -winBltExposedRegionsShadowGDI (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - winPrivCmapPtr pCmapPriv = NULL; - HDC hdcUpdate; - PAINTSTRUCT ps; - - /* BeginPaint gives us an hdc that clips to the invalidated region */ - hdcUpdate = BeginPaint (pScreenPriv->hwndScreen, &ps); - - /* Realize the palette, if we have one */ - if (pScreenPriv->pcmapInstalled != NULL) - { - pCmapPriv = winGetCmapPriv (pScreenPriv->pcmapInstalled); - - SelectPalette (hdcUpdate, pCmapPriv->hPalette, FALSE); - RealizePalette (hdcUpdate); - } - - /* Our BitBlt will be clipped to the invalidated region */ - BitBlt (hdcUpdate, - 0, 0, - pScreenInfo->dwWidth, pScreenInfo->dwHeight, - pScreenPriv->hdcShadow, - 0, 0, - SRCCOPY); - - /* EndPaint frees the DC */ - EndPaint (pScreenPriv->hwndScreen, &ps); - -#ifdef XWIN_MULTIWINDOW - /* Redraw all windows */ - if (pScreenInfo->fMultiWindow) - EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, - (LPARAM)pScreenPriv->hwndScreen); -#endif - - return TRUE; -} - - -/* - * Do any engine-specific appliation-activation processing - */ - -static Bool -winActivateAppShadowGDI (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - - /* - * 2004/04/12 - Harold - We perform the restoring or minimizing - * manually for ShadowGDI in fullscreen modes so that this engine - * will perform just like ShadowDD and ShadowDDNL in fullscreen mode; - * if we do not do this then our fullscreen window will appear in the - * z-order when it is deactivated and it can be uncovered by resizing - * or minimizing another window that is on top of it, which is not how - * the DirectDraw engines work. Therefore we keep this code here to - * make sure that all engines work the same in fullscreen mode. - */ - - /* - * Are we active? - * Are we fullscreen? - */ - if (pScreenPriv->fActive - && pScreenInfo->fFullScreen) - { - /* - * Activating, attempt to bring our window - * to the top of the display - */ - ShowWindow (pScreenPriv->hwndScreen, SW_RESTORE); - } - else if (!pScreenPriv->fActive - && pScreenInfo->fFullScreen) - { - /* - * Deactivating, stuff our window onto the - * task bar. - */ - ShowWindow (pScreenPriv->hwndScreen, SW_MINIMIZE); - } - - return TRUE; -} - - -/* - * Reblit the shadow framebuffer to the screen. - */ - -static Bool -winRedrawScreenShadowGDI (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - - /* Redraw the whole window, to take account for the new colors */ - BitBlt (pScreenPriv->hdcScreen, - 0, 0, - pScreenInfo->dwWidth, pScreenInfo->dwHeight, - pScreenPriv->hdcShadow, - 0, 0, - SRCCOPY); - -#ifdef XWIN_MULTIWINDOW - /* Redraw all windows */ - if (pScreenInfo->fMultiWindow) - EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0); -#endif - - return TRUE; -} - - - -/* - * Realize the currently installed colormap - */ - -static Bool -winRealizeInstalledPaletteShadowGDI (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winPrivCmapPtr pCmapPriv = NULL; - - winDebug ("winRealizeInstalledPaletteShadowGDI\n"); - - /* Don't do anything if there is not a colormap */ - if (pScreenPriv->pcmapInstalled == NULL) - { - winDebug ("winRealizeInstalledPaletteShadowGDI - No colormap " - "installed\n"); - return TRUE; - } - - pCmapPriv = winGetCmapPriv (pScreenPriv->pcmapInstalled); - - /* Realize our palette for the screen */ - if (RealizePalette (pScreenPriv->hdcScreen) == GDI_ERROR) - { - ErrorF ("winRealizeInstalledPaletteShadowGDI - RealizePalette () " - "failed\n"); - return FALSE; - } - - /* Set the DIB color table */ - if (SetDIBColorTable (pScreenPriv->hdcShadow, - 0, - WIN_NUM_PALETTE_ENTRIES, - pCmapPriv->rgbColors) == 0) - { - ErrorF ("winRealizeInstalledPaletteShadowGDI - SetDIBColorTable () " - "failed\n"); - return FALSE; - } - - return TRUE; -} - - -/* - * Install the specified colormap - */ - -static Bool -winInstallColormapShadowGDI (ColormapPtr pColormap) -{ - ScreenPtr pScreen = pColormap->pScreen; - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - winCmapPriv(pColormap); - - /* - * Tell Windows to install the new colormap - */ - if (SelectPalette (pScreenPriv->hdcScreen, - pCmapPriv->hPalette, - FALSE) == NULL) - { - ErrorF ("winInstallColormapShadowGDI - SelectPalette () failed\n"); - return FALSE; - } - - /* Realize the palette */ - if (GDI_ERROR == RealizePalette (pScreenPriv->hdcScreen)) - { - ErrorF ("winInstallColormapShadowGDI - RealizePalette () failed\n"); - return FALSE; - } - - /* Set the DIB color table */ - if (SetDIBColorTable (pScreenPriv->hdcShadow, - 0, - WIN_NUM_PALETTE_ENTRIES, - pCmapPriv->rgbColors) == 0) - { - ErrorF ("winInstallColormapShadowGDI - SetDIBColorTable () failed\n"); - return FALSE; - } - - /* Redraw the whole window, to take account for the new colors */ - BitBlt (pScreenPriv->hdcScreen, - 0, 0, - pScreenInfo->dwWidth, pScreenInfo->dwHeight, - pScreenPriv->hdcShadow, - 0, 0, - SRCCOPY); - - /* Save a pointer to the newly installed colormap */ - pScreenPriv->pcmapInstalled = pColormap; - -#ifdef XWIN_MULTIWINDOW - /* Redraw all windows */ - if (pScreenInfo->fMultiWindow) - EnumThreadWindows (g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0); -#endif - - return TRUE; -} - - -/* - * Store the specified colors in the specified colormap - */ - -static Bool -winStoreColorsShadowGDI (ColormapPtr pColormap, - int ndef, - xColorItem *pdefs) -{ - ScreenPtr pScreen = pColormap->pScreen; - winScreenPriv(pScreen); - winCmapPriv(pColormap); - ColormapPtr curpmap = pScreenPriv->pcmapInstalled; - - /* Put the X colormap entries into the Windows logical palette */ - if (SetPaletteEntries (pCmapPriv->hPalette, - pdefs[0].pixel, - ndef, - pCmapPriv->peColors + pdefs[0].pixel) == 0) - { - ErrorF ("winStoreColorsShadowGDI - SetPaletteEntries () failed\n"); - return FALSE; - } - - /* Don't install the Windows palette if the colormap is not installed */ - if (pColormap != curpmap) - { - return TRUE; - } - - /* Try to install the newly modified colormap */ - if (!winInstallColormapShadowGDI (pColormap)) - { - ErrorF ("winInstallColormapShadowGDI - winInstallColormapShadowGDI " - "failed\n"); - return FALSE; - } - -#if 0 - /* Tell Windows that the palette has changed */ - RealizePalette (pScreenPriv->hdcScreen); - - /* Set the DIB color table */ - if (SetDIBColorTable (pScreenPriv->hdcShadow, - pdefs[0].pixel, - ndef, - pCmapPriv->rgbColors + pdefs[0].pixel) == 0) - { - ErrorF ("winInstallColormapShadowGDI - SetDIBColorTable () failed\n"); - return FALSE; - } - - /* Save a pointer to the newly installed colormap */ - pScreenPriv->pcmapInstalled = pColormap; -#endif - - return TRUE; -} - - -/* - * Colormap initialization procedure - */ - -static Bool -winCreateColormapShadowGDI (ColormapPtr pColormap) -{ - LPLOGPALETTE lpPaletteNew = NULL; - DWORD dwEntriesMax; - VisualPtr pVisual; - HPALETTE hpalNew = NULL; - winCmapPriv(pColormap); - - /* Get a pointer to the visual that the colormap belongs to */ - pVisual = pColormap->pVisual; - - /* Get the maximum number of palette entries for this visual */ - dwEntriesMax = pVisual->ColormapEntries; - - /* Allocate a Windows logical color palette with max entries */ - lpPaletteNew = malloc (sizeof (LOGPALETTE) - + (dwEntriesMax - 1) * sizeof (PALETTEENTRY)); - if (lpPaletteNew == NULL) - { - ErrorF ("winCreateColormapShadowGDI - Couldn't allocate palette " - "with %d entries\n", - (int) dwEntriesMax); - return FALSE; - } - - /* Zero out the colormap */ - ZeroMemory (lpPaletteNew, sizeof (LOGPALETTE) - + (dwEntriesMax - 1) * sizeof (PALETTEENTRY)); - - /* Set the logical palette structure */ - lpPaletteNew->palVersion = 0x0300; - lpPaletteNew->palNumEntries = dwEntriesMax; - - /* Tell Windows to create the palette */ - hpalNew = CreatePalette (lpPaletteNew); - if (hpalNew == NULL) - { - ErrorF ("winCreateColormapShadowGDI - CreatePalette () failed\n"); - free (lpPaletteNew); - return FALSE; - } - - /* Save the Windows logical palette handle in the X colormaps' privates */ - pCmapPriv->hPalette = hpalNew; - - /* Free the palette initialization memory */ - free (lpPaletteNew); - - return TRUE; -} - - -/* - * Colormap destruction procedure - */ - -static Bool -winDestroyColormapShadowGDI (ColormapPtr pColormap) -{ - winScreenPriv(pColormap->pScreen); - winCmapPriv(pColormap); - - /* - * Is colormap to be destroyed the default? - * - * Non-default colormaps should have had winUninstallColormap - * called on them before we get here. The default colormap - * will not have had winUninstallColormap called on it. Thus, - * we need to handle the default colormap in a special way. - */ - if (pColormap->flags & IsDefault) - { - winDebug ("winDestroyColormapShadowGDI - Destroying default " - "colormap\n"); - - /* - * FIXME: Walk the list of all screens, popping the default - * palette out of each screen device context. - */ - - /* Pop the palette out of the device context */ - SelectPalette (pScreenPriv->hdcScreen, - GetStockObject (DEFAULT_PALETTE), - FALSE); - - /* Clear our private installed colormap pointer */ - pScreenPriv->pcmapInstalled = NULL; - } - - /* Try to delete the logical palette */ - if (DeleteObject (pCmapPriv->hPalette) == 0) - { - ErrorF ("winDestroyColormap - DeleteObject () failed\n"); - return FALSE; - } - - /* Invalidate the colormap privates */ - pCmapPriv->hPalette = NULL; - - return TRUE; -} - - -/* - * Set engine specific funtions - */ - -Bool -winSetEngineFunctionsShadowGDI (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - - /* Set our pointers */ - pScreenPriv->pwinAllocateFB = winAllocateFBShadowGDI; - pScreenPriv->pwinShadowUpdate = winShadowUpdateGDI; - pScreenPriv->pwinCloseScreen = winCloseScreenShadowGDI; - pScreenPriv->pwinInitVisuals = winInitVisualsShadowGDI; - pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowGDI; - if (pScreenInfo->fFullScreen) - pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen; - else - pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed; - pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB; - pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowGDI; - pScreenPriv->pwinActivateApp = winActivateAppShadowGDI; - pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowGDI; - pScreenPriv->pwinRealizeInstalledPalette = - winRealizeInstalledPaletteShadowGDI; - pScreenPriv->pwinInstallColormap = winInstallColormapShadowGDI; - pScreenPriv->pwinStoreColors = winStoreColorsShadowGDI; - pScreenPriv->pwinCreateColormap = winCreateColormapShadowGDI; - pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowGDI; - pScreenPriv->pwinHotKeyAltTab = (winHotKeyAltTabProcPtr) (void (*)(void))NoopDDA; - pScreenPriv->pwinCreatePrimarySurface - = (winCreatePrimarySurfaceProcPtr) (void (*)(void))NoopDDA; - pScreenPriv->pwinReleasePrimarySurface - = (winReleasePrimarySurfaceProcPtr) (void (*)(void))NoopDDA; -#ifdef XWIN_MULTIWINDOW - pScreenPriv->pwinFinishCreateWindowsWindow = - (winFinishCreateWindowsWindowProcPtr) (void (*)(void))NoopDDA; -#endif - - return TRUE; -} +/*
+ *Copyright (C) 2001-2004 Harold L Hunt II 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, sublicense, and/or sell copies of the Software, and to
+ *permit persons to whom the Software is furnished to do so, subject to
+ *the following conditions:
+ *
+ *The above copyright notice and this permission notice shall be
+ *included in all copies or substantial portions of the Software.
+ *
+ *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. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR
+ *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *Except as contained in this notice, the name of Harold L Hunt II
+ *shall not be used in advertising or otherwise to promote the sale, use
+ *or other dealings in this Software without prior written authorization
+ *from Harold L Hunt II.
+ *
+ * Authors: Harold L Hunt II
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+
+
+/*
+ * External symbols
+ */
+
+#ifdef XWIN_MULTIWINDOW
+extern DWORD g_dwCurrentThreadID;
+#endif
+extern HWND g_hDlgExit;
+
+
+/*
+ * Local function prototypes
+ */
+
+#ifdef XWIN_MULTIWINDOW
+static wBOOL CALLBACK
+winRedrawAllProcShadowGDI (HWND hwnd, LPARAM lParam);
+
+static wBOOL CALLBACK
+winRedrawDamagedWindowShadowGDI (HWND hwnd, LPARAM lParam);
+#endif
+
+static Bool
+winAllocateFBShadowGDI (ScreenPtr pScreen);
+
+static void
+winShadowUpdateGDI (ScreenPtr pScreen,
+ shadowBufPtr pBuf);
+
+static Bool
+winCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen);
+
+static Bool
+winInitVisualsShadowGDI (ScreenPtr pScreen);
+
+static Bool
+winAdjustVideoModeShadowGDI (ScreenPtr pScreen);
+
+static Bool
+winBltExposedRegionsShadowGDI (ScreenPtr pScreen);
+
+static Bool
+winActivateAppShadowGDI (ScreenPtr pScreen);
+
+static Bool
+winRedrawScreenShadowGDI (ScreenPtr pScreen);
+
+static Bool
+winRealizeInstalledPaletteShadowGDI (ScreenPtr pScreen);
+
+static Bool
+winInstallColormapShadowGDI (ColormapPtr pColormap);
+
+static Bool
+winStoreColorsShadowGDI (ColormapPtr pmap,
+ int ndef,
+ xColorItem *pdefs);
+
+static Bool
+winCreateColormapShadowGDI (ColormapPtr pColormap);
+
+static Bool
+winDestroyColormapShadowGDI (ColormapPtr pColormap);
+
+
+/*
+ * Internal function to get the DIB format that is compatible with the screen
+ */
+
+static
+Bool
+winQueryScreenDIBFormat (ScreenPtr pScreen, BITMAPINFOHEADER *pbmih)
+{
+ winScreenPriv(pScreen);
+ HBITMAP hbmp;
+#ifdef WINDBG
+ LPDWORD pdw = NULL;
+#endif
+
+ /* Create a memory bitmap compatible with the screen */
+ hbmp = CreateCompatibleBitmap (pScreenPriv->hdcScreen, 1, 1);
+ if (hbmp == NULL)
+ {
+ ErrorF ("winQueryScreenDIBFormat - CreateCompatibleBitmap failed\n");
+ return FALSE;
+ }
+
+ /* Initialize our bitmap info header */
+ ZeroMemory (pbmih, sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD));
+ pbmih->biSize = sizeof (BITMAPINFOHEADER);
+
+ /* Get the biBitCount */
+ if (!GetDIBits (pScreenPriv->hdcScreen,
+ hbmp,
+ 0, 1,
+ NULL,
+ (BITMAPINFO*) pbmih,
+ DIB_RGB_COLORS))
+ {
+ ErrorF ("winQueryScreenDIBFormat - First call to GetDIBits failed\n");
+ DeleteObject (hbmp);
+ return FALSE;
+ }
+
+#ifdef WINDBG
+ /* Get a pointer to bitfields */
+ pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER));
+
+ winDebug ("winQueryScreenDIBFormat - First call masks: %08x %08x %08x\n",
+ pdw[0], pdw[1], pdw[2]);
+#endif
+
+ /* Get optimal color table, or the optimal bitfields */
+ if (!GetDIBits (pScreenPriv->hdcScreen,
+ hbmp,
+ 0, 1,
+ NULL,
+ (BITMAPINFO*)pbmih,
+ DIB_RGB_COLORS))
+ {
+ ErrorF ("winQueryScreenDIBFormat - Second call to GetDIBits "
+ "failed\n");
+ DeleteObject (hbmp);
+ return FALSE;
+ }
+
+ /* Free memory */
+ DeleteObject (hbmp);
+
+ return TRUE;
+}
+
+
+/*
+ * Internal function to determine the GDI bits per rgb and bit masks
+ */
+
+static
+Bool
+winQueryRGBBitsAndMasks (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ BITMAPINFOHEADER *pbmih = NULL;
+ Bool fReturn = TRUE;
+ LPDWORD pdw = NULL;
+ DWORD dwRedBits, dwGreenBits, dwBlueBits;
+
+ /* Color masks for 8 bpp are standardized */
+ if (GetDeviceCaps (pScreenPriv->hdcScreen, RASTERCAPS) & RC_PALETTE)
+ {
+ /*
+ * RGB BPP for 8 bit palletes is always 8
+ * and the color masks are always 0.
+ */
+ pScreenPriv->dwBitsPerRGB = 8;
+ pScreenPriv->dwRedMask = 0x0L;
+ pScreenPriv->dwGreenMask = 0x0L;
+ pScreenPriv->dwBlueMask = 0x0L;
+ return TRUE;
+ }
+
+ /* Color masks for 24 bpp are standardized */
+ if (GetDeviceCaps (pScreenPriv->hdcScreen, PLANES)
+ * GetDeviceCaps (pScreenPriv->hdcScreen, BITSPIXEL) == 24)
+ {
+ winDebug ("winQueryRGBBitsAndMasks - GetDeviceCaps (BITSPIXEL) "
+ "returned 24 for the screen. Using default 24bpp masks.\n");
+
+ /* 8 bits per primary color */
+ pScreenPriv->dwBitsPerRGB = 8;
+
+ /* Set screen privates masks */
+ pScreenPriv->dwRedMask = WIN_24BPP_MASK_RED;
+ pScreenPriv->dwGreenMask = WIN_24BPP_MASK_GREEN;
+ pScreenPriv->dwBlueMask = WIN_24BPP_MASK_BLUE;
+
+ return TRUE;
+ }
+
+ /* Allocate a bitmap header and color table */
+ pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER)
+ + 256 * sizeof (RGBQUAD));
+ if (pbmih == NULL)
+ {
+ ErrorF ("winQueryRGBBitsAndMasks - malloc failed\n");
+ return FALSE;
+ }
+
+ /* Get screen description */
+ if (winQueryScreenDIBFormat (pScreen, pbmih))
+ {
+ /* Get a pointer to bitfields */
+ pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER));
+
+#ifdef WINDBG
+ winDebug ("%s - Masks: %08x %08x %08x\n", __FUNCTION__,
+ pdw[0], pdw[1], pdw[2]);
+ winDebug ("%s - Bitmap: %dx%d %d bpp %d planes\n", __FUNCTION__,
+ pbmih->biWidth, pbmih->biHeight, pbmih->biBitCount, pbmih->biPlanes);
+ winDebug ("%s - Compression: %d %s\n", __FUNCTION__,
+ pbmih->biCompression,
+ (pbmih->biCompression == BI_RGB?"(BI_RGB)":
+ (pbmih->biCompression == BI_RLE8?"(BI_RLE8)":
+ (pbmih->biCompression == BI_RLE4?"(BI_RLE4)":
+ (pbmih->biCompression == BI_BITFIELDS?"(BI_BITFIELDS)":""
+ )))));
+#endif
+
+ /* Handle BI_RGB case, which is returned by Wine */
+ if (pbmih->biCompression == BI_RGB)
+ {
+ dwRedBits = 5;
+ dwGreenBits = 5;
+ dwBlueBits = 5;
+
+ pScreenPriv->dwBitsPerRGB = 5;
+
+ /* Set screen privates masks */
+ pScreenPriv->dwRedMask = 0x7c00;
+ pScreenPriv->dwGreenMask = 0x03e0;
+ pScreenPriv->dwBlueMask = 0x001f;
+ }
+ else
+ {
+ /* Count the number of bits in each mask */
+ dwRedBits = winCountBits (pdw[0]);
+ dwGreenBits = winCountBits (pdw[1]);
+ dwBlueBits = winCountBits (pdw[2]);
+
+ /* Find maximum bits per red, green, blue */
+ if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits)
+ pScreenPriv->dwBitsPerRGB = dwRedBits;
+ else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits)
+ pScreenPriv->dwBitsPerRGB = dwGreenBits;
+ else
+ pScreenPriv->dwBitsPerRGB = dwBlueBits;
+
+ /* Set screen privates masks */
+ pScreenPriv->dwRedMask = pdw[0];
+ pScreenPriv->dwGreenMask = pdw[1];
+ pScreenPriv->dwBlueMask = pdw[2];
+ }
+ }
+ else
+ {
+ ErrorF ("winQueryRGBBitsAndMasks - winQueryScreenDIBFormat failed\n");
+ free (pbmih);
+ fReturn = FALSE;
+ }
+
+ /* Free memory */
+ free (pbmih);
+
+ return fReturn;
+}
+
+
+#ifdef XWIN_MULTIWINDOW
+/*
+ * Redraw all ---?
+ */
+
+static wBOOL CALLBACK
+winRedrawAllProcShadowGDI (HWND hwnd, LPARAM lParam)
+{
+ if (hwnd == (HWND)lParam)
+ return TRUE;
+ InvalidateRect (hwnd, NULL, FALSE);
+ UpdateWindow (hwnd);
+ return TRUE;
+}
+
+static wBOOL CALLBACK
+winRedrawDamagedWindowShadowGDI (HWND hwnd, LPARAM lParam)
+{
+ BoxPtr pDamage = (BoxPtr)lParam;
+ RECT rcClient, rcDamage, rcRedraw;
+ POINT topLeft, bottomRight;
+
+ if (IsIconic (hwnd))
+ return TRUE; /* Don't care minimized windows */
+
+ /* Convert the damaged area from Screen coords to Client coords */
+ topLeft.x = pDamage->x1; topLeft.y = pDamage->y1;
+ bottomRight.x = pDamage->x2; bottomRight.y = pDamage->y2;
+ topLeft.x += GetSystemMetrics (SM_XVIRTUALSCREEN);
+ bottomRight.x += GetSystemMetrics (SM_XVIRTUALSCREEN);
+ topLeft.y += GetSystemMetrics (SM_YVIRTUALSCREEN);
+ bottomRight.y += GetSystemMetrics (SM_YVIRTUALSCREEN);
+ ScreenToClient (hwnd, &topLeft);
+ ScreenToClient (hwnd, &bottomRight);
+ SetRect (&rcDamage, topLeft.x, topLeft.y, bottomRight.x, bottomRight.y);
+
+ GetClientRect (hwnd, &rcClient);
+
+ if (IntersectRect (&rcRedraw, &rcClient, &rcDamage))
+ {
+ InvalidateRect (hwnd, &rcRedraw, FALSE);
+ UpdateWindow (hwnd);
+ }
+ return TRUE;
+}
+#endif
+
+
+/*
+ * Allocate a DIB for the shadow framebuffer GDI server
+ */
+
+static Bool
+winAllocateFBShadowGDI (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+ BITMAPINFOHEADER *pbmih = NULL;
+ DIBSECTION dibsection;
+ Bool fReturn = TRUE;
+
+ /* Get device contexts for the screen and shadow bitmap */
+ pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
+ pScreenPriv->hdcShadow = CreateCompatibleDC (pScreenPriv->hdcScreen);
+
+ /* Allocate bitmap info header */
+ pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER)
+ + 256 * sizeof (RGBQUAD));
+ if (pbmih == NULL)
+ {
+ ErrorF ("winAllocateFBShadowGDI - malloc () failed\n");
+ return FALSE;
+ }
+
+ /* Query the screen format */
+ fReturn = winQueryScreenDIBFormat (pScreen, pbmih);
+
+ /* Describe shadow bitmap to be created */
+ pbmih->biWidth = pScreenInfo->dwWidth;
+ pbmih->biHeight = -pScreenInfo->dwHeight;
+
+ winDebug ("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d "
+ "depth: %d\n",
+ (int) pbmih->biWidth, (int) -pbmih->biHeight, pbmih->biBitCount);
+
+ /* Create a DI shadow bitmap with a bit pointer */
+ pScreenPriv->hbmpShadow = CreateDIBSection (pScreenPriv->hdcScreen,
+ (BITMAPINFO *) pbmih,
+ DIB_RGB_COLORS,
+ (VOID**) &pScreenInfo->pfb,
+ NULL,
+ 0);
+ if (pScreenPriv->hbmpShadow == NULL || pScreenInfo->pfb == NULL)
+ {
+ winW32Error ("winAllocateFBShadowGDI - CreateDIBSection failed:");
+ return FALSE;
+ }
+ else
+ {
+ winDebug ("winAllocateFBShadowGDI - Shadow buffer allocated\n");
+ }
+
+ /* Get information about the bitmap that was allocated */
+ GetObject (pScreenPriv->hbmpShadow,
+ sizeof (dibsection),
+ &dibsection);
+
+ /* Print information about bitmap allocated */
+ winDebug ("winAllocateFBShadowGDI - Dibsection width: %d height: %d "
+ "depth: %d size image: %d\n",
+ (int) dibsection.dsBmih.biWidth, (int) dibsection.dsBmih.biHeight,
+ dibsection.dsBmih.biBitCount,
+ (int) dibsection.dsBmih.biSizeImage);
+
+ /* Select the shadow bitmap into the shadow DC */
+ SelectObject (pScreenPriv->hdcShadow,
+ pScreenPriv->hbmpShadow);
+
+ winDebug ("winAllocateFBShadowGDI - Attempting a shadow blit\n");
+
+ /* Do a test blit from the shadow to the screen, I think */
+ fReturn = BitBlt (pScreenPriv->hdcScreen,
+ 0, 0,
+ pScreenInfo->dwWidth, pScreenInfo->dwHeight,
+ pScreenPriv->hdcShadow,
+ 0, 0,
+ SRCCOPY);
+ if (fReturn)
+ {
+ winDebug ("winAllocateFBShadowGDI - Shadow blit success\n");
+ }
+ else
+ {
+ winW32Error ("winAllocateFBShadowGDI - Shadow blit failure\n");
+ /* ago: ignore this error. The blit fails with wine, but does not
+ * cause any problems later. */
+
+ fReturn = TRUE;
+ }
+
+ /* Look for height weirdness */
+ if (dibsection.dsBmih.biHeight < 0)
+ {
+ dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight;
+ }
+
+ /* Set screeninfo stride */
+ pScreenInfo->dwStride = ((dibsection.dsBmih.biSizeImage
+ / dibsection.dsBmih.biHeight)
+ * 8) / pScreenInfo->dwBPP;
+
+ winDebug ("winAllocateFBShadowGDI - Created shadow stride: %d\n",
+ (int) pScreenInfo->dwStride);
+
+ /* See if the shadow bitmap will be larger than the DIB size limit */
+ if (pScreenInfo->dwWidth * pScreenInfo->dwHeight * pScreenInfo->dwBPP
+ >= WIN_DIB_MAXIMUM_SIZE)
+ {
+ ErrorF ("winAllocateFBShadowGDI - Requested DIB (bitmap) "
+ "will be larger than %d MB. The surface may fail to be "
+ "allocated on Windows 95, 98, or Me, due to a %d MB limit in "
+ "DIB size. This limit does not apply to Windows NT/2000, and "
+ "this message may be ignored on those platforms.\n",
+ WIN_DIB_MAXIMUM_SIZE_MB, WIN_DIB_MAXIMUM_SIZE_MB);
+ }
+
+ /* Determine our color masks */
+ if (!winQueryRGBBitsAndMasks (pScreen))
+ {
+ ErrorF ("winAllocateFBShadowGDI - winQueryRGBBitsAndMasks failed\n");
+ return FALSE;
+ }
+
+#ifdef XWIN_MULTIWINDOW
+ /* Redraw all windows */
+ if (pScreenInfo->fMultiWindow)
+ EnumThreadWindows (g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0);
+#endif
+
+ return fReturn;
+}
+
+
+/*
+ * Blit the damaged regions of the shadow fb to the screen
+ */
+
+static void
+winShadowUpdateGDI (ScreenPtr pScreen,
+ shadowBufPtr pBuf)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+ RegionPtr damage = shadowDamage(pBuf);
+ DWORD dwBox = RegionNumRects (damage);
+ BoxPtr pBox = RegionRects (damage);
+ int x, y, w, h;
+ HRGN hrgnTemp = NULL, hrgnCombined = NULL;
+#ifdef XWIN_UPDATESTATS
+ static DWORD s_dwNonUnitRegions = 0;
+ static DWORD s_dwTotalUpdates = 0;
+ static DWORD s_dwTotalBoxes = 0;
+#endif
+ BoxPtr pBoxExtents = RegionExtents(damage);
+
+ /*
+ * Return immediately if the app is not active
+ * and we are fullscreen, or if we have a bad display depth
+ */
+ if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen)
+ || pScreenPriv->fBadDepth) return;
+
+#ifdef XWIN_UPDATESTATS
+ ++s_dwTotalUpdates;
+ s_dwTotalBoxes += dwBox;
+
+ if (dwBox != 1)
+ {
+ ++s_dwNonUnitRegions;
+ winDebug ("winShadowUpdatGDI - dwBox: %d\n", dwBox);
+ }
+
+ if ((s_dwTotalUpdates % 100) == 0)
+ {
+ winDebug ("winShadowUpdateGDI - %d%% non-unity regions, avg boxes: %d "
+ "nu: %d tu: %d\n",
+ (s_dwNonUnitRegions * 100) / s_dwTotalUpdates,
+ s_dwTotalBoxes / s_dwTotalUpdates,
+ s_dwNonUnitRegions, s_dwTotalUpdates);
+ }
+#endif /* XWIN_UPDATESTATS */
+
+ /*
+ * Handle small regions with multiple blits,
+ * handle large regions by creating a clipping region and
+ * doing a single blit constrained to that clipping region.
+ */
+ if (!pScreenInfo->fMultiWindow &&
+ (pScreenInfo->dwClipUpdatesNBoxes == 0 ||
+ dwBox < pScreenInfo->dwClipUpdatesNBoxes))
+ {
+ /* Loop through all boxes in the damaged region */
+ while (dwBox--)
+ {
+ /*
+ * Calculate x offset, y offset, width, and height for
+ * current damage box
+ */
+ x = pBox->x1;
+ y = pBox->y1;
+ w = pBox->x2 - pBox->x1;
+ h = pBox->y2 - pBox->y1;
+
+ BitBlt (pScreenPriv->hdcScreen,
+ x, y,
+ w, h,
+ pScreenPriv->hdcShadow,
+ x, y,
+ SRCCOPY);
+
+ /* Get a pointer to the next box */
+ ++pBox;
+ }
+ }
+ else if (!pScreenInfo->fMultiWindow)
+ {
+ /* Compute a GDI region from the damaged region */
+ hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
+ dwBox--;
+ pBox++;
+ while (dwBox--)
+ {
+ hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
+ CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR);
+ DeleteObject (hrgnTemp);
+ pBox++;
+ }
+
+ /* Install the GDI region as a clipping region */
+ SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined);
+ DeleteObject (hrgnCombined);
+ hrgnCombined = NULL;
+
+ /*
+ * Blit the shadow buffer to the screen,
+ * constrained to the clipping region.
+ */
+ BitBlt (pScreenPriv->hdcScreen,
+ pBoxExtents->x1, pBoxExtents->y1,
+ pBoxExtents->x2 - pBoxExtents->x1,
+ pBoxExtents->y2 - pBoxExtents->y1,
+ pScreenPriv->hdcShadow,
+ pBoxExtents->x1, pBoxExtents->y1,
+ SRCCOPY);
+
+ /* Reset the clip region */
+ SelectClipRgn (pScreenPriv->hdcScreen, NULL);
+ }
+
+#ifdef XWIN_MULTIWINDOW
+ /* Redraw all multiwindow windows */
+ if (pScreenInfo->fMultiWindow)
+ EnumThreadWindows (g_dwCurrentThreadID,
+ winRedrawDamagedWindowShadowGDI,
+ (LPARAM)pBoxExtents);
+#endif
+}
+
+
+/* See Porting Layer Definition - p. 33 */
+/*
+ * We wrap whatever CloseScreen procedure was specified by fb;
+ * a pointer to said procedure is stored in our privates.
+ */
+
+static Bool
+winCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+ Bool fReturn;
+
+ winDebug ("winCloseScreenShadowGDI - Freeing screen resources\n");
+
+ /* Flag that the screen is closed */
+ pScreenPriv->fClosed = TRUE;
+ pScreenPriv->fActive = FALSE;
+
+ /* Call the wrapped CloseScreen procedure */
+ WIN_UNWRAP(CloseScreen);
+ fReturn = (*pScreen->CloseScreen) (nIndex, pScreen);
+
+ /* Delete the window property */
+ RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP);
+
+ /* Free the shadow DC; which allows the bitmap to be freed */
+ DeleteDC (pScreenPriv->hdcShadow);
+
+ /* Free the shadow bitmap */
+ DeleteObject (pScreenPriv->hbmpShadow);
+
+ /* Free the screen DC */
+ ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen);
+
+ /* Delete tray icon, if we have one */
+ if (!pScreenInfo->fNoTrayIcon)
+ winDeleteNotifyIcon (pScreenPriv);
+
+ /* Free the exit confirmation dialog box, if it exists */
+ if (g_hDlgExit != NULL)
+ {
+ DestroyWindow (g_hDlgExit);
+ g_hDlgExit = NULL;
+ }
+
+ /* Kill our window */
+ if (pScreenPriv->hwndScreen)
+ {
+ DestroyWindow (pScreenPriv->hwndScreen);
+ pScreenPriv->hwndScreen = NULL;
+ }
+
+#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
+ /* Destroy the thread startup mutex */
+ pthread_mutex_destroy (&pScreenPriv->pmServerStarted);
+#endif
+
+ /* Invalidate our screeninfo's pointer to the screen */
+ pScreenInfo->pScreen = NULL;
+
+ /* Invalidate the ScreenInfo's fb pointer */
+ pScreenInfo->pfb = NULL;
+
+ /* Free the screen privates for this screen */
+ free ((pointer) pScreenPriv);
+
+ return fReturn;
+}
+
+
+/*
+ * Tell mi what sort of visuals we need.
+ *
+ * Generally we only need one visual, as our screen can only
+ * handle one format at a time, I believe. You may want
+ * to verify that last sentence.
+ */
+
+static Bool
+winInitVisualsShadowGDI (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+
+ /* Display debugging information */
+ winDebug ("winInitVisualsShadowGDI - Masks %08x %08x %08x BPRGB %d d %d "
+ "bpp %d\n",
+ (unsigned int) pScreenPriv->dwRedMask,
+ (unsigned int) pScreenPriv->dwGreenMask,
+ (unsigned int) pScreenPriv->dwBlueMask,
+ (int) pScreenPriv->dwBitsPerRGB,
+ (int) pScreenInfo->dwDepth,
+ (int) pScreenInfo->dwBPP);
+
+ /* Create a single visual according to the Windows screen depth */
+ switch (pScreenInfo->dwDepth)
+ {
+ case 24:
+ case 16:
+ case 15:
+#if defined(XFree86Server)
+ /* Setup the real visual */
+ if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth,
+ TrueColorMask,
+ pScreenPriv->dwBitsPerRGB,
+ -1,
+ pScreenPriv->dwRedMask,
+ pScreenPriv->dwGreenMask,
+ pScreenPriv->dwBlueMask))
+ {
+ ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
+ "failed\n");
+ return FALSE;
+ }
+
+#ifdef XWIN_EMULATEPSEUDO
+ if (!pScreenInfo->fEmulatePseudo)
+ break;
+
+ /* Setup a pseudocolor visual */
+ if (!miSetVisualTypesAndMasks (8,
+ PseudoColorMask,
+ 8,
+ -1,
+ 0,
+ 0,
+ 0))
+ {
+ ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
+ "failed for PseudoColor\n");
+ return FALSE;
+ }
+#endif
+#else /* XFree86Server */
+ /* Setup the real visual */
+ if (!fbSetVisualTypesAndMasks (pScreenInfo->dwDepth,
+ TrueColorMask,
+ pScreenPriv->dwBitsPerRGB,
+ pScreenPriv->dwRedMask,
+ pScreenPriv->dwGreenMask,
+ pScreenPriv->dwBlueMask))
+ {
+ ErrorF ("winInitVisualsShadowGDI - fbSetVisualTypesAndMasks "
+ "failed for TrueColor\n");
+ return FALSE;
+ }
+
+#ifdef XWIN_EMULATEPSEUDO
+ if (!pScreenInfo->fEmulatePseudo)
+ break;
+
+ /* Setup a pseudocolor visual */
+ if (!fbSetVisualTypesAndMasks (8,
+ PseudoColorMask,
+ 8,
+ 0,
+ 0,
+ 0))
+ {
+ ErrorF ("winInitVisualsShadowGDI - fbSetVisualTypesAndMasks "
+ "failed for PseudoColor\n");
+ return FALSE;
+ }
+#endif
+#endif /* XFree86Server */
+ break;
+
+ case 8:
+#if defined(XFree86Server)
+ if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth,
+ PseudoColorMask,
+ pScreenPriv->dwBitsPerRGB,
+ PseudoColor,
+ pScreenPriv->dwRedMask,
+ pScreenPriv->dwGreenMask,
+ pScreenPriv->dwBlueMask))
+ {
+ ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
+ "failed\n");
+ return FALSE;
+ }
+#else /* XFree86Server */
+ if (!fbSetVisualTypesAndMasks (pScreenInfo->dwDepth,
+ PseudoColorMask,
+ pScreenPriv->dwBitsPerRGB,
+ pScreenPriv->dwRedMask,
+ pScreenPriv->dwGreenMask,
+ pScreenPriv->dwBlueMask))
+ {
+ ErrorF ("winInitVisualsShadowGDI - fbSetVisualTypesAndMasks "
+ "failed\n");
+ return FALSE;
+ }
+#endif
+ break;
+
+ default:
+ ErrorF ("winInitVisualsShadowGDI - Unknown screen depth\n");
+ return FALSE;
+ }
+
+ winDebug ("winInitVisualsShadowGDI - Returning\n");
+
+ return TRUE;
+}
+
+
+/*
+ * Adjust the proposed video mode
+ */
+
+static Bool
+winAdjustVideoModeShadowGDI (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+ HDC hdc;
+ DWORD dwBPP;
+
+ hdc = GetDC (NULL);
+
+ /* We're in serious trouble if we can't get a DC */
+ if (hdc == NULL)
+ {
+ ErrorF ("winAdjustVideoModeShadowGDI - GetDC () failed\n");
+ return FALSE;
+ }
+
+ /* Query GDI for current display depth */
+ dwBPP = GetDeviceCaps (hdc, BITSPIXEL);
+
+ /* GDI cannot change the screen depth */
+ if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP)
+ {
+ /* No -depth parameter passed, let the user know the depth being used */
+ winDebug ("winAdjustVideoModeShadowGDI - Using Windows display "
+ "depth of %d bits per pixel\n", (int) dwBPP);
+
+ /* Use GDI's depth */
+ pScreenInfo->dwBPP = dwBPP;
+ }
+ else if (dwBPP != pScreenInfo->dwBPP)
+ {
+ /* Warn user if GDI depth is different than -depth parameter */
+ winDebug ("winAdjustVideoModeShadowGDI - Command line bpp: %d, "\
+ "using bpp: %d\n", (int) pScreenInfo->dwBPP, (int) dwBPP);
+
+ /* We'll use GDI's depth */
+ pScreenInfo->dwBPP = dwBPP;
+ }
+
+ /* Release our DC */
+ ReleaseDC (NULL, hdc);
+ hdc = NULL;
+
+ return TRUE;
+}
+
+
+/*
+ * Blt exposed regions to the screen
+ */
+
+static Bool
+winBltExposedRegionsShadowGDI (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+ winPrivCmapPtr pCmapPriv = NULL;
+ HDC hdcUpdate;
+ PAINTSTRUCT ps;
+
+ /* BeginPaint gives us an hdc that clips to the invalidated region */
+ hdcUpdate = BeginPaint (pScreenPriv->hwndScreen, &ps);
+
+ /* Realize the palette, if we have one */
+ if (pScreenPriv->pcmapInstalled != NULL)
+ {
+ pCmapPriv = winGetCmapPriv (pScreenPriv->pcmapInstalled);
+
+ SelectPalette (hdcUpdate, pCmapPriv->hPalette, FALSE);
+ RealizePalette (hdcUpdate);
+ }
+
+ /* Our BitBlt will be clipped to the invalidated region */
+ BitBlt (hdcUpdate,
+ 0, 0,
+ pScreenInfo->dwWidth, pScreenInfo->dwHeight,
+ pScreenPriv->hdcShadow,
+ 0, 0,
+ SRCCOPY);
+
+ /* EndPaint frees the DC */
+ EndPaint (pScreenPriv->hwndScreen, &ps);
+
+#ifdef XWIN_MULTIWINDOW
+ /* Redraw all windows */
+ if (pScreenInfo->fMultiWindow)
+ EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI,
+ (LPARAM)pScreenPriv->hwndScreen);
+#endif
+
+ return TRUE;
+}
+
+
+/*
+ * Do any engine-specific appliation-activation processing
+ */
+
+static Bool
+winActivateAppShadowGDI (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+
+ /*
+ * 2004/04/12 - Harold - We perform the restoring or minimizing
+ * manually for ShadowGDI in fullscreen modes so that this engine
+ * will perform just like ShadowDD and ShadowDDNL in fullscreen mode;
+ * if we do not do this then our fullscreen window will appear in the
+ * z-order when it is deactivated and it can be uncovered by resizing
+ * or minimizing another window that is on top of it, which is not how
+ * the DirectDraw engines work. Therefore we keep this code here to
+ * make sure that all engines work the same in fullscreen mode.
+ */
+
+ /*
+ * Are we active?
+ * Are we fullscreen?
+ */
+ if (pScreenPriv->fActive
+ && pScreenInfo->fFullScreen)
+ {
+ /*
+ * Activating, attempt to bring our window
+ * to the top of the display
+ */
+ ShowWindow (pScreenPriv->hwndScreen, SW_RESTORE);
+ }
+ else if (!pScreenPriv->fActive
+ && pScreenInfo->fFullScreen)
+ {
+ /*
+ * Deactivating, stuff our window onto the
+ * task bar.
+ */
+ ShowWindow (pScreenPriv->hwndScreen, SW_MINIMIZE);
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Reblit the shadow framebuffer to the screen.
+ */
+
+static Bool
+winRedrawScreenShadowGDI (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+
+ /* Redraw the whole window, to take account for the new colors */
+ BitBlt (pScreenPriv->hdcScreen,
+ 0, 0,
+ pScreenInfo->dwWidth, pScreenInfo->dwHeight,
+ pScreenPriv->hdcShadow,
+ 0, 0,
+ SRCCOPY);
+
+#ifdef XWIN_MULTIWINDOW
+ /* Redraw all windows */
+ if (pScreenInfo->fMultiWindow)
+ EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0);
+#endif
+
+ return TRUE;
+}
+
+
+
+/*
+ * Realize the currently installed colormap
+ */
+
+static Bool
+winRealizeInstalledPaletteShadowGDI (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winPrivCmapPtr pCmapPriv = NULL;
+
+ winDebug ("winRealizeInstalledPaletteShadowGDI\n");
+
+ /* Don't do anything if there is not a colormap */
+ if (pScreenPriv->pcmapInstalled == NULL)
+ {
+ winDebug ("winRealizeInstalledPaletteShadowGDI - No colormap "
+ "installed\n");
+ return TRUE;
+ }
+
+ pCmapPriv = winGetCmapPriv (pScreenPriv->pcmapInstalled);
+
+ /* Realize our palette for the screen */
+ if (RealizePalette (pScreenPriv->hdcScreen) == GDI_ERROR)
+ {
+ ErrorF ("winRealizeInstalledPaletteShadowGDI - RealizePalette () "
+ "failed\n");
+ return FALSE;
+ }
+
+ /* Set the DIB color table */
+ if (SetDIBColorTable (pScreenPriv->hdcShadow,
+ 0,
+ WIN_NUM_PALETTE_ENTRIES,
+ pCmapPriv->rgbColors) == 0)
+ {
+ ErrorF ("winRealizeInstalledPaletteShadowGDI - SetDIBColorTable () "
+ "failed\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Install the specified colormap
+ */
+
+static Bool
+winInstallColormapShadowGDI (ColormapPtr pColormap)
+{
+ ScreenPtr pScreen = pColormap->pScreen;
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+ winCmapPriv(pColormap);
+
+ /*
+ * Tell Windows to install the new colormap
+ */
+ if (SelectPalette (pScreenPriv->hdcScreen,
+ pCmapPriv->hPalette,
+ FALSE) == NULL)
+ {
+ ErrorF ("winInstallColormapShadowGDI - SelectPalette () failed\n");
+ return FALSE;
+ }
+
+ /* Realize the palette */
+ if (GDI_ERROR == RealizePalette (pScreenPriv->hdcScreen))
+ {
+ ErrorF ("winInstallColormapShadowGDI - RealizePalette () failed\n");
+ return FALSE;
+ }
+
+ /* Set the DIB color table */
+ if (SetDIBColorTable (pScreenPriv->hdcShadow,
+ 0,
+ WIN_NUM_PALETTE_ENTRIES,
+ pCmapPriv->rgbColors) == 0)
+ {
+ ErrorF ("winInstallColormapShadowGDI - SetDIBColorTable () failed\n");
+ return FALSE;
+ }
+
+ /* Redraw the whole window, to take account for the new colors */
+ BitBlt (pScreenPriv->hdcScreen,
+ 0, 0,
+ pScreenInfo->dwWidth, pScreenInfo->dwHeight,
+ pScreenPriv->hdcShadow,
+ 0, 0,
+ SRCCOPY);
+
+ /* Save a pointer to the newly installed colormap */
+ pScreenPriv->pcmapInstalled = pColormap;
+
+#ifdef XWIN_MULTIWINDOW
+ /* Redraw all windows */
+ if (pScreenInfo->fMultiWindow)
+ EnumThreadWindows (g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0);
+#endif
+
+ return TRUE;
+}
+
+
+/*
+ * Store the specified colors in the specified colormap
+ */
+
+static Bool
+winStoreColorsShadowGDI (ColormapPtr pColormap,
+ int ndef,
+ xColorItem *pdefs)
+{
+ ScreenPtr pScreen = pColormap->pScreen;
+ winScreenPriv(pScreen);
+ winCmapPriv(pColormap);
+ ColormapPtr curpmap = pScreenPriv->pcmapInstalled;
+
+ /* Put the X colormap entries into the Windows logical palette */
+ if (SetPaletteEntries (pCmapPriv->hPalette,
+ pdefs[0].pixel,
+ ndef,
+ pCmapPriv->peColors + pdefs[0].pixel) == 0)
+ {
+ ErrorF ("winStoreColorsShadowGDI - SetPaletteEntries () failed\n");
+ return FALSE;
+ }
+
+ /* Don't install the Windows palette if the colormap is not installed */
+ if (pColormap != curpmap)
+ {
+ return TRUE;
+ }
+
+ /* Try to install the newly modified colormap */
+ if (!winInstallColormapShadowGDI (pColormap))
+ {
+ ErrorF ("winInstallColormapShadowGDI - winInstallColormapShadowGDI "
+ "failed\n");
+ return FALSE;
+ }
+
+#if 0
+ /* Tell Windows that the palette has changed */
+ RealizePalette (pScreenPriv->hdcScreen);
+
+ /* Set the DIB color table */
+ if (SetDIBColorTable (pScreenPriv->hdcShadow,
+ pdefs[0].pixel,
+ ndef,
+ pCmapPriv->rgbColors + pdefs[0].pixel) == 0)
+ {
+ ErrorF ("winInstallColormapShadowGDI - SetDIBColorTable () failed\n");
+ return FALSE;
+ }
+
+ /* Save a pointer to the newly installed colormap */
+ pScreenPriv->pcmapInstalled = pColormap;
+#endif
+
+ return TRUE;
+}
+
+
+/*
+ * Colormap initialization procedure
+ */
+
+static Bool
+winCreateColormapShadowGDI (ColormapPtr pColormap)
+{
+ LPLOGPALETTE lpPaletteNew = NULL;
+ DWORD dwEntriesMax;
+ VisualPtr pVisual;
+ HPALETTE hpalNew = NULL;
+ winCmapPriv(pColormap);
+
+ /* Get a pointer to the visual that the colormap belongs to */
+ pVisual = pColormap->pVisual;
+
+ /* Get the maximum number of palette entries for this visual */
+ dwEntriesMax = pVisual->ColormapEntries;
+
+ /* Allocate a Windows logical color palette with max entries */
+ lpPaletteNew = malloc (sizeof (LOGPALETTE)
+ + (dwEntriesMax - 1) * sizeof (PALETTEENTRY));
+ if (lpPaletteNew == NULL)
+ {
+ ErrorF ("winCreateColormapShadowGDI - Couldn't allocate palette "
+ "with %d entries\n",
+ (int) dwEntriesMax);
+ return FALSE;
+ }
+
+ /* Zero out the colormap */
+ ZeroMemory (lpPaletteNew, sizeof (LOGPALETTE)
+ + (dwEntriesMax - 1) * sizeof (PALETTEENTRY));
+
+ /* Set the logical palette structure */
+ lpPaletteNew->palVersion = 0x0300;
+ lpPaletteNew->palNumEntries = dwEntriesMax;
+
+ /* Tell Windows to create the palette */
+ hpalNew = CreatePalette (lpPaletteNew);
+ if (hpalNew == NULL)
+ {
+ ErrorF ("winCreateColormapShadowGDI - CreatePalette () failed\n");
+ free (lpPaletteNew);
+ return FALSE;
+ }
+
+ /* Save the Windows logical palette handle in the X colormaps' privates */
+ pCmapPriv->hPalette = hpalNew;
+
+ /* Free the palette initialization memory */
+ free (lpPaletteNew);
+
+ return TRUE;
+}
+
+
+/*
+ * Colormap destruction procedure
+ */
+
+static Bool
+winDestroyColormapShadowGDI (ColormapPtr pColormap)
+{
+ winScreenPriv(pColormap->pScreen);
+ winCmapPriv(pColormap);
+
+ /*
+ * Is colormap to be destroyed the default?
+ *
+ * Non-default colormaps should have had winUninstallColormap
+ * called on them before we get here. The default colormap
+ * will not have had winUninstallColormap called on it. Thus,
+ * we need to handle the default colormap in a special way.
+ */
+ if (pColormap->flags & IsDefault)
+ {
+ winDebug ("winDestroyColormapShadowGDI - Destroying default "
+ "colormap\n");
+
+ /*
+ * FIXME: Walk the list of all screens, popping the default
+ * palette out of each screen device context.
+ */
+
+ /* Pop the palette out of the device context */
+ SelectPalette (pScreenPriv->hdcScreen,
+ GetStockObject (DEFAULT_PALETTE),
+ FALSE);
+
+ /* Clear our private installed colormap pointer */
+ pScreenPriv->pcmapInstalled = NULL;
+ }
+
+ /* Try to delete the logical palette */
+ if (DeleteObject (pCmapPriv->hPalette) == 0)
+ {
+ ErrorF ("winDestroyColormap - DeleteObject () failed\n");
+ return FALSE;
+ }
+
+ /* Invalidate the colormap privates */
+ pCmapPriv->hPalette = NULL;
+
+ return TRUE;
+}
+
+
+/*
+ * Set engine specific funtions
+ */
+
+Bool
+winSetEngineFunctionsShadowGDI (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+
+ /* Set our pointers */
+ pScreenPriv->pwinAllocateFB = winAllocateFBShadowGDI;
+ pScreenPriv->pwinShadowUpdate = winShadowUpdateGDI;
+ pScreenPriv->pwinCloseScreen = winCloseScreenShadowGDI;
+ pScreenPriv->pwinInitVisuals = winInitVisualsShadowGDI;
+ pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowGDI;
+ if (pScreenInfo->fFullScreen)
+ pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen;
+ else
+ pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
+ pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB;
+ pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowGDI;
+ pScreenPriv->pwinActivateApp = winActivateAppShadowGDI;
+ pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowGDI;
+ pScreenPriv->pwinRealizeInstalledPalette =
+ winRealizeInstalledPaletteShadowGDI;
+ pScreenPriv->pwinInstallColormap = winInstallColormapShadowGDI;
+ pScreenPriv->pwinStoreColors = winStoreColorsShadowGDI;
+ pScreenPriv->pwinCreateColormap = winCreateColormapShadowGDI;
+ pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowGDI;
+ pScreenPriv->pwinHotKeyAltTab = (winHotKeyAltTabProcPtr) (void (*)(void))NoopDDA;
+ pScreenPriv->pwinCreatePrimarySurface
+ = (winCreatePrimarySurfaceProcPtr) (void (*)(void))NoopDDA;
+ pScreenPriv->pwinReleasePrimarySurface
+ = (winReleasePrimarySurfaceProcPtr) (void (*)(void))NoopDDA;
+#ifdef XWIN_MULTIWINDOW
+ pScreenPriv->pwinFinishCreateWindowsWindow =
+ (winFinishCreateWindowsWindowProcPtr) (void (*)(void))NoopDDA;
+#endif
+
+ return TRUE;
+}
diff --git a/xorg-server/hw/xwin/winvideo.c b/xorg-server/hw/xwin/winvideo.c index 42f46f405..998a3face 100644 --- a/xorg-server/hw/xwin/winvideo.c +++ b/xorg-server/hw/xwin/winvideo.c @@ -185,7 +185,7 @@ winSetupImageVideo (ScreenPtr pScreen) #if 0
/* gotta uninit this someplace */
- REGION_NULL(pScreen, &pPriv->clip);
+ RegionNull(&pPriv->clip);
#endif
#if 0
diff --git a/xorg-server/hw/xwin/winwin32rootless.c b/xorg-server/hw/xwin/winwin32rootless.c index f76363e43..85a932f75 100644 --- a/xorg-server/hw/xwin/winwin32rootless.c +++ b/xorg-server/hw/xwin/winwin32rootless.c @@ -1,982 +1,982 @@ -/* - *Copyright (C) 1994-2000 The XFree86 Project, 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, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *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. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of the XFree86 Project - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from the XFree86 Project. - * - * Authors: Kensuke Matsuzaki - * Earle F. Philhower, III - * Harold L Hunt II - */ -/* - * Look at hw/darwin/quartz/xpr/xprFrame.c and hw/darwin/quartz/cr/crFrame.c - */ -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" -#include <winuser.h> -#define _WINDOWSWM_SERVER_ -#include <X11/extensions/windowswmstr.h> -#include "dixevents.h" -#include "winmultiwindowclass.h" -#include "winprefs.h" -#include <X11/Xatom.h> - - -/* - * Constant defines - */ - -#ifndef ULW_COLORKEY -#define ULW_COLORKEY 0x00000001 -#endif -#ifndef ULW_ALPHA -#define ULW_ALPHA 0x00000002 -#endif -#ifndef ULW_OPAQUE -#define ULW_OPAQUE 0x00000004 -#endif -#define AC_SRC_ALPHA 0x01 - -/* - * Local function - */ - -DEFINE_ATOM_HELPER(AtmWindowsWmNativeHwnd, WINDOWSWM_NATIVE_HWND) -static void -winMWExtWMSetNativeProperty (RootlessWindowPtr pFrame); - -/* - * Global variables - */ - -Bool g_fNoConfigureWindow = FALSE; - -/* - * Internal function to get the DIB format that is compatible with the screen - * Fixme: Share code with winshadgdi.c - */ - -static -Bool -winMWExtWMQueryDIBFormat (win32RootlessWindowPtr pRLWinPriv, BITMAPINFOHEADER *pbmih) -{ - HBITMAP hbmp; -#if CYGMULTIWINDOW_DEBUG - LPDWORD pdw = NULL; -#endif - - /* Create a memory bitmap compatible with the screen */ - hbmp = CreateCompatibleBitmap (pRLWinPriv->hdcScreen, 1, 1); - if (hbmp == NULL) - { - ErrorF ("winMWExtWMQueryDIBFormat - CreateCompatibleBitmap failed\n"); - return FALSE; - } - - /* Initialize our bitmap info header */ - ZeroMemory (pbmih, sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD)); - pbmih->biSize = sizeof (BITMAPINFOHEADER); - - /* Get the biBitCount */ - if (!GetDIBits (pRLWinPriv->hdcScreen, - hbmp, - 0, 1, - NULL, - (BITMAPINFO*) pbmih, - DIB_RGB_COLORS)) - { - ErrorF ("winMWExtWMQueryDIBFormat - First call to GetDIBits failed\n"); - DeleteObject (hbmp); - return FALSE; - } - -#if CYGMULTIWINDOW_DEBUG - /* Get a pointer to bitfields */ - pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER)); - - winDebug ("winMWExtWMQueryDIBFormat - First call masks: %08x %08x %08x\n", - (unsigned int)pdw[0], (unsigned int)pdw[1], (unsigned int)pdw[2]); -#endif - - /* Get optimal color table, or the optimal bitfields */ - if (!GetDIBits (pRLWinPriv->hdcScreen, - hbmp, - 0, 1, - NULL, - (BITMAPINFO*)pbmih, - DIB_RGB_COLORS)) - { - ErrorF ("winMWExtWMQueryDIBFormat - Second call to GetDIBits " - "failed\n"); - DeleteObject (hbmp); - return FALSE; - } - - /* Free memory */ - DeleteObject (hbmp); - - return TRUE; -} - -static HRGN -winMWExtWMCreateRgnFromRegion (RegionPtr pShape) -{ - int nRects; - BoxPtr pRects, pEnd; - HRGN hRgn, hRgnRect; - - if (pShape == NULL) return NULL; - - nRects = REGION_NUM_RECTS(pShape); - pRects = REGION_RECTS(pShape); - - hRgn = CreateRectRgn (0, 0, 0, 0); - if (hRgn == NULL) - { - ErrorF ("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) " - "failed: %d\n", - 0, 0, 0, 0, (int) GetLastError ()); - } - - /* Loop through all rectangles in the X region */ - for (pEnd = pRects + nRects; pRects < pEnd; pRects++) - { - /* Create a Windows region for the X rectangle */ - hRgnRect = CreateRectRgn (pRects->x1, - pRects->y1, - pRects->x2, - pRects->y2); - if (hRgnRect == NULL) - { - ErrorF ("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) " - "failed: %d\n", - pRects->x1, - pRects->y1, - pRects->x2, - pRects->y2, - (int) GetLastError ()); - } - - /* Merge the Windows region with the accumulated region */ - if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) - { - ErrorF ("winReshape - CombineRgn () failed: %d\n", - (int) GetLastError ()); - } - - /* Delete the temporary Windows region */ - DeleteObject (hRgnRect); - } - - return hRgn; -} - -static void -InitWin32RootlessEngine (win32RootlessWindowPtr pRLWinPriv) -{ - pRLWinPriv->hdcScreen = GetDC (pRLWinPriv->hWnd); - pRLWinPriv->hdcShadow = CreateCompatibleDC (pRLWinPriv->hdcScreen); - pRLWinPriv->hbmpShadow = NULL; - - /* Allocate bitmap info header */ - pRLWinPriv->pbmihShadow = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER) - + 256 * sizeof (RGBQUAD)); - if (pRLWinPriv->pbmihShadow == NULL) - { - ErrorF ("InitWin32RootlessEngine - malloc () failed\n"); - return; - } - - /* Query the screen format */ - winMWExtWMQueryDIBFormat (pRLWinPriv, - pRLWinPriv->pbmihShadow); -} - -Bool -winMWExtWMCreateFrame (RootlessWindowPtr pFrame, ScreenPtr pScreen, - int newX, int newY, RegionPtr pShape) -{ -#define CLASS_NAME_LENGTH 512 - Bool fResult = TRUE; - win32RootlessWindowPtr pRLWinPriv; - WNDCLASSEX wc; - char pszClass[CLASS_NAME_LENGTH], pszWindowID[12]; - HICON hIcon; - HICON hIconSmall; - char *res_name, *res_class, *res_role; - static int s_iWindowID = 0; - -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMCreateFrame %d %d - %d %d\n", - newX, newY, pFrame->width, pFrame->height); -#endif - - pRLWinPriv = (win32RootlessWindowPtr) malloc (sizeof (win32RootlessWindowRec)); - pRLWinPriv->pFrame = pFrame; - pRLWinPriv->pfb = NULL; - pRLWinPriv->hbmpShadow = NULL; - pRLWinPriv->hdcShadow = NULL; - pRLWinPriv->hdcScreen = NULL; - pRLWinPriv->pbmihShadow = NULL; - pRLWinPriv->fResized = TRUE; - pRLWinPriv->fClose = FALSE; - pRLWinPriv->fRestackingNow = FALSE; - pRLWinPriv->fDestroyed = FALSE; - pRLWinPriv->fMovingOrSizing = FALSE; - - // Store the implementation private frame ID - pFrame->wid = (RootlessFrameID) pRLWinPriv; - - winSelectIcons(pFrame->win, &hIcon, &hIconSmall); - - /* Set standard class name prefix so we can identify window easily */ - strncpy (pszClass, WINDOW_CLASS_X, sizeof(pszClass)); - - if (winMultiWindowGetClassHint (pFrame->win, &res_name, &res_class)) - { - strncat (pszClass, "-", 1); - strncat (pszClass, res_name, CLASS_NAME_LENGTH - strlen (pszClass)); - strncat (pszClass, "-", 1); - strncat (pszClass, res_class, CLASS_NAME_LENGTH - strlen (pszClass)); - - /* Check if a window class is provided by the WM_WINDOW_ROLE property, - * if not use the WM_CLASS information. - * For further information see: - * http://tronche.com/gui/x/icccm/sec-5.html - */ - if (winMultiWindowGetWindowRole (pFrame->win, &res_role) ) - { - strcat (pszClass, "-"); - strcat (pszClass, res_role); - free (res_role); - } - - free (res_name); - free (res_class); - } - - /* Add incrementing window ID to make unique class name */ - snprintf (pszWindowID, sizeof(pszWindowID), "-%x", s_iWindowID++); - pszWindowID[sizeof(pszWindowID)-1] = 0; - strcat (pszClass, pszWindowID); - -#if CYGMULTIWINDOW_DEBUG - winDebug ("winCreateWindowsWindow - Creating class: %s\n", pszClass); -#endif - - /* Setup our window class */ - wc.cbSize = sizeof(wc); - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = winMWExtWMWindowProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = g_hInstance; - wc.hIcon = hIcon; - wc.hIconSm = hIconSmall; - wc.hCursor = 0; - wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); - wc.lpszMenuName = NULL; - wc.lpszClassName = pszClass; - RegisterClassEx (&wc); - - /* Create the window */ - g_fNoConfigureWindow = TRUE; - pRLWinPriv->hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */ - pszClass, /* Class name */ - WINDOW_TITLE_X, /* Window name */ - WS_POPUP | WS_CLIPCHILDREN, - newX, /* Horizontal position */ - newY, /* Vertical position */ - pFrame->width, /* Right edge */ - pFrame->height, /* Bottom edge */ - (HWND) NULL, /* No parent or owner window */ - (HMENU) NULL, /* No menu */ - GetModuleHandle (NULL), /* Instance handle */ - pRLWinPriv); /* ScreenPrivates */ - if (pRLWinPriv->hWnd == NULL) - { - ErrorF ("winMWExtWMCreateFrame - CreateWindowExA () failed: %d\n", - (int) GetLastError ()); - fResult = FALSE; - } - - winDebug ("winMWExtWMCreateFrame - ShowWindow\n"); - - //ShowWindow (pRLWinPriv->hWnd, SW_SHOWNOACTIVATE); - g_fNoConfigureWindow = FALSE; - - if (pShape != NULL) - { - winMWExtWMReshapeFrame (pFrame->wid, pShape); - } - -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMCreateFrame - (%08x) %08x\n", - (int) pFrame->wid, (int) pRLWinPriv->hWnd); -#if 0 - { - WindowPtr pWin2 = NULL; - win32RootlessWindowPtr pRLWinPriv2 = NULL; - - /* Check if the Windows window property for our X window pointer is valid */ - if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) - { - pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE); - } - winDebug ("winMWExtWMCreateFrame2 (%08x) %08x\n", - pRLWinPriv2, pRLWinPriv2->hWnd); - if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) - { - winDebug ("Error param missmatch\n"); - } - } -#endif -#endif - - winMWExtWMSetNativeProperty (pFrame); - - return fResult; -} - -void -winMWExtWMDestroyFrame (RootlessFrameID wid) -{ - win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; - HICON hiconClass; - HICON hiconSmClass; - HMODULE hInstance; - int iReturn; - char pszClass[CLASS_NAME_LENGTH]; - -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMDestroyFrame (%08x) %08x\n", - (int) pRLWinPriv, (int) pRLWinPriv->hWnd); -#if 0 - { - WindowPtr pWin2 = NULL; - win32RootlessWindowPtr pRLWinPriv2 = NULL; - - /* Check if the Windows window property for our X window pointer is valid */ - if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) - { - pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE); - } - winDebug ("winMWExtWMDestroyFrame2 (%08x) %08x\n", - pRLWinPriv2, pRLWinPriv2->hWnd); - if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) - { - winDebug ("Error param missmatch\n"); - *(int*)0 = 1;//raise exseption - } - } -#endif -#endif - - /* Store the info we need to destroy after this window is gone */ - hInstance = (HINSTANCE) GetClassLongPtr (pRLWinPriv->hWnd, GCLP_HMODULE); - hiconClass = (HICON) GetClassLongPtr (pRLWinPriv->hWnd, GCLP_HICON); - hiconSmClass = (HICON) GetClassLongPtr (pRLWinPriv->hWnd, GCLP_HICONSM); - iReturn = GetClassName (pRLWinPriv->hWnd, pszClass, CLASS_NAME_LENGTH); - - pRLWinPriv->fClose = TRUE; - pRLWinPriv->fDestroyed = TRUE; - - /* Destroy the Windows window */ - DestroyWindow (pRLWinPriv->hWnd); - - /* Only if we were able to get the name */ - if (iReturn) - { -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMDestroyFrame - Unregistering %s: ", pszClass); -#endif - iReturn = UnregisterClass (pszClass, hInstance); - -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMDestroyFramew - %d Deleting Icon: ", iReturn); -#endif - - winDestroyIcon(hiconClass); - winDestroyIcon(hiconSmClass); - } - -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMDestroyFrame - done\n"); -#endif -} - -void -winMWExtWMMoveFrame (RootlessFrameID wid, ScreenPtr pScreen, int iNewX, int iNewY) -{ - win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; - RECT rcNew; - DWORD dwExStyle; - DWORD dwStyle; - int iX, iY, iWidth, iHeight; - -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMMoveFrame (%08x) (%d %d)\n", (int) pRLWinPriv, iNewX, iNewY); -#endif - - /* Get the Windows window style and extended style */ - dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE); - dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE); - - /* Get the X and Y location of the X window */ - iX = iNewX + GetSystemMetrics (SM_XVIRTUALSCREEN); - iY = iNewY + GetSystemMetrics (SM_YVIRTUALSCREEN); - - /* Get the height and width of the X window */ - iWidth = pRLWinPriv->pFrame->width; - iHeight = pRLWinPriv->pFrame->height; - - /* Store the origin, height, and width in a rectangle structure */ - SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight); - -#ifdef CYGMULTIWINDOW_DEBUG - winDebug("\tWindow {%d, %d, %d, %d}, {%d, %d}\n", - rcNew.left, rcNew.top, rcNew.right, rcNew.bottom, - rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); -#endif - /* - * Calculate the required size of the Windows window rectangle, - * given the size of the Windows window client area. - */ - AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle); - -#ifdef CYGMULTIWINDOW_DEBUG - winDebug("\tAdjusted {%d, %d, %d, %d}, {%d, %d}\n", - rcNew.left, rcNew.top, rcNew.right, rcNew.bottom, - rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); -#endif - g_fNoConfigureWindow = TRUE; - SetWindowPos (pRLWinPriv->hWnd, NULL, rcNew.left, rcNew.top, 0, 0, - SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER); - g_fNoConfigureWindow = FALSE; -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMMoveFrame (%08x) done\n", (int) pRLWinPriv); -#endif -} - -void -winMWExtWMResizeFrame (RootlessFrameID wid, ScreenPtr pScreen, - int iNewX, int iNewY, - unsigned int uiNewWidth, unsigned int uiNewHeight, - unsigned int uiGravity) -{ - win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; - RECT rcNew; - RECT rcOld; - DWORD dwExStyle; - DWORD dwStyle; - int iX, iY; - -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMResizeFrame (%08x) (%d %d)-(%d %d)\n", - (int) pRLWinPriv, iNewX, iNewY, uiNewWidth, uiNewHeight); -#endif - - pRLWinPriv->fResized = TRUE; - - /* Get the Windows window style and extended style */ - dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE); - dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE); - - /* Get the X and Y location of the X window */ - iX = iNewX + GetSystemMetrics (SM_XVIRTUALSCREEN); - iY = iNewY + GetSystemMetrics (SM_YVIRTUALSCREEN); - - /* Store the origin, height, and width in a rectangle structure */ - SetRect (&rcNew, iX, iY, iX + uiNewWidth, iY + uiNewHeight); - - /* - * Calculate the required size of the Windows window rectangle, - * given the size of the Windows window client area. - */ - AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle); - - /* Get a rectangle describing the old Windows window */ - GetWindowRect (pRLWinPriv->hWnd, &rcOld); - - /* Check if the old rectangle and new rectangle are the same */ - if (!EqualRect (&rcNew, &rcOld)) - { - - g_fNoConfigureWindow = TRUE; - MoveWindow (pRLWinPriv->hWnd, - rcNew.left, rcNew.top, - rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, - TRUE); - g_fNoConfigureWindow = FALSE; - } -} - -void -winMWExtWMRestackFrame (RootlessFrameID wid, RootlessFrameID nextWid) -{ - win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; - win32RootlessWindowPtr pRLNextWinPriv = (win32RootlessWindowPtr) nextWid; - winScreenPriv(pRLWinPriv->pFrame->win->drawable.pScreen); - winScreenInfo *pScreenInfo = NULL; - DWORD dwCurrentProcessID = GetCurrentProcessId (); - DWORD dwWindowProcessID = 0; - HWND hWnd; - Bool fFirst = TRUE; - Bool fNeedRestack = TRUE; -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMRestackFrame (%08x)\n", (int) pRLWinPriv); -#endif - - if (pScreenPriv->fRestacking) return; - - if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; - - pRLWinPriv->fRestackingNow = TRUE; - - /* Show window */ - if(!IsWindowVisible (pRLWinPriv->hWnd)) - ShowWindow (pRLWinPriv->hWnd, SW_SHOWNOACTIVATE); - - if (pRLNextWinPriv == NULL) - { -#if CYGMULTIWINDOW_DEBUG - winDebug ("Win %08x is top\n", pRLWinPriv); -#endif - pScreenPriv->widTop = wid; - SetWindowPos (pRLWinPriv->hWnd, HWND_TOP, - 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); - } - else if (winIsInternalWMRunning(pScreenInfo)) - { - /* using mulwinidow wm */ -#if CYGMULTIWINDOW_DEBUG - winDebug ("Win %08x is not top\n", pRLWinPriv); -#endif - for (hWnd = GetNextWindow (pRLWinPriv->hWnd, GW_HWNDPREV); - fNeedRestack && hWnd != NULL; - hWnd = GetNextWindow (hWnd, GW_HWNDPREV)) - { - GetWindowThreadProcessId (hWnd, &dwWindowProcessID); - - if ((dwWindowProcessID == dwCurrentProcessID) - && GetProp (hWnd, WIN_WINDOW_PROP)) - { - if (hWnd == pRLNextWinPriv->hWnd) - { - /* Enable interleave X window and Windows window */ - if (!fFirst) - { -#if CYGMULTIWINDOW_DEBUG - winDebug ("raise: Insert after Win %08x\n", pRLNextWinPriv); -#endif - SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd, - 0, 0, 0, 0, - SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); - } - else - { -#if CYGMULTIWINDOW_DEBUG - winDebug ("No change\n"); -#endif - } - fNeedRestack = FALSE; - break; - } - if (fFirst) fFirst = FALSE; - } - } - - for (hWnd = GetNextWindow (pRLWinPriv->hWnd, GW_HWNDNEXT); - fNeedRestack && hWnd != NULL; - hWnd = GetNextWindow (hWnd, GW_HWNDNEXT)) - { - GetWindowThreadProcessId (hWnd, &dwWindowProcessID); - - if ((dwWindowProcessID == dwCurrentProcessID) - && GetProp (hWnd, WIN_WINDOW_PROP)) - { - if (hWnd == pRLNextWinPriv->hWnd) - { -#if CYGMULTIWINDOW_DEBUG - winDebug ("lower: Insert after Win %08x\n", pRLNextWinPriv); -#endif - SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd, - 0, 0, 0, 0, - SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); - fNeedRestack = FALSE; - break; - } - } - } - } - else - { - /* using general wm like twm, wmaker etc. - Interleave X window and Windows window will cause problem. */ - SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd, - 0, 0, 0, 0, - SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); -#if 0 -#endif - } -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMRestackFrame - done (%08x)\n", (int) pRLWinPriv); -#endif - - pRLWinPriv->fRestackingNow = FALSE; -} - -void -winMWExtWMReshapeFrame (RootlessFrameID wid, RegionPtr pShape) -{ - win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; - HRGN hRgn, hRgnWindow, hRgnClient; - RECT rcWindow, rcClient; -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMReshapeFrame (%08x)\n", (int) pRLWinPriv); -#endif - - hRgn = winMWExtWMCreateRgnFromRegion (pShape); - - /* Create region for non-client area */ - GetWindowRect (pRLWinPriv->hWnd, &rcWindow); - GetClientRect (pRLWinPriv->hWnd, &rcClient); - MapWindowPoints (pRLWinPriv->hWnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2); - OffsetRgn (hRgn, rcClient.left - rcWindow.left, rcClient.top - rcWindow.top); - OffsetRect (&rcClient, -rcWindow.left, -rcWindow.top); - OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top); - hRgnWindow = CreateRectRgnIndirect (&rcWindow); - hRgnClient = CreateRectRgnIndirect (&rcClient); - CombineRgn (hRgnWindow, hRgnWindow, hRgnClient, RGN_DIFF); - CombineRgn (hRgn, hRgnWindow, hRgn, RGN_OR); - - - SetWindowRgn (pRLWinPriv->hWnd, hRgn, TRUE); - - DeleteObject (hRgnWindow); - DeleteObject (hRgnClient); -} - -void -winMWExtWMUnmapFrame (RootlessFrameID wid) -{ - win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMUnmapFrame (%08x)\n", (int) pRLWinPriv); -#endif - - g_fNoConfigureWindow = TRUE; - //ShowWindow (pRLWinPriv->hWnd, SW_MINIMIZE); - ShowWindow (pRLWinPriv->hWnd, SW_HIDE); - g_fNoConfigureWindow = FALSE; -} - -/* - * Fixme: Code sharing with winshadgdi.c and other engine support - */ -void -winMWExtWMStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow) -{ - win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; - winPrivScreenPtr pScreenPriv = NULL; - winScreenInfo *pScreenInfo = NULL; - ScreenPtr pScreen = NULL; - DIBSECTION dibsection; - Bool fReturn = TRUE; - HDC hdcNew; - HBITMAP hbmpNew; -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMStartDrawing (%08x) %08x\n", (int) pRLWinPriv, pRLWinPriv->fDestroyed); -#endif - - if (!pRLWinPriv->fDestroyed) - { - pScreen = pRLWinPriv->pFrame->win->drawable.pScreen; - if (pScreen) pScreenPriv = winGetScreenPriv(pScreen); - if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; - -#if CYGMULTIWINDOW_DEBUG - winDebug ("\tpScreenPriv %08X\n", (int) pScreenPriv); - winDebug ("\tpScreenInfo %08X\n", (int) pScreenInfo); - winDebug ("\t(%d, %d)\n", (int)pRLWinPriv->pFrame->width, - (int) pRLWinPriv->pFrame->height); -#endif - if (pRLWinPriv->hdcScreen == NULL) - { - InitWin32RootlessEngine (pRLWinPriv); - } - - if (pRLWinPriv->fResized) - { - /* width * bpp must be multiple of 4 to match 32bit alignment */ - int stridesize; - int misalignment; - - pRLWinPriv->pbmihShadow->biWidth = pRLWinPriv->pFrame->width; - pRLWinPriv->pbmihShadow->biHeight = -pRLWinPriv->pFrame->height; - - stridesize = pRLWinPriv->pFrame->width * (pScreenInfo->dwBPP >> 3); - misalignment = stridesize & 3; - if (misalignment != 0) - { - stridesize += 4 - misalignment; - pRLWinPriv->pbmihShadow->biWidth = stridesize / (pScreenInfo->dwBPP >> 3); - winDebug("\tresizing to %d (was %d)\n", - pRLWinPriv->pbmihShadow->biWidth, pRLWinPriv->pFrame->width); - } - - hdcNew = CreateCompatibleDC (pRLWinPriv->hdcScreen); - /* Create a DI shadow bitmap with a bit pointer */ - hbmpNew = CreateDIBSection (pRLWinPriv->hdcScreen, - (BITMAPINFO *) pRLWinPriv->pbmihShadow, - DIB_RGB_COLORS, - (VOID**) &pRLWinPriv->pfb, - NULL, - 0); - if (hbmpNew == NULL || pRLWinPriv->pfb == NULL) - { - ErrorF ("winMWExtWMStartDrawing - CreateDIBSection failed\n"); - //return FALSE; - } - else - { -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMStartDrawing - Shadow buffer allocated\n"); -#endif - } - - /* Get information about the bitmap that was allocated */ - GetObject (hbmpNew, sizeof (dibsection), &dibsection); - -#if CYGMULTIWINDOW_DEBUG - /* Print information about bitmap allocated */ - winDebug ("winMWExtWMStartDrawing - Dibsection width: %d height: %d " - "depth: %d size image: %d\n", - (unsigned int)dibsection.dsBmih.biWidth, - (unsigned int)dibsection.dsBmih.biHeight, - (unsigned int)dibsection.dsBmih.biBitCount, - (unsigned int)dibsection.dsBmih.biSizeImage); -#endif - - /* Select the shadow bitmap into the shadow DC */ - SelectObject (hdcNew, hbmpNew); - -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMStartDrawing - Attempting a shadow blit\n"); -#endif - - /* Blit from the old shadow to the new shadow */ - fReturn = BitBlt (hdcNew, - 0, 0, - pRLWinPriv->pFrame->width, pRLWinPriv->pFrame->height, - pRLWinPriv->hdcShadow, - 0, 0, - SRCCOPY); - if (fReturn) - { - winDebug ("winMWExtWMStartDrawing - Shadow blit success\n"); - } - else - { - ErrorF ("winMWExtWMStartDrawing - Shadow blit failure\n"); - } - - /* Look for height weirdness */ - if (dibsection.dsBmih.biHeight < 0) - { - /* FIXME: Figure out why biHeight is sometimes negative */ - ErrorF ("winMWExtWMStartDrawing - WEIRDNESS - " - "biHeight still negative: %d\n", - (int) dibsection.dsBmih.biHeight); - ErrorF ("winMWExtWMStartDrawing - WEIRDNESS - " - "Flipping biHeight sign\n"); - dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight; - } - - pRLWinPriv->dwWidthBytes = dibsection.dsBm.bmWidthBytes; - - winDebug ("winMWExtWMStartDrawing - bytesPerRow: %d\n", - (unsigned int)dibsection.dsBm.bmWidthBytes); - - /* Free the old shadow bitmap */ - DeleteObject (pRLWinPriv->hdcShadow); - DeleteObject (pRLWinPriv->hbmpShadow); - - pRLWinPriv->hdcShadow = hdcNew; - pRLWinPriv->hbmpShadow = hbmpNew; - - pRLWinPriv->fResized = FALSE; - winDebug ("winMWExtWMStartDrawing - 0x%08x %d\n", - (unsigned int)pRLWinPriv->pfb, - (unsigned int)dibsection.dsBm.bmWidthBytes); - } - } - else - { - ErrorF ("winMWExtWMStartDrawing - Already window was destroyed \n"); - } - winDebug ("winMWExtWMStartDrawing - done (0x%08x) 0x%08x %d\n", - (int) pRLWinPriv, - (unsigned int)pRLWinPriv->pfb, (unsigned int)pRLWinPriv->dwWidthBytes); - *pixelData = pRLWinPriv->pfb; - *bytesPerRow = pRLWinPriv->dwWidthBytes; -} - -void -winMWExtWMStopDrawing (RootlessFrameID wid, Bool fFlush) -{ -} - -void -winMWExtWMUpdateRegion (RootlessFrameID wid, RegionPtr pDamage) -{ - win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; - if (!g_fNoConfigureWindow) UpdateWindow (pRLWinPriv->hWnd); -} - -void -winMWExtWMDamageRects (RootlessFrameID wid, int nCount, const BoxRec *pRects, - int shift_x, int shift_y) -{ - win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; - const BoxRec *pEnd; - winDebug ("winMWExtWMDamageRects (%08x, %d, %08x, %d, %d)\n", - pRLWinPriv, nCount, pRects, shift_x, shift_y); - - for (pEnd = pRects + nCount; pRects < pEnd; pRects++) { - RECT rcDmg; - rcDmg.left = pRects->x1 + shift_x; - rcDmg.top = pRects->y1 + shift_y; - rcDmg.right = pRects->x2 + shift_x; - rcDmg.bottom = pRects->y2 + shift_y; - - InvalidateRect (pRLWinPriv->hWnd, &rcDmg, FALSE); - } -} - -void -winMWExtWMRootlessSwitchWindow (RootlessWindowPtr pFrame, WindowPtr oldWin) -{ - win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid; - winDebug ("winMWExtWMRootlessSwitchWindow (%08x) %08x\n", - (int) pRLWinPriv, (int) pRLWinPriv->hWnd); - pRLWinPriv->pFrame = pFrame; - pRLWinPriv->fResized = TRUE; - - /* Set the window extended style flags */ - SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW); - - /* Set the window standard style flags */ - SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE, - WS_POPUP | WS_CLIPCHILDREN); - - DeleteProperty (serverClient, oldWin, AtmWindowsWmNativeHwnd ()); - winMWExtWMSetNativeProperty (pFrame); -} - -void -winMWExtWMCopyBytes (unsigned int width, unsigned int height, - const void *src, unsigned int srcRowBytes, - void *dst, unsigned int dstRowBytes) -{ - winDebug ("winMWExtWMCopyBytes - Not implemented\n"); -} - -void -winMWExtWMFillBytes (unsigned int width, unsigned int height, unsigned int value, - void *dst, unsigned int dstRowBytes) -{ - winDebug ("winMWExtWMFillBytes - Not implemented\n"); -} - -int -winMWExtWMCompositePixels (unsigned int width, unsigned int height, unsigned int function, - void *src[2], unsigned int srcRowBytes[2], - void *mask, unsigned int maskRowBytes, - void *dst[2], unsigned int dstRowBytes[2]) -{ - winDebug ("winMWExtWMCompositePixels - Not implemented\n"); - return 0; -} - - -void -winMWExtWMCopyWindow (RootlessFrameID wid, int nDstRects, const BoxRec *pDstRects, - int nDx, int nDy) -{ - win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; - const BoxRec *pEnd; - RECT rcDmg; - winDebug ("winMWExtWMCopyWindow (%08x, %d, %08x, %d, %d)\n", - (int) pRLWinPriv, nDstRects, (int) pDstRects, nDx, nDy); - - for (pEnd = pDstRects + nDstRects; pDstRects < pEnd; pDstRects++) - { - winDebug ("BitBlt (%d, %d, %d, %d) (%d, %d)\n", - pDstRects->x1, pDstRects->y1, - pDstRects->x2 - pDstRects->x1, - pDstRects->y2 - pDstRects->y1, - pDstRects->x1 + nDx, - pDstRects->y1 + nDy); - - if (!BitBlt (pRLWinPriv->hdcShadow, - pDstRects->x1, pDstRects->y1, - pDstRects->x2 - pDstRects->x1, - pDstRects->y2 - pDstRects->y1, - pRLWinPriv->hdcShadow, - pDstRects->x1 + nDx, pDstRects->y1 + nDy, - SRCCOPY)) - { - ErrorF ("winMWExtWMCopyWindow - BitBlt failed.\n"); - } - - rcDmg.left = pDstRects->x1; - rcDmg.top = pDstRects->y1; - rcDmg.right = pDstRects->x2; - rcDmg.bottom = pDstRects->y2; - - InvalidateRect (pRLWinPriv->hWnd, &rcDmg, FALSE); - } - winDebug ("winMWExtWMCopyWindow - done\n"); -} - - -/* - * winMWExtWMSetNativeProperty - */ - -static void -winMWExtWMSetNativeProperty (RootlessWindowPtr pFrame) -{ - win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid; - long lData; - - /* FIXME: move this to WindowsWM extension */ - - lData = (long) pRLWinPriv->hWnd; - dixChangeWindowProperty(serverClient, pFrame->win, AtmWindowsWmNativeHwnd(), - XA_INTEGER, 32, PropModeReplace, 1, &lData, TRUE); -} +/*
+ *Copyright (C) 1994-2000 The XFree86 Project, 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, sublicense, and/or sell copies of the Software, and to
+ *permit persons to whom the Software is furnished to do so, subject to
+ *the following conditions:
+ *
+ *The above copyright notice and this permission notice shall be
+ *included in all copies or substantial portions of the Software.
+ *
+ *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. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
+ *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *Except as contained in this notice, the name of the XFree86 Project
+ *shall not be used in advertising or otherwise to promote the sale, use
+ *or other dealings in this Software without prior written authorization
+ *from the XFree86 Project.
+ *
+ * Authors: Kensuke Matsuzaki
+ * Earle F. Philhower, III
+ * Harold L Hunt II
+ */
+/*
+ * Look at hw/darwin/quartz/xpr/xprFrame.c and hw/darwin/quartz/cr/crFrame.c
+ */
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+#include <winuser.h>
+#define _WINDOWSWM_SERVER_
+#include <X11/extensions/windowswmstr.h>
+#include "dixevents.h"
+#include "winmultiwindowclass.h"
+#include "winprefs.h"
+#include <X11/Xatom.h>
+
+
+/*
+ * Constant defines
+ */
+
+#ifndef ULW_COLORKEY
+#define ULW_COLORKEY 0x00000001
+#endif
+#ifndef ULW_ALPHA
+#define ULW_ALPHA 0x00000002
+#endif
+#ifndef ULW_OPAQUE
+#define ULW_OPAQUE 0x00000004
+#endif
+#define AC_SRC_ALPHA 0x01
+
+/*
+ * Local function
+ */
+
+DEFINE_ATOM_HELPER(AtmWindowsWmNativeHwnd, WINDOWSWM_NATIVE_HWND)
+static void
+winMWExtWMSetNativeProperty (RootlessWindowPtr pFrame);
+
+/*
+ * Global variables
+ */
+
+Bool g_fNoConfigureWindow = FALSE;
+
+/*
+ * Internal function to get the DIB format that is compatible with the screen
+ * Fixme: Share code with winshadgdi.c
+ */
+
+static
+Bool
+winMWExtWMQueryDIBFormat (win32RootlessWindowPtr pRLWinPriv, BITMAPINFOHEADER *pbmih)
+{
+ HBITMAP hbmp;
+#if CYGMULTIWINDOW_DEBUG
+ LPDWORD pdw = NULL;
+#endif
+
+ /* Create a memory bitmap compatible with the screen */
+ hbmp = CreateCompatibleBitmap (pRLWinPriv->hdcScreen, 1, 1);
+ if (hbmp == NULL)
+ {
+ ErrorF ("winMWExtWMQueryDIBFormat - CreateCompatibleBitmap failed\n");
+ return FALSE;
+ }
+
+ /* Initialize our bitmap info header */
+ ZeroMemory (pbmih, sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD));
+ pbmih->biSize = sizeof (BITMAPINFOHEADER);
+
+ /* Get the biBitCount */
+ if (!GetDIBits (pRLWinPriv->hdcScreen,
+ hbmp,
+ 0, 1,
+ NULL,
+ (BITMAPINFO*) pbmih,
+ DIB_RGB_COLORS))
+ {
+ ErrorF ("winMWExtWMQueryDIBFormat - First call to GetDIBits failed\n");
+ DeleteObject (hbmp);
+ return FALSE;
+ }
+
+#if CYGMULTIWINDOW_DEBUG
+ /* Get a pointer to bitfields */
+ pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER));
+
+ winDebug ("winMWExtWMQueryDIBFormat - First call masks: %08x %08x %08x\n",
+ (unsigned int)pdw[0], (unsigned int)pdw[1], (unsigned int)pdw[2]);
+#endif
+
+ /* Get optimal color table, or the optimal bitfields */
+ if (!GetDIBits (pRLWinPriv->hdcScreen,
+ hbmp,
+ 0, 1,
+ NULL,
+ (BITMAPINFO*)pbmih,
+ DIB_RGB_COLORS))
+ {
+ ErrorF ("winMWExtWMQueryDIBFormat - Second call to GetDIBits "
+ "failed\n");
+ DeleteObject (hbmp);
+ return FALSE;
+ }
+
+ /* Free memory */
+ DeleteObject (hbmp);
+
+ return TRUE;
+}
+
+static HRGN
+winMWExtWMCreateRgnFromRegion (RegionPtr pShape)
+{
+ int nRects;
+ BoxPtr pRects, pEnd;
+ HRGN hRgn, hRgnRect;
+
+ if (pShape == NULL) return NULL;
+
+ nRects = RegionNumRects(pShape);
+ pRects = RegionRects(pShape);
+
+ hRgn = CreateRectRgn (0, 0, 0, 0);
+ if (hRgn == NULL)
+ {
+ ErrorF ("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) "
+ "failed: %d\n",
+ 0, 0, 0, 0, (int) GetLastError ());
+ }
+
+ /* Loop through all rectangles in the X region */
+ for (pEnd = pRects + nRects; pRects < pEnd; pRects++)
+ {
+ /* Create a Windows region for the X rectangle */
+ hRgnRect = CreateRectRgn (pRects->x1,
+ pRects->y1,
+ pRects->x2,
+ pRects->y2);
+ if (hRgnRect == NULL)
+ {
+ ErrorF ("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) "
+ "failed: %d\n",
+ pRects->x1,
+ pRects->y1,
+ pRects->x2,
+ pRects->y2,
+ (int) GetLastError ());
+ }
+
+ /* Merge the Windows region with the accumulated region */
+ if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR)
+ {
+ ErrorF ("winReshape - CombineRgn () failed: %d\n",
+ (int) GetLastError ());
+ }
+
+ /* Delete the temporary Windows region */
+ DeleteObject (hRgnRect);
+ }
+
+ return hRgn;
+}
+
+static void
+InitWin32RootlessEngine (win32RootlessWindowPtr pRLWinPriv)
+{
+ pRLWinPriv->hdcScreen = GetDC (pRLWinPriv->hWnd);
+ pRLWinPriv->hdcShadow = CreateCompatibleDC (pRLWinPriv->hdcScreen);
+ pRLWinPriv->hbmpShadow = NULL;
+
+ /* Allocate bitmap info header */
+ pRLWinPriv->pbmihShadow = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER)
+ + 256 * sizeof (RGBQUAD));
+ if (pRLWinPriv->pbmihShadow == NULL)
+ {
+ ErrorF ("InitWin32RootlessEngine - malloc () failed\n");
+ return;
+ }
+
+ /* Query the screen format */
+ winMWExtWMQueryDIBFormat (pRLWinPriv,
+ pRLWinPriv->pbmihShadow);
+}
+
+Bool
+winMWExtWMCreateFrame (RootlessWindowPtr pFrame, ScreenPtr pScreen,
+ int newX, int newY, RegionPtr pShape)
+{
+#define CLASS_NAME_LENGTH 512
+ Bool fResult = TRUE;
+ win32RootlessWindowPtr pRLWinPriv;
+ WNDCLASSEX wc;
+ char pszClass[CLASS_NAME_LENGTH], pszWindowID[12];
+ HICON hIcon;
+ HICON hIconSmall;
+ char *res_name, *res_class, *res_role;
+ static int s_iWindowID = 0;
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMCreateFrame %d %d - %d %d\n",
+ newX, newY, pFrame->width, pFrame->height);
+#endif
+
+ pRLWinPriv = (win32RootlessWindowPtr) malloc (sizeof (win32RootlessWindowRec));
+ pRLWinPriv->pFrame = pFrame;
+ pRLWinPriv->pfb = NULL;
+ pRLWinPriv->hbmpShadow = NULL;
+ pRLWinPriv->hdcShadow = NULL;
+ pRLWinPriv->hdcScreen = NULL;
+ pRLWinPriv->pbmihShadow = NULL;
+ pRLWinPriv->fResized = TRUE;
+ pRLWinPriv->fClose = FALSE;
+ pRLWinPriv->fRestackingNow = FALSE;
+ pRLWinPriv->fDestroyed = FALSE;
+ pRLWinPriv->fMovingOrSizing = FALSE;
+
+ // Store the implementation private frame ID
+ pFrame->wid = (RootlessFrameID) pRLWinPriv;
+
+ winSelectIcons(pFrame->win, &hIcon, &hIconSmall);
+
+ /* Set standard class name prefix so we can identify window easily */
+ strncpy (pszClass, WINDOW_CLASS_X, sizeof(pszClass));
+
+ if (winMultiWindowGetClassHint (pFrame->win, &res_name, &res_class))
+ {
+ strncat (pszClass, "-", 1);
+ strncat (pszClass, res_name, CLASS_NAME_LENGTH - strlen (pszClass));
+ strncat (pszClass, "-", 1);
+ strncat (pszClass, res_class, CLASS_NAME_LENGTH - strlen (pszClass));
+
+ /* Check if a window class is provided by the WM_WINDOW_ROLE property,
+ * if not use the WM_CLASS information.
+ * For further information see:
+ * http://tronche.com/gui/x/icccm/sec-5.html
+ */
+ if (winMultiWindowGetWindowRole (pFrame->win, &res_role) )
+ {
+ strcat (pszClass, "-");
+ strcat (pszClass, res_role);
+ free (res_role);
+ }
+
+ free (res_name);
+ free (res_class);
+ }
+
+ /* Add incrementing window ID to make unique class name */
+ snprintf (pszWindowID, sizeof(pszWindowID), "-%x", s_iWindowID++);
+ pszWindowID[sizeof(pszWindowID)-1] = 0;
+ strcat (pszClass, pszWindowID);
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winCreateWindowsWindow - Creating class: %s\n", pszClass);
+#endif
+
+ /* Setup our window class */
+ wc.cbSize = sizeof(wc);
+ wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = winMWExtWMWindowProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = g_hInstance;
+ wc.hIcon = hIcon;
+ wc.hIconSm = hIconSmall;
+ wc.hCursor = 0;
+ wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = pszClass;
+ RegisterClassEx (&wc);
+
+ /* Create the window */
+ g_fNoConfigureWindow = TRUE;
+ pRLWinPriv->hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */
+ pszClass, /* Class name */
+ WINDOW_TITLE_X, /* Window name */
+ WS_POPUP | WS_CLIPCHILDREN,
+ newX, /* Horizontal position */
+ newY, /* Vertical position */
+ pFrame->width, /* Right edge */
+ pFrame->height, /* Bottom edge */
+ (HWND) NULL, /* No parent or owner window */
+ (HMENU) NULL, /* No menu */
+ GetModuleHandle (NULL), /* Instance handle */
+ pRLWinPriv); /* ScreenPrivates */
+ if (pRLWinPriv->hWnd == NULL)
+ {
+ ErrorF ("winMWExtWMCreateFrame - CreateWindowExA () failed: %d\n",
+ (int) GetLastError ());
+ fResult = FALSE;
+ }
+
+ winDebug ("winMWExtWMCreateFrame - ShowWindow\n");
+
+ //ShowWindow (pRLWinPriv->hWnd, SW_SHOWNOACTIVATE);
+ g_fNoConfigureWindow = FALSE;
+
+ if (pShape != NULL)
+ {
+ winMWExtWMReshapeFrame (pFrame->wid, pShape);
+ }
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMCreateFrame - (%08x) %08x\n",
+ (int) pFrame->wid, (int) pRLWinPriv->hWnd);
+#if 0
+ {
+ WindowPtr pWin2 = NULL;
+ win32RootlessWindowPtr pRLWinPriv2 = NULL;
+
+ /* Check if the Windows window property for our X window pointer is valid */
+ if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL)
+ {
+ pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE);
+ }
+ winDebug ("winMWExtWMCreateFrame2 (%08x) %08x\n",
+ pRLWinPriv2, pRLWinPriv2->hWnd);
+ if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd)
+ {
+ winDebug ("Error param missmatch\n");
+ }
+ }
+#endif
+#endif
+
+ winMWExtWMSetNativeProperty (pFrame);
+
+ return fResult;
+}
+
+void
+winMWExtWMDestroyFrame (RootlessFrameID wid)
+{
+ win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
+ HICON hiconClass;
+ HICON hiconSmClass;
+ HMODULE hInstance;
+ int iReturn;
+ char pszClass[CLASS_NAME_LENGTH];
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMDestroyFrame (%08x) %08x\n",
+ (int) pRLWinPriv, (int) pRLWinPriv->hWnd);
+#if 0
+ {
+ WindowPtr pWin2 = NULL;
+ win32RootlessWindowPtr pRLWinPriv2 = NULL;
+
+ /* Check if the Windows window property for our X window pointer is valid */
+ if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL)
+ {
+ pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE);
+ }
+ winDebug ("winMWExtWMDestroyFrame2 (%08x) %08x\n",
+ pRLWinPriv2, pRLWinPriv2->hWnd);
+ if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd)
+ {
+ winDebug ("Error param missmatch\n");
+ *(int*)0 = 1;//raise exseption
+ }
+ }
+#endif
+#endif
+
+ /* Store the info we need to destroy after this window is gone */
+ hInstance = (HINSTANCE) GetClassLongPtr (pRLWinPriv->hWnd, GCLP_HMODULE);
+ hiconClass = (HICON) GetClassLongPtr (pRLWinPriv->hWnd, GCLP_HICON);
+ hiconSmClass = (HICON) GetClassLongPtr (pRLWinPriv->hWnd, GCLP_HICONSM);
+ iReturn = GetClassName (pRLWinPriv->hWnd, pszClass, CLASS_NAME_LENGTH);
+
+ pRLWinPriv->fClose = TRUE;
+ pRLWinPriv->fDestroyed = TRUE;
+
+ /* Destroy the Windows window */
+ DestroyWindow (pRLWinPriv->hWnd);
+
+ /* Only if we were able to get the name */
+ if (iReturn)
+ {
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMDestroyFrame - Unregistering %s: ", pszClass);
+#endif
+ iReturn = UnregisterClass (pszClass, hInstance);
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMDestroyFramew - %d Deleting Icon: ", iReturn);
+#endif
+
+ winDestroyIcon(hiconClass);
+ winDestroyIcon(hiconSmClass);
+ }
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMDestroyFrame - done\n");
+#endif
+}
+
+void
+winMWExtWMMoveFrame (RootlessFrameID wid, ScreenPtr pScreen, int iNewX, int iNewY)
+{
+ win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
+ RECT rcNew;
+ DWORD dwExStyle;
+ DWORD dwStyle;
+ int iX, iY, iWidth, iHeight;
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMMoveFrame (%08x) (%d %d)\n", (int) pRLWinPriv, iNewX, iNewY);
+#endif
+
+ /* Get the Windows window style and extended style */
+ dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE);
+ dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE);
+
+ /* Get the X and Y location of the X window */
+ iX = iNewX + GetSystemMetrics (SM_XVIRTUALSCREEN);
+ iY = iNewY + GetSystemMetrics (SM_YVIRTUALSCREEN);
+
+ /* Get the height and width of the X window */
+ iWidth = pRLWinPriv->pFrame->width;
+ iHeight = pRLWinPriv->pFrame->height;
+
+ /* Store the origin, height, and width in a rectangle structure */
+ SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight);
+
+#ifdef CYGMULTIWINDOW_DEBUG
+ winDebug("\tWindow {%d, %d, %d, %d}, {%d, %d}\n",
+ rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
+ rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
+#endif
+ /*
+ * Calculate the required size of the Windows window rectangle,
+ * given the size of the Windows window client area.
+ */
+ AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle);
+
+#ifdef CYGMULTIWINDOW_DEBUG
+ winDebug("\tAdjusted {%d, %d, %d, %d}, {%d, %d}\n",
+ rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
+ rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
+#endif
+ g_fNoConfigureWindow = TRUE;
+ SetWindowPos (pRLWinPriv->hWnd, NULL, rcNew.left, rcNew.top, 0, 0,
+ SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
+ g_fNoConfigureWindow = FALSE;
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMMoveFrame (%08x) done\n", (int) pRLWinPriv);
+#endif
+}
+
+void
+winMWExtWMResizeFrame (RootlessFrameID wid, ScreenPtr pScreen,
+ int iNewX, int iNewY,
+ unsigned int uiNewWidth, unsigned int uiNewHeight,
+ unsigned int uiGravity)
+{
+ win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
+ RECT rcNew;
+ RECT rcOld;
+ DWORD dwExStyle;
+ DWORD dwStyle;
+ int iX, iY;
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMResizeFrame (%08x) (%d %d)-(%d %d)\n",
+ (int) pRLWinPriv, iNewX, iNewY, uiNewWidth, uiNewHeight);
+#endif
+
+ pRLWinPriv->fResized = TRUE;
+
+ /* Get the Windows window style and extended style */
+ dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE);
+ dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE);
+
+ /* Get the X and Y location of the X window */
+ iX = iNewX + GetSystemMetrics (SM_XVIRTUALSCREEN);
+ iY = iNewY + GetSystemMetrics (SM_YVIRTUALSCREEN);
+
+ /* Store the origin, height, and width in a rectangle structure */
+ SetRect (&rcNew, iX, iY, iX + uiNewWidth, iY + uiNewHeight);
+
+ /*
+ * Calculate the required size of the Windows window rectangle,
+ * given the size of the Windows window client area.
+ */
+ AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle);
+
+ /* Get a rectangle describing the old Windows window */
+ GetWindowRect (pRLWinPriv->hWnd, &rcOld);
+
+ /* Check if the old rectangle and new rectangle are the same */
+ if (!EqualRect (&rcNew, &rcOld))
+ {
+
+ g_fNoConfigureWindow = TRUE;
+ MoveWindow (pRLWinPriv->hWnd,
+ rcNew.left, rcNew.top,
+ rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
+ TRUE);
+ g_fNoConfigureWindow = FALSE;
+ }
+}
+
+void
+winMWExtWMRestackFrame (RootlessFrameID wid, RootlessFrameID nextWid)
+{
+ win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
+ win32RootlessWindowPtr pRLNextWinPriv = (win32RootlessWindowPtr) nextWid;
+ winScreenPriv(pRLWinPriv->pFrame->win->drawable.pScreen);
+ winScreenInfo *pScreenInfo = NULL;
+ DWORD dwCurrentProcessID = GetCurrentProcessId ();
+ DWORD dwWindowProcessID = 0;
+ HWND hWnd;
+ Bool fFirst = TRUE;
+ Bool fNeedRestack = TRUE;
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMRestackFrame (%08x)\n", (int) pRLWinPriv);
+#endif
+
+ if (pScreenPriv->fRestacking) return;
+
+ if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo;
+
+ pRLWinPriv->fRestackingNow = TRUE;
+
+ /* Show window */
+ if(!IsWindowVisible (pRLWinPriv->hWnd))
+ ShowWindow (pRLWinPriv->hWnd, SW_SHOWNOACTIVATE);
+
+ if (pRLNextWinPriv == NULL)
+ {
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("Win %08x is top\n", pRLWinPriv);
+#endif
+ pScreenPriv->widTop = wid;
+ SetWindowPos (pRLWinPriv->hWnd, HWND_TOP,
+ 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
+ }
+ else if (winIsInternalWMRunning(pScreenInfo))
+ {
+ /* using mulwinidow wm */
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("Win %08x is not top\n", pRLWinPriv);
+#endif
+ for (hWnd = GetNextWindow (pRLWinPriv->hWnd, GW_HWNDPREV);
+ fNeedRestack && hWnd != NULL;
+ hWnd = GetNextWindow (hWnd, GW_HWNDPREV))
+ {
+ GetWindowThreadProcessId (hWnd, &dwWindowProcessID);
+
+ if ((dwWindowProcessID == dwCurrentProcessID)
+ && GetProp (hWnd, WIN_WINDOW_PROP))
+ {
+ if (hWnd == pRLNextWinPriv->hWnd)
+ {
+ /* Enable interleave X window and Windows window */
+ if (!fFirst)
+ {
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("raise: Insert after Win %08x\n", pRLNextWinPriv);
+#endif
+ SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd,
+ 0, 0, 0, 0,
+ SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
+ }
+ else
+ {
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("No change\n");
+#endif
+ }
+ fNeedRestack = FALSE;
+ break;
+ }
+ if (fFirst) fFirst = FALSE;
+ }
+ }
+
+ for (hWnd = GetNextWindow (pRLWinPriv->hWnd, GW_HWNDNEXT);
+ fNeedRestack && hWnd != NULL;
+ hWnd = GetNextWindow (hWnd, GW_HWNDNEXT))
+ {
+ GetWindowThreadProcessId (hWnd, &dwWindowProcessID);
+
+ if ((dwWindowProcessID == dwCurrentProcessID)
+ && GetProp (hWnd, WIN_WINDOW_PROP))
+ {
+ if (hWnd == pRLNextWinPriv->hWnd)
+ {
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("lower: Insert after Win %08x\n", pRLNextWinPriv);
+#endif
+ SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd,
+ 0, 0, 0, 0,
+ SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
+ fNeedRestack = FALSE;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* using general wm like twm, wmaker etc.
+ Interleave X window and Windows window will cause problem. */
+ SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd,
+ 0, 0, 0, 0,
+ SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
+#if 0
+#endif
+ }
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMRestackFrame - done (%08x)\n", (int) pRLWinPriv);
+#endif
+
+ pRLWinPriv->fRestackingNow = FALSE;
+}
+
+void
+winMWExtWMReshapeFrame (RootlessFrameID wid, RegionPtr pShape)
+{
+ win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
+ HRGN hRgn, hRgnWindow, hRgnClient;
+ RECT rcWindow, rcClient;
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMReshapeFrame (%08x)\n", (int) pRLWinPriv);
+#endif
+
+ hRgn = winMWExtWMCreateRgnFromRegion (pShape);
+
+ /* Create region for non-client area */
+ GetWindowRect (pRLWinPriv->hWnd, &rcWindow);
+ GetClientRect (pRLWinPriv->hWnd, &rcClient);
+ MapWindowPoints (pRLWinPriv->hWnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2);
+ OffsetRgn (hRgn, rcClient.left - rcWindow.left, rcClient.top - rcWindow.top);
+ OffsetRect (&rcClient, -rcWindow.left, -rcWindow.top);
+ OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
+ hRgnWindow = CreateRectRgnIndirect (&rcWindow);
+ hRgnClient = CreateRectRgnIndirect (&rcClient);
+ CombineRgn (hRgnWindow, hRgnWindow, hRgnClient, RGN_DIFF);
+ CombineRgn (hRgn, hRgnWindow, hRgn, RGN_OR);
+
+
+ SetWindowRgn (pRLWinPriv->hWnd, hRgn, TRUE);
+
+ DeleteObject (hRgnWindow);
+ DeleteObject (hRgnClient);
+}
+
+void
+winMWExtWMUnmapFrame (RootlessFrameID wid)
+{
+ win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMUnmapFrame (%08x)\n", (int) pRLWinPriv);
+#endif
+
+ g_fNoConfigureWindow = TRUE;
+ //ShowWindow (pRLWinPriv->hWnd, SW_MINIMIZE);
+ ShowWindow (pRLWinPriv->hWnd, SW_HIDE);
+ g_fNoConfigureWindow = FALSE;
+}
+
+/*
+ * Fixme: Code sharing with winshadgdi.c and other engine support
+ */
+void
+winMWExtWMStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow)
+{
+ win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
+ winPrivScreenPtr pScreenPriv = NULL;
+ winScreenInfo *pScreenInfo = NULL;
+ ScreenPtr pScreen = NULL;
+ DIBSECTION dibsection;
+ Bool fReturn = TRUE;
+ HDC hdcNew;
+ HBITMAP hbmpNew;
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMStartDrawing (%08x) %08x\n", (int) pRLWinPriv, pRLWinPriv->fDestroyed);
+#endif
+
+ if (!pRLWinPriv->fDestroyed)
+ {
+ pScreen = pRLWinPriv->pFrame->win->drawable.pScreen;
+ if (pScreen) pScreenPriv = winGetScreenPriv(pScreen);
+ if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo;
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("\tpScreenPriv %08X\n", (int) pScreenPriv);
+ winDebug ("\tpScreenInfo %08X\n", (int) pScreenInfo);
+ winDebug ("\t(%d, %d)\n", (int)pRLWinPriv->pFrame->width,
+ (int) pRLWinPriv->pFrame->height);
+#endif
+ if (pRLWinPriv->hdcScreen == NULL)
+ {
+ InitWin32RootlessEngine (pRLWinPriv);
+ }
+
+ if (pRLWinPriv->fResized)
+ {
+ /* width * bpp must be multiple of 4 to match 32bit alignment */
+ int stridesize;
+ int misalignment;
+
+ pRLWinPriv->pbmihShadow->biWidth = pRLWinPriv->pFrame->width;
+ pRLWinPriv->pbmihShadow->biHeight = -pRLWinPriv->pFrame->height;
+
+ stridesize = pRLWinPriv->pFrame->width * (pScreenInfo->dwBPP >> 3);
+ misalignment = stridesize & 3;
+ if (misalignment != 0)
+ {
+ stridesize += 4 - misalignment;
+ pRLWinPriv->pbmihShadow->biWidth = stridesize / (pScreenInfo->dwBPP >> 3);
+ winDebug("\tresizing to %d (was %d)\n",
+ pRLWinPriv->pbmihShadow->biWidth, pRLWinPriv->pFrame->width);
+ }
+
+ hdcNew = CreateCompatibleDC (pRLWinPriv->hdcScreen);
+ /* Create a DI shadow bitmap with a bit pointer */
+ hbmpNew = CreateDIBSection (pRLWinPriv->hdcScreen,
+ (BITMAPINFO *) pRLWinPriv->pbmihShadow,
+ DIB_RGB_COLORS,
+ (VOID**) &pRLWinPriv->pfb,
+ NULL,
+ 0);
+ if (hbmpNew == NULL || pRLWinPriv->pfb == NULL)
+ {
+ ErrorF ("winMWExtWMStartDrawing - CreateDIBSection failed\n");
+ //return FALSE;
+ }
+ else
+ {
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMStartDrawing - Shadow buffer allocated\n");
+#endif
+ }
+
+ /* Get information about the bitmap that was allocated */
+ GetObject (hbmpNew, sizeof (dibsection), &dibsection);
+
+#if CYGMULTIWINDOW_DEBUG
+ /* Print information about bitmap allocated */
+ winDebug ("winMWExtWMStartDrawing - Dibsection width: %d height: %d "
+ "depth: %d size image: %d\n",
+ (unsigned int)dibsection.dsBmih.biWidth,
+ (unsigned int)dibsection.dsBmih.biHeight,
+ (unsigned int)dibsection.dsBmih.biBitCount,
+ (unsigned int)dibsection.dsBmih.biSizeImage);
+#endif
+
+ /* Select the shadow bitmap into the shadow DC */
+ SelectObject (hdcNew, hbmpNew);
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMStartDrawing - Attempting a shadow blit\n");
+#endif
+
+ /* Blit from the old shadow to the new shadow */
+ fReturn = BitBlt (hdcNew,
+ 0, 0,
+ pRLWinPriv->pFrame->width, pRLWinPriv->pFrame->height,
+ pRLWinPriv->hdcShadow,
+ 0, 0,
+ SRCCOPY);
+ if (fReturn)
+ {
+ winDebug ("winMWExtWMStartDrawing - Shadow blit success\n");
+ }
+ else
+ {
+ ErrorF ("winMWExtWMStartDrawing - Shadow blit failure\n");
+ }
+
+ /* Look for height weirdness */
+ if (dibsection.dsBmih.biHeight < 0)
+ {
+ /* FIXME: Figure out why biHeight is sometimes negative */
+ ErrorF ("winMWExtWMStartDrawing - WEIRDNESS - "
+ "biHeight still negative: %d\n",
+ (int) dibsection.dsBmih.biHeight);
+ ErrorF ("winMWExtWMStartDrawing - WEIRDNESS - "
+ "Flipping biHeight sign\n");
+ dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight;
+ }
+
+ pRLWinPriv->dwWidthBytes = dibsection.dsBm.bmWidthBytes;
+
+ winDebug ("winMWExtWMStartDrawing - bytesPerRow: %d\n",
+ (unsigned int)dibsection.dsBm.bmWidthBytes);
+
+ /* Free the old shadow bitmap */
+ DeleteObject (pRLWinPriv->hdcShadow);
+ DeleteObject (pRLWinPriv->hbmpShadow);
+
+ pRLWinPriv->hdcShadow = hdcNew;
+ pRLWinPriv->hbmpShadow = hbmpNew;
+
+ pRLWinPriv->fResized = FALSE;
+ winDebug ("winMWExtWMStartDrawing - 0x%08x %d\n",
+ (unsigned int)pRLWinPriv->pfb,
+ (unsigned int)dibsection.dsBm.bmWidthBytes);
+ }
+ }
+ else
+ {
+ ErrorF ("winMWExtWMStartDrawing - Already window was destroyed \n");
+ }
+ winDebug ("winMWExtWMStartDrawing - done (0x%08x) 0x%08x %d\n",
+ (int) pRLWinPriv,
+ (unsigned int)pRLWinPriv->pfb, (unsigned int)pRLWinPriv->dwWidthBytes);
+ *pixelData = pRLWinPriv->pfb;
+ *bytesPerRow = pRLWinPriv->dwWidthBytes;
+}
+
+void
+winMWExtWMStopDrawing (RootlessFrameID wid, Bool fFlush)
+{
+}
+
+void
+winMWExtWMUpdateRegion (RootlessFrameID wid, RegionPtr pDamage)
+{
+ win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
+ if (!g_fNoConfigureWindow) UpdateWindow (pRLWinPriv->hWnd);
+}
+
+void
+winMWExtWMDamageRects (RootlessFrameID wid, int nCount, const BoxRec *pRects,
+ int shift_x, int shift_y)
+{
+ win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
+ const BoxRec *pEnd;
+ winDebug ("winMWExtWMDamageRects (%08x, %d, %08x, %d, %d)\n",
+ pRLWinPriv, nCount, pRects, shift_x, shift_y);
+
+ for (pEnd = pRects + nCount; pRects < pEnd; pRects++) {
+ RECT rcDmg;
+ rcDmg.left = pRects->x1 + shift_x;
+ rcDmg.top = pRects->y1 + shift_y;
+ rcDmg.right = pRects->x2 + shift_x;
+ rcDmg.bottom = pRects->y2 + shift_y;
+
+ InvalidateRect (pRLWinPriv->hWnd, &rcDmg, FALSE);
+ }
+}
+
+void
+winMWExtWMRootlessSwitchWindow (RootlessWindowPtr pFrame, WindowPtr oldWin)
+{
+ win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid;
+ winDebug ("winMWExtWMRootlessSwitchWindow (%08x) %08x\n",
+ (int) pRLWinPriv, (int) pRLWinPriv->hWnd);
+ pRLWinPriv->pFrame = pFrame;
+ pRLWinPriv->fResized = TRUE;
+
+ /* Set the window extended style flags */
+ SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
+
+ /* Set the window standard style flags */
+ SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE,
+ WS_POPUP | WS_CLIPCHILDREN);
+
+ DeleteProperty (serverClient, oldWin, AtmWindowsWmNativeHwnd ());
+ winMWExtWMSetNativeProperty (pFrame);
+}
+
+void
+winMWExtWMCopyBytes (unsigned int width, unsigned int height,
+ const void *src, unsigned int srcRowBytes,
+ void *dst, unsigned int dstRowBytes)
+{
+ winDebug ("winMWExtWMCopyBytes - Not implemented\n");
+}
+
+void
+winMWExtWMFillBytes (unsigned int width, unsigned int height, unsigned int value,
+ void *dst, unsigned int dstRowBytes)
+{
+ winDebug ("winMWExtWMFillBytes - Not implemented\n");
+}
+
+int
+winMWExtWMCompositePixels (unsigned int width, unsigned int height, unsigned int function,
+ void *src[2], unsigned int srcRowBytes[2],
+ void *mask, unsigned int maskRowBytes,
+ void *dst[2], unsigned int dstRowBytes[2])
+{
+ winDebug ("winMWExtWMCompositePixels - Not implemented\n");
+ return 0;
+}
+
+
+void
+winMWExtWMCopyWindow (RootlessFrameID wid, int nDstRects, const BoxRec *pDstRects,
+ int nDx, int nDy)
+{
+ win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
+ const BoxRec *pEnd;
+ RECT rcDmg;
+ winDebug ("winMWExtWMCopyWindow (%08x, %d, %08x, %d, %d)\n",
+ (int) pRLWinPriv, nDstRects, (int) pDstRects, nDx, nDy);
+
+ for (pEnd = pDstRects + nDstRects; pDstRects < pEnd; pDstRects++)
+ {
+ winDebug ("BitBlt (%d, %d, %d, %d) (%d, %d)\n",
+ pDstRects->x1, pDstRects->y1,
+ pDstRects->x2 - pDstRects->x1,
+ pDstRects->y2 - pDstRects->y1,
+ pDstRects->x1 + nDx,
+ pDstRects->y1 + nDy);
+
+ if (!BitBlt (pRLWinPriv->hdcShadow,
+ pDstRects->x1, pDstRects->y1,
+ pDstRects->x2 - pDstRects->x1,
+ pDstRects->y2 - pDstRects->y1,
+ pRLWinPriv->hdcShadow,
+ pDstRects->x1 + nDx, pDstRects->y1 + nDy,
+ SRCCOPY))
+ {
+ ErrorF ("winMWExtWMCopyWindow - BitBlt failed.\n");
+ }
+
+ rcDmg.left = pDstRects->x1;
+ rcDmg.top = pDstRects->y1;
+ rcDmg.right = pDstRects->x2;
+ rcDmg.bottom = pDstRects->y2;
+
+ InvalidateRect (pRLWinPriv->hWnd, &rcDmg, FALSE);
+ }
+ winDebug ("winMWExtWMCopyWindow - done\n");
+}
+
+
+/*
+ * winMWExtWMSetNativeProperty
+ */
+
+static void
+winMWExtWMSetNativeProperty (RootlessWindowPtr pFrame)
+{
+ win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid;
+ long lData;
+
+ /* FIXME: move this to WindowsWM extension */
+
+ lData = (long) pRLWinPriv->hWnd;
+ dixChangeWindowProperty(serverClient, pFrame->win, AtmWindowsWmNativeHwnd(),
+ XA_INTEGER, 32, PropModeReplace, 1, &lData, TRUE);
+}
diff --git a/xorg-server/hw/xwin/winwin32rootlesswindow.c b/xorg-server/hw/xwin/winwin32rootlesswindow.c index 3a49ead69..60e1f8bea 100644 --- a/xorg-server/hw/xwin/winwin32rootlesswindow.c +++ b/xorg-server/hw/xwin/winwin32rootlesswindow.c @@ -1,476 +1,476 @@ -/* - *Copyright (C) 1994-2000 The XFree86 Project, 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, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *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. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of the XFree86 Project - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from the XFree86 Project. - * - * Authors: Kensuke Matsuzaki - * Earle F. Philhower, III - * Harold L Hunt II - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" -#include "winprefs.h" - -#if 0 -/* - * winMWExtWMReorderWindows - */ - -void -winMWExtWMReorderWindows (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - HWND hwnd = NULL; - win32RootlessWindowPtr pRLWin = NULL; - win32RootlessWindowPtr pRLWinSib = NULL; - DWORD dwCurrentProcessID = GetCurrentProcessId (); - DWORD dwWindowProcessID = 0; - XID vlist[2]; - -#if CYGMULTIWINDOW_DEBUG && FALSE - winDebug ("winMWExtWMReorderWindows\n"); -#endif - - pScreenPriv->fRestacking = TRUE; - - if (pScreenPriv->fWindowOrderChanged) - { -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMReorderWindows - Need to restack\n"); -#endif - hwnd = GetTopWindow (NULL); - - while (hwnd) - { - GetWindowThreadProcessId (hwnd, &dwWindowProcessID); - - if ((dwWindowProcessID == dwCurrentProcessID) - && GetProp (hwnd, WIN_WINDOW_PROP)) - { - pRLWinSib = pRLWin; - pRLWin = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP); - - if (pRLWinSib) - { - vlist[0] = pRLWinSib->pFrame->win->drawable.id; - vlist[1] = Below; - - ConfigureWindow (pRLWin->pFrame->win, CWSibling | CWStackMode, - vlist, wClient(pRLWin->pFrame->win)); - } - else - { - /* 1st window - raise to the top */ - vlist[0] = Above; - - ConfigureWindow (pRLWin->pFrame->win, CWStackMode, - vlist, wClient(pRLWin->pFrame->win)); - } - } - hwnd = GetNextWindow (hwnd, GW_HWNDNEXT); - } - } - - pScreenPriv->fRestacking = FALSE; - pScreenPriv->fWindowOrderChanged = FALSE; -} -#endif - - -/* - * winMWExtWMMoveXWindow - */ - -void -winMWExtWMMoveXWindow (WindowPtr pWin, int x, int y) -{ - CARD32 *vlist = malloc(sizeof(CARD32)*2); - - vlist[0] = x; - vlist[1] = y; - ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin)); - free(vlist); -} - - -/* - * winMWExtWMResizeXWindow - */ - -void -winMWExtWMResizeXWindow (WindowPtr pWin, int w, int h) -{ - CARD32 *vlist = malloc(sizeof(CARD32)*2); - - vlist[0] = w; - vlist[1] = h; - ConfigureWindow (pWin, CWWidth | CWHeight, vlist, wClient(pWin)); - free(vlist); -} - - -/* - * winMWExtWMMoveResizeXWindow - */ - -void -winMWExtWMMoveResizeXWindow (WindowPtr pWin, int x, int y, int w, int h) -{ - CARD32 *vlist = malloc(sizeof(long)*4); - - vlist[0] = x; - vlist[1] = y; - vlist[2] = w; - vlist[3] = h; - - ConfigureWindow (pWin, CWX | CWY | CWWidth | CWHeight, vlist, wClient(pWin)); - free(vlist); -} - - -/* - * winMWExtWMUpdateIcon - * Change the Windows window icon - */ - -void -winMWExtWMUpdateIcon (Window id) -{ - WindowPtr pWin; - HICON hIcon, hiconOld; - - dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess); - hIcon = winOverrideIcon ((unsigned long)pWin); - - if (!hIcon) - hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON)); - - if (hIcon) - { - win32RootlessWindowPtr pRLWinPriv - = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE); - - if (pRLWinPriv->hWnd) - { - - hiconOld = (HICON) SendMessage (pRLWinPriv->hWnd, - WM_SETICON, ICON_BIG, (LPARAM) hIcon); - winDestroyIcon(hiconOld); - } - hIcon=NULL; - } -} - - -/* - * winMWExtWMDecorateWindow - Update window style. Called by EnumWindows. - */ - -wBOOL CALLBACK -winMWExtWMDecorateWindow (HWND hwnd, LPARAM lParam) -{ - win32RootlessWindowPtr pRLWinPriv = NULL; - ScreenPtr pScreen = NULL; - winPrivScreenPtr pScreenPriv = NULL; - winScreenInfo *pScreenInfo = NULL; - - /* Check if the Windows window property for our X window pointer is valid */ - if ((pRLWinPriv = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP)) != NULL) - { - pScreen = pRLWinPriv->pFrame->win->drawable.pScreen; - if (pScreen) pScreenPriv = winGetScreenPriv(pScreen); - if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; - if (pRLWinPriv && pScreenInfo) winMWExtWMUpdateWindowDecoration (pRLWinPriv, pScreenInfo); - } - return TRUE; -} - - -/* - * winMWExtWMUpdateWindowDecoration - Update window style. - */ - -void -winMWExtWMUpdateWindowDecoration (win32RootlessWindowPtr pRLWinPriv, - winScreenInfoPtr pScreenInfo) -{ - Bool fDecorate = FALSE; - DWORD dwExStyle = 0; - DWORD dwStyle = 0; - WINDOWPLACEMENT wndPlace; - UINT showCmd = 0; - - wndPlace.length = sizeof (WINDOWPLACEMENT); - - /* Get current window placement */ - GetWindowPlacement (pRLWinPriv->hWnd, &wndPlace); - - if (winIsInternalWMRunning(pScreenInfo)) - { - if (!pRLWinPriv->pFrame->win->overrideRedirect) - fDecorate = TRUE; - } -#if 0 - if (wndPlace.showCmd == SW_HIDE) - return;//showCmd = SWP_HIDEWINDOW; - else - showCmd = SWP_SHOWWINDOW; -#else - if (wndPlace.showCmd == SW_HIDE) - return; - - if (IsWindowVisible (pRLWinPriv->hWnd)) - showCmd = SWP_SHOWWINDOW; -#endif - - showCmd |= SWP_NOMOVE | SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER; - - winDebug ("winMWExtWMUpdateWindowDecoration %08x %s\n", - (int)pRLWinPriv, fDecorate?"Decorate":"Bare"); - - /* Get the standard and extended window style information */ - dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE); - dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE); - - if (fDecorate) - { - RECT rcNew; - int iDx, iDy; - winWMMessageRec wmMsg; - winScreenPriv(pScreenInfo->pScreen); - - /* */ - if (!(dwExStyle & WS_EX_APPWINDOW)) - { - winDebug ("\tBare=>Decorate\n"); - /* Setup a rectangle with the X window position and size */ - SetRect (&rcNew, - pRLWinPriv->pFrame->x, - pRLWinPriv->pFrame->y, - pRLWinPriv->pFrame->x + pRLWinPriv->pFrame->width, - pRLWinPriv->pFrame->y + pRLWinPriv->pFrame->height); - -#ifdef CYGMULTIWINDOW_DEBUG - winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n", - rcNew.left, rcNew.top, rcNew.right, rcNew.bottom, - rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); -#endif - /* */ - AdjustWindowRectEx (&rcNew, - WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW, - FALSE, - WS_EX_APPWINDOW); - -#ifdef CYGMULTIWINDOW_DEBUG - winDebug("\tAdjusted {%d, %d, %d, %d}, {%d, %d}\n", - rcNew.left, rcNew.top, rcNew.right, rcNew.bottom, - rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); -#endif - /* Calculate position deltas */ - iDx = pRLWinPriv->pFrame->x - rcNew.left; - iDy = pRLWinPriv->pFrame->y - rcNew.top; - - /* Calculate new rectangle */ - rcNew.left += iDx; - rcNew.right += iDx; - rcNew.top += iDy; - rcNew.bottom += iDy; - - /* Set the window extended style flags */ - SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW); - - /* Set the window standard style flags */ - SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE, - WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW); - -#ifdef CYGMULTIWINDOW_DEBUG - winDebug("\tWindowStyle: %08x %08x\n", - WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW, - WS_EX_APPWINDOW); -#endif - /* Position the Windows window */ -#ifdef CYGMULTIWINDOW_DEBUG - winDebug("\tMoved {%d, %d, %d, %d}, {%d, %d}\n", - rcNew.left, rcNew.top, rcNew.right, rcNew.bottom, - rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); -#endif - SetWindowPos (pRLWinPriv->hWnd, NULL, - rcNew.left, rcNew.top, - rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, - showCmd); - - - wmMsg.hwndWindow = pRLWinPriv->hWnd; - wmMsg.iWindow = (Window)pRLWinPriv->pFrame->win->drawable.id; - wmMsg.msg = WM_WM_NAME_EVENT; - winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg); - - winMWExtWMReshapeFrame ((RootlessFrameID)pRLWinPriv , - wBoundingShape(pRLWinPriv->pFrame->win)); - } - } - else - { - RECT rcNew; - - /* */ - if (dwExStyle & WS_EX_APPWINDOW) - { - winDebug ("\tDecorate=>Bare\n"); - /* Setup a rectangle with the X window position and size */ - SetRect (&rcNew, - pRLWinPriv->pFrame->x, - pRLWinPriv->pFrame->y, - pRLWinPriv->pFrame->x + pRLWinPriv->pFrame->width, - pRLWinPriv->pFrame->y + pRLWinPriv->pFrame->height); -#if 0 - /* */ - AdjustWindowRectEx (&rcNew, - WS_POPUP | WS_CLIPCHILDREN, - FALSE, - WS_EX_TOOLWINDOW); - - /* Calculate position deltas */ - iDx = pRLWinPriv->pFrame->x - rcNew.left; - iDy = pRLWinPriv->pFrame->y - rcNew.top; - - /* Calculate new rectangle */ - rcNew.left += iDx; - rcNew.right += iDx; - rcNew.top += iDy; - rcNew.bottom += iDy; -#endif - - /* Hide window temporary to remove from taskbar. */ - ShowWindow( pRLWinPriv->hWnd, SW_HIDE ); - - /* Set the window extended style flags */ - SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW); - - /* Set the window standard style flags */ - SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE, - WS_POPUP | WS_CLIPCHILDREN); - - /* Position the Windows window */ - SetWindowPos (pRLWinPriv->hWnd, NULL, - rcNew.left, rcNew.top, - rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, - showCmd); - - winMWExtWMReshapeFrame ((RootlessFrameID)pRLWinPriv , - wBoundingShape(pRLWinPriv->pFrame->win)); - } - } -} - - -/* - * winIsInternalWMRunning (winScreenInfoPtr pScreenInfo) - */ -Bool -winIsInternalWMRunning (winScreenInfoPtr pScreenInfo) -{ - return pScreenInfo->fInternalWM && !pScreenInfo->fAnotherWMRunning; -} - - -/* - * winMWExtWMRestackWindows - */ - -void -winMWExtWMRestackWindows (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - WindowPtr pRoot = WindowTable[pScreen->myNum]; - WindowPtr pWin = NULL; - WindowPtr pWinPrev = NULL; - win32RootlessWindowPtr pRLWin = NULL; - win32RootlessWindowPtr pRLWinPrev = NULL; - int nWindow = 0; - HDWP hWinPosInfo = NULL; - -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMRestackWindows\n"); -#endif - - pScreenPriv->fRestacking = TRUE; - - if (pRoot != NULL) - { - for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib) - nWindow ++; - - hWinPosInfo = BeginDeferWindowPos(nWindow); - - for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib) - { - if (pWin->realized) - { - UINT uFlags; - - pRLWin = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE); - if (pRLWin == NULL) continue; - - if (pWinPrev) - pRLWinPrev = (win32RootlessWindowPtr) RootlessFrameForWindow (pWinPrev, FALSE); - - uFlags = SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW; - if (pRLWinPrev != NULL) uFlags |= SWP_NOACTIVATE; - -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMRestackWindows - DeferWindowPos (%08x, %08x)\n", - pRLWin->hWnd, - pRLWinPrev ? pRLWinPrev->hWnd : HWND_TOP); -#endif - hWinPosInfo = DeferWindowPos (hWinPosInfo, pRLWin->hWnd, - pRLWinPrev ? pRLWinPrev->hWnd : HWND_TOP, - 0, 0, 0, 0, - uFlags); - if (hWinPosInfo == NULL) - { - ErrorF ("winMWExtWMRestackWindows - DeferWindowPos () failed: %d\n", - (int) GetLastError ()); - return; - } - pWinPrev = pWin; - } - } - if (!EndDeferWindowPos (hWinPosInfo)) - { - ErrorF ("winMWExtWMRestackWindows - EndDeferWindowPos () failed: %d\n", - (int) GetLastError ()); - return; - } - } - -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMRestackWindows - done\n"); -#endif - pScreenPriv->fRestacking = FALSE; -} +/*
+ *Copyright (C) 1994-2000 The XFree86 Project, 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, sublicense, and/or sell copies of the Software, and to
+ *permit persons to whom the Software is furnished to do so, subject to
+ *the following conditions:
+ *
+ *The above copyright notice and this permission notice shall be
+ *included in all copies or substantial portions of the Software.
+ *
+ *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. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
+ *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *Except as contained in this notice, the name of the XFree86 Project
+ *shall not be used in advertising or otherwise to promote the sale, use
+ *or other dealings in this Software without prior written authorization
+ *from the XFree86 Project.
+ *
+ * Authors: Kensuke Matsuzaki
+ * Earle F. Philhower, III
+ * Harold L Hunt II
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+#include "winprefs.h"
+
+#if 0
+/*
+ * winMWExtWMReorderWindows
+ */
+
+void
+winMWExtWMReorderWindows (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ HWND hwnd = NULL;
+ win32RootlessWindowPtr pRLWin = NULL;
+ win32RootlessWindowPtr pRLWinSib = NULL;
+ DWORD dwCurrentProcessID = GetCurrentProcessId ();
+ DWORD dwWindowProcessID = 0;
+ XID vlist[2];
+
+#if CYGMULTIWINDOW_DEBUG && FALSE
+ winDebug ("winMWExtWMReorderWindows\n");
+#endif
+
+ pScreenPriv->fRestacking = TRUE;
+
+ if (pScreenPriv->fWindowOrderChanged)
+ {
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMReorderWindows - Need to restack\n");
+#endif
+ hwnd = GetTopWindow (NULL);
+
+ while (hwnd)
+ {
+ GetWindowThreadProcessId (hwnd, &dwWindowProcessID);
+
+ if ((dwWindowProcessID == dwCurrentProcessID)
+ && GetProp (hwnd, WIN_WINDOW_PROP))
+ {
+ pRLWinSib = pRLWin;
+ pRLWin = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP);
+
+ if (pRLWinSib)
+ {
+ vlist[0] = pRLWinSib->pFrame->win->drawable.id;
+ vlist[1] = Below;
+
+ ConfigureWindow (pRLWin->pFrame->win, CWSibling | CWStackMode,
+ vlist, wClient(pRLWin->pFrame->win));
+ }
+ else
+ {
+ /* 1st window - raise to the top */
+ vlist[0] = Above;
+
+ ConfigureWindow (pRLWin->pFrame->win, CWStackMode,
+ vlist, wClient(pRLWin->pFrame->win));
+ }
+ }
+ hwnd = GetNextWindow (hwnd, GW_HWNDNEXT);
+ }
+ }
+
+ pScreenPriv->fRestacking = FALSE;
+ pScreenPriv->fWindowOrderChanged = FALSE;
+}
+#endif
+
+
+/*
+ * winMWExtWMMoveXWindow
+ */
+
+void
+winMWExtWMMoveXWindow (WindowPtr pWin, int x, int y)
+{
+ CARD32 *vlist = malloc(sizeof(CARD32)*2);
+
+ vlist[0] = x;
+ vlist[1] = y;
+ ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin));
+ free(vlist);
+}
+
+
+/*
+ * winMWExtWMResizeXWindow
+ */
+
+void
+winMWExtWMResizeXWindow (WindowPtr pWin, int w, int h)
+{
+ CARD32 *vlist = malloc(sizeof(CARD32)*2);
+
+ vlist[0] = w;
+ vlist[1] = h;
+ ConfigureWindow (pWin, CWWidth | CWHeight, vlist, wClient(pWin));
+ free(vlist);
+}
+
+
+/*
+ * winMWExtWMMoveResizeXWindow
+ */
+
+void
+winMWExtWMMoveResizeXWindow (WindowPtr pWin, int x, int y, int w, int h)
+{
+ CARD32 *vlist = malloc(sizeof(long)*4);
+
+ vlist[0] = x;
+ vlist[1] = y;
+ vlist[2] = w;
+ vlist[3] = h;
+
+ ConfigureWindow (pWin, CWX | CWY | CWWidth | CWHeight, vlist, wClient(pWin));
+ free(vlist);
+}
+
+
+/*
+ * winMWExtWMUpdateIcon
+ * Change the Windows window icon
+ */
+
+void
+winMWExtWMUpdateIcon (Window id)
+{
+ WindowPtr pWin;
+ HICON hIcon, hiconOld;
+
+ dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess);
+ hIcon = winOverrideIcon ((unsigned long)pWin);
+
+ if (!hIcon)
+ hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON));
+
+ if (hIcon)
+ {
+ win32RootlessWindowPtr pRLWinPriv
+ = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE);
+
+ if (pRLWinPriv->hWnd)
+ {
+
+ hiconOld = (HICON) SendMessage (pRLWinPriv->hWnd,
+ WM_SETICON, ICON_BIG, (LPARAM) hIcon);
+ winDestroyIcon(hiconOld);
+ }
+ hIcon=NULL;
+ }
+}
+
+
+/*
+ * winMWExtWMDecorateWindow - Update window style. Called by EnumWindows.
+ */
+
+wBOOL CALLBACK
+winMWExtWMDecorateWindow (HWND hwnd, LPARAM lParam)
+{
+ win32RootlessWindowPtr pRLWinPriv = NULL;
+ ScreenPtr pScreen = NULL;
+ winPrivScreenPtr pScreenPriv = NULL;
+ winScreenInfo *pScreenInfo = NULL;
+
+ /* Check if the Windows window property for our X window pointer is valid */
+ if ((pRLWinPriv = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP)) != NULL)
+ {
+ pScreen = pRLWinPriv->pFrame->win->drawable.pScreen;
+ if (pScreen) pScreenPriv = winGetScreenPriv(pScreen);
+ if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo;
+ if (pRLWinPriv && pScreenInfo) winMWExtWMUpdateWindowDecoration (pRLWinPriv, pScreenInfo);
+ }
+ return TRUE;
+}
+
+
+/*
+ * winMWExtWMUpdateWindowDecoration - Update window style.
+ */
+
+void
+winMWExtWMUpdateWindowDecoration (win32RootlessWindowPtr pRLWinPriv,
+ winScreenInfoPtr pScreenInfo)
+{
+ Bool fDecorate = FALSE;
+ DWORD dwExStyle = 0;
+ DWORD dwStyle = 0;
+ WINDOWPLACEMENT wndPlace;
+ UINT showCmd = 0;
+
+ wndPlace.length = sizeof (WINDOWPLACEMENT);
+
+ /* Get current window placement */
+ GetWindowPlacement (pRLWinPriv->hWnd, &wndPlace);
+
+ if (winIsInternalWMRunning(pScreenInfo))
+ {
+ if (!pRLWinPriv->pFrame->win->overrideRedirect)
+ fDecorate = TRUE;
+ }
+#if 0
+ if (wndPlace.showCmd == SW_HIDE)
+ return;//showCmd = SWP_HIDEWINDOW;
+ else
+ showCmd = SWP_SHOWWINDOW;
+#else
+ if (wndPlace.showCmd == SW_HIDE)
+ return;
+
+ if (IsWindowVisible (pRLWinPriv->hWnd))
+ showCmd = SWP_SHOWWINDOW;
+#endif
+
+ showCmd |= SWP_NOMOVE | SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER;
+
+ winDebug ("winMWExtWMUpdateWindowDecoration %08x %s\n",
+ (int)pRLWinPriv, fDecorate?"Decorate":"Bare");
+
+ /* Get the standard and extended window style information */
+ dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE);
+ dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE);
+
+ if (fDecorate)
+ {
+ RECT rcNew;
+ int iDx, iDy;
+ winWMMessageRec wmMsg;
+ winScreenPriv(pScreenInfo->pScreen);
+
+ /* */
+ if (!(dwExStyle & WS_EX_APPWINDOW))
+ {
+ winDebug ("\tBare=>Decorate\n");
+ /* Setup a rectangle with the X window position and size */
+ SetRect (&rcNew,
+ pRLWinPriv->pFrame->x,
+ pRLWinPriv->pFrame->y,
+ pRLWinPriv->pFrame->x + pRLWinPriv->pFrame->width,
+ pRLWinPriv->pFrame->y + pRLWinPriv->pFrame->height);
+
+#ifdef CYGMULTIWINDOW_DEBUG
+ winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n",
+ rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
+ rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
+#endif
+ /* */
+ AdjustWindowRectEx (&rcNew,
+ WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW,
+ FALSE,
+ WS_EX_APPWINDOW);
+
+#ifdef CYGMULTIWINDOW_DEBUG
+ winDebug("\tAdjusted {%d, %d, %d, %d}, {%d, %d}\n",
+ rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
+ rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
+#endif
+ /* Calculate position deltas */
+ iDx = pRLWinPriv->pFrame->x - rcNew.left;
+ iDy = pRLWinPriv->pFrame->y - rcNew.top;
+
+ /* Calculate new rectangle */
+ rcNew.left += iDx;
+ rcNew.right += iDx;
+ rcNew.top += iDy;
+ rcNew.bottom += iDy;
+
+ /* Set the window extended style flags */
+ SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW);
+
+ /* Set the window standard style flags */
+ SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE,
+ WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW);
+
+#ifdef CYGMULTIWINDOW_DEBUG
+ winDebug("\tWindowStyle: %08x %08x\n",
+ WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW,
+ WS_EX_APPWINDOW);
+#endif
+ /* Position the Windows window */
+#ifdef CYGMULTIWINDOW_DEBUG
+ winDebug("\tMoved {%d, %d, %d, %d}, {%d, %d}\n",
+ rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
+ rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
+#endif
+ SetWindowPos (pRLWinPriv->hWnd, NULL,
+ rcNew.left, rcNew.top,
+ rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
+ showCmd);
+
+
+ wmMsg.hwndWindow = pRLWinPriv->hWnd;
+ wmMsg.iWindow = (Window)pRLWinPriv->pFrame->win->drawable.id;
+ wmMsg.msg = WM_WM_NAME_EVENT;
+ winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
+
+ winMWExtWMReshapeFrame ((RootlessFrameID)pRLWinPriv ,
+ wBoundingShape(pRLWinPriv->pFrame->win));
+ }
+ }
+ else
+ {
+ RECT rcNew;
+
+ /* */
+ if (dwExStyle & WS_EX_APPWINDOW)
+ {
+ winDebug ("\tDecorate=>Bare\n");
+ /* Setup a rectangle with the X window position and size */
+ SetRect (&rcNew,
+ pRLWinPriv->pFrame->x,
+ pRLWinPriv->pFrame->y,
+ pRLWinPriv->pFrame->x + pRLWinPriv->pFrame->width,
+ pRLWinPriv->pFrame->y + pRLWinPriv->pFrame->height);
+#if 0
+ /* */
+ AdjustWindowRectEx (&rcNew,
+ WS_POPUP | WS_CLIPCHILDREN,
+ FALSE,
+ WS_EX_TOOLWINDOW);
+
+ /* Calculate position deltas */
+ iDx = pRLWinPriv->pFrame->x - rcNew.left;
+ iDy = pRLWinPriv->pFrame->y - rcNew.top;
+
+ /* Calculate new rectangle */
+ rcNew.left += iDx;
+ rcNew.right += iDx;
+ rcNew.top += iDy;
+ rcNew.bottom += iDy;
+#endif
+
+ /* Hide window temporary to remove from taskbar. */
+ ShowWindow( pRLWinPriv->hWnd, SW_HIDE );
+
+ /* Set the window extended style flags */
+ SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
+
+ /* Set the window standard style flags */
+ SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE,
+ WS_POPUP | WS_CLIPCHILDREN);
+
+ /* Position the Windows window */
+ SetWindowPos (pRLWinPriv->hWnd, NULL,
+ rcNew.left, rcNew.top,
+ rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
+ showCmd);
+
+ winMWExtWMReshapeFrame ((RootlessFrameID)pRLWinPriv ,
+ wBoundingShape(pRLWinPriv->pFrame->win));
+ }
+ }
+}
+
+
+/*
+ * winIsInternalWMRunning (winScreenInfoPtr pScreenInfo)
+ */
+Bool
+winIsInternalWMRunning (winScreenInfoPtr pScreenInfo)
+{
+ return pScreenInfo->fInternalWM && !pScreenInfo->fAnotherWMRunning;
+}
+
+
+/*
+ * winMWExtWMRestackWindows
+ */
+
+void
+winMWExtWMRestackWindows (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ WindowPtr pRoot = pScreen->root;
+ WindowPtr pWin = NULL;
+ WindowPtr pWinPrev = NULL;
+ win32RootlessWindowPtr pRLWin = NULL;
+ win32RootlessWindowPtr pRLWinPrev = NULL;
+ int nWindow = 0;
+ HDWP hWinPosInfo = NULL;
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMRestackWindows\n");
+#endif
+
+ pScreenPriv->fRestacking = TRUE;
+
+ if (pRoot != NULL)
+ {
+ for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib)
+ nWindow ++;
+
+ hWinPosInfo = BeginDeferWindowPos(nWindow);
+
+ for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib)
+ {
+ if (pWin->realized)
+ {
+ UINT uFlags;
+
+ pRLWin = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE);
+ if (pRLWin == NULL) continue;
+
+ if (pWinPrev)
+ pRLWinPrev = (win32RootlessWindowPtr) RootlessFrameForWindow (pWinPrev, FALSE);
+
+ uFlags = SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW;
+ if (pRLWinPrev != NULL) uFlags |= SWP_NOACTIVATE;
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMRestackWindows - DeferWindowPos (%08x, %08x)\n",
+ pRLWin->hWnd,
+ pRLWinPrev ? pRLWinPrev->hWnd : HWND_TOP);
+#endif
+ hWinPosInfo = DeferWindowPos (hWinPosInfo, pRLWin->hWnd,
+ pRLWinPrev ? pRLWinPrev->hWnd : HWND_TOP,
+ 0, 0, 0, 0,
+ uFlags);
+ if (hWinPosInfo == NULL)
+ {
+ ErrorF ("winMWExtWMRestackWindows - DeferWindowPos () failed: %d\n",
+ (int) GetLastError ());
+ return;
+ }
+ pWinPrev = pWin;
+ }
+ }
+ if (!EndDeferWindowPos (hWinPosInfo))
+ {
+ ErrorF ("winMWExtWMRestackWindows - EndDeferWindowPos () failed: %d\n",
+ (int) GetLastError ());
+ return;
+ }
+ }
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMRestackWindows - done\n");
+#endif
+ pScreenPriv->fRestacking = FALSE;
+}
diff --git a/xorg-server/hw/xwin/winwindow.c b/xorg-server/hw/xwin/winwindow.c index 8156671cd..117a04b00 100644 --- a/xorg-server/hw/xwin/winwindow.c +++ b/xorg-server/hw/xwin/winwindow.c @@ -135,25 +135,25 @@ winCopyWindowNativeGDI (WindowPtr pWin, winScreenPriv(pScreen);
/* Get a pointer to the root window */
- pwinRoot = WindowTable[pWin->drawable.pScreen->myNum];
+ pwinRoot = pWin->drawable.pScreen->root;
/* Create a region for the destination */
- prgnDst = REGION_CREATE(pWin->drawable.pScreen, NULL, 1);
+ prgnDst = RegionCreate(NULL, 1);
/* Calculate the shift from the source to the destination */
dx = ptOldOrg.x - pWin->drawable.x;
dy = ptOldOrg.y - pWin->drawable.y;
/* Translate the region from the destination to the source? */
- REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
- REGION_INTERSECT(pWin->drawable.pScreen, prgnDst, &pWin->borderClip,
+ RegionTranslate(prgnSrc, -dx, -dy);
+ RegionIntersect(prgnDst, &pWin->borderClip,
prgnSrc);
/* Get a pointer to the first box in the region to be copied */
- pBox = REGION_RECTS(prgnDst);
+ pBox = RegionRects(prgnDst);
/* Get the number of boxes in the region */
- nbox = REGION_NUM_RECTS(prgnDst);
+ nbox = RegionNumRects(prgnDst);
/* Allocate source points for each box */
if(!(pptSrc = (DDXPointPtr )malloc(nbox * sizeof(DDXPointRec))))
@@ -170,7 +170,7 @@ winCopyWindowNativeGDI (WindowPtr pWin, }
/* Setup loop pointers again */
- pBoxDst = REGION_RECTS(prgnDst);
+ pBoxDst = RegionRects(prgnDst);
ppt = pptSrc;
/* BitBlt each source to the destination point */
@@ -186,7 +186,7 @@ winCopyWindowNativeGDI (WindowPtr pWin, /* Cleanup the regions, etc. */
free(pptSrc);
- REGION_DESTROY(pWin->drawable.pScreen, prgnDst);
+ RegionDestroy(prgnDst);
}
@@ -413,15 +413,15 @@ winMapWindowRootless (WindowPtr pWin) void
-winSetShapeRootless (WindowPtr pWin)
+winSetShapeRootless (WindowPtr pWin, int kind)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
winScreenPriv(pScreen);
- winDebug ("winSetShapeRootless (%p)\n", pWin);
+ winDebug ("winSetShapeRootless (%p, %i)\n", pWin, kind);
WIN_UNWRAP(SetShape);
- (*pScreen->SetShape)(pWin);
+ (*pScreen->SetShape)(pWin, kind);
WIN_WRAP(SetShape, winSetShapeRootless);
winReshapeRootless (pWin);
@@ -522,7 +522,6 @@ void winReshapeRootless (WindowPtr pWin)
{
int nRects;
- /* ScreenPtr pScreen = pWin->drawable.pScreen;*/
RegionRec rrNewShape;
BoxPtr pShape, pRects, pEnd;
HRGN hRgn, hRgnRect;
@@ -549,13 +548,13 @@ winReshapeRootless (WindowPtr pWin) if (!wBoundingShape (pWin))
return;
- REGION_NULL(pScreen, &rrNewShape);
- REGION_COPY(pScreen, &rrNewShape, wBoundingShape(pWin));
- REGION_TRANSLATE(pScreen, &rrNewShape, pWin->borderWidth,
+ RegionNull(&rrNewShape);
+ RegionCopy(&rrNewShape, wBoundingShape(pWin));
+ RegionTranslate(&rrNewShape, pWin->borderWidth,
pWin->borderWidth);
- nRects = REGION_NUM_RECTS(&rrNewShape);
- pShape = REGION_RECTS(&rrNewShape);
+ nRects = RegionNumRects(&rrNewShape);
+ pShape = RegionRects(&rrNewShape);
if (nRects > 0)
{
@@ -587,7 +586,7 @@ winReshapeRootless (WindowPtr pWin) pWinPriv->hRgn = hRgn;
}
- REGION_UNINIT(pScreen, &rrNewShape);
+ RegionUninit(&rrNewShape);
return;
}
diff --git a/xorg-server/hw/xwin/winwindowswm.c b/xorg-server/hw/xwin/winwindowswm.c index c8f2a7073..0d262c1ea 100644 --- a/xorg-server/hw/xwin/winwindowswm.c +++ b/xorg-server/hw/xwin/winwindowswm.c @@ -414,7 +414,6 @@ ProcWindowsWMFrameDraw (register ClientPtr client) RECT rcNew;
int nCmdShow, rc;
RegionRec newShape;
- ScreenPtr pScreen;
REQUEST_SIZE_MATCH (xWindowsWMFrameDrawReq);
@@ -476,15 +475,14 @@ ProcWindowsWMFrameDraw (register ClientPtr client) if (wBoundingShape(pWin) != NULL)
{
- pScreen = pWin->drawable.pScreen;
/* wBoundingShape is relative to *inner* origin of window.
Translate by borderWidth to get the outside-relative position. */
- REGION_NULL(pScreen, &newShape);
- REGION_COPY(pScreen, &newShape, wBoundingShape(pWin));
- REGION_TRANSLATE(pScreen, &newShape, pWin->borderWidth, pWin->borderWidth);
+ RegionNull(&newShape);
+ RegionCopy(&newShape, wBoundingShape(pWin));
+ RegionTranslate(&newShape, pWin->borderWidth, pWin->borderWidth);
winMWExtWMReshapeFrame (pRLWinPriv, &newShape);
- REGION_UNINIT(pScreen, &newShape);
+ RegionUninit(&newShape);
}
winDebug ("ProcWindowsWMFrameDraw - done\n");
|