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 * CreateWindow (TTYDRV.@)
130 BOOL
TTYDRV_CreateWindow( HWND hwnd
, CREATESTRUCTA
*cs
, BOOL unicode
)
134 HWND parent
, hwndLinkAfter
;
137 TRACE("(%p)\n", hwnd
);
139 /* initialize the dimensions before sending WM_GETMINMAXINFO */
140 SetRect( &rect
, cs
->x
, cs
->y
, cs
->x
+ cs
->cx
, cs
->y
+ cs
->cy
);
141 set_window_pos( hwnd
, 0, &rect
, &rect
, SWP_NOZORDER
);
143 parent
= GetAncestor( hwnd
, GA_PARENT
);
144 if (!parent
) /* desktop window */
146 SetPropA( hwnd
, "__wine_ttydrv_window", root_window
);
151 /* Only create top-level windows */
152 if (parent
== GetDesktopWindow())
155 const INT cellWidth
=8, cellHeight
=8; /* FIXME: Hardcoded */
157 window
= subwin( root_window
, cs
->cy
/cellHeight
, cs
->cx
/cellWidth
,
158 cs
->y
/cellHeight
, cs
->x
/cellWidth
);
161 SetPropA( hwnd
, "__wine_ttydrv_window", window
);
163 #else /* defined(WINE_CURSES) */
164 FIXME("(%p): stub\n", hwnd
);
165 #endif /* defined(WINE_CURSES) */
167 /* Call the WH_CBT hook */
169 hwndLinkAfter
= ((cs
->style
& (WS_CHILD
|WS_MAXIMIZE
)) == WS_CHILD
) ? HWND_BOTTOM
: HWND_TOP
;
172 cbtc
.hwndInsertAfter
= hwndLinkAfter
;
173 if (HOOK_CallHooks( WH_CBT
, HCBT_CREATEWND
, (WPARAM
)hwnd
, (LPARAM
)&cbtc
, unicode
))
175 TRACE("CBT-hook returned !0\n");
181 ret
= SendMessageW( hwnd
, WM_NCCREATE
, 0, (LPARAM
)cs
);
182 if (ret
) ret
= (SendMessageW( hwnd
, WM_CREATE
, 0, (LPARAM
)cs
) != -1);
186 ret
= SendMessageA( hwnd
, WM_NCCREATE
, 0, (LPARAM
)cs
);
187 if (ret
) ret
= (SendMessageA( hwnd
, WM_CREATE
, 0, (LPARAM
)cs
) != -1);
189 if (ret
) NotifyWinEvent(EVENT_OBJECT_CREATE
, hwnd
, OBJID_WINDOW
, 0);
193 /***********************************************************************
194 * DestroyWindow (TTYDRV.@)
196 BOOL
TTYDRV_DestroyWindow( HWND hwnd
)
199 WINDOW
*window
= GetPropA( hwnd
, "__wine_ttydrv_window" );
201 TRACE("(%p)\n", hwnd
);
203 if (window
&& window
!= root_window
) delwin(window
);
204 #else /* defined(WINE_CURSES) */
205 FIXME("(%p): stub\n", hwnd
);
206 #endif /* defined(WINE_CURSES) */
211 /***********************************************************************
214 * Set the drawable, origin and dimensions for the DC associated to
217 BOOL
TTYDRV_GetDC( HWND hwnd
, HDC hdc
, HRGN hrgn
, DWORD flags
)
219 struct ttydrv_escape_set_drawable escape
;
221 if(flags
& DCX_WINDOW
)
224 GetWindowRect( hwnd
, &rect
);
225 escape
.org
.x
= rect
.left
;
226 escape
.org
.y
= rect
.top
;
230 escape
.org
.x
= escape
.org
.y
= 0;
231 MapWindowPoints( hwnd
, 0, &escape
.org
, 1 );
234 escape
.code
= TTYDRV_SET_DRAWABLE
;
235 ExtEscape( hdc
, TTYDRV_ESCAPE
, sizeof(escape
), (LPSTR
)&escape
, 0, NULL
);
237 if (flags
& (DCX_EXCLUDERGN
| DCX_INTERSECTRGN
) ||
238 SetHookFlags16( HDC_16(hdc
), DCHF_VALIDATEVISRGN
)) /* DC was dirty */
240 /* need to recompute the visible region */
241 HRGN visRgn
= get_server_visible_region( hwnd
, flags
);
243 if (flags
& (DCX_EXCLUDERGN
| DCX_INTERSECTRGN
))
244 CombineRgn( visRgn
, visRgn
, hrgn
, (flags
& DCX_INTERSECTRGN
) ? RGN_AND
: RGN_DIFF
);
246 SelectVisRgn16( HDC_16(hdc
), HRGN_16(visRgn
) );
247 DeleteObject( visRgn
);
253 /* fix redundant flags and values in the WINDOWPOS structure */
254 static BOOL
fixup_flags( WINDOWPOS
*winpos
)
257 WND
*wndPtr
= WIN_GetPtr( winpos
->hwnd
);
260 if (!wndPtr
|| wndPtr
== WND_OTHER_PROCESS
)
262 SetLastError( ERROR_INVALID_WINDOW_HANDLE
);
265 winpos
->hwnd
= wndPtr
->hwndSelf
; /* make it a full handle */
267 /* Finally make sure that all coordinates are valid */
268 if (winpos
->x
< -32768) winpos
->x
= -32768;
269 else if (winpos
->x
> 32767) winpos
->x
= 32767;
270 if (winpos
->y
< -32768) winpos
->y
= -32768;
271 else if (winpos
->y
> 32767) winpos
->y
= 32767;
273 if (winpos
->cx
< 0) winpos
->cx
= 0;
274 else if (winpos
->cx
> 32767) winpos
->cx
= 32767;
275 if (winpos
->cy
< 0) winpos
->cy
= 0;
276 else if (winpos
->cy
> 32767) winpos
->cy
= 32767;
278 parent
= GetAncestor( winpos
->hwnd
, GA_PARENT
);
279 if (!IsWindowVisible( parent
)) winpos
->flags
|= SWP_NOREDRAW
;
281 if (wndPtr
->dwStyle
& WS_VISIBLE
) winpos
->flags
&= ~SWP_SHOWWINDOW
;
284 winpos
->flags
&= ~SWP_HIDEWINDOW
;
285 if (!(winpos
->flags
& SWP_SHOWWINDOW
)) winpos
->flags
|= SWP_NOREDRAW
;
288 if ((wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
== winpos
->cx
) &&
289 (wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
== winpos
->cy
))
290 winpos
->flags
|= SWP_NOSIZE
; /* Already the right size */
292 if ((wndPtr
->rectWindow
.left
== winpos
->x
) && (wndPtr
->rectWindow
.top
== winpos
->y
))
293 winpos
->flags
|= SWP_NOMOVE
; /* Already the right position */
295 if ((wndPtr
->dwStyle
& (WS_POPUP
| WS_CHILD
)) != WS_CHILD
)
297 if (!(winpos
->flags
& (SWP_NOACTIVATE
|SWP_HIDEWINDOW
))) /* Bring to the top when activating */
299 winpos
->flags
&= ~SWP_NOZORDER
;
300 winpos
->hwndInsertAfter
= HWND_TOP
;
304 /* Check hwndInsertAfter */
305 if (winpos
->flags
& SWP_NOZORDER
) goto done
;
307 /* fix sign extension */
308 if (winpos
->hwndInsertAfter
== (HWND
)0xffff) winpos
->hwndInsertAfter
= HWND_TOPMOST
;
309 else if (winpos
->hwndInsertAfter
== (HWND
)0xfffe) winpos
->hwndInsertAfter
= HWND_NOTOPMOST
;
311 /* FIXME: TOPMOST not supported yet */
312 if ((winpos
->hwndInsertAfter
== HWND_TOPMOST
) ||
313 (winpos
->hwndInsertAfter
== HWND_NOTOPMOST
)) winpos
->hwndInsertAfter
= HWND_TOP
;
315 /* hwndInsertAfter must be a sibling of the window */
316 if (winpos
->hwndInsertAfter
== HWND_TOP
)
318 if (GetWindow(winpos
->hwnd
, GW_HWNDFIRST
) == winpos
->hwnd
)
319 winpos
->flags
|= SWP_NOZORDER
;
321 else if (winpos
->hwndInsertAfter
== HWND_BOTTOM
)
323 if (GetWindow(winpos
->hwnd
, GW_HWNDLAST
) == winpos
->hwnd
)
324 winpos
->flags
|= SWP_NOZORDER
;
328 if (GetAncestor( winpos
->hwndInsertAfter
, GA_PARENT
) != parent
) ret
= FALSE
;
331 /* don't need to change the Zorder of hwnd if it's already inserted
332 * after hwndInsertAfter or when inserting hwnd after itself.
334 if ((winpos
->hwnd
== winpos
->hwndInsertAfter
) ||
335 (winpos
->hwnd
== GetWindow( winpos
->hwndInsertAfter
, GW_HWNDNEXT
)))
336 winpos
->flags
|= SWP_NOZORDER
;
340 WIN_ReleasePtr( wndPtr
);
345 /***********************************************************************
348 static UINT
SWP_DoNCCalcSize( WINDOWPOS
* pWinpos
, const RECT
* pNewWindowRect
, RECT
* pNewClientRect
)
353 if (!(wndPtr
= WIN_GetPtr( pWinpos
->hwnd
)) || wndPtr
== WND_OTHER_PROCESS
) return 0;
355 /* Send WM_NCCALCSIZE message to get new client area */
356 if( (pWinpos
->flags
& (SWP_FRAMECHANGED
| SWP_NOSIZE
)) != SWP_NOSIZE
)
358 NCCALCSIZE_PARAMS params
;
359 WINDOWPOS winposCopy
;
361 params
.rgrc
[0] = *pNewWindowRect
;
362 params
.rgrc
[1] = wndPtr
->rectWindow
;
363 params
.rgrc
[2] = wndPtr
->rectClient
;
364 params
.lppos
= &winposCopy
;
365 winposCopy
= *pWinpos
;
366 WIN_ReleasePtr( wndPtr
);
368 wvrFlags
= SendMessageW( pWinpos
->hwnd
, WM_NCCALCSIZE
, TRUE
, (LPARAM
)¶ms
);
370 *pNewClientRect
= params
.rgrc
[0];
372 if (!(wndPtr
= WIN_GetPtr( pWinpos
->hwnd
)) || wndPtr
== WND_OTHER_PROCESS
) return 0;
374 TRACE( "hwnd %p old win %s old client %s new win %s new client %s\n", pWinpos
->hwnd
,
375 wine_dbgstr_rect(&wndPtr
->rectWindow
), wine_dbgstr_rect(&wndPtr
->rectClient
),
376 wine_dbgstr_rect(pNewWindowRect
), wine_dbgstr_rect(pNewClientRect
) );
378 if( pNewClientRect
->left
!= wndPtr
->rectClient
.left
||
379 pNewClientRect
->top
!= wndPtr
->rectClient
.top
)
380 pWinpos
->flags
&= ~SWP_NOCLIENTMOVE
;
382 if( (pNewClientRect
->right
- pNewClientRect
->left
!=
383 wndPtr
->rectClient
.right
- wndPtr
->rectClient
.left
))
384 pWinpos
->flags
&= ~SWP_NOCLIENTSIZE
;
386 wvrFlags
&= ~WVR_HREDRAW
;
388 if (pNewClientRect
->bottom
- pNewClientRect
->top
!=
389 wndPtr
->rectClient
.bottom
- wndPtr
->rectClient
.top
)
390 pWinpos
->flags
&= ~SWP_NOCLIENTSIZE
;
392 wvrFlags
&= ~WVR_VREDRAW
;
396 if (!(pWinpos
->flags
& SWP_NOMOVE
) &&
397 (pNewClientRect
->left
!= wndPtr
->rectClient
.left
||
398 pNewClientRect
->top
!= wndPtr
->rectClient
.top
))
399 pWinpos
->flags
&= ~SWP_NOCLIENTMOVE
;
402 WIN_ReleasePtr( wndPtr
);
407 struct move_owned_info
413 static BOOL CALLBACK
move_owned_popups( HWND hwnd
, LPARAM lparam
)
415 struct move_owned_info
*info
= (struct move_owned_info
*)lparam
;
417 if (hwnd
== info
->owner
) return FALSE
;
418 if ((GetWindowLongW( hwnd
, GWL_STYLE
) & WS_POPUP
) &&
419 GetWindow( hwnd
, GW_OWNER
) == info
->owner
)
421 SetWindowPos( hwnd
, info
->insert_after
, 0, 0, 0, 0,
422 SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
|
423 SWP_NOSENDCHANGING
| SWP_DEFERERASE
);
424 info
->insert_after
= hwnd
;
429 /***********************************************************************
432 * fix Z order taking into account owned popups -
433 * basically we need to maintain them above the window that owns them
435 * FIXME: hide/show owned popups when owner visibility changes.
437 static HWND
SWP_DoOwnedPopups(HWND hwnd
, HWND hwndInsertAfter
)
439 HWND owner
= GetWindow( hwnd
, GW_OWNER
);
440 LONG style
= GetWindowLongW( hwnd
, GWL_STYLE
);
441 struct move_owned_info info
;
443 TRACE("(%p) hInsertAfter = %p\n", hwnd
, hwndInsertAfter
);
445 if ((style
& WS_POPUP
) && owner
)
447 /* make sure this popup stays above the owner */
449 if( hwndInsertAfter
!= HWND_TOP
)
451 HWND hwndLocalPrev
= HWND_TOP
;
452 HWND prev
= GetWindow( owner
, GW_HWNDPREV
);
454 while (prev
&& prev
!= hwndInsertAfter
)
456 if (hwndLocalPrev
== HWND_TOP
&& GetWindowLongW( prev
, GWL_STYLE
) & WS_VISIBLE
)
457 hwndLocalPrev
= prev
;
458 prev
= GetWindow( prev
, GW_HWNDPREV
);
460 if (!prev
) hwndInsertAfter
= hwndLocalPrev
;
463 else if (style
& WS_CHILD
) return hwndInsertAfter
;
466 info
.insert_after
= hwndInsertAfter
;
467 EnumWindows( move_owned_popups
, (LPARAM
)&info
);
468 return info
.insert_after
;
472 /***********************************************************************
473 * SWP_DoWinPosChanging
475 static BOOL
SWP_DoWinPosChanging( WINDOWPOS
* pWinpos
, RECT
* pNewWindowRect
, RECT
* pNewClientRect
)
479 /* Send WM_WINDOWPOSCHANGING message */
481 if (!(pWinpos
->flags
& SWP_NOSENDCHANGING
))
482 SendMessageW( pWinpos
->hwnd
, WM_WINDOWPOSCHANGING
, 0, (LPARAM
)pWinpos
);
484 if (!(wndPtr
= WIN_GetPtr( pWinpos
->hwnd
)) || wndPtr
== WND_OTHER_PROCESS
) return FALSE
;
486 /* Calculate new position and size */
488 *pNewWindowRect
= wndPtr
->rectWindow
;
489 *pNewClientRect
= (wndPtr
->dwStyle
& WS_MINIMIZE
) ? wndPtr
->rectWindow
490 : wndPtr
->rectClient
;
492 if (!(pWinpos
->flags
& SWP_NOSIZE
))
494 pNewWindowRect
->right
= pNewWindowRect
->left
+ pWinpos
->cx
;
495 pNewWindowRect
->bottom
= pNewWindowRect
->top
+ pWinpos
->cy
;
497 if (!(pWinpos
->flags
& SWP_NOMOVE
))
499 pNewWindowRect
->left
= pWinpos
->x
;
500 pNewWindowRect
->top
= pWinpos
->y
;
501 pNewWindowRect
->right
+= pWinpos
->x
- wndPtr
->rectWindow
.left
;
502 pNewWindowRect
->bottom
+= pWinpos
->y
- wndPtr
->rectWindow
.top
;
504 OffsetRect( pNewClientRect
, pWinpos
->x
- wndPtr
->rectWindow
.left
,
505 pWinpos
->y
- wndPtr
->rectWindow
.top
);
507 pWinpos
->flags
|= SWP_NOCLIENTMOVE
| SWP_NOCLIENTSIZE
;
509 TRACE( "hwnd %p, after %p, swp %d,%d %dx%d flags %08x\n",
510 pWinpos
->hwnd
, pWinpos
->hwndInsertAfter
, pWinpos
->x
, pWinpos
->y
,
511 pWinpos
->cx
, pWinpos
->cy
, pWinpos
->flags
);
512 TRACE( "current %s style %08lx new %s\n",
513 wine_dbgstr_rect( &wndPtr
->rectWindow
), wndPtr
->dwStyle
,
514 wine_dbgstr_rect( pNewWindowRect
));
516 WIN_ReleasePtr( wndPtr
);
521 /***********************************************************************
522 * SetWindowPos (TTYDRV.@)
524 BOOL
TTYDRV_SetWindowPos( WINDOWPOS
*winpos
)
526 RECT newWindowRect
, newClientRect
;
529 TRACE( "hwnd %p, after %p, swp %d,%d %dx%d flags %08x\n",
530 winpos
->hwnd
, winpos
->hwndInsertAfter
, winpos
->x
, winpos
->y
,
531 winpos
->cx
, winpos
->cy
, winpos
->flags
);
533 orig_flags
= winpos
->flags
;
534 winpos
->flags
&= ~SWP_WINE_NOHOSTMOVE
;
536 /* Check window handle */
537 if (winpos
->hwnd
== GetDesktopWindow()) return FALSE
;
539 /* First make sure that coordinates are valid for WM_WINDOWPOSCHANGING */
540 if (!(winpos
->flags
& SWP_NOMOVE
))
542 if (winpos
->x
< -32768) winpos
->x
= -32768;
543 else if (winpos
->x
> 32767) winpos
->x
= 32767;
544 if (winpos
->y
< -32768) winpos
->y
= -32768;
545 else if (winpos
->y
> 32767) winpos
->y
= 32767;
547 if (!(winpos
->flags
& SWP_NOSIZE
))
549 if (winpos
->cx
< 0) winpos
->cx
= 0;
550 else if (winpos
->cx
> 32767) winpos
->cx
= 32767;
551 if (winpos
->cy
< 0) winpos
->cy
= 0;
552 else if (winpos
->cy
> 32767) winpos
->cy
= 32767;
555 if (!SWP_DoWinPosChanging( winpos
, &newWindowRect
, &newClientRect
)) return FALSE
;
557 /* Fix redundant flags */
558 if (!fixup_flags( winpos
)) return FALSE
;
560 if((winpos
->flags
& (SWP_NOZORDER
| SWP_HIDEWINDOW
| SWP_SHOWWINDOW
)) != SWP_NOZORDER
)
562 if (GetAncestor( winpos
->hwnd
, GA_PARENT
) == GetDesktopWindow())
563 winpos
->hwndInsertAfter
= SWP_DoOwnedPopups( winpos
->hwnd
, winpos
->hwndInsertAfter
);
566 /* Common operations */
568 SWP_DoNCCalcSize( winpos
, &newWindowRect
, &newClientRect
);
570 if (!set_window_pos( winpos
->hwnd
, winpos
->hwndInsertAfter
,
571 &newWindowRect
, &newClientRect
, orig_flags
))
574 if( winpos
->flags
& SWP_HIDEWINDOW
)
575 HideCaret(winpos
->hwnd
);
576 else if (winpos
->flags
& SWP_SHOWWINDOW
)
577 ShowCaret(winpos
->hwnd
);
579 if (!(winpos
->flags
& (SWP_NOACTIVATE
|SWP_HIDEWINDOW
)))
581 /* child windows get WM_CHILDACTIVATE message */
582 if ((GetWindowLongW( winpos
->hwnd
, GWL_STYLE
) & (WS_CHILD
| WS_POPUP
)) == WS_CHILD
)
583 SendMessageA( winpos
->hwnd
, WM_CHILDACTIVATE
, 0, 0 );
585 SetForegroundWindow( winpos
->hwnd
);
588 /* And last, send the WM_WINDOWPOSCHANGED message */
590 TRACE("\tstatus flags = %04x\n", winpos
->flags
& SWP_AGG_STATUSFLAGS
);
592 if (((winpos
->flags
& SWP_AGG_STATUSFLAGS
) != SWP_AGG_NOPOSCHANGE
))
594 /* WM_WINDOWPOSCHANGED is sent even if SWP_NOSENDCHANGING is set
595 and always contains final window position.
597 winpos
->x
= newWindowRect
.left
;
598 winpos
->y
= newWindowRect
.top
;
599 winpos
->cx
= newWindowRect
.right
- newWindowRect
.left
;
600 winpos
->cy
= newWindowRect
.bottom
- newWindowRect
.top
;
601 SendMessageW( winpos
->hwnd
, WM_WINDOWPOSCHANGED
, 0, (LPARAM
)winpos
);
608 /***********************************************************************
609 * WINPOS_MinMaximize (internal)
611 *Lifted from x11 driver
613 static UINT
WINPOS_MinMaximize( HWND hwnd
, UINT cmd
, LPRECT rect
)
618 TRACE("%p %u\n", hwnd
, cmd
);
619 FIXME("(%p): stub\n", hwnd
);
621 wpl
.length
= sizeof(wpl
);
622 GetWindowPlacement( hwnd
, &wpl
);
624 /* If I glark this right, yields an immutable window*/
625 swpFlags
= SWP_NOSIZE
| SWP_NOMOVE
;
627 /*cmd handling goes here. see dlls/x1drv/winpos.c*/
632 /***********************************************************************
633 * ShowWindow (TTYDRV.@)
635 *Lifted from x11 driver
636 *Sets the specified windows' show state.
638 BOOL
TTYDRV_ShowWindow( HWND hwnd
, INT cmd
)
641 LONG style
= GetWindowLongW( hwnd
, GWL_STYLE
);
642 BOOL wasVisible
= (style
& WS_VISIBLE
) != 0;
643 BOOL showFlag
= TRUE
;
644 RECT newPos
= {0, 0, 0, 0};
648 TRACE("hwnd=%p, cmd=%d, wasVisible %d\n", hwnd
, cmd
, wasVisible
);
653 if (!wasVisible
) return FALSE
;
655 swp
|= SWP_HIDEWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOZORDER
;
658 case SW_SHOWMINNOACTIVE
:
659 swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
661 case SW_SHOWMINIMIZED
:
662 case SW_FORCEMINIMIZE
: /* FIXME: Does not work if thread is hung. */
663 swp
|= SWP_SHOWWINDOW
;
666 swp
|= SWP_FRAMECHANGED
;
667 if( !(style
& WS_MINIMIZE
) )
668 swp
|= WINPOS_MinMaximize( hwnd
, SW_MINIMIZE
, &newPos
);
669 else swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
672 case SW_SHOWMAXIMIZED
: /* same as SW_MAXIMIZE */
673 swp
|= SWP_SHOWWINDOW
| SWP_FRAMECHANGED
;
674 if( !(style
& WS_MAXIMIZE
) )
675 swp
|= WINPOS_MinMaximize( hwnd
, SW_MAXIMIZE
, &newPos
);
676 else swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
680 swp
|= SWP_NOACTIVATE
| SWP_SHOWWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
681 if (style
& WS_CHILD
) swp
|= SWP_NOZORDER
;
684 if (wasVisible
) return TRUE
;
685 swp
|= SWP_SHOWWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
689 swp
|= SWP_FRAMECHANGED
;
691 case SW_SHOWNOACTIVATE
:
692 swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
694 case SW_SHOWNORMAL
: /* same as SW_NORMAL: */
695 case SW_SHOWDEFAULT
: /* FIXME: should have its own handler */
696 swp
|= SWP_SHOWWINDOW
;
698 if (style
& (WS_MINIMIZE
| WS_MAXIMIZE
))
699 swp
|= WINPOS_MinMaximize( hwnd
, SW_RESTORE
, &newPos
);
700 else swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
704 if (showFlag
!= wasVisible
|| cmd
== SW_SHOWNA
)
706 SendMessageW( hwnd
, WM_SHOWWINDOW
, showFlag
, 0 );
707 if (!IsWindow( hwnd
)) return wasVisible
;
710 /* ShowWindow won't activate a not being maximized child window */
711 if ((style
& WS_CHILD
) && cmd
!= SW_MAXIMIZE
)
712 swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
714 SetWindowPos( hwnd
, HWND_TOP
, newPos
.left
, newPos
.top
,
715 newPos
.right
, newPos
.bottom
, LOWORD(swp
) );
720 /* FIXME: This will cause the window to be activated irrespective
721 * of whether it is owned by the same thread. Has to be done
725 if (hwnd
== GetActiveWindow())
726 WINPOS_ActivateOtherWindow(hwnd
);
728 /* Revert focus to parent */
730 if (hwnd
== hFocus
|| IsChild(hwnd
, hFocus
))
732 HWND parent
= GetAncestor(hwnd
, GA_PARENT
);
733 if (parent
== GetDesktopWindow()) parent
= 0;
738 if (IsIconic(hwnd
)) WINPOS_ShowIconTitle( hwnd
, TRUE
);
740 if (!(wndPtr
= WIN_GetPtr( hwnd
)) || wndPtr
== WND_OTHER_PROCESS
) return wasVisible
;
742 if (wndPtr
->flags
& WIN_NEED_SIZE
)
744 /* should happen only in CreateWindowEx() */
745 int wParam
= SIZE_RESTORED
;
746 RECT client
= wndPtr
->rectClient
;
748 wndPtr
->flags
&= ~WIN_NEED_SIZE
;
749 if (wndPtr
->dwStyle
& WS_MAXIMIZE
) wParam
= SIZE_MAXIMIZED
;
750 else if (wndPtr
->dwStyle
& WS_MINIMIZE
) wParam
= SIZE_MINIMIZED
;
751 WIN_ReleasePtr( wndPtr
);
753 SendMessageW( hwnd
, WM_SIZE
, wParam
,
754 MAKELONG( client
.right
- client
.left
, client
.bottom
- client
.top
));
755 SendMessageW( hwnd
, WM_MOVE
, 0, MAKELONG( client
.left
, client
.top
));
757 else WIN_ReleasePtr( wndPtr
);