Home | History | Annotate | Line # | Download | only in menu
      1  1.13  nonaka /* -*-C++-*-	$NetBSD: menu.cpp,v 1.13 2011/11/23 15:49:58 nonaka Exp $	*/
      2   1.1     uch 
      3   1.1     uch /*-
      4   1.1     uch  * Copyright (c) 2001 The NetBSD Foundation, Inc.
      5   1.1     uch  * All rights reserved.
      6   1.1     uch  *
      7   1.1     uch  * This code is derived from software contributed to The NetBSD Foundation
      8   1.1     uch  * by UCHIYAMA Yasushi.
      9   1.1     uch  *
     10   1.1     uch  * Redistribution and use in source and binary forms, with or without
     11   1.1     uch  * modification, are permitted provided that the following conditions
     12   1.1     uch  * are met:
     13   1.1     uch  * 1. Redistributions of source code must retain the above copyright
     14   1.1     uch  *    notice, this list of conditions and the following disclaimer.
     15   1.1     uch  * 2. Redistributions in binary form must reproduce the above copyright
     16   1.1     uch  *    notice, this list of conditions and the following disclaimer in the
     17   1.1     uch  *    documentation and/or other materials provided with the distribution.
     18   1.1     uch  *
     19   1.1     uch  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20   1.1     uch  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21   1.1     uch  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22   1.1     uch  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23   1.1     uch  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24   1.1     uch  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25   1.1     uch  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26   1.1     uch  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27   1.1     uch  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28   1.1     uch  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29   1.1     uch  * POSSIBILITY OF SUCH DAMAGE.
     30   1.1     uch  */
     31   1.1     uch 
     32   1.1     uch #include <hpcmenu.h>
     33   1.1     uch #include <hpcboot.h>
     34   1.1     uch #include <res/resource.h>
     35   1.1     uch #include <menu/window.h>
     36   1.1     uch #include <menu/tabwindow.h>
     37   1.1     uch #include <menu/rootwindow.h>
     38   1.1     uch #include <machine/bootinfo.h>
     39   1.1     uch #include <framebuffer.h>
     40   1.1     uch #include <console.h>
     41   1.1     uch 
     42   1.1     uch #include <menu/menu.h>
     43   1.1     uch 
     44  1.12  nonaka #define SCALEX(x) (((x) * dpix) / 96/*DPI*/)
     45  1.12  nonaka #define SCALEY(y) (((y) * dpiy) / 96/*DPI*/)
     46  1.12  nonaka #define UNSCALEX(x) (((x) * 96) / dpix)
     47  1.12  nonaka #define UNSCALEY(y) (((y) * 96) / dpiy)
     48  1.12  nonaka 
     49   1.1     uch TabWindow *
     50   1.1     uch TabWindowBase::boot(int id)
     51   1.1     uch {
     52   1.1     uch 	TabWindow *w = NULL;
     53   1.1     uch 	HpcMenuInterface &menu = HPC_MENU;
     54   1.1     uch 
     55   1.1     uch 	switch(id) {
     56   1.1     uch 	default:
     57   1.1     uch 		break;
     58   1.1     uch 	case IDC_BASE_MAIN:
     59   1.1     uch 		menu._main = new MainTabWindow(*this, IDC_BASE_MAIN);
     60   1.1     uch 		w = menu._main;
     61   1.1     uch 		break;
     62   1.1     uch 	case IDC_BASE_OPTION:
     63   1.1     uch 		menu._option = new OptionTabWindow(*this, IDC_BASE_OPTION);
     64   1.1     uch 		w = menu._option;
     65   1.1     uch 		break;
     66   1.1     uch 	case IDC_BASE_CONSOLE:
     67   1.1     uch 		menu._console = new ConsoleTabWindow(*this, IDC_BASE_CONSOLE);
     68   1.1     uch 		w = menu._console;
     69   1.1     uch 		break;
     70   1.1     uch 	}
     71   1.1     uch 
     72   1.1     uch 	if (w)
     73   1.1     uch 		w->create(0);
     74   1.1     uch 
     75   1.1     uch 	return w;
     76   1.1     uch }
     77   1.1     uch 
     78   1.1     uch //
     79   1.1     uch // Main window
     80   1.1     uch //
     81   1.1     uch void
     82   1.1     uch MainTabWindow::_insert_item(HWND w, TCHAR *name, int id)
     83   1.1     uch {
     84   1.1     uch 	int idx = SendDlgItemMessage(w, id, CB_ADDSTRING, 0,
     85   1.2     uch 	    reinterpret_cast <LPARAM>(name));
     86   1.1     uch 	if (idx != CB_ERR)
     87   1.1     uch 		SendDlgItemMessage(w, IDC_MAIN_DIR, CB_SETITEMDATA,
     88   1.2     uch 		    idx, _item_idx++);
     89   1.1     uch }
     90   1.1     uch 
     91   1.1     uch void
     92   1.1     uch MainTabWindow::init(HWND w)
     93   1.1     uch {
     94   1.1     uch 	HpcMenuInterface &menu = HPC_MENU;
     95   1.1     uch 	struct HpcMenuInterface::HpcMenuPreferences &pref = HPC_PREFERENCE;
     96   1.1     uch 
     97   1.1     uch 	_window = w;
     98   1.1     uch 	// insert myself to tab-control
     99   1.1     uch 	TabWindow::init(w);
    100   1.1     uch 
    101   1.1     uch 	// setup child.
    102   1.1     uch 	TCHAR *entry;
    103   1.1     uch 	int i;
    104   1.1     uch 	// kernel directory path
    105   1.1     uch 	for (i = 0; entry = menu.dir(i); i++)
    106   1.1     uch 		_insert_item(w, entry, IDC_MAIN_DIR);
    107   1.1     uch 	SendDlgItemMessage(w, IDC_MAIN_DIR, CB_SETCURSEL, menu.dir_default(),
    108   1.2     uch 	    0);
    109   1.1     uch 	// platform
    110   1.9     uwe 	_sort_platids(w);
    111   1.1     uch 	// kernel file name.
    112   1.1     uch 	Edit_SetText(GetDlgItem(w, IDC_MAIN_KERNEL), pref.kernel_user ?
    113   1.2     uch 	    pref.kernel_user_file : TEXT("netbsd.gz"));
    114   1.1     uch 
    115   1.1     uch 	// root file system.
    116   1.1     uch 	int fs = pref.rootfs + IDC_MAIN_ROOT_;
    117   1.1     uch 	_set_check(fs, TRUE);
    118   1.1     uch 
    119   1.1     uch 	_edit_md_root = GetDlgItem(w, IDC_MAIN_ROOT_MD_OPS);
    120   1.1     uch 	Edit_SetText(_edit_md_root, pref.rootfs_file);
    121   1.1     uch 	EnableWindow(_edit_md_root, fs == IDC_MAIN_ROOT_MD ? TRUE : FALSE);
    122   1.1     uch 
    123   1.4     uch 	// layout checkbox and editbox.
    124   1.4     uch 	layout();
    125   1.4     uch 
    126   1.4     uch 	// set default kernel boot options.
    127   1.1     uch 	_set_check(IDC_MAIN_OPTION_A, pref.boot_ask_for_name);
    128   1.3   enami 	_set_check(IDC_MAIN_OPTION_D, pref.boot_debugger);
    129   1.1     uch 	_set_check(IDC_MAIN_OPTION_S, pref.boot_single_user);
    130   1.1     uch 	_set_check(IDC_MAIN_OPTION_V, pref.boot_verbose);
    131   1.1     uch 	_set_check(IDC_MAIN_OPTION_H, pref.boot_serial);
    132   1.1     uch 
    133   1.1     uch 	// serial console speed.
    134   1.1     uch 	TCHAR *speed_tab[] = { L"9600", L"19200", L"115200", 0 };
    135   1.1     uch 	int sel = 0;
    136   1.1     uch 	i = 0;
    137   1.1     uch 	for (TCHAR **speed = speed_tab; *speed; speed++, i++) {
    138   1.1     uch 		_insert_item(w, *speed, IDC_MAIN_OPTION_H_SPEED);
    139   1.1     uch 		if (_wtoi(*speed) == pref.serial_speed)
    140   1.1     uch 			sel = i;
    141   1.1     uch 	}
    142   1.1     uch 	_combobox_serial_speed = GetDlgItem(_window, IDC_MAIN_OPTION_H_SPEED);
    143   1.1     uch 	SendDlgItemMessage(w, IDC_MAIN_OPTION_H_SPEED, CB_SETCURSEL, sel, 0);
    144   1.1     uch 	EnableWindow(_combobox_serial_speed, pref.boot_serial);
    145   1.4     uch }
    146   1.4     uch 
    147   1.9     uwe int
    148   1.9     uwe MainTabWindow::_platcmp(const void *a, const void *b)
    149   1.9     uwe {
    150   1.9     uwe 	const MainTabWindow::PlatMap *pa =
    151   1.9     uwe 		reinterpret_cast <const MainTabWindow::PlatMap *>(a);
    152   1.9     uwe 	const MainTabWindow::PlatMap *pb =
    153   1.9     uwe 		reinterpret_cast <const MainTabWindow::PlatMap *>(b);
    154   1.9     uwe 
    155   1.9     uwe 	return wcscmp(pa->name, pb->name);
    156   1.9     uwe }
    157   1.9     uwe 
    158   1.9     uwe void
    159   1.9     uwe MainTabWindow::_sort_platids(HWND w)
    160   1.9     uwe {
    161   1.9     uwe 	HpcMenuInterface &menu = HPC_MENU;
    162   1.9     uwe 	MainTabWindow::PlatMap *p;
    163   1.9     uwe 	TCHAR *entry;
    164   1.9     uwe 	int nids;
    165   1.9     uwe 	int i;
    166   1.9     uwe 
    167   1.9     uwe 	for (nids = 0; menu.platform_get(nids); ++nids)
    168   1.9     uwe 		continue;
    169   1.9     uwe 
    170   1.9     uwe 	_platmap = reinterpret_cast <MainTabWindow::PlatMap *>
    171   1.9     uwe 		(malloc(nids * sizeof(MainTabWindow::PlatMap)));
    172   1.9     uwe 
    173   1.9     uwe 	if (_platmap == NULL) {
    174   1.9     uwe 		// can't sort, present in the order of definition
    175   1.9     uwe 		for (i = 0; entry = menu.platform_get(i); i++)
    176   1.9     uwe 			_insert_item(w, entry, IDC_MAIN_PLATFORM);
    177   1.9     uwe 		SendDlgItemMessage(w, IDC_MAIN_PLATFORM, CB_SETCURSEL,
    178   1.9     uwe 				   menu.platform_default(), 0);
    179   1.9     uwe 		return;
    180   1.9     uwe 	}
    181   1.9     uwe 
    182   1.9     uwe 	for (i = 0, p = _platmap; i < nids; ++i, ++p) {
    183   1.9     uwe 		p->id = i;
    184   1.9     uwe 		p->name = menu.platform_get(i);
    185   1.9     uwe 	}
    186   1.9     uwe 
    187   1.9     uwe 	qsort(_platmap, nids, sizeof(MainTabWindow::PlatMap),
    188   1.9     uwe 	      MainTabWindow::_platcmp);
    189   1.9     uwe 
    190   1.9     uwe 	int defid = menu.platform_default();
    191   1.9     uwe 	int defitem = 0;
    192   1.9     uwe 	for (i = 0; i < nids; ++i) {
    193   1.9     uwe 		if (_platmap[i].id == defid)
    194   1.9     uwe 			defitem = i;
    195   1.9     uwe 		_insert_item(w, _platmap[i].name, IDC_MAIN_PLATFORM);
    196   1.9     uwe 	}
    197   1.9     uwe 	SendDlgItemMessage(w, IDC_MAIN_PLATFORM, CB_SETCURSEL, defitem, 0);
    198   1.9     uwe }
    199   1.9     uwe 
    200   1.9     uwe int
    201   1.9     uwe MainTabWindow::_item_to_platid(int idx)
    202   1.9     uwe {
    203   1.9     uwe 	if (_platmap == NULL)
    204   1.9     uwe 		return idx;
    205   1.9     uwe 	else
    206   1.9     uwe 		return _platmap[idx].id;
    207   1.9     uwe }
    208   1.9     uwe 
    209   1.4     uch void
    210   1.4     uch MainTabWindow::layout()
    211   1.4     uch {
    212   1.4     uch 	// inquire display size.
    213   1.4     uch 	HDC hdc = GetDC(0);
    214   1.4     uch 	int width = GetDeviceCaps(hdc, HORZRES);
    215   1.4     uch 	int height = GetDeviceCaps(hdc, VERTRES);
    216  1.12  nonaka 	int dpix = GetDeviceCaps(hdc, LOGPIXELSX);
    217  1.12  nonaka 	int dpiy = GetDeviceCaps(hdc, LOGPIXELSY);
    218   1.4     uch 	ReleaseDC(0, hdc);
    219   1.4     uch 
    220   1.4     uch 	// set origin
    221   1.4     uch 	int x, y;
    222   1.4     uch 	if (width <= 320) {
    223  1.12  nonaka 		x = 5, y = 140;
    224   1.4     uch 	} else if (height <= 240) {
    225   1.4     uch 		x = 250, y = 5;
    226   1.4     uch 	} else {
    227  1.12  nonaka 		x = 5, y = 140;
    228   1.4     uch 	}
    229   1.4     uch 
    230   1.4     uch 	HWND h;
    231   1.4     uch 	h = GetDlgItem(_window, IDC_MAIN_OPTION_V);
    232  1.12  nonaka 	SetWindowPos(h, 0, SCALEX(x), SCALEY(y),
    233  1.12  nonaka 	    SCALEX(120), SCALEY(10), SWP_NOSIZE | SWP_NOZORDER);
    234   1.4     uch 	h = GetDlgItem(_window, IDC_MAIN_OPTION_S);
    235  1.12  nonaka 	SetWindowPos(h, 0, SCALEX(x), SCALEY(y + 20),
    236  1.12  nonaka             SCALEX(120), SCALEY(10), SWP_NOSIZE | SWP_NOZORDER);
    237   1.4     uch 	h = GetDlgItem(_window, IDC_MAIN_OPTION_A);
    238  1.12  nonaka 	SetWindowPos(h, 0, SCALEX(x), SCALEY(y + 40),
    239  1.12  nonaka 	    SCALEX(120), SCALEY(10), SWP_NOSIZE | SWP_NOZORDER);
    240   1.4     uch 	h = GetDlgItem(_window, IDC_MAIN_OPTION_D);
    241  1.12  nonaka 	SetWindowPos(h, 0, SCALEX(x), SCALEY(y + 60),
    242  1.12  nonaka 	    SCALEX(120), SCALEY(10), SWP_NOSIZE | SWP_NOZORDER);
    243   1.4     uch 	h = GetDlgItem(_window, IDC_MAIN_OPTION_H);
    244  1.12  nonaka 	SetWindowPos(h, 0, SCALEX(x), SCALEY(y + 80),
    245  1.12  nonaka 	    SCALEX(120), SCALEY(10), SWP_NOSIZE | SWP_NOZORDER);
    246   1.4     uch 	h = GetDlgItem(_window, IDC_MAIN_OPTION_H_SPEED);
    247  1.12  nonaka 	SetWindowPos(h, 0, SCALEX(x + 100), SCALEY(y + 80),
    248  1.12  nonaka 	    SCALEX(120), SCALEY(10), SWP_NOSIZE | SWP_NOZORDER);
    249   1.1     uch }
    250   1.1     uch 
    251   1.1     uch void
    252   1.1     uch MainTabWindow::get()
    253   1.1     uch {
    254   1.1     uch 	HpcMenuInterface &menu = HPC_MENU;
    255   1.1     uch 	struct HpcMenuInterface::HpcMenuPreferences &pref = HPC_PREFERENCE;
    256   1.1     uch 
    257   1.1     uch 	HWND w = GetDlgItem(_window, IDC_MAIN_DIR);
    258   1.1     uch 	ComboBox_GetText(w, pref.dir_user_path, MAX_PATH);
    259   1.1     uch 	pref.dir_user = TRUE;
    260   1.1     uch 	w = GetDlgItem(_window, IDC_MAIN_KERNEL);
    261   1.1     uch 	Edit_GetText(w, pref.kernel_user_file, MAX_PATH);
    262   1.1     uch 	pref.kernel_user = TRUE;
    263   1.1     uch 
    264   1.1     uch 	int i = ComboBox_GetCurSel(GetDlgItem(_window, IDC_MAIN_PLATFORM));
    265   1.9     uwe 	menu.platform_set(_item_to_platid(i));
    266   1.1     uch 
    267   1.1     uch 	if (_is_checked(IDC_MAIN_ROOT_WD))
    268   1.1     uch 		pref.rootfs = 0;
    269   1.1     uch 	else if (_is_checked(IDC_MAIN_ROOT_SD))
    270   1.1     uch 		pref.rootfs = 1;
    271   1.1     uch 	else if (_is_checked(IDC_MAIN_ROOT_MD))
    272   1.1     uch 		pref.rootfs = 2;
    273   1.1     uch 	else if (_is_checked(IDC_MAIN_ROOT_NFS))
    274   1.1     uch 		pref.rootfs = 3;
    275  1.12  nonaka 	else if (_is_checked(IDC_MAIN_ROOT_DK))
    276  1.12  nonaka 		pref.rootfs = 4;
    277  1.12  nonaka 	else if (_is_checked(IDC_MAIN_ROOT_LD))
    278  1.12  nonaka 		pref.rootfs = 5;
    279   1.1     uch 
    280   1.1     uch 	pref.boot_ask_for_name	= _is_checked(IDC_MAIN_OPTION_A);
    281   1.3   enami 	pref.boot_debugger	= _is_checked(IDC_MAIN_OPTION_D);
    282   1.1     uch 	pref.boot_verbose	= _is_checked(IDC_MAIN_OPTION_V);
    283   1.1     uch 	pref.boot_single_user	= _is_checked(IDC_MAIN_OPTION_S);
    284   1.1     uch 	pref.boot_serial	= _is_checked(IDC_MAIN_OPTION_H);
    285   1.1     uch 	Edit_GetText(_edit_md_root, pref.rootfs_file, MAX_PATH);
    286   1.1     uch 
    287   1.1     uch 	TCHAR tmpbuf[8];
    288   1.1     uch 	ComboBox_GetText(_combobox_serial_speed, tmpbuf, 8);
    289   1.1     uch 	pref.serial_speed = _wtoi(tmpbuf);
    290   1.1     uch }
    291   1.1     uch 
    292   1.1     uch void
    293   1.1     uch MainTabWindow::command(int id, int msg)
    294   1.1     uch {
    295   1.1     uch 	switch (id) {
    296   1.1     uch 	case IDC_MAIN_OPTION_H:
    297   1.1     uch 		EnableWindow(_combobox_serial_speed,
    298   1.2     uch 		    _is_checked(IDC_MAIN_OPTION_H));
    299   1.1     uch 		break;
    300   1.1     uch 	case IDC_MAIN_ROOT_WD:
    301   1.1     uch 		/* FALLTHROUGH */
    302   1.1     uch 	case IDC_MAIN_ROOT_SD:
    303   1.1     uch 		/* FALLTHROUGH */
    304   1.1     uch 	case IDC_MAIN_ROOT_MD:
    305   1.1     uch 		/* FALLTHROUGH */
    306   1.1     uch 	case IDC_MAIN_ROOT_NFS:
    307  1.12  nonaka 		/* FALLTHROUGH */
    308  1.12  nonaka 	case IDC_MAIN_ROOT_DK:
    309  1.12  nonaka 		/* FALLTHROUGH */
    310  1.12  nonaka 	case IDC_MAIN_ROOT_LD:
    311   1.1     uch 		EnableWindow(_edit_md_root, _is_checked(IDC_MAIN_ROOT_MD));
    312   1.1     uch 	}
    313   1.1     uch }
    314   1.1     uch 
    315   1.1     uch //
    316   1.1     uch // Option window
    317   1.1     uch //
    318   1.1     uch void
    319   1.1     uch OptionTabWindow::init(HWND w)
    320   1.1     uch {
    321   1.1     uch 	struct HpcMenuInterface::HpcMenuPreferences &pref = HPC_PREFERENCE;
    322  1.12  nonaka 	HDC hdc = GetDC(0);
    323  1.12  nonaka 	int dpix = GetDeviceCaps(hdc, LOGPIXELSX);
    324  1.12  nonaka 	int dpiy = GetDeviceCaps(hdc, LOGPIXELSY);
    325  1.12  nonaka 	ReleaseDC(0, hdc);
    326   1.1     uch 
    327   1.1     uch 	_window = w;
    328   1.1     uch 
    329   1.1     uch 	TabWindow::init(_window);
    330   1.1     uch 	_spin_edit = GetDlgItem(_window, IDC_OPT_AUTO_INPUT);
    331   1.1     uch 	_spin = CreateUpDownControl(WS_CHILD | WS_BORDER | WS_VISIBLE |
    332  1.12  nonaka 	    UDS_SETBUDDYINT | UDS_ALIGNRIGHT,
    333  1.12  nonaka 	    SCALEX(80), SCALEY(0), SCALEX(50), SCALEY(50), _window,
    334   1.2     uch 	    IDC_OPT_AUTO_UPDOWN, _app._instance, _spin_edit, 60, 1, 30);
    335   1.1     uch 	BOOL onoff = pref.auto_boot ? TRUE : FALSE;
    336   1.1     uch 	EnableWindow(_spin_edit, onoff);
    337   1.1     uch 	EnableWindow(_spin, onoff);
    338   1.1     uch 
    339   1.1     uch 	SET_CHECK(AUTO, pref.auto_boot);
    340   1.1     uch 	if (pref.auto_boot) {
    341   1.1     uch 		TCHAR tmp[32];
    342   1.1     uch 		wsprintf(tmp, TEXT("%d"), pref.auto_boot);
    343   1.1     uch 		Edit_SetText(_spin_edit, tmp);
    344   1.1     uch 	}
    345   1.1     uch 	SET_CHECK(VIDEO,	pref.reverse_video);
    346   1.1     uch 	SET_CHECK(PAUSE,	pref.pause_before_boot);
    347   1.1     uch 	SET_CHECK(DEBUG,	pref.load_debug_info);
    348   1.1     uch 	SET_CHECK(SAFETY,	pref.safety_message);
    349   1.5     uch 	Edit_SetText(GetDlgItem(w, IDC_OPT_EXTKOPT), pref.boot_extra);
    350   1.1     uch }
    351   1.1     uch 
    352   1.1     uch void
    353   1.1     uch OptionTabWindow::command(int id, int msg)
    354   1.1     uch {
    355   1.1     uch 	switch (id) {
    356   1.1     uch 	case IDC_OPT_AUTO:
    357   1.1     uch 		if (IS_CHECKED(AUTO)) {
    358   1.1     uch 			EnableWindow(_spin_edit, TRUE);
    359   1.1     uch 			EnableWindow(_spin, TRUE);
    360   1.1     uch 		} else {
    361   1.1     uch 			EnableWindow(_spin_edit, FALSE);
    362   1.1     uch 			EnableWindow(_spin, FALSE);
    363   1.1     uch 		}
    364   1.1     uch 		break;
    365   1.1     uch 	}
    366   1.1     uch }
    367   1.1     uch 
    368   1.1     uch void
    369   1.1     uch OptionTabWindow::get()
    370   1.1     uch {
    371   1.5     uch 	HWND w;
    372   1.1     uch 	struct HpcMenuInterface::HpcMenuPreferences &pref = HPC_PREFERENCE;
    373   1.1     uch 	if (IS_CHECKED(AUTO)) {
    374   1.1     uch 		TCHAR tmp[32];
    375   1.1     uch 		Edit_GetText(_spin_edit, tmp, 32);
    376   1.1     uch 		pref.auto_boot = _wtoi(tmp);
    377   1.1     uch 	} else
    378   1.1     uch 		pref.auto_boot = 0;
    379   1.1     uch 	pref.reverse_video	= IS_CHECKED(VIDEO);
    380   1.1     uch 	pref.pause_before_boot	= IS_CHECKED(PAUSE);
    381   1.1     uch 	pref.load_debug_info	= IS_CHECKED(DEBUG);
    382   1.1     uch 	pref.safety_message	= IS_CHECKED(SAFETY);
    383   1.5     uch 
    384   1.5     uch 	w = GetDlgItem(_window, IDC_OPT_EXTKOPT);
    385   1.5     uch 	Edit_GetText(w, pref.boot_extra, MAX_BOOT_STR);
    386   1.1     uch }
    387   1.1     uch #undef IS_CHECKED
    388   1.1     uch #undef SET_CHECK
    389   1.1     uch 
    390   1.1     uch 
    391   1.1     uch //
    392   1.1     uch // Console window
    393   1.1     uch //
    394   1.1     uch void
    395   1.1     uch ConsoleTabWindow::print(TCHAR *buf, BOOL force_display)
    396   1.1     uch {
    397   1.1     uch 	int cr;
    398   1.1     uch 	TCHAR *p;
    399   1.1     uch 
    400   1.1     uch 	if (force_display)
    401   1.1     uch 		goto display;
    402   1.1     uch 
    403   1.1     uch 	if (_filesave) {
    404   1.1     uch 		if (_logfile == INVALID_HANDLE_VALUE && !_open_log_file()) {
    405   1.1     uch 			_filesave = FALSE;
    406   1.1     uch 			_set_check(IDC_CONS_FILESAVE, _filesave);
    407   1.1     uch 			EnableWindow(_filename_edit, _filesave);
    408   1.1     uch 			goto display;
    409   1.1     uch 		}
    410   1.1     uch 		DWORD cnt;
    411   1.1     uch 		char c;
    412   1.1     uch 		for (int i = 0; *buf != TEXT('\0'); buf++) {
    413   1.1     uch 			c = *buf & 0x7f;
    414   1.1     uch 			WriteFile(_logfile, &c, 1, &cnt, 0);
    415   1.1     uch 		}
    416   1.1     uch 		FlushFileBuffers(_logfile);
    417   1.1     uch 		return;
    418   1.1     uch 	}
    419   1.1     uch 
    420   1.1     uch  display:
    421   1.6     uwe 	// count number of '\n'
    422   1.1     uch 	for (cr = 0, p = buf; p = wcschr(p, TEXT('\n')); cr++, p++)
    423   1.6     uwe 		continue;
    424   1.6     uwe 
    425   1.6     uwe 	// total length of new buffer ('\n' -> "\r\n" + '\0')
    426   1.6     uwe 	size_t sz = (wcslen(buf) + cr + 1) * sizeof(TCHAR);
    427   1.1     uch 
    428   1.1     uch 	p = reinterpret_cast <TCHAR *>(malloc(sz));
    429   1.1     uch 	if (p == NULL)
    430   1.1     uch 		return;
    431   1.1     uch 
    432   1.6     uwe 	// convert newlines
    433   1.6     uwe 	TCHAR *d = p;
    434   1.1     uch 	while (*buf != TEXT('\0')) {
    435   1.1     uch 		TCHAR c = *buf++;
    436   1.1     uch 		if (c == TEXT('\n'))
    437   1.1     uch 			*d++ = TEXT('\r');
    438   1.1     uch 		*d++ = c;
    439   1.1     uch 	}
    440   1.1     uch 	*d = TEXT('\0');
    441   1.6     uwe 
    442   1.6     uwe 	// append the text and scroll
    443   1.6     uwe 	int end = Edit_GetTextLength(_edit);
    444   1.6     uwe 	Edit_SetSel(_edit, end, end);
    445   1.6     uwe 	Edit_ReplaceSel(_edit, p);
    446   1.6     uwe 	Edit_ScrollCaret(_edit);
    447   1.1     uch 	UpdateWindow(_edit);
    448   1.1     uch 
    449   1.1     uch 	free(p);
    450   1.1     uch }
    451   1.1     uch 
    452   1.1     uch void
    453   1.1     uch ConsoleTabWindow::init(HWND w)
    454   1.1     uch {
    455  1.12  nonaka 	HDC hdc = GetDC(0);
    456  1.12  nonaka 	int dpix = GetDeviceCaps(hdc, LOGPIXELSX);
    457  1.12  nonaka 	int dpiy = GetDeviceCaps(hdc, LOGPIXELSY);
    458  1.12  nonaka 	ReleaseDC(0, hdc);
    459  1.12  nonaka 
    460   1.1     uch 	// at this time _window is NULL.
    461   1.1     uch 	// use argument of window procedure.
    462   1.1     uch 	TabWindow::init(w);
    463   1.1     uch 	_edit = GetDlgItem(w, IDC_CONS_EDIT);
    464  1.12  nonaka 	MoveWindow(_edit, SCALEX(5), SCALEY(60),
    465  1.12  nonaka 	    SCALEX(UNSCALEX(_rect.right - _rect.left) - 10),
    466  1.12  nonaka 	    SCALEY(UNSCALEY(_rect.bottom - _rect.top) - 60), TRUE);
    467   1.1     uch 	Edit_FmtLines(_edit, TRUE);
    468   1.7     uwe 
    469   1.1     uch 	// log file.
    470   1.1     uch 	_filename_edit = GetDlgItem(w, IDC_CONS_FILENAME);
    471   1.1     uch 	_filesave = FALSE;
    472   1.1     uch 	Edit_SetText(_filename_edit, L"bootlog.txt");
    473   1.1     uch 	EnableWindow(_filename_edit, _filesave);
    474   1.1     uch }
    475   1.1     uch 
    476   1.1     uch void
    477   1.1     uch ConsoleTabWindow::command(int id, int msg)
    478   1.1     uch {
    479   1.1     uch 	HpcMenuInterface &menu = HPC_MENU;
    480   1.1     uch 	struct HpcMenuInterface::cons_hook_args *hook = 0;
    481   1.1     uch 	int bit;
    482   1.1     uch 
    483   1.1     uch 	switch(id) {
    484   1.1     uch 	case IDC_CONS_FILESAVE:
    485   1.1     uch 		_filesave = _is_checked(IDC_CONS_FILESAVE);
    486   1.1     uch 		EnableWindow(_filename_edit, _filesave);
    487   1.1     uch 		break;
    488   1.1     uch 	case IDC_CONS_CHK0:
    489   1.1     uch 		/* FALLTHROUGH */
    490   1.1     uch 	case IDC_CONS_CHK1:
    491   1.1     uch 		/* FALLTHROUGH */
    492   1.1     uch 	case IDC_CONS_CHK2:
    493   1.1     uch 		/* FALLTHROUGH */
    494   1.1     uch 	case IDC_CONS_CHK3:
    495   1.1     uch 		/* FALLTHROUGH */
    496   1.1     uch 	case IDC_CONS_CHK4:
    497   1.1     uch 		/* FALLTHROUGH */
    498   1.1     uch 	case IDC_CONS_CHK5:
    499   1.1     uch 		/* FALLTHROUGH */
    500   1.1     uch 	case IDC_CONS_CHK6:
    501   1.1     uch 		/* FALLTHROUGH */
    502   1.1     uch 	case IDC_CONS_CHK7:
    503   1.1     uch 		bit = 1 << (id - IDC_CONS_CHK_);
    504   1.1     uch 		if (SendDlgItemMessage(_window, id, BM_GETCHECK, 0, 0))
    505   1.1     uch 			menu._cons_parameter |= bit;
    506   1.1     uch 		else
    507   1.1     uch 			menu._cons_parameter &= ~bit;
    508   1.1     uch 		break;
    509   1.1     uch 	case IDC_CONS_BTN0:
    510   1.1     uch 		/* FALLTHROUGH */
    511   1.1     uch 	case IDC_CONS_BTN1:
    512   1.1     uch 		/* FALLTHROUGH */
    513   1.1     uch 	case IDC_CONS_BTN2:
    514   1.1     uch 		/* FALLTHROUGH */
    515   1.1     uch 	case IDC_CONS_BTN3:
    516   1.1     uch 		hook = &menu._cons_hook[id - IDC_CONS_BTN_];
    517   1.1     uch 		if (hook->func)
    518   1.1     uch 			hook->func(hook->arg, menu._cons_parameter);
    519   1.7     uwe 
    520   1.1     uch 		break;
    521   1.1     uch 	}
    522   1.1     uch }
    523   1.1     uch 
    524   1.1     uch BOOL
    525   1.1     uch ConsoleTabWindow::_open_log_file()
    526   1.1     uch {
    527   1.1     uch 	TCHAR path[MAX_PATH];
    528   1.1     uch 	TCHAR filename[MAX_PATH];
    529   1.1     uch 	TCHAR filepath[MAX_PATH];
    530   1.7     uwe 
    531   1.1     uch 	if (!_find_pref_dir(path)) {
    532   1.1     uch 		print(L"couldn't find temporary directory.\n", TRUE);
    533   1.1     uch 		return FALSE;
    534   1.1     uch 	}
    535   1.1     uch 
    536   1.1     uch 	Edit_GetText(_filename_edit, filename, MAX_PATH);
    537   1.1     uch 	wsprintf(filepath, TEXT("\\%s\\%s"), path, filename);
    538   1.1     uch 	_logfile = CreateFile(filepath, GENERIC_WRITE, 0, 0,
    539   1.2     uch 	    CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
    540   1.1     uch 	if (_logfile == INVALID_HANDLE_VALUE)
    541   1.1     uch 		return FALSE;
    542   1.1     uch 
    543   1.1     uch 	wsprintf(path, TEXT("log file is %s\n"), filepath);
    544   1.1     uch 	print(path, TRUE);
    545   1.7     uwe 
    546   1.1     uch 	return TRUE;
    547   1.1     uch }
    548   1.1     uch 
    549   1.1     uch //
    550   1.1     uch // Common utility
    551   1.1     uch //
    552  1.13  nonaka static BOOL
    553  1.13  nonaka is_ignore_directory(TCHAR *filename)
    554  1.13  nonaka {
    555  1.13  nonaka 	static const TCHAR *dirs[] = {
    556  1.13  nonaka 		// Network (in Japanese)
    557  1.13  nonaka 		(const TCHAR *)"\xcd\x30\xc3\x30\xc8\x30\xef\x30\xfc\x30\xaf\x30\x00\x00",
    558  1.13  nonaka 	};
    559  1.13  nonaka 
    560  1.13  nonaka 	for (int i = 0; i < sizeof(dirs) / sizeof(dirs[0]); i++) {
    561  1.13  nonaka 		if (wcscmp(filename, dirs[i]) == 0) {
    562  1.13  nonaka 			return TRUE;
    563  1.13  nonaka 		}
    564  1.13  nonaka 	}
    565  1.13  nonaka 	return FALSE;
    566  1.13  nonaka }
    567  1.13  nonaka 
    568   1.1     uch BOOL
    569   1.1     uch _find_pref_dir(TCHAR *path)
    570   1.1     uch {
    571   1.1     uch 	WIN32_FIND_DATA fd;
    572   1.1     uch 	HANDLE find;
    573   1.1     uch 
    574   1.1     uch 	lstrcpy(path, TEXT("\\*.*"));
    575   1.1     uch 	find = FindFirstFile(path, &fd);
    576   1.1     uch 
    577   1.1     uch 	if (find != INVALID_HANDLE_VALUE) {
    578   1.1     uch 		do {
    579   1.1     uch 			int attr = fd.dwFileAttributes;
    580   1.1     uch 			if ((attr & FILE_ATTRIBUTE_DIRECTORY) &&
    581  1.13  nonaka 			    (attr & FILE_ATTRIBUTE_TEMPORARY) &&
    582  1.13  nonaka 			    !is_ignore_directory(fd.cFileName)) {
    583   1.1     uch 				wcscpy(path, fd.cFileName);
    584   1.1     uch 				FindClose(find);
    585   1.1     uch 				return TRUE;
    586   1.1     uch 			}
    587   1.1     uch 		} while (FindNextFile(find, &fd));
    588   1.1     uch 	}
    589   1.1     uch 	FindClose(find);
    590   1.1     uch 
    591   1.1     uch 	return FALSE;
    592   1.1     uch }
    593