wincreatewnd.c revision 35c4bbdf
1/*
2 *Copyright (C) 2001-2004 Harold L Hunt II 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 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.
22 *
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.
27 *
28 * Authors:	Harold L Hunt II
29 */
30
31#ifdef HAVE_XWIN_CONFIG_H
32#include <xwin-config.h>
33#endif
34#include "win.h"
35#include "shellapi.h"
36
37/*
38 * Local function prototypes
39 */
40
41static Bool
42 winGetWorkArea(RECT * prcWorkArea, winScreenInfo * pScreenInfo);
43
44static Bool
45 winAdjustForAutoHide(RECT * prcWorkArea, winScreenInfo * pScreenInfo);
46
47/*
48 * Create a full screen window
49 */
50
51Bool
52winCreateBoundingWindowFullScreen(ScreenPtr pScreen)
53{
54    winScreenPriv(pScreen);
55    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
56    int iX = pScreenInfo->dwInitialX;
57    int iY = pScreenInfo->dwInitialY;
58    int iWidth = pScreenInfo->dwWidth;
59    int iHeight = pScreenInfo->dwHeight;
60    HWND *phwnd = &pScreenPriv->hwndScreen;
61    WNDCLASSEX wc;
62    char szTitle[256];
63
64#if CYGDEBUG
65    winDebug("winCreateBoundingWindowFullScreen\n");
66#endif
67
68    /* Setup our window class */
69    wc.cbSize = sizeof(WNDCLASSEX);
70    wc.style = CS_HREDRAW | CS_VREDRAW;
71    wc.lpfnWndProc = winWindowProc;
72    wc.cbClsExtra = 0;
73    wc.cbWndExtra = 0;
74    wc.hInstance = g_hInstance;
75    wc.hIcon =
76        (HICON) LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON,
77                          GetSystemMetrics(SM_CXICON),
78                          GetSystemMetrics(SM_CYICON), 0);
79    wc.hCursor = 0;
80    wc.hbrBackground = 0;
81    wc.lpszMenuName = NULL;
82    wc.lpszClassName = WINDOW_CLASS;
83    wc.hIconSm =
84        (HICON) LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON,
85                          GetSystemMetrics(SM_CXSMICON),
86                          GetSystemMetrics(SM_CYSMICON), LR_DEFAULTSIZE);
87    RegisterClassEx(&wc);
88
89    /* Set display and screen-specific tooltip text */
90    if (g_pszQueryHost != NULL)
91        snprintf(szTitle,
92                 sizeof(szTitle),
93                 WINDOW_TITLE_XDMCP,
94                 g_pszQueryHost, display, (int) pScreenInfo->dwScreen);
95    else
96        snprintf(szTitle,
97                 sizeof(szTitle),
98                 WINDOW_TITLE, display, (int) pScreenInfo->dwScreen);
99
100    /* Create the window */
101    *phwnd = CreateWindowExA(0, /* Extended styles */
102                             WINDOW_CLASS,      /* Class name */
103                             szTitle,   /* Window name */
104                             WS_POPUP, 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 */
112
113    /* Hide the window */
114    ShowWindow(*phwnd, SW_SHOWNORMAL);
115
116    /* Send first paint message */
117    UpdateWindow(*phwnd);
118
119    /* Attempt to bring our window to the top of the display */
120    BringWindowToTop(*phwnd);
121
122    return TRUE;
123}
124
125/*
126 * Create our primary Windows display window
127 */
128
129Bool
130winCreateBoundingWindowWindowed(ScreenPtr pScreen)
131{
132    winScreenPriv(pScreen);
133    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
134    int iWidth = pScreenInfo->dwUserWidth;
135    int iHeight = pScreenInfo->dwUserHeight;
136    int iPosX;
137    int iPosY;
138    HWND *phwnd = &pScreenPriv->hwndScreen;
139    WNDCLASSEX wc;
140    RECT rcClient, rcWorkArea;
141    DWORD dwWindowStyle;
142    BOOL fForceShowWindow = FALSE;
143    char szTitle[256];
144
145    winDebug("winCreateBoundingWindowWindowed - User w: %d h: %d\n",
146             (int) pScreenInfo->dwUserWidth, (int) pScreenInfo->dwUserHeight);
147    winDebug("winCreateBoundingWindowWindowed - Current w: %d h: %d\n",
148             (int) pScreenInfo->dwWidth, (int) pScreenInfo->dwHeight);
149
150    /* Set the common window style flags */
151    dwWindowStyle = WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX;
152
153    /* Decorated or undecorated window */
154    if (pScreenInfo->fDecoration
155#ifdef XWIN_MULTIWINDOWEXTWM
156        && !pScreenInfo->fMWExtWM
157#endif
158        && !pScreenInfo->fRootless
159#ifdef XWIN_MULTIWINDOW
160        && !pScreenInfo->fMultiWindow
161#endif
162        ) {
163        /* Try to handle startup via run.exe. run.exe instructs Windows to
164         * hide all created windows. Detect this case and make sure the
165         * window is shown nevertheless */
166        STARTUPINFO startupInfo;
167
168        GetStartupInfo(&startupInfo);
169        if (startupInfo.dwFlags & STARTF_USESHOWWINDOW &&
170            startupInfo.wShowWindow == SW_HIDE) {
171            fForceShowWindow = TRUE;
172        }
173        dwWindowStyle |= WS_CAPTION;
174        if (pScreenInfo->iResizeMode != notAllowed)
175            dwWindowStyle |= WS_THICKFRAME | WS_MAXIMIZEBOX;
176    }
177    else
178        dwWindowStyle |= WS_POPUP;
179
180    /* Setup our window class */
181    wc.cbSize = sizeof(WNDCLASSEX);
182    wc.style = CS_HREDRAW | CS_VREDRAW;
183    wc.lpfnWndProc = winWindowProc;
184    wc.cbClsExtra = 0;
185    wc.cbWndExtra = 0;
186    wc.hInstance = g_hInstance;
187    wc.hIcon =
188        (HICON) LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON,
189                          GetSystemMetrics(SM_CXICON),
190                          GetSystemMetrics(SM_CYICON), 0);
191    wc.hCursor = 0;
192    wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
193    wc.lpszMenuName = NULL;
194    wc.lpszClassName = WINDOW_CLASS;
195    wc.hIconSm =
196        (HICON) LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON,
197                          GetSystemMetrics(SM_CXSMICON),
198                          GetSystemMetrics(SM_CYSMICON), LR_DEFAULTSIZE);
199    RegisterClassEx(&wc);
200
201    /* Get size of work area */
202    winGetWorkArea(&rcWorkArea, pScreenInfo);
203
204    /* Adjust for auto-hide taskbars */
205    winAdjustForAutoHide(&rcWorkArea, pScreenInfo);
206
207    /* Did the user specify a position? */
208    if (pScreenInfo->fUserGavePosition) {
209        iPosX = pScreenInfo->dwInitialX;
210        iPosY = pScreenInfo->dwInitialY;
211    }
212    else {
213        iPosX = rcWorkArea.left;
214        iPosY = rcWorkArea.top;
215    }
216
217    /* Clean up the scrollbars flag, if necessary */
218    if ((!pScreenInfo->fDecoration
219#ifdef XWIN_MULTIWINDOWEXTWM
220         || pScreenInfo->fMWExtWM
221#endif
222         || pScreenInfo->fRootless
223#ifdef XWIN_MULTIWINDOW
224         || pScreenInfo->fMultiWindow
225#endif
226        )
227        && (pScreenInfo->iResizeMode == resizeWithScrollbars)) {
228        /* We cannot have scrollbars if we do not have a window border */
229        pScreenInfo->iResizeMode = notAllowed;
230    }
231
232    /* Did the user specify a height and width? */
233    if (pScreenInfo->fUserGaveHeightAndWidth) {
234        /* User gave a desired height and width, try to accomodate */
235#if CYGDEBUG
236        winDebug("winCreateBoundingWindowWindowed - User gave height "
237                 "and width\n");
238#endif
239
240        /* Adjust the window width and height for borders and title bar */
241        if (pScreenInfo->fDecoration
242#ifdef XWIN_MULTIWINDOWEXTWM
243            && !pScreenInfo->fMWExtWM
244#endif
245            && !pScreenInfo->fRootless
246#ifdef XWIN_MULTIWINDOW
247            && !pScreenInfo->fMultiWindow
248#endif
249            ) {
250#if CYGDEBUG
251            winDebug
252                ("winCreateBoundingWindowWindowed - Window has decoration\n");
253#endif
254
255            /* Are we resizable */
256            if (pScreenInfo->iResizeMode != notAllowed) {
257#if CYGDEBUG
258                winDebug
259                    ("winCreateBoundingWindowWindowed - Window is resizable\n");
260#endif
261
262                iWidth += 2 * GetSystemMetrics(SM_CXSIZEFRAME);
263                iHeight += 2 * GetSystemMetrics(SM_CYSIZEFRAME)
264                    + GetSystemMetrics(SM_CYCAPTION);
265            }
266            else {
267#if CYGDEBUG
268                winDebug
269                    ("winCreateBoundingWindowWindowed - Window is not resizable\n");
270#endif
271
272                iWidth += 2 * GetSystemMetrics(SM_CXFIXEDFRAME);
273                iHeight += 2 * GetSystemMetrics(SM_CYFIXEDFRAME)
274                    + GetSystemMetrics(SM_CYCAPTION);
275            }
276        }
277    }
278    else {
279        /* By default, we are creating a window that is as large as possible */
280#if CYGDEBUG
281        winDebug("winCreateBoundingWindowWindowed - User did not give "
282                 "height and width\n");
283#endif
284        /* Defaults are wrong if we have multiple monitors */
285        if (pScreenInfo->fMultipleMonitors) {
286            iWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
287            iHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
288        }
289    }
290
291    /* Make sure window is no bigger than work area */
292    if (TRUE
293#ifdef XWIN_MULTIWINDOWEXTWM
294        && !pScreenInfo->fMWExtWM
295#endif
296#ifdef XWIN_MULTIWINDOW
297        && !pScreenInfo->fMultiWindow
298#endif
299        ) {
300        /* Trim window width to fit work area */
301        if (iWidth > (rcWorkArea.right - rcWorkArea.left))
302            iWidth = rcWorkArea.right - rcWorkArea.left;
303
304        /* Trim window height to fit work area */
305        if (iHeight >= (rcWorkArea.bottom - rcWorkArea.top))
306            iHeight = rcWorkArea.bottom - rcWorkArea.top;
307
308#if CYGDEBUG
309        winDebug("winCreateBoundingWindowWindowed - Adjusted width: %d "
310                 "height: %d\n", iWidth, iHeight);
311#endif
312    }
313
314    /* Set display and screen-specific tooltip text */
315    if (g_pszQueryHost != NULL)
316        snprintf(szTitle,
317                 sizeof(szTitle),
318                 WINDOW_TITLE_XDMCP,
319                 g_pszQueryHost, display, (int) pScreenInfo->dwScreen);
320    else
321        snprintf(szTitle,
322                 sizeof(szTitle),
323                 WINDOW_TITLE, display, (int) pScreenInfo->dwScreen);
324
325    /* Create the window */
326    *phwnd = CreateWindowExA(0, /* Extended styles */
327                             WINDOW_CLASS,      /* Class name */
328                             szTitle,   /* Window name */
329                             dwWindowStyle, iPosX,      /* Horizontal position */
330                             iPosY,     /* Vertical position */
331                             iWidth,    /* Right edge */
332                             iHeight,   /* Bottom edge */
333                             (HWND) NULL,       /* No parent or owner window */
334                             (HMENU) NULL,      /* No menu */
335                             GetModuleHandle(NULL),     /* Instance handle */
336                             pScreenPriv);      /* ScreenPrivates */
337    if (*phwnd == NULL) {
338        ErrorF("winCreateBoundingWindowWindowed - CreateWindowEx () failed\n");
339        return FALSE;
340    }
341
342#if CYGDEBUG
343    winDebug("winCreateBoundingWindowWindowed - CreateWindowEx () returned\n");
344#endif
345
346    if (fForceShowWindow) {
347        ErrorF
348            ("winCreateBoundingWindowWindowed - Setting normal windowstyle\n");
349        ShowWindow(*phwnd, SW_SHOW);
350    }
351
352    /* Get the client area coordinates */
353    if (!GetClientRect(*phwnd, &rcClient)) {
354        ErrorF("winCreateBoundingWindowWindowed - GetClientRect () "
355               "failed\n");
356        return FALSE;
357    }
358
359    winDebug("winCreateBoundingWindowWindowed - WindowClient "
360             "w %d  h %d r %d l %d b %d t %d\n",
361             (int)(rcClient.right - rcClient.left),
362             (int)(rcClient.bottom - rcClient.top),
363             (int)rcClient.right, (int)rcClient.left,
364             (int)rcClient.bottom, (int)rcClient.top);
365
366    /* We adjust the visual size if the user did not specify it */
367    if (!
368        ((pScreenInfo->iResizeMode == resizeWithScrollbars) &&
369         pScreenInfo->fUserGaveHeightAndWidth)) {
370        /*
371         * User did not give a height and width with scrollbars enabled,
372         * so we will resize the underlying visual to be as large as
373         * the initial view port (page size).  This way scrollbars will
374         * not appear until the user shrinks the window, if they ever do.
375         *
376         * NOTE: We have to store the viewport size here because
377         * the user may have an autohide taskbar, which would
378         * cause the viewport size to be one less in one dimension
379         * than the viewport size that we calculated by subtracting
380         * the size of the borders and caption.
381         */
382        pScreenInfo->dwWidth = rcClient.right - rcClient.left;
383        pScreenInfo->dwHeight = rcClient.bottom - rcClient.top;
384    }
385
386#if 0
387    /*
388     * NOTE: For the uninitiated, the page size is the number of pixels
389     * that we can display in the x or y direction at a time and the
390     * range is the total number of pixels in the x or y direction that we
391     * have available to display.  In other words, the page size is the
392     * size of the window area minus the space the caption, borders, and
393     * scrollbars (if any) occupy, and the range is the size of the
394     * underlying X visual.  Notice that, contrary to what some of the
395     * MSDN Library arcticles lead you to believe, the windows
396     * ``client area'' size does not include the scrollbars.  In other words,
397     * the whole client area size that is reported to you is drawable by
398     * you; you do not have to subtract the size of the scrollbars from
399     * the client area size, and if you did it would result in the size
400     * of the scrollbars being double counted.
401     */
402
403    /* Setup scrollbar page and range, if scrollbars are enabled */
404    if (pScreenInfo->fScrollbars) {
405        SCROLLINFO si;
406
407        /* Initialize the scrollbar info structure */
408        si.cbSize = sizeof(si);
409        si.fMask = SIF_RANGE | SIF_PAGE;
410        si.nMin = 0;
411
412        /* Setup the width range and page size */
413        si.nMax = pScreenInfo->dwWidth - 1;
414        si.nPage = rcClient.right - rcClient.left;
415        winDebug("winCreateBoundingWindowWindowed - HORZ nMax: %d nPage :%d\n",
416                 si.nMax, si.nPage);
417        SetScrollInfo(*phwnd, SB_HORZ, &si, TRUE);
418
419        /* Setup the height range and page size */
420        si.nMax = pScreenInfo->dwHeight - 1;
421        si.nPage = rcClient.bottom - rcClient.top;
422        winDebug("winCreateBoundingWindowWindowed - VERT nMax: %d nPage :%d\n",
423                 si.nMax, si.nPage);
424        SetScrollInfo(*phwnd, SB_VERT, &si, TRUE);
425    }
426#endif
427
428    /* Show the window */
429    if (FALSE
430#ifdef XWIN_MULTIWINDOWEXTWM
431        || pScreenInfo->fMWExtWM
432#endif
433#ifdef XWIN_MULTIWINDOW
434        || pScreenInfo->fMultiWindow
435#endif
436        ) {
437#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
438        pScreenPriv->fRootWindowShown = FALSE;
439#endif
440        ShowWindow(*phwnd, SW_HIDE);
441    }
442    else
443        ShowWindow(*phwnd, SW_SHOWNORMAL);
444    if (!UpdateWindow(*phwnd)) {
445        ErrorF("winCreateBoundingWindowWindowed - UpdateWindow () failed\n");
446        return FALSE;
447    }
448
449    /* Attempt to bring our window to the top of the display */
450    if (TRUE
451#ifdef XWIN_MULTIWINDOWEXTWM
452        && !pScreenInfo->fMWExtWM
453#endif
454        && !pScreenInfo->fRootless
455#ifdef XWIN_MULTIWINDOW
456        && !pScreenInfo->fMultiWindow
457#endif
458        ) {
459        if (!BringWindowToTop(*phwnd)) {
460            ErrorF("winCreateBoundingWindowWindowed - BringWindowToTop () "
461                   "failed\n");
462            return FALSE;
463        }
464    }
465
466    winDebug("winCreateBoundingWindowWindowed -  Returning\n");
467
468    return TRUE;
469}
470
471/*
472 * Find the work area of all attached monitors
473 */
474
475static Bool
476winGetWorkArea(RECT * prcWorkArea, winScreenInfo * pScreenInfo)
477{
478    int iPrimaryWidth, iPrimaryHeight;
479    int iWidth, iHeight;
480    int iLeft, iTop;
481    int iPrimaryNonWorkAreaWidth, iPrimaryNonWorkAreaHeight;
482
483    /* Use GetMonitorInfo to get work area for monitor */
484    if (!pScreenInfo->fMultipleMonitors) {
485        MONITORINFO mi;
486
487        mi.cbSize = sizeof(MONITORINFO);
488        if (GetMonitorInfo(pScreenInfo->hMonitor, &mi)) {
489            *prcWorkArea = mi.rcWork;
490
491            winDebug("winGetWorkArea - Monitor %d WorkArea: %d %d %d %d\n",
492                     pScreenInfo->iMonitor,
493                     (int) prcWorkArea->top, (int) prcWorkArea->left,
494                     (int) prcWorkArea->bottom, (int) prcWorkArea->right);
495        }
496        else {
497            ErrorF("winGetWorkArea - GetMonitorInfo() failed for monitor %d\n",
498                   pScreenInfo->iMonitor);
499        }
500
501        /* Bail out here if we aren't using multiple monitors */
502        return TRUE;
503    }
504
505    /* SPI_GETWORKAREA only gets the work area of the primary screen. */
506    SystemParametersInfo(SPI_GETWORKAREA, 0, prcWorkArea, 0);
507
508    winDebug("winGetWorkArea - Primary Monitor WorkArea: %d %d %d %d\n",
509             (int) prcWorkArea->top, (int) prcWorkArea->left,
510             (int) prcWorkArea->bottom, (int) prcWorkArea->right);
511
512    /* Get size of full virtual screen */
513    iWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
514    iHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
515
516    winDebug("winGetWorkArea - Virtual screen is %d x %d\n", iWidth, iHeight);
517
518    /* Get origin of full virtual screen */
519    iLeft = GetSystemMetrics(SM_XVIRTUALSCREEN);
520    iTop = GetSystemMetrics(SM_YVIRTUALSCREEN);
521
522    winDebug("winGetWorkArea - Virtual screen origin is %d, %d\n", iLeft, iTop);
523
524    /* Get size of primary screen */
525    iPrimaryWidth = GetSystemMetrics(SM_CXSCREEN);
526    iPrimaryHeight = GetSystemMetrics(SM_CYSCREEN);
527
528    winDebug("winGetWorkArea - Primary screen is %d x %d\n",
529             iPrimaryWidth, iPrimaryHeight);
530
531    /* Work out how much of the primary screen we aren't using */
532    iPrimaryNonWorkAreaWidth = iPrimaryWidth - (prcWorkArea->right -
533                                                prcWorkArea->left);
534    iPrimaryNonWorkAreaHeight = iPrimaryHeight - (prcWorkArea->bottom
535                                                  - prcWorkArea->top);
536
537    /* Update the rectangle to include all monitors */
538    if (iLeft < 0) {
539        prcWorkArea->left = iLeft;
540    }
541    if (iTop < 0) {
542        prcWorkArea->top = iTop;
543    }
544    prcWorkArea->right = prcWorkArea->left + iWidth - iPrimaryNonWorkAreaWidth;
545    prcWorkArea->bottom = prcWorkArea->top + iHeight -
546        iPrimaryNonWorkAreaHeight;
547
548    winDebug("winGetWorkArea - Adjusted WorkArea for multiple "
549             "monitors: %d %d %d %d\n",
550             (int) prcWorkArea->top, (int) prcWorkArea->left,
551             (int) prcWorkArea->bottom, (int) prcWorkArea->right);
552
553    return TRUE;
554}
555
556static Bool
557winTaskbarOnScreenEdge(unsigned int uEdge, winScreenInfo * pScreenInfo)
558{
559    APPBARDATA abd;
560    HWND hwndAutoHide;
561
562    ZeroMemory(&abd, sizeof(abd));
563    abd.cbSize = sizeof(abd);
564    abd.uEdge = uEdge;
565
566    hwndAutoHide = (HWND) SHAppBarMessage(ABM_GETAUTOHIDEBAR, &abd);
567    if (hwndAutoHide != NULL) {
568        /*
569           Found an autohide taskbar on that edge, but is it on the
570           same monitor as the screen window?
571         */
572        if (pScreenInfo->fMultipleMonitors ||
573            (MonitorFromWindow(hwndAutoHide, MONITOR_DEFAULTTONULL) ==
574             pScreenInfo->hMonitor))
575            return TRUE;
576    }
577    return FALSE;
578}
579
580/*
581 * Adjust the client area so that any auto-hide toolbars
582 * will work correctly.
583 */
584
585static Bool
586winAdjustForAutoHide(RECT * prcWorkArea, winScreenInfo * pScreenInfo)
587{
588    APPBARDATA abd;
589
590    winDebug("winAdjustForAutoHide - Original WorkArea: %d %d %d %d\n",
591             (int) prcWorkArea->top, (int) prcWorkArea->left,
592             (int) prcWorkArea->bottom, (int) prcWorkArea->right);
593
594    /* Find out if the Windows taskbar is set to auto-hide */
595    ZeroMemory(&abd, sizeof(abd));
596    abd.cbSize = sizeof(abd);
597    if (SHAppBarMessage(ABM_GETSTATE, &abd) & ABS_AUTOHIDE)
598        winDebug("winAdjustForAutoHide - Taskbar is auto hide\n");
599
600    /*
601       Despite the forgoing, we are checking for any AppBar
602       hiding along a monitor edge, not just the Windows TaskBar.
603     */
604
605    /* Look for a TOP auto-hide taskbar */
606    if (winTaskbarOnScreenEdge(ABE_TOP, pScreenInfo)) {
607        winDebug("winAdjustForAutoHide - Found TOP auto-hide taskbar\n");
608        prcWorkArea->top += 1;
609    }
610
611    /* Look for a LEFT auto-hide taskbar */
612    if (winTaskbarOnScreenEdge(ABE_LEFT, pScreenInfo)) {
613        winDebug("winAdjustForAutoHide - Found LEFT auto-hide taskbar\n");
614        prcWorkArea->left += 1;
615    }
616
617    /* Look for a BOTTOM auto-hide taskbar */
618    if (winTaskbarOnScreenEdge(ABE_BOTTOM, pScreenInfo)) {
619        winDebug("winAdjustForAutoHide - Found BOTTOM auto-hide taskbar\n");
620        prcWorkArea->bottom -= 1;
621    }
622
623    /* Look for a RIGHT auto-hide taskbar */
624    if (winTaskbarOnScreenEdge(ABE_RIGHT, pScreenInfo)) {
625        winDebug("winAdjustForAutoHide - Found RIGHT auto-hide taskbar\n");
626        prcWorkArea->right -= 1;
627    }
628
629    winDebug("winAdjustForAutoHide - Adjusted WorkArea: %d %d %d %d\n",
630             (int) prcWorkArea->top, (int) prcWorkArea->left,
631             (int) prcWorkArea->bottom, (int) prcWorkArea->right);
632
633    return TRUE;
634}
635