Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xwin / winwin32rootless.c
CommitLineData
a09e091a
JB
1/*
2 *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
3 *
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:
11 *
12 *The above copyright notice and this permission notice shall be
13 *included in all copies or substantial portions of the Software.
14 *
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.
22 *
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.
27 *
28 * Authors: Kensuke Matsuzaki
29 * Earle F. Philhower, III
30 * Harold L Hunt II
31 */
32/*
33 * Look at hw/darwin/quartz/xpr/xprFrame.c and hw/darwin/quartz/cr/crFrame.c
34 */
35#ifdef HAVE_XWIN_CONFIG_H
36#include <xwin-config.h>
37#endif
38#include "win.h"
39#include <winuser.h>
40#define _WINDOWSWM_SERVER_
41#include <X11/extensions/windowswmstr.h>
42#include "dixevents.h"
43#include "winmultiwindowclass.h"
44#include <X11/Xatom.h>
45
46/*
47 * Constant defines
48 */
49
50#ifndef ULW_COLORKEY
51#define ULW_COLORKEY 0x00000001
52#endif
53#ifndef ULW_ALPHA
54#define ULW_ALPHA 0x00000002
55#endif
56#ifndef ULW_OPAQUE
57#define ULW_OPAQUE 0x00000004
58#endif
59#define AC_SRC_ALPHA 0x01
60
61/*
62 * Local function
63 */
64
65DEFINE_ATOM_HELPER(AtmWindowsWmNativeHwnd, WINDOWSWM_NATIVE_HWND)
66static void
67winMWExtWMSetNativeProperty(RootlessWindowPtr pFrame);
68
69/*
70 * Global variables
71 */
72
73Bool g_fNoConfigureWindow = FALSE;
74
75/*
76 * Internal function to get the DIB format that is compatible with the screen
77 * Fixme: Share code with winshadgdi.c
78 */
79
80static
81Bool
82winMWExtWMQueryDIBFormat(win32RootlessWindowPtr pRLWinPriv,
83 BITMAPINFOHEADER * pbmih)
84{
85 HBITMAP hbmp;
86
87#if CYGMULTIWINDOW_DEBUG
88 LPDWORD pdw = NULL;
89#endif
90
91 /* Create a memory bitmap compatible with the screen */
92 hbmp = CreateCompatibleBitmap(pRLWinPriv->hdcScreen, 1, 1);
93 if (hbmp == NULL) {
94 ErrorF("winMWExtWMQueryDIBFormat - CreateCompatibleBitmap failed\n");
95 return FALSE;
96 }
97
98 /* Initialize our bitmap info header */
99 ZeroMemory(pbmih, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
100 pbmih->biSize = sizeof(BITMAPINFOHEADER);
101
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");
106 DeleteObject(hbmp);
107 return FALSE;
108 }
109
110#if CYGMULTIWINDOW_DEBUG
111 /* Get a pointer to bitfields */
112 pdw = (DWORD *) ((CARD8 *) pbmih + sizeof(BITMAPINFOHEADER));
113
114 winDebug("winMWExtWMQueryDIBFormat - First call masks: %08x %08x %08x\n",
115 (unsigned int) pdw[0], (unsigned int) pdw[1],
116 (unsigned int) pdw[2]);
117#endif
118
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 "
123 "failed\n");
124 DeleteObject(hbmp);
125 return FALSE;
126 }
127
128 /* Free memory */
129 DeleteObject(hbmp);
130
131 return TRUE;
132}
133
134static HRGN
135winMWExtWMCreateRgnFromRegion(RegionPtr pShape)
136{
137 int nRects;
138 BoxPtr pRects, pEnd;
139 HRGN hRgn, hRgnRect;
140
141 if (pShape == NULL)
142 return NULL;
143
144 nRects = RegionNumRects(pShape);
145 pRects = RegionRects(pShape);
146
147 hRgn = CreateRectRgn(0, 0, 0, 0);
148 if (hRgn == NULL) {
149 ErrorF("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) "
150 "failed: %d\n", 0, 0, 0, 0, (int) GetLastError());
151 }
152
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) "
160 "failed: %d\n",
161 pRects->x1,
162 pRects->y1, pRects->x2, pRects->y2, (int) GetLastError());
163 }
164
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());
169 }
170
171 /* Delete the temporary Windows region */
172 DeleteObject(hRgnRect);
173 }
174
175 return hRgn;
176}
177
178static void
179InitWin32RootlessEngine(win32RootlessWindowPtr pRLWinPriv)
180{
181 pRLWinPriv->hdcScreen = GetDC(pRLWinPriv->hWnd);
182 pRLWinPriv->hdcShadow = CreateCompatibleDC(pRLWinPriv->hdcScreen);
183 pRLWinPriv->hbmpShadow = NULL;
184
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");
191 return;
192 }
193
194 /* Query the screen format */
195 winMWExtWMQueryDIBFormat(pRLWinPriv, pRLWinPriv->pbmihShadow);
196}
197
198Bool
199winMWExtWMCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
200 int newX, int newY, RegionPtr pShape)
201{
202#define CLASS_NAME_LENGTH 512
203 Bool fResult = TRUE;
204 win32RootlessWindowPtr pRLWinPriv;
205 WNDCLASSEX wc;
206 char pszClass[CLASS_NAME_LENGTH], pszWindowID[12];
207 HICON hIcon;
208 HICON hIconSmall;
209 char *res_name, *res_class, *res_role;
210 static int s_iWindowID = 0;
211
212#if CYGMULTIWINDOW_DEBUG
213 winDebug("winMWExtWMCreateFrame %d %d - %d %d\n",
214 newX, newY, pFrame->width, pFrame->height);
215#endif
216
217 pRLWinPriv =
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;
230
231 // Store the implementation private frame ID
232 pFrame->wid = (RootlessFrameID) pRLWinPriv;
233
234 winSelectIcons(&hIcon, &hIconSmall);
235
236 /* Set standard class name prefix so we can identify window easily */
237 strncpy(pszClass, WINDOW_CLASS_X, sizeof(pszClass));
238
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));
244
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
249 */
250 if (winMultiWindowGetWindowRole(pFrame->win, &res_role)) {
251 strcat(pszClass, "-");
252 strcat(pszClass, res_role);
253 free(res_role);
254 }
255
256 free(res_name);
257 free(res_class);
258 }
259
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);
264
265#if CYGMULTIWINDOW_DEBUG
266 winDebug("winMWExtWMCreateFrame - Creating class: %s\n", pszClass);
267#endif
268
269 /* Setup our window class */
270 wc.cbSize = sizeof(wc);
271 wc.style = CS_HREDRAW | CS_VREDRAW;
272 wc.lpfnWndProc = winMWExtWMWindowProc;
273 wc.cbClsExtra = 0;
274 wc.cbWndExtra = 0;
275 wc.hInstance = g_hInstance;
276 wc.hIcon = hIcon;
277 wc.hIconSm = hIconSmall;
278 wc.hCursor = 0;
279 wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
280 wc.lpszMenuName = NULL;
281 wc.lpszClassName = pszClass;
282 RegisterClassEx(&wc);
283
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());
300 fResult = FALSE;
301 }
302
303#if CYGMULTIWINDOW_DEBUG
304 winDebug("winMWExtWMCreateFrame - ShowWindow\n");
305#endif
306
307 //ShowWindow (pRLWinPriv->hWnd, SW_SHOWNOACTIVATE);
308 g_fNoConfigureWindow = FALSE;
309
310 if (pShape != NULL) {
311 winMWExtWMReshapeFrame(pFrame->wid, pShape);
312 }
313
314#if CYGMULTIWINDOW_DEBUG
315 winDebug("winMWExtWMCreateFrame - (%p) %p\n",
316 pFrame->wid, pRLWinPriv->hWnd);
317#if 0
318 {
319 WindowPtr pWin2 = NULL;
320 win32RootlessWindowPtr pRLWinPriv2 = NULL;
321
322 /* Check if the Windows window property for our X window pointer is valid */
323 if ((pWin2 =
324 (WindowPtr) GetProp(pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) {
325 pRLWinPriv2 =
326 (win32RootlessWindowPtr) RootlessFrameForWindow(pWin2, FALSE);
327 }
328 winDebug("winMWExtWMCreateFrame2 (%08x) %08x\n",
329 pRLWinPriv2, pRLWinPriv2->hWnd);
330 if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) {
331 winDebug("Error param missmatch\n");
332 }
333 }
334#endif
335#endif
336
337 winMWExtWMSetNativeProperty(pFrame);
338
339 return fResult;
340}
341
342void
343winMWExtWMDestroyFrame(RootlessFrameID wid)
344{
345 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
346 HICON hIcon;
347 HICON hIconSm;
348 HMODULE hInstance;
349 int iReturn;
350 char pszClass[CLASS_NAME_LENGTH];
351
352#if CYGMULTIWINDOW_DEBUG
353 winDebug("winMWExtWMDestroyFrame (%p) %p\n",
354 pRLWinPriv, pRLWinPriv->hWnd);
355#if 0
356 {
357 WindowPtr pWin2 = NULL;
358 win32RootlessWindowPtr pRLWinPriv2 = NULL;
359
360 /* Check if the Windows window property for our X window pointer is valid */
361 if ((pWin2 =
362 (WindowPtr) GetProp(pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) {
363 pRLWinPriv2 =
364 (win32RootlessWindowPtr) RootlessFrameForWindow(pWin2, FALSE);
365 }
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
371 }
372 }
373#endif
374#endif
375
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);
381
382 pRLWinPriv->fClose = TRUE;
383 pRLWinPriv->fDestroyed = TRUE;
384
385 /* Destroy the Windows window */
386 DestroyWindow(pRLWinPriv->hWnd);
387
388 /* Only if we were able to get the name */
389 if (iReturn) {
390#if CYGMULTIWINDOW_DEBUG
391 winDebug("winMWExtWMDestroyFrame - Unregistering %s: ", pszClass);
392#endif
393 iReturn = UnregisterClass(pszClass, hInstance);
394 }
395
396#if CYGMULTIWINDOW_DEBUG
397 winDebug("winMWExtWMDestroyFramew - Deleting Icon\n");
398#endif
399
400 winDestroyIcon(hIcon);
401 winDestroyIcon(hIconSm);
402
403#if CYGMULTIWINDOW_DEBUG
404 winDebug("winMWExtWMDestroyFrame - done\n");
405#endif
406}
407
408void
409winMWExtWMMoveFrame(RootlessFrameID wid, ScreenPtr pScreen, int iNewX,
410 int iNewY)
411{
412 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
413 RECT rcNew;
414 DWORD dwExStyle;
415 DWORD dwStyle;
416 int iX, iY, iWidth, iHeight;
417
418#if CYGMULTIWINDOW_DEBUG
419 winDebug("winMWExtWMMoveFrame (%p) (%d %d)\n", pRLWinPriv, iNewX,
420 iNewY);
421#endif
422
423 /* Get the Windows window style and extended style */
424 dwExStyle = GetWindowLongPtr(pRLWinPriv->hWnd, GWL_EXSTYLE);
425 dwStyle = GetWindowLongPtr(pRLWinPriv->hWnd, GWL_STYLE);
426
427 /* Get the X and Y location of the X window */
428 iX = iNewX + GetSystemMetrics(SM_XVIRTUALSCREEN);
429 iY = iNewY + GetSystemMetrics(SM_YVIRTUALSCREEN);
430
431 /* Get the height and width of the X window */
432 iWidth = pRLWinPriv->pFrame->width;
433 iHeight = pRLWinPriv->pFrame->height;
434
435 /* Store the origin, height, and width in a rectangle structure */
436 SetRect(&rcNew, iX, iY, iX + iWidth, iY + iHeight);
437
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);
442#endif
443 /*
444 * Calculate the required size of the Windows window rectangle,
445 * given the size of the Windows window client area.
446 */
447 AdjustWindowRectEx(&rcNew, dwStyle, FALSE, dwExStyle);
448
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);
453#endif
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);
460#endif
461}
462
463void
464winMWExtWMResizeFrame(RootlessFrameID wid, ScreenPtr pScreen,
465 int iNewX, int iNewY,
466 unsigned int uiNewWidth, unsigned int uiNewHeight,
467 unsigned int uiGravity)
468{
469 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
470 RECT rcNew;
471 RECT rcOld;
472 DWORD dwExStyle;
473 DWORD dwStyle;
474 int iX, iY;
475
476#if CYGMULTIWINDOW_DEBUG
477 winDebug("winMWExtWMResizeFrame (%p) (%d %d)-(%d %d)\n",
478 pRLWinPriv, iNewX, iNewY, uiNewWidth, uiNewHeight);
479#endif
480
481 pRLWinPriv->fResized = TRUE;
482
483 /* Get the Windows window style and extended style */
484 dwExStyle = GetWindowLongPtr(pRLWinPriv->hWnd, GWL_EXSTYLE);
485 dwStyle = GetWindowLongPtr(pRLWinPriv->hWnd, GWL_STYLE);
486
487 /* Get the X and Y location of the X window */
488 iX = iNewX + GetSystemMetrics(SM_XVIRTUALSCREEN);
489 iY = iNewY + GetSystemMetrics(SM_YVIRTUALSCREEN);
490
491 /* Store the origin, height, and width in a rectangle structure */
492 SetRect(&rcNew, iX, iY, iX + uiNewWidth, iY + uiNewHeight);
493
494 /*
495 * Calculate the required size of the Windows window rectangle,
496 * given the size of the Windows window client area.
497 */
498 AdjustWindowRectEx(&rcNew, dwStyle, FALSE, dwExStyle);
499
500 /* Get a rectangle describing the old Windows window */
501 GetWindowRect(pRLWinPriv->hWnd, &rcOld);
502
503 /* Check if the old rectangle and new rectangle are the same */
504 if (!EqualRect(&rcNew, &rcOld)) {
505
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;
511 }
512}
513
514void
515winMWExtWMRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid)
516{
517 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
518 win32RootlessWindowPtr pRLNextWinPriv = (win32RootlessWindowPtr) nextWid;
519
520 winScreenPriv(pRLWinPriv->pFrame->win->drawable.pScreen);
521 winScreenInfo *pScreenInfo = NULL;
522 DWORD dwCurrentProcessID = GetCurrentProcessId();
523 DWORD dwWindowProcessID = 0;
524 HWND hWnd;
525 Bool fFirst = TRUE;
526 Bool fNeedRestack = TRUE;
527
528#if CYGMULTIWINDOW_DEBUG
529 winDebug("winMWExtWMRestackFrame (%p)\n", pRLWinPriv);
530#endif
531
532 if (pScreenPriv && pScreenPriv->fRestacking)
533 return;
534
535 if (pScreenPriv)
536 pScreenInfo = pScreenPriv->pScreenInfo;
537
538 pRLWinPriv->fRestackingNow = TRUE;
539
540 /* Show window */
541 if (!IsWindowVisible(pRLWinPriv->hWnd))
542 ShowWindow(pRLWinPriv->hWnd, SW_SHOWNOACTIVATE);
543
544 if (pRLNextWinPriv == NULL) {
545#if CYGMULTIWINDOW_DEBUG
546 winDebug("Win %08x is top\n", pRLWinPriv);
547#endif
548 pScreenPriv->widTop = wid;
549 SetWindowPos(pRLWinPriv->hWnd, HWND_TOP,
550 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
551 }
552 else if (winIsInternalWMRunning(pScreenInfo)) {
553 /* using mulwinidow wm */
554#if CYGMULTIWINDOW_DEBUG
555 winDebug("Win %08x is not top\n", pRLWinPriv);
556#endif
557 for (hWnd = GetNextWindow(pRLWinPriv->hWnd, GW_HWNDPREV);
558 fNeedRestack && hWnd != NULL;
559 hWnd = GetNextWindow(hWnd, GW_HWNDPREV)) {
560 GetWindowThreadProcessId(hWnd, &dwWindowProcessID);
561
562 if ((dwWindowProcessID == dwCurrentProcessID)
563 && GetProp(hWnd, WIN_WINDOW_PROP)) {
564 if (hWnd == pRLNextWinPriv->hWnd) {
565 /* Enable interleave X window and Windows window */
566 if (!fFirst) {
567#if CYGMULTIWINDOW_DEBUG
568 winDebug("raise: Insert after Win %08x\n",
569 pRLNextWinPriv);
570#endif
571 SetWindowPos(pRLWinPriv->hWnd, pRLNextWinPriv->hWnd,
572 0, 0, 0, 0,
573 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
574 }
575 else {
576#if CYGMULTIWINDOW_DEBUG
577 winDebug("No change\n");
578#endif
579 }
580 fNeedRestack = FALSE;
581 break;
582 }
583 if (fFirst)
584 fFirst = FALSE;
585 }
586 }
587
588 for (hWnd = GetNextWindow(pRLWinPriv->hWnd, GW_HWNDNEXT);
589 fNeedRestack && hWnd != NULL;
590 hWnd = GetNextWindow(hWnd, GW_HWNDNEXT)) {
591 GetWindowThreadProcessId(hWnd, &dwWindowProcessID);
592
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);
598#endif
599 SetWindowPos(pRLWinPriv->hWnd, pRLNextWinPriv->hWnd,
600 0, 0, 0, 0,
601 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
602 fNeedRestack = FALSE;
603 break;
604 }
605 }
606 }
607 }
608 else {
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);
613 }
614#if CYGMULTIWINDOW_DEBUG
615 winDebug("winMWExtWMRestackFrame - done (%p)\n", pRLWinPriv);
616#endif
617
618 pRLWinPriv->fRestackingNow = FALSE;
619}
620
621void
622winMWExtWMReshapeFrame(RootlessFrameID wid, RegionPtr pShape)
623{
624 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
625 HRGN hRgn, hRgnWindow, hRgnClient;
626 RECT rcWindow, rcClient;
627
628#if CYGMULTIWINDOW_DEBUG
629 winDebug("winMWExtWMReshapeFrame (%p)\n", pRLWinPriv);
630#endif
631
632 hRgn = winMWExtWMCreateRgnFromRegion(pShape);
633
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);
645
646 SetWindowRgn(pRLWinPriv->hWnd, hRgn, TRUE);
647
648 DeleteObject(hRgnWindow);
649 DeleteObject(hRgnClient);
650}
651
652void
653winMWExtWMUnmapFrame(RootlessFrameID wid)
654{
655 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
656
657#if CYGMULTIWINDOW_DEBUG
658 winDebug("winMWExtWMUnmapFrame (%p)\n", pRLWinPriv);
659#endif
660
661 g_fNoConfigureWindow = TRUE;
662 //ShowWindow (pRLWinPriv->hWnd, SW_MINIMIZE);
663 ShowWindow(pRLWinPriv->hWnd, SW_HIDE);
664 g_fNoConfigureWindow = FALSE;
665}
666
667/*
668 * Fixme: Code sharing with winshadgdi.c and other engine support
669 */
670void
671winMWExtWMStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow)
672{
673 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
674 winPrivScreenPtr pScreenPriv = NULL;
675 winScreenInfo *pScreenInfo = NULL;
676 ScreenPtr pScreen = NULL;
677 DIBSECTION dibsection;
678 Bool fReturn = TRUE;
679 HDC hdcNew;
680 HBITMAP hbmpNew;
681
682#if CYGMULTIWINDOW_DEBUG
683 winDebug("winMWExtWMStartDrawing (%p) %08x\n", pRLWinPriv,
684 pRLWinPriv->fDestroyed);
685#endif
686
687 if (!pRLWinPriv->fDestroyed) {
688 pScreen = pRLWinPriv->pFrame->win->drawable.pScreen;
689 if (pScreen)
690 pScreenPriv = winGetScreenPriv(pScreen);
691 if (pScreenPriv)
692 pScreenInfo = pScreenPriv->pScreenInfo;
693
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);
699#endif
700 if (pRLWinPriv->hdcScreen == NULL) {
701 InitWin32RootlessEngine(pRLWinPriv);
702 }
703
704 if (pRLWinPriv->fResized) {
705 /* width * bpp must be multiple of 4 to match 32bit alignment */
706 int stridesize;
707 int misalignment;
708
709 pRLWinPriv->pbmihShadow->biWidth = pRLWinPriv->pFrame->width;
710 pRLWinPriv->pbmihShadow->biHeight = -pRLWinPriv->pFrame->height;
711
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);
721 }
722
723 hdcNew = CreateCompatibleDC(pRLWinPriv->hdcScreen);
724 /* Create a DI shadow bitmap with a bit pointer */
725 hbmpNew = CreateDIBSection(pRLWinPriv->hdcScreen,
726 (BITMAPINFO *) pRLWinPriv->pbmihShadow,
727 DIB_RGB_COLORS,
728 (VOID **) &pRLWinPriv->pfb, NULL, 0);
729 if (hbmpNew == NULL || pRLWinPriv->pfb == NULL) {
730 ErrorF("winMWExtWMStartDrawing - CreateDIBSection failed\n");
731 //return FALSE;
732 }
733 else {
734#if CYGMULTIWINDOW_DEBUG
735 winDebug("winMWExtWMStartDrawing - Shadow buffer allocated\n");
736#endif
737 }
738
739 /* Get information about the bitmap that was allocated */
740 GetObject(hbmpNew, sizeof(dibsection), &dibsection);
741
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);
750#endif
751
752 /* Select the shadow bitmap into the shadow DC */
753 SelectObject(hdcNew, hbmpNew);
754
755#if CYGMULTIWINDOW_DEBUG
756 winDebug("winMWExtWMStartDrawing - Attempting a shadow blit\n");
757#endif
758
759 /* Blit from the old shadow to the new shadow */
760 fReturn = BitBlt(hdcNew,
761 0, 0,
762 pRLWinPriv->pFrame->width,
763 pRLWinPriv->pFrame->height, pRLWinPriv->hdcShadow,
764 0, 0, SRCCOPY);
765 if (fReturn) {
766#if CYGMULTIWINDOW_DEBUG
767 winDebug("winMWExtWMStartDrawing - Shadow blit success\n");
768#endif
769 }
770 else {
771 ErrorF("winMWExtWMStartDrawing - Shadow blit failure\n");
772 }
773
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;
783 }
784
785 pRLWinPriv->dwWidthBytes = dibsection.dsBm.bmWidthBytes;
786
787#if CYGMULTIWINDOW_DEBUG
788 winDebug("winMWExtWMStartDrawing - bytesPerRow: %d\n",
789 (unsigned int) dibsection.dsBm.bmWidthBytes);
790#endif
791
792 /* Free the old shadow bitmap */
793 DeleteObject(pRLWinPriv->hdcShadow);
794 DeleteObject(pRLWinPriv->hbmpShadow);
795
796 pRLWinPriv->hdcShadow = hdcNew;
797 pRLWinPriv->hbmpShadow = hbmpNew;
798
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);
804#endif
805 }
806 }
807 else {
808 ErrorF("winMWExtWMStartDrawing - Already window was destroyed \n");
809 }
810#if CYGMULTIWINDOW_DEBUG
811 winDebug("winMWExtWMStartDrawing - done (%p) %p %d\n",
812 pRLWinPriv,
813 pRLWinPriv->pfb,
814 (unsigned int) pRLWinPriv->dwWidthBytes);
815#endif
816 *pixelData = pRLWinPriv->pfb;
817 *bytesPerRow = pRLWinPriv->dwWidthBytes;
818}
819
820void
821winMWExtWMStopDrawing(RootlessFrameID wid, Bool fFlush)
822{
823#if 0
824 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
825 BLENDFUNCTION bfBlend;
826 SIZE szWin;
827 POINT ptSrc;
828
829#if CYGMULTIWINDOW_DEBUG || TRUE
830 winDebug("winMWExtWMStopDrawing (%08x)\n", pRLWinPriv);
831#endif
832 szWin.cx = pRLWinPriv->dwWidth;
833 szWin.cy = pRLWinPriv->dwHeight;
834 ptSrc.x = 0;
835 ptSrc.y = 0;
836 bfBlend.BlendOp = AC_SRC_OVER;
837 bfBlend.BlendFlags = 0;
838 bfBlend.SourceConstantAlpha = 255;
839 bfBlend.AlphaFormat = AC_SRC_ALPHA;
840
841 if (!UpdateLayeredWindow(pRLWinPriv->hWnd,
842 NULL, NULL, &szWin,
843 pRLWinPriv->hdcShadow, &ptSrc,
844 0, &bfBlend, ULW_ALPHA)) {
845 ErrorF("winMWExtWMStopDrawing - UpdateLayeredWindow failed\n");
846 }
847#endif
848}
849
850void
851winMWExtWMUpdateRegion(RootlessFrameID wid, RegionPtr pDamage)
852{
853 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
854
855#if 0
856 BLENDFUNCTION bfBlend;
857 SIZE szWin;
858 POINT ptSrc;
859#endif
860#if CYGMULTIWINDOW_DEBUG && 0
861 winDebug("winMWExtWMUpdateRegion (%08x)\n", pRLWinPriv);
862#endif
863#if 0
864 szWin.cx = pRLWinPriv->dwWidth;
865 szWin.cy = pRLWinPriv->dwHeight;
866 ptSrc.x = 0;
867 ptSrc.y = 0;
868 bfBlend.BlendOp = AC_SRC_OVER;
869 bfBlend.BlendFlags = 0;
870 bfBlend.SourceConstantAlpha = 255;
871 bfBlend.AlphaFormat = AC_SRC_ALPHA;
872
873 if (!UpdateLayeredWindow(pRLWinPriv->hWnd,
874 NULL, NULL, &szWin,
875 pRLWinPriv->hdcShadow, &ptSrc,
876 0, &bfBlend, ULW_ALPHA)) {
877 LPVOID lpMsgBuf;
878
879 /* Display a fancy error message */
880 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
881 FORMAT_MESSAGE_FROM_SYSTEM |
882 FORMAT_MESSAGE_IGNORE_INSERTS,
883 NULL,
884 GetLastError(),
885 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
886 (LPTSTR) &lpMsgBuf, 0, NULL);
887
888 ErrorF("winMWExtWMUpdateRegion - UpdateLayeredWindow failed: %s\n",
889 (LPSTR) lpMsgBuf);
890 LocalFree(lpMsgBuf);
891 }
892#endif
893 if (!g_fNoConfigureWindow)
894 UpdateWindow(pRLWinPriv->hWnd);
895}
896
897void
898winMWExtWMDamageRects(RootlessFrameID wid, int nCount, const BoxRec * pRects,
899 int shift_x, int shift_y)
900{
901 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
902 const BoxRec *pEnd;
903
904#if CYGMULTIWINDOW_DEBUG && 0
905 winDebug("winMWExtWMDamageRects (%08x, %d, %08x, %d, %d)\n",
906 pRLWinPriv, nCount, pRects, shift_x, shift_y);
907#endif
908
909 for (pEnd = pRects + nCount; pRects < pEnd; pRects++) {
910 RECT rcDmg;
911
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;
916
917 InvalidateRect(pRLWinPriv->hWnd, &rcDmg, FALSE);
918 }
919}
920
921void
922winMWExtWMRootlessSwitchWindow(RootlessWindowPtr pFrame, WindowPtr oldWin)
923{
924 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid;
925
926#if CYGMULTIWINDOW_DEBUG
927 winDebug("winMWExtWMRootlessSwitchWindow (%p) %p\n",
928 pRLWinPriv, pRLWinPriv->hWnd);
929#endif
930 pRLWinPriv->pFrame = pFrame;
931 pRLWinPriv->fResized = TRUE;
932
933 /* Set the window extended style flags */
934 SetWindowLongPtr(pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
935
936 /* Set the window standard style flags */
937 SetWindowLongPtr(pRLWinPriv->hWnd, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN);
938
939 DeleteProperty(serverClient, oldWin, AtmWindowsWmNativeHwnd());
940 winMWExtWMSetNativeProperty(pFrame);
941#if CYGMULTIWINDOW_DEBUG
942#if 0
943 {
944 WindowPtr pWin2 = NULL;
945 win32RootlessWindowPtr pRLWinPriv2 = NULL;
946
947 /* Check if the Windows window property for our X window pointer is valid */
948 if ((pWin2 =
949 (WindowPtr) GetProp(pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) {
950 pRLWinPriv2 =
951 (win32RootlessWindowPtr) RootlessFrameForWindow(pWin2, FALSE);
952 }
953 winDebug("winMWExtWMSwitchFrame2 (%08x) %08x\n",
954 pRLWinPriv2, pRLWinPriv2->hWnd);
955 if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) {
956 winDebug("Error param missmatch\n");
957 }
958 }
959#endif
960#endif
961}
962
963void
964winMWExtWMCopyBytes(unsigned int width, unsigned int height,
965 const void *src, unsigned int srcRowBytes,
966 void *dst, unsigned int dstRowBytes)
967{
968#if CYGMULTIWINDOW_DEBUG
969 winDebug("winMWExtWMCopyBytes - Not implemented\n");
970#endif
971}
972
973void
974winMWExtWMCopyWindow(RootlessFrameID wid, int nDstRects,
975 const BoxRec * pDstRects, int nDx, int nDy)
976{
977 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
978 const BoxRec *pEnd;
979 RECT rcDmg;
980
981#if CYGMULTIWINDOW_DEBUG
982 winDebug("winMWExtWMCopyWindow (%p, %d, %p, %d, %d)\n",
983 pRLWinPriv, nDstRects, pDstRects, nDx, nDy);
984#endif
985
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);
993#endif
994
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");
1002 }
1003
1004 rcDmg.left = pDstRects->x1;
1005 rcDmg.top = pDstRects->y1;
1006 rcDmg.right = pDstRects->x2;
1007 rcDmg.bottom = pDstRects->y2;
1008
1009 InvalidateRect(pRLWinPriv->hWnd, &rcDmg, FALSE);
1010 }
1011#if CYGMULTIWINDOW_DEBUG
1012 winDebug("winMWExtWMCopyWindow - done\n");
1013#endif
1014}
1015
1016/*
1017 * winMWExtWMSetNativeProperty
1018 */
1019
1020static void
1021winMWExtWMSetNativeProperty(RootlessWindowPtr pFrame)
1022{
1023 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid;
1024 long lData;
1025
1026 /* FIXME: move this to WindowsWM extension */
1027
1028 lData = (long) pRLWinPriv->hWnd;
1029 dixChangeWindowProperty(serverClient, pFrame->win, AtmWindowsWmNativeHwnd(),
1030 XA_INTEGER, 32, PropModeReplace, 1, &lData, TRUE);
1031}