1 /* -*-C++-*- $NetBSD: menu.cpp,v 1.10 2005/12/11 12:17:28 christos Exp $ */
4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
34 #include <res/resource.h>
35 #include <menu/window.h>
36 #include <menu/tabwindow.h>
37 #include <menu/rootwindow.h>
38 #include <machine/bootinfo.h>
39 #include <framebuffer.h>
42 #include <menu/menu.h>
45 TabWindowBase::boot(int id
)
48 HpcMenuInterface
&menu
= HPC_MENU
;
54 menu
._main
= new MainTabWindow(*this, IDC_BASE_MAIN
);
58 menu
._option
= new OptionTabWindow(*this, IDC_BASE_OPTION
);
61 case IDC_BASE_CONSOLE
:
62 menu
._console
= new ConsoleTabWindow(*this, IDC_BASE_CONSOLE
);
77 MainTabWindow::_insert_item(HWND w
, TCHAR
*name
, int id
)
79 int idx
= SendDlgItemMessage(w
, id
, CB_ADDSTRING
, 0,
80 reinterpret_cast <LPARAM
>(name
));
82 SendDlgItemMessage(w
, IDC_MAIN_DIR
, CB_SETITEMDATA
,
87 MainTabWindow::init(HWND w
)
89 HpcMenuInterface
&menu
= HPC_MENU
;
90 struct HpcMenuInterface::HpcMenuPreferences
&pref
= HPC_PREFERENCE
;
93 // insert myself to tab-control
99 // kernel directory path
100 for (i
= 0; entry
= menu
.dir(i
); i
++)
101 _insert_item(w
, entry
, IDC_MAIN_DIR
);
102 SendDlgItemMessage(w
, IDC_MAIN_DIR
, CB_SETCURSEL
, menu
.dir_default(),
107 Edit_SetText(GetDlgItem(w
, IDC_MAIN_KERNEL
), pref
.kernel_user
?
108 pref
.kernel_user_file
: TEXT("netbsd.gz"));
111 int fs
= pref
.rootfs
+ IDC_MAIN_ROOT_
;
112 _set_check(fs
, TRUE
);
114 _edit_md_root
= GetDlgItem(w
, IDC_MAIN_ROOT_MD_OPS
);
115 Edit_SetText(_edit_md_root
, pref
.rootfs_file
);
116 EnableWindow(_edit_md_root
, fs
== IDC_MAIN_ROOT_MD
? TRUE
: FALSE
);
118 // layout checkbox and editbox.
121 // set default kernel boot options.
122 _set_check(IDC_MAIN_OPTION_A
, pref
.boot_ask_for_name
);
123 _set_check(IDC_MAIN_OPTION_D
, pref
.boot_debugger
);
124 _set_check(IDC_MAIN_OPTION_S
, pref
.boot_single_user
);
125 _set_check(IDC_MAIN_OPTION_V
, pref
.boot_verbose
);
126 _set_check(IDC_MAIN_OPTION_H
, pref
.boot_serial
);
128 // serial console speed.
129 TCHAR
*speed_tab
[] = { L
"9600", L
"19200", L
"115200", 0 };
132 for (TCHAR
**speed
= speed_tab
; *speed
; speed
++, i
++) {
133 _insert_item(w
, *speed
, IDC_MAIN_OPTION_H_SPEED
);
134 if (_wtoi(*speed
) == pref
.serial_speed
)
137 _combobox_serial_speed
= GetDlgItem(_window
, IDC_MAIN_OPTION_H_SPEED
);
138 SendDlgItemMessage(w
, IDC_MAIN_OPTION_H_SPEED
, CB_SETCURSEL
, sel
, 0);
139 EnableWindow(_combobox_serial_speed
, pref
.boot_serial
);
143 MainTabWindow::_platcmp(const void *a
, const void *b
)
145 const MainTabWindow::PlatMap
*pa
=
146 reinterpret_cast <const MainTabWindow::PlatMap
*>(a
);
147 const MainTabWindow::PlatMap
*pb
=
148 reinterpret_cast <const MainTabWindow::PlatMap
*>(b
);
150 return wcscmp(pa
->name
, pb
->name
);
154 MainTabWindow::_sort_platids(HWND w
)
156 HpcMenuInterface
&menu
= HPC_MENU
;
157 MainTabWindow::PlatMap
*p
;
162 for (nids
= 0; menu
.platform_get(nids
); ++nids
)
165 _platmap
= reinterpret_cast <MainTabWindow::PlatMap
*>
166 (malloc(nids
* sizeof(MainTabWindow::PlatMap
)));
168 if (_platmap
== NULL
) {
169 // can't sort, present in the order of definition
170 for (i
= 0; entry
= menu
.platform_get(i
); i
++)
171 _insert_item(w
, entry
, IDC_MAIN_PLATFORM
);
172 SendDlgItemMessage(w
, IDC_MAIN_PLATFORM
, CB_SETCURSEL
,
173 menu
.platform_default(), 0);
177 for (i
= 0, p
= _platmap
; i
< nids
; ++i
, ++p
) {
179 p
->name
= menu
.platform_get(i
);
182 qsort(_platmap
, nids
, sizeof(MainTabWindow::PlatMap
),
183 MainTabWindow::_platcmp
);
185 int defid
= menu
.platform_default();
187 for (i
= 0; i
< nids
; ++i
) {
188 if (_platmap
[i
].id
== defid
)
190 _insert_item(w
, _platmap
[i
].name
, IDC_MAIN_PLATFORM
);
192 SendDlgItemMessage(w
, IDC_MAIN_PLATFORM
, CB_SETCURSEL
, defitem
, 0);
196 MainTabWindow::_item_to_platid(int idx
)
198 if (_platmap
== NULL
)
201 return _platmap
[idx
].id
;
205 MainTabWindow::layout()
207 // inquire display size.
209 int width
= GetDeviceCaps(hdc
, HORZRES
);
210 int height
= GetDeviceCaps(hdc
, VERTRES
);
217 } else if (height
<= 240) {
224 h
= GetDlgItem(_window
, IDC_MAIN_OPTION_V
);
225 SetWindowPos(h
, 0, x
, y
, 120, 10, SWP_NOSIZE
| SWP_NOZORDER
);
226 h
= GetDlgItem(_window
, IDC_MAIN_OPTION_S
);
227 SetWindowPos(h
, 0, x
, y
+ 20, 120, 10, SWP_NOSIZE
| SWP_NOZORDER
);
228 h
= GetDlgItem(_window
, IDC_MAIN_OPTION_A
);
229 SetWindowPos(h
, 0, x
, y
+ 40, 120, 10, SWP_NOSIZE
| SWP_NOZORDER
);
230 h
= GetDlgItem(_window
, IDC_MAIN_OPTION_D
);
231 SetWindowPos(h
, 0, x
, y
+ 60, 120, 10, SWP_NOSIZE
| SWP_NOZORDER
);
232 h
= GetDlgItem(_window
, IDC_MAIN_OPTION_H
);
233 SetWindowPos(h
, 0, x
, y
+ 80, 120, 10, SWP_NOSIZE
| SWP_NOZORDER
);
234 h
= GetDlgItem(_window
, IDC_MAIN_OPTION_H_SPEED
);
235 SetWindowPos(h
, 0, x
+ 100, y
+ 80, 120, 10, SWP_NOSIZE
| SWP_NOZORDER
);
241 HpcMenuInterface
&menu
= HPC_MENU
;
242 struct HpcMenuInterface::HpcMenuPreferences
&pref
= HPC_PREFERENCE
;
244 HWND w
= GetDlgItem(_window
, IDC_MAIN_DIR
);
245 ComboBox_GetText(w
, pref
.dir_user_path
, MAX_PATH
);
246 pref
.dir_user
= TRUE
;
247 w
= GetDlgItem(_window
, IDC_MAIN_KERNEL
);
248 Edit_GetText(w
, pref
.kernel_user_file
, MAX_PATH
);
249 pref
.kernel_user
= TRUE
;
251 int i
= ComboBox_GetCurSel(GetDlgItem(_window
, IDC_MAIN_PLATFORM
));
252 menu
.platform_set(_item_to_platid(i
));
254 if (_is_checked(IDC_MAIN_ROOT_WD
))
256 else if (_is_checked(IDC_MAIN_ROOT_SD
))
258 else if (_is_checked(IDC_MAIN_ROOT_MD
))
260 else if (_is_checked(IDC_MAIN_ROOT_NFS
))
263 pref
.boot_ask_for_name
= _is_checked(IDC_MAIN_OPTION_A
);
264 pref
.boot_debugger
= _is_checked(IDC_MAIN_OPTION_D
);
265 pref
.boot_verbose
= _is_checked(IDC_MAIN_OPTION_V
);
266 pref
.boot_single_user
= _is_checked(IDC_MAIN_OPTION_S
);
267 pref
.boot_serial
= _is_checked(IDC_MAIN_OPTION_H
);
268 Edit_GetText(_edit_md_root
, pref
.rootfs_file
, MAX_PATH
);
271 ComboBox_GetText(_combobox_serial_speed
, tmpbuf
, 8);
272 pref
.serial_speed
= _wtoi(tmpbuf
);
276 MainTabWindow::command(int id
, int msg
)
279 case IDC_MAIN_OPTION_H
:
280 EnableWindow(_combobox_serial_speed
,
281 _is_checked(IDC_MAIN_OPTION_H
));
283 case IDC_MAIN_ROOT_WD
:
285 case IDC_MAIN_ROOT_SD
:
287 case IDC_MAIN_ROOT_MD
:
289 case IDC_MAIN_ROOT_NFS
:
290 EnableWindow(_edit_md_root
, _is_checked(IDC_MAIN_ROOT_MD
));
298 OptionTabWindow::init(HWND w
)
300 struct HpcMenuInterface::HpcMenuPreferences
&pref
= HPC_PREFERENCE
;
304 TabWindow::init(_window
);
305 _spin_edit
= GetDlgItem(_window
, IDC_OPT_AUTO_INPUT
);
306 _spin
= CreateUpDownControl(WS_CHILD
| WS_BORDER
| WS_VISIBLE
|
307 UDS_SETBUDDYINT
| UDS_ALIGNRIGHT
, 80, 0, 50, 50, _window
,
308 IDC_OPT_AUTO_UPDOWN
, _app
._instance
, _spin_edit
, 60, 1, 30);
309 BOOL onoff
= pref
.auto_boot
? TRUE
: FALSE
;
310 EnableWindow(_spin_edit
, onoff
);
311 EnableWindow(_spin
, onoff
);
313 SET_CHECK(AUTO
, pref
.auto_boot
);
314 if (pref
.auto_boot
) {
316 wsprintf(tmp
, TEXT("%d"), pref
.auto_boot
);
317 Edit_SetText(_spin_edit
, tmp
);
319 SET_CHECK(VIDEO
, pref
.reverse_video
);
320 SET_CHECK(PAUSE
, pref
.pause_before_boot
);
321 SET_CHECK(DEBUG
, pref
.load_debug_info
);
322 SET_CHECK(SAFETY
, pref
.safety_message
);
323 Edit_SetText(GetDlgItem(w
, IDC_OPT_EXTKOPT
), pref
.boot_extra
);
327 OptionTabWindow::command(int id
, int msg
)
331 if (IS_CHECKED(AUTO
)) {
332 EnableWindow(_spin_edit
, TRUE
);
333 EnableWindow(_spin
, TRUE
);
335 EnableWindow(_spin_edit
, FALSE
);
336 EnableWindow(_spin
, FALSE
);
343 OptionTabWindow::get()
346 struct HpcMenuInterface::HpcMenuPreferences
&pref
= HPC_PREFERENCE
;
347 if (IS_CHECKED(AUTO
)) {
349 Edit_GetText(_spin_edit
, tmp
, 32);
350 pref
.auto_boot
= _wtoi(tmp
);
353 pref
.reverse_video
= IS_CHECKED(VIDEO
);
354 pref
.pause_before_boot
= IS_CHECKED(PAUSE
);
355 pref
.load_debug_info
= IS_CHECKED(DEBUG
);
356 pref
.safety_message
= IS_CHECKED(SAFETY
);
358 w
= GetDlgItem(_window
, IDC_OPT_EXTKOPT
);
359 Edit_GetText(w
, pref
.boot_extra
, MAX_BOOT_STR
);
369 ConsoleTabWindow::print(TCHAR
*buf
, BOOL force_display
)
378 if (_logfile
== INVALID_HANDLE_VALUE
&& !_open_log_file()) {
380 _set_check(IDC_CONS_FILESAVE
, _filesave
);
381 EnableWindow(_filename_edit
, _filesave
);
386 for (int i
= 0; *buf
!= TEXT('\0'); buf
++) {
388 WriteFile(_logfile
, &c
, 1, &cnt
, 0);
390 FlushFileBuffers(_logfile
);
395 // count number of '\n'
396 for (cr
= 0, p
= buf
; p
= wcschr(p
, TEXT('\n')); cr
++, p
++)
399 // total length of new buffer ('\n' -> "\r\n" + '\0')
400 size_t sz
= (wcslen(buf
) + cr
+ 1) * sizeof(TCHAR
);
402 p
= reinterpret_cast <TCHAR
*>(malloc(sz
));
408 while (*buf
!= TEXT('\0')) {
416 // append the text and scroll
417 int end
= Edit_GetTextLength(_edit
);
418 Edit_SetSel(_edit
, end
, end
);
419 Edit_ReplaceSel(_edit
, p
);
420 Edit_ScrollCaret(_edit
);
427 ConsoleTabWindow::init(HWND w
)
429 // at this time _window is NULL.
430 // use argument of window procedure.
432 _edit
= GetDlgItem(w
, IDC_CONS_EDIT
);
433 MoveWindow(_edit
, 5, 60, _rect
.right
- _rect
.left
- 10,
434 _rect
.bottom
- _rect
.top
- 60, TRUE
);
435 Edit_FmtLines(_edit
, TRUE
);
438 _filename_edit
= GetDlgItem(w
, IDC_CONS_FILENAME
);
440 Edit_SetText(_filename_edit
, L
"bootlog.txt");
441 EnableWindow(_filename_edit
, _filesave
);
445 ConsoleTabWindow::command(int id
, int msg
)
447 HpcMenuInterface
&menu
= HPC_MENU
;
448 struct HpcMenuInterface::cons_hook_args
*hook
= 0;
452 case IDC_CONS_FILESAVE
:
453 _filesave
= _is_checked(IDC_CONS_FILESAVE
);
454 EnableWindow(_filename_edit
, _filesave
);
471 bit
= 1 << (id
- IDC_CONS_CHK_
);
472 if (SendDlgItemMessage(_window
, id
, BM_GETCHECK
, 0, 0))
473 menu
._cons_parameter
|= bit
;
475 menu
._cons_parameter
&= ~bit
;
484 hook
= &menu
._cons_hook
[id
- IDC_CONS_BTN_
];
486 hook
->func(hook
->arg
, menu
._cons_parameter
);
493 ConsoleTabWindow::_open_log_file()
495 TCHAR path
[MAX_PATH
];
496 TCHAR filename
[MAX_PATH
];
497 TCHAR filepath
[MAX_PATH
];
499 if (!_find_pref_dir(path
)) {
500 print(L
"couldn't find temporary directory.\n", TRUE
);
504 Edit_GetText(_filename_edit
, filename
, MAX_PATH
);
505 wsprintf(filepath
, TEXT("\\%s\\%s"), path
, filename
);
506 _logfile
= CreateFile(filepath
, GENERIC_WRITE
, 0, 0,
507 CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, 0);
508 if (_logfile
== INVALID_HANDLE_VALUE
)
511 wsprintf(path
, TEXT("log file is %s\n"), filepath
);
521 _find_pref_dir(TCHAR
*path
)
526 lstrcpy(path
, TEXT("\\*.*"));
527 find
= FindFirstFile(path
, &fd
);
529 if (find
!= INVALID_HANDLE_VALUE
) {
531 int attr
= fd
.dwFileAttributes
;
532 if ((attr
& FILE_ATTRIBUTE_DIRECTORY
) &&
533 (attr
& FILE_ATTRIBUTE_TEMPORARY
)) {
534 wcscpy(path
, fd
.cFileName
);
538 } while (FindNextFile(find
, &fd
));