4 * Copyright 1998,1999 Patrik Stridvall
14 #include "debugtools.h"
16 DEFAULT_DEBUG_CHANNEL(ttydrv
);
18 #define SWP_AGG_NOGEOMETRYCHANGE \
19 (SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE)
20 #define SWP_AGG_NOPOSCHANGE \
21 (SWP_AGG_NOGEOMETRYCHANGE | SWP_NOZORDER)
22 #define SWP_AGG_STATUSFLAGS \
23 (SWP_AGG_NOPOSCHANGE | SWP_FRAMECHANGED | SWP_HIDEWINDOW | SWP_SHOWWINDOW)
25 /**********************************************************************
26 * CreateWindow (TTYDRV.@)
28 BOOL
TTYDRV_CreateWindow( HWND hwnd
, CREATESTRUCTA
*cs
, BOOL unicode
)
33 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
35 INT cellWidth
=8, cellHeight
=8; /* FIXME: Hardcoded */
37 TRACE("(%x)\n", hwnd
);
39 /* Only create top-level windows */
40 if (!(wndPtr
->dwStyle
& WS_CHILD
))
42 if (!wndPtr
->parent
) /* desktop */
46 int x
= wndPtr
->rectWindow
.left
;
47 int y
= wndPtr
->rectWindow
.top
;
48 int cx
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
49 int cy
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
51 window
= subwin( root_window
, cy
/cellHeight
, cx
/cellWidth
,
52 y
/cellHeight
, x
/cellWidth
);
56 wndPtr
->pDriverData
= window
;
58 WIN_ReleaseWndPtr( wndPtr
);
59 #else /* defined(WINE_CURSES) */
60 FIXME("(%x): stub\n", hwnd
);
61 #endif /* defined(WINE_CURSES) */
65 ret
= SendMessageW( hwnd
, WM_NCCREATE
, 0, (LPARAM
)cs
);
66 if (ret
) ret
= (SendMessageW( hwnd
, WM_CREATE
, 0, (LPARAM
)cs
) != -1);
70 ret
= SendMessageA( hwnd
, WM_NCCREATE
, 0, (LPARAM
)cs
);
71 if (ret
) ret
= (SendMessageA( hwnd
, WM_CREATE
, 0, (LPARAM
)cs
) != -1);
76 /***********************************************************************
77 * DestroyWindow (TTYDRV.@)
79 BOOL
TTYDRV_DestroyWindow( HWND hwnd
)
82 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
83 WINDOW
*window
= wndPtr
->pDriverData
;
85 TRACE("(%x)\n", hwnd
);
87 if (window
&& window
!= root_window
) delwin(window
);
88 wndPtr
->pDriverData
= NULL
;
89 WIN_ReleaseWndPtr( wndPtr
);
90 #else /* defined(WINE_CURSES) */
91 FIXME("(%x): stub\n", hwnd
);
92 #endif /* defined(WINE_CURSES) */
97 /***********************************************************************
100 * Change region from DC-origin relative coordinates to screen coords.
103 static void DCE_OffsetVisRgn( HDC hDC
, HRGN hVisRgn
)
106 if (!(dc
= DC_GetDCPtr( hDC
))) return;
108 OffsetRgn( hVisRgn
, dc
->DCOrgX
, dc
->DCOrgY
);
110 GDI_ReleaseObj( hDC
);
114 /***********************************************************************
117 * Calculate the visible rectangle of a window (i.e. the client or
118 * window area clipped by the client area of all ancestors) in the
119 * corresponding coordinates. Return FALSE if the visible region is empty.
121 static BOOL
DCE_GetVisRect( WND
*wndPtr
, BOOL clientArea
, RECT
*lprect
)
123 *lprect
= clientArea
? wndPtr
->rectClient
: wndPtr
->rectWindow
;
125 if (wndPtr
->dwStyle
& WS_VISIBLE
)
127 INT xoffset
= lprect
->left
;
128 INT yoffset
= lprect
->top
;
130 while ((wndPtr
= WIN_FindWndPtr( GetAncestor(wndPtr
->hwndSelf
,GA_PARENT
) )))
132 if ( (wndPtr
->dwStyle
& (WS_ICONIC
| WS_VISIBLE
)) != WS_VISIBLE
)
134 WIN_ReleaseWndPtr(wndPtr
);
138 xoffset
+= wndPtr
->rectClient
.left
;
139 yoffset
+= wndPtr
->rectClient
.top
;
140 OffsetRect( lprect
, wndPtr
->rectClient
.left
,
141 wndPtr
->rectClient
.top
);
143 if( (wndPtr
->rectClient
.left
>= wndPtr
->rectClient
.right
) ||
144 (wndPtr
->rectClient
.top
>= wndPtr
->rectClient
.bottom
) ||
145 (lprect
->left
>= wndPtr
->rectClient
.right
) ||
146 (lprect
->right
<= wndPtr
->rectClient
.left
) ||
147 (lprect
->top
>= wndPtr
->rectClient
.bottom
) ||
148 (lprect
->bottom
<= wndPtr
->rectClient
.top
) )
150 WIN_ReleaseWndPtr(wndPtr
);
154 lprect
->left
= max( lprect
->left
, wndPtr
->rectClient
.left
);
155 lprect
->right
= min( lprect
->right
, wndPtr
->rectClient
.right
);
156 lprect
->top
= max( lprect
->top
, wndPtr
->rectClient
.top
);
157 lprect
->bottom
= min( lprect
->bottom
, wndPtr
->rectClient
.bottom
);
159 WIN_ReleaseWndPtr(wndPtr
);
161 OffsetRect( lprect
, -xoffset
, -yoffset
);
166 SetRectEmpty( lprect
);
171 /***********************************************************************
174 * Go through the linked list of windows from pWndStart to pWndEnd,
175 * adding to the clip region the intersection of the target rectangle
176 * with an offset window rectangle.
178 static void DCE_AddClipRects( HWND parent
, HWND end
, HRGN hrgnClip
, LPRECT lpRect
, int x
, int y
)
183 HWND
*list
= WIN_ListChildren( parent
);
186 for (i
= 0; list
[i
]; i
++)
188 if (list
[i
] == end
) break;
189 if (!(pWnd
= WIN_FindWndPtr( list
[i
] ))) continue;
190 if (pWnd
->dwStyle
& WS_VISIBLE
)
192 rect
.left
= pWnd
->rectWindow
.left
+ x
;
193 rect
.top
= pWnd
->rectWindow
.top
+ y
;
194 rect
.right
= pWnd
->rectWindow
.right
+ x
;
195 rect
.bottom
= pWnd
->rectWindow
.bottom
+ y
;
196 if( IntersectRect( &rect
, &rect
, lpRect
))
198 if(!REGION_UnionRectWithRgn( hrgnClip
, &rect
))
200 WIN_ReleaseWndPtr( pWnd
);
205 WIN_ReleaseWndPtr( pWnd
);
207 HeapFree( GetProcessHeap(), 0, list
);
211 /***********************************************************************
214 * Return the visible region of a window, i.e. the client or window area
215 * clipped by the client area of all ancestors, and then optionally
216 * by siblings and children.
218 static HRGN
DCE_GetVisRgn( HWND hwnd
, WORD flags
, HWND hwndChild
, WORD cflags
)
222 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
223 WND
*childWnd
= WIN_FindWndPtr( hwndChild
);
225 /* Get visible rectangle and create a region with it. */
227 if (wndPtr
&& DCE_GetVisRect(wndPtr
, !(flags
& DCX_WINDOW
), &rect
))
229 if((hrgnVis
= CreateRectRgnIndirect( &rect
)))
231 HRGN hrgnClip
= CreateRectRgn( 0, 0, 0, 0 );
232 INT xoffset
, yoffset
;
236 /* Compute obscured region for the visible rectangle by
237 * clipping children, siblings, and ancestors. Note that
238 * DCE_GetVisRect() returns a rectangle either in client
239 * or in window coordinates (for DCX_WINDOW request). */
241 if (flags
& DCX_CLIPCHILDREN
)
243 if( flags
& DCX_WINDOW
)
245 /* adjust offsets since child window rectangles are
246 * in client coordinates */
248 xoffset
= wndPtr
->rectClient
.left
- wndPtr
->rectWindow
.left
;
249 yoffset
= wndPtr
->rectClient
.top
- wndPtr
->rectWindow
.top
;
252 xoffset
= yoffset
= 0;
254 DCE_AddClipRects( wndPtr
->hwndSelf
, 0, hrgnClip
, &rect
, xoffset
, yoffset
);
257 /* We may need to clip children of child window, if a window with PARENTDC
258 * class style and CLIPCHILDREN window style (like in Free Agent 16
259 * preference dialogs) gets here, we take the region for the parent window
260 * but apparently still need to clip the children of the child window... */
262 if( (cflags
& DCX_CLIPCHILDREN
) && childWnd
)
264 if( flags
& DCX_WINDOW
)
266 /* adjust offsets since child window rectangles are
267 * in client coordinates */
269 xoffset
= wndPtr
->rectClient
.left
- wndPtr
->rectWindow
.left
;
270 yoffset
= wndPtr
->rectClient
.top
- wndPtr
->rectWindow
.top
;
273 xoffset
= yoffset
= 0;
275 /* client coordinates of child window */
276 xoffset
+= childWnd
->rectClient
.left
;
277 yoffset
+= childWnd
->rectClient
.top
;
279 DCE_AddClipRects( childWnd
->hwndSelf
, 0, hrgnClip
,
280 &rect
, xoffset
, yoffset
);
283 /* sibling window rectangles are in client
284 * coordinates of the parent window */
286 if (flags
& DCX_WINDOW
)
288 xoffset
= -wndPtr
->rectWindow
.left
;
289 yoffset
= -wndPtr
->rectWindow
.top
;
293 xoffset
= -wndPtr
->rectClient
.left
;
294 yoffset
= -wndPtr
->rectClient
.top
;
297 if (flags
& DCX_CLIPSIBLINGS
&& wndPtr
->parent
)
298 DCE_AddClipRects( wndPtr
->parent
, wndPtr
->hwndSelf
,
299 hrgnClip
, &rect
, xoffset
, yoffset
);
301 /* Clip siblings of all ancestors that have the
302 * WS_CLIPSIBLINGS style
305 while (wndPtr
->parent
)
307 WND
*ptr
= WIN_FindWndPtr( wndPtr
->parent
);
308 WIN_ReleaseWndPtr( wndPtr
);
310 xoffset
-= wndPtr
->rectClient
.left
;
311 yoffset
-= wndPtr
->rectClient
.top
;
312 if(wndPtr
->dwStyle
& WS_CLIPSIBLINGS
&& wndPtr
->parent
)
314 DCE_AddClipRects( wndPtr
->parent
, wndPtr
->hwndSelf
,
315 hrgnClip
, &rect
, xoffset
, yoffset
);
319 /* Now once we've got a jumbo clip region we have
320 * to substract it from the visible rectangle.
322 CombineRgn( hrgnVis
, hrgnVis
, hrgnClip
, RGN_DIFF
);
323 DeleteObject( hrgnClip
);
327 DeleteObject( hrgnVis
);
333 hrgnVis
= CreateRectRgn(0, 0, 0, 0); /* empty */
334 WIN_ReleaseWndPtr(wndPtr
);
335 WIN_ReleaseWndPtr(childWnd
);
340 /***********************************************************************
343 * Set the drawable, origin and dimensions for the DC associated to
346 BOOL
TTYDRV_GetDC( HWND hwnd
, HDC hdc
, HRGN hrgn
, DWORD flags
)
348 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
351 HRGN hrgnVisible
= 0;
353 if (!wndPtr
) return FALSE
;
355 if (!(dc
= DC_GetDCPtr( hdc
)))
357 WIN_ReleaseWndPtr( wndPtr
);
361 if(flags
& DCX_WINDOW
)
363 dc
->DCOrgX
= wndPtr
->rectWindow
.left
;
364 dc
->DCOrgY
= wndPtr
->rectWindow
.top
;
368 dc
->DCOrgX
= wndPtr
->rectClient
.left
;
369 dc
->DCOrgY
= wndPtr
->rectClient
.top
;
371 updateVisRgn
= (dc
->flags
& DC_DIRTY
) != 0;
372 GDI_ReleaseObj( hdc
);
376 if (flags
& DCX_PARENTCLIP
)
378 WND
*parentPtr
= WIN_FindWndPtr( wndPtr
->parent
);
380 if( wndPtr
->dwStyle
& WS_VISIBLE
&& !(parentPtr
->dwStyle
& WS_MINIMIZE
) )
384 if( parentPtr
->dwStyle
& WS_CLIPSIBLINGS
)
385 dcxFlags
= DCX_CLIPSIBLINGS
| (flags
& ~(DCX_CLIPCHILDREN
| DCX_WINDOW
));
387 dcxFlags
= flags
& ~(DCX_CLIPSIBLINGS
| DCX_CLIPCHILDREN
| DCX_WINDOW
);
389 hrgnVisible
= DCE_GetVisRgn( parentPtr
->hwndSelf
, dcxFlags
,
390 wndPtr
->hwndSelf
, flags
);
391 if( flags
& DCX_WINDOW
)
392 OffsetRgn( hrgnVisible
, -wndPtr
->rectWindow
.left
,
393 -wndPtr
->rectWindow
.top
);
395 OffsetRgn( hrgnVisible
, -wndPtr
->rectClient
.left
,
396 -wndPtr
->rectClient
.top
);
397 DCE_OffsetVisRgn( hdc
, hrgnVisible
);
400 hrgnVisible
= CreateRectRgn( 0, 0, 0, 0 );
401 WIN_ReleaseWndPtr(parentPtr
);
405 hrgnVisible
= DCE_GetVisRgn( hwnd
, flags
, 0, 0 );
406 DCE_OffsetVisRgn( hdc
, hrgnVisible
);
408 SelectVisRgn16( hdc
, hrgnVisible
);
411 /* apply additional region operation (if any) */
413 if( flags
& (DCX_EXCLUDERGN
| DCX_INTERSECTRGN
) )
415 if( !hrgnVisible
) hrgnVisible
= CreateRectRgn( 0, 0, 0, 0 );
417 TRACE("\tsaved VisRgn, clipRgn = %04x\n", hrgn
);
420 CombineRgn( hrgnVisible
, hrgn
, 0, RGN_COPY
);
421 DCE_OffsetVisRgn( hdc
, hrgnVisible
);
422 CombineRgn( hrgnVisible
, InquireVisRgn16( hdc
), hrgnVisible
,
423 (flags
& DCX_INTERSECTRGN
) ? RGN_AND
: RGN_DIFF
);
424 SelectVisRgn16( hdc
, hrgnVisible
);
427 if (hrgnVisible
) DeleteObject( hrgnVisible
);
429 WIN_ReleaseWndPtr( wndPtr
);
434 /***********************************************************************
435 * SetWindowPos (TTYDRV.@)
437 BOOL
TTYDRV_SetWindowPos( WINDOWPOS
*winpos
)
440 RECT newWindowRect
, newClientRect
;
442 HWND hwndActive
= GetForegroundWindow();
444 TRACE( "hwnd %04x, swp (%i,%i)-(%i,%i) flags %08x\n",
445 winpos
->hwnd
, winpos
->x
, winpos
->y
,
446 winpos
->x
+ winpos
->cx
, winpos
->y
+ winpos
->cy
, winpos
->flags
);
448 /* ------------------------------------------------------------------------ CHECKS */
450 /* Check window handle */
452 if (winpos
->hwnd
== GetDesktopWindow()) return FALSE
;
453 if (!(wndPtr
= WIN_FindWndPtr( winpos
->hwnd
))) return FALSE
;
455 TRACE("\tcurrent (%i,%i)-(%i,%i), style %08x\n",
456 wndPtr
->rectWindow
.left
, wndPtr
->rectWindow
.top
,
457 wndPtr
->rectWindow
.right
, wndPtr
->rectWindow
.bottom
, (unsigned)wndPtr
->dwStyle
);
459 /* Fix redundant flags */
461 if(wndPtr
->dwStyle
& WS_VISIBLE
)
462 winpos
->flags
&= ~SWP_SHOWWINDOW
;
465 if (!(winpos
->flags
& SWP_SHOWWINDOW
)) winpos
->flags
|= SWP_NOREDRAW
;
466 winpos
->flags
&= ~SWP_HIDEWINDOW
;
469 if ( winpos
->cx
< 0 ) winpos
->cx
= 0;
470 if ( winpos
->cy
< 0 ) winpos
->cy
= 0;
472 if ((wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
== winpos
->cx
) &&
473 (wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
== winpos
->cy
))
474 winpos
->flags
|= SWP_NOSIZE
; /* Already the right size */
476 if ((wndPtr
->rectWindow
.left
== winpos
->x
) && (wndPtr
->rectWindow
.top
== winpos
->y
))
477 winpos
->flags
|= SWP_NOMOVE
; /* Already the right position */
479 if (winpos
->hwnd
== hwndActive
)
480 winpos
->flags
|= SWP_NOACTIVATE
; /* Already active */
481 else if ( (wndPtr
->dwStyle
& (WS_POPUP
| WS_CHILD
)) != WS_CHILD
)
483 if(!(winpos
->flags
& SWP_NOACTIVATE
)) /* Bring to the top when activating */
485 winpos
->flags
&= ~SWP_NOZORDER
;
486 winpos
->hwndInsertAfter
= HWND_TOP
;
491 /* Check hwndInsertAfter */
493 /* FIXME: TOPMOST not supported yet */
494 if ((winpos
->hwndInsertAfter
== HWND_TOPMOST
) ||
495 (winpos
->hwndInsertAfter
== HWND_NOTOPMOST
)) winpos
->hwndInsertAfter
= HWND_TOP
;
497 /* hwndInsertAfter must be a sibling of the window */
498 if ((winpos
->hwndInsertAfter
!= HWND_TOP
) && (winpos
->hwndInsertAfter
!= HWND_BOTTOM
))
500 WND
* wnd
= WIN_FindWndPtr(winpos
->hwndInsertAfter
);
503 if( wnd
->parent
!= wndPtr
->parent
)
506 WIN_ReleaseWndPtr(wnd
);
509 /* don't need to change the Zorder of hwnd if it's already inserted
510 * after hwndInsertAfter or when inserting hwnd after itself.
512 if ((winpos
->hwnd
== winpos
->hwndInsertAfter
) ||
513 (winpos
->hwnd
== GetWindow( winpos
->hwndInsertAfter
, GW_HWNDNEXT
)))
514 winpos
->flags
|= SWP_NOZORDER
;
516 WIN_ReleaseWndPtr(wnd
);
519 Pos
: /* ------------------------------------------------------------------------ MAIN part */
521 /* Send WM_WINDOWPOSCHANGING message */
523 if (!(winpos
->flags
& SWP_NOSENDCHANGING
))
524 SendMessageA( wndPtr
->hwndSelf
, WM_WINDOWPOSCHANGING
, 0, (LPARAM
)winpos
);
526 /* Calculate new position and size */
528 newWindowRect
= wndPtr
->rectWindow
;
529 newClientRect
= (wndPtr
->dwStyle
& WS_MINIMIZE
) ? wndPtr
->rectWindow
530 : wndPtr
->rectClient
;
532 if (!(winpos
->flags
& SWP_NOSIZE
))
534 newWindowRect
.right
= newWindowRect
.left
+ winpos
->cx
;
535 newWindowRect
.bottom
= newWindowRect
.top
+ winpos
->cy
;
537 if (!(winpos
->flags
& SWP_NOMOVE
))
539 newWindowRect
.left
= winpos
->x
;
540 newWindowRect
.top
= winpos
->y
;
541 newWindowRect
.right
+= winpos
->x
- wndPtr
->rectWindow
.left
;
542 newWindowRect
.bottom
+= winpos
->y
- wndPtr
->rectWindow
.top
;
544 OffsetRect( &newClientRect
, winpos
->x
- wndPtr
->rectWindow
.left
,
545 winpos
->y
- wndPtr
->rectWindow
.top
);
548 if( winpos
->hwndInsertAfter
== HWND_TOP
)
550 if (GetWindow( wndPtr
->hwndSelf
, GW_HWNDFIRST
) == wndPtr
->hwndSelf
)
551 winpos
->flags
|= SWP_NOZORDER
;
554 if( winpos
->hwndInsertAfter
== HWND_BOTTOM
)
556 if (!GetWindow( wndPtr
->hwndSelf
, GW_HWNDNEXT
))
557 winpos
->flags
|= SWP_NOZORDER
;
560 if( !(winpos
->flags
& SWP_NOZORDER
) )
561 if( GetWindow(winpos
->hwndInsertAfter
, GW_HWNDNEXT
) == wndPtr
->hwndSelf
)
562 winpos
->flags
|= SWP_NOZORDER
;
564 /* Common operations */
566 /* Send WM_NCCALCSIZE message to get new client area */
567 if( (winpos
->flags
& (SWP_FRAMECHANGED
| SWP_NOSIZE
)) != SWP_NOSIZE
)
569 NCCALCSIZE_PARAMS params
;
570 WINDOWPOS winposCopy
;
572 params
.rgrc
[0] = newWindowRect
;
573 params
.rgrc
[1] = wndPtr
->rectWindow
;
574 params
.rgrc
[2] = wndPtr
->rectClient
;
575 params
.lppos
= &winposCopy
;
576 winposCopy
= *winpos
;
578 SendMessageW( winpos
->hwnd
, WM_NCCALCSIZE
, TRUE
, (LPARAM
)¶ms
);
580 TRACE( "%d,%d-%d,%d\n", params
.rgrc
[0].left
, params
.rgrc
[0].top
,
581 params
.rgrc
[0].right
, params
.rgrc
[0].bottom
);
583 /* If the application send back garbage, ignore it */
584 if (params
.rgrc
[0].left
<= params
.rgrc
[0].right
&&
585 params
.rgrc
[0].top
<= params
.rgrc
[0].bottom
)
586 newClientRect
= params
.rgrc
[0];
588 /* FIXME: WVR_ALIGNxxx */
590 if( newClientRect
.left
!= wndPtr
->rectClient
.left
||
591 newClientRect
.top
!= wndPtr
->rectClient
.top
)
592 winpos
->flags
&= ~SWP_NOCLIENTMOVE
;
594 if( (newClientRect
.right
- newClientRect
.left
!=
595 wndPtr
->rectClient
.right
- wndPtr
->rectClient
.left
) ||
596 (newClientRect
.bottom
- newClientRect
.top
!=
597 wndPtr
->rectClient
.bottom
- wndPtr
->rectClient
.top
) )
598 winpos
->flags
&= ~SWP_NOCLIENTSIZE
;
601 if(!(winpos
->flags
& SWP_NOZORDER
) && winpos
->hwnd
!= winpos
->hwndInsertAfter
)
603 HWND parent
= GetAncestor( winpos
->hwnd
, GA_PARENT
);
604 if (parent
) WIN_LinkWindow( winpos
->hwnd
, parent
, winpos
->hwndInsertAfter
);
607 /* FIXME: actually do something with WVR_VALIDRECTS */
609 WIN_SetRectangles( winpos
->hwnd
, &newWindowRect
, &newClientRect
);
611 if( winpos
->flags
& SWP_SHOWWINDOW
)
612 WIN_SetStyle( winpos
->hwnd
, wndPtr
->dwStyle
| WS_VISIBLE
);
613 else if( winpos
->flags
& SWP_HIDEWINDOW
)
614 WIN_SetStyle( winpos
->hwnd
, wndPtr
->dwStyle
& ~WS_VISIBLE
);
616 /* ------------------------------------------------------------------------ FINAL */
618 /* repaint invalidated region (if any)
620 * FIXME: if SWP_NOACTIVATE is not set then set invalid regions here without any painting
621 * and force update after ChangeActiveWindow() to avoid painting frames twice.
624 if( !(winpos
->flags
& SWP_NOREDRAW
) )
626 RedrawWindow( wndPtr
->parent
, NULL
, 0,
627 RDW_ERASE
| RDW_INVALIDATE
| RDW_ALLCHILDREN
);
628 if (wndPtr
->parent
== GetDesktopWindow())
629 RedrawWindow( wndPtr
->parent
, NULL
, 0,
630 RDW_ERASENOW
| RDW_NOCHILDREN
);
633 if (!(winpos
->flags
& SWP_NOACTIVATE
)) SetActiveWindow( winpos
->hwnd
);
635 /* And last, send the WM_WINDOWPOSCHANGED message */
637 TRACE("\tstatus flags = %04x\n", winpos
->flags
& SWP_AGG_STATUSFLAGS
);
639 if ((((winpos
->flags
& SWP_AGG_STATUSFLAGS
) != SWP_AGG_NOPOSCHANGE
) &&
640 !(winpos
->flags
& SWP_NOSENDCHANGING
)) )
641 SendMessageA( winpos
->hwnd
, WM_WINDOWPOSCHANGED
, 0, (LPARAM
)winpos
);
645 WIN_ReleaseWndPtr(wndPtr
);
650 /***********************************************************************
651 * WINPOS_MinMaximize (internal)
653 *Lifted from x11 driver
655 static UINT
WINPOS_MinMaximize( HWND hwnd
, UINT cmd
, LPRECT rect
)
661 TRACE("0x%04x %u\n", hwnd
, cmd
);
662 FIXME("(%x): stub\n", hwnd
);
664 wpl
.length
= sizeof(wpl
);
665 GetWindowPlacement( hwnd
, &wpl
);
667 /* If I glark this right, yields an immutable window*/
668 swpFlags
= SWP_NOSIZE
| SWP_NOMOVE
;
670 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
672 /*cmd handling goes here. see dlls/x1drv/winpos.c*/
674 WIN_ReleaseWndPtr( wndPtr
);
678 /***********************************************************************
679 * ShowWindow (TTYDRV.@)
681 *Lifted from x11 driver
682 *Sets the specified windows' show state.
684 BOOL
TTYDRV_ShowWindow( HWND hwnd
, INT cmd
)
686 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
687 BOOL wasVisible
, showFlag
;
688 RECT newPos
= {0, 0, 0, 0};
691 if (!wndPtr
) return FALSE
;
692 hwnd
= wndPtr
->hwndSelf
; /* make it a full handle */
694 TRACE("hwnd=%04x, cmd=%d\n", hwnd
, cmd
);
696 wasVisible
= (wndPtr
->dwStyle
& WS_VISIBLE
) != 0;
701 if (!wasVisible
) goto END
;;
702 swp
|= SWP_HIDEWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
|
703 SWP_NOACTIVATE
| SWP_NOZORDER
;
706 case SW_SHOWMINNOACTIVE
:
707 swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
709 case SW_SHOWMINIMIZED
:
710 swp
|= SWP_SHOWWINDOW
;
713 swp
|= SWP_FRAMECHANGED
;
714 if( !(wndPtr
->dwStyle
& WS_MINIMIZE
) )
715 swp
|= WINPOS_MinMaximize( hwnd
, SW_MINIMIZE
, &newPos
);
716 else swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
719 case SW_SHOWMAXIMIZED
: /* same as SW_MAXIMIZE */
720 swp
|= SWP_SHOWWINDOW
| SWP_FRAMECHANGED
;
721 if( !(wndPtr
->dwStyle
& WS_MAXIMIZE
) )
722 swp
|= WINPOS_MinMaximize( hwnd
, SW_MAXIMIZE
, &newPos
);
723 else swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
727 swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
730 swp
|= SWP_SHOWWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
733 * ShowWindow has a little peculiar behavior that if the
734 * window is already the topmost window, it will not
737 if (GetTopWindow((HWND
)0)==hwnd
&& (wasVisible
|| GetActiveWindow() == hwnd
))
738 swp
|= SWP_NOACTIVATE
;
742 case SW_SHOWNOACTIVATE
:
744 if (GetActiveWindow()) swp
|= SWP_NOACTIVATE
;
746 case SW_SHOWNORMAL
: /* same as SW_NORMAL: */
747 case SW_SHOWDEFAULT
: /* FIXME: should have its own handler */
749 swp
|= SWP_SHOWWINDOW
| SWP_FRAMECHANGED
;
751 if( wndPtr
->dwStyle
& (WS_MINIMIZE
| WS_MAXIMIZE
) )
752 swp
|= WINPOS_MinMaximize( hwnd
, SW_RESTORE
, &newPos
);
753 else swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
757 showFlag
= (cmd
!= SW_HIDE
);
758 if (showFlag
!= wasVisible
)
760 SendMessageA( hwnd
, WM_SHOWWINDOW
, showFlag
, 0 );
761 if (!IsWindow( hwnd
)) goto END
;
764 /* We can't activate a child window */
765 if ((wndPtr
->dwStyle
& WS_CHILD
) &&
766 !(wndPtr
->dwExStyle
& WS_EX_MDICHILD
))
767 swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
769 SetWindowPos( hwnd
, HWND_TOP
, newPos
.left
, newPos
.top
,
770 newPos
.right
, newPos
.bottom
, LOWORD(swp
) );
773 /* FIXME: This will cause the window to be activated irrespective
774 * of whether it is owned by the same thread. Has to be done
778 if (hwnd
== GetActiveWindow())
779 WINPOS_ActivateOtherWindow(hwnd
);
781 /* Revert focus to parent */
782 if (hwnd
== GetFocus() || IsChild(hwnd
, GetFocus()))
783 SetFocus( GetParent(hwnd
) );
785 if (!IsWindow( hwnd
)) goto END
;
786 else if( wndPtr
->dwStyle
& WS_MINIMIZE
) WINPOS_ShowIconTitle( hwnd
, TRUE
);
788 if (wndPtr
->flags
& WIN_NEED_SIZE
)
790 /* should happen only in CreateWindowEx() */
791 int wParam
= SIZE_RESTORED
;
793 wndPtr
->flags
&= ~WIN_NEED_SIZE
;
794 if (wndPtr
->dwStyle
& WS_MAXIMIZE
) wParam
= SIZE_MAXIMIZED
;
795 else if (wndPtr
->dwStyle
& WS_MINIMIZE
) wParam
= SIZE_MINIMIZED
;
796 SendMessageA( hwnd
, WM_SIZE
, wParam
,
797 MAKELONG(wndPtr
->rectClient
.right
-wndPtr
->rectClient
.left
,
798 wndPtr
->rectClient
.bottom
-wndPtr
->rectClient
.top
));
799 SendMessageA( hwnd
, WM_MOVE
, 0,
800 MAKELONG(wndPtr
->rectClient
.left
, wndPtr
->rectClient
.top
) );
804 WIN_ReleaseWndPtr(wndPtr
);