/*-
* Copyright (c) 2001, 2004 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by UCHIYAMA Yasushi.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
RootWindow::~RootWindow()
{
if (_boot_button)
delete _boot_button;
if (_cancel_button)
delete _cancel_button;
if (_progress_bar)
delete _progress_bar;
if (_main)
delete _main;
if (_option)
delete _option;
if (_console)
delete _console;
if (_base)
delete _base;
}
BOOL
RootWindow::create(LPCREATESTRUCT aux)
{
TCHAR app_name[32];
// Root window's create don't called by Window Procedure.
// so aux is NULL
HINSTANCE inst = _app._instance;
TCHAR *wc_name = reinterpret_cast <TCHAR *>
(LoadString(inst, IDS_HPCMENU, 0, 0));
wsprintf(app_name, TEXT("%s Build %d"), wc_name, HPCBOOT_BUILD_NUMBER);
if (_main && IsWindowVisible(_main->_window))
tab_window = _main->_window;
else if (_option && IsWindowVisible(_option->_window))
tab_window = _option->_window;
else if (_console && IsWindowVisible(_console->_window))
tab_window = _console->_window;
if (focusManagerHook(msg, tab_window))
return TRUE;
return IsDialogMessage(tab_window, &msg);
}
//
// XXX !!! XXX !!! XXX !!! XXX !!!
//
// WinCE 2.11 doesn't support keyboard focus traversal for nested
// dialogs, so implement poor man focus manager for our root window.
// This function handles focus transition from boot/cancel buttons.
// Transition from the tab-control is done on WM_NOTIFY/TCN_KEYDOWN
// above.
//
// XXX: This is a very smplistic implementation that doesn't handle
// <TAB> auto-repeat count in LOWORD(msg.lParam), WS_GROUP, etc...
//
BOOL
RootWindow::focusManagerHook(MSG &msg, HWND tab_window)
{
HWND next, prev;
HWND dst = 0;
LRESULT dlgcode = 0;
if (msg.message != WM_KEYDOWN)
return FALSE;
if (msg.hwnd == _boot_button->_window) {
next = _cancel_button->_window;
prev = _base->_window;
} else if (msg.hwnd == _cancel_button->_window) {
next = _base->_window;
prev = _boot_button->_window;
} else if (tab_window == 0) {
return FALSE;
} else {
// last focusable control in the tab_window (XXX: WS_GROUP?)
HWND last = GetNextDlgTabItem(tab_window, NULL, TRUE);
if (last == NULL ||
!(last == msg.hwnd || IsChild(last, msg.hwnd)))
return FALSE;
dlgcode = SendMessage(last, WM_GETDLGCODE, NULL, (LPARAM)&msg);
next = _base->_window; // out of the tab window
prev = 0; // let IsDialogMessage handle it
}
#if 0 // XXX: breaks tabbing out of the console window
if (dlgcode & DLGC_WANTALLKEYS)
return FALSE;
#endif
switch (msg.wParam) {
case VK_RIGHT:
case VK_DOWN:
if (dlgcode & DLGC_WANTARROWS)
return FALSE;
dst = next;
break;
case VK_LEFT:
case VK_UP:
if (dlgcode & DLGC_WANTARROWS)
return FALSE;
dst = prev;
break;
case VK_TAB:
if (dlgcode & DLGC_WANTTAB)
return FALSE;
if (GetKeyState(VK_SHIFT) & 0x8000) // Shift-Tab
dst = prev;
else
dst = next;
break;
}
if (dst == 0)
return FALSE;
SetFocus(dst);
return TRUE;
}
void
RootWindow::progress(const char *msg)
{
if (msg)
Console::Instance()->print(TEXT("[progress] %S\n"), msg);