First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xwin / wincreatewnd.c
blob796a085934b720cace20da081a62587f77fb1aad
1 /*
2 *Copyright (C) 2001-2004 Harold L Hunt II All Rights Reserved.
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:
12 *The above copyright notice and this permission notice shall be
13 *included in all copies or substantial portions of the Software.
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 HAROLD L HUNT II 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.
23 *Except as contained in this notice, the name of Harold L Hunt II
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 Harold L Hunt II.
28 * Authors: Harold L Hunt II
31 #ifdef HAVE_XWIN_CONFIG_H
32 #include <xwin-config.h>
33 #endif
34 #include "win.h"
35 #include "shellapi.h"
37 #ifndef ABS_AUTOHIDE
38 #define ABS_AUTOHIDE 1
39 #endif
42 * Local function prototypes
45 static Bool
46 winGetWorkArea (RECT *prcWorkArea, winScreenInfo *pScreenInfo);
48 static Bool
49 winAdjustForAutoHide (RECT *prcWorkArea);
53 * Create a full screen window
56 Bool
57 winCreateBoundingWindowFullScreen (ScreenPtr pScreen)
59 winScreenPriv(pScreen);
60 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
61 int iX = pScreenInfo->dwInitialX;
62 int iY = pScreenInfo->dwInitialY;
63 int iWidth = pScreenInfo->dwWidth;
64 int iHeight = pScreenInfo->dwHeight;
65 HWND *phwnd = &pScreenPriv->hwndScreen;
66 WNDCLASS wc;
67 char szTitle[256];
69 #if CYGDEBUG
70 winDebug ("winCreateBoundingWindowFullScreen\n");
71 #endif
73 /* Setup our window class */
74 wc.style = CS_HREDRAW | CS_VREDRAW;
75 wc.lpfnWndProc = winWindowProc;
76 wc.cbClsExtra = 0;
77 wc.cbWndExtra = 0;
78 wc.hInstance = g_hInstance;
79 wc.hIcon = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN));
80 wc.hCursor = 0;
81 wc.hbrBackground = 0;
82 wc.lpszMenuName = NULL;
83 wc.lpszClassName = WINDOW_CLASS;
84 RegisterClass (&wc);
86 /* Set display and screen-specific tooltip text */
87 if (g_pszQueryHost != NULL)
88 snprintf (szTitle,
89 sizeof (szTitle),
90 WINDOW_TITLE_XDMCP,
91 g_pszQueryHost);
92 else
93 snprintf (szTitle,
94 sizeof (szTitle),
95 WINDOW_TITLE,
96 display,
97 (int) pScreenInfo->dwScreen);
99 /* Create the window */
100 *phwnd = CreateWindowExA (0, /* Extended styles */
101 WINDOW_CLASS, /* Class name */
102 szTitle, /* Window name */
103 WS_POPUP,
104 iX, /* Horizontal position */
105 iY, /* Vertical position */
106 iWidth, /* Right edge */
107 iHeight, /* Bottom edge */
108 (HWND) NULL, /* No parent or owner window */
109 (HMENU) NULL, /* No menu */
110 GetModuleHandle (NULL),/* Instance handle */
111 pScreenPriv); /* ScreenPrivates */
113 /* Branch on the server engine */
114 switch (pScreenInfo->dwEngine)
116 #ifdef XWIN_NATIVEGDI
117 case WIN_SERVER_SHADOW_GDI:
118 /* Show the window */
119 ShowWindow (*phwnd, SW_SHOWMAXIMIZED);
120 break;
121 #endif
123 default:
124 /* Hide the window */
125 ShowWindow (*phwnd, SW_SHOWNORMAL);
126 break;
129 /* Send first paint message */
130 UpdateWindow (*phwnd);
132 /* Attempt to bring our window to the top of the display */
133 BringWindowToTop (*phwnd);
135 return TRUE;
140 * Create our primary Windows display window
143 Bool
144 winCreateBoundingWindowWindowed (ScreenPtr pScreen)
146 winScreenPriv(pScreen);
147 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
148 int iWidth = pScreenInfo->dwUserWidth;
149 int iHeight = pScreenInfo->dwUserHeight;
150 int iPosX;
151 int iPosY;
152 HWND *phwnd = &pScreenPriv->hwndScreen;
153 WNDCLASS wc;
154 RECT rcClient, rcWorkArea;
155 DWORD dwWindowStyle;
156 BOOL fForceShowWindow = FALSE;
157 char szTitle[256];
159 winDebug ("winCreateBoundingWindowWindowed - User w: %d h: %d\n",
160 (int) pScreenInfo->dwUserWidth, (int) pScreenInfo->dwUserHeight);
161 winDebug ("winCreateBoundingWindowWindowed - Current w: %d h: %d\n",
162 (int) pScreenInfo->dwWidth, (int) pScreenInfo->dwHeight);
164 /* Set the common window style flags */
165 dwWindowStyle = WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX;
167 /* Decorated or undecorated window */
168 if (pScreenInfo->fDecoration
169 #ifdef XWIN_MULTIWINDOWEXTWM
170 && !pScreenInfo->fMWExtWM
171 #endif
172 && !pScreenInfo->fRootless
173 #ifdef XWIN_MULTIWINDOW
174 && !pScreenInfo->fMultiWindow
175 #endif
178 /* Try to handle startup via run.exe. run.exe instructs Windows to
179 * hide all created windows. Detect this case and make sure the
180 * window is shown nevertheless */
181 STARTUPINFO startupInfo;
182 GetStartupInfo(&startupInfo);
183 if (startupInfo.dwFlags & STARTF_USESHOWWINDOW &&
184 startupInfo.wShowWindow == SW_HIDE)
186 fForceShowWindow = TRUE;
188 dwWindowStyle |= WS_CAPTION;
189 if (pScreenInfo->fScrollbars)
190 dwWindowStyle |= WS_THICKFRAME | WS_MAXIMIZEBOX;
192 else
193 dwWindowStyle |= WS_POPUP;
195 /* Setup our window class */
196 wc.style = CS_HREDRAW | CS_VREDRAW;
197 wc.lpfnWndProc = winWindowProc;
198 wc.cbClsExtra = 0;
199 wc.cbWndExtra = 0;
200 wc.hInstance = g_hInstance;
201 wc.hIcon = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN));
202 wc.hCursor = 0;
203 wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
204 wc.lpszMenuName = NULL;
205 wc.lpszClassName = WINDOW_CLASS;
206 RegisterClass (&wc);
208 /* Get size of work area */
209 winGetWorkArea (&rcWorkArea, pScreenInfo);
211 /* Adjust for auto-hide taskbars */
212 winAdjustForAutoHide (&rcWorkArea);
214 /* Did the user specify a position? */
215 if (pScreenInfo->fUserGavePosition)
217 iPosX = pScreenInfo->dwInitialX;
218 iPosY = pScreenInfo->dwInitialY;
220 else
222 iPosX = rcWorkArea.left;
223 iPosY = rcWorkArea.top;
226 /* Did the user specify a height and width? */
227 if (pScreenInfo->fUserGaveHeightAndWidth)
229 /* User gave a desired height and width, try to accomodate */
230 #if CYGDEBUG
231 winDebug ("winCreateBoundingWindowWindowed - User gave height "
232 "and width\n");
233 #endif
235 /* Adjust the window width and height for borders and title bar */
236 if (pScreenInfo->fDecoration
237 #ifdef XWIN_MULTIWINDOWEXTWM
238 && !pScreenInfo->fMWExtWM
239 #endif
240 && !pScreenInfo->fRootless
241 #ifdef XWIN_MULTIWINDOW
242 && !pScreenInfo->fMultiWindow
243 #endif
246 #if CYGDEBUG
247 winDebug ("winCreateBoundingWindowWindowed - Window has decoration\n");
248 #endif
249 /* Are we using scrollbars? */
250 if (pScreenInfo->fScrollbars)
252 #if CYGDEBUG
253 winDebug ("winCreateBoundingWindowWindowed - Window has "
254 "scrollbars\n");
255 #endif
257 iWidth += 2 * GetSystemMetrics (SM_CXSIZEFRAME);
258 iHeight += 2 * GetSystemMetrics (SM_CYSIZEFRAME)
259 + GetSystemMetrics (SM_CYCAPTION);
261 else
263 #if CYGDEBUG
264 winDebug ("winCreateBoundingWindowWindowed - Window does not have "
265 "scrollbars\n");
266 #endif
268 iWidth += 2 * GetSystemMetrics (SM_CXFIXEDFRAME);
269 iHeight += 2 * GetSystemMetrics (SM_CYFIXEDFRAME)
270 + GetSystemMetrics (SM_CYCAPTION);
274 else
276 /* By default, we are creating a window that is as large as possible */
277 #if CYGDEBUG
278 winDebug ("winCreateBoundingWindowWindowed - User did not give "
279 "height and width\n");
280 #endif
281 /* Defaults are wrong if we have multiple monitors */
282 if (pScreenInfo->fMultipleMonitors)
284 iWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN);
285 iHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
289 /* Clean up the scrollbars flag, if necessary */
290 if ((!pScreenInfo->fDecoration
291 #ifdef XWIN_MULTIWINDOWEXTWM
292 || pScreenInfo->fMWExtWM
293 #endif
294 || pScreenInfo->fRootless
295 #ifdef XWIN_MULTIWINDOW
296 || pScreenInfo->fMultiWindow
297 #endif
299 && pScreenInfo->fScrollbars)
301 /* We cannot have scrollbars if we do not have a window border */
302 pScreenInfo->fScrollbars = FALSE;
305 if (TRUE
306 #ifdef XWIN_MULTIWINDOWEXTWM
307 && !pScreenInfo->fMWExtWM
308 #endif
309 #ifdef XWIN_MULTIWINDOW
310 && !pScreenInfo->fMultiWindow
311 #endif
314 /* Trim window width to fit work area */
315 if (iWidth > (rcWorkArea.right - rcWorkArea.left))
316 iWidth = rcWorkArea.right - rcWorkArea.left;
318 /* Trim window height to fit work area */
319 if (iHeight >= (rcWorkArea.bottom - rcWorkArea.top))
320 iHeight = rcWorkArea.bottom - rcWorkArea.top;
322 #if CYGDEBUG
323 winDebug ("winCreateBoundingWindowWindowed - Adjusted width: %d "\
324 "height: %d\n",
325 iWidth, iHeight);
326 #endif
329 /* Set display and screen-specific tooltip text */
330 if (g_pszQueryHost != NULL)
331 snprintf (szTitle,
332 sizeof (szTitle),
333 WINDOW_TITLE_XDMCP,
334 g_pszQueryHost);
335 else
336 snprintf (szTitle,
337 sizeof (szTitle),
338 WINDOW_TITLE,
339 display,
340 (int) pScreenInfo->dwScreen);
342 /* Create the window */
343 *phwnd = CreateWindowExA (0, /* Extended styles */
344 WINDOW_CLASS, /* Class name */
345 szTitle, /* Window name */
346 dwWindowStyle,
347 iPosX, /* Horizontal position */
348 iPosY, /* Vertical position */
349 iWidth, /* Right edge */
350 iHeight, /* Bottom edge */
351 (HWND) NULL, /* No parent or owner window */
352 (HMENU) NULL, /* No menu */
353 GetModuleHandle (NULL),/* Instance handle */
354 pScreenPriv); /* ScreenPrivates */
355 if (*phwnd == NULL)
357 ErrorF ("winCreateBoundingWindowWindowed - CreateWindowEx () failed\n");
358 return FALSE;
361 #if CYGDEBUG
362 winDebug ("winCreateBoundingWindowWindowed - CreateWindowEx () returned\n");
363 #endif
365 if (fForceShowWindow)
367 ErrorF("winCreateBoundingWindowWindowed - Setting normal windowstyle\n");
368 ShowWindow(*phwnd, SW_SHOW);
371 /* Get the client area coordinates */
372 if (!GetClientRect (*phwnd, &rcClient))
374 ErrorF ("winCreateBoundingWindowWindowed - GetClientRect () "
375 "failed\n");
376 return FALSE;
379 winDebug ("winCreateBoundingWindowWindowed - WindowClient "
380 "w %ld h %ld r %ld l %ld b %ld t %ld\n",
381 rcClient.right - rcClient.left,
382 rcClient.bottom - rcClient.top,
383 rcClient.right, rcClient.left,
384 rcClient.bottom, rcClient.top);
386 /* We adjust the visual size if the user did not specify it */
387 if (!(pScreenInfo->fScrollbars && pScreenInfo->fUserGaveHeightAndWidth))
390 * User did not give a height and width with scrollbars enabled,
391 * so we will resize the underlying visual to be as large as
392 * the initial view port (page size). This way scrollbars will
393 * not appear until the user shrinks the window, if they ever do.
395 * NOTE: We have to store the viewport size here because
396 * the user may have an autohide taskbar, which would
397 * cause the viewport size to be one less in one dimension
398 * than the viewport size that we calculated by subtracting
399 * the size of the borders and caption.
401 pScreenInfo->dwWidth = rcClient.right - rcClient.left;
402 pScreenInfo->dwHeight = rcClient.bottom - rcClient.top;
405 #if 0
407 * NOTE: For the uninitiated, the page size is the number of pixels
408 * that we can display in the x or y direction at a time and the
409 * range is the total number of pixels in the x or y direction that we
410 * have available to display. In other words, the page size is the
411 * size of the window area minus the space the caption, borders, and
412 * scrollbars (if any) occupy, and the range is the size of the
413 * underlying X visual. Notice that, contrary to what some of the
414 * MSDN Library arcticles lead you to believe, the windows
415 * ``client area'' size does not include the scrollbars. In other words,
416 * the whole client area size that is reported to you is drawable by
417 * you; you do not have to subtract the size of the scrollbars from
418 * the client area size, and if you did it would result in the size
419 * of the scrollbars being double counted.
422 /* Setup scrollbar page and range, if scrollbars are enabled */
423 if (pScreenInfo->fScrollbars)
425 SCROLLINFO si;
427 /* Initialize the scrollbar info structure */
428 si.cbSize = sizeof (si);
429 si.fMask = SIF_RANGE | SIF_PAGE;
430 si.nMin = 0;
432 /* Setup the width range and page size */
433 si.nMax = pScreenInfo->dwWidth - 1;
434 si.nPage = rcClient.right - rcClient.left;
435 winDebug ("winCreateBoundingWindowWindowed - HORZ nMax: %d nPage :%d\n",
436 si.nMax, si.nPage);
437 SetScrollInfo (*phwnd, SB_HORZ, &si, TRUE);
439 /* Setup the height range and page size */
440 si.nMax = pScreenInfo->dwHeight - 1;
441 si.nPage = rcClient.bottom - rcClient.top;
442 winDebug ("winCreateBoundingWindowWindowed - VERT nMax: %d nPage :%d\n",
443 si.nMax, si.nPage);
444 SetScrollInfo (*phwnd, SB_VERT, &si, TRUE);
446 #endif
448 /* Show the window */
449 if (FALSE
450 #ifdef XWIN_MULTIWINDOWEXTWM
451 || pScreenInfo->fMWExtWM
452 #endif
453 #ifdef XWIN_MULTIWINDOW
454 || pScreenInfo->fMultiWindow
455 #endif
458 #if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
459 pScreenPriv->fRootWindowShown = FALSE;
460 #endif
461 ShowWindow (*phwnd, SW_HIDE);
463 else
464 ShowWindow (*phwnd, SW_SHOWNORMAL);
465 if (!UpdateWindow (*phwnd))
467 ErrorF ("winCreateBoundingWindowWindowed - UpdateWindow () failed\n");
468 return FALSE;
471 /* Attempt to bring our window to the top of the display */
472 if (TRUE
473 #ifdef XWIN_MULTIWINDOWEXTWM
474 && !pScreenInfo->fMWExtWM
475 #endif
476 && !pScreenInfo->fRootless
477 #ifdef XWIN_MULTIWINDOW
478 && !pScreenInfo->fMultiWindow
479 #endif
482 if (!BringWindowToTop (*phwnd))
484 ErrorF ("winCreateBoundingWindowWindowed - BringWindowToTop () "
485 "failed\n");
486 return FALSE;
490 #ifdef XWIN_NATIVEGDI
491 /* Paint window background blue */
492 if (pScreenInfo->dwEngine == WIN_SERVER_NATIVE_GDI)
493 winPaintBackground (*phwnd, RGB (0x00, 0x00, 0xFF));
494 #endif
496 winDebug ("winCreateBoundingWindowWindowed - Returning\n");
498 return TRUE;
503 * Find the work area of all attached monitors
506 static Bool
507 winGetWorkArea (RECT *prcWorkArea, winScreenInfo *pScreenInfo)
509 int iPrimaryWidth, iPrimaryHeight;
510 int iWidth, iHeight;
511 int iLeft, iTop;
512 int iPrimaryNonWorkAreaWidth, iPrimaryNonWorkAreaHeight;
514 /* SPI_GETWORKAREA only gets the work area of the primary screen. */
515 SystemParametersInfo (SPI_GETWORKAREA, 0, prcWorkArea, 0);
517 /* Bail out here if we aren't using multiple monitors */
518 if (!pScreenInfo->fMultipleMonitors)
519 return TRUE;
521 winDebug ("winGetWorkArea - Original WorkArea: %d %d %d %d\n",
522 (int) prcWorkArea->top, (int) prcWorkArea->left,
523 (int) prcWorkArea->bottom, (int) prcWorkArea->right);
525 /* Get size of full virtual screen */
526 iWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN);
527 iHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
529 winDebug ("winGetWorkArea - Virtual screen is %d x %d\n", iWidth, iHeight);
531 /* Get origin of full virtual screen */
532 iLeft = GetSystemMetrics (SM_XVIRTUALSCREEN);
533 iTop = GetSystemMetrics (SM_YVIRTUALSCREEN);
535 winDebug ("winGetWorkArea - Virtual screen origin is %d, %d\n", iLeft, iTop);
537 /* Get size of primary screen */
538 iPrimaryWidth = GetSystemMetrics (SM_CXSCREEN);
539 iPrimaryHeight = GetSystemMetrics (SM_CYSCREEN);
541 winDebug ("winGetWorkArea - Primary screen is %d x %d\n",
542 iPrimaryWidth, iPrimaryHeight);
544 /* Work out how much of the primary screen we aren't using */
545 iPrimaryNonWorkAreaWidth = iPrimaryWidth - (prcWorkArea->right -
546 prcWorkArea->left);
547 iPrimaryNonWorkAreaHeight = iPrimaryHeight - (prcWorkArea->bottom
548 - prcWorkArea->top);
550 /* Update the rectangle to include all monitors */
551 if (iLeft < 0)
553 prcWorkArea->left = iLeft;
555 if (iTop < 0)
557 prcWorkArea->top = iTop;
559 prcWorkArea->right = prcWorkArea->left + iWidth -
560 iPrimaryNonWorkAreaWidth;
561 prcWorkArea->bottom = prcWorkArea->top + iHeight -
562 iPrimaryNonWorkAreaHeight;
564 winDebug ("winGetWorkArea - Adjusted WorkArea for multiple "
565 "monitors: %d %d %d %d\n",
566 (int) prcWorkArea->top, (int) prcWorkArea->left,
567 (int) prcWorkArea->bottom, (int) prcWorkArea->right);
569 return TRUE;
574 * Adjust the client area so that any auto-hide toolbars
575 * will work correctly.
578 static Bool
579 winAdjustForAutoHide (RECT *prcWorkArea)
581 APPBARDATA abd;
582 HWND hwndAutoHide;
584 winDebug ("winAdjustForAutoHide - Original WorkArea: %d %d %d %d\n",
585 (int) prcWorkArea->top, (int) prcWorkArea->left,
586 (int) prcWorkArea->bottom, (int) prcWorkArea->right);
588 /* Find out if the Windows taskbar is set to auto-hide */
589 ZeroMemory (&abd, sizeof (abd));
590 abd.cbSize = sizeof (abd);
591 if (SHAppBarMessage (ABM_GETSTATE, &abd) & ABS_AUTOHIDE)
592 winDebug ("winAdjustForAutoHide - Taskbar is auto hide\n");
594 /* Look for a TOP auto-hide taskbar */
595 abd.uEdge = ABE_TOP;
596 hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETAUTOHIDEBAR, &abd);
597 if (hwndAutoHide != NULL)
599 winDebug ("winAdjustForAutoHide - Found TOP auto-hide taskbar\n");
600 prcWorkArea->top += 1;
603 /* Look for a LEFT auto-hide taskbar */
604 abd.uEdge = ABE_LEFT;
605 hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETAUTOHIDEBAR, &abd);
606 if (hwndAutoHide != NULL)
608 winDebug ("winAdjustForAutoHide - Found LEFT auto-hide taskbar\n");
609 prcWorkArea->left += 1;
612 /* Look for a BOTTOM auto-hide taskbar */
613 abd.uEdge = ABE_BOTTOM;
614 hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETAUTOHIDEBAR, &abd);
615 if (hwndAutoHide != NULL)
617 winDebug ("winAdjustForAutoHide - Found BOTTOM auto-hide taskbar\n");
618 prcWorkArea->bottom -= 1;
621 /* Look for a RIGHT auto-hide taskbar */
622 abd.uEdge = ABE_RIGHT;
623 hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETAUTOHIDEBAR, &abd);
624 if (hwndAutoHide != NULL)
626 winDebug ("winAdjustForAutoHide - Found RIGHT auto-hide taskbar\n");
627 prcWorkArea->right -= 1;
630 winDebug ("winAdjustForAutoHide - Adjusted WorkArea: %d %d %d %d\n",
631 (int) prcWorkArea->top, (int) prcWorkArea->left,
632 (int) prcWorkArea->bottom, (int) prcWorkArea->right);
634 #if 0
635 /* Obtain the task bar window dimensions */
636 abd.hWnd = hwndAutoHide;
637 hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETTASKBARPOS, &abd);
638 winDebug ("hwndAutoHide %08x abd.hWnd %08x %d %d %d %d\n",
639 hwndAutoHide, abd.hWnd,
640 abd.rc.top, abd.rc.left, abd.rc.bottom, abd.rc.right);
641 #endif
643 return TRUE;