MatrixXd MultivariateFNormalSufficient::compute_PW_cg() const
{
    //compute PW using CG. Preconditionner is Sigma^-1 and initial guess
    //is previous value of PW. Do M steps (theoretically sufficient) and if the
    //residuals are too big do the inversion.
    //
    timer_.start(PW_CG_SUCCESS);
    //static unsigned numtries=0;
    //static unsigned numfail=0;
    cg_->set_A(get_Sigma());
    cg_->set_B(get_W());
    cg_->set_X0(PW_);
    cg_->set_tol(cg_tol_);
    MatrixXd PW(cg_->optimize(precond_, M_));
    if (cg_->info()>0) timer_.stop(PW_CG_SUCCESS);
    double resid = (get_Sigma()*PW-get_W()).norm();
    if (resid > cg_tol_)
    {
        //numfail++;
        PW = compute_PW_direct();
    }
    //numtries++;
    //std::cout << "CG: numtries="<<numtries<<" numfail="<<numfail<<std::endl;
    return PW;
}
MatrixXd MultivariateFNormalSufficient::get_PW() const
{
    if (!flag_PW_)
    {
        ////PW
        timer_.start(SOLVE);
        MatrixXd PW(M_,M_);
        if (N_==1)
        {
            IMP_LOG(TERSE, "MVN:   W=0 => PW=0" << std::endl);
            PW.setZero();
        } else {
            IMP_LOG(TERSE, "MVN:   solving for PW" << std::endl);
            if (use_cg_)
            {
                if (first_PW_)
                {
                    PW = compute_PW_direct();
                    (*const_cast<bool *>(&first_PW_))=false;
                } else {
                    PW = compute_PW_cg();
                }
            } else {
                PW = compute_PW_direct();
            }
        }
        const_cast<MultivariateFNormalSufficient *>(this)->set_PW(PW);
        timer_.stop(SOLVE);
    }
    return PW_;
}
MatrixXd MultivariateFNormalSufficient::get_PW() const
{
    if (!flag_PW_)
    {
        ////PW
        MatrixXd PW(M_,M_);
        if (N_==1)
        {
            LOG( "MVN:   W=0 => PW=0" << std::endl);
            PW.setZero();
        } else {
            LOG( "MVN:   solving for PW" << std::endl);
            PW = compute_PW_direct();
        }
        const_cast<MultivariateFNormalSufficient *>(this)->set_PW(PW);
    }
    return PW_;
}
Exemple #4
0
BOOL _TranslateMessage(
    LPMSG pmsg,
    UINT flags)
{
    PTHREADINFO pti;
    UINT wMsgType;
    WORD *pwParam;
    int cChar;
    BOOL fSysKey = FALSE;
    BOOL bBreak;
    LPARAM lParam;

    switch (pmsg->message) {

    default:
        return FALSE;

    case WM_SYSKEYDOWN:
        /*
         * HACK carried over from Win3 code: system messages
         * only get posted during KEYDOWN processing - so
         * set fSysKey only for WM_SYSKEYDOWN.
         */
        fSysKey = TRUE;
        /*
         * Fall thru...
         */

    case WM_SYSKEYUP:
    case WM_KEYDOWN:
    case WM_KEYUP:
        pti = PtiCurrent();

        if ((pti->pMenuState != NULL) &&
                (HW(pti->pMenuState->pGlobalPopupMenu->spwndPopupMenu) ==
                pmsg->hwnd)) {
            flags |= 1;
        } else {
            flags &= ~1;
        }

        /*
         * Don't change the contents of the passed in structure.
         */
        lParam = pmsg->lParam;

        cChar = InternalToUnicode(LOWORD(pmsg->wParam),  // virtual key code
                         HIWORD(lParam),  // scan code, make/break bit
                         pti->pq->afKeyState,
                         pState, 16,  // see init.c
                         flags, &bBreak);

/*
 * LATER 12/7/90 - GregoryW
 * Note: Win3.x TranslateMessage returns TRUE if ToAscii is called.
 *       Proper behavior is to return TRUE if any translation is
 *       performed by ToAscii.  If we have to remain compatible
 *       (even though apps clearly don't currently care about the
 *       return value) then the following return should be changed
 *       to TRUE.  If we want the new 32-bit apps to have a meaningful
 *       return value we should leave this as FALSE.
 *
 *      If console is calling us with the TM_POSTCHARBREAKS flag then we
 *      return FALSE if no char was actually posted
 *
 *      !!! LATER get console to change so it does not need private API
 *      TranslateMessageEx
 */

        if (!cChar) {
            if (flags & TM_POSTCHARBREAKS)
                return FALSE;
            else
                return TRUE;
        }

        /*
         * Some translation performed.  Figure out what type of
         * message to post.
         *
         */
        if (cChar > 0)
            wMsgType = (fSysKey) ? (UINT)WM_SYSCHAR : (UINT)WM_CHAR;
        else {
            wMsgType = (fSysKey) ? (UINT)WM_SYSDEADCHAR : (UINT)WM_DEADCHAR;
            cChar = -cChar;                // want positive value
        }

        if (bBreak) {
            lParam |=  0x80000000;
        } else {
            lParam &= ~0x80000000;
        }

        pwParam = (WORD *)pState;

        for ( ; cChar > 0; cChar--) {

            /*
             * If this is a multi-character posting, all but the last one
             * should be marked as fake keystrokes for Console/VDM.
             */

            _PostMessage(PW(pmsg->hwnd), wMsgType, (DWORD)*pwParam,
                    lParam | (cChar > 1 ? FAKE_KEYSTROKE : 0));

            *pwParam = 0;        // zero out old character
            pwParam += 1;
        }

        return TRUE;
    }
}
Exemple #5
0
BOOL xxxDoHotKeyStuff(
    UINT vk,
    BOOL fBreak,
    DWORD fsReserveKeys)
{
#ifdef WINDOWS_NOT_HOT
    static BOOL fOnlyWinKey = FALSE;
#endif
    static UINT fsModifiers = 0;
    static UINT fsModOnlyCandidate = 0;
    UINT fsModOnlyHotkey;
    UINT fs;
    PHOTKEY phk;
    PWND pwnd;
    BOOL fCancel;
    BOOL fEatDebugKeyBreak = FALSE;

    CheckCritIn();

    /*
     * Update fsModifiers.
     */
    fs = 0;
    fsModOnlyHotkey = 0;

    switch (vk) {
    case VK_RSHIFT:
        fs = MOD_RSHIFT;
    case VK_LSHIFT:
    case VK_SHIFT:
        vk = VK_SHIFT;
        fs |= MOD_SHIFT;
        break;

    case VK_RCONTROL:
        fs = MOD_RCONTROL;
    case VK_LCONTROL:
        vk = VK_CONTROL;
    case VK_CONTROL:
        fs |= MOD_CONTROL;
        break;

    case VK_RMENU:
        fs = MOD_RALT;
    case VK_LMENU:
        vk = VK_MENU;
    case VK_MENU:
        fs |= MOD_ALT;
        break;

    case VK_LWIN:
    case VK_RWIN:
        fs = MOD_WIN;
        break;

    default:
        /*
         * A non-modifier key rules out Modifier-Only hotkeys
         */
        fsModOnlyCandidate = 0;
        break;
    }

    if (fBreak) {
        fsModifiers &= ~fs;
        /*
         * If a modifier key is coming up, the current modifier only hotkey
         * candidate must be tested to see if it is a hotkey.  Store this
         * in fsModOnlyHotkey, and prevent the next key release from
         * being a candidate by clearing fsModOnlyCandidate.
         */
        if (fs != 0) {
            fsModOnlyHotkey = fsModOnlyCandidate;
            fsModOnlyCandidate = 0;
        }
    } else {
        fsModifiers |= fs;
        /*
         * If a modifier key is going down, we have a modifier-only hotkey
         * candidate.  Save current modifier state until the following break.
         */
        if (fs != 0) {
            fsModOnlyCandidate = fsModifiers;
        }
    }

    if (vk == VK_DELETE) {
        /*
         * Special case for SAS (Ctrl+Alt+Del) - examine physical key state!
         *
         * An evil daemon process can fool convincingly pretend to be winlogon
         * by registering Alt+Del as a hotkey, and spinning another thread that
         * continually calls keybd_event() to send the Ctrl key up: when the
         * user types Ctrl+Alt+Del, only Alt+Del will be seen by the system,
         * the evil daemon will get woken by WM_HOTKEY and can pretend to be
         * winlogon.  So look at gafPhysKeyState in this case, to see what keys
         * were physically pressed.
         * NOTE: If hotkeys are ever made to work under journal playback, make
         * sure they don't affect the gafPhysKeyState!  - IanJa.
         */
        UINT fPhysMods =
                (TestKeyDownBit(gafPhysKeyState, VK_MENU) ? MOD_ALT : 0) |
                (TestKeyDownBit(gafPhysKeyState, VK_SHIFT) ? MOD_SHIFT : 0) |
                (TestKeyDownBit(gafPhysKeyState, VK_CONTROL) ? MOD_CONTROL : 0);
        if ((fPhysMods & (MOD_CONTROL|MOD_ALT)) == MOD_CONTROL|MOD_ALT) {
            /*
             * Use physical modifiers keys
             */
            fsModifiers = fPhysMods;
        }
    }

#ifdef WINDOWS_NOT_HOT
    /*
     * track whether any key has been pressed since a Windows key went down
     */
    if (vk == VK_LWIN || vk == VK_RWIN) {
        if (!fBreak) {
            fOnlyWinKey = TRUE;
        } else if (fOnlyWinKey) {
            fOnlyWinKey = FALSE;
            CancelJournalling();

            pwnd = GETDESKINFO(PtiCurrent())->spwndShell;
            if (pwnd != NULL) {
                _PostMessage(pwnd, WM_SYSCOMMAND, SC_TASKLIST, 0);
                return TRUE;
            }
        }

    } else {
        fOnlyWinKey = FALSE;
    }
#endif

    /*
     * If the key is not a hotkey then we're done but first check if the
     * key is an Alt-Escape if so we need to cancel journalling.
     *
     * NOTE: Support for Alt+Esc to cancel journalling dropped in NT 4.0
     */
    if (fsModOnlyHotkey && fBreak) {
        /*
         * A hotkey involving only VK_SHIFT, VK_CONTROL, VK_MENU or VK_WINDOWS
         * must only operate on a key release.
         */
        if ((phk = IsHotKey(LOWORD(fsModOnlyHotkey), VK_NONE)) == NULL) {
            return FALSE;
        }
    } else if ((phk = IsHotKey(LOWORD(fsModifiers), vk)) == NULL) {
        return FALSE;
    }

    if (phk->id == IDHOT_WINDOWS) {
        pwnd = GETDESKINFO(PtiCurrent())->spwndShell;
        if (pwnd != NULL) {
            _PostMessage(pwnd, WM_SYSCOMMAND, SC_TASKLIST, 0);
            return TRUE;
        }
    }

    if ((phk->id == IDHOT_DEBUG) || (phk->id == IDHOT_DEBUGSERVER)) {

        if (!fBreak) {
            /*
             * The DEBUG key has been pressed.  Break the appropriate
             * thread into the debugger.
             */
            fEatDebugKeyBreak = xxxActivateDebugger(phk->fsModifiers);
        }

        /*
         * This'll eat the debug key down and break if we broke into
         * the debugger on the server only on the down.
         */
        return fEatDebugKeyBreak;
    }

    /*
     * don't allow hotkeys(except for ones owned by the logon process)
     * if the window station is locked.
     */

    if (((grpdeskRitInput->rpwinstaParent->dwFlags & WSF_SWITCHLOCK) != 0) &&
            (phk->pti->Thread->Cid.UniqueProcess != gpidLogon)) {
        return FALSE;
    }

    if ((fsModOnlyHotkey == 0) && fBreak) {
        /*
         * Do Modifier-Only hotkeys on break events, else return here.
         */
        return FALSE;
    }

    /*
     * Unhook hooks if a control-escape, alt-escape, or control-alt-del
     * comes through, so the user can cancel if the system seems hung.
     *
     * Note the hook may be locked so even if the unhook succeeds it
     * won't remove the hook from the global asphkStart array.  So
     * we have to walk the list manually.  This code works because
     * we are in the critical section and we know other hooks won't
     * be deleted.
     *
     * Once we've unhooked, post a WM_CANCELJOURNAL message to the app
     * that set the hook so it knows we did this.
     *
     * NOTE: Support for Alt+Esc to cancel journalling dropped in NT 4.0
     */
    fCancel = FALSE;
    if (vk == VK_ESCAPE && LOWORD(fsModifiers) == MOD_CONTROL) {
        fCancel = TRUE;
    }

    if (vk == VK_DELETE && (fsModifiers & (MOD_CONTROL | MOD_ALT)) ==
            (MOD_CONTROL | MOD_ALT)) {
        fCancel = TRUE;
    }

    if (fCancel)
        CancelJournalling();

    /*
     * See if the key is reserved by a console window.  If it is,
     * return FALSE so the key will be passed to the console.
     */
    if (fsReserveKeys != 0) {
        switch (vk) {
        case VK_TAB:
            if ((fsReserveKeys & CONSOLE_ALTTAB) &&
                    ((fsModifiers & (MOD_CONTROL | MOD_ALT)) == MOD_ALT)) {
                return FALSE;
            }
            break;
        case VK_ESCAPE:
            if ((fsReserveKeys & CONSOLE_ALTESC) &&
                    ((fsModifiers & (MOD_CONTROL | MOD_ALT)) == MOD_ALT)) {
                return FALSE;
            }
            if ((fsReserveKeys & CONSOLE_CTRLESC) &&
                    ((fsModifiers & (MOD_CONTROL | MOD_ALT)) == MOD_CONTROL)) {
                return FALSE;
            }
            break;
        case VK_RETURN:
            if ((fsReserveKeys & CONSOLE_ALTENTER) &&
                    ((fsModifiers & (MOD_CONTROL | MOD_ALT)) == MOD_ALT)) {
                return FALSE;
            }
            break;
        case VK_SNAPSHOT:
            if ((fsReserveKeys & CONSOLE_PRTSC) &&
                    ((fsModifiers & (MOD_CONTROL | MOD_ALT)) == 0)) {
                return FALSE;
            }
            if ((fsReserveKeys & CONSOLE_ALTPRTSC) &&
                    ((fsModifiers & (MOD_CONTROL | MOD_ALT)) == MOD_ALT)) {
                return FALSE;
            }
            break;
        case VK_SPACE:
            if ((fsReserveKeys & CONSOLE_ALTSPACE) &&
                    ((fsModifiers & (MOD_CONTROL | MOD_ALT)) == MOD_ALT)) {
                return FALSE;
            }
            break;
        }
    }

    /*
     * If this is the task-list hotkey, go ahead and set foreground
     * status to the task-list queue right now.  This prevents problems
     * where the user hits ctrl-esc and types-ahead before the task-list
     * processes the hotkey and brings up the task-list window.
     */
    if ((LOWORD(fsModifiers) == MOD_CONTROL) && (vk == VK_ESCAPE) && !fBreak) {
        PWND pwndSwitch;
        TL tlpwndSwitch;

        if (ghwndSwitch != NULL) {
            pwndSwitch = PW(ghwndSwitch);
            ThreadLock(pwndSwitch, &tlpwndSwitch);
            xxxSetForegroundWindow2(pwndSwitch, NULL, 0);
            ThreadUnlock(&tlpwndSwitch);
        }
    }

    /*
     * Get the hot key contents.
     */
    if (phk->spwnd == NULL) {
        _PostThreadMessage(
                phk->pti, WM_HOTKEY, phk->id,
                MAKELONG(LOWORD(fsModifiers), vk));
    } else {
        if (phk->spwnd == PWND_INPUTOWNER) {
            if (gpqForeground != NULL) {
                pwnd = gpqForeground->spwndFocus;
            } else {
                return FALSE;
            }

        } else {
            pwnd = phk->spwnd;
        }

        if (pwnd) {
            if (pwnd == pwnd->head.rpdesk->pDeskInfo->spwndShell && phk->id == SC_TASKLIST) {
                _PostMessage(pwnd, WM_SYSCOMMAND, SC_TASKLIST, 0);
            } else {
                _PostMessage(pwnd, WM_HOTKEY, phk->id, MAKELONG(LOWORD(fsModifiers), vk));
            }
        }
    }

    /*
     * If this is a Modifier-Only hotkey, let the modifier break through
     * by returning FALSE, otherwise we will have modifier keys stuck down.
     */
    return (fsModOnlyHotkey == 0);
}
Exemple #6
0
UINT xxxArrangeIconicWindows(
    PWND pwnd)
{
    PBWL pbwl;
    PSMWP psmwp;
    PWND pwndTest, pwndSort, pwndSwitch;
    HWND *phwnd, *phwndSort;
    CHECKPOINT *pcp, *pcpSort;
    POINT ptSort, ptSrc;
    WORD  nIcons = 0;
    RECT  rc;
    POINT ptMin;
    int   xOrg, yOrg;
    int   dx, dy;
    int   dxSlot, dySlot;
    int   cIconsPerPass, iIconPass;
    BOOL  fHorizontal, fBreak;
    TL tlpwndTest;
    BOOL fHideMe;

    CheckLock(pwnd);

    /*
     * Create a window list of all children of pwnd
     */
    if ((pbwl = BuildHwndList(pwnd->spwndChild, BWL_ENUMLIST, NULL)) == NULL)
        return 0;

    fHideMe = IsTrayWindow(pwnd->spwndChild);

    //
    // Put these into local vars for efficiency (see ParkIcon())
    //
    dxSlot = SYSMET(CXMINSPACING);
    dySlot = SYSMET(CYMINSPACING);

    //
    // We need to adjust the client rectangle if the parent has scrollbars.
    //
    GetRealClientRect(pwnd, &rc, GRC_SCROLLS);

    /*
     * find all icons
     */
    pwndSwitch = RevalidateHwnd(ghwndSwitch);
    for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) {
        if (((pwndTest = RevalidateHwnd(*phwnd)) == NULL) ||
                !TestWF(pwndTest , WFVISIBLE) ||
                pwndTest == pwndSwitch ||
                (pcp = (CHECKPOINT *)_GetProp(pwndTest, PROP_CHECKPOINT,
                        PROPF_INTERNAL)) == NULL) {
            *phwnd = NULL;
            continue;
        }

        if (!TestWF(pwndTest, WFMINIMIZED)) {
            pcp->fMinInitialized = FALSE;
            pcp->ptMin.x = pcp->ptMin.y = -1;
            *phwnd = NULL;
            continue;
        }

        /*
         * inc count of icons
         */
        nIcons++;

        /*
         * we will park in default position again...
         */
        pcp->fDragged = FALSE;

        /*
         * ensure the original position is up to date
         */
        pcp->ptMin.x = pwndTest->rcWindow.left - pwnd->rcClient.left;
        pcp->ptMin.y = pwndTest->rcWindow.top - pwnd->rcClient.top;

        // Slide into the nearest row or column
        switch (SYSMET(ARRANGE) & ~ARW_HIDE) {
            case ARW_TOPLEFT | ARW_RIGHT:
            case ARW_TOPRIGHT | ARW_LEFT:
                // Slide into top row
                pcp->ptMin.y += dySlot / 2;
                pcp->ptMin.y -= pcp->ptMin.y % dySlot;
                break;

            case ARW_TOPLEFT | ARW_DOWN:
            case ARW_BOTTOMLEFT | ARW_UP:
                // Slide into left column
                pcp->ptMin.x += dxSlot / 2;
                pcp->ptMin.x -= pcp->ptMin.x % dxSlot;
                break;

            case ARW_BOTTOMLEFT | ARW_RIGHT:
            case ARW_BOTTOMRIGHT | ARW_LEFT:
                // Slide into bottom row
                pcp->ptMin.y = rc.bottom - pcp->ptMin.y;
                pcp->ptMin.y += dySlot / 2;
                pcp->ptMin.y -= pcp->ptMin.y % dySlot;
                pcp->ptMin.y = rc.bottom - pcp->ptMin.y;
                break;

            case ARW_BOTTOMRIGHT | ARW_UP:
            case ARW_TOPRIGHT | ARW_DOWN:
                // Slide into right column
                pcp->ptMin.x = rc.right - pcp->ptMin.x;
                pcp->ptMin.x += dxSlot / 2;
                pcp->ptMin.x -= pcp->ptMin.x % dxSlot;
                pcp->ptMin.x = rc.right - pcp->ptMin.x;
                break;
        }
    }

    if (nIcons == 0) {

        /*
         * no icons were found...  break out
         */
        FreeHwndList(pbwl);
        return 0;
    }

    if (fHideMe) {
        ptMin.x = WHERE_NOONE_CAN_SEE_ME;
        ptMin.y = WHERE_NOONE_CAN_SEE_ME;
        goto JustParkEm;
    }

    //
    // Get gravity && move vars
    //
    if (SYSMET(ARRANGE) & ARW_STARTRIGHT) {
        // Starting on right side
        ptMin.x = xOrg = rc.right - dxSlot;
        dx = -dxSlot;
    } else {
        // Starting on left
        ptMin.x = xOrg = rc.left + DX_GAP;
        dx = dxSlot;
    }

    if (SYSMET(ARRANGE) & ARW_STARTTOP) {
        // Starting on top
        ptMin.y = yOrg = rc.top + DY_GAP;
        dy = dySlot;
    } else {
        // Starting on bottom
        ptMin.y = yOrg = rc.bottom - dySlot;
        dy = -dySlot;
    }

    //
    // Get arrange dir
    //
    fHorizontal = ( (SYSMET(ARRANGE) & ARW_DOWN) ? FALSE : TRUE );

    iIconPass = fHorizontal ? (rc.right / dxSlot) : (rc.bottom / dySlot);
    cIconsPerPass = iIconPass = max(1, iIconPass);

    /*
     * insertion sort of windows by y, and by x within a row.
     */
    for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) {

        /*
         * Check for 0 (window was not icon) and
         * Check for invalid HWND (window has been destroyed)
         */
        if (*phwnd == NULL || (pwndTest = RevalidateHwnd(*phwnd)) == NULL)
            continue;

        pcp = (CHECKPOINT *)_GetProp(pwndTest, PROP_CHECKPOINT,
                PROPF_INTERNAL);
        ptSrc = pcp->ptMin;

        fBreak = FALSE;
        for (phwndSort = pbwl->rghwnd; phwndSort < phwnd; phwndSort++) {
            if (*phwndSort == NULL ||
                    (pwndSort = RevalidateHwnd(*phwndSort)) == NULL)
                continue;

            pcpSort = (CHECKPOINT*)_GetProp(pwndSort, PROP_CHECKPOINT,
                    PROPF_INTERNAL);

            ptSort = pcpSort->ptMin;

            //
            // Is this the position in which to sort this min window?
            //
            switch (SYSMET(ARRANGE) & ~ARW_HIDE) {
                case ARW_BOTTOMLEFT | ARW_RIGHT:
                    // Lower left, moving horizontally
                    if (((ptSort.y == ptSrc.y) && (ptSort.x > ptSrc.x)) ||
                        (ptSort.y < ptSrc.y))
                        fBreak = TRUE;
                    break;

                case ARW_BOTTOMLEFT | ARW_UP:
                    // Lower left, moving vertically
                    if (((ptSort.x == ptSrc.x) && (ptSort.y < ptSrc.y)) ||
                        (ptSort.x > ptSrc.x))
                        fBreak = TRUE;
                    break;

                case ARW_BOTTOMRIGHT | ARW_LEFT:
                    // Lower right, moving horizontally
                    if (((ptSort.y == ptSrc.y) && (ptSort.x < ptSrc.x)) ||
                        (ptSort.y < ptSrc.y))
                        fBreak = TRUE;
                    break;

                case ARW_BOTTOMRIGHT | ARW_UP:
                    // Lower right, moving vertically
                    if (((ptSort.x == ptSrc.x) && (ptSort.y < ptSrc.y)) ||
                        (ptSort.x < ptSrc.x))
                        fBreak = TRUE;
                    break;

                case ARW_TOPLEFT | ARW_RIGHT:
                    // Top left, moving horizontally
                    if (((ptSort.y == ptSrc.y) && (ptSort.x > ptSrc.x)) ||
                        (ptSort.y > ptSrc.y))
                        fBreak = TRUE;
                    break;

                case ARW_TOPLEFT | ARW_DOWN:
                    // Top left, moving vertically
                    if (((ptSort.x == ptSrc.x) && (ptSort.y > ptSrc.y)) ||
                        (ptSort.x > ptSrc.x))
                        fBreak = TRUE;
                    break;

                case ARW_TOPRIGHT | ARW_LEFT:
                    // Top right, moving horizontally
                    if (((ptSort.y == ptSrc.y) && (ptSort.x < ptSrc.x)) ||
                        (ptSort.y > ptSrc.y))
                        fBreak = TRUE;
                    break;

                case ARW_TOPRIGHT | ARW_DOWN:
                    // Top right, moving vertically
                    if (((ptSort.x == ptSrc.x) && (ptSort.y > ptSrc.y)) ||
                        (ptSort.x < ptSrc.x))
                        fBreak = TRUE;
                    break;
            }

            if (fBreak)
                break;
        }

        /*
         * insert the window at this position by sliding the rest up.
         * LATER IanJa, use hwnd intermediate variables, avoid PW() & HW()
         */
        while (phwndSort < phwnd) {
            pwndSort = PW(*phwndSort);
            *phwndSort = HW(pwndTest);
            pwndTest = pwndSort;
            phwndSort++;
        }

        /*
         * replace the window handle in the original position
         */
        *phwnd = HW(pwndTest);
    }

    //
    // Now park the icons.
    //

JustParkEm:

    for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) {
        if (*phwnd == NULL || (pwndTest = RevalidateHwnd(*phwnd)) == NULL)
            continue;

        if (fHideMe) {
            pcp = (CHECKPOINT *)_GetProp(pwndTest, PROP_CHECKPOINT,
                PROPF_INTERNAL);
            if (pcp != NULL) {
                pcp->fMinInitialized = TRUE;
                pcp->ptMin.x = ptMin.x;
                pcp->ptMin.y = ptMin.y;
            }

            continue;
        }

        pcp = (CHECKPOINT *)_GetProp(pwndTest, PROP_CHECKPOINT,
                PROPF_INTERNAL);
        if (pcp != NULL) {
            pcp->fMinInitialized = TRUE;
            pcp->ptMin.x = ptMin.x;
            pcp->ptMin.y = ptMin.y;
        }

        // Setup to process the next position
        if (--iIconPass <= 0) {
            // Need to setup next pass
            iIconPass = cIconsPerPass;

            if (fHorizontal) {
                ptMin.x = xOrg;
                ptMin.y += dy;
            } else {
                ptMin.x += dx;
                ptMin.y = yOrg;
            }
        } else {
            // Same pass
            if (fHorizontal)
                ptMin.x += dx;
            else
                ptMin.y += dy;
        }
    }

    psmwp = _BeginDeferWindowPos(2 * nIcons);
    if (psmwp == NULL)
        goto ParkExit;

    for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) {

        /*
         * Check for a NULL (window has gone away)
         */
        if (*phwnd == NULL || (pwndTest = RevalidateHwnd(*phwnd)) == NULL)
            continue;

        pcp = (CHECKPOINT *)_GetProp(pwndTest, PROP_CHECKPOINT,
                PROPF_INTERNAL);


        ThreadLockAlways(pwndTest, &tlpwndTest);

        psmwp = _DeferWindowPos(psmwp, pwndTest, NULL,
                pcp->ptMin.x, pcp->ptMin.y, rgptMinMaxWnd[MMI_MINSIZE].x, rgptMinMaxWnd[MMI_MINSIZE].y,
                SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS);

        ThreadUnlock(&tlpwndTest);

        if (psmwp == NULL)
            break;
    }
    if (psmwp != NULL) {
        /*
         * Make the swp async so we don't hang waiting for hung apps.
         */
        xxxEndDeferWindowPosEx(psmwp, TRUE);
    }

ParkExit:
    FreeHwndList(pbwl);
    return nIcons;
}