xref: /OK3568_Linux_fs/external/xserver/hw/xwin/winwin32rootless.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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