diff --git a/CREDITS b/CREDITS
index cf2a53e..a357f9c 100644
--- a/CREDITS
+++ b/CREDITS
@@ -4378,6 +4378,12 @@ S: 542 West 112th Street, 5N
 S: New York, New York 10025
 S: USA
 
+N: Masahiro Yamada
+E: masahiroy@kernel.org
+D: Kbuild Maintainer 2017-2025
+D: Kconfig Maintainer 2018-2025
+S: Japan
+
 N: Li Yang
 E: leoli@freescale.com
 D: Freescale Highspeed USB device driver
diff --git a/Documentation/kbuild/kconfig.rst b/Documentation/kbuild/kconfig.rst
index fc4e845..d213c4f 100644
--- a/Documentation/kbuild/kconfig.rst
+++ b/Documentation/kbuild/kconfig.rst
@@ -67,12 +67,12 @@ Environment variables for ``*config``:
     with its value when saving the configuration, instead of using the
     default, ``CONFIG_``.
 
-Environment variables for ``{allyes/allmod/allno/rand}config``:
+Environment variables for ``{allyes/allmod/allno/alldef/rand}config``:
 
 ``KCONFIG_ALLCONFIG``
-    The allyesconfig/allmodconfig/allnoconfig/randconfig variants can also
-    use the environment variable KCONFIG_ALLCONFIG as a flag or a filename
-    that contains config symbols that the user requires to be set to a
+    The allyesconfig/allmodconfig/alldefconfig/allnoconfig/randconfig variants
+    can also use the environment variable KCONFIG_ALLCONFIG as a flag or a
+    filename that contains config symbols that the user requires to be set to a
     specific value.  If KCONFIG_ALLCONFIG is used without a filename where
     KCONFIG_ALLCONFIG == "" or KCONFIG_ALLCONFIG == "1", ``make *config``
     checks for a file named "all{yes/mod/no/def/random}.config"
diff --git a/MAINTAINERS b/MAINTAINERS
index 1b57dd4..833097c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13174,11 +13174,9 @@ F:	mm/kasan/
 F:	scripts/Makefile.kasan
 
 KCONFIG
-M:	Masahiro Yamada <masahiroy@kernel.org>
 L:	linux-kbuild@vger.kernel.org
-S:	Maintained
+S:	Orphan
 Q:	https://patchwork.kernel.org/project/linux-kbuild/list/
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild.git kbuild
 F:	Documentation/kbuild/kconfig*
 F:	scripts/Kconfig.include
 F:	scripts/kconfig/
@@ -13243,13 +13241,12 @@ S:	Maintained
 F:	fs/autofs/
 
 KERNEL BUILD + files below scripts/ (unless maintained elsewhere)
-M:	Masahiro Yamada <masahiroy@kernel.org>
-R:	Nathan Chancellor <nathan@kernel.org>
-R:	Nicolas Schier <nicolas@fjasle.eu>
+M:	Nathan Chancellor <nathan@kernel.org>
+M:	Nicolas Schier <nicolas@fjasle.eu>
 L:	linux-kbuild@vger.kernel.org
-S:	Maintained
+S:	Odd Fixes
 Q:	https://patchwork.kernel.org/project/linux-kbuild/list/
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/kbuild/linux.git
 F:	Documentation/kbuild/
 F:	Makefile
 F:	scripts/*vmlinux*
diff --git a/Makefile b/Makefile
index 98ab343..37e3756 100644
--- a/Makefile
+++ b/Makefile
@@ -549,6 +549,7 @@ LZMA		= lzma
 LZ4		= lz4
 XZ		= xz
 ZSTD		= zstd
+TAR		= tar
 
 CHECKFLAGS     := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
 		  -Wbitwise -Wno-return-void -Wno-unknown-attribute $(CF)
@@ -628,7 +629,7 @@ export RUSTC RUSTDOC RUSTFMT RUSTC_OR_CLIPPY_QUIET RUSTC_OR_CLIPPY BINDGEN
 export HOSTRUSTC KBUILD_HOSTRUSTFLAGS
 export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL
 export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX
-export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD
+export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD TAR
 export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS KBUILD_PROCMACROLDFLAGS LDFLAGS_MODULE
 export KBUILD_USERCFLAGS KBUILD_USERLDFLAGS
 
@@ -1141,7 +1142,7 @@ KBUILD_USERCFLAGS  += $(filter -m32 -m64 --target=%, $(KBUILD_CPPFLAGS) $(KBUILD
 KBUILD_USERLDFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS))
 
 # userspace programs are linked via the compiler, use the correct linker
-ifeq ($(CONFIG_CC_IS_CLANG)$(CONFIG_LD_IS_LLD),yy)
+ifdef CONFIG_CC_IS_CLANG
 KBUILD_USERLDFLAGS += --ld-path=$(LD)
 endif
 
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h
index 188efac..fc45749 100644
--- a/include/crypto/algapi.h
+++ b/include/crypto/algapi.h
@@ -43,8 +43,8 @@
  * alias.
  */
 #define MODULE_ALIAS_CRYPTO(name)	\
-		__MODULE_INFO(alias, alias_userspace, name);	\
-		__MODULE_INFO(alias, alias_crypto, "crypto-" name)
+		MODULE_INFO(alias, name);	\
+		MODULE_INFO(alias, "crypto-" name)
 
 struct crypto_aead;
 struct crypto_instance;
diff --git a/include/linux/module.h b/include/linux/module.h
index 313ecb8..3319a52 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -165,9 +165,6 @@ extern void cleanup_module(void);
 
 struct module_kobject *lookup_or_create_module_kobject(const char *name);
 
-/* Generic info of form tag = "info" */
-#define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
-
 /* For userspace: you can also call me... */
 #define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias)
 
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index a04a2bc..3a25122 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -24,18 +24,19 @@
 #define __MODULE_INFO_PREFIX KBUILD_MODNAME "."
 #endif
 
-#define __MODULE_INFO(tag, name, info)					  \
-	static const char __UNIQUE_ID(name)[]				  \
+/* Generic info of form tag = "info" */
+#define MODULE_INFO(tag, info)					  \
+	static const char __UNIQUE_ID(modinfo)[]			  \
 		__used __section(".modinfo") __aligned(1)		  \
 		= __MODULE_INFO_PREFIX __stringify(tag) "=" info
 
 #define __MODULE_PARM_TYPE(name, _type)					  \
-	__MODULE_INFO(parmtype, name##type, #name ":" _type)
+	MODULE_INFO(parmtype, #name ":" _type)
 
 /* One for each parameter, describing how to use it.  Some files do
    multiple of these per line, so can't just use MODULE_INFO. */
 #define MODULE_PARM_DESC(_parm, desc) \
-	__MODULE_INFO(parm, _parm, #_parm ":" desc)
+	MODULE_INFO(parm, #_parm ":" desc)
 
 struct kernel_param;
 
diff --git a/include/net/tcp.h b/include/net/tcp.h
index b3815d1..526a26e 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -2655,8 +2655,8 @@ void tcp_update_ulp(struct sock *sk, struct proto *p,
 		    void (*write_space)(struct sock *sk));
 
 #define MODULE_ALIAS_TCP_ULP(name)				\
-	__MODULE_INFO(alias, alias_userspace, name);		\
-	__MODULE_INFO(alias, alias_tcp_ulp, "tcp-ulp-" name)
+	MODULE_INFO(alias, name);		\
+	MODULE_INFO(alias, "tcp-ulp-" name)
 
 #ifdef CONFIG_NET_SOCK_MSG
 struct sk_msg;
diff --git a/kernel/.gitignore b/kernel/.gitignore
index c6b299a..a501bfc 100644
--- a/kernel/.gitignore
+++ b/kernel/.gitignore
@@ -1,3 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 /config_data
 /kheaders.md5
+/kheaders-objlist
+/kheaders-srclist
diff --git a/kernel/Makefile b/kernel/Makefile
index 366987d..c606234 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -159,11 +159,48 @@ filechk_cat = cat $<
 $(obj)/config_data: $(KCONFIG_CONFIG) FORCE
 	$(call filechk,cat)
 
+# kheaders_data.tar.xz
 $(obj)/kheaders.o: $(obj)/kheaders_data.tar.xz
 
-quiet_cmd_genikh = CHK     $(obj)/kheaders_data.tar.xz
-      cmd_genikh = $(CONFIG_SHELL) $(srctree)/kernel/gen_kheaders.sh $@
-$(obj)/kheaders_data.tar.xz: FORCE
-	$(call cmd,genikh)
+quiet_cmd_kheaders_data = GEN     $@
+      cmd_kheaders_data = "$<" "$@" "$(obj)/kheaders-srclist" "$(obj)/kheaders-objlist" "$(KBUILD_BUILD_TIMESTAMP)"
+      cmd_kheaders_data_dep = cat $(depfile) >> $(dot-target).cmd; rm -f $(depfile)
 
-clean-files := kheaders_data.tar.xz kheaders.md5
+define rule_kheaders_data
+	$(call cmd_and_savecmd,kheaders_data)
+	$(call cmd,kheaders_data_dep)
+endef
+
+targets += kheaders_data.tar.xz
+$(obj)/kheaders_data.tar.xz: $(src)/gen_kheaders.sh $(obj)/kheaders-srclist $(obj)/kheaders-objlist $(obj)/kheaders.md5 FORCE
+	$(call if_changed_rule,kheaders_data)
+
+# generated headers in objtree
+#
+# include/generated/utsversion.h is ignored because it is generated
+# after gen_kheaders.sh is executed. (utsversion.h is unneeded for kheaders)
+filechk_kheaders_objlist = \
+	for d in include "arch/$(SRCARCH)/include"; do \
+		find "$${d}/generated" ! -path "include/generated/utsversion.h" -a -name "*.h" -print; \
+	done
+
+$(obj)/kheaders-objlist: FORCE
+	$(call filechk,kheaders_objlist)
+
+# non-generated headers in srctree
+filechk_kheaders_srclist = \
+	for d in include "arch/$(SRCARCH)/include"; do \
+		find "$(srctree)/$${d}" -path "$(srctree)/$${d}/generated" -prune -o -name "*.h" -print; \
+	done
+
+$(obj)/kheaders-srclist: FORCE
+	$(call filechk,kheaders_srclist)
+
+# Some files are symlinks. If symlinks are changed, kheaders_data.tar.xz should
+# be rebuilt.
+filechk_kheaders_md5sum = xargs -r -a $< stat -c %N | md5sum
+
+$(obj)/kheaders.md5: $(obj)/kheaders-srclist FORCE
+	$(call filechk,kheaders_md5sum)
+
+clean-files := kheaders.md5 kheaders-srclist kheaders-objlist
diff --git a/kernel/gen_kheaders.sh b/kernel/gen_kheaders.sh
index c9e5dc0..896a503 100755
--- a/kernel/gen_kheaders.sh
+++ b/kernel/gen_kheaders.sh
@@ -4,79 +4,34 @@
 # This script generates an archive consisting of kernel headers
 # for CONFIG_IKHEADERS.
 set -e
-sfile="$(readlink -f "$0")"
-outdir="$(pwd)"
 tarfile=$1
-tmpdir=$outdir/${tarfile%/*}/.tmp_dir
-
-dir_list="
-include/
-arch/$SRCARCH/include/
-"
-
-# Support incremental builds by skipping archive generation
-# if timestamps of files being archived are not changed.
-
-# This block is useful for debugging the incremental builds.
-# Uncomment it for debugging.
-# if [ ! -f /tmp/iter ]; then iter=1; echo 1 > /tmp/iter;
-# else iter=$(($(cat /tmp/iter) + 1)); echo $iter > /tmp/iter; fi
-# find $all_dirs -name "*.h" | xargs ls -l > /tmp/ls-$iter
-
-all_dirs=
-if [ "$building_out_of_srctree" ]; then
-	for d in $dir_list; do
-		all_dirs="$all_dirs $srctree/$d"
-	done
-fi
-all_dirs="$all_dirs $dir_list"
-
-# include/generated/utsversion.h is ignored because it is generated after this
-# script is executed. (utsversion.h is unneeded for kheaders)
-#
-# When Kconfig regenerates include/generated/autoconf.h, its timestamp is
-# updated, but the contents might be still the same. When any CONFIG option is
-# changed, Kconfig touches the corresponding timestamp file include/config/*.
-# Hence, the md5sum detects the configuration change anyway. We do not need to
-# check include/generated/autoconf.h explicitly.
-#
-# Ignore them for md5 calculation to avoid pointless regeneration.
-headers_md5="$(find $all_dirs -name "*.h" -a			\
-		! -path include/generated/utsversion.h -a	\
-		! -path include/generated/autoconf.h		|
-		xargs ls -l | md5sum | cut -d ' ' -f1)"
-
-# Any changes to this script will also cause a rebuild of the archive.
-this_file_md5="$(ls -l $sfile | md5sum | cut -d ' ' -f1)"
-if [ -f $tarfile ]; then tarfile_md5="$(md5sum $tarfile | cut -d ' ' -f1)"; fi
-if [ -f kernel/kheaders.md5 ] &&
-	[ "$(head -n 1 kernel/kheaders.md5)" = "$headers_md5" ] &&
-	[ "$(head -n 2 kernel/kheaders.md5 | tail -n 1)" = "$this_file_md5" ] &&
-	[ "$(tail -n 1 kernel/kheaders.md5)" = "$tarfile_md5" ]; then
-		exit
-fi
-
-echo "  GEN     $tarfile"
+srclist=$2
+objlist=$3
+timestamp=$4
+
+dir=$(dirname "${tarfile}")
+tmpdir=${dir}/.tmp_dir
+depfile=${dir}/.$(basename "${tarfile}").d
+
+# generate dependency list.
+{
+	echo
+	echo "deps_${tarfile} := \\"
+	sed 's:\(.*\):  \1 \\:' "${srclist}"
+	sed -n '/^include\/generated\/autoconf\.h$/!s:\(.*\):  \1 \\:p' "${objlist}"
+	echo
+	echo "${tarfile}: \$(deps_${tarfile})"
+	echo
+	echo "\$(deps_${tarfile}):"
+
+} > "${depfile}"
 
 rm -rf "${tmpdir}"
 mkdir "${tmpdir}"
 
-if [ "$building_out_of_srctree" ]; then
-	(
-		cd $srctree
-		for f in $dir_list
-			do find "$f" -name "*.h";
-		done | tar -c -f - -T - | tar -xf - -C "${tmpdir}"
-	)
-fi
-
-for f in $dir_list;
-	do find "$f" -name "*.h";
-done | tar -c -f - -T - | tar -xf - -C "${tmpdir}"
-
-# Always exclude include/generated/utsversion.h
-# Otherwise, the contents of the tarball may vary depending on the build steps.
-rm -f "${tmpdir}/include/generated/utsversion.h"
+# shellcheck disable=SC2154 # srctree is passed as an env variable
+sed "s:^${srctree}/::" "${srclist}" | ${TAR} -c -f - -C "${srctree}" -T - | ${TAR} -xf - -C "${tmpdir}"
+${TAR} -c -f - -T "${objlist}" | ${TAR} -xf - -C "${tmpdir}"
 
 # Remove comments except SDPX lines
 # Use a temporary file to store directory contents to prevent find/xargs from
@@ -88,12 +43,8 @@ xargs -0 -P8 -n1 \
 rm -f "${tmpdir}.contents.txt"
 
 # Create archive and try to normalize metadata for reproducibility.
-tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \
+${TAR} "${timestamp:+--mtime=$timestamp}" \
     --owner=0 --group=0 --sort=name --numeric-owner --mode=u=rw,go=r,a+X \
-    -I $XZ -cf $tarfile -C "${tmpdir}/" . > /dev/null
-
-echo $headers_md5 > kernel/kheaders.md5
-echo "$this_file_md5" >> kernel/kheaders.md5
-echo "$(md5sum $tarfile | cut -d ' ' -f1)" >> kernel/kheaders.md5
+    -I "${XZ}" -cf "${tarfile}" -C "${tmpdir}/" . > /dev/null
 
 rm -rf "${tmpdir}"
diff --git a/scripts/extract-vmlinux b/scripts/extract-vmlinux
index 8995cd3..189956b 100755
--- a/scripts/extract-vmlinux
+++ b/scripts/extract-vmlinux
@@ -12,13 +12,12 @@
 
 check_vmlinux()
 {
-	# Use readelf to check if it's a valid ELF
-	# TODO: find a better to way to check that it's really vmlinux
-	#       and not just an elf
-	readelf -h $1 > /dev/null 2>&1 || return 1
-
-	cat $1
-	exit 0
+	if file "$1" | grep -q 'Linux kernel.*boot executable' ||
+		readelf -h "$1" > /dev/null 2>&1
+	then
+		cat "$1"
+		exit 0
+	fi
 }
 
 try_decompress()
diff --git a/scripts/gendwarfksyms/cache.c b/scripts/gendwarfksyms/cache.c
index c9c19b8..1c640db 100644
--- a/scripts/gendwarfksyms/cache.c
+++ b/scripts/gendwarfksyms/cache.c
@@ -15,7 +15,7 @@ void cache_set(struct cache *cache, unsigned long key, int value)
 {
 	struct cache_item *ci;
 
-	ci = xmalloc(sizeof(struct cache_item));
+	ci = xmalloc(sizeof(*ci));
 	ci->key = key;
 	ci->value = value;
 	hash_add(cache->cache, &ci->hash, hash_32(key));
diff --git a/scripts/gendwarfksyms/die.c b/scripts/gendwarfksyms/die.c
index 6183bbb..052f7a3 100644
--- a/scripts/gendwarfksyms/die.c
+++ b/scripts/gendwarfksyms/die.c
@@ -33,7 +33,7 @@ static struct die *create_die(Dwarf_Die *die, enum die_state state)
 {
 	struct die *cd;
 
-	cd = xmalloc(sizeof(struct die));
+	cd = xmalloc(sizeof(*cd));
 	init_die(cd);
 	cd->addr = (uintptr_t)die->addr;
 
@@ -123,7 +123,7 @@ static struct die_fragment *append_item(struct die *cd)
 {
 	struct die_fragment *df;
 
-	df = xmalloc(sizeof(struct die_fragment));
+	df = xmalloc(sizeof(*df));
 	df->type = FRAGMENT_EMPTY;
 	list_add_tail(&df->list, &cd->fragments);
 	return df;
diff --git a/scripts/gendwarfksyms/dwarf.c b/scripts/gendwarfksyms/dwarf.c
index 13ea7bf..3538a7d 100644
--- a/scripts/gendwarfksyms/dwarf.c
+++ b/scripts/gendwarfksyms/dwarf.c
@@ -634,7 +634,7 @@ static int get_union_kabi_status(Dwarf_Die *die, Dwarf_Die *placeholder,
 	 * Note that the user of this feature is responsible for ensuring
 	 * that the structure actually remains ABI compatible.
 	 */
-	memset(&state.kabi, 0, sizeof(struct kabi_state));
+	memset(&state.kabi, 0, sizeof(state.kabi));
 
 	res = checkp(process_die_container(&state, NULL, die,
 					   check_union_member_kabi_status,
diff --git a/scripts/gendwarfksyms/kabi.c b/scripts/gendwarfksyms/kabi.c
index b3ade71..e3c2a3c 100644
--- a/scripts/gendwarfksyms/kabi.c
+++ b/scripts/gendwarfksyms/kabi.c
@@ -228,7 +228,7 @@ void kabi_read_rules(int fd)
 		if (type == KABI_RULE_TYPE_UNKNOWN)
 			error("unsupported kABI rule type: '%s'", field);
 
-		rule = xmalloc(sizeof(struct rule));
+		rule = xmalloc(sizeof(*rule));
 
 		rule->type = type;
 		rule->target = xstrdup(get_rule_field(&rule_str, &left));
diff --git a/scripts/gendwarfksyms/symbols.c b/scripts/gendwarfksyms/symbols.c
index 327f873..35ed594 100644
--- a/scripts/gendwarfksyms/symbols.c
+++ b/scripts/gendwarfksyms/symbols.c
@@ -146,7 +146,7 @@ void symbol_read_exports(FILE *file)
 			continue;
 		}
 
-		sym = xcalloc(1, sizeof(struct symbol));
+		sym = xcalloc(1, sizeof(*sym));
 		sym->name = name;
 		sym->addr.section = SHN_UNDEF;
 		sym->state = SYMBOL_UNPROCESSED;
diff --git a/scripts/gendwarfksyms/types.c b/scripts/gendwarfksyms/types.c
index 7bd459e..9c3b053 100644
--- a/scripts/gendwarfksyms/types.c
+++ b/scripts/gendwarfksyms/types.c
@@ -6,6 +6,8 @@
 #define _GNU_SOURCE
 #include <inttypes.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <zlib.h>
 
 #include "gendwarfksyms.h"
@@ -43,7 +45,7 @@ static int type_list_append(struct list_head *list, const char *s, void *owned)
 	if (!s)
 		return 0;
 
-	entry = xmalloc(sizeof(struct type_list_entry));
+	entry = xmalloc(sizeof(*entry));
 	entry->str = s;
 	entry->owned = owned;
 	list_add_tail(&entry->list, list);
@@ -120,7 +122,7 @@ static struct type_expansion *type_map_add(const char *name,
 	struct type_expansion *e;
 
 	if (__type_map_get(name, &e)) {
-		e = xmalloc(sizeof(struct type_expansion));
+		e = xmalloc(sizeof(*e));
 		type_expansion_init(e);
 		e->name = xstrdup(name);
 
@@ -179,20 +181,41 @@ static int type_map_get(const char *name, struct type_expansion **res)
 	return -1;
 }
 
+static int cmp_expansion_name(const void *p1, const void *p2)
+{
+	struct type_expansion *const *e1 = p1;
+	struct type_expansion *const *e2 = p2;
+
+	return strcmp((*e1)->name, (*e2)->name);
+}
+
 static void type_map_write(FILE *file)
 {
 	struct type_expansion *e;
 	struct hlist_node *tmp;
+	struct type_expansion **es;
+	size_t count = 0;
+	size_t i = 0;
 
 	if (!file)
 		return;
 
-	hash_for_each_safe(type_map, e, tmp, hash) {
-		checkp(fputs(e->name, file));
+	hash_for_each_safe(type_map, e, tmp, hash)
+		++count;
+	es = xmalloc(count * sizeof(*es));
+	hash_for_each_safe(type_map, e, tmp, hash)
+		es[i++] = e;
+
+	qsort(es, count, sizeof(*es), cmp_expansion_name);
+
+	for (i = 0; i < count; ++i) {
+		checkp(fputs(es[i]->name, file));
 		checkp(fputs(" ", file));
-		type_list_write(&e->expanded, file);
+		type_list_write(&es[i]->expanded, file);
 		checkp(fputs("\n", file));
 	}
+
+	free(es);
 }
 
 static void type_map_free(void)
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 8abe570..a7b44cd 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -594,7 +594,7 @@ static void check_conf(struct menu *menu)
 		default:
 			if (!conf_cnt++)
 				printf("*\n* Restart config...\n*\n");
-			rootEntry = menu_get_parent_menu(menu);
+			rootEntry = menu_get_menu_or_parent_menu(menu);
 			conf(rootEntry);
 			break;
 		}
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index ac95661..9599a04 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -77,7 +77,7 @@ static bool is_same(const char *file1, const char *file2)
 	if (map2 == MAP_FAILED)
 		goto close2;
 
-	if (bcmp(map1, map2, st1.st_size))
+	if (memcmp(map1, map2, st1.st_size))
 		goto close2;
 
 	ret = true;
diff --git a/scripts/kconfig/gconf-cfg.sh b/scripts/kconfig/gconf-cfg.sh
index fc954c0..856c692 100755
--- a/scripts/kconfig/gconf-cfg.sh
+++ b/scripts/kconfig/gconf-cfg.sh
@@ -6,7 +6,7 @@ set -eu
 cflags=$1
 libs=$2
 
-PKG="gtk+-2.0 gmodule-2.0 libglade-2.0"
+PKG=gtk+-3.0
 
 if [ -z "$(command -v ${HOSTPKG_CONFIG})" ]; then
 	echo >&2 "*"
@@ -18,18 +18,11 @@ fi
 if ! ${HOSTPKG_CONFIG} --exists $PKG; then
 	echo >&2 "*"
 	echo >&2 "* Unable to find the GTK+ installation. Please make sure that"
-	echo >&2 "* the GTK+ 2.0 development package is correctly installed."
+	echo >&2 "* the GTK 3 development package is correctly installed."
 	echo >&2 "* You need $PKG"
 	echo >&2 "*"
 	exit 1
 fi
 
-if ! ${HOSTPKG_CONFIG} --atleast-version=2.0.0 gtk+-2.0; then
-	echo >&2 "*"
-	echo >&2 "* GTK+ is present but version >= 2.0.0 is required."
-	echo >&2 "*"
-	exit 1
-fi
-
 ${HOSTPKG_CONFIG} --cflags ${PKG} > ${cflags}
 ${HOSTPKG_CONFIG} --libs ${PKG} > ${libs}
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c
index c0f46f1..8b164cc 100644
--- a/scripts/kconfig/gconf.c
+++ b/scripts/kconfig/gconf.c
@@ -7,10 +7,7 @@
 #include "lkc.h"
 #include "images.h"
 
-#include <glade/glade.h>
 #include <gtk/gtk.h>
-#include <glib.h>
-#include <gdk/gdkkeysyms.h>
 
 #include <stdio.h>
 #include <string.h>
@@ -18,7 +15,7 @@
 #include <unistd.h>
 #include <time.h>
 
-enum {
+enum view_mode {
 	SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW
 };
 
@@ -30,29 +27,24 @@ static gint view_mode = FULL_VIEW;
 static gboolean show_name = TRUE;
 static gboolean show_range = TRUE;
 static gboolean show_value = TRUE;
-static gboolean resizeable = FALSE;
 static int opt_mode = OPT_NORMAL;
 
-GtkWidget *main_wnd = NULL;
-GtkWidget *tree1_w = NULL;	// left  frame
-GtkWidget *tree2_w = NULL;	// right frame
-GtkWidget *text_w = NULL;
-GtkWidget *hpaned = NULL;
-GtkWidget *vpaned = NULL;
-GtkWidget *back_btn = NULL;
-GtkWidget *save_btn = NULL;
-GtkWidget *save_menu_item = NULL;
+static GtkWidget *main_wnd;
+static GtkWidget *tree1_w;	// left  frame
+static GtkWidget *tree2_w;	// right frame
+static GtkWidget *text_w;
+static GtkWidget *hpaned;
+static GtkWidget *vpaned;
+static GtkWidget *back_btn, *save_btn, *single_btn, *split_btn, *full_btn;
+static GtkWidget *save_menu_item;
 
-GtkTextTag *tag1, *tag2;
-GdkColor color;
+static GtkTextTag *tag1, *tag2;
 
-GtkTreeStore *tree1, *tree2, *tree;
-GtkTreeModel *model1, *model2;
-static GtkTreeIter *parents[256];
-static gint indent;
+static GtkTreeStore *tree1, *tree2;
+static GdkPixbuf *pix_menu;
 
-static struct menu *current; // current node for SINGLE view
-static struct menu *browsed; // browsed node for SPLIT view
+static struct menu *browsed; // browsed menu for SINGLE/SPLIT view
+static struct menu *selected; // selected entry
 
 enum {
 	COL_OPTION, COL_NAME, COL_NO, COL_MOD, COL_YES, COL_VALUE,
@@ -61,28 +53,8 @@ enum {
 	COL_NUMBER
 };
 
-static void display_list(void);
-static void display_tree(struct menu *menu);
-static void display_tree_part(void);
-static void update_tree(struct menu *src, GtkTreeIter * dst);
-
-static void replace_button_icon(GladeXML *xml, GdkDrawable *window,
-				GtkStyle *style, gchar *btn_name, gchar **xpm)
-{
-	GdkPixmap *pixmap;
-	GdkBitmap *mask;
-	GtkToolButton *button;
-	GtkWidget *image;
-
-	pixmap = gdk_pixmap_create_from_xpm_d(window, &mask,
-					      &style->bg[GTK_STATE_NORMAL],
-					      xpm);
-
-	button = GTK_TOOL_BUTTON(glade_xml_get_widget(xml, btn_name));
-	image = gtk_image_new_from_pixmap(pixmap, mask);
-	gtk_widget_show(image);
-	gtk_tool_button_set_icon_widget(button, image);
-}
+static void display_tree(GtkTreeStore *store, struct menu *menu);
+static void recreate_tree(void);
 
 static void conf_changed(bool dirty)
 {
@@ -90,465 +62,373 @@ static void conf_changed(bool dirty)
 	gtk_widget_set_sensitive(save_menu_item, dirty);
 }
 
-/* Main Window Initialization */
-static void init_main_window(const gchar *glade_file)
+/* Utility Functions */
+
+static void text_insert_msg(const char *title, const char *msg)
 {
-	GladeXML *xml;
-	GtkWidget *widget;
-	GtkTextBuffer *txtbuf;
-	GtkStyle *style;
+	GtkTextBuffer *buffer;
+	GtkTextIter start, end;
 
-	xml = glade_xml_new(glade_file, "window1", NULL);
-	if (!xml)
-		g_error("GUI loading failed !\n");
-	glade_xml_signal_autoconnect(xml);
+	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
+	gtk_text_buffer_get_bounds(buffer, &start, &end);
+	gtk_text_buffer_delete(buffer, &start, &end);
+	gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15);
 
-	main_wnd = glade_xml_get_widget(xml, "window1");
-	hpaned = glade_xml_get_widget(xml, "hpaned1");
-	vpaned = glade_xml_get_widget(xml, "vpaned1");
-	tree1_w = glade_xml_get_widget(xml, "treeview1");
-	tree2_w = glade_xml_get_widget(xml, "treeview2");
-	text_w = glade_xml_get_widget(xml, "textview3");
+	gtk_text_buffer_get_end_iter(buffer, &end);
+	gtk_text_buffer_insert_with_tags(buffer, &end, title, -1, tag1,
+					 NULL);
+	gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2);
+	gtk_text_buffer_get_end_iter(buffer, &end);
+	gtk_text_buffer_insert_with_tags(buffer, &end, msg, -1, tag2,
+					 NULL);
+}
 
-	back_btn = glade_xml_get_widget(xml, "button1");
-	gtk_widget_set_sensitive(back_btn, FALSE);
+static void text_insert_help(struct menu *menu)
+{
+	struct gstr help = str_new();
 
-	widget = glade_xml_get_widget(xml, "show_name1");
-	gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
-				       show_name);
+	menu_get_ext_help(menu, &help);
+	text_insert_msg(menu_get_prompt(menu), str_get(&help));
+	str_free(&help);
+}
 
-	widget = glade_xml_get_widget(xml, "show_range1");
-	gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
-				       show_range);
+static void _select_menu(GtkTreeView *view, GtkTreeModel *model,
+			 GtkTreeIter *parent, struct menu *match)
+{
+	GtkTreeIter iter;
+	gboolean valid;
 
-	widget = glade_xml_get_widget(xml, "show_data1");
-	gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
-				       show_value);
+	valid = gtk_tree_model_iter_children(model, &iter, parent);
+	while (valid) {
+		struct menu *menu;
 
-	save_btn = glade_xml_get_widget(xml, "button3");
-	save_menu_item = glade_xml_get_widget(xml, "save1");
-	conf_set_changed_callback(conf_changed);
+		gtk_tree_model_get(model, &iter, COL_MENU, &menu, -1);
 
-	style = gtk_widget_get_style(main_wnd);
-	widget = glade_xml_get_widget(xml, "toolbar1");
+		if (menu == match) {
+			GtkTreeSelection *selection;
+			GtkTreePath *path;
 
-	replace_button_icon(xml, main_wnd->window, style,
-			    "button4", (gchar **) xpm_single_view);
-	replace_button_icon(xml, main_wnd->window, style,
-			    "button5", (gchar **) xpm_split_view);
-	replace_button_icon(xml, main_wnd->window, style,
-			    "button6", (gchar **) xpm_tree_view);
+			/*
+			 * Expand parents to reflect the selection, and
+			 * scroll down to it.
+			 */
+			path = gtk_tree_model_get_path(model, &iter);
+			gtk_tree_view_expand_to_path(view, path);
+			gtk_tree_view_scroll_to_cell(view, path, NULL, TRUE,
+						     0.5, 0.0);
+			gtk_tree_path_free(path);
 
-	txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
-	tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1",
-					  "foreground", "red",
-					  "weight", PANGO_WEIGHT_BOLD,
-					  NULL);
-	tag2 = gtk_text_buffer_create_tag(txtbuf, "mytag2",
-					  /*"style", PANGO_STYLE_OBLIQUE, */
-					  NULL);
+			selection = gtk_tree_view_get_selection(view);
+			gtk_tree_selection_select_iter(selection, &iter);
 
-	gtk_window_set_title(GTK_WINDOW(main_wnd), rootmenu.prompt->text);
+			text_insert_help(menu);
+		}
 
-	gtk_widget_show(main_wnd);
+		_select_menu(view, model, &iter, match);
+
+		valid = gtk_tree_model_iter_next(model, &iter);
+	}
 }
 
-static void init_tree_model(void)
+static void select_menu(GtkTreeView *view, struct menu *match)
 {
-	gint i;
-
-	tree = tree2 = gtk_tree_store_new(COL_NUMBER,
-					  G_TYPE_STRING, G_TYPE_STRING,
-					  G_TYPE_STRING, G_TYPE_STRING,
-					  G_TYPE_STRING, G_TYPE_STRING,
-					  G_TYPE_POINTER, GDK_TYPE_COLOR,
-					  G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
-					  G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
-					  G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
-					  G_TYPE_BOOLEAN);
-	model2 = GTK_TREE_MODEL(tree2);
-
-	for (parents[0] = NULL, i = 1; i < 256; i++)
-		parents[i] = (GtkTreeIter *) g_malloc(sizeof(GtkTreeIter));
-
-	tree1 = gtk_tree_store_new(COL_NUMBER,
-				   G_TYPE_STRING, G_TYPE_STRING,
-				   G_TYPE_STRING, G_TYPE_STRING,
-				   G_TYPE_STRING, G_TYPE_STRING,
-				   G_TYPE_POINTER, GDK_TYPE_COLOR,
-				   G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
-				   G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
-				   G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
-				   G_TYPE_BOOLEAN);
-	model1 = GTK_TREE_MODEL(tree1);
+	_select_menu(view, gtk_tree_view_get_model(view), NULL, match);
 }
 
-static void init_left_tree(void)
+static void _update_row_visibility(GtkTreeView *view)
 {
-	GtkTreeView *view = GTK_TREE_VIEW(tree1_w);
-	GtkCellRenderer *renderer;
-	GtkTreeSelection *sel;
-	GtkTreeViewColumn *column;
-
-	gtk_tree_view_set_model(view, model1);
-	gtk_tree_view_set_headers_visible(view, TRUE);
-	gtk_tree_view_set_rules_hint(view, TRUE);
-
-	column = gtk_tree_view_column_new();
-	gtk_tree_view_append_column(view, column);
-	gtk_tree_view_column_set_title(column, "Options");
+	GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER(gtk_tree_view_get_model(view));
 
-	renderer = gtk_cell_renderer_toggle_new();
-	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
-					renderer, FALSE);
-	gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
-					    renderer,
-					    "active", COL_BTNACT,
-					    "inconsistent", COL_BTNINC,
-					    "visible", COL_BTNVIS,
-					    "radio", COL_BTNRAD, NULL);
-	renderer = gtk_cell_renderer_text_new();
-	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
-					renderer, FALSE);
-	gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
-					    renderer,
-					    "text", COL_OPTION,
-					    "foreground-gdk",
-					    COL_COLOR, NULL);
-
-	sel = gtk_tree_view_get_selection(view);
-	gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
-	gtk_widget_realize(tree1_w);
+	gtk_tree_model_filter_refilter(filter);
 }
 
-static void renderer_edited(GtkCellRendererText * cell,
-			    const gchar * path_string,
-			    const gchar * new_text, gpointer user_data);
+static void update_row_visibility(void)
+{
+	if (view_mode == SPLIT_VIEW)
+		_update_row_visibility(GTK_TREE_VIEW(tree1_w));
+	_update_row_visibility(GTK_TREE_VIEW(tree2_w));
+}
 
-static void init_right_tree(void)
+static void set_node(GtkTreeStore *tree, GtkTreeIter *node, struct menu *menu)
 {
-	GtkTreeView *view = GTK_TREE_VIEW(tree2_w);
-	GtkCellRenderer *renderer;
-	GtkTreeSelection *sel;
-	GtkTreeViewColumn *column;
-	gint i;
+	struct symbol *sym = menu->sym;
+	tristate val;
+	gchar *option;
+	const gchar *_no = "";
+	const gchar *_mod = "";
+	const gchar *_yes = "";
+	const gchar *value = "";
+	GdkRGBA color;
+	gboolean editable = FALSE;
+	gboolean btnvis = FALSE;
+
+	option = g_strdup_printf("%s %s %s %s",
+				 menu->type == M_COMMENT ? "***" : "",
+				 menu_get_prompt(menu),
+				 menu->type == M_COMMENT ? "***" : "",
+				 sym && !sym_has_value(sym) ? "(NEW)" : "");
+
+	gdk_rgba_parse(&color, menu_is_visible(menu) ? "Black" : "DarkGray");
 
-	gtk_tree_view_set_model(view, model2);
-	gtk_tree_view_set_headers_visible(view, TRUE);
-	gtk_tree_view_set_rules_hint(view, TRUE);
+	if (!sym)
+		goto set;
 
-	column = gtk_tree_view_column_new();
-	gtk_tree_view_append_column(view, column);
-	gtk_tree_view_column_set_title(column, "Options");
+	sym_calc_value(sym);
 
-	renderer = gtk_cell_renderer_pixbuf_new();
-	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
-					renderer, FALSE);
-	gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
-					    renderer,
-					    "pixbuf", COL_PIXBUF,
-					    "visible", COL_PIXVIS, NULL);
-	renderer = gtk_cell_renderer_toggle_new();
-	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
-					renderer, FALSE);
-	gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
-					    renderer,
-					    "active", COL_BTNACT,
-					    "inconsistent", COL_BTNINC,
-					    "visible", COL_BTNVIS,
-					    "radio", COL_BTNRAD, NULL);
-	renderer = gtk_cell_renderer_text_new();
-	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
-					renderer, FALSE);
-	gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
-					    renderer,
-					    "text", COL_OPTION,
-					    "foreground-gdk",
-					    COL_COLOR, NULL);
+	if (menu->type == M_CHOICE) {	// parse children to get a final value
+		struct symbol *def_sym = sym_calc_choice(menu);
+		struct menu *def_menu = NULL;
 
-	renderer = gtk_cell_renderer_text_new();
-	gtk_tree_view_insert_column_with_attributes(view, -1,
-						    "Name", renderer,
-						    "text", COL_NAME,
-						    "foreground-gdk",
-						    COL_COLOR, NULL);
-	renderer = gtk_cell_renderer_text_new();
-	gtk_tree_view_insert_column_with_attributes(view, -1,
-						    "N", renderer,
-						    "text", COL_NO,
-						    "foreground-gdk",
-						    COL_COLOR, NULL);
-	renderer = gtk_cell_renderer_text_new();
-	gtk_tree_view_insert_column_with_attributes(view, -1,
-						    "M", renderer,
-						    "text", COL_MOD,
-						    "foreground-gdk",
-						    COL_COLOR, NULL);
-	renderer = gtk_cell_renderer_text_new();
-	gtk_tree_view_insert_column_with_attributes(view, -1,
-						    "Y", renderer,
-						    "text", COL_YES,
-						    "foreground-gdk",
-						    COL_COLOR, NULL);
-	renderer = gtk_cell_renderer_text_new();
-	gtk_tree_view_insert_column_with_attributes(view, -1,
-						    "Value", renderer,
-						    "text", COL_VALUE,
-						    "editable",
-						    COL_EDIT,
-						    "foreground-gdk",
-						    COL_COLOR, NULL);
-	g_signal_connect(G_OBJECT(renderer), "edited",
-			 G_CALLBACK(renderer_edited), NULL);
-
-	column = gtk_tree_view_get_column(view, COL_NAME);
-	gtk_tree_view_column_set_visible(column, show_name);
-	column = gtk_tree_view_get_column(view, COL_NO);
-	gtk_tree_view_column_set_visible(column, show_range);
-	column = gtk_tree_view_get_column(view, COL_MOD);
-	gtk_tree_view_column_set_visible(column, show_range);
-	column = gtk_tree_view_get_column(view, COL_YES);
-	gtk_tree_view_column_set_visible(column, show_range);
-	column = gtk_tree_view_get_column(view, COL_VALUE);
-	gtk_tree_view_column_set_visible(column, show_value);
-
-	if (resizeable) {
-		for (i = 0; i < COL_VALUE; i++) {
-			column = gtk_tree_view_get_column(view, i);
-			gtk_tree_view_column_set_resizable(column, TRUE);
+		for (struct menu *child = menu->list; child; child = child->next) {
+			if (menu_is_visible(child) && child->sym == def_sym)
+				def_menu = child;
 		}
-	}
 
-	sel = gtk_tree_view_get_selection(view);
-	gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
-}
+		if (def_menu)
+			value = menu_get_prompt(def_menu);
 
+		goto set;
+	}
 
-/* Utility Functions */
+	switch (sym_get_type(sym)) {
+	case S_BOOLEAN:
+	case S_TRISTATE:
 
+		btnvis = TRUE;
 
-static void text_insert_help(struct menu *menu)
-{
-	GtkTextBuffer *buffer;
-	GtkTextIter start, end;
-	const char *prompt = menu_get_prompt(menu);
-	struct gstr help = str_new();
+		val = sym_get_tristate_value(sym);
+		switch (val) {
+		case no:
+			_no = "N";
+			value = "N";
+			break;
+		case mod:
+			_mod = "M";
+			value = "M";
+			break;
+		case yes:
+			_yes = "Y";
+			value = "Y";
+			break;
+		}
 
-	menu_get_ext_help(menu, &help);
+		if (val != no && sym_tristate_within_range(sym, no))
+			_no = "_";
+		if (val != mod && sym_tristate_within_range(sym, mod))
+			_mod = "_";
+		if (val != yes && sym_tristate_within_range(sym, yes))
+			_yes = "_";
+		break;
+	default:
+		value = sym_get_string_value(sym);
+		editable = TRUE;
+		break;
+	}
 
-	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
-	gtk_text_buffer_get_bounds(buffer, &start, &end);
-	gtk_text_buffer_delete(buffer, &start, &end);
-	gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15);
+set:
+	gtk_tree_store_set(tree, node,
+			   COL_OPTION, option,
+			   COL_NAME, sym ? sym->name : "",
+			   COL_NO, _no,
+			   COL_MOD, _mod,
+			   COL_YES, _yes,
+			   COL_VALUE, value,
+			   COL_MENU, (gpointer) menu,
+			   COL_COLOR, &color,
+			   COL_EDIT, editable,
+			   COL_PIXBUF, pix_menu,
+			   COL_PIXVIS, view_mode == SINGLE_VIEW && menu->type == M_MENU,
+			   COL_BTNVIS, btnvis,
+			   COL_BTNACT, _yes[0] == 'Y',
+			   COL_BTNINC, _mod[0] == 'M',
+			   COL_BTNRAD, sym && sym_is_choice_value(sym),
+			   -1);
 
-	gtk_text_buffer_get_end_iter(buffer, &end);
-	gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1, tag1,
-					 NULL);
-	gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2);
-	gtk_text_buffer_get_end_iter(buffer, &end);
-	gtk_text_buffer_insert_with_tags(buffer, &end, str_get(&help), -1, tag2,
-					 NULL);
-	str_free(&help);
+	g_free(option);
 }
 
-
-static void text_insert_msg(const char *title, const char *message)
+static void _update_tree(GtkTreeStore *store, GtkTreeIter *parent)
 {
-	GtkTextBuffer *buffer;
-	GtkTextIter start, end;
-	const char *msg = message;
+	GtkTreeModel *model = GTK_TREE_MODEL(store);
+	GtkTreeIter iter;
+	gboolean valid;
 
-	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
-	gtk_text_buffer_get_bounds(buffer, &start, &end);
-	gtk_text_buffer_delete(buffer, &start, &end);
-	gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15);
+	valid = gtk_tree_model_iter_children(model, &iter, parent);
+	while (valid) {
+		struct menu *menu;
 
-	gtk_text_buffer_get_end_iter(buffer, &end);
-	gtk_text_buffer_insert_with_tags(buffer, &end, title, -1, tag1,
-					 NULL);
-	gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2);
-	gtk_text_buffer_get_end_iter(buffer, &end);
-	gtk_text_buffer_insert_with_tags(buffer, &end, msg, -1, tag2,
-					 NULL);
-}
+		gtk_tree_model_get(model, &iter, COL_MENU, &menu, -1);
 
+		if (menu)
+			set_node(store, &iter, menu);
 
-/* Main Windows Callbacks */
+		_update_tree(store, &iter);
+
+		valid = gtk_tree_model_iter_next(model, &iter);
+	}
+}
 
-void on_save_activate(GtkMenuItem * menuitem, gpointer user_data);
-gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event,
-				 gpointer user_data)
+static void update_tree(GtkTreeStore *store)
 {
-	GtkWidget *dialog, *label;
-	gint result;
+	_update_tree(store, NULL);
+	update_row_visibility();
+}
 
-	if (!conf_get_changed())
-		return FALSE;
+static void update_trees(void)
+{
+	if (view_mode == SPLIT_VIEW)
+		update_tree(tree1);
+	update_tree(tree2);
+}
 
-	dialog = gtk_dialog_new_with_buttons("Warning !",
-					     GTK_WINDOW(main_wnd),
-					     (GtkDialogFlags)
-					     (GTK_DIALOG_MODAL |
-					      GTK_DIALOG_DESTROY_WITH_PARENT),
-					     GTK_STOCK_OK,
-					     GTK_RESPONSE_YES,
-					     GTK_STOCK_NO,
-					     GTK_RESPONSE_NO,
-					     GTK_STOCK_CANCEL,
-					     GTK_RESPONSE_CANCEL, NULL);
-	gtk_dialog_set_default_response(GTK_DIALOG(dialog),
-					GTK_RESPONSE_CANCEL);
+static void set_view_mode(enum view_mode mode)
+{
+	view_mode = mode;
 
-	label = gtk_label_new("\nSave configuration ?\n");
-	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
-	gtk_widget_show(label);
+	if (mode == SPLIT_VIEW) { // two panes
+		gint w;
 
-	result = gtk_dialog_run(GTK_DIALOG(dialog));
-	switch (result) {
-	case GTK_RESPONSE_YES:
-		on_save_activate(NULL, NULL);
-		return FALSE;
-	case GTK_RESPONSE_NO:
-		return FALSE;
-	case GTK_RESPONSE_CANCEL:
-	case GTK_RESPONSE_DELETE_EVENT:
-	default:
-		gtk_widget_destroy(dialog);
-		return TRUE;
+		gtk_widget_show(tree1_w);
+		gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, NULL);
+		gtk_paned_set_position(GTK_PANED(hpaned), w / 2);
+	} else {
+		gtk_widget_hide(tree1_w);
+		gtk_paned_set_position(GTK_PANED(hpaned), 0);
 	}
 
-	return FALSE;
-}
+	gtk_widget_set_sensitive(single_btn, TRUE);
+	gtk_widget_set_sensitive(split_btn, TRUE);
+	gtk_widget_set_sensitive(full_btn, TRUE);
 
+	switch (mode) {
+	case SINGLE_VIEW:
+		if (selected)
+			browsed = menu_get_parent_menu(selected) ?: &rootmenu;
+		else
+			browsed = &rootmenu;
+		recreate_tree();
+		text_insert_msg("", "");
+		select_menu(GTK_TREE_VIEW(tree2_w), selected);
+		gtk_widget_set_sensitive(single_btn, FALSE);
+		break;
+	case SPLIT_VIEW:
+		browsed = selected;
+		while (browsed && !(browsed->flags & MENU_ROOT))
+			browsed = browsed->parent;
+		gtk_tree_store_clear(tree1);
+		display_tree(tree1, &rootmenu);
+		gtk_tree_view_expand_all(GTK_TREE_VIEW(tree1_w));
+		gtk_tree_store_clear(tree2);
+		if (browsed)
+			display_tree(tree2, browsed);
+		text_insert_msg("", "");
+		select_menu(GTK_TREE_VIEW(tree1_w), browsed);
+		select_menu(GTK_TREE_VIEW(tree2_w), selected);
+		gtk_widget_set_sensitive(split_btn, FALSE);
+		break;
+	case FULL_VIEW:
+		gtk_tree_store_clear(tree2);
+		display_tree(tree2, &rootmenu);
+		text_insert_msg("", "");
+		select_menu(GTK_TREE_VIEW(tree2_w), selected);
+		gtk_widget_set_sensitive(full_btn, FALSE);
+		break;
+	}
 
-void on_window1_destroy(GtkObject * object, gpointer user_data)
-{
-	gtk_main_quit();
+	gtk_widget_set_sensitive(back_btn,
+				 mode == SINGLE_VIEW && browsed != &rootmenu);
 }
 
+/* Menu & Toolbar Callbacks */
 
-void
-on_window1_size_request(GtkWidget * widget,
-			GtkRequisition * requisition, gpointer user_data)
+static void on_load1_activate(GtkMenuItem *menuitem, gpointer user_data)
 {
-	static gint old_h;
-	gint w, h;
-
-	if (widget->window == NULL)
-		gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h);
-	else
-		gdk_window_get_size(widget->window, &w, &h);
-
-	if (h == old_h)
-		return;
-	old_h = h;
-
-	gtk_paned_set_position(GTK_PANED(vpaned), 2 * h / 3);
-}
+	GtkWidget *dialog;
+	GtkFileChooser *chooser;
+	gint res;
 
+	dialog = gtk_file_chooser_dialog_new("Load file...",
+					     GTK_WINDOW(user_data),
+					     GTK_FILE_CHOOSER_ACTION_OPEN,
+					     "_Cancel", GTK_RESPONSE_CANCEL,
+					     "_Open", GTK_RESPONSE_ACCEPT,
+					     NULL);
 
-/* Menu & Toolbar Callbacks */
+	chooser = GTK_FILE_CHOOSER(dialog);
+	gtk_file_chooser_set_filename(chooser, conf_get_configname());
 
+	res = gtk_dialog_run(GTK_DIALOG(dialog));
+	if (res == GTK_RESPONSE_ACCEPT) {
+		char *filename;
 
-static void
-load_filename(GtkFileSelection * file_selector, gpointer user_data)
-{
-	const gchar *fn;
+		filename = gtk_file_chooser_get_filename(chooser);
 
-	fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION
-					     (user_data));
+		if (conf_read(filename))
+			text_insert_msg("Error",
+					"Unable to load configuration!");
+		else
+			update_trees();
 
-	if (conf_read(fn))
-		text_insert_msg("Error", "Unable to load configuration !");
-	else
-		display_tree_part();
-}
+		g_free(filename);
+	}
 
-void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data)
-{
-	GtkWidget *fs;
-
-	fs = gtk_file_selection_new("Load file...");
-	g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
-			 "clicked",
-			 G_CALLBACK(load_filename), (gpointer) fs);
-	g_signal_connect_swapped(GTK_OBJECT
-				 (GTK_FILE_SELECTION(fs)->ok_button),
-				 "clicked", G_CALLBACK(gtk_widget_destroy),
-				 (gpointer) fs);
-	g_signal_connect_swapped(GTK_OBJECT
-				 (GTK_FILE_SELECTION(fs)->cancel_button),
-				 "clicked", G_CALLBACK(gtk_widget_destroy),
-				 (gpointer) fs);
-	gtk_widget_show(fs);
+	gtk_widget_destroy(GTK_WIDGET(dialog));
 }
 
-
-void on_save_activate(GtkMenuItem * menuitem, gpointer user_data)
+static void on_save_activate(GtkMenuItem *menuitem, gpointer user_data)
 {
 	if (conf_write(NULL))
 		text_insert_msg("Error", "Unable to save configuration !");
 	conf_write_autoconf(0);
 }
 
-
-static void
-store_filename(GtkFileSelection * file_selector, gpointer user_data)
+static void on_save_as1_activate(GtkMenuItem *menuitem, gpointer user_data)
 {
-	const gchar *fn;
+	GtkWidget *dialog;
+	GtkFileChooser *chooser;
+	gint res;
 
-	fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION
-					     (user_data));
+	dialog = gtk_file_chooser_dialog_new("Save file as...",
+					     GTK_WINDOW(user_data),
+					     GTK_FILE_CHOOSER_ACTION_SAVE,
+					     "_Cancel", GTK_RESPONSE_CANCEL,
+					     "_Save", GTK_RESPONSE_ACCEPT,
+					     NULL);
 
-	if (conf_write(fn))
-		text_insert_msg("Error", "Unable to save configuration !");
+	chooser = GTK_FILE_CHOOSER(dialog);
+	gtk_file_chooser_set_filename(chooser, conf_get_configname());
 
-	gtk_widget_destroy(GTK_WIDGET(user_data));
-}
+	res = gtk_dialog_run(GTK_DIALOG(dialog));
+	if (res == GTK_RESPONSE_ACCEPT) {
+		char *filename;
 
-void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data)
-{
-	GtkWidget *fs;
-
-	fs = gtk_file_selection_new("Save file as...");
-	g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
-			 "clicked",
-			 G_CALLBACK(store_filename), (gpointer) fs);
-	g_signal_connect_swapped(GTK_OBJECT
-				 (GTK_FILE_SELECTION(fs)->ok_button),
-				 "clicked", G_CALLBACK(gtk_widget_destroy),
-				 (gpointer) fs);
-	g_signal_connect_swapped(GTK_OBJECT
-				 (GTK_FILE_SELECTION(fs)->cancel_button),
-				 "clicked", G_CALLBACK(gtk_widget_destroy),
-				 (gpointer) fs);
-	gtk_widget_show(fs);
-}
+		filename = gtk_file_chooser_get_filename(chooser);
 
+		if (conf_write(filename))
+			text_insert_msg("Error",
+					"Unable to save configuration !");
 
-void on_quit1_activate(GtkMenuItem * menuitem, gpointer user_data)
-{
-	if (!on_window1_delete_event(NULL, NULL, NULL))
-		gtk_widget_destroy(GTK_WIDGET(main_wnd));
-}
+		g_free(filename);
+	}
 
+	gtk_widget_destroy(dialog);
+}
 
-void on_show_name1_activate(GtkMenuItem * menuitem, gpointer user_data)
+static void on_show_name1_activate(GtkMenuItem *menuitem, gpointer user_data)
 {
 	GtkTreeViewColumn *col;
 
-	show_name = GTK_CHECK_MENU_ITEM(menuitem)->active;
+	show_name = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem));
 	col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NAME);
 	if (col)
 		gtk_tree_view_column_set_visible(col, show_name);
 }
 
-
-void on_show_range1_activate(GtkMenuItem * menuitem, gpointer user_data)
+static void on_show_range1_activate(GtkMenuItem *menuitem, gpointer user_data)
 {
 	GtkTreeViewColumn *col;
 
-	show_range = GTK_CHECK_MENU_ITEM(menuitem)->active;
+	show_range = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem));
 	col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NO);
 	if (col)
 		gtk_tree_view_column_set_visible(col, show_range);
@@ -561,46 +441,38 @@ void on_show_range1_activate(GtkMenuItem * menuitem, gpointer user_data)
 
 }
 
-
-void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data)
+static void on_show_data1_activate(GtkMenuItem *menuitem, gpointer user_data)
 {
 	GtkTreeViewColumn *col;
 
-	show_value = GTK_CHECK_MENU_ITEM(menuitem)->active;
+	show_value = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem));
 	col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_VALUE);
 	if (col)
 		gtk_tree_view_column_set_visible(col, show_value);
 }
 
-
-void
-on_set_option_mode1_activate(GtkMenuItem *menuitem, gpointer user_data)
+static void on_set_option_mode1_activate(GtkMenuItem *menuitem,
+					 gpointer user_data)
 {
 	opt_mode = OPT_NORMAL;
-	gtk_tree_store_clear(tree2);
-	display_tree(&rootmenu);	/* instead of update_tree to speed-up */
+	update_row_visibility();
 }
 
-
-void
-on_set_option_mode2_activate(GtkMenuItem *menuitem, gpointer user_data)
+static void on_set_option_mode2_activate(GtkMenuItem *menuitem,
+					 gpointer user_data)
 {
 	opt_mode = OPT_ALL;
-	gtk_tree_store_clear(tree2);
-	display_tree(&rootmenu);	/* instead of update_tree to speed-up */
+	update_row_visibility();
 }
 
-
-void
-on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data)
+static void on_set_option_mode3_activate(GtkMenuItem *menuitem,
+					 gpointer user_data)
 {
 	opt_mode = OPT_PROMPT;
-	gtk_tree_store_clear(tree2);
-	display_tree(&rootmenu);	/* instead of update_tree to speed-up */
+	update_row_visibility();
 }
 
-
-void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
+static void on_introduction1_activate(GtkMenuItem *menuitem, gpointer user_data)
 {
 	GtkWidget *dialog;
 	const gchar *intro_text =
@@ -621,14 +493,11 @@ void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
 					GTK_DIALOG_DESTROY_WITH_PARENT,
 					GTK_MESSAGE_INFO,
 					GTK_BUTTONS_CLOSE, "%s", intro_text);
-	g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
-				 G_CALLBACK(gtk_widget_destroy),
-				 GTK_OBJECT(dialog));
-	gtk_widget_show_all(dialog);
+	gtk_dialog_run(GTK_DIALOG(dialog));
+	gtk_widget_destroy(dialog);
 }
 
-
-void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data)
+static void on_about1_activate(GtkMenuItem *menuitem, gpointer user_data)
 {
 	GtkWidget *dialog;
 	const gchar *about_text =
@@ -638,15 +507,16 @@ void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data)
 	dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
 					GTK_DIALOG_DESTROY_WITH_PARENT,
 					GTK_MESSAGE_INFO,
-					GTK_BUTTONS_CLOSE, "%s", about_text);
-	g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
-				 G_CALLBACK(gtk_widget_destroy),
-				 GTK_OBJECT(dialog));
-	gtk_widget_show_all(dialog);
+					GTK_BUTTONS_CLOSE, "%s\nGTK version: %d.%d.%d",
+					about_text,
+					gtk_get_major_version(),
+					gtk_get_minor_version(),
+					gtk_get_micro_version());
+	gtk_dialog_run(GTK_DIALOG(dialog));
+	gtk_widget_destroy(dialog);
 }
 
-
-void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data)
+static void on_license1_activate(GtkMenuItem *menuitem, gpointer user_data)
 {
 	GtkWidget *dialog;
 	const gchar *license_text =
@@ -658,81 +528,127 @@ void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data)
 					GTK_DIALOG_DESTROY_WITH_PARENT,
 					GTK_MESSAGE_INFO,
 					GTK_BUTTONS_CLOSE, "%s", license_text);
-	g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
-				 G_CALLBACK(gtk_widget_destroy),
-				 GTK_OBJECT(dialog));
-	gtk_widget_show_all(dialog);
+	gtk_dialog_run(GTK_DIALOG(dialog));
+	gtk_widget_destroy(dialog);
 }
 
-
-void on_back_clicked(GtkButton * button, gpointer user_data)
+/* toolbar handlers */
+static void on_back_clicked(GtkButton *button, gpointer user_data)
 {
-	enum prop_type ptype;
+	browsed = menu_get_parent_menu(browsed) ?: &rootmenu;
 
-	current = current->parent;
-	ptype = current->prompt ? current->prompt->type : P_UNKNOWN;
-	if (ptype != P_MENU)
-		current = current->parent;
-	display_tree_part();
+	recreate_tree();
 
-	if (current == &rootmenu)
+	if (browsed == &rootmenu)
 		gtk_widget_set_sensitive(back_btn, FALSE);
 }
 
-
-void on_load_clicked(GtkButton * button, gpointer user_data)
+static void on_load_clicked(GtkButton *button, gpointer user_data)
 {
 	on_load1_activate(NULL, user_data);
 }
 
-
-void on_single_clicked(GtkButton * button, gpointer user_data)
+static void on_save_clicked(GtkButton *button, gpointer user_data)
 {
-	view_mode = SINGLE_VIEW;
-	gtk_widget_hide(tree1_w);
-	current = &rootmenu;
-	display_tree_part();
+	on_save_activate(NULL, user_data);
 }
 
+static void on_single_clicked(GtkButton *button, gpointer user_data)
+{
+	set_view_mode(SINGLE_VIEW);
+}
 
-void on_split_clicked(GtkButton * button, gpointer user_data)
+static void on_split_clicked(GtkButton *button, gpointer user_data)
 {
-	gint w, h;
-	view_mode = SPLIT_VIEW;
-	gtk_widget_show(tree1_w);
-	gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h);
-	gtk_paned_set_position(GTK_PANED(hpaned), w / 2);
-	if (tree2)
-		gtk_tree_store_clear(tree2);
-	display_list();
+	set_view_mode(SPLIT_VIEW);
+}
 
-	/* Disable back btn, like in full mode. */
-	gtk_widget_set_sensitive(back_btn, FALSE);
+static void on_full_clicked(GtkButton *button, gpointer user_data)
+{
+	set_view_mode(FULL_VIEW);
 }
 
+static void on_collapse_clicked(GtkButton *button, gpointer user_data)
+{
+	gtk_tree_view_collapse_all(GTK_TREE_VIEW(tree2_w));
+}
 
-void on_full_clicked(GtkButton * button, gpointer user_data)
+static void on_expand_clicked(GtkButton *button, gpointer user_data)
 {
-	view_mode = FULL_VIEW;
-	gtk_widget_hide(tree1_w);
-	if (tree2)
-		gtk_tree_store_clear(tree2);
-	display_tree(&rootmenu);
-	gtk_widget_set_sensitive(back_btn, FALSE);
+	gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w));
 }
 
+/* Main Windows Callbacks */
 
-void on_collapse_clicked(GtkButton * button, gpointer user_data)
+static void on_window1_destroy(GtkWidget *widget, gpointer user_data)
 {
-	gtk_tree_view_collapse_all(GTK_TREE_VIEW(tree2_w));
+	gtk_main_quit();
 }
 
+static gboolean on_window1_configure(GtkWidget *self,
+				     GdkEventConfigure *event,
+				     gpointer user_data)
+{
+	gtk_paned_set_position(GTK_PANED(vpaned), 2 * event->height / 3);
+	return FALSE;
+}
 
-void on_expand_clicked(GtkButton * button, gpointer user_data)
+static gboolean on_window1_delete_event(GtkWidget *widget, GdkEvent *event,
+					gpointer user_data)
 {
-	gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w));
+	GtkWidget *dialog, *label, *content_area;
+	gint result;
+	gint ret = FALSE;
+
+	if (!conf_get_changed())
+		return FALSE;
+
+	dialog = gtk_dialog_new_with_buttons("Warning !",
+					     GTK_WINDOW(main_wnd),
+					     (GtkDialogFlags)
+					     (GTK_DIALOG_MODAL |
+					      GTK_DIALOG_DESTROY_WITH_PARENT),
+					     "_OK",
+					     GTK_RESPONSE_YES,
+					     "_No",
+					     GTK_RESPONSE_NO,
+					     "_Cancel",
+					     GTK_RESPONSE_CANCEL, NULL);
+	gtk_dialog_set_default_response(GTK_DIALOG(dialog),
+					GTK_RESPONSE_CANCEL);
+
+	label = gtk_label_new("\nSave configuration ?\n");
+	content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+	gtk_container_add(GTK_CONTAINER(content_area), label);
+	gtk_widget_show(label);
+
+	result = gtk_dialog_run(GTK_DIALOG(dialog));
+	switch (result) {
+	case GTK_RESPONSE_YES:
+		on_save_activate(NULL, NULL);
+		break;
+	case GTK_RESPONSE_NO:
+		break;
+	case GTK_RESPONSE_CANCEL:
+	case GTK_RESPONSE_DELETE_EVENT:
+	default:
+		ret = TRUE;
+		break;
+	}
+
+	gtk_widget_destroy(dialog);
+
+	if (!ret)
+		g_object_unref(pix_menu);
+
+	return ret;
 }
 
+static void on_quit1_activate(GtkMenuItem *menuitem, gpointer user_data)
+{
+	if (!on_window1_delete_event(NULL, NULL, NULL))
+		gtk_widget_destroy(GTK_WIDGET(main_wnd));
+}
 
 /* CTree Callbacks */
 
@@ -741,25 +657,28 @@ static void renderer_edited(GtkCellRendererText * cell,
 			    const gchar * path_string,
 			    const gchar * new_text, gpointer user_data)
 {
+	GtkTreeView *view = GTK_TREE_VIEW(user_data);
+	GtkTreeModel *model = gtk_tree_view_get_model(view);
 	GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
 	GtkTreeIter iter;
 	const char *old_def, *new_def;
 	struct menu *menu;
 	struct symbol *sym;
 
-	if (!gtk_tree_model_get_iter(model2, &iter, path))
-		return;
+	if (!gtk_tree_model_get_iter(model, &iter, path))
+		goto free;
 
-	gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
+	gtk_tree_model_get(model, &iter, COL_MENU, &menu, -1);
 	sym = menu->sym;
 
-	gtk_tree_model_get(model2, &iter, COL_VALUE, &old_def, -1);
+	gtk_tree_model_get(model, &iter, COL_VALUE, &old_def, -1);
 	new_def = new_text;
 
 	sym_set_string_value(sym, new_def);
 
-	update_tree(&rootmenu, NULL);
+	update_trees();
 
+free:
 	gtk_tree_path_free(path);
 }
 
@@ -787,14 +706,7 @@ static void change_sym_value(struct menu *menu, gint col)
 		if (!sym_tristate_within_range(sym, newval))
 			newval = yes;
 		sym_set_tristate_value(sym, newval);
-		if (view_mode == FULL_VIEW)
-			update_tree(&rootmenu, NULL);
-		else if (view_mode == SPLIT_VIEW) {
-			update_tree(browsed, NULL);
-			display_list();
-		}
-		else if (view_mode == SINGLE_VIEW)
-			display_tree_part();	//fixme: keep exp/coll
+		update_trees();
 		break;
 	case S_INT:
 	case S_HEX:
@@ -810,14 +722,7 @@ static void toggle_sym_value(struct menu *menu)
 		return;
 
 	sym_toggle_tristate_value(menu->sym);
-	if (view_mode == FULL_VIEW)
-		update_tree(&rootmenu, NULL);
-	else if (view_mode == SPLIT_VIEW) {
-		update_tree(browsed, NULL);
-		display_list();
-	}
-	else if (view_mode == SINGLE_VIEW)
-		display_tree_part();	//fixme: keep exp/coll
+	update_trees();
 }
 
 static gint column2index(GtkTreeViewColumn * column)
@@ -837,43 +742,39 @@ static gint column2index(GtkTreeViewColumn * column)
 
 
 /* User click: update choice (full) or goes down (single) */
-gboolean
-on_treeview2_button_press_event(GtkWidget * widget,
-				GdkEventButton * event, gpointer user_data)
+static gboolean on_treeview2_button_press_event(GtkWidget *widget,
+						GdkEventButton *event,
+						gpointer user_data)
 {
 	GtkTreeView *view = GTK_TREE_VIEW(widget);
+	GtkTreeModel *model = gtk_tree_view_get_model(view);
 	GtkTreePath *path;
 	GtkTreeViewColumn *column;
 	GtkTreeIter iter;
 	struct menu *menu;
 	gint col;
-
-#if GTK_CHECK_VERSION(2,1,4) // bug in ctree with earlier version of GTK
 	gint tx = (gint) event->x;
 	gint ty = (gint) event->y;
-	gint cx, cy;
 
-	gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx,
-				      &cy);
-#else
-	gtk_tree_view_get_cursor(view, &path, &column);
-#endif
+	gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, NULL, NULL);
 	if (path == NULL)
 		return FALSE;
 
-	if (!gtk_tree_model_get_iter(model2, &iter, path))
+	if (!gtk_tree_model_get_iter(model, &iter, path))
 		return FALSE;
-	gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
+	gtk_tree_model_get(model, &iter, COL_MENU, &menu, -1);
+
+	selected = menu;
 
 	col = column2index(column);
 	if (event->type == GDK_2BUTTON_PRESS) {
 		enum prop_type ptype;
 		ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
 
-		if (ptype == P_MENU && view_mode != FULL_VIEW && col == COL_OPTION) {
+		if (ptype == P_MENU && view_mode == SINGLE_VIEW && col == COL_OPTION) {
 			// goes down into menu
-			current = menu;
-			display_tree_part();
+			browsed = menu;
+			recreate_tree();
 			gtk_widget_set_sensitive(back_btn, TRUE);
 		} else if (col == COL_OPTION) {
 			toggle_sym_value(menu);
@@ -894,35 +795,31 @@ on_treeview2_button_press_event(GtkWidget * widget,
 }
 
 /* Key pressed: update choice */
-gboolean
-on_treeview2_key_press_event(GtkWidget * widget,
-			     GdkEventKey * event, gpointer user_data)
+static gboolean on_treeview2_key_press_event(GtkWidget *widget,
+					     GdkEventKey *event,
+					     gpointer user_data)
 {
 	GtkTreeView *view = GTK_TREE_VIEW(widget);
+	GtkTreeModel *model = gtk_tree_view_get_model(view);
 	GtkTreePath *path;
-	GtkTreeViewColumn *column;
 	GtkTreeIter iter;
 	struct menu *menu;
 	gint col;
 
-	gtk_tree_view_get_cursor(view, &path, &column);
+	gtk_tree_view_get_cursor(view, &path, NULL);
 	if (path == NULL)
 		return FALSE;
 
-	if (event->keyval == GDK_space) {
+	if (event->keyval == GDK_KEY_space) {
 		if (gtk_tree_view_row_expanded(view, path))
 			gtk_tree_view_collapse_row(view, path);
 		else
 			gtk_tree_view_expand_row(view, path, FALSE);
 		return TRUE;
 	}
-	if (event->keyval == GDK_KP_Enter) {
-	}
-	if (widget == tree1_w)
-		return FALSE;
 
-	gtk_tree_model_get_iter(model2, &iter, path);
-	gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
+	gtk_tree_model_get_iter(model, &iter, path);
+	gtk_tree_model_get(model, &iter, COL_MENU, &menu, -1);
 
 	if (!strcasecmp(event->string, "n"))
 		col = COL_NO;
@@ -931,377 +828,82 @@ on_treeview2_key_press_event(GtkWidget * widget,
 	else if (!strcasecmp(event->string, "y"))
 		col = COL_YES;
 	else
-		col = -1;
-	change_sym_value(menu, col);
-
-	return FALSE;
-}
-
-
-/* Row selection changed: update help */
-void
-on_treeview2_cursor_changed(GtkTreeView * treeview, gpointer user_data)
-{
-	GtkTreeSelection *selection;
-	GtkTreeIter iter;
-	struct menu *menu;
-
-	selection = gtk_tree_view_get_selection(treeview);
-	if (gtk_tree_selection_get_selected(selection, &model2, &iter)) {
-		gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
-		text_insert_help(menu);
-	}
-}
-
-
-/* User click: display sub-tree in the right frame. */
-gboolean
-on_treeview1_button_press_event(GtkWidget * widget,
-				GdkEventButton * event, gpointer user_data)
-{
-	GtkTreeView *view = GTK_TREE_VIEW(widget);
-	GtkTreePath *path;
-	GtkTreeViewColumn *column;
-	GtkTreeIter iter;
-	struct menu *menu;
-
-	gint tx = (gint) event->x;
-	gint ty = (gint) event->y;
-	gint cx, cy;
-
-	gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx,
-				      &cy);
-	if (path == NULL)
-		return FALSE;
-
-	gtk_tree_model_get_iter(model1, &iter, path);
-	gtk_tree_model_get(model1, &iter, COL_MENU, &menu, -1);
-
-	if (event->type == GDK_2BUTTON_PRESS) {
-		toggle_sym_value(menu);
-		current = menu;
-		display_tree_part();
-	} else {
-		browsed = menu;
-		display_tree_part();
-	}
-
-	gtk_widget_realize(tree2_w);
-	gtk_tree_view_set_cursor(view, path, NULL, FALSE);
-	gtk_widget_grab_focus(tree2_w);
-
-	return FALSE;
-}
-
-
-/* Fill a row of strings */
-static gchar **fill_row(struct menu *menu)
-{
-	static gchar *row[COL_NUMBER];
-	struct symbol *sym = menu->sym;
-	const char *def;
-	int stype;
-	tristate val;
-	enum prop_type ptype;
-	int i;
-
-	for (i = COL_OPTION; i <= COL_COLOR; i++)
-		g_free(row[i]);
-	bzero(row, sizeof(row));
-
-	ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
-
-	row[COL_OPTION] =
-	    g_strdup_printf("%s %s %s %s",
-			    ptype == P_COMMENT ? "***" : "",
-			    menu_get_prompt(menu),
-			    ptype == P_COMMENT ? "***" : "",
-			    sym && !sym_has_value(sym) ? "(NEW)" : "");
-
-	if (opt_mode == OPT_ALL && !menu_is_visible(menu))
-		row[COL_COLOR] = g_strdup("DarkGray");
-	else if (opt_mode == OPT_PROMPT &&
-			menu_has_prompt(menu) && !menu_is_visible(menu))
-		row[COL_COLOR] = g_strdup("DarkGray");
-	else
-		row[COL_COLOR] = g_strdup("Black");
-
-	switch (ptype) {
-	case P_MENU:
-		row[COL_PIXBUF] = (gchar *) xpm_menu;
-		if (view_mode == SINGLE_VIEW)
-			row[COL_PIXVIS] = GINT_TO_POINTER(TRUE);
-		row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
-		break;
-	case P_COMMENT:
-		row[COL_PIXBUF] = (gchar *) xpm_void;
-		row[COL_PIXVIS] = GINT_TO_POINTER(FALSE);
-		row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
-		break;
-	default:
-		row[COL_PIXBUF] = (gchar *) xpm_void;
-		row[COL_PIXVIS] = GINT_TO_POINTER(FALSE);
-		row[COL_BTNVIS] = GINT_TO_POINTER(TRUE);
-		break;
-	}
-
-	if (!sym)
-		return row;
-	row[COL_NAME] = g_strdup(sym->name);
-
-	sym_calc_value(sym);
-	menu->flags &= ~MENU_CHANGED;
-
-	if (sym_is_choice(sym)) {	// parse childs for getting final value
-		struct menu *child;
-		struct symbol *def_sym = sym_calc_choice(menu);
-		struct menu *def_menu = NULL;
-
-		for (child = menu->list; child; child = child->next) {
-			if (menu_is_visible(child)
-			    && child->sym == def_sym)
-				def_menu = child;
-		}
-
-		if (def_menu)
-			row[COL_VALUE] =
-			    g_strdup(menu_get_prompt(def_menu));
-
-		row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
-		return row;
-	}
-	if (sym_is_choice_value(sym))
-		row[COL_BTNRAD] = GINT_TO_POINTER(TRUE);
-
-	stype = sym_get_type(sym);
-	switch (stype) {
-	case S_BOOLEAN:
-	case S_TRISTATE:
-		val = sym_get_tristate_value(sym);
-		switch (val) {
-		case no:
-			row[COL_NO] = g_strdup("N");
-			row[COL_VALUE] = g_strdup("N");
-			row[COL_BTNACT] = GINT_TO_POINTER(FALSE);
-			row[COL_BTNINC] = GINT_TO_POINTER(FALSE);
-			break;
-		case mod:
-			row[COL_MOD] = g_strdup("M");
-			row[COL_VALUE] = g_strdup("M");
-			row[COL_BTNINC] = GINT_TO_POINTER(TRUE);
-			break;
-		case yes:
-			row[COL_YES] = g_strdup("Y");
-			row[COL_VALUE] = g_strdup("Y");
-			row[COL_BTNACT] = GINT_TO_POINTER(TRUE);
-			row[COL_BTNINC] = GINT_TO_POINTER(FALSE);
-			break;
-		}
-
-		if (val != no && sym_tristate_within_range(sym, no))
-			row[COL_NO] = g_strdup("_");
-		if (val != mod && sym_tristate_within_range(sym, mod))
-			row[COL_MOD] = g_strdup("_");
-		if (val != yes && sym_tristate_within_range(sym, yes))
-			row[COL_YES] = g_strdup("_");
-		break;
-	case S_INT:
-	case S_HEX:
-	case S_STRING:
-		def = sym_get_string_value(sym);
-		row[COL_VALUE] = g_strdup(def);
-		row[COL_EDIT] = GINT_TO_POINTER(TRUE);
-		row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
-		break;
-	}
-
-	return row;
-}
-
-
-/* Set the node content with a row of strings */
-static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row)
-{
-	GdkColor color;
-	gboolean success;
-	GdkPixbuf *pix;
-
-	pix = gdk_pixbuf_new_from_xpm_data((const char **)
-					   row[COL_PIXBUF]);
-
-	gdk_color_parse(row[COL_COLOR], &color);
-	gdk_colormap_alloc_colors(gdk_colormap_get_system(), &color, 1,
-				  FALSE, FALSE, &success);
-
-	gtk_tree_store_set(tree, node,
-			   COL_OPTION, row[COL_OPTION],
-			   COL_NAME, row[COL_NAME],
-			   COL_NO, row[COL_NO],
-			   COL_MOD, row[COL_MOD],
-			   COL_YES, row[COL_YES],
-			   COL_VALUE, row[COL_VALUE],
-			   COL_MENU, (gpointer) menu,
-			   COL_COLOR, &color,
-			   COL_EDIT, GPOINTER_TO_INT(row[COL_EDIT]),
-			   COL_PIXBUF, pix,
-			   COL_PIXVIS, GPOINTER_TO_INT(row[COL_PIXVIS]),
-			   COL_BTNVIS, GPOINTER_TO_INT(row[COL_BTNVIS]),
-			   COL_BTNACT, GPOINTER_TO_INT(row[COL_BTNACT]),
-			   COL_BTNINC, GPOINTER_TO_INT(row[COL_BTNINC]),
-			   COL_BTNRAD, GPOINTER_TO_INT(row[COL_BTNRAD]),
-			   -1);
-
-	g_object_unref(pix);
-}
-
-
-/* Add a node to the tree */
-static void place_node(struct menu *menu, char **row)
-{
-	GtkTreeIter *parent = parents[indent - 1];
-	GtkTreeIter *node = parents[indent];
+		col = -1;
+	change_sym_value(menu, col);
 
-	gtk_tree_store_append(tree, node, parent);
-	set_node(node, menu, row);
+	return FALSE;
 }
 
 
-/* Find a node in the GTK+ tree */
-static GtkTreeIter found;
-
-/*
- * Find a menu in the GtkTree starting at parent.
- */
-static GtkTreeIter *gtktree_iter_find_node(GtkTreeIter *parent,
-					   struct menu *tofind)
+/* Row selection changed: update help */
+static void on_treeview2_cursor_changed(GtkTreeView *treeview,
+					gpointer user_data)
 {
+	GtkTreeModel *model = gtk_tree_view_get_model(treeview);
+	GtkTreeSelection *selection;
 	GtkTreeIter iter;
-	GtkTreeIter *child = &iter;
-	gboolean valid;
-	GtkTreeIter *ret;
-
-	valid = gtk_tree_model_iter_children(model2, child, parent);
-	while (valid) {
-		struct menu *menu;
-
-		gtk_tree_model_get(model2, child, 6, &menu, -1);
-
-		if (menu == tofind) {
-			memcpy(&found, child, sizeof(GtkTreeIter));
-			return &found;
-		}
-
-		ret = gtktree_iter_find_node(child, tofind);
-		if (ret)
-			return ret;
+	struct menu *menu;
 
-		valid = gtk_tree_model_iter_next(model2, child);
+	selection = gtk_tree_view_get_selection(treeview);
+	if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
+		gtk_tree_model_get(model, &iter, COL_MENU, &menu, -1);
+		text_insert_help(menu);
 	}
-
-	return NULL;
 }
 
 
-/*
- * Update the tree by adding/removing entries
- * Does not change other nodes
- */
-static void update_tree(struct menu *src, GtkTreeIter * dst)
+/* User click: display sub-tree in the right frame. */
+static gboolean on_treeview1_button_press_event(GtkWidget *widget,
+						GdkEventButton *event,
+						gpointer user_data)
 {
-	struct menu *child1;
-	GtkTreeIter iter, tmp;
-	GtkTreeIter *child2 = &iter;
-	gboolean valid;
-	GtkTreeIter *sibling;
-	struct symbol *sym;
-	struct menu *menu1, *menu2;
+	GtkTreeView *view = GTK_TREE_VIEW(widget);
+	GtkTreeModel *model = gtk_tree_view_get_model(view);
+	GtkTreePath *path;
+	GtkTreeIter iter;
+	struct menu *menu;
+	gint tx = (gint) event->x;
+	gint ty = (gint) event->y;
 
-	if (src == &rootmenu)
-		indent = 1;
+	gtk_tree_view_get_path_at_pos(view, tx, ty, &path, NULL, NULL, NULL);
+	if (path == NULL)
+		return FALSE;
 
-	valid = gtk_tree_model_iter_children(model2, child2, dst);
-	for (child1 = src->list; child1; child1 = child1->next) {
+	gtk_tree_model_get_iter(model, &iter, path);
+	gtk_tree_model_get(model, &iter, COL_MENU, &menu, -1);
 
-		sym = child1->sym;
+	if (event->type == GDK_2BUTTON_PRESS)
+		toggle_sym_value(menu);
 
-	      reparse:
-		menu1 = child1;
-		if (valid)
-			gtk_tree_model_get(model2, child2, COL_MENU,
-					   &menu2, -1);
-		else
-			menu2 = NULL;	// force adding of a first child
-
-		if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) ||
-		    (opt_mode == OPT_PROMPT && !menu_has_prompt(child1)) ||
-		    (opt_mode == OPT_ALL    && !menu_get_prompt(child1))) {
-
-			/* remove node */
-			if (gtktree_iter_find_node(dst, menu1) != NULL) {
-				memcpy(&tmp, child2, sizeof(GtkTreeIter));
-				valid = gtk_tree_model_iter_next(model2,
-								 child2);
-				gtk_tree_store_remove(tree2, &tmp);
-				if (!valid)
-					return;		/* next parent */
-				else
-					goto reparse;	/* next child */
-			} else
-				continue;
-		}
+	selected = menu;
 
-		if (menu1 != menu2) {
-			if (gtktree_iter_find_node(dst, menu1) == NULL) {	// add node
-				if (!valid && !menu2)
-					sibling = NULL;
-				else
-					sibling = child2;
-				gtk_tree_store_insert_before(tree2,
-							     child2,
-							     dst, sibling);
-				set_node(child2, menu1, fill_row(menu1));
-				if (menu2 == NULL)
-					valid = TRUE;
-			} else {	// remove node
-				memcpy(&tmp, child2, sizeof(GtkTreeIter));
-				valid = gtk_tree_model_iter_next(model2,
-								 child2);
-				gtk_tree_store_remove(tree2, &tmp);
-				if (!valid)
-					return;	// next parent
-				else
-					goto reparse;	// next child
-			}
-		} else if (sym && (child1->flags & MENU_CHANGED)) {
-			set_node(child2, menu1, fill_row(menu1));
-		}
+	if (menu->type == M_MENU) {
+		browsed = menu;
+		recreate_tree();
+	}
 
-		indent++;
-		update_tree(child1, child2);
-		indent--;
+	gtk_tree_view_set_cursor(view, path, NULL, FALSE);
+	gtk_widget_grab_focus(tree2_w);
 
-		valid = gtk_tree_model_iter_next(model2, child2);
-	}
+	return FALSE;
 }
 
-
 /* Display the whole tree (single/split/full view) */
-static void display_tree(struct menu *menu)
+static void _display_tree(GtkTreeStore *tree, struct menu *menu,
+			  GtkTreeIter *parent)
 {
-	struct property *prop;
 	struct menu *child;
-	enum prop_type ptype;
-
-	if (menu == &rootmenu) {
-		indent = 1;
-		current = &rootmenu;
-	}
+	GtkTreeIter iter;
 
 	for (child = menu->list; child; child = child->next) {
-		prop = child->prompt;
-		ptype = prop ? prop->type : P_UNKNOWN;
-
-		menu->flags &= ~MENU_CHANGED;
+		/*
+		 * REVISIT:
+		 * menu_finalize() creates empty "if" entries.
+		 * Do not confuse gtk_tree_model_get(), which would otherwise
+		 * return "if" menu entry.
+		 */
+		if (child->type == M_IF)
+			continue;
 
 		if ((view_mode == SPLIT_VIEW)
 		    && !(child->flags & MENU_ROOT) && (tree == tree1))
@@ -1311,58 +913,25 @@ static void display_tree(struct menu *menu)
 		    && (tree == tree2))
 			continue;
 
-		if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) ||
-		    (opt_mode == OPT_PROMPT && menu_has_prompt(child)) ||
-		    (opt_mode == OPT_ALL    && menu_get_prompt(child)))
-			place_node(child, fill_row(child));
-
-		if ((view_mode != FULL_VIEW) && (ptype == P_MENU)
-		    && (tree == tree2))
-			continue;
-/*
-		if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT))
-		    || (view_mode == FULL_VIEW)
-		    || (view_mode == SPLIT_VIEW))*/
-
-		/* Change paned position if the view is not in 'split mode' */
-		if (view_mode == SINGLE_VIEW || view_mode == FULL_VIEW) {
-			gtk_paned_set_position(GTK_PANED(hpaned), 0);
-		}
+		gtk_tree_store_append(tree, &iter, parent);
+		set_node(tree, &iter, child);
 
-		if (((view_mode == SINGLE_VIEW) && (menu->flags & MENU_ROOT))
-		    || (view_mode == FULL_VIEW)
-		    || (view_mode == SPLIT_VIEW)) {
-			indent++;
-			display_tree(child);
-			indent--;
-		}
+		if (view_mode != SINGLE_VIEW || child->type != M_MENU)
+			_display_tree(tree, child, &iter);
 	}
 }
 
-/* Display a part of the tree starting at current node (single/split view) */
-static void display_tree_part(void)
+static void display_tree(GtkTreeStore *store, struct menu *menu)
 {
-	if (tree2)
-		gtk_tree_store_clear(tree2);
-	if (view_mode == SINGLE_VIEW)
-		display_tree(current);
-	else if (view_mode == SPLIT_VIEW)
-		display_tree(browsed);
-	else if (view_mode == FULL_VIEW)
-		display_tree(&rootmenu);
-	gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w));
+	_display_tree(store, menu, NULL);
 }
 
-/* Display the list in the left frame (split view) */
-static void display_list(void)
+/* Recreate the tree store starting at 'browsed' node */
+static void recreate_tree(void)
 {
-	if (tree1)
-		gtk_tree_store_clear(tree1);
-
-	tree = tree1;
-	display_tree(&rootmenu);
-	gtk_tree_view_expand_all(GTK_TREE_VIEW(tree1_w));
-	tree = tree2;
+	gtk_tree_store_clear(tree2);
+	display_tree(tree2, browsed);
+	gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w));
 }
 
 static void fixup_rootmenu(struct menu *menu)
@@ -1381,6 +950,335 @@ static void fixup_rootmenu(struct menu *menu)
 	}
 }
 
+/* Main Window Initialization */
+static void replace_button_icon(GtkWidget *widget, const char * const xpm[])
+{
+	GdkPixbuf *pixbuf;
+	GtkWidget *image;
+
+	pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)xpm);
+	image = gtk_image_new_from_pixbuf(pixbuf);
+	g_object_unref(pixbuf);
+
+	gtk_widget_show(image);
+	gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(widget), image);
+}
+
+static void init_main_window(const gchar *glade_file)
+{
+	GtkBuilder *builder;
+	GtkWidget *widget;
+	GtkTextBuffer *txtbuf;
+
+	builder = gtk_builder_new_from_file(glade_file);
+	if (!builder)
+		g_error("GUI loading failed !\n");
+
+	main_wnd = GTK_WIDGET(gtk_builder_get_object(builder, "window1"));
+	g_signal_connect(main_wnd, "destroy",
+			 G_CALLBACK(on_window1_destroy), NULL);
+	g_signal_connect(main_wnd, "configure-event",
+			 G_CALLBACK(on_window1_configure), NULL);
+	g_signal_connect(main_wnd, "delete-event",
+			 G_CALLBACK(on_window1_delete_event), NULL);
+
+	hpaned = GTK_WIDGET(gtk_builder_get_object(builder, "hpaned1"));
+	vpaned = GTK_WIDGET(gtk_builder_get_object(builder, "vpaned1"));
+	tree1_w = GTK_WIDGET(gtk_builder_get_object(builder, "treeview1"));
+	g_signal_connect(tree1_w, "cursor-changed",
+			 G_CALLBACK(on_treeview2_cursor_changed), NULL);
+	g_signal_connect(tree1_w, "button-press-event",
+			 G_CALLBACK(on_treeview1_button_press_event), NULL);
+	g_signal_connect(tree1_w, "key-press-event",
+			 G_CALLBACK(on_treeview2_key_press_event), NULL);
+
+	tree2_w = GTK_WIDGET(gtk_builder_get_object(builder, "treeview2"));
+	g_signal_connect(tree2_w, "cursor-changed",
+			 G_CALLBACK(on_treeview2_cursor_changed), NULL);
+	g_signal_connect(tree2_w, "button-press-event",
+			 G_CALLBACK(on_treeview2_button_press_event), NULL);
+	g_signal_connect(tree2_w, "key-press-event",
+			 G_CALLBACK(on_treeview2_key_press_event), NULL);
+
+	text_w = GTK_WIDGET(gtk_builder_get_object(builder, "textview3"));
+
+	/* menubar */
+	widget = GTK_WIDGET(gtk_builder_get_object(builder, "load1"));
+	g_signal_connect(widget, "activate",
+			 G_CALLBACK(on_load1_activate), NULL);
+
+	save_menu_item = GTK_WIDGET(gtk_builder_get_object(builder, "save1"));
+	g_signal_connect(save_menu_item, "activate",
+			 G_CALLBACK(on_save_activate), NULL);
+
+	widget = GTK_WIDGET(gtk_builder_get_object(builder, "save_as1"));
+	g_signal_connect(widget, "activate",
+			 G_CALLBACK(on_save_as1_activate), NULL);
+
+	widget = GTK_WIDGET(gtk_builder_get_object(builder, "quit1"));
+	g_signal_connect(widget, "activate",
+			 G_CALLBACK(on_quit1_activate), NULL);
+
+	widget = GTK_WIDGET(gtk_builder_get_object(builder, "show_name1"));
+	g_signal_connect(widget, "activate",
+			 G_CALLBACK(on_show_name1_activate), NULL);
+	gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
+				       show_name);
+
+	widget = GTK_WIDGET(gtk_builder_get_object(builder, "show_range1"));
+	g_signal_connect(widget, "activate",
+			 G_CALLBACK(on_show_range1_activate), NULL);
+	gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
+				       show_range);
+
+	widget = GTK_WIDGET(gtk_builder_get_object(builder, "show_data1"));
+	g_signal_connect(widget, "activate",
+			 G_CALLBACK(on_show_data1_activate), NULL);
+	gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
+				       show_value);
+
+	widget = GTK_WIDGET(gtk_builder_get_object(builder, "set_option_mode1"));
+	g_signal_connect(widget, "activate",
+			 G_CALLBACK(on_set_option_mode1_activate), NULL);
+
+	widget = GTK_WIDGET(gtk_builder_get_object(builder, "set_option_mode2"));
+	g_signal_connect(widget, "activate",
+			 G_CALLBACK(on_set_option_mode2_activate), NULL);
+
+	widget = GTK_WIDGET(gtk_builder_get_object(builder, "set_option_mode3"));
+	g_signal_connect(widget, "activate",
+			 G_CALLBACK(on_set_option_mode3_activate), NULL);
+
+	widget = GTK_WIDGET(gtk_builder_get_object(builder, "introduction1"));
+	g_signal_connect(widget, "activate",
+			 G_CALLBACK(on_introduction1_activate), NULL);
+
+	widget = GTK_WIDGET(gtk_builder_get_object(builder, "about1"));
+	g_signal_connect(widget, "activate",
+			 G_CALLBACK(on_about1_activate), NULL);
+
+	widget = GTK_WIDGET(gtk_builder_get_object(builder, "license1"));
+	g_signal_connect(widget, "activate",
+			 G_CALLBACK(on_license1_activate), NULL);
+
+	/* toolbar */
+	back_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button1"));
+	g_signal_connect(back_btn, "clicked",
+			 G_CALLBACK(on_back_clicked), NULL);
+	gtk_widget_set_sensitive(back_btn, FALSE);
+
+	widget = GTK_WIDGET(gtk_builder_get_object(builder, "button2"));
+	g_signal_connect(widget, "clicked",
+			 G_CALLBACK(on_load_clicked), NULL);
+
+	save_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button3"));
+	g_signal_connect(save_btn, "clicked",
+			 G_CALLBACK(on_save_clicked), NULL);
+
+	single_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button4"));
+	g_signal_connect(single_btn, "clicked",
+			 G_CALLBACK(on_single_clicked), NULL);
+	replace_button_icon(single_btn, xpm_single_view);
+
+	split_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button5"));
+	g_signal_connect(split_btn, "clicked",
+			 G_CALLBACK(on_split_clicked), NULL);
+	replace_button_icon(split_btn, xpm_split_view);
+
+	full_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button6"));
+	g_signal_connect(full_btn, "clicked",
+			 G_CALLBACK(on_full_clicked), NULL);
+	replace_button_icon(full_btn, xpm_tree_view);
+
+	widget = GTK_WIDGET(gtk_builder_get_object(builder, "button7"));
+	g_signal_connect(widget, "clicked",
+			 G_CALLBACK(on_collapse_clicked), NULL);
+
+	widget = GTK_WIDGET(gtk_builder_get_object(builder, "button8"));
+	g_signal_connect(widget, "clicked",
+			 G_CALLBACK(on_expand_clicked), NULL);
+
+	txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
+	tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1",
+					  "foreground", "red",
+					  "weight", PANGO_WEIGHT_BOLD,
+					  NULL);
+	tag2 = gtk_text_buffer_create_tag(txtbuf, "mytag2",
+					  /*"style", PANGO_STYLE_OBLIQUE, */
+					  NULL);
+
+	gtk_window_set_title(GTK_WINDOW(main_wnd), rootmenu.prompt->text);
+
+	gtk_widget_show_all(main_wnd);
+
+	g_object_unref(builder);
+
+	conf_set_changed_callback(conf_changed);
+}
+
+static gboolean visible_func(GtkTreeModel *model, GtkTreeIter  *iter,
+			     gpointer data)
+{
+	struct menu *menu;
+
+	gtk_tree_model_get(model, iter, COL_MENU, &menu, -1);
+
+	if (!menu)
+		return FALSE;
+
+	return menu_is_visible(menu) || opt_mode == OPT_ALL ||
+		(opt_mode == OPT_PROMPT && menu_has_prompt(menu));
+}
+
+static void init_left_tree(void)
+{
+	GtkTreeView *view = GTK_TREE_VIEW(tree1_w);
+	GtkCellRenderer *renderer;
+	GtkTreeSelection *sel;
+	GtkTreeViewColumn *column;
+	GtkTreeModel *filter;
+
+	tree1 = gtk_tree_store_new(COL_NUMBER,
+				   G_TYPE_STRING, G_TYPE_STRING,
+				   G_TYPE_STRING, G_TYPE_STRING,
+				   G_TYPE_STRING, G_TYPE_STRING,
+				   G_TYPE_POINTER, GDK_TYPE_RGBA,
+				   G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
+				   G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
+				   G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
+				   G_TYPE_BOOLEAN);
+
+	filter = gtk_tree_model_filter_new(GTK_TREE_MODEL(tree1), NULL);
+
+	gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(filter),
+					       visible_func, NULL, NULL);
+	gtk_tree_view_set_model(view, filter);
+
+	column = gtk_tree_view_column_new();
+	gtk_tree_view_append_column(view, column);
+	gtk_tree_view_column_set_title(column, "Options");
+
+	renderer = gtk_cell_renderer_toggle_new();
+	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
+					renderer, FALSE);
+	gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
+					    renderer,
+					    "active", COL_BTNACT,
+					    "inconsistent", COL_BTNINC,
+					    "visible", COL_BTNVIS,
+					    "radio", COL_BTNRAD, NULL);
+	renderer = gtk_cell_renderer_text_new();
+	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
+					renderer, FALSE);
+	gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
+					    renderer,
+					    "text", COL_OPTION,
+					    "foreground-rgba",
+					    COL_COLOR, NULL);
+
+	sel = gtk_tree_view_get_selection(view);
+	gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
+}
+
+static void init_right_tree(void)
+{
+	GtkTreeView *view = GTK_TREE_VIEW(tree2_w);
+	GtkCellRenderer *renderer;
+	GtkTreeSelection *sel;
+	GtkTreeViewColumn *column;
+	GtkTreeModel *filter;
+	gint i;
+
+	tree2 = gtk_tree_store_new(COL_NUMBER,
+				   G_TYPE_STRING, G_TYPE_STRING,
+				   G_TYPE_STRING, G_TYPE_STRING,
+				   G_TYPE_STRING, G_TYPE_STRING,
+				   G_TYPE_POINTER, GDK_TYPE_RGBA,
+				   G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
+				   G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
+				   G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
+				   G_TYPE_BOOLEAN);
+
+	filter = gtk_tree_model_filter_new(GTK_TREE_MODEL(tree2), NULL);
+
+	gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(filter),
+					       visible_func, NULL, NULL);
+	gtk_tree_view_set_model(view, filter);
+
+	column = gtk_tree_view_column_new();
+	gtk_tree_view_append_column(view, column);
+	gtk_tree_view_column_set_title(column, "Options");
+
+	renderer = gtk_cell_renderer_pixbuf_new();
+	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
+					renderer, FALSE);
+	gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
+					    renderer,
+					    "pixbuf", COL_PIXBUF,
+					    "visible", COL_PIXVIS, NULL);
+	renderer = gtk_cell_renderer_toggle_new();
+	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
+					renderer, FALSE);
+	gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
+					    renderer,
+					    "active", COL_BTNACT,
+					    "inconsistent", COL_BTNINC,
+					    "visible", COL_BTNVIS,
+					    "radio", COL_BTNRAD, NULL);
+	renderer = gtk_cell_renderer_text_new();
+	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
+					renderer, FALSE);
+	gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
+					    renderer,
+					    "text", COL_OPTION,
+					    "foreground-rgba",
+					    COL_COLOR, NULL);
+
+	renderer = gtk_cell_renderer_text_new();
+	gtk_tree_view_insert_column_with_attributes(view, -1,
+						    "Name", renderer,
+						    "text", COL_NAME,
+						    "foreground-rgba",
+						    COL_COLOR, NULL);
+	renderer = gtk_cell_renderer_text_new();
+	gtk_tree_view_insert_column_with_attributes(view, -1,
+						    "N", renderer,
+						    "text", COL_NO,
+						    "foreground-rgba",
+						    COL_COLOR, NULL);
+	renderer = gtk_cell_renderer_text_new();
+	gtk_tree_view_insert_column_with_attributes(view, -1,
+						    "M", renderer,
+						    "text", COL_MOD,
+						    "foreground-rgba",
+						    COL_COLOR, NULL);
+	renderer = gtk_cell_renderer_text_new();
+	gtk_tree_view_insert_column_with_attributes(view, -1,
+						    "Y", renderer,
+						    "text", COL_YES,
+						    "foreground-rgba",
+						    COL_COLOR, NULL);
+	renderer = gtk_cell_renderer_text_new();
+	gtk_tree_view_insert_column_with_attributes(view, -1,
+						    "Value", renderer,
+						    "text", COL_VALUE,
+						    "editable",
+						    COL_EDIT,
+						    "foreground-rgba",
+						    COL_COLOR, NULL);
+	g_signal_connect(G_OBJECT(renderer), "edited",
+			 G_CALLBACK(renderer_edited), tree2_w);
+
+	pix_menu = gdk_pixbuf_new_from_xpm_data((const char **)xpm_menu);
+
+	for (i = 0; i < COL_VALUE; i++) {
+		column = gtk_tree_view_get_column(view, i);
+		gtk_tree_view_column_set_resizable(column, TRUE);
+	}
+
+	sel = gtk_tree_view_get_selection(view);
+	gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
+}
 
 /* Main */
 int main(int ac, char *av[])
@@ -1390,18 +1288,16 @@ int main(int ac, char *av[])
 	gchar *glade_file;
 
 	/* GTK stuffs */
-	gtk_set_locale();
 	gtk_init(&ac, &av);
-	glade_init();
 
 	/* Determine GUI path */
 	env = getenv(SRCTREE);
 	if (env)
-		glade_file = g_strconcat(env, "/scripts/kconfig/gconf.glade", NULL);
+		glade_file = g_strconcat(env, "/scripts/kconfig/gconf.ui", NULL);
 	else if (av[0][0] == '/')
-		glade_file = g_strconcat(av[0], ".glade", NULL);
+		glade_file = g_strconcat(av[0], ".ui", NULL);
 	else
-		glade_file = g_strconcat(g_get_current_dir(), "/", av[0], ".glade", NULL);
+		glade_file = g_strconcat(g_get_current_dir(), "/", av[0], ".ui", NULL);
 
 	/* Conf stuffs */
 	if (ac > 1 && av[1][0] == '-') {
@@ -1426,23 +1322,12 @@ int main(int ac, char *av[])
 
 	/* Load the interface and connect signals */
 	init_main_window(glade_file);
-	init_tree_model();
 	init_left_tree();
 	init_right_tree();
 
 	conf_read(NULL);
 
-	switch (view_mode) {
-	case SINGLE_VIEW:
-		display_tree_part();
-		break;
-	case SPLIT_VIEW:
-		display_list();
-		break;
-	case FULL_VIEW:
-		display_tree(&rootmenu);
-		break;
-	}
+	set_view_mode(view_mode);
 
 	gtk_main();
 
diff --git a/scripts/kconfig/gconf.glade b/scripts/kconfig/gconf.ui
similarity index 69%
rename from scripts/kconfig/gconf.glade
rename to scripts/kconfig/gconf.ui
index aa483cb..ab44312 100644
--- a/scripts/kconfig/gconf.glade
+++ b/scripts/kconfig/gconf.ui
@@ -1,8 +1,8 @@
 <?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
 
-<glade-interface>
+<interface>
 
-<widget class="GtkWindow" id="window1">
+<object class="GtkWindow" id="window1">
   <property name="visible">True</property>
   <property name="title" translatable="yes">Gtk Kernel Configurator</property>
   <property name="type">GTK_WINDOW_TOPLEVEL</property>
@@ -17,295 +17,196 @@
   <property name="skip_pager_hint">False</property>
   <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
   <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <signal name="destroy" handler="on_window1_destroy" object="window1"/>
-  <signal name="size_request" handler="on_window1_size_request" object="vpaned1" last_modification_time="Fri, 11 Jan 2002 16:17:11 GMT"/>
-  <signal name="delete_event" handler="on_window1_delete_event" object="window1" last_modification_time="Sun, 09 Mar 2003 19:42:46 GMT"/>
 
   <child>
-    <widget class="GtkVBox" id="vbox1">
+    <object class="GtkBox" id="vbox1">
+      <property name="orientation">vertical</property>
       <property name="visible">True</property>
       <property name="homogeneous">False</property>
       <property name="spacing">0</property>
 
       <child>
-	<widget class="GtkMenuBar" id="menubar1">
+	<object class="GtkMenuBar" id="menubar1">
 	  <property name="visible">True</property>
 
 	  <child>
-	    <widget class="GtkMenuItem" id="file1">
+	    <object class="GtkMenuItem" id="file1">
 	      <property name="visible">True</property>
 	      <property name="label" translatable="yes">_File</property>
 	      <property name="use_underline">True</property>
 
-	      <child>
-		<widget class="GtkMenu" id="file1_menu">
+	      <child type="submenu">
+		<object class="GtkMenu" id="file1_menu">
 
 		  <child>
-		    <widget class="GtkImageMenuItem" id="load1">
+		    <object class="GtkMenuItem" id="load1">
 		      <property name="visible">True</property>
-		      <property name="tooltip" translatable="yes">Load a config file</property>
+		      <property name="tooltip-text" translatable="yes">Load a config file</property>
 		      <property name="label" translatable="yes">_Load</property>
 		      <property name="use_underline">True</property>
-		      <signal name="activate" handler="on_load1_activate"/>
 		      <accelerator key="L" modifiers="GDK_CONTROL_MASK" signal="activate"/>
-
-		      <child internal-child="image">
-			<widget class="GtkImage" id="image39">
-			  <property name="visible">True</property>
-			  <property name="stock">gtk-open</property>
-			  <property name="icon_size">1</property>
-			  <property name="xalign">0.5</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			</widget>
-		      </child>
-		    </widget>
+		    </object>
 		  </child>
 
 		  <child>
-		    <widget class="GtkImageMenuItem" id="save1">
+		    <object class="GtkMenuItem" id="save1">
 		      <property name="visible">True</property>
-		      <property name="tooltip" translatable="yes">Save the config in .config</property>
+		      <property name="tooltip-text" translatable="yes">Save the config in .config</property>
 		      <property name="label" translatable="yes">_Save</property>
 		      <property name="use_underline">True</property>
-		      <signal name="activate" handler="on_save_activate"/>
 		      <accelerator key="S" modifiers="GDK_CONTROL_MASK" signal="activate"/>
-
-		      <child internal-child="image">
-			<widget class="GtkImage" id="image40">
-			  <property name="visible">True</property>
-			  <property name="stock">gtk-save</property>
-			  <property name="icon_size">1</property>
-			  <property name="xalign">0.5</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			</widget>
-		      </child>
-		    </widget>
+		    </object>
 		  </child>
 
 		  <child>
-		    <widget class="GtkImageMenuItem" id="save_as1">
+		    <object class="GtkMenuItem" id="save_as1">
 		      <property name="visible">True</property>
-		      <property name="tooltip" translatable="yes">Save the config in a file</property>
+		      <property name="tooltip-text" translatable="yes">Save the config in a file</property>
 		      <property name="label" translatable="yes">Save _as</property>
 		      <property name="use_underline">True</property>
-		      <signal name="activate" handler="on_save_as1_activate"/>
-
-		      <child internal-child="image">
-			<widget class="GtkImage" id="image41">
-			  <property name="visible">True</property>
-			  <property name="stock">gtk-save-as</property>
-			  <property name="icon_size">1</property>
-			  <property name="xalign">0.5</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			</widget>
-		      </child>
-		    </widget>
+		    </object>
 		  </child>
 
 		  <child>
-		    <widget class="GtkSeparatorMenuItem" id="separator1">
+		    <object class="GtkSeparatorMenuItem" id="separator1">
 		      <property name="visible">True</property>
-		    </widget>
+		    </object>
 		  </child>
 
 		  <child>
-		    <widget class="GtkImageMenuItem" id="quit1">
+		    <object class="GtkMenuItem" id="quit1">
 		      <property name="visible">True</property>
 		      <property name="label" translatable="yes">_Quit</property>
 		      <property name="use_underline">True</property>
-		      <signal name="activate" handler="on_quit1_activate"/>
 		      <accelerator key="Q" modifiers="GDK_CONTROL_MASK" signal="activate"/>
-
-		      <child internal-child="image">
-			<widget class="GtkImage" id="image42">
-			  <property name="visible">True</property>
-			  <property name="stock">gtk-quit</property>
-			  <property name="icon_size">1</property>
-			  <property name="xalign">0.5</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			</widget>
-		      </child>
-		    </widget>
+		    </object>
 		  </child>
-		</widget>
+		</object>
 	      </child>
-	    </widget>
+	    </object>
 	  </child>
 
 	  <child>
-	    <widget class="GtkMenuItem" id="options1">
+	    <object class="GtkMenuItem" id="options1">
 	      <property name="visible">True</property>
 	      <property name="label" translatable="yes">_Options</property>
 	      <property name="use_underline">True</property>
 
-	      <child>
-		<widget class="GtkMenu" id="options1_menu">
+	      <child type="submenu">
+		<object class="GtkMenu" id="options1_menu">
 
 		  <child>
-		    <widget class="GtkCheckMenuItem" id="show_name1">
+		    <object class="GtkCheckMenuItem" id="show_name1">
 		      <property name="visible">True</property>
-		      <property name="tooltip" translatable="yes">Show name</property>
+		      <property name="tooltip-text" translatable="yes">Show name</property>
 		      <property name="label" translatable="yes">Show _name</property>
 		      <property name="use_underline">True</property>
 		      <property name="active">False</property>
-		      <signal name="activate" handler="on_show_name1_activate"/>
-		    </widget>
+		    </object>
 		  </child>
 
 		  <child>
-		    <widget class="GtkCheckMenuItem" id="show_range1">
+		    <object class="GtkCheckMenuItem" id="show_range1">
 		      <property name="visible">True</property>
-		      <property name="tooltip" translatable="yes">Show range (Y/M/N)</property>
+		      <property name="tooltip-text" translatable="yes">Show range (Y/M/N)</property>
 		      <property name="label" translatable="yes">Show _range</property>
 		      <property name="use_underline">True</property>
 		      <property name="active">False</property>
-		      <signal name="activate" handler="on_show_range1_activate"/>
-		    </widget>
+		    </object>
 		  </child>
 
 		  <child>
-		    <widget class="GtkCheckMenuItem" id="show_data1">
+		    <object class="GtkCheckMenuItem" id="show_data1">
 		      <property name="visible">True</property>
-		      <property name="tooltip" translatable="yes">Show value of the option</property>
+		      <property name="tooltip-text" translatable="yes">Show value of the option</property>
 		      <property name="label" translatable="yes">Show _data</property>
 		      <property name="use_underline">True</property>
 		      <property name="active">False</property>
-		      <signal name="activate" handler="on_show_data1_activate"/>
-		    </widget>
+		    </object>
 		  </child>
 
 		  <child>
-		    <widget class="GtkSeparatorMenuItem" id="separator2">
+		    <object class="GtkSeparatorMenuItem" id="separator2">
 		      <property name="visible">True</property>
-		    </widget>
+		    </object>
 		  </child>
 
 		  <child>
-		    <widget class="GtkRadioMenuItem" id="set_option_mode1">
+		    <object class="GtkRadioMenuItem" id="set_option_mode1">
 		      <property name="visible">True</property>
-		      <property name="tooltip" translatable="yes">Show normal options</property>
+		      <property name="tooltip-text" translatable="yes">Show normal options</property>
 		      <property name="label" translatable="yes">Show normal options</property>
 		      <property name="use_underline">True</property>
 		      <property name="active">True</property>
-		      <signal name="activate" handler="on_set_option_mode1_activate"/>
-		    </widget>
+		    </object>
 		  </child>
 
 		  <child>
-		    <widget class="GtkRadioMenuItem" id="set_option_mode2">
+		    <object class="GtkRadioMenuItem" id="set_option_mode2">
 		      <property name="visible">True</property>
-		      <property name="tooltip" translatable="yes">Show all options</property>
+		      <property name="tooltip-text" translatable="yes">Show all options</property>
 		      <property name="label" translatable="yes">Show all _options</property>
 		      <property name="use_underline">True</property>
 		      <property name="active">False</property>
 		      <property name="group">set_option_mode1</property>
-		      <signal name="activate" handler="on_set_option_mode2_activate"/>
-		    </widget>
+		    </object>
 		  </child>
 
 		  <child>
-		    <widget class="GtkRadioMenuItem" id="set_option_mode3">
+		    <object class="GtkRadioMenuItem" id="set_option_mode3">
 		      <property name="visible">True</property>
-		      <property name="tooltip" translatable="yes">Show all options with prompts</property>
+		      <property name="tooltip-text" translatable="yes">Show all options with prompts</property>
 		      <property name="label" translatable="yes">Show all prompt options</property>
 		      <property name="use_underline">True</property>
 		      <property name="active">False</property>
 		      <property name="group">set_option_mode1</property>
-		      <signal name="activate" handler="on_set_option_mode3_activate"/>
-		    </widget>
+		    </object>
 		  </child>
 
-		</widget>
+		</object>
 	      </child>
-	    </widget>
+	    </object>
 	  </child>
 
 	  <child>
-	    <widget class="GtkMenuItem" id="help1">
+	    <object class="GtkMenuItem" id="help1">
 	      <property name="visible">True</property>
 	      <property name="label" translatable="yes">_Help</property>
 	      <property name="use_underline">True</property>
 
-	      <child>
-		<widget class="GtkMenu" id="help1_menu">
+	      <child type="submenu">
+		<object class="GtkMenu" id="help1_menu">
 
 		  <child>
-		    <widget class="GtkImageMenuItem" id="introduction1">
+		    <object class="GtkMenuItem" id="introduction1">
 		      <property name="visible">True</property>
 		      <property name="label" translatable="yes">_Introduction</property>
 		      <property name="use_underline">True</property>
-		      <signal name="activate" handler="on_introduction1_activate" last_modification_time="Fri, 15 Nov 2002 20:26:30 GMT"/>
 		      <accelerator key="I" modifiers="GDK_CONTROL_MASK" signal="activate"/>
-
-		      <child internal-child="image">
-			<widget class="GtkImage" id="image43">
-			  <property name="visible">True</property>
-			  <property name="stock">gtk-dialog-question</property>
-			  <property name="icon_size">1</property>
-			  <property name="xalign">0.5</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			</widget>
-		      </child>
-		    </widget>
+		    </object>
 		  </child>
 
 		  <child>
-		    <widget class="GtkImageMenuItem" id="about1">
+		    <object class="GtkMenuItem" id="about1">
 		      <property name="visible">True</property>
 		      <property name="label" translatable="yes">_About</property>
 		      <property name="use_underline">True</property>
-		      <signal name="activate" handler="on_about1_activate" last_modification_time="Fri, 15 Nov 2002 20:26:30 GMT"/>
 		      <accelerator key="A" modifiers="GDK_CONTROL_MASK" signal="activate"/>
-
-		      <child internal-child="image">
-			<widget class="GtkImage" id="image44">
-			  <property name="visible">True</property>
-			  <property name="stock">gtk-properties</property>
-			  <property name="icon_size">1</property>
-			  <property name="xalign">0.5</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			</widget>
-		      </child>
-		    </widget>
+		    </object>
 		  </child>
 
 		  <child>
-		    <widget class="GtkImageMenuItem" id="license1">
+		    <object class="GtkMenuItem" id="license1">
 		      <property name="visible">True</property>
 		      <property name="label" translatable="yes">_License</property>
 		      <property name="use_underline">True</property>
-		      <signal name="activate" handler="on_license1_activate" last_modification_time="Fri, 15 Nov 2002 20:26:30 GMT"/>
-
-		      <child internal-child="image">
-			<widget class="GtkImage" id="image45">
-			  <property name="visible">True</property>
-			  <property name="stock">gtk-justify-fill</property>
-			  <property name="icon_size">1</property>
-			  <property name="xalign">0.5</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			</widget>
-		      </child>
-		    </widget>
+		    </object>
 		  </child>
-		</widget>
+		</object>
 	      </child>
-	    </widget>
+	    </object>
 	  </child>
-	</widget>
+	</object>
 	<packing>
 	  <property name="padding">0</property>
 	  <property name="expand">False</property>
@@ -314,32 +215,23 @@
       </child>
 
       <child>
-	<widget class="GtkHandleBox" id="handlebox1">
-	  <property name="visible">True</property>
-	  <property name="shadow_type">GTK_SHADOW_OUT</property>
-	  <property name="handle_position">GTK_POS_LEFT</property>
-	  <property name="snap_edge">GTK_POS_TOP</property>
-
-	  <child>
-	    <widget class="GtkToolbar" id="toolbar1">
+	    <object class="GtkToolbar" id="toolbar1">
 	      <property name="visible">True</property>
 	      <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
 	      <property name="toolbar_style">GTK_TOOLBAR_BOTH</property>
-	      <property name="tooltips">True</property>
 	      <property name="show_arrow">True</property>
 
 	      <child>
-		<widget class="GtkToolButton" id="button1">
+		<object class="GtkToolButton" id="button1">
 		  <property name="visible">True</property>
-		  <property name="tooltip" translatable="yes">Goes up of one level (single view)</property>
+		  <property name="tooltip-text" translatable="yes">Goes up one level (single view)</property>
 		  <property name="label" translatable="yes">Back</property>
 		  <property name="use_underline">True</property>
 		  <property name="stock_id">gtk-undo</property>
 		  <property name="visible_horizontal">True</property>
 		  <property name="visible_vertical">True</property>
 		  <property name="is_important">False</property>
-		  <signal name="clicked" handler="on_back_clicked"/>
-		</widget>
+		</object>
 		<packing>
 		  <property name="expand">False</property>
 		  <property name="homogeneous">True</property>
@@ -347,18 +239,18 @@
 	      </child>
 
 	      <child>
-		<widget class="GtkToolItem" id="toolitem1">
+		<object class="GtkToolItem" id="toolitem1">
 		  <property name="visible">True</property>
 		  <property name="visible_horizontal">True</property>
 		  <property name="visible_vertical">True</property>
 		  <property name="is_important">False</property>
 
 		  <child>
-		    <widget class="GtkVSeparator" id="vseparator1">
+		    <object class="GtkVSeparator" id="vseparator1">
 		      <property name="visible">True</property>
-		    </widget>
+		    </object>
 		  </child>
-		</widget>
+		</object>
 		<packing>
 		  <property name="expand">False</property>
 		  <property name="homogeneous">False</property>
@@ -366,17 +258,16 @@
 	      </child>
 
 	      <child>
-		<widget class="GtkToolButton" id="button2">
+		<object class="GtkToolButton" id="button2">
 		  <property name="visible">True</property>
-		  <property name="tooltip" translatable="yes">Load a config file</property>
+		  <property name="tooltip-text" translatable="yes">Load a config file</property>
 		  <property name="label" translatable="yes">Load</property>
 		  <property name="use_underline">True</property>
 		  <property name="stock_id">gtk-open</property>
 		  <property name="visible_horizontal">True</property>
 		  <property name="visible_vertical">True</property>
 		  <property name="is_important">False</property>
-		  <signal name="clicked" handler="on_load_clicked"/>
-		</widget>
+		</object>
 		<packing>
 		  <property name="expand">False</property>
 		  <property name="homogeneous">True</property>
@@ -384,17 +275,16 @@
 	      </child>
 
 	      <child>
-		<widget class="GtkToolButton" id="button3">
+		<object class="GtkToolButton" id="button3">
 		  <property name="visible">True</property>
-		  <property name="tooltip" translatable="yes">Save a config file</property>
+		  <property name="tooltip-text" translatable="yes">Save a config file</property>
 		  <property name="label" translatable="yes">Save</property>
 		  <property name="use_underline">True</property>
 		  <property name="stock_id">gtk-save</property>
 		  <property name="visible_horizontal">True</property>
 		  <property name="visible_vertical">True</property>
 		  <property name="is_important">False</property>
-		  <signal name="clicked" handler="on_save_activate"/>
-		</widget>
+		</object>
 		<packing>
 		  <property name="expand">False</property>
 		  <property name="homogeneous">True</property>
@@ -402,18 +292,18 @@
 	      </child>
 
 	      <child>
-		<widget class="GtkToolItem" id="toolitem2">
+		<object class="GtkToolItem" id="toolitem2">
 		  <property name="visible">True</property>
 		  <property name="visible_horizontal">True</property>
 		  <property name="visible_vertical">True</property>
 		  <property name="is_important">False</property>
 
 		  <child>
-		    <widget class="GtkVSeparator" id="vseparator2">
+		    <object class="GtkVSeparator" id="vseparator2">
 		      <property name="visible">True</property>
-		    </widget>
+		    </object>
 		  </child>
-		</widget>
+		</object>
 		<packing>
 		  <property name="expand">False</property>
 		  <property name="homogeneous">False</property>
@@ -421,17 +311,16 @@
 	      </child>
 
 	      <child>
-		<widget class="GtkToolButton" id="button4">
+		<object class="GtkToolButton" id="button4">
 		  <property name="visible">True</property>
-		  <property name="tooltip" translatable="yes">Single view</property>
+		  <property name="tooltip-text" translatable="yes">Single view</property>
 		  <property name="label" translatable="yes">Single</property>
 		  <property name="use_underline">True</property>
 		  <property name="stock_id">gtk-missing-image</property>
 		  <property name="visible_horizontal">True</property>
 		  <property name="visible_vertical">True</property>
 		  <property name="is_important">False</property>
-		  <signal name="clicked" handler="on_single_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:39 GMT"/>
-		</widget>
+		</object>
 		<packing>
 		  <property name="expand">False</property>
 		  <property name="homogeneous">True</property>
@@ -439,17 +328,16 @@
 	      </child>
 
 	      <child>
-		<widget class="GtkToolButton" id="button5">
+		<object class="GtkToolButton" id="button5">
 		  <property name="visible">True</property>
-		  <property name="tooltip" translatable="yes">Split view</property>
+		  <property name="tooltip-text" translatable="yes">Split view</property>
 		  <property name="label" translatable="yes">Split</property>
 		  <property name="use_underline">True</property>
 		  <property name="stock_id">gtk-missing-image</property>
 		  <property name="visible_horizontal">True</property>
 		  <property name="visible_vertical">True</property>
 		  <property name="is_important">False</property>
-		  <signal name="clicked" handler="on_split_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:45 GMT"/>
-		</widget>
+		</object>
 		<packing>
 		  <property name="expand">False</property>
 		  <property name="homogeneous">True</property>
@@ -457,17 +345,16 @@
 	      </child>
 
 	      <child>
-		<widget class="GtkToolButton" id="button6">
+		<object class="GtkToolButton" id="button6">
 		  <property name="visible">True</property>
-		  <property name="tooltip" translatable="yes">Full view</property>
+		  <property name="tooltip-text" translatable="yes">Full view</property>
 		  <property name="label" translatable="yes">Full</property>
 		  <property name="use_underline">True</property>
 		  <property name="stock_id">gtk-missing-image</property>
 		  <property name="visible_horizontal">True</property>
 		  <property name="visible_vertical">True</property>
 		  <property name="is_important">False</property>
-		  <signal name="clicked" handler="on_full_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:50 GMT"/>
-		</widget>
+		</object>
 		<packing>
 		  <property name="expand">False</property>
 		  <property name="homogeneous">True</property>
@@ -475,18 +362,18 @@
 	      </child>
 
 	      <child>
-		<widget class="GtkToolItem" id="toolitem3">
+		<object class="GtkToolItem" id="toolitem3">
 		  <property name="visible">True</property>
 		  <property name="visible_horizontal">True</property>
 		  <property name="visible_vertical">True</property>
 		  <property name="is_important">False</property>
 
 		  <child>
-		    <widget class="GtkVSeparator" id="vseparator3">
+		    <object class="GtkVSeparator" id="vseparator3">
 		      <property name="visible">True</property>
-		    </widget>
+		    </object>
 		  </child>
-		</widget>
+		</object>
 		<packing>
 		  <property name="expand">False</property>
 		  <property name="homogeneous">False</property>
@@ -494,17 +381,16 @@
 	      </child>
 
 	      <child>
-		<widget class="GtkToolButton" id="button7">
+		<object class="GtkToolButton" id="button7">
 		  <property name="visible">True</property>
-		  <property name="tooltip" translatable="yes">Collapse the whole tree in the right frame</property>
+		  <property name="tooltip-text" translatable="yes">Collapse the whole tree in the right frame</property>
 		  <property name="label" translatable="yes">Collapse</property>
 		  <property name="use_underline">True</property>
 		  <property name="stock_id">gtk-remove</property>
 		  <property name="visible_horizontal">True</property>
 		  <property name="visible_vertical">True</property>
 		  <property name="is_important">False</property>
-		  <signal name="clicked" handler="on_collapse_clicked"/>
-		</widget>
+		</object>
 		<packing>
 		  <property name="expand">False</property>
 		  <property name="homogeneous">True</property>
@@ -512,25 +398,22 @@
 	      </child>
 
 	      <child>
-		<widget class="GtkToolButton" id="button8">
+		<object class="GtkToolButton" id="button8">
 		  <property name="visible">True</property>
-		  <property name="tooltip" translatable="yes">Expand the whole tree in the right frame</property>
+		  <property name="tooltip-text" translatable="yes">Expand the whole tree in the right frame</property>
 		  <property name="label" translatable="yes">Expand</property>
 		  <property name="use_underline">True</property>
 		  <property name="stock_id">gtk-add</property>
 		  <property name="visible_horizontal">True</property>
 		  <property name="visible_vertical">True</property>
 		  <property name="is_important">False</property>
-		  <signal name="clicked" handler="on_expand_clicked"/>
-		</widget>
+		</object>
 		<packing>
 		  <property name="expand">False</property>
 		  <property name="homogeneous">True</property>
 		</packing>
 	      </child>
-	    </widget>
-	  </child>
-	</widget>
+	    </object>
 	<packing>
 	  <property name="padding">0</property>
 	  <property name="expand">False</property>
@@ -539,14 +422,13 @@
       </child>
 
       <child>
-	<widget class="GtkHPaned" id="hpaned1">
+	<object class="GtkPaned" id="hpaned1">
 	  <property name="width_request">1</property>
 	  <property name="visible">True</property>
 	  <property name="can_focus">True</property>
-	  <property name="position">0</property>
 
 	  <child>
-	    <widget class="GtkScrolledWindow" id="scrolledwindow1">
+	    <object class="GtkScrolledWindow" id="scrolledwindow1">
 	      <property name="visible">True</property>
 	      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
 	      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
@@ -554,19 +436,16 @@
 	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
 
 	      <child>
-		<widget class="GtkTreeView" id="treeview1">
+		<object class="GtkTreeView" id="treeview1">
 		  <property name="visible">True</property>
 		  <property name="can_focus">True</property>
 		  <property name="headers_visible">True</property>
 		  <property name="rules_hint">False</property>
 		  <property name="reorderable">False</property>
 		  <property name="enable_search">False</property>
-		  <signal name="cursor_changed" handler="on_treeview2_cursor_changed" last_modification_time="Sun, 12 Jan 2003 15:58:22 GMT"/>
-		  <signal name="button_press_event" handler="on_treeview1_button_press_event" last_modification_time="Sun, 12 Jan 2003 16:03:52 GMT"/>
-		  <signal name="key_press_event" handler="on_treeview2_key_press_event" last_modification_time="Sun, 12 Jan 2003 16:11:44 GMT"/>
-		</widget>
+		</object>
 	      </child>
-	    </widget>
+	    </object>
 	    <packing>
 	      <property name="shrink">True</property>
 	      <property name="resize">False</property>
@@ -574,13 +453,13 @@
 	  </child>
 
 	  <child>
-	    <widget class="GtkVPaned" id="vpaned1">
+	    <object class="GtkPaned" id="vpaned1">
+	      <property name="orientation">vertical</property>
 	      <property name="visible">True</property>
 	      <property name="can_focus">True</property>
-	      <property name="position">0</property>
 
 	      <child>
-		<widget class="GtkScrolledWindow" id="scrolledwindow2">
+		<object class="GtkScrolledWindow" id="scrolledwindow2">
 		  <property name="visible">True</property>
 		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
 		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
@@ -588,7 +467,7 @@
 		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
 
 		  <child>
-		    <widget class="GtkTreeView" id="treeview2">
+		    <object class="GtkTreeView" id="treeview2">
 		      <property name="visible">True</property>
 		      <property name="can_focus">True</property>
 		      <property name="has_focus">True</property>
@@ -596,12 +475,9 @@
 		      <property name="rules_hint">False</property>
 		      <property name="reorderable">False</property>
 		      <property name="enable_search">False</property>
-		      <signal name="cursor_changed" handler="on_treeview2_cursor_changed" last_modification_time="Sun, 12 Jan 2003 15:57:55 GMT"/>
-		      <signal name="button_press_event" handler="on_treeview2_button_press_event" last_modification_time="Sun, 12 Jan 2003 15:57:58 GMT"/>
-		      <signal name="key_press_event" handler="on_treeview2_key_press_event" last_modification_time="Sun, 12 Jan 2003 15:58:01 GMT"/>
-		    </widget>
+		    </object>
 		  </child>
-		</widget>
+		</object>
 		<packing>
 		  <property name="shrink">True</property>
 		  <property name="resize">False</property>
@@ -609,7 +485,7 @@
 	      </child>
 
 	      <child>
-		<widget class="GtkScrolledWindow" id="scrolledwindow3">
+		<object class="GtkScrolledWindow" id="scrolledwindow3">
 		  <property name="visible">True</property>
 		  <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
 		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
@@ -617,7 +493,7 @@
 		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
 
 		  <child>
-		    <widget class="GtkTextView" id="textview3">
+		    <object class="GtkTextView" id="textview3">
 		      <property name="visible">True</property>
 		      <property name="can_focus">True</property>
 		      <property name="editable">False</property>
@@ -632,30 +508,29 @@
 		      <property name="left_margin">0</property>
 		      <property name="right_margin">0</property>
 		      <property name="indent">0</property>
-		      <property name="text" translatable="yes">Sorry, no help available for this option yet.</property>
-		    </widget>
+		    </object>
 		  </child>
-		</widget>
+		</object>
 		<packing>
 		  <property name="shrink">True</property>
 		  <property name="resize">True</property>
 		</packing>
 	      </child>
-	    </widget>
+	    </object>
 	    <packing>
 	      <property name="shrink">True</property>
 	      <property name="resize">True</property>
 	    </packing>
 	  </child>
-	</widget>
+	</object>
 	<packing>
 	  <property name="padding">0</property>
 	  <property name="expand">True</property>
 	  <property name="fill">True</property>
 	</packing>
       </child>
-    </widget>
+    </object>
   </child>
-</widget>
+</object>
 
-</glade-interface>
+</interface>
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index fbc907f..56548ef 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -98,9 +98,11 @@ bool menu_is_visible(struct menu *menu);
 bool menu_has_prompt(const struct menu *menu);
 const char *menu_get_prompt(const struct menu *menu);
 struct menu *menu_get_parent_menu(struct menu *menu);
+struct menu *menu_get_menu_or_parent_menu(struct menu *menu);
 int get_jump_key_char(void);
 struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head);
 void menu_get_ext_help(struct menu *menu, struct gstr *help);
+void menu_dump(void);
 
 /* symbol.c */
 void sym_clear_all_valid(void);
diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c
index 3c6e24b..5e4a131 100644
--- a/scripts/kconfig/lxdialog/inputbox.c
+++ b/scripts/kconfig/lxdialog/inputbox.c
@@ -39,8 +39,10 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
 
 	if (!init)
 		instr[0] = '\0';
-	else
-		strcpy(instr, init);
+	else {
+		strncpy(instr, init, sizeof(dialog_input_result) - 1);
+		instr[sizeof(dialog_input_result) - 1] = '\0';
+	}
 
 do_resize:
 	if (getmaxy(stdscr) <= (height - INPUTBOX_HEIGHT_MIN))
diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c
index 6e6244d..d4c19b7 100644
--- a/scripts/kconfig/lxdialog/menubox.c
+++ b/scripts/kconfig/lxdialog/menubox.c
@@ -264,7 +264,7 @@ do_resize:
 		if (key < 256 && isalpha(key))
 			key = tolower(key);
 
-		if (strchr("ynmh", key))
+		if (strchr("ynmh ", key))
 			i = max_choice;
 		else {
 			for (i = choice + 1; i < max_choice; i++) {
diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c
index 964139c..b34000b 100644
--- a/scripts/kconfig/lxdialog/util.c
+++ b/scripts/kconfig/lxdialog/util.c
@@ -345,8 +345,7 @@ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
 	int prompt_len, room, wlen;
 	char tempstr[MAX_LEN + 1], *word, *sp, *sp2, *newline_separator = 0;
 
-	strcpy(tempstr, prompt);
-
+	snprintf(tempstr, sizeof(tempstr), "%s", prompt);
 	prompt_len = strlen(tempstr);
 
 	if (prompt_len <= width - x * 2) {	/* If prompt is short */
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 7d48a69..0f1a651 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -575,8 +575,28 @@ const char *menu_get_prompt(const struct menu *menu)
 	return NULL;
 }
 
+/**
+ * menu_get_parent_menu - return the parent menu or NULL
+ * @menu: pointer to the menu
+ * return: the parent menu, or NULL if there is no parent.
+ */
 struct menu *menu_get_parent_menu(struct menu *menu)
 {
+	for (menu = menu->parent; menu; menu = menu->parent)
+		if (menu->type == M_MENU)
+			return menu;
+
+	return NULL;
+}
+
+/**
+ * menu_get_menu_or_parent_menu - return the parent menu or the menu itself
+ * @menu: pointer to the menu
+ * return: the parent menu. If the given argument is already a menu, return
+ *         itself.
+ */
+struct menu *menu_get_menu_or_parent_menu(struct menu *menu)
+{
 	enum prop_type type;
 
 	for (; menu != &rootmenu; menu = menu->parent) {
@@ -768,3 +788,77 @@ void menu_get_ext_help(struct menu *menu, struct gstr *help)
 	if (sym)
 		get_symbol_str(help, sym, NULL);
 }
+
+/**
+ * menu_dump - dump all menu entries in a tree-like format
+ */
+void menu_dump(void)
+{
+	struct menu *menu = &rootmenu;
+	unsigned long long bits = 0;
+	int indent = 0;
+
+	while (menu) {
+
+		for (int i = indent - 1; i >= 0; i--) {
+			if (bits & (1ULL << i)) {
+				if (i > 0)
+					printf("|   ");
+				else
+					printf("|-- ");
+			} else {
+				if (i > 0)
+					printf("    ");
+				else
+					printf("`-- ");
+			}
+		}
+
+		switch (menu->type) {
+		case M_CHOICE:
+			printf("choice \"%s\"\n", menu->prompt->text);
+			break;
+		case M_COMMENT:
+			printf("comment \"%s\"\n", menu->prompt->text);
+			break;
+		case M_IF:
+			printf("if\n");
+			break;
+		case M_MENU:
+			printf("menu \"%s\"", menu->prompt->text);
+			if (!menu->sym) {
+				printf("\n");
+				break;
+			}
+			printf(" + ");
+			/* fallthrough */
+		case M_NORMAL:
+			printf("symbol %s\n", menu->sym->name);
+			break;
+		}
+		if (menu->list) {
+			bits <<= 1;
+			menu = menu->list;
+			if (menu->next)
+				bits |= 1;
+			else
+				bits &= ~1;
+			indent++;
+			continue;
+		}
+
+		while (menu && !menu->next) {
+			menu = menu->parent;
+			bits >>= 1;
+			indent--;
+		}
+
+		if (menu) {
+			menu = menu->next;
+			if (menu->next)
+				bits |= 1;
+			else
+				bits &= ~1;
+		}
+	}
+}
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c
index c0b2dab..ae1fe5f 100644
--- a/scripts/kconfig/nconf.c
+++ b/scripts/kconfig/nconf.c
@@ -593,6 +593,8 @@ static void item_add_str(const char *fmt, ...)
 		tmp_str,
 		sizeof(k_menu_items[index].str));
 
+	k_menu_items[index].str[sizeof(k_menu_items[index].str) - 1] = '\0';
+
 	free_item(curses_menu_items[index]);
 	curses_menu_items[index] = new_item(
 			k_menu_items[index].str,
diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c
index 4bfdf8a..7206437 100644
--- a/scripts/kconfig/nconf.gui.c
+++ b/scripts/kconfig/nconf.gui.c
@@ -359,6 +359,7 @@ int dialog_inputbox(WINDOW *main_window,
 	x = (columns-win_cols)/2;
 
 	strncpy(result, init, *result_len);
+	result[*result_len - 1] = '\0';
 
 	/* create the windows */
 	win = newwin(win_lines, win_cols, y, x);
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index eaa465b..f8992db 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -37,6 +37,12 @@ QAction *ConfigMainWindow::saveAction;
 ConfigSettings::ConfigSettings()
 	: QSettings("kernel.org", "qconf")
 {
+	beginGroup("/kconfig/qconf");
+}
+
+ConfigSettings::~ConfigSettings()
+{
+	endGroup();
 }
 
 /**
@@ -92,7 +98,6 @@ void ConfigItem::updateMenu(void)
 {
 	ConfigList* list;
 	struct symbol* sym;
-	struct property *prop;
 	QString prompt;
 	int type;
 	tristate expr;
@@ -105,11 +110,10 @@ void ConfigItem::updateMenu(void)
 	}
 
 	sym = menu->sym;
-	prop = menu->prompt;
 	prompt = menu_get_prompt(menu);
 
-	if (prop) switch (prop->type) {
-	case P_MENU:
+	switch (menu->type) {
+	case M_MENU:
 		if (list->mode == singleMode) {
 			/* a menuconfig entry is displayed differently
 			 * depending whether it's at the view root or a child.
@@ -123,10 +127,16 @@ void ConfigItem::updateMenu(void)
 			setIcon(promptColIdx, QIcon());
 		}
 		goto set_prompt;
-	case P_COMMENT:
+	case M_COMMENT:
 		setIcon(promptColIdx, QIcon());
 		prompt = "*** " + prompt + " ***";
 		goto set_prompt;
+	case M_CHOICE:
+		setIcon(promptColIdx, QIcon());
+		sym = sym_calc_choice(menu);
+		if (sym)
+			setText(dataColIdx, sym->name);
+		goto set_prompt;
 	default:
 		;
 	}
@@ -188,7 +198,11 @@ void ConfigItem::testUpdateMenu(void)
 	if (!menu)
 		return;
 
-	sym_calc_value(menu->sym);
+	if (menu->type == M_CHOICE)
+		sym_calc_choice(menu);
+	else
+		sym_calc_value(menu->sym);
+
 	if (menu->flags & MENU_CHANGED) {
 		/* the menu entry changed, so update all list items */
 		menu->flags &= ~MENU_CHANGED;
@@ -478,7 +492,7 @@ void ConfigList::updateListAllForAll()
 	while (it.hasNext()) {
 		ConfigList *list = it.next();
 
-		list->updateList();
+		list->updateListAll();
 	}
 }
 
@@ -569,7 +583,7 @@ void ConfigList::setParentMenu(void)
 	oldroot = rootEntry;
 	if (rootEntry == &rootmenu)
 		return;
-	setRootMenu(menu_get_parent_menu(rootEntry->parent));
+	setRootMenu(menu_get_menu_or_parent_menu(rootEntry->parent));
 
 	QTreeWidgetItemIterator it(this);
 	while (*it) {
@@ -1532,7 +1546,7 @@ void ConfigMainWindow::setMenuLink(struct menu *menu)
 	switch (configList->mode) {
 	case singleMode:
 		list = configList;
-		parent = menu_get_parent_menu(menu);
+		parent = menu_get_menu_or_parent_menu(menu);
 		if (!parent)
 			return;
 		list->setRootMenu(parent);
@@ -1543,7 +1557,7 @@ void ConfigMainWindow::setMenuLink(struct menu *menu)
 			configList->clearSelection();
 			list = configList;
 		} else {
-			parent = menu_get_parent_menu(menu->parent);
+			parent = menu_get_menu_or_parent_menu(menu->parent);
 			if (!parent)
 				return;
 
@@ -1821,7 +1835,6 @@ int main(int ac, char** av)
 	configApp = new QApplication(ac, av);
 
 	configSettings = new ConfigSettings();
-	configSettings->beginGroup("/kconfig/qconf");
 	v = new ConfigMainWindow();
 
 	//zconfdump(stdout);
@@ -1829,7 +1842,6 @@ int main(int ac, char** av)
 	v->show();
 	configApp->exec();
 
-	configSettings->endGroup();
 	delete configSettings;
 	delete v;
 	delete configApp;
diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h
index 62ab328..ab4e51f 100644
--- a/scripts/kconfig/qconf.h
+++ b/scripts/kconfig/qconf.h
@@ -24,6 +24,7 @@ class ConfigMainWindow;
 class ConfigSettings : public QSettings {
 public:
 	ConfigSettings();
+	~ConfigSettings(void);
 	QList<int> readSizes(const QString& key, bool *ok);
 	bool writeSizes(const QString& key, const QList<int>& value);
 };
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index d57f8cb..26ab10c 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -195,6 +195,10 @@ static void sym_set_changed(struct symbol *sym)
 
 	list_for_each_entry(menu, &sym->menus, link)
 		menu->flags |= MENU_CHANGED;
+
+	menu = sym_get_choice_menu(sym);
+	if (menu)
+		menu->flags |= MENU_CHANGED;
 }
 
 static void sym_set_all_changed(void)
