Index: dialog/1.3-20210621/PATCHES
===================================================================
--- dialog/1.3-20210621/PATCHES (revision 33)
+++ dialog/1.3-20210621/PATCHES (nonexistent)
@@ -1,2 +0,0 @@
-
-../../sources/packages/dialog/patches/dialog-1.3-20210621.patch -p0
Index: dialog/1.3-20210621/Makefile
===================================================================
--- dialog/1.3-20210621/Makefile (revision 33)
+++ dialog/1.3-20210621/Makefile (nonexistent)
@@ -1,56 +0,0 @@
-
-COMPONENT_TARGETS = $(TOOLCHAIN_HOST)
-
-include ../../../../build-system/config.mk
-
-SOURCE_REQUIRES = build-system/3pp/sources/packages/dialog
-
-
-# ======= __END_OF_REQUIRES__ =======
-
-
-tar_gz_archive = $(BUILDSYSTEM)/3pp/sources/packages/dialog/dialog-1.3-20210621.tgz
-src_dir = dialog-1.3-20210621
-build_dir = $(TARGET_BUILD_DIR)/built
-
-src_done = $(TARGET_BUILD_DIR)/.source-done
-SRC_DIR = $(TARGET_BUILD_DIR)/dialog-1.3-20210621
-SRC_ARCHIVE = $(tar_gz_archive)
-
-DIALOGRC = $(BUILDSYSTEM)/3pp/sources/packages/dialog/dialogrc
-
-PATCHES = PATCHES
-
-build_target = $(TARGET_BUILD_DIR)/.built
-install_target = $(TARGET_BUILD_DIR)/.installed
-
-environment =
-extra_configure_switches = --libdir=/usr/lib
-extra_configure_switches += --mandir=/usr/share/man
-extra_configure_switches += --without-shared
-extra_configure_switches += --with-ncursesw
-
-BUILD_TARGETS = $(install_target)
-
-include ../../../../build-system/core.mk
-
-$(src_done): $(SRC_ARCHIVE) $(PATCHES_DEP)
- $(UNPACK_SRC_ARCHIVE)
- $(APPLY_PATCHES)
- @touch $@
-
-$(build_target): $(src_done)
- @mkdir -p $(build_dir)
- @cd $(build_dir) && $(environment) ../$(src_dir)/configure \
- --prefix=/ \
- $(extra_configure_switches)
- @$(environment) $(MAKE) -C $(build_dir) all
- @touch $@
-
-$(install_target): $(build_target)
- @echo -e "\n======= Installing DIALOG binary =======\n"
- @mkdir -p $(BUILDSYSTEM)/{etc,sbin} && \
- cp -a $(DIALOGRC) $(BUILDSYSTEM)/etc && \
- cp -a $(build_dir)/dialog $(BUILDSYSTEM)/sbin && \
- echo "DIALOG := $(BUILDSYSTEM)/sbin/dialog" >> $(BUILDSYSTEM)/sbin/.config
- @touch $@
Index: dialog/1.3-20210621
===================================================================
--- dialog/1.3-20210621 (revision 33)
+++ dialog/1.3-20210621 (nonexistent)
Property changes on: dialog/1.3-20210621
___________________________________________________________________
Deleted: svn:ignore
## -1,16 +0,0 ##
-
-# Target bin dirs
-etc
-gnattools
-sbin
-
-# Build system config files
-targets-config.mk
-
-# Target build dirs
-.host
-
-# Hidden files (each file)
-.makefile
-.src_requires
-.src_requires_depend
Index: dialog/1.3-20240101/Makefile
===================================================================
--- dialog/1.3-20240101/Makefile (nonexistent)
+++ dialog/1.3-20240101/Makefile (revision 34)
@@ -0,0 +1,56 @@
+
+COMPONENT_TARGETS = $(TOOLCHAIN_HOST)
+
+include ../../../../build-system/config.mk
+
+SOURCE_REQUIRES = build-system/3pp/sources/packages/dialog
+
+
+# ======= __END_OF_REQUIRES__ =======
+
+
+tar_gz_archive = $(BUILDSYSTEM)/3pp/sources/packages/dialog/dialog-1.3-20240101.tgz
+src_dir = dialog-1.3-20240101
+build_dir = $(TARGET_BUILD_DIR)/built
+
+src_done = $(TARGET_BUILD_DIR)/.source-done
+SRC_DIR = $(TARGET_BUILD_DIR)/dialog-1.3-20240101
+SRC_ARCHIVE = $(tar_gz_archive)
+
+DIALOGRC = $(BUILDSYSTEM)/3pp/sources/packages/dialog/dialogrc
+
+PATCHES = PATCHES
+
+build_target = $(TARGET_BUILD_DIR)/.built
+install_target = $(TARGET_BUILD_DIR)/.installed
+
+environment =
+extra_configure_switches = --libdir=/usr/lib
+extra_configure_switches += --mandir=/usr/share/man
+extra_configure_switches += --without-shared
+extra_configure_switches += --with-ncursesw
+
+BUILD_TARGETS = $(install_target)
+
+include ../../../../build-system/core.mk
+
+$(src_done): $(SRC_ARCHIVE) $(PATCHES_DEP)
+ $(UNPACK_SRC_ARCHIVE)
+ $(APPLY_PATCHES)
+ @touch $@
+
+$(build_target): $(src_done)
+ @mkdir -p $(build_dir)
+ @cd $(build_dir) && $(environment) ../$(src_dir)/configure \
+ --prefix=/ \
+ $(extra_configure_switches)
+ @$(environment) $(MAKE) -C $(build_dir) all
+ @touch $@
+
+$(install_target): $(build_target)
+ @echo -e "\n======= Installing DIALOG binary =======\n"
+ @mkdir -p $(BUILDSYSTEM)/{etc,sbin} && \
+ cp -a $(DIALOGRC) $(BUILDSYSTEM)/etc && \
+ cp -a $(build_dir)/dialog $(BUILDSYSTEM)/sbin && \
+ echo "DIALOG := $(BUILDSYSTEM)/sbin/dialog" >> $(BUILDSYSTEM)/sbin/.config
+ @touch $@
Index: dialog/1.3-20240101/PATCHES
===================================================================
--- dialog/1.3-20240101/PATCHES (nonexistent)
+++ dialog/1.3-20240101/PATCHES (revision 34)
@@ -0,0 +1,2 @@
+
+../../sources/packages/dialog/patches/dialog-1.3-20240101.patch -p0
Index: dialog/1.3-20240101
===================================================================
--- dialog/1.3-20240101 (nonexistent)
+++ dialog/1.3-20240101 (revision 34)
Property changes on: dialog/1.3-20240101
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,16 ##
+
+# Target bin dirs
+etc
+gnattools
+sbin
+
+# Build system config files
+targets-config.mk
+
+# Target build dirs
+.host
+
+# Hidden files (each file)
+.makefile
+.src_requires
+.src_requires_depend
Index: gnattools/12.2.0/Makefile
===================================================================
--- gnattools/12.2.0/Makefile (revision 33)
+++ gnattools/12.2.0/Makefile (nonexistent)
@@ -1,99 +0,0 @@
-
-COMPONENT_TARGETS = $(TOOLCHAIN_HOST)
-
-include ../../../../build-system/config.mk
-
-
-SOURCE_REQUIRES = build-system/3pp/sources/GNU
-SOURCE_REQUIRES += build-system/3pp/sources/inria
-
-# ======= __END_OF_REQUIRES__ =======
-
-tar_xz_archive = $(BUILDSYSTEM)/3pp/sources/GNU/gcc/gcc-12.2.0/gcc-12.2.0.tar.xz
-tar_xz_archive_gmp = $(BUILDSYSTEM)/3pp/sources/GNU/gmp/gmp-6.2.1.tar.xz
-tar_xz_archive_mpfr = $(BUILDSYSTEM)/3pp/sources/GNU/mpfr/mpfr-4.1.0.tar.xz
-tar_gz_archive_mpc = $(BUILDSYSTEM)/3pp/sources/GNU/mpc/mpc-1.2.1.tar.gz
-tar_xz_archive_isl = $(BUILDSYSTEM)/3pp/sources/inria/isl/isl-0.25.tar.xz
-SRC_ARCHIVE = $(tar_xz_archive)
-SRC_DIR = $(TARGET_BUILD_DIR)/gcc-12.2.0
-src_dir_name = gcc-12.2.0
-src_done = $(TARGET_BUILD_DIR)/.source-done
-gmp_src_done = $(TARGET_BUILD_DIR)/.gmp-source-done
-mpfr_src_done = $(TARGET_BUILD_DIR)/.mpfr-source-done
-mpc_src_done = $(TARGET_BUILD_DIR)/.mpc-source-done
-isl_src_done = $(TARGET_BUILD_DIR)/.isl-source-done
-
-PATCHES = PATCHES
-
-build_dir = $(TARGET_BUILD_DIR)/build
-
-
-build_target = $(TARGET_BUILD_DIR)/.built
-install_target = $(TARGET_BUILD_DIR)/.installed
-
-
-BUILD_TARGETS = $(build_target)
-BUILD_TARGETS += $(install_target)
-
-
-include ../../../../build-system/core.mk
-
-
-JOBS = -j$(NUMPROCS)
-
-environment = CC="$(CCACHE)/usr/bin/gcc"
-environment += CC_FOR_BUILD="$(CCACHE)/usr/bin/gcc"
-environment += CXX_FOR_BUILD="$(CCACHE)/usr/bin/g++"
-
-
-GNATTOOLS_DEST_DIR = $(BUILDSYSTEM)/gnattools/12.2.0/usr
-
-extra_configure_switches = --disable-bootstrap
-extra_configure_switches += --enable-languages=c,c++,ada
-
-
-$(src_done): $(SRC_ARCHIVE) $(PATCHES_DEP)
- $(UNPACK_SRC_ARCHIVE)
- $(APPLY_PATCHES)
- @touch $@
-
-$(gmp_src_done): $(src_done)
- @echo "Expanding $(tar_xz_archive_gmp)"
- @tar xJf $(tar_xz_archive_gmp) -C $(TARGET_BUILD_DIR)
- @cd $(SRC_DIR); ln -sf ../gmp-6.2.1 gmp
- @touch $@
-
-$(mpfr_src_done): $(src_done)
- @echo "Expanding $(tar_xz_archive_mpfr)"
- @tar xJf $(tar_xz_archive_mpfr) -C $(TARGET_BUILD_DIR)
- @cd $(SRC_DIR); ln -sf ../mpfr-4.1.0 mpfr
- @touch $@
-
-$(mpc_src_done): $(src_done)
- @echo "Expanding $(tar_gz_archive_mpc)"
- @tar xzf $(tar_gz_archive_mpc) -C $(TARGET_BUILD_DIR)
- @cd $(SRC_DIR); ln -sf ../mpc-1.2.1 mpc
- @touch $@
-
-$(isl_src_done): $(src_done)
- @echo "Expanding $(tar_xz_archive_isl)"
- @tar xJf $(tar_xz_archive_isl) -C $(TARGET_BUILD_DIR)
- @cd $(SRC_DIR); ln -sf ../isl-0.25 isl
- @touch $@
-
-$(build_target): $(src_done) $(gmp_src_done) $(mpfr_src_done) $(mpc_src_done) $(isl_src_done)
- @mkdir -p $(build_dir)
- @cd $(build_dir) && $(environment) ../$(src_dir_name)/configure \
- --prefix=$(GNATTOOLS_DEST_DIR) \
- --build=$(shell $(BUILDSYSTEM)/canonical-build) \
- --datadir=$(GNATTOOLS_DEST_DIR)/share \
- --infodir=$(GNATTOOLS_DEST_DIR)/share/info \
- --mandir=$(GNATTOOLS_DEST_DIR)/share/man \
- $(extra_configure_switches)
- @cd $(build_dir) && make $(JOBS)
- @touch $@
-
-$(install_target): $(build_target)
- @cd $(build_dir) && make install
- @rm -f $(GNATTOOLS_DEST_DIR)/share/info/dir
- @touch $@
Index: gnattools/12.2.0
===================================================================
--- gnattools/12.2.0 (revision 33)
+++ gnattools/12.2.0 (nonexistent)
Property changes on: gnattools/12.2.0
___________________________________________________________________
Deleted: svn:ignore
## -1,16 +0,0 ##
-
-# Target bin dirs
-etc
-gnattools
-sbin
-
-# Build system config files
-targets-config.mk
-
-# Target build dirs
-.host
-
-# Hidden files (each file)
-.makefile
-.src_requires
-.src_requires_depend
Index: gnattools/13.2.0/Makefile
===================================================================
--- gnattools/13.2.0/Makefile (nonexistent)
+++ gnattools/13.2.0/Makefile (revision 34)
@@ -0,0 +1,99 @@
+
+COMPONENT_TARGETS = $(TOOLCHAIN_HOST)
+
+include ../../../../build-system/config.mk
+
+
+SOURCE_REQUIRES = build-system/3pp/sources/GNU
+SOURCE_REQUIRES += build-system/3pp/sources/inria
+
+# ======= __END_OF_REQUIRES__ =======
+
+tar_xz_archive = $(BUILDSYSTEM)/3pp/sources/GNU/gcc/gcc-13.2.0/gcc-13.2.0.tar.xz
+tar_xz_archive_gmp = $(BUILDSYSTEM)/3pp/sources/GNU/gmp/gmp-6.3.0.tar.xz
+tar_xz_archive_mpfr = $(BUILDSYSTEM)/3pp/sources/GNU/mpfr/mpfr-4.2.1.tar.xz
+tar_gz_archive_mpc = $(BUILDSYSTEM)/3pp/sources/GNU/mpc/mpc-1.3.1.tar.gz
+tar_xz_archive_isl = $(BUILDSYSTEM)/3pp/sources/inria/isl/isl-0.26.tar.xz
+SRC_ARCHIVE = $(tar_xz_archive)
+SRC_DIR = $(TARGET_BUILD_DIR)/gcc-13.2.0
+src_dir_name = gcc-13.2.0
+src_done = $(TARGET_BUILD_DIR)/.source-done
+gmp_src_done = $(TARGET_BUILD_DIR)/.gmp-source-done
+mpfr_src_done = $(TARGET_BUILD_DIR)/.mpfr-source-done
+mpc_src_done = $(TARGET_BUILD_DIR)/.mpc-source-done
+isl_src_done = $(TARGET_BUILD_DIR)/.isl-source-done
+
+PATCHES = PATCHES
+
+build_dir = $(TARGET_BUILD_DIR)/build
+
+
+build_target = $(TARGET_BUILD_DIR)/.built
+install_target = $(TARGET_BUILD_DIR)/.installed
+
+
+BUILD_TARGETS = $(build_target)
+BUILD_TARGETS += $(install_target)
+
+
+include ../../../../build-system/core.mk
+
+
+JOBS = -j$(NUMPROCS)
+
+environment = CC="$(CCACHE)/usr/bin/gcc"
+environment += CC_FOR_BUILD="$(CCACHE)/usr/bin/gcc"
+environment += CXX_FOR_BUILD="$(CCACHE)/usr/bin/g++"
+
+
+GNATTOOLS_DEST_DIR = $(BUILDSYSTEM)/gnattools/13.2.0/usr
+
+extra_configure_switches = --disable-bootstrap
+extra_configure_switches += --enable-languages=c,c++,ada
+
+
+$(src_done): $(SRC_ARCHIVE) $(PATCHES_DEP)
+ $(UNPACK_SRC_ARCHIVE)
+ $(APPLY_PATCHES)
+ @touch $@
+
+$(gmp_src_done): $(src_done)
+ @echo "Expanding $(tar_xz_archive_gmp)"
+ @tar xJf $(tar_xz_archive_gmp) -C $(TARGET_BUILD_DIR)
+ @cd $(SRC_DIR); ln -sf ../gmp-6.3.0 gmp
+ @touch $@
+
+$(mpfr_src_done): $(src_done)
+ @echo "Expanding $(tar_xz_archive_mpfr)"
+ @tar xJf $(tar_xz_archive_mpfr) -C $(TARGET_BUILD_DIR)
+ @cd $(SRC_DIR); ln -sf ../mpfr-4.2.1 mpfr
+ @touch $@
+
+$(mpc_src_done): $(src_done)
+ @echo "Expanding $(tar_gz_archive_mpc)"
+ @tar xzf $(tar_gz_archive_mpc) -C $(TARGET_BUILD_DIR)
+ @cd $(SRC_DIR); ln -sf ../mpc-1.3.1 mpc
+ @touch $@
+
+$(isl_src_done): $(src_done)
+ @echo "Expanding $(tar_xz_archive_isl)"
+ @tar xJf $(tar_xz_archive_isl) -C $(TARGET_BUILD_DIR)
+ @cd $(SRC_DIR); ln -sf ../isl-0.26 isl
+ @touch $@
+
+$(build_target): $(src_done) $(gmp_src_done) $(mpfr_src_done) $(mpc_src_done) $(isl_src_done)
+ @mkdir -p $(build_dir)
+ @cd $(build_dir) && $(environment) ../$(src_dir_name)/configure \
+ --prefix=$(GNATTOOLS_DEST_DIR) \
+ --build=$(shell $(BUILDSYSTEM)/canonical-build) \
+ --datadir=$(GNATTOOLS_DEST_DIR)/share \
+ --infodir=$(GNATTOOLS_DEST_DIR)/share/info \
+ --mandir=$(GNATTOOLS_DEST_DIR)/share/man \
+ $(extra_configure_switches)
+ @cd $(build_dir) && make $(JOBS)
+ @touch $@
+
+$(install_target): $(build_target)
+ @cd $(build_dir) && make install
+ @rm -f $(GNATTOOLS_DEST_DIR)/share/info/dir
+ @touch $@
Index: gnattools/13.2.0/PATCHES
===================================================================
Index: gnattools/13.2.0
===================================================================
--- gnattools/13.2.0 (nonexistent)
+++ gnattools/13.2.0 (revision 34)
Property changes on: gnattools/13.2.0
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,16 ##
+
+# Target bin dirs
+etc
+gnattools
+sbin
+
+# Build system config files
+targets-config.mk
+
+# Target build dirs
+.host
+
+# Hidden files (each file)
+.makefile
+.src_requires
+.src_requires_depend
Index: sources/GNU/gcc/gcc-12.2.0/Makefile
===================================================================
--- sources/GNU/gcc/gcc-12.2.0/Makefile (revision 33)
+++ sources/GNU/gcc/gcc-12.2.0/Makefile (nonexistent)
@@ -1,39 +0,0 @@
-
-COMPONENT_TARGETS = $(TOOLCHAIN_NOARCH)
-
-include ../../../../../../build-system/config.mk
-
-url = $(DOWNLOAD_SERVER)/sources/GNU/gcc/gcc-$(version)
-
-version = 12.2.0
-
-tarballs = $(addsuffix .tar.xz, $(addprefix gcc-, $(version)))
-sha1s = $(addsuffix .sha1sum, $(tarballs))
-
-BUILD_TARGETS = $(tarballs) $(sha1s)
-
-include ../../../../../../build-system/core.mk
-
-.PHONY: download_clean
-
-$(tarballs):
- @echo -e "\n======= Downloading source tarballs =======" ; \
- for tarball in $(tarballs) ; do \
- echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & \
- done ; wait
-
-$(sha1s): $(tarballs)
- @for sha in $@ ; do \
- echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
- echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & wait %1 ; \
- touch $$sha ; \
- echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
- sha1sum --check $$sha ; ret="$$?" ; \
- if [ "$$ret" == "1" ]; then \
- echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
- exit 1 ; \
- fi ; \
- done
-
-download_clean:
- @rm -f $(tarballs) $(sha1s)
Index: sources/GNU/gcc/gcc-12.2.0
===================================================================
--- sources/GNU/gcc/gcc-12.2.0 (revision 33)
+++ sources/GNU/gcc/gcc-12.2.0 (nonexistent)
Property changes on: sources/GNU/gcc/gcc-12.2.0
___________________________________________________________________
Deleted: svn:ignore
## -1,32 +0,0 ##
-
-# Target bin dirs
-etc
-gnattools
-sbin
-
-# Build system config files
-targets-config.mk
-
-# Target build dirs
-.host
-
-# Hidden files (each file)
-.makefile
-.src_requires
-.src_requires_depend
-
-# Tarballs
-*.gz
-*.bz2
-*.xz
-*.tgz
-*.txz
-
-# Signatures
-*.asc
-*.sig
-*.sign
-*.sha1sum
-
-# Patches
-*.patch
Index: sources/GNU/gcc/gcc-13.2.0/Makefile
===================================================================
--- sources/GNU/gcc/gcc-13.2.0/Makefile (nonexistent)
+++ sources/GNU/gcc/gcc-13.2.0/Makefile (revision 34)
@@ -0,0 +1,39 @@
+
+COMPONENT_TARGETS = $(TOOLCHAIN_NOARCH)
+
+include ../../../../../../build-system/config.mk
+
+url = $(DOWNLOAD_SERVER)/sources/GNU/gcc/gcc-$(version)
+
+version = 13.2.0
+
+tarballs = $(addsuffix .tar.xz, $(addprefix gcc-, $(version)))
+sha1s = $(addsuffix .sha1sum, $(tarballs))
+
+BUILD_TARGETS = $(tarballs) $(sha1s)
+
+include ../../../../../../build-system/core.mk
+
+.PHONY: download_clean
+
+$(tarballs):
+ @echo -e "\n======= Downloading source tarballs =======" ; \
+ for tarball in $(tarballs) ; do \
+ echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & \
+ done ; wait
+
+$(sha1s): $(tarballs)
+ @for sha in $@ ; do \
+ echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
+ echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & wait %1 ; \
+ touch $$sha ; \
+ echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
+ sha1sum --check $$sha ; ret="$$?" ; \
+ if [ "$$ret" == "1" ]; then \
+ echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
+ exit 1 ; \
+ fi ; \
+ done
+
+download_clean:
+ @rm -f $(tarballs) $(sha1s)
Index: sources/GNU/gcc/gcc-13.2.0
===================================================================
--- sources/GNU/gcc/gcc-13.2.0 (nonexistent)
+++ sources/GNU/gcc/gcc-13.2.0 (revision 34)
Property changes on: sources/GNU/gcc/gcc-13.2.0
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,32 ##
+
+# Target bin dirs
+etc
+gnattools
+sbin
+
+# Build system config files
+targets-config.mk
+
+# Target build dirs
+.host
+
+# Hidden files (each file)
+.makefile
+.src_requires
+.src_requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
Index: sources/GNU/gmp/Makefile
===================================================================
--- sources/GNU/gmp/Makefile (revision 33)
+++ sources/GNU/gmp/Makefile (revision 34)
@@ -5,7 +5,7 @@
url = $(DOWNLOAD_SERVER)/sources/GNU/gmp
-versions = 6.2.1
+versions = 6.3.0
tarballs = $(addsuffix .tar.xz, $(addprefix gmp-, $(versions)))
sha1s = $(addsuffix .sha1sum, $(tarballs))
Index: sources/GNU/mpc/Makefile
===================================================================
--- sources/GNU/mpc/Makefile (revision 33)
+++ sources/GNU/mpc/Makefile (revision 34)
@@ -5,7 +5,7 @@
url = $(DOWNLOAD_SERVER)/sources/GNU/mpc
-versions = 1.2.1
+versions = 1.3.1
tarballs = $(addsuffix .tar.gz, $(addprefix mpc-, $(versions)))
sha1s = $(addsuffix .sha1sum, $(tarballs))
Index: sources/GNU/mpfr/Makefile
===================================================================
--- sources/GNU/mpfr/Makefile (revision 33)
+++ sources/GNU/mpfr/Makefile (revision 34)
@@ -5,7 +5,7 @@
url = $(DOWNLOAD_SERVER)/sources/GNU/mpfr
-versions = 4.1.0
+versions = 4.2.1
tarballs = $(addsuffix .tar.xz, $(addprefix mpfr-, $(versions)))
sha1s = $(addsuffix .sha1sum, $(tarballs))
Index: sources/inria/isl/Makefile
===================================================================
--- sources/inria/isl/Makefile (revision 33)
+++ sources/inria/isl/Makefile (revision 34)
@@ -7,7 +7,7 @@
url = $(DOWNLOAD_SERVER)/sources/packages/l/isl
-versions = 0.25
+versions = 0.26
pkg_name = isl
suffix = tar.xz
Index: sources/packages/dialog/create-1.3-20210621-patch/file.list
===================================================================
--- sources/packages/dialog/create-1.3-20210621-patch/file.list (revision 33)
+++ sources/packages/dialog/create-1.3-20210621-patch/file.list (nonexistent)
@@ -1,7 +0,0 @@
-dialog-1.3-20210621/buildlist.c
-dialog-1.3-20210621/checklist.c
-dialog-1.3-20210621/dialog-config.in
-dialog-1.3-20210621/fselect.c
-dialog-1.3-20210621/menubox.c
-dialog-1.3-20210621/treeview.c
-dialog-1.3-20210621/util.c
Index: sources/packages/dialog/create-1.3-20210621-patch/create.patch.sh
===================================================================
--- sources/packages/dialog/create-1.3-20210621-patch/create.patch.sh (revision 33)
+++ sources/packages/dialog/create-1.3-20210621-patch/create.patch.sh (nonexistent)
@@ -1,15 +0,0 @@
-#!/bin/bash
-
-VERSION=1.3-20210621
-
-tar --files-from=file.list -xzvf ../dialog-$VERSION.tgz
-mv dialog-$VERSION dialog-$VERSION-orig
-
-cp -rf ./dialog-$VERSION-new ./dialog-$VERSION
-
-diff --unified -Nr dialog-$VERSION-orig dialog-$VERSION > dialog-$VERSION.patch
-
-mv dialog-$VERSION.patch ../patches
-
-rm -rf ./dialog-$VERSION
-rm -rf ./dialog-$VERSION-orig
Property changes on: sources/packages/dialog/create-1.3-20210621-patch/create.patch.sh
___________________________________________________________________
Deleted: svn:executable
## -1 +0,0 ##
-*
\ No newline at end of property
Index: sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/buildlist.c
===================================================================
--- sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/buildlist.c (revision 33)
+++ sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/buildlist.c (nonexistent)
@@ -1,1267 +0,0 @@
-/*
- * $Id: buildlist.c,v 1.95 2021/03/05 00:51:16 tom Exp $
- *
- * buildlist.c -- implements the buildlist dialog
- *
- * Copyright 2012-2020,2021 Thomas E. Dickey
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License, version 2.1
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to
- * Free Software Foundation, Inc.
- * 51 Franklin St., Fifth Floor
- * Boston, MA 02110, USA.
- */
-
-#include <dlg_internals.h>
-#include <dlg_keys.h>
-
-/*
- * Visually like menubox, but two columns.
- */
-
-#define sLEFT (-2)
-#define sRIGHT (-1)
-
-#define KEY_LEFTCOL '^'
-#define KEY_RIGHTCOL '$'
-
-#define MIN_HIGH (1 + (5 * MARGIN))
-
-typedef struct {
- WINDOW *win;
- int box_y;
- int box_x;
- int top_index;
- int cur_index;
- DIALOG_LISTITEM **ip; /* pointers to items in this list */
-} MY_DATA;
-
-#if 0
-#define TRACE(p) dlg_trace_msg p
-#else
-#define TRACE(p) /* nothing */
-#endif
-
-#define okIndex(all,index) ((index) >= 0 && (index) < (all)->item_no)
-
-#define myItem(p,n) ((p)->ip)[n]
-#define mySide(n) ((n)?"right":"left")
-
-typedef struct {
- DIALOG_LISTITEM *items; /* all items in the widget */
- int base_y; /* base for mouse coordinates */
- int base_x;
- int use_height; /* actual size of column box */
- int use_width;
- int item_no;
- int check_x;
- int item_x;
- MY_DATA list[2];
-} ALL_DATA;
-
-/*
- * Translate a choice from items[] to a row-number in an unbounded column,
- * starting at zero.
- */
-static int
-index2row(ALL_DATA * all, int choice, int selected)
-{
- MY_DATA *data = all->list + selected;
- int result = -1;
-
- if (okIndex(all, choice)) {
- int row;
-
- for (row = 0; row < all->item_no; ++row) {
- TRACE(("!... choice %d: %p vs row %d: %p\n",
- choice, all->items + choice,
- row, myItem(data, row)));
- if (myItem(data, row) == all->items + choice) {
- result = row;
- break;
- }
- }
- }
- TRACE(("! index2row(choice %d, %s) = %d\n", choice, mySide(selected), result));
- return result;
-}
-
-/*
- * Convert a row-number back to an item number, i.e., index into items[].
- */
-static int
-row2index(ALL_DATA * all, int row, int selected)
-{
- MY_DATA *data = all->list + selected;
- int result = -1;
- int n;
- for (n = 0; n < all->item_no; ++n) {
- TRACE(("!... row %d: %p vs choice %d: %p\n",
- row, myItem(data, row),
- n, all->items + n));
- if (myItem(data, row) == all->items + n) {
- result = n;
- break;
- }
- }
- TRACE(("! row2index(row %d, %s) = %d\n", row, mySide(selected), result));
- return result;
-}
-
-/*
- * Print list item. The 'selected' parameter is true if 'choice' is the
- * current item. That one is colored differently from the other items.
- */
-static void
-print_item(ALL_DATA * all,
- WINDOW *win,
- DIALOG_LISTITEM * item,
- int row,
- int selected)
-{
- chtype save = dlg_get_attrs(win);
- int i;
- bool both = (!dialog_vars.no_tags && !dialog_vars.no_items);
- bool first = TRUE;
- int climit = (all->item_x - all->check_x - 1);
- const char *show = (dialog_vars.no_items
- ? item->name
- : item->text);
-
- /* Clear 'residue' of last item */
- dlg_attrset(win, menubox_attr);
- (void) wmove(win, row, 0);
- for (i = 0; i < getmaxx(win); i++)
- (void) waddch(win, ' ');
-
- (void) wmove(win, row, all->check_x);
- dlg_attrset(win, menubox_attr);
-
- if (both) {
- dlg_print_listitem(win, item->name, climit, first, selected);
- (void) waddch(win, ' ');
- first = FALSE;
- }
-
- (void) wmove(win, row, all->item_x);
- climit = (getmaxx(win) - all->item_x + 1);
- dlg_print_listitem(win, show, climit, first, selected);
-
- if (selected) {
- dlg_item_help(item->help);
- }
- dlg_attrset(win, save);
-}
-
-/*
- * Prints either the left (unselected) or right (selected) list.
- */
-static void
-print_1_list(ALL_DATA * all,
- int choice,
- int selected)
-{
- MY_DATA *data = all->list + selected;
- DIALOG_LISTITEM *target = (okIndex(all, choice)
- ? all->items + choice
- : 0);
- WINDOW *win = data->win;
- int i, j;
- int last = 0;
- int top_row = index2row(all, data->top_index, selected);
- int max_rows = getmaxy(win);
-
- TRACE(("! print_1_list %d %s, top %d\n", choice, mySide(selected), top_row));
- for (i = j = 0; j < max_rows; i++) {
- int ii = i + top_row;
- if (ii < 0) {
- continue;
- } else if (myItem(data, ii)) {
- print_item(all,
- win,
- myItem(data, ii),
- j, myItem(data, ii) == target);
- last = ++j;
- } else {
- break;
- }
- }
- if (wmove(win, last, 0) != ERR) {
- while (waddch(win, ' ') != ERR) {
- ;
- }
- }
- (void) wnoutrefresh(win);
-}
-
-/*
- * Return the previous item from the list, staying in the same column. If no
- * further movement is possible, return the same choice as given.
- */
-static int
-prev_item(ALL_DATA * all, int choice, int selected)
-{
- int result = choice;
- int row = index2row(all, choice, selected);
- if (row > 0) {
- row--;
- result = row2index(all, row, selected);
- }
- TRACE(("! prev_item choice %d, %s = %d\n", choice, mySide(selected), result));
- return result;
-}
-
-/*
- * Return true if the given choice is on the first page in the current column.
- */
-static bool
-stop_prev(ALL_DATA * all, int choice, int selected)
-{
- return (prev_item(all, choice, selected) == choice);
-}
-
-static bool
-check_hotkey(DIALOG_LISTITEM * items, int choice, int selected)
-{
- bool result = FALSE;
-
- if ((items[choice].state != 0) == selected) {
- if (dlg_match_char(dlg_last_getc(),
- (dialog_vars.no_tags
- ? items[choice].text
- : items[choice].name))) {
- result = TRUE;
- }
- }
- return result;
-}
-
-/*
- * Return the next item from the list, staying in the same column. If no
- * further movement is possible, return the same choice as given.
- */
-static int
-next_item(ALL_DATA * all, int choice, int selected)
-{
- MY_DATA *data = all->list + selected;
- int result = choice;
- int row = index2row(all, choice, selected);
- TRACE(("! given item %d, testing next-item on row %d\n", choice, row + 1));
- if (myItem(data, row + 1)) {
- result = row2index(all, row + 1, selected);
- }
- TRACE(("! next_item(%d, %s) ->%d\n", choice, mySide(selected), result));
- return result;
-}
-
-/*
- * Return the first choice from items[] for the given column.
- */
-static int
-first_item(ALL_DATA * all, int selected)
-{
- MY_DATA *data = all->list + selected;
- int result = -1;
-
- if (myItem(data, 0) != 0) {
- int n;
-
- for (n = 0; n < all->item_no; ++n) {
- if (myItem(data, 0) == &all->items[n]) {
- result = n;
- break;
- }
- }
- }
- TRACE(("! first_item %s = %d\n", mySide(selected), result));
- return result;
-}
-
-/*
- * Return the last choice from items[] for the given column.
- */
-static int
-last_item(ALL_DATA * all, int selected)
-{
- MY_DATA *data = all->list + selected;
- int result = -1;
- int n;
-
- for (n = 0; myItem(data, n) != 0; ++n) {
- result = n;
- }
- if (result >= 0) {
- result = row2index(all, result, selected);
- }
- TRACE(("! last_item %s = %d\n", mySide(selected), result));
- return result;
-}
-
-static int
-skip_rows(ALL_DATA * all, int row, int skip, int selected)
-{
- MY_DATA *data = all->list + selected;
- int result = row;
-
- if (skip > 0) {
- int n;
-
- for (n = row + 1; (n < all->item_no) && (n <= row + skip); ++n) {
- if (myItem(data, n) == 0)
- break;
- result = n;
- }
- } else if (skip < 0) {
- result -= skip;
- if (result < 0)
- result = 0;
- }
- TRACE(("! skip_rows row %d, skip %d, %s = %d\n",
- row, skip, mySide(selected), result));
- return result;
-}
-
-/*
- * Find the closest item in the given column starting with the given choice.
- */
-static int
-closest_item(ALL_DATA * all, int choice, int selected)
-{
- int prev = choice;
- int next = choice;
- int result = choice;
- int n;
-
- for (n = choice; n >= 0; --n) {
- if ((all->items[n].state != 0) == selected) {
- prev = n;
- break;
- }
- }
- for (n = choice; n < all->item_no; ++n) {
- if ((all->items[n].state != 0) == selected) {
- next = n;
- break;
- }
- }
- if (prev != choice) {
- result = prev;
- if (next != choice) {
- if ((choice - prev) > (next - choice)) {
- result = next;
- }
- }
- } else if (next != choice) {
- result = next;
- }
- TRACE(("! XXX closest item choice %d, %s = %d\n",
- choice, mySide(selected), result));
- return result;
-}
-
-static void
-print_both(ALL_DATA * all,
- int choice)
-{
- int selected;
- int cur_y, cur_x;
- WINDOW *dialog = wgetparent(all->list[0].win);
-
- TRACE(("! print_both %d\n", choice));
- getyx(dialog, cur_y, cur_x);
- for (selected = 0; selected < 2; ++selected) {
- MY_DATA *data = all->list + selected;
- WINDOW *win = data->win;
- int thumb_top = index2row(all, data->top_index, selected);
- int thumb_max = index2row(all, -1, selected);
- int thumb_end = thumb_top + getmaxy(win);
-
- print_1_list(all, choice, selected);
-
- dlg_mouse_setcode(selected * KEY_MAX);
- dlg_draw_scrollbar(dialog,
- (long) (data->top_index),
- (long) (thumb_top),
- (long) MIN(thumb_end, thumb_max),
- (long) thumb_max,
- data->box_x + all->check_x,
- data->box_x + getmaxx(win),
- data->box_y,
- data->box_y + getmaxy(win) + 1,
- menubox_border2_attr,
- menubox_border_attr);
- }
- (void) wmove(dialog, cur_y, cur_x);
- dlg_mouse_setcode(0);
-}
-
-static void
-set_top_item(ALL_DATA * all, int choice, int selected)
-{
- if (choice != all->list[selected].top_index) {
- DLG_TRACE(("# set top of %s column to %d\n",
- mySide(selected),
- choice));
- all->list[selected].top_index = choice;
- }
-}
-
-/*
- * Adjust the top-index as needed to ensure that it and the given item are
- * visible.
- */
-static void
-fix_top_item(ALL_DATA * all, int cur_item, int selected)
-{
- int top_item = all->list[selected].top_index;
- int cur_row = index2row(all, cur_item, selected);
- int top_row = index2row(all, top_item, selected);
-
- if (cur_row < top_row) {
- top_item = cur_item;
- } else if ((cur_row - top_row) >= all->use_height) {
- top_item = row2index(all, cur_row + 1 - all->use_height, selected);
- }
- if (cur_row < all->use_height) {
- top_item = row2index(all, 0, selected);
- }
- DLG_TRACE(("# fix_top_item(cur_item %d, %s) ->top_item %d\n",
- cur_item, mySide(selected), top_item));
- set_top_item(all, top_item, selected);
-}
-
-static void
-append_right_side(ALL_DATA * all, int choice)
-{
- MY_DATA *data = &all->list[1];
- int j;
- for (j = 0; j < all->item_no; ++j) {
- if (myItem(data, j) == 0) {
- myItem(data, j) = &all->items[choice];
- break;
- }
- }
-}
-
-static void
-amend_right_side(ALL_DATA * all, int choice)
-{
- MY_DATA *data = &all->list[1];
- int j, k;
- for (j = 0; j < all->item_no; ++j) {
- if (myItem(data, j) == &all->items[choice]) {
- for (k = j; k < all->item_no; ++k) {
- if ((myItem(data, k) = myItem(data, k + 1)) == 0)
- break;
- }
- break;
- }
- }
-}
-
-static void
-fill_one_side(ALL_DATA * all, int selected)
-{
- int i, j;
- MY_DATA *data = all->list + selected;
-
- for (i = j = 0; j < all->item_no; ++j) {
- myItem(data, i) = 0;
- if ((all->items[j].state != 0) == selected) {
- myItem(data, i) = all->items + j;
- TRACE(("! %s item[%d] %p = all[%d] %p\n",
- mySide(selected),
- i, myItem(data, i),
- j, all->items + j));
- ++i;
- }
- }
- myItem(data, i) = 0;
-}
-
-static void
-fill_both_sides(ALL_DATA * all)
-{
- int k;
-
- for (k = 0; k < 2; ++k) {
- fill_one_side(all, k);
- }
-}
-
-/*
- * This is an alternate interface to 'buildlist' which allows the application
- * to read the list item states back directly without putting them in the
- * output buffer.
- */
-int
-dlg_buildlist(const char *title,
- const char *cprompt,
- int height,
- int width,
- int list_height,
- int item_no,
- DIALOG_LISTITEM * items,
- const char *states,
- int order_mode,
- int *current_item)
-{
-#define THIS_FUNC "dlg_buildlist"
- /* *INDENT-OFF* */
- static DLG_KEYS_BINDING binding[] = {
- HELPKEY_BINDINGS,
- ENTERKEY_BINDINGS,
- DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ),
- DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ),
- DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ),
- DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ),
- DLG_KEYS_DATA( DLGK_ITEM_FIRST, KEY_HOME ),
- DLG_KEYS_DATA( DLGK_ITEM_LAST, KEY_END ),
- DLG_KEYS_DATA( DLGK_ITEM_LAST, KEY_LL ),
- DLG_KEYS_DATA( DLGK_ITEM_NEXT, '+' ),
- DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_DOWN ),
- DLG_KEYS_DATA( DLGK_ITEM_NEXT, CHR_NEXT ),
- DLG_KEYS_DATA( DLGK_ITEM_PREV, '-' ),
- DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_UP ),
- DLG_KEYS_DATA( DLGK_ITEM_PREV, CHR_PREVIOUS ),
- DLG_KEYS_DATA( DLGK_PAGE_NEXT, KEY_NPAGE ),
- DLG_KEYS_DATA( DLGK_PAGE_NEXT, DLGK_MOUSE(KEY_NPAGE) ),
- DLG_KEYS_DATA( DLGK_PAGE_NEXT, DLGK_MOUSE(KEY_NPAGE+KEY_MAX) ),
- DLG_KEYS_DATA( DLGK_PAGE_PREV, KEY_PPAGE ),
- DLG_KEYS_DATA( DLGK_PAGE_PREV, DLGK_MOUSE(KEY_PPAGE) ),
- DLG_KEYS_DATA( DLGK_PAGE_PREV, DLGK_MOUSE(KEY_PPAGE+KEY_MAX) ),
- DLG_KEYS_DATA( DLGK_GRID_LEFT, KEY_LEFTCOL ),
- DLG_KEYS_DATA( DLGK_GRID_RIGHT, KEY_RIGHTCOL ),
- TOGGLEKEY_BINDINGS,
- END_KEYS_BINDING
- };
- /* *INDENT-ON* */
-
-#ifdef KEY_RESIZE
- int old_height = height;
- int old_width = width;
-#endif
- ALL_DATA all;
- MY_DATA *data = all.list;
- int i, j, k, key2, found, x, y, cur_x, cur_y;
- int key, fkey;
- bool save_visit = dialog_state.visit_items;
- int button;
- int cur_item;
- int name_width, text_width, full_width, list_width;
- int result = DLG_EXIT_UNKNOWN;
- int num_states;
- bool first = TRUE;
- WINDOW *dialog;
- char *prompt;
- const char **buttons = dlg_ok_labels();
- const char *widget_name = "buildlist";
-
- dialog_state.plain_buttons = TRUE;
-
- /*
- * Unlike other uses of --visit-items, we have two windows to visit.
- */
- if (dialog_state.visit_cols)
- dialog_state.visit_cols = 2;
-
- memset(&all, 0, sizeof(all));
- all.items = items;
- all.item_no = item_no;
- for (k = 0; k < 2; ++k) {
- data[k].ip = dlg_calloc(DIALOG_LISTITEM *, (item_no + 2));
- }
- fill_both_sides(&all);
-
- if (dialog_vars.default_item != 0) {
- cur_item = dlg_default_listitem(items);
- } else {
- if ((cur_item = first_item(&all, 0)) < 0)
- cur_item = first_item(&all, 1);
- }
- button = (dialog_state.visit_items
- ? (items[cur_item].state ? sRIGHT : sLEFT)
- : dlg_default_button());
-
- dlg_does_output();
-
-#ifdef KEY_RESIZE
- retry:
-#endif
-
- prompt = dlg_strclone(cprompt);
- dlg_tab_correct_str(prompt);
-
- all.use_height = list_height;
- all.use_width = (2 * (dlg_calc_list_width(item_no, items)
- + 4
- + 2 * MARGIN)
- + 1);
- all.use_width = MAX(26, all.use_width);
- if (all.use_height == 0) {
- /* calculate height without items (4) */
- dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, all.use_width);
- dlg_calc_listh(&height, &all.use_height, item_no);
- } else {
- dlg_auto_size(title, prompt,
- &height, &width,
- MIN_HIGH + all.use_height, all.use_width);
- }
- dlg_button_layout(buttons, &width);
- dlg_print_size(height, width);
- dlg_ctl_size(height, width);
-
- /* we need at least two states */
- if (states == 0 || strlen(states) < 2)
- states = " *";
- num_states = (int) strlen(states);
-
- x = dlg_box_x_ordinate(width);
- y = dlg_box_y_ordinate(height);
-
- dialog = dlg_new_window(height, width, y, x);
- dlg_register_window(dialog, widget_name, binding);
- dlg_register_buttons(dialog, widget_name, buttons);
-
- dlg_mouse_setbase(all.base_x = x, all.base_y = y);
-
- dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr);
- dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
- dlg_draw_title(dialog, title);
-
- dlg_attrset(dialog, dialog_attr);
- dlg_print_autowrap(dialog, prompt, height, width);
-
- list_width = (width - 6 * MARGIN - 2) / 2;
- getyx(dialog, cur_y, cur_x);
- data[0].box_y = cur_y + 1;
- data[0].box_x = MARGIN + 1;
- data[1].box_y = cur_y + 1;
- data[1].box_x = data[0].box_x + 1 + 2 * MARGIN + list_width;
-
- /*
- * After displaying the prompt, we know how much space we really have.
- * Limit the list to avoid overwriting the ok-button.
- */
- if (all.use_height + MIN_HIGH > height - cur_y)
- all.use_height = height - MIN_HIGH - cur_y;
- if (all.use_height <= 0)
- all.use_height = 1;
-
- for (k = 0; k < 2; ++k) {
- /* create new window for the list */
- data[k].win = dlg_sub_window(dialog, all.use_height, list_width,
- y + data[k].box_y + 1,
- x + data[k].box_x + 1);
-
- /* draw a box around the list items */
- dlg_draw_box(dialog, data[k].box_y, data[k].box_x,
- all.use_height + 2 * MARGIN,
- list_width + 2 * MARGIN,
- menubox_border_attr, menubox_border2_attr);
- }
-
- text_width = 0;
- name_width = 0;
- /* Find length of longest item to center buildlist */
- for (i = 0; i < item_no; i++) {
- text_width = MAX(text_width, dlg_count_columns(items[i].text));
- name_width = MAX(name_width, dlg_count_columns(items[i].name));
- }
-
- /* If the name+text is wider than the list is allowed, then truncate
- * one or both of them. If the name is no wider than 1/4 of the list,
- * leave it intact.
- */
- all.use_width = (list_width - 6 * MARGIN);
- if (dialog_vars.no_tags && !dialog_vars.no_items) {
- full_width = MIN(all.use_width, text_width);
- } else if (dialog_vars.no_items) {
- full_width = MIN(all.use_width, name_width);
- } else {
- if (text_width >= 0
- && name_width >= 0
- && all.use_width > 0
- && text_width + name_width > all.use_width) {
- int need = (int) (0.25 * all.use_width);
- if (name_width > need) {
- int want = (int) (all.use_width * ((double) name_width) /
- (text_width + name_width));
- name_width = (want > need) ? want : need;
- }
- text_width = all.use_width - name_width;
- }
- full_width = text_width + name_width;
- }
-
- all.check_x = (all.use_width - full_width) / 2;
- all.item_x = ((dialog_vars.no_tags
- ? 0
- : (dialog_vars.no_items
- ? 0
- : (name_width + 2)))
- + all.check_x);
-
- /* ensure we are scrolled to show the current choice */
- j = MIN(all.use_height, item_no);
- for (i = 0; i < 2; ++i) {
- if ((items[cur_item].state != 0) == i) {
- int top_item = cur_item - j + 1;
- if (top_item < 0)
- top_item = 0;
- while ((items[top_item].state != 0) != i)
- ++top_item;
- set_top_item(&all, top_item, i);
- } else {
- set_top_item(&all, 0, i);
- }
- }
-
- /* register the new window, along with its borders */
- for (i = 0; i < 2; ++i) {
- dlg_mouse_mkbigregion(data[i].box_y + 1,
- data[i].box_x,
- all.use_height,
- list_width + 2,
- 2 * KEY_MAX + (i * (1 + all.use_height)),
- 1, 1, 1 /* by lines */ );
- }
-
- dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width);
-
- while (result == DLG_EXIT_UNKNOWN) {
- int which = (items[cur_item].state != 0);
- MY_DATA *moi = data + which;
- int at_top = index2row(&all, moi->top_index, which);
- int at_end = index2row(&all, -1, which);
- int at_bot = skip_rows(&all, at_top, all.use_height, which);
- int was_mouse;
-
- DLG_TRACE(("# ** state %d:%d top %d (%d:%d:%d) %s\n",
- cur_item, item_no - 1,
- moi->top_index,
- at_top, at_bot, at_end,
- mySide(which)));
-
- if (first) {
- print_both(&all, cur_item);
- dlg_trace_win(dialog);
- first = FALSE;
- }
-
- if (button < 0) { /* --visit-items */
- int cur_row = index2row(&all, cur_item, which);
- cur_y = (data[which].box_y
- + cur_row
- + 1);
- if (at_top > 0)
- cur_y -= at_top;
- cur_x = (data[which].box_x
- + all.check_x + 1);
- DLG_TRACE(("# ...visit row %d (%d,%d)\n", cur_row, cur_y, cur_x));
- wmove(dialog, cur_y, cur_x);
- }
-
- key = dlg_mouse_wgetch(dialog, &fkey);
- if (dlg_result_key(key, fkey, &result)) {
- if (!dlg_button_key(result, &button, &key, &fkey))
- break;
- }
-
- was_mouse = (fkey && is_DLGK_MOUSE(key));
- if (was_mouse)
- key -= M_EVENT;
-
- if (!was_mouse) {
- ;
- } else if (key >= 2 * KEY_MAX) {
- i = (key - 2 * KEY_MAX) % (1 + all.use_height);
- j = (key - 2 * KEY_MAX) / (1 + all.use_height);
- k = row2index(&all, i + at_top, j);
- DLG_TRACE(("# MOUSE column %d, row %d ->item %d\n", j, i, k));
- if (k >= 0 && j < 2) {
- if (j != which) {
- /*
- * Mouse click was in the other column.
- */
- moi = data + j;
- fix_top_item(&all, k, j);
- }
- which = j;
- at_top = index2row(&all, moi->top_index, which);
- at_bot = skip_rows(&all, at_top, all.use_height, which);
- cur_item = k;
- print_both(&all, cur_item);
- key = DLGK_TOGGLE; /* force the selected item to toggle */
- } else {
- beep();
- continue;
- }
- fkey = FALSE;
- } else if (key >= KEY_MIN) {
- if (key > KEY_MAX) {
- if (which == 0) {
- key = KEY_RIGHTCOL; /* switch to right-column */
- fkey = FALSE;
- } else {
- key -= KEY_MAX;
- }
- } else {
- if (which == 1) {
- key = KEY_LEFTCOL; /* switch to left-column */
- fkey = FALSE;
- }
- }
- key = dlg_lookup_key(dialog, key, &fkey);
- }
-
- /*
- * A space toggles the item status. Normally we put the cursor on
- * the next available item in the same column. But if there are no
- * more items in the column, move the cursor to the other column.
- */
- if (key == DLGK_TOGGLE) {
- int new_choice;
- int new_state = items[cur_item].state + 1;
-
- if ((new_choice = next_item(&all, cur_item, which)) == cur_item) {
- new_choice = prev_item(&all, cur_item, which);
- }
- DLG_TRACE(("# cur_item %d, new_choice:%d\n", cur_item, new_choice));
- /* FIXME - how to test and handle multiple states? */
- if (new_state >= num_states)
- new_state = 0;
-
- items[cur_item].state = new_state;
- if (order_mode) {
- fill_one_side(&all, 0);
- if (new_state) {
- append_right_side(&all, cur_item);
- } else {
- amend_right_side(&all, cur_item);
- }
- } else {
- fill_both_sides(&all);
- }
- if (cur_item == moi->top_index) {
- set_top_item(&all, new_choice, which);
- }
-
- if (new_choice >= 0) {
- fix_top_item(&all, cur_item, !which);
- cur_item = new_choice;
- }
- print_both(&all, cur_item);
- dlg_trace_win(dialog);
- continue; /* wait for another key press */
- }
-
- /*
- * Check if key pressed matches first character of any item tag in
- * list. If there is more than one match, we will cycle through
- * each one as the same key is pressed repeatedly.
- */
- found = FALSE;
- if (!fkey) {
- if (button < 0 || !dialog_state.visit_items) {
- for (j = cur_item + 1; j < item_no; j++) {
- if (check_hotkey(items, j, which)) {
- found = TRUE;
- i = j;
- break;
- }
- }
- if (!found) {
- for (j = 0; j <= cur_item; j++) {
- if (check_hotkey(items, j, which)) {
- found = TRUE;
- i = j;
- break;
- }
- }
- }
- if (found)
- dlg_flush_getc();
- } else if ((j = dlg_char_to_button(key, buttons)) >= 0) {
- button = j;
- ungetch('\n');
- continue;
- }
- }
-
- /*
- * A single digit (1-9) positions the selection to that line in the
- * current screen.
- */
- if (!found
- && (key <= '9')
- && (key > '0')
- && (key - '1' < at_bot)) {
- found = TRUE;
- i = key - '1';
- }
-
- if (!found && fkey) {
- switch (key) {
- case DLGK_FIELD_PREV:
- if ((button == sRIGHT) && dialog_state.visit_items) {
- key = DLGK_GRID_LEFT;
- button = sLEFT;
- } else {
- button = dlg_prev_button(buttons, button);
- dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
- FALSE, width);
- if (button == sRIGHT) {
- key = DLGK_GRID_RIGHT;
- } else {
- continue;
- }
- }
- break;
- case DLGK_FIELD_NEXT:
- if ((button == sLEFT) && dialog_state.visit_items) {
- key = DLGK_GRID_RIGHT;
- button = sRIGHT;
- } else {
- button = dlg_next_button(buttons, button);
- dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
- FALSE, width);
- if (button == sLEFT) {
- key = DLGK_GRID_LEFT;
- } else {
- continue;
- }
- }
- break;
- }
-
- i = cur_item;
- found = TRUE;
- switch (key) {
- case DLGK_GRID_LEFT:
- i = closest_item(&all, cur_item, 0);
- fix_top_item(&all, i, 0);
- break;
- case DLGK_GRID_RIGHT:
- if (order_mode) {
- i = last_item(&all, 1);
- } else {
- i = closest_item(&all, cur_item, 1);
- }
- fix_top_item(&all, i, 1);
- break;
- case DLGK_PAGE_PREV:
- if (cur_item > moi->top_index) {
- i = moi->top_index;
- } else if (moi->top_index != 0) {
- int temp = at_top;
- if ((temp -= all.use_height) < 0)
- temp = 0;
- i = row2index(&all, temp, which);
- }
- break;
- case DLGK_PAGE_NEXT:
- if ((at_end - at_bot) < all.use_height) {
- i = next_item(&all,
- row2index(&all, at_end, which),
- which);
- } else {
- i = next_item(&all,
- row2index(&all, at_bot, which),
- which);
- at_top = at_bot;
- set_top_item(&all,
- next_item(&all,
- row2index(&all, at_top, which),
- which),
- which);
- at_bot = skip_rows(&all, at_top, all.use_height, which);
- at_bot = MIN(at_bot, at_end);
- }
- break;
- case DLGK_ITEM_FIRST:
- i = first_item(&all, which);
- break;
- case DLGK_ITEM_LAST:
- i = last_item(&all, which);
- break;
- case DLGK_ITEM_PREV:
- i = prev_item(&all, cur_item, which);
- if (stop_prev(&all, cur_item, which))
- continue;
- break;
- case DLGK_ITEM_NEXT:
- i = next_item(&all, cur_item, which);
- break;
- default:
- found = FALSE;
- break;
- }
- }
-
- if (found) {
- if (i != cur_item) {
- int now_at = index2row(&all, i, which);
- int oops = item_no;
- int old_item;
-
- DLG_TRACE(("# <--CHOICE %d\n", i));
- DLG_TRACE(("# <--topITM %d\n", moi->top_index));
- DLG_TRACE(("# <--now_at %d\n", now_at));
- DLG_TRACE(("# <--at_top %d\n", at_top));
- DLG_TRACE(("# <--at_bot %d\n", at_bot));
-
- if (now_at >= at_bot) {
- while (now_at >= at_bot) {
- if ((at_bot - at_top) >= all.use_height) {
- set_top_item(&all,
- next_item(&all, moi->top_index, which),
- which);
- }
- at_top = index2row(&all, moi->top_index, which);
- at_bot = skip_rows(&all, at_top, all.use_height, which);
-
- DLG_TRACE(("# ...at_bot %d (now %d vs %d)\n",
- at_bot, now_at, at_end));
- DLG_TRACE(("# ...topITM %d\n", moi->top_index));
- DLG_TRACE(("# ...at_top %d (diff %d)\n", at_top,
- at_bot - at_top));
-
- if (at_bot >= at_end) {
- /*
- * If we bumped into the end, move the top-item
- * down by one line so that we can display the
- * last item in the list.
- */
- if ((at_bot - at_top) > all.use_height) {
- set_top_item(&all,
- next_item(&all, moi->top_index, which),
- which);
- } else if (at_top > 0 &&
- (at_bot - at_top) >= all.use_height) {
- set_top_item(&all,
- next_item(&all, moi->top_index, which),
- which);
- }
- break;
- }
- if (--oops < 0) {
- DLG_TRACE(("# OOPS-forward\n"));
- break;
- }
- }
- } else if (now_at < at_top) {
- while (now_at < at_top) {
- old_item = moi->top_index;
- set_top_item(&all,
- prev_item(&all, moi->top_index, which),
- which);
- at_top = index2row(&all, moi->top_index, which);
-
- DLG_TRACE(("# ...at_top %d (now %d)\n", at_top, now_at));
- DLG_TRACE(("# ...topITM %d\n", moi->top_index));
-
- if (moi->top_index >= old_item)
- break;
- if (at_top <= now_at)
- break;
- if (--oops < 0) {
- DLG_TRACE(("# OOPS-backward\n"));
- break;
- }
- }
- }
- DLG_TRACE(("# -->now_at %d\n", now_at));
- cur_item = i;
- print_both(&all, cur_item);
- }
- dlg_trace_win(dialog);
- continue; /* wait for another key press */
- }
-
- if (fkey) {
- switch (key) {
- case DLGK_ENTER:
- result = dlg_enter_buttoncode(button);
- break;
- case DLGK_LEAVE:
- result = dlg_ok_buttoncode(button);
- break;
-#ifdef KEY_RESIZE
- case KEY_RESIZE:
- dlg_will_resize(dialog);
- /* reset data */
- height = old_height;
- width = old_width;
- free(prompt);
- _dlg_resize_cleanup(dialog);
- /* repaint */
- first = TRUE;
- goto retry;
-#endif
- default:
- if (was_mouse) {
- if ((key2 = dlg_ok_buttoncode(key)) >= 0) {
- result = key2;
- break;
- }
- beep();
- }
- }
- } else if (key > 0) {
- beep();
- }
- }
-
- /*
- * If told to re-order the list, update it to reflect the current display:
- * a) The left-side will be at the beginning, without gaps.
- * b) The right-side will follow, in display-order.
- */
- if (order_mode) {
- DIALOG_LISTITEM *redo;
- int row;
- int choice;
- int new_item = cur_item;
-
- redo = dlg_calloc(DIALOG_LISTITEM, (size_t) item_no + 1);
- assert_ptr(redo, THIS_FUNC);
-
- j = 0;
- for (k = 0; k < 2; ++k) {
- for (row = 0; row < item_no; ++row) {
- if (myItem(all.list + k, row) == 0)
- break;
- choice = row2index(&all, row, k);
- if (choice == cur_item)
- new_item = j;
- redo[j++] = items[choice];
- }
- }
-
- cur_item = new_item;
- memcpy(items, redo, sizeof(DIALOG_LISTITEM) * (size_t) (item_no + 1));
-
- free(redo);
- }
-
- for (k = 0; k < 2; ++k) {
- free(data[k].ip);
- }
-
- dialog_state.visit_cols = save_visit;
- dlg_del_window(dialog);
- dlg_mouse_free_regions();
- free(prompt);
-
- *current_item = cur_item;
- return result;
-#undef THIS_FUNC
-}
-
-/*
- * Display a dialog box with a list of options that can be turned on or off
- */
-int
-dialog_buildlist(const char *title,
- const char *cprompt,
- int height,
- int width,
- int list_height,
- int item_no,
- char **items,
- int order_mode)
-{
-#define THIS_FUNC "dialog_buildlist"
- int result;
- int i, j;
- DIALOG_LISTITEM *listitems;
- bool separate_output = dialog_vars.separate_output;
- bool show_status = FALSE;
- int current = 0;
- char *help_result;
-
- DLG_TRACE(("# buildlist args:\n"));
- DLG_TRACE2S("title", title);
- DLG_TRACE2S("message", cprompt);
- DLG_TRACE2N("height", height);
- DLG_TRACE2N("width", width);
- DLG_TRACE2N("lheight", list_height);
- DLG_TRACE2N("llength", item_no);
- /* FIXME dump the items[][] too */
- DLG_TRACE2N("order", order_mode != 0);
-
- listitems = dlg_calloc(DIALOG_LISTITEM, (size_t) item_no + 1);
- assert_ptr(listitems, THIS_FUNC);
-
- for (i = j = 0; i < item_no; ++i) {
- listitems[i].name = items[j++];
- listitems[i].text = (dialog_vars.no_items
- ? dlg_strempty()
- : items[j++]);
- listitems[i].state = !dlg_strcmp(items[j++], "on");
- listitems[i].help = ((dialog_vars.item_help)
- ? items[j++]
- : dlg_strempty());
- }
- dlg_align_columns(&listitems[0].text, (int) sizeof(DIALOG_LISTITEM), item_no);
-
- result = dlg_buildlist(title,
- cprompt,
- height,
- width,
- list_height,
- item_no,
- listitems,
- NULL,
- order_mode,
- ¤t);
-
- switch (result) {
- case DLG_EXIT_OK: /* FALLTHRU */
- case DLG_EXIT_EXTRA:
- show_status = TRUE;
- break;
- case DLG_EXIT_HELP:
- dlg_add_help_listitem(&result, &help_result, &listitems[current]);
- if ((show_status = dialog_vars.help_status)) {
- if (separate_output) {
- dlg_add_string(help_result);
- } else {
- dlg_add_quoted(help_result);
- }
- } else {
- dlg_add_string(help_result);
- }
- break;
- }
-
- if (show_status) {
- for (i = 0; i < item_no; i++) {
- if (listitems[i].state) {
- if (dlg_need_separator())
- dlg_add_separator();
- if (separate_output) {
- dlg_add_string(listitems[i].name);
- } else {
- dlg_add_quoted(listitems[i].name);
- }
- }
- }
- AddLastKey();
- }
-
- dlg_free_columns(&listitems[0].text, (int) sizeof(DIALOG_LISTITEM), item_no);
- free(listitems);
- return result;
-#undef THIS_FUNC
-}
Index: sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/menubox.c
===================================================================
--- sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/menubox.c (revision 33)
+++ sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/menubox.c (nonexistent)
@@ -1,815 +0,0 @@
-/*
- * $Id: menubox.c,v 1.171 2020/11/23 21:03:11 tom Exp $
- *
- * menubox.c -- implements the menu box
- *
- * Copyright 2000-2019,2020 Thomas E. Dickey
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public Licens, version 2.1e
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to
- * Free Software Foundation, Inc.
- * 51 Franklin St., Fifth Floor
- * Boston, MA 02110, USA.
- *
- * An earlier version of this program lists as authors
- * Savio Lam (lam836@cs.cuhk.hk)
- */
-
-#include <dlg_internals.h>
-#include <dlg_keys.h>
-
-typedef enum {
- Unselected = 0,
- Selected,
- Editing
-} Mode;
-
-typedef struct {
- /* the outer-window */
- WINDOW *dialog;
- int box_y;
- int box_x;
- int tag_x;
- int item_x;
- int menu_height;
- int menu_width;
- /* the inner-window */
- WINDOW *menu;
- DIALOG_LISTITEM *items;
- int item_no;
-} ALL_DATA;
-
-#define MIN_HIGH 4
-
-#define INPUT_ROWS 3 /* rows per inputmenu entry */
-
-#define RowHeight(i) (is_inputmenu ? ((i) * INPUT_ROWS) : ((i) * 1))
-#define ItemToRow(i) (is_inputmenu ? ((i) * INPUT_ROWS + 1) : (i))
-#define RowToItem(i) (is_inputmenu ? ((i) / INPUT_ROWS + 0) : (i))
-
-/*
- * Print menu item
- */
-static void
-print_item(ALL_DATA * data,
- WINDOW *win,
- DIALOG_LISTITEM * item,
- int choice,
- Mode selected,
- bool is_inputmenu)
-{
- chtype save = dlg_get_attrs(win);
- int climit = (data->item_x - data->tag_x - GUTTER);
- int my_width = data->menu_width;
- int my_x = data->item_x;
- int my_y = ItemToRow(choice);
- bool both = (!dialog_vars.no_tags && !dialog_vars.no_items);
- bool first = TRUE;
- chtype bordchar;
- const char *show = (dialog_vars.no_items
- ? item->name
- : item->text);
-
- switch (selected) {
- default:
- case Unselected:
- bordchar = item_attr;
- break;
- case Selected:
- bordchar = item_selected_attr;
- break;
- case Editing:
- bordchar = dialog_attr;
- break;
- }
-
- /* Clear 'residue' of last item and mark current current item */
- if (is_inputmenu) {
- int n;
-
- dlg_attrset(win, (selected != Unselected) ? item_selected_attr : item_attr);
- for (n = my_y - 1; n < my_y + INPUT_ROWS - 1; n++) {
- wmove(win, n, 0);
- wprintw(win, "%*s", my_width, " ");
- }
- } else {
- dlg_attrset(win, menubox_attr);
- wmove(win, my_y, 0);
- wprintw(win, "%*s", my_width, " ");
- }
-
- /* highlight first char of the tag to be special */
- if (both) {
- (void) wmove(win, my_y, data->tag_x);
- dlg_print_listitem(win, item->name, climit, first, selected);
- first = FALSE;
- }
-
- /* Draw the input field box (only for inputmenu) */
- (void) wmove(win, my_y, my_x);
- if (is_inputmenu) {
- my_width -= 1;
- dlg_draw_box(win, my_y - 1, my_x, INPUT_ROWS, my_width - my_x - data->tag_x,
- bordchar,
- bordchar);
- my_width -= 1;
- ++my_x;
- }
-
- /* print actual item */
- wmove(win, my_y, my_x);
- dlg_print_listitem(win, show, my_width - my_x, first, selected);
-
- if (selected) {
- dlg_item_help(item->help);
- }
- dlg_attrset(win, save);
-}
-
-/*
- * Allow the user to edit the text of a menu entry.
- */
-static int
-input_menu_edit(ALL_DATA * data,
- DIALOG_LISTITEM * items,
- int choice,
- char **resultp)
-{
- chtype save = dlg_get_attrs(data->menu);
- char *result;
- int offset = 0;
- int key = 0, fkey = 0;
- bool first = TRUE;
- /* see above */
- bool is_inputmenu = TRUE;
- int y = ItemToRow(choice);
- int code = TRUE;
- int max_len = dlg_max_input(MAX((int) strlen(items->text) + 1, MAX_LEN));
-
- result = dlg_malloc(char, (size_t) max_len);
- assert_ptr(result, "input_menu_edit");
-
- /* original item is used to initialize the input string. */
- result[0] = '\0';
- strcpy(result, items->text);
-
- print_item(data, data->menu, items, choice, Editing, TRUE);
-
- /* taken out of inputbox.c - but somewhat modified */
- for (;;) {
- if (!first) {
- int check = DLG_EXIT_UNKNOWN;
- key = dlg_mouse_wgetch(data->menu, &fkey);
- if (dlg_result_key(key, fkey, &check)) {
- if (check == DLG_EXIT_CANCEL) {
- code = FALSE;
- break;
- } else {
- flash();
- }
- }
- }
- if (dlg_edit_string(result, &offset, key, fkey, first)) {
- dlg_show_string(data->menu, result, offset, inputbox_attr,
- y,
- data->item_x + 1,
- data->menu_width - data->item_x - 3,
- FALSE, first);
- first = FALSE;
- } else if (key == ESC || key == TAB) {
- code = FALSE;
- break;
- } else {
- break;
- }
- }
- print_item(data, data->menu, items, choice, Selected, TRUE);
- dlg_attrset(data->menu, save);
-
- *resultp = result;
- return code;
-}
-
-static int
-handle_button(int code, DIALOG_LISTITEM * items, int choice)
-{
- char *help_result;
-
- switch (code) {
- case DLG_EXIT_OK: /* FALLTHRU */
- case DLG_EXIT_EXTRA:
- dlg_add_string(items[choice].name);
- break;
- case DLG_EXIT_HELP:
- dlg_add_help_listitem(&code, &help_result, &items[choice]);
- dlg_add_string(help_result);
- break;
- }
- AddLastKey();
- return code;
-}
-
-int
-dlg_renamed_menutext(DIALOG_LISTITEM * items, int current, char *newtext)
-{
- if (dialog_vars.input_result)
- dialog_vars.input_result[0] = '\0';
- dlg_add_result("RENAMED ");
- dlg_add_string(items[current].name);
- dlg_add_result(" ");
- dlg_add_string(newtext);
- AddLastKey();
- return DLG_EXIT_EXTRA;
-}
-
-int
-dlg_dummy_menutext(DIALOG_LISTITEM * items, int current, char *newtext)
-{
- (void) items;
- (void) current;
- (void) newtext;
- return DLG_EXIT_ERROR;
-}
-
-static void
-print_menu(ALL_DATA * data, int choice, int scrollamt, int max_choice, bool is_inputmenu)
-{
- int i;
-
- for (i = 0; i < max_choice; i++) {
- print_item(data,
- data->menu,
- &data->items[i + scrollamt],
- i,
- (i == choice) ? Selected : Unselected,
- is_inputmenu);
- }
-
- /* Clean bottom lines */
- if (is_inputmenu) {
- int spare_lines, x_count;
- spare_lines = data->menu_height % INPUT_ROWS;
- dlg_attrset(data->menu, menubox_attr);
- for (; spare_lines; spare_lines--) {
- wmove(data->menu, data->menu_height - spare_lines, 0);
- for (x_count = 0; x_count < data->menu_width;
- x_count++) {
- waddch(data->menu, ' ');
- }
- }
- }
-
- (void) wnoutrefresh(data->menu);
-
- dlg_draw_scrollbar(data->dialog,
- scrollamt,
- scrollamt,
- scrollamt + max_choice,
- data->item_no,
- data->box_x,
- data->box_x + data->menu_width,
- data->box_y,
- data->box_y + data->menu_height + 1,
- menubox_border2_attr,
- menubox_border_attr);
-}
-
-static bool
-check_hotkey(DIALOG_LISTITEM * items, int choice)
-{
- bool result = FALSE;
-
- if (dlg_match_char(dlg_last_getc(),
- (dialog_vars.no_tags
- ? items[choice].text
- : items[choice].name))) {
- result = TRUE;
- }
- return result;
-}
-
-/*
- * This is an alternate interface to 'menu' which allows the application
- * to read the list item states back directly without putting them in the
- * output buffer.
- */
-int
-dlg_menu(const char *title,
- const char *cprompt,
- int height,
- int width,
- int menu_height,
- int item_no,
- DIALOG_LISTITEM * items,
- int *current_item,
- DIALOG_INPUTMENU rename_menutext)
-{
- /* *INDENT-OFF* */
- static DLG_KEYS_BINDING binding[] = {
- HELPKEY_BINDINGS,
- ENTERKEY_BINDINGS,
- TOGGLEKEY_BINDINGS,
- DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ),
- DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ),
- DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ),
- DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ),
- DLG_KEYS_DATA( DLGK_ITEM_NEXT, '+' ),
- DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_DOWN ),
- DLG_KEYS_DATA( DLGK_ITEM_NEXT, CHR_NEXT ),
- DLG_KEYS_DATA( DLGK_ITEM_PREV, '-' ),
- DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_UP ),
- DLG_KEYS_DATA( DLGK_ITEM_PREV, CHR_PREVIOUS ),
- DLG_KEYS_DATA( DLGK_PAGE_FIRST, KEY_HOME ),
- DLG_KEYS_DATA( DLGK_PAGE_LAST, KEY_END ),
- DLG_KEYS_DATA( DLGK_PAGE_LAST, KEY_LL ),
- DLG_KEYS_DATA( DLGK_PAGE_NEXT, KEY_NPAGE ),
- DLG_KEYS_DATA( DLGK_PAGE_PREV, KEY_PPAGE ),
- END_KEYS_BINDING
- };
- static DLG_KEYS_BINDING binding2[] = {
- INPUTSTR_BINDINGS,
- HELPKEY_BINDINGS,
- ENTERKEY_BINDINGS,
- END_KEYS_BINDING
- };
- /* *INDENT-ON* */
-
-#ifdef KEY_RESIZE
- int old_LINES = LINES;
- int old_COLS = COLS;
- int old_height = height;
- int old_width = width;
-#endif
- ALL_DATA all;
- int i, j, x, y, cur_x, cur_y;
- int fkey;
- int button = dialog_state.visit_items ? -1 : dlg_default_button();
- int choice = dlg_default_listitem(items);
- int result = DLG_EXIT_UNKNOWN;
- int scrollamt = 0;
- int max_choice;
- int use_width, name_width, text_width, list_width;
- WINDOW *dialog, *menu;
- char *prompt = 0;
- const char **buttons = dlg_ok_labels();
- bool is_inputmenu = ((rename_menutext != 0)
- && (rename_menutext != dlg_dummy_menutext));
-
- DLG_TRACE(("# menubox args:\n"));
- DLG_TRACE2S("title", title);
- DLG_TRACE2S("message", cprompt);
- DLG_TRACE2N("height", height);
- DLG_TRACE2N("width", width);
- DLG_TRACE2N("lheight", menu_height);
- DLG_TRACE2N("llength", item_no);
- /* FIXME dump the items[][] too */
- DLG_TRACE2N("rename", rename_menutext != 0);
-
- dialog_state.plain_buttons = TRUE;
-
- all.items = items;
- all.item_no = item_no;
-
- dlg_does_output();
-
-#ifdef KEY_RESIZE
- retry:
-#endif
-
- prompt = dlg_strclone(cprompt);
- dlg_tab_correct_str(prompt);
-
- all.menu_height = menu_height;
- use_width = dlg_calc_list_width(item_no, items) + 10;
- use_width = MAX(26, use_width);
- if (all.menu_height == 0) {
- /* calculate height without items (4) */
- dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, use_width);
- dlg_calc_listh(&height, &all.menu_height, item_no);
- } else {
- dlg_auto_size(title, prompt,
- &height, &width,
- MIN_HIGH + all.menu_height, use_width);
- }
- dlg_button_layout(buttons, &width);
- dlg_print_size(height, width);
- dlg_ctl_size(height, width);
-
- x = dlg_box_x_ordinate(width);
- y = dlg_box_y_ordinate(height);
-
- dialog = dlg_new_window(height, width, y, x);
- all.dialog = dialog;
-
- dlg_register_window(dialog, "menubox", binding);
- dlg_register_buttons(dialog, "menubox", buttons);
-
- dlg_mouse_setbase(x, y);
-
- dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr);
- dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
- dlg_draw_title(dialog, title);
-
- dlg_attrset(dialog, dialog_attr);
- dlg_print_autowrap(dialog, prompt, height, width);
-
- all.menu_width = width - 6;
- getyx(dialog, cur_y, cur_x);
- all.box_y = cur_y + 1;
- all.box_x = (width - all.menu_width) / 2 - 1;
-
- /*
- * After displaying the prompt, we know how much space we really have.
- * Limit the list to avoid overwriting the ok-button.
- */
- if (all.menu_height + MIN_HIGH > height - cur_y)
- all.menu_height = height - MIN_HIGH - cur_y;
- if (all.menu_height <= 0)
- all.menu_height = 1;
-
- /* Find out maximal number of displayable items at once. */
- max_choice = MIN(all.menu_height,
- RowHeight(item_no));
- if (is_inputmenu)
- max_choice /= INPUT_ROWS;
-
- /* create new window for the menu */
- menu = dlg_sub_window(dialog, all.menu_height, all.menu_width,
- y + all.box_y + 1,
- x + all.box_x + 1);
- all.menu = menu;
-
- dlg_register_window(menu, "menu", binding2);
- dlg_register_buttons(menu, "menu", buttons);
-
- /* draw a box around the menu items */
- dlg_draw_box(dialog,
- all.box_y, all.box_x,
- all.menu_height + 2, all.menu_width + 2,
- menubox_border_attr, menubox_border2_attr);
-
- name_width = 0;
- text_width = 0;
-
- /* Find length of longest item to center menu *
- * only if --menu was given, using --inputmenu *
- * won't be centered. */
- for (i = 0; i < item_no; i++) {
- name_width = MAX(name_width, dlg_count_columns(items[i].name));
- text_width = MAX(text_width, dlg_count_columns(items[i].text));
- }
-
- /* If the name+text is wider than the list is allowed, then truncate
- * one or both of them. If the name is no wider than 30% of the list,
- * leave it intact.
- *
- * FIXME: the gutter width and name/list ratio should be configurable.
- */
- use_width = (all.menu_width - GUTTER);
- if (dialog_vars.no_tags) {
- list_width = MIN(use_width, text_width);
- } else if (dialog_vars.no_items) {
- list_width = MIN(use_width, name_width);
- } else {
- if (text_width >= 0
- && name_width >= 0
- && use_width > 0
- && text_width + name_width > use_width) {
- int need = (int) (0.30 * use_width);
- if (name_width > need) {
- int want = (int) (use_width
- * ((double) name_width)
- / (text_width + name_width));
- name_width = (want > need) ? want : need;
- }
- text_width = use_width - name_width;
- }
- list_width = (text_width + name_width);
- }
-
- all.tag_x = (is_inputmenu
- ? 0
- : (use_width - list_width) / 2);
- all.item_x = ((dialog_vars.no_tags
- ? 0
- : (dialog_vars.no_items
- ? 0
- : (GUTTER + name_width)))
- + all.tag_x);
-
- if (choice - scrollamt >= max_choice) {
- scrollamt = choice - (max_choice - 1);
- choice = max_choice - 1;
- }
-
- print_menu(&all, choice, scrollamt, max_choice, is_inputmenu);
-
- /* register the new window, along with its borders */
- dlg_mouse_mkbigregion(all.box_y + 1, all.box_x,
- all.menu_height + 2, all.menu_width + 2,
- KEY_MAX, 1, 1, 1 /* by lines */ );
-
- dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width);
-
- dlg_trace_win(dialog);
-
- while (result == DLG_EXIT_UNKNOWN) {
- int key, found;
-
- if (button < 0) /* --visit-items */
- wmove(dialog,
- all.box_y + ItemToRow(choice) + 1,
- all.box_x + all.tag_x + 1);
-
- key = dlg_mouse_wgetch(dialog, &fkey);
- if (dlg_result_key(key, fkey, &result)) {
- if (!dlg_button_key(result, &button, &key, &fkey))
- break;
- }
-
- found = FALSE;
- if (fkey) {
- /*
- * Allow a mouse-click on a box to switch selection to that box.
- * Handling a button click is a little more complicated, since we
- * push a KEY_ENTER back onto the input stream so we'll put the
- * cursor at the right place before handling the "keypress".
- */
- if (key >= DLGK_MOUSE(KEY_MAX)) {
- key -= DLGK_MOUSE(KEY_MAX);
- i = RowToItem(key);
- if (i < max_choice) {
- found = TRUE;
- } else {
- beep();
- continue;
- }
- } else if (is_DLGK_MOUSE(key)
- && dlg_ok_buttoncode(key - M_EVENT) >= 0) {
- button = (key - M_EVENT);
- ungetch('\n');
- continue;
- }
- } else {
- /*
- * Check if key pressed matches first character of any item tag in
- * list. If there is more than one match, we will cycle through
- * each one as the same key is pressed repeatedly.
- */
- if (button < 0 || !dialog_state.visit_items) {
- for (j = scrollamt + choice + 1; j < item_no; j++) {
- if (check_hotkey(items, j)) {
- found = TRUE;
- i = j - scrollamt;
- break;
- }
- }
- if (!found) {
- for (j = 0; j <= scrollamt + choice; j++) {
- if (check_hotkey(items, j)) {
- found = TRUE;
- i = j - scrollamt;
- break;
- }
- }
- }
- if (found)
- dlg_flush_getc();
- } else if ((j = dlg_char_to_button(key, buttons)) >= 0) {
- button = j;
- ungetch('\n');
- continue;
- }
-
- /*
- * A single digit (1-9) positions the selection to that line in the
- * current screen.
- */
- if (!found
- && (key <= '9')
- && (key > '0')
- && (key - '1' < max_choice)) {
- found = TRUE;
- i = key - '1';
- }
- }
-
- if (!found && fkey) {
- found = TRUE;
- switch (key) {
- case DLGK_PAGE_FIRST:
- i = -scrollamt;
- break;
- case DLGK_PAGE_LAST:
- i = item_no - 1 - scrollamt;
- break;
- case DLGK_MOUSE(KEY_PPAGE):
- case DLGK_PAGE_PREV:
- if (choice)
- i = 0;
- else if (scrollamt != 0)
- i = -MIN(scrollamt, max_choice);
- else
- continue;
- break;
- case DLGK_MOUSE(KEY_NPAGE):
- case DLGK_PAGE_NEXT:
- i = MIN(choice + max_choice, item_no - scrollamt - 1);
- break;
- case DLGK_ITEM_PREV:
- i = choice - 1;
- if (choice == 0 && scrollamt == 0)
- continue;
- break;
- case DLGK_ITEM_NEXT:
- i = choice + 1;
- if (scrollamt + choice >= item_no - 1)
- continue;
- break;
- default:
- found = FALSE;
- break;
- }
- }
-
- if (found) {
- if (i != choice) {
- getyx(dialog, cur_y, cur_x);
- if (i < 0 || i >= max_choice) {
- if (i < 0) {
- scrollamt += i;
- choice = 0;
- } else {
- choice = max_choice - 1;
- scrollamt += (i - max_choice + 1);
- }
- print_menu(&all, choice, scrollamt, max_choice, is_inputmenu);
- } else {
- choice = i;
- print_menu(&all, choice, scrollamt, max_choice, is_inputmenu);
- (void) wmove(dialog, cur_y, cur_x);
- wrefresh(dialog);
- }
- }
- continue; /* wait for another key press */
- }
-
- if (fkey) {
- switch (key) {
- case DLGK_FIELD_PREV:
- button = dlg_prev_button(buttons, button);
- dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
- FALSE, width);
- break;
-
- case DLGK_FIELD_NEXT:
- button = dlg_next_button(buttons, button);
- dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
- FALSE, width);
- break;
-
- case DLGK_TOGGLE:
- case DLGK_ENTER:
- case DLGK_LEAVE:
- result = ((key == DLGK_LEAVE)
- ? dlg_ok_buttoncode(button)
- : dlg_enter_buttoncode(button));
-
- /*
- * If dlg_menu() is called from dialog_menu(), we want to
- * capture the results into dialog_vars.input_result.
- */
- if (result == DLG_EXIT_ERROR) {
- result = DLG_EXIT_UNKNOWN;
- } else if (is_inputmenu
- || rename_menutext == dlg_dummy_menutext) {
- result = handle_button(result,
- items,
- scrollamt + choice);
- }
-
- /*
- * If we have a rename_menutext function, interpret the Extra
- * button as a request to rename the menu's text. If that
- * function doesn't return "Unknown", we will exit from this
- * function. Usually that is done for dialog_menu(), so the
- * shell script can use the updated value. If it does return
- * "Unknown", update the list item only. A direct caller of
- * dlg_menu() can free the renamed value - we cannot.
- */
- if (is_inputmenu && result == DLG_EXIT_EXTRA) {
- char *tmp;
-
- if (input_menu_edit(&all,
- &items[scrollamt + choice],
- choice,
- &tmp)) {
- result = rename_menutext(items, scrollamt + choice, tmp);
- if (result == DLG_EXIT_UNKNOWN) {
- items[scrollamt + choice].text = tmp;
- } else {
- free(tmp);
- }
- } else {
- result = DLG_EXIT_UNKNOWN;
- print_item(&all,
- menu,
- &items[scrollamt + choice],
- choice,
- Selected,
- is_inputmenu);
- (void) wnoutrefresh(menu);
- free(tmp);
- }
-
- if (result == DLG_EXIT_UNKNOWN) {
- dlg_draw_buttons(dialog, height - 2, 0,
- buttons, button, FALSE, width);
- }
- }
- break;
-#ifdef KEY_RESIZE
- case KEY_RESIZE:
- dlg_will_resize(dialog);
- /* reset data */
- resizeit(height, LINES);
- resizeit(width, COLS);
- free(prompt);
- _dlg_resize_cleanup(dialog);
- /* repaint */
- goto retry;
-#endif
- default:
- flash();
- break;
- }
- }
- }
-
- dlg_mouse_free_regions();
- dlg_unregister_window(menu);
- dlg_del_window(dialog);
- free(prompt);
-
- *current_item = scrollamt + choice;
-
- DLG_TRACE2N("current", *current_item);
- return result;
-}
-
-/*
- * Display a menu for choosing among a number of options
- */
-int
-dialog_menu(const char *title,
- const char *cprompt,
- int height,
- int width,
- int menu_height,
- int item_no,
- char **items)
-{
- int result;
- int choice;
- int i, j;
- DIALOG_LISTITEM *listitems;
-
- listitems = dlg_calloc(DIALOG_LISTITEM, (size_t) item_no + 1);
- assert_ptr(listitems, "dialog_menu");
-
- for (i = j = 0; i < item_no; ++i) {
- listitems[i].name = items[j++];
- listitems[i].text = (dialog_vars.no_items
- ? dlg_strempty()
- : items[j++]);
- listitems[i].help = ((dialog_vars.item_help)
- ? items[j++]
- : dlg_strempty());
- }
- dlg_align_columns(&listitems[0].text, sizeof(DIALOG_LISTITEM), item_no);
-
- result = dlg_menu(title,
- cprompt,
- height,
- width,
- menu_height,
- item_no,
- listitems,
- &choice,
- (dialog_vars.input_menu
- ? dlg_renamed_menutext
- : dlg_dummy_menutext));
-
- dlg_free_columns(&listitems[0].text, sizeof(DIALOG_LISTITEM), item_no);
- free(listitems);
- return result;
-}
Index: sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/dialog-config.in
===================================================================
--- sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/dialog-config.in (revision 33)
+++ sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/dialog-config.in (nonexistent)
@@ -1,265 +0,0 @@
-#!@SHELL@
-# $Id: dialog-config.in,v 1.14 2021/03/05 23:48:36 tom Exp $
-##############################################################################
-# Copyright (c) 2007-2019,2021 Thomas E. Dickey #
-# #
-# Permission is hereby granted, free of charge, to any person obtaining a #
-# copy of this software and associated documentation files (the "Software"), #
-# to deal in the Software without restriction, including without limitation #
-# the rights to use, copy, modify, merge, publish, distribute, distribute #
-# with modifications, sublicense, and/or sell copies of the Software, and to #
-# permit persons to whom the Software is furnished to do so, subject to the #
-# following conditions: #
-# #
-# The above copyright notice and this permission notice shall be included in #
-# all copies or substantial portions of the Software. #
-# #
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL #
-# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING #
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER #
-# DEALINGS IN THE SOFTWARE. #
-# #
-# Except as contained in this notice, the name(s) of the above copyright #
-# holders shall not be used in advertising or otherwise to promote the sale, #
-# use or other dealings in this Software without prior written #
-# authorization. #
-##############################################################################
-
-prefix="@prefix@"
-exec_prefix="@exec_prefix@"
-datarootdir="@datarootdir@"
-
-same_prefix=yes
-same_exec_prefix=yes
-
-THIS="@PACKAGE@"
-
-test $# = 0 && exec @SHELL@ "$0" --error
-
-while test $# -gt 0; do
-
- # (re)evaluate symbols that may depend upon $prefix
- if [ "x$same_prefix" != "xyes" ]
- then
- eval exec_prefix='@exec_prefix@'
- eval datarootdir='@datarootdir@'
- elif [ "x$same_exec_prefix" != "xyes" ]
- then
- eval datarootdir='@datarootdir@'
- fi
-
- eval bindir='"@bindir@"'
- eval includedir='"@includedir@"'
- eval libdir='"@libdir@"'
- eval datadir='"@datadir@"'
- eval mandir='"@mandir@"'
-
- [ -z "$includedir" ] && includedir="${prefix}/include"
-
- eval LDFLAGS='"@LDFLAGS@"'
- eval LIBS='"@LIBS@"'
- LIBS="-l${THIS} $LIBS"
-
- # If the directory given by --libdir is not in the LDFLAGS+LIBS set,
- # prepend it to LDFLAGS to help link this application's library.
- found=no
- for opt in $LDFLAGS $LIBS
- do
- if [ "x$-L${libdir}" = "x$opt" ]
- then
- found=yes
- break
- fi
- done
- if [ $found = no ]
- then
- [ -n "$LFLAGS" ] && LDFLAGS=" $LFDLAGS"
- LDFLAGS="-L${libdir}$LDFLAGS"
- fi
- [ -z "$LDFLAGS" ] && LDFLAGS="-L${libdir}"
-
- # Ignore -L options which do not correspond to an actual directory,
- # or which are standard library directories (i.e., the linker is
- # supposed to search those directories).
- #
- # There is no portable way to find the list of standard library
- # directories. Require a POSIX shell anyway, to keep this simple.
- lib_flags=
- for opt in $LDFLAGS $LIBS
- do
- case $opt in
- -L*)
- opt_lib=`echo "x$opt" | sed -e 's/^x-L//'`
- [ -d "$opt_lib" ] || continue
- case "$opt_lib" in
- @LD_SEARCHPATH@) # skip standard libdir
- continue
- ;;
- *)
- ;;
- esac
- ;;
- esac
- lib_flags="$lib_flags $opt"
- done
-
- case "$1" in
- -*=*)
- ARG=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'`
- ;;
- *)
- ARG=
- ;;
- esac
-
- case "$1" in
- # basic configuration
- --prefix=*)
- prefix="$ARG"
- test -z "$exec_prefix" && exec_prefix="$ARG"
- same_prefix=no
- ;;
- --prefix)
- echo "$prefix"
- ;;
- --exec-prefix=*)
- exec_prefix="$ARG"
- same_exec_prefix=no
- ;;
- --exec-prefix)
- echo "$exec_prefix"
- ;;
- # compile/link
- --cflags|--cflags-only-I)
- INCS="-I$includedir"
- sed -e 's,^[ ]*,,' -e 's, [ ]*, ,g' -e 's,[ ]*$,,' <<-ENDECHO
- $INCS
-ENDECHO
- ;;
- --cflags-only-other)
- # no -D/-U options should be needed
- echo
- ;;
- --ldflags)
- OPTS=
- for opt in $LDFLAGS $LIBS
- do
- case "x$opt" in
- x-[^l]*)
- OPTS="$OPTS $opt"
- ;;
- esac
- done
- printf "%s\n" "$OPTS"
- ;;
- --libs)
- OPTS=
- for opt in $lib_flags
- do
- [ -n "$OPTS" ] && OPTS="$OPTS "
- OPTS="${OPTS}${opt}"
- done
- printf "%s\n" "$OPTS"
- ;;
- --libs-only-L)
- OPTS=
- for opt in $lib_flags
- do
- case "x$opt" in
- x-L*)
- [ -n "$OPTS" ] && OPTS="$OPTS "
- OPTS="${OPTS}${opt}"
- ;;
- esac
- done
- printf "%s\n" "$OPTS"
- ;;
- --libs-only-l)
- OPTS=
- for opt in $lib_flags
- do
- case "x$opt" in
- x-l*)
- [ -n "$OPTS" ] && OPTS="$OPTS "
- OPTS="${OPTS}${opt}"
- ;;
- esac
- done
- printf "%s\n" "$OPTS"
- ;;
- --libs-only-other)
- OPTS=
- for opt in $lib_flags
- do
- case "x$opt" in
- x-[lL]*)
- ;;
- *)
- [ -n "$OPTS" ] && OPTS="$OPTS "
- OPTS="${OPTS}${opt}"
- ;;
- esac
- done
- printf "%s\n" "$OPTS"
- ;;
- # identification
- --version)
- echo "@VERSION_MAJOR@.@VERSION_MINOR@.@VERSION_PATCH@"
- ;;
- --abi-version)
- echo "@VERSION@" | sed -e 's/:/./g'
- ;;
- # locations
- --bindir)
- echo "${bindir}"
- ;;
- --datadir)
- echo "${datadir}"
- ;;
- --libdir)
- echo "${libdir}"
- ;;
- --mandir)
- echo "${mandir}"
- ;;
- # general info
- --help)
- cat <<ENDHELP
-Usage: ${THIS}-config [options]
-
-Options:
- --prefix echos the package-prefix of ${THIS}
- --prefix=ARG sets the package-prefix of ${THIS}
- --exec-prefix echos the executable-prefix of ${THIS}
- --exec-prefix=ARG sets the executable-prefix of ${THIS}
-
- --cflags echos the C compiler flags needed to compile with ${THIS}
- --ldflags echos the linker flags needed to link with ${THIS}
-
- --libs echos the libraries needed to link with ${THIS}
- --libs-only-L echos -L linker options (search path) for ${THIS}
- --libs-only-l echos -l linker options (libraries) for ${THIS}
- --libs-only-other echos linker options other than -L/-l
-
- --version echos the release+patchdate version of ${THIS}
- --abi-version echos the ABI version of ${THIS}
-
- --bindir echos the directory containing ${THIS} programs
- --datadir echos the directory containing ${THIS} data
- --libdir echos the directory containing ${THIS} libraries
- --mandir echos the directory containing ${THIS} manual pages
-
- --help prints this message
-ENDHELP
- ;;
- --error|*)
- @SHELL@ "$0" --help 1>&2
- exit 1
- ;;
- esac
- shift
-done
-# vile:shmode
Index: sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/checklist.c
===================================================================
--- sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/checklist.c (revision 33)
+++ sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/checklist.c (nonexistent)
@@ -1,703 +0,0 @@
-/*
- * $Id: checklist.c,v 1.167 2020/11/23 00:37:47 tom Exp $
- *
- * checklist.c -- implements the checklist box
- *
- * Copyright 2000-2019,2020 Thomas E. Dickey
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License, version 2.1
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to
- * Free Software Foundation, Inc.
- * 51 Franklin St., Fifth Floor
- * Boston, MA 02110, USA.
- *
- * An earlier version of this program lists as authors:
- * Savio Lam (lam836@cs.cuhk.hk)
- * Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
- * Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
- */
-
-#include <dialog.h>
-#include <dlg_keys.h>
-
-#define MIN_HIGH 4
-
-typedef struct {
- /* the outer-window */
- WINDOW *dialog;
- int box_y;
- int box_x;
- int check_x;
- int item_x;
- int checkflag;
- int use_height;
- int use_width;
- /* the inner-window */
- WINDOW *list;
- DIALOG_LISTITEM *items;
- int item_no;
- const char *states;
-} ALL_DATA;
-
-/*
- * Print list item. The 'selected' parameter is true if 'choice' is the
- * current item. That one is colored differently from the other items.
- */
-static void
-print_item(ALL_DATA * data,
- WINDOW *win,
- DIALOG_LISTITEM * item,
- const char *states,
- int choice,
- int selected)
-{
- chtype save = dlg_get_attrs(win);
- int i;
- bool both = (!dialog_vars.no_tags && !dialog_vars.no_items);
- bool first = TRUE;
- int climit = (getmaxx(win) - data->check_x + 1);
- const char *show = (dialog_vars.no_items
- ? item->name
- : item->text);
-
- /* Clear 'residue' of last item */
- dlg_attrset(win, menubox_attr);
- (void) wmove(win, choice, 0);
- for (i = 0; i < data->use_width; i++)
- (void) waddch(win, ' ');
-
- (void) wmove(win, choice, data->check_x);
- dlg_attrset(win, selected ? check_selected_attr : check_attr);
- (void) wprintw(win,
- (data->checkflag == FLAG_CHECK) ? "[%c]" : "(%c)",
- states[item->state]);
- dlg_attrset(win, menubox_attr);
- (void) waddch(win, ' ');
-
- if (both) {
- dlg_print_listitem(win, item->name, climit, first, selected);
- first = FALSE;
- }
-
- (void) wmove(win, choice, data->item_x);
- dlg_print_listitem(win, show, climit, first, selected);
-
- if (selected) {
- dlg_item_help(item->help);
- }
- dlg_attrset(win, save);
-}
-
-static void
-print_list(ALL_DATA * data, int choice, int scrollamt, int max_choice)
-{
- int i;
- int cur_y, cur_x;
-
- getyx(data->dialog, cur_y, cur_x);
- for (i = 0; i < max_choice; i++) {
- print_item(data,
- data->list,
- &data->items[i + scrollamt],
- data->states,
- i, i == choice);
- }
- (void) wnoutrefresh(data->list);
-
- dlg_draw_scrollbar(data->dialog,
- (long) (scrollamt),
- (long) (scrollamt),
- (long) (scrollamt + max_choice),
- (long) (data->item_no),
- data->box_x + data->check_x,
- data->box_x + data->use_width,
- data->box_y,
- data->box_y + data->use_height + 1,
- menubox_border2_attr,
- menubox_border_attr);
-
- (void) wmove(data->dialog, cur_y, cur_x);
-}
-
-static bool
-check_hotkey(DIALOG_LISTITEM * items, int choice)
-{
- bool result = FALSE;
-
- if (dlg_match_char(dlg_last_getc(),
- (dialog_vars.no_tags
- ? items[choice].text
- : items[choice].name))) {
- result = TRUE;
- }
- return result;
-}
-
-/*
- * This is an alternate interface to 'checklist' which allows the application
- * to read the list item states back directly without putting them in the
- * output buffer. It also provides for more than two states over which the
- * check/radio box can display.
- */
-int
-dlg_checklist(const char *title,
- const char *cprompt,
- int height,
- int width,
- int list_height,
- int item_no,
- DIALOG_LISTITEM * items,
- const char *states,
- int flag,
- int *current_item)
-{
- /* *INDENT-OFF* */
- static DLG_KEYS_BINDING binding[] = {
- HELPKEY_BINDINGS,
- ENTERKEY_BINDINGS,
- DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ),
- DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ),
- DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ),
- DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ),
- DLG_KEYS_DATA( DLGK_ITEM_FIRST, KEY_HOME ),
- DLG_KEYS_DATA( DLGK_ITEM_LAST, KEY_END ),
- DLG_KEYS_DATA( DLGK_ITEM_LAST, KEY_LL ),
- DLG_KEYS_DATA( DLGK_ITEM_NEXT, '+' ),
- DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_DOWN ),
- DLG_KEYS_DATA( DLGK_ITEM_NEXT, CHR_NEXT ),
- DLG_KEYS_DATA( DLGK_ITEM_PREV, '-' ),
- DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_UP ),
- DLG_KEYS_DATA( DLGK_ITEM_PREV, CHR_PREVIOUS ),
- DLG_KEYS_DATA( DLGK_PAGE_NEXT, KEY_NPAGE ),
- DLG_KEYS_DATA( DLGK_PAGE_NEXT, DLGK_MOUSE(KEY_NPAGE) ),
- DLG_KEYS_DATA( DLGK_PAGE_PREV, KEY_PPAGE ),
- DLG_KEYS_DATA( DLGK_PAGE_PREV, DLGK_MOUSE(KEY_PPAGE) ),
- TOGGLEKEY_BINDINGS,
- END_KEYS_BINDING
- };
- /* *INDENT-ON* */
-
-#ifdef KEY_RESIZE
- int old_height = height;
- int old_width = width;
-#endif
- ALL_DATA all;
- int i, j, key2, found, x, y, cur_x, cur_y;
- int key, fkey;
- int button = dialog_state.visit_items ? -1 : dlg_default_button();
- int choice = dlg_default_listitem(items);
- int scrollamt = 0;
- int max_choice;
- int use_width, list_width, name_width, text_width;
- int result = DLG_EXIT_UNKNOWN;
- int num_states;
- WINDOW *dialog;
- char *prompt;
- const char **buttons = dlg_ok_labels();
- const char *widget_name;
-
- DLG_TRACE(("# %s args:\n", flag ? "checklist" : "radiolist"));
- DLG_TRACE2S("title", title);
- DLG_TRACE2S("message", cprompt);
- DLG_TRACE2N("height", height);
- DLG_TRACE2N("width", width);
- DLG_TRACE2N("lheight", list_height);
- DLG_TRACE2N("llength", item_no);
- /* FIXME dump the items[][] too */
- DLG_TRACE2S("states", states);
- DLG_TRACE2N("flag", flag);
- DLG_TRACE2N("current", *current_item);
-
- dialog_state.plain_buttons = TRUE;
-
- memset(&all, 0, sizeof(all));
- all.items = items;
- all.item_no = item_no;
-
- dlg_does_output();
-
- /*
- * If this is a radiobutton list, ensure that no more than one item is
- * selected initially. Allow none to be selected, since some users may
- * wish to provide this flavor.
- */
- if (flag == FLAG_RADIO) {
- bool first = TRUE;
-
- for (i = 0; i < item_no; i++) {
- if (items[i].state) {
- if (first) {
- first = FALSE;
- } else {
- items[i].state = 0;
- }
- }
- }
- widget_name = "radiolist";
- } else {
- widget_name = "checklist";
- }
-#ifdef KEY_RESIZE
- retry:
-#endif
-
- prompt = dlg_strclone(cprompt);
- dlg_tab_correct_str(prompt);
-
- all.use_height = list_height;
- use_width = dlg_calc_list_width(item_no, items) + 10;
- use_width = MAX(26, use_width);
- if (all.use_height == 0) {
- /* calculate height without items (4) */
- dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, use_width);
- dlg_calc_listh(&height, &all.use_height, item_no);
- } else {
- dlg_auto_size(title, prompt,
- &height, &width,
- MIN_HIGH + all.use_height, use_width);
- }
- dlg_button_layout(buttons, &width);
- dlg_print_size(height, width);
- dlg_ctl_size(height, width);
-
- /* we need at least two states */
- if (states == 0 || strlen(states) < 2)
- states = " *";
- num_states = (int) strlen(states);
- all.states = states;
-
- all.checkflag = flag;
-
- x = dlg_box_x_ordinate(width);
- y = dlg_box_y_ordinate(height);
-
- dialog = dlg_new_window(height, width, y, x);
- all.dialog = dialog;
- dlg_register_window(dialog, widget_name, binding);
- dlg_register_buttons(dialog, widget_name, buttons);
-
- dlg_mouse_setbase(x, y);
-
- dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr);
- dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
- dlg_draw_title(dialog, title);
-
- dlg_attrset(dialog, dialog_attr);
- dlg_print_autowrap(dialog, prompt, height, width);
-
- all.use_width = width - 6;
- getyx(dialog, cur_y, cur_x);
- all.box_y = cur_y + 1;
- all.box_x = (width - all.use_width) / 2 - 1;
-
- /*
- * After displaying the prompt, we know how much space we really have.
- * Limit the list to avoid overwriting the ok-button.
- */
- if (all.use_height + MIN_HIGH > height - cur_y)
- all.use_height = height - MIN_HIGH - cur_y;
- if (all.use_height <= 0)
- all.use_height = 1;
-
- max_choice = MIN(all.use_height, item_no);
- max_choice = MAX(max_choice, 1);
-
- /* create new window for the list */
- all.list = dlg_sub_window(dialog, all.use_height, all.use_width,
- y + all.box_y + 1, x + all.box_x + 1);
-
- /* draw a box around the list items */
- dlg_draw_box(dialog, all.box_y, all.box_x,
- all.use_height + 2 * MARGIN,
- all.use_width + 2 * MARGIN,
- menubox_border_attr, menubox_border2_attr);
-
- text_width = 0;
- name_width = 0;
- /* Find length of longest item to center checklist */
- for (i = 0; i < item_no; i++) {
- text_width = MAX(text_width, dlg_count_columns(items[i].text));
- name_width = MAX(name_width, dlg_count_columns(items[i].name));
- }
-
- /* If the name+text is wider than the list is allowed, then truncate
- * one or both of them. If the name is no wider than 1/4 of the list,
- * leave it intact.
- */
- use_width = (all.use_width - 6);
- if (dialog_vars.no_tags) {
- list_width = MIN(all.use_width, text_width);
- } else if (dialog_vars.no_items) {
- list_width = MIN(all.use_width, name_width);
- } else {
- if (text_width >= 0
- && name_width >= 0
- && use_width > 0
- && text_width + name_width > use_width) {
- int need = (int) (0.25 * use_width);
- if (name_width > need) {
- int want = (int) (use_width * ((double) name_width) /
- (text_width + name_width));
- name_width = (want > need) ? want : need;
- }
- text_width = use_width - name_width;
- }
- list_width = (text_width + name_width);
- }
-
- all.check_x = (use_width - list_width) / 2;
- all.item_x = ((dialog_vars.no_tags
- ? 0
- : (dialog_vars.no_items
- ? 0
- : (2 + name_width)))
- + all.check_x + 4);
-
- /* ensure we are scrolled to show the current choice */
- scrollamt = MIN(scrollamt, max_choice + item_no - 1);
- if (choice >= (max_choice + scrollamt - 1)) {
- scrollamt = MAX(0, choice - max_choice + 1);
- choice = max_choice - 1;
- }
- print_list(&all, choice, scrollamt, max_choice);
-
- /* register the new window, along with its borders */
- dlg_mouse_mkbigregion(all.box_y + 1, all.box_x,
- all.use_height, all.use_width + 2,
- KEY_MAX, 1, 1, 1 /* by lines */ );
-
- dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width);
-
- dlg_trace_win(dialog);
-
- while (result == DLG_EXIT_UNKNOWN) {
- int was_mouse;
-
- if (button < 0) /* --visit-items */
- wmove(dialog, all.box_y + choice + 1, all.box_x + all.check_x + 2);
-
- key = dlg_mouse_wgetch(dialog, &fkey);
- if (dlg_result_key(key, fkey, &result)) {
- if (!dlg_button_key(result, &button, &key, &fkey))
- break;
- }
-
- was_mouse = (fkey && is_DLGK_MOUSE(key));
- if (was_mouse)
- key -= M_EVENT;
-
- if (was_mouse && (key >= KEY_MAX)) {
- getyx(dialog, cur_y, cur_x);
- i = (key - KEY_MAX);
- if (i < max_choice) {
- choice = (key - KEY_MAX);
- print_list(&all, choice, scrollamt, max_choice);
-
- key = DLGK_TOGGLE; /* force the selected item to toggle */
- } else {
- beep();
- continue;
- }
- fkey = FALSE;
- } else if (was_mouse && key >= KEY_MIN) {
- key = dlg_lookup_key(dialog, key, &fkey);
- }
-
- /*
- * A space toggles the item status. We handle either a checklist
- * (any number of items can be selected) or radio list (zero or one
- * items can be selected).
- */
- if (key == DLGK_TOGGLE) {
- int current = scrollamt + choice;
- int next = items[current].state + 1;
-
- if (next >= num_states)
- next = 0;
-
- if (flag == FLAG_CHECK) { /* checklist? */
- getyx(dialog, cur_y, cur_x);
- items[current].state = next;
- print_item(&all, all.list,
- &items[scrollamt + choice],
- states,
- choice, TRUE);
- (void) wnoutrefresh(all.list);
- (void) wmove(dialog, cur_y, cur_x);
- } else { /* radiolist */
- for (i = 0; i < item_no; i++) {
- if (i != current) {
- items[i].state = 0;
- }
- }
- if (items[current].state) {
- getyx(dialog, cur_y, cur_x);
- items[current].state = next ? next : 1;
- print_item(&all, all.list,
- &items[current],
- states,
- choice, TRUE);
- (void) wnoutrefresh(all.list);
- (void) wmove(dialog, cur_y, cur_x);
- } else {
- items[current].state = 1;
- print_list(&all, choice, scrollamt, max_choice);
- }
- }
- continue; /* wait for another key press */
- }
-
- /*
- * Check if key pressed matches first character of any item tag in
- * list. If there is more than one match, we will cycle through
- * each one as the same key is pressed repeatedly.
- */
- found = FALSE;
- if (!fkey) {
- if (button < 0 || !dialog_state.visit_items) {
- for (j = scrollamt + choice + 1; j < item_no; j++) {
- if (check_hotkey(items, j)) {
- found = TRUE;
- i = j - scrollamt;
- break;
- }
- }
- if (!found) {
- for (j = 0; j <= scrollamt + choice; j++) {
- if (check_hotkey(items, j)) {
- found = TRUE;
- i = j - scrollamt;
- break;
- }
- }
- }
- if (found)
- dlg_flush_getc();
- } else if ((j = dlg_char_to_button(key, buttons)) >= 0) {
- button = j;
- ungetch('\n');
- continue;
- }
- }
-
- /*
- * A single digit (1-9) positions the selection to that line in the
- * current screen.
- */
- if (!found
- && (key <= '9')
- && (key > '0')
- && (key - '1' < max_choice)) {
- found = TRUE;
- i = key - '1';
- }
-
- if (!found) {
- if (fkey) {
- found = TRUE;
- switch (key) {
- case DLGK_ITEM_FIRST:
- i = -scrollamt;
- break;
- case DLGK_ITEM_LAST:
- i = item_no - 1 - scrollamt;
- break;
- case DLGK_PAGE_PREV:
- if (choice)
- i = 0;
- else if (scrollamt != 0)
- i = -MIN(scrollamt, max_choice);
- else
- continue;
- break;
- case DLGK_PAGE_NEXT:
- i = MIN(choice + max_choice, item_no - scrollamt - 1);
- break;
- case DLGK_ITEM_PREV:
- i = choice - 1;
- if (choice == 0 && scrollamt == 0)
- continue;
- break;
- case DLGK_ITEM_NEXT:
- i = choice + 1;
- if (scrollamt + choice >= item_no - 1)
- continue;
- break;
- default:
- found = FALSE;
- break;
- }
- }
- }
-
- if (found) {
- if (i != choice) {
- getyx(dialog, cur_y, cur_x);
- if (i < 0 || i >= max_choice) {
- if (i < 0) {
- scrollamt += i;
- choice = 0;
- } else {
- choice = max_choice - 1;
- scrollamt += (i - max_choice + 1);
- }
- print_list(&all, choice, scrollamt, max_choice);
- } else {
- choice = i;
- print_list(&all, choice, scrollamt, max_choice);
- }
- }
- continue; /* wait for another key press */
- }
-
- if (fkey) {
- switch (key) {
- case DLGK_ENTER:
- result = dlg_enter_buttoncode(button);
- break;
- case DLGK_LEAVE:
- result = dlg_ok_buttoncode(button);
- break;
- case DLGK_FIELD_PREV:
- button = dlg_prev_button(buttons, button);
- dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
- FALSE, width);
- break;
- case DLGK_FIELD_NEXT:
- button = dlg_next_button(buttons, button);
- dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
- FALSE, width);
- break;
-#ifdef KEY_RESIZE
- case KEY_RESIZE:
- dlg_will_resize(dialog);
- /* reset data */
- height = old_height;
- width = old_width;
- free(prompt);
- _dlg_resize_cleanup(dialog);
- /* repaint */
- goto retry;
-#endif
- default:
- if (was_mouse) {
- if ((key2 = dlg_ok_buttoncode(key)) >= 0) {
- result = key2;
- break;
- }
- beep();
- }
- }
- } else if (key > 0) {
- beep();
- }
- }
-
- dlg_del_window(dialog);
- dlg_mouse_free_regions();
- free(prompt);
- *current_item = (scrollamt + choice);
- return result;
-}
-
-/*
- * Display a dialog box with a list of options that can be turned on or off
- * The `flag' parameter is used to select between radiolist and checklist.
- */
-int
-dialog_checklist(const char *title,
- const char *cprompt,
- int height,
- int width,
- int list_height,
- int item_no,
- char **items,
- int flag)
-{
- int result;
- int i, j;
- DIALOG_LISTITEM *listitems;
- bool separate_output = ((flag == FLAG_CHECK)
- && (dialog_vars.separate_output));
- bool show_status = FALSE;
- int current = 0;
- char *help_result;
-
- listitems = dlg_calloc(DIALOG_LISTITEM, (size_t) item_no + 1);
- assert_ptr(listitems, "dialog_checklist");
-
- for (i = j = 0; i < item_no; ++i) {
- listitems[i].name = items[j++];
- listitems[i].text = (dialog_vars.no_items
- ? dlg_strempty()
- : items[j++]);
- listitems[i].state = !dlg_strcmp(items[j++], "on");
- listitems[i].help = ((dialog_vars.item_help)
- ? items[j++]
- : dlg_strempty());
- }
- dlg_align_columns(&listitems[0].text, (int) sizeof(DIALOG_LISTITEM), item_no);
-
- result = dlg_checklist(title,
- cprompt,
- height,
- width,
- list_height,
- item_no,
- listitems,
- NULL,
- flag,
- ¤t);
-
- switch (result) {
- case DLG_EXIT_OK: /* FALLTHRU */
- case DLG_EXIT_EXTRA:
- show_status = TRUE;
- break;
- case DLG_EXIT_HELP:
- dlg_add_help_listitem(&result, &help_result, &listitems[current]);
- if ((show_status = dialog_vars.help_status)) {
- if (separate_output) {
- dlg_add_string(help_result);
- dlg_add_separator();
- } else {
- dlg_add_quoted(help_result);
- }
- } else {
- dlg_add_string(help_result);
- }
- break;
- }
-
- if (show_status) {
- for (i = 0; i < item_no; i++) {
- if (listitems[i].state) {
- if (separate_output) {
- dlg_add_string(listitems[i].name);
- dlg_add_separator();
- } else {
- if (dlg_need_separator())
- dlg_add_separator();
- if (flag == FLAG_CHECK)
- dlg_add_quoted(listitems[i].name);
- else
- dlg_add_string(listitems[i].name);
- }
- }
- }
- dlg_add_last_key(separate_output);
- }
-
- dlg_free_columns(&listitems[0].text, (int) sizeof(DIALOG_LISTITEM), item_no);
- free(listitems);
- return result;
-}
Index: sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/fselect.c
===================================================================
--- sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/fselect.c (revision 33)
+++ sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/fselect.c (nonexistent)
@@ -1,971 +0,0 @@
-/*
- * $Id: fselect.c,v 1.117 2021/06/21 19:50:35 tom Exp $
- *
- * fselect.c -- implements the file-selector box
- *
- * Copyright 2000-2020,2021 Thomas E. Dickey
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License, version 2.1
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to
- * Free Software Foundation, Inc.
- * 51 Franklin St., Fifth Floor
- * Boston, MA 02110, USA.
- */
-
-#include <dlg_internals.h>
-#include <dlg_keys.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#if HAVE_DIRENT_H
-# include <dirent.h>
-# define NAMLEN(dirent) strlen((dirent)->d_name)
-#else
-# define dirent direct
-# define NAMLEN(dirent) (dirent)->d_namlen
-# if HAVE_SYS_NDIR_H
-# include <sys/ndir.h>
-# endif
-# if HAVE_SYS_DIR_H
-# include <sys/dir.h>
-# endif
-# if HAVE_NDIR_H
-# include <ndir.h>
-# endif
-#endif
-
-# if defined(_FILE_OFFSET_BITS) && defined(HAVE_STRUCT_DIRENT64)
-# if !defined(_LP64) && (_FILE_OFFSET_BITS == 64)
-# define DIRENT struct dirent64
-# else
-# define DIRENT struct dirent
-# endif
-# else
-# define DIRENT struct dirent
-# endif
-
-#define EXT_WIDE 1
-#define HDR_HIGH 1
-#define BTN_HIGH (1 + 2 * MARGIN) /* Ok/Cancel, also input-box */
-#define MIN_HIGH (HDR_HIGH - MARGIN + (BTN_HIGH * 2) + 4 * MARGIN)
-#define MIN_WIDE (2 * MAX(dlg_count_columns(d_label), dlg_count_columns(f_label)) + 6 * MARGIN + 2 * EXT_WIDE)
-
-#define MOUSE_D (KEY_MAX + 0)
-#define MOUSE_F (KEY_MAX + 10000)
-#define MOUSE_T (KEY_MAX + 20000)
-
-typedef enum {
- sDIRS = -3
- ,sFILES = -2
- ,sTEXT = -1
-} STATES;
-
-typedef struct {
- WINDOW *par; /* parent window */
- WINDOW *win; /* this window */
- int length; /* length of the data[] array */
- int offset; /* index of first item on screen */
- int choice; /* index of the selection */
- int mousex; /* base of mouse-code return-values */
- unsigned allocd;
- char **data;
-} LIST;
-
-typedef struct {
- int length;
- char **data;
-} MATCH;
-
-static void
-init_list(LIST * list, WINDOW *par, WINDOW *win, int mousex)
-{
- list->par = par;
- list->win = win;
- list->length = 0;
- list->offset = 0;
- list->choice = 0;
- list->mousex = mousex;
- list->allocd = 0;
- list->data = 0;
- dlg_mouse_mkbigregion(getbegy(win), getbegx(win),
- getmaxy(win), getmaxx(win),
- mousex, 1, 1, 1 /* by lines */ );
-}
-
-static char *
-leaf_of(char *path)
-{
- char *leaf = strrchr(path, '/');
- if (leaf != 0)
- leaf++;
- else
- leaf = path;
- return leaf;
-}
-
-static char *
-data_of(LIST * list)
-{
- if (list != 0
- && list->data != 0)
- return list->data[list->choice];
- return 0;
-}
-
-static void
-free_list(LIST * list, int reinit)
-{
- if (list->data != 0) {
- int n;
-
- for (n = 0; list->data[n] != 0; n++)
- free(list->data[n]);
- free(list->data);
- list->data = 0;
- }
- if (reinit)
- init_list(list, list->par, list->win, list->mousex);
-}
-
-static void
-add_to_list(LIST * list, char *text)
-{
- unsigned need;
-
- need = (unsigned) (list->length + 1);
- if (need + 1 > list->allocd) {
- list->allocd = 2 * (need + 1);
- if (list->data == 0) {
- list->data = dlg_malloc(char *, list->allocd);
- } else {
- list->data = dlg_realloc(char *, list->allocd, list->data);
- }
- assert_ptr(list->data, "add_to_list");
- }
- list->data[list->length++] = dlg_strclone(text);
- list->data[list->length] = 0;
-}
-
-static void
-keep_visible(LIST * list)
-{
- int high = getmaxy(list->win);
-
- if (list->choice < list->offset) {
- list->offset = list->choice;
- }
- if (list->choice - list->offset >= high)
- list->offset = list->choice - high + 1;
-}
-
-#define Value(c) (int)((c) & 0xff)
-
-static int
-find_choice(char *target, LIST * list)
-{
- int choice = list->choice;
-
- if (*target == 0) {
- list->choice = 0;
- } else {
- int n;
- int len_1, cmp_1;
-
- /* find the match with the longest length. If more than one has the
- * same length, choose the one with the closest match of the final
- * character.
- */
- len_1 = 0;
- cmp_1 = 256;
- for (n = 0; n < list->length; n++) {
- char *a = target;
- char *b = list->data[n];
- int len_2, cmp_2;
-
- len_2 = 0;
- while ((*a != 0) && (*b != 0) && (*a == *b)) {
- a++;
- b++;
- len_2++;
- }
- cmp_2 = Value(*a) - Value(*b);
- if (cmp_2 < 0)
- cmp_2 = -cmp_2;
- if ((len_2 > len_1)
- || (len_1 == len_2 && cmp_2 < cmp_1)) {
- len_1 = len_2;
- cmp_1 = cmp_2;
- list->choice = n;
- }
- }
- }
- if (choice != list->choice) {
- keep_visible(list);
- }
- return (choice != list->choice);
-}
-
-static void
-display_list(LIST * list)
-{
- if (list->win != 0) {
- int n;
- int x;
- int y;
- int top;
- int bottom;
-
- dlg_attr_clear(list->win, getmaxy(list->win), getmaxx(list->win), item_attr);
- for (n = list->offset; n < list->length && list->data[n]; n++) {
- y = n - list->offset;
- if (y >= getmaxy(list->win))
- break;
- (void) wmove(list->win, y, 0);
- if (n == list->choice)
- dlg_attrset(list->win, item_selected_attr);
- (void) waddstr(list->win, list->data[n]);
- dlg_attrset(list->win, item_attr);
- }
- dlg_attrset(list->win, item_attr);
-
- getparyx(list->win, y, x);
-
- top = y - 1;
- bottom = y + getmaxy(list->win);
- dlg_draw_scrollbar(list->par,
- (long) list->offset,
- (long) list->offset,
- (long) (list->offset + getmaxy(list->win)),
- (long) (list->length),
- x + 1,
- x + getmaxx(list->win),
- top,
- bottom,
- menubox_border2_attr,
- menubox_border_attr);
-
- (void) wmove(list->win, list->choice - list->offset, 0);
- (void) wnoutrefresh(list->win);
- }
-}
-
-/* FIXME: see arrows.c
- * This workaround is used to allow two lists to have scroll-tabs at the same
- * time, by reassigning their return-values to be different. Just for
- * readability, we use the names of keys with similar connotations, though all
- * that is really required is that they're distinct, so we can put them in a
- * switch statement.
- */
-#if USE_MOUSE
-static void
-fix_arrows(LIST * list)
-{
- if (list->win != 0) {
- int x;
- int y;
- int top;
- int right;
- int bottom;
-
- getparyx(list->win, y, x);
- top = y - 1;
- right = getmaxx(list->win);
- bottom = y + getmaxy(list->win);
-
- mouse_mkbutton(top, x, right,
- ((list->mousex == MOUSE_D)
- ? KEY_PREVIOUS
- : KEY_PPAGE));
- mouse_mkbutton(bottom, x, right,
- ((list->mousex == MOUSE_D)
- ? KEY_NEXT
- : KEY_NPAGE));
- }
-}
-
-#else
-#define fix_arrows(list) /* nothing */
-#endif
-
-static bool
-show_list(char *target, LIST * list, bool keep)
-{
- bool changed = keep || find_choice(target, list);
- display_list(list);
- return changed;
-}
-
-/*
- * Highlight the closest match to 'target' in the given list, setting offset
- * to match.
- */
-static bool
-show_both_lists(char *input, LIST * d_list, LIST * f_list, bool keep)
-{
- char *leaf = leaf_of(input);
-
- return show_list(leaf, d_list, keep) || show_list(leaf, f_list, keep);
-}
-
-/*
- * Move up/down in the given list
- */
-static bool
-change_list(int choice, LIST * list)
-{
- if (data_of(list) != 0) {
- int last = list->length - 1;
-
- choice += list->choice;
- if (choice < 0)
- choice = 0;
- if (choice > last)
- choice = last;
- list->choice = choice;
- keep_visible(list);
- display_list(list);
- return TRUE;
- }
- return FALSE;
-}
-
-static void
-scroll_list(int direction, LIST * list)
-{
- if (data_of(list) != 0) {
- int length = getmaxy(list->win);
- if (change_list(direction * length, list))
- return;
- }
- beep();
-}
-
-static int
-compar(const void *a, const void *b)
-{
- return strcmp(*(const char *const *) a, *(const char *const *) b);
-}
-
-static void
-match(char *name, LIST * d_list, LIST * f_list, MATCH * match_list)
-{
- char *test = leaf_of(name);
- size_t test_len = strlen(test);
- char **matches = dlg_malloc(char *, (size_t) (d_list->length + f_list->length));
- size_t data_len = 0;
-
- if (matches != 0) {
- int i;
- char **new_ptr;
-
- for (i = 2; i < d_list->length; i++) {
- if (strncmp(test, d_list->data[i], test_len) == 0) {
- matches[data_len++] = d_list->data[i];
- }
- }
- for (i = 0; i < f_list->length; i++) {
- if (strncmp(test, f_list->data[i], test_len) == 0) {
- matches[data_len++] = f_list->data[i];
- }
- }
- if ((new_ptr = dlg_realloc(char *, data_len + 1, matches)) != 0) {
- matches = new_ptr;
- } else {
- free(matches);
- matches = 0;
- data_len = 0;
- }
- }
- match_list->data = matches;
- match_list->length = (int) data_len;
-}
-
-static void
-free_match(MATCH * match_list)
-{
- free(match_list->data);
- match_list->length = 0;
-}
-
-static int
-complete(char *name, LIST * d_list, LIST * f_list, char **buff_ptr)
-{
- MATCH match_list;
- char *test;
- size_t test_len;
- size_t i;
- char *buff;
-
- match(name, d_list, f_list, &match_list);
- if (match_list.length == 0) {
- free(match_list.data);
- *buff_ptr = NULL;
- return 0;
- }
-
- test = match_list.data[0];
- test_len = strlen(test);
- buff = dlg_malloc(char, test_len + 2);
- if (match_list.length == 1) {
- strcpy(buff, test);
- i = test_len;
- if (test == data_of(d_list)) {
- buff[test_len] = '/';
- i++;
- }
- } else {
- int j;
- char *next;
-
- for (i = 0; i < test_len; i++) {
- char test_char = test[i];
- if (test_char == '\0')
- break;
- for (j = 0; j < match_list.length; j++) {
- if (match_list.data[j][i] != test_char) {
- break;
- }
- }
- if (j == match_list.length) {
- (buff)[i] = test_char;
- } else
- break;
- }
- next = dlg_realloc(char, i + 1, buff);
- if (next == NULL) {
- free(buff);
- *buff_ptr = NULL;
- return 0;
- }
- buff = next;
- }
- free_match(&match_list);
- buff[i] = '\0';
- *buff_ptr = buff;
- return (i != 0);
-}
-
-static bool
-fill_lists(char *current, char *input, LIST * d_list, LIST * f_list, bool keep)
-{
- bool result = TRUE;
- bool rescan = FALSE;
- struct stat sb;
- int n;
- char path[MAX_LEN + 1];
-
- /* check if we've updated the lists */
- for (n = 0; current[n] && input[n]; n++) {
- if (current[n] != input[n])
- break;
- }
-
- if (current[n] == input[n]) {
- result = FALSE;
- rescan = (n == 0 && d_list->length == 0);
- } else if (strchr(current + n, '/') == 0
- && strchr(input + n, '/') == 0) {
- result = show_both_lists(input, d_list, f_list, keep);
- } else {
- rescan = TRUE;
- }
-
- if (rescan) {
- DIR *dp;
- size_t have = strlen(input);
- char *leaf;
-
- if (have > MAX_LEN)
- have = MAX_LEN;
- memcpy(current, input, have);
- current[have] = '\0';
-
- /* refill the lists */
- free_list(d_list, TRUE);
- free_list(f_list, TRUE);
- memcpy(path, current, have);
- path[have] = '\0';
- if ((leaf = strrchr(path, '/')) != 0) {
- *++leaf = 0;
- } else {
- strcpy(path, "./");
- leaf = path + strlen(path);
- }
- DLG_TRACE(("opendir '%s'\n", path));
- if ((dp = opendir(path)) != 0) {
- DIRENT *de;
-
- while ((de = readdir(dp)) != 0) {
- size_t len = NAMLEN(de);
- if (len == 0 || (len + have + 2) >= MAX_LEN)
- continue;
- memcpy(leaf, de->d_name, len);
- leaf[len] = '\0';
- if (stat(path, &sb) == 0) {
- if ((sb.st_mode & S_IFMT) == S_IFDIR)
- add_to_list(d_list, leaf);
- else if (f_list->win)
- add_to_list(f_list, leaf);
- }
- }
- (void) closedir(dp);
- /* sort the lists */
- if (d_list->data != 0 && d_list->length > 1) {
- qsort(d_list->data,
- (size_t) d_list->length,
- sizeof(d_list->data[0]),
- compar);
- }
- if (f_list->data != 0 && f_list->length > 1) {
- qsort(f_list->data,
- (size_t) f_list->length,
- sizeof(f_list->data[0]),
- compar);
- }
- }
-
- (void) show_both_lists(input, d_list, f_list, FALSE);
- d_list->offset = d_list->choice;
- f_list->offset = f_list->choice;
- result = TRUE;
- }
- return result;
-}
-
-static bool
-usable_state(int state, LIST * dirs, LIST * files)
-{
- bool result;
-
- switch (state) {
- case sDIRS:
- result = (dirs->win != 0) && (data_of(dirs) != 0);
- break;
- case sFILES:
- result = (files->win != 0) && (data_of(files) != 0);
- break;
- default:
- result = TRUE;
- break;
- }
- return result;
-}
-
-#define which_list() ((state == sFILES) \
- ? &f_list \
- : ((state == sDIRS) \
- ? &d_list \
- : 0))
-#define NAVIGATE_BINDINGS \
- DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ), \
- DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ), \
- DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ), \
- DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_DOWN ), \
- DLG_KEYS_DATA( DLGK_ITEM_NEXT, CHR_NEXT ), \
- DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_NEXT ), \
- DLG_KEYS_DATA( DLGK_ITEM_PREV, CHR_PREVIOUS ), \
- DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_UP ), \
- DLG_KEYS_DATA( DLGK_PAGE_NEXT, KEY_NPAGE ), \
- DLG_KEYS_DATA( DLGK_PAGE_PREV, KEY_PPAGE )
-
-/*
- * Display a dialog box for entering a filename
- */
-static int
-dlg_fselect(const char *title, const char *path, int height, int width, int dselect)
-{
- /* *INDENT-OFF* */
- static DLG_KEYS_BINDING binding[] = {
- HELPKEY_BINDINGS,
- ENTERKEY_BINDINGS,
- NAVIGATE_BINDINGS,
- TOGGLEKEY_BINDINGS,
- END_KEYS_BINDING
- };
- static DLG_KEYS_BINDING binding2[] = {
- INPUTSTR_BINDINGS,
- HELPKEY_BINDINGS,
- ENTERKEY_BINDINGS,
- NAVIGATE_BINDINGS,
- TOGGLEKEY_BINDINGS,
- END_KEYS_BINDING
- };
- /* *INDENT-ON* */
-
-#ifdef KEY_RESIZE
- int old_height = height;
- int old_width = width;
- bool resized = FALSE;
-#endif
- int tbox_y, tbox_x, tbox_width, tbox_height;
- int dbox_y, dbox_x, dbox_width, dbox_height;
- int fbox_y, fbox_x, fbox_width, fbox_height;
- int show_buttons = TRUE;
- int offset = 0;
- int key = 0;
- int fkey = FALSE;
- int code;
- int result = DLG_EXIT_UNKNOWN;
- int state = dialog_vars.default_button >= 0 ? dlg_default_button() : sTEXT;
- int button;
- bool first = (state == sTEXT);
- bool first_trace = TRUE;
- char *input;
- char *completed;
- char current[MAX_LEN + 1];
- WINDOW *dialog = 0;
- WINDOW *w_text = 0;
- WINDOW *w_work = 0;
- const char **buttons = dlg_ok_labels();
- const char *d_label = _("Directories");
- const char *f_label = _("Files");
- char *partial = 0;
- int min_wide = MIN_WIDE;
- int min_items = height ? 0 : 4;
- LIST d_list, f_list;
-
- DLG_TRACE(("# %s args:\n", dselect ? "dselect" : "fselect"));
- DLG_TRACE2S("title", title);
- DLG_TRACE2S("path", path);
- DLG_TRACE2N("height", height);
- DLG_TRACE2N("width", width);
-
- dlg_does_output();
-
- /* Set up the initial value */
- input = dlg_set_result(path);
- offset = (int) strlen(input);
- *current = 0;
-
- dlg_button_layout(buttons, &min_wide);
-
-#ifdef KEY_RESIZE
- retry:
-#endif
- if (height > 0)
- height += MIN_HIGH;
- dlg_auto_size(title, "", &height, &width, MIN_HIGH + min_items, min_wide);
-
- dlg_print_size(height, width);
- dlg_ctl_size(height, width);
-
- dialog = dlg_new_window(height + 1, width,
- dlg_box_y_ordinate(height),
- dlg_box_x_ordinate(width));
- dlg_register_window(dialog, "fselect", binding);
- dlg_register_buttons(dialog, "fselect", buttons);
-
- dlg_mouse_setbase(0, 0);
-
- dlg_draw_box2(dialog, 0, 0, height + 1, width, dialog_attr, border_attr, border2_attr);
- dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
- dlg_draw_title(dialog, title);
-
- dlg_attrset(dialog, dialog_attr);
-
- /* Draw the input field box */
- tbox_height = 1;
- tbox_width = width - (4 * MARGIN + 2);
- tbox_y = height - (BTN_HIGH * 2) + MARGIN + 1;
- tbox_x = (width - tbox_width) / 2;
-
- w_text = dlg_der_window(dialog, tbox_height, tbox_width, tbox_y, tbox_x);
- if (w_text == 0) {
- result = DLG_EXIT_ERROR;
- goto finish;
- }
-
- dlg_draw_box(dialog, tbox_y - MARGIN, tbox_x - MARGIN,
- (2 * MARGIN + 1), tbox_width + (MARGIN + EXT_WIDE),
- menubox_border_attr, menubox_border2_attr);
- dlg_mouse_mkbigregion(getbegy(dialog) + tbox_y - MARGIN,
- getbegx(dialog) + tbox_x - MARGIN,
- 1 + (2 * MARGIN),
- tbox_width + (MARGIN + EXT_WIDE),
- MOUSE_T, 1, 1, 3 /* doesn't matter */ );
-
- dlg_register_window(w_text, "fselect2", binding2);
-
- /* Draw the directory listing box */
- if (dselect)
- dbox_width = (width - (6 * MARGIN));
- else
- dbox_width = (width - (6 * MARGIN + 2 * EXT_WIDE)) / 2;
- dbox_height = height - MIN_HIGH;
- dbox_y = (2 * MARGIN + 2);
- dbox_x = tbox_x;
-
- w_work = dlg_der_window(dialog, dbox_height, dbox_width, dbox_y, dbox_x);
- if (w_work == 0) {
- result = DLG_EXIT_ERROR;
- goto finish;
- }
-
- (void) mvwaddstr(dialog, dbox_y - (MARGIN + 1), dbox_x - MARGIN, d_label);
- dlg_draw_box(dialog,
- dbox_y - MARGIN, dbox_x - MARGIN,
- dbox_height + (MARGIN + 1), dbox_width + (MARGIN + 1),
- menubox_border_attr, menubox_border2_attr);
- init_list(&d_list, dialog, w_work, MOUSE_D);
-
- if (!dselect) {
- /* Draw the filename listing box */
- fbox_height = dbox_height;
- fbox_width = dbox_width;
- fbox_y = dbox_y;
- fbox_x = tbox_x + dbox_width + (2 * MARGIN);
-
- w_work = dlg_der_window(dialog, fbox_height, fbox_width, fbox_y, fbox_x);
- if (w_work == 0) {
- result = DLG_EXIT_ERROR;
- goto finish;
- }
-
- (void) mvwaddstr(dialog, fbox_y - (MARGIN + 1), fbox_x - MARGIN, f_label);
- dlg_draw_box(dialog,
- fbox_y - MARGIN, fbox_x - MARGIN,
- fbox_height + (MARGIN + 1), fbox_width + (MARGIN + 1),
- menubox_border_attr, menubox_border2_attr);
- init_list(&f_list, dialog, w_work, MOUSE_F);
- } else {
- memset(&f_list, 0, sizeof(f_list));
- }
-
- while (result == DLG_EXIT_UNKNOWN) {
-
- if (fill_lists(current, input, &d_list, &f_list, state < sTEXT))
- show_buttons = TRUE;
-
-#ifdef KEY_RESIZE
- if (resized) {
- resized = FALSE;
- dlg_show_string(w_text, input, offset, inputbox_attr,
- 0, 0, tbox_width, FALSE, first);
- }
-#endif
-
- /*
- * The last field drawn determines where the cursor is shown:
- */
- if (show_buttons) {
- show_buttons = FALSE;
- button = (state < 0) ? 0 : state;
- dlg_draw_buttons(dialog, height - 1, 0, buttons, button, FALSE, width);
- }
-
- if (first_trace) {
- first_trace = FALSE;
- dlg_trace_win(dialog);
- }
-
- if (state < 0) {
- switch (state) {
- case sTEXT:
- dlg_set_focus(dialog, w_text);
- break;
- case sFILES:
- dlg_set_focus(dialog, f_list.win);
- break;
- case sDIRS:
- dlg_set_focus(dialog, d_list.win);
- break;
- }
- }
-
- if (first) {
- (void) wrefresh(dialog);
- } else {
- fix_arrows(&d_list);
- fix_arrows(&f_list);
- key = dlg_mouse_wgetch((state == sTEXT) ? w_text : dialog, &fkey);
- if (dlg_result_key(key, fkey, &result)) {
- if (!dlg_button_key(result, &button, &key, &fkey))
- break;
- }
- }
-
- if (key == DLGK_TOGGLE) {
- key = DLGK_SELECT;
- fkey = TRUE;
- }
-
- if (fkey) {
- switch (key) {
- case DLGK_MOUSE(KEY_PREVIOUS):
- state = sDIRS;
- scroll_list(-1, which_list());
- continue;
- case DLGK_MOUSE(KEY_NEXT):
- state = sDIRS;
- scroll_list(1, which_list());
- continue;
- case DLGK_MOUSE(KEY_PPAGE):
- state = sFILES;
- scroll_list(-1, which_list());
- continue;
- case DLGK_MOUSE(KEY_NPAGE):
- state = sFILES;
- scroll_list(1, which_list());
- continue;
- case DLGK_PAGE_PREV:
- scroll_list(-1, which_list());
- continue;
- case DLGK_PAGE_NEXT:
- scroll_list(1, which_list());
- continue;
- case DLGK_ITEM_PREV:
- if (change_list(-1, which_list()))
- continue;
- /* FALLTHRU */
- case DLGK_FIELD_PREV:
- show_buttons = TRUE;
- do {
- state = dlg_prev_ok_buttonindex(state, sDIRS);
- } while (!usable_state(state, &d_list, &f_list));
- continue;
- case DLGK_ITEM_NEXT:
- if (change_list(1, which_list()))
- continue;
- /* FALLTHRU */
- case DLGK_FIELD_NEXT:
- show_buttons = TRUE;
- do {
- state = dlg_next_ok_buttonindex(state, sDIRS);
- } while (!usable_state(state, &d_list, &f_list));
- continue;
- case DLGK_SELECT:
- completed = 0;
- if (partial != 0) {
- free(partial);
- partial = 0;
- }
- if (state == sFILES && !dselect) {
- completed = data_of(&f_list);
- } else if (state == sDIRS) {
- completed = data_of(&d_list);
- } else {
- if (complete(input, &d_list, &f_list, &partial)) {
- completed = partial;
- }
- }
- if (completed != 0) {
- state = sTEXT;
- show_buttons = TRUE;
- strcpy(leaf_of(input), completed);
- offset = (int) strlen(input);
- dlg_show_string(w_text, input, offset, inputbox_attr,
- 0, 0, tbox_width, 0, first);
- if (partial != NULL) {
- free(partial);
- partial = 0;
- }
- continue;
- } else { /* if (state < sTEXT) */
- (void) beep();
- continue;
- }
- /* FALLTHRU */
- case DLGK_ENTER:
- result = (state > 0) ? dlg_enter_buttoncode(state) : DLG_EXIT_OK;
- continue;
- case DLGK_LEAVE:
- if (state >= 0)
- result = dlg_ok_buttoncode(state);
- break;
-#ifdef KEY_RESIZE
- case KEY_RESIZE:
- dlg_will_resize(dialog);
- /* reset data */
- height = old_height;
- width = old_width;
- show_buttons = TRUE;
- *current = 0;
- resized = TRUE;
- /* repaint */
- free_list(&d_list, FALSE);
- free_list(&f_list, FALSE);
- _dlg_resize_cleanup(dialog);
- goto retry;
-#endif
- default:
- if (key >= DLGK_MOUSE(MOUSE_T)) {
- state = sTEXT;
- continue;
- } else if (key >= DLGK_MOUSE(MOUSE_F)) {
- if (f_list.win != 0) {
- state = sFILES;
- f_list.choice = (key - DLGK_MOUSE(MOUSE_F)) + f_list.offset;
- display_list(&f_list);
- }
- continue;
- } else if (key >= DLGK_MOUSE(MOUSE_D)) {
- if (d_list.win != 0) {
- state = sDIRS;
- d_list.choice = (key - DLGK_MOUSE(MOUSE_D)) + d_list.offset;
- display_list(&d_list);
- }
- continue;
- } else if (is_DLGK_MOUSE(key)
- && (code = dlg_ok_buttoncode(key - M_EVENT)) >= 0) {
- result = code;
- continue;
- }
- break;
- }
- }
-
- if (state < 0) { /* Input box selected if we're editing */
- int edit = dlg_edit_string(input, &offset, key, fkey, first);
-
- if (edit) {
- dlg_show_string(w_text, input, offset, inputbox_attr,
- 0, 0, tbox_width, 0, first);
- first = FALSE;
- state = sTEXT;
- }
- } else if ((code = dlg_char_to_button(key, buttons)) >= 0) {
- result = dlg_ok_buttoncode(code);
- break;
- }
- }
- AddLastKey();
-
- dlg_unregister_window(w_text);
- dlg_del_window(dialog);
- dlg_mouse_free_regions();
- free_list(&d_list, FALSE);
- free_list(&f_list, FALSE);
-
- finish:
- if (partial != 0)
- free(partial);
- return result;
-}
-
-/*
- * Display a dialog box for entering a filename
- */
-int
-dialog_fselect(const char *title, const char *path, int height, int width)
-{
- return dlg_fselect(title, path, height, width, FALSE);
-}
-
-/*
- * Display a dialog box for entering a directory
- */
-int
-dialog_dselect(const char *title, const char *path, int height, int width)
-{
- return dlg_fselect(title, path, height, width, TRUE);
-}
Index: sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/util.c
===================================================================
--- sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/util.c (revision 33)
+++ sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/util.c (nonexistent)
@@ -1,3031 +0,0 @@
-/*
- * $Id: util.c,v 1.303 2021/06/15 00:10:11 tom Exp $
- *
- * util.c -- miscellaneous utilities for dialog
- *
- * Copyright 2000-2020,2021 Thomas E. Dickey
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License, version 2.1
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to
- * Free Software Foundation, Inc.
- * 51 Franklin St., Fifth Floor
- * Boston, MA 02110, USA.
- *
- * An earlier version of this program lists as authors
- * Savio Lam (lam836@cs.cuhk.hk)
- */
-
-#include <dialog.h>
-#include <dlg_keys.h>
-#include <dlg_internals.h>
-
-#include <sys/time.h>
-
-#ifdef HAVE_SETLOCALE
-#include <locale.h>
-#endif
-
-#ifdef NEED_WCHAR_H
-#include <wchar.h>
-#endif
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
-#if defined(NCURSES_VERSION)
-#define CAN_KEEP_TITE 1
-#elif defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 800000000)
-#define CAN_KEEP_TITE 1
-#else
-#define CAN_KEEP_TITE 0
-#endif
-
-#if CAN_KEEP_TITE
-#if defined(NCURSES_VERSION) && defined(HAVE_NCURSESW_TERM_H)
-#include <ncursesw/term.h>
-#elif defined(NCURSES_VERSION) && defined(HAVE_NCURSES_TERM_H)
-#include <ncurses/term.h>
-#else
-#include <term.h>
-#endif
-#endif
-
-#if defined(HAVE_WCHGAT)
-# if defined(NCURSES_VERSION_PATCH)
-# if NCURSES_VERSION_PATCH >= 20060715
-# define USE_WCHGAT 1
-# else
-# define USE_WCHGAT 0
-# endif
-# else
-# define USE_WCHGAT 1
-# endif
-#else
-# define USE_WCHGAT 0
-#endif
-
-/* globals */
-DIALOG_STATE dialog_state;
-DIALOG_VARS dialog_vars;
-
-#if !(defined(HAVE_WGETPARENT) && defined(HAVE_WINDOW__PARENT))
-#define NEED_WGETPARENT 1
-#else
-#undef NEED_WGETPARENT
-#endif
-
-#define concat(a,b) a##b
-
-#ifdef HAVE_RC_FILE
-#define RC_DATA(name,comment) , #name "_color", comment " color"
-#else
-#define RC_DATA(name,comment) /*nothing */
-#endif
-
-#ifdef HAVE_COLOR
-#include <dlg_colors.h>
-#ifdef HAVE_RC_FILE2
-#define COLOR_DATA(upr) , \
- concat(DLGC_FG_,upr), \
- concat(DLGC_BG_,upr), \
- concat(DLGC_HL_,upr), \
- concat(DLGC_UL_,upr), \
- concat(DLGC_RV_,upr)
-#else /* HAVE_RC_FILE2 */
-#define COLOR_DATA(upr) , \
- concat(DLGC_FG_,upr), \
- concat(DLGC_BG_,upr), \
- concat(DLGC_HL_,upr)
-#endif /* HAVE_RC_FILE2 */
-#else /* HAVE_COLOR */
-#define COLOR_DATA(upr) /*nothing */
-#endif /* HAVE_COLOR */
-
-#define UseShadow(dw) ((dw) != 0 && (dw)->normal != 0 && (dw)->shadow != 0)
-
-/*
- * Table of color and attribute values, default is for mono display.
- * The order matches the DIALOG_ATR() values.
- */
-#define DATA(atr,upr,lwr,cmt) { atr COLOR_DATA(upr) RC_DATA(lwr,cmt) }
-/* *INDENT-OFF* */
-DIALOG_COLORS dlg_color_table[] =
-{
- DATA(A_NORMAL, SCREEN, screen, "Screen"),
- DATA(A_NORMAL, SHADOW, shadow, "Shadow"),
- DATA(A_REVERSE, DIALOG, dialog, "Dialog box"),
- DATA(A_REVERSE, TITLE, title, "Dialog box title"),
- DATA(A_REVERSE, BORDER, border, "Dialog box border"),
- DATA(A_BOLD, BUTTON_ACTIVE, button_active, "Active button"),
- DATA(A_DIM, BUTTON_INACTIVE, button_inactive, "Inactive button"),
- DATA(A_UNDERLINE, BUTTON_KEY_ACTIVE, button_key_active, "Active button key"),
- DATA(A_UNDERLINE, BUTTON_KEY_INACTIVE, button_key_inactive, "Inactive button key"),
- DATA(A_NORMAL, BUTTON_LABEL_ACTIVE, button_label_active, "Active button label"),
- DATA(A_NORMAL, BUTTON_LABEL_INACTIVE, button_label_inactive, "Inactive button label"),
- DATA(A_REVERSE, INPUTBOX, inputbox, "Input box"),
- DATA(A_REVERSE, INPUTBOX_BORDER, inputbox_border, "Input box border"),
- DATA(A_REVERSE, SEARCHBOX, searchbox, "Search box"),
- DATA(A_REVERSE, SEARCHBOX_TITLE, searchbox_title, "Search box title"),
- DATA(A_REVERSE, SEARCHBOX_BORDER, searchbox_border, "Search box border"),
- DATA(A_REVERSE, POSITION_INDICATOR, position_indicator, "File position indicator"),
- DATA(A_REVERSE, MENUBOX, menubox, "Menu box"),
- DATA(A_REVERSE, MENUBOX_BORDER, menubox_border, "Menu box border"),
- DATA(A_REVERSE, ITEM, item, "Item"),
- DATA(A_NORMAL, ITEM_SELECTED, item_selected, "Selected item"),
- DATA(A_REVERSE, TAG, tag, "Tag"),
- DATA(A_REVERSE, TAG_SELECTED, tag_selected, "Selected tag"),
- DATA(A_NORMAL, TAG_KEY, tag_key, "Tag key"),
- DATA(A_BOLD, TAG_KEY_SELECTED, tag_key_selected, "Selected tag key"),
- DATA(A_REVERSE, CHECK, check, "Check box"),
- DATA(A_REVERSE, CHECK_SELECTED, check_selected, "Selected check box"),
- DATA(A_REVERSE, UARROW, uarrow, "Up arrow"),
- DATA(A_REVERSE, DARROW, darrow, "Down arrow"),
- DATA(A_NORMAL, ITEMHELP, itemhelp, "Item help-text"),
- DATA(A_BOLD, FORM_ACTIVE_TEXT, form_active_text, "Active form text"),
- DATA(A_REVERSE, FORM_TEXT, form_text, "Form text"),
- DATA(A_NORMAL, FORM_ITEM_READONLY, form_item_readonly, "Readonly form item"),
- DATA(A_REVERSE, GAUGE, gauge, "Dialog box gauge"),
- DATA(A_REVERSE, BORDER2, border2, "Dialog box border2"),
- DATA(A_REVERSE, INPUTBOX_BORDER2, inputbox_border2, "Input box border2"),
- DATA(A_REVERSE, SEARCHBOX_BORDER2, searchbox_border2, "Search box border2"),
- DATA(A_REVERSE, MENUBOX_BORDER2, menubox_border2, "Menu box border2")
-};
-#undef DATA
-/* *INDENT-ON* */
-
-/*
- * Maintain a list of subwindows so that we can delete them to cleanup.
- * More important, this provides a fallback when wgetparent() is not available.
- */
-static void
-add_subwindow(WINDOW *parent, WINDOW *child)
-{
- DIALOG_WINDOWS *p = dlg_calloc(DIALOG_WINDOWS, 1);
-
- if (p != 0) {
- p->normal = parent;
- p->shadow = child;
- p->getc_timeout = WTIMEOUT_OFF;
- p->next = dialog_state.all_subwindows;
- dialog_state.all_subwindows = p;
- }
-}
-
-static void
-del_subwindows(WINDOW *parent)
-{
- DIALOG_WINDOWS *p = dialog_state.all_subwindows;
- DIALOG_WINDOWS *q = 0;
- DIALOG_WINDOWS *r;
-
- while (p != 0) {
- if (p->normal == parent) {
- delwin(p->shadow);
- r = p->next;
- if (q == 0) {
- dialog_state.all_subwindows = r;
- } else {
- q->next = r;
- }
- free(p);
- p = r;
- } else {
- q = p;
- p = p->next;
- }
- }
-}
-
-/*
- * Display background title if it exists ...
- */
-void
-dlg_put_backtitle(void)
-{
-
- if (dialog_vars.backtitle != NULL) {
- chtype attr = A_NORMAL;
- int backwidth = dlg_count_columns(dialog_vars.backtitle);
- int i;
-
- dlg_attrset(stdscr, screen_attr);
- (void) wmove(stdscr, 0, 1);
- dlg_print_text(stdscr, dialog_vars.backtitle, COLS - 2, &attr);
- for (i = 0; i < COLS - backwidth; i++)
- (void) waddch(stdscr, ' ');
- (void) wmove(stdscr, 1, 1);
- for (i = 0; i < COLS - 2; i++)
- (void) waddch(stdscr, dlg_boxchar(ACS_HLINE));
- }
-
- (void) wnoutrefresh(stdscr);
-}
-
-/*
- * Set window to attribute 'attr'. There are more efficient ways to do this,
- * but will not work on older/buggy ncurses versions.
- */
-void
-dlg_attr_clear(WINDOW *win, int height, int width, chtype attr)
-{
- int i, j;
-
- dlg_attrset(win, attr);
- for (i = 0; i < height; i++) {
- (void) wmove(win, i, 0);
- for (j = 0; j < width; j++)
- (void) waddch(win, ' ');
- }
- (void) touchwin(win);
-}
-
-void
-dlg_clear(void)
-{
- dlg_attr_clear(stdscr, LINES, COLS, screen_attr);
-}
-
-#ifdef KEY_RESIZE
-void
-_dlg_resize_cleanup(WINDOW *w)
-{
- dlg_clear();
- dlg_put_backtitle();
- dlg_del_window(w);
- dlg_mouse_free_regions();
-}
-#endif /* KEY_RESIZE */
-
-#define isprivate(s) ((s) != 0 && strstr(s, "\033[?") != 0)
-
-#define TTY_DEVICE "/dev/tty"
-
-/*
- * If $DIALOG_TTY exists, allow the program to try to open the terminal
- * directly when stdout is redirected. By default we require the "--stdout"
- * option to be given, but some scripts were written making use of the
- * behavior of dialog which tried opening the terminal anyway.
- */
-#define dialog_tty() (dlg_getenv_num("DIALOG_TTY", (int *)0) > 0)
-
-/*
- * Open the terminal directly. If one of stdin, stdout or stderr really points
- * to a tty, use it. Otherwise give up and open /dev/tty.
- */
-static int
-open_terminal(char **result, int mode)
-{
- const char *device = TTY_DEVICE;
- if (!isatty(fileno(stderr))
- || (device = ttyname(fileno(stderr))) == 0) {
- if (!isatty(fileno(stdout))
- || (device = ttyname(fileno(stdout))) == 0) {
- if (!isatty(fileno(stdin))
- || (device = ttyname(fileno(stdin))) == 0) {
- device = TTY_DEVICE;
- }
- }
- }
- *result = dlg_strclone(device);
- return open(device, mode);
-}
-
-#if CAN_KEEP_TITE
-static int
-my_putc(int ch)
-{
- char buffer[2];
- int fd = fileno(dialog_state.screen_output);
-
- buffer[0] = (char) ch;
- return (int) write(fd, buffer, (size_t) 1);
-}
-#endif
-
-/*
- * Do some initialization for dialog.
- *
- * 'input' is the real tty input of dialog. Usually it is stdin, but if
- * --input-fd option is used, it may be anything.
- *
- * 'output' is where dialog will send its result. Usually it is stderr, but
- * if --stdout or --output-fd is used, it may be anything. We are concerned
- * mainly with the case where it happens to be the same as stdout.
- */
-void
-init_dialog(FILE *input, FILE *output)
-{
- int fd1, fd2;
- char *device = 0;
-
- setlocale(LC_ALL, "");
-
- dialog_state.output = output;
- if (dialog_state.tab_len == 0)
- dialog_state.tab_len = TAB_LEN;
- if (dialog_state.aspect_ratio == 0)
- dialog_state.aspect_ratio = DEFAULT_ASPECT_RATIO;
-#ifdef HAVE_COLOR
- dialog_state.use_colors = USE_COLORS; /* use colors by default? */
- dialog_state.use_shadow = USE_SHADOW; /* shadow dialog boxes by default? */
-#endif
-
-#ifdef HAVE_RC_FILE
- if (dlg_parse_rc() == -1) /* Read the configuration file */
- dlg_exiterr("init_dialog: dlg_parse_rc");
-#endif
-
- /*
- * Some widgets (such as gauge) may read from the standard input. Pipes
- * only connect stdout/stdin, so there is not much choice. But reading a
- * pipe would get in the way of curses' normal reading stdin for getch.
- *
- * As in the --stdout (see below), reopening the terminal does not always
- * work properly. dialog provides a --pipe-fd option for this purpose. We
- * test that case first (differing fileno's for input/stdin). If the
- * fileno's are equal, but we're not reading from a tty, see if we can open
- * /dev/tty.
- */
- dialog_state.pipe_input = stdin;
- if (fileno(input) != fileno(stdin)) {
- if ((fd1 = dup(fileno(input))) >= 0
- && (fd2 = dup(fileno(stdin))) >= 0) {
- (void) dup2(fileno(input), fileno(stdin));
- dialog_state.pipe_input = fdopen(fd2, "r");
- if (fileno(stdin) != 0) /* some functions may read fd #0 */
- (void) dup2(fileno(stdin), 0);
- } else {
- dlg_exiterr("cannot open tty-input");
- }
- close(fd1);
- } else if (!isatty(fileno(stdin))) {
- if ((fd1 = open_terminal(&device, O_RDONLY)) >= 0) {
- if ((fd2 = dup(fileno(stdin))) >= 0) {
- dialog_state.pipe_input = fdopen(fd2, "r");
- if (freopen(device, "r", stdin) == 0)
- dlg_exiterr("cannot open tty-input");
- if (fileno(stdin) != 0) /* some functions may read fd #0 */
- (void) dup2(fileno(stdin), 0);
- }
- close(fd1);
- }
- free(device);
- }
-
- /*
- * If stdout is not a tty and dialog is called with the --stdout option, we
- * have to provide for a way to write to the screen.
- *
- * The curses library normally writes its output to stdout, leaving stderr
- * free for scripting. Scripts are simpler when stdout is redirected. The
- * newterm function is useful; it allows us to specify where the output
- * goes. Reopening the terminal is not portable since several
- * configurations do not allow this to work properly:
- *
- * a) some getty implementations (and possibly broken tty drivers, e.g., on
- * HPUX 10 and 11) cause stdin to act as if it is still in cooked mode
- * even though results from ioctl's state that it is successfully
- * altered to raw mode. Broken is the proper term.
- *
- * b) the user may not have permissions on the device, e.g., if one su's
- * from the login user to another non-privileged user.
- */
- if (!isatty(fileno(stdout))
- && (fileno(stdout) == fileno(output) || dialog_tty())) {
- if ((fd1 = open_terminal(&device, O_WRONLY)) >= 0
- && (dialog_state.screen_output = fdopen(fd1, "w")) != 0) {
- if (newterm(NULL, dialog_state.screen_output, stdin) == 0) {
- dlg_exiterr("cannot initialize curses");
- }
- free(device);
- } else {
- dlg_exiterr("cannot open tty-output");
- }
- } else {
- dialog_state.screen_output = stdout;
- (void) initscr();
- }
- dlg_keep_tite(dialog_state.screen_output);
-#ifdef HAVE_FLUSHINP
- (void) flushinp();
-#endif
- (void) keypad(stdscr, TRUE);
- (void) cbreak();
- (void) noecho();
-
- if (!dialog_state.no_mouse) {
- mouse_open();
- }
-
- dialog_state.screen_initialized = TRUE;
-
-#ifdef HAVE_COLOR
- if (dialog_state.use_colors || dialog_state.use_shadow)
- dlg_color_setup(); /* Set up colors */
-#endif
-
- /* Set screen to screen attribute */
- dlg_clear();
-}
-
-void
-dlg_keep_tite(FILE *output)
-{
- if (!dialog_vars.keep_tite) {
-#if CAN_KEEP_TITE
- /*
- * Cancel xterm's alternate-screen mode.
- */
- if ((fileno(output) != fileno(stdout)
- || isatty(fileno(output)))
- && key_mouse != 0 /* xterm and kindred */
- && isprivate(enter_ca_mode)
- && isprivate(exit_ca_mode)) {
- FILE *save = dialog_state.screen_output;
-
- /*
- * initscr() or newterm() already wrote enter_ca_mode as a side
- * effect of initializing the screen. It would be nice to not even
- * do that, but we do not really have access to the correct copy of
- * the terminfo description until those functions have been
- * invoked.
- */
- (void) refresh();
- dialog_state.screen_output = output;
- (void) tputs(exit_ca_mode, 0, my_putc);
- (void) tputs(clear_screen, 0, my_putc);
- dialog_state.screen_output = save;
-
- /*
- * Prevent ncurses from switching "back" to the normal screen when
- * exiting from dialog. That would move the cursor to the original
- * location saved in xterm. Normally curses sets the cursor
- * position to the first line after the display, but the alternate
- * screen switching is done after that point.
- *
- * Cancelling the strings altogether also works around the buggy
- * implementation of alternate-screen in rxvt, etc., which clear
- * more of the display than they should.
- */
- enter_ca_mode = 0;
- exit_ca_mode = 0;
- }
-#else
- /*
- * For other implementations, there are no useful answers:
- * + SVr4 curses "could" support a similar approach, but the clue about
- * xterm is absent from its terminal database.
- * + PDCurses does not provide terminfo.
- */
- (void) output;
-#endif
- }
-}
-
-#ifdef HAVE_COLOR
-static int defined_colors = 1; /* pair-0 is reserved */
-/*
- * Setup for color display
- */
-void
-dlg_color_setup(void)
-{
- if (has_colors()) { /* Terminal supports color? */
- unsigned i;
-
- (void) start_color();
-
-#if defined(HAVE_USE_DEFAULT_COLORS)
- use_default_colors();
-#endif
-
-#if defined(__NetBSD__) && defined(_CURSES_)
-#define C_ATTR(x,y) (((x) != 0 ? A_BOLD : 0) | COLOR_PAIR((y)))
- /* work around bug in NetBSD curses */
- for (i = 0; i < sizeof(dlg_color_table) /
- sizeof(dlg_color_table[0]); i++) {
-
- /* Initialize color pairs */
- (void) init_pair(i + 1,
- dlg_color_table[i].fg,
- dlg_color_table[i].bg);
-
- /* Setup color attributes */
- dlg_color_table[i].atr = C_ATTR(dlg_color_table[i].hilite, i + 1);
- }
- defined_colors = i + 1;
-#else
- for (i = 0; i < sizeof(dlg_color_table) /
- sizeof(dlg_color_table[0]); i++) {
-
- /* Initialize color pairs */
- chtype atr = dlg_color_pair(dlg_color_table[i].fg,
- dlg_color_table[i].bg);
-
- atr |= (dlg_color_table[i].hilite ? A_BOLD : 0);
-#ifdef HAVE_RC_FILE2
- atr |= (dlg_color_table[i].ul ? A_UNDERLINE : 0);
- atr |= (dlg_color_table[i].rv ? A_REVERSE : 0);
-#endif /* HAVE_RC_FILE2 */
-
- dlg_color_table[i].atr = atr;
- }
-#endif
- } else {
- dialog_state.use_colors = FALSE;
- dialog_state.use_shadow = FALSE;
- }
-}
-
-int
-dlg_color_count(void)
-{
- return TableSize(dlg_color_table);
-}
-
-/*
- * Wrapper for getattrs(), or the more cumbersome X/Open wattr_get().
- */
-chtype
-dlg_get_attrs(WINDOW *win)
-{
- chtype result;
-#ifdef HAVE_GETATTRS
- result = (chtype) getattrs(win);
-#else
- attr_t my_result;
- short my_pair;
- wattr_get(win, &my_result, &my_pair, NULL);
- result = my_result;
-#endif
- return result;
-}
-
-/*
- * Reuse color pairs (they are limited), returning a COLOR_PAIR() value if we
- * have (or can) define a pair with the given color as foreground on the
- * window's defined background.
- */
-chtype
-dlg_color_pair(int foreground, int background)
-{
- chtype result = 0;
- int pair;
- short fg, bg;
- bool found = FALSE;
-
- for (pair = 1; pair < defined_colors; ++pair) {
- if (pair_content((short) pair, &fg, &bg) != ERR
- && fg == foreground
- && bg == background) {
- result = (chtype) COLOR_PAIR(pair);
- found = TRUE;
- break;
- }
- }
- if (!found && (defined_colors + 1) < COLOR_PAIRS) {
- pair = defined_colors++;
- (void) init_pair((short) pair, (short) foreground, (short) background);
- result = (chtype) COLOR_PAIR(pair);
- }
- return result;
-}
-
-/*
- * Reuse color pairs (they are limited), returning a COLOR_PAIR() value if we
- * have (or can) define a pair with the given color as foreground on the
- * window's defined background.
- */
-static chtype
-define_color(WINDOW *win, int foreground)
-{
- short fg, bg, background;
- if (dialog_state.text_only) {
- background = COLOR_BLACK;
- } else {
- chtype attrs = dlg_get_attrs(win);
- int pair;
-
- if ((pair = PAIR_NUMBER(attrs)) != 0
- && pair_content((short) pair, &fg, &bg) != ERR) {
- background = bg;
- } else {
- background = COLOR_BLACK;
- }
- }
- return dlg_color_pair(foreground, background);
-}
-#endif
-
-/*
- * End using dialog functions.
- */
-void
-end_dialog(void)
-{
- if (dialog_state.screen_initialized) {
- dialog_state.screen_initialized = FALSE;
- if (dialog_vars.erase_on_exit) {
- /*
- * Clear the screen to the native background color, and leave the
- * terminal cursor at the lower-left corner of the screen.
- */
- werase(stdscr);
- wrefresh(stdscr);
- }
- mouse_close();
- (void) endwin();
- (void) fflush(stdout);
- }
-}
-
-#define ESCAPE_LEN 3
-#define isOurEscape(p) (((p)[0] == '\\') && ((p)[1] == 'Z') && ((p)[2] != 0))
-
-int
-dlg_count_real_columns(const char *text)
-{
- int result = 0;
- if (*text) {
- result = dlg_count_columns(text);
- if (result && dialog_vars.colors) {
- int hidden = 0;
- while (*text) {
- if (isOurEscape(text)) {
- hidden += ESCAPE_LEN;
- text += ESCAPE_LEN;
- } else {
- ++text;
- }
- }
- result -= hidden;
- }
- }
- return result;
-}
-
-static int
-centered(int width, const char *string)
-{
- int need = dlg_count_real_columns(string);
- int left;
-
- left = (width - need) / 2 - 1;
- if (left < 0)
- left = 0;
- return left;
-}
-
-#ifdef USE_WIDE_CURSES
-static bool
-is_combining(const char *txt, int *combined)
-{
- bool result = FALSE;
-
- if (*combined == 0) {
- if (UCH(*txt) >= 128) {
- wchar_t wch;
- mbstate_t state;
- size_t given = strlen(txt);
- size_t len;
-
- memset(&state, 0, sizeof(state));
- len = mbrtowc(&wch, txt, given, &state);
- if ((int) len > 0 && wcwidth(wch) == 0) {
- *combined = (int) len - 1;
- result = TRUE;
- }
- }
- } else {
- result = TRUE;
- *combined -= 1;
- }
- return result;
-}
-#endif
-
-/*
- * Print the name (tag) or text from a DIALOG_LISTITEM, highlighting the
- * first character if selected.
- */
-void
-dlg_print_listitem(WINDOW *win,
- const char *text,
- int climit,
- bool first,
- int selected)
-{
- chtype attr = A_NORMAL;
- int limit;
- chtype attrs[4];
-
- if (text == 0)
- text = "";
-
- if (first && !dialog_vars.no_hot_list) {
- const int *indx = dlg_index_wchars(text);
- attrs[3] = tag_key_selected_attr;
- attrs[2] = tag_key_attr;
- attrs[1] = tag_selected_attr;
- attrs[0] = tag_attr;
-
- dlg_attrset(win, selected ? attrs[3] : attrs[2]);
- if (*text != '\0') {
- (void) waddnstr(win, text, indx[1]);
-
- if ((int) strlen(text) > indx[1]) {
- limit = dlg_limit_columns(text, climit, 1);
- if (limit > 1) {
- dlg_attrset(win, selected ? attrs[1] : attrs[0]);
- (void) waddnstr(win,
- text + indx[1],
- indx[limit] - indx[1]);
- }
- }
- }
- } else {
- const int *cols;
-
- attrs[1] = item_selected_attr;
- attrs[0] = item_attr;
-
- cols = dlg_index_columns(text);
- limit = dlg_limit_columns(text, climit, 0);
-
- if (limit > 0) {
- dlg_attrset(win, selected ? attrs[1] : attrs[0]);
- dlg_print_text(win, text, cols[limit], &attr);
- }
- }
-}
-
-/*
- * Print up to 'cols' columns from 'text', optionally rendering our escape
- * sequence for attributes and color.
- */
-void
-dlg_print_text(WINDOW *win, const char *txt, int cols, chtype *attr)
-{
- int y_origin, x_origin;
- int y_before, x_before = 0;
- int y_after, x_after;
- int tabbed = 0;
- bool ended = FALSE;
-#ifdef USE_WIDE_CURSES
- int combined = 0;
-#endif
-
- if (dialog_state.text_only) {
- y_origin = y_after = 0;
- x_origin = x_after = 0;
- } else {
- y_after = 0;
- x_after = 0;
- getyx(win, y_origin, x_origin);
- }
- while (cols > 0 && (*txt != '\0')) {
- bool thisTab;
- chtype useattr;
-
- if (dialog_vars.colors) {
- while (isOurEscape(txt)) {
- int code;
-
- txt += 2;
- switch (code = CharOf(*txt)) {
-#ifdef HAVE_COLOR
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- *attr &= ~A_COLOR;
- *attr |= define_color(win, code - '0');
- break;
-#endif
- case 'B':
- *attr &= ~A_BOLD;
- break;
- case 'b':
- *attr |= A_BOLD;
- break;
- case 'R':
- *attr &= ~A_REVERSE;
- break;
- case 'r':
- *attr |= A_REVERSE;
- break;
- case 'U':
- *attr &= ~A_UNDERLINE;
- break;
- case 'u':
- *attr |= A_UNDERLINE;
- break;
- case 'n':
- *attr = A_NORMAL;
- break;
- default:
- break;
- }
- ++txt;
- }
- }
- if (ended || *txt == '\n' || *txt == '\0')
- break;
- useattr = (*attr) & A_ATTRIBUTES;
-#ifdef HAVE_COLOR
- /*
- * Prevent this from making text invisible when the foreground and
- * background colors happen to be the same, and there's no bold
- * attribute.
- */
- if ((useattr & A_COLOR) != 0 && (useattr & A_BOLD) == 0) {
- short pair = (short) PAIR_NUMBER(useattr);
- short fg, bg;
- if (pair_content(pair, &fg, &bg) != ERR
- && fg == bg) {
- useattr &= ~A_COLOR;
- useattr |= dlg_color_pair(fg, ((bg == COLOR_BLACK)
- ? COLOR_WHITE
- : COLOR_BLACK));
- }
- }
-#endif
- /*
- * Write the character, using curses to tell exactly how wide it
- * is. If it is a tab, discount that, since the caller thinks
- * tabs are nonprinting, and curses will expand tabs to one or
- * more blanks.
- */
- thisTab = (CharOf(*txt) == TAB);
- if (dialog_state.text_only) {
- x_before = x_after;
- } else {
- if (thisTab) {
- getyx(win, y_before, x_before);
- (void) y_before;
- }
- }
- if (dialog_state.text_only) {
- int ch = CharOf(*txt++);
- if (thisTab) {
- while ((x_after++) % 8) {
- fputc(' ', dialog_state.output);
- }
- } else {
- fputc(ch, dialog_state.output);
- x_after++; /* FIXME: handle meta per locale */
- }
- } else {
- (void) waddch(win, CharOf(*txt++) | useattr);
- getyx(win, y_after, x_after);
- }
- if (thisTab && (y_after == y_origin))
- tabbed += (x_after - x_before);
- if ((y_after != y_origin) ||
- (x_after >= (cols + tabbed + x_origin)
-#ifdef USE_WIDE_CURSES
- && !is_combining(txt, &combined)
-#endif
- )) {
- ended = TRUE;
- }
- }
- if (dialog_state.text_only) {
- fputc('\n', dialog_state.output);
- }
-}
-
-/*
- * Print one line of the prompt in the window within the limits of the
- * specified right margin. The line will end on a word boundary and a pointer
- * to the start of the next line is returned, or a NULL pointer if the end of
- * *prompt is reached.
- */
-const char *
-dlg_print_line(WINDOW *win,
- chtype *attr,
- const char *prompt,
- int lm, int rm, int *x)
-{
- const char *wrap_ptr;
- const char *test_ptr;
- const char *hide_ptr = 0;
- const int *cols = dlg_index_columns(prompt);
- const int *indx = dlg_index_wchars(prompt);
- int wrap_inx = 0;
- int test_inx = 0;
- int cur_x = lm;
- int hidden = 0;
- int limit = dlg_count_wchars(prompt);
- int n;
- int tabbed = 0;
-
- *x = 1;
-
- /*
- * Set *test_ptr to the end of the line or the right margin (rm), whichever
- * is less, and set wrap_ptr to the end of the last word in the line.
- */
- for (n = 0; n < limit; ++n) {
- int ch = *(test_ptr = prompt + indx[test_inx]);
- if (ch == '\n' || ch == '\0' || cur_x >= (rm + hidden))
- break;
- if (ch == TAB && n == 0) {
- tabbed = 8; /* workaround for leading tabs */
- } else if (isblank(UCH(ch))
- && n != 0
- && !isblank(UCH(prompt[indx[n - 1]]))) {
- wrap_inx = n;
- *x = cur_x;
- } else if (dialog_vars.colors && isOurEscape(test_ptr)) {
- hide_ptr = test_ptr;
- hidden += ESCAPE_LEN;
- n += (ESCAPE_LEN - 1);
- }
- cur_x = lm + tabbed + cols[n + 1];
- if (cur_x > (rm + hidden))
- break;
- test_inx = n + 1;
- }
-
- /*
- * If the line doesn't reach the right margin in the middle of a word, then
- * we don't have to wrap it at the end of the previous word.
- */
- test_ptr = prompt + indx[test_inx];
- if (*test_ptr == '\n' || isblank(UCH(*test_ptr)) || *test_ptr == '\0') {
- wrap_inx = test_inx;
- while (wrap_inx > 0 && isblank(UCH(prompt[indx[wrap_inx - 1]]))) {
- wrap_inx--;
- }
- *x = lm + indx[wrap_inx];
- } else if (*x == 1 && cur_x >= rm) {
- /*
- * If the line has no spaces, then wrap it anyway at the right margin
- */
- *x = rm;
- wrap_inx = test_inx;
- }
- wrap_ptr = prompt + indx[wrap_inx];
-#ifdef USE_WIDE_CURSES
- if (UCH(*wrap_ptr) >= 128) {
- int combined = 0;
- while (is_combining(wrap_ptr, &combined)) {
- ++wrap_ptr;
- }
- }
-#endif
-
- /*
- * If we found hidden text past the last point that we will display,
- * discount that from the displayed length.
- */
- if ((hide_ptr != 0) && (hide_ptr >= wrap_ptr)) {
- hidden -= ESCAPE_LEN;
- test_ptr = wrap_ptr;
- while (test_ptr < wrap_ptr) {
- if (dialog_vars.colors && isOurEscape(test_ptr)) {
- hidden -= ESCAPE_LEN;
- test_ptr += ESCAPE_LEN;
- } else {
- ++test_ptr;
- }
- }
- }
-
- /*
- * Print the line if we have a window pointer. Otherwise this routine
- * is just being called for sizing the window.
- */
- if (dialog_state.text_only || win) {
- dlg_print_text(win, prompt, (cols[wrap_inx] - hidden), attr);
- }
-
- /* *x tells the calling function how long the line was */
- if (*x == 1) {
- *x = rm;
- }
-
- *x -= hidden;
-
- /* Find the start of the next line and return a pointer to it */
- test_ptr = wrap_ptr;
- while (isblank(UCH(*test_ptr)))
- test_ptr++;
- if (*test_ptr == '\n')
- test_ptr++;
- dlg_finish_string(prompt);
- return (test_ptr);
-}
-
-static void
-justify_text(WINDOW *win,
- const char *prompt,
- int limit_y,
- int limit_x,
- int *high, int *wide)
-{
- chtype attr = A_NORMAL;
- int x;
- int y = MARGIN;
- int max_x = 2;
- int lm = (2 * MARGIN); /* left margin (box-border plus a space) */
- int rm = limit_x; /* right margin */
- int bm = limit_y; /* bottom margin */
- int last_y = 0, last_x = 0;
-
- dialog_state.text_height = 0;
- dialog_state.text_width = 0;
- if (dialog_state.text_only || win) {
- rm -= (2 * MARGIN);
- bm -= (2 * MARGIN);
- }
- if (prompt == 0)
- prompt = "";
-
- if (win != 0)
- getyx(win, last_y, last_x);
- while (y <= bm && *prompt) {
- x = lm;
-
- if (*prompt == '\n') {
- while (*prompt == '\n' && y < bm) {
- if (*(prompt + 1) != '\0') {
- ++y;
- if (win != 0)
- (void) wmove(win, y, lm);
- }
- prompt++;
- }
- } else if (win != 0)
- (void) wmove(win, y, lm);
-
- if (*prompt) {
- prompt = dlg_print_line(win, &attr, prompt, lm, rm, &x);
- if (win != 0)
- getyx(win, last_y, last_x);
- }
- if (*prompt) {
- ++y;
- if (win != 0)
- (void) wmove(win, y, lm);
- }
- max_x = MAX(max_x, x);
- }
- /* Move back to the last position after drawing prompt, for msgbox. */
- if (win != 0)
- (void) wmove(win, last_y, last_x);
-
- /* Set the final height and width for the calling function */
- if (high != 0)
- *high = y;
- if (wide != 0)
- *wide = max_x;
-}
-
-/*
- * Print a string of text in a window, automatically wrap around to the next
- * line if the string is too long to fit on one line. Note that the string may
- * contain embedded newlines.
- */
-void
-dlg_print_autowrap(WINDOW *win, const char *prompt, int height, int width)
-{
- justify_text(win, prompt,
- height,
- width,
- (int *) 0, (int *) 0);
-}
-
-/*
- * Display the message in a scrollable window. Actually the way it works is
- * that we create a "tall" window of the proper width, let the text wrap within
- * that, and copy a slice of the result to the dialog.
- *
- * It works for ncurses. Other curses implementations show only blanks (Tru64)
- * or garbage (NetBSD).
- */
-int
-dlg_print_scrolled(WINDOW *win,
- const char *prompt,
- int offset,
- int height,
- int width,
- int pauseopt)
-{
- int oldy, oldx;
- int last = 0;
-
- (void) pauseopt; /* used only for ncurses */
-
- getyx(win, oldy, oldx);
-#ifdef NCURSES_VERSION
- if (pauseopt) {
- int wide = width - (2 * MARGIN);
- int high = LINES;
- int len;
- WINDOW *dummy;
-
-#if defined(NCURSES_VERSION_PATCH) && NCURSES_VERSION_PATCH >= 20040417
- /*
- * If we're not limited by the screensize, allow text to possibly be
- * one character per line.
- */
- if ((len = dlg_count_columns(prompt)) > high)
- high = len;
-#endif
- dummy = newwin(high, width, 0, 0);
- if (dummy == 0) {
- dlg_attrset(win, dialog_attr);
- dlg_print_autowrap(win, prompt, height + 1 + (3 * MARGIN), width);
- last = 0;
- } else {
- int y, x;
-
- wbkgdset(dummy, dialog_attr | ' ');
- dlg_attrset(dummy, dialog_attr);
- werase(dummy);
- dlg_print_autowrap(dummy, prompt, high, width);
- getyx(dummy, y, x);
- (void) x;
-
- copywin(dummy, /* srcwin */
- win, /* dstwin */
- offset + MARGIN, /* sminrow */
- MARGIN, /* smincol */
- MARGIN, /* dminrow */
- MARGIN, /* dmincol */
- height, /* dmaxrow */
- wide, /* dmaxcol */
- FALSE);
-
- delwin(dummy);
-
- /* if the text is incomplete, or we have scrolled, show the percentage */
- if (y > 0 && wide > 4) {
- int percent = (int) ((height + offset) * 100.0 / y);
-
- if (percent < 0)
- percent = 0;
- if (percent > 100)
- percent = 100;
-
- if (offset != 0 || percent != 100) {
- char buffer[5];
-
- dlg_attrset(win, position_indicator_attr);
- (void) wmove(win, MARGIN + height, wide - 4);
- (void) sprintf(buffer, "%d%%", percent);
- (void) waddstr(win, buffer);
- if ((len = (int) strlen(buffer)) < 4) {
- dlg_attrset(win, border_attr);
- whline(win, dlg_boxchar(ACS_HLINE), 4 - len);
- }
- }
- }
- last = (y - height);
- }
- } else
-#endif
- {
- (void) offset;
- dlg_attrset(win, dialog_attr);
- dlg_print_autowrap(win, prompt, height + 1 + (3 * MARGIN), width);
- last = 0;
- }
- wmove(win, oldy, oldx);
- return last;
-}
-
-int
-dlg_check_scrolled(int key, int last, int page, bool * show, int *offset)
-{
- int code = 0;
-
- *show = FALSE;
-
- switch (key) {
- case DLGK_PAGE_FIRST:
- if (*offset > 0) {
- *offset = 0;
- *show = TRUE;
- }
- break;
- case DLGK_PAGE_LAST:
- if (*offset < last) {
- *offset = last;
- *show = TRUE;
- }
- break;
- case DLGK_GRID_UP:
- if (*offset > 0) {
- --(*offset);
- *show = TRUE;
- }
- break;
- case DLGK_GRID_DOWN:
- if (*offset < last) {
- ++(*offset);
- *show = TRUE;
- }
- break;
- case DLGK_PAGE_PREV:
- if (*offset > 0) {
- *offset -= page;
- if (*offset < 0)
- *offset = 0;
- *show = TRUE;
- }
- break;
- case DLGK_PAGE_NEXT:
- if (*offset < last) {
- *offset += page;
- if (*offset > last)
- *offset = last;
- *show = TRUE;
- }
- break;
- default:
- code = -1;
- break;
- }
- return code;
-}
-
-/*
- * Calculate the window size for preformatted text. This will calculate box
- * dimensions that are at or close to the specified aspect ratio for the prompt
- * string with all spaces and newlines preserved and additional newlines added
- * as necessary.
- */
-static void
-auto_size_preformatted(const char *prompt, int *height, int *width)
-{
- int high = 0, wide = 0;
- float car; /* Calculated Aspect Ratio */
- int max_y = SLINES - 1;
- int max_x = SCOLS - 2;
- int max_width = max_x;
- int ar = dialog_state.aspect_ratio;
-
- /* Get the initial dimensions */
- justify_text((WINDOW *) 0, prompt, max_y, max_x, &high, &wide);
- car = (float) (wide / high);
-
- *height = high;
- *width = wide;
-}
-
-/*
- * Find the length of the longest "word" in the given string. By setting the
- * widget width at least this long, we can avoid splitting a word on the
- * margin.
- */
-static int
-longest_word(const char *string)
-{
- int result = 0;
-
- while (*string != '\0') {
- int length = 0;
- while (*string != '\0' && !isspace(UCH(*string))) {
- length++;
- string++;
- }
- result = MAX(result, length);
- if (*string != '\0')
- string++;
- }
- return result;
-}
-
-/*
- * if (height or width == -1) Maximize()
- * if (height or width == 0), justify and return actual limits.
- */
-static void
-real_auto_size(const char *title,
- const char *prompt,
- int *height, int *width,
- int boxlines, int mincols)
-{
- int x = (dialog_vars.begin_set ? dialog_vars.begin_x : 2);
- int y = (dialog_vars.begin_set ? dialog_vars.begin_y : 1);
- int title_length = title ? dlg_count_columns(title) : 0;
- int high;
- int save_high = *height;
- int save_wide = *width;
- int max_high;
- int max_wide;
-
- if (prompt == 0) {
- if (*height == 0)
- *height = -1;
- if (*width == 0)
- *width = -1;
- }
-
- max_high = (*height < 0);
- max_wide = (*width < 0);
-
- if (*height > 0) {
- high = *height;
- } else {
- high = SLINES - y;
- }
-
- if (*width <= 0) {
- int wide;
-
- if (prompt != 0) {
- wide = MAX(title_length, mincols);
- if (strchr(prompt, '\n') == 0) {
- double val = (dialog_state.aspect_ratio *
- dlg_count_real_columns(prompt));
- double xxx = sqrt(val);
- int tmp = (int) xxx;
- wide = MAX(wide, tmp);
- wide = MAX(wide, longest_word(prompt));
- justify_text((WINDOW *) 0, prompt, high, wide, height, width);
- } else {
- auto_size_preformatted(prompt, height, width);
- }
- } else {
- wide = SCOLS - x;
- justify_text((WINDOW *) 0, prompt, high, wide, height, width);
- }
- }
-
- if (*width < title_length) {
- justify_text((WINDOW *) 0, prompt, high, title_length, height, width);
- *width = title_length;
- }
-
- dialog_state.text_height = *height;
- dialog_state.text_width = *width;
-
- if (*width < mincols && save_wide == 0)
- *width = mincols;
- if (prompt != 0) {
- *width += ((2 * MARGIN) + SHADOW_COLS);
- *height += boxlines + (2 * MARGIN);
- }
-
- if (save_high > 0)
- *height = save_high;
- if (save_wide > 0)
- *width = save_wide;
-
- if (max_high)
- *height = SLINES - (dialog_vars.begin_set ? dialog_vars.begin_y : 0);
- if (max_wide)
- *width = SCOLS - (dialog_vars.begin_set ? dialog_vars.begin_x : 0);
-}
-
-/* End of real_auto_size() */
-
-void
-dlg_auto_size(const char *title,
- const char *prompt,
- int *height,
- int *width,
- int boxlines,
- int mincols)
-{
- DLG_TRACE(("# dlg_auto_size(%d,%d) limits %d,%d\n",
- *height, *width,
- boxlines, mincols));
-
- real_auto_size(title, prompt, height, width, boxlines, mincols);
-
- if (*width > SCOLS) {
- (*height)++;
- *width = SCOLS;
- }
-
- if (*height > SLINES) {
- *height = SLINES;
- }
- DLG_TRACE(("# ...dlg_auto_size(%d,%d) also %d,%d\n",
- *height, *width,
- dialog_state.text_height, dialog_state.text_width));
-}
-
-/*
- * if (height or width == -1) Maximize()
- * if (height or width == 0)
- * height=MIN(SLINES, num.lines in fd+n);
- * width=MIN(SCOLS, MAX(longer line+n, mincols));
- */
-void
-dlg_auto_sizefile(const char *title,
- const char *file,
- int *height,
- int *width,
- int boxlines,
- int mincols)
-{
- int count = 0;
- int len = title ? dlg_count_columns(title) : 0;
- int nc = 4;
- int numlines = 2;
- FILE *fd;
-
- /* Open input file for reading */
- if ((fd = fopen(file, "rb")) == NULL)
- dlg_exiterr("dlg_auto_sizefile: Cannot open input file %s", file);
-
- if ((*height == -1) || (*width == -1)) {
- *height = SLINES - (dialog_vars.begin_set ? dialog_vars.begin_y : 0);
- *width = SCOLS - (dialog_vars.begin_set ? dialog_vars.begin_x : 0);
- }
- if ((*height != 0) && (*width != 0)) {
- (void) fclose(fd);
- if (*width > SCOLS)
- *width = SCOLS;
- if (*height > SLINES)
- *height = SLINES;
- return;
- }
-
- while (!feof(fd)) {
- int ch;
- long offset;
-
- if (ferror(fd))
- break;
-
- offset = 0;
- while (((ch = getc(fd)) != '\n') && !feof(fd)) {
- if ((ch == TAB) && (dialog_vars.tab_correct)) {
- offset += dialog_state.tab_len - (offset % dialog_state.tab_len);
- } else {
- offset++;
- }
- }
-
- if (offset > len)
- len = (int) offset;
-
- count++;
- }
-
- /* now 'count' has the number of lines of fd and 'len' the max length */
-
- *height = MIN(SLINES, count + numlines + boxlines);
- *width = MIN(SCOLS, MAX((len + nc), mincols));
- /* here width and height can be maximized if > SCOLS|SLINES because
- textbox-like widgets don't put all <file> on the screen.
- Msgbox-like widget instead have to put all <text> correctly. */
-
- (void) fclose(fd);
-}
-
-/*
- * Draw a rectangular box with line drawing characters.
- *
- * borderchar is used to color the upper/left edges.
- *
- * boxchar is used to color the right/lower edges. It also is fill-color used
- * for the box contents.
- *
- * Normally, if you are drawing a scrollable box, use menubox_border_attr for
- * boxchar, and menubox_attr for borderchar since the scroll-arrows are drawn
- * with menubox_attr at the top, and menubox_border_attr at the bottom. That
- * also (given the default color choices) produces a recessed effect.
- *
- * If you want a raised effect (and are not going to use the scroll-arrows),
- * reverse this choice.
- */
-void
-dlg_draw_box2(WINDOW *win, int y, int x, int height, int width,
- chtype boxchar, chtype borderchar, chtype borderchar2)
-{
- int i, j;
- chtype save = dlg_get_attrs(win);
-
- dlg_attrset(win, 0);
- for (i = 0; i < height; i++) {
- (void) wmove(win, y + i, x);
- for (j = 0; j < width; j++)
- if (!i && !j)
- (void) waddch(win, borderchar | dlg_boxchar(ACS_ULCORNER));
- else if (i == height - 1 && !j)
- (void) waddch(win, borderchar | dlg_boxchar(ACS_LLCORNER));
- else if (!i && j == width - 1)
- (void) waddch(win, borderchar2 | dlg_boxchar(ACS_URCORNER));
- else if (i == height - 1 && j == width - 1)
- (void) waddch(win, borderchar2 | dlg_boxchar(ACS_LRCORNER));
- else if (!i)
- (void) waddch(win, borderchar | dlg_boxchar(ACS_HLINE));
- else if (i == height - 1)
- (void) waddch(win, borderchar2 | dlg_boxchar(ACS_HLINE));
- else if (!j)
- (void) waddch(win, borderchar | dlg_boxchar(ACS_VLINE));
- else if (j == width - 1)
- (void) waddch(win, borderchar2 | dlg_boxchar(ACS_VLINE));
- else
- (void) waddch(win, boxchar | ' ');
- }
- dlg_attrset(win, save);
-}
-
-void
-dlg_draw_box(WINDOW *win, int y, int x, int height, int width,
- chtype boxchar, chtype borderchar)
-{
- dlg_draw_box2(win, y, x, height, width, boxchar, borderchar, boxchar);
-}
-
-/*
- * Search the given 'list' for the given window 'win'. Typically 'win' is an
- * input-window, i.e., a window where we might use wgetch.
- *
- * The all-windows list has normal- and shadow-windows. Since we never use the
- * shadow as an input window, normally we just look for the normal-window.
- *
- * However, the all-subwindows list stores parent/child windows rather than
- * normal/shadow windows. When searching that list, we look for the child
- * window (in the .shadow field).
- */
-static DIALOG_WINDOWS *
-find_window(DIALOG_WINDOWS * list, WINDOW *win, bool normal)
-{
- DIALOG_WINDOWS *result = 0;
- DIALOG_WINDOWS *p;
-
- for (p = list; p != 0; p = p->next) {
- WINDOW *check = normal ? p->normal : p->shadow;
- if (check == win) {
- result = p;
- break;
- }
- }
- return result;
-}
-
-#define SearchTopWindows(win) find_window(dialog_state.all_windows, win, TRUE)
-#define SearchSubWindows(win) find_window(dialog_state.all_subwindows, win, FALSE)
-
-/*
- * Check for the existence of a window, e.g., when used for input or updating
- * the display. This is used in dlg_getc() and related functions, to guard
- * against an asynchronous window-deletion that might invalidate the input
- * window used in dlg_getc().
- */
-DIALOG_WINDOWS *
-_dlg_find_window(WINDOW *win)
-{
- DIALOG_WINDOWS *result = 0;
-
- if ((result = SearchTopWindows(win)) == NULL)
- result = SearchSubWindows(win);
- return result;
-}
-
-#ifdef HAVE_COLOR
-/*
- * If we have wchgat(), use that for updating shadow attributes, to work with
- * wide-character data.
- */
-
-/*
- * Check if the given point is "in" the given window. If so, return the window
- * pointer, otherwise null.
- */
-static WINDOW *
-in_window(WINDOW *win, int y, int x)
-{
- WINDOW *result = 0;
- int y_base = getbegy(win);
- int x_base = getbegx(win);
- int y_last = getmaxy(win) + y_base;
- int x_last = getmaxx(win) + x_base;
-
- if (y >= y_base && y <= y_last && x >= x_base && x <= x_last)
- result = win;
- return result;
-}
-
-static WINDOW *
-window_at_cell(DIALOG_WINDOWS * dw, int y, int x)
-{
- WINDOW *result = 0;
- DIALOG_WINDOWS *p;
- int y_want = y + getbegy(dw->shadow);
- int x_want = x + getbegx(dw->shadow);
-
- for (p = dialog_state.all_windows; p != 0; p = p->next) {
- if (dw->normal != p->normal
- && dw->shadow != p->normal
- && (result = in_window(p->normal, y_want, x_want)) != 0) {
- break;
- }
- }
- if (result == 0) {
- result = stdscr;
- }
- return result;
-}
-
-static bool
-in_shadow(WINDOW *normal, WINDOW *shadow, int y, int x)
-{
- bool result = FALSE;
- int ybase = getbegy(normal);
- int ylast = getmaxy(normal) + ybase;
- int xbase = getbegx(normal);
- int xlast = getmaxx(normal) + xbase;
-
- y += getbegy(shadow);
- x += getbegx(shadow);
-
- if (y >= ybase + SHADOW_ROWS
- && y < ylast + SHADOW_ROWS
- && x >= xlast
- && x < xlast + SHADOW_COLS) {
- /* in the right-side */
- result = TRUE;
- } else if (y >= ylast
- && y < ylast + SHADOW_ROWS
- && x >= ybase + SHADOW_COLS
- && x < ylast + SHADOW_COLS) {
- /* check the bottom */
- result = TRUE;
- }
-
- return result;
-}
-
-/*
- * When erasing a shadow, check each cell to make sure that it is not part of
- * another box's shadow. This is a little complicated since most shadows are
- * merged onto stdscr.
- */
-static bool
-last_shadow(DIALOG_WINDOWS * dw, int y, int x)
-{
- DIALOG_WINDOWS *p;
- bool result = TRUE;
-
- for (p = dialog_state.all_windows; p != 0; p = p->next) {
- if (p->normal != dw->normal
- && in_shadow(p->normal, dw->shadow, y, x)) {
- result = FALSE;
- break;
- }
- }
- return result;
-}
-
-static void
-repaint_cell(DIALOG_WINDOWS * dw, bool draw, int y, int x)
-{
- WINDOW *win = dw->shadow;
- WINDOW *cellwin;
- int y2, x2;
-
- if ((cellwin = window_at_cell(dw, y, x)) != 0
- && (draw || last_shadow(dw, y, x))
- && (y2 = (y + getbegy(win) - getbegy(cellwin))) >= 0
- && (x2 = (x + getbegx(win) - getbegx(cellwin))) >= 0
- && wmove(cellwin, y2, x2) != ERR) {
- chtype the_cell = dlg_get_attrs(cellwin);
- chtype the_attr = (draw ? shadow_attr : the_cell);
-
- if (winch(cellwin) & A_ALTCHARSET) {
- the_attr |= A_ALTCHARSET;
- }
-#if USE_WCHGAT
- wchgat(cellwin, 1,
- the_attr & (chtype) (~A_COLOR),
- (short) PAIR_NUMBER(the_attr),
- NULL);
-#else
- {
- chtype the_char = ((winch(cellwin) & A_CHARTEXT) | the_attr);
- (void) waddch(cellwin, the_char);
- }
-#endif
- wnoutrefresh(cellwin);
- }
-}
-
-#define RepaintCell(dw, draw, y, x) repaint_cell(dw, draw, y, x)
-
-static void
-repaint_shadow(DIALOG_WINDOWS * dw, bool draw, int y, int x, int height, int width)
-{
- if (UseShadow(dw)) {
- int i, j;
-
-#if !USE_WCHGAT
- chtype save = dlg_get_attrs(dw->shadow);
- dlg_attrset(dw->shadow, draw ? shadow_attr : screen_attr);
-#endif
- for (i = 0; i < SHADOW_ROWS; ++i) {
- for (j = 0; j < width; ++j) {
- RepaintCell(dw, draw, i + y + height, j + x + SHADOW_COLS);
- }
- }
- for (i = 0; i < height; i++) {
- for (j = 0; j < SHADOW_COLS; ++j) {
- RepaintCell(dw, draw, i + y + SHADOW_ROWS, j + x + width);
- }
- }
- (void) wnoutrefresh(dw->shadow);
-#if !USE_WCHGAT
- dlg_attrset(dw->shadow, save);
-#endif
- }
-}
-
-/*
- * Draw a shadow on the parent window corresponding to the right- and
- * bottom-edge of the child window, to give a 3-dimensional look.
- */
-static void
-draw_childs_shadow(DIALOG_WINDOWS * dw)
-{
- if (UseShadow(dw)) {
- repaint_shadow(dw,
- TRUE,
- getbegy(dw->normal) - getbegy(dw->shadow),
- getbegx(dw->normal) - getbegx(dw->shadow),
- getmaxy(dw->normal),
- getmaxx(dw->normal));
- }
-}
-
-/*
- * Erase a shadow on the parent window corresponding to the right- and
- * bottom-edge of the child window.
- */
-static void
-erase_childs_shadow(DIALOG_WINDOWS * dw)
-{
- if (UseShadow(dw)) {
- repaint_shadow(dw,
- FALSE,
- getbegy(dw->normal) - getbegy(dw->shadow),
- getbegx(dw->normal) - getbegx(dw->shadow),
- getmaxy(dw->normal),
- getmaxx(dw->normal));
- }
-}
-
-/*
- * Draw shadows along the right and bottom edge to give a more 3D look
- * to the boxes.
- */
-void
-dlg_draw_shadow(WINDOW *win, int y, int x, int height, int width)
-{
- repaint_shadow(SearchTopWindows(win), TRUE, y, x, height, width);
-}
-#endif /* HAVE_COLOR */
-
-/*
- * Allow shell scripts to remap the exit codes so they can distinguish ESC
- * from ERROR.
- */
-void
-dlg_exit(int code)
-{
- /* *INDENT-OFF* */
- static const struct {
- int code;
- const char *name;
- } table[] = {
- { DLG_EXIT_CANCEL, "DIALOG_CANCEL" },
- { DLG_EXIT_ERROR, "DIALOG_ERROR" },
- { DLG_EXIT_ESC, "DIALOG_ESC" },
- { DLG_EXIT_EXTRA, "DIALOG_EXTRA" },
- { DLG_EXIT_HELP, "DIALOG_HELP" },
- { DLG_EXIT_OK, "DIALOG_OK" },
- { DLG_EXIT_ITEM_HELP, "DIALOG_ITEM_HELP" },
- { DLG_EXIT_TIMEOUT, "DIALOG_TIMEOUT" },
- };
- /* *INDENT-ON* */
-
- unsigned n;
- bool overridden = FALSE;
-
- retry:
- for (n = 0; n < TableSize(table); n++) {
- if (table[n].code == code) {
- if (dlg_getenv_num(table[n].name, &code)) {
- overridden = TRUE;
- }
- break;
- }
- }
-
- /*
- * Prior to 2004/12/19, a widget using --item-help would exit with "OK"
- * if the help button were selected. Now we want to exit with "HELP",
- * but allow the environment variable to override.
- */
- if (code == DLG_EXIT_ITEM_HELP && !overridden) {
- code = DLG_EXIT_HELP;
- goto retry;
- }
-#ifdef HAVE_DLG_TRACE
- dlg_trace((const char *) 0); /* close it */
-#endif
-
-#ifdef NO_LEAKS
- _dlg_inputstr_leaks();
-#if defined(NCURSES_VERSION) && (defined(HAVE_EXIT_CURSES) || defined(HAVE__NC_FREE_AND_EXIT))
- exit_curses(code);
-#endif
-#endif
-
- if (dialog_state.input == stdin) {
- exit(code);
- } else {
- /*
- * Just in case of using --input-fd option, do not
- * call atexit functions of ncurses which may hang.
- */
- if (dialog_state.input) {
- fclose(dialog_state.input);
- dialog_state.input = 0;
- }
- if (dialog_state.pipe_input) {
- if (dialog_state.pipe_input != stdin) {
- fclose(dialog_state.pipe_input);
- dialog_state.pipe_input = 0;
- }
- }
- _exit(code);
- }
-}
-
-#define DATA(name) { DLG_EXIT_ ## name, #name }
-/* *INDENT-OFF* */
-static struct {
- int code;
- const char *name;
-} exit_codenames[] = {
- DATA(ESC),
- DATA(UNKNOWN),
- DATA(ERROR),
- DATA(OK),
- DATA(CANCEL),
- DATA(HELP),
- DATA(EXTRA),
- DATA(ITEM_HELP),
-};
-#undef DATA
-/* *INDENT-ON* */
-
-const char *
-dlg_exitcode2s(int code)
-{
- const char *result = "?";
- size_t n;
-
- for (n = 0; n < TableSize(exit_codenames); ++n) {
- if (exit_codenames[n].code == code) {
- result = exit_codenames[n].name;
- break;
- }
- }
- return result;
-}
-
-int
-dlg_exitname2n(const char *name)
-{
- int result = DLG_EXIT_UNKNOWN;
- size_t n;
-
- for (n = 0; n < TableSize(exit_codenames); ++n) {
- if (!dlg_strcmp(exit_codenames[n].name, name)) {
- result = exit_codenames[n].code;
- break;
- }
- }
- return result;
-}
-
-/* quit program killing all tailbg */
-void
-dlg_exiterr(const char *fmt, ...)
-{
- int retval;
- va_list ap;
-
- end_dialog();
-
- (void) fputc('\n', stderr);
- va_start(ap, fmt);
- (void) vfprintf(stderr, fmt, ap);
- va_end(ap);
- (void) fputc('\n', stderr);
-
-#ifdef HAVE_DLG_TRACE
- va_start(ap, fmt);
- dlg_trace_msg("## Error: ");
- dlg_trace_va_msg(fmt, ap);
- va_end(ap);
-#endif
-
- dlg_killall_bg(&retval);
-
- (void) fflush(stderr);
- (void) fflush(stdout);
- dlg_exit(strcmp(fmt, "timeout") == 0 ? DLG_EXIT_TIMEOUT : DLG_EXIT_ERROR);
-}
-
-/*
- * Get a string from the environment, rejecting those which are entirely blank.
- */
-char *
-dlg_getenv_str(const char *name)
-{
- char *result = getenv(name);
- if (result != NULL) {
- while (*result != '\0' && isspace(UCH(*result)))
- ++result;
- if (*result == '\0')
- result = NULL;
- }
- return result;
-}
-
-/*
- * Get a number from the environment:
- * + If the caller provides a pointer in the second parameter, return
- * success/failure for the function return, and the actual value via the
- * pointer. Use this for decoding arbitrary numbers, e.g., negative or zero.
- * + If the caller does not provide a pointer, return the decoded value for
- * the function-return. Use this when only values greater than zero are
- * useful.
- */
-int
-dlg_getenv_num(const char *name, int *value)
-{
- int result = 0;
- char *data = getenv(name);
- if (data != NULL) {
- char *temp = NULL;
- long check = strtol(data, &temp, 0);
- if (temp != 0 && temp != data && *temp == '\0') {
- result = (int) check;
- if (value != NULL) {
- *value = result;
- result = 1;
- }
- }
- }
- return result;
-}
-
-void
-dlg_beeping(void)
-{
- if (dialog_vars.beep_signal) {
- (void) beep();
- dialog_vars.beep_signal = 0;
- }
-}
-
-void
-dlg_print_size(int height, int width)
-{
- if (dialog_vars.print_siz) {
- fprintf(dialog_state.output, "Size: %d, %d\n", height, width);
- DLG_TRACE(("# print size: %dx%d\n", height, width));
- }
-}
-
-void
-dlg_ctl_size(int height, int width)
-{
- if (dialog_vars.size_err) {
- if ((width > COLS) || (height > LINES)) {
- dlg_exiterr("Window too big. (height, width) = (%d, %d). Max allowed (%d, %d).",
- height, width, LINES, COLS);
- }
-#ifdef HAVE_COLOR
- else if ((dialog_state.use_shadow)
- && ((width > SCOLS || height > SLINES))) {
- if ((width <= COLS) && (height <= LINES)) {
- /* try again, without shadows */
- dialog_state.use_shadow = 0;
- } else {
- dlg_exiterr("Window+Shadow too big. (height, width) = (%d, %d). Max allowed (%d, %d).",
- height, width, SLINES, SCOLS);
- }
- }
-#endif
- }
-}
-
-/*
- * If the --tab-correct was not selected, convert tabs to single spaces.
- */
-void
-dlg_tab_correct_str(char *prompt)
-{
- char *ptr;
-
- if (dialog_vars.tab_correct) {
- while ((ptr = strchr(prompt, TAB)) != NULL) {
- *ptr = ' ';
- prompt = ptr;
- }
- }
-}
-
-void
-dlg_calc_listh(int *height, int *list_height, int item_no)
-{
- /* calculate new height and list_height */
- int rows = SLINES - (dialog_vars.begin_set ? dialog_vars.begin_y : 0);
- if (rows - (*height) > 0) {
- if (rows - (*height) > item_no)
- *list_height = item_no;
- else
- *list_height = rows - (*height);
- }
- (*height) += (*list_height);
-}
-
-/* obsolete */
-int
-dlg_calc_listw(int item_no, char **items, int group)
-{
- int i, len1 = 0, len2 = 0;
-
- for (i = 0; i < (item_no * group); i += group) {
- int n;
-
- if ((n = dlg_count_columns(items[i])) > len1)
- len1 = n;
- if ((n = dlg_count_columns(items[i + 1])) > len2)
- len2 = n;
- }
- return len1 + len2;
-}
-
-int
-dlg_calc_list_width(int item_no, DIALOG_LISTITEM * items)
-{
- int n, i, len1 = 0, len2 = 0;
- int bits = ((dialog_vars.no_tags ? 1 : 0)
- + (dialog_vars.no_items ? 2 : 0));
-
- for (i = 0; i < item_no; ++i) {
- switch (bits) {
- case 0:
- /* FALLTHRU */
- case 1:
- if ((n = dlg_count_columns(items[i].name)) > len1)
- len1 = n;
- if ((n = dlg_count_columns(items[i].text)) > len2)
- len2 = n;
- break;
- case 2:
- /* FALLTHRU */
- case 3:
- if ((n = dlg_count_columns(items[i].name)) > len1)
- len1 = n;
- break;
- }
- }
- return len1 + len2;
-}
-
-char *
-dlg_strempty(void)
-{
- static char empty[] = "";
- return empty;
-}
-
-char *
-dlg_strclone(const char *cprompt)
-{
- char *prompt = 0;
- if (cprompt != 0) {
- prompt = dlg_malloc(char, strlen(cprompt) + 1);
- assert_ptr(prompt, "dlg_strclone");
- strcpy(prompt, cprompt);
- }
- return prompt;
-}
-
-chtype
-dlg_asciibox(chtype ch)
-{
- chtype result = 0;
-
- if (ch == ACS_ULCORNER)
- result = '+';
- else if (ch == ACS_LLCORNER)
- result = '+';
- else if (ch == ACS_URCORNER)
- result = '+';
- else if (ch == ACS_LRCORNER)
- result = '+';
- else if (ch == ACS_HLINE)
- result = '-';
- else if (ch == ACS_VLINE)
- result = '|';
- else if (ch == ACS_LTEE)
- result = '+';
- else if (ch == ACS_RTEE)
- result = '+';
- else if (ch == ACS_UARROW)
- result = '^';
- else if (ch == ACS_DARROW)
- result = 'v';
-
- return result;
-}
-
-chtype
-dlg_boxchar(chtype ch)
-{
- chtype result = dlg_asciibox(ch);
-
- if (result != 0) {
- if (dialog_vars.ascii_lines)
- ch = result;
- else if (dialog_vars.no_lines)
- ch = ' ';
- }
- return ch;
-}
-
-int
-dlg_box_x_ordinate(int width)
-{
- int x;
-
- if (dialog_vars.begin_set == 1) {
- x = dialog_vars.begin_x;
- } else {
- /* center dialog box on screen unless --begin-set */
- x = (SCOLS - width) / 2;
- }
- return x;
-}
-
-int
-dlg_box_y_ordinate(int height)
-{
- int y;
-
- if (dialog_vars.begin_set == 1) {
- y = dialog_vars.begin_y;
- } else {
- /* center dialog box on screen unless --begin-set */
- y = (SLINES - height) / 2;
- }
- return y;
-}
-
-void
-dlg_draw_title(WINDOW *win, const char *title)
-{
- if (title != NULL) {
- chtype attr = A_NORMAL;
- chtype save = dlg_get_attrs(win);
- int x = centered(getmaxx(win), title);
-
- dlg_attrset(win, title_attr);
- wmove(win, 0, x);
- dlg_print_text(win, title, getmaxx(win) - x, &attr);
- dlg_attrset(win, save);
- dlg_finish_string(title);
- }
-}
-
-void
-dlg_draw_bottom_box2(WINDOW *win, chtype on_left, chtype on_right, chtype on_inside)
-{
- int width = getmaxx(win);
- int height = getmaxy(win);
- int i;
-
- dlg_attrset(win, on_left);
- (void) wmove(win, height - 3, 0);
- (void) waddch(win, dlg_boxchar(ACS_LTEE));
- for (i = 0; i < width - 2; i++)
- (void) waddch(win, dlg_boxchar(ACS_HLINE));
- dlg_attrset(win, on_right);
- (void) waddch(win, dlg_boxchar(ACS_RTEE));
- dlg_attrset(win, on_inside);
- (void) wmove(win, height - 2, 1);
- for (i = 0; i < width - 2; i++)
- (void) waddch(win, ' ');
-}
-
-void
-dlg_draw_bottom_box(WINDOW *win)
-{
- dlg_draw_bottom_box2(win, border_attr, dialog_attr, dialog_attr);
-}
-
-/*
- * Remove a window, repainting everything else. This would be simpler if we
- * used the panel library, but that is not _always_ available.
- */
-void
-dlg_del_window(WINDOW *win)
-{
- DIALOG_WINDOWS *p, *q, *r;
-
- /*
- * If --keep-window was set, do not delete/repaint the windows.
- */
- if (dialog_vars.keep_window)
- return;
-
- /* Leave the main window untouched if there are no background windows.
- * We do this so the current window will not be cleared on exit, allowing
- * things like the infobox demo to run without flicker.
- */
- if (dialog_state.getc_callbacks != 0) {
- touchwin(stdscr);
- wnoutrefresh(stdscr);
- }
-
- for (p = dialog_state.all_windows, q = r = 0; p != 0; r = p, p = p->next) {
- if (p->normal == win) {
- q = p; /* found a match - should be only one */
- if (r == 0) {
- dialog_state.all_windows = p->next;
- } else {
- r->next = p->next;
- }
- } else {
- if (p->shadow != 0) {
- touchwin(p->shadow);
- wnoutrefresh(p->shadow);
- }
- touchwin(p->normal);
- wnoutrefresh(p->normal);
- }
- }
-
- if (q) {
- if (dialog_state.all_windows != 0)
- erase_childs_shadow(q);
- del_subwindows(q->normal);
- dlg_unregister_window(q->normal);
- delwin(q->normal);
- free(q);
- }
- doupdate();
-}
-
-/*
- * Create a window, optionally with a shadow.
- */
-WINDOW *
-dlg_new_window(int height, int width, int y, int x)
-{
- return dlg_new_modal_window(stdscr, height, width, y, x);
-}
-
-/*
- * "Modal" windows differ from normal ones by having a shadow in a window
- * separate from the standard screen.
- */
-WINDOW *
-dlg_new_modal_window(WINDOW *parent, int height, int width, int y, int x)
-{
- WINDOW *win;
- DIALOG_WINDOWS *p = dlg_calloc(DIALOG_WINDOWS, 1);
-
- (void) parent;
- if (p == 0
- || (win = newwin(height, width, y, x)) == 0) {
- dlg_exiterr("Can't make new window at (%d,%d), size (%d,%d).\n",
- y, x, height, width);
- }
- p->next = dialog_state.all_windows;
- p->normal = win;
- p->getc_timeout = WTIMEOUT_OFF;
- dialog_state.all_windows = p;
-#ifdef HAVE_COLOR
- if (dialog_state.use_shadow) {
- p->shadow = parent;
- draw_childs_shadow(p);
- }
-#endif
-
- (void) keypad(win, TRUE);
- return win;
-}
-
-/*
- * dlg_getc() uses the return-value to determine how to handle an ERR return
- * from a non-blocking read:
- * a) if greater than zero, there was an expired timeout (blocking for a short
- * time), or
- * b) if zero, it was a non-blocking read, or
- * c) if negative, an error occurred on a blocking read.
- */
-int
-dlg_set_timeout(WINDOW *win, bool will_getc)
-{
- DIALOG_WINDOWS *p;
- int result = 0;
-
- if ((p = SearchTopWindows(win)) != NULL) {
- int interval = (dialog_vars.timeout_secs * 1000);
-
- if (will_getc || dialog_vars.pause_secs) {
- interval = WTIMEOUT_VAL;
- } else {
- result = interval;
- if (interval <= 0) {
- interval = WTIMEOUT_OFF;
- }
- }
- wtimeout(win, interval);
- p->getc_timeout = interval;
- }
- return result;
-}
-
-void
-dlg_reset_timeout(WINDOW *win)
-{
- DIALOG_WINDOWS *p;
-
- if ((p = SearchTopWindows(win)) != NULL) {
- wtimeout(win, p->getc_timeout);
- } else {
- wtimeout(win, WTIMEOUT_OFF);
- }
-}
-
-/*
- * Move/Resize a window, optionally with a shadow.
- */
-#ifdef KEY_RESIZE
-void
-dlg_move_window(WINDOW *win, int height, int width, int y, int x)
-{
- if (win != 0) {
- DIALOG_WINDOWS *p;
-
- dlg_ctl_size(height, width);
-
- if ((p = SearchTopWindows(win)) != 0) {
- (void) wresize(win, height, width);
- (void) mvwin(win, y, x);
-#ifdef HAVE_COLOR
- if (p->shadow != 0) {
- if (dialog_state.use_shadow) {
- (void) mvwin(p->shadow, y + SHADOW_ROWS, x + SHADOW_COLS);
- } else {
- p->shadow = 0;
- }
- }
-#endif
- (void) refresh();
-
-#ifdef HAVE_COLOR
- draw_childs_shadow(p);
-#endif
- }
- }
-}
-
-/*
- * Having just received a KEY_RESIZE, wait a short time to ignore followup
- * KEY_RESIZE events.
- */
-void
-dlg_will_resize(WINDOW *win)
-{
- int n, base;
- int caught = 0;
-
- dialog_state.had_resize = TRUE;
- dlg_trace_win(win);
- wtimeout(win, WTIMEOUT_VAL * 5);
-
- for (n = base = 0; n < base + 10; ++n) {
- int ch;
-
- if ((ch = wgetch(win)) != ERR) {
- if (ch == KEY_RESIZE) {
- base = n;
- ++caught;
- } else if (ch != ERR) {
- ungetch(ch);
- break;
- }
- }
- }
- dlg_reset_timeout(win);
- DLG_TRACE(("# caught %d KEY_RESIZE key%s\n",
- 1 + caught,
- caught == 1 ? "" : "s"));
-}
-#endif /* KEY_RESIZE */
-
-WINDOW *
-dlg_der_window(WINDOW *parent, int height, int width, int y, int x)
-{
- WINDOW *win;
-
- /* existing uses of derwin are (almost) guaranteed to succeed, and the
- * caller has to allow for failure.
- */
- if ((win = derwin(parent, height, width, y, x)) != 0) {
- add_subwindow(parent, win);
- (void) keypad(win, TRUE);
- }
- return win;
-}
-
-WINDOW *
-dlg_sub_window(WINDOW *parent, int height, int width, int y, int x)
-{
- WINDOW *win;
-
- if ((win = subwin(parent, height, width, y, x)) == 0) {
- dlg_exiterr("Can't make sub-window at (%d,%d), size (%d,%d).\n",
- y, x, height, width);
- }
-
- add_subwindow(parent, win);
- (void) keypad(win, TRUE);
- return win;
-}
-
-/* obsolete */
-int
-dlg_default_item(char **items, int llen)
-{
- int result = 0;
-
- if (dialog_vars.default_item != 0) {
- int count = 0;
- while (*items != 0) {
- if (!strcmp(dialog_vars.default_item, *items)) {
- result = count;
- break;
- }
- items += llen;
- count++;
- }
- }
- return result;
-}
-
-int
-dlg_default_listitem(DIALOG_LISTITEM * items)
-{
- int result = 0;
-
- if (dialog_vars.default_item != 0) {
- int count = 0;
- while (items->name != 0) {
- if (!strcmp(dialog_vars.default_item, items->name)) {
- result = count;
- break;
- }
- ++items;
- count++;
- }
- }
- return result;
-}
-
-/*
- * Draw the string for item_help
- */
-void
-dlg_item_help(const char *txt)
-{
- if (USE_ITEM_HELP(txt)) {
- chtype attr = A_NORMAL;
-
- dlg_attrset(stdscr, itemhelp_attr);
- (void) wmove(stdscr, LINES - 1, 0);
- (void) wclrtoeol(stdscr);
- (void) addch(' ');
- dlg_print_text(stdscr, txt, COLS - 1, &attr);
-
- if (itemhelp_attr & A_COLOR) {
- int y, x;
- /* fill the remainder of the line with the window's attributes */
- getyx(stdscr, y, x);
- (void) y;
- while (x < COLS) {
- (void) addch(' ');
- ++x;
- }
- }
- (void) wnoutrefresh(stdscr);
- }
-}
-
-#ifndef HAVE_STRCASECMP
-int
-dlg_strcmp(const char *a, const char *b)
-{
- int ac, bc, cmp;
-
- for (;;) {
- ac = UCH(*a++);
- bc = UCH(*b++);
- if (isalpha(ac) && islower(ac))
- ac = _toupper(ac);
- if (isalpha(bc) && islower(bc))
- bc = _toupper(bc);
- cmp = ac - bc;
- if (ac == 0 || bc == 0 || cmp != 0)
- break;
- }
- return cmp;
-}
-#endif
-
-/*
- * Returns true if 'dst' points to a blank which follows another blank which
- * is not a leading blank on a line.
- */
-static bool
-trim_blank(char *base, char *dst)
-{
- int count = !!isblank(UCH(*dst));
-
- while (dst-- != base) {
- if (*dst == '\n') {
- break;
- } else if (isblank(UCH(*dst))) {
- count++;
- } else {
- break;
- }
- }
- return (count > 1);
-}
-
-/*
- * Change embedded "\n" substrings to '\n' characters and tabs to single
- * spaces. If there are no "\n"s, it will strip all extra spaces, for
- * justification. If it has "\n"'s, it will preserve extra spaces. If cr_wrap
- * is set, it will preserve '\n's.
- */
-void
-dlg_trim_string(char *s)
-{
- char *base = s;
- char *p1;
- char *p = s;
- int has_newlines = !dialog_vars.no_nl_expand && (strstr(s, "\\n") != 0);
-
- while (*p != '\0') {
- if (*p == TAB && !dialog_vars.nocollapse)
- *p = ' ';
-
- if (has_newlines) { /* If prompt contains "\n" strings */
- if (*p == '\\' && *(p + 1) == 'n') {
- *s++ = '\n';
- p += 2;
- p1 = p;
- /*
- * Handle end of lines intelligently. If '\n' follows "\n"
- * then ignore the '\n'. This eliminates the need to escape
- * the '\n' character (no need to use "\n\").
- */
- while (isblank(UCH(*p1)))
- p1++;
- if (*p1 == '\n')
- p = p1 + 1;
- } else if (*p == '\n') {
- if (dialog_vars.cr_wrap)
- *s++ = *p++;
- else {
- /* Replace the '\n' with a space if cr_wrap is not set */
- if (!trim_blank(base, p))
- *s++ = ' ';
- p++;
- }
- } else /* If *p != '\n' */
- *s++ = *p++;
- } else if (dialog_vars.trim_whitespace) {
- if (isblank(UCH(*p))) {
- if (!isblank(UCH(*(s - 1)))) {
- *s++ = ' ';
- p++;
- } else
- p++;
- } else if (*p == '\n') {
- if (dialog_vars.cr_wrap)
- *s++ = *p++;
- else if (!isblank(UCH(*(s - 1)))) {
- /* Strip '\n's if cr_wrap is not set. */
- *s++ = ' ';
- p++;
- } else
- p++;
- } else
- *s++ = *p++;
- } else { /* If there are no "\n" strings */
- if (isblank(UCH(*p)) && !dialog_vars.nocollapse) {
- if (!trim_blank(base, p))
- *s++ = *p;
- p++;
- } else
- *s++ = *p++;
- }
- }
-
- *s = '\0';
-}
-
-void
-dlg_set_focus(WINDOW *parent, WINDOW *win)
-{
- if (win != 0) {
- (void) wmove(parent,
- getpary(win) + getcury(win),
- getparx(win) + getcurx(win));
- (void) wnoutrefresh(win);
- (void) doupdate();
- }
-}
-
-/*
- * Returns the nominal maximum buffer size.
- */
-int
-dlg_max_input(int max_len)
-{
- if (dialog_vars.max_input != 0 && dialog_vars.max_input < MAX_LEN)
- max_len = dialog_vars.max_input;
-
- return max_len;
-}
-
-/*
- * Free storage used for the result buffer.
- */
-void
-dlg_clr_result(void)
-{
- if (dialog_vars.input_length) {
- dialog_vars.input_length = 0;
- if (dialog_vars.input_result)
- free(dialog_vars.input_result);
- }
- dialog_vars.input_result = 0;
-}
-
-/*
- * Setup a fixed-buffer for the result.
- */
-char *
-dlg_set_result(const char *string)
-{
- unsigned need = string ? (unsigned) strlen(string) + 1 : 0;
-
- /* inputstr.c needs a fixed buffer */
- if (need < MAX_LEN)
- need = MAX_LEN;
-
- /*
- * If the buffer is not big enough, allocate a new one.
- */
- if (dialog_vars.input_length != 0
- || dialog_vars.input_result == 0
- || need > MAX_LEN) {
-
- dlg_clr_result();
-
- dialog_vars.input_length = need;
- dialog_vars.input_result = dlg_malloc(char, need);
- assert_ptr(dialog_vars.input_result, "dlg_set_result");
- }
-
- strcpy(dialog_vars.input_result, string ? string : "");
-
- return dialog_vars.input_result;
-}
-
-/*
- * Accumulate results in dynamically allocated buffer.
- * If input_length is zero, it is a MAX_LEN buffer belonging to the caller.
- */
-void
-dlg_add_result(const char *string)
-{
- unsigned have = (dialog_vars.input_result
- ? (unsigned) strlen(dialog_vars.input_result)
- : 0);
- unsigned want = (unsigned) strlen(string) + 1 + have;
-
- if ((want >= MAX_LEN)
- || (dialog_vars.input_length != 0)
- || (dialog_vars.input_result == 0)) {
-
- if (dialog_vars.input_length == 0
- || dialog_vars.input_result == 0) {
-
- char *save_result = dialog_vars.input_result;
-
- dialog_vars.input_length = want * 2;
- dialog_vars.input_result = dlg_malloc(char, dialog_vars.input_length);
- assert_ptr(dialog_vars.input_result, "dlg_add_result malloc");
- dialog_vars.input_result[0] = '\0';
- if (save_result != 0)
- strcpy(dialog_vars.input_result, save_result);
- } else if (want >= dialog_vars.input_length) {
- dialog_vars.input_length = want * 2;
- dialog_vars.input_result = dlg_realloc(char,
- dialog_vars.input_length,
- dialog_vars.input_result);
- assert_ptr(dialog_vars.input_result, "dlg_add_result realloc");
- }
- }
- strcat(dialog_vars.input_result, string);
-}
-
-/*
- * These are characters that (aside from the quote-delimiter) will have to
- * be escaped in a single- or double-quoted string.
- */
-#define FIX_SINGLE "\n\\"
-#define FIX_DOUBLE FIX_SINGLE "[]{}?*;`~#$^&()|<>"
-
-/*
- * Returns the quote-delimiter.
- */
-static const char *
-quote_delimiter(void)
-{
- return dialog_vars.single_quoted ? "'" : "\"";
-}
-
-/*
- * Returns true if we should quote the given string.
- */
-static bool
-must_quote(char *string)
-{
- bool code = FALSE;
-
- if (*string != '\0') {
- size_t len = strlen(string);
- if (strcspn(string, quote_delimiter()) != len)
- code = TRUE;
- else if (strcspn(string, "\n\t ") != len)
- code = TRUE;
- else
- code = (strcspn(string, FIX_DOUBLE) != len);
- } else {
- code = TRUE;
- }
-
- return code;
-}
-
-/*
- * Add a quoted string to the result buffer.
- */
-void
-dlg_add_quoted(char *string)
-{
- char temp[2];
- const char *my_quote = quote_delimiter();
- const char *must_fix = (dialog_vars.single_quoted
- ? FIX_SINGLE
- : FIX_DOUBLE);
-
- if (must_quote(string)) {
- temp[1] = '\0';
- dlg_add_result(my_quote);
- while (*string != '\0') {
- temp[0] = *string++;
- if ((strchr) (my_quote, *temp) || (strchr) (must_fix, *temp))
- dlg_add_result("\\");
- dlg_add_result(temp);
- }
- dlg_add_result(my_quote);
- } else {
- dlg_add_result(string);
- }
-}
-
-/*
- * When adding a result, make that depend on whether "--quoted" is used.
- */
-void
-dlg_add_string(char *string)
-{
- if (dialog_vars.quoted) {
- dlg_add_quoted(string);
- } else {
- dlg_add_result(string);
- }
-}
-
-bool
-dlg_need_separator(void)
-{
- bool result = FALSE;
-
- if (dialog_vars.output_separator) {
- result = TRUE;
- } else if (dialog_vars.input_result && *(dialog_vars.input_result)) {
- result = TRUE;
- }
- return result;
-}
-
-void
-dlg_add_separator(void)
-{
- const char *separator = (dialog_vars.separate_output) ? "\n" : " ";
-
- if (dialog_vars.output_separator)
- separator = dialog_vars.output_separator;
-
- dlg_add_result(separator);
-}
-
-#define HELP_PREFIX "HELP "
-
-void
-dlg_add_help_listitem(int *result, char **tag, DIALOG_LISTITEM * item)
-{
- dlg_add_result(HELP_PREFIX);
- if (USE_ITEM_HELP(item->help)) {
- *tag = dialog_vars.help_tags ? item->name : item->help;
- *result = DLG_EXIT_ITEM_HELP;
- } else {
- *tag = item->name;
- }
-}
-
-void
-dlg_add_help_formitem(int *result, char **tag, DIALOG_FORMITEM * item)
-{
- dlg_add_result(HELP_PREFIX);
- if (USE_ITEM_HELP(item->help)) {
- *tag = dialog_vars.help_tags ? item->name : item->help;
- *result = DLG_EXIT_ITEM_HELP;
- } else {
- *tag = item->name;
- }
-}
-
-/*
- * Some widgets support only one value of a given variable - save/restore the
- * global dialog_vars so we can override it consistently.
- */
-void
-dlg_save_vars(DIALOG_VARS * vars)
-{
- *vars = dialog_vars;
-}
-
-/*
- * Most of the data in DIALOG_VARS is normally set by command-line options.
- * The input_result member is an exception; it is normally set by the dialog
- * library to return result values.
- */
-void
-dlg_restore_vars(DIALOG_VARS * vars)
-{
- char *save_result = dialog_vars.input_result;
- unsigned save_length = dialog_vars.input_length;
-
- dialog_vars = *vars;
- dialog_vars.input_result = save_result;
- dialog_vars.input_length = save_length;
-}
-
-/*
- * Called each time a widget is invoked which may do output, increment a count.
- */
-void
-dlg_does_output(void)
-{
- dialog_state.output_count += 1;
-}
-
-/*
- * Compatibility for different versions of curses.
- */
-#if !(defined(HAVE_GETBEGX) && defined(HAVE_GETBEGY))
-int
-dlg_getbegx(WINDOW *win)
-{
- int y, x;
- getbegyx(win, y, x);
- (void) y;
- return x;
-}
-int
-dlg_getbegy(WINDOW *win)
-{
- int y, x;
- getbegyx(win, y, x);
- (void) x;
- return y;
-}
-#endif
-
-#if !(defined(HAVE_GETCURX) && defined(HAVE_GETCURY))
-int
-dlg_getcurx(WINDOW *win)
-{
- int y, x;
- getyx(win, y, x);
- (void) y;
- return x;
-}
-int
-dlg_getcury(WINDOW *win)
-{
- int y, x;
- getyx(win, y, x);
- (void) x;
- return y;
-}
-#endif
-
-#if !(defined(HAVE_GETMAXX) && defined(HAVE_GETMAXY))
-int
-dlg_getmaxx(WINDOW *win)
-{
- int y, x;
- getmaxyx(win, y, x);
- (void) y;
- return x;
-}
-int
-dlg_getmaxy(WINDOW *win)
-{
- int y, x;
- getmaxyx(win, y, x);
- (void) x;
- return y;
-}
-#endif
-
-#if !(defined(HAVE_GETPARX) && defined(HAVE_GETPARY))
-int
-dlg_getparx(WINDOW *win)
-{
- int y, x;
- getparyx(win, y, x);
- (void) y;
- return x;
-}
-int
-dlg_getpary(WINDOW *win)
-{
- int y, x;
- getparyx(win, y, x);
- (void) x;
- return y;
-}
-#endif
-
-#ifdef NEED_WGETPARENT
-WINDOW *
-dlg_wgetparent(WINDOW *win)
-{
-#undef wgetparent
- WINDOW *result = 0;
- DIALOG_WINDOWS *p;
-
- for (p = dialog_state.all_subwindows; p != 0; p = p->next) {
- if (p->shadow == win) {
- result = p->normal;
- break;
- }
- }
- return result;
-}
-#endif
Index: sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/dialog.m4
===================================================================
--- sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/dialog.m4 (revision 33)
+++ sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/dialog.m4 (nonexistent)
@@ -1,324 +0,0 @@
-dnl #
-dnl # /usr/share/aclocal/dialog.m4
-dnl #
-dnl # Configure paths for dialog
-dnl # Andrew V.Kosteltsev
-
-dnl ============================================================
-dnl
-dnl Synopsis:
-dnl AC_CHECK_DIALOG([MIN-VERSION [, # minimum dialog version, e.g. 1.3-20190211
-dnl DEFAULT-WITH-DIALOG [, # default value for --with-dialog option
-dnl DEFAULT-WITH-DIALOG-TEST [,# default value for --with-dialog-test option
-dnl EXTEND-VARS [, # whether CFLAGS/LDFLAGS/etc are extended
-dnl ACTION-IF-FOUND [, # action to perform if dialog was found
-dnl ACTION-IF-NOT-FOUND # action to perform if dialog was not found
-dnl ]]]]]])
-dnl Examples:
-dnl AC_CHECK_DIALOG(1.3-20210621)
-dnl AC_CHECK_DIALOG(1.3-20210621,,,no,CFLAGS="$CFLAGS -DHAVE_DIALOG $DIALOG_CFLAGS")
-dnl AC_CHECK_DIALOG(1.3-20210621,yes,yes,yes,CFLAGS="$CFLAGS -DHAVE_DIALOG")
-dnl
-dnl
-dnl If you have to change prefix returned by dialog-config script or change
-dnl location of dialog-config, you may set environment variable DIALOG_CONFIG,
-dnl for example:
-dnl
-dnl # export DIALOG_CONFIG="dialog-config --prefix=/usr/local"
-dnl # export DIALOG_CONFIG="/usr/bin/dialog-config --prefix=/usr/local"
-dnl
-dnl ============================================================
-dnl
-dnl ============================================================
-dnl auxilliary macros
-dnl ============================================================
-AC_DEFUN([_AC_DIALOG_ERROR], [dnl
-AC_MSG_RESULT([*FAILED*])
-cat <<EOT | sed -e 's/^[[ ]]*/ | /' -e 's/>>/ /' 1>&2
-$1
-EOT
-exit 1
-])
-
-AC_DEFUN([_AC_DIALOG_VERBOSE], [dnl
-if test ".$verbose" = .yes; then
- AC_MSG_RESULT([ $1])
-fi
-])
-
-dnl ============================================================
-dnl the user macro
-dnl ============================================================
-AC_DEFUN([AC_CHECK_DIALOG], [dnl
-dnl
-dnl ============================================================
-dnl prerequisites
-dnl ============================================================
-AC_REQUIRE([AC_PROG_CC])dnl
-AC_REQUIRE([AC_PROG_CPP])dnl
-dnl
-dnl ============================================================
-dnl set DIALOG_CONFIG variable
-dnl ============================================================
-if test -z "$DIALOG_CONFIG"; then
- DIALOG_CONFIG='dialog-config'
-fi
-dnl
-DIALOG_CFLAGS=''
-DIALOG_LDFLAGS=''
-DIALOG_LIBS=''
-AC_SUBST(DIALOG_CFLAGS)
-AC_SUBST(DIALOG_LDFLAGS)
-AC_SUBST(DIALOG_LIBS)
-dnl
-dnl ============================================================
-dnl command line options
-dnl ============================================================
-_AC_DIALOG_VERBOSE([])
-AC_ARG_WITH(dialog,dnl
-[ --with-dialog[=ARG] Build with dialog Library (default=]ifelse([$2],,yes,$2)[)],dnl
-,dnl
-with_dialog="ifelse([$2],,yes,$2)"
-)dnl
-AC_ARG_WITH(dialog-test,dnl
-[ --with-dialog-test Perform dialog Sanity Test (default=]ifelse([$3],,yes,$3)[)],dnl
-,dnl
-with_dialog_test="ifelse([$3],,yes,$3)"
-)dnl
-_AC_DIALOG_VERBOSE([+ Command Line Options:])
-_AC_DIALOG_VERBOSE([ o --with-dialog=$with_dialog])
-_AC_DIALOG_VERBOSE([ o --with-dialog-test=$with_dialog_test])
-dnl
-dnl ============================================================
-dnl configuration
-dnl ============================================================
-if test ".$with_dialog" != .no; then
- dialog_subdir=no
- dialog_subdir_opts=''
- case "$with_dialog" in
- subdir:* )
- dialog_subdir=yes
- changequote(, )dnl
- dialog_subdir_opts=`echo $with_dialog | sed -e 's/^subdir:[^ ]*[ ]*//'`
- with_dialog=`echo $with_dialog | sed -e 's/^subdir:\([^ ]*\).*$/\1/'`
- changequote([, ])dnl
- ;;
- esac
- dialog_version=""
- dialog_location=""
- dialog_type=""
- dialog_cflags=""
- dialog_ldflags=""
- dialog_libs=""
- if test ".$with_dialog" = .yes; then
- # via config script in $PATH
- changequote(, )dnl
- dialog_version=`($DIALOG_CONFIG --version) 2>/dev/null |\
- sed -e 's/^.*\([0-9]\.[0-9]*[-][0-9]*\).*$/\1/'`
- changequote([, ])dnl
- if test ".$dialog_version" != .; then
- dialog_location=`$DIALOG_CONFIG --prefix`
- dialog_type='installed'
- dialog_cflags=`$DIALOG_CONFIG --cflags`
- dialog_ldflags=`$DIALOG_CONFIG --ldflags`
- dialog_libs=`$DIALOG_CONFIG --libs`
- fi
- elif test -d "$with_dialog"; then
- with_dialog=`echo $with_dialog | sed -e 's;/*$;;'`
- dialog_found=no
- # via config script under a specified directory
- # (a standard installation, but not a source tree)
- if test ".$dialog_found" = .no; then
- for _dir in $with_dialog/bin $with_dialog; do
- if test -f "$_dir/dialog-config"; then
- test -f "$_dir/dialog-config.in" && continue # dialog-config in source tree!
- changequote(, )dnl
- dialog_version=`($_dir/dialog-config --version) 2>/dev/null |\
- sed -e 's/^.*\([0-9]\.[0-9]*[.][0-9]*\).*$/\1/'`
- changequote([, ])dnl
- if test ".$dialog_version" != .; then
- dialog_location=`$_dir/dialog-config --prefix`
- dialog_type="installed"
- dialog_cflags=`$_dir/dialog-config --cflags`
- dialog_ldflags=`$_dir/dialog-config --ldflags`
- dialog_libs=`$_dir/dialog-config --libs`
- dialog_found=yes
- break
- fi
- fi
- done
- fi
- fi
- _AC_DIALOG_VERBOSE([+ Determined Location:])
- _AC_DIALOG_VERBOSE([ o path: $dialog_location])
- _AC_DIALOG_VERBOSE([ o type: $dialog_type])
- if test ".$dialog_version" = .; then
- if test ".$with_dialog" != .yes; then
- _AC_DIALOG_ERROR([dnl
- Unable to locate dialog under $with_dialog.
- Please specify the correct path to either a dialog installation tree
- (use --with-dialog=DIR if you used --prefix=DIR for installing dialog in
- the past).])
- else
- _AC_DIALOG_ERROR([dnl
- Unable to locate dialog in any system-wide location (see \$PATH).
- Please specify the correct path to either a dialog installation tree
- (use --with-dialog=DIR if you used --prefix=DIR for installing dialog in
- the past, or set the DIALOG_CONFIG environment variable to the full path
- to dialog-config).])
- fi
- fi
- dnl ========================================================
- dnl Check whether the found version is sufficiently new
- dnl ========================================================
- _req_version="ifelse([$1],,1.0.0,$1)"
- for _var in dialog_version _req_version; do
- eval "_val=\"\$${_var}\""
- _major=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[.]]\)\([[0-9]]*\)/\1/'`
- _minor=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[.]]\)\([[0-9]]*\)/\2/'`
- _micro=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[.]]\)\([[0-9]]*\)/\4/'`
- _hex=`echo dummy | awk '{ printf("%d%02d%02d", major, minor, micro); }' \
- "major=$_major" "minor=$_minor" "micro=$_micro"`
- eval "${_var}_hex=\"\$_hex\""
- done
- _AC_DIALOG_VERBOSE([+ Determined Versions:])
- _AC_DIALOG_VERBOSE([ o existing: $dialog_version -> 0x$dialog_version_hex])
- _AC_DIALOG_VERBOSE([ o required: $_req_version -> 0x$_req_version_hex])
- _ok=0
- if test ".$dialog_version_hex" != .; then
- if test ".$_req_version_hex" != .; then
- if test $dialog_version_hex -ge $_req_version_hex; then
- _ok=1
- fi
- fi
- fi
- if test ".$_ok" = .0; then
- _AC_DIALOG_ERROR([dnl
- Found dialog version $dialog_version, but required at least version $_req_version.
- Upgrade dialog under $dialog_location to $_req_version or higher first, please.])
- fi
- dnl ========================================================
- dnl Perform dialog Sanity Compile Check
- dnl ========================================================
- if test ".$with_dialog_test" = .yes; then
- _ac_save_CFLAGS="$CFLAGS"
- _ac_save_LDFLAGS="$LDFLAGS"
- _ac_save_LIBS="$LIBS"
- CFLAGS="$CFLAGS $dialog_cflags"
- LDFLAGS="$LDFLAGS $dialog_ldflags"
- LIBS="$LIBS $dialog_libs"
- _AC_DIALOG_VERBOSE([+ Test Build Environment:])
- _AC_DIALOG_VERBOSE([ o CFLAGS="$CFLAGS"])
- _AC_DIALOG_VERBOSE([ o LDFLAGS="$LDFLAGS"])
- _AC_DIALOG_VERBOSE([ o LIBS="$LIBS"])
- cross_compile=no
- define([_code1], [
-#include <stdlib.h>
-#include <stdio.h>
-#include <strings.h> /* index(3) */
-
-#include <dialog.h>
-#include <dlg_colors.h>
-#include <dlg_keys.h>
- ])
- define([_code2], [
- int status = 0;
-
- bzero( (void *)&dialog_vars, sizeof(DIALOG_VARS) );
-
- init_dialog(stdin, stdout);
-
- dialog_vars.colors = 1;
- dialog_vars.backtitle = "Test dialog Library";
- dialog_vars.dlg_clear_screen = 1;
- dialog_vars.sleep_secs = 1;
-
-
- dlg_put_backtitle();
-
- /*************************************************
- Ruler: 68 characters + 2 spaces left and right:
-
- | ----handy-ruler----------------------------------------------------- | */
- status = dialog_msgbox( " Dialog ==>libdialog<== [required] ",
- "\nPackage is installed and corect.\n",
- 5, 72, 0 );
-
- if( dialog_vars.sleep_secs )
- (void)napms(dialog_vars.sleep_secs * 1000);
-
- if( dialog_vars.dlg_clear_screen )
- {
- dlg_clear();
- (void)refresh();
- }
- end_dialog();
- ])
- _AC_DIALOG_VERBOSE([+ Performing Sanity Checks:])
- _AC_DIALOG_VERBOSE([ o pre-processor test])
- AC_PREPROC_IFELSE([AC_LANG_PROGRAM([_code1], [_code2])], [_ok=yes], [_ok=no])
- if test ".$_ok" != .yes; then
- _AC_DIALOG_ERROR([dnl
- Found dialog $dialog_version under $dialog_location, but
- was unable to perform a sanity pre-processor check. This means
- the dialog header dialog.h was not found.
- We used the following build environment:
- >> CPP="$CPP"
- See config.log for possibly more details.])
- fi
- _AC_DIALOG_VERBOSE([ o link check])
- AC_LINK_IFELSE([AC_LANG_PROGRAM([_code1], [_code2])], [_ok=yes], [_ok=no])
- if test ".$_ok" != .yes; then
- _AC_DIALOG_ERROR([dnl
- Found dialog $dialog_version under $dialog_location, but
- was unable to perform a sanity linker check. This means
- the dialog library libdialog.a was not found.
- We used the following build environment:
- >> CC="$CC"
- >> CFLAGS="$CFLAGS"
- >> LDFLAGS="$LDFLAGS"
- >> LIBS="$LIBS"
- See config.log for possibly more details.])
- fi
- _extendvars="ifelse([$4],,yes,$4)"
- if test ".$_extendvars" != .yes; then
- CFLAGS="$_ac_save_CFLAGS"
- LDFLAGS="$_ac_save_LDFLAGS"
- LIBS="$_ac_save_LIBS"
- fi
- else
- _extendvars="ifelse([$4],,yes,$4)"
- if test ".$_extendvars" = .yes; then
- if test ".$dialog_subdir" = .yes; then
- CFLAGS="$CFLAGS $dialog_cflags"
- LDFLAGS="$LDFLAGS $dialog_ldflags"
- LIBS="$LIBS $dialog_libs"
- fi
- fi
- fi
- DIALOG_CFLAGS="$dialog_cflags"
- DIALOG_LDFLAGS="$dialog_ldflags"
- DIALOG_LIBS="$dialog_libs"
- AC_SUBST(DIALOG_CFLAGS)
- AC_SUBST(DIALOG_LDFLAGS)
- AC_SUBST(DIALOG_LIBS)
-
- AC_SUBST(HAVE_DIALOG, [1])
-
- AC_CHECK_HEADERS(dialog.h dlg_colors.h dlg_keys.h)
-
- _AC_DIALOG_VERBOSE([+ Final Results:])
- _AC_DIALOG_VERBOSE([ o DIALOG_CFLAGS="$DIALOG_CFLAGS"])
- _AC_DIALOG_VERBOSE([ o DIALOG_LDFLAGS="$DIALOG_LDFLAGS"])
- _AC_DIALOG_VERBOSE([ o DIALOG_LIBS="$DIALOG_LIBS"])
-fi
-if test ".$with_dialog" != .no; then
- AC_MSG_CHECKING(for libdialog)
- AC_MSG_RESULT([version $dialog_version, $dialog_type under $dialog_location])
- ifelse([$5], , :, [$5])
-else
- AC_MSG_CHECKING(for libdialog)
- AC_MSG_RESULT([no])
- ifelse([$6], , :, [$6])
-fi
-])
Index: sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/treeview.c
===================================================================
--- sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/treeview.c (revision 33)
+++ sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new/treeview.c (nonexistent)
@@ -1,675 +0,0 @@
-/*
- * $Id: treeview.c,v 1.43 2020/11/23 00:38:31 tom Exp $
- *
- * treeview.c -- implements the treeview dialog
- *
- * Copyright 2012-2019,2020 Thomas E. Dickey
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License, version 2.1
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to
- * Free Software Foundation, Inc.
- * 51 Franklin St., Fifth Floor
- * Boston, MA 02110, USA.
- */
-
-#include <dlg_internals.h>
-#include <dlg_keys.h>
-
-#define INDENT 3
-#define MIN_HIGH (1 + (5 * MARGIN))
-
-typedef struct {
- /* the outer-window */
- WINDOW *dialog;
- bool is_check;
- int box_y;
- int box_x;
- int check_x;
- int item_x;
- int use_height;
- int use_width;
- /* the inner-window */
- WINDOW *list;
- DIALOG_LISTITEM *items;
- int item_no;
- int *depths;
- const char *states;
-} ALL_DATA;
-
-/*
- * Print list item. The 'selected' parameter is true if 'choice' is the
- * current item. That one is colored differently from the other items.
- */
-static void
-print_item(ALL_DATA * data,
- DIALOG_LISTITEM * item,
- const char *states,
- int depths,
- int choice,
- int selected)
-{
- WINDOW *win = data->list;
- chtype save = dlg_get_attrs(win);
- int i;
- bool first = TRUE;
- int climit = (getmaxx(win) - data->check_x + 1);
- const char *show = (dialog_vars.no_items
- ? item->name
- : item->text);
-
- /* Clear 'residue' of last item */
- dlg_attrset(win, menubox_attr);
- (void) wmove(win, choice, 0);
- for (i = 0; i < data->use_width; i++)
- (void) waddch(win, ' ');
-
- (void) wmove(win, choice, data->check_x);
- dlg_attrset(win, selected ? check_selected_attr : check_attr);
- (void) wprintw(win,
- data->is_check ? "[%c]" : "(%c)",
- states[item->state]);
- dlg_attrset(win, menubox_attr);
-
- dlg_attrset(win, selected ? item_selected_attr : item_attr);
- for (i = 0; i < depths; ++i) {
- int j;
- (void) wmove(win, choice, data->item_x + INDENT * i);
- (void) waddch(win, ACS_VLINE);
- for (j = INDENT - 1; j > 0; --j)
- (void) waddch(win, ' ');
- }
- (void) wmove(win, choice, data->item_x + INDENT * depths);
-
- dlg_print_listitem(win, show, climit, first, selected);
-
- if (selected) {
- dlg_item_help(item->help);
- }
- dlg_attrset(win, save);
-}
-
-static void
-print_list(ALL_DATA * data,
- int choice,
- int scrollamt,
- int max_choice)
-{
- int i;
- int cur_y, cur_x;
-
- getyx(data->dialog, cur_y, cur_x);
-
- for (i = 0; i < max_choice; i++) {
- print_item(data,
- &data->items[scrollamt + i],
- data->states,
- data->depths[scrollamt + i],
- i, i == choice);
- }
- (void) wnoutrefresh(data->list);
-
- dlg_draw_scrollbar(data->dialog,
- (long) (scrollamt),
- (long) (scrollamt),
- (long) (scrollamt + max_choice),
- (long) (data->item_no),
- data->box_x + data->check_x,
- data->box_x + data->use_width,
- data->box_y,
- data->box_y + data->use_height + 1,
- menubox_border2_attr,
- menubox_border_attr);
-
- (void) wmove(data->dialog, cur_y, cur_x);
-}
-
-static bool
-check_hotkey(DIALOG_LISTITEM * items, int choice)
-{
- bool result = FALSE;
-
- if (dlg_match_char(dlg_last_getc(),
- (dialog_vars.no_tags
- ? items[choice].text
- : items[choice].name))) {
- result = TRUE;
- }
- return result;
-}
-
-/*
- * This is an alternate interface to 'treeview' which allows the application
- * to read the list item states back directly without putting them in the
- * output buffer.
- */
-int
-dlg_treeview(const char *title,
- const char *cprompt,
- int height,
- int width,
- int list_height,
- int item_no,
- DIALOG_LISTITEM * items,
- const char *states,
- int *depths,
- int flag,
- int *current_item)
-{
- /* *INDENT-OFF* */
- static DLG_KEYS_BINDING binding[] = {
- HELPKEY_BINDINGS,
- ENTERKEY_BINDINGS,
- DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ),
- DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ),
- DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ),
- DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ),
- DLG_KEYS_DATA( DLGK_ITEM_FIRST, KEY_HOME ),
- DLG_KEYS_DATA( DLGK_ITEM_LAST, KEY_END ),
- DLG_KEYS_DATA( DLGK_ITEM_LAST, KEY_LL ),
- DLG_KEYS_DATA( DLGK_ITEM_NEXT, '+' ),
- DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_DOWN ),
- DLG_KEYS_DATA( DLGK_ITEM_NEXT, CHR_NEXT ),
- DLG_KEYS_DATA( DLGK_ITEM_PREV, '-' ),
- DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_UP ),
- DLG_KEYS_DATA( DLGK_ITEM_PREV, CHR_PREVIOUS ),
- DLG_KEYS_DATA( DLGK_PAGE_NEXT, KEY_NPAGE ),
- DLG_KEYS_DATA( DLGK_PAGE_NEXT, DLGK_MOUSE(KEY_NPAGE) ),
- DLG_KEYS_DATA( DLGK_PAGE_PREV, KEY_PPAGE ),
- DLG_KEYS_DATA( DLGK_PAGE_PREV, DLGK_MOUSE(KEY_PPAGE) ),
- TOGGLEKEY_BINDINGS,
- END_KEYS_BINDING
- };
- /* *INDENT-ON* */
-
-#ifdef KEY_RESIZE
- int old_height = height;
- int old_width = width;
-#endif
- ALL_DATA all;
- int i, j, key2, found, x, y, cur_y, box_x, box_y;
- int key, fkey;
- int button = dialog_state.visit_items ? -1 : dlg_default_button();
- int choice = dlg_default_listitem(items);
- int scrollamt = 0;
- int max_choice;
- int use_height;
- int use_width, name_width, text_width, tree_width;
- int result = DLG_EXIT_UNKNOWN;
- int num_states;
- WINDOW *dialog, *list;
- char *prompt = dlg_strclone(cprompt);
- const char **buttons = dlg_ok_labels();
- const char *widget_name;
-
- /* we need at least two states */
- if (states == 0 || strlen(states) < 2)
- states = " *";
- num_states = (int) strlen(states);
-
- dialog_state.plain_buttons = TRUE;
-
- memset(&all, 0, sizeof(all));
- all.items = items;
- all.item_no = item_no;
- all.states = states;
- all.depths = depths;
-
- dlg_does_output();
- dlg_tab_correct_str(prompt);
-
- /*
- * If this is a radiobutton list, ensure that no more than one item is
- * selected initially. Allow none to be selected, since some users may
- * wish to provide this flavor.
- */
- if (flag == FLAG_RADIO) {
- bool first = TRUE;
-
- for (i = 0; i < item_no; i++) {
- if (items[i].state) {
- if (first) {
- first = FALSE;
- } else {
- items[i].state = 0;
- }
- }
- }
- } else {
- all.is_check = TRUE;
- }
- widget_name = "treeview";
-#ifdef KEY_RESIZE
- retry:
-#endif
-
- use_height = list_height;
- use_width = dlg_calc_list_width(item_no, items) + 10;
- use_width = MAX(26, use_width);
- if (use_height == 0) {
- /* calculate height without items (4) */
- dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, use_width);
- dlg_calc_listh(&height, &use_height, item_no);
- } else {
- dlg_auto_size(title, prompt, &height, &width, MIN_HIGH + use_height, use_width);
- }
- dlg_button_layout(buttons, &width);
- dlg_print_size(height, width);
- dlg_ctl_size(height, width);
-
- x = dlg_box_x_ordinate(width);
- y = dlg_box_y_ordinate(height);
-
- dialog = dlg_new_window(height, width, y, x);
- dlg_register_window(dialog, widget_name, binding);
- dlg_register_buttons(dialog, widget_name, buttons);
-
- dlg_mouse_setbase(x, y);
-
- dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr);
- dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
- dlg_draw_title(dialog, title);
-
- dlg_attrset(dialog, dialog_attr);
- dlg_print_autowrap(dialog, prompt, height, width);
-
- all.use_width = width - 4;
- cur_y = getcury(dialog);
- box_y = cur_y + 1;
- box_x = (width - all.use_width) / 2 - 1;
-
- /*
- * After displaying the prompt, we know how much space we really have.
- * Limit the list to avoid overwriting the ok-button.
- */
- if (use_height + MIN_HIGH > height - cur_y)
- use_height = height - MIN_HIGH - cur_y;
- if (use_height <= 0)
- use_height = 1;
-
- max_choice = MIN(use_height, item_no);
-
- /* create new window for the list */
- list = dlg_sub_window(dialog, use_height, all.use_width,
- y + box_y + 1, x + box_x + 1);
-
- /* draw a box around the list items */
- dlg_draw_box(dialog, box_y, box_x,
- use_height + 2 * MARGIN,
- all.use_width + 2 * MARGIN,
- menubox_border_attr, menubox_border2_attr);
-
- text_width = 0;
- name_width = 0;
- tree_width = 0;
- /* Find length of longest item to center treeview */
- for (i = 0; i < item_no; i++) {
- tree_width = MAX(tree_width, INDENT * depths[i]);
- text_width = MAX(text_width, dlg_count_columns(items[i].text));
- name_width = MAX(name_width, dlg_count_columns(items[i].name));
- }
- if (dialog_vars.no_tags && !dialog_vars.no_items) {
- tree_width += text_width;
- } else if (dialog_vars.no_items) {
- tree_width += name_width;
- } else {
- tree_width += (text_width + name_width);
- }
-
- use_width = (all.use_width - 4);
- tree_width = MIN(tree_width, all.use_width);
-
- all.check_x = (use_width - tree_width) / 2;
- all.item_x = ((dialog_vars.no_tags
- ? 0
- : (dialog_vars.no_items
- ? 0
- : (2 + name_width)))
- + all.check_x + 4);
-
- /* ensure we are scrolled to show the current choice */
- if (choice >= (max_choice + scrollamt)) {
- scrollamt = choice - max_choice + 1;
- choice = max_choice - 1;
- }
-
- /* register the new window, along with its borders */
- dlg_mouse_mkbigregion(box_y + 1, box_x,
- use_height, all.use_width + 2,
- KEY_MAX, 1, 1, 1 /* by lines */ );
-
- all.dialog = dialog;
- all.box_x = box_x;
- all.box_y = box_y;
- all.use_height = use_height;
- all.list = list;
- print_list(&all, choice, scrollamt, max_choice);
-
- dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width);
-
- dlg_trace_win(dialog);
-
- while (result == DLG_EXIT_UNKNOWN) {
- int was_mouse;
-
- if (button < 0) /* --visit-items */
- wmove(dialog, box_y + choice + 1, box_x + all.check_x + 2);
-
- key = dlg_mouse_wgetch(dialog, &fkey);
- if (dlg_result_key(key, fkey, &result)) {
- if (!dlg_button_key(result, &button, &key, &fkey))
- break;
- }
-
- was_mouse = (fkey && is_DLGK_MOUSE(key));
- if (was_mouse)
- key -= M_EVENT;
-
- if (was_mouse && (key >= KEY_MAX)) {
- i = (key - KEY_MAX);
- if (i < max_choice) {
- choice = (key - KEY_MAX);
- print_list(&all, choice, scrollamt, max_choice);
-
- key = DLGK_TOGGLE; /* force the selected item to toggle */
- } else {
- beep();
- continue;
- }
- fkey = FALSE;
- } else if (was_mouse && key >= KEY_MIN) {
- key = dlg_lookup_key(dialog, key, &fkey);
- }
-
- /*
- * A space toggles the item status.
- */
- if (key == DLGK_TOGGLE) {
- int current = scrollamt + choice;
- int next = items[current].state + 1;
-
- if (next >= num_states)
- next = 0;
-
- if (flag == FLAG_CHECK) { /* checklist? */
- items[current].state = next;
- } else {
- for (i = 0; i < item_no; i++) {
- if (i != current) {
- items[i].state = 0;
- }
- }
- if (items[current].state) {
- items[current].state = next ? next : 1;
- } else {
- items[current].state = 1;
- }
- }
- print_list(&all, choice, scrollamt, max_choice);
- continue; /* wait for another key press */
- }
-
- /*
- * Check if key pressed matches first character of any item tag in
- * list. If there is more than one match, we will cycle through
- * each one as the same key is pressed repeatedly.
- */
- found = FALSE;
- if (!fkey) {
- if (button < 0 || !dialog_state.visit_items) {
- for (j = scrollamt + choice + 1; j < item_no; j++) {
- if (check_hotkey(items, j)) {
- found = TRUE;
- i = j - scrollamt;
- break;
- }
- }
- if (!found) {
- for (j = 0; j <= scrollamt + choice; j++) {
- if (check_hotkey(items, j)) {
- found = TRUE;
- i = j - scrollamt;
- break;
- }
- }
- }
- if (found)
- dlg_flush_getc();
- } else if ((j = dlg_char_to_button(key, buttons)) >= 0) {
- button = j;
- ungetch('\n');
- continue;
- }
- }
-
- /*
- * A single digit (1-9) positions the selection to that line in the
- * current screen.
- */
- if (!found
- && (key <= '9')
- && (key > '0')
- && (key - '1' < max_choice)) {
- found = TRUE;
- i = key - '1';
- }
-
- if (!found) {
- if (fkey) {
- found = TRUE;
- switch (key) {
- case DLGK_ITEM_FIRST:
- i = -scrollamt;
- break;
- case DLGK_ITEM_LAST:
- i = item_no - 1 - scrollamt;
- break;
- case DLGK_PAGE_PREV:
- if (choice)
- i = 0;
- else if (scrollamt != 0)
- i = -MIN(scrollamt, max_choice);
- else
- continue;
- break;
- case DLGK_PAGE_NEXT:
- i = MIN(choice + max_choice, item_no - scrollamt - 1);
- break;
- case DLGK_ITEM_PREV:
- i = choice - 1;
- if (choice == 0 && scrollamt == 0)
- continue;
- break;
- case DLGK_ITEM_NEXT:
- i = choice + 1;
- if (scrollamt + choice >= item_no - 1)
- continue;
- break;
- default:
- found = FALSE;
- break;
- }
- }
- }
-
- if (found) {
- if (i != choice) {
- if (i < 0 || i >= max_choice) {
- if (i < 0) {
- scrollamt += i;
- choice = 0;
- } else {
- choice = max_choice - 1;
- scrollamt += (i - max_choice + 1);
- }
- print_list(&all, choice, scrollamt, max_choice);
- } else {
- choice = i;
- print_list(&all, choice, scrollamt, max_choice);
- }
- }
- continue; /* wait for another key press */
- }
-
- if (fkey) {
- switch (key) {
- case DLGK_ENTER:
- result = dlg_enter_buttoncode(button);
- break;
- case DLGK_LEAVE:
- result = dlg_ok_buttoncode(button);
- break;
- case DLGK_FIELD_PREV:
- button = dlg_prev_button(buttons, button);
- dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
- FALSE, width);
- break;
- case DLGK_FIELD_NEXT:
- button = dlg_next_button(buttons, button);
- dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
- FALSE, width);
- break;
-#ifdef KEY_RESIZE
- case KEY_RESIZE:
- dlg_will_resize(dialog);
- /* reset data */
- height = old_height;
- width = old_width;
- /* repaint */
- _dlg_resize_cleanup(dialog);
- goto retry;
-#endif
- default:
- if (was_mouse) {
- if ((key2 = dlg_ok_buttoncode(key)) >= 0) {
- result = key2;
- break;
- }
- beep();
- }
- }
- } else if (key > 0) {
- beep();
- }
- }
-
- dlg_del_window(dialog);
- dlg_mouse_free_regions();
- free(prompt);
- *current_item = (scrollamt + choice);
- return result;
-}
-
-/*
- * Display a set of items as a tree.
- */
-int
-dialog_treeview(const char *title,
- const char *cprompt,
- int height,
- int width,
- int list_height,
- int item_no,
- char **items,
- int flag)
-{
- int result;
- int i, j;
- DIALOG_LISTITEM *listitems;
- int *depths;
- bool show_status = FALSE;
- int current = 0;
- char *help_result;
-
- DLG_TRACE(("# treeview args:\n"));
- DLG_TRACE2S("title", title);
- DLG_TRACE2S("message", cprompt);
- DLG_TRACE2N("height", height);
- DLG_TRACE2N("width", width);
- DLG_TRACE2N("lheight", list_height);
- DLG_TRACE2N("llength", item_no);
- /* FIXME dump the items[][] too */
- DLG_TRACE2N("flag", flag);
-
- listitems = dlg_calloc(DIALOG_LISTITEM, (size_t) item_no + 1);
- assert_ptr(listitems, "dialog_treeview");
-
- depths = dlg_calloc(int, (size_t) item_no + 1);
- assert_ptr(depths, "dialog_treeview");
-
- for (i = j = 0; i < item_no; ++i) {
- listitems[i].name = items[j++];
- listitems[i].text = (dialog_vars.no_items
- ? dlg_strempty()
- : items[j++]);
- listitems[i].state = !dlg_strcmp(items[j++], "on");
- depths[i] = atoi(items[j++]);
- listitems[i].help = ((dialog_vars.item_help)
- ? items[j++]
- : dlg_strempty());
- }
- dlg_align_columns(&listitems[0].text, (int) sizeof(DIALOG_LISTITEM), item_no);
-
- result = dlg_treeview(title,
- cprompt,
- height,
- width,
- list_height,
- item_no,
- listitems,
- NULL,
- depths,
- flag,
- ¤t);
-
- switch (result) {
- case DLG_EXIT_OK: /* FALLTHRU */
- case DLG_EXIT_EXTRA:
- show_status = TRUE;
- break;
- case DLG_EXIT_HELP:
- dlg_add_help_listitem(&result, &help_result, &listitems[current]);
- if ((show_status = dialog_vars.help_status)) {
- if (dialog_vars.separate_output) {
- dlg_add_string(help_result);
- dlg_add_separator();
- } else {
- dlg_add_quoted(help_result);
- }
- } else {
- dlg_add_string(help_result);
- }
- break;
- }
-
- if (show_status) {
- for (i = 0; i < item_no; i++) {
- if (listitems[i].state) {
- if (dlg_need_separator())
- dlg_add_separator();
- if (dialog_vars.separate_output) {
- dlg_add_string(listitems[i].name);
- } else {
- if (flag == FLAG_CHECK)
- dlg_add_quoted(listitems[i].name);
- else
- dlg_add_string(listitems[i].name);
- }
- }
- }
- AddLastKey();
- }
-
- dlg_free_columns(&listitems[0].text, (int) sizeof(DIALOG_LISTITEM), item_no);
- free(depths);
- free(listitems);
- return result;
-}
Index: sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new
===================================================================
--- sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new (revision 33)
+++ sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new (nonexistent)
Property changes on: sources/packages/dialog/create-1.3-20210621-patch/dialog-1.3-20210621-new
___________________________________________________________________
Deleted: svn:ignore
## -1,16 +0,0 ##
-
-# Target bin dirs
-etc
-gnattools
-sbin
-
-# Build system config files
-targets-config.mk
-
-# Target build dirs
-.host
-
-# Hidden files (each file)
-.makefile
-.src_requires
-.src_requires_depend
Index: sources/packages/dialog/create-1.3-20210621-patch
===================================================================
--- sources/packages/dialog/create-1.3-20210621-patch (revision 33)
+++ sources/packages/dialog/create-1.3-20210621-patch (nonexistent)
Property changes on: sources/packages/dialog/create-1.3-20210621-patch
___________________________________________________________________
Deleted: svn:ignore
## -1,16 +0,0 ##
-
-# Target bin dirs
-etc
-gnattools
-sbin
-
-# Build system config files
-targets-config.mk
-
-# Target build dirs
-.host
-
-# Hidden files (each file)
-.makefile
-.src_requires
-.src_requires_depend
Index: sources/packages/dialog/Makefile
===================================================================
--- sources/packages/dialog/Makefile (revision 33)
+++ sources/packages/dialog/Makefile (revision 34)
@@ -7,7 +7,7 @@
url = $(DOWNLOAD_SERVER)/sources/packages/a/dialog
-versions = 1.3-20210621
+versions = 1.3-20240101
pkgname = dialog
suffix = tgz
@@ -14,7 +14,7 @@
tarballs = $(addsuffix .$(suffix), $(addprefix $(pkgname)-, $(versions)))
sha1s = $(addsuffix .sha1sum, $(tarballs))
-patches = $(CURDIR)/patches/dialog-1.3-20210621.patch
+patches = $(CURDIR)/patches/dialog-1.3-20240101.patch
.NOTPARALLEL: $(patches)
@@ -49,7 +49,7 @@
$(patches): $(sha1s)
@echo -e "\n======= Create Patches =======\n" ; \
- ( cd create-1.3-20210621-patch ; ./create.patch.sh ) ; \
+ ( cd create-1.3-20240101-patch ; ./create.patch.sh ) ; \
echo -e "\n"
download_clean:
Index: sources/packages/dialog/create-1.3-20240101-patch/create.patch.sh
===================================================================
--- sources/packages/dialog/create-1.3-20240101-patch/create.patch.sh (nonexistent)
+++ sources/packages/dialog/create-1.3-20240101-patch/create.patch.sh (revision 34)
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+VERSION=1.3-20240101
+
+tar --files-from=file.list -xzvf ../dialog-$VERSION.tgz
+mv dialog-$VERSION dialog-$VERSION-orig
+
+cp -rf ./dialog-$VERSION-new ./dialog-$VERSION
+
+diff --unified -Nr dialog-$VERSION-orig dialog-$VERSION > dialog-$VERSION.patch
+
+mv dialog-$VERSION.patch ../patches
+
+rm -rf ./dialog-$VERSION
+rm -rf ./dialog-$VERSION-orig
Property changes on: sources/packages/dialog/create-1.3-20240101-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/buildlist.c
===================================================================
--- sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/buildlist.c (nonexistent)
+++ sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/buildlist.c (revision 34)
@@ -0,0 +1,1267 @@
+/*
+ * $Id: buildlist.c,v 1.95 2021/03/05 00:51:16 tom Exp $
+ *
+ * buildlist.c -- implements the buildlist dialog
+ *
+ * Copyright 2012-2020,2021 Thomas E. Dickey
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License, version 2.1
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to
+ * Free Software Foundation, Inc.
+ * 51 Franklin St., Fifth Floor
+ * Boston, MA 02110, USA.
+ */
+
+#include <dlg_internals.h>
+#include <dlg_keys.h>
+
+/*
+ * Visually like menubox, but two columns.
+ */
+
+#define sLEFT (-2)
+#define sRIGHT (-1)
+
+#define KEY_LEFTCOL '^'
+#define KEY_RIGHTCOL '$'
+
+#define MIN_HIGH (1 + (5 * MARGIN))
+
+typedef struct {
+ WINDOW *win;
+ int box_y;
+ int box_x;
+ int top_index;
+ int cur_index;
+ DIALOG_LISTITEM **ip; /* pointers to items in this list */
+} MY_DATA;
+
+#if 0
+#define TRACE(p) dlg_trace_msg p
+#else
+#define TRACE(p) /* nothing */
+#endif
+
+#define okIndex(all,index) ((index) >= 0 && (index) < (all)->item_no)
+
+#define myItem(p,n) ((p)->ip)[n]
+#define mySide(n) ((n)?"right":"left")
+
+typedef struct {
+ DIALOG_LISTITEM *items; /* all items in the widget */
+ int base_y; /* base for mouse coordinates */
+ int base_x;
+ int use_height; /* actual size of column box */
+ int use_width;
+ int item_no;
+ int check_x;
+ int item_x;
+ MY_DATA list[2];
+} ALL_DATA;
+
+/*
+ * Translate a choice from items[] to a row-number in an unbounded column,
+ * starting at zero.
+ */
+static int
+index2row(ALL_DATA * all, int choice, int selected)
+{
+ MY_DATA *data = all->list + selected;
+ int result = -1;
+
+ if (okIndex(all, choice)) {
+ int row;
+
+ for (row = 0; row < all->item_no; ++row) {
+ TRACE(("!... choice %d: %p vs row %d: %p\n",
+ choice, all->items + choice,
+ row, myItem(data, row)));
+ if (myItem(data, row) == all->items + choice) {
+ result = row;
+ break;
+ }
+ }
+ }
+ TRACE(("! index2row(choice %d, %s) = %d\n", choice, mySide(selected), result));
+ return result;
+}
+
+/*
+ * Convert a row-number back to an item number, i.e., index into items[].
+ */
+static int
+row2index(ALL_DATA * all, int row, int selected)
+{
+ MY_DATA *data = all->list + selected;
+ int result = -1;
+ int n;
+ for (n = 0; n < all->item_no; ++n) {
+ TRACE(("!... row %d: %p vs choice %d: %p\n",
+ row, myItem(data, row),
+ n, all->items + n));
+ if (myItem(data, row) == all->items + n) {
+ result = n;
+ break;
+ }
+ }
+ TRACE(("! row2index(row %d, %s) = %d\n", row, mySide(selected), result));
+ return result;
+}
+
+/*
+ * Print list item. The 'selected' parameter is true if 'choice' is the
+ * current item. That one is colored differently from the other items.
+ */
+static void
+print_item(ALL_DATA * all,
+ WINDOW *win,
+ DIALOG_LISTITEM * item,
+ int row,
+ int selected)
+{
+ chtype save = dlg_get_attrs(win);
+ int i;
+ bool both = (!dialog_vars.no_tags && !dialog_vars.no_items);
+ bool first = TRUE;
+ int climit = (all->item_x - all->check_x - 1);
+ const char *show = (dialog_vars.no_items
+ ? item->name
+ : item->text);
+
+ /* Clear 'residue' of last item */
+ dlg_attrset(win, menubox_attr);
+ (void) wmove(win, row, 0);
+ for (i = 0; i < getmaxx(win); i++)
+ (void) waddch(win, ' ');
+
+ (void) wmove(win, row, all->check_x);
+ dlg_attrset(win, menubox_attr);
+
+ if (both) {
+ dlg_print_listitem(win, item->name, climit, first, selected);
+ (void) waddch(win, ' ');
+ first = FALSE;
+ }
+
+ (void) wmove(win, row, all->item_x);
+ climit = (getmaxx(win) - all->item_x + 1);
+ dlg_print_listitem(win, show, climit, first, selected);
+
+ if (selected) {
+ dlg_item_help(item->help);
+ }
+ dlg_attrset(win, save);
+}
+
+/*
+ * Prints either the left (unselected) or right (selected) list.
+ */
+static void
+print_1_list(ALL_DATA * all,
+ int choice,
+ int selected)
+{
+ MY_DATA *data = all->list + selected;
+ DIALOG_LISTITEM *target = (okIndex(all, choice)
+ ? all->items + choice
+ : 0);
+ WINDOW *win = data->win;
+ int i, j;
+ int last = 0;
+ int top_row = index2row(all, data->top_index, selected);
+ int max_rows = getmaxy(win);
+
+ TRACE(("! print_1_list %d %s, top %d\n", choice, mySide(selected), top_row));
+ for (i = j = 0; j < max_rows; i++) {
+ int ii = i + top_row;
+ if (ii < 0) {
+ continue;
+ } else if (myItem(data, ii)) {
+ print_item(all,
+ win,
+ myItem(data, ii),
+ j, myItem(data, ii) == target);
+ last = ++j;
+ } else {
+ break;
+ }
+ }
+ if (wmove(win, last, 0) != ERR) {
+ while (waddch(win, ' ') != ERR) {
+ ;
+ }
+ }
+ (void) wnoutrefresh(win);
+}
+
+/*
+ * Return the previous item from the list, staying in the same column. If no
+ * further movement is possible, return the same choice as given.
+ */
+static int
+prev_item(ALL_DATA * all, int choice, int selected)
+{
+ int result = choice;
+ int row = index2row(all, choice, selected);
+ if (row > 0) {
+ row--;
+ result = row2index(all, row, selected);
+ }
+ TRACE(("! prev_item choice %d, %s = %d\n", choice, mySide(selected), result));
+ return result;
+}
+
+/*
+ * Return true if the given choice is on the first page in the current column.
+ */
+static bool
+stop_prev(ALL_DATA * all, int choice, int selected)
+{
+ return (prev_item(all, choice, selected) == choice);
+}
+
+static bool
+check_hotkey(DIALOG_LISTITEM * items, int choice, int selected)
+{
+ bool result = FALSE;
+
+ if ((items[choice].state != 0) == selected) {
+ if (dlg_match_char(dlg_last_getc(),
+ (dialog_vars.no_tags
+ ? items[choice].text
+ : items[choice].name))) {
+ result = TRUE;
+ }
+ }
+ return result;
+}
+
+/*
+ * Return the next item from the list, staying in the same column. If no
+ * further movement is possible, return the same choice as given.
+ */
+static int
+next_item(ALL_DATA * all, int choice, int selected)
+{
+ MY_DATA *data = all->list + selected;
+ int result = choice;
+ int row = index2row(all, choice, selected);
+ TRACE(("! given item %d, testing next-item on row %d\n", choice, row + 1));
+ if (myItem(data, row + 1)) {
+ result = row2index(all, row + 1, selected);
+ }
+ TRACE(("! next_item(%d, %s) ->%d\n", choice, mySide(selected), result));
+ return result;
+}
+
+/*
+ * Return the first choice from items[] for the given column.
+ */
+static int
+first_item(ALL_DATA * all, int selected)
+{
+ MY_DATA *data = all->list + selected;
+ int result = -1;
+
+ if (myItem(data, 0) != 0) {
+ int n;
+
+ for (n = 0; n < all->item_no; ++n) {
+ if (myItem(data, 0) == &all->items[n]) {
+ result = n;
+ break;
+ }
+ }
+ }
+ TRACE(("! first_item %s = %d\n", mySide(selected), result));
+ return result;
+}
+
+/*
+ * Return the last choice from items[] for the given column.
+ */
+static int
+last_item(ALL_DATA * all, int selected)
+{
+ MY_DATA *data = all->list + selected;
+ int result = -1;
+ int n;
+
+ for (n = 0; myItem(data, n) != 0; ++n) {
+ result = n;
+ }
+ if (result >= 0) {
+ result = row2index(all, result, selected);
+ }
+ TRACE(("! last_item %s = %d\n", mySide(selected), result));
+ return result;
+}
+
+static int
+skip_rows(ALL_DATA * all, int row, int skip, int selected)
+{
+ MY_DATA *data = all->list + selected;
+ int result = row;
+
+ if (skip > 0) {
+ int n;
+
+ for (n = row + 1; (n < all->item_no) && (n <= row + skip); ++n) {
+ if (myItem(data, n) == 0)
+ break;
+ result = n;
+ }
+ } else if (skip < 0) {
+ result -= skip;
+ if (result < 0)
+ result = 0;
+ }
+ TRACE(("! skip_rows row %d, skip %d, %s = %d\n",
+ row, skip, mySide(selected), result));
+ return result;
+}
+
+/*
+ * Find the closest item in the given column starting with the given choice.
+ */
+static int
+closest_item(ALL_DATA * all, int choice, int selected)
+{
+ int prev = choice;
+ int next = choice;
+ int result = choice;
+ int n;
+
+ for (n = choice; n >= 0; --n) {
+ if ((all->items[n].state != 0) == selected) {
+ prev = n;
+ break;
+ }
+ }
+ for (n = choice; n < all->item_no; ++n) {
+ if ((all->items[n].state != 0) == selected) {
+ next = n;
+ break;
+ }
+ }
+ if (prev != choice) {
+ result = prev;
+ if (next != choice) {
+ if ((choice - prev) > (next - choice)) {
+ result = next;
+ }
+ }
+ } else if (next != choice) {
+ result = next;
+ }
+ TRACE(("! XXX closest item choice %d, %s = %d\n",
+ choice, mySide(selected), result));
+ return result;
+}
+
+static void
+print_both(ALL_DATA * all,
+ int choice)
+{
+ int selected;
+ int cur_y, cur_x;
+ WINDOW *dialog = wgetparent(all->list[0].win);
+
+ TRACE(("! print_both %d\n", choice));
+ getyx(dialog, cur_y, cur_x);
+ for (selected = 0; selected < 2; ++selected) {
+ MY_DATA *data = all->list + selected;
+ WINDOW *win = data->win;
+ int thumb_top = index2row(all, data->top_index, selected);
+ int thumb_max = index2row(all, -1, selected);
+ int thumb_end = thumb_top + getmaxy(win);
+
+ print_1_list(all, choice, selected);
+
+ dlg_mouse_setcode(selected * KEY_MAX);
+ dlg_draw_scrollbar(dialog,
+ (long) (data->top_index),
+ (long) (thumb_top),
+ (long) MIN(thumb_end, thumb_max),
+ (long) thumb_max,
+ data->box_x + all->check_x,
+ data->box_x + getmaxx(win),
+ data->box_y,
+ data->box_y + getmaxy(win) + 1,
+ menubox_border2_attr,
+ menubox_border_attr);
+ }
+ (void) wmove(dialog, cur_y, cur_x);
+ dlg_mouse_setcode(0);
+}
+
+static void
+set_top_item(ALL_DATA * all, int choice, int selected)
+{
+ if (choice != all->list[selected].top_index) {
+ DLG_TRACE(("# set top of %s column to %d\n",
+ mySide(selected),
+ choice));
+ all->list[selected].top_index = choice;
+ }
+}
+
+/*
+ * Adjust the top-index as needed to ensure that it and the given item are
+ * visible.
+ */
+static void
+fix_top_item(ALL_DATA * all, int cur_item, int selected)
+{
+ int top_item = all->list[selected].top_index;
+ int cur_row = index2row(all, cur_item, selected);
+ int top_row = index2row(all, top_item, selected);
+
+ if (cur_row < top_row) {
+ top_item = cur_item;
+ } else if ((cur_row - top_row) >= all->use_height) {
+ top_item = row2index(all, cur_row + 1 - all->use_height, selected);
+ }
+ if (cur_row < all->use_height) {
+ top_item = row2index(all, 0, selected);
+ }
+ DLG_TRACE(("# fix_top_item(cur_item %d, %s) ->top_item %d\n",
+ cur_item, mySide(selected), top_item));
+ set_top_item(all, top_item, selected);
+}
+
+static void
+append_right_side(ALL_DATA * all, int choice)
+{
+ MY_DATA *data = &all->list[1];
+ int j;
+ for (j = 0; j < all->item_no; ++j) {
+ if (myItem(data, j) == 0) {
+ myItem(data, j) = &all->items[choice];
+ break;
+ }
+ }
+}
+
+static void
+amend_right_side(ALL_DATA * all, int choice)
+{
+ MY_DATA *data = &all->list[1];
+ int j, k;
+ for (j = 0; j < all->item_no; ++j) {
+ if (myItem(data, j) == &all->items[choice]) {
+ for (k = j; k < all->item_no; ++k) {
+ if ((myItem(data, k) = myItem(data, k + 1)) == 0)
+ break;
+ }
+ break;
+ }
+ }
+}
+
+static void
+fill_one_side(ALL_DATA * all, int selected)
+{
+ int i, j;
+ MY_DATA *data = all->list + selected;
+
+ for (i = j = 0; j < all->item_no; ++j) {
+ myItem(data, i) = 0;
+ if ((all->items[j].state != 0) == selected) {
+ myItem(data, i) = all->items + j;
+ TRACE(("! %s item[%d] %p = all[%d] %p\n",
+ mySide(selected),
+ i, myItem(data, i),
+ j, all->items + j));
+ ++i;
+ }
+ }
+ myItem(data, i) = 0;
+}
+
+static void
+fill_both_sides(ALL_DATA * all)
+{
+ int k;
+
+ for (k = 0; k < 2; ++k) {
+ fill_one_side(all, k);
+ }
+}
+
+/*
+ * This is an alternate interface to 'buildlist' which allows the application
+ * to read the list item states back directly without putting them in the
+ * output buffer.
+ */
+int
+dlg_buildlist(const char *title,
+ const char *cprompt,
+ int height,
+ int width,
+ int list_height,
+ int item_no,
+ DIALOG_LISTITEM * items,
+ const char *states,
+ int order_mode,
+ int *current_item)
+{
+#define THIS_FUNC "dlg_buildlist"
+ /* *INDENT-OFF* */
+ static DLG_KEYS_BINDING binding[] = {
+ HELPKEY_BINDINGS,
+ ENTERKEY_BINDINGS,
+ DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ),
+ DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ),
+ DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ),
+ DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ),
+ DLG_KEYS_DATA( DLGK_ITEM_FIRST, KEY_HOME ),
+ DLG_KEYS_DATA( DLGK_ITEM_LAST, KEY_END ),
+ DLG_KEYS_DATA( DLGK_ITEM_LAST, KEY_LL ),
+ DLG_KEYS_DATA( DLGK_ITEM_NEXT, '+' ),
+ DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_DOWN ),
+ DLG_KEYS_DATA( DLGK_ITEM_NEXT, CHR_NEXT ),
+ DLG_KEYS_DATA( DLGK_ITEM_PREV, '-' ),
+ DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_UP ),
+ DLG_KEYS_DATA( DLGK_ITEM_PREV, CHR_PREVIOUS ),
+ DLG_KEYS_DATA( DLGK_PAGE_NEXT, KEY_NPAGE ),
+ DLG_KEYS_DATA( DLGK_PAGE_NEXT, DLGK_MOUSE(KEY_NPAGE) ),
+ DLG_KEYS_DATA( DLGK_PAGE_NEXT, DLGK_MOUSE(KEY_NPAGE+KEY_MAX) ),
+ DLG_KEYS_DATA( DLGK_PAGE_PREV, KEY_PPAGE ),
+ DLG_KEYS_DATA( DLGK_PAGE_PREV, DLGK_MOUSE(KEY_PPAGE) ),
+ DLG_KEYS_DATA( DLGK_PAGE_PREV, DLGK_MOUSE(KEY_PPAGE+KEY_MAX) ),
+ DLG_KEYS_DATA( DLGK_GRID_LEFT, KEY_LEFTCOL ),
+ DLG_KEYS_DATA( DLGK_GRID_RIGHT, KEY_RIGHTCOL ),
+ TOGGLEKEY_BINDINGS,
+ END_KEYS_BINDING
+ };
+ /* *INDENT-ON* */
+
+#ifdef KEY_RESIZE
+ int old_height = height;
+ int old_width = width;
+#endif
+ ALL_DATA all;
+ MY_DATA *data = all.list;
+ int i, j, k, key2, found, x, y, cur_x, cur_y;
+ int key, fkey;
+ bool save_visit = dialog_state.visit_items;
+ int button;
+ int cur_item;
+ int name_width, text_width, full_width, list_width;
+ int result = DLG_EXIT_UNKNOWN;
+ int num_states;
+ bool first = TRUE;
+ WINDOW *dialog;
+ char *prompt;
+ const char **buttons = dlg_ok_labels();
+ const char *widget_name = "buildlist";
+
+ dialog_state.plain_buttons = TRUE;
+
+ /*
+ * Unlike other uses of --visit-items, we have two windows to visit.
+ */
+ if (dialog_state.visit_cols)
+ dialog_state.visit_cols = 2;
+
+ memset(&all, 0, sizeof(all));
+ all.items = items;
+ all.item_no = item_no;
+ for (k = 0; k < 2; ++k) {
+ data[k].ip = dlg_calloc(DIALOG_LISTITEM *, (item_no + 2));
+ }
+ fill_both_sides(&all);
+
+ if (dialog_vars.default_item != 0) {
+ cur_item = dlg_default_listitem(items);
+ } else {
+ if ((cur_item = first_item(&all, 0)) < 0)
+ cur_item = first_item(&all, 1);
+ }
+ button = (dialog_state.visit_items
+ ? (items[cur_item].state ? sRIGHT : sLEFT)
+ : dlg_default_button());
+
+ dlg_does_output();
+
+#ifdef KEY_RESIZE
+ retry:
+#endif
+
+ prompt = dlg_strclone(cprompt);
+ dlg_tab_correct_str(prompt);
+
+ all.use_height = list_height;
+ all.use_width = (2 * (dlg_calc_list_width(item_no, items)
+ + 4
+ + 2 * MARGIN)
+ + 1);
+ all.use_width = MAX(26, all.use_width);
+ if (all.use_height == 0) {
+ /* calculate height without items (4) */
+ dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, all.use_width);
+ dlg_calc_listh(&height, &all.use_height, item_no);
+ } else {
+ dlg_auto_size(title, prompt,
+ &height, &width,
+ MIN_HIGH + all.use_height, all.use_width);
+ }
+ dlg_button_layout(buttons, &width);
+ dlg_print_size(height, width);
+ dlg_ctl_size(height, width);
+
+ /* we need at least two states */
+ if (states == 0 || strlen(states) < 2)
+ states = " *";
+ num_states = (int) strlen(states);
+
+ x = dlg_box_x_ordinate(width);
+ y = dlg_box_y_ordinate(height);
+
+ dialog = dlg_new_window(height, width, y, x);
+ dlg_register_window(dialog, widget_name, binding);
+ dlg_register_buttons(dialog, widget_name, buttons);
+
+ dlg_mouse_setbase(all.base_x = x, all.base_y = y);
+
+ dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr);
+ dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
+ dlg_draw_title(dialog, title);
+
+ dlg_attrset(dialog, dialog_attr);
+ dlg_print_autowrap(dialog, prompt, height, width);
+
+ list_width = (width - 6 * MARGIN - 2) / 2;
+ getyx(dialog, cur_y, cur_x);
+ data[0].box_y = cur_y + 1;
+ data[0].box_x = MARGIN + 1;
+ data[1].box_y = cur_y + 1;
+ data[1].box_x = data[0].box_x + 1 + 2 * MARGIN + list_width;
+
+ /*
+ * After displaying the prompt, we know how much space we really have.
+ * Limit the list to avoid overwriting the ok-button.
+ */
+ if (all.use_height + MIN_HIGH > height - cur_y)
+ all.use_height = height - MIN_HIGH - cur_y;
+ if (all.use_height <= 0)
+ all.use_height = 1;
+
+ for (k = 0; k < 2; ++k) {
+ /* create new window for the list */
+ data[k].win = dlg_sub_window(dialog, all.use_height, list_width,
+ y + data[k].box_y + 1,
+ x + data[k].box_x + 1);
+
+ /* draw a box around the list items */
+ dlg_draw_box(dialog, data[k].box_y, data[k].box_x,
+ all.use_height + 2 * MARGIN,
+ list_width + 2 * MARGIN,
+ menubox_border_attr, menubox_border2_attr);
+ }
+
+ text_width = 0;
+ name_width = 0;
+ /* Find length of longest item to center buildlist */
+ for (i = 0; i < item_no; i++) {
+ text_width = MAX(text_width, dlg_count_columns(items[i].text));
+ name_width = MAX(name_width, dlg_count_columns(items[i].name));
+ }
+
+ /* If the name+text is wider than the list is allowed, then truncate
+ * one or both of them. If the name is no wider than 1/4 of the list,
+ * leave it intact.
+ */
+ all.use_width = (list_width - 6 * MARGIN);
+ if (dialog_vars.no_tags && !dialog_vars.no_items) {
+ full_width = MIN(all.use_width, text_width);
+ } else if (dialog_vars.no_items) {
+ full_width = MIN(all.use_width, name_width);
+ } else {
+ if (text_width >= 0
+ && name_width >= 0
+ && all.use_width > 0
+ && text_width + name_width > all.use_width) {
+ int need = (int) (0.25 * all.use_width);
+ if (name_width > need) {
+ int want = (int) (all.use_width * ((double) name_width) /
+ (text_width + name_width));
+ name_width = (want > need) ? want : need;
+ }
+ text_width = all.use_width - name_width;
+ }
+ full_width = text_width + name_width;
+ }
+
+ all.check_x = (all.use_width - full_width) / 2;
+ all.item_x = ((dialog_vars.no_tags
+ ? 0
+ : (dialog_vars.no_items
+ ? 0
+ : (name_width + 2)))
+ + all.check_x);
+
+ /* ensure we are scrolled to show the current choice */
+ j = MIN(all.use_height, item_no);
+ for (i = 0; i < 2; ++i) {
+ if ((items[cur_item].state != 0) == i) {
+ int top_item = cur_item - j + 1;
+ if (top_item < 0)
+ top_item = 0;
+ while ((items[top_item].state != 0) != i)
+ ++top_item;
+ set_top_item(&all, top_item, i);
+ } else {
+ set_top_item(&all, 0, i);
+ }
+ }
+
+ /* register the new window, along with its borders */
+ for (i = 0; i < 2; ++i) {
+ dlg_mouse_mkbigregion(data[i].box_y + 1,
+ data[i].box_x,
+ all.use_height,
+ list_width + 2,
+ 2 * KEY_MAX + (i * (1 + all.use_height)),
+ 1, 1, 1 /* by lines */ );
+ }
+
+ dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width);
+
+ while (result == DLG_EXIT_UNKNOWN) {
+ int which = (items[cur_item].state != 0);
+ MY_DATA *moi = data + which;
+ int at_top = index2row(&all, moi->top_index, which);
+ int at_end = index2row(&all, -1, which);
+ int at_bot = skip_rows(&all, at_top, all.use_height, which);
+ int was_mouse;
+
+ DLG_TRACE(("# ** state %d:%d top %d (%d:%d:%d) %s\n",
+ cur_item, item_no - 1,
+ moi->top_index,
+ at_top, at_bot, at_end,
+ mySide(which)));
+
+ if (first) {
+ print_both(&all, cur_item);
+ dlg_trace_win(dialog);
+ first = FALSE;
+ }
+
+ if (button < 0) { /* --visit-items */
+ int cur_row = index2row(&all, cur_item, which);
+ cur_y = (data[which].box_y
+ + cur_row
+ + 1);
+ if (at_top > 0)
+ cur_y -= at_top;
+ cur_x = (data[which].box_x
+ + all.check_x + 1);
+ DLG_TRACE(("# ...visit row %d (%d,%d)\n", cur_row, cur_y, cur_x));
+ wmove(dialog, cur_y, cur_x);
+ }
+
+ key = dlg_mouse_wgetch(dialog, &fkey);
+ if (dlg_result_key(key, fkey, &result)) {
+ if (!dlg_button_key(result, &button, &key, &fkey))
+ break;
+ }
+
+ was_mouse = (fkey && is_DLGK_MOUSE(key));
+ if (was_mouse)
+ key -= M_EVENT;
+
+ if (!was_mouse) {
+ ;
+ } else if (key >= 2 * KEY_MAX) {
+ i = (key - 2 * KEY_MAX) % (1 + all.use_height);
+ j = (key - 2 * KEY_MAX) / (1 + all.use_height);
+ k = row2index(&all, i + at_top, j);
+ DLG_TRACE(("# MOUSE column %d, row %d ->item %d\n", j, i, k));
+ if (k >= 0 && j < 2) {
+ if (j != which) {
+ /*
+ * Mouse click was in the other column.
+ */
+ moi = data + j;
+ fix_top_item(&all, k, j);
+ }
+ which = j;
+ at_top = index2row(&all, moi->top_index, which);
+ at_bot = skip_rows(&all, at_top, all.use_height, which);
+ cur_item = k;
+ print_both(&all, cur_item);
+ key = DLGK_TOGGLE; /* force the selected item to toggle */
+ } else {
+ beep();
+ continue;
+ }
+ fkey = FALSE;
+ } else if (key >= KEY_MIN) {
+ if (key > KEY_MAX) {
+ if (which == 0) {
+ key = KEY_RIGHTCOL; /* switch to right-column */
+ fkey = FALSE;
+ } else {
+ key -= KEY_MAX;
+ }
+ } else {
+ if (which == 1) {
+ key = KEY_LEFTCOL; /* switch to left-column */
+ fkey = FALSE;
+ }
+ }
+ key = dlg_lookup_key(dialog, key, &fkey);
+ }
+
+ /*
+ * A space toggles the item status. Normally we put the cursor on
+ * the next available item in the same column. But if there are no
+ * more items in the column, move the cursor to the other column.
+ */
+ if (key == DLGK_TOGGLE) {
+ int new_choice;
+ int new_state = items[cur_item].state + 1;
+
+ if ((new_choice = next_item(&all, cur_item, which)) == cur_item) {
+ new_choice = prev_item(&all, cur_item, which);
+ }
+ DLG_TRACE(("# cur_item %d, new_choice:%d\n", cur_item, new_choice));
+ /* FIXME - how to test and handle multiple states? */
+ if (new_state >= num_states)
+ new_state = 0;
+
+ items[cur_item].state = new_state;
+ if (order_mode) {
+ fill_one_side(&all, 0);
+ if (new_state) {
+ append_right_side(&all, cur_item);
+ } else {
+ amend_right_side(&all, cur_item);
+ }
+ } else {
+ fill_both_sides(&all);
+ }
+ if (cur_item == moi->top_index) {
+ set_top_item(&all, new_choice, which);
+ }
+
+ if (new_choice >= 0) {
+ fix_top_item(&all, cur_item, !which);
+ cur_item = new_choice;
+ }
+ print_both(&all, cur_item);
+ dlg_trace_win(dialog);
+ continue; /* wait for another key press */
+ }
+
+ /*
+ * Check if key pressed matches first character of any item tag in
+ * list. If there is more than one match, we will cycle through
+ * each one as the same key is pressed repeatedly.
+ */
+ found = FALSE;
+ if (!fkey) {
+ if (button < 0 || !dialog_state.visit_items) {
+ for (j = cur_item + 1; j < item_no; j++) {
+ if (check_hotkey(items, j, which)) {
+ found = TRUE;
+ i = j;
+ break;
+ }
+ }
+ if (!found) {
+ for (j = 0; j <= cur_item; j++) {
+ if (check_hotkey(items, j, which)) {
+ found = TRUE;
+ i = j;
+ break;
+ }
+ }
+ }
+ if (found)
+ dlg_flush_getc();
+ } else if ((j = dlg_char_to_button(key, buttons)) >= 0) {
+ button = j;
+ ungetch('\n');
+ continue;
+ }
+ }
+
+ /*
+ * A single digit (1-9) positions the selection to that line in the
+ * current screen.
+ */
+ if (!found
+ && (key <= '9')
+ && (key > '0')
+ && (key - '1' < at_bot)) {
+ found = TRUE;
+ i = key - '1';
+ }
+
+ if (!found && fkey) {
+ switch (key) {
+ case DLGK_FIELD_PREV:
+ if ((button == sRIGHT) && dialog_state.visit_items) {
+ key = DLGK_GRID_LEFT;
+ button = sLEFT;
+ } else {
+ button = dlg_prev_button(buttons, button);
+ dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
+ FALSE, width);
+ if (button == sRIGHT) {
+ key = DLGK_GRID_RIGHT;
+ } else {
+ continue;
+ }
+ }
+ break;
+ case DLGK_FIELD_NEXT:
+ if ((button == sLEFT) && dialog_state.visit_items) {
+ key = DLGK_GRID_RIGHT;
+ button = sRIGHT;
+ } else {
+ button = dlg_next_button(buttons, button);
+ dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
+ FALSE, width);
+ if (button == sLEFT) {
+ key = DLGK_GRID_LEFT;
+ } else {
+ continue;
+ }
+ }
+ break;
+ }
+
+ i = cur_item;
+ found = TRUE;
+ switch (key) {
+ case DLGK_GRID_LEFT:
+ i = closest_item(&all, cur_item, 0);
+ fix_top_item(&all, i, 0);
+ break;
+ case DLGK_GRID_RIGHT:
+ if (order_mode) {
+ i = last_item(&all, 1);
+ } else {
+ i = closest_item(&all, cur_item, 1);
+ }
+ fix_top_item(&all, i, 1);
+ break;
+ case DLGK_PAGE_PREV:
+ if (cur_item > moi->top_index) {
+ i = moi->top_index;
+ } else if (moi->top_index != 0) {
+ int temp = at_top;
+ if ((temp -= all.use_height) < 0)
+ temp = 0;
+ i = row2index(&all, temp, which);
+ }
+ break;
+ case DLGK_PAGE_NEXT:
+ if ((at_end - at_bot) < all.use_height) {
+ i = next_item(&all,
+ row2index(&all, at_end, which),
+ which);
+ } else {
+ i = next_item(&all,
+ row2index(&all, at_bot, which),
+ which);
+ at_top = at_bot;
+ set_top_item(&all,
+ next_item(&all,
+ row2index(&all, at_top, which),
+ which),
+ which);
+ at_bot = skip_rows(&all, at_top, all.use_height, which);
+ at_bot = MIN(at_bot, at_end);
+ }
+ break;
+ case DLGK_ITEM_FIRST:
+ i = first_item(&all, which);
+ break;
+ case DLGK_ITEM_LAST:
+ i = last_item(&all, which);
+ break;
+ case DLGK_ITEM_PREV:
+ i = prev_item(&all, cur_item, which);
+ if (stop_prev(&all, cur_item, which))
+ continue;
+ break;
+ case DLGK_ITEM_NEXT:
+ i = next_item(&all, cur_item, which);
+ break;
+ default:
+ found = FALSE;
+ break;
+ }
+ }
+
+ if (found) {
+ if (i != cur_item) {
+ int now_at = index2row(&all, i, which);
+ int oops = item_no;
+ int old_item;
+
+ DLG_TRACE(("# <--CHOICE %d\n", i));
+ DLG_TRACE(("# <--topITM %d\n", moi->top_index));
+ DLG_TRACE(("# <--now_at %d\n", now_at));
+ DLG_TRACE(("# <--at_top %d\n", at_top));
+ DLG_TRACE(("# <--at_bot %d\n", at_bot));
+
+ if (now_at >= at_bot) {
+ while (now_at >= at_bot) {
+ if ((at_bot - at_top) >= all.use_height) {
+ set_top_item(&all,
+ next_item(&all, moi->top_index, which),
+ which);
+ }
+ at_top = index2row(&all, moi->top_index, which);
+ at_bot = skip_rows(&all, at_top, all.use_height, which);
+
+ DLG_TRACE(("# ...at_bot %d (now %d vs %d)\n",
+ at_bot, now_at, at_end));
+ DLG_TRACE(("# ...topITM %d\n", moi->top_index));
+ DLG_TRACE(("# ...at_top %d (diff %d)\n", at_top,
+ at_bot - at_top));
+
+ if (at_bot >= at_end) {
+ /*
+ * If we bumped into the end, move the top-item
+ * down by one line so that we can display the
+ * last item in the list.
+ */
+ if ((at_bot - at_top) > all.use_height) {
+ set_top_item(&all,
+ next_item(&all, moi->top_index, which),
+ which);
+ } else if (at_top > 0 &&
+ (at_bot - at_top) >= all.use_height) {
+ set_top_item(&all,
+ next_item(&all, moi->top_index, which),
+ which);
+ }
+ break;
+ }
+ if (--oops < 0) {
+ DLG_TRACE(("# OOPS-forward\n"));
+ break;
+ }
+ }
+ } else if (now_at < at_top) {
+ while (now_at < at_top) {
+ old_item = moi->top_index;
+ set_top_item(&all,
+ prev_item(&all, moi->top_index, which),
+ which);
+ at_top = index2row(&all, moi->top_index, which);
+
+ DLG_TRACE(("# ...at_top %d (now %d)\n", at_top, now_at));
+ DLG_TRACE(("# ...topITM %d\n", moi->top_index));
+
+ if (moi->top_index >= old_item)
+ break;
+ if (at_top <= now_at)
+ break;
+ if (--oops < 0) {
+ DLG_TRACE(("# OOPS-backward\n"));
+ break;
+ }
+ }
+ }
+ DLG_TRACE(("# -->now_at %d\n", now_at));
+ cur_item = i;
+ print_both(&all, cur_item);
+ }
+ dlg_trace_win(dialog);
+ continue; /* wait for another key press */
+ }
+
+ if (fkey) {
+ switch (key) {
+ case DLGK_ENTER:
+ result = dlg_enter_buttoncode(button);
+ break;
+ case DLGK_LEAVE:
+ result = dlg_ok_buttoncode(button);
+ break;
+#ifdef KEY_RESIZE
+ case KEY_RESIZE:
+ dlg_will_resize(dialog);
+ /* reset data */
+ height = old_height;
+ width = old_width;
+ free(prompt);
+ _dlg_resize_cleanup(dialog);
+ /* repaint */
+ first = TRUE;
+ goto retry;
+#endif
+ default:
+ if (was_mouse) {
+ if ((key2 = dlg_ok_buttoncode(key)) >= 0) {
+ result = key2;
+ break;
+ }
+ beep();
+ }
+ }
+ } else if (key > 0) {
+ beep();
+ }
+ }
+
+ /*
+ * If told to re-order the list, update it to reflect the current display:
+ * a) The left-side will be at the beginning, without gaps.
+ * b) The right-side will follow, in display-order.
+ */
+ if (order_mode) {
+ DIALOG_LISTITEM *redo;
+ int row;
+ int choice;
+ int new_item = cur_item;
+
+ redo = dlg_calloc(DIALOG_LISTITEM, (size_t) item_no + 1);
+ assert_ptr(redo, THIS_FUNC);
+
+ j = 0;
+ for (k = 0; k < 2; ++k) {
+ for (row = 0; row < item_no; ++row) {
+ if (myItem(all.list + k, row) == 0)
+ break;
+ choice = row2index(&all, row, k);
+ if (choice == cur_item)
+ new_item = j;
+ redo[j++] = items[choice];
+ }
+ }
+
+ cur_item = new_item;
+ memcpy(items, redo, sizeof(DIALOG_LISTITEM) * (size_t) (item_no + 1));
+
+ free(redo);
+ }
+
+ for (k = 0; k < 2; ++k) {
+ free(data[k].ip);
+ }
+
+ dialog_state.visit_cols = save_visit;
+ dlg_del_window(dialog);
+ dlg_mouse_free_regions();
+ free(prompt);
+
+ *current_item = cur_item;
+ return result;
+#undef THIS_FUNC
+}
+
+/*
+ * Display a dialog box with a list of options that can be turned on or off
+ */
+int
+dialog_buildlist(const char *title,
+ const char *cprompt,
+ int height,
+ int width,
+ int list_height,
+ int item_no,
+ char **items,
+ int order_mode)
+{
+#define THIS_FUNC "dialog_buildlist"
+ int result;
+ int i, j;
+ DIALOG_LISTITEM *listitems;
+ bool separate_output = dialog_vars.separate_output;
+ bool show_status = FALSE;
+ int current = 0;
+ char *help_result;
+
+ DLG_TRACE(("# buildlist args:\n"));
+ DLG_TRACE2S("title", title);
+ DLG_TRACE2S("message", cprompt);
+ DLG_TRACE2N("height", height);
+ DLG_TRACE2N("width", width);
+ DLG_TRACE2N("lheight", list_height);
+ DLG_TRACE2N("llength", item_no);
+ /* FIXME dump the items[][] too */
+ DLG_TRACE2N("order", order_mode != 0);
+
+ listitems = dlg_calloc(DIALOG_LISTITEM, (size_t) item_no + 1);
+ assert_ptr(listitems, THIS_FUNC);
+
+ for (i = j = 0; i < item_no; ++i) {
+ listitems[i].name = items[j++];
+ listitems[i].text = (dialog_vars.no_items
+ ? dlg_strempty()
+ : items[j++]);
+ listitems[i].state = !dlg_strcmp(items[j++], "on");
+ listitems[i].help = ((dialog_vars.item_help)
+ ? items[j++]
+ : dlg_strempty());
+ }
+ dlg_align_columns(&listitems[0].text, (int) sizeof(DIALOG_LISTITEM), item_no);
+
+ result = dlg_buildlist(title,
+ cprompt,
+ height,
+ width,
+ list_height,
+ item_no,
+ listitems,
+ NULL,
+ order_mode,
+ ¤t);
+
+ switch (result) {
+ case DLG_EXIT_OK: /* FALLTHRU */
+ case DLG_EXIT_EXTRA:
+ show_status = TRUE;
+ break;
+ case DLG_EXIT_HELP:
+ dlg_add_help_listitem(&result, &help_result, &listitems[current]);
+ if ((show_status = dialog_vars.help_status)) {
+ if (separate_output) {
+ dlg_add_string(help_result);
+ } else {
+ dlg_add_quoted(help_result);
+ }
+ } else {
+ dlg_add_string(help_result);
+ }
+ break;
+ }
+
+ if (show_status) {
+ for (i = 0; i < item_no; i++) {
+ if (listitems[i].state) {
+ if (dlg_need_separator())
+ dlg_add_separator();
+ if (separate_output) {
+ dlg_add_string(listitems[i].name);
+ } else {
+ dlg_add_quoted(listitems[i].name);
+ }
+ }
+ }
+ AddLastKey();
+ }
+
+ dlg_free_columns(&listitems[0].text, (int) sizeof(DIALOG_LISTITEM), item_no);
+ free(listitems);
+ return result;
+#undef THIS_FUNC
+}
Index: sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/checklist.c
===================================================================
--- sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/checklist.c (nonexistent)
+++ sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/checklist.c (revision 34)
@@ -0,0 +1,708 @@
+/*
+ * $Id: checklist.c,v 1.170 2022/04/04 22:25:11 tom Exp $
+ *
+ * checklist.c -- implements the checklist box
+ *
+ * Copyright 2000-2020,2022 Thomas E. Dickey
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License, version 2.1
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to
+ * Free Software Foundation, Inc.
+ * 51 Franklin St., Fifth Floor
+ * Boston, MA 02110, USA.
+ *
+ * An earlier version of this program lists as authors:
+ * Savio Lam (lam836@cs.cuhk.hk)
+ * Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
+ * Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
+ */
+
+#include <dlg_internals.h>
+#include <dlg_keys.h>
+
+#define MIN_HIGH 4
+
+typedef struct {
+ /* the outer-window */
+ WINDOW *dialog;
+ int box_y;
+ int box_x;
+ int check_x;
+ int item_x;
+ int checkflag;
+ int use_height;
+ int use_width;
+ /* the inner-window */
+ WINDOW *list;
+ DIALOG_LISTITEM *items;
+ int item_no;
+ const char *states;
+} ALL_DATA;
+
+/*
+ * Print list item. The 'selected' parameter is true if 'choice' is the
+ * current item. That one is colored differently from the other items.
+ */
+static void
+print_item(ALL_DATA * data,
+ WINDOW *win,
+ DIALOG_LISTITEM * item,
+ const char *states,
+ int choice,
+ int selected)
+{
+ chtype save = dlg_get_attrs(win);
+ int i;
+ bool both = (!dialog_vars.no_tags && !dialog_vars.no_items);
+ bool first = TRUE;
+ int climit = (getmaxx(win) - data->check_x + 1);
+ const char *show = (dialog_vars.no_items
+ ? item->name
+ : item->text);
+
+ /* Clear 'residue' of last item */
+ dlg_attrset(win, menubox_attr);
+ (void) wmove(win, choice, 0);
+ for (i = 0; i < data->use_width; i++)
+ (void) waddch(win, ' ');
+
+ (void) wmove(win, choice, data->check_x);
+ dlg_attrset(win, selected ? check_selected_attr : check_attr);
+ (void) wprintw(win,
+ (data->checkflag == FLAG_CHECK) ? "[%c]" : "(%c)",
+ states[item->state]);
+ dlg_attrset(win, menubox_attr);
+ (void) waddch(win, ' ');
+
+ if (both) {
+ dlg_print_listitem(win, item->name, climit, first, selected);
+ first = FALSE;
+ }
+
+ (void) wmove(win, choice, data->item_x);
+ dlg_print_listitem(win, show, climit, first, selected);
+
+ if (selected) {
+ dlg_item_help(item->help);
+ }
+ dlg_attrset(win, save);
+}
+
+static void
+print_list(ALL_DATA * data, int choice, int scrollamt, int max_choice, int max_items)
+{
+ int i;
+ int cur_y, cur_x;
+
+ getyx(data->dialog, cur_y, cur_x);
+ for (i = 0; i < max_choice; i++) {
+ int ii = i + scrollamt;
+ if (ii < max_items)
+ print_item(data,
+ data->list,
+ &data->items[ii],
+ data->states,
+ i, i == choice);
+ }
+ (void) wnoutrefresh(data->list);
+
+ dlg_draw_scrollbar(data->dialog,
+ (long) (scrollamt),
+ (long) (scrollamt),
+ (long) (scrollamt + max_choice),
+ (long) (data->item_no),
+ data->box_x + data->check_x,
+ data->box_x + data->use_width,
+ data->box_y,
+ data->box_y + data->use_height + 1,
+ menubox_border2_attr,
+ menubox_border_attr);
+
+ (void) wmove(data->dialog, cur_y, cur_x);
+}
+
+static bool
+check_hotkey(DIALOG_LISTITEM * items, int choice)
+{
+ bool result = FALSE;
+
+ if (dlg_match_char(dlg_last_getc(),
+ (dialog_vars.no_tags
+ ? items[choice].text
+ : items[choice].name))) {
+ result = TRUE;
+ }
+ return result;
+}
+
+/*
+ * This is an alternate interface to 'checklist' which allows the application
+ * to read the list item states back directly without putting them in the
+ * output buffer. It also provides for more than two states over which the
+ * check/radio box can display.
+ */
+int
+dlg_checklist(const char *title,
+ const char *cprompt,
+ int height,
+ int width,
+ int list_height,
+ int item_no,
+ DIALOG_LISTITEM * items,
+ const char *states,
+ int flag,
+ int *current_item)
+{
+ /* *INDENT-OFF* */
+ static DLG_KEYS_BINDING binding[] = {
+ HELPKEY_BINDINGS,
+ ENTERKEY_BINDINGS,
+ DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ),
+ DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ),
+ DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ),
+ DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ),
+ DLG_KEYS_DATA( DLGK_ITEM_FIRST, KEY_HOME ),
+ DLG_KEYS_DATA( DLGK_ITEM_LAST, KEY_END ),
+ DLG_KEYS_DATA( DLGK_ITEM_LAST, KEY_LL ),
+ DLG_KEYS_DATA( DLGK_ITEM_NEXT, '+' ),
+ DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_DOWN ),
+ DLG_KEYS_DATA( DLGK_ITEM_NEXT, CHR_NEXT ),
+ DLG_KEYS_DATA( DLGK_ITEM_PREV, '-' ),
+ DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_UP ),
+ DLG_KEYS_DATA( DLGK_ITEM_PREV, CHR_PREVIOUS ),
+ DLG_KEYS_DATA( DLGK_PAGE_NEXT, KEY_NPAGE ),
+ DLG_KEYS_DATA( DLGK_PAGE_NEXT, DLGK_MOUSE(KEY_NPAGE) ),
+ DLG_KEYS_DATA( DLGK_PAGE_PREV, KEY_PPAGE ),
+ DLG_KEYS_DATA( DLGK_PAGE_PREV, DLGK_MOUSE(KEY_PPAGE) ),
+ TOGGLEKEY_BINDINGS,
+ END_KEYS_BINDING
+ };
+ /* *INDENT-ON* */
+
+#ifdef KEY_RESIZE
+ int old_height = height;
+ int old_width = width;
+#endif
+ ALL_DATA all;
+ int i, j, key2, found, x, y, cur_x, cur_y;
+ int key, fkey;
+ int button = dialog_state.visit_items ? -1 : dlg_default_button();
+ int choice = dlg_default_listitem(items);
+ int scrollamt = 0;
+ int max_choice;
+ int use_width, list_width, name_width, text_width;
+ int result = DLG_EXIT_UNKNOWN;
+ int num_states;
+ WINDOW *dialog;
+ char *prompt;
+ const char **buttons = dlg_ok_labels();
+ const char *widget_name;
+
+ DLG_TRACE(("# %s args:\n", flag ? "checklist" : "radiolist"));
+ DLG_TRACE2S("title", title);
+ DLG_TRACE2S("message", cprompt);
+ DLG_TRACE2N("height", height);
+ DLG_TRACE2N("width", width);
+ DLG_TRACE2N("lheight", list_height);
+ DLG_TRACE2N("llength", item_no);
+ /* FIXME dump the items[][] too */
+ DLG_TRACE2S("states", states);
+ DLG_TRACE2N("flag", flag);
+ DLG_TRACE2N("current", *current_item);
+
+ dialog_state.plain_buttons = TRUE;
+
+ memset(&all, 0, sizeof(all));
+ all.items = items;
+ all.item_no = item_no;
+
+ dlg_does_output();
+
+ /*
+ * If this is a radiobutton list, ensure that no more than one item is
+ * selected initially. Allow none to be selected, since some users may
+ * wish to provide this flavor.
+ */
+ if (flag == FLAG_RADIO) {
+ bool first = TRUE;
+
+ for (i = 0; i < item_no; i++) {
+ if (items[i].state) {
+ if (first) {
+ first = FALSE;
+ } else {
+ items[i].state = 0;
+ }
+ }
+ }
+ widget_name = "radiolist";
+ } else {
+ widget_name = "checklist";
+ }
+#ifdef KEY_RESIZE
+ retry:
+#endif
+
+ prompt = dlg_strclone(cprompt);
+ dlg_tab_correct_str(prompt);
+
+ all.use_height = list_height;
+ use_width = dlg_calc_list_width(item_no, items) + 10;
+ use_width = MAX(26, use_width);
+ if (all.use_height == 0) {
+ /* calculate height without items (4) */
+ dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, use_width);
+ dlg_calc_listh(&height, &all.use_height, item_no);
+ } else {
+ dlg_auto_size(title, prompt,
+ &height, &width,
+ MIN_HIGH + all.use_height, use_width);
+ }
+ dlg_button_layout(buttons, &width);
+ dlg_print_size(height, width);
+ dlg_ctl_size(height, width);
+
+ /* we need at least two states */
+ if (states == 0 || strlen(states) < 2)
+ states = " *";
+ num_states = (int) strlen(states);
+ all.states = states;
+
+ all.checkflag = flag;
+
+ x = dlg_box_x_ordinate(width);
+ y = dlg_box_y_ordinate(height);
+
+ dialog = dlg_new_window(height, width, y, x);
+ all.dialog = dialog;
+ dlg_register_window(dialog, widget_name, binding);
+ dlg_register_buttons(dialog, widget_name, buttons);
+
+ dlg_mouse_setbase(x, y);
+
+ dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr);
+ dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
+ dlg_draw_title(dialog, title);
+
+ dlg_attrset(dialog, dialog_attr);
+ dlg_print_autowrap(dialog, prompt, height, width);
+
+ all.use_width = width - 6;
+ getyx(dialog, cur_y, cur_x);
+ all.box_y = cur_y + 1;
+ all.box_x = (width - all.use_width) / 2 - 1;
+
+ /*
+ * After displaying the prompt, we know how much space we really have.
+ * Limit the list to avoid overwriting the ok-button.
+ */
+ if (all.use_height + MIN_HIGH > height - cur_y)
+ all.use_height = height - MIN_HIGH - cur_y;
+ if (all.use_height <= 0)
+ all.use_height = 1;
+
+ max_choice = MIN(all.use_height, item_no);
+ max_choice = MAX(max_choice, 1);
+
+ /* create new window for the list */
+ all.list = dlg_sub_window(dialog, all.use_height, all.use_width,
+ y + all.box_y + 1, x + all.box_x + 1);
+
+ /* draw a box around the list items */
+ dlg_draw_box(dialog, all.box_y, all.box_x,
+ all.use_height + 2 * MARGIN,
+ all.use_width + 2 * MARGIN,
+ menubox_border_attr, menubox_border2_attr);
+
+ text_width = 0;
+ name_width = 0;
+ /* Find length of longest item to center checklist */
+ for (i = 0; i < item_no; i++) {
+ text_width = MAX(text_width, dlg_count_columns(items[i].text));
+ name_width = MAX(name_width, dlg_count_columns(items[i].name));
+ }
+
+ /* If the name+text is wider than the list is allowed, then truncate
+ * one or both of them. If the name is no wider than 1/4 of the list,
+ * leave it intact.
+ */
+ use_width = (all.use_width - 6);
+ if (dialog_vars.no_tags) {
+ list_width = MIN(all.use_width, text_width);
+ } else if (dialog_vars.no_items) {
+ list_width = MIN(all.use_width, name_width);
+ } else {
+ if (text_width >= 0
+ && name_width >= 0
+ && use_width > 0
+ && text_width + name_width > use_width) {
+ int need = (int) (0.25 * use_width);
+ if (name_width > need) {
+ int want = (int) (use_width * ((double) name_width) /
+ (text_width + name_width));
+ name_width = (want > need) ? want : need;
+ }
+ text_width = use_width - name_width;
+ }
+ list_width = (text_width + name_width);
+ }
+
+ all.check_x = (use_width - list_width) / 2;
+ all.item_x = ((dialog_vars.no_tags
+ ? 0
+ : (dialog_vars.no_items
+ ? 0
+ : (2 + name_width)))
+ + all.check_x + 4);
+
+ /* ensure we are scrolled to show the current choice */
+ scrollamt = MIN(scrollamt, max_choice + item_no - 1);
+ if (choice >= (max_choice + scrollamt - 1)) {
+ scrollamt = MAX(0, choice - max_choice + 1);
+ choice = max_choice - 1;
+ }
+ print_list(&all, choice, scrollamt, max_choice, item_no);
+
+ /* register the new window, along with its borders */
+ dlg_mouse_mkbigregion(all.box_y + 1, all.box_x,
+ all.use_height, all.use_width + 2,
+ KEY_MAX, 1, 1, 1 /* by lines */ );
+
+ dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width);
+
+ dlg_trace_win(dialog);
+
+ while (result == DLG_EXIT_UNKNOWN) {
+ int was_mouse;
+
+ if (button < 0) /* --visit-items */
+ wmove(dialog, all.box_y + choice + 1, all.box_x + all.check_x + 2);
+
+ key = dlg_mouse_wgetch(dialog, &fkey);
+ if (dlg_result_key(key, fkey, &result)) {
+ if (!dlg_button_key(result, &button, &key, &fkey))
+ break;
+ }
+
+ was_mouse = (fkey && is_DLGK_MOUSE(key));
+ if (was_mouse)
+ key -= M_EVENT;
+
+ if (was_mouse && (key >= KEY_MAX)) {
+ getyx(dialog, cur_y, cur_x);
+ i = (key - KEY_MAX);
+ if (i < max_choice) {
+ choice = (key - KEY_MAX);
+ print_list(&all, choice, scrollamt, max_choice, item_no);
+
+ key = DLGK_TOGGLE; /* force the selected item to toggle */
+ } else {
+ beep();
+ continue;
+ }
+ fkey = FALSE;
+ } else if (was_mouse && key >= KEY_MIN) {
+ key = dlg_lookup_key(dialog, key, &fkey);
+ }
+
+ /*
+ * A space toggles the item status. We handle either a checklist
+ * (any number of items can be selected) or radio list (zero or one
+ * items can be selected).
+ */
+ if (key == DLGK_TOGGLE) {
+ int current = scrollamt + choice;
+ int next = items[current].state + 1;
+
+ if (next >= num_states)
+ next = 0;
+
+ if (flag == FLAG_CHECK) { /* checklist? */
+ getyx(dialog, cur_y, cur_x);
+ items[current].state = next;
+ print_item(&all, all.list,
+ &items[scrollamt + choice],
+ states,
+ choice, TRUE);
+ (void) wnoutrefresh(all.list);
+ (void) wmove(dialog, cur_y, cur_x);
+ } else { /* radiolist */
+ for (i = 0; i < item_no; i++) {
+ if (i != current) {
+ items[i].state = 0;
+ }
+ }
+ if (items[current].state) {
+ getyx(dialog, cur_y, cur_x);
+ items[current].state = next ? next : 1;
+ print_item(&all, all.list,
+ &items[current],
+ states,
+ choice, TRUE);
+ (void) wnoutrefresh(all.list);
+ (void) wmove(dialog, cur_y, cur_x);
+ } else {
+ items[current].state = 1;
+ print_list(&all, choice, scrollamt, max_choice, item_no);
+ }
+ }
+ continue; /* wait for another key press */
+ }
+
+ /*
+ * Check if key pressed matches first character of any item tag in
+ * list. If there is more than one match, we will cycle through
+ * each one as the same key is pressed repeatedly.
+ */
+ found = FALSE;
+ if (!fkey) {
+ if (button < 0 || !dialog_state.visit_items) {
+ for (j = scrollamt + choice + 1; j < item_no; j++) {
+ if (check_hotkey(items, j)) {
+ found = TRUE;
+ i = j - scrollamt;
+ break;
+ }
+ }
+ if (!found) {
+ for (j = 0; j <= scrollamt + choice; j++) {
+ if (check_hotkey(items, j)) {
+ found = TRUE;
+ i = j - scrollamt;
+ break;
+ }
+ }
+ }
+ if (found)
+ dlg_flush_getc();
+ } else if ((j = dlg_char_to_button(key, buttons)) >= 0) {
+ button = j;
+ ungetch('\n');
+ continue;
+ }
+ }
+
+ /*
+ * A single digit (1-9) positions the selection to that line in the
+ * current screen.
+ */
+ if (!found
+ && (key <= '9')
+ && (key > '0')
+ && (key - '1' < max_choice)) {
+ found = TRUE;
+ i = key - '1';
+ }
+
+ if (!found) {
+ if (fkey) {
+ found = TRUE;
+ switch (key) {
+ case DLGK_ITEM_FIRST:
+ i = -scrollamt;
+ break;
+ case DLGK_ITEM_LAST:
+ i = item_no - 1 - scrollamt;
+ break;
+ case DLGK_PAGE_PREV:
+ if (choice)
+ i = 0;
+ else if (scrollamt != 0)
+ i = -MIN(scrollamt, max_choice);
+ else
+ continue;
+ break;
+ case DLGK_PAGE_NEXT:
+ i = MIN(choice + max_choice, item_no - scrollamt - 1);
+ break;
+ case DLGK_ITEM_PREV:
+ i = choice - 1;
+ if (choice == 0 && scrollamt == 0)
+ continue;
+ break;
+ case DLGK_ITEM_NEXT:
+ i = choice + 1;
+ if (scrollamt + choice >= item_no - 1)
+ continue;
+ break;
+ default:
+ found = FALSE;
+ break;
+ }
+ }
+ }
+
+ if (found) {
+ if (i != choice) {
+ getyx(dialog, cur_y, cur_x);
+ if (i < 0 || i >= max_choice) {
+ if (i < 0) {
+ scrollamt += i;
+ choice = 0;
+ } else {
+ choice = max_choice - 1;
+ scrollamt += (i - max_choice + 1);
+ }
+ print_list(&all, choice, scrollamt, max_choice, item_no);
+ } else {
+ choice = i;
+ print_list(&all, choice, scrollamt, max_choice, item_no);
+ }
+ }
+ continue; /* wait for another key press */
+ }
+
+ if (fkey) {
+ switch (key) {
+ case DLGK_ENTER:
+ result = dlg_enter_buttoncode(button);
+ break;
+ case DLGK_LEAVE:
+ result = dlg_ok_buttoncode(button);
+ break;
+ case DLGK_FIELD_PREV:
+ button = dlg_prev_button(buttons, button);
+ dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
+ FALSE, width);
+ break;
+ case DLGK_FIELD_NEXT:
+ button = dlg_next_button(buttons, button);
+ dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
+ FALSE, width);
+ break;
+#ifdef KEY_RESIZE
+ case KEY_RESIZE:
+ dlg_will_resize(dialog);
+ /* reset data */
+ height = old_height;
+ width = old_width;
+ free(prompt);
+ _dlg_resize_cleanup(dialog);
+ /* keep position */
+ choice += scrollamt;
+ scrollamt = 0;
+ /* repaint */
+ goto retry;
+#endif
+ default:
+ if (was_mouse) {
+ if ((key2 = dlg_ok_buttoncode(key)) >= 0) {
+ result = key2;
+ break;
+ }
+ beep();
+ }
+ }
+ } else if (key > 0) {
+ beep();
+ }
+ }
+
+ dlg_del_window(dialog);
+ dlg_mouse_free_regions();
+ free(prompt);
+ *current_item = (scrollamt + choice);
+ return result;
+}
+
+/*
+ * Display a dialog box with a list of options that can be turned on or off
+ * The `flag' parameter is used to select between radiolist and checklist.
+ */
+int
+dialog_checklist(const char *title,
+ const char *cprompt,
+ int height,
+ int width,
+ int list_height,
+ int item_no,
+ char **items,
+ int flag)
+{
+ int result;
+ int i, j;
+ DIALOG_LISTITEM *listitems;
+ bool separate_output = ((flag == FLAG_CHECK)
+ && (dialog_vars.separate_output));
+ bool show_status = FALSE;
+ int current = 0;
+ char *help_result;
+
+ listitems = dlg_calloc(DIALOG_LISTITEM, (size_t) item_no + 1);
+ assert_ptr(listitems, "dialog_checklist");
+
+ for (i = j = 0; i < item_no; ++i) {
+ listitems[i].name = items[j++];
+ listitems[i].text = (dialog_vars.no_items
+ ? dlg_strempty()
+ : items[j++]);
+ listitems[i].state = !dlg_strcmp(items[j++], "on");
+ listitems[i].help = ((dialog_vars.item_help)
+ ? items[j++]
+ : dlg_strempty());
+ }
+ dlg_align_columns(&listitems[0].text, (int) sizeof(DIALOG_LISTITEM), item_no);
+
+ result = dlg_checklist(title,
+ cprompt,
+ height,
+ width,
+ list_height,
+ item_no,
+ listitems,
+ NULL,
+ flag,
+ ¤t);
+
+ switch (result) {
+ case DLG_EXIT_OK: /* FALLTHRU */
+ case DLG_EXIT_EXTRA:
+ show_status = TRUE;
+ break;
+ case DLG_EXIT_HELP:
+ dlg_add_help_listitem(&result, &help_result, &listitems[current]);
+ if ((show_status = dialog_vars.help_status)) {
+ if (separate_output) {
+ dlg_add_string(help_result);
+ dlg_add_separator();
+ } else {
+ dlg_add_quoted(help_result);
+ }
+ } else {
+ dlg_add_string(help_result);
+ }
+ break;
+ }
+
+ if (show_status) {
+ for (i = 0; i < item_no; i++) {
+ if (listitems[i].state) {
+ if (separate_output) {
+ dlg_add_string(listitems[i].name);
+ dlg_add_separator();
+ } else {
+ if (dlg_need_separator())
+ dlg_add_separator();
+ if (flag == FLAG_CHECK)
+ dlg_add_quoted(listitems[i].name);
+ else
+ dlg_add_string(listitems[i].name);
+ }
+ }
+ }
+ dlg_add_last_key(separate_output);
+ }
+
+ dlg_free_columns(&listitems[0].text, (int) sizeof(DIALOG_LISTITEM), item_no);
+ free(listitems);
+ return result;
+}
Index: sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/dialog-config.in
===================================================================
--- sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/dialog-config.in (nonexistent)
+++ sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/dialog-config.in (revision 34)
@@ -0,0 +1,265 @@
+#!@SHELL@
+# $Id: dialog-config.in,v 1.14 2021/03/05 23:48:36 tom Exp $
+##############################################################################
+# Copyright (c) 2007-2019,2021 Thomas E. Dickey #
+# #
+# Permission is hereby granted, free of charge, to any person obtaining a #
+# copy of this software and associated documentation files (the "Software"), #
+# to deal in the Software without restriction, including without limitation #
+# the rights to use, copy, modify, merge, publish, distribute, distribute #
+# with modifications, sublicense, and/or sell copies of the Software, and to #
+# permit persons to whom the Software is furnished to do so, subject to the #
+# following conditions: #
+# #
+# The above copyright notice and this permission notice shall be included in #
+# all copies or substantial portions of the Software. #
+# #
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL #
+# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING #
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER #
+# DEALINGS IN THE SOFTWARE. #
+# #
+# Except as contained in this notice, the name(s) of the above copyright #
+# holders shall not be used in advertising or otherwise to promote the sale, #
+# use or other dealings in this Software without prior written #
+# authorization. #
+##############################################################################
+
+prefix="@prefix@"
+exec_prefix="@exec_prefix@"
+datarootdir="@datarootdir@"
+
+same_prefix=yes
+same_exec_prefix=yes
+
+THIS="@PACKAGE@"
+
+test $# = 0 && exec @SHELL@ "$0" --error
+
+while test $# -gt 0; do
+
+ # (re)evaluate symbols that may depend upon $prefix
+ if [ "x$same_prefix" != "xyes" ]
+ then
+ eval exec_prefix='@exec_prefix@'
+ eval datarootdir='@datarootdir@'
+ elif [ "x$same_exec_prefix" != "xyes" ]
+ then
+ eval datarootdir='@datarootdir@'
+ fi
+
+ eval bindir='"@bindir@"'
+ eval includedir='"@includedir@"'
+ eval libdir='"@libdir@"'
+ eval datadir='"@datadir@"'
+ eval mandir='"@mandir@"'
+
+ [ -z "$includedir" ] && includedir="${prefix}/include"
+
+ eval LDFLAGS='"@LDFLAGS@"'
+ eval LIBS='"@LIBS@"'
+ LIBS="-l${THIS} $LIBS"
+
+ # If the directory given by --libdir is not in the LDFLAGS+LIBS set,
+ # prepend it to LDFLAGS to help link this application's library.
+ found=no
+ for opt in $LDFLAGS $LIBS
+ do
+ if [ "x$-L${libdir}" = "x$opt" ]
+ then
+ found=yes
+ break
+ fi
+ done
+ if [ $found = no ]
+ then
+ [ -n "$LFLAGS" ] && LDFLAGS=" $LFDLAGS"
+ LDFLAGS="-L${libdir}$LDFLAGS"
+ fi
+ [ -z "$LDFLAGS" ] && LDFLAGS="-L${libdir}"
+
+ # Ignore -L options which do not correspond to an actual directory,
+ # or which are standard library directories (i.e., the linker is
+ # supposed to search those directories).
+ #
+ # There is no portable way to find the list of standard library
+ # directories. Require a POSIX shell anyway, to keep this simple.
+ lib_flags=
+ for opt in $LDFLAGS $LIBS
+ do
+ case $opt in
+ -L*)
+ opt_lib=`echo "x$opt" | sed -e 's/^x-L//'`
+ [ -d "$opt_lib" ] || continue
+ case "$opt_lib" in
+ @LD_SEARCHPATH@) # skip standard libdir
+ continue
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ esac
+ lib_flags="$lib_flags $opt"
+ done
+
+ case "$1" in
+ -*=*)
+ ARG=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'`
+ ;;
+ *)
+ ARG=
+ ;;
+ esac
+
+ case "$1" in
+ # basic configuration
+ --prefix=*)
+ prefix="$ARG"
+ test -z "$exec_prefix" && exec_prefix="$ARG"
+ same_prefix=no
+ ;;
+ --prefix)
+ echo "$prefix"
+ ;;
+ --exec-prefix=*)
+ exec_prefix="$ARG"
+ same_exec_prefix=no
+ ;;
+ --exec-prefix)
+ echo "$exec_prefix"
+ ;;
+ # compile/link
+ --cflags|--cflags-only-I)
+ INCS="-I$includedir"
+ sed -e 's,^[ ]*,,' -e 's, [ ]*, ,g' -e 's,[ ]*$,,' <<-ENDECHO
+ $INCS
+ENDECHO
+ ;;
+ --cflags-only-other)
+ # no -D/-U options should be needed
+ echo
+ ;;
+ --ldflags)
+ OPTS=
+ for opt in $LDFLAGS $LIBS
+ do
+ case "x$opt" in
+ x-[^l]*)
+ OPTS="$OPTS $opt"
+ ;;
+ esac
+ done
+ printf "%s\n" "$OPTS"
+ ;;
+ --libs)
+ OPTS=
+ for opt in $lib_flags
+ do
+ [ -n "$OPTS" ] && OPTS="$OPTS "
+ OPTS="${OPTS}${opt}"
+ done
+ printf "%s\n" "$OPTS"
+ ;;
+ --libs-only-L)
+ OPTS=
+ for opt in $lib_flags
+ do
+ case "x$opt" in
+ x-L*)
+ [ -n "$OPTS" ] && OPTS="$OPTS "
+ OPTS="${OPTS}${opt}"
+ ;;
+ esac
+ done
+ printf "%s\n" "$OPTS"
+ ;;
+ --libs-only-l)
+ OPTS=
+ for opt in $lib_flags
+ do
+ case "x$opt" in
+ x-l*)
+ [ -n "$OPTS" ] && OPTS="$OPTS "
+ OPTS="${OPTS}${opt}"
+ ;;
+ esac
+ done
+ printf "%s\n" "$OPTS"
+ ;;
+ --libs-only-other)
+ OPTS=
+ for opt in $lib_flags
+ do
+ case "x$opt" in
+ x-[lL]*)
+ ;;
+ *)
+ [ -n "$OPTS" ] && OPTS="$OPTS "
+ OPTS="${OPTS}${opt}"
+ ;;
+ esac
+ done
+ printf "%s\n" "$OPTS"
+ ;;
+ # identification
+ --version)
+ echo "@VERSION_MAJOR@.@VERSION_MINOR@.@VERSION_PATCH@"
+ ;;
+ --abi-version)
+ echo "@VERSION@" | sed -e 's/:/./g'
+ ;;
+ # locations
+ --bindir)
+ echo "${bindir}"
+ ;;
+ --datadir)
+ echo "${datadir}"
+ ;;
+ --libdir)
+ echo "${libdir}"
+ ;;
+ --mandir)
+ echo "${mandir}"
+ ;;
+ # general info
+ --help)
+ cat <<ENDHELP
+Usage: ${THIS}-config [options]
+
+Options:
+ --prefix echos the package-prefix of ${THIS}
+ --prefix=ARG sets the package-prefix of ${THIS}
+ --exec-prefix echos the executable-prefix of ${THIS}
+ --exec-prefix=ARG sets the executable-prefix of ${THIS}
+
+ --cflags echos the C compiler flags needed to compile with ${THIS}
+ --ldflags echos the linker flags needed to link with ${THIS}
+
+ --libs echos the libraries needed to link with ${THIS}
+ --libs-only-L echos -L linker options (search path) for ${THIS}
+ --libs-only-l echos -l linker options (libraries) for ${THIS}
+ --libs-only-other echos linker options other than -L/-l
+
+ --version echos the release+patchdate version of ${THIS}
+ --abi-version echos the ABI version of ${THIS}
+
+ --bindir echos the directory containing ${THIS} programs
+ --datadir echos the directory containing ${THIS} data
+ --libdir echos the directory containing ${THIS} libraries
+ --mandir echos the directory containing ${THIS} manual pages
+
+ --help prints this message
+ENDHELP
+ ;;
+ --error|*)
+ @SHELL@ "$0" --help 1>&2
+ exit 1
+ ;;
+ esac
+ shift
+done
+# vile:shmode
Index: sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/dialog.m4
===================================================================
--- sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/dialog.m4 (nonexistent)
+++ sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/dialog.m4 (revision 34)
@@ -0,0 +1,324 @@
+dnl #
+dnl # /usr/share/aclocal/dialog.m4
+dnl #
+dnl # Configure paths for dialog
+dnl # Andrew V.Kosteltsev
+
+dnl ============================================================
+dnl
+dnl Synopsis:
+dnl AC_CHECK_DIALOG([MIN-VERSION [, # minimum dialog version, e.g. 1.3-20190211
+dnl DEFAULT-WITH-DIALOG [, # default value for --with-dialog option
+dnl DEFAULT-WITH-DIALOG-TEST [,# default value for --with-dialog-test option
+dnl EXTEND-VARS [, # whether CFLAGS/LDFLAGS/etc are extended
+dnl ACTION-IF-FOUND [, # action to perform if dialog was found
+dnl ACTION-IF-NOT-FOUND # action to perform if dialog was not found
+dnl ]]]]]])
+dnl Examples:
+dnl AC_CHECK_DIALOG(1.3-20210621)
+dnl AC_CHECK_DIALOG(1.3-20210621,,,no,CFLAGS="$CFLAGS -DHAVE_DIALOG $DIALOG_CFLAGS")
+dnl AC_CHECK_DIALOG(1.3-20210621,yes,yes,yes,CFLAGS="$CFLAGS -DHAVE_DIALOG")
+dnl
+dnl
+dnl If you have to change prefix returned by dialog-config script or change
+dnl location of dialog-config, you may set environment variable DIALOG_CONFIG,
+dnl for example:
+dnl
+dnl # export DIALOG_CONFIG="dialog-config --prefix=/usr/local"
+dnl # export DIALOG_CONFIG="/usr/bin/dialog-config --prefix=/usr/local"
+dnl
+dnl ============================================================
+dnl
+dnl ============================================================
+dnl auxilliary macros
+dnl ============================================================
+AC_DEFUN([_AC_DIALOG_ERROR], [dnl
+AC_MSG_RESULT([*FAILED*])
+cat <<EOT | sed -e 's/^[[ ]]*/ | /' -e 's/>>/ /' 1>&2
+$1
+EOT
+exit 1
+])
+
+AC_DEFUN([_AC_DIALOG_VERBOSE], [dnl
+if test ".$verbose" = .yes; then
+ AC_MSG_RESULT([ $1])
+fi
+])
+
+dnl ============================================================
+dnl the user macro
+dnl ============================================================
+AC_DEFUN([AC_CHECK_DIALOG], [dnl
+dnl
+dnl ============================================================
+dnl prerequisites
+dnl ============================================================
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_CPP])dnl
+dnl
+dnl ============================================================
+dnl set DIALOG_CONFIG variable
+dnl ============================================================
+if test -z "$DIALOG_CONFIG"; then
+ DIALOG_CONFIG='dialog-config'
+fi
+dnl
+DIALOG_CFLAGS=''
+DIALOG_LDFLAGS=''
+DIALOG_LIBS=''
+AC_SUBST(DIALOG_CFLAGS)
+AC_SUBST(DIALOG_LDFLAGS)
+AC_SUBST(DIALOG_LIBS)
+dnl
+dnl ============================================================
+dnl command line options
+dnl ============================================================
+_AC_DIALOG_VERBOSE([])
+AC_ARG_WITH(dialog,dnl
+[ --with-dialog[=ARG] Build with dialog Library (default=]ifelse([$2],,yes,$2)[)],dnl
+,dnl
+with_dialog="ifelse([$2],,yes,$2)"
+)dnl
+AC_ARG_WITH(dialog-test,dnl
+[ --with-dialog-test Perform dialog Sanity Test (default=]ifelse([$3],,yes,$3)[)],dnl
+,dnl
+with_dialog_test="ifelse([$3],,yes,$3)"
+)dnl
+_AC_DIALOG_VERBOSE([+ Command Line Options:])
+_AC_DIALOG_VERBOSE([ o --with-dialog=$with_dialog])
+_AC_DIALOG_VERBOSE([ o --with-dialog-test=$with_dialog_test])
+dnl
+dnl ============================================================
+dnl configuration
+dnl ============================================================
+if test ".$with_dialog" != .no; then
+ dialog_subdir=no
+ dialog_subdir_opts=''
+ case "$with_dialog" in
+ subdir:* )
+ dialog_subdir=yes
+ changequote(, )dnl
+ dialog_subdir_opts=`echo $with_dialog | sed -e 's/^subdir:[^ ]*[ ]*//'`
+ with_dialog=`echo $with_dialog | sed -e 's/^subdir:\([^ ]*\).*$/\1/'`
+ changequote([, ])dnl
+ ;;
+ esac
+ dialog_version=""
+ dialog_location=""
+ dialog_type=""
+ dialog_cflags=""
+ dialog_ldflags=""
+ dialog_libs=""
+ if test ".$with_dialog" = .yes; then
+ # via config script in $PATH
+ changequote(, )dnl
+ dialog_version=`($DIALOG_CONFIG --version) 2>/dev/null |\
+ sed -e 's/^.*\([0-9]\.[0-9]*[-][0-9]*\).*$/\1/'`
+ changequote([, ])dnl
+ if test ".$dialog_version" != .; then
+ dialog_location=`$DIALOG_CONFIG --prefix`
+ dialog_type='installed'
+ dialog_cflags=`$DIALOG_CONFIG --cflags`
+ dialog_ldflags=`$DIALOG_CONFIG --ldflags`
+ dialog_libs=`$DIALOG_CONFIG --libs`
+ fi
+ elif test -d "$with_dialog"; then
+ with_dialog=`echo $with_dialog | sed -e 's;/*$;;'`
+ dialog_found=no
+ # via config script under a specified directory
+ # (a standard installation, but not a source tree)
+ if test ".$dialog_found" = .no; then
+ for _dir in $with_dialog/bin $with_dialog; do
+ if test -f "$_dir/dialog-config"; then
+ test -f "$_dir/dialog-config.in" && continue # dialog-config in source tree!
+ changequote(, )dnl
+ dialog_version=`($_dir/dialog-config --version) 2>/dev/null |\
+ sed -e 's/^.*\([0-9]\.[0-9]*[.][0-9]*\).*$/\1/'`
+ changequote([, ])dnl
+ if test ".$dialog_version" != .; then
+ dialog_location=`$_dir/dialog-config --prefix`
+ dialog_type="installed"
+ dialog_cflags=`$_dir/dialog-config --cflags`
+ dialog_ldflags=`$_dir/dialog-config --ldflags`
+ dialog_libs=`$_dir/dialog-config --libs`
+ dialog_found=yes
+ break
+ fi
+ fi
+ done
+ fi
+ fi
+ _AC_DIALOG_VERBOSE([+ Determined Location:])
+ _AC_DIALOG_VERBOSE([ o path: $dialog_location])
+ _AC_DIALOG_VERBOSE([ o type: $dialog_type])
+ if test ".$dialog_version" = .; then
+ if test ".$with_dialog" != .yes; then
+ _AC_DIALOG_ERROR([dnl
+ Unable to locate dialog under $with_dialog.
+ Please specify the correct path to either a dialog installation tree
+ (use --with-dialog=DIR if you used --prefix=DIR for installing dialog in
+ the past).])
+ else
+ _AC_DIALOG_ERROR([dnl
+ Unable to locate dialog in any system-wide location (see \$PATH).
+ Please specify the correct path to either a dialog installation tree
+ (use --with-dialog=DIR if you used --prefix=DIR for installing dialog in
+ the past, or set the DIALOG_CONFIG environment variable to the full path
+ to dialog-config).])
+ fi
+ fi
+ dnl ========================================================
+ dnl Check whether the found version is sufficiently new
+ dnl ========================================================
+ _req_version="ifelse([$1],,1.0.0,$1)"
+ for _var in dialog_version _req_version; do
+ eval "_val=\"\$${_var}\""
+ _major=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[.]]\)\([[0-9]]*\)/\1/'`
+ _minor=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[.]]\)\([[0-9]]*\)/\2/'`
+ _micro=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[.]]\)\([[0-9]]*\)/\4/'`
+ _hex=`echo dummy | awk '{ printf("%d%02d%02d", major, minor, micro); }' \
+ "major=$_major" "minor=$_minor" "micro=$_micro"`
+ eval "${_var}_hex=\"\$_hex\""
+ done
+ _AC_DIALOG_VERBOSE([+ Determined Versions:])
+ _AC_DIALOG_VERBOSE([ o existing: $dialog_version -> 0x$dialog_version_hex])
+ _AC_DIALOG_VERBOSE([ o required: $_req_version -> 0x$_req_version_hex])
+ _ok=0
+ if test ".$dialog_version_hex" != .; then
+ if test ".$_req_version_hex" != .; then
+ if test $dialog_version_hex -ge $_req_version_hex; then
+ _ok=1
+ fi
+ fi
+ fi
+ if test ".$_ok" = .0; then
+ _AC_DIALOG_ERROR([dnl
+ Found dialog version $dialog_version, but required at least version $_req_version.
+ Upgrade dialog under $dialog_location to $_req_version or higher first, please.])
+ fi
+ dnl ========================================================
+ dnl Perform dialog Sanity Compile Check
+ dnl ========================================================
+ if test ".$with_dialog_test" = .yes; then
+ _ac_save_CFLAGS="$CFLAGS"
+ _ac_save_LDFLAGS="$LDFLAGS"
+ _ac_save_LIBS="$LIBS"
+ CFLAGS="$CFLAGS $dialog_cflags"
+ LDFLAGS="$LDFLAGS $dialog_ldflags"
+ LIBS="$LIBS $dialog_libs"
+ _AC_DIALOG_VERBOSE([+ Test Build Environment:])
+ _AC_DIALOG_VERBOSE([ o CFLAGS="$CFLAGS"])
+ _AC_DIALOG_VERBOSE([ o LDFLAGS="$LDFLAGS"])
+ _AC_DIALOG_VERBOSE([ o LIBS="$LIBS"])
+ cross_compile=no
+ define([_code1], [
+#include <stdlib.h>
+#include <stdio.h>
+#include <strings.h> /* index(3) */
+
+#include <dialog.h>
+#include <dlg_colors.h>
+#include <dlg_keys.h>
+ ])
+ define([_code2], [
+ int status = 0;
+
+ bzero( (void *)&dialog_vars, sizeof(DIALOG_VARS) );
+
+ init_dialog(stdin, stdout);
+
+ dialog_vars.colors = 1;
+ dialog_vars.backtitle = "Test dialog Library";
+ dialog_vars.dlg_clear_screen = 1;
+ dialog_vars.sleep_secs = 1;
+
+
+ dlg_put_backtitle();
+
+ /*************************************************
+ Ruler: 68 characters + 2 spaces left and right:
+
+ | ----handy-ruler----------------------------------------------------- | */
+ status = dialog_msgbox( " Dialog ==>libdialog<== [required] ",
+ "\nPackage is installed and corect.\n",
+ 5, 72, 0 );
+
+ if( dialog_vars.sleep_secs )
+ (void)napms(dialog_vars.sleep_secs * 1000);
+
+ if( dialog_vars.dlg_clear_screen )
+ {
+ dlg_clear();
+ (void)refresh();
+ }
+ end_dialog();
+ ])
+ _AC_DIALOG_VERBOSE([+ Performing Sanity Checks:])
+ _AC_DIALOG_VERBOSE([ o pre-processor test])
+ AC_PREPROC_IFELSE([AC_LANG_PROGRAM([_code1], [_code2])], [_ok=yes], [_ok=no])
+ if test ".$_ok" != .yes; then
+ _AC_DIALOG_ERROR([dnl
+ Found dialog $dialog_version under $dialog_location, but
+ was unable to perform a sanity pre-processor check. This means
+ the dialog header dialog.h was not found.
+ We used the following build environment:
+ >> CPP="$CPP"
+ See config.log for possibly more details.])
+ fi
+ _AC_DIALOG_VERBOSE([ o link check])
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([_code1], [_code2])], [_ok=yes], [_ok=no])
+ if test ".$_ok" != .yes; then
+ _AC_DIALOG_ERROR([dnl
+ Found dialog $dialog_version under $dialog_location, but
+ was unable to perform a sanity linker check. This means
+ the dialog library libdialog.a was not found.
+ We used the following build environment:
+ >> CC="$CC"
+ >> CFLAGS="$CFLAGS"
+ >> LDFLAGS="$LDFLAGS"
+ >> LIBS="$LIBS"
+ See config.log for possibly more details.])
+ fi
+ _extendvars="ifelse([$4],,yes,$4)"
+ if test ".$_extendvars" != .yes; then
+ CFLAGS="$_ac_save_CFLAGS"
+ LDFLAGS="$_ac_save_LDFLAGS"
+ LIBS="$_ac_save_LIBS"
+ fi
+ else
+ _extendvars="ifelse([$4],,yes,$4)"
+ if test ".$_extendvars" = .yes; then
+ if test ".$dialog_subdir" = .yes; then
+ CFLAGS="$CFLAGS $dialog_cflags"
+ LDFLAGS="$LDFLAGS $dialog_ldflags"
+ LIBS="$LIBS $dialog_libs"
+ fi
+ fi
+ fi
+ DIALOG_CFLAGS="$dialog_cflags"
+ DIALOG_LDFLAGS="$dialog_ldflags"
+ DIALOG_LIBS="$dialog_libs"
+ AC_SUBST(DIALOG_CFLAGS)
+ AC_SUBST(DIALOG_LDFLAGS)
+ AC_SUBST(DIALOG_LIBS)
+
+ AC_SUBST(HAVE_DIALOG, [1])
+
+ AC_CHECK_HEADERS(dialog.h dlg_colors.h dlg_keys.h)
+
+ _AC_DIALOG_VERBOSE([+ Final Results:])
+ _AC_DIALOG_VERBOSE([ o DIALOG_CFLAGS="$DIALOG_CFLAGS"])
+ _AC_DIALOG_VERBOSE([ o DIALOG_LDFLAGS="$DIALOG_LDFLAGS"])
+ _AC_DIALOG_VERBOSE([ o DIALOG_LIBS="$DIALOG_LIBS"])
+fi
+if test ".$with_dialog" != .no; then
+ AC_MSG_CHECKING(for libdialog)
+ AC_MSG_RESULT([version $dialog_version, $dialog_type under $dialog_location])
+ ifelse([$5], , :, [$5])
+else
+ AC_MSG_CHECKING(for libdialog)
+ AC_MSG_RESULT([no])
+ ifelse([$6], , :, [$6])
+fi
+])
Index: sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/fselect.c
===================================================================
--- sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/fselect.c (nonexistent)
+++ sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/fselect.c (revision 34)
@@ -0,0 +1,941 @@
+/*
+ * $Id: fselect.c,v 1.119 2022/04/03 22:38:16 tom Exp $
+ *
+ * fselect.c -- implements the file-selector box
+ *
+ * Copyright 2000-2021,2022 Thomas E. Dickey
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License, version 2.1
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to
+ * Free Software Foundation, Inc.
+ * 51 Franklin St., Fifth Floor
+ * Boston, MA 02110, USA.
+ */
+
+#include <dlg_internals.h>
+#include <dlg_keys.h>
+
+#define EXT_WIDE 1
+#define HDR_HIGH 1
+#define BTN_HIGH (1 + 2 * MARGIN) /* Ok/Cancel, also input-box */
+#define MIN_HIGH (HDR_HIGH - MARGIN + (BTN_HIGH * 2) + 4 * MARGIN)
+#define MIN_WIDE (2 * MAX(dlg_count_columns(d_label), dlg_count_columns(f_label)) + 6 * MARGIN + 2 * EXT_WIDE)
+
+#define MOUSE_D (KEY_MAX + 0)
+#define MOUSE_F (KEY_MAX + 10000)
+#define MOUSE_T (KEY_MAX + 20000)
+
+typedef enum {
+ sDIRS = -3
+ ,sFILES = -2
+ ,sTEXT = -1
+} STATES;
+
+typedef struct {
+ WINDOW *par; /* parent window */
+ WINDOW *win; /* this window */
+ int length; /* length of the data[] array */
+ int offset; /* index of first item on screen */
+ int choice; /* index of the selection */
+ int mousex; /* base of mouse-code return-values */
+ unsigned allocd;
+ char **data;
+} LIST;
+
+typedef struct {
+ int length;
+ char **data;
+} MATCH;
+
+static void
+init_list(LIST * list, WINDOW *par, WINDOW *win, int mousex)
+{
+ list->par = par;
+ list->win = win;
+ list->length = 0;
+ list->offset = 0;
+ list->choice = 0;
+ list->mousex = mousex;
+ list->allocd = 0;
+ list->data = 0;
+ dlg_mouse_mkbigregion(getbegy(win), getbegx(win),
+ getmaxy(win), getmaxx(win),
+ mousex, 1, 1, 1 /* by lines */ );
+}
+
+static char *
+leaf_of(char *path)
+{
+ char *leaf = strrchr(path, '/');
+ if (leaf != 0)
+ leaf++;
+ else
+ leaf = path;
+ return leaf;
+}
+
+static char *
+data_of(LIST * list)
+{
+ if (list != 0
+ && list->data != 0)
+ return list->data[list->choice];
+ return 0;
+}
+
+static void
+free_list(LIST * list, int reinit)
+{
+ if (list->data != 0) {
+ int n;
+
+ for (n = 0; list->data[n] != 0; n++)
+ free(list->data[n]);
+ free(list->data);
+ list->data = 0;
+ }
+ if (reinit)
+ init_list(list, list->par, list->win, list->mousex);
+}
+
+static void
+add_to_list(LIST * list, char *text)
+{
+ unsigned need;
+
+ need = (unsigned) (list->length + 1);
+ if (need + 1 > list->allocd) {
+ list->allocd = 2 * (need + 1);
+ if (list->data == 0) {
+ list->data = dlg_malloc(char *, list->allocd);
+ } else {
+ list->data = dlg_realloc(char *, list->allocd, list->data);
+ }
+ assert_ptr(list->data, "add_to_list");
+ }
+ list->data[list->length++] = dlg_strclone(text);
+ list->data[list->length] = 0;
+}
+
+static void
+keep_visible(LIST * list)
+{
+ int high = getmaxy(list->win);
+
+ if (list->choice < list->offset) {
+ list->offset = list->choice;
+ }
+ if (list->choice - list->offset >= high)
+ list->offset = list->choice - high + 1;
+}
+
+#define Value(c) (int)((c) & 0xff)
+
+static int
+find_choice(char *target, LIST * list)
+{
+ int choice = list->choice;
+
+ if (*target == 0) {
+ list->choice = 0;
+ } else {
+ int n;
+ int len_1, cmp_1;
+
+ /* find the match with the longest length. If more than one has the
+ * same length, choose the one with the closest match of the final
+ * character.
+ */
+ len_1 = 0;
+ cmp_1 = 256;
+ for (n = 0; n < list->length; n++) {
+ char *a = target;
+ char *b = list->data[n];
+ int len_2, cmp_2;
+
+ len_2 = 0;
+ while ((*a != 0) && (*b != 0) && (*a == *b)) {
+ a++;
+ b++;
+ len_2++;
+ }
+ cmp_2 = Value(*a) - Value(*b);
+ if (cmp_2 < 0)
+ cmp_2 = -cmp_2;
+ if ((len_2 > len_1)
+ || (len_1 == len_2 && cmp_2 < cmp_1)) {
+ len_1 = len_2;
+ cmp_1 = cmp_2;
+ list->choice = n;
+ }
+ }
+ }
+ if (choice != list->choice) {
+ keep_visible(list);
+ }
+ return (choice != list->choice);
+}
+
+static void
+display_list(LIST * list)
+{
+ if (list->win != 0) {
+ int n;
+ int x;
+ int y;
+ int top;
+ int bottom;
+
+ dlg_attr_clear(list->win, getmaxy(list->win), getmaxx(list->win), item_attr);
+ for (n = list->offset; n < list->length && list->data[n]; n++) {
+ y = n - list->offset;
+ if (y >= getmaxy(list->win))
+ break;
+ (void) wmove(list->win, y, 0);
+ if (n == list->choice)
+ dlg_attrset(list->win, item_selected_attr);
+ (void) waddstr(list->win, list->data[n]);
+ dlg_attrset(list->win, item_attr);
+ }
+ dlg_attrset(list->win, item_attr);
+
+ getparyx(list->win, y, x);
+
+ top = y - 1;
+ bottom = y + getmaxy(list->win);
+ dlg_draw_scrollbar(list->par,
+ (long) list->offset,
+ (long) list->offset,
+ (long) (list->offset + getmaxy(list->win)),
+ (long) (list->length),
+ x + 1,
+ x + getmaxx(list->win),
+ top,
+ bottom,
+ menubox_border2_attr,
+ menubox_border_attr);
+
+ (void) wmove(list->win, list->choice - list->offset, 0);
+ (void) wnoutrefresh(list->win);
+ }
+}
+
+/* FIXME: see arrows.c
+ * This workaround is used to allow two lists to have scroll-tabs at the same
+ * time, by reassigning their return-values to be different. Just for
+ * readability, we use the names of keys with similar connotations, though all
+ * that is really required is that they're distinct, so we can put them in a
+ * switch statement.
+ */
+#if USE_MOUSE
+static void
+fix_arrows(LIST * list)
+{
+ if (list->win != 0) {
+ int x;
+ int y;
+ int top;
+ int right;
+ int bottom;
+
+ getparyx(list->win, y, x);
+ top = y - 1;
+ right = getmaxx(list->win);
+ bottom = y + getmaxy(list->win);
+
+ mouse_mkbutton(top, x, right,
+ ((list->mousex == MOUSE_D)
+ ? KEY_PREVIOUS
+ : KEY_PPAGE));
+ mouse_mkbutton(bottom, x, right,
+ ((list->mousex == MOUSE_D)
+ ? KEY_NEXT
+ : KEY_NPAGE));
+ }
+}
+
+#else
+#define fix_arrows(list) /* nothing */
+#endif
+
+static bool
+show_list(char *target, LIST * list, bool keep)
+{
+ bool changed = keep || find_choice(target, list);
+ display_list(list);
+ return changed;
+}
+
+/*
+ * Highlight the closest match to 'target' in the given list, setting offset
+ * to match.
+ */
+static bool
+show_both_lists(char *input, LIST * d_list, LIST * f_list, bool keep)
+{
+ char *leaf = leaf_of(input);
+
+ return show_list(leaf, d_list, keep) || show_list(leaf, f_list, keep);
+}
+
+/*
+ * Move up/down in the given list
+ */
+static bool
+change_list(int choice, LIST * list)
+{
+ if (data_of(list) != 0) {
+ int last = list->length - 1;
+
+ choice += list->choice;
+ if (choice < 0)
+ choice = 0;
+ if (choice > last)
+ choice = last;
+ list->choice = choice;
+ keep_visible(list);
+ display_list(list);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+scroll_list(int direction, LIST * list)
+{
+ if (data_of(list) != 0) {
+ int length = getmaxy(list->win);
+ if (change_list(direction * length, list))
+ return;
+ }
+ beep();
+}
+
+static int
+compar(const void *a, const void *b)
+{
+ return strcmp(*(const char *const *) a, *(const char *const *) b);
+}
+
+static void
+match(char *name, LIST * d_list, LIST * f_list, MATCH * match_list)
+{
+ char *test = leaf_of(name);
+ size_t test_len = strlen(test);
+ char **matches = dlg_malloc(char *, (size_t) (d_list->length + f_list->length));
+ size_t data_len = 0;
+
+ if (matches != 0) {
+ int i;
+ char **new_ptr;
+
+ for (i = 2; i < d_list->length; i++) {
+ if (strncmp(test, d_list->data[i], test_len) == 0) {
+ matches[data_len++] = d_list->data[i];
+ }
+ }
+ for (i = 0; i < f_list->length; i++) {
+ if (strncmp(test, f_list->data[i], test_len) == 0) {
+ matches[data_len++] = f_list->data[i];
+ }
+ }
+ if ((new_ptr = dlg_realloc(char *, data_len + 1, matches)) != 0) {
+ matches = new_ptr;
+ } else {
+ free(matches);
+ matches = 0;
+ data_len = 0;
+ }
+ }
+ match_list->data = matches;
+ match_list->length = (int) data_len;
+}
+
+static void
+free_match(MATCH * match_list)
+{
+ free(match_list->data);
+ match_list->length = 0;
+}
+
+static int
+complete(char *name, LIST * d_list, LIST * f_list, char **buff_ptr)
+{
+ MATCH match_list;
+ char *test;
+ size_t test_len;
+ size_t i;
+ char *buff;
+
+ match(name, d_list, f_list, &match_list);
+ if (match_list.length == 0) {
+ free(match_list.data);
+ *buff_ptr = NULL;
+ return 0;
+ }
+
+ test = match_list.data[0];
+ test_len = strlen(test);
+ buff = dlg_malloc(char, test_len + 2);
+ if (match_list.length == 1) {
+ strcpy(buff, test);
+ i = test_len;
+ if (test == data_of(d_list)) {
+ buff[test_len] = '/';
+ i++;
+ }
+ } else {
+ int j;
+ char *next;
+
+ for (i = 0; i < test_len; i++) {
+ char test_char = test[i];
+ if (test_char == '\0')
+ break;
+ for (j = 0; j < match_list.length; j++) {
+ if (match_list.data[j][i] != test_char) {
+ break;
+ }
+ }
+ if (j == match_list.length) {
+ (buff)[i] = test_char;
+ } else
+ break;
+ }
+ next = dlg_realloc(char, i + 1, buff);
+ if (next == NULL) {
+ free(buff);
+ *buff_ptr = NULL;
+ return 0;
+ }
+ buff = next;
+ }
+ free_match(&match_list);
+ buff[i] = '\0';
+ *buff_ptr = buff;
+ return (i != 0);
+}
+
+static bool
+fill_lists(char *current, char *input, LIST * d_list, LIST * f_list, bool keep)
+{
+ bool result = TRUE;
+ bool rescan = FALSE;
+ struct stat sb;
+ int n;
+ char path[MAX_LEN + 1];
+
+ /* check if we've updated the lists */
+ for (n = 0; current[n] && input[n]; n++) {
+ if (current[n] != input[n])
+ break;
+ }
+
+ if (current[n] == input[n]) {
+ result = FALSE;
+ rescan = (n == 0 && d_list->length == 0);
+ } else if (strchr(current + n, '/') == 0
+ && strchr(input + n, '/') == 0) {
+ result = show_both_lists(input, d_list, f_list, keep);
+ } else {
+ rescan = TRUE;
+ }
+
+ if (rescan) {
+ DIR *dp;
+ size_t have = strlen(input);
+ char *leaf;
+
+ if (have > MAX_LEN)
+ have = MAX_LEN;
+ memcpy(current, input, have);
+ current[have] = '\0';
+
+ /* refill the lists */
+ free_list(d_list, TRUE);
+ free_list(f_list, TRUE);
+ memcpy(path, current, have);
+ path[have] = '\0';
+ if ((leaf = strrchr(path, '/')) != 0) {
+ *++leaf = 0;
+ } else {
+ strcpy(path, "./");
+ leaf = path + strlen(path);
+ }
+ DLG_TRACE(("opendir '%s'\n", path));
+ if ((dp = opendir(path)) != 0) {
+ DIRENT *de;
+
+ while ((de = readdir(dp)) != 0) {
+ size_t len = NAMLEN(de);
+ if (len == 0 || (len + have + 2) >= MAX_LEN)
+ continue;
+ memcpy(leaf, de->d_name, len);
+ leaf[len] = '\0';
+ if (stat(path, &sb) == 0) {
+ if ((sb.st_mode & S_IFMT) == S_IFDIR)
+ add_to_list(d_list, leaf);
+ else if (f_list->win)
+ add_to_list(f_list, leaf);
+ }
+ }
+ (void) closedir(dp);
+ /* sort the lists */
+ if (d_list->data != 0 && d_list->length > 1) {
+ qsort(d_list->data,
+ (size_t) d_list->length,
+ sizeof(d_list->data[0]),
+ compar);
+ }
+ if (f_list->data != 0 && f_list->length > 1) {
+ qsort(f_list->data,
+ (size_t) f_list->length,
+ sizeof(f_list->data[0]),
+ compar);
+ }
+ }
+
+ (void) show_both_lists(input, d_list, f_list, FALSE);
+ d_list->offset = d_list->choice;
+ f_list->offset = f_list->choice;
+ result = TRUE;
+ }
+ return result;
+}
+
+static bool
+usable_state(int state, LIST * dirs, LIST * files)
+{
+ bool result;
+
+ switch (state) {
+ case sDIRS:
+ result = (dirs->win != 0) && (data_of(dirs) != 0);
+ break;
+ case sFILES:
+ result = (files->win != 0) && (data_of(files) != 0);
+ break;
+ default:
+ result = TRUE;
+ break;
+ }
+ return result;
+}
+
+#define which_list() ((state == sFILES) \
+ ? &f_list \
+ : ((state == sDIRS) \
+ ? &d_list \
+ : 0))
+#define NAVIGATE_BINDINGS \
+ DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ), \
+ DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ), \
+ DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ), \
+ DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_DOWN ), \
+ DLG_KEYS_DATA( DLGK_ITEM_NEXT, CHR_NEXT ), \
+ DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_NEXT ), \
+ DLG_KEYS_DATA( DLGK_ITEM_PREV, CHR_PREVIOUS ), \
+ DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_UP ), \
+ DLG_KEYS_DATA( DLGK_PAGE_NEXT, KEY_NPAGE ), \
+ DLG_KEYS_DATA( DLGK_PAGE_PREV, KEY_PPAGE )
+
+/*
+ * Display a dialog box for entering a filename
+ */
+static int
+dlg_fselect(const char *title, const char *path, int height, int width, int dselect)
+{
+ /* *INDENT-OFF* */
+ static DLG_KEYS_BINDING binding[] = {
+ HELPKEY_BINDINGS,
+ ENTERKEY_BINDINGS,
+ NAVIGATE_BINDINGS,
+ TOGGLEKEY_BINDINGS,
+ END_KEYS_BINDING
+ };
+ static DLG_KEYS_BINDING binding2[] = {
+ INPUTSTR_BINDINGS,
+ HELPKEY_BINDINGS,
+ ENTERKEY_BINDINGS,
+ NAVIGATE_BINDINGS,
+ TOGGLEKEY_BINDINGS,
+ END_KEYS_BINDING
+ };
+ /* *INDENT-ON* */
+
+#ifdef KEY_RESIZE
+ int old_height = height;
+ int old_width = width;
+ bool resized = FALSE;
+#endif
+ int tbox_y, tbox_x, tbox_width, tbox_height;
+ int dbox_y, dbox_x, dbox_width, dbox_height;
+ int fbox_y, fbox_x, fbox_width, fbox_height;
+ int show_buttons = TRUE;
+ int offset = 0;
+ int key = 0;
+ int fkey = FALSE;
+ int code;
+ int result = DLG_EXIT_UNKNOWN;
+ int state = dialog_vars.default_button >= 0 ? dlg_default_button() : sTEXT;
+ int button;
+ bool first = (state == sTEXT);
+ bool first_trace = TRUE;
+ char *input;
+ char *completed;
+ char current[MAX_LEN + 1];
+ WINDOW *dialog = 0;
+ WINDOW *w_text = 0;
+ WINDOW *w_work = 0;
+ const char **buttons = dlg_ok_labels();
+ const char *d_label = _("Directories");
+ const char *f_label = _("Files");
+ char *partial = 0;
+ int min_wide = MIN_WIDE;
+ int min_items = height ? 0 : 4;
+ LIST d_list, f_list;
+
+ DLG_TRACE(("# %s args:\n", dselect ? "dselect" : "fselect"));
+ DLG_TRACE2S("title", title);
+ DLG_TRACE2S("path", path);
+ DLG_TRACE2N("height", height);
+ DLG_TRACE2N("width", width);
+
+ dlg_does_output();
+
+ /* Set up the initial value */
+ input = dlg_set_result(path);
+ offset = (int) strlen(input);
+ *current = 0;
+
+ dlg_button_layout(buttons, &min_wide);
+
+#ifdef KEY_RESIZE
+ retry:
+#endif
+ if (height > 0)
+ height += MIN_HIGH;
+ dlg_auto_size(title, "", &height, &width, MIN_HIGH + min_items, min_wide);
+
+ dlg_print_size(height, width);
+ dlg_ctl_size(height, width);
+
+ dialog = dlg_new_window(height + 1, width,
+ dlg_box_y_ordinate(height),
+ dlg_box_x_ordinate(width));
+ dlg_register_window(dialog, "fselect", binding);
+ dlg_register_buttons(dialog, "fselect", buttons);
+
+ dlg_mouse_setbase(0, 0);
+
+ dlg_draw_box2(dialog, 0, 0, height + 1, width, dialog_attr, border_attr, border2_attr);
+ dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
+ dlg_draw_title(dialog, title);
+
+ dlg_attrset(dialog, dialog_attr);
+
+ /* Draw the input field box */
+ tbox_height = 1;
+ tbox_width = width - (4 * MARGIN + 2);
+ tbox_y = height - (BTN_HIGH * 2) + MARGIN + 1;
+ tbox_x = (width - tbox_width) / 2;
+
+ w_text = dlg_der_window(dialog, tbox_height, tbox_width, tbox_y, tbox_x);
+ if (w_text == 0) {
+ result = DLG_EXIT_ERROR;
+ goto finish;
+ }
+
+ dlg_draw_box(dialog, tbox_y - MARGIN, tbox_x - MARGIN,
+ (2 * MARGIN + 1), tbox_width + (MARGIN + EXT_WIDE),
+ menubox_border_attr, menubox_border2_attr);
+ dlg_mouse_mkbigregion(getbegy(dialog) + tbox_y - MARGIN,
+ getbegx(dialog) + tbox_x - MARGIN,
+ 1 + (2 * MARGIN),
+ tbox_width + (MARGIN + EXT_WIDE),
+ MOUSE_T, 1, 1, 3 /* doesn't matter */ );
+
+ dlg_register_window(w_text, "fselect2", binding2);
+
+ /* Draw the directory listing box */
+ if (dselect)
+ dbox_width = (width - (6 * MARGIN));
+ else
+ dbox_width = (width - (6 * MARGIN + 2 * EXT_WIDE)) / 2;
+ dbox_height = height - MIN_HIGH;
+ dbox_y = (2 * MARGIN + 2);
+ dbox_x = tbox_x;
+
+ w_work = dlg_der_window(dialog, dbox_height, dbox_width, dbox_y, dbox_x);
+ if (w_work == 0) {
+ result = DLG_EXIT_ERROR;
+ goto finish;
+ }
+
+ (void) mvwaddstr(dialog, dbox_y - (MARGIN + 1), dbox_x - MARGIN, d_label);
+ dlg_draw_box(dialog,
+ dbox_y - MARGIN, dbox_x - MARGIN,
+ dbox_height + (MARGIN + 1), dbox_width + (MARGIN + 1),
+ menubox_border_attr, menubox_border2_attr);
+ init_list(&d_list, dialog, w_work, MOUSE_D);
+
+ if (!dselect) {
+ /* Draw the filename listing box */
+ fbox_height = dbox_height;
+ fbox_width = dbox_width;
+ fbox_y = dbox_y;
+ fbox_x = tbox_x + dbox_width + (2 * MARGIN);
+
+ w_work = dlg_der_window(dialog, fbox_height, fbox_width, fbox_y, fbox_x);
+ if (w_work == 0) {
+ result = DLG_EXIT_ERROR;
+ goto finish;
+ }
+
+ (void) mvwaddstr(dialog, fbox_y - (MARGIN + 1), fbox_x - MARGIN, f_label);
+ dlg_draw_box(dialog,
+ fbox_y - MARGIN, fbox_x - MARGIN,
+ fbox_height + (MARGIN + 1), fbox_width + (MARGIN + 1),
+ menubox_border_attr, menubox_border2_attr);
+ init_list(&f_list, dialog, w_work, MOUSE_F);
+ } else {
+ memset(&f_list, 0, sizeof(f_list));
+ }
+
+ while (result == DLG_EXIT_UNKNOWN) {
+
+ if (fill_lists(current, input, &d_list, &f_list, state < sTEXT))
+ show_buttons = TRUE;
+
+#ifdef KEY_RESIZE
+ if (resized) {
+ resized = FALSE;
+ dlg_show_string(w_text, input, offset, inputbox_attr,
+ 0, 0, tbox_width, FALSE, first);
+ }
+#endif
+
+ /*
+ * The last field drawn determines where the cursor is shown:
+ */
+ if (show_buttons) {
+ show_buttons = FALSE;
+ button = (state < 0) ? 0 : state;
+ dlg_draw_buttons(dialog, height - 1, 0, buttons, button, FALSE, width);
+ }
+
+ if (first_trace) {
+ first_trace = FALSE;
+ dlg_trace_win(dialog);
+ }
+
+ if (state < 0) {
+ switch (state) {
+ case sTEXT:
+ dlg_set_focus(dialog, w_text);
+ break;
+ case sFILES:
+ dlg_set_focus(dialog, f_list.win);
+ break;
+ case sDIRS:
+ dlg_set_focus(dialog, d_list.win);
+ break;
+ }
+ }
+
+ if (first) {
+ (void) wrefresh(dialog);
+ } else {
+ fix_arrows(&d_list);
+ fix_arrows(&f_list);
+ key = dlg_mouse_wgetch((state == sTEXT) ? w_text : dialog, &fkey);
+ if (dlg_result_key(key, fkey, &result)) {
+ if (!dlg_button_key(result, &button, &key, &fkey))
+ break;
+ }
+ }
+
+ if (key == DLGK_TOGGLE) {
+ key = DLGK_SELECT;
+ fkey = TRUE;
+ }
+
+ if (fkey) {
+ switch (key) {
+ case DLGK_MOUSE(KEY_PREVIOUS):
+ state = sDIRS;
+ scroll_list(-1, which_list());
+ continue;
+ case DLGK_MOUSE(KEY_NEXT):
+ state = sDIRS;
+ scroll_list(1, which_list());
+ continue;
+ case DLGK_MOUSE(KEY_PPAGE):
+ state = sFILES;
+ scroll_list(-1, which_list());
+ continue;
+ case DLGK_MOUSE(KEY_NPAGE):
+ state = sFILES;
+ scroll_list(1, which_list());
+ continue;
+ case DLGK_PAGE_PREV:
+ scroll_list(-1, which_list());
+ continue;
+ case DLGK_PAGE_NEXT:
+ scroll_list(1, which_list());
+ continue;
+ case DLGK_ITEM_PREV:
+ if (change_list(-1, which_list()))
+ continue;
+ /* FALLTHRU */
+ case DLGK_FIELD_PREV:
+ show_buttons = TRUE;
+ do {
+ state = dlg_prev_ok_buttonindex(state, sDIRS);
+ } while (!usable_state(state, &d_list, &f_list));
+ continue;
+ case DLGK_ITEM_NEXT:
+ if (change_list(1, which_list()))
+ continue;
+ /* FALLTHRU */
+ case DLGK_FIELD_NEXT:
+ show_buttons = TRUE;
+ do {
+ state = dlg_next_ok_buttonindex(state, sDIRS);
+ } while (!usable_state(state, &d_list, &f_list));
+ continue;
+ case DLGK_SELECT:
+ completed = 0;
+ if (partial != 0) {
+ free(partial);
+ partial = 0;
+ }
+ if (state == sFILES && !dselect) {
+ completed = data_of(&f_list);
+ } else if (state == sDIRS) {
+ completed = data_of(&d_list);
+ } else {
+ if (complete(input, &d_list, &f_list, &partial)) {
+ completed = partial;
+ }
+ }
+ if (completed != 0) {
+ state = sTEXT;
+ show_buttons = TRUE;
+ strcpy(leaf_of(input), completed);
+ offset = (int) strlen(input);
+ dlg_show_string(w_text, input, offset, inputbox_attr,
+ 0, 0, tbox_width, 0, first);
+ if (partial != NULL) {
+ free(partial);
+ partial = 0;
+ }
+ continue;
+ } else { /* if (state < sTEXT) */
+ (void) beep();
+ continue;
+ }
+ /* FALLTHRU */
+ case DLGK_ENTER:
+ result = (state > 0) ? dlg_enter_buttoncode(state) : DLG_EXIT_OK;
+ continue;
+ case DLGK_LEAVE:
+ if (state >= 0)
+ result = dlg_ok_buttoncode(state);
+ break;
+#ifdef KEY_RESIZE
+ case KEY_RESIZE:
+ dlg_will_resize(dialog);
+ /* reset data */
+ height = old_height;
+ width = old_width;
+ show_buttons = TRUE;
+ *current = 0;
+ resized = TRUE;
+ /* repaint */
+ free_list(&d_list, FALSE);
+ free_list(&f_list, FALSE);
+ _dlg_resize_cleanup(dialog);
+ goto retry;
+#endif
+ default:
+ if (key >= DLGK_MOUSE(MOUSE_T)) {
+ state = sTEXT;
+ continue;
+ } else if (key >= DLGK_MOUSE(MOUSE_F)) {
+ if (f_list.win != 0) {
+ state = sFILES;
+ f_list.choice = (key - DLGK_MOUSE(MOUSE_F)) + f_list.offset;
+ display_list(&f_list);
+ }
+ continue;
+ } else if (key >= DLGK_MOUSE(MOUSE_D)) {
+ if (d_list.win != 0) {
+ state = sDIRS;
+ d_list.choice = (key - DLGK_MOUSE(MOUSE_D)) + d_list.offset;
+ display_list(&d_list);
+ }
+ continue;
+ } else if (is_DLGK_MOUSE(key)
+ && (code = dlg_ok_buttoncode(key - M_EVENT)) >= 0) {
+ result = code;
+ continue;
+ }
+ break;
+ }
+ }
+
+ if (state < 0) { /* Input box selected if we're editing */
+ int edit = dlg_edit_string(input, &offset, key, fkey, first);
+
+ if (edit) {
+ dlg_show_string(w_text, input, offset, inputbox_attr,
+ 0, 0, tbox_width, 0, first);
+ first = FALSE;
+ state = sTEXT;
+ }
+ } else if ((code = dlg_char_to_button(key, buttons)) >= 0) {
+ result = dlg_ok_buttoncode(code);
+ break;
+ }
+ }
+ AddLastKey();
+
+ dlg_unregister_window(w_text);
+ dlg_del_window(dialog);
+ dlg_mouse_free_regions();
+ free_list(&d_list, FALSE);
+ free_list(&f_list, FALSE);
+
+ finish:
+ if (partial != 0)
+ free(partial);
+ return result;
+}
+
+/*
+ * Display a dialog box for entering a filename
+ */
+int
+dialog_fselect(const char *title, const char *path, int height, int width)
+{
+ return dlg_fselect(title, path, height, width, FALSE);
+}
+
+/*
+ * Display a dialog box for entering a directory
+ */
+int
+dialog_dselect(const char *title, const char *path, int height, int width)
+{
+ return dlg_fselect(title, path, height, width, TRUE);
+}
Index: sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/menubox.c
===================================================================
--- sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/menubox.c (nonexistent)
+++ sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/menubox.c (revision 34)
@@ -0,0 +1,828 @@
+/*
+ * $Id: menubox.c,v 1.175 2022/04/05 00:14:56 tom Exp $
+ *
+ * menubox.c -- implements the menu box
+ *
+ * Copyright 2000-2021,2022 Thomas E. Dickey
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public Licens, version 2.1e
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to
+ * Free Software Foundation, Inc.
+ * 51 Franklin St., Fifth Floor
+ * Boston, MA 02110, USA.
+ *
+ * An earlier version of this program lists as authors
+ * Savio Lam (lam836@cs.cuhk.hk)
+ */
+
+#include <dlg_internals.h>
+#include <dlg_keys.h>
+
+typedef enum {
+ Unselected = 0,
+ Selected,
+ Editing
+} Mode;
+
+typedef struct {
+ /* the outer-window */
+ WINDOW *dialog;
+ int box_y;
+ int box_x;
+ int tag_x;
+ int item_x;
+ int menu_height;
+ int menu_width;
+ /* the inner-window */
+ WINDOW *menu;
+ DIALOG_LISTITEM *items;
+ int item_no;
+} ALL_DATA;
+
+#define MIN_HIGH 4
+
+#define INPUT_ROWS 3 /* rows per inputmenu entry */
+
+#define RowHeight(i) (is_inputmenu ? ((i) * INPUT_ROWS) : ((i) * 1))
+#define ItemToRow(i) (is_inputmenu ? ((i) * INPUT_ROWS + 1) : (i))
+#define RowToItem(i) (is_inputmenu ? ((i) / INPUT_ROWS + 0) : (i))
+
+/*
+ * Print menu item
+ */
+static void
+print_item(ALL_DATA * data,
+ WINDOW *win,
+ DIALOG_LISTITEM * item,
+ int choice,
+ Mode selected,
+ bool is_inputmenu)
+{
+ chtype save = dlg_get_attrs(win);
+ int climit = (data->item_x - data->tag_x - GUTTER);
+ int my_width = data->menu_width;
+ int my_x = data->item_x;
+ int my_y = ItemToRow(choice);
+ bool both = (!dialog_vars.no_tags && !dialog_vars.no_items);
+ bool first = TRUE;
+ chtype bordchar;
+ const char *show = (dialog_vars.no_items
+ ? item->name
+ : item->text);
+
+ switch (selected) {
+ default:
+ case Unselected:
+ bordchar = item_attr;
+ break;
+ case Selected:
+ bordchar = item_selected_attr;
+ break;
+ case Editing:
+ bordchar = dialog_attr;
+ break;
+ }
+
+ /* Clear 'residue' of last item and mark current current item */
+ if (is_inputmenu) {
+ int n;
+
+ dlg_attrset(win, (selected != Unselected) ? item_selected_attr : item_attr);
+ for (n = my_y - 1; n < my_y + INPUT_ROWS - 1; n++) {
+ wmove(win, n, 0);
+ wprintw(win, "%*s", my_width, " ");
+ }
+ } else {
+ dlg_attrset(win, menubox_attr);
+ wmove(win, my_y, 0);
+ wprintw(win, "%*s", my_width, " ");
+ }
+
+ /* highlight first char of the tag to be special */
+ if (both) {
+ (void) wmove(win, my_y, data->tag_x);
+ dlg_print_listitem(win, item->name, climit, first, selected);
+ first = FALSE;
+ }
+
+ /* Draw the input field box (only for inputmenu) */
+ (void) wmove(win, my_y, my_x);
+ if (is_inputmenu) {
+ my_width -= 1;
+ dlg_draw_box(win, my_y - 1, my_x, INPUT_ROWS, my_width - my_x - data->tag_x,
+ bordchar,
+ bordchar);
+ my_width -= 1;
+ ++my_x;
+ }
+
+ /* print actual item */
+ wmove(win, my_y, my_x);
+ dlg_print_listitem(win, show, my_width - my_x, first, selected);
+
+ if (selected) {
+ dlg_item_help(item->help);
+ }
+ dlg_attrset(win, save);
+}
+
+/*
+ * Allow the user to edit the text of a menu entry.
+ */
+static int
+input_menu_edit(ALL_DATA * data,
+ DIALOG_LISTITEM * items,
+ int choice,
+ char **resultp)
+{
+ chtype save = dlg_get_attrs(data->menu);
+ char *result;
+ int offset = 0;
+ int key = 0, fkey = 0;
+ bool first = TRUE;
+ /* see above */
+ bool is_inputmenu = TRUE;
+ int y = ItemToRow(choice);
+ int code = TRUE;
+ int max_len = dlg_max_input(MAX((int) strlen(items->text) + 1, MAX_LEN));
+
+ result = dlg_malloc(char, (size_t) max_len);
+ assert_ptr(result, "input_menu_edit");
+
+ /* original item is used to initialize the input string. */
+ result[0] = '\0';
+ strcpy(result, items->text);
+
+ print_item(data, data->menu, items, choice, Editing, TRUE);
+
+ /* taken out of inputbox.c - but somewhat modified */
+ for (;;) {
+ if (!first) {
+ int check = DLG_EXIT_UNKNOWN;
+ key = dlg_mouse_wgetch(data->menu, &fkey);
+ if (dlg_result_key(key, fkey, &check)) {
+ if (check == DLG_EXIT_CANCEL) {
+ code = FALSE;
+ break;
+ } else {
+ flash();
+ }
+ }
+ }
+ if (dlg_edit_string(result, &offset, key, fkey, first)) {
+ dlg_show_string(data->menu, result, offset, inputbox_attr,
+ y,
+ data->item_x + 1,
+ data->menu_width - data->item_x - 3,
+ FALSE, first);
+ first = FALSE;
+ } else if (key == ESC || key == TAB) {
+ code = FALSE;
+ break;
+ } else {
+ break;
+ }
+ }
+ print_item(data, data->menu, items, choice, Selected, TRUE);
+ dlg_attrset(data->menu, save);
+
+ *resultp = result;
+ return code;
+}
+
+static int
+handle_button(int code, DIALOG_LISTITEM * items, int choice)
+{
+ char *help_result;
+
+ switch (code) {
+ case DLG_EXIT_OK: /* FALLTHRU */
+ case DLG_EXIT_EXTRA:
+ dlg_add_string(items[choice].name);
+ break;
+ case DLG_EXIT_HELP:
+ dlg_add_help_listitem(&code, &help_result, &items[choice]);
+ dlg_add_string(help_result);
+ break;
+ }
+ AddLastKey();
+ return code;
+}
+
+int
+dlg_renamed_menutext(DIALOG_LISTITEM * items, int current, char *newtext)
+{
+ if (dialog_vars.input_result)
+ dialog_vars.input_result[0] = '\0';
+ dlg_add_result("RENAMED ");
+ dlg_add_string(items[current].name);
+ dlg_add_result(" ");
+ dlg_add_string(newtext);
+ AddLastKey();
+ return DLG_EXIT_EXTRA;
+}
+
+int
+dlg_dummy_menutext(DIALOG_LISTITEM * items, int current, char *newtext)
+{
+ (void) items;
+ (void) current;
+ (void) newtext;
+ return DLG_EXIT_ERROR;
+}
+
+static void
+print_menu(ALL_DATA * data,
+ int choice,
+ int scrollamt,
+ int max_choice,
+ int max_items,
+ bool is_inputmenu)
+{
+ int i;
+
+ for (i = 0; i < max_choice; i++) {
+ int ii = i + scrollamt;
+ if (ii < max_items)
+ print_item(data,
+ data->menu,
+ &data->items[ii],
+ i,
+ (i == choice) ? Selected : Unselected,
+ is_inputmenu);
+ }
+
+ /* Clean bottom lines */
+ if (is_inputmenu) {
+ int spare_lines, x_count;
+ spare_lines = data->menu_height % INPUT_ROWS;
+ dlg_attrset(data->menu, menubox_attr);
+ for (; spare_lines; spare_lines--) {
+ wmove(data->menu, data->menu_height - spare_lines, 0);
+ for (x_count = 0; x_count < data->menu_width;
+ x_count++) {
+ waddch(data->menu, ' ');
+ }
+ }
+ }
+
+ (void) wnoutrefresh(data->menu);
+
+ dlg_draw_scrollbar(data->dialog,
+ scrollamt,
+ scrollamt,
+ scrollamt + max_choice,
+ data->item_no,
+ data->box_x,
+ data->box_x + data->menu_width,
+ data->box_y,
+ data->box_y + data->menu_height + 1,
+ menubox_border2_attr,
+ menubox_border_attr);
+}
+
+static bool
+check_hotkey(DIALOG_LISTITEM * items, int choice)
+{
+ bool result = FALSE;
+
+ if (dlg_match_char(dlg_last_getc(),
+ (dialog_vars.no_tags
+ ? items[choice].text
+ : items[choice].name))) {
+ result = TRUE;
+ }
+ return result;
+}
+
+/*
+ * This is an alternate interface to 'menu' which allows the application
+ * to read the list item states back directly without putting them in the
+ * output buffer.
+ */
+int
+dlg_menu(const char *title,
+ const char *cprompt,
+ int height,
+ int width,
+ int menu_height,
+ int item_no,
+ DIALOG_LISTITEM * items,
+ int *current_item,
+ DIALOG_INPUTMENU rename_menutext)
+{
+ /* *INDENT-OFF* */
+ static DLG_KEYS_BINDING binding[] = {
+ HELPKEY_BINDINGS,
+ ENTERKEY_BINDINGS,
+ TOGGLEKEY_BINDINGS,
+ DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ),
+ DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ),
+ DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ),
+ DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ),
+ DLG_KEYS_DATA( DLGK_ITEM_NEXT, '+' ),
+ DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_DOWN ),
+ DLG_KEYS_DATA( DLGK_ITEM_NEXT, CHR_NEXT ),
+ DLG_KEYS_DATA( DLGK_ITEM_PREV, '-' ),
+ DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_UP ),
+ DLG_KEYS_DATA( DLGK_ITEM_PREV, CHR_PREVIOUS ),
+ DLG_KEYS_DATA( DLGK_PAGE_FIRST, KEY_HOME ),
+ DLG_KEYS_DATA( DLGK_PAGE_LAST, KEY_END ),
+ DLG_KEYS_DATA( DLGK_PAGE_LAST, KEY_LL ),
+ DLG_KEYS_DATA( DLGK_PAGE_NEXT, KEY_NPAGE ),
+ DLG_KEYS_DATA( DLGK_PAGE_PREV, KEY_PPAGE ),
+ END_KEYS_BINDING
+ };
+ static DLG_KEYS_BINDING binding2[] = {
+ INPUTSTR_BINDINGS,
+ HELPKEY_BINDINGS,
+ ENTERKEY_BINDINGS,
+ END_KEYS_BINDING
+ };
+ /* *INDENT-ON* */
+
+#ifdef KEY_RESIZE
+ int old_LINES = LINES;
+ int old_COLS = COLS;
+ int old_height = height;
+ int old_width = width;
+#endif
+ ALL_DATA all;
+ int i, j, x, y, cur_x, cur_y;
+ int fkey;
+ int button = dialog_state.visit_items ? -1 : dlg_default_button();
+ int choice = dlg_default_listitem(items);
+ int result = DLG_EXIT_UNKNOWN;
+ int scrollamt = 0;
+ int max_choice;
+ int use_width, name_width, text_width, list_width;
+ WINDOW *dialog, *menu;
+ char *prompt = 0;
+ const char **buttons = dlg_ok_labels();
+ bool is_inputmenu = ((rename_menutext != 0)
+ && (rename_menutext != dlg_dummy_menutext));
+
+ DLG_TRACE(("# menubox args:\n"));
+ DLG_TRACE2S("title", title);
+ DLG_TRACE2S("message", cprompt);
+ DLG_TRACE2N("height", height);
+ DLG_TRACE2N("width", width);
+ DLG_TRACE2N("lheight", menu_height);
+ DLG_TRACE2N("llength", item_no);
+ /* FIXME dump the items[][] too */
+ DLG_TRACE2N("rename", rename_menutext != 0);
+
+ dialog_state.plain_buttons = TRUE;
+
+ all.items = items;
+ all.item_no = item_no;
+
+ dlg_does_output();
+
+#ifdef KEY_RESIZE
+ retry:
+#endif
+
+ prompt = dlg_strclone(cprompt);
+ dlg_tab_correct_str(prompt);
+
+ all.menu_height = menu_height;
+ use_width = dlg_calc_list_width(item_no, items) + 10;
+ use_width = MAX(26, use_width);
+ if (all.menu_height == 0) {
+ /* calculate height without items (4) */
+ dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, use_width);
+ dlg_calc_listh(&height, &all.menu_height, item_no);
+ } else {
+ dlg_auto_size(title, prompt,
+ &height, &width,
+ MIN_HIGH + all.menu_height, use_width);
+ }
+ dlg_button_layout(buttons, &width);
+ dlg_print_size(height, width);
+ dlg_ctl_size(height, width);
+
+ x = dlg_box_x_ordinate(width);
+ y = dlg_box_y_ordinate(height);
+
+ dialog = dlg_new_window(height, width, y, x);
+ all.dialog = dialog;
+
+ dlg_register_window(dialog, "menubox", binding);
+ dlg_register_buttons(dialog, "menubox", buttons);
+
+ dlg_mouse_setbase(x, y);
+
+ dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr);
+ dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
+ dlg_draw_title(dialog, title);
+
+ dlg_attrset(dialog, dialog_attr);
+ dlg_print_autowrap(dialog, prompt, height, width);
+
+ all.menu_width = width - 6;
+ getyx(dialog, cur_y, cur_x);
+ all.box_y = cur_y + 1;
+ all.box_x = (width - all.menu_width) / 2 - 1;
+
+ /*
+ * After displaying the prompt, we know how much space we really have.
+ * Limit the list to avoid overwriting the ok-button.
+ */
+ if (all.menu_height + MIN_HIGH > height - cur_y)
+ all.menu_height = height - MIN_HIGH - cur_y;
+ if (all.menu_height <= 0)
+ all.menu_height = 1;
+
+ /* Find out maximal number of displayable items at once. */
+ max_choice = MIN(all.menu_height,
+ RowHeight(item_no));
+ if (is_inputmenu)
+ max_choice /= INPUT_ROWS;
+
+ /* create new window for the menu */
+ menu = dlg_sub_window(dialog, all.menu_height, all.menu_width,
+ y + all.box_y + 1,
+ x + all.box_x + 1);
+ all.menu = menu;
+
+ dlg_register_window(menu, "menu", binding2);
+ dlg_register_buttons(menu, "menu", buttons);
+
+ /* draw a box around the menu items */
+ dlg_draw_box(dialog,
+ all.box_y, all.box_x,
+ all.menu_height + 2, all.menu_width + 2,
+ menubox_border_attr, menubox_border2_attr);
+
+ name_width = 0;
+ text_width = 0;
+
+ /* Find length of longest item to center menu *
+ * only if --menu was given, using --inputmenu *
+ * won't be centered. */
+ for (i = 0; i < item_no; i++) {
+ name_width = MAX(name_width, dlg_count_columns(items[i].name));
+ text_width = MAX(text_width, dlg_count_columns(items[i].text));
+ }
+
+ /* If the name+text is wider than the list is allowed, then truncate
+ * one or both of them. If the name is no wider than 30% of the list,
+ * leave it intact.
+ *
+ * FIXME: the gutter width and name/list ratio should be configurable.
+ */
+ use_width = (all.menu_width - GUTTER);
+ if (dialog_vars.no_tags) {
+ list_width = MIN(use_width, text_width);
+ } else if (dialog_vars.no_items) {
+ list_width = MIN(use_width, name_width);
+ } else {
+ if (text_width >= 0
+ && name_width >= 0
+ && use_width > 0
+ && text_width + name_width > use_width) {
+ int need = (int) (0.30 * use_width);
+ if (name_width > need) {
+ int want = (int) (use_width
+ * ((double) name_width)
+ / (text_width + name_width));
+ name_width = (want > need) ? want : need;
+ }
+ text_width = use_width - name_width;
+ }
+ list_width = (text_width + name_width);
+ }
+
+ all.tag_x = (is_inputmenu
+ ? 0
+ : (use_width - list_width) / 2);
+ all.item_x = ((dialog_vars.no_tags
+ ? 0
+ : (dialog_vars.no_items
+ ? 0
+ : (GUTTER + name_width)))
+ + all.tag_x);
+
+ if (choice - scrollamt >= max_choice) {
+ scrollamt = choice - (max_choice - 1);
+ choice = max_choice - 1;
+ }
+#define PrintMenu() \
+ print_menu(&all, choice, scrollamt, max_choice, item_no, is_inputmenu)
+ PrintMenu();
+
+ /* register the new window, along with its borders */
+ dlg_mouse_mkbigregion(all.box_y + 1, all.box_x,
+ all.menu_height + 2, all.menu_width + 2,
+ KEY_MAX, 1, 1, 1 /* by lines */ );
+
+ dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width);
+
+ dlg_trace_win(dialog);
+
+ while (result == DLG_EXIT_UNKNOWN) {
+ int key, found;
+
+ if (button < 0) /* --visit-items */
+ wmove(dialog,
+ all.box_y + ItemToRow(choice) + 1,
+ all.box_x + all.tag_x + 1);
+
+ key = dlg_mouse_wgetch(dialog, &fkey);
+ if (dlg_result_key(key, fkey, &result)) {
+ if (!dlg_button_key(result, &button, &key, &fkey))
+ break;
+ }
+
+ found = FALSE;
+ if (fkey) {
+ /*
+ * Allow a mouse-click on a box to switch selection to that box.
+ * Handling a button click is a little more complicated, since we
+ * push a KEY_ENTER back onto the input stream so we'll put the
+ * cursor at the right place before handling the "keypress".
+ */
+ if (key >= DLGK_MOUSE(KEY_MAX)) {
+ key -= DLGK_MOUSE(KEY_MAX);
+ i = RowToItem(key);
+ if (i < max_choice) {
+ found = TRUE;
+ } else {
+ beep();
+ continue;
+ }
+ } else if (is_DLGK_MOUSE(key)
+ && dlg_ok_buttoncode(key - M_EVENT) >= 0) {
+ button = (key - M_EVENT);
+ ungetch('\n');
+ continue;
+ }
+ } else {
+ /*
+ * Check if key pressed matches first character of any item tag in
+ * list. If there is more than one match, we will cycle through
+ * each one as the same key is pressed repeatedly.
+ */
+ if (button < 0 || !dialog_state.visit_items) {
+ for (j = scrollamt + choice + 1; j < item_no; j++) {
+ if (check_hotkey(items, j)) {
+ found = TRUE;
+ i = j - scrollamt;
+ break;
+ }
+ }
+ if (!found) {
+ for (j = 0; j <= scrollamt + choice; j++) {
+ if (check_hotkey(items, j)) {
+ found = TRUE;
+ i = j - scrollamt;
+ break;
+ }
+ }
+ }
+ if (found)
+ dlg_flush_getc();
+ } else if ((j = dlg_char_to_button(key, buttons)) >= 0) {
+ button = j;
+ ungetch('\n');
+ continue;
+ }
+
+ /*
+ * A single digit (1-9) positions the selection to that line in the
+ * current screen.
+ */
+ if (!found
+ && (key <= '9')
+ && (key > '0')
+ && (key - '1' < max_choice)) {
+ found = TRUE;
+ i = key - '1';
+ }
+ }
+
+ if (!found && fkey) {
+ found = TRUE;
+ switch (key) {
+ case DLGK_PAGE_FIRST:
+ i = -scrollamt;
+ break;
+ case DLGK_PAGE_LAST:
+ i = item_no - 1 - scrollamt;
+ break;
+ case DLGK_MOUSE(KEY_PPAGE):
+ case DLGK_PAGE_PREV:
+ if (choice)
+ i = 0;
+ else if (scrollamt != 0)
+ i = -MIN(scrollamt, max_choice);
+ else
+ continue;
+ break;
+ case DLGK_MOUSE(KEY_NPAGE):
+ case DLGK_PAGE_NEXT:
+ i = MIN(choice + max_choice, item_no - scrollamt - 1);
+ break;
+ case DLGK_ITEM_PREV:
+ i = choice - 1;
+ if (choice == 0 && scrollamt == 0)
+ continue;
+ break;
+ case DLGK_ITEM_NEXT:
+ i = choice + 1;
+ if (scrollamt + choice >= item_no - 1)
+ continue;
+ break;
+ default:
+ found = FALSE;
+ break;
+ }
+ }
+
+ if (found) {
+ if (i != choice) {
+ getyx(dialog, cur_y, cur_x);
+ if (i < 0 || i >= max_choice) {
+ if (i < 0) {
+ scrollamt += i;
+ choice = 0;
+ } else {
+ choice = max_choice - 1;
+ scrollamt += (i - max_choice + 1);
+ }
+ PrintMenu();
+ } else {
+ choice = i;
+ PrintMenu();
+ (void) wmove(dialog, cur_y, cur_x);
+ wrefresh(dialog);
+ }
+ }
+ continue; /* wait for another key press */
+ }
+
+ if (fkey) {
+ switch (key) {
+ case DLGK_FIELD_PREV:
+ button = dlg_prev_button(buttons, button);
+ dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
+ FALSE, width);
+ break;
+
+ case DLGK_FIELD_NEXT:
+ button = dlg_next_button(buttons, button);
+ dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
+ FALSE, width);
+ break;
+
+ case DLGK_TOGGLE:
+ case DLGK_ENTER:
+ case DLGK_LEAVE:
+ result = ((key == DLGK_LEAVE)
+ ? dlg_ok_buttoncode(button)
+ : dlg_enter_buttoncode(button));
+
+ /*
+ * If dlg_menu() is called from dialog_menu(), we want to
+ * capture the results into dialog_vars.input_result.
+ */
+ if (result == DLG_EXIT_ERROR) {
+ result = DLG_EXIT_UNKNOWN;
+ } else if (is_inputmenu
+ || rename_menutext == dlg_dummy_menutext) {
+ result = handle_button(result,
+ items,
+ scrollamt + choice);
+ }
+
+ /*
+ * If we have a rename_menutext function, interpret the Extra
+ * button as a request to rename the menu's text. If that
+ * function doesn't return "Unknown", we will exit from this
+ * function. Usually that is done for dialog_menu(), so the
+ * shell script can use the updated value. If it does return
+ * "Unknown", update the list item only. A direct caller of
+ * dlg_menu() can free the renamed value - we cannot.
+ */
+ if (is_inputmenu && result == DLG_EXIT_EXTRA) {
+ char *tmp;
+
+ if (input_menu_edit(&all,
+ &items[scrollamt + choice],
+ choice,
+ &tmp)) {
+ result = rename_menutext(items, scrollamt + choice, tmp);
+ if (result == DLG_EXIT_UNKNOWN) {
+ items[scrollamt + choice].text = tmp;
+ } else {
+ free(tmp);
+ }
+ } else {
+ result = DLG_EXIT_UNKNOWN;
+ print_item(&all,
+ menu,
+ &items[scrollamt + choice],
+ choice,
+ Selected,
+ is_inputmenu);
+ (void) wnoutrefresh(menu);
+ free(tmp);
+ }
+
+ if (result == DLG_EXIT_UNKNOWN) {
+ dlg_draw_buttons(dialog, height - 2, 0,
+ buttons, button, FALSE, width);
+ }
+ }
+ break;
+#ifdef KEY_RESIZE
+ case KEY_RESIZE:
+ dlg_will_resize(dialog);
+ /* reset data */
+ resizeit(height, LINES);
+ resizeit(width, COLS);
+ free(prompt);
+ _dlg_resize_cleanup(dialog);
+ dlg_unregister_window(menu);
+ dlg_unregister_window(dialog);
+ /* keep position */
+ choice += scrollamt;
+ scrollamt = 0;
+ /* repaint */
+ goto retry;
+#endif
+ default:
+ flash();
+ break;
+ }
+ }
+ }
+
+ dlg_mouse_free_regions();
+ dlg_unregister_window(menu);
+ dlg_del_window(dialog);
+ free(prompt);
+
+ *current_item = scrollamt + choice;
+
+ DLG_TRACE2N("current", *current_item);
+ return result;
+}
+
+/*
+ * Display a menu for choosing among a number of options
+ */
+int
+dialog_menu(const char *title,
+ const char *cprompt,
+ int height,
+ int width,
+ int menu_height,
+ int item_no,
+ char **items)
+{
+ int result;
+ int choice;
+ int i, j;
+ DIALOG_LISTITEM *listitems;
+
+ listitems = dlg_calloc(DIALOG_LISTITEM, (size_t) item_no + 1);
+ assert_ptr(listitems, "dialog_menu");
+
+ for (i = j = 0; i < item_no; ++i) {
+ listitems[i].name = items[j++];
+ listitems[i].text = (dialog_vars.no_items
+ ? dlg_strempty()
+ : items[j++]);
+ listitems[i].help = ((dialog_vars.item_help)
+ ? items[j++]
+ : dlg_strempty());
+ }
+ dlg_align_columns(&listitems[0].text, sizeof(DIALOG_LISTITEM), item_no);
+
+ result = dlg_menu(title,
+ cprompt,
+ height,
+ width,
+ menu_height,
+ item_no,
+ listitems,
+ &choice,
+ (dialog_vars.input_menu
+ ? dlg_renamed_menutext
+ : dlg_dummy_menutext));
+
+ dlg_free_columns(&listitems[0].text, sizeof(DIALOG_LISTITEM), item_no);
+ free(listitems);
+ return result;
+}
Index: sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/treeview.c
===================================================================
--- sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/treeview.c (nonexistent)
+++ sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/treeview.c (revision 34)
@@ -0,0 +1,683 @@
+/*
+ * $Id: treeview.c,v 1.46 2022/04/05 00:15:15 tom Exp $
+ *
+ * treeview.c -- implements the treeview dialog
+ *
+ * Copyright 2012-2021,2022 Thomas E. Dickey
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License, version 2.1
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to
+ * Free Software Foundation, Inc.
+ * 51 Franklin St., Fifth Floor
+ * Boston, MA 02110, USA.
+ */
+
+#include <dlg_internals.h>
+#include <dlg_keys.h>
+
+#define INDENT 3
+#define MIN_HIGH (1 + (5 * MARGIN))
+
+typedef struct {
+ /* the outer-window */
+ WINDOW *dialog;
+ bool is_check;
+ int box_y;
+ int box_x;
+ int check_x;
+ int item_x;
+ int use_height;
+ int use_width;
+ /* the inner-window */
+ WINDOW *list;
+ DIALOG_LISTITEM *items;
+ int item_no;
+ int *depths;
+ const char *states;
+} ALL_DATA;
+
+/*
+ * Print list item. The 'selected' parameter is true if 'choice' is the
+ * current item. That one is colored differently from the other items.
+ */
+static void
+print_item(ALL_DATA * data,
+ DIALOG_LISTITEM * item,
+ const char *states,
+ int depths,
+ int choice,
+ int selected)
+{
+ WINDOW *win = data->list;
+ chtype save = dlg_get_attrs(win);
+ int i;
+ bool first = TRUE;
+ int climit = (getmaxx(win) - data->check_x + 1);
+ const char *show = (dialog_vars.no_items
+ ? item->name
+ : item->text);
+
+ /* Clear 'residue' of last item */
+ dlg_attrset(win, menubox_attr);
+ (void) wmove(win, choice, 0);
+ for (i = 0; i < data->use_width; i++)
+ (void) waddch(win, ' ');
+
+ (void) wmove(win, choice, data->check_x);
+ dlg_attrset(win, selected ? check_selected_attr : check_attr);
+ (void) wprintw(win,
+ data->is_check ? "[%c]" : "(%c)",
+ states[item->state]);
+ dlg_attrset(win, menubox_attr);
+
+ dlg_attrset(win, selected ? item_selected_attr : item_attr);
+ for (i = 0; i < depths; ++i) {
+ int j;
+ (void) wmove(win, choice, data->item_x + INDENT * i);
+ (void) waddch(win, ACS_VLINE);
+ for (j = INDENT - 1; j > 0; --j)
+ (void) waddch(win, ' ');
+ }
+ (void) wmove(win, choice, data->item_x + INDENT * depths);
+
+ dlg_print_listitem(win, show, climit, first, selected);
+
+ if (selected) {
+ dlg_item_help(item->help);
+ }
+ dlg_attrset(win, save);
+}
+
+static void
+print_list(ALL_DATA * data,
+ int choice,
+ int scrollamt,
+ int max_choice,
+ int max_items)
+{
+ int i;
+ int cur_y, cur_x;
+
+ getyx(data->dialog, cur_y, cur_x);
+
+ for (i = 0; i < max_choice; i++) {
+ int ii = i + scrollamt;
+ if (ii < max_items)
+ print_item(data,
+ &data->items[ii],
+ data->states,
+ data->depths[ii],
+ i, i == choice);
+ }
+ (void) wnoutrefresh(data->list);
+
+ dlg_draw_scrollbar(data->dialog,
+ (long) (scrollamt),
+ (long) (scrollamt),
+ (long) (scrollamt + max_choice),
+ (long) (data->item_no),
+ data->box_x + data->check_x,
+ data->box_x + data->use_width,
+ data->box_y,
+ data->box_y + data->use_height + 1,
+ menubox_border2_attr,
+ menubox_border_attr);
+
+ (void) wmove(data->dialog, cur_y, cur_x);
+}
+
+static bool
+check_hotkey(DIALOG_LISTITEM * items, int choice)
+{
+ bool result = FALSE;
+
+ if (dlg_match_char(dlg_last_getc(),
+ (dialog_vars.no_tags
+ ? items[choice].text
+ : items[choice].name))) {
+ result = TRUE;
+ }
+ return result;
+}
+
+/*
+ * This is an alternate interface to 'treeview' which allows the application
+ * to read the list item states back directly without putting them in the
+ * output buffer.
+ */
+int
+dlg_treeview(const char *title,
+ const char *cprompt,
+ int height,
+ int width,
+ int list_height,
+ int item_no,
+ DIALOG_LISTITEM * items,
+ const char *states,
+ int *depths,
+ int flag,
+ int *current_item)
+{
+ /* *INDENT-OFF* */
+ static DLG_KEYS_BINDING binding[] = {
+ HELPKEY_BINDINGS,
+ ENTERKEY_BINDINGS,
+ DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ),
+ DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ),
+ DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ),
+ DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ),
+ DLG_KEYS_DATA( DLGK_ITEM_FIRST, KEY_HOME ),
+ DLG_KEYS_DATA( DLGK_ITEM_LAST, KEY_END ),
+ DLG_KEYS_DATA( DLGK_ITEM_LAST, KEY_LL ),
+ DLG_KEYS_DATA( DLGK_ITEM_NEXT, '+' ),
+ DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_DOWN ),
+ DLG_KEYS_DATA( DLGK_ITEM_NEXT, CHR_NEXT ),
+ DLG_KEYS_DATA( DLGK_ITEM_PREV, '-' ),
+ DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_UP ),
+ DLG_KEYS_DATA( DLGK_ITEM_PREV, CHR_PREVIOUS ),
+ DLG_KEYS_DATA( DLGK_PAGE_NEXT, KEY_NPAGE ),
+ DLG_KEYS_DATA( DLGK_PAGE_NEXT, DLGK_MOUSE(KEY_NPAGE) ),
+ DLG_KEYS_DATA( DLGK_PAGE_PREV, KEY_PPAGE ),
+ DLG_KEYS_DATA( DLGK_PAGE_PREV, DLGK_MOUSE(KEY_PPAGE) ),
+ TOGGLEKEY_BINDINGS,
+ END_KEYS_BINDING
+ };
+ /* *INDENT-ON* */
+
+#ifdef KEY_RESIZE
+ int old_height = height;
+ int old_width = width;
+#endif
+ ALL_DATA all;
+ int i, j, key2, found, x, y, cur_y, box_x, box_y;
+ int key, fkey;
+ int button = dialog_state.visit_items ? -1 : dlg_default_button();
+ int choice = dlg_default_listitem(items);
+ int scrollamt = 0;
+ int max_choice;
+ int use_height;
+ int use_width, name_width, text_width, tree_width;
+ int result = DLG_EXIT_UNKNOWN;
+ int num_states;
+ WINDOW *dialog, *list;
+ char *prompt = dlg_strclone(cprompt);
+ const char **buttons = dlg_ok_labels();
+ const char *widget_name;
+
+ /* we need at least two states */
+ if (states == 0 || strlen(states) < 2)
+ states = " *";
+ num_states = (int) strlen(states);
+
+ dialog_state.plain_buttons = TRUE;
+
+ memset(&all, 0, sizeof(all));
+ all.items = items;
+ all.item_no = item_no;
+ all.states = states;
+ all.depths = depths;
+
+ dlg_does_output();
+ dlg_tab_correct_str(prompt);
+
+ /*
+ * If this is a radiobutton list, ensure that no more than one item is
+ * selected initially. Allow none to be selected, since some users may
+ * wish to provide this flavor.
+ */
+ if (flag == FLAG_RADIO) {
+ bool first = TRUE;
+
+ for (i = 0; i < item_no; i++) {
+ if (items[i].state) {
+ if (first) {
+ first = FALSE;
+ } else {
+ items[i].state = 0;
+ }
+ }
+ }
+ } else {
+ all.is_check = TRUE;
+ }
+ widget_name = "treeview";
+#ifdef KEY_RESIZE
+ retry:
+#endif
+
+ use_height = list_height;
+ use_width = dlg_calc_list_width(item_no, items) + 10;
+ use_width = MAX(26, use_width);
+ if (use_height == 0) {
+ /* calculate height without items (4) */
+ dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, use_width);
+ dlg_calc_listh(&height, &use_height, item_no);
+ } else {
+ dlg_auto_size(title, prompt, &height, &width, MIN_HIGH + use_height, use_width);
+ }
+ dlg_button_layout(buttons, &width);
+ dlg_print_size(height, width);
+ dlg_ctl_size(height, width);
+
+ x = dlg_box_x_ordinate(width);
+ y = dlg_box_y_ordinate(height);
+
+ dialog = dlg_new_window(height, width, y, x);
+ dlg_register_window(dialog, widget_name, binding);
+ dlg_register_buttons(dialog, widget_name, buttons);
+
+ dlg_mouse_setbase(x, y);
+
+ dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr);
+ dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
+ dlg_draw_title(dialog, title);
+
+ dlg_attrset(dialog, dialog_attr);
+ dlg_print_autowrap(dialog, prompt, height, width);
+
+ all.use_width = width - 4;
+ cur_y = getcury(dialog);
+ box_y = cur_y + 1;
+ box_x = (width - all.use_width) / 2 - 1;
+
+ /*
+ * After displaying the prompt, we know how much space we really have.
+ * Limit the list to avoid overwriting the ok-button.
+ */
+ if (use_height + MIN_HIGH > height - cur_y)
+ use_height = height - MIN_HIGH - cur_y;
+ if (use_height <= 0)
+ use_height = 1;
+
+ max_choice = MIN(use_height, item_no);
+
+ /* create new window for the list */
+ list = dlg_sub_window(dialog, use_height, all.use_width,
+ y + box_y + 1, x + box_x + 1);
+
+ /* draw a box around the list items */
+ dlg_draw_box(dialog, box_y, box_x,
+ use_height + 2 * MARGIN,
+ all.use_width + 2 * MARGIN,
+ menubox_border_attr, menubox_border2_attr);
+
+ text_width = 0;
+ name_width = 0;
+ tree_width = 0;
+ /* Find length of longest item to center treeview */
+ for (i = 0; i < item_no; i++) {
+ tree_width = MAX(tree_width, INDENT * depths[i]);
+ text_width = MAX(text_width, dlg_count_columns(items[i].text));
+ name_width = MAX(name_width, dlg_count_columns(items[i].name));
+ }
+ if (dialog_vars.no_tags && !dialog_vars.no_items) {
+ tree_width += text_width;
+ } else if (dialog_vars.no_items) {
+ tree_width += name_width;
+ } else {
+ tree_width += (text_width + name_width);
+ }
+
+ use_width = (all.use_width - 4);
+ tree_width = MIN(tree_width, all.use_width);
+
+ all.check_x = (use_width - tree_width) / 2;
+ all.item_x = ((dialog_vars.no_tags
+ ? 0
+ : (dialog_vars.no_items
+ ? 0
+ : (2 + name_width)))
+ + all.check_x + 4);
+
+ /* ensure we are scrolled to show the current choice */
+ if (choice >= (max_choice + scrollamt)) {
+ scrollamt = choice - max_choice + 1;
+ choice = max_choice - 1;
+ }
+
+ /* register the new window, along with its borders */
+ dlg_mouse_mkbigregion(box_y + 1, box_x,
+ use_height, all.use_width + 2,
+ KEY_MAX, 1, 1, 1 /* by lines */ );
+
+ all.dialog = dialog;
+ all.box_x = box_x;
+ all.box_y = box_y;
+ all.use_height = use_height;
+ all.list = list;
+#define PrintList() \
+ print_list(&all, choice, scrollamt, max_choice, item_no)
+ PrintList();
+
+ dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width);
+
+ dlg_trace_win(dialog);
+
+ while (result == DLG_EXIT_UNKNOWN) {
+ int was_mouse;
+
+ if (button < 0) /* --visit-items */
+ wmove(dialog, box_y + choice + 1, box_x + all.check_x + 2);
+
+ key = dlg_mouse_wgetch(dialog, &fkey);
+ if (dlg_result_key(key, fkey, &result)) {
+ if (!dlg_button_key(result, &button, &key, &fkey))
+ break;
+ }
+
+ was_mouse = (fkey && is_DLGK_MOUSE(key));
+ if (was_mouse)
+ key -= M_EVENT;
+
+ if (was_mouse && (key >= KEY_MAX)) {
+ i = (key - KEY_MAX);
+ if (i < max_choice) {
+ choice = (key - KEY_MAX);
+ PrintList();
+
+ key = DLGK_TOGGLE; /* force the selected item to toggle */
+ } else {
+ beep();
+ continue;
+ }
+ fkey = FALSE;
+ } else if (was_mouse && key >= KEY_MIN) {
+ key = dlg_lookup_key(dialog, key, &fkey);
+ }
+
+ /*
+ * A space toggles the item status.
+ */
+ if (key == DLGK_TOGGLE) {
+ int current = scrollamt + choice;
+ int next = items[current].state + 1;
+
+ if (next >= num_states)
+ next = 0;
+
+ if (flag == FLAG_CHECK) { /* checklist? */
+ items[current].state = next;
+ } else {
+ for (i = 0; i < item_no; i++) {
+ if (i != current) {
+ items[i].state = 0;
+ }
+ }
+ if (items[current].state) {
+ items[current].state = next ? next : 1;
+ } else {
+ items[current].state = 1;
+ }
+ }
+ PrintList();
+ continue; /* wait for another key press */
+ }
+
+ /*
+ * Check if key pressed matches first character of any item tag in
+ * list. If there is more than one match, we will cycle through
+ * each one as the same key is pressed repeatedly.
+ */
+ found = FALSE;
+ if (!fkey) {
+ if (button < 0 || !dialog_state.visit_items) {
+ for (j = scrollamt + choice + 1; j < item_no; j++) {
+ if (check_hotkey(items, j)) {
+ found = TRUE;
+ i = j - scrollamt;
+ break;
+ }
+ }
+ if (!found) {
+ for (j = 0; j <= scrollamt + choice; j++) {
+ if (check_hotkey(items, j)) {
+ found = TRUE;
+ i = j - scrollamt;
+ break;
+ }
+ }
+ }
+ if (found)
+ dlg_flush_getc();
+ } else if ((j = dlg_char_to_button(key, buttons)) >= 0) {
+ button = j;
+ ungetch('\n');
+ continue;
+ }
+ }
+
+ /*
+ * A single digit (1-9) positions the selection to that line in the
+ * current screen.
+ */
+ if (!found
+ && (key <= '9')
+ && (key > '0')
+ && (key - '1' < max_choice)) {
+ found = TRUE;
+ i = key - '1';
+ }
+
+ if (!found) {
+ if (fkey) {
+ found = TRUE;
+ switch (key) {
+ case DLGK_ITEM_FIRST:
+ i = -scrollamt;
+ break;
+ case DLGK_ITEM_LAST:
+ i = item_no - 1 - scrollamt;
+ break;
+ case DLGK_PAGE_PREV:
+ if (choice)
+ i = 0;
+ else if (scrollamt != 0)
+ i = -MIN(scrollamt, max_choice);
+ else
+ continue;
+ break;
+ case DLGK_PAGE_NEXT:
+ i = MIN(choice + max_choice, item_no - scrollamt - 1);
+ break;
+ case DLGK_ITEM_PREV:
+ i = choice - 1;
+ if (choice == 0 && scrollamt == 0)
+ continue;
+ break;
+ case DLGK_ITEM_NEXT:
+ i = choice + 1;
+ if (scrollamt + choice >= item_no - 1)
+ continue;
+ break;
+ default:
+ found = FALSE;
+ break;
+ }
+ }
+ }
+
+ if (found) {
+ if (i != choice) {
+ if (i < 0 || i >= max_choice) {
+ if (i < 0) {
+ scrollamt += i;
+ choice = 0;
+ } else {
+ choice = max_choice - 1;
+ scrollamt += (i - max_choice + 1);
+ }
+ PrintList();
+ } else {
+ choice = i;
+ PrintList();
+ }
+ }
+ continue; /* wait for another key press */
+ }
+
+ if (fkey) {
+ switch (key) {
+ case DLGK_ENTER:
+ result = dlg_enter_buttoncode(button);
+ break;
+ case DLGK_LEAVE:
+ result = dlg_ok_buttoncode(button);
+ break;
+ case DLGK_FIELD_PREV:
+ button = dlg_prev_button(buttons, button);
+ dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
+ FALSE, width);
+ break;
+ case DLGK_FIELD_NEXT:
+ button = dlg_next_button(buttons, button);
+ dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
+ FALSE, width);
+ break;
+#ifdef KEY_RESIZE
+ case KEY_RESIZE:
+ dlg_will_resize(dialog);
+ /* reset data */
+ height = old_height;
+ width = old_width;
+ /* repaint */
+ _dlg_resize_cleanup(dialog);
+ /* keep position */
+ choice += scrollamt;
+ scrollamt = 0;
+ goto retry;
+#endif
+ default:
+ if (was_mouse) {
+ if ((key2 = dlg_ok_buttoncode(key)) >= 0) {
+ result = key2;
+ break;
+ }
+ beep();
+ }
+ }
+ } else if (key > 0) {
+ beep();
+ }
+ }
+
+ dlg_del_window(dialog);
+ dlg_mouse_free_regions();
+ free(prompt);
+ *current_item = (scrollamt + choice);
+ return result;
+}
+
+/*
+ * Display a set of items as a tree.
+ */
+int
+dialog_treeview(const char *title,
+ const char *cprompt,
+ int height,
+ int width,
+ int list_height,
+ int item_no,
+ char **items,
+ int flag)
+{
+ int result;
+ int i, j;
+ DIALOG_LISTITEM *listitems;
+ int *depths;
+ bool show_status = FALSE;
+ int current = 0;
+ char *help_result;
+
+ DLG_TRACE(("# treeview args:\n"));
+ DLG_TRACE2S("title", title);
+ DLG_TRACE2S("message", cprompt);
+ DLG_TRACE2N("height", height);
+ DLG_TRACE2N("width", width);
+ DLG_TRACE2N("lheight", list_height);
+ DLG_TRACE2N("llength", item_no);
+ /* FIXME dump the items[][] too */
+ DLG_TRACE2N("flag", flag);
+
+ listitems = dlg_calloc(DIALOG_LISTITEM, (size_t) item_no + 1);
+ assert_ptr(listitems, "dialog_treeview");
+
+ depths = dlg_calloc(int, (size_t) item_no + 1);
+ assert_ptr(depths, "dialog_treeview");
+
+ for (i = j = 0; i < item_no; ++i) {
+ listitems[i].name = items[j++];
+ listitems[i].text = (dialog_vars.no_items
+ ? dlg_strempty()
+ : items[j++]);
+ listitems[i].state = !dlg_strcmp(items[j++], "on");
+ depths[i] = atoi(items[j++]);
+ listitems[i].help = ((dialog_vars.item_help)
+ ? items[j++]
+ : dlg_strempty());
+ }
+ dlg_align_columns(&listitems[0].text, (int) sizeof(DIALOG_LISTITEM), item_no);
+
+ result = dlg_treeview(title,
+ cprompt,
+ height,
+ width,
+ list_height,
+ item_no,
+ listitems,
+ NULL,
+ depths,
+ flag,
+ ¤t);
+
+ switch (result) {
+ case DLG_EXIT_OK: /* FALLTHRU */
+ case DLG_EXIT_EXTRA:
+ show_status = TRUE;
+ break;
+ case DLG_EXIT_HELP:
+ dlg_add_help_listitem(&result, &help_result, &listitems[current]);
+ if ((show_status = dialog_vars.help_status)) {
+ if (dialog_vars.separate_output) {
+ dlg_add_string(help_result);
+ dlg_add_separator();
+ } else {
+ dlg_add_quoted(help_result);
+ }
+ } else {
+ dlg_add_string(help_result);
+ }
+ break;
+ }
+
+ if (show_status) {
+ for (i = 0; i < item_no; i++) {
+ if (listitems[i].state) {
+ if (dlg_need_separator())
+ dlg_add_separator();
+ if (dialog_vars.separate_output) {
+ dlg_add_string(listitems[i].name);
+ } else {
+ if (flag == FLAG_CHECK)
+ dlg_add_quoted(listitems[i].name);
+ else
+ dlg_add_string(listitems[i].name);
+ }
+ }
+ }
+ AddLastKey();
+ }
+
+ dlg_free_columns(&listitems[0].text, (int) sizeof(DIALOG_LISTITEM), item_no);
+ free(depths);
+ free(listitems);
+ return result;
+}
Index: sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/util.c
===================================================================
--- sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/util.c (nonexistent)
+++ sources/packages/dialog/create-1.3-20240101-patch/dialog-1.3-20240101-new/util.c (revision 34)
@@ -0,0 +1,3050 @@
+/*
+ * $Id: util.c,v 1.309 2023/10/03 00:07:51 tom Exp $
+ *
+ * util.c -- miscellaneous utilities for dialog
+ *
+ * Copyright 2000-2022,2023 Thomas E. Dickey
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License, version 2.1
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to
+ * Free Software Foundation, Inc.
+ * 51 Franklin St., Fifth Floor
+ * Boston, MA 02110, USA.
+ *
+ * An earlier version of this program lists as authors
+ * Savio Lam (lam836@cs.cuhk.hk)
+ */
+
+#include <dlg_internals.h>
+#include <dlg_keys.h>
+
+#if defined(NCURSES_VERSION)
+#define CAN_KEEP_TITE 1
+#elif defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 800000000)
+#define CAN_KEEP_TITE 1
+#else
+#define CAN_KEEP_TITE 0
+#endif
+
+#if CAN_KEEP_TITE
+#if defined(NCURSES_VERSION) && defined(HAVE_NCURSESW_TERM_H)
+#include <ncursesw/term.h>
+#elif defined(NCURSES_VERSION) && defined(HAVE_NCURSES_TERM_H)
+#include <ncurses/term.h>
+#else
+#include <term.h>
+#endif
+#endif
+
+#if defined(HAVE_WCHGAT)
+# if defined(NCURSES_VERSION_PATCH)
+# if NCURSES_VERSION_PATCH >= 20060715
+# define USE_WCHGAT 1
+# else
+# define USE_WCHGAT 0
+# endif
+# else
+# define USE_WCHGAT 1
+# endif
+#else
+# define USE_WCHGAT 0
+#endif
+
+/* globals */
+DIALOG_STATE dialog_state;
+DIALOG_VARS dialog_vars;
+
+#if !(defined(HAVE_WGETPARENT) && defined(HAVE_WINDOW__PARENT))
+#define NEED_WGETPARENT 1
+#else
+#undef NEED_WGETPARENT
+#endif
+
+#define concat(a,b) a##b
+
+#ifdef HAVE_RC_FILE
+#define RC_DATA(name,comment) , #name "_color", comment " color"
+#else
+#define RC_DATA(name,comment) /*nothing */
+#endif
+
+#ifdef HAVE_COLOR
+#include <dlg_colors.h>
+#ifdef HAVE_RC_FILE2
+#define COLOR_DATA(upr) , \
+ concat(DLGC_FG_,upr), \
+ concat(DLGC_BG_,upr), \
+ concat(DLGC_HL_,upr), \
+ concat(DLGC_UL_,upr), \
+ concat(DLGC_RV_,upr)
+#else /* HAVE_RC_FILE2 */
+#define COLOR_DATA(upr) , \
+ concat(DLGC_FG_,upr), \
+ concat(DLGC_BG_,upr), \
+ concat(DLGC_HL_,upr)
+#endif /* HAVE_RC_FILE2 */
+#else /* HAVE_COLOR */
+#define COLOR_DATA(upr) /*nothing */
+#endif /* HAVE_COLOR */
+
+#define UseShadow(dw) ((dw) != 0 && (dw)->normal != 0 && (dw)->shadow != 0)
+
+/*
+ * Table of color and attribute values, default is for mono display.
+ * The order matches the DIALOG_ATR() values.
+ */
+#define DATA(atr,upr,lwr,cmt) { atr COLOR_DATA(upr) RC_DATA(lwr,cmt) }
+/* *INDENT-OFF* */
+DIALOG_COLORS dlg_color_table[] =
+{
+ DATA(A_NORMAL, SCREEN, screen, "Screen"),
+ DATA(A_NORMAL, SHADOW, shadow, "Shadow"),
+ DATA(A_REVERSE, DIALOG, dialog, "Dialog box"),
+ DATA(A_REVERSE, TITLE, title, "Dialog box title"),
+ DATA(A_REVERSE, BORDER, border, "Dialog box border"),
+ DATA(A_BOLD, BUTTON_ACTIVE, button_active, "Active button"),
+ DATA(A_DIM, BUTTON_INACTIVE, button_inactive, "Inactive button"),
+ DATA(A_UNDERLINE, BUTTON_KEY_ACTIVE, button_key_active, "Active button key"),
+ DATA(A_UNDERLINE, BUTTON_KEY_INACTIVE, button_key_inactive, "Inactive button key"),
+ DATA(A_NORMAL, BUTTON_LABEL_ACTIVE, button_label_active, "Active button label"),
+ DATA(A_NORMAL, BUTTON_LABEL_INACTIVE, button_label_inactive, "Inactive button label"),
+ DATA(A_REVERSE, INPUTBOX, inputbox, "Input box"),
+ DATA(A_REVERSE, INPUTBOX_BORDER, inputbox_border, "Input box border"),
+ DATA(A_REVERSE, SEARCHBOX, searchbox, "Search box"),
+ DATA(A_REVERSE, SEARCHBOX_TITLE, searchbox_title, "Search box title"),
+ DATA(A_REVERSE, SEARCHBOX_BORDER, searchbox_border, "Search box border"),
+ DATA(A_REVERSE, POSITION_INDICATOR, position_indicator, "File position indicator"),
+ DATA(A_REVERSE, MENUBOX, menubox, "Menu box"),
+ DATA(A_REVERSE, MENUBOX_BORDER, menubox_border, "Menu box border"),
+ DATA(A_REVERSE, ITEM, item, "Item"),
+ DATA(A_NORMAL, ITEM_SELECTED, item_selected, "Selected item"),
+ DATA(A_REVERSE, TAG, tag, "Tag"),
+ DATA(A_REVERSE, TAG_SELECTED, tag_selected, "Selected tag"),
+ DATA(A_NORMAL, TAG_KEY, tag_key, "Tag key"),
+ DATA(A_BOLD, TAG_KEY_SELECTED, tag_key_selected, "Selected tag key"),
+ DATA(A_REVERSE, CHECK, check, "Check box"),
+ DATA(A_REVERSE, CHECK_SELECTED, check_selected, "Selected check box"),
+ DATA(A_REVERSE, UARROW, uarrow, "Up arrow"),
+ DATA(A_REVERSE, DARROW, darrow, "Down arrow"),
+ DATA(A_NORMAL, ITEMHELP, itemhelp, "Item help-text"),
+ DATA(A_BOLD, FORM_ACTIVE_TEXT, form_active_text, "Active form text"),
+ DATA(A_REVERSE, FORM_TEXT, form_text, "Form text"),
+ DATA(A_NORMAL, FORM_ITEM_READONLY, form_item_readonly, "Readonly form item"),
+ DATA(A_REVERSE, GAUGE, gauge, "Dialog box gauge"),
+ DATA(A_REVERSE, BORDER2, border2, "Dialog box border2"),
+ DATA(A_REVERSE, INPUTBOX_BORDER2, inputbox_border2, "Input box border2"),
+ DATA(A_REVERSE, SEARCHBOX_BORDER2, searchbox_border2, "Search box border2"),
+ DATA(A_REVERSE, MENUBOX_BORDER2, menubox_border2, "Menu box border2")
+};
+#undef DATA
+/* *INDENT-ON* */
+
+/*
+ * Maintain a list of subwindows so that we can delete them to cleanup.
+ * More important, this provides a fallback when wgetparent() is not available.
+ */
+static void
+add_subwindow(WINDOW *parent, WINDOW *child)
+{
+ DIALOG_WINDOWS *p = dlg_calloc(DIALOG_WINDOWS, 1);
+
+ if (p != 0) {
+ p->normal = parent;
+ p->shadow = child;
+ p->getc_timeout = WTIMEOUT_OFF;
+ p->next = dialog_state.all_subwindows;
+ dialog_state.all_subwindows = p;
+ }
+}
+
+static void
+del_subwindows(WINDOW *parent)
+{
+ DIALOG_WINDOWS *p = dialog_state.all_subwindows;
+ DIALOG_WINDOWS *q = 0;
+ DIALOG_WINDOWS *r;
+
+ while (p != 0) {
+ if (p->normal == parent) {
+ delwin(p->shadow);
+ r = p->next;
+ if (q == 0) {
+ dialog_state.all_subwindows = r;
+ } else {
+ q->next = r;
+ }
+ free(p);
+ p = r;
+ } else {
+ q = p;
+ p = p->next;
+ }
+ }
+}
+
+/*
+ * Display background title if it exists ...
+ */
+void
+dlg_put_backtitle(void)
+{
+
+ if (dialog_vars.backtitle != NULL) {
+ chtype attr = A_NORMAL;
+ int backwidth = dlg_count_columns(dialog_vars.backtitle);
+ int i;
+
+ dlg_attrset(stdscr, screen_attr);
+ (void) wmove(stdscr, 0, 1);
+ dlg_print_text(stdscr, dialog_vars.backtitle, COLS - 2, &attr);
+ for (i = 0; i < COLS - backwidth; i++)
+ (void) waddch(stdscr, ' ');
+ (void) wmove(stdscr, 1, 1);
+ for (i = 0; i < COLS - 2; i++)
+ (void) waddch(stdscr, dlg_boxchar(ACS_HLINE));
+ }
+
+ (void) wnoutrefresh(stdscr);
+}
+
+/*
+ * Set window to attribute 'attr'. There are more efficient ways to do this,
+ * but will not work on older/buggy ncurses versions.
+ */
+void
+dlg_attr_clear(WINDOW *win, int height, int width, chtype attr)
+{
+ int i, j;
+
+ dlg_attrset(win, attr);
+ for (i = 0; i < height; i++) {
+ (void) wmove(win, i, 0);
+ for (j = 0; j < width; j++)
+ (void) waddch(win, ' ');
+ }
+ (void) touchwin(win);
+}
+
+void
+dlg_clear(void)
+{
+ dlg_attr_clear(stdscr, LINES, COLS, screen_attr);
+}
+
+#ifdef KEY_RESIZE
+void
+_dlg_resize_cleanup(WINDOW *w)
+{
+ dlg_clear();
+ dlg_put_backtitle();
+ dlg_del_window(w);
+ dlg_mouse_free_regions();
+}
+#endif /* KEY_RESIZE */
+
+#define isprivate(s) ((s) != 0 && strstr(s, "\033[?") != 0)
+
+#define TTY_DEVICE "/dev/tty"
+
+/*
+ * If $DIALOG_TTY exists, allow the program to try to open the terminal
+ * directly when stdout is redirected. By default we require the "--stdout"
+ * option to be given, but some scripts were written making use of the
+ * behavior of dialog which tried opening the terminal anyway.
+ */
+#define dialog_tty() (dlg_getenv_num("DIALOG_TTY", (int *)0) > 0)
+
+/*
+ * Open the terminal directly. If one of stdin, stdout or stderr really points
+ * to a tty, use it. Otherwise give up and open /dev/tty.
+ */
+static int
+open_terminal(char **result, int mode)
+{
+ const char *device = TTY_DEVICE;
+ if (!isatty(fileno(stderr))
+ || (device = ttyname(fileno(stderr))) == 0) {
+ if (!isatty(fileno(stdout))
+ || (device = ttyname(fileno(stdout))) == 0) {
+ if (!isatty(fileno(stdin))
+ || (device = ttyname(fileno(stdin))) == 0) {
+ device = TTY_DEVICE;
+ }
+ }
+ }
+ *result = dlg_strclone(device);
+ return open(device, mode);
+}
+
+#if CAN_KEEP_TITE
+static int
+my_putc(int ch)
+{
+ char buffer[2];
+ int fd = fileno(dialog_state.screen_output);
+
+ buffer[0] = (char) ch;
+ return (int) write(fd, buffer, (size_t) 1);
+}
+#endif
+
+/*
+ * Do some initialization for dialog.
+ *
+ * 'input' is the real tty input of dialog. Usually it is stdin, but if
+ * --input-fd option is used, it may be anything.
+ *
+ * 'output' is where dialog will send its result. Usually it is stderr, but
+ * if --stdout or --output-fd is used, it may be anything. We are concerned
+ * mainly with the case where it happens to be the same as stdout.
+ */
+void
+init_dialog(FILE *input, FILE *output)
+{
+ int fd1, fd2;
+ char *device = 0;
+
+ setlocale(LC_ALL, "");
+
+ dialog_state.output = output;
+ if (dialog_state.tab_len == 0)
+ dialog_state.tab_len = TAB_LEN;
+ if (dialog_state.aspect_ratio == 0)
+ dialog_state.aspect_ratio = DEFAULT_ASPECT_RATIO;
+#ifdef HAVE_COLOR
+ dialog_state.use_colors = USE_COLORS; /* use colors by default? */
+ dialog_state.use_shadow = USE_SHADOW; /* shadow dialog boxes by default? */
+#endif
+
+#ifdef HAVE_RC_FILE
+ if (dlg_parse_rc() == -1) /* Read the configuration file */
+ dlg_exiterr("init_dialog: dlg_parse_rc");
+#endif
+
+ /*
+ * Some widgets (such as gauge) may read from the standard input. Pipes
+ * only connect stdout/stdin, so there is not much choice. But reading a
+ * pipe would get in the way of curses' normal reading stdin for getch.
+ *
+ * As in the --stdout (see below), reopening the terminal does not always
+ * work properly. dialog provides a --pipe-fd option for this purpose. We
+ * test that case first (differing fileno's for input/stdin). If the
+ * fileno's are equal, but we're not reading from a tty, see if we can open
+ * /dev/tty.
+ */
+ dialog_state.pipe_input = stdin;
+ if (fileno(input) != fileno(stdin)) {
+ if ((fd1 = dup(fileno(input))) >= 0
+ && (fd2 = dup(fileno(stdin))) >= 0) {
+ (void) dup2(fileno(input), fileno(stdin));
+ dialog_state.pipe_input = fdopen(fd2, "r");
+ if (fileno(stdin) != 0) /* some functions may read fd #0 */
+ (void) dup2(fileno(stdin), 0);
+ } else {
+ dlg_exiterr("cannot open tty-input");
+ }
+ close(fd1);
+ } else if (!isatty(fileno(stdin))) {
+ if ((fd1 = open_terminal(&device, O_RDONLY)) >= 0) {
+ if ((fd2 = dup(fileno(stdin))) >= 0) {
+ dialog_state.pipe_input = fdopen(fd2, "r");
+ if (freopen(device, "r", stdin) == 0)
+ dlg_exiterr("cannot open tty-input");
+ if (fileno(stdin) != 0) /* some functions may read fd #0 */
+ (void) dup2(fileno(stdin), 0);
+ }
+ close(fd1);
+ }
+ free(device);
+ }
+
+ /*
+ * If stdout is not a tty and dialog is called with the --stdout option, we
+ * have to provide for a way to write to the screen.
+ *
+ * The curses library normally writes its output to stdout, leaving stderr
+ * free for scripting. Scripts are simpler when stdout is redirected. The
+ * newterm function is useful; it allows us to specify where the output
+ * goes. Reopening the terminal is not portable since several
+ * configurations do not allow this to work properly:
+ *
+ * a) some getty implementations (and possibly broken tty drivers, e.g., on
+ * HPUX 10 and 11) cause stdin to act as if it is still in cooked mode
+ * even though results from ioctl's state that it is successfully
+ * altered to raw mode. Broken is the proper term.
+ *
+ * b) the user may not have permissions on the device, e.g., if one su's
+ * from the login user to another non-privileged user.
+ */
+ if (!isatty(fileno(stdout))
+ && (fileno(stdout) == fileno(output) || dialog_tty())) {
+ if ((fd1 = open_terminal(&device, O_WRONLY)) >= 0
+ && (dialog_state.screen_output = fdopen(fd1, "w")) != 0) {
+ if (newterm(NULL, dialog_state.screen_output, stdin) == 0) {
+ dlg_exiterr("cannot initialize curses");
+ }
+ free(device);
+ } else {
+ dlg_exiterr("cannot open tty-output");
+ }
+ } else {
+ dialog_state.screen_output = stdout;
+ (void) initscr();
+ }
+ dlg_keep_tite(dialog_state.screen_output);
+#ifdef HAVE_FLUSHINP
+ (void) flushinp();
+#endif
+ (void) keypad(stdscr, TRUE);
+ (void) cbreak();
+ (void) noecho();
+
+ if (!dialog_state.no_mouse) {
+ mouse_open();
+ }
+
+ dialog_state.screen_initialized = TRUE;
+
+#ifdef HAVE_COLOR
+ if (dialog_state.use_colors || dialog_state.use_shadow)
+ dlg_color_setup(); /* Set up colors */
+#endif
+
+ /* Set screen to screen attribute */
+ dlg_clear();
+}
+
+void
+dlg_keep_tite(FILE *output)
+{
+ if (!dialog_vars.keep_tite) {
+#if CAN_KEEP_TITE
+ /*
+ * Cancel xterm's alternate-screen mode.
+ */
+ if ((fileno(output) != fileno(stdout)
+ || isatty(fileno(output)))
+ && key_mouse != 0 /* xterm and kindred */
+ && isprivate(enter_ca_mode)
+ && isprivate(exit_ca_mode)) {
+ FILE *save = dialog_state.screen_output;
+
+ /*
+ * initscr() or newterm() already wrote enter_ca_mode as a side
+ * effect of initializing the screen. It would be nice to not even
+ * do that, but we do not really have access to the correct copy of
+ * the terminfo description until those functions have been
+ * invoked.
+ */
+ (void) refresh();
+ dialog_state.screen_output = output;
+ (void) tputs(exit_ca_mode, 0, my_putc);
+ (void) tputs(clear_screen, 0, my_putc);
+ dialog_state.screen_output = save;
+
+ /*
+ * Prevent ncurses from switching "back" to the normal screen when
+ * exiting from dialog. That would move the cursor to the original
+ * location saved in xterm. Normally curses sets the cursor
+ * position to the first line after the display, but the alternate
+ * screen switching is done after that point.
+ *
+ * Cancelling the strings altogether also works around the buggy
+ * implementation of alternate-screen in rxvt, etc., which clear
+ * more of the display than they should.
+ */
+ enter_ca_mode = 0;
+ exit_ca_mode = 0;
+ }
+#else
+ /*
+ * For other implementations, there are no useful answers:
+ * + SVr4 curses "could" support a similar approach, but the clue about
+ * xterm is absent from its terminal database.
+ * + PDCurses does not provide terminfo.
+ */
+ (void) output;
+#endif
+ }
+}
+
+#ifdef HAVE_COLOR
+static int defined_colors = 1; /* pair-0 is reserved */
+/*
+ * Setup for color display
+ */
+void
+dlg_color_setup(void)
+{
+ if (has_colors()) { /* Terminal supports color? */
+ unsigned i;
+
+ (void) start_color();
+
+#if defined(HAVE_USE_DEFAULT_COLORS)
+ use_default_colors();
+#endif
+
+#if defined(__NetBSD__) && defined(_CURSES_)
+#define C_ATTR(x,y) (((x) != 0 ? A_BOLD : 0) | COLOR_PAIR((y)))
+ /* work around bug in NetBSD curses */
+ for (i = 0; i < sizeof(dlg_color_table) /
+ sizeof(dlg_color_table[0]); i++) {
+
+ /* Initialize color pairs */
+ (void) init_pair(i + 1,
+ dlg_color_table[i].fg,
+ dlg_color_table[i].bg);
+
+ /* Setup color attributes */
+ dlg_color_table[i].atr = C_ATTR(dlg_color_table[i].hilite, i + 1);
+ }
+ defined_colors = i + 1;
+#else
+ for (i = 0; i < sizeof(dlg_color_table) /
+ sizeof(dlg_color_table[0]); i++) {
+
+ /* Initialize color pairs */
+ chtype atr = dlg_color_pair(dlg_color_table[i].fg,
+ dlg_color_table[i].bg);
+
+ atr |= (dlg_color_table[i].hilite ? A_BOLD : 0);
+#ifdef HAVE_RC_FILE2
+ atr |= (dlg_color_table[i].ul ? A_UNDERLINE : 0);
+ atr |= (dlg_color_table[i].rv ? A_REVERSE : 0);
+#endif /* HAVE_RC_FILE2 */
+
+ dlg_color_table[i].atr = atr;
+ }
+#endif
+ } else {
+ dialog_state.use_colors = FALSE;
+ dialog_state.use_shadow = FALSE;
+ }
+}
+
+int
+dlg_color_count(void)
+{
+ return TableSize(dlg_color_table);
+}
+
+/*
+ * Wrapper for getattrs(), or the more cumbersome X/Open wattr_get().
+ */
+chtype
+dlg_get_attrs(WINDOW *win)
+{
+ chtype result;
+#ifdef HAVE_GETATTRS
+ result = (chtype) getattrs(win);
+#else
+ attr_t my_result;
+ short my_pair;
+ wattr_get(win, &my_result, &my_pair, NULL);
+ result = my_result;
+#endif
+ return result;
+}
+
+/*
+ * Reuse color pairs (they are limited), returning a COLOR_PAIR() value if we
+ * have (or can) define a pair with the given color as foreground on the
+ * window's defined background.
+ */
+chtype
+dlg_color_pair(int foreground, int background)
+{
+ chtype result = 0;
+ int pair;
+ short fg, bg;
+ bool found = FALSE;
+
+ for (pair = 1; pair < defined_colors; ++pair) {
+ if (pair_content((short) pair, &fg, &bg) != ERR
+ && fg == foreground
+ && bg == background) {
+ result = (chtype) COLOR_PAIR(pair);
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found && (defined_colors + 1) < COLOR_PAIRS) {
+ pair = defined_colors++;
+ (void) init_pair((short) pair, (short) foreground, (short) background);
+ result = (chtype) COLOR_PAIR(pair);
+ }
+ return result;
+}
+
+/*
+ * Reuse color pairs (they are limited), returning a COLOR_PAIR() value if we
+ * have (or can) define a pair with the given color as foreground on the
+ * window's defined background.
+ */
+static chtype
+define_color(WINDOW *win, int foreground)
+{
+ short fg, bg, background;
+ if (dialog_state.text_only) {
+ background = COLOR_BLACK;
+ } else {
+ chtype attrs = dlg_get_attrs(win);
+ int pair;
+
+ if ((pair = PAIR_NUMBER(attrs)) != 0
+ && pair_content((short) pair, &fg, &bg) != ERR) {
+ background = bg;
+ } else {
+ background = COLOR_BLACK;
+ }
+ }
+ return dlg_color_pair(foreground, background);
+}
+#endif
+
+/*
+ * End using dialog functions.
+ */
+void
+end_dialog(void)
+{
+ if (dialog_state.screen_initialized) {
+ dialog_state.screen_initialized = FALSE;
+ if (dialog_vars.erase_on_exit) {
+ /*
+ * Clear the screen to the native background color, and leave the
+ * terminal cursor at the lower-left corner of the screen.
+ */
+ werase(stdscr);
+ wrefresh(stdscr);
+ }
+ mouse_close();
+ (void) endwin();
+ (void) fflush(stdout);
+ }
+}
+
+#define ESCAPE_LEN 3
+#define isOurEscape(p) (((p)[0] == '\\') && ((p)[1] == 'Z') && ((p)[2] != 0))
+
+int
+dlg_count_real_columns(const char *text)
+{
+ int result = 0;
+ if (*text) {
+ result = dlg_count_columns(text);
+ if (result && dialog_vars.colors) {
+ int hidden = 0;
+ while (*text) {
+ if (isOurEscape(text)) {
+ hidden += ESCAPE_LEN;
+ text += ESCAPE_LEN;
+ } else {
+ ++text;
+ }
+ }
+ result -= hidden;
+ }
+ }
+ return result;
+}
+
+static int
+centered(int width, const char *string)
+{
+ int need = dlg_count_real_columns(string);
+ int left;
+
+ left = (width - need) / 2 - 1;
+ if (left < 0)
+ left = 0;
+ return left;
+}
+
+#ifdef USE_WIDE_CURSES
+static bool
+is_combining(const char *txt, int *combined)
+{
+ bool result = FALSE;
+
+ if (*combined == 0) {
+ if (UCH(*txt) >= 128) {
+ wchar_t wch;
+ mbstate_t state;
+ size_t given = strlen(txt);
+ size_t len;
+
+ memset(&state, 0, sizeof(state));
+ len = mbrtowc(&wch, txt, given, &state);
+ if ((int) len > 0 && wcwidth(wch) == 0) {
+ *combined = (int) len - 1;
+ result = TRUE;
+ }
+ }
+ } else {
+ result = TRUE;
+ *combined -= 1;
+ }
+ return result;
+}
+#endif
+
+/*
+ * Print the name (tag) or text from a DIALOG_LISTITEM, highlighting the
+ * first character if selected.
+ */
+void
+dlg_print_listitem(WINDOW *win,
+ const char *text,
+ int climit,
+ bool first,
+ int selected)
+{
+ chtype attr = A_NORMAL;
+ int limit;
+ chtype attrs[4];
+
+ if (text == 0)
+ text = "";
+
+ if (first && !dialog_vars.no_hot_list) {
+ const int *indx = dlg_index_wchars(text);
+ attrs[3] = tag_key_selected_attr;
+ attrs[2] = tag_key_attr;
+ attrs[1] = tag_selected_attr;
+ attrs[0] = tag_attr;
+
+ dlg_attrset(win, selected ? attrs[3] : attrs[2]);
+ if (*text != '\0') {
+ (void) waddnstr(win, text, indx[1]);
+
+ if ((int) strlen(text) > indx[1]) {
+ limit = dlg_limit_columns(text, climit, 1);
+ if (limit > 1) {
+ dlg_attrset(win, selected ? attrs[1] : attrs[0]);
+ (void) waddnstr(win,
+ text + indx[1],
+ indx[limit] - indx[1]);
+ }
+ }
+ }
+ } else {
+ const int *cols;
+
+ attrs[1] = item_selected_attr;
+ attrs[0] = item_attr;
+
+ cols = dlg_index_columns(text);
+ limit = dlg_limit_columns(text, climit, 0);
+
+ if (limit > 0) {
+ dlg_attrset(win, selected ? attrs[1] : attrs[0]);
+ dlg_print_text(win, text, cols[limit], &attr);
+ }
+ }
+}
+
+void
+dlg_print_nowrap(WINDOW *win, const char *line, int width)
+{
+ int limit;
+ int x_1st;
+ int x_now;
+ int x = 0;
+ int y;
+ int ch;
+ bool done;
+
+ (void) y;
+ getyx(win, y, x_1st);
+ waddch(win, ' ');
+ done = (width <= MARGIN);
+ limit = x_1st + width - 1;
+ do {
+ if (done) {
+ waddch(win, ' ');
+ } else if ((ch = line[x++]) != '\0') {
+ waddch(win, UCH(ch));
+ } else {
+ done = TRUE;
+ }
+ getyx(win, y, x_now);
+ } while (x_now < limit);
+}
+
+/*
+ * Print up to 'cols' columns from 'text', optionally rendering our escape
+ * sequence for attributes and color.
+ */
+void
+dlg_print_text(WINDOW *win, const char *txt, int cols, chtype *attr)
+{
+ int y_origin, x_origin;
+ int y_before, x_before = 0;
+ int y_after, x_after;
+ int tabbed = 0;
+ bool ended = FALSE;
+#ifdef USE_WIDE_CURSES
+ int combined = 0;
+#endif
+
+ if (dialog_state.text_only) {
+ y_origin = y_after = 0;
+ x_origin = x_after = 0;
+ } else {
+ y_after = 0;
+ x_after = 0;
+ getyx(win, y_origin, x_origin);
+ }
+ while (cols > 0 && (*txt != '\0')) {
+ bool thisTab;
+ chtype useattr;
+
+ if (dialog_vars.colors) {
+ while (isOurEscape(txt)) {
+ int code;
+
+ txt += 2;
+ switch (code = UCH(*txt)) {
+#ifdef HAVE_COLOR
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ *attr &= ~A_COLOR;
+ *attr |= define_color(win, code - '0');
+ break;
+#endif
+ case 'B':
+ *attr &= ~A_BOLD;
+ break;
+ case 'b':
+ *attr |= A_BOLD;
+ break;
+ case 'R':
+ *attr &= ~A_REVERSE;
+ break;
+ case 'r':
+ *attr |= A_REVERSE;
+ break;
+ case 'U':
+ *attr &= ~A_UNDERLINE;
+ break;
+ case 'u':
+ *attr |= A_UNDERLINE;
+ break;
+ case 'n':
+ *attr = A_NORMAL;
+ break;
+ default:
+ break;
+ }
+ ++txt;
+ }
+ }
+ if (ended || *txt == '\n' || *txt == '\0')
+ break;
+ useattr = (*attr) & A_ATTRIBUTES;
+#ifdef HAVE_COLOR
+ /*
+ * Prevent this from making text invisible when the foreground and
+ * background colors happen to be the same, and there's no bold
+ * attribute.
+ */
+ if ((useattr & A_COLOR) != 0 && (useattr & A_BOLD) == 0) {
+ short pair = (short) PAIR_NUMBER(useattr);
+ short fg, bg;
+ if (pair_content(pair, &fg, &bg) != ERR
+ && fg == bg) {
+ useattr &= ~A_COLOR;
+ useattr |= dlg_color_pair(fg, ((bg == COLOR_BLACK)
+ ? COLOR_WHITE
+ : COLOR_BLACK));
+ }
+ }
+#endif
+ /*
+ * Write the character, using curses to tell exactly how wide it
+ * is. If it is a tab, discount that, since the caller thinks
+ * tabs are nonprinting, and curses will expand tabs to one or
+ * more blanks.
+ */
+ thisTab = (UCH(*txt) == TAB);
+ if (dialog_state.text_only) {
+ x_before = x_after;
+ } else {
+ if (thisTab) {
+ getyx(win, y_before, x_before);
+ (void) y_before;
+ }
+ }
+ if (dialog_state.text_only) {
+ int ch = UCH(*txt++);
+ if (thisTab) {
+ while ((x_after++) % 8) {
+ fputc(' ', dialog_state.output);
+ }
+ } else {
+ fputc(ch, dialog_state.output);
+ x_after++; /* FIXME: handle meta per locale */
+ }
+ } else {
+ (void) waddch(win, UCH(*txt++) | useattr);
+ getyx(win, y_after, x_after);
+ }
+ if (thisTab && (y_after == y_origin))
+ tabbed += (x_after - x_before);
+ if ((y_after != y_origin) ||
+ (x_after >= (cols + tabbed + x_origin)
+#ifdef USE_WIDE_CURSES
+ && !is_combining(txt, &combined)
+#endif
+ )) {
+ ended = TRUE;
+ }
+ }
+ if (dialog_state.text_only) {
+ fputc('\n', dialog_state.output);
+ }
+}
+
+/*
+ * Print one line of the prompt in the window within the limits of the
+ * specified right margin. The line will end on a word boundary and a pointer
+ * to the start of the next line is returned, or a NULL pointer if the end of
+ * *prompt is reached.
+ */
+const char *
+dlg_print_line(WINDOW *win,
+ chtype *attr,
+ const char *prompt,
+ int lm, int rm, int *x)
+{
+ const char *wrap_ptr;
+ const char *test_ptr;
+ const char *hide_ptr = 0;
+ const int *cols = dlg_index_columns(prompt);
+ const int *indx = dlg_index_wchars(prompt);
+ int wrap_inx = 0;
+ int test_inx = 0;
+ int cur_x = lm;
+ int hidden = 0;
+ int limit = dlg_count_wchars(prompt);
+ int n;
+ int tabbed = 0;
+
+ *x = 1;
+
+ /*
+ * Set *test_ptr to the end of the line or the right margin (rm), whichever
+ * is less, and set wrap_ptr to the end of the last word in the line.
+ */
+ for (n = 0; n < limit; ++n) {
+ int ch = *(test_ptr = prompt + indx[test_inx]);
+ if (ch == '\n' || ch == '\0' || cur_x >= (rm + hidden))
+ break;
+ if (ch == TAB && n == 0) {
+ tabbed = 8; /* workaround for leading tabs */
+ } else if (isblank(UCH(ch))
+ && n != 0
+ && !isblank(UCH(prompt[indx[n - 1]]))) {
+ wrap_inx = n;
+ *x = cur_x;
+ } else if (dialog_vars.colors && isOurEscape(test_ptr)) {
+ hide_ptr = test_ptr;
+ hidden += ESCAPE_LEN;
+ n += (ESCAPE_LEN - 1);
+ }
+ cur_x = lm + tabbed + cols[n + 1];
+ if (cur_x > (rm + hidden))
+ break;
+ test_inx = n + 1;
+ }
+
+ /*
+ * If the line doesn't reach the right margin in the middle of a word, then
+ * we don't have to wrap it at the end of the previous word.
+ */
+ test_ptr = prompt + indx[test_inx];
+ if (*test_ptr == '\n' || isblank(UCH(*test_ptr)) || *test_ptr == '\0') {
+ wrap_inx = test_inx;
+ while (wrap_inx > 0 && isblank(UCH(prompt[indx[wrap_inx - 1]]))) {
+ wrap_inx--;
+ }
+ *x = lm + indx[wrap_inx];
+ } else if (*x == 1 && cur_x >= rm) {
+ /*
+ * If the line has no spaces, then wrap it anyway at the right margin
+ */
+ *x = rm;
+ wrap_inx = test_inx;
+ }
+ wrap_ptr = prompt + indx[wrap_inx];
+#ifdef USE_WIDE_CURSES
+ if (UCH(*wrap_ptr) >= 128) {
+ int combined = 0;
+ while (is_combining(wrap_ptr, &combined)) {
+ ++wrap_ptr;
+ }
+ }
+#endif
+
+ /*
+ * If we found hidden text past the last point that we will display,
+ * discount that from the displayed length.
+ */
+ if ((hide_ptr != 0) && (hide_ptr >= wrap_ptr)) {
+ hidden -= ESCAPE_LEN;
+ test_ptr = wrap_ptr;
+ while (test_ptr < wrap_ptr) {
+ if (dialog_vars.colors && isOurEscape(test_ptr)) {
+ hidden -= ESCAPE_LEN;
+ test_ptr += ESCAPE_LEN;
+ } else {
+ ++test_ptr;
+ }
+ }
+ }
+
+ /*
+ * Print the line if we have a window pointer. Otherwise this routine
+ * is just being called for sizing the window.
+ */
+ if (dialog_state.text_only || win) {
+ dlg_print_text(win, prompt, (cols[wrap_inx] - hidden), attr);
+ }
+
+ /* *x tells the calling function how long the line was */
+ if (*x == 1) {
+ *x = rm;
+ }
+
+ *x -= hidden;
+
+ /* Find the start of the next line and return a pointer to it */
+ test_ptr = wrap_ptr;
+ while (isblank(UCH(*test_ptr)))
+ test_ptr++;
+ if (*test_ptr == '\n')
+ test_ptr++;
+ dlg_finish_string(prompt);
+ return (test_ptr);
+}
+
+static void
+justify_text(WINDOW *win,
+ const char *prompt,
+ int limit_y,
+ int limit_x,
+ int *high, int *wide)
+{
+ chtype attr = A_NORMAL;
+ int x;
+ int y = MARGIN;
+ int max_x = 2;
+ int lm = (2 * MARGIN); /* left margin (box-border plus a space) */
+ int rm = limit_x; /* right margin */
+ int bm = limit_y; /* bottom margin */
+ int last_y = 0, last_x = 0;
+
+ dialog_state.text_height = 0;
+ dialog_state.text_width = 0;
+ if (dialog_state.text_only || win) {
+ rm -= (2 * MARGIN);
+ bm -= (2 * MARGIN);
+ }
+ if (prompt == 0)
+ prompt = "";
+
+ if (win != 0)
+ getyx(win, last_y, last_x);
+ while (y <= bm && *prompt) {
+ x = lm;
+
+ if (*prompt == '\n') {
+ while (*prompt == '\n' && y < bm) {
+ if (*(prompt + 1) != '\0') {
+ ++y;
+ if (win != 0)
+ (void) wmove(win, y, lm);
+ }
+ prompt++;
+ }
+ } else if (win != 0)
+ (void) wmove(win, y, lm);
+
+ if (*prompt) {
+ prompt = dlg_print_line(win, &attr, prompt, lm, rm, &x);
+ if (win != 0)
+ getyx(win, last_y, last_x);
+ }
+ if (*prompt) {
+ ++y;
+ if (win != 0)
+ (void) wmove(win, y, lm);
+ }
+ max_x = MAX(max_x, x);
+ }
+ /* Move back to the last position after drawing prompt, for msgbox. */
+ if (win != 0)
+ (void) wmove(win, last_y, last_x);
+
+ /* Set the final height and width for the calling function */
+ if (high != 0)
+ *high = y;
+ if (wide != 0)
+ *wide = max_x;
+}
+
+/*
+ * Print a string of text in a window, automatically wrap around to the next
+ * line if the string is too long to fit on one line. Note that the string may
+ * contain embedded newlines.
+ */
+void
+dlg_print_autowrap(WINDOW *win, const char *prompt, int height, int width)
+{
+ justify_text(win, prompt,
+ height,
+ width,
+ (int *) 0, (int *) 0);
+}
+
+/*
+ * Display the message in a scrollable window. Actually the way it works is
+ * that we create a "tall" window of the proper width, let the text wrap within
+ * that, and copy a slice of the result to the dialog.
+ *
+ * It works for ncurses. Other curses implementations show only blanks (Tru64)
+ * or garbage (NetBSD).
+ */
+int
+dlg_print_scrolled(WINDOW *win,
+ const char *prompt,
+ int offset,
+ int height,
+ int width,
+ int pauseopt)
+{
+ int oldy, oldx;
+ int last = 0;
+
+ (void) pauseopt; /* used only for ncurses */
+
+ getyx(win, oldy, oldx);
+#ifdef NCURSES_VERSION
+ if (pauseopt) {
+ int wide = width - (2 * MARGIN);
+ int high = LINES;
+ int len;
+ WINDOW *dummy;
+
+#if defined(NCURSES_VERSION_PATCH) && NCURSES_VERSION_PATCH >= 20040417
+ /*
+ * If we're not limited by the screensize, allow text to possibly be
+ * one character per line.
+ */
+ if ((len = dlg_count_columns(prompt)) > high)
+ high = len;
+#endif
+ dummy = newwin(high, width, 0, 0);
+ if (dummy == 0) {
+ dlg_attrset(win, dialog_attr);
+ dlg_print_autowrap(win, prompt, height + 1 + (3 * MARGIN), width);
+ last = 0;
+ } else {
+ int y, x;
+
+ wbkgdset(dummy, dialog_attr | ' ');
+ dlg_attrset(dummy, dialog_attr);
+ werase(dummy);
+ dlg_print_autowrap(dummy, prompt, high, width);
+ getyx(dummy, y, x);
+ (void) x;
+
+ copywin(dummy, /* srcwin */
+ win, /* dstwin */
+ offset + MARGIN, /* sminrow */
+ MARGIN, /* smincol */
+ MARGIN, /* dminrow */
+ MARGIN, /* dmincol */
+ height, /* dmaxrow */
+ wide, /* dmaxcol */
+ FALSE);
+
+ delwin(dummy);
+
+ /* if the text is incomplete, or we have scrolled, show the percentage */
+ if (y > 0 && wide > 4) {
+ int percent = (int) ((height + offset) * 100.0 / y);
+
+ if (percent < 0)
+ percent = 0;
+ if (percent > 100)
+ percent = 100;
+
+ if (offset != 0 || percent != 100) {
+ char buffer[5];
+
+ dlg_attrset(win, position_indicator_attr);
+ (void) wmove(win, MARGIN + height, wide - 4);
+ (void) sprintf(buffer, "%d%%", percent);
+ (void) waddstr(win, buffer);
+ if ((len = (int) strlen(buffer)) < 4) {
+ dlg_attrset(win, border_attr);
+ whline(win, dlg_boxchar(ACS_HLINE), 4 - len);
+ }
+ }
+ }
+ last = (y - height);
+ }
+ } else
+#endif
+ {
+ (void) offset;
+ dlg_attrset(win, dialog_attr);
+ dlg_print_autowrap(win, prompt, height + 1 + (3 * MARGIN), width);
+ last = 0;
+ }
+ wmove(win, oldy, oldx);
+ return last;
+}
+
+int
+dlg_check_scrolled(int key, int last, int page, bool * show, int *offset)
+{
+ int code = 0;
+
+ *show = FALSE;
+
+ switch (key) {
+ case DLGK_PAGE_FIRST:
+ if (*offset > 0) {
+ *offset = 0;
+ *show = TRUE;
+ }
+ break;
+ case DLGK_PAGE_LAST:
+ if (*offset < last) {
+ *offset = last;
+ *show = TRUE;
+ }
+ break;
+ case DLGK_GRID_UP:
+ if (*offset > 0) {
+ --(*offset);
+ *show = TRUE;
+ }
+ break;
+ case DLGK_GRID_DOWN:
+ if (*offset < last) {
+ ++(*offset);
+ *show = TRUE;
+ }
+ break;
+ case DLGK_PAGE_PREV:
+ if (*offset > 0) {
+ *offset -= page;
+ if (*offset < 0)
+ *offset = 0;
+ *show = TRUE;
+ }
+ break;
+ case DLGK_PAGE_NEXT:
+ if (*offset < last) {
+ *offset += page;
+ if (*offset > last)
+ *offset = last;
+ *show = TRUE;
+ }
+ break;
+ default:
+ code = -1;
+ break;
+ }
+ return code;
+}
+
+/*
+ * Calculate the window size for preformatted text. This will calculate box
+ * dimensions that are at or close to the specified aspect ratio for the prompt
+ * string with all spaces and newlines preserved and additional newlines added
+ * as necessary.
+ */
+static void
+auto_size_preformatted(const char *prompt, int *height, int *width)
+{
+ int high = 0, wide = 0;
+ float car; /* Calculated Aspect Ratio */
+ int max_y = SLINES - 1;
+ int max_x = SCOLS - 2;
+ int max_width = max_x;
+ int ar = dialog_state.aspect_ratio;
+
+ /* Get the initial dimensions */
+ justify_text((WINDOW *) 0, prompt, max_y, max_x, &high, &wide);
+ car = (float) (wide / high);
+
+ *height = high;
+ *width = wide;
+}
+
+/*
+ * Find the length of the longest "word" in the given string. By setting the
+ * widget width at least this long, we can avoid splitting a word on the
+ * margin.
+ */
+static int
+longest_word(const char *string)
+{
+ int result = 0;
+
+ while (*string != '\0') {
+ int length = 0;
+ while (*string != '\0' && !isspace(UCH(*string))) {
+ length++;
+ string++;
+ }
+ result = MAX(result, length);
+ if (*string != '\0')
+ string++;
+ }
+ return result;
+}
+
+/*
+ * if (height or width == -1) Maximize()
+ * if (height or width == 0), justify and return actual limits.
+ */
+static void
+real_auto_size(const char *title,
+ const char *prompt,
+ int *height, int *width,
+ int boxlines, int mincols)
+{
+ int x = (dialog_vars.begin_set ? dialog_vars.begin_x : 2);
+ int y = (dialog_vars.begin_set ? dialog_vars.begin_y : 1);
+ int title_length = title ? dlg_count_columns(title) : 0;
+ int high;
+ int save_high = *height;
+ int save_wide = *width;
+ int max_high;
+ int max_wide;
+
+ if (prompt == 0) {
+ if (*height == 0)
+ *height = -1;
+ if (*width == 0)
+ *width = -1;
+ }
+
+ max_high = (*height < 0);
+ max_wide = (*width < 0);
+
+ if (*height > 0) {
+ high = *height;
+ } else {
+ high = SLINES - y;
+ }
+
+ if (*width <= 0) {
+ int wide;
+
+ if (prompt != 0) {
+ wide = MAX(title_length, mincols);
+ if (strchr(prompt, '\n') == 0) {
+ double val = (dialog_state.aspect_ratio *
+ dlg_count_real_columns(prompt));
+ double xxx = sqrt(val);
+ int tmp = (int) xxx;
+ wide = MAX(wide, tmp);
+ wide = MAX(wide, longest_word(prompt));
+ justify_text((WINDOW *) 0, prompt, high, wide, height, width);
+ } else {
+ auto_size_preformatted(prompt, height, width);
+ }
+ } else {
+ wide = SCOLS - x;
+ justify_text((WINDOW *) 0, prompt, high, wide, height, width);
+ }
+ }
+
+ if (*width < title_length) {
+ justify_text((WINDOW *) 0, prompt, high, title_length, height, width);
+ *width = title_length;
+ }
+
+ dialog_state.text_height = *height;
+ dialog_state.text_width = *width;
+
+ if (*width < mincols && save_wide == 0)
+ *width = mincols;
+ if (prompt != 0) {
+ *width += ((2 * MARGIN) + SHADOW_COLS);
+ *height += boxlines + (2 * MARGIN);
+ }
+
+ if (save_high > 0)
+ *height = save_high;
+ if (save_wide > 0)
+ *width = save_wide;
+
+ if (max_high)
+ *height = SLINES - (dialog_vars.begin_set ? dialog_vars.begin_y : 0);
+ if (max_wide)
+ *width = SCOLS - (dialog_vars.begin_set ? dialog_vars.begin_x : 0);
+}
+
+/* End of real_auto_size() */
+
+void
+dlg_auto_size(const char *title,
+ const char *prompt,
+ int *height,
+ int *width,
+ int boxlines,
+ int mincols)
+{
+ DLG_TRACE(("# dlg_auto_size(%d,%d) limits %d,%d\n",
+ *height, *width,
+ boxlines, mincols));
+
+ real_auto_size(title, prompt, height, width, boxlines, mincols);
+
+ if (*width > SCOLS) {
+ (*height)++;
+ *width = SCOLS;
+ }
+
+ if (*height > SLINES) {
+ *height = SLINES;
+ }
+ DLG_TRACE(("# ...dlg_auto_size(%d,%d) also %d,%d\n",
+ *height, *width,
+ dialog_state.text_height, dialog_state.text_width));
+}
+
+/*
+ * if (height or width == -1) Maximize()
+ * if (height or width == 0)
+ * height=MIN(SLINES, num.lines in fd+n);
+ * width=MIN(SCOLS, MAX(longer line+n, mincols));
+ */
+void
+dlg_auto_sizefile(const char *title,
+ const char *file,
+ int *height,
+ int *width,
+ int boxlines,
+ int mincols)
+{
+ int count = 0;
+ int len = title ? dlg_count_columns(title) : 0;
+ int nc = 4;
+ int numlines = 2;
+ FILE *fd;
+
+ /* Open input file for reading */
+ if ((fd = fopen(file, "rb")) == NULL)
+ dlg_exiterr("dlg_auto_sizefile: Cannot open input file %s", file);
+
+ if ((*height == -1) || (*width == -1)) {
+ *height = SLINES - (dialog_vars.begin_set ? dialog_vars.begin_y : 0);
+ *width = SCOLS - (dialog_vars.begin_set ? dialog_vars.begin_x : 0);
+ }
+ if ((*height != 0) && (*width != 0)) {
+ (void) fclose(fd);
+ if (*width > SCOLS)
+ *width = SCOLS;
+ if (*height > SLINES)
+ *height = SLINES;
+ return;
+ }
+
+ while (!feof(fd)) {
+ int ch;
+ long offset;
+
+ if (ferror(fd))
+ break;
+
+ offset = 0;
+ while (((ch = getc(fd)) != '\n') && !feof(fd)) {
+ if ((ch == TAB) && (dialog_vars.tab_correct)) {
+ offset += dialog_state.tab_len - (offset % dialog_state.tab_len);
+ } else {
+ offset++;
+ }
+ }
+
+ if (offset > len)
+ len = (int) offset;
+
+ count++;
+ }
+
+ /* now 'count' has the number of lines of fd and 'len' the max length */
+
+ *height = MIN(SLINES, count + numlines + boxlines);
+ *width = MIN(SCOLS, MAX((len + nc), mincols));
+ /* here width and height can be maximized if > SCOLS|SLINES because
+ textbox-like widgets don't put all <file> on the screen.
+ Msgbox-like widget instead have to put all <text> correctly. */
+
+ (void) fclose(fd);
+}
+
+/*
+ * Draw a rectangular box with line drawing characters.
+ *
+ * borderchar is used to color the upper/left edges.
+ *
+ * boxchar is used to color the right/lower edges. It also is fill-color used
+ * for the box contents.
+ *
+ * Normally, if you are drawing a scrollable box, use menubox_border_attr for
+ * boxchar, and menubox_attr for borderchar since the scroll-arrows are drawn
+ * with menubox_attr at the top, and menubox_border_attr at the bottom. That
+ * also (given the default color choices) produces a recessed effect.
+ *
+ * If you want a raised effect (and are not going to use the scroll-arrows),
+ * reverse this choice.
+ */
+void
+dlg_draw_box2(WINDOW *win, int y, int x, int height, int width,
+ chtype boxchar, chtype borderchar, chtype borderchar2)
+{
+ int i, j;
+ chtype save = dlg_get_attrs(win);
+
+ dlg_attrset(win, 0);
+ for (i = 0; i < height; i++) {
+ (void) wmove(win, y + i, x);
+ for (j = 0; j < width; j++)
+ if (!i && !j)
+ (void) waddch(win, borderchar | dlg_boxchar(ACS_ULCORNER));
+ else if (i == height - 1 && !j)
+ (void) waddch(win, borderchar | dlg_boxchar(ACS_LLCORNER));
+ else if (!i && j == width - 1)
+ (void) waddch(win, borderchar2 | dlg_boxchar(ACS_URCORNER));
+ else if (i == height - 1 && j == width - 1)
+ (void) waddch(win, borderchar2 | dlg_boxchar(ACS_LRCORNER));
+ else if (!i)
+ (void) waddch(win, borderchar | dlg_boxchar(ACS_HLINE));
+ else if (i == height - 1)
+ (void) waddch(win, borderchar2 | dlg_boxchar(ACS_HLINE));
+ else if (!j)
+ (void) waddch(win, borderchar | dlg_boxchar(ACS_VLINE));
+ else if (j == width - 1)
+ (void) waddch(win, borderchar2 | dlg_boxchar(ACS_VLINE));
+ else
+ (void) waddch(win, boxchar | ' ');
+ }
+ dlg_attrset(win, save);
+}
+
+void
+dlg_draw_box(WINDOW *win, int y, int x, int height, int width,
+ chtype boxchar, chtype borderchar)
+{
+ dlg_draw_box2(win, y, x, height, width, boxchar, borderchar, boxchar);
+}
+
+/*
+ * Search the given 'list' for the given window 'win'. Typically 'win' is an
+ * input-window, i.e., a window where we might use wgetch.
+ *
+ * The all-windows list has normal- and shadow-windows. Since we never use the
+ * shadow as an input window, normally we just look for the normal-window.
+ *
+ * However, the all-subwindows list stores parent/child windows rather than
+ * normal/shadow windows. When searching that list, we look for the child
+ * window (in the .shadow field).
+ */
+static DIALOG_WINDOWS *
+find_window(DIALOG_WINDOWS * list, WINDOW *win, bool normal)
+{
+ DIALOG_WINDOWS *result = 0;
+ DIALOG_WINDOWS *p;
+
+ for (p = list; p != 0; p = p->next) {
+ WINDOW *check = normal ? p->normal : p->shadow;
+ if (check == win) {
+ result = p;
+ break;
+ }
+ }
+ return result;
+}
+
+#define SearchTopWindows(win) find_window(dialog_state.all_windows, win, TRUE)
+#define SearchSubWindows(win) find_window(dialog_state.all_subwindows, win, FALSE)
+
+/*
+ * Check for the existence of a window, e.g., when used for input or updating
+ * the display. This is used in dlg_getc() and related functions, to guard
+ * against an asynchronous window-deletion that might invalidate the input
+ * window used in dlg_getc().
+ */
+DIALOG_WINDOWS *
+_dlg_find_window(WINDOW *win)
+{
+ DIALOG_WINDOWS *result = 0;
+
+ if ((result = SearchTopWindows(win)) == NULL)
+ result = SearchSubWindows(win);
+ return result;
+}
+
+#ifdef HAVE_COLOR
+/*
+ * If we have wchgat(), use that for updating shadow attributes, to work with
+ * wide-character data.
+ */
+
+/*
+ * Check if the given point is "in" the given window. If so, return the window
+ * pointer, otherwise null.
+ */
+static WINDOW *
+in_window(WINDOW *win, int y, int x)
+{
+ WINDOW *result = 0;
+ int y_base = getbegy(win);
+ int x_base = getbegx(win);
+ int y_last = getmaxy(win) + y_base;
+ int x_last = getmaxx(win) + x_base;
+
+ if (y >= y_base && y <= y_last && x >= x_base && x <= x_last)
+ result = win;
+ return result;
+}
+
+static WINDOW *
+window_at_cell(DIALOG_WINDOWS * dw, int y, int x)
+{
+ WINDOW *result = 0;
+ DIALOG_WINDOWS *p;
+ int y_want = y + getbegy(dw->shadow);
+ int x_want = x + getbegx(dw->shadow);
+
+ for (p = dialog_state.all_windows; p != 0; p = p->next) {
+ if (dw->normal != p->normal
+ && dw->shadow != p->normal
+ && (result = in_window(p->normal, y_want, x_want)) != 0) {
+ break;
+ }
+ }
+ if (result == 0) {
+ result = stdscr;
+ }
+ return result;
+}
+
+static bool
+in_shadow(WINDOW *normal, WINDOW *shadow, int y, int x)
+{
+ bool result = FALSE;
+ int ybase = getbegy(normal);
+ int ylast = getmaxy(normal) + ybase;
+ int xbase = getbegx(normal);
+ int xlast = getmaxx(normal) + xbase;
+
+ y += getbegy(shadow);
+ x += getbegx(shadow);
+
+ if (y >= ybase + SHADOW_ROWS
+ && y < ylast + SHADOW_ROWS
+ && x >= xlast
+ && x < xlast + SHADOW_COLS) {
+ /* in the right-side */
+ result = TRUE;
+ } else if (y >= ylast
+ && y < ylast + SHADOW_ROWS
+ && x >= ybase + SHADOW_COLS
+ && x < ylast + SHADOW_COLS) {
+ /* check the bottom */
+ result = TRUE;
+ }
+
+ return result;
+}
+
+/*
+ * When erasing a shadow, check each cell to make sure that it is not part of
+ * another box's shadow. This is a little complicated since most shadows are
+ * merged onto stdscr.
+ */
+static bool
+last_shadow(DIALOG_WINDOWS * dw, int y, int x)
+{
+ DIALOG_WINDOWS *p;
+ bool result = TRUE;
+
+ for (p = dialog_state.all_windows; p != 0; p = p->next) {
+ if (p->normal != dw->normal
+ && in_shadow(p->normal, dw->shadow, y, x)) {
+ result = FALSE;
+ break;
+ }
+ }
+ return result;
+}
+
+static void
+repaint_cell(DIALOG_WINDOWS * dw, bool draw, int y, int x)
+{
+ WINDOW *win = dw->shadow;
+ WINDOW *cellwin;
+ int y2, x2;
+
+ if ((cellwin = window_at_cell(dw, y, x)) != 0
+ && (draw || last_shadow(dw, y, x))
+ && (y2 = (y + getbegy(win) - getbegy(cellwin))) >= 0
+ && (x2 = (x + getbegx(win) - getbegx(cellwin))) >= 0
+ && wmove(cellwin, y2, x2) != ERR) {
+ chtype the_cell = dlg_get_attrs(cellwin);
+ chtype the_attr = (draw ? shadow_attr : the_cell);
+
+ if (winch(cellwin) & A_ALTCHARSET) {
+ the_attr |= A_ALTCHARSET;
+ }
+#if USE_WCHGAT
+ wchgat(cellwin, 1,
+ the_attr & (chtype) (~A_COLOR),
+ (short) PAIR_NUMBER(the_attr),
+ NULL);
+#else
+ {
+ chtype the_char = ((winch(cellwin) & A_CHARTEXT) | the_attr);
+ (void) waddch(cellwin, the_char);
+ }
+#endif
+ wnoutrefresh(cellwin);
+ }
+}
+
+#define RepaintCell(dw, draw, y, x) repaint_cell(dw, draw, y, x)
+
+static void
+repaint_shadow(DIALOG_WINDOWS * dw, bool draw, int y, int x, int height, int width)
+{
+ if (UseShadow(dw)) {
+ int i, j;
+
+#if !USE_WCHGAT
+ chtype save = dlg_get_attrs(dw->shadow);
+ dlg_attrset(dw->shadow, draw ? shadow_attr : screen_attr);
+#endif
+ for (i = 0; i < SHADOW_ROWS; ++i) {
+ for (j = 0; j < width; ++j) {
+ RepaintCell(dw, draw, i + y + height, j + x + SHADOW_COLS);
+ }
+ }
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < SHADOW_COLS; ++j) {
+ RepaintCell(dw, draw, i + y + SHADOW_ROWS, j + x + width);
+ }
+ }
+ (void) wnoutrefresh(dw->shadow);
+#if !USE_WCHGAT
+ dlg_attrset(dw->shadow, save);
+#endif
+ }
+}
+
+/*
+ * Draw a shadow on the parent window corresponding to the right- and
+ * bottom-edge of the child window, to give a 3-dimensional look.
+ */
+static void
+draw_childs_shadow(DIALOG_WINDOWS * dw)
+{
+ if (UseShadow(dw)) {
+ repaint_shadow(dw,
+ TRUE,
+ getbegy(dw->normal) - getbegy(dw->shadow),
+ getbegx(dw->normal) - getbegx(dw->shadow),
+ getmaxy(dw->normal),
+ getmaxx(dw->normal));
+ }
+}
+
+/*
+ * Erase a shadow on the parent window corresponding to the right- and
+ * bottom-edge of the child window.
+ */
+static void
+erase_childs_shadow(DIALOG_WINDOWS * dw)
+{
+ if (UseShadow(dw)) {
+ repaint_shadow(dw,
+ FALSE,
+ getbegy(dw->normal) - getbegy(dw->shadow),
+ getbegx(dw->normal) - getbegx(dw->shadow),
+ getmaxy(dw->normal),
+ getmaxx(dw->normal));
+ }
+}
+
+/*
+ * Draw shadows along the right and bottom edge to give a more 3D look
+ * to the boxes.
+ */
+void
+dlg_draw_shadow(WINDOW *win, int y, int x, int height, int width)
+{
+ repaint_shadow(SearchTopWindows(win), TRUE, y, x, height, width);
+}
+#endif /* HAVE_COLOR */
+
+/*
+ * Allow shell scripts to remap the exit codes so they can distinguish ESC
+ * from ERROR.
+ */
+void
+dlg_exit(int code)
+{
+ /* *INDENT-OFF* */
+ static const struct {
+ int code;
+ const char *name;
+ } table[] = {
+ { DLG_EXIT_CANCEL, "DIALOG_CANCEL" },
+ { DLG_EXIT_ERROR, "DIALOG_ERROR" },
+ { DLG_EXIT_ESC, "DIALOG_ESC" },
+ { DLG_EXIT_EXTRA, "DIALOG_EXTRA" },
+ { DLG_EXIT_HELP, "DIALOG_HELP" },
+ { DLG_EXIT_OK, "DIALOG_OK" },
+ { DLG_EXIT_ITEM_HELP, "DIALOG_ITEM_HELP" },
+ { DLG_EXIT_TIMEOUT, "DIALOG_TIMEOUT" },
+ };
+ /* *INDENT-ON* */
+
+ unsigned n;
+ bool overridden = FALSE;
+
+ retry:
+ for (n = 0; n < TableSize(table); n++) {
+ if (table[n].code == code) {
+ if (dlg_getenv_num(table[n].name, &code)) {
+ overridden = TRUE;
+ }
+ break;
+ }
+ }
+
+ /*
+ * Prior to 2004/12/19, a widget using --item-help would exit with "OK"
+ * if the help button were selected. Now we want to exit with "HELP",
+ * but allow the environment variable to override.
+ */
+ if (code == DLG_EXIT_ITEM_HELP && !overridden) {
+ code = DLG_EXIT_HELP;
+ goto retry;
+ }
+#ifdef HAVE_DLG_TRACE
+ dlg_trace((const char *) 0); /* close it */
+#endif
+
+#ifdef NO_LEAKS
+ _dlg_inputstr_leaks();
+#if defined(NCURSES_VERSION) && (defined(HAVE_EXIT_CURSES) || defined(HAVE__NC_FREE_AND_EXIT))
+ exit_curses(code);
+#endif
+#endif
+
+ if (dialog_state.input == stdin) {
+ exit(code);
+ } else {
+ /*
+ * Just in case of using --input-fd option, do not
+ * call atexit functions of ncurses which may hang.
+ */
+ if (dialog_state.input) {
+ fclose(dialog_state.input);
+ dialog_state.input = 0;
+ }
+ if (dialog_state.pipe_input) {
+ if (dialog_state.pipe_input != stdin) {
+ fclose(dialog_state.pipe_input);
+ dialog_state.pipe_input = 0;
+ }
+ }
+ _exit(code);
+ }
+}
+
+#define DATA(name) { DLG_EXIT_ ## name, #name }
+/* *INDENT-OFF* */
+static struct {
+ int code;
+ const char *name;
+} exit_codenames[] = {
+ DATA(ESC),
+ DATA(UNKNOWN),
+ DATA(ERROR),
+ DATA(OK),
+ DATA(CANCEL),
+ DATA(HELP),
+ DATA(EXTRA),
+ DATA(ITEM_HELP),
+};
+#undef DATA
+/* *INDENT-ON* */
+
+const char *
+dlg_exitcode2s(int code)
+{
+ const char *result = "?";
+ size_t n;
+
+ for (n = 0; n < TableSize(exit_codenames); ++n) {
+ if (exit_codenames[n].code == code) {
+ result = exit_codenames[n].name;
+ break;
+ }
+ }
+ return result;
+}
+
+int
+dlg_exitname2n(const char *name)
+{
+ int result = DLG_EXIT_UNKNOWN;
+ size_t n;
+
+ for (n = 0; n < TableSize(exit_codenames); ++n) {
+ if (!dlg_strcmp(exit_codenames[n].name, name)) {
+ result = exit_codenames[n].code;
+ break;
+ }
+ }
+ return result;
+}
+
+/* quit program killing all tailbg */
+void
+dlg_exiterr(const char *fmt, ...)
+{
+ int retval;
+ va_list ap;
+
+ end_dialog();
+
+ (void) fputc('\n', stderr);
+ va_start(ap, fmt);
+ (void) vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ (void) fputc('\n', stderr);
+
+#ifdef HAVE_DLG_TRACE
+ va_start(ap, fmt);
+ dlg_trace_msg("## Error: ");
+ dlg_trace_va_msg(fmt, ap);
+ va_end(ap);
+#endif
+
+ dlg_killall_bg(&retval);
+
+ (void) fflush(stderr);
+ (void) fflush(stdout);
+ dlg_exit(strcmp(fmt, "timeout") == 0 ? DLG_EXIT_TIMEOUT : DLG_EXIT_ERROR);
+}
+
+/*
+ * Get a string from the environment, rejecting those which are entirely blank.
+ */
+char *
+dlg_getenv_str(const char *name)
+{
+ char *result = getenv(name);
+ if (result != NULL) {
+ while (*result != '\0' && isspace(UCH(*result)))
+ ++result;
+ if (*result == '\0')
+ result = NULL;
+ }
+ return result;
+}
+
+/*
+ * Get a number from the environment:
+ * + If the caller provides a pointer in the second parameter, return
+ * success/failure for the function return, and the actual value via the
+ * pointer. Use this for decoding arbitrary numbers, e.g., negative or zero.
+ * + If the caller does not provide a pointer, return the decoded value for
+ * the function-return. Use this when only values greater than zero are
+ * useful.
+ */
+int
+dlg_getenv_num(const char *name, int *value)
+{
+ int result = 0;
+ char *data = getenv(name);
+ if (data != NULL) {
+ char *temp = NULL;
+ long check = strtol(data, &temp, 0);
+ if (temp != 0 && temp != data && *temp == '\0') {
+ result = (int) check;
+ if (value != NULL) {
+ *value = result;
+ result = 1;
+ }
+ }
+ }
+ return result;
+}
+
+void
+dlg_beeping(void)
+{
+ if (dialog_vars.beep_signal) {
+ (void) beep();
+ dialog_vars.beep_signal = 0;
+ }
+}
+
+void
+dlg_print_size(int height, int width)
+{
+ if (dialog_vars.print_siz) {
+ fprintf(dialog_state.output, "Size: %d, %d\n", height, width);
+ DLG_TRACE(("# print size: %dx%d\n", height, width));
+ }
+}
+
+void
+dlg_ctl_size(int height, int width)
+{
+ if (dialog_vars.size_err) {
+ if ((width > COLS) || (height > LINES)) {
+ dlg_exiterr("Window too big. (height, width) = (%d, %d). Max allowed (%d, %d).",
+ height, width, LINES, COLS);
+ }
+#ifdef HAVE_COLOR
+ else if ((dialog_state.use_shadow)
+ && ((width > SCOLS || height > SLINES))) {
+ if ((width <= COLS) && (height <= LINES)) {
+ /* try again, without shadows */
+ dialog_state.use_shadow = 0;
+ } else {
+ dlg_exiterr("Window+Shadow too big. (height, width) = (%d, %d). Max allowed (%d, %d).",
+ height, width, SLINES, SCOLS);
+ }
+ }
+#endif
+ }
+}
+
+/*
+ * If the --tab-correct was not selected, convert tabs to single spaces.
+ */
+void
+dlg_tab_correct_str(char *prompt)
+{
+ char *ptr;
+
+ if (dialog_vars.tab_correct) {
+ while ((ptr = strchr(prompt, TAB)) != NULL) {
+ *ptr = ' ';
+ prompt = ptr;
+ }
+ }
+}
+
+void
+dlg_calc_listh(int *height, int *list_height, int item_no)
+{
+ /* calculate new height and list_height */
+ int rows = SLINES - (dialog_vars.begin_set ? dialog_vars.begin_y : 0);
+ if (rows - (*height) > 0) {
+ if (rows - (*height) > item_no)
+ *list_height = item_no;
+ else
+ *list_height = rows - (*height);
+ }
+ (*height) += (*list_height);
+}
+
+/* obsolete */
+int
+dlg_calc_listw(int item_no, char **items, int group)
+{
+ int i, len1 = 0, len2 = 0;
+
+ for (i = 0; i < (item_no * group); i += group) {
+ int n;
+
+ if ((n = dlg_count_columns(items[i])) > len1)
+ len1 = n;
+ if ((n = dlg_count_columns(items[i + 1])) > len2)
+ len2 = n;
+ }
+ return len1 + len2;
+}
+
+int
+dlg_calc_list_width(int item_no, DIALOG_LISTITEM * items)
+{
+ int n, i, len1 = 0, len2 = 0;
+ int bits = ((dialog_vars.no_tags ? 1 : 0)
+ + (dialog_vars.no_items ? 2 : 0));
+
+ for (i = 0; i < item_no; ++i) {
+ switch (bits) {
+ case 0:
+ /* FALLTHRU */
+ case 1:
+ if ((n = dlg_count_columns(items[i].name)) > len1)
+ len1 = n;
+ if ((n = dlg_count_columns(items[i].text)) > len2)
+ len2 = n;
+ break;
+ case 2:
+ /* FALLTHRU */
+ case 3:
+ if ((n = dlg_count_columns(items[i].name)) > len1)
+ len1 = n;
+ break;
+ }
+ }
+ return len1 + len2;
+}
+
+char *
+dlg_strempty(void)
+{
+ static char empty[] = "";
+ return empty;
+}
+
+char *
+dlg_strclone(const char *cprompt)
+{
+ char *prompt = 0;
+ if (cprompt != 0) {
+ prompt = dlg_malloc(char, strlen(cprompt) + 1);
+ assert_ptr(prompt, "dlg_strclone");
+ strcpy(prompt, cprompt);
+ }
+ return prompt;
+}
+
+chtype
+dlg_asciibox(chtype ch)
+{
+ chtype result = 0;
+
+ if (ch == ACS_ULCORNER)
+ result = '+';
+ else if (ch == ACS_LLCORNER)
+ result = '+';
+ else if (ch == ACS_URCORNER)
+ result = '+';
+ else if (ch == ACS_LRCORNER)
+ result = '+';
+ else if (ch == ACS_HLINE)
+ result = '-';
+ else if (ch == ACS_VLINE)
+ result = '|';
+ else if (ch == ACS_LTEE)
+ result = '+';
+ else if (ch == ACS_RTEE)
+ result = '+';
+ else if (ch == ACS_UARROW)
+ result = '^';
+ else if (ch == ACS_DARROW)
+ result = 'v';
+
+ return result;
+}
+
+chtype
+dlg_boxchar(chtype ch)
+{
+ chtype result = dlg_asciibox(ch);
+
+ if (result != 0) {
+ if (dialog_vars.ascii_lines)
+ ch = result;
+ else if (dialog_vars.no_lines)
+ ch = ' ';
+ }
+ return ch;
+}
+
+int
+dlg_box_x_ordinate(int width)
+{
+ int x;
+
+ if (dialog_vars.begin_set == 1) {
+ x = dialog_vars.begin_x;
+ } else {
+ /* center dialog box on screen unless --begin-set */
+ x = (SCOLS - width) / 2;
+ }
+ return x;
+}
+
+int
+dlg_box_y_ordinate(int height)
+{
+ int y;
+
+ if (dialog_vars.begin_set == 1) {
+ y = dialog_vars.begin_y;
+ } else {
+ /* center dialog box on screen unless --begin-set */
+ y = (SLINES - height) / 2;
+ }
+ return y;
+}
+
+void
+dlg_draw_title(WINDOW *win, const char *title)
+{
+ if (title != NULL) {
+ chtype attr = A_NORMAL;
+ chtype save = dlg_get_attrs(win);
+ int x = centered(getmaxx(win), title);
+
+ dlg_attrset(win, title_attr);
+ wmove(win, 0, x);
+ dlg_print_text(win, title, getmaxx(win) - x, &attr);
+ dlg_attrset(win, save);
+ dlg_finish_string(title);
+ }
+}
+
+void
+dlg_draw_bottom_box2(WINDOW *win, chtype on_left, chtype on_right, chtype on_inside)
+{
+ int width = getmaxx(win);
+ int height = getmaxy(win);
+ int i;
+
+ dlg_attrset(win, on_left);
+ (void) wmove(win, height - 3, 0);
+ (void) waddch(win, dlg_boxchar(ACS_LTEE));
+ for (i = 0; i < width - 2; i++)
+ (void) waddch(win, dlg_boxchar(ACS_HLINE));
+ dlg_attrset(win, on_right);
+ (void) waddch(win, dlg_boxchar(ACS_RTEE));
+ dlg_attrset(win, on_inside);
+ (void) wmove(win, height - 2, 1);
+ for (i = 0; i < width - 2; i++)
+ (void) waddch(win, ' ');
+}
+
+void
+dlg_draw_bottom_box(WINDOW *win)
+{
+ dlg_draw_bottom_box2(win, border_attr, dialog_attr, dialog_attr);
+}
+
+/*
+ * Remove a window, repainting everything else. This would be simpler if we
+ * used the panel library, but that is not _always_ available.
+ */
+void
+dlg_del_window(WINDOW *win)
+{
+ DIALOG_WINDOWS *p, *q, *r;
+
+ /*
+ * If --keep-window was set, do not delete/repaint the windows.
+ */
+ if (dialog_vars.keep_window)
+ return;
+
+ /* Leave the main window untouched if there are no background windows.
+ * We do this so the current window will not be cleared on exit, allowing
+ * things like the infobox demo to run without flicker.
+ */
+ if (dialog_state.getc_callbacks != 0) {
+ touchwin(stdscr);
+ wnoutrefresh(stdscr);
+ }
+
+ for (p = dialog_state.all_windows, q = r = 0; p != 0; r = p, p = p->next) {
+ if (p->normal == win) {
+ q = p; /* found a match - should be only one */
+ if (r == 0) {
+ dialog_state.all_windows = p->next;
+ } else {
+ r->next = p->next;
+ }
+ } else {
+ if (p->shadow != 0) {
+ touchwin(p->shadow);
+ wnoutrefresh(p->shadow);
+ }
+ touchwin(p->normal);
+ wnoutrefresh(p->normal);
+ }
+ }
+
+ if (q) {
+ if (dialog_state.all_windows != 0)
+ erase_childs_shadow(q);
+ del_subwindows(q->normal);
+ dlg_unregister_window(q->normal);
+ delwin(q->normal);
+ free(q);
+ }
+ doupdate();
+}
+
+/*
+ * Create a window, optionally with a shadow.
+ */
+WINDOW *
+dlg_new_window(int height, int width, int y, int x)
+{
+ return dlg_new_modal_window(stdscr, height, width, y, x);
+}
+
+/*
+ * "Modal" windows differ from normal ones by having a shadow in a window
+ * separate from the standard screen.
+ */
+WINDOW *
+dlg_new_modal_window(WINDOW *parent, int height, int width, int y, int x)
+{
+ WINDOW *win;
+ DIALOG_WINDOWS *p = dlg_calloc(DIALOG_WINDOWS, 1);
+
+ (void) parent;
+ if (p == 0
+ || (win = newwin(height, width, y, x)) == 0) {
+ dlg_exiterr("Can't make new window at (%d,%d), size (%d,%d).\n",
+ y, x, height, width);
+ }
+ p->next = dialog_state.all_windows;
+ p->normal = win;
+ p->getc_timeout = WTIMEOUT_OFF;
+ dialog_state.all_windows = p;
+#ifdef HAVE_COLOR
+ if (dialog_state.use_shadow) {
+ p->shadow = parent;
+ draw_childs_shadow(p);
+ }
+#endif
+
+ (void) keypad(win, TRUE);
+ return win;
+}
+
+/*
+ * dlg_getc() uses the return-value to determine how to handle an ERR return
+ * from a non-blocking read:
+ * a) if greater than zero, there was an expired timeout (blocking for a short
+ * time), or
+ * b) if zero, it was a non-blocking read, or
+ * c) if negative, an error occurred on a blocking read.
+ */
+int
+dlg_set_timeout(WINDOW *win, bool will_getc)
+{
+ DIALOG_WINDOWS *p;
+ int result = 0;
+
+ if ((p = SearchTopWindows(win)) != NULL) {
+ int interval = (dialog_vars.timeout_secs * 1000);
+
+ if (will_getc || dialog_vars.pause_secs) {
+ interval = WTIMEOUT_VAL;
+ } else {
+ result = interval;
+ if (interval <= 0) {
+ interval = WTIMEOUT_OFF;
+ }
+ }
+ wtimeout(win, interval);
+ p->getc_timeout = interval;
+ }
+ return result;
+}
+
+void
+dlg_reset_timeout(WINDOW *win)
+{
+ DIALOG_WINDOWS *p;
+
+ if ((p = SearchTopWindows(win)) != NULL) {
+ wtimeout(win, p->getc_timeout);
+ } else {
+ wtimeout(win, WTIMEOUT_OFF);
+ }
+}
+
+/*
+ * Move/Resize a window, optionally with a shadow.
+ */
+#ifdef KEY_RESIZE
+void
+dlg_move_window(WINDOW *win, int height, int width, int y, int x)
+{
+ if (win != 0) {
+ DIALOG_WINDOWS *p;
+
+ dlg_ctl_size(height, width);
+
+ if ((p = SearchTopWindows(win)) != 0) {
+ (void) wresize(win, height, width);
+ (void) mvwin(win, y, x);
+#ifdef HAVE_COLOR
+ if (p->shadow != 0) {
+ if (dialog_state.use_shadow) {
+ (void) mvwin(p->shadow, y + SHADOW_ROWS, x + SHADOW_COLS);
+ } else {
+ p->shadow = 0;
+ }
+ }
+#endif
+ (void) refresh();
+
+#ifdef HAVE_COLOR
+ draw_childs_shadow(p);
+#endif
+ }
+ }
+}
+
+/*
+ * Having just received a KEY_RESIZE, wait a short time to ignore followup
+ * KEY_RESIZE events.
+ */
+void
+dlg_will_resize(WINDOW *win)
+{
+ int n, base;
+ int caught = 0;
+
+ dialog_state.had_resize = TRUE;
+ dlg_trace_win(win);
+ wtimeout(win, WTIMEOUT_VAL * 5);
+
+ for (n = base = 0; n < base + 10; ++n) {
+ int ch;
+
+ if ((ch = wgetch(win)) != ERR) {
+ if (ch == KEY_RESIZE) {
+ base = n;
+ ++caught;
+ } else if (ch != ERR) {
+ ungetch(ch);
+ break;
+ }
+ }
+ }
+ dlg_reset_timeout(win);
+ DLG_TRACE(("# caught %d KEY_RESIZE key%s\n",
+ 1 + caught,
+ caught == 1 ? "" : "s"));
+}
+#endif /* KEY_RESIZE */
+
+WINDOW *
+dlg_der_window(WINDOW *parent, int height, int width, int y, int x)
+{
+ WINDOW *win;
+
+ /* existing uses of derwin are (almost) guaranteed to succeed, and the
+ * caller has to allow for failure.
+ */
+ if ((win = derwin(parent, height, width, y, x)) != 0) {
+ add_subwindow(parent, win);
+ (void) keypad(win, TRUE);
+ }
+ return win;
+}
+
+WINDOW *
+dlg_sub_window(WINDOW *parent, int height, int width, int y, int x)
+{
+ WINDOW *win;
+
+ if ((win = subwin(parent, height, width, y, x)) == 0) {
+ dlg_exiterr("Can't make sub-window at (%d,%d), size (%d,%d).\n",
+ y, x, height, width);
+ }
+
+ add_subwindow(parent, win);
+ (void) keypad(win, TRUE);
+ return win;
+}
+
+/* obsolete */
+int
+dlg_default_item(char **items, int llen)
+{
+ int result = 0;
+
+ if (dialog_vars.default_item != 0) {
+ int count = 0;
+ while (*items != 0) {
+ if (!strcmp(dialog_vars.default_item, *items)) {
+ result = count;
+ break;
+ }
+ items += llen;
+ count++;
+ }
+ }
+ return result;
+}
+
+int
+dlg_default_listitem(DIALOG_LISTITEM * items)
+{
+ int result = 0;
+
+ if (dialog_vars.default_item != 0) {
+ int count = 0;
+ while (items->name != 0) {
+ if (!strcmp(dialog_vars.default_item, items->name)) {
+ result = count;
+ break;
+ }
+ ++items;
+ count++;
+ }
+ }
+ return result;
+}
+
+/*
+ * Draw the string for item_help
+ */
+void
+dlg_item_help(const char *txt)
+{
+ if (USE_ITEM_HELP(txt)) {
+ chtype attr = A_NORMAL;
+
+ dlg_attrset(stdscr, itemhelp_attr);
+ (void) wmove(stdscr, LINES - 1, 0);
+ (void) wclrtoeol(stdscr);
+ (void) addch(' ');
+ dlg_print_text(stdscr, txt, COLS - 1, &attr);
+
+ if (itemhelp_attr & A_COLOR) {
+ int y, x;
+ /* fill the remainder of the line with the window's attributes */
+ getyx(stdscr, y, x);
+ (void) y;
+ while (x < COLS) {
+ (void) addch(' ');
+ ++x;
+ }
+ }
+ (void) wnoutrefresh(stdscr);
+ }
+}
+
+#ifndef HAVE_STRCASECMP
+int
+dlg_strcmp(const char *a, const char *b)
+{
+ int ac, bc, cmp;
+
+ for (;;) {
+ ac = UCH(*a++);
+ bc = UCH(*b++);
+ if (isalpha(ac) && islower(ac))
+ ac = _toupper(ac);
+ if (isalpha(bc) && islower(bc))
+ bc = _toupper(bc);
+ cmp = ac - bc;
+ if (ac == 0 || bc == 0 || cmp != 0)
+ break;
+ }
+ return cmp;
+}
+#endif
+
+/*
+ * Returns true if 'dst' points to a blank which follows another blank which
+ * is not a leading blank on a line.
+ */
+static bool
+trim_blank(char *base, char *dst)
+{
+ int count = !!isblank(UCH(*dst));
+
+ while (dst-- != base) {
+ if (*dst == '\n') {
+ break;
+ } else if (isblank(UCH(*dst))) {
+ count++;
+ } else {
+ break;
+ }
+ }
+ return (count > 1);
+}
+
+/*
+ * Change embedded "\n" substrings to '\n' characters and tabs to single
+ * spaces. If there are no "\n"s, it will strip all extra spaces, for
+ * justification. If it has "\n"'s, it will preserve extra spaces. If cr_wrap
+ * is set, it will preserve '\n's.
+ */
+void
+dlg_trim_string(char *s)
+{
+ char *base = s;
+ char *p1;
+ char *p = s;
+ int has_newlines = !dialog_vars.no_nl_expand && (strstr(s, "\\n") != 0);
+
+ while (*p != '\0') {
+ if (*p == TAB && !dialog_vars.nocollapse)
+ *p = ' ';
+
+ if (has_newlines) { /* If prompt contains "\n" strings */
+ if (*p == '\\' && *(p + 1) == 'n') {
+ *s++ = '\n';
+ p += 2;
+ p1 = p;
+ /*
+ * Handle end of lines intelligently. If '\n' follows "\n"
+ * then ignore the '\n'. This eliminates the need to escape
+ * the '\n' character (no need to use "\n\").
+ */
+ while (isblank(UCH(*p1)))
+ p1++;
+ if (*p1 == '\n')
+ p = p1 + 1;
+ } else if (*p == '\n') {
+ if (dialog_vars.cr_wrap)
+ *s++ = *p++;
+ else {
+ /* Replace the '\n' with a space if cr_wrap is not set */
+ if (!trim_blank(base, p))
+ *s++ = ' ';
+ p++;
+ }
+ } else /* If *p != '\n' */
+ *s++ = *p++;
+ } else if (dialog_vars.trim_whitespace) {
+ if (isblank(UCH(*p))) {
+ if (!isblank(UCH(*(s - 1)))) {
+ *s++ = ' ';
+ p++;
+ } else
+ p++;
+ } else if (*p == '\n') {
+ if (dialog_vars.cr_wrap)
+ *s++ = *p++;
+ else if (!isblank(UCH(*(s - 1)))) {
+ /* Strip '\n's if cr_wrap is not set. */
+ *s++ = ' ';
+ p++;
+ } else
+ p++;
+ } else
+ *s++ = *p++;
+ } else { /* If there are no "\n" strings */
+ if (isblank(UCH(*p)) && !dialog_vars.nocollapse) {
+ if (!trim_blank(base, p))
+ *s++ = *p;
+ p++;
+ } else
+ *s++ = *p++;
+ }
+ }
+
+ *s = '\0';
+}
+
+void
+dlg_set_focus(WINDOW *parent, WINDOW *win)
+{
+ if (win != 0) {
+ (void) wmove(parent,
+ getpary(win) + getcury(win),
+ getparx(win) + getcurx(win));
+ (void) wnoutrefresh(win);
+ (void) doupdate();
+ }
+}
+
+/*
+ * Returns the nominal maximum buffer size, given the caller's estimate of
+ * the needed size. If the parameter is not greater than zero, return the
+ * configured buffer size.
+ */
+int
+dlg_max_input(int max_len)
+{
+ int limit = ((dialog_vars.max_input > 0)
+ ? dialog_vars.max_input
+ : MAX_LEN);
+
+ if (max_len > limit || max_len <= 0)
+ max_len = limit;
+
+ return max_len;
+}
+
+/*
+ * Free storage used for the result buffer.
+ */
+void
+dlg_clr_result(void)
+{
+ if (dialog_vars.input_length) {
+ dialog_vars.input_length = 0;
+ if (dialog_vars.input_result)
+ free(dialog_vars.input_result);
+ }
+ dialog_vars.input_result = 0;
+}
+
+/*
+ * Setup a fixed-buffer for the result.
+ */
+char *
+dlg_set_result(const char *string)
+{
+ unsigned need = string ? (unsigned) strlen(string) + 1 : 0;
+
+ /* inputstr.c needs a fixed buffer */
+ if (need < MAX_LEN)
+ need = MAX_LEN;
+
+ /*
+ * If the buffer is not big enough, allocate a new one.
+ */
+ if (dialog_vars.input_length != 0
+ || dialog_vars.input_result == 0
+ || need > MAX_LEN) {
+
+ dlg_clr_result();
+
+ dialog_vars.input_length = need;
+ dialog_vars.input_result = dlg_malloc(char, need);
+ assert_ptr(dialog_vars.input_result, "dlg_set_result");
+ }
+
+ strcpy(dialog_vars.input_result, string ? string : "");
+
+ return dialog_vars.input_result;
+}
+
+/*
+ * Accumulate results in dynamically allocated buffer.
+ * If input_length is zero, it is a MAX_LEN buffer belonging to the caller.
+ */
+void
+dlg_add_result(const char *string)
+{
+ unsigned have = (dialog_vars.input_result
+ ? (unsigned) strlen(dialog_vars.input_result)
+ : 0);
+ unsigned want = (unsigned) strlen(string) + 1 + have;
+
+ if ((want >= MAX_LEN)
+ || (dialog_vars.input_length != 0)
+ || (dialog_vars.input_result == 0)) {
+
+ if (dialog_vars.input_length == 0
+ || dialog_vars.input_result == 0) {
+
+ char *save_result = dialog_vars.input_result;
+
+ dialog_vars.input_length = want * 2;
+ dialog_vars.input_result = dlg_malloc(char, dialog_vars.input_length);
+ assert_ptr(dialog_vars.input_result, "dlg_add_result malloc");
+ dialog_vars.input_result[0] = '\0';
+ if (save_result != 0)
+ strcpy(dialog_vars.input_result, save_result);
+ } else if (want >= dialog_vars.input_length) {
+ dialog_vars.input_length = want * 2;
+ dialog_vars.input_result = dlg_realloc(char,
+ dialog_vars.input_length,
+ dialog_vars.input_result);
+ assert_ptr(dialog_vars.input_result, "dlg_add_result realloc");
+ }
+ }
+ strcat(dialog_vars.input_result, string);
+}
+
+/*
+ * These are characters that (aside from the quote-delimiter) will have to
+ * be escaped in a single- or double-quoted string.
+ */
+#define FIX_SINGLE "\n\\"
+#define FIX_DOUBLE FIX_SINGLE "[]{}?*;`~#$^&()|<>"
+
+/*
+ * Returns the quote-delimiter.
+ */
+static const char *
+quote_delimiter(void)
+{
+ return dialog_vars.single_quoted ? "'" : "\"";
+}
+
+/*
+ * Returns true if we should quote the given string.
+ */
+static bool
+must_quote(char *string)
+{
+ bool code = FALSE;
+
+ if (*string != '\0') {
+ size_t len = strlen(string);
+ if (strcspn(string, quote_delimiter()) != len)
+ code = TRUE;
+ else if (strcspn(string, "\n\t ") != len)
+ code = TRUE;
+ else
+ code = (strcspn(string, FIX_DOUBLE) != len);
+ } else {
+ code = TRUE;
+ }
+
+ return code;
+}
+
+/*
+ * Add a quoted string to the result buffer.
+ */
+void
+dlg_add_quoted(char *string)
+{
+ char temp[2];
+ const char *my_quote = quote_delimiter();
+ const char *must_fix = (dialog_vars.single_quoted
+ ? FIX_SINGLE
+ : FIX_DOUBLE);
+
+ if (must_quote(string)) {
+ temp[1] = '\0';
+ dlg_add_result(my_quote);
+ while (*string != '\0') {
+ temp[0] = *string++;
+ if ((strchr) (my_quote, *temp) || (strchr) (must_fix, *temp))
+ dlg_add_result("\\");
+ dlg_add_result(temp);
+ }
+ dlg_add_result(my_quote);
+ } else {
+ dlg_add_result(string);
+ }
+}
+
+/*
+ * When adding a result, make that depend on whether "--quoted" is used.
+ */
+void
+dlg_add_string(char *string)
+{
+ if (dialog_vars.quoted) {
+ dlg_add_quoted(string);
+ } else {
+ dlg_add_result(string);
+ }
+}
+
+bool
+dlg_need_separator(void)
+{
+ bool result = FALSE;
+
+ if (dialog_vars.output_separator) {
+ result = TRUE;
+ } else if (dialog_vars.input_result && *(dialog_vars.input_result)) {
+ result = TRUE;
+ }
+ return result;
+}
+
+void
+dlg_add_separator(void)
+{
+ const char *separator = (dialog_vars.separate_output) ? "\n" : " ";
+
+ if (dialog_vars.output_separator)
+ separator = dialog_vars.output_separator;
+
+ dlg_add_result(separator);
+}
+
+#define HELP_PREFIX "HELP "
+
+void
+dlg_add_help_listitem(int *result, char **tag, DIALOG_LISTITEM * item)
+{
+ dlg_add_result(HELP_PREFIX);
+ if (USE_ITEM_HELP(item->help)) {
+ *tag = dialog_vars.help_tags ? item->name : item->help;
+ *result = DLG_EXIT_ITEM_HELP;
+ } else {
+ *tag = item->name;
+ }
+}
+
+void
+dlg_add_help_formitem(int *result, char **tag, DIALOG_FORMITEM * item)
+{
+ dlg_add_result(HELP_PREFIX);
+ if (USE_ITEM_HELP(item->help)) {
+ *tag = dialog_vars.help_tags ? item->name : item->help;
+ *result = DLG_EXIT_ITEM_HELP;
+ } else {
+ *tag = item->name;
+ }
+}
+
+/*
+ * Some widgets support only one value of a given variable - save/restore the
+ * global dialog_vars so we can override it consistently.
+ */
+void
+dlg_save_vars(DIALOG_VARS * vars)
+{
+ *vars = dialog_vars;
+}
+
+/*
+ * Most of the data in DIALOG_VARS is normally set by command-line options.
+ * The input_result member is an exception; it is normally set by the dialog
+ * library to return result values.
+ */
+void
+dlg_restore_vars(DIALOG_VARS * vars)
+{
+ char *save_result = dialog_vars.input_result;
+ unsigned save_length = dialog_vars.input_length;
+
+ dialog_vars = *vars;
+ dialog_vars.input_result = save_result;
+ dialog_vars.input_length = save_length;
+}
+
+/*
+ * Called each time a widget is invoked which may do output, increment a count.
+ */
+void
+dlg_does_output(void)
+{
+ dialog_state.output_count += 1;
+}
+
+/*
+ * Compatibility for different versions of curses.
+ */
+#if !(defined(HAVE_GETBEGX) && defined(HAVE_GETBEGY))
+int
+dlg_getbegx(WINDOW *win)
+{
+ int y, x;
+ getbegyx(win, y, x);
+ (void) y;
+ return x;
+}
+int
+dlg_getbegy(WINDOW *win)
+{
+ int y, x;
+ getbegyx(win, y, x);
+ (void) x;
+ return y;
+}
+#endif
+
+#if !(defined(HAVE_GETCURX) && defined(HAVE_GETCURY))
+int
+dlg_getcurx(WINDOW *win)
+{
+ int y, x;
+ getyx(win, y, x);
+ (void) y;
+ return x;
+}
+int
+dlg_getcury(WINDOW *win)
+{
+ int y, x;
+ getyx(win, y, x);
+ (void) x;
+ return y;
+}
+#endif
+
+#if !(defined(HAVE_GETMAXX) && defined(HAVE_GETMAXY))
+int
+dlg_getmaxx(WINDOW *win)
+{
+ int y, x;
+ getmaxyx(win, y, x);
+ (void) y;
+ return x;
+}
+int
+dlg_getmaxy(WINDOW *win)
+{
+ int y, x;
+ getmaxyx(win, y, x);
+ (void) x;
+ return y;
+}
+#endif
+
+#if !(defined(HAVE_GETPARX) && defined(HAVE_GETPARY))
+int
+dlg_getparx(WINDOW *win)
+{
+ int y, x;
+ getparyx(win, y, x);
+ (void) y;
+ return x;
+}
+int
+dlg_getpary(WINDOW *win)
+{
+ int y, x;
+ getparyx(win, y, x);
+ (void) x;
+ return y;
+}
+#endif
+
+#ifdef NEED_WGETPARENT
+WINDOW *
+dlg_wgetparent(WINDOW *win)
+{
+#undef wgetparent
+ WINDOW *result = 0;
+ DIALOG_WINDOWS *p;
+
+ for (p = dialog_state.all_subwindows; p != 0; p = p->next) {
+ if (p->shadow == win) {
+ result = p->normal;
+ break;
+ }
+ }
+ return result;
+}
+#endif
Index: sources/packages/dialog/create-1.3-20240101-patch/file.list
===================================================================
--- sources/packages/dialog/create-1.3-20240101-patch/file.list (nonexistent)
+++ sources/packages/dialog/create-1.3-20240101-patch/file.list (revision 34)
@@ -0,0 +1,7 @@
+dialog-1.3-20240101/buildlist.c
+dialog-1.3-20240101/checklist.c
+dialog-1.3-20240101/dialog-config.in
+dialog-1.3-20240101/fselect.c
+dialog-1.3-20240101/menubox.c
+dialog-1.3-20240101/treeview.c
+dialog-1.3-20240101/util.c
Index: sources/packages/dialog/patches/README
===================================================================
--- sources/packages/dialog/patches/README (revision 33)
+++ sources/packages/dialog/patches/README (revision 34)
@@ -1,6 +1,6 @@
/* begin *
- dialog-1.3-20210621.patch - Some enhance the appearance of dialogs.
+ dialog-1.3-20240101.patch - Some enhance the appearance of dialogs.
* end */