1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun *Permission is hereby granted, free of charge, to any person obtaining
5*4882a593Smuzhiyun * a copy of this software and associated documentation files (the
6*4882a593Smuzhiyun *"Software"), to deal in the Software without restriction, including
7*4882a593Smuzhiyun *without limitation the rights to use, copy, modify, merge, publish,
8*4882a593Smuzhiyun *distribute, sublicense, and/or sell copies of the Software, and to
9*4882a593Smuzhiyun *permit persons to whom the Software is furnished to do so, subject to
10*4882a593Smuzhiyun *the following conditions:
11*4882a593Smuzhiyun *
12*4882a593Smuzhiyun *The above copyright notice and this permission notice shall be
13*4882a593Smuzhiyun *included in all copies or substantial portions of the Software.
14*4882a593Smuzhiyun *
15*4882a593Smuzhiyun *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16*4882a593Smuzhiyun *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17*4882a593Smuzhiyun *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18*4882a593Smuzhiyun *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
19*4882a593Smuzhiyun *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20*4882a593Smuzhiyun *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21*4882a593Smuzhiyun *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22*4882a593Smuzhiyun *
23*4882a593Smuzhiyun *Except as contained in this notice, the name of the XFree86 Project
24*4882a593Smuzhiyun *shall not be used in advertising or otherwise to promote the sale, use
25*4882a593Smuzhiyun *or other dealings in this Software without prior written authorization
26*4882a593Smuzhiyun *from the XFree86 Project.
27*4882a593Smuzhiyun *
28*4882a593Smuzhiyun * Authors: Kensuke Matsuzaki
29*4882a593Smuzhiyun * Earle F. Philhower, III
30*4882a593Smuzhiyun * Harold L Hunt II
31*4882a593Smuzhiyun */
32*4882a593Smuzhiyun /*
33*4882a593Smuzhiyun * Look at hw/darwin/quartz/xpr/xprFrame.c and hw/darwin/quartz/cr/crFrame.c
34*4882a593Smuzhiyun */
35*4882a593Smuzhiyun #ifdef HAVE_XWIN_CONFIG_H
36*4882a593Smuzhiyun #include <xwin-config.h>
37*4882a593Smuzhiyun #endif
38*4882a593Smuzhiyun #include "win.h"
39*4882a593Smuzhiyun #include <winuser.h>
40*4882a593Smuzhiyun #define _WINDOWSWM_SERVER_
41*4882a593Smuzhiyun #include <X11/extensions/windowswmstr.h>
42*4882a593Smuzhiyun #include "winmultiwindowclass.h"
43*4882a593Smuzhiyun #include "winmultiwindowicons.h"
44*4882a593Smuzhiyun #include <X11/Xatom.h>
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun /*
47*4882a593Smuzhiyun * Constant defines
48*4882a593Smuzhiyun */
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun #ifndef ULW_COLORKEY
51*4882a593Smuzhiyun #define ULW_COLORKEY 0x00000001
52*4882a593Smuzhiyun #endif
53*4882a593Smuzhiyun #ifndef ULW_ALPHA
54*4882a593Smuzhiyun #define ULW_ALPHA 0x00000002
55*4882a593Smuzhiyun #endif
56*4882a593Smuzhiyun #ifndef ULW_OPAQUE
57*4882a593Smuzhiyun #define ULW_OPAQUE 0x00000004
58*4882a593Smuzhiyun #endif
59*4882a593Smuzhiyun #define AC_SRC_ALPHA 0x01
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun /*
62*4882a593Smuzhiyun * Local function
63*4882a593Smuzhiyun */
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun DEFINE_ATOM_HELPER(AtmWindowsWmNativeHwnd, WINDOWSWM_NATIVE_HWND)
66*4882a593Smuzhiyun static void
67*4882a593Smuzhiyun winMWExtWMSetNativeProperty(RootlessWindowPtr pFrame);
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun /*
70*4882a593Smuzhiyun * Global variables
71*4882a593Smuzhiyun */
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun Bool g_fNoConfigureWindow = FALSE;
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun /*
76*4882a593Smuzhiyun * Internal function to get the DIB format that is compatible with the screen
77*4882a593Smuzhiyun * Fixme: Share code with winshadgdi.c
78*4882a593Smuzhiyun */
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun static
81*4882a593Smuzhiyun Bool
winMWExtWMQueryDIBFormat(win32RootlessWindowPtr pRLWinPriv,BITMAPINFOHEADER * pbmih)82*4882a593Smuzhiyun winMWExtWMQueryDIBFormat(win32RootlessWindowPtr pRLWinPriv,
83*4882a593Smuzhiyun BITMAPINFOHEADER * pbmih)
84*4882a593Smuzhiyun {
85*4882a593Smuzhiyun HBITMAP hbmp;
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
88*4882a593Smuzhiyun LPDWORD pdw = NULL;
89*4882a593Smuzhiyun #endif
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun /* Create a memory bitmap compatible with the screen */
92*4882a593Smuzhiyun hbmp = CreateCompatibleBitmap(pRLWinPriv->hdcScreen, 1, 1);
93*4882a593Smuzhiyun if (hbmp == NULL) {
94*4882a593Smuzhiyun ErrorF("winMWExtWMQueryDIBFormat - CreateCompatibleBitmap failed\n");
95*4882a593Smuzhiyun return FALSE;
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun /* Initialize our bitmap info header */
99*4882a593Smuzhiyun ZeroMemory(pbmih, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
100*4882a593Smuzhiyun pbmih->biSize = sizeof(BITMAPINFOHEADER);
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun /* Get the biBitCount */
103*4882a593Smuzhiyun if (!GetDIBits(pRLWinPriv->hdcScreen,
104*4882a593Smuzhiyun hbmp, 0, 1, NULL, (BITMAPINFO *) pbmih, DIB_RGB_COLORS)) {
105*4882a593Smuzhiyun ErrorF("winMWExtWMQueryDIBFormat - First call to GetDIBits failed\n");
106*4882a593Smuzhiyun DeleteObject(hbmp);
107*4882a593Smuzhiyun return FALSE;
108*4882a593Smuzhiyun }
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
111*4882a593Smuzhiyun /* Get a pointer to bitfields */
112*4882a593Smuzhiyun pdw = (DWORD *) ((CARD8 *) pbmih + sizeof(BITMAPINFOHEADER));
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun winDebug("winMWExtWMQueryDIBFormat - First call masks: %08x %08x %08x\n",
115*4882a593Smuzhiyun (unsigned int) pdw[0], (unsigned int) pdw[1],
116*4882a593Smuzhiyun (unsigned int) pdw[2]);
117*4882a593Smuzhiyun #endif
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun /* Get optimal color table, or the optimal bitfields */
120*4882a593Smuzhiyun if (!GetDIBits(pRLWinPriv->hdcScreen,
121*4882a593Smuzhiyun hbmp, 0, 1, NULL, (BITMAPINFO *) pbmih, DIB_RGB_COLORS)) {
122*4882a593Smuzhiyun ErrorF("winMWExtWMQueryDIBFormat - Second call to GetDIBits "
123*4882a593Smuzhiyun "failed\n");
124*4882a593Smuzhiyun DeleteObject(hbmp);
125*4882a593Smuzhiyun return FALSE;
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun /* Free memory */
129*4882a593Smuzhiyun DeleteObject(hbmp);
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun return TRUE;
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun static HRGN
winMWExtWMCreateRgnFromRegion(RegionPtr pShape)135*4882a593Smuzhiyun winMWExtWMCreateRgnFromRegion(RegionPtr pShape)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun int nRects;
138*4882a593Smuzhiyun BoxPtr pRects, pEnd;
139*4882a593Smuzhiyun HRGN hRgn, hRgnRect;
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun if (pShape == NULL)
142*4882a593Smuzhiyun return NULL;
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun nRects = RegionNumRects(pShape);
145*4882a593Smuzhiyun pRects = RegionRects(pShape);
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun hRgn = CreateRectRgn(0, 0, 0, 0);
148*4882a593Smuzhiyun if (hRgn == NULL) {
149*4882a593Smuzhiyun ErrorF("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) "
150*4882a593Smuzhiyun "failed: %d\n", 0, 0, 0, 0, (int) GetLastError());
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun /* Loop through all rectangles in the X region */
154*4882a593Smuzhiyun for (pEnd = pRects + nRects; pRects < pEnd; pRects++) {
155*4882a593Smuzhiyun /* Create a Windows region for the X rectangle */
156*4882a593Smuzhiyun hRgnRect = CreateRectRgn(pRects->x1,
157*4882a593Smuzhiyun pRects->y1, pRects->x2, pRects->y2);
158*4882a593Smuzhiyun if (hRgnRect == NULL) {
159*4882a593Smuzhiyun ErrorF("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) "
160*4882a593Smuzhiyun "failed: %d\n",
161*4882a593Smuzhiyun pRects->x1,
162*4882a593Smuzhiyun pRects->y1, pRects->x2, pRects->y2, (int) GetLastError());
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun /* Merge the Windows region with the accumulated region */
166*4882a593Smuzhiyun if (CombineRgn(hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) {
167*4882a593Smuzhiyun ErrorF("winReshape - CombineRgn () failed: %d\n",
168*4882a593Smuzhiyun (int) GetLastError());
169*4882a593Smuzhiyun }
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun /* Delete the temporary Windows region */
172*4882a593Smuzhiyun DeleteObject(hRgnRect);
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun return hRgn;
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun static void
InitWin32RootlessEngine(win32RootlessWindowPtr pRLWinPriv)179*4882a593Smuzhiyun InitWin32RootlessEngine(win32RootlessWindowPtr pRLWinPriv)
180*4882a593Smuzhiyun {
181*4882a593Smuzhiyun pRLWinPriv->hdcScreen = GetDC(pRLWinPriv->hWnd);
182*4882a593Smuzhiyun pRLWinPriv->hdcShadow = CreateCompatibleDC(pRLWinPriv->hdcScreen);
183*4882a593Smuzhiyun pRLWinPriv->hbmpShadow = NULL;
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun /* Allocate bitmap info header */
186*4882a593Smuzhiyun pRLWinPriv->pbmihShadow =
187*4882a593Smuzhiyun malloc(sizeof(BITMAPINFOHEADER)
188*4882a593Smuzhiyun + 256 * sizeof(RGBQUAD));
189*4882a593Smuzhiyun if (pRLWinPriv->pbmihShadow == NULL) {
190*4882a593Smuzhiyun ErrorF("InitWin32RootlessEngine - malloc () failed\n");
191*4882a593Smuzhiyun return;
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun /* Query the screen format */
195*4882a593Smuzhiyun winMWExtWMQueryDIBFormat(pRLWinPriv, pRLWinPriv->pbmihShadow);
196*4882a593Smuzhiyun }
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun Bool
winMWExtWMCreateFrame(RootlessWindowPtr pFrame,ScreenPtr pScreen,int newX,int newY,RegionPtr pShape)199*4882a593Smuzhiyun winMWExtWMCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
200*4882a593Smuzhiyun int newX, int newY, RegionPtr pShape)
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun #define CLASS_NAME_LENGTH 512
203*4882a593Smuzhiyun Bool fResult = TRUE;
204*4882a593Smuzhiyun win32RootlessWindowPtr pRLWinPriv;
205*4882a593Smuzhiyun WNDCLASSEX wc;
206*4882a593Smuzhiyun char pszClass[CLASS_NAME_LENGTH], pszWindowID[12];
207*4882a593Smuzhiyun HICON hIcon;
208*4882a593Smuzhiyun HICON hIconSmall;
209*4882a593Smuzhiyun char *res_name, *res_class, *res_role;
210*4882a593Smuzhiyun static int s_iWindowID = 0;
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
213*4882a593Smuzhiyun winDebug("winMWExtWMCreateFrame %d %d - %d %d\n",
214*4882a593Smuzhiyun newX, newY, pFrame->width, pFrame->height);
215*4882a593Smuzhiyun #endif
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun pRLWinPriv = malloc(sizeof(win32RootlessWindowRec));
218*4882a593Smuzhiyun pRLWinPriv->pFrame = pFrame;
219*4882a593Smuzhiyun pRLWinPriv->pfb = NULL;
220*4882a593Smuzhiyun pRLWinPriv->hbmpShadow = NULL;
221*4882a593Smuzhiyun pRLWinPriv->hdcShadow = NULL;
222*4882a593Smuzhiyun pRLWinPriv->hdcScreen = NULL;
223*4882a593Smuzhiyun pRLWinPriv->pbmihShadow = NULL;
224*4882a593Smuzhiyun pRLWinPriv->fResized = TRUE;
225*4882a593Smuzhiyun pRLWinPriv->fClose = FALSE;
226*4882a593Smuzhiyun pRLWinPriv->fRestackingNow = FALSE;
227*4882a593Smuzhiyun pRLWinPriv->fDestroyed = FALSE;
228*4882a593Smuzhiyun pRLWinPriv->fMovingOrSizing = FALSE;
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun // Store the implementation private frame ID
231*4882a593Smuzhiyun pFrame->wid = (RootlessFrameID) pRLWinPriv;
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun winSelectIcons(&hIcon, &hIconSmall);
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun /* Set standard class name prefix so we can identify window easily */
236*4882a593Smuzhiyun strncpy(pszClass, WINDOW_CLASS_X, sizeof(pszClass));
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun if (winMultiWindowGetClassHint(pFrame->win, &res_name, &res_class)) {
239*4882a593Smuzhiyun strncat(pszClass, "-", 1);
240*4882a593Smuzhiyun strncat(pszClass, res_name, CLASS_NAME_LENGTH - strlen(pszClass));
241*4882a593Smuzhiyun strncat(pszClass, "-", 1);
242*4882a593Smuzhiyun strncat(pszClass, res_class, CLASS_NAME_LENGTH - strlen(pszClass));
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun /* Check if a window class is provided by the WM_WINDOW_ROLE property,
245*4882a593Smuzhiyun * if not use the WM_CLASS information.
246*4882a593Smuzhiyun * For further information see:
247*4882a593Smuzhiyun * http://tronche.com/gui/x/icccm/sec-5.html
248*4882a593Smuzhiyun */
249*4882a593Smuzhiyun if (winMultiWindowGetWindowRole(pFrame->win, &res_role)) {
250*4882a593Smuzhiyun strcat(pszClass, "-");
251*4882a593Smuzhiyun strcat(pszClass, res_role);
252*4882a593Smuzhiyun free(res_role);
253*4882a593Smuzhiyun }
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun free(res_name);
256*4882a593Smuzhiyun free(res_class);
257*4882a593Smuzhiyun }
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun /* Add incrementing window ID to make unique class name */
260*4882a593Smuzhiyun snprintf(pszWindowID, sizeof(pszWindowID), "-%x", s_iWindowID++);
261*4882a593Smuzhiyun pszWindowID[sizeof(pszWindowID) - 1] = 0;
262*4882a593Smuzhiyun strcat(pszClass, pszWindowID);
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
265*4882a593Smuzhiyun winDebug("winMWExtWMCreateFrame - Creating class: %s\n", pszClass);
266*4882a593Smuzhiyun #endif
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun /* Setup our window class */
269*4882a593Smuzhiyun wc.cbSize = sizeof(wc);
270*4882a593Smuzhiyun wc.style = CS_HREDRAW | CS_VREDRAW;
271*4882a593Smuzhiyun wc.lpfnWndProc = winMWExtWMWindowProc;
272*4882a593Smuzhiyun wc.cbClsExtra = 0;
273*4882a593Smuzhiyun wc.cbWndExtra = 0;
274*4882a593Smuzhiyun wc.hInstance = g_hInstance;
275*4882a593Smuzhiyun wc.hIcon = hIcon;
276*4882a593Smuzhiyun wc.hIconSm = hIconSmall;
277*4882a593Smuzhiyun wc.hCursor = 0;
278*4882a593Smuzhiyun wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
279*4882a593Smuzhiyun wc.lpszMenuName = NULL;
280*4882a593Smuzhiyun wc.lpszClassName = pszClass;
281*4882a593Smuzhiyun RegisterClassEx(&wc);
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun /* Create the window */
284*4882a593Smuzhiyun g_fNoConfigureWindow = TRUE;
285*4882a593Smuzhiyun pRLWinPriv->hWnd = CreateWindowExA(WS_EX_TOOLWINDOW, /* Extended styles */
286*4882a593Smuzhiyun pszClass, /* Class name */
287*4882a593Smuzhiyun WINDOW_TITLE_X, /* Window name */
288*4882a593Smuzhiyun WS_POPUP | WS_CLIPCHILDREN, newX, /* Horizontal position */
289*4882a593Smuzhiyun newY, /* Vertical position */
290*4882a593Smuzhiyun pFrame->width, /* Right edge */
291*4882a593Smuzhiyun pFrame->height, /* Bottom edge */
292*4882a593Smuzhiyun (HWND) NULL, /* No parent or owner window */
293*4882a593Smuzhiyun (HMENU) NULL, /* No menu */
294*4882a593Smuzhiyun GetModuleHandle(NULL), /* Instance handle */
295*4882a593Smuzhiyun pRLWinPriv); /* ScreenPrivates */
296*4882a593Smuzhiyun if (pRLWinPriv->hWnd == NULL) {
297*4882a593Smuzhiyun ErrorF("winMWExtWMCreateFrame - CreateWindowExA () failed: %d\n",
298*4882a593Smuzhiyun (int) GetLastError());
299*4882a593Smuzhiyun fResult = FALSE;
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
303*4882a593Smuzhiyun winDebug("winMWExtWMCreateFrame - ShowWindow\n");
304*4882a593Smuzhiyun #endif
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun //ShowWindow (pRLWinPriv->hWnd, SW_SHOWNOACTIVATE);
307*4882a593Smuzhiyun g_fNoConfigureWindow = FALSE;
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun if (pShape != NULL) {
310*4882a593Smuzhiyun winMWExtWMReshapeFrame(pFrame->wid, pShape);
311*4882a593Smuzhiyun }
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
314*4882a593Smuzhiyun winDebug("winMWExtWMCreateFrame - (%p) %p\n",
315*4882a593Smuzhiyun pFrame->wid, pRLWinPriv->hWnd);
316*4882a593Smuzhiyun #if 0
317*4882a593Smuzhiyun {
318*4882a593Smuzhiyun WindowPtr pWin2 = NULL;
319*4882a593Smuzhiyun win32RootlessWindowPtr pRLWinPriv2 = NULL;
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun /* Check if the Windows window property for our X window pointer is valid */
322*4882a593Smuzhiyun if ((pWin2 =
323*4882a593Smuzhiyun (WindowPtr) GetProp(pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) {
324*4882a593Smuzhiyun pRLWinPriv2 =
325*4882a593Smuzhiyun (win32RootlessWindowPtr) RootlessFrameForWindow(pWin2, FALSE);
326*4882a593Smuzhiyun }
327*4882a593Smuzhiyun winDebug("winMWExtWMCreateFrame2 (%08x) %08x\n",
328*4882a593Smuzhiyun pRLWinPriv2, pRLWinPriv2->hWnd);
329*4882a593Smuzhiyun if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) {
330*4882a593Smuzhiyun winDebug("Error param missmatch\n");
331*4882a593Smuzhiyun }
332*4882a593Smuzhiyun }
333*4882a593Smuzhiyun #endif
334*4882a593Smuzhiyun #endif
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun winMWExtWMSetNativeProperty(pFrame);
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun return fResult;
339*4882a593Smuzhiyun }
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun void
winMWExtWMDestroyFrame(RootlessFrameID wid)342*4882a593Smuzhiyun winMWExtWMDestroyFrame(RootlessFrameID wid)
343*4882a593Smuzhiyun {
344*4882a593Smuzhiyun win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
345*4882a593Smuzhiyun HICON hIcon;
346*4882a593Smuzhiyun HICON hIconSm;
347*4882a593Smuzhiyun HMODULE hInstance;
348*4882a593Smuzhiyun int iReturn;
349*4882a593Smuzhiyun char pszClass[CLASS_NAME_LENGTH];
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
352*4882a593Smuzhiyun winDebug("winMWExtWMDestroyFrame (%p) %p\n",
353*4882a593Smuzhiyun pRLWinPriv, pRLWinPriv->hWnd);
354*4882a593Smuzhiyun #if 0
355*4882a593Smuzhiyun {
356*4882a593Smuzhiyun WindowPtr pWin2 = NULL;
357*4882a593Smuzhiyun win32RootlessWindowPtr pRLWinPriv2 = NULL;
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun /* Check if the Windows window property for our X window pointer is valid */
360*4882a593Smuzhiyun if ((pWin2 =
361*4882a593Smuzhiyun (WindowPtr) GetProp(pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) {
362*4882a593Smuzhiyun pRLWinPriv2 =
363*4882a593Smuzhiyun (win32RootlessWindowPtr) RootlessFrameForWindow(pWin2, FALSE);
364*4882a593Smuzhiyun }
365*4882a593Smuzhiyun winDebug("winMWExtWMDestroyFrame2 (%08x) %08x\n",
366*4882a593Smuzhiyun pRLWinPriv2, pRLWinPriv2->hWnd);
367*4882a593Smuzhiyun if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) {
368*4882a593Smuzhiyun winDebug("Error param missmatch\n");
369*4882a593Smuzhiyun *(int *) 0 = 1; //raise exseption
370*4882a593Smuzhiyun }
371*4882a593Smuzhiyun }
372*4882a593Smuzhiyun #endif
373*4882a593Smuzhiyun #endif
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun /* Store the info we need to destroy after this window is gone */
376*4882a593Smuzhiyun hInstance = (HINSTANCE) GetClassLongPtr(pRLWinPriv->hWnd, GCLP_HMODULE);
377*4882a593Smuzhiyun hIcon = (HICON) SendMessage(pRLWinPriv->hWnd, WM_GETICON, ICON_BIG, 0);
378*4882a593Smuzhiyun hIconSm = (HICON) SendMessage(pRLWinPriv->hWnd, WM_GETICON, ICON_SMALL, 0);
379*4882a593Smuzhiyun iReturn = GetClassName(pRLWinPriv->hWnd, pszClass, CLASS_NAME_LENGTH);
380*4882a593Smuzhiyun
381*4882a593Smuzhiyun pRLWinPriv->fClose = TRUE;
382*4882a593Smuzhiyun pRLWinPriv->fDestroyed = TRUE;
383*4882a593Smuzhiyun
384*4882a593Smuzhiyun /* Destroy the Windows window */
385*4882a593Smuzhiyun DestroyWindow(pRLWinPriv->hWnd);
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun /* Only if we were able to get the name */
388*4882a593Smuzhiyun if (iReturn) {
389*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
390*4882a593Smuzhiyun winDebug("winMWExtWMDestroyFrame - Unregistering %s: ", pszClass);
391*4882a593Smuzhiyun #endif
392*4882a593Smuzhiyun iReturn = UnregisterClass(pszClass, hInstance);
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
396*4882a593Smuzhiyun winDebug("winMWExtWMDestroyFramew - Deleting Icon\n");
397*4882a593Smuzhiyun #endif
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun winDestroyIcon(hIcon);
400*4882a593Smuzhiyun winDestroyIcon(hIconSm);
401*4882a593Smuzhiyun
402*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
403*4882a593Smuzhiyun winDebug("winMWExtWMDestroyFrame - done\n");
404*4882a593Smuzhiyun #endif
405*4882a593Smuzhiyun }
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun void
winMWExtWMMoveFrame(RootlessFrameID wid,ScreenPtr pScreen,int iNewX,int iNewY)408*4882a593Smuzhiyun winMWExtWMMoveFrame(RootlessFrameID wid, ScreenPtr pScreen, int iNewX,
409*4882a593Smuzhiyun int iNewY)
410*4882a593Smuzhiyun {
411*4882a593Smuzhiyun win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
412*4882a593Smuzhiyun RECT rcNew;
413*4882a593Smuzhiyun DWORD dwExStyle;
414*4882a593Smuzhiyun DWORD dwStyle;
415*4882a593Smuzhiyun int iX, iY, iWidth, iHeight;
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
418*4882a593Smuzhiyun winDebug("winMWExtWMMoveFrame (%p) (%d %d)\n", pRLWinPriv, iNewX,
419*4882a593Smuzhiyun iNewY);
420*4882a593Smuzhiyun #endif
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun /* Get the Windows window style and extended style */
423*4882a593Smuzhiyun dwExStyle = GetWindowLongPtr(pRLWinPriv->hWnd, GWL_EXSTYLE);
424*4882a593Smuzhiyun dwStyle = GetWindowLongPtr(pRLWinPriv->hWnd, GWL_STYLE);
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun /* Get the X and Y location of the X window */
427*4882a593Smuzhiyun iX = iNewX + GetSystemMetrics(SM_XVIRTUALSCREEN);
428*4882a593Smuzhiyun iY = iNewY + GetSystemMetrics(SM_YVIRTUALSCREEN);
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun /* Get the height and width of the X window */
431*4882a593Smuzhiyun iWidth = pRLWinPriv->pFrame->width;
432*4882a593Smuzhiyun iHeight = pRLWinPriv->pFrame->height;
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun /* Store the origin, height, and width in a rectangle structure */
435*4882a593Smuzhiyun SetRect(&rcNew, iX, iY, iX + iWidth, iY + iHeight);
436*4882a593Smuzhiyun
437*4882a593Smuzhiyun #ifdef CYGMULTIWINDOW_DEBUG
438*4882a593Smuzhiyun winDebug("\tWindow {%d, %d, %d, %d}, {%d, %d}\n",
439*4882a593Smuzhiyun rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
440*4882a593Smuzhiyun rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
441*4882a593Smuzhiyun #endif
442*4882a593Smuzhiyun /*
443*4882a593Smuzhiyun * Calculate the required size of the Windows window rectangle,
444*4882a593Smuzhiyun * given the size of the Windows window client area.
445*4882a593Smuzhiyun */
446*4882a593Smuzhiyun AdjustWindowRectEx(&rcNew, dwStyle, FALSE, dwExStyle);
447*4882a593Smuzhiyun
448*4882a593Smuzhiyun #ifdef CYGMULTIWINDOW_DEBUG
449*4882a593Smuzhiyun winDebug("\tAdjusted {%d, %d, %d, %d}, {%d, %d}\n",
450*4882a593Smuzhiyun rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
451*4882a593Smuzhiyun rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
452*4882a593Smuzhiyun #endif
453*4882a593Smuzhiyun g_fNoConfigureWindow = TRUE;
454*4882a593Smuzhiyun SetWindowPos(pRLWinPriv->hWnd, NULL, rcNew.left, rcNew.top, 0, 0,
455*4882a593Smuzhiyun SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
456*4882a593Smuzhiyun g_fNoConfigureWindow = FALSE;
457*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
458*4882a593Smuzhiyun winDebug("winMWExtWMMoveFrame (%p) done\n", pRLWinPriv);
459*4882a593Smuzhiyun #endif
460*4882a593Smuzhiyun }
461*4882a593Smuzhiyun
462*4882a593Smuzhiyun void
winMWExtWMResizeFrame(RootlessFrameID wid,ScreenPtr pScreen,int iNewX,int iNewY,unsigned int uiNewWidth,unsigned int uiNewHeight,unsigned int uiGravity)463*4882a593Smuzhiyun winMWExtWMResizeFrame(RootlessFrameID wid, ScreenPtr pScreen,
464*4882a593Smuzhiyun int iNewX, int iNewY,
465*4882a593Smuzhiyun unsigned int uiNewWidth, unsigned int uiNewHeight,
466*4882a593Smuzhiyun unsigned int uiGravity)
467*4882a593Smuzhiyun {
468*4882a593Smuzhiyun win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
469*4882a593Smuzhiyun RECT rcNew;
470*4882a593Smuzhiyun RECT rcOld;
471*4882a593Smuzhiyun DWORD dwExStyle;
472*4882a593Smuzhiyun DWORD dwStyle;
473*4882a593Smuzhiyun int iX, iY;
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
476*4882a593Smuzhiyun winDebug("winMWExtWMResizeFrame (%p) (%d %d)-(%d %d)\n",
477*4882a593Smuzhiyun pRLWinPriv, iNewX, iNewY, uiNewWidth, uiNewHeight);
478*4882a593Smuzhiyun #endif
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun pRLWinPriv->fResized = TRUE;
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun /* Get the Windows window style and extended style */
483*4882a593Smuzhiyun dwExStyle = GetWindowLongPtr(pRLWinPriv->hWnd, GWL_EXSTYLE);
484*4882a593Smuzhiyun dwStyle = GetWindowLongPtr(pRLWinPriv->hWnd, GWL_STYLE);
485*4882a593Smuzhiyun
486*4882a593Smuzhiyun /* Get the X and Y location of the X window */
487*4882a593Smuzhiyun iX = iNewX + GetSystemMetrics(SM_XVIRTUALSCREEN);
488*4882a593Smuzhiyun iY = iNewY + GetSystemMetrics(SM_YVIRTUALSCREEN);
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun /* Store the origin, height, and width in a rectangle structure */
491*4882a593Smuzhiyun SetRect(&rcNew, iX, iY, iX + uiNewWidth, iY + uiNewHeight);
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun /*
494*4882a593Smuzhiyun * Calculate the required size of the Windows window rectangle,
495*4882a593Smuzhiyun * given the size of the Windows window client area.
496*4882a593Smuzhiyun */
497*4882a593Smuzhiyun AdjustWindowRectEx(&rcNew, dwStyle, FALSE, dwExStyle);
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun /* Get a rectangle describing the old Windows window */
500*4882a593Smuzhiyun GetWindowRect(pRLWinPriv->hWnd, &rcOld);
501*4882a593Smuzhiyun
502*4882a593Smuzhiyun /* Check if the old rectangle and new rectangle are the same */
503*4882a593Smuzhiyun if (!EqualRect(&rcNew, &rcOld)) {
504*4882a593Smuzhiyun
505*4882a593Smuzhiyun g_fNoConfigureWindow = TRUE;
506*4882a593Smuzhiyun MoveWindow(pRLWinPriv->hWnd,
507*4882a593Smuzhiyun rcNew.left, rcNew.top,
508*4882a593Smuzhiyun rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, TRUE);
509*4882a593Smuzhiyun g_fNoConfigureWindow = FALSE;
510*4882a593Smuzhiyun }
511*4882a593Smuzhiyun }
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun void
winMWExtWMRestackFrame(RootlessFrameID wid,RootlessFrameID nextWid)514*4882a593Smuzhiyun winMWExtWMRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid)
515*4882a593Smuzhiyun {
516*4882a593Smuzhiyun win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
517*4882a593Smuzhiyun win32RootlessWindowPtr pRLNextWinPriv = (win32RootlessWindowPtr) nextWid;
518*4882a593Smuzhiyun
519*4882a593Smuzhiyun winScreenPriv(pRLWinPriv->pFrame->win->drawable.pScreen);
520*4882a593Smuzhiyun
521*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
522*4882a593Smuzhiyun winDebug("winMWExtWMRestackFrame (%p)\n", pRLWinPriv);
523*4882a593Smuzhiyun #endif
524*4882a593Smuzhiyun
525*4882a593Smuzhiyun if (pScreenPriv && pScreenPriv->fRestacking)
526*4882a593Smuzhiyun return;
527*4882a593Smuzhiyun
528*4882a593Smuzhiyun pRLWinPriv->fRestackingNow = TRUE;
529*4882a593Smuzhiyun
530*4882a593Smuzhiyun /* Show window */
531*4882a593Smuzhiyun if (!IsWindowVisible(pRLWinPriv->hWnd))
532*4882a593Smuzhiyun ShowWindow(pRLWinPriv->hWnd, SW_SHOWNOACTIVATE);
533*4882a593Smuzhiyun
534*4882a593Smuzhiyun if (pRLNextWinPriv == NULL) {
535*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
536*4882a593Smuzhiyun winDebug("Win %p is top\n", pRLWinPriv);
537*4882a593Smuzhiyun #endif
538*4882a593Smuzhiyun pScreenPriv->widTop = wid;
539*4882a593Smuzhiyun SetWindowPos(pRLWinPriv->hWnd, HWND_TOP,
540*4882a593Smuzhiyun 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
541*4882a593Smuzhiyun }
542*4882a593Smuzhiyun else {
543*4882a593Smuzhiyun /* using general wm like twm, wmaker etc.
544*4882a593Smuzhiyun Interleave X window and Windows window will cause problem. */
545*4882a593Smuzhiyun SetWindowPos(pRLWinPriv->hWnd, pRLNextWinPriv->hWnd,
546*4882a593Smuzhiyun 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
547*4882a593Smuzhiyun }
548*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
549*4882a593Smuzhiyun winDebug("winMWExtWMRestackFrame - done (%p)\n", pRLWinPriv);
550*4882a593Smuzhiyun #endif
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun pRLWinPriv->fRestackingNow = FALSE;
553*4882a593Smuzhiyun }
554*4882a593Smuzhiyun
555*4882a593Smuzhiyun void
winMWExtWMReshapeFrame(RootlessFrameID wid,RegionPtr pShape)556*4882a593Smuzhiyun winMWExtWMReshapeFrame(RootlessFrameID wid, RegionPtr pShape)
557*4882a593Smuzhiyun {
558*4882a593Smuzhiyun win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
559*4882a593Smuzhiyun HRGN hRgn, hRgnWindow, hRgnClient;
560*4882a593Smuzhiyun RECT rcWindow, rcClient;
561*4882a593Smuzhiyun
562*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
563*4882a593Smuzhiyun winDebug("winMWExtWMReshapeFrame (%p)\n", pRLWinPriv);
564*4882a593Smuzhiyun #endif
565*4882a593Smuzhiyun
566*4882a593Smuzhiyun hRgn = winMWExtWMCreateRgnFromRegion(pShape);
567*4882a593Smuzhiyun
568*4882a593Smuzhiyun /* Create region for non-client area */
569*4882a593Smuzhiyun GetWindowRect(pRLWinPriv->hWnd, &rcWindow);
570*4882a593Smuzhiyun GetClientRect(pRLWinPriv->hWnd, &rcClient);
571*4882a593Smuzhiyun MapWindowPoints(pRLWinPriv->hWnd, HWND_DESKTOP, (LPPOINT) &rcClient, 2);
572*4882a593Smuzhiyun OffsetRgn(hRgn, rcClient.left - rcWindow.left, rcClient.top - rcWindow.top);
573*4882a593Smuzhiyun OffsetRect(&rcClient, -rcWindow.left, -rcWindow.top);
574*4882a593Smuzhiyun OffsetRect(&rcWindow, -rcWindow.left, -rcWindow.top);
575*4882a593Smuzhiyun hRgnWindow = CreateRectRgnIndirect(&rcWindow);
576*4882a593Smuzhiyun hRgnClient = CreateRectRgnIndirect(&rcClient);
577*4882a593Smuzhiyun CombineRgn(hRgnWindow, hRgnWindow, hRgnClient, RGN_DIFF);
578*4882a593Smuzhiyun CombineRgn(hRgn, hRgnWindow, hRgn, RGN_OR);
579*4882a593Smuzhiyun
580*4882a593Smuzhiyun SetWindowRgn(pRLWinPriv->hWnd, hRgn, TRUE);
581*4882a593Smuzhiyun
582*4882a593Smuzhiyun DeleteObject(hRgnWindow);
583*4882a593Smuzhiyun DeleteObject(hRgnClient);
584*4882a593Smuzhiyun }
585*4882a593Smuzhiyun
586*4882a593Smuzhiyun void
winMWExtWMUnmapFrame(RootlessFrameID wid)587*4882a593Smuzhiyun winMWExtWMUnmapFrame(RootlessFrameID wid)
588*4882a593Smuzhiyun {
589*4882a593Smuzhiyun win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
590*4882a593Smuzhiyun
591*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
592*4882a593Smuzhiyun winDebug("winMWExtWMUnmapFrame (%p)\n", pRLWinPriv);
593*4882a593Smuzhiyun #endif
594*4882a593Smuzhiyun
595*4882a593Smuzhiyun g_fNoConfigureWindow = TRUE;
596*4882a593Smuzhiyun //ShowWindow (pRLWinPriv->hWnd, SW_MINIMIZE);
597*4882a593Smuzhiyun ShowWindow(pRLWinPriv->hWnd, SW_HIDE);
598*4882a593Smuzhiyun g_fNoConfigureWindow = FALSE;
599*4882a593Smuzhiyun }
600*4882a593Smuzhiyun
601*4882a593Smuzhiyun /*
602*4882a593Smuzhiyun * Fixme: Code sharing with winshadgdi.c and other engine support
603*4882a593Smuzhiyun */
604*4882a593Smuzhiyun void
winMWExtWMStartDrawing(RootlessFrameID wid,char ** pixelData,int * bytesPerRow)605*4882a593Smuzhiyun winMWExtWMStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow)
606*4882a593Smuzhiyun {
607*4882a593Smuzhiyun win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
608*4882a593Smuzhiyun winPrivScreenPtr pScreenPriv = NULL;
609*4882a593Smuzhiyun winScreenInfo *pScreenInfo = NULL;
610*4882a593Smuzhiyun ScreenPtr pScreen = NULL;
611*4882a593Smuzhiyun DIBSECTION dibsection;
612*4882a593Smuzhiyun Bool fReturn = TRUE;
613*4882a593Smuzhiyun HDC hdcNew;
614*4882a593Smuzhiyun HBITMAP hbmpNew;
615*4882a593Smuzhiyun
616*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
617*4882a593Smuzhiyun winDebug("winMWExtWMStartDrawing (%p) %08x\n", pRLWinPriv,
618*4882a593Smuzhiyun pRLWinPriv->fDestroyed);
619*4882a593Smuzhiyun #endif
620*4882a593Smuzhiyun
621*4882a593Smuzhiyun if (!pRLWinPriv->fDestroyed) {
622*4882a593Smuzhiyun pScreen = pRLWinPriv->pFrame->win->drawable.pScreen;
623*4882a593Smuzhiyun if (pScreen)
624*4882a593Smuzhiyun pScreenPriv = winGetScreenPriv(pScreen);
625*4882a593Smuzhiyun if (pScreenPriv)
626*4882a593Smuzhiyun pScreenInfo = pScreenPriv->pScreenInfo;
627*4882a593Smuzhiyun
628*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
629*4882a593Smuzhiyun winDebug("\tpScreenPriv %p\n", pScreenPriv);
630*4882a593Smuzhiyun winDebug("\tpScreenInfo %p\n", pScreenInfo);
631*4882a593Smuzhiyun winDebug("\t(%d, %d)\n", (int) pRLWinPriv->pFrame->width,
632*4882a593Smuzhiyun (int) pRLWinPriv->pFrame->height);
633*4882a593Smuzhiyun #endif
634*4882a593Smuzhiyun if (pRLWinPriv->hdcScreen == NULL) {
635*4882a593Smuzhiyun InitWin32RootlessEngine(pRLWinPriv);
636*4882a593Smuzhiyun }
637*4882a593Smuzhiyun
638*4882a593Smuzhiyun if (pRLWinPriv->fResized) {
639*4882a593Smuzhiyun /* width * bpp must be multiple of 4 to match 32bit alignment */
640*4882a593Smuzhiyun int stridesize;
641*4882a593Smuzhiyun int misalignment;
642*4882a593Smuzhiyun
643*4882a593Smuzhiyun pRLWinPriv->pbmihShadow->biWidth = pRLWinPriv->pFrame->width;
644*4882a593Smuzhiyun pRLWinPriv->pbmihShadow->biHeight = -pRLWinPriv->pFrame->height;
645*4882a593Smuzhiyun
646*4882a593Smuzhiyun stridesize = pRLWinPriv->pFrame->width * (pScreenInfo->dwBPP >> 3);
647*4882a593Smuzhiyun misalignment = stridesize & 3;
648*4882a593Smuzhiyun if (misalignment != 0) {
649*4882a593Smuzhiyun stridesize += 4 - misalignment;
650*4882a593Smuzhiyun pRLWinPriv->pbmihShadow->biWidth =
651*4882a593Smuzhiyun stridesize / (pScreenInfo->dwBPP >> 3);
652*4882a593Smuzhiyun winDebug("\tresizing to %d (was %d)\n",
653*4882a593Smuzhiyun pRLWinPriv->pbmihShadow->biWidth,
654*4882a593Smuzhiyun pRLWinPriv->pFrame->width);
655*4882a593Smuzhiyun }
656*4882a593Smuzhiyun
657*4882a593Smuzhiyun hdcNew = CreateCompatibleDC(pRLWinPriv->hdcScreen);
658*4882a593Smuzhiyun /* Create a DI shadow bitmap with a bit pointer */
659*4882a593Smuzhiyun hbmpNew = CreateDIBSection(pRLWinPriv->hdcScreen,
660*4882a593Smuzhiyun (BITMAPINFO *) pRLWinPriv->pbmihShadow,
661*4882a593Smuzhiyun DIB_RGB_COLORS,
662*4882a593Smuzhiyun (VOID **) &pRLWinPriv->pfb, NULL, 0);
663*4882a593Smuzhiyun if (hbmpNew == NULL || pRLWinPriv->pfb == NULL) {
664*4882a593Smuzhiyun ErrorF("winMWExtWMStartDrawing - CreateDIBSection failed\n");
665*4882a593Smuzhiyun //return FALSE;
666*4882a593Smuzhiyun }
667*4882a593Smuzhiyun else {
668*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
669*4882a593Smuzhiyun winDebug("winMWExtWMStartDrawing - Shadow buffer allocated\n");
670*4882a593Smuzhiyun #endif
671*4882a593Smuzhiyun }
672*4882a593Smuzhiyun
673*4882a593Smuzhiyun /* Get information about the bitmap that was allocated */
674*4882a593Smuzhiyun GetObject(hbmpNew, sizeof(dibsection), &dibsection);
675*4882a593Smuzhiyun
676*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
677*4882a593Smuzhiyun /* Print information about bitmap allocated */
678*4882a593Smuzhiyun winDebug("winMWExtWMStartDrawing - Dibsection width: %d height: %d "
679*4882a593Smuzhiyun "depth: %d size image: %d\n",
680*4882a593Smuzhiyun (unsigned int) dibsection.dsBmih.biWidth,
681*4882a593Smuzhiyun (unsigned int) dibsection.dsBmih.biHeight,
682*4882a593Smuzhiyun (unsigned int) dibsection.dsBmih.biBitCount,
683*4882a593Smuzhiyun (unsigned int) dibsection.dsBmih.biSizeImage);
684*4882a593Smuzhiyun #endif
685*4882a593Smuzhiyun
686*4882a593Smuzhiyun /* Select the shadow bitmap into the shadow DC */
687*4882a593Smuzhiyun SelectObject(hdcNew, hbmpNew);
688*4882a593Smuzhiyun
689*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
690*4882a593Smuzhiyun winDebug("winMWExtWMStartDrawing - Attempting a shadow blit\n");
691*4882a593Smuzhiyun #endif
692*4882a593Smuzhiyun
693*4882a593Smuzhiyun /* Blit from the old shadow to the new shadow */
694*4882a593Smuzhiyun fReturn = BitBlt(hdcNew,
695*4882a593Smuzhiyun 0, 0,
696*4882a593Smuzhiyun pRLWinPriv->pFrame->width,
697*4882a593Smuzhiyun pRLWinPriv->pFrame->height, pRLWinPriv->hdcShadow,
698*4882a593Smuzhiyun 0, 0, SRCCOPY);
699*4882a593Smuzhiyun if (fReturn) {
700*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
701*4882a593Smuzhiyun winDebug("winMWExtWMStartDrawing - Shadow blit success\n");
702*4882a593Smuzhiyun #endif
703*4882a593Smuzhiyun }
704*4882a593Smuzhiyun else {
705*4882a593Smuzhiyun ErrorF("winMWExtWMStartDrawing - Shadow blit failure\n");
706*4882a593Smuzhiyun }
707*4882a593Smuzhiyun
708*4882a593Smuzhiyun /* Look for height weirdness */
709*4882a593Smuzhiyun if (dibsection.dsBmih.biHeight < 0) {
710*4882a593Smuzhiyun /* FIXME: Figure out why biHeight is sometimes negative */
711*4882a593Smuzhiyun ErrorF("winMWExtWMStartDrawing - WEIRDNESS - "
712*4882a593Smuzhiyun "biHeight still negative: %d\n",
713*4882a593Smuzhiyun (int) dibsection.dsBmih.biHeight);
714*4882a593Smuzhiyun ErrorF("winMWExtWMStartDrawing - WEIRDNESS - "
715*4882a593Smuzhiyun "Flipping biHeight sign\n");
716*4882a593Smuzhiyun dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight;
717*4882a593Smuzhiyun }
718*4882a593Smuzhiyun
719*4882a593Smuzhiyun pRLWinPriv->dwWidthBytes = dibsection.dsBm.bmWidthBytes;
720*4882a593Smuzhiyun
721*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
722*4882a593Smuzhiyun winDebug("winMWExtWMStartDrawing - bytesPerRow: %d\n",
723*4882a593Smuzhiyun (unsigned int) dibsection.dsBm.bmWidthBytes);
724*4882a593Smuzhiyun #endif
725*4882a593Smuzhiyun
726*4882a593Smuzhiyun /* Free the old shadow bitmap */
727*4882a593Smuzhiyun DeleteObject(pRLWinPriv->hdcShadow);
728*4882a593Smuzhiyun DeleteObject(pRLWinPriv->hbmpShadow);
729*4882a593Smuzhiyun
730*4882a593Smuzhiyun pRLWinPriv->hdcShadow = hdcNew;
731*4882a593Smuzhiyun pRLWinPriv->hbmpShadow = hbmpNew;
732*4882a593Smuzhiyun
733*4882a593Smuzhiyun pRLWinPriv->fResized = FALSE;
734*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG && FALSE
735*4882a593Smuzhiyun winDebug("winMWExtWMStartDrawing - 0x%08x %d\n",
736*4882a593Smuzhiyun (unsigned int) pRLWinPriv->pfb,
737*4882a593Smuzhiyun (unsigned int) dibsection.dsBm.bmWidthBytes);
738*4882a593Smuzhiyun #endif
739*4882a593Smuzhiyun }
740*4882a593Smuzhiyun }
741*4882a593Smuzhiyun else {
742*4882a593Smuzhiyun ErrorF("winMWExtWMStartDrawing - Already window was destroyed \n");
743*4882a593Smuzhiyun }
744*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
745*4882a593Smuzhiyun winDebug("winMWExtWMStartDrawing - done (%p) %p %d\n",
746*4882a593Smuzhiyun pRLWinPriv,
747*4882a593Smuzhiyun pRLWinPriv->pfb,
748*4882a593Smuzhiyun (unsigned int) pRLWinPriv->dwWidthBytes);
749*4882a593Smuzhiyun #endif
750*4882a593Smuzhiyun *pixelData = pRLWinPriv->pfb;
751*4882a593Smuzhiyun *bytesPerRow = pRLWinPriv->dwWidthBytes;
752*4882a593Smuzhiyun }
753*4882a593Smuzhiyun
754*4882a593Smuzhiyun void
winMWExtWMStopDrawing(RootlessFrameID wid,Bool fFlush)755*4882a593Smuzhiyun winMWExtWMStopDrawing(RootlessFrameID wid, Bool fFlush)
756*4882a593Smuzhiyun {
757*4882a593Smuzhiyun #if 0
758*4882a593Smuzhiyun win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
759*4882a593Smuzhiyun BLENDFUNCTION bfBlend;
760*4882a593Smuzhiyun SIZE szWin;
761*4882a593Smuzhiyun POINT ptSrc;
762*4882a593Smuzhiyun
763*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG || TRUE
764*4882a593Smuzhiyun winDebug("winMWExtWMStopDrawing (%08x)\n", pRLWinPriv);
765*4882a593Smuzhiyun #endif
766*4882a593Smuzhiyun szWin.cx = pRLWinPriv->dwWidth;
767*4882a593Smuzhiyun szWin.cy = pRLWinPriv->dwHeight;
768*4882a593Smuzhiyun ptSrc.x = 0;
769*4882a593Smuzhiyun ptSrc.y = 0;
770*4882a593Smuzhiyun bfBlend.BlendOp = AC_SRC_OVER;
771*4882a593Smuzhiyun bfBlend.BlendFlags = 0;
772*4882a593Smuzhiyun bfBlend.SourceConstantAlpha = 255;
773*4882a593Smuzhiyun bfBlend.AlphaFormat = AC_SRC_ALPHA;
774*4882a593Smuzhiyun
775*4882a593Smuzhiyun if (!UpdateLayeredWindow(pRLWinPriv->hWnd,
776*4882a593Smuzhiyun NULL, NULL, &szWin,
777*4882a593Smuzhiyun pRLWinPriv->hdcShadow, &ptSrc,
778*4882a593Smuzhiyun 0, &bfBlend, ULW_ALPHA)) {
779*4882a593Smuzhiyun ErrorF("winMWExtWMStopDrawing - UpdateLayeredWindow failed\n");
780*4882a593Smuzhiyun }
781*4882a593Smuzhiyun #endif
782*4882a593Smuzhiyun }
783*4882a593Smuzhiyun
784*4882a593Smuzhiyun void
winMWExtWMUpdateRegion(RootlessFrameID wid,RegionPtr pDamage)785*4882a593Smuzhiyun winMWExtWMUpdateRegion(RootlessFrameID wid, RegionPtr pDamage)
786*4882a593Smuzhiyun {
787*4882a593Smuzhiyun win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
788*4882a593Smuzhiyun
789*4882a593Smuzhiyun #if 0
790*4882a593Smuzhiyun BLENDFUNCTION bfBlend;
791*4882a593Smuzhiyun SIZE szWin;
792*4882a593Smuzhiyun POINT ptSrc;
793*4882a593Smuzhiyun #endif
794*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG && 0
795*4882a593Smuzhiyun winDebug("winMWExtWMUpdateRegion (%08x)\n", pRLWinPriv);
796*4882a593Smuzhiyun #endif
797*4882a593Smuzhiyun #if 0
798*4882a593Smuzhiyun szWin.cx = pRLWinPriv->dwWidth;
799*4882a593Smuzhiyun szWin.cy = pRLWinPriv->dwHeight;
800*4882a593Smuzhiyun ptSrc.x = 0;
801*4882a593Smuzhiyun ptSrc.y = 0;
802*4882a593Smuzhiyun bfBlend.BlendOp = AC_SRC_OVER;
803*4882a593Smuzhiyun bfBlend.BlendFlags = 0;
804*4882a593Smuzhiyun bfBlend.SourceConstantAlpha = 255;
805*4882a593Smuzhiyun bfBlend.AlphaFormat = AC_SRC_ALPHA;
806*4882a593Smuzhiyun
807*4882a593Smuzhiyun if (!UpdateLayeredWindow(pRLWinPriv->hWnd,
808*4882a593Smuzhiyun NULL, NULL, &szWin,
809*4882a593Smuzhiyun pRLWinPriv->hdcShadow, &ptSrc,
810*4882a593Smuzhiyun 0, &bfBlend, ULW_ALPHA)) {
811*4882a593Smuzhiyun LPVOID lpMsgBuf;
812*4882a593Smuzhiyun
813*4882a593Smuzhiyun /* Display a fancy error message */
814*4882a593Smuzhiyun FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
815*4882a593Smuzhiyun FORMAT_MESSAGE_FROM_SYSTEM |
816*4882a593Smuzhiyun FORMAT_MESSAGE_IGNORE_INSERTS,
817*4882a593Smuzhiyun NULL,
818*4882a593Smuzhiyun GetLastError(),
819*4882a593Smuzhiyun MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
820*4882a593Smuzhiyun (LPTSTR) &lpMsgBuf, 0, NULL);
821*4882a593Smuzhiyun
822*4882a593Smuzhiyun ErrorF("winMWExtWMUpdateRegion - UpdateLayeredWindow failed: %s\n",
823*4882a593Smuzhiyun (LPSTR) lpMsgBuf);
824*4882a593Smuzhiyun LocalFree(lpMsgBuf);
825*4882a593Smuzhiyun }
826*4882a593Smuzhiyun #endif
827*4882a593Smuzhiyun if (!g_fNoConfigureWindow)
828*4882a593Smuzhiyun UpdateWindow(pRLWinPriv->hWnd);
829*4882a593Smuzhiyun }
830*4882a593Smuzhiyun
831*4882a593Smuzhiyun void
winMWExtWMDamageRects(RootlessFrameID wid,int nCount,const BoxRec * pRects,int shift_x,int shift_y)832*4882a593Smuzhiyun winMWExtWMDamageRects(RootlessFrameID wid, int nCount, const BoxRec * pRects,
833*4882a593Smuzhiyun int shift_x, int shift_y)
834*4882a593Smuzhiyun {
835*4882a593Smuzhiyun win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
836*4882a593Smuzhiyun const BoxRec *pEnd;
837*4882a593Smuzhiyun
838*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG && 0
839*4882a593Smuzhiyun winDebug("winMWExtWMDamageRects (%08x, %d, %08x, %d, %d)\n",
840*4882a593Smuzhiyun pRLWinPriv, nCount, pRects, shift_x, shift_y);
841*4882a593Smuzhiyun #endif
842*4882a593Smuzhiyun
843*4882a593Smuzhiyun for (pEnd = pRects + nCount; pRects < pEnd; pRects++) {
844*4882a593Smuzhiyun RECT rcDmg;
845*4882a593Smuzhiyun
846*4882a593Smuzhiyun rcDmg.left = pRects->x1 + shift_x;
847*4882a593Smuzhiyun rcDmg.top = pRects->y1 + shift_y;
848*4882a593Smuzhiyun rcDmg.right = pRects->x2 + shift_x;
849*4882a593Smuzhiyun rcDmg.bottom = pRects->y2 + shift_y;
850*4882a593Smuzhiyun
851*4882a593Smuzhiyun InvalidateRect(pRLWinPriv->hWnd, &rcDmg, FALSE);
852*4882a593Smuzhiyun }
853*4882a593Smuzhiyun }
854*4882a593Smuzhiyun
855*4882a593Smuzhiyun void
winMWExtWMRootlessSwitchWindow(RootlessWindowPtr pFrame,WindowPtr oldWin)856*4882a593Smuzhiyun winMWExtWMRootlessSwitchWindow(RootlessWindowPtr pFrame, WindowPtr oldWin)
857*4882a593Smuzhiyun {
858*4882a593Smuzhiyun win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid;
859*4882a593Smuzhiyun
860*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
861*4882a593Smuzhiyun winDebug("winMWExtWMRootlessSwitchWindow (%p) %p\n",
862*4882a593Smuzhiyun pRLWinPriv, pRLWinPriv->hWnd);
863*4882a593Smuzhiyun #endif
864*4882a593Smuzhiyun pRLWinPriv->pFrame = pFrame;
865*4882a593Smuzhiyun pRLWinPriv->fResized = TRUE;
866*4882a593Smuzhiyun
867*4882a593Smuzhiyun /* Set the window extended style flags */
868*4882a593Smuzhiyun SetWindowLongPtr(pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
869*4882a593Smuzhiyun
870*4882a593Smuzhiyun /* Set the window standard style flags */
871*4882a593Smuzhiyun SetWindowLongPtr(pRLWinPriv->hWnd, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN);
872*4882a593Smuzhiyun
873*4882a593Smuzhiyun DeleteProperty(serverClient, oldWin, AtmWindowsWmNativeHwnd());
874*4882a593Smuzhiyun winMWExtWMSetNativeProperty(pFrame);
875*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
876*4882a593Smuzhiyun #if 0
877*4882a593Smuzhiyun {
878*4882a593Smuzhiyun WindowPtr pWin2 = NULL;
879*4882a593Smuzhiyun win32RootlessWindowPtr pRLWinPriv2 = NULL;
880*4882a593Smuzhiyun
881*4882a593Smuzhiyun /* Check if the Windows window property for our X window pointer is valid */
882*4882a593Smuzhiyun if ((pWin2 =
883*4882a593Smuzhiyun (WindowPtr) GetProp(pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) {
884*4882a593Smuzhiyun pRLWinPriv2 =
885*4882a593Smuzhiyun (win32RootlessWindowPtr) RootlessFrameForWindow(pWin2, FALSE);
886*4882a593Smuzhiyun }
887*4882a593Smuzhiyun winDebug("winMWExtWMSwitchFrame2 (%08x) %08x\n",
888*4882a593Smuzhiyun pRLWinPriv2, pRLWinPriv2->hWnd);
889*4882a593Smuzhiyun if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) {
890*4882a593Smuzhiyun winDebug("Error param missmatch\n");
891*4882a593Smuzhiyun }
892*4882a593Smuzhiyun }
893*4882a593Smuzhiyun #endif
894*4882a593Smuzhiyun #endif
895*4882a593Smuzhiyun }
896*4882a593Smuzhiyun
897*4882a593Smuzhiyun void
winMWExtWMCopyBytes(unsigned int width,unsigned int height,const void * src,unsigned int srcRowBytes,void * dst,unsigned int dstRowBytes)898*4882a593Smuzhiyun winMWExtWMCopyBytes(unsigned int width, unsigned int height,
899*4882a593Smuzhiyun const void *src, unsigned int srcRowBytes,
900*4882a593Smuzhiyun void *dst, unsigned int dstRowBytes)
901*4882a593Smuzhiyun {
902*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
903*4882a593Smuzhiyun winDebug("winMWExtWMCopyBytes - Not implemented\n");
904*4882a593Smuzhiyun #endif
905*4882a593Smuzhiyun }
906*4882a593Smuzhiyun
907*4882a593Smuzhiyun void
winMWExtWMCopyWindow(RootlessFrameID wid,int nDstRects,const BoxRec * pDstRects,int nDx,int nDy)908*4882a593Smuzhiyun winMWExtWMCopyWindow(RootlessFrameID wid, int nDstRects,
909*4882a593Smuzhiyun const BoxRec * pDstRects, int nDx, int nDy)
910*4882a593Smuzhiyun {
911*4882a593Smuzhiyun win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
912*4882a593Smuzhiyun const BoxRec *pEnd;
913*4882a593Smuzhiyun RECT rcDmg;
914*4882a593Smuzhiyun
915*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
916*4882a593Smuzhiyun winDebug("winMWExtWMCopyWindow (%p, %d, %p, %d, %d)\n",
917*4882a593Smuzhiyun pRLWinPriv, nDstRects, pDstRects, nDx, nDy);
918*4882a593Smuzhiyun #endif
919*4882a593Smuzhiyun
920*4882a593Smuzhiyun for (pEnd = pDstRects + nDstRects; pDstRects < pEnd; pDstRects++) {
921*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
922*4882a593Smuzhiyun winDebug("BitBlt (%d, %d, %d, %d) (%d, %d)\n",
923*4882a593Smuzhiyun pDstRects->x1, pDstRects->y1,
924*4882a593Smuzhiyun pDstRects->x2 - pDstRects->x1,
925*4882a593Smuzhiyun pDstRects->y2 - pDstRects->y1,
926*4882a593Smuzhiyun pDstRects->x1 + nDx, pDstRects->y1 + nDy);
927*4882a593Smuzhiyun #endif
928*4882a593Smuzhiyun
929*4882a593Smuzhiyun if (!BitBlt(pRLWinPriv->hdcShadow,
930*4882a593Smuzhiyun pDstRects->x1, pDstRects->y1,
931*4882a593Smuzhiyun pDstRects->x2 - pDstRects->x1,
932*4882a593Smuzhiyun pDstRects->y2 - pDstRects->y1,
933*4882a593Smuzhiyun pRLWinPriv->hdcShadow,
934*4882a593Smuzhiyun pDstRects->x1 + nDx, pDstRects->y1 + nDy, SRCCOPY)) {
935*4882a593Smuzhiyun ErrorF("winMWExtWMCopyWindow - BitBlt failed.\n");
936*4882a593Smuzhiyun }
937*4882a593Smuzhiyun
938*4882a593Smuzhiyun rcDmg.left = pDstRects->x1;
939*4882a593Smuzhiyun rcDmg.top = pDstRects->y1;
940*4882a593Smuzhiyun rcDmg.right = pDstRects->x2;
941*4882a593Smuzhiyun rcDmg.bottom = pDstRects->y2;
942*4882a593Smuzhiyun
943*4882a593Smuzhiyun InvalidateRect(pRLWinPriv->hWnd, &rcDmg, FALSE);
944*4882a593Smuzhiyun }
945*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
946*4882a593Smuzhiyun winDebug("winMWExtWMCopyWindow - done\n");
947*4882a593Smuzhiyun #endif
948*4882a593Smuzhiyun }
949*4882a593Smuzhiyun
950*4882a593Smuzhiyun /*
951*4882a593Smuzhiyun * winMWExtWMSetNativeProperty
952*4882a593Smuzhiyun */
953*4882a593Smuzhiyun
954*4882a593Smuzhiyun static void
winMWExtWMSetNativeProperty(RootlessWindowPtr pFrame)955*4882a593Smuzhiyun winMWExtWMSetNativeProperty(RootlessWindowPtr pFrame)
956*4882a593Smuzhiyun {
957*4882a593Smuzhiyun win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid;
958*4882a593Smuzhiyun long lData;
959*4882a593Smuzhiyun
960*4882a593Smuzhiyun /* FIXME: move this to WindowsWM extension */
961*4882a593Smuzhiyun
962*4882a593Smuzhiyun lData = (long) pRLWinPriv->hWnd;
963*4882a593Smuzhiyun dixChangeWindowProperty(serverClient, pFrame->win, AtmWindowsWmNativeHwnd(),
964*4882a593Smuzhiyun XA_INTEGER, 32, PropModeReplace, 1, &lData, TRUE);
965*4882a593Smuzhiyun }
966