2 *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
4 *Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 *"Software"), to deal in the Software without restriction, including
7 *without limitation the rights to use, copy, modify, merge, publish,
8 *distribute, sublicense, and/or sell copies of the Software, and to
9 *permit persons to whom the Software is furnished to do so, subject to
10 *the following conditions:
12 *The above copyright notice and this permission notice shall be
13 *included in all copies or substantial portions of the Software.
15 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
19 *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20 *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *Except as contained in this notice, the name of the XFree86 Project
24 *shall not be used in advertising or otherwise to promote the sale, use
25 *or other dealings in this Software without prior written authorization
26 *from the XFree86 Project.
28 * Authors: Kensuke Matsuzaki
29 * Earle F. Philhower, III
33 * Look at hw/darwin/quartz/xpr/xprFrame.c and hw/darwin/quartz/cr/crFrame.c
35 #ifdef HAVE_XWIN_CONFIG_H
36 #include <xwin-config.h>
40 #define _WINDOWSWM_SERVER_
41 #include <X11/extensions/windowswmstr.h>
42 #include "dixevents.h"
43 #include "winmultiwindowclass.h"
44 #include <X11/Xatom.h>
51 #define ULW_COLORKEY 0x00000001
54 #define ULW_ALPHA 0x00000002
57 #define ULW_OPAQUE 0x00000004
59 #define AC_SRC_ALPHA 0x01
65 DEFINE_ATOM_HELPER(AtmWindowsWmNativeHwnd
, WINDOWSWM_NATIVE_HWND
)
67 winMWExtWMSetNativeProperty(RootlessWindowPtr pFrame
);
73 Bool g_fNoConfigureWindow
= FALSE
;
76 * Internal function to get the DIB format that is compatible with the screen
77 * Fixme: Share code with winshadgdi.c
82 winMWExtWMQueryDIBFormat(win32RootlessWindowPtr pRLWinPriv
,
83 BITMAPINFOHEADER
* pbmih
)
87 #if CYGMULTIWINDOW_DEBUG
91 /* Create a memory bitmap compatible with the screen */
92 hbmp
= CreateCompatibleBitmap(pRLWinPriv
->hdcScreen
, 1, 1);
94 ErrorF("winMWExtWMQueryDIBFormat - CreateCompatibleBitmap failed\n");
98 /* Initialize our bitmap info header */
99 ZeroMemory(pbmih
, sizeof(BITMAPINFOHEADER
) + 256 * sizeof(RGBQUAD
));
100 pbmih
->biSize
= sizeof(BITMAPINFOHEADER
);
102 /* Get the biBitCount */
103 if (!GetDIBits(pRLWinPriv
->hdcScreen
,
104 hbmp
, 0, 1, NULL
, (BITMAPINFO
*) pbmih
, DIB_RGB_COLORS
)) {
105 ErrorF("winMWExtWMQueryDIBFormat - First call to GetDIBits failed\n");
110 #if CYGMULTIWINDOW_DEBUG
111 /* Get a pointer to bitfields */
112 pdw
= (DWORD
*) ((CARD8
*) pbmih
+ sizeof(BITMAPINFOHEADER
));
114 winDebug("winMWExtWMQueryDIBFormat - First call masks: %08x %08x %08x\n",
115 (unsigned int) pdw
[0], (unsigned int) pdw
[1],
116 (unsigned int) pdw
[2]);
119 /* Get optimal color table, or the optimal bitfields */
120 if (!GetDIBits(pRLWinPriv
->hdcScreen
,
121 hbmp
, 0, 1, NULL
, (BITMAPINFO
*) pbmih
, DIB_RGB_COLORS
)) {
122 ErrorF("winMWExtWMQueryDIBFormat - Second call to GetDIBits "
135 winMWExtWMCreateRgnFromRegion(RegionPtr pShape
)
144 nRects
= RegionNumRects(pShape
);
145 pRects
= RegionRects(pShape
);
147 hRgn
= CreateRectRgn(0, 0, 0, 0);
149 ErrorF("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) "
150 "failed: %d\n", 0, 0, 0, 0, (int) GetLastError());
153 /* Loop through all rectangles in the X region */
154 for (pEnd
= pRects
+ nRects
; pRects
< pEnd
; pRects
++) {
155 /* Create a Windows region for the X rectangle */
156 hRgnRect
= CreateRectRgn(pRects
->x1
,
157 pRects
->y1
, pRects
->x2
, pRects
->y2
);
158 if (hRgnRect
== NULL
) {
159 ErrorF("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) "
162 pRects
->y1
, pRects
->x2
, pRects
->y2
, (int) GetLastError());
165 /* Merge the Windows region with the accumulated region */
166 if (CombineRgn(hRgn
, hRgn
, hRgnRect
, RGN_OR
) == ERROR
) {
167 ErrorF("winReshape - CombineRgn () failed: %d\n",
168 (int) GetLastError());
171 /* Delete the temporary Windows region */
172 DeleteObject(hRgnRect
);
179 InitWin32RootlessEngine(win32RootlessWindowPtr pRLWinPriv
)
181 pRLWinPriv
->hdcScreen
= GetDC(pRLWinPriv
->hWnd
);
182 pRLWinPriv
->hdcShadow
= CreateCompatibleDC(pRLWinPriv
->hdcScreen
);
183 pRLWinPriv
->hbmpShadow
= NULL
;
185 /* Allocate bitmap info header */
186 pRLWinPriv
->pbmihShadow
=
187 (BITMAPINFOHEADER
*) malloc(sizeof(BITMAPINFOHEADER
)
188 + 256 * sizeof(RGBQUAD
));
189 if (pRLWinPriv
->pbmihShadow
== NULL
) {
190 ErrorF("InitWin32RootlessEngine - malloc () failed\n");
194 /* Query the screen format */
195 winMWExtWMQueryDIBFormat(pRLWinPriv
, pRLWinPriv
->pbmihShadow
);
199 winMWExtWMCreateFrame(RootlessWindowPtr pFrame
, ScreenPtr pScreen
,
200 int newX
, int newY
, RegionPtr pShape
)
202 #define CLASS_NAME_LENGTH 512
204 win32RootlessWindowPtr pRLWinPriv
;
206 char pszClass
[CLASS_NAME_LENGTH
], pszWindowID
[12];
209 char *res_name
, *res_class
, *res_role
;
210 static int s_iWindowID
= 0;
212 #if CYGMULTIWINDOW_DEBUG
213 winDebug("winMWExtWMCreateFrame %d %d - %d %d\n",
214 newX
, newY
, pFrame
->width
, pFrame
->height
);
218 (win32RootlessWindowPtr
) malloc(sizeof(win32RootlessWindowRec
));
219 pRLWinPriv
->pFrame
= pFrame
;
220 pRLWinPriv
->pfb
= NULL
;
221 pRLWinPriv
->hbmpShadow
= NULL
;
222 pRLWinPriv
->hdcShadow
= NULL
;
223 pRLWinPriv
->hdcScreen
= NULL
;
224 pRLWinPriv
->pbmihShadow
= NULL
;
225 pRLWinPriv
->fResized
= TRUE
;
226 pRLWinPriv
->fClose
= FALSE
;
227 pRLWinPriv
->fRestackingNow
= FALSE
;
228 pRLWinPriv
->fDestroyed
= FALSE
;
229 pRLWinPriv
->fMovingOrSizing
= FALSE
;
231 // Store the implementation private frame ID
232 pFrame
->wid
= (RootlessFrameID
) pRLWinPriv
;
234 winSelectIcons(&hIcon
, &hIconSmall
);
236 /* Set standard class name prefix so we can identify window easily */
237 strncpy(pszClass
, WINDOW_CLASS_X
, sizeof(pszClass
));
239 if (winMultiWindowGetClassHint(pFrame
->win
, &res_name
, &res_class
)) {
240 strncat(pszClass
, "-", 1);
241 strncat(pszClass
, res_name
, CLASS_NAME_LENGTH
- strlen(pszClass
));
242 strncat(pszClass
, "-", 1);
243 strncat(pszClass
, res_class
, CLASS_NAME_LENGTH
- strlen(pszClass
));
245 /* Check if a window class is provided by the WM_WINDOW_ROLE property,
246 * if not use the WM_CLASS information.
247 * For further information see:
248 * http://tronche.com/gui/x/icccm/sec-5.html
250 if (winMultiWindowGetWindowRole(pFrame
->win
, &res_role
)) {
251 strcat(pszClass
, "-");
252 strcat(pszClass
, res_role
);
260 /* Add incrementing window ID to make unique class name */
261 snprintf(pszWindowID
, sizeof(pszWindowID
), "-%x", s_iWindowID
++);
262 pszWindowID
[sizeof(pszWindowID
) - 1] = 0;
263 strcat(pszClass
, pszWindowID
);
265 #if CYGMULTIWINDOW_DEBUG
266 winDebug("winMWExtWMCreateFrame - Creating class: %s\n", pszClass
);
269 /* Setup our window class */
270 wc
.cbSize
= sizeof(wc
);
271 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
272 wc
.lpfnWndProc
= winMWExtWMWindowProc
;
275 wc
.hInstance
= g_hInstance
;
277 wc
.hIconSm
= hIconSmall
;
279 wc
.hbrBackground
= (HBRUSH
) GetStockObject(WHITE_BRUSH
);
280 wc
.lpszMenuName
= NULL
;
281 wc
.lpszClassName
= pszClass
;
282 RegisterClassEx(&wc
);
284 /* Create the window */
285 g_fNoConfigureWindow
= TRUE
;
286 pRLWinPriv
->hWnd
= CreateWindowExA(WS_EX_TOOLWINDOW
, /* Extended styles */
287 pszClass
, /* Class name */
288 WINDOW_TITLE_X
, /* Window name */
289 WS_POPUP
| WS_CLIPCHILDREN
, newX
, /* Horizontal position */
290 newY
, /* Vertical position */
291 pFrame
->width
, /* Right edge */
292 pFrame
->height
, /* Bottom edge */
293 (HWND
) NULL
, /* No parent or owner window */
294 (HMENU
) NULL
, /* No menu */
295 GetModuleHandle(NULL
), /* Instance handle */
296 pRLWinPriv
); /* ScreenPrivates */
297 if (pRLWinPriv
->hWnd
== NULL
) {
298 ErrorF("winMWExtWMCreateFrame - CreateWindowExA () failed: %d\n",
299 (int) GetLastError());
303 #if CYGMULTIWINDOW_DEBUG
304 winDebug("winMWExtWMCreateFrame - ShowWindow\n");
307 //ShowWindow (pRLWinPriv->hWnd, SW_SHOWNOACTIVATE);
308 g_fNoConfigureWindow
= FALSE
;
310 if (pShape
!= NULL
) {
311 winMWExtWMReshapeFrame(pFrame
->wid
, pShape
);
314 #if CYGMULTIWINDOW_DEBUG
315 winDebug("winMWExtWMCreateFrame - (%p) %p\n",
316 pFrame
->wid
, pRLWinPriv
->hWnd
);
319 WindowPtr pWin2
= NULL
;
320 win32RootlessWindowPtr pRLWinPriv2
= NULL
;
322 /* Check if the Windows window property for our X window pointer is valid */
324 (WindowPtr
) GetProp(pRLWinPriv
->hWnd
, WIN_WINDOW_PROP
)) != NULL
) {
326 (win32RootlessWindowPtr
) RootlessFrameForWindow(pWin2
, FALSE
);
328 winDebug("winMWExtWMCreateFrame2 (%08x) %08x\n",
329 pRLWinPriv2
, pRLWinPriv2
->hWnd
);
330 if (pRLWinPriv
!= pRLWinPriv2
|| pRLWinPriv
->hWnd
!= pRLWinPriv2
->hWnd
) {
331 winDebug("Error param missmatch\n");
337 winMWExtWMSetNativeProperty(pFrame
);
343 winMWExtWMDestroyFrame(RootlessFrameID wid
)
345 win32RootlessWindowPtr pRLWinPriv
= (win32RootlessWindowPtr
) wid
;
350 char pszClass
[CLASS_NAME_LENGTH
];
352 #if CYGMULTIWINDOW_DEBUG
353 winDebug("winMWExtWMDestroyFrame (%p) %p\n",
354 pRLWinPriv
, pRLWinPriv
->hWnd
);
357 WindowPtr pWin2
= NULL
;
358 win32RootlessWindowPtr pRLWinPriv2
= NULL
;
360 /* Check if the Windows window property for our X window pointer is valid */
362 (WindowPtr
) GetProp(pRLWinPriv
->hWnd
, WIN_WINDOW_PROP
)) != NULL
) {
364 (win32RootlessWindowPtr
) RootlessFrameForWindow(pWin2
, FALSE
);
366 winDebug("winMWExtWMDestroyFrame2 (%08x) %08x\n",
367 pRLWinPriv2
, pRLWinPriv2
->hWnd
);
368 if (pRLWinPriv
!= pRLWinPriv2
|| pRLWinPriv
->hWnd
!= pRLWinPriv2
->hWnd
) {
369 winDebug("Error param missmatch\n");
370 *(int *) 0 = 1; //raise exseption
376 /* Store the info we need to destroy after this window is gone */
377 hInstance
= (HINSTANCE
) GetClassLongPtr(pRLWinPriv
->hWnd
, GCLP_HMODULE
);
378 hIcon
= (HICON
) SendMessage(pRLWinPriv
->hWnd
, WM_GETICON
, ICON_BIG
, 0);
379 hIconSm
= (HICON
) SendMessage(pRLWinPriv
->hWnd
, WM_GETICON
, ICON_SMALL
, 0);
380 iReturn
= GetClassName(pRLWinPriv
->hWnd
, pszClass
, CLASS_NAME_LENGTH
);
382 pRLWinPriv
->fClose
= TRUE
;
383 pRLWinPriv
->fDestroyed
= TRUE
;
385 /* Destroy the Windows window */
386 DestroyWindow(pRLWinPriv
->hWnd
);
388 /* Only if we were able to get the name */
390 #if CYGMULTIWINDOW_DEBUG
391 winDebug("winMWExtWMDestroyFrame - Unregistering %s: ", pszClass
);
393 iReturn
= UnregisterClass(pszClass
, hInstance
);
396 #if CYGMULTIWINDOW_DEBUG
397 winDebug("winMWExtWMDestroyFramew - Deleting Icon\n");
400 winDestroyIcon(hIcon
);
401 winDestroyIcon(hIconSm
);
403 #if CYGMULTIWINDOW_DEBUG
404 winDebug("winMWExtWMDestroyFrame - done\n");
409 winMWExtWMMoveFrame(RootlessFrameID wid
, ScreenPtr pScreen
, int iNewX
,
412 win32RootlessWindowPtr pRLWinPriv
= (win32RootlessWindowPtr
) wid
;
416 int iX
, iY
, iWidth
, iHeight
;
418 #if CYGMULTIWINDOW_DEBUG
419 winDebug("winMWExtWMMoveFrame (%p) (%d %d)\n", pRLWinPriv
, iNewX
,
423 /* Get the Windows window style and extended style */
424 dwExStyle
= GetWindowLongPtr(pRLWinPriv
->hWnd
, GWL_EXSTYLE
);
425 dwStyle
= GetWindowLongPtr(pRLWinPriv
->hWnd
, GWL_STYLE
);
427 /* Get the X and Y location of the X window */
428 iX
= iNewX
+ GetSystemMetrics(SM_XVIRTUALSCREEN
);
429 iY
= iNewY
+ GetSystemMetrics(SM_YVIRTUALSCREEN
);
431 /* Get the height and width of the X window */
432 iWidth
= pRLWinPriv
->pFrame
->width
;
433 iHeight
= pRLWinPriv
->pFrame
->height
;
435 /* Store the origin, height, and width in a rectangle structure */
436 SetRect(&rcNew
, iX
, iY
, iX
+ iWidth
, iY
+ iHeight
);
438 #ifdef CYGMULTIWINDOW_DEBUG
439 winDebug("\tWindow {%d, %d, %d, %d}, {%d, %d}\n",
440 rcNew
.left
, rcNew
.top
, rcNew
.right
, rcNew
.bottom
,
441 rcNew
.right
- rcNew
.left
, rcNew
.bottom
- rcNew
.top
);
444 * Calculate the required size of the Windows window rectangle,
445 * given the size of the Windows window client area.
447 AdjustWindowRectEx(&rcNew
, dwStyle
, FALSE
, dwExStyle
);
449 #ifdef CYGMULTIWINDOW_DEBUG
450 winDebug("\tAdjusted {%d, %d, %d, %d}, {%d, %d}\n",
451 rcNew
.left
, rcNew
.top
, rcNew
.right
, rcNew
.bottom
,
452 rcNew
.right
- rcNew
.left
, rcNew
.bottom
- rcNew
.top
);
454 g_fNoConfigureWindow
= TRUE
;
455 SetWindowPos(pRLWinPriv
->hWnd
, NULL
, rcNew
.left
, rcNew
.top
, 0, 0,
456 SWP_NOACTIVATE
| SWP_NOSIZE
| SWP_NOZORDER
);
457 g_fNoConfigureWindow
= FALSE
;
458 #if CYGMULTIWINDOW_DEBUG
459 winDebug("winMWExtWMMoveFrame (%p) done\n", pRLWinPriv
);
464 winMWExtWMResizeFrame(RootlessFrameID wid
, ScreenPtr pScreen
,
465 int iNewX
, int iNewY
,
466 unsigned int uiNewWidth
, unsigned int uiNewHeight
,
467 unsigned int uiGravity
)
469 win32RootlessWindowPtr pRLWinPriv
= (win32RootlessWindowPtr
) wid
;
476 #if CYGMULTIWINDOW_DEBUG
477 winDebug("winMWExtWMResizeFrame (%p) (%d %d)-(%d %d)\n",
478 pRLWinPriv
, iNewX
, iNewY
, uiNewWidth
, uiNewHeight
);
481 pRLWinPriv
->fResized
= TRUE
;
483 /* Get the Windows window style and extended style */
484 dwExStyle
= GetWindowLongPtr(pRLWinPriv
->hWnd
, GWL_EXSTYLE
);
485 dwStyle
= GetWindowLongPtr(pRLWinPriv
->hWnd
, GWL_STYLE
);
487 /* Get the X and Y location of the X window */
488 iX
= iNewX
+ GetSystemMetrics(SM_XVIRTUALSCREEN
);
489 iY
= iNewY
+ GetSystemMetrics(SM_YVIRTUALSCREEN
);
491 /* Store the origin, height, and width in a rectangle structure */
492 SetRect(&rcNew
, iX
, iY
, iX
+ uiNewWidth
, iY
+ uiNewHeight
);
495 * Calculate the required size of the Windows window rectangle,
496 * given the size of the Windows window client area.
498 AdjustWindowRectEx(&rcNew
, dwStyle
, FALSE
, dwExStyle
);
500 /* Get a rectangle describing the old Windows window */
501 GetWindowRect(pRLWinPriv
->hWnd
, &rcOld
);
503 /* Check if the old rectangle and new rectangle are the same */
504 if (!EqualRect(&rcNew
, &rcOld
)) {
506 g_fNoConfigureWindow
= TRUE
;
507 MoveWindow(pRLWinPriv
->hWnd
,
508 rcNew
.left
, rcNew
.top
,
509 rcNew
.right
- rcNew
.left
, rcNew
.bottom
- rcNew
.top
, TRUE
);
510 g_fNoConfigureWindow
= FALSE
;
515 winMWExtWMRestackFrame(RootlessFrameID wid
, RootlessFrameID nextWid
)
517 win32RootlessWindowPtr pRLWinPriv
= (win32RootlessWindowPtr
) wid
;
518 win32RootlessWindowPtr pRLNextWinPriv
= (win32RootlessWindowPtr
) nextWid
;
520 winScreenPriv(pRLWinPriv
->pFrame
->win
->drawable
.pScreen
);
521 winScreenInfo
*pScreenInfo
= NULL
;
522 DWORD dwCurrentProcessID
= GetCurrentProcessId();
523 DWORD dwWindowProcessID
= 0;
526 Bool fNeedRestack
= TRUE
;
528 #if CYGMULTIWINDOW_DEBUG
529 winDebug("winMWExtWMRestackFrame (%p)\n", pRLWinPriv
);
532 if (pScreenPriv
&& pScreenPriv
->fRestacking
)
536 pScreenInfo
= pScreenPriv
->pScreenInfo
;
538 pRLWinPriv
->fRestackingNow
= TRUE
;
541 if (!IsWindowVisible(pRLWinPriv
->hWnd
))
542 ShowWindow(pRLWinPriv
->hWnd
, SW_SHOWNOACTIVATE
);
544 if (pRLNextWinPriv
== NULL
) {
545 #if CYGMULTIWINDOW_DEBUG
546 winDebug("Win %08x is top\n", pRLWinPriv
);
548 pScreenPriv
->widTop
= wid
;
549 SetWindowPos(pRLWinPriv
->hWnd
, HWND_TOP
,
550 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
);
552 else if (winIsInternalWMRunning(pScreenInfo
)) {
553 /* using mulwinidow wm */
554 #if CYGMULTIWINDOW_DEBUG
555 winDebug("Win %08x is not top\n", pRLWinPriv
);
557 for (hWnd
= GetNextWindow(pRLWinPriv
->hWnd
, GW_HWNDPREV
);
558 fNeedRestack
&& hWnd
!= NULL
;
559 hWnd
= GetNextWindow(hWnd
, GW_HWNDPREV
)) {
560 GetWindowThreadProcessId(hWnd
, &dwWindowProcessID
);
562 if ((dwWindowProcessID
== dwCurrentProcessID
)
563 && GetProp(hWnd
, WIN_WINDOW_PROP
)) {
564 if (hWnd
== pRLNextWinPriv
->hWnd
) {
565 /* Enable interleave X window and Windows window */
567 #if CYGMULTIWINDOW_DEBUG
568 winDebug("raise: Insert after Win %08x\n",
571 SetWindowPos(pRLWinPriv
->hWnd
, pRLNextWinPriv
->hWnd
,
573 SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
);
576 #if CYGMULTIWINDOW_DEBUG
577 winDebug("No change\n");
580 fNeedRestack
= FALSE
;
588 for (hWnd
= GetNextWindow(pRLWinPriv
->hWnd
, GW_HWNDNEXT
);
589 fNeedRestack
&& hWnd
!= NULL
;
590 hWnd
= GetNextWindow(hWnd
, GW_HWNDNEXT
)) {
591 GetWindowThreadProcessId(hWnd
, &dwWindowProcessID
);
593 if ((dwWindowProcessID
== dwCurrentProcessID
)
594 && GetProp(hWnd
, WIN_WINDOW_PROP
)) {
595 if (hWnd
== pRLNextWinPriv
->hWnd
) {
596 #if CYGMULTIWINDOW_DEBUG
597 winDebug("lower: Insert after Win %08x\n", pRLNextWinPriv
);
599 SetWindowPos(pRLWinPriv
->hWnd
, pRLNextWinPriv
->hWnd
,
601 SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
);
602 fNeedRestack
= FALSE
;
609 /* using general wm like twm, wmaker etc.
610 Interleave X window and Windows window will cause problem. */
611 SetWindowPos(pRLWinPriv
->hWnd
, pRLNextWinPriv
->hWnd
,
612 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
);
614 #if CYGMULTIWINDOW_DEBUG
615 winDebug("winMWExtWMRestackFrame - done (%p)\n", pRLWinPriv
);
618 pRLWinPriv
->fRestackingNow
= FALSE
;
622 winMWExtWMReshapeFrame(RootlessFrameID wid
, RegionPtr pShape
)
624 win32RootlessWindowPtr pRLWinPriv
= (win32RootlessWindowPtr
) wid
;
625 HRGN hRgn
, hRgnWindow
, hRgnClient
;
626 RECT rcWindow
, rcClient
;
628 #if CYGMULTIWINDOW_DEBUG
629 winDebug("winMWExtWMReshapeFrame (%p)\n", pRLWinPriv
);
632 hRgn
= winMWExtWMCreateRgnFromRegion(pShape
);
634 /* Create region for non-client area */
635 GetWindowRect(pRLWinPriv
->hWnd
, &rcWindow
);
636 GetClientRect(pRLWinPriv
->hWnd
, &rcClient
);
637 MapWindowPoints(pRLWinPriv
->hWnd
, HWND_DESKTOP
, (LPPOINT
) &rcClient
, 2);
638 OffsetRgn(hRgn
, rcClient
.left
- rcWindow
.left
, rcClient
.top
- rcWindow
.top
);
639 OffsetRect(&rcClient
, -rcWindow
.left
, -rcWindow
.top
);
640 OffsetRect(&rcWindow
, -rcWindow
.left
, -rcWindow
.top
);
641 hRgnWindow
= CreateRectRgnIndirect(&rcWindow
);
642 hRgnClient
= CreateRectRgnIndirect(&rcClient
);
643 CombineRgn(hRgnWindow
, hRgnWindow
, hRgnClient
, RGN_DIFF
);
644 CombineRgn(hRgn
, hRgnWindow
, hRgn
, RGN_OR
);
646 SetWindowRgn(pRLWinPriv
->hWnd
, hRgn
, TRUE
);
648 DeleteObject(hRgnWindow
);
649 DeleteObject(hRgnClient
);
653 winMWExtWMUnmapFrame(RootlessFrameID wid
)
655 win32RootlessWindowPtr pRLWinPriv
= (win32RootlessWindowPtr
) wid
;
657 #if CYGMULTIWINDOW_DEBUG
658 winDebug("winMWExtWMUnmapFrame (%p)\n", pRLWinPriv
);
661 g_fNoConfigureWindow
= TRUE
;
662 //ShowWindow (pRLWinPriv->hWnd, SW_MINIMIZE);
663 ShowWindow(pRLWinPriv
->hWnd
, SW_HIDE
);
664 g_fNoConfigureWindow
= FALSE
;
668 * Fixme: Code sharing with winshadgdi.c and other engine support
671 winMWExtWMStartDrawing(RootlessFrameID wid
, char **pixelData
, int *bytesPerRow
)
673 win32RootlessWindowPtr pRLWinPriv
= (win32RootlessWindowPtr
) wid
;
674 winPrivScreenPtr pScreenPriv
= NULL
;
675 winScreenInfo
*pScreenInfo
= NULL
;
676 ScreenPtr pScreen
= NULL
;
677 DIBSECTION dibsection
;
682 #if CYGMULTIWINDOW_DEBUG
683 winDebug("winMWExtWMStartDrawing (%p) %08x\n", pRLWinPriv
,
684 pRLWinPriv
->fDestroyed
);
687 if (!pRLWinPriv
->fDestroyed
) {
688 pScreen
= pRLWinPriv
->pFrame
->win
->drawable
.pScreen
;
690 pScreenPriv
= winGetScreenPriv(pScreen
);
692 pScreenInfo
= pScreenPriv
->pScreenInfo
;
694 #if CYGMULTIWINDOW_DEBUG
695 winDebug("\tpScreenPriv %p\n", pScreenPriv
);
696 winDebug("\tpScreenInfo %p\n", pScreenInfo
);
697 winDebug("\t(%d, %d)\n", (int) pRLWinPriv
->pFrame
->width
,
698 (int) pRLWinPriv
->pFrame
->height
);
700 if (pRLWinPriv
->hdcScreen
== NULL
) {
701 InitWin32RootlessEngine(pRLWinPriv
);
704 if (pRLWinPriv
->fResized
) {
705 /* width * bpp must be multiple of 4 to match 32bit alignment */
709 pRLWinPriv
->pbmihShadow
->biWidth
= pRLWinPriv
->pFrame
->width
;
710 pRLWinPriv
->pbmihShadow
->biHeight
= -pRLWinPriv
->pFrame
->height
;
712 stridesize
= pRLWinPriv
->pFrame
->width
* (pScreenInfo
->dwBPP
>> 3);
713 misalignment
= stridesize
& 3;
714 if (misalignment
!= 0) {
715 stridesize
+= 4 - misalignment
;
716 pRLWinPriv
->pbmihShadow
->biWidth
=
717 stridesize
/ (pScreenInfo
->dwBPP
>> 3);
718 winDebug("\tresizing to %d (was %d)\n",
719 pRLWinPriv
->pbmihShadow
->biWidth
,
720 pRLWinPriv
->pFrame
->width
);
723 hdcNew
= CreateCompatibleDC(pRLWinPriv
->hdcScreen
);
724 /* Create a DI shadow bitmap with a bit pointer */
725 hbmpNew
= CreateDIBSection(pRLWinPriv
->hdcScreen
,
726 (BITMAPINFO
*) pRLWinPriv
->pbmihShadow
,
728 (VOID
**) &pRLWinPriv
->pfb
, NULL
, 0);
729 if (hbmpNew
== NULL
|| pRLWinPriv
->pfb
== NULL
) {
730 ErrorF("winMWExtWMStartDrawing - CreateDIBSection failed\n");
734 #if CYGMULTIWINDOW_DEBUG
735 winDebug("winMWExtWMStartDrawing - Shadow buffer allocated\n");
739 /* Get information about the bitmap that was allocated */
740 GetObject(hbmpNew
, sizeof(dibsection
), &dibsection
);
742 #if CYGMULTIWINDOW_DEBUG
743 /* Print information about bitmap allocated */
744 winDebug("winMWExtWMStartDrawing - Dibsection width: %d height: %d "
745 "depth: %d size image: %d\n",
746 (unsigned int) dibsection
.dsBmih
.biWidth
,
747 (unsigned int) dibsection
.dsBmih
.biHeight
,
748 (unsigned int) dibsection
.dsBmih
.biBitCount
,
749 (unsigned int) dibsection
.dsBmih
.biSizeImage
);
752 /* Select the shadow bitmap into the shadow DC */
753 SelectObject(hdcNew
, hbmpNew
);
755 #if CYGMULTIWINDOW_DEBUG
756 winDebug("winMWExtWMStartDrawing - Attempting a shadow blit\n");
759 /* Blit from the old shadow to the new shadow */
760 fReturn
= BitBlt(hdcNew
,
762 pRLWinPriv
->pFrame
->width
,
763 pRLWinPriv
->pFrame
->height
, pRLWinPriv
->hdcShadow
,
766 #if CYGMULTIWINDOW_DEBUG
767 winDebug("winMWExtWMStartDrawing - Shadow blit success\n");
771 ErrorF("winMWExtWMStartDrawing - Shadow blit failure\n");
774 /* Look for height weirdness */
775 if (dibsection
.dsBmih
.biHeight
< 0) {
776 /* FIXME: Figure out why biHeight is sometimes negative */
777 ErrorF("winMWExtWMStartDrawing - WEIRDNESS - "
778 "biHeight still negative: %d\n",
779 (int) dibsection
.dsBmih
.biHeight
);
780 ErrorF("winMWExtWMStartDrawing - WEIRDNESS - "
781 "Flipping biHeight sign\n");
782 dibsection
.dsBmih
.biHeight
= -dibsection
.dsBmih
.biHeight
;
785 pRLWinPriv
->dwWidthBytes
= dibsection
.dsBm
.bmWidthBytes
;
787 #if CYGMULTIWINDOW_DEBUG
788 winDebug("winMWExtWMStartDrawing - bytesPerRow: %d\n",
789 (unsigned int) dibsection
.dsBm
.bmWidthBytes
);
792 /* Free the old shadow bitmap */
793 DeleteObject(pRLWinPriv
->hdcShadow
);
794 DeleteObject(pRLWinPriv
->hbmpShadow
);
796 pRLWinPriv
->hdcShadow
= hdcNew
;
797 pRLWinPriv
->hbmpShadow
= hbmpNew
;
799 pRLWinPriv
->fResized
= FALSE
;
800 #if CYGMULTIWINDOW_DEBUG && FALSE
801 winDebug("winMWExtWMStartDrawing - 0x%08x %d\n",
802 (unsigned int) pRLWinPriv
->pfb
,
803 (unsigned int) dibsection
.dsBm
.bmWidthBytes
);
808 ErrorF("winMWExtWMStartDrawing - Already window was destroyed \n");
810 #if CYGMULTIWINDOW_DEBUG
811 winDebug("winMWExtWMStartDrawing - done (%p) %p %d\n",
814 (unsigned int) pRLWinPriv
->dwWidthBytes
);
816 *pixelData
= pRLWinPriv
->pfb
;
817 *bytesPerRow
= pRLWinPriv
->dwWidthBytes
;
821 winMWExtWMStopDrawing(RootlessFrameID wid
, Bool fFlush
)
824 win32RootlessWindowPtr pRLWinPriv
= (win32RootlessWindowPtr
) wid
;
825 BLENDFUNCTION bfBlend
;
829 #if CYGMULTIWINDOW_DEBUG || TRUE
830 winDebug("winMWExtWMStopDrawing (%08x)\n", pRLWinPriv
);
832 szWin
.cx
= pRLWinPriv
->dwWidth
;
833 szWin
.cy
= pRLWinPriv
->dwHeight
;
836 bfBlend
.BlendOp
= AC_SRC_OVER
;
837 bfBlend
.BlendFlags
= 0;
838 bfBlend
.SourceConstantAlpha
= 255;
839 bfBlend
.AlphaFormat
= AC_SRC_ALPHA
;
841 if (!UpdateLayeredWindow(pRLWinPriv
->hWnd
,
843 pRLWinPriv
->hdcShadow
, &ptSrc
,
844 0, &bfBlend
, ULW_ALPHA
)) {
845 ErrorF("winMWExtWMStopDrawing - UpdateLayeredWindow failed\n");
851 winMWExtWMUpdateRegion(RootlessFrameID wid
, RegionPtr pDamage
)
853 win32RootlessWindowPtr pRLWinPriv
= (win32RootlessWindowPtr
) wid
;
856 BLENDFUNCTION bfBlend
;
860 #if CYGMULTIWINDOW_DEBUG && 0
861 winDebug("winMWExtWMUpdateRegion (%08x)\n", pRLWinPriv
);
864 szWin
.cx
= pRLWinPriv
->dwWidth
;
865 szWin
.cy
= pRLWinPriv
->dwHeight
;
868 bfBlend
.BlendOp
= AC_SRC_OVER
;
869 bfBlend
.BlendFlags
= 0;
870 bfBlend
.SourceConstantAlpha
= 255;
871 bfBlend
.AlphaFormat
= AC_SRC_ALPHA
;
873 if (!UpdateLayeredWindow(pRLWinPriv
->hWnd
,
875 pRLWinPriv
->hdcShadow
, &ptSrc
,
876 0, &bfBlend
, ULW_ALPHA
)) {
879 /* Display a fancy error message */
880 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
881 FORMAT_MESSAGE_FROM_SYSTEM
|
882 FORMAT_MESSAGE_IGNORE_INSERTS
,
885 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
886 (LPTSTR
) &lpMsgBuf
, 0, NULL
);
888 ErrorF("winMWExtWMUpdateRegion - UpdateLayeredWindow failed: %s\n",
893 if (!g_fNoConfigureWindow
)
894 UpdateWindow(pRLWinPriv
->hWnd
);
898 winMWExtWMDamageRects(RootlessFrameID wid
, int nCount
, const BoxRec
* pRects
,
899 int shift_x
, int shift_y
)
901 win32RootlessWindowPtr pRLWinPriv
= (win32RootlessWindowPtr
) wid
;
904 #if CYGMULTIWINDOW_DEBUG && 0
905 winDebug("winMWExtWMDamageRects (%08x, %d, %08x, %d, %d)\n",
906 pRLWinPriv
, nCount
, pRects
, shift_x
, shift_y
);
909 for (pEnd
= pRects
+ nCount
; pRects
< pEnd
; pRects
++) {
912 rcDmg
.left
= pRects
->x1
+ shift_x
;
913 rcDmg
.top
= pRects
->y1
+ shift_y
;
914 rcDmg
.right
= pRects
->x2
+ shift_x
;
915 rcDmg
.bottom
= pRects
->y2
+ shift_y
;
917 InvalidateRect(pRLWinPriv
->hWnd
, &rcDmg
, FALSE
);
922 winMWExtWMRootlessSwitchWindow(RootlessWindowPtr pFrame
, WindowPtr oldWin
)
924 win32RootlessWindowPtr pRLWinPriv
= (win32RootlessWindowPtr
) pFrame
->wid
;
926 #if CYGMULTIWINDOW_DEBUG
927 winDebug("winMWExtWMRootlessSwitchWindow (%p) %p\n",
928 pRLWinPriv
, pRLWinPriv
->hWnd
);
930 pRLWinPriv
->pFrame
= pFrame
;
931 pRLWinPriv
->fResized
= TRUE
;
933 /* Set the window extended style flags */
934 SetWindowLongPtr(pRLWinPriv
->hWnd
, GWL_EXSTYLE
, WS_EX_TOOLWINDOW
);
936 /* Set the window standard style flags */
937 SetWindowLongPtr(pRLWinPriv
->hWnd
, GWL_STYLE
, WS_POPUP
| WS_CLIPCHILDREN
);
939 DeleteProperty(serverClient
, oldWin
, AtmWindowsWmNativeHwnd());
940 winMWExtWMSetNativeProperty(pFrame
);
941 #if CYGMULTIWINDOW_DEBUG
944 WindowPtr pWin2
= NULL
;
945 win32RootlessWindowPtr pRLWinPriv2
= NULL
;
947 /* Check if the Windows window property for our X window pointer is valid */
949 (WindowPtr
) GetProp(pRLWinPriv
->hWnd
, WIN_WINDOW_PROP
)) != NULL
) {
951 (win32RootlessWindowPtr
) RootlessFrameForWindow(pWin2
, FALSE
);
953 winDebug("winMWExtWMSwitchFrame2 (%08x) %08x\n",
954 pRLWinPriv2
, pRLWinPriv2
->hWnd
);
955 if (pRLWinPriv
!= pRLWinPriv2
|| pRLWinPriv
->hWnd
!= pRLWinPriv2
->hWnd
) {
956 winDebug("Error param missmatch\n");
964 winMWExtWMCopyBytes(unsigned int width
, unsigned int height
,
965 const void *src
, unsigned int srcRowBytes
,
966 void *dst
, unsigned int dstRowBytes
)
968 #if CYGMULTIWINDOW_DEBUG
969 winDebug("winMWExtWMCopyBytes - Not implemented\n");
974 winMWExtWMCopyWindow(RootlessFrameID wid
, int nDstRects
,
975 const BoxRec
* pDstRects
, int nDx
, int nDy
)
977 win32RootlessWindowPtr pRLWinPriv
= (win32RootlessWindowPtr
) wid
;
981 #if CYGMULTIWINDOW_DEBUG
982 winDebug("winMWExtWMCopyWindow (%p, %d, %p, %d, %d)\n",
983 pRLWinPriv
, nDstRects
, pDstRects
, nDx
, nDy
);
986 for (pEnd
= pDstRects
+ nDstRects
; pDstRects
< pEnd
; pDstRects
++) {
987 #if CYGMULTIWINDOW_DEBUG
988 winDebug("BitBlt (%d, %d, %d, %d) (%d, %d)\n",
989 pDstRects
->x1
, pDstRects
->y1
,
990 pDstRects
->x2
- pDstRects
->x1
,
991 pDstRects
->y2
- pDstRects
->y1
,
992 pDstRects
->x1
+ nDx
, pDstRects
->y1
+ nDy
);
995 if (!BitBlt(pRLWinPriv
->hdcShadow
,
996 pDstRects
->x1
, pDstRects
->y1
,
997 pDstRects
->x2
- pDstRects
->x1
,
998 pDstRects
->y2
- pDstRects
->y1
,
999 pRLWinPriv
->hdcShadow
,
1000 pDstRects
->x1
+ nDx
, pDstRects
->y1
+ nDy
, SRCCOPY
)) {
1001 ErrorF("winMWExtWMCopyWindow - BitBlt failed.\n");
1004 rcDmg
.left
= pDstRects
->x1
;
1005 rcDmg
.top
= pDstRects
->y1
;
1006 rcDmg
.right
= pDstRects
->x2
;
1007 rcDmg
.bottom
= pDstRects
->y2
;
1009 InvalidateRect(pRLWinPriv
->hWnd
, &rcDmg
, FALSE
);
1011 #if CYGMULTIWINDOW_DEBUG
1012 winDebug("winMWExtWMCopyWindow - done\n");
1017 * winMWExtWMSetNativeProperty
1021 winMWExtWMSetNativeProperty(RootlessWindowPtr pFrame
)
1023 win32RootlessWindowPtr pRLWinPriv
= (win32RootlessWindowPtr
) pFrame
->wid
;
1026 /* FIXME: move this to WindowsWM extension */
1028 lData
= (long) pRLWinPriv
->hWnd
;
1029 dixChangeWindowProperty(serverClient
, pFrame
->win
, AtmWindowsWmNativeHwnd(),
1030 XA_INTEGER
, 32, PropModeReplace
, 1, &lData
, TRUE
);