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 "winmultiwindowclass.h"
43 #include "winmultiwindowicons.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
65 DEFINE_ATOM_HELPER(AtmWindowsWmNativeHwnd, WINDOWSWM_NATIVE_HWND)
66 static void
67 winMWExtWMSetNativeProperty(RootlessWindowPtr pFrame);
68
69 /*
70 * Global variables
71 */
72
73 Bool 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
80 static
81 Bool
winMWExtWMQueryDIBFormat(win32RootlessWindowPtr pRLWinPriv,BITMAPINFOHEADER * pbmih)82 winMWExtWMQueryDIBFormat(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
134 static HRGN
winMWExtWMCreateRgnFromRegion(RegionPtr pShape)135 winMWExtWMCreateRgnFromRegion(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
178 static void
InitWin32RootlessEngine(win32RootlessWindowPtr pRLWinPriv)179 InitWin32RootlessEngine(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 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
198 Bool
winMWExtWMCreateFrame(RootlessWindowPtr pFrame,ScreenPtr pScreen,int newX,int newY,RegionPtr pShape)199 winMWExtWMCreateFrame(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 = malloc(sizeof(win32RootlessWindowRec));
218 pRLWinPriv->pFrame = pFrame;
219 pRLWinPriv->pfb = NULL;
220 pRLWinPriv->hbmpShadow = NULL;
221 pRLWinPriv->hdcShadow = NULL;
222 pRLWinPriv->hdcScreen = NULL;
223 pRLWinPriv->pbmihShadow = NULL;
224 pRLWinPriv->fResized = TRUE;
225 pRLWinPriv->fClose = FALSE;
226 pRLWinPriv->fRestackingNow = FALSE;
227 pRLWinPriv->fDestroyed = FALSE;
228 pRLWinPriv->fMovingOrSizing = FALSE;
229
230 // Store the implementation private frame ID
231 pFrame->wid = (RootlessFrameID) pRLWinPriv;
232
233 winSelectIcons(&hIcon, &hIconSmall);
234
235 /* Set standard class name prefix so we can identify window easily */
236 strncpy(pszClass, WINDOW_CLASS_X, sizeof(pszClass));
237
238 if (winMultiWindowGetClassHint(pFrame->win, &res_name, &res_class)) {
239 strncat(pszClass, "-", 1);
240 strncat(pszClass, res_name, CLASS_NAME_LENGTH - strlen(pszClass));
241 strncat(pszClass, "-", 1);
242 strncat(pszClass, res_class, CLASS_NAME_LENGTH - strlen(pszClass));
243
244 /* Check if a window class is provided by the WM_WINDOW_ROLE property,
245 * if not use the WM_CLASS information.
246 * For further information see:
247 * http://tronche.com/gui/x/icccm/sec-5.html
248 */
249 if (winMultiWindowGetWindowRole(pFrame->win, &res_role)) {
250 strcat(pszClass, "-");
251 strcat(pszClass, res_role);
252 free(res_role);
253 }
254
255 free(res_name);
256 free(res_class);
257 }
258
259 /* Add incrementing window ID to make unique class name */
260 snprintf(pszWindowID, sizeof(pszWindowID), "-%x", s_iWindowID++);
261 pszWindowID[sizeof(pszWindowID) - 1] = 0;
262 strcat(pszClass, pszWindowID);
263
264 #if CYGMULTIWINDOW_DEBUG
265 winDebug("winMWExtWMCreateFrame - Creating class: %s\n", pszClass);
266 #endif
267
268 /* Setup our window class */
269 wc.cbSize = sizeof(wc);
270 wc.style = CS_HREDRAW | CS_VREDRAW;
271 wc.lpfnWndProc = winMWExtWMWindowProc;
272 wc.cbClsExtra = 0;
273 wc.cbWndExtra = 0;
274 wc.hInstance = g_hInstance;
275 wc.hIcon = hIcon;
276 wc.hIconSm = hIconSmall;
277 wc.hCursor = 0;
278 wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
279 wc.lpszMenuName = NULL;
280 wc.lpszClassName = pszClass;
281 RegisterClassEx(&wc);
282
283 /* Create the window */
284 g_fNoConfigureWindow = TRUE;
285 pRLWinPriv->hWnd = CreateWindowExA(WS_EX_TOOLWINDOW, /* Extended styles */
286 pszClass, /* Class name */
287 WINDOW_TITLE_X, /* Window name */
288 WS_POPUP | WS_CLIPCHILDREN, newX, /* Horizontal position */
289 newY, /* Vertical position */
290 pFrame->width, /* Right edge */
291 pFrame->height, /* Bottom edge */
292 (HWND) NULL, /* No parent or owner window */
293 (HMENU) NULL, /* No menu */
294 GetModuleHandle(NULL), /* Instance handle */
295 pRLWinPriv); /* ScreenPrivates */
296 if (pRLWinPriv->hWnd == NULL) {
297 ErrorF("winMWExtWMCreateFrame - CreateWindowExA () failed: %d\n",
298 (int) GetLastError());
299 fResult = FALSE;
300 }
301
302 #if CYGMULTIWINDOW_DEBUG
303 winDebug("winMWExtWMCreateFrame - ShowWindow\n");
304 #endif
305
306 //ShowWindow (pRLWinPriv->hWnd, SW_SHOWNOACTIVATE);
307 g_fNoConfigureWindow = FALSE;
308
309 if (pShape != NULL) {
310 winMWExtWMReshapeFrame(pFrame->wid, pShape);
311 }
312
313 #if CYGMULTIWINDOW_DEBUG
314 winDebug("winMWExtWMCreateFrame - (%p) %p\n",
315 pFrame->wid, pRLWinPriv->hWnd);
316 #if 0
317 {
318 WindowPtr pWin2 = NULL;
319 win32RootlessWindowPtr pRLWinPriv2 = NULL;
320
321 /* Check if the Windows window property for our X window pointer is valid */
322 if ((pWin2 =
323 (WindowPtr) GetProp(pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) {
324 pRLWinPriv2 =
325 (win32RootlessWindowPtr) RootlessFrameForWindow(pWin2, FALSE);
326 }
327 winDebug("winMWExtWMCreateFrame2 (%08x) %08x\n",
328 pRLWinPriv2, pRLWinPriv2->hWnd);
329 if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) {
330 winDebug("Error param missmatch\n");
331 }
332 }
333 #endif
334 #endif
335
336 winMWExtWMSetNativeProperty(pFrame);
337
338 return fResult;
339 }
340
341 void
winMWExtWMDestroyFrame(RootlessFrameID wid)342 winMWExtWMDestroyFrame(RootlessFrameID wid)
343 {
344 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
345 HICON hIcon;
346 HICON hIconSm;
347 HMODULE hInstance;
348 int iReturn;
349 char pszClass[CLASS_NAME_LENGTH];
350
351 #if CYGMULTIWINDOW_DEBUG
352 winDebug("winMWExtWMDestroyFrame (%p) %p\n",
353 pRLWinPriv, pRLWinPriv->hWnd);
354 #if 0
355 {
356 WindowPtr pWin2 = NULL;
357 win32RootlessWindowPtr pRLWinPriv2 = NULL;
358
359 /* Check if the Windows window property for our X window pointer is valid */
360 if ((pWin2 =
361 (WindowPtr) GetProp(pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) {
362 pRLWinPriv2 =
363 (win32RootlessWindowPtr) RootlessFrameForWindow(pWin2, FALSE);
364 }
365 winDebug("winMWExtWMDestroyFrame2 (%08x) %08x\n",
366 pRLWinPriv2, pRLWinPriv2->hWnd);
367 if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) {
368 winDebug("Error param missmatch\n");
369 *(int *) 0 = 1; //raise exseption
370 }
371 }
372 #endif
373 #endif
374
375 /* Store the info we need to destroy after this window is gone */
376 hInstance = (HINSTANCE) GetClassLongPtr(pRLWinPriv->hWnd, GCLP_HMODULE);
377 hIcon = (HICON) SendMessage(pRLWinPriv->hWnd, WM_GETICON, ICON_BIG, 0);
378 hIconSm = (HICON) SendMessage(pRLWinPriv->hWnd, WM_GETICON, ICON_SMALL, 0);
379 iReturn = GetClassName(pRLWinPriv->hWnd, pszClass, CLASS_NAME_LENGTH);
380
381 pRLWinPriv->fClose = TRUE;
382 pRLWinPriv->fDestroyed = TRUE;
383
384 /* Destroy the Windows window */
385 DestroyWindow(pRLWinPriv->hWnd);
386
387 /* Only if we were able to get the name */
388 if (iReturn) {
389 #if CYGMULTIWINDOW_DEBUG
390 winDebug("winMWExtWMDestroyFrame - Unregistering %s: ", pszClass);
391 #endif
392 iReturn = UnregisterClass(pszClass, hInstance);
393 }
394
395 #if CYGMULTIWINDOW_DEBUG
396 winDebug("winMWExtWMDestroyFramew - Deleting Icon\n");
397 #endif
398
399 winDestroyIcon(hIcon);
400 winDestroyIcon(hIconSm);
401
402 #if CYGMULTIWINDOW_DEBUG
403 winDebug("winMWExtWMDestroyFrame - done\n");
404 #endif
405 }
406
407 void
winMWExtWMMoveFrame(RootlessFrameID wid,ScreenPtr pScreen,int iNewX,int iNewY)408 winMWExtWMMoveFrame(RootlessFrameID wid, ScreenPtr pScreen, int iNewX,
409 int iNewY)
410 {
411 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
412 RECT rcNew;
413 DWORD dwExStyle;
414 DWORD dwStyle;
415 int iX, iY, iWidth, iHeight;
416
417 #if CYGMULTIWINDOW_DEBUG
418 winDebug("winMWExtWMMoveFrame (%p) (%d %d)\n", pRLWinPriv, iNewX,
419 iNewY);
420 #endif
421
422 /* Get the Windows window style and extended style */
423 dwExStyle = GetWindowLongPtr(pRLWinPriv->hWnd, GWL_EXSTYLE);
424 dwStyle = GetWindowLongPtr(pRLWinPriv->hWnd, GWL_STYLE);
425
426 /* Get the X and Y location of the X window */
427 iX = iNewX + GetSystemMetrics(SM_XVIRTUALSCREEN);
428 iY = iNewY + GetSystemMetrics(SM_YVIRTUALSCREEN);
429
430 /* Get the height and width of the X window */
431 iWidth = pRLWinPriv->pFrame->width;
432 iHeight = pRLWinPriv->pFrame->height;
433
434 /* Store the origin, height, and width in a rectangle structure */
435 SetRect(&rcNew, iX, iY, iX + iWidth, iY + iHeight);
436
437 #ifdef CYGMULTIWINDOW_DEBUG
438 winDebug("\tWindow {%d, %d, %d, %d}, {%d, %d}\n",
439 rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
440 rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
441 #endif
442 /*
443 * Calculate the required size of the Windows window rectangle,
444 * given the size of the Windows window client area.
445 */
446 AdjustWindowRectEx(&rcNew, dwStyle, FALSE, dwExStyle);
447
448 #ifdef CYGMULTIWINDOW_DEBUG
449 winDebug("\tAdjusted {%d, %d, %d, %d}, {%d, %d}\n",
450 rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
451 rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
452 #endif
453 g_fNoConfigureWindow = TRUE;
454 SetWindowPos(pRLWinPriv->hWnd, NULL, rcNew.left, rcNew.top, 0, 0,
455 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
456 g_fNoConfigureWindow = FALSE;
457 #if CYGMULTIWINDOW_DEBUG
458 winDebug("winMWExtWMMoveFrame (%p) done\n", pRLWinPriv);
459 #endif
460 }
461
462 void
winMWExtWMResizeFrame(RootlessFrameID wid,ScreenPtr pScreen,int iNewX,int iNewY,unsigned int uiNewWidth,unsigned int uiNewHeight,unsigned int uiGravity)463 winMWExtWMResizeFrame(RootlessFrameID wid, ScreenPtr pScreen,
464 int iNewX, int iNewY,
465 unsigned int uiNewWidth, unsigned int uiNewHeight,
466 unsigned int uiGravity)
467 {
468 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
469 RECT rcNew;
470 RECT rcOld;
471 DWORD dwExStyle;
472 DWORD dwStyle;
473 int iX, iY;
474
475 #if CYGMULTIWINDOW_DEBUG
476 winDebug("winMWExtWMResizeFrame (%p) (%d %d)-(%d %d)\n",
477 pRLWinPriv, iNewX, iNewY, uiNewWidth, uiNewHeight);
478 #endif
479
480 pRLWinPriv->fResized = TRUE;
481
482 /* Get the Windows window style and extended style */
483 dwExStyle = GetWindowLongPtr(pRLWinPriv->hWnd, GWL_EXSTYLE);
484 dwStyle = GetWindowLongPtr(pRLWinPriv->hWnd, GWL_STYLE);
485
486 /* Get the X and Y location of the X window */
487 iX = iNewX + GetSystemMetrics(SM_XVIRTUALSCREEN);
488 iY = iNewY + GetSystemMetrics(SM_YVIRTUALSCREEN);
489
490 /* Store the origin, height, and width in a rectangle structure */
491 SetRect(&rcNew, iX, iY, iX + uiNewWidth, iY + uiNewHeight);
492
493 /*
494 * Calculate the required size of the Windows window rectangle,
495 * given the size of the Windows window client area.
496 */
497 AdjustWindowRectEx(&rcNew, dwStyle, FALSE, dwExStyle);
498
499 /* Get a rectangle describing the old Windows window */
500 GetWindowRect(pRLWinPriv->hWnd, &rcOld);
501
502 /* Check if the old rectangle and new rectangle are the same */
503 if (!EqualRect(&rcNew, &rcOld)) {
504
505 g_fNoConfigureWindow = TRUE;
506 MoveWindow(pRLWinPriv->hWnd,
507 rcNew.left, rcNew.top,
508 rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, TRUE);
509 g_fNoConfigureWindow = FALSE;
510 }
511 }
512
513 void
winMWExtWMRestackFrame(RootlessFrameID wid,RootlessFrameID nextWid)514 winMWExtWMRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid)
515 {
516 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
517 win32RootlessWindowPtr pRLNextWinPriv = (win32RootlessWindowPtr) nextWid;
518
519 winScreenPriv(pRLWinPriv->pFrame->win->drawable.pScreen);
520
521 #if CYGMULTIWINDOW_DEBUG
522 winDebug("winMWExtWMRestackFrame (%p)\n", pRLWinPriv);
523 #endif
524
525 if (pScreenPriv && pScreenPriv->fRestacking)
526 return;
527
528 pRLWinPriv->fRestackingNow = TRUE;
529
530 /* Show window */
531 if (!IsWindowVisible(pRLWinPriv->hWnd))
532 ShowWindow(pRLWinPriv->hWnd, SW_SHOWNOACTIVATE);
533
534 if (pRLNextWinPriv == NULL) {
535 #if CYGMULTIWINDOW_DEBUG
536 winDebug("Win %p is top\n", pRLWinPriv);
537 #endif
538 pScreenPriv->widTop = wid;
539 SetWindowPos(pRLWinPriv->hWnd, HWND_TOP,
540 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
541 }
542 else {
543 /* using general wm like twm, wmaker etc.
544 Interleave X window and Windows window will cause problem. */
545 SetWindowPos(pRLWinPriv->hWnd, pRLNextWinPriv->hWnd,
546 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
547 }
548 #if CYGMULTIWINDOW_DEBUG
549 winDebug("winMWExtWMRestackFrame - done (%p)\n", pRLWinPriv);
550 #endif
551
552 pRLWinPriv->fRestackingNow = FALSE;
553 }
554
555 void
winMWExtWMReshapeFrame(RootlessFrameID wid,RegionPtr pShape)556 winMWExtWMReshapeFrame(RootlessFrameID wid, RegionPtr pShape)
557 {
558 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
559 HRGN hRgn, hRgnWindow, hRgnClient;
560 RECT rcWindow, rcClient;
561
562 #if CYGMULTIWINDOW_DEBUG
563 winDebug("winMWExtWMReshapeFrame (%p)\n", pRLWinPriv);
564 #endif
565
566 hRgn = winMWExtWMCreateRgnFromRegion(pShape);
567
568 /* Create region for non-client area */
569 GetWindowRect(pRLWinPriv->hWnd, &rcWindow);
570 GetClientRect(pRLWinPriv->hWnd, &rcClient);
571 MapWindowPoints(pRLWinPriv->hWnd, HWND_DESKTOP, (LPPOINT) &rcClient, 2);
572 OffsetRgn(hRgn, rcClient.left - rcWindow.left, rcClient.top - rcWindow.top);
573 OffsetRect(&rcClient, -rcWindow.left, -rcWindow.top);
574 OffsetRect(&rcWindow, -rcWindow.left, -rcWindow.top);
575 hRgnWindow = CreateRectRgnIndirect(&rcWindow);
576 hRgnClient = CreateRectRgnIndirect(&rcClient);
577 CombineRgn(hRgnWindow, hRgnWindow, hRgnClient, RGN_DIFF);
578 CombineRgn(hRgn, hRgnWindow, hRgn, RGN_OR);
579
580 SetWindowRgn(pRLWinPriv->hWnd, hRgn, TRUE);
581
582 DeleteObject(hRgnWindow);
583 DeleteObject(hRgnClient);
584 }
585
586 void
winMWExtWMUnmapFrame(RootlessFrameID wid)587 winMWExtWMUnmapFrame(RootlessFrameID wid)
588 {
589 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
590
591 #if CYGMULTIWINDOW_DEBUG
592 winDebug("winMWExtWMUnmapFrame (%p)\n", pRLWinPriv);
593 #endif
594
595 g_fNoConfigureWindow = TRUE;
596 //ShowWindow (pRLWinPriv->hWnd, SW_MINIMIZE);
597 ShowWindow(pRLWinPriv->hWnd, SW_HIDE);
598 g_fNoConfigureWindow = FALSE;
599 }
600
601 /*
602 * Fixme: Code sharing with winshadgdi.c and other engine support
603 */
604 void
winMWExtWMStartDrawing(RootlessFrameID wid,char ** pixelData,int * bytesPerRow)605 winMWExtWMStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow)
606 {
607 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
608 winPrivScreenPtr pScreenPriv = NULL;
609 winScreenInfo *pScreenInfo = NULL;
610 ScreenPtr pScreen = NULL;
611 DIBSECTION dibsection;
612 Bool fReturn = TRUE;
613 HDC hdcNew;
614 HBITMAP hbmpNew;
615
616 #if CYGMULTIWINDOW_DEBUG
617 winDebug("winMWExtWMStartDrawing (%p) %08x\n", pRLWinPriv,
618 pRLWinPriv->fDestroyed);
619 #endif
620
621 if (!pRLWinPriv->fDestroyed) {
622 pScreen = pRLWinPriv->pFrame->win->drawable.pScreen;
623 if (pScreen)
624 pScreenPriv = winGetScreenPriv(pScreen);
625 if (pScreenPriv)
626 pScreenInfo = pScreenPriv->pScreenInfo;
627
628 #if CYGMULTIWINDOW_DEBUG
629 winDebug("\tpScreenPriv %p\n", pScreenPriv);
630 winDebug("\tpScreenInfo %p\n", pScreenInfo);
631 winDebug("\t(%d, %d)\n", (int) pRLWinPriv->pFrame->width,
632 (int) pRLWinPriv->pFrame->height);
633 #endif
634 if (pRLWinPriv->hdcScreen == NULL) {
635 InitWin32RootlessEngine(pRLWinPriv);
636 }
637
638 if (pRLWinPriv->fResized) {
639 /* width * bpp must be multiple of 4 to match 32bit alignment */
640 int stridesize;
641 int misalignment;
642
643 pRLWinPriv->pbmihShadow->biWidth = pRLWinPriv->pFrame->width;
644 pRLWinPriv->pbmihShadow->biHeight = -pRLWinPriv->pFrame->height;
645
646 stridesize = pRLWinPriv->pFrame->width * (pScreenInfo->dwBPP >> 3);
647 misalignment = stridesize & 3;
648 if (misalignment != 0) {
649 stridesize += 4 - misalignment;
650 pRLWinPriv->pbmihShadow->biWidth =
651 stridesize / (pScreenInfo->dwBPP >> 3);
652 winDebug("\tresizing to %d (was %d)\n",
653 pRLWinPriv->pbmihShadow->biWidth,
654 pRLWinPriv->pFrame->width);
655 }
656
657 hdcNew = CreateCompatibleDC(pRLWinPriv->hdcScreen);
658 /* Create a DI shadow bitmap with a bit pointer */
659 hbmpNew = CreateDIBSection(pRLWinPriv->hdcScreen,
660 (BITMAPINFO *) pRLWinPriv->pbmihShadow,
661 DIB_RGB_COLORS,
662 (VOID **) &pRLWinPriv->pfb, NULL, 0);
663 if (hbmpNew == NULL || pRLWinPriv->pfb == NULL) {
664 ErrorF("winMWExtWMStartDrawing - CreateDIBSection failed\n");
665 //return FALSE;
666 }
667 else {
668 #if CYGMULTIWINDOW_DEBUG
669 winDebug("winMWExtWMStartDrawing - Shadow buffer allocated\n");
670 #endif
671 }
672
673 /* Get information about the bitmap that was allocated */
674 GetObject(hbmpNew, sizeof(dibsection), &dibsection);
675
676 #if CYGMULTIWINDOW_DEBUG
677 /* Print information about bitmap allocated */
678 winDebug("winMWExtWMStartDrawing - Dibsection width: %d height: %d "
679 "depth: %d size image: %d\n",
680 (unsigned int) dibsection.dsBmih.biWidth,
681 (unsigned int) dibsection.dsBmih.biHeight,
682 (unsigned int) dibsection.dsBmih.biBitCount,
683 (unsigned int) dibsection.dsBmih.biSizeImage);
684 #endif
685
686 /* Select the shadow bitmap into the shadow DC */
687 SelectObject(hdcNew, hbmpNew);
688
689 #if CYGMULTIWINDOW_DEBUG
690 winDebug("winMWExtWMStartDrawing - Attempting a shadow blit\n");
691 #endif
692
693 /* Blit from the old shadow to the new shadow */
694 fReturn = BitBlt(hdcNew,
695 0, 0,
696 pRLWinPriv->pFrame->width,
697 pRLWinPriv->pFrame->height, pRLWinPriv->hdcShadow,
698 0, 0, SRCCOPY);
699 if (fReturn) {
700 #if CYGMULTIWINDOW_DEBUG
701 winDebug("winMWExtWMStartDrawing - Shadow blit success\n");
702 #endif
703 }
704 else {
705 ErrorF("winMWExtWMStartDrawing - Shadow blit failure\n");
706 }
707
708 /* Look for height weirdness */
709 if (dibsection.dsBmih.biHeight < 0) {
710 /* FIXME: Figure out why biHeight is sometimes negative */
711 ErrorF("winMWExtWMStartDrawing - WEIRDNESS - "
712 "biHeight still negative: %d\n",
713 (int) dibsection.dsBmih.biHeight);
714 ErrorF("winMWExtWMStartDrawing - WEIRDNESS - "
715 "Flipping biHeight sign\n");
716 dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight;
717 }
718
719 pRLWinPriv->dwWidthBytes = dibsection.dsBm.bmWidthBytes;
720
721 #if CYGMULTIWINDOW_DEBUG
722 winDebug("winMWExtWMStartDrawing - bytesPerRow: %d\n",
723 (unsigned int) dibsection.dsBm.bmWidthBytes);
724 #endif
725
726 /* Free the old shadow bitmap */
727 DeleteObject(pRLWinPriv->hdcShadow);
728 DeleteObject(pRLWinPriv->hbmpShadow);
729
730 pRLWinPriv->hdcShadow = hdcNew;
731 pRLWinPriv->hbmpShadow = hbmpNew;
732
733 pRLWinPriv->fResized = FALSE;
734 #if CYGMULTIWINDOW_DEBUG && FALSE
735 winDebug("winMWExtWMStartDrawing - 0x%08x %d\n",
736 (unsigned int) pRLWinPriv->pfb,
737 (unsigned int) dibsection.dsBm.bmWidthBytes);
738 #endif
739 }
740 }
741 else {
742 ErrorF("winMWExtWMStartDrawing - Already window was destroyed \n");
743 }
744 #if CYGMULTIWINDOW_DEBUG
745 winDebug("winMWExtWMStartDrawing - done (%p) %p %d\n",
746 pRLWinPriv,
747 pRLWinPriv->pfb,
748 (unsigned int) pRLWinPriv->dwWidthBytes);
749 #endif
750 *pixelData = pRLWinPriv->pfb;
751 *bytesPerRow = pRLWinPriv->dwWidthBytes;
752 }
753
754 void
winMWExtWMStopDrawing(RootlessFrameID wid,Bool fFlush)755 winMWExtWMStopDrawing(RootlessFrameID wid, Bool fFlush)
756 {
757 #if 0
758 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
759 BLENDFUNCTION bfBlend;
760 SIZE szWin;
761 POINT ptSrc;
762
763 #if CYGMULTIWINDOW_DEBUG || TRUE
764 winDebug("winMWExtWMStopDrawing (%08x)\n", pRLWinPriv);
765 #endif
766 szWin.cx = pRLWinPriv->dwWidth;
767 szWin.cy = pRLWinPriv->dwHeight;
768 ptSrc.x = 0;
769 ptSrc.y = 0;
770 bfBlend.BlendOp = AC_SRC_OVER;
771 bfBlend.BlendFlags = 0;
772 bfBlend.SourceConstantAlpha = 255;
773 bfBlend.AlphaFormat = AC_SRC_ALPHA;
774
775 if (!UpdateLayeredWindow(pRLWinPriv->hWnd,
776 NULL, NULL, &szWin,
777 pRLWinPriv->hdcShadow, &ptSrc,
778 0, &bfBlend, ULW_ALPHA)) {
779 ErrorF("winMWExtWMStopDrawing - UpdateLayeredWindow failed\n");
780 }
781 #endif
782 }
783
784 void
winMWExtWMUpdateRegion(RootlessFrameID wid,RegionPtr pDamage)785 winMWExtWMUpdateRegion(RootlessFrameID wid, RegionPtr pDamage)
786 {
787 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
788
789 #if 0
790 BLENDFUNCTION bfBlend;
791 SIZE szWin;
792 POINT ptSrc;
793 #endif
794 #if CYGMULTIWINDOW_DEBUG && 0
795 winDebug("winMWExtWMUpdateRegion (%08x)\n", pRLWinPriv);
796 #endif
797 #if 0
798 szWin.cx = pRLWinPriv->dwWidth;
799 szWin.cy = pRLWinPriv->dwHeight;
800 ptSrc.x = 0;
801 ptSrc.y = 0;
802 bfBlend.BlendOp = AC_SRC_OVER;
803 bfBlend.BlendFlags = 0;
804 bfBlend.SourceConstantAlpha = 255;
805 bfBlend.AlphaFormat = AC_SRC_ALPHA;
806
807 if (!UpdateLayeredWindow(pRLWinPriv->hWnd,
808 NULL, NULL, &szWin,
809 pRLWinPriv->hdcShadow, &ptSrc,
810 0, &bfBlend, ULW_ALPHA)) {
811 LPVOID lpMsgBuf;
812
813 /* Display a fancy error message */
814 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
815 FORMAT_MESSAGE_FROM_SYSTEM |
816 FORMAT_MESSAGE_IGNORE_INSERTS,
817 NULL,
818 GetLastError(),
819 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
820 (LPTSTR) &lpMsgBuf, 0, NULL);
821
822 ErrorF("winMWExtWMUpdateRegion - UpdateLayeredWindow failed: %s\n",
823 (LPSTR) lpMsgBuf);
824 LocalFree(lpMsgBuf);
825 }
826 #endif
827 if (!g_fNoConfigureWindow)
828 UpdateWindow(pRLWinPriv->hWnd);
829 }
830
831 void
winMWExtWMDamageRects(RootlessFrameID wid,int nCount,const BoxRec * pRects,int shift_x,int shift_y)832 winMWExtWMDamageRects(RootlessFrameID wid, int nCount, const BoxRec * pRects,
833 int shift_x, int shift_y)
834 {
835 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
836 const BoxRec *pEnd;
837
838 #if CYGMULTIWINDOW_DEBUG && 0
839 winDebug("winMWExtWMDamageRects (%08x, %d, %08x, %d, %d)\n",
840 pRLWinPriv, nCount, pRects, shift_x, shift_y);
841 #endif
842
843 for (pEnd = pRects + nCount; pRects < pEnd; pRects++) {
844 RECT rcDmg;
845
846 rcDmg.left = pRects->x1 + shift_x;
847 rcDmg.top = pRects->y1 + shift_y;
848 rcDmg.right = pRects->x2 + shift_x;
849 rcDmg.bottom = pRects->y2 + shift_y;
850
851 InvalidateRect(pRLWinPriv->hWnd, &rcDmg, FALSE);
852 }
853 }
854
855 void
winMWExtWMRootlessSwitchWindow(RootlessWindowPtr pFrame,WindowPtr oldWin)856 winMWExtWMRootlessSwitchWindow(RootlessWindowPtr pFrame, WindowPtr oldWin)
857 {
858 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid;
859
860 #if CYGMULTIWINDOW_DEBUG
861 winDebug("winMWExtWMRootlessSwitchWindow (%p) %p\n",
862 pRLWinPriv, pRLWinPriv->hWnd);
863 #endif
864 pRLWinPriv->pFrame = pFrame;
865 pRLWinPriv->fResized = TRUE;
866
867 /* Set the window extended style flags */
868 SetWindowLongPtr(pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
869
870 /* Set the window standard style flags */
871 SetWindowLongPtr(pRLWinPriv->hWnd, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN);
872
873 DeleteProperty(serverClient, oldWin, AtmWindowsWmNativeHwnd());
874 winMWExtWMSetNativeProperty(pFrame);
875 #if CYGMULTIWINDOW_DEBUG
876 #if 0
877 {
878 WindowPtr pWin2 = NULL;
879 win32RootlessWindowPtr pRLWinPriv2 = NULL;
880
881 /* Check if the Windows window property for our X window pointer is valid */
882 if ((pWin2 =
883 (WindowPtr) GetProp(pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) {
884 pRLWinPriv2 =
885 (win32RootlessWindowPtr) RootlessFrameForWindow(pWin2, FALSE);
886 }
887 winDebug("winMWExtWMSwitchFrame2 (%08x) %08x\n",
888 pRLWinPriv2, pRLWinPriv2->hWnd);
889 if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) {
890 winDebug("Error param missmatch\n");
891 }
892 }
893 #endif
894 #endif
895 }
896
897 void
winMWExtWMCopyBytes(unsigned int width,unsigned int height,const void * src,unsigned int srcRowBytes,void * dst,unsigned int dstRowBytes)898 winMWExtWMCopyBytes(unsigned int width, unsigned int height,
899 const void *src, unsigned int srcRowBytes,
900 void *dst, unsigned int dstRowBytes)
901 {
902 #if CYGMULTIWINDOW_DEBUG
903 winDebug("winMWExtWMCopyBytes - Not implemented\n");
904 #endif
905 }
906
907 void
winMWExtWMCopyWindow(RootlessFrameID wid,int nDstRects,const BoxRec * pDstRects,int nDx,int nDy)908 winMWExtWMCopyWindow(RootlessFrameID wid, int nDstRects,
909 const BoxRec * pDstRects, int nDx, int nDy)
910 {
911 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
912 const BoxRec *pEnd;
913 RECT rcDmg;
914
915 #if CYGMULTIWINDOW_DEBUG
916 winDebug("winMWExtWMCopyWindow (%p, %d, %p, %d, %d)\n",
917 pRLWinPriv, nDstRects, pDstRects, nDx, nDy);
918 #endif
919
920 for (pEnd = pDstRects + nDstRects; pDstRects < pEnd; pDstRects++) {
921 #if CYGMULTIWINDOW_DEBUG
922 winDebug("BitBlt (%d, %d, %d, %d) (%d, %d)\n",
923 pDstRects->x1, pDstRects->y1,
924 pDstRects->x2 - pDstRects->x1,
925 pDstRects->y2 - pDstRects->y1,
926 pDstRects->x1 + nDx, pDstRects->y1 + nDy);
927 #endif
928
929 if (!BitBlt(pRLWinPriv->hdcShadow,
930 pDstRects->x1, pDstRects->y1,
931 pDstRects->x2 - pDstRects->x1,
932 pDstRects->y2 - pDstRects->y1,
933 pRLWinPriv->hdcShadow,
934 pDstRects->x1 + nDx, pDstRects->y1 + nDy, SRCCOPY)) {
935 ErrorF("winMWExtWMCopyWindow - BitBlt failed.\n");
936 }
937
938 rcDmg.left = pDstRects->x1;
939 rcDmg.top = pDstRects->y1;
940 rcDmg.right = pDstRects->x2;
941 rcDmg.bottom = pDstRects->y2;
942
943 InvalidateRect(pRLWinPriv->hWnd, &rcDmg, FALSE);
944 }
945 #if CYGMULTIWINDOW_DEBUG
946 winDebug("winMWExtWMCopyWindow - done\n");
947 #endif
948 }
949
950 /*
951 * winMWExtWMSetNativeProperty
952 */
953
954 static void
winMWExtWMSetNativeProperty(RootlessWindowPtr pFrame)955 winMWExtWMSetNativeProperty(RootlessWindowPtr pFrame)
956 {
957 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid;
958 long lData;
959
960 /* FIXME: move this to WindowsWM extension */
961
962 lData = (long) pRLWinPriv->hWnd;
963 dixChangeWindowProperty(serverClient, pFrame->win, AtmWindowsWmNativeHwnd(),
964 XA_INTEGER, 32, PropModeReplace, 1, &lData, TRUE);
965 }
966