4 * Copyright 1998,1999 Patrik Stridvall
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "wine/wingdi16.h"
29 #include "wine/server.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(ttydrv
);
34 #define SWP_AGG_NOGEOMETRYCHANGE \
35 (SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE)
36 #define SWP_AGG_NOPOSCHANGE \
37 (SWP_AGG_NOGEOMETRYCHANGE | SWP_NOZORDER)
38 #define SWP_AGG_STATUSFLAGS \
39 (SWP_AGG_NOPOSCHANGE | SWP_FRAMECHANGED | SWP_HIDEWINDOW | SWP_SHOWWINDOW)
41 /***********************************************************************
42 * get_server_visible_region
44 static HRGN
get_server_visible_region( HWND hwnd
, UINT flags
)
53 if (!(data
= HeapAlloc( GetProcessHeap(), 0, sizeof(*data
) + size
- 1 ))) return 0;
54 SERVER_START_REQ( get_visible_region
)
58 wine_server_set_reply( req
, data
->Buffer
, size
);
59 if (!(status
= wine_server_call( req
)))
61 size_t reply_size
= wine_server_reply_size( reply
);
62 data
->rdh
.dwSize
= sizeof(data
->rdh
);
63 data
->rdh
.iType
= RDH_RECTANGLES
;
64 data
->rdh
.nCount
= reply_size
/ sizeof(RECT
);
65 data
->rdh
.nRgnSize
= reply_size
;
66 ret
= ExtCreateRegion( NULL
, size
, data
);
68 else size
= reply
->total_size
;
71 HeapFree( GetProcessHeap(), 0, data
);
72 } while (status
== STATUS_BUFFER_OVERFLOW
);
74 if (status
) SetLastError( RtlNtStatusToDosError(status
) );
79 /***********************************************************************
82 * Set a window position and Z order.
84 static BOOL
set_window_pos( HWND hwnd
, HWND insert_after
, const RECT
*rectWindow
,
85 const RECT
*rectClient
, UINT swp_flags
)
87 WND
*win
= WIN_GetPtr( hwnd
);
90 if (!win
) return FALSE
;
91 if (win
== WND_OTHER_PROCESS
)
93 if (IsWindow( hwnd
)) ERR( "cannot set rectangles of other process window %p\n", hwnd
);
96 SERVER_START_REQ( set_window_pos
)
99 req
->previous
= insert_after
;
100 req
->flags
= swp_flags
;
101 req
->window
.left
= rectWindow
->left
;
102 req
->window
.top
= rectWindow
->top
;
103 req
->window
.right
= rectWindow
->right
;
104 req
->window
.bottom
= rectWindow
->bottom
;
105 req
->client
.left
= rectClient
->left
;
106 req
->client
.top
= rectClient
->top
;
107 req
->client
.right
= rectClient
->right
;
108 req
->client
.bottom
= rectClient
->bottom
;
109 ret
= !wine_server_call( req
);
112 if (win
== WND_DESKTOP
) return ret
;
115 win
->rectWindow
= *rectWindow
;
116 win
->rectClient
= *rectClient
;
118 TRACE( "win %p window (%ld,%ld)-(%ld,%ld) client (%ld,%ld)-(%ld,%ld)\n", hwnd
,
119 rectWindow
->left
, rectWindow
->top
, rectWindow
->right
, rectWindow
->bottom
,
120 rectClient
->left
, rectClient
->top
, rectClient
->right
, rectClient
->bottom
);
122 WIN_ReleasePtr( win
);
127 /**********************************************************************
128 * CreateDesktopWindow (TTYDRV.@)
130 BOOL
TTYDRV_CreateDesktopWindow( HWND hwnd
)
134 SetRect( &rect
, 0, 0, cell_width
* screen_cols
, cell_height
* screen_rows
);
135 set_window_pos( hwnd
, 0, &rect
, &rect
, SWP_NOZORDER
);
136 SetPropA( hwnd
, "__wine_ttydrv_window", root_window
);
140 /**********************************************************************
141 * CreateWindow (TTYDRV.@)
143 BOOL
TTYDRV_CreateWindow( HWND hwnd
, CREATESTRUCTA
*cs
, BOOL unicode
)
150 TRACE("(%p)\n", hwnd
);
152 /* initialize the dimensions before sending WM_GETMINMAXINFO */
153 SetRect( &rect
, cs
->x
, cs
->y
, cs
->x
+ cs
->cx
, cs
->y
+ cs
->cy
);
154 set_window_pos( hwnd
, 0, &rect
, &rect
, SWP_NOZORDER
);
157 /* Only create top-level windows */
158 if (GetAncestor( hwnd
, GA_PARENT
) == GetDesktopWindow())
161 const INT cellWidth
=8, cellHeight
=8; /* FIXME: Hardcoded */
163 window
= subwin( root_window
, cs
->cy
/cellHeight
, cs
->cx
/cellWidth
,
164 cs
->y
/cellHeight
, cs
->x
/cellWidth
);
167 SetPropA( hwnd
, "__wine_ttydrv_window", window
);
169 #else /* defined(WINE_CURSES) */
170 FIXME("(%p): stub\n", hwnd
);
171 #endif /* defined(WINE_CURSES) */
173 /* Call the WH_CBT hook */
175 hwndLinkAfter
= ((cs
->style
& (WS_CHILD
|WS_MAXIMIZE
)) == WS_CHILD
) ? HWND_BOTTOM
: HWND_TOP
;
178 cbtc
.hwndInsertAfter
= hwndLinkAfter
;
179 if (HOOK_CallHooks( WH_CBT
, HCBT_CREATEWND
, (WPARAM
)hwnd
, (LPARAM
)&cbtc
, unicode
))
181 TRACE("CBT-hook returned !0\n");
187 ret
= SendMessageW( hwnd
, WM_NCCREATE
, 0, (LPARAM
)cs
);
188 if (ret
) ret
= (SendMessageW( hwnd
, WM_CREATE
, 0, (LPARAM
)cs
) != -1);
192 ret
= SendMessageA( hwnd
, WM_NCCREATE
, 0, (LPARAM
)cs
);
193 if (ret
) ret
= (SendMessageA( hwnd
, WM_CREATE
, 0, (LPARAM
)cs
) != -1);
195 if (ret
) NotifyWinEvent(EVENT_OBJECT_CREATE
, hwnd
, OBJID_WINDOW
, 0);
199 /***********************************************************************
200 * DestroyWindow (TTYDRV.@)
202 BOOL
TTYDRV_DestroyWindow( HWND hwnd
)
205 WINDOW
*window
= GetPropA( hwnd
, "__wine_ttydrv_window" );
207 TRACE("(%p)\n", hwnd
);
209 if (window
&& window
!= root_window
) delwin(window
);
210 #else /* defined(WINE_CURSES) */
211 FIXME("(%p): stub\n", hwnd
);
212 #endif /* defined(WINE_CURSES) */
217 /***********************************************************************
220 * Set the drawable, origin and dimensions for the DC associated to
223 BOOL
TTYDRV_GetDC( HWND hwnd
, HDC hdc
, HRGN hrgn
, DWORD flags
)
225 struct ttydrv_escape_set_drawable escape
;
227 if(flags
& DCX_WINDOW
)
230 GetWindowRect( hwnd
, &rect
);
231 escape
.org
.x
= rect
.left
;
232 escape
.org
.y
= rect
.top
;
236 escape
.org
.x
= escape
.org
.y
= 0;
237 MapWindowPoints( hwnd
, 0, &escape
.org
, 1 );
240 escape
.code
= TTYDRV_SET_DRAWABLE
;
241 ExtEscape( hdc
, TTYDRV_ESCAPE
, sizeof(escape
), (LPSTR
)&escape
, 0, NULL
);
243 if (flags
& (DCX_EXCLUDERGN
| DCX_INTERSECTRGN
) ||
244 SetHookFlags16( HDC_16(hdc
), DCHF_VALIDATEVISRGN
)) /* DC was dirty */
246 /* need to recompute the visible region */
247 HRGN visRgn
= get_server_visible_region( hwnd
, flags
);
249 if (flags
& (DCX_EXCLUDERGN
| DCX_INTERSECTRGN
))
250 CombineRgn( visRgn
, visRgn
, hrgn
, (flags
& DCX_INTERSECTRGN
) ? RGN_AND
: RGN_DIFF
);
252 SelectVisRgn16( HDC_16(hdc
), HRGN_16(visRgn
) );
253 DeleteObject( visRgn
);
259 /* fix redundant flags and values in the WINDOWPOS structure */
260 static BOOL
fixup_flags( WINDOWPOS
*winpos
)
263 WND
*wndPtr
= WIN_GetPtr( winpos
->hwnd
);
266 if (!wndPtr
|| wndPtr
== WND_OTHER_PROCESS
)
268 SetLastError( ERROR_INVALID_WINDOW_HANDLE
);
271 winpos
->hwnd
= wndPtr
->hwndSelf
; /* make it a full handle */
273 /* Finally make sure that all coordinates are valid */
274 if (winpos
->x
< -32768) winpos
->x
= -32768;
275 else if (winpos
->x
> 32767) winpos
->x
= 32767;
276 if (winpos
->y
< -32768) winpos
->y
= -32768;
277 else if (winpos
->y
> 32767) winpos
->y
= 32767;
279 if (winpos
->cx
< 0) winpos
->cx
= 0;
280 else if (winpos
->cx
> 32767) winpos
->cx
= 32767;
281 if (winpos
->cy
< 0) winpos
->cy
= 0;
282 else if (winpos
->cy
> 32767) winpos
->cy
= 32767;
284 parent
= GetAncestor( winpos
->hwnd
, GA_PARENT
);
285 if (!IsWindowVisible( parent
)) winpos
->flags
|= SWP_NOREDRAW
;
287 if (wndPtr
->dwStyle
& WS_VISIBLE
) winpos
->flags
&= ~SWP_SHOWWINDOW
;
290 winpos
->flags
&= ~SWP_HIDEWINDOW
;
291 if (!(winpos
->flags
& SWP_SHOWWINDOW
)) winpos
->flags
|= SWP_NOREDRAW
;
294 if ((wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
== winpos
->cx
) &&
295 (wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
== winpos
->cy
))
296 winpos
->flags
|= SWP_NOSIZE
; /* Already the right size */
298 if ((wndPtr
->rectWindow
.left
== winpos
->x
) && (wndPtr
->rectWindow
.top
== winpos
->y
))
299 winpos
->flags
|= SWP_NOMOVE
; /* Already the right position */
301 if ((wndPtr
->dwStyle
& (WS_POPUP
| WS_CHILD
)) != WS_CHILD
)
303 if (!(winpos
->flags
& (SWP_NOACTIVATE
|SWP_HIDEWINDOW
))) /* Bring to the top when activating */
305 winpos
->flags
&= ~SWP_NOZORDER
;
306 winpos
->hwndInsertAfter
= HWND_TOP
;
310 /* Check hwndInsertAfter */
311 if (winpos
->flags
& SWP_NOZORDER
) goto done
;
313 /* fix sign extension */
314 if (winpos
->hwndInsertAfter
== (HWND
)0xffff) winpos
->hwndInsertAfter
= HWND_TOPMOST
;
315 else if (winpos
->hwndInsertAfter
== (HWND
)0xfffe) winpos
->hwndInsertAfter
= HWND_NOTOPMOST
;
317 /* FIXME: TOPMOST not supported yet */
318 if ((winpos
->hwndInsertAfter
== HWND_TOPMOST
) ||
319 (winpos
->hwndInsertAfter
== HWND_NOTOPMOST
)) winpos
->hwndInsertAfter
= HWND_TOP
;
321 /* hwndInsertAfter must be a sibling of the window */
322 if (winpos
->hwndInsertAfter
== HWND_TOP
)
324 if (GetWindow(winpos
->hwnd
, GW_HWNDFIRST
) == winpos
->hwnd
)
325 winpos
->flags
|= SWP_NOZORDER
;
327 else if (winpos
->hwndInsertAfter
== HWND_BOTTOM
)
329 if (GetWindow(winpos
->hwnd
, GW_HWNDLAST
) == winpos
->hwnd
)
330 winpos
->flags
|= SWP_NOZORDER
;
334 if (GetAncestor( winpos
->hwndInsertAfter
, GA_PARENT
) != parent
) ret
= FALSE
;
337 /* don't need to change the Zorder of hwnd if it's already inserted
338 * after hwndInsertAfter or when inserting hwnd after itself.
340 if ((winpos
->hwnd
== winpos
->hwndInsertAfter
) ||
341 (winpos
->hwnd
== GetWindow( winpos
->hwndInsertAfter
, GW_HWNDNEXT
)))
342 winpos
->flags
|= SWP_NOZORDER
;
346 WIN_ReleasePtr( wndPtr
);
351 /***********************************************************************
354 static UINT
SWP_DoNCCalcSize( WINDOWPOS
* pWinpos
, const RECT
* pNewWindowRect
, RECT
* pNewClientRect
)
359 if (!(wndPtr
= WIN_GetPtr( pWinpos
->hwnd
)) || wndPtr
== WND_OTHER_PROCESS
) return 0;
361 /* Send WM_NCCALCSIZE message to get new client area */
362 if( (pWinpos
->flags
& (SWP_FRAMECHANGED
| SWP_NOSIZE
)) != SWP_NOSIZE
)
364 NCCALCSIZE_PARAMS params
;
365 WINDOWPOS winposCopy
;
367 params
.rgrc
[0] = *pNewWindowRect
;
368 params
.rgrc
[1] = wndPtr
->rectWindow
;
369 params
.rgrc
[2] = wndPtr
->rectClient
;
370 params
.lppos
= &winposCopy
;
371 winposCopy
= *pWinpos
;
372 WIN_ReleasePtr( wndPtr
);
374 wvrFlags
= SendMessageW( pWinpos
->hwnd
, WM_NCCALCSIZE
, TRUE
, (LPARAM
)¶ms
);
376 *pNewClientRect
= params
.rgrc
[0];
378 if (!(wndPtr
= WIN_GetPtr( pWinpos
->hwnd
)) || wndPtr
== WND_OTHER_PROCESS
) return 0;
380 TRACE( "hwnd %p old win %s old client %s new win %s new client %s\n", pWinpos
->hwnd
,
381 wine_dbgstr_rect(&wndPtr
->rectWindow
), wine_dbgstr_rect(&wndPtr
->rectClient
),
382 wine_dbgstr_rect(pNewWindowRect
), wine_dbgstr_rect(pNewClientRect
) );
384 if( pNewClientRect
->left
!= wndPtr
->rectClient
.left
||
385 pNewClientRect
->top
!= wndPtr
->rectClient
.top
)
386 pWinpos
->flags
&= ~SWP_NOCLIENTMOVE
;
388 if( (pNewClientRect
->right
- pNewClientRect
->left
!=
389 wndPtr
->rectClient
.right
- wndPtr
->rectClient
.left
))
390 pWinpos
->flags
&= ~SWP_NOCLIENTSIZE
;
392 wvrFlags
&= ~WVR_HREDRAW
;
394 if (pNewClientRect
->bottom
- pNewClientRect
->top
!=
395 wndPtr
->rectClient
.bottom
- wndPtr
->rectClient
.top
)
396 pWinpos
->flags
&= ~SWP_NOCLIENTSIZE
;
398 wvrFlags
&= ~WVR_VREDRAW
;
402 if (!(pWinpos
->flags
& SWP_NOMOVE
) &&
403 (pNewClientRect
->left
!= wndPtr
->rectClient
.left
||
404 pNewClientRect
->top
!= wndPtr
->rectClient
.top
))
405 pWinpos
->flags
&= ~SWP_NOCLIENTMOVE
;
408 WIN_ReleasePtr( wndPtr
);
413 struct move_owned_info
419 static BOOL CALLBACK
move_owned_popups( HWND hwnd
, LPARAM lparam
)
421 struct move_owned_info
*info
= (struct move_owned_info
*)lparam
;
423 if (hwnd
== info
->owner
) return FALSE
;
424 if ((GetWindowLongW( hwnd
, GWL_STYLE
) & WS_POPUP
) &&
425 GetWindow( hwnd
, GW_OWNER
) == info
->owner
)
427 SetWindowPos( hwnd
, info
->insert_after
, 0, 0, 0, 0,
428 SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
|
429 SWP_NOSENDCHANGING
| SWP_DEFERERASE
);
430 info
->insert_after
= hwnd
;
435 /***********************************************************************
438 * fix Z order taking into account owned popups -
439 * basically we need to maintain them above the window that owns them
441 * FIXME: hide/show owned popups when owner visibility changes.
443 static HWND
SWP_DoOwnedPopups(HWND hwnd
, HWND hwndInsertAfter
)
445 HWND owner
= GetWindow( hwnd
, GW_OWNER
);
446 LONG style
= GetWindowLongW( hwnd
, GWL_STYLE
);
447 struct move_owned_info info
;
449 TRACE("(%p) hInsertAfter = %p\n", hwnd
, hwndInsertAfter
);
451 if ((style
& WS_POPUP
) && owner
)
453 /* make sure this popup stays above the owner */
455 if( hwndInsertAfter
!= HWND_TOP
)
457 HWND hwndLocalPrev
= HWND_TOP
;
458 HWND prev
= GetWindow( owner
, GW_HWNDPREV
);
460 while (prev
&& prev
!= hwndInsertAfter
)
462 if (hwndLocalPrev
== HWND_TOP
&& GetWindowLongW( prev
, GWL_STYLE
) & WS_VISIBLE
)
463 hwndLocalPrev
= prev
;
464 prev
= GetWindow( prev
, GW_HWNDPREV
);
466 if (!prev
) hwndInsertAfter
= hwndLocalPrev
;
469 else if (style
& WS_CHILD
) return hwndInsertAfter
;
472 info
.insert_after
= hwndInsertAfter
;
473 EnumWindows( move_owned_popups
, (LPARAM
)&info
);
474 return info
.insert_after
;
478 /***********************************************************************
479 * SWP_DoWinPosChanging
481 static BOOL
SWP_DoWinPosChanging( WINDOWPOS
* pWinpos
, RECT
* pNewWindowRect
, RECT
* pNewClientRect
)
485 /* Send WM_WINDOWPOSCHANGING message */
487 if (!(pWinpos
->flags
& SWP_NOSENDCHANGING
))
488 SendMessageW( pWinpos
->hwnd
, WM_WINDOWPOSCHANGING
, 0, (LPARAM
)pWinpos
);
490 if (!(wndPtr
= WIN_GetPtr( pWinpos
->hwnd
)) || wndPtr
== WND_OTHER_PROCESS
) return FALSE
;
492 /* Calculate new position and size */
494 *pNewWindowRect
= wndPtr
->rectWindow
;
495 *pNewClientRect
= (wndPtr
->dwStyle
& WS_MINIMIZE
) ? wndPtr
->rectWindow
496 : wndPtr
->rectClient
;
498 if (!(pWinpos
->flags
& SWP_NOSIZE
))
500 pNewWindowRect
->right
= pNewWindowRect
->left
+ pWinpos
->cx
;
501 pNewWindowRect
->bottom
= pNewWindowRect
->top
+ pWinpos
->cy
;
503 if (!(pWinpos
->flags
& SWP_NOMOVE
))
505 pNewWindowRect
->left
= pWinpos
->x
;
506 pNewWindowRect
->top
= pWinpos
->y
;
507 pNewWindowRect
->right
+= pWinpos
->x
- wndPtr
->rectWindow
.left
;
508 pNewWindowRect
->bottom
+= pWinpos
->y
- wndPtr
->rectWindow
.top
;
510 OffsetRect( pNewClientRect
, pWinpos
->x
- wndPtr
->rectWindow
.left
,
511 pWinpos
->y
- wndPtr
->rectWindow
.top
);
513 pWinpos
->flags
|= SWP_NOCLIENTMOVE
| SWP_NOCLIENTSIZE
;
515 TRACE( "hwnd %p, after %p, swp %d,%d %dx%d flags %08x\n",
516 pWinpos
->hwnd
, pWinpos
->hwndInsertAfter
, pWinpos
->x
, pWinpos
->y
,
517 pWinpos
->cx
, pWinpos
->cy
, pWinpos
->flags
);
518 TRACE( "current %s style %08lx new %s\n",
519 wine_dbgstr_rect( &wndPtr
->rectWindow
), wndPtr
->dwStyle
,
520 wine_dbgstr_rect( pNewWindowRect
));
522 WIN_ReleasePtr( wndPtr
);
527 /***********************************************************************
528 * SetWindowPos (TTYDRV.@)
530 BOOL
TTYDRV_SetWindowPos( WINDOWPOS
*winpos
)
532 RECT newWindowRect
, newClientRect
;
535 TRACE( "hwnd %p, after %p, swp %d,%d %dx%d flags %08x\n",
536 winpos
->hwnd
, winpos
->hwndInsertAfter
, winpos
->x
, winpos
->y
,
537 winpos
->cx
, winpos
->cy
, winpos
->flags
);
539 orig_flags
= winpos
->flags
;
540 winpos
->flags
&= ~SWP_WINE_NOHOSTMOVE
;
542 /* Check window handle */
543 if (winpos
->hwnd
== GetDesktopWindow()) return FALSE
;
545 /* First make sure that coordinates are valid for WM_WINDOWPOSCHANGING */
546 if (!(winpos
->flags
& SWP_NOMOVE
))
548 if (winpos
->x
< -32768) winpos
->x
= -32768;
549 else if (winpos
->x
> 32767) winpos
->x
= 32767;
550 if (winpos
->y
< -32768) winpos
->y
= -32768;
551 else if (winpos
->y
> 32767) winpos
->y
= 32767;
553 if (!(winpos
->flags
& SWP_NOSIZE
))
555 if (winpos
->cx
< 0) winpos
->cx
= 0;
556 else if (winpos
->cx
> 32767) winpos
->cx
= 32767;
557 if (winpos
->cy
< 0) winpos
->cy
= 0;
558 else if (winpos
->cy
> 32767) winpos
->cy
= 32767;
561 if (!SWP_DoWinPosChanging( winpos
, &newWindowRect
, &newClientRect
)) return FALSE
;
563 /* Fix redundant flags */
564 if (!fixup_flags( winpos
)) return FALSE
;
566 if((winpos
->flags
& (SWP_NOZORDER
| SWP_HIDEWINDOW
| SWP_SHOWWINDOW
)) != SWP_NOZORDER
)
568 if (GetAncestor( winpos
->hwnd
, GA_PARENT
) == GetDesktopWindow())
569 winpos
->hwndInsertAfter
= SWP_DoOwnedPopups( winpos
->hwnd
, winpos
->hwndInsertAfter
);
572 /* Common operations */
574 SWP_DoNCCalcSize( winpos
, &newWindowRect
, &newClientRect
);
576 if (!set_window_pos( winpos
->hwnd
, winpos
->hwndInsertAfter
,
577 &newWindowRect
, &newClientRect
, orig_flags
))
580 if( winpos
->flags
& SWP_HIDEWINDOW
)
581 HideCaret(winpos
->hwnd
);
582 else if (winpos
->flags
& SWP_SHOWWINDOW
)
583 ShowCaret(winpos
->hwnd
);
585 if (!(winpos
->flags
& (SWP_NOACTIVATE
|SWP_HIDEWINDOW
)))
587 /* child windows get WM_CHILDACTIVATE message */
588 if ((GetWindowLongW( winpos
->hwnd
, GWL_STYLE
) & (WS_CHILD
| WS_POPUP
)) == WS_CHILD
)
589 SendMessageA( winpos
->hwnd
, WM_CHILDACTIVATE
, 0, 0 );
591 SetForegroundWindow( winpos
->hwnd
);
594 /* And last, send the WM_WINDOWPOSCHANGED message */
596 TRACE("\tstatus flags = %04x\n", winpos
->flags
& SWP_AGG_STATUSFLAGS
);
598 if (((winpos
->flags
& SWP_AGG_STATUSFLAGS
) != SWP_AGG_NOPOSCHANGE
))
600 /* WM_WINDOWPOSCHANGED is sent even if SWP_NOSENDCHANGING is set
601 and always contains final window position.
603 winpos
->x
= newWindowRect
.left
;
604 winpos
->y
= newWindowRect
.top
;
605 winpos
->cx
= newWindowRect
.right
- newWindowRect
.left
;
606 winpos
->cy
= newWindowRect
.bottom
- newWindowRect
.top
;
607 SendMessageW( winpos
->hwnd
, WM_WINDOWPOSCHANGED
, 0, (LPARAM
)winpos
);
614 /***********************************************************************
615 * WINPOS_MinMaximize (internal)
617 *Lifted from x11 driver
619 static UINT
WINPOS_MinMaximize( HWND hwnd
, UINT cmd
, LPRECT rect
)
624 TRACE("%p %u\n", hwnd
, cmd
);
625 FIXME("(%p): stub\n", hwnd
);
627 wpl
.length
= sizeof(wpl
);
628 GetWindowPlacement( hwnd
, &wpl
);
630 /* If I glark this right, yields an immutable window*/
631 swpFlags
= SWP_NOSIZE
| SWP_NOMOVE
;
633 /*cmd handling goes here. see dlls/x1drv/winpos.c*/
638 /***********************************************************************
639 * ShowWindow (TTYDRV.@)
641 *Lifted from x11 driver
642 *Sets the specified windows' show state.
644 BOOL
TTYDRV_ShowWindow( HWND hwnd
, INT cmd
)
647 LONG style
= GetWindowLongW( hwnd
, GWL_STYLE
);
648 BOOL wasVisible
= (style
& WS_VISIBLE
) != 0;
649 BOOL showFlag
= TRUE
;
650 RECT newPos
= {0, 0, 0, 0};
654 TRACE("hwnd=%p, cmd=%d, wasVisible %d\n", hwnd
, cmd
, wasVisible
);
659 if (!wasVisible
) return FALSE
;
661 swp
|= SWP_HIDEWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOZORDER
;
664 case SW_SHOWMINNOACTIVE
:
665 swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
667 case SW_SHOWMINIMIZED
:
668 case SW_FORCEMINIMIZE
: /* FIXME: Does not work if thread is hung. */
669 swp
|= SWP_SHOWWINDOW
;
672 swp
|= SWP_FRAMECHANGED
;
673 if( !(style
& WS_MINIMIZE
) )
674 swp
|= WINPOS_MinMaximize( hwnd
, SW_MINIMIZE
, &newPos
);
675 else swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
678 case SW_SHOWMAXIMIZED
: /* same as SW_MAXIMIZE */
679 swp
|= SWP_SHOWWINDOW
| SWP_FRAMECHANGED
;
680 if( !(style
& WS_MAXIMIZE
) )
681 swp
|= WINPOS_MinMaximize( hwnd
, SW_MAXIMIZE
, &newPos
);
682 else swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
686 swp
|= SWP_NOACTIVATE
| SWP_SHOWWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
687 if (style
& WS_CHILD
) swp
|= SWP_NOZORDER
;
690 if (wasVisible
) return TRUE
;
691 swp
|= SWP_SHOWWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
695 swp
|= SWP_FRAMECHANGED
;
697 case SW_SHOWNOACTIVATE
:
698 swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
700 case SW_SHOWNORMAL
: /* same as SW_NORMAL: */
701 case SW_SHOWDEFAULT
: /* FIXME: should have its own handler */
702 swp
|= SWP_SHOWWINDOW
;
704 if (style
& (WS_MINIMIZE
| WS_MAXIMIZE
))
705 swp
|= WINPOS_MinMaximize( hwnd
, SW_RESTORE
, &newPos
);
706 else swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
710 if (showFlag
!= wasVisible
|| cmd
== SW_SHOWNA
)
712 SendMessageW( hwnd
, WM_SHOWWINDOW
, showFlag
, 0 );
713 if (!IsWindow( hwnd
)) return wasVisible
;
716 /* ShowWindow won't activate a not being maximized child window */
717 if ((style
& WS_CHILD
) && cmd
!= SW_MAXIMIZE
)
718 swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
720 SetWindowPos( hwnd
, HWND_TOP
, newPos
.left
, newPos
.top
,
721 newPos
.right
, newPos
.bottom
, LOWORD(swp
) );
726 /* FIXME: This will cause the window to be activated irrespective
727 * of whether it is owned by the same thread. Has to be done
731 if (hwnd
== GetActiveWindow())
732 WINPOS_ActivateOtherWindow(hwnd
);
734 /* Revert focus to parent */
736 if (hwnd
== hFocus
|| IsChild(hwnd
, hFocus
))
738 HWND parent
= GetAncestor(hwnd
, GA_PARENT
);
739 if (parent
== GetDesktopWindow()) parent
= 0;
744 if (IsIconic(hwnd
)) WINPOS_ShowIconTitle( hwnd
, TRUE
);
746 if (!(wndPtr
= WIN_GetPtr( hwnd
)) || wndPtr
== WND_OTHER_PROCESS
) return wasVisible
;
748 if (wndPtr
->flags
& WIN_NEED_SIZE
)
750 /* should happen only in CreateWindowEx() */
751 int wParam
= SIZE_RESTORED
;
752 RECT client
= wndPtr
->rectClient
;
754 wndPtr
->flags
&= ~WIN_NEED_SIZE
;
755 if (wndPtr
->dwStyle
& WS_MAXIMIZE
) wParam
= SIZE_MAXIMIZED
;
756 else if (wndPtr
->dwStyle
& WS_MINIMIZE
) wParam
= SIZE_MINIMIZED
;
757 WIN_ReleasePtr( wndPtr
);
759 SendMessageW( hwnd
, WM_SIZE
, wParam
,
760 MAKELONG( client
.right
- client
.left
, client
.bottom
- client
.top
));
761 SendMessageW( hwnd
, WM_MOVE
, 0, MAKELONG( client
.left
, client
.top
));
763 else WIN_ReleasePtr( wndPtr
);