xserver-multidpi/hw/xwin/winwin32rootless.c
Keith Packard 9838b7032e Introduce a consistent coding style
This is strictly the application of the script 'x-indent-all.sh'
from util/modular. Compared to the patch that Daniel posted in
January, I've added a few indent flags:

	-bap
	-psl
	-T PrivatePtr
	-T pmWait
	-T _XFUNCPROTOBEGIN
	-T _XFUNCPROTOEND
	-T _X_EXPORT

The typedefs were needed to make the output of sdksyms.sh match the
previous output, otherwise, the code is formatted badly enough that
sdksyms.sh generates incorrect output.

The generated code was compared with the previous version and found to
be essentially identical -- "assert" line numbers and BUILD_TIME were
the only differences found.

The comparison was done with this script:

dir1=$1
dir2=$2

for dir in $dir1 $dir2; do
	(cd $dir && find . -name '*.o' | while read file; do
		dir=`dirname $file`
		base=`basename $file .o`
		dump=$dir/$base.dump
		objdump -d $file > $dump
	done)
done

find $dir1 -name '*.dump' | while read dump; do
	otherdump=`echo $dump | sed "s;$dir1;$dir2;"`
	diff -u $dump $otherdump
done

Signed-off-by: Keith Packard <keithp@keithp.com>
Acked-by: Daniel Stone <daniel@fooishbar.org>
Acked-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2012-03-21 13:54:42 -07:00

1032 lines
34 KiB
C

/*
*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 <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;
}
#if CYGMULTIWINDOW_DEBUG
winDebug("winMWExtWMCreateFrame - ShowWindow\n");
#endif
//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 hIcon;
HICON hIconSm;
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);
hIcon = (HICON) SendMessage(pRLWinPriv->hWnd, WM_GETICON, ICON_BIG, 0);
hIconSm = (HICON) SendMessage(pRLWinPriv->hWnd, WM_GETICON, ICON_SMALL, 0);
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 - Deleting Icon\n");
#endif
winDestroyIcon(hIcon);
winDestroyIcon(hIconSm);
#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 && 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 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) {
#if CYGMULTIWINDOW_DEBUG
winDebug("winMWExtWMStartDrawing - Shadow blit success\n");
#endif
}
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;
#if CYGMULTIWINDOW_DEBUG
winDebug("winMWExtWMStartDrawing - bytesPerRow: %d\n",
(unsigned int) dibsection.dsBm.bmWidthBytes);
#endif
/* Free the old shadow bitmap */
DeleteObject(pRLWinPriv->hdcShadow);
DeleteObject(pRLWinPriv->hbmpShadow);
pRLWinPriv->hdcShadow = hdcNew;
pRLWinPriv->hbmpShadow = hbmpNew;
pRLWinPriv->fResized = FALSE;
#if CYGMULTIWINDOW_DEBUG && FALSE
winDebug("winMWExtWMStartDrawing - 0x%08x %d\n",
(unsigned int) pRLWinPriv->pfb,
(unsigned int) dibsection.dsBm.bmWidthBytes);
#endif
}
}
else {
ErrorF("winMWExtWMStartDrawing - Already window was destroyed \n");
}
#if CYGMULTIWINDOW_DEBUG
winDebug("winMWExtWMStartDrawing - done (0x%08x) 0x%08x %d\n",
(int) pRLWinPriv,
(unsigned int) pRLWinPriv->pfb,
(unsigned int) pRLWinPriv->dwWidthBytes);
#endif
*pixelData = pRLWinPriv->pfb;
*bytesPerRow = pRLWinPriv->dwWidthBytes;
}
void
winMWExtWMStopDrawing(RootlessFrameID wid, Bool fFlush)
{
#if 0
win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
BLENDFUNCTION bfBlend;
SIZE szWin;
POINT ptSrc;
#if CYGMULTIWINDOW_DEBUG || TRUE
winDebug("winMWExtWMStopDrawing (%08x)\n", pRLWinPriv);
#endif
szWin.cx = pRLWinPriv->dwWidth;
szWin.cy = pRLWinPriv->dwHeight;
ptSrc.x = 0;
ptSrc.y = 0;
bfBlend.BlendOp = AC_SRC_OVER;
bfBlend.BlendFlags = 0;
bfBlend.SourceConstantAlpha = 255;
bfBlend.AlphaFormat = AC_SRC_ALPHA;
if (!UpdateLayeredWindow(pRLWinPriv->hWnd,
NULL, NULL, &szWin,
pRLWinPriv->hdcShadow, &ptSrc,
0, &bfBlend, ULW_ALPHA)) {
ErrorF("winMWExtWMStopDrawing - UpdateLayeredWindow failed\n");
}
#endif
}
void
winMWExtWMUpdateRegion(RootlessFrameID wid, RegionPtr pDamage)
{
win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
#if 0
BLENDFUNCTION bfBlend;
SIZE szWin;
POINT ptSrc;
#endif
#if CYGMULTIWINDOW_DEBUG && 0
winDebug("winMWExtWMUpdateRegion (%08x)\n", pRLWinPriv);
#endif
#if 0
szWin.cx = pRLWinPriv->dwWidth;
szWin.cy = pRLWinPriv->dwHeight;
ptSrc.x = 0;
ptSrc.y = 0;
bfBlend.BlendOp = AC_SRC_OVER;
bfBlend.BlendFlags = 0;
bfBlend.SourceConstantAlpha = 255;
bfBlend.AlphaFormat = AC_SRC_ALPHA;
if (!UpdateLayeredWindow(pRLWinPriv->hWnd,
NULL, NULL, &szWin,
pRLWinPriv->hdcShadow, &ptSrc,
0, &bfBlend, ULW_ALPHA)) {
LPVOID lpMsgBuf;
/* Display a fancy error message */
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) & lpMsgBuf, 0, NULL);
ErrorF("winMWExtWMUpdateRegion - UpdateLayeredWindow failed: %s\n",
(LPSTR) lpMsgBuf);
LocalFree(lpMsgBuf);
}
#endif
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;
#if CYGMULTIWINDOW_DEBUG && 0
winDebug("winMWExtWMDamageRects (%08x, %d, %08x, %d, %d)\n",
pRLWinPriv, nCount, pRects, shift_x, shift_y);
#endif
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;
#if CYGMULTIWINDOW_DEBUG
winDebug("winMWExtWMRootlessSwitchWindow (%08x) %08x\n",
(int) pRLWinPriv, (int) pRLWinPriv->hWnd);
#endif
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);
#if CYGMULTIWINDOW_DEBUG
#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("winMWExtWMSwitchFrame2 (%08x) %08x\n",
pRLWinPriv2, pRLWinPriv2->hWnd);
if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) {
winDebug("Error param missmatch\n");
}
}
#endif
#endif
}
void
winMWExtWMCopyBytes(unsigned int width, unsigned int height,
const void *src, unsigned int srcRowBytes,
void *dst, unsigned int dstRowBytes)
{
#if CYGMULTIWINDOW_DEBUG
winDebug("winMWExtWMCopyBytes - Not implemented\n");
#endif
}
void
winMWExtWMCopyWindow(RootlessFrameID wid, int nDstRects,
const BoxRec * pDstRects, int nDx, int nDy)
{
win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
const BoxRec *pEnd;
RECT rcDmg;
#if CYGMULTIWINDOW_DEBUG
winDebug("winMWExtWMCopyWindow (%08x, %d, %08x, %d, %d)\n",
(int) pRLWinPriv, nDstRects, (int) pDstRects, nDx, nDy);
#endif
for (pEnd = pDstRects + nDstRects; pDstRects < pEnd; pDstRects++) {
#if CYGMULTIWINDOW_DEBUG
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);
#endif
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);
}
#if CYGMULTIWINDOW_DEBUG
winDebug("winMWExtWMCopyWindow - done\n");
#endif
}
/*
* 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);
}